mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-07 05:54:11 +08:00
Merge pull request #1077 from hathach/st-synopsy-compliance
St synopsy compliance
This commit is contained in:
commit
5f141a4c13
@ -96,6 +96,9 @@
|
|||||||
#elif CFG_TUSB_MCU == OPT_MCU_GD32VF103
|
#elif CFG_TUSB_MCU == OPT_MCU_GD32VF103
|
||||||
#include "synopsys_common.h"
|
#include "synopsys_common.h"
|
||||||
|
|
||||||
|
// for remote wakeup delay
|
||||||
|
#define __NOP() __asm volatile ("nop")
|
||||||
|
|
||||||
// These numbers are the same for the whole GD32VF103 family.
|
// These numbers are the same for the whole GD32VF103 family.
|
||||||
#define OTG_FS_IRQn 86
|
#define OTG_FS_IRQn 86
|
||||||
#define EP_MAX_FS 4
|
#define EP_MAX_FS 4
|
||||||
@ -213,17 +216,18 @@ static void bus_reset(uint8_t rhport)
|
|||||||
tu_memclr(xfer_status, sizeof(xfer_status));
|
tu_memclr(xfer_status, sizeof(xfer_status));
|
||||||
_out_ep_closed = false;
|
_out_ep_closed = false;
|
||||||
|
|
||||||
|
// clear device address
|
||||||
|
dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk;
|
||||||
|
|
||||||
|
// 1. NAK for all OUT endpoints
|
||||||
for(uint8_t n = 0; n < EP_MAX; n++) {
|
for(uint8_t n = 0; n < EP_MAX; n++) {
|
||||||
out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
|
out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear device address
|
// 2. Un-mask interrupt bits
|
||||||
dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk;
|
dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos);
|
||||||
|
dev->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
|
||||||
// TODO should probably assign value when reset rather than OR
|
dev->DIEPMSK = USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM;
|
||||||
dev->DAINTMSK |= (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos);
|
|
||||||
dev->DOEPMSK |= USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
|
|
||||||
dev->DIEPMSK |= USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM;
|
|
||||||
|
|
||||||
// "USB Data FIFOs" section in reference manual
|
// "USB Data FIFOs" section in reference manual
|
||||||
// Peripheral FIFO architecture
|
// Peripheral FIFO architecture
|
||||||
@ -307,8 +311,6 @@ static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed)
|
|||||||
// Turnaround timeout depends on the MCU clock
|
// Turnaround timeout depends on the MCU clock
|
||||||
uint32_t turnaround;
|
uint32_t turnaround;
|
||||||
|
|
||||||
TU_LOG_INT(2, SystemCoreClock);
|
|
||||||
|
|
||||||
if ( SystemCoreClock >= 32000000U )
|
if ( SystemCoreClock >= 32000000U )
|
||||||
turnaround = 0x6U;
|
turnaround = 0x6U;
|
||||||
else if ( SystemCoreClock >= 27500000U )
|
else if ( SystemCoreClock >= 27500000U )
|
||||||
@ -556,13 +558,34 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
|
|||||||
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
|
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void remote_wakeup_delay(void)
|
||||||
|
{
|
||||||
|
// try to delay for 1 ms
|
||||||
|
uint32_t count = SystemCoreClock / 1000;
|
||||||
|
while ( count-- )
|
||||||
|
{
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dcd_remote_wakeup(uint8_t rhport)
|
void dcd_remote_wakeup(uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
|
|
||||||
// TODO must manually clear this bit after 1-15 ms
|
USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
|
||||||
// USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
|
USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
|
||||||
// dev->DCTL |= USB_OTG_DCTL_RWUSIG;
|
|
||||||
|
// set remote wakeup
|
||||||
|
dev->DCTL |= USB_OTG_DCTL_RWUSIG;
|
||||||
|
|
||||||
|
// enable SOF to detect bus resume
|
||||||
|
usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF;
|
||||||
|
usb_otg->GINTMSK |= USB_OTG_GINTMSK_SOFM;
|
||||||
|
|
||||||
|
// Per specs: remote wakeup signal bit must be clear within 1-15ms
|
||||||
|
remote_wakeup_delay();
|
||||||
|
|
||||||
|
dev->DCTL &= ~USB_OTG_DCTL_RWUSIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_connect(uint8_t rhport)
|
void dcd_connect(uint8_t rhport)
|
||||||
@ -618,8 +641,9 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
|||||||
usb_otg->GRXFSIZ = sz;
|
usb_otg->GRXFSIZ = sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) |
|
out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) |
|
(desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos) |
|
||||||
|
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) |
|
||||||
(desc_edpt->wMaxPacketSize.size << USB_OTG_DOEPCTL_MPSIZ_Pos);
|
(desc_edpt->wMaxPacketSize.size << USB_OTG_DOEPCTL_MPSIZ_Pos);
|
||||||
|
|
||||||
dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum));
|
dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum));
|
||||||
@ -661,7 +685,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
|||||||
in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) |
|
in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) |
|
||||||
(epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) |
|
(epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) |
|
(desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) |
|
||||||
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) |
|
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM : 0) |
|
||||||
(desc_edpt->wMaxPacketSize.size << USB_OTG_DIEPCTL_MPSIZ_Pos);
|
(desc_edpt->wMaxPacketSize.size << USB_OTG_DIEPCTL_MPSIZ_Pos);
|
||||||
|
|
||||||
dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum));
|
dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum));
|
||||||
@ -670,10 +694,32 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close all non-control endpoints, cancel all pending transfers if any.
|
||||||
void dcd_edpt_close_all (uint8_t rhport)
|
void dcd_edpt_close_all (uint8_t rhport)
|
||||||
{
|
{
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
// TODO implement dcd_edpt_close_all()
|
|
||||||
|
// USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
|
||||||
|
USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
|
||||||
|
USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
|
||||||
|
USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
|
||||||
|
|
||||||
|
// Disable non-control interrupt
|
||||||
|
dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos);
|
||||||
|
|
||||||
|
for(uint8_t n = 1; n < EP_MAX; n++)
|
||||||
|
{
|
||||||
|
// disable OUT endpoint
|
||||||
|
out_ep[n].DOEPCTL = 0;
|
||||||
|
xfer_status[n][TUSB_DIR_OUT].max_size = 0;
|
||||||
|
|
||||||
|
// disable IN endpoint
|
||||||
|
in_ep[n].DIEPCTL = 0;
|
||||||
|
xfer_status[n][TUSB_DIR_IN].max_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset allocated fifo IN
|
||||||
|
_allocated_fifo_words_tx = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
|
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
|
||||||
@ -835,22 +881,13 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
|||||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||||
|
|
||||||
|
// Clear stall and reset data toggle
|
||||||
if(dir == TUSB_DIR_IN) {
|
if(dir == TUSB_DIR_IN) {
|
||||||
in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
|
in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
|
||||||
|
in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
|
||||||
uint8_t eptype = (in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP_Msk) >> USB_OTG_DIEPCTL_EPTYP_Pos;
|
|
||||||
// Required by USB spec to reset DATA toggle bit to DATA0 on interrupt and bulk endpoints.
|
|
||||||
if(eptype == 2 || eptype == 3) {
|
|
||||||
in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
|
out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
|
||||||
|
out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
|
||||||
uint8_t eptype = (out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP_Msk) >> USB_OTG_DOEPCTL_EPTYP_Pos;
|
|
||||||
// Required by USB spec to reset DATA toggle bit to DATA0 on interrupt and bulk endpoints.
|
|
||||||
if(eptype == 2 || eptype == 3) {
|
|
||||||
out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1087,7 +1124,7 @@ void dcd_int_handler(uint8_t rhport)
|
|||||||
USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
|
USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
|
||||||
USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
|
USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
|
||||||
|
|
||||||
uint32_t int_status = usb_otg->GINTSTS;
|
uint32_t const int_status = usb_otg->GINTSTS & usb_otg->GINTMSK;
|
||||||
|
|
||||||
if(int_status & USB_OTG_GINTSTS_USBRST)
|
if(int_status & USB_OTG_GINTSTS_USBRST)
|
||||||
{
|
{
|
||||||
@ -1120,6 +1157,9 @@ void dcd_int_handler(uint8_t rhport)
|
|||||||
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
|
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO check USB_OTG_GINTSTS_DISCINT for disconnect detection
|
||||||
|
// if(int_status & USB_OTG_GINTSTS_DISCINT)
|
||||||
|
|
||||||
if(int_status & USB_OTG_GINTSTS_OTGINT)
|
if(int_status & USB_OTG_GINTSTS_OTGINT)
|
||||||
{
|
{
|
||||||
// OTG INT bit is read-only
|
// OTG INT bit is read-only
|
||||||
@ -1133,13 +1173,15 @@ void dcd_int_handler(uint8_t rhport)
|
|||||||
usb_otg->GOTGINT = otg_int;
|
usb_otg->GOTGINT = otg_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SOF
|
|
||||||
if(int_status & USB_OTG_GINTSTS_SOF)
|
if(int_status & USB_OTG_GINTSTS_SOF)
|
||||||
{
|
{
|
||||||
usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF;
|
usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF;
|
||||||
|
|
||||||
|
// Disable SOF interrupt since currently only used for remote wakeup detection
|
||||||
|
usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_SOFM;
|
||||||
|
|
||||||
dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
|
dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// RxFIFO non-empty interrupt handling.
|
// RxFIFO non-empty interrupt handling.
|
||||||
if(int_status & USB_OTG_GINTSTS_RXFLVL)
|
if(int_status & USB_OTG_GINTSTS_RXFLVL)
|
||||||
@ -1153,8 +1195,7 @@ void dcd_int_handler(uint8_t rhport)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
handle_rxflvl_ints(rhport, out_ep);
|
handle_rxflvl_ints(rhport, out_ep);
|
||||||
int_status = usb_otg->GINTSTS;
|
} while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL);
|
||||||
} while(int_status & USB_OTG_GINTSTS_RXFLVL);
|
|
||||||
|
|
||||||
// Manage RX FIFO size
|
// Manage RX FIFO size
|
||||||
if (_out_ep_closed)
|
if (_out_ep_closed)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user