1#include "../hardware_api.h"
3#if defined(__arm__) && defined(__SAM3X8E__)
7#pragma message("SimpleFOC: compiling for Arduino/Due")
11#define _PWM_FREQUENCY 25000
12#define _PWM_FREQUENCY_MAX 50000
14#define _PWM_RES_MIN 255
17static unsigned long _pwm_frequency;
18static int _max_pwm_value = 1023;
21static IRQn_Type irq_type[] = {TC0_IRQn, TC0_IRQn, TC1_IRQn, TC1_IRQn, TC2_IRQn, TC2_IRQn, TC3_IRQn, TC3_IRQn, TC4_IRQn, TC4_IRQn, TC5_IRQn, TC5_IRQn, TC6_IRQn, TC6_IRQn, TC7_IRQn, TC7_IRQn, TC8_IRQn, TC8_IRQn};
23static volatile uint32_t pwm_counter_vals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
27static uint8_t PWMEnabled = 0;
28static uint8_t TCChanEnabled[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
29static const uint32_t channelToChNo[] = { 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2 };
30static const uint32_t channelToAB[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
31static Tc *channelToTC[] = {
32 TC0, TC0, TC0, TC0, TC0, TC0,
33 TC1, TC1, TC1, TC1, TC1, TC1,
34 TC2, TC2, TC2, TC2, TC2, TC2 };
35static const uint32_t channelToId[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
39static void TC_SetCMR_ChannelA(Tc *tc, uint32_t chan, uint32_t v){ tc->TC_CHANNEL[chan].TC_CMR = (tc->TC_CHANNEL[chan].TC_CMR & 0xFFF0FFFF) | v;}
40static void TC_SetCMR_ChannelB(Tc *tc, uint32_t chan, uint32_t v){ tc->TC_CHANNEL[chan].TC_CMR = (tc->TC_CHANNEL[chan].TC_CMR & 0xF0FFFFFF) | v; }
45void syncTimers(uint32_t ulPin1,uint32_t ulPin2, uint32_t ulPin3 = -1, uint32_t ulPin4 = -1){
46 uint32_t chNo1,chNo2,chNo3,chNo4;
47 Tc *chTC1 =
nullptr,*chTC2 =
nullptr,*chTC3 =
nullptr,*chTC4 =
nullptr;
50 uint32_t attr = g_APinDescription[ulPin1].ulPinAttribute;
51 if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
52 ETCChannel channel1 = g_APinDescription[ulPin1].ulTCChannel;
53 chNo1 = channelToChNo[channel1];
54 chTC1 = channelToTC[channel1];
55 TCChanEnabled[channelToId[channel1]] = 1;
59 attr = g_APinDescription[ulPin2].ulPinAttribute;
60 if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
61 ETCChannel channel2 = g_APinDescription[ulPin2].ulTCChannel;
62 chNo2 = channelToChNo[channel2];
63 chTC2 = channelToTC[channel2];
64 TCChanEnabled[channelToId[channel2]] = 1;
68 attr = g_APinDescription[ulPin3].ulPinAttribute;
69 if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
70 ETCChannel channel3 = g_APinDescription[ulPin3].ulTCChannel;
71 chNo3 = channelToChNo[channel3];
72 chTC3 = channelToTC[channel3];
73 TCChanEnabled[channelToId[channel3]] = 1;
78 attr = g_APinDescription[ulPin4].ulPinAttribute;
79 if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
80 ETCChannel channel4 = g_APinDescription[ulPin4].ulTCChannel;
81 chNo4 = channelToChNo[channel4];
82 chTC4 = channelToTC[channel4];
83 TCChanEnabled[channelToId[channel4]] = 1;
88 TC_Start(chTC1, chNo1);
89 chTC1->TC_BCR = TC_BCR_SYNC;
92 TC_Start(chTC2, chNo2);
93 chTC2->TC_BCR = TC_BCR_SYNC;
96 TC_Start(chTC3, chNo3);
97 chTC3->TC_BCR = TC_BCR_SYNC;
100 TC_Start(chTC4, chNo4);
101 chTC4->TC_BCR = TC_BCR_SYNC;
107void initPWM(uint32_t ulPin, uint32_t pwm_freq){
109 uint32_t attr = g_APinDescription[ulPin].ulPinAttribute;
110 if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) {
114 pmc_enable_periph_clk(PWM_INTERFACE_ID);
119 uint32_t divisors[11] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024};
124 prescaler = (VARIANT_MCK / divisors[divisor]) / (pwm_freq*_max_pwm_value);
125 while ((prescaler > 255) && (divisor < 11)) {
127 prescaler = (VARIANT_MCK / divisors[divisor]) / (pwm_freq*_max_pwm_value);
130 prescaler = prescaler | (divisor << 8);
134 _max_pwm_value = (double)VARIANT_MCK / (
double)pwm_freq / (double)(prescaler);
136 PWM->PWM_CLK = prescaler;
141 uint32_t chan = g_APinDescription[ulPin].ulPWMChannel;
142 if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
144 PIO_Configure(g_APinDescription[ulPin].pPort,
145 g_APinDescription[ulPin].ulPinType,
146 g_APinDescription[ulPin].ulPin,
147 g_APinDescription[ulPin].ulPinConfiguration);
150 PWMC_ConfigureChannel(PWM_INTERFACE, chan, PWM_CMR_CPRE_CLKA, 0, 0);
151 PWMC_SetPeriod(PWM_INTERFACE, chan, _max_pwm_value);
152 PWMC_SetDutyCycle(PWM_INTERFACE, chan, 0);
153 PWMC_EnableChannel(PWM_INTERFACE, chan);
154 g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
159 if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
161 const uint32_t TC = VARIANT_MCK / 2 / pwm_freq ;
163 ETCChannel channel = g_APinDescription[ulPin].ulTCChannel;
164 uint32_t chNo = channelToChNo[channel];
165 uint32_t chA = channelToAB[channel];
166 Tc *chTC = channelToTC[channel];
167 uint32_t interfaceID = channelToId[channel];
169 if (!TCChanEnabled[interfaceID]) {
170 pmc_enable_periph_clk(TC_INTERFACE_ID + interfaceID);
171 TC_Configure(chTC, chNo,
172 TC_CMR_TCCLKS_TIMER_CLOCK1 |
174 TC_CMR_WAVSEL_UP_RC |
176 TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
177 TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR);
178 TC_SetRC(chTC, chNo, TC);
183 TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET);
185 TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET);
188 if ((g_pinStatus[ulPin] & 0xF) != PIN_STATUS_PWM) {
189 PIO_Configure(g_APinDescription[ulPin].pPort,
190 g_APinDescription[ulPin].ulPinType,
191 g_APinDescription[ulPin].ulPin,
192 g_APinDescription[ulPin].ulPinConfiguration);
193 g_pinStatus[ulPin] = (g_pinStatus[ulPin] & 0xF0) | PIN_STATUS_PWM;
196 chTC->TC_CHANNEL[chNo].TC_IER = TC_IER_CPAS
199 chTC->TC_CHANNEL[chNo].TC_IDR = ~TC_IER_CPAS
203 NVIC_EnableIRQ(irq_type[channel]);
210void setPwm(uint32_t ulPin, uint32_t ulValue) {
212 uint32_t attr = g_APinDescription[ulPin].ulPinAttribute;
213 if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) {
214 uint32_t chan = g_APinDescription[ulPin].ulPWMChannel;
215 PWMC_SetDutyCycle(PWM_INTERFACE, chan, ulValue);
219 if ((attr & PIN_ATTR_TIMER) == PIN_ATTR_TIMER) {
221 ETCChannel channel = g_APinDescription[ulPin].ulTCChannel;
222 Tc *chTC = channelToTC[channel];
223 uint32_t chNo = channelToChNo[channel];
226 if (channelToAB[channel])
227 TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR);
229 TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR);
233 const uint32_t TC = VARIANT_MCK / 2 / _pwm_frequency;
236 ulValue = ulValue * TC ;
237 pwm_counter_vals[channel] = ulValue / _max_pwm_value;
239 if (channelToAB[channel])
240 TC_SetCMR_ChannelA(chTC, chNo, TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET);
242 TC_SetCMR_ChannelB(chTC, chNo, TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_SET);
253 TC_GetStatus(TC0, 0);
255 if(pwm_counter_vals[0]) TC_SetRA(TC0, 0, pwm_counter_vals[0]);
256 if(pwm_counter_vals[1]) TC_SetRB(TC0, 0, pwm_counter_vals[1]);
262 TC_GetStatus(TC0, 1);
264 if(pwm_counter_vals[2]) TC_SetRA(TC0, 1, pwm_counter_vals[2]);
265 if(pwm_counter_vals[3]) TC_SetRB(TC0, 1, pwm_counter_vals[3]);
271 TC_GetStatus(TC0, 2);
273 if(pwm_counter_vals[4]) TC_SetRA(TC0, 2, pwm_counter_vals[4]);
274 if(pwm_counter_vals[5]) TC_SetRB(TC0, 2, pwm_counter_vals[5]);
279 TC_GetStatus(TC1, 0);
281 if(pwm_counter_vals[6]) TC_SetRA(TC1, 0, pwm_counter_vals[6]);
282 if(pwm_counter_vals[7]) TC_SetRB(TC1, 0, pwm_counter_vals[7]);
288 TC_GetStatus(TC1, 1);
290 if(pwm_counter_vals[8]) TC_SetRA(TC1, 1, pwm_counter_vals[8]);
291 if(pwm_counter_vals[9]) TC_SetRB(TC1, 1, pwm_counter_vals[9]);
297 TC_GetStatus(TC1, 2);
299 if(pwm_counter_vals[10]) TC_SetRA(TC1, 2, pwm_counter_vals[10]);
300 if(pwm_counter_vals[11]) TC_SetRB(TC1, 2, pwm_counter_vals[11]);
305 TC_GetStatus(TC2, 0);
307 if(pwm_counter_vals[12]) TC_SetRA(TC2, 0, pwm_counter_vals[12]);
308 if(pwm_counter_vals[13]) TC_SetRB(TC2, 0, pwm_counter_vals[13]);
314 TC_GetStatus(TC2, 1);
316 if(pwm_counter_vals[14]) TC_SetRA(TC2, 1, pwm_counter_vals[14]);
317 if(pwm_counter_vals[15]) TC_SetRB(TC2, 1, pwm_counter_vals[15]);
323 TC_GetStatus(TC2, 2);
325 if(pwm_counter_vals[16]) TC_SetRA(TC2, 2, pwm_counter_vals[16]);
326 if(pwm_counter_vals[17]) TC_SetRB(TC2, 2, pwm_counter_vals[17]);
340 if(!pwm_frequency || !
_isset(pwm_frequency) ) pwm_frequency = _PWM_FREQUENCY;
341 else pwm_frequency =
_constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX);
343 _pwm_frequency = pwm_frequency;
345 initPWM(
pinA, _pwm_frequency);
346 initPWM(
pinB, _pwm_frequency);
347 initPWM(
pinC, _pwm_frequency);
353 .pwm_frequency = pwm_frequency
365 if(!pwm_frequency || !
_isset(pwm_frequency)) pwm_frequency = _PWM_FREQUENCY;
366 else pwm_frequency =
_constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX);
368 _pwm_frequency = pwm_frequency;
370 initPWM(
pinA, _pwm_frequency);
371 initPWM(
pinB, _pwm_frequency);
377 .pwm_frequency = pwm_frequency
389 if(!pwm_frequency || !
_isset(pwm_frequency)) pwm_frequency = _PWM_FREQUENCY;
390 else pwm_frequency =
_constrain(pwm_frequency, 0, _PWM_FREQUENCY_MAX);
392 _pwm_frequency = pwm_frequency;
394 initPWM(
pinA, _pwm_frequency);
395 initPWM(
pinB, _pwm_frequency);
396 initPWM(
pinC, _pwm_frequency);
397 initPWM(pinD, _pwm_frequency);
403 .pwm_frequency = pwm_frequency
417 setPwm(p->
pins[0], _max_pwm_value*dc_a);
418 setPwm(p->
pins[1], _max_pwm_value*
dc_b);
419 setPwm(p->
pins[2], _max_pwm_value*
dc_c);
430 setPwm(p->
pins[0], _max_pwm_value*dc_1a);
431 setPwm(p->
pins[1], _max_pwm_value*
dc_1b);
432 setPwm(p->
pins[2], _max_pwm_value*
dc_2a);
433 setPwm(p->
pins[3], _max_pwm_value*
dc_2b);
444 setPwm(p->
pins[0], _max_pwm_value*dc_a);
445 setPwm(p->
pins[1], _max_pwm_value*
dc_b);
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 * _configure2PWM(long pwm_frequency, const int pinA, const int pinB)
void _writeDutyCycle2PWM(float dc_a, float dc_b, void *params)
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 _writeDutyCycle3PWM(float dc_a, float dc_b, float dc_c, void *params)
#define _constrain(amt, low, high)