error.c

Go to the documentation of this file.
00001 
00019 #include <includes.h>
00020 
00021 #ifndef __VERSION_0_1__
00022 #warning RangerOS mismatch, expected v0.1. 
00023 #endif
00024 
00025 
00026 static volatile ERROR_BUFFER er_buffer; 
00027 static volatile ERROR_INFO* er_active; 
00028 static VOID_VOID_F er_transmit = voidvoid; 
00029 static INT_VOID_F er_get_timestamp = intvoid; 
00030 static BOARD_ID er_board_id; 
00031 static int er_is_init = 0; 
00032 static const int er_length = ((int)(ERROR_LAST_ID)/32)+1; 
00033 static volatile unsigned int er_flags[er_length]; 
00041 void error_init(VOID_VOID_F transmit_function, INT_VOID_F timestamp_function, BOARD_ID board_id)
00042 {
00043   er_buffer.first = 0;
00044   er_buffer.next = 0;
00045   er_buffer.overflows = 0;
00046   er_buffer.empty = 1;
00047   er_transmit = transmit_function;
00048   er_get_timestamp = timestamp_function;
00049   er_board_id = board_id;
00050   er_is_init = 1;
00051 }
00052 
00053 MUTEX er_mutex;
00060 void error_occurred(ERROR_ID error_code)
00061 {
00062   volatile int index, bit;
00063   if (er_is_init){//make sure error module has been initialized first
00064     volatile int index, bit;
00065     if (!mutex_check(&er_mutex)){
00066       mutex_lock(&er_mutex);
00067       index = (int)(error_code) / 32;
00068       bit = (int)(error_code) % 32;
00069       er_flags[index] |= (1<<bit);
00070    //   mcu_led_red_blink(100);
00071       mutex_unlock(&er_mutex);
00072     } else {
00073     }
00074   }
00075 }
00076 
00077 MUTEX er_irq_mutex;
00084 void error_occurred_irq(ERROR_ID error_code)
00085 {
00086   volatile int index, bit;
00087   if (er_is_init){//make sure error module has been initialized first
00088     if (!mutex_check(&er_irq_mutex)){
00089       mutex_lock(&er_irq_mutex);
00090       index = (int)(error_code) / 32;
00091       bit = (int)(error_code) % 32;
00092       er_flags[index] |= (1<<bit);
00093    //   mcu_led_red_blink(100);
00094       mutex_unlock(&er_irq_mutex);
00095     } else {
00096     }
00097   }
00098 }
00099 MUTEX er_fiq_mutex;
00106 void error_occurred_fiq(ERROR_ID error_code)
00107 {
00108   volatile int index, bit;
00109   if (er_is_init){ //make sure error module has been initialized first
00110     if (!mutex_check(&er_fiq_mutex)){
00111       mutex_lock(&er_fiq_mutex);
00112       index = (int)(error_code) / 32;
00113       bit = (int)(error_code) % 32;
00114       er_flags[index] |= (1<<bit);
00115    //   mcu_led_red_blink(100);
00116       mutex_unlock(&er_fiq_mutex);
00117     } else {
00118     }
00119   }
00120 }
00121 
00127 void error_update(void){
00128   int chunk, bit;
00129   int index;
00130   int found = 0;
00131   ERROR_ID error_code;
00132   volatile ERROR_BUFFER* buf;
00133   volatile ERROR_INFO new_error; 
00134   
00135   if (er_is_init){ //make sure error module has been initialized first
00136     for (chunk = 0; chunk < er_length; chunk++){
00137       if (er_flags[chunk]){
00138         for (bit = 0; bit < 32; bit++){
00139           if (er_flags[chunk] & (1<<bit)){
00140             error_code = (ERROR_ID)(bit + (32 * chunk));
00141             
00142             buf = &er_buffer;
00143             
00144             // ********* CHECK IF ERROR ALREADY OCCURRED ***********
00145             if (!(buf->empty)){ //only traverse if the buffer has stuff in it
00146               index = buf->first;
00147               while (index != buf->next) { //traverse the buf of errors to see if this error has already been generated
00148                 if (buf->errors[index].error_id == error_code) { //we've had this error before since the last time we sent info
00149                   buf->errors[index].frequency++; //if it has, increase the frequency
00150                   found = 1;
00151                   break;
00152                 }
00153                 if (index + 1 >= ERR_BUF_SIZE){
00154                   index = 0;
00155                 } else {
00156                   index++;
00157                 }
00158               }
00159             }
00160             
00161             // ********** ADD NEW ERROR TO BUFFER *********
00162             if (!found) { //we haven't seen this error before, add it to the ring buffer
00163               new_error.error_id = error_code;
00164               new_error.frequency = 1;
00165               new_error.time_occurred = er_get_timestamp(); //will hold actual value when sent out; this is just the initial time
00166               error_push(buf, new_error); //will new_error be out of scope here and be meaningless? TOMMY HELP!!
00167             } 
00168           }
00169         }
00170         er_flags[chunk] = 0;
00171       }  
00172     } 
00173   } 
00174 }
00175 
00182 static void error_push(volatile ERROR_BUFFER* buffer, volatile ERROR_INFO new_error)
00183 { 
00184   // ****** CHECK FOR OVERFLOW ******
00185   if ((buffer->next == buffer->first) && !(buffer->empty)){ //the front has caught up to the tail!! it's eating itself!! nooooo
00186     buffer->overflows++;
00187     if (buffer->first + 1 >= ERR_BUF_SIZE){
00188       buffer->first = 0;
00189     } else {
00190       buffer->first++;
00191     }
00192   }
00193   // ****** ADD NEW DATA ****** 
00194   buffer->errors[buffer->next] = new_error;
00195   if (buffer->next + 1 >= ERR_BUF_SIZE){
00196     buffer->next = 0;
00197   } else {
00198     buffer->next++;
00199   }
00200   buffer->empty = 0; //buffer now has stuff in it
00201 }
00202 
00209 static volatile ERROR_INFO* error_pop(volatile ERROR_BUFFER* buffer)
00210 {
00211   volatile ERROR_INFO* err = 0;
00212   if (!buffer->empty){
00213     err = &(buffer->errors[buffer->first]);
00214     if (buffer->first + 1 >= ERR_BUF_SIZE){
00215       buffer->first = 0;
00216     } else {
00217       buffer->first++;
00218     }
00219     buffer->overflows = 0;    
00220     if (buffer->first == buffer->next){
00221       buffer->empty = 1;
00222     }
00223   } 
00224   return err;
00225 }
00226 
00231 int error_get_time(void)
00232 {
00233   if (er_is_init){ //make sure error module has been initialized first
00234     return (int)(er_active->time_occurred); 
00235   } else {
00236     return 0;
00237   }
00238 }
00247 int error_get_info(void)
00248 {
00249   if (er_is_init){ //make sure error module has been initialized first
00250     long int info = (er_active->error_id & 0xFFFF) | ((er_board_id & 0x3F) << 16) | ((er_active->frequency & 0x3FF) << 22);
00251     return info;
00252   } else {
00253     return 0;
00254   }
00255 }
00256 
00261 BOARD_ID error_get_board(void)
00262 {
00263   return er_board_id;
00264 }
00265 
00270 ERROR_ID error_get_id(void)
00271 {
00272   if (er_is_init){ //make sure error module has been initialized first
00273     return (ERROR_ID)er_active->error_id;
00274   } else {
00275     return ERROR_DEFAULT;
00276   }
00277 }
00278 
00283 int error_get_frequency(void)
00284 {
00285   if (er_is_init){ //make sure error module has been initialized first
00286     return er_active->frequency;
00287   } else {
00288     return 0;
00289   }
00290 }
00291  
00299 void error_send_next(void)
00300 {
00301   if (er_is_init){ //make sure error module has been initialized first
00302     if (!er_buffer.empty){
00303       er_active = error_pop(&er_buffer);
00304       if (er_active != 0){
00305         er_transmit();
00306       }
00307     }
00308   }
00309 }
00310 
00311 
00312 
00313 
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3