--- /dev/null
+#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
+
--- /dev/null
+#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__ */
#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
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);