1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-03 11:30:02 +00:00

Adds an extended rationale for current implementation.

Also strips some cruft of prior guesses.
This commit is contained in:
Thomas Harte 2019-07-31 23:19:46 -04:00
parent 1ae3799aee
commit 9bbccd89d3
3 changed files with 25 additions and 13 deletions

View File

@ -63,6 +63,7 @@ uint8_t IWM::read(int address) {
if(data_register_ & 0x80) {
// printf("\n\nIWM:%02x\n\n", data_register_);
// printf(".");
data_register_ = 0;
}
// LOG("Reading data register: " << PADHEX(2) << int(result));

View File

@ -23,26 +23,37 @@ void DriveSpeedAccumulator::post_sample(uint8_t sample) {
if(sample_pointer_ == samples_.size()) {
sample_pointer_ = 0;
// Treat 33 as a zero point and count zero crossings; then approximate
// the RPM from the frequency of those.
int samples_over = 0;
int sum = 0;
const uint8_t centre = 33;
for(size_t c = 0; c < 512; ++c) {
if(samples_[c] > centre) ++ samples_over;
sum += samples_[c];
}
// The below fits for a function like `a + bc`; it encapsultes the following
// beliefs:
//
// (i) motor speed is proportional to voltage supplied;
// (ii) with pulse-width modulation it's therefore proportional to the duty cycle;
// (iii) the Mac pulse-width modulates whatever it reads from the disk speed buffer;
// (iv) ... subject to software pulse-width modulation of that pulse-width modulation.
//
// So, I believe current motor speed is proportional to a low-pass filtering of
// the speed buffer. Which I've implemented very coarsely via 'large' bucketed-averages,
// noting also that exact disk motor speed is always a little approximate.
// Sum all samples.
// TODO: if the above is the correct test, do it on sample receipt rather than
// bothering with an intermediate buffer.
int sum = 0;
for(auto s: samples_) {
sum += s;
}
// The below fits for a function like `a + bc`.
const float rotation_speed = (float(sum) * 0.052896440564137f) - 259.0f;
// The formula below was derived from observing values the Mac wrote into its
// disk-speed buffer. Given that it runs a calibration loop before doing so,
// I cannot guarantee the accuracy of these numbers beyond being within the
// range that the computer would accept.
const float normalised_sum = float(sum) / float(samples_.size());
const float rotation_speed = (normalised_sum * 27.08f) - 259.0f;
for(int c = 0; c < number_of_drives_; ++c) {
drives_[c]->set_rotation_speed(rotation_speed);
}
// printf("RPM: %0.2f (%d over; %d sum)\n", rotation_speed, samples_over, sum);
// printf("RPM: %0.2f (%d sum)\n", rotation_speed, sum);
}
}

View File

@ -33,7 +33,7 @@ class DriveSpeedAccumulator {
void add_drive(Apple::Macintosh::DoubleDensityDrive *drive);
private:
std::array<uint8_t, 512> samples_;
std::array<uint8_t, 20> samples_;
std::size_t sample_pointer_ = 0;
Apple::Macintosh::DoubleDensityDrive *drives_[2] = {nullptr, nullptr};
int number_of_drives_ = 0;