#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
+#include <util/twi.h>
+#include <avr/eeprom.h>
+#include <avr/wdt.h>
#include "uart.h"
/*
#define PWM_BREAK INT16_MIN
#define STALL_LIMIT 140000
-#define TWI_ACK TWCR = (1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
-#define TWI_RESET TWCR &= ~((1 << TWSTO) | (1 << TWEN)); TWI_ACK
+#define TWI_ACK TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE)
#define TWI_NAK TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
+#define TWI_RESET TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWSTO) | (1<<TWEN) | (1<<TWIE);
#define ENABLE_PWM_MOTOR1 TCCR1A |= (1 << COM1A1)
#define ENABLE_PWM_MOTOR2 TCCR1A |= (1 << COM1B1)
#define ENABLE_PWM_MOTOR3 TCCR2 |= (1 << COM21);
static ufloat_t tmp_speed;
static ufloat_t tmp_angle;
- switch (TWSR & 0xF8)
+ switch(TW_STATUS)
{
- case 0x60: // start write
+ case TW_SR_SLA_ACK: // start write
TWI_ACK;
ireg = 0;
break;
- case 0x80: // write
+ case TW_SR_DATA_ACK: // write
switch(ireg) {
case 0x00: // register select
ireg = TWDR;
}
ireg++;
break;
- case 0xA8: // start read
- case 0xB8: // read
+ case TW_ST_SLA_ACK: // start read
+ case TW_ST_DATA_ACK: // read
switch(ireg) {
case 0x02: // Motor 1 PWM
TWDR = OCR1A;
}
ireg++;
break;
+ case TW_SR_STOP:
+ TWI_ACK;
+ break;
default:
TWI_RESET;
}
speed1_wish_old = speed1_wish;
}
- if (speed1_wish == 0) {
+ uint8_t dir_change = (speed1_wish > 0 && speed1 < 0) || (speed1_wish < 0 && speed1 > 0); // Prevent dangerous immediate engine reverse
+ if (speed1_wish == 0 || dir_change) {
motor1 = 0;
eold1 = 0;
error_state &= ~(1<<4);
speed2_wish_old = speed2_wish;
}
- if (speed2_wish == 0) {
+ uint8_t dir_change = (speed2_wish > 0 && speed2 < 0) || (speed2_wish < 0 && speed2 > 0); // Prevent dangerous immediate engine reverse
+ if (speed2_wish == 0 || dir_change) {
motor2 = 0;
eold2 = 0;
error_state &= ~(1<<5);
speed3_wish_old = speed3_wish;
}
- if (speed3_wish == 0) {
+ uint8_t dir_change = (speed3_wish > 0 && speed3 < 0) || (speed3_wish < 0 && speed3 > 0); // Prevent dangerous immediate engine reverse
+ if (speed3_wish == 0 || dir_change) {
motor3 = 0;
eold3 = 0;
error_state &= ~(1<<6);
speed4_wish_old = speed4_wish;
}
- if (speed4_wish == 0) {
+ uint8_t dir_change = (speed4_wish > 0 && speed4 < 0) || (speed4_wish < 0 && speed4 > 0); // Prevent dangerous immediate engine reverse
+ if (speed4_wish == 0 || dir_change) {
motor4 = 0;
eold4 = 0;
error_state &= ~(1<<7);
// I2C
TWAR = 0x50;
- TWI_RESET;
+ TWI_ACK;
// Motor 1 & 2
// Also used for PWM frequency TIMER1_FREQ (F_CPU/256)
case 0xff: // Magic reg that starts the bootloader
if (bootloader == 0xa5) {
cli();
- {
- void (*start)(void) = (void*)0x1800;
- start();
- }
+ // write mark to first area in eeprom
+ eeprom_write_byte((uint8_t*)0, 123);
+ eeprom_busy_wait();
+ // Use watchdog to restart
+ wdt_enable(WDTO_15MS);
}
break;
}