Subversion Repositories HomeAutomation

Rev

Rev 73 | Go to most recent revision | Blame | Last modification | View Log | SVN | RSS feed

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