From f180c606d8485911240ba5441cbd1ca5a9a5d56a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 3 May 2015 12:49:42 +0000 Subject: DAC dual mode, to be tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7946 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/DACv1/dac_lld.c | 100 +++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 29 deletions(-) (limited to 'os/hal/ports/STM32') diff --git a/os/hal/ports/STM32/LLD/DACv1/dac_lld.c b/os/hal/ports/STM32/LLD/DACv1/dac_lld.c index 8fc51ae88..f3191e47b 100644 --- a/os/hal/ports/STM32/LLD/DACv1/dac_lld.c +++ b/os/hal/ports/STM32/LLD/DACv1/dac_lld.c @@ -253,9 +253,16 @@ void dac_lld_start(DACDriver *dacp) { dacp->params->dac->CR |= DAC_CR_EN1 << dacp->params->regshift; dac_lld_put_channel(dacp, 0U, dacp->config->init); #else - dacp->params->dac->CR = DAC_CR_EN2 | DAC_CR_EN1; + if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) || + (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) || + (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) { + dacp->params->dac->CR = DAC_CR_EN2 | DAC_CR_EN1; + dac_lld_put_channel(dacp, 1U, dacp->config->init); + } + else { + dacp->params->dac->CR = DAC_CR_EN1; + } dac_lld_put_channel(dacp, 0U, dacp->config->init); - dac_lld_put_channel(dacp, 1U, dacp->config->init); #endif } } @@ -308,6 +315,7 @@ void dac_lld_put_channel(DACDriver *dacp, switch (dacp->config->datamode) { case DAC_DHRM_12BIT_RIGHT: + case DAC_DHRM_12BIT_RIGHT_DUAL: if (channel == 0U) { dacp->params->dac->DHR12R1 = (uint32_t)sample; } @@ -316,6 +324,7 @@ void dac_lld_put_channel(DACDriver *dacp, } break; case DAC_DHRM_12BIT_LEFT: + case DAC_DHRM_12BIT_LEFT_DUAL: if (channel == 0U) { dacp->params->dac->DHR12L1 = (uint32_t)sample; } @@ -324,6 +333,7 @@ void dac_lld_put_channel(DACDriver *dacp, } break; case DAC_DHRM_8BIT_RIGHT: + case DAC_DHRM_8BIT_RIGHT_DUAL: if (channel == 0U) { dacp->params->dac->DHR8R1 = (uint32_t)sample; } @@ -340,13 +350,24 @@ void dac_lld_put_channel(DACDriver *dacp, /** * @brief Starts a DAC conversion. * @details Starts an asynchronous conversion operation. + * @note In @p DAC_DHRM_8BIT_RIGHT mode the parameters passed to the + * callback are wrong because two samples are packed in a single + * dacsample_t element. This will not be corrected, do not rely + * on those parameters. + * @note In @p DAC_DHRM_8BIT_RIGHT_DUAL mode two samples are treated + * as a single 16 bits sample and packed into a single dacsample_t + * element. The num_channels must be set to one in the group + * conversion configuration structure. * * @param[in] dacp pointer to the @p DACDriver object * * @notapi */ void dac_lld_start_conversion(DACDriver *dacp) { - uint32_t cr, dmamode; + uint32_t n, cr, dmamode; + + /* Number of DMA operations per buffer.*/ + n = dacp->depth * dacp->grpp->num_channels; /* Allocating the DMA channel.*/ bool b = dmaStreamAllocate(dacp->params->dma, dacp->params->dmairqprio, @@ -354,53 +375,67 @@ void dac_lld_start_conversion(DACDriver *dacp) { (void *)dacp); osalDbgAssert(!b, "stream already allocated"); -#if STM32_DAC_DUAL_MODE == FALSE + /* DMA settings depend on the chosed DAC mode.*/ switch (dacp->config->datamode) { /* Sets the DAC data register */ case DAC_DHRM_12BIT_RIGHT: + osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels"); + dmaStreamSetPeripheral(dacp->params->dma, &dacp->params->dac->DHR12R1 + dacp->params->dataoffset); dmamode = dacp->params->dmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; break; case DAC_DHRM_12BIT_LEFT: + osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels"); + dmaStreamSetPeripheral(dacp->params->dma, &dacp->params->dac->DHR12L1 + dacp->params->dataoffset); dmamode = dacp->params->dmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; break; case DAC_DHRM_8BIT_RIGHT: + osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels"); + dmaStreamSetPeripheral(dacp->params->dma, &dacp->params->dac->DHR8R1 + dacp->params->dataoffset); dmamode = dacp->params->dmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + + /* In this mode the size of the buffer is halved because two samples + packed in a single dacsample_t element.*/ + n = (n + 1) / 2; + break; +#if STM32_DAC_DUAL_MODE == TRUE + case DAC_DHRM_12BIT_RIGHT_DUAL: + osalDbgAssert(dacp->grpp->num_channels == 2, "invalid number of channels"); + + dmaStreamSetPeripheral(dacp->params->dma, &dacp->params->dac->DHR12RD); + dmamode = dacp->params->dmamode | + STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD; + break; + case DAC_DHRM_12BIT_LEFT_DUAL: + osalDbgAssert(dacp->grpp->num_channels == 2, "invalid number of channels"); + + dmaStreamSetPeripheral(dacp->params->dma, &dacp->params->dac->DHR12LD); + dmamode = dacp->params->dmamode | + STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD; break; + case DAC_DHRM_8BIT_RIGHT_DUAL: + osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels"); + + dmaStreamSetPeripheral(dacp->params->dma, &dacp->params->dac->DHR8RD); + dmamode = dacp->params->dmamode | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + break; +#endif default: chDbgAssert(false, "unexpected DAC mode"); break; } -#else -#if defined(STM32_HAS_DAC_CHN2) && STM32_HAS_DAC_CHN2 - case DAC_DHRM_12BIT_RIGHT_DUAL: - dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12RD); - dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | - STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; - break; - case DAC_DHRM_12BIT_LEFT_DUAL: - dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12LD); - dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | - STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; - break; - case DAC_DHRM_8BIT_RIGHT_DUAL: - dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8RD); - dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | - STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; - break; -#endif -#endif dmaStreamSetMemory0(dacp->params->dma, dacp->samples); - dmaStreamSetTransactionSize(dacp->params->dma, dacp->depth); + dmaStreamSetTransactionSize(dacp->params->dma, n); dmaStreamSetMode(dacp->params->dma, dmamode | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE | STM32_DMA_CR_TCIE); @@ -412,11 +447,13 @@ void dac_lld_start_conversion(DACDriver *dacp) { dacp->params->dac->CR &= dacp->params->regmask; dacp->params->dac->CR |= cr << dacp->params->regshift; #else - /* TODO: Dual.*/ + dacp->params->dac->CR = 0; + cr = DAC_CR_DMAEN1 | (dacp->grpp->trigger << 3) | DAC_CR_TEN1 | DAC_CR_EN1 + | (dacp->grpp->trigger << 19) | DAC_CR_TEN2 | DAC_CR_EN2; + dacp->params->dac->CR = cr; #endif } - /** * @brief Stops an ongoing conversion. * @details This function stops the currently ongoing conversion and returns @@ -436,10 +473,15 @@ void dac_lld_stop_conversion(DACDriver *dacp) { #if STM32_DAC_DUAL_MODE == FALSE dacp->params->dac->CR &= dacp->params->regmask; dacp->params->dac->CR |= DAC_CR_EN1 << dacp->params->regshift; - *(&dacp->params->dac->DHR12R1 + dacp->params->dataoffset) = 0U; #else - dacp->params->dac->CR = DAC_CR_EN2 | DAC_CR_EN1; - dacp->params->dac->DAC_DHR12RD = 0U; + if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) || + (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) || + (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) { + dacp->params->dac->CR = DAC_CR_EN2 | DAC_CR_EN1; + } + else { + dacp->params->dac->CR = DAC_CR_EN1; + } #endif } -- cgit v1.2.3