浏览代码

f7: Clean up board-specific handling.

Keir Fraser 4 年之前
父节点
当前提交
8178531e2c
共有 5 个文件被更改,包括 165 次插入148 次删除
  1. 18 0
      inc/stm32/f7.h
  2. 141 29
      src/f7/board.c
  3. 3 48
      src/f7/floppy.c
  4. 2 63
      src/f7/stm32.c
  5. 1 8
      src/usb/hw_dwc_otg.c

+ 18 - 0
inc/stm32/f7.h

@@ -94,6 +94,24 @@ enum {
     F7SM_lightning = 2
 };
 
+struct user_pin {
+    uint8_t pin_id;
+    uint8_t gpio_bank;
+    uint8_t gpio_pin;
+    bool_t  push_pull;
+};
+
+struct board_config {
+    uint8_t hse_mhz;
+    bool_t hs_usb;
+    const struct user_pin *user_pins;
+};
+
+extern const struct board_config *board_config;
+void identify_board_config(void);
+
+GPIO gpio_from_id(uint8_t id);
+
 /*
  * Local variables:
  * mode: C

+ 141 - 29
src/f7/board.c

@@ -12,29 +12,134 @@
 #define gpio_led gpiob
 #define pin_led 13
 
-static void mcu_board_init(void)
+enum { _A = 0, _B, _C, _D, _E, _F, _G, _H, _I };
+enum { _OD = 0, _PP };
+
+GPIO gpio_from_id(uint8_t id)
 {
-    uint16_t a = 0x9930; /* PA4-5,8,11-12,15 */
-    uint16_t b = 0x23f8; /* PB3-9,13 */
-    uint16_t c = 0xffe7; /* PC0-2,5-15 */
-    uint16_t d = 0xffff; /* PD0-15 */
-    uint16_t e = 0xffff; /* PE0-15 */
-    uint16_t f = 0xffff; /* PF0-15 */
-    uint16_t g = 0xffff; /* PG0-15 */
-    uint16_t h = 0xffff; /* PH0-15 */
-    uint16_t i = 0xffff; /* PI0-15 */
-    uint32_t ahb1enr = rcc->ahb1enr;
+    switch (id) {
+    case _A: return gpioa;
+    case _B: return gpiob;
+    case _C: return gpioc;
+    case _D: return gpiod;
+    case _E: return gpioe;
+    case _F: return gpiof;
+    case _G: return gpiog;
+    case _H: return gpioh;
+    case _I: return gpioi;
+    }
+    ASSERT(0);
+    return NULL;
+}
+
+const static struct user_pin _user_pins_F7SM_basic[] = {
+    { 2, _B, 12, _OD },
+    { 0,  0,  0, _OD } };
+const static struct user_pin _user_pins_F7SM_ambertronic_f7_plus[] = {
+    { 2, _B, 12, _OD }, /* board bug: B12 isn't buffered */
+    { 4, _C,  6, _PP },
+    { 0,  0,  0, _PP } };
+const static struct user_pin _user_pins_F7SM_lightning[] = {
+    { 2, _B, 12, _PP },
+    { 4, _E, 15, _PP },
+    { 6, _E, 14, _PP },
+    { 0,  0,  0, _PP } };
+const static struct board_config _board_config[] = {
+    [F7SM_basic] = {
+        .hse_mhz   = 8,
+        .hs_usb    = FALSE,
+        .user_pins = _user_pins_F7SM_basic },
+    [F7SM_ambertronic_f7_plus] = {
+        .hse_mhz   = 8,
+        .hs_usb    = FALSE,
+        .user_pins = _user_pins_F7SM_ambertronic_f7_plus },
+    [F7SM_lightning] = {
+        .hse_mhz   = 16,
+        .hs_usb    = TRUE,
+        .user_pins = _user_pins_F7SM_lightning },
+};
+const struct board_config *board_config;
+
+#define early_delay_ms(ms) (delay_ticks((ms)*2000))
+#define early_delay_us(ms) (delay_ticks((ms)*2))
 
-    switch (gw_info.hw_submodel) {
-    case F7SM_basic:
-        break;
-    case F7SM_ambertronic_f7_plus:
-        break;
-    case F7SM_lightning:
-        /* Uses PE12 and PE13 for extra drive outputs. */
-        ahb1enr |= RCC_AHB1ENR_GPIOEEN;
-        break;
+/* Blink the activity LED to indicate fatal error. */
+static void early_fatal(int blinks) __attribute__((noreturn));
+static void early_fatal(int blinks)
+{
+    int i;
+    rcc->ahb1enr |= RCC_AHB1ENR_GPIOBEN;
+    delay_ticks(10);
+    gpio_configure_pin(gpiob, 13, GPO_pushpull(IOSPD_LOW, HIGH));
+    for (;;) {
+        for (i = 0; i < blinks; i++) {
+            gpio_write_pin(gpiob, 13, LOW);
+            early_delay_ms(150);
+            gpio_write_pin(gpiob, 13, HIGH);
+            early_delay_ms(150);
+        }
+        early_delay_ms(2000);
     }
+}
+
+void identify_board_config(void)
+{
+    uint16_t low, high;
+    uint8_t id = 0;
+    int i;
+
+    rcc->ahb1enr |= RCC_AHB1ENR_GPIOCEN;
+    early_delay_us(2);
+
+    /* Pull PC[15:13] low, and check which are tied HIGH. */
+    for (i = 0; i < 3; i++)
+        gpio_configure_pin(gpioc, 13+i, GPI_pull_down);
+    early_delay_us(10);
+    high = (gpioc->idr >> 13) & 7;
+
+    /* Pull PC[15:13] high, and check which are tied LOW. */
+    for (i = 0; i < 3; i++)
+        gpio_configure_pin(gpioc, 13+i, GPI_pull_up);
+    early_delay_us(10);
+    low = (~gpioc->idr >> 13) & 7;
+
+    /* Each PCx pin defines a 'trit': 0=float, 1=low, 2=high. 
+     * We build a 3^3 ID space from the resulting three-trit ID. */
+    for (i = 0; i < 3; i++) {
+        id *= 3;
+        switch ((high>>1&2) | (low>>2&1)) {
+        case 0: break;          /* float = 0 */
+        case 1: id += 1; break; /* LOW   = 1 */
+        case 2: id += 2; break; /* HIGH  = 2 */
+        case 3: early_fatal(1); /* cannot be tied HIGH *and* LOW! */
+        }
+        high <<= 1;
+        low <<= 1;
+    }
+
+    /* Panic if the ID is unrecognised. */
+    if (id >= ARRAY_SIZE(_board_config))
+        early_fatal(2);
+
+    gw_info.hw_submodel = id;
+    board_config = &_board_config[id];
+}
+
+static void mcu_board_init(void)
+{
+    uint16_t pu[] = {
+        [_A] = 0x9930, /* PA4-5,8,11-12,15 */
+        [_B] = 0x23f8, /* PB3-9,13 */
+        [_C] = 0xffe7, /* PC0-2,5-15 */
+        [_D] = 0xffff, /* PD0-15 */
+        [_E] = 0xffff, /* PE0-15 */
+        [_F] = 0xffff, /* PF0-15 */
+        [_G] = 0xffff, /* PG0-15 */
+        [_H] = 0xffff, /* PH0-15 */
+        [_I] = 0xffff, /* PI0-15 */
+    };
+    uint32_t ahb1enr = rcc->ahb1enr;
+    const struct user_pin *upin;
 
     /* Enable all GPIO bank register clocks to configure unused pins. */
     rcc->ahb1enr |= (RCC_AHB1ENR_GPIOAEN |
@@ -48,15 +153,22 @@ static void mcu_board_init(void)
                      RCC_AHB1ENR_GPIOIEN);
     peripheral_clock_delay();
 
-    gpio_pull_up_pins(gpioa, a);
-    gpio_pull_up_pins(gpiob, b);
-    gpio_pull_up_pins(gpioc, c);
-    gpio_pull_up_pins(gpiod, d);
-    gpio_pull_up_pins(gpioe, e);
-    gpio_pull_up_pins(gpiof, f);
-    gpio_pull_up_pins(gpiog, g);
-    gpio_pull_up_pins(gpioh, h);
-    gpio_pull_up_pins(gpioi, i);
+    /* Keep clock enabled for all banks containing user-modifiable pins. 
+     * Also do not default these pins to pull-up mode. */
+    for (upin = board_config->user_pins; upin->pin_id != 0; upin++) {
+        ahb1enr |= 1u << upin->gpio_bank;
+        pu[upin->gpio_bank] &= ~(1u << upin->gpio_pin);
+    }
+
+    gpio_pull_up_pins(gpioa, pu[_A]);
+    gpio_pull_up_pins(gpiob, pu[_B]);
+    gpio_pull_up_pins(gpioc, pu[_C]);
+    gpio_pull_up_pins(gpiod, pu[_D]);
+    gpio_pull_up_pins(gpioe, pu[_E]);
+    gpio_pull_up_pins(gpiof, pu[_F]);
+    gpio_pull_up_pins(gpiog, pu[_G]);
+    gpio_pull_up_pins(gpioh, pu[_H]);
+    gpio_pull_up_pins(gpioi, pu[_I]);
 
     /* Unused GPIO banks can have their clocks disabled again. They will 
      * statically hold their configuration state. */

+ 3 - 48
src/f7/floppy.c

@@ -67,50 +67,6 @@ void IRQ_8(void) __attribute__((alias("IRQ_INDEX_changed"))); /* EXTI2 */
 #define U_BUF_SZ (128*1024)
 static uint8_t u_buf[U_BUF_SZ] aligned(4) section_ext_ram;
 
-enum { _A = 1, _B, _C, _D, _E, _F, _G, _H, _I };
-enum { _OD = 0, _PP };
-struct user_pin {
-    uint8_t pin_id;
-    uint8_t gpio_bank;
-    uint8_t gpio_pin;
-    bool_t  push_pull;
-};
-
-const static struct user_pin _user_pins_F7SM_basic[] = {
-    { 2, _B, 12, _OD },
-    { 0,  0,  0, _OD } };
-const static struct user_pin _user_pins_F7SM_ambertronic_f7_plus[] = {
-    { 2, _B, 12, _OD }, /* board bug: B12 isn't buffered */
-    { 4, _C,  6, _PP },
-    { 0,  0,  0, _PP } };
-const static struct user_pin _user_pins_F7SM_lightning[] = {
-    { 2, _B, 12, _PP },
-    { 4, _E, 15, _PP },
-    { 6, _E, 14, _PP },
-    { 0,  0,  0, _PP } };
-const static struct user_pin *user_pins, *_user_pins[] = {
-    [F7SM_basic]               = _user_pins_F7SM_basic,
-    [F7SM_ambertronic_f7_plus] = _user_pins_F7SM_ambertronic_f7_plus,
-    [F7SM_lightning]           = _user_pins_F7SM_lightning
-};
-
-static GPIO gpio_from_id(uint8_t id)
-{
-    switch (id) {
-    case _A: return gpioa;
-    case _B: return gpiob;
-    case _C: return gpioc;
-    case _D: return gpiod;
-    case _E: return gpioe;
-    case _F: return gpiof;
-    case _G: return gpiog;
-    case _H: return gpioh;
-    case _I: return gpioi;
-    }
-    ASSERT(0);
-    return NULL;
-}
-
 static void floppy_mcu_init(void)
 {
     const struct user_pin *upin;
@@ -125,8 +81,7 @@ static void floppy_mcu_init(void)
     configure_pin(rdata, AFI(PUPD_none));
 
     /* Configure user-modifiable pins. */
-    user_pins = _user_pins[gw_info.hw_submodel];
-    for (upin = user_pins; upin->gpio_bank != 0; upin++) {
+    for (upin = board_config->user_pins; upin->pin_id != 0; upin++) {
         gpio_configure_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin,
                            upin->push_pull ? GPO_bus_pp : GPO_bus_od);
     }
@@ -309,7 +264,7 @@ static uint8_t set_user_pin(unsigned int pin, unsigned int level)
 {
     const struct user_pin *upin;
 
-    for (upin = user_pins; upin->gpio_bank != 0; upin++) {
+    for (upin = board_config->user_pins; upin->pin_id != 0; upin++) {
         if (upin->pin_id == pin)
             goto found;
     }
@@ -324,7 +279,7 @@ static void reset_user_pins(void)
 {
     const struct user_pin *upin;
 
-    for (upin = user_pins; upin->gpio_bank != 0; upin++)
+    for (upin = board_config->user_pins; upin->pin_id != 0; upin++)
         gpio_write_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin, O_FALSE);
 }
 

+ 2 - 63
src/f7/stm32.c

@@ -9,72 +9,11 @@
  * See the file COPYING for more details, or visit <http://unlicense.org>.
  */
 
-#define early_delay_ms(ms) (delay_ticks((ms)*2000))
 #define early_delay_us(ms) (delay_ticks((ms)*2))
 
-/* Blink the activity LED to indicate fatal error. */
-static void early_fatal(int blinks) __attribute__((noreturn));
-static void early_fatal(int blinks)
-{
-    int i;
-    rcc->ahb1enr |= RCC_AHB1ENR_GPIOBEN;
-    delay_ticks(10);
-    gpio_configure_pin(gpiob, 13, GPO_pushpull(IOSPD_LOW, HIGH));
-    for (;;) {
-        for (i = 0; i < blinks; i++) {
-            gpio_write_pin(gpiob, 13, LOW);
-            early_delay_ms(150);
-            gpio_write_pin(gpiob, 13, HIGH);
-            early_delay_ms(150);
-        }
-        early_delay_ms(2000);
-    }
-}
-
-static void board_id_init(void)
-{
-    uint16_t low, high;
-    uint8_t id = 0;
-    int i;
-
-    rcc->ahb1enr |= RCC_AHB1ENR_GPIOCEN;
-    early_delay_us(2);
-
-    /* Pull PC[15:13] low, and check which are tied HIGH. */
-    for (i = 0; i < 3; i++)
-        gpio_configure_pin(gpioc, 13+i, GPI_pull_down);
-    early_delay_us(10);
-    high = (gpioc->idr >> 13) & 7;
-
-    /* Pull PC[15:13] high, and check which are tied LOW. */
-    for (i = 0; i < 3; i++)
-        gpio_configure_pin(gpioc, 13+i, GPI_pull_up);
-    early_delay_us(10);
-    low = (~gpioc->idr >> 13) & 7;
-
-    /* Each PCx pin defines a 'trit': 0=float, 1=low, 2=high. 
-     * We build a 3^3 ID space from the resulting three-trit ID. */
-    for (i = 0; i < 3; i++) {
-        id *= 3;
-        switch ((high>>1&2) | (low>>2&1)) {
-        case 0: break;          /* float = 0 */
-        case 1: id += 1; break; /* LOW   = 1 */
-        case 2: id += 2; break; /* HIGH  = 2 */
-        case 3: early_fatal(1); /* cannot be tied HIGH *and* LOW! */
-        }
-        high <<= 1;
-        low <<= 1;
-    }
-
-    /* Panic if the ID is unrecognised. */
-    gw_info.hw_submodel = id;
-    if (id > 2)
-        early_fatal(2);
-}
-
 static void clock_init(void)
 {
-    unsigned int hse = (gw_info.hw_submodel == F7SM_lightning) ? 16 : 8;
+    unsigned int hse = board_config->hse_mhz;
 
     /* Disable all peripheral clocks except the essentials before enabling 
      * Over-drive mode (see note in RM0431, p102). We still need access to RAM
@@ -156,7 +95,7 @@ static void peripheral_init(void)
 void stm32_init(void)
 {
     cortex_init();
-    board_id_init();
+    identify_board_config();
     clock_init();
     icache_enable();
     dcache_enable();

+ 1 - 8
src/usb/hw_dwc_otg.c

@@ -155,14 +155,7 @@ void hw_usb_init(void)
     int i;
 
     /* Determine which PHY we use based on hardware submodel ID. */
-    switch (gw_info.hw_submodel) {
-    case F7SM_lightning:
-        conf_iface = IFACE_HS_EMBEDDED;
-        break;
-    default:
-        conf_iface = IFACE_FS;
-        break;
-    }
+    conf_iface = board_config->hs_usb ? IFACE_HS_EMBEDDED : IFACE_FS;
 
     /*
      * HAL_PCD_MspInit