Add Bangle.js 2, JDI memory displays and ACeP epd
This 2-in-1 PR started with the goal of support the Bangle.js 2 smartwatch with *no USB*. * Adds "secure" DFU build support with a committed private key. * Adds 3-bit color support with one dummy bit for the JDI memory display * Allows nrf boards to have a board_background_task() run in RUN_BACKGROUND_TASK. This is needed because the Bangle.js 2 uses the watchdog to reset. * Renamed port_background_task() to port_background_tick() to indicate it runs on tick, not RUN_BACKGROUND_TASK. * Marks serial connected when the display terminal is inited. This means that safe mode messages show up on the display. ACep, 7-color epaper displays also pack 3 bits in 4. So, I added that support as well. * Adds 3-bit ACeP color support for 7-color e-paper displays. (Not watch related but similar due to color depth.) * Allows a refresh sequence instead of a single int command. The 7" ACeP display requires a data byte for refresh. * Adds optional delay after resetting the display. The ACeP displays need this. (Probably to load LUTs from flash.) * Adds a cleaning phase for ACeP displays before the real refresh. For both: * Add dither support to Palette. * Palette no longer converts colors when set. Instead, it caches converted colors at each index. * ColorConverter now caches the last converted color. It should make conversions faster for repeated colors (not dithering.)
This commit is contained in:
parent
ca24cff0d3
commit
931c7c1c51
|
@ -37,7 +37,7 @@ runs:
|
|||
|
||||
# arm
|
||||
- name: Get arm toolchain
|
||||
if: inputs.platform == 'aarch' || inputs.platform == 'arm'
|
||||
if: inputs.platform == 'aarch' || inputs.platform == 'arm' || inputs.platform == 'nrf'
|
||||
uses: carlosperate/arm-none-eabi-gcc-action@v1
|
||||
with:
|
||||
release: '10-2020-q4'
|
||||
|
@ -65,6 +65,22 @@ runs:
|
|||
echo >> $GITHUB_PATH "$PATH"
|
||||
shell: bash
|
||||
|
||||
# nrf
|
||||
- name: Get nrfutil 7+
|
||||
if: inputs.platform == 'nrf'
|
||||
run: |
|
||||
wget https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil
|
||||
chmod +x nrfutil
|
||||
./nrfutil install nrf5sdk-tools
|
||||
mkdir -p $HOME/.local/bin
|
||||
mv nrfutil $HOME/.local/bin
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- name: Print nrfutil version
|
||||
if: inputs.platform == 'nrf'
|
||||
run: nrfutil -V
|
||||
shell: bash
|
||||
|
||||
# riscv
|
||||
- name: Get riscv toolchain
|
||||
if: inputs.platform == 'riscv'
|
||||
|
|
|
@ -25,6 +25,7 @@ jobs:
|
|||
boards-aarch: ${{ steps.set-matrix.outputs.boards-aarch }}
|
||||
boards-arm: ${{ steps.set-matrix.outputs.boards-arm }}
|
||||
boards-esp: ${{ steps.set-matrix.outputs.boards-esp }}
|
||||
boards-nrf: ${{ steps.set-matrix.outputs.boards-nrf }}
|
||||
boards-riscv: ${{ steps.set-matrix.outputs.boards-riscv }}
|
||||
boards-rpi: ${{ steps.set-matrix.outputs.boards-rpi }}
|
||||
cp-version: ${{ steps.set-up-submodules.outputs.version }}
|
||||
|
@ -252,6 +253,16 @@ jobs:
|
|||
boards: ${{ needs.scheduler.outputs.boards-esp }}
|
||||
cp-version: ${{ needs.scheduler.outputs.cp-version }}
|
||||
|
||||
nrf:
|
||||
needs: [scheduler, mpy-cross, tests]
|
||||
if: ${{ needs.scheduler.outputs.boards-nrf != '[]' }}
|
||||
uses: ./.github/workflows/build-boards.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
platform: nrf
|
||||
boards: ${{ needs.scheduler.outputs.boards-nrf }}
|
||||
cp-version: ${{ needs.scheduler.outputs.cp-version }}
|
||||
|
||||
riscv:
|
||||
needs: [scheduler, mpy-cross, tests]
|
||||
if: ${{ needs.scheduler.outputs.boards-riscv != '[]' }}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 2d292ad4e67890d4b85b027431ba9fef7bf561fd
|
||||
Subproject commit 73fafcbe4c66b23df63be31e9227353b695abb08
|
|
@ -202,10 +202,6 @@ msgstr ""
|
|||
msgid "%q out of range"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/microcontroller/Pin.c
|
||||
msgid "%q pin invalid"
|
||||
msgstr ""
|
||||
|
||||
#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c
|
||||
msgid "%q step cannot be zero"
|
||||
msgstr ""
|
||||
|
@ -1210,9 +1206,11 @@ msgid "Internal watchdog timer expired."
|
|||
msgstr ""
|
||||
|
||||
#: py/argcheck.c shared-bindings/digitalio/DigitalInOut.c
|
||||
#: shared-bindings/displayio/EPaperDisplay.c
|
||||
msgid "Invalid %q"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/microcontroller/Pin.c
|
||||
#: shared-bindings/microcontroller/Pin.c
|
||||
msgid "Invalid %q pin"
|
||||
msgstr ""
|
||||
|
|
|
@ -57,5 +57,8 @@ void port_finish_background_task(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void port_background_tick(void) {
|
||||
}
|
||||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
|
|
|
@ -52,6 +52,10 @@ uint8_t stop_sequence[] = {
|
|||
0x02, 0x80, 0xf0 // Power off
|
||||
};
|
||||
|
||||
uint8_t refresh_sequence[] = {
|
||||
0x12, 0x00
|
||||
};
|
||||
|
||||
void board_init(void) {
|
||||
busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus;
|
||||
common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL, false);
|
||||
|
@ -74,6 +78,7 @@ void board_init(void) {
|
|||
bus,
|
||||
start_sequence,
|
||||
sizeof(start_sequence),
|
||||
0, // start up time
|
||||
stop_sequence,
|
||||
sizeof(stop_sequence),
|
||||
300, // width
|
||||
|
@ -92,13 +97,15 @@ void board_init(void) {
|
|||
NO_COMMAND, // write_color_ram_command (can add this for grayscale eventually)
|
||||
false, // color_bits_inverted
|
||||
0x000000, // highlight_color
|
||||
0x12, // refresh_display_command
|
||||
refresh_sequence, // refresh_display_sequence
|
||||
sizeof(refresh_sequence),
|
||||
40, // refresh_time
|
||||
&pin_PA01, // busy_pin
|
||||
false, // busy_state
|
||||
5, // seconds_per_frame
|
||||
false, // chip_select (don't always toggle chip select)
|
||||
false, // grayscale
|
||||
false, // acep
|
||||
false); // two_byte_sequence_length
|
||||
}
|
||||
|
||||
|
|
|
@ -53,3 +53,10 @@ CIRCUITPY_DISPLAY_FONT = $(TOP)/ports/atmel-samd/boards/ugame10/brutalist-6.bdf
|
|||
|
||||
# Override optimization to keep binary small
|
||||
OPTIMIZATION_FLAGS = -Os
|
||||
|
||||
# We don't have room for the fonts for terminalio for certain languages,
|
||||
# so turn off terminalio and force a clean build.
|
||||
ifneq (,$(filter $(TRANSLATION),ja ko ru))
|
||||
CIRCUITPY_TERMINALIO = 0
|
||||
RELEASE_NEEDS_CLEAN_BUILD = 1
|
||||
endif
|
||||
|
|
|
@ -211,5 +211,5 @@ mcu_pin_function_t *mcu_find_pin_function(mcu_pin_function_t *table, const mcu_p
|
|||
return table;
|
||||
}
|
||||
}
|
||||
mp_raise_ValueError_varg(translate("%q pin invalid"), name);
|
||||
mp_raise_ValueError_varg(translate("Invalid %q pin"), name);
|
||||
}
|
||||
|
|
|
@ -33,5 +33,8 @@ void port_start_background_task(void) {
|
|||
void port_finish_background_task(void) {
|
||||
}
|
||||
|
||||
void port_background_tick(void) {
|
||||
}
|
||||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "supervisor/filesystem.h"
|
||||
#include "supervisor/shared/stack.h"
|
||||
|
||||
void port_background_tick(void) {
|
||||
}
|
||||
void port_background_task(void) {
|
||||
}
|
||||
void port_start_background_task(void) {
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "common-hal/pulseio/PulseIn.h"
|
||||
#endif
|
||||
|
||||
void port_background_task(void) {
|
||||
void port_background_tick(void) {
|
||||
// Zero delay in case FreeRTOS wants to switch to something else.
|
||||
vTaskDelay(0);
|
||||
#if CIRCUITPY_PULSEIO
|
||||
|
@ -48,6 +48,9 @@ void port_background_task(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
|
||||
void port_start_background_task(void) {
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,10 @@ const uint8_t display_stop_sequence[] = {
|
|||
0x02, 0x00 // Power off
|
||||
};
|
||||
|
||||
const uint8_t refresh_sequence[] = {
|
||||
0x12, 0x00
|
||||
};
|
||||
|
||||
void board_init(void) {
|
||||
// Debug UART
|
||||
#ifdef DEBUG
|
||||
|
@ -137,6 +141,7 @@ void board_init(void) {
|
|||
display,
|
||||
bus,
|
||||
display_start_sequence, sizeof(display_start_sequence),
|
||||
0, // start up time
|
||||
display_stop_sequence, sizeof(display_stop_sequence),
|
||||
296, // width
|
||||
128, // height
|
||||
|
@ -154,13 +159,14 @@ void board_init(void) {
|
|||
0x13, // write_color_ram_command
|
||||
false, // color_bits_inverted
|
||||
0x000000, // highlight_color
|
||||
0x12, // refresh_display_command
|
||||
refresh_sequence, sizeof(refresh_sequence),
|
||||
1.0, // refresh_time
|
||||
&pin_GPIO5, // busy_pin
|
||||
false, // busy_state
|
||||
5.0, // seconds_per_frame
|
||||
false, // always_toggle_chip_select
|
||||
true, // grayscale
|
||||
false, // acep
|
||||
false); // two_byte_sequence_length
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
void port_background_tick(void) {
|
||||
}
|
||||
void port_start_background_task(void) {
|
||||
}
|
||||
void port_finish_background_task(void) {
|
||||
|
|
|
@ -28,10 +28,14 @@
|
|||
#include "supervisor/port.h"
|
||||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
|
||||
void port_background_tick(void) {
|
||||
#if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO
|
||||
audio_dma_background();
|
||||
#endif
|
||||
}
|
||||
|
||||
void port_start_background_task(void) {
|
||||
}
|
||||
void port_finish_background_task(void) {
|
||||
|
|
|
@ -275,7 +275,8 @@ endif
|
|||
#####################
|
||||
.phony: dfu-gen dfu-flash
|
||||
|
||||
NRFUTIL = adafruit-nrfutil
|
||||
NRFUTIL = nrfutil
|
||||
ADAFRUIT_NRFUTIL = adafruit-nrfutil
|
||||
|
||||
ifeq ($(MCU_SUB_VARIANT),nrf52840)
|
||||
DFU_TOUCH = --touch 1200
|
||||
|
@ -293,14 +294,19 @@ __check_defined = \
|
|||
## Flash with DFU serial
|
||||
dfu-flash: $(BUILD)/dfu-package.zip
|
||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0)
|
||||
$(NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank $(DFU_TOUCH)
|
||||
$(ADAFRUIT_NRFUTIL) --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank $(DFU_TOUCH)
|
||||
|
||||
## Create DFU package file
|
||||
dfu-gen: $(BUILD)/dfu-package.zip
|
||||
|
||||
$(BUILD)/dfu-package.zip: $(BUILD)/firmware.hex
|
||||
$(NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip
|
||||
$(ADAFRUIT_NRFUTIL) dfu genpkg --sd-req 0xFFFE --dev-type 0x0052 --application $^ $(BUILD)/dfu-package.zip
|
||||
|
||||
# Espruino DFU
|
||||
$(BUILD)/firmware.espruino.zip: $(BUILD)/firmware.hex
|
||||
$(Q)$(NRFUTIL) pkg generate $(BUILD)/firmware.espruino.zip --application $^ --application-version 0xff --hw-version 52 --sd-req 0xa9,0xae,0xb6 --key-file espruino_dfu_private_key.pem
|
||||
|
||||
espruino-dfu-gen: $(BUILD)/firmware.espruino.zip
|
||||
|
||||
include $(TOP)/py/mkrules.mk
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "background.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "supervisor/filesystem.h"
|
||||
#include "supervisor/port.h"
|
||||
|
@ -44,10 +46,11 @@
|
|||
|
||||
void port_start_background_task(void) {
|
||||
}
|
||||
|
||||
void port_finish_background_task(void) {
|
||||
}
|
||||
|
||||
void port_background_task(void) {
|
||||
void port_background_tick(void) {
|
||||
#if CIRCUITPY_AUDIOPWMIO
|
||||
audiopwmout_background();
|
||||
#endif
|
||||
|
@ -55,3 +58,11 @@ void port_background_task(void) {
|
|||
i2s_background();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Allow boards to override this.
|
||||
MP_WEAK void board_background_task(void) {
|
||||
}
|
||||
|
||||
void port_background_task(void) {
|
||||
board_background_task();
|
||||
}
|
||||
|
|
|
@ -27,4 +27,6 @@
|
|||
#ifndef MICROPY_INCLUDED_NRF_BACKGROUND_H
|
||||
#define MICROPY_INCLUDED_NRF_BACKGROUND_H
|
||||
|
||||
void board_background_task(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_BACKGROUND_H
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 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 "supervisor/board.h"
|
||||
#include "background.h"
|
||||
#include "mpconfigboard.h"
|
||||
|
||||
#include "shared-bindings/busio/SPI.h"
|
||||
#include "shared-bindings/displayio/FourWire.h"
|
||||
#include "shared-bindings/framebufferio/FramebufferDisplay.h"
|
||||
#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h"
|
||||
#include "shared-module/displayio/__init__.h"
|
||||
|
||||
digitalio_digitalinout_obj_t extcomin;
|
||||
digitalio_digitalinout_obj_t display_on;
|
||||
|
||||
uint32_t last_down_ticks_ms;
|
||||
|
||||
void board_init(void) {
|
||||
common_hal_digitalio_digitalinout_construct(&extcomin, &pin_P0_06);
|
||||
common_hal_digitalio_digitalinout_switch_to_output(&extcomin, true, DRIVE_MODE_PUSH_PULL);
|
||||
common_hal_digitalio_digitalinout_never_reset(&extcomin);
|
||||
|
||||
common_hal_digitalio_digitalinout_construct(&display_on, &pin_P0_07);
|
||||
common_hal_digitalio_digitalinout_switch_to_output(&display_on, true, DRIVE_MODE_PUSH_PULL);
|
||||
common_hal_digitalio_digitalinout_never_reset(&display_on);
|
||||
|
||||
sharpdisplay_framebuffer_obj_t *fb = &allocate_display_bus()->sharpdisplay;
|
||||
fb->base.type = &sharpdisplay_framebuffer_type;
|
||||
|
||||
busio_spi_obj_t *spi = &fb->inline_bus;
|
||||
common_hal_busio_spi_construct(spi, &pin_P0_26, &pin_P0_27, NULL, false);
|
||||
common_hal_busio_spi_never_reset(spi);
|
||||
|
||||
common_hal_sharpdisplay_framebuffer_construct(fb, spi, &pin_P0_05, 500000, 176, 176, true);
|
||||
|
||||
primary_display_t *display = allocate_display();
|
||||
framebufferio_framebufferdisplay_obj_t *self = &display->framebuffer_display;
|
||||
self->base.type = &framebufferio_framebufferdisplay_type;
|
||||
common_hal_framebufferio_framebufferdisplay_construct(self, fb, 0, true);
|
||||
}
|
||||
|
||||
bool board_requests_safe_mode(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void reset_board(void) {
|
||||
nrf_gpio_cfg_input(17, NRF_GPIO_PIN_PULLUP);
|
||||
}
|
||||
|
||||
void board_deinit(void) {
|
||||
// common_hal_displayio_release_displays();
|
||||
}
|
||||
|
||||
void board_background_task(void) {
|
||||
if (!nrf_gpio_pin_read(17)) {
|
||||
if (last_down_ticks_ms == 0) {
|
||||
last_down_ticks_ms = supervisor_ticks_ms32();
|
||||
}
|
||||
} else {
|
||||
last_down_ticks_ms = 0;
|
||||
}
|
||||
// If the button isn't pressed, then feed the watchdog.
|
||||
if (last_down_ticks_ms == 0) {
|
||||
NRF_WDT->RR[0] = 0x6E524635;
|
||||
return;
|
||||
}
|
||||
// if the button has been pressed less than 5 seconds, then feed the watchdog.
|
||||
uint32_t now = supervisor_ticks_ms32();
|
||||
if (now - last_down_ticks_ms < 5000) {
|
||||
NRF_WDT->RR[0] = 0x6E524635;
|
||||
}
|
||||
// Don't feed the watchdog so that it'll expire and kick us to the bootloader.
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Glenn Ruben Bakke
|
||||
* Copyright (c) 2018 Dan Halbert 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 "nrfx/hal/nrf_gpio.h"
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "Espruino Bangle.js 2"
|
||||
#define MICROPY_HW_MCU_NAME "nRF52840"
|
||||
|
||||
#define MICROPY_HW_LED_STATUS (&pin_P0_19)
|
||||
|
||||
#if SPI_FLASH_FILESYSTEM
|
||||
#define SPI_FLASH_MOSI_PIN &pin_P0_15
|
||||
#define SPI_FLASH_MISO_PIN &pin_P0_13
|
||||
#define SPI_FLASH_SCK_PIN &pin_P0_16
|
||||
#define SPI_FLASH_CS_PIN &pin_P0_14
|
||||
#endif
|
||||
|
||||
#define CIRCUITPY_BOOT_BUTTON (&pin_P0_17)
|
||||
|
||||
#define BOARD_HAS_32KHZ_XTAL (1)
|
|
@ -0,0 +1,27 @@
|
|||
CIRCUITPY_CREATOR_ID = 0xBA000000
|
||||
CIRCUITPY_CREATION_ID = 0x0BA20001
|
||||
MCU_CHIP = nrf52840
|
||||
|
||||
SPI_FLASH_FILESYSTEM = 1
|
||||
EXTERNAL_FLASH_DEVICES = "XT25F64B,GD25Q64C"
|
||||
|
||||
CIRCUITPY_USB = 0
|
||||
|
||||
CIRCUITPY_FULL_BUILD = 1
|
||||
CIRCUITPY_AUDIOBUSIO = 0
|
||||
CIRCUITPY_AUDIOPWMIO = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_NEOPIXEL_WRITE = 0
|
||||
CIRCUITPY_ROTARYIO = 0
|
||||
CIRCUITPY_SYNTHIO = 0
|
||||
CIRCUITPY_AESIO = 0
|
||||
CIRCUITPY_ANALOGIO = 1
|
||||
CIRCUITPY_AUDIOCORE = 0
|
||||
CIRCUITPY_AUDIOMIXER = 0
|
||||
CIRCUITPY_RAINBOWIO = 0
|
||||
CIRCUITPY_RGBMATRIX = 0
|
||||
CIRCUITPY_ONEWIREIO = 0
|
||||
|
||||
CIRCUITPY_BUILD_EXTENSIONS = espruino.zip
|
||||
|
||||
CIRCUITPY_DISPLAYIO = 1
|
|
@ -0,0 +1,41 @@
|
|||
#include "shared-bindings/board/__init__.h"
|
||||
|
||||
#include "supervisor/board.h"
|
||||
#include "shared-module/displayio/__init__.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
||||
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_PRESSURE_SCL), MP_ROM_PTR(&pin_P0_02) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_03) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MEMLCD_CS), MP_ROM_PTR(&pin_P0_05) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MEMLCD_EXTCOMIN), MP_ROM_PTR(&pin_P0_06) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MEMLCD_DISP), MP_ROM_PTR(&pin_P0_07) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_BACKLIGHT), MP_ROM_PTR(&pin_P0_08) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P0_17) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_VIBRATE), MP_ROM_PTR(&pin_P0_19) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_HRM_POWER), MP_ROM_PTR(&pin_P0_21) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_HRM_INT), MP_ROM_PTR(&pin_P0_22) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_CHARGE_PORT), MP_ROM_PTR(&pin_P0_23) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_HRM_SDA), MP_ROM_PTR(&pin_P0_24) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_CHARGE_COMPLETE), MP_ROM_PTR(&pin_P0_25) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MEMLCD_SCK), MP_ROM_PTR(&pin_P0_26) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MEMLCD_MOSI), MP_ROM_PTR(&pin_P0_27) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPS_POWER), MP_ROM_PTR(&pin_P0_29) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPS_TX), MP_ROM_PTR(&pin_P0_30) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPS_RX), MP_ROM_PTR(&pin_P0_31) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_HRM_SCL), MP_ROM_PTR(&pin_P1_00) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TOUCH_SDA), MP_ROM_PTR(&pin_P1_01) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TOUCH_SCL), MP_ROM_PTR(&pin_P1_02) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_P1_03) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ACCEL_SDA), MP_ROM_PTR(&pin_P1_04) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ACCEL_SCL), MP_ROM_PTR(&pin_P1_05) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_COMPASS_SDA), MP_ROM_PTR(&pin_P1_10) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_COMPASS_SCL), MP_ROM_PTR(&pin_P1_11) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PRESSURE_SDA), MP_ROM_PTR(&pin_P1_13) },
|
||||
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}
|
||||
};
|
||||
|
||||
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIK5uG3MovsdlHdw0xKzHsiv7hCRlFFQbwF30wW2KT4YJoAoGCCqGSM49
|
||||
AwEHoUQDQgAElQMkm+myar6SNwygD8seLeccsydVakcn3kHvxVK5AUnTCcYEFKPY
|
||||
B9RfTIE/mwpHoaXs8e4swKX9nPBeC2mTZQ==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -30,8 +30,12 @@
|
|||
|
||||
void port_start_background_task(void) {
|
||||
}
|
||||
|
||||
void port_finish_background_task(void) {
|
||||
}
|
||||
|
||||
void port_background_tick(void) {
|
||||
}
|
||||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
|
|
|
@ -260,6 +260,10 @@ const uint8_t display_stop_sequence[] = {
|
|||
POF, 0x00 // Power off
|
||||
};
|
||||
|
||||
const uint8_t refresh_sequence[] = {
|
||||
DRF, 0x00
|
||||
};
|
||||
|
||||
void board_init(void) {
|
||||
// Drive the EN_3V3 pin high so the board stays awake on battery power
|
||||
enable_pin_obj.base.type = &digitalio_digitalinout_type;
|
||||
|
@ -293,6 +297,7 @@ void board_init(void) {
|
|||
display,
|
||||
bus,
|
||||
display_start_sequence, sizeof(display_start_sequence),
|
||||
0, // start up time
|
||||
display_stop_sequence, sizeof(display_stop_sequence),
|
||||
296, // width
|
||||
128, // height
|
||||
|
@ -310,13 +315,14 @@ void board_init(void) {
|
|||
DTM1, // write_color_ram_command
|
||||
false, // color_bits_inverted
|
||||
0x000000, // highlight_color
|
||||
DRF, // refresh_display_command
|
||||
refresh_sequence, sizeof(refresh_sequence), // refresh_display_command
|
||||
1.0, // refresh_time
|
||||
&pin_GPIO26, // busy_pin
|
||||
false, // busy_state
|
||||
2.0, // seconds_per_frame
|
||||
false, // always_toggle_chip_select
|
||||
false, // grayscale
|
||||
false, // acep
|
||||
false); // two_byte_sequence_length
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
void port_background_task(void) {
|
||||
}
|
||||
void port_background_tick(void) {
|
||||
}
|
||||
void port_start_background_task(void) {
|
||||
}
|
||||
void port_finish_background_task(void) {
|
||||
|
|
|
@ -159,7 +159,12 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r
|
|||
STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) {
|
||||
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
check_for_deinit(self);
|
||||
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self));
|
||||
uint32_t available = common_hal_bleio_characteristic_buffer_rx_characters_available(self);
|
||||
if (available == 0) {
|
||||
// Only check if connected when none available, otherwise, allow code to continue.
|
||||
raise_error_if_not_connected(self);
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(available);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting);
|
||||
|
||||
|
|
|
@ -71,14 +71,16 @@
|
|||
//| write_color_ram_command: Optional[int] = None,
|
||||
//| color_bits_inverted: bool = False,
|
||||
//| highlight_color: int = 0x000000,
|
||||
//| refresh_display_command: int,
|
||||
//| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer],
|
||||
//| refresh_time: float = 40,
|
||||
//| busy_pin: Optional[microcontroller.Pin] = None,
|
||||
//| busy_state: bool = True,
|
||||
//| seconds_per_frame: float = 180,
|
||||
//| always_toggle_chip_select: bool = False,
|
||||
//| grayscale: bool = False,
|
||||
//| two_byte_sequence_length: bool = False
|
||||
//| advanced_color_epaper: bool = False,
|
||||
//| two_byte_sequence_length: bool = False,
|
||||
//| start_up_time: float = 0
|
||||
//| ) -> None:
|
||||
//| """Create a EPaperDisplay object on the given display bus (`displayio.FourWire` or `paralleldisplay.ParallelBus`).
|
||||
//|
|
||||
|
@ -92,8 +94,8 @@
|
|||
//|
|
||||
//| :param display_bus: The bus that the display is connected to
|
||||
//| :type _DisplayBus: displayio.FourWire or paralleldisplay.ParallelBus
|
||||
//| :param ~circuitpython_typing.ReadableBuffer start_sequence: Byte-packed initialization sequence.
|
||||
//| :param ~circuitpython_typing.ReadableBuffer stop_sequence: Byte-packed initialization sequence.
|
||||
//| :param ~circuitpython_typing.ReadableBuffer start_sequence: Byte-packed command sequence.
|
||||
//| :param ~circuitpython_typing.ReadableBuffer stop_sequence: Byte-packed command sequence.
|
||||
//| :param int width: Width in pixels
|
||||
//| :param int height: Height in pixels
|
||||
//| :param int ram_width: RAM width in pixels
|
||||
|
@ -110,14 +112,16 @@
|
|||
//| :param int write_color_ram_command: Command used to write pixels values into the update region
|
||||
//| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color.
|
||||
//| :param int highlight_color: RGB888 of source color to highlight with third ePaper color.
|
||||
//| :param int refresh_display_command: Command used to start a display refresh
|
||||
//| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence
|
||||
//| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided.
|
||||
//| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy
|
||||
//| :param bool busy_state: State of the busy pin when the display is busy
|
||||
//| :param float seconds_per_frame: Minimum number of seconds between screen refreshes
|
||||
//| :param bool always_toggle_chip_select: When True, chip select is toggled every byte
|
||||
//| :param bool grayscale: When true, the color ram is the low bit of 2-bit grayscale
|
||||
//| :param bool advanced_color_epaper: When true, the display is a 7-color advanced color epaper (ACeP)
|
||||
//| :param bool two_byte_sequence_length: When true, use two bytes to define sequence length
|
||||
//| :param float start_up_time: Time to wait after reset before sending commands
|
||||
//| """
|
||||
//| ...
|
||||
STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
|
@ -127,7 +131,8 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size
|
|||
ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted,
|
||||
ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color,
|
||||
ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state,
|
||||
ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_two_byte_sequence_length };
|
||||
ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper,
|
||||
ARG_two_byte_sequence_length, ARG_start_up_time };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_start_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
|
@ -148,14 +153,16 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size
|
|||
{ MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} },
|
||||
{ MP_QSTR_refresh_display_command, MP_ARG_INT | MP_ARG_REQUIRED },
|
||||
{ MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED },
|
||||
{ MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} },
|
||||
{ MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_busy_state, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
|
||||
{ MP_QSTR_seconds_per_frame, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(180)} },
|
||||
{ MP_QSTR_always_toggle_chip_select, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_advanced_color_epaper, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_two_byte_sequence_length, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
|
||||
{ MP_QSTR_start_up_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(0)} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
@ -177,10 +184,10 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size
|
|||
|
||||
primary_display_t *disp = allocate_display_or_raise();
|
||||
displayio_epaperdisplay_obj_t *self = &disp->epaper_display;
|
||||
;
|
||||
|
||||
mp_float_t refresh_time = mp_obj_get_float(args[ARG_refresh_time].u_obj);
|
||||
mp_float_t seconds_per_frame = mp_obj_get_float(args[ARG_seconds_per_frame].u_obj);
|
||||
mp_float_t start_up_time = mp_obj_get_float(args[ARG_start_up_time].u_obj);
|
||||
|
||||
mp_int_t write_color_ram_command = NO_COMMAND;
|
||||
mp_int_t highlight_color = args[ARG_highlight_color].u_int;
|
||||
|
@ -188,19 +195,40 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size
|
|||
write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj);
|
||||
}
|
||||
|
||||
bool two_byte_sequence_length = args[ARG_two_byte_sequence_length].u_bool;
|
||||
|
||||
mp_obj_t refresh_obj = args[ARG_refresh_display_command].u_obj;
|
||||
const uint8_t *refresh_buf;
|
||||
mp_buffer_info_t refresh_bufinfo;
|
||||
size_t refresh_buf_len = 0;
|
||||
mp_int_t refresh_command;
|
||||
if (mp_obj_get_int_maybe(refresh_obj, &refresh_command)) {
|
||||
uint8_t *command_buf = m_malloc(3, true);
|
||||
command_buf[0] = refresh_command;
|
||||
command_buf[1] = 0;
|
||||
command_buf[2] = 0;
|
||||
refresh_buf = command_buf;
|
||||
refresh_buf_len = two_byte_sequence_length? 3: 2;
|
||||
} else if (mp_get_buffer(refresh_obj, &refresh_bufinfo, MP_BUFFER_READ)) {
|
||||
refresh_buf = refresh_bufinfo.buf;
|
||||
refresh_buf_len = refresh_bufinfo.len;
|
||||
} else {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_refresh_display_command);
|
||||
}
|
||||
|
||||
self->base.type = &displayio_epaperdisplay_type;
|
||||
common_hal_displayio_epaperdisplay_construct(
|
||||
self,
|
||||
display_bus,
|
||||
start_bufinfo.buf, start_bufinfo.len, stop_bufinfo.buf, stop_bufinfo.len,
|
||||
start_bufinfo.buf, start_bufinfo.len, start_up_time, stop_bufinfo.buf, stop_bufinfo.len,
|
||||
args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_ram_width].u_int, args[ARG_ram_height].u_int,
|
||||
args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation,
|
||||
args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int,
|
||||
args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int,
|
||||
args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command,
|
||||
args[ARG_color_bits_inverted].u_bool, highlight_color, args[ARG_refresh_display_command].u_int, refresh_time,
|
||||
args[ARG_color_bits_inverted].u_bool, highlight_color, refresh_buf, refresh_buf_len, refresh_time,
|
||||
busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame,
|
||||
args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_two_byte_sequence_length].u_bool
|
||||
args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, two_byte_sequence_length
|
||||
);
|
||||
|
||||
return self;
|
||||
|
|
|
@ -37,12 +37,12 @@ extern const mp_obj_type_t displayio_epaperdisplay_type;
|
|||
#define NO_COMMAND 0x100
|
||||
|
||||
void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t *self,
|
||||
mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, const uint8_t *stop_sequence, uint16_t stop_sequence_len,
|
||||
mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, const uint8_t *stop_sequence, uint16_t stop_sequence_len,
|
||||
uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation,
|
||||
uint16_t set_column_window_command, uint16_t set_row_window_command,
|
||||
uint16_t set_current_column_command, uint16_t set_current_row_command,
|
||||
uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time,
|
||||
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select, bool grayscale, bool two_byte_sequence_length);
|
||||
uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
|
||||
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool always_toggle_chip_select, bool grayscale, bool acep, bool two_byte_sequence_length);
|
||||
|
||||
bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t *self);
|
||||
|
||||
|
|
|
@ -40,29 +40,54 @@
|
|||
//| """Map a pixel palette_index to a full color. Colors are transformed to the display's format internally to
|
||||
//| save memory."""
|
||||
//|
|
||||
//| def __init__(self, color_count: int) -> None:
|
||||
//| def __init__(self, color_count: int, *, dither: bool = False) -> None:
|
||||
//| """Create a Palette object to store a set number of colors.
|
||||
//|
|
||||
//| :param int color_count: The number of colors in the Palette"""
|
||||
//| :param int color_count: The number of colors in the Palette
|
||||
//| :param bool dither: When true, dither the RGB color before converting to the display's color space
|
||||
//| """
|
||||
//| ...
|
||||
// TODO(tannewt): Add support for other color formats.
|
||||
// TODO(tannewt): Add support for 8-bit alpha blending.
|
||||
//|
|
||||
STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_color_count };
|
||||
enum { ARG_color_count, ARG_dither };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_color_count, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_dither, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
displayio_palette_t *self = m_new_obj(displayio_palette_t);
|
||||
self->base.type = &displayio_palette_type;
|
||||
common_hal_displayio_palette_construct(self, args[ARG_color_count].u_int);
|
||||
common_hal_displayio_palette_construct(self, args[ARG_color_count].u_int, args[ARG_dither].u_bool);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
//| dither: bool
|
||||
//| """When `True` the Palette dithers the output color by adding random
|
||||
//| noise when truncating to display bitdepth"""
|
||||
STATIC mp_obj_t displayio_palette_obj_get_dither(mp_obj_t self_in) {
|
||||
displayio_palette_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(common_hal_displayio_palette_get_dither(self));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(displayio_palette_get_dither_obj, displayio_palette_obj_get_dither);
|
||||
|
||||
STATIC mp_obj_t displayio_palette_obj_set_dither(mp_obj_t self_in, mp_obj_t dither) {
|
||||
displayio_palette_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
common_hal_displayio_palette_set_dither(self, mp_obj_is_true(dither));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_set_dither_obj, displayio_palette_obj_set_dither);
|
||||
|
||||
MP_PROPERTY_GETSET(displayio_palette_dither_obj,
|
||||
(mp_obj_t)&displayio_palette_get_dither_obj,
|
||||
(mp_obj_t)&displayio_palette_set_dither_obj);
|
||||
|
||||
//| def __bool__(self) -> bool: ...
|
||||
//| def __len__(self) -> int:
|
||||
//| """Returns the number of colors in a Palette"""
|
||||
|
@ -185,6 +210,7 @@ STATIC mp_obj_t displayio_palette_obj_is_transparent(mp_obj_t self_in, mp_obj_t
|
|||
MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_is_transparent_obj, displayio_palette_obj_is_transparent);
|
||||
|
||||
STATIC const mp_rom_map_elem_t displayio_palette_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_dither), MP_ROM_PTR(&displayio_palette_dither_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_make_transparent), MP_ROM_PTR(&displayio_palette_make_transparent_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_make_opaque), MP_ROM_PTR(&displayio_palette_make_opaque_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_is_transparent), MP_ROM_PTR(&displayio_palette_is_transparent_obj) },
|
||||
|
|
|
@ -31,11 +31,14 @@
|
|||
|
||||
extern const mp_obj_type_t displayio_palette_type;
|
||||
|
||||
void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count);
|
||||
void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count, bool dither);
|
||||
void common_hal_displayio_palette_set_color(displayio_palette_t *self, uint32_t palette_index, uint32_t color);
|
||||
uint32_t common_hal_displayio_palette_get_color(displayio_palette_t *self, uint32_t palette_index);
|
||||
uint32_t common_hal_displayio_palette_get_len(displayio_palette_t *self);
|
||||
|
||||
void common_hal_displayio_palette_set_dither(displayio_palette_t *self, bool dither);
|
||||
bool common_hal_displayio_palette_get_dither(displayio_palette_t *self);
|
||||
|
||||
void common_hal_displayio_palette_make_opaque(displayio_palette_t *self, uint32_t palette_index);
|
||||
void common_hal_displayio_palette_make_transparent(displayio_palette_t *self, uint32_t palette_index);
|
||||
bool common_hal_displayio_palette_is_transparent(displayio_palette_t *self, uint32_t palette_index);
|
||||
|
|
|
@ -33,14 +33,42 @@
|
|||
#include "shared-module/displayio/__init__.h"
|
||||
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
|
||||
|
||||
//| class SharpMemoryFramebuffer:
|
||||
//| """A framebuffer for a memory-in-pixel display. Sharp makes monochrome displays and JDI used
|
||||
//| to make 8-color displays.
|
||||
//|
|
||||
//| 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."""
|
||||
//|
|
||||
//| def __init__(
|
||||
//| self,
|
||||
//| spi_bus: busio.SPI,
|
||||
//| chip_select: microcontroller.Pin,
|
||||
//| width: int,
|
||||
//| height: int,
|
||||
//| baudrate: int = 2000000,
|
||||
//| jdi_display: bool = False,
|
||||
//| ) -> None:
|
||||
//| """Create a framebuffer for the memory-in-pixel display.
|
||||
//|
|
||||
//| :param busio.SPI spi_bus: The SPI bus that the display is connected to
|
||||
//| :param microcontroller.Pin chip_select: The pin connect to the display's chip select line
|
||||
//| :param int width: The width of the display in pixels
|
||||
//| :param int height: The height of the display in pixels
|
||||
//| :param int baudrate: The baudrate to communicate with the screen at
|
||||
//| :param bool jdi_display: When True, work with an 8-color JDI display. Otherwise, a monochrome Sharp display.
|
||||
//| """
|
||||
//| ...
|
||||
STATIC mp_obj_t sharpdisplay_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, NUM_ARGS };
|
||||
enum { ARG_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, ARG_jdi_display, NUM_ARGS };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_spi_bus, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} },
|
||||
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} },
|
||||
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 2000000} },
|
||||
{ MP_QSTR_jdi_display, MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
MP_STATIC_ASSERT(MP_ARRAY_SIZE(allowed_args) == NUM_ARGS);
|
||||
|
@ -53,7 +81,7 @@ STATIC mp_obj_t sharpdisplay_framebuffer_make_new(const mp_obj_type_t *type, siz
|
|||
sharpdisplay_framebuffer_obj_t *self = &allocate_display_bus_or_raise()->sharpdisplay;
|
||||
self->base.type = &sharpdisplay_framebuffer_type;
|
||||
|
||||
common_hal_sharpdisplay_framebuffer_construct(self, spi, chip_select, args[ARG_baudrate].u_int, args[ARG_width].u_int, args[ARG_height].u_int);
|
||||
common_hal_sharpdisplay_framebuffer_construct(self, spi, chip_select, args[ARG_baudrate].u_int, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_jdi_display].u_bool);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
@ -69,6 +97,12 @@ STATIC mp_int_t sharpdisplay_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_
|
|||
return 0;
|
||||
}
|
||||
|
||||
//| def deinit(self) -> None:
|
||||
//| """Free the resources (pins, timers, etc.) associated with this
|
||||
//| SharpMemoryFramebuffer instance. After deinitialization, no further operations
|
||||
//| may be performed."""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t sharpdisplay_framebuffer_deinit(mp_obj_t self_in) {
|
||||
sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t *)self_in;
|
||||
common_hal_sharpdisplay_framebuffer_deinit(self);
|
||||
|
|
|
@ -26,9 +26,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
|
||||
// #include "shared-module/framebufferio/FramebufferDisplay.h"
|
||||
|
||||
#include "py/objtype.h"
|
||||
|
||||
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
|
||||
|
||||
extern const mp_obj_type_t sharpdisplay_framebuffer_type;
|
||||
|
||||
void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *chip_select, int baudrate, int width, int height, bool jdi_display);
|
||||
void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask);
|
||||
void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self);
|
||||
void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo);
|
||||
int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self);
|
||||
int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self);
|
||||
void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask);
|
||||
void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self);
|
||||
void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self);
|
||||
|
|
|
@ -54,6 +54,13 @@ uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) {
|
|||
return r5 << 11 | g6 << 5 | b5;
|
||||
}
|
||||
|
||||
uint8_t displayio_colorconverter_compute_rgbd(uint32_t color_rgb888) {
|
||||
uint32_t r1 = (color_rgb888 >> 23) & 0x1;
|
||||
uint32_t g1 = (color_rgb888 >> 15) & 0x1;
|
||||
uint32_t b1 = (color_rgb888 >> 7) & 0x1;
|
||||
return r1 << 3 | g1 << 2 | b1 << 1 /* | dummy */;
|
||||
}
|
||||
|
||||
uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) {
|
||||
uint32_t r8 = (color_rgb888 >> 16);
|
||||
uint32_t g8 = (color_rgb888 >> 8) & 0xff;
|
||||
|
@ -96,6 +103,44 @@ uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888) {
|
|||
return hue;
|
||||
}
|
||||
|
||||
uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) {
|
||||
// This is DDX=1, the default for the displays.
|
||||
uint8_t chroma = displayio_colorconverter_compute_chroma(color_rgb888);
|
||||
if (chroma >= 64) {
|
||||
uint8_t hue = displayio_colorconverter_compute_hue(color_rgb888);
|
||||
// Red 0
|
||||
if (hue < 10) {
|
||||
return 0x4;
|
||||
}
|
||||
// Orange 21
|
||||
if (hue < 21 + 10) {
|
||||
return 0x6;
|
||||
}
|
||||
// Yellow 42
|
||||
if (hue < 42 + 21) {
|
||||
return 0x5;
|
||||
}
|
||||
// Green 85
|
||||
if (hue < 85 + 42) {
|
||||
return 0x2;
|
||||
}
|
||||
// Blue 170
|
||||
if (hue < 170 + 42) {
|
||||
return 0x3;
|
||||
}
|
||||
|
||||
// The rest is red to 255
|
||||
return 0x4;
|
||||
} else {
|
||||
uint8_t luma = displayio_colorconverter_compute_luma(color_rgb888);
|
||||
if (luma >= 128) {
|
||||
return 0x1; // White
|
||||
} else {
|
||||
return 0x0; // Black
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color) {
|
||||
|
||||
int16_t hue_diff = colorspace->tricolor_hue - pixel_hue;
|
||||
|
@ -207,18 +252,9 @@ uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspac
|
|||
return pixel;
|
||||
}
|
||||
|
||||
void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
|
||||
void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dither, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
|
||||
uint32_t pixel = input_pixel->pixel;
|
||||
|
||||
if (self->transparent_color == pixel) {
|
||||
output_color->opaque = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pixel = displayio_colorconverter_convert_pixel(self->input_colorspace, pixel);
|
||||
|
||||
|
||||
if (self->dither) {
|
||||
if (dither) {
|
||||
uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y));
|
||||
uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x + 33,input_pixel->tile_y));
|
||||
uint8_t randb = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y + 33));
|
||||
|
@ -272,10 +308,44 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d
|
|||
output_color->pixel = pixel;
|
||||
output_color->opaque = true;
|
||||
return;
|
||||
} else if (colorspace->depth == 4) {
|
||||
uint8_t packed;
|
||||
if (colorspace->sevencolor) {
|
||||
packed = displayio_colorconverter_compute_sevencolor(pixel);
|
||||
} else {
|
||||
packed = displayio_colorconverter_compute_rgbd(pixel);
|
||||
}
|
||||
output_color->pixel = packed;
|
||||
output_color->opaque = true;
|
||||
return;
|
||||
}
|
||||
output_color->opaque = false;
|
||||
}
|
||||
|
||||
void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
|
||||
uint32_t pixel = input_pixel->pixel;
|
||||
|
||||
if (self->transparent_color == pixel) {
|
||||
output_color->opaque = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self->dither && self->cached_colorspace == colorspace && self->cached_input_pixel == input_pixel->pixel) {
|
||||
output_color->pixel = self->cached_output_color;
|
||||
return;
|
||||
}
|
||||
|
||||
displayio_input_pixel_t rgb888_pixel = *input_pixel;
|
||||
rgb888_pixel.pixel = displayio_colorconverter_convert_pixel(self->input_colorspace, input_pixel->pixel);
|
||||
displayio_convert_color(colorspace, self->dither, &rgb888_pixel, output_color);
|
||||
|
||||
if (!self->dither) {
|
||||
self->cached_colorspace = colorspace;
|
||||
self->cached_input_pixel = input_pixel->pixel;
|
||||
self->cached_output_color = output_color->pixel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Currently no refresh logic is needed for a ColorConverter.
|
||||
|
|
|
@ -38,6 +38,11 @@ typedef struct displayio_colorconverter {
|
|||
bool dither;
|
||||
uint8_t input_colorspace;
|
||||
uint32_t transparent_color;
|
||||
|
||||
// Cache the last computed color in case the are the same.
|
||||
const _displayio_colorspace_t *cached_colorspace;
|
||||
uint32_t cached_input_pixel;
|
||||
uint32_t cached_output_color;
|
||||
} displayio_colorconverter_t;
|
||||
|
||||
bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self);
|
||||
|
@ -47,10 +52,15 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d
|
|||
uint32_t displayio_colorconverter_dither_noise_1(uint32_t n);
|
||||
uint32_t displayio_colorconverter_dither_noise_2(uint32_t x, uint32_t y);
|
||||
|
||||
// Convert version that doesn't require a colorconverter object.
|
||||
void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dither, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color);
|
||||
|
||||
uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888);
|
||||
uint8_t displayio_colorconverter_compute_rgbd(uint32_t color_rgb888);
|
||||
uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888);
|
||||
uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888);
|
||||
uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888);
|
||||
uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888);
|
||||
void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_COLORCONVERTER_H
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "shared-bindings/displayio/ColorConverter.h"
|
||||
#include "shared-bindings/displayio/FourWire.h"
|
||||
#include "shared-bindings/displayio/I2CDisplay.h"
|
||||
|
@ -47,21 +48,31 @@
|
|||
#define DELAY 0x80
|
||||
|
||||
void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t *self,
|
||||
mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len,
|
||||
mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time,
|
||||
const uint8_t *stop_sequence, uint16_t stop_sequence_len,
|
||||
uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height,
|
||||
int16_t colstart, int16_t rowstart, uint16_t rotation,
|
||||
uint16_t set_column_window_command, uint16_t set_row_window_command,
|
||||
uint16_t set_current_column_command, uint16_t set_current_row_command,
|
||||
uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time,
|
||||
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select, bool grayscale, bool two_byte_sequence_length) {
|
||||
uint16_t write_black_ram_command, bool black_bits_inverted,
|
||||
uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color,
|
||||
const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time,
|
||||
const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame,
|
||||
bool chip_select, bool grayscale, bool acep, bool two_byte_sequence_length) {
|
||||
uint16_t color_depth = 1;
|
||||
if (highlight_color != 0x000000) {
|
||||
self->core.colorspace.tricolor = true;
|
||||
self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color);
|
||||
self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color);
|
||||
}
|
||||
if (acep) {
|
||||
self->core.colorspace.sevencolor = true;
|
||||
color_depth = 4; // bits. 7 colors + clean
|
||||
self->acep = acep;
|
||||
grayscale = false;
|
||||
}
|
||||
|
||||
displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true, true);
|
||||
displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, color_depth, grayscale, true, 1, true, true);
|
||||
|
||||
self->set_column_window_command = set_column_window_command;
|
||||
self->set_row_window_command = set_row_window_command;
|
||||
|
@ -71,7 +82,6 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t
|
|||
self->black_bits_inverted = black_bits_inverted;
|
||||
self->write_color_ram_command = write_color_ram_command;
|
||||
self->color_bits_inverted = color_bits_inverted;
|
||||
self->refresh_display_command = refresh_display_command;
|
||||
self->refresh_time = refresh_time * 1000;
|
||||
self->busy_state = busy_state;
|
||||
self->refreshing = false;
|
||||
|
@ -81,8 +91,11 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t
|
|||
|
||||
self->start_sequence = start_sequence;
|
||||
self->start_sequence_len = start_sequence_len;
|
||||
self->start_up_time_ms = start_up_time * 1000;
|
||||
self->stop_sequence = stop_sequence;
|
||||
self->stop_sequence_len = stop_sequence_len;
|
||||
self->refresh_sequence = refresh_sequence;
|
||||
self->refresh_sequence_len = refresh_sequence_len;
|
||||
|
||||
self->busy.base.type = &mp_type_NoneType;
|
||||
self->two_byte_sequence_length = two_byte_sequence_length;
|
||||
|
@ -193,6 +206,8 @@ STATIC void displayio_epaperdisplay_start_refresh(displayio_epaperdisplay_obj_t
|
|||
// run start sequence
|
||||
self->core.bus_reset(self->core.bus);
|
||||
|
||||
common_hal_time_delay_ms(self->start_up_time_ms);
|
||||
|
||||
send_command_sequence(self, true, self->start_sequence, self->start_sequence_len);
|
||||
displayio_display_core_start_refresh(&self->core);
|
||||
}
|
||||
|
@ -211,9 +226,8 @@ uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaper
|
|||
|
||||
STATIC void displayio_epaperdisplay_finish_refresh(displayio_epaperdisplay_obj_t *self) {
|
||||
// Actually refresh the display now that all pixel RAM has been updated.
|
||||
displayio_display_core_begin_transaction(&self->core);
|
||||
self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &self->refresh_display_command, 1);
|
||||
displayio_display_core_end_transaction(&self->core);
|
||||
send_command_sequence(self, false, self->refresh_sequence, self->refresh_sequence_len);
|
||||
|
||||
supervisor_enable_tick();
|
||||
self->refreshing = true;
|
||||
|
||||
|
@ -326,8 +340,10 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t *
|
|||
memset(mask, 0, mask_length * sizeof(mask[0]));
|
||||
memset(buffer, 0, buffer_size * sizeof(buffer[0]));
|
||||
|
||||
if (self->grayscale) {
|
||||
self->core.colorspace.grayscale = true;
|
||||
self->core.colorspace.grayscale_bit = 7;
|
||||
}
|
||||
if (pass == 1) {
|
||||
if (self->grayscale) { // 4-color grayscale
|
||||
self->core.colorspace.grayscale_bit = 6;
|
||||
|
@ -335,6 +351,8 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t *
|
|||
} else if (self->core.colorspace.tricolor) {
|
||||
self->core.colorspace.grayscale = false;
|
||||
displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer);
|
||||
} else if (self->core.colorspace.sevencolor) {
|
||||
displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer);
|
||||
}
|
||||
} else {
|
||||
displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer);
|
||||
|
@ -366,6 +384,38 @@ STATIC bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t *
|
|||
return true;
|
||||
}
|
||||
|
||||
STATIC bool _clean_area(displayio_epaperdisplay_obj_t *self) {
|
||||
uint16_t width = displayio_display_core_get_width(&self->core);
|
||||
uint16_t height = displayio_display_core_get_height(&self->core);
|
||||
|
||||
// Allocated and shared as a uint32_t array so the compiler knows the
|
||||
// alignment everywhere.
|
||||
uint8_t buffer[width / 2];
|
||||
memset(buffer, 0x77, width / 2);
|
||||
|
||||
uint8_t write_command = self->write_black_ram_command;
|
||||
displayio_display_core_begin_transaction(&self->core);
|
||||
self->core.send(self->core.bus, DISPLAY_COMMAND, self->chip_select, &write_command, 1);
|
||||
displayio_display_core_end_transaction(&self->core);
|
||||
|
||||
for (uint16_t j = 0; j < height; j++) {
|
||||
if (!displayio_display_core_begin_transaction(&self->core)) {
|
||||
// Can't acquire display bus; skip the rest of the data. Try next display.
|
||||
return false;
|
||||
}
|
||||
self->core.send(self->core.bus, DISPLAY_DATA, self->chip_select, (uint8_t *)buffer, width / 2);
|
||||
displayio_display_core_end_transaction(&self->core);
|
||||
|
||||
// TODO(tannewt): Make refresh displays faster so we don't starve other
|
||||
// background tasks.
|
||||
#if CIRCUITPY_USB
|
||||
usb_background();
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t *self) {
|
||||
|
||||
if (self->refreshing && self->busy.base.type == &digitalio_digitalinout_type) {
|
||||
|
@ -393,6 +443,18 @@ bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t *s
|
|||
if (current_area == NULL) {
|
||||
return true;
|
||||
}
|
||||
if (self->acep) {
|
||||
displayio_epaperdisplay_start_refresh(self);
|
||||
_clean_area(self);
|
||||
displayio_epaperdisplay_finish_refresh(self);
|
||||
while (self->refreshing && !mp_hal_is_interrupted()) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
}
|
||||
if (mp_hal_is_interrupted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
displayio_epaperdisplay_start_refresh(self);
|
||||
while (current_area != NULL) {
|
||||
displayio_epaperdisplay_refresh_area(self, current_area);
|
||||
|
|
|
@ -39,9 +39,12 @@ typedef struct {
|
|||
digitalio_digitalinout_obj_t busy;
|
||||
uint32_t milliseconds_per_frame;
|
||||
const uint8_t *start_sequence;
|
||||
uint32_t start_sequence_len;
|
||||
const uint8_t *stop_sequence;
|
||||
uint32_t stop_sequence_len;
|
||||
const uint8_t *refresh_sequence;
|
||||
uint16_t start_sequence_len;
|
||||
uint16_t stop_sequence_len;
|
||||
uint16_t refresh_sequence_len;
|
||||
uint16_t start_up_time_ms;
|
||||
uint16_t refresh_time;
|
||||
uint16_t set_column_window_command;
|
||||
uint16_t set_row_window_command;
|
||||
|
@ -49,15 +52,15 @@ typedef struct {
|
|||
uint16_t set_current_row_command;
|
||||
uint16_t write_black_ram_command;
|
||||
uint16_t write_color_ram_command;
|
||||
uint8_t refresh_display_command;
|
||||
uint8_t hue;
|
||||
bool busy_state;
|
||||
bool black_bits_inverted;
|
||||
bool color_bits_inverted;
|
||||
bool refreshing;
|
||||
bool grayscale;
|
||||
display_chip_select_behavior_t chip_select;
|
||||
bool acep;
|
||||
bool two_byte_sequence_length;
|
||||
display_chip_select_behavior_t chip_select;
|
||||
} displayio_epaperdisplay_obj_t;
|
||||
|
||||
void displayio_epaperdisplay_change_refresh_mode_parameters(displayio_epaperdisplay_obj_t *self,
|
||||
|
|
|
@ -90,7 +90,7 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self,
|
|||
|
||||
displayio_palette_t *palette = m_new_obj(displayio_palette_t);
|
||||
palette->base.type = &displayio_palette_type;
|
||||
common_hal_displayio_palette_construct(palette, number_of_colors);
|
||||
common_hal_displayio_palette_construct(palette, number_of_colors, false);
|
||||
|
||||
if (number_of_colors > 1) {
|
||||
uint16_t palette_size = number_of_colors * sizeof(uint32_t);
|
||||
|
|
|
@ -28,9 +28,18 @@
|
|||
|
||||
#include "shared-module/displayio/ColorConverter.h"
|
||||
|
||||
void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count) {
|
||||
void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count, bool dither) {
|
||||
self->color_count = color_count;
|
||||
self->colors = (_displayio_color_t *)m_malloc(color_count * sizeof(_displayio_color_t), false);
|
||||
self->dither = dither;
|
||||
}
|
||||
|
||||
void common_hal_displayio_palette_set_dither(displayio_palette_t *self, bool dither) {
|
||||
self->dither = dither;
|
||||
}
|
||||
|
||||
bool common_hal_displayio_palette_get_dither(displayio_palette_t *self) {
|
||||
return self->dither;
|
||||
}
|
||||
|
||||
void common_hal_displayio_palette_make_opaque(displayio_palette_t *self, uint32_t palette_index) {
|
||||
|
@ -56,12 +65,7 @@ void common_hal_displayio_palette_set_color(displayio_palette_t *self, uint32_t
|
|||
return;
|
||||
}
|
||||
self->colors[palette_index].rgb888 = color;
|
||||
self->colors[palette_index].luma = displayio_colorconverter_compute_luma(color);
|
||||
self->colors[palette_index].rgb565 = displayio_colorconverter_compute_rgb565(color);
|
||||
|
||||
uint8_t chroma = displayio_colorconverter_compute_chroma(color);
|
||||
self->colors[palette_index].chroma = chroma;
|
||||
self->colors[palette_index].hue = displayio_colorconverter_compute_hue(color);
|
||||
self->colors[palette_index].cached_colorspace = NULL;
|
||||
self->needs_refresh = true;
|
||||
}
|
||||
|
||||
|
@ -69,40 +73,26 @@ uint32_t common_hal_displayio_palette_get_color(displayio_palette_t *self, uint3
|
|||
return self->colors[palette_index].rgb888;
|
||||
}
|
||||
|
||||
bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_colorspace_t *colorspace, uint32_t palette_index, uint32_t *color) {
|
||||
void displayio_palette_get_color(displayio_palette_t *self, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
|
||||
uint32_t palette_index = input_pixel->pixel;
|
||||
if (palette_index > self->color_count || self->colors[palette_index].transparent) {
|
||||
return false; // returns transparent
|
||||
output_color->opaque = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (colorspace->tricolor) {
|
||||
uint8_t luma = self->colors[palette_index].luma;
|
||||
*color = luma >> (8 - colorspace->depth);
|
||||
// Chroma 0 means the color is a gray and has no hue so never color based on it.
|
||||
if (self->colors[palette_index].chroma <= 16) {
|
||||
if (!colorspace->grayscale) {
|
||||
*color = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
uint8_t pixel_hue = self->colors[palette_index].hue;
|
||||
displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, color);
|
||||
} else if (colorspace->grayscale) {
|
||||
size_t bitmask = (1 << colorspace->depth) - 1;
|
||||
*color = (self->colors[palette_index].luma >> colorspace->grayscale_bit) & bitmask;
|
||||
} else if (colorspace->depth == 16) {
|
||||
uint16_t packed = self->colors[palette_index].rgb565;
|
||||
if (colorspace->reverse_bytes_in_word) {
|
||||
// swap bytes
|
||||
packed = __builtin_bswap16(packed);
|
||||
}
|
||||
*color = packed;
|
||||
} else if (colorspace->depth == 32) {
|
||||
*color = self->colors[palette_index].rgb888;
|
||||
} else {
|
||||
return false;
|
||||
// Cache results when not dithering.
|
||||
if (!self->dither && self->colors[palette_index].cached_colorspace == colorspace) {
|
||||
output_color->pixel = self->colors[palette_index].cached_color;
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
displayio_input_pixel_t rgb888_pixel = *input_pixel;
|
||||
rgb888_pixel.pixel = self->colors[palette_index].rgb888;
|
||||
displayio_convert_color(colorspace, self->dither, &rgb888_pixel, output_color);
|
||||
if (!self->dither) {
|
||||
self->colors[palette_index].cached_colorspace = colorspace;
|
||||
self->colors[palette_index].cached_color = output_color->pixel;
|
||||
}
|
||||
}
|
||||
|
||||
bool displayio_palette_needs_refresh(displayio_palette_t *self) {
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct {
|
|||
uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth.
|
||||
bool grayscale;
|
||||
bool tricolor;
|
||||
bool sevencolor; // Acep e-ink screens.
|
||||
bool pixels_in_byte_share_row;
|
||||
bool reverse_pixels_in_byte;
|
||||
bool reverse_bytes_in_word;
|
||||
|
@ -48,10 +49,8 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint32_t rgb888;
|
||||
uint16_t rgb565;
|
||||
uint8_t luma;
|
||||
uint8_t hue;
|
||||
uint8_t chroma;
|
||||
const _displayio_colorspace_t *cached_colorspace;
|
||||
uint32_t cached_color;
|
||||
bool transparent; // This may have additional bits added later for blending.
|
||||
} _displayio_color_t;
|
||||
|
||||
|
@ -74,11 +73,12 @@ typedef struct displayio_palette {
|
|||
_displayio_color_t *colors;
|
||||
uint32_t color_count;
|
||||
bool needs_refresh;
|
||||
bool dither;
|
||||
} displayio_palette_t;
|
||||
|
||||
// Returns false if color fetch did not succeed (out of range or transparent).
|
||||
// Returns true if color is opaque, and sets color.
|
||||
bool displayio_palette_get_color(displayio_palette_t *palette, const _displayio_colorspace_t *colorspace, uint32_t palette_index, uint32_t *color);
|
||||
|
||||
void displayio_palette_get_color(displayio_palette_t *palette, const _displayio_colorspace_t *colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color);
|
||||
;
|
||||
bool displayio_palette_needs_refresh(displayio_palette_t *self);
|
||||
void displayio_palette_finish_refresh(displayio_palette_t *self);
|
||||
|
||||
|
|
|
@ -507,7 +507,7 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self,
|
|||
if (self->pixel_shader == mp_const_none) {
|
||||
output_pixel.pixel = input_pixel.pixel;
|
||||
} else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) {
|
||||
output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel);
|
||||
displayio_palette_get_color(self->pixel_shader, colorspace, &input_pixel, &output_pixel);
|
||||
} else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) {
|
||||
displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ typedef bool (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t);
|
|||
typedef int (*framebuffer_get_bytes_per_cell_fun)(mp_obj_t);
|
||||
typedef int (*framebuffer_get_color_depth_fun)(mp_obj_t);
|
||||
typedef int (*framebuffer_get_first_pixel_offset_fun)(mp_obj_t);
|
||||
typedef int (*framebuffer_get_grayscale_fun)(mp_obj_t);
|
||||
typedef bool (*framebuffer_get_grayscale_fun)(mp_obj_t);
|
||||
typedef int (*framebuffer_get_height_fun)(mp_obj_t);
|
||||
typedef int (*framebuffer_get_native_frames_per_second_fun)(mp_obj_t);
|
||||
typedef bool (*framebuffer_get_pixels_in_byte_share_row_fun)(mp_obj_t);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "supervisor/memory.h"
|
||||
|
||||
#define SHARPMEM_BIT_WRITECMD_LSB (0x80)
|
||||
#define JDI_BIT_WRITECMD_LSB (0x90)
|
||||
#define SHARPMEM_BIT_VCOM_LSB (0x40)
|
||||
|
||||
STATIC uint8_t bitrev(uint8_t n) {
|
||||
|
@ -54,8 +55,12 @@ int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_
|
|||
}
|
||||
|
||||
STATIC int common_hal_sharpdisplay_framebuffer_get_row_stride(sharpdisplay_framebuffer_obj_t *self) {
|
||||
if (self->jdi_display) {
|
||||
return (self->width + 1) / 2 + 2;
|
||||
} else {
|
||||
return (self->width + 7) / 8 + 2;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int common_hal_sharpdisplay_framebuffer_get_first_pixel_offset(sharpdisplay_framebuffer_obj_t *self) {
|
||||
return 2;
|
||||
|
@ -99,10 +104,18 @@ void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_ob
|
|||
memset(alloc->ptr, 0, self->bufinfo.len);
|
||||
|
||||
uint8_t *data = self->bufinfo.buf;
|
||||
if (self->jdi_display) {
|
||||
*data++ = JDI_BIT_WRITECMD_LSB;
|
||||
} else {
|
||||
*data++ = SHARPMEM_BIT_WRITECMD_LSB;
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
if (self->jdi_display) {
|
||||
*data = y + 1;
|
||||
} else {
|
||||
*data = bitrev(y + 1);
|
||||
}
|
||||
data += row_stride;
|
||||
}
|
||||
self->full_refresh = true;
|
||||
|
@ -128,7 +141,14 @@ void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *
|
|||
memset(self, 0, sizeof(*self));
|
||||
}
|
||||
|
||||
void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *chip_select, int baudrate, int width, int height) {
|
||||
void common_hal_sharpdisplay_framebuffer_construct(
|
||||
sharpdisplay_framebuffer_obj_t *self,
|
||||
busio_spi_obj_t *spi,
|
||||
const mcu_pin_obj_t *chip_select,
|
||||
int baudrate,
|
||||
int width,
|
||||
int height,
|
||||
bool jdi_display) {
|
||||
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_never_reset_pin(chip_select);
|
||||
|
@ -139,6 +159,7 @@ void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_
|
|||
self->width = width;
|
||||
self->height = height;
|
||||
self->baudrate = baudrate;
|
||||
self->jdi_display = jdi_display;
|
||||
|
||||
common_hal_sharpdisplay_framebuffer_get_bufinfo(self, NULL);
|
||||
}
|
||||
|
@ -169,7 +190,8 @@ STATIC void common_hal_sharpdisplay_framebuffer_swapbuffers(sharpdisplay_framebu
|
|||
}
|
||||
|
||||
// output a trailing zero
|
||||
common_hal_busio_spi_write(self->bus, data, 1);
|
||||
uint8_t zero[2] = {0, 0};
|
||||
common_hal_busio_spi_write(self->bus, zero, self->jdi_display ? 2 : 1);
|
||||
|
||||
// set chip select low
|
||||
common_hal_digitalio_digitalinout_set_value(&self->chip_select, false);
|
||||
|
@ -191,7 +213,13 @@ STATIC void sharpdisplay_framebuffer_get_bufinfo(mp_obj_t self_in, mp_buffer_inf
|
|||
}
|
||||
|
||||
STATIC int sharpdisplay_framebuffer_get_color_depth(mp_obj_t self_in) {
|
||||
return 1;
|
||||
sharpdisplay_framebuffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return self->jdi_display ? 4 : 1;
|
||||
}
|
||||
|
||||
STATIC bool sharpdisplay_framebuffer_get_grayscale(mp_obj_t self_in) {
|
||||
sharpdisplay_framebuffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return !self->jdi_display;
|
||||
}
|
||||
|
||||
STATIC int sharpdisplay_framebuffer_get_height(mp_obj_t self_in) {
|
||||
|
@ -234,6 +262,7 @@ const framebuffer_p_t sharpdisplay_framebuffer_proto = {
|
|||
.deinit = sharpdisplay_framebuffer_deinit,
|
||||
.get_bufinfo = sharpdisplay_framebuffer_get_bufinfo,
|
||||
.get_color_depth = sharpdisplay_framebuffer_get_color_depth,
|
||||
.get_grayscale = sharpdisplay_framebuffer_get_grayscale,
|
||||
.get_height = sharpdisplay_framebuffer_get_height,
|
||||
.get_width = sharpdisplay_framebuffer_get_width,
|
||||
.swapbuffers = sharpdisplay_framebuffer_swapbuffers,
|
||||
|
|
|
@ -41,19 +41,10 @@ typedef struct {
|
|||
uint16_t width, height;
|
||||
uint32_t baudrate;
|
||||
|
||||
bool full_refresh : 1;
|
||||
bool full_refresh;
|
||||
bool jdi_display;
|
||||
} sharpdisplay_framebuffer_obj_t;
|
||||
|
||||
void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *chip_select, int baudrate, int width, int height);
|
||||
void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask);
|
||||
void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self);
|
||||
void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo);
|
||||
int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self);
|
||||
int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self);
|
||||
void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask);
|
||||
void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self);
|
||||
void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self);
|
||||
|
||||
extern const framebuffer_p_t sharpdisplay_framebuffer_proto;
|
||||
|
||||
void common_hal_sharpdisplay_framebuffer_collect_ptrs(sharpdisplay_framebuffer_obj_t *);
|
||||
|
|
|
@ -406,7 +406,7 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ
|
|||
if (self->pixel_shader == mp_const_none) {
|
||||
output_pixel.pixel = input_pixel.pixel;
|
||||
} else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) {
|
||||
output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel);
|
||||
displayio_palette_get_color(self->pixel_shader, colorspace, &input_pixel, &output_pixel);
|
||||
} else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) {
|
||||
displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,11 @@ void port_interrupt_after_ticks(uint32_t ticks);
|
|||
// may not be a system level sleep.
|
||||
void port_idle_until_interrupt(void);
|
||||
|
||||
// Execute port specific actions during background tasks.
|
||||
// Execute port specific actions during background tick. Only if ticks are enabled.
|
||||
void port_background_tick(void);
|
||||
|
||||
// Execute port specific actions during background tasks. This is before the
|
||||
// background callback system.
|
||||
void port_background_task(void);
|
||||
|
||||
// Take port specific actions at the beginning and end of background tasks.
|
||||
|
|
|
@ -74,6 +74,7 @@ bool PLACE_IN_ITCM(background_callback_pending)(void) {
|
|||
|
||||
static bool in_background_callback;
|
||||
void PLACE_IN_ITCM(background_callback_run_all)() {
|
||||
port_background_task();
|
||||
if (!background_callback_pending()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) {
|
|||
_private_advertising = true;
|
||||
// Advertise with less power when doing so publicly to reduce who can hear us. This will make it
|
||||
// harder for someone with bad intentions to pair from a distance.
|
||||
if (!bonded) {
|
||||
if (!bonded || boot_in_discovery_mode) {
|
||||
tx_power = -20;
|
||||
adv = public_advertising_data;
|
||||
adv_len = sizeof(public_advertising_data);
|
||||
|
@ -179,7 +179,7 @@ STATIC void supervisor_bluetooth_start_advertising(void) {
|
|||
}
|
||||
uint32_t status = _common_hal_bleio_adapter_start_advertising(&common_hal_bleio_adapter_obj,
|
||||
true,
|
||||
bonded, // Advertise anonymously if we are bonded
|
||||
_private_advertising, // Advertise anonymously if we are privately advertising
|
||||
timeout,
|
||||
interval,
|
||||
adv,
|
||||
|
|
|
@ -159,6 +159,14 @@ void supervisor_stop_terminal(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool supervisor_terminal_started(void) {
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
return tilegrid_tiles != NULL;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void supervisor_display_move_memory(void) {
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid;
|
||||
|
|
|
@ -54,6 +54,7 @@ extern displayio_tilegrid_t supervisor_blinka_sprite;
|
|||
|
||||
void supervisor_start_terminal(uint16_t width_px, uint16_t height_px);
|
||||
void supervisor_stop_terminal(void);
|
||||
bool supervisor_terminal_started(void);
|
||||
|
||||
void supervisor_display_move_memory(void);
|
||||
|
||||
|
|
|
@ -192,6 +192,12 @@ bool serial_connected(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_TERMINALIO
|
||||
if (supervisor_terminal_started()) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (port_serial_connected()) {
|
||||
return true;
|
||||
|
|
|
@ -66,13 +66,20 @@ for board in build_boards:
|
|||
if clean_build:
|
||||
build_dir += "-{language}".format(language=language)
|
||||
|
||||
extensions = [
|
||||
extension.strip()
|
||||
for extension in board_settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",")
|
||||
]
|
||||
|
||||
artifacts = [os.path.join(build_dir, "firmware." + extension) for extension in extensions]
|
||||
make_result = subprocess.run(
|
||||
"make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build} -j {cores}".format(
|
||||
"make -C ../ports/{port} TRANSLATION={language} BOARD={board} BUILD={build} -j {cores} {artifacts}".format(
|
||||
port=board_info["port"],
|
||||
language=language,
|
||||
board=board,
|
||||
build=build_dir,
|
||||
cores=cores,
|
||||
artifacts=" ".join(artifacts),
|
||||
),
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
|
@ -86,10 +93,6 @@ for board in build_boards:
|
|||
success = "\033[31mfailed\033[0m"
|
||||
|
||||
other_output = ""
|
||||
extensions = [
|
||||
extension.strip()
|
||||
for extension in board_settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",")
|
||||
]
|
||||
|
||||
for extension in extensions:
|
||||
temp_filename = "../ports/{port}/{build}/firmware.{extension}".format(
|
||||
|
|
|
@ -42,14 +42,14 @@ from shared_bindings_matrix import (
|
|||
all_ports_all_boards,
|
||||
)
|
||||
|
||||
PORT_TO_ARCH = {
|
||||
PORT_TO_BUILD_JOB = {
|
||||
"atmel-samd": "arm",
|
||||
"broadcom": "aarch",
|
||||
"cxd56": "arm",
|
||||
"espressif": "esp",
|
||||
"litex": "riscv",
|
||||
"mimxrt10xx": "arm",
|
||||
"nrf": "arm",
|
||||
"nrf": "nrf",
|
||||
"raspberrypi": "rpi",
|
||||
"stm": "arm",
|
||||
}
|
||||
|
@ -203,14 +203,14 @@ def set_boards_to_build(build_all: bool):
|
|||
boards_to_build = all_board_ids
|
||||
break
|
||||
|
||||
# Split boards by architecture.
|
||||
arch_to_boards = {"aarch": [], "arm": [], "esp": [], "riscv": [], "rpi": []}
|
||||
# Split boards by build job.
|
||||
build_job_to_boards = {"aarch": [], "arm": [], "esp": [], "nrf": [], "riscv": [], "rpi": []}
|
||||
|
||||
# Append previously failed boards
|
||||
for arch in arch_to_boards:
|
||||
arch_to_job = f"build-{arch}"
|
||||
if arch_to_job in last_failed_jobs:
|
||||
for board in last_failed_jobs[arch_to_job]:
|
||||
for build_job in build_job_to_boards:
|
||||
job_name = f"build-{build_job}"
|
||||
if job_name in last_failed_jobs:
|
||||
for board in last_failed_jobs[job_name]:
|
||||
if not board in boards_to_build:
|
||||
boards_to_build.append(board)
|
||||
|
||||
|
@ -225,12 +225,12 @@ def set_boards_to_build(build_all: bool):
|
|||
# if this happens it's not in `board_to_port`.
|
||||
if not port:
|
||||
continue
|
||||
arch_to_boards[PORT_TO_ARCH[port]].append(board)
|
||||
build_job_to_boards[PORT_TO_BUILD_JOB[port]].append(board)
|
||||
print(" ", board)
|
||||
|
||||
# Set the step outputs for each architecture
|
||||
for arch in arch_to_boards:
|
||||
set_output(f"boards-{arch}", json.dumps(arch_to_boards[arch]))
|
||||
for build_job in build_job_to_boards:
|
||||
set_output(f"boards-{build_job}", json.dumps(build_job_to_boards[build_job]))
|
||||
|
||||
|
||||
def set_docs_to_build(build_doc: bool):
|
||||
|
|
|
@ -180,51 +180,25 @@ displayio_bitmap_t blinka_bitmap = {{
|
|||
_displayio_color_t blinka_colors[7] = {{
|
||||
{{
|
||||
.rgb888 = 0x000000,
|
||||
.rgb565 = 0x0000,
|
||||
.luma = 0x00,
|
||||
.chroma = 0,
|
||||
.transparent = true
|
||||
}},
|
||||
{{
|
||||
.rgb888 = 0x8428bc,
|
||||
.rgb565 = 0x8978,
|
||||
.luma = 0xff, // We cheat the luma here. It is actually 0x60
|
||||
.hue = 184,
|
||||
.chroma = 148
|
||||
{{ // Purple
|
||||
.rgb888 = 0x8428bc
|
||||
}},
|
||||
{{
|
||||
.rgb888 = 0xff89bc,
|
||||
.rgb565 = 0xFCB8,
|
||||
.luma = 0xb5,
|
||||
.hue = 222,
|
||||
.chroma = 118
|
||||
{{ // Pink
|
||||
.rgb888 = 0xff89bc
|
||||
}},
|
||||
{{
|
||||
.rgb888 = 0x7beffe,
|
||||
.rgb565 = 0x869F,
|
||||
.luma = 0xe0,
|
||||
.hue = 124,
|
||||
.chroma = 131
|
||||
{{ // Light blue
|
||||
.rgb888 = 0x7beffe
|
||||
}},
|
||||
{{
|
||||
.rgb888 = 0x51395f,
|
||||
.rgb565 = 0x5A0D,
|
||||
.luma = 0x47,
|
||||
.hue = 185,
|
||||
.chroma = 38
|
||||
{{ // Dark purple
|
||||
.rgb888 = 0x51395f
|
||||
}},
|
||||
{{
|
||||
.rgb888 = 0xffffff,
|
||||
.rgb565 = 0xffff,
|
||||
.luma = 0xff,
|
||||
.chroma = 0
|
||||
{{ // White
|
||||
.rgb888 = 0xffffff
|
||||
}},
|
||||
{{
|
||||
.rgb888 = 0x0736a0,
|
||||
.rgb565 = 0x01f5,
|
||||
.luma = 0x44,
|
||||
.hue = 147,
|
||||
.chroma = 153
|
||||
{{ // Dark Blue
|
||||
.rgb888 = 0x0736a0
|
||||
}},
|
||||
}};
|
||||
|
||||
|
@ -270,16 +244,10 @@ c_file.write(
|
|||
#if CIRCUITPY_TERMINALIO
|
||||
_displayio_color_t terminal_colors[2] = {
|
||||
{
|
||||
.rgb888 = 0x000000,
|
||||
.rgb565 = 0x0000,
|
||||
.luma = 0x00,
|
||||
.chroma = 0
|
||||
.rgb888 = 0x000000
|
||||
},
|
||||
{
|
||||
.rgb888 = 0xffffff,
|
||||
.rgb565 = 0xffff,
|
||||
.luma = 0xff,
|
||||
.chroma = 0
|
||||
.rgb888 = 0xffffff
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue