From ec581fd0a414c58fa65ed7676b7110b729c3068f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 22 Mar 2023 05:15:00 +0800 Subject: [PATCH] lotus: Remove usage of chibios ADC API Signed-off-by: Daniel Schaefer --- keyboards/lotus/factory.c | 4 - keyboards/lotus/matrix.c | 286 ++------------------------------------ 2 files changed, 8 insertions(+), 282 deletions(-) diff --git a/keyboards/lotus/factory.c b/keyboards/lotus/factory.c index 250ff64c7f..c9e81552db 100644 --- a/keyboards/lotus/factory.c +++ b/keyboards/lotus/factory.c @@ -11,7 +11,6 @@ enum factory_commands { f_emu_keypress = 0x01, // Next byte is keycode - f_adc = 0x03, // ADC trigger f_serialnum = 0x04, // Read device serial number f_bootloader = 0xFE, }; @@ -49,9 +48,6 @@ void handle_factory_command(uint8_t *data) { tap_code(command_data[0]); #endif break; - case f_adc: - factory_trigger_adc(); - break; case f_serialnum: print("Reading Device serial number\n"); diff --git a/keyboards/lotus/matrix.c b/keyboards/lotus/matrix.c index c57758d310..7ee3a86c4b 100644 --- a/keyboards/lotus/matrix.c +++ b/keyboards/lotus/matrix.c @@ -13,31 +13,8 @@ #include "matrix.h" #include "lotus.h" -// Use raw ChibiOS ADC functions instead of those from QMK -// Using the QMK functions doesn't work yet -#define CHIBIOS_ADC FALSE - #define adc10ksample_t int -uint32_t prev_matrix_ts = 0; -adc10ksample_t adc_voltage; -#if CHIBIOS_ADC -bool letsgo = false; -adc10ksample_t temperature; - -enum sample_state { - s_never, // Never received a sample - s_waiting, // Waiting for a new sample (at least one received) - s_ready, // Received a sample, ready to be consumed -}; -#define ADC_RESOLUTION 10 -#define ADC_GRP_NUM_CHANNELS 2 -#define ADC_GRP_BUF_DEPTH 2 -static adcsample_t prev_samples[CACHE_SIZE_ALIGN(adcsample_t, ADC_GRP_NUM_CHANNELS * ADC_GRP_BUF_DEPTH)]; -static adcsample_t samples[CACHE_SIZE_ALIGN(adcsample_t, ADC_GRP_NUM_CHANNELS * ADC_GRP_BUF_DEPTH)]; -static enum sample_state adc_state; -#endif - // Mux GPIOs #define MUX_A GP1 #define MUX_B GP2 @@ -69,138 +46,21 @@ static enum sample_state adc_state; #define KSO15 GP22 #define ADC_CH2_PIN GP28 -// Voltage threshold - TODO: Need to adjust + +// Voltage threshold - anything below that counts as pressed const adc10ksample_t ADC_THRESHOLD = (adc10ksample_t) 3.0 * 10000; adc10ksample_t to_voltage(adcsample_t sample) { -#if CHIBIOS_ADC - // 1241 = (1 << 12) * 10000 / (3.3 * 10000) - int voltage = sample * 10000; - return voltage / 1241; -#else int voltage = sample * 33000; return voltage / 1023; -#endif } -adc10ksample_t to_temp(adcsample_t sample) { - int temp = sample * 10000; - // Scaled up by 10000 - //temperature = 27.0 - (temp - 0.706)/0.001721; - return 270000 - (((temp / 8) - 7060) /17);//.21; -} void print_as_float(adc10ksample_t sample) { int digits = sample / 10000; int decimals = sample % 10000; uprintf("%d.%02d\n", digits, decimals); } -#if CHIBIOS_ADC -/** - * Average the mulitiple samples due to depth>1 together to a single value - */ -adcsample_t average_samples(adcsample_t s[], int channel) { - adcsample_t sum = 0; - assert(ADC_GRP_BUF_DEPTH == 2); - - for (int i = 0; i < ADC_GRP_NUM_CHANNELS; i++) { - sum += s[channel + (i * ADC_GRP_BUF_DEPTH)]; - } - - return sum / ADC_GRP_NUM_CHANNELS; -} - -void print_samples(adcsample_t s[]) { - // Samples go from 0 to 4095 - //uprintf("Raw ADC samples: %d, %d, %d, %d\n", samples[0], samples[1], samples[2], samples[3]); - - print("Temp: "); - print_as_float(temperature); - - uprintf("ADC Voltage: "); - print_as_float(adc_voltage); -} - -/** - * Convert the ADC samples to meaningful values - * - * Should be called after receiving a set of samples from the ADC - */ -void handle_sample(void) { - adcsample_t adv_avg = average_samples(samples, 0); - adcsample_t temp_avg = average_samples(samples, 1); - - // Uses global variables because it might be called from an interrupt handler - // But we might not want to act upon them from there. - // Convert to real temperature based on RP2040 datasheet - temperature = to_temp(temp_avg); - adc_voltage = to_voltage(adv_avg); - - //print_samples(samples); -} - -/* - * Call back function which is called when ADC is finished. - */ -void adc_end_callback(ADCDriver *adcp) { - (void)adcp; - adc_state = s_ready; - //print("adc_end_callback\n"); - - //handle_sample(); -} - -/* - * Call back function which called when ADC gives some error. - */ -void adc_error_callback(ADCDriver *adcp, adcerror_t err) { - (void)adcp; - uprintf("error: %ld\n", err); - assert(false); -} - -const ADCConversionGroup adcConvGroup = { - .circular = false, - .num_channels = ADC_GRP_NUM_CHANNELS, - .end_cb = &adc_end_callback, - .error_cb = &adc_error_callback, - // CH2 is the keyboard matrix, CH4 is the temp sensor - .channel_mask = RP_ADC_CH2 | RP_ADC_CH4, -}; - -/** - * Trigger an ADC conversion. When done, the callback is called. - * - * Never blocks. - * If adcConvGroup.circular is true, callbacks will keep coming. - */ -void trigger_adc(void) { - adcStartConversion(&ADCD1, &adcConvGroup, - samples, ADC_GRP_BUF_DEPTH); -} - -/** - * Trigger a single, blocking ADC conversion - */ -void factory_trigger_adc(void) { - if (!letsgo) { - print("Factory triggered ADC\n"); - letsgo = true; - } - // adcConvert brings frequency from 6kHz down to 360Hz - adcConvert(&ADCD1, &adcConvGroup, - samples, ADC_GRP_BUF_DEPTH); - //print("After adcConvert\n"); - memcpy(prev_samples, samples, sizeof(samples)); - handle_sample(); - //print("After handle_sample"); -} -#else -void factory_trigger_adc(void) { - print("NOT IMPLEMENTED - Factory triggered ADC\n"); -} -#endif - /** * Tell RP2040 ADC controller to initialize a specific GPIO for ADC input */ @@ -260,7 +120,6 @@ static void mux_select_row(int row) { writePin(MUX_C, bits[2]); } -#if 1 /** * Based on the ADC value, update the matrix for this column * */ @@ -277,7 +136,6 @@ static bool interpret_adc_row(matrix_row_t cur_matrix[], adc10ksample_t voltage, key_state = true; } - //if (key_state) { if (key_state) { uprintf("Col %d - Row %d - State: %d, Voltage: ", col, row, key_state); print_as_float(voltage); @@ -303,11 +161,8 @@ static bool interpret_adc_row(matrix_row_t cur_matrix[], adc10ksample_t voltage, } cur_matrix[row] = new_row; - // Debug keyboard - //return false; return changed; } -#endif /** * Drive the GPIO for a column low or high. @@ -388,43 +243,12 @@ void drive_col(int col, bool high) { /** * Read a value from the ADC and print some debugging details */ -static void read_adc(void) { -#if !CHIBIOS_ADC - // Can't use analogReadPin because it gets rid of the internal pullup on this pin - //uint16_t val = analogReadPin(ADC_CH2_PIN); +static adc10ksample_t read_adc(void) { + // Can't use analogReadPin because it gets rid of the internal pullup on + // this pin, that we configure in matrix_init_custom + // uint16_t val = analogReadPin(ADC_CH2_PIN); uint16_t val = adc_read(pinToMux(ADC_CH2_PIN)); - adc_voltage = to_voltage(val); - //uprintf("ADC raw %d, Voltage: ", val); - //print_as_float(to_voltage(val)); -#else - if (letsgo) { - factory_trigger_adc(); - } - - // Interrupt-driven - // Even the "blocking" one suspends the thread, so we shouldn't need this - //if (adc_state == s_ready) { - // print("new sample\n"); - - // memcpy(prev_samples, samples, sizeof(samples)); - - // adc_state = s_waiting; - - // // Works if both are commented out. - // // Doesn't work if we don't sleep at all or sleep less than 300ms. - // // Then we seemingly are stuck, no prints and doesn't respond to raw HID commands. - // // - // // Also works if we never trigger ADC at all - // //hThdSleepMilliseconds(300); - // // Trigger non-blocking ADC read that will be handled by and interrupt callback - // trigger_adc(); - //} -#endif // CHIBIOS_ADC - - //uprintf("Temperature: "); - //print_as_float(temperature); - //uprintf("ADC Voltage: "); - //print_as_float(adc_voltage); + return to_voltage(val); } /** @@ -447,15 +271,6 @@ void handle_idle(void) { bool matrix_scan_custom(matrix_row_t current_matrix[]) { bool changed = false; - //print("scan\n"); - - uint32_t current_ts = timer_read32(); - if (prev_matrix_ts) { - //uint32_t delta = current_ts - prev_matrix_ts; - //uprintf("%lu ms (%ld Hz)\n", delta, 1000 / delta); - } - prev_matrix_ts = current_ts; - handle_idle(); //wait_us(500 * 1000); @@ -463,59 +278,6 @@ bool matrix_scan_custom(matrix_row_t current_matrix[]) { for (int col = 0; col < MATRIX_COLS; col++) { drive_col(col, true); } - //drive_col(2, false); - - // Striped red/black - // - // Shows low when not pressing. High when pressing. REVERSED! - // - // If no col is driven high. No cols work. (Row always low) - // If all cols are driven high. Col 4 works. (high when pressed) - // If just col 4 is driven high. Col 4 works. (high when pressed) - //mux_select_row(3); - - // Black - // Shows low when not pressing. High when pressing. REVERSED! - // - // Correctly works only for the col that is driven high. REVERSED! - // If all cols are driven high. All cols work. (high when pressed) - // If no col is driven high. No cols work (high when pressed) - //mux_select_row(2); - - // Red - // - // High when not pressing. Low when pressing. - // If no col is driven low. No cols work. - // If all cols are driven low. All cols work. (low when pressed) - // If just col 0 is driven low. Only col 0/GP8 works - // If just col 1 is driven low. Only col 1/GP9 works - // If just col 2 is driven low. Only col 2/GP10 works - // If just col 3 is driven low. Only col 3/GP11 works - // If just col 4 is driven low. Only col 4/GP12 works - // If just col 5 is driven low. Only col 5/GP13 works - // If just col 6 is driven low. Only col 6/GP14 works - // If just col 7 is driven low. Only col 7/GP15 works - //mux_select_row(1); - - // Blue. - // High when not pressing. Low when pressing. - // - // If no col is driven low. No cols work. - // If all cols are driven low. All cols work. (low when pressed) - // If just col 0 is driven low. Only col 0/GP8 works - // If just col 1 is driven low. Only col 1/GP9 works - // If just col 2 is driven low. Only col 2/GP10 works - // If just col 3 is driven low. Only col 3/GP11 works - // If just col 4 is driven low. Only col 4/GP12 works - // If just col 5 is driven low. Only col 5/GP13 works - // If just col 6 is driven low. Only col 6/GP14 works - // If just col 7 is driven low. Only col 7/GP15 works - //mux_select_row(0); - // - //wait_us(100); - //read_adc(); - //uprintf("ADC Voltage: "); - //print_as_float(adc_voltage); // Go through every matrix column (KSO) and drive them low individually // Then go through every matrix row (KSI), select it with the mux and check their ADC value @@ -531,18 +293,14 @@ bool matrix_scan_custom(matrix_row_t current_matrix[]) { // Wait for column select to settle and propagate to ADC //wait_us(500 * 1000); - read_adc(); - // Interpret ADC value as rows - changed |= interpret_adc_row(current_matrix, adc_voltage, col, row); + changed |= interpret_adc_row(current_matrix, read_adc(), col, row); } // Drive column high again drive_col(col, true); } - //uprintf("changed: %d\n", changed); - return changed; } @@ -600,32 +358,4 @@ void matrix_init_custom(void) { // Set unused pins to input to avoid interfering. They're hooked up to rows 5 and 6 setPinInput(GP6); setPinInput(GP7); - -#if CHIBIOS_ADC - adc_state = s_never; - const ADCConfig adcConfig = { - // Default clock divider - .div_int = 0, - .div_frac = 0, - // Don't shift FIFO results - .shift = false, - }; - adcStart(&ADCD1, &adcConfig); - - // For testing enable temp sensor - adcRPEnableTS(&ADCD1); - - // Start ADC conversion immediately. Don't wait for factory command to enable - // For debugging it's sometimes useful to start later because the first - // prints won't show on the console. So if it hangs here, it's hard to tell - // what's going wrong. - letsgo = true; - - // Start automatic conversion - //chThdSleepMilliseconds(100); - //trigger_adc(); - - // TODO: Not sure we ever need to stop. Perhaps to save power. - // adcStopConversion(&ADCD1); -#endif }