6 * @author Bc. Jiri Kubias, jiri.kubias@gmail.com
7 * @author Michal Sojka <sojkam1@fel.cvut.cz>
14 * @defgroup fork Vidle (fork) application
22 #include <lpc21xx.h> /* LPC21xx definitions */
25 #include <system_def.h>
27 #include <periph/can.h>
32 #include <can_msg_def.h>
38 #define CAN_SPEED 1000000 //< CAN bus speed
43 #define TIMER_IRQ_PRIORITY 5
48 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 void init_motors(void){
57 init_engine_A(); // initialization of PWM unit
58 engine_A_en(ENGINE_EN_ON); //enable motor A
59 engine_A_dir(ENGINE_DIR_FW); //set direction
60 engine_A_pwm(0); // STOP pwm is in percent, range 0~100~200
62 init_engine_B(); // initialization of PWM unit
63 engine_B_en(ENGINE_EN_ON); //enable motor B
64 engine_B_dir(ENGINE_DIR_FW); //set direction
65 engine_B_pwm(0); // STOP pwm is in percent, range 0~100~200
70 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71 void set_irq_handler(uint8_t source, uint8_t irq_vect, void (*handler)()) {
72 /* set interrupt vector */
73 ((uint32_t*)&VICVectAddr0)[irq_vect] = (uint32_t)handler;
74 ((uint32_t*)&VICVectCntl0)[irq_vect] = 0x20 | source;
75 /* enable interrupt */
76 VICIntEnable = 1<<source;
79 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82 void timer0_irq() __attribute__((interrupt));
83 volatile uint32_t timer_msec = 0, timer_usec = 0;
85 void init_timer0(uint32_t prescale, uint32_t period) {
86 T0TCR = 0x2; /* reset */
89 T0MCR = 0x3; /* match0: reset & irq */
90 T0EMR = 0; /* no ext. match */
91 T0CCR = 0x0; /* no capture */
92 T0TCR = 0x1; /* go! */
96 static unsigned cnt1khz = 0;
101 /* increment timer_usec */
103 /* increment msec @1kHz */
104 if (++cnt1khz == 100) {
109 /* int acknowledge */
114 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116 // #define START_PIN 15 // start pin
117 // #define START_SEND_PRIOD_FAST 50 /* [miliseconds] */
118 // #define START_SEND_PRIOD_SLOW 300 /* [miliseconds] */
119 // #define START_SEND_FAST_COUNT 10 /* How many times to send start with small period (after a change) */
122 // void start_button(void)
125 // bool start_condition;
126 // static bool last_start_condition = 0;
128 // static int count = 0;
129 // static uint32_t next_send = 0;
132 // start_condition = (IO0PIN & (1<<START_PIN)) == 0;
134 // if (start_condition != last_start_condition) {
135 // last_start_condition = start_condition;
137 // next_send = timer_msec; /* Send now */
140 // if (timer_msec >= next_send) {
141 // msg.id = CAN_ROBOT_CMD;
144 // msg.data[0] = start_condition;
145 // /*while*/ (can_tx_msg(&msg));
147 // if (count < START_SEND_FAST_COUNT) {
149 // next_send = timer_msec + START_SEND_PRIOD_FAST;
151 // next_send = timer_msec + START_SEND_PRIOD_SLOW;
158 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159 void CAN_rx(can_msg_t *msg) {
163 memcpy(&rx_msg, msg, sizeof(can_msg_t));//make copy of message
170 case CAN_JAW_LEFT_CMD:
172 req = ((rx_msg.data[0]<<8) | (rx_msg.data[1]));
173 spd = rx_msg.data[2];
175 if (req >= 0x150 && req <= 0x3e0) {
176 fsm_jaws.flags &= ~CAN_JAWS_OUT_OF_BOUNDS;
177 fsm_jaws.can_req_position_left = req;// save new req position of lift
178 fsm_jaws.can_req_spd_left = spd;// save new req spd of lift
180 fsm_jaws.flags |= CAN_JAWS_OUT_OF_BOUNDS;
183 case CAN_JAW_RIGHT_CMD:
185 req = ((rx_msg.data[0]<<8) | (rx_msg.data[1]));
186 spd = rx_msg.data[2];
188 if (req >= 0x150 && req <= 0x3e0) {
189 fsm_jaws.flags &= ~CAN_JAWS_OUT_OF_BOUNDS;
190 fsm_jaws.can_req_position_right = req;// save new req position of lift
191 fsm_jaws.can_req_spd_right = spd;// save new req spd of lift
193 fsm_jaws.flags |= CAN_JAWS_OUT_OF_BOUNDS;
203 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204 void init_periphery(void){
206 can_init_baudrate(CAN_SPEED, CAN_ISR, CAN_rx);//initialization of CAN bus
210 init_timer0(1, CPU_APB_HZ/100000);
211 set_irq_handler(4 /*timer0*/, TIMER_IRQ_PRIORITY, timer0_irq);
218 /*********************************************************/
219 void can_send_status(void)
222 tx_msg.id = CAN_JAW_LEFT_STATUS;
225 tx_msg.data[0] = (fsm_jaws.act_pos_left >> 8) & 0xFF;
226 tx_msg.data[1] = fsm_jaws.act_pos_left & 0xFF;
227 tx_msg.data[2] = (fsm_jaws.can_response >> 8) & 0xFF;
228 tx_msg.data[3] = fsm_jaws.can_response & 0xFF;
229 tx_msg.data[4] = fsm_jaws.flags;
230 /*while*/(can_tx_msg(&tx_msg)); /* CAN erratum workaround */
233 tx_msg.id = CAN_JAW_RIGHT_STATUS;
236 tx_msg.data[0] = (fsm_jaws.act_pos_right >> 8) & 0xFF;
237 tx_msg.data[1] = fsm_jaws.act_pos_right & 0xFF;
238 tx_msg.data[2] = (fsm_jaws.can_response >> 8) & 0xFF;
239 tx_msg.data[3] = fsm_jaws.can_response & 0xFF;
240 tx_msg.data[4] = fsm_jaws.flags;
241 /*while*/(can_tx_msg(&tx_msg)); /* CAN erratum workaround */
244 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
247 void dbg_print_time()
250 unsigned t = timer_usec, i;
251 memset(str, ' ', sizeof(str));
254 for (i=7; t > 0; i--) {
261 void fsm_jaws_init(struct fsm *fsm, enum event event);
266 static uint32_t led_time = 0;
268 if(timer_msec >= led_time + 500)
270 led_time = timer_msec;
273 fsm_vidle.can_req_position = 0x380;
275 fsm_vidle.can_req_position = 0x1e0;
278 deb_led_change(LEDG);
279 send_rs_str("LEFT_ACT_POS:");
280 send_rs_int(fsm_jaws.act_pos_left);
282 send_rs_str("RIGHT_ACT_POS:");
283 send_rs_int(fsm_jaws.act_pos_right);
289 // #define BUMPER_PIN 17 // bumper pin (SCK1/P0_17)
290 // #define COLOR_PIN 3 // change color of dress pin (SDA1/P0_3)
292 // #define BUMPER_LEFT 19 // left bumper MOSI1/P0_19
293 // #define BUMPER_RIGHT 9 // right bumper RXD1/P0_9
295 #define BUMPER_REAR 17 // rear bumper in the lift (SCK1/P0_17)
297 #define BUMPER_LEFT 19 // left bumper MOSI1/P0_19
298 #define BUMPER_RIGHT 9 // right bumper RXD1/P0_9
300 #define BUMPER_LEFT_CORNER 16 // left bumper in rear corner
301 #define BUMPER_RIGHT_CORNER 13 // right bumper in rear corner
305 static uint32_t bumper_time = 0;
308 if (timer_msec >= bumper_time + 100)
312 bumper_time = timer_msec;
316 if (IO0PIN & (1<<BUMPER_REAR))
317 sw &= ~CAN_SWITCH_BUMPER;
319 sw |= CAN_SWITCH_BUMPER;
321 if (IO0PIN & (1<<BUMPER_LEFT_CORNER))
322 sw |= CAN_SWITCH_CORNER_LEFT;
324 sw &= ~CAN_SWITCH_CORNER_LEFT;
326 if (IO0PIN & (1<<BUMPER_RIGHT_CORNER))
327 sw |= CAN_SWITCH_CORNER_RIGHT;
329 sw &= ~CAN_SWITCH_CORNER_RIGHT;
331 if (IO0PIN & (1<<BUMPER_LEFT))
332 sw &= ~CAN_SWITCH_LEFT;
334 sw |= CAN_SWITCH_LEFT;
336 if (IO0PIN & (1<<BUMPER_RIGHT))
337 sw &= ~CAN_SWITCH_RIGHT;
339 sw |= CAN_SWITCH_RIGHT;
341 // if (sw & CAN_SWITCH_COLOR)
342 // deb_led_off(LEDY);
346 if (sw & (CAN_SWITCH_BUMPER|CAN_SWITCH_LEFT|CAN_SWITCH_RIGHT|BUMPER_RIGHT_CORNER|BUMPER_LEFT_CORNER))
351 /* TODO: Put color to the second bit */
353 tx_msg.id = CAN_ROBOT_SWITCHES;
366 // char dir = ENGINE_DIR_BW;
369 // spd = (spd+1)%100;
374 // vhn_speed(spd, dir);
376 // uart_send_char(' ');
378 // send_rs_str(" Vidle started\n");
379 // /* char ch = uart_get_char(); */
380 // /* switch (ch) { */
385 // /* vhn_speed(0, dir); */
388 // /* vhn_speed(0x40, dir); */
391 // /* vhn_speed(0x80, dir); */
394 // /* vhn_speed(0xa0, dir); */
399 // /* uart_send_char(ch); */
405 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
406 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
407 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
410 uint32_t main_time = timer_usec;
411 uint32_t status_time = timer_usec;
416 /* TODO: Add comment FIXME: zkusit smazat, mam moct ze to melo neco spojeneho s chelae z eb09 */
417 //SET_PIN(PINSEL1, 1, PINSEL_0);
418 //SET_PIN(PINSEL1, 3, PINSEL_0);
423 // SET_PIN(PINSEL0, START_PIN, PINSEL_0); // inicializace start pinu
424 SET_PIN(PINSEL0, COLOR_PIN, PINSEL_0);
425 SET_PIN(PINSEL1, 1, PINSEL_0); // inicializace bumper pinu (FIXME SET_PIN je BLBA implemetace, musim ji nekdy opravit)
427 SET_PIN(PINSEL1, 3, PINSEL_0);
428 SET_PIN(PINSEL0, BUMPER_RIGHT, PINSEL_0);
431 // IO0DIR &= ~((1<<START_PIN) | (1<<BUMPER_RIGHT) | (1 << COLOR_PIN));
432 IO0DIR &= ~((1<<BUMPER_PIN) | (1<<BUMPER_LEFT));
434 //IO1DIR &= ~(3<<20);
436 send_rs_str("Jaws started\n");
437 // The above send_rs_str is importat - we wait for the first AD conversion to be finished
438 fsm_jaws.act_pos_left = adc_val[0];
439 fsm_jaws.act_pos_right = adc_val[1];
441 init_fsm(&fsm_jaws, &fsm_jaws_init);
447 if(timer_usec >= main_time + 1000)
449 main_time = timer_usec;
453 fsm_jaws.act_pos_left = adc_val[0];
454 fsm_jaws.act_pos_right = adc_val[1];
460 if (timer_msec >= status_time + 100 || //repeat sending message every 100 ms
462 .trigger_can_send) { //or when something important happen
464 .trigger_can_send = false;
465 status_time = timer_msec; //save new time, when message was sent