|
| 1 | +#include <Adafruit_SPIDevice.h> |
| 2 | + |
| 3 | +static const int pulseDelayTime = 6; |
| 4 | + |
| 5 | +#define DENSITY_PIN 5 // IDC 2 |
| 6 | +// IDC 4 no connect |
| 7 | +// IDC 6 no connect |
| 8 | +#define INDEX_PIN 6 // IDC 8 |
| 9 | +// IDC 10 no connect |
| 10 | +#define SELECT_PIN A5 // IDC 12 |
| 11 | +// IDC 14 no connect |
| 12 | +#define MOTOR_PIN 9 // IDC 16 |
| 13 | +#define DIR_PIN 10 // IDC 18 |
| 14 | +#define STEP_PIN 11 // IDC 20 |
| 15 | +#define READY_PIN A0 // IDC 22 |
| 16 | +#define SIDE_PIN A1 // IDC |
| 17 | +#define READ_PIN 12 |
| 18 | +#define PROT_PIN A3 |
| 19 | +#define TRK0_PIN A4 |
| 20 | + |
| 21 | +#define MAX_FLUX_PULSE_PER_TRACK (500000 / 5) // 500khz / 5 hz per track rotation |
| 22 | +#define STEP_OUT HIGH |
| 23 | +#define STEP_IN LOW |
| 24 | + |
| 25 | +#define LED_PIN 13 |
| 26 | + |
| 27 | +BusIO_PortReg *indexPort, *dataPort, *ledPort; |
| 28 | +BusIO_PortMask indexMask, dataMask, ledMask; |
| 29 | + |
| 30 | +inline bool read_index(void) { |
| 31 | + return *indexPort & indexMask; |
| 32 | +} |
| 33 | +inline bool read_data(void) { |
| 34 | + return *dataPort & dataMask; |
| 35 | +} |
| 36 | + |
| 37 | +void setup() { |
| 38 | + Serial.begin(115200); |
| 39 | + while (!Serial) delay(100); |
| 40 | + pinMode(LED_PIN, OUTPUT); |
| 41 | + |
| 42 | + // deselect drive |
| 43 | + pinMode(SELECT_PIN, OUTPUT); |
| 44 | + digitalWrite(SELECT_PIN, HIGH); |
| 45 | + |
| 46 | + // motor enable pin, drive low to turn on motor |
| 47 | + pinMode(MOTOR_PIN, OUTPUT); |
| 48 | + digitalWrite(MOTOR_PIN, HIGH); |
| 49 | + |
| 50 | + // set motor direction (low is in, high is out) |
| 51 | + pinMode(DIR_PIN, OUTPUT); |
| 52 | + digitalWrite(DIR_PIN, LOW); // move inwards to start |
| 53 | + |
| 54 | + // step track pin, pulse low for 3us min, 3ms max per pulse |
| 55 | + pinMode(STEP_PIN, OUTPUT); |
| 56 | + digitalWrite(STEP_PIN, HIGH); |
| 57 | + |
| 58 | + // side selector |
| 59 | + pinMode(SIDE_PIN, OUTPUT); |
| 60 | + digitalWrite(STEP_PIN, HIGH); // side 0 to start |
| 61 | + |
| 62 | + pinMode(INDEX_PIN, INPUT_PULLUP); |
| 63 | + pinMode(TRK0_PIN, INPUT_PULLUP); |
| 64 | + pinMode(PROT_PIN, INPUT_PULLUP); |
| 65 | + pinMode(READY_PIN, INPUT_PULLUP); |
| 66 | + pinMode(READ_PIN, INPUT_PULLUP); |
| 67 | + |
| 68 | + indexPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(INDEX_PIN)); |
| 69 | + indexMask = digitalPinToBitMask(INDEX_PIN); |
| 70 | + dataPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(READ_PIN)); |
| 71 | + dataMask = digitalPinToBitMask(READ_PIN); |
| 72 | + ledPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(LED_PIN)); |
| 73 | + ledMask = digitalPinToBitMask(LED_PIN); |
| 74 | + |
| 75 | + Serial.println("its time for a nice floppy transfer!"); |
| 76 | + |
| 77 | + digitalWrite(SELECT_PIN, HIGH); |
| 78 | + delay(100); |
| 79 | + // Main motor turn on |
| 80 | + digitalWrite(MOTOR_PIN, LOW); |
| 81 | + // Select drive |
| 82 | + digitalWrite(SELECT_PIN, LOW); |
| 83 | + delay(1000); |
| 84 | + /* |
| 85 | + Serial.print("Seeking track 00..."); |
| 86 | + if (! goto_track(0)) { |
| 87 | + Serial.println("Failed to get to track 0"); |
| 88 | + while (1); |
| 89 | + } |
| 90 | + Serial.println("done!"); |
| 91 | +*/ |
| 92 | +} |
| 93 | +uint32_t time_stamp = 0; |
| 94 | + |
| 95 | +void wait_for_index_pulse_low(void) { |
| 96 | + // initial state |
| 97 | + bool index_state = read_index(); |
| 98 | + bool last_index_state = index_state; |
| 99 | + |
| 100 | + // wait until last index state is H and current state is L |
| 101 | + while (true) { |
| 102 | + index_state = read_index(); |
| 103 | + if (last_index_state && !index_state) { |
| 104 | + return; |
| 105 | + } |
| 106 | + last_index_state = index_state; |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +void capture_track(void) { |
| 111 | + uint8_t pulse_count; |
| 112 | + uint8_t pulses[MAX_FLUX_PULSE_PER_TRACK]; |
| 113 | + uint8_t *pulses_ptr = pulses; |
| 114 | + |
| 115 | + memset(pulses, 0, MAX_FLUX_PULSE_PER_TRACK); // zero zem out |
| 116 | + |
| 117 | + noInterrupts(); |
| 118 | + wait_for_index_pulse_low(); |
| 119 | + |
| 120 | + // ok we have a h-to-l transition so... |
| 121 | + bool last_index_state = read_index(); |
| 122 | + while (true) { |
| 123 | + bool index_state = read_index(); |
| 124 | + // ahh another H to L transition, we're done with this track! |
| 125 | + if (last_index_state && !index_state) { |
| 126 | + break; |
| 127 | + } |
| 128 | + last_index_state = index_state; |
| 129 | + |
| 130 | + // muahaha, now we can read track data! |
| 131 | + pulse_count = 0; |
| 132 | + // while pulse is in the low pulse, count up |
| 133 | + while (!read_data()) pulse_count++; |
| 134 | + *ledPort |= ledMask; |
| 135 | + |
| 136 | + // while pulse is high, keep counting up |
| 137 | + while (read_data()) pulse_count++; |
| 138 | + *ledPort &= ~ledMask; |
| 139 | + |
| 140 | + pulses_ptr[0] = pulse_count; |
| 141 | + pulses_ptr++; |
| 142 | + } |
| 143 | + // whew done |
| 144 | + interrupts(); |
| 145 | + |
| 146 | + int32_t num_pulses = pulses_ptr - pulses; |
| 147 | + Serial.print("Captured "); |
| 148 | + Serial.print(num_pulses); |
| 149 | + Serial.println(" flux transitions"); |
| 150 | + |
| 151 | + for (uint32_t i=0; i<num_pulses; i++) { |
| 152 | + Serial.print(pulses[i]); |
| 153 | + Serial.print(", "); |
| 154 | + } |
| 155 | + Serial.println(); |
| 156 | +} |
| 157 | + |
| 158 | +void loop() { |
| 159 | + capture_track(); |
| 160 | + |
| 161 | + if ((millis() - time_stamp) > 1000) { |
| 162 | + Serial.print("Ready? "); |
| 163 | + Serial.println(digitalRead(READY_PIN) ? "No" : "Yes"); |
| 164 | + Serial.print("Write Protected? "); |
| 165 | + Serial.println(digitalRead(PROT_PIN) ? "No" : "Yes"); |
| 166 | + Serial.print("Track 0? "); |
| 167 | + Serial.println(digitalRead(TRK0_PIN) ? "No" : "Yes"); |
| 168 | + time_stamp = millis(); |
| 169 | + } |
| 170 | + |
| 171 | +} |
| 172 | + |
| 173 | + |
| 174 | + |
| 175 | + |
| 176 | + |
| 177 | + |
| 178 | + |
| 179 | + |
| 180 | +void step(bool dir, uint8_t times) { |
| 181 | + digitalWrite(DIR_PIN, dir); |
| 182 | + delayMicroseconds(10); // 1 microsecond, but we're generous |
| 183 | + |
| 184 | + while (times--) { |
| 185 | + digitalWrite(STEP_PIN, HIGH); |
| 186 | + delay(2); // 3ms min per step |
| 187 | + digitalWrite(STEP_PIN, LOW); |
| 188 | + delay(2); // 3ms min per step |
| 189 | + digitalWrite(STEP_PIN, HIGH); // end high |
| 190 | + } |
| 191 | +} |
| 192 | + |
| 193 | +bool goto_track(uint8_t track_num) { |
| 194 | + if (track_num == 0) { |
| 195 | + uint8_t max_steps = 30; |
| 196 | + while (max_steps-- && digitalRead(TRK0_PIN)) { |
| 197 | + step(STEP_OUT, 1); |
| 198 | + } |
| 199 | + return (max_steps == 0); |
| 200 | + } |
| 201 | + if (!goto_track(0)) return false; |
| 202 | + step(STEP_IN, max(track_num, 159)); |
| 203 | +} |
0 commit comments