From 0e126c8908fa4c055a4ac56b2ab03bb4c9cd76f9 Mon Sep 17 00:00:00 2001 From: ASleepyCat Date: Sat, 13 Jan 2024 23:45:14 +1000 Subject: [PATCH 1/3] Fix analog outputs freezing at start up, sample QE inputs 1000 times --- roxy/axis.h | 63 +++++++++++++++++++++++++++++++++++----------- roxy/main.cpp | 13 +++------- roxy/report_desc.h | 8 +++--- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/roxy/axis.h b/roxy/axis.h index e24441c..33668c1 100644 --- a/roxy/axis.h +++ b/roxy/axis.h @@ -12,8 +12,7 @@ class Axis { uint32_t axis_debounce_start; uint32_t axis_time = 0; - uint32_t last_axis = 0; - int8_t last_axis_stae = 0; + int8_t last_axis_state = 0; uint8_t axis_debounce_time = 0; uint8_t axis_sustain_time = 0; @@ -26,6 +25,7 @@ class Axis { protected: uint16_t max_count = 255; int8_t sensitivity = 0; + uint32_t last_axis = 0; public: uint32_t count; @@ -37,10 +37,10 @@ class Axis { axis_debounce_time = _debounce; axis_sustain_time = _sustain; reduction_ratio = _reduction; - deadzone_angle = (float)_deadzone / 2.0f; + deadzone_angle = _deadzone / 2.0f; } - void process() { + virtual void process() { uint32_t current_time = Time::time(); count = get(); @@ -138,8 +138,6 @@ class Axis { } else { count = last_axis; } - - count -= 128; } }; @@ -261,7 +259,6 @@ class IntAxis : public Axis { if(count >= max_count) { count -= max_count; } - } virtual uint32_t get() final { @@ -273,7 +270,21 @@ class AnalogAxis : public Axis { private: ADC_t& adc; uint32_t ch; - + int8_t delta; + + void smoothing_function() { + const uint16_t qe_samples = 1000; + + for (uint16_t sample = 0; sample < qe_samples; ++sample) { + count += get(); + } + + count /= qe_samples; + + delta = last_axis - count; + last_axis = count; + } + public: AnalogAxis(ADC_t& a, uint32_t c) : adc(a), ch(c) {} @@ -282,22 +293,22 @@ class AnalogAxis : public Axis { adc.CR &= ~((1 << 28) | (1 << 29)); // Reset ADVREGEN adc.CR |= 1 << 28; // Turn on ADVREGEN Time::sleep(2); // Wait for regulator to turn on - + // Calibrate ADC. adc.CR &= ~(1 << 30); // ADCALDIF = 0 (single ended) adc.CR |= 1 << 31; // Enable ADCAL while(!(adc.CR & (1 << 31))); // Wait for ADCAL to finish - - // Configure continous capture on one channel. + + // Configure continuous capture on one channel. adc.CFGR = (1 << 13) | (1 << 12) | (1 << 5); // CONT, OVRMOD, ALIGN adc.SQR1 = (ch << 6); // adc.SMPR1 = (7 << (ch * 3)); // 72 MHz / 64 / 614 = apx. 1.8 kHz - + // Enable ADC. adc.CR |= 1 << 0; // ADEN while(!(adc.ISR & (1 << 0))); // ADRDY adc.ISR = (1 << 0); // ADRDY - + // Start conversion. adc.CR |= 1 << 2; // ADSTART } @@ -305,6 +316,30 @@ class AnalogAxis : public Axis { virtual uint32_t get() final { return adc.DR >> 8; } + + virtual void process() { + smoothing_function(); + + if(delta > 0) { + dir_state = 1; + } else if(delta < 0) { + dir_state = -1; + } else { + dir_state = 0; + } + + if(sensitivity == -127) { + count *= (256.0f / (600.0f * 4.0f)); + } else if(sensitivity == -126) { + count *= (256.0f / (400.0f * 4.0f)); + } else if(sensitivity == -125) { + count *= (256.0f / (360.0f * 4.0f)); + } else if(sensitivity < 0) { + count /= -sensitivity; + } else if(sensitivity > 0) { + count *= sensitivity; + } + } }; -#endif \ No newline at end of file +#endif diff --git a/roxy/main.cpp b/roxy/main.cpp index ac0e89e..d289ab2 100644 --- a/roxy/main.cpp +++ b/roxy/main.cpp @@ -410,20 +410,12 @@ int main() { tcleds.init(); } - // int8_t axis_state[2] = {0, 0}; // Current axis state - // uint32_t axis_sustain_start[2] = {0, 0}; // Clock time a sustain is started - // uint32_t axis_debounce_start[2] = {0, 0}; - - // uint32_t axis_time[2] = {0, 0}; - // uint8_t last_axis[2] = {0, 0}; - - // int8_t last_axis_state[2] = {0, 0}; - // uint32_t qe_count[2] = {0, 0}; uint32_t axis_buttons[4] = {(1 << 12), (1 << 13), (1 << 14), (1 << 15)}; +#pragma clang diagnostic push +#pragma ide diagnostic ignored "EndlessLoop" while(1) { usb->process(); - uint32_t current_time = Time::time(); uint16_t buttons = button_manager.read_buttons(); @@ -559,4 +551,5 @@ int main() { } } } +#pragma clang diagnostic pop } diff --git a/roxy/report_desc.h b/roxy/report_desc.h index 833a5dc..c1958e5 100644 --- a/roxy/report_desc.h +++ b/roxy/report_desc.h @@ -11,16 +11,16 @@ auto report_desc = joystick( usage_page(UsagePage::Desktop), usage(DesktopUsage::X), - logical_minimum(-128), - logical_maximum(127), + logical_minimum(0), + logical_maximum(255), report_count(1), report_size(8), input(0x02), usage_page(UsagePage::Desktop), usage(DesktopUsage::Y), - logical_minimum(-128), - logical_maximum(127), + logical_minimum(0), + logical_maximum(255), report_count(1), report_size(8), input(0x02), From 770259bd63dcf81f754bb36963f80a3edcc31d1c Mon Sep 17 00:00:00 2001 From: ASleepyCat Date: Sun, 14 Jan 2024 00:02:48 +1000 Subject: [PATCH 2/3] Minor refactoring --- roxy/axis.h | 4 ++-- roxy/main.cpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/roxy/axis.h b/roxy/axis.h index 33668c1..56c7527 100644 --- a/roxy/axis.h +++ b/roxy/axis.h @@ -272,7 +272,7 @@ class AnalogAxis : public Axis { uint32_t ch; int8_t delta; - void smoothing_function() { + void sampleQe() { const uint16_t qe_samples = 1000; for (uint16_t sample = 0; sample < qe_samples; ++sample) { @@ -318,7 +318,7 @@ class AnalogAxis : public Axis { } virtual void process() { - smoothing_function(); + sampleQe(); if(delta > 0) { dir_state = 1; diff --git a/roxy/main.cpp b/roxy/main.cpp index d289ab2..2064b9f 100644 --- a/roxy/main.cpp +++ b/roxy/main.cpp @@ -412,8 +412,6 @@ int main() { uint32_t axis_buttons[4] = {(1 << 12), (1 << 13), (1 << 14), (1 << 15)}; -#pragma clang diagnostic push -#pragma ide diagnostic ignored "EndlessLoop" while(1) { usb->process(); @@ -551,5 +549,4 @@ int main() { } } } -#pragma clang diagnostic pop } From 5943fb8ad0fa3a585400e2d23d61828f11d17e93 Mon Sep 17 00:00:00 2001 From: ASleepyCat Date: Fri, 21 Jun 2024 19:01:58 +1000 Subject: [PATCH 3/3] Reduce QE sampling to 128 times, add some comments on ADC registers --- roxy/axis.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/roxy/axis.h b/roxy/axis.h index 56c7527..3e9d595 100644 --- a/roxy/axis.h +++ b/roxy/axis.h @@ -272,19 +272,6 @@ class AnalogAxis : public Axis { uint32_t ch; int8_t delta; - void sampleQe() { - const uint16_t qe_samples = 1000; - - for (uint16_t sample = 0; sample < qe_samples; ++sample) { - count += get(); - } - - count /= qe_samples; - - delta = last_axis - count; - last_axis = count; - } - public: AnalogAxis(ADC_t& a, uint32_t c) : adc(a), ch(c) {} @@ -302,23 +289,35 @@ class AnalogAxis : public Axis { // Configure continuous capture on one channel. adc.CFGR = (1 << 13) | (1 << 12) | (1 << 5); // CONT, OVRMOD, ALIGN adc.SQR1 = (ch << 6); - // adc.SMPR1 = (7 << (ch * 3)); // 72 MHz / 64 / 614 = apx. 1.8 kHz + // For some reason this is broken, seems to do nothing and breaks QE2? + // adc.SMPR1 = (7 << (ch * 3)); // Max sample time (72 MHz / 64 / 614 = apx. 1.8 kHz) // Enable ADC. adc.CR |= 1 << 0; // ADEN + // Wait for ADC to get ready. while(!(adc.ISR & (1 << 0))); // ADRDY + // Clear ADRDY flag. adc.ISR = (1 << 0); // ADRDY // Start conversion. adc.CR |= 1 << 2; // ADSTART } - + virtual uint32_t get() final { - return adc.DR >> 8; + const uint16_t qe_samples = 128; + uint32_t samples = 0; + + for (uint16_t sample = 0; sample < qe_samples; ++sample) { + samples += adc.DR >> 8; + } + + return samples / qe_samples; } - virtual void process() { - sampleQe(); + void process() { + count = get(); + delta = last_axis - count; + last_axis = count; if(delta > 0) { dir_state = 1;