test_tmr_capture.c 7.9 KB

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