test_tmr_capture.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. * SPDX-License-Identifier: Apache-2.0
  4. *
  5. * Change Logs:
  6. * Date Author Notes
  7. * 2025-01-10 CDT first version
  8. */
  9. /*
  10. * 功能
  11. * 展示捕获单元 ic1、ic2、ic3 的捕获输入功能
  12. * 当捕获单元捕获到设定数量(watermark)的数据(微秒级别的电平宽度)后,终端将输出这些已捕获的数据
  13. *
  14. * 默认配置
  15. * input pin:
  16. * ic1: INPUT_CAPTURE_TMR6_1_PORT, INPUT_CAPTURE_TMR6_1_PIN
  17. * ic2: INPUT_CAPTURE_TMR6_2_PORT, INPUT_CAPTURE_TMR6_2_PIN
  18. * ic3: INPUT_CAPTURE_TMR6_3_PORT, INPUT_CAPTURE_TMR6_3_PIN
  19. * watermark:
  20. * ic1:5
  21. * ic2:5
  22. * ic3: 5
  23. *
  24. * 命令行命令
  25. * 1)开启捕获单元:
  26. * 格式:
  27. * ic open <unit>
  28. * 示例:
  29. * MSH >ic open 3(开启 ic3)
  30. * 2)关闭捕获单元:
  31. * 格式:
  32. * ic close <unit>
  33. * 示例:
  34. * MSH >ic close 3 (关闭 ic3)
  35. * 3)设置捕获单元的 watermark:
  36. * 格式:
  37. * ic wm <unit> <wm>
  38. * 示例:
  39. * MSH >ic wm 3 11 (设置 ic3 的 watermark 为 11)
  40. * 4)清除捕获单元的捕获数据:
  41. * 格式:
  42. * ic clr <unit>
  43. * 示例:
  44. * MSH >ic clr 3 (清除 ic3 的捕获数据)
  45. * 5)显示命令的使用方法说明:
  46. * 格式:
  47. * ic
  48. * 示例:
  49. * MSH >ic
  50. */
  51. #include <rtthread.h>
  52. #include <rtdevice.h>
  53. #include <board.h>
  54. #include <stdlib.h>
  55. #define MSH_USAGE_IC_OPEN " ic open <unit> - e.g., open ic3: ic open 3 \n"
  56. #define MSH_USAGE_IC_CLOSE " ic close <unit> - e.g., close ic3: ic close 3\n"
  57. #define MSH_USAGE_IC_SET_WM " ic wm <unit> <wm> - e.g., set warter mark of ic3 to 11: ic wm 3 11\n"
  58. #define MSH_USAGE_IC_CLR " ic clr <unit> - e.g., clear data buffer of ic3: ic clr 3 \n"
  59. #if defined (HC32F4A0)
  60. #define IC_DEV_CNT (8)
  61. #elif defined (HC32F460)
  62. #define IC_DEV_CNT (3)
  63. #endif
  64. #define IC_NAME_LEN (3)
  65. #define DEFAULT_WATER_MARK (5)
  66. #ifdef BSP_USING_INPUT_CAPTURE
  67. typedef struct
  68. {
  69. rt_device_t ic_dev;
  70. rt_sem_t rx_sem;
  71. rt_mutex_t mutex;
  72. __IO rt_size_t ic_data_size;
  73. rt_thread_t thread;
  74. } test_ic_t;
  75. static test_ic_t g_arr_test_ic[IC_DEV_CNT] = {0};
  76. static int32_t _get_test_id(rt_device_t ic_dev)
  77. {
  78. for (int i = 0; i < IC_DEV_CNT; i++)
  79. {
  80. if (ic_dev == g_arr_test_ic[i].ic_dev)
  81. {
  82. return i;
  83. }
  84. }
  85. return -1;
  86. }
  87. static rt_err_t ic_rx_all(rt_device_t dev, rt_size_t size)
  88. {
  89. uint32_t id = _get_test_id(dev);
  90. g_arr_test_ic[id].ic_data_size = size;
  91. rt_sem_release((g_arr_test_ic[id].rx_sem));
  92. return RT_EOK;
  93. }
  94. static void ic_rx_thread(void *parameter)
  95. {
  96. rt_size_t size;
  97. rt_device_t ic_dev;
  98. rt_uint32_t id = *(uint32_t *)parameter;
  99. test_ic_t *p_test_ic = &g_arr_test_ic[id];
  100. ic_dev = p_test_ic->ic_dev;
  101. struct rt_inputcapture_data *pData = RT_NULL;
  102. struct rt_inputcapture_data *pItem = RT_NULL;
  103. int i = 0;
  104. while (1)
  105. {
  106. rt_sem_take((p_test_ic->rx_sem), RT_WAITING_FOREVER);
  107. pData = (struct rt_inputcapture_data *)rt_malloc(sizeof(struct rt_inputcapture_data) * p_test_ic->ic_data_size);
  108. if (pData)
  109. {
  110. rt_mutex_take(p_test_ic->mutex, RT_WAITING_FOREVER);
  111. size = rt_device_read(ic_dev, 0, pData, p_test_ic->ic_data_size);
  112. rt_mutex_release(p_test_ic->mutex);
  113. if (size == 0)
  114. {
  115. rt_free(pData);
  116. pData = RT_NULL;
  117. continue;
  118. }
  119. rt_kprintf("ic%d captured %d data:\n", id + 1, size);
  120. for (i = 0; i < size; i++)
  121. {
  122. pItem = pData + i;
  123. rt_kprintf("%d : h = %d, w =%d\n", i, pItem->is_high, pItem->pulsewidth_us);
  124. }
  125. rt_free(pData);
  126. pData = RT_NULL;
  127. }
  128. rt_kprintf("-------------------\n");
  129. }
  130. }
  131. static rt_int32_t _ic_test_open(rt_int32_t id)
  132. {
  133. rt_err_t ret = RT_EOK;
  134. uint32_t def_wm = DEFAULT_WATER_MARK;
  135. rt_device_t ic_dev;
  136. char ic_name[IC_NAME_LEN] = "ic";
  137. ic_name[IC_NAME_LEN - 1] = 0x30 + id + 1;
  138. ic_dev = rt_device_find(ic_name);
  139. RT_ASSERT(ic_dev != RT_NULL);
  140. g_arr_test_ic[id].ic_dev = ic_dev;
  141. g_arr_test_ic[id].rx_sem = rt_sem_create(ic_name, 0, RT_IPC_FLAG_FIFO);
  142. g_arr_test_ic[id].mutex = rt_mutex_create(ic_name, RT_IPC_FLAG_FIFO);
  143. ret = rt_device_init(ic_dev);
  144. RT_ASSERT(ret == RT_EOK);
  145. rt_device_set_rx_indicate(ic_dev, ic_rx_all);
  146. g_arr_test_ic[id].thread = rt_thread_create(ic_name, ic_rx_thread, &id, 2048, 5, 10);
  147. RT_ASSERT(g_arr_test_ic[id].thread != RT_NULL);
  148. rt_thread_startup(g_arr_test_ic[id].thread);
  149. ret = rt_device_open(ic_dev, 0);
  150. RT_ASSERT(ret == RT_EOK);
  151. ret = rt_device_control(ic_dev, INPUTCAPTURE_CMD_SET_WATERMARK, &def_wm);
  152. RT_ASSERT(ret == RT_EOK);
  153. return RT_EOK;
  154. }
  155. static rt_int32_t _ic_test_close(rt_int32_t id)
  156. {
  157. rt_err_t ret = RT_EOK;
  158. ret = rt_device_close(g_arr_test_ic[id].ic_dev);
  159. RT_ASSERT(ret == RT_EOK);
  160. rt_sem_delete(g_arr_test_ic[id].rx_sem);
  161. rt_mutex_delete(g_arr_test_ic[id].mutex);
  162. rt_thread_delete(g_arr_test_ic[id].thread);
  163. rt_memset(&g_arr_test_ic[id], 0, sizeof(test_ic_t));
  164. return RT_EOK;
  165. }
  166. static rt_int32_t _ic_ctrl(rt_int32_t id, rt_int32_t cmd, char *param)
  167. {
  168. rt_err_t ret = RT_EOK;
  169. uint32_t int_param = (param == RT_NULL) ? 0 : atoi(param);
  170. rt_mutex_take(g_arr_test_ic[id].mutex, RT_WAITING_FOREVER);
  171. ret = rt_device_control(g_arr_test_ic[id].ic_dev, cmd, &int_param);
  172. rt_mutex_release(g_arr_test_ic[id].mutex);
  173. return ret;
  174. }
  175. static rt_err_t _msh_cmd_parse_unit(char *n, uint32_t *u_out)
  176. {
  177. rt_err_t result = -RT_ERROR;
  178. uint32_t u_temp = atoi(n) - 1;
  179. if (u_temp >= IC_DEV_CNT)
  180. {
  181. rt_kprintf("param error: channel exceed max value %d \n", IC_DEV_CNT);
  182. return result;
  183. }
  184. *u_out = u_temp;
  185. return RT_EOK;
  186. }
  187. void _show_usage(void)
  188. {
  189. rt_kprintf("Usage: \n");
  190. rt_kprintf(MSH_USAGE_IC_OPEN);
  191. rt_kprintf(MSH_USAGE_IC_CLOSE);
  192. rt_kprintf(MSH_USAGE_IC_SET_WM);
  193. rt_kprintf(MSH_USAGE_IC_CLR);
  194. }
  195. static rt_int32_t ic(int argc, char *argv[])
  196. {
  197. uint32_t id = 0;
  198. if (argc == 1)
  199. {
  200. _show_usage();
  201. return 0;
  202. }
  203. switch (argc)
  204. {
  205. case 1:
  206. _show_usage();
  207. return 0;
  208. case 3:
  209. case 4:
  210. if (_msh_cmd_parse_unit(argv[2], &id) != RT_EOK)
  211. {
  212. return 0;
  213. }
  214. if (!rt_strcmp(argv[1], "open"))
  215. {
  216. if (g_arr_test_ic[id].ic_dev != RT_NULL)
  217. {
  218. return 0;
  219. }
  220. _ic_test_open(id);
  221. break;
  222. }
  223. if (g_arr_test_ic[id].ic_dev == RT_NULL)
  224. {
  225. return 0;
  226. }
  227. if (!rt_strcmp(argv[1], "close"))
  228. {
  229. _ic_test_close(id);
  230. }
  231. else if (!rt_strcmp(argv[1], "wm"))
  232. {
  233. _ic_ctrl(id, INPUTCAPTURE_CMD_SET_WATERMARK, argv[3]);
  234. }
  235. else if (!rt_strcmp(argv[1], "clr"))
  236. {
  237. _ic_ctrl(id, INPUTCAPTURE_CMD_CLEAR_BUF, RT_NULL);
  238. }
  239. else
  240. {
  241. rt_kprintf("usage error, input \"ic\" to show cmd info\n");
  242. return 0;
  243. }
  244. break;
  245. default:
  246. rt_kprintf("usage error, input \"ic\" to show cmd info\n");
  247. return 0;
  248. }
  249. rt_kprintf("done \n");
  250. return 0;
  251. }
  252. MSH_CMD_EXPORT(ic, ic [opt])
  253. #endif
  254. /*
  255. EOF
  256. */