csr_router.c

00001 //Code for SSP - CAN router. CAN frames are received from up to 4 CAN buses and the SSP bus,
00002 //and directed out again as per the bits set in the routing table. Each possible standard CAN address
00003 //from 0 to 2031 (CAN does not permit addresses 2032 through 2047) gets its own routing entry (one byte)
00004 //in the CSR_Routing_Table lookup table. Bit 0 (LSB) indicates that SSP (the main brain) is to receive a
00005 //frame; bit 1 through 4 are for CAN buses 1 through 4, respectively.
00006 
00007 #include <includes.h>
00008 
00009 
00010 
00011 //CAN packet routing table. This can be filled in manually, or by having each
00012 //processor "subscribe" to data types it wants to receive by sending out a request to
00013 //receive (RTR) packet for each data type. Max routing table size would be 11 bits (2048),
00014 //except that CAN does not allow the first (most significant) 7 bits to be all high (recessive), thus limiting
00015 //the top CAN address in standard mode to 0b11111101111 = 2031. (CAN20B.pdf page 13)
00016 
00017 #define CSR_ROUTING_TABLE_SIZE 2032
00018 CSR_ROUTE csr_routing_table[CSR_ROUTING_TABLE_SIZE];
00019 
00020 /*
00022 void can_test_transmitter(void)
00023 {
00024  CAN_FRAME frame;
00025  unsigned short buffer_full = 1;
00026 
00027  frame.rtr = 0;
00028  frame.dlc = 8;
00029  frame.payload.w.w1 = 0xAAAA;
00030  frame.payload.w.w2 = 0x5555;
00031 
00032  //CAN controller 1
00033  frame.addr = 1;
00034  frame.chan = CHAN_CAN1;
00035  buffer_full = can_transmit_frame(&frame);
00036 
00037  //CAN controller 2
00038  frame.addr = 2;
00039  frame.chan = CHAN_CAN2;
00040  buffer_full = can_transmit_frame(&frame);
00041 
00042  //CAN controller 3
00043  frame.addr = 3;
00044  frame.chan = CHAN_CAN3;
00045  buffer_full = can_transmit_frame(&frame);
00046 
00047  //CAN controller 4
00048  frame.addr = 4;
00049  frame.chan = CHAN_CAN4;
00050  buffer_full = can_transmit_frame(&frame);
00051 }
00053 */
00054 
00056 void csr_routing_table_init(void)
00057 {
00058 unsigned short i;
00059 
00060 for (i=0; i<CSR_ROUTING_TABLE_SIZE; ++i)
00061 {
00062   //csr_routing_table[i].destinations = 0;    // default is 0: no data destinations yet included
00063   csr_routing_table[i].destinations = 1 << CHAN_SSP;    // Start with all data going to SSP; may use rtr later with SSP too.
00064                                                         // Now have a check to prevent data from being sent back to its source
00065   csr_routing_table[i].source = 0x7;        // default is 7: no data source yet determined
00066 }
00067 
00068   #include <csr_routing_table.c> // Created by CAN ID parsing script
00069                           
00070 }
00071 
00073 //Route one received CAN frame
00074 unsigned short int csr_route_frame(CAN_FRAME * frameptr)
00075 {
00076   unsigned char dest, src;
00077   unsigned short buffer_full = 0;
00078 
00079   dest = csr_routing_table[frameptr->addr].destinations;  //Get routing information from lookup table
00080   src = csr_routing_table[frameptr->addr].source;
00081 
00082   if (frameptr->rtr)  // Initiate RTR processing; 
00083   {
00084     //Subscribe CAN/SSP channel "chan" to this CAN_ID/address
00085     csr_routing_table[frameptr->addr].destinations |= (1 << frameptr->chan);
00086     
00087     //Activate below code if needed: Additional RTR handling - send RTR frame to data source
00088     //(if not also the source of the RTR frame)
00089     //If data source is not yet defined, send to all except RTR source
00090     /*
00091     //Remote Transfer Request (RTR) frame handling
00092     if (src != 0x7)
00093     {
00094       if (src != frameptr->chan)
00095       {
00096         frameptr->chan = src;
00097         buffer_full = csr_push_ssp_frame(frameptr);
00098       }  
00099     }
00100     else  //send to all but RTR source
00101     {
00102       if (frameptr->chan != CHAN_SSP)
00103       {
00104         frameptr->chan = CHAN_SSP;
00105         buffer_full = csr_push_ssp_frame(frameptr);
00106       }
00107     
00108       if (frameptr->chan != CHAN_CAN1)
00109       {    
00110         frameptr->chan = CHAN_CAN1;
00111         buffer_full = can_transmit_frame(frameptr);
00112       }
00113 
00114       if (frameptr->chan != CHAN_CAN2)
00115       {      
00116         frameptr->chan = CHAN_CAN2;
00117         buffer_full = can_transmit_frame(frameptr);
00118       }
00119 
00120       if (frameptr->chan != CHAN_CAN3)
00121       {    
00122         frameptr->chan = CHAN_CAN3;      
00123         buffer_full = can_transmit_frame(frameptr);
00124       }
00125 
00126       if (frameptr->chan != CHAN_CAN4)
00127       {    
00128         frameptr->chan = CHAN_CAN4;       
00129         buffer_full = can_transmit_frame(frameptr);
00130       }
00131     }
00132     */  
00133   }
00134 
00135   else  //route frame
00136   {
00137   
00138     //Check data source validity.
00139     //Only one data source is permitted per data_id
00140   
00141     if (src != frameptr->chan) // New source channel for this DATA_ID
00142     {
00143       if (src == 0x7)   // 0x7 is default initialized value, updated when data received
00144       {
00145         csr_routing_table[frameptr->addr].source = frameptr->chan;    // Update routing table to include new source
00146         src = frameptr->chan;
00147       }
00148       else  // ERROR - source has changed, or there are multiple sources for frames with this DATA_ID
00149       {
00150         // ERROR call
00151         csr_routing_table[frameptr->addr].source = frameptr->chan;    // Update routing table to use new source instead
00152         src = frameptr->chan;
00153       }
00154     }
00155   
00156     //Push frame onto destination bus ring buffers,
00157     //according to entries in routing table  
00158   
00159       if ((dest & 1<<CHAN_SSP) && (src != CHAN_SSP))
00160       {
00161         frameptr->chan = CHAN_SSP;
00162         buffer_full = csr_push_ssp_frame(frameptr);
00163       }
00164     
00165       if ((dest & 1<<CHAN_CAN1) && (src != CHAN_CAN1))
00166       {    
00167         frameptr->chan = CHAN_CAN1;
00168         buffer_full = csr_can1_tx_push_frame(frameptr);
00169         //buffer_full = can_transmit_frame(frameptr);
00170       }
00171 
00172       if ((dest & 1<<CHAN_CAN2) && (src != CHAN_CAN2))
00173       {      
00174         frameptr->chan = CHAN_CAN2;
00175         buffer_full = csr_can2_tx_push_frame(frameptr);
00176         //buffer_full = can_transmit_frame(frameptr);
00177       }
00178 
00179       if ((dest & 1<<CHAN_CAN3) && (src != CHAN_CAN3))
00180       {    
00181         frameptr->chan = CHAN_CAN3;
00182         buffer_full = csr_can3_tx_push_frame(frameptr);              
00183        // buffer_full = can_transmit_frame(frameptr);
00184       }
00185 
00186       if ((dest & 1<<CHAN_CAN4) && (src != CHAN_CAN4))
00187       {    
00188         frameptr->chan = CHAN_CAN4; 
00189         buffer_full = csr_can4_tx_push_frame(frameptr);     
00190         //buffer_full = can_transmit_frame(frameptr);
00191       }
00192     }
00193   return(buffer_full);
00194 }
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3