Subversion Repositories HomeAutomation

Rev

Rev 59 | 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-10-28
  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.
  34.  *
  35.  * @param bitrate
  36.  *      The bitrate that should be used.
  37.  * @return
  38.  *      CAN_OK if initialization was successful.
  39.  *      CAN_FAILINIT otherwise.
  40.  */
  41. CanReturn_t CanInit(const CanBitrate_t bitrate) {
  42.  
  43. #ifdef CAN_CONTROLLER_MCP2515
  44.     if (mcp2515_init(bitrate) != MCP2515_OK) {
  45.         return CAN_FAILINIT;
  46.     }
  47.     if (mcp2515_setCANCTRL_Mode(MODE_NORMAL) != MCP2515_OK) {
  48.         return CAN_FAILINIT;
  49.     }
  50.     return CAN_OK;
  51. #endif
  52.  
  53.     return CAN_FAILINIT;
  54.    
  55. }
  56.  
  57.  
  58. /**
  59.  * Sends a CAN message. If the CAN controller is busy, the message will be
  60.  * copied to an internal transmission queue and transmitted later.
  61.  *
  62.  * @param msg
  63.  *      Pointer to the CAN message storage buffer.
  64.  * @return
  65.  *      CAN_OK if the message was successfully sent (or put in queue).
  66.  *      CAN_FAILTX if the controller is busy AND the transmission queue is full.
  67.  */
  68. CanReturn_t CanSend(CanMessage_t* msg) {
  69.  
  70. #ifdef CAN_CONTROLLER_MCP2515
  71.     uint8_t res, txbuf_n;
  72.     res = mcp2515_getNextFreeTXBuf(&txbuf_n); // info = addr.
  73.     if (res == MCP_ALLTXBUSY) {
  74.         return CAN_FAILTX;
  75.     }
  76.     mcp2515_write_canMsg(txbuf_n, msg);
  77.     mcp2515_start_transmit(txbuf_n);
  78.     return CAN_OK;
  79. #endif
  80.  
  81. }
  82.  
  83.  
  84. /**
  85.  * Pulls a message from the internal CAN interface reception queue. Unless this queue
  86.  * is empty, a CAN message is moved from the queue into the message storage provided
  87.  * by the calling function.
  88.  *
  89.  * @param msg
  90.  *      Pointer to the message storage buffer.
  91.  * @return
  92.  *      CAN_OK if a received message was successfully copied into the buffer.
  93.  *      CAN_NOMSG if there are no received messages available.
  94.  */
  95. CanReturn_t CanReceive(CanMessage_t *msg) {
  96.    
  97. #ifdef CAN_CONTROLLER_MCP2515
  98.     uint8_t stat, res;
  99.     stat = mcp2515_readStatus();
  100.     if (stat & MCP_STAT_RX0IF) {
  101.         // Msg in Buffer 0
  102.         mcp2515_read_canMsg( MCP_RXBUF_0, msg);
  103.         mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
  104.         res = CAN_OK;
  105.     }
  106.     else if (stat & MCP_STAT_RX1IF) {
  107.         // Msg in Buffer 1
  108.         mcp2515_read_canMsg( MCP_RXBUF_1, msg);
  109.         mcp2515_modifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
  110.         res = CAN_OK;
  111.     }
  112.     else {
  113.         res = CAN_NOMSG;
  114.     }  
  115.     return res;
  116. #endif
  117.  
  118. }
  119.  
  120.  
  121. /**
  122.  * Checks if there are any received CAN messages waiting in the reception queue.
  123.  *
  124.  * @return
  125.  *      CAN_MSGAVAIL if there are messages available.
  126.  *      CAN_NOMSG if the queue is empty.
  127.  */
  128. CanReturn_t CanReceiveAvailable(void) {
  129.    
  130. #ifdef CAN_CONTROLLER_MCP2515
  131.     uint8_t res;
  132.     res = mcp2515_readStatus(); // RXnIF in Bit 1 and 0
  133.     if ( res & MCP_STAT_RXIF_MASK ) {
  134.         return CAN_MSGAVAIL;
  135.     }
  136.     else {
  137.         return CAN_NOMSG;
  138.     }
  139. #endif
  140.  
  141. }
  142.  
  143.  
  144. /*
  145.  * Checks Controller-Error-State.
  146.  *
  147.  * @return
  148.  *      CAN_OK if the controller is OK.
  149.  *      CAN_CTRLERROR if errors have occured.
  150.  * @todo
  151.  *      Styr upp denna funktion lite bättre.
  152.  */
  153. CanReturn_t CanCheckError(void) {
  154.    
  155. #ifdef CAN_CONTROLLER_MCP2515
  156.     uint8_t eflg = mcp2515_readRegister(MCP_EFLG);
  157.     if (eflg & MCP_EFLG_ERRORMASK) {
  158.         return CAN_CTRLERROR;
  159.     }
  160.     else {
  161.         return CAN_OK;
  162.     }
  163. #endif
  164.  
  165. }
  166.