Skip to content

Add Freenove ESP32 Display 3.5 inch - #11540

Merged
tannewt merged 2 commits into
adafruit:mainfrom
agent-nelson:add-freenove-esp32-display-3-5
Oct 12, 2026
Merged

tannewt merged 2 commits into
adafruit:mainfrom
agent-nelson:add-freenove-esp32-display-3-5

Conversation

@agent-nelson

Copy link
Copy Markdown

Adds the Freenove ESP32 Display 3.5 inch
(FNK0103N, also sold as the "Freenove Bitcoin Miner Solo Lottery Miner, ESP32 CYD
3.5 inch"): an ESP32-WROOM-32E "Cheap Yellow Display" style board with a 3.5"
320x480 ST7796 TFT over SPI, XPT2046 resistive touch, microSD slot, RGB LED,
DAC speaker output through an SC8002B amplifier, TP4054 LiPo charger with
battery sense, and UART/I2C/SPI/input headers. The USB-C port goes through a
CH340C, so there is no native USB (no VID/PID; serial REPL and web workflow).

Notes on the board definition:

  • board.DISPLAY is a 480x320 BusDisplay (ST7796, 16-bit colour, init
    sequence from the vendor's TFT_eSPI setup) with PWM backlight on GPIO27.
    Rotation 0 is landscape with the USB connector on the left;
    CIRCUITPY_DISPLAY_ROTATION in settings.toml rotates it, as on the Sunton
    boards.
  • The SPI clock is 26.67 MHz: the display bus is routed through the GPIO
    matrix, which is the ESP32's full-duplex limit there. (Asking for 40 MHz
    makes busio.SPI raise, and an exception inside board_init() silently
    resets the chip.)
  • The XPT2046 touch controller shares the LCD SPI bus (TOUCH_CS,
    TOUCH_IRQ); after displayio.release_displays() the display and the touch
    driver can share board.LCD_SPI().
  • The microSD slot and the SPI header share board.SPI() (SD_CS GPIO5, header
    CS GPIO21). board.I2C() is the I2C header (SDA GPIO32, SCL GPIO25).
  • RGB LED pins are active low (common anode); the blue element is the status
    LED (MICROPY_HW_LED_STATUS_INVERTED). SPEAKER_ENABLE_INVERTED is the
    amplifier's shutdown pin (pulled up, drive low to enable).

Tested on hardware (11.0.0-alpha.1 at df53dd9 + this commit, ESP-IDF 6.1):

  • Boots, correct board id and banner on the CH340 serial console, REPL works,
    1.2 MB CIRCUITPY filesystem created.
  • Display: colour bars, labels, 1-px edge markers and the REPL are drawn, and
    pixels read back from the ST7796 GRAM over MISO match what was written;
    CIRCUITPY_DISPLAY_ROTATION round-trips; DISPLAY.brightness sets the
    backlight PWM.
  • XPT2046 touch answers on the shared bus (temperature channels, idle X/Y,
    TOUCH_IRQ high while not pressed) after release_displays() and
    re-creating the display on board.LCD_SPI().
  • RGB LED pins drive, BOOT button reads high unpressed, IO35/IO39 read,
    battery ADC through the 1:2 divider reads the TP4054 float voltage (4.2 V,
    no cell attached).
  • DAC square wave on SPEAKER with SPEAKER_ENABLE_INVERTED low runs.
  • board.I2C() scan runs (nothing attached); sdcardio on board.SPI()
    reports "no SD card" with the slot empty.
  • Wi-Fi scan lists networks; BLE scan lists devices.
  • pre-commit run --all-files and the VID/PID / creator-ID duplicate check pass.

Not yet checked by eye, ear or finger: display orientation and colour order,
touch coordinates under a finger, LED colours and speaker audibility; also
an SD card mount with a card inserted and Wi-Fi station mode. I will follow
up here once those are confirmed.

🤖 Generated with Claude Code

ESP32-WROOM-32E (4 MB flash, no PSRAM, CH340C USB-serial) with a 3.5"
320x480 ST7796 display over SPI, XPT2046 resistive touch on the same
bus, microSD slot, RGB LED, DAC speaker output through an amplifier,
LiPo charger with battery sense and UART/I2C/SPI/input headers. Sold
by Freenove as FNK0103N and as the "Bitcoin Miner Solo Lottery Miner,
ESP32 CYD 3.5 inch". board.DISPLAY is set up at boot in landscape and
honours CIRCUITPY_DISPLAY_ROTATION from settings.toml.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One ID comment. Please let us know when you've tested it on the device.

Comment thread ports/espressif/boards/freenove_esp32_display_3_5/mpconfigboard.mk Outdated
Freenove already has creator ID 0x1C33_0000 in creationid/creators.
The creation ID 0x0103_0035 is registered there in creationid/creators#95.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@agent-nelson

Copy link
Copy Markdown
Author

Thanks for the review. Freenove already has creator ID 0x1C33_0000 in creationid/creators, so I switched CIRCUITPY_CREATOR_ID to that and opened creationid/creators#95 to register the creation ID 0x0103_0035 for this board (the 0x0103 prefix follows the FNK0103 product code). The 0xF4EE0000 value in the first push was a placeholder, sorry about that.

Pushed as a follow-up commit so the change is visible on its own. I'll follow up separately on the on-device testing.

tannewt pushed a commit to creationid/creators that referenced this pull request Oct 12, 2026
Used by the CircuitPython board definitions freenove_esp32_display_3_5
(adafruit/circuitpython#11540) and freenove_esp32_display_2_8.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Def looks good. Will merge as-is. Feel free to follow up if on device testing shows an issue.

@tannewt
tannewt merged commit c8895e3 into adafruit:main Oct 12, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants