Last active
September 8, 2020 19:17
-
-
Save samyk/6273cf9a45d63a50c38c8b50a39a8f52 to your computer and use it in GitHub Desktop.
134kHz sine wave w/DMA, DAC and PDB on Teensy 3.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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() { | |
} |
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.