38 lines
1.9 KiB
C
38 lines
1.9 KiB
C
#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;
|
|
}
|