EP0 Read intermittently overwrites buffer.

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

 I have the following code in a vendor command handler:

   

 

   

  log_debug ( "gRdwrCmd buffer: %d\n" , gRdwrCmd.ep_buffer_size );

   

  status = CyU3PUsbGetEP0Data(wLength, (uint8_t *) &(gRdwrCmd.header), &debug_datasize);

   

  if (!gRdwrCmd.ep_buffer_size) {

   

    log_error ( "gRdwrCmd buffer: %d wLength %d data read: %d\n" , gRdwrCmd.ep_buffer_size, wLength, debug_datasize );

   

  }

   
     gRdwrCmd is a struct that holds the necessary information for us to handle correctly the vendor command we're processing.  The contents of the vendor command are copied into the struct as sent from the host.   
   
        
   
    The ep_buffer_size has been set up previously in the Application Start with CyU3PUsbGetSpeed.  Pretty similar to how all the samples work.   
   
        
   
    Most of the time this prints the buffer size is 512, then it doesn't print anything and it all works.   
   
    Now and then (sometimes it gets in a state where it does it all the time) it prints the buffer size is 512, but then after the EP0Data read it prints the buffer size is 0.  The ep_buffer_size param is a couple data members after the header portion of the struct.  In this case, it prints that wLength is 11 and the debug_datasize is also 11, but apparently more than 11 bytes were written?   
   
        
   
    I've added a hack around this to make it so my later calls setting up the ep buffers for transport don't error out when I pass in an invalid buffer size.  Here is the output as seen on my serial console:   
   
        
   
    
     gRdwrCmd buffer: 512    
    
     gRdwrCmd buffer: 0 wLength 11 data read: 11    
    
          
    
     Any thoughts what could be causing this?    
   
0 Likes
6 Replies
Anonymous
Not applicable

Hi dennisjm,

Could it be data caching issue?

Do you enable data caching in CyU3PDeviceCacheControl call? Is "gRdwrCmd.header" aligned to 32-byte boundary? Where is "gRdwrCmd.ep_buffer_size" located relative to "gRdwrCmd.header"?

br,

kalev

0 Likes
Anonymous
Not applicable

 We call this right after we call DeviceInit and before we config the IO Matrix:

   

CyU3PDeviceCacheControl (CyTrue, CyTrue, CyTrue);

   

Our struct looks like this:

   

   

typedef struct {

   

  rdwr_data_header_t header;   // current command

   

  io_handler_t *handler;       // current io_handler

   

  uint16_t ep_buffer_size;     // usb end point buffer size

   

  uint8_t done;                // has this command been handled?

   

} rdwr_cmd_t;

   
    The instance of our rdwr_cmd is simply declared as a global in one of the files where it is used.  I haven't done anything to ensure it is 32 byte aligned.   
0 Likes
Anonymous
Not applicable

 Here is some more fodder...

   

I replaced our struct memory with a tmp_buffer of ~256 bytes.  

   

Code:

   

   

 uint8_t tmp_buffer[sizeof(rdwr_data_header_t)+256];

   

   

CyU3PMemSet ( tmp_buffer, 0xa5, sizeof(tmp_buffer));

   

   

status = CyU3PUsbGetEP0Data(wLength, tmp_buffer+4, &debug_datasize );

   

  for (i=0;i<sizeof(tmp_buffer);++i)

   

      log_debug ( "%d ", tmp_buffer );

   

   

   

Called the VC twice.  You can see the first time it seems appropriate:

   

165 165 165 165 1 2 0 0 0 0 0 2 0 0 0 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 

   

The 2nd time what up?  That's about 21 extra bytes.

   

165 165 165 165 1 2 0 0 0 0 0 2 0 0 0 64 0 0 0 0 0 0 0 0 200 101 2 64 160 58 1 64 16 235 0 64 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 165 

   

Like I was saying before.  A lot of the time it works correctly.  I don't what I might ought to change to avoid this behaviour.

   

Here is some bytes from the next few failures:

   

1 2 0 0 0 0 0 2 0 0 0 64 80 124 2 64 80 125 2 64 20 104 2 64 0 0 0 0 3 0 0 0

   

1 2 0 0 0 0 0 2 0 0 0 96 80 104 2 64 0 0 0 0 192 101 2 64 80 125 2 64 20 104 2 64

   

1 2 0 0 0 0 0 2 0 0 0 64 80 124 2 64 80 125 2 64 20 104 2 64 0 0 0 0 3 0 0 0

   

1 2 0 0 0 0 0 2 0 0 0 64 80 124 2 64 80 125 2 64 20 104 2 64 0 0 0 0 3 0 0 0

   

A side note, 11 bytes + 21 extra is 32.  Is it possible there is an undocumented minimum read size?

0 Likes
Anonymous
Not applicable

Hi  dennisjm,

   

Read description of CyU3PDeviceCacheControl. CyU3PUsbGetEP0Data invalidates cache lines where data will be returned and that's why your 165s are not preserved.

   

Br,

   

kalev

0 Likes
Anonymous
Not applicable

 Ok, that makes sense.  So it seems there isn't a way to read directly into the header unless you're not using the dma cache.  For now I'll use a 32 byte aligned buffer and just memcpy the relevant bits into the header.

   

Thanks for pointing that out I figured there was some tidbit in the reference I hadn't yet gleaned.

0 Likes
Anonymous
Not applicable

CyU3PUsbGetEP0Data invalidates cache lines where data will be returned

   

Just one question: why the F**K isn't this documented in the API guide??
 

   

The FX3 is a neat product but time and time again the doco is crap.

0 Likes