1 /* procesor H8S/2638 ver 1.1 */
6 #include <system_def.h>
9 #include <periph/sci_rs232.h>
15 /* void exit(int status) */
26 #define MAXTIME 32767 //Maximum of time_after_start
27 #define STARTUP_TIME 50*15 //Time for calibration
28 int time_after_start = 0; //Counting time after start, will stop at MAXTIME
30 int heli_mode = HELI_MODE_INIT;
32 int timer_led_can0 = LED_SHORT_BLINK_TIME;
33 int timer_led_can1 = LED_SHORT_BLINK_TIME;
35 int allow_direct_wd_refresh = 0; //Hack for WD refresh during printf
38 #define SER_MODE_IDLE 0
39 #define SER_MODE_COMMAND 1
41 int serial_mode = SER_MODE_IDLE;
42 int serial_command = 0;
43 int awaited_chars = 0;
44 int received_chars = 0;
47 char receive_array[REC_LENGTH];
50 int debug_voltages = 0;
53 int debug_main_prog = 0;
68 /* If you want to spare memory and only have support for SCI channels
69 * 0 and 1 uncomment the following block. */
71 sci_info_t *sci_rs232_chan_array[] = {
77 static void deb_led_out(char val)
98 {/* set shaddow registers */
99 /* DIO_P1DDR_shadow=0;
100 DIO_P3DDR_shadow=0; */
103 SHADOW_REG_SET(DIO_PJDDR,0xee); / * set PJ.1, PJ.2, PJ.3 LED output * /
106 SHADOW_REG_SET(DIO_P3DDR,0x85); */
108 /* show something on debug leds */
113 //Initialize WD pin as output
114 SHADOW_REG_SET(DIO_PCDDR,PCDDR_PC7DDRm);
121 void led_blink(int* timer, int mask, int time) {
128 void debug_main(void) {
131 case HELI_MODE_INIT: printf("INIT, ");break;
132 case HELI_MODE_RUN: printf("RUN, ");break;
133 default: printf("????, ");break;
135 printf("Uptime: %i s, ",(time_after_start/50));
140 void LightOn(void) __attribute__ ((interrupt_handler));
143 *TPU_TSR1 &= ~TSR1_TCFVm ; //reset overflow flag
144 *TPU_TCNT1 = 0xFFFF - 29*1000;
152 int out_num=-1,out_val=-1;
155 cli(); //Stop interrupts
158 *DIO_PADDR=0x0f; /* A16-A19 are outputs */
161 excptvec_initfill(LightOn,0);
163 excptvec_set(42,LightOn);
165 init_CAN_interrupts();
166 init_servo_outputs();
177 sci_rs232_chan_default = 0;
178 sci_rs232_setmode(57600, 0, 0, 0);
187 print_introduction();
189 received = sci_rs232_recch(0);
191 switch (serial_mode) {
192 case SER_MODE_COMMAND:
193 printf("Got char %c in command mode. Total chars: %d, awaiting: %d\n",received,received_chars,awaited_chars);
194 receive_array[received_chars++] = (char)received;
195 receive_array[received_chars] = 0;
196 if(received_chars>=awaited_chars) {
198 switch(serial_command) {
200 printf("Got sentence: %s\n",receive_array);
201 sscanf(receive_array+1,"%4X",&out_val);
202 receive_array[1] = 0;
203 sscanf(receive_array,"%1X",&out_num);
204 printf("Decoded: %d, %X\n",out_num,out_val);
205 if((out_num < OUTPUTS_COUNT) && (out_num >= 0)) {
206 servo_mirror_input[out_num] = out_val;
210 printf("Got sentence: %s\n",receive_array);
211 sscanf(receive_array,"%2X",&out_val);
212 printf("Decoded: %X\n",out_val);
213 *rc_maska_can = out_val;
217 serial_mode = SER_MODE_IDLE;received_chars = 0;
219 if(received_chars>=REC_LENGTH-1) {
220 printf("buffer full\n");
221 serial_mode = SER_MODE_IDLE;received_chars = 0;
228 case 'H': case 'h': print_help(); break;
229 case 'A': case 'a': rc_mode = RC_MODE_AUTO; break;
230 case 'M': case 'm': rc_mode = RC_MODE_MANUAL; break;
231 case 'C': case 'c': debug_CAN = ~debug_CAN; break;
232 case 'V': case 'v': debug_voltages = ~debug_voltages; break;
233 case 'S': case 's': debug_servos = ~debug_servos; break;
234 case 'P': case 'p': debug_main_prog = ~debug_main_prog; break;
235 case 'O': case 'o': awaited_chars = 5; serial_mode = SER_MODE_COMMAND; serial_command = 'O'; break;
236 case 'K': case 'k': awaited_chars = 2; serial_mode = SER_MODE_COMMAND; serial_command = 'K'; break;
237 case '?': print_short_status(); break;
238 default : printf("For help hit h.\n"); break;
242 default: serial_mode = SER_MODE_IDLE; break;
245 //printf(":%c:\n",received);
253 timer_middle_interval();
264 void print_introduction() {
265 int temp_wd_rfr = allow_direct_wd_refresh;
267 allow_direct_wd_refresh = 1;
268 printf("**************************************\n");
269 printf("* H E L I C O P T E R S E R V O *\n");
270 printf("* C O N T R O L L E R *\n");
271 printf("*------------------------------------*\n");
272 printf("* Ota Herm, DCE FEE CTU 2006 *\n");
273 printf("**************************************\n");
274 printf("Compiled: %s, %s\n",__DATE__,__TIME__);
275 printf("For help hit h.\n\n");
277 allow_direct_wd_refresh = temp_wd_rfr;
281 allow_direct_wd_refresh = 1;
283 print_introduction();
285 printf("H\tshows this help\n");
286 printf("A\tsets to the AUTOMATIC mode\n");
287 printf("M\tsets to the MANUAL mode\n");
288 printf("V\ttoggles debugging of voltages\n");
289 printf("S\ttoggles debugging of servo values\n");
290 printf("C\ttoggles debugging of CAN\n");
291 printf("P\ttoggles debugging of main program\n");
292 printf("OxYYYY\tset value for output number x, value YYYY hexadecimal\n");
293 printf("KYY\tset value for mask, value YY hexadecimal\n");
296 allow_direct_wd_refresh = 0;
299 void print_short_status() {
300 allow_direct_wd_refresh = 1;
302 allow_direct_wd_refresh = 0;
305 void set_led_living(int state) {
307 DEB_LED_ON(LED_LIVING);
309 DEB_LED_OFF(LED_LIVING);
314 * 50Hz timer ... to be short as possible
316 void timer_middle_interval(void) {
317 if(heli_mode == HELI_MODE_INIT) {
318 //During the startup time blink the LED rapidly
319 if((timer_1s % 5) > 2) {
325 //After startup time blink the LED slowly
333 if(timer_led_can0 > 0) {
334 DEB_LED_ON(LED_CAN0);
336 if(timer_led_can0==0) DEB_LED_OFF(LED_CAN0);
339 if(timer_led_can1 > 0) {
340 DEB_LED_ON(LED_CAN1);
342 if(timer_led_can1==0) DEB_LED_OFF(LED_CAN1);
349 start_AD_conversion();
351 allow_direct_wd_refresh = 1;
352 if(debug_main_prog) debug_main();
353 //servo_debug_fast();
354 if(debug_servos) servo_debug_visual();
355 if(debug_CAN) debug_out_CAN();
356 if(debug_voltages) debug_AD_convertion();
359 send_temp_message_CAN0();
360 send_temp_message_CAN1();
362 allow_direct_wd_refresh = 0;
365 if(time_after_start < MAXTIME) time_after_start++;
366 if(time_after_start < STARTUP_TIME) {
367 heli_mode = HELI_MODE_INIT;
369 heli_mode = HELI_MODE_RUN;
374 void init_AD_converter(void) {
375 *SYS_MSTPCRA &= ~MSTPCRA_MSTPA1m; //Switch the AD module ON
377 excptvec_set(28,int_AD_convert);
379 *AD_ADCSR |= ADCSR_SCANm; //Set to SCAN MODE
380 *AD_ADCSR &= ~ADCSR_ADFm; //Clear INTERRUPT FLAG
381 *AD_ADCSR |= ADCSR_ADIEm; //Set the INTERRUPT MASK
383 //Set the channels AN0 to AN4
384 *AD_ADCSR &= ~ADCSR_CH3m;*AD_ADCSR &= ~ADCSR_CH2m;*AD_ADCSR |= ADCSR_CH1m; *AD_ADCSR |= ADCSR_CH0m;
386 //Set the LOWEST CONVERSION SPEED
387 *AD_ADCR &= ~ADCR_CKS0m;*AD_ADCR &= ~ADCR_CKS1m;
389 //Trigger the convertion by software
390 *AD_ADCR &= ~ADCR_TRGS0m;*AD_ADCR &= ~ADCR_TRGS1m;
392 //Now the AD converter should be prepared
396 void start_AD_conversion(void) {
397 *AD_ADCSR |= ADCSR_ADSTm;
400 void debug_AD_convertion(void) {
401 printf("AD:ints:%d,",count_AD);
402 printf("VAL:%02X%02X,%02X%02X,%02X%02X,%02X%02X\n", *AD_ADDRAH,*AD_ADDRAL,*AD_ADDRBH,*AD_ADDRBL,*AD_ADDRCH,*AD_ADDRCL,*AD_ADDRDH,*AD_ADDRDL);
403 printf("val:%4X,%4X,%4X,%4X\n",ad0,ad1,ad2,ad3);
404 printf("val:%4d,%4d,%4d,%4d\n",ad0_val,ad1_val,ad2_val,ad3_val);
408 * AD convertion finished interrupt
410 void int_AD_convert(void) {
411 unsigned int ad0_temp,ad1_temp;
414 *AD_ADCSR &= ~ADCSR_ADFm; //Clear INTERRUPT FLAG
417 ad0 = (((*AD_ADDRAH) << 8) + *AD_ADDRAL);
418 ad1 = (((*AD_ADDRBH) << 8) + *AD_ADDRBL);
419 ad2 = (((*AD_ADDRCH) << 8) + *AD_ADDRCL);
420 ad3 = (((*AD_ADDRDH) << 8) + *AD_ADDRDL);
422 ad0_temp = (ad0 >> 6) & 0x03FF;ad1_temp = (ad1 >> 6) & 0x03FF; ad2_val = (ad2 >> 6) & 0x03FF; ad3_val = (ad3 >> 6) & 0x03FF;
423 ad0_val = (ad0_temp * ad0_mul) >> ad0_shiftr;
424 ad1_val = (ad1_temp * ad1_mul) >> ad1_shiftr;
425 *AD_ADCSR &= ~ADCSR_ADSTm;
429 void watchdog_refresh(void) {
430 //Complement Watchdog
431 *DIO_PCDR ^= PCDR_PC7DRm;