3 Replies Latest reply on Jan 27, 2011 12:01 AM by shubham.trivedi

    EP0 OUT Transfers

    bill.olson

      I'm having an issue with EP0BUF.  Is it double buffered?

         

      I've written a few control endpoint vendor functions to handle some low load functions in our firmware (transferring a few bytes).  I've got most of the functions working which just do a single read, read two bytes, a write followed by a read, etc.  Only one of these functions uses data from the PC in EP0BUF.

         

      I have a switch statement which parses SETUPDAT[1].  The part that reads EP0BUF is here:

         

               case VR_WRITE_N:
                  //Write n bytes, buffer has data, addr, data, addr
                  //wValue = 0,0                SETUPDAT[3],SETUPDAT[2]
                  //wIndex = 0, 0                SETUPDAT[5],SETUPDAT[4]
                  //wLength = 0, len            SETUPDAT[7],SETUPDAT[6]
                  for(i=0;i<SETUPDAT[6]; i++)
                  {
                      dat = *(EP0BUF+i);
                      addr = *(EP0BUF+i+1);
                      i++;
                      WriteByte(dat,addr);
                      IOA = i;
                  }
                  EP0BCH = 0;
                  EP0BCL = 0; // Arm endpoint with # bytes to transfer
                  EP0CS |= bmHSNAK; // Acknowledge handshake phase of device request
                  break;
       

         

      WriteByte just sets addr to Port C and dat to Port B and then does a write cycle on a proprietary data bus connected to those ports.

         

      The data that goes out on the bus is always one cycle old.  For example:

         

      1) Start device and initialize
      2) PC writes several bytes to EP0 with vendor code VR_WRITE_N
      3) First time, data out on the bus is random garbage
      4) PC writes another set of bytes to EP0 with VR_WRITE_N
      5) Data on the bus is the first data set sent.

         

      WriteByte works because I use it for the single byte write functions which pass the address and data in wValue and wIndex and doesn't use EP0BUF.  The only time I see a problem is with the VR_WRITE_N function.  How do I get EP0BUF to have the latest data from the PC?

         

      Bill

        • 1. Re: EP0 OUT Transfers
          shubham.trivedi

          Bill,

             

          No, EP0 is not double buffered but it has seperate buffers for IN and out data transfers.

             

           

             

          I believe the problem you are facing is because as soon as you send the vendor command the case statement is triggered but still the data buffer is not updated hence it takes the old value.

             

          There can be many alternative ways to avoid this , you may issue first a vendor command to just send the data and then issue another vendor command consecutively to send data to the ports.

             

          -shub

          • 2. Re: EP0 OUT Transfers
            bill.olson

            OK, that makes sense.  It looks like the SETUPDAT array gets filled first.  I inserted a call to SYNCDELAY before reading EP0BUF and it now works.  There is sort of a race condition going on though.  It would be nice if there was a buffer ready bit.

               

            Thanks,
            Bill

            • 3. Re: EP0 OUT Transfers
              shubham.trivedi

              Great, Happy to hear that it worked.

                 

              -shub