]> defiant.homedns.org Git - ros_wild_thumper.git/blobdiff - avr/motor_ctrl/main.c
misc avr fixes
[ros_wild_thumper.git] / avr / motor_ctrl / main.c
index a9565871f0058d7f2585f28ea5f2ca64b55694ca..ec9965f68800c26812a9eadf04da5e67dd3cec81 100644 (file)
@@ -5,6 +5,9 @@
 #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 KP 0.061
+#define KP 0.062
 #define KI 0.12
 #define KD 0.0
 #define PID_T 0.01
 // wheel diameter=12cm, encoder=48cpr, gear ratio=1:47
 // STEP_PER_M = 48*47/(d*pi)
 // Left real diameter: 0.12808, Right real diameter: 0.121
-#define STEP_PER_M 5770.8
+#define STEP_PER_M 5573.0
 #define STEP_PER_M_LEFT (STEP_PER_M)
 #define STEP_PER_M_RIGHT (STEP_PER_M)
 #define WHEEL_DIST 0.39912 // Measured: 0.252
 #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);
@@ -187,13 +191,13 @@ ISR(TWI_vect)
        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;
@@ -378,10 +382,10 @@ ISR(TWI_vect)
                                default:
                                        TWI_NAK;
                        }
-                       ireg++;
+                       if (ireg < 0xff) 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;
@@ -615,6 +619,9 @@ ISR(TWI_vect)
                        }
                        ireg++;
                        break;
+               case TW_SR_STOP:
+                       TWI_ACK;
+                       break;
                default:
                        TWI_RESET;
        }
@@ -899,25 +906,25 @@ static void update_pid(void) {
        static int32_t esum4=0;
 
        // protect motors from damage if stalling
-       if (labs(esum1) > 140000 && speed1 == 0) {
+       if (labs(esum1) > STALL_LIMIT && speed1 == 0) {
                motor1 = 0;
                motor1_mode = MOTOR_MANUAL;
                error_state |= (1<<4);
                esum1 = 0;
        }       
-       if (labs(esum2) > 140000 && speed2 == 0) {
+       if (labs(esum2) > STALL_LIMIT && speed2 == 0) {
                motor2 = 0;
                motor2_mode = MOTOR_MANUAL;
                error_state |= (1<<5);
                esum2 = 0;
        }       
-       if (labs(esum3) > 140000 && speed3 == 0) {
+       if (labs(esum3) > STALL_LIMIT && speed3 == 0) {
                motor3 = 0;
                motor3_mode = MOTOR_MANUAL;
                error_state |= (1<<6);
                esum3 = 0;
        }       
-       if (labs(esum4) > 140000 && speed4 == 0) {
+       if (labs(esum4) > STALL_LIMIT && speed4 == 0) {
                motor4 = 0;
                motor4_mode = MOTOR_MANUAL;
                error_state |= (1<<7);
@@ -930,7 +937,8 @@ static void update_pid(void) {
                        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);
@@ -952,7 +960,8 @@ static void update_pid(void) {
                        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);
@@ -974,7 +983,8 @@ static void update_pid(void) {
                        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);
@@ -996,7 +1006,8 @@ static void update_pid(void) {
                        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);
@@ -1040,11 +1051,11 @@ int main(void) {
 
        // I2C
        TWAR = 0x50;
-       TWI_RESET;
+       TWI_ACK;
 
        // Motor 1 & 2
-       // Also used for PWM frequency TIMER1_FREQ
-       // Timer 1: Fast PWM non-inverting mode, Top=255 => 15.625kHz
+       // Also used for PWM frequency TIMER1_FREQ (F_CPU/256)
+       // Timer 1: Fast PWM non-inverting mode, Top=255 => 19.531kHz
        // Prescaler=1
        //TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10);
        // Avoid narrow spike on extreme pwm value 0 by not setting COM1*1
@@ -1081,10 +1092,11 @@ int main(void) {
                        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;
                }
@@ -1125,7 +1137,7 @@ int main(void) {
                        motor4_mode = MOTOR_PID;
                }
 
-               if (run_update >= 156) { // TIMER1_FREQ/156 = ~100Hz
+               if (run_update >= 195) { // TIMER1_FREQ/195 = ~100Hz
                        run_update=0;
 
                        update_pos();