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