MCP2515 an Arduino mehr als 8 Frames senden

#5737600
Lesenswert?

Hallo,

ich möchte ganz gerne mehr als 8 Frames senden könnnen. Idealerweise 
würde ich gerne 16 Frames senden und empfangen können.

Also habe ich mir die "mcp_can.h" genommen und diese modifiziert. Alle 
Dateien in der mcp_can lib habe ich um "_ext" erweitert.
Geändert habe ich in der mcp_can_ext.h nur MAX_CHAR_IN_MESSAGE. Und zwar 
habe ich den Wert erstmal von 8 auf 9 gesetzt. Das gleiche habe ich mit 
CAN_MAX_CHAR_IN_MESSAGE in mcp_can_dfs_ext.h gemacht.
Aber es funktioniert nicht. In meinem Testscetch enthält der 9. Frame 
ein "c" obwohl dieser eine "9" beinhalten sollte.





mcp_can_ext.h:
1
/*
2
  mcp_can.h
3
  2012 Copyright (c) Seeed Technology Inc.  All right reserved.
4

5
  Author:Loovee
6
  2014-1-16
7
  
8
  Contributor: 
9
  
10
  Cory J. Fowler
11
  Latonita
12
  Woodward1
13
  Mehtajaghvi
14
  BykeBlast
15
  TheRo0T
16
  Tsipizic
17
  ralfEdmund
18
  Nathancheek
19
  BlueAndi
20
  Adlerweb
21
  Btetz
22
  Hurvajs
23
  
24
  The MIT License (MIT)
25

26
  Copyright (c) 2013 Seeed Technology Inc.
27

28
  Permission is hereby granted, free of charge, to any person obtaining a copy
29
  of this software and associated documentation files (the "Software"), to deal
30
  in the Software without restriction, including without limitation the rights
31
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
  copies of the Software, and to permit persons to whom the Software is
33
  furnished to do so, subject to the following conditions:
34

35
  The above copyright notice and this permission notice shall be included in
36
  all copies or substantial portions of the Software.
37

38
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
  THE SOFTWARE.
45
*/
46
#ifndef _MCP2515_H_
47
#define _MCP2515_H_
48

49
#include "mcp_can_dfs_ext.h"
50

51
#define MAX_CHAR_IN_MESSAGE 9
52

53
class MCP_CAN
54
{
55
    private:
56
    
57
    INT8U   m_nExtFlg;                                                  /* identifier xxxID             */
58
                                                                        /* either extended (the 29 LSB) */
59
                                                                        /* or standard (the 11 LSB)     */
60
    INT32U  m_nID;                                                      /* can id                       */
61
    INT8U   m_nDlc;                                                     /* data length:                 */
62
    INT8U   m_nDta[MAX_CHAR_IN_MESSAGE];                              /* data                         */
63
    INT8U   m_nRtr;                                                     /* rtr                          */
64
    INT8U   m_nfilhit;
65
    INT8U   SPICS;
66

67
/*
68
*  mcp2515 driver function 
69
*/
70
   // private:
71
private:
72

73
    void mcp2515_reset(void);                                           /* reset mcp2515                */
74

75
    INT8U mcp2515_readRegister(const INT8U address);                    /* read mcp2515's register      */
76
    
77
    void mcp2515_readRegisterS(const INT8U address, 
78
                         INT8U values[], 
79
                               const INT8U n);
80
    void mcp2515_setRegister(const INT8U address,                       /* set mcp2515's register       */
81
                             const INT8U value);
82

83
    void mcp2515_setRegisterS(const INT8U address,                      /* set mcp2515's registers      */
84
                              const INT8U values[],
85
                              const INT8U n);
86
    
87
    void mcp2515_initCANBuffers(void);
88
    
89
    void mcp2515_modifyRegister(const INT8U address,                    /* set bit of one register      */
90
                                const INT8U mask,
91
                                const INT8U data);
92

93
    INT8U mcp2515_readStatus(void);                                     /* read mcp2515's Status        */
94
    INT8U mcp2515_setCANCTRL_Mode(const INT8U newmode);                 /* set mode                     */
95
    INT8U mcp2515_configRate(const INT8U canSpeed);                     /* set boadrate                 */
96
    INT8U mcp2515_init(const INT8U canSpeed);                           /* mcp2515init                  */
97

98
    void mcp2515_write_id( const INT8U mcp_addr,                        /* write can id                 */
99
                               const INT8U ext,
100
                               const INT32U id );
101

102
    void mcp2515_read_id( const INT8U mcp_addr,                         /* read can id                  */
103
                                    INT8U* ext,
104
                                    INT32U* id );
105

106
    void mcp2515_write_canMsg( const INT8U buffer_sidh_addr );          /* write can msg                */
107
    void mcp2515_read_canMsg( const INT8U buffer_sidh_addr);            /* read can msg                 */
108
    void mcp2515_start_transmit(const INT8U mcp_addr);                  /* start transmit               */
109
    INT8U mcp2515_getNextFreeTXBuf(INT8U *txbuf_n);                     /* get Next free txbuf          */
110

111
/*
112
*  can operator function
113
*/    
114

115
    INT8U setMsg(INT32U id, INT8U ext, INT8U len, INT8U rtr, INT8U *pData); /* set message                  */  
116
    INT8U setMsg(INT32U id, INT8U ext, INT8U len, INT8U *pData); /* set message                  */  
117
    INT8U clearMsg();                                               /* clear all message to zero    */
118
    INT8U readMsg();                                                /* read message                 */
119
    INT8U sendMsg();                                                /* send message                 */
120

121
public:
122
    MCP_CAN(INT8U _CS);
123
    INT8U begin(INT8U speedset);                                    /* init can                     */
124
    INT8U init_Mask(INT8U num, INT8U ext, INT32U ulData);           /* init Masks                   */
125
    INT8U init_Filt(INT8U num, INT8U ext, INT32U ulData);           /* init filters                 */
126
    INT8U sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *buf);   /* send buf                     */
127
    INT8U sendMsgBuf(INT32U id, INT8U ext, INT8U len, INT8U *buf);   /* send buf                     */
128
    INT8U readMsgBuf(INT8U *len, INT8U *buf);                       /* read buf                     */
129
    INT8U readMsgBufID(INT32U *ID, INT8U *len, INT8U *buf);         /* read buf with object ID      */
130
    INT8U checkReceive(void);                                       /* if something received        */
131
    INT8U checkError(void);                                         /* if something error           */
132
    INT32U getCanId(void);                                          /* get can id when receive      */
133
    INT8U isRemoteRequest(void);                                    /* get RR flag when receive     */
134
    INT8U isExtendedFrame(void);                                    /* did we recieve 29bit frame?  */
135
};
136

137
#endif
138
/*********************************************************************************************************
139
  END FILE
140
*********************************************************************************************************/


mcp_can_dfs_ext.h:
1
/*
2
  mcp_can_dfs.h
3
  2012 Copyright (c) Seeed Technology Inc.  All right reserved.
4

5
  Author:Loovee
6
  2014-1-16
7
  
8
  Contributor: 
9
  
10
  Cory J. Fowler
11
  Latonita
12
  Woodward1
13
  Mehtajaghvi
14
  BykeBlast
15
  TheRo0T
16
  Tsipizic
17
  ralfEdmund
18
  Nathancheek
19
  BlueAndi
20
  Adlerweb
21
  Btetz
22
  Hurvajs
23
  xboxpro1
24
  
25
  The MIT License (MIT)
26

27
  Copyright (c) 2013 Seeed Technology Inc.
28

29
  Permission is hereby granted, free of charge, to any person obtaining a copy
30
  of this software and associated documentation files (the "Software"), to deal
31
  in the Software without restriction, including without limitation the rights
32
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
  copies of the Software, and to permit persons to whom the Software is
34
  furnished to do so, subject to the following conditions:
35

36
  The above copyright notice and this permission notice shall be included in
37
  all copies or substantial portions of the Software.
38

39
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
  THE SOFTWARE.
46
*/
47
#ifndef _MCP2515DFS_H_
48
#define _MCP2515DFS_H_
49

50
#include <Arduino.h>
51
#include <SPI.h>
52
#include <inttypes.h>
53

54
#ifndef INT32U
55
#define INT32U unsigned long
56
#endif
57

58
#ifndef INT8U
59
#define INT8U byte
60
#endif
61

62
// if print debug information
63
#define DEBUG_MODE 0
64

65
/*
66
 *   Begin mt
67
 */
68
#define TIMEOUTVALUE    50
69
#define MCP_SIDH        0
70
#define MCP_SIDL        1
71
#define MCP_EID8        2
72
#define MCP_EID0        3
73

74
#define MCP_TXB_EXIDE_M     0x08                                        /* In TXBnSIDL                  */
75
#define MCP_DLC_MASK        0x0F                                        /* 4 LSBits                     */
76
#define MCP_RTR_MASK        0x40                                        /* (1<<6) Bit 6                 */
77

78
#define MCP_RXB_RX_ANY      0x60
79
#define MCP_RXB_RX_EXT      0x40
80
#define MCP_RXB_RX_STD      0x20
81
#define MCP_RXB_RX_STDEXT   0x00
82
#define MCP_RXB_RX_MASK     0x60
83
#define MCP_RXB_BUKT_MASK   (1<<2)
84

85
/*
86
** Bits in the TXBnCTRL registers.
87
*/
88
#define MCP_TXB_TXBUFE_M    0x80
89
#define MCP_TXB_ABTF_M      0x40
90
#define MCP_TXB_MLOA_M      0x20
91
#define MCP_TXB_TXERR_M     0x10
92
#define MCP_TXB_TXREQ_M     0x08
93
#define MCP_TXB_TXIE_M      0x04
94
#define MCP_TXB_TXP10_M     0x03
95

96
#define MCP_TXB_RTR_M       0x40                                        /* In TXBnDLC                   */
97
#define MCP_RXB_IDE_M       0x08                                        /* In RXBnSIDL                  */
98
#define MCP_RXB_RTR_M       0x40                                        /* In RXBnDLC                   */
99

100
#define MCP_STAT_RXIF_MASK   (0x03)
101
#define MCP_STAT_RX0IF (1<<0)
102
#define MCP_STAT_RX1IF (1<<1)
103

104
#define MCP_EFLG_RX1OVR (1<<7)
105
#define MCP_EFLG_RX0OVR (1<<6)
106
#define MCP_EFLG_TXBO   (1<<5)
107
#define MCP_EFLG_TXEP   (1<<4)
108
#define MCP_EFLG_RXEP   (1<<3)
109
#define MCP_EFLG_TXWAR  (1<<2)
110
#define MCP_EFLG_RXWAR  (1<<1)
111
#define MCP_EFLG_EWARN  (1<<0)
112
#define MCP_EFLG_ERRORMASK  (0xF8)                                      /* 5 MS-Bits                    */
113

114

115
/*
116
 *   Define MCP2515 register addresses
117
 */
118

119
#define MCP_RXF0SIDH    0x00
120
#define MCP_RXF0SIDL    0x01
121
#define MCP_RXF0EID8    0x02
122
#define MCP_RXF0EID0    0x03
123
#define MCP_RXF1SIDH    0x04
124
#define MCP_RXF1SIDL    0x05
125
#define MCP_RXF1EID8    0x06
126
#define MCP_RXF1EID0    0x07
127
#define MCP_RXF2SIDH    0x08
128
#define MCP_RXF2SIDL    0x09
129
#define MCP_RXF2EID8    0x0A
130
#define MCP_RXF2EID0    0x0B
131
#define MCP_CANSTAT     0x0E
132
#define MCP_CANCTRL     0x0F
133
#define MCP_RXF3SIDH    0x10
134
#define MCP_RXF3SIDL    0x11
135
#define MCP_RXF3EID8    0x12
136
#define MCP_RXF3EID0    0x13
137
#define MCP_RXF4SIDH    0x14
138
#define MCP_RXF4SIDL    0x15
139
#define MCP_RXF4EID8    0x16
140
#define MCP_RXF4EID0    0x17
141
#define MCP_RXF5SIDH    0x18
142
#define MCP_RXF5SIDL    0x19
143
#define MCP_RXF5EID8    0x1A
144
#define MCP_RXF5EID0    0x1B
145
#define MCP_TEC         0x1C
146
#define MCP_REC         0x1D
147
#define MCP_RXM0SIDH    0x20
148
#define MCP_RXM0SIDL    0x21
149
#define MCP_RXM0EID8    0x22
150
#define MCP_RXM0EID0    0x23
151
#define MCP_RXM1SIDH    0x24
152
#define MCP_RXM1SIDL    0x25
153
#define MCP_RXM1EID8    0x26
154
#define MCP_RXM1EID0    0x27
155
#define MCP_CNF3        0x28
156
#define MCP_CNF2        0x29
157
#define MCP_CNF1        0x2A
158
#define MCP_CANINTE     0x2B
159
#define MCP_CANINTF     0x2C
160
#define MCP_EFLG        0x2D
161
#define MCP_TXB0CTRL    0x30
162
#define MCP_TXB1CTRL    0x40
163
#define MCP_TXB2CTRL    0x50
164
#define MCP_RXB0CTRL    0x60
165
#define MCP_RXB0SIDH    0x61
166
#define MCP_RXB1CTRL    0x70
167
#define MCP_RXB1SIDH    0x71
168

169

170
#define MCP_TX_INT          0x1C                                    // Enable all transmit interrup ts
171
#define MCP_TX01_INT        0x0C                                    // Enable TXB0 and TXB1 interru pts
172
#define MCP_RX_INT          0x03                                    // Enable receive interrupts
173
#define MCP_NO_INT          0x00                                    // Disable all interrupts
174

175
#define MCP_TX01_MASK       0x14
176
#define MCP_TX_MASK         0x54
177

178
/*
179
 *   Define SPI Instruction Set
180
 */
181

182
#define MCP_WRITE           0x02
183

184
#define MCP_READ            0x03
185

186
#define MCP_BITMOD          0x05
187

188
#define MCP_LOAD_TX0        0x40
189
#define MCP_LOAD_TX1        0x42
190
#define MCP_LOAD_TX2        0x44
191

192
#define MCP_RTS_TX0         0x81
193
#define MCP_RTS_TX1         0x82
194
#define MCP_RTS_TX2         0x84
195
#define MCP_RTS_ALL         0x87
196

197
#define MCP_READ_RX0        0x90
198
#define MCP_READ_RX1        0x94
199

200
#define MCP_READ_STATUS     0xA0
201

202
#define MCP_RX_STATUS       0xB0
203

204
#define MCP_RESET           0xC0
205

206

207
/*
208
 *   CANCTRL Register Values
209
 */
210

211
#define MODE_NORMAL     0x00
212
#define MODE_SLEEP      0x20
213
#define MODE_LOOPBACK   0x40
214
#define MODE_LISTENONLY 0x60
215
#define MODE_CONFIG     0x80
216
#define MODE_POWERUP    0xE0
217
#define MODE_MASK       0xE0
218
#define ABORT_TX        0x10
219
#define MODE_ONESHOT    0x08
220
#define CLKOUT_ENABLE   0x04
221
#define CLKOUT_DISABLE  0x00
222
#define CLKOUT_PS1      0x00
223
#define CLKOUT_PS2      0x01
224
#define CLKOUT_PS4      0x02
225
#define CLKOUT_PS8      0x03
226

227

228
/*
229
 *   CNF1 Register Values
230
 */
231

232
#define SJW1            0x00
233
#define SJW2            0x40
234
#define SJW3            0x80
235
#define SJW4            0xC0
236

237

238
/*
239
 *   CNF2 Register Values
240
 */
241

242
#define BTLMODE         0x80
243
#define SAMPLE_1X       0x00
244
#define SAMPLE_3X       0x40
245

246

247
/*
248
 *   CNF3 Register Values
249
 */
250

251
#define SOF_ENABLE      0x80
252
#define SOF_DISABLE     0x00
253
#define WAKFIL_ENABLE   0x40
254
#define WAKFIL_DISABLE  0x00
255

256

257
/*
258
 *   CANINTF Register Bits
259
 */
260

261
#define MCP_RX0IF       0x01
262
#define MCP_RX1IF       0x02
263
#define MCP_TX0IF       0x04
264
#define MCP_TX1IF       0x08
265
#define MCP_TX2IF       0x10
266
#define MCP_ERRIF       0x20
267
#define MCP_WAKIF       0x40
268
#define MCP_MERRF       0x80
269

270
/*
271
 *  speed 16M
272
 */
273
#define MCP_16MHz_1000kBPS_CFG1 (0x00)
274
#define MCP_16MHz_1000kBPS_CFG2 (0xD0)
275
#define MCP_16MHz_1000kBPS_CFG3 (0x82)
276

277
#define MCP_16MHz_500kBPS_CFG1 (0x00)
278
#define MCP_16MHz_500kBPS_CFG2 (0xF0)
279
#define MCP_16MHz_500kBPS_CFG3 (0x86)
280

281
#define MCP_16MHz_250kBPS_CFG1 (0x41)
282
#define MCP_16MHz_250kBPS_CFG2 (0xF1)
283
#define MCP_16MHz_250kBPS_CFG3 (0x85)
284

285
#define MCP_16MHz_200kBPS_CFG1 (0x01)
286
#define MCP_16MHz_200kBPS_CFG2 (0xFA)
287
#define MCP_16MHz_200kBPS_CFG3 (0x87)
288

289
#define MCP_16MHz_125kBPS_CFG1 (0x03)
290
#define MCP_16MHz_125kBPS_CFG2 (0xF0)
291
#define MCP_16MHz_125kBPS_CFG3 (0x86)
292

293
#define MCP_16MHz_100kBPS_CFG1 (0x03)
294
#define MCP_16MHz_100kBPS_CFG2 (0xFA)
295
#define MCP_16MHz_100kBPS_CFG3 (0x87)
296

297
#define MCP_16MHz_95kBPS_CFG1 (0x03)
298
#define MCP_16MHz_95kBPS_CFG2 (0xAD)
299
#define MCP_16MHz_95kBPS_CFG3 (0x07)
300

301
#define MCP_16MHz_83k3BPS_CFG1 (0x03)
302
#define MCP_16MHz_83k3BPS_CFG2 (0xBE)
303
#define MCP_16MHz_83k3BPS_CFG3 (0x07)
304

305
#define MCP_16MHz_80kBPS_CFG1 (0x03)
306
#define MCP_16MHz_80kBPS_CFG2 (0xFF)
307
#define MCP_16MHz_80kBPS_CFG3 (0x87)
308

309
#define MCP_16MHz_50kBPS_CFG1 (0x07)
310
#define MCP_16MHz_50kBPS_CFG2 (0xFA)
311
#define MCP_16MHz_50kBPS_CFG3 (0x87)
312

313
#define MCP_16MHz_40kBPS_CFG1 (0x07)
314
#define MCP_16MHz_40kBPS_CFG2 (0xFF)
315
#define MCP_16MHz_40kBPS_CFG3 (0x87)
316

317
#define MCP_16MHz_33kBPS_CFG1 (0x09)
318
#define MCP_16MHz_33kBPS_CFG2 (0xBE)
319
#define MCP_16MHz_33kBPS_CFG3 (0x07)
320

321
#define MCP_16MHz_31k25BPS_CFG1 (0x0F)
322
#define MCP_16MHz_31k25BPS_CFG2 (0xF1)
323
#define MCP_16MHz_31k25BPS_CFG3 (0x85)
324

325
#define MCP_16MHz_25kBPS_CFG1 (0X0F)
326
#define MCP_16MHz_25kBPS_CFG2 (0XBA)
327
#define MCP_16MHz_25kBPS_CFG3 (0X07)
328

329
#define MCP_16MHz_20kBPS_CFG1 (0x0F)
330
#define MCP_16MHz_20kBPS_CFG2 (0xFF)
331
#define MCP_16MHz_20kBPS_CFG3 (0x87)
332

333
#define MCP_16MHz_10kBPS_CFG1 (0x1F)
334
#define MCP_16MHz_10kBPS_CFG2 (0xFF)
335
#define MCP_16MHz_10kBPS_CFG3 (0x87)
336

337
#define MCP_16MHz_5kBPS_CFG1 (0x3F)
338
#define MCP_16MHz_5kBPS_CFG2 (0xFF)
339
#define MCP_16MHz_5kBPS_CFG3 (0x87)
340

341
#define MCP_16MHz_666kBPS_CFG1 (0x00)
342
#define MCP_16MHz_666kBPS_CFG2 (0xA0)
343
#define MCP_16MHz_666kBPS_CFG3 (0x04)
344

345

346
#define MCPDEBUG        (0)
347
#define MCPDEBUG_TXBUF  (0)
348
#define MCP_N_TXBUFFERS (3)
349

350
#define MCP_RXBUF_0 (MCP_RXB0SIDH)
351
#define MCP_RXBUF_1 (MCP_RXB1SIDH)
352

353
//#define SPICS 10
354
#define MCP2515_SELECT()   digitalWrite(SPICS, LOW)
355
#define MCP2515_UNSELECT() digitalWrite(SPICS, HIGH)
356

357
#define MCP2515_OK         (0)
358
#define MCP2515_FAIL       (1)
359
#define MCP_ALLTXBUSY      (2)
360

361
#define CANDEBUG   1
362

363
#define CANUSELOOP 0
364

365
#define CANSENDTIMEOUT (200)                                            /* milliseconds                 */
366

367
/*
368
 *   initial value of gCANAutoProcess
369
 */
370
#define CANAUTOPROCESS (1)
371
#define CANAUTOON  (1)
372
#define CANAUTOOFF (0)
373

374
#define CAN_STDID (0)
375
#define CAN_EXTID (1)
376

377
#define CANDEFAULTIDENT    (0x55CC)
378
#define CANDEFAULTIDENTEXT (CAN_EXTID)
379

380
#define CAN_5KBPS    1
381
#define CAN_10KBPS   2
382
#define CAN_20KBPS   3
383
#define CAN_25KBPS   4 
384
#define CAN_31K25BPS 5
385
#define CAN_33KBPS   6
386
#define CAN_40KBPS   7
387
#define CAN_50KBPS   8
388
#define CAN_80KBPS   9
389
#define CAN_83K3BPS  10
390
#define CAN_95KBPS   11
391
#define CAN_100KBPS  12
392
#define CAN_125KBPS  13
393
#define CAN_200KBPS  14
394
#define CAN_250KBPS  15
395
#define CAN_500KBPS  16
396
#define CAN_666KBPS  17
397
#define CAN_1000KBPS 18
398

399
#define CAN_OK                  (0)
400
#define CAN_FAILINIT            (1)
401
#define CAN_FAILTX              (2)
402
#define CAN_MSGAVAIL            (3)
403
#define CAN_NOMSG               (4)
404
#define CAN_CTRLERROR           (5)
405
#define CAN_GETTXBFTIMEOUT      (6)
406
#define CAN_SENDMSGTIMEOUT      (7)
407
#define CAN_FAIL                (0xff)
408

409
#define CAN_MAX_CHAR_IN_MESSAGE (9)
410

411
#endif
412
/*********************************************************************************************************
413
  END FILE
414
*********************************************************************************************************/


Ich bin nicht so fit in der Thematik. Hat vielleicht jemand eine Lösung 
für mich?
Danke!

MfG
Jonny
Angehängte Dateien:
#5737601
Lesenswert?

mcp_can_ext.ccp:
1
/*
2
  mcp_can.cpp
3
  2012 Copyright (c) Seeed Technology Inc.  All right reserved.
4

5
  Author:Loovee
6
  2014-1-16
7
  
8
  Contributor: 
9
  
10
  Cory J. Fowler
11
  Latonita
12
  Woodward1
13
  Mehtajaghvi
14
  BykeBlast
15
  TheRo0T
16
  Tsipizic
17
  ralfEdmund
18
  Nathancheek
19
  BlueAndi
20
  Adlerweb
21
  Btetz
22
  Hurvajs
23
  xboxpro1
24
  
25
  The MIT License (MIT)
26

27
  Copyright (c) 2013 Seeed Technology Inc.
28

29
  Permission is hereby granted, free of charge, to any person obtaining a copy
30
  of this software and associated documentation files (the "Software"), to deal
31
  in the Software without restriction, including without limitation the rights
32
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
  copies of the Software, and to permit persons to whom the Software is
34
  furnished to do so, subject to the following conditions:
35

36
  The above copyright notice and this permission notice shall be included in
37
  all copies or substantial portions of the Software.
38

39
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
  THE SOFTWARE.
46
*/
47
#include "mcp_can_ext.h"
48

49
#define spi_readwrite SPI.transfer
50
#define spi_read() spi_readwrite(0x00)
51
#define SPI_BEGIN() SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0))
52
#define SPI_END() SPI.endTransaction()
53

54
/*********************************************************************************************************
55
** Function name:           mcp2515_reset
56
** Descriptions:            reset the device
57
*********************************************************************************************************/
58
void MCP_CAN::mcp2515_reset(void)
59
{
60
    #ifdef SPI_HAS_TRANSACTION
61
      SPI_BEGIN();
62
    #endif
63
    MCP2515_SELECT();
64
    spi_readwrite(MCP_RESET);
65
    MCP2515_UNSELECT();
66
    #ifdef SPI_HAS_TRANSACTION
67
      SPI_END();
68
    #endif
69
    delay(10);
70
}
71

72
/*********************************************************************************************************
73
** Function name:           mcp2515_readRegister
74
** Descriptions:            read register
75
*********************************************************************************************************/
76
INT8U MCP_CAN::mcp2515_readRegister(const INT8U address)                                                                     
77
{
78
    INT8U ret;
79

80
    #ifdef SPI_HAS_TRANSACTION
81
      SPI_BEGIN();
82
    #endif
83
    MCP2515_SELECT();
84
    spi_readwrite(MCP_READ);
85
    spi_readwrite(address);
86
    ret = spi_read();
87
    MCP2515_UNSELECT();
88
    #ifdef SPI_HAS_TRANSACTION
89
      SPI_END();
90
    #endif
91

92
    return ret;
93
}
94

95
/*********************************************************************************************************
96
** Function name:           mcp2515_readRegisterS
97
** Descriptions:            read registerS
98
*********************************************************************************************************/
99
void MCP_CAN::mcp2515_readRegisterS(const INT8U address, INT8U values[], const INT8U n)
100
{
101
  INT8U i;
102
  #ifdef SPI_HAS_TRANSACTION
103
    SPI_BEGIN();
104
  #endif
105
  MCP2515_SELECT();
106
  spi_readwrite(MCP_READ);
107
  spi_readwrite(address);
108
  // mcp2515 has auto-increment of address-pointer
109
  for (i=0; i<n && i<CAN_MAX_CHAR_IN_MESSAGE; i++) {
110
    values[i] = spi_read();
111
  }
112
  MCP2515_UNSELECT();
113
  #ifdef SPI_HAS_TRANSACTION
114
    SPI_END();
115
  #endif
116
}
117

118
/*********************************************************************************************************
119
** Function name:           mcp2515_setRegister
120
** Descriptions:            set register
121
*********************************************************************************************************/
122
void MCP_CAN::mcp2515_setRegister(const INT8U address, const INT8U value)
123
{
124
    #ifdef SPI_HAS_TRANSACTION
125
      SPI_BEGIN();
126
    #endif
127
    MCP2515_SELECT();
128
    spi_readwrite(MCP_WRITE);
129
    spi_readwrite(address);
130
    spi_readwrite(value);
131
    MCP2515_UNSELECT();
132
    #ifdef SPI_HAS_TRANSACTION
133
      SPI_END();
134
    #endif
135
}
136

137
/*********************************************************************************************************
138
** Function name:           mcp2515_setRegisterS
139
** Descriptions:            set registerS
140
*********************************************************************************************************/
141
void MCP_CAN::mcp2515_setRegisterS(const INT8U address, const INT8U values[], const INT8U n)
142
{
143
    INT8U i;
144
    #ifdef SPI_HAS_TRANSACTION
145
      SPI_BEGIN();
146
    #endif
147
    MCP2515_SELECT();
148
    spi_readwrite(MCP_WRITE);
149
    spi_readwrite(address);
150
       
151
    for (i=0; i<n; i++) 
152
    {
153
        spi_readwrite(values[i]);
154
    }
155
    MCP2515_UNSELECT();
156
    #ifdef SPI_HAS_TRANSACTION
157
      SPI_END();
158
    #endif
159
}
160

161
/*********************************************************************************************************
162
** Function name:           mcp2515_modifyRegister
163
** Descriptions:            set bit of one register
164
*********************************************************************************************************/
165
void MCP_CAN::mcp2515_modifyRegister(const INT8U address, const INT8U mask, const INT8U data)
166
{
167
    #ifdef SPI_HAS_TRANSACTION
168
      SPI_BEGIN();
169
    #endif
170
    MCP2515_SELECT();
171
    spi_readwrite(MCP_BITMOD);
172
    spi_readwrite(address);
173
    spi_readwrite(mask);
174
    spi_readwrite(data);
175
    MCP2515_UNSELECT();
176
    #ifdef SPI_HAS_TRANSACTION
177
      SPI_END();
178
    #endif
179
}
180

181
/*********************************************************************************************************
182
** Function name:           mcp2515_readStatus
183
** Descriptions:            read mcp2515's Status
184
*********************************************************************************************************/
185
INT8U MCP_CAN::mcp2515_readStatus(void)                             
186
{
187
  INT8U i;
188
  #ifdef SPI_HAS_TRANSACTION
189
    SPI_BEGIN();
190
  #endif
191
  MCP2515_SELECT();
192
  spi_readwrite(MCP_READ_STATUS);
193
  i = spi_read();
194
  MCP2515_UNSELECT();
195
  #ifdef SPI_HAS_TRANSACTION
196
    SPI_END();
197
  #endif
198
  
199
  return i;
200
}
201

202
/*********************************************************************************************************
203
** Function name:           mcp2515_setCANCTRL_Mode
204
** Descriptions:            set control mode
205
*********************************************************************************************************/
206
INT8U MCP_CAN::mcp2515_setCANCTRL_Mode(const INT8U newmode)
207
{
208
    INT8U i;
209

210
    mcp2515_modifyRegister(MCP_CANCTRL, MODE_MASK, newmode);
211

212
    i = mcp2515_readRegister(MCP_CANCTRL);
213
    i &= MODE_MASK;
214

215
    if ( i == newmode ) 
216
    {
217
        return MCP2515_OK;
218
    }
219

220
    return MCP2515_FAIL;
221

222
}
223

224
/*********************************************************************************************************
225
** Function name:           mcp2515_configRate
226
** Descriptions:            set boadrate
227
*********************************************************************************************************/
228
INT8U MCP_CAN::mcp2515_configRate(const INT8U canSpeed)            
229
{
230
    INT8U set, cfg1, cfg2, cfg3;
231
    set = 1;
232
    switch (canSpeed)
233
    {
234
        case (CAN_5KBPS):
235
        cfg1 = MCP_16MHz_5kBPS_CFG1;
236
        cfg2 = MCP_16MHz_5kBPS_CFG2;
237
        cfg3 = MCP_16MHz_5kBPS_CFG3;
238
        break;
239

240
        case (CAN_10KBPS):
241
        cfg1 = MCP_16MHz_10kBPS_CFG1;
242
        cfg2 = MCP_16MHz_10kBPS_CFG2;
243
        cfg3 = MCP_16MHz_10kBPS_CFG3;
244
        break;
245

246
        case (CAN_20KBPS):
247
        cfg1 = MCP_16MHz_20kBPS_CFG1;
248
        cfg2 = MCP_16MHz_20kBPS_CFG2;
249
        cfg3 = MCP_16MHz_20kBPS_CFG3;
250
        break;
251
        
252
        case (CAN_25KBPS):
253
        cfg1 = MCP_16MHz_25kBPS_CFG1;
254
        cfg2 = MCP_16MHz_25kBPS_CFG2;
255
        cfg3 = MCP_16MHz_25kBPS_CFG3;
256
        break;
257
        
258
        case (CAN_31K25BPS):
259
        cfg1 = MCP_16MHz_31k25BPS_CFG1;
260
        cfg2 = MCP_16MHz_31k25BPS_CFG2;
261
        cfg3 = MCP_16MHz_31k25BPS_CFG3;
262
        break;
263

264
        case (CAN_33KBPS):
265
        cfg1 = MCP_16MHz_33kBPS_CFG1;
266
        cfg2 = MCP_16MHz_33kBPS_CFG2;
267
        cfg3 = MCP_16MHz_33kBPS_CFG3;
268
        break;
269

270
        case (CAN_40KBPS):
271
        cfg1 = MCP_16MHz_40kBPS_CFG1;
272
        cfg2 = MCP_16MHz_40kBPS_CFG2;
273
        cfg3 = MCP_16MHz_40kBPS_CFG3;
274
        break;
275

276
        case (CAN_50KBPS):
277
        cfg1 = MCP_16MHz_50kBPS_CFG1;
278
        cfg2 = MCP_16MHz_50kBPS_CFG2;
279
        cfg3 = MCP_16MHz_50kBPS_CFG3;
280
        break;
281

282
        case (CAN_80KBPS):
283
        cfg1 = MCP_16MHz_80kBPS_CFG1;
284
        cfg2 = MCP_16MHz_80kBPS_CFG2;
285
        cfg3 = MCP_16MHz_80kBPS_CFG3;
286
        break;
287

288
        case (CAN_83K3BPS):
289
        cfg1 = MCP_16MHz_83k3BPS_CFG1;
290
        cfg2 = MCP_16MHz_83k3BPS_CFG2;
291
        cfg3 = MCP_16MHz_83k3BPS_CFG3;
292
        break;  
293

294
        case (CAN_95KBPS):
295
        cfg1 = MCP_16MHz_95kBPS_CFG1;
296
        cfg2 = MCP_16MHz_95kBPS_CFG2;
297
        cfg3 = MCP_16MHz_95kBPS_CFG3;
298
        break;
299

300
        case (CAN_100KBPS):                                             /* 100KBPS                  */
301
        cfg1 = MCP_16MHz_100kBPS_CFG1;
302
        cfg2 = MCP_16MHz_100kBPS_CFG2;
303
        cfg3 = MCP_16MHz_100kBPS_CFG3;
304
        break;
305

306
        case (CAN_125KBPS):
307
        cfg1 = MCP_16MHz_125kBPS_CFG1;
308
        cfg2 = MCP_16MHz_125kBPS_CFG2;
309
        cfg3 = MCP_16MHz_125kBPS_CFG3;
310
        break;
311

312
        case (CAN_200KBPS):
313
        cfg1 = MCP_16MHz_200kBPS_CFG1;
314
        cfg2 = MCP_16MHz_200kBPS_CFG2;
315
        cfg3 = MCP_16MHz_200kBPS_CFG3;
316
        break;
317

318
        case (CAN_250KBPS):
319
        cfg1 = MCP_16MHz_250kBPS_CFG1;
320
        cfg2 = MCP_16MHz_250kBPS_CFG2;
321
        cfg3 = MCP_16MHz_250kBPS_CFG3;
322
        break;
323

324
        case (CAN_500KBPS):
325
        cfg1 = MCP_16MHz_500kBPS_CFG1;
326
        cfg2 = MCP_16MHz_500kBPS_CFG2;
327
        cfg3 = MCP_16MHz_500kBPS_CFG3;
328
        break;
329
        
330
  case (CAN_666KBPS):
331
        cfg1 = MCP_16MHz_666kBPS_CFG1;
332
        cfg2 = MCP_16MHz_666kBPS_CFG2;
333
        cfg3 = MCP_16MHz_666kBPS_CFG3;
334
        break;
335
        
336
        case (CAN_1000KBPS):
337
        cfg1 = MCP_16MHz_1000kBPS_CFG1;
338
        cfg2 = MCP_16MHz_1000kBPS_CFG2;
339
        cfg3 = MCP_16MHz_1000kBPS_CFG3;
340
        break;  
341

342
        default:
343
        set = 0;
344
        break;
345
    }
346

347
    if (set) {
348
        mcp2515_setRegister(MCP_CNF1, cfg1);
349
        mcp2515_setRegister(MCP_CNF2, cfg2);
350
        mcp2515_setRegister(MCP_CNF3, cfg3);
351
        return MCP2515_OK;
352
    }
353
    else {
354
        return MCP2515_FAIL;
355
    }
356
}
357

358
/*********************************************************************************************************
359
** Function name:           mcp2515_initCANBuffers
360
** Descriptions:            init canbuffers
361
*********************************************************************************************************/
362
void MCP_CAN::mcp2515_initCANBuffers(void)
363
{
364
    INT8U i, a1, a2, a3;
365

366
    a1 = MCP_TXB0CTRL;
367
    a2 = MCP_TXB1CTRL;
368
    a3 = MCP_TXB2CTRL;
369
    for (i = 0; i < 14; i++) {                                          /* in-buffer loop               */
370
        mcp2515_setRegister(a1, 0);
371
        mcp2515_setRegister(a2, 0);
372
        mcp2515_setRegister(a3, 0);
373
        a1++;
374
        a2++;
375
        a3++;
376
    }
377
    mcp2515_setRegister(MCP_RXB0CTRL, 0);
378
    mcp2515_setRegister(MCP_RXB1CTRL, 0);
379
}
380

381
/*********************************************************************************************************
382
** Function name:           mcp2515_init
383
** Descriptions:            init the device
384
*********************************************************************************************************/
385
INT8U MCP_CAN::mcp2515_init(const INT8U canSpeed)                       /* mcp2515init                  */
386
{
387

388
  INT8U res;
389

390
    mcp2515_reset();
391

392
    res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
393
    if(res > 0)
394
    {
395
#if DEBUG_MODE
396
      Serial.print("Enter setting mode fall\r\n"); 
397
#else
398
      delay(10);
399
#endif
400
      return res;
401
    }
402
#if DEBUG_MODE
403
    Serial.print("Enter setting mode success \r\n");
404
#else
405
    delay(10);
406
#endif
407

408
                                                                        /* set boadrate                 */
409
    if(mcp2515_configRate(canSpeed))
410
    {
411
#if DEBUG_MODE
412
      Serial.print("set rate fall!!\r\n");
413
#else
414
      delay(10);
415
#endif
416
      return res;
417
    }
418
#if DEBUG_MODE
419
    Serial.print("set rate success!!\r\n");
420
#else
421
    delay(10);
422
#endif
423

424
    if ( res == MCP2515_OK ) {
425

426
                                                                        /* init canbuffers              */
427
        mcp2515_initCANBuffers();
428

429
                                                                        /* interrupt mode               */
430
        mcp2515_setRegister(MCP_CANINTE, MCP_RX0IF | MCP_RX1IF);
431

432
#if (DEBUG_RXANY==1)
433
                                                                        /* enable both receive-buffers  */
434
                                                                        /* to receive any message       */
435
                                                                        /* and enable rollover          */
436
        mcp2515_modifyRegister(MCP_RXB0CTRL,
437
        MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
438
        MCP_RXB_RX_ANY | MCP_RXB_BUKT_MASK);
439
        mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
440
        MCP_RXB_RX_ANY);
441
#else
442
                                                                        /* enable both receive-buffers  */
443
                                                                        /* to receive messages          */
444
                                                                        /* with std. and ext. identifie */
445
                                                                        /* rs                           */
446
                                                                        /* and enable rollover          */
447
        mcp2515_modifyRegister(MCP_RXB0CTRL,
448
        MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
449
        MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK );
450
        mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
451
        MCP_RXB_RX_STDEXT);
452
#endif
453
                                                                        /* enter normal mode            */
454
        res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);                                                                
455
        if(res)
456
        {
457
#if DEBUG_MODE        
458
          Serial.print("Enter Normal Mode Fall!!\r\n");
459
#else
460
            delay(10);
461
#endif           
462
          return res;
463
        }
464

465

466
#if DEBUG_MODE
467
          Serial.print("Enter Normal Mode Success!!\r\n");
468
#else
469
            delay(10);
470
#endif
471

472
    }
473
    return res;
474

475
}
476

477
/*********************************************************************************************************
478
** Function name:           mcp2515_write_id
479
** Descriptions:            write can id
480
*********************************************************************************************************/
481
void MCP_CAN::mcp2515_write_id( const INT8U mcp_addr, const INT8U ext, const INT32U id )
482
{
483
    uint16_t canid;
484
    INT8U tbufdata[4];
485

486
    canid = (uint16_t)(id & 0x0FFFF);
487

488
    if ( ext == 1) 
489
    {
490
        tbufdata[MCP_EID0] = (INT8U) (canid & 0xFF);
491
        tbufdata[MCP_EID8] = (INT8U) (canid >> 8);
492
        canid = (uint16_t)(id >> 16);
493
        tbufdata[MCP_SIDL] = (INT8U) (canid & 0x03);
494
        tbufdata[MCP_SIDL] += (INT8U) ((canid & 0x1C) << 3);
495
        tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
496
        tbufdata[MCP_SIDH] = (INT8U) (canid >> 5 );
497
    }
498
    else 
499
    {
500
        tbufdata[MCP_SIDH] = (INT8U) (canid >> 3 );
501
        tbufdata[MCP_SIDL] = (INT8U) ((canid & 0x07 ) << 5);
502
        tbufdata[MCP_EID0] = 0;
503
        tbufdata[MCP_EID8] = 0;
504
    }
505
    mcp2515_setRegisterS( mcp_addr, tbufdata, 4 );
506
}
507

508
/*********************************************************************************************************
509
** Function name:           mcp2515_read_id
510
** Descriptions:            read can id
511
*********************************************************************************************************/
512
void MCP_CAN::mcp2515_read_id( const INT8U mcp_addr, INT8U* ext, INT32U* id )
513
{
514
    INT8U tbufdata[4];
515

516
    *ext = 0;
517
    *id = 0;
518

519
    mcp2515_readRegisterS( mcp_addr, tbufdata, 4 );
520

521
    *id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
522

523
    if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) ==  MCP_TXB_EXIDE_M ) 
524
    {
525
                                                                        /* extended id                  */
526
        *id = (*id<<2) + (tbufdata[MCP_SIDL] & 0x03);
527
        *id = (*id<<8) + tbufdata[MCP_EID8];
528
        *id = (*id<<8) + tbufdata[MCP_EID0];
529
        *ext = 1;
530
    }
531
}
532

533
/*********************************************************************************************************
534
** Function name:           mcp2515_write_canMsg
535
** Descriptions:            write msg
536
*********************************************************************************************************/
537
void MCP_CAN::mcp2515_write_canMsg( const INT8U buffer_sidh_addr)
538
{
539
    INT8U mcp_addr;
540
    mcp_addr = buffer_sidh_addr;
541
    mcp2515_setRegisterS(mcp_addr+5, m_nDta, m_nDlc );                  /* write data bytes             */
542
    if ( m_nRtr == 1)                                                   /* if RTR set bit in byte       */
543
    {
544
        m_nDlc |= MCP_RTR_MASK;  
545
    }
546
    mcp2515_setRegister((mcp_addr+4), m_nDlc );                        /* write the RTR and DLC        */
547
    mcp2515_write_id(mcp_addr, m_nExtFlg, m_nID );                     /* write CAN id                 */
548

549
}
550

551
/*********************************************************************************************************
552
** Function name:           mcp2515_read_canMsg
553
** Descriptions:            read message
554
*********************************************************************************************************/
555
void MCP_CAN::mcp2515_read_canMsg( const INT8U buffer_sidh_addr)        /* read can msg                 */
556
{
557
    INT8U mcp_addr, ctrl;
558

559
    mcp_addr = buffer_sidh_addr;
560

561
    mcp2515_read_id( mcp_addr, &m_nExtFlg,&m_nID );
562

563
    ctrl = mcp2515_readRegister( mcp_addr-1 );
564
    m_nDlc = mcp2515_readRegister( mcp_addr+4 );
565

566
    if ((ctrl & 0x08)) {
567
        m_nRtr = 1;
568
    }
569
    else {
570
        m_nRtr = 0;
571
    }
572

573
    m_nDlc &= MCP_DLC_MASK;
574
    mcp2515_readRegisterS( mcp_addr+5, &(m_nDta[0]), m_nDlc );
575
}
576

577
/*********************************************************************************************************
578
** Function name:           mcp2515_start_transmit
579
** Descriptions:            start transmit
580
*********************************************************************************************************/
581
void MCP_CAN::mcp2515_start_transmit(const INT8U mcp_addr)              /* start transmit               */
582
{
583
    mcp2515_modifyRegister( mcp_addr-1 , MCP_TXB_TXREQ_M, MCP_TXB_TXREQ_M );
584
}
585

586
/*********************************************************************************************************
587
** Function name:           mcp2515_getNextFreeTXBuf
588
** Descriptions:            get Next free txbuf
589
*********************************************************************************************************/
590
INT8U MCP_CAN::mcp2515_getNextFreeTXBuf(INT8U *txbuf_n)                 /* get Next free txbuf          */
591
{
592
    INT8U res, i, ctrlval;
593
    INT8U ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
594

595
    res = MCP_ALLTXBUSY;
596
    *txbuf_n = 0x00;
597

598
                                                                        /* check all 3 TX-Buffers       */
599
    for (i=0; i<MCP_N_TXBUFFERS; i++) {
600
        ctrlval = mcp2515_readRegister( ctrlregs[i] );
601
        if ( (ctrlval & MCP_TXB_TXREQ_M) == 0 ) {
602
            *txbuf_n = ctrlregs[i]+1;                                   /* return SIDH-address of Buffe */
603
                                                                        /* r                            */
604
            res = MCP2515_OK;
605
            return res;                                                 /* ! function exit              */
606
        }
607
    }
608
    return res;
609
}
610

611
/*********************************************************************************************************
612
** Function name:           set CS
613
** Descriptions:            init CS pin and set UNSELECTED
614
*********************************************************************************************************/
615
MCP_CAN::MCP_CAN(INT8U _CS)
616
{
617
    SPICS = _CS;
618
    pinMode(SPICS, OUTPUT);
619
    MCP2515_UNSELECT();
620
}
621

622
/*********************************************************************************************************
623
** Function name:           init
624
** Descriptions:            init can and set speed
625
*********************************************************************************************************/
626
INT8U MCP_CAN::begin(INT8U speedset)
627
{
628
    INT8U res;
629

630
    SPI.begin();
631
    res = mcp2515_init(speedset);
632
    if (res == MCP2515_OK) return CAN_OK;
633
    else return CAN_FAILINIT;
634
}
635

636
/*********************************************************************************************************
637
** Function name:           init_Mask
638
** Descriptions:            init canid Masks
639
*********************************************************************************************************/
640
INT8U MCP_CAN::init_Mask(INT8U num, INT8U ext, INT32U ulData)
641
{
642
    INT8U res = MCP2515_OK;
643
#if DEBUG_MODE
644
    Serial.print("Begin to set Mask!!\r\n");
645
#else
646
    delay(10);
647
#endif
648
    res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
649
    if(res > 0){
650
#if DEBUG_MODE
651
    Serial.print("Enter setting mode fall\r\n"); 
652
#else
653
    delay(10);
654
#endif
655
    return res;
656
    }
657
    
658
    if (num == 0){
659
        mcp2515_write_id(MCP_RXM0SIDH, ext, ulData);
660

661
    }
662
    else if(num == 1){
663
        mcp2515_write_id(MCP_RXM1SIDH, ext, ulData);
664
    }
665
    else res =  MCP2515_FAIL;
666
    
667
    res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
668
    if(res > 0){
669
#if DEBUG_MODE
670
    Serial.print("Enter normal mode fall\r\n"); 
671
#else
672
    delay(10);
673
#endif
674
    return res;
675
  }
676
#if DEBUG_MODE
677
    Serial.print("set Mask success!!\r\n");
678
#else
679
    delay(10);
680
#endif
681
    return res;
682
}
683

684
/*********************************************************************************************************
685
** Function name:           init_Filt
686
** Descriptions:            init canid filters
687
*********************************************************************************************************/
688
INT8U MCP_CAN::init_Filt(INT8U num, INT8U ext, INT32U ulData)
689
{
690
    INT8U res = MCP2515_OK;
691
#if DEBUG_MODE
692
    Serial.print("Begin to set Filter!!\r\n");
693
#else
694
    delay(10);
695
#endif
696
    res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
697
    if(res > 0)
698
    {
699
#if DEBUG_MODE
700
      Serial.print("Enter setting mode fall\r\n"); 
701
#else
702
      delay(10);
703
#endif
704
      return res;
705
    }
706
    
707
    switch( num )
708
    {
709
        case 0:
710
        mcp2515_write_id(MCP_RXF0SIDH, ext, ulData);
711
        break;
712

713
        case 1:
714
        mcp2515_write_id(MCP_RXF1SIDH, ext, ulData);
715
        break;
716

717
        case 2:
718
        mcp2515_write_id(MCP_RXF2SIDH, ext, ulData);
719
        break;
720

721
        case 3:
722
        mcp2515_write_id(MCP_RXF3SIDH, ext, ulData);
723
        break;
724

725
        case 4:
726
        mcp2515_write_id(MCP_RXF4SIDH, ext, ulData);
727
        break;
728

729
        case 5:
730
        mcp2515_write_id(MCP_RXF5SIDH, ext, ulData);
731
        break;
732

733
        default:
734
        res = MCP2515_FAIL;
735
    }
736
    
737
    res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
738
    if(res > 0)
739
    {
740
#if DEBUG_MODE
741
      Serial.print("Enter normal mode fall\r\nSet filter fail!!\r\n"); 
742
#else
743
      delay(10);
744
#endif
745
      return res;
746
    }
747
#if DEBUG_MODE
748
    Serial.print("set Filter success!!\r\n");
749
#else
750
    delay(10);
751
#endif
752
    
753
    return res;
754
}
755

756
/*********************************************************************************************************
757
** Function name:           setMsg
758
** Descriptions:            set can message, such as dlc, id, dta[] and so on
759
*********************************************************************************************************/
760
INT8U MCP_CAN::setMsg(INT32U id, INT8U ext, INT8U len, INT8U rtr, INT8U *pData)
761
{
762
    m_nExtFlg = ext;
763
    m_nID     = id;
764
    m_nDlc    = min( len, MAX_CHAR_IN_MESSAGE );
765
    m_nRtr    = rtr;
766
    for(int i = 0; i<m_nDlc; i++)
767
    {
768
        m_nDta[i] = *(pData+i);
769
    }
770
    return MCP2515_OK;
771
}
772

773

774
/*********************************************************************************************************
775
** Function name:           setMsg
776
** Descriptions:            set can message, such as dlc, id, dta[] and so on
777
*********************************************************************************************************/
778
INT8U MCP_CAN::setMsg(INT32U id, INT8U ext, INT8U len, INT8U *pData)
779
{
780
    return setMsg( id, ext, len, 0, pData );
781
}
782

783
/*********************************************************************************************************
784
** Function name:           clearMsg
785
** Descriptions:            set all message to zero
786
*********************************************************************************************************/
787
INT8U MCP_CAN::clearMsg()
788
{
789
    m_nID       = 0;
790
    m_nDlc      = 0;
791
    m_nExtFlg   = 0;
792
    m_nRtr      = 0;
793
    m_nfilhit   = 0;
794
    for(int i = 0; i<m_nDlc; i++ )
795
      m_nDta[i] = 0x00;
796

797
    return MCP2515_OK;
798
}
799

800
/*********************************************************************************************************
801
** Function name:           sendMsg
802
** Descriptions:            send message
803
*********************************************************************************************************/
804
INT8U MCP_CAN::sendMsg()
805
{
806
    INT8U res, res1, txbuf_n;
807
    uint16_t uiTimeOut = 0;
808

809
    do {
810
        res = mcp2515_getNextFreeTXBuf(&txbuf_n);                       /* info = addr.                 */
811
        uiTimeOut++;
812
    } while (res == MCP_ALLTXBUSY && (uiTimeOut < TIMEOUTVALUE));
813

814
    if(uiTimeOut == TIMEOUTVALUE) 
815
    {   
816
        return CAN_GETTXBFTIMEOUT;                                      /* get tx buff time out         */
817
    }
818
    uiTimeOut = 0;
819
    mcp2515_write_canMsg( txbuf_n);
820
    mcp2515_start_transmit( txbuf_n );
821
    do
822
    {
823
        uiTimeOut++;        
824
        res1= mcp2515_readRegister(txbuf_n-1 /* the ctrl reg is located at txbuf_n-1 */);  /* read send buff ctrl reg   */
825
        res1 = res1 & 0x08;                                   
826
    }while(res1 && (uiTimeOut < TIMEOUTVALUE));   
827
    if(uiTimeOut == TIMEOUTVALUE)                                       /* send msg timeout             */  
828
    {
829
        return CAN_SENDMSGTIMEOUT;
830
    }
831
    return CAN_OK;
832

833
}
834

835
/*********************************************************************************************************
836
** Function name:           sendMsgBuf
837
** Descriptions:            send buf
838
*********************************************************************************************************/
839
INT8U MCP_CAN::sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *buf)
840
{
841
    setMsg(id, ext, len, rtr, buf);
842
    return sendMsg();
843
}
844

845
/*********************************************************************************************************
846
** Function name:           sendMsgBuf
847
** Descriptions:            send buf
848
*********************************************************************************************************/
849
INT8U MCP_CAN::sendMsgBuf(INT32U id, INT8U ext, INT8U len, INT8U *buf)
850
{
851
    setMsg(id, ext, len, buf);
852
    return sendMsg();
853
}
854

855

856
/*********************************************************************************************************
857
** Function name:           readMsg
858
** Descriptions:            read message
859
*********************************************************************************************************/
860
INT8U MCP_CAN::readMsg()
861
{
862
    INT8U stat, res;
863

864
    stat = mcp2515_readStatus();
865

866
    if ( stat & MCP_STAT_RX0IF )                                        /* Msg in Buffer 0              */
867
    {
868
        mcp2515_read_canMsg( MCP_RXBUF_0);
869
        mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
870
        res = CAN_OK;
871
    }
872
    else if ( stat & MCP_STAT_RX1IF )                                   /* Msg in Buffer 1              */
873
    {
874
        mcp2515_read_canMsg( MCP_RXBUF_1);
875
        mcp2515_modifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
876
        res = CAN_OK;
877
    }
878
    else 
879
    {
880
        res = CAN_NOMSG;
881
    }
882
    return res;
883
}
884

885
/*********************************************************************************************************
886
** Function name:           readMsgBuf
887
** Descriptions:            read message buf
888
*********************************************************************************************************/
889
INT8U MCP_CAN::readMsgBuf(INT8U *len, INT8U buf[])
890
{
891
    INT8U  rc;
892
    
893
    rc = readMsg();
894
    
895
    if (rc == CAN_OK) {
896
       *len = m_nDlc;
897
       for(int i = 0; i<m_nDlc; i++) {
898
         buf[i] = m_nDta[i];
899
       } 
900
    } else {
901
          *len = 0;
902
    }
903
    return rc;
904
}
905

906
/*********************************************************************************************************
907
** Function name:           readMsgBufID
908
** Descriptions:            read message buf and can bus source ID
909
*********************************************************************************************************/
910
INT8U MCP_CAN::readMsgBufID(INT32U *ID, INT8U *len, INT8U buf[])
911
{
912
    INT8U rc;
913
    rc = readMsg();
914

915
    if (rc == CAN_OK) {
916
       *len = m_nDlc;
917
       *ID  = m_nID;
918
       for(int i = 0; i<m_nDlc && i < MAX_CHAR_IN_MESSAGE; i++) {
919
          buf[i] = m_nDta[i];
920
       }
921
    } else {
922
       *len = 0;
923
    }
924
    return rc;
925
}
926

927
/*********************************************************************************************************
928
** Function name:           checkReceive
929
** Descriptions:            check if got something
930
*********************************************************************************************************/
931
INT8U MCP_CAN::checkReceive(void)
932
{
933
    INT8U res;
934
    res = mcp2515_readStatus();                                         /* RXnIF in Bit 1 and 0         */
935
    if ( res & MCP_STAT_RXIF_MASK ) 
936
    {
937
        return CAN_MSGAVAIL;
938
    }
939
    else 
940
    {
941
        return CAN_NOMSG;
942
    }
943
}
944

945
/*********************************************************************************************************
946
** Function name:           checkError
947
** Descriptions:            if something error
948
*********************************************************************************************************/
949
INT8U MCP_CAN::checkError(void)
950
{
951
    INT8U eflg = mcp2515_readRegister(MCP_EFLG);
952

953
    if ( eflg & MCP_EFLG_ERRORMASK ) 
954
    {
955
        return CAN_CTRLERROR;
956
    }
957
    else 
958
    {
959
        return CAN_OK;
960
    }
961
}
962

963
/*********************************************************************************************************
964
** Function name:           getCanId
965
** Descriptions:            when receive something you can get the can id!!
966
*********************************************************************************************************/
967
INT32U MCP_CAN::getCanId(void)
968
{
969
    return m_nID;
970
} 
971

972
/*********************************************************************************************************
973
** Function name:           isRemoteRequest
974
** Descriptions:            when receive something you can check if it was a request
975
*********************************************************************************************************/
976
INT8U MCP_CAN::isRemoteRequest(void)
977
{
978
    return m_nRtr;
979
} 
980

981
/*********************************************************************************************************
982
** Function name:           isExtendedFrame
983
** Descriptions:            did we just receive standard 11bit frame or extended 29bit? 0 = std, 1 = ext
984
*********************************************************************************************************/
985
INT8U MCP_CAN::isExtendedFrame(void)
986
{
987
    return m_nExtFlg;
988
} 
989

990
/*********************************************************************************************************
991
  END FILE
992
*********************************************************************************************************/
#5737635
Lesenswert?

Was ist bei dir ein frame? Falls die die Anzahl der Datenbytes innerhalb 
einer message meinst - die kann nicht grösser als 8 sein. Kleiner ja.

Und wenn du mehr schicken willst/musst, gibts mehrere Möglichkeiten.
Am einfachsten 2 IDs mit je 8 Byte.
Oder du missbrauchst z.B. das erste Datenbyte, um mitzuteilen, welcher 
Teil nun kommt. Ergibt dann max. 256x7Byte auf einer ID.
#5739361
Lesenswert?

H.Joachim S. schrieb:
> Was ist bei dir ein frame? Falls die die Anzahl der Datenbytes innerhalb
> einer message meinst - die kann nicht grösser als 8 sein. Kleiner ja.

Genau, das Datenbyte ist gemeint.


H.Joachim S. schrieb:
> Oder du missbrauchst z.B. das erste Datenbyte, um mitzuteilen, welcher
> Teil nun kommt. Ergibt dann max. 256x7Byte auf einer ID.

So mache ich es momentan.

Ich habe in der Industrie mal einen Anwedungsfall gesehen, in dem mehr 
als 8 Frames in einer CAN-Nachricht enthalten war.
So würde ich es auch gerne machen, weil dadurch die CAN-Auslastung 
reduziert werden würde und beim Debugging alles leichter für mich zu 
lesen wäre.
Aber mir scheint es so, als wenn der MCP2515 nicht mehr als 8 Frames 
unterstützt.
Vielen Dank.
#5739405
Lesenswert?

CAN FD macht nur Sinn, wenn du wirklich ans Bandbreitenende kommst.

Jonny H. schrieb:
> weil dadurch die CAN-Auslastung
> reduziert werden würde und beim Debugging alles leichter für mich zu
> lesen wäre.
> Aber mir scheint es so, als wenn der MCP2515 nicht mehr als 8 Frames
> unterstützt.

Hohe Auslastung ist erstmal kein Problem, erst Überlastung wird eins. 
Bist du wirklich dran?? Ich habs noch nie gebraucht.
Und das mit dem debuggung ist ja nun wirklich kein Argument. Was spricht 
gegen 2 IDs?
Und nein, der MCP2515 kann kein FD.
#5739469
Lesenswert?

Nein sehr wahrscheinlich werde ich nicht an die Grenzen kommen.
Mein Ziel ist es ein komplettes Haus über CAN zu steuern. Also alle 
Lampen, Lichtschalter, ein paar Steckdosen, Jalousien, Sensoren 
(Raumtemperatur, Energiezählerstände, Fensterpositionen), 
Fußbodenheizung usw.
Ich habe bisher schon mit CAN-Bus gearbeitet aber ich habe noch nie 
einen großen CAN-Bus ausgelegt bzw. programmiert.

Bei meinem Vorhaben stoße ich natürlich im Bezug auf Bus-Länge schnell 
an die Grenzen des theoretisch machbaren. Deshalb bin ich am überlegen, 
ob ich einen CAN-Bus im Flur aufbaue und von dort aus über Repeater in 
mehrere Sub-CAN-Buse gehe. Damit kein einzelner CAN über eine gewisse 
Länge kommt. Denkbar wäre es auch, dass ich im Flur eine hohe 
Geschwindigkeit wähle und in den Sub-Bussen eine geringer wähle.
Vielleicht könnt ihr ja was zu dem Ansatz sagen oder vielleicht habt ihr 
eine bessere Idee!?

Eigentlich will ich auch schon seit 2 Jahren einen Prototypen aufbauen, 
aber mir fehlt es an Zeit.

Es spricht nichts gegen 2 Id's. Ich würde es nur schöner und 
komfortabler finden, wenn ich alles in einer Nachricht verpacken könnte.

Aber da bei meinem Vorhaben sehr viele CAN-Transceiver zum Einsatz 
kommen werden, spielt der Preis naürtlich eine Rolle. Und somit werde 
ich wohl bei dem MCP2515 bleiben.
#5739531
Lesenswert?

Jonny H. schrieb:
> Bei meinem Vorhaben stoße ich natürlich im Bezug auf Bus-Länge schnell
> an die Grenzen des theoretisch machbaren.

Warum? Einen Hausbus wird man kaum mit 1MBit laufen lassen. Ich habe 
jetzt bei mir 25kbit CAN vom Keller bis ins 1. Obergeschoß mit 5m 
Stichleitung.

> über Repeater in mehrere Sub-CAN-Buse gehe.
Viel zu umständlich. Wie gesagt, niedrigere Bitrate und Stichleitungen 
funktionieren dann auch problemlos.

Jonny H. schrieb:
> Ich würde es nur schöner und
> komfortabler finden, wenn ich alles in einer Nachricht verpacken könnte.

Was soll denn alles in eine Nachricht rein?
Eine Nachricht hat 64Bits. Man könnte also mit einer ID 64 Lampen ein- 
oder ausschalten.
Oder eine ID pro Raum für Licht und Rolladen? Dann reichen 8 Bytes auch 
wieder.

Für einen Hausbus CAN-FD zu verwenden finde ich völlig überzogen und 
macht das Unternehmen unnötig kompliziert.
#5739787
Lesenswert?

Um mehr als 8 Bytes zu übertragen, sendet man einfach mehrere Pakete 
nacheinander. Man kann z.B. ein Byte als Paketzähler benutzen und 7 
Nutzbyte. Damit kann man absichern, ob Pakete verloren gehen oder die 
Reihenfolge sich vertauscht hat.
So kann man z.B. im CAN-Bootloader ein Firmwareupdate übertragen.
Man kann aber auch im 29Bit Indentifier schon 2 Datenbyte senden, d.h. 
max 10 Byte je Paket.
Gast #5739795
Lesenswert?

Peter D. schrieb:
> Um mehr als 8 Bytes zu übertragen, sendet man einfach mehrere
> Pakete
> nacheinander. Man kann z.B. ein Byte als Paketzähler benutzen und 7
> Nutzbyte. Damit kann man absichern, ob Pakete verloren gehen oder die
> Reihenfolge sich vertauscht hat.
> So kann man z.B. im CAN-Bootloader ein Firmwareupdate übertragen.
> Man kann aber auch im 29Bit Indentifier schon 2 Datenbyte senden, d.h.
> max 10 Byte je Paket.

Um am Ende CANopen zu verwenden...
#5739796
Lesenswert?

Thomas F. schrieb:
> Jonny H. schrieb:
>> Bei meinem Vorhaben stoße ich natürlich im Bezug auf Bus-Länge schnell
>> an die Grenzen des theoretisch machbaren.
>
> Warum? Einen Hausbus wird man kaum mit 1MBit laufen lassen. Ich habe
> jetzt bei mir 25kbit CAN vom Keller bis ins 1. Obergeschoß mit 5m
> Stichleitung.

an so eine geringe Geschwindigkeit habe ich noch nicht gedacht. Aber 
reicht ja scheinbar auch.
Weisst du wie lang dein Bus ohne Stichleitungen ist? Wie viele 
Teilnehmer hast du ca? Was für Kabel verwendest du?

> Jonny H. schrieb:
>> Ich würde es nur schöner und
>> komfortabler finden, wenn ich alles in einer Nachricht verpacken könnte.
>
> Was soll denn alles in eine Nachricht rein?
> Eine Nachricht hat 64Bits. Man könnte also mit einer ID 64 Lampen ein-
> oder ausschalten.
> Oder eine ID pro Raum für Licht und Rolladen? Dann reichen 8 Bytes auch
> wieder.
>
> Für einen Hausbus CAN-FD zu verwenden finde ich völlig überzogen und
> macht das Unternehmen unnötig kompliziert.

Um Lampen zu schalten sendet der Master bisher:
- 2 Datenfelder bilden die Empfängernummer (jeder Teilnehmer hat eine 
Empfängernummer
- 2 Datenfelder die Sollhelligkeit. Wird noch auf 1 Datenfeld geändert. 
2 Datenfelder benötigte ich für einen anderen Ansatz
- 1 Datenfeld enthält die Ein- bzw. Ausschaltgeschwindigkeit der Lampen. 
Weil ich Tastdimmer realisieren will und die Leuchte dann langsammer 
eingestellt werden muss, wie als wenn man sie einfach nur Ein- oder 
Ausschaltet.
- 3 Datenfelder für RGB-Code (glaube zwar nicht das RGB-LEDs zum Einsatz 
kommen, aber ich will die Möglichkeit beibehalten

Das passt so weit gerade so.
Aber wenn ich zum Beispiel Energiezählerstände übertragen will, dann 
benötige ich den kompletten Frame für den Zählerstand. Aber die 
Energiezähler sollen noch mehr übertragen (Einstellungen, Anzahl der 
EEPROM-Schreibvorgänge, Manipulationsversuche [Mietwohnung] usw). Hier 
Übertrage ich die Zählerstände in mehreren Nachrichten. Das währe mit 
CAN-FD übersichtlicher, leichter.
#5739998
Lesenswert?

Samuel C. schrieb:
> Jonny H. schrieb:
>> Um Lampen zu schalten sendet der Master bisher:
>> - 2 Datenfelder bilden die Empfängernummer (jeder Teilnehmer hat eine
>> Empfängernummer
>
> Und den Identifier lässt du ungenutzt?

Nein, den benutze ich auch. Lampen haben z.B. eine andere ID als der 
Master.

Ich benötige die Empfängernummer, weil der Master den Lampen einen 
Sollwert vorgibt und die Lampen alle x Sekunden den Istwert ausgeben, 
damit dieser vom Master in eine Datenbank eingetragen werden kann bzw. 
damit die Statusleuchten in den Lichtschaltern (falls vorhanden) 
eingeschaltet werden können.
#5740005
Lesenswert?

Im Extended Mode hast du 29-Bit-Identifier. Damit kannst du eine halbe 
Million verschiedene Nachrichten definieren. Nutze das.
Verschicke jede Anweisung oder Status unter einem anderen Identifier.

So kannst du beispielsweise jeder Lampe 4 Identifier geben. Einer für 
Anweisungen des Masters, einer für Status und zwei weitere nach 
belieben. Und trotzdem kommt jede Lampe mit einer Maske aus. Wenn du die 
Identifier ordentlich zuteilst, kannst auch dafür sorgen, dass du zum 
Beispiel alle Nachrichten von Lampen über eine Maske empfängst.
#5740023
Lesenswert?

Jonny H. schrieb:
> Was für Kabel verwendest du?

Telefonkabel 2x2x0,14.

Jonny H. schrieb:
> - 2 Datenfelder bilden die Empfängernummer (jeder Teilnehmer hat eine
> Empfängernummer

Wozu? Wie Samuel schon schrieb benutzt man genau dazu die CAN-ID.

> Energiezähler sollen noch mehr übertragen ....Das währe mit
> CAN-FD übersichtlicher, leichter.

Nein wird es nicht. Viele Informationen in eine Botschaft zu packen oder 
Multiplex-Botschaften zu verwenden machen das ganze nur schwierig zu 
programmieren und verworren beim Debuggen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren