diff --git a/circuit/README.md b/circuit/README.md index 5d23ea832e6eb7e7913b8822f826df2114b43d56..a2f06f0e24571e674aa193f6690854e4ea036b2f 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 55ad9d1111549880886972fd7462368f73d22cec..a701f1dc9378c8c7fdc56d2afac212dc85366e6c 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 d5a1f4deaaeea7141daebfba92ac8c3db20f3106..0d51b274956f4b3ba52ae51603b37953a05dcbe2 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 500ce0ac9e04aa4c870817b41597ab6c2b555f2b..56c8b18cc01bff2fa54d736eb93df42a807a3baa 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 d930ce591de717d660533c01d0527115f5df1030..0577c4693978a6a15babaa7626e12c2cdc666a99 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 0000000000000000000000000000000000000000..d99f98b189982de81d7c6780fc43485e5cca4903 --- /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 0000000000000000000000000000000000000000..e0a911f8fdeef19285fa4010ea502b8cc6ac70ec --- /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 35003eaaf7c9dcbdc1eb91de57aafd93cb420950..85044ecf054ca0af8e8abc18c980a5a53ff7b0b0 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 0da60d43cc64ab7324db027c3f4d68b15cad2211..a90dc47329dd582d77bbffbfbd82b5c8827a0801 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); }