| BLDC control on ATAVRMC303 with ATxMega128A1

mc_drv.c
Go to the documentation of this file.
1
15 //_____ I N C L U D E S ___________________________________________________
16
17 #include "config.h"
18
19 #include "mc_drv.h"
20 #include "mc_interface.h"
21 #include "mc_control.h"
22
23 #include "adc\adc_drv.h"
24 #include "dac\Dac_drv.h"
25 #include "pll\pll_drv.h"
26 #include "comparator\comparator_drv.h"
27 #include "awex_driver.h"
28 #include "TC_driver.h"
29 #include "hires_driver.h"
30 #include "adc_driver.h"
31 U8 count = 1; // variable "count" is use for calculate the "average" speed on 'n' samples
32 U16 average = 0;
33 U8 ovf_timer = 0; // variable "ovf_timer" is use to simulate a 16 bits timer with 8 bits timer
34
35 Bool inrush_mask_flag = FALSE;
36 U16 inrush_delay = 0;
37
38 Bool g_mc_read_enable = FALSE; // the speed can be read
39 Bool g_tick = FALSE;
40 Bool hall1_old_val = 1;
41
42 Bool current_EOC = FALSE; //End Of Conversion Flag
43
44 char State = CONV_INIT; // State of the ADC scheduler
45 char ADC_State = FREE; // ADC State : running = BUSY not running = FREE
46
47 volatile char offset=0;
48 /******************************************************************************/
49 /******************************************************************************/
50 /* Hardware Initialization */
51 /******************************************************************************/
52 /******************************************************************************/
53 void ADC_Init()
54 {
55 /* Move stored calibration values to ADC B. */
56 ADC_CalibrationValues_Set(&ADCB);
57
58 /* Get offset value for ADC B. */
59 offset = ADC_Offset_Get(&ADCB);
60
61 /* Set up ADC B to have signed conversion mode and 12 bit resolution. */
62 ADC_ConvMode_and_Resolution_Config(&ADCB, true, ADC_RESOLUTION_12BIT_gc);
63
64 /* Sample rate is CPUFREQ/16. Allow time for storing data. */
65 ADC_Prescaler_Config(&ADCB, ADC_PRESCALER_DIV16_gc);
66
67 /* Set referance voltage on ADC B to be VCC-0.6 V.*/
68 ADC_Referance_Config(&ADCB, ADC_REFSEL_INTVCC_gc);
69
70 /* Setup channel 0, 1, 2 and 3 to have single ended input. */
71 ADC_Ch_InputMode_and_Gain_Config(&ADCB.CH0,
72 ADC_CH_INPUTMODE_SINGLEENDED_gc,
73 ADC_CH_GAIN_1X_gc);
74
75 /* Set input to the channels in ADC B to be PIN 0. */
76 ADC_Ch_InputMux_Config(&ADCB.CH0, ADC_CH_MUXPOS_PIN0_gc, ADC_CH_MUXNEG_PIN0_gc);
77
78 /* Enable ADC B with free running mode, VCC reference and signed conversion.*/
79 ADC_Enable(&ADCB);
80
81 /* Wait until common mode voltage is stable. Default clk is 2MHz and
82 * therefore below the maximum frequency to use this function. */
83 ADC_Wait_8MHz(&ADCB);
84
85 /* Enable free running mode. */
86 ADC_FreeRunning_Enable(&ADCB);
87
88 }
89
95 void mc_init_HW(void)
96
97 {
98
99 //Do not modify PSCOUT Configuration
100 // PORT C :
101 PORTC.DIRSET = (PIN0_bm | PIN1_bm | PIN2_bm | PIN3_bm | PIN4_bm | PIN5_bm);
102 PORTC.OUTCLR = (PIN0_bm | PIN1_bm | PIN2_bm | PIN3_bm | PIN4_bm | PIN5_bm);
103
104 // Hall sensor input pull up activation
105 PORTE.DIRCLR = (PIN0_bm | PIN1_bm | PIN2_bm);
106
107 //Initialization of AT90PWM3 External Interrupts
108 PORTE.INTCTRL = PORT_INT0LVL_LO_gc;
109 PORTE.INT0MASK = (PIN0_bm | PIN1_bm | PIN2_bm);
110 PORTCFG.MPCMASK = (PIN0_bm | PIN1_bm | PIN2_bm);
111 PORTE.PIN0CTRL = PORT_ISC_BOTHEDGES_gc;
112
113
114 // In Center Aligned Mode :
115 // => PSCx_Init(Period_Half, Dutyx0_Half, Synchro, Dutyx1_Half)
116 PWM_Init(255);
117
118 mc_init_timer0();
119 mc_init_timer1();
120
121 ADC_Init();
122
123 }
124
130 void init_amplifier_1(void)
131 {
132 // AMP1CSR = (1<<AMP1EN) /* amplifier enable */ \
133 // | (1<<AMP1G1)|(0<<AMP1G0) /* gain = 20 */ \
134 // | (0<<AMP1TS1)|(1<<AMP1TS0) /* clock from PSC0 */ ;
135 }
136
137 // PSC initialization depend on the PSC mode
138 // 0- One ramp Mode
139 // 1- Two ramp Mode
140 // 2- Four ramp Mode
141 // 3- Center Aligned Mode
142 void ConfigDTI( U8 deadTime )
143 {
144 /* Configure dead time insertion. */
145 AWEX_EnableDeadTimeInsertion( &AWEXC, AWEX_DTICCAEN_bm |AWEX_DTICCBEN_bm|AWEX_DTICCCEN_bm );
146 AWEX_SetOutputOverrideValue( AWEXC, 0xFF );
147 AWEX_SetDeadTimesSymmetricalUnbuffered( AWEXC, deadTime );
148 }
149
153 void PWM_Init ( unsigned int OCRnRB)
154 {
155 ConfigDTI( 3 );
156 TCC0.PER = OCRnRB;
157 TCC0.CTRLB = TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm| TC_WGMODE_DS_T_gc;
158 TCC0.INTCTRLA = TC_OVFINTLVL_LO_gc;
159 TCC0.CTRLA = TC_CLKSEL_DIV4_gc;
160
161 AWEX_SetOutputOverrideValue( AWEXC, 0 );
162 AWEX_EnableCommonWaveformChannelMode(AWEXC);
163 }
164
165
166 /***************************************************************************/
167 /***************************************************************************/
168 /* All functions for motor's phases commutation */
169 /***************************************************************************/
170 /***************************************************************************/
171
179 U8 mc_get_hall(void)
180 {
181 return HALL_SENSOR_VALUE();
182 }
183
190 #pragma vector = HALL_A()
191 __interrupt void mc_hall_a(void)
192 {
193 mc_switch_commutation(HALL_SENSOR_VALUE());
194
195 //estimation speed on rising edge of Hall_A
196 if ((hall1_old_val == 0) && (PORTE.IN & PIN0_bm))
197 {
198 mc_estimation_speed();
199 g_mc_read_enable=FALSE; // Wait 1 period
200 }
201 else
202 {
203 g_mc_read_enable=TRUE;
204 }
205 hall1_old_val = (PORTE.IN & PIN0_bm);
206 }
207
208
212 void mc_duty_cycle(U8 level)
213 {
214 /* Output new compare value. */
215 TC_SetCompareA( &TCC0, level );
216 TC_SetCompareB( &TCC0, level );
217 TC_SetCompareC( &TCC0, level );
218 }
219
226 void mc_switch_commutation(U8 position)
227 {
228 // get the motor direction to commute the right switches.
229 char direction = mc_get_motor_direction();
230
231 // Switches are commuted only if the user start the motor and
232 // the speed consign is different from 0.
233 if ((mc_motor_is_running()) && (mc_get_motor_speed()!=0))
234 {
235 mc_duty_cycle(mc_get_Duty_Cycle());
236 switch(position)
237 {
238 // cases according to rotor position
239 case HS_001: if (direction==CCW) {Set_Q1Q6();}
240 else {Set_Q5Q2();}
241 break;
242
243 case HS_101: if (direction==CCW) {Set_Q3Q6();}
244 else {Set_Q5Q4();}
245 break;
246
247 case HS_100: if (direction==CCW) {Set_Q3Q2();}
248 else {Set_Q1Q4();}
249 break;
250
251 case HS_110: if (direction==CCW) {Set_Q5Q2();}
252 else {Set_Q1Q6();}
253 break;
254
255 case HS_010: if (direction==CCW) {Set_Q5Q4();}
256 else {Set_Q3Q6();}
257 break;
258
259 case HS_011: if (direction==CCW) {Set_Q1Q4();}
260 else {Set_Q3Q2();}
261 break;
262 default : break;
263 }
264 }
265 else
266 {
267 Set_none(); // all switches are switched OFF
268 }
269 }
270
271 /******************************************************************************/
272 /******************************************************************************/
273 /* TIMER 1 : generate the g_tick */
274 /******************************************************************************/
275 /******************************************************************************/
276
283 void mc_init_timer1(void)
284 {
285 TCD1.PER = 8000;
286 TCD1.INTCTRLA = TC_OVFINTLVL_LO_gc;
287 TCD1.CTRLA = TC_CLKSEL_DIV1_gc;
288 }
289
295 #pragma vector = TCD1_OVF_vect
296 __interrupt void launch_sampling_period(void)
297 {
298 g_tick = TRUE;
299 }
300
301 /******************************************************************************/
302 /******************************************************************************/
303 /* TIMER 0 : Speed Measurement */
304 /******************************************************************************/
305 /******************************************************************************/
306
313 void mc_init_timer0(void)
314 {
315 TCD0.PER = 0xFFFF;
316 TCD0.INTCTRLA = TC_OVFINTLVL_LO_gc;
317 TCD0.CTRLA = TC_CLKSEL_DIV256_gc;
318 }
319
326 #pragma vector = TCD0_OVF_vect
327 __interrupt void ovfl_timer0(void)
328 {
329 mc_set_motor_measured_speed(0);
330 //if the motor was turning and no stop order
331 // was given, motor run automatically.
332 if(mc_motor_is_running())mci_retry_run();
333
334 }
335
342 void mc_estimation_speed(void)
343 {
344 U16 timer_value;
345 U32 new_measured_speed;
346
347 if (g_mc_read_enable==TRUE)
348 {
349 // Two 8 bits variables are use to simulate a 16 bits timers
350 timer_value = TCD0.CNT/2;
351
352 if (timer_value == 0) {timer_value += 1 ;} // warning DIV by 0
353 new_measured_speed = K_SPEED / timer_value;
354 if(new_measured_speed > 255) new_measured_speed = 255; // Variable saturation
355
356
357 #ifdef AVERAGE_SPEED_MEASURE
358 // To avoid noise an average is realized on 8 samples
359 average += new_measured_speed;
360 if(count >= n_SAMPLE)
361 {
362 count = 1;
363 mc_set_motor_measured_speed(average >> 3);
364 average = 0;
365 }
366 else count++;
367 #else
368 // else get the real speed
369 mc_set_motor_measured_speed(new_measured_speed);
370 #endif
371
372 // Reset Timer 0 register and variables
373 TCD0.CNT = 0x00;
374 g_mc_read_enable=FALSE;
375 }
376 }
377
378 /******************************************************************************/
379 /******************************************************************************/
380 /* ADC use for current and potentiometer measurement */
381 /******************************************************************************/
382 /******************************************************************************/
388 void mc_ADC_Scheduler(void)
389 {
390 do{
391 /* If the conversion on the ADCB channel 0 never is
392 * complete this will be a deadlock. */
393 }while(!ADC_Ch_Conversion_Complete(&ADCB.CH0));
394 unsigned int value;
395 value = ADC_ResultCh_GetWord(&ADCB.CH0,offset);
396
397 value = ((value)>>4);
398 value = value + 140;
399 if ( (value&0xFF) < 150) value = 0;
400
401 //value = ((value>>2)&0x00FF);
402 //value = (0xFF - value)*2;
403 mc_set_potentiometer_value(value);
404 }
405
406 /******************************************************************************/
407 /******************************************************************************/
408 /* Over Current Configuration */
409 /******************************************************************************/
410 /******************************************************************************/
411
415 void mc_set_Over_Current(U8 Level)
416 {
417 //Set_dac_8_bits(Level);
418 }
419
422 void mc_disable_during_inrush(void)
423 {
424 inrush_delay = (U16) 1000;
425 inrush_mask_flag = TRUE;
426 //Disable_over_current();
427 }
428
431 void mc_inrush_task(void)
432 {
433 if (inrush_mask_flag == TRUE)
434 {
435 if (inrush_delay-- == 0)
436 {
437 inrush_mask_flag = FALSE;
438 // Enable_over_current();
439 }
440 }
441 }
inrush_mask_flag
Bool inrush_mask_flag
Definition: mc_drv.c:35
mc_set_Over_Current
void mc_set_Over_Current(U8 Level)
Set the Over Current threshold.
Definition: mc_drv.c:415
TC_SetCompareA
#define TC_SetCompareA(_tc, _compareValue)
Set new compare value for compare channel A. ( Double buffered )
Definition: TC_driver.h:169
mc_interface.h
mc_switch_commutation
void mc_switch_commutation(U8 position)
Set the Switching Commutation value on outputs according to sensor or estimation position.
Definition: mc_drv.c:226
g_tick
Bool g_tick
Use for control the sampling period value.
Definition: mc_drv.c:39
inrush_delay
U16 inrush_delay
Definition: mc_drv.c:36
mc_init_timer1
void mc_init_timer1(void)
timer 1 Configuration Use to generate a 250us activation for sampling speed regulation ...
Definition: mc_drv.c:283
Set_Q1Q6
#define Set_Q1Q6()
Definition: mc_drv.h:70
ADC_ResultCh_GetWord
uint16_t ADC_ResultCh_GetWord(ADC_CH_t *adc_ch, uint8_t offset)
This function clears the interrupt flag and returns the coversion result.
Definition: adc_driver.c:98
ADC_Init
void ADC_Init()
Definition: mc_drv.c:53
Set_Q5Q2
#define Set_Q5Q2()
Definition: mc_drv.h:76
ADC_Offset_Get
uint8_t ADC_Offset_Get(ADC_t *adc)
This function get the offset of the ADC.
Definition: adc_driver.c:241
mc_init_timer0
void mc_init_timer0(void)
Timer 0 Configuration The timer 0 is used to generate an IT when an overflow occurs.
Definition: mc_drv.c:313
mc_get_motor_direction
U8 mc_get_motor_direction(void)
Definition: mc_interface.c:148
CONV_INIT
#define CONV_INIT
Definition: mc_drv.h:119
ADC_CalibrationValues_Set
void ADC_CalibrationValues_Set(ADC_t *adc)
This function get the calibration data from the production calibration.
Definition: adc_driver.c:77
AWEX_SetDeadTimesSymmetricalUnbuffered
#define AWEX_SetDeadTimesSymmetricalUnbuffered(_awex, _deadTime)
This macro sets an equal dead time for high and low side.
Definition: awex_driver.h:147
config.h
,v
Set_none
#define Set_none()
Definition: mc_drv.h:66
mc_motor_is_running
Bool mc_motor_is_running(void)
get the motor state
Definition: mc_interface.c:70
Set_Q3Q2
#define Set_Q3Q2()
Definition: mc_drv.h:72
mc_drv.h
ADC_ConvMode_and_Resolution_Config
#define ADC_ConvMode_and_Resolution_Config(_adc, _signedMode, _resolution)
This macro set the conversion mode and resolution in the selected adc.
Definition: adc_driver.h:110
g_mc_read_enable
Bool g_mc_read_enable
Definition: mc_drv.c:38
ADC_Ch_InputMode_and_Gain_Config
#define ADC_Ch_InputMode_and_Gain_Config(_adc_ch, _inputMode, _gain)
This macro configures the input mode and gain to a specific virtual channel.
Definition: adc_driver.h:197
AWEX_EnableCommonWaveformChannelMode
#define AWEX_EnableCommonWaveformChannelMode(_awex)
This macro enables the Common Waveform Channel mode.
Definition: awex_driver.h:71
Set_Q3Q6
#define Set_Q3Q6()
Definition: mc_drv.h:74
mci_retry_run
void mci_retry_run(void)
mci_retry_run retry to run if speed is null
Definition: mc_interface.c:55
HS_101
Definition: config_motor.h:23
mc_duty_cycle
void mc_duty_cycle(U8 level)
Set the duty cycle values in the PSC according to the value calculate by the regulation loop...
Definition: mc_drv.c:212
ADC_Prescaler_Config
#define ADC_Prescaler_Config(_adc, _div)
This macro set the prescaler factor in the selected adc.
Definition: adc_driver.h:127
init_amplifier_1
void init_amplifier_1(void)
init Amplifier 1
Definition: mc_drv.c:130
ADC_Ch_Conversion_Complete
#define ADC_Ch_Conversion_Complete(_adc_ch)
This macro returns the channel conversion complete flag..
Definition: adc_driver.h:222
ADC_Ch_InputMux_Config
#define ADC_Ch_InputMux_Config(_adc_ch, _posInput, _negInput)
This macro configures the Positiv and negativ inputs.
Definition: adc_driver.h:212
ADC_Referance_Config
#define ADC_Referance_Config(_adc, _convRef)
This macro set the conversion referance in the selected adc.
Definition: adc_driver.h:137
TC_driver.h
XMEGA Timer/Counter driver header file.
mc_inrush_task
void mc_inrush_task(void)
the purpose of this function is to manage the delay used when the overcurrent detection is disabled...
Definition: mc_drv.c:431
PWM_Init
void PWM_Init(unsigned int OCRnRB)
Initialization of PWM generator PSC0.
Definition: mc_drv.c:153
count
U8 count
Definition: mc_drv.c:31
launch_sampling_period
__interrupt void launch_sampling_period(void)
Launch the regulation loop (see main.c) .
Definition: mc_drv.c:296
HS_110
Definition: config_motor.h:23
hall1_old_val
Bool hall1_old_val
Definition: mc_drv.c:40
Set_Q5Q4
#define Set_Q5Q4()
Definition: mc_drv.h:78
mc_get_hall
U8 mc_get_hall(void)
Get the value of hall sensors (1 to 6)
Definition: mc_drv.c:179
mc_set_potentiometer_value
void mc_set_potentiometer_value(U8 potentiometer)
Set the &#39;mc_potentiometer_value&#39; variable with the potentiometer value.
Definition: mc_interface.c:209
average
U16 average
Definition: mc_drv.c:32
ovf_timer
U8 ovf_timer
Definition: mc_drv.c:33
mc_set_motor_measured_speed
void mc_set_motor_measured_speed(U8 measured_speed)
set Measured of speed (for initialization)
Definition: mc_interface.c:158
AWEX_EnableDeadTimeInsertion
void AWEX_EnableDeadTimeInsertion(AWEX_t *awex, uint8_t enableMask)
Enable Dead Time Insertion.
Definition: awex_driver.c:73
mc_get_Duty_Cycle
U8 mc_get_Duty_Cycle()
set type of regulation
Definition: mc_control.c:197
current_EOC
Bool current_EOC
Definition: mc_drv.c:42
HS_010
Definition: config_motor.h:23
HS_001
Definition: config_motor.h:23
ADC_FreeRunning_Enable
#define ADC_FreeRunning_Enable(_adc)
This macro enables the Free Running mode in the selected adc.
Definition: adc_driver.h:246
awex_driver.h
XMEGA AWeX driver header file.
mc_disable_during_inrush
void mc_disable_during_inrush(void)
the purpose of this function is to disable the overcurrent detection during startup (inrush current...
Definition: mc_drv.c:422
HALL_SENSOR_VALUE
#define HALL_SENSOR_VALUE()
Definition: mc_drv.h:53
Set_Q1Q4
#define Set_Q1Q4()
Definition: mc_drv.h:68
adc_driver.h
XMEGA ADC driver header file.
ADC_Wait_8MHz
void ADC_Wait_8MHz(ADC_t *adc)
This function waits until the adc common mode is settled.
Definition: adc_driver.c:182
K_SPEED
#define K_SPEED
Definition: config_motor.h:82
mc_ADC_Scheduler
void mc_ADC_Scheduler(void)
Launch the scheduler for the ADC.
Definition: mc_drv.c:388
HS_100
Definition: config_motor.h:23
n_SAMPLE
#define n_SAMPLE
Definition: config_motor.h:43
mc_estimation_speed
void mc_estimation_speed(void)
estimation speed
Definition: mc_drv.c:342
mc_init_HW
void mc_init_HW(void)
init HW
Definition: mc_drv.c:95
CCW
Definition: config_motor.h:34
TC_SetCompareB
#define TC_SetCompareB(_tc, _compareValue)
Set new compare value for compare channel B. ( Double buffered )
Definition: TC_driver.h:180
mc_hall_a
__interrupt void mc_hall_a(void)
External interruption Sensor (A) mode toggle.
Definition: mc_drv.c:191
FREE
#define FREE
Definition: mc_drv.h:123
mc_get_motor_speed
U8 mc_get_motor_speed(void)
Definition: mc_interface.c:118
mc_control.h
ADC_Enable
#define ADC_Enable(_adc)
This macro enables the selected adc.
Definition: adc_driver.h:83
ConfigDTI
void ConfigDTI(U8 deadTime)
Definition: mc_drv.c:142
AWEX_SetOutputOverrideValue
#define AWEX_SetOutputOverrideValue(_awex, _overrideValue)
This macro sets an output override value.
Definition: awex_driver.h:100
TC_SetCompareC
#define TC_SetCompareC(_tc, _compareValue)
Set new compare value for compare channel C. ( Double buffered )
Definition: TC_driver.h:193
hires_driver.h
XMEGA HiRes driver header file.
ADC_State
char ADC_State
Definition: mc_drv.c:45
offset
volatile char offset
Definition: mc_drv.c:47
State
char State
Definition: mc_drv.c:44
ovfl_timer0
__interrupt void ovfl_timer0(void)
Timer0 Overflow for speed measurement.
Definition: mc_drv.c:327
HS_011
Definition: config_motor.h:23