token-vesting
token-vesting copied to clipboard
analogWrite does not work for ATtiny412 pin PA6
The default implementation does not correctly configure TCD0 to output PWM on pin PA6 for the ATtiny 412. I went fairly deep into the megaTinyCore source code and I'm guessing something isn't configured correctly with the different #defined macros, because it seems to be defaulting to the "pwm not available on this pin" path in the code instead of using TCD0, which is available.
Code to reproduce
Board: ATtiny412/402/212/202 Chip: ATtiny412 Clock speed: 20MHz internal (also tried with 1MHz internal) millis/micros timer: Default, which I believe is TCD0 on this chip (also tried with TCB0 and TCA)
void setup() {
// put your setup code here, to run once:
pinMode(PIN_PA6, OUTPUT);
analogWrite(PIN_PA6, 200);
}
void loop() {
// put your main code here, to run repeatedly:
}
I can properly configure TCD manually to output with WOA on PA6
Code that works
Same chip settings as above
void pwm_init(void) {
// Enable-protected reg must have 0 written to enable bit before any other bits can be changed, and it defaults to
// enabled on startup
TCD0.CTRLA &= ~TCD_ENABLE_bm;
// Don't need overlapping PWM signals so just do oneramp
TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
// Disable all input control
TCD0.INPUTCTRLA = TCD_INPUTMODE_NONE_gc;
// Set/clear values to create desired duty cycle. Don't care about CMPB (outputs on PA7) at all so leave it off
TCD0.CMPASET = 0x000;
TCD0.CMPACLR = 0x1FF;
// System 1MHz clock w/ DIV4 standard prescaler but no synchronization prescaler (I think they multiply together, not add).
// Must be done as last operation before starting timer with ENABLE bit
// NOTE :: DEFAULT TIMER FOR MILLIS/MICROS FUNCTIONS ON 1-SERIES ATTINIES IS TCD. I think this still works with it set as the default,
// but if not, try switching it to TCB0.
TCD0.CTRLA = TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV4_gc | TCD_SYNCPRES_DIV1_gc;
}
void pwm_start(void) {
// Turn off output override (because we want pwm to run it duh)
TCD0.CTRLC &= ~TCD_CMPOVR_bm;
// Enable WOA (PA6) but not and WOB/C/D (PA7/?/?). Since FAULTCTRL reg is write protected we need to make it editable in
// CCP reg. Must be done in start func because we can't take over output pins in stop func unless we disable them in FAULTCTRL.
CPU_CCP = CCP_IOREG_gc;
TCD0.FAULTCTRL = TCD_CMPAEN_bm;
while (!(TCD0.STATUS & TCD_ENRDY_bm)) {
;
}
TCD0.CTRLA |= TCD_ENABLE_bm;
}
/*
* Must be called every time TCD0.CMPASET or TCD0.CMPACLR are updated for them to take effect if they're changed while PWM running.
*/
void pwm_sync(void) {
TCD0.CTRLE = TCD_SYNCEOC_bm;
}
void setup() {
pwm_init();
pwm_start();
}
void loop() {}
Not sure if I'm doing something wrong with the setup/config, or if it's a megatinycore issue. Happy to test any changes out on my board if needed.
Maybe it has something to do with this announcement from March '23
https://github.com/SpenceKonde/megaTinyCore/discussions/928
I just tested on both Github and Boards Manager version of MTC and get the same what you get. As you seem to have passed the complex hurdle of beating TCD into submission, I would stick with your second approach for now.
Yeah I'm all set, it's a simple one-off little project. Just raising the issue here in case it wasn't known. The version of megaTinyCore that I have installed is from before that post. Actually I'm not sure what version it is, so maybe it's been fixed since honestly.
Yeah it seems that it isn't passing one of the params it needs to...