CANopenPIC
CANopenNode on PIC microcontrollers
Loading...
Searching...
No Matches
PIC24_dsPIC33
CO_driver_target.h
1
/*
2
* Microchip dsPIC33 or PIC24 specific definitions for CANopenNode.
3
*
4
* @file CO_driver_target.h
5
* @author Janez Paternoster
6
* @author Peter Rozsahegyi (EDS)
7
* @author Jens Nielsen (CAN receive)
8
* @copyright 2004 - 2020 Janez Paternoster
9
*
10
* This file is part of CANopenNode, an opensource CANopen Stack.
11
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
12
* For more information on CANopen see <http://www.can-cia.org/>.
13
*
14
* Licensed under the Apache License, Version 2.0 (the "License");
15
* you may not use this file except in compliance with the License.
16
* You may obtain a copy of the License at
17
*
18
* http://www.apache.org/licenses/LICENSE-2.0
19
*
20
* Unless required by applicable law or agreed to in writing, software
21
* distributed under the License is distributed on an "AS IS" BASIS,
22
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
* See the License for the specific language governing permissions and
24
* limitations under the License.
25
*/
26
27
28
#ifndef CO_DRIVER_TARGET
29
#define CO_DRIVER_TARGET
30
31
/* This file contains device and application specific definitions.
32
* It is included from CO_driver.h, which contains documentation
33
* for definitions below. */
34
35
#include <xc.h>
36
#include <stddef.h>
37
#include <stdbool.h>
38
#include <stdint.h>
39
40
#ifdef CO_DRIVER_CUSTOM
41
#include "CO_driver_custom.h"
42
#endif
43
44
#ifdef __cplusplus
45
extern
"C"
{
46
#endif
47
48
/* Stack configuration override from CO_driver.h.
49
* For more information see file CO_config.h. */
50
/* Use default options here, it is possible to reduce memory usage. */
51
52
53
/* Basic definitions */
54
#define CO_LITTLE_ENDIAN
55
#define CO_SWAP_16(x) x
56
#define CO_SWAP_32(x) x
57
#define CO_SWAP_64(x) x
58
#define CO_OWN_INTTYPES
59
#define PRIu32 "lu"
60
#define PRId32 "ld"
61
/* NULL is defined in stddef.h */
62
/* true and false are defined in stdbool.h */
63
/* int8_t to uint64_t are defined in stdint.h */
64
typedef
unsigned
char
bool_t
;
65
typedef
float
float32_t
;
66
typedef
long
double
float64_t
;
67
68
69
/* CAN message buffer sizes for CAN module 1 and 2. Valid values
70
* are 0, 4, 6, 8, 12, 16. Default is one TX and seven RX messages (FIFO). */
71
#ifndef CO_CAN1msgBuffSize
72
#define CO_CAN1msgBuffSize 8
73
#endif
74
#ifndef CO_CAN2msgBuffSize
75
#define CO_CAN2msgBuffSize 0
//CAN module 2 not used by default
76
#endif
77
78
/* Default DMA addresses for CAN modules. */
79
#ifndef CO_CAN1_DMA0
80
#define CO_CAN1_DMA0 ADDR_DMA0
81
#endif
82
#ifndef CO_CAN1_DMA1
83
#define CO_CAN1_DMA1 ADDR_DMA1
84
#endif
85
#ifndef CO_CAN2_DMA0
86
#define CO_CAN2_DMA0 ADDR_DMA2
87
#endif
88
#ifndef CO_CAN2_DMA1
89
#define CO_CAN2_DMA1 ADDR_DMA3
90
#endif
91
92
/* Define DMA attribute on supported platforms */
93
#if defined(__dsPIC33F__) || defined(__PIC24H__) || defined(__DMA_BASE)
94
#define __dma __attribute__((space(dma)))
95
#else
96
#define __dma
97
#if defined(__C30_VERSION__) && !defined(__XC16_VERSION__)
98
#define __builtin_dmaoffset(V) (uint16_t)V
99
#endif
100
#endif
101
102
/* Define EDS attribute on supported platforms */
103
#if defined(__HAS_EDS__)
104
#define __eds __attribute__((eds))
105
#if defined(__C30_VERSION__) && !defined(__XC16_VERSION__)
106
#define __builtin_dmapage(V) (uint16_t)0
107
#endif
108
#else
109
#define __eds
110
#define __eds__
111
#endif
112
113
/* CAN module base addresses */
114
#define ADDR_CAN1 ((void *)&C1CTRL1)
115
#define ADDR_CAN2 ((void *)&C2CTRL1)
116
117
/* DMA addresses */
118
#define ADDR_DMA0 ((uint16_t)&DMA0CON)
119
#define ADDR_DMA1 ((uint16_t)&DMA1CON)
120
#define ADDR_DMA2 ((uint16_t)&DMA2CON)
121
#define ADDR_DMA3 ((uint16_t)&DMA3CON)
122
#define ADDR_DMA4 ((uint16_t)&DMA4CON)
123
#define ADDR_DMA5 ((uint16_t)&DMA5CON)
124
#define ADDR_DMA6 ((uint16_t)&DMA6CON)
125
#define ADDR_DMA7 ((uint16_t)&DMA7CON)
126
127
128
/* CAN receive message structure as aligned in CAN module. */
129
/* In dsPIC33F and PIC24H this structure is used for both: transmitting and
130
* receiving to and from CAN module. (Object is ownded by CAN module).
131
*/
132
typedef
struct
{
133
uint16_t
ident;
/* Standard Identifier as aligned in CAN module. 16 bits:
134
'UUUSSSSS SSSSSSRE' (U: unused; S: SID; R=SRR; E=IDE). */
135
uint16_t
extIdent;
/* Extended identifier, not used here */
136
uint16_t
DLC :4;
/* Data length code (bits 0...3) */
137
uint16_t
DLCrest :12;
/* Not used here (bits 4..15) */
138
uint8_t
data[8];
/* 8 data bytes */
139
uint8_t
dummy;
/* Not used */
140
uint8_t
FILHIT;
/* Filter hit */
141
} CO_CANrxMsg_t;
142
143
/* Access to received CAN message */
144
#define CO_CANrxMsg_readIdent(msg) ((((uint16_t)(((CO_CANrxMsg_t *)(msg))->ident))>>2)&0x7FF)
145
#define CO_CANrxMsg_readDLC(msg) ((uint8_t)(((CO_CANrxMsg_t *)(msg))->DLC))
146
#define CO_CANrxMsg_readData(msg) ((uint8_t *)(((CO_CANrxMsg_t *)(msg))->data))
147
148
/* Received message object */
149
typedef
struct
{
150
uint16_t
ident;
151
uint16_t
mask;
152
void
*object;
153
void (*CANrx_callback)(
void
*object,
void
*message);
154
}
CO_CANrx_t
;
155
156
/* Transmit message object */
157
typedef
struct
{
158
uint16_t
ident;
/* Standard Identifier as aligned in CAN module. 16 bits:
159
'SSSSSUUU SSSSSSRE' (U: unused; S: SID; R=SRR; E=IDE). */
160
uint8_t
DLC;
161
uint8_t
data[8];
162
volatile
bool_t
bufferFull;
163
volatile
bool_t
syncFlag;
164
}
CO_CANtx_t
;
165
166
/* CAN module object */
167
typedef
struct
{
168
void
*CANptr;
169
__eds__ CO_CANrxMsg_t *CANmsgBuff;
/* dsPIC33F specific: CAN message buffer for CAN module */
170
uint8_t
CANmsgBuffSize;
/* dsPIC33F specific: Size of the above buffer */
171
CO_CANrx_t
*rxArray;
172
uint16_t
rxSize;
173
CO_CANtx_t
*txArray;
174
uint16_t
txSize;
175
uint16_t
CANerrorStatus;
176
volatile
bool_t
CANnormal;
177
volatile
bool_t
useCANrxFilters;
178
volatile
bool_t
bufferInhibitFlag;
179
volatile
bool_t
firstCANtxMessage;
180
volatile
uint16_t
CANtxCount;
181
uint16_t
errOld;
182
}
CO_CANmodule_t
;
183
184
185
/* (un)lock critical section in CO_CANsend() */
186
#define CO_LOCK_CAN_SEND(CAN_MODULE) asm volatile ("disi #0x3FFF")
187
#define CO_UNLOCK_CAN_SEND(CAN_MODULE) asm volatile ("disi #0x0000")
188
189
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
190
#define CO_LOCK_EMCY(CAN_MODULE) asm volatile ("disi #0x3FFF")
191
#define CO_UNLOCK_EMCY(CAN_MODULE) asm volatile ("disi #0x0000")
192
193
/* (un)lock critical section when accessing Object Dictionary */
194
#define CO_LOCK_OD(CAN_MODULE) asm volatile ("disi #0x3FFF")
195
#define CO_UNLOCK_OD(CAN_MODULE) asm volatile ("disi #0x0000")
196
197
/* dsPIC33F specific */
198
#define CO_DISABLE_INTERRUPTS() asm volatile ("disi #0x3FFF")
199
#define CO_ENABLE_INTERRUPTS() asm volatile ("disi #0x0000")
200
201
/* Synchronization between CAN receive and message processing threads. */
202
#define CO_MemoryBarrier()
203
#define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
204
#define CO_FLAG_SET(rxNew) {CO_MemoryBarrier(); rxNew = (void*)1L;}
205
#define CO_FLAG_CLEAR(rxNew) {CO_MemoryBarrier(); rxNew = NULL;}
206
207
208
/* CAN bit rates
209
*
210
* CAN bit rates are initializers for array of eight CO_CANbitRateData_t
211
* objects.
212
*
213
* Macros are not used by driver itself, they may be used by application with
214
* combination with object CO_CANbitRateData_t.
215
* Application must declare following global variable depending on CO_FCY used:
216
* const CO_CANbitRateData_t CO_CANbitRateData[8] = {CO_CANbitRateDataInitializers};
217
*
218
* There are initializers for eight objects, which corresponds to following
219
* CAN bit rates (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000.
220
*
221
* CO_FCY is internal instruction cycle clock frequency in kHz units. See
222
* dsPIC33F documentation for more information on FCY.
223
*
224
* Possible values for FCY are (in three groups):
225
* - Optimal CAN bit timing on all Baud Rates: 8000, 12000, 16000, 24000.
226
* - Not so optimal CAN bit timing on all Baud Rates: 4000, 32000.
227
* - not all CANopen Baud Rates possible: 2000, 3000, 5000, 6000, 10000,
228
* 20000, 40000, 48000, 56000, 64000, 70000.
229
*
230
* IMPORTANT: For FCY<=12000 there is unresolved bug; CANCKS configuration
231
* bit on ECAN does not work, so some baudrates are not possible.
232
*/
233
#ifdef CO_FCY
234
/* Macros, which divides K into (SJW + PROP + PhSeg1 + PhSeg2) */
235
#define TQ_x_4 1, 1, 1, 1
236
#define TQ_x_5 1, 1, 2, 1
237
#define TQ_x_6 1, 1, 3, 1
238
#define TQ_x_8 1, 2, 3, 2
239
#define TQ_x_9 1, 2, 4, 2
240
#define TQ_x_10 1, 3, 4, 2
241
#define TQ_x_12 1, 3, 6, 2
242
#define TQ_x_14 1, 4, 7, 2
243
#define TQ_x_15 1, 4, 8, 2
/* good timing */
244
#define TQ_x_16 1, 5, 8, 2
/* good timing */
245
#define TQ_x_17 1, 6, 8, 2
/* good timing */
246
#define TQ_x_18 1, 7, 8, 2
/* good timing */
247
#define TQ_x_19 1, 8, 8, 2
/* good timing */
248
#define TQ_x_20 1, 8, 8, 3
/* good timing */
249
#define TQ_x_21 1, 8, 8, 4
250
#define TQ_x_25 1, 8, 8, 8
251
252
#if CO_FCY == 2000
253
#define CO_CANbitRateDataInitializers \
254
{1, 5, TQ_x_20, 10}, \
255
{2, 5, TQ_x_20, 20}, \
256
{1, 1, TQ_x_20, 50}, \
257
{2, 1, TQ_x_16, 125}, \
258
{2, 1, TQ_x_8 , 250}, \
259
{2, 1, TQ_x_4 , 500}, \
260
{2, 1, TQ_x_4 , 0}, \
261
{2, 1, TQ_x_4 , 0}
262
#elif CO_FCY == 3000
263
#define CO_CANbitRateDataInitializers \
264
{2, 15, TQ_x_20, 10}, \
265
{1, 5, TQ_x_15, 20}, \
266
{1, 2, TQ_x_15, 50}, \
267
{1, 1, TQ_x_12, 125}, \
268
{2, 1, TQ_x_12, 250}, \
269
{2, 1, TQ_x_6 , 500}, \
270
{2, 1, TQ_x_6 , 0}, \
271
{2, 1, TQ_x_6 , 0}
272
#elif CO_FCY == 4000
273
#define CO_CANbitRateDataInitializers \
274
{2, 25, TQ_x_16, 10}, \
275
{1, 5, TQ_x_20, 20}, \
276
{2, 5, TQ_x_16, 50}, \
277
{1, 1, TQ_x_16, 125}, \
278
{2, 1, TQ_x_16, 250}, \
279
{2, 1, TQ_x_8 , 500}, \
280
{2, 1, TQ_x_5 , 800}, \
281
{2, 1, TQ_x_4 , 1000}
282
#elif CO_FCY == 5000
283
#define CO_CANbitRateDataInitializers \
284
{2, 25, TQ_x_20, 10}, \
285
{1, 5, TQ_x_25, 20}, \
286
{2, 5, TQ_x_20, 50}, \
287
{1, 1, TQ_x_20, 125}, \
288
{2, 1, TQ_x_20, 250}, \
289
{2, 1, TQ_x_10, 500}, \
290
{2, 1, TQ_x_10, 0}, \
291
{2, 1, TQ_x_5 , 1000}
292
#elif CO_FCY == 6000
293
#define CO_CANbitRateDataInitializers \
294
{1, 20, TQ_x_15, 10}, \
295
{1, 10, TQ_x_15, 20}, \
296
{1, 4, TQ_x_15, 50}, \
297
{2, 3, TQ_x_16, 125}, \
298
{1, 1, TQ_x_12, 250}, \
299
{2, 1, TQ_x_12, 500}, \
300
{2, 1, TQ_x_12, 0}, \
301
{2, 1, TQ_x_6 , 1000}
302
#elif CO_FCY == 8000
303
#define CO_CANbitRateDataInitializers \
304
{1, 25, TQ_x_16, 10}, \
305
{2, 25, TQ_x_16, 20}, \
306
{1, 5, TQ_x_16, 50}, \
307
{1, 2, TQ_x_16, 125}, \
308
{1, 1, TQ_x_16, 250}, \
309
{2, 1, TQ_x_16, 500}, \
310
{2, 1, TQ_x_10, 800}, \
311
{2, 1, TQ_x_8 , 1000}
312
#elif CO_FCY == 10000
313
#define CO_CANbitRateDataInitializers \
314
{1, 25, TQ_x_20, 10}, \
315
{2, 25, TQ_x_20, 20}, \
316
{1, 5, TQ_x_20, 50}, \
317
{2, 5, TQ_x_16, 125}, \
318
{1, 1, TQ_x_20, 250}, \
319
{2, 1, TQ_x_20, 500}, \
320
{2, 1, TQ_x_20, 0}, \
321
{2, 1, TQ_x_10, 1000}
322
#elif CO_FCY == 12000
323
#define CO_CANbitRateDataInitializers \
324
{2, 63, TQ_x_19, 10}, \
325
{1, 20, TQ_x_15, 20}, \
326
{2, 15, TQ_x_16, 50}, \
327
{1, 3, TQ_x_16, 125}, \
328
{2, 3, TQ_x_16, 250}, \
329
{1, 1, TQ_x_12, 500}, \
330
{2, 1, TQ_x_15, 800}, \
331
{2, 1, TQ_x_12, 1000}
332
#elif CO_FCY == 16000
333
#define CO_CANbitRateDataInitializers \
334
{1, 50, TQ_x_16, 10}, \
335
{1, 25, TQ_x_16, 20}, \
336
{1, 10, TQ_x_16, 50}, \
337
{1, 4, TQ_x_16, 125}, \
338
{1, 2, TQ_x_16, 250}, \
339
{1, 1, TQ_x_16, 500}, \
340
{1, 1, TQ_x_10, 800}, \
341
{1, 1, TQ_x_8 , 1000}
342
#elif CO_FCY == 20000
343
#define CO_CANbitRateDataInitializers \
344
{1, 50, TQ_x_20, 10}, \
345
{1, 25, TQ_x_20, 20}, \
346
{1, 10, TQ_x_20, 50}, \
347
{1, 5, TQ_x_16, 125}, \
348
{1, 2, TQ_x_20, 250}, \
349
{1, 1, TQ_x_20, 500}, \
350
{1, 1, TQ_x_20, 0}, \
351
{1, 1, TQ_x_10, 1000}
352
#elif CO_FCY == 24000
353
#define CO_CANbitRateDataInitializers \
354
{1, 63, TQ_x_19, 10}, \
355
{1, 40, TQ_x_15, 20}, \
356
{1, 15, TQ_x_16, 50}, \
357
{1, 6, TQ_x_16, 125}, \
358
{1, 3, TQ_x_16, 250}, \
359
{1, 2, TQ_x_12, 500}, \
360
{1, 1, TQ_x_15, 800}, \
361
{1, 1, TQ_x_12, 1000}
362
#elif CO_FCY == 32000
363
#define CO_CANbitRateDataInitializers \
364
{1, 64, TQ_x_25, 10}, \
365
{1, 50, TQ_x_16, 20}, \
366
{1, 20, TQ_x_16, 50}, \
367
{1, 8, TQ_x_16, 125}, \
368
{1, 4, TQ_x_16, 250}, \
369
{1, 2, TQ_x_16, 500}, \
370
{1, 2, TQ_x_10, 800}, \
371
{1, 1, TQ_x_16, 1000}
372
#elif CO_FCY == 40000
373
#define CO_CANbitRateDataInitializers \
374
{1, 50, TQ_x_20, 0}, \
375
{1, 50, TQ_x_20, 20}, \
376
{1, 25, TQ_x_16, 50}, \
377
{1, 10, TQ_x_16, 125}, \
378
{1, 5, TQ_x_16, 250}, \
379
{1, 2, TQ_x_20, 500}, \
380
{1, 1, TQ_x_25, 800}, \
381
{1, 1, TQ_x_20, 1000}
382
#elif CO_FCY == 48000
383
#define CO_CANbitRateDataInitializers \
384
{1, 63, TQ_x_19, 0}, \
385
{1, 63, TQ_x_19, 20}, \
386
{1, 30, TQ_x_16, 50}, \
387
{1, 12, TQ_x_16, 125}, \
388
{1, 6, TQ_x_16, 250}, \
389
{1, 3, TQ_x_16, 500}, \
390
{1, 2, TQ_x_15, 800}, \
391
{1, 2, TQ_x_12, 1000}
392
#elif CO_FCY == 56000
393
#define CO_CANbitRateDataInitializers \
394
{1, 61, TQ_x_23, 0}, \
395
{1, 61, TQ_x_23, 20}, \
396
{1, 35, TQ_x_16, 50}, \
397
{1, 14, TQ_x_16, 125}, \
398
{1, 7, TQ_x_16, 250}, \
399
{1, 4, TQ_x_14, 500}, \
400
{1, 5, TQ_x_7 , 800}, \
401
{1, 2, TQ_x_14, 1000}
402
#elif CO_FCY == 64000
403
#define CO_CANbitRateDataInitializers \
404
{1, 64, TQ_x_25, 0}, \
405
{1, 64, TQ_x_25, 20}, \
406
{1, 40, TQ_x_16, 50}, \
407
{1, 16, TQ_x_16, 125}, \
408
{1, 8, TQ_x_16, 250}, \
409
{1, 4, TQ_x_16, 500}, \
410
{1, 2, TQ_x_20, 800}, \
411
{1, 2, TQ_x_16, 1000}
412
#elif CO_FCY == 70000
413
#define CO_CANbitRateDataInitializers \
414
{1, 64, TQ_x_25, 0}, \
415
{1, 64, TQ_x_25, 20}, \
416
{1, 35, TQ_x_20, 50}, \
417
{1, 14, TQ_x_20, 125}, \
418
{1, 7, TQ_x_20, 250}, \
419
{1, 5, TQ_x_14, 500}, \
420
{1, 3, TQ_x_15, 0}, \
421
{1, 2, TQ_x_17, 0}
422
#else
423
#error define_CO_FCY CO_FCY not supported
424
#endif
425
#endif
426
427
/* Structure contains timing coefficients for CAN module.
428
*
429
* CAN baud rate is calculated from following equations:
430
* FCAN = FCY * Scale - Input frequency to CAN module (MAX 40MHz for dsPIC33F/PIC24H and 70MHz for dsPIC33E/PIC24E)
431
* TQ = 2 * BRP / FCAN - Time Quanta
432
* BaudRate = 1 / (TQ * K) - Can bus Baud Rate
433
* K = SJW + PROP + PhSeg1 + PhSeg2 - Number of Time Quantas
434
*/
435
typedef
struct
{
436
uint8_t
scale;
/* (1 or 2) Scales FCY clock - dsPIC33F and PIC24H specific */
437
uint8_t
BRP;
/* (1...64) Baud Rate Prescaler */
438
uint8_t
SJW;
/* (1...4) SJW time */
439
uint8_t
PROP;
/* (1...8) PROP time */
440
uint8_t
phSeg1;
/* (1...8) Phase Segment 1 time */
441
uint8_t
phSeg2;
/* (1...8) Phase Segment 2 time */
442
uint16_t
bitrate;
/* bitrate in kbps */
443
} CO_CANbitRateData_t;
444
445
#ifdef __cplusplus
446
}
447
#endif
/* __cplusplus */
448
449
#endif
/* CO_DRIVER_TARGET */
uint16_t
unsigned int uint16_t
float32_t
float float32_t
bool_t
uint_fast8_t bool_t
uint8_t
unsigned char uint8_t
float64_t
double float64_t
CO_CANmodule_t
CO_CANrx_t
CO_CANtx_t
Generated by
1.11.0