industrialNETworXnetx

Krasi Gichev

Krasi Gichev

AMK

| 30.03.2010 | 13:28 | 2 replies

rcX BSP Drv_Urt with USB CDC example

Hi,

I saw a note in your documentation:

 "- Drv_Urt now supports USB cdc emulation using the internal USB core."

Is there any example how to configure (use) it?

What "uUrtNum" to define in RX_UART_SET_T?

 

Thank you!

 

Andreas Jacob

Andreas Jacob

Hilscher Gesellschaft fuer Systemautomation mbH

| 31.03.2010 | 09:44

Hi Krasi Gichev,

sorry but I have only some code snippets.

Config.c:

/*
*****************************************************************************
*   Interrupt Instances
*****************************************************************************
*/

STATIC CONST FAR RX_INTERRUPT_SET_T atrXInt[] =
{
  {
    {"SYSTIMER", RX_PERIPHERAL_TYPE_INTERRUPT, 0},
    SRT_NETX_VIC_IRQ_STAT_timer0,                   /* use external Timer 0 interrupt bit in the VIC IRQ status register */
    29,                                             /* interrupt priority */
    RX_INTERRUPT_MODE_SYSTEM,                       /* do not create a separate task for the interrupt */
    RX_INTERRUPT_EOI_AUTO,                          /* EOI handled automatically */
    RX_INTERRUPT_TRIGGER_RISING_EDGE,               /* edge triggered */
    RX_INTERRUPT_PRIORITY_STANDARD,                 /* normal priority */
    RX_INTERRUPT_REENTRANCY_DISABLED,               /* interrupt is not reentrant */
  },
#ifndef __POLLING_MODE                              /* do not instantiate interrupts in polling mode                         */
#ifdef __UART_MODE
  {
    {UART_IRQ_NAME, RX_PERIPHERAL_TYPE_INTERRUPT, 0},
    SRT_NETX_VIC_IRQ_STAT_uart0,                    /* use UART 0 interrupt bit in the VIC IRQ status register     */
    17,                                             /* interrupt priority                                                                             */
    RX_INTERRUPT_MODE_SYSTEM,                       /* do not create a separate task for the interrupt                     */
    RX_INTERRUPT_EOI_AUTO,                          /* EOI handled automatically                                                                 */
    RX_INTERRUPT_TRIGGER_RISING_EDGE,               /* edge triggered (no effect on UART peripherals)                     */
    RX_INTERRUPT_PRIORITY_STANDARD,                 /* normal priority                                                                                     */
    RX_INTERRUPT_REENTRANCY_DISABLED,               /* interrupt is not reentrant                                                             */
    0,                                              /* interrupt task priority (not used)                                             */
    0,                                              /* interrupt task token (not used)                                                     */
    0                                               /* interrupt task stack size (not used)                                         */
  },
#endif /* __UART_MODE */
#ifdef __USB_MODE
  {
    {UART_IRQ_NAME, RX_PERIPHERAL_TYPE_INTERRUPT, 0},
    SRT_NETX_VIC_IRQ_STAT_usb,                      /* use USB interrupt bit in the VIC IRQ status register         */
    5,                                              /* interrupt priority                                                                             */
    RX_INTERRUPT_MODE_TASK,                         /* create a separate task for the interrupt                                 */
    RX_INTERRUPT_EOI_AUTO,                          /* EOI handled automatically                                                                 */
    RX_INTERRUPT_TRIGGER_RISING_EDGE,               /* edge triggered                                                                                     */
    RX_INTERRUPT_PRIORITY_STANDARD,                 /* normal priority                                                                                     */
    RX_INTERRUPT_REENTRANCY_DISABLED,               /* interrupt is not reentrant                                                             */
    TSK_PRIO_6,                                     /* interrupt task priority                                                                     */
    TSK_TOK_6,                                      /* interrupt task token                                                                         */
    1024                                            /* interrupt task stack size                                                                 */
  }
#endif  /* __USB_MODE */
#endif  /* __POLLING_MODE */
};


/*
*****************************************************************************
*   UART Instances
*****************************************************************************
*/

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.
*/


/*
*****************************************************************************
*   GPIO Instances
*****************************************************************************
*/

STATIC CONST FAR RX_GPIO_SET_T atrXGpio[] =
{
#ifdef __UART_MODE
  {{"USBENABLE", RX_PERIPHERAL_TYPE_GPIO, 0},
   12,                              /* GPIO number         */
   RX_GPIO_TYPE_OUTPUT,             /* GPIO type             */
   RX_GPIO_POLARITY_NORMAL,         /* GPIO polarity     */
   RX_GPIO_OUTPUTMODE_STANDARD_0,   /* GPIO mode             */
   RX_GPIO_COUNTER_NONE,            /* counter reference, needed when edges or levels shall be counted     */
   FALSE,                           /* enables/disables IRQ in the case a counter is referenced                 */
   0,                               /* threshold / capture value in PWM mode                                                         */
  },
#endif  /* __USB_MODE */
};

UsbExample.c:

/*
*****************************************************************************
* Functions
*****************************************************************************
*/


static void UartHandlerRxReady (RX_HANDLE hUart, UART_HANDLER_INTERNAL_T* ptUartData, UINT uRxChar)

{ /* 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 ();
}
}
}



static void UartHandlerTxEmpty (RX_HANDLE hUart, UART_HANDLER_INTERNAL_T* ptUartData)

{ /* 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;
}
}
}



static void UartHandlerError (RX_HANDLE hUart, UART_HANDLER_INTERNAL_T* ptUartData)

{ /* 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);
}
}
}



static void UartHandlerExit (UART_HANDLER_INTERNAL_T* ptUartData)

{ /* 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);
}
}



TLR_RESULT UartHandlerInit (UART_HANDLER_CONFIG_T* ptConfigData)

{ /* 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) */


/* interrupt configuration flag */
#ifdef __POLLING_MODE
#define UART_IRQ_ENABLE FALSE
#else /* __POLLING_MODE */
#define UART_IRQ_ENABLE TRUE
#endif /* __POLLING_MODE */


/* UART and USB names */
#ifdef __USB_MODE
#define UART_NAME "VIRTUART"
#define UART_IRQ_NAME "INTUSB"
#define UART_INSTANCE 16 /* virtual UART instances on USB start with instance 0x10 (currently only one USB I/F defined) */
#define UART_RX_READY_LEVEL 0 /* "rx ready" trigger level for rx FIFO (set to 0 to force immediate notification) */
#define UART_TX_EMPTY_LEVEL, 0 /* "tx empty" trigger level for tx FIFO (set to 0 to force immediate send) */
#else /* __USB_MODE */
#define UART_NAME "REALUART"
#define UART_IRQ_NAME "INTUART"
#define UART_INSTANCE 0 /* use integrated UART 0 */
#define UART_RX_READY_LEVEL 8 /* "rx ready" trigger level for rx FIFO (set to 1..16 to enable FIFO) */
#define UART_TX_EMPTY_LEVEL, 4 /* "tx empty" trigger level for tx FIFO (set to 1..16 to enable FIFO) */
#endif /* __USB_MODE */


/* identification on USB */
#ifdef __USB_MODE
#define IDENT_VENDOR_NAME "Hilscher GmbH"
#define IDENT_DEVICE_NAME "netX USB CDC"
#define IDENT_VENDOR_ID 0x1939
#define IDENT_PRODUCT_ID 0x0001
#define IDENT_PRODUCT_RELEASE 0x0001
#else /* __USB_MODE */
#define IDENT_VENDOR_NAME ""
#define IDENT_DEVICE_NAME ""
#define IDENT_VENDOR_ID 0x0000
#define IDENT_PRODUCT_ID 0x0000
#define IDENT_PRODUCT_RELEASE 0x0000
#endif /* __USB_MODE */



/*
*****************************************************************************
* Class, Type, and Structure Definitions
*****************************************************************************
*/


typedef struct
{ /* UART driver instance configuration data */
STRING szUartName[16];
UINT32 ulUartInst;
/* UART driver instance configuration data */
STRING szIrqName[16];
UINT32 ulIrqInst;
/* mode configuration flag */
BOOLEAN fInterruptMode;
} UART_HANDLER_CONFIG_T;



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 */
};

#else /* __UART_EXAMPLE_C */

extern CONST UART_HANDLER_CONFIG_T g_tUartConfig;

#endif /* __UART_EXAMPLE_C */



/*
*****************************************************************************
* Functions
*****************************************************************************
*/


/* application callback prototypes */
TLR_RESULT AppTxEmpty (UINT8* pabSendBuffer, UINT32 ulSendBufferLen, UINT32* pulSendDataLen);
TLR_RESULT AppRxReady (UINT8* pabReceiveBuffer, UINT32 ulReceiveDataLen);
TLR_RESULT AppError (void);



#endif /* __USB_EXAMPLE_H */

Hope this will help.

Regards
AJ

Krasi Gichev

Krasi Gichev

AMK

| 31.03.2010 | 15:24

Sure it will help :-)

It's a lot of code, thank you! I'll post if it runs in my project.

Login