From ff551265b12de68f2943b7d4c4793a33c8626d35 Mon Sep 17 00:00:00 2001 From: dexter93 Date: Thu, 3 Mar 2022 13:09:04 +0200 Subject: [PATCH] sn32: usb hal cleanup (#42) * import helper header * seperate usb buf init * move usb init in chibios driver handle the address set in a more elegant way * clean up some code move through sn32_usb use macros for ep dir * handle the setup interrupt * report back the frame no wake up directly * further deviate from usbhw.c call registers directly use chibios for reset interrupt party time * flag update * switch n/ack to simple macros * even more native * bye sonix mess * bring functions up to the docs * usb stop, setup error handling * further cleanup remove dead code cleanup headers add missing connect/dc functionality bring ep0 init to platform correct * usb restart is now working * attempt to fix wakeup * no more delay on init * fix the usb wakeup * improve the wakeup * make sure the direction is not set before init * only mess with one ep * need to enable the bus override too in order to control it * driver block checks * allow wakeup time override * dynamic sram allocation * remove useless ep naming * testing: remove packet limits * guard all i/o ops * better wakeup/suspend handling * remove dead code * code cleanup * make sure all ep's are handled --- os/hal/boards/SN_SN32F240B/board.c | 4 - os/hal/boards/SN_SN32F260/board.c | 4 - os/hal/boards/SN_SN32F280/board.c | 4 - os/hal/boards/SN_SN32F290/board.c | 4 - os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk | 1 - .../ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c | 794 ++++++++---------- .../ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.h | 69 +- os/hal/ports/SN32/LLD/SN32F2xx/USB/sn32_usb.h | 73 +- os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c | 381 --------- os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.h | 115 +-- 10 files changed, 475 insertions(+), 974 deletions(-) delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c diff --git a/os/hal/boards/SN_SN32F240B/board.c b/os/hal/boards/SN_SN32F240B/board.c index 655a9b04b4..ccaf913c45 100644 --- a/os/hal/boards/SN_SN32F240B/board.c +++ b/os/hal/boards/SN_SN32F240B/board.c @@ -65,7 +65,3 @@ void boardInit(void) { SN_SYS0->EXRSTCTRL_b.RESETDIS = 1; // Disable RESET SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD } - -void restart_usb_driver(USBDriver *usbp) { - // Do nothing. Restarting the USB driver on these boards breaks it. -} diff --git a/os/hal/boards/SN_SN32F260/board.c b/os/hal/boards/SN_SN32F260/board.c index adbcbe42cb..72ad880c15 100644 --- a/os/hal/boards/SN_SN32F260/board.c +++ b/os/hal/boards/SN_SN32F260/board.c @@ -58,7 +58,3 @@ void __early_init(void) { void boardInit(void) { SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD } - -void restart_usb_driver(USBDriver *usbp) { - // Do nothing. Restarting the USB driver on these boards breaks it. -} diff --git a/os/hal/boards/SN_SN32F280/board.c b/os/hal/boards/SN_SN32F280/board.c index 655a9b04b4..ccaf913c45 100644 --- a/os/hal/boards/SN_SN32F280/board.c +++ b/os/hal/boards/SN_SN32F280/board.c @@ -65,7 +65,3 @@ void boardInit(void) { SN_SYS0->EXRSTCTRL_b.RESETDIS = 1; // Disable RESET SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD } - -void restart_usb_driver(USBDriver *usbp) { - // Do nothing. Restarting the USB driver on these boards breaks it. -} diff --git a/os/hal/boards/SN_SN32F290/board.c b/os/hal/boards/SN_SN32F290/board.c index 655a9b04b4..ccaf913c45 100644 --- a/os/hal/boards/SN_SN32F290/board.c +++ b/os/hal/boards/SN_SN32F290/board.c @@ -65,7 +65,3 @@ void boardInit(void) { SN_SYS0->EXRSTCTRL_b.RESETDIS = 1; // Disable RESET SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD } - -void restart_usb_driver(USBDriver *usbp) { - // Do nothing. Restarting the USB driver on these boards breaks it. -} diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk b/os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk index c67da0de71..a65d21caac 100644 --- a/os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk +++ b/os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk @@ -1,4 +1,3 @@ PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c -PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/USB diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c b/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c index 863a7f1ea9..cc637fe4f9 100644 --- a/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c +++ b/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c @@ -1,5 +1,5 @@ /* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,17 +22,14 @@ * @{ */ -#include #include #include "hal.h" -#include "usbhw.h" #if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__) /*===========================================================================*/ /* Driver local definitions. */ /*===========================================================================*/ -#define SN32_USB_PMA_SIZE 256 /*===========================================================================*/ /* Driver exported variables. */ @@ -41,16 +38,15 @@ /** * @brief USB1 driver identifier. */ -#if (PLATFORM_USB_USE_USB1 == TRUE) || defined(__DOXYGEN__) +#if (SN32_USB_USE_USB1 == TRUE) || defined(__DOXYGEN__) USBDriver USBD1; -#endif +#endif /* SN32_USB_USE_USB1 == TRUE */ /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ -static int address; -static uint8_t nakcnt[USB_MAX_ENDPOINTS + 1] = {0, 0, 0, 0, 0}; +static uint8_t nakcnt[USB_MAX_ENDPOINTS + 1] = {0}; /** * @brief EP0 state. @@ -68,34 +64,26 @@ static union { USBOutEndpointState out; } ep0_state; +/** + * @brief Buffer for the EP0 setup packets. + */ +static uint8_t ep0setup_buffer[8]; + /** * @brief EP0 initialization structure. */ static const USBEndpointConfig ep0config = { - USB_ENDPOINT_TYPE_CONTROL, - _usb_ep0setup, - _usb_ep0in, - _usb_ep0out, - 0x40, - 0x40, - &ep0_state.in, - &ep0_state.out + .ep_mode = USB_EP_MODE_TYPE_CTRL, + .setup_cb = _usb_ep0setup, + .in_cb = _usb_ep0in, + .out_cb = _usb_ep0out, + .in_maxsize = 0x40, + .out_maxsize = 0x40, + .in_state = &ep0_state.in, + .out_state = &ep0_state.out, + .ep_buffers = 1, + .setup_buf = ep0setup_buffer }; -void rgb_matrix_toggle(void); -void handleACK(USBDriver* usbp, usbep_t ep); -void handleNAK(USBDriver* usbp, usbep_t ep); -#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__) -#define _usb_isr_invoke_tx_complete_cb(usbp, ep) { \ - (usbp)->transmitting &= ~(1 << (ep)); \ - osalSysLockFromISR(); \ - osalThreadResumeI(&(usbp)->epc[ep]->in_state->thread, MSG_OK); \ - osalSysUnlockFromISR(); \ -} -#else -#define _usb_isr_invoke_tx_complete_cb(usbp, ep) { \ - (usbp)->transmitting &= ~(1 << (ep)); \ -} -#endif /*===========================================================================*/ /* Driver local variables and types. */ @@ -105,36 +93,63 @@ void handleNAK(USBDriver* usbp, usbep_t ep); /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Resets the packet memory allocator. + * + * @param[in] usbp pointer to the @p USBDriver object + */ +static void usb_pm_reset(USBDriver *usbp) { + + /* The first 64 bytes are reserved for the descriptors table. The effective + available RAM for endpoint buffers is just 192/448 bytes.*/ + usbp->pmnext = 64; +} + +/** + * @brief Sets the packet memory allocator. + * + * @param[in] usbp pointer to the @p USBDriver object + * @param[in] size size of the packet buffer to allocate + * @return The packet buffer address. + */ +static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) { + uint32_t next; + + next = usbp->pmnext; + usbp->pmnext += (size + 1) & ~1; + osalDbgAssert(usbp->pmnext <= SN32_USB_PMA_SIZE, "PMA overflow"); + return next; +} + static void sn32_usb_read_fifo(usbep_t ep, uint8_t *buf, size_t sz, bool intr) { - size_t ep_offset = wUSB_EPnOffset[ep]; + size_t ep_offset; + if (ep == 0) { + ep_offset = 0; + } + else { + ep_offset = SN32_USB->EPBUFOS[ep-1]; + } size_t off; size_t chunk; uint32_t data; - //Limit size to max packet size allowed in USB ram - //if (sz > wUSB_EPnMaxPacketSize[ep]) { - // sz = wUSB_EPnMaxPacketSize[ep]; - //} - off = 0; while (off != sz) { chunk = 4; if (off + chunk > sz) chunk = sz - off; - if(intr) - { - SN_USB->RWADDR = off + ep_offset; - SN_USB->RWSTATUS = 0x02; - while (SN_USB->RWSTATUS & 0x02); - data = SN_USB->RWDATA; + if(intr) { + SN32_USB->RWADDR = off + ep_offset; + SN32_USB->RWSTATUS = 0x02; + while (SN32_USB->RWSTATUS & 0x02); + data = SN32_USB->RWDATA; } - else - { - SN_USB->RWADDR2 = off + ep_offset; - SN_USB->RWSTATUS2 = 0x02; - while (SN_USB->RWSTATUS2 & 0x02); - data = SN_USB->RWDATA2; + else { + SN32_USB->RWADDR2 = off + ep_offset; + SN32_USB->RWSTATUS2 = 0x02; + while (SN32_USB->RWSTATUS2 & 0x02); + data = SN32_USB->RWDATA2; } //dest, src, size @@ -146,16 +161,17 @@ static void sn32_usb_read_fifo(usbep_t ep, uint8_t *buf, size_t sz, bool intr) { } static void sn32_usb_write_fifo(usbep_t ep, const uint8_t *buf, size_t sz, bool intr) { - size_t ep_offset = wUSB_EPnOffset[ep]; + size_t ep_offset; + if (ep == 0) { + ep_offset = 0; + } + else { + ep_offset = SN32_USB->EPBUFOS[ep-1]; + } size_t off; size_t chunk; uint32_t data; - //Limit size to max packet size allowed in USB ram - //if (sz > wUSB_EPnMaxPacketSize[ep]) { - // sz = wUSB_EPnMaxPacketSize[ep]; - //} - off = 0; while (off != sz) { @@ -166,19 +182,17 @@ static void sn32_usb_write_fifo(usbep_t ep, const uint8_t *buf, size_t sz, bool //dest, src, size memcpy(&data, buf, chunk); - if(intr) - { - SN_USB->RWADDR = off + ep_offset; - SN_USB->RWDATA = data; - SN_USB->RWSTATUS = 0x01; - while (SN_USB->RWSTATUS & 0x01); + if(intr) { + SN32_USB->RWADDR = off + ep_offset; + SN32_USB->RWDATA = data; + SN32_USB->RWSTATUS = 0x01; + while (SN32_USB->RWSTATUS & 0x01); } - else - { - SN_USB->RWADDR2 = off + ep_offset; - SN_USB->RWDATA2 = data; - SN_USB->RWSTATUS2 = 0x01; - while (SN_USB->RWSTATUS2 & 0x01); + else { + SN32_USB->RWADDR2 = off + ep_offset; + SN32_USB->RWDATA2 = data; + SN32_USB->RWSTATUS2 = 0x01; + while (SN32_USB->RWSTATUS2 & 0x01); } off += chunk; @@ -186,8 +200,6 @@ static void sn32_usb_write_fifo(usbep_t ep, const uint8_t *buf, size_t sz, bool } } -void rgb_matrix_disable_noeeprom(void); - /** * @brief USB shared ISR. * @@ -195,258 +207,189 @@ void rgb_matrix_disable_noeeprom(void); * * @notapi */ -static void usb_lld_serve_interrupt(USBDriver *usbp) -{ +static void usb_lld_serve_interrupt(USBDriver *usbp) { uint32_t iwIntFlag; - size_t n; - //** Get Interrupt Status and clear immediately. - iwIntFlag = SN_USB->INSTS; - //Clear flags right away for interrupts that we dont handle, keep other untill fully handled - SN_USB->INSTSC = 0x0007F0F0; + /* Get Interrupt Status and clear immediately. */ + iwIntFlag = SN32_USB->INSTS; + /* Keep only PRESETUP & ERR_SETUP flags. */ + SN32_USB->INSTSC = ~(mskEP0_PRESETUP | mskERR_SETUP); - if(iwIntFlag == 0) - { + if (iwIntFlag == 0) { //@20160902 add for EMC protection - USB_ReturntoNormal(); + SN32_USB->CFG |= (mskESD_EN|mskPHY_EN); return; } - ///////////////////////////////////////////////// - /* Device Status Interrupt (BusReset, Suspend) */ - ///////////////////////////////////////////////// - if (iwIntFlag & (mskBUS_RESET | mskBUS_SUSPEND | mskBUS_RESUME)) - { - if (iwIntFlag & mskBUS_RESET) - { + ///////////////////////////////////////////////////////////////// + /* Device Status Interrupt (BusReset, Suspend, Resume, Wakeup) */ + ///////////////////////////////////////////////////////////////// + if (iwIntFlag & (mskBUS_RESET | mskBUS_SUSPEND | mskBUS_RESUME | mskBUS_WAKEUP)) { + if (iwIntFlag & mskBUS_RESET) { /* BusReset */ - USB_ReturntoNormal(); - USB_ResetEvent(); + SN32_USB->CFG |= (mskESD_EN|mskPHY_EN); + SN32_USB->INSTSC = (mskBUS_RESET); _usb_reset(usbp); } - else if (iwIntFlag & mskBUS_SUSPEND) - { + else if (iwIntFlag & mskBUS_SUSPEND) { /* Suspend */ - __USB_CLRINSTS(mskBUS_SUSPEND); + SN32_USB->CFG &= ~(mskESD_EN|mskPHY_EN); _usb_suspend(usbp); - //USB suspend will put MCU in sleep mode with lower clock - //and disable execution of user code allowing only interrupt to execute - //keeping it here just for reference on how to could be done - //not necessary for remote wakeup to work - //uncomment if want to experiment with suspend mode - //USB_SuspendEvent(); + SN32_USB->INSTSC = (mskBUS_SUSPEND); } - else if(iwIntFlag & mskBUS_RESUME) - { + else if(iwIntFlag & mskBUS_RESUME) { /* Resume */ - USB_ReturntoNormal(); - __USB_CLRINSTS(mskBUS_RESUME); + SN32_USB->CFG |= (mskESD_EN|mskPHY_EN); + SN32_USB->INSTSC = (mskBUS_RESUME); + } + else if(iwIntFlag & mskBUS_WAKEUP) { + /* Wakeup */ + SN32_USB->CFG |= (mskESD_EN|mskPHY_EN); + SN32_USB->INSTSC = (mskBUS_WAKEUP); _usb_wakeup(usbp); } } ///////////////////////////////////////////////// - /* Device Status Interrupt (SETUP, IN, OUT) */ + /* Device Status Interrupt (SETUP, IN, OUT) */ ///////////////////////////////////////////////// - else if (iwIntFlag & (mskEP0_SETUP|mskEP0_IN|mskEP0_OUT|mskEP0_IN_STALL|mskEP0_OUT_STALL)) - { + else if (iwIntFlag & mskERR_SETUP) { + SN32_USB->INSTSC = (mskERR_SETUP); + usb_lld_stall_in(usbp, 0); + } + else if (iwIntFlag & (mskEP0_SETUP|mskEP0_IN|mskEP0_OUT|mskEP0_IN_STALL|mskEP0_OUT_STALL)) { const USBEndpointConfig *epcp = usbp->epc[0]; - if (iwIntFlag & mskEP0_SETUP) - { + if (iwIntFlag & mskEP0_SETUP) { /* SETUP */ - //** keep EP0 NAK - //USB_EPnNak(USB_EP0); //useless - - //not sure we need it here... - //TODO: clean it up when packets are properly handled - epcp->in_state->txcnt = 0; - epcp->in_state->txsize = 0; - epcp->in_state->txlast = 0; - epcp->out_state->rxcnt = 0; - epcp->out_state->rxsize = 0; - epcp->out_state->rxpkts = 0; - + /* Clear receiving in the chibios state machine */ + (usbp)->receiving &= ~1; + SN32_USB->INSTSC = (mskEP0_PRESETUP); + /* Call SETUP function (ChibiOS core), which prepares + * for send or receive and releases the buffer + */ _usb_isr_invoke_setup_cb(usbp, 0); - __USB_CLRINSTS((mskEP0_SETUP|mskEP0_PRESETUP|mskEP0_OUT_STALL|mskEP0_IN_STALL)); + SN32_USB->INSTSC = (mskEP0_SETUP); } - else if (iwIntFlag & mskEP0_IN) - { + else if (iwIntFlag & mskEP0_IN) { USBInEndpointState *isp = epcp->in_state; /* IN */ - - // The address - if (address) { - SN_USB->ADDR = address; - address = 0; - USB_EPnStall(USB_EP0); + /* Special case for SetAddress for EP0*/ + if((((uint16_t)usbp->setup[0]<<8)|usbp->setup[1]) == 0x0500) { + usbp->address = usbp->setup[2]; + usb_lld_set_address(usbp); + _usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS); + usbp->state = USB_SELECTED; + usb_lld_stall_in(usbp, 0); } isp->txcnt += isp->txlast; - n = isp->txsize - isp->txcnt; - if (n > 0) { + size_t txed = isp->txsize - isp->txcnt; + if (txed > 0) { /* Transfer not completed, there are more packets to send.*/ - if (n > epcp->in_maxsize) - n = epcp->in_maxsize; + if (txed > epcp->in_maxsize) + txed = epcp->in_maxsize; /* Writes the packet from the defined buffer.*/ isp->txbuf += isp->txlast; - isp->txlast = n; - - sn32_usb_write_fifo(0, isp->txbuf, n, true); + isp->txlast = txed; + osalSysLockFromISR(); + sn32_usb_write_fifo(0, isp->txbuf, txed, true); + osalSysUnlockFromISR(); - USB_EPnAck(USB_EP0, n); + EPCTL_SET_STAT_ACK(0, txed); } - else - { - //USB_EPnNak(USB_EP0); //not needed - + else { + /* Transfer complete, invokes the callback.*/ + //EPCTL_SET_STAT_NAK(0); //useless mcu resets it anyways _usb_isr_invoke_in_cb(usbp, 0); } - __USB_CLRINSTS(mskEP0_IN); + SN32_USB->INSTSC = (mskEP0_IN); } - else if (iwIntFlag & mskEP0_OUT) - { + else if (iwIntFlag & mskEP0_OUT) { USBOutEndpointState *osp = epcp->out_state; /* OUT */ - n = SN_USB->EP0CTL & mskEPn_CNT; - if (n > epcp->out_maxsize) - n = epcp->out_maxsize; + size_t rxed = SN32_USB->EPCTL[0] & mskEPn_CNT; + if (rxed) { + osalSysLockFromISR(); + sn32_usb_read_fifo(0, osp->rxbuf, rxed, true); + osalSysUnlockFromISR(); - //Just being paranoid here. keep here while debugging EP handling issue - //TODO: clean it up when packets are properly handled - if (epcp->out_state->rxsize >= n) { - //we are ok to copy n bytes to buf - sn32_usb_read_fifo(USB_EP0, osp->rxbuf, n, true); - epcp->out_state->rxsize -= n; - } - else if (epcp->out_state->rxsize > 0) { - //we dont have enough buffer to receive n bytes - //copy only size availabe on buffer - n = epcp->out_state->rxsize; - sn32_usb_read_fifo(USB_EP0, osp->rxbuf, n, true); - epcp->out_state->rxsize -= n; - } - else { - //well buffer is 0 size. strange. do nothing. - n = 0; - } - - epcp->out_state->rxbuf += n; - epcp->out_state->rxcnt += n; - if (epcp->out_state->rxpkts > 0) { + /* Update transaction data */ + epcp->out_state->rxbuf += rxed; + epcp->out_state->rxcnt += rxed; + epcp->out_state->rxsize -= rxed; epcp->out_state->rxpkts -= 1; - } - if (epcp->out_state->rxpkts == 0) - { - //done with transfer - //USB_EPnNak(USB_EP0); //useless mcu resets it anyways - _usb_isr_invoke_out_cb(usbp, 0); - } - else { - //more to receive - USB_EPnAck(USB_EP0, 0); + /* The transaction is completed if the specified number of packets + has been received or the current packet is a short packet.*/ + if ((rxed < epcp->out_maxsize) || (epcp->out_state->rxpkts == 0)) + { + /* Transfer complete, invokes the callback.*/ + //EPCTL_SET_STAT_NAK(0); //useless mcu resets it anyways + _usb_isr_invoke_out_cb(usbp, 0); + } + else { + /* Transfer not complete, there are more packets to receive.*/ + EPCTL_SET_STAT_ACK(0, 0); + } } - __USB_CLRINSTS(mskEP0_OUT); + SN32_USB->INSTSC = (mskEP0_OUT); } - else if (iwIntFlag & (mskEP0_IN_STALL|mskEP0_OUT_STALL)) + else if (iwIntFlag & (mskEP0_IN_STALL)) { + /* EP0_IN_STALL */ + usb_lld_stall_in(usbp, 0); + SN32_USB->INSTSC = (mskEP0_IN_STALL); + } + else if (iwIntFlag & (mskEP0_OUT_STALL)) { - /* EP0_IN_OUT_STALL */ - USB_EPnStall(USB_EP0); - SN_USB->INSTSC = (mskEP0_IN_STALL|mskEP0_OUT_STALL); + /* EP0_OUT_STALL */ + usb_lld_stall_out(usbp, 0); + SN32_USB->INSTSC = (mskEP0_OUT_STALL); } } ///////////////////////////////////////////////// /* Device Status Interrupt (EPnACK) */ ///////////////////////////////////////////////// - else if (iwIntFlag & (mskEP4_ACK|mskEP3_ACK|mskEP2_ACK|mskEP1_ACK)) - { + else if (iwIntFlag & (mskEP6_ACK|mskEP5_ACK|mskEP4_ACK|mskEP3_ACK|mskEP2_ACK|mskEP1_ACK)) { // Determine the interrupting endpoint, direction, and clear the interrupt flag - if(iwIntFlag & mskEP1_ACK) - { - handleACK(usbp, USB_EP1); - __USB_CLRINSTS(mskEP1_ACK); - } - if(iwIntFlag & mskEP2_ACK) - { - handleACK(usbp, USB_EP2); - __USB_CLRINSTS(mskEP2_ACK); - } - if(iwIntFlag & mskEP3_ACK) - { - handleACK(usbp, USB_EP3); - __USB_CLRINSTS(mskEP3_ACK); - } - if(iwIntFlag & mskEP4_ACK) - { - handleACK(usbp, USB_EP4); - __USB_CLRINSTS(mskEP4_ACK); + for(usbep_t ep = 1; ep <= USB_MAX_ENDPOINTS; ep++) { + if (iwIntFlag & mskEPn_ACK(ep)){ + handleACK(usbp, ep); + SN32_USB->INSTSC = (mskEPn_ACK(ep)); + } } } - else if (iwIntFlag & (mskEP4_NAK|mskEP3_NAK|mskEP2_NAK|mskEP1_NAK)) - { + else if (iwIntFlag & (mskEP6_NAK|mskEP5_NAK|mskEP4_NAK|mskEP3_NAK|mskEP2_NAK|mskEP1_NAK)) { // Determine the interrupting endpoint, direction, and clear the interrupt flag - if (iwIntFlag & mskEP1_NAK) - { - handleNAK(usbp, USB_EP1); - __USB_CLRINSTS(mskEP1_NAK); - } - if (iwIntFlag & mskEP2_NAK) - { - handleNAK(usbp, USB_EP2); - __USB_CLRINSTS(mskEP2_NAK); - } - if (iwIntFlag & mskEP3_NAK) - { - handleNAK(usbp, USB_EP3); - __USB_CLRINSTS(mskEP3_NAK); - } - if (iwIntFlag & mskEP4_NAK) - { - handleNAK(usbp, USB_EP4); - __USB_CLRINSTS(mskEP4_NAK); + for(usbep_t ep = 1; ep <= USB_MAX_ENDPOINTS; ep++) { + if (iwIntFlag & mskEPn_NAK(ep)){ + handleNAK(usbp, ep); + SN32_USB->INSTSC = (mskEPn_NAK(ep)); + } } } ///////////////////////////////////////////////// /* Device Status Interrupt (SOF) */ ///////////////////////////////////////////////// - if ((iwIntFlag & mskUSB_SOF) && (SN_USB->INTEN & mskUSB_SOF_IE)) - { + if ((iwIntFlag & mskUSB_SOF) && (SN32_USB->INTEN & mskUSB_SOF_IE)) { /* SOF */ _usb_isr_invoke_sof_cb(usbp); - __USB_CLRINSTS(mskUSB_SOF); + SN32_USB->INSTSC = (mskUSB_SOF); } } void handleACK(USBDriver* usbp, usbep_t ep) { uint8_t out = 0; uint8_t cnt = 0; - size_t n; - if(ep == USB_EP1) - { - out = ( SN_USB->CFG & mskEP1_DIR ) == mskEP1_DIR; - cnt = SN_USB->EP1CTL & mskEPn_CNT; - } - else if(ep == USB_EP2) - { - out = ( SN_USB->CFG & mskEP2_DIR ) == mskEP2_DIR; - cnt = SN_USB->EP2CTL & mskEPn_CNT; - } - else if(ep == USB_EP3) - { - out = ( SN_USB->CFG & mskEP3_DIR ) == mskEP3_DIR; - cnt = SN_USB->EP3CTL & mskEPn_CNT; - } - else if(ep == USB_EP4) - { - out = ( SN_USB->CFG & mskEP4_DIR ) == mskEP4_DIR; - cnt = SN_USB->EP4CTL & mskEPn_CNT; + if(ep > 0 && ep <= USB_MAX_ENDPOINTS) { + out = ( SN32_USB->CFG & mskEPn_DIR(ep) ) == mskEPn_DIR(ep); + cnt = SN32_USB->EPCTL[ep] & mskEPn_CNT; } else { return; @@ -459,76 +402,59 @@ void handleACK(USBDriver* usbp, usbep_t ep) { USBOutEndpointState *osp = epcp->out_state; // Process based on endpoint direction - if(out) - { + if(out) { // Read size of received data - n = cnt; - - if (n > epcp->out_maxsize) - n = epcp->out_maxsize; - - //state is NAK already - //Just being paranoid here. keep here while debugging EP handling issue - //TODO: clean it up when packets are properly handled - if (epcp->out_state->rxsize >= n) { - //we are ok to copy n bytes to buf - sn32_usb_read_fifo(ep, osp->rxbuf, n, true); - epcp->out_state->rxsize -= n; - } - else if (epcp->out_state->rxsize > 0) { - //we dont have enough buffer to receive n bytes - //copy only size availabe on buffer - n = epcp->out_state->rxsize; - sn32_usb_read_fifo(ep, osp->rxbuf, n, true); - epcp->out_state->rxsize -= n; - } - else { - //well buffer is 0 size. strange. do nothing. - n = 0; - } - osp->rxbuf += n; - - epcp->out_state->rxcnt += n; - if (epcp->out_state->rxpkts > 0) { + size_t rxed = cnt; + if (rxed) { + osalSysLockFromISR(); + sn32_usb_read_fifo(ep, osp->rxbuf, rxed, true); + osalSysUnlockFromISR(); + + /* Update transaction data */ + epcp->out_state->rxbuf += rxed; + epcp->out_state->rxcnt += rxed; + epcp->out_state->rxsize -= rxed; epcp->out_state->rxpkts -= 1; - } - if (n < epcp->out_maxsize || epcp->out_state->rxpkts == 0) - { - _usb_isr_invoke_out_cb(usbp, ep); - } - else - { - //not done. keep on receiving - USB_EPnAck(ep, 0); + /* The transaction is completed if the specified number of packets + has been received or the current packet is a short packet.*/ + if ((rxed < epcp->out_maxsize) || (epcp->out_state->rxpkts == 0)) + { + /* Transfer complete, invokes the callback.*/ + //EPCTL_SET_STAT_NAK(0); //useless mcu resets it anyways + _usb_isr_invoke_out_cb(usbp, ep); + } + else { + /* Transfer not complete, there are more packets to receive.*/ + EPCTL_SET_STAT_ACK(ep, 0); + } } } - else - { + else { // Process transmit queue isp->txcnt += isp->txlast; - n = isp->txsize - isp->txcnt; + size_t txed = isp->txsize - isp->txcnt; - if (n > 0) + if (txed > 0) { /* Transfer not completed, there are more packets to send.*/ - if (n > epcp->in_maxsize) + if (txed > epcp->in_maxsize) { - n = epcp->in_maxsize; + txed = epcp->in_maxsize; } /* Writes the packet from the defined buffer.*/ isp->txbuf += isp->txlast; - isp->txlast = n; - - sn32_usb_write_fifo(ep, isp->txbuf, n, true); + isp->txlast = txed; + osalSysLockFromISR(); + sn32_usb_write_fifo(ep, isp->txbuf, txed, true); + osalSysUnlockFromISR(); - USB_EPnAck(ep, n); + EPCTL_SET_STAT_ACK(ep, txed); } - else - { - //USB_EPnNak(ep); //not needed here it is autoreset to NAK already - + else { + /* Transfer complete, invokes the callback.*/ + //EPCTL_SET_STAT_NAK(ep); //useless mcu resets it anyways _usb_isr_invoke_in_cb(usbp, ep); } } @@ -536,18 +462,9 @@ void handleACK(USBDriver* usbp, usbep_t ep) { void handleNAK(USBDriver *usbp, usbep_t ep) { uint8_t out = 0; - //handle it properly - if (ep == USB_EP1) { - out = ( SN_USB->CFG & mskEP1_DIR ) == mskEP1_DIR; - } - else if (ep == USB_EP2) { - out = ( SN_USB->CFG & mskEP2_DIR ) == mskEP2_DIR; - } - else if (ep == USB_EP3) { - out = ( SN_USB->CFG & mskEP3_DIR ) == mskEP3_DIR; - } - else if (ep == USB_EP4) { - out = ( SN_USB->CFG & mskEP4_DIR ) == mskEP4_DIR; + + if(ep > 0 && ep <= USB_MAX_ENDPOINTS) { + out = ( SN32_USB->CFG & mskEPn_DIR(ep) ) == mskEPn_DIR(ep); } else { return; @@ -596,7 +513,7 @@ void handleNAK(USBDriver *usbp, usbep_t ep) { else if (nakcnt[ep] > 2) { //3-10 nakcnt[ep]++; - USB_EPnAck(ep, 0); + EPCTL_SET_STAT_ACK(ep, 0); } else { //1-2 @@ -611,7 +528,7 @@ void handleNAK(USBDriver *usbp, usbep_t ep) { /*===========================================================================*/ /* Driver interrupt handlers and threads. */ /*===========================================================================*/ - +#if (SN32_USB_USE_USB1 == TRUE) || defined(__DOXYGEN__) /** * @brief SN32 USB Interrupt handler. * @@ -623,7 +540,7 @@ OSAL_IRQ_HANDLER(SN32_USB_HANDLER) { usb_lld_serve_interrupt(&USBD1); OSAL_IRQ_EPILOGUE(); } - +#endif /* SN32_USB_USE_USB1 == TRUE */ /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -634,10 +551,10 @@ OSAL_IRQ_HANDLER(SN32_USB_HANDLER) { * @notapi */ void usb_lld_init(void) { - #if PLATFORM_USB_USE_USB1 == TRUE +#if SN32_USB_USE_USB1 == TRUE /* Driver initialization.*/ usbObjectInit(&USBD1); - #endif +#endif /* SN32_USB_USE_USB1 == TRUE */ } /** @@ -648,16 +565,29 @@ void usb_lld_init(void) { * @notapi */ void usb_lld_start(USBDriver *usbp) { - if (usbp->state == USB_STOP) { - /* Enables the peripheral.*/ - #if PLATFORM_USB_USE_USB1 == TRUE - if (&USBD1 == usbp) { - USB_Init(); - nvicEnableVector(SN32_USB_NUMBER, SN32_USB_IRQ_PRIORITY); - } - #endif + if (usbp->state == USB_STOP) { + /* Clock activation.*/ +#if SN32_USB_USE_USB1 + if (&USBD1 == usbp) { + /* USB clock enabled.*/ + sys1EnableUSB(); + /* Powers up the transceiver while holding the USB in reset state.*/ + SN32_USB->SGCTL = (mskBUS_DRVEN|mskBUS_J_STATE); + SN32_USB->CFG = (mskVREG33_EN|mskPHY_EN|mskDPPU_EN|mskSIE_EN|mskESD_EN); + /* Set up hardware configuration.*/ + SN32_USB->PHYPRM = 0x80000000; + SN32_USB->PHYPRM2 = 0x00004004; + /* Enable the USB Bus Interrupts.*/ + SN32_USB->INTEN = mskBUS_IE; + + nvicEnableVector(SN32_USB_NUMBER, SN32_USB_IRQ_PRIORITY); + /* Releases the reset state.*/ + SN32_USB->SGCTL &= ~mskBUS_DRVEN; } - /* Configures the peripheral.*/ +#endif /* SN32_USB_USE_USB1 == TRUE */ + /* Reset procedure enforced on driver start.*/ + usb_lld_reset(usbp); + } } /** @@ -668,14 +598,15 @@ void usb_lld_start(USBDriver *usbp) { * @notapi */ void usb_lld_stop(USBDriver *usbp) { - if (usbp->state == USB_READY) { - /* Resets the peripheral.*/ - - /* Disables the peripheral.*/ - #if PLATFORM_USB_USE_USB1 == TRUE - if (&USBD1 == usbp) { - } - #endif + /* If in ready state then disables the USB clock.*/ + if (usbp->state != USB_STOP) { +#if SN32_USB_USE_USB1 == TRUE + /* Disables the peripheral.*/ + if (&USBD1 == usbp) { + nvicDisableVector(SN32_USB_NUMBER); + sys1DisableUSB(); + } +#endif /* SN32_USB_USE_USB1 == TRUE */ } } @@ -688,10 +619,26 @@ void usb_lld_stop(USBDriver *usbp) { */ void usb_lld_reset(USBDriver *usbp) { /* Post reset initialization.*/ + SN32_USB->INSTSC = (0xFFFFFFFF); + + /* Set the address to zero during enumeration.*/ + usbp->address = 0; + SN32_USB->ADDR = 0; + + /* Resets the packet memory allocator.*/ + usb_pm_reset(usbp); /* EP0 initialization.*/ usbp->epc[0] = &ep0config; usb_lld_init_endpoint(usbp, 0); + + /* Enable other interrupts.*/ + SN32_USB->INTEN |= (mskUSB_IE|mskEPnACK_EN|mskBUSWK_IE|mskUSB_SOF_IE); + SN32_USB->INTEN |= (mskEP1_NAK_EN|mskEP2_NAK_EN|mskEP3_NAK_EN|mskEP4_NAK_EN); +#if (USB_ENDPOINTS_NUMBER > 4) + SN32_USB->INTEN |= (mskEP5_NAK_EN|mskEP6_NAK_EN); +#endif /* (USB_ENDPOINTS_NUMBER > 4) */ + } /** @@ -702,9 +649,8 @@ void usb_lld_reset(USBDriver *usbp) { * @notapi */ void usb_lld_set_address(USBDriver *usbp) { - // It seems the address must be set after an endpoint interrupt, so store it for now. - // It will be written to SN_USB->ADDR in the EP0 IN interrupt - address = usbp->address; + + SN32_USB->ADDR = usbp->address & 0x7F; } /** @@ -718,6 +664,11 @@ void usb_lld_set_address(USBDriver *usbp) { void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { const USBEndpointConfig *epcp = usbp->epc[ep]; + /* Make sure direction flags are not set.*/ + if(ep > 0 && ep <= USB_MAX_ENDPOINTS) { + SN32_USB->CFG &= ~mskEPn_DIR(ep); + } + /* Set the endpoint type. */ switch (epcp->ep_mode & USB_EP_MODE_TYPE) { case USB_EP_MODE_TYPE_ISOC: @@ -732,60 +683,35 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { /* IN endpoint? */ if (epcp->in_state != NULL) { - // Set endpoint direction flag in USB configuration register - switch (ep) - { - case 1: - SN_USB->CFG &= ~mskEP1_DIR; - break; - case 2: - SN_USB->CFG &= ~mskEP2_DIR; - break; - case 3: - SN_USB->CFG &= ~mskEP3_DIR; - break; - case 4: - SN_USB->CFG &= ~mskEP4_DIR; - break; + if(ep ==0) { + usb_lld_stall_in(usbp, 0); + } + else if(ep <= USB_MAX_ENDPOINTS) { + /* Set endpoint direction flag in USB configuration register.*/ + SN32_USB->CFG &= ~mskEPn_DIR(ep); + /* Set endpoint PMA buffer offset in USB configuration register.*/ + uint32_t buff_addr = usb_pm_alloc(usbp, epcp->in_maxsize); + USB_SET_BUFFER_OFST(ep,buff_addr); } } /* OUT endpoint? */ if (epcp->out_state != NULL) { - // Set endpoint direction flag in USB configuration register - // Also enable ACK state - switch (ep) - { - case 1: - SN_USB->CFG |= mskEP1_DIR; - break; - case 2: - SN_USB->CFG |= mskEP2_DIR; - break; - case 3: - SN_USB->CFG |= mskEP3_DIR; - break; - case 4: - SN_USB->CFG |= mskEP4_DIR; - break; + if(ep ==0) { + usb_lld_stall_out(usbp, 0); + } + else if(ep <= USB_MAX_ENDPOINTS) { + /* Set endpoint direction flag in USB configuration register.*/ + SN32_USB->CFG |= mskEPn_DIR(ep); + /* Set endpoint PMA buffer offset in USB configuration register.*/ + uint32_t buff_addr = usb_pm_alloc(usbp, epcp->out_maxsize); + USB_SET_BUFFER_OFST(ep,buff_addr); } } /* Enable endpoint. */ - switch(ep) - { - case 1: - SN_USB->EP1CTL |= mskEPn_ENDP_EN; - break; - case 2: - SN_USB->EP2CTL |= mskEPn_ENDP_EN; - break; - case 3: - SN_USB->EP3CTL |= mskEPn_ENDP_EN; - break; - case 4: - SN_USB->EP4CTL |= mskEPn_ENDP_EN; - break; + if(ep <= USB_MAX_ENDPOINTS) { + SN32_USB->EPCTL[ep] |= mskEPn_ENDP_EN; } } @@ -797,11 +723,14 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { * @notapi */ void usb_lld_disable_endpoints(USBDriver *usbp) { - unsigned i; + + /* Resets the packet memory allocator.*/ + usb_pm_reset(usbp); /* Disabling all endpoints.*/ - for (i = 1; i <= USB_MAX_ENDPOINTS; i++) { - USB_EPnDisable(i); + for(usbep_t ep=1; ep <= USB_MAX_ENDPOINTS; ep++) { + SN32_USB->EPCTL[ep] = 0; + SN32_USB->CFG &= ~mskEPn_DIR(ep); } } @@ -818,22 +747,14 @@ void usb_lld_disable_endpoints(USBDriver *usbp) { * @notapi */ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { + (void)usbp; if (ep > USB_MAX_ENDPOINTS) return EP_STATUS_DISABLED; - if (!USB_EPnEnabled(ep)) + if ((SN32_USB->EPCTL[ep] & mskEPn_ENDP_EN) != mskEPn_ENDP_EN) return EP_STATUS_DISABLED; - if (USB_EPnStalled(ep)) + if ((SN32_USB->EPCTL[ep] & mskEPn_ENDP_STATE) == mskEPn_ENDP_STATE_STALL) return EP_STATUS_STALLED; return EP_STATUS_ACTIVE; -/* - if (SN_USB->INSTS & mskEP0_OUT) { - return EP_STATUS_DISABLED; - } else if (SN_USB->INSTS & mskEP0_OUT_STALL) { - return EP_STATUS_STALLED; - } else { - return EP_STATUS_ACTIVE; - } -*/ } /** @@ -849,22 +770,14 @@ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { * @notapi */ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { + (void)usbp; if (ep > USB_MAX_ENDPOINTS) return EP_STATUS_DISABLED; - if (!USB_EPnEnabled(ep)) + if ((SN32_USB->EPCTL[ep] & mskEPn_ENDP_EN) != mskEPn_ENDP_EN) return EP_STATUS_DISABLED; - if (USB_EPnStalled(ep)) + if ((SN32_USB->EPCTL[ep] & mskEPn_ENDP_STATE) == mskEPn_ENDP_STATE_STALL) return EP_STATUS_STALLED; return EP_STATUS_ACTIVE; -/* - if (SN_USB->INSTS & mskEP0_IN) { - return EP_STATUS_DISABLED; - } else if (SN_USB->INSTS & mskEP0_IN_STALL) { - return EP_STATUS_STALLED; - } else { - return EP_STATUS_ACTIVE; - } -*/ } /** @@ -883,8 +796,9 @@ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) { */ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { - + osalSysLockFromISR(); sn32_usb_read_fifo(ep, buf, 8, false); + osalSysUnlockFromISR(); } /** @@ -905,8 +819,7 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) { else osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / usbp->epc[ep]->out_maxsize); - osp->rxcnt = 0;//haven't received anything yet - USB_EPnAck(ep, 0); + EPCTL_SET_STAT_ACK(ep, 0); } /** @@ -923,26 +836,23 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep) USBInEndpointState *isp = usbp->epc[ep]->in_state; /* Transfer initialization.*/ - //who handles 0 packet ack on setup? n = isp->txsize; - if((n >= 0) || (ep == 0)) - { + if((n >= 0) || (ep == 0)) { + if (n > (size_t)usbp->epc[ep]->in_maxsize) n = (size_t)usbp->epc[ep]->in_maxsize; isp->txlast = n; - + osalSysLockFromISR(); sn32_usb_write_fifo(ep, isp->txbuf, n, false); - + osalSysUnlockFromISR(); nakcnt[ep] = 1; - USB_EPnAck(ep, n); + EPCTL_SET_STAT_ACK(ep, n); } - else - { + else { _usb_isr_invoke_in_cb(usbp, ep); } - } /** @@ -954,9 +864,17 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep) * @notapi */ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { - - USB_EPnStall(ep); - + (void)usbp; + if (ep == 0 ) { + if (SN32_USB->INSTS & mskEP0_PRESETUP) { + return; + } + if (SN32_USB->INSTS & mskEP0_OUT_STALL) { + SN32_USB->EPCTL[ep] |= mskEP0_OUT_STALL_EN; + return; + } + } + EPCTL_SET_STAT_STALL(ep); } /** @@ -968,9 +886,17 @@ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { * @notapi */ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { - - USB_EPnStall(ep); - + (void)usbp; + if (ep == 0 ) { + if (SN32_USB->INSTS & mskEP0_PRESETUP) { + return; + } + if (SN32_USB->INSTS & mskEP0_IN_STALL) { + SN32_USB->EPCTL[ep] |= mskEP0_IN_STALL_EN; + return; + } + } + EPCTL_SET_STAT_STALL(ep); } /** @@ -982,10 +908,11 @@ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { * @notapi */ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { - if (ep > USB_MAX_ENDPOINTS) - return; - USB_EPnNak(ep); - //__USB_CLRINSTS(mskEP0_OUT); + (void)usbp; + /* Makes sure to not put to NAK an endpoint that is already + transferring.*/ + if (!(SN32_USB->EPCTL[ep] & mskEPn_ENDP_STATE_NAK)) + EPCTL_SET_STAT_NAK(ep); } /** @@ -997,10 +924,11 @@ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) { * @notapi */ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { - if (ep > USB_MAX_ENDPOINTS) - return; - USB_EPnNak(ep); - //__USB_CLRINSTS(mskEP0_IN); + (void)usbp; + /* Makes sure to not put to NAK an endpoint that is already + transferring.*/ + if (!(SN32_USB->EPCTL[ep] & mskEPn_ENDP_STATE_NAK)) + EPCTL_SET_STAT_NAK(ep); } #endif /* HAL_USE_USB == TRUE */ diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.h b/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.h index 46437cd600..44a19f2ccf 100644 --- a/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.h +++ b/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.h @@ -28,21 +28,25 @@ #if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__) #include "sn32_usb.h" -#include "usbhw.h" /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ +/** + * @brief Maximum endpoint address. + */ +#define USB_MAX_ENDPOINTS USB_ENDPOINTS_NUMBER + /** * @brief Status stage handling method. */ #define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW /** - * @brief The address can be changed immediately upon packet reception. + * @brief This device requires the address change after the status packet. */ -#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS +#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS /** * @brief Method for set address acknowledge. @@ -62,8 +66,8 @@ * @details If set to @p TRUE the support for USB1 is included. * @note The default is @p FALSE. */ -#if !defined(PLATFORM_USB_USE_USB1) || defined(__DOXYGEN__) -#define PLATFORM_USB_USE_USB1 TRUE +#if !defined(SN32_USB_USE_USB1) || defined(__DOXYGEN__) +#define SN32_USB_USE_USB1 TRUE #endif /** @@ -72,6 +76,13 @@ #if !defined(SN32_USB_IRQ_PRIORITY) || defined(__DOXYGEN__) #define SN32_USB_IRQ_PRIORITY 3 #endif + +/** + * @brief Host wake-up procedure duration. + */ +#if !defined(SN32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__) +#define SN32_USB_HOST_WAKEUP_DURATION 2 +#endif /** @} */ /*===========================================================================*/ @@ -195,7 +206,6 @@ typedef struct { */ USBOutEndpointState *out_state; /* End of the mandatory fields.*/ - /* End of the mandatory fields.*/ /** * @brief Reserved field, not currently used. * @note Initialize this field to 1 in order to be forward compatible. @@ -332,7 +342,7 @@ struct USBDriver { * * @notapi */ -#define usb_lld_get_frame_number(usbp) 0 +#define usb_lld_get_frame_number(usbp) (SN32_USB->FRMNO & mskFRAME_NO) /** * @brief Returns the exact size of a receive transaction. @@ -356,50 +366,39 @@ struct USBDriver { * * @api */ -#define usb_lld_connect_bus(usbp) +#define usb_lld_connect_bus(usbp) \ + do { \ + SN32_USB->CFG |= mskDPPU_EN; \ + } while (false) /** * @brief Disconnect the USB device. * * @api */ -#define usb_lld_disconnect_bus(usbp) +#define usb_lld_disconnect_bus(usbp) \ + do { \ + SN32_USB->CFG &= ~mskDPPU_EN; \ + } while (false) + /** * @brief Start of host wake-up procedure. * * @notapi */ -#define usb_lld_wakeup_host(usbp) { \ - USB_RemoteWakeUp(); \ -} +#define usb_lld_wakeup_host(usbp) \ + do { \ + SN32_USB->SGCTL = (mskBUS_DRVEN|mskBUS_K_STATE); \ + osalThreadSleepMilliseconds(SN32_USB_HOST_WAKEUP_DURATION); \ + SN32_USB->SGCTL &= ~mskBUS_DRVEN; \ + } while (false) /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ -/* Descriptor related */ -/* bmAttributes in Endpoint Descriptor */ -#define USB_ENDPOINT_TYPE_MASK 0x03 -#define USB_ENDPOINT_TYPE_CONTROL 0x00 -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 -#define USB_ENDPOINT_TYPE_BULK 0x02 -#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 -#define USB_ENDPOINT_SYNC_MASK 0x0C -#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 -#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 -#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 -#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C -#define USB_ENDPOINT_USAGE_MASK 0x30 -#define USB_ENDPOINT_USAGE_DATA 0x00 -#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 -#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 -#define USB_ENDPOINT_USAGE_RESERVED 0x30 - -/* bEndpointAddress in Endpoint Descriptor */ -#define USB_ENDPOINT_DIRECTION_MASK 0x80 - -#if (PLATFORM_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__) +#if (SN32_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__) extern USBDriver USBD1; #endif @@ -424,6 +423,8 @@ extern "C" { void usb_lld_stall_in(USBDriver *usbp, usbep_t ep); void usb_lld_clear_out(USBDriver *usbp, usbep_t ep); void usb_lld_clear_in(USBDriver *usbp, usbep_t ep); + void handleACK(USBDriver* usbp, usbep_t ep); + void handleNAK(USBDriver* usbp, usbep_t ep); #ifdef __cplusplus } #endif diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/USB/sn32_usb.h b/os/hal/ports/SN32/LLD/SN32F2xx/USB/sn32_usb.h index b2bf25d593..c5974b06fb 100644 --- a/os/hal/ports/SN32/LLD/SN32F2xx/USB/sn32_usb.h +++ b/os/hal/ports/SN32/LLD/SN32F2xx/USB/sn32_usb.h @@ -15,10 +15,9 @@ */ /** - * @file USBv1/sn32_usb.h + * @file USB/sn32_usb.h * @brief SN32 USB registers layout header. - * @note This file requires definitions from the ST STM32 header files - * sn32f124x.h + * @note This file requires definitions from the SN32 header files * * @addtogroup USB * @{ @@ -27,32 +26,88 @@ #ifndef SN32_USB_H #define SN32_USB_H -// TODO: ENDPOINTS nubmer is chip dependent and needs to be organized better +#include "usbhw.h" + /** * @brief Number of the available endpoints. * @details This value does not include the endpoint 0 which is always present. */ -#define USB_MAX_ENDPOINTS 4 +#define HAL_MAX_ENDPOINTS 6 +#if (defined(SN32F240B) || defined(SN32F260)) +#define USB_ENDPOINTS_NUMBER 4 +#define SN32_USB_PMA_SIZE 256 +#elif (defined(SN32F280) || defined(SN32F290)) +#define USB_ENDPOINTS_NUMBER HAL_MAX_ENDPOINTS +#define SN32_USB_PMA_SIZE 512 +#else +#error "USB driver not supported in the selected device" +#endif + +/** + * @brief USB registers block. + */ + typedef struct { + volatile uint32_t INTEN; /*!< (@ 0x00000000) Offset:0x00 USB Interrupt Enable Register */ + volatile uint32_t INSTS; /*!< (@ 0x00000004) Offset:0x04 USB Interrupt Event Status Register */ + volatile uint32_t INSTSC; /*!< (@ 0x00000008) Offset:0x08 USB Interrupt Event Status Clear Register */ + volatile uint32_t ADDR; /*!< (@ 0x0000000C) Offset:0x0C USB Device Address Register */ + volatile uint32_t CFG; /*!< (@ 0x00000010) Offset:0x10 USB Configuration Register */ + volatile uint32_t SGCTL; /*!< (@ 0x00000014) Offset:0x14 USB Signal Control Register */ + volatile uint32_t EPCTL[HAL_MAX_ENDPOINTS +1]; /*!< (@ 0x00000018) Offset:0x18 USB Endpoint 0-6 Control Registers */ + volatile uint32_t RESERVED[2]; + volatile uint32_t EPTOGGLE; /*!< (@ 0x0000003C) Offset:0x3C USB Endpoint Data Toggle Register */ + volatile uint32_t RESERVED1[2]; + volatile uint32_t EPBUFOS[HAL_MAX_ENDPOINTS]; /*!< (@ 0x00000048) Offset:0x48 USB Endpoint 1-6 Buffer Offset Registers */ + volatile uint32_t FRMNO; /*!< (@ 0x00000060) Offset:0x60 USB Frame Number Register */ + volatile uint32_t PHYPRM; /*!< (@ 0x00000064) Offset:0x64 USB PHY Parameter Register */ + volatile uint32_t RESERVED3; + volatile uint32_t PHYPRM2; /*!< (@ 0x0000006C) Offset:0x6C USB PHY Parameter 2 Register */ + volatile uint32_t PS2CTL; /*!< (@ 0x00000070) Offset:0x70 PS/2 Control Register */ + volatile uint32_t RESERVED4; + volatile uint32_t RWADDR; /*!< (@ 0x00000078) Offset:0x78 USB Read/Write Address Register */ + volatile uint32_t RWDATA; /*!< (@ 0x0000007C) Offset:0x7C USB Read/Write Data Register */ + volatile uint32_t RWSTATUS; /*!< (@ 0x00000080) Offset:0x80 USB Read/Write Status Register */ + volatile uint32_t RWADDR2; /*!< (@ 0x00000084) Offset:0x84 USB Read/Write Address Register 2 */ + volatile uint32_t RWDATA2; /*!< (@ 0x00000088) Offset:0x88 USB Read/Write Data Register 2 */ + volatile uint32_t RWSTATUS2; /*!< (@ 0x0000008C) Offset:0x8C USB Read/Write Status Register 2 */ +} sn32_usb_t; /*!< Size = 144 (0x90) */ + +/** @} */ /** * @brief USB registers block numeric address. */ -#define SN32_USB_BASE SN_USB_BASE +#define SN32_USB_BASE SN_USB_BASE /** * @brief USB RAM numeric address. */ -#define SN32_USBRAM_BASE SN_USB_BASE + 0x100 +#define SN32_USBRAM_BASE (SN_USB_BASE + 0x100) /** * @brief Pointer to the USB registers block. */ -// #define SN32_USB ((sn32_usb_t *)SN32_USB_BASE) +#define SN32_USB ((sn32_usb_t *)SN32_USB_BASE) /** * @brief Pointer to the USB RAM. */ -#define SN32_USBRAM ((sn32_usb_pma_t *)SN32_USBRAM_BASE) +#define SN32_USBRAM ((sn32_usb_pma_t *)SN32_USBRAM_BASE) +#define mskEPn_NAK(ep) (0x1<<(ep -1)) +#define mskEPn_ACK(ep) (0x1<<(8+(ep-1))) +#define mskEPn_DIR(ep) (0x1<<(ep-1)) +#define mskEPn_DATA_TOGGLE(ep) (0x1<<(ep-1)) + +#define EPCTL_SET_STAT_ACK(ep, bBytecnt) \ + SN32_USB->EPCTL[ep] = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_ACK|bBytecnt) +#define EPCTL_SET_STAT_NAK(ep) \ + SN32_USB->EPCTL[ep] = (mskEPn_ENDP_EN) +#define EPCTL_SET_STAT_STALL(ep) \ + SN32_USB->EPCTL[ep] = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_STALL) +#define EPCTL_TOGGLE(ep) \ + SN32_USB->EPTOGGLE = mskEPn_DATA_TOGGLE(ep) +#define USB_SET_BUFFER_OFST(ep, addr) \ + SN32_USB->EPBUFOS[ep-1] = addr #endif /* SN32_USB_H */ diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c b/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c deleted file mode 100644 index 41d51db6b3..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c +++ /dev/null @@ -1,381 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: usbhw.c - * Purpose: USB Custom User Module - * Version: V1.01 - * Date: 2017/07 - *------------------------------------------------------------------------------*/ -#include -#include "SN32F200_Def.h" -#include -#include "usbhw.h" - -const uint32_t wUSB_EPnOffset[5] = { - 0, EP1_BUFFER_OFFSET_VALUE, - EP2_BUFFER_OFFSET_VALUE, EP3_BUFFER_OFFSET_VALUE, - EP4_BUFFER_OFFSET_VALUE}; - -const uint32_t wUSB_EPnMaxPacketSize[5] = { - USB_EP0_PACKET_SIZE, USB_EP1_PACKET_SIZE, - USB_EP2_PACKET_SIZE, USB_EP3_PACKET_SIZE, - USB_EP4_PACKET_SIZE}; - -/***************************************************************************** -* Description :Setting USB for different Power domain -*****************************************************************************/ -#define System_Power_Supply System_Work_at_5_0V // only 3.3V, 5V -#define System_Work_at_3_3V 0 -#define System_Work_at_5_0V 1 - - -/***************************************************************************** -* Function : USB_Init -* Description : 1. setting IDLE_TIME, REPORT_PROTOCOL, S_USB_EP0setupdata.wUSB_Status -* 2. set EP1~EP6 FIFO RAM address. -* 3. save EP1~EP6 FIFO RAM point address. -* 4. save EP1~EP6 Package Size. -* 5. Enable USB function and setting EP1~EP6 Direction. -* 6. NEVER REMOVE !! USB D+/D- Dischage -* 7. Enable USB PHY and USB interrupt. -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_Init(void) -{ - uint32_t wTmp; - - /* Initialize clock and Enable USB PHY. */ - SystemInit(); - SystemCoreClockUpdate(); - sys1EnableUSB(); // Enable USB Clock - - /* Initialize USB EP1~EP4 RAM Start address base on 64-bytes. */ - USB_EPnBufferOffset(1, EP1_BUFFER_OFFSET_VALUE); - USB_EPnBufferOffset(2, EP2_BUFFER_OFFSET_VALUE); - USB_EPnBufferOffset(3, EP3_BUFFER_OFFSET_VALUE); - USB_EPnBufferOffset(4, EP4_BUFFER_OFFSET_VALUE); - - /* Enable the USB Interrupt */ - SN_USB->INTEN = (mskBUS_IE|mskUSB_IE|mskEPnACK_EN|mskBUSWK_IE); - SN_USB->INTEN |= mskEP1_NAK_EN; - SN_USB->INTEN |= mskEP2_NAK_EN; - SN_USB->INTEN |= mskEP3_NAK_EN; - SN_USB->INTEN |= mskEP4_NAK_EN; - SN_USB->INTEN |= mskUSB_SOF_IE; - - NVIC_ClearPendingIRQ(USB_IRQn); - NVIC_EnableIRQ(USB_IRQn); - - /* BUS_DRVEN = 0, BUS_DP = 1, BUS_DN = 0 */ - SN_USB->SGCTL = mskBUS_J_STATE; - - #if (System_Power_Supply == System_Work_at_5_0V) - //----------------------------------// - //Setting USB for System work at 5V // - //----------------------------------// - //VREG33_EN = 1, PHY_EN = 1, DPPU_EN = 1, SIE_EN = 1, ESD_EN = 1 - wTmp = (mskVREG33_EN|mskPHY_EN|mskDPPU_EN|mskSIE_EN|mskESD_EN); - - #elif (System_Power_Supply == System_Work_at_3_3V) - //------------------------------------// - //Setting USB for System work at 3.3V // - //------------------------------------// - //VREG33_EN = 0, PHY_EN = 1, DPPU_EN = 1, SIE_EN = 1, ESD_EN = 1 - wTmp = (mskVREG33_DIS|mskPHY_EN|mskDPPU_EN|mskSIE_EN|mskESD_EN); - #endif - - //** Delay for the connection between Device and Host - // UT_MAIN_DelayNms(50); - // chThdSleepMilliseconds(50); - //** Setting USB Configuration Register - SN_USB->CFG = wTmp; - - SN_USB->PHYPRM = 0x80000000; // PHY parameter - SN_USB->PHYPRM2 = 0x00004004; // PHY parameter 2 -} - - -/***************************************************************************** -* Function : USB_ClrEPnToggle -* Description : USB Clear EP1~EP6 toggle bit to DATA0 -* write 1: toggle bit Auto. -* write 0: clear EPn toggle bit to DATA0 -* Input : hwEPNum ->EP1~EP6 -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_ClrEPnToggle(uint32_t hwEPNum) -{ - SN_USB->EPTOGGLE &= ~(0x1< USB_EP4) - return; - pEPn_ptr = &SN_USB->EP0CTL + wEPNum; - *pEPn_ptr = 0; //** SET DISABLE. No handshake IN/OUT token. -} - - -/***************************************************************************** -* Function : USB_EPnNak -* Description : SET EP1~EP4 is NAK. -* For IN will handshake NAK to IN token. -* For OUT will handshake NAK to OUT token. -* Input : wEPNum -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_EPnNak(uint32_t wEPNum) -{ - volatile uint32_t *pEPn_ptr; - if(wEPNum > USB_EP4) - return; - pEPn_ptr = &SN_USB->EP0CTL + wEPNum; - *pEPn_ptr = mskEPn_ENDP_EN; //** SET NAK -} - - -/***************************************************************************** -* Function : USB_EPnAck -* Description : SET EP1~EP4 is ACK. -* For IN will handshake bBytent to IN token. -* For OUT will handshake ACK to OUT token. -* Input : wEPNum:EP1~EP4. -* bBytecnt: Byte Number of Handshake. -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_EPnAck(uint32_t wEPNum, uint8_t bBytecnt) -{ - volatile uint32_t *pEPn_ptr; - if (wEPNum > USB_EP4) - return; - pEPn_ptr = &SN_USB->EP0CTL + wEPNum; - *pEPn_ptr = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_ACK|bBytecnt); -} - - -/***************************************************************************** -* Function : USB_EPnStall -* Description : SET EP1~EP4 is STALL. -* For IN will handshake STALL to IN token. -* For OUT will handshake STALL to OUT token. -* Input : wEPNum:EP1~EP4. -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_EPnStall(uint32_t wEPNum) -{ - volatile uint32_t *pEPn_ptr; - if(wEPNum > USB_EP4) //** wEPNum != EP0~EP4 - return; - pEPn_ptr = &SN_USB->EP0CTL + wEPNum; - if (wEPNum == USB_EP0) - { - if(SN_USB->INSTS & mskEP0_PRESETUP) - return; - } - *pEPn_ptr = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_STALL); -} - -/***************************************************************************** -* Function : USB_EPnEnabled -* Description : check if EP0~EP4 enabled or not -* Input : wEPNum:EP0~EP4. -* Output : None -* Return : true - enabled/false - disabled -* Note : None -*****************************************************************************/ -_Bool USB_EPnEnabled(uint32_t wEPNum) -{ - volatile uint32_t *pEPn_ptr; - if(wEPNum > USB_EP4) //** wEPNum != EP0~EP4 - return 0; - pEPn_ptr = &SN_USB->EP0CTL + wEPNum; - return (((*pEPn_ptr) & mskEPn_ENDP_EN) == mskEPn_ENDP_EN); -} - -/***************************************************************************** -* Function : USB_EPnStalled -* Description : GET EP0~EP4 state. -* Input : wEPNum:EP0~EP4. -* Output : None -* Return : mskEPn_ENDP_STATE -* Note : None -*****************************************************************************/ -_Bool USB_EPnStalled(uint32_t wEPNum) -{ - volatile uint32_t *pEPn_ptr; - if(wEPNum > USB_EP4) //** wEPNum != EP0~EP4 - return 0; - pEPn_ptr = &SN_USB->EP0CTL + wEPNum; - return (((*pEPn_ptr) & mskEPn_ENDP_STATE) == mskEPn_ENDP_STATE_STALL); -} - -/***************************************************************************** -* Function : USB_RemoteWakeUp -* Description : USB Remote wakeup: USB D+/D- siganl is J-K state. -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_RemoteWakeUp() -{ - __USB_JSTATE_DRIVER; //** J state ;Full speed D+ = 1, D- = 0 - USB_DelayJstate(); - __USB_KSTATE_DRIVER; //** K state ;Full speed D+ = 0, D- = 1 - USB_DelayKstate(); - SN_USB->SGCTL &= ~mskBUS_DRVEN; -} - - -/***************************************************************************** -* Function : USB_DelayJstate -* Description : For J state delay. about 180us -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_DelayJstate() -{ - uint32_t i = 1500>>SN_SYS0->AHBCP; - while(i--); -} - - -/***************************************************************************** -* Function : USB_DelayKstate -* Description : For K state delay. about 9~10ms -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_DelayKstate() -{ - uint32_t i = 80000>>SN_SYS0->AHBCP; //** 10ms @ 12~48MHz - while(i--); //** require delay 1ms ~ 15ms -} - - -/***************************************************************************** -* Function : USB_EPnBufferOffset -* Description : SET EP1~EP4 RAM point address -* Input : wEPNum: EP1~EP4 -* wAddr of device address -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_EPnBufferOffset(uint32_t wEPNum, uint32_t wAddr) -{ - volatile uint32_t *pEPn_ptr; - if ((wEPNum > USB_EP0) && (wEPNum <= USB_EP4)) //** wEPNum = EP1 ~ EP4 - { - pEPn_ptr = &SN_USB->EP1BUFOS; //** Assign point to EP1 RAM address - *(pEPn_ptr+wEPNum-1) = wAddr; //** SET point to EPn RAM address - } -} - - -/***************************************************************************** -* Function : USB_ReturntoNormal -* Description : Enable USB IHRC and switch system into IHRC -* Enable PHY/ESD protect -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_ReturntoNormal(void) -{ - if(((SN_FLASH->LPCTRL)&0xF)!=0x05) // avoid MCU run 48MHz call this function occur HF - SystemInit(); - SystemCoreClockUpdate(); - USB_WakeupEvent(); -} - - -/***************************************************************************** -* Function : USB_ResetEvent -* Description : recevice USB bus reset to Initial parameter -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_ResetEvent(void) -{ - uint32_t wLoop; - __USB_CLRINSTS(0xFFFFFFFF); //** Clear all USB Event status - __USB_SETADDRESS(0); //** Set USB address = 0 - USB_EPnStall(USB_EP0); //** Set EP0 enable & INOUTSTALL - - for (wLoop=USB_EP1; wLoop<=USB_EP4; wLoop++) - USB_EPnDisable(wLoop); //** Set EP1~EP4 disable & NAK -} - - -/***************************************************************************** -* Function : USB_WakeupEvent -* Description : Enable USB CLK and PHY -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_WakeupEvent(void) -{ - __USB_PHY_ENABLE; //** enable ESD_EN & PHY_EN - __USB_CLRINSTS(mskBUS_WAKEUP); //** Clear BUS_WAKEUP -} - -/***************************************************************************** -* Function : USB_SuspendEvent -* Description : puts MCU in sleep mode -* Input : None -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -void USB_SuspendEvent(void) -{ - __USB_PHY_DISABLE; - SN_USB->INTEN = 0; - //** switch ILRC - SN_SYS0->CLKCFG = 0x01; - //** check ILRC status - while((SN_SYS0->CLKCFG & 0x10) != 0x10); - //** switch SYSCLK / 4 DO NOT set SYSCLK / 1 or SYSCLK / 2!!!! - SN_SYS0->AHBCP = 2; - //** disable IHRC - SN_SYS0->ANBCTRL = 0; - SN_USB->INTEN = (mskBUS_IE|mskUSB_IE|mskEPnACK_EN|mskBUSWK_IE); - SN_USB->INTEN |= mskEP1_NAK_EN; - SN_USB->INTEN |= mskEP2_NAK_EN; - SN_USB->INTEN |= mskEP3_NAK_EN; - SN_USB->INTEN |= mskEP4_NAK_EN; - SN_USB->INTEN |= mskUSB_SOF_IE; - SN_PMU->CTRL = 0x04; -} \ No newline at end of file diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.h b/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.h index f4ea3ff951..36a2f2e99b 100644 --- a/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.h +++ b/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.h @@ -4,34 +4,15 @@ #ifndef __USBHW_H__ #define __USBHW_H__ -/* USB Remote Wakeup I/O Define */ -/* USB Remote Wakeup I/O Port Define, Default P1.5 */ -#define REMOTE_WAKEUP_IO_P0 DISABLE -#define REMOTE_WAKEUP_IO_P1 ENABLE -#define REMOTE_WAKEUP_IO_P2 DISABLE -#define REMOTE_WAKEUP_IO_P3 DISABLE - -/* USB Remote Wakeup I/O Bit Define */ -#define REMOTE_WAKEUP_IO_P0_BIT 0x0000 -#define REMOTE_WAKEUP_IO_P1_BIT 0x0020 -#define REMOTE_WAKEUP_IO_P2_BIT 0x0000 -#define REMOTE_WAKEUP_IO_P3_BIT 0x0000 - -/* USB EPn NAK interrupt */ -#define EP1_NAK_IE DISABLE -#define EP2_NAK_IE DISABLE -#define EP3_NAK_IE DISABLE -#define EP4_NAK_IE DISABLE - -/* USB SOF interrupt */ -#define SOF_IE DISABLE - /* USB Interrupt Enable Bit Definitions */ #define mskEP1_NAK_EN (0x1<<0) #define mskEP2_NAK_EN (0x1<<1) #define mskEP3_NAK_EN (0x1<<2) #define mskEP4_NAK_EN (0x1<<3) -#define mskEPnACK_EN (0x1<<4) +#define mskEP5_NAK_EN (0x1<<4) +#define mskEP6_NAK_EN (0x1<<5) +#define mskEPnACK_EN (0x1<<6) + #define mskBUSWK_IE (0x1<<28) #define mskUSB_IE (0x1<<29) #define mskUSB_SOF_IE (0x1<<30) @@ -42,10 +23,17 @@ #define mskEP2_NAK (0x1<<1) #define mskEP3_NAK (0x1<<2) #define mskEP4_NAK (0x1<<3) +#define mskEP5_NAK (0x1<<4) +#define mskEP6_NAK (0x1<<5) + #define mskEP1_ACK (0x1<<8) #define mskEP2_ACK (0x1<<9) #define mskEP3_ACK (0x1<<10) #define mskEP4_ACK (0x1<<11) +#define mskEP5_ACK (0x1<<12) +#define mskEP6_ACK (0x1<<13) + + #define mskERR_TIMEOUT (0x1<<17) #define mskERR_SETUP (0x1<<18) #define mskEP0_OUT_STALL (0x1<<19) @@ -68,6 +56,9 @@ #define mskEP2_DIR (0x1<<1) #define mskEP3_DIR (0x1<<2) #define mskEP4_DIR (0x1<<3) +#define mskEP5_DIR (0x1<<4) +#define mskEP6_DIR (0x1<<5) + #define mskDIS_PDEN (0x1<<26) #define mskESD_EN (0x1<<27) #define mskSIE_EN (0x1<<28) @@ -108,8 +99,8 @@ /* Rx & Tx Packet Length Definitions */ #define PKT_LNGTH_MASK 0x000003FF -/* nUsb_Status Register Definitions */ +/* nUsb_Status Register Definitions */ #define mskBUSRESET (0x1<<0) #define mskBUSSUSPEND (0x1<<1) #define mskBUSRESUME (0x1<<2) @@ -130,82 +121,6 @@ #define mskINITREPEAT (0x1<<17) #define mskREMOTE_WAKEUP_ACT (0x1<<18) -//ISP KERNEL MODE -#define RETURN_KERNEL_0 0x5AA555AA -#define RETURN_KERNEL_1 0xCC3300FF -/*********Marco function***************/ - -//USB device address set -#define __USB_SETADDRESS(addr) (SN_USB->ADDR = addr) -//USB INT status register clear -#define __USB_CLRINSTS(Clrflag) (SN_USB->INSTSC = Clrflag) -//USB EP0_IN token set STALL -#define __USB_EP0INSTALL_EN (SN_USB->EP0CTL |= mskEP0_IN_STALL_EN) -//USB EP0_OUT token set STALL -#define __USB_EP0OUTSTALL_EN (SN_USB->EP0CTL |= mskEP0_OUT_STALL_EN) -//USB bus driver J state -#define __USB_JSTATE_DRIVER (SN_USB->SGCTL = (mskBUS_DRVEN|mskBUS_J_STATE)) -//USB bus driver K state -#define __USB_KSTATE_DRIVER (SN_USB->SGCTL = (mskBUS_DRVEN|mskBUS_K_STATE)) -//USB PHY set enable -#define __USB_PHY_ENABLE (SN_USB->CFG |= (mskESD_EN|mskPHY_EN)) -//USB PHY set Disable -#define __USB_PHY_DISABLE (SN_USB->CFG &= ~(mskESD_EN|mskPHY_EN)) - /***************************************/ -/* TODO: orgaize better since this is MCU dependent: - * 240b has 1+4 EPs/256 Bytes USB SRAM - * 240 has 1+6 EPs/512 Bytes USB SRAM - * 260 has 1+4 EPs/256 Bytes USB SRAM - * */ -// USB EPn Buffer Offset Register -#define EP1_BUFFER_OFFSET_VALUE 0x40 -#define EP2_BUFFER_OFFSET_VALUE 0x80 -#define EP3_BUFFER_OFFSET_VALUE 0xC0 -#define EP4_BUFFER_OFFSET_VALUE 0xE0 - -/* USB Endpoint Max Packet Size */ -#define USB_EP0_PACKET_SIZE 64 // only 8, 64 -#define USB_EP1_PACKET_SIZE 0x40 -#define USB_EP2_PACKET_SIZE 0x40 -#define USB_EP3_PACKET_SIZE 0x20 -#define USB_EP4_PACKET_SIZE 0x20 - -/* USB Endpoint Direction */ -#define USB_DIRECTION_OUT 0 -#define USB_DIRECTION_IN 1 - -/* USB Endpoint Address */ -#define USB_EP0 0x0 -#define USB_EP1 0x1 -#define USB_EP2 0x2 -#define USB_EP3 0x3 -#define USB_EP4 0x4 - - -extern const uint32_t wUSB_EPnOffset[]; -extern const uint32_t wUSB_EPnMaxPacketSize[]; - -/* USB Hardware Functions */ -extern void USB_Init(void); -extern void USB_ClrEPnToggle(uint32_t wEPNum); -extern void USB_EPnDisable(uint32_t wEPNum); -extern void USB_EPnNak(uint32_t wEPNum); -extern void USB_EPnAck(uint32_t wEPNum, uint8_t bBytecnt); -extern void USB_EPnStall(uint32_t wEPNum); -extern _Bool USB_EPnEnabled(uint32_t wEPNum); -extern _Bool USB_EPnStalled(uint32_t wEPNum); - -extern void USB_RemoteWakeUp(void); -extern void USB_DelayJstate(void); -extern void USB_DelayKstate(void); -extern void USB_EPnBufferOffset(uint32_t wEPNum, uint32_t wAddr); - -/* USB IRQ Functions*/ -extern void USB_ReturntoNormal(void); -extern void USB_ResetEvent(void); -extern void USB_WakeupEvent(void); -extern void USB_SuspendEvent(void); - #endif /* __USBHW_H__ */