Hey Everyone I'm trying to get my nano every to out 3 different sine waves (one wave being delayed by 120 degrees and the last wave being delayed by 240 degrees). I already have one wave being formed but I can't get the second wave to be sent to any of the pins for me to monitor. I'm expecting them to show up on pins 3 and 4 but those pins are dead. Any advice would be appreciated.
#include <Arduino.h>
#include <math.h>
// 360-point sine table, values in [0..255]
#define SINE_STEPS 360
static uint8_t sineTable[SINE_STEPS];
// Build sine table
void setupSineTable() {
for (int i = 0; i < SINE_STEPS; i++) {
float angle = (float)i * 2.0f * M_PI / 360.0f;
float s = sinf(angle); // in [-1..+1]
float shifted = (s + 1.0f) * 127.5f; // map to [0..255]
if (shifted < 0.0f) shifted = 0.0f;
if (shifted > 255.0f) shifted = 255.0f;
sineTable[i] = (uint8_t)(shifted + 0.5f);
}
}
// (Phase A: LCMP0/LCMP1 -> D2/D7, Phase B: LCMP2/HCMP0 -> D4/D3)
void setupTCA0SplitPWM() {
// Route TCA0 outputs to default pins (WO0..WO5 on PA0..PA5 => D2..D7, plus others).
PORTMUX.TCAROUTEA = 0x00;
// Enable SPLIT mode => two 8-bit timers with 3 "low" channels + 3 "high" channels.
TCA0.SINGLE.CTRLD = 0;
TCA0.SPLIT.CTRLD = TCA_SPLIT_SPLITM_bm;
// Each half is 8-bit from 0..255
TCA0.SPLIT.LPER = 0xFF; // Low half
TCA0.SPLIT.HPER = 0xFF; // High half
// Initialize all channels to 0% duty
// Phase A: D2=LCMP0, D7=LCMP1
TCA0.SPLIT.LCMP0 = 0;
TCA0.SPLIT.LCMP1 = 0;
// Phase B: D4=LCMP2, D3=HCMP0
TCA0.SPLIT.LCMP2 = 0;
TCA0.SPLIT.HCMP0 = 0;
// Make sure pins are outputs
pinMode(2, OUTPUT); // A High => WO0 => LCMP0
pinMode(7, OUTPUT); // A Low => WO1 => LCMP1
pinMode(4, OUTPUT); // B High => WO2 => LCMP2
pinMode(3, OUTPUT); // B Low => WO3 => HCMP0
// Enable the 4 channels we need:
// LCMP0EN, LCMP1EN, LCMP2EN (Phase A + B Highs)
// HCMP0EN (Phase B Low)
TCA0.SPLIT.CTRLB =
TCA_SPLIT_LCMP0EN_bm |
TCA_SPLIT_LCMP1EN_bm |
TCA_SPLIT_LCMP2EN_bm |
TCA_SPLIT_HCMP0EN_bm;
// Start timer with prescaler=64 => ~1.22 kHz at 20MHz CPU
TCA0.SPLIT.CTRLA = TCA_SINGLE_CLKSEL_DIV64_gc | TCA_SINGLE_ENABLE_bm;
}
void setup() {
setupSineTable();
setupTCA0SplitPWM();
}
void loop() {
static uint16_t i = 0;
i = (i + 1) % SINE_STEPS;
// Phase A: index i
uint8_t A_duty = sineTable[i];
uint8_t A_comp = 255 - A_duty;
// Phase B: index i+120° => +120 steps
uint8_t B_duty = sineTable[(i + 120) % SINE_STEPS];
uint8_t B_comp = 255 - B_duty;
// Assign to hardware compare registers:
// Phase A => "High" (LCMP0 => D2) & "Low" (LCMP1 => D7)
TCA0.SPLIT.LCMP0 = A_duty;
TCA0.SPLIT.LCMP1 = A_comp;
// Phase B => "High" (LCMP2 => D4) & "Low" (HCMP0 => D3)
TCA0.SPLIT.LCMP2 = B_duty;
TCA0.SPLIT.HCMP0 = B_comp;
// ~10ms => ~100 Hz update for the sine wave
delay(10);
}
