logging.c: simple logging implementation
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 30 Jan 2014 16:03:15 +0000 (17:03 +0100)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 30 Jan 2014 16:03:15 +0000 (17:03 +0100)
firmware/Makefile
firmware/logging.c [new file with mode: 0644]
firmware/logging.h [new file with mode: 0644]
firmware/main.c

index da02dbb..bcacd50 100644 (file)
@@ -1,6 +1,6 @@
 
 PROGRAM=heater
-SRC=version.c main.c
+SRC=version.c main.c logging.c
 OBJ=$(SRC:.c=.o)
 
 
diff --git a/firmware/logging.c b/firmware/logging.c
new file mode 100644 (file)
index 0000000..82c9877
--- /dev/null
@@ -0,0 +1,89 @@
+#ifdef USE_LOGGING
+
+#include <avr/io.h>
+#include <avr/eeprom.h>
+#include <util/atomic.h>
+
+#include "logging.h"
+
+static unsigned char buffer_ee[LOG_EE_BUF_SIZE] EEMEM;
+static unsigned char buffer_ram[LOG_RAM_BUF_SIZE];
+
+static unsigned char buffer_ram_ptr, buffer_ee_ptr;
+static unsigned char log_enabled = 0;
+
+static void inline log_init_common()
+{
+       log_enabled = 1;
+       buffer_ram_ptr = 0;
+       buffer_ee_ptr = 0;
+}
+
+#ifdef LOG_RATELIMIT_BOOTCOUNT
+static unsigned char reboot_count EEMEM;
+
+void log_init()
+{
+       unsigned char r_count;
+
+       r_count = eeprom_read_byte(&reboot_count);
+       r_count >>= 4;
+
+       if (r_count < LOG_RATELIMIT_BOOTCOUNT) {
+               r_count++;
+               eeprom_write_byte(&reboot_count,
+                       (r_count << 4) | (MCUSR & 0xF));
+               log_init_common();
+       }
+}
+#else
+void log_init() { log_init_common(); }
+#endif
+
+void log_byte(unsigned char byte)
+{
+       if (!log_enabled)
+               return;
+
+       ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+               buffer_ram[buffer_ram_ptr++] = byte;
+
+               if (buffer_ram_ptr >= LOG_RAM_BUF_SIZE)
+                       log_flush();
+       }
+}
+
+void log_word(uint16_t word)
+{
+       if (!log_enabled)
+               return;
+
+       ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+               log_byte(word & 0xFF);
+               log_byte(word >> 8);
+       }
+}
+
+void log_flush()
+{
+       unsigned char i;
+
+       if (!log_enabled)
+               return;
+
+       ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+               for (i = 0; i < buffer_ram_ptr; i++) {
+                       eeprom_write_byte(&buffer_ee[buffer_ee_ptr++],
+                               buffer_ram[i]);
+
+                       if (buffer_ee_ptr >= LOG_EE_BUF_SIZE) {
+                               log_enabled = 0;
+                               return;
+                       }
+               }
+               buffer_ram_ptr = 0;
+       }
+}
+
+#endif
+
diff --git a/firmware/logging.h b/firmware/logging.h
new file mode 100644 (file)
index 0000000..962a830
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef LOGGING_H__
+#define LOGGING_H__ 1
+
+#define USE_LOGGING 1  // comment out to disable logging
+
+#define LOG_EE_BUF_SIZE 64     // log buffer size in EEPROM
+#define LOG_RAM_BUF_SIZE 16    // log double buffer size
+
+#define LOG_RATELIMIT_BOOTCOUNT 5 // limit logging to first five boots
+       // if commented out, logs after each boot (beware the EEPROM wear!)
+
+#ifdef USE_LOGGING
+
+void log_init();
+void log_byte(unsigned char byte);
+void log_word(uint16_t word);
+void log_flush();
+
+#else /* !USE_LOGGING */
+
+#define init_log(dummy)        do { } while(0)
+#define log_byte(dummy)        do { } while(0)
+#define log_word(dummy)        do { } while(0)
+#define log_flush()    do { } while(0)
+
+#endif /* USE_LOGGING */
+
+#endif /* !LOGGING_H__ */
index 30f904b..7877786 100644 (file)
@@ -1,11 +1,12 @@
 #include <avr/io.h>
-#include <avr/eeprom.h>
 #include <util/delay.h>
 
-static uint16_t adcval EEMEM;
+#include "logging.h"
 
 int main()
 {
+       log_init();
+
        DDRB |= _BV(PB2) | _BV(PB4);
        TCCR1 = _BV(CS10); // clk/1 = 1 MHz
        // TCCR1 = _BV(CS11) | _BV(CS13); // clk/512 = 2 kHz
@@ -19,10 +20,12 @@ int main()
        ADCSRA |= _BV(ADSC);
        while (!(ADCSRA & _BV(ADIF)))
                ;
+       log_word(ADCW);
        ADCSRA |= _BV(ADSC);
        while (!(ADCSRA & _BV(ADIF)))
                ;
-       eeprom_write_word(&adcval, ADCW);
+       log_word(ADCW);
+       log_flush();
 
        while(1) {
                PORTB |= _BV(PB2);