cancel
Showing results for 
Search instead for 
Did you mean: 

[stm32f4 - discovery] USB OTG FS in device mode - initialization

bkdi
Associate II
Posted on July 30, 2013 at 20:19

I set all registers as shown in Reference Manual. When I preview OTG_FS_GRXSTS register (value: 0x004c0080) I know that the host sent SETUP packet to my discovery board. The first SETUP packet should contain GET DESCRIPTOR request. When I try to read data as my last line of code shows, value of variable named 'a' don't indicates GET DESCRIPTOR request. I thinkI have trouble reading data of RxFIFO, any idea?

RCC_AHB1ENR_GPIOAEN_BB = SET; 
GPIO_Port_Cfg(GPIOA, GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12, GPIO_Mode_AF, GPIO_Type_PP, GPIO_Speed_100MHz, GPIO_Pull_None); 
GPIO_Port_Cfg(GPIOA, GPIO_Pin_9, GPIO_Mode_AF, GPIO_Type_OD, GPIO_Speed_100MHz, GPIO_Pull_None); 
GPIO_Port_Cfg(GPIOA, GPIO_Pin_10, GPIO_Mode_AF, GPIO_Type_OD, GPIO_Speed_100MHz, GPIO_Pull_Up); 
GPIO_Port_AF_Cfg(GPIOA, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12, GPIO_AF_OTG_FS); 
RCC_AHB2ENR_OTGFSEN_BB = SET; 
/*----------- CORE INIT ----------*/
USB_FS_GAHBCFG GAHBCFG; 
USB_FS_GUSBCFG GUSBCFG; 
USB_FS_GINTMSK GINTMSK; 
/* 
Program the following fields in the OTG_FS_GAHBCFG register: 
- Global interrupt mask bit GINTMSK = 1 
- RxFIFO non-empty (RXFLVL bit in OTG_FS_GINTSTS) 
- Periodic TxFIFO empty level 
*/
GAHBCFG.reg_val = USB_OTG_FS->GLOBAL.GAHBCFG; 
GAHBCFG.bits.GINTMSK = 1; 
GAHBCFG.bits.TXFELVL = 0; 
USB_OTG_FS->GLOBAL.GAHBCFG = GAHBCFG.reg_val; 
/* 
Program the following fields in the OTG_FS_GUSBCFG register: 
- HNP capable bit 
- SRP capable bit 
- FS timeout calibration field 
- USB turnaround time field 
*/
GUSBCFG.reg_val = USB_OTG_FS->GLOBAL.GUSBCFG; 
GUSBCFG.bits.TOCAL = 5; 
GUSBCFG.bits.SRPCAP = 0; 
GUSBCFG.bits.HNPCAP = 0; 
GUSBCFG.bits.TRDT = 15; 
USB_OTG_FS->GLOBAL.GUSBCFG = GUSBCFG.reg_val; 
/* 
Unmask the following bits in the OTG_FS_GINTMSK register: 
- OTG interrupt mask 
- Mode mismatch interrupt mask 
*/
GINTMSK.reg_val = USB_OTG_FS->GLOBAL.GINTMSK; 
GINTMSK.bits.MMISM = 1; 
GINTMSK.bits.OTGINT = 1; 
USB_OTG_FS->GLOBAL.GINTMSK = GINTMSK.reg_val; 
if
( ((USB_FS_GINTSTS)USB_OTG_FS->GLOBAL.GINTSTS).bits.CMOD != 0) 
{ 
GUSBCFG.reg_val = USB_OTG_FS->GLOBAL.GUSBCFG; 
GUSBCFG.bits.FDMOD = 1; 
USB_OTG_FS->GLOBAL.GUSBCFG = GUSBCFG.reg_val; 
while
( ((USB_FS_GUSBCFG)USB_OTG_FS->GLOBAL.GUSBCFG).bits.FDMOD == 1); 
} 
/*----------- CORE INIT END ----------*/
/*----------- DEVICE INIT ----------*/
USB_FS_DCFG DCFG; 
USB_FS_GCCFG GCCFG; 
/* 
Program the following fields in the OTG_FS_DCFG register: 
- Device speed 
- Non-zero-length status OUT handshake 
*/
DCFG.reg_val = USB_OTG_FS->DEVICE.DCFG; 
DCFG.bits.DSPD = 3; 
DCFG.bits.NZLSOHSK = 1; 
USB_OTG_FS->DEVICE.DCFG = DCFG.reg_val; 
/* 
Program the OTG_FS_GINTMSK register to unmask the following interrupts: 
- USB reset 
- Enumeration done 
- Early suspend 
- USB suspend 
- SOF 
*/
GINTMSK.reg_val = USB_OTG_FS->GLOBAL.GINTMSK; 
GINTMSK.bits.SOFM = 1; 
GINTMSK.bits.RXFLVLM = 1; 
GINTMSK.bits.ESUSPM = 1; 
GINTMSK.bits.USBSUSPM = 1; 
GINTMSK.bits.USBRST = 1; 
GINTMSK.bits.ENUMDNEM = 1; 
USB_OTG_FS->GLOBAL.GINTMSK = GINTMSK.reg_val; 
/* 
Program the VBUSBSEN bit in the OTG_FS_GCCFG register to enable VBUS sensing 
in B-device mode and supply the 5 volts across the pull-up resistor on the DP line. 
*/
GCCFG.reg_val = USB_OTG_FS->GLOBAL.GCCFG; 
GCCFG.bits.VBUSBSEN = 1; 
GCCFG.bits.PWRDWN = 1; 
USB_OTG_FS->GLOBAL.GCCFG = GCCFG.reg_val; 
/* 
Wait for the USBRST interrupt in OTG_FS_GINTSTS. It indicates that a reset has been 
detected on the USB that lasts for about 10 ms on receiving this interrupt. 
*/
while
( ((USB_FS_GINTSTS)USB_OTG_FS->GLOBAL.GINTSTS).bits.USBRST != 1); 
/*------- Endpoint initialization on USB reset ------*/
USB_FS_DOEPCTL DOEPCTL; 
USB_FS_DAINTMSK DAINTMSK; 
USB_FS_DIEPMSK DIEPMSK; 
USB_FS_DOEPMSK DOEPMSK; 
USB_FS_GRXFSIZ GRXFSIZ; 
USB_FS_HNPTXFSIZ_DIEPTXF0 HNPTXFSIZ_DIEPTXF0; 
USB_FS_DOEPTSIZ DOEPTSIZ; 
/* 
Set the NAK bit for all OUT endpoints 
- SNAK = 1 in OTG_FS_DOEPCTLx (for all OUT endpoints) 
*/
DOEPCTL.reg_val = USB_OTG_FS->DEVICE.DOEP[0].DOEPCTL; 
DOEPCTL.bits.SNAK = 1; 
USB_OTG_FS->DEVICE.DOEP[0].DOEPCTL = DOEPCTL.reg_val; 
DOEPCTL.reg_val = USB_OTG_FS->DEVICE.DOEP[1].DOEPCTL; 
DOEPCTL.bits.SNAK = 1; 
USB_OTG_FS->DEVICE.DOEP[1].DOEPCTL = DOEPCTL.reg_val; 
DOEPCTL.reg_val = USB_OTG_FS->DEVICE.DOEP[2].DOEPCTL; 
DOEPCTL.bits.SNAK = 1; 
USB_OTG_FS->DEVICE.DOEP[2].DOEPCTL = DOEPCTL.reg_val; 
DOEPCTL.reg_val = USB_OTG_FS->DEVICE.DOEP[3].DOEPCTL; 
DOEPCTL.bits.SNAK = 1; 
USB_OTG_FS->DEVICE.DOEP[3].DOEPCTL = DOEPCTL.reg_val; 
/* 
Unmask the following interrupt bits 
- INEP0 = 1 in OTG_FS_DAINTMSK (control 0 IN endpoint) 
- OUTEP0 = 1 in OTG_FS_DAINTMSK (control 0 OUT endpoint) 
- STUP=1 in DOEPMSK 
- XFRC = 1 in DOEPMSK 
- XFRC = 1 in DIEPMSK 
- TOC = 1 in DIEPMSK 
*/
DAINTMSK.reg_val = USB_OTG_FS->DEVICE.DAINTMSK; 
DAINTMSK.bits.IEPM = 1; 
DAINTMSK.bits.OEPM = 1; 
USB_OTG_FS->DEVICE.DAINTMSK = DAINTMSK.reg_val; 
DIEPMSK.reg_val = USB_OTG_FS->DEVICE.DIEPMSK; 
DIEPMSK.bits.XFRCM = 1; 
DIEPMSK.bits.TOM = 1; 
USB_OTG_FS->DEVICE.DIEPMSK = DIEPMSK.reg_val; 
DOEPMSK.reg_val = USB_OTG_FS->DEVICE.DOEPMSK; 
DOEPMSK.bits.XFRCM = 1; 
DOEPMSK.bits.STUPM = 1; 
USB_OTG_FS->DEVICE.DOEPMSK = DOEPMSK.reg_val; 
/* 
Set up the Data FIFO RAM for each of the FIFOs 
- Program the OTG_FS_GRXFSIZ register, to be able to receive control OUT data 
and setup data. If thresholding is not enabled, at a minimum, this must be equal to 
1 max packet size of control endpoint 0 + 2 Words (for the status of the control 
OUT data packet) + 10 Words (for setup packets). 
- Program the OTG_FS_TX0FSIZ register (depending on the FIFO number chosen) 
to be able to transmit control IN data. At a minimum, this must be equal to 1 max 
packet size of control endpoint 0. 
*/
GRXFSIZ.bits.RXFD = 128; 
USB_OTG_FS->GLOBAL.GRXFSIZ = GRXFSIZ.reg_val; 
HNPTXFSIZ_DIEPTXF0.bits.NPTXFSA_TX0FSA = 128; 
HNPTXFSIZ_DIEPTXF0.bits.NPTXFD_TX0FD = 64; 
USB_OTG_FS->GLOBAL.HNPTXFSIZ_DIEPTXF0 = HNPTXFSIZ_DIEPTXF0.reg_val; 
/* 
Program the following fields in the endpoint-specific registers for control OUT endpoint 
0 to receive a SETUP packet 
- STUPCNT = 3 in OTG_FS_DOEPTSIZ0 (to receive up to 3 back-to-back SETUP 
packets) 
*/
DOEPTSIZ.bits.XFRSIZ = 30; 
DOEPTSIZ.bits.PKTCNT = 1; 
DOEPTSIZ.bits.RXDPID_STUPCNT = 3; 
USB_OTG_FS->DEVICE.DOEP[0].DOEPTSIZ = DOEPTSIZ.reg_val; 
while
( ((USB_FS_GINTSTS)USB_OTG_FS->GLOBAL.GINTSTS).bits.ENUMDNE != 1); 
/*------- Endpoint initialization on USB reset END ------*/
/*------ Endpoint initialization on enumeration completion -------*/
/*------ Endpoint activation -------*/
USB_FS_DIEPCTL DIEPCTL; 
/* 
Program the MPSIZ field in OTG_FS_DIEPCTL0 to set the maximum packet size. This 
step configures control endpoint 0. The maximum packet size for a control endpoint 
depends on the enumeration speed. 
*/
DIEPCTL.reg_val = USB_OTG_FS->DEVICE.DIEP[0].DIEPCTL; 
DIEPCTL.bits.MPSIZ = 0; 
DIEPCTL.bits.EPENA = 1; 
USB_OTG_FS->DEVICE.DIEP[0].DIEPCTL = DIEPCTL.reg_val; 
DOEPCTL.reg_val = USB_OTG_FS->DEVICE.DOEP[0].DOEPCTL; 
DOEPCTL.bits.MPSIZ = 0; 
DIEPCTL.bits.EPENA = 1; 
USB_OTG_FS->DEVICE.DOEP[0].DOEPCTL = DOEPCTL.reg_val; 
/*------ Endpoint initialization on enumeration completion END -------*/
/*------ Endpoint activation END -------*/
while
( ((USB_FS_GINTSTS)USB_OTG_FS->GLOBAL.GINTSTS).bits.RXFLVL != 1); 
uint32_t a = *((uint32_t*)(0x50001000));

0 REPLIES 0