Skip to content

Commit 12e38c1

Browse files
committed
Implemented GPIO MP support for Encoder wheel
1 parent 653090c commit 12e38c1

File tree

4 files changed

+77
-14
lines changed

4 files changed

+77
-14
lines changed

drivers/ioexpander/ioexpander.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ namespace pimoroni {
2727
static const uint8_t PIN_MODE_ADC = 0b01010; // ADC, Input-only (high-impedance)
2828

2929
static const uint32_t RESET_TIMEOUT_MS = 1000;
30-
static const uint32_t CLOCK_FREQ = 24000000;
31-
static const uint32_t MAX_PERIOD = (1 << 16) - 1;
32-
static const uint32_t MAX_DIVIDER = (1 << 7);
3330

3431
public:
3532
static const uint8_t DEFAULT_I2C_ADDRESS = 0x18;
@@ -50,6 +47,10 @@ namespace pimoroni {
5047
static const uint16_t LOW = 0;
5148
static const uint16_t HIGH = 1;
5249

50+
static const uint32_t CLOCK_FREQ = 24000000;
51+
static const uint32_t MAX_PERIOD = (1 << 16) - 1;
52+
static const uint32_t MAX_DIVIDER = (1 << 7);
53+
5354

5455
//--------------------------------------------------
5556
// Subclasses

libraries/breakout_encoder_wheel/breakout_encoder_wheel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ namespace encoderwheel {
219219
ioe.pwm_load(wait_for_load);
220220
}
221221

222-
int BreakoutEncoderWheel::gpio_pwm_frequency(float frequency, bool load, bool wait_for_load) {
222+
uint16_t BreakoutEncoderWheel::gpio_pwm_frequency(float frequency, bool load, bool wait_for_load) {
223223
return ioe.set_pwm_frequency(frequency, load, wait_for_load);
224224
}
225225

libraries/breakout_encoder_wheel/breakout_encoder_wheel.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ namespace encoderwheel {
152152
float gpio_pin_value_as_voltage(uint8_t gpio);
153153
void gpio_pin_value(uint8_t gpio, uint16_t value, bool load = true, bool wait_for_load = false);
154154
void gpio_pwm_load(bool wait_for_load = true);
155-
int gpio_pwm_frequency(float frequency, bool load = true, bool wait_for_load = false);
155+
uint16_t gpio_pwm_frequency(float frequency, bool load = true, bool wait_for_load = false);
156156

157157
private:
158158
void take_encoder_reading();

micropython/modules/breakout_encoder_wheel/breakout_encoder_wheel.cpp

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,22 +244,77 @@ extern mp_obj_t BreakoutEncoderWheel_show(mp_obj_t self_in) {
244244
}
245245

246246
extern mp_obj_t BreakoutEncoderWheel_gpio_pin_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
247-
//breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
247+
enum { ARG_self, ARG_gpio, ARG_mode };
248+
static const mp_arg_t allowed_args[] = {
249+
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
250+
{ MP_QSTR_gpio, MP_ARG_REQUIRED | MP_ARG_INT },
251+
{ MP_QSTR_mode, MP_ARG_OBJ, { .u_obj = mp_const_none }},
252+
};
248253

249-
return mp_const_none;
254+
// Parse args.
255+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
256+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
257+
258+
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
259+
int gpio = args[ARG_gpio].u_int;
260+
if(gpio < 7 || gpio > 9) {
261+
mp_raise_ValueError("gpio out of range. Expected GP7 (7), GP8 (8), or GP9 (9)");
262+
}
263+
264+
if(args[ARG_mode].u_obj == mp_const_none) {
265+
return mp_obj_new_int(self->breakout->gpio_pin_mode(gpio));
266+
}
267+
else {
268+
int mode = mp_obj_get_int(args[ARG_mode].u_obj);
269+
self->breakout->gpio_pin_mode(gpio, mode);
270+
271+
return mp_const_none;
272+
}
250273
}
251274

252275
extern mp_obj_t BreakoutEncoderWheel_gpio_pin_value(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
253-
//breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(self_in, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
276+
enum { ARG_self, ARG_gpio, ARG_value, ARG_load, ARG_wait_for_load };
277+
static const mp_arg_t allowed_args[] = {
278+
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
279+
{ MP_QSTR_gpio, MP_ARG_REQUIRED | MP_ARG_INT },
280+
{ MP_QSTR_value, MP_ARG_OBJ, { .u_obj = mp_const_none }},
281+
{ MP_QSTR_load, MP_ARG_BOOL, { .u_bool = true }},
282+
{ MP_QSTR_wait_for_load, MP_ARG_BOOL, { .u_bool = false }},
283+
};
254284

255-
return mp_const_none;
285+
// Parse args.
286+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
287+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
288+
289+
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
290+
int gpio = args[ARG_gpio].u_int;
291+
if(gpio < 7 || gpio > 9) {
292+
mp_raise_ValueError("gpio out of range. Expected GP7 (7), GP8 (8), or GP9 (9)");
293+
}
294+
295+
if(args[ARG_value].u_obj == mp_const_none) {
296+
if(self->breakout->gpio_pin_mode(gpio) == IOExpander::PIN_ADC) {
297+
return mp_obj_new_float(self->breakout->gpio_pin_value_as_voltage(gpio));
298+
}
299+
else {
300+
return mp_obj_new_int(self->breakout->gpio_pin_value(gpio));
301+
}
302+
}
303+
else {
304+
int value = mp_obj_get_int(args[ARG_value].u_obj);
305+
bool load = args[ARG_load].u_bool;
306+
bool wait_for_load = args[ARG_wait_for_load].u_bool;
307+
self->breakout->gpio_pin_value(gpio, value, load, wait_for_load);
308+
309+
return mp_const_none;
310+
}
256311
}
257312

258313
extern mp_obj_t BreakoutEncoderWheel_gpio_pwm_load(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
259314
enum { ARG_self, ARG_wait_for_load };
260315
static const mp_arg_t allowed_args[] = {
261316
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
262-
{ MP_QSTR_wait_for_load, MP_ARG_BOOL, { .u_bool = false }},
317+
{ MP_QSTR_wait_for_load, MP_ARG_BOOL, { .u_bool = true }},
263318
};
264319

265320
// Parse args.
@@ -279,8 +334,8 @@ extern mp_obj_t BreakoutEncoderWheel_gpio_pwm_frequency(size_t n_args, const mp_
279334
static const mp_arg_t allowed_args[] = {
280335
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
281336
{ MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_OBJ },
282-
{ MP_QSTR_load, MP_ARG_BOOL, { .u_bool = false }},
283-
{ MP_QSTR_wait_for_load, MP_ARG_BOOL, { .u_bool = false }},
337+
{ MP_QSTR_load, MP_ARG_BOOL, { .u_bool = true }},
338+
{ MP_QSTR_wait_for_load, MP_ARG_BOOL, { .u_bool = true }},
284339
};
285340

286341
// Parse args.
@@ -289,10 +344,17 @@ extern mp_obj_t BreakoutEncoderWheel_gpio_pwm_frequency(size_t n_args, const mp_
289344

290345
breakout_encoder_wheel_BreakoutEncoderWheel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_encoder_wheel_BreakoutEncoderWheel_obj_t);
291346
float frequency = mp_obj_get_float(args[ARG_frequency].u_obj);
347+
uint32_t period = (uint32_t)(IOExpander::CLOCK_FREQ / frequency);
348+
if (period / 128 > IOExpander::MAX_PERIOD) {
349+
mp_raise_ValueError("The provided frequency is too low");
350+
}
351+
if (period < 2) {
352+
mp_raise_ValueError("The provided frequency is too high");
353+
}
354+
292355
bool load = args[ARG_load].u_bool;
293356
bool wait_for_load = args[ARG_wait_for_load].u_bool;
294-
295-
int period = self->breakout->gpio_pwm_frequency(frequency, load, wait_for_load);
357+
period = self->breakout->gpio_pwm_frequency(frequency, load, wait_for_load);
296358

297359
return mp_obj_new_int(period);
298360
}

0 commit comments

Comments
 (0)