00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00052 #include <avr/io.h>
00053 #include <avr/signal.h>
00054
00055
00056 #include <pwm.h>
00057
00058 #include <utils.h>
00059
00060
00061 #include <avr/pgmspace.h>
00062
00063 #include <brushless.h>
00064
00065 #include "brushless_3phase_digital_hall_double_config.h"
00066
00067 #if (BRUSHLESS_TYPE != BRUSHLESS_DIGITAL_DOUBLE)
00068 #error mauvais fichier de config "brushless_double_config.h"
00069 #endif
00070
00071
00072
00073
00077 #if (BRUSHLESS_TIMER == 0)
00078 #define INIT_INT() sbi(TIMSK, TOIE0)
00079 #define INT SIG_OVERFLOW0
00080
00081 #elif (BRUSHLESS_TIMER == 1)
00082 #define INIT_INT() sbi(TIMSK, TOIE1)
00083 #define INT SIG_OVERFLOW1
00084
00085 #elif (BRUSHLESS_TIMER == 2)
00086 #define INIT_INT() sbi(TIMSK, TOIE2)
00087 #define INT SIG_OVERFLOW2
00088
00089 #elif (BRUSHLESS_TIMER == 3)
00090 #define INIT_INT() sbi(ETIMSK, TOIE3)
00091 #define INT SIG_OVERFLOW3
00092
00093 #endif
00094
00095
00105
00106
00107
00108 const int8_t g_brushless_angle[]= {0, 1, 5, 0, 3, 2, 4, 0};
00109
00110
00111 const int8_t PROGMEM g_brushless_phase1[]= {0, 1, -1, 0, 0, 1, -1, 0};
00112 const int8_t PROGMEM g_brushless_phase2[]= {0, 0, 1, 1, -1, -1, 0, 0};
00113 const int8_t PROGMEM g_brushless_phase3[]= {0, -1, 0, -1, 1, 0, 1, 0};
00114
00115
00116
00117
00118 void brushless_speed_update_manage(void * dummy);
00119
00120
00121
00122 brushless_position g_brushless_0_position_previous;
00123 brushless_position g_brushless_1_position_previous;
00124
00125
00126 brushless g_brushless_0;
00127 brushless g_brushless_1;
00128
00129
00130 brushless_torque g_brushless_0_torque;
00131 brushless_torque g_brushless_1_torque;
00132
00133
00134 uint16_t g_brushless_0_pwm_divider = 1;
00135 uint16_t g_brushless_1_pwm_divider = 1;
00136
00137
00138
00139 void (*periodic_event_0)(brushless) = 0;
00140 void (*periodic_event_1)(brushless) = 0;
00141
00142
00167 volatile uint8_t pwm_division_timer asm("pwm_div") = 1;
00168 volatile uint8_t interrupt_pwm;
00169 volatile uint8_t pwm_previous_sensors_0 = 0;
00170 volatile uint8_t pwm_previous_sensors_1 = 0;
00171
00172
00173
00174 #ifdef ASMHEADER
00175
00180 void INT (void) __attribute__ ((naked));
00181 SIGNAL(INT)
00182 {
00183 asm volatile(
00184
00185
00186 "PUSH R1 \n\t"
00187 "IN R1,0x3F \n\t"
00188 "PUSH R1 \n\t"
00189 "LDS R1,pwm_div \n\t"
00190 "DEC R1 \n\t"
00191 "BREQ continue \n\t"
00192 "STS pwm_div,R1 \n\t"
00193
00194
00195
00196 "go_out: \n\t"
00197 "POP R1 \n\t"
00198 "OUT 0x3F,R1 \n\t"
00199 "POP R1 \n\t"
00200 "RETI \n\t"
00201
00202
00203 "continue: \n\t"
00204 "POP R1 \n\t"
00205 "OUT 0x3F,R1 \n\t"
00206 "POP R1 \n\t"
00207
00208 ::);
00209
00210 }
00211 SIGNAL(DUMMY)
00212 {
00213
00214 #else // the same code in C
00215 SIGNAL(INT)
00216 {
00218 if (--pwm_division_timer != 0)
00219 return;
00220
00221
00222 #endif //common code
00223
00224
00225 pwm_division_timer = BRUSHLESS_PWM_TO_SAMPLE_DIVISOR;
00226
00227
00228
00229
00232
00233 static int8_t angle_electrical_previous_0 = 0;
00234 static int8_t angle_electrical_previous_1 = 0;
00235 static uint8_t angle_previous_sensors_0 = 0;
00236 static uint8_t angle_previous_sensors_1 = 0;
00237 int8_t angle_electrical, diff;
00238 uint8_t sensors_0 = 0;
00239 uint8_t sensors_1 = 0;
00240
00241
00242 static uint16_t pwm_update_timer_0 = 1;
00243 static uint16_t pwm_update_timer_1 = 1;
00244
00245
00246 {
00247
00248
00249
00254 if(bit_is_set(PIN(BRUSHLESS_0_SENSOR_1_PORT),BRUSHLESS_0_SENSOR_1_BIT))
00255 sensors_0 +=1;
00256 if(bit_is_set(PIN(BRUSHLESS_0_SENSOR_2_PORT),BRUSHLESS_0_SENSOR_2_BIT))
00257 sensors_0 +=2;
00258 if(bit_is_set(PIN(BRUSHLESS_0_SENSOR_3_PORT),BRUSHLESS_0_SENSOR_3_BIT))
00259 sensors_0 +=4;
00260
00261 #ifdef BRUSHLESS_0_SENSORS_INVERT
00262 sensors_0 = (~ sensors_0) & 0x7;
00263 #endif
00264
00265
00266
00269 #ifndef LOADTEST
00270
00271 if(sensors_0 != angle_previous_sensors_0)
00272 #endif
00273 {
00274 angle_previous_sensors_0 = sensors_0;
00275
00276
00277 angle_electrical = g_brushless_angle[sensors_0];
00278
00279 diff = angle_electrical - angle_electrical_previous_0;
00280 angle_electrical_previous_0 = angle_electrical;
00281
00282
00283 if (diff > 3)
00284 diff -=6;
00285 else if (diff < -3)
00286 diff +=6;
00287
00288 #ifndef BRUSHLESS_0_INVERT
00289 diff *= -1;
00290 #endif
00291
00292
00293
00294 g_brushless_0.position -= (brushless_position)diff * BRUSHLESS_POSITION_PRECISION;
00295
00296
00297 }
00298
00299
00300
00301
00302
00303
00308 if(bit_is_set(PIN(BRUSHLESS_1_SENSOR_1_PORT),BRUSHLESS_1_SENSOR_1_BIT))
00309 sensors_1 +=1;
00310 if(bit_is_set(PIN(BRUSHLESS_1_SENSOR_2_PORT),BRUSHLESS_1_SENSOR_2_BIT))
00311 sensors_1 +=2;
00312 if(bit_is_set(PIN(BRUSHLESS_1_SENSOR_3_PORT),BRUSHLESS_1_SENSOR_3_BIT))
00313 sensors_1 +=4;
00314
00315 #ifdef BRUSHLESS_1_SENSORS_INVERT
00316 sensors_1 = (~ sensors_1) & 0x7;
00317 #endif
00318
00319
00320
00323 #ifndef LOADTEST
00324
00325 if(sensors_1 != angle_previous_sensors_1)
00326 #endif
00327 {
00328 angle_previous_sensors_1 = sensors_1;
00329
00330
00331 angle_electrical = g_brushless_angle[sensors_1];
00332
00333 diff = angle_electrical - angle_electrical_previous_1;
00334 angle_electrical_previous_1 = angle_electrical;
00335
00336
00337 if (diff > 3)
00338 diff -=6;
00339 else if (diff < -3)
00340 diff +=6;
00341
00342 #ifndef BRUSHLESS_1_INVERT
00343 diff *= -1;
00344 #endif
00345
00346
00347
00348 g_brushless_1.position -= (brushless_position)diff * BRUSHLESS_POSITION_PRECISION;
00349
00350
00351 }
00352
00353
00354 }
00355
00356
00357 if(interrupt_pwm ==0)
00358 {
00359 interrupt_pwm =1;
00360
00361 sei();
00362
00363
00364
00365
00366 if (--pwm_update_timer_0 == 0)
00367 {
00368 uint8_t flags;
00369 IRQ_LOCK(flags);
00370 pwm_update_timer_0 = g_brushless_0_pwm_divider;
00371 IRQ_UNLOCK(flags);
00372
00373
00374 #ifndef LOADTEST
00375
00376 if(sensors_0 != pwm_previous_sensors_0)
00377 #endif
00378 {
00379 brushless_torque torque;
00380
00381 pwm_previous_sensors_0 = sensors_0;
00382
00383
00384 IRQ_LOCK(flags);
00385 torque = g_brushless_0_torque;
00386 IRQ_UNLOCK(flags);
00387
00388
00389
00390
00391 BRUSHLESS_0_PWM_SET_1(
00392 PWM_MAX/2 +
00393 ((int8_t)pgm_read_byte(g_brushless_phase1 + sensors_0)) *
00394 torque );
00395 BRUSHLESS_0_PWM_SET_2(
00396 PWM_MAX/2 +
00397 ((int8_t)pgm_read_byte(g_brushless_phase2 + sensors_0)) *
00398 torque );
00399 BRUSHLESS_0_PWM_SET_3(
00400 PWM_MAX/2 +
00401 ((int8_t)pgm_read_byte(g_brushless_phase3 + sensors_0)) *
00402 torque );
00403 }
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413 if (--pwm_update_timer_1 == 0)
00414 {
00415 uint8_t flags;
00416 IRQ_LOCK(flags);
00417 pwm_update_timer_1 = g_brushless_1_pwm_divider;
00418 IRQ_UNLOCK(flags);
00419
00420
00421 #ifndef LOADTEST
00422
00423 if(sensors_1 != pwm_previous_sensors_1)
00424 #endif
00425 {
00426 brushless_torque torque;
00427
00428 pwm_previous_sensors_1 = sensors_1;
00429
00430
00431 IRQ_LOCK(flags);
00432 torque = g_brushless_1_torque;
00433 IRQ_UNLOCK(flags);
00434
00435
00436
00437
00438 BRUSHLESS_1_PWM_SET_1(
00439 PWM_MAX/2 +
00440 ((int8_t)pgm_read_byte(g_brushless_phase1 + sensors_1)) *
00441 torque );
00442 BRUSHLESS_1_PWM_SET_2(
00443 PWM_MAX/2 +
00444 ((int8_t)pgm_read_byte(g_brushless_phase2 + sensors_1)) *
00445 torque );
00446 BRUSHLESS_1_PWM_SET_3(
00447 PWM_MAX/2 +
00448 ((int8_t)pgm_read_byte(g_brushless_phase3 + sensors_1)) *
00449 torque );
00450 }
00451 }
00452
00453 interrupt_pwm =0;
00454 }
00455
00458 #ifndef BRUSHLESS_MANAGE_EXTERNAL
00459
00460 static uint16_t speed_division_timer = 1;
00461
00462 if (--speed_division_timer == 0)
00463 {
00464
00465 speed_division_timer = BRUSHLESS_SAMPLE_TO_EVENT_DIVISOR;
00466
00467
00468 brushless_speed_update_manage((void *)0);
00469
00470 }
00471 #endif
00472
00473 }
00474
00475 void brushless_speed_update_manage(void * dummy)
00476 {
00477
00478 uint8_t flags;
00479
00480
00481 IRQ_LOCK(flags);
00482 g_brushless_0.speed = g_brushless_0.position - g_brushless_0_position_previous;
00483 g_brushless_0_position_previous = g_brushless_0.position;
00484 IRQ_UNLOCK(flags);
00485
00486 IRQ_LOCK(flags);
00487 g_brushless_1.speed = g_brushless_1.position - g_brushless_1_position_previous;
00488 g_brushless_1_position_previous = g_brushless_1.position;
00489 IRQ_UNLOCK(flags);
00490
00491
00492 {
00493 void (*f)(brushless);
00494 static volatile uint8_t in_progress = 0;
00495
00496 if(in_progress ==0) {
00497 in_progress = 1;
00498
00499 IRQ_LOCK(flags);
00500 f = periodic_event_0;
00501 IRQ_UNLOCK(flags);
00502
00503 if(f)
00504 f(g_brushless_0);
00505
00506
00507 IRQ_LOCK(flags);
00508 f = periodic_event_1;
00509 IRQ_UNLOCK(flags);
00510
00511 if(f)
00512 f(g_brushless_1);
00513
00514 in_progress = 0;
00515 }
00516 }
00517 }
00518
00519
00520
00521 brushless_speed speed_mem_0 = BRUSHLESS_MAX_SPEED;
00522 brushless_torque torque_mem_0 = 0;
00523 brushless_speed speed_mem_1 = BRUSHLESS_MAX_SPEED;
00524 brushless_torque torque_mem_1 = 0;
00525
00526
00528 void brushless_init(void)
00529 {
00530
00531 pwm_init();
00532
00533
00534 #ifdef BRUSHLESS_0_SENSORS_PULL_UP_RESISTORS
00535 sbi(BRUSHLESS_0_SENSOR_1_PORT,BRUSHLESS_0_SENSOR_1_BIT);
00536 sbi(BRUSHLESS_0_SENSOR_2_PORT,BRUSHLESS_0_SENSOR_2_BIT);
00537 sbi(BRUSHLESS_0_SENSOR_3_PORT,BRUSHLESS_0_SENSOR_3_BIT);
00538 #endif
00539
00540 #ifdef BRUSHLESS_1_SENSORS_PULL_UP_RESISTORS
00541 sbi(BRUSHLESS_1_SENSOR_1_PORT,BRUSHLESS_1_SENSOR_1_BIT);
00542 sbi(BRUSHLESS_1_SENSOR_2_PORT,BRUSHLESS_1_SENSOR_2_BIT);
00543 sbi(BRUSHLESS_1_SENSOR_3_PORT,BRUSHLESS_1_SENSOR_3_BIT);
00544 #endif
00545
00546
00547 INIT_INT();
00548
00549 }
00550
00551
00552
00553
00554
00555 void brushless_0_set_parameters(brushless_speed speed, brushless_torque torque)
00556 {
00557 uint16_t pwm_divider = 0;
00558 uint8_t flags;
00559
00560
00561 speed_mem_0 = speed;
00562 torque_mem_0 = torque;
00563
00564
00565 if(speed ==0)
00566 torque = 0;
00567 else
00568 pwm_divider = BRUSHLESS_MAX_SPEED / speed ;
00569
00570 if (pwm_divider ==0)
00571 pwm_divider =1;
00572
00573 torque /= 2;
00574
00575
00576 #ifdef BRUSHLESS_0_INVERT
00577 torque *= -1;
00578 #endif
00579
00580 IRQ_LOCK(flags);
00581 g_brushless_0_pwm_divider = pwm_divider;
00582 g_brushless_0_torque = torque;
00583 IRQ_UNLOCK(flags);
00584
00585 pwm_previous_sensors_0 = 0;
00586 }
00587
00588 void brushless_1_set_parameters(brushless_speed speed, brushless_torque torque)
00589 {
00590 uint16_t pwm_divider = 0;
00591 uint8_t flags;
00592
00593
00594 speed_mem_1 = speed;
00595 torque_mem_1 = torque;
00596
00597
00598 if(speed ==0)
00599 torque = 0;
00600 else
00601 pwm_divider = BRUSHLESS_MAX_SPEED / speed ;
00602
00603 if (pwm_divider ==0)
00604 pwm_divider =1;
00605
00606 torque /= 2;
00607
00608
00609 #ifdef BRUSHLESS_1_INVERT
00610 torque *= -1;
00611 #endif
00612
00613 IRQ_LOCK(flags);
00614 g_brushless_1_pwm_divider = pwm_divider;
00615 g_brushless_1_torque = torque;
00616 IRQ_UNLOCK(flags);
00617
00618 pwm_previous_sensors_1 = 0;
00619 }
00620
00621
00622
00623 brushless brushless_0_get_mesures(void)
00624 {
00625 brushless ret;
00626 uint8_t flags;
00627
00628 IRQ_LOCK(flags);
00629 ret = g_brushless_0;
00630 IRQ_UNLOCK(flags);
00631
00632 return ret;
00633 }
00634 brushless brushless_1_get_mesures(void)
00635 {
00636 brushless ret;
00637 uint8_t flags;
00638
00639 IRQ_LOCK(flags);
00640 ret = g_brushless_1;
00641 IRQ_UNLOCK(flags);
00642
00643 return ret;
00644 }
00645
00646
00647
00648 void brushless_0_set_position(brushless_position p)
00649 {
00650 uint8_t flags;
00651 IRQ_LOCK(flags);
00652 g_brushless_0_position_previous += p - g_brushless_0.position;
00653 g_brushless_0.position = p;
00654 IRQ_UNLOCK(flags);
00655 }
00656 void brushless_1_set_position(brushless_position p)
00657 {
00658 uint8_t flags;
00659 IRQ_LOCK(flags);
00660 g_brushless_1_position_previous += p - g_brushless_1.position;
00661 g_brushless_1.position = p;
00662 IRQ_UNLOCK(flags);
00663 }
00664
00665
00666 void brushless_0_register_periodic_event(void (*f)(brushless))
00667 {
00668 uint8_t flags;
00669 IRQ_LOCK(flags);
00670 periodic_event_0 = f;
00671 IRQ_UNLOCK(flags);
00672 }
00673 void brushless_1_register_periodic_event(void (*f)(brushless))
00674 {
00675 uint8_t flags;
00676 IRQ_LOCK(flags);
00677 periodic_event_1 = f;
00678 IRQ_UNLOCK(flags);
00679 }
00680
00681
00682
00687 int32_t brushless_get_speed(void * motor_num)
00688 {
00689 brushless retour;
00690
00691 if(motor_num)
00692 retour = brushless_1_get_mesures();
00693 else
00694 retour = brushless_0_get_mesures();
00695
00696 return (int32_t)(retour.speed);
00697 }
00698
00700 int32_t brushless_get_pos(void * motor_num)
00701 {
00702 brushless retour;
00703
00704 if(motor_num)
00705 retour = brushless_1_get_mesures();
00706 else
00707 retour = brushless_0_get_mesures();
00708
00709 return (int32_t)(retour.position);
00710 }
00711
00713 void brushless_set_torque(void * motor_num, int32_t torque)
00714 {
00715 if(motor_num)
00716 brushless_1_set_parameters(speed_mem_1, (brushless_torque) torque);
00717 else
00718 brushless_0_set_parameters(speed_mem_0, (brushless_torque) torque);
00719 }
00720
00722 void brushless_set_speed(void * motor_num, int32_t speed)
00723 {
00724 if(motor_num)
00725 brushless_1_set_parameters((brushless_speed) speed, torque_mem_1);
00726 else
00727 brushless_0_set_parameters((brushless_speed) speed, torque_mem_0);
00728 }