use LEDs for status output

This commit is contained in:
Olaf Rempel 2008-02-17 18:17:28 +01:00
parent 8434c011c8
commit 9e0763b332
6 changed files with 117 additions and 40 deletions

View File

@ -19,7 +19,7 @@ OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump OBJDUMP = avr-objdump
SIZE = avr-size SIZE = avr-size
all: $(PRG).elf lst text eeprom all: $(PRG).elf lst text
$(SIZE) -x -A $(PRG).elf $(SIZE) -x -A $(PRG).elf
$(PRG).elf: $(OBJ) $(PRG).elf: $(OBJ)

27
blmc.c
View File

@ -24,6 +24,7 @@
struct blmc_ blmc; struct blmc_ blmc;
/* Analog Comparator Channel */
static uint8_t next_sense; static uint8_t next_sense;
void trigger_adc(uint8_t channel) void trigger_adc(uint8_t channel)
@ -155,22 +156,23 @@ void spinup(void)
*/ */
void setpwm(uint8_t pwm) 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) if (blmc.pwm == 0)
blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP; blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
blmc.pwm = pwm;
} else { } else {
blmc.flags = 0x00; blmc.flags &= ~FLAG_RUN_MASK;
blmc.pwm = 0; pwm = 0;
} }
/* do spinup with small pwm */ /* do spinup with small pwm */
if (blmc.flags & FLAG_PWM_SPINUP) if (blmc.flags & FLAG_PWM_SPINUP)
pwm = 0x0f; pwm = 0x0f;
else
pwm = blmc.pwm; /* save pwm value */
blmc.pwm = pwm;
/* raise current limit, TODO: magic value */ /* raise current limit, TODO: magic value */
if (blmc.current > 120) if (blmc.current > 120)
@ -180,6 +182,13 @@ void setpwm(uint8_t pwm)
else if (blmc.pwm_limit > 0) else if (blmc.pwm_limit > 0)
blmc.pwm_limit--; 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) if (blmc.pwm_limit > pwm)
blmc.pwm_limit = pwm; blmc.pwm_limit = pwm;
@ -221,7 +230,7 @@ ISR(ADC_vect)
current_tmp = 0; current_tmp = 0;
current_cnt = 0; current_cnt = 0;
} }
// TODO: ueberstrom-abschaltung // TODO: overcurrent shutdown
} else { } else {
voltage_tmp += value; voltage_tmp += value;
@ -231,6 +240,6 @@ ISR(ADC_vect)
voltage_tmp = 0; voltage_tmp = 0;
voltage_cnt = 0; voltage_cnt = 0;
} }
// TODO: unterspannungs-abschaltung // TODO: undervoltage shutdown
} }
} }

21
blmc.h
View File

@ -20,21 +20,30 @@
#define SENSE_VOLTAGE 3 #define SENSE_VOLTAGE 3
#define SENSE_CURRENT 6 #define SENSE_CURRENT 6
#define FLAG_PWM_SPINUP 0x01 #define FLAG_RUN_MASK 0x00F
#define FLAG_PWM_NORMAL 0x02 #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_SOFTERR_MASK 0x0F0
#define FLAG_COM_NORMAL 0x20 #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_ { struct blmc_ {
uint8_t flags; uint16_t flags;
uint8_t pwm; // pwm setpoint uint8_t pwm; // pwm setpoint
uint8_t pwm_limit; // increased by current-limit uint8_t pwm_limit; // increased by current-limit
uint16_t rpm; uint16_t rpm;
uint16_t rpm_tmp; uint16_t rpm_tmp;
uint16_t rpm_tmp2; uint16_t rpm_tmp_old;
uint16_t current; uint16_t current;
uint16_t voltage; uint16_t voltage;

View File

@ -33,7 +33,7 @@ extern struct blmc_ blmc;
// #define CMD_GET_PARAM 0x24 // #define CMD_GET_PARAM 0x24
#define CMD_BOOT_LOADER 0x2F #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) ISR(TWI_vect)
{ {

100
main.c
View File

@ -17,19 +17,15 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
/* /*
* Application: * Status LED_GN LED_RT
* LED_GN blinking -> motor stop * No Error, Motor off ON -
* LED_GN on -> motor running * No Error, Motor spinup FAST -
* LED_GN on & LED_RT blinking -> pwm soft limit * No Error, Motor running SLOW -
* LED_GN off & LED_RT blinking -> current to high / undervoltage * Current Limit - ON
* * i2c Timeout - ON (not implemented yet)
* startup: * Undervoltage OFF SLOW (not implemented yet)
* - selftest * Overcurrent (Hard Limit) OFF FAST (not implemented yet)
* * SELFTEST failed SLOW SLOW (not implemented yet)
* cmdloop:
* - set motor (pwm)
* - get status (motor speed, voltage, current)
* - reboot (with cookie)
*/ */
#include <avr/io.h> #include <avr/io.h>
@ -40,6 +36,8 @@
extern struct blmc_ blmc; extern struct blmc_ blmc;
static uint8_t led[2];
ISR(TIMER0_OVF_vect) ISR(TIMER0_OVF_vect)
{ {
static uint8_t timer0_cnt = 0; static uint8_t timer0_cnt = 0;
@ -48,16 +46,17 @@ ISR(TIMER0_OVF_vect)
/* Come back in 20ms */ /* Come back in 20ms */
TCNT0 = 0xFF - 156; TCNT0 = 0xFF - 156;
/* current-limiting */ /* commutations during last 20ms */
setpwm(blmc.pwm); 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; /* too few commutations while running -> do a spinup */
blmc.rpm_tmp2 = blmc.rpm_tmp; if (diff < 0x8 && (blmc.flags & FLAG_RUN_MASK) == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL))
/* too low rpm while running -> do a spinup */
if (diff < 0x8 && blmc.flags == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL))
blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP; blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
/* set pwm again (adjust current limit) */
setpwm(blmc.pwm);
/* calc rpm every second */ /* calc rpm every second */
timer0_cnt++; timer0_cnt++;
if (timer0_cnt == 50) { if (timer0_cnt == 50) {
@ -75,6 +74,30 @@ ISR(TIMER0_OVF_vect)
else else
adc_chan = SENSE_CURRENT; 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) int main(void)
@ -82,7 +105,7 @@ int main(void)
DDRB = PHASE_H_MASK | LED_RT | LED_GN; DDRB = PHASE_H_MASK | LED_RT | LED_GN;
DDRD = PHASE_L_MASK; DDRD = PHASE_L_MASK;
PORTB = LED_GN; PORTB = 0x00;
PORTD = 0x00; PORTD = 0x00;
/* timer0: running with F_CPU/1024 */ /* timer0: running with F_CPU/1024 */
@ -96,7 +119,7 @@ int main(void)
TCCR2 = (1<<WGM20) | (1<<CS20); TCCR2 = (1<<WGM20) | (1<<CS20);
/* enable Timer0 OVF Interrupt */ /* enable Timer0 OVF Interrupt */
TIMSK = (1<<TOIE0); // | (1<<OCIE2); // | (1<<TOIE2) TIMSK = (1<<TOIE0);
/* Enable Analog Comparator Multiplexer */ /* Enable Analog Comparator Multiplexer */
SFIOR |= (1<<ACME); SFIOR |= (1<<ACME);
@ -104,12 +127,43 @@ int main(void)
/* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */ /* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */
TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE); TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
blmc.flags = 0x00;
sei(); sei();
while (1) { while (1) {
/* get motor status: spinup, running or off */
if (blmc.flags & FLAG_RUN_MASK) {
if (blmc.flags & (FLAG_COM_SPINUP | FLAG_PWM_SPINUP))
led[0] = LED_FAST;
else
led[0] = LED_SLOW;
} else {
led[0] = LED_ON;
}
/* soft errors (current limit, i2c timeout) */
if (blmc.flags & FLAG_SOFTERR_MASK)
led[1] = LED_ON;
/* hard errors */
if (blmc.flags & FLAG_HARDERR_MASK) {
led[0] = LED_OFF;
if (blmc.flags & FLAG_CURRENTLIMIT) {
led[1] = LED_FAST;
} else if (blmc.flags & FLAG_UNDERVOLTAGE) {
led[1] = LED_SLOW;
} else if (blmc.flags & FLAG_SELFTESTFAILED) {
led[0] = LED_SLOW;
led[1] = LED_SLOW;
}
}
/* do a spinup from main loop (blocking for > 200ms) */
if (blmc.flags & FLAG_COM_SPINUP) if (blmc.flags & FLAG_COM_SPINUP)
spinup(); spinup();
}; };
return 0; return 0;
} }

5
main.h
View File

@ -9,4 +9,9 @@
#define LED_RT (1<<PORTB4) #define LED_RT (1<<PORTB4)
#define LED_GN (1<<PORTB5) #define LED_GN (1<<PORTB5)
#define LED_OFF 0x00
#define LED_SLOW 0x01
#define LED_FAST 0x10
#define LED_ON 0x11
#endif #endif