aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-05-03 12:49:42 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-05-03 12:49:42 +0000
commitf180c606d8485911240ba5441cbd1ca5a9a5d56a (patch)
tree0a9da5edd5124a56ae2cb17b75bd84d321a1bec3 /os/hal/ports
parentd3a7d7370c267d094edd047fc223ef575f257bae (diff)
downloadChibiOS-f180c606d8485911240ba5441cbd1ca5a9a5d56a.tar.gz
ChibiOS-f180c606d8485911240ba5441cbd1ca5a9a5d56a.tar.bz2
ChibiOS-f180c606d8485911240ba5441cbd1ca5a9a5d56a.zip
DAC dual mode, to be tested.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7946 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/ports')
-rw-r--r--os/hal/ports/STM32/LLD/DACv1/dac_lld.c100
1 files changed, 71 insertions, 29 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
}