From 7528037d4eedbf364bc9895df391b9512169ce23 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sun, 4 Dec 2011 18:22:11 +0100 Subject: [PATCH] Save status register on each interrupt. Costs 28 bytes binary size and two CPU cycles per interrupt, at the advantage of getting rid of possible well hidden bugs. --- analog.c | 8 ++++++++ intercom.c | 21 +++++++++++++++++++++ serial.c | 15 +++++++++++++++ timer.c | 22 +++++++++++++++------- watchdog.c | 8 ++++++++ 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/analog.c b/analog.c index bfa348a..7856fd0 100644 --- a/analog.c +++ b/analog.c @@ -7,6 +7,7 @@ #include "temp.h" #include +#include "memory_barrier.h" /* OR-combined mask of all channels */ #undef DEFINE_TEMP_SENSOR @@ -79,6 +80,9 @@ void analog_init() { This is where we read our analog value and store it in an array for later retrieval */ ISR(ADC_vect, ISR_NOBLOCK) { + // save status register + uint8_t sreg_save = SREG; + // emulate free-running mode but be more deterministic about exactly which result we have, since this project has long-running interrupts if (analog_mask > 0) { // store next result @@ -102,6 +106,10 @@ ISR(ADC_vect, ISR_NOBLOCK) { // After the mux has been set, start a new conversion ADCSRA |= MASK(ADSC); } + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } /*! Read analog value from saved result array diff --git a/intercom.c b/intercom.c index 6bcfe35..8547072 100644 --- a/intercom.c +++ b/intercom.c @@ -139,6 +139,9 @@ ISR(USART1_RX_vect) ISR(USART_RX_vect) #endif { + // save status register + uint8_t sreg_save = SREG; + // pull character static uint8_t c; @@ -196,6 +199,10 @@ ISR(USART_RX_vect) #endif } } + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } // finished transmitting interrupt- only enabled at end of packet @@ -205,6 +212,9 @@ ISR(USART1_TX_vect) ISR(USART_TX_vect) #endif { + // save status register + uint8_t sreg_save = SREG; + if (packet_pointer >= sizeof(intercom_packet_t)) { disable_transmit(); packet_pointer = 0; @@ -215,6 +225,10 @@ ISR(USART_TX_vect) UCSR0B &= ~MASK(TXCIE0); #endif } + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } // tx queue empty interrupt- send next byte @@ -224,6 +238,9 @@ ISR(USART1_UDRE_vect) ISR(USART_UDRE_vect) #endif { + // save status register + uint8_t sreg_save = SREG; + #ifdef HOST UDR1 = _tx.data[packet_pointer++]; #else @@ -239,6 +256,10 @@ ISR(USART_UDRE_vect) UCSR0B |= MASK(TXCIE0); #endif } + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } #endif /* TEMP_INTERCOM */ diff --git a/serial.c b/serial.c index 999eca0..5630016 100644 --- a/serial.c +++ b/serial.c @@ -11,6 +11,7 @@ */ #include +#include "memory_barrier.h" #include "config.h" #include "arduino.h" @@ -110,6 +111,9 @@ ISR(USART_RX_vect) ISR(USART0_RX_vect) #endif { + // save status register + uint8_t sreg_save = SREG; + if (buf_canwrite(rx)) buf_push(rx, UDR0); else { @@ -128,6 +132,10 @@ ISR(USART0_RX_vect) UCSR0B |= MASK(UDRIE0); } #endif + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } /// transmit buffer ready interrupt @@ -139,6 +147,9 @@ ISR(USART_UDRE_vect) ISR(USART0_UDRE_vect) #endif { + // save status register + uint8_t sreg_save = SREG; + #ifdef XONXOFF if (flowflags & FLOWFLAG_SEND_XON) { UDR0 = ASCII_XON; @@ -154,6 +165,10 @@ ISR(USART0_UDRE_vect) buf_pop(tx, UDR0); else UCSR0B &= ~MASK(UDRIE0); + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } /* diff --git a/timer.c b/timer.c index 9472aa1..19fec0d 100644 --- a/timer.c +++ b/timer.c @@ -11,6 +11,7 @@ */ #include +#include "memory_barrier.h" #include "arduino.h" #include "config.h" @@ -19,7 +20,6 @@ #include "dda_queue.h" #endif -#include "memory_barrier.h" /// how often we overflow and update our clock; with F_CPU=16MHz, max is < 4.096ms (TICK_TIME = 65535) #define TICK_TIME 2 MS @@ -48,6 +48,9 @@ volatile uint8_t clock_flag_1s = 0; /// comparator B is the system clock, happens every TICK_TIME ISR(TIMER1_COMPB_vect) { + // save status register + uint8_t sreg_save = SREG; + // set output compare register to the next clock tick OCR1B = (OCR1B + TICK_TIME) & 0xFFFF; @@ -71,12 +74,19 @@ ISR(TIMER1_COMPB_vect) { } } } + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } #ifdef HOST /// comparator A is the step timer. It has higher priority then B. ISR(TIMER1_COMPA_vect) { + // save status register + uint8_t sreg_save = SREG; + // Check if this is a real step, or just a next_step_time "overflow" if (next_step_time < 65536) { // step! @@ -108,6 +118,10 @@ ISR(TIMER1_COMPA_vect) { next_step_time += 10000; } // leave OCR1A as it was + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } #endif /* ifdef HOST */ @@ -136,8 +150,6 @@ void timer_init() */ void setTimer(uint32_t delay) { - // save interrupt flag - uint8_t sreg = SREG; uint16_t step_start = 0; #ifdef ACCELERATION_TEMPORAL uint16_t current_time; @@ -211,10 +223,6 @@ void setTimer(uint32_t delay) // timer1a interrupt to the far side of the return, protecting the // stack from recursively clobbering memory. TIMSK1 |= MASK(OCIE1A); - - // restore interrupt flag - MEMORY_BARRIER(); - SREG = sreg; } /// stop timers - emergency stop diff --git a/watchdog.c b/watchdog.c index f31b42e..c1d15ff 100644 --- a/watchdog.c +++ b/watchdog.c @@ -14,6 +14,7 @@ #include #include +#include "memory_barrier.h" #include "arduino.h" #ifndef EXTRUDER @@ -31,10 +32,17 @@ volatile uint8_t wd_flag = 0; // } ISR(WDT_vect) { + // save status register + uint8_t sreg_save = SREG; + // watchdog has tripped- no main loop activity for 0.5s, probably a bad thing // if watchdog fires again, we will reset // perhaps we should do something more intelligent in this interrupt? wd_flag |= 1; + + // restore status register + MEMORY_BARRIER(); + SREG = sreg_save; } /// intialise watchdog