cy7c67200 bulk read(10) on embedded host

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

cross mob
Anonymous
Not applicable

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.

0 Likes
1 Solution
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

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

Hemanth

View solution in original post

0 Likes
7 Replies
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hello Matthias,

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

pastedImage_0.png

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

Hemanth
0 Likes
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

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:

pastedImage_0.png

Regards,

Hemanth

Hemanth
0 Likes
Anonymous
Not applicable

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

0 Likes
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

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:

pastedImage_0.png

Regards,

Hemanth

Hemanth
0 Likes
Anonymous
Not applicable

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 😎

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

0 Likes
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

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

Hemanth
0 Likes
Anonymous
Not applicable

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

0 Likes