From 043697ab9589955f831f4f716bb37b5470ba11f6 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 21 Nov 2019 16:08:08 +0700 Subject: rename lpc 17/18 irq to dcd_isr/hcd_isr --- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 2 +- src/portable/nxp/lpc17_40/hal_lpc17_40.c | 8 ++++---- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 10 +++++++--- src/portable/nxp/lpc18_43/hal_lpc18_43.c | 22 +++++++++++++++------- 4 files changed, 27 insertions(+), 15 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 8c439616a..89a4ba3f8 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -495,7 +495,7 @@ static void dd_complete_isr(uint8_t rhport, uint8_t ep_id) } // main USB IRQ handler -void hal_dcd_isr(uint8_t rhport) +void dcd_isr(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/lpc17_40/hal_lpc17_40.c b/src/portable/nxp/lpc17_40/hal_lpc17_40.c index e83e3e9a4..bc2477a90 100644 --- a/src/portable/nxp/lpc17_40/hal_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/hal_lpc17_40.c @@ -30,17 +30,17 @@ #include "chip.h" -extern void hal_hcd_isr(uint8_t hostid); -extern void hal_dcd_isr(uint8_t rhport); +extern void hcd_isr(uint8_t hostid); +extern void dcd_isr(uint8_t rhport); void USB_IRQHandler(void) { #if TUSB_OPT_HOST_ENABLED - hal_hcd_isr(0); + hcd_isr(0); #endif #if TUSB_OPT_DEVICE_ENABLED - hal_dcd_isr(0); + dcd_isr(0); #endif } diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 3619a7c2b..30cab820f 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX) +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_RT10XX) //--------------------------------------------------------------------+ // INCLUDE @@ -35,7 +35,11 @@ #include "device/dcd.h" #include "dcd_lpc18_43.h" -#include "chip.h" +#if CFG_TUSB_MCU == OPT_MCU_RT10XX + #include "fsl_device_registers.h" +#else + #include "chip.h" +#endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -270,7 +274,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ -void hal_dcd_isr(uint8_t rhport) +void dcd_isr(uint8_t rhport) { LPC_USBHS_T* const lpc_usb = LPC_USB[rhport]; diff --git a/src/portable/nxp/lpc18_43/hal_lpc18_43.c b/src/portable/nxp/lpc18_43/hal_lpc18_43.c index 3f4e9c23d..5710b9ffd 100644 --- a/src/portable/nxp/lpc18_43/hal_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/hal_lpc18_43.c @@ -26,35 +26,43 @@ #include "tusb.h" -#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX) +#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_RT10XX) #include "chip.h" -extern void hal_dcd_isr(uint8_t rhport); -extern void hal_hcd_isr(uint8_t hostid); +extern void dcd_isr(uint8_t rhport); +extern void hcd_isr(uint8_t hostid); #if CFG_TUSB_RHPORT0_MODE +#if CFG_TUSB_MCU == OPT_MCU_RT10XX +void USB_OTG1_IRQHandler(void) +#else void USB0_IRQHandler(void) +#endif { #if TUSB_OPT_HOST_ENABLED - hal_hcd_isr(0); + hcd_isr(0); #endif #if TUSB_OPT_DEVICE_ENABLED - hal_dcd_isr(0); + dcd_isr(0); #endif } #endif #if CFG_TUSB_RHPORT1_MODE +#if CFG_TUSB_MCU == OPT_MCU_RT10XX +void USB_OTG2_IRQHandler(void) +#else void USB1_IRQHandler(void) +#endif { #if TUSB_OPT_HOST_ENABLED - hal_hcd_isr(1); + hcd_isr(1); #endif #if TUSB_OPT_DEVICE_ENABLED - hal_dcd_isr(1); + dcd_isr(1); #endif } #endif -- cgit v1.3.1 From f5d737aa7ec6abde5738d29510c8416d5e8b17e7 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 21 Nov 2019 23:19:38 +0700 Subject: moving irq to bsp for lpc17/40 --- hw/bsp/ea4088qs/board.mk | 3 -- hw/bsp/ea4088qs/ea4088qs.c | 15 +++++++ hw/bsp/ea4357/ea4357.c | 8 ++-- hw/bsp/lpcxpresso1769/board.mk | 3 -- hw/bsp/lpcxpresso1769/lpcxpresso1769.c | 14 +++++++ hw/bsp/mbed1768/board.mk | 9 ++-- hw/bsp/mbed1768/mbed1768.c | 14 +++++++ hw/bsp/mcb1800/mcb1800.c | 9 ++-- hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c | 25 ++++++++++++ hw/bsp/ngx4330/ngx4330.c | 8 ++-- src/device/dcd.h | 3 ++ src/portable/nxp/lpc17_40/hal_lpc17_40.c | 61 ---------------------------- src/portable/nxp/lpc17_40/hcd_lpc17_40.c | 46 +++++++++++++++++++++ src/portable/nxp/lpc18_43/hal_lpc18_43.c | 70 -------------------------------- test/test/device/usbd/test_usbd.c | 2 +- 15 files changed, 134 insertions(+), 156 deletions(-) delete mode 100644 src/portable/nxp/lpc17_40/hal_lpc17_40.c create mode 100644 src/portable/nxp/lpc17_40/hcd_lpc17_40.c delete mode 100644 src/portable/nxp/lpc18_43/hal_lpc18_43.c (limited to 'src/portable') diff --git a/hw/bsp/ea4088qs/board.mk b/hw/bsp/ea4088qs/board.mk index 7869ea8d0..a88976d3a 100644 --- a/hw/bsp/ea4088qs/board.mk +++ b/hw/bsp/ea4088qs/board.mk @@ -17,9 +17,6 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx # All source paths should be relative to the top level. LD_FILE = hw/bsp/ea4088qs/lpc4088.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ diff --git a/hw/bsp/ea4088qs/ea4088qs.c b/hw/bsp/ea4088qs/ea4088qs.c index 8adb61fda..83b2d6b1e 100644 --- a/hw/bsp/ea4088qs/ea4088qs.c +++ b/hw/bsp/ea4088qs/ea4088qs.c @@ -113,6 +113,21 @@ void board_init(void) LPC_USB->StCtrl = 0x3; } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/ea4357/ea4357.c b/hw/bsp/ea4357/ea4357.c index e8252f210..f21d3259d 100644 --- a/hw/bsp/ea4357/ea4357.c +++ b/hw/bsp/ea4357/ea4357.c @@ -235,22 +235,22 @@ void board_init(void) //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if TUSB_OPT_HOST_ENABLED + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST tuh_isr(0); #endif - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE tud_isr(0); #endif } void USB1_IRQHandler(void) { - #if TUSB_OPT_HOST_ENABLED + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST tuh_isr(1); #endif - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE tud_isr(1); #endif } diff --git a/hw/bsp/lpcxpresso1769/board.mk b/hw/bsp/lpcxpresso1769/board.mk index 8d1f14c42..b87d6afc9 100644 --- a/hw/bsp/lpcxpresso1769/board.mk +++ b/hw/bsp/lpcxpresso1769/board.mk @@ -17,9 +17,6 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x # All source paths should be relative to the top level. LD_FILE = hw/bsp/lpcxpresso1769/lpc1769.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ diff --git a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c index e2d5f6cf2..76755e89f 100644 --- a/hw/bsp/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpcxpresso1769/lpcxpresso1769.c @@ -143,6 +143,20 @@ void board_init(void) #endif } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/mbed1768/board.mk b/hw/bsp/mbed1768/board.mk index 03176b543..60428bcb4 100644 --- a/hw/bsp/mbed1768/board.mk +++ b/hw/bsp/mbed1768/board.mk @@ -17,9 +17,6 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x # All source paths should be relative to the top level. LD_FILE = hw/bsp/mbed1768/lpc1768.ld -# TODO remove later -SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c - SRC_C += \ $(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \ $(MCU_DIR)/src/chip_17xx_40xx.c \ @@ -44,5 +41,7 @@ FREERTOS_PORT = ARM_CM3 JLINK_DEVICE = LPC1768 JLINK_IF = swd -# flash using jlink -flash: flash-jlink +# flash using pyocd +flash: $(BUILD)/$(BOARD)-firmware.hex + pyocd flash -t lpc1768 $< + diff --git a/hw/bsp/mbed1768/mbed1768.c b/hw/bsp/mbed1768/mbed1768.c index 9f1ed12ef..66cf44a0e 100644 --- a/hw/bsp/mbed1768/mbed1768.c +++ b/hw/bsp/mbed1768/mbed1768.c @@ -135,6 +135,20 @@ void board_init(void) #endif } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/mcb1800/mcb1800.c b/hw/bsp/mcb1800/mcb1800.c index 4e75c10dd..4fe874762 100644 --- a/hw/bsp/mcb1800/mcb1800.c +++ b/hw/bsp/mcb1800/mcb1800.c @@ -177,26 +177,25 @@ void board_init(void) //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if TUSB_OPT_HOST_ENABLED + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST tuh_isr(0); #endif - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE tud_isr(0); #endif } void USB1_IRQHandler(void) { - #if TUSB_OPT_HOST_ENABLED + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST tuh_isr(1); #endif - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE tud_isr(1); #endif } - //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c b/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c index 62117e64e..8793a759c 100644 --- a/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c +++ b/hw/bsp/mimxrt1064_evk/mimxrt1064_evk.c @@ -118,6 +118,31 @@ void board_init(void) // CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); } +//--------------------------------------------------------------------+ +// USB Interrupt Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST + tuh_isr(0); + #endif + + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE + tud_isr(0); + #endif +} + +void USB1_IRQHandler(void) +{ + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST + tuh_isr(1); + #endif + + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE + tud_isr(1); + #endif +} + //--------------------------------------------------------------------+ // Board porting API //--------------------------------------------------------------------+ diff --git a/hw/bsp/ngx4330/ngx4330.c b/hw/bsp/ngx4330/ngx4330.c index e95f6b059..fd6f0119b 100644 --- a/hw/bsp/ngx4330/ngx4330.c +++ b/hw/bsp/ngx4330/ngx4330.c @@ -224,22 +224,22 @@ void board_init(void) //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { - #if TUSB_OPT_HOST_ENABLED + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST tuh_isr(0); #endif - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE tud_isr(0); #endif } void USB1_IRQHandler(void) { - #if TUSB_OPT_HOST_ENABLED + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST tuh_isr(1); #endif - #if TUSB_OPT_DEVICE_ENABLED + #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE tud_isr(1); #endif } diff --git a/src/device/dcd.h b/src/device/dcd.h index 6e43ab3e9..dca289e78 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -88,6 +88,9 @@ typedef struct TU_ATTR_ALIGNED(4) // Initialize controller to device mode void dcd_init (uint8_t rhport); +// Interrupt Handler +void dcd_isr (uint8_t rhport); + // Enable device interrupt void dcd_int_enable (uint8_t rhport); diff --git a/src/portable/nxp/lpc17_40/hal_lpc17_40.c b/src/portable/nxp/lpc17_40/hal_lpc17_40.c deleted file mode 100644 index bc2477a90..000000000 --- a/src/portable/nxp/lpc17_40/hal_lpc17_40.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "common/tusb_common.h" - -#if (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) - -#include "chip.h" - -extern void hcd_isr(uint8_t hostid); -extern void dcd_isr(uint8_t rhport); - -void USB_IRQHandler(void) -{ - #if TUSB_OPT_HOST_ENABLED - hcd_isr(0); - #endif - - #if TUSB_OPT_DEVICE_ENABLED - dcd_isr(0); - #endif -} - -//FIXME move later -void hcd_int_enable(uint8_t rhport) -{ - (void) rhport; - NVIC_EnableIRQ(USB_IRQn); -} - -void hcd_int_disable(uint8_t rhport) -{ - (void) rhport; - NVIC_DisableIRQ(USB_IRQn); -} - - -#endif diff --git a/src/portable/nxp/lpc17_40/hcd_lpc17_40.c b/src/portable/nxp/lpc17_40/hcd_lpc17_40.c new file mode 100644 index 000000000..537b3daba --- /dev/null +++ b/src/portable/nxp/lpc17_40/hcd_lpc17_40.c @@ -0,0 +1,46 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX) + +#include "chip.h" + +void hcd_int_enable(uint8_t rhport) +{ + (void) rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void) rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +#endif + diff --git a/src/portable/nxp/lpc18_43/hal_lpc18_43.c b/src/portable/nxp/lpc18_43/hal_lpc18_43.c deleted file mode 100644 index 5710b9ffd..000000000 --- a/src/portable/nxp/lpc18_43/hal_lpc18_43.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb.h" - -#if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_RT10XX) - -#include "chip.h" - -extern void dcd_isr(uint8_t rhport); -extern void hcd_isr(uint8_t hostid); - -#if CFG_TUSB_RHPORT0_MODE -#if CFG_TUSB_MCU == OPT_MCU_RT10XX -void USB_OTG1_IRQHandler(void) -#else -void USB0_IRQHandler(void) -#endif -{ - #if TUSB_OPT_HOST_ENABLED - hcd_isr(0); - #endif - - #if TUSB_OPT_DEVICE_ENABLED - dcd_isr(0); - #endif -} -#endif - -#if CFG_TUSB_RHPORT1_MODE -#if CFG_TUSB_MCU == OPT_MCU_RT10XX -void USB_OTG2_IRQHandler(void) -#else -void USB1_IRQHandler(void) -#endif -{ - #if TUSB_OPT_HOST_ENABLED - hcd_isr(1); - #endif - - #if TUSB_OPT_DEVICE_ENABLED - dcd_isr(1); - #endif -} -#endif - -#endif diff --git a/test/test/device/usbd/test_usbd.c b/test/test/device/usbd/test_usbd.c index fcd739b40..c59d94c2c 100644 --- a/test/test/device/usbd/test_usbd.c +++ b/test/test/device/usbd/test_usbd.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 hathach for Adafruit Industries + * Copyright (c) 2019, Ha Thach (tinyusb.org) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.3.1 From 1f52273d99a340128d535d8c3d146b8522cad0ec Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 00:38:22 +0700 Subject: move dcd_lpc18_43.h into .c file --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 98 ++++++++++++++++++++- src/portable/nxp/lpc18_43/dcd_lpc18_43.h | 144 ------------------------------- 2 files changed, 97 insertions(+), 145 deletions(-) delete mode 100644 src/portable/nxp/lpc18_43/dcd_lpc18_43.h (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 30cab820f..75f9c8d5d 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -33,7 +33,6 @@ //--------------------------------------------------------------------+ #include "common/tusb_common.h" #include "device/dcd.h" -#include "dcd_lpc18_43.h" #if CFG_TUSB_MCU == OPT_MCU_RT10XX #include "fsl_device_registers.h" @@ -45,6 +44,103 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +/*---------- ENDPTCTRL ----------*/ +enum { + ENDPTCTRL_MASK_STALL = TU_BIT(0), + ENDPTCTRL_MASK_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only + ENDPTCTRL_MASK_TOGGLE_RESET = TU_BIT(6), + ENDPTCTRL_MASK_ENABLE = TU_BIT(7) +}; + +/*---------- USBCMD ----------*/ +enum { + USBCMD_MASK_RUN_STOP = TU_BIT(0), + USBCMD_MASK_RESET = TU_BIT(1), + USBCMD_MASK_SETUP_TRIPWIRE = TU_BIT(13), + USBCMD_MASK_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD +}; +// Interrupt Threshold bit 23:16 + +/*---------- USBSTS, USBINTR ----------*/ +enum { + INT_MASK_USB = TU_BIT(0), + INT_MASK_ERROR = TU_BIT(1), + INT_MASK_PORT_CHANGE = TU_BIT(2), + INT_MASK_RESET = TU_BIT(6), + INT_MASK_SOF = TU_BIT(7), + INT_MASK_SUSPEND = TU_BIT(8), + INT_MASK_NAK = TU_BIT(16) +}; + +//------------- PORTSC -------------// +enum { + PORTSC_CURRENT_CONNECT_STATUS_MASK = TU_BIT(0), + PORTSC_FORCE_PORT_RESUME_MASK = TU_BIT(6), + PORTSC_SUSPEND_MASK = TU_BIT(7) +}; + +typedef struct +{ + // Word 0: Next QTD Pointer + uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed + + // Word 1: qTQ Token + uint32_t : 3 ; + volatile uint32_t xact_err : 1 ; + uint32_t : 1 ; + volatile uint32_t buffer_err : 1 ; + volatile uint32_t halted : 1 ; + volatile uint32_t active : 1 ; + uint32_t : 2 ; + uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. + uint32_t : 3 ; + uint32_t int_on_complete : 1 ; + volatile uint32_t total_bytes : 15 ; + uint32_t : 0 ; + + // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page + uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous + + //------------- DCD Area -------------// + uint16_t expected_bytes; + uint8_t reserved[2]; +} dcd_qtd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); + +typedef struct +{ + // Word 0: Capabilities and Characteristics + uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. + uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. + uint32_t max_package_size : 11 ; ///< This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) + uint32_t : 2 ; + uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. + uint32_t iso_mult : 2 ; ///< + uint32_t : 0 ; + + // Word 1: Current qTD Pointer + volatile uint32_t qtd_addr; + + // Word 2-9: Transfer Overlay + volatile dcd_qtd_t qtd_overlay; + + // Word 10-11: Setup request (control OUT only) + volatile tusb_control_request_t setup_request; + + //--------------------------------------------------------------------+ + /// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes + /// thus there are 16 bytes padding free that we can make use of. + //--------------------------------------------------------------------+ + uint8_t reserved[16]; +} dcd_qhd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); + +//--------------------------------------------------------------------+ +// Variables +//--------------------------------------------------------------------+ + #define QHD_MAX 12 #define QTD_NEXT_INVALID 0x01 diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.h b/src/portable/nxp/lpc18_43/dcd_lpc18_43.h deleted file mode 100644 index 00f4854b1..000000000 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/** \ingroup group_dcd - * \defgroup group_dcd_lpc143xx LPC43xx - * @{ */ - -#ifndef _TUSB_DCD_LPC43XX_H_ -#define _TUSB_DCD_LPC43XX_H_ - -#include "common/tusb_common.h" - -#ifdef __cplusplus - extern "C" { -#endif - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ - -/*---------- ENDPTCTRL ----------*/ -enum { - ENDPTCTRL_MASK_STALL = TU_BIT(0), - ENDPTCTRL_MASK_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only - ENDPTCTRL_MASK_TOGGLE_RESET = TU_BIT(6), - ENDPTCTRL_MASK_ENABLE = TU_BIT(7) -}; - -/*---------- USBCMD ----------*/ -enum { - USBCMD_MASK_RUN_STOP = TU_BIT(0), - USBCMD_MASK_RESET = TU_BIT(1), - USBCMD_MASK_SETUP_TRIPWIRE = TU_BIT(13), - USBCMD_MASK_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD -}; -// Interrupt Threshold bit 23:16 - -/*---------- USBSTS, USBINTR ----------*/ -enum { - INT_MASK_USB = TU_BIT(0), - INT_MASK_ERROR = TU_BIT(1), - INT_MASK_PORT_CHANGE = TU_BIT(2), - INT_MASK_RESET = TU_BIT(6), - INT_MASK_SOF = TU_BIT(7), - INT_MASK_SUSPEND = TU_BIT(8), - INT_MASK_NAK = TU_BIT(16) -}; - -//------------- PORTSC -------------// -enum { - PORTSC_CURRENT_CONNECT_STATUS_MASK = TU_BIT(0), - PORTSC_FORCE_PORT_RESUME_MASK = TU_BIT(6), - PORTSC_SUSPEND_MASK = TU_BIT(7) -}; - -typedef struct -{ - // Word 0: Next QTD Pointer - uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed - - // Word 1: qTQ Token - uint32_t : 3 ; - volatile uint32_t xact_err : 1 ; - uint32_t : 1 ; - volatile uint32_t buffer_err : 1 ; - volatile uint32_t halted : 1 ; - volatile uint32_t active : 1 ; - uint32_t : 2 ; - uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. - uint32_t : 3 ; - uint32_t int_on_complete : 1 ; - volatile uint32_t total_bytes : 15 ; - uint32_t : 0 ; - - // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page - uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous - - //------------- DCD Area -------------// - uint16_t expected_bytes; - uint8_t reserved[2]; -} dcd_qtd_t; - -TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); - -typedef struct -{ - // Word 0: Capabilities and Characteristics - uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. - uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. - uint32_t max_package_size : 11 ; ///< This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) - uint32_t : 2 ; - uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. - uint32_t iso_mult : 2 ; ///< - uint32_t : 0 ; - - // Word 1: Current qTD Pointer - volatile uint32_t qtd_addr; - - // Word 2-9: Transfer Overlay - volatile dcd_qtd_t qtd_overlay; - - // Word 10-11: Setup request (control OUT only) - volatile tusb_control_request_t setup_request; - - //--------------------------------------------------------------------+ - /// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes - /// thus there are 16 bytes padding free that we can make use of. - //--------------------------------------------------------------------+ - uint8_t reserved[16]; -} dcd_qhd_t; - -TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); - - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_DCD_LPC43XX_H_ */ - -/** @} */ -- cgit v1.3.1 From 623b16af2eb9ead9d4267464eb8f178a037ad5fc Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 00:58:18 +0700 Subject: clean up dcd lpc18_43 drop supporting both device mode on both ports. --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 56 +++++++++----------------------- 1 file changed, 16 insertions(+), 40 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 75f9c8d5d..7613f6711 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -26,7 +26,9 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_RT10XX) +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ + CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ + CFG_TUSB_MCU == OPT_MCU_RT10XX) //--------------------------------------------------------------------+ // INCLUDE @@ -150,31 +152,9 @@ typedef struct { dcd_qtd_t qtd[QHD_MAX] TU_ATTR_ALIGNED(32); }dcd_data_t; -#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) -CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t dcd_data0; -#endif - -#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) -CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t dcd_data1; -#endif - +static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; -static dcd_data_t* const dcd_data_ptr[2] = -{ -#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) - &dcd_data0, -#else - NULL, -#endif - -#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) - &dcd_data1 -#else - NULL -#endif -}; - //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ @@ -210,25 +190,23 @@ static void bus_reset(uint8_t rhport) // read reset bit in portsc //------------- Queue Head & Queue TD -------------// - dcd_data_t* p_dcd = dcd_data_ptr[rhport]; - tu_memclr(p_dcd, sizeof(dcd_data_t)); + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// - p_dcd->qhd[0].zero_length_termination = p_dcd->qhd[1].zero_length_termination = 1; - p_dcd->qhd[0].max_package_size = p_dcd->qhd[1].max_package_size = CFG_TUD_ENDPOINT0_SIZE; - p_dcd->qhd[0].qtd_overlay.next = p_dcd->qhd[1].qtd_overlay.next = QTD_NEXT_INVALID; + _dcd_data.qhd[0].zero_length_termination = _dcd_data.qhd[1].zero_length_termination = 1; + _dcd_data.qhd[0].max_package_size = _dcd_data.qhd[1].max_package_size = CFG_TUD_ENDPOINT0_SIZE; + _dcd_data.qhd[0].qtd_overlay.next = _dcd_data.qhd[1].qtd_overlay.next = QTD_NEXT_INVALID; - p_dcd->qhd[0].int_on_setup = 1; // OUT only + _dcd_data.qhd[0].int_on_setup = 1; // OUT only } void dcd_init(uint8_t rhport) { LPC_USBHS_T* const lpc_usb = LPC_USB[rhport]; - dcd_data_t* p_dcd = dcd_data_ptr[rhport]; - tu_memclr(p_dcd, sizeof(dcd_data_t)); + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - lpc_usb->ENDPOINTLISTADDR = (uint32_t) p_dcd->qhd; // Endpoint List Address has to be 2K alignment + lpc_usb->ENDPOINTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment lpc_usb->USBSTS_D = lpc_usb->USBSTS_D; lpc_usb->USBINTR_D = INT_MASK_USB | INT_MASK_ERROR | INT_MASK_PORT_CHANGE | INT_MASK_RESET | INT_MASK_SUSPEND | INT_MASK_SOF; @@ -327,7 +305,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) TU_ASSERT( epnum <= (rhport ? 3 : 5) ); //------------- Prepare Queue Head -------------// - dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx]; + dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; tu_memclr(p_qhd, sizeof(dcd_qhd_t)); p_qhd->zero_length_termination = 1; @@ -353,8 +331,8 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t while(LPC_USB[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} } - dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx]; - dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx]; + dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; //------------- Prepare qtd -------------// qtd_init(p_qtd, buffer, total_bytes); @@ -414,15 +392,13 @@ void dcd_isr(uint8_t rhport) uint32_t const edpt_complete = lpc_usb->ENDPTCOMPLETE; lpc_usb->ENDPTCOMPLETE = edpt_complete; // acknowledge - dcd_data_t* const p_dcd = dcd_data_ptr[rhport]; - if (lpc_usb->ENDPTSETUPSTAT) { //------------- Set up Received -------------// // 23.10.10.2 Operational model for setup transfers lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;// acknowledge - dcd_event_setup_received(rhport, (uint8_t*) &p_dcd->qhd[0].setup_request, true); + dcd_event_setup_received(rhport, (uint8_t*) &_dcd_data.qhd[0].setup_request, true); } if ( edpt_complete ) @@ -432,7 +408,7 @@ void dcd_isr(uint8_t rhport) if ( tu_bit_test(edpt_complete, ep_idx2bit(ep_idx)) ) { // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set - dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; -- cgit v1.3.1 From 8aacd1eacdc706e2fc54fa069b9ccf966aee6713 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 12:11:13 +0700 Subject: refactor dcd_lpc18_43, making it capatible with rt10xx --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 94 ++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 22 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 7613f6711..75dd7b850 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -40,12 +40,61 @@ #include "fsl_device_registers.h" #else #include "chip.h" + + // Register base to CAPLENGTH + #define DCD_REGS_BASE { (dcd_registers_t*) (LPC_USB0_BASE + 0x100), (dcd_registers_t*) (LPC_USB1_BASE + 0x100) } #endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +// Device Register starting with CAPLENGTH offset +typedef struct +{ + //------------- Capability Registers-------------// + __I uint8_t CAPLENGTH; ///< Capability Registers Length + __I uint8_t TU_RESERVED[1]; + __I uint16_t HCIVERSION; ///< Host Controller Interface Version + + __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters + __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters + __I uint32_t TU_RESERVED[5]; + + __I uint16_t DCIVERSION; ///< Device Controller Interface Version + __I uint8_t TU_RESERVED[2]; + + __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters + __I uint32_t TU_RESERVED[6]; + + //------------- Operational Registers -------------// + __IO uint32_t USBCMD; ///< USB Command Register + __IO uint32_t USBSTS; ///< USB Status Register + __IO uint32_t USBINTR; ///< Interrupt Enable Register + __IO uint32_t FRINDEX; ///< USB Frame Index + __I uint32_t TU_RESERVED; + __IO uint32_t DEVICEADDR; ///< Device Address + __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address + __I uint32_t TU_RESERVED; + __IO uint32_t BURSTSIZE; ///< Programmable Burst Size + __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning + uint32_t TU_RESERVED[4]; + __IO uint32_t ENDPTNAK; ///< Endpoint NAK + __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable + __I uint32_t TU_RESERVED; + __IO uint32_t PORTSC1; ///< Port Status & Control + __I uint32_t TU_RESERVED[7]; + __IO uint32_t OTGSC; ///< On-The-Go Status & control + __IO uint32_t USBMODE; ///< USB Device Mode + __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status + __IO uint32_t ENDPTPRIME; ///< Endpoint Prime + __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush + __I uint32_t ENDPTSTAT; ///< Endpoint Status + __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete + __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 +} dcd_registers_t; + + /*---------- ENDPTCTRL ----------*/ enum { ENDPTCTRL_MASK_STALL = TU_BIT(0), @@ -153,7 +202,8 @@ typedef struct { }dcd_data_t; static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); -static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; +//static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; +static dcd_registers_t* dcd_regs[] = DCD_REGS_BASE; //--------------------------------------------------------------------+ // CONTROLLER API @@ -162,7 +212,7 @@ static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; /// follows LPC43xx User Manual 23.10.3 static void bus_reset(uint8_t rhport) { - LPC_USBHS_T* lpc_usb = LPC_USB[rhport]; + dcd_registers_t* lpc_usb = dcd_regs[rhport]; // The reset value for all endpoint types is the control endpoint. If one endpoint // direction is enabled and the paired endpoint of opposite direction is disabled, then the @@ -179,7 +229,7 @@ static void bus_reset(uint8_t rhport) //------------- Clear All Registers -------------// lpc_usb->ENDPTNAK = lpc_usb->ENDPTNAK; lpc_usb->ENDPTNAKEN = 0; - lpc_usb->USBSTS_D = lpc_usb->USBSTS_D; + lpc_usb->USBSTS = lpc_usb->USBSTS; lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT; lpc_usb->ENDPTCOMPLETE = lpc_usb->ENDPTCOMPLETE; @@ -202,16 +252,16 @@ static void bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - LPC_USBHS_T* const lpc_usb = LPC_USB[rhport]; + dcd_registers_t* const lpc_usb = dcd_regs[rhport]; tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - lpc_usb->ENDPOINTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment - lpc_usb->USBSTS_D = lpc_usb->USBSTS_D; - lpc_usb->USBINTR_D = INT_MASK_USB | INT_MASK_ERROR | INT_MASK_PORT_CHANGE | INT_MASK_RESET | INT_MASK_SUSPEND | INT_MASK_SOF; + lpc_usb->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + lpc_usb->USBSTS = lpc_usb->USBSTS; + lpc_usb->USBINTR = INT_MASK_USB | INT_MASK_ERROR | INT_MASK_PORT_CHANGE | INT_MASK_RESET | INT_MASK_SUSPEND | INT_MASK_SOF; - lpc_usb->USBCMD_D &= ~0x00FF0000; // Interrupt Threshold Interval = 0 - lpc_usb->USBCMD_D |= TU_BIT(0); // connect + lpc_usb->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 + lpc_usb->USBCMD |= TU_BIT(0); // connect } void dcd_int_enable(uint8_t rhport) @@ -229,7 +279,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - LPC_USB[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); + dcd_regs[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); } void dcd_set_config(uint8_t rhport, uint8_t config_num) @@ -279,7 +329,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - LPC_USB[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_STALL << (dir ? 16 : 0); + dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_STALL << (dir ? 16 : 0); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) @@ -288,8 +338,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); // data toggle also need to be reset - LPC_USB[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_TOGGLE_RESET << ( dir ? 16 : 0 ); - LPC_USB[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_MASK_STALL << ( dir ? 16 : 0)); + dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_TOGGLE_RESET << ( dir ? 16 : 0 ); + dcd_regs[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_MASK_STALL << ( dir ? 16 : 0)); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) @@ -313,7 +363,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; // Enable EP Control - LPC_USB[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0); + dcd_regs[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0); return true; } @@ -328,7 +378,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t { // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out - while(LPC_USB[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} + while(dcd_regs[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} } dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; @@ -340,7 +390,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd // start transfer - LPC_USB[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; + dcd_regs[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; return true; } @@ -350,11 +400,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t //--------------------------------------------------------------------+ void dcd_isr(uint8_t rhport) { - LPC_USBHS_T* const lpc_usb = LPC_USB[rhport]; + dcd_registers_t* const lpc_usb = dcd_regs[rhport]; - uint32_t const int_enable = lpc_usb->USBINTR_D; - uint32_t const int_status = lpc_usb->USBSTS_D & int_enable; - lpc_usb->USBSTS_D = int_status; // Acknowledge handled interrupt + uint32_t const int_enable = lpc_usb->USBINTR; + uint32_t const int_status = lpc_usb->USBSTS & int_enable; + lpc_usb->USBSTS = int_status; // Acknowledge handled interrupt if (int_status == 0) return;// disabled interrupt sources @@ -367,7 +417,7 @@ void dcd_isr(uint8_t rhport) if (int_status & INT_MASK_SUSPEND) { - if (lpc_usb->PORTSC1_D & PORTSC_SUSPEND_MASK) + if (lpc_usb->PORTSC1 & PORTSC_SUSPEND_MASK) { // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. if ((lpc_usb->DEVICEADDR >> 25) & 0x0f) @@ -380,7 +430,7 @@ void dcd_isr(uint8_t rhport) // TODO disconnection does not generate interrupt !!!!!! // if (int_status & INT_MASK_PORT_CHANGE) // { -// if ( !(lpc_usb->PORTSC1_D & PORTSC_CURRENT_CONNECT_STATUS_MASK) ) +// if ( !(lpc_usb->PORTSC1 & PORTSC_CURRENT_CONNECT_STATUS_MASK) ) // { // dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; // dcd_event_handler(&event, true); -- cgit v1.3.1 From 7e16a9a1dbbb5ad87d351a7332adb361b1b6b2d3 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 12:14:55 +0700 Subject: more constant rename clean up --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 100 ++++++++++++++++--------------- 1 file changed, 51 insertions(+), 49 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 75dd7b850..1e710c9c6 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -49,6 +49,41 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +// ENDPTCTRL +enum { + ENDPTCTRL_STALL = TU_BIT(0), + ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only + ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), + ENDPTCTRL_ENABLE = TU_BIT(7) +}; + +// USBCMD +enum { + USBCMD_RUN_STOP = TU_BIT(0), + USBCMD_RESET = TU_BIT(1), + USBCMD_SETUP_TRIPWIRE = TU_BIT(13), + USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD +}; +// Interrupt Threshold bit 23:16 + +// USBSTS, USBINTR +enum { + INTR_USB = TU_BIT(0), + INTR_ERROR = TU_BIT(1), + INTR_PORT_CHANGE = TU_BIT(2), + INTR_RESET = TU_BIT(6), + INTR_SOF = TU_BIT(7), + INTR_SUSPEND = TU_BIT(8), + INTR_NAK = TU_BIT(16) +}; + +// PORTSC +enum { + PORTSC_CURRENT_CONNECT_STATUS = TU_BIT(0), + PORTSC_FORCE_PORT_RESUME = TU_BIT(6), + PORTSC_SUSPEND = TU_BIT(7) +}; + // Device Register starting with CAPLENGTH offset typedef struct { @@ -95,41 +130,7 @@ typedef struct } dcd_registers_t; -/*---------- ENDPTCTRL ----------*/ -enum { - ENDPTCTRL_MASK_STALL = TU_BIT(0), - ENDPTCTRL_MASK_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only - ENDPTCTRL_MASK_TOGGLE_RESET = TU_BIT(6), - ENDPTCTRL_MASK_ENABLE = TU_BIT(7) -}; - -/*---------- USBCMD ----------*/ -enum { - USBCMD_MASK_RUN_STOP = TU_BIT(0), - USBCMD_MASK_RESET = TU_BIT(1), - USBCMD_MASK_SETUP_TRIPWIRE = TU_BIT(13), - USBCMD_MASK_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD -}; -// Interrupt Threshold bit 23:16 - -/*---------- USBSTS, USBINTR ----------*/ -enum { - INT_MASK_USB = TU_BIT(0), - INT_MASK_ERROR = TU_BIT(1), - INT_MASK_PORT_CHANGE = TU_BIT(2), - INT_MASK_RESET = TU_BIT(6), - INT_MASK_SOF = TU_BIT(7), - INT_MASK_SUSPEND = TU_BIT(8), - INT_MASK_NAK = TU_BIT(16) -}; - -//------------- PORTSC -------------// -enum { - PORTSC_CURRENT_CONNECT_STATUS_MASK = TU_BIT(0), - PORTSC_FORCE_PORT_RESUME_MASK = TU_BIT(6), - PORTSC_SUSPEND_MASK = TU_BIT(7) -}; - +// Queue Transfer Descriptor typedef struct { // Word 0: Next QTD Pointer @@ -159,6 +160,7 @@ typedef struct TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); +// Queue Head typedef struct { // Word 0: Capabilities and Characteristics @@ -258,7 +260,7 @@ void dcd_init(uint8_t rhport) lpc_usb->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment lpc_usb->USBSTS = lpc_usb->USBSTS; - lpc_usb->USBINTR = INT_MASK_USB | INT_MASK_ERROR | INT_MASK_PORT_CHANGE | INT_MASK_RESET | INT_MASK_SUSPEND | INT_MASK_SOF; + lpc_usb->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND | INTR_SOF; lpc_usb->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 lpc_usb->USBCMD |= TU_BIT(0); // connect @@ -329,7 +331,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_STALL << (dir ? 16 : 0); + dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) @@ -338,8 +340,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); // data toggle also need to be reset - dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_MASK_TOGGLE_RESET << ( dir ? 16 : 0 ); - dcd_regs[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_MASK_STALL << ( dir ? 16 : 0)); + dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + dcd_regs[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) @@ -363,7 +365,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; // Enable EP Control - dcd_regs[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_MASK_ENABLE | ENDPTCTRL_MASK_TOGGLE_RESET) << (dir ? 16 : 0); + dcd_regs[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); return true; } @@ -409,15 +411,15 @@ void dcd_isr(uint8_t rhport) if (int_status == 0) return;// disabled interrupt sources - if (int_status & INT_MASK_RESET) + if (int_status & INTR_RESET) { bus_reset(rhport); dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); } - if (int_status & INT_MASK_SUSPEND) + if (int_status & INTR_SUSPEND) { - if (lpc_usb->PORTSC1 & PORTSC_SUSPEND_MASK) + if (lpc_usb->PORTSC1 & PORTSC_SUSPEND) { // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. if ((lpc_usb->DEVICEADDR >> 25) & 0x0f) @@ -428,16 +430,16 @@ void dcd_isr(uint8_t rhport) } // TODO disconnection does not generate interrupt !!!!!! -// if (int_status & INT_MASK_PORT_CHANGE) +// if (int_status & INTR_PORT_CHANGE) // { -// if ( !(lpc_usb->PORTSC1 & PORTSC_CURRENT_CONNECT_STATUS_MASK) ) +// if ( !(lpc_usb->PORTSC1 & PORTSC_CURRENT_CONNECT_STATUS) ) // { // dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; // dcd_event_handler(&event, true); // } // } - if (int_status & INT_MASK_USB) + if (int_status & INTR_USB) { uint32_t const edpt_complete = lpc_usb->ENDPTCOMPLETE; lpc_usb->ENDPTCOMPLETE = edpt_complete; // acknowledge @@ -470,13 +472,13 @@ void dcd_isr(uint8_t rhport) } } - if (int_status & INT_MASK_SOF) + if (int_status & INTR_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } - if (int_status & INT_MASK_NAK) {} - if (int_status & INT_MASK_ERROR) TU_ASSERT(false, ); + if (int_status & INTR_NAK) {} + if (int_status & INTR_ERROR) TU_ASSERT(false, ); } #endif -- cgit v1.3.1 From ccb09db3b782163e93f2208ff5612c789d465058 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 12:16:47 +0700 Subject: more clean up --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 74 ++++++++++++++++---------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 1e710c9c6..2f3d8ab25 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -205,7 +205,7 @@ typedef struct { static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); //static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; -static dcd_registers_t* dcd_regs[] = DCD_REGS_BASE; +static dcd_registers_t* DCD_REGS[] = DCD_REGS_BASE; //--------------------------------------------------------------------+ // CONTROLLER API @@ -214,7 +214,7 @@ static dcd_registers_t* dcd_regs[] = DCD_REGS_BASE; /// follows LPC43xx User Manual 23.10.3 static void bus_reset(uint8_t rhport) { - dcd_registers_t* lpc_usb = dcd_regs[rhport]; + dcd_registers_t* dcd_reg = DCD_REGS[rhport]; // The reset value for all endpoint types is the control endpoint. If one endpoint // direction is enabled and the paired endpoint of opposite direction is disabled, then the @@ -225,19 +225,19 @@ static void bus_reset(uint8_t rhport) // USB0 has 5 but USB1 only has 3 non-control endpoints for( int i=1; i < (rhport ? 6 : 4); i++) { - lpc_usb->ENDPTCTRL[i] = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18); + dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18); } //------------- Clear All Registers -------------// - lpc_usb->ENDPTNAK = lpc_usb->ENDPTNAK; - lpc_usb->ENDPTNAKEN = 0; - lpc_usb->USBSTS = lpc_usb->USBSTS; - lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT; - lpc_usb->ENDPTCOMPLETE = lpc_usb->ENDPTCOMPLETE; + dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; + dcd_reg->ENDPTNAKEN = 0; + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; - while (lpc_usb->ENDPTPRIME); - lpc_usb->ENDPTFLUSH = 0xFFFFFFFF; - while (lpc_usb->ENDPTFLUSH); + while (dcd_reg->ENDPTPRIME); + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH); // read reset bit in portsc @@ -254,16 +254,16 @@ static void bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - dcd_registers_t* const lpc_usb = dcd_regs[rhport]; + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - lpc_usb->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment - lpc_usb->USBSTS = lpc_usb->USBSTS; - lpc_usb->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND | INTR_SOF; + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND | INTR_SOF; - lpc_usb->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 - lpc_usb->USBCMD |= TU_BIT(0); // connect + dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0 + dcd_reg->USBCMD |= TU_BIT(0); // connect } void dcd_int_enable(uint8_t rhport) @@ -281,7 +281,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - dcd_regs[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); + DCD_REGS[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); } void dcd_set_config(uint8_t rhport, uint8_t config_num) @@ -331,7 +331,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) @@ -340,8 +340,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); // data toggle also need to be reset - dcd_regs[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); - dcd_regs[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + DCD_REGS[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) @@ -365,7 +365,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; // Enable EP Control - dcd_regs[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); return true; } @@ -380,7 +380,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t { // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out - while(dcd_regs[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} + while(DCD_REGS[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} } dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; @@ -392,7 +392,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd // start transfer - dcd_regs[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; + DCD_REGS[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; return true; } @@ -402,14 +402,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t //--------------------------------------------------------------------+ void dcd_isr(uint8_t rhport) { - dcd_registers_t* const lpc_usb = dcd_regs[rhport]; + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; - uint32_t const int_enable = lpc_usb->USBINTR; - uint32_t const int_status = lpc_usb->USBSTS & int_enable; - lpc_usb->USBSTS = int_status; // Acknowledge handled interrupt - - if (int_status == 0) return;// disabled interrupt sources + uint32_t const int_enable = dcd_reg->USBINTR; + uint32_t const int_status = dcd_reg->USBSTS & int_enable; + dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt + // disabled interrupt sources + if (int_status == 0) return; if (int_status & INTR_RESET) { @@ -419,10 +419,10 @@ void dcd_isr(uint8_t rhport) if (int_status & INTR_SUSPEND) { - if (lpc_usb->PORTSC1 & PORTSC_SUSPEND) + if (dcd_reg->PORTSC1 & PORTSC_SUSPEND) { // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. - if ((lpc_usb->DEVICEADDR >> 25) & 0x0f) + if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } @@ -432,7 +432,7 @@ void dcd_isr(uint8_t rhport) // TODO disconnection does not generate interrupt !!!!!! // if (int_status & INTR_PORT_CHANGE) // { -// if ( !(lpc_usb->PORTSC1 & PORTSC_CURRENT_CONNECT_STATUS) ) +// if ( !(dcd_reg->PORTSC1 & PORTSC_CURRENT_CONNECT_STATUS) ) // { // dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; // dcd_event_handler(&event, true); @@ -441,14 +441,14 @@ void dcd_isr(uint8_t rhport) if (int_status & INTR_USB) { - uint32_t const edpt_complete = lpc_usb->ENDPTCOMPLETE; - lpc_usb->ENDPTCOMPLETE = edpt_complete; // acknowledge + uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; + dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge - if (lpc_usb->ENDPTSETUPSTAT) + if (dcd_reg->ENDPTSETUPSTAT) { //------------- Set up Received -------------// // 23.10.10.2 Operational model for setup transfers - lpc_usb->ENDPTSETUPSTAT = lpc_usb->ENDPTSETUPSTAT;// acknowledge + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;// acknowledge dcd_event_setup_received(rhport, (uint8_t*) &_dcd_data.qhd[0].setup_request, true); } -- cgit v1.3.1 From 2ead26a12d8ec1a3c229d2afdb3f36fdde444162 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 12:26:40 +0700 Subject: more clean up --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 2f3d8ab25..6e3e993d2 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -38,11 +38,11 @@ #if CFG_TUSB_MCU == OPT_MCU_RT10XX #include "fsl_device_registers.h" + #define DCD_REGS_BASE { (dcd_registers_t*) USB1_BASE, (dcd_registers_t*) USB2_BASE } + #else #include "chip.h" - - // Register base to CAPLENGTH - #define DCD_REGS_BASE { (dcd_registers_t*) (LPC_USB0_BASE + 0x100), (dcd_registers_t*) (LPC_USB1_BASE + 0x100) } + #define DCD_REGS_BASE { (dcd_registers_t*) LPC_USB0_BASE, (dcd_registers_t*) LPC_USB1_BASE } #endif //--------------------------------------------------------------------+ @@ -84,9 +84,12 @@ enum { PORTSC_SUSPEND = TU_BIT(7) }; -// Device Register starting with CAPLENGTH offset +// Device Registers typedef struct { + //------------- ID + HW Parameter Registers-------------// + __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX + //------------- Capability Registers-------------// __I uint8_t CAPLENGTH; ///< Capability Registers Length __I uint8_t TU_RESERVED[1]; @@ -204,7 +207,6 @@ typedef struct { }dcd_data_t; static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); -//static LPC_USBHS_T * const LPC_USB[2] = { LPC_USB0, LPC_USB1 }; static dcd_registers_t* DCD_REGS[] = DCD_REGS_BASE; //--------------------------------------------------------------------+ -- cgit v1.3.1 From fca4653b95038d1ed1905d5a4731f758a1023eaa Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 12:34:41 +0700 Subject: able to compile dcd 18/43 with rt1064 --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 6e3e993d2..4972446b6 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -38,11 +38,13 @@ #if CFG_TUSB_MCU == OPT_MCU_RT10XX #include "fsl_device_registers.h" - #define DCD_REGS_BASE { (dcd_registers_t*) USB1_BASE, (dcd_registers_t*) USB2_BASE } + #define DCD_REGS_BASE { (dcd_registers_t*) USB1_BASE, (dcd_registers_t*) USB2_BASE } + IRQn_Type DCD_IRQn[] = { USB_OTG1_IRQn, USB_OTG2_IRQn }; #else #include "chip.h" - #define DCD_REGS_BASE { (dcd_registers_t*) LPC_USB0_BASE, (dcd_registers_t*) LPC_USB1_BASE } + #define DCD_REGS_BASE { (dcd_registers_t*) LPC_USB0_BASE, (dcd_registers_t*) LPC_USB1_BASE } + IRQn_Type DCD_IRQn[] = { USB0_IRQn, USB1_IRQn }; #endif //--------------------------------------------------------------------+ @@ -270,12 +272,12 @@ void dcd_init(uint8_t rhport) void dcd_int_enable(uint8_t rhport) { - NVIC_EnableIRQ(rhport ? USB1_IRQn : USB0_IRQn); + NVIC_EnableIRQ(DCD_IRQn[rhport]); } void dcd_int_disable(uint8_t rhport) { - NVIC_DisableIRQ(rhport ? USB1_IRQn : USB0_IRQn); + NVIC_DisableIRQ(DCD_IRQn[rhport]); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -- cgit v1.3.1 From a0b2561a2df93cccbf48002348daf4220262f8d8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 14:20:10 +0700 Subject: move nxp dcd ehci controller reset and modde into dcd rt1064 work with cdc msc example --- hw/bsp/ea4357/ea4357.c | 52 ++++++++++++++--------------- hw/bsp/mcb1800/mcb1800.c | 48 +++++++++++++-------------- hw/bsp/ngx4330/ngx4330.c | 52 ++++++++++++++--------------- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 56 ++++++++++++++++++++++++++++---- 4 files changed, 125 insertions(+), 83 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/ea4357/ea4357.c b/hw/bsp/ea4357/ea4357.c index f21d3259d..f5d2a199e 100644 --- a/hw/bsp/ea4357/ea4357.c +++ b/hw/bsp/ea4357/ea4357.c @@ -166,19 +166,19 @@ void board_init(void) #if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); - // Reset controller - LPC_USB0->USBCMD_D |= 0x02; - while( LPC_USB0->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - - LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging - #else // TODO OTG - LPC_USB0->USBMODE_D = USBMODE_DEVICE; - LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; - #endif +// // Reset controller +// LPC_USB0->USBCMD_D |= 0x02; +// while( LPC_USB0->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST +// LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// +// LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging +// #else // TODO OTG +// LPC_USB0->USBMODE_D = USBMODE_DEVICE; +// LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; +// #endif #endif /* USB1 @@ -202,19 +202,19 @@ void board_init(void) #if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Reset controller - LPC_USB1->USBCMD_D |= 0x02; - while( LPC_USB1->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB1->USBMODE_D = USBMODE_DEVICE; - #endif - - // USB1 as fullspeed - LPC_USB1->PORTSC1_D |= (1<<24); +// // Reset controller +// LPC_USB1->USBCMD_D |= 0x02; +// while( LPC_USB1->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST +// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB1->USBMODE_D = USBMODE_DEVICE; +// #endif +// +// // USB1 as fullspeed +// LPC_USB1->PORTSC1_D |= (1<<24); #endif // USB0 Vbus Power: P2_3 on EA4357 channel B U20 GPIO26 active low (base board) diff --git a/hw/bsp/mcb1800/mcb1800.c b/hw/bsp/mcb1800/mcb1800.c index 4fe874762..6d5284869 100644 --- a/hw/bsp/mcb1800/mcb1800.c +++ b/hw/bsp/mcb1800/mcb1800.c @@ -139,36 +139,36 @@ void board_init(void) #if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); - // Reset controller - LPC_USB0->USBCMD_D |= 0x02; - while( LPC_USB0->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB0->USBMODE_D = USBMODE_DEVICE; - LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; - #endif +// // Reset controller +// LPC_USB0->USBCMD_D |= 0x02; +// while( LPC_USB0->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST +// LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB0->USBMODE_D = USBMODE_DEVICE; +// LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; +// #endif #endif // USB1 #if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Reset controller - LPC_USB1->USBCMD_D |= 0x02; - while( LPC_USB1->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB1->USBMODE_D = USBMODE_DEVICE; - #endif - - // USB1 as fullspeed - LPC_USB1->PORTSC1_D |= (1<<24); +// // Reset controller +// LPC_USB1->USBCMD_D |= 0x02; +// while( LPC_USB1->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST +// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB1->USBMODE_D = USBMODE_DEVICE; +// #endif +// +// // USB1 as fullspeed +// LPC_USB1->PORTSC1_D |= (1<<24); #endif } diff --git a/hw/bsp/ngx4330/ngx4330.c b/hw/bsp/ngx4330/ngx4330.c index fd6f0119b..e1bafff8d 100644 --- a/hw/bsp/ngx4330/ngx4330.c +++ b/hw/bsp/ngx4330/ngx4330.c @@ -164,19 +164,19 @@ void board_init(void) #if CFG_TUSB_RHPORT0_MODE Chip_USB0_Init(); - // Reset controller - LPC_USB0->USBCMD_D |= 0x02; - while( LPC_USB0->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST - LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - - LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging - #else // TODO OTG - LPC_USB0->USBMODE_D = USBMODE_DEVICE; - LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; - #endif +// // Reset controller +// LPC_USB0->USBCMD_D |= 0x02; +// while( LPC_USB0->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST +// LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// +// LPC_USB0->PORTSC1_D |= (1<<24); // FIXME force full speed for debugging +// #else // TODO OTG +// LPC_USB0->USBMODE_D = USBMODE_DEVICE; +// LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/; +// #endif #endif /* USB1 @@ -200,19 +200,19 @@ void board_init(void) #if CFG_TUSB_RHPORT1_MODE Chip_USB1_Init(); - // Reset controller - LPC_USB1->USBCMD_D |= 0x02; - while( LPC_USB1->USBCMD_D & 0x02 ) {} - - // Set mode - #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST - LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); - #else // TODO OTG - LPC_USB1->USBMODE_D = USBMODE_DEVICE; - #endif - - // USB1 as fullspeed - LPC_USB1->PORTSC1_D |= (1<<24); +// // Reset controller +// LPC_USB1->USBCMD_D |= 0x02; +// while( LPC_USB1->USBCMD_D & 0x02 ) {} +// +// // Set mode +// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST +// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5); +// #else // TODO OTG +// LPC_USB1->USBMODE_D = USBMODE_DEVICE; +// #endif +// +// // USB1 as fullspeed +// LPC_USB1->PORTSC1_D |= (1<<24); // Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 5, 6); /* GPIO5[6] = USB1_PWR_EN */ // Chip_GPIO_SetPinState(LPC_GPIO_PORT, 5, 6, true); /* GPIO5[6] output high */ diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 4972446b6..b9527d65d 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -79,11 +79,42 @@ enum { INTR_NAK = TU_BIT(16) }; -// PORTSC +// PORTSC1 enum { - PORTSC_CURRENT_CONNECT_STATUS = TU_BIT(0), - PORTSC_FORCE_PORT_RESUME = TU_BIT(6), - PORTSC_SUSPEND = TU_BIT(7) + PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), + PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), + PORTSC1_SUSPEND = TU_BIT(7), + PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), +}; + +// OTGSC +enum { + OTGSC_VBUS_DISCHARGE = TU_BIT(0), + OTGSC_VBUS_CHARGE = TU_BIT(1), +// OTGSC_HWASSIST_AUTORESET = TU_BIT(2), + OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode + OTGSC_DATA_PULSING = TU_BIT(4), + OTGSC_ID_PULLUP = TU_BIT(5), +// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), +// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), + OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device + OTGSC_A_VBUS_VALID = TU_BIT(9), + OTGSC_A_SESSION_VALID = TU_BIT(10), + OTGSC_B_SESSION_VALID = TU_BIT(11), + OTGSC_B_SESSION_END = TU_BIT(12), + OTGSC_1MS_TOGGLE = TU_BIT(13), + OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), +}; + +// USBMode +enum { + USBMODE_CM_DEVICE = 2, + USBMODE_CM_HOST = 3, + + USBMODE_SLOM = TU_BIT(3), + USBMODE_SDIS = TU_BIT(4), + + USBMODE_VBUS_POWER_SELCT = TU_BIT(5), // Enable for LPC18XX/43XX in host most only }; // Device Registers @@ -258,9 +289,20 @@ static void bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; - tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + // Reset controller + dcd_reg->USBCMD |= USBCMD_RESET; + while( dcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset + dcd_reg->USBMODE = USBMODE_CM_DEVICE; + dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; + + // TODO Force fullspeed on non-highspeed port + // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment dcd_reg->USBSTS = dcd_reg->USBSTS; @@ -423,7 +465,7 @@ void dcd_isr(uint8_t rhport) if (int_status & INTR_SUSPEND) { - if (dcd_reg->PORTSC1 & PORTSC_SUSPEND) + if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) { // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) @@ -436,7 +478,7 @@ void dcd_isr(uint8_t rhport) // TODO disconnection does not generate interrupt !!!!!! // if (int_status & INTR_PORT_CHANGE) // { -// if ( !(dcd_reg->PORTSC1 & PORTSC_CURRENT_CONNECT_STATUS) ) +// if ( !(dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) ) // { // dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; // dcd_event_handler(&event, true); -- cgit v1.3.1 From 6123b600fc9706cec73f1116eeaf0246773fccf9 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Nov 2019 14:47:07 +0700 Subject: rename dcd_lpc18_43 to dcd_transdimension --- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 530 --------------------- .../nxp/transdimension/dcd_transdimension.c | 530 +++++++++++++++++++++ 2 files changed, 530 insertions(+), 530 deletions(-) delete mode 100644 src/portable/nxp/lpc18_43/dcd_lpc18_43.c create mode 100644 src/portable/nxp/transdimension/dcd_transdimension.c (limited to 'src/portable') diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c deleted file mode 100644 index b9527d65d..000000000 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ - CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ - CFG_TUSB_MCU == OPT_MCU_RT10XX) - -//--------------------------------------------------------------------+ -// INCLUDE -//--------------------------------------------------------------------+ -#include "common/tusb_common.h" -#include "device/dcd.h" - -#if CFG_TUSB_MCU == OPT_MCU_RT10XX - #include "fsl_device_registers.h" - #define DCD_REGS_BASE { (dcd_registers_t*) USB1_BASE, (dcd_registers_t*) USB2_BASE } - IRQn_Type DCD_IRQn[] = { USB_OTG1_IRQn, USB_OTG2_IRQn }; - -#else - #include "chip.h" - #define DCD_REGS_BASE { (dcd_registers_t*) LPC_USB0_BASE, (dcd_registers_t*) LPC_USB1_BASE } - IRQn_Type DCD_IRQn[] = { USB0_IRQn, USB1_IRQn }; -#endif - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF -//--------------------------------------------------------------------+ - -// ENDPTCTRL -enum { - ENDPTCTRL_STALL = TU_BIT(0), - ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only - ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), - ENDPTCTRL_ENABLE = TU_BIT(7) -}; - -// USBCMD -enum { - USBCMD_RUN_STOP = TU_BIT(0), - USBCMD_RESET = TU_BIT(1), - USBCMD_SETUP_TRIPWIRE = TU_BIT(13), - USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD -}; -// Interrupt Threshold bit 23:16 - -// USBSTS, USBINTR -enum { - INTR_USB = TU_BIT(0), - INTR_ERROR = TU_BIT(1), - INTR_PORT_CHANGE = TU_BIT(2), - INTR_RESET = TU_BIT(6), - INTR_SOF = TU_BIT(7), - INTR_SUSPEND = TU_BIT(8), - INTR_NAK = TU_BIT(16) -}; - -// PORTSC1 -enum { - PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), - PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), - PORTSC1_SUSPEND = TU_BIT(7), - PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), -}; - -// OTGSC -enum { - OTGSC_VBUS_DISCHARGE = TU_BIT(0), - OTGSC_VBUS_CHARGE = TU_BIT(1), -// OTGSC_HWASSIST_AUTORESET = TU_BIT(2), - OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode - OTGSC_DATA_PULSING = TU_BIT(4), - OTGSC_ID_PULLUP = TU_BIT(5), -// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), -// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), - OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device - OTGSC_A_VBUS_VALID = TU_BIT(9), - OTGSC_A_SESSION_VALID = TU_BIT(10), - OTGSC_B_SESSION_VALID = TU_BIT(11), - OTGSC_B_SESSION_END = TU_BIT(12), - OTGSC_1MS_TOGGLE = TU_BIT(13), - OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), -}; - -// USBMode -enum { - USBMODE_CM_DEVICE = 2, - USBMODE_CM_HOST = 3, - - USBMODE_SLOM = TU_BIT(3), - USBMODE_SDIS = TU_BIT(4), - - USBMODE_VBUS_POWER_SELCT = TU_BIT(5), // Enable for LPC18XX/43XX in host most only -}; - -// Device Registers -typedef struct -{ - //------------- ID + HW Parameter Registers-------------// - __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX - - //------------- Capability Registers-------------// - __I uint8_t CAPLENGTH; ///< Capability Registers Length - __I uint8_t TU_RESERVED[1]; - __I uint16_t HCIVERSION; ///< Host Controller Interface Version - - __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters - __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters - __I uint32_t TU_RESERVED[5]; - - __I uint16_t DCIVERSION; ///< Device Controller Interface Version - __I uint8_t TU_RESERVED[2]; - - __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters - __I uint32_t TU_RESERVED[6]; - - //------------- Operational Registers -------------// - __IO uint32_t USBCMD; ///< USB Command Register - __IO uint32_t USBSTS; ///< USB Status Register - __IO uint32_t USBINTR; ///< Interrupt Enable Register - __IO uint32_t FRINDEX; ///< USB Frame Index - __I uint32_t TU_RESERVED; - __IO uint32_t DEVICEADDR; ///< Device Address - __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address - __I uint32_t TU_RESERVED; - __IO uint32_t BURSTSIZE; ///< Programmable Burst Size - __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning - uint32_t TU_RESERVED[4]; - __IO uint32_t ENDPTNAK; ///< Endpoint NAK - __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable - __I uint32_t TU_RESERVED; - __IO uint32_t PORTSC1; ///< Port Status & Control - __I uint32_t TU_RESERVED[7]; - __IO uint32_t OTGSC; ///< On-The-Go Status & control - __IO uint32_t USBMODE; ///< USB Device Mode - __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status - __IO uint32_t ENDPTPRIME; ///< Endpoint Prime - __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush - __I uint32_t ENDPTSTAT; ///< Endpoint Status - __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete - __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 -} dcd_registers_t; - - -// Queue Transfer Descriptor -typedef struct -{ - // Word 0: Next QTD Pointer - uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed - - // Word 1: qTQ Token - uint32_t : 3 ; - volatile uint32_t xact_err : 1 ; - uint32_t : 1 ; - volatile uint32_t buffer_err : 1 ; - volatile uint32_t halted : 1 ; - volatile uint32_t active : 1 ; - uint32_t : 2 ; - uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. - uint32_t : 3 ; - uint32_t int_on_complete : 1 ; - volatile uint32_t total_bytes : 15 ; - uint32_t : 0 ; - - // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page - uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous - - //------------- DCD Area -------------// - uint16_t expected_bytes; - uint8_t reserved[2]; -} dcd_qtd_t; - -TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); - -// Queue Head -typedef struct -{ - // Word 0: Capabilities and Characteristics - uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. - uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. - uint32_t max_package_size : 11 ; ///< This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) - uint32_t : 2 ; - uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. - uint32_t iso_mult : 2 ; ///< - uint32_t : 0 ; - - // Word 1: Current qTD Pointer - volatile uint32_t qtd_addr; - - // Word 2-9: Transfer Overlay - volatile dcd_qtd_t qtd_overlay; - - // Word 10-11: Setup request (control OUT only) - volatile tusb_control_request_t setup_request; - - //--------------------------------------------------------------------+ - /// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes - /// thus there are 16 bytes padding free that we can make use of. - //--------------------------------------------------------------------+ - uint8_t reserved[16]; -} dcd_qhd_t; - -TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); - -//--------------------------------------------------------------------+ -// Variables -//--------------------------------------------------------------------+ - -#define QHD_MAX 12 -#define QTD_NEXT_INVALID 0x01 - -typedef struct { - // Must be at 2K alignment - dcd_qhd_t qhd[QHD_MAX] TU_ATTR_ALIGNED(64); - dcd_qtd_t qtd[QHD_MAX] TU_ATTR_ALIGNED(32); -}dcd_data_t; - -static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); -static dcd_registers_t* DCD_REGS[] = DCD_REGS_BASE; - -//--------------------------------------------------------------------+ -// CONTROLLER API -//--------------------------------------------------------------------+ - -/// follows LPC43xx User Manual 23.10.3 -static void bus_reset(uint8_t rhport) -{ - dcd_registers_t* dcd_reg = DCD_REGS[rhport]; - - // The reset value for all endpoint types is the control endpoint. If one endpoint - // direction is enabled and the paired endpoint of opposite direction is disabled, then the - // endpoint type of the unused direction must bechanged from the control type to any other - // type (e.g. bulk). Leaving an unconfigured endpoint control will cause undefined behavior - // for the data PID tracking on the active endpoint. - - // USB0 has 5 but USB1 only has 3 non-control endpoints - for( int i=1; i < (rhport ? 6 : 4); i++) - { - dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18); - } - - //------------- Clear All Registers -------------// - dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; - dcd_reg->ENDPTNAKEN = 0; - dcd_reg->USBSTS = dcd_reg->USBSTS; - dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; - dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; - - while (dcd_reg->ENDPTPRIME); - dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; - while (dcd_reg->ENDPTFLUSH); - - // read reset bit in portsc - - //------------- Queue Head & Queue TD -------------// - tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - - //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// - _dcd_data.qhd[0].zero_length_termination = _dcd_data.qhd[1].zero_length_termination = 1; - _dcd_data.qhd[0].max_package_size = _dcd_data.qhd[1].max_package_size = CFG_TUD_ENDPOINT0_SIZE; - _dcd_data.qhd[0].qtd_overlay.next = _dcd_data.qhd[1].qtd_overlay.next = QTD_NEXT_INVALID; - - _dcd_data.qhd[0].int_on_setup = 1; // OUT only -} - -void dcd_init(uint8_t rhport) -{ - tu_memclr(&_dcd_data, sizeof(dcd_data_t)); - - dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; - - // Reset controller - dcd_reg->USBCMD |= USBCMD_RESET; - while( dcd_reg->USBCMD & USBCMD_RESET ) {} - - // Set mode to device, must be set immediately after reset - dcd_reg->USBMODE = USBMODE_CM_DEVICE; - dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; - - // TODO Force fullspeed on non-highspeed port - // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; - - dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment - dcd_reg->USBSTS = dcd_reg->USBSTS; - 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) -{ - NVIC_EnableIRQ(DCD_IRQn[rhport]); -} - -void dcd_int_disable(uint8_t rhport) -{ - NVIC_DisableIRQ(DCD_IRQn[rhport]); -} - -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - // Response with status first before changing device address - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - - DCD_REGS[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); -} - -void dcd_set_config(uint8_t rhport, uint8_t config_num) -{ - (void) rhport; - (void) config_num; - // nothing to do -} - -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; -} - -//--------------------------------------------------------------------+ -// HELPER -//--------------------------------------------------------------------+ -// index to bit position in register -static inline uint8_t ep_idx2bit(uint8_t ep_idx) -{ - return ep_idx/2 + ( (ep_idx%2) ? 16 : 0); -} - -static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) -{ - tu_memclr(p_qtd, sizeof(dcd_qtd_t)); - - p_qtd->next = QTD_NEXT_INVALID; - p_qtd->active = 1; - p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; - - if (data_ptr != NULL) - { - p_qtd->buffer[0] = (uint32_t) data_ptr; - for(uint8_t i=1; i<5; i++) - { - p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096; - } - } -} - -//--------------------------------------------------------------------+ -// DCD Endpoint Port -//--------------------------------------------------------------------+ -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); -} - -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - // data toggle also need to be reset - DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); - DCD_REGS[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); -} - -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) -{ - // TODO not support ISO yet - TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); - - uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); - uint8_t const ep_idx = 2*epnum + dir; - - // USB0 has 5, USB1 has 3 non-control endpoints - TU_ASSERT( epnum <= (rhport ? 3 : 5) ); - - //------------- Prepare Queue Head -------------// - dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; - tu_memclr(p_qhd, sizeof(dcd_qhd_t)); - - p_qhd->zero_length_termination = 1; - p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size; - p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; - - // Enable EP Control - DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); - - return true; -} - -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - uint8_t const ep_idx = 2*epnum + dir; - - if ( epnum == 0 ) - { - // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism - // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out - while(DCD_REGS[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} - } - - dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; - dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; - - //------------- Prepare qtd -------------// - qtd_init(p_qtd, buffer, total_bytes); - p_qtd->int_on_complete = true; - p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd - - // start transfer - DCD_REGS[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; - - return true; -} - -//--------------------------------------------------------------------+ -// ISR -//--------------------------------------------------------------------+ -void dcd_isr(uint8_t rhport) -{ - dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; - - uint32_t const int_enable = dcd_reg->USBINTR; - uint32_t const int_status = dcd_reg->USBSTS & int_enable; - dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt - - // disabled interrupt sources - if (int_status == 0) return; - - if (int_status & INTR_RESET) - { - bus_reset(rhport); - dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); - } - - if (int_status & INTR_SUSPEND) - { - if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) - { - // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. - if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) - { - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - } - } - - // TODO disconnection does not generate interrupt !!!!!! -// if (int_status & INTR_PORT_CHANGE) -// { -// if ( !(dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) ) -// { -// dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; -// dcd_event_handler(&event, true); -// } -// } - - if (int_status & INTR_USB) - { - uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; - dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge - - if (dcd_reg->ENDPTSETUPSTAT) - { - //------------- Set up Received -------------// - // 23.10.10.2 Operational model for setup transfers - dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;// acknowledge - - dcd_event_setup_received(rhport, (uint8_t*) &_dcd_data.qhd[0].setup_request, true); - } - - if ( edpt_complete ) - { - for(uint8_t ep_idx = 0; ep_idx < QHD_MAX; ep_idx++) - { - if ( tu_bit_test(edpt_complete, ep_idx2bit(ep_idx)) ) - { - // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set - dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; - - uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : - ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; - - uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 ); - dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd - } - } - } - } - - if (int_status & INTR_SOF) - { - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - - if (int_status & INTR_NAK) {} - if (int_status & INTR_ERROR) TU_ASSERT(false, ); -} - -#endif diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c new file mode 100644 index 000000000..b9527d65d --- /dev/null +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -0,0 +1,530 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || \ + CFG_TUSB_MCU == OPT_MCU_LPC43XX || \ + CFG_TUSB_MCU == OPT_MCU_RT10XX) + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "common/tusb_common.h" +#include "device/dcd.h" + +#if CFG_TUSB_MCU == OPT_MCU_RT10XX + #include "fsl_device_registers.h" + #define DCD_REGS_BASE { (dcd_registers_t*) USB1_BASE, (dcd_registers_t*) USB2_BASE } + IRQn_Type DCD_IRQn[] = { USB_OTG1_IRQn, USB_OTG2_IRQn }; + +#else + #include "chip.h" + #define DCD_REGS_BASE { (dcd_registers_t*) LPC_USB0_BASE, (dcd_registers_t*) LPC_USB1_BASE } + IRQn_Type DCD_IRQn[] = { USB0_IRQn, USB1_IRQn }; +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +// ENDPTCTRL +enum { + ENDPTCTRL_STALL = TU_BIT(0), + ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), ///< used for test only + ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), + ENDPTCTRL_ENABLE = TU_BIT(7) +}; + +// USBCMD +enum { + USBCMD_RUN_STOP = TU_BIT(0), + USBCMD_RESET = TU_BIT(1), + USBCMD_SETUP_TRIPWIRE = TU_BIT(13), + USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD +}; +// Interrupt Threshold bit 23:16 + +// USBSTS, USBINTR +enum { + INTR_USB = TU_BIT(0), + INTR_ERROR = TU_BIT(1), + INTR_PORT_CHANGE = TU_BIT(2), + INTR_RESET = TU_BIT(6), + INTR_SOF = TU_BIT(7), + INTR_SUSPEND = TU_BIT(8), + INTR_NAK = TU_BIT(16) +}; + +// PORTSC1 +enum { + PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0), + PORTSC1_FORCE_PORT_RESUME = TU_BIT(6), + PORTSC1_SUSPEND = TU_BIT(7), + PORTSC1_FORCE_FULL_SPEED = TU_BIT(24), +}; + +// OTGSC +enum { + OTGSC_VBUS_DISCHARGE = TU_BIT(0), + OTGSC_VBUS_CHARGE = TU_BIT(1), +// OTGSC_HWASSIST_AUTORESET = TU_BIT(2), + OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode + OTGSC_DATA_PULSING = TU_BIT(4), + OTGSC_ID_PULLUP = TU_BIT(5), +// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6), +// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7), + OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device + OTGSC_A_VBUS_VALID = TU_BIT(9), + OTGSC_A_SESSION_VALID = TU_BIT(10), + OTGSC_B_SESSION_VALID = TU_BIT(11), + OTGSC_B_SESSION_END = TU_BIT(12), + OTGSC_1MS_TOGGLE = TU_BIT(13), + OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14), +}; + +// USBMode +enum { + USBMODE_CM_DEVICE = 2, + USBMODE_CM_HOST = 3, + + USBMODE_SLOM = TU_BIT(3), + USBMODE_SDIS = TU_BIT(4), + + USBMODE_VBUS_POWER_SELCT = TU_BIT(5), // Enable for LPC18XX/43XX in host most only +}; + +// Device Registers +typedef struct +{ + //------------- ID + HW Parameter Registers-------------// + __I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX + + //------------- Capability Registers-------------// + __I uint8_t CAPLENGTH; ///< Capability Registers Length + __I uint8_t TU_RESERVED[1]; + __I uint16_t HCIVERSION; ///< Host Controller Interface Version + + __I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters + __I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters + __I uint32_t TU_RESERVED[5]; + + __I uint16_t DCIVERSION; ///< Device Controller Interface Version + __I uint8_t TU_RESERVED[2]; + + __I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters + __I uint32_t TU_RESERVED[6]; + + //------------- Operational Registers -------------// + __IO uint32_t USBCMD; ///< USB Command Register + __IO uint32_t USBSTS; ///< USB Status Register + __IO uint32_t USBINTR; ///< Interrupt Enable Register + __IO uint32_t FRINDEX; ///< USB Frame Index + __I uint32_t TU_RESERVED; + __IO uint32_t DEVICEADDR; ///< Device Address + __IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address + __I uint32_t TU_RESERVED; + __IO uint32_t BURSTSIZE; ///< Programmable Burst Size + __IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning + uint32_t TU_RESERVED[4]; + __IO uint32_t ENDPTNAK; ///< Endpoint NAK + __IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable + __I uint32_t TU_RESERVED; + __IO uint32_t PORTSC1; ///< Port Status & Control + __I uint32_t TU_RESERVED[7]; + __IO uint32_t OTGSC; ///< On-The-Go Status & control + __IO uint32_t USBMODE; ///< USB Device Mode + __IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status + __IO uint32_t ENDPTPRIME; ///< Endpoint Prime + __IO uint32_t ENDPTFLUSH; ///< Endpoint Flush + __I uint32_t ENDPTSTAT; ///< Endpoint Status + __IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete + __IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7 +} dcd_registers_t; + + +// Queue Transfer Descriptor +typedef struct +{ + // Word 0: Next QTD Pointer + uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed + + // Word 1: qTQ Token + uint32_t : 3 ; + volatile uint32_t xact_err : 1 ; + uint32_t : 1 ; + volatile uint32_t buffer_err : 1 ; + volatile uint32_t halted : 1 ; + volatile uint32_t active : 1 ; + uint32_t : 2 ; + uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. + uint32_t : 3 ; + uint32_t int_on_complete : 1 ; + volatile uint32_t total_bytes : 15 ; + uint32_t : 0 ; + + // Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page + uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous + + //------------- DCD Area -------------// + uint16_t expected_bytes; + uint8_t reserved[2]; +} dcd_qtd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct"); + +// Queue Head +typedef struct +{ + // Word 0: Capabilities and Characteristics + uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. + uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. + uint32_t max_package_size : 11 ; ///< This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) + uint32_t : 2 ; + uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. + uint32_t iso_mult : 2 ; ///< + uint32_t : 0 ; + + // Word 1: Current qTD Pointer + volatile uint32_t qtd_addr; + + // Word 2-9: Transfer Overlay + volatile dcd_qtd_t qtd_overlay; + + // Word 10-11: Setup request (control OUT only) + volatile tusb_control_request_t setup_request; + + //--------------------------------------------------------------------+ + /// Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes + /// thus there are 16 bytes padding free that we can make use of. + //--------------------------------------------------------------------+ + uint8_t reserved[16]; +} dcd_qhd_t; + +TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct"); + +//--------------------------------------------------------------------+ +// Variables +//--------------------------------------------------------------------+ + +#define QHD_MAX 12 +#define QTD_NEXT_INVALID 0x01 + +typedef struct { + // Must be at 2K alignment + dcd_qhd_t qhd[QHD_MAX] TU_ATTR_ALIGNED(64); + dcd_qtd_t qtd[QHD_MAX] TU_ATTR_ALIGNED(32); +}dcd_data_t; + +static dcd_data_t _dcd_data CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048); +static dcd_registers_t* DCD_REGS[] = DCD_REGS_BASE; + +//--------------------------------------------------------------------+ +// CONTROLLER API +//--------------------------------------------------------------------+ + +/// follows LPC43xx User Manual 23.10.3 +static void bus_reset(uint8_t rhport) +{ + dcd_registers_t* dcd_reg = DCD_REGS[rhport]; + + // The reset value for all endpoint types is the control endpoint. If one endpoint + // direction is enabled and the paired endpoint of opposite direction is disabled, then the + // endpoint type of the unused direction must bechanged from the control type to any other + // type (e.g. bulk). Leaving an unconfigured endpoint control will cause undefined behavior + // for the data PID tracking on the active endpoint. + + // USB0 has 5 but USB1 only has 3 non-control endpoints + for( int i=1; i < (rhport ? 6 : 4); i++) + { + dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << 2) | (TUSB_XFER_BULK << 18); + } + + //------------- Clear All Registers -------------// + dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK; + dcd_reg->ENDPTNAKEN = 0; + dcd_reg->USBSTS = dcd_reg->USBSTS; + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT; + dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE; + + while (dcd_reg->ENDPTPRIME); + dcd_reg->ENDPTFLUSH = 0xFFFFFFFF; + while (dcd_reg->ENDPTFLUSH); + + // read reset bit in portsc + + //------------- Queue Head & Queue TD -------------// + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + //------------- Set up Control Endpoints (0 OUT, 1 IN) -------------// + _dcd_data.qhd[0].zero_length_termination = _dcd_data.qhd[1].zero_length_termination = 1; + _dcd_data.qhd[0].max_package_size = _dcd_data.qhd[1].max_package_size = CFG_TUD_ENDPOINT0_SIZE; + _dcd_data.qhd[0].qtd_overlay.next = _dcd_data.qhd[1].qtd_overlay.next = QTD_NEXT_INVALID; + + _dcd_data.qhd[0].int_on_setup = 1; // OUT only +} + +void dcd_init(uint8_t rhport) +{ + tu_memclr(&_dcd_data, sizeof(dcd_data_t)); + + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; + + // Reset controller + dcd_reg->USBCMD |= USBCMD_RESET; + while( dcd_reg->USBCMD & USBCMD_RESET ) {} + + // Set mode to device, must be set immediately after reset + dcd_reg->USBMODE = USBMODE_CM_DEVICE; + dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION; + + // TODO Force fullspeed on non-highspeed port + // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; + + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment + dcd_reg->USBSTS = dcd_reg->USBSTS; + 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) +{ + NVIC_EnableIRQ(DCD_IRQn[rhport]); +} + +void dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(DCD_IRQn[rhport]); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + // Response with status first before changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); + + DCD_REGS[rhport]->DEVICEADDR = (dev_addr << 25) | TU_BIT(24); +} + +void dcd_set_config(uint8_t rhport, uint8_t config_num) +{ + (void) rhport; + (void) config_num; + // nothing to do +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void) rhport; +} + +//--------------------------------------------------------------------+ +// HELPER +//--------------------------------------------------------------------+ +// index to bit position in register +static inline uint8_t ep_idx2bit(uint8_t ep_idx) +{ + return ep_idx/2 + ( (ep_idx%2) ? 16 : 0); +} + +static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) +{ + tu_memclr(p_qtd, sizeof(dcd_qtd_t)); + + p_qtd->next = QTD_NEXT_INVALID; + p_qtd->active = 1; + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + + if (data_ptr != NULL) + { + p_qtd->buffer[0] = (uint32_t) data_ptr; + for(uint8_t i=1; i<5; i++) + { + p_qtd->buffer[i] |= tu_align4k( p_qtd->buffer[i-1] ) + 4096; + } + } +} + +//--------------------------------------------------------------------+ +// DCD Endpoint Port +//--------------------------------------------------------------------+ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + // data toggle also need to be reset + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); + DCD_REGS[rhport]->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) +{ + // TODO not support ISO yet + TU_VERIFY ( p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); + + uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); + uint8_t const ep_idx = 2*epnum + dir; + + // USB0 has 5, USB1 has 3 non-control endpoints + TU_ASSERT( epnum <= (rhport ? 3 : 5) ); + + //------------- Prepare Queue Head -------------// + dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; + tu_memclr(p_qhd, sizeof(dcd_qhd_t)); + + p_qhd->zero_length_termination = 1; + p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size; + p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; + + // Enable EP Control + DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); + + return true; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_idx = 2*epnum + dir; + + if ( epnum == 0 ) + { + // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism + // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out + while(DCD_REGS[rhport]->ENDPTSETUPSTAT & TU_BIT(0)) {} + } + + dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; + dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; + + //------------- Prepare qtd -------------// + qtd_init(p_qtd, buffer, total_bytes); + p_qtd->int_on_complete = true; + p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd + + // start transfer + DCD_REGS[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; + + return true; +} + +//--------------------------------------------------------------------+ +// ISR +//--------------------------------------------------------------------+ +void dcd_isr(uint8_t rhport) +{ + dcd_registers_t* const dcd_reg = DCD_REGS[rhport]; + + uint32_t const int_enable = dcd_reg->USBINTR; + uint32_t const int_status = dcd_reg->USBSTS & int_enable; + dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt + + // disabled interrupt sources + if (int_status == 0) return; + + if (int_status & INTR_RESET) + { + bus_reset(rhport); + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + } + + if (int_status & INTR_SUSPEND) + { + if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) + { + // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. + if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + } + } + + // TODO disconnection does not generate interrupt !!!!!! +// if (int_status & INTR_PORT_CHANGE) +// { +// if ( !(dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) ) +// { +// dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED }; +// dcd_event_handler(&event, true); +// } +// } + + if (int_status & INTR_USB) + { + uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE; + dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge + + if (dcd_reg->ENDPTSETUPSTAT) + { + //------------- Set up Received -------------// + // 23.10.10.2 Operational model for setup transfers + dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;// acknowledge + + dcd_event_setup_received(rhport, (uint8_t*) &_dcd_data.qhd[0].setup_request, true); + } + + if ( edpt_complete ) + { + for(uint8_t ep_idx = 0; ep_idx < QHD_MAX; ep_idx++) + { + if ( tu_bit_test(edpt_complete, ep_idx2bit(ep_idx)) ) + { + // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set + dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; + + uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : + ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; + + uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 ); + dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd + } + } + } + } + + if (int_status & INTR_SOF) + { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + + if (int_status & INTR_NAK) {} + if (int_status & INTR_ERROR) TU_ASSERT(false, ); +} + +#endif -- cgit v1.3.1