ESP32 as Wifi and Bluetooth Peripheral on STM32

From Stm32World Wiki
Jump to navigation Jump to search
ESP32-S3 Development Board

There are no STM32 MCUs available with built-in WiFi. ST entered a partnership with Qualcomm to create a WiFi module for STM32, but these modules are crazy expensive and quite poorly supported by STM32CubeMX and STM32CubeIDE.

In this article we'll be exploring the use of ESP32 as a WiFi "bridge".

There are in principle two ways to do this:

  1. ESP-AT
  2. esp_hosted

ESP-AT

The simplest way of implementing some form of WiFi on a STM32 is to use the ESP-AT firmware on the ESP32.

ESP-HOSTED

ESP32 Part

Actual ESP32-S3 used

NOTICE! The following example is all using and require ESP-IDF v. 5.3!

For this walk-through we'll be using an ESP32-S3 development board with the following pinout:

ESP32-S3 Board pinout.webp

Create the esp-hosted slave

lth@nb7:~$ cd tmp
lth@nb7:~/tmp$ idf.py create-project-from-example "espressif/esp_hosted=2.12.8:slave"
lth@nb7:~/tmp$ cd slave
lth@nb7:~/tmp/slave$ idf.py set-target esp32s3
lth@nb7:~/tmp/slave$ idf.py build

After successful build, we can flash and monitor the target:

lth@nb7:~/tmp/slave$ idf.py flash monitor
Executing action: flash
Serial port /dev/ttyACM0
Connecting....
Detecting chip type... ESP32-S3
Running ninja in directory /home/lth/tmp/slave/build
Executing "ninja flash"...
[1/5] cd /home/lth/tmp/slave/build/esp-idf/esptool_py &...table.bin /home/lth/tmp/slave/build/network_adapter.bin
network_adapter.bin binary size 0xe5b20 bytes. Smallest app partition is 0x180000 bytes. 0x9a4e0 bytes (40%) free.
[1/1] cd /home/lth/tmp/slave/build/bootloader/esp-idf/e...0x0 /home/lth/tmp/slave/build/bootloader/bootloader.bin
Bootloader binary size 0x58f0 bytes. 0x2710 bytes (31%) free.
[4/5] cd /home/lth/esp/esp-idf/components/esptool_py &&...esp/esp-idf/components/esptool_py/run_serial_tool.cmake
esptool.py --chip esp32s3 -p /dev/ttyACM0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 4MB 0x10000 network_adapter.bin 0x8000 partition_table/partition-table.bin 0xd000 ota_data_initial.bin 0x0 bootloader/bootloader.bin
esptool.py v4.11.0
Serial port /dev/ttyACM0
Connecting...
Chip is ESP32-S3 (QFN56) (revision v0.1)
Features: WiFi, BLE, Embedded PSRAM 2MB (AP_3v3)
Crystal is 40MHz
USB mode: USB-Serial/JTAG
MAC: 68:b6:b3:2b:28:b4
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00010000 to 0x000f5fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000d000 to 0x0000efff...
Flash will be erased from 0x00000000 to 0x00005fff...
Compressed 940832 bytes to 563734...
Writing at 0x000f3298... (100 %)
Wrote 940832 bytes (563734 compressed) at 0x00010000 in 7.5 seconds (effective 1006.1 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 129...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (129 compressed) at 0x00008000 in 0.1 seconds (effective 358.5 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 31...
Writing at 0x0000d000... (100 %)
Wrote 8192 bytes (31 compressed) at 0x0000d000 in 0.1 seconds (effective 555.3 kbit/s)...
Hash of data verified.
SHA digest in image updated
Compressed 22768 bytes to 14090...
Writing at 0x00000000... (100 %)
Wrote 22768 bytes (14090 compressed) at 0x00000000 in 0.4 seconds (effective 420.0 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Executing action: monitor
Running idf_monitor in directory /home/lth/tmp/slave
Executing "/home/lth/.espressif/python_env/idf5.3_py3.13_env/bin/python /home/lth/esp/esp-idf/tools/idf_monitor.py -p /dev/ttyACM0 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 --revision 0 /home/lth/tmp/slave/build/network_adapter.elf -m '/home/lth/.espressif/python_env/idf5.3_py3.13_env/bin/python' '/home/lth/esp/esp-idf/tools/idf.py'"...
--- esp-idf-monitor 1.9.0 on /dev/ttyACM0 115200
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
I (100) boot:  4 ota_1            OTA app          00 11 ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x15 (USB_UART_CHIP_RESET),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x403cdba6
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2810,len:0x18e8
load:0x403c8700,len:0x4
load:0x403c8704,len:0xd7c
load:0x403cb700,len:0x3224
entry 0x403c8998
I (26) boot: ESP-IDF v5.3.5-506-g0cf21f6beb 2nd stage bootloader
I (27) boot: compile time May 31 2026 09:08:13
I (27) boot: Multicore bootloader
I (31) boot: chip revision: v0.1
I (35) boot: efuse block revision: v1.2
I (39) boot.esp32s3: Boot SPI Speed : 80MHz
I (44) boot.esp32s3: SPI Mode       : DIO
I (49) boot.esp32s3: SPI Flash Size : 4MB
I (54) boot: Enabling RNG early entropy source...
I (59) boot: Partition Table:
I (63) boot: ## Label            Usage          Type ST Offset   Length
I (70) boot:  0 nvs              WiFi data        01 02 00009000 00004000
I (77) boot:  1 otadata          OTA data         01 00 0000d000 00002000
I (85) boot:  2 phy_init         RF data          01 01 0000f000 00001000
I (92) boot:  3 ota_0            OTA app          00 10 00010000 00180000
I (100) boot:  4 ota_1            OTA app          00 11 00190000 00180000
I (107) boot: End of partition table
I (112) boot: No factory image, trying OTA 0
I (117) esp_image: segment 0: paddr=00010020 vaddr=3c090020 size=37ff4h (229364) map
I (163) esp_image: segment 1: paddr=0004801c vaddr=3fc9ee00 size=05108h ( 20744) load
I (168) esp_image: segment 2: paddr=0004d12c vaddr=40374000 size=02eech ( 12012) load
I (172) esp_image: segment 3: paddr=00050020 vaddr=42000020 size=8dc90h (580752) map
I (275) esp_image: segment 4: paddr=000ddcb8 vaddr=40376eec size=17e3ch ( 97852) load
I (305) boot: Loaded app from partition at offset 0x10000
I (356) boot: Set actual ota_seq=1 in otadata[0]
I (356) boot: Disabling RNG early entropy source...
I (367) cpu_start: Multicore app
I (376) cpu_start: Pro cpu start user code
I (376) cpu_start: cpu freq: 160000000 Hz
I (376) app_init: Application information:
I (379) app_init: Project name:     network_adapter
I (384) app_init: App version:      2.12.8
I (389) app_init: Compile time:     May 31 2026 09:07:44
I (395) app_init: ELF file SHA256:  7cb8a5f36...
I (401) app_init: ESP-IDF:          v5.3.5-506-g0cf21f6beb
I (407) efuse_init: Min chip rev:     v0.0
I (411) efuse_init: Max chip rev:     v0.99 
I (416) efuse_init: Chip rev:         v0.1
I (421) heap_init: Initializing. RAM available for dynamic allocation:
I (428) heap_init: At 3FCA9850 len 0003FEC0 (255 KiB): RAM
I (435) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (441) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (447) heap_init: At 600FE000 len 00001FE8 (7 KiB): RTCRAM
I (454) spi_flash: detected chip: generic
I (458) spi_flash: flash io: dio
W (462) spi_flash: Detected size(8192k) larger than the size in the binary image header(4096k). Using the size in the binary image header.
I (475) sleep: Configure to isolate all GPIO pins in sleep state
I (482) sleep: Enable automatic switching of GPIO sleep configuration
I (499) main_task: Started on CPU0
I (503) main_task: Calling app_main()
I (512) co-pro-main: *********************************************************************
I (516) co-pro-main:                 ESP-Hosted-MCU Slave FW version :: 2.12.8                        
I (526) co-pro-main:                 Transport used :: SPI only                      
I (535) co-pro-main: *********************************************************************
I (544) SPI_DRIVER: Using SPI interface
I (548) gpio: GPIO[17]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (557) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (567) SPI_DRIVER: SPI Ctrl:1 mode: 3, Freq:ConfigAtHost
GPIOs: CLK:12 MOSI:11 MISO:13 CS:10 HS:17 DR:4

I (577) SPI_DRIVER: Hosted SPI queue size: Tx:20 Rx:20
I (583) gpio: GPIO[10]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (592) gpio: GPIO[10]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (602) SPI_DRIVER: SPI post process task started
I (607) co-pro-main: host reset handler task started
I (612) co-pro-main: Supported features are:
I (617) co-pro-main: - WLAN over SPI
I (621) h_bt: - BT/BLE
I (624) h_bt:    - HCI Over SPI
I (628) h_bt:    - BLE only
I (632) co-pro-main: capabilities: 0xe8
I (636) co-pro-main: Supported extended features are:
I (642) h_bt: - BT/BLE (extended)
I (646) co-pro-main: extended capabilities: 0x0
I (651) co-pro-main: host reconfig event
I (656) SPI_DRIVER: Slave chip Id[12]
I (660) main_task: Returned from app_main()
I (660) slave_rpc: event ESPInit

Miscellaneous links