hpm_esc_drv.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright (c) 2024 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_ESC_DRV_H
  8. #define HPM_ESC_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_esc_regs.h"
  11. /**
  12. *
  13. * @brief ESC driver APIs
  14. * @defgroup esc_interface ESC driver APIs
  15. * @ingroup esc_interfaces
  16. * @{
  17. */
  18. /**
  19. * @brief ESC error codes
  20. */
  21. enum {
  22. status_esc_eeprom_ack_error = MAKE_STATUS(status_group_esc, 0), /**< ESC EEPROM ack error */
  23. status_esc_eeprom_checksum_error = MAKE_STATUS(status_group_esc, 1), /**< ESC EEPROM checksum error */
  24. };
  25. typedef enum {
  26. latch_source_from_ntm = 0,
  27. latch_source_from_trigger_mux = 1,
  28. } esc_latch_source_t;
  29. typedef enum {
  30. esc_eeprom_idle_cmd = 0, /* clear error bits */
  31. esc_eeprom_read_cmd = 1,
  32. esc_eeprom_write_cmd = 2,
  33. esc_eeprom_reload_cmd = 4,
  34. } esc_eeprom_cmd_t;
  35. typedef enum {
  36. esc_ctrl_signal_func_alt_nmii_link0 = 0,
  37. esc_ctrl_signal_func_alt_nmii_link1 = 1,
  38. esc_ctrl_signal_func_alt_nmii_link2 = 2,
  39. esc_ctrl_signal_func_alt_link_act0 = 3,
  40. esc_ctrl_signal_func_alt_link_act1 = 4,
  41. esc_ctrl_signal_func_alt_link_act2 = 5,
  42. esc_ctrl_signal_func_alt_led_run = 6,
  43. esc_ctrl_signal_func_alt_led_err = 7,
  44. esc_ctrl_signal_func_alt_reset_out = 8,
  45. } esc_ctrl_signal_function_t;
  46. typedef struct {
  47. bool eeprom_emulation;
  48. bool eeprom_size_over_16kbit;
  49. bool core_clock_en;
  50. bool phy_refclk_en;
  51. } esc_eeprom_clock_config_t;
  52. #ifdef __cplusplus
  53. extern "C" {
  54. #endif
  55. /**
  56. * @brief ESC peripheral clock
  57. *
  58. * @param[in] ptr ESC base address
  59. * @param[in] enable Set true to enable or false to disable
  60. */
  61. static inline void esc_core_enable_clock(ESC_Type *ptr, bool enable)
  62. {
  63. if (enable) {
  64. ptr->GPR_CFG0 |= ESC_GPR_CFG0_CLK100_EN_MASK;
  65. } else {
  66. ptr->GPR_CFG0 &= ~ESC_GPR_CFG0_CLK100_EN_MASK;
  67. }
  68. }
  69. /**
  70. * @brief ESC PHY clock
  71. *
  72. * @param[in] ptr ESC base address
  73. * @param[in] enable Set true to enable or false to disable
  74. */
  75. static inline void esc_phy_enable_clock(ESC_Type *ptr, bool enable)
  76. {
  77. if (enable) {
  78. ptr->PHY_CFG1 |= ESC_PHY_CFG1_REFCK_25M_OE_MASK; /*!< enable PHY 25M refck */
  79. } else {
  80. ptr->PHY_CFG1 &= ~ESC_PHY_CFG1_REFCK_25M_OE_MASK; /*!< disable PHY 25M refck */
  81. }
  82. }
  83. /**
  84. * @brief ESC config eeprom attributes(emulation and size) and peripheral clock
  85. *
  86. * @param[in] ptr ESC base address
  87. * @param[in] config esc_eeprom_clock_config_t
  88. */
  89. static inline void esc_config_eeprom_and_clock(ESC_Type *ptr, esc_eeprom_clock_config_t *config)
  90. {
  91. uint32_t gpr_cfg0 = ptr->GPR_CFG0;
  92. if (config->eeprom_emulation) {
  93. gpr_cfg0 |= ESC_GPR_CFG0_EEPROM_EMU_MASK;
  94. gpr_cfg0 &= ~(ESC_GPR_CFG0_PROM_SIZE_MASK | ESC_GPR_CFG0_I2C_SCLK_EN_MASK);
  95. } else {
  96. gpr_cfg0 &= ~ESC_GPR_CFG0_EEPROM_EMU_MASK;
  97. gpr_cfg0 |= ESC_GPR_CFG0_I2C_SCLK_EN_MASK;
  98. if (config->eeprom_size_over_16kbit) {
  99. gpr_cfg0 |= ESC_GPR_CFG0_PROM_SIZE_MASK;
  100. } else {
  101. gpr_cfg0 &= ~ESC_GPR_CFG0_PROM_SIZE_MASK;
  102. }
  103. }
  104. ptr->GPR_CFG0 = gpr_cfg0;
  105. esc_core_enable_clock(ptr, config->core_clock_en);
  106. esc_phy_enable_clock(ptr, config->phy_refclk_en);
  107. }
  108. /**
  109. * @brief ESC assign specific function to CTRL signal
  110. *
  111. * @param[in] ptr ESC base address
  112. * @param[in] index CTRL signal index(0-8)
  113. * @param[in] func specific function
  114. * @param[in] invert invert signal
  115. */
  116. static inline void esc_config_ctrl_signal_function(ESC_Type *ptr, uint8_t index, esc_ctrl_signal_function_t func, bool invert)
  117. {
  118. ptr->IO_CFG[index] = ESC_IO_CFG_FUNC_ALT_SET(func) | ESC_IO_CFG_INVERT_SET(invert);
  119. }
  120. /**
  121. * @brief ESC config nmii_link signal source
  122. *
  123. * @param[in] ptr ESC base address
  124. * @param[in] link0_from_io true for signal from configured IO; false for signal from register(GPR_CFG2) value
  125. * @param[in] link1_from_io true for signal from configured IO; false for signal from register(GPR_CFG2) value
  126. * @param[in] link2_from_io true for signal from configured IO; false for signal from register(GPR_CFG2) value
  127. */
  128. static inline void esc_config_nmii_link_source(ESC_Type *ptr, bool link0_from_io, bool link1_from_io, bool link2_from_io)
  129. {
  130. if (link0_from_io) {
  131. ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK0_FROM_IO_MASK;
  132. } else {
  133. ptr->GPR_CFG2 &= ~ESC_GPR_CFG2_NMII_LINK0_FROM_IO_MASK;
  134. ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK0_GPR_MASK; /* config GRP to indicate LINK0 is invalid by default */
  135. }
  136. if (link1_from_io) {
  137. ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK1_FROM_IO_MASK;
  138. } else {
  139. ptr->GPR_CFG2 &= ~ESC_GPR_CFG2_NMII_LINK1_FROM_IO_MASK;
  140. ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK1_GPR_MASK; /* config GRP to indicate LINK1 is invalid by default */
  141. }
  142. if (link2_from_io) {
  143. ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK2_FROM_IO_MASK;
  144. } else {
  145. ptr->GPR_CFG2 &= ~ESC_GPR_CFG2_NMII_LINK2_FROM_IO_MASK;
  146. ptr->GPR_CFG2 |= ESC_GPR_CFG2_NMII_LINK2_GPR_MASK; /* config GRP to indicate LINK2 is invalid by default */
  147. }
  148. }
  149. /* config ESC reset request source: ESC core or GRP_REG value */
  150. /**
  151. * @brief ESC config reset signal source
  152. *
  153. * @param[in] ptr ESC base address
  154. * @param[in] reset_from_ecat_core true for reset signal from ecat core; false for reset signal from register(GPR_CFG1) value
  155. */
  156. static inline void esc_config_reset_source(ESC_Type *ptr, bool reset_from_ecat_core)
  157. {
  158. if (reset_from_ecat_core) {
  159. ptr->GPR_CFG1 |= ESC_GPR_CFG1_RSTO_OVRD_ENJ_MASK;
  160. } else {
  161. ptr->GPR_CFG1 &= ~ESC_GPR_CFG1_RSTO_OVRD_ENJ_MASK;
  162. }
  163. }
  164. /**
  165. * @brief ESC generate reset signal to ESC_RESET interrupt and RESET_OUT pin
  166. * @note the reset signal source should be configured in esc_config_reset_source before
  167. *
  168. * @param[in] ptr ESC base address
  169. */
  170. static inline void esc_pdi_reset(ESC_Type *ptr)
  171. {
  172. ptr->ESC_RST_PDI = 0x52; /* R */
  173. ptr->ESC_RST_PDI = 0x45; /* E */
  174. ptr->ESC_RST_PDI = 0x53; /* S */
  175. }
  176. /*!
  177. * @brief ESC read PHY register via ESC MII Management Interface
  178. *
  179. * @param[in] ptr ESC base address
  180. * @param[in] phy_addr PHY address.
  181. * @param[in] reg_addr Register address.
  182. * @param[in] data PHY data returned.
  183. */
  184. hpm_stat_t esc_mdio_read(ESC_Type *ptr, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
  185. /*!
  186. * @brief ESc write PHY register via ESC MII Management Interface
  187. *
  188. * @param[in] ptr ESC base address
  189. * @param[in] phy_addr PHY address.
  190. * @param[in] reg_addr Register address.
  191. * @param[in] data Write to PHY register.
  192. */
  193. hpm_stat_t esc_mdio_write(ESC_Type *ptr, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
  194. /*!
  195. * @brief ESC check eeprom loading data status
  196. * @note EtherCAT communication is possible even if the EEPROM is blank
  197. *
  198. * @param[in] ptr ESC base address.
  199. * @retval status_success: loding data successfully and correctlly.
  200. * @retval status_esc_eeprom_ack_error: loding data checksum error(eeprom blank).
  201. * @retval status_esc_eeprom_checksum_error: no ack error.
  202. * @retval status_timeout: loding data timeout.
  203. */
  204. hpm_stat_t esc_check_eeprom_loading(ESC_Type *ptr);
  205. /*!
  206. * @brief ESC get eeprom cmd, this using in eeprom emulation function
  207. *
  208. * @param[in] ptr ESC base address
  209. * @return uint8_t esc_eeprom_cmd_t.
  210. */
  211. static inline uint8_t esc_get_eeprom_cmd(ESC_Type *ptr)
  212. {
  213. return ESC_EEPROM_CTRL_STAT_CMD_GET(ptr->EEPROM_CTRL_STAT);
  214. }
  215. /*!
  216. * @brief ESC ack eeprom cmd in eeprom emualtion function
  217. *
  218. * @param[in] ptr ESC base address
  219. * @param[in] cmd esc_eeprom_cmd_t
  220. * @param[in] ack_err eeprom ack error occurrred
  221. * @param[in] crc_err eeprom checksum error occurrred
  222. */
  223. static inline void esc_eeprom_emulation_ack(ESC_Type *ptr, esc_eeprom_cmd_t cmd, bool ack_err, bool crc_err)
  224. {
  225. uint16_t temp = ESC_EEPROM_CTRL_STAT_CMD_SET(cmd);
  226. if (ack_err) {
  227. temp |= ESC_EEPROM_CTRL_STAT_ERR_ACK_CMD_MASK;
  228. }
  229. if (crc_err) {
  230. temp |= ESC_EEPROM_CTRL_STAT_CKSM_ERR_MASK;
  231. }
  232. ptr->EEPROM_CTRL_STAT = temp;
  233. }
  234. /*!
  235. * @brief ESC get eeprom byte address
  236. *
  237. * @param[in] ptr ESC base address
  238. * @return byte address
  239. */
  240. static inline uint32_t esc_get_eeprom_byte_address(ESC_Type *ptr)
  241. {
  242. return (ptr->EEPROM_ADDR) << 1U;
  243. }
  244. /*!
  245. * @brief ESC get eeprom word(2 bytes) address
  246. *
  247. * @param[in] ptr ESC base address
  248. * @return word address
  249. */
  250. static inline uint32_t esc_get_eeprom_word_address(ESC_Type *ptr)
  251. {
  252. return ptr->EEPROM_ADDR;
  253. }
  254. /*!
  255. * @brief ESC read eeprom data from register, this function is using in eeprom emulation function
  256. *
  257. * @param[in] ptr ESC base address
  258. * @return eeprom data
  259. */
  260. static inline uint64_t esc_read_eeprom_data(ESC_Type *ptr)
  261. {
  262. return ptr->EEPROM_DATA;
  263. }
  264. /*!
  265. * @brief ESC write eeprom data to register, this function is using in eeprom emulation function
  266. *
  267. * @param[in] ptr ESC base address
  268. * @param[in] data eeprom data
  269. */
  270. static inline void esc_write_eeprom_data(ESC_Type *ptr, uint64_t data)
  271. {
  272. ptr->EEPROM_DATA = data;
  273. }
  274. /*!
  275. * @brief ESC config latch0 signal source
  276. *
  277. * @param[in] ptr ESC base address
  278. * @param[in] latch0_from_ntm true for signal from ntm system, false for signal from IO
  279. */
  280. static inline void esc_config_latch0_source(ESC_Type *ptr, bool latch0_from_ntm)
  281. {
  282. if (latch0_from_ntm) {
  283. ptr->GPR_CFG1 &= ~ESC_GPR_CFG1_LATCH0_FROM_IO_MASK;
  284. } else {
  285. ptr->GPR_CFG1 |= ESC_GPR_CFG1_LATCH0_FROM_IO_MASK;
  286. }
  287. }
  288. /*!
  289. * @brief ESC config latch1 signal source
  290. *
  291. * @param[in] ptr ESC base address
  292. * @param[in] latch0_from_trigmux true for signal from trigmux system, false for signal from IO
  293. */
  294. static inline void esc_config_latch1_source(ESC_Type *ptr, bool latch0_from_trigmux)
  295. {
  296. if (latch0_from_trigmux) {
  297. ptr->GPR_CFG1 &= ~ESC_GPR_CFG1_LATCH1_FROM_IO_MASK;
  298. } else {
  299. ptr->GPR_CFG1 |= ESC_GPR_CFG1_LATCH1_FROM_IO_MASK;
  300. }
  301. }
  302. #ifdef __cplusplus
  303. }
  304. #endif
  305. /**
  306. * @}
  307. */
  308. #endif /* HPM_ESC_DRV_H */