Periodically interrupting PWM signal using DMA

Status
Not open for further replies.

emiel.h

Member
Hi,

I've been trying to create a high frequency PWM signal which is periodically interrupted by a lower frequency PWM signal.
By studying the OctoWS2811 library and the MK20DX256 Manual I've created the code below.

I'm using two timers; FTM1, which creates the to be modulated signal and FTM2, which creates the modulating signal.
FTM2 ch0 and ch1 trigger DMA channels dma1 and dma2; dma1 turns FTM1 ch0 on and dma2 turns it off again.
This is done by making the DMA channels write to the appropriate timer channel's Status And Control register and enabling or disabling the appropriate fields.
This is, as far as my limited understanding goes, how it works, please correct me if I'm wrong.

I would like to get some feedback about whether this is the correct way to do it as I've noticed that the output (pin 3) is not actually being pulled low during the "breaks".
I've tried to make dma1 and dma2 write to CORE_PIN3_CONFIG and change the pin's mux setting but it seemed like the DMA channel didn't have any influence on it; is there a difference between registers the DMA controller can and can't write to?
Lastly could somebody explain to me what dma1.transferSize() & dma1.transferCount() do?

Thanks in advance!


For Teensy 3.2:
Code:
#include "DMAChannel.h"
static DMAChannel dma1, dma2;

static uint32_t on = 0x28;
static uint32_t off = 0;

void setup() {
  FTM1_SC = 0;
  FTM1_CNT = 0;
  FTM1_MOD = 100;
  FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
  FTM1_C0SC = on;
  FTM1_C0V = 50;
  // pin 3 is FTM1_CH0
  CORE_PIN3_CONFIG = PORT_PCR_MUX(3);

  FTM2_SC = 0;
  FTM2_CNT = 0;
  FTM2_MOD = 65000;
  FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(7);
  FTM2_C0SC = 0x69;
  FTM2_C1SC = 0x69;
  FTM2_C0V = 1;
  FTM2_C1V = 30000;

  dma1.source(on);
  dma1.destination(FTM1_C0SC);
  dma1.transferSize(1);
  dma1.transferCount(1);

  dma2.source(off);
  dma2.destination(FTM1_C0SC);
  dma2.transferSize(1);
  dma2.transferCount(1);

  dma1.triggerAtHardwareEvent(DMAMUX_SOURCE_FTM2_CH0);
  dma2.triggerAtHardwareEvent(DMAMUX_SOURCE_FTM2_CH1);

  dma1.enable();
  dma2.enable();
}

void loop() {
  Serial.println("running");
  delay(500);
}
 
Last edited:
Status
Not open for further replies.
Back
Top