45
45
typedef struct _machine_pwm_obj_t {
46
46
mp_obj_base_t base ;
47
47
PWM_Type * instance ;
48
+ const machine_pin_obj_t * pwm_pin ;
49
+ const machine_pin_af_obj_t * pwm_pin_af_obj ;
48
50
bool is_flexpwm ;
49
51
uint8_t complementary ;
50
52
uint8_t module ;
@@ -255,6 +257,8 @@ static void configure_flexpwm(machine_pwm_obj_t *self) {
255
257
PWM_SetupFaultDisableMap (self -> instance , self -> submodule , self -> channel2 , kPWM_faultchannel_1 , 0 );
256
258
}
257
259
260
+ // clear the load okay bit for the submodules in case there is a pending load
261
+ PWM_SetPwmLdok (self -> instance , 1 << self -> submodule , false);
258
262
if (self -> channel1 != kPWM_PwmX ) { // Only for A/B channels
259
263
// Initialize the channel parameters
260
264
pwmSignal .pwmChannel = self -> channel1 ;
@@ -283,6 +287,17 @@ static void configure_flexpwm(machine_pwm_obj_t *self) {
283
287
self -> instance -> SM [self -> submodule ].CTRL &= ~(PWM_CTRL_DBLEN_MASK | PWM_CTRL_SPLIT_MASK );
284
288
}
285
289
} else {
290
+ if (self -> duty_u16 == 0 ) {
291
+ // For duty_u16 == 0 just set the output to GPIO mode
292
+ if (self -> invert ) {
293
+ mp_hal_pin_high (self -> pwm_pin );
294
+ } else {
295
+ mp_hal_pin_low (self -> pwm_pin );
296
+ }
297
+ IOMUXC_SetPinMux (self -> pwm_pin -> muxRegister , PIN_AF_MODE_ALT5 , 0 , 0 , 0 , 0U );
298
+ } else {
299
+ IOMUXC_SetPinMux (self -> pwm_pin -> muxRegister , self -> pwm_pin_af_obj -> af_mode , 0 , 0 , 0 , 0U );
300
+ }
286
301
PWM_SetupPwmx_u16 (self -> instance , self -> submodule , self -> freq , self -> duty_u16 ,
287
302
self -> invert , pwmSourceClockInHz );
288
303
if (self -> xor ) {
@@ -408,12 +423,16 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self,
408
423
}
409
424
self -> center = center ;
410
425
} else { // Use alignment setting shortcut
411
- if (args [ARG_align ].u_int >= 0 ) {
426
+ uint32_t duty = self -> duty_u16 ;
427
+ if (duty == VALUE_NOT_SET && self -> duty_ns != VALUE_NOT_SET ) {
428
+ duty = duty_ns_to_duty_u16 (self -> freq , self -> duty_ns );
429
+ }
430
+ if (args [ARG_align ].u_int >= 0 && duty != VALUE_NOT_SET && self -> freq != VALUE_NOT_SET ) {
412
431
uint8_t align = args [ARG_align ].u_int & 3 ; // limit to 0..3
413
432
if (align == PWM_BEGIN ) {
414
- self -> center = self -> duty_u16 / 2 ;
433
+ self -> center = duty / 2 ;
415
434
} else if (align == PWM_END ) {
416
- self -> center = PWM_FULL_SCALE - self -> duty_u16 / 2 ;
435
+ self -> center = PWM_FULL_SCALE - duty / 2 ;
417
436
} else {
418
437
self -> center = 32768 ; // Default value: mid.
419
438
}
@@ -515,6 +534,8 @@ static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
515
534
516
535
// Create and populate the PWM object.
517
536
machine_pwm_obj_t * self = mp_obj_malloc (machine_pwm_obj_t , & machine_pwm_type );
537
+ self -> pwm_pin = pin1 ;
538
+ self -> pwm_pin_af_obj = af_obj1 ;
518
539
self -> is_flexpwm = is_flexpwm ;
519
540
self -> instance = af_obj1 -> instance ;
520
541
self -> module = module ;
@@ -534,6 +555,8 @@ static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
534
555
535
556
// Initialize the Pin(s).
536
557
CLOCK_EnableClock (kCLOCK_Iomuxc ); // just in case it was not set yet
558
+ // Configure PWMX channels to pin output mode to be prepared for duty_u16 == 0.
559
+ mp_hal_pin_output (pin1 );
537
560
IOMUXC_SetPinMux (pin1 -> muxRegister , af_obj1 -> af_mode , af_obj1 -> input_register , af_obj1 -> input_daisy ,
538
561
pin1 -> configRegister , 0U );
539
562
IOMUXC_SetPinConfig (pin1 -> muxRegister , af_obj1 -> af_mode , af_obj1 -> input_register , af_obj1 -> input_daisy ,
0 commit comments