diff options
-rw-r--r-- | libmaple/adc.c | 32 | ||||
-rw-r--r-- | libmaple/adc.h | 20 | ||||
-rw-r--r-- | wirish/wirish.c | 6 |
3 files changed, 48 insertions, 10 deletions
diff --git a/libmaple/adc.c b/libmaple/adc.c index b70c8bd..3e6818c 100644 --- a/libmaple/adc.c +++ b/libmaple/adc.c @@ -60,7 +60,9 @@ * * At 55.5 cycles/sample, the external input impedance < 50kOhms*/ -void adc_init(void) { +void set_adc_smprx(adc_smp_rate smp_rate); + +void adc_init(adc_smp_rate smp_rate) { rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); rcc_clk_enable(RCC_ADC1); rcc_reset_dev(RCC_ADC1); @@ -70,11 +72,9 @@ void adc_init(void) { ADC_CR2 = CR2_EXTSEL_SWSTART | CR2_EXTTRIG; ADC_SQR1 = 0; - /* Up the sample conversion time to 55.5 cycles/sec, see note - above */ - /* TODO: fix magic numbers */ - ADC_SMPR1 = 0xB6DB6D; - ADC_SMPR2 = 0x2DB6DB6D; + /* Set the sample conversion time. See note above for impedance + requirements. */ + adc_set_sample_rate(smp_rate); /* Enable the ADC */ CR2_ADON_BIT = 1; @@ -93,3 +93,23 @@ void adc_init(void) { void adc_disable(void) { CR2_ADON_BIT = 0; } + +/* Turn the given sample rate into values for ADC_SMPRx. (Don't + * precompute in order to avoid wasting space). + * + * Don't call this during conversion! + */ +void adc_set_sample_rate(adc_smp_rate smp_rate) { + uint32 adc_smpr1_val = 0, adc_smpr2_val = 0; + int i; + for (i = 0; i < 10; i++) { + if (i < 8) { + /* ADC_SMPR1 determines sample time for channels [10,17] */ + adc_smpr1_val |= smp_rate << (i * 3); + } + /* ADC_SMPR2 determines sample time for channels [0,9] */ + adc_smpr2_val |= smp_rate << (i * 3); + } + ADC_SMPR1 = adc_smpr1_val; + ADC_SMPR2 = adc_smpr2_val; +} diff --git a/libmaple/adc.h b/libmaple/adc.h index fe1196f..976986f 100644 --- a/libmaple/adc.h +++ b/libmaple/adc.h @@ -70,8 +70,24 @@ extern "C"{ #define SR_EOC_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0, 1)) /* (NR_ANALOG_PINS is board specific) */ -/** Initialize ADC1 to do one-shot conversions */ -void adc_init(void); +/** ADC per-sample conversion times, in ADC clock cycles */ +typedef enum { + ADC_SMPR_1_5, + ADC_SMPR_7_5, + ADC_SMPR_13_5, + ADC_SMPR_28_5, + ADC_SMPR_41_5, + ADC_SMPR_55_5, + ADC_SMPR_71_5, + ADC_SMPR_239_5 +} adc_smp_rate; + +/** Initialize ADC1 to do one-shot conversions at the given sample + rate. */ +void adc_init(adc_smp_rate smp_rate); + +void adc_set_sample_rate(adc_smp_rate smp_rate); + void adc_disable(void); /** diff --git a/wirish/wirish.c b/wirish/wirish.c index 5935f95..aaae9d4 100644 --- a/wirish/wirish.c +++ b/wirish/wirish.c @@ -54,7 +54,7 @@ void init(void) { #if NR_DAC_PINS > 0 dac_init(); #endif - + /* initialize clocks */ rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); @@ -64,7 +64,9 @@ void init(void) { nvic_init(); systick_init(SYSTICK_RELOAD_VAL); gpio_init(); - adc_init(); + /* Initialize the ADC for slow conversions, to allow for high + impedance inputs. */ + adc_init(ADC_SMPR_55_5); timer_init(TIMER1, 1); timer_init(TIMER2, 1); timer_init(TIMER3, 1); |