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
64 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65 void set_irq_handler(uint8_t source, uint8_t irq_vect, void (*handler)()) {
66 /* set interrupt vector */
67 ((uint32_t*)&VICVectAddr0)[irq_vect] = (uint32_t)handler;
68 ((uint32_t*)&VICVectCntl0)[irq_vect] = 0x20 | source;
69 /* enable interrupt */
70 VICIntEnable = 1<<source;
73 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76 void timer0_irq() __attribute__((interrupt));
77 volatile uint32_t timer_msec = 0, timer_usec = 0;
79 void init_timer0(uint32_t prescale, uint32_t period) {
80 T0TCR = 0x2; /* reset */
83 T0MCR = 0x3; /* match0: reset & irq */
84 T0EMR = 0; /* no ext. match */
85 T0CCR = 0x0; /* no capture */
86 T0TCR = 0x1; /* go! */
90 static unsigned cnt1khz = 0;
95 /* increment timer_usec */
97 /* increment msec @1kHz */
98 if (++cnt1khz == 100) {
103 /* int acknowledge */
108 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110 #define START_PIN 15 // start pin
111 #define START_SEND_PRIOD_FAST 50 /* [miliseconds] */
112 #define START_SEND_PRIOD_SLOW 300 /* [miliseconds] */
113 #define START_SEND_FAST_COUNT 10 /* How many times to send start with small period (after a change) */
116 void start_button(void)
119 bool start_condition;
120 static bool last_start_condition = 0;
122 static int count = 0;
123 static uint32_t next_send = 0;
126 start_condition = (IO0PIN & (1<<START_PIN)) == 0;
128 if (start_condition != last_start_condition) {
129 last_start_condition = start_condition;
131 next_send = timer_msec; /* Send now */
134 if (timer_msec >= next_send) {
135 msg.id = CAN_ROBOT_CMD;
138 msg.data[0] = start_condition;
139 /*while*/ (can_tx_msg(&msg));
141 if (count < START_SEND_FAST_COUNT) {
143 next_send = timer_msec + START_SEND_PRIOD_FAST;
145 next_send = timer_msec + START_SEND_PRIOD_SLOW;
153 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
154 void CAN_rx(can_msg_t *msg) {
158 memcpy(&rx_msg, msg, sizeof(can_msg_t));//make copy of message
167 req = ((rx_msg.data[0]<<8) | (rx_msg.data[1]));
168 spd = rx_msg.data[2];
170 if (req >= 0x150 && req <= 0x3e0) {
171 fsm_vidle.flags &= ~CAN_VIDLE_OUT_OF_BOUNDS;
172 fsm_vidle.can_req_position = req;// save new req position of lift
173 fsm_vidle.can_req_spd = spd;// save new req spd of lift
175 fsm_vidle.flags |= CAN_VIDLE_OUT_OF_BOUNDS;
184 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185 void init_periphery(void){
187 // can_init_baudrate(CAN_SPEED, CAN_ISR, CAN_rx);//initialization of CAN bus
191 init_timer0(1, CPU_APB_HZ/100000);
192 set_irq_handler(4 /*timer0*/, TIMER_IRQ_PRIORITY, timer0_irq);
199 /*********************************************************/
201 void can_send_status(void)
204 tx_msg.id = CAN_VIDLE_STATUS;
207 tx_msg.data[0] = (fsm_vidle.act_pos >> 8) & 0xFF;
208 tx_msg.data[1] = fsm_vidle.act_pos & 0xFF;
209 tx_msg.data[2] = (fsm_vidle.can_response >> 8) & 0xFF;
210 tx_msg.data[3] = fsm_vidle.can_response & 0xFF;
211 tx_msg.data[4] = fsm_vidle.flags;
212 /*while*/(can_tx_msg(&tx_msg)); /* CAN erratum workaround */
215 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
216 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218 void dbg_print_time()
221 unsigned t = timer_usec, i;
222 memset(str, ' ', sizeof(str));
225 for (i=7; t > 0; i--) {
232 void fsm_vidle_init(struct fsm *fsm, enum event event);
237 static uint32_t led_time = 0;
239 if(timer_msec >= led_time + 500)
241 led_time = timer_msec;
244 fsm_vidle.can_req_position = 0x380;
246 fsm_vidle.can_req_position = 0x1e0;
249 deb_led_change(LEDG);
250 send_rs_int(fsm_vidle.act_pos);
256 #define BUMPER_PIN 17 // bumper pin (SCK1/P0_17)
257 #define COLOR_PIN 3 // change color of dress pin (SDA1/P0_3)
259 #define BUMPER_LEFT 19 // left bumper MOSI1/P0_19
260 #define BUMPER_RIGHT 9 // right bumper RXD1/P0_9
265 static uint32_t bumper_time = 0;
268 if (timer_msec >= bumper_time + 100)
272 bumper_time = timer_msec;
276 if (IO0PIN & (1<<BUMPER_PIN))
277 sw &= ~CAN_SWITCH_BUMPER;
279 sw |= CAN_SWITCH_BUMPER;
281 if (IO0PIN & (1<<COLOR_PIN))
282 sw |= CAN_SWITCH_COLOR;
284 sw &= ~CAN_SWITCH_COLOR;
286 if (IO0PIN & (1<<BUMPER_LEFT))
287 sw &= ~CAN_SWITCH_LEFT;
289 sw |= CAN_SWITCH_LEFT;
291 if (IO0PIN & (1<<BUMPER_RIGHT))
292 sw &= ~CAN_SWITCH_RIGHT;
294 sw |= CAN_SWITCH_RIGHT;
296 if (sw & CAN_SWITCH_COLOR)
301 if (sw & (CAN_SWITCH_BUMPER|CAN_SWITCH_LEFT|CAN_SWITCH_RIGHT))
306 /* TODO: Put color to the second bit */
308 tx_msg.id = CAN_ROBOT_SWITCHES;
320 volatile unsigned int wait = 5000000;
323 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
325 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
328 uint32_t main_time = timer_usec;
329 uint32_t status_time = timer_usec;
332 int i=0,delta=0,j=0,suma=0;
337 /* TODO: Add comment FIXME: zkusit smazat, mam moct ze to melo neco spojeneho s chelae z eb09 */
338 //SET_PIN(PINSEL1, 1, PINSEL_0);
339 //SET_PIN(PINSEL1, 3, PINSEL_0);
344 SET_PIN(PINSEL0, START_PIN, PINSEL_0); // inicializace start pinu
345 SET_PIN(PINSEL0, COLOR_PIN, PINSEL_0);
346 SET_PIN(PINSEL1, 1, PINSEL_0); // inicializace bumper pinu (FIXME SET_PIN je BLBA implemetace, musim ji nekdy opravit)
348 SET_PIN(PINSEL1, 3, PINSEL_0);
349 SET_PIN(PINSEL0, BUMPER_RIGHT, PINSEL_0);
352 IO0DIR &= ~((1<<START_PIN) | (1<<BUMPER_RIGHT) | (1 << COLOR_PIN));
353 IO0DIR &= ~((1<<BUMPER_PIN) | (1<<BUMPER_LEFT));
355 //IO1DIR &= ~(3<<20);
357 send_rs_str("Vidle started\n");
358 // The above send_rs_str is importat - we wait for the first AD conversion to be finished
359 fsm_vidle.act_pos = adc_val[0];
366 if(timer_usec >= main_time + 1000)
368 main_time = timer_usec;
372 // fsm_vidle.act_pos = adc_val[0];
375 // run_fsm(&fsm_vidle);
378 if (timer_msec >= status_time + 100 || //repeat sending message every 100 ms
379 fsm_vidle.trigger_can_send) { //or when something important happen
380 fsm_vidle.trigger_can_send = false;
381 status_time = timer_msec; //save new time, when message was sent
382 // can_send_status();
396 if (abs(suma)<1) {obrat=!obrat;}
406 engine_A_dir(ENGINE_DIR_BW);
407 else {engine_A_dir(ENGINE_DIR_FW);
415 engine_A_dir(ENGINE_DIR_FW);
416 else {engine_A_dir(ENGINE_DIR_BW);