Skip to content

Commit 0762b68

Browse files
committed
新增多路pwm驱动+配置
1 parent d64c05d commit 0762b68

29 files changed

Lines changed: 5399 additions & 4930 deletions

libraries/HAL_Drivers/drv_pwm.c

Lines changed: 143 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3429
static 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+
4871
static 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

5583
static 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+
66112
static 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)
79125
static 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
101152
static 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

128189
static 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 };
236335
static 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
}

libraries/HAL_Drivers/drv_pwm.h

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,46 @@
1818
extern "C" {
1919
#endif
2020

21+
#define IFX_PWM_DEVICE(_cfg, _hal_cfg, _name) \
22+
{ \
23+
.tcpwm_pwm_config = &(_cfg), \
24+
.hal_cfg = &(_hal_cfg), \
25+
.name = (_name), \
26+
},
27+
28+
#ifdef BSP_USING_PWM5
29+
#define IFX_PWM_DEVICE_ITEM_PWM5 \
30+
IFX_PWM_DEVICE(tcpwm_0_group_0_cnt_5_config, tcpwm_0_group_0_cnt_5_hal_config, "pwm5")
31+
#else
32+
#define IFX_PWM_DEVICE_ITEM_PWM5
33+
#endif
34+
35+
#ifdef BSP_USING_PWM6
36+
#define IFX_PWM_DEVICE_ITEM_PWM6 \
37+
IFX_PWM_DEVICE(tcpwm_0_group_0_cnt_6_config, tcpwm_0_group_0_cnt_6_hal_config, "pwm6")
38+
#else
39+
#define IFX_PWM_DEVICE_ITEM_PWM6
40+
#endif
41+
2142
#ifdef BSP_USING_PWM18
43+
#define IFX_PWM_DEVICE_ITEM_PWM18 \
44+
IFX_PWM_DEVICE(tcpwm_0_group_1_cnt_9_config, tcpwm_0_group_1_cnt_9_hal_config, "pwm18")
45+
#else
46+
#define IFX_PWM_DEVICE_ITEM_PWM18
47+
#endif
2248

23-
#ifndef TCPWM_0_GRP_1_PWM_9_CONFIG
24-
#define TCPWM_0_GRP_1_PWM_9_CONFIG \
25-
{ \
26-
.tcpwm_pwm_config = &tcpwm_0_group_1_cnt_9_config,\
27-
.base = TCPWM0,\
28-
.cntNum = 265UL,\
29-
.name = "pwm18",\
30-
.clk_dst = PERI_0_GROUP_1_DIV_8_4_GRP_NUM,\
31-
.clk_divType = CY_SYSCLK_DIV_8_BIT,\
32-
.clk_divNum = 4U,\
33-
}
34-
#endif /* TCPWM_0_GRP_1_PWM_9_CONFIG */
49+
#ifdef BSP_USING_PWM13
50+
#define IFX_PWM_DEVICE_ITEM_PWM13 \
51+
IFX_PWM_DEVICE(tcpwm_0_group_1_cnt_13_config, tcpwm_0_group_1_cnt_13_hal_config, "pwm13")
52+
#else
53+
#define IFX_PWM_DEVICE_ITEM_PWM13
54+
#endif
3555

36-
#endif /* BSP_USING_PWM18 */
56+
#define IFX_PWM_DEVICE_LIST \
57+
IFX_PWM_DEVICE_ITEM_PWM5 \
58+
IFX_PWM_DEVICE_ITEM_PWM6 \
59+
IFX_PWM_DEVICE_ITEM_PWM18 \
60+
IFX_PWM_DEVICE_ITEM_PWM13
3761

3862
#ifdef __cplusplus
3963
}

0 commit comments

Comments
 (0)