1 //*****************************************************************************
 2 // testmain.c
 3 // this file controls the transmit and receive over usart
 4 // author: chris madormo
 5 //*****************************************************************************
 6 
 7 
 8 //*****************************************************************************
 9 // includes
10 //*****************************************************************************
11 // required includes
12 #include <hidef.h>         /* common defines and macros */
13 #include <mc9s12e128.h>    /* derivative information */
14 #include <S12e128bits.h>   /* bit definitions  */
15 #include <Bin_Const.h>     /* macros to allow specifying binary constants */
16 #include <termio.h>        /* to get prototype for kbhit() */
17 #include "S12eVec.h"
18 
19 // other includes
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <ads12.h>
23 #include "controller_sensors.h"
24 #include "luc_state_machine.h"
25 #include "controller_actuators.h"
26 #include "TestMain.h"
27 //*****************************************************************************
28 
29 
30 //*****************************************************************************
31 // definitions
32 //*****************************************************************************
33 
34 // timing constants
35 #define _MS_               *188
36 #define PERIOD             (200 _MS_)
37 #define PERIOD5            (250 _MS_)
38 #define PERIOD6            (20 _MS_)
39 #define baud_var           156
40 #define timeout            4
41 
42 // api identifiers
43 #define transmit_request   0x01
44 #define transmit_status    0x89
45 #define receive_packet     0x81
46 
47 // packet definitions
48 #define necromancer_packet 0x01
49 #define command_packet     0x02
50 #define handshake_packet   0x03
51 #define hzv_ack_packet     0x04
52 
53 // packet constants
54 #define start_delimiter    0x7E
55 #define frame_id           0x01
56 #define dest_add_msb       0x21
57 #define dont_send_ack      0x00
58 #define send_ack           0x01
59 #define packet_options     0x01
60 #define handshake_message  0xED
61 #define data_custom_1      0x00
62 #define data_custom_2      0x00
63 #define data_custom_3      0x00
64 
65 // other constants
66 #define message_incoming   (SCI1SR1 & _S12_RDRF)
67 #define max_buffer_length  15
68 //*****************************************************************************
69 
70 
71 //*****************************************************************************
72 // module variables
73 //*****************************************************************************
74 
75 // buffers
76 static char transmit_buffer[max_buffer_length];
77 static unsigned char receive_buffer[max_buffer_length];
78 
79 // tx/rx counters
80 static unsigned char transmit_count;
81 static unsigned char receive_count;
82 static unsigned char transmit_length;
83 static unsigned char receive_length;
84 
85 static unsigned char transmit_checksum;
86 static unsigned char receive_checksum;
87 
88 // state machine variables
89 static unsigned char transmit_in_progress;
90 static unsigned char ready_to_transmit;
91 static unsigned char ready_to_package;
92 static unsigned char receive_in_progress;
93 static unsigned char ready_to_decode;
94 static unsigned char next_transmit_ready;
95 static unsigned char last_message_received;
96 static unsigned char last_message_received;
97 static unsigned char xbee_connected;
98 
99 // controller data
100 static char data_speed;
101 static char data_direction;
102 static char data_action;
103 
104 // destination address
105 static unsigned char source_addr_msb;
106 static unsigned char source_addr_lsb;
107 static unsigned char boat_address;
108 
109 // timer data
110 static unsigned char num_overflows
111 static unsigned char sound_overflows;
112 static unsigned char controller_timeout;
113 //*****************************************************************************
114 
115 
116 //*****************************************************************************
117 // function prototypes
118 //*****************************************************************************
119 static void init_sci(void);
120 static void init_pins(void);
121 static void receive_message(void);
122 static void setup_handshake_packet(void);
123 static void setup_command_packet(void);
124 static void finalize_packet(void);
125 static unsigned char find_checksum(void);
126 static void decode_packet(void);
127 static void reset_timeout(unsigned char message_received);
128 //*****************************************************************************
129 
130 
131 //*****************************************************************************
132 // helper functions
133 //*****************************************************************************
134 
135 // initialize the sci
136 static void init_sci(void)
137 {
138     // set baud rate
139     SCI1BDH = 0;
140     SCI1BDL = baud_var;      // baud rate = 9600
141 
142     // enable transmit and receive
143     SCI1CR2 |= _S12_RE;	   //enable receive
144     SCI1CR2 |= _S12_TE;     //enable transmit
145 }
146 
147 
148 // initialize the e128 pins
149 static void init_pins(void)
150 {
151     // initialize port AD 0,1,2 as inputs
152     if (ADS12_Init("OOOOOAAA") == ADS12_OK) puts("ADS Initialized here \n\r");
153 
154     // initialize port T0-4 as outputs, T5-7 as inputs
155     DDRT = 0x1F;
156 
157     // initialize port U
158     DDRU = 0xFF;      // port U all outputs
159     PTU = 0x03;       // default light and audio off
160 
161     // initialize port S as inputs
162     DDRS = 0x00;
163 
164     // turn led dislay off
165     setLEDDisplay(OFF);
166 }
167 
168 
169 // init timer
170 static void init_timer(void)
171 {
172     TIM0_TSCR1 = _S12_TEN;                             // turn the timer system on
173     TIM0_TSCR2 = (_S12_PR2 | _S12_PR1 | _S12_PR0);     // set pre-scale to /128 = 0.1875MHz timer clk
174 
175     // Set up TIM0 OC4 to time updates
176     TIM0_TIOS |= _S12_IOS4;                             // set cap/comp 4 to output compare rest are inputs
177     TIM0_TCTL1|= TIM0_TCTL1 & ~(_S12_OL4 |_S12_OM4);    // no pin connected for OC4
178     TIM0_TC4 = TIM0_TCNT + PERIOD;                     // schedule first rise
179     TIM0_TFLG1 |= _S12_C4F;                             // clear OC4 flag
180     TIM0_TIE |= _S12_C4I;                              // enable OC4 interrupt
181 
182 
183     // Set up TIM0 OC5 to time updates
184     TIM0_TIOS |= _S12_IOS5;                             // set cap/comp 5 to output compare rest are inputs
185     TIM0_TCTL1|= TIM0_TCTL1 & ~(_S12_OL5 |_S12_OM5);    // no pin connected for OC53
186     TIM0_TC5 = TIM0_TCNT + PERIOD5;                     // schedule first rise
187     TIM0_TFLG1 |= _S12_C5F;                             // clear OC5 flag
188     TIM0_TIE |= _S12_C5I;                              // enable OC5 interrupt
189 
190     // Set up TIM0 OC6 to time updates
191     TIM0_TIOS |= _S12_IOS6;                             // set cap/comp 6 to output compare rest are inputs
192     TIM0_TCTL1|= TIM0_TCTL1 & ~(_S12_OL6 |_S12_OM6);    // no pin connected for OC63
193     TIM0_TC6 = TIM0_TCNT + PERIOD6;                     // schedule first rise
194     TIM0_TFLG1 |= _S12_C6F;                             // clear OC6 flag
195     TIM0_TIE |= _S12_C6I;                              // enable OC6 interrupt
196 
197     // initialize variables
198     next_transmit_ready = 1;
199     num_overflows = 0;                                 // used for the 1 sec hzv timeou
200     sound_overflows = 0;                               // initialize sound timer to be 0
201     controller_timeout = 0;
202 
203     // enable interrupts
204     EnableInterrupts;
205 }
206 
207 
208 // code to transmit byte
209 static void transmit(void)
210 {
211 
212     if (transmit_count == transmit_length+3)
213         {
214             // make sure transmit buffer empty
215             if ((SCI1SR1 & _S12_TDRE) !=0)
216                 {
217                     // make sure receive not in progress
218                     if ((SCI1SR2 & _S12_RAF) == 0)
219                         {
220                             SCI1DRL = transmit_checksum;
221                             transmit_in_progress = 0;
222                         }
223                 }
224         }
225     else
226         {
227             // make sure transmit buffer empty
228             if ((SCI1SR1 & _S12_TDRE) !=0)
229                 {
230                     // make sure receive not in progress
231                     if ((SCI1SR2 & _S12_RAF) == 0)
232                         {
233 
234                             SCI1DRL = transmit_buffer[transmit_count];
235                             transmit_count++;
236                         }
237                 }
238         }
239 }
240 
241 
242 // code to receive incoming message
243 static void receive_message(void)
244 {
245 
246     // read in receive data to buffer
247     receive_buffer[receive_count] = SCI1DRL;
248 
249     // determine place in receive packet
250     if (receive_count == 0)
251         {
252             if (receive_buffer[receive_count] == start_delimiter)
253                 {
254                     // reset receive checksum
255                     receive_checksum = 0;
256                     // increment count
257                     receive_count++;
258                 }
259         }
260     else if (receive_count == 1)
261         {
262             if (receive_buffer[receive_count] == 0x00)
263                 {
264                     // increment count
265                     receive_count++;
266                 }
267             else receive_count = 0;
268         }
269     else if (receive_count == 2)
270         {
271             // set receive length
272             receive_length = receive_buffer[receive_count];
273             // increment count
274             receive_count++;
275         }
276     else if (receive_count < receive_length+3)
277         {
278             // update receive checksum
279             receive_checksum += receive_buffer[receive_count];
280             // increment count
281             receive_count++;
282         }
283     else if (receive_count == receive_length+3)
284         {
285 
286             receive_checksum += receive_buffer[receive_count];
287 
288             // confirm checksum
289             if (receive_checksum == 0xFF)
290                 {
291                     ready_to_decode = 1;
292                 }
293 
294             // update counter
295             receive_count = 0;
296         }
297 }
298 
299 
300 // set up handshake packet
301 static void setup_handshake_packet(void)
302 {
303 
304     // fill in transmit buffer
305     transmit_buffer[3]  = transmit_request;      // 0x01
306     transmit_buffer[4]  = send_ack;              // 0x01
307     transmit_buffer[5]  = dest_add_msb;          // 0x21
308     transmit_buffer[6]  = boat_address;
309     transmit_buffer[7]  = packet_options;        // 0x00
310     transmit_buffer[8]  = handshake_packet;      // 0x03
311     transmit_buffer[9]  = handshake_message;     // 0xED
312 
313     // set up variables
314     transmit_length = 7;
315     transmit_checksum = find_checksum();
316 }
317 
318 
319 // set up command packet
320 static void setup_command_packet(void)
321 {
322 
323     // set up temp sensor values
324     data_speed = get_throttle();
325     data_direction = get_direction();
326     data_action = get_shoot();
327 
328     // fill in transmit buffer
329     transmit_buffer[3]   = transmit_request;      // 0x01
330     transmit_buffer[4]   = dont_send_ack;         // 0x00
331     transmit_buffer[5]   = dest_add_msb;          // 0x21
332     transmit_buffer[6]   = boat_address;
333     transmit_buffer[7]   = packet_options;        // 0x00
334     transmit_buffer[8]   = command_packet;        // 0x02
335     transmit_buffer[9]   = data_speed;
336     transmit_buffer[10]  = data_direction;
337     transmit_buffer[11]  = data_action;
338     transmit_buffer[12]  = data_custom_1;         // 0x00
339     transmit_buffer[13]  = data_custom_2;         // 0x00
340     transmit_buffer[14]  = data_custom_3;         // 0x00
341 
342     // set up variables
343     transmit_length = 12;
344     transmit_checksum = find_checksum();
345 }
346 
347 
348 // finalize packet
349 static void finalize_packet(void)
350 {
351     // fill in standard packet info
352     transmit_buffer[0] = start_delimiter;
353     transmit_buffer[1] = 0x00;
354     transmit_buffer[2] = transmit_length;
355     transmit_buffer[transmit_length+3] = transmit_checksum;
356 }
357 
358 
359 // calculate transmit checksum
360 static unsigned char find_checksum(void)
361 {
362     //add up all data bytes
363     int i;
364     unsigned char total = 0;
365 
366     for (i=3; i<transmit_length+3; i++)
367         {
368             total += transmit_buffer[i];
369         }
370     total = 0xFF - total;
371     return total;
372 }
373 
374 
375 // decode packet
376 static void decode_packet(void)
377 {
378     unsigned char api_identifier;
379     unsigned char message_identifier;
380 
381     // read in api identifier
382     api_identifier = receive_buffer[3];
383 
384     // determine what type of packet was received
385     switch (api_identifier)
386         {
387         case (transmit_status):
388             switch (receive_buffer[5])
389                 {
390                 case (0):
391                     //printf("message acknowledged\r\n");
392                     break;
393                 case (1):
394                     //printf("no ack received\r\n");
395                     last_message_received = 1;
396                     break;
397                 case (2):
398                     //printf("cca failure\r\n");
399                     break;
400                 case (3):
401                     //printf("purged\r\n");
402                     break;
403                 default:
404                     break;
405                 }
406             break;
407         case (receive_packet):
408 
409             // mark message as received
410             last_message_received = 1;
411 
412             // store data
413             source_addr_msb = receive_buffer[4];
414             source_addr_lsb = receive_buffer[5];
415             message_identifier = receive_buffer[8];
416 
417             // determine what type of message was received
418             switch (message_identifier)
419                 {
420                 case (necromancer_packet):
421                     // ignore
422                     break;
423                 case (command_packet):
424                     // ignore
425                     break;
426                 case (handshake_packet):
427                     // confirm handshake came from intended recipient
428                     if ( (source_addr_msb == dest_add_msb) && (source_addr_lsb == boat_address) )
429                         {
430                             // confirm correct handshake message was sent
431                             if (receive_buffer[9] == 0xCD)
432                                 {
433 
434                                     // reset timeout timer
435                                     reset_timeout(handshake_packet);
436 
437                                     // update state machine
438                                     call_luc_sm(handshake_received);
439 
440                                     // light up leds
441                                     turn_on_leds();
442 
443                                     // turn on audio
444                                     turn_on_audio();
445                                 }
446                             else
447                                 {
448                                     //printf("bad handshake\r\n");
449                                 }
450                         }
451                     else
452                         {
453                             //printf("wrong hand\r\n");
454                         }
455                     break;
456                 case (hzv_ack_packet):
457                     if ( (source_addr_msb == dest_add_msb) && (source_addr_lsb == boat_address) )
458                         {
459                             // reset timer
460                             reset_timeout(hzv_ack_packet);
461                         }
462                     else
463                         {
464                             printf("ignoring, wrong sender\r\n");
465                         }
466                     break;
467                 default:
468                     printf("got something wrong\r\n");
469                     break;
470                 }
471 
472             break;
473         default:
474             printf("got something else\r\n");
475             break;
476         }
477 }
478 
479 
480 // reset timeout
481 static void reset_timeout(unsigned char message_received)
482 {
483     switch (message_received)
484         {
485         case (handshake_packet):
486             // only accept handshake if handshake was requested
487             if (is_handshake_requested())
488                 {
489                     // reset timer
490                     TIM0_TC5 += PERIOD;      // program next compare
491                     num_overflows = 0;       // reset num overflows
492                 }
493             break;
494         case (hzv_ack_packet):
495             // only accept ack packet if connected
496             if (is_luc_connected())
497                 {
498                     // reset timer
499                     TIM0_TC5 += PERIOD;      // program next compare
500                     num_overflows = 0;       // reset num overflows
501                 }
502             break;
503         default:
504             break;
505         }
506 
507 }
508 
509 
510 // This timer starts the sound_overflow counter
511 void init_sound_timer(void)
512 {
513     sound_overflows = 0;
514 }
515 //*****************************************************************************
516 
517 
518 //*****************************************************************************
519 // interrupts
520 //*****************************************************************************
521 
522 // 200 ms message rate interrupt
523 void interrupt _Vec_tim0ch4 timer_0_ch_4(void)
524 {
525     TIM0_TFLG1 |= _S12_C4F;   // clear OC4 flag
526     TIM0_TC4 += PERIOD;      // program next compare
527     next_transmit_ready = 1;
528 
529     // do timer overflows
530     sound_overflows++;
531 
532     if (sound_overflows == 6)
533         {
534             PTU |= BIT1HI;
535         }
536 }
537 
538 // 1 sec timeout interrupt
539 void interrupt _Vec_tim0ch5 timer_0_ch_5(void)
540 {
541     TIM0_TFLG1 |= _S12_C5F;   // clear OC5 flag
542     TIM0_TC5 += PERIOD5;      // program next compare
543 
544     // timeout code
545     if (is_timeout_enabled())
546         {
547             num_overflows++;
548         }
549     else
550         {
551             num_overflows = 0;
552         }
553 }
554 
555 // 20 ms analog sensor update
556 void interrupt _Vec_tim0ch6 timer_0_ch_6(void)
557 {
558     TIM0_TFLG1 |= _S12_C6F;   // clear OC6 flag
559     TIM0_TC6 += PERIOD6;      // program next compare
560 }
561 //*****************************************************************************
562 
563 
564 //*****************************************************************************
565 // main
566 //*****************************************************************************
567 void main(void)
568 {
569 
570     // init pins
571     init_pins();
572 
573     // init sci
574     init_sci();
575 
576     // init timer
577     init_timer();
578 
579     // init states
580     transmit_in_progress = 0;
581     ready_to_transmit = 0;
582     ready_to_package = 0;
583     receive_in_progress = 0;
584     transmit_count = 0;
585     receive_count = 0;
586     ready_to_decode = 0;
587     xbee_connected = 0;
588     last_message_received = 1;
589 
590     // main loop
591     while (1)
592         {
593             // check if message incoming
594             if (message_incoming)
595                 {
596                     receive_message();
597                 }
598 
599             // check if timeout occurred
600             if (num_overflows > timeout)
601                 {
602                     // turn off leds
603                     turn_off_leds();
604 
605                     // turn off audio
606                     turn_off_audio();
607 
608                     // update state machine
609                     call_luc_sm(hzv_timeout);
610                     //controller_timeout = 0;
611                     num_overflows = 0;
612 
613                     // reset last transmit received
614                     last_message_received = 1;
615                 }
616 
617             // check if handshake requested
618             if (isButtonPressed())
619                 {
620                     // update state machine
621                     call_luc_sm(handshake_requested);
622                 }
623 
624             // check if transmit is in progress
625             if (transmit_in_progress)
626                 {
627                     // transmit
628                     transmit();
629 
630                     // update variables
631                     last_message_received = 0;
632                 }
633 
634             // check if ready to transmit
635             if (ready_to_transmit)
636                 {
637                     // set up transmit
638                     transmit_count = 0;
639                     ready_to_transmit = 0;
640                     transmit_in_progress = 1;
641                 }
642 
643             // check if ready to package
644             if (ready_to_package)
645                 {
646                     // package
647                     finalize_packet();
648 
649                     // update state
650                     ready_to_package = 0;
651                     ready_to_transmit = 1;
652                 }
653 
654             // update boat address
655             get_boat_address();
656 
657             // check if ready to transmit next message
658             if (last_message_received)
659                 {
660                     if (next_transmit_ready)
661                         {
662                             if (is_handshake_requested())
663                                 {
664                                     // check boat requested
665                                     boat_address = get_boat_address();
666                                     if (boat_address != 100)
667                                         {
668                                             // set up handshake packet
669                                             setup_handshake_packet();
670                                             ready_to_package = 1;
671                                             next_transmit_ready = 0;
672                                         }
673                                 }
674                             else if (is_luc_connected())
675                                 {
676                                     // set up command packet
677                                     setup_command_packet();
678                                     ready_to_package = 1;
679                                     next_transmit_ready = 0;
680                                 }
681                             else
682                                 {
683                                     // keep waiting
684                                 }
685                         }
686                 }
687 
688             // check if ready to decode received message
689             if (ready_to_decode)
690                 {
691                     decode_packet();
692                     ready_to_decode = 0;
693                 }
694 
695         }
696 
697 }