lpcware

Please help me understand LPCopen CDC example

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by abonent on Sun Jan 25 12:50:14 MST 2015
Hello.
I'm using this http://www.embeddedartists.com/products/boards/lpc11u35_qsb.php board, plus LPC-Link2 and LPCXpresso v7.5.0 [Build 254] [2014-10-31] for my experiments.
I took LPCopen package http://www.lpcware.com/system/files/lpcopen_v2_03_lpcxpresso_nxp_lpcxpresso_11u37h.zip and imported nxp_lpcxpresso_11u37_usbd_rom_cdc, nxp_lpcxpresso_11u37h_board_lib and lpc_chip_11uxx_lib projects. I built it successfully and flashed on the board. The board enumerated as CDCserial device and I was able to talk to it using serial terminal, strings sent to it were correctly echoed back. So far everything OK.

When my mainline code looks like this:

while (1)
{
//dly_ms(1);
LPC_GPIO->NOT[0]  = (1<<7);
if (vcom_connected() != 0)
{
rdCnt = vcom_bread(&g_rxBuff[0], 256);
if (rdCnt)
vcom_write(&g_rxBuff[0], rdCnt);
}
}

all data are correctly echoed. However, once I uncomment the dly_ms function (doing simple delay loop for approximately 1ms), most of the characters is missing. From message "Hello world" I usually receive only "d" or "ld" characters.
I plan to use the LPC device to process data from stream od characters and the delay represents time delay caused by data processing. I expect the incomming data to be NAK-ed while the LPC is busy with data processing (should be done in USB interrupts) and I don't care about slow data transfer, but lost data is problem. I put breakpoint at the vcom_write function and the received data (to send back to PC) is the one or two symbols I receive in terminal, so it looks like the data is lost at the receiving part of code.
I took a look at vcom_bread function and it looks like it just reads data from pVcom structure, filled by VCOM_bulk_out_hdlr handler and it looks a bit more complicated and honestly I don't understand it much:

/* VCOM bulk EP_OUT endpoint handler */
static ErrorCode_t VCOM_bulk_out_hdlr(USBD_HANDLE_T hUsb, void *data, uint32_t event)
{
VCOM_DATA_T *pVcom = (VCOM_DATA_T *) data;
switch (event) {
case USB_EVT_OUT:
pVcom->rx_count = USBD_API->hw->ReadEP(hUsb, USB_CDC_OUT_EP, pVcom->rx_buff);
if (pVcom->rx_flags & VCOM_RX_BUF_QUEUED) {
pVcom->rx_flags &= ~VCOM_RX_BUF_QUEUED;
if (pVcom->rx_count != 0) {
pVcom->rx_flags |= VCOM_RX_BUF_FULL;
}

}
else if (pVcom->rx_flags & VCOM_RX_DB_QUEUED) {
pVcom->rx_flags &= ~VCOM_RX_DB_QUEUED;
pVcom->rx_flags |= VCOM_RX_DONE;
}
break;
case USB_EVT_OUT_NAK:
/* queue free buffer for RX */
if ((pVcom->rx_flags & (VCOM_RX_BUF_FULL | VCOM_RX_BUF_QUEUED)) == 0) {
USBD_API->hw->ReadReqEP(hUsb, USB_CDC_OUT_EP, pVcom->rx_buff, VCOM_RX_BUF_SZ);
pVcom->rx_flags |= VCOM_RX_BUF_QUEUED;
}
break;
default:
break;
}
return LPC_OK;
}

I see that when OUT event on givent endpoint happens, the pVcom->rx_buff is overwritten by new data, regardless whether it was read or not. Honestly, I don't understand the meaning of flags VCOM_RX_BUF_QUEUED, VCOM_RX_BUF_FULL, VCOM_RX_DB_QUEUED and VCOM_RX_DONE, as well as what the handler actually does. I looked into documentation and it was quite sparse

static ErrorCode_t VCOM_bulk_out_hdlr ( USBD_HANDLE_T  hUsb,
void *  data,
uint32_t  event
)
static

Definition at line 65 of file cdc_vcom.c.

and explanation of the flags I just can't find.

TLDR version: I have no idea why my data are lost when I don't read it very often from main loop. The documentation didn't help me much.

Could anybody, please, help me with understanding why the data from OUT transaction are lost when vcom_bread function is not called often and how to fix the code?

Outcomes