- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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(at | 0x734) |
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.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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-Type | Value |
---|---|
SETUP | D |
IN | 9 |
OUT | 1 |
DATA0 | 3 |
DATA1 | B |
I will try the changes you suggested and let you know if i have success with it. Thank you very much.
Best regards Matthias
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 |
DataTransferLength | 0x200 |
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 😎
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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