Sine wave generator

What are you developing?
ted
Posts: 62
Joined: Sun Jul 16, 2017 9:57 pm

Re: Sine wave generator

Post by ted » Tue Jan 30, 2018 5:03 pm

here is it

Code: Select all

#define F_TIMER   72000000
#define FREQ    10000  //in Hz
#define SAMPLES ((int)sqrt(F_TIMER / FREQ))
#define T_CNT   ((F_TIMER/FREQ)/SAMPLES)

#define sin_zero     (T_CNT/2)
#define amp0         (sin_zero/2)
#define max_amp      (sin_zero-1)

/*
#define DEBOUNCE_DELAY 100

#define DEBOUNCE_IDLE 0
#define DEBOUNCE_ACTIVE 1
*/
#include <libmaple/dma.h>

dma_tube_config dma_cfg, dma_cfg2;

int flag1 = 0;
int flag2 = 0;

int out1 = PB7;
int out2 = PA8;
int out3 = PA9;

int * val1 = new int[SAMPLES];
int * val2 = new int[SAMPLES];

int phasep = PB6;
int phasen = PB5;
int ampp = PB8;
int ampn = PB9;

int16 shift = 0;

int amp = amp0;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;

timer_dev *dev1 = PIN_MAP[out1].timer_device;
timer_dev *dev2 = PIN_MAP[out2].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;
uint8 cc_channel2 = PIN_MAP[out2].timer_channel;

void fun()
{
  static uint8_t ff = 0;
  flag1++;

}

void fun2()
{
  static uint8_t ff = 0;
  flag2++;
  digitalWrite(out3, ff = (1 - ff));

}

void timer_conf()
{

  timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
  timer_dma_set_burst_len(dev1, 1);
  timer_dma_enable_req(dev1, cc_channel1);
  timer_set_reload(dev1, T_CNT);
  timer_set_prescaler(dev1, 0);

  timer_dma_set_base_addr(dev2, TIMER_DMA_BASE_CCR1);
  timer_dma_set_burst_len(dev2, 1);
  timer_dma_enable_req(dev2, cc_channel2);
  timer_set_reload(dev2, T_CNT);
  timer_set_prescaler(dev2, 0);
}

void dma_conf()
{
  dma_init(DMA1);
  /* T4C2 DMA C4 */
  dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
  dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
  dma_cfg.tube_src = val1;
  dma_cfg.tube_src_size = DMA_SIZE_32BITS;

  dma_cfg.tube_nr_xfers = SAMPLES;
  dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;

  dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
  dma_cfg.target_data = 0;

  ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);

  /* T1C1 DMA C2 */
  dma_cfg.tube_dst = &(dev2->regs.gen->DMAR);
  dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
  dma_cfg.tube_src = val2;
  dma_cfg.tube_src_size = DMA_SIZE_32BITS;

  dma_cfg.tube_nr_xfers = SAMPLES;
  dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_HALF_CMPLT_IE | DMA_CFG_CMPLT_IE;

  dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH1;
  dma_cfg.target_data = 0;

  ret = dma_tube_cfg(DMA1, DMA_CH2, &dma_cfg);
}

void dma_start()
{
//  dma_attach_interrupt(DMA1, DMA_CH4, fun);
  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);
  
  dma_attach_interrupt(DMA1, DMA_CH2, fun2);
  dma_enable(DMA1, DMA_CH2);
  timer_resume(dev2);
}

void init_wave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  {
    val1[i] = sin_zero + amp * sin(stp * i);
    val2[i] = val1[i];
  }
}

void setup() {
  int i;
  pinMode(out1, PWM);
  pinMode(out2, PWM);
  pinMode(out3, OUTPUT);

  Serial.begin(9600);

  timer_conf();
  dma_conf();
  dma_start();
  init_wave();

}

void loop() {

}


Last edited by ted on Tue Jan 30, 2018 8:48 pm, edited 1 time in total.

User avatar
ahull
Posts: 1730
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Sine wave generator

Post by ahull » Tue Jan 30, 2018 8:37 pm

That looks pretty useful, what are the limitations (max frequency, sample size, etc.) and how does it work?
- Andy Hull -

ted
Posts: 62
Joined: Sun Jul 16, 2017 9:57 pm

Re: Sine wave generator

Post by ted » Tue Jan 30, 2018 8:54 pm

I was using it for 15 kHz, you change the frequency very easy - line # 2, for frequency above 2 or 3 kHz single LC filter works excellent

Post Reply