aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/PPC-SPC563M-GCC/mcuconf.h8
-rw-r--r--os/hal/platforms/SPC563Mxx/spc563m_registry.h2
-rw-r--r--os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h148
-rw-r--r--os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c240
-rw-r--r--os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h35
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,23 +136,115 @@ 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.
*
* @param[in] channel the channel number
@@ -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,42 +96,123 @@ 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_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
};
-#endif /* SPC5_ADC_USE_ADC0_Q3 */
+
+/**
+ * @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.
*
* @param[in] fifo the FIFO identifier
@@ -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
@@ -62,6 +62,22 @@
/** @} */
/**
+ * @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;
/**
@@ -472,6 +487,10 @@ typedef struct {
*/
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.
*/