2013-07-30 11:19 AM
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));