doxyclang
This commit is contained in:
parent
7999fb5469
commit
24ecf22e4e
2 changed files with 135 additions and 55 deletions
|
|
@ -1,15 +1,35 @@
|
|||
#include "Adafruit_Floppy.h"
|
||||
|
||||
|
||||
#define read_index() (*indexPort & indexMask)
|
||||
#define read_data() (*dataPort & dataMask)
|
||||
#define read_data() (*dataPort & dataMask)
|
||||
|
||||
Adafruit_Floppy::Adafruit_Floppy(int8_t densitypin, int8_t indexpin, int8_t selectpin,
|
||||
int8_t motorpin, int8_t directionpin, int8_t steppin,
|
||||
int8_t wrdatapin, int8_t wrgatepin, int8_t track0pin,
|
||||
int8_t protectpin, int8_t rddatapin, int8_t sidepin,
|
||||
int8_t readypin)
|
||||
{
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Create a hardware interface to a floppy drive
|
||||
@param densitypin A pin connected to the floppy Density Select input
|
||||
@param indexpin A pin connected to the floppy Index Sensor output
|
||||
@param selectpin A pin connected to the floppy Drive Select input
|
||||
@param motorpin A pin connected to the floppy Motor Enable input
|
||||
@param directionpin A pin connected to the floppy Stepper Direction input
|
||||
@param steppin A pin connected to the floppy Stepper input
|
||||
@param wrdatapin A pin connected to the floppy Write Data input
|
||||
@param wrgatepin A pin connected to the floppy Write Gate input
|
||||
@param track0pin A pin connected to the floppy Track 00 Sensor output
|
||||
@param protectpin A pin connected to the floppy Write Protect Sensor output
|
||||
@param rddatapin A pin connected to the floppy Read Data output
|
||||
@param sidepin A pin connected to the floppy Side Select input
|
||||
@param readypin A pin connected to the floppy Ready/Disk Change output
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
Adafruit_Floppy::Adafruit_Floppy(int8_t densitypin, int8_t indexpin,
|
||||
int8_t selectpin, int8_t motorpin,
|
||||
int8_t directionpin, int8_t steppin,
|
||||
int8_t wrdatapin, int8_t wrgatepin,
|
||||
int8_t track0pin, int8_t protectpin,
|
||||
int8_t rddatapin, int8_t sidepin,
|
||||
int8_t readypin) {
|
||||
_densitypin = densitypin;
|
||||
_indexpin = indexpin;
|
||||
_selectpin = selectpin;
|
||||
|
|
@ -25,15 +45,20 @@ Adafruit_Floppy::Adafruit_Floppy(int8_t densitypin, int8_t indexpin, int8_t sele
|
|||
_readypin = readypin;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Initializes the GPIO pins but do not start the motor or anything
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::begin(void) {
|
||||
// deselect drive
|
||||
pinMode(_selectpin, OUTPUT);
|
||||
digitalWrite(_selectpin, HIGH);
|
||||
|
||||
|
||||
// motor enable pin, drive low to turn on motor
|
||||
pinMode(_motorpin, OUTPUT);
|
||||
digitalWrite(_motorpin, HIGH);
|
||||
|
||||
|
||||
// set motor direction (low is in, high is out)
|
||||
pinMode(_directionpin, OUTPUT);
|
||||
digitalWrite(_directionpin, LOW); // move inwards to start
|
||||
|
|
@ -44,7 +69,7 @@ void Adafruit_Floppy::begin(void) {
|
|||
|
||||
// side selector
|
||||
pinMode(_sidepin, OUTPUT);
|
||||
digitalWrite(_sidepin, HIGH); // side 0 to start
|
||||
digitalWrite(_sidepin, HIGH); // side 0 to start
|
||||
|
||||
pinMode(_indexpin, INPUT_PULLUP);
|
||||
pinMode(_track0pin, INPUT_PULLUP);
|
||||
|
|
@ -56,25 +81,42 @@ void Adafruit_Floppy::begin(void) {
|
|||
indexMask = digitalPinToBitMask(_indexpin);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Select and spin up the floppy motor
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::spin_up(void) {
|
||||
digitalWrite(_selectpin, HIGH);
|
||||
delay(10);
|
||||
// Main motor turn on
|
||||
digitalWrite(_motorpin, LOW);
|
||||
// Select drive
|
||||
digitalWrite(_selectpin, LOW);
|
||||
digitalWrite(_selectpin, HIGH);
|
||||
delay(10);
|
||||
// Main motor turn on
|
||||
digitalWrite(_motorpin, LOW);
|
||||
// Select drive
|
||||
digitalWrite(_selectpin, LOW);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Spin down the motor and de-select the drive
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::spin_down(void) {
|
||||
// Main motor turn off
|
||||
digitalWrite(_motorpin, HIGH);
|
||||
// De-select drive
|
||||
digitalWrite(_selectpin, HIGH);
|
||||
// Main motor turn off
|
||||
digitalWrite(_motorpin, HIGH);
|
||||
// De-select drive
|
||||
digitalWrite(_selectpin, HIGH);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Seek to the desired track, requires the motor to be spun up!
|
||||
@param track_num The track to step to
|
||||
@return True If we were able to get to the track location
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_Floppy::goto_track(uint8_t track_num) {
|
||||
// track 0 is a very special case because its the only one we actually know we got to
|
||||
// track 0 is a very special case because its the only one we actually know we
|
||||
// got to
|
||||
if (track_num == 0) {
|
||||
uint8_t max_steps = MAX_TRACKS;
|
||||
while (max_steps--) {
|
||||
|
|
@ -86,31 +128,51 @@ bool Adafruit_Floppy::goto_track(uint8_t track_num) {
|
|||
}
|
||||
return false; // we 'timed' out!
|
||||
}
|
||||
if (!goto_track(0)) return false;
|
||||
step(STEP_IN, max(track_num, MAX_TRACKS-1));
|
||||
if (!goto_track(0))
|
||||
return false;
|
||||
step(STEP_IN, max(track_num, MAX_TRACKS - 1));
|
||||
_track = track_num;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Step the track motor
|
||||
@param dir STEP_OUT or STEP_IN depending on desired direction
|
||||
@param times How many steps to take
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::step(bool dir, uint8_t times) {
|
||||
digitalWrite(_directionpin, dir);
|
||||
delayMicroseconds(10); // 1 microsecond, but we're generous
|
||||
|
||||
|
||||
while (times--) {
|
||||
digitalWrite(_steppin, HIGH);
|
||||
delay(3); // 3ms min per step
|
||||
digitalWrite(_steppin, LOW);
|
||||
delay(3); // 3ms min per step
|
||||
delay(3); // 3ms min per step
|
||||
digitalWrite(_steppin, HIGH); // end high
|
||||
}
|
||||
}
|
||||
|
||||
int8_t Adafruit_Floppy::track(void) {
|
||||
return _track;
|
||||
}
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief The current track location, based on internal caching
|
||||
@return The cached track location
|
||||
*/
|
||||
/**************************************************************************/
|
||||
int8_t Adafruit_Floppy::track(void) { return _track; }
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Capture one track's worth of flux transitions, between two falling
|
||||
index pulses
|
||||
@param pulses A pointer to an array of memory we can use to store into
|
||||
@param max_pulses The size of the allocated pulses array
|
||||
@return Number of pulses we actually captured
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) {
|
||||
uint8_t pulse_count;
|
||||
uint8_t *pulses_ptr = pulses;
|
||||
|
|
@ -141,13 +203,15 @@ uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) {
|
|||
// muahaha, now we can read track data!
|
||||
pulse_count = 0;
|
||||
// while pulse is in the low pulse, count up
|
||||
while (!read_data()) pulse_count++;
|
||||
while (!read_data())
|
||||
pulse_count++;
|
||||
*ledPort |= ledMask;
|
||||
|
||||
// while pulse is high, keep counting up
|
||||
while (read_data()) pulse_count++;
|
||||
while (read_data())
|
||||
pulse_count++;
|
||||
*ledPort &= ~ledMask;
|
||||
|
||||
|
||||
pulses_ptr[0] = pulse_count;
|
||||
pulses_ptr++;
|
||||
if (pulses_ptr == pulses_end) {
|
||||
|
|
@ -159,8 +223,11 @@ uint32_t Adafruit_Floppy::capture_track(uint8_t *pulses, uint32_t max_pulses) {
|
|||
return pulses_ptr - pulses;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Busy wait until the index line goes from high to low
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::wait_for_index_pulse_low(void) {
|
||||
// initial state
|
||||
bool index_state = read_index();
|
||||
|
|
@ -176,29 +243,43 @@ void Adafruit_Floppy::wait_for_index_pulse_low(void) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Pretty print the counts in a list of flux transitions
|
||||
@param pulses A pointer to an array of memory containing pulse counts
|
||||
@param num_pulses The size of the pulses in the array
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::print_pulses(uint8_t *pulses, uint32_t num_pulses) {
|
||||
for (uint32_t i=0; i<num_pulses; i++) {
|
||||
for (uint32_t i = 0; i < num_pulses; i++) {
|
||||
Serial.print(pulses[i]);
|
||||
Serial.print(", ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void Adafruit_Floppy::print_pulse_bins(uint8_t *pulses, uint32_t num_pulses, uint8_t max_bins) {
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Pretty print a simple histogram of flux transitions
|
||||
@param pulses A pointer to an array of memory containing pulse counts
|
||||
@param num_pulses The size of the pulses in the array
|
||||
@param max_bins The maximum number of histogram bins to use (default 64)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_Floppy::print_pulse_bins(uint8_t *pulses, uint32_t num_pulses,
|
||||
uint8_t max_bins) {
|
||||
// lets bin em!
|
||||
uint32_t bins[max_bins][2];
|
||||
memset(bins, 0, max_bins*2*sizeof(uint32_t));
|
||||
memset(bins, 0, max_bins * 2 * sizeof(uint32_t));
|
||||
|
||||
// we'll add each pulse to a bin so we can figure out the 3 buckets
|
||||
for (uint32_t i=0; i<num_pulses; i++) {
|
||||
for (uint32_t i = 0; i < num_pulses; i++) {
|
||||
uint8_t p = pulses[i];
|
||||
// find a bin for this pulse
|
||||
uint8_t bin = 0;
|
||||
for (bin=0; bin<max_bins; bin++) {
|
||||
for (bin = 0; bin < max_bins; bin++) {
|
||||
// bin already exists? increment the count!
|
||||
if (bins[bin][0] == p) {
|
||||
bins[bin][1] ++;
|
||||
bins[bin][1]++;
|
||||
break;
|
||||
}
|
||||
if (bins[bin][0] == 0) {
|
||||
|
|
@ -208,11 +289,12 @@ void Adafruit_Floppy::print_pulse_bins(uint8_t *pulses, uint32_t num_pulses, uin
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (bin == max_bins) Serial.println("oof we ran out of bins but we'll keep going");
|
||||
if (bin == max_bins)
|
||||
Serial.println("oof we ran out of bins but we'll keep going");
|
||||
}
|
||||
// this is a very lazy way to print the bins sorted
|
||||
for (uint8_t pulse_w=1; pulse_w<255; pulse_w++) {
|
||||
for (uint8_t b=0; b<max_bins; b++) {
|
||||
for (uint8_t pulse_w = 1; pulse_w < 255; pulse_w++) {
|
||||
for (uint8_t b = 0; b < max_bins; b++) {
|
||||
if (bins[b][0] == pulse_w) {
|
||||
Serial.print(bins[b][0]);
|
||||
Serial.print(": ");
|
||||
|
|
@ -221,6 +303,3 @@ void Adafruit_Floppy::print_pulse_bins(uint8_t *pulses, uint32_t num_pulses, uin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#define MAX_TRACKS 80
|
||||
#define STEP_OUT HIGH
|
||||
#define STEP_IN LOW
|
||||
#define MAX_FLUX_PULSE_PER_TRACK (500000 / 5) // 500khz / 5 hz per track rotation
|
||||
|
||||
#define MAX_FLUX_PULSE_PER_TRACK \
|
||||
(500000 / 5) // 500khz / 5 hz per track rotation
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
|
@ -30,7 +30,8 @@ public:
|
|||
void step(bool dir, uint8_t times);
|
||||
|
||||
uint32_t capture_track(uint8_t *pulses, uint32_t max_pulses);
|
||||
void print_pulse_bins(uint8_t *pulses, uint32_t num_pulses, uint8_t max_bins = 64);
|
||||
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);
|
||||
|
||||
int8_t led_pin = LED_BUILTIN;
|
||||
|
|
@ -40,13 +41,13 @@ private:
|
|||
|
||||
// theres a lot of GPIO!
|
||||
int8_t _densitypin, _indexpin, _selectpin, _motorpin, _directionpin, _steppin,
|
||||
_wrdatapin, _wrgatepin, _track0pin, _protectpin, _rddatapin, _sidepin, _readypin;
|
||||
_wrdatapin, _wrgatepin, _track0pin, _protectpin, _rddatapin, _sidepin,
|
||||
_readypin;
|
||||
|
||||
int8_t _track = -1;
|
||||
|
||||
BusIO_PortReg *indexPort;
|
||||
BusIO_PortMask indexMask;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue