From 05d8885a1ab959fabdbb77f99408b2e7dc78b97c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 16 Jan 2019 12:04:42 -0800 Subject: Rework displays in prep for dynamic support and 8bit parallel. --- shared-bindings/displayio/Display.c | 149 ++++++++++++++++++++++++++++++++ shared-bindings/displayio/Display.h | 59 +++++++++++++ shared-bindings/displayio/FourWire.c | 83 ++++++++---------- shared-bindings/displayio/FourWire.h | 29 ++----- shared-bindings/displayio/ParallelBus.c | 79 +++++++++++++++++ shared-bindings/displayio/ParallelBus.h | 47 ++++++++++ 6 files changed, 376 insertions(+), 70 deletions(-) create mode 100644 shared-bindings/displayio/Display.c create mode 100644 shared-bindings/displayio/Display.h create mode 100644 shared-bindings/displayio/ParallelBus.c create mode 100644 shared-bindings/displayio/ParallelBus.h (limited to 'shared-bindings') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c new file mode 100644 index 000000000..5db470417 --- /dev/null +++ b/shared-bindings/displayio/Display.c @@ -0,0 +1,149 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/displayio/Display.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`FourWire` -- Manage updating a display over SPI four wire protocol +//| ========================================================================== +//| +//| Manage updating a display over SPI four wire protocol in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, +//| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) +//| +//| Create a FourWire object associated with the given pins. +//| +STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, + { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, + { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t display_bus = args[ARG_display_bus].u_obj; + + mp_int_t width = args[ARG_width].u_int; + mp_int_t height = args[ARG_height].u_int; + if (width == -1 || height == -1) { + mp_raise_ValueError(translate("Width and height kwargs required")); + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + + displayio_display_obj_t *self; + if (display_bus == &primary_display.fourwire_bus) { + self = &primary_display.display; + } else { + self = m_new_obj(displayio_display_obj_t); + } + self->base.type = &displayio_display_type; + common_hal_displayio_display_construct(self, + display_bus, width, height, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, + args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len); + + return self; +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. +//| +STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Must be a Group subclass.")); + } + displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); + common_hal_displayio_display_show(self, group); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); + +//| .. method:: refresh_soon() +//| +//| Queues up a display refresh that happens in the background. +//| +STATIC mp_obj_t displayio_display_obj_refresh_soon(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_displayio_display_refresh_soon(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_refresh_soon_obj, displayio_display_obj_refresh_soon); + +//| .. method:: wait_for_frame() +//| +//| Waits until the next frame has been transmitted to the display unless the wait count is +//| behind the rendered frames. In that case, this will return immediately with the wait count. +//| +STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_wait_for_frame(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame); + + +STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) }, + { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table); + +const mp_obj_type_t displayio_display_type = { + { &mp_type_type }, + .name = MP_QSTR_Display, + .make_new = displayio_display_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_display_locals_dict, +}; diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h new file mode 100644 index 000000000..4cec66058 --- /dev/null +++ b/shared-bindings/displayio/Display.h @@ -0,0 +1,59 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Display.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_display_type; + +#define DELAY 0x80 + +void common_hal_displayio_display_construct(displayio_display_obj_t* self, + mp_obj_t bus, uint16_t width, uint16_t height, + int16_t colstart, int16_t rowstart, uint16_t color_depth, + uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, + uint8_t* init_sequence, uint16_t init_sequence_len); + +int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); + +void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group); + +void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self); + +void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); +void displayio_display_finish_region_update(displayio_display_obj_t* self); +bool displayio_display_frame_queued(displayio_display_obj_t* self); + +bool displayio_display_refresh_queued(displayio_display_obj_t* self); +void displayio_display_finish_refresh(displayio_display_obj_t* self); +bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 80aa814df..674d1c900 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018-2019 Scott Shawcroft for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,6 +35,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/translate.h" //| .. currentmodule:: displayio @@ -47,14 +48,44 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: FourWire(*, clock, data, command, chip_select, width, height, colstart, rowstart, -//| color_depth, set_column_command, set_row_command, write_ram_command) +//| .. class:: FourWire(spi_bus, *, command, chip_select, reset) //| //| Create a FourWire object associated with the given pins. //| STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_raise_NotImplementedError(translate("displayio is a work in progress")); - return mp_const_none; + enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + mp_obj_t reset = args[ARG_reset].u_obj; + if (command == mp_const_none || chip_select == mp_const_none) { + mp_raise_ValueError(translate("Command and chip_select required")); + } + + displayio_fourwire_obj_t* self; + mp_obj_t spi = args[ARG_spi_bus].u_obj; + if (board_spi() == spi && primary_display.bus_type == NULL) { + self = &primary_display.fourwire_bus; + primary_display.bus_type = &displayio_fourwire_type; + } else { + // TODO(tannewt): Always check pin free. For now we ignore the primary display. + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(reset); + self = m_new_obj(displayio_fourwire_obj_t); + } + + common_hal_displayio_fourwire_construct(self, + MP_OBJ_TO_PTR(spi), command, chip_select, reset); + return self; } @@ -68,50 +99,8 @@ STATIC mp_obj_t displayio_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_a } MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 1, displayio_fourwire_obj_send); -//| .. method:: show(group) -//| -//| Switches do displaying the given group of elements. -//| -STATIC mp_obj_t displayio_fourwire_obj_show(mp_obj_t self_in, mp_obj_t group_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Must be a Group subclass.")); - } - displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); - common_hal_displayio_fourwire_show(self, group); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(displayio_fourwire_show_obj, displayio_fourwire_obj_show); - -//| .. method:: refresh_soon() -//| -//| Queues up a display refresh that happens in the background. -//| -STATIC mp_obj_t displayio_fourwire_obj_refresh_soon(mp_obj_t self_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_displayio_fourwire_refresh_soon(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_refresh_soon_obj, displayio_fourwire_obj_refresh_soon); - -//| .. method:: wait_for_frame() -//| -//| Waits until the next frame has been transmitted to the display unless the wait count is -//| behind the rendered frames. In that case, this will return immediately with the wait count. -//| -STATIC mp_obj_t displayio_fourwire_obj_wait_for_frame(mp_obj_t self_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_fourwire_wait_for_frame(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_wait_for_frame_obj, displayio_fourwire_obj_wait_for_frame); - - STATIC const mp_rom_map_elem_t displayio_fourwire_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_fourwire_send_obj) }, - { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_fourwire_show_obj) }, - { MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_fourwire_refresh_soon_obj) }, - { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_fourwire_wait_for_frame_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table); diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index fc51f558d..a9e1bf566 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -31,35 +31,18 @@ #include "common-hal/microcontroller/Pin.h" #include "shared-module/displayio/Group.h" +#include "supervisor/shared/board_busses.h" extern const mp_obj_type_t displayio_fourwire_type; -// TODO(tannewt): Split this apart into FourWire and a Display object because the dimensions and -// commands are also used for the parallel buses. void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, - const mcu_pin_obj_t* clock, const mcu_pin_obj_t* data, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint16_t width, uint16_t height, - int16_t colstart, int16_t rowstart, uint16_t color_depth, - uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command); + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset); -int32_t common_hal_displayio_fourwire_wait_for_frame(displayio_fourwire_obj_t* self); +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); -bool common_hal_displayio_fourwire_begin_transaction(displayio_fourwire_obj_t* self); +void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); -void common_hal_displayio_fourwire_send(displayio_fourwire_obj_t* self, bool command, uint8_t *data, uint32_t data_length); - -void common_hal_displayio_fourwire_end_transaction(displayio_fourwire_obj_t* self); - -void common_hal_displayio_fourwire_show(displayio_fourwire_obj_t* self, displayio_group_t* root_group); - -void common_hal_displayio_fourwire_refresh_soon(displayio_fourwire_obj_t* self); - -void displayio_fourwire_start_region_update(displayio_fourwire_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); -void displayio_fourwire_finish_region_update(displayio_fourwire_obj_t* self); -bool displayio_fourwire_frame_queued(displayio_fourwire_obj_t* self); - -bool displayio_fourwire_refresh_queued(displayio_fourwire_obj_t* self); -void displayio_fourwire_finish_refresh(displayio_fourwire_obj_t* self); -bool displayio_fourwire_send_pixels(displayio_fourwire_obj_t* self, uint32_t* pixels, uint32_t length); +void common_hal_displayio_fourwire_end_transaction(mp_obj_t self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c new file mode 100644 index 000000000..dddb4ce8a --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.c @@ -0,0 +1,79 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`ParallelBus` -- Manage updating a display over SPI four wire protocol +//| ========================================================================== +//| +//| Manage updating a display over SPI four wire protocol in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: ParallelBus(*, data0, command, chip_select, reset, write, bus_width=8) +//| +//| Create a ParallelBus object associated with the given pins. +//| +STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_raise_NotImplementedError(translate("displayio is a work in progress")); + return mp_const_none; +} + + +//| .. method:: send(command, data) +//| +//| +STATIC mp_obj_t displayio_parallelbus_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_raise_NotImplementedError(translate("displayio is a work in progress")); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(displayio_parallelbus_send_obj, 1, displayio_parallelbus_obj_send); + +STATIC const mp_rom_map_elem_t displayio_parallelbus_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_parallelbus_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_parallelbus_locals_dict, displayio_parallelbus_locals_dict_table); + +const mp_obj_type_t displayio_parallelbus_type = { + { &mp_type_type }, + .name = MP_QSTR_ParallelBus, + .make_new = displayio_parallelbus_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_parallelbus_locals_dict, +}; diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h new file mode 100644 index 000000000..f1d1656b1 --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.h @@ -0,0 +1,47 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H + +#include "common-hal/displayio/ParallelBus.h" +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_parallelbus_type; + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); + +void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H -- cgit v1.2.3 From 84292ad89070f1994ed09b59c8a693216a40cd89 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 00:20:16 -0800 Subject: External fourwire works and blinka splash after --- main.c | 2 +- ports/atmel-samd/background.c | 2 +- .../boards/grandcentral_m4_express/mpconfigboard.h | 2 + .../boards/grandcentral_m4_express/pins.c | 2 +- ports/atmel-samd/boards/pyportal/mpconfigboard.h | 2 +- ports/atmel-samd/boards/pyportal/pins.c | 4 +- ports/atmel-samd/common-hal/busio/SPI.c | 13 ++ ports/atmel-samd/common-hal/displayio/FourWire.c | 10 + ports/atmel-samd/common-hal/displayio/FourWire.h | 1 + ports/atmel-samd/common-hal/microcontroller/Pin.c | 2 + shared-bindings/displayio/Display.c | 23 ++- shared-bindings/displayio/FourWire.c | 23 ++- shared-bindings/displayio/FourWire.h | 2 + shared-bindings/displayio/ParallelBus.h | 2 + shared-bindings/displayio/__init__.c | 16 ++ shared-bindings/displayio/__init__.h | 4 +- shared-module/displayio/__init__.c | 220 ++++++++++++++++----- shared-module/displayio/__init__.h | 7 +- 18 files changed, 255 insertions(+), 82 deletions(-) (limited to 'shared-bindings') diff --git a/main.c b/main.c index d328fcaa4..02c832e67 100755 --- a/main.c +++ b/main.c @@ -201,7 +201,7 @@ bool run_code_py(safe_mode_t safe_mode) { } } // Turn off the display before the heap disappears. - reset_primary_display(); + reset_displays(); stop_mp(); free_memory(heap); diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 439877d2e..59e03008a 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -44,7 +44,7 @@ void run_background_tasks(void) { audio_dma_background(); #endif #ifdef CIRCUITPY_DISPLAYIO - displayio_refresh_display(); + displayio_refresh_displays(); #endif #if MICROPY_PY_NETWORK diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h index e1bef0019..465c51b4a 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h @@ -46,3 +46,5 @@ #define IGNORE_PIN_PA25 1 #define CIRCUITPY_I2CSLAVE +#define CIRCUITPY_DISPLAYIO (1) +#define CIRCUITPY_DISPLAY_LIMIT (3) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index 081bb701e..0d19a63ef 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.h b/ports/atmel-samd/boards/pyportal/mpconfigboard.h index 847e2ba76..f02d4a372 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.h +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.h @@ -13,7 +13,7 @@ // QSPI Data pins #define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) // QSPI CS, and QSPI SCK -#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 ) +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 ) #define MICROPY_PORT_C ( 0 ) #define MICROPY_PORT_D (0) diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index ddb8fa08a..4ddc10e52 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -1,7 +1,7 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from @@ -72,7 +72,5 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, - - { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&board_display_obj)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 68382d405..8fb831a69 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -54,6 +54,17 @@ void never_reset_sercom(Sercom* sercom) { } } +void allow_reset_sercom(Sercom* sercom) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_instances[i] == sercom) { + never_reset_sercoms[i] = false; + break; + } + } +} + void reset_sercoms(void) { // Reset all SERCOMs except the ones being used by on-board devices. Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; @@ -235,6 +246,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } + allow_reset_sercom(self->spi_desc.dev.prvt); + spi_m_sync_disable(&self->spi_desc); spi_m_sync_deinit(&self->spi_desc); reset_pin_number(self->clock_pin); diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c index 7a0bdd0c1..ab01e2609 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ b/ports/atmel-samd/common-hal/displayio/FourWire.c @@ -53,6 +53,16 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, never_reset_pin_number(reset->number); } +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { + if (self->bus == &self->inline_bus) { + common_hal_busio_spi_deinit(self->bus); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->reset.pin->number); +} + bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); if (!common_hal_busio_spi_try_lock(self->bus)) { diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.h b/ports/atmel-samd/common-hal/displayio/FourWire.h index e3ae5781b..234bcf794 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.h +++ b/ports/atmel-samd/common-hal/displayio/FourWire.h @@ -34,6 +34,7 @@ typedef struct { mp_obj_base_t base; busio_spi_obj_t* bus; + busio_spi_obj_t inline_bus; digitalio_digitalinout_obj_t command; digitalio_digitalinout_obj_t chip_select; digitalio_digitalinout_obj_t reset; diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 7d0d97758..b7d527d04 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -100,6 +100,8 @@ void never_reset_pin_number(uint8_t pin_number) { } void reset_pin_number(uint8_t pin_number) { + never_reset_pins[GPIO_PORT(pin_number)] &= ~(1 << GPIO_PIN(pin_number)); + if (pin_number >= PORT_BITS) { return; } diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 5db470417..21f44965e 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -40,18 +40,19 @@ //| .. currentmodule:: displayio //| -//| :class:`FourWire` -- Manage updating a display over SPI four wire protocol +//| :class:`Display` -- Manage updating a display over a display bus //| ========================================================================== //| -//| Manage updating a display over SPI four wire protocol in the background while Python code runs. -//| It doesn't handle display initialization. +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| //| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, //| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) //| -//| Create a FourWire object associated with the given pins. +//| Create a Display object. //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; @@ -80,11 +81,15 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - displayio_display_obj_t *self; - if (display_bus == &primary_display.fourwire_bus) { - self = &primary_display.display; - } else { - self = m_new_obj(displayio_display_obj_t); + displayio_display_obj_t *self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + self = &displays[i].display; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display limit reached")); } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 674d1c900..9833fbc64 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -69,18 +69,21 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ if (command == mp_const_none || chip_select == mp_const_none) { mp_raise_ValueError(translate("Command and chip_select required")); } + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(reset); - displayio_fourwire_obj_t* self; + displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; - if (board_spi() == spi && primary_display.bus_type == NULL) { - self = &primary_display.fourwire_bus; - primary_display.bus_type = &displayio_fourwire_type; - } else { - // TODO(tannewt): Always check pin free. For now we ignore the primary display. - assert_pin_free(command); - assert_pin_free(chip_select); - assert_pin_free(reset); - self = m_new_obj(displayio_fourwire_obj_t); + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type== NULL) { + self = &displays[i].fourwire_bus; + self->base.type = &displayio_fourwire_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display bus limit reached")); } common_hal_displayio_fourwire_construct(self, diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index a9e1bf566..3a9f66d4c 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -39,6 +39,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, busio_spi_obj_t* spi, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset); +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); + bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h index f1d1656b1..c73934838 100644 --- a/shared-bindings/displayio/ParallelBus.h +++ b/shared-bindings/displayio/ParallelBus.h @@ -38,6 +38,8 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); + bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index d485d8095..66cf4d63d 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -32,6 +32,7 @@ #include "shared-bindings/displayio/__init__.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" @@ -61,6 +62,7 @@ //| //| Bitmap //| ColorConverter +//| Display //| FourWire //| Group //| OnDiskBitmap @@ -71,10 +73,22 @@ //| All libraries change hardware state but are never deinit //| + +//| .. method:: release_displays() +//| +//| Releases any actively used displays so theis pins can be used again. +//| +STATIC mp_obj_t displayio_release_displays(void) { + common_hal_displayio_release_displays(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays); + STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, { MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) }, { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, @@ -82,6 +96,8 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, + + { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h index a6663bf57..427ddb47d 100644 --- a/shared-bindings/displayio/__init__.h +++ b/shared-bindings/displayio/__init__.h @@ -27,8 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H -#include "py/obj.h" - -// Nothing now. +void common_hal_displayio_release_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index b528c3289..48194f63f 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -1,68 +1,190 @@ +#include #include "shared-module/displayio/__init__.h" +#include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Sprite.h" -primary_display_t primary_display; +primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -void displayio_refresh_display(void) { - displayio_display_obj_t* display = &primary_display.display; +void displayio_refresh_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + displayio_display_obj_t* display = &displays[i].display; - if (!displayio_display_frame_queued(display)) { - return; - } - if (displayio_display_refresh_queued(display)) { - PORT->Group[1].DIRSET.reg = 1 << 22; - - // We compute the pixels - uint16_t x0 = 0; - uint16_t y0 = 0; - uint16_t x1 = display->width; - uint16_t y1 = display->height; - size_t index = 0; - //size_t row_size = (x1 - x0); - uint16_t buffer_size = 256; - uint32_t buffer[buffer_size / 2]; - displayio_display_start_region_update(display, x0, y0, x1, y1); - for (uint16_t y = y0; y < y1; ++y) { - for (uint16_t x = x0; x < x1; ++x) { - uint16_t* pixel = &(((uint16_t*)buffer)[index]); - *pixel = 0; - - PORT->Group[1].OUTTGL.reg = 1 << 22; - - //if (index == 0) { - if (display->current_group != NULL) { - displayio_group_get_pixel(display->current_group, x, y, pixel); - } - // } else { - // *pixel = (((uint16_t*)buffer)[0]); - // } + if (!displayio_display_frame_queued(display)) { + return; + } + if (displayio_display_refresh_queued(display)) { + PORT->Group[1].DIRSET.reg = 1 << 22; + + // We compute the pixels + uint16_t x0 = 0; + uint16_t y0 = 0; + uint16_t x1 = display->width; + uint16_t y1 = display->height; + size_t index = 0; + //size_t row_size = (x1 - x0); + uint16_t buffer_size = 256; + uint32_t buffer[buffer_size / 2]; + displayio_display_start_region_update(display, x0, y0, x1, y1); + for (uint16_t y = y0; y < y1; ++y) { + for (uint16_t x = x0; x < x1; ++x) { + uint16_t* pixel = &(((uint16_t*)buffer)[index]); + *pixel = 0; + + PORT->Group[1].OUTTGL.reg = 1 << 22; + + //if (index == 0) { + if (display->current_group != NULL) { + displayio_group_get_pixel(display->current_group, x, y, pixel); + } + // } else { + // *pixel = (((uint16_t*)buffer)[0]); + // } - PORT->Group[1].OUTTGL.reg = 1 << 22; + PORT->Group[1].OUTTGL.reg = 1 << 22; - index += 1; - // The buffer is full, send it. - if (index >= buffer_size) { - if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { - displayio_display_finish_region_update(display); - return; + index += 1; + // The buffer is full, send it. + if (index >= buffer_size) { + if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { + displayio_display_finish_region_update(display); + return; + } + index = 0; } - index = 0; } } - } - // Send the remaining data. - if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + // Send the remaining data. + if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + displayio_display_finish_region_update(display); + return; + } displayio_display_finish_region_update(display); - return; } - displayio_display_finish_region_update(display); + displayio_display_finish_refresh(display); } - displayio_display_finish_refresh(display); } -void reset_primary_display(void) { - common_hal_displayio_display_show(&primary_display.display, NULL); +uint32_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; + +displayio_bitmap_t blinka_bitmap = { + .base = {.type = &displayio_bitmap_type }, + .width = 16, + .height = 16, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf +}; + +uint32_t blinka_transparency[1] = {0x80000000}; +uint32_t blinka_colors[8] = {0x1e910000, 0x72dc722b, 0xffffb05a, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000}; + +displayio_palette_t blinka_palette = { + .base = {.type = &displayio_palette_type }, + .opaque = blinka_transparency, + .colors = blinka_colors, + .color_count = 16, + .needs_refresh = false +}; + +displayio_sprite_t blinka_sprite = { + .base = {.type = &displayio_sprite_type }, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .width = 16, + .height = 16, + .needs_refresh = false +}; + +mp_obj_t splash_children[1] = { + &blinka_sprite, +}; + +displayio_group_t splash = { + .base = {.type = &displayio_group_type }, + .x = 0, + .y = 0, + .size = 1, + .max_size = 1, + .children = splash_children, + .needs_refresh = true +}; + +void reset_displays(void) { + // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) { + continue; + } + displayio_fourwire_obj_t* fourwire = &displays[i].fourwire_bus; + if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) || + ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { + busio_spi_obj_t* original_spi = fourwire->bus; + memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); + fourwire->bus = &fourwire->inline_bus; + // Check for other displays that use the same spi bus and swap them too. + for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + if (displays[i].fourwire_bus.bus == original_spi) { + displays[i].fourwire_bus.bus = &fourwire->inline_bus; + } + } + } + } + + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + displayio_display_obj_t* display = &displays[i].display; + common_hal_displayio_display_show(display, &splash); + } +} + +void common_hal_displayio_release_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; + if (bus_type == NULL) { + continue; + } else if (bus_type == &displayio_fourwire_type) { + common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); + } else if (bus_type == &displayio_parallelbus_type) { + //common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + } + displays[i].fourwire_bus.base.type = NULL; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + displays[i].display.base.type = NULL; + } + // TODO(tannewt): Clear the display datastructures and release everything used. } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 84db98fcc..fdabd4ec4 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -36,13 +36,12 @@ typedef struct { displayio_fourwire_obj_t fourwire_bus; displayio_parallelbus_obj_t parallel_bus; }; - mp_const_obj_t bus_type; displayio_display_obj_t display; } primary_display_t; -extern primary_display_t primary_display; +extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -void displayio_refresh_display(void); -void reset_primary_display(void); +void displayio_refresh_displays(void); +void reset_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H -- cgit v1.2.3 From 2d136d58bf288f0be945ed5cd3efe9113d0acce3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 14:45:29 -0800 Subject: Fix other builds and hallowing --- ports/atmel-samd/boards/arduino_mkr1300/pins.c | 2 +- ports/atmel-samd/boards/arduino_mkrzero/pins.c | 4 +- ports/atmel-samd/boards/arduino_zero/pins.c | 2 +- ports/atmel-samd/boards/catwan_usbstick/pins.c | 2 +- .../boards/circuitplayground_express/pins.c | 2 +- .../circuitplayground_express_crickit/pins.c | 2 +- ports/atmel-samd/boards/cp32-m4/pins.c | 2 +- ports/atmel-samd/boards/datalore_ip_m4/pins.c | 2 +- .../atmel-samd/boards/feather_m0_adalogger/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_basic/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_express/pins.c | 2 +- .../boards/feather_m0_express_crickit/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_rfm69/pins.c | 2 +- ports/atmel-samd/boards/feather_m0_rfm9x/pins.c | 2 +- .../atmel-samd/boards/feather_m0_supersized/pins.c | 2 +- .../boards/feather_radiofruit_zigbee/pins.c | 2 +- ports/atmel-samd/boards/gemma_m0/pins.c | 2 +- .../atmel-samd/boards/hallowing_m0_express/board.c | 47 ++++++-------------- .../atmel-samd/boards/hallowing_m0_express/pins.c | 5 ++- .../atmel-samd/boards/itsybitsy_m0_express/pins.c | 2 +- .../atmel-samd/boards/itsybitsy_m4_express/pins.c | 2 +- ports/atmel-samd/boards/meowmeow/pins.c | 2 +- ports/atmel-samd/boards/metro_m0_express/pins.c | 2 +- ports/atmel-samd/boards/metro_m4_express/pins.c | 2 +- ports/atmel-samd/boards/mini_sam_m4/pins.c | 2 +- ports/atmel-samd/boards/pirkey_m0/pins.c | 2 +- ports/atmel-samd/boards/pyportal/board.c | 12 +++--- ports/atmel-samd/boards/pyportal/pins.c | 3 ++ .../atmel-samd/boards/sparkfun_samd21_mini/pins.c | 16 +++---- ports/atmel-samd/boards/trellis_m4_express/pins.c | 2 +- ports/atmel-samd/boards/trinket_m0/pins.c | 2 +- ports/atmel-samd/boards/trinket_m0_haxpress/pins.c | 2 +- ports/atmel-samd/boards/ugame10/pins.c | 2 +- .../atmel-samd/common-hal/displayio/ParallelBus.c | 38 +++++++++++++--- .../atmel-samd/common-hal/displayio/ParallelBus.h | 4 ++ ports/atmel-samd/mpconfigport.h | 1 + shared-bindings/displayio/ParallelBus.c | 50 ++++++++++++++++++++-- shared-bindings/displayio/ParallelBus.h | 4 +- shared-bindings/displayio/__init__.c | 3 ++ shared-module/displayio/Display.c | 4 +- shared-module/displayio/__init__.c | 17 +++----- 41 files changed, 160 insertions(+), 102 deletions(-) (limited to 'shared-bindings') diff --git a/ports/atmel-samd/boards/arduino_mkr1300/pins.c b/ports/atmel-samd/boards/arduino_mkr1300/pins.c index de9f9769c..a5a058ace 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/pins.c +++ b/ports/atmel-samd/boards/arduino_mkr1300/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/arduino_mkrzero/pins.c b/ports/atmel-samd/boards/arduino_mkrzero/pins.c index 3ffd37fa6..654c0d6da 100644 --- a/ports/atmel-samd/boards/arduino_mkrzero/pins.c +++ b/ports/atmel-samd/boards/arduino_mkrzero/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, @@ -31,7 +31,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB23) }, { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB22) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB22) }, { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA13) }, { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA12) }, { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA15) }, diff --git a/ports/atmel-samd/boards/arduino_zero/pins.c b/ports/atmel-samd/boards/arduino_zero/pins.c index 8a7ff70e6..f9403bb9a 100644 --- a/ports/atmel-samd/boards/arduino_zero/pins.c +++ b/ports/atmel-samd/boards/arduino_zero/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/catwan_usbstick/pins.c b/ports/atmel-samd/boards/catwan_usbstick/pins.c index 8997b653f..87ee84c0b 100644 --- a/ports/atmel-samd/boards/catwan_usbstick/pins.c +++ b/ports/atmel-samd/boards/catwan_usbstick/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA30) }, diff --git a/ports/atmel-samd/boards/circuitplayground_express/pins.c b/ports/atmel-samd/boards/circuitplayground_express/pins.c index 14ae89c55..70743366e 100644 --- a/ports/atmel-samd/boards/circuitplayground_express/pins.c +++ b/ports/atmel-samd/boards/circuitplayground_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c index 14ae89c55..70743366e 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c +++ b/ports/atmel-samd/boards/circuitplayground_express_crickit/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/cp32-m4/pins.c b/ports/atmel-samd/boards/cp32-m4/pins.c index 93c169c8b..9da67dfb4 100644 --- a/ports/atmel-samd/boards/cp32-m4/pins.c +++ b/ports/atmel-samd/boards/cp32-m4/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/datalore_ip_m4/pins.c b/ports/atmel-samd/boards/datalore_ip_m4/pins.c index 460fd6fef..468a09a47 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/pins.c +++ b/ports/atmel-samd/boards/datalore_ip_m4/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c index 0029bba1a..d99e62c95 100644 --- a/ports/atmel-samd/boards/feather_m0_adalogger/pins.c +++ b/ports/atmel-samd/boards/feather_m0_adalogger/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_basic/pins.c b/ports/atmel-samd/boards/feather_m0_basic/pins.c index 4400a253d..f9b6db63b 100644 --- a/ports/atmel-samd/boards/feather_m0_basic/pins.c +++ b/ports/atmel-samd/boards/feather_m0_basic/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_express/pins.c b/ports/atmel-samd/boards/feather_m0_express/pins.c index cd6c351d4..1eaa98a58 100644 --- a/ports/atmel-samd/boards/feather_m0_express/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c index cd6c351d4..1eaa98a58 100644 --- a/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c +++ b/ports/atmel-samd/boards/feather_m0_express_crickit/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c index 7e14b3f25..ba59cb69b 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm69/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm69/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c index 4e77b7fb9..29a01d405 100644 --- a/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c +++ b/ports/atmel-samd/boards/feather_m0_rfm9x/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_m0_supersized/pins.c b/ports/atmel-samd/boards/feather_m0_supersized/pins.c index cd6c351d4..1eaa98a58 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/pins.c +++ b/ports/atmel-samd/boards/feather_m0_supersized/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c b/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c index cd111e174..211596f78 100755 --- a/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c +++ b/ports/atmel-samd/boards/feather_radiofruit_zigbee/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB02) }, diff --git a/ports/atmel-samd/boards/gemma_m0/pins.c b/ports/atmel-samd/boards/gemma_m0/pins.c index c9c7ea555..b24b45838 100644 --- a/ports/atmel-samd/boards/gemma_m0/pins.c +++ b/ports/atmel-samd/boards/gemma_m0/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA05) }, // pad 1 diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index b47c5fbb2..2b12ae464 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -27,6 +27,7 @@ #include "boards/board.h" #include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" #include "shared-module/displayio/mipi_constants.h" #include "tick.h" @@ -68,13 +69,18 @@ uint8_t display_init_sequence[] = { }; void board_init(void) { - board_display_obj.base.type = &displayio_fourwire_type; - common_hal_displayio_fourwire_construct(&board_display_obj, - &pin_PB23, // Clock - &pin_PB22, // Data + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + board_spi(), &pin_PA28, // Command or data &pin_PA01, // Chip select - &pin_PA27, // Reset + &pin_PA27); // Reset + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, 128, // Width 128, // Height 2, // column start @@ -82,33 +88,9 @@ void board_init(void) { 16, // Color depth MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command - MIPI_COMMAND_WRITE_MEMORY_START); // Write memory command - - uint32_t i = 0; - common_hal_displayio_fourwire_begin_transaction(&board_display_obj); - while (i < sizeof(display_init_sequence)) { - uint8_t *cmd = display_init_sequence + i; - uint8_t data_size = *(cmd + 1); - bool delay = (data_size & DELAY) != 0; - data_size &= ~DELAY; - uint8_t *data = cmd + 2; - common_hal_displayio_fourwire_send(&board_display_obj, true, cmd, 1); - common_hal_displayio_fourwire_send(&board_display_obj, false, data, data_size); - if (delay) { - data_size++; - uint16_t delay_length_ms = *(cmd + 1 + data_size); - if (delay_length_ms == 255) { - delay_length_ms = 500; - } - uint64_t start = ticks_ms; - while (ticks_ms - start < delay_length_ms) {} - } else { - uint64_t start = ticks_ms; - while (ticks_ms - start < 10) {} - } - i += 2 + data_size; - } - common_hal_displayio_fourwire_end_transaction(&board_display_obj); + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence)); } bool board_requests_safe_mode(void) { @@ -116,5 +98,4 @@ bool board_requests_safe_mode(void) { } void reset_board(void) { - common_hal_displayio_fourwire_show(&board_display_obj, NULL); } diff --git a/ports/atmel-samd/boards/hallowing_m0_express/pins.c b/ports/atmel-samd/boards/hallowing_m0_express/pins.c index d1f8609ff..3db1b1752 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/pins.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/pins.c @@ -1,7 +1,8 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" +#include "shared-module/displayio/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, @@ -62,6 +63,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, - { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&board_display_obj)} + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c index 25407bc14..912fba4ed 100644 --- a/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m0_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c index 2a89c3037..ed91c88ee 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/meowmeow/pins.c b/ports/atmel-samd/boards/meowmeow/pins.c index 59c51f4eb..089baad32 100644 --- a/ports/atmel-samd/boards/meowmeow/pins.c +++ b/ports/atmel-samd/boards/meowmeow/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/metro_m0_express/pins.c b/ports/atmel-samd/boards/metro_m0_express/pins.c index 13f0eb0ba..0707a3581 100644 --- a/ports/atmel-samd/boards/metro_m0_express/pins.c +++ b/ports/atmel-samd/boards/metro_m0_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c index 0e66817f7..dd419aec6 100644 --- a/ports/atmel-samd/boards/metro_m4_express/pins.c +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/mini_sam_m4/pins.c b/ports/atmel-samd/boards/mini_sam_m4/pins.c index 87e210381..f78fe1bc8 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/pins.c +++ b/ports/atmel-samd/boards/mini_sam_m4/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/pirkey_m0/pins.c b/ports/atmel-samd/boards/pirkey_m0/pins.c index e08302f14..a6dbcefe3 100644 --- a/ports/atmel-samd/boards/pirkey_m0/pins.c +++ b/ports/atmel-samd/boards/pirkey_m0/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_REMOTEIN), MP_ROM_PTR(&pin_PA28) }, diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index cf03bb28a..6e5b37dd2 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -64,12 +64,14 @@ uint8_t display_init_sequence[] = { }; void board_init(void) { - displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; - bus->base.type = &displayio_fourwire_type; - common_hal_displayio_fourwire_construct(bus, - board_spi(), - &pin_PB09, // Command or data + displayio_parallelbus_obj_t* bus = &displays[0].parallel_bus; + bus->base.type = &displayio_parallelbus_type; + common_hal_displayio_parallelbus_construct(bus, + &pin_PA16, // Data0 + &pin_PB05, // Command or data &pin_PB06, // Chip select + &pin_PB09, // Write + &pin_PB04, // Read &pin_PA00); // Reset displayio_display_obj_t* display = &displays[0].display; diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index 4ddc10e52..6b1254dfc 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -1,6 +1,7 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken @@ -72,5 +73,7 @@ STATIC const mp_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c index abe63d064..42cd3736b 100644 --- a/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c +++ b/ports/atmel-samd/boards/sparkfun_samd21_mini/pins.c @@ -1,15 +1,15 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { - + // Analog pins { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA04) }, - + // Digital pins { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA11) }, { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA10) }, @@ -25,16 +25,16 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, - + // UART pins - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA11) }, - + // SPI pins { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA16) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA19) }, - + // I2C pins { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA23) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA22) }, @@ -44,7 +44,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA17) }, { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA27) }, { MP_ROM_QSTR(MP_QSTR_YELLOW_LED), MP_ROM_PTR(&pin_PB03) }, - + // Comm objects { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/atmel-samd/boards/trellis_m4_express/pins.c b/ports/atmel-samd/boards/trellis_m4_express/pins.c index 9626f525f..a9f204318 100644 --- a/ports/atmel-samd/boards/trellis_m4_express/pins.c +++ b/ports/atmel-samd/boards/trellis_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/trinket_m0/pins.c b/ports/atmel-samd/boards/trinket_m0/pins.c index 633017024..b3637bd5b 100644 --- a/ports/atmel-samd/boards/trinket_m0/pins.c +++ b/ports/atmel-samd/boards/trinket_m0/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c index 633017024..b3637bd5b 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA08) }, diff --git a/ports/atmel-samd/boards/ugame10/pins.c b/ports/atmel-samd/boards/ugame10/pins.c index 87ace5e96..71db52752 100644 --- a/ports/atmel-samd/boards/ugame10/pins.c +++ b/ports/atmel-samd/boards/ugame10/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_X), MP_ROM_PTR(&pin_PA00) }, diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c index f852647a4..3c287eccd 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.c +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -35,8 +35,8 @@ #include "tick.h" void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, - const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write) { + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { uint8_t data_pin = data0->number; if (data_pin % 8 != 0 || data_pin % 32 >= 24) { @@ -47,8 +47,8 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); } } - PortGroup *const g = &PORT->Group[data0->number % 32]; - g->DIRSET.reg = 0xff << data_pin; + PortGroup *const g = &PORT->Group[data0->number / 32]; + g->DIRSET.reg = 0xff << (data_pin % 32); self->bus = ((uint8_t*) &g->OUT.reg) + (data0->number % 32 / 8); self->command.base.type = &digitalio_digitalinout_type; @@ -67,15 +67,36 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel common_hal_digitalio_digitalinout_construct(&self->write, write); common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + self->write_group = &PORT->Group[write->number / 32]; + self->write_mask = 1 << (write->number % 32); + never_reset_pin_number(command->number); never_reset_pin_number(chip_select->number); - never_reset_pin_number(reset->number); never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + never_reset_pin_number(reset->number); for (uint8_t i = 0; i < 8; i++) { never_reset_pin_number(data_pin + i); } } +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); +} + bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); @@ -85,10 +106,13 @@ bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); common_hal_digitalio_digitalinout_set_value(&self->command, !command); + uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR.reg; + uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET.reg; + uint32_t mask = self->write_mask; for (uint32_t i = 0; i < data_length; i++) { - common_hal_digitalio_digitalinout_set_value(&self->write, false); + *clear_write = mask; *self->bus = data[i]; - common_hal_digitalio_digitalinout_set_value(&self->write, true); + *set_write = mask; } } diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.h b/ports/atmel-samd/common-hal/displayio/ParallelBus.h index cc45598c5..630bec351 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.h +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.h @@ -36,6 +36,10 @@ typedef struct { digitalio_digitalinout_obj_t chip_select; digitalio_digitalinout_obj_t reset; digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; + PortGroup* write_group; + uint32_t write_mask; } displayio_parallelbus_obj_t; #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 77881fefd..a2e4075c4 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -282,6 +282,7 @@ extern const struct _mp_obj_module_t wiznet_module; #endif #ifdef CIRCUITPY_DISPLAYIO + #define CIRCUITPY_DISPLAY_LIMIT (3) #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #else #define DISPLAYIO_MODULE diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index dddb4ce8a..aa861bb81 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -34,6 +34,7 @@ #include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/translate.h" //| .. currentmodule:: displayio @@ -46,13 +47,54 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: ParallelBus(*, data0, command, chip_select, reset, write, bus_width=8) +//| .. class:: ParallelBus(*, data0, command, chip_select, write, read, reset) //| -//| Create a ParallelBus object associated with the given pins. +//| Create a ParallelBus object associated with the given pins. The bus is inferred from data0 +//| by implying the next 7 additional pins on a given GPIO port. //| STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_raise_NotImplementedError(translate("displayio is a work in progress")); - return mp_const_none; + enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t data0 = args[ARG_data0].u_obj; + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + mp_obj_t write = args[ARG_write].u_obj; + mp_obj_t read = args[ARG_read].u_obj; + mp_obj_t reset = args[ARG_reset].u_obj; + if (data0 == mp_const_none || command == mp_const_none || chip_select == mp_const_none || write == mp_const_none || read == mp_const_none) { + mp_raise_ValueError(translate("Data0, command, chip_select, write and read required")); + } + assert_pin_free(data0); + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(write); + assert_pin_free(read); + assert_pin_free(reset); + + displayio_parallelbus_obj_t* self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].parallel_bus.base.type== NULL) { + self = &displays[i].parallel_bus; + self->base.type = &displayio_parallelbus_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display bus limit reached")); + } + + common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); + return self; } diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h index c73934838..c4cde5ff5 100644 --- a/shared-bindings/displayio/ParallelBus.h +++ b/shared-bindings/displayio/ParallelBus.h @@ -35,8 +35,8 @@ extern const mp_obj_type_t displayio_parallelbus_type; void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, - const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset); void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 66cf4d63d..306f8c08b 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -37,6 +37,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/displayio/Shape.h" #include "shared-bindings/displayio/Sprite.h" @@ -67,6 +68,7 @@ //| Group //| OnDiskBitmap //| Palette +//| ParallelBus //| Shape //| Sprite //| @@ -96,6 +98,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, + { MP_ROM_QSTR(MP_QSTR_ParallelBus), MP_ROM_PTR(&displayio_parallelbus_type) }, { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, }; diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 0a14e74bb..f75f0392f 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -113,10 +113,10 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16 uint16_t data[2]; self->send(self->bus, true, &self->set_column_command, 1); data[0] = __builtin_bswap16(x0 + self->colstart); - data[1] = __builtin_bswap16(x1 + self->colstart); + data[1] = __builtin_bswap16(x1 - 1 + self->colstart); self->send(self->bus, false, (uint8_t*) data, 4); self->send(self->bus, true, &self->set_row_command, 1); - data[0] = __builtin_bswap16(y0 + self->rowstart); + data[0] = __builtin_bswap16(y0 + 1 + self->rowstart); data[1] = __builtin_bswap16(y1 + self->rowstart); self->send(self->bus, false, (uint8_t*) data, 4); self->send(self->bus, true, &self->write_ram_command, 1); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index dc5957c23..92d97a6ef 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -7,6 +7,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/Sprite.h" +#include "supervisor/usb.h" primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; @@ -21,8 +22,6 @@ void displayio_refresh_displays(void) { return; } if (displayio_display_refresh_queued(display)) { - PORT->Group[1].DIRSET.reg = 1 << 22; - // We compute the pixels uint16_t x0 = 0; uint16_t y0 = 0; @@ -38,8 +37,6 @@ void displayio_refresh_displays(void) { uint16_t* pixel = &(((uint16_t*)buffer)[index]); *pixel = 0; - PORT->Group[1].OUTTGL.reg = 1 << 22; - //if (index == 0) { if (display->current_group != NULL) { displayio_group_get_pixel(display->current_group, x, y, pixel); @@ -48,9 +45,6 @@ void displayio_refresh_displays(void) { // *pixel = (((uint16_t*)buffer)[0]); // } - - PORT->Group[1].OUTTGL.reg = 1 << 22; - index += 1; // The buffer is full, send it. if (index >= buffer_size) { @@ -58,6 +52,9 @@ void displayio_refresh_displays(void) { displayio_display_finish_region_update(display); return; } + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + usb_background(); index = 0; } } @@ -182,12 +179,12 @@ void common_hal_displayio_release_displays(void) { } else if (bus_type == &displayio_fourwire_type) { common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); } else if (bus_type == &displayio_parallelbus_type) { - //common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); } - displays[i].fourwire_bus.base.type = NULL; + displays[i].fourwire_bus.base.type = &mp_type_NoneType; } for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - displays[i].display.base.type = NULL; + displays[i].display.base.type = &mp_type_NoneType; } // TODO(tannewt): Clear the display datastructures and release everything used. } -- cgit v1.2.3 From 760bd8d8a4f0aa0ed8651e89596fb2e6effbc14f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 15:15:59 -0800 Subject: share fourwire and make nrf compile --- ports/atmel-samd/Makefile | 2 +- ports/atmel-samd/common-hal/displayio/FourWire.c | 87 ------------- ports/atmel-samd/common-hal/displayio/FourWire.h | 43 ------- ports/nrf/Makefile | 12 +- ports/nrf/board_busses.c | 114 ----------------- ports/nrf/board_busses.h | 39 ------ ports/nrf/boards/feather_nrf52840_express/pins.c | 4 +- ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c | 2 +- .../makerdiary_nrf52840_mdk_usb_dongle/pins.c | 2 +- ports/nrf/boards/particle_argon/pins.c | 2 +- ports/nrf/boards/particle_boron/pins.c | 2 +- ports/nrf/boards/particle_xenon/pins.c | 2 +- ports/nrf/boards/pca10056/pins.c | 2 +- ports/nrf/boards/pca10059/pins.c | 2 +- ports/nrf/boards/sparkfun_nrf52840_mini/pins.c | 2 +- ports/nrf/common-hal/displayio/ParallelBus.c | 137 +++++++++++++++++++++ ports/nrf/common-hal/displayio/ParallelBus.h | 45 +++++++ ports/nrf/common-hal/microcontroller/Pin.h | 1 + ports/nrf/mpconfigport.h | 2 + shared-bindings/displayio/FourWire.h | 2 +- shared-module/displayio/FourWire.c | 87 +++++++++++++ shared-module/displayio/FourWire.h | 43 +++++++ supervisor/shared/board_busses.c | 1 - 23 files changed, 338 insertions(+), 297 deletions(-) delete mode 100644 ports/atmel-samd/common-hal/displayio/FourWire.c delete mode 100644 ports/atmel-samd/common-hal/displayio/FourWire.h delete mode 100644 ports/nrf/board_busses.c delete mode 100644 ports/nrf/board_busses.h create mode 100644 ports/nrf/common-hal/displayio/ParallelBus.c create mode 100644 ports/nrf/common-hal/displayio/ParallelBus.h create mode 100644 shared-module/displayio/FourWire.c create mode 100644 shared-module/displayio/FourWire.h (limited to 'shared-bindings') diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 088288fbd..c8d197b3e 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -305,7 +305,6 @@ SRC_COMMON_HAL = \ busio/UART.c \ digitalio/__init__.c \ digitalio/DigitalInOut.c \ - displayio/FourWire.c \ displayio/ParallelBus.c \ i2cslave/__init__.c \ i2cslave/I2CSlave.c \ @@ -380,6 +379,7 @@ SRC_SHARED_MODULE = \ displayio/Bitmap.c \ displayio/ColorConverter.c \ displayio/Display.c \ + displayio/FourWire.c \ displayio/Group.c \ displayio/OnDiskBitmap.c \ displayio/Palette.c \ diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c deleted file mode 100644 index ab01e2609..000000000 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/displayio/FourWire.h" - -#include - -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/digitalio/DigitalInOut.h" - -#include "tick.h" - -void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, - busio_spi_obj_t* spi, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset) { - - self->bus = spi; - common_hal_busio_spi_never_reset(self->bus); - - common_hal_digitalio_digitalinout_construct(&self->command, command); - common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); - common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); - common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); - - common_hal_digitalio_digitalinout_construct(&self->reset, reset); - common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); - - never_reset_pin_number(command->number); - never_reset_pin_number(chip_select->number); - never_reset_pin_number(reset->number); -} - -void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { - if (self->bus == &self->inline_bus) { - common_hal_busio_spi_deinit(self->bus); - } - - reset_pin_number(self->command.pin->number); - reset_pin_number(self->chip_select.pin->number); - reset_pin_number(self->reset.pin->number); -} - -bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { - displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); - if (!common_hal_busio_spi_try_lock(self->bus)) { - return false; - } - // TODO(tannewt): Stop hardcoding SPI frequency, polarity and phase. - common_hal_busio_spi_configure(self->bus, 12000000, 0, 0, 8); - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); - return true; -} - -void common_hal_displayio_fourwire_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { - displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); - common_hal_digitalio_digitalinout_set_value(&self->command, !command); - common_hal_busio_spi_write(self->bus, data, data_length); -} - -void common_hal_displayio_fourwire_end_transaction(mp_obj_t obj) { - displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); - common_hal_busio_spi_unlock(self->bus); -} diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.h b/ports/atmel-samd/common-hal/displayio/FourWire.h deleted file mode 100644 index 234bcf794..000000000 --- a/ports/atmel-samd/common-hal/displayio/FourWire.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H - -#include "common-hal/busio/SPI.h" -#include "common-hal/digitalio/DigitalInOut.h" -#include "shared-module/displayio/Group.h" - -typedef struct { - mp_obj_base_t base; - busio_spi_obj_t* bus; - busio_spi_obj_t inline_bus; - digitalio_digitalinout_obj_t command; - digitalio_digitalinout_obj_t chip_select; - digitalio_digitalinout_obj_t reset; -} displayio_fourwire_obj_t; - -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2bc508475..85e6346a1 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -118,7 +118,6 @@ SRC_C += \ fatfs_port.c \ mphalport.c \ tick.c \ - board_busses.c \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ @@ -156,6 +155,7 @@ SRC_COMMON_HAL += \ busio/__init__.c\ digitalio/DigitalInOut.c \ digitalio/__init__.c \ + displayio/ParallelBus.c \ microcontroller/Pin.c \ microcontroller/Processor.c \ microcontroller/__init__.c \ @@ -214,6 +214,16 @@ SRC_SHARED_MODULE = \ bitbangio/OneWire.c \ bitbangio/SPI.c \ busio/OneWire.c \ + displayio/__init__.c \ + displayio/Bitmap.c \ + displayio/ColorConverter.c \ + displayio/Display.c \ + displayio/FourWire.c \ + displayio/Group.c \ + displayio/OnDiskBitmap.c \ + displayio/Palette.c \ + displayio/Shape.c \ + displayio/Sprite.c \ storage/__init__.c # uheap/__init__.c \ diff --git a/ports/nrf/board_busses.c b/ports/nrf/board_busses.c deleted file mode 100644 index 6d5cbd041..000000000 --- a/ports/nrf/board_busses.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/busio/I2C.h" -#include "shared-bindings/busio/SPI.h" -#include "shared-bindings/busio/UART.h" - -#include "shared-bindings/microcontroller/Pin.h" -#include "supervisor/shared/translate.h" -#include "nrf/pins.h" -#include "py/mpconfig.h" -#include "py/runtime.h" - -#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL) - STATIC mp_obj_t board_i2c(void) { - mp_raise_NotImplementedError(translate("No default I2C bus")); - return NULL; - } -#else - STATIC mp_obj_t i2c_singleton = NULL; - - STATIC mp_obj_t board_i2c(void) { - - if (i2c_singleton == NULL) { - busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); - self->base.type = &busio_i2c_type; - - assert_pin_free(DEFAULT_I2C_BUS_SDA); - assert_pin_free(DEFAULT_I2C_BUS_SCL); - common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0); - i2c_singleton = (mp_obj_t)self; - } - return i2c_singleton; - - } -#endif -MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); - -#if !defined(DEFAULT_SPI_BUS_SCK) || !defined(DEFAULT_SPI_BUS_MISO) || !defined(DEFAULT_SPI_BUS_MOSI) - STATIC mp_obj_t board_spi(void) { - mp_raise_NotImplementedError(translate("No default SPI bus")); - return NULL; - } -#else - STATIC mp_obj_t spi_singleton = NULL; - - STATIC mp_obj_t board_spi(void) { - - if (spi_singleton == NULL) { - busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); - self->base.type = &busio_spi_type; - assert_pin_free(DEFAULT_SPI_BUS_SCK); - assert_pin_free(DEFAULT_SPI_BUS_MOSI); - assert_pin_free(DEFAULT_SPI_BUS_MISO); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); - common_hal_busio_spi_construct(self, clock, mosi, miso); - spi_singleton = (mp_obj_t)self; - } - return spi_singleton; - } -#endif -MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); - -#if !defined(DEFAULT_UART_BUS_RX) || !defined(DEFAULT_UART_BUS_TX) - STATIC mp_obj_t board_uart(void) { - mp_raise_NotImplementedError(translate("No default UART bus")); - return NULL; - } -#else - STATIC mp_obj_t uart_singleton = NULL; - - STATIC mp_obj_t board_uart(void) { - if (uart_singleton == NULL) { - busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); - self->base.type = &busio_uart_type; - - assert_pin_free(DEFAULT_UART_BUS_RX); - assert_pin_free(DEFAULT_UART_BUS_TX); - - const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX); - const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX); - - common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64); - uart_singleton = (mp_obj_t)self; - } - return uart_singleton; - } -#endif -MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart); diff --git a/ports/nrf/board_busses.h b/ports/nrf/board_busses.h deleted file mode 100644 index 2a4bfc3d4..000000000 --- a/ports/nrf/board_busses.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MICROPY_INCLUDED_NRF_BOARD_BUSSES_H -#define MICROPY_INCLUDED_NRF_BOARD_BUSSES_H - -void board_i2c(void); -extern mp_obj_fun_builtin_fixed_t board_i2c_obj; - -void board_spi(void); -extern mp_obj_fun_builtin_fixed_t board_spi_obj; - -void board_uart(void); -extern mp_obj_fun_builtin_fixed_t board_uart_obj; - -#endif // MICROPY_INCLUDED_NRF_BOARD_BUSSES_H diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index 2f8ac0259..dfb0be6df 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, @@ -44,7 +44,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, - + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, }; diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c index 27f0c6797..2d24e8597 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, diff --git a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c index 6049ac053..10490c8cb 100644 --- a/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c +++ b/ports/nrf/boards/makerdiary_nrf52840_mdk_usb_dongle/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) }, diff --git a/ports/nrf/boards/particle_argon/pins.c b/ports/nrf/boards/particle_argon/pins.c index 0457f0aa8..8c2fb38e6 100644 --- a/ports/nrf/boards/particle_argon/pins.c +++ b/ports/nrf/boards/particle_argon/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, diff --git a/ports/nrf/boards/particle_boron/pins.c b/ports/nrf/boards/particle_boron/pins.c index 2bff0a2ce..5981212bf 100644 --- a/ports/nrf/boards/particle_boron/pins.c +++ b/ports/nrf/boards/particle_boron/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, diff --git a/ports/nrf/boards/particle_xenon/pins.c b/ports/nrf/boards/particle_xenon/pins.c index 11a29e927..cdd5b5306 100644 --- a/ports/nrf/boards/particle_xenon/pins.c +++ b/ports/nrf/boards/particle_xenon/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_03) }, diff --git a/ports/nrf/boards/pca10056/pins.c b/ports/nrf/boards/pca10056/pins.c index a57c9d1c9..510b6100e 100644 --- a/ports/nrf/boards/pca10056/pins.c +++ b/ports/nrf/boards/pca10056/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, diff --git a/ports/nrf/boards/pca10059/pins.c b/ports/nrf/boards/pca10059/pins.c index a1916bd04..c43d3a9eb 100644 --- a/ports/nrf/boards/pca10059/pins.c +++ b/ports/nrf/boards/pca10059/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, diff --git a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c index 5c50f55c7..f826ac771 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c +++ b/ports/nrf/boards/sparkfun_nrf52840_mini/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P1_15) }, // D1/TX diff --git a/ports/nrf/common-hal/displayio/ParallelBus.c b/ports/nrf/common-hal/displayio/ParallelBus.c new file mode 100644 index 000000000..3afedf736 --- /dev/null +++ b/ports/nrf/common-hal/displayio/ParallelBus.c @@ -0,0 +1,137 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/displayio/ParallelBus.h" + +#include + +#include "common-hal/microcontroller/Pin.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "tick.h" + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { + + uint8_t data_pin = data0->number; + if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); + } + for (uint8_t i = 0; i < 8; i++) { + if (!pin_number_is_free(data_pin + i)) { + mp_raise_ValueError_varg(translate("Bus pin %d is already in use"), i); + } + } + NRF_GPIO_Type *g; + uint8_t num_pins_in_port; + if (data0->number < P0_PIN_NUM) { + g = NRF_P0; + num_pins_in_port = P0_PIN_NUM; + } else { + g = NRF_P1; + num_pins_in_port = P1_PIN_NUM; + } + g->DIRSET = 0xff << (data_pin % num_pins_in_port); + self->bus = ((uint8_t*) &g->OUT) + (data0->number % num_pins_in_port / 8); + + self->command.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + + self->chip_select.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + self->reset.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + + self->write.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->write, write); + common_hal_digitalio_digitalinout_switch_to_output(&self->write, true, DRIVE_MODE_PUSH_PULL); + + self->read.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->read, read); + common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL); + + self->data0_pin = data_pin; + uint8_t num_pins_in_write_port; + if (data0->number < P0_PIN_NUM) { + self->write_group = NRF_P0; + num_pins_in_write_port = P0_PIN_NUM; + } else { + self->write_group = NRF_P1; + num_pins_in_write_port = P1_PIN_NUM; + } + self->write_mask = 1 << (write->number % num_pins_in_write_port); + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(write->number); + never_reset_pin_number(read->number); + never_reset_pin_number(reset->number); + for (uint8_t i = 0; i < 8; i++) { + never_reset_pin_number(data_pin + i); + } +} + +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self) { + for (uint8_t i = 0; i < 8; i++) { + reset_pin_number(self->data0_pin + i); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->write.pin->number); + reset_pin_number(self->read.pin->number); + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +void common_hal_displayio_parallelbus_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, !command); + uint32_t* clear_write = (uint32_t*) &self->write_group->OUTCLR; + uint32_t* set_write = (uint32_t*) &self->write_group->OUTSET; + uint32_t mask = self->write_mask; + for (uint32_t i = 0; i < data_length; i++) { + *clear_write = mask; + *self->bus = data[i]; + *set_write = mask; + } +} + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t obj) { + displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); +} diff --git a/ports/nrf/common-hal/displayio/ParallelBus.h b/ports/nrf/common-hal/displayio/ParallelBus.h new file mode 100644 index 000000000..5c10d3d42 --- /dev/null +++ b/ports/nrf/common-hal/displayio/ParallelBus.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H + +#include "common-hal/digitalio/DigitalInOut.h" + +typedef struct { + mp_obj_base_t base; + uint8_t* bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; + digitalio_digitalinout_obj_t write; + digitalio_digitalinout_obj_t read; + uint8_t data0_pin; + NRF_GPIO_Type* write_group; + uint32_t write_mask; +} displayio_parallelbus_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_DISPLAYIO_PARALLELBUS_H diff --git a/ports/nrf/common-hal/microcontroller/Pin.h b/ports/nrf/common-hal/microcontroller/Pin.h index 61be8bc35..735ed90cc 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.h +++ b/ports/nrf/common-hal/microcontroller/Pin.h @@ -44,6 +44,7 @@ void reset_all_pins(void); // need to store a full pointer. void reset_pin_number(uint8_t pin); void claim_pin(const mcu_pin_obj_t* pin); +bool pin_number_is_free(uint8_t pin_number); void never_reset_pin_number(uint8_t pin_number); // Lower 5 bits of a pin number are the pin number in a port. diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index d38b14578..b6e5f9fdf 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -235,5 +235,7 @@ void run_background_tasks(void); //#define CIRCUITPY_BOOT_OUTPUT_FILE "/boot_out.txt" #define CIRCUITPY_DEFAULT_STACK_SIZE 4096 +#define CIRCUITPY_DISPLAYIO (1) +#define CIRCUITPY_DISPLAY_LIMIT (3) #endif diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index 3a9f66d4c..b8b00372c 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H -#include "common-hal/displayio/FourWire.h" +#include "shared-module/displayio/FourWire.h" #include "common-hal/microcontroller/Pin.h" #include "shared-module/displayio/Group.h" diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c new file mode 100644 index 000000000..ab01e2609 --- /dev/null +++ b/shared-module/displayio/FourWire.c @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/displayio/FourWire.h" + +#include + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "tick.h" + +void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset) { + + self->bus = spi; + common_hal_busio_spi_never_reset(self->bus); + + common_hal_digitalio_digitalinout_construct(&self->command, command); + common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + + never_reset_pin_number(command->number); + never_reset_pin_number(chip_select->number); + never_reset_pin_number(reset->number); +} + +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { + if (self->bus == &self->inline_bus) { + common_hal_busio_spi_deinit(self->bus); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->reset.pin->number); +} + +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + if (!common_hal_busio_spi_try_lock(self->bus)) { + return false; + } + // TODO(tannewt): Stop hardcoding SPI frequency, polarity and phase. + common_hal_busio_spi_configure(self->bus, 12000000, 0, 0, 8); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + return true; +} + +void common_hal_displayio_fourwire_send(mp_obj_t obj, bool command, uint8_t *data, uint32_t data_length) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->command, !command); + common_hal_busio_spi_write(self->bus, data, data_length); +} + +void common_hal_displayio_fourwire_end_transaction(mp_obj_t obj) { + displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + common_hal_busio_spi_unlock(self->bus); +} diff --git a/shared-module/displayio/FourWire.h b/shared-module/displayio/FourWire.h new file mode 100644 index 000000000..234bcf794 --- /dev/null +++ b/shared-module/displayio/FourWire.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H + +#include "common-hal/busio/SPI.h" +#include "common-hal/digitalio/DigitalInOut.h" +#include "shared-module/displayio/Group.h" + +typedef struct { + mp_obj_base_t base; + busio_spi_obj_t* bus; + busio_spi_obj_t inline_bus; + digitalio_digitalinout_obj_t command; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t reset; +} displayio_fourwire_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DISPLAYIO_FOURWIRE_H diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index 84919ebff..38308ccee 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -31,7 +31,6 @@ #include "shared-bindings/microcontroller/Pin.h" #include "supervisor/shared/translate.h" #include "mpconfigboard.h" -#include "samd/pins.h" #include "py/runtime.h" #define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL)) -- cgit v1.2.3 From 6404aaf411d7fe5fd96f3a8cbf7a1cb7580a09e7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 17 Jan 2019 18:19:07 -0800 Subject: Fix up nrf and using board.SPI in FourWire --- main.c | 7 ++- ports/atmel-samd/background.c | 5 +- ports/atmel-samd/mpconfigport.h | 2 + ports/nrf/background.c | 15 ++++-- ports/nrf/boards/feather_nrf52840_express/pins.c | 68 +++++++++++++----------- ports/nrf/common-hal/microcontroller/Pin.c | 7 ++- ports/nrf/mpconfigport.h | 2 + shared-bindings/displayio/Display.c | 3 +- shared-bindings/displayio/FourWire.c | 11 ++-- shared-bindings/displayio/ParallelBus.c | 3 +- shared-module/displayio/FourWire.c | 8 +-- shared-module/displayio/__init__.c | 3 ++ supervisor/shared/board_busses.c | 25 +++++++-- supervisor/shared/board_busses.h | 6 +-- 14 files changed, 109 insertions(+), 56 deletions(-) (limited to 'shared-bindings') diff --git a/main.c b/main.c index 02c832e67..e137f7d47 100755 --- a/main.c +++ b/main.c @@ -27,7 +27,6 @@ #include #include -#include "shared-module/displayio/__init__.h" #include "extmod/vfs.h" #include "extmod/vfs_fat.h" @@ -62,6 +61,10 @@ #include "shared-module/network/__init__.h" #endif +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -200,8 +203,10 @@ bool run_code_py(safe_mode_t safe_mode) { serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); } } + #ifdef CIRCUITPY_DISPLAYIO // Turn off the display before the heap disappears. reset_displays(); + #endif stop_mp(); free_memory(heap); diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 59e03008a..4f3257f3f 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -30,10 +30,13 @@ #include "supervisor/usb.h" #include "py/runtime.h" -#include "shared-module/displayio/__init__.h" #include "shared-module/network/__init__.h" #include "supervisor/shared/stack.h" +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + volatile uint64_t last_finished_tick = 0; bool stack_ok_so_far = true; diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index a2e4075c4..12410b0be 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -285,6 +285,7 @@ extern const struct _mp_obj_module_t wiznet_module; #define CIRCUITPY_DISPLAY_LIMIT (3) #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #else + #define CIRCUITPY_DISPLAY_LIMIT (0) #define DISPLAYIO_MODULE #endif @@ -338,6 +339,7 @@ extern const struct _mp_obj_module_t wiznet_module; #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) + #define CIRCUITPY_DISPLAY_LIMIT (0) #endif // Disabled for now. diff --git a/ports/nrf/background.c b/ports/nrf/background.c index f022b5bc9..69c76fd06 100644 --- a/ports/nrf/background.c +++ b/ports/nrf/background.c @@ -24,15 +24,20 @@ * THE SOFTWARE. */ -#ifdef NRF52840 +#include "py/runtime.h" #include "supervisor/usb.h" -#endif - #include "supervisor/shared/stack.h" +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + void run_background_tasks(void) { - #ifdef NRF52840 - usb_background(); + usb_background(); + + #ifdef CIRCUITPY_DISPLAYIO + displayio_refresh_displays(); #endif + assert_heap_ok(); } diff --git a/ports/nrf/boards/feather_nrf52840_express/pins.c b/ports/nrf/boards/feather_nrf52840_express/pins.c index dfb0be6df..c6f643761 100644 --- a/ports/nrf/boards/feather_nrf52840_express/pins.c +++ b/ports/nrf/boards/feather_nrf52840_express/pins.c @@ -3,49 +3,53 @@ #include "supervisor/shared/board_busses.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, - { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, - { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) }, - { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_09) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, - { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nrf/common-hal/microcontroller/Pin.c b/ports/nrf/common-hal/microcontroller/Pin.c index 02847e150..268e2f75d 100644 --- a/ports/nrf/common-hal/microcontroller/Pin.c +++ b/ports/nrf/common-hal/microcontroller/Pin.c @@ -142,6 +142,11 @@ void claim_pin(const mcu_pin_obj_t* pin) { #endif } + +bool pin_number_is_free(uint8_t pin_number) { + return !(claimed_pins[nrf_pin_port(pin_number)] & (1 << nrf_relative_pin_number(pin_number))); +} + bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { #ifdef MICROPY_HW_NEOPIXEL if (pin == MICROPY_HW_NEOPIXEL) { @@ -163,5 +168,5 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { } #endif - return !(claimed_pins[nrf_pin_port(pin->number)] & (1 << nrf_relative_pin_number(pin->number))); + return pin_number_is_free(pin->number); } diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index b6e5f9fdf..3ec37960b 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -163,6 +163,7 @@ extern const struct _mp_obj_module_t microcontroller_module; extern const struct _mp_obj_module_t bitbangio_module; extern const struct _mp_obj_module_t analogio_module; extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t displayio_module; extern const struct _mp_obj_module_t pulseio_module; extern const struct _mp_obj_module_t busio_module; extern const struct _mp_obj_module_t board_module; @@ -195,6 +196,7 @@ extern const struct _mp_obj_module_t bleio_module; { MP_OBJ_NEW_QSTR (MP_QSTR_busio ), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_analogio ), (mp_obj_t)&analogio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_digitalio ), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR (MP_QSTR_displayio ), (mp_obj_t)&displayio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_pulseio ), (mp_obj_t)&pulseio_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_microcontroller ), (mp_obj_t)µcontroller_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_neopixel_write ), (mp_obj_t)&neopixel_write_module }, \ diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 21f44965e..9028c2865 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -83,7 +83,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a displayio_display_obj_t *self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL) { + if (displays[i].display.base.type == NULL || + displays[i].display.base.type == &mp_type_NoneType) { self = &displays[i].display; break; } diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 9833fbc64..530eafb51 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -65,18 +65,23 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mp_obj_t command = args[ARG_command].u_obj; mp_obj_t chip_select = args[ARG_chip_select].u_obj; - mp_obj_t reset = args[ARG_reset].u_obj; if (command == mp_const_none || chip_select == mp_const_none) { mp_raise_ValueError(translate("Command and chip_select required")); } assert_pin_free(command); assert_pin_free(chip_select); - assert_pin_free(reset); + mp_obj_t reset = args[ARG_reset].u_obj; + if (reset != mp_const_none) { + assert_pin_free(reset); + } else { + reset = NULL; + } displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].fourwire_bus.base.type== NULL) { + if (displays[i].fourwire_bus.base.type == NULL || + displays[i].fourwire_bus.base.type == &mp_type_NoneType) { self = &displays[i].fourwire_bus; self->base.type = &displayio_fourwire_type; break; diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index aa861bb81..e1079acb5 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -83,7 +83,8 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t displayio_parallelbus_obj_t* self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].parallel_bus.base.type== NULL) { + if (displays[i].parallel_bus.base.type== NULL || + displays[i].parallel_bus.base.type == &mp_type_NoneType) { self = &displays[i].parallel_bus; self->base.type = &displayio_parallelbus_type; break; diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c index ab01e2609..9da5c0701 100644 --- a/shared-module/displayio/FourWire.c +++ b/shared-module/displayio/FourWire.c @@ -45,12 +45,14 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); - common_hal_digitalio_digitalinout_construct(&self->reset, reset); - common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + if (reset != NULL) { + common_hal_digitalio_digitalinout_construct(&self->reset, reset); + common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + never_reset_pin_number(reset->number); + } never_reset_pin_number(command->number); never_reset_pin_number(chip_select->number); - never_reset_pin_number(reset->number); } void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 92d97a6ef..ccabe9c9d 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -151,6 +151,9 @@ void reset_displays(void) { if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) || ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { busio_spi_obj_t* original_spi = fourwire->bus; + if (original_spi == board_spi()) { + continue; + } memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); fourwire->bus = &fourwire->inline_bus; // Check for other displays that use the same spi bus and swap them too. diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index 38308ccee..ed1f98a58 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -33,6 +33,10 @@ #include "mpconfigboard.h" #include "py/runtime.h" +#ifdef CIRCUITPY_DISPLAYIO +#include "shared-module/displayio/__init__.h" +#endif + #define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL)) #define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI)) #define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX)) @@ -40,7 +44,7 @@ #if BOARD_I2C STATIC mp_obj_t i2c_singleton = NULL; -STATIC mp_obj_t board_i2c(void) { +mp_obj_t board_i2c(void) { if (i2c_singleton == NULL) { busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); @@ -54,7 +58,7 @@ STATIC mp_obj_t board_i2c(void) { return i2c_singleton; } #else -STATIC mp_obj_t board_i2c(void) { +mp_obj_t board_i2c(void) { mp_raise_NotImplementedError(translate("No default I2C bus")); return NULL; } @@ -91,7 +95,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); #if BOARD_UART STATIC mp_obj_t uart_singleton = NULL; -STATIC mp_obj_t board_uart(void) { +mp_obj_t board_uart(void) { if (uart_singleton == NULL) { busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; @@ -108,7 +112,7 @@ STATIC mp_obj_t board_uart(void) { return uart_singleton; } #else -STATIC mp_obj_t board_uart(void) { +mp_obj_t board_uart(void) { mp_raise_NotImplementedError(translate("No default UART bus")); return NULL; } @@ -121,7 +125,18 @@ void reset_board_busses(void) { i2c_singleton = NULL; #endif #if BOARD_SPI - spi_singleton = NULL; + bool display_using_spi = false; + #ifdef CIRCUITPY_DISPLAYIO + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.bus == spi_singleton) { + display_using_spi = true; + break; + } + } + #endif + if (!display_using_spi) { + spi_singleton = NULL; + } #endif #if BOARD_UART uart_singleton = NULL; diff --git a/supervisor/shared/board_busses.h b/supervisor/shared/board_busses.h index f6a8a4296..0ccb3ba6a 100644 --- a/supervisor/shared/board_busses.h +++ b/supervisor/shared/board_busses.h @@ -30,13 +30,13 @@ #include "py/obj.h" mp_obj_t board_i2c(void); -extern mp_obj_fun_builtin_fixed_t board_i2c_obj; +MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj); mp_obj_t board_spi(void); -extern mp_obj_fun_builtin_fixed_t board_spi_obj; +MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj); mp_obj_t board_uart(void); -extern mp_obj_fun_builtin_fixed_t board_uart_obj; +MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj); void reset_board_busses(void); -- cgit v1.2.3 From dc024cf411e5a77bffc3662aa581c667284e67e6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 12:59:23 -0800 Subject: Add a bit more to the docs --- shared-bindings/displayio/Display.c | 37 ++++++++++++++++++++++++++++++--- shared-bindings/displayio/FourWire.c | 5 +++++ shared-bindings/displayio/ParallelBus.c | 9 +++++++- shared-bindings/displayio/__init__.c | 11 +++++----- 4 files changed, 52 insertions(+), 10 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 9028c2865..501b96549 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -49,10 +49,41 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, -//| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) +//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c) //| -//| Create a Display object. +//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`). +//| +//| The ``init_sequence`` is bitbacked to minimize the ram impact. Every command begins with a +//| command byte followed by a byte to determine the parameter count and if a delay is need after. +//| When the top bit of the second byte is 1, the next byte will be the delay time in milliseconds. +//| The remaining 7 bits are the parameter count excluding any delay byte. The third through final +//| bytes are the remaining command parameters. The next byte will begin a new command definition. +//| Here is a portion of ILI9341 init code: +//| +//| .. code-block:: python +//| +//| init_sequence = (b"\xe1\x0f\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F" # Set Gamma +//| b"\x11\x80\x78"# Exit Sleep then delay 0x78 (120ms) +//| b"\x29\x80\x78"# Display on then delay 0x78 (120ms) +//| ) +//| display = displayio.Display(display_bus, init_sequence, width=320, height=240) +//| +//| The first command is 0xe1 with 15 (0xf) parameters following. The second and third are 0x11 and +//| 0x29 respectively with delays (0x80) of 120ms (0x78) and no parameters. Multiple byte literals +//| (b"") are merged together on load. The parens are needed to allow byte literals on subsequent +//| lines. +//| +//| :param displayio.FourWire or displayio.ParallelBus display_bus: The bus that the display is connected to +//| :param buffer init_sequence: Byte-packed initialization sequence. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays +//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) +//| :param int set_column_command: Command used to set the start and end columns to update +//| :param int set_row_command: Command used so set the start and end rows to update +//| :param int write_ram_command: Command used to write pixels values into the update region //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 530eafb51..561e2871e 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -52,6 +52,11 @@ //| //| Create a FourWire object associated with the given pins. //| +//| :param busio.SPI spi_bus: The SPI bus that make up the clock and data lines +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin reset: Reset pin +//| STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index e1079acb5..2f9967866 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -40,7 +40,7 @@ //| .. currentmodule:: displayio //| //| :class:`ParallelBus` -- Manage updating a display over SPI four wire protocol -//| ========================================================================== +//| ============================================================================== //| //| Manage updating a display over SPI four wire protocol in the background while Python code runs. //| It doesn't handle display initialization. @@ -52,6 +52,13 @@ //| Create a ParallelBus object associated with the given pins. The bus is inferred from data0 //| by implying the next 7 additional pins on a given GPIO port. //| +//| :param microcontroller.Pin: The first data pin. The rest are implied +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin write: Write pin +//| :param microcontroller.Pin read: Read pin +//| :param microcontroller.Pin reset: Reset pin +//| STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 306f8c08b..6ed1218b2 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -46,13 +46,10 @@ //| //| .. module:: displayio //| :synopsis: Native helpers for driving displays -//| :platform: SAMD21, SAMD51 +//| :platform: SAMD21, SAMD51, nRF52 //| //| The `displayio` module contains classes to manage display output -//| including synchronizing with refresh rates and partial updating. It does -//| not include display initialization commands. It should live in a Python -//| driver for use when a display is connected to a board. It should also be -//| built into the board init when the board has the display on it. +//| including synchronizing with refresh rates and partial updating. //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| @@ -78,7 +75,9 @@ //| .. method:: release_displays() //| -//| Releases any actively used displays so theis pins can be used again. +//| Releases any actively used displays so their busses and pins can be used again. This will also +//| release the builtin display on boards that have one. You will need to reinitialize it yourself +//| afterwards. //| STATIC mp_obj_t displayio_release_displays(void) { common_hal_displayio_release_displays(); -- cgit v1.2.3 From edc8383e2297156134a58067899eefacd5764802 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 16:37:06 -0800 Subject: Improvements thanks to danh's review --- ports/atmel-samd/common-hal/displayio/ParallelBus.c | 9 ++++++++- ports/nrf/common-hal/displayio/ParallelBus.c | 5 ++++- shared-bindings/displayio/Display.c | 6 +++--- shared-bindings/displayio/FourWire.c | 9 +++------ shared-bindings/displayio/ParallelBus.c | 15 ++++++--------- supervisor/shared/board_busses.c | 2 ++ 6 files changed, 26 insertions(+), 20 deletions(-) (limited to 'shared-bindings') diff --git a/ports/atmel-samd/common-hal/displayio/ParallelBus.c b/ports/atmel-samd/common-hal/displayio/ParallelBus.c index 3c287eccd..7a5f61448 100644 --- a/ports/atmel-samd/common-hal/displayio/ParallelBus.c +++ b/ports/atmel-samd/common-hal/displayio/ParallelBus.c @@ -39,7 +39,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { uint8_t data_pin = data0->number; - if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + if (data_pin % 8 != 0) { mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); } for (uint8_t i = 0; i < 8; i++) { @@ -49,6 +49,13 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel } PortGroup *const g = &PORT->Group[data0->number / 32]; g->DIRSET.reg = 0xff << (data_pin % 32); + uint32_t wrconfig = PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_DRVSTR; + if (data_pin % 32 > 15) { + wrconfig |= PORT_WRCONFIG_HWSEL | (0xff << ((data_pin % 32) - 16)); + } else { + wrconfig |= 0xff << (data_pin % 32); + } + g->WRCONFIG.reg = wrconfig; self->bus = ((uint8_t*) &g->OUT.reg) + (data0->number % 32 / 8); self->command.base.type = &digitalio_digitalinout_type; diff --git a/ports/nrf/common-hal/displayio/ParallelBus.c b/ports/nrf/common-hal/displayio/ParallelBus.c index 3afedf736..42231be52 100644 --- a/ports/nrf/common-hal/displayio/ParallelBus.c +++ b/ports/nrf/common-hal/displayio/ParallelBus.c @@ -39,7 +39,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset) { uint8_t data_pin = data0->number; - if (data_pin % 8 != 0 || data_pin % 32 >= 24) { + if (data_pin % 8 != 0) { mp_raise_ValueError(translate("Data 0 pin must be byte aligned")); } for (uint8_t i = 0; i < 8; i++) { @@ -57,6 +57,9 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel num_pins_in_port = P1_PIN_NUM; } g->DIRSET = 0xff << (data_pin % num_pins_in_port); + for (uint8_t i = 0; i < 8; i++) { + g->PIN_CNF[data_pin + i] |= NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos; + } self->bus = ((uint8_t*) &g->OUT) + (data0->number % num_pins_in_port / 8); self->command.base.type = &digitalio_digitalinout_type; diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 501b96549..4de6c2b24 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -90,8 +90,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, - { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, @@ -121,7 +121,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a } } if (self == NULL) { - mp_raise_RuntimeError(translate("Display limit reached")); + mp_raise_RuntimeError(translate("Too many displays")); } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 561e2871e..dceb4fe69 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -61,8 +61,8 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; static const mp_arg_t allowed_args[] = { { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -70,9 +70,6 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mp_obj_t command = args[ARG_command].u_obj; mp_obj_t chip_select = args[ARG_chip_select].u_obj; - if (command == mp_const_none || chip_select == mp_const_none) { - mp_raise_ValueError(translate("Command and chip_select required")); - } assert_pin_free(command); assert_pin_free(chip_select); mp_obj_t reset = args[ARG_reset].u_obj; @@ -93,7 +90,7 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ } } if (self == NULL) { - mp_raise_RuntimeError(translate("Display bus limit reached")); + mp_raise_RuntimeError(translate("Too many display busses")); } common_hal_displayio_fourwire_construct(self, diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 2f9967866..916c5f852 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -62,11 +62,11 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -78,9 +78,6 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t mp_obj_t write = args[ARG_write].u_obj; mp_obj_t read = args[ARG_read].u_obj; mp_obj_t reset = args[ARG_reset].u_obj; - if (data0 == mp_const_none || command == mp_const_none || chip_select == mp_const_none || write == mp_const_none || read == mp_const_none) { - mp_raise_ValueError(translate("Data0, command, chip_select, write and read required")); - } assert_pin_free(data0); assert_pin_free(command); assert_pin_free(chip_select); @@ -98,7 +95,7 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t } } if (self == NULL) { - mp_raise_RuntimeError(translate("Display bus limit reached")); + mp_raise_RuntimeError(translate("Too many display busses")); } common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); diff --git a/supervisor/shared/board_busses.c b/supervisor/shared/board_busses.c index ed1f98a58..8a1c7bf86 100644 --- a/supervisor/shared/board_busses.c +++ b/supervisor/shared/board_busses.c @@ -66,6 +66,8 @@ mp_obj_t board_i2c(void) { MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); #if BOARD_SPI +// Statically allocate the SPI object so it can live past the end of the heap and into the next VM. +// That way it can be used by built-in FourWire displays and be accessible through board.SPI(). STATIC busio_spi_obj_t spi_obj; STATIC mp_obj_t spi_singleton = NULL; -- cgit v1.2.3 From b41d386d02f26e81dc1f234826fde7d24b020531 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 18 Jan 2019 17:04:18 -0800 Subject: simplify arg checking for display --- shared-bindings/displayio/Display.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 4de6c2b24..d61732f6f 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -104,11 +104,6 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_obj_t display_bus = args[ARG_display_bus].u_obj; - mp_int_t width = args[ARG_width].u_int; - mp_int_t height = args[ARG_height].u_int; - if (width == -1 || height == -1) { - mp_raise_ValueError(translate("Width and height kwargs required")); - } mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); @@ -125,7 +120,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, - display_bus, width, height, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, + display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len); -- cgit v1.2.3