is_was_0.6_0.7-Gulper
Produced: 8/16/2007 12:41:52 PM
   
Mode:  All Lines  
Left base folder: \\Tornado\ProjectLibrary\900403_AUV_GULPER\Software\SDF\Releases\EX_0.7  
Right base folder: \\Tornado\ProjectLibrary\900403_AUV_GULPER\Software\SDF\Releases\EX_0.6  
   
File: Gulper_Main.c  
1 /****************************************************************************/ = 1 /****************************************************************************/
2 /* Copyright 2005 MBARI.                                                    */   2 /* Copyright 2005 MBARI.                                                    */
3 /* Monterey Bay Aquarium Research Institute Proprietary Information.        */   3 /* Monterey Bay Aquarium Research Institute Proprietary Information.        */
4 /* All rights reserved.                                                     */   4 /* All rights reserved.                                                     */
5 /****************************************************************************/   5 /****************************************************************************/
6 #include <16f876A.h>   6 #include <16f876A.h>
7     7  
8 #include <string.h>   8 #include <string.h>
9 #include <stdlib.h>   9 #include <stdlib.h>
10 #include <stdio.h>   10 #include <stdio.h>
11     11  
12 #use delay(clock=4000000, restart_wdt)   12 #use delay(clock=4000000, restart_wdt)
13 #include "Gulper_Main.h"   13 #include "Gulper_Main.h"
14 #include "RS485.c"   14 #include "RS485.c"
15 #include "Command_Handler.c"   15 #include "Command_Handler.c"
16     16  
17     17  
18 #if DEBUG   18 #if DEBUG
19 #device ICD=TRUE   19 #device ICD=TRUE
20 #fuses XT,WDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP   20 #fuses XT,WDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
21 #else   21 #else
22 #fuses XT,WDT,NOPROTECT,PUT,NOLVP   22 #fuses XT,WDT,NOPROTECT,PUT,NOLVP
23 #endif   23 #endif
24     24  
25 //#define  RS485_RX_BUFFER_SIZE 64   25 //#define  RS485_RX_BUFFER_SIZE 64
26 #define  RS485_USE_EXT_INT    FALSE   26 #define  RS485_USE_EXT_INT    FALSE
27     27  
28     28  
29 int8 in_char = 0;   29 int8 in_char = 0;
30 int8 next_in = 0;   30 int8 next_in = 0;
31 int8 next_out = 0;   31 int8 next_out = 0;
32 int8 *command;   32 int8 *command;
33 int8 data[1];   33 int8 data[1];
34 Boolean uart_TX = false;       // Used for BIT uart checking   34 Boolean uart_TX = false;       // Used for BIT uart checking
35     35  
36 #define INTS_PER_SECOND 15     // (20000000/(4*256*256))   36 #define INTS_PER_SECOND 15     // (20000000/(4*256*256))
37 #define T2_INTS_PER_SECOND 98  // 1/( (1/4000000) * 4 * 4 * 255 * 10   )   37 #define T2_INTS_PER_SECOND 98  // 1/( (1/4000000) * 4 * 4 * 255 * 10   )
38     38  
39     39  
40 #INT_TIMER1                        // This function is called every time   40 #INT_TIMER1                        // This function is called every time
41 void clock_isr() {                 // timer 1 overflows (65535->0), which is   41 void clock_isr() {                 // timer 1 overflows (65535->0), which is
42                                    // approximately 15 times per second for   42                                    // approximately 15 times per second for
43     if(--int_count==0) {           // this program.   43     if(--int_count==0) {           // this program.
44       ++seconds;   44       ++seconds;
45       int_count = INTS_PER_SECOND;   45       int_count = INTS_PER_SECOND;
46     }   46     }
47 }   47 }
48     48  
49 #INT_TIMER2                        // This function is called every time   49 #INT_TIMER2                        // This function is called every time
50 void timer_2_isr() {               // timer 2 overflows, which is   50 void timer_2_isr() {               // timer 2 overflows, which is
51                                    // approximately 98 times per second   51                                    // approximately 98 times per second
52     if(--T2_int_count==0) {             52     if(--T2_int_count==0) {          
53       ++T2_seconds;   53       ++T2_seconds;
54       T2_int_count = T2_INTS_PER_SECOND;   54       T2_int_count = T2_INTS_PER_SECOND;
55     }   55     }
56 }   56 }
57     57  
58 // Purpose: Clears elapsed time to "start" the clock   58 // Purpose: Clears elapsed time to "start" the clock
59 void startTimer(void)   59 void startTimer(void)
60 {   60 {
61   disable_interrupts(INT_TIMER1);   61   disable_interrupts(INT_TIMER1);
62     seconds=0;   62     seconds=0;
63     int_count=INTS_PER_SECOND;   63     int_count=INTS_PER_SECOND;
64     enable_interrupts(INT_TIMER1);                64     enable_interrupts(INT_TIMER1);             
65 }   65 }
66     66  
67 // Purpose: Stores elapsed time   67 // Purpose: Stores elapsed time
68 void getElapsedTime(void)   68 void getElapsedTime(void)
69 {   69 {
70     disable_interrupts(INT_TIMER1);   70     disable_interrupts(INT_TIMER1);
71     ElapsedSeconds=seconds;   71     ElapsedSeconds=seconds;
72     Elapsed_int_count=INTS_PER_SECOND-int_count; // Number of interrupts since the last second, there are 15 per sec   72     Elapsed_int_count=INTS_PER_SECOND-int_count; // Number of interrupts since the last second, there are 15 per sec
73     enable_interrupts(INT_TIMER1);   73     enable_interrupts(INT_TIMER1);
74 }   74 }
75     75  
76 // Purpose: Clears elapsed time to "start" the clock for Timer 2   76 // Purpose: Clears elapsed time to "start" the clock for Timer 2
77 void T2_startTimer(void)   77 void T2_startTimer(void)
78 {   78 {
79   disable_interrupts(INT_TIMER2);   79   disable_interrupts(INT_TIMER2);
80     T2_seconds=0;   80     T2_seconds=0;
81     T2_int_count=T2_INTS_PER_SECOND;   81     T2_int_count=T2_INTS_PER_SECOND;
82     enable_interrupts(INT_TIMER2);                82     enable_interrupts(INT_TIMER2);             
83 }   83 }
84     84  
85 // Purpose: Stores elapsed time from Timer 2   85 // Purpose: Stores elapsed time from Timer 2
86 void T2_getElapsedTime(void)   86 void T2_getElapsedTime(void)
87 {   87 {
88     disable_interrupts(INT_TIMER2);   88     disable_interrupts(INT_TIMER2);
89     T2_ElapsedSeconds=T2_seconds;   89     T2_ElapsedSeconds=T2_seconds;
90     T2_Elapsed_int_count=T2_INTS_PER_SECOND-T2_int_count; // Number of interrupts since the last second   90     T2_Elapsed_int_count=T2_INTS_PER_SECOND-T2_int_count; // Number of interrupts since the last second
91     enable_interrupts(INT_TIMER2);   91     enable_interrupts(INT_TIMER2);
92 }   92 }
93     93  
94     94  
95 // Purpose: Interrupt service routine for handling incoming proximity sensor.   95 // Purpose: Interrupt service routine for handling incoming proximity sensor.
96 #INT_EXT   96 #INT_EXT
97 void proximity_isr() {   97 void proximity_isr() {
98   //Only service proximity sensor after firing has been commanded   98   //Only service proximity sensor after firing has been commanded
99   //and only if proximity has not expired   99   //and only if proximity has not expired
100   if((Fired) && (!proximity) && (!proximity_expired)) {   100   if((Fired) && (!proximity) && (!proximity_expired)) {
101     getElapsedTime();   101     getElapsedTime();
102     <>    
103     // This if statement is a hack to avoid a false trigger when the pin puller is activated      
104     // The time is checked to see if either a second has already elapsed or if more than 200 msec      
105     // have gone by. Then it can be assumed that it's a real trigger      
106     if( (ElapsedSeconds > 0) || ( (Elapsed_int_count * 66.6666) > 200) ) {      
107       output_bit(PIN_B4, HI); // Turn on proximity LED   102     output_bit(PIN_B4, HI); // Turn on proximity LED
108       proximity = true;   103     proximity = true;
109     }      
110   } = 104   }
111   //Otherwise, check for a misfire assuming that prox timeout has not expired   105   //Otherwise, check for a misfire assuming that prox timeout has not expired
112   else if ( (!Fired) && (!prox_error) && (!proximity_expired) ) {   106   else if ( (!Fired) && (!prox_error) && (!proximity_expired) ) {
113     prox_error = true;   107     prox_error = true;
114   }   108   }
115       109    
116 }   110 }
117     111  
118 // Purpose: Holds software in infinite loop to allow watchdog to reset   112 // Purpose: Holds software in infinite loop to allow watchdog to reset
119 void software_reset() {   113 void software_reset() {
120   for(;;) {   114   for(;;) {
121     null;   115     null;
122   }   116   }
123 }   117 }
124     118  
125 // Purpose: The built in test executive procedure   119 // Purpose: The built in test executive procedure
126 void BIT_Exec() {   120 void BIT_Exec() {
127     // Check for a UART held in TX mode for more than 2 sec   121     // Check for a UART held in TX mode for more than 2 sec
128   if( (input(PIN_B5)) && (!uart_TX) ) {   122   if( (input(PIN_B5)) && (!uart_TX) ) {
129     T2_startTimer();   123     T2_startTimer();
130     uart_TX = true;   124     uart_TX = true;
131   }   125   }
132   else if( (input(PIN_B5)) && (uart_TX) ) {   126   else if( (input(PIN_B5)) && (uart_TX) ) {
133     T2_getElapsedTime();   127     T2_getElapsedTime();
134     if(T2_ElapsedSeconds >= 2) {   128     if(T2_ElapsedSeconds >= 2) {
135       software_reset(); // Call reset and wait for watchdog timer to expire   129       software_reset(); // Call reset and wait for watchdog timer to expire
136     }     130     }  
137   }   131   }
138   else {   132   else {
139     uart_TX = false;   133     uart_TX = false;
140   }         134   }      
141 }   135 }
142     136  
143     137  
144 //   138 //
145 // Main execution loop   139 // Main execution loop
146 //   140 //
147 main()   141 main()
148 {   142 {
149     143  
150   // Change edge definition for prox sensor interrupt   144   // Change edge definition for prox sensor interrupt
151   EXT_INT_EDGE(H_TO_L);    145   EXT_INT_EDGE(H_TO_L); 
152     146  
153   // Set up the system clocks   147   // Set up the system clocks
154   int_count=INTS_PER_SECOND;   148   int_count=INTS_PER_SECOND;
155   T2_int_count=T2_INTS_PER_SECOND;   149   T2_int_count=T2_INTS_PER_SECOND;
156   setup_wdt(WDT_288MS); // Initialize the watchdog. See fuses WDT also   150   setup_wdt(WDT_288MS); // Initialize the watchdog. See fuses WDT also
157     151  
158   //Using timer 1 for proximity timing so as not to interfere with WDT/RTC/Timer0   152   //Using timer 1 for proximity timing so as not to interfere with WDT/RTC/Timer0
159   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   153   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
160     154  
161   //Using timer 2 for BIT and actuation voltage timing   155   //Using timer 2 for BIT and actuation voltage timing
162   setup_timer_2(T2_DIV_BY_4, 0xFF, 10);     156   setup_timer_2(T2_DIV_BY_4, 0xFF, 10);  
163     157  
164   // Initialize Serial and enable interrupts   158   // Initialize Serial and enable interrupts
165   rs485_init();   159   rs485_init();
166   enable_interrupts(INT_EXT);   160   enable_interrupts(INT_EXT);
167   enable_interrupts(INT_TIMER1);   161   enable_interrupts(INT_TIMER1);
168   enable_interrupts(INT_TIMER2);   162   enable_interrupts(INT_TIMER2);
169     163  
170   // Initialize Outputs   164   // Initialize Outputs
171   output_bit(PIN_C4, HI);   165   output_bit(PIN_C4, HI);
172     output_bit(PIN_C5, LO);   166     output_bit(PIN_C5, LO);
173   output_bit(PIN_B1, LO);   167   output_bit(PIN_B1, LO);
174   output_bit(PIN_B2, LO);   168   output_bit(PIN_B2, LO);
175   output_bit(PIN_B4, LO);   169   output_bit(PIN_B4, LO);
176     170  
177   // Set up analog input for AN0   171   // Set up analog input for AN0
178   setup_adc(ADC_CLOCK_INTERNAL);   172   setup_adc(ADC_CLOCK_INTERNAL);
179   setup_adc_ports(AN0);   173   setup_adc_ports(AN0);
180   set_adc_channel(0);   174   set_adc_channel(0);
181     175  
182   // Check for WDT reset and output error if necessary   176   // Check for WDT reset and output error if necessary
183   switch ( restart_cause() )   177   switch ( restart_cause() )
184   {   178   {
185     case WDT_TIMEOUT:   179     case WDT_TIMEOUT:
186     {   180     {
187       sprintf(response_message, "WDT\r\n");   181       sprintf(response_message, "WDT\r\n");
188       send_error_response(response_message);   182       send_error_response(response_message);
189       break;   183       break;
190     }   184     }
191     case NORMAL_POWER_UP:   185     case NORMAL_POWER_UP:
192     {   186     {
193       break;   187       break;
194     }   188     }
195   }   189   }
196     190  
197     // Send ID info via "blank" message   191     // Send ID info via "blank" message
198     // send_response fills in the address   192     // send_response fills in the address
199     // For DEBUG only   193     // For DEBUG only
200     //   194     //
201   //## sprintf(response_message, "\r\n");    195   //## sprintf(response_message, "\r\n"); 
202   //## send_response(response_message);   196   //## send_response(response_message);
203             197          
204     198  
205 /* Begin Loop */          199 /* Begin Loop */       
206     for(;;)   200     for(;;)
207         {   201         {
208           // strobe the dog   202           // strobe the dog
209           restart_wdt();   203           restart_wdt();
210           204        
211         if(rs485_get_new_message(RS485_ID, FALSE)) // Check for new command   205         if(rs485_get_new_message(RS485_ID, FALSE)) // Check for new command
212             {   206             {
213                 // Check to see which command was received...   207                 // Check to see which command was received...
214         if(!strcmp(cmd_InBuffer,fire)) {   208         if(!strcmp(cmd_InBuffer,fire)) {
215           handle_fire_command();   209           handle_fire_command();
216         }   210         }
217         else if(!strcmp(cmd_InBuffer,query))  {   211         else if(!strcmp(cmd_InBuffer,query))  {
218           handle_query_command();   212           handle_query_command();
219         }   213         }
220         else if(!strcmp(cmd_InBuffer,status))  {   214         else if(!strcmp(cmd_InBuffer,status))  {
221           handle_status_command();   215           handle_status_command();
222         }   216         }
223         else if(!strcmp(cmd_InBuffer,version))  {   217         else if(!strcmp(cmd_InBuffer,version))  {
224           handle_version_command();   218           handle_version_command();
225         }   219         }
226         else if(!strcmp(cmd_InBuffer,actuation))  {   220         else if(!strcmp(cmd_InBuffer,actuation))  {
227           handle_actuation_voltage_command();   221           handle_actuation_voltage_command();
228         }   222         }
229         else if(!strcmp(cmd_InBuffer,reset))  {   223         else if(!strcmp(cmd_InBuffer,reset))  {
230           software_reset();   224           software_reset();
231         }   225         }
232           226        
233         //...Or if the command is invalid   227         //...Or if the command is invalid
234         else {   228         else {
235           sprintf(response_message, "COMMAND ERROR\r\n");   229           sprintf(response_message, "COMMAND ERROR\r\n");
236           send_error_response(response_message);   230           send_error_response(response_message);
237         }   231         }
238             }   // Check for new command   232             }   // Check for new command
239     233  
240       234    
241     // If > 30 secs have elapsed and proximity ISR has not been called,   235     // If > 30 secs have elapsed and proximity ISR has not been called,
242     // report 0 for time elapsed   236     // report 0 for time elapsed
243     if( (Fired) && (!proximity) && (!proximity_expired) ) {   237     if( (Fired) && (!proximity) && (!proximity_expired) ) {
244       getElapsedTime();   238       getElapsedTime();
245       if(ElapsedSeconds >= 30) {   239       if(ElapsedSeconds >= 30) {
246         proximity_expired = true;   240         proximity_expired = true;
247       }    241       } 
248     }   242     }
249     243  
250     // Check actuation voltage for >= 2 volts.   244     // Check actuation voltage for >= 2 volts.
251     if( (Fired) && (!actuation_bool) && (!proximity_expired) ) {   245     if( (Fired) && (!actuation_bool) && (!proximity_expired) ) {
252       float adc_value_loc;   246       float adc_value_loc;
253       adc_value_loc = Read_ADC();   247       adc_value_loc = Read_ADC();
254         adc_value_loc = adc_value_loc / 256 * 5.00; // scale for 0-5 Volts   248         adc_value_loc = adc_value_loc / 256 * 5.00; // scale for 0-5 Volts
255     249  
256         if (adc_value_loc >= 2)   250         if (adc_value_loc >= 2)
257        {   251        {
258         T2_getElapsedTime();   252         T2_getElapsedTime();
259         Final_Actuation_Milliseconds = ( (T2_ElapsedSeconds * 1000) + (T2_Elapsed_int_count * 10.2040) );   253         Final_Actuation_Milliseconds = ( (T2_ElapsedSeconds * 1000) + (T2_Elapsed_int_count * 10.2040) );
260         actuation_bool = true;   254         actuation_bool = true;
261         pin_puller_retracted = true;   255         pin_puller_retracted = true;
262        }   256        }
263     }   257     }
264     258  
265     259  
266     // Finally, call BIT to do safety checks if we're not in the firing sequence   260     // Finally, call BIT to do safety checks if we're not in the firing sequence
267     if ( (!fired) || (proximity || proximity_expired) )   261     if ( (!fired) || (proximity || proximity_expired) )
268      {   262      {
269      // BIT_Exec();   263      // BIT_Exec();
270      }   264      }
271     265  
272   } // Main control loop   266   } // Main control loop
273           267        
274      268   
275     269  
276 }   270 }
   
File: Gulper_Main.h  
1 /****************************************************************************/ = 1 /****************************************************************************/
2 /* Copyright 2006 MBARI.                                                    */   2 /* Copyright 2006 MBARI.                                                    */
3 /* Monterey Bay Aquarium Research Institute Proprietary Information.        */   3 /* Monterey Bay Aquarium Research Institute Proprietary Information.        */
4 /* All rights reserved.                                                     */   4 /* All rights reserved.                                                     */
5 /****************************************************************************/   5 /****************************************************************************/
6 #ifndef PH_PROBE_H   6 #ifndef PH_PROBE_H
7 #define PH_PROBE_H   7 #define PH_PROBE_H
8     8  
9  #define VS_VERSION  "0.7" <> 9  #define VS_VERSION  "0.6"
10 #define DEBUG 0 = 10 #define DEBUG 0
11     11  
12     12  
13 int8 fire[]="F";   13 int8 fire[]="F";
14 int8 query[]="Q";   14 int8 query[]="Q";
15 int8 status[]= "S";   15 int8 status[]= "S";
16 int8 version[]="V";   16 int8 version[]="V";
17 int8 actuation[]="A";   17 int8 actuation[]="A";
18 int8 reset[]="R";   18 int8 reset[]="R";
19     19  
20 char response_message[20]; // String for storing node response back to MVC   20 char response_message[20]; // String for storing node response back to MVC
21     21  
22 int8 serial_delay_msec = 3; // delay for clocking 485 bits   22 int8 serial_delay_msec = 3; // delay for clocking 485 bits
23     23  
24 // Timing variable initialization   24 // Timing variable initialization
25 int32 seconds = 0;                      // A running seconds counter for timer 1   25 int32 seconds = 0;                      // A running seconds counter for timer 1
26 int32 T2_seconds = 0;                   // A running seconds counter for timer 2   26 int32 T2_seconds = 0;                   // A running seconds counter for timer 2
27 int8 int_count = 0;                     // Number of interrupts left before a second has elapsed on timer 1   27 int8 int_count = 0;                     // Number of interrupts left before a second has elapsed on timer 1
28 int8 T2_int_count = 0;                  // Number of interrupts left before a second has elapsed on timer 2   28 int8 T2_int_count = 0;                  // Number of interrupts left before a second has elapsed on timer 2
29 int32 ElapsedSeconds = 0;               // A running seconds counter for timer 1   29 int32 ElapsedSeconds = 0;               // A running seconds counter for timer 1
30 int32 T2_ElapsedSeconds = 0;            // A running seconds counter for timer 2   30 int32 T2_ElapsedSeconds = 0;            // A running seconds counter for timer 2
31 int8 Elapsed_int_count = 0;             // Number of interrupts elapsed for timer 1   31 int8 Elapsed_int_count = 0;             // Number of interrupts elapsed for timer 1
32 int8 T2_Elapsed_int_count = 0;          // Number of interrupts elapsed for timer 2   32 int8 T2_Elapsed_int_count = 0;          // Number of interrupts elapsed for timer 2
33 int32 Final_Proximity_Milliseconds = 0; // Used to store time between fire and proximity sensor   33 int32 Final_Proximity_Milliseconds = 0; // Used to store time between fire and proximity sensor
34 int32 Final_Actuation_Milliseconds = 0; // Used to store time between fire and pin puller voltage >= 2 volts   34 int32 Final_Actuation_Milliseconds = 0; // Used to store time between fire and pin puller voltage >= 2 volts
35     35  
36 // Booleans   36 // Booleans
37 Boolean Fired = false;                // Fire command received?   37 Boolean Fired = false;                // Fire command received?
38 Boolean proximity = false;            // Proximity sensor ISR called?   38 Boolean proximity = false;            // Proximity sensor ISR called?
39 Boolean prox_error = false;            // Proximity sensor triggered before firing?   39 Boolean prox_error = false;            // Proximity sensor triggered before firing?
40 Boolean actuation_bool = false;       // Actuation voltage above 2 volts?   40 Boolean actuation_bool = false;       // Actuation voltage above 2 volts?
41 Boolean proximity_expired = false;    // Set true at 30 seconds past firing if no prox interrupt received   41 Boolean proximity_expired = false;    // Set true at 30 seconds past firing if no prox interrupt received
42 Boolean bad_address = false;          // Address out of range?   42 Boolean bad_address = false;          // Address out of range?
43 Boolean bad_checksum = false;         // Incoming checksum error?   43 Boolean bad_checksum = false;         // Incoming checksum error?
44 Boolean pin_puller_retracted = false; // did the pin puller retract?   44 Boolean pin_puller_retracted = false; // did the pin puller retract?
45     45  
46     46  
47 /*   47 /*
48     The ticks per second is based on an 8-bit counter over flowing that   48     The ticks per second is based on an 8-bit counter over flowing that
49     is driven by a 4 Mhz ocsillator prescaled by 4 and postscaled by 64.   49     is driven by a 4 Mhz ocsillator prescaled by 4 and postscaled by 64.
50     50  
51     TICKS_PER_SEC = (OSC_CLK) / (PRESCALE) / (POSTSCALE) / (8_BIT_OVERFLOW)   51     TICKS_PER_SEC = (OSC_CLK) / (PRESCALE) / (POSTSCALE) / (8_BIT_OVERFLOW)
52                   = 4000000   /     4      /      64     /      256   52                   = 4000000   /     4      /      64     /      256
53                   = 61.0351   53                   = 61.0351
54 */   54 */
55 #define TICKS_PER_SEC   61   55 #define TICKS_PER_SEC   61
56     56  
57 #define HI  1   57 #define HI  1
58 #define LO  0   58 #define LO  0
59     59  
60 #define ON  1   60 #define ON  1
61 #define OFF 0   61 #define OFF 0
62     62  
63 void startTimer(void);   63 void startTimer(void);
64 void getElapsedTime(void);   64 void getElapsedTime(void);
65 void T2_startTimer(void);   65 void T2_startTimer(void);
66 void T2_getElapsedTime(void);   66 void T2_getElapsedTime(void);
67     67  
68 #endif   68 #endif