mcp2515.c
Go to the documentation of this file.
1 // coding: utf-8
2 // ----------------------------------------------------------------------------
3 /*
4  * Copyright (c) 2007 Fabian Greif, Roboterclub Aachen e.V.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $Id: mcp2515.c 8086 2009-07-14 14:08:25Z fabian $
29  */
30 // ----------------------------------------------------------------------------
31 /* ---- Beispiel zum Einstellen des Bit Timings ----
32  *
33  * Fosc = 16MHz
34  * BRP = 7
35  * TQ = 2 * (BRP + 1) / Fosc
36  * = 1 uS
37  *
38  * Sync Seg = = 1 TQ
39  * Prop Seg = (PRSEG + 1) * TQ = 1 TQ
40  * Phase Seg1 = (PHSEG1 + 1) * TQ = 3 TQ
41  * Phase Seg2 = (PHSEG2 + 1) * TQ = 3 TQ
42  * --------
43  * 8 TQ
44  *
45  * Bus speed = 1 / ((Total # of TQ) * TQ)
46  * = 1 / (8 * TQ) = 125 kHz
47  */
48 // -------------------------------------------------------------------------
49 
50 #include "mcp2515_private.h"
51 #ifdef SUPPORT_FOR_MCP2515__
52 
53 #ifndef MCP2515_CLKOUT_PRESCALER
54  #error MCP2515_CLKOUT_PRESCALER not defined!
55 #elif MCP2515_CLKOUT_PRESCALER == 0
56  #define CLKOUT_PRESCALER_ 0x0
57 #elif MCP2515_CLKOUT_PRESCALER == 1
58  #define CLKOUT_PRESCALER_ 0x4
59 #elif MCP2515_CLKOUT_PRESCALER == 2
60  #define CLKOUT_PRESCALER_ 0x5
61 #elif MCP2515_CLKOUT_PRESCALER == 4
62  #define CLKOUT_PRESCALER_ 0x6
63 #elif MCP2515_CLKOUT_PRESCALER == 8
64  #define CLKOUT_PRESCALER_ 0x7
65 #else
66  #error invaild value of MCP2515_CLKOUT_PRESCALER
67 #endif
68 
69 // -------------------------------------------------------------------------
70 void mcp2515_write_register( uint8_t adress, uint8_t data )
71 {
73 
75  spi_putc(adress);
76  spi_putc(data);
77 
78  SET(MCP2515_CS);
79 }
80 
81 // -------------------------------------------------------------------------
82 uint8_t mcp2515_read_register(uint8_t adress)
83 {
84  uint8_t data;
85 
87 
89  spi_putc(adress);
90 
91  data = spi_putc(0xff);
92 
93  SET(MCP2515_CS);
94 
95  return data;
96 }
97 
98 // -------------------------------------------------------------------------
99 void mcp2515_bit_modify(uint8_t adress, uint8_t mask, uint8_t data)
100 {
101  RESET(MCP2515_CS);
102 
104  spi_putc(adress);
105  spi_putc(mask);
106  spi_putc(data);
107 
108  SET(MCP2515_CS);
109 }
110 
111 // ----------------------------------------------------------------------------
112 uint8_t mcp2515_read_status(uint8_t type)
113 {
114  uint8_t data;
115 
116  RESET(MCP2515_CS);
117 
118  spi_putc(type);
119  data = spi_putc(0xff);
120 
121  SET(MCP2515_CS);
122 
123  return data;
124 }
125 
126 // -------------------------------------------------------------------------
127 
128 const uint8_t _mcp2515_cnf[8][3] PROGMEM = {
129  // 10 kbps
130  { 0x04,
131  0xb6,
132  0xe7
133  },
134  // 20 kbps
135  { 0x04,
136  0xb6,
137  0xd3
138  },
139  // 50 kbps
140  { 0x04,
141  0xb6,
142  0xc7
143  },
144  // 100 kbps
145  { 0x04,
146  0xb6,
147  0xc3
148  },
149  // 125 kbps
150  { (1<<PHSEG21), // CNF3
151  (1<<BTLMODE)|(1<<PHSEG11), // CNF2
152  (1<<BRP2)|(1<<BRP1)|(1<<BRP0) // CNF1
153  },
154  // 250 kbps
155  { 0x03,
156  0xac,
157  0x81
158  },
159  // 500 kbps
160  { 0x03,
161  0xac,
162  0x80
163  },
164  // 1 Mbps
165  { (1<<PHSEG21),
166  (1<<BTLMODE)|(1<<PHSEG11),
167  0
168  }
169 };
170 
171 // -------------------------------------------------------------------------
172 bool mcp2515_init(can_bitrate_t bitrate)
173 {
174  if (bitrate >= 8)
175  return false;
176 
177  SET(MCP2515_CS);
179 
180  // Aktivieren der Pins fuer das SPI Interface
181  RESET(P_SCK);
182  RESET(P_MOSI);
183  RESET(P_MISO);
184 
185  SET_OUTPUT(P_SCK);
186  SET_OUTPUT(P_MOSI);
187  SET_INPUT(P_MISO);
188 
189  // SPI Einstellung setzen
191 
192  // MCP2515 per Software Reset zuruecksetzten,
193  // danach ist er automatisch im Konfigurations Modus
194  RESET(MCP2515_CS);
196 
197  _delay_ms(1);
198 
199  SET(MCP2515_CS);
200 
201  // ein bisschen warten bis der MCP2515 sich neu gestartet hat
202  _delay_ms(10);
203 
204  // CNF1..3 Register laden (Bittiming)
205  RESET(MCP2515_CS);
207  spi_putc(CNF3);
208  for (uint8_t i=0; i<3 ;i++ ) {
209  spi_putc(pgm_read_byte(&_mcp2515_cnf[bitrate][i]));
210  }
211  // aktivieren/deaktivieren der Interrupts
212  spi_putc(MCP2515_INTERRUPTS);
213  SET(MCP2515_CS);
214 
215  // TXnRTS Bits als Inputs schalten
216  mcp2515_write_register(TXRTSCTRL, 0);
217 
218  #if defined(MCP2515_INT)
220  SET(MCP2515_INT);
221  #endif
222 
223  #ifdef RXnBF_FUNKTION
224  SET_INPUT(MCP2515_RX0BF);
225  SET_INPUT(MCP2515_RX1BF);
226 
227  SET(MCP2515_RX0BF);
228  SET(MCP2515_RX1BF);
229 
230  // Aktivieren der Pin-Funktionen fuer RX0BF und RX1BF
231  mcp2515_write_register(BFPCTRL, (1<<B0BFE)|(1<<B1BFE)|(1<<B0BFM)|(1<<B1BFM));
232  #else
233  #ifdef MCP2515_TRANSCEIVER_SLEEP
234  // activate the pin RX1BF as GPIO which is connected
235  // to RS of MCP2551 and set it to 0
236  mcp2515_write_register(BFPCTRL, (1<<B1BFE));
237  #else
238  // Deaktivieren der Pins RXnBF Pins (High Impedance State)
239  mcp2515_write_register(BFPCTRL, 0);
240  #endif
241  #endif
242 
243  // Testen ob das auf die beschreibenen Register zugegriffen werden kann
244  // (=> ist der Chip ueberhaupt ansprechbar?)
245  bool error = false;
246  if (mcp2515_read_register(CNF2) != pgm_read_byte(&_mcp2515_cnf[bitrate][1])) {
247  error = true;
248  }
249 
250  // Device zurueck in den normalen Modus versetzten
251  // und aktivieren/deaktivieren des Clkout-Pins
252  mcp2515_write_register(CANCTRL, CLKOUT_PRESCALER_);
253 
254  if (error) {
255  return false;
256  }
257  else
258  {
259  while ((mcp2515_read_register(CANSTAT) & 0xe0) != 0) {
260  // warten bis der neue Modus uebernommen wurde
261  }
262 
263  return true;
264  }
265 }
266 
267 #endif // SUPPORT_FOR_MCP2515__
B0BFE
#define B0BFE
Definition: mcp2515_defs.h:183
pyuavcan_v0.dsdl.parser.error
def error(fmt, *args)
Definition: parser.py:722
CNF2
#define CNF2
Definition: mcp2515_defs.h:94
SPI_RESET
#define SPI_RESET
Definition: mcp2515_defs.h:36
SPI_WRITE
#define SPI_WRITE
Definition: mcp2515_defs.h:39
can_bitrate_t
can_bitrate_t
Bitraten fuer den CAN-Bus.
Definition: can.h:83
mcp2515_spi_init
void mcp2515_spi_init(void)
Initialize SPI interface.
SPI_READ
#define SPI_READ
Definition: mcp2515_defs.h:37
SET
@ SET
Definition: lpc_types.h:62
PHSEG21
#define PHSEG21
Definition: mcp2515_defs.h:215
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
BTLMODE
#define BTLMODE
Bitdefinition von CNF2.
Definition: mcp2515_defs.h:219
B1BFM
#define B1BFM
Definition: mcp2515_defs.h:184
PHSEG11
#define PHSEG11
Definition: mcp2515_defs.h:222
CANSTAT
#define CANSTAT
Definition: mcp2515_defs.h:67
B1BFE
#define B1BFE
Definition: mcp2515_defs.h:182
CANCTRL
#define CANCTRL
Definition: mcp2515_defs.h:68
BRP0
#define BRP0
Definition: mcp2515_defs.h:236
BRP2
#define BRP2
Definition: mcp2515_defs.h:234
MCP2515_INT
#define MCP2515_INT
Definition: src/config.h:49
SET_OUTPUT
#define SET_OUTPUT(x)
Definition: utils.h:231
CNF3
#define CNF3
Definition: mcp2515_defs.h:93
mcp2515_private.h
SPI_BIT_MODIFY
#define SPI_BIT_MODIFY
Definition: mcp2515_defs.h:44
BRP1
#define BRP1
Definition: mcp2515_defs.h:235
B0BFM
#define B0BFM
Definition: mcp2515_defs.h:185
SET_INPUT
#define SET_INPUT(x)
Definition: utils.h:232
spi_putc
uint8_t spi_putc(uint8_t data)
Write/read one byte of the SPI interface.
TXRTSCTRL
#define TXRTSCTRL
Definition: mcp2515_defs.h:66
RESET
@ RESET
Definition: lpc_types.h:62
PROGMEM
const uint8_t can_filter[] PROGMEM
Definition: main.c:60
BFPCTRL
#define BFPCTRL
Definition: mcp2515_defs.h:65
MCP2515_CS
#define MCP2515_CS
Definition: src/config.h:48


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02