diff options
Diffstat (limited to 'libmaple/dac.c')
-rw-r--r-- | libmaple/dac.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/libmaple/dac.c b/libmaple/dac.c index 63a96ac..1726d19 100644 --- a/libmaple/dac.c +++ b/libmaple/dac.c @@ -23,43 +23,96 @@ *****************************************************************************/ #include "libmaple.h" -#include "rcc.h" #include "gpio.h" #include "dac.h" +#ifdef STM32_HIGH_DENSITY + /** * @brief DAC peripheral routines. */ -/* This numbering follows the registers (1-indexed) */ -#define DAC_CH1 1 -#define DAC_CH2 2 - -DAC_Map *dac = (DAC_Map*)(DAC_BASE); +dac_dev dac = { + .regs = DAC_BASE, +}; +const dac_dev *DAC = &dac; -/* Sets up the DAC peripheral */ -void dac_init(void) { +/** + * @brief Initialize the digital to analog converter + * @param dev DAC device + * @param flags Flags: + * DAC_CH1: Enable channel 1 + * DAC_CH2: Enable channel 2 + * @sideeffect May set PA4 or PA5 to INPUT_ANALOG + */ +void dac_init(const dac_dev *dev, uint32 flags) { /* First turn on the clock */ rcc_clk_enable(RCC_DAC); + rcc_reset_dev(RCC_DAC); - /* Then setup ANALOG mode on PA4 and PA5 */ - gpio_set_mode(GPIOA_BASE, 4, CNF_INPUT_ANALOG); - gpio_set_mode(GPIOA_BASE, 5, CNF_INPUT_ANALOG); + if (flags & DAC_CH1) { + dac_enable_channel(dev, 1); + } - /* Then do register stuff. Default does no triggering, and - * buffered output, so all good. */ - dac->CR = DAC_CR_EN1 | DAC_CR_EN2; + if (flags & DAC_CH2) { + dac_enable_channel(dev, 2); + } } -void dac_write(uint8 chan, uint16 val) { - switch(chan) { - case DAC_CH1: - dac->DHR12R1 = 0x0FFF & val; +/** + * @brief Write a 12-bit value to the DAC to output + * @param dev DAC device + * @param channel channel to select (1 or 2) + * @param val value to write + */ +void dac_write_channel(const dac_dev *dev, uint8 channel, uint16 val) { + switch(channel) { + case 1: + dev->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val; break; - case DAC_CH2: - dac->DHR12R2 = 0x0FFF & val; + case 2: + dev->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val; break; - default: - ASSERT(0); // can't happen } } + +/** + * @brief Enable a DAC channel + * @param dev DAC device + * @param channel channel to enable, either 1 or 2 + * @sideeffect May change pin mode of PA4 or PA5 + */ +void dac_enable_channel(const dac_dev *dev, uint8 channel) { + /* + * Setup ANALOG mode on PA4 and PA5. This mapping is consistent across + * all STM32 chips with a DAC. See RM0008 12.2. + */ + switch (channel) { + case 1: + gpio_set_mode(GPIOA, 4, GPIO_INPUT_ANALOG); + dev->regs->CR |= DAC_CR_EN1; + break; + case 2: + gpio_set_mode(GPIOA, 5, GPIO_INPUT_ANALOG); + dev->regs->CR |= DAC_CR_EN2; + break; + } +} + +/** + * @brief Disable a DAC channel + * @param dev DAC device + * @param channel channel to disable, either 1 or 2 + */ +void dac_disable_channel(const dac_dev *dev, uint8 channel) { + switch (channel) { + case 1: + dev->regs->CR &= ~DAC_CR_EN1; + break; + case 2: + dev->regs->CR &= ~DAC_CR_EN2; + break; + } +} + +#endif /* STM32_HIGH_DENSITY */ |