diff --git a/ports/raspberrypi/boards/bradanlane_rp2040_dck01/board.c b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/board.c new file mode 100644 index 0000000000000..70d81003f4a9c --- /dev/null +++ b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/board.c @@ -0,0 +1,179 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Bradán Lane STUDIO + * + * 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/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/board.h" + +#define HEIGHT 200 +#define WIDTH 200 + +#define DELAY_FLAG 0x80 + +#define EPD_RAM_BW 0x10 +#define EPD_RAM_RED 0x13 +// #define BUSY_WAIT 500 + +// These commands are the combination of SSD1608 and SSD1681 and not all commands are supported for each controller +#define SSD_DRIVER_CONTROL 0x01 +#define SSD_GATE_VOLTAGE 0x03 +#define SSD_SOURCE_VOLTAGE 0x04 +#define SSD_DISPLAY_CONTROL 0x07 +#define SSD_PROGOTP_INITIAL 0x08 +#define SSD_WRITEREG_INITIAL 0x09 +#define SSD_READREG_INITIAL 0x0A +#define SSD_NON_OVERLAP 0x0B +#define SSD_BOOST_SOFT_START 0x0C +#define SSD_DEEP_SLEEP 0x10 +#define SSD_DATA_MODE 0x11 +#define SSD_SW_RESET 0x12 +#define SSD_HV_DETECT 0x14 +#define SSD_VCI_DETECT 0x15 +#define SSD1681_TEMP_CONTROL 0x18 +#define SSD1608_TEMP_CONTROL 0x1C +#define SSD_TEMP_WRITE 0x1A +#define SSD_TEMP_READ 0x1B +#define SSD_TEMP_EXTERN 0x1C +#define SSD_MASTER_ACTIVATE 0x20 +#define SSD_DISP_CTRL1 0x21 +#define SSD_DISP_CTRL2 0x22 +#define SSD_WRITE_RAM_BLK 0x24 +// #define SSD_READ_RAM_BLK 0x25 +#define SSD_WRITE_RAM_RED 0x26 +// #define SSD_READ_RAM_RED 0x27 +#define SSD_VCOM_SENSE 0x28 +// #define SSD_VCOM_DURRATION 0x29 +// #define SSD_PROG_VCOM 0x2A +// #define SSD_CTRL_VCOM 0x2B +// #define SSD_WRITE_VCOM 0x2C +#define SSD_READ_OTP 0x2D +#define SSD_READ_ID 0x2E +#define SSD_READ_STATUS 0x2F +#define SSD_WRITE_LUT 0x32 +#define SSD_WRITE_DUMMY 0x3A +#define SSD1608_WRITE_GATELINE 0x3B +#define SSD_WRITE_BORDER 0x3C +#define SSD_SET_RAMXPOS 0x44 +#define SSD_SET_RAMYPOS 0x45 +#define SSD_SET_RAMXCOUNT 0x4E +#define SSD_SET_RAMYCOUNT 0x4F +#define SSD_NOP 0xFF + +#define SSD_TEMP_CONTROL SSD1681_TEMP_CONTROL + +const uint8_t _start_sequence[] = { + SSD_SW_RESET, DELAY_FLAG + 0, 20, // soft reset and wait 20ms + SSD_DATA_MODE, 1, 0x03, // Data entry sequence + SSD_WRITE_BORDER, 1, 0x05, // border color + SSD_TEMP_CONTROL, 1, 0x80, // Temp control + SSD_SET_RAMXCOUNT, 1, 0x00, + SSD_SET_RAMYCOUNT, 2, 0x00, 0x00, + SSD_DRIVER_CONTROL, 3, ((WIDTH - 1) & 0xFF), (((WIDTH >> 8) - 1) & 0xFF), 0x00, // set display size + SSD_DISP_CTRL2, 1, 0xf7, // Set DISP only full refreshes +}; + +const uint8_t _stop_sequence[] = { + SSD_DEEP_SLEEP, DELAY_FLAG + 1, 1, 0x64 // Enter deep sleep +}; + +const uint8_t _refresh_sequence[] = { + SSD_MASTER_ACTIVATE, 0, +// SSD_SW_RESET, 0, +}; + +void board_init(void) { + // Set up the SPI object used to control the display + displayio_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, DEFAULT_SPI_BUS_SCK, DEFAULT_SPI_BUS_MOSI, NULL, false); + common_hal_busio_spi_never_reset(spi); + + // Set up the DisplayIO pin object + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + DEFAULT_SPI_BUS_DC, // EPD_DC Command or data + DEFAULT_SPI_BUS_CS, // EPD_CS Chip select + DEFAULT_SPI_BUS_RESET, // EPD_RST Reset + 1000000, // Baudrate + 0, // Polarity + 0); // Phase + + // Set up the DisplayIO epaper object + displayio_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; + display->base.type = &displayio_epaperdisplay_type; + + common_hal_displayio_epaperdisplay_construct( + display, + bus, + _start_sequence, sizeof(_start_sequence), + 1.0, // start up time + _stop_sequence, sizeof(_stop_sequence), + WIDTH, // width + HEIGHT, // height + WIDTH, // ram_width + HEIGHT + 0x60, // ram_height RAM is actually only 200 bits high but we use 296 to match the 9 bits + 0, // colstart + 0, // rowstart + 0, // rotation + SSD_SET_RAMXPOS, // set_column_window_command + SSD_SET_RAMYPOS, // set_row_window_command + SSD_SET_RAMXCOUNT, // set_current_column_command + SSD_SET_RAMYCOUNT, // set_current_row_command + SSD_WRITE_RAM_BLK, // write_black_ram_command + false, // black_bits_inverted + SSD_WRITE_RAM_RED, // write_color_ram_command + false, // color_bits_inverted + 0xFF0000, // highlight_color (RED for tri-color display) + _refresh_sequence, sizeof(_refresh_sequence), // refresh_display_command + 15.0, // refresh_time + DEFAULT_SPI_BUS_BUSY, // busy_pin + true, // busy_state + 20.0, // seconds_per_frame (does not seem the user can change this) + true, // always_toggle_chip_select + false, // grayscale + false, // acep + false, // two_byte_sequence_length + true); // address_little_endian +} + +void board_deinit(void) { + #if 0 + displayio_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &displayio_epaperdisplay_type) { + while (common_hal_displayio_epaperdisplay_get_busy(display)) { + // RUN_BACKGROUND_TASKS; + } + } + common_hal_displayio_release_displays(); + #endif +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/bradanlane_rp2040_dck01/mpconfigboard.h b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/mpconfigboard.h new file mode 100644 index 0000000000000..b44cb56e18a6f --- /dev/null +++ b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Bradán Lane STUDIO + * + * 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. + */ + +#pragma once + +#define MICROPY_HW_BOARD_NAME "DCK01" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_SPI_BUS_BUSY (&pin_GPIO9) +#define DEFAULT_SPI_BUS_RESET (&pin_GPIO10) +#define DEFAULT_SPI_BUS_DC (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12) +#define DEFAULT_SPI_BUS_CS (&pin_GPIO13) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) diff --git a/ports/raspberrypi/boards/bradanlane_rp2040_dck01/mpconfigboard.mk b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/mpconfigboard.mk new file mode 100644 index 0000000000000..8aa3c93b2c191 --- /dev/null +++ b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/mpconfigboard.mk @@ -0,0 +1,12 @@ +USB_VID = 0x2E8A +USB_PID = 0x1073 +USB_PRODUCT = "RP2040 DCK01" +USB_MANUFACTURER = "Bradán Lane STUDIO" +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C" + +CIRCUITPY__EVE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text diff --git a/ports/raspberrypi/boards/bradanlane_rp2040_dck01/pico-sdk-configboard.h b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/pico-sdk-configboard.h new file mode 100644 index 0000000000000..36da55d457197 --- /dev/null +++ b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/bradanlane_rp2040_dck01/pins.c b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/pins.c new file mode 100644 index 0000000000000..8eecb55e69e8a --- /dev/null +++ b/ports/raspberrypi/boards/bradanlane_rp2040_dck01/pins.c @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Bradán Lane STUDIO + * + * 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 "mpconfigboard.h" + +#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_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + // GPIO0 and GPIO1 are also the UART + { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(DEFAULT_UART_BUS_TX) }, + { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(DEFAULT_UART_BUS_RX) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + // GPIO2 and GPIO3 are also the I2C + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(DEFAULT_I2C_BUS_SDA) }, + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(DEFAULT_I2C_BUS_SCL) }, + + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + // GPIO4 is also the LED + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(MICROPY_HW_LED_STATUS) }, + + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + // GPIO5 is also the NEOPIXEL + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + // GPIO6 is also the speaker (PWM) and GPIO7 is the enable + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER_EN), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + // GPIO9 thru GPIO15 are the SPI for the ePaper display + { MP_ROM_QSTR(MP_QSTR_SPI_BUSY), MP_ROM_PTR(DEFAULT_SPI_BUS_BUSY) }, + { MP_ROM_QSTR(MP_QSTR_SPI_RESET), MP_ROM_PTR(DEFAULT_SPI_BUS_RESET) }, + { MP_ROM_QSTR(MP_QSTR_SPI_DC), MP_ROM_PTR(DEFAULT_SPI_BUS_DC) }, + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(DEFAULT_SPI_BUS_MISO) }, + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(DEFAULT_SPI_BUS_CS) }, + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(DEFAULT_SPI_BUS_SCK) }, + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(DEFAULT_SPI_BUS_MOSI) }, + + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + // GPIO16 thru GPIO18 are also the I2S audio + { MP_ROM_QSTR(MP_QSTR_I2S_DATA), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCK), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + // GPIO19 thru GPIO24 are also the touch sensors + { MP_ROM_QSTR(MP_QSTR_TOUCH1), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH3), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH4), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH5), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH6), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + // GPIO26 thru GPIO29 are also the analog pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)}, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);