CANopenPIC
CANopenNode on PIC microcontrollers
Loading...
Searching...
No Matches
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
45extern "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 */
64typedef unsigned char bool_t;
65typedef float float32_t;
66typedef 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 */
132typedef 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 */
149typedef 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 */
157typedef 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 */
167typedef 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;
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 */
435typedef 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 */
unsigned int uint16_t
float float32_t
uint_fast8_t bool_t
unsigned char uint8_t
double float64_t