User | Revision | Line number | New contents of line |
tecnosys |
0:d8f50b1e384f
|
1
|
/******************************************************************************
|
tecnosys |
1:dbc44582f2f8
|
2
|
*
|
tecnosys |
0:d8f50b1e384f
|
3
|
* Controller Area Network (CAN) Demo-Application
|
tecnosys |
1:dbc44582f2f8
|
4
|
* Atmel AVR with Microchip MCP2515
|
tecnosys |
1:dbc44582f2f8
|
5
|
*
|
tecnosys |
0:d8f50b1e384f
|
6
|
* Copyright (C) 2005 Martin THOMAS, Kaiserslautern, Germany
|
tecnosys |
0:d8f50b1e384f
|
7
|
* <eversmith@heizung-thomas.de>
|
tecnosys |
0:d8f50b1e384f
|
8
|
* http://www.siwawi.arubi.uni-kl.de/avr_projects
|
tecnosys |
0:d8f50b1e384f
|
9
|
*
|
tecnosys |
0:d8f50b1e384f
|
10
|
*****************************************************************************
|
tecnosys |
0:d8f50b1e384f
|
11
|
*
|
tecnosys |
0:d8f50b1e384f
|
12
|
* File : mcp2515.c
|
tecnosys |
0:d8f50b1e384f
|
13
|
* Version : 0.9
|
tecnosys |
1:dbc44582f2f8
|
14
|
*
|
tecnosys |
0:d8f50b1e384f
|
15
|
* Summary : MCP2515 "low-level" driver
|
tecnosys |
0:d8f50b1e384f
|
16
|
*
|
tecnosys |
1:dbc44582f2f8
|
17
|
* Parts of this code are adapted from a MCP2510 sample-application
|
tecnosys |
0:d8f50b1e384f
|
18
|
* by KVASER AB, http://www.kvaser.com (KVASER-code is marked as free)
|
tecnosys |
0:d8f50b1e384f
|
19
|
*
|
tecnosys |
0:d8f50b1e384f
|
20
|
* This code-module is free to use but you have to keep the copyright
|
tecnosys |
0:d8f50b1e384f
|
21
|
* notice.
|
tecnosys |
0:d8f50b1e384f
|
22
|
*
|
tecnosys |
0:d8f50b1e384f
|
23
|
*
|
tecnosys |
0:d8f50b1e384f
|
24
|
*****************************************************************************
|
tecnosys |
0:d8f50b1e384f
|
25
|
*
|
tecnosys |
0:d8f50b1e384f
|
26
|
* File : mcp2515.cpp (mbed LPC1768 version)
|
tecnosys |
0:d8f50b1e384f
|
27
|
* Version : 0.1
|
tecnosys |
0:d8f50b1e384f
|
28
|
*
|
tecnosys |
1:dbc44582f2f8
|
29
|
* All credits to the nerds above, this source has been adapted for the
|
tecnosys |
0:d8f50b1e384f
|
30
|
* LPC1768 platform by J.Engelman. And does'nt require and of the copyrighted
|
tecnosys |
0:d8f50b1e384f
|
31
|
* SPI or AVR controller code that Martin or co have excluded copyright.
|
tecnosys |
0:d8f50b1e384f
|
32
|
* This module remains free.
|
tecnosys |
0:d8f50b1e384f
|
33
|
*
|
tecnosys |
0:d8f50b1e384f
|
34
|
*
|
tecnosys |
0:d8f50b1e384f
|
35
|
*****************************************************************************/
|
tecnosys |
0:d8f50b1e384f
|
36
|
|
tecnosys |
0:d8f50b1e384f
|
37
|
#include "mcp2515.h"
|
tecnosys |
0:d8f50b1e384f
|
38
|
|
tecnosys |
1:dbc44582f2f8
|
39
|
#include "mbed.h"
|
tecnosys |
0:d8f50b1e384f
|
40
|
#include "mcp2515_can.h"
|
tecnosys |
0:d8f50b1e384f
|
41
|
#include "mcp2515_defs.h"
|
tecnosys |
0:d8f50b1e384f
|
42
|
#include "mcp2515_bittime.h"
|
tecnosys |
0:d8f50b1e384f
|
43
|
|
tecnosys |
0:d8f50b1e384f
|
44
|
#define SPI_NULL (0x00)
|
tecnosys |
0:d8f50b1e384f
|
45
|
|
tecnosys |
1:dbc44582f2f8
|
46
|
#define PHSEG11 4
|
tecnosys |
1:dbc44582f2f8
|
47
|
#define PHSEG21 1
|
tecnosys |
1:dbc44582f2f8
|
48
|
#define BTLMODE2 7
|
tecnosys |
1:dbc44582f2f8
|
49
|
//BTLMODE 0x80 (128)
|
tecnosys |
1:dbc44582f2f8
|
50
|
#define BRP2 2
|
tecnosys |
1:dbc44582f2f8
|
51
|
#define BRP1 1
|
tecnosys |
1:dbc44582f2f8
|
52
|
#define BRP0 0
|
tecnosys |
0:d8f50b1e384f
|
53
|
|
tecnosys |
1:dbc44582f2f8
|
54
|
#define CNF2_BTLMODE 0x80
|
tecnosys |
1:dbc44582f2f8
|
55
|
#define CNF3 0x28
|
tecnosys |
1:dbc44582f2f8
|
56
|
#define CNF3_SOF 0x08
|
tecnosys |
1:dbc44582f2f8
|
57
|
#define CNF3_WAKFIL 0x04
|
tecnosys |
1:dbc44582f2f8
|
58
|
#define CNF3_PHSEG2_MASK 0x07
|
tecnosys |
0:d8f50b1e384f
|
59
|
|
tecnosys |
1:dbc44582f2f8
|
60
|
mcp2515::mcp2515(SPI& _spi, PinName ncs)
|
tecnosys |
1:dbc44582f2f8
|
61
|
: spi(_spi), _ncs(ncs) {
|
tecnosys |
1:dbc44582f2f8
|
62
|
printf("\n\rmcp2515 = %d",this);
|
tecnosys |
1:dbc44582f2f8
|
63
|
printf("\n\rpin = %d",ncs);
|
tecnosys |
0:d8f50b1e384f
|
64
|
|
tecnosys |
0:d8f50b1e384f
|
65
|
}
|
tecnosys |
0:d8f50b1e384f
|
66
|
|
tecnosys |
0:d8f50b1e384f
|
67
|
|
tecnosys |
1:dbc44582f2f8
|
68
|
|
tecnosys |
0:d8f50b1e384f
|
69
|
void mcp2515::_reset() {
|
tecnosys |
0:d8f50b1e384f
|
70
|
|
tecnosys |
0:d8f50b1e384f
|
71
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
72
|
_spi_readwrite(MCP_RESET);
|
tecnosys |
0:d8f50b1e384f
|
73
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
74
|
wait(0.001);
|
tecnosys |
0:d8f50b1e384f
|
75
|
}
|
tecnosys |
0:d8f50b1e384f
|
76
|
|
tecnosys |
1:dbc44582f2f8
|
77
|
void mcp2515::setRegister( uint8_t address, uint8_t value) {
|
tecnosys |
0:d8f50b1e384f
|
78
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
79
|
_spi_readwrite(MCP_WRITE);
|
tecnosys |
0:d8f50b1e384f
|
80
|
_spi_readwrite(address);
|
tecnosys |
0:d8f50b1e384f
|
81
|
_spi_readwrite(value);
|
tecnosys |
0:d8f50b1e384f
|
82
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
83
|
}
|
tecnosys |
0:d8f50b1e384f
|
84
|
|
tecnosys |
1:dbc44582f2f8
|
85
|
uint8_t mcp2515::configRate( uint8_t canSpeed) {
|
tecnosys |
0:d8f50b1e384f
|
86
|
uint8_t set, cfg1, cfg2, cfg3;
|
tecnosys |
1:dbc44582f2f8
|
87
|
|
tecnosys |
0:d8f50b1e384f
|
88
|
set = 0;
|
tecnosys |
1:dbc44582f2f8
|
89
|
|
tecnosys |
0:d8f50b1e384f
|
90
|
switch (canSpeed) {
|
tecnosys |
1:dbc44582f2f8
|
91
|
case (CAN_500KBPS_8MHZ) :
|
tecnosys |
1:dbc44582f2f8
|
92
|
cfg1 = 0x04;
|
tecnosys |
1:dbc44582f2f8
|
93
|
cfg2 = 0xA0;
|
tecnosys |
1:dbc44582f2f8
|
94
|
cfg3 = 0x02;
|
tecnosys |
1:dbc44582f2f8
|
95
|
case (CAN_50KBPS_8MHZ) :
|
tecnosys |
1:dbc44582f2f8
|
96
|
cfg1 = 0x04; //0x09;
|
tecnosys |
1:dbc44582f2f8
|
97
|
cfg2 = 0xB8; //0x90;
|
tecnosys |
1:dbc44582f2f8
|
98
|
cfg3 = 0x05; //0x02;
|
tecnosys |
0:d8f50b1e384f
|
99
|
case (CAN_125KBPS) :
|
tecnosys |
1:dbc44582f2f8
|
100
|
cfg1 = MCP_4MHz_125kBPS_CFG1 ;
|
tecnosys |
0:d8f50b1e384f
|
101
|
cfg2 = MCP_4MHz_125kBPS_CFG2 ;
|
tecnosys |
0:d8f50b1e384f
|
102
|
cfg3 = MCP_4MHz_125kBPS_CFG3 ;
|
tecnosys |
0:d8f50b1e384f
|
103
|
set = 1;
|
tecnosys |
0:d8f50b1e384f
|
104
|
break;
|
tecnosys |
0:d8f50b1e384f
|
105
|
case (CAN_20KBPS) :
|
tecnosys |
1:dbc44582f2f8
|
106
|
cfg1 = MCP_4MHz_20kBPS_CFG1 ;
|
tecnosys |
0:d8f50b1e384f
|
107
|
cfg2 = MCP_4MHz_20kBPS_CFG2 ;
|
tecnosys |
0:d8f50b1e384f
|
108
|
cfg3 = MCP_4MHz_20kBPS_CFG3 ;
|
tecnosys |
0:d8f50b1e384f
|
109
|
set = 1;
|
tecnosys |
0:d8f50b1e384f
|
110
|
break;
|
tecnosys |
0:d8f50b1e384f
|
111
|
default:
|
tecnosys |
0:d8f50b1e384f
|
112
|
set = 0;
|
tecnosys |
0:d8f50b1e384f
|
113
|
break;
|
tecnosys |
0:d8f50b1e384f
|
114
|
}
|
tecnosys |
1:dbc44582f2f8
|
115
|
|
tecnosys |
0:d8f50b1e384f
|
116
|
if (set) {
|
tecnosys |
0:d8f50b1e384f
|
117
|
setRegister(MCP_CNF1, cfg1);
|
tecnosys |
0:d8f50b1e384f
|
118
|
setRegister(MCP_CNF2, cfg2);
|
tecnosys |
0:d8f50b1e384f
|
119
|
setRegister(MCP_CNF3, cfg3);
|
tecnosys |
0:d8f50b1e384f
|
120
|
return MCP2515_OK;
|
tecnosys |
1:dbc44582f2f8
|
121
|
} else {
|
tecnosys |
0:d8f50b1e384f
|
122
|
return MCP2515_FAIL;
|
tecnosys |
0:d8f50b1e384f
|
123
|
}
|
tecnosys |
1:dbc44582f2f8
|
124
|
}
|
tecnosys |
1:dbc44582f2f8
|
125
|
|
tecnosys |
1:dbc44582f2f8
|
126
|
int mcp2515::configRate2(int bit_rate)
|
tecnosys |
1:dbc44582f2f8
|
127
|
{
|
tecnosys |
1:dbc44582f2f8
|
128
|
//struct spi_device *spi = to_spi_device(can->cdev.dev);
|
tecnosys |
1:dbc44582f2f8
|
129
|
//struct mcp251x *chip = dev_get_drvdata(&spi->dev);
|
tecnosys |
1:dbc44582f2f8
|
130
|
//struct mcp251x_platform_data *pdata = spi->dev.platform_data;
|
tecnosys |
1:dbc44582f2f8
|
131
|
|
tecnosys |
1:dbc44582f2f8
|
132
|
printf("\n\rcanspeed=%d",bit_rate);
|
tecnosys |
1:dbc44582f2f8
|
133
|
int f_osc = 8000000; //4000000; //4Mhz
|
tecnosys |
1:dbc44582f2f8
|
134
|
int tqs; /* tbit/TQ */
|
tecnosys |
1:dbc44582f2f8
|
135
|
int brp;
|
tecnosys |
1:dbc44582f2f8
|
136
|
int ps1, ps2, propseg, sjw;
|
tecnosys |
1:dbc44582f2f8
|
137
|
|
tecnosys |
1:dbc44582f2f8
|
138
|
/* Determine the BRP value that gives the requested bit rate. */
|
tecnosys |
1:dbc44582f2f8
|
139
|
for(brp = 0; brp < 8; brp++) {
|
tecnosys |
1:dbc44582f2f8
|
140
|
tqs = f_osc / (2 * (brp + 1)) / bit_rate;
|
tecnosys |
1:dbc44582f2f8
|
141
|
if (tqs >= 5 && tqs <= 25
|
tecnosys |
1:dbc44582f2f8
|
142
|
&& (f_osc / (2 * (brp + 1)) / tqs) == bit_rate)
|
tecnosys |
1:dbc44582f2f8
|
143
|
break;
|
tecnosys |
1:dbc44582f2f8
|
144
|
}
|
tecnosys |
1:dbc44582f2f8
|
145
|
if (brp >= 8) printf("Spaztic BRP");
|
tecnosys |
1:dbc44582f2f8
|
146
|
// return -1;
|
tecnosys |
0:d8f50b1e384f
|
147
|
|
tecnosys |
1:dbc44582f2f8
|
148
|
/* The CAN bus bit time (tbit) is determined by:
|
tecnosys |
1:dbc44582f2f8
|
149
|
* tbit = (SyncSeg + PropSeg + PS1 + PS2) * TQ
|
tecnosys |
1:dbc44582f2f8
|
150
|
* with:
|
tecnosys |
1:dbc44582f2f8
|
151
|
* SyncSeg = 1
|
tecnosys |
1:dbc44582f2f8
|
152
|
* sample point (between PS1 and PS2) must be at 60%-70% of the bit time
|
tecnosys |
1:dbc44582f2f8
|
153
|
* PropSeg + PS1 >= PS2
|
tecnosys |
1:dbc44582f2f8
|
154
|
* PropSeg + PS1 >= Tdelay
|
tecnosys |
1:dbc44582f2f8
|
155
|
* PS2 > SJW
|
tecnosys |
1:dbc44582f2f8
|
156
|
* 1 <= PropSeg <= 8, 1 <= PS1 <=8, 2 <= PS2 <= 8
|
tecnosys |
1:dbc44582f2f8
|
157
|
* SJW = 1 is sufficient in most cases.
|
tecnosys |
1:dbc44582f2f8
|
158
|
* Tdelay is usually 1 or 2 TQ.
|
tecnosys |
1:dbc44582f2f8
|
159
|
*/
|
tecnosys |
1:dbc44582f2f8
|
160
|
|
tecnosys |
1:dbc44582f2f8
|
161
|
propseg = ps1 = ps2 = (tqs - 1) / 3;
|
tecnosys |
1:dbc44582f2f8
|
162
|
if (tqs - (1 + propseg + ps1 + ps2) == 2)
|
tecnosys |
1:dbc44582f2f8
|
163
|
ps1++;
|
tecnosys |
1:dbc44582f2f8
|
164
|
if (tqs - (1 + propseg + ps1 + ps2) == 1)
|
tecnosys |
1:dbc44582f2f8
|
165
|
ps2++;
|
tecnosys |
1:dbc44582f2f8
|
166
|
sjw = 1;
|
tecnosys |
1:dbc44582f2f8
|
167
|
|
tecnosys |
1:dbc44582f2f8
|
168
|
printf("\n\rbit rate: BRP = %d, Tbit = %d TQ, PropSeg = %d, PS1 = %d, PS2 = %d, SJW = %d\n",
|
tecnosys |
1:dbc44582f2f8
|
169
|
brp, tqs, propseg, ps1, ps2, sjw);
|
tecnosys |
1:dbc44582f2f8
|
170
|
|
tecnosys |
1:dbc44582f2f8
|
171
|
/* Since we can only change the bit rate when the network device is
|
tecnosys |
1:dbc44582f2f8
|
172
|
* down the chip must be in sleep mode. Wake it up and put it into
|
tecnosys |
1:dbc44582f2f8
|
173
|
* config mode. */
|
tecnosys |
1:dbc44582f2f8
|
174
|
//mcp251x_hw_wakeup(spi);
|
tecnosys |
1:dbc44582f2f8
|
175
|
//mcp251x_write_bits(spi, CANCTRL, CANCTRL_REQOP_MASK, CANCTRL_REQOP_CONF);
|
tecnosys |
1:dbc44582f2f8
|
176
|
|
tecnosys |
1:dbc44582f2f8
|
177
|
//mcp251x_write_reg(spi, CNF1, ((sjw-1) << 6) | brp);
|
tecnosys |
1:dbc44582f2f8
|
178
|
//mcp251x_write_reg(spi, CNF2, CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1));
|
tecnosys |
1:dbc44582f2f8
|
179
|
//mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK, (ps2-1));
|
tecnosys |
1:dbc44582f2f8
|
180
|
setRegister(MCP_CNF1, ((sjw-1) << 6) | brp );
|
tecnosys |
1:dbc44582f2f8
|
181
|
setRegister(MCP_CNF2, CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1) );
|
tecnosys |
1:dbc44582f2f8
|
182
|
modifyRegister(MCP_CNF3, CNF3_PHSEG2_MASK, (ps2-1) );
|
tecnosys |
1:dbc44582f2f8
|
183
|
//mcp251x_hw_sleep(spi);
|
tecnosys |
1:dbc44582f2f8
|
184
|
|
tecnosys |
1:dbc44582f2f8
|
185
|
/* Calculate actual bit rate. */
|
tecnosys |
1:dbc44582f2f8
|
186
|
//chip->bit_rate = pdata->f_osc / (2 * (brp + 1)) / tqs;
|
tecnosys |
1:dbc44582f2f8
|
187
|
|
tecnosys |
1:dbc44582f2f8
|
188
|
return 0;
|
tecnosys |
1:dbc44582f2f8
|
189
|
}
|
tecnosys |
1:dbc44582f2f8
|
190
|
|
tecnosys |
1:dbc44582f2f8
|
191
|
uint8_t mcp2515::readRegister( uint8_t address) {
|
tecnosys |
0:d8f50b1e384f
|
192
|
uint8_t ret;
|
tecnosys |
1:dbc44582f2f8
|
193
|
|
tecnosys |
0:d8f50b1e384f
|
194
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
195
|
_spi_readwrite(MCP_READ);
|
tecnosys |
0:d8f50b1e384f
|
196
|
_spi_readwrite(address);
|
tecnosys |
0:d8f50b1e384f
|
197
|
ret = _spi_read();
|
tecnosys |
0:d8f50b1e384f
|
198
|
_deselect();
|
tecnosys |
1:dbc44582f2f8
|
199
|
|
tecnosys |
0:d8f50b1e384f
|
200
|
return ret;
|
tecnosys |
0:d8f50b1e384f
|
201
|
}
|
tecnosys |
0:d8f50b1e384f
|
202
|
|
tecnosys |
1:dbc44582f2f8
|
203
|
void mcp2515::readRegisterS( uint8_t address,
|
tecnosys |
1:dbc44582f2f8
|
204
|
uint8_t values[], uint8_t n) {
|
tecnosys |
0:d8f50b1e384f
|
205
|
uint8_t i;
|
tecnosys |
1:dbc44582f2f8
|
206
|
|
tecnosys |
0:d8f50b1e384f
|
207
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
208
|
_spi_readwrite(MCP_READ);
|
tecnosys |
0:d8f50b1e384f
|
209
|
_spi_readwrite(address);
|
tecnosys |
0:d8f50b1e384f
|
210
|
// mcp2515 has auto-increment of address-pointer
|
tecnosys |
0:d8f50b1e384f
|
211
|
for (i=0; i<n; i++) {
|
tecnosys |
0:d8f50b1e384f
|
212
|
values[i] = _spi_read();
|
tecnosys |
0:d8f50b1e384f
|
213
|
}
|
tecnosys |
0:d8f50b1e384f
|
214
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
215
|
}
|
tecnosys |
0:d8f50b1e384f
|
216
|
|
tecnosys |
1:dbc44582f2f8
|
217
|
void mcp2515::modifyRegister( uint8_t address,
|
tecnosys |
1:dbc44582f2f8
|
218
|
uint8_t mask, uint8_t data) {
|
tecnosys |
0:d8f50b1e384f
|
219
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
220
|
_spi_readwrite(MCP_BITMOD);
|
tecnosys |
0:d8f50b1e384f
|
221
|
_spi_readwrite(address);
|
tecnosys |
0:d8f50b1e384f
|
222
|
_spi_readwrite(mask);
|
tecnosys |
0:d8f50b1e384f
|
223
|
_spi_readwrite(data);
|
tecnosys |
0:d8f50b1e384f
|
224
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
225
|
}
|
tecnosys |
0:d8f50b1e384f
|
226
|
|
tecnosys |
0:d8f50b1e384f
|
227
|
|
tecnosys |
1:dbc44582f2f8
|
228
|
uint8_t mcp2515::readXXStatus_helper( uint8_t cmd) {
|
tecnosys |
0:d8f50b1e384f
|
229
|
uint8_t i;
|
tecnosys |
1:dbc44582f2f8
|
230
|
|
tecnosys |
0:d8f50b1e384f
|
231
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
232
|
_spi_readwrite(cmd);
|
tecnosys |
0:d8f50b1e384f
|
233
|
i = _spi_read();
|
tecnosys |
0:d8f50b1e384f
|
234
|
_deselect();
|
tecnosys |
1:dbc44582f2f8
|
235
|
|
tecnosys |
0:d8f50b1e384f
|
236
|
return i;
|
tecnosys |
0:d8f50b1e384f
|
237
|
}
|
tecnosys |
1:dbc44582f2f8
|
238
|
|
tecnosys |
1:dbc44582f2f8
|
239
|
uint8_t mcp2515::readStatus(void) {
|
tecnosys |
0:d8f50b1e384f
|
240
|
return readXXStatus_helper(MCP_READ_STATUS);
|
tecnosys |
0:d8f50b1e384f
|
241
|
}
|
tecnosys |
0:d8f50b1e384f
|
242
|
|
tecnosys |
1:dbc44582f2f8
|
243
|
uint8_t mcp2515::RXStatus(void) {
|
tecnosys |
0:d8f50b1e384f
|
244
|
return readXXStatus_helper(MCP_RX_STATUS);
|
tecnosys |
0:d8f50b1e384f
|
245
|
}
|
tecnosys |
0:d8f50b1e384f
|
246
|
|
tecnosys |
0:d8f50b1e384f
|
247
|
// read-modify-write - better: Bit Modify Instruction
|
tecnosys |
1:dbc44582f2f8
|
248
|
uint8_t mcp2515::setCANCTRL_Mode(uint8_t newmode) {
|
tecnosys |
1:dbc44582f2f8
|
249
|
|
tecnosys |
0:d8f50b1e384f
|
250
|
uint8_t i;
|
tecnosys |
1:dbc44582f2f8
|
251
|
|
tecnosys |
0:d8f50b1e384f
|
252
|
i = readRegister(MCP_CANCTRL);
|
tecnosys |
0:d8f50b1e384f
|
253
|
i &= ~(MODE_MASK);
|
tecnosys |
0:d8f50b1e384f
|
254
|
i |= newmode;
|
tecnosys |
0:d8f50b1e384f
|
255
|
setRegister(MCP_CANCTRL, i);
|
tecnosys |
1:dbc44582f2f8
|
256
|
|
tecnosys |
0:d8f50b1e384f
|
257
|
// verify as advised in datasheet
|
tecnosys |
0:d8f50b1e384f
|
258
|
i = readRegister(MCP_CANCTRL);
|
tecnosys |
0:d8f50b1e384f
|
259
|
i &= MODE_MASK;
|
tecnosys |
0:d8f50b1e384f
|
260
|
if ( i == newmode ) {
|
tecnosys |
1:dbc44582f2f8
|
261
|
return MCP2515_OK;
|
tecnosys |
1:dbc44582f2f8
|
262
|
} else {
|
tecnosys |
0:d8f50b1e384f
|
263
|
return MCP2515_FAIL;
|
tecnosys |
0:d8f50b1e384f
|
264
|
}
|
tecnosys |
1:dbc44582f2f8
|
265
|
|
tecnosys |
0:d8f50b1e384f
|
266
|
}
|
tecnosys |
0:d8f50b1e384f
|
267
|
|
tecnosys |
0:d8f50b1e384f
|
268
|
|
tecnosys |
1:dbc44582f2f8
|
269
|
void mcp2515::setRegisterS( uint8_t address,
|
tecnosys |
1:dbc44582f2f8
|
270
|
uint8_t values[], uint8_t n) {
|
tecnosys |
0:d8f50b1e384f
|
271
|
uint8_t i;
|
tecnosys |
1:dbc44582f2f8
|
272
|
|
tecnosys |
0:d8f50b1e384f
|
273
|
_select();
|
tecnosys |
0:d8f50b1e384f
|
274
|
_spi_readwrite(MCP_WRITE);
|
tecnosys |
0:d8f50b1e384f
|
275
|
_spi_readwrite(address);
|
tecnosys |
0:d8f50b1e384f
|
276
|
// mcp2515 has auto-increment of address-pointer
|
tecnosys |
0:d8f50b1e384f
|
277
|
for (i=0; i<n; i++) {
|
tecnosys |
0:d8f50b1e384f
|
278
|
_spi_readwrite(values[i]);
|
tecnosys |
0:d8f50b1e384f
|
279
|
}
|
tecnosys |
0:d8f50b1e384f
|
280
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
281
|
}
|
tecnosys |
0:d8f50b1e384f
|
282
|
|
tecnosys |
1:dbc44582f2f8
|
283
|
void mcp2515::read_can_id( uint8_t mcp_addr,
|
tecnosys |
1:dbc44582f2f8
|
284
|
uint8_t* ext, uint32_t* can_id ) {
|
tecnosys |
0:d8f50b1e384f
|
285
|
uint8_t tbufdata[4];
|
tecnosys |
1:dbc44582f2f8
|
286
|
|
tecnosys |
0:d8f50b1e384f
|
287
|
*ext = 0;
|
tecnosys |
0:d8f50b1e384f
|
288
|
*can_id = 0;
|
tecnosys |
1:dbc44582f2f8
|
289
|
|
tecnosys |
0:d8f50b1e384f
|
290
|
readRegisterS( mcp_addr, tbufdata, 4 );
|
tecnosys |
1:dbc44582f2f8
|
291
|
|
tecnosys |
0:d8f50b1e384f
|
292
|
*can_id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
|
tecnosys |
1:dbc44582f2f8
|
293
|
|
tecnosys |
0:d8f50b1e384f
|
294
|
if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M ) {
|
tecnosys |
0:d8f50b1e384f
|
295
|
// extended id
|
tecnosys |
0:d8f50b1e384f
|
296
|
*can_id = (*can_id<<2) + (tbufdata[MCP_SIDL] & 0x03);
|
tecnosys |
0:d8f50b1e384f
|
297
|
*can_id <<= 16;
|
tecnosys |
0:d8f50b1e384f
|
298
|
*can_id = *can_id +(tbufdata[MCP_EID8]<<8) + tbufdata[MCP_EID0];
|
tecnosys |
0:d8f50b1e384f
|
299
|
*ext = 1;
|
tecnosys |
0:d8f50b1e384f
|
300
|
}
|
tecnosys |
0:d8f50b1e384f
|
301
|
}
|
tecnosys |
0:d8f50b1e384f
|
302
|
|
tecnosys |
0:d8f50b1e384f
|
303
|
|
tecnosys |
1:dbc44582f2f8
|
304
|
void mcp2515::read_can_idN( uint8_t mcp_addr,
|
tecnosys |
1:dbc44582f2f8
|
305
|
CANFormat* ext, unsigned int* can_id ) {
|
tecnosys |
1:dbc44582f2f8
|
306
|
uint8_t tbufdata[4];
|
tecnosys |
1:dbc44582f2f8
|
307
|
|
tecnosys |
1:dbc44582f2f8
|
308
|
*ext = CANStandard;
|
tecnosys |
1:dbc44582f2f8
|
309
|
*can_id = 0;
|
tecnosys |
1:dbc44582f2f8
|
310
|
|
tecnosys |
1:dbc44582f2f8
|
311
|
readRegisterS( mcp_addr, tbufdata, 4 );
|
tecnosys |
1:dbc44582f2f8
|
312
|
|
tecnosys |
1:dbc44582f2f8
|
313
|
*can_id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
|
tecnosys |
1:dbc44582f2f8
|
314
|
|
tecnosys |
1:dbc44582f2f8
|
315
|
if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M ) {
|
tecnosys |
1:dbc44582f2f8
|
316
|
// extended id
|
tecnosys |
1:dbc44582f2f8
|
317
|
*can_id = (*can_id<<2) + (tbufdata[MCP_SIDL] & 0x03);
|
tecnosys |
1:dbc44582f2f8
|
318
|
*can_id <<= 16;
|
tecnosys |
1:dbc44582f2f8
|
319
|
*can_id = *can_id +(tbufdata[MCP_EID8]<<8) + tbufdata[MCP_EID0];
|
tecnosys |
1:dbc44582f2f8
|
320
|
*ext = CANExtended;//1;
|
tecnosys |
1:dbc44582f2f8
|
321
|
}
|
tecnosys |
1:dbc44582f2f8
|
322
|
}
|
tecnosys |
1:dbc44582f2f8
|
323
|
|
tecnosys |
0:d8f50b1e384f
|
324
|
// Buffer can be MCP_RXBUF_0 or MCP_RXBUF_1
|
tecnosys |
1:dbc44582f2f8
|
325
|
void mcp2515::read_canMsg( uint8_t buffer_sidh_addr, CANMessage* msg)
|
tecnosys |
1:dbc44582f2f8
|
326
|
//CANMessage mcp2515::read_canMsg( uint8_t buffer_sidh_addr)
|
tecnosys |
0:d8f50b1e384f
|
327
|
{
|
tecnosys |
1:dbc44582f2f8
|
328
|
uint8_t mcp_addr, ctrl,dlc;
|
tecnosys |
1:dbc44582f2f8
|
329
|
|
tecnosys |
1:dbc44582f2f8
|
330
|
|
tecnosys |
0:d8f50b1e384f
|
331
|
|
tecnosys |
0:d8f50b1e384f
|
332
|
mcp_addr = buffer_sidh_addr;
|
tecnosys |
1:dbc44582f2f8
|
333
|
|
tecnosys |
1:dbc44582f2f8
|
334
|
read_can_idN( mcp_addr, &msg->format, &msg->id );
|
tecnosys |
1:dbc44582f2f8
|
335
|
|
tecnosys |
0:d8f50b1e384f
|
336
|
ctrl = readRegister( mcp_addr-1 );
|
tecnosys |
1:dbc44582f2f8
|
337
|
dlc = readRegister( mcp_addr+4 );
|
tecnosys |
1:dbc44582f2f8
|
338
|
|
tecnosys |
0:d8f50b1e384f
|
339
|
//if ((*dlc & RTR_MASK) || (ctrl & 0x08)) {
|
tecnosys |
0:d8f50b1e384f
|
340
|
if ((ctrl & 0x08)) {
|
tecnosys |
1:dbc44582f2f8
|
341
|
msg->type = CANRemote; //1 CANRemote
|
tecnosys |
0:d8f50b1e384f
|
342
|
} else {
|
tecnosys |
1:dbc44582f2f8
|
343
|
msg->type = CANData; //0 CANData
|
tecnosys |
0:d8f50b1e384f
|
344
|
}
|
tecnosys |
1:dbc44582f2f8
|
345
|
|
tecnosys |
1:dbc44582f2f8
|
346
|
dlc &= MCP_DLC_MASK;
|
tecnosys |
1:dbc44582f2f8
|
347
|
readRegisterS( mcp_addr+5, &(msg->data[0]), dlc );
|
tecnosys |
1:dbc44582f2f8
|
348
|
msg->len =dlc;
|
tecnosys |
1:dbc44582f2f8
|
349
|
|
tecnosys |
0:d8f50b1e384f
|
350
|
}
|
tecnosys |
0:d8f50b1e384f
|
351
|
|
tecnosys |
1:dbc44582f2f8
|
352
|
void mcp2515::setDebugConsole(Serial c){
|
tecnosys |
1:dbc44582f2f8
|
353
|
//console=c;
|
tecnosys |
1:dbc44582f2f8
|
354
|
debug=true;
|
tecnosys |
1:dbc44582f2f8
|
355
|
}
|
tecnosys |
0:d8f50b1e384f
|
356
|
|
tecnosys |
1:dbc44582f2f8
|
357
|
void mcp2515::write_can_id( uint8_t mcp_addr,
|
tecnosys |
1:dbc44582f2f8
|
358
|
uint8_t ext, uint32_t can_id ) {
|
tecnosys |
0:d8f50b1e384f
|
359
|
uint16_t canid;
|
tecnosys |
0:d8f50b1e384f
|
360
|
uint8_t tbufdata[4];
|
tecnosys |
1:dbc44582f2f8
|
361
|
|
tecnosys |
0:d8f50b1e384f
|
362
|
canid = (uint16_t)(can_id & 0x0FFFF);
|
tecnosys |
1:dbc44582f2f8
|
363
|
|
tecnosys |
0:d8f50b1e384f
|
364
|
if ( ext == 1) {
|
tecnosys |
0:d8f50b1e384f
|
365
|
tbufdata[MCP_EID0] = (uint8_t) (canid & 0xFF);
|
tecnosys |
0:d8f50b1e384f
|
366
|
tbufdata[MCP_EID8] = (uint8_t) (canid / 256);
|
tecnosys |
0:d8f50b1e384f
|
367
|
canid = (uint16_t)( can_id / 0x10000L );
|
tecnosys |
0:d8f50b1e384f
|
368
|
tbufdata[MCP_SIDL] = (uint8_t) (canid & 0x03);
|
tecnosys |
0:d8f50b1e384f
|
369
|
tbufdata[MCP_SIDL] += (uint8_t) ((canid & 0x1C )*8);
|
tecnosys |
0:d8f50b1e384f
|
370
|
tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
|
tecnosys |
0:d8f50b1e384f
|
371
|
tbufdata[MCP_SIDH] = (uint8_t) (canid / 32 );
|
tecnosys |
1:dbc44582f2f8
|
372
|
} else {
|
tecnosys |
0:d8f50b1e384f
|
373
|
tbufdata[MCP_SIDH] = (uint8_t) (canid / 8 );
|
tecnosys |
0:d8f50b1e384f
|
374
|
tbufdata[MCP_SIDL] = (uint8_t) ((canid & 0x07 )*32);
|
tecnosys |
0:d8f50b1e384f
|
375
|
tbufdata[MCP_EID0] = 0;
|
tecnosys |
0:d8f50b1e384f
|
376
|
tbufdata[MCP_EID8] = 0;
|
tecnosys |
0:d8f50b1e384f
|
377
|
}
|
tecnosys |
0:d8f50b1e384f
|
378
|
setRegisterS( mcp_addr, tbufdata, 4 );
|
tecnosys |
0:d8f50b1e384f
|
379
|
}
|
tecnosys |
0:d8f50b1e384f
|
380
|
|
tecnosys |
0:d8f50b1e384f
|
381
|
// Buffer can be MCP_TXBUF_0 MCP_TXBUF_1 or MCP_TXBUF_2
|
tecnosys |
1:dbc44582f2f8
|
382
|
void mcp2515::write_canMsg( uint8_t buffer_sidh_addr,
|
tecnosys |
1:dbc44582f2f8
|
383
|
CANMessage* msg) {
|
tecnosys |
0:d8f50b1e384f
|
384
|
uint8_t mcp_addr, dlc;
|
tecnosys |
0:d8f50b1e384f
|
385
|
|
tecnosys |
0:d8f50b1e384f
|
386
|
mcp_addr = buffer_sidh_addr;
|
tecnosys |
0:d8f50b1e384f
|
387
|
dlc = msg->len;
|
tecnosys |
1:dbc44582f2f8
|
388
|
|
tecnosys |
0:d8f50b1e384f
|
389
|
setRegisterS(mcp_addr+5, &(msg->data[0]), dlc ); // write data bytes
|
tecnosys |
0:d8f50b1e384f
|
390
|
write_can_id( mcp_addr, msg->format,
|
tecnosys |
1:dbc44582f2f8
|
391
|
msg->id ); // write CAN id
|
tecnosys |
0:d8f50b1e384f
|
392
|
if ( msg->type == 1) dlc |= MCP_RTR_MASK; // if RTR set bit in byte
|
tecnosys |
0:d8f50b1e384f
|
393
|
setRegister( (mcp_addr+4), dlc ); // write the RTR and DLC
|
tecnosys |
0:d8f50b1e384f
|
394
|
}
|
tecnosys |
0:d8f50b1e384f
|
395
|
|
tecnosys |
1:dbc44582f2f8
|
396
|
void mcp2515::start_transmit( uint8_t buffer_sidh_addr) {
|
tecnosys |
1:dbc44582f2f8
|
397
|
// TXBnCTRL_addr = TXBnSIDH_addr - 1
|
tecnosys |
1:dbc44582f2f8
|
398
|
modifyRegister( buffer_sidh_addr-1 , MCP_TXB_TXREQ_M,
|
tecnosys |
1:dbc44582f2f8
|
399
|
MCP_TXB_TXREQ_M );
|
tecnosys |
0:d8f50b1e384f
|
400
|
}
|
tecnosys |
0:d8f50b1e384f
|
401
|
|
tecnosys |
1:dbc44582f2f8
|
402
|
uint8_t mcp2515::getNextFreeTXBuf(uint8_t *txbuf_n) {
|
tecnosys |
1:dbc44582f2f8
|
403
|
uint8_t res, i, ctrlval;
|
tecnosys |
1:dbc44582f2f8
|
404
|
uint8_t ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
|
tecnosys |
1:dbc44582f2f8
|
405
|
|
tecnosys |
1:dbc44582f2f8
|
406
|
res = MCP_ALLTXBUSY;
|
tecnosys |
1:dbc44582f2f8
|
407
|
*txbuf_n = 0x00;
|
tecnosys |
0:d8f50b1e384f
|
408
|
|
tecnosys |
1:dbc44582f2f8
|
409
|
// check all 3 TX-Buffers
|
tecnosys |
1:dbc44582f2f8
|
410
|
for (i=0; i<MCP_N_TXBUFFERS; i++) {
|
tecnosys |
1:dbc44582f2f8
|
411
|
ctrlval = readRegister( ctrlregs[i] );
|
tecnosys |
1:dbc44582f2f8
|
412
|
if ( (ctrlval & MCP_TXB_TXREQ_M) == 0 ) {
|
tecnosys |
1:dbc44582f2f8
|
413
|
|
tecnosys |
1:dbc44582f2f8
|
414
|
*txbuf_n = ctrlregs[i]+1; // return SIDH-address of Buffer
|
tecnosys |
1:dbc44582f2f8
|
415
|
res = MCP2515_OK;
|
tecnosys |
1:dbc44582f2f8
|
416
|
return res; /* ! function exit */
|
tecnosys |
1:dbc44582f2f8
|
417
|
}
|
tecnosys |
1:dbc44582f2f8
|
418
|
}
|
tecnosys |
1:dbc44582f2f8
|
419
|
|
tecnosys |
1:dbc44582f2f8
|
420
|
return res;
|
tecnosys |
0:d8f50b1e384f
|
421
|
}
|
tecnosys |
0:d8f50b1e384f
|
422
|
|
tecnosys |
1:dbc44582f2f8
|
423
|
void mcp2515::initCANBuffers(void) {
|
tecnosys |
1:dbc44582f2f8
|
424
|
// uint8_t i, a1, a2, a3;
|
tecnosys |
1:dbc44582f2f8
|
425
|
|
tecnosys |
1:dbc44582f2f8
|
426
|
// TODO: check why this is needed to receive extended
|
tecnosys |
0:d8f50b1e384f
|
427
|
// and standard frames
|
tecnosys |
0:d8f50b1e384f
|
428
|
// Mark all filter bits as don't care:
|
tecnosys |
0:d8f50b1e384f
|
429
|
write_can_id(MCP_RXM0SIDH, 0, 0);
|
tecnosys |
0:d8f50b1e384f
|
430
|
write_can_id(MCP_RXM1SIDH, 0, 0);
|
tecnosys |
0:d8f50b1e384f
|
431
|
// Anyway, set all filters to 0:
|
tecnosys |
1:dbc44582f2f8
|
432
|
write_can_id(MCP_RXF0SIDH, 1, 0); // RXB0: extended
|
tecnosys |
0:d8f50b1e384f
|
433
|
write_can_id(MCP_RXF1SIDH, 0, 0); // AND standard
|
tecnosys |
1:dbc44582f2f8
|
434
|
write_can_id(MCP_RXF2SIDH, 1, 0); // RXB1: extended
|
tecnosys |
0:d8f50b1e384f
|
435
|
write_can_id(MCP_RXF3SIDH, 0, 0); // AND standard
|
tecnosys |
0:d8f50b1e384f
|
436
|
write_can_id(MCP_RXF4SIDH, 0, 0);
|
tecnosys |
0:d8f50b1e384f
|
437
|
write_can_id(MCP_RXF5SIDH, 0, 0);
|
tecnosys |
1:dbc44582f2f8
|
438
|
/*
|
tecnosys |
0:d8f50b1e384f
|
439
|
// Clear, deactivate the three transmit buffers
|
tecnosys |
0:d8f50b1e384f
|
440
|
// TXBnCTRL -> TXBnD7
|
tecnosys |
0:d8f50b1e384f
|
441
|
a1 = MCP_TXB0CTRL;
|
tecnosys |
0:d8f50b1e384f
|
442
|
a2 = MCP_TXB1CTRL;
|
tecnosys |
0:d8f50b1e384f
|
443
|
a3 = MCP_TXB2CTRL;
|
tecnosys |
0:d8f50b1e384f
|
444
|
for (i = 0; i < 14; i++) { // in-buffer loop
|
tecnosys |
0:d8f50b1e384f
|
445
|
setRegister(a1, 0);
|
tecnosys |
0:d8f50b1e384f
|
446
|
setRegister(a2, 0);
|
tecnosys |
0:d8f50b1e384f
|
447
|
setRegister(a3, 0);
|
tecnosys |
0:d8f50b1e384f
|
448
|
a1++;
|
tecnosys |
0:d8f50b1e384f
|
449
|
a2++;
|
tecnosys |
0:d8f50b1e384f
|
450
|
a3++;
|
tecnosys |
0:d8f50b1e384f
|
451
|
}
|
tecnosys |
1:dbc44582f2f8
|
452
|
*/
|
tecnosys |
0:d8f50b1e384f
|
453
|
// and clear, deactivate the two receive buffers.
|
tecnosys |
1:dbc44582f2f8
|
454
|
// setRegister(MCP_RXB0CTRL, 0);
|
tecnosys |
1:dbc44582f2f8
|
455
|
//setRegister(MCP_RXB1CTRL, 0);
|
tecnosys |
0:d8f50b1e384f
|
456
|
}
|
tecnosys |
0:d8f50b1e384f
|
457
|
|
tecnosys |
1:dbc44582f2f8
|
458
|
uint8_t mcp2515::init( int canSpeed) {
|
tecnosys |
0:d8f50b1e384f
|
459
|
uint8_t res;
|
tecnosys |
1:dbc44582f2f8
|
460
|
|
tecnosys |
0:d8f50b1e384f
|
461
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
462
|
//MCP_CS_DDR |= ( 1 << MCP_CS_BIT );
|
tecnosys |
1:dbc44582f2f8
|
463
|
|
tecnosys |
0:d8f50b1e384f
|
464
|
_reset();
|
tecnosys |
1:dbc44582f2f8
|
465
|
|
tecnosys |
0:d8f50b1e384f
|
466
|
|
tecnosys |
0:d8f50b1e384f
|
467
|
res = setCANCTRL_Mode(MODE_CONFIG);
|
tecnosys |
1:dbc44582f2f8
|
468
|
|
tecnosys |
1:dbc44582f2f8
|
469
|
if ( res == MCP2515_FAIL ) {
|
tecnosys |
1:dbc44582f2f8
|
470
|
printf("\r\nCAN init failed %d\n\r",&_ncs);
|
tecnosys |
1:dbc44582f2f8
|
471
|
return res; /* function exit on error */
|
tecnosys |
0:d8f50b1e384f
|
472
|
}
|
tecnosys |
1:dbc44582f2f8
|
473
|
res = configRate2(canSpeed);
|
tecnosys |
1:dbc44582f2f8
|
474
|
|
tecnosys |
0:d8f50b1e384f
|
475
|
if ( res == MCP2515_OK ) {
|
tecnosys |
0:d8f50b1e384f
|
476
|
initCANBuffers();
|
tecnosys |
1:dbc44582f2f8
|
477
|
|
tecnosys |
0:d8f50b1e384f
|
478
|
|
tecnosys |
0:d8f50b1e384f
|
479
|
// enable both receive-buffers to receive messages
|
tecnosys |
0:d8f50b1e384f
|
480
|
// with std. and ext. identifiers
|
tecnosys |
0:d8f50b1e384f
|
481
|
// and enable rollover
|
tecnosys |
1:dbc44582f2f8
|
482
|
modifyRegister(MCP_RXB0CTRL,
|
tecnosys |
1:dbc44582f2f8
|
483
|
MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
|
tecnosys |
1:dbc44582f2f8
|
484
|
MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK );
|
tecnosys |
1:dbc44582f2f8
|
485
|
modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
|
tecnosys |
1:dbc44582f2f8
|
486
|
MCP_RXB_RX_STDEXT);
|
tecnosys |
0:d8f50b1e384f
|
487
|
|
tecnosys |
1:dbc44582f2f8
|
488
|
// Prescaler setting of the CLKOUT pin to zero
|
tecnosys |
1:dbc44582f2f8
|
489
|
// => Spending clock frequency of the CLKOUT pin MCP2515
|
tecnosys |
1:dbc44582f2f8
|
490
|
modifyRegister (MCP_CANCTRL, 0x07, CLKOUT_ENABLE);
|
tecnosys |
0:d8f50b1e384f
|
491
|
}
|
tecnosys |
1:dbc44582f2f8
|
492
|
|
tecnosys |
0:d8f50b1e384f
|
493
|
return res;
|
tecnosys |
0:d8f50b1e384f
|
494
|
}
|
tecnosys |
0:d8f50b1e384f
|
495
|
|
tecnosys |
0:d8f50b1e384f
|
496
|
/*
|
tecnosys |
0:d8f50b1e384f
|
497
|
* Select function
|
tecnosys |
0:d8f50b1e384f
|
498
|
*/
|
tecnosys |
1:dbc44582f2f8
|
499
|
|
tecnosys |
0:d8f50b1e384f
|
500
|
void mcp2515::_select() {
|
tecnosys |
0:d8f50b1e384f
|
501
|
//printf("{");
|
tecnosys |
0:d8f50b1e384f
|
502
|
_ncs = 0;
|
tecnosys |
0:d8f50b1e384f
|
503
|
}
|
tecnosys |
0:d8f50b1e384f
|
504
|
|
tecnosys |
0:d8f50b1e384f
|
505
|
|
tecnosys |
0:d8f50b1e384f
|
506
|
/*
|
tecnosys |
0:d8f50b1e384f
|
507
|
* Deselect function
|
tecnosys |
0:d8f50b1e384f
|
508
|
*/
|
tecnosys |
0:d8f50b1e384f
|
509
|
|
tecnosys |
0:d8f50b1e384f
|
510
|
void mcp2515::_deselect() {
|
tecnosys |
0:d8f50b1e384f
|
511
|
_ncs = 1;
|
tecnosys |
0:d8f50b1e384f
|
512
|
//printf("}");
|
tecnosys |
0:d8f50b1e384f
|
513
|
}
|
tecnosys |
0:d8f50b1e384f
|
514
|
|
tecnosys |
0:d8f50b1e384f
|
515
|
int mcp2515::status() {
|
tecnosys |
0:d8f50b1e384f
|
516
|
int status = 0;
|
tecnosys |
0:d8f50b1e384f
|
517
|
_select();
|
tecnosys |
1:dbc44582f2f8
|
518
|
spi.write(0xd7);
|
tecnosys |
1:dbc44582f2f8
|
519
|
status = (spi.write(0x00) << 8 );
|
tecnosys |
1:dbc44582f2f8
|
520
|
status |= spi.write(0x00);
|
tecnosys |
0:d8f50b1e384f
|
521
|
_deselect();
|
tecnosys |
0:d8f50b1e384f
|
522
|
return status;
|
tecnosys |
0:d8f50b1e384f
|
523
|
}
|
tecnosys |
0:d8f50b1e384f
|
524
|
|
tecnosys |
0:d8f50b1e384f
|
525
|
void mcp2515::_pollbusy() {
|
tecnosys |
0:d8f50b1e384f
|
526
|
volatile int busy = 1;
|
tecnosys |
0:d8f50b1e384f
|
527
|
while (busy) {
|
tecnosys |
0:d8f50b1e384f
|
528
|
// if bit 7 is set, we can proceed
|
tecnosys |
0:d8f50b1e384f
|
529
|
if ( status() & 0x80 ) {
|
tecnosys |
0:d8f50b1e384f
|
530
|
busy = 0;
|
tecnosys |
0:d8f50b1e384f
|
531
|
}
|
tecnosys |
0:d8f50b1e384f
|
532
|
}
|
tecnosys |
0:d8f50b1e384f
|
533
|
}
|
tecnosys |
0:d8f50b1e384f
|
534
|
|
tecnosys |
0:d8f50b1e384f
|
535
|
|
tecnosys |
1:dbc44582f2f8
|
536
|
uint8_t mcp2515::_spi_readwrite(uint8_t data) {
|
tecnosys |
1:dbc44582f2f8
|
537
|
//printf("W0x%x ", data);
|
tecnosys |
1:dbc44582f2f8
|
538
|
uint8_t ret = spi.write(data);
|
tecnosys |
1:dbc44582f2f8
|
539
|
// printf("R0x%x,", ret);
|
tecnosys |
0:d8f50b1e384f
|
540
|
return ret;
|
tecnosys |
0:d8f50b1e384f
|
541
|
}
|
tecnosys |
0:d8f50b1e384f
|
542
|
|
tecnosys |
1:dbc44582f2f8
|
543
|
uint8_t mcp2515::_spi_read(void) {
|
tecnosys |
0:d8f50b1e384f
|
544
|
return _spi_readwrite(SPI_NULL);
|
tecnosys |
0:d8f50b1e384f
|
545
|
}
|
tecnosys |
1:dbc44582f2f8
|
546
|
|
tecnosys |
1:dbc44582f2f8
|
547
|
void mcp2515::dumpExtendedStatus(void) {
|
tecnosys |
1:dbc44582f2f8
|
548
|
uint8_t tec, rec, eflg;
|
tecnosys |
1:dbc44582f2f8
|
549
|
|
tecnosys |
1:dbc44582f2f8
|
550
|
tec = readRegister(MCP_TEC);
|
tecnosys |
1:dbc44582f2f8
|
551
|
rec = readRegister(MCP_REC);
|
tecnosys |
1:dbc44582f2f8
|
552
|
eflg = readRegister(MCP_EFLG);
|
tecnosys |
1:dbc44582f2f8
|
553
|
|
tecnosys |
1:dbc44582f2f8
|
554
|
printf("MCP2515 Extended Status:\n\r");
|
tecnosys |
1:dbc44582f2f8
|
555
|
printf("MCP Transmit Error Count %d \r\n", tec);
|
tecnosys |
1:dbc44582f2f8
|
556
|
printf("MCP Receiver Error Count %d \n\r", rec);
|
tecnosys |
1:dbc44582f2f8
|
557
|
printf("MCP Error Flag %d\n\r", eflg);
|
tecnosys |
1:dbc44582f2f8
|
558
|
|
tecnosys |
1:dbc44582f2f8
|
559
|
if ( (rec>127) || (tec>127) ) {
|
tecnosys |
1:dbc44582f2f8
|
560
|
printf("Error-Passive or Bus-Off\n\r");
|
tecnosys |
1:dbc44582f2f8
|
561
|
}
|
tecnosys |
1:dbc44582f2f8
|
562
|
|
tecnosys |
1:dbc44582f2f8
|
563
|
if (eflg & MCP_EFLG_RX1OVR)
|
tecnosys |
1:dbc44582f2f8
|
564
|
printf("Receive Buffer 1 Overflow\r\n");
|
tecnosys |
1:dbc44582f2f8
|
565
|
if (eflg & MCP_EFLG_RX0OVR)
|
tecnosys |
1:dbc44582f2f8
|
566
|
printf("Receive Buffer 0 Overflow\n\r");
|
tecnosys |
1:dbc44582f2f8
|
567
|
if (eflg & MCP_EFLG_TXBO)
|
tecnosys |
1:dbc44582f2f8
|
568
|
printf("Bus-Off\n\r");
|
tecnosys |
1:dbc44582f2f8
|
569
|
if (eflg & MCP_EFLG_TXEP)
|
tecnosys |
1:dbc44582f2f8
|
570
|
printf("Receive Error Passive\n\r");
|
tecnosys |
1:dbc44582f2f8
|
571
|
if (eflg & MCP_EFLG_TXWAR)
|
tecnosys |
1:dbc44582f2f8
|
572
|
printf("Transmit Error Warning\n\r");
|
tecnosys |
1:dbc44582f2f8
|
573
|
if (eflg & MCP_EFLG_RXWAR)
|
tecnosys |
1:dbc44582f2f8
|
574
|
printf("Receive Error Warning\r\n");
|
tecnosys |
1:dbc44582f2f8
|
575
|
if (eflg & MCP_EFLG_EWARN )
|
tecnosys |
1:dbc44582f2f8
|
576
|
printf("Receive Error Warning\n\r");
|
tecnosys |
1:dbc44582f2f8
|
577
|
}
|