/*************************************************************************** * Copyright (C) 09/2007 by Olaf Rempel * * razzor@kopf-tisch.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License, * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /* * Status LED_GN LED_RT * No Error, Motor off ON - * No Error, Motor spinup FAST - * No Error, Motor running SLOW - * Current Limit F/S ON * i2c Timeout ON ON * Undervoltage OFF SLOW * Overcurrent (Hard Limit) OFF FAST * SELFTEST failed FAST FAST (not implemented yet) * EEPROM invalid SLOW SLOW */ #include #include #include "main.h" #include "blmc.h" #include "eeprom.h" #define LED_OFF 0x00 #define LED_SLOW 0x01 #define LED_FAST 0x10 #define LED_ON 0x11 extern struct blmc_ blmc; static uint8_t led[2]; ISR(TIMER1_OVF_vect) { static uint8_t rpm_cnt = 0; static uint8_t adc_chan = SENSE_CURRENT; /* Come back in 20ms */ TCNT1 = (0xFFFF - 20000); /* commutations during last 20ms */ uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old; blmc.rpm_tmp_old = blmc.rpm_tmp; if ((blmc.flags & FLAG_RUN_MASK) == (FLAG_PWM_NORMAL | FLAG_COM_NORMAL)) { /* too few commutations while running -> do a spinup */ if (diff < 0x08) { blmc.flags &= ~(FLAG_RUN_MASK); blmc.flags |= FLAG_PWM_SPINUP | FLAG_COM_SPINUP; } /* no i2c cmd in the last 20ms */ if (!(blmc.flags & FLAG_I2C_ACTIVE)) { /* already in i2c timeout, turn off motor */ if (blmc.flags & FLAG_I2C_TIMEOUT) blmc.pwm = 0; blmc.flags |= FLAG_I2C_TIMEOUT; } else { blmc.flags &= ~FLAG_I2C_TIMEOUT; } // TODO: currently disabled // blmc.flags &= ~FLAG_I2C_ACTIVE; } /* set pwm again (adjust current limit) */ setpwm(blmc.pwm); /* calc rpm every second */ rpm_cnt++; if (rpm_cnt == 50) { rpm_cnt = 0; blmc.rpm = blmc.rpm_tmp; blmc.rpm_tmp = 0; } /* trigger adc by hand when not running */ if (!(blmc.flags & FLAG_COM_NORMAL)) { trigger_adc(adc_chan); if (adc_chan == SENSE_CURRENT) adc_chan = SENSE_VOLTAGE; 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; } } /* * For newer devices (mega88) the watchdog timer remains active even after a * system reset. So disable it as soon as possible. * automagically called on startup */ void get_mcusr(void) __attribute__((naked, section(".init3"))); void get_mcusr(void) { MCUSR = 0; WDTCSR = (1< 200ms) */ if (blmc.flags & FLAG_COM_SPINUP) spinup(); }; return 0; }