1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-23 balanceTWK first version
* 2021-01-19 Leslie Lee port to imxrt series
*/
#include <rtthread.h>
#include <rtdevice.h>
#ifdef BSP_USING_PULSE_ENCODER
#include "fsl_common.h"
#include "fsl_enc.h"
#define LOG_TAG "drv.pulse_encoder"
#include <drv_log.h>
#if !defined(BSP_USING_PULSE_ENCODER1) && !defined(BSP_USING_PULSE_ENCODER2) && !defined(BSP_USING_PULSE_ENCODER3) \
&& !defined(BSP_USING_PULSE_ENCODER4)
#error "Please define at least one BSP_USING_PULSE_ENCODERx"
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
#elif (defined(BSP_USING_PULSE_ENCODER2) || defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1015_SERIES)
#error "IMXRT1015 had only one quadrature decoder module"
#elif (defined(BSP_USING_PULSE_ENCODER3) || defined(BSP_USING_PULSE_ENCODER4)) || defined(SOC_IMXRT1020_SERIES)
#error "IMXRT1020 had only two quadrature decoder module"
#endif
enum
{
#ifdef BSP_USING_PULSE_ENCODER1
PULSE_ENCODER1_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER2
PULSE_ENCODER2_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER3
PULSE_ENCODER3_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER4
PULSE_ENCODER4_INDEX,
#endif
};
struct imxrt_pulse_encoder_device
{
struct rt_pulse_encoder_device pulse_encoder;
ENC_Type *base;
char *name;
};
typedef struct imxrt_pulse_encoder_device imxrt_pulse_enccoder_device_t;
static imxrt_pulse_enccoder_device_t imxrt_pulse_encoder_obj[] =
{
#ifdef BSP_USING_PULSE_ENCODER1
{
.base = ENC1,
.name = "pulse1"
},
#endif
#ifdef BSP_USING_PULSE_ENCODER2
{
.base = ENC2,
.name = "pulse2"
},
#endif
#ifdef BSP_USING_PULSE_ENCODER3
{
.base = ENC3,
.name = "pulse3"
},
#endif
#ifdef BSP_USING_PULSE_ENCODER4
{
.base = ENC4,
.name = "pulse4"
},
#endif
};
rt_err_t pulse_encoder_init(struct rt_pulse_encoder_device *pulse_encoder)
{
ENC_Type *base = ((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base;
enc_config_t enc_config;
ENC_GetDefaultConfig(&enc_config);
ENC_Init(base, &enc_config);
ENC_DoSoftwareLoadInitialPositionValue(base); /* Update the position counter with initial value. */
return RT_EOK;
}
rt_err_t pulse_encoder_clear_count(struct rt_pulse_encoder_device *pulse_encoder)
{
ENC_SetInitialPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base, 0);
return RT_EOK;
}
rt_int32_t pulse_encoder_get_count(struct rt_pulse_encoder_device *pulse_encoder)
{
return (rt_int32_t)ENC_GetPositionValue(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
}
rt_err_t pulse_encoder_control(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args)
{
rt_err_t result;
result = RT_EOK;
switch (cmd)
{
case PULSE_ENCODER_CMD_ENABLE:
result = pulse_encoder->ops->init(pulse_encoder);
break;
case PULSE_ENCODER_CMD_DISABLE:
ENC_Deinit(((imxrt_pulse_enccoder_device_t *)(pulse_encoder->parent.user_data))->base);
break;
default:
result = -RT_ENOSYS;
break;
}
return result;
}
static const struct rt_pulse_encoder_ops _ops =
{
.init = pulse_encoder_init,
.get_count = pulse_encoder_get_count,
.clear_count = pulse_encoder_clear_count,
.control = pulse_encoder_control,
};
int rt_hw_pulse_encoder_init(void)
{
int i;
int result;
result = RT_EOK;
for (i = 0; i < sizeof(imxrt_pulse_encoder_obj) / sizeof(imxrt_pulse_encoder_obj[0]); i++)
{
imxrt_pulse_encoder_obj[i].pulse_encoder.type = AB_PHASE_PULSE_ENCODER;
imxrt_pulse_encoder_obj[i].pulse_encoder.ops = &_ops;
imxrt_pulse_encoder_obj[i].pulse_encoder.parent.user_data = &(imxrt_pulse_encoder_obj[i]);
if (rt_device_pulse_encoder_register(&imxrt_pulse_encoder_obj[i].pulse_encoder, imxrt_pulse_encoder_obj[i].name, &imxrt_pulse_encoder_obj[i]) != RT_EOK)
{
LOG_E("%s register failed", imxrt_pulse_encoder_obj[i].name);
result = -RT_ERROR;
}
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_pulse_encoder_init);
#endif
|