Commit 31155db3 authored by Jake Read's avatar Jake Read

v031 commutating closed loop, ready for network

parent bc5a946a
...@@ -36,11 +36,11 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu ...@@ -36,11 +36,11 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu
[Win_1] [Win_1]
Type="Schematic Editor" Type="Schematic Editor"
Loc="0 0 1919 1016" Loc="-1928 -8 -9 1008"
State=1 State=1
Number=2 Number=2
File="mkbldcdriver.sch" File="mkbldcdriver.sch"
View="-133.101 -16.4054 69.9278 60.3757" View="-191.238 -0.355913 101.124 110.209"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524" WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0" PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6" PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6"
...@@ -79,7 +79,7 @@ ArcDirection=0 ...@@ -79,7 +79,7 @@ ArcDirection=0
AddLevel=2 AddLevel=2
PadsSameType=0 PadsSameType=0
Layer=91 Layer=91
Views=" 1: -133.101 -16.4054 69.9278 60.3757" Views=" 1: -191.238 -0.355913 101.124 110.209"
Sheet="1" Sheet="1"
[Win_2] [Win_2]
...@@ -88,7 +88,7 @@ Loc="0 0 1919 1016" ...@@ -88,7 +88,7 @@ Loc="0 0 1919 1016"
State=1 State=1
Number=1 Number=1
File="mkbldcdriver.brd" File="mkbldcdriver.brd"
View="13.5716 56.9498 32.0603 57.5241" View="21.1469 45.1135 67.1527 46.5425"
WireWidths=" 0.0762 0.1016 0.127 0.15 0.508 0.6096 0.8128 2.54 1.016 1.27 0.3048 0.254 0.2 0.4064 0.2032 0.1524" WireWidths=" 0.0762 0.1016 0.127 0.15 0.508 0.6096 0.8128 2.54 1.016 1.27 0.3048 0.254 0.2 0.4064 0.2032 0.1524"
PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0" PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0"
PadDrills=" 0.2 0.25 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.3" PadDrills=" 0.2 0.25 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.3"
......
...@@ -173,8 +173,8 @@ ...@@ -173,8 +173,8 @@
<text x="35.052" y="20.193" size="0.6096" layer="21" font="vector">V-W</text> <text x="35.052" y="20.193" size="0.6096" layer="21" font="vector">V-W</text>
<text x="35.052" y="22.86" size="0.6096" layer="21" font="vector">V-V</text> <text x="35.052" y="22.86" size="0.6096" layer="21" font="vector">V-V</text>
<text x="35.052" y="25.273" size="0.6096" layer="21" font="vector">V-U</text> <text x="35.052" y="25.273" size="0.6096" layer="21" font="vector">V-U</text>
<text x="35.052" y="30.48" size="0.6096" layer="21" font="vector">C-V</text> <text x="35.052" y="30.48" size="0.6096" layer="21" font="vector">I-V</text>
<text x="35.052" y="27.813" size="0.6096" layer="21" font="vector">C-W</text> <text x="35.052" y="27.813" size="0.6096" layer="21" font="vector">I-W</text>
<text x="35.052" y="33.02" size="0.6096" layer="21" font="vector">3V3</text> <text x="35.052" y="33.02" size="0.6096" layer="21" font="vector">3V3</text>
<text x="35.052" y="35.56" size="0.6096" layer="21" font="vector">GND</text> <text x="35.052" y="35.56" size="0.6096" layer="21" font="vector">GND</text>
<text x="35.052" y="37.973" size="0.6096" layer="21" font="vector">LO3</text> <text x="35.052" y="37.973" size="0.6096" layer="21" font="vector">LO3</text>
......
...@@ -517,3 +517,42 @@ OK! ...@@ -517,3 +517,42 @@ OK!
Properly, I should do this on a timer. I'm going to do it in the while() loop for now, just to check that I'm having the output on the PWMs that I want. Properly, I should do this on a timer. I'm going to do it in the while() loop for now, just to check that I'm having the output on the PWMs that I want.
Great - I have this running in the open while() loop. It commutates! I suppose I shouldn't be surprised at this stuff anymore.
I set up my logic analyzer so that I can start on this commutation debug cycle. I have three pins on the lo-sides of the PWMs, three on the voltage sense pinse, and two on the current sense pins.
I'm hearing this 'tick' every so often as the motor commutates. Here's what it looks like on the analyzer:
![pwm-tick](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-pwm-ticking.png)
So I think that one of the PWM registers is occasionally being written to 100% in error. My suspicion is that this has something to do with my fast-and-loose commutation scheme, which I'm about to improve.
While I did notice that this was only occuring while the motor driver's gates where enabled (so, 'stuff was happening'), I tried using the ATSAMD's PWM Capture-Compare Buffer (capture-compare is the value the pwm timer checks to switch-or-not-switch the output). The buffer let's me write into the PWM registers when I'm sure they're not being read by the peripheral. This eliminated the problem. I also pushed the PWM frequency to 22kHZ and it's all silky smooth sounding now.
OK, some current / voltage waveforms:
Channels: Fault, PWM Hi U, Pwm Hi V, Pwm Hi W, Current V, Current W, Voltage V, Voltage W.
![currents](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-currents-olcommutate-1.png)
![currents](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/master/images/programming-currents-olcommutate-2.png)
I set this up to accept a commanded 'torque' (just PWM duty cycle) and direction, so next step here is doing some network integration as well.
![clvideo](https://gitlab.cba.mit.edu/jakeread/mkbldcdriver/raw/video/20khz-commutate.mp4)
Then, a longer list of development:
# Next:
## Firmware
- Closed-Loop Speed Control (maybe using simple 6-step commutation?)
- Search for Encoder Offset
- Closed-Loop Position Control
- Probably just Sinusoid PWM Commutation
- The Big Bite: FOC
## Hardware
- I have a list of incremental improvements... mostly:
- Go to 2oz copper so that I dont' blow up any traces when the power hits
- Discrete LEDs and more indication (there's an overcurrent / overtemp warning I want to break out)
\ No newline at end of file
...@@ -38,8 +38,10 @@ SUBDIRS := \ ...@@ -38,8 +38,10 @@ SUBDIRS := \
# Add inputs and outputs from these tool invocations to the build variables # Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \ C_SRCS += \
../bldc_pfoc.c \
../Device_Startup/startup_samd51.c \ ../Device_Startup/startup_samd51.c \
../Device_Startup/system_samd51.c \ ../Device_Startup/system_samd51.c \
../encoder.c \
../main.c \ ../main.c \
../pin.c \ ../pin.c \
../pwm_foc.c \ ../pwm_foc.c \
...@@ -55,8 +57,10 @@ ASM_SRCS += ...@@ -55,8 +57,10 @@ ASM_SRCS +=
OBJS += \ OBJS += \
bldc_pfoc.o \
Device_Startup/startup_samd51.o \ Device_Startup/startup_samd51.o \
Device_Startup/system_samd51.o \ Device_Startup/system_samd51.o \
encoder.o \
main.o \ main.o \
pin.o \ pin.o \
pwm_foc.o \ pwm_foc.o \
...@@ -65,8 +69,10 @@ spiport.o \ ...@@ -65,8 +69,10 @@ spiport.o \
uartport.o uartport.o
OBJS_AS_ARGS += \ OBJS_AS_ARGS += \
bldc_pfoc.o \
Device_Startup/startup_samd51.o \ Device_Startup/startup_samd51.o \
Device_Startup/system_samd51.o \ Device_Startup/system_samd51.o \
encoder.o \
main.o \ main.o \
pin.o \ pin.o \
pwm_foc.o \ pwm_foc.o \
...@@ -75,8 +81,10 @@ spiport.o \ ...@@ -75,8 +81,10 @@ spiport.o \
uartport.o uartport.o
C_DEPS += \ C_DEPS += \
bldc_pfoc.d \
Device_Startup/startup_samd51.d \ Device_Startup/startup_samd51.d \
Device_Startup/system_samd51.d \ Device_Startup/system_samd51.d \
encoder.d \
main.d \ main.d \
pin.d \ pin.d \
pwm_foc.d \ pwm_foc.d \
...@@ -85,8 +93,10 @@ spiport.d \ ...@@ -85,8 +93,10 @@ spiport.d \
uartport.d uartport.d
C_DEPS_AS_ARGS += \ C_DEPS_AS_ARGS += \
bldc_pfoc.d \
Device_Startup/startup_samd51.d \ Device_Startup/startup_samd51.d \
Device_Startup/system_samd51.d \ Device_Startup/system_samd51.d \
encoder.d \
main.d \ main.d \
pin.d \ pin.d \
pwm_foc.d \ pwm_foc.d \
...@@ -127,14 +137,18 @@ LINKER_SCRIPT_DEP+= \ ...@@ -127,14 +137,18 @@ LINKER_SCRIPT_DEP+= \
Device_Startup/%.o: ../Device_Startup/%.c
./%.o: .././%.c
@echo Building file: $< @echo Building file: $<
@echo Invoking: ARM/GNU C Compiler : 6.3.1 @echo Invoking: ARM/GNU C Compiler : 6.3.1
$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE) -x c -mthumb -D__SAMD51J18A__ -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include" -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -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\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE) -x c -mthumb -D__SAMD51J18A__ -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include" -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<"
@echo Finished building: $< @echo Finished building: $<
./%.o: .././%.c Device_Startup/%.o: ../Device_Startup/%.c
@echo Building file: $< @echo Building file: $<
@echo Invoking: ARM/GNU C Compiler : 6.3.1 @echo Invoking: ARM/GNU C Compiler : 6.3.1
$(QUOTE)C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE) -x c -mthumb -D__SAMD51J18A__ -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include" -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -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\arm\arm-gnu-toolchain\bin\arm-none-eabi-gcc.exe$(QUOTE) -x c -mthumb -D__SAMD51J18A__ -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\arm\CMSIS\5.0.1\CMSIS\Include" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\SAMD51_DFP\1.0.70\include" -O1 -ffunction-sections -mlong-calls -g3 -Wall -mcpu=cortex-m4 -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<"
......
...@@ -2,10 +2,14 @@ ...@@ -2,10 +2,14 @@
# Automatically-generated file. Do not edit or delete the file # Automatically-generated file. Do not edit or delete the file
################################################################################ ################################################################################
bldc_pfoc.c
Device_Startup\startup_samd51.c Device_Startup\startup_samd51.c
Device_Startup\system_samd51.c Device_Startup\system_samd51.c
encoder.c
main.c main.c
pin.c pin.c
......
/*
* bldc_pfoc.c
*
* Created: 2/19/2018 10:40:54 AM
* Author: Jake
*/
#include "bldc_pfoc.h"
#include "encoder.h"
#include "sinelut.h"
#include "pwm_foc.h"
#include "hardware.h"
void bldc_init(bldc_t *bldc, uint32_t resolution, uint32_t modulo, uint32_t offset, uint32_t reverse){
bldc->resolution = resolution;
bldc->modulo = modulo;
bldc->offset = offset;
bldc->reverse = reverse;
bldc->modmap = modulo / 1024;
}
// super simple throttle
void bldc_command(bldc_t *bldc, uint32_t scalar, uint32_t dir){
if(scalar > BLDC_MAX_SCALAR){
bldc->scalar = BLDC_MAX_SCALAR;
} else {
bldc->scalar = scalar;
}
bldc->dir = dir;
}
void bldc_update(bldc_t *bldc){
// read encoder, where 0 - 2^14 is 0 - 2*PI rads mechanical phase
encoder_read(&bldc->reading);
// reverse the reading if that flag is set
if(bldc->reverse){
bldc->reading = bldc->resolution - bldc->reading;
}
// electric position and offsetting
// one modulo is one full electric phase, is some division of full rotations
// so, elecpos is 0 - modulo (uint) describing 0 - 2*PI rads of an electric phase
bldc->elecpos = (bldc->reading + bldc->offset) % bldc->modulo;
// now we map the phases from 0 - modulo (uint) -> 0 - 1024 (uint)
// this is the depth of our lookup table for sin()
// we computed this value at init, as modulo / lut_depth;
// we compute the modpos once
bldc->modpos = bldc->elecpos / bldc->modmap;
if(bldc->dir){
bldc->phaseu = bldc->modpos;
bldc->phasev = bldc->modpos + 341; // + 120* in lut phase
bldc->phasew = bldc->modpos + 682; // + 240*
} else {
bldc->phaseu = bldc->modpos + 682;
bldc->phasev = bldc->modpos + 341; // + 120* in lut phase
bldc->phasew = bldc->modpos; // + 240*
}
// now we check for wrap arounds in the lut phase
(bldc->phaseu > 1023) ? (bldc->phaseu -= 1023) : (0);
(bldc->phasev > 1023) ? (bldc->phasev -= 1023) : (0);
(bldc->phasew > 1023) ? (bldc->phasew -= 1023) : (0);
// and set the pwm value to be the sin of it's current electric phase,
// where the sinelut returns a value 0 - 255
// midpoint (0 volts, equal time on / off) being 128
// and multiply that value by a scalar
bldc->pwmu = (sinelut[bldc->phaseu] * bldc->scalar) / 255;
bldc->pwmv = sinelut[bldc->phasev] * bldc->scalar / 255;
bldc->pwmw = sinelut[bldc->phasew] * bldc->scalar / 255;
// finally, sending new pwm values
// we assert the minimum value to be 5 and the max to be 250
// this leaves some time for deadtime insertion (set with TCC_WEXCTRL_DTHS(1) in PWM setup)
pwmupdate_foc(bldc->pwmu,bldc->pwmv,bldc->pwmw);
}
\ No newline at end of file
/*
* bldc_pfoc.h
*
* Created: 2/19/2018 10:40:36 AM
* Author: Jake
*/
#ifndef BLDC_PFOC_H_
#define BLDC_PFOC_H_
#include "sam.h"
#define BLDC_MAX_SCALAR 255
#define BLDC_INIT_OFFSET 700
#define BLDC_RESOLUTION 16834
#define BLDC_MODULO 2340
#define BLDC_REVERSE 1
// struct to wrap commutation information
typedef struct{
uint32_t resolution;
uint32_t modulo;
uint32_t offset;
uint32_t reverse;
uint32_t modmap;
uint32_t scalar;
uint32_t dir;
uint32_t reading;
uint32_t elecpos;
uint32_t modpos;
uint32_t phaseu, pwmu;
uint32_t phasev, pwmv;
uint32_t phasew, pwmw;
}bldc_t;
void bldc_init(bldc_t *bldc, uint32_t resolution, uint32_t modulo, uint32_t offset, uint32_t reverse);
void bldc_command(bldc_t *bldc, uint32_t scalar, uint32_t dir);
void bldc_update(bldc_t *bldc);
#endif /* BLDC_PFOC_H_ */
\ No newline at end of file
/*
* encoder.c
*
* Created: 2/19/2018 11:11:57 AM
* Author: Jake
*/
#include "encoder.h"
#include "hardware.h"
void encoder_read(uint32_t *data_return){
uint8_t data_tx[2] = {0xFF, 0xFF}; // read command: 1s, noop: 0s
uint8_t data_rx[2];
spi_txrxchars_polled(&spi_encoder, data_tx, 2, data_rx);
data_tx[0] = 0x00;
data_tx[1] = 0x00;
spi_txrxchars_polled(&spi_encoder, data_tx, 2, data_rx);
* data_return = (data_rx[0] & 0b00111111) << 8 | data_rx[1];
}
\ No newline at end of file
/*
* encoder.h
*
* Created: 2/19/2018 11:11:23 AM
* Author: Jake
*/
#ifndef ENCODER_H_
#define ENCODER_H_
#include "sam.h"
void encoder_read(uint32_t *data_return);
#endif /* ENCODER_H_ */
\ No newline at end of file
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include "ringbuffer.h" #include "ringbuffer.h"
#include "uartport.h" #include "uartport.h"
#include "spiport.h" #include "spiport.h"
#include "bldc_pfoc.h"
#include "pwm_foc.h"
pin_t stlb; pin_t stlb;
...@@ -33,4 +35,8 @@ pin_t m_gain; ...@@ -33,4 +35,8 @@ pin_t m_gain;
pin_t fault; pin_t fault;
pin_t octw; pin_t octw;
bldc_t bldc;
pin_t testp;
#endif /* HARDWARE_H_ */ #endif /* HARDWARE_H_ */
\ No newline at end of file
...@@ -7,27 +7,42 @@ ...@@ -7,27 +7,42 @@
#include "sam.h" #include "sam.h"
#include "pwm_foc.h"
#include "pin.h"
#include "ringbuffer.h"
#include "uartport.h"
#include "spiport.h"
#include "hardware.h" #include "hardware.h"
#include "sinelut.h" #include "encoder.h"
#include <stdio.h> #include <stdio.h>
// stlb is PA23 void comticker_init(uint32_t cc){
// Timers: in 32 bit mode we pair two - obscure datasheet reading later, they pair in a predefined way: 0 with 1...
uint32_t encoder_read(void){ // a word of warning: with the same code, a 16-bit timer was not working. I am mystified.
uint8_t data_tx[2] = {0xFF, 0xFF}; // read command: 1s, noop: 0s TC2->COUNT32.CTRLA.bit.ENABLE = 0;
uint8_t data_rx[2]; TC3->COUNT32.CTRLA.bit.ENABLE = 0;
spi_txrxchars_polled(&spi_encoder, data_tx, 2, data_rx); // unmask clocks
data_tx[0] = 0x00; MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC2 | MCLK_APBBMASK_TC3; // at 15.8.9
data_tx[1] = 0x00; // generate a gclk
spi_txrxchars_polled(&spi_encoder, data_tx, 2, data_rx); GCLK->GENCTRL[11].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN;
while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(11));
uint32_t data = (data_rx[0] & 0b00111111) << 8 | data_rx[1]; // ship gclk to their channels
return data; GCLK->PCHCTRL[TC2_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(11);
GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(11);
// turn on in mode, presync
TC2->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_CAPTEN0;// | TC_CTRLA_CAPTEN1;
TC3->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_CAPTEN0;// | TC_CTRLA_CAPTEN1;
// do frequency match
TC2->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
TC3->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
// allow interrupt to trigger on this event (compare channel 0)
TC2->COUNT32.INTENSET.bit.MC0 = 1;
TC2->COUNT32.INTENSET.bit.MC1 = 1; // don't know why, but had to turn this on to get the interrupts
// set period
while(TC2->COUNT32.SYNCBUSY.bit.CC0);
TC2->COUNT32.CC[0].reg = 165;
while(TC2->COUNT32.SYNCBUSY.bit.CC1);
TC2->COUNT32.CC[1].reg = 165;
// enable, sync for enable write
TC2->COUNT32.CTRLA.bit.ENABLE = 1;
while(TC2->COUNT32.SYNCBUSY.bit.ENABLE);
TC3->COUNT32.CTRLA.bit.ENABLE = 1;
while(TC3->COUNT32.SYNCBUSY.bit.ENABLE);
} }
int main(void) int main(void)
...@@ -46,6 +61,7 @@ int main(void) ...@@ -46,6 +61,7 @@ int main(void)
NVIC_EnableIRQ(SERCOM4_2_IRQn); //up1rx NVIC_EnableIRQ(SERCOM4_2_IRQn); //up1rx
NVIC_EnableIRQ(SERCOM5_0_IRQn); NVIC_EnableIRQ(SERCOM5_0_IRQn);
NVIC_EnableIRQ(SERCOM5_2_IRQn); NVIC_EnableIRQ(SERCOM5_2_IRQn);
NVIC_EnableIRQ(TC2_IRQn);
// Rinbuffers for UARTs // Rinbuffers for UARTs
rb_init(&up1_rbrx); rb_init(&up1_rbrx);
...@@ -103,11 +119,10 @@ int main(void) ...@@ -103,11 +119,10 @@ int main(void)
// OCTW PA22: input, open drain when active, use pullup // OCTW PA22: input, open drain when active, use pullup
fault = pin_new(&PORT->Group[0], 21); fault = pin_new(&PORT->Group[0], 21);
pin_input(&fault); pin_input(&fault);
pin_pullup(&fault);
octw = pin_new(&PORT->Group[0], 22); octw = pin_new(&PORT->Group[0], 22);
pin_input(&octw); pin_input(&octw);
pin_pullup(&octw);
// do closed loop sinucommutate, following old ATSAMS70 code
// do BLDC closed, open loop
// enable or don't // enable or don't
//pin_clear(&en_gate); //pin_clear(&en_gate);
...@@ -118,61 +133,31 @@ int main(void) ...@@ -118,61 +133,31 @@ int main(void)
pin_clear(&m_gain); pin_clear(&m_gain);
pin_clear(&dc_cal); pin_clear(&dc_cal);
uint32_t resolution = 16384; bldc_init(&bldc, BLDC_RESOLUTION, BLDC_MODULO, BLDC_INIT_OFFSET, BLDC_REVERSE);
uint32_t modulo = 2340; bldc_command(&bldc, 90, 1);
uint32_t offset = 800;
uint32_t reverse = 1;
uint32_t scalar = 42; // of 255
uint32_t reading; // startup timer for 5khz commutation loop
uint32_t elecpos; comticker_init(64);
uint32_t phaseu, pwmu;
uint32_t phasev, pwmv;
uint32_t phasew, pwmw;
while (1) while (1)
{ {
// read encoder & get electric position (relative phase period, not rotation period) if(!pin_read(&octw)){
reading = encoder_read(); pin_clear(&stlb);
if(reverse){
reading = resolution - reading;
} }
elecpos = (reading + offset) % modulo; // timer should be running, doing bldc things
// use these while() loops to handle network
// not LUT'd yet
phaseu = elecpos / (modulo / 1024);
phasev = elecpos / (modulo / 1024) + 341;
phasew = elecpos / (modulo / 1024) + 682;
(phaseu > 1023) ? (phaseu -= 1023) : (0);
(phasev > 1023) ? (phasev -= 1023) : (0);
(phasew > 1023) ? (phasew -= 1023) : (0);
pwmu = sinelut[phaseu] * scalar / 255 + 1;
pwmv = sinelut[phasev] * scalar / 255 + 1;
pwmw = sinelut[phasew] * scalar / 255 + 1;
pwmupdate_foc(pwmu,pwmv,pwmw);
} }
} }
// ok, we're commutating
/*
- ticking: it's a PWM update error, occasionally setting some values to 100%
- implement a timer to commutate at a set frequency
- work through the mess of values above, go faster, cleaner
- basic search for reverse, offset, modulo etc would be cool, hard (probably)
- verify all gates are opening
*/
uint8_t loopcnt; uint8_t loopcnt;
void SysTick_Handler(void){ void SysTick_Handler(void){
pin_toggle(&stlb); pin_set(&stlb);
loopcnt ++; loopcnt ++;
uart_sendchar_buffered(&up1, loopcnt); uart_sendchar_buffered(&up1, loopcnt);
uint32_t reading = encoder_read(); uint32_t reading;
//encoder_read(&reading);
reading = bldc.reading;
uint8_t d1 = reading >> 8; uint8_t d1 = reading >> 8;
uint8_t d2 = reading; uint8_t d2 = reading;
uart_sendchar_buffered(&up1, d1); uart_sendchar_buffered(&up1, d1);
...@@ -194,3 +179,9 @@ void SERCOM5_0_Handler(void){ ...@@ -194,3 +179,9 @@ void SERCOM5_0_Handler(void){
void SERCOM5_2_Handler(void){ void SERCOM5_2_Handler(void){
uart_rxhandler(&up2);