35 #include "pios_config.h"
37 #if defined(PIOS_INCLUDE_DAC)
41 #include "stm32f4xx_tim.h"
54 #define DAC_DMA_SAMPLE_COUNT 120
56 typedef bool (*
fill_dma_cb)(
void *ctx, uint16_t *buf,
int len);
59 #define DAC_MAGIC 0x61434144
65 uint16_t dma_buf_0[DAC_DMA_SAMPLE_COUNT];
66 uint16_t dma_buf_1[DAC_DMA_SAMPLE_COUNT];
71 volatile bool in_progress;
73 volatile uint8_t priority;
90 *dev = (
struct dac_dev_s) {
95 TIM_DeInit(cfg->
timer);
96 TIM_Cmd(cfg->
timer, DISABLE);
98 TIM_TimeBaseInit(cfg->
timer,
99 (TIM_TimeBaseInitTypeDef *) &cfg->
clock_cfg);
103 TIM_ITConfig(cfg->
timer, TIM_IT_Update | TIM_IT_CC1 | TIM_IT_CC2 |
104 TIM_IT_CC3 | TIM_IT_CC4 | TIM_IT_COM | TIM_IT_Trigger |
105 TIM_IT_Break, DISABLE);
108 TIM_SelectOutputTrigger(cfg->
timer, TIM_TRGOSource_Update);
110 TIM_Cmd(cfg->
timer, ENABLE);
113 NVIC_Init((NVIC_InitTypeDef *)(&dev->cfg->interrupt));
126 if (dev->in_progress) {
127 bool ret_val =
false;
129 if (dev->priority < priority) {
134 dev->priority = priority;
145 dev->priority = priority;
148 for (
int i = 0;
i < DAC_DMA_SAMPLE_COUNT;
i++) {
149 dev->dma_buf_0[
i] = 32767;
150 dev->dma_buf_1[
i] = 32767;
156 dev->in_progress =
true;
166 GPIO_InitTypeDef gpio_cfg = {
167 .GPIO_Pin = dev->cfg->gpio_pin,
168 .GPIO_Mode = GPIO_Mode_AN,
169 .GPIO_PuPd = GPIO_PuPd_NOPULL,
172 GPIO_Init(dev->cfg->gpio, &gpio_cfg);
174 DAC_InitTypeDef dac_cfg = {
175 .DAC_Trigger = dev->cfg->dac_trigger,
176 .DAC_WaveGeneration = DAC_WaveGeneration_None,
177 .DAC_OutputBuffer = DAC_OutputBuffer_Enable,
180 DAC_Init(dev->cfg->dac_channel, &dac_cfg);
181 DAC_Cmd(dev->cfg->dac_channel, ENABLE);
182 DAC_DMACmd(dev->cfg->dac_channel, ENABLE);
184 dev->cur_buf =
false;
185 dev->in_progress =
true;
187 DMA_Cmd(dev->cfg->dma_stream, DISABLE);
189 DMA_DeInit(dev->cfg->dma_stream);
191 DMA_InitTypeDef dma_init;
193 DMA_StructInit(&dma_init);
195 dma_init.DMA_Channel = dev->cfg->dma_channel;
196 dma_init.DMA_PeripheralBaseAddr = (uintptr_t) dev->cfg->dac_outreg;
197 dma_init.DMA_Memory0BaseAddr = (uintptr_t) dev->dma_buf_0;
198 dma_init.DMA_DIR = DMA_DIR_MemoryToPeripheral;
199 dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
200 dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
201 dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
202 dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
204 dma_init.DMA_BufferSize = DAC_DMA_SAMPLE_COUNT;
205 dma_init.DMA_Mode = DMA_Mode_Circular;
206 dma_init.DMA_Priority = DMA_Priority_High;
207 dma_init.DMA_FIFOMode = DMA_FIFOMode_Enable;
208 dma_init.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
209 dma_init.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
210 dma_init.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
215 DMA_Init(dev->cfg->dma_stream, &dma_init);
217 DMA_DoubleBufferModeConfig(dev->cfg->dma_stream,
218 (uintptr_t) dev->dma_buf_1,
221 DMA_DoubleBufferModeCmd(dev->cfg->dma_stream, ENABLE);
223 DMA_ClearITPendingBit(dev->cfg->dma_stream,
226 DMA_ITConfig(dev->cfg->dma_stream,
229 DMA_Cmd(dev->cfg->dma_stream, ENABLE);
236 DMA_ClearITPendingBit(dev->cfg->dma_stream, dev->cfg->dma_tcif);
237 dev->cur_buf = DMA_GetCurrentMemoryTarget(dev->cfg->dma_stream);
239 uint16_t *buf = dev->cur_buf ? dev->dma_buf_0 : dev->dma_buf_1;
243 in_prog = dev->dma_cb((
void *)dev->ctx, buf, DAC_DMA_SAMPLE_COUNT);
248 DMA_Cmd(dev->cfg->dma_stream, DISABLE);
249 dev->in_progress =
false;
Types that are specific to the STM32 peripherals.
int32_t PIOS_IRQ_Enable(void)
Main PiOS header to include all the compiled in PiOS options.
bool PIOS_DAC_install_callback(dac_dev_t dev, uint8_t priority, fill_dma_cb cb, void *ctx)
#define PIOS_IRQ_Epilogue()
void * PIOS_malloc(size_t size)
static struct flyingpicmd_cfg_fa cfg
int PIOS_DAC_init(dac_dev_t *dev_out, const struct pios_dac_cfg *cfg)
Allocate and initialise DAC device.
int32_t PIOS_IRQ_Disable(void)
bool(* fill_dma_cb)(void *ctx, uint16_t *buf, int len)
struct dac_dev_s * dac_dev_t
#define PIOS_IRQ_Prologue()
#define PIOS_Assert(test)
TIM_TimeBaseInitTypeDef clock_cfg
void PIOS_DAC_dma_interrupt_handler(dac_dev_t dev)
Handles a DMA completion interrupt on dma_stream.