Hi, my (for here stripped down, but probably not minimalist) program executes a pin change interrupt handler after hitting a button. Its handler does toggle an LED and also starts a timer. The timer finally overflows to toggle the LED back. Pretty easy. Unbounced, but hey, just demoing. Additionally, there is some UART output in the beginning (just to have it there for debugging purpose later on), and that's basically it. The program, when flashed to an ATmega 328p works as expected. See the issue below the code section. The format will most probably be terrible, but here it is: #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include "uart.h" //fleury's #include "main.h" #define UART_BAUD_RATE 38400 #define RELAIS_TIME_MS 500 volatile uint16_t cnt_switch_ms; char uart_getc_wait(); void io_init(void); unsigned int c; int main(void) { cli(); uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU)); io_init(); sei(); uart_puts( "Basic UART node1\r\n" ); while(1) { } } void io_init() { cli(); //PD4 as input and triggers pin change ISR DDRD &= ~(1 << PIND4); // PD4 as input PCICR |= (1 << PCIE2); // enable interrupt PCMSK2 |= (1 << PCINT20); // set to trigger an interrupt on state change // PB7 as output (red LED) DDRB |= (1 << PIND7); // PB7 as output // timer1 config // Set the Timer1 Mode to CTC TCCR1B |= (1 << WGM12); //OCRn = [ (clock_speed / Prescaler_value) * Desired_time_in_Seconds ] - 1 //OCR1 = [ (8000000 / 64 ) * 0.001] - 1 = 125-1 = 0x7c (timer IRQ each 1ms) OCR1A = 0x007c; TIMSK1 |= (1 << OCIE1A); //Set the ISR COMPA vect sei(); } //PD4 pin change interrupt handler ISR(PCINT2_vect) // remark: higher prio than timer1 ISR { cli(); PORTB ^= (1 << PINB7); //switch relais TCCR1B |= ((1 << CS11) | (1 << CS10)); //start timer1 sei(); } // end PCINT2_vect // timer1 overflow interrupt handler ISR (TIMER1_COMPA_vect) { //executed every 1ms cnt_switch_ms += 1; //do stuff when timer is over if (cnt_switch_ms >= RELAIS_TIME_MS ) { PORTB ^= (1 << PINB7); // toggle the LED back TCCR1B &= ~((1 << CS11) | (1 << CS10)); // stop the timer cnt_switch_ms = 0; // reset its counters TCNT1 = 0; uart_puts( "t" ); // even notify via UART for checking the ISR was exec'd } } // end TIMER1_COMPA_vect 1 When flashed to the AVR via ISP programmer, this is all working as expected (LED flashes on triggering the pin, LED is toggled back after timer is overflowed, "t" is printed on the serial console). 2 AVR was reset via hardware (button on reset pin): still works as in 1. 3 When this program was not ISP-programmer flashed, but by a bootloader (CAN here): still works as expected. 4 When flashed via this bootloader, and the mentioned reset button was used at least once - the LED will still change its status by toggling the button connected to PD4 (i.e. pin change ISR is working fine). However, the timer ISR is not working at all it seems (toggling the LED back is missing as well as the uart's "t" on console). 5 Same behavior as in 3 for powering down, short circuiting and re-powering the board. --> any obvious pitfalls here one can think of? In the case of using the bootloader, at least some ISR's are suffering from not being .. executed?! Of course, after getting the code running with the bootloader, and having it disfunctional after resetting the AVR, one can still re-flash it via the bootloader and it will run without problems. Until the next reset/powerdown. Is there something very obvious coming to your minds, what could be the problem here? Something, an unexperienced hobbyist like me could have easily overlooked? Standard issues not tackled, because not known? I can add details later (e.g. the bootloader), but don't want to get it too long in the opening thread. Regards Christian
booti wrote: > I can add details later (e.g. the bootloader), but don't want to get it No need 4 that. Just don't use it any more. Or change ur Bootloader code from MEGA8 to M328 and it should be fine.
logarithmus wrote: > Just don't use it any more. Brilliant, also could've jumped from the roof to fix even more problems ;) For the folks that's interested: It's fixed now. The hardware reset will run through the bootloader, before continuing with the firmware. Any register modification done by the bootloader will survive, if starting the actual firmware is realized by a jump to address 0x0 initated by the bootloader. Watchdog timer reset does not seem to be an option in this scenario, but re-initialising the bootloader touched registers did the job :)
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.