瀏覽代碼

F1: Introduce new submodel "F1 Plus"

Keir Fraser 3 年之前
父節點
當前提交
c6e86add16

+ 2 - 0
inc/mcu/stm32/common.h

@@ -107,6 +107,8 @@ uint8_t write_mapped_pin(
 uint8_t read_mapped_pin(
     const struct pin_mapping *map, int pin_id, bool_t *p_level);
 
+extern const struct board_config *board_config;
+
 /*
  * Local variables:
  * mode: C

+ 11 - 0
inc/mcu/stm32/f1.h

@@ -63,6 +63,17 @@ static SER_ID ser_id = (uint32_t *)0x1ffff7e8;
 /* No secondary RAM region */
 #define section_ext_ram
 
+enum {
+    F1SM_basic = 0,
+    F1SM_plus,
+};
+
+struct board_config {
+    bool_t flippy;
+    const struct pin_mapping *user_pins;
+    const struct pin_mapping *msel_pins;
+};
+
 /*
  * Local variables:
  * mode: C

+ 0 - 1
inc/mcu/stm32/f7.h

@@ -108,7 +108,6 @@ struct board_config {
     const struct pin_mapping *msel_pins;
 };
 
-extern const struct board_config *board_config;
 void identify_board_config(void);
 
 void early_fatal(int blinks) __attribute__((noreturn));

+ 2 - 1
scripts/greaseweazle/tools/info.py

@@ -15,7 +15,8 @@ from greaseweazle.tools import util
 from greaseweazle import usb as USB
 from greaseweazle import version
 
-model_id = { 1: { 0: 'F1' },
+model_id = { 1: { 0: 'F1',
+                  1: 'F1 Plus' },
              7: { 0: 'F7 v1',
                   1: 'F7 Plus (Ant Goffart, v1)',
                   2: 'F7 Lightning',

+ 2 - 1
scripts/greaseweazle/tools/util.py

@@ -282,7 +282,8 @@ def usb_open(devicename, is_update=False, mode_check=True):
     usb = USB.Unit(serial.Serial(devicename))
     usb.port_info = port_info(devicename)
     is_win7 = (platform.system() == 'Windows' and platform.release() == '7')
-    usb.jumperless_update = usb.hw_model != 1 and not is_win7
+    usb.jumperless_update = ((usb.hw_model, usb.hw_submodel) != (1, 0)
+                             and not is_win7)
 
     if not mode_check:
         return usb

+ 2 - 0
src/board.c

@@ -9,6 +9,8 @@
  * See the file COPYING for more details, or visit <http://unlicense.org>.
  */
 
+const struct board_config *board_config;
+
 GPIO gpio_from_id(uint8_t id)
 {
     switch (id) {

+ 146 - 0
src/floppy.c

@@ -123,6 +123,152 @@ static enum {
 static uint32_t u_cons, u_prod;
 #define U_MASK(x) ((x)&(U_BUF_SZ-1))
 
+static void drive_deselect(void)
+{
+    int pin = -1;
+    uint8_t rc;
+
+    if (unit_nr == -1)
+        return;
+
+    switch (bus_type) {
+    case BUS_IBMPC:
+        switch (unit_nr) {
+        case 0: pin = 14; break;
+        case 1: pin = 12; break;
+        }
+        break;
+    case BUS_SHUGART:
+        switch (unit_nr) {
+        case 0: pin = 10; break;
+        case 1: pin = 12; break;
+        case 2: pin = 14; break;
+        }
+        break;
+    }
+
+    rc = write_mapped_pin(board_config->msel_pins, pin, O_FALSE);
+    ASSERT(rc == ACK_OKAY);
+
+    unit_nr = -1;
+}
+
+static uint8_t drive_select(uint8_t nr)
+{
+    int pin = -1;
+    uint8_t rc;
+
+    if (nr == unit_nr)
+        return ACK_OKAY;
+
+    drive_deselect();
+
+    switch (bus_type) {
+    case BUS_IBMPC:
+        switch (nr) {
+        case 0: pin = 14; break;
+        case 1: pin = 12; break;
+        default: return ACK_BAD_UNIT;
+        }
+        break;
+    case BUS_SHUGART:
+        switch (nr) {
+        case 0: pin = 10; break;
+        case 1: pin = 12; break;
+        case 2: pin = 14; break;
+        default: return ACK_BAD_UNIT;
+        }
+        break;
+    default:
+        return ACK_NO_BUS;
+    }
+
+    rc = write_mapped_pin(board_config->msel_pins, pin, O_TRUE);
+    if (rc != ACK_OKAY)
+        return ACK_BAD_UNIT;
+
+    unit_nr = nr;
+    delay_us(delay_params.select_delay);
+
+    return ACK_OKAY;
+}
+
+static uint8_t drive_motor(uint8_t nr, bool_t on)
+{
+    int pin = -1;
+    uint8_t rc;
+
+    switch (bus_type) {
+    case BUS_IBMPC:
+        if (nr >= 2) 
+            return ACK_BAD_UNIT;
+        if (unit[nr].motor == on)
+            return ACK_OKAY;
+        switch (nr) {
+        case 0: pin = 10; break;
+        case 1: pin = 16; break;
+        }
+        break;
+    case BUS_SHUGART:
+        if (nr >= 3)
+            return ACK_BAD_UNIT;
+        /* All shugart units share one motor line. Alias them all to unit 0. */
+        nr = 0;
+        if (unit[nr].motor == on)
+            return ACK_OKAY;
+        pin = 16;
+        break;
+    default:
+        return ACK_NO_BUS;
+    }
+
+    rc = write_mapped_pin(board_config->msel_pins, pin, on ? O_TRUE : O_FALSE);
+    if (rc != ACK_OKAY)
+        return ACK_BAD_UNIT;
+
+    unit[nr].motor = on;
+    if (on)
+        delay_ms(delay_params.motor_delay);
+
+    return ACK_OKAY;
+
+}
+
+static uint8_t set_user_pin(unsigned int pin, unsigned int level)
+{
+    const struct pin_mapping *upin;
+
+    for (upin = board_config->user_pins; upin->pin_id != 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 pin_mapping *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);
+}
+
+#define flippy_trk0_sensor_disable() flippy_trk0_sensor(HIGH)
+#define flippy_trk0_sensor_enable() flippy_trk0_sensor(LOW)
+
+static bool_t flippy_detect(void)
+{
+    bool_t is_flippy;
+    flippy_trk0_sensor_disable();
+    is_flippy = (get_trk0() == HIGH);
+    flippy_trk0_sensor_enable();
+    return is_flippy;
+}
+
 static void step_dir_set(bool_t assert)
 {
     write_pin(dir, assert);

+ 24 - 0
src/mcu/at32f415/board.c

@@ -12,6 +12,27 @@
 #define gpio_led gpiob
 #define pin_led 13
 
+const static struct pin_mapping _msel_pins[] = {
+    { 10, _A,  3 },
+    { 12, _B,  9 },
+    { 14, _A,  4 },
+    { 16, _A,  1 },
+    {  0,  0,  0 }
+};
+
+const static struct pin_mapping _user_pins[] = {
+    {  2, _A,  6 },
+    {  4, _A,  5 },
+    {  6, _A,  7 },
+    {  0,  0,  0 }
+};
+
+const static struct board_config _board_config = {
+    .flippy    = TRUE,
+    .user_pins = _user_pins,
+    .msel_pins = _msel_pins
+};
+
 static void mcu_board_init(void)
 {
     gpio_pull_up_pins(gpioa, 0x0101); /* PA0,8 */
@@ -23,6 +44,9 @@ static void mcu_board_init(void)
 
     /* /RDY input line is externally pulled up. */
     gpio_configure_pin(gpiob, 15, GPI_floating);
+
+    /* Single static config. */
+    board_config = &_board_config;
 }
 
 /*

+ 2 - 163
src/mcu/at32f415/floppy.c

@@ -51,21 +51,6 @@ typedef uint16_t timcnt_t;
 #define irq_index 40
 void IRQ_40(void) __attribute__((alias("IRQ_INDEX_changed"))); /* EXTI15_10 */
 
-const struct pin_mapping msel_pins[] = {
-    { 10, _A,  3 },
-    { 12, _B,  9 },
-    { 14, _A,  4 },
-    { 16, _A,  1 },
-    {  0,  0,  0 }
-};
-
-const struct pin_mapping user_pins[] = {
-    {  2, _A,  6 },
-    {  4, _A,  5 },
-    {  6, _A,  7 },
-    {  0,  0,  0 }
-};
-
 /* We sometimes cast u_buf to uint32_t[], hence the alignment constraint. */
 #define U_BUF_SZ 16384
 static uint8_t u_buf[U_BUF_SZ] aligned(4);
@@ -85,13 +70,13 @@ static void floppy_mcu_init(void)
     configure_pin(rdata, GPI_bus);
 
     /* Configure user-modifiable pins. */
-    for (upin = user_pins; upin->pin_id != 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,
                            GPO_bus);
     }
 
     /* Configure SELECT/MOTOR lines. */
-    for (mpin = msel_pins; mpin->pin_id != 0; mpin++) {
+    for (mpin = board_config->msel_pins; mpin->pin_id != 0; mpin++) {
         gpio_configure_pin(gpio_from_id(mpin->gpio_bank), mpin->gpio_pin,
                            GPO_bus);
     }
@@ -159,117 +144,6 @@ static void dma_wdata_start(void)
                     DMA_CR_EN);
 }
 
-static void drive_deselect(void)
-{
-    int pin = -1;
-    uint8_t rc;
-
-    if (unit_nr == -1)
-        return;
-
-    switch (bus_type) {
-    case BUS_IBMPC:
-        switch (unit_nr) {
-        case 0: pin = 14; break;
-        case 1: pin = 12; break;
-        }
-        break;
-    case BUS_SHUGART:
-        switch (unit_nr) {
-        case 0: pin = 10; break;
-        case 1: pin = 12; break;
-        case 2: pin = 14; break;
-        }
-        break;
-    }
-
-    rc = write_mapped_pin(msel_pins, pin, O_FALSE);
-    ASSERT(rc == ACK_OKAY);
-
-    unit_nr = -1;
-}
-
-static uint8_t drive_select(uint8_t nr)
-{
-    int pin = -1;
-    uint8_t rc;
-
-    if (nr == unit_nr)
-        return ACK_OKAY;
-
-    drive_deselect();
-
-    switch (bus_type) {
-    case BUS_IBMPC:
-        switch (nr) {
-        case 0: pin = 14; break;
-        case 1: pin = 12; break;
-        default: return ACK_BAD_UNIT;
-        }
-        break;
-    case BUS_SHUGART:
-        switch (nr) {
-        case 0: pin = 10; break;
-        case 1: pin = 12; break;
-        case 2: pin = 14; break;
-        default: return ACK_BAD_UNIT;
-        }
-        break;
-    default:
-        return ACK_NO_BUS;
-    }
-
-    rc = write_mapped_pin(msel_pins, pin, O_TRUE);
-    if (rc != ACK_OKAY)
-        return ACK_BAD_UNIT;
-
-    unit_nr = nr;
-    delay_us(delay_params.select_delay);
-
-    return ACK_OKAY;
-}
-
-static uint8_t drive_motor(uint8_t nr, bool_t on)
-{
-    int pin = -1;
-    uint8_t rc;
-
-    switch (bus_type) {
-    case BUS_IBMPC:
-        if (nr >= 2) 
-            return ACK_BAD_UNIT;
-        if (unit[nr].motor == on)
-            return ACK_OKAY;
-        switch (nr) {
-        case 0: pin = 10; break;
-        case 1: pin = 16; break;
-        }
-        break;
-    case BUS_SHUGART:
-        if (nr >= 3)
-            return ACK_BAD_UNIT;
-        /* All shugart units share one motor line. Alias them all to unit 0. */
-        nr = 0;
-        if (unit[nr].motor == on)
-            return ACK_OKAY;
-        pin = 16;
-        break;
-    default:
-        return ACK_NO_BUS;
-    }
-
-    rc = write_mapped_pin(msel_pins, pin, on ? O_TRUE : O_FALSE);
-    if (rc != ACK_OKAY)
-        return ACK_BAD_UNIT;
-
-    unit[nr].motor = on;
-    if (on)
-        delay_ms(delay_params.motor_delay);
-
-    return ACK_OKAY;
-
-}
-
 static uint8_t mcu_get_floppy_pin(unsigned int pin, uint8_t *p_level)
 {
     if (pin == 34) {
@@ -279,47 +153,12 @@ static uint8_t mcu_get_floppy_pin(unsigned int pin, uint8_t *p_level)
     return ACK_BAD_PIN;
 }
 
-static uint8_t set_user_pin(unsigned int pin, unsigned int level)
-{
-    const struct pin_mapping *upin;
-
-    for (upin = user_pins; upin->pin_id != 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 pin_mapping *upin;
-
-    for (upin = user_pins; upin->pin_id != 0; upin++)
-        gpio_write_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin, O_FALSE);
-}
-
 static void flippy_trk0_sensor(bool_t level)
 {
     gpio_write_pin(gpiob, 14, level);
     delay_us(10);
 }
 
-#define flippy_trk0_sensor_disable() flippy_trk0_sensor(HIGH)
-#define flippy_trk0_sensor_enable() flippy_trk0_sensor(LOW)
-
-static bool_t flippy_detect(void)
-{
-    bool_t is_flippy;
-    flippy_trk0_sensor_disable();
-    is_flippy = (get_trk0() == HIGH);
-    flippy_trk0_sensor_enable();
-    return is_flippy;
-}
-
 /*
  * Local variables:
  * mode: C

+ 2 - 24
src/mcu/at32f415/testmode.c

@@ -7,7 +7,7 @@
  * See the file COPYING for more details, or visit <http://unlicense.org>.
  */
 
-const static struct pin_mapping in_pins[] = {
+const struct pin_mapping testmode_in_pins[] = {
     {  8, _B, 10 },
     { 26, _B,  4 },
     { 28, _B,  3 },
@@ -16,7 +16,7 @@ const static struct pin_mapping in_pins[] = {
     {  0,  0,  0 }
 };
 
-const static struct pin_mapping out_pins[] = {
+const struct pin_mapping testmode_out_pins[] = {
     { 18, _B,  8 },
     { 20, _B,  6 },
     { 22, _A,  2 },
@@ -26,28 +26,6 @@ const static struct pin_mapping out_pins[] = {
     {  0,  0,  0 }
 };
 
-extern const struct pin_mapping msel_pins[];
-extern const struct pin_mapping user_pins[];
-
-void testmode_set_pin(unsigned int pin, bool_t level)
-{
-    int rc;
-    rc = write_mapped_pin(out_pins, pin, level);
-    if (rc != ACK_OKAY)
-        rc = write_mapped_pin(msel_pins, pin, level);
-    if (rc != ACK_OKAY)
-        rc = write_mapped_pin(user_pins, pin, level);
-}
-
-bool_t testmode_get_pin(unsigned int pin)
-{
-    bool_t level;
-    int rc = read_mapped_pin(in_pins, pin, &level);
-    if (rc != ACK_OKAY)
-        level = FALSE;
-    return level;
-}
-
 void testmode_get_option_bytes(void *buf)
 {
     memcpy(buf, (void *)0x1ffff800, 16);

+ 124 - 3
src/mcu/stm32f1/board.c

@@ -12,11 +12,132 @@
 #define gpio_led gpioc
 #define pin_led 13
 
+const static struct pin_mapping _msel_pins_std[] = {
+    { 10, _B, 11 },
+    { 14, _B, 10 },
+    {  0,  0,  0 }
+};
+
+const static struct pin_mapping _msel_pins_f1_plus[] = {
+    { 10, _B, 11 },
+    { 12, _B,  0 },
+    { 14, _B, 10 },
+    { 16, _B,  1 },
+    {  0,  0,  0 }
+};
+
+const static struct pin_mapping _user_pins_std[] = {
+    { 2, _B,  9, _OD },
+    { 0,  0,  0, _OD } };
+const static struct pin_mapping _user_pins_f1_plus[] = {
+    { 2, _B,  9, _PP },
+    { 4, _A,  3, _PP },
+    { 6, _A,  1, _PP },
+    { 0,  0,  0, _PP } };
+
+const static struct board_config _board_config[] = {
+    [F1SM_basic] = {
+        .flippy    = FALSE,
+        .user_pins = _user_pins_std,
+        .msel_pins = _msel_pins_std },
+    [F1SM_plus] = {
+        .flippy    = TRUE,
+        .user_pins = _user_pins_f1_plus,
+        .msel_pins = _msel_pins_f1_plus }
+};
+
+/* Blink the activity LED to indicate fatal error. */
+static void blink_fatal(int blinks)
+{
+    int i;
+    gpio_configure_pin(gpio_led, pin_led, GPO_pushpull(IOSPD_LOW, HIGH));
+    for (;;) {
+        for (i = 0; i < blinks; i++) {
+            gpio_write_pin(gpio_led, pin_led, LOW);
+            delay_ms(150);
+            gpio_write_pin(gpio_led, pin_led, HIGH);
+            delay_ms(150);
+        }
+        delay_ms(2000);
+    }
+}
+
+static void identify_board_config(void)
+{
+    uint16_t low, high;
+    uint8_t id = 0;
+    int i;
+
+    /* Pull PC[15:14] low, and check which are tied HIGH. */
+    for (i = 0; i < 2; i++)
+        gpio_configure_pin(gpioc, 14+i, GPI_pull_down);
+    delay_us(10);
+    high = (gpioc->idr >> 14) & 3;
+
+    /* Pull PC[15:14] high, and check which are tied LOW. */
+    for (i = 0; i < 2; i++)
+        gpio_configure_pin(gpioc, 14+i, GPI_pull_up);
+    delay_us(10);
+    low = (~gpioc->idr >> 14) & 3;
+
+    /* Each PCx pin defines a 'trit': 0=float, 1=low, 2=high. 
+     * We build a 2^3 ID space from the resulting two-trit ID. */
+    for (i = 0; i < 2; i++) {
+        id *= 3;
+        switch ((high&2) | (low>>1&1)) {
+        case 0: break;          /* float = 0 */
+        case 1: id += 1; break; /* LOW   = 1 */
+        case 2: id += 2; break; /* HIGH  = 2 */
+        case 3: blink_fatal(1); /* cannot be tied HIGH *and* LOW! */
+        }
+        high <<= 1;
+        low <<= 1;
+    }
+
+    /* Panic if the ID is unrecognised. */
+    if (id >= ARRAY_SIZE(_board_config))
+        blink_fatal(2);
+
+    gw_info.hw_submodel = id;
+    board_config = &_board_config[id];
+}
+
 static void mcu_board_init(void)
 {
-    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 */
+    uint16_t pu[] = {
+        [_A] = 0xe1fe, /* PA1-8,13-15 */
+        [_B] = 0x0e27, /* PB0-2,5,9-11 */
+        [_C] = 0xffff, /* PC0-15 */
+    };
+    const struct pin_mapping *mpin;
+    const struct pin_mapping *upin;
+
+    identify_board_config();
+
+    /* MSEL pins: do not default these pins to pull-up mode. */
+    for (mpin = board_config->msel_pins; mpin->pin_id != 0; mpin++)
+        pu[mpin->gpio_bank] &= ~(1u << mpin->gpio_pin);
+
+    /* User pins: do not default these pins to pull-up mode. */
+    for (upin = board_config->user_pins; upin->pin_id != 0; upin++)
+        pu[upin->gpio_bank] &= ~(1u << upin->gpio_pin);
+
+    /* Flippy TRK0_DISABLE output: Set inactive (LOW). */
+    if (board_config->flippy) {
+        gpio_configure_pin(gpioa, 2, GPO_pushpull(IOSPD_LOW, LOW));
+        pu[_A] &= ~(1u << 2); /* PA2 */
+    }
+
+    switch (gw_info.hw_submodel) {
+    case F1SM_plus:
+        /* /RDY input line is externally pulled up. */
+        pu[_A] &= ~(1u << 8); /* PA8 */
+        break;
+    }
+
+    gpio_pull_up_pins(gpioa, pu[_A]);
+    gpio_pull_up_pins(gpiob, pu[_B]);
+    gpio_pull_up_pins(gpioc, pu[_C]);
 }
 
 /*

+ 50 - 55
src/mcu/stm32f1/floppy.c

@@ -12,8 +12,12 @@
 #define O_FALSE 1
 #define O_TRUE  0
 
-#define GPO_bus GPO_opendrain(_2MHz,O_FALSE)
-#define AFO_bus AFO_opendrain(_2MHz)
+#define GPO_bus_pp GPO_pushpull(_2MHz,O_FALSE)
+#define AFO_bus_pp AFO_pushpull(_2MHz)
+#define GPO_bus_od GPO_opendrain(_2MHz,O_FALSE)
+#define AFO_bus_od AFO_opendrain(_2MHz)
+static unsigned int GPO_bus;
+static unsigned int AFO_bus;
 static unsigned int GPI_bus;
 
 /* Input pins */
@@ -63,10 +67,21 @@ static uint8_t u_buf[U_BUF_SZ] aligned(4);
 
 static void floppy_mcu_init(void)
 {
-    /* Determine whether input pins must be internally pulled down. */
-    configure_pin(index, GPI_pull_down);
-    delay_us(10);
-    GPI_bus = (get_index() == LOW) ? GPI_pull_up : GPI_floating;
+    const struct pin_mapping *mpin;
+    const struct pin_mapping *upin;
+
+    switch (gw_info.hw_submodel) {
+    case F1SM_basic:
+        /* Determine whether input pins must be internally pulled down. */
+        configure_pin(index, GPI_pull_down);
+        delay_us(10);
+        GPI_bus = (get_index() == LOW) ? GPI_pull_up : GPI_floating;
+        break;
+    case F1SM_plus:
+        GPI_bus = GPI_floating;
+        break;
+    }
+
     printk("Floppy Inputs: %sternal Pullup\n",
            (GPI_bus == GPI_pull_up) ? "In" : "Ex");
 
@@ -74,17 +89,26 @@ static void floppy_mcu_init(void)
     afio->mapr |= (AFIO_MAPR_TIM2_REMAP_PARTIAL_1
                    | AFIO_MAPR_TIM3_REMAP_PARTIAL);
 
-    /* Set up EXTI mapping for INDEX: PB[15:0] -> EXT[15:0] */
-    afio->exticr1 = afio->exticr2 = afio->exticr3 = afio->exticr4 = 0x1111;
-
     configure_pin(rdata, GPI_bus);
 
+    /* Configure user-modifiable pins. */
+    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);
+    }
+
+    /* 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(sel, GPO_bus);
-    configure_pin(mot, GPO_bus);
+    for (mpin = board_config->msel_pins; mpin->pin_id != 0; mpin++) {
+        gpio_configure_pin(gpio_from_id(mpin->gpio_bank), mpin->gpio_pin,
+                           GPO_bus);
+    }
 
-    /* Configure user-modifiable lines. */
-    configure_pin(densel, GPO_bus);
+    /* Set up EXTI mapping for INDEX: PB[15:0] -> EXT[15:0] */
+    afio->exticr1 = afio->exticr2 = afio->exticr3 = afio->exticr4 = 0x1111;
 }
 
 static void rdata_prep(void)
@@ -146,56 +170,27 @@ static void dma_wdata_start(void)
                     DMA_CR_EN);
 }
 
-static void drive_deselect(void)
-{
-    write_pin(sel, FALSE);
-    unit_nr = -1;
-}
-
-static uint8_t drive_select(uint8_t nr)
-{
-    write_pin(sel, TRUE);
-    unit_nr = 0;
-    delay_us(delay_params.select_delay);
-    return ACK_OKAY;
-}
-
-static uint8_t drive_motor(uint8_t nr, bool_t on)
-{
-    if (unit[0].motor == on)
-        return ACK_OKAY;
-
-    write_pin(mot, on);
-    unit[0].motor = on;
-    if (on)
-        delay_ms(delay_params.motor_delay);
-
-    return ACK_OKAY;
-}
-
 static uint8_t mcu_get_floppy_pin(unsigned int pin, uint8_t *p_level)
 {
+    switch (gw_info.hw_submodel) {
+    case F1SM_plus:
+        if (pin == 34) {
+            *p_level = gpio_read_pin(gpioa, 8);
+            return ACK_OKAY;
+        }
+        break;
+    }
     return ACK_BAD_PIN;
 }
 
-static uint8_t set_user_pin(unsigned int pin, unsigned int level)
+static void flippy_trk0_sensor(bool_t level)
 {
-    if (pin != 2)
-        return ACK_BAD_PIN;
-    gpio_write_pin(gpio_densel, pin_densel, level);
-    return ACK_OKAY;
+    if (board_config->flippy) {
+        gpio_write_pin(gpioa, 2, level);
+        delay_us(10);
+    }
 }
 
-static void reset_user_pins(void)
-{
-    write_pin(densel, FALSE);
-}
-
-/* No Flippy-modded drive support on F1 boards. */
-#define flippy_trk0_sensor_disable() ((void)0)
-#define flippy_trk0_sensor_enable() ((void)0)
-#define flippy_detect() FALSE
-
 /*
  * Local variables:
  * mode: C

+ 0 - 1
src/mcu/stm32f7/board.c

@@ -100,7 +100,6 @@ const static struct board_config _board_config[] = {
         .user_pins = _user_pins_F7SM_v3,
         .msel_pins = _msel_pins_std },
 };
-const struct board_config *board_config;
 
 /* Blink the activity LED to indicate fatal error. */
 void early_fatal(int blinks)

+ 0 - 146
src/mcu/stm32f7/floppy.c

@@ -154,117 +154,6 @@ static void dma_wdata_start(void)
     dma_wdata.cr |= DMA_CR_EN;
 }
 
-static void drive_deselect(void)
-{
-    int pin = -1;
-    uint8_t rc;
-
-    if (unit_nr == -1)
-        return;
-
-    switch (bus_type) {
-    case BUS_IBMPC:
-        switch (unit_nr) {
-        case 0: pin = 14; break;
-        case 1: pin = 12; break;
-        }
-        break;
-    case BUS_SHUGART:
-        switch (unit_nr) {
-        case 0: pin = 10; break;
-        case 1: pin = 12; break;
-        case 2: pin = 14; break;
-        }
-        break;
-    }
-
-    rc = write_mapped_pin(board_config->msel_pins, pin, O_FALSE);
-    ASSERT(rc == ACK_OKAY);
-
-    unit_nr = -1;
-}
-
-static uint8_t drive_select(uint8_t nr)
-{
-    int pin = -1;
-    uint8_t rc;
-
-    if (nr == unit_nr)
-        return ACK_OKAY;
-
-    drive_deselect();
-
-    switch (bus_type) {
-    case BUS_IBMPC:
-        switch (nr) {
-        case 0: pin = 14; break;
-        case 1: pin = 12; break;
-        default: return ACK_BAD_UNIT;
-        }
-        break;
-    case BUS_SHUGART:
-        switch (nr) {
-        case 0: pin = 10; break;
-        case 1: pin = 12; break;
-        case 2: pin = 14; break;
-        default: return ACK_BAD_UNIT;
-        }
-        break;
-    default:
-        return ACK_NO_BUS;
-    }
-
-    rc = write_mapped_pin(board_config->msel_pins, pin, O_TRUE);
-    if (rc != ACK_OKAY)
-        return ACK_BAD_UNIT;
-
-    unit_nr = nr;
-    delay_us(delay_params.select_delay);
-
-    return ACK_OKAY;
-}
-
-static uint8_t drive_motor(uint8_t nr, bool_t on)
-{
-    int pin = -1;
-    uint8_t rc;
-
-    switch (bus_type) {
-    case BUS_IBMPC:
-        if (nr >= 2) 
-            return ACK_BAD_UNIT;
-        if (unit[nr].motor == on)
-            return ACK_OKAY;
-        switch (nr) {
-        case 0: pin = 10; break;
-        case 1: pin = 16; break;
-        }
-        break;
-    case BUS_SHUGART:
-        if (nr >= 3)
-            return ACK_BAD_UNIT;
-        /* All shugart units share one motor line. Alias them all to unit 0. */
-        nr = 0;
-        if (unit[nr].motor == on)
-            return ACK_OKAY;
-        pin = 16;
-        break;
-    default:
-        return ACK_NO_BUS;
-    }
-
-    rc = write_mapped_pin(board_config->msel_pins, pin, on ? O_TRUE : O_FALSE);
-    if (rc != ACK_OKAY)
-        return ACK_BAD_UNIT;
-
-    unit[nr].motor = on;
-    if (on)
-        delay_ms(delay_params.motor_delay);
-
-    return ACK_OKAY;
-
-}
-
 static uint8_t mcu_get_floppy_pin(unsigned int pin, uint8_t *p_level)
 {
     switch (gw_info.hw_submodel) {
@@ -279,29 +168,6 @@ static uint8_t mcu_get_floppy_pin(unsigned int pin, uint8_t *p_level)
     return ACK_BAD_PIN;
 }
 
-static uint8_t set_user_pin(unsigned int pin, unsigned int level)
-{
-    const struct pin_mapping *upin;
-
-    for (upin = board_config->user_pins; upin->pin_id != 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 pin_mapping *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);
-}
-
 static void flippy_trk0_sensor(bool_t level)
 {
     if (board_config->flippy) {
@@ -310,18 +176,6 @@ static void flippy_trk0_sensor(bool_t level)
     }
 }
 
-#define flippy_trk0_sensor_disable() flippy_trk0_sensor(HIGH)
-#define flippy_trk0_sensor_enable() flippy_trk0_sensor(LOW)
-
-static bool_t flippy_detect(void)
-{
-    bool_t is_flippy;
-    flippy_trk0_sensor_disable();
-    is_flippy = (get_trk0() == HIGH);
-    flippy_trk0_sensor_enable();
-    return is_flippy;
-}
-
 /*
  * Local variables:
  * mode: C

+ 2 - 21
src/mcu/stm32f7/testmode.c

@@ -7,7 +7,7 @@
  * See the file COPYING for more details, or visit <http://unlicense.org>.
  */
 
-const static struct pin_mapping in_pins[] = {
+const struct pin_mapping testmode_in_pins[] = {
     {  8, _B,  2 },
     { 26, _A,  3 },
     { 28, _A,  1 },
@@ -16,7 +16,7 @@ const static struct pin_mapping in_pins[] = {
     {  0,  0,  0 }
 };
 
-const static struct pin_mapping out_pins[] = {
+const struct pin_mapping testmode_out_pins[] = {
     { 18, _C,  4 },
     { 20, _A,  7 },
     { 22, _A,  2 },
@@ -26,25 +26,6 @@ const static struct pin_mapping out_pins[] = {
     {  0,  0,  0 }
 };
 
-void testmode_set_pin(unsigned int pin, bool_t level)
-{
-    int rc;
-    rc = write_mapped_pin(out_pins, pin, level);
-    if (rc != ACK_OKAY)
-        rc = write_mapped_pin(board_config->msel_pins, pin, level);
-    if (rc != ACK_OKAY)
-        rc = write_mapped_pin(board_config->user_pins, pin, level);
-}
-
-bool_t testmode_get_pin(unsigned int pin)
-{
-    bool_t level;
-    int rc = read_mapped_pin(in_pins, pin, &level);
-    if (rc != ACK_OKAY)
-        level = FALSE;
-    return level;
-}
-
 void testmode_get_option_bytes(void *buf)
 {
     memcpy(buf, (void *)0x1fff0000, 32);

+ 21 - 2
src/testmode.c

@@ -30,10 +30,29 @@ struct rsp {
 #define TEST_BIT(p,n) (!!((p)[(n)/8] & (1<<((n)&7))))
 #define SET_BIT(p,n) ((p)[(n)/8] |= (1<<((n)&7)))
 
-void testmode_set_pin(unsigned int pin, bool_t level);
-bool_t testmode_get_pin(unsigned int pin);
+extern struct pin_mapping testmode_in_pins[];
+extern struct pin_mapping testmode_out_pins[];
 void testmode_get_option_bytes(void *buf);
 
+static void testmode_set_pin(unsigned int pin, bool_t level)
+{
+    int rc;
+    rc = write_mapped_pin(testmode_out_pins, pin, level);
+    if (rc != ACK_OKAY)
+        rc = write_mapped_pin(board_config->msel_pins, pin, level);
+    if (rc != ACK_OKAY)
+        rc = write_mapped_pin(board_config->user_pins, pin, level);
+}
+
+static bool_t testmode_get_pin(unsigned int pin)
+{
+    bool_t level;
+    int rc = read_mapped_pin(testmode_in_pins, pin, &level);
+    if (rc != ACK_OKAY)
+        level = FALSE;
+    return level;
+}
+
 static void set_pins(uint8_t *pins)
 {
     int i;