cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 USB FS Device mode Programing

Jim Chacko
Associate II

Hi.

I am using STM32F407 discovery board programed in USB FS mode. The driver used is WINUSB. mY os IS WINDOWS 10.

I am using USF FS configured as ENDP1 OUT and ENDP1 IN. Both in bulk mode. I was managed to successfully enumerated with PC and managed to send Data from my c# application. But when i try to read , it shows success but zero bytes read.

My sequence of Program is like this

1) Receive bunch od data from ENDP1 OUT Endpoint.

2) Then Prerpare reply in Buffer

3) Write XFRSIZE and PKTCNT

4) Enable CNAK & EPENA

5) Then look for DTXFSTS1 for empty status

6) Fill the FIFO from Buffer

7) exit and wait manin code till ENDP1 XFRC trigger..

Everything looks fine but after XFRC triggered, i look in DTXFSTS1, it shows only 8 bytes reduced from the original count. XFRsize, PKTCNT shows 0.

Hope to receive advise.... Thanks in advance..

11 REPLIES 11

The Synopsys OTG has a fragile internal state machine, and the (already rather messy) description in RM does not necessarily reflect all its requirements. For taster, https://community.st.com/s/question/0D50X00009nKK7wSAG/synopsys-otg-fifo-clash .

In your case, you do have multipacket data size, and write more than DIEPCTL.MPSIZ bytes into the FIFO?

Are you aware that DTXFSTS indicates *words* rather than *bytes*?

You might want to check the data you've written through the debug access to FIFO, at offset 0x20000. However, note, that looking at the registers or at the mailbox address area of the FIFO using debugger will be intrusive.

JW

Hi,

Many thanks for your response. It gave me some insight. I start with single packets means less than 64. Below is my FIFO setting. Yes, I do aware of the DTXFSTS  indicating word count. And also I was debugging the FIFO using direct access at offsets 0x20000. 

Using this debug feature, i understood that the TXFIFO starting address should in words. Am i correct? Below is my FIFO assignment. When i put start address in bytes, then when debug i understood it goes wrong. So when use word then become correct.

I tried to disable the RXFLVL interrupt still i failed to receive from ENDP1 IN. Will you be kind enough to go below my flow and advise where to correct?

1) waiting for RXFLVL ISR

2) decode OTG_FS_GRXSTSP for data packet for ENDP1? if yes write to ENDPI buffer

3) wait for ENDP1 IN XFRC

4) in ENDP1 XFRC i disable RXFLVL. Then decode the received data and prepare ENDP1 buffer

5) Then prepare OTG_FS_DIEPCTL1, OTG_FS_DTXFSTS1

6) enable OTG_FS_DIEPEMPMSK for ENDP1

7) in isr ENDP1 IN i check TXFE and fill TX1buffer and quit.

😎 then wait for XFRC in DIEPNIT1 for host read completion.

When check, i get still zero bytes.. Below is my FIFO assignment.

;--------------------------------------

;USB_FS FIFO [1280 BYTES]

;-------------------------------------

CNST_HWORD_USB_FS_FIFO_RX_START_ADDRESS EQU 0x000

CNST_HWORD_USB_FS_FIFO_RX_SIZE EQU 0x40

CNST_HWORD_USB_FS_FIFO_TXF0_START_ADDRESS EQU 0x040 (???????)

CNST_HWORD_USB_FS_FIFO_TXF0_SIZE EQU 0x10

CNST_HWORD_USB_FS_FIFO_TXF1_START_ADDRESS EQU 0x050 (???????)

CNST_HWORD_USB_FS_FIFO_TXF1_SIZE EQU 0xC0

CNST_HWORD_USB_FS_FIFO_TXF2_START_ADDRESS EQU 0x110 (???????)

CNST_HWORD_USB_FS_FIFO_TXF2_SIZE EQU 0x10

CNST_HWORD_USB_FS_FIFO_TXF3_START_ADDRESS EQU 0x120 (???????)

CNST_HWORD_USB_FS_FIFO_TXF3_SIZE EQU 0x10

CNST_HWORD_USB_FS_FIFO_HPTXF_START_ADDRESS EQU 0x130 (???????)

CNST_HWORD_USB_FS_FIFO_HPTXF_SIZE EQU 0x10

> TXFIFO starting address should in words.

Yes. Everything around FIFO must be in words - the sizes and start addresses, the actual occupancy, and you also must read and write FIFO in words, even if you have non-mod4=0 bytes of data to write/read.

So the question is, do you try to transmit non-mod4=0 number of data and write correctly aligned and padded data? You don't attempt to write bytes or halfwords into the FIFO, do you?

> 2) decode OTG_FS_GRXSTSP for data packet for ENDP1? if yes write to ENDPI buffer

You meant *read* from ENDP1 buffer, didn't you?

Otherwise the scheme looks good. Maybe post actual numbers you write into the registers.

JW

Jim Chacko
Associate II

HI,

1) My interface uses ENDPOINT1 as 'OUT' and also ENDPOINT1 as' IN'. Is there any problem to use same endpoint as OUT and IN configuration? I read it is possible because of different Endpoint addressing in USB as '0x1 for OUT' and '0x81 for IN'.

2) My application in C# write to ENDP1OUT using winusb driver and i am successfully receiving the packet and managed to decode it using  OTG_FS_GRXSTSP.

3) In response to the received packet, i am preparing a reply packet to application using ENDPI IN. This is where i screwed up.

4) To reconfirm, "MPSIZE" in OTG_FS_DIEPCTL1 should be in bytes or words. Right now i use bytes 0x40 (64)

Also "XFRSIZ" in "OTG_FS_DIEPTSIZ1" should be in bytes or words. i use now in bytes as per Manual.

--------------------------------------

Actual values i am writing

---------------------------------------

When SET_INTERFACE command received, i do this

;---------------------------

;ENDPOINT 1 [OUT]

;---------------------------

MOV32 R0,#(REG_WORD_USB_OTG_FS_DOEPCTL1)

MOV32 R1,#(0x94088040) //[EPENA: 1][SD0PID: 1][CNAK: 1][EPTYP: 2 : BULK][USBAEP: 1][MPSIZ: 64]

STR R1,[R0]

;------------------------

;ENDPOINT 1 [IN]

;-----------------------

MOV32 R0,#(REG_WORD_USB_OTG_FS_DIEPCTL1)

MOV32 R1,#(0x98488040) //[EPENA: 1][SD0PID: 1][SNAK: 1][TXFNUM: 1][EPTYP: 2 : BULK][USBAEP: 1][MPSIZ: 64]

STR R1,[R0]

Upon decoding the OUT packet from PC, i do this to start IN transfer

-----------------------------------------------------------------------

MOV32 R3,#(REG_WORD_USB_OTG_FS_DIEPTSIZ1)

LDR R4,[R3]

BFI R4,R0,#(CNST_VAL0),#(CNST_VAL19) // R0 contains byte count to be transferred. Now '16'

BFI R4,R2,#(CNST_VAL19),#(CNST_VAL10) // R2 contains packet count. Now '1'

STR R4,[R3]

MOV32 R3,#(REG_WORD_USB_OTG_FS_DIEPCTL1)

LDR R4,[R3]

MOV R5,#(0x1)

BFI R4,R5,#(CNST_VAL26),#(CNST_VAL1) ;[CNAK: 1]

BFI R4,R5,#(CNST_VAL31),#(CNST_VAL1) ;[EPENA: 1]

STR R4,[R3]

OTG_FS_DTXFSTS1 shows 0xC0 - 768 bytes free space as configured.

OTG_FS_DIEPTSIZ1 Shows PKTCNT: 1 and XFRSIZE: 0x10

Then filling the FIFO

----------------------------

MOV32 R3,#(CCSRAM_BUFFER_INTERFACE_USB_FS_ENDP1_IN_POINTER) // Data buffer

MOV32 R4,#(REG_WORD_USB_OTG_FS_HCH1_ENDP1_FIFO) // (0x50000000 + 0x1000 + 0x1000)

LDR R5,[R3],#(0x4)

STR R5,[R4]

LOOP 4 TIME TO COMPLETE 4 WORDS (16 bytes). After this the register values are

OTG_FS_DTXFSTS1 shows 0xBC - 752 bytes free space as expected.

OTG_FS_DIEPTSIZ1 Shows PKTCNT: 1 and XFRSIZE: 0x10

Then quit function and wait for ISR. ENDPI IN XFRC triggers. Then i get these values in the following registers

Now the OTG_FS_DTXFSTS1 shows 0xBE !!!!!!!!!!!!!!! - means only 8 bytes transferred from FIFO...

OTG_FS_DIEPTSIZ1 Shows PKTCNT: 0 and XFRSIZE: 0x0

But in my c# application i receive nothing. Just showing receive failed. with zero bytes read...

Thanks

Jim

Hi,

I think i made a mistake by setting 'EPENA ' in Set_Interface reques for IN endpointt. I removed that .

Now whst i observ is that I am getting a clear feture request immediately after read attempt fail. Usually this is asociated with a stall condition but i check none of stall bits are activated.

Thanks in advance

Jim

HI,

1) My interface uses ENDPOINT1 as 'OUT' and also ENDPOINT1 as' IN'. Is there any problem to use same endpoint as OUT and IN configuration? I read it is possible because of different Endpoint addressing in USB as '0x1 for OUT' and '0x81 for IN'.

2) My application in C# write to ENDP1OUT using winusb driver and i am successfully receiving the packet and managed to decode it using OTG_FS_GRXSTSP.

3) In response to the received packet, i am preparing a reply packet to application using ENDPI IN. This is where i screwed up.

4) To reconfirm, "MPSIZE" in OTG_FS_DIEPCTL1 should be in bytes or words. Right now i use bytes 0x40 (64)

Also "XFRSIZ" in "OTG_FS_DIEPTSIZ1" should be in bytes or words. i use now in bytes as per Manual.

--------------------------------------

Actual values i am writing

---------------------------------------

When SET_INTERFACE command received, i do this

;---------------------------

;ENDPOINT 1 [OUT]

;---------------------------

MOV32 R0,#(REG_WORD_USB_OTG_FS_DOEPCTL1)

MOV32 R1,#(0x94088040) //[EPENA: 1][SD0PID: 1][CNAK: 1][EPTYP: 2 : BULK][USBAEP: 1][MPSIZ: 64]

STR R1,[R0]

;------------------------

;ENDPOINT 1 [IN]

;-----------------------

MOV32 R0,#(REG_WORD_USB_OTG_FS_DIEPCTL1)

MOV32 R1,#(0x98488040) //[EPENA: 1][SD0PID: 1][SNAK: 1][TXFNUM: 1][EPTYP: 2 : BULK][USBAEP: 1][MPSIZ: 64]

STR R1,[R0]

Upon decoding the OUT packet from PC, i do this to start IN transfer

-----------------------------------------------------------------------

MOV32 R3,#(REG_WORD_USB_OTG_FS_DIEPTSIZ1)

LDR R4,[R3]

BFI R4,R0,#(CNST_VAL0),#(CNST_VAL19) // R0 contains byte count to be transferred. Now '16'

BFI R4,R2,#(CNST_VAL19),#(CNST_VAL10) // R2 contains packet count. Now '1'

STR R4,[R3]

MOV32 R3,#(REG_WORD_USB_OTG_FS_DIEPCTL1)

LDR R4,[R3]

MOV R5,#(0x1)

BFI R4,R5,#(CNST_VAL26),#(CNST_VAL1) ;[CNAK: 1]

BFI R4,R5,#(CNST_VAL31),#(CNST_VAL1) ;[EPENA: 1]

STR R4,[R3]

OTG_FS_DTXFSTS1 shows 0xC0 - 768 bytes free space as configured.

OTG_FS_DIEPTSIZ1 Shows PKTCNT: 1 and XFRSIZE: 0x10

Then filling the FIFO

----------------------------

MOV32 R3,#(CCSRAM_BUFFER_INTERFACE_USB_FS_ENDP1_IN_POINTER) // Data buffer

MOV32 R4,#(REG_WORD_USB_OTG_FS_HCH1_ENDP1_FIFO) // (0x50000000 + 0x1000 + 0x1000)

LDR R5,[R3],#(0x4)

STR R5,[R4]

LOOP 4 TIME TO COMPLETE 4 WORDS (16 bytes). After this the register values are

OTG_FS_DTXFSTS1 shows 0xBC - 752 bytes free space as expected.

OTG_FS_DIEPTSIZ1 Shows PKTCNT: 1 and XFRSIZE: 0x10

Then quit function and wait for ISR. ENDPI IN XFRC triggers. Then i get these values in the following registers

Now the OTG_FS_DTXFSTS1 shows 0xBE !!!!!!!!!!!!!!! - means only 8 bytes transferred from FIFO...

OTG_FS_DIEPTSIZ1 Shows PKTCNT: 0 and XFRSIZE: 0x0

But in my c# application i receive nothing. Just showing receive failed. with zero bytes read...

Thanks

Jim

Hi,

I think i made a mistake by setting 'EPENA ' in Set_Interface reques for IN endpointt. I removed that .

Now whst i observ is that I am getting a clear feture request immediately after read attempt fail. Usually this is asociated with a stall condition but i check none of stall bits are activated.

Thanks in advance

Jim

Just to confirm, only the FIFO-related stuff is in words, everything else is in bytes. Including DIEPTSIZx.XFRSIZ and DIEPCTL.MPSIZ

Your code looks reasonable, I don't know what's the problem, sorry

JW

Thanks.

To confirm with you, writing to IN endpoint

fill DIEPSIZ, PKTCNT -> CNAK,EPENA -> DIEPTSIZ: 1 -> TXFE -> Push to FIFO

or

fill DIEPSIZ, PKTCNT -> Push to FIFO -> CNAK,EPENA ?

which is te right meod? i mean sting CNAK an EPENA ater pushinbg data to FIFO or bfore pusinbg data?

Jim