Merge pull request #53 from mrenters/cache_state

Cache drive select and motor on moving it out of Greaseweazle
This commit is contained in:
Jeff Epler 2025-02-27 11:34:45 -06:00 committed by GitHub
commit 7c489bf56b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 100 additions and 43 deletions

View file

@ -208,7 +208,6 @@ uint32_t transfered_bytes;
uint32_t captured_pulses;
// WARNING! there are 100K max flux pulses per track!
uint8_t flux_transitions[MAX_FLUX_PULSE_PER_TRACK];
bool motor_state = false; // we can cache whether the motor is spinning
bool flux_status; // result of last flux read or write command
@ -217,16 +216,18 @@ void loop() {
if (!cmd_len) {
if ((millis() > timestamp) && ((millis() - timestamp) > 10000)) {
Serial1.println("Timed out waiting for command, resetting motor");
if (floppy) {
if (floppy && floppy->motor_is_spinning()) {
floppy->select(true); // Need to select before we can move
Serial1.println("goto track 0");
floppy->goto_track(0);
Serial1.println("stop motor");
floppy->spin_motor(false);
}
if (floppy && floppy->drive_is_selected()) {
Serial1.println("deselect");
floppy->select(false);
}
Serial1.println("motor reset");
motor_state = false;
timestamp = millis();
}
return;
@ -328,7 +329,6 @@ void loop() {
} else {
reply_buffer[i++] = GW_ACK_BADCMD;
}
motor_state = false;
Serial.write(reply_buffer, 2);
}
@ -366,10 +366,7 @@ void loop() {
uint8_t unit = cmd_buffer[2];
uint8_t state = cmd_buffer[3];
Serial1.printf("Turn motor %d %s\n\r", unit, state ? "on" : "off");
if (motor_state != state) { // we're in the opposite state
floppy->spin_motor(state);
motor_state = state;
}
floppy->spin_motor(state);
reply_buffer[i++] = GW_ACK_OK;
Serial.write(reply_buffer, 2);
}

View file

@ -145,6 +145,10 @@ void Adafruit_FloppyBase::soft_reset(void) {
watchdog_delay_ms = 1000;
bus_type = BUSTYPE_IBMPC;
is_drive_selected = false;
is_motor_spinning = false;
is_index_seen = false;
if (led_pin >= 0) {
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
@ -168,6 +172,9 @@ void Adafruit_FloppyBase::end(void) {
if (_indexpin >= 0) {
pinMode(_indexpin, INPUT);
}
is_drive_selected = false;
is_motor_spinning = false;
is_index_seen = false;
}
/**************************************************************************/
@ -251,6 +258,7 @@ void Adafruit_Floppy::end(void) {
/**************************************************************************/
void Adafruit_Floppy::select(bool selected) {
digitalWrite(_selectpin, !selected); // Selected logic level 0!
is_drive_selected = selected;
// Select drive
delayMicroseconds(select_delay_us);
}
@ -284,9 +292,18 @@ bool Adafruit_Floppy::side(int head) {
*/
/**************************************************************************/
bool Adafruit_Floppy::spin_motor(bool motor_on) {
digitalWrite(_motorpin, !motor_on); // Motor on is logic level 0!
if (!motor_on)
if (motor_on != is_motor_spinning) {
digitalWrite(_motorpin, !motor_on); // Motor on is logic level 0!
is_motor_spinning = motor_on;
}
if (!motor_on) {
is_index_seen = false;
return true; // we're done, easy!
}
if (is_index_seen)
return true; // motor on and already have seen index pulses
delay(motor_delay_ms); // Main motor turn on
@ -304,14 +321,16 @@ bool Adafruit_Floppy::spin_motor(bool motor_on) {
yield();
}
if (timedout) {
if (debug_serial)
is_index_seen = !timedout;
if (debug_serial) {
if (timedout) {
debug_serial->println("Didn't find an index pulse!");
return false;
} else {
debug_serial->println("Found!");
}
}
if (debug_serial)
debug_serial->println("Found!");
return true;
return is_index_seen;
}
/**************************************************************************/
@ -1017,7 +1036,17 @@ void Adafruit_Apple2Floppy::soft_reset() {
*/
/**************************************************************************/
void Adafruit_Apple2Floppy::select(bool selected) {
if (selected == is_drive_selected)
return; // Already in correct state
digitalWrite(_selectpin, !selected);
is_drive_selected = selected;
is_motor_spinning = selected;
// Selecting the drive also turns the motor on, but we need to look
// for index pulses, so leave that job to spin_motor.
is_index_seen = false;
if (debug_serial)
debug_serial->printf("set selectpin %d to %d\n", _selectpin, !selected);
}
@ -1033,38 +1062,44 @@ void Adafruit_Apple2Floppy::select(bool selected) {
*/
/**************************************************************************/
bool Adafruit_Apple2Floppy::spin_motor(bool motor_on) {
if (motor_on) {
delay(motor_delay_ms); // Main motor turn on
if (!motor_on)
return true; // Nothing to do
uint32_t index_stamp = millis();
bool timedout = false;
if (motor_on && is_index_seen)
return true; // motor on and already have index pulses
if (debug_serial)
debug_serial->print("Waiting for index pulse...");
delay(motor_delay_ms); // Main motor turn on
while (!read_index()) {
if ((millis() - index_stamp) > 10000) {
timedout = true; // its been 10 seconds?
break;
}
uint32_t index_stamp = millis();
bool timedout = false;
if (debug_serial)
debug_serial->print("Waiting for index pulse...");
while (!read_index()) {
if ((millis() - index_stamp) > 10000) {
timedout = true; // its been 10 seconds?
break;
}
while (read_index()) {
if ((millis() - index_stamp) > 10000) {
timedout = true; // its been 10 seconds?
break;
}
}
if (timedout) {
if (debug_serial)
debug_serial->println("Didn't find an index pulse!");
return false;
}
if (debug_serial)
debug_serial->println("Found!");
}
return true;
while (read_index()) {
if ((millis() - index_stamp) > 10000) {
timedout = true; // its been 10 seconds?
break;
}
}
is_index_seen = !timedout;
if (debug_serial) {
if (timedout) {
debug_serial->println("Didn't find an index pulse!");
} else {
debug_serial->println("Found!");
}
}
return is_index_seen;
}
// stepping FORWARD through phases steps OUT towards SMALLER track numbers

View file

@ -75,6 +75,14 @@ public:
*/
/**************************************************************************/
virtual void select(bool selected) = 0;
/**************************************************************************/
/*!
@brief Is the drive selected based on interal caching
@returns True if the drive is selected, false otherwise
*/
/**************************************************************************/
bool drive_is_selected(void) { return is_drive_selected; }
/**************************************************************************/
/*!
@brief Turn on or off the floppy motor, if on we wait till we get an
@ -86,6 +94,20 @@ public:
/**************************************************************************/
virtual bool spin_motor(bool motor_on) = 0;
/**************************************************************************/
/*!
@brief Is the drive motor spinning based on interal caching
@returns True if the motor is spinning, false otherwise
*/
/**************************************************************************/
bool motor_is_spinning(void) { return is_motor_spinning; }
/**************************************************************************/
/*!
@brief Are index pulses being seen?
@returns True if we're seeing index pulses, false otherwise
*/
/**************************************************************************/
bool index_pulses_seen(void) { return is_index_seen; }
/**************************************************************************/
/*!
@brief Seek to the desired track, requires the motor to be spun up!
@param track_num The track to step to
@ -195,6 +217,9 @@ public:
protected:
bool read_index();
bool is_drive_selected; ///< cached drive select state
bool is_motor_spinning; ///< cached motor spinning state
bool is_index_seen; ///< cached index pulses seen state
private:
#if defined(__SAMD51__)