STM32L4 DAC: report transfer as completed in DMA callback. Without this even O_NONBLOCK writes block the calling task if DAC was using DMA.
This commit is contained in:
parent
874947d7e5
commit
1152e4868b
@ -3249,7 +3249,9 @@ config STM32L4_DAC1_TIMER
|
|||||||
|
|
||||||
config STM32L4_DAC1_TIMER_FREQUENCY
|
config STM32L4_DAC1_TIMER_FREQUENCY
|
||||||
int "DAC1 timer frequency"
|
int "DAC1 timer frequency"
|
||||||
default 0
|
default 100
|
||||||
|
---help---
|
||||||
|
DAC1 output frequency. Default: 100Hz
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -3272,7 +3274,9 @@ config STM32L4_DAC2_TIMER
|
|||||||
|
|
||||||
config STM32L4_DAC2_TIMER_FREQUENCY
|
config STM32L4_DAC2_TIMER_FREQUENCY
|
||||||
int "DAC2 timer frequency"
|
int "DAC2 timer frequency"
|
||||||
default 0
|
default 100
|
||||||
|
---help---
|
||||||
|
DAC2 output frequency. Default: 100Hz
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -103,11 +103,12 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_STM32L4_DAC1_DMA
|
#ifdef CONFIG_STM32L4_DAC1_DMA
|
||||||
# if !defined(CONFIG_STM32L4_DAC1_TIMER)
|
# if !defined(CONFIG_STM32L4_DAC1_TIMER)
|
||||||
# warning "A timer number must be specificed in CONFIG_STM32L4_DAC1_TIMER"
|
# warning "A timer number must be specified in CONFIG_STM32L4_DAC1_TIMER"
|
||||||
# undef CONFIG_STM32L4_DAC1_DMA
|
# undef CONFIG_STM32L4_DAC1_DMA
|
||||||
# undef CONFIG_STM32L4_DAC1_TIMER_FREQUENCY
|
# undef CONFIG_STM32L4_DAC1_TIMER_FREQUENCY
|
||||||
# elif !defined(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY)
|
# elif !defined(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY) || \
|
||||||
# warning "A timer frequency must be specificed in CONFIG_STM32L4_DAC1_TIMER_FREQUENCY"
|
(CONFIG_STM32L4_DAC1_TIMER_FREQUENCY < 1)
|
||||||
|
# warning "A timer frequency (>0) must be specified in CONFIG_STM32L4_DAC1_TIMER_FREQUENCY"
|
||||||
# undef CONFIG_STM32L4_DAC1_DMA
|
# undef CONFIG_STM32L4_DAC1_DMA
|
||||||
# undef CONFIG_STM32L4_DAC1_TIMER
|
# undef CONFIG_STM32L4_DAC1_TIMER
|
||||||
# endif
|
# endif
|
||||||
@ -115,11 +116,12 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_STM32L4_DAC2_DMA
|
#ifdef CONFIG_STM32L4_DAC2_DMA
|
||||||
# if !defined(CONFIG_STM32L4_DAC2_TIMER)
|
# if !defined(CONFIG_STM32L4_DAC2_TIMER)
|
||||||
# warning "A timer number must be specificed in CONFIG_STM32L4_DAC2_TIMER"
|
# warning "A timer number must be specified in CONFIG_STM32L4_DAC2_TIMER"
|
||||||
# undef CONFIG_STM32L4_DAC2_DMA
|
# undef CONFIG_STM32L4_DAC2_DMA
|
||||||
# undef CONFIG_STM32L4_DAC2_TIMER_FREQUENCY
|
# undef CONFIG_STM32L4_DAC2_TIMER_FREQUENCY
|
||||||
# elif !defined(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY)
|
# elif !defined(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY) || \
|
||||||
# warning "A timer frequency must be specificed in CONFIG_STM32L4_DAC2_TIMER_FREQUENCY"
|
(CONFIG_STM32L4_DAC2_TIMER_FREQUENCY < 1)
|
||||||
|
# warning "A timer frequency (>0) must be specified in CONFIG_STM32L4_DAC2_TIMER_FREQUENCY"
|
||||||
# undef CONFIG_STM32L4_DAC2_DMA
|
# undef CONFIG_STM32L4_DAC2_DMA
|
||||||
# undef CONFIG_STM32L4_DAC2_TIMER
|
# undef CONFIG_STM32L4_DAC2_TIMER
|
||||||
# endif
|
# endif
|
||||||
@ -269,7 +271,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
|
/* Calculate timer divider values based upon DACn_TIMER_PCLK_FREQUENCY and
|
||||||
* CONFIG_STM32_DACn_TIMER_FREQUENCY.
|
* CONFIG_STM32L4_DACn_TIMER_FREQUENCY.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#warning "Missing Logic"
|
#warning "Missing Logic"
|
||||||
@ -312,6 +314,7 @@ struct stm32_chan_s
|
|||||||
DMA_HANDLE dma; /* Allocated DMA channel */
|
DMA_HANDLE dma; /* Allocated DMA channel */
|
||||||
uint32_t tbase; /* Timer base address */
|
uint32_t tbase; /* Timer base address */
|
||||||
uint32_t tfrequency; /* Timer frequency */
|
uint32_t tfrequency; /* Timer frequency */
|
||||||
|
int result; /* DMA result */
|
||||||
uint16_t dmabuffer[CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
|
uint16_t dmabuffer[CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -323,9 +326,10 @@ struct stm32_chan_s
|
|||||||
/* DAC Register access */
|
/* DAC Register access */
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset);
|
static inline void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
uint32_t value);
|
||||||
uint32_t value);
|
static inline void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
|
uint32_t clearbits, uint32_t setbits);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* DAC methods */
|
/* DAC methods */
|
||||||
@ -457,7 +461,7 @@ static struct stm32_dac_s g_dacblock;
|
|||||||
* Modify the contents of the DAC control register.
|
* Modify the contents of the DAC control register.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* priv - Driver state instance
|
* chan - A reference to the DAC channel state data
|
||||||
* clearbits - Bits in the control register to be cleared
|
* clearbits - Bits in the control register to be cleared
|
||||||
* setbits - Bits in the control register to be set
|
* setbits - Bits in the control register to be set
|
||||||
*
|
*
|
||||||
@ -484,28 +488,6 @@ static inline void stm32l4_dac_modify_cr(FAR struct stm32_chan_s *chan,
|
|||||||
modifyreg32(chan->cr, clearbits << shift, setbits << shift);
|
modifyreg32(chan->cr, clearbits << shift, setbits << shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: tim_getreg
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Read the value of an DMA timer register.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* chan - A reference to the DAC block status
|
|
||||||
* offset - The offset to the register to read
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* The current contents of the specified register
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
|
||||||
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
|
||||||
{
|
|
||||||
return getreg32(chan->tbase + offset);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tim_putreg
|
* Name: tim_putreg
|
||||||
*
|
*
|
||||||
@ -513,7 +495,7 @@ static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
|||||||
* Read the value of an DMA timer register.
|
* Read the value of an DMA timer register.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* chan - A reference to the DAC block status
|
* chan - A reference to the DAC channel state data
|
||||||
* offset - The offset to the register to read
|
* offset - The offset to the register to read
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@ -522,8 +504,8 @@ static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
static inline void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
uint32_t value)
|
uint32_t value)
|
||||||
{
|
{
|
||||||
putreg32(value, chan->tbase + offset);
|
putreg32(value, chan->tbase + offset);
|
||||||
}
|
}
|
||||||
@ -536,7 +518,7 @@ static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
|||||||
* Modify the value of an DMA timer register.
|
* Modify the value of an DMA timer register.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* priv - Driver state instance
|
* chan - A reference to the DAC channel state data
|
||||||
* offset - The timer register offset
|
* offset - The timer register offset
|
||||||
* clearbits - Bits in the control register to be cleared
|
* clearbits - Bits in the control register to be cleared
|
||||||
* setbits - Bits in the control register to be set
|
* setbits - Bits in the control register to be set
|
||||||
@ -547,8 +529,8 @@ static void tim_putreg(FAR struct stm32_chan_s *chan, int offset,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
static inline void tim_modifyreg(FAR struct stm32_chan_s *chan, int offset,
|
||||||
uint32_t clearbits, uint32_t setbits)
|
uint32_t clearbits, uint32_t setbits)
|
||||||
{
|
{
|
||||||
modifyreg32(chan->tbase + offset, clearbits, setbits);
|
modifyreg32(chan->tbase + offset, clearbits, setbits);
|
||||||
}
|
}
|
||||||
@ -659,6 +641,48 @@ static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
|
|||||||
#ifdef HAVE_DMA
|
#ifdef HAVE_DMA
|
||||||
static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg)
|
static void dac_dmatxcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg)
|
||||||
{
|
{
|
||||||
|
struct stm32_chan_s *chan = (struct stm32_chan_s *)arg;
|
||||||
|
struct dac_dev_s *dev;
|
||||||
|
|
||||||
|
DEBUGASSERT(chan);
|
||||||
|
|
||||||
|
#ifdef CONFIG_STM32L4_DAC1
|
||||||
|
if (chan->intf == 0)
|
||||||
|
{
|
||||||
|
dev = &g_dac1dev;
|
||||||
|
}
|
||||||
|
#if STM32L4_NDAC > 1
|
||||||
|
else if (chan->intf == 1)
|
||||||
|
{
|
||||||
|
dev = &g_dac2dev;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
#endif /* CONFIG_STM32L4_DAC1 */
|
||||||
|
#ifdef CONFIG_STM32L4_DAC2
|
||||||
|
if (chan->intf == 2)
|
||||||
|
{
|
||||||
|
dev = &g_dac3dev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
DEBUGPANIC();
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(dev->ad_priv == chan);
|
||||||
|
|
||||||
|
/* Report the result of the transfer only if the TX callback has not already
|
||||||
|
* reported an error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (chan->result == -EBUSY)
|
||||||
|
{
|
||||||
|
/* Save the result of the transfer if no error was previously reported. */
|
||||||
|
|
||||||
|
chan->result = (isr & DMA_CHAN_TEIF_BIT) ? -EIO : OK;
|
||||||
|
dac_txdone(dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -705,8 +729,9 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
|
|||||||
stm32l4_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer,
|
stm32l4_dmasetup(chan->dma, chan->dro, (uint32_t)chan->dmabuffer,
|
||||||
CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE, DAC_DMA_CONTROL_WORD);
|
CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE, DAC_DMA_CONTROL_WORD);
|
||||||
|
|
||||||
/* Enable DMA */
|
/* Start the DMA */
|
||||||
|
|
||||||
|
chan->result = -EBUSY;
|
||||||
stm32l4_dmastart(chan->dma, dac_dmatxcallback, chan, false);
|
stm32l4_dmastart(chan->dma, dac_dmatxcallback, chan, false);
|
||||||
|
|
||||||
/* Enable DMA for DAC Channel */
|
/* Enable DMA for DAC Channel */
|
||||||
@ -777,7 +802,7 @@ static int dac_timinit(FAR struct stm32_chan_s *chan)
|
|||||||
* counter mode (up).
|
* counter mode (up).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Enable the timer. At most, two of the following cases (pluse the
|
/* Enable the timer. At most, two of the following cases (plus the
|
||||||
* default) will be enabled
|
* default) will be enabled
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1004,6 +1029,7 @@ static int dac_chaninit(FAR struct stm32_chan_s *chan)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret);
|
aerr("ERROR: Failed to initialize the DMA timer: %d\n", ret);
|
||||||
|
stm32l4_dmafree(chan->dma);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user