optimize DAC using calling registers instead of analogWriteDAC0
Take what's needed from framework's analogWriteDAC0 A sine wave of 1MHz can now be generate without any problemmain
parent
e10b4869d8
commit
f9f2cbe89b
|
@ -1,11 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#define LUT_SIZE 4096
|
||||
//DAC sampling time(1428571,428571429), found on the Datasheet
|
||||
#define SAMPLE_FREQ 1428571
|
||||
#define LUT_SIZE 512
|
||||
|
||||
// Sampling frequency of the DAC
|
||||
// Since the teensy runs on 168MHz and Fastest + LTO, using the DAC sampling frequency (1428571Hz) from the Datasheet kinda falls apart
|
||||
#define SAMPLE_FREQ 5316436
|
||||
|
||||
//Max Freq with good results achievable with Teensy 3.5 DAC
|
||||
#define MAX_ACHIEVABLE_FREQ 300000
|
||||
#define MAX_ACHIEVABLE_FREQ 1000000
|
||||
|
||||
void generateSine(float);
|
||||
void setupSine();
|
|
@ -8,8 +8,8 @@
|
|||
#define extr extern
|
||||
#endif
|
||||
|
||||
#define MAX_VALUE 4096
|
||||
#define MAX_VALUE_HALF 2048
|
||||
#define MAX_VALUE 1024
|
||||
#define MAX_VALUE_HALF 512
|
||||
|
||||
//How much time (nanoseconds) is required for an analogWriteDAC0() call
|
||||
#define ANALOG_WRITE_TIME_NS 477
|
||||
|
|
|
@ -10,5 +10,5 @@ void setup() {
|
|||
}
|
||||
|
||||
FASTRUN void loop() {
|
||||
generateSine(1000);
|
||||
generateSine(1000000);
|
||||
}
|
|
@ -24,54 +24,30 @@ void calculateSineLookup(){
|
|||
}
|
||||
}
|
||||
|
||||
/*Generate sine wave at the given frequency
|
||||
Use the classical DDS Phase Accumulator technique
|
||||
On some lower frequency the maths for the phase accumulator doesn't work (delta_phi becomes too close to zero to be noticed)
|
||||
and a simpler approach waiting microseconds can be used*/
|
||||
|
||||
//Write the DAC with using some parts of framework's Arduino.h, for higher speeds
|
||||
// Use FASTRUN to run code in RAM
|
||||
typedef int16_t __attribute__((__may_alias__)) aliased_int16_t;
|
||||
|
||||
FASTRUN void generateSine(float frequency){
|
||||
startGenerating();
|
||||
|
||||
if (frequency <= 500){
|
||||
// Phase accumulator
|
||||
float phase = 0;
|
||||
|
||||
// Period of the wave in microseconds
|
||||
unsigned long periodMS = 1/frequency * pow (10, 6);
|
||||
//Constrain frequency
|
||||
frequency = constrain(frequency, 0, MAX_ACHIEVABLE_FREQ);
|
||||
|
||||
//Time to pass between outputting each sample
|
||||
unsigned long sampleTime = (unsigned long) ((float)periodMS / LUT_SIZE + ANALOG_WRITE_TIME_MS);
|
||||
|
||||
int i = 0;
|
||||
while(generateWave){
|
||||
//Write the voltage on the DAC. i gets incremented after the call to the function is done
|
||||
analogWriteDAC0(LUT[i++]);
|
||||
|
||||
// handle wraparound
|
||||
if(i >= LUT_SIZE) i -= LUT_SIZE;
|
||||
|
||||
// Wait the needed time
|
||||
delayMicroseconds(sampleTime);
|
||||
}
|
||||
|
||||
}else{
|
||||
// Phase accumulator
|
||||
float phase = 0;
|
||||
|
||||
//Constrain frequency
|
||||
frequency = constrain(frequency, 0, MAX_ACHIEVABLE_FREQ);
|
||||
|
||||
// Phase increment at each step
|
||||
float delta_phi = (int) (frequency / SAMPLE_FREQ * LUT_SIZE);
|
||||
|
||||
while(generateWave){
|
||||
// increment phase
|
||||
phase += delta_phi;
|
||||
|
||||
// handle wraparound
|
||||
if (phase >= (float)LUT_SIZE) phase -= (float)LUT_SIZE;
|
||||
|
||||
//Write the voltage on the DAC
|
||||
analogWriteDAC0(LUT[(int)phase]);
|
||||
}
|
||||
// Phase increment at each step
|
||||
float delta_phi = frequency / SAMPLE_FREQ * LUT_SIZE;
|
||||
|
||||
while(generateWave){
|
||||
// increment phase
|
||||
phase += delta_phi;
|
||||
|
||||
// handle wraparound
|
||||
if (phase >= LUT_SIZE) phase -= LUT_SIZE;
|
||||
|
||||
//Write the voltage on the DAC
|
||||
*(volatile aliased_int16_t *)&(DAC0_DAT0L) = LUT[(int)phase];
|
||||
}
|
||||
}
|
|
@ -10,6 +10,10 @@ void setupWaves(){
|
|||
|
||||
//Set DACs resolution to 12 bits
|
||||
analogWriteResolution(12);
|
||||
|
||||
// Enable DAC0, from framework's analogWriteDAC0, place here from higher speeds
|
||||
SIM_SCGC2 |= SIM_SCGC2_DAC0;
|
||||
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS;
|
||||
}
|
||||
|
||||
// Wait time by counting clock cycles
|
||||
|
|
Loading…
Reference in New Issue