Subversion Repositories HomeAutomation

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Controller Area Network (CAN) Demo-Application
  4.  * Atmel AVR with Microchip MCP2515
  5.  *
  6.  * Copyright (C) 2005 Martin THOMAS, Kaiserslautern, Germany
  7.  * <eversmith@heizung-thomas.de>
  8.  * http://www.siwawi.arubi.uni-kl.de/avr_projects
  9.  *
  10.  *****************************************************************************
  11.  *
  12.  * File    : can.c
  13.  * Version : 0.9
  14.  *
  15.  * Summary : Interface between application and CAN-Hardware
  16.  *           ("middle tier", "abstraction layer")
  17.  *
  18.  *****************************************************************************/
  19.  
  20. #include <string.h>
  21.  
  22. #include "can.h"
  23. #include "mcp2515.h"
  24. #include "timebase.h"
  25.  
  26. #if (CANDEBUG)
  27. #include "uart.h"
  28. #include "debughelper.h"
  29. #include "termio.h"
  30. #endif
  31.  
  32.  
  33. /*extern*/ uint8_t gCANAutoProcess = CANAUTOPROCESS;
  34.  
  35.  
  36. uint8_t can_init(uint8_t speedset)
  37. {
  38.     uint8_t res;
  39.    
  40.     res = mcp2515_init(speedset);
  41.    
  42.     if (res == MCP2515_OK) return CAN_OK;
  43.     else return CAN_FAILINIT;
  44. }
  45.  
  46. void can_initMessageStruct(CanMessage* msg)
  47. {
  48.     memset(msg,0,sizeof(CanMessage));
  49. }
  50.  
  51. uint8_t can_sendMessage(const CanMessage* msg)
  52. {
  53.     uint8_t res, txbuf_n;
  54.     uint8_t timeout = 0;
  55.     uint16_t time;
  56.    
  57.     time = timebase_actTime();
  58.    
  59.     do {
  60.         res = mcp2515_getNextFreeTXBuf(&txbuf_n); // info = addr.
  61.         if (timebase_passedTimeMS(time) > CANSENDTIMEOUT ) timeout = 1;
  62.     } while (res == MCP_ALLTXBUSY && !timeout);
  63.    
  64.     if (!timeout) {
  65.         mcp2515_write_canMsg( txbuf_n, msg);
  66.         mcp2515_start_transmit( txbuf_n );
  67.         return CAN_OK;
  68.     }
  69.     else {
  70. #if (CANDEBUG)
  71.         term_puts_P("Transmit timeout\n");
  72. #endif
  73.         return CAN_FAILTX;
  74.     }
  75. }
  76.  
  77. uint8_t can_readMessage(CanMessage *msg)
  78. {
  79.     uint8_t stat, res;
  80.    
  81.     stat = mcp2515_readStatus();
  82.    
  83.     if ( stat & MCP_STAT_RX0IF ) {
  84.         // Msg in Buffer 0
  85.         mcp2515_read_canMsg( MCP_RXBUF_0, msg);
  86.         mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
  87.         res = CAN_OK;
  88.     }
  89.     else if ( stat & MCP_STAT_RX1IF ) {
  90.         // Msg in Buffer 1
  91.         mcp2515_read_canMsg( MCP_RXBUF_1, msg);
  92.         mcp2515_modifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
  93.         res = CAN_OK;
  94.     }
  95.     else {
  96.         res = CAN_NOMSG;
  97.     }  
  98.    
  99.     return res;
  100. }
  101.  
  102. /* returns either
  103.  #define CAN_MSGAVAIL   (3) - a message has been received
  104.  #define CAN_NOMSG      (4) - no new message
  105. */
  106. uint8_t can_checkReceive(void)
  107. {
  108.     uint8_t res;
  109.    
  110.     res = mcp2515_readStatus(); // RXnIF in Bit 1 and 0
  111.     if ( res & MCP_STAT_RXIF_MASK ) {
  112.         return CAN_MSGAVAIL;
  113.     }
  114.     else {
  115.         return CAN_NOMSG;
  116.     }
  117. }
  118.  
  119. /* checks Controller-Error-State, returns CAN_OK or CAN_CTRLERROR
  120.    only errors (and not warnings) lead to "CTRLERROR" */
  121. uint8_t can_checkError(void)
  122. {
  123.     uint8_t eflg = mcp2515_readRegister(MCP_EFLG);
  124.  
  125.     if ( eflg & MCP_EFLG_ERRORMASK ) {
  126.         return CAN_CTRLERROR;
  127.     }
  128.     else {
  129.         return CAN_OK;
  130.     }
  131. }
  132.  
  133. #if (CANDEBUG)
  134.  
  135. uint8_t can_testTransmit(const uint8_t ext, const uint8_t data2)
  136. {
  137.     CanMessage msg;
  138.    
  139.     can_initMessageStruct(&msg);
  140.     msg.identifier = CANDEFAULTIDENT;
  141.     msg.extended_identifier = ext;
  142.     msg.dlc = 3;
  143.     msg.dta[0] = 'M';
  144.     msg.dta[1] = 'T';
  145.     msg.dta[2] = data2;
  146.    
  147.     return can_sendMessage(&msg);
  148. }
  149.  
  150. void can_debug1(void)
  151. {
  152.     uint8_t i;
  153.     // CanMessage msg;
  154.    
  155.     term_puts_P("CAN-DEBUG 1\r");
  156.     i = mcp2515_readRegister(MCP_CANCTRL);
  157.     Debug_ByteToUart_P("CANCTRL", i);
  158.     i = mcp2515_readRegister(MCP_CANSTAT);
  159.     Debug_ByteToUart_P("CANSTAT", i);
  160.     i = mcp2515_readRegister(MCP_CNF1);
  161.     Debug_ByteToUart_P("CNF1", i);
  162.     i = mcp2515_readRegister(MCP_CNF2);
  163.     Debug_ByteToUart_P("CNF2", i);
  164.     i = mcp2515_readRegister(MCP_CNF3);
  165.     Debug_ByteToUart_P("CNF3", i);
  166.    
  167. #if CANUSELOOP == 1
  168.     term_puts_P("Setting Loopback-Mode - ");
  169.     if ( mcp2515_setCANCTRL_Mode(MODE_LOOPBACK) == MCP2515_OK) {
  170.         uart_puts_P("OK\r");
  171.     }
  172.     else {
  173.         uart_puts_P("failed\r");
  174.     }
  175. #else
  176. term_puts_P("Setting Normal-Mode - ");
  177.     if ( mcp2515_setCANCTRL_Mode(MODE_NORMAL) == MCP2515_OK) {
  178.         uart_puts_P("OK\r");
  179.     }
  180.     else {
  181.         uart_puts_P("failed\r");
  182.     }
  183. #endif
  184.    
  185.     i = mcp2515_readRegister(MCP_CANCTRL);
  186.     Debug_ByteToUart_P("CANCTRL", i);
  187.     i = mcp2515_readRegister(MCP_RXB0CTRL);
  188.     Debug_ByteToUart_P("RXB0CTRL", i);
  189.     i = mcp2515_readRegister(MCP_RXB1CTRL);
  190.     Debug_ByteToUart_P("RXB1CTRL", i);
  191.  
  192. #if 0  
  193.     can_initMessageStruct(&msg);
  194.     msg.identifier = CANDEFAULTIDENT;
  195.     msg.extended_identifier = CAN_STDID; // CANDEFAULTIDENTEXT;
  196.     msg.dlc = 3;
  197.     msg.dta[0] = 'M';
  198.     msg.dta[1] = 'T';
  199.     msg.dta[2] = '1';
  200.     term_puts_P("Sending a message...");
  201.     can_sendMessage(&msg);
  202.    
  203.     msg.extended_identifier = CANDEFAULTIDENTEXT;
  204.     msg.dta[2] = '2';
  205.     term_puts_P("Sending a message...");
  206.     can_sendMessage(&msg);
  207. #endif
  208. }
  209.  
  210. void can_dumpMessage(CanMessage *msg)
  211. {
  212.     uint8_t i;
  213.  
  214.     term_puts_P("\nMessage-Dump :\n");
  215.     // identifier type 0=standard 1=extended:
  216.     if ( (msg->extended_identifier) == CAN_EXTID ) {
  217.         term_puts_P("Extended");
  218.     }
  219.     else {
  220.         term_puts_P("Standard");
  221.     }
  222.     term_puts_P("-Identifier :\n");
  223.     Debug_ByteToUart_P("Byte 0", (uint8_t) ( (msg->identifier) ));
  224.     Debug_ByteToUart_P("Byte 1", (uint8_t) ( (msg->identifier) >> 8 ));
  225.     if ( (msg->extended_identifier) == CAN_EXTID ) {
  226.         Debug_ByteToUart_P("Byte 2", (uint8_t) ( (msg->identifier) >> 16 ));
  227.         Debug_ByteToUart_P("Byte 3", (uint8_t) ( (msg->identifier) >> 24 ));
  228.     }
  229.    
  230.     // data length:
  231.     term_puts_P("Data :\n");
  232.     Debug_ByteToUart_P( "dlc", msg->dlc );
  233.     for (i=0;i<msg->dlc;i++) {
  234.         Debug_ByteToUart_P( "dta", msg->dta[i] );
  235.     }
  236.    
  237.     term_puts_P("Meta:\n");
  238.     // used for receive only:
  239.     // Received Remote Transfer Bit
  240.     //  (0=no... 1=remote transfer request received)
  241.     Debug_ByteToUart_P( "rtr", msg->rtr );
  242.     // Acceptence Filter that enabled the reception
  243.     Debug_ByteToUart_P( "filhit", msg->filhit );
  244. }
  245.  
  246. void can_dumpStatus(void)
  247. {
  248.     mcp2515_dumpExtendedStatus();
  249. }
  250.  
  251. #endif /* CANDEBUG */
  252.