diff options
| author | hathach <[email protected]> | 2020-04-17 13:38:22 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2020-04-17 13:38:22 +0700 |
| commit | 05476d9ad72321aa6e57ff5acbc4b25e1366fead (patch) | |
| tree | 10a12e71a679243ad5775ed7e0088242b8e763c8 /src/portable | |
| parent | f4df82939955d86f6c2e826e1bc9f4b5bb713df8 (diff) | |
| parent | 85f0894fff89baaaa91a6dc3554a3149fc2fc062 (diff) | |
Merge branch 'master' into remove-dcd-set-config
Diffstat (limited to 'src/portable')
| -rw-r--r-- | src/portable/espressif/esp32s2/dcd_esp32s2.c | 21 | ||||
| -rw-r--r-- | src/portable/microchip/samd/dcd_samd.c | 2 | ||||
| -rw-r--r-- | src/portable/microchip/samg/dcd_samg.c | 22 | ||||
| -rw-r--r-- | src/portable/nordic/nrf5x/dcd_nrf5x.c | 2 | ||||
| -rw-r--r-- | src/portable/nuvoton/nuc120/dcd_nuc120.c | 2 | ||||
| -rw-r--r-- | src/portable/nuvoton/nuc121/dcd_nuc121.c | 2 | ||||
| -rw-r--r-- | src/portable/nuvoton/nuc505/dcd_nuc505.c | 13 | ||||
| -rw-r--r-- | src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 18 | ||||
| -rw-r--r-- | src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 16 | ||||
| -rw-r--r-- | src/portable/nxp/transdimension/dcd_transdimension.c | 17 | ||||
| -rw-r--r-- | src/portable/sony/cxd56/dcd_cxd56.c | 12 | ||||
| -rw-r--r-- | src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 164 | ||||
| -rw-r--r-- | src/portable/st/synopsys/dcd_synopsys.c | 23 | ||||
| -rw-r--r-- | src/portable/template/dcd_template.c | 12 | ||||
| -rw-r--r-- | src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 27 | ||||
| -rw-r--r-- | src/portable/valentyusb/eptri/dcd_eptri.c | 15 |
16 files changed, 292 insertions, 76 deletions
diff --git a/src/portable/espressif/esp32s2/dcd_esp32s2.c b/src/portable/espressif/esp32s2/dcd_esp32s2.c index 126f3ea20..986df3b3b 100644 --- a/src/portable/espressif/esp32s2/dcd_esp32s2.c +++ b/src/portable/espressif/esp32s2/dcd_esp32s2.c @@ -190,9 +190,6 @@ void dcd_init(uint8_t rhport) USB_ENUMDONEMSK_M | USB_RESETDETMSK_M | USB_DISCONNINTMSK_M; - - ESP_LOGV(TAG, "DCD init - Soft CONNECT"); - USB0.dctl &= ~USB_SFTDISCON_M; // Connect } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) @@ -216,18 +213,20 @@ void dcd_remote_wakeup(uint8_t rhport) (void)rhport; } -// disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ - USB0.dctl |= USB_SFTDISCON_M; -} - // connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { + (void) rhport; USB0.dctl &= ~USB_SFTDISCON_M; } +// disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB0.dctl |= USB_SFTDISCON_M; +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ @@ -639,7 +638,7 @@ static void handle_epin_ints(void) } -static void dcd_int_handler(void* arg) +static void _dcd_int_handler(void* arg) { (void) arg; @@ -727,7 +726,7 @@ static void dcd_int_handler(void* arg) void dcd_int_enable (uint8_t rhport) { (void) rhport; - esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) dcd_int_handler, NULL, &usb_ih); + esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) _dcd_int_handler, NULL, &usb_ih); } void dcd_int_disable (uint8_t rhport) diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 2c01f8017..bd61df86a 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -331,7 +331,7 @@ void maybe_transfer_complete(void) { } -void dcd_irq_handler (uint8_t rhport) +void dcd_int_handler (uint8_t rhport) { (void) rhport; diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index 93d9029d6..7703ee0dc 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -138,9 +138,6 @@ void dcd_init (uint8_t rhport) (void) rhport; tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); - - // Enable pull-up, disable transceiver - UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk; } // Enable device interrupt @@ -186,6 +183,23 @@ void dcd_remote_wakeup (uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + + // Enable pull-up, disable transceiver + UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + + // disable both pullup and transceiver + UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk; +} + + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ @@ -333,7 +347,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { uint32_t const intr_mask = UDP->UDP_IMR; uint32_t const intr_status = UDP->UDP_ISR & intr_mask; diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 389266217..95240f9f0 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -373,7 +373,7 @@ void bus_reset(void) _dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE; } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void) rhport; diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c index 050aea255..9195b8dbe 100644 --- a/src/portable/nuvoton/nuc120/dcd_nuc120.c +++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -306,7 +306,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) ep->CFG |= USBD_CFG_CSTALL_Msk; } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void) rhport; diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index df72cbb2d..edd1e14a7 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -312,7 +312,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) ep->CFG |= USBD_CFG_CSTALL_Msk; } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void) rhport; diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index 3baed87c5..aceb6df09 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -112,8 +112,6 @@ static struct uint16_t total_bytes; } ctrl_in_xfer; -static volatile bool configuration_changed; - static volatile struct xfer_ctl_t *current_dma_xfer; @@ -219,7 +217,6 @@ static void bus_reset(void) /* Reset USB device address */ USBD->FADDR = 0; - configuration_changed = false; current_dma_xfer = NULL; } @@ -305,7 +302,6 @@ void dcd_set_config(uint8_t rhport, uint8_t config_num) { (void) rhport; (void) config_num; - configuration_changed = true; } void dcd_remote_wakeup(uint8_t rhport) @@ -435,7 +431,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) } } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void) rhport; @@ -579,15 +575,14 @@ void dcd_irq_handler(uint8_t rhport) else if (cep_state & USBD_CEPINTSTS_STSDONEIF_Msk) { /* given ACK from host has happened, we can now set the address (if not already done) */ - if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) USBD->FADDR = assigned_address; - - if (configuration_changed) + if((USBD->FADDR != assigned_address) && (USBD->FADDR == 0)) { + USBD->FADDR = assigned_address; + for (enum ep_enum ep_index = PERIPH_EPA; ep_index < PERIPH_MAX_EP; ep_index++) { if (USBD->EP[ep_index].EPCFG & USBD_EPCFG_EPEN_Msk) USBD->EP[ep_index].EPRSPCTL = USBD_EPRSPCTL_TOGGLE_Msk; } - configuration_changed = false; } USBD->CEPINTEN = USBD_CEPINTEN_SETUPPKIEN_Msk; diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 1d755ce63..21a678c66 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -181,9 +181,7 @@ void dcd_init(uint8_t rhport) LPC_USB->UDCAH = (uint32_t) _dcd.udca; LPC_USB->DMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK); - sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 1); // connect - - // USB IRQ priority should be set by application previously + // Clear pending IRQ NVIC_ClearPendingIRQ(USB_IRQn); } @@ -221,6 +219,18 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, SIE_DEV_STATUS_CONNECT_STATUS_MASK); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 0); +} + //--------------------------------------------------------------------+ // CONTROL HELPER //--------------------------------------------------------------------+ @@ -498,7 +508,7 @@ static void dd_complete_isr(uint8_t rhport, uint8_t ep_id) } // main USB IRQ handler -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { uint32_t const dev_int_status = LPC_USB->DevIntSt & LPC_USB->DevIntEn; LPC_USB->DevIntClr = dev_int_status;// Acknowledge handled interrupt diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 9af8e6019..c1f80185b 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -95,7 +95,7 @@ enum { CMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, CMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), CMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), - CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), ///< reflect the softconnect only, does not reflect the actual attached state + CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), ///< reflect the soft-connect only, does not reflect the actual attached state CMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), CMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), CMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), @@ -209,6 +209,18 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + DCD_REGS->DEVCMDSTAT |= CMDSTAT_DEVICE_CONNECT_MASK; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + DCD_REGS->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK; +} + //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ @@ -333,7 +345,7 @@ static void process_xfer_isr(uint32_t int_status) } } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void) rhport; // TODO support multiple USB on supported mcu such as LPC55s69 diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 2872f1435..539629c3d 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -322,7 +322,7 @@ void dcd_init(uint8_t rhport) { tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - dcd_registers_t* const dcd_reg = _dcd_controller[rhport].regs; + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; // Reset controller dcd_reg->USBCMD |= USBCMD_RESET; @@ -342,7 +342,6 @@ void dcd_init(uint8_t rhport) dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND /*| INTR_SOF*/; dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 - dcd_reg->USBCMD |= TU_BIT(0); // connect } void dcd_int_enable(uint8_t rhport) @@ -376,6 +375,18 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->USBCMD |= USBCMD_RUN_STOP; +} + +void dcd_disconnect(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; + dcd_reg->USBCMD &= ~USBCMD_RUN_STOP; +} + //--------------------------------------------------------------------+ // HELPER //--------------------------------------------------------------------+ @@ -492,7 +503,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { dcd_registers_t* const dcd_reg = _dcd_controller[rhport].regs; diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 320b7237e..7fd630384 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -201,6 +201,18 @@ void dcd_remote_wakeup(uint8_t rhport) DEV_WAKEUP(usbdev); } +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + DEV_CONNECT(usbdev); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + DEV_DISCONNECT(usbdev); +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2939e5ae2..dbc1e6952 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -63,19 +63,16 @@ * Current driver limitations (i.e., a list of features for you to add): * - STALL handled, but not tested. * - Does it work? No clue. - * - All EP BTABLE buffers are created as max 64 bytes. - * - Smaller can be requested, but it has to be an even number. + * - All EP BTABLE buffers are created based on max packet size of first EP opened with that address. * - No isochronous endpoints * - Endpoint index is the ID of the endpoint * - This means that priority is given to endpoints with lower ID numbers * - Code is mixing up EP IX with EP ID. Everywhere. - * - No way to close endpoints; Can a device be reconfigured without a reset? * - Packet buffer memory is copied in the interrupt. * - This is better for performance, but means interrupts are disabled for longer * - DMA may be the best choice, but it could also be pushed to the USBD task. * - No double-buffering * - No DMA - * - No provision to control the D+ pull-up using GPIO on devices without an internal pull-up. * - Minimal error handling * - Perhaps error interrupts should be reported to the stack, or cause a device reset? * - Assumes a single USB peripheral; I think that no hardware has multiple so this is fine. @@ -131,15 +128,16 @@ * Configuration *****************************************************/ -// HW supports max of 8 endpoints, but this can be reduced to save RAM +// HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM +// (8u here would mean 8 IN and 8 OUT) #ifndef MAX_EP_COUNT -# define MAX_EP_COUNT 8u +# define MAX_EP_COUNT 8U #endif // If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it // Both of these MUST be a multiple of 2, and are in byte units. #ifndef DCD_STM32_BTABLE_BASE -# define DCD_STM32_BTABLE_BASE 0u +# define DCD_STM32_BTABLE_BASE 0U #endif #ifndef DCD_STM32_BTABLE_LENGTH @@ -163,7 +161,9 @@ typedef struct uint8_t * buffer; uint16_t total_len; uint16_t queued_len; - uint16_t max_packet_size; + uint16_t pma_ptr; + uint8_t max_packet_size; + uint8_t pma_alloc_size; } xfer_ctl_t; static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; @@ -177,15 +177,19 @@ static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; static uint8_t remoteWakeCountdown; // When wake is requested -// EP Buffers assigned from end of memory location, to minimize their chance of crashing // into the stack. -static uint16_t ep_buf_ptr; static void dcd_handle_bus_reset(void); -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes); -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes); static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix); static void dcd_ep_ctr_handler(void); +// PMA allocation/access +static uint8_t open_ep_count; +static uint16_t ep_buf_ptr; ///< Points to first free memory location +static void dcd_pma_alloc_reset(void); +static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length); +static void dcd_pma_free(uint8_t ep_addr); +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes); +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wNBytes); // Using a function due to better type checks // This seems better than having to do type casts everywhere else @@ -219,7 +223,7 @@ void dcd_init (uint8_t rhport) asm("NOP"); } USB->CNTR = 0; // Enable USB - + USB->BTABLE = DCD_STM32_BTABLE_BASE; reg16_clear_bits(&USB->ISTR, USB_ISTR_ALL_EVENTS); // Clear pending interrupts @@ -231,12 +235,6 @@ void dcd_init (uint8_t rhport) pcd_set_endpoint(USB,i,0u); } - // Initialize the BTABLE for EP0 at this point (though setting up the EP0R is unneeded) - // This is actually not necessary, but helps debugging to start with a blank RAM area - for(uint32_t i=0;i<(DCD_STM32_BTABLE_LENGTH>>1); i++) - { - pma[PMA_STRIDE*(DCD_STM32_BTABLE_BASE + i)] = 0u; - } USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; dcd_handle_bus_reset(); @@ -368,7 +366,7 @@ static void dcd_handle_bus_reset(void) pcd_set_endpoint(USB,i,0u); } - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) + dcd_pma_alloc_reset(); dcd_edpt_open (0, &ep0OUT_desc); dcd_edpt_open (0, &ep0IN_desc); @@ -501,7 +499,7 @@ static void dcd_ep_ctr_handler(void) } } -void dcd_irq_handler(uint8_t rhport) { +void dcd_int_handler(uint8_t rhport) { (void) rhport; @@ -592,6 +590,85 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re } } +static void dcd_pma_alloc_reset(void) +{ + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) + //TU_LOG2("dcd_pma_alloc_reset()\r\n"); + for(uint32_t i=0; i<MAX_EP_COUNT; i++) + { + xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_ptr = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_ptr = 0U; + } +} + +/*** + * Allocate a section of PMA + * + * If the EP number has already been allocated, and the new allocation + * is larger than the old allocation, then this will fail with a TU_ASSERT. + * (This is done to simplify the code. More complicated algorithms could be used) + * + * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually. + */ +static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t* epXferCtl = xfer_ctl_ptr(epnum,dir); + + if(epXferCtl->pma_alloc_size != 0U) + { + //TU_LOG2("dcd_pma_alloc(%x,%x)=%x (cached)\r\n",ep_addr,length,epXferCtl->pma_ptr); + // Previously allocated + TU_ASSERT(length <= epXferCtl->pma_alloc_size, 0xFFFF); // Verify no larger than previous alloc + return epXferCtl->pma_ptr; + } + + uint16_t addr = ep_buf_ptr; + ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + + // Verify no overflow + TU_ASSERT(ep_buf_ptr <= PMA_LENGTH, 0xFFFF); + + epXferCtl->pma_ptr = addr; + epXferCtl->pma_alloc_size = length; + //TU_LOG2("dcd_pma_alloc(%x,%x)=%x\r\n",ep_addr,length,addr); + + return addr; +} + +/*** + * Free a block of PMA space + */ +static void dcd_pma_free(uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // Presently, this should never be called for EP0 IN/OUT + TU_ASSERT(open_ep_count > 2, /**/); + TU_ASSERT(xfer_ctl_ptr(epnum,dir)->max_packet_size != 0, /**/); + open_ep_count--; + + // If count is 2, only EP0 should be open, so allocations can be mostly reset. + + if(open_ep_count == 2) + { + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT + 2*CFG_TUD_ENDPOINT0_SIZE; // 8 bytes per endpoint (two TX and two RX words, each), and EP0 + + // Skip EP0 + for(uint32_t i=1; i<MAX_EP_COUNT; i++) + { + xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_alloc_size = 0U; + xfer_ctl_ptr(i,TUSB_DIR_OUT)->pma_ptr = 0U; + xfer_ctl_ptr(i,TUSB_DIR_IN)->pma_ptr = 0U; + } + } +} + // The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, // so I'm using the #define from HAL here, instead. @@ -601,28 +678,30 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); const uint16_t epMaxPktSize = p_endpoint_desc->wMaxPacketSize.size; + uint16_t pma_addr; + uint32_t wType; + // Isochronous not supported (yet), and some other driver assumptions. - TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); TU_ASSERT(epnum < MAX_EP_COUNT); // Set type switch(p_endpoint_desc->bmAttributes.xfer) { case TUSB_XFER_CONTROL: - pcd_set_eptype(USB, epnum, USB_EP_CONTROL); + wType = USB_EP_CONTROL; break; #if (0) case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported - pcd_set_eptype(USB, epnum, USB_EP_ISOCHRONOUS); break; + wType = USB_EP_ISOCHRONOUS; break; #endif case TUSB_XFER_BULK: - pcd_set_eptype(USB, epnum, USB_EP_BULK); + wType = USB_EP_CONTROL; break; case TUSB_XFER_INTERRUPT: - pcd_set_eptype(USB, epnum, USB_EP_INTERRUPT); + wType = USB_EP_INTERRUPT; break; default: @@ -630,32 +709,59 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc return false; } + pcd_set_eptype(USB, epnum, wType); pcd_set_ep_address(USB, epnum, epnum); // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) // or being double-buffered (bulk endpoints) pcd_clear_ep_kind(USB,0); + pma_addr = dcd_pma_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->wMaxPacketSize.size); + if(dir == TUSB_DIR_IN) { - *pcd_ep_tx_address_ptr(USB, epnum) = ep_buf_ptr; + *pcd_ep_tx_address_ptr(USB, epnum) = pma_addr; pcd_set_ep_tx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); pcd_clear_tx_dtog(USB, epnum); pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_NAK); } else { - *pcd_ep_rx_address_ptr(USB, epnum) = ep_buf_ptr; + *pcd_ep_rx_address_ptr(USB, epnum) = pma_addr; pcd_set_ep_rx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); pcd_clear_rx_dtog(USB, epnum); pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); } xfer_ctl_ptr(epnum, dir)->max_packet_size = epMaxPktSize; - ep_buf_ptr = (uint16_t)(ep_buf_ptr + p_endpoint_desc->wMaxPacketSize.size); // increment buffer pointer return true; } +/** + * Close an endpoint. + * + * This function may be called with interrupts enabled or disabled. + * + * This also clears transfers in progress, should there be any. + */ +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + uint32_t const epnum = tu_edpt_number(ep_addr); + uint32_t const dir = tu_edpt_dir(ep_addr); + + if(dir == TUSB_DIR_IN) + { + pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_DIS); + } + else + { + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_DIS); + } + + dcd_pma_free(ep_addr); +} + // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index dc752b37a..0c9c2650d 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -209,10 +209,6 @@ void dcd_init (uint8_t rhport) // Enable USB transceiver. USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_PWRDWN; - - // Soft Connect -> Enable pullup on D+/D-. - // This step does not appear to be specified in the programmer's model. - dev->DCTL &= ~USB_OTG_DCTL_SDIS; } void dcd_int_enable (uint8_t rhport) @@ -250,6 +246,23 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; + + dev->DCTL &= ~USB_OTG_DCTL_SDIS; +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; + + dev->DCTL |= USB_OTG_DCTL_SDIS; +} + + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ @@ -656,7 +669,7 @@ static void handle_epin_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointType } } -void dcd_irq_handler(uint8_t rhport) { +void dcd_int_handler(uint8_t rhport) { (void) rhport; diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index d29c98e55..ba1383f31 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -91,6 +91,18 @@ void dcd_remote_wakeup (uint8_t rhport) (void) rhport; } +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void) rhport; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index edccec33f..da75a7f3f 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -134,9 +134,6 @@ void dcd_init (uint8_t rhport) // Enable reset and wait for it before continuing. USBIE |= RSTRIE; - // Enable pullup. - USBCNF |= PUR_EN; - USBKEYPID = 0; } @@ -207,6 +204,28 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + dcd_int_disable(rhport); + + USBKEYPID = USBKEY; + USBCNF |= PUR_EN; // Enable pullup. + USBKEYPID = 0; + + dcd_int_enable(rhport); +} + +void dcd_disconnect(uint8_t rhport) +{ + dcd_int_disable(rhport); + + USBKEYPID = USBKEY; + USBCNF &= ~PUR_EN; // Disable pullup. + USBKEYPID = 0; + + dcd_int_enable(rhport); +} + /*------------------------------------------------------------------*/ /* DCD Endpoint port *------------------------------------------------------------------*/ @@ -539,7 +558,7 @@ static void handle_setup_packet(void) dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void) rhport; diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 1054e71d6..8dde874fc 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -397,6 +397,19 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_connect(uint8_t rhport) +{ + (void) rhport; + usb_pullup_out_write(1); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void) rhport; + usb_pullup_out_write(0); +} + + //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ @@ -613,7 +626,7 @@ static void handle_setup(void) usb_setup_ev_pending_write(1); } -void dcd_irq_handler(uint8_t rhport) +void dcd_int_handler(uint8_t rhport) { (void)rhport; uint8_t next_ev; |
