6 Replies Latest reply on Apr 25, 2013 12:03 PM by dennis.muhlestein

    EP0 Read intermittently overwrites buffer.

    dennis.muhlestein

       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?    
         
        • 1. Re: EP0 Read intermittently overwrites buffer.
          kalev.sildaru

          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

          • 2. Re: EP0 Read intermittently overwrites buffer.
            dennis.muhlestein

             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.   
            • 3. Re: EP0 Read intermittently overwrites buffer.
              dennis.muhlestein

               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[i] );

                 

               

                 

               

                 

              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?

              • 4. Re: EP0 Read intermittently overwrites buffer.
                kalev.sildaru

                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

                • 5. Re: EP0 Read intermittently overwrites buffer.
                  dennis.muhlestein

                   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.

                  • 6. Re: EP0 Read intermittently overwrites buffer.
                    david.austin

                    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.