Subversion Repositories HomeAutomation

Rev

Rev 260 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*********************************************************************
  2.  *
  3.  *                  CAN driver
  4.  *
  5.  *********************************************************************
  6.  * FileName:        $HeadURL: https://svn.auml.se/svn/HomeAutomation/branches/modules/EmbeddedSoftware/PIC/canToSerial/Source/CAN.c $
  7.  * Last changed:    $LastChangedDate: 2007-01-28 14:58:11 +0100 (Sun, 28 Jan 2007) $
  8.  * By:              $LastChangedBy: johboh $
  9.  * Revision:        $Revision: 260 $
  10.  ********************************************************************/
  11.  
  12. #include <CANdefs.h>
  13. #include <stackTasks.h>
  14. #include <CAN.h>
  15.  
  16. static void canGetPacket(void);
  17.  
  18. #ifdef USE_CAN
  19.  
  20.  
  21. /*
  22. *   Function: canInit
  23. *
  24. *   Input:  none
  25. *   Output: none
  26. *   Pre-conditions: none
  27. *   Affects: Changes can registers.
  28. *   Depends: none.
  29. */
  30. void canInit()
  31. {
  32.     CANCON = 0x80; //request config mode
  33.     while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
  34.  
  35.     // BAUD AND TQS
  36.  
  37.     //BRGCON1 = 0x03;    //500Kbit@40MHz 1TQ Sync, 2TQ Prop, 4TQ Phase1, 3TQ Phase2
  38.     //BRGCON2 = 0x99;
  39.     //BRGCON3 = 0x02;
  40.  
  41.     //75%, 250Kbps @40MHz
  42.     //BRGCON1 = 0x09;
  43.     //BRGCON2 = 0xDB;
  44.     //BRGCON3 = 0x01;
  45.  
  46.     //75% ,1 , 500Kbps @40MHz
  47.     //BRGCON1 = 0x01;
  48.     //BRGCON2 = (0xB6 | 0x80);
  49.     //BRGCON3 = 0x04;
  50.    
  51.     //75% ,1 , 500Kbps @80MHz
  52.     //BRGCON1 = 0x03;
  53.     //BRGCON2 = (0xB6 | 0x80);
  54.     //BRGCON3 = 0x04;
  55.  
  56.     // 500Khz@40Mhz (new by the book)
  57.     BRGCON1 = 0x04;
  58.     BRGCON2 = 0xD1;
  59.     BRGCON3 = 0x81;
  60.  
  61.  
  62.     //BRGCON1=0;
  63.    
  64.     // Sync_Seq = 2 x TQ = 1
  65.     //BRGCON1bits.SJW1=0;
  66.     //BRGCON1bits.SJW0=1;
  67.    
  68.     // Setting BRP.
  69.     //BRGCON1=BRGCON1|CAN_BRP;
  70.    
  71.     // Maximum PHEG1
  72.     //BRGCON2bits.SEG2PHTS = 1;
  73.    
  74.     // Phase_Seg1 = 2 x TQ = 1
  75.     //BRGCON2bits.SEG1PH2 = 0;
  76.     //BRGCON2bits.SEG1PH1 = 0;
  77.     //BRGCON2bits.SEG1PH0 = 1;
  78.    
  79.     // Prop_Seq = 2 x TQ = 1
  80.     //BRGCON2bits.PRSEG2 = 0;
  81.     //BRGCON2bits.PRSEG1 = 0;
  82.     //BRGCON2bits.PRSEG0 = 1;
  83.    
  84.     //  Enableing bus wake-up
  85.     //BRGCON3bits.WAKDIS = 0;
  86.    
  87.     // Dont use filter when wakeup
  88.     //BRGCON3bits.WAKFIL = 0;
  89.    
  90.     // Phase_Seg2 = 2 x TQ = 1
  91.     //BRGCON3bits.SEG2PH2 = 0;
  92.     //BRGCON3bits.SEG2PH1 = 0;
  93.     //BRGCON3bits.SEG2PH0 = 1;
  94.  
  95.     ECANCON=0;
  96.     ECANCONbits.MDSEL1 = 1;
  97.     ECANCONbits.MDSEL0 = 0;
  98.  
  99.  
  100.     // FILTERS AND MASKS
  101.     RXB0CONbits.RXM1=1;
  102.     RXB0CONbits.RXM0=0;
  103.  
  104.     // Set ressesive VDD
  105.     CIOCONbits.ENDRHI = 1;
  106.  
  107.     // INTERRUPTS
  108.    
  109.     // Diable transmit interrupt
  110.     TXBIE = 0;
  111.  
  112.     //rx any interrupt
  113.     PIR3 = 0;
  114.     PIE3 = 0b00000011;
  115.  
  116.     // High interrupt
  117.     IPR3 =0b00000011;
  118.  
  119.     // Programmable buffers interrupt
  120.     BIE0  = 0xFF;  
  121.  
  122.  
  123.     //loopback mode or not
  124.     #ifdef CAN_LOOPBACK_MODE
  125.         CANCON = 0x40;//request loopback mode
  126.         while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
  127.     #else
  128.         CANCON = 0x00;//request normal mode
  129.         while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
  130.     #endif
  131.  
  132. }
  133.  
  134.  
  135. /*
  136. *   Function: canISR
  137. *
  138. *   Input:  none
  139. *   Output: none
  140. *   Pre-conditions: a call to canInit()
  141. *   Affects: interrupt registers and receive data buffers
  142. *   Depends: ..
  143. */
  144. void canISR()
  145. {
  146.     if (PIR3bits.RXBnIF || PIR3bits.RXB1IF || PIR3bits.RXB0IF)
  147.     {
  148.         ECANCON=(ECANCON&0b00000)|(0b10000|(CANCON&0x0F));
  149.         if (RXB0CONbits.RXFUL) canGetPacket();
  150.    
  151.         if (PIR3bits.RXBnIF) {PIR3bits.RXBnIF = 0; return;}
  152.         if (PIR3bits.RXB1IF) {PIR3bits.RXB1IF = 0; return;}
  153.         if (PIR3bits.RXB0IF) {PIR3bits.RXB0IF = 0; return;}
  154.     }
  155. }
  156.  
  157.  
  158. /*
  159. *   Function: canGetPacket
  160. *
  161. *   Input:  none
  162. *   Output: none
  163. *   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
  164. *   Affects: Calls canParse() function in main for parsing received packet.
  165. *   Depends: none.
  166. */
  167. void canGetPacket()
  168. {
  169.         CAN_MESSAGE cm;
  170.  
  171.         // Set extended mode or not.
  172.         cm.extended=(RXB0SIDLbits.EXID==0?FALSE:TRUE);
  173.  
  174.         // Clear
  175.         cm.ident=0;
  176.  
  177.  
  178.         if (cm.extended==TRUE)
  179.         {
  180.             //Read extended ident.
  181.  
  182.             //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
  183.  
  184.             //RXB0SIDH 28 27 26 25 24 23 22 21
  185.             //RXB0SIDL 20 19 18 xx xx xx 17 16
  186.             //RXB0EIDH 15 14 13 12 11 10 09 08
  187.             //RXB0EIDL 07 06 05 04 03 02 01 00
  188.  
  189.  
  190.             cm.ident = (((DWORD)RXB0SIDH)<<21) + (((DWORD)(RXB0SIDL & 0xE0))<<13) + (((DWORD)(RXB0SIDL & 0x03))<<16) + (((DWORD)RXB0EIDH)<<8) + (BYTE)RXB0EIDL;
  191.  
  192.         }
  193.         else
  194.         {
  195.             //Read standard ident.
  196.  
  197.             //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
  198.  
  199.             //RXB0SIDH 10 09 08 07 06 05 04 03
  200.             //RXB0SIDL 02 01 00 xx xx xx xx xx
  201.  
  202.             cm.ident = (((DWORD)RXB0SIDH)<<3) + (((DWORD)RXB0SIDL)>>5);
  203.         }
  204.  
  205.         // Data length
  206.         cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
  207.  
  208.         // Remote request
  209.         cm.remote_request=(RXB0DLCbits.RXRTR==0?FALSE:TRUE);
  210.  
  211.         // Data one bye one, for speed
  212.         cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
  213.         cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
  214.         cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
  215.         cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
  216.  
  217.         // Clear ful status
  218.         RXB0CONbits.RXFUL=0;
  219.  
  220.         //Call main parser
  221.         canParse(cm);
  222. }
  223.  
  224.  
  225. /*
  226. *   Function: canSendMessage
  227. *
  228. *   Input:  CAN_MESSAGE to send
  229. *   Output: True if packet scheduled sucess, false otherwise.
  230. *   Pre-conditions: canInit
  231. *   Affects: ..
  232. *   Depends: ..
  233. */
  234. BOOL canSendMessage(CAN_MESSAGE cm,CAN_PRIORITY prio)
  235. {
  236.    
  237.     if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
  238.     if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
  239.     if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
  240.     // None of the transmit buffers were empty.
  241.     else { return FALSE;}
  242.  
  243.     if (prio<0 || prio>3) prio = 0;
  244.  
  245.  
  246.         if (cm.extended==TRUE)
  247.         {
  248.             //Write extended ident.
  249.    
  250.             //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
  251.  
  252.             //RXB0SIDH 28 27 26 25 24 23 22 21
  253.             //RXB0SIDL 20 19 18 xx xx xx 17 16
  254.             //RXB0EIDH 15 14 13 12 11 10 09 08
  255.             //RXB0EIDL 07 06 05 04 03 02 01 00
  256.  
  257.  
  258.             RXB0SIDH =  (BYTE)((cm.ident>>21));
  259.             RXB0SIDL = ((BYTE)(cm.ident>>16) & 0x03) + ((BYTE)(cm.ident>>13) & 0xE0);
  260.             RXB0EIDH =  (BYTE)(cm.ident>>8);
  261.             RXB0EIDL =  (BYTE)cm.ident;
  262.  
  263.         }
  264.         else
  265.         {
  266.             //Write standard ident.
  267.        
  268.             //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
  269.  
  270.             //RXB0SIDH 10 09 08 07 06 05 04 03
  271.             //RXB0SIDL 02 01 00 xx xx xx xx xx
  272.  
  273.             RXB0SIDH=  (BYTE)(cm.ident>>3);
  274.             RXB0SIDL= ((BYTE)(cm.ident<<5) & 0xE0);
  275.  
  276.         }
  277.  
  278.         // Data length
  279.         RXB0DLC = 0;
  280.         if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
  281.        
  282.         // Remote request
  283.         if (cm.remote_request==TRUE)
  284.         {
  285.             _asm
  286.                 bsf RXB0DLC, 6, 0
  287.             _endasm
  288.         }
  289.         else
  290.         {
  291.             _asm
  292.                 bcf RXB0DLC, 6, 0
  293.             _endasm
  294.         }
  295.  
  296.         // Data one bye one, for speed
  297.         RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
  298.         RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
  299.         RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
  300.         RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
  301.  
  302.         // set extended or not
  303.         RXB0SIDLbits.EXID=(cm.extended==TRUE?1:0);
  304.  
  305.         // Priority
  306.         RXB0CON = (RXB0CON & 0b11111100) | prio;
  307.  
  308.         // mark as redy to transmit
  309.         _asm
  310.             bsf RXB0CON, 3, 0
  311.         _endasm
  312.  
  313.         return TRUE;
  314.  
  315. }
  316.  
  317.  
  318.  
  319. #endif //USE_CAN
  320.