aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2010-10-12 20:47:30 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2010-10-12 20:47:30 +0000
commitec7455babe131ee0b8a4c228ed00a02396619a7d (patch)
treea3a8fb7fd348052d3a2f52511e2673d37d1dd5f9 /os
parentf49c8de5b2d1a4e35bef8daa2a923f751d6e17b3 (diff)
downloadChibiOS-ec7455babe131ee0b8a4c228ed00a02396619a7d.tar.gz
ChibiOS-ec7455babe131ee0b8a4c228ed00a02396619a7d.tar.bz2
ChibiOS-ec7455babe131ee0b8a4c228ed00a02396619a7d.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2253 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/adc.h97
-rw-r--r--os/hal/platforms/STM32/adc_lld.c42
2 files changed, 99 insertions, 40 deletions
diff --git a/os/hal/include/adc.h b/os/hal/include/adc.h
index dab90b477..3a4a08de0 100644
--- a/os/hal/include/adc.h
+++ b/os/hal/include/adc.h
@@ -115,16 +115,105 @@ typedef enum {
} \
}
-#else /* !ADC_USE_WAIT */
+/**
+ * @brief Wakes up the waiting thread.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_wakeup_i(adcp) { \
+ chSysLockFromIsr(); \
+ (adcp)->ad_grpp = NULL; \
+ if ((adcp)->ad_thread != NULL) { \
+ Thread *tp = (adcp)->ad_thread; \
+ (adcp)->ad_thread = NULL; \
+ tp->p_u.rdymsg = RDY_OK; \
+ chSchReadyI(tp); \
+ } \
+ chSysUnlockFromIsr(); \
+}
+#else /* !ADC_USE_WAIT */
#define _adc_reset_i(adcp)
-
#define _adc_reset_s(adcp)
+#define _adc_wakeup(adcp)
+#endif /* !ADC_USE_WAIT */
-#define _adc_isr_code(adcp) { \
+/**
+ * @brief Common ISR code, half buffer full.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_isr_half_code(adcp) { \
+ if ((adcp)->ad_grpp->acg_endcb != NULL) { \
+ (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
+ (adcp)->ad_depth / 2); \
+ } \
}
-#endif /* !ADC_USE_WAIT */
+/**
+ * @brief Common ISR code, full buffer full.
+ * @details This code handles the portable part of the ISR code:
+ * - Callback invocation.
+ * - Waiting thread wakeup, if any.
+ * - Driver state transitions.
+ * .
+ * @note This macro is meant to be used in the low level drivers
+ * implementation only.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+#define _adc_isr_full_code(adcp) { \
+ if ((adcp)->ad_grpp->acg_circular) { \
+ /* Callback handling.*/ \
+ if ((adcp)->ad_grpp->acg_endcb != NULL) { \
+ if ((adcp)->ad_depth > 1) { \
+ /* Invokes the callback passing the 2nd half of the buffer.*/ \
+ size_t half = (adcp)->ad_depth / 2; \
+ (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples + half, half); \
+ } \
+ else { \
+ /* Invokes the callback passing the whole buffer.*/ \
+ (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
+ (adcp)->ad_depth); \
+ } \
+ } \
+ } \
+ else { \
+ (adcp)->ad_grpp = NULL; \
+ /* End conversion.*/ \
+ adc_lld_stop_conversion(adcp); \
+ if ((adcp)->ad_grpp->acg_endcb == NULL) { \
+ (adcp)->ad_state = ADC_READY; \
+ _adc_wakeup_i(adcp); \
+ } \
+ else { \
+ (adcp)->ad_state = ADC_COMPLETE; \
+ if ((adcp)->ad_depth > 1) { \
+ /* Invokes the callback passing the 2nd half of the buffer.*/ \
+ size_t half = (adcp)->ad_depth / 2; \
+ (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples + half, half); \
+ } \
+ else { \
+ /* Invokes the callback passing the whole buffer.*/ \
+ (adcp)->ad_grpp->acg_endcb(adcp, (adcp)->ad_samples, \
+ (adcp)->ad_depth); \
+ } \
+ if ((adcp)->ad_state == ADC_COMPLETE) \
+ (adcp)->ad_state = ADC_READY; \
+ } \
+ } \
+}
/*===========================================================================*/
/* External declarations. */
diff --git a/os/hal/platforms/STM32/adc_lld.c b/os/hal/platforms/STM32/adc_lld.c
index cbb206a2e..9df5bb5e1 100644
--- a/os/hal/platforms/STM32/adc_lld.c
+++ b/os/hal/platforms/STM32/adc_lld.c
@@ -64,47 +64,17 @@ CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) {
isr = STM32_DMA1->ISR;
dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_1);
+ if ((isr & DMA_ISR_TEIF1) != 0) {
+ /* DMA error processing.*/
+ STM32_ADC1_DMA_ERROR_HOOK();
+ }
if ((isr & DMA_ISR_HTIF1) != 0) {
/* Half transfer processing.*/
- if (ADCD1.ad_grpp->acg_endcb != NULL) {
- /* Invokes the callback passing the 1st half of the buffer.*/
- ADCD1.ad_grpp->acg_endcb(&ADCD1, ADCD1.ad_samples, ADCD1.ad_depth / 2);
- }
+ _adc_isr_half_code(&ADCD1);
}
if ((isr & DMA_ISR_TCIF1) != 0) {
/* Transfer complete processing.*/
- if (!ADCD1.ad_grpp->acg_circular) {
- /* End conversion.*/
- adc_lld_stop_conversion(&ADCD1);
- ADCD1.ad_grpp = NULL;
- ADCD1.ad_state = ADC_COMPLETE;
-#if ADC_USE_WAIT
- chSysLockFromIsr();
- if (ADCD1.ad_thread != NULL) {
- Thread *tp = ADCD1.ad_thread;
- ADCD1.ad_thread = NULL;
- tp->p_u.rdymsg = RDY_OK;
- chSchReadyI(tp);
- }
- chSysUnlockFromIsr();
-#endif
- }
- /* Callback handling.*/
- if (ADCD1.ad_grpp->acg_endcb != NULL) {
- if (ADCD1.ad_depth > 1) {
- /* Invokes the callback passing the 2nd half of the buffer.*/
- size_t half = ADCD1.ad_depth / 2;
- ADCD1.ad_grpp->acg_endcb(&ADCD1, ADCD1.ad_samples + half, half);
- }
- else {
- /* Invokes the callback passing the whole buffer.*/
- ADCD1.ad_grpp->acg_endcb(&ADCD1, ADCD1.ad_samples, ADCD1.ad_depth);
- }
- }
- }
- if ((isr & DMA_ISR_TEIF1) != 0) {
- /* DMA error processing.*/
- STM32_ADC1_DMA_ERROR_HOOK();
+ _adc_isr_full_code(&ADCD1);
}
CH_IRQ_EPILOGUE();