mirror of
https://github.com/keirf/greaseweazle-firmware.git
synced 2025-10-31 11:06:44 -07:00
F1: Introduce new submodel "F1 Plus"
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
src/floppy.c
146
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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 SELECT/MOTOR lines. */
|
||||
configure_pin(sel, GPO_bus);
|
||||
configure_pin(mot, GPO_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 user-modifiable lines. */
|
||||
configure_pin(densel, GPO_bus);
|
||||
/* 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. */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user