#include <util/twi.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
+#include <avr/pgmspace.h>
#include "uart.h"
/*
* 0xA0 Reset reason
* 0xA1 Error status
* 0xA2 count test
+ * 0xA3 last i2c status before boot
+ * 0xA4 Watchdog enable
* free
* 0xff Bootloader
*/
static volatile uint8_t front_handicap=0;
static volatile uint8_t aft_handicap=0;
static volatile uint8_t error_state=0;
-static volatile uint8_t last_man_update_count=I2C_TIMEOUT_DISABLE;
+static volatile uint8_t last_man_update_count=0;
+static volatile uint8_t last_i2c_status = 0;
+static uint8_t last_i2c_status_boot = 0;
+static volatile uint8_t watchdog_enable = 0;
ISR(TWI_vect)
{
static ufloat_t tmp_speed;
static ufloat_t tmp_angle;
+ last_i2c_status = TW_STATUS;
switch(TW_STATUS)
{
case TW_SR_SLA_ACK: // start write
cmd_vel.bUpdate = 1;
TWI_ACK;
break;
+ case 0xA4: // Watchdog enable
+ watchdog_enable = TWDR;
+ TWI_ACK;
+ break;
case 0xff: // bootloader
bootloader = TWDR;
default:
case 0xA2: // count test
TWDR = count_test;
TWI_ACK;
+ case 0xA3: // last i2c status before boot
+ TWDR = last_i2c_status_boot;
+ TWI_ACK;
+ case 0xA4: // Watchdog enable
+ TWDR = watchdog_enable;
+ TWI_ACK;
default:
TWDR = 0;
TWI_NAK;
case TW_SR_STOP:
TWI_ACK;
break;
+ case TW_NO_INFO:
+ break;
default:
TWI_RESET;
}
+
+ if (watchdog_enable == 2) {
+ wdt_reset();
+ }
}
TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << CS00);
OCR0 = 0;
- printf("\r\nStart\r\n");
+ printf_P(PSTR("\r\nStart\r\n"));
+
+ last_i2c_status_boot = eeprom_read_byte((uint8_t*)1);
set_sleep_mode(SLEEP_MODE_IDLE);
// Enable Timer 1 Overflow Interrupt
while(1) {
switch(ireg) {
+ case 0xA4: // Watchdog enable
+ if (watchdog_enable == 1) {
+ wdt_enable(WDTO_2S);
+ watchdog_enable = 2;
+ } else if (watchdog_enable == 0) {
+ wdt_disable();
+ watchdog_enable = 3;
+ }
+ break;
case 0xff: // Magic reg that starts the bootloader
if (bootloader == 0xa5) {
cli();
count_test++;
if (last_man_update_count != I2C_TIMEOUT_DISABLE) last_man_update_count++;
- if (last_man_update_count > 100) {
+ if (last_man_update_count >= 100) {
// ~1s without a new i2c command
cmd_vel.speed = 0;
cmd_vel.angle = 0;
cmd_vel.bUpdate = 1;
+ if (last_man_update_count == 100) {
+ printf_P(PSTR("I2C State: 0x%x\r\n"), last_i2c_status);
+ eeprom_write_byte((uint8_t*)1, last_i2c_status);
+ eeprom_busy_wait();
+ }
last_man_update_count = I2C_TIMEOUT_DISABLE;
}
}