-
-
Save samyk/6273cf9a45d63a50c38c8b50a39a8f52 to your computer and use it in GitHub Desktop.
// Generating a 134kHz sine wave using Teensy 3.6 with virtually | |
// 0 cpu usage by filling the DAC up via DMA triggered by PDB | |
// -samy kamkar | |
#include <DMAChannel.h> | |
#include "pdb.h" | |
DMAChannel dma(false); | |
static volatile uint16_t sinetable[] = { | |
2048,2277,2503,2724,2936,3137,3324,3495,3648,3781,3892,3980,4044,4082,4095,4082,4044,3980,3892,3781,3648,3495,3324,3137,2936,2724,2503,2277,2048,1818,1592,1371,1159,958,771,600,447,314,203,115,51,13,0,13,51,115,203,314,447,600,771,958,1159,1371,1592,1818 | |
}; | |
void setup() | |
{ | |
dma.begin(true); // allocate the DMA channel first | |
SIM_SCGC2 |= SIM_SCGC2_DAC0; // enable DAC clock | |
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // enable the DAC module, 3.3V reference | |
// slowly ramp up to DC voltage, approx 1/4 second | |
for (int16_t i=0; i<2048; i+=8) | |
{ | |
*(volatile int16_t *)&(DAC0_DAT0L) = i; | |
delay(1); | |
} | |
// set the programmable delay block to trigger DMA requests | |
SIM_SCGC6 |= SIM_SCGC6_PDB; // enable PDB clock | |
PDB0_IDLY = 0; // interrupt delay register | |
PDB0_MOD = 0; //PDB_PERIOD; // modulus register, sets period | |
PDB0_SC = PDB_CONFIG | PDB_SC_LDOK; // load registers from buffers | |
PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG; // reset and restart | |
PDB0_CH0C1 = 0x0101; // channel n control register? | |
dma.sourceBuffer(sinetable, sizeof(sinetable)); | |
dma.destination(*(volatile uint16_t *)&(DAC0_DAT0L)); | |
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_PDB); | |
dma.enable(); | |
} | |
void loop() { | |
} |
Great! Many thanksssss
🎉 (I would've applied that to your response but just learned gist
comments don't allow emojis applied, only github
issue comments do!)
Hi Samky,
I'm progress in my project (thanks to you) and I come back to you to say that your software works well on a Teensy3.2. The max frequency is around 60 kHz at 72Mhz's cpu frequency.
Well, I don't have the ratio "CPU Freq / Output Freq" but I've the desired frequency 15 kHz (14.998 Hz) by setting the register PDB0_MOD equals to 0x2A. To avoid crenels, I've added a capacitor to smooth the output signal.
I don't tried yet to involve additional code (like an OLED display or other) but I hope that the frequency will be stable.
Any way: THANKS 💯
Nice! I'm surprised you're saying the max freq is 15kHz? I know I was able to generate either 125kHz or 134kHz on a Teensy 3.1 and 3.2 as well (those were specific frequencies I wanted, not maximums). I'm sure I adjusted the sinetable and perhaps something else.
I also was doing it in the main loop with a separate test, but I'm guessing you want to keep your main loop unoccupied.
The frequency I was looking for was 15kHz so I've updated the register. It is not the max frequency that we can see on the scope before setting PDB0_MOD register.
However, if a better method exist, it welcome.
I will use 2 interrupts to calculate the phase difference between reference frequency (fixed at 15kHz) and a 2nd incoming signal.
The loop will populated with some functions like a OLED display and capacitive touch.
Hi Samky, I've tried you code on a Teensy but it can not be compiled because "pdb.h" is not provided. Can you add this file ?
Many thanks.