Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
59 jimmy 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
 */
63 jimmy 68
CanReturn_t CanSend(CanMessage_t* msg) {
59 jimmy 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
}