STATIC CONST FAR RX_UART_SET_T atrXUrt[] = { { {UART_NAME, RX_PERIPHERAL_TYPE_UART, 0}, /* peripheral name, type, and instance */ UART_INSTANCE, /* 0 = first real UART, 16 = first virtual UART on USB */ RX_UART_BAUDRATE_115200, /* baud rate 115,2k */ RX_UART_PARITY_NONE, /* no parity */ RX_UART_STOPBIT_1, /* 1 stop bit */ RX_UART_DATABIT_8, /* 8 data bits */ UART_RX_READY_LEVEL, /* "rx ready" trigger level for rx FIFO (set to 1..16 to enable FIFO, set to 0 to force immediate notification) */ UART_TX_EMPTY_LEVEL, /* "tx empty" trigger level for tx FIFO (set to 1..16 to enable FIFO, set to 0 to force immediate send) */ RX_UART_RTS_NONE, /* no RTS in use */ RX_UART_RTS_DEFAULT, /* no RTS in use */ 0, /* no RTS forerun */ 0, /* no RTS trail */ RX_UART_CTS_NONE, /* no CTS in use */ RX_UART_CTS_DEFAULT, /* default CTS handling */
/* structure extensions for USB support start here */ 0x00000000, /* connection management flags, see RX_UART_FLAG_xxx in rX_Config.h */ IDENT_VENDOR_ID, /* USB device vendor ID (VID) */ IDENT_PRODUCT_ID, /* USB device product ID (PID) */ IDENT_PRODUCT_RELEASE, /* USB device product release number */ IDENT_VENDOR_NAME, /* USB vendor name */ IDENT_DEVICE_NAME, /* USB product name */ "00000000" /* USB serial number */ } };
/* Note on USB product name: Windows XP reads this string once when the device is connected for the first time, i.e. when the Install Driver dialog is shown. The string is buffered in the registry together with the VID and PID until the end of time! In subsequent connect events, Windows XP uses the string buffered in the registry rather than the string used by the firmware. I.e.: When connecting a device with the same VID and PID but with a different USB product name Windows shows the string buffered in the registry rather than the string actually used by the firmware. */
{ /* UartHandlerRxReady() is called on demand from within the UART driver's ISR or from within the UART driver's polling callback */ TLR_RESULT eRet; UINT8 abData[64]; UINT uiRxCount;
if (hUart != NULL && ptUartData != NULL) { eRet = TLR_S_OK; abData[0] = (UINT8) uRxChar; uiRxCount = sizeof (abData) - 1; /* Collect all received chars and pass them to the application */ eRet = Drv_UrtRecv (hUart, &abData[1], &uiRxCount); if (eRet == TLR_S_OK) uiRxCount += 1; else uiRxCount = 1; eRet = AppRxReady (abData, uiRxCount); if (eRet != TLR_S_OK) { /* receive problem on application level */ eRet = AppError (); } } }
{ /* UartHandlerTxEmpty() is called on demand from within the UART driver's ISR or from within the UART driver's polling callback */ TLR_RESULT eRet; UINT32 ulLock; UINT uiSent;
if (hUart != NULL && ptUartData != NULL) { uiSent = ptUartData->ulUsedSendDataBufferLen - ptUartData->ulCurrentSendOffset; if (uiSent == 0) { /* no telegram or telegram sent completely */ lock_irq_save (ulLock); ptUartData->ulUsedSendDataBufferLen = 0; ptUartData->ulCurrentSendOffset = 0; eRet = AppTxEmpty (ptUartData->abSendBuffer, sizeof (ptUartData->abSendBuffer), &ptUartData->ulUsedSendDataBufferLen); if (eRet == TLR_S_OK && ptUartData->ulUsedSendDataBufferLen > 0) { /* application has provided data for sending */ ptUartData->fSendActive = TRUE; uiSent = ptUartData->ulUsedSendDataBufferLen; eRet = Drv_UrtSend (ptUartData->hUart, ptUartData->abSendBuffer, &uiSent); if (eRet == TLR_S_OK) { /* update send offset and re-enable UART transmit interrupt (if configured for interrupt mode) */ ptBuffer->tMgmt.ulCurrentSendOffset += uiSent; eRet = Drv_UrtEnableTransmitter (ptUartData->hUart, ptUartData->tConfigData.fInterruptMode); } } else { /* no data to send */ ptUartData->fSendActive = FALSE; eRet = Drv_UrtEnableTransmitter (ptUartData->hUart, FALSE); } lock_irq_restore (ulLock); } else { /* continue sending the rest of the telegram */ eRet = Drv_UrtSend (ptUartData->hUart, &ptUartData->abSendBuffer[ptBuffer->ulCurrentSendOffset], &uiSent); if (eRet == TLR_S_OK) ptBuffer->ulCurrentSendOffset += uiSent; } } }
{ /* UartHandlerError() is called on demand from within the UART driver's ISR or from within the UART driver's polling callback */ TLR_RESULT eRet; UINT32 ulLock;
if (hUart != NULL && ptUartData != NULL) { eRet = AppError (); if (eRet != TLR_S_OK) { /* reset a pending transmit, if any */ lock_irq_save (ulLock); ptUartData->fSendActive = FALSE; ptUartData->ulUsedSendDataBufferLen = 0; ptUartData->ulCurrentSendOffset = 0; Drv_UrtEnableTransmitter (ptUartData->hUart, FALSE); lock_irq_restore (ulLock); } } }
{ /* UartHandlerExit() resets and releases a UART driver instance and its associated resources */ if (ptUartData != NULL) { /* release everything that is referred to by an OS handle, then release the management data memory block */ if (ptUartData->hIrq != NULL) { /* an interrupt driver instance has been created: delete it */ Drv_IntDisableInterrupt (ptUartData->hIrq); Drv_IntDeleteInterrupt (ptUartData->hIrq); ptUartData->hIrq = NULL; } if (ptUartData->hTimer != NULL) { /* a polling timer has been created: delete it */ rX_TimHaltTimer (ptUartData->hTimer); rX_TimDeleteTimer (ptUartData->hTimer); ptUartData->hTimer = NULL; } if (ptUartData->hUart != NULL) { /* a UART driver instance has been created: delete it */ Drv_UrtDisableUart (ptUartData->hUart); Drv_UrtDeleteUart (ptUartData->hUart); ptUartData->hUart = NULL; } rX_MemFreeMemory(ptUartData); } }
{ /* UartHandlerInit() initializes and enables a UART driver instance either in interrupt mode or in polling mode */ TLR_RESULT eRet = TLR_S_OK; UART_HANDLER_INTERNAL_T* ptUartData = NULL;
if (ptConfigData == NULL) eRet = HIL_MARSHALLER_E_INVALIDPARAMETER; else { /* allocate memory for the management data block */ eRet = rX_MemAllocateMemory ((void**) (UINT32) &ptUartData, sizeof (*ptUartData)); if (eRet == TLR_S_OK) { /* initialize the management data block */ MEMSET (ptUartData, 0, sizeof (*ptUartData)); MEMCPY (&ptUartData->tConfigData, ptConfigData, sizeof (ptUartData->tConfigData)); /* obtain a handle for the UART driver instance */ eRet = Drv_UrtIdentifyUart (ptUartData->tConfigData.szUartName, ptUartData->tConfigData.ulUartInstance, &ptUartData->hUart); if (eRet == TLR_S_OK) { /* initialize the UART driver instance using the given parameters */ eRet = Drv_UrtInitializeUart (ptUartData->hUart, (void (CALLBACK FAR*) (RX_HANDLE, void FAR*, UINT)) UartHandlerRxReady, (void (CALLBACK FAR*) (RX_HANDLE, void FAR*)) UartHandlerTxEmpty, (void (CALLBACK FAR*) (RX_HANDLE, void FAR*)) UartHandlerError, ptUartData, ptUartData->tConfigData.fInterruptMode, &ptUartData->unUartHandler); if (eRet == TLR_S_OK) { /* check whether to run in IRQ mode or in polling mode */ if (ptUartData->tConfigData.fInterruptMode) { /* obtain a handle for the interrupt associated with the UART driver instance */ eRet = Drv_IntIdentifyInterrupt (ptUartData->tConfigData.szIrqName, ptUartData->tConfigData.ulUartInstance, &ptUartData->hIrq); if (eRet == TLR_S_OK) { /* configure the interrupt in the VIC */ eRet = Drv_IntInitializeInterrupt (ptUartData->hIrq, ptUartData->unUartHandler.fnIrq, ptUartData->hUart); if (eRet == TLR_S_OK) { /* enable the interrupt in the VIC */ eRet = Drv_IntEnableInterrupt (ptUartData->hIrq); } } } else { /* use a software timer to animate the UART driver's polling callback */ eRet = rX_TimCreateTimer (ptUartData->abTimer, ptUartData->unUartHandler.fnPoll, ptUartData->hUart, RX_TIM_AUTO_RELOAD, 10, 10); if (eRet == TLR_S_OK) ptUartData->hTimer = (RX_HANDLE) abTimer; } } } } /* Check if basic initialization was successful */ if (eRet == TLR_S_OK) { /* Enforce a delay of 2 seconds before enabling the (virtual) UART. */ /* (Allows remote PC to recognize loss of USB connection after firmware reset.) */ /* 2 s = 2000 ms = 2000 * (system tick in microseconds / 1000) = 2 * (system tick in microseconds) */ rX_SysSleepTask (2 * rX_SysGetSystemCycletime ()); eRet = Drv_UrtEnableUart (ptUartData->hUart); if (eRet == TLR_S_OK) { /* enable Rx ready interrupt in the UART (if configured for interrupt mode) */ eRet = Drv_UrtEnableReceiver (ptUartData->hUart, ptUartData->tConfigData.fInterruptMode); if (eRet == TLR_S_OK) { /* disable Tx empty interrupt in the UART (will be enabled when sending data) */ eRet = Drv_UrtEnableTransmitter (ptUartData->hUart, FALSE); } } } if (eRet != TLR_S_OK) { /* initialization failure: reset the resources */ UartHandlerExit (ptUartData); } } return (eRet); }
UsbExample.h
/* ***************************************************************************** * Symbol Definitions ***************************************************************************** */
/* configuration switches */ #define __USB_MODE /* if defined, enables support for communication via USB (otherwise real UART 0 will be used) */ #undef __POLLING_MODE /* if defined, enables polling mode (otherwise interrupt mode will be used) */
typedef struct { /* copy of the configuration data */ UART_HANDLER_CONFIG_T tConfigData; /* OS resource handles */ RX_HANDLE hUart; RX_HANDLE hIrq; RX_HANDLE hTimer; /* buffer for ISR / polling function address */ RX_URT_HANDLER_UN unUartHandler; /* timer management data buffer to be provided to the OS */ UINT8 abTimer[RX_TIMER_SIZE]; /* transmit management data */ BOOLEAN fSendActive; UINT8 abSendBuffer[64]; UINT32 ulUsedSendDataBufferLen; UINT32 ulCurrentSendOffset; } UART_HANDLER_INTERNAL_T;
/* ***************************************************************************** * Global Variables ***************************************************************************** */
#ifdef __UART_EXAMPLE_C
CONST UART_HANDLER_CONFIG_T g_tUartConfig = { /* UART configuration parameters (for a virtual UART based on the netX USB interface) */ .szUartName = UART_NAME, /* name of the UART peripheral device */ .ulUartInst = 0, /* UART device instance number */ .fInterrupt = UART_IRQ_ENABLE, /* use polling mode */ .szIrqName = UART_IRQ_NAME, /* interrupt name */ .ulIrqInst = 0 /* interrupt instance number */ };
Andreas Jacob
Hilscher Gesellschaft fuer Systemautomation mbH
Hi Krasi Gichev,
sorry but I have only some code snippets.
Config.c:
UsbExample.c:
UsbExample.h
Hope this will help.
Regards
AJ