STM32L4 DAC: Added basic support for low level operations
This commit is contained in:
parent
7e6b4f6e07
commit
40e6c8dca4
@ -5473,6 +5473,12 @@ config STM32L4_DAC2_OUTPUT_ADC
|
||||
---help---
|
||||
Route DAC2 output to ADC input instead of external pin.
|
||||
|
||||
config STM32L4_DAC_LL_OPS
|
||||
bool "DAC low-level operations"
|
||||
default n
|
||||
---help---
|
||||
Enable low-level DAC ops.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "DFSDM Configuration"
|
||||
|
@ -305,6 +305,9 @@ struct stm32_dac_s
|
||||
|
||||
struct stm32_chan_s
|
||||
{
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
const struct stm32_dac_ops_s *llops; /* Low-level DAC ops */
|
||||
#endif
|
||||
uint8_t inuse : 1; /* True, the driver is in use and not available */
|
||||
#ifdef HAVE_DMA
|
||||
uint8_t hasdma : 1; /* True, this channel supports DMA */
|
||||
@ -333,6 +336,9 @@ struct stm32_chan_s
|
||||
|
||||
/* DAC Register access */
|
||||
|
||||
static uint32_t dac_getreg(struct stm32_chan_s *priv, int offset);
|
||||
static void dac_dumpregs(struct stm32_chan_s *priv);
|
||||
|
||||
#ifdef HAVE_DMA
|
||||
static inline void tim_putreg(struct stm32_chan_s *chan, int offset,
|
||||
uint32_t value);
|
||||
@ -357,6 +363,16 @@ static int dac_timinit(struct stm32_chan_s *chan);
|
||||
static int dac_chaninit(struct stm32_chan_s *chan);
|
||||
static void dac_blockinit(void);
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
static void dac_llops_enable(struct stm32_dac_dev_s *dev, bool enabled);
|
||||
static void dac_llops_writedro(struct stm32_dac_dev_s *dev, uint16_t data);
|
||||
#ifdef HAVE_DMA
|
||||
static void dac_llops_startdma(struct stm32_dac_dev_s *dev);
|
||||
static void dac_llops_stopdma(struct stm32_dac_dev_s *dev);
|
||||
#endif
|
||||
static void dac_llops_dumpregs(struct stm32_dac_dev_s *dev);
|
||||
#endif /* CONFIG_STM32L4_DAC_LL_OPS */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -371,6 +387,21 @@ static const struct dac_ops_s g_dacops =
|
||||
.ao_ioctl = dac_ioctl,
|
||||
};
|
||||
|
||||
/* Publicly visible DAC lower-half operations */
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
static const struct stm32_dac_ops_s g_dac_llops =
|
||||
{
|
||||
.enable = dac_llops_enable,
|
||||
.write_dro = dac_llops_writedro,
|
||||
#ifdef HAVE_DMA
|
||||
.start_dma = dac_llops_startdma,
|
||||
.stop_dma = dac_llops_stopdma,
|
||||
#endif
|
||||
.dump_regs = dac_llops_dumpregs
|
||||
};
|
||||
#endif /* CONFIG_STM32L4_DAC_LL_OPS */
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC1
|
||||
/* Channel 1 */
|
||||
|
||||
@ -380,6 +411,9 @@ uint16_t stm32l4_dac1_dmabuffer[CONFIG_STM32L4_DAC1_DMA_BUFFER_SIZE];
|
||||
|
||||
static struct stm32_chan_s g_dac1priv =
|
||||
{
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
.llops = &g_dac_llops,
|
||||
#endif
|
||||
.intf = 0,
|
||||
#ifdef CONFIG_STM32L4_DAC1_OUTPUT_ADC
|
||||
.pin = 0xffffffffu,
|
||||
@ -417,6 +451,9 @@ uint16_t stm32l4_dac2_dmabuffer[CONFIG_STM32L4_DAC2_DMA_BUFFER_SIZE];
|
||||
|
||||
static struct stm32_chan_s g_dac2priv =
|
||||
{
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
.llops = &g_dac_llops,
|
||||
#endif
|
||||
.intf = 1,
|
||||
#ifdef CONFIG_STM32L4_DAC2_OUTPUT_ADC
|
||||
.pin = 0xffffffffu,
|
||||
@ -451,6 +488,26 @@ static struct stm32_dac_s g_dacblock;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dac_getreg
|
||||
*
|
||||
* Description:
|
||||
* Read the value of an DAC register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the DAC block status
|
||||
* offset - The offset to the register to read
|
||||
*
|
||||
* Returned Value:
|
||||
* The current contents of the specified register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t dac_getreg(struct stm32_chan_s *priv, int offset)
|
||||
{
|
||||
return getreg32(STM32L4_DAC_BASE + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32l4_dac_modify_cr
|
||||
*
|
||||
@ -519,6 +576,22 @@ static inline void stm32l4_dac_modify_mcr(struct stm32_chan_s *chan,
|
||||
modifyreg32(STM32L4_DAC_MCR, clearbits << shift, setbits << shift);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dac_dumpregs
|
||||
****************************************************************************/
|
||||
|
||||
static void dac_dumpregs(struct stm32_chan_s *priv)
|
||||
{
|
||||
UNUSED(priv);
|
||||
|
||||
ainfo("CR: 0x%08" PRIx32 " SWTRGR: 0x%08" PRIx32
|
||||
"SR: 0x%08" PRIx32 " MCR: 0x%08" PRIx32 "\n",
|
||||
dac_getreg(priv, STM32L4_DAC_CR_OFFSET),
|
||||
dac_getreg(priv, STM32L4_DAC_SWTRIGR_OFFSET),
|
||||
dac_getreg(priv, STM32L4_DAC_SR_OFFSET),
|
||||
dac_getreg(priv, STM32L4_DAC_MCR_OFFSET));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tim_putreg
|
||||
*
|
||||
@ -1140,6 +1213,112 @@ static void dac_blockinit(void)
|
||||
g_dacblock.init = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dac_llops_enable
|
||||
****************************************************************************/
|
||||
|
||||
static void dac_llops_enable(struct stm32_dac_dev_s *dev, bool enabled)
|
||||
{
|
||||
struct stm32_chan_s *priv = (struct stm32_chan_s *)dev;
|
||||
|
||||
/* Enable/disable DAC Channel */
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
stm32l4_dac_modify_cr(priv, 0, DAC_CR_EN);
|
||||
}
|
||||
else
|
||||
{
|
||||
stm32l4_dac_modify_cr(priv, DAC_CR_EN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dac_llops_writedro
|
||||
****************************************************************************/
|
||||
|
||||
static void dac_llops_writedro(struct stm32_dac_dev_s *dev, uint16_t data)
|
||||
{
|
||||
struct stm32_chan_s *priv = (struct stm32_chan_s *)dev;
|
||||
|
||||
putreg16(data, priv->dro);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dac_llops_startdma
|
||||
****************************************************************************/
|
||||
#ifdef HAVE_DMA
|
||||
static void dac_llops_startdma(struct stm32_dac_dev_s *dev)
|
||||
{
|
||||
struct stm32_chan_s *priv = (struct stm32_chan_s *)dev;
|
||||
|
||||
/* Configure the DMA stream/channel.
|
||||
*
|
||||
* - Channel number
|
||||
* - Peripheral address
|
||||
* - Direction: Memory to peripheral
|
||||
* - Disable peripheral address increment
|
||||
* - Enable memory address increment
|
||||
* - Peripheral data size: half word
|
||||
* - Mode: circular???
|
||||
* - Priority: ?
|
||||
* - FIFO mode: disable
|
||||
* - FIFO threshold: half full
|
||||
* - Memory Burst: single
|
||||
* - Peripheral Burst: single
|
||||
*/
|
||||
|
||||
stm32l4_dmasetup(priv->dma, priv->dro, (uint32_t)priv->dmabuffer,
|
||||
priv->buffer_len, DAC_DMA_CONTROL_WORD);
|
||||
|
||||
/* Start the DMA */
|
||||
|
||||
priv->result = -EBUSY;
|
||||
stm32l4_dmastart(priv->dma, dac_dmatxcallback, priv, false);
|
||||
|
||||
/* Enable DMA for DAC Channel */
|
||||
|
||||
stm32l4_dac_modify_cr(priv, 0, DAC_CR_DMAEN);
|
||||
|
||||
/* Reset counters (generate an update) */
|
||||
|
||||
tim_modifyreg(priv, STM32L4_GTIM_EGR_OFFSET, 0, GTIM_EGR_UG);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dac_llops_stopdma
|
||||
****************************************************************************/
|
||||
|
||||
static void dac_llops_stopdma(struct stm32_dac_dev_s *dev)
|
||||
{
|
||||
struct stm32_chan_s *priv = (struct stm32_chan_s *)dev;
|
||||
|
||||
/* Stop the DMA */
|
||||
|
||||
priv->result = -EBUSY;
|
||||
stm32l4_dmastop(priv->dma);
|
||||
|
||||
/* Enable DMA for DAC Channel */
|
||||
|
||||
stm32l4_dac_modify_cr(priv, 0, DAC_CR_DMAEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_llops_dumpregs
|
||||
****************************************************************************/
|
||||
|
||||
static void dac_llops_dumpregs(struct stm32_dac_dev_s *dev)
|
||||
{
|
||||
struct stm32_chan_s *priv = (struct stm32_chan_s *)dev;
|
||||
|
||||
dac_dumpregs(priv);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STM32L4_DAC_LL_OPS */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -78,6 +78,65 @@
|
||||
# undef CONFIG_STM32L4_TIM17_DAC
|
||||
#endif
|
||||
|
||||
/* Low-level ops helpers ****************************************************/
|
||||
|
||||
#define DAC_ENABLE(dac,d) \
|
||||
(dac)->llops->enable(dac,d)
|
||||
#define DAC_WRITE_DRO(dac,d) \
|
||||
(dac)->llops->write_dro(dac,d)
|
||||
#define DAC_START_DMA(dac) \
|
||||
(dac)->llops->start_dma(dac)
|
||||
#define DAC_STOP_DMA(dac) \
|
||||
(dac)->llops->stop_dma(dac)
|
||||
#define DAC_DUMP_REGS(dac) \
|
||||
(dac)->llops->dump_regs(dac)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32L4_DAC_LL_OPS
|
||||
|
||||
/* This structure provides the publicly visible representation of the
|
||||
* "lower-half" DAC driver structure.
|
||||
*/
|
||||
|
||||
struct stm32_dac_dev_s
|
||||
{
|
||||
/* Publicly visible portion of the "lower-half" ADC driver structure */
|
||||
|
||||
const struct stm32_dac_ops_s *llops;
|
||||
|
||||
/* Require cast-compatibility with private "lower-half" ADC structure */
|
||||
};
|
||||
|
||||
/* Low-level operations for DAC */
|
||||
|
||||
struct stm32_dac_ops_s
|
||||
{
|
||||
/* Enable / Disable DAC */
|
||||
|
||||
void (*enable)(struct stm32_dac_dev_s *dev, bool enabled);
|
||||
|
||||
/* Write DRO */
|
||||
|
||||
void (*write_dro)(struct stm32_dac_dev_s *dev, uint16_t data);
|
||||
|
||||
/* Start DMA */
|
||||
|
||||
void (*start_dma)(struct stm32_dac_dev_s *dev);
|
||||
|
||||
/* Stop DMA */
|
||||
|
||||
void (*stop_dma)(struct stm32_dac_dev_s *dev);
|
||||
|
||||
/* Dump DAC regs */
|
||||
|
||||
void (*dump_regs)(struct stm32_dac_dev_s *dev);
|
||||
};
|
||||
|
||||
#endif /* CONFIG_STM32L4_DAC_LL_OPS */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user