From e1868bc0b1a52cf22a2684595afca26dc8814550 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 6 Mar 2013 11:36:21 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5367 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/PPC-SPC563M-GCC/mcuconf.h | 8 +- os/hal/platforms/SPC563Mxx/spc563m_registry.h | 2 - os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h | 148 ++++++++++- os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c | 240 +++++++++++++++--- os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h | 35 ++- 5 files changed, 373 insertions(+), 60 deletions(-) diff --git a/demos/PPC-SPC563M-GCC/mcuconf.h b/demos/PPC-SPC563M-GCC/mcuconf.h index c3d3be8f3..bca85fb65 100644 --- a/demos/PPC-SPC563M-GCC/mcuconf.h +++ b/demos/PPC-SPC563M-GCC/mcuconf.h @@ -46,11 +46,11 @@ * ADC driver settings. */ #define SPC5_ADC_USE_ADC0_Q0 TRUE -#define SPC5_ADC_USE_ADC0_Q1 FALSE -#define SPC5_ADC_USE_ADC0_Q2 FALSE +#define SPC5_ADC_USE_ADC0_Q1 TRUE +#define SPC5_ADC_USE_ADC0_Q2 TRUE #define SPC5_ADC_USE_ADC1_Q3 TRUE -#define SPC5_ADC_USE_ADC1_Q4 FALSE -#define SPC5_ADC_USE_ADC1_Q5 FALSE +#define SPC5_ADC_USE_ADC1_Q4 TRUE +#define SPC5_ADC_USE_ADC1_Q5 TRUE #define SPC5_ADC_CR_CLK_PS ADC_CR_CLK_PS(5) /* diff --git a/os/hal/platforms/SPC563Mxx/spc563m_registry.h b/os/hal/platforms/SPC563Mxx/spc563m_registry.h index 6b9cb2d7d..40d2cd07c 100644 --- a/os/hal/platforms/SPC563Mxx/spc563m_registry.h +++ b/os/hal/platforms/SPC563Mxx/spc563m_registry.h @@ -38,8 +38,6 @@ /* eQADC attributes.*/ #define SPC5_HAS_EQADC TRUE -#define SPC5_EQADC1_HANDLER vector146 -#define SPC5_EQADC1_NUMBER 146 /* eSCI attributes.*/ #define SPC5_HAS_ESCIA TRUE diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h index ad7f5ed5e..5b0f00843 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h @@ -36,7 +36,19 @@ /** * @brief EDMA channel allocation error. */ -#define EDMA_ERROR -1 +#define EDMA_ERROR -1 + +/** + * @name EDMA mode constants + * @{ + */ +#define EDMA_TCD_MODE_START (1U << 0) +#define EDMA_TCD_MODE_INT_END (1U << 1) +#define EDMA_TCD_MODE_INT_HALF (1U << 2) +#define EDMA_TCD_MODE_DREQ (1U << 3) +#define EDMA_TCD_MODE_ACTIVE (1U << 6) +#define EDMA_TCD_MODE_DONE (1U << 7) +/** @} */ /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -77,7 +89,10 @@ typedef int32_t edma_channel_t; * @brief Type of an EDMA TCD. */ typedef struct { - uint32_t word[8]; + union { + uint32_t word[8]; + uint32_t hword[16]; + }; } edma_tcd_t; /** @@ -121,22 +136,114 @@ typedef struct { * @brief Sets the source address into a TCD. * * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] dst the source address * * @api */ -#define edmaChannelSetSourceAddress(tcdp, src) \ +#define edmaTCDSetSourceAddress(tcdp, src) \ ((tcdp)->word[0] = (uint32_t)(src)) /** * @brief Sets the destination address into a TCD. * * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] dst the destination address * * @api */ -#define edmaChannelSetDestinationAddress(tcdp, dst) \ +#define edmaTCDSetDestinationAddress(tcdp, dst) \ ((tcdp)->word[4] = (uint32_t)(dst)) +/** + * @brief Sets the transfer widths into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] ssize the source width + * @param[in] dst the destination width + * + * @api + */ +#define edmaTCDSetTransferWidths(tcdp, ssize, dsize) \ + ((tcdp)->hword[2] = ((uint16_t)((ssize) << 8) | (uint16_t)(dsize))) + +/** + * @brief Sets the inner loop counter value into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] nbytes the inner counter value + * + * @api + */ +#define edmaTCDSetInnnerLoopCount(tcdp, nbytes) \ + ((tcdp)->word[2] = (uint32_t)(nbytes)) + +/** + * @brief Sets the source address increment value into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] soff the source increment value + * + * @api + */ +#define edmaTCDSetSetSourceIncrement(tcdp, soff) \ + ((tcdp)->hword[3] = (uint16_t)(soff)) + +/** + * @brief Sets the destination address increment value into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] soff the source increment value + * + * @api + */ +#define edmaTCDSetSetDestinationIncrement(tcdp, doff) \ + ((tcdp)->hword[3] = (uint16_t)(doff)) + +/** + * @brief Sets the outer loop counter value into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] iter the outer counter value + * + * @api + */ +#define edmaTCDSetOuterLoopCount(tcdp, iter) { \ + ((tcdp)->hword[10] = (uint16_t)(iter)); \ + ((tcdp)->hword[14] = (uint16_t)(iter)); \ +} + +/** + * @brief Sets the source address adjustment into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] iter the adjustment value + * + * @api + */ +#define edmaTCDSetSourceAdjustment(tcdp, slast) \ + ((tcdp)->word[3] = (uint32_t)(slast)) + +/** + * @brief Sets the destination address adjustment into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] iter the adjustment value + * + * @api + */ +#define edmaTCDSetDestinationAdjustment(tcdp, dlast) \ + ((tcdp)->word[6] = (uint32_t)(dlast)) + +/** + * @brief Sets the channel mode bits into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] iter the adjustment value + * + * @api + */ +#define edmaTCDSetMode(tcdp, mode) ((tcdp)->hword[15] = (uint16_t)(mode)) + /** * @brief Starts or restarts an EDMA channel. * @@ -174,19 +281,32 @@ typedef struct { * @api */ #define edmaChannelSetup(channel, src, dst, soff, doff, ssize, dsize, \ - nbytes, iter, slast, dlast, mode) { \ + nbytes, iter, slast, dlast, mode) { \ edma_tcd_t *tcdp = edmaGetTCD(channel); \ - tcdp->word[0] = (uint32_t)(src); \ - tcdp->word[1] = ((uint32_t)(ssize) << 24) | ((uint32_t)(dsize) << 16) | \ - (uint32_t)(soff); \ - tcdp->word[2] = (uint32_t)(nbytes); \ - tcdp->word[3] = (uint32_t)(slast); \ - tcdp->word[0] = (uint32_t)(dst); \ - tcdp->word[5] = ((uint32_t)(iter) << 16) | (uint32_t)(doff); \ - tcdp->word[6] = (uint32_t)(dlast); \ - tcdp->word[7] = ((uint32_t)(iter) << 16) | (uint32_t)(mode); \ + edmaTCDSetSourceAddress(tcdp, src); \ + edmaTCDSetDestinationAddress(tcdp, dst); \ + edmaTCDSetSetSourceIncrement(tcdp, soff); \ + edmaTCDSetSetDestinationIncrement(tcdp, doff); \ + edmaTCDSetTransferWidths(tcdp, ssize, dsize); \ + edmaTCDSetInnnerLoopCount(tcdp, nbytes); \ + edmaTCDSetOuterLoopCount(tcdp, iter); \ + edmaTCDSetSourceAdjustment(tcdp, slast); \ + edmaTCDSetDestinationAdjustment(tcdp, dlast); \ + edmaTCDSetMode(tcdp, dlast); \ } +#if 0 +tcdp->word[0] = (uint32_t)(src); \ +tcdp->word[1] = ((uint32_t)(ssize) << 24) | ((uint32_t)(dsize) << 16) | \ + (uint32_t)(soff); \ +tcdp->word[2] = (uint32_t)(nbytes); \ +tcdp->word[3] = (uint32_t)(slast); \ +tcdp->word[0] = (uint32_t)(dst); \ +tcdp->word[5] = ((uint32_t)(iter) << 16) | (uint32_t)(doff); \ +tcdp->word[6] = (uint32_t)(dlast); \ +tcdp->word[7] = ((uint32_t)(iter) << 16) | (uint32_t)(mode); +#endif + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c index b198c1799..2a27c62f7 100644 --- a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c +++ b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c @@ -27,8 +27,7 @@ /* Some forward declarations.*/ static void adc_serve_rfifo_irq(edma_channel_t channel, void *p); -static void adc_serve_rfifo_error_irq(edma_channel_t channel, void *p); -static void adc_serve_cfifo_error_irq(edma_channel_t channel, void *p); +static void adc_serve_dma_error_irq(edma_channel_t channel, void *p); /*===========================================================================*/ /* Driver local definitions. */ @@ -97,41 +96,122 @@ static const uint16_t pudcrs[8] = SPC5_ADC_PUDCR; * @brief DMA configuration for EQADC CFIFO0. */ static const edma_channel_config_t adc_cfifo0_dma_config = { - 0, SPC5_ADC_FIFO0_DMA_PRIO, SPC5_ADC0_FIFO0_DMA_IRQ_PRIO, - NULL, adc_serve_cfifo_error_irq, NULL + 0, SPC5_ADC_FIFO0_DMA_PRIO, SPC5_ADC_FIFO0_DMA_IRQ_PRIO, + NULL, adc_serve_dma_error_irq, &ADCD1 }; /** * @brief DMA configuration for EQADC RFIFO0. */ static const edma_channel_config_t adc_rfifo0_dma_config = { - 1, SPC5_ADC_FIFO0_DMA_PRIO, SPC5_ADC0_FIFO0_DMA_IRQ_PRIO, - adc_serve_rfifo_irq, adc_serve_rfifo_error_irq, NULL + 1, SPC5_ADC_FIFO0_DMA_PRIO, SPC5_ADC_FIFO0_DMA_IRQ_PRIO, + adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD1 }; -#endif /* SPC5_ADC_USE_ADC0_Q3 */ +#endif /* SPC5_ADC_USE_ADC0_Q0 */ + +#if SPC5_ADC_USE_ADC0_Q1 || defined(__DOXYGEN__) +/** + * @brief DMA configuration for EQADC CFIFO1. + */ +static const edma_channel_config_t adc_cfifo1_dma_config = { + 2, SPC5_ADC_FIFO1_DMA_PRIO, SPC5_ADC_FIFO1_DMA_IRQ_PRIO, + NULL, adc_serve_dma_error_irq, &ADCD2 +}; + +/** + * @brief DMA configuration for EQADC RFIFO1. + */ +static const edma_channel_config_t adc_rfifo1_dma_config = { + 3, SPC5_ADC_FIFO1_DMA_PRIO, SPC5_ADC_FIFO1_DMA_IRQ_PRIO, + adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD2 +}; +#endif /* SPC5_ADC_USE_ADC0_Q1 */ + +#if SPC5_ADC_USE_ADC0_Q2 || defined(__DOXYGEN__) +/** + * @brief DMA configuration for EQADC CFIFO2. + */ +static const edma_channel_config_t adc_cfifo2_dma_config = { + 4, SPC5_ADC_FIFO2_DMA_PRIO, SPC5_ADC_FIFO2_DMA_IRQ_PRIO, + NULL, adc_serve_dma_error_irq, &ADCD3 +}; + +/** + * @brief DMA configuration for EQADC RFIFO2. + */ +static const edma_channel_config_t adc_rfifo2_dma_config = { + 5, SPC5_ADC_FIFO2_DMA_PRIO, SPC5_ADC_FIFO2_DMA_IRQ_PRIO, + adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD3 +}; +#endif /* SPC5_ADC_USE_ADC0_Q2 */ #if SPC5_ADC_USE_ADC1_Q3 || defined(__DOXYGEN__) /** * @brief DMA configuration for EQADC CFIFO3. */ static const edma_channel_config_t adc_cfifo3_dma_config = { - 0, SPC5_ADC_FIFO3_DMA_PRIO, SPC5_ADC0_FIFO3_DMA_IRQ_PRIO, - NULL, adc_serve_cfifo_error_irq, NULL + 6, SPC5_ADC_FIFO3_DMA_PRIO, SPC5_ADC_FIFO3_DMA_IRQ_PRIO, + NULL, adc_serve_dma_error_irq, &ADCD4 }; /** * @brief DMA configuration for EQADC RFIFO3. */ static const edma_channel_config_t adc_rfifo3_dma_config = { - 1, SPC5_ADC_FIFO3_DMA_PRIO, SPC5_ADC0_FIFO3_DMA_IRQ_PRIO, - adc_serve_rfifo_irq, adc_serve_rfifo_error_irq, NULL + 7, SPC5_ADC_FIFO3_DMA_PRIO, SPC5_ADC_FIFO3_DMA_IRQ_PRIO, + adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD4 }; #endif /* SPC5_ADC_USE_ADC1_Q3 */ +#if SPC5_ADC_USE_ADC1_Q4 || defined(__DOXYGEN__) +/** + * @brief DMA configuration for EQADC CFIFO4. + */ +static const edma_channel_config_t adc_cfifo4_dma_config = { + 8, SPC5_ADC_FIFO4_DMA_PRIO, SPC5_ADC_FIFO4_DMA_IRQ_PRIO, + NULL, adc_serve_dma_error_irq, &ADCD5 +}; + +/** + * @brief DMA configuration for EQADC RFIFO4. + */ +static const edma_channel_config_t adc_rfifo4_dma_config = { + 9, SPC5_ADC_FIFO4_DMA_PRIO, SPC5_ADC_FIFO4_DMA_IRQ_PRIO, + adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD5 +}; +#endif /* SPC5_ADC_USE_ADC1_Q4 */ + +#if SPC5_ADC_USE_ADC1_Q5 || defined(__DOXYGEN__) +/** + * @brief DMA configuration for EQADC CFIFO5. + */ +static const edma_channel_config_t adc_cfifo5_dma_config = { + 10, SPC5_ADC_FIFO5_DMA_PRIO, SPC5_ADC_FIFO5_DMA_IRQ_PRIO, + NULL, adc_serve_dma_error_irq, &ADCD6 +}; + +/** + * @brief DMA configuration for EQADC RFIFO5. + */ +static const edma_channel_config_t adc_rfifo5_dma_config = { + 11, SPC5_ADC_FIFO5_DMA_PRIO, SPC5_ADC_FIFO5_DMA_IRQ_PRIO, + adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD6 +}; +#endif /* SPC5_ADC_USE_ADC1_Q5 */ + /*===========================================================================*/ /* Driver local functions and macros. */ /*===========================================================================*/ +/** + * @brief Unsigned two's complement. + * + * @param[in] n the value to be complemented + * + * @notapi + */ +#define CPL2(n) ((~(uint32_t)(n)) + 1) + /** * @brief Address of a CFIFO push register. * @@ -334,37 +414,37 @@ static void adc_setup_resistors(uint32_t adc) { * @notapi */ static void adc_serve_rfifo_irq(edma_channel_t channel, void *p) { + ADCDriver *adcp = (ADCDriver *)p; + edma_tcd_t *tcdp = edmaGetTCD(channel); - (void)channel; - (void)p; + if (adcp->grpp != NULL) { + if (tcdp->hword[10] != tcdp->hword[14]) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + else { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } + } } /** - * @brief Shared ISR for RFIFO DMA error events. + * @brief Shared ISR for CFIFO/RFIFO DMA error events. * * @param[in] channel the channel number * @param[in] p parameter for the registered function * * @notapi */ -static void adc_serve_rfifo_error_irq(edma_channel_t channel, void *p) { +static void adc_serve_dma_error_irq(edma_channel_t channel, void *p) { + ADCDriver *adcp = (ADCDriver *)p; (void)channel; - (void)p; -} -/** - * @brief Shared ISR for CFIFO DMA error events. - * - * @param[in] channel the channel number - * @param[in] p parameter for the registered function - * - * @notapi - */ -static void adc_serve_cfifo_error_irq(edma_channel_t channel, void *p) { - - (void)channel; - (void)p; + /* 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); } /*===========================================================================*/ @@ -390,6 +470,22 @@ void adc_lld_init(void) { ADCD1.fifo = ADC_FIFO_0; #endif /* SPC5_ADC_USE_EQADC_Q0 */ +#if SPC5_ADC_USE_ADC0_Q1 + /* Driver initialization.*/ + adcObjectInit(&ADCD2); + ADCD2.cfifo_channel = EDMA_ERROR; + ADCD2.rfifo_channel = EDMA_ERROR; + ADCD2.fifo = ADC_FIFO_1; +#endif /* SPC5_ADC_USE_EQADC_Q1 */ + +#if SPC5_ADC_USE_ADC0_Q2 + /* Driver initialization.*/ + adcObjectInit(&ADCD3); + ADCD3.cfifo_channel = EDMA_ERROR; + ADCD3.rfifo_channel = EDMA_ERROR; + ADCD3.fifo = ADC_FIFO_2; +#endif /* SPC5_ADC_USE_EQADC_Q2 */ + #if SPC5_ADC_USE_ADC1_Q3 /* Driver initialization.*/ adcObjectInit(&ADCD4); @@ -398,6 +494,22 @@ void adc_lld_init(void) { ADCD4.fifo = ADC_FIFO_3; #endif /* SPC5_ADC_USE_ADC1_Q3 */ +#if SPC5_ADC_USE_ADC1_Q4 + /* Driver initialization.*/ + adcObjectInit(&ADCD5); + ADCD5.cfifo_channel = EDMA_ERROR; + ADCD5.rfifo_channel = EDMA_ERROR; + ADCD5.fifo = ADC_FIFO_4; +#endif /* SPC5_ADC_USE_ADC1_Q4 */ + +#if SPC5_ADC_USE_ADC1_Q5 + /* Driver initialization.*/ + adcObjectInit(&ADCD4); + ADCD4.cfifo_channel = EDMA_ERROR; + ADCD4.rfifo_channel = EDMA_ERROR; + ADCD4.fifo = ADC_FIFO_5; +#endif /* SPC5_ADC_USE_ADC1_Q5 */ + /* Temporarily enables CFIFO0 for calibration and initialization.*/ cfifo_enable(ADC_FIFO_0, EQADC_CFCR_SSE | EQADC_CFCR_MODE_SWCS, 0); adc_enable(); @@ -439,13 +551,42 @@ void adc_lld_start(ADCDriver *adcp) { adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo0_dma_config); adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo0_dma_config); } -#endif /* SPC5_ADC_USE_EQADC_Q0 */ +#endif /* SPC5_ADC_USE_ADC0_Q0 */ + +#if SPC5_ADC_USE_ADC0_Q1 + if (&ADCD2 == adcp) { + adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo1_dma_config); + adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo1_dma_config); + } +#endif /* SPC5_ADC_USE_ADC0_Q1 */ + +#if SPC5_ADC_USE_ADC0_Q2 + if (&ADCD3 == adcp) { + adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo2_dma_config); + adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo2_dma_config); + } +#endif /* SPC5_ADC_USE_ADC0_Q2 */ + #if SPC5_ADC_USE_ADC1_Q3 if (&ADCD4 == adcp) { adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo3_dma_config); adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo3_dma_config); } #endif /* SPC5_ADC_USE_ADC1_Q3 */ + +#if SPC5_ADC_USE_ADC1_Q4 + if (&ADCD5 == adcp) { + adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo4_dma_config); + adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo4_dma_config); + } +#endif /* SPC5_ADC_USE_ADC1_Q4 */ + +#if SPC5_ADC_USE_ADC1_Q5 + if (&ADCD6 == adcp) { + adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo5_dma_config); + adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo5_dma_config); + } +#endif /* SPC5_ADC_USE_ADC1_Q5 */ } chDbgAssert((adcp->cfifo_channel != EDMA_ERROR) && @@ -466,7 +607,7 @@ void adc_lld_start(ADCDriver *adcp) { 0, /* iter, temporary. */ 0, /* slast, temporary. */ 0, /* dlast, no dest.adjust. */ - 0); /* mode, temporary. */ + EDMA_TCD_MODE_DREQ); /* mode. */ edmaChannelSetup(adcp->rfifo_channel, /* channel. */ RFIFO_POP_ADDR(adcp->fifo), /* source. */ NULL, /* destination, temporary. */ @@ -517,8 +658,38 @@ void adc_lld_stop(ADCDriver *adcp) { * @notapi */ void adc_lld_start_conversion(ADCDriver *adcp) { + edma_tcd_t *ctcdp = edmaGetTCD(adcp->cfifo_channel); + edma_tcd_t *rtcdp = edmaGetTCD(adcp->rfifo_channel); /* TODO: ISEL0, ISEL3 setup for HW triggers.*/ + + /* Updating the variable TCD fields for CFIFO.*/ + edmaTCDSetSourceAddress(ctcdp, adcp->grpp->commands); + edmaTCDSetOuterLoopCount(ctcdp, (uint32_t)adcp->grpp->num_channels * + (uint32_t)adcp->depth); + edmaTCDSetSourceAdjustment(ctcdp, + CPL2((uint32_t)adcp->grpp->num_channels * + (uint32_t)adcp->depth * + sizeof(adccommand_t))); + + /* Updating the variable TCD fields for RFIFO.*/ + edmaTCDSetDestinationAddress(rtcdp, adcp->samples); + edmaTCDSetOuterLoopCount(rtcdp, (uint32_t)adcp->grpp->num_channels * + (uint32_t)adcp->depth); + edmaTCDSetDestinationAdjustment(ctcdp, + CPL2((uint32_t)adcp->grpp->num_channels * + (uint32_t)adcp->depth * + sizeof(adcsample_t))); + edmaTCDSetMode(rtcdp, EDMA_TCD_MODE_DREQ | EDMA_TCD_MODE_INT_END | + (adcp->depth > 1) ? EDMA_TCD_MODE_INT_HALF: 0); + + /* Starting DMA channels.*/ + edmaChannelStart(adcp->rfifo_channel); + edmaChannelStart(adcp->cfifo_channel); + + /* Enabling CFIFO, conversion starts.*/ + cfifo_enable(adcp->fifo, adcp->grpp->cfcr, + EQADC_IDCR_CFFE | EQADC_IDCR_RFDE); } /** @@ -530,7 +701,12 @@ void adc_lld_start_conversion(ADCDriver *adcp) { */ void adc_lld_stop_conversion(ADCDriver *adcp) { - (void)adcp; + /* Stopping DMA channels.*/ + edmaChannelStop(adcp->cfifo_channel); + edmaChannelStop(adcp->rfifo_channel); + + /* Disabling CFIFO.*/ + cfifo_disable(adcp->fifo); } #endif /* HAL_USE_ADC */ diff --git a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h index 5ca2008c6..ef19f7e86 100644 --- a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h +++ b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h @@ -61,6 +61,22 @@ #define ADC_REG_PUDCR7 0x77UL /** @} */ +/** + * @name EQADC IDCR registers definitions + * @{ + */ +#define EQADC_IDCR_NCIE (1U << 15) +#define EQADC_IDCR_TORIE (1U << 14) +#define EQADC_IDCR_PIE (1U << 13) +#define EQADC_IDCR_EOQIE (1U << 12) +#define EQADC_IDCR_CFUIE (1U << 11) +#define EQADC_IDCR_CFFE (1U << 9) +#define EQADC_IDCR_CFFS (1U << 8) +#define EQADC_IDCR_RFOIE (1U << 3) +#define EQADC_IDCR_RFDE (1U << 1) +#define EQADC_IDCR_RFDS (1U << 0) +/** @} */ + /** * @name EQADC CFCR registers definitions * @{ @@ -300,42 +316,42 @@ * @brief EQADC CFIFO0 and RFIFO0 DMA IRQ priority. */ #if !defined(SPC5_ADC0_FIFO0_DMA_IRQ_PRIO) || defined(__DOXYGEN__) -#define SPC5_ADC0_FIFO0_DMA_IRQ_PRIO 12 +#define SPC5_ADC_FIFO0_DMA_IRQ_PRIO 12 #endif /** * @brief EQADC CFIFO1 and RFIFO1 DMA IRQ priority. */ #if !defined(SPC5_ADC0_FIFO1_DMA_IRQ_PRIO) || defined(__DOXYGEN__) -#define SPC5_ADC0_FIFO1_DMA_IRQ_PRIO 12 +#define SPC5_ADC_FIFO1_DMA_IRQ_PRIO 12 #endif /** * @brief EQADC CFIFO2 and RFIFO2 DMA IRQ priority. */ #if !defined(SPC5_ADC0_FIFO2_DMA_IRQ_PRIO) || defined(__DOXYGEN__) -#define SPC5_ADC0_FIFO2_DMA_IRQ_PRIO 12 +#define SPC5_ADC_FIFO2_DMA_IRQ_PRIO 12 #endif /** * @brief EQADC CFIFO3 and RFIFO3 DMA IRQ priority. */ #if !defined(SPC5_ADC0_FIFO3_DMA_IRQ_PRIO) || defined(__DOXYGEN__) -#define SPC5_ADC0_FIFO3_DMA_IRQ_PRIO 12 +#define SPC5_ADC_FIFO3_DMA_IRQ_PRIO 12 #endif /** * @brief EQADC CFIFO4 and RFIFO4 DMA IRQ priority. */ #if !defined(SPC5_ADC0_FIFO4_DMA_IRQ_PRIO) || defined(__DOXYGEN__) -#define SPC5_ADC0_FIFO4_DMA_IRQ_PRIO 12 +#define SPC5_ADC_FIFO4_DMA_IRQ_PRIO 12 #endif /** * @brief EQADC CFIFO5 and RFIFO5 DMA IRQ priority. */ #if !defined(SPC5_ADC0_FIFO5_DMA_IRQ_PRIO) || defined(__DOXYGEN__) -#define SPC5_ADC0_FIFO5_DMA_IRQ_PRIO 12 +#define SPC5_ADC_FIFO5_DMA_IRQ_PRIO 12 #endif /** @@ -409,8 +425,7 @@ typedef uint16_t adc_channels_num_t; * upon. */ typedef enum { - ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */ - ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */ + ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */ } adcerror_t; /** @@ -471,6 +486,10 @@ typedef struct { * @p adcStartConversion(). */ uint32_t num_iterations; + /** + * @brief Initialization value for CFCR register. + */ + uint16_t cfcr; /** * @brief Pointer to an array of low level EQADC commands to be pushed * into the CFIFO during a conversion.