1010 Our version number - used by the daemon to ensure that the major number is equal between firmware and daemon
1111*/
1212#define MAJOR 2L
13- #define MINOR 4L
14- #define PATCH 2L
13+ #define MINOR 6L
14+ #define PATCH 3L
1515
1616const uint32_t prog_version = (MAJOR << 16 ) | (MINOR << 8 ) | PATCH ;
1717
@@ -36,6 +36,15 @@ uint8_t state = UNCLEAR_STATE;
3636*/
3737uint8_t register_number;
3838
39+ /*
40+ These variables hold the fuse settings. If we try to read the fuse settings over I2C without
41+ this buffering then we very often get timeouts. So, until we are in dire need of memory we
42+ simply copy the fuse settings to RAM.
43+ */
44+ uint8_t fuse_low;
45+ uint8_t fuse_high;
46+ uint8_t fuse_extended;
47+
3948/*
4049 These are the 8 bit registers (the register numbers are defined in ATTinyDaemon.h)
4150 Important: The value 0xFF is no valid value and will be filtered on the RPi side
@@ -69,6 +78,8 @@ uint16_t sw_recovery_delay = 1000; // the pause needed between two reset puls
6978void setup () {
7079 reset_watchdog (); // do this first in case WDT fires
7180
81+ check_fuses (); // verify that we can run with the fuse settings
82+
7283 /*
7384 If we got a reset while pulling down the switch, this might lead to short
7485 spike on switch pin. Shouldn't be a problem because we can stop the RPi
@@ -131,12 +142,7 @@ void loop() {
131142 if (state < SHUTDOWN_STATE ) {
132143 if (should_shutdown > SL_INITIATED && (seconds < timeout)) {
133144 // RPi should take action, possibly shut down. Signal by blinking 5 times
134- for (int i = 0 ; i < 5 ; i++) {
135- delay (BLINK_TIME );
136- ledOff_buttonOn ();
137- delay (BLINK_TIME );
138- ledOn_buttonOff ();
139- }
145+ blink_led (5 , BLINK_TIME );
140146 }
141147 }
142148
@@ -171,12 +177,7 @@ void loop() {
171177 if (seconds > timeout) {
172178 // RPi has not accessed the I2C interface for more than timeout seconds.
173179 // We restart it. Signal restart by blinking ten times
174- for (int i = 0 ; i < 10 ; i++) {
175- ledOn_buttonOff ();
176- delay (BLINK_TIME / 2 );
177- ledOff_buttonOn ();
178- delay (BLINK_TIME / 2 );
179- }
180+ blink_led (10 , BLINK_TIME / 2 );
180181 restart_raspberry ();
181182 reset_counter ();
182183 }
@@ -195,7 +196,7 @@ void loop() {
195196 reset_watchdog ();
196197 sleep_enable ();
197198 sleep_bod_disable ();
198- interrupts (); // guarantees next instruction executed
199+ interrupts (); // guarantees next instruction executed
199200 sleep_cpu ();
200201 sleep_disable ();
201202}
@@ -208,6 +209,53 @@ void reset_counter() {
208209 seconds = 0 ;
209210}
210211
212+ /*
213+ check the fuse settings for clock frequency and divisor. Signal SOS in
214+ an endless loop if not correct.
215+ */
216+ void check_fuses () {
217+ fuse_low = boot_lock_fuse_bits_get (GET_LOW_FUSE_BITS );
218+ fuse_high = boot_lock_fuse_bits_get (GET_HIGH_FUSE_BITS );
219+ fuse_extended = boot_lock_fuse_bits_get (GET_EXTENDED_FUSE_BITS );
220+
221+ if (fuse_low == 0xE2 ) {
222+ // everything set up perfectly, we are running at 8MHz
223+ return ;
224+ }
225+ if (fuse_low == 0x62 ) {
226+ /*
227+ Default fuse setting, we can change the clock divisor to run with 8 MHz.
228+ We do not need to correct any other values for the arduino libraries
229+ since we only use the delay()-function which relies on a system timer
230+ */
231+
232+ clock_prescale_set (clock_div_1);
233+ return ;
234+ }
235+ // fuses have been changed, but not to the needed frequency. We send an SOS.
236+
237+ while (1 ) {
238+ blink_led (3 , BLINK_TIME / 2 );
239+ delay (BLINK_TIME / 2 );
240+ blink_led (3 , BLINK_TIME );
241+ delay (BLINK_TIME / 2 );
242+ blink_led (3 , BLINK_TIME / 2 );
243+ delay (BLINK_TIME );
244+ }
245+ }
246+
247+ /*
248+ Blink the led n times for blink_length
249+ */
250+ void blink_led (int n, int blink_length) {
251+ for (int i = 0 ; i < n; i++) {
252+ ledOn_buttonOff ();
253+ delay (blink_length);
254+ ledOff_buttonOn ();
255+ delay (blink_length);
256+ }
257+ }
258+
211259/*
212260 Read the values stored in the EEPROM. The addresses are defined in
213261 the header file. We use the modern get()-method that determines the
0 commit comments