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,9 +180,39 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ -void __attribute__ ((interrupt(USB_UBM_VECTOR))) USB_UBM_ISR(void) +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; + } + +} + #endif