Skip to content

Commit 8c22e67

Browse files
committed
Save space by disabling DigitalInOut protocol support where needed
1 parent e1fe8a0 commit 8c22e67

File tree

9 files changed

+95
-40
lines changed

9 files changed

+95
-40
lines changed

locale/circuitpython.pot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ msgstr ""
313313
msgid "'%q' argument required"
314314
msgstr ""
315315

316-
#: py/proto.c
316+
#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c
317317
msgid "'%q' object does not support '%q'"
318318
msgstr ""
319319

ports/atmel-samd/mpconfigport.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ CIRCUITPY_LTO = 1
1414
CIRCUITPY_KEYPAD_DEMUX ?= 0
1515
CIRCUITPY_LVFONTIO ?= 0
1616

17+
CIRCUITPY_DIGITALINOUT_PROTOCOL = 0
18+
1719
######################################################################
1820
# Put samd21-only choices here.
1921

ports/stm/boards/meowbit_v121/mpconfigboard.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ CIRCUITPY_ZLIB = 0
3737

3838
CIRCUITPY_STAGE = 1
3939

40+
CIRCUITPY_DIGITALINOUT_PROTOCOL = 0
41+
4042
FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/meowbit

py/circuitpy_mpconfig.mk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ CFLAGS += -DCIRCUITPY_CYW43=$(CIRCUITPY_CYW43)
241241
CIRCUITPY_DIGITALIO ?= 1
242242
CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO)
243243

244+
# Enable the DigitalInOut protocol on the native DigitalInOut type.
245+
# This allows other C code to use DigitalInOut objects polymorphically.
246+
# Disable on small builds to save space.
247+
CIRCUITPY_DIGITALINOUT_PROTOCOL ?= $(CIRCUITPY_FULL_BUILD)
248+
CFLAGS += -DCIRCUITPY_DIGITALINOUT_PROTOCOL=$(CIRCUITPY_DIGITALINOUT_PROTOCOL)
249+
244250
CIRCUITPY_COPROC ?= 0
245251
CFLAGS += -DCIRCUITPY_COPROC=$(CIRCUITPY_COPROC)
246252

shared-bindings/digitalio/DigitalInOut.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -343,85 +343,90 @@ static const mp_rom_map_elem_t digitalio_digitalinout_locals_dict_table[] = {
343343
static MP_DEFINE_CONST_DICT(digitalio_digitalinout_locals_dict, digitalio_digitalinout_locals_dict_table);
344344

345345
// Protocol implementation - thin wrappers to match protocol signature
346-
static void digitalinout_proto_deinit(mp_obj_t self_in) {
346+
void digitalinout_deinit(mp_obj_t self_in) {
347347
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
348348
common_hal_digitalio_digitalinout_deinit(self);
349349
}
350350

351-
static bool digitalinout_proto_deinited(mp_obj_t self_in) {
351+
bool digitalinout_deinited(mp_obj_t self_in) {
352352
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
353353
return common_hal_digitalio_digitalinout_deinited(self);
354354
}
355355

356-
static digitalinout_result_t digitalinout_proto_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull) {
356+
digitalinout_result_t digitalinout_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull) {
357357
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
358358
return common_hal_digitalio_digitalinout_switch_to_input(self, pull);
359359
}
360360

361-
static digitalinout_result_t digitalinout_proto_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode) {
361+
digitalinout_result_t digitalinout_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode) {
362362
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
363363
return common_hal_digitalio_digitalinout_switch_to_output(self, value, drive_mode);
364364
}
365365

366-
static digitalio_direction_t digitalinout_proto_get_direction(mp_obj_t self_in) {
366+
digitalio_direction_t digitalinout_get_direction(mp_obj_t self_in) {
367367
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
368368
return common_hal_digitalio_digitalinout_get_direction(self);
369369
}
370370

371-
static mp_errno_t digitalinout_proto_set_value(mp_obj_t self_in, bool value) {
371+
mp_errno_t digitalinout_set_value(mp_obj_t self_in, bool value) {
372372
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
373373
common_hal_digitalio_digitalinout_set_value(self, value);
374374
return 0;
375375
}
376376

377-
static mp_errno_t digitalinout_proto_get_value(mp_obj_t self_in, bool *value) {
377+
mp_errno_t digitalinout_get_value(mp_obj_t self_in, bool *value) {
378378
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
379379
*value = common_hal_digitalio_digitalinout_get_value(self);
380380
return 0;
381381
}
382382

383-
static digitalinout_result_t digitalinout_proto_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode) {
383+
digitalinout_result_t digitalinout_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode) {
384384
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
385385
return common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode);
386386
}
387387

388-
static digitalio_drive_mode_t digitalinout_proto_get_drive_mode(mp_obj_t self_in) {
388+
digitalio_drive_mode_t digitalinout_get_drive_mode(mp_obj_t self_in) {
389389
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
390390
return common_hal_digitalio_digitalinout_get_drive_mode(self);
391391
}
392392

393-
static digitalinout_result_t digitalinout_proto_set_pull(mp_obj_t self_in, digitalio_pull_t pull) {
393+
digitalinout_result_t digitalinout_set_pull(mp_obj_t self_in, digitalio_pull_t pull) {
394394
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
395395
return common_hal_digitalio_digitalinout_set_pull(self, pull);
396396
}
397397

398-
static digitalio_pull_t digitalinout_proto_get_pull(mp_obj_t self_in) {
398+
digitalio_pull_t digitalinout_get_pull(mp_obj_t self_in) {
399399
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
400400
return common_hal_digitalio_digitalinout_get_pull(self);
401401
}
402402

403+
#if CIRCUITPY_DIGITALINOUT_PROTOCOL
403404
static const digitalinout_p_t digitalinout_digitalinout_proto = {
404-
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_digitalinout)
405-
.deinit = digitalinout_proto_deinit,
406-
.deinited = digitalinout_proto_deinited,
407-
.switch_to_input = digitalinout_proto_switch_to_input,
408-
.switch_to_output = digitalinout_proto_switch_to_output,
409-
.get_direction = digitalinout_proto_get_direction,
410-
.get_value = digitalinout_proto_get_value,
411-
.set_value = digitalinout_proto_set_value,
412-
.get_drive_mode = digitalinout_proto_get_drive_mode,
413-
.set_drive_mode = digitalinout_proto_set_drive_mode,
414-
.get_pull = digitalinout_proto_get_pull,
415-
.set_pull = digitalinout_proto_set_pull,
405+
MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut)
406+
.deinit = digitalinout_deinit,
407+
.deinited = digitalinout_deinited,
408+
.switch_to_input = digitalinout_switch_to_input,
409+
.switch_to_output = digitalinout_switch_to_output,
410+
.get_direction = digitalinout_get_direction,
411+
.get_value = digitalinout_get_value,
412+
.set_value = digitalinout_set_value,
413+
.get_drive_mode = digitalinout_get_drive_mode,
414+
.set_drive_mode = digitalinout_set_drive_mode,
415+
.get_pull = digitalinout_get_pull,
416+
.set_pull = digitalinout_set_pull,
416417
};
418+
#endif
417419

418420
MP_DEFINE_CONST_OBJ_TYPE(
419421
digitalio_digitalinout_type,
420422
MP_QSTR_DigitalInOut,
421423
MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS,
422424
make_new, digitalio_digitalinout_make_new,
423-
locals_dict, &digitalio_digitalinout_locals_dict,
425+
locals_dict, &digitalio_digitalinout_locals_dict
426+
#if CIRCUITPY_DIGITALINOUT_PROTOCOL
427+
,
424428
protocol, &digitalinout_digitalinout_proto
429+
#endif
425430
);
426431

427432
// Helper for validating digitalio.DigitalInOut arguments

shared-bindings/digitalio/DigitalInOut.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,16 @@ digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj);
5757

5858
volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask);
5959
bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op);
60+
61+
// Protocol wrapper functions - always available for direct calls
62+
void digitalinout_deinit(mp_obj_t self_in);
63+
bool digitalinout_deinited(mp_obj_t self_in);
64+
digitalinout_result_t digitalinout_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull);
65+
digitalinout_result_t digitalinout_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode);
66+
digitalio_direction_t digitalinout_get_direction(mp_obj_t self_in);
67+
mp_errno_t digitalinout_set_value(mp_obj_t self_in, bool value);
68+
mp_errno_t digitalinout_get_value(mp_obj_t self_in, bool *value);
69+
digitalinout_result_t digitalinout_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode);
70+
digitalio_drive_mode_t digitalinout_get_drive_mode(mp_obj_t self_in);
71+
digitalinout_result_t digitalinout_set_pull(mp_obj_t self_in, digitalio_pull_t pull);
72+
digitalio_pull_t digitalinout_get_pull(mp_obj_t self_in);

shared-bindings/digitalio/DigitalInOutProtocol.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
//
103103
// Example:
104104
// static const digitalinout_p_t my_type_proto = {
105-
// MP_PROTO_IMPLEMENT(MP_QSTR_protocol_digitalinout)
105+
// MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut)
106106
// .construct = my_construct_func,
107107
// .deinit = my_deinit_func,
108108
// .deinited = my_deinited_func,
@@ -128,7 +128,7 @@
128128
// See shared-bindings/digitalio/DigitalInOut.c for a complete example.
129129
//
130130

131-
131+
#if CIRCUITPY_DIGITALINOUT_PROTOCOL
132132
static void check_object_has_method(mp_obj_t obj, qstr method_name) {
133133
mp_obj_t dest[2];
134134
mp_load_method_protected(obj, method_name, dest, true);
@@ -144,6 +144,7 @@ static void check_object_has_attr(mp_obj_t obj, qstr attr_name) {
144144
mp_raise_TypeError_varg(MP_ERROR_TEXT("%q object missing '%q' attribute"), MP_OBJ_TO_PTR(obj), attr_name);
145145
}
146146
}
147+
#endif
147148

148149
mp_obj_t digitalinout_protocol_from_pin(
149150
mp_obj_t pin_or_dio,
@@ -195,8 +196,9 @@ mp_obj_t digitalinout_protocol_from_pin(
195196
return dio_obj;
196197
}
197198

199+
#if CIRCUITPY_DIGITALINOUT_PROTOCOL
198200
// Check if it natively implements the DigitalInOutProtocol
199-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, pin_or_dio);
201+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, pin_or_dio);
200202
if (proto != NULL) {
201203
// Native protocol support - use it directly
202204
return pin_or_dio;
@@ -214,8 +216,15 @@ mp_obj_t digitalinout_protocol_from_pin(
214216

215217
// Object has all required attributes - use it as DigitalInOutProtocol
216218
return pin_or_dio;
219+
#else
220+
mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object does not support '%q'"),
221+
mp_obj_get_type_qstr(pin_or_dio), MP_QSTR_DigitalInOut);
222+
#endif
217223
}
218224

225+
// These functions are only used when CIRCUITPY_DIGITALINOUT_PROTOCOL is enabled.
226+
// Otherwise, the digitalinout_* functions are called directly.
227+
#if CIRCUITPY_DIGITALINOUT_PROTOCOL
219228
void digitalinout_protocol_deinit(mp_obj_t self) {
220229
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
221230
if (proto && proto->deinit) {
@@ -233,7 +242,7 @@ void digitalinout_protocol_deinit(mp_obj_t self) {
233242
}
234243

235244
bool digitalinout_protocol_deinited(mp_obj_t self) {
236-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
245+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
237246
if (proto && proto->deinited) {
238247
return proto->deinited(self);
239248
}
@@ -244,7 +253,7 @@ bool digitalinout_protocol_deinited(mp_obj_t self) {
244253
}
245254

246255
digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digitalio_pull_t pull) {
247-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
256+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
248257
if (proto && proto->switch_to_input) {
249258
return proto->switch_to_input(self, pull);
250259
}
@@ -268,7 +277,7 @@ digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digit
268277
}
269278

270279
digitalinout_result_t digitalinout_protocol_switch_to_output(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode) {
271-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
280+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
272281
if (proto && proto->switch_to_output) {
273282
return proto->switch_to_output(self, value, drive_mode);
274283
}
@@ -289,7 +298,7 @@ digitalinout_result_t digitalinout_protocol_switch_to_output(mp_obj_t self, bool
289298
}
290299

291300
digitalio_direction_t digitalinout_protocol_get_direction(mp_obj_t self) {
292-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
301+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
293302
if (proto && proto->get_direction) {
294303
return proto->get_direction(self);
295304
}
@@ -303,7 +312,7 @@ digitalio_direction_t digitalinout_protocol_get_direction(mp_obj_t self) {
303312
}
304313

305314
mp_errno_t digitalinout_protocol_set_value(mp_obj_t self, bool value) {
306-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
315+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
307316
if (proto && proto->set_value) {
308317
return proto->set_value(self, value);
309318
}
@@ -314,7 +323,7 @@ mp_errno_t digitalinout_protocol_set_value(mp_obj_t self, bool value) {
314323
}
315324

316325
mp_errno_t digitalinout_protocol_get_value(mp_obj_t self, bool *value) {
317-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
326+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
318327
if (proto && proto->get_value) {
319328
return proto->get_value(self, value);
320329
}
@@ -325,7 +334,7 @@ mp_errno_t digitalinout_protocol_get_value(mp_obj_t self, bool *value) {
325334
}
326335

327336
digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digitalio_drive_mode_t drive_mode) {
328-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
337+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
329338
if (proto && proto->set_drive_mode) {
330339
return proto->set_drive_mode(self, drive_mode);
331340
}
@@ -339,7 +348,7 @@ digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digita
339348
}
340349

341350
digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self) {
342-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
351+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
343352
if (proto && proto->get_drive_mode) {
344353
return proto->get_drive_mode(self);
345354
}
@@ -353,7 +362,7 @@ digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self) {
353362
}
354363

355364
digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pull_t pull) {
356-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
365+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
357366
if (proto && proto->set_pull) {
358367
return proto->set_pull(self, pull);
359368
}
@@ -370,7 +379,7 @@ digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pu
370379
}
371380

372381
digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self) {
373-
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self);
382+
const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self);
374383
if (proto && proto->get_pull) {
375384
return proto->get_pull(self);
376385
}
@@ -384,3 +393,5 @@ digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self) {
384393
}
385394
return PULL_NONE;
386395
}
396+
397+
#endif // CIRCUITPY_DIGITALINOUT_PROTOCOL

shared-bindings/digitalio/DigitalInOutProtocol.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// Protocol structure for DigitalInOut implementations
2020
// Note: mcu_pin_obj_t and digitalinout_result_t are defined by files that include this header
2121
typedef struct _digitalinout_p_t {
22-
MP_PROTOCOL_HEAD // MP_QSTR_protocol_digitalinout
22+
MP_PROTOCOL_HEAD // MP_QSTR_DigitalInOut
2323
void (*deinit)(mp_obj_t self);
2424
bool (*deinited)(mp_obj_t self);
2525
digitalinout_result_t (*switch_to_input)(mp_obj_t self, digitalio_pull_t pull);
@@ -54,6 +54,8 @@ mp_obj_t digitalinout_protocol_from_pin(
5454
bool force_port_allocation,
5555
bool *out_owns_pin);
5656

57+
#if CIRCUITPY_DIGITALINOUT_PROTOCOL
58+
// Protocol helper functions that do protocol lookup or Python fallback
5759
void digitalinout_protocol_deinit(mp_obj_t self);
5860
bool digitalinout_protocol_deinited(mp_obj_t self);
5961
digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digitalio_pull_t pull);
@@ -65,3 +67,17 @@ digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digita
6567
digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self);
6668
digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pull_t pull);
6769
digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self);
70+
#else
71+
// When protocol is disabled, map directly to native DigitalInOut functions
72+
#define digitalinout_protocol_deinit digitalinout_deinit
73+
#define digitalinout_protocol_deinited digitalinout_deinited
74+
#define digitalinout_protocol_switch_to_input digitalinout_switch_to_input
75+
#define digitalinout_protocol_switch_to_output digitalinout_switch_to_output
76+
#define digitalinout_protocol_get_direction digitalinout_get_direction
77+
#define digitalinout_protocol_set_value digitalinout_set_value
78+
#define digitalinout_protocol_get_value digitalinout_get_value
79+
#define digitalinout_protocol_set_drive_mode digitalinout_set_drive_mode
80+
#define digitalinout_protocol_get_drive_mode digitalinout_get_drive_mode
81+
#define digitalinout_protocol_set_pull digitalinout_set_pull
82+
#define digitalinout_protocol_get_pull digitalinout_get_pull
83+
#endif

shared-bindings/i2cioexpander/IOPin.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ static digitalinout_result_t iopin_protocol_set_pull(mp_obj_t self_in, digitalio
290290
}
291291

292292
static const digitalinout_p_t iopin_digitalinout_p = {
293-
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_digitalinout)
293+
MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut)
294294
.deinit = iopin_protocol_deinit,
295295
.deinited = iopin_protocol_deinited,
296296
.switch_to_input = iopin_protocol_switch_to_input,

0 commit comments

Comments
 (0)