Commit 8539995e authored by Jake Read's avatar Jake Read

six step with fullly individual waveforms

parent c58120a5
......@@ -141,7 +141,7 @@ LINKER_SCRIPT_DEP+=
./%.o: .././%.c
@echo Building file: $<
@echo Invoking: AVR/GNU C Compiler : 5.4.0
$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\include" -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atxmega256a3u -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<"
$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\include" -O2 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atxmega256a3u -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.1.68\gcc\dev\atxmega256a3u" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<"
@echo Finished building: $<
......
......@@ -127,7 +127,7 @@
<Value>%24(PackRepoDir)\atmel\XMEGAA_DFP\1.1.68\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.level>Optimize more (-O2)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
......@@ -143,7 +143,7 @@
</ListValues>
</avrgcc.assembler.general.IncludePaths>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc>
</AvrGcc>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
......
......@@ -66,7 +66,7 @@ static uint16_t enc_reading = 0;
static uint16_t phase_target = 0;
// 2^14 = 16,384
void pwm_periods(uint16_t peru, uint16_t perv, uint16_t perw){
void pwm_sintype_periods(uint16_t peru, uint16_t perv, uint16_t perw){
// check overrun
(peru > 1024) ? peru = 1024 : (0);
(perv > 1024) ? perv = 1024 : (0);
......@@ -84,16 +84,16 @@ 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){
void pwm_sintype_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);
pwm_sintype_periods(peru, perv, perw);
}
void pwm_by_sin_duty(uint16_t phase, float duty){
void pwm_sintype_by_sin_duty(uint16_t phase, float duty){
// phases respective of home
int16_t pu = phase;
(pu >= twoPi_enc) ? (pu -= twoPi_enc) : (0);
......@@ -107,35 +107,37 @@ void pwm_by_sin_duty(uint16_t phase, float duty){
int16_t perv = ((sinelut[pv] - 512) * duty) + 512;
int16_t perw = ((sinelut[pw] - 512) * duty) + 512;
pwm_periods(peru, perv, perw);
pwm_sintype_periods(peru, perv, perw);
}
uint16_t readings[20];
uint8_t readIndex = 0;
void putReading(uint16_t reading){
readings[readIndex] = reading;
readIndex ++;
}
void getReadAverage(uint16_t *avg){
uint8_t numReads = readIndex; // sloppy, but makes this interrupt safe
uint32_t readSum = 0;
for(uint8_t i = 0; i < numReads; i ++){
readSum += readings[i];
}
*avg = readSum / numReads;
void pwm_sixstep(uint16_t lo1, uint16_t hi1, uint16_t lo2, uint16_t hi2, uint16_t lo3, uint16_t hi3){
TCC1.CCABUFL = (uint8_t) lo1;
TCC1.CCABUFH = (uint8_t) (lo1 >> 8);
TCC1.CCBBUFL = (uint8_t) hi1;
TCC1.CCBBUFH = (uint8_t) (hi1 >> 8);
TCC0.CCCBUFL = (uint8_t) lo2;
TCC0.CCCBUFH = (uint8_t) (lo2 >> 8);
TCC0.CCDBUFL = (uint8_t) hi2;
TCC0.CCDBUFH = (uint8_t) (hi2 >> 8);
TCC0.CCABUFL = (uint8_t) lo3;
TCC0.CCABUFH = (uint8_t) (lo3 >> 8);
TCC0.CCBBUFL = (uint8_t) hi3;
TCC0.CCBBUFH = (uint8_t) (hi3 >> 8);
}
void pwm_init(void){
// setup awex etc
pin_init(&lo1, &PORTC, PIN4_bm, 4, 1);
pin_init(&hi1, &PORTC, PIN5_bm, 5, 1);
pin_init(&lo2, &PORTC, PIN2_bm, 2, 1);
pin_init(&hi2, &PORTC, PIN3_bm, 3, 1);
pin_init(&lo3, &PORTC, PIN0_bm, 0, 1);
pin_init(&hi3, &PORTC, PIN1_bm, 1, 1);
pin_init(&lo1, &PORTC, PIN4_bm, 4, 1); // TCC1 OC1A
pin_init(&hi1, &PORTC, PIN5_bm, 5, 1); // TCC1 OC1B
pin_init(&lo2, &PORTC, PIN2_bm, 2, 1); // TCC0 OC0C
pin_init(&hi2, &PORTC, PIN3_bm, 3, 1); // TCC0 OC0D
pin_init(&lo3, &PORTC, PIN0_bm, 0, 1); // TCC0 OC0A
pin_init(&hi3, &PORTC, PIN1_bm, 1, 1); // TCC0 OC0B
// compare and capture at value
uint16_t per = 1024; // at DIV1, 1024 period is 23.5kHz
......@@ -143,10 +145,22 @@ void pwm_init(void){
uint8_t perl = (uint8_t) per;
uint8_t perh = (uint8_t) (per >> 8);
// PWM for 6-step commutation
TCC0.CTRLA = TC_CLKSEL_DIV1_gc;
TCC1.CTRLA = TC_CLKSEL_DIV1_gc;
TCC0.PERBUFL = perl;
TCC0.PERBUFH = perh;
TCC1.PERBUFL = perl;
TCC1.PERBUFH = perh;
TCC0.CTRLB = TC_WGMODE_DS_T_gc | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);
TCC1.CTRLB = TC_WGMODE_DS_T_gc | (1 << 5) | (1 << 4);
/*
// PWM for three complimentary pairs:
// turnt to dual-slope pwm to have center aligned, and eventually sampling on top event
TCC0.CTRLB = TC_WGMODE_DS_T_gc;// | (1 << 7) | (1 << 6) | (1 << 5); // dual slope, and enable channels a, b, c for capture
......@@ -156,6 +170,7 @@ void pwm_init(void){
AWEXC.OUTOVEN = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5);
pwm_periods(0, 0, 0);
*/
}
void drv_init(void){
......@@ -236,17 +251,19 @@ int main(void)
// initialize the bldc state structure
bldc_init(&bldc);
bldc_setTargetSpeed(&bldc, 1000);
bldc_setDuty(&bldc, 45); // MAX 512, dangerous above ~ 120
// start the timers that do work
tickers_init();
bldc_setTargetSpeed(&bldc, 800);
bldc_setSpeed(&bldc, 100);
bldc.currentSpeed = 100;
bldc_setDuty(&bldc, 52); // MAX 512, dangerous above ~ 120
// startup the driver
drv_init();
// and enable the gate
drv_enable();
// start the timers that do work
tickers_init();
// runtime globals
uint32_t tck = 0;
......@@ -255,8 +272,6 @@ int main(void)
atkport_scan(&atkp0, 2);
// just... as fast as we can
tck++;
// this modulo op is slow AF
// that means streamlining atkport_scan without modulos is probably a rad thing
if(!(fastModulo(tck, 4096))){
pin_toggle(&stlclk);
}
......@@ -273,11 +288,32 @@ ISR(TCD0_OVF_vect){
bldc.comState = 0;
}
pwm_by_offset( comTable[bldc.comState][0] * bldc.comDuty,
uint8_t cs = bldc.comState;
uint16_t dt = bldc.comDuty;
uint16_t clo1 = ct[cs][0];
clo1 *= dt;
uint16_t chi1 = ct[cs][1];
chi1 *= dt;
uint16_t clo2 = ct[cs][2];
clo2 *= dt;
uint16_t chi2 = ct[cs][3];
chi2 *= dt;
uint16_t clo3 = ct[cs][4];
clo3 *= dt;
uint16_t chi3 = ct[cs][5];
chi3 *= dt;
// ct is comtable
pwm_sixstep(clo1, chi1, clo2, chi2, clo3, chi3);
/*
// here is PWM for sinusoid-type pwm setup
pwm_by_offset(comTable[bldc.comState][0] * bldc.comDuty,
comTable[bldc.comState][1] * bldc.comDuty,
comTable[bldc.comState][2] * bldc.comDuty
);
*/
/*
// CL 6-step Commutate
......
......@@ -160,13 +160,13 @@ const static int16_t sinelut[2340] = {
};
const static int8_t comTable[6][3] = {
{1,-1,0},
{1,0,-1},
{0,1,-1},
{-1,1,0},
{-1,0,1},
{0,-1,1}
const static int8_t ct[6][6] = {
{0,1,1,0,0,0}, // hi1, lo2
{0,1,0,0,1,0}, // hi1, lo3
{0,0,0,1,1,0}, // hi2, lo3
{1,0,0,1,0,0}, // hi2, lo1
{1,0,0,0,0,1}, // hi3, lo1
{0,0,1,0,0,1}, // hi3, lo2
};
#endif /* SINELUT_H_ */
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment