瀏覽代碼

Support new boards F7 Plus and Ultra730 in the firmware.

Keir Fraser 4 年之前
父節點
當前提交
e87c5af441
共有 4 個文件被更改,包括 110 次插入13 次删除
  1. 5 1
      inc/stm32/f7.h
  2. 3 8
      src/floppy.c
  3. 16 0
      src/floppy_f1.c
  4. 86 4
      src/floppy_f7.c

+ 5 - 1
inc/stm32/f7.h

@@ -88,7 +88,11 @@ void gpio_set_af(GPIO gpio, unsigned int pin, unsigned int af);
 
 #define section_ext_ram __attribute__((section(".ext_ram")))
 
-extern uint8_t board_id;
+enum {
+    F7SM_basic = 0,
+    F7SM_ambertronic_f7_plus = 1,
+    F7SM_ultra730 = 2
+};
 
 /*
  * Local variables:

+ 3 - 8
src/floppy.c

@@ -221,7 +221,6 @@ void floppy_init(void)
     floppy_mcu_init();
 
     /* Output pins, unbuffered. */
-    configure_pin(densel, GPO_bus);
     configure_pin(dir,    GPO_bus);
     configure_pin(step,   GPO_bus);
     configure_pin(wgate,  GPO_bus);
@@ -1058,19 +1057,15 @@ static void process_command(void)
         uint8_t level = u_buf[3];
         if ((len != 4) || (level & ~1))
             goto bad_command;
-        if (pin != 2) {
-            u_buf[1] = ACK_BAD_PIN;
-            goto out;
-        }
-        gpio_write_pin(gpio_densel, pin_densel, level);
-        break;
+        u_buf[1] = set_user_pin(pin, level);
+        goto out;
     }
     case CMD_RESET: {
         if (len != 2)
             goto bad_command;
         delay_params = factory_delay_params;
         _set_bus_type(BUS_NONE);
-        write_pin(densel, FALSE);
+        reset_user_pins();
         break;
     }
     case CMD_ERASE_FLUX: {

+ 16 - 0
src/floppy_f1.c

@@ -82,6 +82,9 @@ static void floppy_mcu_init(void)
     /* Configure SELECT/MOTOR lines. */
     configure_pin(sel, GPO_bus);
     configure_pin(mot, GPO_bus);
+
+    /* Configure user-modifiable lines. */
+    configure_pin(densel, GPO_bus);
 }
 
 static void rdata_prep(void)
@@ -176,6 +179,19 @@ static void reset_bus(void)
     write_pin(mot, FALSE);
 }
 
+static uint8_t set_user_pin(unsigned int pin, unsigned int level)
+{
+    if (pin != 2)
+        return ACK_BAD_PIN;
+    gpio_write_pin(gpio_densel, pin_densel, level);
+    return ACK_OKAY;
+}
+
+static void reset_user_pins(void)
+{
+    write_pin(densel, FALSE);
+}
+
 /*
  * Local variables:
  * mode: C

+ 86 - 4
src/floppy_f7.c

@@ -12,8 +12,12 @@
 #define O_FALSE 1
 #define O_TRUE  0
 
-#define GPO_bus GPO_opendrain(IOSPD_LOW,O_FALSE)
-#define AFO_bus AFO_opendrain(IOSPD_LOW)
+#define GPO_bus_pp GPO_pushpull(IOSPD_LOW,O_FALSE)
+#define AFO_bus_pp AFO_pushpull(IOSPD_LOW)
+#define GPO_bus_od GPO_opendrain(IOSPD_LOW,O_FALSE)
+#define AFO_bus_od AFO_opendrain(IOSPD_LOW)
+static unsigned int GPO_bus;
+static unsigned int AFO_bus;
 #define GPI_bus GPI_floating
 
 /* Input pins */
@@ -25,8 +29,6 @@
 #define pin_wrprot  1 /* PA1 */
 
 /* Output pins. */
-#define gpio_densel gpiob
-#define pin_densel 12 /* PB12 */
 #define gpio_pin10 gpiob
 #define pin_pin10  1  /* PB1 */
 #define gpio_pin12 gpiob
@@ -65,8 +67,54 @@ 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_ultra730[] = {
+    { 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_ultra730]            = _user_pins_F7SM_ultra730
+};
+
+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;
+
     /* Enable clock for Timer 2. */
     rcc->apb1enr |= RCC_APB1ENR_TIM2EN;
     peripheral_clock_delay();
@@ -76,6 +124,17 @@ static void floppy_mcu_init(void)
     gpio_set_af(gpio_wdata, pin_wdata, 1);
     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++) {
+        gpio_configure_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin,
+                           upin->push_pull ? GPO_bus_pp : GPO_bus_od);
+    }
+
+    /* Configure the standard output types. */
+    GPO_bus = upin->push_pull ? GPO_bus_pp : GPO_bus_od;
+    AFO_bus = upin->push_pull ? AFO_bus_pp : AFO_bus_od;
+
     /* Configure SELECT/MOTOR lines. */
     configure_pin(pin10, GPO_bus);
     configure_pin(pin12, GPO_bus);
@@ -246,6 +305,29 @@ static void reset_bus(void)
     write_pin(pin16, FALSE);
 }
 
+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++) {
+        if (upin->pin_id == pin)
+            goto found;
+    }
+    return ACK_BAD_PIN;
+
+found:
+    gpio_write_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin, level);
+    return ACK_OKAY;
+}
+
+static void reset_user_pins(void)
+{
+    const struct user_pin *upin;
+
+    for (upin = user_pins; upin->gpio_bank != 0; upin++)
+        gpio_write_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin, O_FALSE);
+}
+
 /*
  * Local variables:
  * mode: C