diff --git a/ports/espressif/boards/m5stack_stick_c_plus/board.c b/ports/espressif/boards/m5stack_stick_c_plus/board.c new file mode 100755 index 0000000000..8188ac9ded --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus/board.c @@ -0,0 +1,245 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 n0xa + * + * 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/busio/I2C.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "components/driver/include/driver/gpio.h" +#include "components/hal/include/hal/gpio_hal.h" +#include "common-hal/microcontroller/Pin.h" + +#include "../../pmic/axp192/axp192.h" + +// display init sequence according to adafruit_st7735r.py library +uint8_t display_init_sequence[] = { + 0x01,0x80,0x96, // SWRESET and Delay 150ms + 0x11,0x80,0xff, // SLPOUT and Delay + 0xb1,0x03,0x01,0x2C,0x2D, // _FRMCTR1 + 0xb2,0x03,0x01,0x2C,0x2D, // _FRMCTR2 + 0xb3,0x06,0x01,0x2C,0x2D,0x01,0x2C,0x2D, // _FRMCTR3 + 0xb4,0x01,0x07, // _INVCTR line inversion + 0xc0,0x03,0xa2,0x02,0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1,0x01,0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2,0x02,0x0a,0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3,0x02,0x8a,0x2a, + 0xc4,0x02,0x8a,0xee, + 0xc5,0x01,0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36,0x01,0xc8, // MADCTL Rotate display + 0x21,0x00, // _INVON + 0x3a,0x01,0x05, // COLMOD - 16bit color + 0xe0,0x10,0x02,0x1c,0x07,0x12,0x37,0x32,0x29,0x2d,0x29,0x25,0x2B,0x39,0x00,0x01,0x03,0x10, // _GMCTRP1 Gamma + 0xe1,0x10,0x03,0x1d,0x07,0x06,0x2E,0x2C,0x29,0x2D,0x2E,0x2E,0x37,0x3F,0x00,0x00,0x02,0x10, // _GMCTRN1 + 0x13,0x80,0x0a, // _NORON + 0x29,0x80,0x64 // _DISPON +}; + +static bool pmic_init(busio_i2c_obj_t *i2c) { + int rc; + uint8_t write_buf[2]; + + if (!pmic_common_init(i2c)) { + return false; + } + + // Reg: 30h + // The VBUS-IPSOUT path can be selected to be opened regardless of the status of N_VBUSEN + // VBUS VHOLD pressure limit control disabled + // VBUS current limit control disabled + write_buf[0] = AXP192_VBUS_IPSOUT; + write_buf[1] = AXP192_VBUS_IPSOUT_IGNORE_VBUSEN; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 33h + // Charge function enable control bit, including internal and external channels + // Charging target voltage: 4.2V + // Charging end current: End charging when charging current is less than 10% setting + // Internal path charging current: 100mA + write_buf[0] = AXP192_CHARGING_CTRL1; + write_buf[1] = AXP192_CHARGING_CTRL1_ENABLE | + AXP192_CHARGING_CTRL1_VOLTAGE_4_20V | + AXP192_CHARGING_CTRL1_CURRENT_100mA; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 90h + // GPIO0(LDOio0) floating + write_buf[0] = AXP192_GPIO0_FUNCTION; + write_buf[1] = AXP192_GPIO0_FUNCTION_FLOATING; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 91h + // GPIO0(LDOio0) 2.8V + write_buf[0] = AXP192_GPIO0_LDO_VOLTAGE; + write_buf[1] = AXP192_GPIO0_LDO_VOLTAGE_2_8V; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 28h + // LDO2 (TFT backlight): 2.8V + // LDO3 (TFT logic): 3.0V + write_buf[0] = AXP192_LDO23_OUT_VOLTAGE; + write_buf[1] = AXP192_LDO23_OUT_VOLTAGE_LDO2_2_8V | + AXP192_LDO23_OUT_VOLTAGE_LDO3_3_0V; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 12h + // Enable CTRL_EXTEN, DCDC1, LDO2 and LDO3 + write_buf[0] = AXP192_DCDC13_LDO23_CTRL; + write_buf[1] = AXP192_DCDC13_LDO23_CTRL_EXTEN | + AXP192_DCDC13_LDO23_CTRL_LDO3 | + AXP192_DCDC13_LDO23_CTRL_LDO2 | + AXP192_DCDC13_LDO23_CTRL_DCDC1; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // Reg: 26h + // DCDC1 (ESP32 VDD): 3.350V + write_buf[0] = AXP192_DCDC1_OUT_VOLTAGE; + write_buf[1] = AXP192_DCDC1_OUT_VOLTAGE_3_350V; + rc = common_hal_busio_i2c_write(i2c, AXP192_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + if (!pmic_disable_all_irq(i2c)) { + return false; + } + + if (!pmic_clear_all_irq(i2c)) { + return false; + } + + if (!pmic_enable_power_key_press_irq(i2c)) { + return false; + } + + if (!pmic_enable_low_battery_irq(i2c)) { + return false; + } + + return true; +} + +static bool display_init(void) { + displayio_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO23, // DC + &pin_GPIO5, // CS + &pin_GPIO18, // RST + 10000000, // baudrate + 0, // polarity + 0 // phase + ); + + displayio_display_obj_t *display = &allocate_display()->display; + display->base.type = &displayio_display_type; + + common_hal_displayio_display_construct( + display, + bus, + 135, // width (after rotation) + 240, // height (after rotation) + 40, // column start + 52, // row start + 1, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid 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), + NULL, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 80, // native_frames_per_second + false, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + + return true; +} + +void board_init(void) { + busio_i2c_obj_t *internal_i2c = common_hal_board_create_i2c(0); + + if (!pmic_init(internal_i2c)) { + mp_printf(&mp_plat_print, "could not initialize axp192 pmic\n"); + return; + } + + if (!display_init()) { + mp_printf(&mp_plat_print, "could not initialize the display"); + return; + } +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Set IR led gpio high to prevent power drain from the led + if (pin_number == 9) { + gpio_set_direction(pin_number, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(pin_number, true); + return true; + } + return false; +} diff --git a/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h b/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h new file mode 100644 index 0000000000..3e988248c6 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 n0xa + * + * 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. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Stick C Plus" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO10) +#define MICROPY_HW_LED_STATUS_INVERTED (1) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}, \ + {.scl = &pin_GPIO33, .sda = &pin_GPIO32}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO37) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION translate("You pressed button A at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk b/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk new file mode 100644 index 0000000000..101ef3c2e0 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk @@ -0,0 +1,11 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x0032000A + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESPCAMERA = 0 + +SRC_C += pmic/axp192/axp192.c diff --git a/ports/espressif/boards/m5stack_stick_c_plus/pins.c b/ports/espressif/boards/m5stack_stick_c_plus/pins.c new file mode 100644 index 0000000000..63e3f2d8d9 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus/pins.c @@ -0,0 +1,62 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_A36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO9) }, + + // buttons + { MP_ROM_QSTR(MP_QSTR_BTN_A), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_BTN_B), MP_ROM_PTR(&pin_GPIO39) }, + + // internal i2c bus + { MP_ROM_QSTR(MP_QSTR_SYS_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SYS_SCL), MP_ROM_PTR(&pin_GPIO22) }, + + // internal devices interrupt + { MP_ROM_QSTR(MP_QSTR_SYS_INT), MP_ROM_PTR(&pin_GPIO35) }, + + // pmu AXP192 + { MP_ROM_QSTR(MP_QSTR_PMU_N_VBUSEN), MP_ROM_PTR(&pin_GPIO27) }, + + // pdm microphone + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_CLK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_DATA), MP_ROM_PTR(&pin_GPIO34) }, + + // buzzer + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO2) }, + + // lcd spi bus + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SYS_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig b/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig new file mode 100644 index 0000000000..a37e88cedf --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig @@ -0,0 +1,26 @@ +CONFIG_ESP32_SPIRAM_SUPPORT=n + +# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskStickCPlus" +# end of LWIP + +# Uncomment (remove ###) to send ESP_LOG output to TX/RX pins +### # +### # ESP System Settings +### # +### CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +### # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +### CONFIG_ESP_CONSOLE_UART_CUSTOM=y +### CONFIG_ESP_CONSOLE_NONE is not set +### CONFIG_ESP_CONSOLE_UART=y +### CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y +### # CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_1 is not set +### CONFIG_ESP_CONSOLE_UART_NUM=0 +### CONFIG_ESP_CONSOLE_UART_TX_GPIO=17 +### CONFIG_ESP_CONSOLE_UART_RX_GPIO=16 +### CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +### # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +### # end of ESP System Settings