|
/*********************************************************************************
Copyright(c) 2004 Analog Devices, Inc. All Rights Reserved.
This software is proprietary and confidential. By using this software you agree to the terms of the associated Analog Devices License Agreement.
$RCSfile: UARTExample.c,v $ $Revision: 1.4 $ $Date: 2006/03/31 14:31:48 $
*******************************************************************************
Please refer to the 'readme.txt' file for a description of the UART examples. *********************************************************************************/
/*********************************************************************
Include files
*********************************************************************/
#include <services\services.h> // system services #include <drivers\adi_dev.h> // device manager includes #include <drivers\uart\adi_uart.h> // uart driver includes #include "ezkitutilities.h" // EZ-Kit utilities
/*********************************************************************
User configurations:
Callbacks can be either "live" meaning they happen at hardware interrupt time, or "deferred" meaning that the Deferred Callback Service is used to make callbacks at a lower priority interrupt level. Deferred callbacks usually allow the system to process data more efficiently with lower interrupt latencies.
The macro below can be used to toggle between "live" and "deferred" callbacks. All drivers and system services that make callbacks into an application are passed a handle to a callback service. If that handle is NULL, then live callbacks are used. If that handle is non-NULL, meaning the handle is a real handle into a deferred callback service, then callbacks are deferred using the given callback service.
Also included is a macro that can be used to set the baud rate for the UART.
*********************************************************************/
#define USE_DEFERRED_CALLBACKS // enables deferred callbacks
#define BAUD_RATE (9600) // baud rate at which the UART will run
/*********************************************************************
Static data
*********************************************************************/
// Create two buffer chains. One chain will be used for one of the frames, // the other chain for the other frame. Note that in this example there // is only 1 buffer in each chain ADI_DEV_1D_BUFFER InboundBuffer; ADI_DEV_1D_BUFFER OutboundBuffer;
// data for the inbound and outbound buffer u8 InboundData; u8 OutboundData;
// Deferred Callback Manager data (memory for 1 service plus 4 posted callbacks) #if defined(USE_DEFERRED_CALLBACKS) static u8 DCBMgrData[ADI_DCB_QUEUE_SIZE + (ADI_DCB_ENTRY_SIZE)*4]; #endif
// Device Manager data (base memory + memory for 1 device) static u8 DevMgrData[ADI_DEV_BASE_MEMORY + (ADI_DEV_DEVICE_MEMORY * 1)];
// Handle to the UART driver static ADI_DEV_DEVICE_HANDLE DriverHandle;
/*********************************************************************
Function: ExceptionHandler HWErrorHandler
Description: We should never get an exception or hardware error, but just in case we'll catch them and simply turn on all the LEDS should one ever occur.
*********************************************************************/
static ADI_INT_HANDLER(ExceptionHandler) // exception handler { ezErrorCheck(1); return(ADI_INT_RESULT_PROCESSED); } static ADI_INT_HANDLER(HWErrorHandler) // hardware error handler { ezErrorCheck(1); return(ADI_INT_RESULT_PROCESSED); }
/*********************************************************************
Function: Callback
Description: Each type of callback event has it's own unique ID so we can use a single callback function for all callback events. The switch statement tells us which event has occurred. In the example, we've configured the buffers going to the driver for inbound data to generate a callback but the buffers going to the driver for outbound data will not generate a callback. When we get a callback for an inbound buffer, we simply copy the data to the outbound buffer, then send the outbound buffer to the device for transmission and re-queue the inbound buffer so that it can receive the next piece of data. *********************************************************************/
static void Callback( void *AppHandle, u32 Event, void *pArg) { ADI_DEV_BUFFER *pBuffer; // pointer to the buffer that was processed // CASEOF (event type) switch (Event) { // CASE (buffer processed) case ADI_DEV_EVENT_BUFFER_PROCESSED: // identify which buffer is generating the callback // we're setup to only get callbacks on inbound buffers so we know this // is an inbound buffer pBuffer = (ADI_DEV_BUFFER *)pArg; // copy the data to the outbound buffer OutboundData = InboundData; // send the outbound buffer ezErrorCheck(adi_dev_Write(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&OutboundBuffer)); // requeue the inbound buffer ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer)); // cycle the LEDs so it looks like we're doing something important ezCycleLEDs(); break; // CASE (an error) case ADI_UART_EVENT_BREAK_INTERRUPT: case ADI_UART_EVENT_FRAMING_ERROR: case ADI_UART_EVENT_PARITY_ERROR: case ADI_UART_EVENT_OVERRUN_ERROR: // turn on all LEDs and wait for help ezTurnOnAllLEDs(); while (1) ; // ENDCASE } // return }
/********************************************************************* * * Function: main * *********************************************************************/
void main(void) { ADI_DCB_HANDLE DCBManagerHandle; // handle to the callback service ADI_DEV_MANAGER_HANDLE DeviceManagerHandle; // handle to the Device Manager u32 ResponseCount; // response counter u32 cclk, sclk, vco; // frequencies (note these are in MHz) u32 i; //loop variable ADI_DEV_CMD_VALUE_PAIR ConfigurationTable [] = { // configuration table for the UART driver { ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED }, { ADI_UART_CMD_SET_DATA_BITS, (void *)8 }, { ADI_UART_CMD_ENABLE_PARITY, (void *)FALSE }, { ADI_UART_CMD_SET_STOP_BITS, (void *)1 }, { ADI_UART_CMD_SET_BAUD_RATE, (void *)BAUD_RATE }, { ADI_UART_CMD_SET_LINE_STATUS_EVENTS, (void *)TRUE }, { ADI_DEV_CMD_END, NULL }, };
// initialize the EZ-Kit ezInit(1); // turn off all LEDs ezTurnOffAllLEDs(); // initialize the Interrupt Manager and hook the exception and hardware error interrupts // all interrupts are on unique IVGs so we don't need any secondary handler memory ezErrorCheck(adi_int_Init(NULL, 0, &ResponseCount, NULL)); ezErrorCheck(adi_int_CECHook(3, ExceptionHandler, NULL, FALSE)); ezErrorCheck(adi_int_CECHook(5, HWErrorHandler, NULL, FALSE)); // initialize the Deferred Callback Manager and setup a queue #if defined(USE_DEFERRED_CALLBACKS) ezErrorCheck(adi_dcb_Init(&DCBMgrData[0], ADI_DCB_QUEUE_SIZE, &ResponseCount, NULL)); ezErrorCheck(adi_dcb_Open(14, &DCBMgrData[ADI_DCB_QUEUE_SIZE], (ADI_DCB_ENTRY_SIZE)*4, &ResponseCount, &DCBManagerHandle)); #else DCBManagerHandle = NULL; #endif
//Initialize the flag service, memory is not passed because callbacks are not being used ezErrorCheck(adi_flag_Init(NULL, 0, &ResponseCount, NULL)); //Initialize all LEDS for (i = EZ_FIRST_LED; i < EZ_NUM_LEDS; i++){ ezInitLED(i); }
// turn off all LEDs ezTurnOffAllLEDs();
// initialize the Device Manager ezErrorCheck(adi_dev_Init(DevMgrData, sizeof(DevMgrData), &ResponseCount, &DeviceManagerHandle, NULL)); // create two buffers that will be initially be placed on the inbound queue // only the inbound buffer will have a callback InboundBuffer.Data = &InboundData; InboundBuffer.ElementCount = 1; InboundBuffer.ElementWidth = 1; InboundBuffer.CallbackParameter = &InboundBuffer; InboundBuffer.ProcessedFlag = FALSE; InboundBuffer.pNext = NULL; OutboundBuffer.Data = &OutboundData; OutboundBuffer.ElementCount = 1; OutboundBuffer.ElementWidth = 1; OutboundBuffer.CallbackParameter = NULL; OutboundBuffer.ProcessedFlag = FALSE; OutboundBuffer.pNext = NULL; // open the UART driver for bidirectional data flow ezErrorCheck(adi_dev_Open(DeviceManagerHandle, &ADIUARTEntryPoint, 0, NULL, &DriverHandle, ADI_DEV_DIRECTION_BIDIRECTIONAL, NULL, DCBManagerHandle, Callback)); // configure the UART driver with the values from the configuration table ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_TABLE, ConfigurationTable)); // give the device the inbound buffer ezErrorCheck(adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&InboundBuffer)); // enable data flow ezErrorCheck(adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void *)TRUE)); // wait until the last push button is pressed while (ezIsButtonPushed(EZ_LAST_BUTTON) == FALSE) ; // close down the device driver ezErrorCheck(adi_dev_Close(DriverHandle)); // close the Device Manager ezErrorCheck(adi_dev_Terminate(DeviceManagerHandle)); // close down the Deferred Callback Manager #if defined(USE_DEFERRED_CALLBACKS) ezErrorCheck(adi_dcb_Close(DCBManagerHandle)); ezErrorCheck(adi_dcb_Terminate()); #endif
// turn off all LEDs ezTurnOffAllLEDs(); // return }
|