working version

This commit is contained in:
Olaf Rempel 2011-01-25 13:43:30 +01:00
parent d755d1382e
commit 27b32bd462
5 changed files with 63 additions and 47 deletions

14
blmc.c
View File

@ -39,13 +39,13 @@ void trigger_adc(uint8_t channel)
/* /*
* turn on ADC with interrupts * turn on ADC with interrupts
* start conversion with 1/16 of F_CPU * start conversion with 1/32 of F_CPU
* 1/500kHz * 25 => 50us conversion time * 1/250kHz * 25 => 100us conversion time
*/ */
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADIF)| (1<<ADPS2) | (0<<ADPS0); ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADIF)| (1<<ADPS2) | (0<<ADPS0);
} }
void next_phase(void) static void next_phase(void)
{ {
static uint8_t phase; static uint8_t phase;
static uint8_t phase_adc; static uint8_t phase_adc;
@ -53,9 +53,6 @@ void next_phase(void)
/* Disable Analog Comperator Interrupt */ /* Disable Analog Comperator Interrupt */
TIMSK1 &= ~(1<<ICIE1); TIMSK1 &= ~(1<<ICIE1);
TCNT0 = 0x00;
TCNT2 = 0x00;
switch (phase) { switch (phase) {
case 0: /* A: PWM, B: LOW, C: SENSE => disable EN_C, disable PWM_B, enable EN_B */ case 0: /* A: PWM, B: LOW, C: SENSE => disable EN_C, disable PWM_B, enable EN_B */
PORTD &= ~PHASE_C_EN; PORTD &= ~PHASE_C_EN;
@ -235,11 +232,8 @@ void setpwm(uint8_t pwm)
OCR2A = pwm; OCR2A = pwm;
OCR2B = pwm; OCR2B = pwm;
/* disable all drivers */ /* disable PWM signales, enable all drivers -> brake */
if (pwm == 0) { if (pwm == 0) {
PORTB &= ~PHASE_A_EN;
PORTD &= ~(PHASE_B_EN | PHASE_C_EN);
TCCR0A &= ~PHASE_B_OC; TCCR0A &= ~PHASE_B_OC;
TCCR2A &= ~(PHASE_A_OC | PHASE_C_OC); TCCR2A &= ~(PHASE_A_OC | PHASE_C_OC);

View File

@ -16,11 +16,12 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include <avr/pgmspace.h>
#include <avr/eeprom.h> #include <avr/eeprom.h>
#include <util/crc16.h> #include <util/crc16.h>
#include "eeprom.h" #include "eeprom.h"
static const struct ee_param defaults = DEFAULT_PARAMETERS; static struct ee_param defaults PROGMEM = DEFAULT_PARAMETERS;
struct ee_param params; struct ee_param params;
struct ee_param params_in_eeprom EEMEM = DEFAULT_PARAMETERS; struct ee_param params_in_eeprom EEMEM = DEFAULT_PARAMETERS;
@ -48,12 +49,7 @@ uint8_t read_parameters(void)
crc = _crc_ccitt_update(crc, *tmp++); crc = _crc_ccitt_update(crc, *tmp++);
if (crc != 0x0000) { if (crc != 0x0000) {
i = sizeof(struct ee_param); memcpy_P(&params, &defaults, sizeof(struct ee_param));
uint8_t *src = (uint8_t *)&defaults;
uint8_t *dst = (uint8_t *)&params;
while (i--)
*dst++ = *src++;
write_parameters(); write_parameters();
return 1; return 1;
} }

View File

@ -22,16 +22,17 @@ struct ee_param {
}; };
#define DEFAULT_PARAMETERS { \ #define DEFAULT_PARAMETERS { \
.spinup_ticks = 1000, \ .spinup_ticks = 2000, \
.spinup_tick = 25, \ .spinup_tick = 24, \
.spinup_step = 24, \ .spinup_step = 4, \
.spinup_wait = 10, \ .spinup_wait = 10, \
.spinup_pwm = 0x0f, \ .spinup_pwm = 25, \
.pwm_min = 0x08, \ .pwm_min = 0x08, \
.pwm_max = 0xff, \ .pwm_max = 0xff, \
.current_limit = 120, \ .current_limit = 120, \
.current_max = 0x3ff, \ .current_max = 0x3ff, \
.voltage_min = 0x000, \ .voltage_min = 0x000, \
.crc16 = 0xDB76, \
}; };
uint8_t read_parameters(void); uint8_t read_parameters(void);

View File

@ -61,20 +61,19 @@ extern struct ee_param params;
const static uint8_t info[16] = "blctrl m88-v1.2"; const static uint8_t info[16] = "blctrl m88-v2.0";
ISR(TWI_vect) ISR(TWI_vect)
{ {
static uint8_t cmd; static uint8_t cmd;
static uint8_t bcnt; static uint8_t bcnt;
uint8_t data; uint8_t data;
uint8_t ack = (1<<TWEA);
switch (TWSR & 0xF8) { switch (TWSR & 0xF8) {
/* SLA + W received, ACK returned -> receive Data and ACK */ /* SLA + W received, ACK returned -> receive Data and ACK */
case 0x60: case 0x60:
bcnt = 0; bcnt = 0;
TWCR |= (1<<TWINT) | (1<<TWEA); TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
break; break;
/* prev. SLA + W, data received, ACK returned -> receive Data and ACK */ /* prev. SLA + W, data received, ACK returned -> receive Data and ACK */
@ -103,9 +102,6 @@ ISR(TWI_vect)
case CMD_SWITCH_APPLICATION: case CMD_SWITCH_APPLICATION:
if (data == BOOTTYPE_BOOTLOADER) { if (data == BOOTTYPE_BOOTLOADER) {
wdt_enable(WDTO_15MS); wdt_enable(WDTO_15MS);
} else {
ack = (0<<TWEA);
} }
break; break;
@ -113,14 +109,10 @@ ISR(TWI_vect)
bcnt++; bcnt++;
if (data == MEMTYPE_PARAMETERS) { if (data == MEMTYPE_PARAMETERS) {
cmd = CMD_WRITE_PARAMETERS; cmd = CMD_WRITE_PARAMETERS;
} else {
ack = (0<<TWEA);
} }
break; break;
default: default:
ack = (0<<TWEA);
break; break;
} }
break; break;
@ -136,21 +128,16 @@ ISR(TWI_vect)
((uint8_t *)&params)[bcnt++ -4] = data; ((uint8_t *)&params)[bcnt++ -4] = data;
if (bcnt == sizeof(params)) { if (bcnt == sizeof(params)) {
write_parameters(); write_parameters();
ack = (0<<TWEA);
} }
break; break;
default: default:
ack = (0<<TWEA);
break; break;
} }
break; break;
} }
if (ack == 0x00) TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
bcnt = 0;
TWCR |= (1<<TWINT) | ack;
break; break;
/* SLA+R received, ACK returned -> send data */ /* SLA+R received, ACK returned -> send data */
@ -160,7 +147,35 @@ ISR(TWI_vect)
case 0xB8: case 0xB8:
switch (cmd) { switch (cmd) {
case CMD_WAIT: case CMD_WAIT:
data = 0x00; /* TODO: transmit Current and MaxPWM */ switch (bcnt++) {
case 0: data = blmc.pwm - blmc.pwm_limit;
break;
case 1: data = blmc.pwm;
break;
case 2: data = (blmc.rpm & 0xFF);
break;
case 3: data = (blmc.rpm >> 8);
break;
case 4: data = (blmc.current & 0xFF);
break;
case 5: data = (blmc.current >> 8);
break;
case 6: data = (blmc.voltage & 0xFF);
break;
case 7: data = (blmc.voltage >> 8);
break;
default:
data = 0x00;
break;
}
break; break;
case CMD_READ_VERSION: case CMD_READ_VERSION:
@ -180,19 +195,19 @@ ISR(TWI_vect)
} }
TWDR = data; TWDR = data;
TWCR |= (1<<TWINT) | (1<<TWEA); TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
break; break;
/* STOP or repeated START */ /* STOP or repeated START */
case 0xA0: case 0xA0:
/* Data transmitted, NACK returned */ /* Data transmitted, NACK returned */
case 0xC0: case 0xC0:
TWCR |= (1<<TWINT) | (1<<TWEA); TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA);
break; break;
/* failsave -> reset Hardware */ /* failsave -> reset Hardware */
default: default:
TWCR |= (1<<TWINT) | (1<<TWSTO) | (1<<TWEA); TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWSTO) | (1<<TWEA);
break; break;
} }
} }

22
main.c
View File

@ -31,6 +31,7 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/sleep.h>
#include "main.h" #include "main.h"
#include "blmc.h" #include "blmc.h"
@ -63,7 +64,7 @@ ISR(TIMER1_COMPB_vect)
blmc.flags &= ~(FLAG_RUN_MASK); blmc.flags &= ~(FLAG_RUN_MASK);
blmc.flags |= FLAG_PWM_SPINUP | FLAG_COM_SPINUP; blmc.flags |= FLAG_PWM_SPINUP | FLAG_COM_SPINUP;
} }
#if 0
/* no i2c cmd in the last 20ms */ /* no i2c cmd in the last 20ms */
if (!(blmc.flags & FLAG_I2C_ACTIVE)) { if (!(blmc.flags & FLAG_I2C_ACTIVE)) {
/* already in i2c timeout, turn off motor */ /* already in i2c timeout, turn off motor */
@ -75,9 +76,8 @@ ISR(TIMER1_COMPB_vect)
} else { } else {
blmc.flags &= ~FLAG_I2C_TIMEOUT; blmc.flags &= ~FLAG_I2C_TIMEOUT;
} }
#endif
// TODO: currently disabled blmc.flags &= ~FLAG_I2C_ACTIVE;
// blmc.flags &= ~FLAG_I2C_ACTIVE;
} }
/* set pwm again (adjust current limit) */ /* set pwm again (adjust current limit) */
@ -100,7 +100,6 @@ ISR(TIMER1_COMPB_vect)
else else
adc_chan = SENSE_CURRENT; adc_chan = SENSE_CURRENT;
} }
/* led blink timer */ /* led blink timer */
static uint8_t led_timer = 0; static uint8_t led_timer = 0;
led_timer = (led_timer +1) & 0x1F; led_timer = (led_timer +1) & 0x1F;
@ -151,12 +150,18 @@ int main(void)
TCCR0B = (1<<CS00); TCCR0B = (1<<CS00);
/* timer1: running with F_CPU/8 */ /* timer1: running with F_CPU/8 */
TCCR1B = (1<<CS11); TCCR1B = (1<<CS11) | (1<<ICNC1);
/* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */ /* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
TCCR2A = (1<<WGM20); TCCR2A = (1<<WGM20);
TCCR2B = (1<<CS20); TCCR2B = (1<<CS20);
/* sync PWM timers */
GTCCR = (1<<TSM) | (1<<PSRASY) | (1<<PSRSYNC);
TCNT0 = 0x00;
TCNT2 = 0x00;
GTCCR = (0<<TSM);
/* enable Timer1 OVF Interrupt */ /* enable Timer1 OVF Interrupt */
TIMSK1 = (1<<OCIE1B); TIMSK1 = (1<<OCIE1B);
@ -171,6 +176,8 @@ int main(void)
if (read_parameters()) if (read_parameters())
blmc.flags |= FLAG_INVALID_EEPROM; blmc.flags |= FLAG_INVALID_EEPROM;
set_sleep_mode(SLEEP_MODE_IDLE);
sei(); sei();
while (1) { while (1) {
@ -219,6 +226,9 @@ int main(void)
/* do a spinup from main loop (blocking for > 200ms) */ /* do a spinup from main loop (blocking for > 200ms) */
if (blmc.flags & FLAG_COM_SPINUP) if (blmc.flags & FLAG_COM_SPINUP)
spinup(); spinup();
sleep_mode();
}; };
return 0; return 0;
} }