ESP-Hosted-MCU is an open-source solution that allows you to use Espressif Chipsets and modules as a communication co-processor. This solution provides wireless connectivity (Wi-Fi and Bluetooth) to the host microprocessor or microcontroller, enabling it to communicate with other devices. Additionally, the user has complete control over the co-processor's resources.
This high-level block diagram shows ESP-Hosted's relationship with the host MCU and slave co-processor.
For detailed design diagrams in Wi-Fi and Bluetooth, refer to the following design documents:
This branch, feature/esp_as_mcu_host
is dedicated for any host as MCU support. If you are interested in Linux as host, please refer to master
branch.
This is an ESP chip that provides Wi-Fi, Bluetooth, and other capabilities. It is also referred as hosted-slave
interchangeably.
This can be any generic microcontroller (MCU). We demonstrate any ESP as host. Using port layer, any host can act as host MCU.
Impatient to test? We've got you covered! The ESP32-P4-Function-EV-Board can be used as a host MCU with an on-board ESP32-C6 as co-processor, already connected via SDIO as transport. Prerequisite: You need to have an ESP32-P4-Function-EV-Board`
[!NOTE] If you have already set up ESP-IDF (version 5.3 or later), you can skip to 5 Source Code and Dependencies.
Windows
Linux or MacOS
bash docs/setup_esp_idf__latest_stable__linux_macos.sh
fish docs/setup_esp_idf__latest_stable__linux_macos.fish
The host, ESP32-P4, lacks native Wi-Fi/Bluetooth support. Our Quick Demo will help you run iperf over P4--SDIO--C6.
No worries if you don't have an ESP32-P4. In fact, most users don't. You can choose and use any two ESP chipsets/SoCs/Modules/DevKits. DevKits are convenient to use as they have GPIO headers already in place. From these two ESP chipsets, one would act as host and another as slave/co-processor. However, as these are not connected directly, you would need to manually connect some transport, which is explained later in the section Detailed Setup
.
ESP-Hosted-MCU code can be found at Espressif Registry Component esp_hosted
(ESP-Hosted) or GitHub repo at ESP-Hosted
ESP-Hosted repo clone is not required if you have ESP as host.
However, For non-ESP host development, you can clone the repo using command:
git clone --recurse-submodules --branch feature/esp_as_mcu_host --depth 1 \
https://github.com/espressif/esp-hosted esp_hosted_mcu
ESP-Hosted-MCU Solution is dependent on ESP-IDF
, esp_wifi_remote
and protobuf-c
ESP-IDF
is the development framework for Espressif SoCs supported on Windows, Linux and macOSesp_wifi_remote
i.e. 'Wi-Fi Remote' is very thin interface made up of ESP-IDF Wi-Fi APIs with empty weak definitions. Real definitions for these APIs are provided by ESP-Hosted-MCUprotobuf-c
is data serialization framework provided by Google. RPC messages communicated in host and slave are protobuf encoded.common/protobuf-c
esp_wifi_init()
, etc.)The communication bus is required to be setup correctly between host and slave.
We refer this as transport medium
or simply transport
.
ESP-Hosted-MCU supports SPI/SDIO/UART transports. User can choose which transport to use. Choosing specific transport depends on factors: high performance, easy and quick to test, number of GPIOs used, or simply co-processor preference
Below is chart for the transport medium comparison.
Legends:
FD
: Full duplex communicationHD
: Half duplex communicationBT
: Bluetooth+2
in column Num of GPIOs
RST
/EN
pin of co-processor, to reset on bootupAny_Slave
Dedicated platforms
Host can be any ESP chipset or any non-ESP MCU.
Transport | Type | Num of GPIOs | Setup with | Co-processor supported | Host Tx iperf | Host Rx iperf | Remarks |
---|---|---|---|---|---|---|---|
Standard SPI | FD | 6 | jumper or PCB | Any_Slave | udp: 24 tcp: 22 | udp: 25 tcp: 22 | Simplest solution for quick test |
Dual SPI | HD | 5 | jumper or PCB | Any_Slave [1] | udp: 32 tcp: 26 (O) | udp: 33 tcp: 25 (O) | Better throughput, but half duplex |
Quad SPI | HD | 7 | PCB only | Any_Slave [1] | udp: 41 tcp: 29 (O) | udp: 42 tcp: 28 (O) | Due to signal integrity, PCB is mandatory |
SDIO 1-Bit | HD | 4 | jumper or PCB | ESP32, ESP32-C6 | TBD | TBD | Stepping stone for PCB based SDIO 4-bit |
SDIO 4-Bit | HD | 6 | PCB only | ESP32, ESP32-C6 | udp: 79.5 tcp: 53.4 (S) | udp: 68.1 tcp: 44 (S) | Highest performance |
Only BT over UART | FD | 2 or 4 | jumper or PCB | Any_Slave | NA | NA | Dedicated Bluetooth over UART pins |
UART | FD | 2 | jumper or PCB | Any_Slave | udp: 0.68 tcp: 0.67 (O) | udp: 0.68 tcp: 0.60 (O) | UART dedicated for BT & Wi-Fi [2] |
Dedicated platforms | FD | Extra 2 or 4 | jumper or PCB | Any_Slave | NA | NA | UART dedicated for BT & Wi-Fi on any other transport |
[!NOTE]
[1] Dual/Quad SPI is not supported on ESP32
[2] UART is only suitable for low throughput environments
With jumper cables, 'Standard SPI' and 'Dual SPI' solutions are easiest to evaluate, without much of hardware dependencies. SDIO 1-Bit can be tested with jumper cables, but it needs some additional hardware config, such as installation of external pull-up registers.
In case case of dedicated platforms, Blutooth uses standard HCI over UART. In rest of cases, Bluetooth and Wi-Fi uses same transport and hence less GPIOs and less complicated. In shared mode, bluetooth runs as vHCI (multiplexed mode)
Host and slave always populate below header at the start of every frame, irrespective of actual or dummy data in payload.
Field | Type | Bits | Mandatory? | Description |
---|---|---|---|---|
if_type | uint8_t | 4 | M | Interface type |
if_num | uint8_t | 4 | M | Interface number |
flags | uint8_t | 8 | M | Flags for additional information |
len | uint16_t | 16 | M | Length of the payload |
offset | uint16_t | 16 | M | Offset for the payload |
checksum | uint16_t | 16 | M | Checksum for error detection (0 if checksum disabled) |
seq_num | uint16_t | 16 | O | Sequence number for tracking packets (Useful in debugging) |
throttle_cmd | uint8_t | 0 or 2 | O | Flow control command |
reserved2 | uint8_t | 6 or 8 | M | Reserved bits |
reserved3 | uint8_t | 8 | M | Reserved byte (union field) |
hci_pkt_type or priv_pkt_type | uint8_t | 8 | M | Packet type for HCI interface (union field) |
Start of header states which type of frame is being carried.
Interface Type | Value | Description |
---|---|---|
ESP_INVALID_IF | 0 | Invalid interface |
ESP_STA_IF | 1 | Station frame |
ESP_AP_IF | 2 | SoftAP frame |
ESP_SERIAL_IF | 3 | Control frame |
ESP_HCI_IF | 4 | Bluetooth vHCI frame |
ESP_PRIV_IF | 5 | Private communication between slave and host |
ESP_TEST_IF | 6 | Transport throughput test |
ESP_ETH_IF | 7 | Invalid |
ESP_MAX_IF | 8 | type mentioned in dummy or empty frame |
Once you decided the transport to use, this section should guide how to set this transport, with hardware connections, configurations and verification. Users can evaluate one transport first and then move to other.
[!IMPORTANT]
Design Considerations that could be reffered to, before you stick to any transport option. Referring to these consideration would help to get you faster to solution, make your design stable and less error-prone.
Irrespective of transport chosen, following steps are needed, which are step-wise explained in each transport.
Check examples directory for sample applications using ESP-Hosted.
examples/bleprph_host_only_vhci
If you encounter issues with using ESP-Hosted, see the following guide: