From 6280e4e7cbad956aab1a2a519d93620c3990eedc Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 14 Sep 2019 18:01:52 -0400 Subject: msp430f5529: Add empty msp_exp430f5529lp BSP and DCD. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 116 ++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/portable/ti/msp430x5xx/dcd_msp430x5xx.c (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c new file mode 100644 index 000000000..4c8c370ce --- /dev/null +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -0,0 +1,116 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 William D. Jones + * 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_MSP430x5xx ) + +#include "device/dcd.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init (uint8_t rhport) +{ + (void) rhport; +} + +void dcd_int_enable (uint8_t rhport) +{ + (void) rhport; +} + +void dcd_int_disable (uint8_t rhport) +{ + (void) rhport; +} + +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) +{ + (void) rhport; + (void) dev_addr; +} + +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; +} + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + (void) rhport; + (void) desc_edpt; + + return false; +} + +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void) rhport; + (void) ep_addr; + (void) buffer; + (void) total_bytes; + + return false; +} + +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) +{ + (void) rhport; + (void) ep_addr; +} + +/*------------------------------------------------------------------*/ + +void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) +{ + +} + +#endif -- cgit v1.3.1 From 907bc3df9ba70c9a82ad2f98031879f17e2ad2b5 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 23 Sep 2019 17:48:18 -0400 Subject: msp430f5529: Ensure cdc_msc demo compiles. --- hw/bsp/msp_exp430f5529lp/board.mk | 3 ++- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 1 + src/tusb_option.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/hw/bsp/msp_exp430f5529lp/board.mk b/hw/bsp/msp_exp430f5529lp/board.mk index 741b3e00e..b47e764bd 100644 --- a/hw/bsp/msp_exp430f5529lp/board.mk +++ b/hw/bsp/msp_exp430f5529lp/board.mk @@ -1,6 +1,7 @@ CFLAGS += \ -D__MSP430F5529__ \ - -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx + -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ + -DCFG_EXAMPLE_MSC_READONLY # All source paths should be relative to the top level. LD_FILE = hw/bsp/msp_exp430f5529lp/msp430f5529.ld diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 4c8c370ce..b2df9e3b6 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -29,6 +29,7 @@ #if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MSP430x5xx ) +#include "msp430.h" #include "device/dcd.h" /*------------------------------------------------------------------*/ diff --git a/src/tusb_option.h b/src/tusb_option.h index eccb4245c..5de599951 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -60,6 +60,8 @@ #define OPT_MCU_STM32F7 305 ///< ST STM32F7 #define OPT_MCU_STM32H7 306 ///< ST STM32H7 +#define OPT_MCU_MSP430x5xx 400 ///< TI MSP430x5xx + /** @} */ -- cgit v1.3.1 From a6a79df9fb6864ad2d30dde85fd04c836f28f5d5 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 23 Sep 2019 18:53:31 -0400 Subject: msp430f5529: Enable clocks/PLL for msp_exp430f5529lp and enable USB module in dcd_msp430x5xx; device does not enumerate. --- hw/bsp/msp_exp430f5529lp/msp_exp430f5529lp.c | 33 +++++++++++++++++++++++++++- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 5 +++++ 2 files changed, 37 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/hw/bsp/msp_exp430f5529lp/msp_exp430f5529lp.c b/hw/bsp/msp_exp430f5529lp/msp_exp430f5529lp.c index 5fa69465d..29f88ccf5 100644 --- a/hw/bsp/msp_exp430f5529lp/msp_exp430f5529lp.c +++ b/hw/bsp/msp_exp430f5529lp/msp_exp430f5529lp.c @@ -36,6 +36,8 @@ #define BUTTON_PIN BIT1 #define BUTTON_STATE_ACTIVE 1 +uint32_t cnt = 0; + static void SystemClock_Config(void) { WDTCTL = WDTPW + WDTHOLD; // Disable watchdog. @@ -86,16 +88,45 @@ static void SystemClock_Config(void) TA0CCTL0 |= CCIE; TA0CCR0 = 999; // 1000 ticks. TA0CTL |= TASSEL_2 + ID_3 + MC__UP; // Use SMCLK, divide by 8, start timer. + + // Initialize USB power and PLL. + USBKEYPID = USBKEY; + + // VUSB enabled automatically. + // Wait two milliseconds to stabilize, per manual recommendation. + uint32_t ms_elapsed = board_millis(); + do + { + while((board_millis() - ms_elapsed) < 2); + }while(!(USBPWRCTL & USBBGVBV)); + + // USB uses XT2 (4 MHz) directly. Enable the PLL. + USBPLLDIVB |= USBPLL_SETCLK_4_0; + USBPLLCTL |= (UPFDEN | UPLLEN); + + // Wait until PLL locks. Check every 2ms, per manual. + ms_elapsed = board_millis(); + do + { + USBPLLIR &= ~USBOOLIFG; + while((board_millis() - ms_elapsed) < 2); + }while(USBPLLIR & USBOOLIFG); + + USBKEYPID = 0; } void board_init(void) { - SystemClock_Config(); __bis_SR_register(GIE); // Enable interrupts. + SystemClock_Config(); P1DIR |= LED_PIN; // LED output. P1REN |= BUTTON_PIN; // Internal resistor enable. P1OUT |= BUTTON_PIN; // Pullup. + + USBKEYPID = USBKEY; + USBPHYCTL |= PUSEL; // Convert USB D+/D- pins to USB functionality. + USBKEYPID = 0; } //--------------------------------------------------------------------+ diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index b2df9e3b6..e9ca76853 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -43,6 +43,11 @@ void dcd_init (uint8_t rhport) { (void) rhport; + + // Enable the module! + USBKEYPID = USBKEY; + USBCNF |= (PUR_EN | USB_EN); + USBKEYPID = 0; } void dcd_int_enable (uint8_t rhport) -- cgit v1.3.1 From 950614a841a69f09ffd8b97205183e1c85b09443 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Mon, 23 Sep 2019 22:58:49 -0400 Subject: msp430f5529: Implement dcd_int_enable/disable. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index e9ca76853..e01c0243f 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -35,6 +35,11 @@ /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ +// usbpllir_mirror and usbmaintl_mirror can be added later if needed. +static volatile uint16_t usbiepie_mirror = 0; +static volatile uint16_t usboepie_mirror = 0; +static volatile uint16_t usbie_mirror = 0; +static volatile uint16_t usbpwrctl_mirror = 0; /*------------------------------------------------------------------*/ @@ -50,14 +55,40 @@ void dcd_init (uint8_t rhport) USBKEYPID = 0; } +// There is no "USB peripheral interrupt disable" bit on MSP430, so we have +// to save the relevant registers individually. +// WARNING: Unlike the ARM/NVIC routines, these functions are _not_ idempotent +// if you modified the registers saved in between calls so they don't match +// the mirrors; mirrors will be updated to reflect most recent register +// contents. void dcd_int_enable (uint8_t rhport) { (void) rhport; + + __bic_SR_register(GIE); // Unlikely to be called in ISR, but let's be safe. + // Also, this cleanly disables all USB interrupts + // atomically from application's POV. + USBOEPIE = usboepie_mirror; + USBIEPIE = usbiepie_mirror; + USBIE = usbie_mirror; + USBPWRCTL |= usbpwrctl_mirror; + __bis_SR_register(GIE); } void dcd_int_disable (uint8_t rhport) { (void) rhport; + + __bic_SR_register(GIE); + usboepie_mirror = USBOEPIE; + usbiepie_mirror = USBIEPIE; + usbie_mirror = USBIE; + usbpwrctl_mirror = (USBPWRCTL & (VUOVLIE | VBONIE | VBOFFIE)); + USBOEPIE = 0; + USBIEPIE = 0; + USBIE = 0; + USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE); + __bis_SR_register(GIE); } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -- cgit v1.3.1 From d2e4af5a7b42ab54510bc8507ca28aed3604d9d1 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 24 Sep 2019 02:41:11 -0400 Subject: msp430f5529: Change EP0 size to 8, implement interrupt logic up to bus reset detection. --- hw/bsp/msp_exp430f5529lp/board.mk | 3 +- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 79 ++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/hw/bsp/msp_exp430f5529lp/board.mk b/hw/bsp/msp_exp430f5529lp/board.mk index b47e764bd..1ae7330c9 100644 --- a/hw/bsp/msp_exp430f5529lp/board.mk +++ b/hw/bsp/msp_exp430f5529lp/board.mk @@ -1,7 +1,8 @@ CFLAGS += \ -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ - -DCFG_EXAMPLE_MSC_READONLY + -DCFG_EXAMPLE_MSC_READONLY \ + -DCFG_TUD_ENDOINT0_SIZE=8 # All source paths should be relative to the top level. LD_FILE = hw/bsp/msp_exp430f5529lp/msp430f5529.ld diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index e01c0243f..9ff63f839 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -38,8 +38,16 @@ // usbpllir_mirror and usbmaintl_mirror can be added later if needed. static volatile uint16_t usbiepie_mirror = 0; static volatile uint16_t usboepie_mirror = 0; -static volatile uint16_t usbie_mirror = 0; +static volatile uint8_t usbie_mirror = 0; static volatile uint16_t usbpwrctl_mirror = 0; +static bool in_isr = false; + +uint8_t _setup_packet[8]; + +static void bus_reset(void) +{ + +} /*------------------------------------------------------------------*/ @@ -49,9 +57,27 @@ void dcd_init (uint8_t rhport) { (void) rhport; - // Enable the module! USBKEYPID = USBKEY; - USBCNF |= (PUR_EN | USB_EN); + + // Enable the module (required to write config regs)! + USBCNF |= USB_EN; + + // Reset used interrupts + USBOEPIE = 0; + USBIEPIE = 0; + USBIE = 0; + USBOEPIFG = 0; + USBIEPIFG = 0; + USBIFG = 0; + USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE | VUOVLIFG | VBONIFG | VBOFFIFG); + USBVECINT = 0; + + // Enable reset and wait for it before continuing. + USBIE |= RSTRIE; + + // Enable pullup. + USBCNF |= PUR_EN; + USBKEYPID = 0; } @@ -68,10 +94,18 @@ void dcd_int_enable (uint8_t rhport) __bic_SR_register(GIE); // Unlikely to be called in ISR, but let's be safe. // Also, this cleanly disables all USB interrupts // atomically from application's POV. - USBOEPIE = usboepie_mirror; - USBIEPIE = usbiepie_mirror; - USBIE = usbie_mirror; - USBPWRCTL |= usbpwrctl_mirror; + + // This guard is required because tinyusb can enable interrupts without + // having disabled them first. + if(in_isr) + { + USBOEPIE = usboepie_mirror; + USBIEPIE = usbiepie_mirror; + USBIE = usbie_mirror; + USBPWRCTL |= usbpwrctl_mirror; + } + + in_isr = false; __bis_SR_register(GIE); } @@ -88,6 +122,7 @@ void dcd_int_disable (uint8_t rhport) USBIEPIE = 0; USBIE = 0; USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE); + in_isr = true; __bis_SR_register(GIE); } @@ -145,8 +180,38 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ +static void handle_setup_packet(void) +{ + +} + void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) { + // Setup is special- reading USBVECINT to handle setup packets is done to + // stop NAKs on EP0. + uint8_t setup_status = USBIFG & SETUPIFG; + + if(setup_status) + { + handle_setup_packet(); + } + + uint16_t curr_vector = USBVECINT; + + switch(curr_vector) + { + case USBVECINT_RSTR: + bus_reset(); + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + break; + + // Clear the NAK on EP 0 after a SETUP packet is received. + case USBVECINT_SETUP_PACKET_RECEIVED: + break; + + default: + break; + } } -- cgit v1.3.1 From 550e8215f3ee60c13548e623925ca870023b20e4 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 24 Sep 2019 03:43:51 -0400 Subject: dcd_msp430x5xx: Setup packets are now received successfully (with delay). --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 41 ++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 9ff63f839..4b35cd984 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -35,6 +35,8 @@ /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ +#define USB_BUF_PTR(_x) (uint8_t *) ((uint16_t) _x) + // usbpllir_mirror and usbmaintl_mirror can be added later if needed. static volatile uint16_t usbiepie_mirror = 0; static volatile uint16_t usboepie_mirror = 0; @@ -46,7 +48,19 @@ uint8_t _setup_packet[8]; static void bus_reset(void) { - + // Enable the control EP 0. Also enable Indication Enable- a guard flag + // separate from the Interrupt Enable mask. + USBOEPCNF_0 |= (UBME | USBIIE); + USBIEPCNF_0 |= (UBME | USBIIE); + + // Enable interrupts for this endpoint. + USBOEPIE |= BIT0; + USBIEPIE |= BIT0; + + // Clear NAK so packets can be received. + // Dedicated buffers in hardware for SETUP and EP0, no setup needed. + USBOEPCNT_0 &= ~NAK; + USBIEPCNT_0 &= ~NAK; } @@ -180,9 +194,26 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ +static void receive_packet(void) +{ + +} + +static void transmit_packet(void) +{ + +} + static void handle_setup_packet(void) { + volatile uint8_t * setup_buf = &USBSUBLK; + + for(int i = 0; i < 8; i++) + { + _setup_packet[i] = setup_buf[i]; + } + dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) @@ -209,6 +240,14 @@ void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) case USBVECINT_SETUP_PACKET_RECEIVED: break; + case USBVECINT_INPUT_ENDPOINT0: + transmit_packet(); + break; + + case USBVECINT_OUTPUT_ENDPOINT0: + receive_packet(); + break; + default: break; } -- cgit v1.3.1 From 01b4115b0b26a9fb5c706daf320c85556d16f920 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 24 Sep 2019 04:06:34 -0400 Subject: dcd_msp430x5xx: Fix Setup packet delay by actually enabling corresponding interrupt. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 4b35cd984..fe78218df 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -61,6 +61,9 @@ static void bus_reset(void) // Dedicated buffers in hardware for SETUP and EP0, no setup needed. USBOEPCNT_0 &= ~NAK; USBIEPCNT_0 &= ~NAK; + + // Now safe to respond to SETUP packets. + USBIE |= SETUPIE; } -- cgit v1.3.1 From c4483d244b04a6679d85376e3e686c23b9ee82af Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 27 Sep 2019 12:41:46 -0400 Subject: Fix typo of CFG_TUD_ENDOINT0_SIZE. --- examples/device/board_test/src/tusb_config.h | 2 +- examples/device/cdc_msc/src/tusb_config.h | 4 ++-- examples/device/cdc_msc/src/usb_descriptors.c | 2 +- examples/device/cdc_msc_hid_freertos/src/tusb_config.h | 4 ++-- examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c | 2 +- examples/device/hid_composite/src/tusb_config.h | 4 ++-- examples/device/hid_composite/src/usb_descriptors.c | 2 +- examples/device/hid_generic_inout/src/tusb_config.h | 4 ++-- examples/device/hid_generic_inout/src/usb_descriptors.c | 2 +- examples/device/midi_test/src/tusb_config.h | 4 ++-- examples/device/midi_test/src/usb_descriptors.c | 2 +- examples/device/msc_dual_lun/src/tusb_config.h | 4 ++-- examples/device/msc_dual_lun/src/usb_descriptors.c | 2 +- examples/device/webusb_serial/src/tusb_config.h | 4 ++-- examples/device/webusb_serial/src/usb_descriptors.c | 2 +- hw/bsp/msp_exp430f5529lp/board.mk | 2 +- src/device/usbd_control.c | 2 +- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 4 ++-- src/portable/nxp/lpc18_43/dcd_lpc18_43.c | 2 +- 19 files changed, 27 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h index 5c3cac83a..2f2a4deeb 100644 --- a/examples/device/board_test/src/tusb_config.h +++ b/examples/device/board_test/src/tusb_config.h @@ -64,7 +64,7 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUD_ENDOINT0_SIZE 64 +#define CFG_TUD_ENDPOINT0_SIZE 64 //------------- CLASS -------------// #define CFG_TUD_CDC 0 diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index e307870ed..4455f665e 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -68,8 +68,8 @@ //-------------------------------------------------------------------- // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index ac8214e37..11d07e9ba 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -50,7 +50,7 @@ tusb_desc_device_t const desc_device = .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h index 7869e24cc..f84874ab1 100644 --- a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h @@ -69,8 +69,8 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c index 5d93cc2f6..d60c9a585 100644 --- a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c @@ -57,7 +57,7 @@ tusb_desc_device_t const desc_device = .bDeviceProtocol = 0x00, #endif - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 13ecfa415..8d29f10be 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -69,8 +69,8 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/hid_composite/src/usb_descriptors.c b/examples/device/hid_composite/src/usb_descriptors.c index 678b7528b..01f2cb59b 100644 --- a/examples/device/hid_composite/src/usb_descriptors.c +++ b/examples/device/hid_composite/src/usb_descriptors.c @@ -47,7 +47,7 @@ tusb_desc_device_t const desc_device = .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h index c82588c2f..a7ce7acf8 100644 --- a/examples/device/hid_generic_inout/src/tusb_config.h +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -69,8 +69,8 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index d0fc6b1bc..07989c5fd 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -46,7 +46,7 @@ tusb_desc_device_t const desc_device = .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/examples/device/midi_test/src/tusb_config.h b/examples/device/midi_test/src/tusb_config.h index 4a84812c5..fcd6b97c2 100644 --- a/examples/device/midi_test/src/tusb_config.h +++ b/examples/device/midi_test/src/tusb_config.h @@ -69,8 +69,8 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 7cebc6a15..2305c9f68 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -46,7 +46,7 @@ tusb_desc_device_t const desc_device = .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index 073e2379f..b45e9c4dc 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -69,8 +69,8 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index cab37cf1f..e0a5904a4 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -46,7 +46,7 @@ tusb_desc_device_t const desc_device = .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index b2f09cac0..8a73e8353 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -69,8 +69,8 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- -#ifndef CFG_TUD_ENDOINT0_SIZE -#define CFG_TUD_ENDOINT0_SIZE 64 +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 #endif //------------- CLASS -------------// diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index a1d5cd9b9..740defe4e 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -50,7 +50,7 @@ tusb_desc_device_t const desc_device = .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0xCafe, .idProduct = USB_PID, diff --git a/hw/bsp/msp_exp430f5529lp/board.mk b/hw/bsp/msp_exp430f5529lp/board.mk index 1ae7330c9..2e6e77f18 100644 --- a/hw/bsp/msp_exp430f5529lp/board.mk +++ b/hw/bsp/msp_exp430f5529lp/board.mk @@ -2,7 +2,7 @@ CFLAGS += \ -D__MSP430F5529__ \ -DCFG_TUSB_MCU=OPT_MCU_MSP430x5xx \ -DCFG_EXAMPLE_MSC_READONLY \ - -DCFG_TUD_ENDOINT0_SIZE=8 + -DCFG_TUD_ENDPOINT0_SIZE=8 # All source paths should be relative to the top level. LD_FILE = hw/bsp/msp_exp430f5529lp/msp430f5529.ld diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 4ec432185..eed933f68 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -124,7 +124,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result _control_state.total_transferred += xferred_bytes; _control_state.buffer += xferred_bytes; - if ( _control_state.total_len == _control_state.total_transferred || xferred_bytes < CFG_TUD_ENDOINT0_SIZE ) + if ( _control_state.total_len == _control_state.total_transferred || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) { // DATA stage is complete bool is_ok = true; diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 2b49f52e9..97809e758 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -172,8 +172,8 @@ void dcd_init(uint8_t rhport) //------------- user manual 11.13 usb device controller initialization -------------// // step 6 : set up control endpoint - set_ep_size(0, CFG_TUD_ENDOINT0_SIZE); - set_ep_size(1, CFG_TUD_ENDOINT0_SIZE); + set_ep_size(0, CFG_TUD_ENDPOINT0_SIZE); + set_ep_size(1, CFG_TUD_ENDPOINT0_SIZE); bus_reset(); diff --git a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c index 519e0dcc6..3619a7c2b 100644 --- a/src/portable/nxp/lpc18_43/dcd_lpc18_43.c +++ b/src/portable/nxp/lpc18_43/dcd_lpc18_43.c @@ -115,7 +115,7 @@ static void bus_reset(uint8_t rhport) //------------- 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_ENDOINT0_SIZE; + 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; p_dcd->qhd[0].int_on_setup = 1; // OUT only -- cgit v1.3.1 From 3ac43076da7acf8e8e83086bf895e0b2c5f8105e Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 27 Sep 2019 21:20:33 -0400 Subject: dcd_msp430x5xx: Implement EP0 IN xfers, clean up. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 105 ++++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index fe78218df..c52cf5505 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -35,8 +35,6 @@ /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ -#define USB_BUF_PTR(_x) (uint8_t *) ((uint16_t) _x) - // usbpllir_mirror and usbmaintl_mirror can be added later if needed. static volatile uint16_t usbiepie_mirror = 0; static volatile uint16_t usboepie_mirror = 0; @@ -46,8 +44,26 @@ static bool in_isr = false; uint8_t _setup_packet[8]; +typedef struct { + uint8_t * buffer; + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool short_packet; +} xfer_ctl_t; + +xfer_ctl_t xfer_status[8][2]; +#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] + + static void bus_reset(void) { + // Hardcoded into the USB core. + xfer_status[0][TUSB_DIR_OUT].max_size = 8; + xfer_status[0][TUSB_DIR_IN].max_size = 8; + + USBKEYPID = USBKEY; + // Enable the control EP 0. Also enable Indication Enable- a guard flag // separate from the Interrupt Enable mask. USBOEPCNF_0 |= (UBME | USBIIE); @@ -57,13 +73,17 @@ static void bus_reset(void) USBOEPIE |= BIT0; USBIEPIE |= BIT0; - // Clear NAK so packets can be received. - // Dedicated buffers in hardware for SETUP and EP0, no setup needed. - USBOEPCNT_0 &= ~NAK; - USBIEPCNT_0 &= ~NAK; + // Set NAK until a setup packet is received. + USBOEPCNT_0 |= NAK; + USBIEPCNT_0 |= NAK; + + USBCTL |= FEN; // Enable responding to packets. + // Dedicated buffers in hardware for SETUP and EP0, no setup needed. // Now safe to respond to SETUP packets. USBIE |= SETUPIE; + + USBKEYPID = 0; } @@ -87,6 +107,11 @@ void dcd_init (uint8_t rhport) USBIEPIFG = 0; USBIFG = 0; USBPWRCTL &= ~(VUOVLIE | VBONIE | VBOFFIE | VUOVLIFG | VBONIFG | VBOFFIFG); + usboepie_mirror = 0; + usbiepie_mirror = 0; + usbie_mirror = 0; + usbpwrctl_mirror = 0; + USBVECINT = 0; // Enable reset and wait for it before continuing. @@ -173,14 +198,40 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return false; } +static volatile uint8_t iepcnt = 0xFF; + bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { (void) rhport; - (void) ep_addr; - (void) buffer; - (void) total_bytes; - return false; + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->short_packet = false; + + if(epnum == 0) + { + if(dir == TUSB_DIR_OUT) + { + // Interrupt will notify us when data was received. + USBCTL &= ~DIR; + USBOEPCNT_0 &= ~NAK; + } + else + { + // Kickstart the IN packet handler by queuing initial data and calling + // the ISR to transmit the first packet. + // Interrupt only fires on completed xfer. + USBCTL |= DIR; + USBIEPIFG |= BIT0; + } + } + + return true; } void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) @@ -197,14 +248,39 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ -static void receive_packet(void) +static void receive_packet(uint8_t ep_num) { + (void) ep_num; } -static void transmit_packet(void) +static void transmit_packet(uint8_t ep_num) { + xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_IN); + if(ep_num == 0) + { + if(xfer->total_len == xfer->queued_len) + { + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + return; + } + + uint8_t * base = (xfer->buffer + xfer->queued_len); + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; + + xfer->queued_len += xfer_size; + + volatile uint8_t * ep0in_buf = &USBIEP0BUF; + for(int i = 0; i < xfer_size; i++) + { + ep0in_buf[i] = base[i]; + } + + USBIEPCNT_0 = (USBIEPCNT_0 & 0xF0) + xfer_size; + USBIEPCNT_0 &= ~NAK; + } } static void handle_setup_packet(void) @@ -244,14 +320,15 @@ void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) break; case USBVECINT_INPUT_ENDPOINT0: - transmit_packet(); + transmit_packet(0); break; case USBVECINT_OUTPUT_ENDPOINT0: - receive_packet(); + receive_packet(0); break; default: + while(true); break; } -- cgit v1.3.1 From 030560792d1d2d6a2d4febf1c54f9735cddc7aca Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Fri, 27 Sep 2019 21:59:45 -0400 Subject: dcd_msp430x5xx: Implement dcd_set_address. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index c52cf5505..66b7ab293 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -50,6 +50,7 @@ typedef struct { uint16_t queued_len; uint16_t max_size; bool short_packet; + bool zlp_sent; } xfer_ctl_t; xfer_ctl_t xfer_status[8][2]; @@ -171,7 +172,11 @@ void dcd_int_disable (uint8_t rhport) void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { (void) rhport; - (void) dev_addr; + + USBFUNADR = dev_addr; + + // Response with status after changing device address + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); } void dcd_set_config (uint8_t rhport, uint8_t config_num) @@ -212,6 +217,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->short_packet = false; + xfer->zlp_sent = false; if(epnum == 0) { @@ -260,7 +266,8 @@ static void transmit_packet(uint8_t ep_num) if(ep_num == 0) { - if(xfer->total_len == xfer->queued_len) + bool zlp = (xfer->total_len == 0); + if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->zlp_sent) { dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); return; @@ -271,6 +278,10 @@ static void transmit_packet(uint8_t ep_num) uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; xfer->queued_len += xfer_size; + if(xfer->total_len == 0) + { + xfer->zlp_sent = true; + } volatile uint8_t * ep0in_buf = &USBIEP0BUF; for(int i = 0; i < xfer_size; i++) -- cgit v1.3.1 From 63c94ff684372e804011ef9f2b283f2340bb67fd Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 28 Sep 2019 01:51:05 -0400 Subject: dcd_msp430x5xx: Improve EP0 IN handling (reuse short_packet field). --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 66b7ab293..62aaee3cb 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -50,7 +50,6 @@ typedef struct { uint16_t queued_len; uint16_t max_size; bool short_packet; - bool zlp_sent; } xfer_ctl_t; xfer_ctl_t xfer_status[8][2]; @@ -203,8 +202,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return false; } -static volatile uint8_t iepcnt = 0xFF; - bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { (void) rhport; @@ -217,7 +214,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer->total_len = total_bytes; xfer->queued_len = 0; xfer->short_packet = false; - xfer->zlp_sent = false; if(epnum == 0) { @@ -266,21 +262,27 @@ static void transmit_packet(uint8_t ep_num) if(ep_num == 0) { - bool zlp = (xfer->total_len == 0); - if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->zlp_sent) + // First, determine whether we should even send a packet or finish + // up the xfer. + bool zlp = (xfer->total_len == 0); // By necessity, xfer->total_len will + // equal xfer->queued_len for ZLPs. + // Of course a ZLP is a short packet. + if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->short_packet) { dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); return; } + // Then actually commit to transmit a packet. uint8_t * base = (xfer->buffer + xfer->queued_len); uint16_t remaining = xfer->total_len - xfer->queued_len; uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; xfer->queued_len += xfer_size; - if(xfer->total_len == 0) + if(xfer_size < xfer->max_size) { - xfer->zlp_sent = true; + // Next "xfer complete interrupt", the transfer will end. + xfer->short_packet = true; } volatile uint8_t * ep0in_buf = &USBIEP0BUF; -- cgit v1.3.1 From 5d9f83391544261117fffa2dec218b80ccd1d01c Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 28 Sep 2019 02:09:03 -0400 Subject: dcd_msp430x5xx: Implement STALL logic for EP 0. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 34 +++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 62aaee3cb..7a4599c26 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -239,13 +239,43 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if(epnum == 0) + { + if(dir == TUSB_DIR_OUT) + { + USBOEPCNT_0 |= NAK; + USBOEPCNF_0 |= STALL; + } + else + { + USBIEPCNT_0 |= NAK; + USBIEPCNF_0 |= STALL; + } + } } void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; + + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + if(epnum == 0) + { + if(dir == TUSB_DIR_OUT) + { + USBOEPCNT_0 &= ~NAK; + } + else + { + USBIEPCNT_0 &= ~NAK; + } + } } /*------------------------------------------------------------------*/ -- cgit v1.3.1 From 529efcc0d2b60cceac14ca01a1f6e5fecab4d8aa Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 29 Sep 2019 00:21:40 -0400 Subject: dcd_msp430x5xx: Implement dcd_edpt_open. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 74 +++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 7a4599c26..aac4f01db 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -44,7 +44,9 @@ static bool in_isr = false; uint8_t _setup_packet[8]; -typedef struct { +// Xfer control +typedef struct +{ uint8_t * buffer; uint16_t total_len; uint16_t queued_len; @@ -55,6 +57,21 @@ typedef struct { xfer_ctl_t xfer_status[8][2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] +// Accessing endpoint regs +typedef volatile uint8_t * ep_regs_t; + +typedef enum +{ + CNF = 0, + BBAX = 1, + BCTX = 2, + BBAY = 5, + BCTY = 6, + SIZXY = 7 +} ep_regs_index_t; + +#define EP_REGS(epnum, dir) &USBOEPCNF_1 + 64*dir + 8*(epnum - 1) + static void bus_reset(void) { @@ -197,9 +214,60 @@ void dcd_remote_wakeup(uint8_t rhport) bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { (void) rhport; - (void) desc_edpt; - return false; + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + // Unsupported endpoint numbers/size or type (Iso not supported. Control + // not supported on nonzero endpoints). + if((desc_edpt->wMaxPacketSize.size > 64) || (epnum > 7) || \ + (desc_edpt->bmAttributes.xfer == 0) || \ + (desc_edpt->bmAttributes.xfer == 1)) { + return false; + } + + // Buffer allocation scheme: + // For simplicity, only single buffer for now, since tinyusb currently waits + // for an xfer to complete before scheduling another one. This means only + // the X buffer is used. + // + // 1904 bytes are available, the max endpoint size supported on msp430 is + // 64 bytes. This is enough RAM for all 14 endpoints enabled _with_ double + // bufferring (64*14*2 = 1792 bytes). Extra RAM exists for triple and higher + // order bufferring, which must be maintained in software. + // + // For simplicity, each endpoint gets a hardcoded 64 byte chunk (regardless + // of actual wMaxPacketSize) whose start address is the following: + // addr = 128 * (epnum - 1) + 64 * dir. + // + // Double buffering equation: + // x_addr = 256 * (epnum - 1) + 128 * dir + // y_addr = x_addr + 64 + + ep_regs_t ep_regs = EP_REGS(epnum, dir); + uint8_t buf_base = (128 * (epnum - 1) + 64 * dir) >> 3; + + // IN and OUT EP registers have the same structure. + + ep_regs[SIZXY] = desc_edpt->wMaxPacketSize.size; + ep_regs[BCTX] |= NAK; + ep_regs[BBAX] = buf_base; + ep_regs[CNF] &= ~TOGGLE; // ISO xfers not supported on MSP430, so no need + // to gate DATA0/1 and frame behavior. + ep_regs[CNF] |= (UBME | USBIIE); + + USBKEYPID = USBKEY; + if(dir == TUSB_DIR_OUT) + { + USBOEPIE |= (1 << epnum); + } + else + { + USBIEPIE |= (1 << epnum); + } + USBKEYPID = 0; + + return true; } bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -- cgit v1.3.1 From ea0e799df6594fa6644575493547f41994c9be27 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 29 Sep 2019 02:17:59 -0400 Subject: dcd_msp430x5xx: Fix clear stall logic. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index aac4f01db..edb707963 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -337,11 +337,11 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { if(dir == TUSB_DIR_OUT) { - USBOEPCNT_0 &= ~NAK; + USBOEPCNT_0 &= ~STALL; } else { - USBIEPCNT_0 &= ~NAK; + USBIEPCNT_0 &= ~STALL; } } } -- cgit v1.3.1 From 2247f132ca00667253630f833459f0129eb75f11 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 29 Sep 2019 02:22:09 -0400 Subject: Implement dcd_edpt_xfer for nonzero endpoints. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 56 +++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index edb707963..3950a6204 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -226,6 +226,9 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return false; } + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->max_size = desc_edpt->wMaxPacketSize.size; + // Buffer allocation scheme: // For simplicity, only single buffer for now, since tinyusb currently waits // for an xfer to complete before scheduling another one. This means only @@ -243,17 +246,23 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Double buffering equation: // x_addr = 256 * (epnum - 1) + 128 * dir // y_addr = x_addr + 64 + // Address is right-shifted by 3 to fit into 8 bits. - ep_regs_t ep_regs = EP_REGS(epnum, dir); uint8_t buf_base = (128 * (epnum - 1) + 64 * dir) >> 3; // IN and OUT EP registers have the same structure. + ep_regs_t ep_regs = EP_REGS(epnum, dir); + // FIXME: I was able to get into a situation where OUT EP 3 would stall + // while debugging, despite stall code never being called. It appears + // these registers don't get cleared on reset, being part of RAM. + // Investigate and see if I can duplicate. ep_regs[SIZXY] = desc_edpt->wMaxPacketSize.size; ep_regs[BCTX] |= NAK; ep_regs[BBAX] = buf_base; - ep_regs[CNF] &= ~TOGGLE; // ISO xfers not supported on MSP430, so no need - // to gate DATA0/1 and frame behavior. + ep_regs[CNF] &= ~TOGGLE; // ISO xfers not supported on MSP430, + // so no need to gate DATA0/1 and frame + // behavior. ep_regs[CNF] |= (UBME | USBIIE); USBKEYPID = USBKEY; @@ -300,6 +309,21 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t USBIEPIFG |= BIT0; } } + else + { + ep_regs_t ep_regs = EP_REGS(epnum, dir); + + ep_regs[CNF] &= ~TOGGLE; // Bulk and int begin on DATA0. + + if(dir == TUSB_DIR_OUT) + { + ep_regs[BCTX] &= ~NAK; + } + else + { + USBIEPIFG |= (1 << epnum); + } + } return true; } @@ -438,6 +462,32 @@ void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) receive_packet(0); break; + case USBVECINT_INPUT_ENDPOINT1: + case USBVECINT_INPUT_ENDPOINT2: + case USBVECINT_INPUT_ENDPOINT3: + case USBVECINT_INPUT_ENDPOINT4: + case USBVECINT_INPUT_ENDPOINT5: + case USBVECINT_INPUT_ENDPOINT6: + case USBVECINT_INPUT_ENDPOINT7: + { + uint8_t ep = ((curr_vector - USBVECINT_INPUT_ENDPOINT1) >> 1) + 1; + transmit_packet(ep); + } + break; + + case USBVECINT_OUTPUT_ENDPOINT1: + case USBVECINT_OUTPUT_ENDPOINT2: + case USBVECINT_OUTPUT_ENDPOINT3: + case USBVECINT_OUTPUT_ENDPOINT4: + case USBVECINT_OUTPUT_ENDPOINT5: + case USBVECINT_OUTPUT_ENDPOINT6: + case USBVECINT_OUTPUT_ENDPOINT7: + { + uint8_t ep = ((curr_vector - USBVECINT_OUTPUT_ENDPOINT1) >> 1) + 1; + receive_packet(ep); + } + break; + default: while(true); break; -- cgit v1.3.1 From 838b431faca79e0bd9d627a79b6905010769551c Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 29 Sep 2019 02:43:05 -0400 Subject: dcd_msp430x5xx: Implement transmit_packet for nonzero endpoints. Untested. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 56 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 3950a6204..da68074e7 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -382,31 +382,31 @@ static void transmit_packet(uint8_t ep_num) { xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_IN); - if(ep_num == 0) + // First, determine whether we should even send a packet or finish + // up the xfer. + bool zlp = (xfer->total_len == 0); // By necessity, xfer->total_len will + // equal xfer->queued_len for ZLPs. + // Of course a ZLP is a short packet. + if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->short_packet) { - // First, determine whether we should even send a packet or finish - // up the xfer. - bool zlp = (xfer->total_len == 0); // By necessity, xfer->total_len will - // equal xfer->queued_len for ZLPs. - // Of course a ZLP is a short packet. - if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->short_packet) - { - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); - return; - } + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + return; + } - // Then actually commit to transmit a packet. - uint8_t * base = (xfer->buffer + xfer->queued_len); - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; + // Then actually commit to transmit a packet. + uint8_t * base = (xfer->buffer + xfer->queued_len); + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint8_t xfer_size = (xfer->max_size < xfer->total_len) ? xfer->max_size : remaining; - xfer->queued_len += xfer_size; - if(xfer_size < xfer->max_size) - { - // Next "xfer complete interrupt", the transfer will end. - xfer->short_packet = true; - } + xfer->queued_len += xfer_size; + if(xfer_size < xfer->max_size) + { + // Next "xfer complete interrupt", the transfer will end. + xfer->short_packet = true; + } + if(ep_num == 0) + { volatile uint8_t * ep0in_buf = &USBIEP0BUF; for(int i = 0; i < xfer_size; i++) { @@ -416,6 +416,20 @@ static void transmit_packet(uint8_t ep_num) USBIEPCNT_0 = (USBIEPCNT_0 & 0xF0) + xfer_size; USBIEPCNT_0 &= ~NAK; } + else + { + ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_IN); + uint16_t in_buf_base = USBSTABUFF + (ep_regs[BBAX] << 3); + + volatile uint8_t * ep_buf = (volatile uint8_t *) (in_buf_base); + for(int i = 0; i < xfer_size; i++) + { + ep_buf[i] = base[i]; + } + + ep_regs[BCTX] = (ep_regs[BCTX] & 0xF0) + xfer_size; + ep_regs[BCTX] &= ~NAK; + } } static void handle_setup_packet(void) -- cgit v1.3.1 From 549ad1d9b6a0a5b05e3017c2ed0e46ab65137760 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 29 Sep 2019 03:02:59 -0400 Subject: dcd_msp430x5xx: Fix missing mask when posting IN xfer events. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index da68074e7..e53a4b7cd 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -389,7 +389,7 @@ static void transmit_packet(uint8_t ep_num) // Of course a ZLP is a short packet. if((!zlp && (xfer->total_len == xfer->queued_len)) || xfer->short_packet) { - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(0, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len, XFER_RESULT_SUCCESS, true); return; } -- cgit v1.3.1 From b623e3023e7aaa8c9541f7d17a0c458667861cd4 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sun, 29 Sep 2019 03:58:30 -0400 Subject: dcd_msp430x5xx: Implement receive_packet for all endpoints, correct some mistakes in transmit_packet. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 68 +++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index e53a4b7cd..5e9fbf0f1 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -374,8 +374,69 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) static void receive_packet(uint8_t ep_num) { - (void) ep_num; + xfer_ctl_t * xfer = XFER_CTL_BASE(ep_num, TUSB_DIR_OUT); + ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_OUT); + uint8_t xfer_size; + if(ep_num == 0) + { + xfer_size = USBOEPCNT_0 & 0x0F; + } + else + { + xfer_size = ep_regs[BCTX] & 0x3F; + } + + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t to_recv_size; + + if(remaining <= xfer->max_size) { + // Avoid buffer overflow. + to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; + } else { + // Room for full packet, choose recv_size based on what the microcontroller + // claims. + to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; + } + + uint8_t * base = (xfer->buffer + xfer->queued_len); + + if(ep_num == 0) + { + volatile uint8_t * ep0out_buf = &USBOEP0BUF; + for(uint16_t i = 0; i < to_recv_size; i++) + { + base[i] = ep0out_buf[i]; + } + } + else + { + volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3); + for(uint16_t i = 0; i < to_recv_size ; i++) + { + base[i] = ep_buf[i]; + } + } + + xfer->queued_len += xfer_size; + + xfer->short_packet = (xfer_size < xfer->max_size); + if((xfer->total_len == xfer->queued_len) || xfer->short_packet) + { + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } + else + { + // Schedule to receive another packet. + if(ep_num == 0) + { + USBOEPCNT_0 &= ~NAK; + } + else + { + ep_regs[BCTX] &= ~NAK; + } + } } static void transmit_packet(uint8_t ep_num) @@ -408,7 +469,7 @@ static void transmit_packet(uint8_t ep_num) if(ep_num == 0) { volatile uint8_t * ep0in_buf = &USBIEP0BUF; - for(int i = 0; i < xfer_size; i++) + for(uint16_t i = 0; i < xfer_size; i++) { ep0in_buf[i] = base[i]; } @@ -419,9 +480,8 @@ static void transmit_packet(uint8_t ep_num) else { ep_regs_t ep_regs = EP_REGS(ep_num, TUSB_DIR_IN); - uint16_t in_buf_base = USBSTABUFF + (ep_regs[BBAX] << 3); + volatile uint8_t * ep_buf = &USBSTABUFF + (ep_regs[BBAX] << 3); - volatile uint8_t * ep_buf = (volatile uint8_t *) (in_buf_base); for(int i = 0; i < xfer_size; i++) { ep_buf[i] = base[i]; -- cgit v1.3.1 From fad44c03c874ad5b278e41ab842e2fb36134ad2a Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 1 Oct 2019 23:03:39 -0400 Subject: dcd_msp430x5xx: Fix TOGGLE bit behavior, clear stall when endpoint opened due to reset potentially not resetting everything. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 5e9fbf0f1..121dd03ac 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -260,9 +260,9 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) ep_regs[SIZXY] = desc_edpt->wMaxPacketSize.size; ep_regs[BCTX] |= NAK; ep_regs[BBAX] = buf_base; - ep_regs[CNF] &= ~TOGGLE; // ISO xfers not supported on MSP430, + ep_regs[CNF] &= ~(TOGGLE | STALL); // ISO xfers not supported on MSP430, // so no need to gate DATA0/1 and frame - // behavior. + // behavior. Clear stall bit- see above comment. ep_regs[CNF] |= (UBME | USBIIE); USBKEYPID = USBKEY; @@ -313,8 +313,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t { ep_regs_t ep_regs = EP_REGS(epnum, dir); - ep_regs[CNF] &= ~TOGGLE; // Bulk and int begin on DATA0. - if(dir == TUSB_DIR_OUT) { ep_regs[BCTX] &= ~NAK; -- cgit v1.3.1 From 54478aaa2a57e62f946581f492da5792741116f9 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 1 Oct 2019 23:28:41 -0400 Subject: dcd_msp430x5xx: Add STALL support for nonzero endpoints. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 121dd03ac..5202f156a 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -346,6 +346,11 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) USBIEPCNF_0 |= STALL; } } + else + { + ep_regs_t ep_regs = EP_REGS(epnum, dir); + ep_regs[CNF] |= STALL; + } } void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) @@ -366,6 +371,13 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) USBIEPCNT_0 &= ~STALL; } } + else + { + ep_regs_t ep_regs = EP_REGS(epnum, dir); + // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt + // and bulk endpoints. + ep_regs[CNF] &= ~(STALL + TOGGLE); + } } /*------------------------------------------------------------------*/ -- cgit v1.3.1 From 19ee5199265d064e23c376c4ab0fdf92b08a5378 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 2 Oct 2019 00:01:58 -0400 Subject: dcd_msp430x5xx: Correct byte count masks in transmit/receive routines. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 5202f156a..2f67e5d37 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -394,7 +394,7 @@ static void receive_packet(uint8_t ep_num) } else { - xfer_size = ep_regs[BCTX] & 0x3F; + xfer_size = ep_regs[BCTX] & 0x7F; } uint16_t remaining = xfer->total_len - xfer->queued_len; @@ -497,7 +497,7 @@ static void transmit_packet(uint8_t ep_num) ep_buf[i] = base[i]; } - ep_regs[BCTX] = (ep_regs[BCTX] & 0xF0) + xfer_size; + ep_regs[BCTX] = (ep_regs[BCTX] & 0xF0) + (xfer_size & 0x7F); ep_regs[BCTX] &= ~NAK; } } -- cgit v1.3.1 From 3edb5548e98e76cda7479d2d039b0557eda26a1b Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 2 Oct 2019 01:18:56 -0400 Subject: dcd_msp430x5xx: Ensure DBUF bit is cleared on endpoint open, as it could get spuriously set in debugging sessions. cdc_msc functional. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 2f67e5d37..ac7e27ee7 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -257,12 +257,16 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // while debugging, despite stall code never being called. It appears // these registers don't get cleared on reset, being part of RAM. // Investigate and see if I can duplicate. + // Also, DBUF got set on OUT EP 2 while debugging. Only OUT EPs seem to be + // affected at this time. USB RAM directly precedes main RAM; perhaps I'm + // overwriting registers via buffer overflow w/ my debugging code? ep_regs[SIZXY] = desc_edpt->wMaxPacketSize.size; ep_regs[BCTX] |= NAK; ep_regs[BBAX] = buf_base; - ep_regs[CNF] &= ~(TOGGLE | STALL); // ISO xfers not supported on MSP430, - // so no need to gate DATA0/1 and frame - // behavior. Clear stall bit- see above comment. + ep_regs[CNF] &= ~(TOGGLE | STALL | DBUF); // ISO xfers not supported on + // MSP430, so no need to gate DATA0/1 and frame + // behavior. Clear stall and double buffer bit as + // well- see above comment. ep_regs[CNF] |= (UBME | USBIIE); USBKEYPID = USBKEY; -- cgit v1.3.1 From 05914de10992c0bc0f35f6fc3c6bc8064ffcd935 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 2 Oct 2019 22:36:45 -0400 Subject: dcd_msp430x5xx: Fix typos in dcd_edpt_clear_stall. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index ac7e27ee7..32565c38e 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -368,11 +368,11 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { if(dir == TUSB_DIR_OUT) { - USBOEPCNT_0 &= ~STALL; + USBOEPCNF_0 &= ~STALL; } else { - USBIEPCNT_0 &= ~STALL; + USBIEPCNF_0 &= ~STALL; } } else -- cgit v1.3.1 From b0b737b42a14982a1f928e408ba7eadc3f474d04 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 2 Oct 2019 23:02:55 -0400 Subject: usbd_control.c: Decide whether a control transfer has a data stage based on setup packet wLength. --- src/device/usbd_control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index eed933f68..69ab47b4d 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -94,7 +94,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo _control_state.total_len = tu_min16(len, request->wLength); _control_state.total_transferred = 0; - if ( len ) + if ( _control_state.total_len ) { TU_ASSERT(buffer); -- cgit v1.3.1 From a01b0a73c13ca771e77440d040b0e1e3c5ecbcf7 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 3 Oct 2019 23:58:24 -0400 Subject: Remove accidentally-commited debug var. --- src/device/usbd_control.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 070ff504b..e1e9b9f01 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -116,7 +116,6 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo return true; } -volatile int dummy = 0; // callback when a transaction complete on DATA stage of control endpoint bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -133,13 +132,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result _control_state.total_transferred += xferred_bytes; _control_state.buffer = ((uint8_t*)_control_state.buffer) + xferred_bytes; - if((_control_state.total_transferred >= 144)) - { - dummy = 1; - } - if ( (_control_state.requested_len == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) - { // DATA stage is complete bool is_ok = true; -- cgit v1.3.1 From c8e899fef03461d0aecfd82370f818483e8c9a3d Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 10 Oct 2019 04:02:35 -0400 Subject: dcd_msp430x5xx: Improve SETUP packet and EP0 NAK interactions, per 42.3.1.3 in Reference Manual; fix is incomplete but works. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 32565c38e..7b31ddd0a 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -90,9 +90,9 @@ static void bus_reset(void) USBOEPIE |= BIT0; USBIEPIE |= BIT0; - // Set NAK until a setup packet is received. - USBOEPCNT_0 |= NAK; - USBIEPCNT_0 |= NAK; + // Clear NAK until a setup packet is received. + USBOEPCNT_0 &= ~NAK; + USBIEPCNT_0 &= ~NAK; USBCTL |= FEN; // Enable responding to packets. @@ -515,6 +515,11 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } + // The NAK bits must be clear to receive a SETUP packet. Clearing SETUPIFG + // by reading USBVECINT does not set NAK, so now that we have a SETUP packet + // force NAKs. + USBIEPCNT_0 |= NAK; + USBOEPCNT_0 |= NAK; dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } -- cgit v1.3.1 From d0146be00b4dd41826f29e36bb10e0ecafce5e47 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Thu, 10 Oct 2019 04:19:48 -0400 Subject: dcd_msp430x5xx: Fix typo in copy-paste in transmit_packet. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 7b31ddd0a..a6efee094 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -501,7 +501,7 @@ static void transmit_packet(uint8_t ep_num) ep_buf[i] = base[i]; } - ep_regs[BCTX] = (ep_regs[BCTX] & 0xF0) + (xfer_size & 0x7F); + ep_regs[BCTX] = (ep_regs[BCTX] & 0x80) + (xfer_size & 0x7F); ep_regs[BCTX] &= ~NAK; } } -- cgit v1.3.1 From de333a6f1879f43fde6e17f4dc866ad2ad77dc6b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 29 Oct 2019 16:21:31 +0700 Subject: clean up warning, msp430 gcc 8.3 fixed the library lto issue --- examples/make.mk | 4 ---- src/tusb.c | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/examples/make.mk b/examples/make.mk index 4a2af3c22..95b2593bd 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -77,10 +77,6 @@ CFLAGS += \ -ffunction-sections \ -fdata-sections -ifneq ($(BOARD), msp_exp430f5529lp) - CFLAGS += -Wno-error=lto-type-mismatch -endif - # This causes lots of warning with nrf5x build due to nrfx code # CFLAGS += -Wcast-align diff --git a/src/tusb.c b/src/tusb.c index 271b35f1e..e7f5d800d 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -71,7 +71,7 @@ char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) }; static void dump_str_line(uint8_t const* buf, uint16_t count) { // each line is 16 bytes - for(int i=0; i Date: Tue, 29 Oct 2019 16:25:32 +0700 Subject: should fix #184 only response up to EP0 size with get device descriptor if not addressed. --- src/device/usbd.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index f2becab95..5c6fc3748 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -44,6 +44,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint8_t connected : 1; + volatile uint8_t addressed : 1; volatile uint8_t configured : 1; volatile uint8_t suspended : 1; @@ -478,6 +479,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Depending on mcu, status phase could be sent either before or after changing device address // Therefore DCD must include zero-length status response dcd_set_address(rhport, (uint8_t) p_request->wValue); + _usbd_dev.addressed = 1; return true; // skip status break; @@ -752,7 +754,17 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const switch(desc_type) { case TUSB_DESC_DEVICE: - return tud_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), sizeof(tusb_desc_device_t)); + { + uint16_t len = sizeof(tusb_desc_device_t); + + // Only send up to EP0 Packet Size if not addressed + if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed) + { + len = CFG_TUD_ENDPOINT0_SIZE; + } + + return tud_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), len); + } break; case TUSB_DESC_BOS: @@ -820,6 +832,7 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) case DCD_EVENT_UNPLUGGED: _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; _usbd_dev.configured = 0; _usbd_dev.suspended = 0; osal_queue_send(_usbd_q, event, in_isr); -- cgit v1.3.1 From 66faa96f1609a1a6e95004ec7adbcd1568df01e2 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 29 Oct 2019 11:33:19 -0400 Subject: tusb_option.h: Assign msp430 ID range 500+ to avoid conflict with Sony. --- src/tusb_option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tusb_option.h b/src/tusb_option.h index 5ebda9f3b..d8cd3782b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -72,7 +72,7 @@ #define OPT_MCU_CXD56 400 ///< SONY CXD56 // TI MSP430 -#define OPT_MCU_MSP430x5xx 400 ///< TI MSP430x5xx +#define OPT_MCU_MSP430x5xx 500 ///< TI MSP430x5xx /** @} */ -- cgit v1.3.1 From 3f0f7cfd07e04e6a5a154de44b94b074ab5b4307 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 29 Oct 2019 12:52:56 -0400 Subject: dcd_msp430x5xx: Clarify hardware STALL behavior and current vs ideal behavior of driver in comments. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index a6efee094..e2a9a9e95 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -515,9 +515,12 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // The NAK bits must be clear to receive a SETUP packet. Clearing SETUPIFG - // by reading USBVECINT does not set NAK, so now that we have a SETUP packet - // force NAKs. + // The EP0 NAK bits must be clear to receive a SETUP packet, according to the + // manual (we don't do this right now- see below comments). + // Race conditions where the hardware STALLs can occur if the NAK bits aren't + // set for both IN/OUT EP0. Clearing SETUPIFG by reading USBVECINT does not + // set NAK, so now that we have a SETUP packet, force NAKs. + // FIXME: Explain more accurately why the STALL occurs. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); @@ -526,7 +529,7 @@ static void handle_setup_packet(void) void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) { // Setup is special- reading USBVECINT to handle setup packets is done to - // stop NAKs on EP0. + // stop hardware-generated NAKs on EP0. uint8_t setup_status = USBIFG & SETUPIFG; if(setup_status) @@ -543,7 +546,14 @@ void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); break; - // Clear the NAK on EP 0 after a SETUP packet is received. + // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet + // is received. The NAK bits for EP0 should still be set because it's + // possible for the hardware to STALL in the middle of a control xfer + // if the EP0 NAK bits aren't set properly. + // See: https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/845259 + // FIXME: Per manual, we should be clearing the NAK bits of EP0 after the + // Status Phase of a control xfer is done, in preparation of another + // possible setup packet. No clean way to do this right now. case USBVECINT_SETUP_PACKET_RECEIVED: break; -- cgit v1.3.1 From 5d585c03bdf5059c7856d5ee32a754bd3cdbdd2f Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 29 Oct 2019 14:08:39 -0400 Subject: dcd_msp430x5xx: Improve comments regarding SETUP packet handling. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 35 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index e2a9a9e95..3a73cf9bf 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -515,12 +515,9 @@ static void handle_setup_packet(void) _setup_packet[i] = setup_buf[i]; } - // The EP0 NAK bits must be clear to receive a SETUP packet, according to the - // manual (we don't do this right now- see below comments). - // Race conditions where the hardware STALLs can occur if the NAK bits aren't - // set for both IN/OUT EP0. Clearing SETUPIFG by reading USBVECINT does not - // set NAK, so now that we have a SETUP packet, force NAKs. - // FIXME: Explain more accurately why the STALL occurs. + // Clearing SETUPIFG by reading USBVECINT does not set NAK, so now that we + // have a SETUP packet, force NAKs until tinyusb can handle the SETUP + // packet and prepare for a new xfer. USBIEPCNT_0 |= NAK; USBOEPCNT_0 |= NAK; dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); @@ -547,13 +544,31 @@ void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) break; // Clear the (hardware-enforced) NAK on EP 0 after a SETUP packet - // is received. The NAK bits for EP0 should still be set because it's - // possible for the hardware to STALL in the middle of a control xfer - // if the EP0 NAK bits aren't set properly. + // is received. At this point, even though the hardware is no longer + // forcing NAKs, the EP0 NAK bits should still be set to avoid + // sending/receiving data before tinyusb is ready. + // + // Furthermore, it's possible for the hardware to STALL in the middle of + // a control xfer if the EP0 NAK bits aren't set properly. // See: https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/845259 + // From my testing, if all of the following hold: + // * OUT EP0 NAK is cleared. + // * IN EP0 NAK is set. + // * DIR bit in USBCTL is clear. + // and an IN packet is received on EP0, the USB core will STALL. Setting + // both EP0 NAKs manually when a SETUP packet is received, as is done + // in handle_setup_packet(), avoids meeting STALL conditions. + // + // TODO: Figure out/explain why the STALL condition can be reached in the + // first place. When I first noticed the STALL, the only two places I + // touched the NAK bits were in dcd_edpt_xfer() and to _set_ (sic) them in + // bus_reset(). SETUP packet handling should've been unaffected. + // // FIXME: Per manual, we should be clearing the NAK bits of EP0 after the // Status Phase of a control xfer is done, in preparation of another - // possible setup packet. No clean way to do this right now. + // possible SETUP packet. We don't do this right now, as there is no + // "Status Phase done" callback the driver can use. However, SETUP packets + // _are_ correctly handled by the USB core without clearing the NAKs. case USBVECINT_SETUP_PACKET_RECEIVED: break; -- cgit v1.3.1 From 1b51b78eafb1a078aa7fc8caf57d01d92b84ca0f Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Nov 2019 00:17:17 +0700 Subject: hack the request length for the first get device descriptor if EP0 size =8 or 16 to prevent usbd control send out ZLP --- src/device/usbd.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 8661717f5..360881f34 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -771,9 +771,13 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const uint16_t len = sizeof(tusb_desc_device_t); // Only send up to EP0 Packet Size if not addressed + // This only happens with the very first get device descriptor and EP0 size = 8 or 16. if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed) { len = CFG_TUD_ENDPOINT0_SIZE; + + // Hack here: we modify the request length to prevent usbd_control response with zlp + ((tusb_control_request_t*) p_request)->wLength = CFG_TUD_ENDPOINT0_SIZE; } return tud_control_xfer(rhport, p_request, (void*) tud_descriptor_device_cb(), len); -- cgit v1.3.1 From 65e96e5d525ea02e0ca7f265a4d62b4f428cc821 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Nov 2019 18:00:07 +0700 Subject: added optional dcd_control_status_complete() --- src/device/dcd.h | 4 ++++ src/device/usbd_control.c | 1 + test/test/device/usbd/test_usbd.c | 2 ++ 3 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/device/dcd.h b/src/device/dcd.h index 9fa98c669..c88465cbb 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -119,6 +119,10 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // clear stall, data toggle is also reset to DATA0 void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); +// Invoked when a control transfer's status stage is complete. +// May help DCD to prepare for next control transfer, this API is optional. +void dcd_control_status_complete(uint8_t rhport) TU_ATTR_WEAK; + //--------------------------------------------------------------------+ // Event API //--------------------------------------------------------------------+ diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index f41614ef1..d37e9ec2a 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -129,6 +129,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction ) { TU_ASSERT(0 == xferred_bytes); + if (dcd_control_status_complete) dcd_control_status_complete(rhport); return true; } diff --git a/test/test/device/usbd/test_usbd.c b/test/test/device/usbd/test_usbd.c index add947b3d..a4063a488 100644 --- a/test/test/device/usbd/test_usbd.c +++ b/test/test/device/usbd/test_usbd.c @@ -231,5 +231,7 @@ void test_usbd_control_in_zlp(void) dcd_edpt_xfer_ExpectAndReturn(rhport, EDPT_CTRL_OUT, NULL, 0, true); dcd_event_xfer_complete(rhport, EDPT_CTRL_OUT, 0, 0, false); + dcd_control_status_complete_Expect(rhport); + tud_task(); } -- cgit v1.3.1 From 6b5157fd28a9495ee37fb2c84d29c1a61bb7c68b Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Tue, 24 Mar 2020 00:03:12 -0400 Subject: dcd_msp430x5xx: Add dummy dcd_edpt0_status_complete handler. Add comment which describes why it might be needed. --- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 3a73cf9bf..d50fa17fe 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -1,8 +1,8 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 William D. Jones - * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2019-2020 William D. Jones + * Copyright (c) 2019-2020 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 @@ -384,6 +384,22 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) } } +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void) rhport; + (void) request; + + // FIXME: Per manual, we should be clearing the NAK bits of EP0 after the + // Status Phase of a control xfer is done, in preparation of another possible + // SETUP packet. However, from my own testing, SETUP packets _are_ correctly + // handled by the USB core without clearing the NAKs. + // + // Right now, clearing NAKs in this callbacks causes a direction mismatch + // between host and device on EP0. Figure out why and come back to this. + // USBOEPCNT_0 &= ~NAK; + // USBIEPCNT_0 &= ~NAK; +} + /*------------------------------------------------------------------*/ static void receive_packet(uint8_t ep_num) @@ -563,12 +579,6 @@ void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) // first place. When I first noticed the STALL, the only two places I // touched the NAK bits were in dcd_edpt_xfer() and to _set_ (sic) them in // bus_reset(). SETUP packet handling should've been unaffected. - // - // FIXME: Per manual, we should be clearing the NAK bits of EP0 after the - // Status Phase of a control xfer is done, in preparation of another - // possible SETUP packet. We don't do this right now, as there is no - // "Status Phase done" callback the driver can use. However, SETUP packets - // _are_ correctly handled by the USB core without clearing the NAKs. case USBVECINT_SETUP_PACKET_RECEIVED: break; -- cgit v1.3.1