From 134b4b6a8bd61378d510175311b85bdc9e2f13d5 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Mon, 2 Aug 2021 10:03:48 +0200 Subject: [PATCH] firmware: Move more of the USB shutdown control to usb_enable/usb_disable - make sure USB resources are re-enabled before jumping to bootloader - make sure all USB resources are disabled prior to jumping to user fw --- firmware/main.c | 91 +++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/firmware/main.c b/firmware/main.c index 6b4b962..02abf86 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -150,7 +150,7 @@ static __bit jump_to_usb_bootloader = 0; uint8_t __idata __at(0xff) stock_flag = 1; -//XXX: check if we want to jump to user FW +static void usb_disable(void); // cleanup after stock firmware and jump to user firmware static void jmp_to_user_fw(void) __naked @@ -184,17 +184,10 @@ static void jmp_to_user_fw(void) __naked P0_PRST = 0; // disable USB and clear irq flags - PAGESW = 1; - P1_PHYTEST0 &= ~BIT(6); // phy disable - P1_UDCCTRL &= ~BIT(6); // udc disable - P1_UDCINT0STA = 0; - P1_UDCINT1STA = 0; - P1_UDCINT2STA = 0; - P1_UDCINT0EN = 0; - P1_UDCINT1EN = 0; - P1_UDCINT2EN = 0; + usb_disable(); // disable pullups, set all pins to input + PAGESW = 1; P1_PHCON2 = 0; P1_P9M0 = 0xffu; PAGESW = 0; @@ -254,6 +247,24 @@ static void usb_bootloader_jump(void) __naked P1_UDCINT1EN = 0; P1_UDCINT2EN = 0; + // Bootloader would not enable these resources, so we need to make + // sure we enable them before jumping to it: + + // USB on USB pins + P1_USBCTRL |= BIT(7); + + // turn on PLL48 + P1_UDCCTRL &= ~BIT(0); + + // turn on USB resources (phy power up, PLL48 powerup) + P1_USBCTRL &= ~(BIT(0) | BIT(1)); + + // enable auto-tuning internal RC oscillator based on USB SOF packets + P1_IRCCTRL &= ~BIT(1); // disable manual trim + + // wait for pll to stabilize + delay_us(5000); + // disable pullups, set all pins to input P1_PHCON2 = 0; P1_P9M0 = 0xffu; @@ -1611,6 +1622,21 @@ static void usb_init(void) { PAGESW = 1; + // USB on USB pins + P1_USBCTRL |= BIT(7); + + // turn on PLL48 + P1_UDCCTRL &= ~BIT(0); + + // turn on USB resources (phy power up, PLL48 powerup) + P1_USBCTRL &= ~(BIT(0) | BIT(1)); + + // enable auto-tuning internal RC oscillator based on USB SOF packets + P1_IRCCTRL &= ~BIT(1); // disable manual trim + + // wait for pll to stabilize + delay_us(5000); + P1_UDCCTRL |= BIT(6); // udc enable // wait for UDC to complete initialization while (!(P1_UDCCTRL & BIT(1))); @@ -1646,9 +1672,6 @@ static void usb_init(void) P1_UDCINT0EN = BIT(5) | BIT(1) | BIT(6) | BIT(3); P1_UDCINT1EN = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(6); P1_UDCINT2EN = BIT(2); - //P1_UDCINT0EN = 0; - //P1_UDCINT1EN = 0; - //P1_UDCINT2EN = 0; // enable phy, wakeup enable P1_PHYTEST0 |= BIT(5) | BIT(6); @@ -1665,11 +1688,32 @@ static void usb_init(void) static void usb_disable(void) { - // reset phy/usb + // disable USB interrupts + PAGESW = 0; + P0_EIE2 &= ~BIT(2); + PAGESW = 1; + // disable interrupts + P1_UDCINT0EN = 0; + P1_UDCINT1EN = 0; + P1_UDCINT2EN = 0; + + // reset phy/usb P1_PHYTEST0 &= ~(BIT(6) | BIT(5)); // phy disable P1_UDCCTRL &= ~BIT(6); // udc disable + + // turn off PLL48 + P1_UDCCTRL |= BIT(0); + + // turn off unused USB resources (phy power down, PLL48 powerdown + P1_USBCTRL |= BIT(0) | BIT(1); + + // disable auto-tuning internal RC oscillator based on USB SOF packets + P1_IRCCTRL |= BIT(1); // enable manual trim + + // GPIO on USB pins + P1_USBCTRL &= ~BIT(7); } // }}} @@ -1729,9 +1773,6 @@ void main(void) PAGESW = 1; P1_PHCON2 = 0x00; - // enable auto-tuning internal RC oscillator based on USB SOF packets - P1_IRCCTRL &= ~BIT(1); // disable manual trim - #if CONFIG_STOCK_FW puts("ppkb firmware " FW_REVISION_STR " (stock)\n"); #else @@ -1744,22 +1785,6 @@ void main(void) usb_disable(); -#if !CONFIG_USB_STACK - PAGESW = 1; - - // GPIO on USB pins - P1_USBCTRL &= ~BIT(7); - - // turn off PLL48 - P1_UDCCTRL |= BIT(0); - - // turn off unused USB resources (phy power down, PLL48 powerdown - P1_USBCTRL |= BIT(0) | BIT(1); - - // enable auto-tuning internal RC oscillator based on USB SOF packets - P1_IRCCTRL |= BIT(1); // enable manual trim -#endif - #if CONFIG_FLASH_ENABLE for (uint8_t i = 0; i < 128; i++) flash_content[i] = 0;