diff --git a/.gitmodules b/.gitmodules index 9c8d3b4b68..e2e90243a4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -324,3 +324,6 @@ path = ports/broadcom/peripherals url = https://github.com/adafruit/broadcom-peripherals.git branch = main-build +[submodule "frozen/circuitpython-pcf85063a"] + path = frozen/circuitpython-pcf85063a + url = https://github.com/bablokb/circuitpython-pcf85063a diff --git a/frozen/circuitpython-pcf85063a b/frozen/circuitpython-pcf85063a new file mode 160000 index 0000000000..21baeb6479 --- /dev/null +++ b/frozen/circuitpython-pcf85063a @@ -0,0 +1 @@ +Subproject commit 21baeb6479434b950e9356a320a5a4d050a4bf47 diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/badger-shared.h b/ports/raspberrypi/boards/pimoroni_badger2040w/badger-shared.h new file mode 100644 index 0000000000..5a64e9e00b --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/badger-shared.h @@ -0,0 +1,8 @@ +#ifndef PIMORONI_BADGER2040W_SHARED +#define PIMORONI_BADGER2040W_SHARED + +#include "shared-bindings/digitalio/DigitalInOut.h" + +extern digitalio_digitalinout_obj_t enable_pin_obj; + +#endif // PIMORONI_BADGER2040W_SHARED diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c new file mode 100644 index 0000000000..9eea472925 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c @@ -0,0 +1,341 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 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/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" +#include "badger-shared.h" + +digitalio_digitalinout_obj_t enable_pin_obj; + +#define DELAY 0x80 + +enum reg { + PSR = 0x00, + PWR = 0x01, + POF = 0x02, + PFS = 0x03, + PON = 0x04, + PMES = 0x05, + BTST = 0x06, + DSLP = 0x07, + DTM1 = 0x10, + DSP = 0x11, + DRF = 0x12, + DTM2 = 0x13, + LUT_VCOM = 0x20, + LUT_WW = 0x21, + LUT_BW = 0x22, + LUT_WB = 0x23, + LUT_BB = 0x24, + PLL = 0x30, + TSC = 0x40, + TSE = 0x41, + TSR = 0x43, + TSW = 0x42, + CDI = 0x50, + LPD = 0x51, + TCON = 0x60, + TRES = 0x61, + REV = 0x70, + FLG = 0x71, + AMV = 0x80, + VV = 0x81, + VDCS = 0x82, + PTL = 0x90, + PTIN = 0x91, + PTOU = 0x92, + PGM = 0xa0, + APG = 0xa1, + ROTP = 0xa2, + CCSET = 0xe0, + PWS = 0xe3, + TSSET = 0xe5 +}; + +enum PSR_FLAGS { + RES_96x230 = 0b00000000, + RES_96x252 = 0b01000000, + RES_128x296 = 0b10000000, + RES_160x296 = 0b11000000, + + LUT_OTP = 0b00000000, + LUT_REG = 0b00100000, + + FORMAT_BWR = 0b00000000, + FORMAT_BW = 0b00010000, + + SCAN_DOWN = 0b00000000, + SCAN_UP = 0b00001000, + + SHIFT_LEFT = 0b00000000, + SHIFT_RIGHT = 0b00000100, + + BOOSTER_OFF = 0b00000000, + BOOSTER_ON = 0b00000010, + + RESET_SOFT = 0b00000000, + RESET_NONE = 0b00000001 +}; + +enum PWR_FLAGS_1 { + VDS_EXTERNAL = 0b00000000, + VDS_INTERNAL = 0b00000010, + + VDG_EXTERNAL = 0b00000000, + VDG_INTERNAL = 0b00000001 +}; + +enum PWR_FLAGS_2 { + VCOM_VD = 0b00000000, + VCOM_VG = 0b00000100, + + VGHL_16V = 0b00000000, + VGHL_15V = 0b00000001, + VGHL_14V = 0b00000010, + VGHL_13V = 0b00000011 +}; + +enum BOOSTER_FLAGS { + START_10MS = 0b00000000, + START_20MS = 0b01000000, + START_30MS = 0b10000000, + START_40MS = 0b11000000, + + STRENGTH_1 = 0b00000000, + STRENGTH_2 = 0b00001000, + STRENGTH_3 = 0b00010000, + STRENGTH_4 = 0b00011000, + STRENGTH_5 = 0b00100000, + STRENGTH_6 = 0b00101000, + STRENGTH_7 = 0b00110000, + STRENGTH_8 = 0b00111000, + + OFF_0_27US = 0b00000000, + OFF_0_34US = 0b00000001, + OFF_0_40US = 0b00000010, + OFF_0_54US = 0b00000011, + OFF_0_80US = 0b00000100, + OFF_1_54US = 0b00000101, + OFF_3_34US = 0b00000110, + OFF_6_58US = 0b00000111 +}; + +enum PFS_FLAGS { + FRAMES_1 = 0b00000000, + FRAMES_2 = 0b00010000, + FRAMES_3 = 0b00100000, + FRAMES_4 = 0b00110000 +}; + +enum TSE_FLAGS { + TEMP_INTERNAL = 0b00000000, + TEMP_EXTERNAL = 0b10000000, + + OFFSET_0 = 0b00000000, + OFFSET_1 = 0b00000001, + OFFSET_2 = 0b00000010, + OFFSET_3 = 0b00000011, + OFFSET_4 = 0b00000100, + OFFSET_5 = 0b00000101, + OFFSET_6 = 0b00000110, + OFFSET_7 = 0b00000111, + + OFFSET_MIN_8 = 0b00001000, + OFFSET_MIN_7 = 0b00001001, + OFFSET_MIN_6 = 0b00001010, + OFFSET_MIN_5 = 0b00001011, + OFFSET_MIN_4 = 0b00001100, + OFFSET_MIN_3 = 0b00001101, + OFFSET_MIN_2 = 0b00001110, + OFFSET_MIN_1 = 0b00001111 +}; + +enum PLL_FLAGS { + // other frequency options exist but there doesn't seem to be much + // point in including them - this is a fair range of options... + HZ_29 = 0b00111111, + HZ_33 = 0b00111110, + HZ_40 = 0b00111101, + HZ_50 = 0b00111100, + HZ_67 = 0b00111011, + HZ_100 = 0b00111010, + HZ_200 = 0b00111001 +}; + +// This is an UC8151 control chip. The display is a 2.9" grayscale EInk. +const uint8_t display_start_sequence[] = { + PWR, 5, VDS_INTERNAL | VDG_INTERNAL, VCOM_VD | VGHL_16V, 0b101011, 0b101011, 0b101011, // power setting + PON, DELAY, 200, // power on and wait 200 ms + BTST, 3, (START_10MS | STRENGTH_3 | OFF_6_58US), (START_10MS | STRENGTH_3 | OFF_6_58US), (START_10MS | STRENGTH_3 | OFF_6_58US), + PSR, 1, (RES_128x296 | LUT_REG | FORMAT_BW | SCAN_UP | SHIFT_RIGHT | BOOSTER_ON | RESET_NONE), + PFS, 1, FRAMES_1, + TSE, 1, TEMP_INTERNAL | OFFSET_0, + TCON, 1, 0x22, // tcon setting + CDI, 1, 0b01001100, // vcom and data interval + PLL, 1, HZ_100, // PLL set to 100 Hz + + // Look up tables for voltage sequence for pixel transition + // Common voltage + LUT_VCOM, 44, + 0x00, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x00, 0x23, 0x23, 0x00, 0x00, 0x02, + 0x00, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + + // White to white + LUT_WW, 42, + 0x54, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x60, 0x23, 0x23, 0x00, 0x00, 0x02, + 0xa8, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // Black to white + LUT_BW, 42, + 0x54, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x60, 0x23, 0x23, 0x00, 0x00, 0x02, + 0xa8, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // White to black + LUT_WB, 42, + 0xa8, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x60, 0x23, 0x23, 0x00, 0x00, 0x02, + 0x54, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // Black to black + LUT_BB, 42, + 0xa8, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x60, 0x23, 0x23, 0x00, 0x00, 0x02, + 0x54, 0x16, 0x16, 0x0d, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +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; + common_hal_digitalio_digitalinout_construct(&enable_pin_obj, &pin_GPIO10); + common_hal_digitalio_digitalinout_switch_to_output(&enable_pin_obj, true, DRIVE_MODE_PUSH_PULL); + + // Never reset + common_hal_digitalio_digitalinout_never_reset(&enable_pin_obj); + + // Set up the SPI object used to control the display + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, false); + common_hal_busio_spi_never_reset(spi); + + // Set up the DisplayIO pin object + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_GPIO20, // EPD_DC Command or data + &pin_GPIO17, // EPD_CS Chip select + &pin_GPIO21, // EPD_RST Reset + 1200000, // Baudrate + 0, // Polarity + 0); // Phase + + // Set up the DisplayIO epaper object + displayio_epaperdisplay_obj_t *display = &displays[0].epaper_display; + display->base.type = &displayio_epaperdisplay_type; + common_hal_displayio_epaperdisplay_construct( + display, + bus, + display_start_sequence, sizeof(display_start_sequence), + 0, // start up time + display_stop_sequence, sizeof(display_stop_sequence), + 296, // width + 128, // height + 160, // ram_width + 296, // ram_height + 0, // colstart + 0, // rowstart + 270, // rotation + NO_COMMAND, // set_column_window_command + NO_COMMAND, // set_row_window_command + NO_COMMAND, // set_current_column_command + NO_COMMAND, // set_current_row_command + DTM2, // write_black_ram_command + true, // black_bits_inverted + DTM1, // write_color_ram_command + false, // color_bits_inverted + 0x000000, // highlight_color + 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 +} + +void board_deinit(void) { + displayio_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &displayio_epaperdisplay_type) { + size_t i = 0; + while (common_hal_displayio_epaperdisplay_get_busy(display)) { + RUN_BACKGROUND_TASKS; + i++; + } + } + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/link.ld b/ports/raspberrypi/boards/pimoroni_badger2040w/link.ld new file mode 100644 index 0000000000..2777b41720 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/link.ld @@ -0,0 +1,294 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +MEMORY +{ + FLASH_FIRMWARE (rx) : ORIGIN = 0x10000000, LENGTH = 1532k + /* Followed by: 4kB of NVRAM and at least 512kB of CIRCUITPY */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256k + SCRATCH_X (rwx) : ORIGIN = 0x20040000, LENGTH = 4k + SCRATCH_Y (rwx) : ORIGIN = 0x20041000, LENGTH = 4k +} + +ENTRY(_entry_point) + +SECTIONS +{ + /* Second stage bootloader is prepended to the image. It must be 256 bytes big + and checksummed. It is usually built by the boot_stage2 target + in the Pico SDK + */ + + .flash_begin : { + __flash_binary_start = .; + } > FLASH_FIRMWARE + + .boot2 : { + __boot2_start__ = .; + KEEP (*(.boot2)) + __boot2_end__ = .; + } > FLASH_FIRMWARE + + ASSERT(__boot2_end__ - __boot2_start__ == 256, + "ERROR: Pico second stage bootloader must be 256 bytes in size") + + /* The second stage will always enter the image at the start of .text. + The debugger will use the ELF entry point, which is the _entry_point + symbol if present, otherwise defaults to start of .text. + This can be used to transfer control back to the bootrom on debugger + launches only, to perform proper flash setup. + */ + + .text : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.reset)) + /* TODO revisit this now memset/memcpy/float in ROM */ + /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from + * FLASH ... we will include any thing excluded here in .data below by default */ + *(.init) + + __property_getter_start = .; + *(.property_getter) + __property_getter_end = .; + __property_getset_start = .; + *(.property_getset) + __property_getset_end = .; + + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .rodata : { + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) + . = ALIGN(4); + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH_FIRMWARE + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH_FIRMWARE + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH_FIRMWARE + __binary_info_end = .; + . = ALIGN(4); + + /* End of .text-like segments */ + __etext = .; + + .ram_vector_table (COPY): { + *(.ram_vector_table) + } > RAM + + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ + *(.text*) + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + + *(.data*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT> FLASH_FIRMWARE + + .itcm : + { + . = ALIGN(4); + *(.itcm.*) + + . = ALIGN(4); + } > RAM AT> FLASH_FIRMWARE + _ld_itcm_destination = ADDR(.itcm); + _ld_itcm_flash_copy = LOADADDR(.itcm); + _ld_itcm_size = SIZEOF(.itcm); + + .dtcm_data : + { + . = ALIGN(4); + + *(.dtcm_data.*) + + . = ALIGN(4); + } > RAM AT> FLASH_FIRMWARE + _ld_dtcm_data_destination = ADDR(.dtcm_data); + _ld_dtcm_data_flash_copy = LOADADDR(.dtcm_data); + _ld_dtcm_data_size = SIZEOF(.dtcm_data); + + .dtcm_bss : + { + . = ALIGN(4); + + *(.dtcm_bss.*) + + . = ALIGN(4); + } > RAM AT> RAM + _ld_dtcm_bss_start = ADDR(.dtcm_bss); + _ld_dtcm_bss_size = SIZEOF(.dtcm_bss); + + .uninitialized_data (COPY): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + /* Start and end symbols must be word-aligned */ + .scratch_x : { + __scratch_x_start__ = .; + *(.scratch_x.*) + . = ALIGN(4); + __scratch_x_end__ = .; + } > SCRATCH_X AT > FLASH_FIRMWARE + __scratch_x_source__ = LOADADDR(.scratch_x); + + .scratch_y : { + __scratch_y_start__ = .; + *(.scratch_y.*) + . = ALIGN(4); + __scratch_y_end__ = .; + } > SCRATCH_Y AT > FLASH_FIRMWARE + __scratch_y_source__ = LOADADDR(.scratch_y); + + .bss : { + . = ALIGN(4); + __bss_start__ = .; + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack*_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later + * + * stack1 section may be empty/missing if platform_launch_core1 is not used */ + + /* by default we put core 0 stack at the end of scratch Y, so that if core 1 + * stack is not used then all of SCRATCH_X is free. + */ + .stack1_dummy (COPY): + { + *(.stack1*) + } > SCRATCH_X + .stack_dummy (COPY): + { + *(.stack*) + } > SCRATCH_Y + + .flash_end : { + __flash_binary_end = .; + } > FLASH_FIRMWARE + + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") + /* todo assert on extra code */ +} diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.h new file mode 100644 index 0000000000..674f07b538 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.h @@ -0,0 +1,18 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Badger 2040 W" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_CYW0) + +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) + +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk new file mode 100644 index 0000000000..4ddb0e7d87 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk @@ -0,0 +1,27 @@ +USB_VID = 0x2E8A +USB_PID = 0x104F + +USB_PRODUCT = "Badger 2040 W" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_SSL_MBEDTLS = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-pcf85063a diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_badger2040w/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/pins.c b/ports/raspberrypi/boards/pimoroni_badger2040w/pins.c new file mode 100644 index 0000000000..49a821000c --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/pins.c @@ -0,0 +1,68 @@ +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" +#include "badger-shared.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), 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) }, + + { MP_ROM_QSTR(MP_QSTR_RTC_ALARM), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + // { MP_ROM_QSTR(MP_QSTR_EN_3V3), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_SW_DOWN), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SW_C), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SW_UP), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_INKY_CS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_INKY_DC), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_INKY_RST), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_USER_LED), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_INKY_BUSY), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + { 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_ROM_QSTR(MP_QSTR_ENABLE_DIO), MP_ROM_PTR(&enable_pin_obj)}, // GP10 +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);