/*************************************************************************** * 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. * ***************************************************************************/ #include #include #include "main.h" #include "blmc.h" struct blmc_ blmc; /* Analog Comparator Channel */ static uint8_t next_sense; void trigger_adc(uint8_t channel) { /* Disable Analog Comperator */ ACSR &= ~(1< 50) { next_phase(); uint16_t i; for (i = 0; i < time; i++) _delay_us(25); time -= (time / 24 +1); } /* manual spinup complete, analog comperator takes control */ blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_NORMAL; next_phase(); for (time = 0; time < 10; time++) _delay_ms(20); /* switch to desired pwm value */ blmc.flags = FLAG_PWM_NORMAL | FLAG_COM_NORMAL; } /* * sets new pwm value * called from i2c-slave (set new value) and from timer (recalc current limit) */ void setpwm(uint8_t pwm) { /* 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; } else { blmc.flags &= ~FLAG_RUN_MASK; pwm = 0; } /* do spinup with small pwm */ if (blmc.flags & FLAG_PWM_SPINUP) pwm = 0x0f; /* save pwm value */ blmc.pwm = pwm; /* raise current limit, TODO: magic value */ if (blmc.current > 120) blmc.pwm_limit++; /* lower current limit */ 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; /* set new value */ pwm -= blmc.pwm_limit; OCR1A = pwm; OCR1B = pwm; OCR2 = pwm; } ISR(ANA_COMP_vect) { next_phase(); } ISR(ADC_vect) { static uint16_t current_tmp, voltage_tmp; static uint8_t current_cnt, voltage_cnt; uint8_t channel = ADMUX & 0x0F; uint16_t value = ADCW; /* restore channel */ ADMUX = next_sense; /* turn off ADC, disable interrupt */ ADCSRA = 0x00; /* enable Analog Comparator with Interrupts */ if (blmc.flags & FLAG_COM_NORMAL) ACSR |= (1<