Compare commits

...

3 commits

Author SHA1 Message Date
48168fe82c
I needed a different number of NOPs 2022-01-24 17:29:35 -06:00
lady ada
e363e35b80 write fluxes 2022-01-20 15:28:41 -05:00
ladyada
b293703f13 fix index pulse output for greaseweazle and start fluxwrite support 2022-01-18 11:29:23 -05:00
3 changed files with 642 additions and 532 deletions

View file

@ -85,6 +85,7 @@ uint8_t cmd_buff_idx = 0;
#define GW_CMD_GETPARAMS_DELAYS 0
#define GW_CMD_MOTOR 6
#define GW_CMD_READFLUX 7
#define GW_CMD_WRITEFLUX 8
#define GW_CMD_GETFLUXSTATUS 9
#define GW_CMD_SELECT 12
#define GW_CMD_DESELECT 13
@ -162,7 +163,7 @@ void loop() {
memset(reply_buffer, 0, sizeof(reply_buffer));
reply_buffer[i++] = cmd; // echo back the cmd itself
Serial1.printf("Got command 0x%02x\n\r", cmd);
Serial1.printf("Got command 0x%02x of length %d\n\r", cmd, cmd_buffer[1]);
if (cmd == GW_CMD_GETINFO) {
Serial1.println("Get info");
@ -334,25 +335,52 @@ void loop() {
reply_buffer[i++] = GW_ACK_OK;
Serial.write(reply_buffer, 2);
while (revs--) {
captured_pulses = floppy.capture_track(flux_transitions, sizeof(flux_transitions));
Serial1.printf("Rev #%d captured %u pulses\n\r", revs, captured_pulses);
uint32_t index_offset;
captured_pulses = floppy.capture_track(flux_transitions, sizeof(flux_transitions), &index_offset);
Serial1.printf("Rev #%d captured %u pulses, second index fall @ %d\n\r",
revs, captured_pulses, index_offset);
//floppy.print_pulse_bins(flux_transitions, captured_pulses, 64, Serial1);
// trim down extra long pulses
for (uint32_t f=0; f<captured_pulses; f++) {
if (flux_transitions[f] > 250) {
flux_transitions[f] = 250;
// MEME FIX: in theory, we can 'pack' longer flux transitions
// with modulo 250 byte math but we're lazy right now
if (flux_transitions[f] > 249) {
Serial1.printf("*** Extra long pulse encountered ***\n\r");
flux_transitions[f] = 249;
}
}
// Send the index opcode, which is right at the start of this data xfer
reply_buffer[0] = 0xFF;
// Send the index falling signal opcode, which was right
// at the start of this data xfer (we wait for index to fall
// before we start reading
reply_buffer[0] = 0xFF; // FLUXOP INDEX
reply_buffer[1] = 1; // index opcode
reply_buffer[2] = 0x1;
reply_buffer[3] = 0x1;
reply_buffer[4] = 0x1;
reply_buffer[5] = 0x1; // 0 are special, so we send 1 to == 0
reply_buffer[2] = 0x1; // 0 are special, so we send 1's to == 0
reply_buffer[3] = 0x1; // ""
reply_buffer[4] = 0x1; // ""
reply_buffer[5] = 0x1; // ""
Serial.write(reply_buffer, 6);
uint8_t *flux_ptr = flux_transitions;
// send all data until the flux transition
while (index_offset) {
uint32_t to_send = min(index_offset, (uint32_t)256);
Serial.write(flux_ptr, to_send);
//Serial1.println(to_send);
flux_ptr += to_send;
captured_pulses -= to_send;
index_offset -= to_send;
}
// we interrupt this broadcast for a flux op index
reply_buffer[0] = 0xFF; // FLUXOP INDEX
reply_buffer[1] = 1; // index opcode
reply_buffer[2] = 0x1; // 0 are special, so we send 1's to == 0
reply_buffer[3] = 0x1; // ""
reply_buffer[4] = 0x1; // ""
reply_buffer[5] = 0x1; // ""
Serial.write(reply_buffer, 6);
// send remaining data until the flux transition
while (captured_pulses) {
uint32_t to_send = min(captured_pulses, (uint32_t)256);
Serial.write(flux_ptr, to_send);
@ -362,20 +390,43 @@ void loop() {
}
}
// send a final indexop
reply_buffer[0] = 0xFF;
reply_buffer[1] = 1; // index opcode
reply_buffer[2] = 0x1;
reply_buffer[3] = 0x1;
reply_buffer[4] = 0x1;
reply_buffer[5] = 0x1; // 0 are special, so we send 1 to == 0
Serial.write(reply_buffer, 6);
// flush input, to account for fluxengine bug
while (Serial.available()) Serial.read();
// THE END
Serial.write((byte)0);
}
else if (cmd == GW_CMD_WRITEFLUX) {
Serial1.println("write flux");
uint8_t cue_at_index = cmd_buffer[2];
uint8_t terminate_at_index = cmd_buffer[3];
reply_buffer[i++] = GW_ACK_OK;
Serial.write(reply_buffer, 2);
uint32_t fluxors = 0;
uint8_t flux = 0xFF;
while (flux && (fluxors < MAX_FLUX_PULSE_PER_TRACK)) {
while (!Serial.available()) yield();
flux = Serial.read();
flux_transitions[fluxors++] = flux;
}
if (fluxors == MAX_FLUX_PULSE_PER_TRACK) {
Serial1.println("*** FLUX OVERRUN ***");
while(1) yield();
}
Serial1.printf("Read in %d flux transitions\n\r", fluxors);
for (uint32_t i=0; i<fluxors; i++) {
uint8_t flux = flux_transitions[i];
if (flux >= 250) { // a fluxop!
Serial1.printf("Fluxop 0x%x at %d\n\r", flux, i);
}
}
floppy.print_pulse_bins(flux_transitions, fluxors-7, 64);
floppy.write_track(flux_transitions, fluxors-7);
Serial1.println("wrote fluxors");
Serial.write((byte)0);
}
else if (cmd == GW_CMD_GETFLUXSTATUS) {
Serial1.println("get flux status");
reply_buffer[i++] = GW_ACK_OK;

View file

@ -1,6 +1,6 @@
#include "Adafruit_Floppy.h"
#define DEBUG_FLOPPY (0)
#define DEBUG_FLOPPY (1)
// We need to read and write some pins at optimized speeds - use raw registers
// or native SDK API!
@ -9,6 +9,8 @@
#define read_data() (*dataPort & dataMask)
#define set_debug_led() (*ledPort |= ledMask)
#define clr_debug_led() (*ledPort &= ~ledMask)
#define set_write() (*writePort |= writeMask)
#define clr_write() (*writePort &= ~writeMask)
#elif defined(ARDUINO_ARCH_RP2040)
#define read_index() gpio_get(_indexpin)
#define read_data() gpio_get(_rddatapin)
@ -358,7 +360,7 @@ uint32_t Adafruit_Floppy::read_track_mfm(uint8_t *sectors, size_t n_sectors,
@return Number of pulses we actually captured
*/
/**************************************************************************/
uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) {
uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses, uint32_t *falling_index_offset) {
unsigned pulse_count;
uint8_t *pulses_ptr = pulses;
uint8_t *pulses_end = pulses + max_pulses;
@ -403,9 +405,13 @@ uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) {
// ahh a L to H transition
if (!last_index_state && index_state) {
index_transitions++;
if (index_transitions ==
2) // and its the second one, so we're done with this track!
break;
if (index_transitions == 2)
break; // and its the second one, so we're done with this track!
}
// ooh a H to L transition, thats 1 revolution
else if (last_index_state && !index_state) {
// we'll keep track of when it happened
*falling_index_offset = (pulses_ptr - pulses);
}
last_index_state = index_state;
@ -437,6 +443,57 @@ uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) {
return pulses_ptr - pulses;
}
void Adafruit_Floppy::write_track(uint8_t *pulses, uint32_t num_pulses) {
unsigned pulse_count, pulse_count2;
uint8_t *pulses_ptr = pulses;
#ifdef BUSIO_USE_FAST_PINIO
BusIO_PortReg *writePort, *ledPort;
BusIO_PortMask writeMask, ledMask;
writePort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(_wrdatapin));
writeMask = digitalPinToBitMask(_wrdatapin);
ledPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(led_pin));
ledMask = digitalPinToBitMask(led_pin);
(void)ledPort;
(void)ledMask;
#endif
pinMode(_wrdatapin, OUTPUT);
digitalWrite(_wrdatapin, HIGH);
pinMode(_wrgatepin, OUTPUT);
digitalWrite(_wrgatepin, HIGH);
noInterrupts();
wait_for_index_pulse_low();
digitalWrite(_wrgatepin, LOW);
// write track data
while (num_pulses--) {
pulse_count = pulses_ptr[0];
pulses_ptr++;
// ?? lets bail
if (pulse_count == 0) break;
clr_write();
pulse_count -= 11;
while(pulse_count--) {
asm("nop; nop; nop; nop; nop;");
}
set_write();
pulse_count = 8;
while(pulse_count--) {
asm("nop; nop; nop; nop; nop; nop; nop; nop; nop;");
}
}
// whew done
digitalWrite(_wrgatepin, HIGH);
digitalWrite(_wrdatapin, HIGH);
interrupts();
return;
}
/**************************************************************************/
/*!
@brief Busy wait until the index line goes from high to low

View file

@ -67,8 +67,10 @@ public:
uint32_t read_track_mfm(uint8_t *sectors, size_t n_sectors,
uint8_t *sector_validity);
uint32_t capture_track(uint8_t *pulses, uint32_t max_pulses)
uint32_t capture_track(uint8_t *pulses, uint32_t max_pulses,
uint32_t *index_offset)
__attribute__((optimize("O3")));
void write_track(uint8_t *pulses, uint32_t num_pulses) __attribute__((optimize("O3")));
void print_pulse_bins(uint8_t *pulses, uint32_t num_pulses,
uint8_t max_bins = 64);
void print_pulses(uint8_t *pulses, uint32_t num_pulses);