7 Replies Latest reply on Jul 9, 2018 9:27 AM by user_3406851

    cy7c67200 bulk read(10) on embedded host

      Hello I use the cy7c67200 (EZ-OTG) on a fpga (Altera DE2-115). I successfully implemented The enumeration process with help of the document "Using HPI in Coprocessor mode with OTG-Host -AN6010"

      and want to read now some data from a usb flash drive.

      But i have issues on that. Im not fully sure if I understand right how to do that, sadly i didnt found any examples which don't use high level frameworks and

      where i can see how i send CBWs (command block wrapper) and how i receive the CSW (Command Status Wrapper).

      Thats why i like to describe how i do it in the hope someone can tell me if I do it right in general .

      What i do is: i issue a bulk reset.

      Then i write a setup TD (Transfer Descriptor) which points with its BaseAddr to the CBW content.

      CBW (on position 0x50C):

      Signature:0x43425355
      Tag:   0xfefefeed

      DataTransferLength 0x200

      Flags: 0x80
      Lun:   0x0
      Length:0xa

      CDB: 28 00 00 00 00 00 00 00 08 00

       

      My wMaxPacketSize as reported by the endpoint descriptor is 64 so i think I have to define the length in the CDB as 8 if i want 512bytes?

       

       

      TD (at position 0x500):

      base_addr: 0x50c

      port_length:  0x1c

      pid_ep:       0x12

      dev_addr:     0x2

      ctrl_reg:     0x41

      status:       0x0

      retry_cnt:    0x1b

      residue:      0x0

      next_td_addr: 0x528

       

      Then i write a (data) TD with PID_IN and point with the BaseAddr where i want the data should be written.

       

      TD (at 0x528)

      base_addr: 0x534

      port_length:  0x200

      pid_ep:       0x91

      dev_addr:     0x2

      ctrl_reg:     0x1

      status:       0x0

      retry_cnt:    0x1b

      residue:      0x0

      next_td_addr: 0x734

       

      Then i write a (status) TD which points with BaseAddr where i want to read the CSW

      TD(at0x734)

      base_addr: 0x740

      port_length:  0x0

      pid_ep:0x11
      dev_addr:0x2
      ctrl_reg:0x1
      status:0x0
      retry_cnt:0x1b
      residue:0x0

      next_td_addr: 0x0

       

      Then i set the CurrentTDPointer to 500 and wait until the HPI_STATUS register reports TDListDone.

      Then i read the data buffer at 0x534 where I expect the content from my usb device and i read the content

      from 0x740 where i expect my CSW content.

       

      But the data contains garbage, the csw signature for example is wrong and the csw tag is not equal to the value in my cbw.

      Also the data which should be the 512 bytes of the flashdrive from LBA: 0 are not identical with the contents from the flashdrive.

        • 1. Re: cy7c67200 bulk read(10) on embedded host
          HemanthR_06

          Hello Matthias,

           

          The CDB structure of READ 10 CBW command looks like below:

          Where, the transfer length would mean below:

          The TRANSFER LENGTH field specifies the number of contiguous logical blocks of data that shall be read and transferred to the data-in buffer, starting with the logical block specified by the LOGICAL BLOCK ADDRESS field. A TRANSFER LENGTH field set to zero specifies that no logical blocks shall be read.

           

          So in your case you put transfer length as 0x0008.

           

          Note that each logical block would indicate 512 bytes.

          So, your transfer length would indicate 8*512 = 4KB of data.

           

          Please correct this and check.

           

          Also let me know what what is port_length and why it is put as 0x1C at position 0x500.

           

          Regards,

          Hemanth

          • 2. Re: cy7c67200 bulk read(10) on embedded host
            HemanthR_06

            Hello Matthias,

             

            Few more inputs:

            - As per the above comment, the transfer field in your cdb structure should be changed from 0x0008 to 0x0001 if you want to read 512 bytes.

            - And I noticed pid_ep for the out endpoint is 0x12 - I assume you mean to indicate endpoint number 2 which is out endpoint. In that case you need to change it to 0x02

            Similarly the pid_ep field for in endpoint is 0x91. Please change it to 0x81

            - For the status phase you have given 0x11 for pid_ep field which also needs to be changed to 0x81.

             

            FYI:

             

            Regards,

            Hemanth

            • 3. Re: cy7c67200 bulk read(10) on embedded host

              Hello hman,

              first of thank you so much for your effort on answering me.

              With the names in my TD i referred to the described data structure in the bios user manual in chapter 3.5

              (http://www.cypress.com/file/43311/download )

              which describes the port_len field as: Port Number /Data Length -

              "The TD data length and port number must be written into Port_Length when submitting a TD."

              DL9-0 - 10 Bit Data Length Value in Binary.

              PN1-0 - 2 Bit Port Number in Binary:

              00 --- Port 0 (Port A)

              01 --- Port 1 (Port B)

              10 --- Port 2 (Port C)

              11 --- Port 3 (Port D)

              With port_len:1C I want to use port 0 with TD length of 1C (28) which is the length of the cbw with the cdb.

               

              The pid values for pid_ep are defined there as followed:

              PID-TypeValue
              SETUPD
              IN9
              OUT1

              DATA0

              3
              DATA1B

               

              I will try the changes you suggested and let you know if i have success with it. Thank you very much.

               

              Best regards Matthias

              • 4. Re: cy7c67200 bulk read(10) on embedded host
                HemanthR_06

                Hello Matthias,

                 

                Okay. I got what you are referring to.

                In that case,

                - When you send CBW, the PID_EP which you gave as 0x12 is correct.

                - But in the case of CSW transfer, you have put PID_EP as 0x11 which should be 0x91. Please correct this.

                - And one more correction that you need to make: CBW should be 31 bytes in total not 28 bytes so you should replace 0x1C by 0x1F

                FYI:

                 

                Regards,

                Hemanth

                • 5. Re: cy7c67200 bulk read(10) on embedded host

                  Hello Hemanth,

                   

                  I adjusted my code to follow your advices. Additional I noticed that i used in my data TD a data length of 0x200.

                  And send only one data TD. As I read, the data per TD cant be bigger then wMaxPacketSize of the Endpoint descriptor which is 0x40 bytes in my case.

                  So I think i have to send 8 data TD's where each refers to 0x40 bytes of the 512 bytes i want to read?

                   

                  What I try to send is this:

                  CBW at 0x700:

                  Signature:0x43425355
                  Tag:0x1
                  DataTransferLength0x200

                   

                  Flags:0x80
                  Lun:0x0
                  Length:0xa
                  CDB:28 0 0 0 0 0 0 0 1 0

                   

                  Then the TD holding the CBW at 0x500:

                   

                  base_addr: 0x700

                  port_length:  0x1f

                  pid_ep:0x12
                  dev_addr:0x2
                  ctrl_reg:0x41
                  status:0x0
                  retry_cnt:0x1b
                  residue:0x0

                  next_td_addr: 0x50c

                   

                  Then i write 8 data TD's each of them with a length of 0x40

                  at 0x50c: (data 1)

                  base_addr: 0x720

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x41

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x518

                   

                  at 0x518: (data 2)

                  base_addr: 0x760

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x1

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x524

                   

                   

                  at 0x524: (data 3)

                  base_addr: 0x7a0

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x41

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x530

                   

                  at 0x530: (data 4)

                  base_addr: 0x7e0

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x1

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x53c

                   

                  at 0x53c: (data 5)

                  base_addr: 0x820

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x41

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x548

                   

                  at 0x548: (data 6)

                  base_addr: 0x860

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x1

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x554

                   

                  at 0x554: (data 7)

                  base_addr: 0x8a0

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x41

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x560

                   

                   

                  at 0x560: (data 8)

                  base_addr: 0x8e0

                  port_length:  0x40

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x1

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x56c

                   

                  status td for the CSW at 0x56c:

                  base_addr: 0x920

                  port_length:  0x0

                  pid_ep:       0x91

                  dev_addr:     0x2

                  ctrl_reg:     0x1

                  status:       0x0

                  retry_cnt:    0x1b

                  residue:      0x0

                  next_td_addr: 0x0

                   

                  Sadly - If I send that the CSW looks invalid (tag/signature is wrong) also the data i read are not the same as on my

                  flashdrive. So there still seems to be something wrong. Am i right that I have to send multiple data TD's? Thanks again for your effort i appreciate it alots.

                  Do I need to set port_length in status TD to the length of the CSW? (I tried that already but no change). Im also not sure if i do the data toggle handling correct.

                   

                  Best regards Matthias

                  • 6. Re: cy7c67200 bulk read(10) on embedded host
                    HemanthR_06

                    Hello Matthias,

                     

                    Please make one correction:

                    port length for CSW transfer should be changed from 0x0 to 0x0D.

                    Change it and let me know if the CSW is as expected.

                    (If it is right, then we can check on data)

                    And one more question: The maxEndPoint size reported by the endpoint1 (IN) of your mass storage device (not EZ-Host) is 64. Can you confirm this?

                     

                    Regards,

                    Hemanth

                    • 7. Re: cy7c67200 bulk read(10) on embedded host

                      Hello Hemanth,

                       

                      Ok I changed the port_length value of the TD for CSW transfer to 0x0D. Still I did'nt got valid values in my CSW. I can confirm that the maxPacketSize of my Endpoint Descriptor is 64 (0x40). After beginning with different toggle bit I am able now to receive the correct first 512 byte from my flash drive and also get the correct CSW. With toggle bit I mean the 6th bit of the TD's Control byte (ctrl_reg in my traces). Which toggles Data0/Data1.

                      Thank you so much for your help on that.

                       

                      Best regards, Matthias