aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmaple/adc.c32
-rw-r--r--libmaple/adc.h20
-rw-r--r--wirish/wirish.c6
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);