|
| 1 | +// This file is part of the CircuitPython project: https://circuitpython.org |
| 2 | +// |
| 3 | +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries |
| 4 | +// |
| 5 | +// SPDX-License-Identifier: MIT |
| 6 | + |
| 7 | +#include "bindings/zephyr_display/Display.h" |
| 8 | + |
| 9 | +#include "py/objproperty.h" |
| 10 | +#include "py/objtype.h" |
| 11 | +#include "py/runtime.h" |
| 12 | +#include "shared-bindings/displayio/Group.h" |
| 13 | +#include "shared-module/displayio/__init__.h" |
| 14 | + |
| 15 | +static mp_obj_t zephyr_display_display_make_new(const mp_obj_type_t *type, |
| 16 | + size_t n_args, |
| 17 | + size_t n_kw, |
| 18 | + const mp_obj_t *all_args) { |
| 19 | + (void)type; |
| 20 | + (void)n_args; |
| 21 | + (void)n_kw; |
| 22 | + (void)all_args; |
| 23 | + mp_raise_NotImplementedError(MP_ERROR_TEXT("Use board.DISPLAY")); |
| 24 | + return mp_const_none; |
| 25 | +} |
| 26 | + |
| 27 | +static zephyr_display_display_obj_t *native_display(mp_obj_t display_obj) { |
| 28 | + mp_obj_t native = mp_obj_cast_to_native_base(display_obj, &zephyr_display_display_type); |
| 29 | + mp_obj_assert_native_inited(native); |
| 30 | + return MP_OBJ_TO_PTR(native); |
| 31 | +} |
| 32 | + |
| 33 | +static mp_obj_t zephyr_display_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { |
| 34 | + (void)self_in; |
| 35 | + (void)group_in; |
| 36 | + mp_raise_AttributeError(MP_ERROR_TEXT(".show(x) removed. Use .root_group = x")); |
| 37 | + return mp_const_none; |
| 38 | +} |
| 39 | +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_show_obj, zephyr_display_display_obj_show); |
| 40 | + |
| 41 | +static mp_obj_t zephyr_display_display_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { |
| 42 | + enum { |
| 43 | + ARG_target_frames_per_second, |
| 44 | + ARG_minimum_frames_per_second, |
| 45 | + }; |
| 46 | + static const mp_arg_t allowed_args[] = { |
| 47 | + { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, |
| 48 | + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, |
| 49 | + }; |
| 50 | + |
| 51 | + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; |
| 52 | + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); |
| 53 | + |
| 54 | + zephyr_display_display_obj_t *self = native_display(pos_args[0]); |
| 55 | + |
| 56 | + uint32_t maximum_ms_per_real_frame = NO_FPS_LIMIT; |
| 57 | + mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; |
| 58 | + if (minimum_frames_per_second > 0) { |
| 59 | + maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; |
| 60 | + } |
| 61 | + |
| 62 | + uint32_t target_ms_per_frame; |
| 63 | + if (args[ARG_target_frames_per_second].u_obj == mp_const_none) { |
| 64 | + target_ms_per_frame = NO_FPS_LIMIT; |
| 65 | + } else { |
| 66 | + target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj); |
| 67 | + } |
| 68 | + |
| 69 | + return mp_obj_new_bool(common_hal_zephyr_display_display_refresh( |
| 70 | + self, |
| 71 | + target_ms_per_frame, |
| 72 | + maximum_ms_per_real_frame)); |
| 73 | +} |
| 74 | +MP_DEFINE_CONST_FUN_OBJ_KW(zephyr_display_display_refresh_obj, 1, zephyr_display_display_obj_refresh); |
| 75 | + |
| 76 | +static mp_obj_t zephyr_display_display_obj_get_auto_refresh(mp_obj_t self_in) { |
| 77 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 78 | + return mp_obj_new_bool(common_hal_zephyr_display_display_get_auto_refresh(self)); |
| 79 | +} |
| 80 | +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_auto_refresh_obj, zephyr_display_display_obj_get_auto_refresh); |
| 81 | + |
| 82 | +static mp_obj_t zephyr_display_display_obj_set_auto_refresh(mp_obj_t self_in, mp_obj_t auto_refresh) { |
| 83 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 84 | + common_hal_zephyr_display_display_set_auto_refresh(self, mp_obj_is_true(auto_refresh)); |
| 85 | + return mp_const_none; |
| 86 | +} |
| 87 | +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_auto_refresh_obj, zephyr_display_display_obj_set_auto_refresh); |
| 88 | + |
| 89 | +MP_PROPERTY_GETSET(zephyr_display_display_auto_refresh_obj, |
| 90 | + (mp_obj_t)&zephyr_display_display_get_auto_refresh_obj, |
| 91 | + (mp_obj_t)&zephyr_display_display_set_auto_refresh_obj); |
| 92 | + |
| 93 | +static mp_obj_t zephyr_display_display_obj_get_brightness(mp_obj_t self_in) { |
| 94 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 95 | + mp_float_t brightness = common_hal_zephyr_display_display_get_brightness(self); |
| 96 | + if (brightness < 0) { |
| 97 | + mp_raise_RuntimeError(MP_ERROR_TEXT("Brightness not adjustable")); |
| 98 | + } |
| 99 | + return mp_obj_new_float(brightness); |
| 100 | +} |
| 101 | +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_brightness_obj, zephyr_display_display_obj_get_brightness); |
| 102 | + |
| 103 | +static mp_obj_t zephyr_display_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { |
| 104 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 105 | + mp_float_t brightness = mp_obj_get_float(brightness_obj); |
| 106 | + if (brightness < 0.0f || brightness > 1.0f) { |
| 107 | + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be %d-%d"), MP_QSTR_brightness, 0, 1); |
| 108 | + } |
| 109 | + bool ok = common_hal_zephyr_display_display_set_brightness(self, brightness); |
| 110 | + if (!ok) { |
| 111 | + mp_raise_RuntimeError(MP_ERROR_TEXT("Brightness not adjustable")); |
| 112 | + } |
| 113 | + return mp_const_none; |
| 114 | +} |
| 115 | +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_brightness_obj, zephyr_display_display_obj_set_brightness); |
| 116 | + |
| 117 | +MP_PROPERTY_GETSET(zephyr_display_display_brightness_obj, |
| 118 | + (mp_obj_t)&zephyr_display_display_get_brightness_obj, |
| 119 | + (mp_obj_t)&zephyr_display_display_set_brightness_obj); |
| 120 | + |
| 121 | +static mp_obj_t zephyr_display_display_obj_get_width(mp_obj_t self_in) { |
| 122 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 123 | + return MP_OBJ_NEW_SMALL_INT(common_hal_zephyr_display_display_get_width(self)); |
| 124 | +} |
| 125 | +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_width_obj, zephyr_display_display_obj_get_width); |
| 126 | +MP_PROPERTY_GETTER(zephyr_display_display_width_obj, (mp_obj_t)&zephyr_display_display_get_width_obj); |
| 127 | + |
| 128 | +static mp_obj_t zephyr_display_display_obj_get_height(mp_obj_t self_in) { |
| 129 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 130 | + return MP_OBJ_NEW_SMALL_INT(common_hal_zephyr_display_display_get_height(self)); |
| 131 | +} |
| 132 | +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_height_obj, zephyr_display_display_obj_get_height); |
| 133 | +MP_PROPERTY_GETTER(zephyr_display_display_height_obj, (mp_obj_t)&zephyr_display_display_get_height_obj); |
| 134 | + |
| 135 | +static mp_obj_t zephyr_display_display_obj_get_rotation(mp_obj_t self_in) { |
| 136 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 137 | + return MP_OBJ_NEW_SMALL_INT(common_hal_zephyr_display_display_get_rotation(self)); |
| 138 | +} |
| 139 | +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_rotation_obj, zephyr_display_display_obj_get_rotation); |
| 140 | + |
| 141 | +static mp_obj_t zephyr_display_display_obj_set_rotation(mp_obj_t self_in, mp_obj_t value) { |
| 142 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 143 | + common_hal_zephyr_display_display_set_rotation(self, mp_obj_get_int(value)); |
| 144 | + return mp_const_none; |
| 145 | +} |
| 146 | +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_rotation_obj, zephyr_display_display_obj_set_rotation); |
| 147 | + |
| 148 | +MP_PROPERTY_GETSET(zephyr_display_display_rotation_obj, |
| 149 | + (mp_obj_t)&zephyr_display_display_get_rotation_obj, |
| 150 | + (mp_obj_t)&zephyr_display_display_set_rotation_obj); |
| 151 | + |
| 152 | +static mp_obj_t zephyr_display_display_obj_get_root_group(mp_obj_t self_in) { |
| 153 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 154 | + return common_hal_zephyr_display_display_get_root_group(self); |
| 155 | +} |
| 156 | +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_root_group_obj, zephyr_display_display_obj_get_root_group); |
| 157 | + |
| 158 | +static mp_obj_t zephyr_display_display_obj_set_root_group(mp_obj_t self_in, mp_obj_t group_in) { |
| 159 | + zephyr_display_display_obj_t *self = native_display(self_in); |
| 160 | + displayio_group_t *group = NULL; |
| 161 | + if (group_in != mp_const_none) { |
| 162 | + group = MP_OBJ_TO_PTR(native_group(group_in)); |
| 163 | + } |
| 164 | + |
| 165 | + bool ok = common_hal_zephyr_display_display_set_root_group(self, group); |
| 166 | + if (!ok) { |
| 167 | + mp_raise_ValueError(MP_ERROR_TEXT("Group already used")); |
| 168 | + } |
| 169 | + return mp_const_none; |
| 170 | +} |
| 171 | +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_root_group_obj, zephyr_display_display_obj_set_root_group); |
| 172 | + |
| 173 | +MP_PROPERTY_GETSET(zephyr_display_display_root_group_obj, |
| 174 | + (mp_obj_t)&zephyr_display_display_get_root_group_obj, |
| 175 | + (mp_obj_t)&zephyr_display_display_set_root_group_obj); |
| 176 | + |
| 177 | +static const mp_rom_map_elem_t zephyr_display_display_locals_dict_table[] = { |
| 178 | + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&zephyr_display_display_show_obj) }, |
| 179 | + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&zephyr_display_display_refresh_obj) }, |
| 180 | + |
| 181 | + { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&zephyr_display_display_auto_refresh_obj) }, |
| 182 | + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&zephyr_display_display_brightness_obj) }, |
| 183 | + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&zephyr_display_display_width_obj) }, |
| 184 | + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&zephyr_display_display_height_obj) }, |
| 185 | + { MP_ROM_QSTR(MP_QSTR_rotation), MP_ROM_PTR(&zephyr_display_display_rotation_obj) }, |
| 186 | + { MP_ROM_QSTR(MP_QSTR_root_group), MP_ROM_PTR(&zephyr_display_display_root_group_obj) }, |
| 187 | +}; |
| 188 | +static MP_DEFINE_CONST_DICT(zephyr_display_display_locals_dict, zephyr_display_display_locals_dict_table); |
| 189 | + |
| 190 | +MP_DEFINE_CONST_OBJ_TYPE( |
| 191 | + zephyr_display_display_type, |
| 192 | + MP_QSTR_Display, |
| 193 | + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, |
| 194 | + make_new, zephyr_display_display_make_new, |
| 195 | + locals_dict, &zephyr_display_display_locals_dict); |
0 commit comments