diff --git a/include/libopenstm32/adc.h b/include/libopenstm32/adc.h index d1ba9ec3..4f15b26e 100644 --- a/include/libopenstm32/adc.h +++ b/include/libopenstm32/adc.h @@ -339,6 +339,7 @@ /* --- Function prototypes ------------------------------------------------- */ + /* TODO */ void adc_enable_analog_watchdog_regular(u32 adc); void adc_disable_analog_watchdog_regular(u32 adc); @@ -360,5 +361,29 @@ void adc_enable_awd_interrupt(u32 adc); void adc_disable_awd_interrupt(u32 adc); void adc_enable_eoc_interrupt(u32 adc); void adc_disable_eoc_interrupt(u32 adc); +void adc_enable_temperature_sensor(u32 adc); +void adc_disable_temperature_sensor(u32 adc); +void adc_start_conversion_regular(u32 adc); +void adc_start_conversion_injected(u32 adc); +void adc_enable_external_trigger_regular(u32 adc, u8 trigger); +void adc_disable_external_trigger_regular(u32 adc); +void adc_enable_external_trigger_injected(u32 adc, u8 trigger); +void adc_disable_external_trigger_injected(u32 adc); +void adc_set_left_aligned(u32 adc); +void adc_set_right_aligned(u32 adc); +void adc_enable_dma(u32 adc); +void adc_disable_dma(u32 adc); +void adc_reset_calibration(u32 adc); +void adc_calibration(u32 adc); +void adc_set_continous_conversion_mode(u32 adc); +void adc_set_single_conversion_mode(u32 adc); +void adc_on(u32 adc); +void adc_off(u32 adc); +void adc_set_conversion_time(u32 adc, u8 channel, u8 time); +void adc_set_conversion_time_on_all_channels(u32 adc, u8 time); +void adc_set_watchdog_high_threshold(u32 adc, u16 threshold); +void adc_set_watchdog_low_threshold(u32 adc, u16 threshold); +void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]); +void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]); #endif diff --git a/lib/adc.c b/lib/adc.c index 01fe2fd8..b47e4839 100644 --- a/lib/adc.c +++ b/lib/adc.c @@ -164,3 +164,213 @@ void adc_disable_eoc_interrupt(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_EOCIE; } + +void adc_enable_temperature_sensor(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_TSVREFE; +} + +void adc_disable_temperature_sensor(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_TSVREFE; +} + +void adc_start_conversion_regular(u32 adc) +{ + /* start conversion on regular channels */ + ADC_CR2(adc) |= ADC_CR2_SWSTART; + + /* wait til the ADC starts the conversion */ + while (ADC_CR2(adc) & ADC_CR2_SWSTART); +} + +void adc_start_conversion_injected(u32 adc) +{ + /* start conversion on injected channels */ + ADC_CR2(adc) |= ADC_CR2_JSWSTART; + + /* wait til the ADC starts the conversion */ + while (ADC_CR2(adc) & ADC_CR2_JSWSTART); +} + +void adc_enable_external_trigger_regular(u32 adc, u8 trigger) +{ + u32 reg32; + + reg32 = (ADC_CR2(adc) & 0xfff1ffff); /* Clear bits [19:17]. */ + if (trigger < 8) + reg32 |= (trigger << ADC_CR2_EXTSEL_LSB); + ADC_CR2(adc) = reg32; + ADC_CR2(adc) |= ADC_CR2_EXTTRIG; +} + +void adc_disable_external_trigger_regular(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTTRIG; +} + +void adc_enable_external_trigger_injected(u32 adc, u8 trigger) +{ + u32 reg32; + + reg32 = (ADC_CR2(adc) & 0xffff8fff); /* Clear bits [12:14]. */ + if (trigger < 8) + reg32 |= (trigger << ADC_CR2_JEXTSEL_LSB); + ADC_CR2(adc) = reg32; + ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; +} + +void adc_disable_external_trigger_injected(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTTRIG; +} + +void adc_set_left_aligned(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_ALIGN; +} + +void adc_set_right_aligned(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ALIGN; +} + +void adc_enable_dma(u32 adc) +{ + if ((adc == ADC1) | (adc==ADC3)) + ADC_CR2(adc) |= ADC_CR2_DMA; +} + +void adc_disable_dma(u32 adc) +{ + if ((adc == ADC1) | (adc==ADC3)) + ADC_CR2(adc) &= ~ADC_CR2_DMA; +} + +void adc_reset_calibration(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_RSTCAL; + while (ADC_CR2(adc) & ADC_CR2_RSTCAL); +} + +void adc_calibration(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_CAL; + while (ADC_CR2(adc) & ADC_CR2_CAL); +} + +void adc_set_continous_conversion_mode(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_CONT; +} + +void adc_set_single_conversion_mode(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_CONT; +} + +void adc_on(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_ADON; +} + +void adc_off(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ADON; +} + +void adc_set_conversion_time(u32 adc, u8 channel, u8 time) +{ + u32 reg32; + + if (channel < 10) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0b111 << (channel * 3)); + reg32 |= (time << (channel *3)); + ADC_SMPR2(adc) = reg32; + } + else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0b111 << ((channel-10) *3)); + reg32 |= (time << ((channel-10) *3)); + ADC_SMPR1(adc) = reg32; + } +} + +void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) +{ + u32 reg32 = 0; + u8 i; + + for (i=0; i<=9; i++) { + reg32 |= (time << (i * 3)); + } + ADC_SMPR2(adc) = reg32; + + for (i=10; i<=17; i++) { + reg32 |= (time << ((i-10) * 3)); + } + ADC_SMPR1(adc) = reg32; +} + +void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) +{ + u32 reg32 = 0; + + reg32 = (u32)threshold; + reg32 &= ~0xfffff000; /* clear all bits above 11 */ + ADC_HTR(adc) = reg32; +} + +void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) +{ + u32 reg32 = 0; + + reg32 = (u32)threshold; + reg32 &= ~0xfffff000; /* clear all bits above 11 */ + ADC_LTR(adc) = reg32; +} + +void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) +{ + u32 reg32_1 = 0; + u32 reg32_2 = 0; + u32 reg32_3 = 0; + u8 i = 0; + + /* maximum sequence length is 16 channels */ + if (length > 16) + return; + + for (i=1; i<=length; i++) { + if (i<=6) + reg32_3 |= (channel[i-1] << ((i-1) * 5)); + if ((i>6) & (i<=12)) + reg32_2 |= (channel[i-6-1] << ((i-6-1) * 5)); + if ((i>12) & (i<=16)) + reg32_1 |= (channel[i-12-1] << ((i-12-1) * 5)); + } + reg32_1 |= (length << ADC_SQR1_L_LSB); + + ADC_SQR1(adc) = reg32_1; + ADC_SQR2(adc) = reg32_2; + ADC_SQR3(adc) = reg32_3; +} + +void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) +{ + u32 reg32 = 0; + u8 i = 0; + + /* maximum sequence length is 4 channels */ + if (length > 4) + return; + + for (i=1; i<=length; i++) { + reg32 |= (channel[i-1] << ((i-1) * 5)); + } + reg32 |= (length << ADC_JSQR_JL_LSB); + + ADC_JSQR(adc) = reg32; +} +