Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. #include "../Include/CANdefs.h"
  2. #include "../Include/stackTasks.h"
  3. #include "../Include/CAN.h"
  4. #include "../Include/uart.h"
  5.  
  6.  
  7. #ifdef USE_CAN
  8.  
  9.  
  10.  
  11.  
  12. /*
  13. *   Function: canInit
  14. *
  15. *   Input:  none
  16. *   Output: none
  17. *   Pre-conditions: none
  18. *   Affects: Changes can registers.
  19. *   Depends: none.
  20. */
  21. void canInit()
  22. {
  23.  
  24.     // 1. Ensure that the ECAN module is in Configuration mode.
  25.     CANCON=0;
  26.  
  27.     CANCONbits.REQOP2=1; // Request configruation mode
  28.     while(!CANSTATbits.OPMODE2); // Wait for configuration mode
  29.  
  30.     //2. Select ECAN operational mode.
  31.     #ifdef CAN_ENCHANCED_MODE
  32.         // Use Mode 1: Enchanged Legacy mode
  33.         // ECANCON.MDSEL1:MDSEL0 = 1
  34.         ECANCONbits.MDSEL1 = 0;
  35.         ECANCONbits.MDSEL0 = 1;
  36.     #else
  37.         // Use Mode 0: Legacy mode
  38.         // ECANCON.MDSEL1:MDSEL0 = 0
  39.         ECANCONbits.MDSEL1 = 0;
  40.         ECANCONbits.MDSEL0 = 0;
  41.     #endif
  42.  
  43.  
  44.     // BUFFERS
  45.    
  46.     // Make all programmable buffers receive buffers
  47.     BSEL0 = 0x00;
  48.    
  49.     // Setup the receive buffers
  50.     RXB0CON = 0;
  51.     RXB1CON = 0;
  52.     B0CON = 0;
  53.     B1CON = 0;
  54.     B2CON = 0;
  55.     B3CON = 0;
  56.     B4CON = 0;
  57.     B5CON = 0;
  58.  
  59.  
  60.  
  61.     //3. Set up the baud rate registers.
  62.     // Times for different time segments:
  63.     // Sync_Seq + Prop_Seq + Phase_Seg1 + Phase_Seg2 = 8
  64.     // Sync_Seq = 2, Prop_Seq = 2, Phase_Seg1 = 2, Phase_Seg2 = 2
  65.     // BRGCON1.SJW1:SJW0 = 1
  66.     // BRGCON1.BRP5:BRP0 = CAN_BRP
  67.     // BRGCON2.SEG2PHTS = 0 //Maximum PHEG1
  68.     // BRGCON2.SEG1PH2:SEG1PH0 = 1
  69.     // BRGCON2.PRSEG2:PRSEG0 = 1
  70.     // BRGCON3.WAKDIS = 1/0  1=Dsiable CAN bus wake up
  71.     // BRGCON3.WAKFIL = 1/0  1=Use filter on wake up
  72.     // BRGCON3.SEG2PH2:SEG2PH0 = 1
  73.    
  74.     BRGCON1=0;
  75.    
  76.     // Sync_Seq = 2 x TQ = 1
  77.     BRGCON1bits.SJW1=0;
  78.     BRGCON1bits.SJW0=1;
  79.    
  80.     // Setting BRP.
  81.     BRGCON1=BRGCON1|CAN_BRP;
  82.    
  83.     // Maximum PHEG1
  84.     BRGCON2bits.SEG2PHTS = 1;
  85.    
  86.     // Phase_Seg1 = 2 x TQ = 1
  87.     BRGCON2bits.SEG1PH2 = 0;
  88.     BRGCON2bits.SEG1PH1 = 0;
  89.     BRGCON2bits.SEG1PH0 = 1;
  90.    
  91.     // Prop_Seq = 2 x TQ = 1
  92.     BRGCON2bits.PRSEG2 = 0;
  93.     BRGCON2bits.PRSEG1 = 0;
  94.     BRGCON2bits.PRSEG0 = 1;
  95.    
  96.     //  Enableing bus wake-up
  97.     BRGCON3bits.WAKDIS = 0;
  98.    
  99.     // Dont use filter when wakeup
  100.     BRGCON3bits.WAKFIL = 0;
  101.    
  102.     // Phase_Seg2 = 2 x TQ = 1
  103.     BRGCON3bits.SEG2PH2 = 0;
  104.     BRGCON3bits.SEG2PH1 = 0;
  105.     BRGCON3bits.SEG2PH0 = 1;
  106.    
  107.    
  108.     //4. Set up the filter and mask registers.
  109.    
  110.     // Disable all filters
  111.     RXFCON0 = 0;
  112.     RXFCON1 = 0;
  113.  
  114.  
  115.     // No data byte filtering
  116.     SDFLC = 0;
  117.    
  118.     // Setup filter/buffer association, two filters per buffer
  119.     RXFBCON0 = 0x00;
  120.     RXFBCON1 = 0x11;
  121.     RXFBCON2 = 0x22;
  122.     RXFBCON3 = 0x33;
  123.     RXFBCON4 = 0x44;
  124.     RXFBCON5 = 0x55;
  125.     RXFBCON6 = 0x66;
  126.     RXFBCON7 = 0x77;
  127.  
  128.     // Setup filter/mask association to Mask 0
  129.     MSEL0 = MSEL1 = MSEL2 = MSEL3 = 0;
  130.    
  131.     // Set Mask 0 to not mask any filter bit
  132.     RXM0SIDH = 0xFF;
  133.     RXM0SIDL = 0xE3;
  134.     RXM0EIDH = 0xFF;
  135.     RXM0EIDL = 0xFF;   
  136.    
  137.     // Set I/O control CANTX pin will drive VDD when recessive
  138.     CIOCON = 0x20;
  139.  
  140.     // Set interrupts  
  141.     // Diable transmit interrupt
  142.     TXBIE = 0;
  143.  
  144.     //rx any interrupt
  145.     PIR3 = 0;
  146.     PIE3 = 0b00000011;
  147.  
  148.     // High interrupt
  149.     IPR3 =0b00000011;
  150.  
  151.     // Programmable buffers interrupt
  152.     BIE0  = 0xFF;  
  153.  
  154.     //5. Set the ECAN module to normal mode or any other mode required by the application logic.
  155.     #ifdef CAN_LOOPBACK_MODE
  156.         // Use Loopback mode
  157.         CANCON=0b01000000;
  158.     #else
  159.         // Use Normal mode
  160.         CANCON=0b00000000;
  161.     #endif
  162.  
  163.     while(CANSTATbits.OPMODE2); // Wait for configuration mode
  164. }
  165.  
  166.  
  167. /*
  168. *   Function: canISR
  169. *
  170. *   Input:  none
  171. *   Output: none
  172. *   Pre-conditions: a call to canInit()
  173. *   Affects: interrupt registers and receive data buffers
  174. *   Depends: ..
  175. */
  176. void canISR()
  177. {
  178.     BYTE defECANCON;
  179.  
  180.  
  181.     if (PIR3bits.RXBnIF==1 && PIE3bits.RXBnIE==1 || PIR3bits.RXB1IF==1 || PIR3bits.RXB0IF==1)
  182.     {
  183.         uartPutrs("canISR!");
  184.  
  185.  
  186.         // Save default ECANCON
  187.         #ifdef CAN_ENCHANCED_MODE
  188.             defECANCON=(ECANCON&0b00000)|0b10000;
  189.         #else
  190.             defECANCON=(CANCON&0b000)|0b000;
  191.         #endif
  192.  
  193.              if (RXB0CONbits.RXFUL==1)  
  194.             {          
  195.                 #ifdef CAN_ENCHANCED_MODE
  196.                     ECANCON = defECANCON|0b10000;
  197.                 #else
  198.                     CANCON = defECANCON|0b000;
  199.                 #endif
  200.  
  201.                 canGetPacket();
  202.                 RXB0CONbits.RXFUL=0;
  203.             }
  204.         else if (RXB1CONbits.RXFUL==1)  
  205.         {
  206.  
  207.             #ifdef CAN_ENCHANCED_MODE
  208.                 ECANCON = defECANCON|0b10001;
  209.             #else
  210.                 CANCON = defECANCON|0b101;
  211.             #endif 
  212.    
  213.             canGetPacket();
  214.             RXB1CONbits.RXFUL=0;
  215.         }
  216.         #ifdef CAN_ENCHANCED_MODE
  217.             else if (B0CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10010; canGetPacket(); B0CONbits.RXFUL=0; }
  218.             else if (B1CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10011; canGetPacket(); B1CONbits.RXFUL=0; }
  219.             else if (B2CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10100; canGetPacket(); B2CONbits.RXFUL=0; }
  220.             else if (B3CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10101; canGetPacket(); B3CONbits.RXFUL=0; }
  221.             else if (B4CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10110; canGetPacket(); B4CONbits.RXFUL=0; }
  222.             else if (B5CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10111; canGetPacket(); B5CONbits.RXFUL=0; }
  223.         #endif
  224.         else {PIR3bits.RXBnIF=0; PIR3bits.RXB1IF=0; PIR3bits.RXB0IF=0; return;}
  225.  
  226.         // Restore mapping
  227.         #ifdef CAN_ENCHANCED_MODE
  228.             ECANCON = defECANCON;
  229.         #else
  230.             CANCON = defECANCON;
  231.         #endif 
  232.  
  233.         PIR3bits.RXBnIF=0;
  234.     }
  235.  
  236. }
  237. /*
  238. *   Function: canGetPacket
  239. *
  240. *   Input:  none
  241. *   Output: none
  242. *   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
  243. *   Affects: Calls canParse() function in main for parsing received packet.
  244. *   Depends: none.
  245. */
  246. void canGetPacket()
  247. {
  248.         CAN_MESSAGE cm;
  249.  
  250.         // Set extended mode or not.
  251.         cm.extended=RXB0SIDLbits.EXID;
  252.  
  253.         // Clear
  254.         cm.ident[0]=cm.ident[1]=cm.ident[2]=cm.ident[3]=0;
  255.  
  256.  
  257.         if (cm.extended==TRUE)
  258.         {
  259.             //Read extended ident.
  260.             cm.ident[0]=RXB0EIDL;
  261.             cm.ident[1]=RXB0EIDH;
  262.             cm.ident[2]=(RXB0SIDL & 0b00000011)+((RXB0SIDL & 0b11100000)>3)+((RXB0SIDH & 0b00000111)<5);
  263.             cm.ident[3]=RXB0SIDH>3;
  264.         }
  265.         else
  266.         {
  267.             //Read standard ident.
  268.             cm.ident[0]=((RXB0SIDL & 0b11100000)>5)+(RXB0SIDH>2);
  269.             cm.ident[1]=RXB0SIDH>5;
  270.         }
  271.  
  272.         // Data length
  273.         cm.data_length=RXB0DLC;
  274.  
  275.         // Data one bye one, for speed
  276.         cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
  277.         cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
  278.         cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
  279.         cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
  280.  
  281.  
  282.         //Call main parser
  283.         canParse(cm);
  284.  
  285.         //RXBnCON.RXFUL to know if there actually is a message.
  286.         //RXB0 och RXB1 (0 <= n <= 1)
  287.         //RXBnCON.FILHIT  do determine filter hit.
  288.  
  289.         //EXID =  1:extended frame
  290.         //RXBnSIDH  = high standard ident (bit10->bit3 if standard, bit28->bit21 if ext)
  291.         //RXBnSIDL(7:5) = low standard ident (bit2->bit0 if standard, bit20->bit18 if ext)
  292.         //RXBnSIDL(1:0) = low standard ident (bit17->bit16 if ext)
  293.         //RXBnEIDH      = high extended ident (bit15->bit8)
  294.         //RXBnEIDL      = low extended ident (bit7->bit0)
  295.         //RXBnDLC = Data length
  296.         //RXBnDm = Data bytes. (0 <= m <= 7)
  297.  
  298.         // Same for Bn...  (1 <= n <= 5)
  299.  
  300. }
  301.  
  302.  
  303. /*
  304. *   Function: canSendMessage
  305. *
  306. *   Input:  CAN_MESSAGE to send
  307. *   Output: True if packet scheduled sucess, false otherwise.
  308. *   Pre-conditions: canInit
  309. *   Affects: ..
  310. *   Depends: ..
  311. */
  312. BOOL canSendMessage(CAN_MESSAGE cm)
  313. {
  314.     BYTE defECANCON;
  315.    
  316.     // Save default ECANCON
  317.     #ifdef CAN_ENCHANCED_MODE
  318.         defECANCON=(ECANCON&0b00000)|0b10000;
  319.     #else
  320.         defECANCON=(CANCON&0b000)|0b100;
  321.     #endif
  322.  
  323.     // Find the first empty transmitter.
  324.     if ( TXB0CONbits.TXREQ == 0 )
  325.     {
  326.         // TxBuffer0 is empty. Set EWIN bits to point to TXB0
  327.         #ifdef CAN_ENCHANCED_MODE
  328.             ECANCON=(defECANCON&0b00000)|0b00011;
  329.         #else
  330.             //CANCON=(defECANCON&0b000)|0b100;
  331.         #endif
  332.     }
  333.     else if ( TXB1CONbits.TXREQ == 0 )
  334.     {
  335.         // TxBuffer1 is empty. Set EWIN bits to point to TXB1
  336.         #ifdef CAN_ENCHANCED_MODE
  337.             ECANCON=(defECANCON&0b00000)|0b00100;
  338.         #else
  339.             //CANCON=(defECANCON&0b000)|0b011;
  340.         #endif
  341.     }
  342.     else if ( TXB2CONbits.TXREQ == 0 )
  343.     {
  344.         // TxBuffer2 is empty. Set EWIN bits to point to TXB2
  345.         #ifdef CAN_ENCHANCED_MODE
  346.             ECANCON=(defECANCON&0b00000)|0b00101;
  347.         #else
  348.             //CANCON=(defECANCON&0b000)|0b010;
  349.         #endif
  350.     }
  351.     // None of the transmit buffers were empty.
  352.     else { return FALSE;}
  353.  
  354.  
  355.  
  356.         uartPutrs("Sending..");
  357.  
  358.         // Set extended mode or not.
  359.         TXB0SIDLbits.EXIDE=cm.extended;
  360.  
  361.         if (cm.extended==TRUE)
  362.         {
  363.             //Write extended ident.
  364.             TXB0SIDH=(cm.ident[3]<3)+(cm.ident[2]>5);
  365.             TXB0SIDL=(TXB0SIDL & 0b00011100)+((cm.ident[2] & 0b0001100)<3)+(cm.ident[2] & 0b00000011);
  366.             TXB0EIDH=cm.ident[1];
  367.             TXB0EIDL=cm.ident[0];
  368.         }
  369.         else
  370.         {
  371.             //Write standard ident.
  372.             TXB0SIDH=(cm.ident[1]<5)+(cm.ident[0]>3);
  373.             TXB0SIDL=(TXB0SIDL & 0b00011111)+(cm.ident[0]<5);
  374.         }
  375.  
  376.         // Data length
  377.         if (cm.data_length>8) TXB0DLC=8; else TXB0DLC=cm.data_length;
  378.  
  379.         // Data one bye one, for speed
  380.         TXB0D0=cm.data[0];  TXB0D1=cm.data[1];
  381.         TXB0D2=cm.data[2];  TXB0D3=cm.data[3];
  382.         TXB0D4=cm.data[4];  TXB0D5=cm.data[5];
  383.         TXB0D6=cm.data[6];  TXB0D7=cm.data[7];
  384.  
  385.         // mark as redy to transmit
  386.         TXB0CONbits.TXREQ=1;
  387.  
  388.         uartPutrs("While");
  389.         while(TXB0CONbits.TXREQ);
  390.         uartPutrs("after");
  391.  
  392.  
  393. /*
  394.         // Set extended mode or not.
  395.         //RXB0SIDLbits.EXID=cm.extended;
  396.         if (cm.extended==TRUE)
  397.         {
  398.             _asm
  399.                 bsf RXB0SIDL, 3, 0
  400.             _endasm
  401.         }
  402.         else
  403.         {
  404.             _asm
  405.                 bcf RXB0SIDL, 3, 0
  406.             _endasm
  407.         }
  408.  
  409.  
  410.         if (cm.extended==TRUE)
  411.         {
  412.             //Write extended ident.
  413.             RXB0SIDH=(cm.ident[3]<3)+(cm.ident[2]>5);
  414.             RXB0SIDL=(RXB0SIDL & 0b00011100)+((cm.ident[2] & 0b0001100)<3)+(cm.ident[2] & 0b00000011);
  415.             RXB0EIDH=cm.ident[1];
  416.             RXB0EIDL=cm.ident[0];
  417.         }
  418.         else
  419.         {
  420.             //Write standard ident.
  421.             RXB0SIDH=(cm.ident[1]<5)+(cm.ident[0]>3);
  422.             RXB0SIDL=(RXB0SIDL & 0b00011111)+(cm.ident[0]<5);
  423.         }
  424.  
  425.         // Data length
  426.         if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
  427.  
  428.         // Data one bye one, for speed
  429.         RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
  430.         RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
  431.         RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
  432.         RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
  433.  
  434.         // mark as redy to transmit
  435.         _asm
  436.             bsf RXB0CON, 3, 0
  437.         _endasm
  438.  
  439.         // restore mapping
  440.         #ifdef CAN_ENCHANCED_MODE
  441.             ECANCON = defECANCON;
  442.         #else
  443.             CANCON = defECANCON;
  444.         #endif
  445. */
  446.        
  447.        
  448.  
  449.        
  450.         return TRUE;
  451.  
  452. }
  453.  
  454.  
  455. #endif //USE_CAN
  456.