Hey everybody
I have an issue waking my ATTiny2313A up from POWER DOWN sleep.
My original code was for an ATTiny85 with a tinycore on the arduino compiler.
Now I am converting my code to be used within Atmel Studio 7 with a ATTiny2313A.
Here is my code:
#include <avr/io.h> #define F_CPU 8000000UL // 8 MHz #include <util/delay.h> #include <avr/sleep.h> #include <avr/wdt.h> #include <avr/interrupt.h> //for ISR interrupt) // ATtiny2313A outputs for PWM const char RedPin = PB2; const char GreenPin = PD5; const char BluePin = PB3; // Variables for PWM color unsigned char Red = 0; unsigned char Blue = 0; unsigned char Green = 0; // Other variables unsigned char SleepTime = 8; ISR(WDT_OVERFLOW_vect) { // = executed on wake-up } void setup_watchdog(unsigned char timerPrescaler) { if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings unsigned char bb = timerPrescaler & 7; if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary //This order of commands is important and cannot be combined MCUSR &= ~(1<<WDRF); //Clear the watch dog reset WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable WDTCR = bb; //Set new watchdog timeout value WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int //Sets the watchdog timer to wake us up, but not reset //0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms //6=1sec, 7=2sec, 8=4sec, 9=8sec //From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/ } int main(void) { DDRB |= (1 << RedPin); // PWM output on PB2 - 0C0A DDRD |= (1 << GreenPin); // PWM output on PD5 - 0C0B DDRB |= (1 << BluePin); // PWM output on PD5 - 0C1B TCCR0A = (15 << COM0B0) | (3 << WGM00); // fast inverted PWM on 0C0 A&B TCCR0B = (1 << CS00); // clock source = CLK, start PWM -> check libraries do not want another value TCCR1A = (3 << COM1A0) | (1 << WGM10); TCCR1B = (1 << CS10) | (1 << WGM12); OCR0A=0xFF; //Red OCR0B=0xFF; //Green OCR1A=0xFF; //Blue Red=0x00; Green=0x55; Blue=0xAA; set_sleep_mode(SLEEP_MODE_PWR_DOWN); while (1) { if(Red==0xFF) Red=0x00; else Red++; if(Green==0xFF) Green=0x00; else Green++; if(Blue==0xFF) Blue=0x00; else Blue++; OCR0A=~(Red); //Red OCR0B=~(Green); //Green OCR1A=~(Blue); //Blue _delay_ms(10); if (Red == 0xFF) { //sleepy mode DDRB &= ~(1 << RedPin); // PWM input on PB2 - 0C0A DDRD &= ~(1 << GreenPin); // PWM input on PD5 - 0C0B DDRB &= ~(1 << BluePin); // PWM input on PD5 - 0C1B setup_watchdog(SleepTime); //Setup watchdog to go off after Xsec sleep_mode(); //Go to sleep! Wake up Xsec later and continue DDRB |= (1 << RedPin); // PWM output on PB2 - 0C0A DDRD |= (1 << GreenPin); // PWM output on PD5 - 0C0B DDRB |= (1 << BluePin); // PWM output on PD5 - 0C1B } } }
The PWM works perfectly till the Red = 0xFF trigger is reached.
The LED's switch off and the AVR powers down. (I tested this with a current meter, it does enter the POWER DOWN mode)
But when I expect it to wake up, and continue with the code, nothing happens.
I have searched this forum and google, but nowhere I can find answers that work.
Some notes:
- First I was still using the WDT_vect (for all tinies except the 2313..) I switched this to WDT_OVERFLOW_vect -> Did not solve the issue
- WDTCR vs WDTCSR: The manual for the 2313A talks about WDTCSR. I still had WDTCR in my code as it was originally for and ATTiny85. But as it now happens, the iotn2313a.h file has it defined as WDTCR. So no adjustment should be needed. I checked the register and it is the correct bit. Except for the 2313 it is defined as 0x21 and for the 2313A as 0x021. But this does not matter as it is the same value I presume.
Thanks for the help in advance.