diff --git a/include/adc.h b/include/adc.h index 6ec842e..2be31bf 100644 --- a/include/adc.h +++ b/include/adc.h @@ -14,11 +14,11 @@ #define ADC_CHANNELS 5 -#define ADC_HISTLEN 16 +#define ADC_HISTLEN 32 -extern uint16_t adc_avg[ADC_CHANNELS]; +extern uint32_t adc_avg[ADC_CHANNELS]; diff --git a/src/adc.c b/src/adc.c index 16a1615..1eaa915 100644 --- a/src/adc.c +++ b/src/adc.c @@ -9,12 +9,12 @@ * voltage - only the analog supply can be the reference. * * because most inputs are high impedance, which is not ideal, - * sampling time is increased. this results in a final ADC sample rate - * of about 33KHz, still well beyond what is needed in this application. - * this value may change in the future. + * sampling time is increased. this value may change in the future. * * note: attempted to use DMA for this and scanning all channels * at once, but that didn't work. would not reliably read channels. + * the example does 32bit transfers and I was doing 16bit; + * maybe there's some issue with that. * tried many different variations and it just wasn't working. * because of this I moved to using interrupt and the built-in * wait mode just in case things went slow. @@ -30,7 +30,7 @@ -#define SAMPLE_TIME LL_ADC_SAMPLINGTIME_239CYCLES_5 +#define SAMPLE_TIME LL_ADC_SAMPLINGTIME_41CYCLES_5 #define ADC_SEQ_RDY 0xff #define ADC_SEQ_STARTUP 0xfe @@ -44,7 +44,7 @@ static uint16_t adc_read[ADC_CHANNELS]; static uint16_t adc_hist[ADC_CHANNELS][ADC_HISTLEN]; -uint16_t adc_avg[ADC_CHANNELS]; +uint32_t adc_avg[ADC_CHANNELS]; static uint8_t adc_seq = 0; static uint8_t adc_idx = ADC_HISTLEN + 1; @@ -70,6 +70,9 @@ void adc_init() // with wait mode (anti-overrun) active ADC1->CFGR1 = ADC_CFGR1_OVRMOD | ADC_CFGR1_WAIT; + // default clock + ADC1->CFGR2 = 0; + // configure scan channels, sampling time (11 = temp, 12 = vrefint) ADC1->SMPR = SAMPLE_TIME; ADC1->CHSELR = CONF_SET1_AN | PROBE_AN | // note: SET1 and VREFEXT are @@ -160,6 +163,9 @@ uint8_t adc_next() // wait for calibration to complete, if started while (ADC1->CR & ADC_CR_ADCAL) {}; + // set ADC clock to 4MHz + ADC1->CFGR2 = LL_ADC_CLOCK_ASYNC_HSI_DIV2; + // do our first round of conversions adc_go(); @@ -185,7 +191,7 @@ uint8_t adc_next() for (j = 0; j < ADC_HISTLEN; j++) { adc_avg[i] += adc_hist[i][j]; } - adc_avg[i] >>= 4; + adc_avg[i] /= ADC_HISTLEN; } // check vref to determine if we need to recalibrate diff --git a/src/main.c b/src/main.c index ee39a20..786d053 100644 --- a/src/main.c +++ b/src/main.c @@ -116,7 +116,7 @@ int main() while (1) { // run LED programs out of interrupt context at 256Hz - if ((ctr & 0xf) == 0) { + if (!(ctr & 0xf)) { if (userio_get_mode() == MODE_FUN) { rgbprog_run(); } @@ -130,6 +130,8 @@ int main() /* * main application interrupt */ +uint16_t adc_ctr = 0; // count ADC cycles +volatile uint16_t adc_sec; // ADC cycles per second (used w/debugger) void SysTick_Handler(void) { @@ -144,16 +146,21 @@ void SysTick_Handler(void) ctr &= 0xfff; if (!ctr) { uptime++; + adc_sec = adc_ctr; + adc_ctr = 0; } - // run main logic at 1024Hz - if (!(ctr & 0x3)) { + // run main logic at 2048Hz + if (!(ctr & 0x1)) { // shifted counter for use in the program - cs = ctr >> 2; + cs = ctr >> 1; // adc tested to result in about 61 reads/second if (!adc_next()) { // adc has new computed results + adc_ctr++; + + // start using ADC results only after the first cycle if (uptime || cs) { // figure out knobs, buttons, switches userio_parse();