8000 ports/psoc6/machine_pwm.c: Clean up refactor and fixes on arithmetic. · micropython/micropython@fe81830 · GitHub
[go: up one dir, main page]

Skip to content

Commit fe81830

Browse files
committed
ports/psoc6/machine_pwm.c: Clean up refactor and fixes on arithmetic.
Signed-off-by: enriquezgarc <enriquezgarcia.external@infineon.com>
1 parent 3159ab8 commit fe81830

File tree

1 file changed

+50
-29
lines changed

1 file changed

+50
-29
lines changed

ports/psoc6/machine_pwm.c

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
#include "machine_pin_phy.h"
3333
#include "mplogger.h"
3434

35+
#define pwm_assert_raise_val(msg, ret) if (ret != CY_RSLT_SUCCESS) { \
36+
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT(msg), ret); \
37+
}
38+
3539
typedef struct _machine_pwm_obj_t {
3640
mp_obj_base_t base;
3741
cyhal_pwm_t pwm_obj;
@@ -69,14 +73,35 @@ enum {
6973
DUTY_NS
7074
};
7175

72-
static void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq);
76+
/* Unit conversion macros */
77+
#define pwm_duty_cycle_ns_to_u16(duty_ns, fz) ((int)(((float)(duty_ns * fz) / (float)1000000000) * (float)65536) - 1)
78+
#define pwm_duty_cycle_u16_to_ns(duty_u16, fz) ((int)(((float)(duty_u16 + 1) / (float)65536) * ((float)1000000000 / (float)fz)))
79+
#define pwm_duty_cycle_u16_to_percent(duty_u16) ((float)((duty_u16) * 100) / (float)65535)
80+
#define pwm_freq_to_period_us(fz) ((uint32_t)(1000000 / fz))
81+
#define pwm_period_ns_to_us(period_ns) ((uint32_t)(period_ns / 1000))
82+
83+
static void pwm_duty_ns_assert(mp_int_t duty_ns, uint32_t fz) {
84+
if (duty_ns > (int)(1000000000 / fz)) {
85+
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("PWM duty in ns is larger than the period %d ns"), (int)(1000000000 / fz));
86+
}
87+
}
88+
89+
static inline void pwm_freq_duty_set(cyhal_pwm_t *pwm_obj, uint32_t fz, mp_int_t duty_cycle) {
90+
cy_rslt_t ret = cyhal_pwm_set_duty_cycle(pwm_obj, pwm_duty_cycle_u16_to_percent(duty_cycle), fz);
91+
pwm_assert_raise_val("PWM frequency and duty cycle set failed with return code %lx !", ret);
92+
}
7393

74-
static cy_rslt_t pwm_freq_duty_set(cyhal_pwm_t *pwm_obj, uint32_t fz, float duty_cycle) {
75-
return cyhal_pwm_set_duty_cycle(pwm_obj, duty_cycle * 100, fz); // duty_cycle in percentage
94+
static void pwm_duty_set_ns(cyhal_pwm_t *pwm_obj, uint32_t fz, uint32_t pulse_width) {
95+
cy_rslt_t ret = cyhal_pwm_set_period(pwm_obj, pwm_freq_to_period_us(fz), pwm_period_ns_to_us(pulse_width));
96+
pwm_assert_raise_val("PWM period set failed with return code %lx !", ret);
7697
}
7798

78-
static inline cy_rslt_t pwm_duty_set_ns(cyhal_pwm_t *pwm_obj, uint32_t fz, uint32_t pulse_width) {
79-
return cyhal_pwm_set_period(pwm_obj, 1000000 / fz, pulse_width / 1000);
99+
static void pwm_config(machine_pwm_obj_t *self) {
100+
if (self->duty_type == DUTY_U16) {
101+
pwm_freq_duty_set(&self->pwm_obj, self->fz, self->duty);
102+
} else {
103+
pwm_duty_set_ns(&self->pwm_obj, self->fz, self->duty);
104+
}
80105
}
81106

82107
static void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -111,19 +136,20 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
111136
}
112137

113138
if ((args[ARG_duty_u16].u_int != VALUE_NOT_SET)) {
114-
float val = (float)(args[ARG_duty_u16].u_int) / (float)65535;
115-
pwm_freq_duty_set(&self->pwm_obj, self->fz, val);
116-
self->duty = args[ARG_duty_u16].u_int;
139+
self->duty = args[ARG_duty_u16].u_int > 65535 ? 65535 : args[ARG_duty_u16].u_int;
117140
self->duty_type = DUTY_U16;
118141
} else if (args[ARG_duty_ns].u_int != VALUE_NOT_SET) {
119-
pwm_duty_set_ns(&self->pwm_obj, self->fz, args[ARG_duty_ns].u_int);
142+
pwm_duty_ns_assert(args[ARG_duty_ns].u_int, self->fz);
120143
self->duty = args[ARG_duty_ns].u_int;
121144
self->duty_type = DUTY_NS;
122145
} else {
123146
mp_raise_ValueError(MP_ERROR_TEXT("PWM duty should be specified in either ns or u16"));
124147
}
125148

126-
cyhal_pwm_start(&self->pwm_obj);
149+
pwm_config(self);
150+
151+
cy_rslt_t result = cyhal_pwm_start(&self->pwm_obj);
152+
pwm_assert_raise_val("PWM start failed with return code %lx !", result);
127153
}
128154

129155
static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
@@ -136,14 +162,9 @@ static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
136162
self->duty_type = DUTY_NOT_SET;
137163
self->fz = -1;
138164

139-
// Initialize PWM
140165
cy_rslt_t result = cyhal_pwm_init(&self->pwm_obj, self->pin, NULL);
141-
142-
// To check whether PWM init is successful
143-
if (result != CY_RSLT_SUCCESS) {
144-
assert_pin_phy_used(result);
145-
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("PWM initialisation failed with return code %lx !"), result);
146-
}
166+
assert_pin_phy_used(result);
167+
pwm_assert_raise_val("PWM initialisation failed with return code %lx !", result);
147168

148169
// Process the remaining parameters.
149170
mp_map_t kw_args;
@@ -154,16 +175,17 @@ static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
154175
}
155176

156177
static void mp_machine_pwm_deinit(machine_pwm_obj_t *self) {
157-
cyhal_pwm_stop(&self->pwm_obj);
178+
cy_rslt_t result = cyhal_pwm_stop(&self->pwm_obj);
179+
pwm_assert_raise_val("PWM stop failed with return code %lx !", result);
158180
cyhal_pwm_free(&self->pwm_obj);
159181
pwm_obj_free(self);
160182
}
341A
161183

162184
static mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) {
163185
if (self->duty_type == DUTY_NS) {
164-
return mp_obj_new_float(((self->duty) * (self->fz) * 65535) / 1000000000 - 1);
186+
return mp_obj_new_int(pwm_duty_cycle_ns_to_u16(self->duty, self->fz));
165187
} else {
166-
return mp_obj_new_float(self->duty);
188+
return mp_obj_new_int(self->duty);
167189
}
168190
}
169191

@@ -172,36 +194,35 @@ static void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u
172194
// Check the value is more than the max value
173195
self->duty = duty_u16 > 65535 ? 65535 : duty_u16;
174196
self->duty_type = DUTY_U16;
175-
pwm_freq_duty_set(&self->pwm_obj, self->fz, (float)(self->duty) / (float)65535); // s conversion of duty_u16 into dutyu16/65535
197+
pwm_config(self);
176198
}
177199

178200
static mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) {
179201
if (self->duty_type == DUTY_U16) {
180-
return mp_obj_new_float(((self->duty) * 1000000000) / ((self->fz) * 65535)); // pw (ns) = duty_cycle*10^9/fz
202+
return mp_obj_new_int(pwm_duty_cycle_u16_to_ns(self->duty, self->fz));
181203
} else {
182-
return mp_obj_new_float(self->duty);
204+
return mp_obj_new_int(self->duty);
183205
}
184206
}
185207

186208
// sets the pulse width in nanoseconds
187209
static void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) {
210+
pwm_duty_ns_assert(duty_ns, self->fz);
188211
self->duty = duty_ns;
189212
self->duty_type = DUTY_NS;
190-
pwm_duty_set_ns(&self->pwm_obj, self->fz, duty_ns);
213+
pwm_config(self);
191214
}
192215

193216
static mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
194217
return MP_OBJ_NEW_SMALL_INT(self->fz);
195-
196218
}
197219

198220
static void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) {
199-
self->fz = freq;
200-
pwm_freq_duty_set(&self->pwm_obj, freq, self->duty);
201221
if (self->duty_type == DUTY_NS) {
202-
self->duty = ((self->duty) * (self->fz) * 65535) / 1000000000;
203-
mp_machine_pwm_duty_set_ns(self, self->duty);
222+
pwm_duty_ns_assert(self->duty, freq);
204223
}
224+
self->fz = freq;
225+
pwm_config(self);
205226
}
206227

207228
void machine_pwm_deinit_all() {

0 commit comments

Comments
 (0)
0