Hi Grumpy_Mike, I tried to develop the system but I have a bottleneck due to the low frequency of the i2c communication. So I would like to implement the pwm sine wave generator. I developed this code till now, can you help me to modify it in order to use the PWM instead of the DAC?
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_MCP4725.h>
#include <Adafruit_MMA8451.h>
// Output 25kHz single slope PWM with timer TCC0 on D7
volatile int flag = 0;
int ind = -1;
Adafruit_MCP4725 dac;
#define DAC_RESOLUTION (10)
volatile int sintable[256] PROGMEM = {
512,524,537,549,562,574,587,599,611,624,636,648,660,672,684,696,707,719,730,741,753,764,774,785,796,806,816,826,836,846,855,864,873,882,890,899,907,915,922,930,
937,944,950,957,963,968,974,979,984,989,993,997,1001,1004,1008,1011,1013,1015,1017,1019,1021,1022,1022,1023,1023,1023,1022,1022,1021,1019,1017,1015,1013,1011,1008,1004,1001,997,993,989,
984,979,974,968,963,957,950,944,937,930,922,915,907,899,890,882,873,864,855,846,836,826,816,806,796,785,774,764,753,741,730,719,707,696,684,672,660,648,636,624,
611,599,587,574,562,549,537,524,512,499,486,474,461,449,436,424,412,399,387,375,363,351,339,327,316,304,293,282,270,259,249,238,227,217,207,197,187,177,168,159,
150,141,133,124,116,108,101,93,86,79,73,66,60,55,49,44,39,34,30,26,22,19,15,12,10,8,6,4,2,1,1,0,0,0,1,1,2,4,6,8,
10,12,15,19,22,26,30,34,39,44,49,55,60,66,73,79,86,93,101,108,116,124,133,141,150,159,168,177,187,197,207,217,227,238,249,259,270,282,293,304,
316,327,339,351,363,375,387,399,412,424,436,449,461,474,486,499
};
void setup()
{
ind = i+128;
Wire.begin();
Wire.setClock(400000);
Serial.begin(9600);
dac.begin(0x62);
Serial.println("MCP4725A found!");
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide the 48MHz clock source by divisor 1: 48MHz/1=48MHz
GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN | // Enable GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
GCLK_GENCTRL_ID(4); // Select GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Feed GCLK4 to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Normal (single slope) PWM operation: timers countinuously count up to PER register value and then is reset to 0
REG_TCC0_WAVE |= TCC_WAVE_WAVEGEN_NPWM; // Setup single slope PWM on TCC0
while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
// Each timer counts up to a maximum or TOP value set by the PER register,
// this determines the frequency of the PWM operation:
REG_TCC0_PER = 1919; // Set the frequency of the PWM on TCC0 to 25kHz
while(TCC0->SYNCBUSY.bit.PER); // Wait for synchronization
// Set the PWM signal to output 50% duty cycle on D7
REG_TCC0_CCB3 = 959; // TCC0 CCB3 - on output on D7 50% duty cycle
while(TCC0->SYNCBUSY.bit.CCB3); // Wait for synchronization
NVIC_SetPriority(TCC0_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TCC0 to 0 (highest)
NVIC_EnableIRQ(TCC0_IRQn); // Connect TCC0 to Nested Vector Interrupt Controller (NVIC)
REG_TCC0_INTENSET = TC_INTENSET_OVF; // Enable TCC0 overflow interrupt
// Divide the 48MHz signal by 1 giving 48MHz (20.83ns) TCC0 timer tick and enable the outputs
REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
TCC_CTRLA_ENABLE; // Enable the TCC0 output
while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
}
void loop() {
if(flag){
dac.setVoltage(pgm_read_word(&(sintable[ind])), false);
flag = 0;
}
}
// Ineterrupt handler called every time the TCC0 timer overflows
void TCC0_Handler() // Interrupt Service Routine (ISR) for timer TCC0
{
// Check for overflow (OVF) interrupt
if (TCC0->INTFLAG.bit.OVF && TCC0->INTENSET.bit.OVF)
{
flag = 1;
ind++;
if(ind == 256)
ind = 0;
REG_TCC0_INTFLAG = TC_INTFLAG_OVF; // Clear the OVF interrupt flag
}
}