From 222f289ab2e6f8c971552847615265bff451ce50 Mon Sep 17 00:00:00 2001 From: Jake <jake.read@cba.mit.edu> Date: Thu, 12 Jul 2018 15:04:49 -0400 Subject: [PATCH] bldc spins, accepts speed commands, now looking for acceleration --- circuit/README.md | 1 + .../atkbldcdriver/Debug/Makefile | 7 ++ .../atkbldcdriver/Debug/makedep.mk | 2 + .../atkbldcdriver/atkbldcdriver.cproj | 6 ++ .../atkbldcdriver/atkbldcdriver/atkhandler.c | 15 ++- embedded/atkbldcdriver/atkbldcdriver/bldc.c | 57 +++++++++++ embedded/atkbldcdriver/atkbldcdriver/bldc.h | 35 +++++++ .../atkbldcdriver/atkbldcdriver/hardware.h | 10 ++ embedded/atkbldcdriver/atkbldcdriver/main.c | 95 ++++++++++++++++--- 9 files changed, 211 insertions(+), 17 deletions(-) create mode 100644 embedded/atkbldcdriver/atkbldcdriver/bldc.c create mode 100644 embedded/atkbldcdriver/atkbldcdriver/bldc.h diff --git a/circuit/README.md b/circuit/README.md index 5d23ea8..a2f06f0 100644 --- a/circuit/README.md +++ b/circuit/README.md @@ -12,6 +12,7 @@ Power is bussed to the board with two M3 Screw Terminals. The board includes roo - label lights - wants one lo-side debug pin! + - for resets etc, pull en to gnd on other side of switch! - might have to go to DRV8320 - newer, available - CSD88548 is CSD88599 but more amps less volts, use these diff --git a/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile b/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile index 55ad9d1..a701f1d 100644 --- a/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile +++ b/embedded/atkbldcdriver/atkbldcdriver/Debug/Makefile @@ -39,6 +39,7 @@ SUBDIRS := C_SRCS += \ ../atkhandler.c \ ../atkport.c \ +../bldc.c \ ../fastmath.c \ ../main.c \ ../pin.c \ @@ -57,6 +58,7 @@ ASM_SRCS += OBJS += \ atkhandler.o \ atkport.o \ +bldc.o \ fastmath.o \ main.o \ pin.o \ @@ -68,6 +70,7 @@ uartport.o OBJS_AS_ARGS += \ atkhandler.o \ atkport.o \ +bldc.o \ fastmath.o \ main.o \ pin.o \ @@ -79,6 +82,7 @@ uartport.o C_DEPS += \ atkhandler.d \ atkport.d \ +bldc.d \ fastmath.d \ main.d \ pin.d \ @@ -90,6 +94,7 @@ uartport.d C_DEPS_AS_ARGS += \ atkhandler.d \ atkport.d \ +bldc.d \ fastmath.d \ main.d \ pin.d \ @@ -130,6 +135,8 @@ LINKER_SCRIPT_DEP+= + + ./%.o: .././%.c @echo Building file: $< diff --git a/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk b/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk index d5a1f4d..0d51b27 100644 --- a/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk +++ b/embedded/atkbldcdriver/atkbldcdriver/Debug/makedep.mk @@ -6,6 +6,8 @@ atkhandler.c atkport.c +bldc.c + fastmath.c main.c diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj b/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj index 500ce0a..56c8b18 100644 --- a/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj +++ b/embedded/atkbldcdriver/atkbldcdriver/atkbldcdriver.cproj @@ -148,6 +148,12 @@ <Compile Include="atkport.h"> <SubType>compile</SubType> </Compile> + <Compile Include="bldc.c"> + <SubType>compile</SubType> + </Compile> + <Compile Include="bldc.h"> + <SubType>compile</SubType> + </Compile> <Compile Include="fastmath.c"> <SubType>compile</SubType> </Compile> diff --git a/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c b/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c index d930ce5..0577c46 100644 --- a/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c +++ b/embedded/atkbldcdriver/atkbldcdriver/atkhandler.c @@ -8,7 +8,8 @@ #include "hardware.h" #include "atkhandler.h" -int32_t steps; +uint8_t testReply[4] = {127, 12, 24, 48}; +uint8_t speedReply[4] = {141, 13, 25, 49}; void atk_handle_packet(uint8_t *packet, uint8_t length){ // dirty debug reply @@ -16,7 +17,6 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){ // through packet int i = 0; int atk_handler_state = ATK_HANDLER_OUTSIDE; - uint8_t testReply[4] = {127, 12, 24, 48}; while(i < length){ // prep for the messy double switch :| switch (atk_handler_state){ @@ -50,7 +50,16 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){ break; case DELIM_KEY_SPEED: - // set timers + // integer signed so that we can do dir with the same command + if(i + 9 > length){ + i ++; + } else { + int32_t speed = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4]; + uint32_t duty = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8]; + i += 9; + bldc_newSpeed(&bldc, speed, duty); + atk_reply_packet(packet, speedReply, 4); + } break; case DELIM_KEY_TRAPEZOID: diff --git a/embedded/atkbldcdriver/atkbldcdriver/bldc.c b/embedded/atkbldcdriver/atkbldcdriver/bldc.c new file mode 100644 index 0000000..d99f98b --- /dev/null +++ b/embedded/atkbldcdriver/atkbldcdriver/bldc.c @@ -0,0 +1,57 @@ +/* + * bldc.c + * + * Created: 7/12/2018 1:52:34 PM + * Author: Jake + */ + +#include "bldc.h" +#include "hardware.h" + +void bldc_init(bldc_t *bldc){ + bldc->comState = 0; + bldc->comDir = 1; + bldc->comDuty = 0; +} + +void bldc_shutdown(bldc_t *bldc){ + pin_clear(&drvEnPin); + bldc->comState = 0; + bldc->comDir = 1; + bldc->comDuty = 0; +} + +void bldc_setDuty(bldc_t *bldc, uint32_t duty){ + // blind pwm duty 0-512 + (duty > 512) ? duty = 512 : (0); + bldc->comDuty = (uint16_t) duty; +} + +void bldc_setSpeed(bldc_t *bldc, int32_t speed){ + // speed in eRPM + // assert max + uint32_t sAbs = abs(speed); + (sAbs > 20000) ? sAbs = 20000 : (0); + // check dir + if(speed == 0){ + bldc_shutdown(bldc); + } else if (speed > 0){ + bldc->comDir = 1; + } else { + bldc->comDir = 0; + } + + // base time, and we want 6 steps / rev, and rpm-rps + bldc->comPeriod = COMTICKER_TICKS_SECOND / (sAbs / 10); + + // set a new timer period + uint8_t ctPerBufL = (uint8_t) bldc->comPeriod; + uint8_t ctPerBufH = (uint8_t) (bldc->comPeriod >> 8); + TCD0.PERBUFL = ctPerBufL; + TCD0.PERBUFH = ctPerBufH; +} + +void bldc_newSpeed(bldc_t *bldc, int32_t speed, uint32_t duty){ + bldc_setDuty(bldc, duty); + bldc_setSpeed(bldc, speed); +} \ No newline at end of file diff --git a/embedded/atkbldcdriver/atkbldcdriver/bldc.h b/embedded/atkbldcdriver/atkbldcdriver/bldc.h new file mode 100644 index 0000000..e0a911f --- /dev/null +++ b/embedded/atkbldcdriver/atkbldcdriver/bldc.h @@ -0,0 +1,35 @@ +/* + * bldc.h + * + * Created: 7/12/2018 1:52:26 PM + * Author: Jake + */ + + +#ifndef BLDC_H_ +#define BLDC_H_ + +#include "avr/io.h" + +typedef struct{ + uint8_t comState; + uint8_t comDir; + uint16_t comDuty; + + uint16_t comPeriod; +}bldc_t; + +void bldc_init(bldc_t *bldc); + +void bldc_shutdown(bldc_t *bldc); + +void bldc_setDuty(bldc_t *bldc, uint32_t duty); + +void bldc_setSpeed(bldc_t *bldc, int32_t speed); + +void bldc_start(bldc_t *bldc, int32_t speed, uint32_t duty); + +void bldc_newSpeed(bldc_t *bldc, int32_t speed, uint32_t duty); + + +#endif /* BLDC_H_ */ \ No newline at end of file diff --git a/embedded/atkbldcdriver/atkbldcdriver/hardware.h b/embedded/atkbldcdriver/atkbldcdriver/hardware.h index 35003ea..85044ec 100644 --- a/embedded/atkbldcdriver/atkbldcdriver/hardware.h +++ b/embedded/atkbldcdriver/atkbldcdriver/hardware.h @@ -16,12 +16,17 @@ #include "atkport.h" #include "atkhandler.h" #include "ams5047.h" +#include "bldc.h" // results in 1MBaud #define SYSTEM_BAUDA 3 #define SYSTEM_BAUDB 0 #define SYSTEM_NUM_UPS 1 +// ticker bases + +#define COMTICKER_TICKS_SECOND 750000 + pin_t stlclk; pin_t stlerr; @@ -70,6 +75,11 @@ pin_t hi3; // controller functions +bldc_t bldc; + +uint8_t comState; +uint16_t comDuty; + // bldc_t bldc; pin_t tstpin1; diff --git a/embedded/atkbldcdriver/atkbldcdriver/main.c b/embedded/atkbldcdriver/atkbldcdriver/main.c index 0da60d4..a90dc47 100644 --- a/embedded/atkbldcdriver/atkbldcdriver/main.c +++ b/embedded/atkbldcdriver/atkbldcdriver/main.c @@ -66,6 +66,15 @@ void pwm_periods(uint16_t peru, uint16_t perv, uint16_t perw){ TCC0.CCCBUFH = (uint8_t) (peru >> 8); } +void pwm_by_offset(int16_t ofu, int16_t ofv, int16_t ofw){ + // +ve offset to spend more time with hi-side off, signals are complimentary + uint16_t peru = 512 + ofu; + uint16_t perv = 512 + ofv; + uint16_t perw = 512 + ofw; + // now through business + pwm_periods(peru, perv, perw); +} + void pwm_init(void){ // setup awex etc @@ -94,34 +103,62 @@ void pwm_init(void){ AWEXC.DTBOTHBUF = 4; // four counts of pwm clock for deadtime AWEXC.OUTOVEN = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5); - pwm_periods(256, 512, 768); + pwm_periods(0, 0, 0); } void drv_init(void){ - + // mode pins + pin_init(&drvEnPin, &PORTD, PIN1_bm, 1, 1); + pin_init(&drvModePwm, &PORTB, PIN6_bm, 6, 1); + pin_init(&drvModeGain, &PORTC, PIN6_bm, 6, 1); + pin_init(&drvDcCal, &PORTB, PIN7_bm, 7, 1); + // status + pin_init(&drvFault, &PORTC, PIN7_bm, 7, 0); + pin_init(&drvOCTW, &PORTD, PIN0_bm, 0, 0); + + // setup drv8302 mode + pin_clear(&drvModePwm); // low for 6-channel pwm, hi and lo sides from uc + pin_clear(&drvModeGain); // low for 10v/v, hi for 40v/v current sense gains + pin_clear(&drvDcCal); // turn DC cal off, we turn this high to set midpoint on amps + pin_clear(&drvEnPin); // disable the gate driver, to start. also broken by no/go hardware switch +} + +void drv_enable(void){ + pin_set(&drvEnPin); +} + +void drv_disable(void){ + pin_clear(&drvEnPin); } void tickers_init(void){ // sets up two timers // compare and capture at value - uint16_t pera = 1200; + // this is a low-speed-start friendly value, to start the commutation ticker with + uint16_t perStartSpeed = 2400; // write low first, bc bussing / xmega 8-bit oddities cc datasheet @ 3.11 - uint8_t peral = (uint8_t) pera; - uint8_t perah = (uint8_t) (pera >> 8); + uint8_t perSl = (uint8_t) perStartSpeed; + uint8_t perSh = (uint8_t) (perStartSpeed >> 8); // turn on TCC0 - TCD0.CTRLA = TC_CLKSEL_DIV256_gc; - TCD0.PERBUFL = peral; - TCD0.PERBUFH = perah; + TCD0.CTRLA = TC_CLKSEL_DIV64_gc; + TCD0.PERBUFL = perSl; + TCD0.PERBUFH = perSh; // set cca interrupt on TCD0.INTCTRLA = TC_OVFINTLVL_HI_gc; - + + // and a reasonable speed for acceleration ticking + + uint16_t perAccelRate = 2400; + uint8_t perAl = (uint8_t) perAccelRate; + uint8_t perAh = (uint8_t) (perAccelRate >> 8); + // another ticker to execute accel - TCD1.CTRLA = TC_CLKSEL_DIV256_gc; - TCD1.PERBUFL = peral; - TCD1.PERBUFH = perah; + TCD1.CTRLA = TC_CLKSEL_DIV64_gc; + TCD1.PERBUFL = perAl; + TCD1.PERBUFH = perAh; TCD1.INTCTRLA = TC_OVFINTLVL_HI_gc; } @@ -144,9 +181,20 @@ int main(void) //pin_init(&tstpin1, &PORTC, PIN5_bm, 5, 1); //pin_init(&tstpin2, &PORTC, PIN3_bm, 3, 1); + // start timers for commutation, accel tickers tickers_init(); - + // start pwm system pwm_init(); + // initialize the bldc state structure + bldc_init(&bldc); + // on startup speed and duty + bldc_setSpeed(&bldc, 1000); + bldc_setDuty(&bldc, 10); + // startup the driver + drv_init(); + // and enable the gate + drv_enable(); + // now we should be spinning at 500 eRPM, so we can set an accel... later // runtime globals uint32_t tck = 0; @@ -168,11 +216,30 @@ ISR(TCC0_OVF_vect){ pin_toggle(&hi1); } +int8_t comTable[6][3] = { + {1,-1,0}, + {1,0,-1}, + {0,1,-1}, + {-1,1,0}, + {-1,0,1}, + {0,-1,1} +}; + +// commutation timer ISR(TCD0_OVF_vect){ // commutate? - //pin_toggle(&tstpin1); + (bldc.comDir) ? (bldc.comState ++) : (bldc.comState --); + if(bldc.comState > 5){ + bldc.comState = 0; + } + + pwm_by_offset( comTable[bldc.comState][0] * bldc.comDuty, + comTable[bldc.comState][1] * bldc.comDuty, + comTable[bldc.comState][2] * bldc.comDuty + ); } +// acceleration timer ISR(TCD1_OVF_vect){ //pin_toggle(&tstpin2); } -- GitLab