Commit f40cca4c authored by Jake Read's avatar Jake Read

begin closed loop commutation

parent a72933cf
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd"> <!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="9.1.1"> <eagle version="9.0.0">
<drawing> <drawing>
<settings> <settings>
<setting alwaysvectorfont="no"/> <setting alwaysvectorfont="no"/>
...@@ -962,9 +962,6 @@ design rules under a new name.</description> ...@@ -962,9 +962,6 @@ design rules under a new name.</description>
<param name="checkRestrict" value="1"/> <param name="checkRestrict" value="1"/>
<param name="checkStop" value="0"/> <param name="checkStop" value="0"/>
<param name="checkValues" value="0"/> <param name="checkValues" value="0"/>
<param name="checkNames" value="1"/>
<param name="checkWireStubs" value="1"/>
<param name="checkPolygonWidth" value="0"/>
<param name="useDiameter" value="13"/> <param name="useDiameter" value="13"/>
<param name="maxErrors" value="50"/> <param name="maxErrors" value="50"/>
</designrules> </designrules>
...@@ -3641,13 +3638,6 @@ design rules under a new name.</description> ...@@ -3641,13 +3638,6 @@ design rules under a new name.</description>
<wire x1="51.2308" y1="51.1808" x2="50.4" y2="50.35" width="0.1524" layer="1"/> <wire x1="51.2308" y1="51.1808" x2="50.4" y2="50.35" width="0.1524" layer="1"/>
</signal> </signal>
</signals> </signals>
<mfgpreviewcolors>
<mfgpreviewcolor name="soldermaskcolor" color="0xC8008000"/>
<mfgpreviewcolor name="silkscreencolor" color="0xFFFEFEFE"/>
<mfgpreviewcolor name="backgroundcolor" color="0xFF282828"/>
<mfgpreviewcolor name="coppercolor" color="0xFFFFBF00"/>
<mfgpreviewcolor name="substratecolor" color="0xFF786E46"/>
</mfgpreviewcolors>
</board> </board>
</drawing> </drawing>
<compatibility> <compatibility>
......
...@@ -42,7 +42,7 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu ...@@ -42,7 +42,7 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFu
Type="Board Editor" Type="Board Editor"
Number=1 Number=1
File="atkbldcdriver.brd" File="atkbldcdriver.brd"
View="46.6255 23.8801 69.1125 42.6084" View="41.6112 50.1586 52.4556 59.1904"
WireWidths=" 0.0762 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.1016 0.2032 0.1524" WireWidths=" 0.0762 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.1016 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"
...@@ -86,7 +86,7 @@ Layer=1 ...@@ -86,7 +86,7 @@ Layer=1
Type="Schematic Editor" Type="Schematic Editor"
Number=3 Number=3
File="atkbldcdriver.sch" File="atkbldcdriver.sch"
View="-280.35 -76.1712 223.851 152.676" View="-250.34 -67.9039 169.828 122.802"
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"
...@@ -125,7 +125,7 @@ ArcDirection=0 ...@@ -125,7 +125,7 @@ ArcDirection=0
AddLevel=2 AddLevel=2
PadsSameType=0 PadsSameType=0
Layer=91 Layer=91
Views=" 1: -280.35 -76.1712 223.851 152.676" Views=" 1: -250.34 -67.9039 169.828 122.802"
Sheet="1" Sheet="1"
[Win_3] [Win_3]
......
...@@ -32,4 +32,6 @@ In any case, I'd say it's enough to start trying to cut things, with some more c ...@@ -32,4 +32,6 @@ In any case, I'd say it's enough to start trying to cut things, with some more c
I know I can do this if I can manage to read my encoder successfully. I could also probably do it with the ADC, but I would want an oscilloscope to go down that path, and I don't have one here. I know I can do this if I can manage to read my encoder successfully. I could also probably do it with the ADC, but I would want an oscilloscope to go down that path, and I don't have one here.
So, we use a logic analyzer to try reading this AMS5047 So, we use a logic analyzer to try reading this AMS5047
\ No newline at end of file
Got this running, feels pretty mediocre. I need to understand commutation a bit better, and do this with a fan setup etc. I perhaps just have not counted my poles properly, but I wamt to do this with an oscilloscope, and understand how we might search for those offsets etc.
\ No newline at end of file
...@@ -7,34 +7,20 @@ ...@@ -7,34 +7,20 @@
#include "ams5047.h" #include "ams5047.h"
void ams5047_init(ams5047_t *ams, spiport_t *spi, pin_t *en, pin_t *sg){ void ams5047_init(ams5047_t *ams, spiport_t *spi){
ams->spi = spi; ams->spi = spi;
ams->en_pin = en; ams5047_readOp = (1 << 15) | (1 << 14) | 0x3FFF; // parity bit, 1 for read / notwrite, 1s for read-op address
ams->sg_pin = sg; ams5047_readBytes[0] = ams5047_readOp >> 8;
ams5047_readBytes[1] = (uint8_t)ams5047_readOp;
ams5047_noOp = (1 << 15); // parity bit, 0's for no-op
ams5047_noOpBytes[0] = ams5047_noOp >> 8;
ams5047_noOpBytes[1] = (uint8_t)ams5047_noOp;
} }
void ams5047_write(ams5047_t *ams, uint32_t word){ void ams5047_read(ams5047_t *ams, uint16_t *result){
// ? // at baud, takes ~ 20us (bauda = 12, baudb = 0) so max 50kHz
uint8_t bytes[3]; spi_txchars_polled(ams->spi, ams5047_readBytes, 2);
bytes[0] = word >> 16;// | 0b11110000; // top 4 & mask for visibility // issue noop, read rx'd on this tx (one step back)
bytes[1] = word >> 8; // middle 8 spi_txrxchars_polled(ams->spi, ams5047_readBytes, ams5047_resultBytes, 2);
bytes[2] = word; // last 4 and 0's *result = ((ams5047_resultBytes[0] & 0b00111111) << 8) | ams5047_resultBytes[1];
spi_txchars_polled(ams->spi, bytes, 3);
}
void ams5047_start(ams5047_t *ams){
//
}
void ams5047_update(ams5047_t *ams){
uint32_t smarten = 0b10100000000000000000;
ams5047_write(ams, smarten);
}
void ams5047_enable(ams5047_t *ams){
pin_clear(ams->en_pin);
}
void ams5047_disable(ams5047_t *ams){
pin_set(ams->en_pin);
} }
\ No newline at end of file
...@@ -18,21 +18,17 @@ ...@@ -18,21 +18,17 @@
typedef struct{ typedef struct{
spiport_t *spi; spiport_t *spi;
pin_t *en_pin;
pin_t *sg_pin;
}ams5047_t; }ams5047_t;
void ams5047_init(ams5047_t *ams, spiport_t *spi, pin_t *en, pin_t *sg); uint16_t ams5047_readOp;
uint16_t ams5047_noOp;
uint8_t ams5047_readBytes[2];
uint8_t ams5047_noOpBytes[2];
void ams5047_write(ams5047_t *ams, uint32_t word); uint8_t ams5047_resultBytes[2];
void ams5047_start(ams5047_t *ams); void ams5047_init(ams5047_t *ams, spiport_t *spi);
void ams5047_update(ams5047_t *ams); void ams5047_read(ams5047_t *ams, uint16_t *result);
void ams5047_enable(ams5047_t *ams);
void ams5047_disable(ams5047_t *ams);
#endif /* AMS5047_H_ */ #endif /* AMS5047_H_ */
\ No newline at end of file
...@@ -43,9 +43,12 @@ void atkps_init(void){ ...@@ -43,9 +43,12 @@ void atkps_init(void){
} }
void encoder_init(void){ void encoder_init(void){
// startup SPI
pin_init(&spiEncCsPin, &PORTD, PIN4_bm, 4, 1); pin_init(&spiEncCsPin, &PORTD, PIN4_bm, 4, 1);
spi_init(&spiEncoder, &USARTD1, &PORTD, PIN6_bm, PIN7_bm, PIN5_bm, &spiEncCsPin); spi_init(&spiEncoder, &USARTD1, &PORTD, PIN6_bm, PIN7_bm, PIN5_bm, &spiEncCsPin);
spi_start(&spiEncoder, 0); spi_start(&spiEncoder, 1);
// startup object
ams5047_init(&ams5047, &spiEncoder);
} }
void pwm_periods(uint16_t peru, uint16_t perv, uint16_t perw){ void pwm_periods(uint16_t peru, uint16_t perv, uint16_t perw){
...@@ -135,8 +138,7 @@ void tickers_init(void){ ...@@ -135,8 +138,7 @@ void tickers_init(void){
// sets up two timers // sets up two timers
// compare and capture at value // compare and capture at value
// this is a low-speed-start friendly value, to start the commutation ticker with uint16_t perStartSpeed = 150; // 75 should be 10kHz for commutation, 150 for 5kHz
uint16_t perStartSpeed = 2400;
// write low first, bc bussing / xmega 8-bit oddities cc datasheet @ 3.11 // write low first, bc bussing / xmega 8-bit oddities cc datasheet @ 3.11
uint8_t perSl = (uint8_t) perStartSpeed; uint8_t perSl = (uint8_t) perStartSpeed;
uint8_t perSh = (uint8_t) (perStartSpeed >> 8); uint8_t perSh = (uint8_t) (perStartSpeed >> 8);
...@@ -149,6 +151,7 @@ void tickers_init(void){ ...@@ -149,6 +151,7 @@ void tickers_init(void){
// set cca interrupt on // set cca interrupt on
TCD0.INTCTRLA = TC_OVFINTLVL_HI_gc; TCD0.INTCTRLA = TC_OVFINTLVL_HI_gc;
/*
// and a reasonable speed for acceleration ticking // and a reasonable speed for acceleration ticking
uint16_t perAccelRate = 800; uint16_t perAccelRate = 800;
...@@ -161,6 +164,7 @@ void tickers_init(void){ ...@@ -161,6 +164,7 @@ void tickers_init(void){
TCD1.PERBUFH = perAh; TCD1.PERBUFH = perAh;
TCD1.INTCTRLA = TC_OVFINTLVL_HI_gc; TCD1.INTCTRLA = TC_OVFINTLVL_HI_gc;
*/
} }
int main(void) int main(void)
...@@ -178,33 +182,28 @@ int main(void) ...@@ -178,33 +182,28 @@ int main(void)
pin_set(&stlerr); pin_set(&stlerr);
pin_set(&stlclk); pin_set(&stlclk);
//pin_init(&tstpin1, &PORTC, PIN5_bm, 5, 1); // startup encoder
//pin_init(&tstpin2, &PORTC, PIN3_bm, 3, 1); encoder_init();
// start timers for commutation, accel tickers // start timers for commutation, accel tickers
tickers_init(); tickers_init();
// startup encoder
//encoder_init();
// start pwm system // start pwm system
pwm_init(); pwm_init();
// initialize the bldc state structure // initialize the bldc state structure
bldc_init(&bldc); bldc_init(&bldc);
// on startup speed and duty // on startup, speed (if clcomm) and duty
bldc_setTargetSpeed(&bldc, 1000); //bldc_setTargetSpeed(&bldc, 1000);
bldc_setDuty(&bldc, 10); bldc_setDuty(&bldc, 40);
// startup the driver // startup the driver
drv_init(); drv_init();
// and enable the gate // and enable the gate
drv_enable(); drv_enable();
// now we should be spinning at 500 eRPM, so we can set an accel... later
// runtime globals // runtime globals
uint32_t tck = 0; uint32_t tck = 0;
while (1) while (1)
{ {
//ams5047_write(&ams5047, 1200);
atkport_scan(&atkp0, 2); atkport_scan(&atkp0, 2);
// just... as fast as we can // just... as fast as we can
tck++; tck++;
...@@ -216,10 +215,6 @@ int main(void) ...@@ -216,10 +215,6 @@ int main(void)
} }
} }
ISR(TCC0_OVF_vect){
pin_toggle(&hi1);
}
int8_t comTable[6][3] = { int8_t comTable[6][3] = {
{1,-1,0}, {1,-1,0},
{1,0,-1}, {1,0,-1},
...@@ -229,9 +224,48 @@ int8_t comTable[6][3] = { ...@@ -229,9 +224,48 @@ int8_t comTable[6][3] = {
{0,-1,1} {0,-1,1}
}; };
#define ENC_RESOLUTION 16834
// a handful of constants, probably need many less
// divisor is # of poles on motor / 2 (for each n/s pair, one set of 3 coils per full rotation)
const static uint16_t enc_resolution = ENC_RESOLUTION;
const static uint8_t enc_reverse = 0; // 1 or 0, for reverse op
const static uint16_t enc_modulo = ENC_RESOLUTION / 4; // 2805 in this case: divisor is # poles / 2
const static uint16_t enc_offset = 60; // start at midpoint - adjust -ve or +ve from
const static uint16_t enc_steplength = ENC_RESOLUTION / 4 / 6;
static uint16_t enc_reading = 0;
static uint16_t enc_adjusted = 0;
static uint16_t enc_phase = 0;
static uint16_t enc_target = 0;
// 2^14 = 16,384
// commutation timer // commutation timer
ISR(TCD0_OVF_vect){ ISR(TCD0_OVF_vect){
// commutate? // CL 6-step Commutate
// get encoder reading
ams5047_read(&ams5047, &enc_reading);
// offset and modulo to bring to in-phase relative location
if(enc_reverse){
enc_adjusted = enc_resolution - enc_reading;
}
enc_adjusted += enc_offset; // add offset
enc_adjusted %= enc_resolution; // wrap to resolution
enc_adjusted %= enc_modulo; // break into phase relative
// so this should represent the phase (0-5) that we're currently in
enc_phase = enc_adjusted / enc_steplength;
// if dir, phase + 2 to go forwards, else + 4, effectively - 2, and wrap past circle
(bldc.comDir) ? (enc_target = (enc_phase + 2) % 6) : (enc_target = (enc_phase + 4) % 6);
//uint8_t dout[6] = {6,0,5,254,255,enc_target};
//uart_sendchars_buffered(&up0, dout, 6);
// now we can set PWMs accordingly
pwm_by_offset( comTable[enc_target][0] * bldc.comDuty,
comTable[enc_target][1] * bldc.comDuty,
comTable[enc_target][2] * bldc.comDuty
);
// OL Commutate
/*
(bldc.comDir) ? (bldc.comState ++) : (bldc.comState --); (bldc.comDir) ? (bldc.comState ++) : (bldc.comState --);
if(bldc.comState > 5){ if(bldc.comState > 5){
bldc.comState = 0; bldc.comState = 0;
...@@ -241,10 +275,15 @@ ISR(TCD0_OVF_vect){ ...@@ -241,10 +275,15 @@ ISR(TCD0_OVF_vect){
comTable[bldc.comState][1] * bldc.comDuty, comTable[bldc.comState][1] * bldc.comDuty,
comTable[bldc.comState][2] * bldc.comDuty comTable[bldc.comState][2] * bldc.comDuty
); );
*/
} }
// acceleration timer // acceleration timer
ISR(TCD1_OVF_vect){ ISR(TCD1_OVF_vect){
// CL Commutate: PID Speed Loop
// OL Commutate: Acceleration to Speed
/*
if(bldc.currentSpeed != bldc.targetSpeed){ if(bldc.currentSpeed != bldc.targetSpeed){
if(bldc.currentSpeed < bldc.targetSpeed){ if(bldc.currentSpeed < bldc.targetSpeed){
bldc.currentSpeed ++; bldc.currentSpeed ++;
...@@ -254,6 +293,7 @@ ISR(TCD1_OVF_vect){ ...@@ -254,6 +293,7 @@ ISR(TCD1_OVF_vect){
bldc_setSpeed(&bldc, bldc.currentSpeed); bldc_setSpeed(&bldc, bldc.currentSpeed);
} }
} }
*/
} }
ISR(USARTE1_RXC_vect){ ISR(USARTE1_RXC_vect){
......
...@@ -23,8 +23,8 @@ void spi_start(spiport_t *spi, uint8_t cpha){ ...@@ -23,8 +23,8 @@ void spi_start(spiport_t *spi, uint8_t cpha){
spi->port->DIRCLR = spi->miso_bm; spi->port->DIRCLR = spi->miso_bm;
// want BSEL 7 and BSCALE -4 // want BSEL 7 and BSCALE -4
spi->com->BAUDCTRLA = 0; //130; spi->com->BAUDCTRLA = 12; //130;
spi->com->BAUDCTRLB = 1; //USART_BSCALE3_bm | USART_BSCALE2_bm | USART_BSCALE1_bm | USART_BSCALE0_bm; spi->com->BAUDCTRLB = 0; //USART_BSCALE3_bm | USART_BSCALE2_bm | USART_BSCALE1_bm | USART_BSCALE0_bm;
spi->com->CTRLB = USART_TXEN_bm | USART_RXEN_bm; spi->com->CTRLB = USART_TXEN_bm | USART_RXEN_bm;
...@@ -42,13 +42,23 @@ void spi_txchar_polled(spiport_t *spi, uint8_t data){ ...@@ -42,13 +42,23 @@ void spi_txchar_polled(spiport_t *spi, uint8_t data){
void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length){ void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length){
pin_clear(spi->csn); pin_clear(spi->csn);
for(int i = 0; i < length; i ++){ for(int i = 0; i < length; i ++){
spi->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag
spi_txchar_polled(spi, data[i]); spi_txchar_polled(spi, data[i]);
spi->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag
} }
while(!(spi->com->STATUS & USART_TXCIF_bm)); // wait for complete before while(!(spi->com->STATUS & USART_TXCIF_bm)); // wait for complete before
pin_set(spi->csn); pin_set(spi->csn);
} }
void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata){ void spi_txrxchars_polled(spiport_t *spi, uint8_t *data, uint8_t *result, uint8_t length){
// how to read? pin_clear(spi->csn);
for(int i = 0; i < length; i ++){
// rm'd extra clear of txcomplete flag
while(!(spi->com->STATUS & USART_DREIF_bm)); // wait for data register empty
spi->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag
spi->com->DATA = data[i]; // tx this
while(!(spi->com->STATUS & USART_TXCIF_bm)); // wait for complete before
while(!(spi->com->STATUS & USART_RXCIF_bm)); // wait for rx complete
result[i] = spi->com->DATA; // this is incoming (when read DATA reg, rx, when write, TX)
}
pin_set(spi->csn);
} }
\ No newline at end of file
...@@ -30,6 +30,7 @@ void spi_start(spiport_t *spi, uint8_t cpha); // bits: 0: 8, 1: 32 ...@@ -30,6 +30,7 @@ void spi_start(spiport_t *spi, uint8_t cpha); // bits: 0: 8, 1: 32
void spi_txchar_polled(spiport_t *spi, uint8_t data); void spi_txchar_polled(spiport_t *spi, uint8_t data);
void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length); void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length);
void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata); void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata);
void spi_txrxchars_polled(spiport_t *spi, uint8_t *data, uint8_t *result, uint8_t length);
#endif /* SPIPORT_H_ */ #endif /* SPIPORT_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