Compare commits

..

9 Commits

Author SHA1 Message Date
27b32bd462 working version 2011-01-25 13:43:30 +01:00
d755d1382e new i2c protocol 2011-01-22 17:51:58 +01:00
f35be86a71 missing rename 2008-06-23 20:23:04 +02:00
e473216eba added schematic and board files 2008-06-23 13:44:54 +02:00
e4f6fd2d36 use timer1 icp 2008-06-22 23:46:52 +02:00
d05f1de3b1 fix ADC ref, cleanup, brake added 2008-06-22 21:22:03 +02:00
efd7ebbe36 cleanup and little endian status format 2008-06-22 21:21:23 +02:00
77fa66a6d9 disable watchdog after reset 2008-06-21 15:40:07 +02:00
639c0e9bb9 mega88 version 2008-06-21 14:34:57 +02:00
18 changed files with 175 additions and 116 deletions

View File

@ -1,6 +1,6 @@
PRG = blmc PRG = blmc
OBJ = blmc.o eeprom.o i2c-slave.o main.o OBJ = blmc.o eeprom.o i2c-slave.o main.o
MCU_TARGET = atmega8 MCU_TARGET = atmega88
OPTIMIZE = -Os OPTIMIZE = -Os
DEFS = DEFS =
@ -61,4 +61,4 @@ ebin: $(PRG)_eeprom.bin
install: text install: text
# uisp -dprog=avr910 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=M8 --erase --upload if=$(PRG).hex # uisp -dprog=avr910 -dserial=/dev/ttyS0 -dspeed=115200 -dpart=M8 --erase --upload if=$(PRG).hex
avrdude -p m8 -c butterfly -b 115200 -P /dev/ttyUSB1 -u -e -V -U flash:w:$(PRG).hex avrdude -p m88 -c butterfly -b 115200 -u -e -V -U flash:w:$(PRG).hex

9
README
View File

@ -1,8 +1,11 @@
blmc v1 blmc v2
======= =======
An AVR mega8 based brushless motor controller. An AVR mega88/168 based brushless motor controller.
- SW/HW and i2c protocol are *NOT* compatible with H+I blctrl!
- must run with TWIBOOT as bootloader to get own i2c address - must run with TWIBOOT as bootloader to get own i2c address
- spinup parameters in EEPROM - spinup parameters in EEPROM
- extended i2c protocol - extended i2c protocol
TODO:
- remove C1/C3/C6 and do "timed" commutation
- replace C11 with smaller value / remove it

120
blmc.c
View File

@ -31,67 +31,86 @@ static uint8_t next_sense;
void trigger_adc(uint8_t channel) void trigger_adc(uint8_t channel)
{ {
/* Disable Analog Comperator */ /* Disable Analog Comperator Interrupt */
ACSR &= ~(1<<ACIE); TIMSK1 &= ~(1<<ICIE1);
/* set channel (Internal reference, 2.56V) */ /* set channel (external reference, 5V) */
ADMUX = (1<<REFS1) | (1<<REFS0) | channel; ADMUX = (0<<REFS1) | (0<<REFS0) | channel;
/* turn on ADC with interrupts, start conversion with 1/32 of F_CPU */ /*
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADIF)| (1<<ADPS2) | (1<<ADPS0); * turn on ADC with interrupts
* start conversion with 1/32 of F_CPU
* 1/250kHz * 25 => 100us conversion time
*/
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;
/* Disable Analog Comperator */ /* Disable Analog Comperator Interrupt */
ACSR &= ~(1<<ACIE); TIMSK1 &= ~(1<<ICIE1);
TCNT1 = 0x00;
TCNT2 = 0x00;
switch (phase) { switch (phase) {
case 0: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_B_L; case 0: /* A: PWM, B: LOW, C: SENSE => disable EN_C, disable PWM_B, enable EN_B */
TCCR1A = (TCCR1A & ~(1<<COM1B1)) | (1<<COM1A1); PORTD &= ~PHASE_C_EN;
TCCR2 &= ~(1<<COM21); TCCR0A &= ~PHASE_B_OC;
ACSR = (1<<ACIS1); PORTD |= PHASE_B_EN;
/* C: falling edge */
TCCR1B &= ~(1<<ICES1);
next_sense = SENSE_C; next_sense = SENSE_C;
break; break;
case 1: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_B_L; case 1: /* A: SENSE, B: LOW, C: PWM => disable EN_A, enable PWM_C, enable EN_C */
TCCR1A &= ~((1<<COM1A1) | (1<<COM1B1)); PORTB &= ~PHASE_A_EN;
TCCR2 |= (1<<COM21); TCCR2A |= PHASE_C_OC;
ACSR = (1<<ACIS1) | (1<<ACIS0); PORTD |= PHASE_C_EN;
/* A: rising edge */
TCCR1B |= (1<<ICES1);
next_sense = SENSE_A; next_sense = SENSE_A;
break; break;
case 2: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_A_L; case 2: /* A: LOW, B: SENSE, C: PWM => disable EN_B, disable PWM_A, enable EN_A */
TCCR1A &= ~((1<<COM1A1) | (1<<COM1B1)); PORTD &= ~PHASE_B_EN;
TCCR2 |= (1<<COM21); TCCR2A &= ~PHASE_A_OC;
ACSR = (1<<ACIS1); PORTB |= PHASE_A_EN;
/* B: falling edge */
TCCR1B &= ~(1<<ICES1);
next_sense = SENSE_B; next_sense = SENSE_B;
break; break;
case 3: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_A_L; case 3: /* A: LOW, B: PWM, C: SENSE => disable EN_C, enable PWM_B, enable EN_B */
TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1B1); PORTD &= ~PHASE_C_EN;
TCCR2 &= ~(1<<COM21); TCCR0A |= PHASE_B_OC;
ACSR = (1<<ACIS1) | (1<<ACIS0); PORTD |= PHASE_B_EN;
/* C: rising edge */
TCCR1B |= (1<<ICES1);
next_sense = SENSE_C; next_sense = SENSE_C;
break; break;
case 4: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_C_L; case 4: /* A: SENSE, B: PWM, C: LOW => disable EN_A, disable PWM_C, enable EN_C */
TCCR1A = (TCCR1A & ~(1<<COM1A1)) | (1<<COM1B1); PORTB &= ~PHASE_A_EN;
TCCR2 &= ~(1<<COM21); TCCR2A &= ~PHASE_C_OC;
ACSR = (1<<ACIS1); PORTD |= PHASE_C_EN;
/* A: falling edge */
TCCR1B &= ~(1<<ICES1);
next_sense = SENSE_A; next_sense = SENSE_A;
break; break;
case 5: PORTD = (PORTD & ~PHASE_L_MASK) | PHASE_C_L; case 5: /* A: PWM, B: SENSE, C: LOW => disable EN_B, enable PWM_A, enable EN_A */
TCCR1A = (TCCR1A & ~(1<<COM1B1)) | (1<<COM1A1); PORTD &= ~PHASE_B_EN;
TCCR2 &= ~(1<<COM21); TCCR2A |= PHASE_A_OC;
ACSR = (1<<ACIS1) | (1<<ACIS0); PORTB |= PHASE_A_EN;
/* B: rising edge */
TCCR1B |= (1<<ICES1);
next_sense = SENSE_B; next_sense = SENSE_B;
break; break;
} }
@ -114,8 +133,10 @@ void next_phase(void)
ADMUX = next_sense; ADMUX = next_sense;
/* enable Analog Comparator with Interrupts */ /* enable Analog Comparator with Interrupts */
if (blmc.flags & FLAG_COM_NORMAL) if (blmc.flags & FLAG_COM_NORMAL) {
ACSR |= (1<<ACIE) | (1<<ACI); TIFR1 |= (1<<ICF1);
TIMSK1 |= (1<<ICIE1);
}
} }
phase++; phase++;
@ -207,12 +228,21 @@ void setpwm(uint8_t pwm)
if (pwm > params.pwm_max) if (pwm > params.pwm_max)
pwm = params.pwm_max; pwm = params.pwm_max;
OCR1A = pwm; OCR0B = pwm;
OCR1B = pwm; OCR2A = pwm;
OCR2 = pwm; OCR2B = pwm;
/* disable PWM signales, enable all drivers -> brake */
if (pwm == 0) {
TCCR0A &= ~PHASE_B_OC;
TCCR2A &= ~(PHASE_A_OC | PHASE_C_OC);
PORTB |= PHASE_A_EN;
PORTD |= (PHASE_B_EN | PHASE_C_EN);
}
} }
ISR(ANA_COMP_vect) ISR(TIMER1_CAPT_vect)
{ {
next_phase(); next_phase();
} }
@ -232,8 +262,10 @@ ISR(ADC_vect)
ADCSRA = 0x00; ADCSRA = 0x00;
/* enable Analog Comparator with Interrupts */ /* enable Analog Comparator with Interrupts */
if (blmc.flags & FLAG_COM_NORMAL) if (blmc.flags & FLAG_COM_NORMAL) {
ACSR |= (1<<ACIE) | (1<<ACI); TIFR1 |= (1<<ICF1);
TIMSK1 |= (1<<ICIE1);
}
if (channel == SENSE_CURRENT) { if (channel == SENSE_CURRENT) {
current_tmp += value; current_tmp += value;

2
blmc.h
View File

@ -1,6 +1,8 @@
#ifndef _BLMC_H_ #ifndef _BLMC_H_
#define _BLMC_H_ #define _BLMC_H_
#include <avr/io.h>
#define FLAG_RUN_MASK 0x00F #define FLAG_RUN_MASK 0x00F
#define FLAG_PWM_SPINUP 0x001 #define FLAG_PWM_SPINUP 0x001
#define FLAG_PWM_NORMAL 0x002 #define FLAG_PWM_NORMAL 0x002

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

BIN
eagle/blmc-v2-bot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
eagle/blmc-v2-sch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
eagle/blmc-v2-top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
eagle/blmc.brd Normal file

Binary file not shown.

Binary file not shown.

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] = "blmc m8-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 */
@ -161,16 +148,32 @@ ISR(TWI_vect)
switch (cmd) { switch (cmd) {
case CMD_WAIT: case CMD_WAIT:
switch (bcnt++) { switch (bcnt++) {
case 0: case 0: data = blmc.pwm - blmc.pwm_limit;
data = blmc.current & 0xFF;
break; break;
case 1: case 1: data = blmc.pwm;
data = 0xFF - blmc.pwm_limit; 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; break;
default: default:
data = 0xFF; data = 0x00;
break; break;
} }
break; break;
@ -192,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;
} }
} }

60
main.c
View File

@ -46,13 +46,13 @@ extern struct blmc_ blmc;
static uint8_t led[2]; static uint8_t led[2];
ISR(TIMER0_OVF_vect) ISR(TIMER1_COMPB_vect)
{ {
static uint8_t timer0_cnt = 0; static uint8_t rpm_cnt = 0;
static uint8_t adc_chan = SENSE_CURRENT; static uint8_t adc_chan = SENSE_CURRENT;
/* Come back in 20ms */ /* Come back in 20ms */
TCNT0 = 0xFF - 156; OCR1B = TCNT1 + 20000;
/* commutations during last 20ms */ /* commutations during last 20ms */
uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old; uint16_t diff = blmc.rpm_tmp - blmc.rpm_tmp_old;
@ -64,7 +64,7 @@ ISR(TIMER0_OVF_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 */
@ -76,7 +76,7 @@ ISR(TIMER0_OVF_vect)
} else { } else {
blmc.flags &= ~FLAG_I2C_TIMEOUT; blmc.flags &= ~FLAG_I2C_TIMEOUT;
} }
#endif
blmc.flags &= ~FLAG_I2C_ACTIVE; blmc.flags &= ~FLAG_I2C_ACTIVE;
} }
@ -84,9 +84,9 @@ ISR(TIMER0_OVF_vect)
setpwm(blmc.pwm); setpwm(blmc.pwm);
/* calc rpm every second */ /* calc rpm every second */
timer0_cnt++; rpm_cnt++;
if (timer0_cnt == 50) { if (rpm_cnt == 50) {
timer0_cnt = 0; rpm_cnt = 0;
blmc.rpm = blmc.rpm_tmp; blmc.rpm = blmc.rpm_tmp;
blmc.rpm_tmp = 0; blmc.rpm_tmp = 0;
@ -100,7 +100,6 @@ ISR(TIMER0_OVF_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;
@ -126,29 +125,49 @@ ISR(TIMER0_OVF_vect)
} }
} }
/*
* 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<<WDCE) | (0<<WDE);
}
int main(void) int main(void)
{ {
DDRB = PHASE_H_MASK | LED_RT | LED_GN; DDRB = PHASE_A_EN | PHASE_A_PWM | LED_RT | LED_GN;
DDRD = PHASE_L_MASK; DDRD = PHASE_B_EN | PHASE_B_PWM | PHASE_C_EN | PHASE_C_PWM;
PORTB = 0x00; PORTB = 0x00;
PORTD = 0x00; PORTD = 0x00;
/* timer0: running with F_CPU/1024 */ /* timer0: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
TCCR0 = (1<<CS02) | (1<<CS00); TCCR0A = (1<<WGM00);
TCCR0B = (1<<CS00);
/* timer1: running with F_CPU, 8bit Phase Correct PWM (16kHz) */ /* timer1: running with F_CPU/8 */
TCCR1B = (1<<CS10); TCCR1B = (1<<CS11) | (1<<ICNC1);
TCCR1A = (1<<WGM10);
/* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */ /* timer2: running with F_CPU, 8bit Phase Correct PWM (16kHz) */
TCCR2 = (1<<WGM20) | (1<<CS20); TCCR2A = (1<<WGM20);
TCCR2B = (1<<CS20);
/* enable Timer0 OVF Interrupt */ /* sync PWM timers */
TIMSK = (1<<TOIE0); GTCCR = (1<<TSM) | (1<<PSRASY) | (1<<PSRSYNC);
TCNT0 = 0x00;
TCNT2 = 0x00;
GTCCR = (0<<TSM);
/* enable Timer1 OVF Interrupt */
TIMSK1 = (1<<OCIE1B);
/* Enable Analog Comparator Multiplexer */ /* Enable Analog Comparator Multiplexer */
SFIOR |= (1<<ACME); ADCSRB |= (1<<ACME);
ACSR |= (1<<ACIC);
/* 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);
@ -210,5 +229,6 @@ int main(void)
sleep_mode(); sleep_mode();
}; };
return 0; return 0;
} }

26
main.h
View File

@ -9,21 +9,23 @@
#define LED_RT (1<<PORTB4) #define LED_RT (1<<PORTB4)
#define LED_GN (1<<PORTB5) #define LED_GN (1<<PORTB5)
#define PHASE_A_H (1<<PORTB1) #define PHASE_A_EN (1<<PORTB2)
#define PHASE_B_H (1<<PORTB2) #define PHASE_A_PWM (1<<PORTB3)
#define PHASE_C_H (1<<PORTB3) #define PHASE_A_OC (1<<COM2A1)
#define PHASE_H_MASK (PHASE_A_H | PHASE_B_H | PHASE_C_H)
#define PHASE_A_L (1<<PORTD4) #define PHASE_B_EN (1<<PORTD7)
#define PHASE_B_L (1<<PORTD3) #define PHASE_B_PWM (1<<PORTD5)
#define PHASE_C_L (1<<PORTD2) #define PHASE_B_OC (1<<COM0B1)
#define PHASE_L_MASK (PHASE_A_L | PHASE_B_L | PHASE_C_L)
#define PHASE_C_EN (1<<PORTD4)
#define PHASE_C_PWM (1<<PORTD3)
#define PHASE_C_OC (1<<COM2B1)
#define SENSE_A 0 #define SENSE_A 0
#define SENSE_B 1 #define SENSE_B 2
#define SENSE_C 2 #define SENSE_C 1
#define SENSE_VOLTAGE 3 #define SENSE_VOLTAGE 7
#define SENSE_CURRENT 6 #define SENSE_CURRENT 3
#endif #endif