aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/platforms/STM32F0xx/adc_lld.c28
-rw-r--r--os/hal/platforms/STM32F0xx/adc_lld.h15
-rw-r--r--testhal/STM32F0xx/ADC/main.c8
3 files changed, 38 insertions, 13 deletions
diff --git a/os/hal/platforms/STM32F0xx/adc_lld.c b/os/hal/platforms/STM32F0xx/adc_lld.c
index af03bd058..7f8414743 100644
--- a/os/hal/platforms/STM32F0xx/adc_lld.c
+++ b/os/hal/platforms/STM32F0xx/adc_lld.c
@@ -109,15 +109,23 @@ CH_IRQ_HANDLER(ADC1_COMP_IRQHandler) {
isr = ADC1->ISR;
ADC1->ISR = isr;
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((isr & ADC_ISR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- if (ADCD1.grpp != NULL)
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (ADCD1.grpp != NULL) {
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((isr & ADC_ISR_OVR) &&
+ (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
_adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
+ }
+ if (isr & ADC_ISR_AWD) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(&ADCD1, ADC_ERR_AWD);
+ }
}
- /* TODO: Add here analog watchdog handling.*/
CH_IRQ_EPILOGUE();
}
@@ -258,9 +266,11 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
(uint32_t)adcp->depth);
dmaStreamSetMode(adcp->dmastp, mode);
- /* ADC setup.*/
+ /* ADC setup, if it is defined a callback for the analog watch dog then it
+ is enabled.*/
adcp->adc->ISR = adcp->adc->ISR;
- adcp->adc->IER = ADC_IER_OVRIE;
+ adcp->adc->IER = ADC_IER_OVRIE | ADC_IER_AWDIE;
+ adcp->adc->TR = grpp->tr;
adcp->adc->SMPR = grpp->smpr;
adcp->adc->CHSELR = grpp->chselr;
diff --git a/os/hal/platforms/STM32F0xx/adc_lld.h b/os/hal/platforms/STM32F0xx/adc_lld.h
index dce0d7d1a..a0d823a8b 100644
--- a/os/hal/platforms/STM32F0xx/adc_lld.h
+++ b/os/hal/platforms/STM32F0xx/adc_lld.h
@@ -59,6 +59,13 @@
#define ADC_CFGR1_RES_6BIT (3 << 3)
/** @} */
+/**
+ * @name Threashold register initializer
+ * @{
+ */
+#define ADC_TR(low, high) (((uint32_t)(high) << 16) | (uint32_t)(low))
+/** @} */
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -151,7 +158,8 @@ typedef uint16_t adc_channels_num_t;
*/
typedef enum {
ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */
+ ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
+ ADC_ERR_AWD = 2 /**< Analog watchdog triggered. */
} adcerror_t;
/**
@@ -174,6 +182,7 @@ typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
*
* @param[in] adcp pointer to the @p ADCDriver object triggering the
* callback
+ * @param[in] err ADC error code
*/
typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
@@ -208,6 +217,10 @@ typedef struct {
*/
uint32_t cfgr1;
/**
+ * @brief ADC TR register initialization data.
+ */
+ uint32_t tr;
+ /**
* @brief ADC SMPR register initialization data.
*/
uint32_t smpr;
diff --git a/testhal/STM32F0xx/ADC/main.c b/testhal/STM32F0xx/ADC/main.c
index 6038a2fb2..bdb8bed0f 100644
--- a/testhal/STM32F0xx/ADC/main.c
+++ b/testhal/STM32F0xx/ADC/main.c
@@ -61,9 +61,10 @@ static const ADCConversionGroup adcgrpcfg1 = {
ADC_GRP1_NUM_CHANNELS,
NULL,
adcerrorcallback,
- ADC_CFGR1_RES_12BIT, /* CFGRR1 */
- ADC_SMPR_SMP_1P5, /* SMPR */
- ADC_CHSELR_CHSEL10 /* CHSELR */
+ ADC_CFGR1_RES_12BIT, /* CFGRR1 */
+ ADC_TR(0, 0), /* TR */
+ ADC_SMPR_SMP_1P5, /* SMPR */
+ ADC_CHSELR_CHSEL10 /* CHSELR */
};
/*
@@ -77,6 +78,7 @@ static const ADCConversionGroup adcgrpcfg2 = {
adccallback,
adcerrorcallback,
ADC_CFGR1_RES_12BIT, /* CFGRR1 */
+ ADC_TR(0, 0), /* TR */
ADC_SMPR_SMP_28P5, /* SMPR */
ADC_CHSELR_CHSEL10 | ADC_CHSELR_CHSEL11 |
ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17 /* CHSELR */