00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 #include "window_lib.h"
00042 #include "filtre1.h"
00043 #include "eep_lib.h"
00044 #include "lib_window\hall_sensor_ISR.h"
00045 #include "timer1_ovf_isr.h"
00046
00047
00048
00049 un_eep_WindowParam eep;
00050
00051
00056
00059 U8 last_direction;
00060
00063 U8 direction;
00064
00066 signed char ctrl_state = STOP_STATE;
00067
00072 U16 position;
00073
00078 U16 ref;
00079
00083 U16 current;
00084
00088 U8 pinch_threshold;
00089
00094 U16 pinch;
00095
00097 U8 gain;
00099
00102 U8 h_max_mm;
00103
00106 U8 h_max;
00107
00110 U16 window_height_mm;
00111
00114 U16 h_detect_min_mm;
00115
00118 U16 h_detect_min;
00119
00122 U16 top_mm;
00123
00127 U16 backlash;
00128
00131 U16 down;
00132
00135 st_b_point_tab block_point;
00136
00139 st_b_point point_temp;
00140
00143 U16 start_pos;
00144
00147 U16 stop_pos;
00148
00150 U8 update=0;
00151
00152
00153
00158 signed char get_window_state (void)
00159 {
00160 return (ctrl_state);
00161 }
00162
00168 signed char force_window_state (signed char temp)
00169 {
00170 ctrl_state=temp;
00171 return (ctrl_state);
00172 }
00173
00178 U16 get_h_detect_min(void)
00179 {
00180 return (h_detect_min);
00181 }
00182
00187 U8 get_h_max(void)
00188 {
00189 return (h_max);
00190 }
00191
00233 U8 init_window_size_position()
00234 {
00235 U8 returned_state;
00236 static U8 init_state = INIT_START_INIT;
00237 static U16 init_pos = 0;
00238 U16 temp16;
00239 U32 temp32;
00240 static signed char go_up_cmde=0, go_down_cmde=0;
00241 if((ADC & 0x200)== 0x200)current = mean_16(0);
00242 else current = mean_16(ADC);
00243
00244 returned_state = window_ctrl(&go_up_cmde, &go_down_cmde, ANTI_PINCH_DISABLED);
00245
00246
00247 blocking_point(returned_state);
00248
00249
00250 switch (init_state)
00251 {
00252 case INIT_START_INIT:
00253 if ((returned_state != STOP_STATE) || (returned_state != STOPING_STATE))
00254 force_window_state(STOPING_STATE);
00255
00256 if (returned_state == STOP_STATE)
00257 {
00258 go_down_cmde = CMDE_NEW_CMDE;
00259 init_state = INIT_DETECT_BOTTOM;
00260 TCNT1 = 0;
00261 }
00262 break;
00263
00264 case INIT_DETECT_BOTTOM:
00265 if( (current > 350) || (TIMEOUT && (current > 200)))
00266 {
00267 SET_MOTOR_OFF();
00268 put_position(0xFFFF);
00269 go_down_cmde = CMDE_NO_CMDE;
00270 go_up_cmde = CMDE_NO_CMDE;
00271 init_state = INIT_START_TOP_DETECT;
00272 erase_block_point();
00273 }
00274 else if (returned_state == STOP_STATE)
00275 go_down_cmde = CMDE_NEW_CMDE;
00276 break;
00277
00278 case INIT_START_TOP_DETECT:
00279 if (current < 5)
00280 {
00281 go_down_cmde = CMDE_NO_CMDE;
00282 go_up_cmde = CMDE_NEW_CMDE;
00283 init_state = INIT_DETECT_TOP;
00284 TCNT1 = 0;
00285 }
00286 break;
00287
00288 case INIT_DETECT_TOP:
00289 if((current > 350) || (TIMEOUT&& (current > 200)))
00290 {
00291 SET_MOTOR_OFF();
00292 temp16 = get_position();
00293 down = 0xFFFF - temp16;
00294 block_point_set_origin (temp16);
00295 put_position(0);
00296 force_window_state(STOPING_STATE);
00297 init_state = INIT_COMPUTE_PARAMS;
00298 }
00299 else if (returned_state == STOP_STATE)
00300 go_up_cmde = CMDE_NEW_CMDE;
00301 break;
00302
00303 case INIT_COMPUTE_PARAMS:
00304 temp32 = (((U32)down<<8));
00305 top_mm = (U16)(temp32/window_height_mm);
00306 h_detect_min = (U16)(((U32)h_detect_min_mm*top_mm)>>8);
00307 h_max = (U8)(((U32)h_max_mm*top_mm)>>8);
00308 init_state = INIT_BACKLASH_START;
00309 break;
00310
00311 case INIT_BACKLASH_START:
00312 if ((returned_state != STOP_STATE) || (returned_state != STOPING_STATE))
00313 force_window_state(STOPING_STATE);
00314
00315 if ((returned_state == STOP_STATE) && (current < 5))
00316 {
00317 go_down_cmde = CMDE_NEW_CMDE;
00318 init_state = INIT_BACKLASH_DOWN;
00319 TCNT1 = 0;
00320 }
00321 break;
00322
00323 case INIT_BACKLASH_DOWN:
00324 if (get_position() >= (h_detect_min>>1))
00325 {
00326 if ((returned_state == STOP_STATE)&&(current < 5))
00327 {
00328 init_state = INIT_BACKLASH_ACQUIRE;
00329 init_pos = get_position();
00330 go_up_cmde = CMDE_NEW_CMDE;
00331 }
00332 else
00333 force_window_state(STOPING_STATE);
00334 }
00335 else if (returned_state != GO_DOWN_STATE)
00336 go_down_cmde = CMDE_NEW_CMDE;
00337 break;
00338
00339 case INIT_BACKLASH_ACQUIRE:
00340 if (get_position() < (init_pos - (top_mm >> 3)))
00341 {
00342 if (returned_state == STOP_STATE)
00343 {
00344 init_state = INIT_END_INIT;
00345 }
00346 else
00347 force_window_state(STOPING_STATE);
00348 }
00349 else if (returned_state == STOP_STATE)
00350 go_up_cmde = CMDE_NEW_CMDE;
00351 else if ((current - ref) > (pinch >> 2))
00352 {
00353
00354
00355 backlash = init_pos - get_position();
00356 }
00357 break;
00358
00359 default:
00360 init_state = INIT_START_INIT;
00361 break;
00362 }
00363 return (init_state);
00364 }
00365
00366
00375 U8 Read_Eep_WindowParameters(void)
00376 {
00377 U8 i;
00378 U8 init_to_perform = INIT_EEP_DONE;
00379 U32 temp;
00380 U8 *eep_b_point_ptr;
00381 eep_b_point_ptr = (void *)&block_point;
00382
00383
00384 for (i = 0; i < sizeof(eep); i++)
00385 {
00386 eep.U8_ptr[i] = EEPROM_read(i);
00387 }
00388
00389 for (i = 0; i < sizeof(block_point); i++)
00390 {
00391 eep_b_point_ptr[i] = EEPROM_read(i + PT_NUM_ADR);
00392 }
00393
00394 position = eep.param.position;
00395 last_direction = eep.param.last_direction;
00396 gain = eep.param.gain;
00397 pinch_threshold = eep.param.pinch_threshold;
00398 window_height_mm = eep.param.window_height_mm;
00399 h_detect_min_mm = eep.param.h_detect_min_mm;
00400 h_max_mm = eep.param.h_max_mm;
00401 down = eep.param.down;
00402 backlash = eep.param.backlash;
00403
00404
00405 if ( (position == 0xFFFF)
00406 ||(last_direction == 0xFF)
00407 ||(down == 0xFFFF)
00408 ||(backlash == 0xFFFF)
00409 ||(block_point.pt_num > PT_NUM_MAX))
00410 {
00411
00412 init_to_perform |= INIT_POSITION_REQUEST;
00413
00414 for (i = 0; i < sizeof(block_point); i++)
00415 eep_b_point_ptr[i] = 0;
00416 }
00417
00418
00419 if ( (window_height_mm == 0xFFFF)
00420 ||(gain == 0xFF)
00421 ||(pinch_threshold == 0xFF)
00422 ||(h_detect_min_mm == 0xffff)
00423 ||(h_max_mm == 0xff))
00424 {
00425
00426
00427 window_height_mm = WINDOW_HEIGHT_MM;
00428 gain = GAIN;
00429 pinch_threshold = PINCH_THRES;
00430 h_detect_min_mm = H_DETECT_MIN_MM;
00431 h_max_mm = H_MAX_MM;
00432 }
00433
00434 temp = (((U32)down<<8));
00435 top_mm = (U16)(temp/window_height_mm);
00436 pinch = ((U16)gain*pinch_threshold) >> 5;
00437
00438
00439 if (INIT_EEP_DONE == init_to_perform)
00440 {
00441 h_detect_min = (U16)(((U32)h_detect_min_mm*top_mm)>>8);
00442 h_max = (U8)(((U32)h_max_mm*top_mm)>>8);
00443 }
00444 return (init_to_perform);
00445 }
00446
00458 void save_window_parameters(void)
00459 {
00460 U8 i;
00461 U8 *U8_ptr;
00462 U32 temp;
00463 U8 *eep_b_point_ptr;
00464 eep_b_point_ptr = (void *)&block_point;
00465
00466 if (save_k > 1 && ctrl_state == STOP_STATE)
00467 {
00468
00469 if (save_k==2)
00470 {
00471 eep.param.position = get_position();
00472 eep.param.last_direction = last_direction;
00473 eep.param.gain = gain;
00474 eep.param.pinch_threshold = pinch_threshold;
00475 eep.param.window_height_mm = window_height_mm;
00476 eep.param.h_detect_min_mm = h_detect_min_mm;
00477 eep.param.h_max_mm = h_max_mm;
00478 eep.param.down = down;
00479 eep.param.backlash = backlash;
00480 U8_ptr = eep.U8_ptr;
00481 }
00482
00483 else if(save_k == 3)
00484 {
00485 U8_ptr = eep.U8_ptr;
00486
00487 gain = eep.param.gain;
00488 pinch_threshold = eep.param.pinch_threshold;
00489 window_height_mm = eep.param.window_height_mm;
00490 h_detect_min_mm = eep.param.h_detect_min_mm;
00491 h_max_mm = eep.param.h_max_mm;
00492
00493 temp = (((U32)down<<8));
00494 top_mm = (U16)(temp/window_height_mm);
00495 pinch = ((U16)gain*pinch_threshold) >> 5;
00496
00497 }
00498
00499
00500 for (i = 0; i < sizeof(eep); i++)
00501 {
00502 EEPROM_write(i, U8_ptr[i]);
00503 }
00504
00505 for (i = 0; i < sizeof(block_point); i++)
00506 {
00507 EEPROM_write(i + PT_NUM_ADR, eep_b_point_ptr[i]);
00508 }
00509 save_k=1;
00510 }
00511 }
00512
00529 U8 window_ctrl(signed char *up_cmde,signed char *down_cmde,U8 no_anti_pinch)
00530 {
00531 static U16 delay=0;
00532 static int k_init;
00533 U16 position = get_position();
00534 switch(ctrl_state)
00535 {
00536
00537 case STOP_STATE:
00538 SET_MOTOR_OFF();
00539 if((position!=k_init) || (delay>0))
00540 {
00541 delay=0;
00542 }
00543 k_init=position;
00544 last_direction=direction;
00545 if (*up_cmde == CMDE_NEW_CMDE)
00546 {
00547 *up_cmde = CMDE_PERFORMED;
00548 if (position > (top_mm >> 7))
00549 {
00550 direction = UPWARD;
00551 RESET_MOTOR_DIRECTION();
00552 SET_MOTOR_ON();
00553 ctrl_state=START_UP_STATE;
00554 delay=0;
00555 TCNT1=0;
00556 }
00557 }
00558 if (*down_cmde == CMDE_NEW_CMDE)
00559 {
00560 *down_cmde= CMDE_PERFORMED;
00561 direction = DOWNWARD;
00562 SET_MOTOR_DIRECTION();
00563
00564 delay=0;
00565 ctrl_state=GO_DOWN_STATE;
00566 TCNT1=0;
00567 }
00568
00569 break;
00570
00571 case START_UP_STATE:
00572 if (no_anti_pinch != ANTI_PINCH_DISABLED)
00573 {
00574 if( (position < (k_init - backlash))
00575 || (position < (k_init - (backlash >> 2))
00576 &&last_direction == UPWARD) )
00577 {
00578 start_pos=position;
00579 update=1;
00580 ctrl_state=GO_UP_STATE;
00581 }
00582 else if (TIMEOUT)
00583 {
00584 if (current>5)
00585 ctrl_state=PINCH_STATE;
00586 else
00587 {
00588
00589
00590 }
00591 }
00592 }
00593 else
00594 {
00595 start_pos=position;
00596 ctrl_state = GO_UP_STATE;
00597 }
00598 if (*up_cmde == CMDE_NEW_CMDE || *down_cmde == CMDE_NEW_CMDE)
00599 ctrl_state=STOPING_STATE;
00600 break;
00601
00602 case GO_UP_STATE:
00603 if ( *up_cmde == CMDE_NEW_CMDE || *down_cmde == CMDE_NEW_CMDE)
00604 ctrl_state=STOPING_STATE;
00605
00606 if ( (current > (pinch + ref + get_block_point(position))) || TIMEOUT )
00607 {
00608 if (position > h_max)
00609 {
00610 ctrl_state=OBSTRUCT_STATE;
00611 }
00612 else if (position < (top_mm >> 7))
00613 {
00614 SET_MOTOR_OFF();
00615 ctrl_state=STOP_STATE;
00616 }
00617 else if (TIMEOUT)
00618 {
00619 SET_MOTOR_OFF();
00620 ctrl_state=STOP_STATE;
00621 if ( (position < h_max) && (position>0))
00622 position--;
00623 put_position(position);
00624 }
00625 }
00626 else if (position < (top_mm >> 7))
00627 {
00628 ctrl_state = STOPING_STATE;
00629 }
00630 else if (current<5 && position<h_detect_min)
00631 {
00632
00633
00634 if (delay>30)
00635 {
00636 ctrl_state = STOPING_STATE;
00637 delay=0;
00638 }
00639 else
00640 delay++;
00641 }
00642
00643 break;
00644
00645 case OBSTRUCT_STATE:
00646 if (*up_cmde == CMDE_NEW_CMDE)
00647 ctrl_state=STOPING_STATE;
00648
00649
00650 if( (position < h_detect_min)
00651 && (position > h_max)
00652 && (direction == UPWARD)
00653 && (no_anti_pinch == ANTI_PINCH_ENABLED))
00654 {
00655 ctrl_state=PINCH_STATE;
00656 }
00657 else if (position < (top_mm >> 7))
00658 {
00659 SET_MOTOR_OFF();
00660 ctrl_state=STOP_STATE;
00661 }
00662 else if (TIMEOUT)
00663 {
00664 SET_MOTOR_OFF();
00665 ctrl_state=STOP_STATE;
00666 if (position<h_max && position>0)
00667 {
00668 position--;
00669 put_position(position);
00670 }
00671 }
00672 else
00673 ctrl_state=GO_UP_STATE;
00674 break;
00675
00676 case PINCH_STATE:
00677 SET_MOTOR_OFF();
00678 if ((delay>5)&(current<5))
00679 {
00680 ctrl_state=REVERSE_STATE;
00681 SET_MOTOR_DIRECTION();
00682 TCNT1=0;
00683 }
00684 else
00685 delay++;
00686 break;
00687
00688 case REVERSE_STATE:
00689 if (position<h_detect_min)
00690 {
00691 direction=DOWNWARD;
00692 SET_MOTOR_ON();
00693 }
00694 else
00695 {
00696 ctrl_state=STOPING_STATE;
00697 }
00698 if(TIMEOUT)
00699 ctrl_state=STOPING_STATE;
00700 break;
00701
00702 case STOPING_STATE:
00703 SET_MOTOR_OFF();
00704 if (TIMEOUT)
00705 {
00706 RESET_MOTOR_DIRECTION();
00707 *up_cmde = CMDE_PERFORMED;
00708 *down_cmde = CMDE_PERFORMED;
00709 ctrl_state=STOP_STATE;
00710 }
00711 break;
00712
00713 case GO_DOWN_STATE:
00714 if(delay>20)
00715 SET_MOTOR_ON();
00716 else
00717 delay++;
00718
00719 if (position>down)
00720 {
00721 if(*down_cmde == CMDE_NO_CMDE || TIMEOUT)
00722 {
00723 SET_MOTOR_OFF();
00724 ctrl_state=STOPING_STATE;
00725 }
00726 else
00727 {
00728
00729 position=down;
00730 put_position(position);
00731 }
00732
00733 }
00734 else if (TIMEOUT)
00735 {
00736 if (current>5)
00737 {
00738 position=down;
00739 put_position(down);
00740 ctrl_state=STOPING_STATE;
00741 }
00742 else
00743 {
00744
00745
00746
00747
00748 ctrl_state=STOPING_STATE;
00749 SET_MOTOR_OFF();
00750 }
00751 }
00752 if (*down_cmde == CMDE_NEW_CMDE || *up_cmde == CMDE_NEW_CMDE)
00753 {
00754 ctrl_state=STOPING_STATE;
00755 }
00756 break;
00757
00758 default:
00759 SET_MOTOR_OFF();
00760 ctrl_state=STOP_STATE;
00761 }
00762 return (ctrl_state);
00763 }
00764
00775 U8 blocking_point(signed char window_state)
00776 {
00777 static U8 point_state=NORMAL_STATE;
00778 U16 position=get_position();
00779
00780
00781 if (window_state == GO_UP_STATE)
00782 {
00783 switch(point_state)
00784 {
00785 case NORMAL_STATE:
00786 if ((current-ref) > (pinch>>1) && position < h_detect_min)
00787 {
00788 point_temp.origin=position;
00789 update=1;
00790 point_state = BLOCKING_STATE;
00791 }
00792 break;
00793
00794 case BLOCKING_STATE:
00795 if ( (current-ref) < (pinch/3))
00796 {
00797 point_temp.end=position;
00798 point_state = SORT_STATE;
00799 }
00800 break;
00801
00802 case SORT_STATE:
00803 update_point();
00804 point_state = NORMAL_STATE;
00805 break;
00806
00807 default:
00808 point_state = NORMAL_STATE;
00809 break;
00810 }
00811 }
00812 else if (window_state == STOPING_STATE)
00813 {
00814 stop_pos=position;
00815 point_state = NORMAL_STATE;
00816 }
00817 else if (window_state == STOP_STATE)
00818 {
00819 if (update==1)
00820 {
00821 stop_pos=position;
00822 clean_point();
00823 update=0;
00824 }
00825 point_state = NORMAL_STATE;
00826 }
00827
00828 return (point_state);
00829 }
00830
00833 U8 update_point (void)
00834 {
00835 U8 i=0,j=0;
00836 while ((block_point.point[i].end>point_temp.origin) && (i < (PT_NUM_MAX -1)))
00837 i++;
00838 if ( i < PT_NUM_MAX)
00839 {
00840 if (block_point.point[i].origin<=point_temp.end)
00841 {
00842 if (block_point.pt_num<PT_NUM_MAX-1)
00843 {
00844 block_point.pt_num++;
00845 for(j=block_point.pt_num;j>i;j--)
00846 {
00847 block_point.point[j].origin = block_point.point[j-1].origin;
00848 block_point.point[j].end = block_point.point[j-1].end;
00849 block_point.point[j].occ = block_point.point[j-1].occ;
00850 }
00851 block_point.point[i].origin = point_temp.origin;
00852 block_point.point[i].end = point_temp.end;
00853 block_point.point[i].occ = 2;
00854 }
00855
00856 }
00857 else
00858 {
00859 block_point.point[i].origin = point_temp.origin;
00860 block_point.point[i].end = point_temp.end;
00861 block_point.point[i].occ += 2;
00862 if (block_point.point[i].occ>=4)
00863 block_point.point[i].occ=5;
00864 }
00865 }
00866 else
00867 {
00868
00869
00870 }
00871 return (0);
00872 }
00873
00877 U8 get_table_indice (U16 position)
00878 {
00879 U8 i=0;
00880 while (block_point.point[i].origin<position && i<PT_NUM_MAX &&block_point.point[i].origin!=0)
00881 i++;
00882 return (i);
00883 }
00884
00887 void clean_point(void)
00888 {
00889 U8 i=0,j,end;
00890 end = get_table_indice (start_pos);
00891 i = get_table_indice (stop_pos);
00892 while (i<block_point.pt_num && i<end)
00893 {
00894 block_point.point[i].occ--;
00895 if (block_point.point[i].occ==0)
00896 {
00897 for (j=i;j<block_point.pt_num;j++)
00898 {
00899 block_point.point[j].origin = block_point.point[j+1].origin;
00900 block_point.point[j].end = block_point.point[j+1].end;
00901 block_point.point[j].occ = block_point.point[j+1].occ;
00902 }
00903 block_point.point[j+1].origin=0;
00904 block_point.point[j+1].end=0;
00905 block_point.point[j+1].occ=0;
00906 if (block_point.pt_num>0)
00907 block_point.pt_num--;
00908 }
00909 i++;
00910 }
00911 }
00912
00923 U8 get_block_point(U16 position)
00924 {
00925 U8 i,blocking_value=0;
00926 for(i=0;i<PT_NUM_MAX;i++)
00927 {
00928 if (position<=block_point.point[i].origin)
00929 {
00930 if (position>=block_point.point[i].end)
00931 {
00932 blocking_value = (pinch>>1);
00933 break;
00934 }
00935 }
00936 }
00937 return (blocking_value);
00938 }
00939
00944 void erase_block_point(void)
00945 {
00946 U8 i, *b_point_ptr;
00947 b_point_ptr = (void *)&block_point;
00948 for(i=0;i<sizeof(block_point);i++)
00949 {
00950 b_point_ptr[i] = 0;
00951 }
00952 }
00953
00962 void block_point_set_origin(U16 origin)
00963 {
00964 U8 i;
00965 for(i=0;i<PT_NUM_MAX;i++)
00966 {
00967 if (block_point.point[i].occ != 0)
00968 {
00969 block_point.point[i].origin -= origin;
00970 block_point.point[i].end -= origin;
00971 }
00972 }
00973 }
00974
00985 void init_window_peripherals(void)
00986 {
00987 #if defined (__ATmega88__) || defined (__ATmega168__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
00988
00989
00990 PCICR |= 1 << PCIE1;
00991 PCMSK1 |= 1 << PCINT10;
00992
00993
00994 ADMUX |= 1 << REFS0;
00995
00996
00997 TCCR1B = TCCR1B | (1 << CS12);
00998 TIMSK1 |= 1<<TOIE1;
00999
01000
01001 TCCR0B = TCCR0B | (1 << CS01);
01002 TIMSK0 |= 1<<TOIE0;
01003
01004
01005 #elif defined(__AT90PWM2__) || defined(__AT90PWM3__) || defined(__AVR_AT90PWM2__) || defined(__AVR_AT90PWM3__)
01006
01007 EICRA = 0x01;
01008 EIMSK = 0x01;
01009
01010
01011 init_adc();
01012 init_amp0();
01013
01014
01015 TCCR0B = TCCR0B | (1 << CS01);
01016 TIMSK0 |= 1<<TOIE0;
01017
01018
01019 TCCR1B = TCCR1B | (1 << CS12);
01020 TIMSK1 |= 1<<TOIE1;
01021
01022 #else
01023 #error "Update init_window_peripherals() routine for your MCU"
01024 #endif
01025 }
01026
01027