USB VCOM data transmission problem..

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

USB VCOM data transmission problem..

1,028 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ranaya on Thu Jul 12 01:01:14 MST 2012
hi all......

   Im using lpc1769 xpresso board to communicate with pc c# host application using usb cdc class. At the pc side the port is enumerated as com 11 a virtual port.

   Here Im reading 64 byte data blocks from an SD card and send them to the host via usb connection. Communication is almost successful. But i need to synchronize the data coming from the MCU. I use serial port event handler in c# to acquire the data from the inbuffer. Text file in the sd card has the data sequence like :

0.00
1.00
.
.
49.00
0.00
.
.

at each time i press a button in c# form these values will be displayed. when the serial port event triggers ( i think after reading 64 bytes)the result in the console is:
0.00
1.00
2.00...  //this sequence is correct
...9.00
10.
         //11.00, 12.00 and 13.00 missing
14.00
15.00 

and like this :
37.00
38.

42.00
43.00 

after each reading I noticed there's a gap of 4 integers, 10 - 14 and 38 - 42 ! I think the problem occurs inside the mcu. Here my codes -

}

else if(serBuf[0]=='s'){//when press a button (each time) in c# command 's'sent to              
                        //serial buff

  if(f_eof(&File)== 0){
   res = f_read(&File, serBuf, strlen(serBuf), &br);
     USB_WriteEP(CDC_DEP_IN,(unsigned char *)&serBuf[0],61);
    delayMs(0,1);

  }else{
        res = f_close(&File);   //reach file end
        GPIO_SetValue(0,1<<22);
        for(j = 1000000; j > 0; j--);
        GPIO_ClearValue(0,1<<22);
  }

}



USB_WriteEP code :
uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) {
  uint32_t n;
  LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
  LPC_USB->TxPLen = cnt;
  for (n = 0; n < (cnt + 3) / 4; n++) {
    LPC_USB->TxData = *((__attribute__((packed)) uint32_t *)pData);
    pData += 4;
  }
  LPC_USB->Ctrl = 0;
  WrCmdEP(EPNum, CMD_VALID_BUF);
  return (cnt);
}



Serial port settings:
CDC_LINE_CODING CDC_LineCoding  = {115200, 1, 0, 8};
//baud, number of stop bit, parity, data bits



c# serial port settings :
[IMG]https://dl.dropbox.com/u/16049803/untitledgg3.JPG[/IMG]

Helps and ideas woud be appreciated
0 Kudos
Reply
2 Replies

920 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ranaya on Sat Jul 14 07:42:42 MST 2012
Hi... thanx for well explained response :)

It was another problem that I coudnt send more than 64 bytes. Thanx alot
0 Kudos
Reply

920 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Thu Jul 12 18:57:45 MST 2012
Using endpoint interrupt callback (CDC_BulkIn()), your firmware can send longer file than 64 bytes.
The send_file process starts in your firmware, as follows. It just sets up flags, and kick the EP interrupt manually.

volatile uint8_t cdc_send_file = FALSE;
volatile uint8_t cdc_send_ZLP  = FALSE;

...
else if(serBuf[0]=='s'){//when press a button (each time) in c# command 's'sent to              
                        //serial buff
  if ( ! cdc_send_file ) {
    //
    // open the target file, here
    //
    cdc_send_ZLP  = FALSE;                               // start send_file process
    cdc_send_file = TRUE;
    LPC_USB->EpIntSet = (1 << EPAdr(CDC_DEP_IN));        // kick EP interrupt manually
  }


The body of the send_file process is implemented in the EP interrupt callback

cdcuser.c

#define CDC_BULK_MAX_PACKET_SIZE  64
extern volatile uint8_t cdc_send_file;
extern volatile uint8_t cdc_send_ZLP;

void CDC_BulkIn(void) {
  uint32_t br;

  if ( cdc_send_file ) {                                 // send_file process is going on
    if( f_eof( &File ) ) {                               // if entire file has been sent out,
      if ( cdc_send_ZLP ) {                              // if the last transaction is full-size,
        cdc_send_ZLP = FALSE;
        USB_WriteEP( CDC_DEP_IN, NULL, 0 );              // send ZLP to terminate the transfer
      } else {
        f_close( &File );                                // finish file send session
        cdc_send_file = FALSE;
      }
    } else {                                             // send a transaction from the file
      f_read( &File, serBuf, CDC_BULK_MAX_PACKET_SIZE, &br );
      USB_WriteEP( CDC_DEP_IN, serBuf, br );
      cdc_send_ZLP = ( br == CDC_BULK_MAX_PACKET_SIZE ); // is full-size transaction?
    }
  }
} 



Lastly, the context (variables) is initialized in Set_Configuration callback.

usbuser.c

/*
 *  USB Set Configuration Event Callback
 *   Called automatically on USB Set Configuration Request
 */

#if USB_CONFIGURE_EVENT

extern volatile uint8_t cdc_send_file;
extern volatile uint8_t cdc_send_ZLP;

void USB_Configure_Event (void) {

  if (USB_Configuration) {                  /* Check if USB is configured */
    /* add your code here */

    cdc_send_file = FALSE;                               // initialize context
    cdc_send_ZLP  = FALSE;
    
  }
}
#endif


Tsuneo
0 Kudos
Reply