// Port-Write DDS Experiments, Teensy 4.0, 600MHz clock
// G. Kovacs, 8/12/19
// Calculate a 8-bit (uint16_t, straight binary) sinewave look-up-table
// LS bit = D0, MS-bit = D7.
#define arraySize 256 //Must be an even power of two, and usually the same number of points as the number of DAC steps, here 256.
int numbitsLUT = int(log(arraySize)/log(2)); //Compute number of bits needed to address DDS LUT, and later, from this, how many to shift the DDS accumulator to address LUT.
const uint16_t DDSshift = 32 - numbitsLUT; //use const for speed
uint8_t waveform[arraySize];
uint16_t synthTemp;
int pinPoint;
uint8_t pointOut;
uint16_t pointer = 0;
uint32_t sum = 0; //This is the DDS "accumulator" that rolls over at a frequency determined by "pointerIncrement," thus defining the output frequency.
float freqOut = 100.000E3; //Desired output frequency
const float measuredSampleRate = 10.1E6; //Effective sample rate, determined by trial and error for a given code version.
uint32_t pointerIncrement = 0;
void setup() {
for (int i = 0; i < 8; i++) {pinMode(i, OUTPUT);}
pointerIncrement = int((freqOut/measuredSampleRate)*pow(2,32)+0.5);
for (uint16_t i=0; i<arraySize; i++)
{
// Data is scaled to 0..255, unsigned, 8-bit binary for DAC.
// This floating point mapping gives a verified good sine LUT.
synthTemp = (32767.5+(32767.5*sin(2*3.141592654*(float(i)/(arraySize-1))))); //Here use a sinewave, but could be anything desired.
waveform[i] = synthTemp>>8; // shift data here for 8-bit external DAC. Adjust as necessary.
}
//See: https://forum.pjrc.com/threads/27690-IntervalTimer-is-not-precise
//Technique to reduce intervalTimer jitter.
SCB_SHPR3 = 0x20200000; // Systick = priority 32 (defaults to zero, or highest priority)
}
void yield () {} //Get rid of the hidden function that checks for serial input and such.
FASTRUN void loop()
// Use FASTRUN to force code to run in RAM.
{
noInterrupts();
while (1) //Loop inside void loop () avoids the overhead of the main loop.
{
pointer = sum >> DDSshift; //Shift to fit range waveform look-up table. Change as needed.
pointOut = waveform[pointer];
digitalWriteFast(7, (0x80 & pointOut)); //MSbit
digitalWriteFast(6, (0x40 & pointOut));
digitalWriteFast(5, (0x20 & pointOut));
digitalWriteFast(4, (0x10 & pointOut));
digitalWriteFast(3, (0x08 & pointOut));
digitalWriteFast(2, (0x04 & pointOut));
digitalWriteFast(1, (0x02 & pointOut));
digitalWriteFast(0, (0x01 & pointOut)); //LSbit
// Value added to "sum" determines the output frequency. Larger values added translate to lower frequencies. That's DDS!
// sum = sum + 0x80000000; //For sine LUT, should be Nyquist rate, or 1/2 of effective sample rate, on the MSBit, pin 29. (mayb 0x7FFFFFFF?).
sum = sum + pointerIncrement; //For sine LUT, should be Nyquist rate, or 1/2 of effective sample rate, on the MSBit, pin 29.
}
}