1 /*
2 * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-12-30 CDT first version
9 */
10
11 /*
12 * 程序清单: Pulse encoder 设备使用例程, 请在图形化配置界面打开pulse encoder device,
13 * 并使能tmra_1和tmr6_1.
14 * 例程导出了 encoder_sample 命令到控制终端, 通过串口可查看当前的count数值
15 * 命令调用格式:pulse_encoder_sample devname [option1] [option2]
16 * devname: [pulse_a1/pulse_61] 编码器单元名称
17 * option1: 正转脉冲数
18 * option2: 反转脉冲数
19 * eg:encoder_sample pulse_a1 2000 1000
20 * 编码器的分辨率是1000
21 * 硬件IO查看对应board/board_config.h中相关端口定义,并且需要正确连接到对应模拟脉冲生成的端口
22 * 程序功能:
23 */
24
25 #include <rtthread.h>
26 #include <rtdevice.h>
27 #include <stdlib.h>
28 #include "board_config.h"
29 #include <board.h>
30
31 #ifdef BSP_USING_PULSE_ENCODER
32
33 #if defined (HC32F4A0)
34 #define TEST_IO_A_PIN GET_PIN(A, 5)
35 #define TEST_IO_B_PIN GET_PIN(A, 6)
36 #else
37 #define TEST_IO_A_PIN GET_PIN(B, 0)
38 #define TEST_IO_B_PIN GET_PIN(B, 1)
39 #endif
40
41 static rt_device_t pulse_encoder_dev = RT_NULL;
42
printf_connect(void)43 static void printf_connect(void)
44 {
45 #if defined (HC32F4A0)
46 #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
47 rt_kprintf(" [tmra]*connect PA5-->PA8 PA6-->PA9\n");
48 #endif
49 #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
50 rt_kprintf(" [tmr6]*connect PA5-->PB9 PA6-->PB8\n");
51 #endif
52 #endif
53 #if defined (HC32F460)
54 #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
55 rt_kprintf(" [tmra]*connect PB0-->PA8 PB1-->PA9\n");
56 #endif
57 #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
58 rt_kprintf(" [tmr6]*connect PB0-->PE9 PB1-->PE8\n");
59 #endif
60 #endif
61 #if defined (HC32F448)
62 #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
63 rt_kprintf(" [tmra]*connect PB0-->PA8 PB1-->PA9\n");
64 #endif
65 #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
66 rt_kprintf(" [tmr6]*connect PB0-->PB5 PB1-->PB13\n");
67 #endif
68 #endif
69 #if defined (HC32F472)
70 #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
71 rt_kprintf(" [tmra]*connect PB0-->PA0 PB1-->PA1\n");
72 #endif
73 #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
74 rt_kprintf(" [tmr6]*connect PB0-->PA3 PB1-->PA7\n");
75 #endif
76 #endif
77 }
78
_pulse_cmd_print_usage(void)79 static void _pulse_cmd_print_usage(void)
80 {
81 rt_kprintf("encoder_sample devname [option1] [option2]\n");
82 rt_kprintf(" devname: [pulse_a1/pulse_61..] pulse uint\n");
83 rt_kprintf(" option1: number of positive pulses\n");
84 rt_kprintf(" option2: number of reversal pulses\n");
85 rt_kprintf(" e.g. MSH >encoder_sample pulse_a1 2000 1000\n");
86 printf_connect();
87 }
88
GenClkUp(const uint16_t cnt)89 static void GenClkUp(const uint16_t cnt)
90 {
91 uint32_t i, j;
92 rt_int32_t count;
93 const uint8_t bAin[4U] = {1U, 1U, 0U, 0U};
94 const uint8_t bBin[4U] = {0U, 1U, 1U, 0U};
95 for (j = 0UL; j < cnt; j++)
96 {
97 for (i = 0UL; i < 4UL; i++)
98 {
99 if (0U == bAin[i])
100 {
101 rt_pin_write(TEST_IO_A_PIN, PIN_LOW);
102 }
103 else
104 {
105 rt_pin_write(TEST_IO_A_PIN, PIN_HIGH);
106 }
107 if (0U == bBin[i])
108 {
109 rt_pin_write(TEST_IO_B_PIN, PIN_LOW);
110 }
111 else
112 {
113 rt_pin_write(TEST_IO_B_PIN, PIN_HIGH);
114 }
115 rt_thread_mdelay(1UL);
116 }
117 rt_device_read(pulse_encoder_dev, 0, &count, 1);
118 rt_kprintf("%d\r\n", count);
119 }
120 }
121
GenClkDown(const uint16_t cnt)122 static void GenClkDown(const uint16_t cnt)
123 {
124 uint32_t i, j;
125 rt_int32_t count;
126 const uint8_t bAin[4U] = {0U, 1U, 1U, 0U};
127 const uint8_t bBin[4U] = {1U, 1U, 0U, 0U};
128 for (j = 0UL; j < cnt; j++)
129 {
130 for (i = 0UL; i < 4UL; i++)
131 {
132 if (0U == bAin[i])
133 {
134 rt_pin_write(TEST_IO_A_PIN, PIN_LOW);
135 }
136 else
137 {
138 rt_pin_write(TEST_IO_A_PIN, PIN_HIGH);
139 }
140 if (0U == bBin[i])
141 {
142 rt_pin_write(TEST_IO_B_PIN, PIN_LOW);
143 }
144 else
145 {
146 rt_pin_write(TEST_IO_B_PIN, PIN_HIGH);
147 }
148 rt_thread_mdelay(1UL);
149 }
150 rt_device_read(pulse_encoder_dev, 0, &count, 1);
151 rt_kprintf("%d\r\n", count);
152 }
153 }
154
encoder_sample(int argc,char ** argv)155 static int encoder_sample(int argc, char **argv)
156 {
157 rt_int32_t count;
158
159 if ((argc != 4))
160 {
161 _pulse_cmd_print_usage();
162 return -RT_ERROR;
163 }
164
165 rt_pin_mode(TEST_IO_A_PIN, PIN_MODE_OUTPUT);
166 rt_pin_mode(TEST_IO_B_PIN, PIN_MODE_OUTPUT);
167
168 pulse_encoder_dev = rt_device_find(argv[1]);
169 if (pulse_encoder_dev == RT_NULL)
170 {
171 rt_kprintf("encoder_sample run failed! can't find %s device!\n", argv[1]);
172 _pulse_cmd_print_usage();
173 return -RT_ERROR;
174 }
175 rt_device_open(pulse_encoder_dev, RT_DEVICE_OFLAG_RDONLY);
176 rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
177 rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
178
179 /* 自测DISABLE和CLEAR功能 */
180 GenClkUp(100);
181 rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_DISABLE, RT_NULL);
182 /* 测试DISABLE后是否还会计数 */
183 GenClkUp(10);
184 rt_device_read(pulse_encoder_dev, 0, &count, 1);
185 rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
186 if (count != 100)
187 {
188 rt_kprintf("**************Self-test failed**************\n");
189 rt_device_close(pulse_encoder_dev);
190 _pulse_cmd_print_usage();
191 return -RT_ERROR;
192 }
193 else
194 {
195 rt_kprintf("**************Self-test success**************\n");
196 rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
197 GenClkUp(atoi(argv[2]));
198 GenClkDown(atoi(argv[3]));
199
200 rt_device_read(pulse_encoder_dev, 0, &count, 1);
201 if (count == (atoi(argv[2]) - atoi(argv[3])))
202 {
203 rt_kprintf("encoder_sample test success\n");
204 }
205 else
206 {
207 rt_kprintf("encoder_sample test failed\n");
208 }
209
210 rt_device_close(pulse_encoder_dev);
211 }
212
213 return RT_EOK;
214 }
215
216 /* 导出到 msh 命令列表中 */
217 MSH_CMD_EXPORT(encoder_sample, encoder sample devname [option1] [option2]);
218 #endif
219