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>
37 #define CAN_SPEED 1000000 //< CAN bus speed
42 #define TIMER_IRQ_PRIORITY 5
45 struct fsm fsm_jaw_right;
46 struct fsm fsm_jaw_left;
48 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52 void init_motors(void){
54 init_engine_A(); // initialization of PWM unit
55 engine_A_en(ENGINE_EN_ON); //enable motor A
56 engine_A_dir(ENGINE_DIR_FW); //set direction
57 engine_A_pwm(0); // STOP pwm is in percent, range 0~100~200
59 init_engine_B(); // initialization of PWM unit
60 engine_B_en(ENGINE_EN_ON); //enable motor A
61 engine_B_dir(ENGINE_DIR_FW); //set direction
62 engine_B_pwm(0); // STOP pwm is in percent, range 0~100~200
67 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
68 void set_irq_handler(uint8_t source, uint8_t irq_vect, void (*handler)()) {
69 /* set interrupt vector */
70 ((uint32_t*)&VICVectAddr0)[irq_vect] = (uint32_t)handler;
71 ((uint32_t*)&VICVectCntl0)[irq_vect] = 0x20 | source;
72 /* enable interrupt */
73 VICIntEnable = 1<<source;
76 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79 void timer0_irq() __attribute__((interrupt));
80 volatile uint32_t timer_msec = 0, timer_usec = 0;
83 void init_timer0(uint32_t prescale, uint32_t period) {
84 T0TCR = 0x2; /* reset */
87 T0MCR = 0x3; /* match0: reset & irq */
88 T0EMR = 0; /* no ext. match */
89 T0CCR = 0x0; /* no capture */
90 T0TCR = 0x1; /* go! */
95 static unsigned cnt1khz = 0;
100 /* increment timer_usec */
102 /* increment msec @1kHz */
103 if (++cnt1khz == 100) {
108 /* int acknowledge */
113 void CAN_rx(can_msg_t *msg) {
117 memcpy(&rx_msg, msg, sizeof(can_msg_t));//make copy of message
124 case CAN_JAW_LEFT_CMD:
127 req = ((rx_msg.data[0]<<8) | (rx_msg.data[1]));
128 spd = rx_msg.data[2];
130 if (req >= fsm_jaw_left.min_pos && req <= fsm_jaw_left.max_pos) {
131 fsm_jaw_left.flags &= ~CAN_JAW_OUT_OF_BOUNDS;
132 fsm_jaw_left.can_req_position = req;
133 fsm_jaw_left.can_req_spd = spd;
135 fsm_jaw_left.flags |= CAN_JAW_OUT_OF_BOUNDS;
138 case CAN_JAW_RIGHT_CMD:
141 req = ((rx_msg.data[0]<<8) | (rx_msg.data[1]));
142 spd = rx_msg.data[2];
144 if (req >= fsm_jaw_right.min_pos && req <= fsm_jaw_right.max_pos) {
145 fsm_jaw_right.flags &= ~CAN_JAW_OUT_OF_BOUNDS;
146 fsm_jaw_right.can_req_position = req;
147 fsm_jaw_right.can_req_spd = spd;
149 fsm_jaw_right.flags |= CAN_JAW_OUT_OF_BOUNDS;
158 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
159 void init_periphery(void){
161 can_init_baudrate(CAN_SPEED, CAN_ISR, CAN_rx);//initialization of CAN bus
165 init_timer0(1, CPU_APB_HZ/100000);
166 set_irq_handler(4 /*timer0*/, TIMER_IRQ_PRIORITY, timer0_irq);
173 /*********************************************************/
174 void can_send_status(struct fsm *fsm){
176 tx_msg.id = fsm->can_id;
179 tx_msg.data[0] = (fsm->act_pos >> 8) & 0xFF;
180 tx_msg.data[1] = fsm->act_pos & 0xFF;
181 tx_msg.data[2] = (fsm->can_response >> 8) & 0xFF;
182 tx_msg.data[3] = fsm->can_response & 0xFF;
183 tx_msg.data[4] = fsm->flags;
184 /*while*/(can_tx_msg(&tx_msg)); /* CAN erratum workaround */
188 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
189 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191 void dbg_print_time()
194 unsigned t = timer_usec, i;
195 memset(str, ' ', sizeof(str));
198 for (i=7; t > 0; i--) {
205 void fsm_jaw_init(struct fsm *fsm, enum event event);
209 static uint32_t led_time = 0;
211 if(timer_msec >= led_time + 500)
213 led_time = timer_msec;
216 fsm_vidle.can_req_position = 0x380;
218 fsm_vidle.can_req_position = 0x1e0;
221 deb_led_change(LEDG);
222 send_rs_int(fsm_jaw_left.act_pos);
224 send_rs_int(fsm_jaw_right.act_pos);
231 #define BUMPER_LEFT 18
232 #define BUMPER_RIGHT 8
234 #define BUMPER_LEFT_ACROSS 19
235 #define BUMPER_RIGHT_ACROSS 17
237 #define BUMPER_REAR 15
241 static uint32_t bumper_time = 0;
244 if (timer_msec >= bumper_time + 100)
248 bumper_time = timer_msec;
252 if (IO0PIN & (1<<BUMPER_REAR)){
253 sw &= ~CAN_BUMPER_REAR;
255 // send_rs_str("rear\n");
260 sw |= CAN_BUMPER_REAR;
262 // deb_led_off(LEDY);
265 if (IO0PIN & (1<<BUMPER_LEFT)){
267 sw &= ~CAN_BUMPER_LEFT;
269 // send_rs_str("left\n");
275 sw |= CAN_BUMPER_LEFT;
277 // deb_led_off(LEDB);
279 if (IO0PIN & (1<<BUMPER_RIGHT)){
280 sw &= ~CAN_BUMPER_RIGHT;
281 // send_rs_str("right\n");
285 sw |= CAN_BUMPER_RIGHT;
287 // deb_led_off(LEDG);
289 if (IO0PIN & (1<<BUMPER_LEFT_ACROSS)){
290 sw &= ~CAN_BUMPER_LEFT_ACROSS;
291 // send_rs_str("left_across\n");
295 sw |= CAN_BUMPER_LEFT_ACROSS;
297 // deb_led_off(LEDR);
299 if (IO0PIN & (1<<BUMPER_RIGHT_ACROSS)){
300 sw &= ~CAN_BUMPER_RIGHT_ACROSS;
301 // send_rs_str("right_across\n");
305 sw |= CAN_BUMPER_RIGHT_ACROSS;
307 // deb_led_off(LEDY);
310 if (sw & (CAN_BUMPER_REAR | CAN_BUMPER_LEFT | CAN_BUMPER_RIGHT | CAN_BUMPER_LEFT_ACROSS | CAN_BUMPER_RIGHT_ACROSS))
315 // send_rs_int(IO1PIN);
317 // send_rs_str("\n");
320 tx_msg.id = CAN_ROBOT_BUMPERS;
330 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
331 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
332 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
335 uint32_t main_time = timer_usec;
336 uint32_t status_time_left = timer_usec;
337 uint32_t status_time_right = timer_usec;
342 SET_PIN(PINSEL1, 1, PINSEL_0);
343 SET_PIN(PINSEL1, 2, PINSEL_0);
344 SET_PIN(PINSEL1, 3, PINSEL_0);
345 SET_PIN(PINSEL0, BUMPER_REAR, PINSEL_0);
346 SET_PIN(PINSEL0, BUMPER_RIGHT, PINSEL_0);
348 IO0DIR &= ~((1<<BUMPER_REAR) | (1<<BUMPER_RIGHT) | (1<<BUMPER_LEFT) | (1<<BUMPER_RIGHT_ACROSS) | (1<<BUMPER_LEFT_ACROSS));
350 send_rs_str("Jaws started\n");
352 //close jaw, max_pos, open jaw min_pos
353 //letf jaw potenciometer on ADC 0, header J32 on board
354 fsm_jaw_left.max_pos=0x320; //max 0x324
355 fsm_jaw_left.min_pos=0xC0; //min 0xb7
356 fsm_jaw_left.act_pos = adc_val[0];
358 //close jaw, max_pos, open jaw min_pos
359 //letf jaw potenciometer on ADC 1, header J33 on board
360 fsm_jaw_right.max_pos=0x380; //max 0x387
361 fsm_jaw_right.min_pos=0x120; //min 0x117
362 fsm_jaw_right.act_pos = adc_val[1];
364 //left jaw engine is engine A, conector MOTA on board
365 fsm_jaw_left.engine_en = &engine_A_en;
366 fsm_jaw_left.engine_dir = &engine_A_dir;
367 fsm_jaw_left.engine_pwm = &engine_A_pwm;
369 fsm_jaw_left.can_id=CAN_JAW_LEFT_STATUS;
371 //right jaw engine is engine B, conector MOTB on board
372 fsm_jaw_right.engine_en = &engine_B_en;
373 fsm_jaw_right.engine_dir = &engine_B_dir;
374 fsm_jaw_right.engine_pwm = &engine_B_pwm;
376 fsm_jaw_right.can_id=CAN_JAW_RIGHT_STATUS;
378 init_fsm(&fsm_jaw_right, &fsm_jaw_init);
379 init_fsm(&fsm_jaw_left, &fsm_jaw_init);
385 if(timer_usec >= main_time + 1000)
387 main_time = timer_usec;
391 fsm_jaw_left.act_pos = adc_val[0];
392 run_fsm(&fsm_jaw_left);
394 fsm_jaw_right.act_pos = adc_val[1];
395 run_fsm(&fsm_jaw_right);
399 if (timer_msec >= status_time_left + 100 || //repeat sending message every 100 ms
400 fsm_jaw_left.trigger_can_send) { //or when something important happen
401 fsm_jaw_left.trigger_can_send = false;
402 status_time_left = timer_msec; //save new time, when message was sent
403 can_send_status(&fsm_jaw_left);
407 if (timer_msec >= status_time_right + 100 || //repeat sending message every 100 ms
408 fsm_jaw_right.trigger_can_send) { //or when something important happen
409 fsm_jaw_right.trigger_can_send = false;
410 status_time_right = timer_msec; //save new time, when message was sent
411 can_send_status(&fsm_jaw_right);