00001
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "config.h"
00044
00045 #include "mc_drv.h"
00046 #include "mc_interface.h"
00047 #include "mc_control.h"
00048
00049 #include "psc\psc_drv.h"
00050 #include "adc\adc_drv.h"
00051 #include "dac\dac_drv.h"
00052 #include "pll\pll_drv.h"
00053 #include "comparator\comparator_drv.h"
00054
00055 #define PSWAP0 2
00056 #define PSWAP1 3
00057 #define PSWAP2 4
00058
00059 Bool overcurrent = FALSE;
00060
00061 U8 count = 1;
00062 U16 average = 0;
00063 static volatile U8 timer0_ext = 0;
00064
00065 static Bool inrush_mask_flag = FALSE;
00066 static U16 inrush_delay = 0;
00067
00068 static U16 stored_time = 0;
00069
00070 static U32 top_average = 200;
00071
00072 static U8 motor_step;
00073
00074 volatile Bool g_tick = FALSE;
00075
00076 Bool current_EOC = FALSE;
00077
00078 static char State = CONV_INIT;
00079 static char ADC_State = FREE;
00080
00081
00082
00083
00084
00085
00086
00087
00090 void mc_init_HW(void)
00091 {
00092
00093
00094
00095
00096
00097
00098 PORTB &= ~(1<<PORTB7 | 1<<PORTB6 | 1<<PORTB1 | 1<<PORTB0);
00099 PORTC &= ~(1<<PORTC0);
00100 PORTD &= ~(1<<PORTD0);
00101
00102
00103 PORTB |= (1<<PORTB4)|(1<<PORTB3);
00104 PORTC |= (1<<PORTC3);
00105
00106
00107 #ifdef USE_INTERNAL_COMPARATORS
00108 #else
00109 PORTD |= (1<<PORTD7)|(1<<PORTD5);
00110 PORTC |= (1<<PORTC6);
00111 #endif
00112
00113
00114 DDRB = (1<<DDB7)|(1<<DDB6)|(1<<DDB1)|(1<<DDB0);
00115
00116 DDRC = (1<<DDC0);
00117
00118 DDRD = (1<<DDD0);
00119
00120 DDRE |= (1<<DDE2)|(1<<DDE1);
00121
00122 Init_PC7();
00123
00124
00125 DIDR1 = (1<<ADC9D)|(1<<ADC8D);
00126
00127
00128 #ifdef USE_INTERNAL_COMPARATORS
00129 DIDR0 = (1<<ADC6D)|(1<<ADC5D)|(1<<ADC3D)|(1<<ADC2D);
00130 DIDR1 = (1<<ADC10D)|(1<<ACMP0D);
00131 #endif
00132
00133
00134
00135
00136
00137 Adc_config();
00138 Amp1_config();
00139
00140
00141
00142 Dac_config();
00143
00144 Dac_set_8_bits(IMAX);
00145
00146 mc_init_timer0();
00147 mc_init_timer1();
00148
00149 Comp_0_config();
00150 Comp_1_config();
00151 Comp_2_config();
00152
00153
00154 PCMSK0 = (1<<PCINT4)|(1<<PCINT3);
00155 PCMSK1 = (1<<PCINT11);
00156 PCICR = (1<<PCIE1)|(1<<PCIE0);
00157
00158
00159 Start_pll_64_mega();
00160 Wait_pll_ready();
00161
00162
00163
00164 PSC_Init();
00165
00166 }
00167
00168
00169
00170
00172 void PSC_Init (void)
00173 {
00174 Psc_set_module_A(A_SA_VAL,A_RA_VAL,A_SB_VAL);
00175 Psc_set_module_B(B_SA_VAL,B_RA_VAL,B_SB_VAL);
00176 Psc_set_module_C(C_SA_VAL,C_RA_VAL,C_SB_VAL);
00177 Psc_set_register_RB(RB_VAL);
00178
00179 Psc_config();
00180
00181 Psc_config_input_0(PSC_OVERLAP_ENABLE,\
00182 PSC_USE_PIN,\
00183 PSC_USE_LOW_LEVEL,\
00184 PSC_INPUT_FILTER_ENABLE,\
00185 PSC_SYNCHRONOUS_OUTPUT_CONTROL,\
00186 PSC_INPUT_NO_ACTION);
00187
00188 Psc_config_input_1(PSC_OVERLAP_ENABLE,\
00189 PSC_USE_COMPARATOR,\
00190 PSC_USE_HIGH_LEVEL,\
00191 PSC_INPUT_FILTER_ENABLE,\
00192 PSC_SYNCHRONOUS_OUTPUT_CONTROL,\
00193 PSC_INPUT_NO_ACTION);
00194
00195 Psc_config_input_2(PSC_OVERLAP_ENABLE,\
00196 PSC_USE_PIN,\
00197 PSC_USE_LOW_LEVEL,\
00198 PSC_INPUT_FILTER_ENABLE,\
00199 PSC_SYNCHRONOUS_OUTPUT_CONTROL,\
00200 PSC_INPUT_NO_ACTION);
00201
00202 PIFR = (1<<PEV2)|(1<<PEV1)|(1<<PEV0)|(1<<PEOP);
00203 PIM = (1<<PEVE1);
00204
00205 Psc_run();
00206 }
00207
00208
00209
00210
00211
00212
00213
00221 Motor_Position mc_get_hall(void)
00222 {
00223 return HALL_SENSOR_VALUE();
00224 }
00225
00232 #ifdef __GNUC__
00233 ISR(HALL_A())
00234 #else
00235 #pragma vector = HALL_A()
00236 __interrupt void mc_hall_a(void)
00237 #endif
00238 {
00239
00240
00241
00242
00243 if (PINC&(1<<PORTC3))
00244 {
00245 mc_estimation_speed();
00246 }
00247
00248 }
00249
00256 #ifdef __GNUC__
00257 ISR(HALL_B())
00258 #else
00259 #pragma vector = HALL_B()
00260 __interrupt void mc_hall_b(void)
00261 #endif
00262 {
00263
00264
00265 }
00266
00267
00268
00272 void mc_duty_cycle(U8 level)
00273 {
00274 U8 duty;
00275 duty = level;
00276
00277 #if ((CURRENT_DECAY == SLOW_DECAY_SYNCHRONOUS)||(CURRENT_DECAY == FAST_DECAY_SYNCHRONOUS))
00278 U8 dutydt;
00279 if (duty >= DEADTIME) dutydt = duty - DEADTIME;
00280 #endif
00281
00282 Psc_lock();
00283
00284
00285
00286
00287 #if (CURRENT_DECAY == FAST_DECAY)
00288 Psc_set_module_A(duty,A_RA_VAL,duty);
00289 Psc_set_module_B(duty,B_RA_VAL,duty);
00290 Psc_set_module_C(duty,C_RA_VAL,duty);
00291 #else
00292 #if ((CURRENT_DECAY == SLOW_DECAY_SYNCHRONOUS)||(CURRENT_DECAY == FAST_DECAY_SYNCHRONOUS))
00293 Psc_set_module_A(duty,A_RA_VAL,dutydt);
00294 Psc_set_module_B(duty,B_RA_VAL,dutydt);
00295 Psc_set_module_C(duty,C_RA_VAL,dutydt);
00296 #else
00297 Psc_set_module_A(duty,A_RA_VAL,0);
00298 Psc_set_module_B(duty,B_RA_VAL,0);
00299 Psc_set_module_C(duty,C_RA_VAL,0);
00300 #endif
00301 #endif
00302
00303 Psc_unlock();
00304 }
00305
00311 void mc_switch_commutation(Motor_Position position)
00312 {
00313
00314 char direction = mci_get_motor_direction();
00315
00316
00317 if (mci_motor_is_running())
00318 {
00319 switch(position)
00320 {
00321
00322 case MS_001: {Set_Q1Q6();motor_step=MS_001;}
00323 break;
00324
00325 case MS_101: {Set_Q1Q4();motor_step=MS_101;}
00326 break;
00327
00328 case MS_100: {Set_Q5Q4();motor_step=MS_100;}
00329 break;
00330
00331 case MS_110: {Set_Q5Q2();motor_step=MS_110;}
00332 break;
00333
00334 case MS_010: {Set_Q3Q2();motor_step=MS_010;}
00335 break;
00336
00337 case MS_011: {Set_Q3Q6();motor_step=MS_011;}
00338 break;
00339 default : break;
00340 }
00341 }
00342 else
00343 {
00344 Set_none();
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353
00357 void mc_init_timer1(void)
00358 {
00359 TCCR1A = 0;
00360 TCCR1B = 1<<CS11 | 1<<CS10 ;
00361 TCCR1C = 0;
00362 }
00363
00364
00368 #ifdef __GNUC__
00369 ISR(TIMER1_COMPA_vect)
00370 #else
00371 #pragma vector = TIMER1_COMPA_vect
00372 __interrupt void thirty_degres_interrupt(void)
00373 #endif
00374 {
00375 char direction = mci_get_motor_direction();
00376
00377 if (mci_motor_is_running())
00378 {
00379
00380 switch(motor_step)
00381 {
00382 case (MS_100):
00383 if (direction==CCW) {Set_Q1Q4();motor_step=MS_101;}
00384 else {Set_Q5Q2();motor_step=MS_110;}
00385 break;
00386
00387 case (MS_110):
00388 if (direction==CCW) {Set_Q5Q4();motor_step=MS_100;}
00389 else {Set_Q3Q2();motor_step=MS_010;}
00390 break;
00391
00392 case (MS_010):
00393 if (direction==CCW) {Set_Q5Q2();motor_step=MS_110;}
00394 else {Set_Q3Q6();motor_step=MS_011;}
00395 break;
00396
00397 case (MS_011):
00398 if (direction==CCW) {Set_Q3Q2();motor_step=MS_010;}
00399 else {Set_Q1Q6();motor_step=MS_001;}
00400 break;
00401
00402 case (MS_001):
00403 if (direction==CCW) {Set_Q3Q6();motor_step=MS_011;}
00404 else {Set_Q1Q4();motor_step=MS_101;}
00405 break;
00406
00407 case (MS_101):
00408 if (direction==CCW) {Set_Q1Q6();motor_step=MS_001;}
00409 else {Set_Q5Q4();motor_step=MS_100;}
00410 break;
00411
00412 default :
00413 Set_none();
00414 motor_step=MS_010;
00415 break;
00416
00417 }
00418 }
00419 }
00420
00424 #ifdef __GNUC__
00425 ISR(TIMER1_COMPB_vect)
00426 #else
00427 #pragma vector = TIMER1_COMPB_vect
00428 __interrupt void demag_interrupt(void)
00429 #endif
00430 {
00431
00432 switch(motor_step)
00433 {
00434 case (MS_100):
00435 Enable_IT_comparator0();
00436 break;
00437
00438 case (MS_110):
00439 Enable_IT_comparator1();
00440 break;
00441
00442 case (MS_010):
00443 Enable_IT_comparator2();
00444 break;
00445
00446 case (MS_011):
00447 Enable_IT_comparator0();
00448 break;
00449
00450 case (MS_001):
00451 Enable_IT_comparator1();
00452 break;
00453
00454 case (MS_101):
00455 Enable_IT_comparator2();
00456 break;
00457
00458 default :
00459 Enable_IT_comparator2_1_0();
00460 motor_step=MS_010;
00461 break;
00462 }
00463 }
00464
00465 #define ADVANCE 70
00466
00467 #ifdef __GNUC__
00468 ISR(ANACOMP0_vect)
00469 #else
00470 #pragma vector = ANA_COMP0_vect
00471 __interrupt void mc_comparator_0(void)
00472 #endif
00473 {
00474 U16 top;
00475 U16 tmp1;
00476 U16 tmp2;
00477 U8 temp;
00478 TCCR1B = 0 ;
00479 temp = TCNT1L;
00480 top = (TCNT1H<<8) + temp;
00481 TCNT1H = 0;
00482 TCNT1L = 0;
00483 top_average = ((U32)top_average*15 + top ) >> 4;
00484 tmp1 = (top_average >> 1);
00485 tmp2 = tmp1 + (top_average >> 2);
00486
00487
00488
00489
00490
00491
00492 OCR1AH = MSB(tmp1);
00493 OCR1AL = LSB(tmp1);
00494 OCR1BH = MSB(tmp2);
00495 OCR1BL = LSB(tmp2);
00496 TCCR1B = 1<<CS11 | 1<<CS10 ;
00497 Disable_IT_comparator2_1_0();
00498
00499 }
00500
00501 #ifdef __GNUC__
00502 ISR(ANACOMP1_vect)
00503 #else
00504 #pragma vector = ANA_COMP1_vect
00505 __interrupt void mc_comparator_1(void)
00506 #endif
00507 {
00508 U16 top;
00509 U16 tmp1;
00510 U16 tmp2;
00511 U8 temp;
00512 TCCR1B = 0 ;
00513 temp = TCNT1L;
00514 top = (TCNT1H<<8) + temp;
00515 TCNT1H = 0;
00516 TCNT1L = 0;
00517 top_average = ((U32)top_average*15 + top ) >> 4;
00518 tmp1 = (top_average >> 1);
00519 tmp2 = tmp1 + (top_average >> 2);
00520
00521
00522
00523
00524
00525
00526 OCR1AH = MSB(tmp1);
00527 OCR1AL = LSB(tmp1);
00528 OCR1BH = MSB(tmp2);
00529 OCR1BL = LSB(tmp2);
00530 TCCR1B = 1<<CS11 | 1<<CS10 ;
00531 Disable_IT_comparator2_1_0();
00532 mc_estimation_speed();
00533 }
00534
00535 #ifdef __GNUC__
00536 ISR(ANACOMP2_vect)
00537 #else
00538 #pragma vector = ANA_COMP2_vect
00539 __interrupt void mc_comparator_2(void)
00540 #endif
00541 {
00542 U16 top;
00543 U16 tmp1;
00544 U16 tmp2;
00545 U8 temp;
00546
00547 TCCR1B = 0 ;
00548 temp = TCNT1L;
00549 top = (TCNT1H<<8) + temp;
00550 TCNT1H = 0;
00551 TCNT1L = 0;
00552 top_average = ((U32)top_average*15 + top ) >> 4;
00553 tmp1 = (top_average >> 1);
00554 tmp2 = tmp1 + (top_average >> 2);
00555
00556
00557
00558
00559
00560
00561 OCR1AH = MSB(tmp1);
00562 OCR1AL = LSB(tmp1);
00563 OCR1BH = MSB(tmp2);
00564 OCR1BL = LSB(tmp2);
00565 TCCR1B = 1<<CS11 | 1<<CS10 ;
00566 Disable_IT_comparator2_1_0();
00567 }
00568
00569
00570 void start_running_phase(void)
00571 {
00572 U16 top;
00573 TCCR1B = 0 ;
00574 top_average = TIMER1_AT_STARTUP_END;
00575 top = (top_average >> 1);
00576 TCNT1H = HIGH(top);
00577 TCNT1L = LOW(top);
00578 OCR1AH = 0;
00579 OCR1AL = 0;
00580 top = top + (top_average >> 2);
00581 OCR1BH = HIGH(top);
00582 OCR1BL = LOW(top);
00583 TCCR1B = (1<<CS11) | (1<<CS10) ;
00584 TIFR1 = (1<<OCF1B) | (1<<OCF1A) | (1<<TOV1);
00585 TIMSK1= (1<<OCIE1B) | (1<<OCIE1A);
00586 }
00587
00588
00589
00590
00591
00592
00593
00599 void mc_init_timer0(void)
00600 {
00601 TCCR0A = 0;
00602 TCCR0B = (0<<CS02)|(1<<CS01)|(1<<CS00);
00603 TIMSK0 = (1<<TOIE0);
00604 }
00605
00610 #ifdef __GNUC__
00611 ISR(TIMER0_OVF_vect)
00612 #else
00613 #pragma vector = TIMER0_OVF_vect
00614 __interrupt void ovfl_timer0(void)
00615 #endif
00616 {
00617 timer0_ext++;
00618 g_tick = TRUE;
00619 }
00620
00627 void mc_estimation_speed(void)
00628 {
00629 U16 actual_time;
00630 U16 period_motor;
00631
00632
00633 actual_time = (timer0_ext<<8) + TCNT0;
00634
00635 if (actual_time > stored_time)
00636 {
00637 period_motor = actual_time - stored_time;
00638 }
00639 else
00640 {
00641 period_motor = (U16)65535 - stored_time + actual_time;
00642 }
00643
00644 stored_time = actual_time;
00645
00646 mc_set_measured_period(period_motor>>1);
00647
00648 }
00649
00650
00651
00652
00653
00654
00655
00659 #ifdef __GNUC__
00660 ISR(ADC_vect)
00661 #else
00662 #pragma vector = ADC_vect
00663 __interrupt void ADC_end_of_conversion(void)
00664 #endif
00665 {
00666 Adc_select_channel(ADC_INPUT_GND);
00667 if(State == CONV_POT) mc_set_potentiometer_value(Adc_get_8_bits_result());
00668 if(State == CONV_CURRENT) mci_store_measured_current(Adc_get_10_bits_result());
00669 ADC_State = FREE;
00670 }
00671
00672
00675 void mc_ADC_Scheduler(void)
00676 {
00677 switch(State)
00678 {
00679 case CONV_INIT :
00680 ADC_State = FREE;
00681 State = CONV_CURRENT;
00682 break;
00683
00684 case CONV_CURRENT :
00685 if(ADC_State == FREE)
00686 {
00687 ADC_State = BUSY;
00688 State= CONV_POT;
00689 Adc_left_adjust_result();
00690 Adc_start_conv_channel(ADC_INPUT_ISRC);
00691 }
00692 break;
00693
00694 case CONV_POT :
00695 if(ADC_State == FREE)
00696 {
00697 ADC_State = BUSY;
00698 State = CONV_CURRENT;
00699 Adc_right_adjust_result();
00700 Adc_start_conv_channel(ADC_INPUT_AMP1);
00701 }
00702 break;
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00715 void mc_disable_during_inrush(void)
00716 {
00717 inrush_delay = (U16) 500;
00718 inrush_mask_flag = TRUE;
00719 Disable_over_current();
00720 }
00721
00724 void mc_inrush_task(void)
00725 {
00726 if (inrush_mask_flag == TRUE)
00727 {
00728 if (inrush_delay-- == 0)
00729 {
00730 inrush_mask_flag = FALSE;
00731 Enable_over_current();
00732 }
00733 }
00734 }
00735
00736
00737 #ifdef __GNUC__
00738 ISR(PSC_FAULT_vect)
00739 #else
00740 #pragma vector = PSC_FAULT_vect
00741 __interrupt void mc_overcurrent_detect(void)
00742 #endif
00743 {
00744 PIFR = (1<<PEV1);
00745 overcurrent = TRUE;
00746 mci_stop();
00747 }