Merge branch 'main' into typing-fixes

This commit is contained in:
Justin Myers 2024-02-09 08:36:21 -08:00
commit e906873527
33 changed files with 354 additions and 265 deletions

View file

@ -20,7 +20,7 @@ CIRCUITPY_USB_MIDI = 0
# So not all of displayio, sorry!
CIRCUITPY_VECTORIO = 0
CIRCUITPY_BITMAPTOOLS = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_CircuitPlayground/frozen_cpx

View file

@ -14,7 +14,7 @@ CIRCUITPY_LTO_PARTITION = one
CIRCUITPY_AESIO = 0
CIRCUITPY_FLOPPYIO = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_SHARPDISPLAY = 0
CIRCUITPY_ULAB = 0

View file

@ -22,7 +22,7 @@ CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CTARGET = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_ONEWIREIO = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_PIXELBUF = 0
CIRCUITPY_PS2IO = 0
CIRCUITPY_PULSEIO = 0

View file

@ -24,7 +24,7 @@ CIRCUITPY_BITMAPTOOLS = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CTARGET = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_PIXELBUF = 0
CIRCUITPY_RTC = 0
CIRCUITPY_TOUCHIO = 0

View file

@ -490,6 +490,9 @@ endif
ifneq ($(CIRCUITPY_DOTCLOCKFRAMEBUFFER),0)
ESP_IDF_COMPONENTS_LINK += esp_lcd
endif
ifneq ($(CIRCUITPY_PARALLELDISPLAYBUS),0)
ESP_IDF_COMPONENTS_LINK += esp_lcd
endif
ESP_IDF_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a)

View file

@ -20,7 +20,7 @@ CIRCUITPY_ESPCAMERA = 1
CIRCUITPY_FRAMEBUFFERIO = 0
CIRCUITPY_KEYPAD = 0
CIRCUITPY_ONEWIREIO = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_RGBMATRIX = 0
CIRCUITPY_ROTARYIO = 0

View file

@ -15,3 +15,4 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m
OPTIMIZATION_FLAGS = -Os
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -15,5 +15,6 @@ CIRCUITPY_ESP_PSRAM_MODE = qio
CIRCUITPY_ESP_PSRAM_FREQ = 80m
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
OPTIMIZATION_FLAGS = -Os

View file

@ -12,6 +12,7 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB
OPTIMIZATION_FLAGS = -Os
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_ESP_PSRAM_SIZE = 2MB
CIRCUITPY_ESP_PSRAM_MODE = qio

View file

@ -14,3 +14,6 @@ CIRCUITPY_ESP_PSRAM_MODE = qio
CIRCUITPY_ESP_PSRAM_FREQ = 80m
CIRCUITPY_ESP32_CAMERA = 0
# Not enough pins.
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -10,3 +10,6 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m
CIRCUITPY_ESP_PSRAM_SIZE = 2MB
CIRCUITPY_ESP_PSRAM_MODE = qio
CIRCUITPY_ESP_PSRAM_FREQ = 80m
# Not enough pins.
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -10,3 +10,6 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB
CIRCUITPY_ESP_USB_SERIAL_JTAG = 1
CIRCUITPY_BLEIO = 0
# Not enough pins.
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -13,3 +13,6 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB
CIRCUITPY_ESP_PSRAM_SIZE = 2MB
CIRCUITPY_ESP_PSRAM_MODE = qio
CIRCUITPY_ESP_PSRAM_FREQ = 80m
# Not enough pins.
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -15,3 +15,5 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m
OPTIMIZATION_FLAGS = -Os
CIRCUITPY_ESPCAMERA = 0
# Not enough pins.
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -11,3 +11,6 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m
CIRCUITPY_ESP_FLASH_SIZE = 8MB
CIRCUITPY_ESPCAMERA = 0
# Not enough pins.
CIRCUITPY_PARALLELDISPLAYBUS = 0

View file

@ -16,5 +16,6 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_BITMAPFILTER = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
OPTIMIZATION_FLAGS = -Os

View file

@ -0,0 +1,131 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 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 "mpconfigboard.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/mipi_constants.h"
#define DELAY 0x80
// display init sequence according to LilyGO example app
uint8_t display_init_sequence[] = {
// sw reset
0x01, 0 | DELAY, 150,
// sleep out
0x11, 0 | DELAY, 255,
// colmod and delay 10ms
0x3A, 1 | DELAY, 0x55, 10,
0x21, 0 | DELAY, 10,
// normal display mode on
0x13, 0 | DELAY, 10,
// madctl display and color format settings
0x36, 1, 0x60,
// ST7789V gamma setting
// 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17,
// 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E,
// display on
0x29, 0 | DELAY, 255,
};
static void display_init(void) {
gpio_set_direction(15, GPIO_MODE_DEF_OUTPUT);
gpio_set_level(15, true);
paralleldisplaybus_parallelbus_obj_t *bus = &allocate_display_bus()->parallel_bus;
bus->base.type = &paralleldisplaybus_parallelbus_type;
const mcu_pin_obj_t *data_pins[] = {
&pin_GPIO39,
&pin_GPIO40,
&pin_GPIO41,
&pin_GPIO42,
&pin_GPIO45,
&pin_GPIO46,
&pin_GPIO47,
&pin_GPIO48
};
common_hal_paralleldisplaybus_parallelbus_construct_nonsequential(bus,
8, // num pins
data_pins, // Data pins
&pin_GPIO7, // Command or data
&pin_GPIO6, // Chip select
&pin_GPIO8, // Write
&pin_GPIO9, // Read
&pin_GPIO5, // Reset
15000000); // Frequency. ST7789 datasheet says min clock cycle is 66ns which is ~15 mhz.
busdisplay_busdisplay_obj_t *display = &allocate_display()->display;
display->base.type = &busdisplay_busdisplay_type;
common_hal_busdisplay_busdisplay_construct(display,
bus,
320, // Width
170, // Height
0, // column start
35, // row start
0, // rotation
16, // Color depth
false, // grayscale
false, // pixels_in_byte_share_row (unused for depths > 8)
1, // bytes per cell. Only valid for depths < 8
false, // reverse_pixels_in_byte. Only valid for depths < 8
true, // reverse_pixels_in_word
MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command
MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command
MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command
display_init_sequence,
sizeof(display_init_sequence),
&pin_GPIO38, // Backlight pin
NO_BRIGHTNESS_COMMAND,
1.0f, // brightness
false, // single_byte_bounds
false, // data_as_commands
true, // auto_refresh
60, // native_frames_per_second
true, // backlight_on_high
false, // SH1107_addressing
50000); // backlight pwm frequency
}
void board_init(void) {
// Display
display_init();
}
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
// Override the I2C/TFT power pin reset to prevent resetting the display.
if (pin_number == 15) {
// Turn on TFT
gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT);
gpio_set_level(pin_number, true);
return true;
}
return false;
}
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

View file

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Jeff Epler for Adafruit Industries
* 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
@ -24,19 +24,10 @@
* THE SOFTWARE.
*/
#pragma once
// Micropython setup
#include "py/obj.h"
#include "shared-bindings/imagecapture/ParallelImageCapture.h"
#include "cam.h"
#define MICROPY_HW_BOARD_NAME "LILYGO T-DISPLAY S3 v1.2"
#define MICROPY_HW_MCU_NAME "ESP32S3"
struct imagecapture_parallelimagecapture_obj {
mp_obj_base_t base;
cam_config_t config;
gpio_num_t data_clock;
gpio_num_t vertical_sync;
gpio_num_t horizontal_reference;
uint8_t data_count;
mp_obj_t buffer1, buffer2;
uint8_t *buffer_to_give;
};
#define DEFAULT_UART_BUS_RX (&pin_GPIO44)
#define DEFAULT_UART_BUS_TX (&pin_GPIO43)

View file

@ -0,0 +1,14 @@
USB_VID = 0x303a
USB_PID = 0x813F
USB_PRODUCT = "T-Display S3"
USB_MANUFACTURER = "LILYGO"
IDF_TARGET = esp32s3
CIRCUITPY_ESP_FLASH_SIZE = 16MB
CIRCUITPY_ESP_FLASH_MODE = qio
CIRCUITPY_ESP_FLASH_FREQ = 80m
CIRCUITPY_ESP_PSRAM_SIZE = 8MB
CIRCUITPY_ESP_PSRAM_MODE = opi
CIRCUITPY_ESP_PSRAM_FREQ = 80m

View file

@ -0,0 +1,59 @@
#include "shared-bindings/board/__init__.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_BUTTON0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) },
// Left side
{ MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) },
{ MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) },
// Right side.
{ MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) },
{ MP_ROM_QSTR(MP_QSTR_STEMMA_SDA), MP_ROM_PTR(&pin_GPIO43) },
{ MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) },
{ MP_ROM_QSTR(MP_QSTR_STEMMA_SCL), MP_ROM_PTR(&pin_GPIO44) },
{ MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_SDA), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_SCL), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_RES), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO16) },
// 1.14 inch LCD ST7789
{ MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO38) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D0), MP_ROM_PTR(&pin_GPIO39) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D1), MP_ROM_PTR(&pin_GPIO40) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D2), MP_ROM_PTR(&pin_GPIO41) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D3), MP_ROM_PTR(&pin_GPIO42) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D4), MP_ROM_PTR(&pin_GPIO45) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D5), MP_ROM_PTR(&pin_GPIO46) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D6), MP_ROM_PTR(&pin_GPIO47) },
{ MP_ROM_QSTR(MP_QSTR_LCD_D7), MP_ROM_PTR(&pin_GPIO48) },
{ MP_ROM_QSTR(MP_QSTR_LCD_WR), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_LCD_RD), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_LCD_POWER_ON), MP_ROM_PTR(&pin_GPIO15) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) },
// Battery Sense
{ MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO4) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View file

@ -0,0 +1,15 @@
#
# Espressif IoT Development Framework Configuration
#
#
# Component config
#
#
# LWIP
#
CONFIG_LWIP_LOCAL_HOSTNAME="T-DISPLAY-S3"
# end of LWIP
# end of Component config
# end of Espressif IoT Development Framework Configuration

View file

@ -17,6 +17,7 @@ OPTIMIZATION_FLAGS = -Os
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_BITMAPFILTER = 0
CIRCUITPY_CODEOP=0
CIRCUITPY_PARALLELDISPLAYBUS = 0
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel

View file

@ -16,6 +16,7 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m
OPTIMIZATION_FLAGS = -Os
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_BITMAPFILTER = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
# Include these Python libraries in firmware.
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel

View file

@ -1,177 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Jeff Epler 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 <string.h>
#include "py/obj.h"
#include "py/runtime.h"
#include "common-hal/audiobusio/__init__.h"
#include "common-hal/imagecapture/ParallelImageCapture.h"
#include "cam.h"
void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_parallelimagecapture_obj_t *self,
const uint8_t data_pins[],
uint8_t data_count,
const mcu_pin_obj_t *data_clock,
const mcu_pin_obj_t *vertical_sync,
const mcu_pin_obj_t *horizontal_reference) {
// only 8 bits is supported at present
mp_arg_validate_int_range(data_count, 8, 16, MP_QSTR_data_count);
// This will throw if unsuccessful. Everything following is guaranteed to succeed.
port_i2s_allocate_i2s0();
claim_pin(data_clock);
claim_pin(vertical_sync);
claim_pin(horizontal_reference);
self->data_count = data_count;
self->data_clock = data_clock->number;
self->vertical_sync = vertical_sync->number;
self->horizontal_reference = horizontal_reference->number;
self->config = (cam_config_t) {
.bit_width = data_count,
.pin = {
.pclk = data_clock->number,
.vsync = vertical_sync->number,
.hsync = horizontal_reference->number,
},
.vsync_invert = true,
.hsync_invert = false,
.size = 0,
.max_buffer_size = 8 * 1024,
.task_stack = 1024,
.task_pri = configMAX_PRIORITIES
};
for (int i = 0; i < data_count; i++) {
claim_pin_number(data_pins[i]);
self->config.pin_data[i] = data_pins[i];
}
}
void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) {
cam_deinit();
self->buffer1 = NULL;
self->buffer2 = NULL;
reset_pin_number(self->data_clock);
self->data_clock = NO_PIN;
reset_pin_number(self->vertical_sync);
self->vertical_sync = NO_PIN;
reset_pin_number(self->horizontal_reference);
self->horizontal_reference = NO_PIN;
for (int i = 0; i < self->data_count; i++) {
if (self->config.pin_data[i] != NO_PIN) {
reset_pin_number(self->config.pin_data[i]);
self->config.pin_data[i] = NO_PIN;
}
}
port_i2s_reset_instance(0);
}
bool common_hal_imagecapture_parallelimagecapture_deinited(imagecapture_parallelimagecapture_obj_t *self) {
return self->data_clock == NO_PIN;
}
void common_hal_imagecapture_parallelimagecapture_continuous_capture_start(imagecapture_parallelimagecapture_obj_t *self, mp_obj_t buffer1, mp_obj_t buffer2) {
if (buffer1 == self->buffer1 && buffer2 == self->buffer2) {
return;
}
mp_buffer_info_t bufinfo1, bufinfo2 = {};
mp_get_buffer_raise(buffer1, &bufinfo1, MP_BUFFER_RW);
if (buffer2 != mp_const_none) {
mp_get_buffer_raise(buffer2, &bufinfo2, MP_BUFFER_RW);
if (bufinfo1.len != bufinfo2.len) {
mp_raise_ValueError(MP_ERROR_TEXT("Buffers must be same size"));
}
}
self->buffer1 = buffer1;
self->buffer2 = buffer2;
cam_deinit();
self->config.size = bufinfo1.len / 2; // count is in pixels
self->config.frame1_buffer = bufinfo1.buf;
self->config.frame2_buffer = bufinfo2.buf;
self->buffer_to_give = NULL;
cam_init(&self->config);
cam_start();
}
void common_hal_imagecapture_parallelimagecapture_continuous_capture_stop(imagecapture_parallelimagecapture_obj_t *self) {
cam_deinit();
self->buffer1 = self->buffer2 = NULL;
self->buffer_to_give = NULL;
}
STATIC void common_hal_imagecapture_parallelimagecapture_continuous_capture_give_frame(imagecapture_parallelimagecapture_obj_t *self) {
if (self->buffer_to_give) {
cam_give(self->buffer_to_give);
self->buffer_to_give = NULL;
}
}
mp_obj_t common_hal_imagecapture_parallelimagecapture_continuous_capture_get_frame(imagecapture_parallelimagecapture_obj_t *self) {
if (self->buffer1 == NULL) {
mp_raise_RuntimeError(MP_ERROR_TEXT("No capture in progress"));
}
common_hal_imagecapture_parallelimagecapture_continuous_capture_give_frame(self);
while (!cam_ready()) {
RUN_BACKGROUND_TASKS;
if (mp_hal_is_interrupted()) {
return mp_const_none;
}
}
cam_take(&self->buffer_to_give);
if (self->buffer_to_give == self->config.frame1_buffer) {
return self->buffer1;
}
if (self->buffer_to_give == self->config.frame2_buffer) {
return self->buffer2;
}
return mp_const_none; // should be unreachable
}
void common_hal_imagecapture_parallelimagecapture_singleshot_capture(imagecapture_parallelimagecapture_obj_t *self, mp_obj_t buffer) {
common_hal_imagecapture_parallelimagecapture_continuous_capture_start(self, buffer, mp_const_none);
common_hal_imagecapture_parallelimagecapture_continuous_capture_get_frame(self);
}

View file

@ -28,6 +28,8 @@
#include <string.h>
#include "shared-bindings/paralleldisplaybus/ParallelBus.h"
#include "bindings/espidf/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/microcontroller/__init__.h"
@ -42,6 +44,11 @@
* Current pin limitations for ESP32-S2 ParallelBus:
* - data0 pin must be byte aligned
*/
STATIC bool _transfer_done(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx) {
paralleldisplaybus_parallelbus_obj_t *self = user_ctx;
self->transfer_done = true;
return false;
}
void common_hal_paralleldisplaybus_parallelbus_construct_nonsequential(paralleldisplaybus_parallelbus_obj_t *self,
uint8_t n_pins, const mcu_pin_obj_t **data_pins,
@ -58,24 +65,29 @@ void common_hal_paralleldisplaybus_parallelbus_construct_nonsequential(paralleld
}
}
// This will throw if unsuccessful. Everything following is guaranteed to succeed.
port_i2s_allocate_i2s0();
i2s_lcd_config_t config = {
.data_width = n_pins,
.pin_num_cs = common_hal_mcu_pin_number(chip_select),
.pin_num_wr = common_hal_mcu_pin_number(write), // write strobe
.pin_num_rs = common_hal_mcu_pin_number(command), // The "register select" pin is called "command" by CircuitPython
.clk_freq = frequency,
.i2s_port = 0,
.swap_data = false,
.buffer_size = 512,
};
self->config.dc_gpio_num = common_hal_mcu_pin_number(command);
self->config.wr_gpio_num = common_hal_mcu_pin_number(write); // write strobe
self->config.clk_src = LCD_CLK_SRC_DEFAULT;
self->config.bus_width = n_pins;
self->config.max_transfer_bytes = 512;
for (uint8_t i = 0; i < n_pins; i++) {
common_hal_never_reset_pin(data_pins[i]);
config.pin_data_num[i] = common_hal_mcu_pin_number(data_pins[i]);
self->config.data_gpio_nums[i] = common_hal_mcu_pin_number(data_pins[i]);
}
CHECK_ESP_RESULT(esp_lcd_new_i80_bus(&self->config, &self->bus_handle));
esp_lcd_panel_io_i80_config_t panel_io_config = {
.cs_gpio_num = -1, // We manage CS
.pclk_hz = frequency,
.trans_queue_depth = 1, // We block anyway
.on_color_trans_done = _transfer_done,
.user_ctx = self,
.lcd_cmd_bits = 8,
.lcd_param_bits = 8
};
panel_io_config.dc_levels.dc_cmd_level = 0;
panel_io_config.dc_levels.dc_data_level = 1;
panel_io_config.dc_levels.dc_idle_level = 1;
CHECK_ESP_RESULT(esp_lcd_new_panel_io_i80(self->bus_handle, &panel_io_config, &self->panel_io_handle));
if (read != NULL) {
common_hal_never_reset_pin(read);
@ -97,16 +109,23 @@ void common_hal_paralleldisplaybus_parallelbus_construct_nonsequential(paralleld
self->reset_pin_number = reset->number;
}
self->cs_pin_number = common_hal_mcu_pin_number(chip_select);
gpio_config_t chip_select_config = {
.pin_bit_mask = 1ull << self->cs_pin_number,
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&chip_select_config);
gpio_set_level(self->cs_pin_number, true);
common_hal_never_reset_pin(chip_select);
common_hal_never_reset_pin(command);
common_hal_never_reset_pin(write);
self->config = config;
self->handle = i2s_lcd_driver_init(&config);
if (!self->handle) {
port_i2s_reset_instance(0);
mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error"));
for (uint8_t i = 0; i < n_pins; i++) {
common_hal_never_reset_pin(data_pins[i]);
}
}
@ -126,23 +145,22 @@ void common_hal_paralleldisplaybus_parallelbus_construct(paralleldisplaybus_para
void common_hal_paralleldisplaybus_parallelbus_deinit(paralleldisplaybus_parallelbus_obj_t *self) {
if (!self->handle) {
if (!self->panel_io_handle) {
return;
}
i2s_lcd_driver_deinit(self->handle);
self->handle = NULL;
/* SNIP - same as from SAMD and NRF ports */
for (uint8_t i = 0; i < self->config.data_width; i++) {
reset_pin_number(self->config.pin_data_num[i]);
esp_lcd_panel_io_del(self->panel_io_handle);
self->panel_io_handle = NULL;
esp_lcd_del_i80_bus(self->bus_handle);
self->bus_handle = NULL;
for (uint8_t i = 0; i < self->config.bus_width; i++) {
reset_pin_number(self->config.data_gpio_nums[i]);
}
reset_pin_number(self->config.pin_num_cs);
reset_pin_number(self->config.pin_num_wr);
reset_pin_number(self->config.pin_num_rs);
reset_pin_number(self->config.dc_gpio_num);
reset_pin_number(self->config.wr_gpio_num);
reset_pin_number(self->cs_pin_number);
reset_pin_number(self->read_pin_number);
reset_pin_number(self->reset_pin_number);
port_i2s_reset_instance(0);
}
bool common_hal_paralleldisplaybus_parallelbus_reset(mp_obj_t obj) {
@ -166,25 +184,33 @@ bool common_hal_paralleldisplaybus_parallelbus_bus_free(mp_obj_t obj) {
bool common_hal_paralleldisplaybus_parallelbus_begin_transaction(mp_obj_t obj) {
paralleldisplaybus_parallelbus_obj_t *self = MP_OBJ_TO_PTR(obj);
bool lock_acquired = false;
i2s_lcd_acquire_nonblocking(self->handle, 1, &lock_acquired);
if (lock_acquired) {
gpio_set_level(self->config.pin_num_cs, false);
}
return lock_acquired;
gpio_set_level(self->cs_pin_number, false);
return true;
}
void common_hal_paralleldisplaybus_parallelbus_send(mp_obj_t obj, display_byte_type_t byte_type,
display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) {
paralleldisplaybus_parallelbus_obj_t *self = MP_OBJ_TO_PTR(obj);
if (data_length) {
gpio_set_level(self->config.pin_num_rs, byte_type == DISPLAY_DATA);
i2s_lcd_write(self->handle, data, data_length);
if (data_length == 0) {
return;
}
if (byte_type == DISPLAY_DATA) {
// We don't use the color transmit function because this buffer will be small-ish. displayio
// will already partition it into small pieces.
self->transfer_done = false;
CHECK_ESP_RESULT(esp_lcd_panel_io_tx_color(self->panel_io_handle, -1, data, data_length));
while (!self->transfer_done) {
RUN_BACKGROUND_TASKS;
}
} else if (data_length == 1) {
CHECK_ESP_RESULT(esp_lcd_panel_io_tx_param(self->panel_io_handle, data[0], NULL, 0));
} else {
// Command with length > 1 isn't supported.
}
}
void common_hal_paralleldisplaybus_parallelbus_end_transaction(mp_obj_t obj) {
paralleldisplaybus_parallelbus_obj_t *self = MP_OBJ_TO_PTR(obj);
i2s_lcd_release(self->handle);
gpio_set_level(self->config.pin_num_cs, true);
gpio_set_level(self->cs_pin_number, true);
}

View file

@ -27,12 +27,16 @@
#pragma once
#include "common-hal/digitalio/DigitalInOut.h"
#include "i2s_lcd_driver.h"
#include "esp-idf/components/esp_lcd/include/esp_lcd_panel_io.h"
typedef struct {
mp_obj_base_t base;
gpio_num_t cs_pin_number;
gpio_num_t read_pin_number;
gpio_num_t reset_pin_number;
i2s_lcd_config_t config;
i2s_lcd_handle_t handle;
esp_lcd_i80_bus_config_t config;
esp_lcd_i80_bus_handle_t bus_handle;
esp_lcd_panel_io_handle_t panel_io_handle;
bool transfer_done;
} paralleldisplaybus_parallelbus_obj_t;

View file

@ -33,11 +33,9 @@ CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_FREQUENCYIO ?= 1
CIRCUITPY_HASHLIB ?= 1
CIRCUITPY_I2CTARGET ?= 0
CIRCUITPY_IMAGECAPTURE = 0
CIRCUITPY_MEMORYMAP ?= 1
CIRCUITPY_NVM ?= 1
# Turn off because it uses the old I2S driver which conflicts with the new ADC driver.
CIRCUITPY_PARALLELDISPLAYBUS ?= 0
CIRCUITPY_PARALLELDISPLAYBUS ?= 1
CIRCUITPY_PS2IO ?= 1
CIRCUITPY_RGBMATRIX ?= 1
CIRCUITPY_ROTARYIO ?= 1
@ -63,7 +61,7 @@ CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_ESPULP = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_MEMORYMAP = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_TOUCHIO ?= 1
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
@ -78,7 +76,7 @@ CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_ESPULP = 0
CIRCUITPY_MEMORYMAP = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_TOUCHIO ?= 1
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
# Features
@ -95,7 +93,7 @@ CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_ESPCAMERA = 0
CIRCUITPY_ESPULP = 0
CIRCUITPY_MEMORYMAP = 0
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_RGBMATRIX = 0
CIRCUITPY_TOUCHIO ?= 1
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
@ -115,7 +113,6 @@ CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 0
else ifeq ($(IDF_TARGET),esp32s3)
# Modules
CIRCUITPY_BITMAPFILTER ?= $(CIRCUITPY_ESPCAMERA)
CIRCUITPY_PARALLELDISPLAY = 0
CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION = 0
CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 0

View file

@ -10,9 +10,11 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_L), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_R), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) },

View file

@ -43,10 +43,11 @@
//| def __init__(
//| self,
//| *,
//| data0: microcontroller.Pin,
//| command: microcontroller.Pin,
//| chip_select: microcontroller.Pin,
//| write: microcontroller.Pin,
//| data0: Optional[microcontroller.Pin] = None,
//| data_pins: Optional[Sequence[microcontroller.Pin]] = None,
//| read: Optional[microcontroller.Pin],
//| reset: Optional[microcontroller.Pin] = None,
//| frequency: int = 30_000_000,

View file

@ -62,7 +62,7 @@ STATIC const uint16_t triangle[] = {0, 32767, 0, -32767};
//|
//| def __init__(
//| self,
//| waveform: ReadableBuffer,
//| waveform: Optional[ReadableBuffer] = None,
//| *,
//| rate: BlockInput = 1.0,
//| scale: BlockInput = 1.0,

View file

@ -1,26 +1,26 @@
# SPDX-FileCopyrightText: 2024 Tim Cocks
#
# SPDX-License-Identifier: MIT
import sys
from importlib import resources
import os
import sys
import shutil
def set_board():
if len(sys.argv) != 2:
print(f"Incorrect args. Please call with: 'circuitpython_setboard chosen_board'")
return
chosen_board = sys.argv[1]
print(f"setting board: {chosen_board}")
board_defs_path = (
os.path.sep.join(__file__.split("/")[:-2]) + f"{os.path.sep}board_definitions{os.path.sep}"
)
board_stubs_path = (
os.path.sep.join(__file__.split("/")[:-2])
+ f"{os.path.sep}board-stubs{os.path.sep}__init__.pyi"
)
if chosen_board not in os.listdir(board_defs_path):
board_stubs_file = resources.files("board-stubs").joinpath("__init__.pyi")
board_definitions_path = resources.files("board_definitions").joinpath(chosen_board)
board_definitions_file = board_definitions_path.joinpath("__init__.pyi")
if not board_definitions_file.is_file():
print(f"Board: '{chosen_board}' was not found")
return
shutil.copyfile(
board_defs_path + f"{os.path.sep}{chosen_board}{os.path.sep}__init__.pyi", board_stubs_path
)
shutil.copyfile(board_definitions_file, board_stubs_file)