From f180c606d8485911240ba5441cbd1ca5a9a5d56a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 3 May 2015 12:49:42 +0000 Subject: [PATCH] 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 +++++++++++++----- ...x-DAC_DUAL (OpenOCD, Flash and Run).launch | 2 +- testhal/STM32/STM32F4xx/DAC_DUAL/main.c | 11 +- testhal/STM32/STM32F4xx/DAC_DUAL/mcuconf.h | 4 +- 4 files changed, 81 insertions(+), 36 deletions(-) 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 } diff --git a/testhal/STM32/STM32F4xx/DAC_DUAL/debug/STM32F4xx-DAC_DUAL (OpenOCD, Flash and Run).launch b/testhal/STM32/STM32F4xx/DAC_DUAL/debug/STM32F4xx-DAC_DUAL (OpenOCD, Flash and Run).launch index a6cdd3e04..cf2bb94e6 100644 --- a/testhal/STM32/STM32F4xx/DAC_DUAL/debug/STM32F4xx-DAC_DUAL (OpenOCD, Flash and Run).launch +++ b/testhal/STM32/STM32F4xx/DAC_DUAL/debug/STM32F4xx-DAC_DUAL (OpenOCD, Flash and Run).launch @@ -33,7 +33,7 @@ - + diff --git a/testhal/STM32/STM32F4xx/DAC_DUAL/main.c b/testhal/STM32/STM32F4xx/DAC_DUAL/main.c index e57d8a3f2..b6d46b284 100644 --- a/testhal/STM32/STM32F4xx/DAC_DUAL/main.c +++ b/testhal/STM32/STM32F4xx/DAC_DUAL/main.c @@ -89,11 +89,11 @@ static void error_cb1(DACDriver *dacp, dacerror_t err) { static const DACConfig dac1cfg1 = { init: 2047U, - datamode: DAC_DHRM_12BIT_RIGHT + datamode: DAC_DHRM_12BIT_RIGHT_DUAL }; static const DACConversionGroup dacgrpcfg1 = { - num_channels: 1U, + num_channels: 2U, end_cb: end_cb1, error_cb: error_cb1, trigger: DAC_TRG(0) @@ -125,10 +125,11 @@ int main(void) { chSysInit(); /* - * Starting DAC1 driver, setting up the output pin as analog as suggested + * Starting DAC1 driver, setting up the output pins as analog as suggested * by the Reference Manual. */ palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); + palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); dacStart(&DACD1, &dac1cfg1); /* @@ -138,8 +139,10 @@ int main(void) { /* * Starting a continuous conversion. + * Note, the buffer size is divided by two because two elements are fetched + * for each transfer. */ - dacStartConversion(&DACD1, &dacgrpcfg1, dac_buffer, DAC_BUFFER_SIZE); + dacStartConversion(&DACD1, &dacgrpcfg1, dac_buffer, DAC_BUFFER_SIZE / 2U); gptStartContinuous(&GPTD6, 2U); /* diff --git a/testhal/STM32/STM32F4xx/DAC_DUAL/mcuconf.h b/testhal/STM32/STM32F4xx/DAC_DUAL/mcuconf.h index a6bc10980..d16ac4194 100644 --- a/testhal/STM32/STM32F4xx/DAC_DUAL/mcuconf.h +++ b/testhal/STM32/STM32F4xx/DAC_DUAL/mcuconf.h @@ -93,9 +93,9 @@ /* * DAC driver system settings. */ -#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_DUAL_MODE TRUE #define STM32_DAC_USE_DAC1_CH1 TRUE -#define STM32_DAC_USE_DAC1_CH2 TRUE +#define STM32_DAC_USE_DAC1_CH2 FALSE #define STM32_DAC1_CH1_IRQ_PRIORITY 10 #define STM32_DAC1_CH2_IRQ_PRIORITY 10 #define STM32_DAC1_CH1_DMA_PRIORITY 2