diff --git a/Makefile b/Makefile index 14a644e..44854dd 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ OBJCOPY = avr-objcopy OBJDUMP = avr-objdump SIZE = avr-size -all: $(PRG).elf lst text eeprom +all: $(PRG).elf lst text $(SIZE) -x -A $(PRG).elf $(PRG).elf: $(OBJ) diff --git a/blmc.c b/blmc.c index 03d801c..0a4b8fd 100644 --- a/blmc.c +++ b/blmc.c @@ -24,6 +24,7 @@ struct blmc_ blmc; +/* Analog Comparator Channel */ static uint8_t next_sense; void trigger_adc(uint8_t channel) @@ -155,22 +156,23 @@ void spinup(void) */ void setpwm(uint8_t pwm) { - if (pwm >= 8) { + /* run motor *only* if there are no hard errors */ + if (pwm >= 8 && !(blmc.flags & FLAG_HARDERR_MASK)) { + /* do a spinup */ if (blmc.pwm == 0) blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP; - blmc.pwm = pwm; - } else { - blmc.flags = 0x00; - blmc.pwm = 0; + blmc.flags &= ~FLAG_RUN_MASK; + pwm = 0; } /* do spinup with small pwm */ if (blmc.flags & FLAG_PWM_SPINUP) pwm = 0x0f; - else - pwm = blmc.pwm; + + /* save pwm value */ + blmc.pwm = pwm; /* raise current limit, TODO: magic value */ if (blmc.current > 120) @@ -180,6 +182,13 @@ void setpwm(uint8_t pwm) else if (blmc.pwm_limit > 0) blmc.pwm_limit--; + /* set soft current flag */ + if (blmc.pwm_limit) + blmc.flags |= FLAG_CURRENTLIMIT; + else + blmc.flags &= ~FLAG_CURRENTLIMIT; + + /* prevent overflow */ if (blmc.pwm_limit > pwm) blmc.pwm_limit = pwm; @@ -221,7 +230,7 @@ ISR(ADC_vect) current_tmp = 0; current_cnt = 0; } - // TODO: ueberstrom-abschaltung + // TODO: overcurrent shutdown } else { voltage_tmp += value; @@ -231,6 +240,6 @@ ISR(ADC_vect) voltage_tmp = 0; voltage_cnt = 0; } - // TODO: unterspannungs-abschaltung + // TODO: undervoltage shutdown } } diff --git a/blmc.h b/blmc.h index 3f9ddb2..8d308e1 100644 --- a/blmc.h +++ b/blmc.h @@ -20,21 +20,30 @@ #define SENSE_VOLTAGE 3 #define SENSE_CURRENT 6 -#define FLAG_PWM_SPINUP 0x01 -#define FLAG_PWM_NORMAL 0x02 +#define FLAG_RUN_MASK 0x00F +#define FLAG_PWM_SPINUP 0x001 +#define FLAG_PWM_NORMAL 0x002 +#define FLAG_COM_SPINUP 0x004 +#define FLAG_COM_NORMAL 0x008 -#define FLAG_COM_SPINUP 0x10 -#define FLAG_COM_NORMAL 0x20 +#define FLAG_SOFTERR_MASK 0x0F0 +#define FLAG_CURRENTLIMIT 0x010 +#define FLAG_I2CTIMEOUT 0x020 + +#define FLAG_HARDERR_MASK 0xF00 +#define FLAG_UNDERVOLTAGE 0x100 +#define FLAG_OVERCURRENT 0x200 +#define FLAG_SELFTESTFAILED 0x400 struct blmc_ { - uint8_t flags; + uint16_t flags; uint8_t pwm; // pwm setpoint uint8_t pwm_limit; // increased by current-limit uint16_t rpm; uint16_t rpm_tmp; - uint16_t rpm_tmp2; + uint16_t rpm_tmp_old; uint16_t current; uint16_t voltage; diff --git a/i2c-slave.c b/i2c-slave.c index 37e41b4..80d804d 100644 --- a/i2c-slave.c +++ b/i2c-slave.c @@ -33,7 +33,7 @@ extern struct blmc_ blmc; // #define CMD_GET_PARAM 0x24 #define CMD_BOOT_LOADER 0x2F -const static uint8_t info[16] = "blctrl m8-v1.0"; +const static uint8_t info[16] = "blctrl m8-v1.1"; ISR(TWI_vect) { diff --git a/main.c b/main.c index 2699eb5..997d10f 100644 --- a/main.c +++ b/main.c @@ -17,19 +17,15 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* - * Application: - * LED_GN blinking -> motor stop - * LED_GN on -> motor running - * LED_GN on & LED_RT blinking -> pwm soft limit - * LED_GN off & LED_RT blinking -> current to high / undervoltage - * - * startup: - * - selftest - * - * cmdloop: - * - set motor (pwm) - * - get status (motor speed, voltage, current) - * - reboot (with cookie) + * Status LED_GN LED_RT + * No Error, Motor off ON - + * No Error, Motor spinup FAST - + * No Error, Motor running SLOW - + * Current Limit - ON + * i2c Timeout - ON (not implemented yet) + * Undervoltage OFF SLOW (not implemented yet) + * Overcurrent (Hard Limit) OFF FAST (not implemented yet) + * SELFTEST failed SLOW SLOW (not implemented yet) */ #include @@ -40,6 +36,8 @@ extern struct blmc_ blmc; +static uint8_t led[2]; + ISR(TIMER0_OVF_vect) { static uint8_t timer0_cnt = 0; @@ -48,16 +46,17 @@ ISR(TIMER0_OVF_vect) /* Come back in 20ms */ TCNT0 = 0xFF - 156; - /* current-limiting */ - setpwm(blmc.pwm); + /* commutations during last 20ms */ + uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old; + blmc.rpm_tmp_old = blmc.rpm_tmp; - uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp2; - blmc.rpm_tmp2 = blmc.rpm_tmp; - - /* too low rpm while running -> do a spinup */ - if (diff < 0x8 && blmc.flags == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL)) + /* too few commutations while running -> do a spinup */ + if (diff < 0x8 && (blmc.flags & FLAG_RUN_MASK) == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL)) blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP; + /* set pwm again (adjust current limit) */ + setpwm(blmc.pwm); + /* calc rpm every second */ timer0_cnt++; if (timer0_cnt == 50) { @@ -75,6 +74,30 @@ ISR(TIMER0_OVF_vect) else adc_chan = SENSE_CURRENT; } + + /* led blink timer */ + static uint8_t led_timer = 0; + led_timer = (led_timer +1) & 0x1F; + + /* green LED */ + if (((led[0] == LED_SLOW) && (led_timer & 0x10)) || + (led[0] == LED_FAST && (led_timer & 0x04)) || + (led[0] == LED_ON)) { + PORTB |= LED_GN; + + } else { + PORTB &= ~LED_GN; + } + + /* red LED */ + if (((led[1] == LED_SLOW) && !(led_timer & 0x10)) || + (led[1] == LED_FAST && !(led_timer & 0x04)) || + (led[1] == LED_ON)) { + PORTB |= LED_RT; + + } else { + PORTB &= ~LED_RT; + } } int main(void) @@ -82,7 +105,7 @@ int main(void) DDRB = PHASE_H_MASK | LED_RT | LED_GN; DDRD = PHASE_L_MASK; - PORTB = LED_GN; + PORTB = 0x00; PORTD = 0x00; /* timer0: running with F_CPU/1024 */ @@ -96,7 +119,7 @@ int main(void) TCCR2 = (1< 200ms) */ if (blmc.flags & FLAG_COM_SPINUP) spinup(); }; - return 0; } diff --git a/main.h b/main.h index fe8af71..89f5dd1 100644 --- a/main.h +++ b/main.h @@ -9,4 +9,9 @@ #define LED_RT (1<