Improved DAC driver, updated STM32 DACv1.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16315 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
f77d00b0c9
commit
665b0d48b4
|
@ -40,11 +40,14 @@
|
|||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
* @brief Support for thread synchronization API.
|
||||
*/
|
||||
#if !defined(DAC_USE_SYNCHRONIZATION) || defined(__DOXYGEN__)
|
||||
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define DAC_USE_WAIT TRUE
|
||||
#define DAC_USE_SYNCHRONIZATION FALSE
|
||||
#else
|
||||
#define DAC_USE_SYNCHRONIZATION DAC_USE_WAIT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -163,12 +166,12 @@ struct hal_dac_driver {
|
|||
* @brief Current configuration data.
|
||||
*/
|
||||
const DACConfig *config;
|
||||
#if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
#if (DAC_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
thread_reference_t thread;
|
||||
#endif /* DAC_USE_WAIT */
|
||||
#endif /* DAC_USE_SYNCHRONIZATION */
|
||||
#if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the bus.
|
||||
|
@ -205,7 +208,7 @@ struct hal_dac_driver {
|
|||
*/
|
||||
#define dacIsBufferComplete(dacp) ((bool)((dacp)->state == DAC_COMPLETE))
|
||||
|
||||
#if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
#if (DAC_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waits for operation completion.
|
||||
* @details This function waits for the driver to complete the current
|
||||
|
@ -264,13 +267,13 @@ struct hal_dac_driver {
|
|||
osalSysUnlockFromISR(); \
|
||||
}
|
||||
|
||||
#else /* !DAC_USE_WAIT */
|
||||
#else /* !DAC_USE_SYNCHRONIZATION */
|
||||
#define _dac_wait_s(dacp)
|
||||
#define _dac_reset_i(dacp)
|
||||
#define _dac_reset_s(dacp)
|
||||
#define _dac_wakeup_isr(dacp)
|
||||
#define _dac_timeout_isr(dacp)
|
||||
#endif /* !DAC_USE_WAIT */
|
||||
#endif /* !DAC_USE_SYNCHRONIZATION */
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, half buffer event.
|
||||
|
@ -310,13 +313,14 @@ struct hal_dac_driver {
|
|||
if ((dacp)->state == DAC_COMPLETE) \
|
||||
(dacp)->state = DAC_ACTIVE; \
|
||||
} \
|
||||
_dac_wakeup_isr(dacp); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, error event.
|
||||
* @details This code handles the portable part of the ISR code:
|
||||
* - Callback invocation.
|
||||
* - Waiting thread timeout signaling, if any.
|
||||
* - Waiting thread timeout signalling, if any.
|
||||
* - Driver state transitions.
|
||||
* .
|
||||
* @note This macro is meant to be used in the low level drivers
|
||||
|
@ -360,10 +364,12 @@ extern "C" {
|
|||
dacsample_t *samples, size_t depth);
|
||||
void dacStopConversion(DACDriver *dacp);
|
||||
void dacStopConversionI(DACDriver *dacp);
|
||||
#if DAC_USE_WAIT
|
||||
#if DAC_USE_SYNCHRONIZATION
|
||||
msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp,
|
||||
dacsample_t *samples, size_t depth);
|
||||
#endif
|
||||
msg_t dacSynchronizeS(DACDriver *dacp, sysinterval_t timeout);
|
||||
msg_t dacSynchronize(DACDriver *dacp, sysinterval_t timeout);
|
||||
#endif /* DAC_USE_SYNCHRONIZATION */
|
||||
#if DAC_USE_MUTUAL_EXCLUSION
|
||||
void dacAcquireBus(DACDriver *dacp);
|
||||
void dacReleaseBus(DACDriver *dacp);
|
||||
|
|
|
@ -68,6 +68,9 @@
|
|||
STM32_DAC4_CH2_DMA_CHN)
|
||||
|
||||
#define CHANNEL_DATA_OFFSET 3U
|
||||
#define CHANNEL_REGISTER_SHIFT 16U
|
||||
#define CHANNEL_REGISTER_MASK1 0xFFFF0000U
|
||||
#define CHANNEL_REGISTER_MASK2 0x0000FFFFU
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
|
@ -122,7 +125,7 @@ static const dacparams_t dac1_ch1_params = {
|
|||
.dac = DAC1,
|
||||
.dataoffset = 0U,
|
||||
.regshift = 0U,
|
||||
.regmask = 0xFFFF0000U,
|
||||
.regmask = CHANNEL_REGISTER_MASK1,
|
||||
.dmastream = STM32_DAC_DAC1_CH1_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC1_CH1,
|
||||
|
@ -140,8 +143,8 @@ static const dacparams_t dac1_ch1_params = {
|
|||
static const dacparams_t dac1_ch2_params = {
|
||||
.dac = DAC1,
|
||||
.dataoffset = CHANNEL_DATA_OFFSET,
|
||||
.regshift = 16U,
|
||||
.regmask = 0x0000FFFFU,
|
||||
.regshift = CHANNEL_REGISTER_SHIFT,
|
||||
.regmask = CHANNEL_REGISTER_MASK2,
|
||||
.dmastream = STM32_DAC_DAC1_CH2_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC1_CH2,
|
||||
|
@ -160,7 +163,7 @@ static const dacparams_t dac2_ch1_params = {
|
|||
.dac = DAC2,
|
||||
.dataoffset = 0U,
|
||||
.regshift = 0U,
|
||||
.regmask = 0xFFFF0000U,
|
||||
.regmask = CHANNEL_REGISTER_MASK1,
|
||||
.dmastream = STM32_DAC_DAC2_CH1_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC2_CH1,
|
||||
|
@ -178,8 +181,8 @@ static const dacparams_t dac2_ch1_params = {
|
|||
static const dacparams_t dac2_ch2_params = {
|
||||
.dac = DAC2,
|
||||
.dataoffset = CHANNEL_DATA_OFFSET,
|
||||
.regshift = 16U,
|
||||
.regmask = 0x0000FFFFU,
|
||||
.regshift = CHANNEL_REGISTER_SHIFT,
|
||||
.regmask = CHANNEL_REGISTER_MASK2,
|
||||
.dmastream = STM32_DAC_DAC2_CH2_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC2_CH2,
|
||||
|
@ -198,7 +201,7 @@ static const dacparams_t dac3_ch1_params = {
|
|||
.dac = DAC3,
|
||||
.dataoffset = 0U,
|
||||
.regshift = 0U,
|
||||
.regmask = 0xFFFF0000U,
|
||||
.regmask = CHANNEL_REGISTER_MASK1,
|
||||
.dmastream = STM32_DAC_DAC3_CH1_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC3_CH1,
|
||||
|
@ -216,8 +219,8 @@ static const dacparams_t dac3_ch1_params = {
|
|||
static const dacparams_t dac3_ch2_params = {
|
||||
.dac = DAC3,
|
||||
.dataoffset = CHANNEL_DATA_OFFSET,
|
||||
.regshift = 16U,
|
||||
.regmask = 0x0000FFFFU,
|
||||
.regshift = CHANNEL_REGISTER_SHIFT,
|
||||
.regmask = CHANNEL_REGISTER_MASK2,
|
||||
.dmastream = STM32_DAC_DAC3_CH2_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC3_CH2,
|
||||
|
@ -236,7 +239,7 @@ static const dacparams_t dac4_ch1_params = {
|
|||
.dac = DAC4,
|
||||
.dataoffset = 0U,
|
||||
.regshift = 0U,
|
||||
.regmask = 0xFFFF0000U,
|
||||
.regmask = CHANNEL_REGISTER_MASK1,
|
||||
.dmastream = STM32_DAC_DAC4_CH1_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC4_CH1,
|
||||
|
@ -254,8 +257,8 @@ static const dacparams_t dac4_ch1_params = {
|
|||
static const dacparams_t dac4_ch2_params = {
|
||||
.dac = DAC4,
|
||||
.dataoffset = CHANNEL_DATA_OFFSET,
|
||||
.regshift = 16U,
|
||||
.regmask = 0x0000FFFFU,
|
||||
.regshift = CHANNEL_REGISTER_SHIFT,
|
||||
.regmask = CHANNEL_REGISTER_MASK2,
|
||||
.dmastream = STM32_DAC_DAC4_CH2_DMA_STREAM,
|
||||
#if STM32_DMA_SUPPORTS_DMAMUX
|
||||
.peripheral = STM32_DMAMUX1_DAC4_CH2,
|
||||
|
@ -429,30 +432,41 @@ void dac_lld_start(DACDriver *dacp) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Enabling DAC in SW triggering mode initially, initializing data to
|
||||
zero.*/
|
||||
#if STM32_DAC_DUAL_MODE == FALSE
|
||||
/* Enabling DAC in SW triggering mode initially, initializing data to
|
||||
configuration default.*/
|
||||
{
|
||||
uint32_t cr;
|
||||
uint32_t reg;
|
||||
|
||||
cr = dacp->params->dac->CR;
|
||||
cr &= dacp->params->regmask;
|
||||
cr |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
|
||||
dacp->params->dac->CR = cr;
|
||||
dac_lld_put_channel(dacp, channel, dacp->config->init);
|
||||
/* Operating in SINGLE mode with one channel to set. Set registers for
|
||||
specified channel from configuration. Lower half word of
|
||||
configuration specifies configuration for any channel.*/
|
||||
reg = dacp->params->dac->MCR & dacp->params->regmask;
|
||||
dacp->params->dac->MCR = reg |
|
||||
((dacp->config->mcr & ~dacp->params->regmask) << dacp->params->regshift);
|
||||
|
||||
/* Enable and initialise the channel.*/
|
||||
reg = dacp->params->dac->CR;
|
||||
reg &= dacp->params->regmask;
|
||||
reg |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
|
||||
dacp->params->dac->CR = reg;
|
||||
dac_lld_put_channel(dacp, channel, (dacsample_t)dacp->config->init);
|
||||
}
|
||||
#else
|
||||
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 | (dacp->config->cr << 16) | DAC_CR_EN1 | dacp->config->cr;
|
||||
dac_lld_put_channel(dacp, 1U, dacp->config->init);
|
||||
}
|
||||
else {
|
||||
dacp->params->dac->CR = DAC_CR_EN1 | dacp->config->cr;
|
||||
}
|
||||
dac_lld_put_channel(dacp, channel, dacp->config->init);
|
||||
#endif
|
||||
#else /* STM32_DAC_DUAL_MODE != FALSE */
|
||||
/* Operating in DUAL mode with two channels to setup. Set registers for
|
||||
both channels from configuration. Lower and upper half words specify
|
||||
configuration for channels CH1 & CH2 respectively.*/
|
||||
(void)channel;
|
||||
dacp->params->dac->MCR = dacp->config->mcr;
|
||||
|
||||
/* Enable and initialise both CH1 and CH2. Mask out DMA and calibrate.*/
|
||||
reg = dacp->config->cr;
|
||||
reg &= ~(DAC_CR_DMAEN1 | DAC_CR_DMAEN2 | DAC_CR_CEN1 | DAC_CR_CEN2);
|
||||
dacp->params->dac->CR = DAC_CR_EN2 | DAC_CR_EN1 | reg;
|
||||
dac_lld_put_channel(dacp, 0U, (dacsample_t)dacp->config->init);
|
||||
dac_lld_put_channel(dacp, 1U, (dacsample_t)(dacp->config->init >>
|
||||
(sizeof(dacsample_t) * 8)));
|
||||
#endif /* STM32_DAC_DUAL_MODE == FALSE */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,6 +569,8 @@ void dac_lld_stop(DACDriver *dacp) {
|
|||
|
||||
/**
|
||||
* @brief Outputs a value directly on a DAC channel.
|
||||
* @note While a group is active in DUAL mode on CH1 only then CH2
|
||||
* is available for normal output (put) operations.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
* @param[in] channel DAC channel number
|
||||
|
@ -566,6 +582,13 @@ void dac_lld_put_channel(DACDriver *dacp,
|
|||
dacchannel_t channel,
|
||||
dacsample_t sample) {
|
||||
|
||||
#if STM32_DAC_DUAL_MODE
|
||||
if (dacp->grpp != NULL) {
|
||||
osalDbgAssert(dacp->grpp->num_channels == 1 && channel == 1,
|
||||
"channel busy");
|
||||
}
|
||||
#endif /* STM32_DAC_DUAL_MODE */
|
||||
|
||||
switch (dacp->config->datamode) {
|
||||
case DAC_DHRM_12BIT_RIGHT:
|
||||
#if STM32_DAC_DUAL_MODE
|
||||
|
@ -638,6 +661,11 @@ void dac_lld_put_channel(DACDriver *dacp,
|
|||
* 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.
|
||||
* @note If using DUAL mode with a single channel conversion then CH2
|
||||
* is enabled for manual (put_channel) for non DMA triggered use. The
|
||||
* the data format for put operations is specified in the upper half
|
||||
* word of the 'datamode' field. The CR setting is in the upper half
|
||||
* word of the 'cr' field of the configuration.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
*
|
||||
|
@ -744,15 +772,18 @@ void dac_lld_start_conversion(DACDriver *dacp) {
|
|||
STM32_DMA_CR_HTIE | STM32_DMA_CR_TCIE);
|
||||
dmaStreamEnable(dacp->dma);
|
||||
|
||||
/* DAC configuration.*/
|
||||
/* DAC configuration. Mask out DMA and calibration.*/
|
||||
cr = dacp->params->dac->CR;
|
||||
|
||||
cr &= ~(DAC_CR_CEN1 | DAC_CR_CEN2 | DAC_CR_DMAEN2);
|
||||
#if STM32_DAC_DUAL_MODE == FALSE
|
||||
/* Start the DMA on the single channel.*/
|
||||
cr &= dacp->params->regmask;
|
||||
cr |= (DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) | DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
|
||||
cr |= (DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) |
|
||||
DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
|
||||
#else
|
||||
cr = DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) | DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr
|
||||
| (dacp->grpp->trigger << DAC_CR_TSEL2_Pos) | DAC_CR_TEN2 | DAC_CR_EN2 | (dacp->config->cr << 16);
|
||||
/* Enable the DMA operation on CH1.*/
|
||||
cr = DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) |
|
||||
DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr;
|
||||
#endif
|
||||
|
||||
dacp->params->dac->CR = cr;
|
||||
|
@ -760,9 +791,9 @@ void dac_lld_start_conversion(DACDriver *dacp) {
|
|||
|
||||
/**
|
||||
* @brief Stops an ongoing conversion.
|
||||
* @details This function stops the currently ongoing conversion and returns
|
||||
* the driver in the @p DAC_READY state. If there was no conversion
|
||||
* being processed then the function does nothing.
|
||||
* @details This function stops the currently ongoing conversion. The
|
||||
* configuration is restored to start condition. The DOR values
|
||||
* are not updated.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
*
|
||||
|
@ -776,21 +807,19 @@ void dac_lld_stop_conversion(DACDriver *dacp) {
|
|||
dmaStreamFreeI(dacp->dma);
|
||||
dacp->dma = NULL;
|
||||
|
||||
/* Restore start configuration but leave DORx at current values.*/
|
||||
cr = dacp->params->dac->CR;
|
||||
|
||||
#if STM32_DAC_DUAL_MODE == FALSE
|
||||
uint32_t mcr;
|
||||
mcr = dacp->params->dac->MCR & dacp->params->regmask;
|
||||
dacp->params->dac->MCR = mcr |
|
||||
((dacp->config->mcr & dacp->params->regmask) << dacp->params->regshift);
|
||||
cr &= dacp->params->regmask;
|
||||
cr |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
|
||||
cr |= (DAC_CR_EN1 | (dacp->config->cr & ~dacp->params->regmask)) <<
|
||||
dacp->params->regshift;
|
||||
#else
|
||||
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)) {
|
||||
cr = DAC_CR_EN2 | (dacp->config->cr << 16) |
|
||||
DAC_CR_EN1 | dacp->config->cr;
|
||||
}
|
||||
else {
|
||||
cr = DAC_CR_EN1 | dacp->config->cr;
|
||||
}
|
||||
dacp->params->dac->MCR = dacp->config->mcr;
|
||||
cr = dacp->config->cr | DAC_CR_EN1 | DAC_CR_EN2;
|
||||
#endif
|
||||
|
||||
dacp->params->dac->CR = cr;
|
||||
|
|
|
@ -31,14 +31,6 @@
|
|||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name DAC trigger modes
|
||||
* @{
|
||||
*/
|
||||
#define DAC_TRG_MASK 7U
|
||||
#define DAC_TRG(n) (n)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
@ -487,7 +479,7 @@
|
|||
/**
|
||||
* @brief Max DAC channels.
|
||||
*/
|
||||
#if STM32_DAC_DUAL_MODE == FALSE
|
||||
#if STM32_DAC_DUAL_MODE == TRUE
|
||||
#define DAC_MAX_CHANNELS 2
|
||||
#else
|
||||
#define DAC_MAX_CHANNELS 1
|
||||
|
@ -571,10 +563,6 @@ typedef enum {
|
|||
#endif
|
||||
} dacdhrmode_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the DAC driver structure.
|
||||
*/
|
||||
|
@ -586,14 +574,18 @@ typedef enum {
|
|||
|
||||
/**
|
||||
* @brief Low level fields of the DAC configuration structure.
|
||||
* @note In DUAL mode init, cr and mcr fields hold CH1 settings in their
|
||||
* lower 16 bits and CH2 settings in the upper 16 bits.
|
||||
*/
|
||||
#define dac_lld_config_fields \
|
||||
/* Initial output on DAC channels.*/ \
|
||||
dacsample_t init; \
|
||||
/* Initial output on DAC channel.*/ \
|
||||
uint32_t init; \
|
||||
/* DAC data holding register mode.*/ \
|
||||
dacdhrmode_t datamode; \
|
||||
/* DAC control register lower 16 bits.*/ \
|
||||
uint32_t cr
|
||||
/* DAC control register.*/ \
|
||||
uint32_t cr; \
|
||||
/* DAC mode control register.*/ \
|
||||
uint32_t mcr
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the DAC group configuration structure.
|
||||
|
@ -604,6 +596,23 @@ typedef enum {
|
|||
initialization. All other fields are handled internally.*/ \
|
||||
uint32_t trigger
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name DAC trigger modes
|
||||
* @{
|
||||
*/
|
||||
#define DAC_TRG_MASK 7U
|
||||
#define DAC_TRG(n) (n)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Shift of initialisation value for channel 2 in dual mode.
|
||||
*/
|
||||
#define DAC_VALUE_DUAL(n) ((n) << (sizeof(dacsample_t) * 8))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -158,7 +158,8 @@ void dacStop(DACDriver *dacp) {
|
|||
void dacPutChannelX(DACDriver *dacp, dacchannel_t channel, dacsample_t sample) {
|
||||
|
||||
osalDbgCheck(channel < (dacchannel_t)DAC_MAX_CHANNELS);
|
||||
osalDbgAssert(dacp->state == DAC_READY, "invalid state");
|
||||
osalDbgAssert(dacp->state == DAC_READY || dacp->state == DAC_ACTIVE,
|
||||
"invalid state");
|
||||
|
||||
dac_lld_put_channel(dacp, channel, sample);
|
||||
}
|
||||
|
@ -193,10 +194,10 @@ void dacStartConversion(DACDriver *dacp,
|
|||
* @brief Starts a DAC conversion.
|
||||
* @details Starts an asynchronous conversion operation.
|
||||
* @post The callbacks associated to the conversion group will be invoked
|
||||
* on buffer fill and error events.
|
||||
* on buffer complete and error events.
|
||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||
* channels number configured into the conversion group and N is the
|
||||
* buffer depth. The samples are sequentially written into the buffer
|
||||
* buffer depth. The samples are sequentially organised in the buffer
|
||||
* with no gaps.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
|
@ -284,25 +285,25 @@ void dacStopConversionI(DACDriver *dacp) {
|
|||
}
|
||||
}
|
||||
|
||||
#if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
#if (DAC_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Performs a DAC conversion.
|
||||
* @details Performs a synchronous conversion operation.
|
||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||
* channels number configured into the conversion group and N is the
|
||||
* buffer depth. The samples are sequentially written into the buffer
|
||||
* buffer depth. The samples are sequentially organised in the buffer
|
||||
* with no gaps.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
* @param[in] grpp pointer to a @p DACConversionGroup object
|
||||
* @param[out] samples pointer to the samples buffer
|
||||
* @param[in] samples pointer to the samples buffer
|
||||
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
||||
* must be one or an even number.
|
||||
*
|
||||
* @return The operation result.
|
||||
* @retval MSG_OK Conversion finished.
|
||||
* @retval MSG_RESET The conversion has been stopped using
|
||||
* @p acdStopConversion() or @p acdStopConversionI(),
|
||||
* the result buffer may contain incorrect data.
|
||||
* @p dacStopConversion() or @p dacStopConversionI().
|
||||
* @retval MSG_TIMEOUT The conversion has been stopped because an hardware
|
||||
* error.
|
||||
*
|
||||
|
@ -322,7 +323,63 @@ msg_t dacConvert(DACDriver *dacp,
|
|||
osalSysUnlock();
|
||||
return msg;
|
||||
}
|
||||
#endif /* DAC_USE_WAIT == TRUE */
|
||||
|
||||
/**
|
||||
* @brief Synchronize to a conversion completion.
|
||||
* @note This function can only be called by a single thread at time.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
* @param[in] timeout wait timeout
|
||||
*
|
||||
* @return The wait result.
|
||||
* @retval MSG_OK if operation completed without errors.
|
||||
* @retval MSG_TIMEOUT if synchronization request timed out.
|
||||
* @retval MSG_RESET if the conversion has been stopped.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
msg_t dacSynchronizeS(DACDriver *dacp, sysinterval_t timeout) {
|
||||
msg_t msg;
|
||||
|
||||
osalDbgCheckClassS();
|
||||
osalDbgCheck(dacp != NULL);
|
||||
osalDbgAssert((dacp->state == DAC_ACTIVE) || (dacp->state == DAC_READY),
|
||||
"invalid state");
|
||||
|
||||
if (dacp->state == DAC_ACTIVE) {
|
||||
msg = osalThreadSuspendTimeoutS(&dacp->thread, timeout);
|
||||
}
|
||||
else {
|
||||
msg = MSG_OK;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Synchronize to a conversion completion.
|
||||
* @note This function can only be called by a single thread at time.
|
||||
*
|
||||
* @param[in] dacp pointer to the @p DACDriver object
|
||||
* @param[in] timeout wait timeout
|
||||
*
|
||||
* @return The wait result.
|
||||
* @retval MSG_OK if operation completed without errors.
|
||||
* @retval MSG_TIMEOUT if synchronization request timed out.
|
||||
* @retval MSG_RESET if the conversion has been stopped.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t dacSynchronize(DACDriver *dacp, sysinterval_t timeout) {
|
||||
msg_t msg;
|
||||
|
||||
osalSysLock();
|
||||
msg = dacSynchronizeS(dacp, timeout);
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif /* DAC_USE_SYNCHRONIZATION == TRUE */
|
||||
|
||||
#if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
*****************************************************************************
|
||||
|
||||
*** Next ***
|
||||
- NEW: Improved DAC driver, updated STM32 DACv1.
|
||||
- NEW: STM32 RTCv2 and RTCv3 modified to not use shadow registers.
|
||||
- NEW: Enhanced STM32F7xx MPU configuration in mcuconf.h.
|
||||
- NEW: I2C slave support in HAL high level driver.
|
||||
|
|
Loading…
Reference in New Issue