Files
templates/c/set-protocol/ports/stm32g474-wavegen/set_wave_g474.c

44 lines
2.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* HAL-порт генератора STM32G474: DAC1, TIM6 и циклический DMA с 16-битными элементами.
* Проверяются конфигурация DMA и точная достижимость частоты, ограниченной 50 кГц; остановка
* выводит нулевой уровень без ожидания следующего триггера.
*/
#include "set_wave_g474.h"
static void stop(void *context) {
set_wave_g474 *c=(set_wave_g474 *)context;
HAL_TIM_Base_Stop(c->timer);
HAL_DAC_Stop_DMA(c->dac,DAC_CHANNEL_1);
/* Disable triggering so zero is applied without another timer edge. */
CLEAR_BIT(c->dac->Instance->CR,DAC_CR_TEN1);
HAL_DAC_SetValue(c->dac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0);
HAL_DAC_Start(c->dac,DAC_CHANNEL_1);
}
static int start(void *context,const uint16_t *samples,size_t count,uint32_t rate) {
set_wave_g474 *c=(set_wave_g474 *)context;
uint32_t ticks,psc; DMA_HandleTypeDef *dma;
if(!c||!c->dac||!c->timer||c->dac->Instance!=DAC1||c->timer->Instance!=TIM6
||!rate||rate>50000||count<2||count>SET_WAVE_MAX||c->timer_hz%rate) return 1;
dma=c->dac->DMA_Handle1;
if(!dma||dma->Init.Mode!=DMA_CIRCULAR||dma->Init.MemDataAlignment!=DMA_MDATAALIGN_HALFWORD
||dma->Init.PeriphDataAlignment!=DMA_PDATAALIGN_HALFWORD
||dma->Init.Request!=DMA_REQUEST_DAC1_CHANNEL1||dma->Init.MemInc!=DMA_MINC_ENABLE) return 1;
ticks=c->timer_hz/rate;
for(psc=1;psc<=65536;++psc) if(ticks%psc==0&&ticks/psc<=65536) break;
if(psc>65536||ticks<psc) return 1;
stop(context);
__HAL_TIM_SET_PRESCALER(c->timer,psc-1);
__HAL_TIM_SET_AUTORELOAD(c->timer,ticks/psc-1);
__HAL_TIM_SET_COUNTER(c->timer,0);
c->timer->Instance->EGR=TIM_EGR_UG;
__HAL_TIM_CLEAR_FLAG(c->timer,TIM_FLAG_UPDATE);
MODIFY_REG(c->dac->Instance->CR,DAC_CR_TSEL1|DAC_CR_TEN1,DAC_TRIGGER_T6_TRGO);
HAL_DAC_SetValue(c->dac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,samples[count-1]);
if(HAL_DAC_Start_DMA(c->dac,DAC_CHANNEL_1,(uint32_t *)samples,(uint32_t)count,DAC_ALIGN_12B_R)!=HAL_OK) return 1;
if(HAL_TIM_Base_Start(c->timer)!=HAL_OK) {stop(context);return 1;}
return 0;
}
set_wave_port set_wave_g474_port(set_wave_g474 *context) {
set_wave_port port={context,start,stop};return port;
}