@@ -35,8 +35,11 @@ typedef struct _machine_pwm_obj_t {
35
35
pyb_pin_obj_t * pin ;
36
36
uint8_t active ;
37
37
uint8_t channel ;
38
+ int32_t duty_ns ;
38
39
} machine_pwm_obj_t ;
39
40
41
+ STATIC void mp_machine_pwm_duty_set_ns (machine_pwm_obj_t * self , mp_int_t duty );
42
+
40
43
STATIC bool pwm_inited = false;
41
44
42
45
/******************************************************************************/
@@ -53,10 +56,12 @@ STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_p
53
56
}
54
57
55
58
STATIC void mp_machine_pwm_init_helper (machine_pwm_obj_t * self , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
56
- enum { ARG_freq , ARG_duty };
59
+ enum { ARG_freq , ARG_duty , ARG_duty_u16 , ARG_duty_ns };
57
60
static const mp_arg_t allowed_args [] = {
58
61
{ MP_QSTR_freq , MP_ARG_INT , {.u_int = -1 } },
59
62
{ MP_QSTR_duty , MP_ARG_INT , {.u_int = -1 } },
63
+ { MP_QSTR_duty_u16 , MP_ARG_INT , {.u_int = -1 } },
64
+ { MP_QSTR_duty_ns , MP_ARG_INT , {.u_int = -1 } },
60
65
};
61
66
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
62
67
mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
@@ -74,6 +79,15 @@ STATIC void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, c
74
79
if (args [ARG_duty ].u_int != -1 ) {
75
80
pwm_set_duty (args [ARG_duty ].u_int , self -> channel );
76
81
}
82
+ if (args [ARG_duty_u16 ].u_int != -1 ) {
83
+ pwm_set_duty (args [ARG_duty_u16 ].u_int * 1000 / 65536 , self -> channel );
84
+ }
85
+ if (args [ARG_duty_ns ].u_int != -1 ) {
86
+ uint32_t freq = pwm_get_freq (0 );
87
+ if (freq > 0 ) {
88
+ pwm_set_duty ((uint64_t )args [ARG_duty_ns ].u_int * freq / 1000000 , self -> channel );
89
+ }
90
+ }
77
91
78
92
if (pin_mode [self -> pin -> phys_port ] == GPIO_MODE_OPEN_DRAIN ) {
79
93
mp_hal_pin_open_drain (self -> pin -> phys_port );
@@ -91,6 +105,7 @@ STATIC mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args
91
105
self -> pin = pin ;
92
106
self -> active = 0 ;
93
107
self -> channel = -1 ;
108
+ self -> duty_ns = -1 ;
94
109
95
110
// start the PWM subsystem if it's not already running
96
111
if (!pwm_inited ) {
@@ -118,26 +133,57 @@ STATIC mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
118
133
119
134
STATIC void mp_machine_pwm_freq_set (machine_pwm_obj_t * self , mp_int_t freq ) {
120
135
pwm_set_freq (freq , 0 );
121
- pwm_start ();
136
+ if (self -> duty_ns != -1 ) {
137
+ mp_machine_pwm_duty_set_ns (self , self -> duty_ns );
138
+ } else {
139
+ pwm_start ();
140
+ }
122
141
}
123
142
124
- STATIC mp_obj_t mp_machine_pwm_duty_get (machine_pwm_obj_t * self ) {
143
+ STATIC void set_active (machine_pwm_obj_t * self , bool set_pin ) {
125
144
if (!self -> active ) {
126
145
pwm_add (self -> pin -> phys_port , self -> pin -> periph , self -> pin -> func );
127
146
self -> active = 1 ;
128
-
129
- if (pin_mode [self -> pin -> phys_port ] == GPIO_MODE_OPEN_DRAIN ) {
147
+ if (set_pin && pin_mode [self -> pin -> phys_port ] == GPIO_MODE_OPEN_DRAIN ) {
130
148
mp_hal_pin_open_drain (self -> pin -> phys_port );
131
149
}
132
150
}
151
+ }
152
+
153
+ STATIC mp_obj_t mp_machine_pwm_duty_get (machine_pwm_obj_t * self ) {
154
+ set_active (self , true);
133
155
return MP_OBJ_NEW_SMALL_INT (pwm_get_duty (self -> channel ));
134
156
}
135
157
136
158
STATIC void mp_machine_pwm_duty_set (machine_pwm_obj_t * self , mp_int_t duty ) {
137
- if (!self -> active ) {
138
- pwm_add (self -> pin -> phys_port , self -> pin -> periph , self -> pin -> func );
139
- self -> active = 1 ;
140
- }
159
+ set_active (self , false);
160
+ self -> duty_ns = -1 ;
141
161
pwm_set_duty (duty , self -> channel );
142
162
pwm_start ();
143
163
}
164
+
165
+ STATIC mp_obj_t mp_machine_pwm_duty_get_u16 (machine_pwm_obj_t * self ) {
166
+ set_active (self , true);
167
+ return MP_OBJ_NEW_SMALL_INT (pwm_get_duty (self -> channel ) * 65536 / 1024 );
168
+ }
169
+
170
+ STATIC void mp_machine_pwm_duty_set_u16 (machine_pwm_obj_t * self , mp_int_t duty ) {
171
+ set_active (self , false);
172
+ self -> duty_ns = -1 ;
173
+ pwm_set_duty (duty * 1024 / 65536 , self -> channel );
174
+ pwm_start ();
175
+ }
176
+
177
+ STATIC mp_obj_t mp_machine_pwm_duty_get_ns (machine_pwm_obj_t * self ) {
178
+ set_active (self , true);
179
+ uint32_t freq = pwm_get_freq (0 );
180
+ return MP_OBJ_NEW_SMALL_INT (pwm_get_duty (self -> channel ) * 976563 / freq );
181
+ }
182
+
183
+ STATIC void mp_machine_pwm_duty_set_ns (machine_pwm_obj_t * self , mp_int_t duty ) {
184
+ set_active (self , false);
185
+ self -> duty_ns = duty ;
186
+ uint32_t freq = pwm_get_freq (0 );
187
+ pwm_set_duty (duty * freq / 976562 , self -> channel ); // 1e9/1024 = 976562.5
188
+ pwm_start ();
189
+ }
0 commit comments