window_lib.c File Reference

#include "window_lib.h"
#include "filtre1.h"
#include "eep_lib.h"
#include "lib_window\hall_sensor_ISR.h"
#include "timer1_ovf_isr.h"

Go to the source code of this file.

Functions

signed char get_window_state (void)
 get_window_state reports state Returns window control machine state
signed char force_window_state (signed char temp)
 force_window_state Forces state
U16 get_h_detect_min (void)
 get_h_detect_min reports the distance from top to activate anti-pinch
U8 get_h_max (void)
 get_h_max reports the distance from top to disable anti-pinch
U8 init_window_size_position ()
 Allows to automatically operate window down, then up to detect Bottom and top ends, and backlash : It's an adaptation routine.
U8 Read_Eep_WindowParameters (void)
 Read and check parameters stored into eeprom.
void save_window_parameters (void)
 Store window-lift parameters to eeprom memory when required.
U8 window_ctrl (signed char *up_cmde, signed char *down_cmde, U8 no_anti_pinch)
 Manage window lift.
U8 blocking_point (signed char window_state)
 blocking point detection state machine
U8 update_point (void)
 Creates/Refresh data in the blocking points table.
U8 get_table_indice (U16 position)
 get the indice of the next blocking point referenced in the table in function of a given position
void clean_point (void)
 erase not existing blocking points (which stopped to occur)
U8 get_block_point (U16 position)
 Returns blocking point value for the given position.
void erase_block_point (void)
 clear all block points structure fields.
void block_point_set_origin (U16 origin)
 Changes All blocking points reference/origin position. Useful after adaptation time (first init) : after reference origin is known.
void init_window_peripherals (void)
 Initialize window lift requiered peripherals like ADC, TIMERs, Pin Change, Interrupts.

Variables

un_eep_WindowParam eep
 eeprom parameters
U8 last_direction
 Window operating direction during last operation (according to command).
U8 direction
 Window operating direction (according to command).
signed char ctrl_state = STOP_STATE
 Window-lift Control state (see Window lift control state machine definitions).
U16 position
 Window position buffer.
U16 ref
 Computed current reference ( I(A) <-> ADC * ADC gain ).
U16 current
 Current Image: Has to be filtered (meaned) for the algorithm to work well.
U8 pinch_threshold
 Pinch Threshold: Must be parametred by user (in Newton).
U16 pinch
 Normalized pinch threshold according to gain (motor & ADC parameters).
U8 gain
 Global gain to determine pinch value.
U8 h_max_mm
 Distance from top of window to inactivate anti-pinch in mm Filled by used in eeprom or by default value (see Default Window area and measurement definitions).
U8 h_max
 Distance from top of window to inactivate anti-pinch in hall sensor edges computed using h_max_mm and down variables.
U16 window_height_mm
 Opening apartus height in millimeters (filled by user) (see Default Window area and measurement definitions).
U16 h_detect_min_mm
 Distance from top of window to activate anti-pinch in millimeters (mm) Filled by used in eeprom or by default value (see Default Window area and measurement definitions).
U16 h_detect_min
 Distance from top to activate anti-pinch (in hall sensor edges number) computed using h_detect_min_mm and down variables.
U16 top_mm
 number of hall sensor edges per millimeters (left shifted by 8 to allow a good precision, see Default Window area and measurement definitions).
U16 backlash
 Backlash value (measured, in hall sensor edges number when revesing direction at intialization time by adaptation routine : init_window_size_position()).
U16 down
 Down is the number of hall sensor edges for a top to bottom operation Filled by adaptation routine or by user (see Default Window area and measurement definitions).
st_b_point_tab block_point
 blocking points ram storing table.
st_b_point point_temp
 blocking point temporary buffer.
U16 start_pos
 Remembers the start position of the window lift to refresh blocking points table, starting from this position, when window lift operation ends.
U16 stop_pos
 Remembers the stop position of the window lift to refresh blocking points table, until this position, when window lift operation ends.
U8 update = 0
 Flag used to refresh blocking points when window lift operation ends.


Function Documentation

signed char get_window_state ( void   ) 

get_window_state reports state Returns window control machine state

Returns:
window state

Definition at line 158 of file window_lib.c.

References ctrl_state.

00159 {
00160   return (ctrl_state);
00161 }

signed char force_window_state ( signed char  temp  ) 

force_window_state Forces state

Force window control machine state

Returns:
window state

Definition at line 168 of file window_lib.c.

References ctrl_state.

Referenced by init_window_size_position().

00169 {
00170   ctrl_state=temp;
00171   return (ctrl_state);
00172 }

U16 get_h_detect_min ( void   ) 

get_h_detect_min reports the distance from top to activate anti-pinch

Returns:
bottom height limit to activate anti-pinch (in hall sensor 'tops')

Definition at line 178 of file window_lib.c.

References h_detect_min.

00179 {
00180   return (h_detect_min);
00181 }

U8 get_h_max ( void   ) 

get_h_max reports the distance from top to disable anti-pinch

Returns:
bottom height limit to activate anti-pinch (in hall sensor 'tops')

Definition at line 187 of file window_lib.c.

References h_max.

00188 {
00189   return (h_max);
00190 }

U8 init_window_size_position ( void   ) 

Allows to automatically operate window down, then up to detect Bottom and top ends, and backlash : It's an adaptation routine.

An init loop runs until init ends (until init_state isn't INIT_END_INIT) After each complete analog conversion, (ADIF read to 1 is reseted) state machine is executed:

Definition at line 233 of file window_lib.c.

References ANTI_PINCH_DISABLED, backlash, block_point_set_origin(), blocking_point(), CMDE_NEW_CMDE, CMDE_NO_CMDE, current, down, erase_block_point(), force_window_state(), get_position(), GO_DOWN_STATE, h_detect_min, h_detect_min_mm, h_max, h_max_mm, INIT_BACKLASH_ACQUIRE, INIT_BACKLASH_DOWN, INIT_BACKLASH_START, INIT_COMPUTE_PARAMS, INIT_DETECT_BOTTOM, INIT_DETECT_TOP, INIT_END_INIT, INIT_START_INIT, INIT_START_TOP_DETECT, pinch, put_position(), ref, STOP_STATE, STOPING_STATE, top_mm, window_ctrl(), and window_height_mm.

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);  // force motor stop
00255     
00256     if (returned_state == STOP_STATE)  
00257     { // ready to start init operation
00258       go_down_cmde = CMDE_NEW_CMDE;       // command : initialize window at Bottom
00259       init_state = INIT_DETECT_BOTTOM;
00260       TCNT1 = 0;                          // Reset timeout detection
00261     }
00262     break;
00263   //---------------------------------
00264   case INIT_DETECT_BOTTOM:                // wait bottom detection
00265     if( (current > 350) || (TIMEOUT && (current > 200)))
00266     {                                     // bottom detected
00267       SET_MOTOR_OFF();                    //motor mosfet 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();          // erase blocking point table before rebuild
00273     }
00274     else if (returned_state == STOP_STATE)
00275       go_down_cmde = CMDE_NEW_CMDE;
00276     break;
00277   //---------------------------------
00278   case INIT_START_TOP_DETECT:             // Wait current to be low
00279     if (current < 5)                      // current has decrease
00280     {
00281       go_down_cmde = CMDE_NO_CMDE;
00282       go_up_cmde = CMDE_NEW_CMDE;         // initiate top detection
00283       init_state = INIT_DETECT_TOP;
00284       TCNT1 = 0;                          // Reset timeout detection
00285     }
00286     break;
00287   //---------------------------------
00288   case INIT_DETECT_TOP:                   // wait top detection
00289     if((current > 350) || (TIMEOUT&& (current > 200)))
00290     {                                     // top detected
00291       SET_MOTOR_OFF();                    // motor mosfet OFF
00292       temp16 = get_position();
00293       down = 0xFFFF - temp16;
00294       block_point_set_origin (temp16);    // set top origin for blocking points
00295       put_position(0);
00296       force_window_state(STOPING_STATE);  // force motor stop
00297       init_state = INIT_COMPUTE_PARAMS;   // compute over parameters
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));              // top_mm: number of hall sensor
00305     top_mm = (U16)(temp32/window_height_mm);// edges per millimeters * 256
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;       // break loop, initialisation ends
00309     break;
00310   //---------------------------------
00311   case INIT_BACKLASH_START:
00312     if ((returned_state != STOP_STATE) || (returned_state != STOPING_STATE))
00313       force_window_state(STOPING_STATE);    // force motor stop
00314     
00315     if ((returned_state == STOP_STATE) && (current < 5))
00316     { // ready to start down operation
00317       go_down_cmde = CMDE_NEW_CMDE;         // command : downward operation command
00318       init_state = INIT_BACKLASH_DOWN;
00319       TCNT1 = 0;                            // Reset timeout detection
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;         // command : upward operation command
00331       }
00332       else
00333         force_window_state(STOPING_STATE);  // force motor stop
00334     }
00335     else if (returned_state != GO_DOWN_STATE)
00336       go_down_cmde = CMDE_NEW_CMDE;         // command : downward operation command
00337     break;    
00338   //---------------------------------
00339   case INIT_BACKLASH_ACQUIRE:
00340     if (get_position() < (init_pos - (top_mm >> 3))) // maximum backlash: 32mm
00341     { // Stop acquisition
00342       if (returned_state == STOP_STATE)              
00343       {
00344         init_state = INIT_END_INIT;
00345       }
00346       else
00347         force_window_state(STOPING_STATE);  // force motor stop
00348     }
00349     else if (returned_state == STOP_STATE)
00350       go_up_cmde = CMDE_NEW_CMDE;   // command : downward operation command
00351     else if ((current - ref) > (pinch >> 2))     // Check startup
00352     { // Bashlash defined at startup as:
00353       // - Operating direction has changed
00354       // - Current reference is up to date: Current - reference < pinch / 4
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 }

U8 Read_Eep_WindowParameters ( void   ) 

Read and check parameters stored into eeprom.

Reads EEprom to load parameters, When they are not initialized:

Returns:
Initialisation status (see Initialisation status definitions)

Definition at line 375 of file window_lib.c.

References backlash, st_eep_WindowParam::backlash, block_point, down, st_eep_WindowParam::down, eep, gain, st_eep_WindowParam::gain, h_detect_min_mm, st_eep_WindowParam::h_detect_min_mm, h_max_mm, st_eep_WindowParam::h_max_mm, INIT_EEP_DONE, INIT_POSITION_REQUEST, last_direction, st_eep_WindowParam::last_direction, un_eep_WindowParam::param, pinch_threshold, st_eep_WindowParam::pinch_threshold, position, st_eep_WindowParam::position, st_b_point_tab::pt_num, PT_NUM_ADR, PT_NUM_MAX, un_eep_WindowParam::U8_ptr, window_height_mm, and st_eep_WindowParam::window_height_mm.

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; // pointer to block_point structure
00382   
00383   // restore EEPROM into application buffer
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   //------------ Check / Restore positionnig and area parameters ---------------
00405   if (  (position           == 0xFFFF)      // Check position
00406       ||(last_direction     == 0xFF)        // Check last_direction
00407       ||(down               == 0xFFFF)      // Check down 
00408       ||(backlash           == 0xFFFF)      // Check backlash
00409       ||(block_point.pt_num > PT_NUM_MAX))  // Check pt_num
00410   {
00411     // Request for adaptation / learning function to initialise it
00412     init_to_perform |= INIT_POSITION_REQUEST;
00413     // Clear blocking points area
00414     for (i = 0; i < sizeof(block_point); i++)
00415       eep_b_point_ptr[i] = 0;       
00416   }
00417   
00418   //------------ Check / Restore Default user parameters -----------------------
00419   if (  (window_height_mm   == 0xFFFF)      // Has to be parametred by user
00420       ||(gain               == 0xFF)
00421       ||(pinch_threshold    == 0xFF)
00422       ||(h_detect_min_mm    == 0xffff)
00423       ||(h_max_mm           == 0xff))
00424   { 
00425     // Has to be parametred by user 
00426     // (default val in window_lib.h)
00427     window_height_mm = WINDOW_HEIGHT_MM;    // Restore window_height_mm
00428     gain = GAIN;                            // Restore gain
00429     pinch_threshold = PINCH_THRES;          // Restore pinch_threshold
00430     h_detect_min_mm = H_DETECT_MIN_MM;      // Restore h_detect_min
00431     h_max_mm = H_MAX_MM;                    // Restore h_max_mm
00432   }
00433   
00434   temp = (((U32)down<<8));                  // top_mm: number of hall sensor
00435   top_mm = (U16)(temp/window_height_mm);    // edges per millimeters * 256
00436   pinch = ((U16)gain*pinch_threshold) >> 5; //compute pinch value
00437  
00438   // ----------- Window lift considered correctly initiated/positionned --------
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 }

void save_window_parameters ( void   ) 

Store window-lift parameters to eeprom memory when required.

Store parameters table and blocking to eeprom according to sake_k flag:

Warning:
sake_k has to be 2 or 3 for parameters to be written. Flag is then cleared (set to 1)

Definition at line 458 of file window_lib.c.

References st_eep_WindowParam::backlash, backlash, block_point, ctrl_state, st_eep_WindowParam::down, down, eep, st_eep_WindowParam::gain, gain, get_position(), st_eep_WindowParam::h_detect_min_mm, h_detect_min_mm, st_eep_WindowParam::h_max_mm, h_max_mm, st_eep_WindowParam::last_direction, last_direction, un_eep_WindowParam::param, pinch, st_eep_WindowParam::pinch_threshold, st_eep_WindowParam::position, PT_NUM_ADR, save_k, STOP_STATE, un_eep_WindowParam::U8_ptr, st_eep_WindowParam::window_height_mm, and window_height_mm.

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; // pointer to block_point structure
00465   
00466   if (save_k > 1 && ctrl_state == STOP_STATE)// stop and then no operation (timer1_ovf)
00467   {
00468     // Check if window-lift has been operated and parameters need to be stored
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     // New parameters have been uploaded, It requires storage to EEPROM
00483     else if(save_k == 3)  
00484     {
00485       U8_ptr = eep.U8_ptr;  // Initiliaze Pointer to parse 
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));                    // top_mm: number of hall sensor
00494       top_mm = (U16)(temp/window_height_mm);      // edges per millimeters * 256
00495       pinch = ((U16)gain*pinch_threshold) >> 5;   //compute pinch value
00496 
00497     }
00498     
00499     // EEPROM window lift parameters storage
00500     for (i = 0; i < sizeof(eep); i++)
00501     {
00502       EEPROM_write(i, U8_ptr[i]);
00503     }  
00504     // EEPROM window lift blocking points storage    
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; // Update flag : parameters has been saved
00510   }
00511 }

U8 window_ctrl ( signed char *  up_cmde,
signed char *  down_cmde,
U8  no_anti_pinch 
)

Manage window lift.

Manage window lift operations according to upward, downward and no_anti_pinch commands. Monitors measured current and position to reverse window when necessary.

Warning:
Ensure all initialization has been performed before enabling anti-pinch. ADC must be complete and result must be filtered before using it!
Parameters:
*up_cmde Initiate or Report command (see window_ctrl() parameter)
*down_cmde Range : CMDE_NO_CMDE, CMDE_NEW_CMDE, CMDE_PERFORMED
no_anti_pinch Enable/disable anti-pinch window_ctrl() parameter
Precondition:
Precondition.mean_16 should have been called before
Returns:
(U8)window control machine state (see Window lift control state machine definitions)

Definition at line 529 of file window_lib.c.

References ANTI_PINCH_DISABLED, ANTI_PINCH_ENABLED, backlash, CMDE_NEW_CMDE, CMDE_NO_CMDE, CMDE_PERFORMED, ctrl_state, current, direction, down, DOWNWARD, get_block_point(), get_position(), GO_DOWN_STATE, GO_UP_STATE, h_detect_min, h_max, last_direction, OBSTRUCT_STATE, pinch, PINCH_STATE, position, put_position(), ref, REVERSE_STATE, start_pos, START_UP_STATE, STOP_STATE, STOPING_STATE, update, and UPWARD.

Referenced by init_window_size_position().

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:          // stop state
00538       SET_MOTOR_OFF();                //motor mosfet OFF
00539       if((position!=k_init) || (delay>0))
00540       {
00541         delay=0;
00542       }
00543       k_init=position;                //put init position
00544       last_direction=direction;       // save last operation direction to take mechanical backlash into account
00545       if (*up_cmde == CMDE_NEW_CMDE)
00546       {
00547         *up_cmde = CMDE_PERFORMED;
00548         if (position > (top_mm >> 7)) //software top limit (2 mm)
00549         {
00550           direction = UPWARD;         // upward
00551           RESET_MOTOR_DIRECTION();    // turn off direction relay
00552           SET_MOTOR_ON();             // motor mosfet ON
00553           ctrl_state=START_UP_STATE;
00554           delay=0;
00555           TCNT1=0; // Start initialization for speed measurment & timeout
00556         }
00557       }
00558       if (*down_cmde == CMDE_NEW_CMDE)
00559       {
00560           *down_cmde= CMDE_PERFORMED;
00561           direction = DOWNWARD;       // downward
00562           SET_MOTOR_DIRECTION();      // turn on direction relay
00563           //SET_MOTOR_ON();           // motor on in GO_DOWN_STATE
00564           delay=0;
00565           ctrl_state=GO_DOWN_STATE;
00566           TCNT1=0; // Start initialization for speed measurment & timeout
00567       }
00568 
00569       break;
00570     //--------------------------------------------------------------------------
00571     case START_UP_STATE:       // acceleration
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) ) // start_up complete (backlash)
00577         {
00578           start_pos=position; // start position used to refresh blocking points
00579           update=1;           // flag used for blocking points
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             /*INSERT CODE HERE
00589               TO REPORT A DEFAULT*/
00590           }
00591         }
00592       }
00593       else
00594       {
00595         start_pos=position; // start position used to determine backlash value
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:       // normal go upward operation
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)) // software top limit (2 mm)
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)) // if mechanical top limit
00622             position--;                    // position correction
00623             put_position(position);
00624         }
00625       }
00626       else if (position < (top_mm >> 7))   //software top limit (2 mm)
00627       {
00628         ctrl_state = STOPING_STATE;
00629       }
00630       else if (current<5 && position<h_detect_min)
00631      {  // no current ( = defaut)
00632             /*INSERT CODE HERE
00633             TO REPORT A DEFAULT*/
00634         if (delay>30)       //go upward step by step in pinch area
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             // Check Anti-pinch rules
00650             if(   (position < h_detect_min)   // Check Pinch Area
00651                && (position > h_max) 
00652                && (direction == UPWARD)       // Check Direction
00653                && (no_anti_pinch == ANTI_PINCH_ENABLED))
00654             {
00655               ctrl_state=PINCH_STATE;         // Pinch conditions are met
00656             }
00657             else if (position < (top_mm >> 7))// Check software top limit (1mm)
00658             {
00659               SET_MOTOR_OFF();
00660               ctrl_state=STOP_STATE;
00661             }
00662             else if (TIMEOUT)                     // time out: null speed
00663             {
00664                 SET_MOTOR_OFF();
00665                 ctrl_state=STOP_STATE;
00666                 if (position<h_max && position>0) //if mechanical top limit
00667                 {
00668                   position--;                     // position correction
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();            //pinch : stop motor
00678             if ((delay>5)&(current<5))  //delay & low current
00679             {
00680               ctrl_state=REVERSE_STATE;
00681               SET_MOTOR_DIRECTION();    // turn off direction relay
00682               TCNT1=0;                  // reset TIMEOUT
00683             }
00684             else
00685               delay++;
00686             break;
00687     //--------------------------------------------------------------------------
00688     case REVERSE_STATE:                 // pinch : go downward
00689             if (position<h_detect_min)
00690             {
00691               direction=DOWNWARD;
00692               SET_MOTOR_ON();           // turn on FET
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:                   // stop request
00703             SET_MOTOR_OFF();              // turn off FET
00704             if (TIMEOUT)
00705             {
00706               RESET_MOTOR_DIRECTION();    // turn off direction relay
00707               *up_cmde = CMDE_PERFORMED;  // empty push button buffer
00708               *down_cmde = CMDE_PERFORMED;// to inhibit all commands
00709               ctrl_state=STOP_STATE;
00710             }
00711             break;
00712     //--------------------------------------------------------------------------
00713     case GO_DOWN_STATE:                   // go downward
00714               if(delay>20)                // wait relay in position
00715                 SET_MOTOR_ON();           // motor mosfet ON
00716               else
00717                 delay++;
00718 
00719               if (position>down)          // bottom stop limit
00720               {
00721                 if(*down_cmde == CMDE_NO_CMDE || TIMEOUT)
00722                 {
00723                   SET_MOTOR_OFF();
00724                   ctrl_state=STOPING_STATE;
00725                 }
00726                 else  // go down till push button relax or timeout
00727                 {     // allow manually go_down
00728 
00729                   position=down;
00730                   put_position(position);
00731                 }
00732 
00733               }
00734               else if (TIMEOUT)
00735               {
00736                 if (current>5)      // ensure motor is connected : current > 0
00737                 {
00738                   position=down;    // bottom: adjust position
00739                   put_position(down);
00740                   ctrl_state=STOPING_STATE;
00741                 }
00742                 else
00743                 {
00744                   /* INSERT CODE HERE
00745                    * TO REPORT A DEFAULT
00746                    * HALL SENSOR TIMEOUT DETECTION
00747                    * AND NO CURRENT*/
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; //stop command
00755               }
00756               break;
00757     //--------------------------------------------------------------------------
00758     default:
00759             SET_MOTOR_OFF();        //motor mosfet OFF
00760             ctrl_state=STOP_STATE;
00761   }
00762   return (ctrl_state);
00763 }

U8 blocking_point ( signed char  window_state  ) 

blocking point detection state machine

Manages blocking point detection state machine. It's used to calibrate and update blocking points.

Parameters:
window_state is required for detection to be synchronized on the window lift state machine.
Precondition:
Precondition.window_ctrl should have been called before.

Definition at line 775 of file window_lib.c.

References BLOCKING_STATE, clean_point(), current, st_b_point::end, get_position(), GO_UP_STATE, h_detect_min, NORMAL_STATE, st_b_point::origin, pinch, point_temp, position, ref, SORT_STATE, stop_pos, STOP_STATE, STOPING_STATE, update, and update_point().

Referenced by init_window_size_position().

00776 {
00777   static U8 point_state=NORMAL_STATE; //blocking point state;
00778   U16 position=get_position();        
00779 
00780   //blocking point management
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; // save hard/blocking 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; // save hard/blocking 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 }

U8 update_point ( void   ) 

Creates/Refresh data in the blocking points table.

Definition at line 833 of file window_lib.c.

References block_point, st_b_point::end, st_b_point::occ, st_b_point::origin, st_b_point_tab::point, point_temp, st_b_point_tab::pt_num, and PT_NUM_MAX.

Referenced by blocking_point().

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     {// new blocking point, shift following results
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     {//update blocking point reference
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     // PT_NUM_MAX is reached: No more block points will be referenced
00869     // Nothing to do
00870   }
00871   return (0);
00872 }

U8 get_table_indice ( U16  position  ) 

get the indice of the next blocking point referenced in the table in function of a given position

Definition at line 877 of file window_lib.c.

References block_point, st_b_point::origin, st_b_point_tab::point, and PT_NUM_MAX.

Referenced by clean_point().

00878 {
00879   U8 i=0;
00880   while (block_point.point[i].origin<position && i<PT_NUM_MAX &&block_point.point[i].origin!=0)  //get table indice of starting point
00881     i++;
00882   return (i);
00883 }

void clean_point ( void   ) 

erase not existing blocking points (which stopped to occur)

Definition at line 887 of file window_lib.c.

References block_point, st_b_point::end, get_table_indice(), st_b_point::occ, st_b_point::origin, st_b_point_tab::point, st_b_point_tab::pt_num, start_pos, and stop_pos.

Referenced by blocking_point().

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)    // scan table elements (in the last move area)
00893   {
00894     block_point.point[i].occ--;
00895     if (block_point.point[i].occ==0) // erase data
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 }

U8 get_block_point ( U16  position  ) 

Returns blocking point value for the given position.

When a blocking point has been registered for the position provided in parameter, returns the threshold to be added to pinch value. Otherwise, when no blocking point is registered for this position, returns 0

Parameters:
position Any position where a blocking point could exist
Returns:
Blocking point threshold for this position or 0

Definition at line 923 of file window_lib.c.

References block_point, st_b_point::end, st_b_point::origin, pinch, st_b_point_tab::point, and PT_NUM_MAX.

Referenced by window_ctrl().

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 }

void erase_block_point ( void   ) 

clear all block points structure fields.

Writes 0 to all block point fields (in RAM)

Definition at line 944 of file window_lib.c.

References block_point.

Referenced by init_window_size_position().

00945 {
00946   U8 i, *b_point_ptr;
00947   b_point_ptr = (void *)&block_point; // pointer to block_point structure
00948   for(i=0;i<sizeof(block_point);i++)
00949   {
00950     b_point_ptr[i] = 0;
00951   }
00952 }

void block_point_set_origin ( U16  origin  ) 

Changes All blocking points reference/origin position. Useful after adaptation time (first init) : after reference origin is known.

Parse blocking point table to change all existing points origin and end positions

Parameters:
origin Actual origin offset, which shall be removed

Definition at line 962 of file window_lib.c.

References block_point, st_b_point::end, st_b_point::occ, st_b_point::origin, st_b_point_tab::point, and PT_NUM_MAX.

Referenced by init_window_size_position().

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 }

void init_window_peripherals ( void   ) 

Initialize window lift requiered peripherals like ADC, TIMERs, Pin Change, Interrupts.

Depending on MCU used:

Warning:
used MCU shall be defined in config.h

Definition at line 985 of file window_lib.c.

00986 {
00987 #if defined (__ATmega88__) || defined (__ATmega168__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
00988   
00989    /*init PCINT 10  Pin change interrupt initialisation */
00990   PCICR |= 1 << PCIE1;     // PCINT14...8 interrupt pins enabled 
00991   PCMSK1 |= 1 << PCINT10;  // PCINT10 interrupt pin enabled 
00992   
00993   /* init ADC */
00994   ADMUX |= 1 << REFS0;     // conversion result right ajusted in ADC, AVCC with external capacitor at AREF pin, ADC0 selected
00995   
00996   /* init timer/counter 1 */
00997   TCCR1B = TCCR1B | (1 << CS12);  // CS12 = 1, period = 2.097152 sec
00998   TIMSK1 |= 1<<TOIE1;             // enable timer/counter1 overflow interrupt 
00999   
01000   /* init timer/counter 0 */
01001   TCCR0B = TCCR0B | (1 << CS01)/*|(1 << CS00)*/;  // clock = fclock/8
01002   TIMSK0 |= 1<<TOIE0;             // enable timer 0 overflow interrupt   
01003 
01004 
01005 #elif defined(__AT90PWM2__) || defined(__AT90PWM3__) || defined(__AVR_AT90PWM2__) || defined(__AVR_AT90PWM3__)
01006   // Init External interrupt for Hall effect sensors
01007   EICRA = 0x01; // Rising Edge
01008   EIMSK = 0x01; // INT0
01009 
01010   // Init ADC and Amplifier for current measurement
01011   init_adc();
01012   init_amp0();
01013 
01014   // Init Timer/Counter 0 to execute the current measurement
01015   TCCR0B = TCCR0B | (1 << CS01)/*|(1 << CS00)*/;  // clock = fclock/8
01016   TIMSK0 |= 1<<TOIE0;             // enable overflow interrupt on timer 0
01017 
01018   // Init Timer/Counter 1 to save parameters every 2 sec
01019   TCCR1B = TCCR1B | (1 << CS12);  // CS12 = 1, period = 2.097152 sec
01020   TIMSK1 |= 1<<TOIE1;             // interrupt enable on timer/counter1 overflow
01021 
01022 #else
01023   #error "Update init_window_peripherals() routine for your MCU"
01024 #endif
01025 }


Variable Documentation

U8 h_max_mm

Distance from top of window to inactivate anti-pinch in mm Filled by used in eeprom or by default value (see Default Window area and measurement definitions).

Definition at line 102 of file window_lib.c.

Referenced by init_window_size_position(), Read_Eep_WindowParameters(), and save_window_parameters().

U8 h_max

Distance from top of window to inactivate anti-pinch in hall sensor edges computed using h_max_mm and down variables.

Definition at line 106 of file window_lib.c.

Referenced by get_h_max(), init_window_size_position(), and window_ctrl().

U16 window_height_mm

Opening apartus height in millimeters (filled by user) (see Default Window area and measurement definitions).

Definition at line 110 of file window_lib.c.

Referenced by init_window_size_position(), Read_Eep_WindowParameters(), and save_window_parameters().

U16 h_detect_min_mm

Distance from top of window to activate anti-pinch in millimeters (mm) Filled by used in eeprom or by default value (see Default Window area and measurement definitions).

Definition at line 114 of file window_lib.c.

Referenced by init_window_size_position(), Read_Eep_WindowParameters(), and save_window_parameters().

U16 h_detect_min

Distance from top to activate anti-pinch (in hall sensor edges number) computed using h_detect_min_mm and down variables.

Definition at line 118 of file window_lib.c.

Referenced by blocking_point(), get_h_detect_min(), init_window_size_position(), and window_ctrl().

U16 top_mm

number of hall sensor edges per millimeters (left shifted by 8 to allow a good precision, see Default Window area and measurement definitions).

Definition at line 122 of file window_lib.c.

Referenced by init_window_size_position().

U16 backlash

Backlash value (measured, in hall sensor edges number when revesing direction at intialization time by adaptation routine : init_window_size_position()).

Definition at line 127 of file window_lib.c.

Referenced by init_window_size_position(), Read_Eep_WindowParameters(), save_window_parameters(), and window_ctrl().

U16 down

Down is the number of hall sensor edges for a top to bottom operation Filled by adaptation routine or by user (see Default Window area and measurement definitions).

Definition at line 131 of file window_lib.c.

Referenced by init_window_size_position(), Read_Eep_WindowParameters(), save_window_parameters(), and window_ctrl().

st_b_point_tab block_point

blocking points ram storing table.

It's managed by blocking_point() routine It contains all detected blocking points, and is adapted at operating time.

Definition at line 135 of file window_lib.c.

Referenced by block_point_set_origin(), clean_point(), erase_block_point(), get_block_point(), get_table_indice(), Read_Eep_WindowParameters(), save_window_parameters(), and update_point().

st_b_point point_temp

blocking point temporary buffer.

It's managed by blocking_point() routine while operating to add or refresh blocking points in block_point structure.

Definition at line 139 of file window_lib.c.

Referenced by blocking_point(), and update_point().

U16 start_pos

Remembers the start position of the window lift to refresh blocking points table, starting from this position, when window lift operation ends.

Definition at line 143 of file window_lib.c.

Referenced by clean_point(), and window_ctrl().

U16 stop_pos

Remembers the stop position of the window lift to refresh blocking points table, until this position, when window lift operation ends.

Definition at line 147 of file window_lib.c.

Referenced by blocking_point(), and clean_point().

U8 update = 0

Flag used to refresh blocking points when window lift operation ends.

Definition at line 150 of file window_lib.c.

Referenced by blocking_point(), and window_ctrl().


Generated on Mon May 28 20:26:50 2007 for WINDOWLIFTLIBRARY by  doxygen 1.4.7