SimpleFOClibrary 2.4.0
Loading...
Searching...
No Matches
atmega32u4_mcu.cpp
Go to the documentation of this file.
1
2#include "../../hardware_api.h"
3
4#if defined(__AVR_ATmega32U4__)
5
6#pragma message("")
7#pragma message("SimpleFOC: compiling for Arduino/ATmega32U4")
8#pragma message("")
9
10// set pwm frequency to 32KHz
11void _pinHighFrequency(const int pin){
12 // High PWM frequency
13 // reference: http://r6500.blogspot.com/2014/12/fast-pwm-on-arduino-leonardo.html
14 if (pin == 3 || pin == 11 ) {
15 TCCR0A = ((TCCR0A & 0b11111100) | 0x01); // configure the pwm phase-corrected mode
16 TCCR0B = ((TCCR0B & 0b11110000) | 0x01); // set prescaler to 1
17 }
18 else if (pin == 9 || pin == 10 )
19 TCCR1B = ((TCCR1B & 0b11111000) | 0x01); // set prescaler to 1
20 else if (pin == 5 )
21 TCCR3B = ((TCCR3B & 0b11111000) | 0x01); // set prescaler to 1
22 else if ( pin == 6 || pin == 13 ) { // a bit more complicated 10 bit timer
23 // PLL Configuration
24 PLLFRQ= ((PLLFRQ & 0b11001111) | 0x20); // Use 96MHz / 1.5 = 64MHz
25 TCCR4B = ((TCCR4B & 0b11110000) | 0xB); // configure prescaler to get 64M/2/1024 = 31.25 kHz
26 TCCR4D = ((TCCR4D & 0b11111100) | 0x01); // configure the pwm phase-corrected mode
27
28 if (pin == 6) TCCR4A = 0x82; // activate channel A - pin 13
29 else if (pin == 13) TCCR4C |= 0x09; // Activate channel D - pin 6
30 }
31
32}
33
34
35// function setting the high pwm frequency to the supplied pins
36// - Stepper motor - 2PWM setting
37// - hardware speciffic
38void* _configure1PWM(long pwm_frequency,const int pinA) {
39 // High PWM frequency
40 // - always max 32kHz
41 _pinHighFrequency(pinA);
43 .pins = { pinA },
44 .pwm_frequency = pwm_frequency,
45 .dead_zone = 0.0f
46 };
47 return params;
48}
49
50// function setting the high pwm frequency to the supplied pins
51// - Stepper motor - 2PWM setting
52// - hardware speciffic
53void* _configure2PWM(long pwm_frequency,const int pinA, const int pinB) {
54 // High PWM frequency
55 // - always max 32kHz
56 _pinHighFrequency(pinA);
57 _pinHighFrequency(pinB);
59 .pins = { pinA, pinB },
60 .pwm_frequency = pwm_frequency,
61 .dead_zone = 0.0f
62 };
63 return params;
64}
65
66// function setting the high pwm frequency to the supplied pins
67// - BLDC motor - 3PWM setting
68// - hardware speciffic
69void* _configure3PWM(long pwm_frequency,const int pinA, const int pinB, const int pinC) {
70 // High PWM frequency
71 // - always max 32kHz
72 _pinHighFrequency(pinA);
73 _pinHighFrequency(pinB);
74 _pinHighFrequency(pinC);
76 .pins = { pinA, pinB, pinC },
77 .pwm_frequency = pwm_frequency,
78 .dead_zone = 0.0f
79 };
80 return params;
81}
82
83
84
85// function setting the pwm duty cycle to the hardware
86// - Stepper motor - 2PWM setting
87// - hardware speciffic
88void _writeDutyCycle1PWM(float dc_a, void* params){
89 // transform duty cycle from [0,1] to [0,255]
90 analogWrite(((GenericDriverParams*)params)->pins[0], 255.0f*dc_a);
91}
92
93
94// function setting the pwm duty cycle to the hardware
95// - Stepper motor - 2PWM setting
96// - hardware speciffic
97void _writeDutyCycle2PWM(float dc_a, float dc_b, void* params){
98 // transform duty cycle from [0,1] to [0,255]
99 analogWrite(((GenericDriverParams*)params)->pins[0], 255.0f*dc_a);
100 analogWrite(((GenericDriverParams*)params)->pins[1], 255.0f*dc_b);
101}
102
103// function setting the pwm duty cycle to the hardware
104// - BLDC motor - 3PWM setting
105// - hardware speciffic
106void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, int pinA, void* params){
107 // transform duty cycle from [0,1] to [0,255]
108 analogWrite(((GenericDriverParams*)params)->pins[0], 255.0f*dc_a);
109 analogWrite(((GenericDriverParams*)params)->pins[1], 255.0f*dc_b);
110 analogWrite(((GenericDriverParams*)params)->pins[2], 255.0f*dc_c);
111}
112
113// function setting the high pwm frequency to the supplied pins
114// - Stepper motor - 4PWM setting
115// - hardware speciffic
116void* _configure4PWM(long pwm_frequency,const int pin1A, const int pin1B, const int pin2A, const int pin2B) {
117 // High PWM frequency
118 // - always max 32kHz
119 _pinHighFrequency(pin1A);
120 _pinHighFrequency(pin1B);
121 _pinHighFrequency(pin2A);
122 _pinHighFrequency(pin2B);
124 .pins = { pin1A, pin1B, pin2A, pin2B },
125 .pwm_frequency = pwm_frequency,
126 .dead_zone = 0.0f
127 };
128 return params;
129}
130
131// function setting the pwm duty cycle to the hardware
132// - Stepper motor - 4PWM setting
133// - hardware speciffic
134void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void* params){
135 // transform duty cycle from [0,1] to [0,255]
136 analogWrite(((GenericDriverParams*)params)->pins[0], 255.0f*dc_1a);
137 analogWrite(((GenericDriverParams*)params)->pins[1], 255.0f*dc_1b);
138 analogWrite(((GenericDriverParams*)params)->pins[2], 255.0f*dc_2a);
139 analogWrite(((GenericDriverParams*)params)->pins[3], 255.0f*dc_2b);
140}
141
142
143
144
145// function configuring pair of high-low side pwm channels, 32khz frequency and center aligned pwm
146int _configureComplementaryPair(int pinH, int pinL) {
147 if( (pinH == 3 && pinL == 11 ) || (pinH == 11 && pinL == 3 ) ){
148 // configure the pwm phase-corrected mode
149 TCCR0A = ((TCCR0A & 0b11111100) | 0x01);
150 // configure complementary pwm on low side
151 if(pinH == 11 ) TCCR0A = 0b10110000 | (TCCR0A & 0b00001111) ;
152 else TCCR0A = 0b11100000 | (TCCR0A & 0b00001111) ;
153 // set prescaler to 1 - 32kHz freq
154 TCCR0B = ((TCCR0B & 0b11110000) | 0x01);
155 }else if( (pinH == 9 && pinL == 10 ) || (pinH == 10 && pinL == 9 ) ){
156 // set prescaler to 1 - 32kHz freq
157 TCCR1B = ((TCCR1B & 0b11111000) | 0x01);
158 // configure complementary pwm on low side
159 if(pinH == 9 ) TCCR1A = 0b10110000 | (TCCR1A & 0b00001111) ;
160 else TCCR1A = 0b11100000 | (TCCR1A & 0b00001111) ;
161 }else if((pinH == 6 && pinL == 13 ) || (pinH == 13 && pinL == 6 ) ){
162 // PLL Configuration
163 PLLFRQ= ((PLLFRQ & 0b11001111) | 0x20); // Use 96MHz / 1.5 = 64MHz
164 TCCR4B = ((TCCR4B & 0b11110000) | 0xB); // configure prescaler to get 64M/2/1024 = 31.25 kHz
165 TCCR4D = ((TCCR4D & 0b11111100) | 0x01); // configure the pwm phase-corrected mode
166
167 // configure complementary pwm on low side
168 if(pinH == 13 ){
169 TCCR4A = 0x82; // activate channel A - pin 13
170 TCCR4C |= 0x0d; // Activate complementary channel D - pin 6
171 }else {
172 TCCR4C |= 0x09; // Activate channel D - pin 6
173 TCCR4A = 0xc2; // activate complementary channel A - pin 13
174 }
175 }else{
176 return -1;
177 }
178 return 0;
179}
180
181
182// Configuring PWM frequency, resolution and alignment
183// - BLDC driver - 6PWM setting
184// - hardware specific
185void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l) {
186 // High PWM frequency
187 // - always max 32kHz
188 int ret_flag = 0;
189 ret_flag += _configureComplementaryPair(pinA_h, pinA_l);
190 ret_flag += _configureComplementaryPair(pinB_h, pinB_l);
191 ret_flag += _configureComplementaryPair(pinC_h, pinC_l);
192 if (ret_flag!=0) return SIMPLEFOC_DRIVER_INIT_FAILED;
195 .pwm_frequency = pwm_frequency,
196 .dead_zone = dead_zone
197 };
198 return params;
199}
200
201// function setting the
202void _setPwmPair(int pinH, int pinL, float val, int dead_time)
203{
204 int pwm_h = _constrain(val-dead_time/2,0,255);
205 int pwm_l = _constrain(val+dead_time/2,0,255);
206
207 analogWrite(pinH, pwm_h);
208 if(pwm_l == 255 || pwm_l == 0)
209 digitalWrite(pinL, pwm_l ? LOW : HIGH);
210 else
211 analogWrite(pinL, pwm_l);
212}
213
214// Function setting the duty cycle to the pwm pin (ex. analogWrite())
215// - BLDC driver - 6PWM setting
216// - hardware specific
217// supports Arudino/ATmega328
218void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void* params){
219 _setPwmPair(((GenericDriverParams*)params)->pins[0], ((GenericDriverParams*)params)->pins[1], dc_a*255.0, ((GenericDriverParams*)params)->dead_zone*255.0);
220 _setPwmPair(((GenericDriverParams*)params)->pins[2], ((GenericDriverParams*)params)->pins[3], dc_b*255.0, ((GenericDriverParams*)params)->dead_zone*255.0);
221 _setPwmPair(((GenericDriverParams*)params)->pins[4], ((GenericDriverParams*)params)->pins[5], dc_c*255.0, ((GenericDriverParams*)params)->dead_zone*255.0);
222
224}
225
226#endif
PhaseState
Definition FOCDriver.h:7
const int const int const int pinC
GenericCurrentSenseParams * params
void * _configure4PWM(long pwm_frequency, const int pin1A, const int pin1B, const int pin2A, const int pin2B)
void * _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, const int pinA_l, const int pinB_h, const int pinB_l, const int pinC_h, const int pinC_l)
void * _configure2PWM(long pwm_frequency, const int pinA, const int pinB)
void _writeDutyCycle2PWM(float dc_a, float dc_b, void *params)
void _writeDutyCycle1PWM(float dc_a, void *params)
#define SIMPLEFOC_DRIVER_INIT_FAILED
void _writeDutyCycle4PWM(float dc_1a, float dc_1b, float dc_2a, float dc_2b, void *params)
void * _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const int pinC)
void _writeDutyCycle6PWM(float dc_a, float dc_b, float dc_c, PhaseState *phase_state, void *params)
void * _configure1PWM(long pwm_frequency, const int pinA)
void _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void *params)
float const int const int const int pinB_h
float const int const int const int const int pinB_l
const int const int pin1B
const int const int const int pin2A
float const int const int const int const int const int pinC_h
float float float dc_2b
float float PhaseState * phase_state
float const int const int const int const int const int const int pinC_l
float const int const int pinA_l
analogWrite(((GenericDriverParams *) params) ->pins[1], 255.0f *dc_b)
const int const int const int const int pin2B
#define _UNUSED(v)
Definition foc_utils.h:14
#define _constrain(amt, low, high)
Definition foc_utils.h:11