1 /* 2 * CAN module object for Microchip dsPIC33 or PIC24 microcontroller. 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_H 29 #define CO_DRIVER_TARGET_H 30 31 32 #if defined(__dsPIC33F__) || defined(__PIC24H__) 33 #include <p33Fxxxx.h> /* processor header file */ 34 #elif defined(__dsPIC33E__) || defined(__PIC24E__) 35 #include <p33Exxxx.h> /* processor header file */ 36 #endif 37 #include <stddef.h> /* for 'NULL' */ 38 #include <stdint.h> /* for 'int8_t' to 'uint64_t' */ 39 #include <stdbool.h> /* for 'true' and 'false' */ 40 41 /* Endianness */ 42 #define CO_LITTLE_ENDIAN 43 44 /* CAN message buffer sizes for CAN module 1 and 2. Valid values 45 * are 0, 4, 6, 8, 12, 16. Default is one TX and seven RX messages (FIFO). */ 46 #ifndef CO_CAN1msgBuffSize 47 #define CO_CAN1msgBuffSize 8 48 #endif /* CO_CAN1msgBuffSize */ 49 #ifndef CO_CAN2msgBuffSize 50 #define CO_CAN2msgBuffSize 0 //CAN module 2 not used by default 51 #endif /* CO_CAN2msgBuffSize */ 52 53 54 /* Default DMA addresses for CAN modules. */ 55 #ifndef CO_CAN1_DMA0 56 #define CO_CAN1_DMA0 ADDR_DMA0 57 #endif /* CO_CAN1_DMA0 */ 58 #ifndef CO_CAN1_DMA1 59 #define CO_CAN1_DMA1 ADDR_DMA1 60 #endif /* CO_CAN1_DMA1 */ 61 #ifndef CO_CAN2_DMA0 62 #define CO_CAN2_DMA0 ADDR_DMA2 63 #endif /* CO_CAN2_DMA0 */ 64 #ifndef CO_CAN2_DMA1 65 #define CO_CAN2_DMA1 ADDR_DMA3 66 #endif /* CO_CAN2_DMA1 */ 67 68 69 /* Define DMA attribute on supported platforms */ 70 #if defined(__dsPIC33F__) || defined(__PIC24H__) || defined(__DMA_BASE) 71 #define __dma __attribute__((space(dma))) 72 #else 73 #define __dma 74 #if defined(__C30_VERSION__) && !defined(__XC16_VERSION__) 75 #define __builtin_dmaoffset(V) (uint16_t)V 76 #endif 77 #endif 78 79 /* Define EDS attribute on supported platforms */ 80 #if defined(__HAS_EDS__) 81 #define __eds __attribute__((eds)) 82 #if defined(__C30_VERSION__) && !defined(__XC16_VERSION__) 83 #define __builtin_dmapage(V) (uint16_t)0 84 #endif 85 #else 86 #define __eds 87 #define __eds__ 88 #endif 89 90 91 /* CAN module base addresses */ 92 #define ADDR_CAN1 ((uint16_t)&C1CTRL1) 93 #define ADDR_CAN2 ((uint16_t)&C2CTRL1) 94 95 /* DMA addresses */ 96 #define ADDR_DMA0 ((uint16_t)&DMA0CON) 97 #define ADDR_DMA1 ((uint16_t)&DMA1CON) 98 #define ADDR_DMA2 ((uint16_t)&DMA2CON) 99 #define ADDR_DMA3 ((uint16_t)&DMA3CON) 100 #define ADDR_DMA4 ((uint16_t)&DMA4CON) 101 #define ADDR_DMA5 ((uint16_t)&DMA5CON) 102 #define ADDR_DMA6 ((uint16_t)&DMA6CON) 103 #define ADDR_DMA7 ((uint16_t)&DMA7CON) 104 105 106 /* Critical sections */ 107 #define CO_LOCK_CAN_SEND() asm volatile ("disi #0x3FFF") 108 #define CO_UNLOCK_CAN_SEND() asm volatile ("disi #0x0000") 109 110 #define CO_LOCK_EMCY() asm volatile ("disi #0x3FFF") 111 #define CO_UNLOCK_EMCY() asm volatile ("disi #0x0000") 112 113 #define CO_LOCK_OD() asm volatile ("disi #0x3FFF") 114 #define CO_UNLOCK_OD() asm volatile ("disi #0x0000") 115 116 #define CO_DISABLE_INTERRUPTS() asm volatile ("disi #0x3FFF") 117 #define CO_ENABLE_INTERRUPTS() asm volatile ("disi #0x0000") 118 119 120 /* Data types */ 121 /* int8_t to uint64_t are defined in stdint.h */ 122 typedef unsigned char bool_t; 123 typedef float float32_t; 124 typedef long double float64_t; 125 typedef char char_t; 126 typedef unsigned char oChar_t; 127 typedef unsigned char domain_t; 128 129 130 /* CAN bit rates 131 * 132 * CAN bit rates are initializers for array of eight CO_CANbitRateData_t 133 * objects. 134 * 135 * Macros are not used by driver itself, they may be used by application with 136 * combination with object CO_CANbitRateData_t. 137 * Application must declare following global variable depending on CO_FCY used: 138 * const CO_CANbitRateData_t CO_CANbitRateData[8] = {CO_CANbitRateDataInitializers}; 139 * 140 * There are initializers for eight objects, which corresponds to following 141 * CAN bit rates (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000. 142 * 143 * CO_FCY is internal instruction cycle clock frequency in kHz units. See 144 * dsPIC33F documentation for more information on FCY. 145 * 146 * Possible values for FCY are (in three groups): 147 * - Optimal CAN bit timing on all Baud Rates: 8000, 12000, 16000, 24000. 148 * - Not so optimal CAN bit timing on all Baud Rates: 4000, 32000. 149 * - not all CANopen Baud Rates possible: 2000, 3000, 5000, 6000, 10000, 150 * 20000, 40000, 48000, 56000, 64000, 70000. 151 * 152 * IMPORTANT: For FCY<=12000 there is unresolved bug; CANCKS configuration 153 * bit on ECAN does not work, so some baudrates are not possible. 154 */ 155 #ifdef CO_FCY 156 /* Macros, which divides K into (SJW + PROP + PhSeg1 + PhSeg2) */ 157 #define TQ_x_4 1, 1, 1, 1 158 #define TQ_x_5 1, 1, 2, 1 159 #define TQ_x_6 1, 1, 3, 1 160 #define TQ_x_8 1, 2, 3, 2 161 #define TQ_x_9 1, 2, 4, 2 162 #define TQ_x_10 1, 3, 4, 2 163 #define TQ_x_12 1, 3, 6, 2 164 #define TQ_x_14 1, 4, 7, 2 165 #define TQ_x_15 1, 4, 8, 2 /* good timing */ 166 #define TQ_x_16 1, 5, 8, 2 /* good timing */ 167 #define TQ_x_17 1, 6, 8, 2 /* good timing */ 168 #define TQ_x_18 1, 7, 8, 2 /* good timing */ 169 #define TQ_x_19 1, 8, 8, 2 /* good timing */ 170 #define TQ_x_20 1, 8, 8, 3 /* good timing */ 171 #define TQ_x_21 1, 8, 8, 4 172 #define TQ_x_25 1, 8, 8, 8 173 174 #if CO_FCY == 2000 175 #define CO_CANbitRateDataInitializers \ 176 {1, 5, TQ_x_20}, /*CAN=10kbps*/ \ 177 {2, 5, TQ_x_20}, /*CAN=20kbps*/ \ 178 {1, 1, TQ_x_20}, /*CAN=50kbps*/ \ 179 {2, 1, TQ_x_16}, /*CAN=125kbps*/ \ 180 {2, 1, TQ_x_8 }, /*CAN=250kbps*/ \ 181 {2, 1, TQ_x_4 }, /*CAN=500kbps*/ \ 182 {2, 1, TQ_x_4 }, /*Not possible*/ \ 183 {2, 1, TQ_x_4 } /*Not possible*/ 184 #elif CO_FCY == 3000 185 #define CO_CANbitRateDataInitializers \ 186 {2, 15, TQ_x_20}, /*CAN=10kbps*/ \ 187 {1, 5, TQ_x_15}, /*CAN=20kbps*/ \ 188 {1, 2, TQ_x_15}, /*CAN=50kbps*/ \ 189 {1, 1, TQ_x_12}, /*CAN=125kbps*/ \ 190 {2, 1, TQ_x_12}, /*CAN=250kbps*/ \ 191 {2, 1, TQ_x_6 }, /*CAN=500kbps*/ \ 192 {2, 1, TQ_x_6 }, /*Not possible*/ \ 193 {2, 1, TQ_x_6 } /*Not possible*/ 194 #elif CO_FCY == 4000 195 #define CO_CANbitRateDataInitializers \ 196 {2, 25, TQ_x_16}, /*CAN=10kbps*/ \ 197 {1, 5, TQ_x_20}, /*CAN=20kbps*/ \ 198 {2, 5, TQ_x_16}, /*CAN=50kbps*/ \ 199 {1, 1, TQ_x_16}, /*CAN=125kbps*/ \ 200 {2, 1, TQ_x_16}, /*CAN=250kbps*/ \ 201 {2, 1, TQ_x_8 }, /*CAN=500kbps*/ \ 202 {2, 1, TQ_x_5 }, /*CAN=800kbps*/ \ 203 {2, 1, TQ_x_4 } /*CAN=1000kbps*/ 204 #elif CO_FCY == 5000 205 #define CO_CANbitRateDataInitializers \ 206 {2, 25, TQ_x_20}, /*CAN=10kbps*/ \ 207 {1, 5, TQ_x_25}, /*CAN=20kbps*/ \ 208 {2, 5, TQ_x_20}, /*CAN=50kbps*/ \ 209 {1, 1, TQ_x_20}, /*CAN=125kbps*/ \ 210 {2, 1, TQ_x_20}, /*CAN=250kbps*/ \ 211 {2, 1, TQ_x_10}, /*CAN=500kbps*/ \ 212 {2, 1, TQ_x_10}, /*Not possible*/ \ 213 {2, 1, TQ_x_5 } /*CAN=1000kbps*/ 214 #elif CO_FCY == 6000 215 #define CO_CANbitRateDataInitializers \ 216 {1, 20, TQ_x_15}, /*CAN=10kbps*/ \ 217 {1, 10, TQ_x_15}, /*CAN=20kbps*/ \ 218 {1, 4, TQ_x_15}, /*CAN=50kbps*/ \ 219 {2, 3, TQ_x_16}, /*CAN=125kbps*/ \ 220 {1, 1, TQ_x_12}, /*CAN=250kbps*/ \ 221 {2, 1, TQ_x_12}, /*CAN=500kbps*/ \ 222 {2, 1, TQ_x_12}, /*Not possible*/ \ 223 {2, 1, TQ_x_6 } /*CAN=1000kbps*/ 224 #elif CO_FCY == 8000 225 #define CO_CANbitRateDataInitializers \ 226 {1, 25, TQ_x_16}, /*CAN=10kbps*/ \ 227 {2, 25, TQ_x_16}, /*CAN=20kbps*/ \ 228 {1, 5, TQ_x_16}, /*CAN=50kbps*/ \ 229 {1, 2, TQ_x_16}, /*CAN=125kbps*/ \ 230 {1, 1, TQ_x_16}, /*CAN=250kbps*/ \ 231 {2, 1, TQ_x_16}, /*CAN=500kbps*/ \ 232 {2, 1, TQ_x_10}, /*CAN=800kbps*/ \ 233 {2, 1, TQ_x_8 } /*CAN=1000kbps*/ 234 #elif CO_FCY == 10000 235 #define CO_CANbitRateDataInitializers \ 236 {1, 25, TQ_x_20}, /*CAN=10kbps*/ \ 237 {2, 25, TQ_x_20}, /*CAN=20kbps*/ \ 238 {1, 5, TQ_x_20}, /*CAN=50kbps*/ \ 239 {2, 5, TQ_x_16}, /*CAN=125kbps*/ \ 240 {1, 1, TQ_x_20}, /*CAN=250kbps*/ \ 241 {2, 1, TQ_x_20}, /*CAN=500kbps*/ \ 242 {2, 1, TQ_x_20}, /*Not possible*/ \ 243 {2, 1, TQ_x_10} /*CAN=1000kbps*/ 244 #elif CO_FCY == 12000 245 #define CO_CANbitRateDataInitializers \ 246 {2, 63, TQ_x_19}, /*CAN=10kbps*/ \ 247 {1, 20, TQ_x_15}, /*CAN=20kbps*/ \ 248 {2, 15, TQ_x_16}, /*CAN=50kbps*/ \ 249 {1, 3, TQ_x_16}, /*CAN=125kbps*/ \ 250 {2, 3, TQ_x_16}, /*CAN=250kbps*/ \ 251 {1, 1, TQ_x_12}, /*CAN=500kbps*/ \ 252 {2, 1, TQ_x_15}, /*CAN=800kbps*/ \ 253 {2, 1, TQ_x_12} /*CAN=1000kbps*/ 254 #elif CO_FCY == 16000 255 #define CO_CANbitRateDataInitializers \ 256 {1, 50, TQ_x_16}, /*CAN=10kbps*/ \ 257 {1, 25, TQ_x_16}, /*CAN=20kbps*/ \ 258 {1, 10, TQ_x_16}, /*CAN=50kbps*/ \ 259 {1, 4, TQ_x_16}, /*CAN=125kbps*/ \ 260 {1, 2, TQ_x_16}, /*CAN=250kbps*/ \ 261 {1, 1, TQ_x_16}, /*CAN=500kbps*/ \ 262 {1, 1, TQ_x_10}, /*CAN=800kbps*/ \ 263 {1, 1, TQ_x_8 } /*CAN=1000kbps*/ 264 #elif CO_FCY == 20000 265 #define CO_CANbitRateDataInitializers \ 266 {1, 50, TQ_x_20}, /*CAN=10kbps*/ \ 267 {1, 25, TQ_x_20}, /*CAN=20kbps*/ \ 268 {1, 10, TQ_x_20}, /*CAN=50kbps*/ \ 269 {1, 5, TQ_x_16}, /*CAN=125kbps*/ \ 270 {1, 2, TQ_x_20}, /*CAN=250kbps*/ \ 271 {1, 1, TQ_x_20}, /*CAN=500kbps*/ \ 272 {1, 1, TQ_x_20}, /*Not possible*/ \ 273 {1, 1, TQ_x_10} /*CAN=1000kbps*/ 274 #elif CO_FCY == 24000 275 #define CO_CANbitRateDataInitializers \ 276 {1, 63, TQ_x_19}, /*CAN=10kbps*/ \ 277 {1, 40, TQ_x_15}, /*CAN=20kbps*/ \ 278 {1, 15, TQ_x_16}, /*CAN=50kbps*/ \ 279 {1, 6, TQ_x_16}, /*CAN=125kbps*/ \ 280 {1, 3, TQ_x_16}, /*CAN=250kbps*/ \ 281 {1, 2, TQ_x_12}, /*CAN=500kbps*/ \ 282 {1, 1, TQ_x_15}, /*CAN=800kbps*/ \ 283 {1, 1, TQ_x_12} /*CAN=1000kbps*/ 284 #elif CO_FCY == 32000 285 #define CO_CANbitRateDataInitializers \ 286 {1, 64, TQ_x_25}, /*CAN=10kbps*/ \ 287 {1, 50, TQ_x_16}, /*CAN=20kbps*/ \ 288 {1, 20, TQ_x_16}, /*CAN=50kbps*/ \ 289 {1, 8, TQ_x_16}, /*CAN=125kbps*/ \ 290 {1, 4, TQ_x_16}, /*CAN=250kbps*/ \ 291 {1, 2, TQ_x_16}, /*CAN=500kbps*/ \ 292 {1, 2, TQ_x_10}, /*CAN=800kbps*/ \ 293 {1, 1, TQ_x_16} /*CAN=1000kbps*/ 294 #elif CO_FCY == 40000 295 #define CO_CANbitRateDataInitializers \ 296 {1, 50, TQ_x_20}, /*Not possible*/ \ 297 {1, 50, TQ_x_20}, /*CAN=20kbps*/ \ 298 {1, 25, TQ_x_16}, /*CAN=50kbps*/ \ 299 {1, 10, TQ_x_16}, /*CAN=125kbps*/ \ 300 {1, 5, TQ_x_16}, /*CAN=250kbps*/ \ 301 {1, 2, TQ_x_20}, /*CAN=500kbps*/ \ 302 {1, 1, TQ_x_25}, /*CAN=800kbps*/ \ 303 {1, 1, TQ_x_20} /*CAN=1000kbps*/ 304 #elif CO_FCY == 48000 305 #define CO_CANbitRateDataInitializers \ 306 {1, 63, TQ_x_19}, /*Not possible*/ \ 307 {1, 63, TQ_x_19}, /*CAN=20kbps*/ \ 308 {1, 30, TQ_x_16}, /*CAN=50kbps*/ \ 309 {1, 12, TQ_x_16}, /*CAN=125kbps*/ \ 310 {1, 6, TQ_x_16}, /*CAN=250kbps*/ \ 311 {1, 3, TQ_x_16}, /*CAN=500kbps*/ \ 312 {1, 2, TQ_x_15}, /*CAN=800kbps*/ \ 313 {1, 2, TQ_x_12} /*CAN=1000kbps*/ 314 #elif CO_FCY == 56000 315 #define CO_CANbitRateDataInitializers \ 316 {1, 61, TQ_x_23}, /*Not possible*/ \ 317 {1, 61, TQ_x_23}, /*CAN=20kbps*/ \ 318 {1, 35, TQ_x_16}, /*CAN=50kbps*/ \ 319 {1, 14, TQ_x_16}, /*CAN=125kbps*/ \ 320 {1, 7, TQ_x_16}, /*CAN=250kbps*/ \ 321 {1, 4, TQ_x_14}, /*CAN=500kbps*/ \ 322 {1, 5, TQ_x_7 }, /*CAN=800kbps*/ \ 323 {1, 2, TQ_x_14} /*CAN=1000kbps*/ 324 #elif CO_FCY == 64000 325 #define CO_CANbitRateDataInitializers \ 326 {1, 64, TQ_x_25}, /*Not possible*/ \ 327 {1, 64, TQ_x_25}, /*CAN=20kbps*/ \ 328 {1, 40, TQ_x_16}, /*CAN=50kbps*/ \ 329 {1, 16, TQ_x_16}, /*CAN=125kbps*/ \ 330 {1, 8, TQ_x_16}, /*CAN=250kbps*/ \ 331 {1, 4, TQ_x_16}, /*CAN=500kbps*/ \ 332 {1, 2, TQ_x_20}, /*CAN=800kbps*/ \ 333 {1, 2, TQ_x_16} /*CAN=1000kbps*/ 334 #elif CO_FCY == 70000 335 #define CO_CANbitRateDataInitializers \ 336 {1, 64, TQ_x_25}, /*Not possible*/ \ 337 {1, 64, TQ_x_25}, /*CAN=20kbps*/ \ 338 {1, 35, TQ_x_20}, /*CAN=50kbps*/ \ 339 {1, 14, TQ_x_20}, /*CAN=125kbps*/ \ 340 {1, 7, TQ_x_20}, /*CAN=250kbps*/ \ 341 {1, 5, TQ_x_14}, /*CAN=500kbps*/ \ 342 {1, 3, TQ_x_15}, /*Not working*/ \ 343 {1, 2, TQ_x_17} /*Not working*/ 344 #else 345 #error define_CO_FCY CO_FCY not supported 346 #endif /* CO_FCY == <value> */ 347 #endif /* CO_FCY */ 348 349 350 /* Structure contains timing coefficients for CAN module. 351 * 352 * CAN baud rate is calculated from following equations: 353 * FCAN = FCY * Scale - Input frequency to CAN module (MAX 40MHz for dsPIC33F/PIC24H and 70MHz for dsPIC33E/PIC24E) 354 * TQ = 2 * BRP / FCAN - Time Quanta 355 * BaudRate = 1 / (TQ * K) - Can bus Baud Rate 356 * K = SJW + PROP + PhSeg1 + PhSeg2 - Number of Time Quantas 357 */ 358 typedef struct{ 359 uint8_t scale; /* (1 or 2) Scales FCY clock - dsPIC33F and PIC24H specific */ 360 uint8_t BRP; /* (1...64) Baud Rate Prescaler */ 361 uint8_t SJW; /* (1...4) SJW time */ 362 uint8_t PROP; /* (1...8) PROP time */ 363 uint8_t phSeg1; /* (1...8) Phase Segment 1 time */ 364 uint8_t phSeg2; /* (1...8) Phase Segment 2 time */ 365 }CO_CANbitRateData_t; 366 367 368 /* CAN receive message structure as aligned in CAN module. 369 * In dsPIC33F and PIC24H this structure is used for both: transmitting and 370 * receiving to and from CAN module. (Object is ownded by CAN module). 371 */ 372 typedef struct{ 373 uint16_t ident; /* Standard Identifier as aligned in CAN module. 16 bits: 374 'UUUSSSSS SSSSSSRE' (U: unused; S: SID; R=SRR; E=IDE). */ 375 uint16_t extIdent; /* Extended identifier, not used here */ 376 uint16_t DLC :4; /* Data length code (bits 0...3) */ 377 uint16_t DLCrest :12; /* Not used here (bits 4..15) */ 378 uint8_t data[8]; /* 8 data bytes */ 379 uint8_t dummy; /* Not used */ 380 uint8_t FILHIT; /* Filter hit */ 381 }CO_CANrxMsg_t; 382 383 384 /* Received message object */ 385 typedef struct{ 386 uint16_t ident; 387 uint16_t mask; 388 void *object; 389 void (*pFunct)(void *object, const CO_CANrxMsg_t *message); 390 }CO_CANrx_t; 391 392 393 /* Transmit message object. */ 394 typedef struct{ 395 uint16_t ident; /* Standard Identifier as aligned in CAN module. 16 bits: 396 'SSSSSUUU SSSSSSRE' (U: unused; S: SID; R=SRR; E=IDE). */ 397 uint8_t DLC; 398 uint8_t data[8]; 399 volatile bool_t bufferFull; 400 volatile bool_t syncFlag; 401 }CO_CANtx_t; 402 403 404 /* CAN module object. */ 405 typedef struct{ 406 void *CANdriverState; 407 __eds__ CO_CANrxMsg_t *CANmsgBuff; /* dsPIC33F specific: CAN message buffer for CAN module */ 408 uint8_t CANmsgBuffSize; /* dsPIC33F specific: Size of the above buffer */ 409 CO_CANrx_t *rxArray; 410 uint16_t rxSize; 411 CO_CANtx_t *txArray; 412 uint16_t txSize; 413 volatile bool_t CANnormal; 414 volatile bool_t useCANrxFilters; 415 volatile bool_t bufferInhibitFlag; 416 volatile bool_t firstCANtxMessage; 417 volatile uint16_t CANtxCount; 418 uint16_t errOld; 419 void *em; 420 }CO_CANmodule_t; 421 422 423 /* CAN interrupt receives and transmits CAN messages. 424 * 425 * Function must be called directly from _C1Interrupt or _C2Interrupt with 426 * high priority. 427 */ 428 void CO_CANinterrupt(CO_CANmodule_t *CANmodule); 429 430 431 #endif /* CO_DRIVER_TARGET_H */ 432