-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathco_main.h
299 lines (265 loc) · 7.91 KB
/
co_main.h
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*********************************************************************
* _ _ _
* _ __ | |_ _ | | __ _ | |__ ___
* | '__|| __|(_)| | / _` || '_ \ / __|
* | | | |_ _ | || (_| || |_) |\__ \
* |_| \__|(_)|_| \__,_||_.__/ |___/
*
* www.rt-labs.com
* Copyright 2017 rt-labs AB, Sweden.
*
* This software is dual-licensed under GPLv3 and a commercial
* license. See the file LICENSE.md distributed with this software for
* full license information.
********************************************************************/
/**
* @file
* @brief Core definitions
*/
#ifndef CO_MAIN_H
#define CO_MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "co_api.h"
#include "osal.h"
#include "coal_can.h"
#include "options.h"
#include "osal_log.h"
#include <stdbool.h>
#define CO_BYTELENGTH(bitlength) (((bitlength) + 7) / 8)
#define CO_RTR_MASK BIT (30)
#define CO_EXT_MASK BIT (29)
#define CO_ID_MASK 0x1FFFFFFF
#define CO_EXTID_MASK (CO_EXT_MASK | CO_ID_MASK)
#define CO_COBID_INVALID BIT (31)
#define CO_NODE_GET(id) ((id)&0x7F)
/* Pre-defined connection set (see CiA 301 chapter 7.3.3) */
#define CO_FUNCTION_NMT (0 << 7)
#define CO_FUNCTION_SYNC (1 << 7)
#define CO_FUNCTION_TIME (2 << 7)
#define CO_FUNCTION_EMCY (1 << 7)
#define CO_FUNCTION_PDO1_TX (3 << 7)
#define CO_FUNCTION_PDO1_RX (4 << 7)
#define CO_FUNCTION_PDO2_TX (5 << 7)
#define CO_FUNCTION_PDO2_RX (6 << 7)
#define CO_FUNCTION_PDO3_TX (7 << 7)
#define CO_FUNCTION_PDO3_RX (8 << 7)
#define CO_FUNCTION_PDO4_TX (9 << 7)
#define CO_FUNCTION_PDO4_RX (10 << 7)
#define CO_FUNCTION_SDO_TX (11 << 7)
#define CO_FUNCTION_SDO_RX (12 << 7)
#define CO_FUNCTION_NMT_ERR (14 << 7)
#define CO_FUNCTION_LSS (15 << 7)
#define CO_FUNCTION_MASK (15 << 7)
/**
* Process data object (PDO)
*/
typedef struct co_pdo
{
uint16_t number;
uint32_t cobid;
uint8_t transmission_type;
uint8_t sync_start;
uint8_t sync_counter;
uint16_t inhibit_time;
uint16_t event_timer;
os_tick_t timestamp;
uint64_t frame;
size_t bitlength;
uint8_t number_of_mappings;
struct
{
bool queued : 1;
bool sync_wait : 1;
};
uint32_t mappings[MAX_PDO_ENTRIES];
const co_obj_t * objs[MAX_PDO_ENTRIES];
const co_entry_t * entries[MAX_PDO_ENTRIES];
} co_pdo_t;
typedef enum co_job_type
{
CO_JOB_NONE,
CO_JOB_PERIODIC,
CO_JOB_RX,
CO_JOB_PDO_EVENT,
CO_JOB_PDO_OBJ_EVENT,
CO_JOB_SDO_READ,
CO_JOB_SDO_WRITE,
CO_JOB_SDO_UPLOAD,
CO_JOB_SDO_DOWNLOAD,
CO_JOB_EMCY_TX,
CO_JOB_ERROR_SET,
CO_JOB_ERROR_CLEAR,
CO_JOB_ERROR_GET,
CO_JOB_EXIT,
} co_job_type_t;
/** Parameters for SDO job */
typedef struct co_sdo_job
{
uint8_t node;
uint16_t index;
uint8_t subindex;
uint8_t * data;
uint64_t value;
size_t remain;
size_t total;
struct
{
bool toggle : 1;
bool cached : 1;
};
} co_sdo_job_t;
/** Parameters for emergency job */
typedef struct co_emcy_job
{
uint16_t code;
uint16_t info;
uint8_t * msef;
uint8_t value;
} co_emcy_job_t;
/** Parameters for PDO job */
typedef struct co_pdo_job
{
uint16_t index;
uint8_t subindex;
} co_pdo_job_t;
/** Generic job */
typedef struct co_job
{
co_job_type_t type;
union
{
co_sdo_job_t sdo;
co_emcy_job_t emcy;
co_pdo_job_t pdo;
};
os_tick_t timestamp;
struct co_client * client;
void (*callback) (struct co_job * job);
int result;
} co_job_t;
/** Client state */
struct co_client
{
os_sem_t * sem;
co_job_t job;
co_net_t * net;
};
/** Heartbeat consumer state */
typedef struct co_heartbeat
{
uint8_t node;
bool is_alive;
uint16_t time;
os_tick_t timestamp;
} co_heartbeat_t;
/** Node guarding state */
typedef struct co_node_guard
{
bool is_alive;
uint16_t guard_time;
uint8_t life_time_factor;
uint8_t toggle;
os_tick_t timestamp;
} co_node_guard_t;
/** LSS states */
typedef enum lss_state
{
LSS_STATE_WAITING = 0,
LSS_STATE_CONFIG = 1,
} lss_state_t;
/** LSS state */
typedef struct lss
{
lss_state_t state;
int bitrate;
uint8_t node;
const co_obj_t * identity;
uint8_t match;
} lss_t;
/** SYNC producer state */
typedef struct co_sync
{
uint32_t cobid;
uint8_t counter;
uint8_t overflow;
uint32_t period;
os_tick_t timestamp;
} co_sync_t;
/** EMCY state */
typedef struct co_emcy
{
uint32_t cobid; /**< EMCY COB ID */
os_tick_t timestamp; /**< Timestamp of last EMCY */
uint32_t bus_off_timestamp; /**< Timestamp of bus-off event */
uint16_t inhibit; /**< Inhibit time [100 us] */
uint8_t error; /**< Error register */
os_channel_state_t state; /**< CAN state */
bool node_guard_error; /**< Node guard error */
bool heartbeat_error; /**< Heartbeat error */
uint32_t cobids[MAX_EMCY_COBIDS]; /**< EMCY consumer object */
} co_emcy_t;
/** CANopen network state */
struct co_net
{
os_channel_t * channel; /**< CAN channel */
int bitrate; /**< CAN bitrate (bits per second) */
os_mbox_t * mbox; /**< Mailbox for job submission */
co_job_type_t job_periodic; /**< Static message for periodic job */
co_job_type_t job_rx; /**< Static message for rx job */
co_job_t job_sdo_server; /**< Current SDO server job */
co_job_t * job_client; /**< Pointer to current client job */
uint32_t nodes[4]; /**< Discovered nodes. 128-bit bitmap */
uint8_t node; /**< Node ID for this node */
co_emcy_t emcy; /**< EMCY state */
co_sync_t sync; /**< SYNC state */
co_state_t state; /**< NMT state */
os_tick_t hb_timestamp; /**< Heartbeat producer timestamp */
uint32_t hb_time; /**< Heartbeat producer time */
os_tick_t sync_timestamp; /**< Timestamp of last SYNC */
uint32_t sync_window; /**< Synchronous window length */
uint32_t restart_ms; /**< Delay before attempting to recover from bus-off */
co_pdo_t pdo_tx[MAX_TX_PDO]; /**< TPDOs */
co_pdo_t pdo_rx[MAX_RX_PDO]; /**< RPDOs */
co_node_guard_t node_guard; /**< Node guarding state */
co_heartbeat_t heartbeat[MAX_HEARTBEATS]; /**< Heartbeat consumer state */
uint8_t number_of_errors; /**< Number of active errors */
uint32_t errors[MAX_ERRORS]; /**< List of active errors */
uint8_t error_behavior; /**< Error behavior object */
uint32_t config_date; /**< Configuration date */
uint32_t config_time; /**< Configuration time */
uint8_t config_dirty; /**< Configuration has changed */
lss_t lss; /**< LSS state */
const co_obj_t * od; /**< Object dictionary */
const co_default_t * defaults; /**< Dictionary default values */
void * cb_arg; /**< Callback opaque argument */
uint32_t mbox_overrun; /**< Mailbox overruns (for debugging) */
/** Reset callback */
void (*cb_reset) (co_net_t * net);
/** NMT callback */
void (*cb_nmt) (co_net_t * net, co_state_t state);
/** SYNC callback */
void (*cb_sync) (co_net_t * net);
/** EMCY callback */
bool (*cb_emcy) (
co_net_t * net,
uint8_t node,
uint16_t code,
uint8_t reg,
uint8_t msef[5]);
/** Notify callback */
void (*cb_notify) (co_net_t * net, uint16_t index, uint8_t subindex, od_notify_event_t event, uint32_t value);
/** Function to open dictionary store */
void * (*open) (co_store_t store, co_mode_t mode);
/** Function to read from dictionary store */
int (*read) (void * arg, void * data, size_t size);
/** Function to write to dictionary store */
int (*write) (void * arg, const void * data, size_t size);
/** Function to close dictionary store */
int (*close) (void * arg);
};
#ifdef __cplusplus
}
#endif
#endif /* CO_MAIN_H */