Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CAN Interface. This is a general high-level interface for CAN communication.
  3.  * Underlying CAN controllers are abstracted by this interface, so the
  4.  * application needs not work directly against the CAN controllers.
  5.  *
  6.  * @date    2006-11-19
  7.  *
  8.  * @author  Jimmy Myhrman
  9.  * @author  Martin Thomas
  10.  *  
  11.  */
  12.  
  13. /*-----------------------------------------------------------------------------
  14.  * Includes
  15.  *---------------------------------------------------------------------------*/
  16. #include <string.h>
  17. #include <can.h>
  18. #include "timebase.h"
  19.  
  20.  
  21. #ifdef CAN_CONTROLLER_MCP2515
  22.     #include "mcp2515.h"
  23. #else
  24.     #error No CAN controller specified! Edit can_cfg.h !
  25. #endif
  26.  
  27.  
  28. /*-----------------------------------------------------------------------------
  29.  * Functions
  30.  *---------------------------------------------------------------------------*/
  31.  
  32. /**
  33.  * Initializes the CAN interface. Edit can_cfg.h to choose bitrate.
  34.  *
  35.  * @return
  36.  *      CAN_OK if initialization was successful.
  37.  *      CAN_FAILINIT otherwise.
  38.  */
  39. Can_Return_t Can_Init() {
  40.     Can_Bitrate_t bitrate = CAN_BITRATE;
  41. #ifdef CAN_CONTROLLER_MCP2515
  42.     if (MCP2515_Init(bitrate) != MCP2515_OK) {
  43.         return CAN_FAILINIT;
  44.     }
  45.     if (MCP2515_SetCanCtrlMode(MODE_NORMAL) != MCP2515_OK) {
  46.         return CAN_FAILINIT;
  47.     }
  48.     return CAN_OK;
  49. #endif
  50.  
  51.     return CAN_FAILINIT;
  52.    
  53. }
  54.  
  55.  
  56. /**
  57.  * Sends a CAN message. If the CAN controller is busy, the message will be
  58.  * copied to an internal transmission queue and transmitted later.
  59.  *
  60.  * @param msg
  61.  *      Pointer to the CAN message storage buffer.
  62.  * @return
  63.  *      CAN_OK if the message was successfully sent (or put in queue).
  64.  *      CAN_FAILTX if the controller is busy AND the transmission queue is full.
  65.  */
  66. Can_Return_t Can_Send(Can_Message_t* msg) {
  67.  
  68. #ifdef CAN_CONTROLLER_MCP2515
  69.     uint8_t res, txbuf_n;
  70.     res = MCP2515_GetNextFreeTXBuf(&txbuf_n); // info = addr.
  71.     if (res == MCP_ALLTXBUSY) {
  72.         return CAN_FAILTX;
  73.     }
  74.     MCP2515_WriteCanMsg(txbuf_n, msg);
  75.     MCP2515_StartTransmit(txbuf_n);
  76.     return CAN_OK;
  77. #endif
  78.  
  79. }
  80.  
  81.  
  82. /**
  83.  * Pulls a message from the internal CAN interface reception queue. Unless this queue
  84.  * is empty, a CAN message is moved from the queue into the message storage provided
  85.  * by the calling function.
  86.  *
  87.  * @param msg
  88.  *      Pointer to the message storage buffer.
  89.  * @return
  90.  *      CAN_OK if a received message was successfully copied into the buffer.
  91.  *      CAN_NOMSG if there are no received messages available.
  92.  */
  93. Can_Return_t Can_Receive(Can_Message_t *msg) {
  94.    
  95. #ifdef CAN_CONTROLLER_MCP2515
  96.     uint8_t stat, res;
  97.     stat = MCP2515_ReadStatus();
  98.     if (stat & MCP_STAT_RX0IF) {
  99.         // Msg in Buffer 0
  100.         MCP2515_ReadCanMsg( MCP_RXBUF_0, msg);
  101.         MCP2515_ModifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
  102.         res = CAN_OK;
  103.     }
  104.     else if (stat & MCP_STAT_RX1IF) {
  105.         // Msg in Buffer 1
  106.         MCP2515_ReadCanMsg( MCP_RXBUF_1, msg);
  107.         MCP2515_ModifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
  108.         res = CAN_OK;
  109.     }
  110.     else {
  111.         res = CAN_NOMSG;
  112.     }  
  113.     return res;
  114. #endif
  115.  
  116. }
  117.  
  118.  
  119. /**
  120.  * Checks if there are any received CAN messages waiting in the reception queue.
  121.  *
  122.  * @return
  123.  *      CAN_MSGAVAIL if there are messages available.
  124.  *      CAN_NOMSG if the queue is empty.
  125.  */
  126. Can_Return_t Can_ReceiveAvailable(void) {
  127.    
  128. #ifdef CAN_CONTROLLER_MCP2515
  129.     uint8_t res;
  130.     res = MCP2515_ReadStatus(); // RXnIF in Bit 1 and 0
  131.     if ( res & MCP_STAT_RXIF_MASK ) {
  132.         return CAN_MSGAVAIL;
  133.     }
  134.     else {
  135.         return CAN_NOMSG;
  136.     }
  137. #endif
  138.  
  139. }
  140.  
  141.  
  142. /*
  143.  * Checks Controller-Error-State.
  144.  *
  145.  * @return
  146.  *      CAN_OK if the controller is OK.
  147.  *      CAN_CTRLERROR if errors have occured.
  148.  * @todo
  149.  *      Styr upp denna funktion lite bättre.
  150.  */
  151. Can_Return_t Can_CheckError(void) {
  152.    
  153. #ifdef CAN_CONTROLLER_MCP2515
  154.     uint8_t eflg = MCP2515_ReadRegister(MCP_EFLG);
  155.     if (eflg & MCP_EFLG_ERRORMASK) {
  156.         return CAN_CTRLERROR;
  157.     }
  158.     else {
  159.         return CAN_OK;
  160.     }
  161. #endif
  162.  
  163. }
  164.