Subversion Repositories HomeAutomation

Rev

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

  1. /*********************************************************************
  2.  *
  3.  *                  CAN driver
  4.  *
  5.  *********************************************************************
  6.  * FileName:        CAN.c
  7.  *
  8.  * Author               Date    Comment
  9.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10.  * Johan Böhlin     21-10-06    Original        (Rev 1.0)
  11.  ********************************************************************/
  12.  
  13. #include "../Include/CANdefs.h"
  14. #include "../Include/stackTasks.h"
  15. #include "../Include/CAN.h"
  16. #include "../Include/uart.h"
  17.  
  18. static void canGetPacket(void);
  19.  
  20. #ifdef USE_CAN
  21.  
  22.  
  23. /*
  24. *   Function: canInit
  25. *
  26. *   Input:  none
  27. *   Output: none
  28. *   Pre-conditions: none
  29. *   Affects: Changes can registers.
  30. *   Depends: none.
  31. */
  32. void canInit()
  33. {
  34.     CANCON = 0x80; //request config mode
  35.     while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
  36.  
  37.     // BAUD AND TQS
  38.  
  39.     BRGCON1=0;
  40.    
  41.     // Sync_Seq = 2 x TQ = 1
  42.     BRGCON1bits.SJW1=0;
  43.     BRGCON1bits.SJW0=1;
  44.    
  45.     // Setting BRP.
  46.     BRGCON1=BRGCON1|CAN_BRP;
  47.    
  48.     // Maximum PHEG1
  49.     BRGCON2bits.SEG2PHTS = 1;
  50.    
  51.     // Phase_Seg1 = 2 x TQ = 1
  52.     BRGCON2bits.SEG1PH2 = 0;
  53.     BRGCON2bits.SEG1PH1 = 0;
  54.     BRGCON2bits.SEG1PH0 = 1;
  55.    
  56.     // Prop_Seq = 2 x TQ = 1
  57.     BRGCON2bits.PRSEG2 = 0;
  58.     BRGCON2bits.PRSEG1 = 0;
  59.     BRGCON2bits.PRSEG0 = 1;
  60.    
  61.     //  Enableing bus wake-up
  62.     BRGCON3bits.WAKDIS = 0;
  63.    
  64.     // Dont use filter when wakeup
  65.     BRGCON3bits.WAKFIL = 0;
  66.    
  67.     // Phase_Seg2 = 2 x TQ = 1
  68.     BRGCON3bits.SEG2PH2 = 0;
  69.     BRGCON3bits.SEG2PH1 = 0;
  70.     BRGCON3bits.SEG2PH0 = 1;
  71.  
  72.     ECANCON=0;
  73.     ECANCONbits.MDSEL1 = 0;
  74.     ECANCONbits.MDSEL0 = 1;
  75.  
  76.  
  77.     // FILTERS AND MASKS
  78.     RXB0CONbits.RXM1=1;
  79.     RXB0CONbits.RXM0=0;
  80.  
  81.  
  82.     // INTERRUPTS
  83.    
  84.     // Diable transmit interrupt
  85.     TXBIE = 0;
  86.  
  87.     //rx any interrupt
  88.     PIR3 = 0;
  89.     PIE3 = 0b00000011;
  90.  
  91.     // High interrupt
  92.     IPR3 =0b00000011;
  93.  
  94.     // Programmable buffers interrupt
  95.     BIE0  = 0xFF;  
  96.  
  97.  
  98.     //loopback mode or not
  99.     #ifdef CAN_LOOPBACK_MODE
  100.         CANCON = 0x40;//request loopback mode
  101.         while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
  102.     #else
  103.         CANCON = 0x00;//request normal mode
  104.         while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
  105.     #endif
  106.  
  107. }
  108.  
  109.  
  110. /*
  111. *   Function: canISR
  112. *
  113. *   Input:  none
  114. *   Output: none
  115. *   Pre-conditions: a call to canInit()
  116. *   Affects: interrupt registers and receive data buffers
  117. *   Depends: ..
  118. */
  119. void canISR()
  120. {
  121.    
  122.  
  123.     if (PIR3bits.RXBnIF || PIR3bits.RXB1IF || PIR3bits.RXB0IF)
  124.     {
  125.         // Get which buffer that is ful.
  126.              if (RXB0CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10000; canGetPacket(); }
  127.         else if (RXB1CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10001; canGetPacket(); }
  128.         else if (B0CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10010; canGetPacket(); }
  129.         else if (B1CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10011; canGetPacket(); }
  130.         else if (B2CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10100; canGetPacket(); }
  131.         else if (B3CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10101; canGetPacket(); }
  132.         else if (B4CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10110; canGetPacket(); }
  133.         else if (B5CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10111; canGetPacket(); }
  134.    
  135.         if (PIR3bits.RXBnIF) {PIR3bits.RXBnIF = 0;}
  136.         if (PIR3bits.RXB1IF) {PIR3bits.RXB1IF = 0;}
  137.         if (PIR3bits.RXB0IF) {PIR3bits.RXB0IF = 0;}
  138.    
  139.     }
  140. }
  141.  
  142.  
  143. /*
  144. *   Function: canGetPacket
  145. *
  146. *   Input:  none
  147. *   Output: none
  148. *   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
  149. *   Affects: Calls canParse() function in main for parsing received packet.
  150. *   Depends: none.
  151. */
  152. void canGetPacket()
  153. {
  154.         CAN_MESSAGE cm;
  155.  
  156.         // Set extended mode or not.
  157.         cm.extended=(RXB0SIDLbits.EXID==0?FALSE:TRUE);
  158.  
  159.         // Clear
  160.         cm.ident=0;
  161.  
  162.  
  163.         if (cm.extended==TRUE)
  164.         {
  165.             //Read extended ident.
  166.  
  167.             //xx xx xx 28 27 26 25 24   23 22 21 20 19 18 17 16   15 14 13 12 11 10 09 08   07 06 05 04 03 02 01 00
  168.  
  169.             //RXB0SIDH 28 27 26 25 24 23 22 21
  170.             //RXB0SIDL 20 19 18 xx xx xx 17 16
  171.             //RXB0EIDH 15 14 13 12 11 10 09 08
  172.             //RXB0EIDL 07 06 05 04 03 02 01 00
  173.  
  174.  
  175.             cm.ident = (((DWORD)RXB0SIDH)<<21) + (((DWORD)(RXB0SIDL & 0xE0))<<13) + (((DWORD)(RXB0SIDL & 0x03))<<16) + (((DWORD)RXB0EIDH)<<8) + (BYTE)RXB0EIDL;
  176.  
  177.         }
  178.         else
  179.         {
  180.             //Read standard ident.
  181.  
  182.             //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
  183.  
  184.             //RXB0SIDH 10 09 08 07 06 05 04 03
  185.             //RXB0SIDL 02 01 00 xx xx xx xx xx
  186.  
  187.             cm.ident = (((DWORD)RXB0SIDH)<<3) + (((DWORD)RXB0SIDL)>>5);
  188.         }
  189.  
  190.         // Data length
  191.         cm.data_length=RXB0DLC;
  192.  
  193.         // Data one bye one, for speed
  194.         cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
  195.         cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
  196.         cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
  197.         cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
  198.  
  199.         // Clear ful status
  200.         RXB0CONbits.RXFUL=0;
  201.  
  202.         //Call main parser
  203.         canParse(cm);
  204. }
  205.  
  206.  
  207. /*
  208. *   Function: canSendMessage
  209. *
  210. *   Input:  CAN_MESSAGE to send
  211. *   Output: True if packet scheduled sucess, false otherwise.
  212. *   Pre-conditions: canInit
  213. *   Affects: ..
  214. *   Depends: ..
  215. */
  216. BOOL canSendMessage(CAN_MESSAGE cm)
  217. {
  218.    
  219.     if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
  220.     if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
  221.     if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
  222.     // None of the transmit buffers were empty.
  223.     else { return FALSE;}
  224.  
  225.  
  226.         if (cm.extended==TRUE)
  227.         {
  228.             //Write extended ident.
  229.    
  230.             //xx xx xx 28 27 26 25 24   23 22 21 20 19 18 17 16   15 14 13 12 11 10 09 08   07 06 05 04 03 02 01 00
  231.  
  232.             //RXB0SIDH 28 27 26 25 24 23 22 21
  233.             //RXB0SIDL 20 19 18 xx xx xx 17 16
  234.             //RXB0EIDH 15 14 13 12 11 10 09 08
  235.             //RXB0EIDL 07 06 05 04 03 02 01 00
  236.  
  237.  
  238.             RXB0SIDH =  (BYTE)((cm.ident>>21));
  239.             RXB0SIDL = ((BYTE)(cm.ident>>16) & 0x03) + ((BYTE)(cm.ident>>13) & 0xE0);
  240.             RXB0EIDH =  (BYTE)(cm.ident>>8);
  241.             RXB0EIDL =  (BYTE)cm.ident;
  242.  
  243.         }
  244.         else
  245.         {
  246.             //Write standard ident.
  247.        
  248.             //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
  249.  
  250.             //RXB0SIDH 10 09 08 07 06 05 04 03
  251.             //RXB0SIDL 02 01 00 xx xx xx xx xx
  252.  
  253.             RXB0SIDH=  (BYTE)(cm.ident>>3);
  254.             RXB0SIDL= ((BYTE)(cm.ident<<5) & 0xE0);
  255.  
  256.         }
  257.  
  258.         // Data length
  259.         if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
  260.  
  261.         // Data one bye one, for speed
  262.         RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
  263.         RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
  264.         RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
  265.         RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
  266.  
  267.         // set extended or not
  268.         RXB0SIDLbits.EXID=(cm.extended==TRUE?1:0);
  269.  
  270.  
  271.         // mark as redy to transmit
  272.         _asm
  273.             bsf RXB0CON, 3, 0
  274.         _endasm
  275.  
  276.         return TRUE;
  277.  
  278. }
  279.  
  280.  
  281.  
  282. #endif //USE_CAN
  283.