DMA problem solved

What are you developing?
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: DMA problem solved

Post by mlundin »

Still overcomplicated, no val arrays or sin and cosines are needed

Code: Select all

for (i = 0; i < SAMPLES; i++) 
  {
    if ( i  < SAMPLES/2)
    {
      digitalWrite(PB8, HIGH);
    }
    else
    {
      digitalWrite(PB8, LOW);
    }
    int j = i+PHASE;
    /* adjust j by a SAMPLES period to be between 0 and SAMPLES-1 */
    if (j>=SAMPLES) j-=SAMPLES;
    if ( j  < SAMPLES/2)
    {
      digitalWrite(PB6, HIGH);
    }
    else
    {
      digitalWrite(PB6, LOW);
    }
  }
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

Re: DMA problem solved

Post by stan »

adjust j by a SAMPLES period = not clear.
# of SAMPLES are determining frequency of signal = period of signal. With cos there is no need for an adjustment.
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

DMA Synchronization problem

Post by stan »

Those two squares are not synchronized with sin on PB7, I was trying to take them out from the loop but I do not succeeded.

Code: Select all

#define SAMPLES 77
#include <libmaple/dma.h>
dma_tube_config dma_cfg, dma_cfg2;
int flag = 0;
int flag1 = 0;
int out = PB6;
int out2 = PB8;
int out1 = PB7;

int val[SAMPLES];
int val1[SAMPLES];

int16 shift = 0;

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

timer_dev *dev = PIN_MAP[out].timer_device;
uint8 cc_channel = PIN_MAP[out].timer_channel;
timer_dev *dev1 = PIN_MAP[out1].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;

void fun()
{
  flag++;
}
void fun1()
{
  flag1++;
}

void timer_conf()
{

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

  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, 102);
  timer_set_prescaler(dev1, 0);
}

void dma_conf()
{
  dma_init(DMA1);
  /* T4C2 DMA C4 */
  dma_cfg.tube_dst = &(dev->regs.gen->DMAR);
  dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
  dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
  dma_cfg.tube_src = val;
  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_CH1;
  dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
  dma_cfg.target_data = 0;

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

void dma_start()
{
  dma_attach_interrupt(DMA1, DMA_CH4, fun);
  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);
  dma_enable(DMA1, DMA_CH1);
  dma_enable(DMA1, DMA_CH2);

}

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

void setup()
{
  int i;
  pinMode(out1, PWM);
  pinMode(out, OUTPUT);
  pinMode(out2, OUTPUT);
  timer_conf();
  dma_conf();
  dma_start();
  init_wave();
}

void loop()

{
  int i;
for (i = 0; i < SAMPLES; i++)
  {
    //if ( val1[i]  > 40)
    if ( val[i]  < 40)
    {
      digitalWrite(PB8, HIGH);
    }
    else
    {
      digitalWrite(PB8, LOW);
    }
    if ( val1[i]  > 40)
      //if ( val1[i]  > 38)
    {
      digitalWrite(PB6, HIGH);
    }
    else
    {
      digitalWrite(PB6, LOW);
    }
  }

}
Last edited by stan on Sun Nov 22, 2020 12:09 pm, edited 1 time in total.
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

Re: DMA Synchronization problem

Post by stan »

I created - void init_LEDwave() - but it is not working

Code: Select all

void init_wave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  {
    val[i] = 40 + amp * sin(stp * i);
    val1[i] = 40 + amp * cos(stp * i);
 }
}
//311
/////////////////////
void init_LEDwave()
{
  int i;
  if ( val[i]  < 40)
    {
      digitalWrite(PB8, HIGH);
    }
    else
    {
      digitalWrite(PB8, LOW);
    }
    if ( val1[i]  > 40)
      //if ( val1[i]  > 38)
    {
      digitalWrite(PB6, HIGH);
    }
    else
    {
      digitalWrite(PB6, LOW);
    }
}
////////////////////
void setup()
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: DMA Synchronization problem

Post by stevestrong »

It probably works as it is coded.
The question is: what do you want the function to do?
I assume the variable "i" should somehow increment...
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

Re: DMA Synchronization problem

Post by stan »

This is the code with 3 outputs; PB7 = sine wave, PB6 and PB8 = square wave, sine wave is not synchronized with square waves when PB6,PB8 are in - void loop(), so I want to take them from the loop and put them outside of it.

Code: Select all

#define SAMPLES 77
#include <libmaple/dma.h>
dma_tube_config dma_cfg, dma_cfg2;
int flag = 0;
int flag1 = 0;
int out = PB6;
int out2 = PB8;
int out1 = PB7;

int val[SAMPLES];
int val1[SAMPLES];

int16 shift = 0;

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

timer_dev *dev = PIN_MAP[out].timer_device;
uint8 cc_channel = PIN_MAP[out].timer_channel;
timer_dev *dev1 = PIN_MAP[out1].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;

void fun()
{
  flag++;
}
void fun1()
{
  flag1++;
}

void timer_conf()
{

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

  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, 102);
  timer_set_prescaler(dev1, 0);
}

void dma_conf()
{
  dma_init(DMA1);
  /* T4C2 DMA C4 */
  dma_cfg.tube_dst = &(dev->regs.gen->DMAR);
  dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
  dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
  dma_cfg.tube_src = val;
  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_CH1;
  dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
  dma_cfg.target_data = 0;

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

void dma_start()
{
  dma_attach_interrupt(DMA1, DMA_CH4, fun);
  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);
  dma_enable(DMA1, DMA_CH1);
  dma_enable(DMA1, DMA_CH2);

}

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

/////////////////////
void init_LEDwave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  if ( val[i]  < 40)
    {
      digitalWrite(PB8, HIGH);
    }
    else
    {
      digitalWrite(PB8, LOW);
    }
    if ( val1[i]  > 40)
      //if ( val1[i]  > 38)
    {
      digitalWrite(PB6, HIGH);
    }
    else
    {
      digitalWrite(PB6, LOW);
    }
}
////////////////////
void setup()
{
  int i;
  pinMode(out1, PWM);
  pinMode(out, OUTPUT);
  pinMode(out2, OUTPUT);
  timer_conf();
  dma_conf();
  dma_start();
  init_wave();
}

void loop()

{
  int i;
  /*
for (i = 0; i < SAMPLES; i++)
  {
    //if ( val1[i]  > 40)
    if ( val[i]  < 40)
    {
      digitalWrite(PB8, HIGH);
    }
    else
    {
      digitalWrite(PB8, LOW);
    }
    if ( val1[i]  > 40)
      //if ( val1[i]  > 38)
    {
      digitalWrite(PB6, HIGH);
    }
    else
    {
      digitalWrite(PB6, LOW);
    }
  }
*/
}
nothing on PB6,PB8
stan
Posts: 70
Joined: Wed Nov 11, 2020 7:40 pm

Re: DMA Synchronization problem

Post by stan »

I put PB6,PB8 inside - void init_wave() - I got only sine

Code: Select all

void init_wave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  {
    val[i] = 40 + amp * sin(stp * i);
    val1[i] = 40 + amp * cos(stp * i);
      if ( val[i]  < 40)
    {
      digitalWrite(PB8, HIGH);
    }
    else
    {
      digitalWrite(PB8, LOW);
    }
    if ( val1[i]  > 40)
      //if ( val1[i]  > 38)
    {
      digitalWrite(PB6, HIGH);
    }
    else
    {
      digitalWrite(PB6, LOW);
    }
 }
}
Post Reply

Return to “Projects”