@@ -22,34 +22,62 @@ struct ifx_pwm
2222{
2323 struct rt_device_pwm pwm_device ;
2424 const cy_stc_tcpwm_pwm_config_t * tcpwm_pwm_config ;
25- TCPWM_Type * base ;
26- uint32_t cntNum ;
27- rt_uint8_t channel ;
25+ const mtb_hal_pwm_configurator_t * hal_cfg ;
2826 const char * name ;
29- uint32_t clk_dst ;
30- cy_en_divider_types_t clk_divType ;
31- uint32_t clk_divNum ;
3227};
3328
3429static struct ifx_pwm ifx_pwm_obj [] =
3530{
36- #ifdef BSP_USING_PWM18
37- #ifdef TCPWM_0_GRP_1_PWM_9_CONFIG
38- TCPWM_0_GRP_1_PWM_9_CONFIG ,
39- #endif
40- #endif
31+ IFX_PWM_DEVICE_LIST
32+ {0 }
4133};
4234
4335
4436#ifndef IFX_PWM_MAX_TICKS
4537#define IFX_PWM_MAX_TICKS 65535U
4638#endif
4739
40+ #ifndef IFX_PWM_DEFAULT_CHANNEL
41+ #define IFX_PWM_DEFAULT_CHANNEL 1U
42+ #endif
43+
44+ static inline TCPWM_Type * ifx_pwm_get_base (struct ifx_pwm * pwm )
45+ {
46+ if ((pwm == RT_NULL ) || (pwm -> hal_cfg == RT_NULL ))
47+ return RT_NULL ;
48+
49+ return pwm -> hal_cfg -> base ;
50+ }
51+
52+ static inline uint32_t ifx_pwm_get_cntnum (struct ifx_pwm * pwm )
53+ {
54+ if ((pwm == RT_NULL ) || (pwm -> hal_cfg == RT_NULL ))
55+ return 0U ;
56+
57+ return pwm -> hal_cfg -> cntnum ;
58+ }
59+
60+ static inline const mtb_hal_peri_div_t * ifx_pwm_get_clock_ref (struct ifx_pwm * pwm )
61+ {
62+ if ((pwm == RT_NULL ) || (pwm -> hal_cfg == RT_NULL ) ||
63+ (pwm -> hal_cfg -> clock == RT_NULL ) || (pwm -> hal_cfg -> clock -> clock_ref == RT_NULL ))
64+ {
65+ return RT_NULL ;
66+ }
67+
68+ return (const mtb_hal_peri_div_t * )pwm -> hal_cfg -> clock -> clock_ref ;
69+ }
70+
4871static inline uint32_t ifx_pwm_get_clock (struct ifx_pwm * pwm )
4972{
50- return Cy_SysClk_PeriPclkGetFrequency ((en_clk_dst_t )pwm -> clk_dst ,
51- pwm -> clk_divType ,
52- pwm -> clk_divNum );
73+ const mtb_hal_peri_div_t * clock_ref = ifx_pwm_get_clock_ref (pwm );
74+
75+ if (clock_ref == RT_NULL )
76+ return 0U ;
77+
78+ return Cy_SysClk_PeriPclkGetFrequency ((en_clk_dst_t )clock_ref -> clk_dst ,
79+ clock_ref -> div_type ,
80+ clock_ref -> div_num );
5381}
5482
5583static inline int ifx_pwm_check_clk (struct ifx_pwm * pwm , uint32_t * clk )
@@ -63,6 +91,24 @@ static inline int ifx_pwm_check_clk(struct ifx_pwm *pwm, uint32_t *clk)
6391 return RT_EOK ;
6492}
6593
94+ static inline rt_err_t ifx_pwm_check_cfg (struct ifx_pwm * pwm , const struct rt_pwm_configuration * cfg )
95+ {
96+ if (!pwm || ifx_pwm_get_base (pwm ) == RT_NULL )
97+ return - RT_ERROR ;
98+
99+ if (cfg == RT_NULL )
100+ return - RT_EINVAL ;
101+
102+ /* Single-channel PWM devices keep compatibility with channel 0 and default channel(1). */
103+ if ((cfg -> channel != 0U ) && (cfg -> channel != IFX_PWM_DEFAULT_CHANNEL ))
104+ {
105+ LOG_E ("%s: unsupported channel %u" , pwm -> name ? pwm -> name : "ifx_pwm" , cfg -> channel );
106+ return - RT_EINVAL ;
107+ }
108+
109+ return RT_EOK ;
110+ }
111+
66112static inline uint64_t ns_to_ticks (uint64_t ns , uint32_t clk )
67113{
68114 if (clk == 0U )
@@ -79,20 +125,25 @@ static inline uint64_t ns_to_ticks(uint64_t ns, uint32_t clk)
79125static rt_err_t drv_pwm_enable (struct rt_device_pwm * device , struct rt_pwm_configuration * configuration , rt_bool_t enable )
80126{
81127 struct ifx_pwm * pwm = (struct ifx_pwm * )device -> parent .user_data ;
128+ rt_err_t ret ;
129+ TCPWM_Type * base ;
130+ uint32_t cntNum ;
82131
83- (void )configuration ;
132+ ret = ifx_pwm_check_cfg (pwm , configuration );
133+ if (ret != RT_EOK )
134+ return ret ;
84135
85- if (! pwm || pwm -> base == RT_NULL )
86- return - RT_ERROR ;
136+ base = ifx_pwm_get_base ( pwm );
137+ cntNum = ifx_pwm_get_cntnum ( pwm ) ;
87138
88139 if (!enable )
89140 {
90- Cy_TCPWM_PWM_Disable (pwm -> base , pwm -> cntNum );
141+ Cy_TCPWM_PWM_Disable (base , cntNum );
91142 }
92143 else
93144 {
94- Cy_TCPWM_PWM_Enable (pwm -> base , pwm -> cntNum );
95- Cy_TCPWM_TriggerStart_Single (pwm -> base , pwm -> cntNum );
145+ Cy_TCPWM_PWM_Enable (base , cntNum );
146+ Cy_TCPWM_TriggerStart_Single (base , cntNum );
96147 }
97148
98149 return RT_EOK ;
@@ -101,10 +152,20 @@ static rt_err_t drv_pwm_enable(struct rt_device_pwm *device, struct rt_pwm_confi
101152static rt_err_t drv_pwm_set_period (struct ifx_pwm * pwm , struct rt_pwm_configuration * configuration )
102153{
103154 uint32_t clk ;
155+ uint32_t cntNum ;
156+ TCPWM_Type * base ;
157+ rt_err_t ret ;
158+
159+ ret = ifx_pwm_check_cfg (pwm , configuration );
160+ if (ret != RT_EOK )
161+ return ret ;
104162
105163 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
106164 return - RT_ERROR ;
107165
166+ base = ifx_pwm_get_base (pwm );
167+ cntNum = ifx_pwm_get_cntnum (pwm );
168+
108169 uint64_t period_ns = configuration -> period ;
109170 uint64_t ticks = ns_to_ticks (period_ns , clk );
110171
@@ -120,22 +181,32 @@ static rt_err_t drv_pwm_set_period(struct ifx_pwm *pwm, struct rt_pwm_configurat
120181 if (ticks > IFX_PWM_MAX_TICKS )
121182 ticks = IFX_PWM_MAX_TICKS ;
122183
123- Cy_TCPWM_PWM_SetPeriod0 (pwm -> base , pwm -> cntNum , (uint32_t )ticks );
184+ Cy_TCPWM_PWM_SetPeriod0 (base , cntNum , (uint32_t )ticks );
124185
125186 return RT_EOK ;
126187}
127188
128189static rt_err_t drv_pwm_set_pulse (struct ifx_pwm * pwm , struct rt_pwm_configuration * configuration )
129190{
130191 uint32_t clk ;
192+ uint32_t cntNum ;
193+ TCPWM_Type * base ;
194+ rt_err_t ret ;
195+
196+ ret = ifx_pwm_check_cfg (pwm , configuration );
197+ if (ret != RT_EOK )
198+ return ret ;
131199
132200 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
133201 return - RT_ERROR ;
134202
203+ base = ifx_pwm_get_base (pwm );
204+ cntNum = ifx_pwm_get_cntnum (pwm );
205+
135206 uint64_t pulse_ns = configuration -> pulse ;
136207 uint64_t ticks = ns_to_ticks (pulse_ns , clk );
137208
138- uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (pwm -> base , pwm -> cntNum );
209+ uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (base , cntNum );
139210
140211 if (period_ticks == 0 )
141212 {
@@ -148,7 +219,7 @@ static rt_err_t drv_pwm_set_pulse(struct ifx_pwm *pwm, struct rt_pwm_configurati
148219 ticks = period_ticks ;
149220 }
150221
151- Cy_TCPWM_PWM_SetCompare0Val (pwm -> base , pwm -> cntNum , (uint32_t )ticks );
222+ Cy_TCPWM_PWM_SetCompare0Val (base , cntNum , (uint32_t )ticks );
152223
153224 return RT_EOK ;
154225}
@@ -157,10 +228,20 @@ static rt_err_t drv_pwm_set(struct rt_device_pwm *device, struct rt_pwm_configur
157228{
158229 struct ifx_pwm * pwm = (struct ifx_pwm * )device -> parent .user_data ;
159230 uint32_t clk ;
231+ uint32_t cntNum ;
232+ TCPWM_Type * base ;
233+ rt_err_t ret ;
234+
235+ ret = ifx_pwm_check_cfg (pwm , configuration );
236+ if (ret != RT_EOK )
237+ return ret ;
160238
161239 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
162240 return - RT_ERROR ;
163241
242+ base = ifx_pwm_get_base (pwm );
243+ cntNum = ifx_pwm_get_cntnum (pwm );
244+
164245 uint64_t period_ticks = ns_to_ticks (configuration -> period , clk );
165246 uint64_t pulse_ticks = ns_to_ticks (configuration -> pulse , clk );
166247
@@ -179,8 +260,8 @@ static rt_err_t drv_pwm_set(struct rt_device_pwm *device, struct rt_pwm_configur
179260 if (period_ticks > IFX_PWM_MAX_TICKS )
180261 period_ticks = IFX_PWM_MAX_TICKS ;
181262
182- Cy_TCPWM_PWM_SetPeriod0 (pwm -> base , pwm -> cntNum , (uint32_t )period_ticks );
183- Cy_TCPWM_PWM_SetCompare0Val (pwm -> base , pwm -> cntNum , (uint32_t )pulse_ticks );
263+ Cy_TCPWM_PWM_SetPeriod0 (base , cntNum , (uint32_t )period_ticks );
264+ Cy_TCPWM_PWM_SetCompare0Val (base , cntNum , (uint32_t )pulse_ticks );
184265
185266 return RT_EOK ;
186267}
@@ -189,12 +270,22 @@ static rt_err_t drv_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configur
189270{
190271 struct ifx_pwm * pwm = (struct ifx_pwm * )device -> parent .user_data ;
191272 uint32_t clk ;
273+ uint32_t cntNum ;
274+ TCPWM_Type * base ;
275+ rt_err_t ret ;
276+
277+ ret = ifx_pwm_check_cfg (pwm , configuration );
278+ if (ret != RT_EOK )
279+ return ret ;
192280
193281 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
194282 return - RT_ERROR ;
195283
196- uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (pwm -> base , pwm -> cntNum );
197- uint32_t cmp_ticks = Cy_TCPWM_PWM_GetCompare0Val (pwm -> base , pwm -> cntNum );
284+ base = ifx_pwm_get_base (pwm );
285+ cntNum = ifx_pwm_get_cntnum (pwm );
286+
287+ uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (base , cntNum );
288+ uint32_t cmp_ticks = Cy_TCPWM_PWM_GetCompare0Val (base , cntNum );
198289
199290 configuration -> period = (uint64_t )period_ticks * 1000000000ULL / (uint64_t )clk ;
200291 configuration -> pulse = (uint64_t )cmp_ticks * 1000000000ULL / (uint64_t )clk ;
@@ -206,6 +297,14 @@ static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg
206297{
207298 struct rt_pwm_configuration * configuration = (struct rt_pwm_configuration * )arg ;
208299
300+ if ((cmd == PWM_CMD_ENABLE ) || (cmd == PWM_CMD_DISABLE ) ||
301+ (cmd == PWM_CMD_SET ) || (cmd == PWM_CMD_GET ) ||
302+ (cmd == PWM_CMD_SET_PERIOD ) || (cmd == PWM_CMD_SET_PULSE ))
303+ {
304+ if (configuration == RT_NULL )
305+ return - RT_EINVAL ;
306+ }
307+
209308 switch (cmd )
210309 {
211310 case PWM_CMD_ENABLE :
@@ -236,16 +335,22 @@ static struct rt_pwm_ops drv_ops = { drv_pwm_control };
236335static rt_err_t ifx_hw_pwm_init (struct ifx_pwm * device )
237336{
238337 cy_en_tcpwm_status_t tcpwm_status ;
338+ TCPWM_Type * base ;
339+ uint32_t cntNum ;
340+
239341 RT_ASSERT (device != RT_NULL );
240342
241- if (!device -> tcpwm_pwm_config || !device -> base )
343+ if (!device -> tcpwm_pwm_config || !device -> hal_cfg )
242344 {
243345 LOG_W ("%s: tcpwm config or base missing" , device -> name ? device -> name : "ifx_pwm" );
244346 return - RT_ERROR ;
245347 }
246348
247- tcpwm_status = Cy_TCPWM_PWM_Init (device -> base , device -> cntNum , device -> tcpwm_pwm_config );
248- if (CY_RSLT_SUCCESS != tcpwm_status )
349+ base = ifx_pwm_get_base (device );
350+ cntNum = ifx_pwm_get_cntnum (device );
351+
352+ tcpwm_status = Cy_TCPWM_PWM_Init (base , cntNum , device -> tcpwm_pwm_config );
353+ if (CY_TCPWM_SUCCESS != tcpwm_status )
249354 {
250355 LOG_E ("%s: Initialize the TCPWM block failed" , device -> name ? device -> name : "ifx_pwm" );
251356 return - RT_ERROR ;
@@ -259,20 +364,14 @@ static int rt_hw_pwm_init(void)
259364 int i ;
260365 int result = RT_EOK ;
261366 int count = sizeof (ifx_pwm_obj ) / sizeof (ifx_pwm_obj [0 ]);
262-
263- if (count == 0 )
264- {
265- LOG_W ("No PWM instances configured" );
266- return RT_EOK ;
267- }
367+ int registered = 0 ;
268368
269369 for (i = 0 ; i < count ; i ++ )
270370 {
271371 struct ifx_pwm * obj = & ifx_pwm_obj [i ];
272372
273- if (obj -> tcpwm_pwm_config == RT_NULL || obj -> base == RT_NULL )
373+ if (obj -> tcpwm_pwm_config == RT_NULL || obj -> hal_cfg == RT_NULL )
274374 {
275- LOG_W ("pwm obj %d not configured (skipped)" , i );
276375 continue ;
277376 }
278377
@@ -288,6 +387,7 @@ static int rt_hw_pwm_init(void)
288387 if (rt_device_pwm_register (& obj -> pwm_device , obj -> name , & drv_ops , obj ) == RT_EOK )
289388 {
290389 LOG_D ("%s register success" , obj -> name ? obj -> name : "ifx_pwm" );
390+ registered ++ ;
291391 }
292392 else
293393 {
@@ -296,6 +396,11 @@ static int rt_hw_pwm_init(void)
296396 }
297397 }
298398
399+ if (registered == 0 )
400+ {
401+ LOG_W ("No PWM instances configured" );
402+ }
403+
299404__exit :
300405 return result ;
301406}
0 commit comments