Переглянути джерело

bootloader: Fix bootloader purgatory due to not enabling AFIO clock.
Also clean stuff up a bit.

Keir Fraser 5 роки тому
батько
коміт
4d235e8469
3 змінених файлів з 31 додано та 51 видалено
  1. 0 1
      inc/util.h
  2. 6 21
      src/board.c
  3. 25 29
      src/fw_update.c

+ 0 - 1
inc/util.h

@@ -79,7 +79,6 @@ int snprintf(char *str, size_t size, const char *format, ...)
 
 /* Board-specific callouts */
 void board_init(void);
-extern uint8_t board_id;
 
 #ifndef NDEBUG
 

+ 6 - 21
src/board.c

@@ -1,7 +1,7 @@
 /*
- * gotek/board.c
+ * board.c
  * 
- * Gotek board-specific setup and management.
+ * Board-specific setup and management.
  * 
  * Written & released by Keir Fraser <keir.xen@gmail.com>
  * 
@@ -9,8 +9,6 @@
  * See the file COPYING for more details, or visit <http://unlicense.org>.
  */
 
-uint8_t board_id;
-
 /* Pull up currently unused and possibly-floating pins. */
 static void gpio_pull_up_pins(GPIO gpio, uint16_t mask)
 {
@@ -24,23 +22,10 @@ static void gpio_pull_up_pins(GPIO gpio, uint16_t mask)
 
 void board_init(void)
 {
-    uint16_t pa_skip, pb_skip;
-
-    /* PA0-7 (floppy outputs), PA9-10 (serial console), PA11-12 (USB) */
-    pa_skip = 0x1eff;
-
-    /* PB0 (USB disconnect), PB4,6,8,13 (floppy inputs). */
-    pb_skip = 0x2151;
-
-    /* Pull up all PCx pins. */
-    gpio_pull_up_pins(gpioc, ~0x0000);
-
-    /* Wait for ID to stabilise at PC[15:12]. */
-    delay_us(5);
-    board_id = (gpioc->idr >> 12) & 0xf;
-
-    gpio_pull_up_pins(gpioa, ~pa_skip);
-    gpio_pull_up_pins(gpiob, ~pb_skip);
+    /* Pull up all unused pins. */
+    gpio_pull_up_pins(gpioa, 0xe1fe); /* PA1-8,13-15 */
+    gpio_pull_up_pins(gpiob, 0x0027); /* PB0-2,5 */
+    gpio_pull_up_pins(gpioc, 0xffff); /* PC0-15 */
 }
 
 /*

+ 25 - 29
src/fw_update.c

@@ -9,30 +9,12 @@
  * See the file COPYING for more details, or visit <http://unlicense.org>.
  */
 
-/* Main bootloader: flashes the main firmware (last 96kB of Flash). */
+/* Main bootloader: flashes the main firmware. */
 #define FIRMWARE_START 0x08002000
 #define FIRMWARE_END   0x08010000
 
 int EXC_reset(void) __attribute__((alias("main")));
 
-static void canary_init(void)
-{
-    _irq_stackbottom[0] = _thread_stackbottom[0] = 0xdeadbeef;
-}
-
-static void canary_check(void)
-{
-    ASSERT(_irq_stackbottom[0] == 0xdeadbeef);
-    ASSERT(_thread_stackbottom[0] == 0xdeadbeef);
-}
-
-static void erase_old_firmware(void)
-{
-    uint32_t p;
-    for (p = FIRMWARE_START; p < FIRMWARE_END; p += FLASH_PAGE_SIZE)
-        fpec_page_erase(p);
-}
-
 static enum {
     ST_inactive,
     ST_command_wait,
@@ -42,6 +24,8 @@ static enum {
 static uint8_t u_buf[256];
 static uint32_t u_prod;
 
+static bool_t pa14_strapped;
+
 static struct gw_info gw_info = {
     /* Max Revs == 0 signals that this is the Bootloader. */
     .max_rev = 0,
@@ -76,13 +60,20 @@ static struct {
     uint32_t cur;
 } update;
 
+static void erase_old_firmware(void)
+{
+    uint32_t p;
+    for (p = FIRMWARE_START; p < FIRMWARE_END; p += FLASH_PAGE_SIZE)
+        fpec_page_erase(p);
+}
+
 static void update_prep(uint32_t len)
 {
     fpec_init();
     erase_old_firmware();
 
     state = ST_update;
-    memset(&update, 0, sizeof(update));
+    update.cur = 0;
     update.len = len;
 
     printk("Update: %u bytes\n", len);
@@ -105,12 +96,14 @@ static void update_continue(void)
         memcpy(u_buf, &u_buf[nr], u_prod);
     }
 
-    if (update.cur >= update.len) {
+    if ((update.cur >= update.len) && ep_tx_ready(EP_TX)) {
         uint16_t crc = crc16_ccitt((void *)FIRMWARE_START, update.len, 0xffff);
         printk("Final CRC: %04x (%s)\n", crc, crc ? "FAIL" : "OK");
         u_buf[0] = !!crc;
         state = ST_command_wait;
         end_command(u_buf, 1);
+        if (crc)
+            erase_old_firmware();
     }
 }
 
@@ -130,7 +123,7 @@ static void process_command(void)
         gw_info.fw_minor = fw_minor;
         /* sample_freq is used as flags: bit 0 indicates if we entered 
          * the bootloader because PA14 is strapped to GND. */
-        gw_info.sample_freq = !gpio_read_pin(gpioa, 14);
+        gw_info.sample_freq = pa14_strapped;
         memcpy(&u_buf[2], &gw_info, sizeof(gw_info));
         resp_sz += 32;
         break;
@@ -193,17 +186,24 @@ int main(void)
         memcpy(_sdat, _ldat, _edat-_sdat);
     memset(_sbss, 0, _ebss-_sbss);
 
+    /* Turn on AFIO and GPIOA clocks. */
+    rcc->apb2enr = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
+
     /* Turn off serial-wire JTAG and reclaim the GPIOs. */
     afio->mapr = AFIO_MAPR_SWJ_CFG_DISABLED;
 
     /* Enable GPIOA, set all pins as floating, except PA14 = weak pull-up. */
-    rcc->apb2enr = RCC_APB2ENR_IOPAEN;
     gpioa->odr = 0xffffu;
     gpioa->crh = 0x48444444u;
-    gpioc->crl = 0x44444444u;
+    gpioa->crl = 0x44444444u;
+
+    /* Wait for PA14 to be pulled HIGH. */
+    cpu_relax();
+    cpu_relax();
 
     /* Enter update mode only if PA14 (DCLK) is strapped to GND. */
-    if (gpio_read_pin(gpioa, 14)) {
+    pa14_strapped = !gpio_read_pin(gpioa, 14);
+    if (!pa14_strapped) {
         /* Nope, so jump straight at the main firmware. */
         uint32_t sp = *(uint32_t *)FIRMWARE_START;
         uint32_t pc = *(uint32_t *)(FIRMWARE_START + 4);
@@ -214,7 +214,6 @@ int main(void)
         }
     }
 
-    canary_init();
     stm32_init();
     console_init();
     console_crash_on_input();
@@ -225,12 +224,9 @@ int main(void)
     printk("** Keir Fraser <keir.xen@gmail.com>\n");
     printk("** https://github.com/keirf/Greaseweazle\n\n");
 
-    gpio_configure_pin(gpioa, 14, GPI_pull_up);
-
     usb_init();
 
     for (;;) {
-        canary_check();
         usb_process();
         update_process();
     }