aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-09-22 14:53:42 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-09-22 14:53:42 +0000
commit4a3e3fc01ec6dfb4a710db771bee262d5dc9327e (patch)
treee1ff2640c6b25bf93b3d461ff867ce3353a62424 /os/hal/platforms
parent40c7a8982aaef28d6ac7cbbd378708f237711ccf (diff)
downloadChibiOS-4a3e3fc01ec6dfb4a710db771bee262d5dc9327e.tar.gz
ChibiOS-4a3e3fc01ec6dfb4a710db771bee262d5dc9327e.tar.bz2
ChibiOS-4a3e3fc01ec6dfb4a710db771bee262d5dc9327e.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3381 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms')
-rw-r--r--os/hal/platforms/STM32F1xx/adc_lld.c26
-rw-r--r--os/hal/platforms/STM32F1xx/adc_lld.h30
-rw-r--r--os/hal/platforms/STM32L1xx/adc_lld.c51
-rw-r--r--os/hal/platforms/STM32L1xx/adc_lld.h34
4 files changed, 95 insertions, 46 deletions
diff --git a/os/hal/platforms/STM32F1xx/adc_lld.c b/os/hal/platforms/STM32F1xx/adc_lld.c
index ac74251f8..84b194c0f 100644
--- a/os/hal/platforms/STM32F1xx/adc_lld.c
+++ b/os/hal/platforms/STM32F1xx/adc_lld.c
@@ -57,20 +57,20 @@ ADCDriver ADCD1;
static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
/* DMA errors handling.*/
-#if defined(STM32_ADC_DMA_ERROR_HOOK)
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
- STM32_ADC_DMA_ERROR_HOOK(spip);
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
}
-#else
- (void)flags;
-#endif
- if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
+ else {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
}
}
@@ -146,7 +146,7 @@ void adc_lld_start(ADCDriver *adcp) {
/* ADC setup, the calibration procedure has already been performed
during initialization.*/
- adcp->adc->CR1 = ADC_CR1_SCAN;
+ adcp->adc->CR1 = 0;
adcp->adc->CR2 = 0;
}
}
diff --git a/os/hal/platforms/STM32F1xx/adc_lld.h b/os/hal/platforms/STM32F1xx/adc_lld.h
index 1d1052f50..e3a327afa 100644
--- a/os/hal/platforms/STM32F1xx/adc_lld.h
+++ b/os/hal/platforms/STM32F1xx/adc_lld.h
@@ -108,15 +108,6 @@
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
#endif
-/**
- * @brief ADC DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
-#endif
-
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
@@ -148,6 +139,15 @@ typedef uint16_t adcsample_t;
typedef uint16_t adc_channels_num_t;
/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */
+} adcerror_t;
+
+/**
* @brief Type of a structure representing an ADC driver.
*/
typedef struct ADCDriver ADCDriver;
@@ -163,6 +163,14 @@ typedef struct ADCDriver ADCDriver;
typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
/**
+ * @brief ADC error callback type.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object triggering the
+ * callback
+ */
+typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
+
+/**
* @brief Conversion group configuration structure.
* @details This implementation-dependent structure describes a conversion
* operation.
@@ -183,6 +191,10 @@ typedef struct {
* @brief Callback function associated to the group or @p NULL.
*/
adccallback_t end_cb;
+ /**
+ * @brief Error callback or @p NULL.
+ */
+ adcerrorcallback_t error_cb;
/* End of the mandatory fields.*/
/**
* @brief ADC CR1 register initialization data.
diff --git a/os/hal/platforms/STM32L1xx/adc_lld.c b/os/hal/platforms/STM32L1xx/adc_lld.c
index 9ccb198e4..a2149b6ae 100644
--- a/os/hal/platforms/STM32L1xx/adc_lld.c
+++ b/os/hal/platforms/STM32L1xx/adc_lld.c
@@ -57,20 +57,20 @@ ADCDriver ADCD1;
static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
/* DMA errors handling.*/
-#if defined(STM32_ADC_DMA_ERROR_HOOK)
if ((flags & STM32_DMA_ISR_TEIF) != 0) {
- STM32_ADC_DMA_ERROR_HOOK(spip);
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
}
-#else
- (void)flags;
-#endif
- if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
+ else {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
}
}
@@ -78,6 +78,29 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
/* Driver interrupt handlers. */
/*===========================================================================*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+/**
+ * @brief ADC1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(UART5_IRQHandler) {
+ uint32_t sr;
+
+ CH_IRQ_PROLOGUE();
+
+ sr = ADC1->SR;
+ ADC1->SR = 0;
+ if (sr & ADC_SR_OVR) {
+ /* 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);
+ }
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@@ -145,6 +168,7 @@ void adc_lld_stop(ADCDriver *adcp) {
if (adcp->state == ADC_READY) {
#if STM32_ADC_USE_ADC1
if (&ADCD1 == adcp) {
+ ADC1->CR1 = 0;
ADC1->CR2 = 0;
dmaStreamRelease(adcp->dmastp);
rccDisableADC1(FALSE);
@@ -182,7 +206,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
/* ADC setup.*/
adcp->adc->SR = 0;
- adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
+ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;
adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */
adcp->adc->SMPR2 = grpp->smpr2;
adcp->adc->SMPR3 = grpp->smpr3;
@@ -211,6 +235,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) {
void adc_lld_stop_conversion(ADCDriver *adcp) {
dmaStreamDisable(adcp->dmastp);
+ adcp->adc->CR1 = 0;
adcp->adc->CR2 = 0;
}
diff --git a/os/hal/platforms/STM32L1xx/adc_lld.h b/os/hal/platforms/STM32L1xx/adc_lld.h
index 2889387ab..0ca41c269 100644
--- a/os/hal/platforms/STM32L1xx/adc_lld.h
+++ b/os/hal/platforms/STM32L1xx/adc_lld.h
@@ -39,8 +39,7 @@
* @name Triggers selection
* @{
*/
-#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
-#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */
+#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */
/** @} */
/**
@@ -136,15 +135,6 @@
#define STM32_ADC_ADC1_IRQ_PRIORITY 5
#endif
-/**
- * @brief ADC DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_ADC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_ADC_DMA_ERROR_HOOK(adcp) chSysHalt()
-#endif
-
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
@@ -176,6 +166,16 @@ typedef uint16_t adcsample_t;
typedef uint16_t adc_channels_num_t;
/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */
+} adcerror_t;
+
+/**
* @brief Type of a structure representing an ADC driver.
*/
typedef struct ADCDriver ADCDriver;
@@ -191,6 +191,14 @@ typedef struct ADCDriver ADCDriver;
typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
/**
+ * @brief ADC error callback type.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object triggering the
+ * callback
+ */
+typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
+
+/**
* @brief Conversion group configuration structure.
* @details This implementation-dependent structure describes a conversion
* operation.
@@ -211,6 +219,10 @@ typedef struct {
* @brief Callback function associated to the group or @p NULL.
*/
adccallback_t end_cb;
+ /**
+ * @brief Error callback or @p NULL.
+ */
+ adcerrorcallback_t error_cb;
/* End of the mandatory fields.*/
/**
* @brief ADC CR1 register initialization data.