Originally, I was using the CMP as sort of a CTC type thing, where I would reset the RTC count inside the ISR. This wouldn't work - the interrupt just never happened. Trying to fix this, I stumbled upon this thread (https://www.avrfreaks.net/forum/...) where it talked about how you can accomplish the same thing the "right" way by setting PER to your desired overflow value (which will do the same thing but will autoclear your RTC count). Now, this is not what I understood the datasheet to say, but you guys know what you're talking about so I switched to that method, which is what I used below. Except, even still, the ISR never triggers from the RTC. I know it's not a problem with the interrupts being disabled, because I have a push button interrupt as well which is working fine. Can anyone help me figure out what I'm doing wrong?
(I removed the parts that use the ADC and the external interrupt, but I left the setup parts just in case)
#include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 312500 #include <util/delay.h> #define LED PIN2 #define PUMP PIN3 #define RST PIN0 #define TEM ADC_MUXPOS_AIN1_gc #define RH ADC_MUXPOS_AIN7_gc #define VDDREF 4 int cycles=0; // Not in EEPROM for now bool needPrime=1; // Temporary stand-in for reading eeprom & calculating whether runtime since manual reset is 0 void init(){ PORTA.DIRCLR = 0xFF; PORTA.DIRSET = (1<<LED)|(1<<PUMP); // PA2 & PA3 as output PORTA.OUTSET = (1<<LED); // LED off PORTA.PIN1CTRL = PORT_ISC_INPUT_DISABLE_gc; // PA1 & PA7 as ADC inputs PORTA.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc; PORTA.PIN0CTRL = PORT_ISC_FALLING_gc; // Push button interrupt CCP = CCP_IOREG_gc; // Unlock protected registers for 4 cycles CLKCTRL.MCLKCTRLB = 0xB; // System clock 312.5 kHz VREF.CTRLA = 0x30; ADC0.CTRLC = ADC_SAMPCAP_bm | (1 << VDDREF); // Select sampling cap, 5v ref ADC0.CTRLD = ADC_INITDLY_DLY16_gc; // ADC sample delay ADC0.MUXPOS = ADC_MUXPOS_GND_gc; // Sampling GND by default RTC.CLKSEL = RTC_CLKSEL_INT32K_gc; // RTC low power 32.768kHz source while(RTC.STATUS > 0){;} // Ensure startup is finished with RTC RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV32768_gc; // Run in standby. 1-second resolution allows for 18.2 hr counter RTC.PER = 0x1D; // 30 sec timer RTC.INTCTRL = RTC_OVF_bm; // Enable overflow interrupt RTC.CTRLA |= RTC_RTCEN_bm; // Begin RTC sei(); } int main(void) { init(); for(;;){ if(needPrime){ PORTA.OUTCLR = (1<<LED); // Turn on LED PORTA.OUTSET = (1<<PUMP); // Run Pump _delay_ms(3000); // Possible to replace delays with timers & remove delay utility to save space? PORTA.OUTCLR = (1<<PUMP); PORTA.OUTSET = (1<<LED); needPrime = 0; cycles = 0; } if(cycles<19){ _delay_ms(100); PORTA.OUTCLR = (1<<LED); _delay_ms(100); PORTA.OUTSET = (1<<LED); } else PORTA.OUTSET = (1<<LED); } } ISR(RTC_CNT_vect){ RTC.INTFLAGS = RTC_OVF_bm; // Clear flag cycles++; PORTA.OUTCLR = (1<<LED); // Turn on LED PORTA.OUTSET = (1<<PUMP); // Run Pump _delay_ms(2000); // Possible to replace delays with timers & remove delay utility to save space? PORTA.OUTCLR = (1<<PUMP); PORTA.OUTSET = (1<<LED); }