diff --git a/ports/esp32/boards/CM_-CombinedS3CH340/board.json b/ports/esp32/boards/CM_-CombinedS3CH340/board.json new file mode 100644 index 00000000000..d31a7c7a239 --- /dev/null +++ b/ports/esp32/boards/CM_-CombinedS3CH340/board.json @@ -0,0 +1,18 @@ +{ + "vendor": "CircuitMess", + "product": "ESP32S3 CH340 Devices", + "thumbnail": "", + "url": "https://circuitmess.com/", + "images": [], + + "docs": "", + "mcu": "esp32s3", + "features": [ + "USB-C", + "BLE", + "WiFi" + ], + "deploy": [ + "../deploy_s3.md" + ] +} diff --git a/ports/esp32/boards/CM_-CombinedS3CH340/board.md b/ports/esp32/boards/CM_-CombinedS3CH340/board.md new file mode 100644 index 00000000000..576ea80450f --- /dev/null +++ b/ports/esp32/boards/CM_-CombinedS3CH340/board.md @@ -0,0 +1,3 @@ +The following files are daily firmware for ESP32-based boards without external SPIRAM. + +This firmware is compiled using ESP-IDF v4.x. Some older releases are also provided that are compiled with ESP-IDF v3.x. diff --git a/ports/esp32/boards/CM_-CombinedS3CH340/manifest.py b/ports/esp32/boards/CM_-CombinedS3CH340/manifest.py new file mode 100644 index 00000000000..2459bfc2f06 --- /dev/null +++ b/ports/esp32/boards/CM_-CombinedS3CH340/manifest.py @@ -0,0 +1,3 @@ +include("$(PORT_DIR)/boards/manifest.py") + +package("ButterBotCtrl", base_path="$(PORT_DIR)/libraries") diff --git a/ports/esp32/boards/CM_-CombinedS3CH340/mpconfigboard.cmake b/ports/esp32/boards/CM_-CombinedS3CH340/mpconfigboard.cmake new file mode 100644 index 00000000000..5b1523ed3d7 --- /dev/null +++ b/ports/esp32/boards/CM_-CombinedS3CH340/mpconfigboard.cmake @@ -0,0 +1,9 @@ +set(IDF_TARGET esp32s3) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.ble + boards/CM_-CombinedS3CH340/sdkconfig.board +) + +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) diff --git a/ports/esp32/boards/CM_-CombinedS3CH340/mpconfigboard.h b/ports/esp32/boards/CM_-CombinedS3CH340/mpconfigboard.h new file mode 100644 index 00000000000..93ef87da50f --- /dev/null +++ b/ports/esp32/boards/CM_-CombinedS3CH340/mpconfigboard.h @@ -0,0 +1,9 @@ +#define MICROPY_HW_BOARD_NAME "CircuitMess ESP32S3 CH340 Devices" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_PY_MACHINE_DAC (0) + +// Enable UART REPL for modules that have an external USB-UART and don't use native USB. - set to 1 to enable +// These devices route USB-C through an onboard CH340 to UART0; the S3's native USB pins +// (GPIO19/20) are repurposed as regular GPIOs. +#define MICROPY_HW_ENABLE_UART_REPL (1) diff --git a/ports/esp32/boards/CM_-CombinedS3CH340/sdkconfig.board b/ports/esp32/boards/CM_-CombinedS3CH340/sdkconfig.board new file mode 100644 index 00000000000..4de2f2099a5 --- /dev/null +++ b/ports/esp32/boards/CM_-CombinedS3CH340/sdkconfig.board @@ -0,0 +1,7 @@ +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB= +CONFIG_ESPTOOLPY_FLASHSIZE_16MB= diff --git a/ports/esp32/boards/CM_ButterBotCtrl/board.json b/ports/esp32/boards/CM_ButterBotCtrl/board.json new file mode 100644 index 00000000000..5e57121abd2 --- /dev/null +++ b/ports/esp32/boards/CM_ButterBotCtrl/board.json @@ -0,0 +1,16 @@ +{ + "vendor": "CircuitMess", + "product": "Butter Bot Controller", + "thumbnail": "", + "url": "https://circuitmess.com/", + "images": [], + + "docs": "", + "mcu": "esp32s3", + "features": [ + "USB-C" + ], + "deploy": [ + "../deploy_s3.md" + ] +} \ No newline at end of file diff --git a/ports/esp32/boards/CM_ButterBotCtrl/board.md b/ports/esp32/boards/CM_ButterBotCtrl/board.md new file mode 100644 index 00000000000..3d6a9113540 --- /dev/null +++ b/ports/esp32/boards/CM_ButterBotCtrl/board.md @@ -0,0 +1,3 @@ +The following files are daily firmware for ESP32-based boards without external SPIRAM. + +This firmware is compiled using ESP-IDF v4.x. Some older releases are also provided that are compiled with ESP-IDF v3.x. \ No newline at end of file diff --git a/ports/esp32/boards/CM_ButterBotCtrl/manifest.py b/ports/esp32/boards/CM_ButterBotCtrl/manifest.py new file mode 100644 index 00000000000..a7942cf7e1a --- /dev/null +++ b/ports/esp32/boards/CM_ButterBotCtrl/manifest.py @@ -0,0 +1,3 @@ +include("$(PORT_DIR)/boards/manifest.py") + +package("ButterBotCtrl", base_path="$(PORT_DIR)/libraries") \ No newline at end of file diff --git a/ports/esp32/boards/CM_ButterBotCtrl/mpconfigboard.cmake b/ports/esp32/boards/CM_ButterBotCtrl/mpconfigboard.cmake new file mode 100644 index 00000000000..2a8235ecd3d --- /dev/null +++ b/ports/esp32/boards/CM_ButterBotCtrl/mpconfigboard.cmake @@ -0,0 +1,9 @@ +set(IDF_TARGET esp32s3) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.ble + boards/CM_ButterBotCtrl/sdkconfig.board +) + +set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) \ No newline at end of file diff --git a/ports/esp32/boards/CM_ButterBotCtrl/mpconfigboard.h b/ports/esp32/boards/CM_ButterBotCtrl/mpconfigboard.h new file mode 100644 index 00000000000..c41bb203643 --- /dev/null +++ b/ports/esp32/boards/CM_ButterBotCtrl/mpconfigboard.h @@ -0,0 +1,9 @@ +#define MICROPY_HW_BOARD_NAME "CircuitMess Butter Bot Controller" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_PY_MACHINE_DAC (0) + +// Enable UART REPL for modules that have an external USB-UART and don't use native USB. - set to 1 to enable +// Butter Bot Controller has no native USB (GPIO19/D- is used as the battery calibration +// reference); its USB-C routes through an onboard CH340 to UART0. +#define MICROPY_HW_ENABLE_UART_REPL (1) \ No newline at end of file diff --git a/ports/esp32/boards/CM_ButterBotCtrl/sdkconfig.board b/ports/esp32/boards/CM_ButterBotCtrl/sdkconfig.board new file mode 100644 index 00000000000..cb7820bf043 --- /dev/null +++ b/ports/esp32/boards/CM_ButterBotCtrl/sdkconfig.board @@ -0,0 +1,9 @@ +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_AFTER_NORESET=y + +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_8MB= +CONFIG_ESPTOOLPY_FLASHSIZE_16MB= +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/noota_4MB.csv" \ No newline at end of file diff --git a/ports/esp32/libraries/ButterBotCtrl/Pins.py b/ports/esp32/libraries/ButterBotCtrl/Pins.py new file mode 100644 index 00000000000..7bd5fbc917f --- /dev/null +++ b/ports/esp32/libraries/ButterBotCtrl/Pins.py @@ -0,0 +1,100 @@ +from micropython import const + + +class Pins: + LED_WIFI: int = const(0) + LED_POWER: int = const(1) + LED_BATTLOW: int = const(2) + LED_BIG: int = const(3) + + BTN_MANOVER: int = const(4) + BTN_POKE: int = const(5) + BTN_SHUTUP: int = const(6) + BTN_SUMMON: int = const(7) + BTN_JOY: int = const(8) + + JOY_V: int = const(9) + JOY_H: int = const(10) + + TFT_SCK: int = const(11) + TFT_SDA: int = const(12) + TFT_DC: int = const(13) + TFT_RST: int = const(14) + LED_BACKLIGHT: int = const(15) + + PIN_BATT: int = const(16) + PIN_VREF: int = const(17) + + Rev1Map = { + LED_WIFI: const(7), + LED_POWER: const(8), + LED_BATTLOW: const(9), + LED_BIG: const(46), + + BTN_MANOVER: const(10), + BTN_POKE: const(11), + BTN_SHUTUP: const(18), + BTN_SUMMON: const(13), + BTN_JOY: const(21), + + JOY_V: const(4), + JOY_H: const(5), + + TFT_SCK: const(14), + TFT_SDA: const(15), + TFT_DC: const(16), + TFT_RST: const(17), + LED_BACKLIGHT: const(45), + + PIN_BATT: const(6), + PIN_VREF: const(19), + } + + def __init__(self, revision): + self.currentMap = None + if revision == 0: + self.currentMap = self.Rev1Map + else: + print("Unknown revision", revision) + + def get(self, pin: int) -> int: + if not pin in self.currentMap: + print("Pin", pin, "not in map") + return -1 + + return self.currentMap[pin] + + +class Buttons: + ManualOverride: int = const(0) + Poke: int = const(1) + ShutUp: int = const(2) + Summon: int = const(3) + Joystick: int = const(4) + + def __init__(self, pins: Pins): + # Maps Buttons [0-4] to their respective GPIO pins + self.Pins: [int] = const([ + pins.get(Pins.BTN_MANOVER), pins.get(Pins.BTN_POKE), pins.get(Pins.BTN_SHUTUP), + pins.get(Pins.BTN_SUMMON), pins.get(Pins.BTN_JOY) + ]) + + def get_pins_array(self) -> [int]: + return self.Pins + + +class LEDs: + BigGreen: int = const(0) + Wifi: int = const(1) + Power: int = const(2) + BatteryLow: int = const(3) + + def __init__(self, pins: Pins): + # Maps LEDs to their respective GPIO pins + self.pins: [int] = const([ + pins.get(Pins.LED_BIG), pins.get(Pins.LED_WIFI), pins.get(Pins.LED_POWER), + pins.get(Pins.LED_BATTLOW) + ]) + + def get_pins_array(self) -> [int]: + return self.pins \ No newline at end of file diff --git a/ports/esp32/libraries/ButterBotCtrl/_LED.py b/ports/esp32/libraries/ButterBotCtrl/_LED.py new file mode 100644 index 00000000000..2a2709dae55 --- /dev/null +++ b/ports/esp32/libraries/ButterBotCtrl/_LED.py @@ -0,0 +1,20 @@ +from CircuitOS import SingleLED + + +class LED: + def __init__(self, pins: [int]): + self.leds = [SingleLED(pin) for pin in pins] + + def set(self, led: int, value: int): + """ + @param led: LED from LEDs + @param value: value from 0 to 100 + """ + if led < 0 or led >= len(self.leds): + return + + self.leds[led].set(value) + + def set_all(self, value: int): + for led in self.leds: + led.set(value) \ No newline at end of file diff --git a/ports/esp32/libraries/ButterBotCtrl/__init__.py b/ports/esp32/libraries/ButterBotCtrl/__init__.py new file mode 100644 index 00000000000..ab8aa550cdf --- /dev/null +++ b/ports/esp32/libraries/ButterBotCtrl/__init__.py @@ -0,0 +1,43 @@ +from machine import SPI, Pin, Signal, ADC +from CircuitOS import InputGPIO, Display, PanelST7735_128x128, SliderADC, Sliders +from .Pins import * +from ._LED import LED + +pins = Pins(0) +btn_pins = Buttons(pins) +led_pins = LEDs(pins) + +spiTFT: SPI = SPI(1, baudrate=40000000, polarity=0, phase=0, sck=Pin(pins.get(Pins.TFT_SCK)), + mosi=Pin(pins.get(Pins.TFT_SDA))) + +blPin = Pin(pins.get(Pins.LED_BACKLIGHT), mode=Pin.OUT, value=True) +backlight = Signal(blPin, invert=True) + +# GPIO19 high injects the 2.5V calibration reference onto the battery ADC node - keep it off +vref = Pin(pins.get(Pins.PIN_VREF), mode=Pin.OUT, value=False) + +buttons = InputGPIO(btn_pins.get_pins_array(), inverted=True) + +joystick_x = SliderADC(pins.get(Pins.JOY_H), min=0, max=4096, ema_a=0.05, width=ADC.WIDTH_12BIT) +joystick_y = SliderADC(pins.get(Pins.JOY_V), min=0, max=4096, ema_a=0.05, width=ADC.WIDTH_12BIT) +joystick = Sliders([joystick_x, joystick_y]) + +leds = LED(led_pins.pins) + +dc = Pin(pins.get(Pins.TFT_DC), Pin.OUT) +reset = Pin(pins.get(Pins.TFT_RST), Pin.OUT) +panel = PanelST7735_128x128(spiTFT, dc=dc, reset=reset, rotation=0, + rotations=[(0x00, 128, 128, 0, 0)]) +display = Display(panel) + + +def begin(): + panel.init() + + display.fill(Display.Color.Black) + display.commit() + + backlight.on() + + buttons.scan() + joystick.scan() \ No newline at end of file diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 43caf6e9663..4c71096a3c2 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -92,7 +92,7 @@ void mp_task(void *pvParameter) { #endif #if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG usb_serial_jtag_init(); - #elif CONFIG_USB_OTG_SUPPORTED + #elif CONFIG_USB_OTG_SUPPORTED && !MICROPY_HW_ENABLE_UART_REPL usb_init(); #endif #if MICROPY_HW_ENABLE_UART_REPL diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c index 538b3e405c9..6df84c765ab 100644 --- a/ports/esp32/mphalport.c +++ b/ports/esp32/mphalport.c @@ -127,7 +127,7 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) { } #if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG usb_serial_jtag_tx_strn(str, len); - #elif CONFIG_USB_OTG_SUPPORTED + #elif CONFIG_USB_OTG_SUPPORTED && !MICROPY_HW_ENABLE_UART_REPL usb_tx_strn(str, len); #endif #if MICROPY_HW_ENABLE_UART_REPL diff --git a/ports/esp32/usb.c b/ports/esp32/usb.c index 2e417755c9a..8413163db32 100644 --- a/ports/esp32/usb.c +++ b/ports/esp32/usb.c @@ -28,7 +28,7 @@ #include "py/mphal.h" #include "usb.h" -#if CONFIG_USB_OTG_SUPPORTED && !CONFIG_ESP_CONSOLE_USB_CDC && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +#if CONFIG_USB_OTG_SUPPORTED && !CONFIG_ESP_CONSOLE_USB_CDC && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG && !MICROPY_HW_ENABLE_UART_REPL #include "esp_timer.h" #ifndef NO_QSTR