ROM_USB_cdc Example for LPC1347

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ROM_USB_cdc Example for LPC1347

1,220 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ECamino on Fri Sep 28 13:57:54 MST 2012
Hi,

I am running the LPC1347 demo board with the project ROM_USB_cdc from NXP_LPC1347_2012_02_22.zip in my \\\nxp\LPCXpresso_4.2.3_292\lpcxpresso\Examples\NXP\LPC1000\LPC13xx_12bitADC

I build with [B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]#define[/COLOR][/SIZE][/COLOR][/SIZE][/B][SIZE=2] UART_BRIDGE 1 [/SIZE]defined and the bridge program works OK.

I build without the define and I'm trying to ping pong a byte from Hyperterm. When I run the program, my USB protocol analyzer catches the out report with the key I typed. The problem is the in report.

[SIZE=2][COLOR=#000080][SIZE=3][COLOR=#000080]URB [B]Bulk or Interrupt Transfer [/B]issued[/COLOR][/SIZE]
[/COLOR][/SIZE][B][SIZE=1][SIZE=3]Device Object [/SIZE][/SIZE][/B][SIZE=1][SIZE=3]USBPDO-6[/SIZE]
[B][SIZE=3]Driver Object [/SIZE][/B][SIZE=3]usbuhci[/SIZE]
[B][SIZE=3]URB Function [/SIZE][/B][SIZE=3]URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER[/SIZE]
[B][SIZE=3]Endpoint 82h [/SIZE][/B][SIZE=3]2 In, Bulk[/SIZE]
[B][SIZE=3]Buffer Length [/SIZE][/B][SIZE=3]1000h (4096)[/SIZE]

[SIZE=3]The buffer length should only be a byte as the Zero-Copy Data Transfer model is being used?[/SIZE]

[SIZE=3]Here's the demo code as supplied:[/SIZE]


[SIZE=3][COLOR=#005032][COLOR=#005032]ErrorCode_t[/COLOR][/COLOR][/SIZE][COLOR=#005032]
[LEFT][/COLOR][SIZE=3][B]VCOM_bulk_in_hdlr[/B]([COLOR=#005032][COLOR=#005032]USBD_HANDLE_T[/COLOR][/COLOR] hUsb, [B][COLOR=#7f0055][COLOR=#7f0055]void[/COLOR][/COLOR][/B]* data, [COLOR=#005032][COLOR=#005032]uint32_t[/COLOR][/COLOR] event) [/SIZE][/LEFT]

[LEFT][SIZE=3]{[/SIZE][/LEFT]

[SIZE=3][LEFT][COLOR=#3f7f5f][COLOR=#3f7f5f]// VCOM_DATA_T* pVcom = (VCOM_DATA_T*) data;[/COLOR][/COLOR][/SIZE]
[LEFT][SIZE=3][COLOR=#3f7f5f][COLOR=#3f7f5f]// Not needed as WriteEP() is called in VCOM_usb_send() immediately. [/COLOR][/COLOR][/SIZE][COLOR=#3f7f5f]
[SIZE=3][COLOR=#3f7f5f]// if (event == USB_EVT_IN) {[/COLOR][/SIZE]
[SIZE=3][COLOR=#3f7f5f]// }[/COLOR][/SIZE]
[/COLOR][SIZE=3][B][COLOR=#7f0055][COLOR=#7f0055]return[/COLOR][/COLOR][/B][I][COLOR=#0000c0][COLOR=#0000c0]LPC_OK[/COLOR][/COLOR][/I];[/SIZE][/LEFT]
[/LEFT]



[LEFT][SIZE=3]}[/SIZE][/LEFT]


[LEFT][SIZE=3][B][COLOR=#7f0055][COLOR=#7f0055]void[/COLOR][/COLOR][/B][/SIZE][/LEFT]
[SIZE=3][SIZE=2]

[LEFT][SIZE=3][B]VCOM_usb_send[/B]([COLOR=#005032][COLOR=#005032]VCOM_DATA_T[/COLOR][/COLOR]* pVcom)[/SIZE][/LEFT]

[LEFT][SIZE=3]{[/SIZE]

[COLOR=#3f7f5f][SIZE=3][COLOR=#3f7f5f]/* data received send it back */[/COLOR][/SIZE][/COLOR]
[LEFT][SIZE=3]pVcom->[/SIZE][/LEFT]
[/LEFT]




[LEFT][SIZE=3][COLOR=#0000c0][COLOR=#0000c0]txlen[/COLOR][/COLOR] -= pUsbApi->[COLOR=#0000c0][COLOR=#0000c0]hw[/COLOR][/COLOR]->[COLOR=#0000c0][COLOR=#0000c0]WriteEP[/COLOR][/COLOR] (pVcom->[COLOR=#0000c0][COLOR=#0000c0]hUsb[/COLOR][/COLOR], USB_CDC_EP_BULK_IN,[/SIZE][/LEFT]

[LEFT][SIZE=3]pVcom->[COLOR=#0000c0][COLOR=#0000c0]txBuf[/COLOR][/COLOR], pVcom->[COLOR=#0000c0][COLOR=#0000c0]txlen[/COLOR][/COLOR]);[/SIZE][/LEFT]

[LEFT][SIZE=3]}[/SIZE][/LEFT]

[LEFT][SIZE=2][SIZE=3]Why is the incorrect buffer size being sent? [/SIZE][/SIZE][/LEFT]

[LEFT][SIZE=2][SIZE=3]What would I have to do to ping pong data on the USB endpoints from Hyperterm? [/SIZE][/LEFT]
[/SIZE][/SIZE][/SIZE]

[/SIZE]
0 Kudos
Reply
8 Replies

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ECamino on Wed Oct 03 10:29:50 MST 2012
Hi,

I ran into a problem running the original demo program with #define UART_BRIDGE 1.  It seems that after the first character is sent and then returned, the endpoint just continuously floods with a transfer on EP 2 in.  There is no data sent though.  I stepped through and see that [SIZE=2][B]VCOM_bulk_in_hdlr()[/B] [SIZE=3]is continuously being called after the first byte is sent and received[/SIZE][B].[/B]  [SIZE=3]Why is that happening if there is no data being sent?[/SIZE]
[/SIZE]
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ECamino on Tue Oct 02 07:54:45 MST 2012
I added the code you provided and now it works fine!

Thanks for all the help, Tsuneo!
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Tue Oct 02 07:25:14 MST 2012
When UART_BRIDGE is not define,
in VCOM_bulk_out_hdlr(), this CDC example calls pVcom->send_fn() (ie. VCOM_usb_send()) without copying data from RX buffer to TX one. It causes the trouble. Here is fix.


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:

      if (pVcom->rxlen == 0) {
        pVcom->rxlen = pUsbApi->hw->ReadEP(hUsb, USB_CDC_EP_BULK_OUT, pVcom->rxBuf);

                                                          [COLOR=Red]// <--- insert these lines, from here[/COLOR]
#if !defined( UART_BRIDGE )
        {
          uint16_t idx;
                                              // move data from RX buffer to TX buffer
          for ( idx = 0; idx < pVcom->rxlen; idx++ ) {
            pVcom->txBuf[pVcom->txlen++] = pVcom->rxBuf[idx];
          }
          pVcom->rxlen = 0;
        }
#endif
                                                          [COLOR=red]// <--- to here[/COLOR]
        pVcom->send_fn(pVcom);
      } else {
        /* indicate bridge write buffer pending in USB buf */
        pVcom->usbrx_pend = 1;
      }
      break;
    default: 
      break;
  }
  return LPC_OK;
}


Another potential problem is,
This firmware initializes buffer parameters just in the response of Set_Line_Coding request (VCOM_SetLineCode())
The parameters should be initialized in Set_Configuration, too.


ErrorCode_t USB_Configure_Event (USBD_HANDLE_T hUsb) {

  USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb;
  if (pCtrl->config_value) {                   /* Check if USB is configured */
    g_vCOM.ser_pos = 0;                   // initialize buffer parameters
    g_vCOM.rxlen = g_vCOM.txlen = 0;
  }
  return LPC_OK;
}

int main (void)
{
  ...
  ...
  ...

  /* initilize call back structures */
  memset((void*)&usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
  usb_param.usb_reg_base = LPC_USB_BASE;
  usb_param.mem_base = 0x10001000;
  usb_param.mem_size = 0x1000;
  usb_param.max_num_ep = 3;

  usb_param.USB_Configure_Event = USB_Configure_Event;    // <-------- register above callback



Tsuneo
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ECamino on Mon Oct 01 08:39:55 MST 2012
[SIZE=2][COLOR=#7f0055][COLOR=black]Hi, I see what problem was. To make characters bounce between the endpoints and using Hyperterm, I modified the code like this:[/COLOR][/COLOR][/SIZE][COLOR=#7f0055]


[SIZE=2][B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]void
[/COLOR][/SIZE][/COLOR][/SIZE][/B][LEFT][SIZE=2][COLOR=#000000][B]VCOM_usb_send[/B]([/COLOR][/SIZE][SIZE=2][COLOR=#005032][SIZE=2][COLOR=#005032]VCOM_DATA_T[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#000000]* pVcom)[/COLOR][/SIZE]
[LEFT][SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#005032][SIZE=2][COLOR=#005032]ErrorCode_t[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] foo;[/SIZE][/LEFT]

[LEFT][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* loop endpoint data */[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#3f7f5f][/LEFT]
[/COLOR][/SIZE]
[LEFT][SIZE=2]pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txlen[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]rxlen[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]*pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txBuf[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = *pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]rxBuf[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];[/SIZE][/LEFT]


[LEFT][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]/* data received send it back */[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#3f7f5f]
[/COLOR][/SIZE][SIZE=2]foo = pVcom->[/LEFT]
[/LEFT]
[/SIZE][LEFT][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txlen[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] -= pUsbApi->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]hw[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]WriteEP[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] (pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]hUsb[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], USB_CDC_EP_BULK_IN, pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txBuf[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txlen[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);[/SIZE]

[SIZE=2]}[/SIZE]

[SIZE=2][COLOR=black]foo returns LPC_OK.[/COLOR][/SIZE]

[SIZE=2][COLOR=black]But only the first character works, and any keypresses after the first one don't come through. So I stepped through the code stopping at the end of VCOM_usb_send() [/COLOR][/SIZE]
[SIZE=2][COLOR=black]and at the end of VCOM_bulk_out_hdlr(). The second break was never reached so I breaked at the begining of VCOM_bulk_out_hdlr() and stepped through. The problem is the return to main. The program aborts with this message:[/COLOR][/SIZE]

[SIZE=2][COLOR=#7f0055][SIZE=3][COLOR=#000000]15: Target error from Set break/watch[/COLOR][/SIZE]
[SIZE=3][COLOR=#000000]Invalid address for HW Execution break.[/COLOR][/SIZE]

[SIZE=3][COLOR=#000000]What causes this error?[/COLOR][/SIZE]

[SIZE=3][COLOR=#000000]EC[/COLOR][/SIZE]
[/COLOR][/SIZE][/SIZE][/COLOR][SIZE=2]
[/SIZE]
[/LEFT]
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ECamino on Mon Oct 01 06:08:17 MST 2012
Thanks, Tsuneo!

When I have:

#define UART_BRIDGE 1

The loop back works great when tying RX and TX together.

When I have:

//#define UART_BRIDGE 1 (not defined)

Then I don't tie the RX and TX. I verified there is no signal on TX.

But I thought I would be able to loop through the USB endpoints via Hyperterm as a virtual com. That part isn't completely working. I have the ep out sending chars, but the in report does not get sent or get through.

in VCOM_usb_send, I added these first two lines below:

[LEFT][SIZE=2][COLOR=#3f7f5f][SIZE=2][COLOR=#3f7f5f]uint8_t TXbyte = 'g';[/COLOR][/SIZE][/LEFT]
[SIZE=2][COLOR=#3f7f5f]pVcom->txBuf = &TXbyte;[/COLOR][/SIZE]


[SIZE=2][COLOR=#3f7f5f][SIZE=2]pVcom->
[/SIZE][LEFT][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txlen[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] -= pUsbApi->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]hw[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]WriteEP[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] (pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]hUsb[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], USB_CDC_EP_BULK_IN,[/SIZE]
[SIZE=2]pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txBuf[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], pVcom->[/SIZE][SIZE=2][COLOR=#0000c0][SIZE=2][COLOR=#0000c0]txlen[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);[/SIZE]

[SIZE=3][COLOR=black]I step through the code and I can see that *txBuf has 'g'. But why is there nothing getting through ep 2 in to Hyper?[/COLOR][/SIZE]

[SIZE=3][COLOR=#000000]After this, any other keypress takes 2 seconds to get sent out - like it's hangging somewhere and timing out?[/COLOR][/SIZE]

[SIZE=3][COLOR=#000000]EC[/COLOR][/SIZE]
[/COLOR][/SIZE][/COLOR][/SIZE]
[/LEFT]
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Sat Sep 29 18:53:31 MST 2012

Quote:
But the real problem seems to be that after that last sniffer report, nothing is sent on the in pipe. It looks like WriteEP() not sending the buffer data?


Ya. It is a reasonable estimation.


Quote:
Since I'm running the unmodified demo code on a stock LPCXpresso board,


Did you tie the UART TX and RX ports together on the board?
On the example, TX and RX work independently.
To see loopback on the PC terminal software, you have the loopback circuit at there.

Tsuneo
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ECamino on Sat Sep 29 05:16:38 MST 2012
Thanks, Tsuneo.   I thought the problem was that the buffer length was reported wrong.
 
But the real problem seems to be that after that last sniffer report, nothing is sent on the in pipe.  It looks like WriteEP() not sending the buffer data?  After that, any keypresses result in out reports being canceled?  Since I'm running the unmodified demo code on a stock LPCXpresso board, could the problem be in the PC settings?
0 Kudos
Reply

1,146 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Sat Sep 29 04:15:27 MST 2012

Quote:
The problem is the in report.

Buffer Length 1000h (4096)

The buffer length should only be a byte as the Zero-Copy Data Transfer model is being used?


There is nothing so odd.
You are seeing sniffer report on your PC.
It shows the URB (USB Request Block) parameters, requested by the PC class driver (in this case, usbser.sys: CDC driver) at the IN pipe. That is, usbser.sys always requests 4096 bytes for bulk IN transfer. After this record, you'll find a completion record for this URB, which indicates the exact number, sent by the device.

Host doesn't know the exact transfer size, until device finishes the transfer. In this reason, usbser.sys requests greater number of bytes in advance. Device is allowed to put less or equal size of data than this number. Also, it is the reason for the requirement of ZLP (Zero-Length Packet) to terminate bulk IN transfer of CDC.

I've explained about transfer termination in this post.
It helps you to realize what is going on here.
http://www.cygnal.org/ubb/Forum9/HTML/001627.html

Tsuneo
0 Kudos
Reply