DAC dual mode, to be tested.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7946 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2015-05-03 12:49:42 +00:00
parent d3a7d7370c
commit f180c606d8
4 changed files with 81 additions and 36 deletions

View File

@ -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
}

View File

@ -33,7 +33,7 @@
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;cr2-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-null-port_wait_for_interrupt-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-adcp-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/>
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList&gt;&lt;content id=&quot;CR2-adc-adcp-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;CR2-adc-null-port_wait_for_interrupt-(format)&quot; val=&quot;4&quot;/&gt;&lt;content id=&quot;cr2-adc_lld_start_conversion-(format)&quot; val=&quot;4&quot;/&gt;&lt;/contentList&gt;"/>
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>

View File

@ -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);
/*

View File

@ -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