Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
29 jimmy 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 */