CANopenPIC
CANopenNode on PIC microcontrollers
Loading...
Searching...
No Matches
CO_driver_target.h
1/*
2 * Microchip PIC32MX specific definitions for CANopenNode.
3 *
4 * @file CO_driver_target.h
5 * @author Janez Paternoster
6 * @copyright 2021 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_H
27#define CO_DRIVER_TARGET_H
28
29/* This file contains device and application specific definitions.
30 * It is included from CO_driver.h, which contains documentation
31 * for common definitions below. */
32
33#include <p32xxxx.h>
34#include <stddef.h>
35#include <stdbool.h>
36#include <stdint.h>
37
38#include "CO_driver_custom.h"
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44
45/* Stack configuration override from CO_driver.h.
46 * For more information see file CO_config.h. */
47#ifndef CO_CONFIG_NMT
48#define CO_CONFIG_NMT CO_CONFIG_NMT_MASTER
49#endif
50
51/* Add full SDO_SRV_BLOCK transfer with CRC16 */
52#ifndef CO_CONFIG_SDO_SRV
53#define CO_CONFIG_SDO_SRV (CO_CONFIG_SDO_SRV_SEGMENTED | \
54 CO_CONFIG_SDO_SRV_BLOCK)
55#endif
56#ifndef CO_CONFIG_SDO_SRV_BUFFER_SIZE
57#define CO_CONFIG_SDO_SRV_BUFFER_SIZE 900
58#endif
59#ifndef CO_CONFIG_CRC16
60#define CO_CONFIG_CRC16 (CO_CONFIG_CRC16_ENABLE)
61#endif
62
63
64/* default system clock configuration */
65#ifndef CO_FSYS
66#define CO_FSYS 64000 /* (8MHz Quartz used) */
67#endif
68
69/* default peripheral bus clock configuration */
70#ifndef CO_PBCLK
71#define CO_PBCLK 32000
72#endif
73
74
75/* Basic definitions */
76#define CO_LITTLE_ENDIAN
77#define CO_SWAP_16(x) x
78#define CO_SWAP_32(x) x
79#define CO_SWAP_64(x) x
80/* NULL is defined in stddef.h */
81/* true and false are defined in stdbool.h */
82/* int8_t to uint64_t are defined in stdint.h */
83typedef unsigned char bool_t;
84typedef float float32_t;
85typedef long double float64_t;
86
87
88/* CAN receive message structure as aligned in CAN module. */
89typedef struct {
90 unsigned ident :11; /* Standard Identifier */
91 unsigned FILHIT :5; /* Filter hit, see PIC32MX documentation */
92 unsigned CMSGTS :16; /* CAN message timestamp, see PIC32MX documentation */
93 unsigned DLC :4; /* Data length code (bits 0...3) */
94 unsigned :5;
95 unsigned RTR :1; /* Remote Transmission Request bit */
96 unsigned :22;
97 uint8_t data[8]; /* 8 data bytes */
98} CO_CANrxMsg_t;
99
100/* Access to received CAN message */
101#define CO_CANrxMsg_readIdent(msg) ((uint16_t)(((CO_CANrxMsg_t *)(msg))->ident))
102#define CO_CANrxMsg_readDLC(msg) ((uint8_t)(((CO_CANrxMsg_t *)(msg))->DLC))
103#define CO_CANrxMsg_readData(msg) ((uint8_t *)(((CO_CANrxMsg_t *)(msg))->data))
104
105/* Received message object */
106typedef struct {
107 uint16_t ident;
108 uint16_t mask;
109 void *object;
110 void (*CANrx_callback)(void *object, void *message);
111} CO_CANrx_t;
112
113/* Transmit message object */
114typedef struct {
115 uint32_t CMSGSID; /* Equal to register in transmit message buffer. Includes standard Identifier */
116 uint32_t CMSGEID; /* Equal to register in transmit message buffer. Includes data length code and RTR */
117 uint8_t data[8];
118 volatile bool_t bufferFull;
119 volatile bool_t syncFlag;
120} CO_CANtx_t;
121
122/* CAN module object */
123typedef struct {
124 void *CANptr;
125 CO_CANrxMsg_t CANmsgBuff[33]; /* PIC32 specific: CAN message buffer for CAN module. 32 buffers for receive, 1 buffer for transmit */
126 uint8_t CANmsgBuffSize; /* PIC32 specific: Size of the above buffer == 33. Take care initial value! */
127 CO_CANrx_t *rxArray;
128 uint16_t rxSize;
129 CO_CANtx_t *txArray;
130 uint16_t txSize;
131 uint16_t CANerrorStatus;
132 volatile bool_t CANnormal;
133 volatile bool_t useCANrxFilters;
134 volatile bool_t bufferInhibitFlag;
135 volatile bool_t firstCANtxMessage;
136 volatile uint16_t CANtxCount;
137 uint32_t errOld;
138 unsigned int interruptStatus; /* for enabling/disabling interrupts */
139 unsigned int interruptDisabler; /* for enabling/disabling interrupts */
141
142
143/* Data storage object for one entry */
144typedef struct {
145 void *addr;
146 size_t len;
147 uint8_t subIndexOD;
148 uint8_t attr;
149 void *storageModule;
150 uint16_t crc;
151 size_t eepromAddrSignature;
152 size_t eepromAddr;
153 size_t offset;
155
156
157/* (un)lock critical section in CO_CANsend() */
158#define CO_LOCK_CAN_SEND(CAN_MODULE) { \
159 if ((CAN_MODULE)->interruptDisabler == 0) { \
160 (CAN_MODULE)->interruptStatus = __builtin_disable_interrupts(); \
161 (CAN_MODULE)->interruptDisabler = 1; \
162 } \
163}
164#define CO_UNLOCK_CAN_SEND(CAN_MODULE) { \
165 if ((CAN_MODULE)->interruptDisabler == 1) { \
166 if(((CAN_MODULE)->interruptStatus & _CP0_STATUS_IE_MASK) != 0) { \
167 __builtin_enable_interrupts(); \
168 } \
169 (CAN_MODULE)->interruptDisabler = 0; \
170 } \
171}
172
173/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
174#define CO_LOCK_EMCY(CAN_MODULE) { \
175 if ((CAN_MODULE)->interruptDisabler == 0) { \
176 (CAN_MODULE)->interruptStatus = __builtin_disable_interrupts(); \
177 (CAN_MODULE)->interruptDisabler = 2; \
178 } \
179}
180#define CO_UNLOCK_EMCY(CAN_MODULE) { \
181 if ((CAN_MODULE)->interruptDisabler == 2) { \
182 if(((CAN_MODULE)->interruptStatus & _CP0_STATUS_IE_MASK) != 0) { \
183 __builtin_enable_interrupts(); \
184 } \
185 (CAN_MODULE)->interruptDisabler = 0; \
186 } \
187}
188
189/* (un)lock critical section when accessing Object Dictionary */
190#define CO_LOCK_OD(CAN_MODULE) { \
191 if ((CAN_MODULE)->interruptDisabler == 0) { \
192 (CAN_MODULE)->interruptStatus = __builtin_disable_interrupts(); \
193 (CAN_MODULE)->interruptDisabler = 3; \
194 } \
195}
196#define CO_UNLOCK_OD(CAN_MODULE) { \
197 if ((CAN_MODULE)->interruptDisabler == 3) { \
198 if(((CAN_MODULE)->interruptStatus & _CP0_STATUS_IE_MASK) != 0) { \
199 __builtin_enable_interrupts(); \
200 } \
201 (CAN_MODULE)->interruptDisabler = 0; \
202 } \
203}
204
205
206/* Synchronization between CAN receive and message processing threads. */
207#define CO_MemoryBarrier()
208#define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
209#define CO_FLAG_SET(rxNew) {CO_MemoryBarrier(); rxNew = (void*)1L;}
210#define CO_FLAG_CLEAR(rxNew) {CO_MemoryBarrier(); rxNew = NULL;}
211
212
213/* Translate a kernel virtual address in KSEG0 or KSEG1 to a real
214 * physical address and back. */
215typedef unsigned long CO_paddr_t; /* a physical address */
216typedef unsigned long CO_vaddr_t; /* a virtual address */
217#define CO_KVA_TO_PA(v) ((CO_paddr_t)(v) & 0x1fffffff)
218#define CO_PA_TO_KVA0(pa) ((void *) ((pa) | 0x80000000))
219#define CO_PA_TO_KVA1(pa) ((void *) ((pa) | 0xa0000000))
220
221
222/* Callback for checking bitrate, needed by LSS slave */
223bool_t CO_LSSchkBitrateCallback(void *object, uint16_t bitRate);
224
225
226/* Function called from CAN receive interrupt handler */
227void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
228
229#ifdef __cplusplus
230}
231#endif /* __cplusplus */
232
233#endif /* CO_DRIVER_TARGET_H */
unsigned int uint16_t
unsigned long int uint32_t
float float32_t
uint_fast8_t bool_t
unsigned char uint8_t
double float64_t