Subversion Repositories HomeAutomation

Rev

Rev 59 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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