@@ -22,34 +22,66 @@ 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+ {
33+ .tcpwm_pwm_config = RT_NULL ,
34+ .hal_cfg = RT_NULL ,
35+ .name = RT_NULL ,
36+ }
4137};
4238
4339
4440#ifndef IFX_PWM_MAX_TICKS
4541#define IFX_PWM_MAX_TICKS 65535U
4642#endif
4743
44+ #ifndef IFX_PWM_DEFAULT_CHANNEL
45+ #define IFX_PWM_DEFAULT_CHANNEL 1U
46+ #endif
47+
48+ static inline TCPWM_Type * ifx_pwm_get_base (struct ifx_pwm * pwm )
49+ {
50+ if ((pwm == RT_NULL ) || (pwm -> hal_cfg == RT_NULL ))
51+ return RT_NULL ;
52+
53+ return pwm -> hal_cfg -> base ;
54+ }
55+
56+ static inline uint32_t ifx_pwm_get_cntnum (struct ifx_pwm * pwm )
57+ {
58+ if ((pwm == RT_NULL ) || (pwm -> hal_cfg == RT_NULL ))
59+ return 0U ;
60+
61+ return pwm -> hal_cfg -> cntnum ;
62+ }
63+
64+ static inline const mtb_hal_peri_div_t * ifx_pwm_get_clock_ref (struct ifx_pwm * pwm )
65+ {
66+ if ((pwm == RT_NULL ) || (pwm -> hal_cfg == RT_NULL ) ||
67+ (pwm -> hal_cfg -> clock == RT_NULL ) || (pwm -> hal_cfg -> clock -> clock_ref == RT_NULL ))
68+ {
69+ return RT_NULL ;
70+ }
71+
72+ return (const mtb_hal_peri_div_t * )pwm -> hal_cfg -> clock -> clock_ref ;
73+ }
74+
4875static inline uint32_t ifx_pwm_get_clock (struct ifx_pwm * pwm )
4976{
50- return Cy_SysClk_PeriPclkGetFrequency ((en_clk_dst_t )pwm -> clk_dst ,
51- pwm -> clk_divType ,
52- pwm -> clk_divNum );
77+ const mtb_hal_peri_div_t * clock_ref = ifx_pwm_get_clock_ref (pwm );
78+
79+ if (clock_ref == RT_NULL )
80+ return 0U ;
81+
82+ return Cy_SysClk_PeriPclkGetFrequency ((en_clk_dst_t )clock_ref -> clk_dst ,
83+ clock_ref -> div_type ,
84+ clock_ref -> div_num );
5385}
5486
5587static inline int ifx_pwm_check_clk (struct ifx_pwm * pwm , uint32_t * clk )
@@ -63,6 +95,24 @@ static inline int ifx_pwm_check_clk(struct ifx_pwm *pwm, uint32_t *clk)
6395 return RT_EOK ;
6496}
6597
98+ static inline rt_err_t ifx_pwm_check_cfg (struct ifx_pwm * pwm , const struct rt_pwm_configuration * cfg )
99+ {
100+ if (!pwm || ifx_pwm_get_base (pwm ) == RT_NULL )
101+ return - RT_ERROR ;
102+
103+ if (cfg == RT_NULL )
104+ return - RT_EINVAL ;
105+
106+ /* Single-channel PWM devices keep compatibility with channel 0 and default channel(1). */
107+ if ((cfg -> channel != 0U ) && (cfg -> channel != IFX_PWM_DEFAULT_CHANNEL ))
108+ {
109+ LOG_E ("%s: unsupported channel %u" , pwm -> name ? pwm -> name : "ifx_pwm" , cfg -> channel );
110+ return - RT_EINVAL ;
111+ }
112+
113+ return RT_EOK ;
114+ }
115+
66116static inline uint64_t ns_to_ticks (uint64_t ns , uint32_t clk )
67117{
68118 if (clk == 0U )
@@ -79,20 +129,25 @@ static inline uint64_t ns_to_ticks(uint64_t ns, uint32_t clk)
79129static rt_err_t drv_pwm_enable (struct rt_device_pwm * device , struct rt_pwm_configuration * configuration , rt_bool_t enable )
80130{
81131 struct ifx_pwm * pwm = (struct ifx_pwm * )device -> parent .user_data ;
132+ rt_err_t ret ;
133+ TCPWM_Type * base ;
134+ uint32_t cntNum ;
82135
83- (void )configuration ;
136+ ret = ifx_pwm_check_cfg (pwm , configuration );
137+ if (ret != RT_EOK )
138+ return ret ;
84139
85- if (! pwm || pwm -> base == RT_NULL )
86- return - RT_ERROR ;
140+ base = ifx_pwm_get_base ( pwm );
141+ cntNum = ifx_pwm_get_cntnum ( pwm ) ;
87142
88143 if (!enable )
89144 {
90- Cy_TCPWM_PWM_Disable (pwm -> base , pwm -> cntNum );
145+ Cy_TCPWM_PWM_Disable (base , cntNum );
91146 }
92147 else
93148 {
94- Cy_TCPWM_PWM_Enable (pwm -> base , pwm -> cntNum );
95- Cy_TCPWM_TriggerStart_Single (pwm -> base , pwm -> cntNum );
149+ Cy_TCPWM_PWM_Enable (base , cntNum );
150+ Cy_TCPWM_TriggerStart_Single (base , cntNum );
96151 }
97152
98153 return RT_EOK ;
@@ -101,10 +156,20 @@ static rt_err_t drv_pwm_enable(struct rt_device_pwm *device, struct rt_pwm_confi
101156static rt_err_t drv_pwm_set_period (struct ifx_pwm * pwm , struct rt_pwm_configuration * configuration )
102157{
103158 uint32_t clk ;
159+ uint32_t cntNum ;
160+ TCPWM_Type * base ;
161+ rt_err_t ret ;
162+
163+ ret = ifx_pwm_check_cfg (pwm , configuration );
164+ if (ret != RT_EOK )
165+ return ret ;
104166
105167 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
106168 return - RT_ERROR ;
107169
170+ base = ifx_pwm_get_base (pwm );
171+ cntNum = ifx_pwm_get_cntnum (pwm );
172+
108173 uint64_t period_ns = configuration -> period ;
109174 uint64_t ticks = ns_to_ticks (period_ns , clk );
110175
@@ -120,22 +185,32 @@ static rt_err_t drv_pwm_set_period(struct ifx_pwm *pwm, struct rt_pwm_configurat
120185 if (ticks > IFX_PWM_MAX_TICKS )
121186 ticks = IFX_PWM_MAX_TICKS ;
122187
123- Cy_TCPWM_PWM_SetPeriod0 (pwm -> base , pwm -> cntNum , (uint32_t )ticks );
188+ Cy_TCPWM_PWM_SetPeriod0 (base , cntNum , (uint32_t )ticks );
124189
125190 return RT_EOK ;
126191}
127192
128193static rt_err_t drv_pwm_set_pulse (struct ifx_pwm * pwm , struct rt_pwm_configuration * configuration )
129194{
130195 uint32_t clk ;
196+ uint32_t cntNum ;
197+ TCPWM_Type * base ;
198+ rt_err_t ret ;
199+
200+ ret = ifx_pwm_check_cfg (pwm , configuration );
201+ if (ret != RT_EOK )
202+ return ret ;
131203
132204 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
133205 return - RT_ERROR ;
134206
207+ base = ifx_pwm_get_base (pwm );
208+ cntNum = ifx_pwm_get_cntnum (pwm );
209+
135210 uint64_t pulse_ns = configuration -> pulse ;
136211 uint64_t ticks = ns_to_ticks (pulse_ns , clk );
137212
138- uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (pwm -> base , pwm -> cntNum );
213+ uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (base , cntNum );
139214
140215 if (period_ticks == 0 )
141216 {
@@ -148,7 +223,7 @@ static rt_err_t drv_pwm_set_pulse(struct ifx_pwm *pwm, struct rt_pwm_configurati
148223 ticks = period_ticks ;
149224 }
150225
151- Cy_TCPWM_PWM_SetCompare0Val (pwm -> base , pwm -> cntNum , (uint32_t )ticks );
226+ Cy_TCPWM_PWM_SetCompare0Val (base , cntNum , (uint32_t )ticks );
152227
153228 return RT_EOK ;
154229}
@@ -157,10 +232,20 @@ static rt_err_t drv_pwm_set(struct rt_device_pwm *device, struct rt_pwm_configur
157232{
158233 struct ifx_pwm * pwm = (struct ifx_pwm * )device -> parent .user_data ;
159234 uint32_t clk ;
235+ uint32_t cntNum ;
236+ TCPWM_Type * base ;
237+ rt_err_t ret ;
238+
239+ ret = ifx_pwm_check_cfg (pwm , configuration );
240+ if (ret != RT_EOK )
241+ return ret ;
160242
161243 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
162244 return - RT_ERROR ;
163245
246+ base = ifx_pwm_get_base (pwm );
247+ cntNum = ifx_pwm_get_cntnum (pwm );
248+
164249 uint64_t period_ticks = ns_to_ticks (configuration -> period , clk );
165250 uint64_t pulse_ticks = ns_to_ticks (configuration -> pulse , clk );
166251
@@ -179,8 +264,8 @@ static rt_err_t drv_pwm_set(struct rt_device_pwm *device, struct rt_pwm_configur
179264 if (period_ticks > IFX_PWM_MAX_TICKS )
180265 period_ticks = IFX_PWM_MAX_TICKS ;
181266
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 );
267+ Cy_TCPWM_PWM_SetPeriod0 (base , cntNum , (uint32_t )period_ticks );
268+ Cy_TCPWM_PWM_SetCompare0Val (base , cntNum , (uint32_t )pulse_ticks );
184269
185270 return RT_EOK ;
186271}
@@ -189,12 +274,22 @@ static rt_err_t drv_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configur
189274{
190275 struct ifx_pwm * pwm = (struct ifx_pwm * )device -> parent .user_data ;
191276 uint32_t clk ;
277+ uint32_t cntNum ;
278+ TCPWM_Type * base ;
279+ rt_err_t ret ;
280+
281+ ret = ifx_pwm_check_cfg (pwm , configuration );
282+ if (ret != RT_EOK )
283+ return ret ;
192284
193285 if (ifx_pwm_check_clk (pwm , & clk ) != RT_EOK )
194286 return - RT_ERROR ;
195287
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 );
288+ base = ifx_pwm_get_base (pwm );
289+ cntNum = ifx_pwm_get_cntnum (pwm );
290+
291+ uint32_t period_ticks = Cy_TCPWM_PWM_GetPeriod0 (base , cntNum );
292+ uint32_t cmp_ticks = Cy_TCPWM_PWM_GetCompare0Val (base , cntNum );
198293
199294 configuration -> period = (uint64_t )period_ticks * 1000000000ULL / (uint64_t )clk ;
200295 configuration -> pulse = (uint64_t )cmp_ticks * 1000000000ULL / (uint64_t )clk ;
@@ -206,6 +301,14 @@ static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg
206301{
207302 struct rt_pwm_configuration * configuration = (struct rt_pwm_configuration * )arg ;
208303
304+ if ((cmd == PWM_CMD_ENABLE ) || (cmd == PWM_CMD_DISABLE ) ||
305+ (cmd == PWM_CMD_SET ) || (cmd == PWM_CMD_GET ) ||
306+ (cmd == PWM_CMD_SET_PERIOD ) || (cmd == PWM_CMD_SET_PULSE ))
307+ {
308+ if (configuration == RT_NULL )
309+ return - RT_EINVAL ;
310+ }
311+
209312 switch (cmd )
210313 {
211314 case PWM_CMD_ENABLE :
@@ -236,16 +339,22 @@ static struct rt_pwm_ops drv_ops = { drv_pwm_control };
236339static rt_err_t ifx_hw_pwm_init (struct ifx_pwm * device )
237340{
238341 cy_en_tcpwm_status_t tcpwm_status ;
342+ TCPWM_Type * base ;
343+ uint32_t cntNum ;
344+
239345 RT_ASSERT (device != RT_NULL );
240346
241- if (!device -> tcpwm_pwm_config || !device -> base )
347+ if (!device -> tcpwm_pwm_config || !device -> hal_cfg )
242348 {
243349 LOG_W ("%s: tcpwm config or base missing" , device -> name ? device -> name : "ifx_pwm" );
244350 return - RT_ERROR ;
245351 }
246352
247- tcpwm_status = Cy_TCPWM_PWM_Init (device -> base , device -> cntNum , device -> tcpwm_pwm_config );
248- if (CY_RSLT_SUCCESS != tcpwm_status )
353+ base = ifx_pwm_get_base (device );
354+ cntNum = ifx_pwm_get_cntnum (device );
355+
356+ tcpwm_status = Cy_TCPWM_PWM_Init (base , cntNum , device -> tcpwm_pwm_config );
357+ if (CY_TCPWM_SUCCESS != tcpwm_status )
249358 {
250359 LOG_E ("%s: Initialize the TCPWM block failed" , device -> name ? device -> name : "ifx_pwm" );
251360 return - RT_ERROR ;
@@ -259,20 +368,14 @@ static int rt_hw_pwm_init(void)
259368 int i ;
260369 int result = RT_EOK ;
261370 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- }
371+ int registered = 0 ;
268372
269373 for (i = 0 ; i < count ; i ++ )
270374 {
271375 struct ifx_pwm * obj = & ifx_pwm_obj [i ];
272376
273- if (obj -> tcpwm_pwm_config == RT_NULL || obj -> base == RT_NULL )
377+ if (obj -> tcpwm_pwm_config == RT_NULL || obj -> hal_cfg == RT_NULL )
274378 {
275- LOG_W ("pwm obj %d not configured (skipped)" , i );
276379 continue ;
277380 }
278381
@@ -288,6 +391,7 @@ static int rt_hw_pwm_init(void)
288391 if (rt_device_pwm_register (& obj -> pwm_device , obj -> name , & drv_ops , obj ) == RT_EOK )
289392 {
290393 LOG_D ("%s register success" , obj -> name ? obj -> name : "ifx_pwm" );
394+ registered ++ ;
291395 }
292396 else
293397 {
@@ -296,6 +400,11 @@ static int rt_hw_pwm_init(void)
296400 }
297401 }
298402
403+ if (registered == 0 )
404+ {
405+ LOG_W ("No PWM instances configured" );
406+ }
407+
299408__exit :
300409 return result ;
301410}
0 commit comments