-
Notifications
You must be signed in to change notification settings - Fork 172
Expand file tree
/
Copy pathCO_driver_target.h
More file actions
246 lines (212 loc) · 11 KB
/
CO_driver_target.h
File metadata and controls
246 lines (212 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
* Device and application specific definitions for CANopenNode.
*
* @file CO_driver_target.h
* @author Hamed Jafarzadeh 2022
* Tilen Marjerle 2021
* Janez Paternoster 2020
* @copyright 2004 - 2020 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
/* This file contains device and application specific definitions.
* It is included from CO_driver.h, which contains documentation
* for common definitions below. */
#include "main.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef USE_FREERTOS_LOCKING
#include "FreeRTOS.h"
#include "task.h"
#endif
// Determining the CANOpen Driver
#if defined(FDCAN) || defined(FDCAN1) || defined(FDCAN2) || defined(FDCAN3)
#define CO_STM32_FDCAN_Driver 1
#elif defined(CAN) || defined(CAN1) || defined(CAN2) || defined(CAN3)
#define CO_STM32_CAN_Driver 1
#else
#error This STM32 Do not support CAN or FDCAN
#endif
#ifdef USE_CO_STORAGE_FLASH
#define CO_CONFIG_STORAGE CO_CONFIG_STORAGE_ENABLE
#define CO_CONFIG_CRC16 CO_CONFIG_CRC16_ENABLE
#else
#undef CO_CONFIG_STORAGE_ENABLE // We don't need Storage option, implement based on your use case and remove this line from here
#endif
#ifdef CO_DRIVER_CUSTOM
#include "CO_driver_custom.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Stack configuration override default values.
* For more information see file CO_config.h. */
/* Basic definitions. If big endian, CO_SWAP_xx macros must swap bytes. */
#define CO_LITTLE_ENDIAN
#define CO_SWAP_16(x) x
#define CO_SWAP_32(x) x
#define CO_SWAP_64(x) x
/* NULL is defined in stddef.h */
/* true and false are defined in stdbool.h */
/* int8_t to uint64_t are defined in stdint.h */
typedef uint_fast8_t bool_t;
typedef float float32_t;
typedef double float64_t;
/**
* \brief CAN RX message for platform
*
* This is platform specific one
*/
typedef struct {
uint32_t ident; /*!< Standard identifier */
uint8_t dlc; /*!< Data length */
uint8_t data[8]; /*!< Received data */
} CO_CANrxMsg_t;
/* Access to received CAN message */
#define CO_CANrxMsg_readIdent(msg) ((uint16_t)(((CO_CANrxMsg_t*)(msg)))->ident)
#define CO_CANrxMsg_readDLC(msg) ((uint8_t)(((CO_CANrxMsg_t*)(msg)))->dlc)
#define CO_CANrxMsg_readData(msg) ((uint8_t*)(((CO_CANrxMsg_t*)(msg)))->data)
/* Received message object */
typedef struct {
uint16_t ident;
uint16_t mask;
void* object;
void (*CANrx_callback)(void* object, void* message);
} CO_CANrx_t;
/* Transmit message object */
typedef struct {
uint32_t ident;
uint8_t DLC;
uint8_t data[8];
volatile bool_t bufferFull;
volatile bool_t syncFlag;
} CO_CANtx_t;
/* CAN module object */
typedef struct {
void* CANptr;
CO_CANrx_t* rxArray;
uint16_t rxSize;
CO_CANtx_t* txArray;
uint16_t txSize;
uint16_t CANerrorStatus;
volatile bool_t CANnormal;
volatile bool_t useCANrxFilters;
volatile bool_t bufferInhibitFlag;
volatile bool_t firstCANtxMessage;
volatile uint16_t CANtxCount;
uint32_t errOld;
/* STM32 specific features */
uint32_t primask_send; /* Primask register for interrupts for send operation */
uint32_t primask_emcy; /* Primask register for interrupts for emergency operation */
uint32_t primask_od; /* Primask register for interrupts for send operation */
} CO_CANmodule_t;
/* Data storage object for one entry */
typedef struct {
void* addr;
size_t len;
uint8_t subIndexOD;
uint8_t attr;
/* Additional variables (target specific) */
void* addrNV;
#ifdef USE_CO_STORAGE_FLASH
uint16_t offset;
uint16_t reservedSpace;
uint16_t crc;
#endif
} CO_storage_entry_t;
/* (un)lock critical section in CO_CANsend() */
#ifdef USE_FREERTOS_LOCKING
// NOTE: valid for STM32F3XX. Not tested on other MCUs
// This works as long as you don't have interrupts pre-empting each other, which call the CO_LOCK_* macros below!
#define CO_VECTACTIVE_MASK (0xFFUL)
#define CO_IS_IRQ() ((portNVIC_INT_CTRL_REG & CO_VECTACTIVE_MASK) != 0)
#define CO_ENTER_CRITICAL_SECTION() \
do \
{ \
if (CO_IS_IRQ()) \
{ \
taskENTER_CRITICAL_FROM_ISR(); \
} \
else \
{ \
taskENTER_CRITICAL(); \
} \
} while (0)
#define CO_EXIT_CRITICAL_SECTION() \
do \
{ \
if (CO_IS_IRQ()) \
{ \
taskEXIT_CRITICAL_FROM_ISR(0); \
} \
else \
{ \
taskEXIT_CRITICAL(); \
} \
} while (0)
/* (un)lock critical section in CO_CANsend() */
#define CO_LOCK_CAN_SEND(CAN_MODULE) CO_ENTER_CRITICAL_SECTION()
#define CO_UNLOCK_CAN_SEND(CAN_MODULE) CO_EXIT_CRITICAL_SECTION()
/* (un)lock critical section when accessing Object Dictionary */
#define CO_LOCK_OD(CAN_MODULE) CO_ENTER_CRITICAL_SECTION()
#define CO_UNLOCK_OD(CAN_MODULE) CO_EXIT_CRITICAL_SECTION()
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
#define CO_LOCK_EMCY(CAN_MODULE) CO_ENTER_CRITICAL_SECTION()
#define CO_UNLOCK_EMCY(CAN_MODULE) CO_EXIT_CRITICAL_SECTION()
#else
// Why disabling the whole Interrupt
#define CO_LOCK_CAN_SEND(CAN_MODULE) \
do { \
(CAN_MODULE)->primask_send = __get_PRIMASK(); \
__disable_irq(); \
} while (0)
#define CO_UNLOCK_CAN_SEND(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_send)
/* (un)lock critical section in CO_errorReport() or CO_errorReset() */
#define CO_LOCK_EMCY(CAN_MODULE) \
do { \
(CAN_MODULE)->primask_emcy = __get_PRIMASK(); \
__disable_irq(); \
} while (0)
#define CO_UNLOCK_EMCY(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_emcy)
/* (un)lock critical section when accessing Object Dictionary */
#define CO_LOCK_OD(CAN_MODULE) \
do { \
(CAN_MODULE)->primask_od = __get_PRIMASK(); \
__disable_irq(); \
} while (0)
#define CO_UNLOCK_OD(CAN_MODULE) __set_PRIMASK((CAN_MODULE)->primask_od)
#endif
/* Synchronization between CAN receive and message processing threads. */
#define CO_MemoryBarrier()
#define CO_FLAG_READ(rxNew) ((rxNew) != NULL)
#define CO_FLAG_SET(rxNew) \
do { \
CO_MemoryBarrier(); \
rxNew = (void*)1L; \
} while (0)
#define CO_FLAG_CLEAR(rxNew) \
do { \
CO_MemoryBarrier(); \
rxNew = NULL; \
} while (0)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CO_DRIVER_TARGET_H */