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