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