hpm_canopen.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * Copyright (c) 2023-2024 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <stdio.h>
  8. #include <assert.h>
  9. #include "board.h"
  10. #include "hpm_sysctl_drv.h"
  11. #include "hpm_canopen.h"
  12. extern struct device hpm_canopen_dev;
  13. struct hpm_can_config hpm_canopen_config = {0};
  14. struct hpm_can_data hpm_canopen_data = {0};
  15. uint32_t press_counter =0;
  16. static void hpmicro_can_remove_rx_filter(const struct device *dev, int filter_id)
  17. {
  18. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  19. hpm_mcan_remove_rx_filter(dev, filter_id);
  20. #else
  21. hpm_can_remove_rx_filter(dev, filter_id);
  22. #endif
  23. }
  24. static int hpmicro_can_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data, const struct can_filter *filter)
  25. {
  26. int filter_id = -ENOSPC;
  27. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  28. if ((filter->flags & CAN_FILTER_IDE) != 0U) {
  29. filter_id = hpm_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
  30. } else {
  31. filter_id = hpm_mcan_add_rx_filter_std(dev, callback, user_data, filter);
  32. }
  33. #else
  34. filter_id = hpm_can_add_rx_filter(dev, callback, user_data, filter);
  35. #endif
  36. return filter_id;
  37. }
  38. static int hpmicro_can_set_timing(const struct device *dev, const struct can_timing *timing)
  39. {
  40. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  41. return hpm_mcan_set_timing(dev, timing);
  42. #else
  43. return hpm_can_set_timing(dev, timing);
  44. #endif
  45. }
  46. static int hpm_can_get_core_clock(const struct device *dev, uint32_t *rate)
  47. {
  48. const struct hpm_can_config *cfg = dev->config;
  49. if (rate != NULL) {
  50. *rate = board_init_can_clock(cfg->base);
  51. }
  52. return 0;
  53. }
  54. static int hpmicro_can_set_mode(const struct device *dev, can_mode_t mode)
  55. {
  56. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  57. hpm_mcan_set_mode(dev, mode);
  58. #else
  59. hpm_can_set_mode(dev, mode);
  60. #endif
  61. return 0;
  62. }
  63. static int hpmicro_can_start(const struct device *dev)
  64. {
  65. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  66. hpm_mcan_start(dev);
  67. #else
  68. hpm_can_start(dev);
  69. #endif
  70. return 0;
  71. }
  72. static int hpmicro_can_stop(const struct device *dev)
  73. {
  74. const struct hpm_can_config *config = dev->config;
  75. struct hpm_can_data *data = dev->data;
  76. if (!data->started) {
  77. return -EALREADY;
  78. }
  79. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  80. mcan_deinit(config->base);
  81. #else
  82. can_deinit(config->base);
  83. #endif
  84. data->started = false;
  85. return 0;
  86. }
  87. static int hpmicro_can_get_max_filters(const struct device *dev, bool ide)
  88. {
  89. ARG_UNUSED(dev);
  90. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  91. if (ide) {
  92. return 16;
  93. } else {
  94. return 16;
  95. }
  96. #else
  97. ARG_UNUSED(ide);
  98. return 16;
  99. #endif
  100. }
  101. static int hpmicro_can_get_state(const struct device *dev,
  102. enum can_state *state,
  103. struct can_bus_err_cnt *err_cnt)
  104. {
  105. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  106. hpm_mcan_get_state(dev, state, err_cnt);
  107. #else
  108. hpm_can_get_state(dev, state, err_cnt);
  109. #endif
  110. return 0;
  111. }
  112. static int hpmicro_can_send(const struct device *dev,
  113. const struct can_frame *frame,
  114. k_timeout_t timeout,
  115. can_tx_callback_t callback,
  116. void *user_data)
  117. {
  118. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  119. hpm_mcan_send(dev, frame, timeout, callback, user_data);
  120. #else
  121. hpm_can_send(dev, frame, timeout, callback, user_data);
  122. #endif
  123. return 0;
  124. }
  125. static const struct can_driver_api hpm_can_driver_api = {
  126. .get_capabilities = NULL,
  127. .set_mode = hpmicro_can_set_mode,
  128. .set_timing = hpmicro_can_set_timing,
  129. .send = hpmicro_can_send,
  130. .start = hpmicro_can_start,
  131. .stop = hpmicro_can_stop,
  132. .add_rx_filter = hpmicro_can_add_rx_filter,
  133. .remove_rx_filter = hpmicro_can_remove_rx_filter,
  134. .get_state = hpmicro_can_get_state,
  135. .set_state_change_callback = NULL,
  136. .get_core_clock = hpm_can_get_core_clock,
  137. .get_max_filters = hpmicro_can_get_max_filters,
  138. .timing_min = {
  139. .sjw = 1,
  140. .prop_seg = 1,
  141. .phase_seg1 = 1,
  142. .phase_seg2 = 2,
  143. .prescaler = 1,
  144. },
  145. .timing_max = {
  146. .sjw = 16,
  147. .prop_seg = 8,
  148. .phase_seg1 = 56,
  149. .phase_seg2 = 32,
  150. .prescaler = 256,
  151. },
  152. };
  153. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  154. void canopen_init(struct canopen_context *CANdriverState, MCAN_Type *canptr, uint32_t baudrate)
  155. #else
  156. void canopen_init(struct canopen_context *CANdriverState, CAN_Type *canptr, uint32_t baudrate)
  157. #endif
  158. {
  159. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  160. mcan_deinit(canptr);
  161. mcan_config_t can_config;
  162. mcan_get_default_config(canptr, &can_config);
  163. can_config.mode = mcan_mode_normal;
  164. #else
  165. can_deinit(canptr);
  166. can_config_t can_config;
  167. can_get_default_config(&can_config);
  168. can_config.mode = can_mode_normal;
  169. #endif
  170. can_config.baudrate = baudrate;
  171. uint32_t can_src_clk_freq = board_init_can_clock(canptr);
  172. board_init_can(canptr);
  173. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  174. hpm_stat_t status = mcan_init(canptr, &can_config, can_src_clk_freq);
  175. #else
  176. hpm_stat_t status = can_init(canptr, &can_config, can_src_clk_freq);
  177. #endif
  178. if (status != status_success) {
  179. printf("CAN initialization failed, error code: %d\n", status);
  180. return;
  181. }
  182. hpm_canopen_config.base = canptr;
  183. hpm_canopen_data.config = can_config;
  184. hpm_canopen_data.started = false;
  185. hpm_canopen_data.filter_rtr = 0;
  186. hpm_canopen_data.filter_rtr_mask = 0;
  187. #ifdef HPMSOC_HAS_HPMSDK_MCAN
  188. hpm_canopen_data.ext_filter_count = 0;
  189. hpm_canopen_data.std_filter_count = 0;
  190. #else
  191. hpm_canopen_data.can_filter_count = 0;
  192. #endif
  193. hpm_canopen_dev.config = &hpm_canopen_config;
  194. hpm_canopen_dev.data = &hpm_canopen_data;
  195. hpm_canopen_dev.api = &hpm_can_driver_api;
  196. CANdriverState->dev = &hpm_canopen_dev;
  197. }
  198. CO_SDO_abortCode_t odf_2102(CO_ODF_arg_t *odf_arg)
  199. {
  200. uint32_t value;
  201. value = CO_getUint32(odf_arg->data);
  202. if (odf_arg->reading) {
  203. return CO_SDO_AB_NONE;
  204. }
  205. if (odf_arg->subIndex != 0U) {
  206. return CO_SDO_AB_NONE;
  207. }
  208. if (value != 0) {
  209. /* Preserve old value */
  210. memcpy(odf_arg->data, odf_arg->ODdataStorage, sizeof(uint32_t));
  211. return CO_SDO_AB_DATA_TRANSF;
  212. }
  213. printf("Resetting button press counter");
  214. press_counter = 0;
  215. return CO_SDO_AB_NONE;
  216. }