ecat_master.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /**
  2. * RT-Thread RuiChing
  3. *
  4. * COPYRIGHT (C) 2024-2025 Shanghai Real-Thread Electronic Technology Co., Ltd.
  5. * All rights reserved.
  6. *
  7. * The license and distribution terms for this file may be
  8. * found in the file LICENSE in this distribution.
  9. */
  10. #ifndef __ECAT_MASTER_H__
  11. #define __ECAT_MASTER_H__
  12. #include <stdint.h>
  13. #define EC_MAX_STRING_LENGTH (64)
  14. #define EC_MAX_PORTS (4)
  15. /** Master state.
  16. *
  17. * This is used for the output parameter of ecat_master_state().
  18. *
  19. * \see ecat_master_state().
  20. */
  21. typedef struct
  22. {
  23. unsigned int slaves_responding; /**< Sum of responding slaves on all
  24. Ethernet devices. */
  25. unsigned int al_states : 4; /**< Application-layer states of all slaves.
  26. The states are coded in the lower 4 bits.
  27. If a bit is set, it means that at least one
  28. slave in the network is in the corresponding
  29. state:
  30. - Bit 0: \a INIT
  31. - Bit 1: \a PREOP
  32. - Bit 2: \a SAFEOP
  33. - Bit 3: \a OP */
  34. unsigned int link_up : 1; /**< \a true, if at least one Ethernet link is
  35. up. */
  36. } ec_master_state_t;
  37. /****************************************************************************/
  38. /** State of an EtherCAT slave.
  39. */
  40. enum ec_slave_state
  41. {
  42. EC_SLAVE_STATE_UNKNOWN = 0x00,
  43. /**< unknown state */
  44. EC_SLAVE_STATE_INIT = 0x01,
  45. /**< INIT state (no mailbox communication, no IO) */
  46. EC_SLAVE_STATE_PREOP = 0x02,
  47. /**< PREOP state (mailbox communication, no IO) */
  48. EC_SLAVE_STATE_BOOT = 0x03,
  49. /**< Bootstrap state (mailbox communication, firmware update) */
  50. EC_SLAVE_STATE_SAFEOP = 0x04,
  51. /**< SAFEOP (mailbox communication and input update) */
  52. EC_SLAVE_STATE_OP = 0x08,
  53. /**< OP (mailbox communication and input/output update) */
  54. EC_SLAVE_STATE_ACK_ERR = 0x10
  55. /**< Acknowledge/Error bit (no actual state) */
  56. };
  57. typedef struct
  58. {
  59. uint8_t request_state; /**< request state of the slave. */
  60. uint8_t al_state; /**< Current state of the slave. */
  61. } ec_slave_state_t;
  62. /****************************************************************************/
  63. /** Slave information.
  64. *
  65. * This is used as an output parameter of ecrt_master_get_slave().
  66. *
  67. * \see ecrt_master_get_slave().
  68. */
  69. typedef struct
  70. {
  71. uint16_t index; /**< Offset of the slave in the ring. */
  72. uint16_t state; /** state of slave */
  73. uint16_t al_statuscode; /** AL status code */
  74. uint16_t parent; /** slave number for parent, 0=master */
  75. uint32_t vendor_id; /**< Vendor-ID stored on the slave. */
  76. uint32_t product_code; /**< Product-Code stored on the slave. */
  77. uint32_t revision_number; /**< Revision-Number stored on the slave. */
  78. uint32_t serial_number; /**< Serial-Number stored on the slave. */
  79. uint16_t alias; /**< The slaves alias if not equal to 0. */
  80. int16_t current_on_ebus; /**< Used current in mA. */
  81. struct
  82. {
  83. uint32_t receive_time; /**< Receive time on DC transmission delay
  84. measurement. */
  85. uint16_t next_slave; /**< Ring position of next DC slave on that
  86. port. */
  87. uint32_t delay_to_next_dc; /**< Delay [ns] to next DC slave. */
  88. } ports[EC_MAX_PORTS]; /**< Port information. */
  89. uint8_t error_flag; /**< Error flag for that slave. */
  90. uint8_t sync_count; /**< Number of sync managers. */
  91. uint16_t sdo_count; /**< Number of SDOs. */
  92. uint16_t mbx_proto; /** mailbox supported protocols */
  93. uint16_t configadr; /** Configured address */
  94. uint16_t Itype; /** Interface type */
  95. uint16_t Dtype; /** Device type */
  96. uint16_t Obits; /** output bits */
  97. uint16_t Ibits; /** input bits */
  98. uint8_t *outputs;
  99. uint8_t *inputs;
  100. int32_t pdelay; /** propagation delay */
  101. uint16_t DCnext; /** next DC slave */
  102. uint16_t DCprevious; /** previous DC slave */
  103. int32_t DCcycle; /** DC cycle time in ns */
  104. int32_t DCshift; /** DC shift from clock modulus boundary */
  105. uint8_t DCactive; /** DC sync activation, 0=off, 1=on */
  106. char name[EC_MAX_STRING_LENGTH]; /**< Name of the slave. */
  107. } ec_slave_info_t;
  108. /****************************************************************************/
  109. /** Domain working counter interpretation.
  110. *
  111. * This is used in ec_domain_state_t.
  112. */
  113. typedef enum
  114. {
  115. EC_WC_ZERO = 0, /**< No registered process data were exchanged. */
  116. EC_WC_INCOMPLETE, /**< Some of the registered process data were
  117. exchanged. */
  118. EC_WC_COMPLETE /**< All registered process data were exchanged. */
  119. } ec_wc_state_t;
  120. /****************************************************************************/
  121. /** Domain state.
  122. *
  123. * This is used for the output parameter of ecat_domain_state().
  124. */
  125. typedef struct
  126. {
  127. unsigned int working_counter; /**< Value of the last working counter. */
  128. unsigned int
  129. expected_working_counter; /**< Value of the expected working counter. */
  130. ec_wc_state_t wc_state; /**< Working counter interpretation. */
  131. unsigned int redundancy_active; /**< Redundant link is in use. */
  132. } ec_domain_state_t;
  133. /****************************************************************************/
  134. /** Direction type for PDO assignment functions.
  135. */
  136. typedef enum
  137. {
  138. EC_DIR_OUTPUT, /**< Values written by the master. */
  139. EC_DIR_INPUT, /**< Values read by the master. */
  140. } ec_direction_t;
  141. /****************************************************************************/
  142. /** Watchdog mode for sync manager configuration.
  143. *
  144. * Used to specify, if a sync manager's watchdog is to be enabled.
  145. */
  146. typedef enum
  147. {
  148. EC_WD_DEFAULT, /**< Use the default setting of the sync manager. */
  149. EC_WD_ENABLE, /**< Enable the watchdog. */
  150. EC_WD_DISABLE, /**< Disable the watchdog. */
  151. } ec_watchdog_mode_t;
  152. /****************************************************************************/
  153. /** PDO entry configuration information.
  154. *
  155. * This is the data type of the \a entries field in ec_pdo_info_t.
  156. *
  157. * \see ecrt_slave_config_pdos().
  158. */
  159. typedef struct
  160. {
  161. uint16_t index; /**< PDO entry index. */
  162. uint8_t subindex; /**< PDO entry subindex. */
  163. uint8_t bit_length; /**< Size of the PDO entry in bit. */
  164. } ec_pdo_entry_info_t;
  165. /****************************************************************************/
  166. /** PDO configuration information.
  167. *
  168. * This is the data type of the \a pdos field in ec_sync_info_t.
  169. *
  170. * \see ecrt_slave_config_pdos().
  171. */
  172. typedef struct
  173. {
  174. uint16_t index; /**< PDO index. */
  175. uint32_t n_entries; /**< Number of PDO entries in \a entries to map.
  176. Zero means, that the default mapping shall be
  177. used (this can only be done if the slave is
  178. present at configuration time). */
  179. ec_pdo_entry_info_t const *entries; /**< Array of PDO entries to map. Can
  180. either be \a NULL, or must contain
  181. at least \a n_entries values. */
  182. } ec_pdo_info_t;
  183. /****************************************************************************/
  184. /** Sync manager configuration information.
  185. *
  186. * This can be use to configure multiple sync managers including the PDO
  187. * assignment and PDO mapping. It is used as an input parameter type in
  188. * ecrt_slave_config_pdos().
  189. */
  190. typedef struct
  191. {
  192. uint8_t index; /**< Sync manager index. */
  193. ec_direction_t dir; /**< Sync manager direction. */
  194. uint32_t n_pdos; /**< Number of PDOs in \a pdos. */
  195. ec_pdo_info_t const *pdos; /**< Array with PDOs to assign. This must
  196. contain at least \a n_pdos PDOs. */
  197. ec_watchdog_mode_t watchdog_mode; /**< Watchdog mode. */
  198. } ec_sync_info_t;
  199. /****************************************************************************/
  200. /** List record type for PDO entry mass-registration.
  201. *
  202. * This type is used for the array parameter of the
  203. * ecrt_domain_reg_pdo_entry_list()
  204. */
  205. typedef struct
  206. {
  207. uint16_t alias; /**< Slave alias address. */
  208. uint16_t position; /**< Slave position. */
  209. uint32_t vendor_id; /**< Slave vendor ID. */
  210. uint32_t product_code; /**< Slave product code. */
  211. uint16_t index; /**< PDO entry index. */
  212. uint8_t subindex; /**< PDO entry subindex. */
  213. unsigned int *offset; /**< Pointer to a variable to store the PDO entry's
  214. (byte-)offset in the process data. */
  215. unsigned int *bit_position; /**< Pointer to a variable to store a bit
  216. position (0-7) within the \a offset. Can be
  217. NULL, in which case an error is raised if
  218. the PDO entry does not byte-align. */
  219. } ec_pdo_entry_reg_t;
  220. /****************************************************************************/
  221. /** Request state.
  222. *
  223. * This is used as return type for ecrt_sdo_request_state() and
  224. * ecrt_voe_handler_state().
  225. */
  226. typedef enum
  227. {
  228. EC_REQUEST_UNUSED, /**< Not requested. */
  229. EC_REQUEST_BUSY, /**< Request is being processed. */
  230. EC_REQUEST_SUCCESS, /**< Request was processed successfully. */
  231. EC_REQUEST_ERROR, /**< Request processing failed. */
  232. } ec_request_state_t;
  233. /****************************************************************************/
  234. /** Application-layer state.
  235. */
  236. typedef enum
  237. {
  238. EC_AL_STATE_INIT = 0x01, /**< Init. */
  239. EC_AL_STATE_PREOP = 0x02, /**< Pre-operational. */
  240. EC_AL_STATE_SAFEOP = 0x04, /**< Safe-operational. */
  241. EC_AL_STATE_OP = 0x08, /**< Operational. */
  242. } ec_al_state_t;
  243. typedef enum
  244. {
  245. /** No valid state. */
  246. EC_STATE_NONE = 0x00,
  247. /** Init state*/
  248. EC_STATE_INIT = 0x01,
  249. /** Pre-operational. */
  250. EC_STATE_PRE_OP = 0x02,
  251. /** Boot state*/
  252. EC_STATE_BOOT = 0x03,
  253. /** Safe-operational. */
  254. EC_STATE_SAFE_OP = 0x04,
  255. /** Operational */
  256. EC_STATE_OPERATIONAL = 0x08,
  257. /** Error or ACK error */
  258. EC_STATE_ACK = 0x10,
  259. EC_STATE_ERROR = 0x10
  260. } ec_state;
  261. #define EC_EVENT_RUN (0x01)
  262. #define EC_EVENT_STOP (0x02)
  263. #define EC_EVENT_LOOP (0x04)
  264. #define EC_EVENT_EXIT (0x08)
  265. typedef enum
  266. {
  267. EC_NET_MODE_BRIDGING = 0x00, /**< Bridging mode. */
  268. EC_NET_MODE_EXCLUSIVE = 0x01, /**< Exclusive mode. */
  269. } ec_net_mode_t;
  270. typedef struct ec_master
  271. {
  272. const char *name;
  273. void *priv;
  274. const char *nic0;
  275. const char *nic1;
  276. const char *eni_file;
  277. uint32_t main_cycletime_us;
  278. uint32_t sub_cycletime_us;
  279. uint32_t recovery_timeout_ms;
  280. uint8_t *process_data;
  281. uint32_t process_data_size;
  282. uint32_t pdo_timeout;
  283. uint32_t sdo_tx_timeout;
  284. uint32_t sdo_rx_timeout;
  285. uint32_t info_cycle;
  286. uint32_t dc_cycltime0;
  287. uint32_t dc_cycltime1;
  288. int32_t dc_cyclshift;
  289. uint16_t dc_index;
  290. uint8_t dc_active;
  291. uint8_t dc_type;
  292. uint8_t pdi_check;
  293. uint8_t wdt_enable;
  294. uint32_t wdt_timeout;
  295. ec_master_state_t state;
  296. ec_domain_state_t domain_state;
  297. rt_thread_t domain_thread;
  298. struct rt_event event;
  299. uint8_t net_mode;
  300. uint8_t run;
  301. uint8_t priority;
  302. int64_t *dc_time;
  303. float pgain;
  304. float igain;
  305. } ec_master_t;
  306. struct _ecat_timer
  307. {
  308. uint32_t sec; /*< Seconds elapsed since the Epoch (Jan 1, 1970) */
  309. uint32_t usec; /*< Microseconds elapsed since last second boundary */
  310. };
  311. struct ecat_timer
  312. {
  313. struct _ecat_timer stop_timer;
  314. };
  315. typedef void (*ec_pdo_callback_t)(uint16_t slave_index, uint8_t *output, uint8_t *input);
  316. /** EtherCAT slave sync signal configuration.
  317. */
  318. typedef struct {
  319. uint32_t cycle_time; /**< Cycle time [ns]. */
  320. int32_t shift_time; /**< Shift time [ns]. */
  321. } ec_sync_signal_t;
  322. #define EC_SYNC_SIGNAL_COUNT (2)
  323. typedef struct {
  324. ec_sync_info_t *sync; /**< Sync manager configuration. */
  325. uint8_t sync_count; /**< Number of sync managers. */
  326. ec_pdo_callback_t pdo_callback; /**< PDO process data callback. */
  327. uint16_t dc_assign_activate; /**< dc assign control */
  328. ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]; /**< DC sync signals. */
  329. } ec_slave_config_t;
  330. rt_err_t ecat_master_init(ec_master_t *master);
  331. rt_err_t ecat_master_deinit(ec_master_t *master);
  332. rt_err_t ecat_master_start(ec_master_t *master);
  333. rt_err_t ecat_simple_start(ec_master_t *master);
  334. rt_err_t ecat_simple_stop(ec_master_t *master);
  335. rt_err_t ecat_slave_config(
  336. ec_master_t *master, uint16_t slave, ec_slave_config_t *config);
  337. rt_err_t ecat_master_state(ec_master_t *master, ec_master_state_t *state);
  338. rt_err_t ecat_slave_state(
  339. ec_master_t *master, uint16_t slave, ec_slave_state_t *state);
  340. rt_err_t ecat_slave_info(
  341. ec_master_t *master, uint16_t slave, ec_slave_info_t *info);
  342. int ecat_sdo_write(ec_master_t *master,
  343. uint16_t slave,
  344. uint16_t index,
  345. uint8_t subindex,
  346. uint8_t complete_access,
  347. void *data,
  348. int size,
  349. int timeout);
  350. int ecat_sdo_read(ec_master_t *master,
  351. uint16_t slave,
  352. uint16_t index,
  353. uint8_t subindex,
  354. uint8_t complete_access,
  355. void *data,
  356. int size,
  357. int timeout);
  358. void ecat_dc_config(ec_master_t *master,
  359. uint16_t slave,
  360. uint8_t act,
  361. uint32_t cycle_time,
  362. int32_t cycle_shift);
  363. void ecat_dc_config_ex(ec_master_t *master,
  364. uint16_t slave,
  365. uint8_t act,
  366. uint32_t cycle_time0,
  367. uint32_t cycle_time1,
  368. int32_t cycle_shift);
  369. int ecat_slavecount(ec_master_t *master);
  370. rt_inline int ecat_sdo_write_u8(ec_master_t *master,
  371. uint16_t slave,
  372. uint16_t index,
  373. uint8_t subindex,
  374. uint8_t data,
  375. int timeout)
  376. {
  377. return ecat_sdo_write(master, slave, index, subindex, 0, &data, 1, timeout);
  378. }
  379. rt_inline int ecat_sdo_write_u16(ec_master_t *master,
  380. uint16_t slave,
  381. uint16_t index,
  382. uint8_t subindex,
  383. uint16_t data,
  384. int timeout)
  385. {
  386. return ecat_sdo_write(master, slave, index, subindex, 0, &data, 2, timeout);
  387. }
  388. rt_inline int ecat_sdo_write_u32(ec_master_t *master,
  389. uint16_t slave,
  390. uint16_t index,
  391. uint8_t subindex,
  392. uint32_t data,
  393. int timeout)
  394. {
  395. return ecat_sdo_write(master, slave, index, subindex, 0, &data, 4, timeout);
  396. }
  397. rt_inline int ecat_sdo_read_u8(ec_master_t *master,
  398. uint16_t slave,
  399. uint16_t index,
  400. uint8_t subindex,
  401. uint8_t *data,
  402. int timeout)
  403. {
  404. return ecat_sdo_read(master, slave, index, subindex, 0, data, 1, timeout);
  405. }
  406. rt_inline int ecat_sdo_read_u16(ec_master_t *master,
  407. uint16_t slave,
  408. uint16_t index,
  409. uint8_t subindex,
  410. uint16_t *data,
  411. int timeout)
  412. {
  413. return ecat_sdo_read(master, slave, index, subindex, 0, data, 2, timeout);
  414. }
  415. rt_inline int ecat_sdo_read_u32(ec_master_t *master,
  416. uint16_t slave,
  417. uint16_t index,
  418. uint8_t subindex,
  419. uint32_t *data,
  420. int timeout)
  421. {
  422. return ecat_sdo_read(master, slave, index, subindex, 0, data, 4, timeout);
  423. }
  424. rt_err_t ecat_write_state(ec_master_t *master, uint16_t slave, uint16_t state);
  425. rt_err_t ecat_check_state(
  426. ec_master_t *master, uint16_t slave, uint16_t *state, int timeout);
  427. rt_err_t ecat_config_init(ec_master_t *master, uint8_t usetable);
  428. rt_err_t ecat_config_dc(ec_master_t *master);
  429. rt_err_t ecat_config_map_group(ec_master_t *master, void *map, uint8_t group);
  430. rt_err_t ecat_send_processdata_group(ec_master_t *master, uint8_t group);
  431. rt_err_t ecat_receive_processdata_group(
  432. ec_master_t *master, uint8_t group, int timeout);
  433. rt_err_t ecat_timer_start(struct ecat_timer *t, uint32_t timeout_us);
  434. rt_bool_t ecat_timer_is_expired(struct ecat_timer *t);
  435. rt_err_t ecat_sync_dc(ec_master_t *master);
  436. rt_err_t ecat_hwtimer_start(ec_master_t *master);
  437. int ecat_service_init(void);
  438. #endif /* __ECAT_MASTER_H__ */