can.c

00001 #include <includes.h>
00002 
00003 unsigned long can_elapsed_ms = 0;
00004 
00005 // ************************************************************************************
00006 // TRANSMIT VARIABLES
00007 // ************************************************************************************
00008 CAN_TX_CHAN_CFG  can_tx_chan_cfgs[5];   //Five elements, index 1 to 4
00009 
00010 // CAN transmit frame count global variables:
00011 volatile unsigned short can_tx_frame_count_1 = 0;
00012 volatile unsigned short can_tx_frame_count_2 = 0;
00013 volatile unsigned short can_tx_frame_count_3 = 0;
00014 volatile unsigned short can_tx_frame_count_4 = 0;
00015 
00016 //Set up CAN transmit buffers
00017 #ifndef CAN_TX_BUFFER_SIZE
00018   #define CAN_TX_BUFFER_SIZE  8
00019 #endif
00020 volatile CAN_FRAME can1_tx_buffer[CAN_TX_BUFFER_SIZE];
00021 volatile short int can1_tx_index1 = 0;
00022 volatile short int can1_tx_index2 = 0;
00023 
00024 volatile CAN_FRAME can2_tx_buffer[CAN_TX_BUFFER_SIZE];
00025 volatile short int can2_tx_index1 = 0;
00026 volatile short int can2_tx_index2 = 0;
00027 
00028 volatile CAN_FRAME can3_tx_buffer[CAN_TX_BUFFER_SIZE];
00029 volatile short int can3_tx_index1 = 0;
00030 volatile short int can3_tx_index2 = 0;
00031 
00032 volatile CAN_FRAME can4_tx_buffer[CAN_TX_BUFFER_SIZE];
00033 volatile short int can4_tx_index1 = 0;
00034 volatile short int can4_tx_index2 = 0;
00035 
00036 
00037 
00038 // ************************************************************************************
00039 // RECEIVE VARIABLES
00040 // ************************************************************************************
00041 CAN_FRAME_DESC   ** can_rx_descriptors;
00042 CAN_FRAME_DESC   ** can_rx_rtr_descriptors;
00043 CAN_RX_CHAN_CFG     can_rx_chan_cfgs[5];
00044 
00045 // CAN receive frame count global variables:
00046 volatile unsigned short can_rx_frame_count_1 = 0;
00047 volatile unsigned short can_rx_frame_count_2 = 0;
00048 volatile unsigned short can_rx_frame_count_3 = 0;
00049 volatile unsigned short can_rx_frame_count_4 = 0;
00050 
00051 //Set up CAN receive buffer
00052 #ifndef CAN_RX_BUFFER_SIZE
00053   #define CAN_RX_BUFFER_SIZE  64
00054 #endif
00055 volatile CAN_FRAME can_rx_buffer[CAN_RX_BUFFER_SIZE];
00056 volatile short int can_rx_index1 = 0;
00057 volatile short int can_rx_index2 = 0;
00058 
00059 // ************************************************************************************
00060 // ERROR VARIABLES
00061 // ************************************************************************************
00062 volatile unsigned long can_error_1 = 0;
00063 volatile unsigned long can_error_2 = 0;
00064 volatile unsigned long can_error_3 = 0;
00065 volatile unsigned long can_error_4 = 0;
00066 
00067 // ************************************************************************************
00068 // TRANSMIT FUNCTIONS
00069 // ************************************************************************************
00070 
00072 //Push one CAN frame onto CAN1 transmit ring buffer
00073 unsigned short int can_tx1_push_frame(CAN_FRAME * frameptr)
00074 {
00075   short int ret = 1, temp_index = can1_tx_index1;
00076   
00077   if (++temp_index == CAN_TX_BUFFER_SIZE) {temp_index = 0;}
00078 
00079   if (temp_index != can1_tx_index2) 
00080   { 
00081     //Push new frame onto buffer
00082     can1_tx_buffer[can1_tx_index1] = *frameptr;
00083     can1_tx_index1 = temp_index;   //update index1
00084     ret = 0; //Frame successfully pushed onto buffer
00085   } 
00086 //  if (ret == 1)mcu_led_red_blink(10); 
00087   return ret; // 0 = successful push, 1 = buffer full
00088 }
00090 
00092 void can_tx1(void)
00093 {
00094   while (can1_tx_index2 != can1_tx_index1)
00095   {
00096     if (C1SR & (1<<2)) // buffer 1 is available
00097     {              
00098       C1TFI1 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00099       C1TID1 = can1_tx_buffer[can1_tx_index2].addr;   //get CAN_ID
00100       C1TDA1 = can1_tx_buffer[can1_tx_index2].payload.w.w1;   //load first data word
00101       C1TDB1 = can1_tx_buffer[can1_tx_index2].payload.w.w2;   //load second data word 
00102       C1CMR = (1<<0) | (1<<5);     // Select buffer 1, request transmission
00103 
00104       //Move to next read index location
00105       if (can1_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00106       {
00107         can1_tx_index2 = 0;
00108       }
00109       else
00110       {
00111         ++can1_tx_index2;
00112       }
00113 
00114       can_tx_frame_count_1++;
00115     }
00116     else if (C1SR & (1<<10)) // buffer 2 is available
00117     {
00118       C1TFI2 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00119       C1TID2 = can1_tx_buffer[can1_tx_index2].addr;   //get CAN_ID
00120       C1TDA2 = can1_tx_buffer[can1_tx_index2].payload.w.w1;   //load first data word
00121       C1TDB2 = can1_tx_buffer[can1_tx_index2].payload.w.w2;   //load second data word 
00122       C1CMR = (1<<0) | (1<<6);     // select buffer 2, request transmission
00123 
00124       //Move to next read index location
00125       if (can1_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00126       {
00127         can1_tx_index2 = 0;
00128       }
00129       else
00130       {
00131         ++can1_tx_index2;
00132       }
00133       
00134       can_tx_frame_count_1++;
00135     }
00136     else
00137     {
00138       return;   //all available buffers full
00139     } 
00140   }
00141 }
00143 
00145 //Push one CAN frame onto CAN2 transmit ring buffer
00146 unsigned short int can_tx2_push_frame(CAN_FRAME * frameptr)
00147 {
00148   short int ret = 1, temp_index = can2_tx_index1;
00149   
00150   if (++temp_index == CAN_TX_BUFFER_SIZE) {temp_index = 0;}
00151 
00152   if (temp_index != can2_tx_index2) 
00153   {
00154     //Push new frame onto buffer
00155     can2_tx_buffer[can2_tx_index1] = *frameptr;
00156     can2_tx_index1 = temp_index;   //update index1
00157     ret = 0; //Frame successfully pushed onto buffer
00158   }
00159   
00160   return ret; // 0 = successful push, 1 = buffer full
00161 }
00162 
00164 void can_tx2(void)
00165 {  
00166   while (can2_tx_index2 != can2_tx_index1)
00167   {
00168     if (C2SR & (1<<2)) // buffer 1 is available
00169     {   
00170       C2TFI1 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00171       C2TID1 = can2_tx_buffer[can2_tx_index2].addr;   //get CAN_ID
00172       C2TDA1 = can2_tx_buffer[can2_tx_index2].payload.w.w1;   //load first data word
00173       C2TDB1 = can2_tx_buffer[can2_tx_index2].payload.w.w2;   //load second data word 
00174       C2CMR = (1<<0) | (1<<5);     // select buffer 1, request transmission
00175       can_tx_frame_count_2++;
00176 
00177       //Move to next read index location
00178       if (can2_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00179       {
00180         can2_tx_index2 = 0;
00181       }
00182       else
00183       {
00184         ++can2_tx_index2;
00185       }
00186     }
00187     else if (C2SR & (1<<10)) // buffer 2 is available
00188     {
00189       C2TFI2 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00190       C2TID2 = can2_tx_buffer[can2_tx_index2].addr;   //get CAN_ID
00191       C2TDA2 = can2_tx_buffer[can2_tx_index2].payload.w.w1;   //load first data word
00192       C2TDB2 = can2_tx_buffer[can2_tx_index2].payload.w.w2;   //load second data word 
00193       C2CMR = (1<<0) | (1<<6);     // select buffer 2, request transmission
00194       can_tx_frame_count_2++;
00195 
00196       //Move to next read index location
00197       if (can2_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00198       {
00199         can2_tx_index2 = 0;
00200       }
00201       else
00202       {
00203         ++can2_tx_index2;
00204       }
00205     }
00206     else
00207     {
00208       return;   //all available buffers full
00209     } 
00210   }
00211 }
00213 
00214 
00216 //Push one CAN frame onto CAN3 transmit ring buffer
00217 unsigned short int can_tx3_push_frame(CAN_FRAME * frameptr)
00218 {
00219   short int ret = 1, temp_index = can3_tx_index1;
00220   
00221   if (++temp_index == CAN_TX_BUFFER_SIZE) {temp_index = 0;}
00222 
00223   if (temp_index != can3_tx_index2) 
00224   {
00225     //Push new frame onto buffer
00226     can3_tx_buffer[can3_tx_index1] = *frameptr;
00227     can3_tx_index1 = temp_index;   //update index1
00228     ret = 0; //Frame successfully pushed onto buffer
00229   }
00230 
00231   return ret; // 0 = successful push, 1 = buffer full
00232 }
00233 
00235 void can_tx3(void)
00236 {
00237   while (can3_tx_index2 != can3_tx_index1)
00238   {
00239     if (C3SR & (1<<2)) // buffer 1 is available
00240     {   
00241       C3TFI1 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00242       C3TID1 = can3_tx_buffer[can3_tx_index2].addr;   //get CAN_ID
00243       C3TDA1 = can3_tx_buffer[can3_tx_index2].payload.w.w1;   //load first data word
00244       C3TDB1 = can3_tx_buffer[can3_tx_index2].payload.w.w2;   //load second data word 
00245       C3CMR = (1<<0) | (1<<5);     // select buffer 1, request transmission
00246       can_tx_frame_count_3++;
00247  
00248       //Move to next read index location
00249       if (can3_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00250       {
00251         can3_tx_index2 = 0;
00252       }
00253       else
00254       {
00255         ++can3_tx_index2;
00256       }
00257     }
00258     else if (C3SR & (1<<10)) // buffer 2 is available
00259     {
00260       C3TFI2 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00261       C3TID2 = can3_tx_buffer[can3_tx_index2].addr;   //get CAN_ID
00262       C3TDA2 = can3_tx_buffer[can3_tx_index2].payload.w.w1;   //load first data word
00263       C3TDB2 = can3_tx_buffer[can3_tx_index2].payload.w.w2;   //load second data word 
00264       C3CMR = (1<<0) | (1<<6);     // select buffer 2, request transmission
00265       can_tx_frame_count_3++;
00266 
00267       //Move to next read index location
00268       if (can3_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00269       {
00270         can3_tx_index2 = 0;
00271       }
00272       else
00273       {
00274         ++can3_tx_index2;
00275       }
00276     }
00277     else
00278     {
00279       return;   //all available buffers full
00280     } 
00281   }
00282 }
00284 
00285 
00287 //Push one CAN frame onto CAN4 transmit ring buffer
00288 unsigned short int can_tx4_push_frame(CAN_FRAME * frameptr)
00289 {
00290   short int ret = 1, temp_index = can4_tx_index1;
00291   
00292   if (++temp_index == CAN_TX_BUFFER_SIZE) {temp_index = 0;}
00293 
00294   if (temp_index != can4_tx_index2) 
00295   {
00296     //Push new frame onto buffer
00297     can4_tx_buffer[can4_tx_index1] = *frameptr;
00298     can4_tx_index1 = temp_index;   //update index1
00299     ret = 0; //Frame successfully pushed onto buffer
00300   }
00301 
00302   return ret; // 0 = successful push, 1 = buffer full
00303 }
00304 
00305 
00307 void can_tx4(void)
00308 {
00309   while (can4_tx_index2 != can4_tx_index1)
00310   {
00311     if (C4SR & (1<<2)) // buffer 1 is available
00312     {   
00313       C4TFI1 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00314       C4TID1 = can4_tx_buffer[can4_tx_index2].addr;   //get CAN_ID
00315       C4TDA1 = can4_tx_buffer[can4_tx_index2].payload.w.w1;   //load first data word
00316       C4TDB1 = can4_tx_buffer[can4_tx_index2].payload.w.w2;   //load second data word 
00317       C4CMR = (1<<0) | (1<<5);     // select buffer 1, request transmission
00318       can_tx_frame_count_4++;
00319  
00320       //Move to next read index location
00321       if (can4_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00322       {
00323         can4_tx_index2 = 0;
00324       }
00325       else
00326       {
00327         ++can4_tx_index2;
00328       }
00329     }
00330     else if (C4SR & (1<<10)) // buffer 2 is available
00331     {
00332       C4TFI2 = 1<<19;  //Data length 8, FF = 0, RTR = 0, PRIO = 0
00333       C4TID2 = can4_tx_buffer[can4_tx_index2].addr;   //get CAN_ID
00334       C4TDA2 = can4_tx_buffer[can4_tx_index2].payload.w.w1;   //load first data word
00335       C4TDB2 = can4_tx_buffer[can4_tx_index2].payload.w.w2;   //load second data word 
00336       C4CMR = (1<<0) | (1<<6);     // select buffer 2, request transmission
00337       can_tx_frame_count_4++;
00338 
00339       //Move to next read index location
00340       if (can4_tx_index2 >= CAN_TX_BUFFER_SIZE - 1)
00341       {
00342         can4_tx_index2 = 0;
00343       }
00344       else
00345       {
00346         ++can4_tx_index2;
00347       }
00348     }
00349     else
00350     {
00351       return;   //all available buffers full
00352     } 
00353   }
00354 }
00356 
00357 
00358 unsigned short can_tx_get_frame_count_1(CAN_FRAME * frame)
00359 {
00360   frame->payload.w.w1 = can_tx_frame_count_1;
00361   can_tx_frame_count_1 = 0;     //Reset frame counter - could lose a count here, but not critical
00362   frame->payload.w.w2 = can_elapsed_ms;
00363   return 0;
00364 }
00365 
00366 unsigned short can_tx_get_frame_count_2(CAN_FRAME * frame)
00367 {
00368   frame->payload.w.w1 = can_tx_frame_count_2;
00369   can_tx_frame_count_2 = 0;     //Reset frame counter - could lose a count here, but not critical
00370   frame->payload.w.w2 = can_elapsed_ms;
00371   return 0;
00372 }
00373 
00374 unsigned short can_tx_get_frame_count_3(CAN_FRAME * frame)
00375 {
00376   frame->payload.w.w1 = can_tx_frame_count_3;
00377   can_tx_frame_count_3 = 0;     //Reset frame counter - could lose a count here, but not critical
00378   frame->payload.w.w2 = can_elapsed_ms;
00379   return 0;
00380 }
00381 
00382 unsigned short can_tx_get_frame_count_4(CAN_FRAME * frame)
00383 {
00384   frame->payload.w.w1 = can_tx_frame_count_4;
00385   can_tx_frame_count_4 = 0;     //Reset frame counter - could lose a count here, but not critical
00386   frame->payload.w.w2 = can_elapsed_ms;
00387   return 0;
00388 }
00389 
00390 // Set up CAN_TX_CHAN_CFG for channel chan; stalled is initialized to 1 to kickstart transmit process
00391 void can_tx_set_chan_cfg(CAN_CHANNEL chan,volatile unsigned long * base_addr, CAN_RING * tx_ring){
00392   can_tx_chan_cfgs[chan].base_addr = base_addr;
00393   can_tx_chan_cfgs[chan].ring      = tx_ring;
00394   can_tx_chan_cfgs[chan].stalled   = 1;
00395 }
00396 
00397 // Basic can_transmit function, calls multi-argument can_transmit_alt
00398 int can_transmit(CAN_FRAME_DESC * frame_desc){
00399   return can_transmit_alt(frame_desc,frame_desc->chan, frame_desc->rtr);
00400 }
00401 
00402 // CAN transmit function; has options for CAN channel and rtr (remote transmission request)
00403 int can_transmit_alt(CAN_FRAME_DESC * frame_desc, CAN_CHANNEL chan, char rtr){
00404   CAN_LAYOUT  layout = frame_desc->frame_layout;
00405   CAN_FRAME   frame;
00406   int         dlc;
00407 
00408 // Set data length code of transmitted frame, based on rtr bit or CAN_LAYOUT
00409   if(rtr){
00410     dlc = 0;
00411   }else{
00412     switch(layout){
00413       case CAN_LAYOUT_D:
00414       case CAN_LAYOUT_FF:
00415       case CAN_LAYOUT_II:
00416       case CAN_LAYOUT_FI:
00417       case CAN_LAYOUT_ISS:
00418         dlc = 8;
00419         break;
00420       default:
00421         //Unrecognized layout, throw error and abort.
00422         return 1;
00423     }
00424   }
00425   
00426 
00427  
00428   // Use getter functions to fill in payload data bytes of transmitted frame.
00429   // Function pointers are from the frame descriptor in the first argument
00430   if(rtr) {
00431     dlc = 0;
00432   } else {
00433     switch(layout){
00434       //WARNING!!! not for the faint of heart.  Here we are casting function pointers
00435       //to another type of function pointer, and then we call it.  If this doesn't
00436       //make sense, read about function pointers and casting.
00437       case CAN_LAYOUT_D:
00438         frame.payload.d.d1 = ((CAN_TX_GETTER_DOUBLE)frame_desc->ptr1)();
00439         dlc = 8;
00440         break;
00441       case CAN_LAYOUT_FF:
00442         frame.payload.f.f1 = ((CAN_TX_GETTER_FLOAT)frame_desc->ptr1)();
00443         frame.payload.f.f2 = ((CAN_TX_GETTER_FLOAT)frame_desc->ptr2)();
00444         dlc = 8;
00445         break;
00446       case CAN_LAYOUT_II:
00447         frame.payload.i.i1 = ((CAN_TX_GETTER_INT)frame_desc->ptr1)();
00448         frame.payload.i.i2 = ((CAN_TX_GETTER_INT)frame_desc->ptr2)();
00449         dlc = 8;
00450       break;
00451       case CAN_LAYOUT_FI:
00452         frame.payload.f.f1 = ((CAN_TX_GETTER_FLOAT)frame_desc->ptr1)();
00453         frame.payload.i.i2 = ((CAN_TX_GETTER_INT)frame_desc->ptr2)();
00454         dlc = 8;
00455       break;
00456       case CAN_LAYOUT_ISS:
00457         frame.payload.i.i1 = ((CAN_TX_GETTER_INT  )frame_desc->ptr1)();
00458         frame.payload.s.s3 = ((CAN_TX_GETTER_SHORT)frame_desc->ptr2)();
00459         frame.payload.s.s4 = ((CAN_TX_GETTER_SHORT)frame_desc->ptr3)();
00460         dlc = 8;
00461       break;
00462       default:
00463         //Unrecognized layout, throw error and abort.
00464         return 1;
00465     }
00466   }
00467 
00468   // Fill in the rest of the CAN_FRAME elements
00469   // Note that the channel number chan comes from the frame descriptor here, not the argument chan.
00470   // This may or may not be useful. ***************************************************************
00471   // So the chan argument does nothing at this point.
00472   frame.addr = frame_desc->addr;
00473   frame.chan = frame_desc->chan;
00474   frame.dlc  = dlc;
00475   frame.rtr  = rtr;
00476   
00477   //The frame is now fully populated with Address, Data Length, and Payload
00478   //and is therefore ready to be sent out.
00479   return can_transmit_frame(&frame);
00480 }
00481 
00482 // Push CAN_FRAME onto related CAN ring buffer
00483 int can_transmit_frame(CAN_FRAME * frameptr)
00484 {
00485   CAN_CHANNEL   chan      = frameptr->chan;
00486   int           ret = 1;
00487 
00488   if (chan == CHAN_CAN1)
00489   {
00490     ret = can_tx1_push_frame(frameptr);
00491     can_tx1();
00492   }
00493   else if (chan == CHAN_CAN2)
00494   {
00495     ret = can_tx2_push_frame(frameptr);
00496     can_tx2();
00497   }
00498   else if (chan == CHAN_CAN3)
00499   {
00500     ret = can_tx3_push_frame(frameptr);
00501     can_tx3();
00502   }
00503   else if (chan == CHAN_CAN4)
00504   {
00505     ret = can_tx4_push_frame(frameptr);
00506     can_tx4();
00507   }
00508 
00509   return ret; // ret = 1: buffer full; ret = 0: frame was successfully pushed onto buffer
00510 }
00511 
00512 // ************************************************************************************
00513 // RECEIVE
00514 // ************************************************************************************
00515 
00516 void can_rx_dispatch_all(void)
00517 {
00518   CAN_FRAME frame;
00519   while (!can_rx_pop_frame(&frame))
00520   {
00521     can_rx_dispatch_frame(&frame);
00522   }
00523 }
00524 
00525 unsigned short can_rx_pop_frame(CAN_FRAME * frameptr)
00526 {
00527   volatile short int temp_index1 = can_rx_index1;
00528   volatile short int temp_index2 = can_rx_index2;
00529 
00530   if (temp_index2 != temp_index1)
00531   {
00532     *frameptr = can_rx_buffer[temp_index2];
00533     if (++temp_index2 >= CAN_RX_BUFFER_SIZE) 
00534     {
00535       temp_index2 = 0;
00536     }
00537     can_rx_index2 = temp_index2;  // Update read index
00538     return 0; // Frame popped successfully
00539   }
00540   else
00541   {
00542     return 1; // Buffer empty
00543   }
00544 }
00545 
00547 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00548 void can_rx1_fiq(void)
00549 {
00550   short int temp_index = can_rx_index1; 
00551 
00552   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00553   if (temp_index == can_rx_index2)
00554   {
00555     //Buffer full, new data will be lost; don't advance write index
00556     error_occurred_fiq(ERROR_CAN1_RX_BUF_OF);  
00557     C1CMR = 1<<2; //Release CAN data buffer
00558     return;
00559   }
00560   ++can_rx_frame_count_1; // Count received frame
00561  
00562   can_rx_buffer[temp_index].chan            = CHAN_CAN1;
00563   can_rx_buffer[temp_index].addr            = C1RID;
00564   can_rx_buffer[temp_index].dlc             = (C1RFS>>16)&0xF;
00565   can_rx_buffer[temp_index].rtr             = (C1RFS>>30)&0x1;
00566   can_rx_buffer[temp_index].payload.w.w1    = C1RDA;
00567   can_rx_buffer[temp_index].payload.w.w2    = C1RDB;
00568    
00569   C1CMR = 1<<2; //Release CAN data buffer 
00570 
00571   can_rx_index1 = temp_index;   //update index1
00572 }
00574 
00576 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00577 void can_rx2_fiq(void)
00578 {
00579   short int temp_index = can_rx_index1;
00580 
00581   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00582   if (temp_index == can_rx_index2)
00583   {
00584     //Buffer full, new data will be lost; don't advance write index
00585     error_occurred_fiq(ERROR_CAN2_RX_BUF_OF);  
00586     C2CMR = 1<<2; //Release CAN data buffer
00587     return;
00588   }
00589   ++can_rx_frame_count_2; // Count received frame
00590 
00591   can_rx_buffer[temp_index].chan            = CHAN_CAN2;
00592   can_rx_buffer[temp_index].addr            = C2RID;
00593   can_rx_buffer[temp_index].dlc             = (C2RFS>>16)&0xF;
00594   can_rx_buffer[temp_index].rtr             = (C2RFS>>30)&0x1;
00595   can_rx_buffer[temp_index].payload.w.w1    = C2RDA;
00596   can_rx_buffer[temp_index].payload.w.w2    = C2RDB; 
00597 
00598   C2CMR = 1<<2; //Release CAN data buffer 
00599    
00600   can_rx_index1 = temp_index;   //update index1
00601 }
00603 
00605 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00606 void can_rx3_fiq(void)
00607 {
00608   short int temp_index = can_rx_index1;
00609 
00610   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00611   if (temp_index == can_rx_index2)
00612   {
00613     //Buffer full, new data will be lost; don't advance write index
00614     error_occurred_fiq(ERROR_CAN3_RX_BUF_OF);  
00615     C3CMR = 1<<2; //Release CAN data buffer
00616     return;
00617   }
00618 
00619   ++can_rx_frame_count_3; // Count received frame
00620 
00621   can_rx_buffer[temp_index].chan            = CHAN_CAN3;
00622   can_rx_buffer[temp_index].addr            = C3RID;
00623   can_rx_buffer[temp_index].dlc             = (C3RFS>>16)&0xF;
00624   can_rx_buffer[temp_index].rtr             = (C3RFS>>30)&0x1;
00625   can_rx_buffer[temp_index].payload.w.w1    = C3RDA;
00626   can_rx_buffer[temp_index].payload.w.w2    = C1RDB;
00627   
00628   C3CMR = 1<<2; //Release CAN data buffer 
00629    
00630   can_rx_index1 = temp_index;   //update index1
00631 }
00633 
00635 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00636 void can_rx4_fiq(void)
00637 {
00638   short int temp_index = can_rx_index1;
00639 
00640   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00641   if (temp_index == can_rx_index2)
00642   {
00643     //Buffer full, new data will be lost; don't advance write index
00644     error_occurred_fiq(ERROR_CAN4_RX_BUF_OF);  
00645     C4CMR = 1<<2; //Release CAN data buffer
00646     return;
00647   }
00648 
00649   ++can_rx_frame_count_4; // Count received frame
00650 
00651   can_rx_buffer[temp_index].chan            = CHAN_CAN4;
00652   can_rx_buffer[temp_index].addr            = C4RID;
00653   can_rx_buffer[temp_index].dlc             = (C4RFS>>16)&0xF;
00654   can_rx_buffer[temp_index].rtr             = (C4RFS>>30)&0x1;
00655   can_rx_buffer[temp_index].payload.w.w1    = C4RDA;
00656   can_rx_buffer[temp_index].payload.w.w2    = C4RDB;
00657   
00658   C4CMR = 1<<2; //Release CAN data buffer 
00659    
00660   can_rx_index1 = temp_index;   //update index1
00661 }
00663 
00664 
00666 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00667 void can_rx1_isr(void) __irq
00668 {
00669   short int temp_index = can_rx_index1;
00670 
00671   #ifdef DEBUG
00672   if (FIO0PIN & 1<<14)
00673   {
00674     VICIntEnClr = 0xFFFFFFFF; //Disable all interrupts before debugging
00675     VICVectAddr = 0;
00676     return;
00677   }
00678   #endif
00679   
00680   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00681   if (temp_index == can_rx_index2)
00682   {
00683     //Buffer full, new data will be lost; don't advance write index
00684     error_occurred_irq(ERROR_CAN1_RX_BUF_OF);  
00685     C1CMR = 1<<2; //Release CAN data buffer
00686     return;
00687   }
00688   ++can_rx_frame_count_1; // Count received frame
00689 
00690   can_rx_buffer[temp_index].chan            = CHAN_CAN1;
00691   can_rx_buffer[temp_index].addr            = C1RID;
00692   can_rx_buffer[temp_index].dlc             = (C1RFS>>16)&0xF;
00693   can_rx_buffer[temp_index].rtr             = (C1RFS>>30)&0x1;
00694   can_rx_buffer[temp_index].payload.w.w1    = C1RDA;
00695   can_rx_buffer[temp_index].payload.w.w2    = C1RDB;
00696 
00697   mcu_led_green_blink(5);
00698    
00699   C1CMR = 1<<2; //Release CAN data buffer 
00700    
00701   can_rx_index1 = temp_index;   //update index1
00702   VICVectAddr = 0;    // Clear interrupt in VIC.
00703 }
00705 
00707 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00708 void can_rx2_isr(void) __irq
00709 {
00710   short int temp_index = can_rx_index1;
00711 
00712   #ifdef DEBUG
00713   if (FIO0PIN & 1<<14)
00714   {
00715     VICIntEnClr = 0xFFFFFFFF; //Disable all interrupts before debugging
00716     VICVectAddr = 0;
00717     return;
00718   }
00719   #endif
00720 
00721   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00722   if (temp_index == can_rx_index2)
00723   {
00724     //Buffer full, new data will be lost; don't advance write index
00725     error_occurred_irq(ERROR_CAN2_RX_BUF_OF);  
00726     C2CMR = 1<<2; //Release CAN data buffer
00727     return;
00728   }
00729   ++can_rx_frame_count_2; // Count received frame
00730 
00731   can_rx_buffer[temp_index].chan            = CHAN_CAN2;
00732   can_rx_buffer[temp_index].addr            = C2RID;
00733   can_rx_buffer[temp_index].dlc             = (C2RFS>>16)&0xF;
00734   can_rx_buffer[temp_index].rtr             = (C2RFS>>30)&0x1;
00735   can_rx_buffer[temp_index].payload.w.w1    = C2RDA;
00736   can_rx_buffer[temp_index].payload.w.w2    = C2RDB; 
00737 
00738   C2CMR = 1<<2; //Release CAN data buffer 
00739    
00740   can_rx_index1 = temp_index;   //update index1
00741   VICVectAddr = 0;    // Clear interrupt in VIC.
00742 }
00744 
00746 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00747 void can_rx3_isr(void) __irq
00748 {
00749   short int temp_index = can_rx_index1;
00750 
00751   #ifdef DEBUG
00752   if (FIO0PIN & 1<<14)
00753   {
00754     VICIntEnClr = 0xFFFFFFFF; //Disable all interrupts before debugging
00755     VICVectAddr = 0;
00756     return;
00757   }
00758   #endif
00759 
00760   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00761   if (temp_index == can_rx_index2)
00762   {
00763     //Buffer full, new data will be lost; don't advance write index
00764     error_occurred_irq(ERROR_CAN3_RX_BUF_OF);  
00765     C3CMR = 1<<2; //Release CAN data buffer
00766     return;
00767   }
00768 
00769   ++can_rx_frame_count_3; // Count received frame
00770 
00771   can_rx_buffer[temp_index].chan            = CHAN_CAN3;
00772   can_rx_buffer[temp_index].addr            = C3RID;
00773   can_rx_buffer[temp_index].dlc             = (C3RFS>>16)&0xF;
00774   can_rx_buffer[temp_index].rtr             = (C3RFS>>30)&0x1;
00775   can_rx_buffer[temp_index].payload.w.w1    = C3RDA;
00776   can_rx_buffer[temp_index].payload.w.w2    = C1RDB;
00777   
00778   C3CMR = 1<<2; //Release CAN data buffer 
00779    
00780   can_rx_index1 = temp_index;   //update index1
00781   VICVectAddr = 0;    // Clear interrupt in VIC.
00782 }
00784 
00786 //Read CAN rx controller buffer, create CAN frame and push onto receive ring buffer
00787 void can_rx4_isr(void) __irq
00788 {
00789   short int temp_index = can_rx_index1;
00790 
00791   #ifdef DEBUG
00792   if (FIO0PIN & 1<<14)
00793   {
00794     VICIntEnClr = 0xFFFFFFFF; //Disable all interrupts before debugging
00795     VICVectAddr = 0;
00796     return;
00797   }
00798   #endif
00799    
00800   if (++temp_index == CAN_RX_BUFFER_SIZE) {temp_index = 0;}
00801   if (temp_index == can_rx_index2)
00802   {
00803     //Buffer full, new data will be lost; don't advance write index
00804     error_occurred_irq(ERROR_CAN4_RX_BUF_OF);  
00805     C4CMR = 1<<2; //Release CAN data buffer
00806     return;
00807   }
00808 
00809   ++can_rx_frame_count_4; // Count received frame
00810 
00811   can_rx_buffer[temp_index].chan            = CHAN_CAN4;
00812   can_rx_buffer[temp_index].addr            = C4RID;
00813   can_rx_buffer[temp_index].dlc             = (C4RFS>>16)&0xF;
00814   can_rx_buffer[temp_index].rtr             = (C4RFS>>30)&0x1;
00815   can_rx_buffer[temp_index].payload.w.w1    = C4RDA;
00816   can_rx_buffer[temp_index].payload.w.w2    = C4RDB;
00817   
00818   C4CMR = 1<<2; //Release CAN data buffer 
00819    
00820   can_rx_index1 = temp_index;   //update index1
00821   VICVectAddr = 0;    // Clear interrupt in VIC.
00822 }
00824 
00825 unsigned short can_rx_get_frame_count_1(CAN_FRAME * frame)
00826 {
00827   frame->payload.w.w1 = can_rx_frame_count_1;
00828   can_rx_frame_count_1 = 0;     //Reset frame counter - could lose a count here, but not critical
00829   frame->payload.w.w2 = can_elapsed_ms;
00830   return 0;
00831 }
00832 
00833 unsigned short can_rx_get_frame_count_2(CAN_FRAME * frame)
00834 {
00835   frame->payload.w.w1 = can_rx_frame_count_2;
00836   can_rx_frame_count_2 = 0;     //Reset frame counter - could lose a count here, but not critical
00837   frame->payload.w.w2 = can_elapsed_ms;
00838   return 0;
00839 }
00840 
00841 unsigned short can_rx_get_frame_count_3(CAN_FRAME * frame)
00842 {
00843   frame->payload.w.w1 = can_rx_frame_count_3;
00844   can_rx_frame_count_3 = 0;     //Reset frame counter - could lose a count here, but not critical
00845   frame->payload.w.w2 = can_elapsed_ms;
00846   return 0;
00847 }
00848 
00849 unsigned short can_rx_get_frame_count_4(CAN_FRAME * frame)
00850 {
00851   frame->payload.w.w1 = can_rx_frame_count_4;
00852   can_rx_frame_count_4 = 0;     //Reset frame counter - could lose a count here, but not critical
00853   frame->payload.w.w2 = can_elapsed_ms;
00854   return 0;
00855 }
00856 
00857 void can_rx_set_descriptors(CAN_FRAME_DESC ** rx_descriptors,CAN_FRAME_DESC ** rtr_descriptors){
00858   can_rx_descriptors     = rx_descriptors;
00859   can_rx_rtr_descriptors = rtr_descriptors;
00860 //  can_rx_acceptance_filter_init();  Put acceptance filter config here? And RTR-subscribe? Or keep it separate in software_setup.c?
00861 }
00862 
00863 void can_rx_set_chan_cfg(CAN_CHANNEL chan,volatile unsigned long * base_addr, CAN_RING * rx_ring, CAN_DISPATCH_MODE mode){
00864   CAN_RX_CHAN_CFG * cfg = &can_rx_chan_cfgs[chan];
00865   
00866   cfg->base_addr     = base_addr;
00867   cfg->dispatch_mode = mode;
00868   cfg->ring          = rx_ring; 
00869 }
00870 
00871 void can_rx_dispatch_frame(CAN_FRAME * frame){
00872   CAN_FRAME_DESC  * frame_desc = 0;
00873   CAN_LAYOUT        layout;
00874   int               expected_dlc;
00875   int               i;
00876   CAN_FRAME_DESC ** search_list;
00877 
00878  // static unsigned long old_time = 0;
00879   
00880   search_list = (frame->rtr) ? can_rx_rtr_descriptors : can_rx_descriptors;
00881   
00882   if(search_list == NULL) {
00883     return; //Error, list not valid.
00884   }
00885   
00886   i = 0;
00887   while(1){
00888     frame_desc = search_list[i];
00889     if((frame_desc == 0) ||                               //if we have reached the end of the rx descriptor list, or
00890       ((frame_desc->addr&0x7FF) == (frame->addr&0x7FF))) {//if we have found an address match
00891       break;
00892     }
00893     i++;
00894   }
00895 
00896   if(frame_desc == 0) {
00897     //Throw error.  This shouldn't have gotten through the acceptance filter
00898     return;
00899   }
00900   //frame_desc points now to the descriptor for the received frame
00901 
00902   //now, verify that the correct data length field value has been received  
00903   layout = frame_desc->frame_layout;
00904 
00905   if(frame->rtr) {
00906     expected_dlc = 0;
00907   } else {
00908     switch(layout){
00909       case CAN_LAYOUT_D:
00910       case CAN_LAYOUT_FF:
00911       case CAN_LAYOUT_II:
00912       case CAN_LAYOUT_FI:
00913       case CAN_LAYOUT_ISS:
00914         expected_dlc =  8;
00915         break;
00916       default:
00917         //this packet uses an unrecognized layout
00918         expected_dlc = -1;
00919         break;
00920     };
00921   }
00922   if(expected_dlc == -1){
00923     //handle unrecognized frame layout exception
00924     return;
00925   }
00926   if((expected_dlc == 8) &&(frame->dlc < 8) ||
00927      (expected_dlc != frame->dlc)) {
00928     //handle dlc mismatch exception
00929     return;
00930   }
00931 
00932   /*  Test code - check for missing timestamps
00933     if (frame->addr == 0)
00934     {
00935       mcu_led_green_blink(5);
00936       if (frame->payload.w.w2 != old_time + 1)
00937       {
00938         mcu_led_red_blink(50);
00939       }
00940       old_time = frame->payload.w.w2;
00941     }
00942     */
00943 
00944   //dispatch payload contents per frame layout based on frame descriptor
00945   if(frame->rtr == 0){
00946     switch(layout){
00947       case CAN_LAYOUT_D:
00948         ((CAN_RX_SETTER_DOUBLE)frame_desc->ptr1)(frame->payload.d.d1);
00949         break;
00950       case CAN_LAYOUT_FF:
00951         ((CAN_RX_SETTER_FLOAT)frame_desc->ptr1)(frame->payload.f.f1);
00952         ((CAN_RX_SETTER_FLOAT)frame_desc->ptr2)(frame->payload.f.f2);
00953         break;
00954       case CAN_LAYOUT_II:
00955         ((CAN_RX_SETTER_INT)frame_desc->ptr1)(frame->payload.i.i1);
00956         ((CAN_RX_SETTER_INT)frame_desc->ptr2)(frame->payload.i.i2);
00957         break;
00958       case CAN_LAYOUT_FI:
00959         ((CAN_RX_SETTER_FLOAT)frame_desc->ptr1)(frame->payload.f.f1);
00960         ((CAN_RX_SETTER_INT)  frame_desc->ptr2)(frame->payload.i.i2);
00961         break;
00962       case CAN_LAYOUT_ISS:
00963         ((CAN_RX_SETTER_INT  )frame_desc->ptr1)(frame->payload.i.i1);
00964         ((CAN_RX_SETTER_SHORT)frame_desc->ptr2)(frame->payload.s.s3);
00965         ((CAN_RX_SETTER_SHORT)frame_desc->ptr3)(frame->payload.s.s4);   
00966         break;    
00967       default:
00968         //this packet uses an unrecognized layout, throw an error
00969         break;
00970     };
00971   } else {
00972     can_transmit(frame_desc);
00973   }
00974   //YAY!!!
00975   //Now we're done, this frame has been fully dispatched!
00976 }
00977 
00978 // ************************************************************************************
00979 // ERROR HANDLING
00980 // ************************************************************************************
00981 
00982 unsigned short can_get_error_1(CAN_FRAME * frame)
00983 {
00984   frame->payload.w.w1 = can_error_1;
00985   can_error_1 = 0;     //Reset error
00986   frame->payload.w.w2 = can_elapsed_ms;
00987   return 0;
00988 }
00989 
00990 unsigned short can_get_error_2(CAN_FRAME * frame)
00991 {
00992   frame->payload.w.w1 = can_error_2;
00993   can_error_2 = 0;     //Reset error
00994   frame->payload.w.w2 = can_elapsed_ms;
00995   return 0;
00996 }
00997 
00998 unsigned short can_get_error_3(CAN_FRAME * frame)
00999 {
01000   frame->payload.w.w1 = can_error_3;
01001   can_error_3 = 0;     //Reset error
01002   frame->payload.w.w2 = can_elapsed_ms;
01003   return 0;
01004 }
01005 
01006 unsigned short can_get_error_4(CAN_FRAME * frame)
01007 {
01008   frame->payload.w.w1 = can_error_4;
01009   can_error_4 = 0;     //Reset error
01010   frame->payload.w.w2 = can_elapsed_ms;
01011   return 0;
01012 }
01013 
01014 void can_error_isr(void) __irq
01015 {
01016  volatile int can_status1; //save state of capture register
01017  volatile int can_status2; //save state of capture register
01018  volatile int can_status3; //save state of capture register
01019  volatile int can_status4; //save state of capture register
01020  
01021  volatile unsigned long can_acc_filter_error;   //save location of error in AF lookup table
01022   
01023   #ifdef DEBUG
01024     if (FIO0PIN & 1<<14)
01025     {
01026       VICIntEnClr = 0xFFFFFFFF; //Disable all interrupts before debugging
01027       VICVectAddr = 0;
01028       return;
01029     }
01030   #endif
01031 
01032   if (LUTerr & (1<<0))
01033   {
01034     can_acc_filter_error = LUTerrAd;  // Address in look-up table RAM (AF) at which error was encountered
01035                                       // Reading this register clears LUTerr error flag
01036     error_occurred_irq(ERROR_CAN_ACC_FILTER);  // Acceptance filter error - most likely a table error
01037   }
01038 
01039 #ifdef USE_CAN1
01040   if (C1GSR & (1<<7))
01041   { //Bus-off due to too many transmit errors. Probably because someone flashed a board somewhere...
01042     C1MOD = 0; //restart the can bus
01043     error_occurred_irq(ERROR_CAN1_TX_BUSOFF);  // Transmit errors leading to bus off error state
01044     can_error_1 = ERROR_CAN1_TX_BUSOFF;
01045     //can_tx_send_next_frame(CHAN_CAN1); //start the transmissions again
01046     //VICSoftInt = 1<<20;   //Force CAN1 TX interrupt     // **** TEST CODE ****
01047   }
01048   can_status1 = C1ICR; //save state of capture register
01049     if (can_status1 & ((1<<2)|(1<<3)|(1<<5)|(1<<7)))
01050   {
01051     if (can_status1 & (1<<2))
01052     {
01053       can_error_1 = ERROR_CAN1_ERR_WARN;
01054       error_occurred_irq(ERROR_CAN1_ERR_WARN);  // Shows change in error or bus status bits in either direction
01055     }
01056     if (can_status1 & (1<<3))
01057     {
01058       can_error_1 = ERROR_CAN1_DATA_OVRN;
01059       error_occurred_irq(ERROR_CAN1_DATA_OVRN);  // Receive data overrun on CAN1 - receive buffer not read before
01060                                                     // arrival of next received frame, data lost
01061     }
01062     if (can_status1 & (1<<5))
01063     {
01064       can_error_1 = ERROR_CAN1_ERR_PASS;
01065       error_occurred_irq(ERROR_CAN1_ERR_PASS);  // Shows change in active or passive error status in either direction
01066     }
01067     if (can_status1 & (1<<7))
01068     {
01069       if (can_status1 & (1<<21))
01070       {
01071         can_error_1 = ERROR_CAN1_BUS_RX;
01072         error_occurred_irq(ERROR_CAN1_BUS_RX);  // CAN1 has detected an rx bus error. Details of the error require reading
01073                                                   // the other bits in can_status1. For now that has to be done in the debugger,
01074                                                   // including all the possiblities in the ERROR_IDs would be cumbersome.
01075                                                   // But we could make a non-error CAN_FRAME dedicated to the CAN error status register,
01076       }                                           // if we wanted.
01077       else
01078       {
01079          can_error_1 = ERROR_CAN1_BUS_TX;
01080          error_occurred_irq(ERROR_CAN1_BUS_TX);
01081       }
01082     }
01083   } 
01084 #endif
01085 
01086 #ifdef USE_CAN2
01087   if (C2GSR & (1<<7))
01088   { //Bus-off due to too many transmit errors. Probably because someone flashed a board somewhere...
01089     C2MOD = 0; //restart the can bus
01090     error_occurred_irq(ERROR_CAN2_TX_BUSOFF);  // Transmit errors leading to bus off error state
01091     can_error_2 = ERROR_CAN2_TX_BUSOFF;
01092    // can_tx_send_next_frame(CHAN_CAN2); //start the transmissions again
01093     //VICSoftInt = 1<<21;   //Force CAN2 TX interrupt     // **** TEST CODE ****
01094   }
01095   can_status2 = C2ICR; //save state of capture register
01096   if (can_status2 & (((1<<2)|(1<<3)|(1<<5)|(1<<7))&0x7FF))
01097   {
01098     if (can_status2 & (1<<2))
01099     {
01100       can_error_2 = ERROR_CAN2_ERR_WARN;
01101       error_occurred_irq(ERROR_CAN2_ERR_WARN);  // Shows change in error or bus status bits in either direction
01102     }
01103     if (can_status2 & (1<<3))
01104     {
01105       can_error_2 = ERROR_CAN2_DATA_OVRN;
01106       error_occurred_irq(ERROR_CAN2_DATA_OVRN);  // Receive data overrun on CAN2 - receive buffer not read before
01107                                                     // arrival of next received frame, data lost
01108     }
01109     if (can_status2 & (1<<5))
01110     {
01111       can_error_2 = ERROR_CAN2_ERR_PASS;
01112       error_occurred_irq(ERROR_CAN2_ERR_PASS);  // Shows change in active or passive error status in either direction
01113     }
01114     if (can_status2 & (1<<7))
01115     {
01116       if (can_status2 & (1<<21))
01117       {
01118         can_error_2 = ERROR_CAN2_BUS_RX;
01119         error_occurred_irq(ERROR_CAN2_BUS_RX);  // CAN2 has detected an rx bus error. Details of the error require reading
01120                                                   // the other bits in can_status1. For now that has to be done in the debugger,
01121                                                   // including all the possiblities in the ERROR_IDs would be cumbersome.
01122                                                   // But we could make a non-error CAN_FRAME dedicated to the CAN error status register,
01123                                                   // if we wanted.
01124       }
01125       else
01126       {
01127         can_error_2 = ERROR_CAN2_BUS_TX;
01128          error_occurred_irq(ERROR_CAN2_BUS_TX);
01129       }
01130     }
01131   }
01132 #endif
01133 
01134 #ifdef USE_CAN3
01135   if (C3GSR & (1<<7))
01136   { //Bus-off due to too many transmit errors. Probably because someone flashed a board somewhere...
01137     C3MOD = 0; //restart the can bus
01138     error_occurred_irq(ERROR_CAN3_TX_BUSOFF);  // Transmit errors leading to bus off error state
01139     can_error_3 = ERROR_CAN3_TX_BUSOFF;
01140     //can_tx_send_next_frame(CHAN_CAN3); //start the transmissions again
01141     //VICSoftInt = 1<<22;   //Force CAN3 TX interrupt     // **** TEST CODE ****
01142   } 
01143   can_status3 = C3ICR; //save state of capture register
01144   if (can_status3 & (((1<<2)|(1<<3)|(1<<5)|(1<<7))&0x7FF))
01145   {
01146     if (can_status3 & (1<<2))
01147     {
01148       can_error_3 = ERROR_CAN3_ERR_WARN;
01149       error_occurred_irq(ERROR_CAN3_ERR_WARN);  // Shows change in error or bus status bits in either direction
01150     }
01151     if (can_status3 & (1<<3))
01152     {
01153       can_error_3 = ERROR_CAN3_DATA_OVRN;
01154       error_occurred_irq(ERROR_CAN3_DATA_OVRN);  // Receive data overrun on CAN3 - receive buffer not read before
01155                                                     // arrival of next received frame, data lost
01156     }
01157     if (can_status3 & (1<<5))
01158     {
01159       can_error_3 = ERROR_CAN3_ERR_PASS;
01160       error_occurred_irq(ERROR_CAN3_ERR_PASS);  // Shows change in active or passive error status in either direction
01161     }
01162     if (can_status3 & (1<<7))
01163     {
01164       if (can_status3 & (1<<21))
01165       {
01166         can_error_3 = ERROR_CAN3_BUS_RX;
01167         error_occurred_irq(ERROR_CAN3_BUS_RX);  // CAN3 has detected an rx bus error. Details of the error require reading
01168                                                   // the other bits in can_status1. For now that has to be done in the debugger,
01169                                                   // including all the possiblities in the ERROR_IDs would be cumbersome.
01170                                                   // But we could make a non-error CAN_FRAME dedicated to the CAN error status register,
01171                                                   // if we wanted.
01172       }
01173       else
01174       {
01175          can_error_3 = ERROR_CAN3_BUS_TX;
01176          error_occurred_irq(ERROR_CAN3_BUS_TX);
01177       }
01178     }
01179   }
01180 #endif
01181 
01182 #ifdef USE_CAN4
01183   if (C4GSR & (1<<7))
01184   { //Bus-off due to too many transmit errors. Probably because someone flashed a board somewhere...
01185     C4MOD = 0; //restart the can bus
01186     error_occurred_irq(ERROR_CAN4_TX_BUSOFF);  // Transmit errors leading to bus off error state
01187     can_error_4 = ERROR_CAN4_TX_BUSOFF;
01188    // can_tx_send_next_frame(CHAN_CAN4); //start the transmissions again
01189    // VICSoftInt = 1<<23;   //Force CAN4 TX interrupt     // **** TEST CODE ****
01190   }
01191   can_status4 = C4ICR; //save state of capture register 
01192   
01193   if (can_status4 & (((1<<2)|(1<<3)|(1<<5)|(1<<7))&0x7FF))
01194   {
01195     if (can_status4 & (1<<2))
01196     {
01197       can_error_4 = ERROR_CAN4_ERR_WARN;
01198       error_occurred_irq(ERROR_CAN4_ERR_WARN);  // Shows change in error or bus status bits in either direction
01199     }
01200     if (can_status4 & (1<<3))
01201     {
01202       can_error_4 = ERROR_CAN4_DATA_OVRN;
01203       error_occurred_irq(ERROR_CAN4_DATA_OVRN);  // Receive data overrun on CAN4 - receive buffer not read before
01204                                                     // arrival of next received frame, data lost
01205     }
01206     if (can_status4 & (1<<5))
01207     {
01208       can_error_4 = ERROR_CAN4_ERR_PASS;
01209       error_occurred_irq(ERROR_CAN4_ERR_PASS);  // Shows change in active or passive error status in either direction
01210     }
01211     if (can_status4 & (1<<7))
01212     {
01213       if (can_status4 & (1<<21))
01214       {
01215         can_error_4 = ERROR_CAN4_BUS_RX;
01216         error_occurred_irq(ERROR_CAN4_BUS_RX);  // CAN4 has detected an rx bus error. Details of the error require reading
01217                                                   // the other bits in can_status1. For now that has to be done in the debugger,
01218                                                   // including all the possiblities in the ERROR_IDs would be cumbersome.
01219                                                   // But we could make a non-error CAN_FRAME dedicated to the CAN error status register,
01220                                                   // if we wanted.
01221       }
01222       else
01223       {
01224         can_error_4 = ERROR_CAN4_BUS_TX;
01225         error_occurred_irq(ERROR_CAN4_BUS_TX);
01226       }
01227     }
01228   }
01229  #endif
01230   //To do? Put software interrupt force bits for all tx channels here? What about 2-channel MCUs vs. 4-channel?
01231 
01232   VICVectAddr = 0;
01233 }
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3