STM32L4 DAC: add option for routing DAC output to ADC
Actually write something to the DAC DMA buffer. Change-Id: I1b2516ac26fb17f5242611b56be8926c5f40c2c7 Signed-off-by: Juha Niskanen <juha.niskanen@haltian.com>
This commit is contained in:
parent
91d473b816
commit
4025205772
@ -157,7 +157,7 @@
|
||||
# define DAC_CR_WAVE_TRIANGLE (2 << DAC_CR_WAVE_SHIFT) /* Triangle wave generation enabled */
|
||||
#define DAC_CR_MAMP_SHIFT (8) /* Bits 8-11: DAC channel mask/amplitude selector */
|
||||
#define DAC_CR_MAMP_MASK (15 << DAC_CR_MAMP_SHIFT)
|
||||
# define DAC_CR_MAMP_AMP1 (0 << DAC_CR_MAMP1_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */
|
||||
# define DAC_CR_MAMP_AMP1 (0 << DAC_CR_MAMP_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */
|
||||
# define DAC_CR_MAMP_AMP3 (1 << DAC_CR_MAMP_SHIFT) /* Unmask bits[1:0] of LFSR/triangle amplitude=3 */
|
||||
# define DAC_CR_MAMP_AMP7 (2 << DAC_CR_MAMP_SHIFT) /* Unmask bits[2:0] of LFSR/triangle amplitude=7 */
|
||||
# define DAC_CR_MAMP_AMP15 (3 << DAC_CR_MAMP_SHIFT) /* Unmask bits[3:0] of LFSR/triangle amplitude=15 */
|
||||
|
@ -3271,6 +3271,13 @@ config STM32L4_DAC1_TIMER_FREQUENCY
|
||||
|
||||
endif
|
||||
|
||||
config STM32L4_DAC1_OUTPUT_ADC
|
||||
bool "DAC1 output to ADC"
|
||||
depends on STM32L4_DAC1
|
||||
default n
|
||||
---help---
|
||||
Route DAC1 output to ADC input instead of external pin.
|
||||
|
||||
config STM32L4_DAC2_DMA
|
||||
bool "DAC2 DMA"
|
||||
depends on STM32L4_DAC2
|
||||
@ -3296,8 +3303,16 @@ config STM32L4_DAC2_TIMER_FREQUENCY
|
||||
|
||||
endif
|
||||
|
||||
config STM32L4_DAC2_OUTPUT_ADC
|
||||
bool "DAC2 output to ADC"
|
||||
depends on STM32L4_DAC2
|
||||
default n
|
||||
---help---
|
||||
Route DAC2 output to ADC input instead of external pin.
|
||||
|
||||
config STM32L4_DAC_DMA_BUFFER_SIZE
|
||||
int "DAC DMA buffer size"
|
||||
depends on STM32L4_DAC1_DMA || STM32L4_DAC2_DMA
|
||||
default 256
|
||||
|
||||
endmenu
|
||||
|
@ -120,7 +120,7 @@
|
||||
# define DAC_CR_WAVE_TRIANGLE (2 << DAC_CR_WAVE_SHIFT) /* Triangle wave generation enabled */
|
||||
#define DAC_CR_MAMP_SHIFT (8) /* Bits 8-11: DAC channel mask/amplitude selector */
|
||||
#define DAC_CR_MAMP_MASK (15 << DAC_CR_MAMP_SHIFT)
|
||||
# define DAC_CR_MAMP_AMP1 (0 << DAC_CR_MAMP1_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */
|
||||
# define DAC_CR_MAMP_AMP1 (0 << DAC_CR_MAMP_SHIFT) /* Unmask bit0 of LFSR/triangle amplitude=1 */
|
||||
# define DAC_CR_MAMP_AMP3 (1 << DAC_CR_MAMP_SHIFT) /* Unmask bits[1:0] of LFSR/triangle amplitude=3 */
|
||||
# define DAC_CR_MAMP_AMP7 (2 << DAC_CR_MAMP_SHIFT) /* Unmask bits[2:0] of LFSR/triangle amplitude=7 */
|
||||
# define DAC_CR_MAMP_AMP15 (3 << DAC_CR_MAMP_SHIFT) /* Unmask bits[3:0] of LFSR/triangle amplitude=15 */
|
||||
@ -291,6 +291,16 @@
|
||||
|
||||
#define DAC_MCR_MODE_SHIFT(n) (((n)-1) << 4)
|
||||
#define DAC_MCR_MODE_MASK(n) (0x7 << DAC_MCR_MODE_SHIFT(n))
|
||||
/* DAC channel in normal mode: */
|
||||
# define DAC_MCR_MODE_EXTBUF (0) /* DAC channel connected to external pin, Buffer enabled */
|
||||
# define DAC_MCR_MODE_EXTINBUF (1) /* DAC channel connected to external pin, on-chip peripherals, Buffer enabled */
|
||||
# define DAC_MCR_MODE_EXT (2) /* DAC channel connected to external pin, Buffer disabled */
|
||||
# define DAC_MCR_MODE_IN (3) /* DAC channel connected to on-chip peripherals, Buffer disabled */
|
||||
/* DAC channel in Sample and Hold mode: */
|
||||
# define DAC_MCR_MODE_SHEXTBUF (4) /* DAC channel connected to external pin, Buffer enabled */
|
||||
# define DAC_MCR_MODE_SHEXTINBUF (5) /* DAC channel connected to external pin, on-chip peripherals, Buffer enabled */
|
||||
# define DAC_MCR_MODE_SHEXTIN (6) /* DAC channel connected to external pin, on-chip peripherals, Buffer disabled */
|
||||
# define DAC_MCR_MODE_SHIN (7) /* DAC channel connected to on-chip peripherals, Buffer disabled */
|
||||
|
||||
#define DAC_MCR_MODE1_SHIFT (0) /* Bits 0-2: DAC channel 1 mode */
|
||||
#define DAC_MCR_MODE1_MASK (0x7 << DAC_MCR_MODE1_SHIFT)
|
||||
|
@ -1253,8 +1253,9 @@ static int adc_setup(FAR struct adc_dev_s *dev)
|
||||
ADC_CCR_TSEN | ADC_CCR_VBATEN;
|
||||
setbits = ADC_CCR_PRESC_NOT_DIV;
|
||||
|
||||
/* REVISIT: there is no way to select DAC1 or DAC2 output here on
|
||||
* STM32L4X3 devices where they are multiplexed with ADC1 TSEN and VBAT.
|
||||
/* On STM32L4X3 devices DAC1 and DAC2 outputs are multiplexed with ADC1 TS and VBAT.
|
||||
* adc_internal() knows about this and does not set TSEN or VBATEN bits if configuration
|
||||
* has requested DAC output to be connected to ADC.
|
||||
*/
|
||||
|
||||
adc_internal(priv, &setbits);
|
||||
@ -1434,11 +1435,14 @@ static bool adc_internal(FAR struct stm32_dev_s * priv, uint32_t *adc_ccr)
|
||||
break;
|
||||
|
||||
case 17:
|
||||
#if !(defined(CONFIG_STM32L4_STM32L4X3) && defined(CONFIG_STM32L4_DAC1_OUTPUT_ADC))
|
||||
*adc_ccr |= ADC_CCR_TSEN;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 18:
|
||||
#if !(defined(CONFIG_STM32L4_STM32L4X3) && defined(CONFIG_STM32L4_DAC2_OUTPUT_ADC))
|
||||
*adc_ccr |= ADC_CCR_VBATEN;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@
|
||||
# define DAC2_TSEL_VALUE DAC_CR_TSEL_SW
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE
|
||||
#if !defined(CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE) || CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE < 1
|
||||
# define CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE 256
|
||||
#endif
|
||||
|
||||
@ -315,6 +315,7 @@ struct stm32_chan_s
|
||||
uint32_t tbase; /* Timer base address */
|
||||
uint32_t tfrequency; /* Timer frequency */
|
||||
int result; /* DMA result */
|
||||
uint16_t dmapos; /* Position in dmabuffer where to write new value */
|
||||
uint16_t dmabuffer[CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE]; /* DMA transfer buffer */
|
||||
#endif
|
||||
};
|
||||
@ -488,6 +489,38 @@ static inline void stm32l4_dac_modify_cr(FAR struct stm32_chan_s *chan,
|
||||
modifyreg32(chan->cr, clearbits << shift, setbits << shift);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32l4_dac_modify_mcr
|
||||
*
|
||||
* Description:
|
||||
* Modify the contents of the DAC mode register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* chan - A reference to the DAC channel state data
|
||||
* clearbits - Bits in the control register to be cleared
|
||||
* setbits - Bits in the control register to be set
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32l4_dac_modify_mcr(FAR struct stm32_chan_s *chan,
|
||||
uint32_t clearbits, uint32_t setbits)
|
||||
{
|
||||
unsigned int shift;
|
||||
|
||||
/* DAC1 channels 1 and 2 share the STM32L4_DAC_MCR control register.
|
||||
* Bit 0 of the interface number provides the correct shift.
|
||||
*
|
||||
* Bit 0 = 0: Shift = 0
|
||||
* Bit 0 = 1: Shift = 16
|
||||
*/
|
||||
|
||||
shift = (chan->intf & 1) << 4;
|
||||
modifyreg32(STM32L4_DAC_MCR, clearbits << shift, setbits << shift);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tim_putreg
|
||||
*
|
||||
@ -710,6 +743,18 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
|
||||
#ifdef HAVE_DMA
|
||||
if (chan->hasdma)
|
||||
{
|
||||
/* Copy the value to circular buffer. Since dmabuffer is initialized to zero,
|
||||
* writing e.g. monotonously increasing values creates a continuosly repeating
|
||||
* ramp-effect, alternating with periods of zero output.
|
||||
*
|
||||
* In real use it would be better to initialize dmabuffer with desired pattern
|
||||
* beforehand. If want to write just one value at a time with DMA, set
|
||||
* CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE to 1.
|
||||
*/
|
||||
|
||||
chan->dmabuffer[chan->dmapos] = (uint16_t)msg->am_data;
|
||||
chan->dmapos = (chan->dmapos + 1) % CONFIG_STM32L4_DAC_DMA_BUFFER_SIZE;
|
||||
|
||||
/* Configure the DMA stream/channel.
|
||||
*
|
||||
* - Channel number
|
||||
@ -1001,7 +1046,28 @@ static int dac_chaninit(FAR struct stm32_chan_s *chan)
|
||||
DAC_CR_WAVE_DISABLED; /* Set no noise */
|
||||
stm32l4_dac_modify_cr(chan, clearbits, setbits);
|
||||
|
||||
/* TODO: Enable output buffer? */
|
||||
/* Enable output buffer or route DAC output to on-chip peripherals (ADC) */
|
||||
|
||||
clearbits = DAC_MCR_MODE1_MASK;
|
||||
#if defined(CONFIG_STM32L4_DAC1_OUTPUT_ADC)
|
||||
if (chan->intf == 0)
|
||||
{
|
||||
setbits = DAC_MCR_MODE_IN;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(CONFIG_STM32L4_DAC2_OUTPUT_ADC)
|
||||
if (chan->intf == 1)
|
||||
{
|
||||
setbits = DAC_MCR_MODE_IN;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
setbits = DAC_MCR_MODE_EXTBUF;
|
||||
}
|
||||
|
||||
stm32l4_dac_modify_mcr(chan, clearbits, setbits);
|
||||
|
||||
#ifdef HAVE_DMA
|
||||
/* Determine if DMA is supported by this channel */
|
||||
|
Loading…
Reference in New Issue
Block a user