diff --git a/Makefile b/Makefile index 44854dd..62854f7 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ PRG = bl_test -OBJ = blmc.o i2c-slave.o main.o +OBJ = blmc.o eeprom.o i2c-slave.o main.o MCU_TARGET = atmega8 OPTIMIZE = -Os @@ -19,7 +19,7 @@ OBJCOPY = avr-objcopy OBJDUMP = avr-objdump SIZE = avr-size -all: $(PRG).elf lst text +all: $(PRG).elf lst text ehex ebin $(SIZE) -x -A $(PRG).elf $(PRG).elf: $(OBJ) diff --git a/blmc.c b/blmc.c index 0a4b8fd..9f43880 100644 --- a/blmc.c +++ b/blmc.c @@ -21,7 +21,9 @@ #include "main.h" #include "blmc.h" +#include "eeprom.h" +extern struct ee_param params; struct blmc_ blmc; /* Analog Comparator Channel */ @@ -128,22 +130,25 @@ void next_phase(void) */ void spinup(void) { - uint16_t time = 1000; + /* see util/delay.h for details.. */ + uint16_t tick = (((uint16_t)(F_CPU / 3e6)) << 8) * (params.spinup_tick & 0x3F); + + uint16_t time = params.spinup_ticks; while (time > 50) { next_phase(); uint16_t i; for (i = 0; i < time; i++) - _delay_us(25); + _delay_loop_1(tick >> 8); - time -= (time / 24 +1); + time -= (time / params.spinup_step +1); } /* manual spinup complete, analog comperator takes control */ blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_NORMAL; next_phase(); - for (time = 0; time < 10; time++) + for (time = 0; time < params.spinup_wait; time++) _delay_ms(20); /* switch to desired pwm value */ @@ -157,7 +162,7 @@ void spinup(void) void setpwm(uint8_t pwm) { /* run motor *only* if there are no hard errors */ - if (pwm >= 8 && !(blmc.flags & FLAG_HARDERR_MASK)) { + if (pwm >= params.pwm_min && !(blmc.flags & FLAG_HARDERR_MASK)) { /* do a spinup */ if (blmc.pwm == 0) blmc.flags = FLAG_PWM_SPINUP | FLAG_COM_SPINUP; @@ -167,22 +172,22 @@ void setpwm(uint8_t pwm) 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) + /* do spinup with small pwm */ + if (blmc.flags & FLAG_PWM_SPINUP) + pwm = params.spinup_pwm; + + /* raise current-limit */ + if (blmc.current > params.current_limit) blmc.pwm_limit++; - /* lower current limit */ + /* lower current-limit */ else if (blmc.pwm_limit > 0) blmc.pwm_limit--; - /* set soft current flag */ + /* set current-limit flag */ if (blmc.pwm_limit) blmc.flags |= FLAG_CURRENTLIMIT; else @@ -194,6 +199,11 @@ void setpwm(uint8_t pwm) /* set new value */ pwm -= blmc.pwm_limit; + + /* limit pwm */ + if (pwm > params.pwm_max) + pwm = params.pwm_max; + OCR1A = pwm; OCR1B = pwm; OCR2 = pwm; @@ -230,7 +240,9 @@ ISR(ADC_vect) current_tmp = 0; current_cnt = 0; } - // TODO: overcurrent shutdown + + if (value > params.current_max) + blmc.flags |= FLAG_OVERCURRENT; } else { voltage_tmp += value; @@ -239,7 +251,9 @@ ISR(ADC_vect) blmc.voltage = voltage_tmp; voltage_tmp = 0; voltage_cnt = 0; + + if (blmc.voltage < params.voltage_min) + blmc.flags |= FLAG_UNDERVOLTAGE; } - // TODO: undervoltage shutdown } } diff --git a/eeprom.c b/eeprom.c new file mode 100644 index 0000000..d958435 --- /dev/null +++ b/eeprom.c @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 02/2008 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 "eeprom.h" + +#include +#include "main.h" + +static const struct ee_param defaults = DEFAULT_PARAMETERS; + +struct ee_param params; +struct ee_param params_in_eeprom EEMEM; + +void write_parameters(struct ee_param *p) +{ + uint8_t i; + uint16_t crc = 0x0000; + uint8_t *tmp = (uint8_t *)p; + for (i = 0; i < sizeof(params) -2; i++) + crc = _crc_ccitt_update(crc, *tmp++); + + params.crc16 = crc; + eeprom_write_block(&p, ¶ms_in_eeprom, sizeof(params)); +} + +void read_parameters(void) +{ + eeprom_read_block(¶ms, ¶ms_in_eeprom, sizeof(params)); + + uint8_t i; + uint16_t crc = 0x0000; + uint8_t *tmp = (uint8_t *)¶ms; + for (i = 0; i < sizeof(params); i++) + crc = _crc_ccitt_update(crc, *tmp++); + + if (crc != 0x0000) { + i = sizeof(params); + uint8_t *src = (uint8_t *)&defaults; + uint8_t *dst = (uint8_t *)¶ms; + while (i--) + *dst++ = *src++; + + write_parameters((struct ee_param *)¶ms); + } +} diff --git a/eeprom.h b/eeprom.h new file mode 100644 index 0000000..152610d --- /dev/null +++ b/eeprom.h @@ -0,0 +1,40 @@ +#ifndef _EEPROM_PARAMETERS_H_ +#define _EEPROM_PARAMETERS_H_ + +struct ee_param { + uint16_t spinup_ticks; + + uint8_t spinup_tick; + uint8_t spinup_step; + + uint8_t spinup_wait; + uint8_t spinup_pwm; + + uint8_t pwm_min; + uint8_t pwm_max; + + uint16_t current_limit; + uint16_t current_max; + + uint16_t voltage_min; + + uint16_t crc16; +}; + +#define DEFAULT_PARAMETERS { \ + .spinup_ticks = 1000, \ + .spinup_tick = 25, \ + .spinup_step = 24, \ + .spinup_wait = 10, \ + .spinup_pwm = 0x0f, \ + .pwm_min = 0x08, \ + .pwm_max = 0xff, \ + .current_limit = 120, \ + .current_max = 0x3ff, \ + .voltage_min = 0x000, \ +}; + +void read_parameters(void); +void write_parameters(struct ee_param *p); + +#endif diff --git a/main.c b/main.c index 997d10f..21882c6 100644 --- a/main.c +++ b/main.c @@ -33,6 +33,12 @@ #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; @@ -127,6 +133,7 @@ int main(void) /* I2C Init: keep Address from bootloader, Auto ACKs with Interrupts */ TWCR = (1< 200ms) */ if (blmc.flags & FLAG_COM_SPINUP) spinup(); diff --git a/main.h b/main.h index 89f5dd1..fe8af71 100644 --- a/main.h +++ b/main.h @@ -9,9 +9,4 @@ #define LED_RT (1<