From b8861047963cae44890f8928d4fe1a2bcad864b1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 5 Mar 2013 15:37:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5364 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c | 42 +++++++++++++++++++ os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h | 62 +++++++++++++++++++++++++++++ os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c | 58 +++++++++++++++++++++++---- os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h | 4 ++ 4 files changed, 159 insertions(+), 7 deletions(-) (limited to 'os') diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c index cbb7e7ef8..0998289c2 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c @@ -748,4 +748,46 @@ void edmaChannelRelease(edma_channel_t channel) { channels[channel] = NULL; } +/** + * @brief EDMA channel setup. + * + * @param[in] channel eDMA channel number + * @param[in] src source address + * @param[in] dst destination address + * @param[in] soff source address offset + * @param[in] doff destination address offset + * @param[in] ssize source transfer size + * @param[in] dsize destination transfer size + * @param[in] nbytes minor loop count + * @param[in] iter major loop count + * @param[in] dlast_sga Last Destination Address Adjustment or + * Scatter Gather Address + * @param[in] slast last source address adjustment + * @param[in] mode LSW of TCD register 7 + */ +void edmaChannelSetupx(edma_channel_t channel, + void *src, + void *dst, + uint32_t soff, + uint32_t doff, + uint32_t ssize, + uint32_t dsize, + uint32_t nbytes, + uint32_t iter, + uint32_t slast, + uint32_t dlast, + uint32_t mode) { + + edma_tcd_t *tcdp = edmaGetTCD(channel); + + tcdp->word[0] = (uint32_t)src; + tcdp->word[1] = (ssize << 24) | (dsize << 16) | soff; + tcdp->word[2] = nbytes; + tcdp->word[3] = slast; + tcdp->word[0] = (uint32_t)dst; + tcdp->word[5] = (iter << 16) | doff; + tcdp->word[6] = dlast; + tcdp->word[7] = (iter << 16) | mode; +} + /** @} */ diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h index 1ea965551..ad7f5ed5e 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h @@ -107,6 +107,36 @@ typedef struct { /* Driver macros. */ /*===========================================================================*/ +/** + * @brief Returns the TCD address associated to a channel. + * + * @param[in] channel the channel number + * @return A pointer to an @p edma_tcd_t structure. + * + * @api + */ +#define edmaGetTCD(channel) ((edma_tcd_t *)&EDMA.TCD[channel]) + +/** + * @brief Sets the source address into a TCD. + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * + * @api + */ +#define edmaChannelSetSourceAddress(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 + * + * @api + */ +#define edmaChannelSetDestinationAddress(tcdp, dst) \ + ((tcdp)->word[4] = (uint32_t)(dst)) + /** * @brief Starts or restarts an EDMA channel. * @@ -125,6 +155,38 @@ typedef struct { */ #define edmaChannelStop(channel) (EDMA.CERQR.R = (channel)) +/** + * @brief EDMA channel setup. + * + * @param[in] channel eDMA channel number + * @param[in] src source address + * @param[in] dst destination address + * @param[in] soff source address offset + * @param[in] doff destination address offset + * @param[in] ssize source transfer size + * @param[in] dsize destination transfer size + * @param[in] nbytes minor loop count + * @param[in] iter major loop count + * @param[in] dlast last destination address adjustment + * @param[in] slast last source address adjustment + * @param[in] mode LSW of TCD register 7 + * + * @api + */ +#define edmaChannelSetup(channel, src, dst, soff, doff, ssize, dsize, \ + 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); \ +} + /*===========================================================================*/ /* 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 a9e8a5e26..b198c1799 100644 --- a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c +++ b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.c @@ -132,6 +132,24 @@ static const edma_channel_config_t adc_rfifo3_dma_config = { /* Driver local functions and macros. */ /*===========================================================================*/ +/** + * @brief Address of a CFIFO push register. + * + * @param[in] fifo the FIFO identifier + * + * @notapi + */ +#define CFIFO_PUSH_ADDR(fifo) ((uint32_t *)(&EQADC.CFPR[fifo].R)) + +/** + * @brief Address of a RFIFO pop register. + * + * @param[in] fifo the FIFO identifier + * + * @notapi + */ +#define RFIFO_POP_ADDR(fifo) (((uint16_t *)&EQADC.RFPR[fifo].R) + 1) + /** * @brief Enables a CFIFO. * @@ -147,7 +165,6 @@ static void cfifo_enable(adcfifo_t fifo, uint16_t cfcr, uint16_t idcr) { EQADC.IDCR[fifo].R = idcr; } - /** * @brief Disables a CFIFO and the associated resources. * @@ -370,13 +387,15 @@ void adc_lld_init(void) { adcObjectInit(&ADCD1); ADCD1.cfifo_channel = EDMA_ERROR; ADCD1.rfifo_channel = EDMA_ERROR; + ADCD1.fifo = ADC_FIFO_0; #endif /* SPC5_ADC_USE_EQADC_Q0 */ #if SPC5_ADC_USE_ADC1_Q3 /* Driver initialization.*/ - adcObjectInit(&ADCD1); - ADCD1.cfifo_channel = EDMA_ERROR; - ADCD1.rfifo_channel = EDMA_ERROR; + adcObjectInit(&ADCD4); + ADCD4.cfifo_channel = EDMA_ERROR; + ADCD4.rfifo_channel = EDMA_ERROR; + ADCD4.fifo = ADC_FIFO_3; #endif /* SPC5_ADC_USE_ADC1_Q3 */ /* Temporarily enables CFIFO0 for calibration and initialization.*/ @@ -433,8 +452,33 @@ void adc_lld_start(ADCDriver *adcp) { (adcp->rfifo_channel != EDMA_ERROR), "adc_lld_start(), #1", "channel cannot be allocated"); - /* Configures the peripheral.*/ - + /* Setting up TCD parameters that will not change during operations, + other parameters are set to a temporary value and will be changed + when starting a conversion.*/ + edmaChannelSetup(adcp->cfifo_channel, /* channel. */ + NULL, /* source, temporary. */ + CFIFO_PUSH_ADDR(adcp->fifo), /* destination. */ + 4, /* soff, advance by 4. */ + 0, /* doff, do not advance. */ + 2, /* ssize, 32 bits transfers.*/ + 2, /* dsize, 32 bits transfers.*/ + 4, /* nbytes, always four. */ + 0, /* iter, temporary. */ + 0, /* slast, temporary. */ + 0, /* dlast, no dest.adjust. */ + 0); /* mode, temporary. */ + edmaChannelSetup(adcp->rfifo_channel, /* channel. */ + RFIFO_POP_ADDR(adcp->fifo), /* source. */ + NULL, /* destination, temporary. */ + 0, /* soff, do not advance. */ + 2, /* doff, advance by two. */ + 1, /* ssize, 16 bits transfers.*/ + 1, /* dsize, 16 bits transfers.*/ + 2, /* nbytes, always two. */ + 0, /* iter, temporary. */ + 0, /* slast, no source adjust. */ + 0, /* dlast, temporary. */ + 0); /* mode, temporary. */ } /** @@ -474,7 +518,7 @@ void adc_lld_stop(ADCDriver *adcp) { */ void adc_lld_start_conversion(ADCDriver *adcp) { - (void)adcp; + /* TODO: ISEL0, ISEL3 setup for HW triggers.*/ } /** diff --git a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h index 395f7f871..5ca2008c6 100644 --- a/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h +++ b/os/hal/platforms/SPC5xx/EQADC_v1/adc_lld.h @@ -530,6 +530,10 @@ struct ADCDriver { ADC_DRIVER_EXT_FIELDS #endif /* End of the mandatory fields.*/ + /** + * @brief CFIFO/RFIFO used by this instance. + */ + adcfifo_t fifo; /** * @brief EDMA channel used for the CFIFO. */ -- cgit v1.2.3