1 #include <lpc21xx.h> /* LPC21xx definitions */
3 #include <system_def.h>
5 #include <periph/can.h>
15 #include <can_msg_def.h>
18 #define ENG_LIFT_HOME_SLOW_SPEED 15
19 #define ENG_LIFT_HOME_SPEED 40
20 #define ENG_LIFT_FULL_SPEED 100
21 #define ENG_PUSHER_HOME_SPEED 70
22 #define ENG_PUSHER_FULL_SPEED 100
23 #define ENG_PUSHER_HOME_SLOW_SPEED 40
25 #define TIME_HOMING_WAIT 7000
29 #define PRINT_STR_VAL(fsm,str, val) print_str_val(fsm, str, val)
30 #define PRINT_STR(fsm, str) print_str(fsm, str)
33 static uint8_t fsm_homing_block;
36 void print_str(uint8_t type, uint8_t text[])
39 send_rs_str("FSM_LIFT ");
41 send_rs_str("FSM_PUSHER ");
48 void print_str_val(uint8_t type, uint8_t text[], uint32_t val)
51 send_rs_str("FSM_LIFT ");
53 send_rs_str("FSM_PUSHER ");
61 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 void move_pusher(unsigned char direct,unsigned char velocity){//how many pulzes
63 engine_A_dir(direct);//set direction for lift
64 engine_A_pwm(velocity); // set velocity, range 0~100~200
65 engine_A_en(ENGINE_EN_ON);//enable motor of pusher
68 void move_lift(uint8_t direct,uint8_t velocity){ //how many pulzes
69 // engine_B_dir(direct); //set direction for lift
70 // engine_B_pwm(velocity); // set velocity, range 0~100~200
71 // engine_B_en(ENGINE_EN_ON); //enable motor of pusher
74 vhn_speed(velocity , direct);
75 // PRINT_STR_VAL(FSM_LIFT,"VHN speed:", velocity);
76 // PRINT_STR_VAL(FSM_LIFT,"VHN direct:", direct);
80 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81 void fsm_irc(struct fsm *fsm)
83 int32_t irc = *fsm->irc ;
85 if(fsm->motor_dir == ENGINE_DIR_FW)
86 fsm->act_pos += irc - fsm->last_irc;
88 fsm->act_pos -= irc - fsm->last_irc;
90 if (irc != fsm->last_irc)
91 fsm->last_move_time = timer_msec;
98 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99 void fsm_init(struct fsm *fsm, events my_event)
105 PRINT_STR(fsm->type,"fsm_init: EVENT_ENTRY");
109 fsm->can_req_position = 0;
110 fsm->timeout_glob = 0; // ms
111 fsm->timeout_switch = 0; // ms
112 fsm->motor_dir = ENGINE_DIR_FW;
117 if(fsm->type == FSM_LIFT)
119 fsm->irc = &irc2_count;
120 fsm->set_engine = &move_lift;
121 fsm->sw_pin = LIFT_END_SWITCH; //LIFT_END_SWITCH;
122 fsm->speed_home = ENG_LIFT_HOME_SPEED;
123 fsm->speed_normal= ENG_LIFT_FULL_SPEED;
124 fsm->init_flag = LIFT_LIFT_INIT;
125 fsm->speed_slow = ENG_LIFT_HOME_SLOW_SPEED;
126 fsm_homing_block = FSM_LIFT;
129 if(fsm->type == FSM_PUSHER)
131 fsm->irc = &irc1_count;
132 fsm->set_engine = &move_pusher;
133 fsm->sw_pin = PUSH_END_SWITCH;
134 fsm->speed_home = ENG_PUSHER_HOME_SPEED;
135 fsm->speed_normal= ENG_PUSHER_FULL_SPEED;
136 fsm->init_flag = LIFT_PUSHER_INIT;
137 fsm->speed_slow = ENG_PUSHER_HOME_SLOW_SPEED;
140 fsm->last_irc = *fsm->irc;
141 can_flags |= fsm->init_flag;
146 if(fsm_homing_block == fsm->type) // block lift until release fsm_homing_block
147 fsm->current_state = &fsm_homing_bw;
161 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
162 void fsm_homing_fw(struct fsm *fsm, events my_event){
167 PRINT_STR(fsm->type,"fsm_homing_fw: EVENT_ENTRY");
168 fsm->motor_dir = ENGINE_DIR_FW;
169 fsm->set_engine(fsm->motor_dir, fsm->speed_home);
170 fsm->timeout_glob = timer_msec;
176 if(fsm->switch_front) // || (fsm->timeout_glob + TIME_HOMING_WAIT < timer_msec))
178 fsm->set_engine(fsm->motor_dir, ENG_STOP);
179 fsm->act_pos = 0; // reset position
180 fsm->current_state = &fsm_homing_bw; // move to fsm_homing_bw
181 PRINT_STR(fsm->type,"fsm_homing_fw: EVENT_DO reached endswitch");
182 PRINT_STR_VAL(fsm->type, "Measured IRC: ", *fsm->irc);
193 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194 void fsm_homing_bw(struct fsm *fsm, events my_event){
198 PRINT_STR(fsm->type,"fsm_homing_bw: EVENT_ENTRY");
199 fsm->motor_dir = ENGINE_DIR_BW;
200 fsm->set_engine(ENGINE_DIR_BW, fsm->speed_home);
201 fsm->timeout_switch = timer_msec;
202 fsm->timeout_glob = timer_msec; // FIXME nevim jestli je potreba
209 fsm->set_engine(fsm->motor_dir, ENG_STOP);
210 fsm->lenght = -1 * fsm->act_pos; // store measured lenght
211 fsm->act_pos = 0; // reset position
212 fsm->current_state = &fsm_homing_fw_up; // move to fsm_stop
214 PRINT_STR(fsm->type,"fsm_homing_bw: EVENT_DO reached endswitch");
226 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
227 void fsm_homing_fw_up(struct fsm *fsm, events my_event){
232 can_flags |= fsm->init_flag;
233 PRINT_STR(fsm->type,"fsm_homing_fw_up: EVENT_ENTRY");
234 fsm->motor_dir = ENGINE_DIR_FW;
235 fsm->set_engine(fsm->motor_dir, fsm->speed_home);
236 fsm->timeout_glob = timer_msec;
242 if(fsm->switch_front || (fsm->timeout_glob + 1000 < timer_msec))
244 fsm->set_engine(fsm->motor_dir, ENG_STOP);
245 fsm->current_state = &fsm_homing_bw_zero; // move to fsm_homing_bw
247 PRINT_STR(fsm->type,"fsm_homing_fw_up: EVENT_DO reached endswitch");
259 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
260 void fsm_homing_bw_zero(struct fsm *fsm, events my_event){
264 PRINT_STR(fsm->type,"fsm_homing_bw_zero: EVENT_ENTRY");
265 fsm->motor_dir = ENGINE_DIR_BW;
266 fsm->set_engine(ENGINE_DIR_BW, fsm->speed_slow);
267 fsm->timeout_switch = timer_msec;
268 fsm->timeout_glob = timer_msec; // FIXME nevim jestli je potreba
275 fsm->set_engine(fsm->motor_dir, ENG_STOP);
278 if(fsm->type == FSM_LIFT)
280 fsm->current_state = &fsm_homing_fw_5;
284 fsm->current_state = &fsm_stop; // move to fsm_stop
285 PRINT_STR(fsm->type,"fsm_homing_bw_zero: EVENT_DO reached endswitch");
297 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
298 void fsm_wait_for_pusher_init(struct fsm *fsm, events my_event);
299 void fsm_homing_fw_5(struct fsm *fsm, events my_event){
305 PRINT_STR(fsm->type,"fsm_homing_fw_5: EVENT_ENTRY");
306 fsm->motor_dir = ENGINE_DIR_FW;
307 fsm->set_engine(fsm->motor_dir, fsm->speed_slow);
308 fsm->timeout_glob = timer_msec;
314 if(fsm->switch_front || (fsm->act_pos >= (5*8)))
316 fsm->set_engine(fsm->motor_dir, ENG_STOP);
317 fsm->current_state = fsm_wait_for_pusher_init;
318 PRINT_STR_VAL(fsm->type,"fsm_homing_fw_5: EVENT_DO reached endswitch", *fsm->irc);
319 fsm_homing_block = FSM_PUSHER; // release pusher
330 void fsm_wait_for_pusher_init(struct fsm *fsm, events my_event){
333 can_flags &= ~fsm->init_flag;
336 if ((can_flags & LIFT_PUSHER_INIT) == 0) {
337 fsm->current_state = &fsm_stop; // move to fsm_homing_bw
345 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
346 void fsm_stop(struct fsm *fsm, events my_event){
349 can_flags &= ~fsm->init_flag;
351 fsm->set_engine(fsm->motor_dir , ENG_STOP);
352 PRINT_STR(fsm->type,"fsm_stop: EVENT_ENTRY");
357 /* if(fsm->type == FSM_LIFT) { */
358 /* if ((req >= LIFT_LIFT_PROTECT_PUSHER_TOP) && */
359 /* (fsm->act_pos >= LIFT_PUSHER_PROTECT_TOP )) */
360 /* can_flags |= LIFT_LIFT_ERR_POS; */
362 /* can_flags &= ~(LIFT_LIFT_ERR_POS); */
364 /* if (fsm->type == FSM_PUSHER) { */
365 /* if (fsm_pusher.act_pos < 0) { */
366 /* can_flags |= LIFT_PUSHER_ERR_POS; */
370 /* can_flags &= ~(LIFT_PUSHER_ERR_POS); */
373 if(fsm->req_pos != fsm->can_req_position)
375 fsm->req_pos = fsm->can_req_position;
376 fsm->current_state = &fsm_move; // move to fsm_move
377 PRINT_STR_VAL(fsm->type, "fsm_stop: new position recieved", fsm->req_pos);
378 PRINT_STR_VAL(fsm->type, "fsm_stop: act pos: ", fsm->act_pos);
389 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
390 void fsm_move(struct fsm *fsm, events my_event){
395 PRINT_STR(fsm->type,"fsm_move: EVENT_ENTRY");
397 if (fsm->act_pos > fsm->req_pos) {
398 fsm->motor_dir = ENGINE_DIR_BW; //set the direction of pusher moving
401 fsm->motor_dir = ENGINE_DIR_FW;
404 fsm->last_move_time = timer_msec;
405 fsm->enable_reg = 1; // enable re
410 /* Check end-switches */
412 if((fsm->act_pos < fsm->req_pos) && (fsm->act_pos >= 0xF0))
413 set_servo(SERVO_DOOR, SERVO_DOOR_MAX);
415 if ((fsm->motor_dir == ENGINE_DIR_BW && fsm->switch_back) ||
416 (fsm->motor_dir == ENGINE_DIR_FW && fsm->switch_front)) {
417 fsm->set_engine(fsm->motor_dir, ENG_STOP);
418 fsm->current_state = &fsm_wait; // move to fsm_homing_bw
419 fsm->ans_can = fsm->req_pos;
421 PRINT_STR_VAL(fsm->type, "fsm_move: reached endswitch", fsm->req_pos);
422 // TODO FIXME TODO FIXME TODO FIXME nastavit act_pos =0?????
426 /* Normal movement */
427 if (fsm->motor_dir == ENGINE_DIR_BW)
428 e = fsm->act_pos - fsm->req_pos;
430 e = fsm->req_pos - fsm->act_pos;
433 if(fsm->req_pos == 0) // musi dojet na koncak
435 if(e <= 0 || timer_msec - fsm->last_move_time > 200)
437 fsm->set_engine(fsm->motor_dir, 35 /*fsm->speed_normal*/);
444 if (e > 0 && fsm->enable_reg ) {
445 /* Go there (P controller)*/
448 fsm->set_engine(fsm->motor_dir, u /*fsm->speed_normal*/);
449 fsm->ans_can = fsm->act_pos;
454 if (e <= 0 || timer_msec - fsm->last_move_time > 200) {
456 fsm->set_engine(fsm->motor_dir, ENG_STOP);
458 fsm->current_state = &fsm_wait;
460 fsm->current_state = &fsm_stop;
461 fsm->ans_can = fsm->req_pos;
464 PRINT_STR(fsm->type,"fsm_move: reached target");
466 PRINT_STR_VAL(fsm->type,"fsm_move: move timeout at pos", fsm->act_pos);
470 fsm->set_engine(fsm->motor_dir, ENG_STOP);
476 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
477 void fsm_wait(struct fsm *fsm, events my_event){
480 fsm->timeout_glob = timer_msec;
481 PRINT_STR(fsm->type,"fsm_wait: EVENT_ENTRY");
486 if((fsm->timeout_glob + TIME_WAIT) >+ timer_msec)
488 fsm->current_state = &fsm_stop; // move to fsm_homing_bw
493 PRINT_STR(fsm->type,"fsm_wait: EXIT");