diff --git a/README.md b/README.md index 396cae7e8a..4825c977ec 100644 --- a/README.md +++ b/README.md @@ -1,136 +1,259 @@ # ESP-Hosted -ESP-Hosted is an open source solution that provides a way to use -Espressif SoCs and modules as a communication co-processor. This -solution provides wireless connectivity (Wi-Fi and BT/BLE) to the host -microprocessor or microcontroller, allowing it to communicate with -other devices. - -## ESP as MCU Host branch - -This branch provides ESP-Hosted functionality to any generic MCU -host. The purpose is to allow the [ESP Wi-Fi api -calls](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html) -to be used on hosts that don't have native Wi-Fi. - -This branch showcases ESP chipsets to use as MCU hosts. For other -MCUs, a port layer is required to adapt Hosted to your MCU and OS. - -## Getting started +**Table of Contents** + +- [1. Introduction](#1-introduction) + - [1.1. ESP as MCU Host branch](#11-esp-as-mcu-host-branch) + - [1.2. ESP-Hosted Architecture](#12-esp-hosted-architecture) + - [1.2.1. ESP-Hosted Features](#121-esp-hosted-features) + - [1.2.2. ESP-Hosted Bluetooth Support](#122-esp-hosted-bluetooth-support) + - [1.3. Hosted on ESP32s with Native Wi-Fi](#13-hosted-on-esp32s-with-native-wi-fi) +- [2. Getting Started](#2-getting-started) + - [2.1. DevKit Specific Information](#21-devkit-specific-information) +- [3. Preparing the Host to use ESP-Hosted](#3-preparing-the-host-to-use-esp-hosted) + - [3.1. Adding required components to your ESP-IDF Project](#31-adding-required-components-to-your-esp-idf-project) + - [3.2. Disabling Native Wi-Fi Support](#32-disabling-native-wi-fi-support) +- [4. Getting the ESP-Hosted Slave Project](#4-getting-the-esp-hosted-slave-project) +- [5. Selecting the Hardware Interface for Host and Slave](#5-selecting-the-hardware-interface-for-host-and-slave) + - [5.1. Evaluating ESP-Hosted Hardware Interface](#51-evaluating-esp-hosted-hardware-interface) +- [6. Configuring the ESP-Hosted Components](#6-configuring-the-esp-hosted-components) + - [6.1. Configuring the Hosted Host](#61-configuring-the-hosted-host) + - [6.2. Configuring the Hosted Slave](#62-configuring-the-hosted-slave) + - [6.3. Flashing and Running ESP-Hosted](#63-flashing-and-running-esp-hosted) +- [7. Verifying that ESP-Hosted is Running](#7-verifying-that-esp-hosted-is-running) + - [7.1. Checking the Console Output](#71-checking-the-console-output) +- [8. Troubleshooting](#8-troubleshooting) +- [9. References](#9-references) + +## 1. Introduction -Two extra components are required to intergrate ESP-Hosted into the -host code. Both are available in the [ESP -Registry](https://components.espressif.com/): -- WiFi Remote ([https://components.espressif.com/components/espressif/esp_wifi_remote](https://components.espressif.com/components/espressif/esp_wifi_remote)) -- ESP-Hosted ([https://components.espressif.com/components/espressif/esp_hosted](https://components.espressif.com/components/espressif/esp_hosted)) +ESP-Hosted is an open source solution that provides a way to use +Espressif SoCs and modules as a communication (slave) +co-processor. This solution provides wireless connectivity (Wi-Fi and +Bluetooth) to the host microprocessor or microcontroller, allowing it +to communicate with other devices. + +This high-level block diagram shows ESP-Hosted's relationship with the +host MCU and slave co-processor. + +![ESP-Hosted Block Dragram](docs/images/hosted_diagram-ditaa.svg) + +*ESP-Hosted Block Dragram* + +### 1.1. ESP as MCU Host branch + +This branch uses ESP chipsets as the host processor. This allows the +ESP Wi-Fi api calls to be used on ESP chipsets that don't have native +Wi-Fi. ESP-IDF applications like the ESP-IDF Iperf Example can be +built and run on the ESP32-P4 without changes, using Hosted and a +ESP32 co-processor to provide the Wi-Fi connection. + +### 1.2. ESP-Hosted Architecture + +There are two parts in the ESP-Hosted solution, the Hosted slave, +which is an ESP chip, and a host MCU, which can be a generic MCU. The +ESP-Hosted Slave provides the Wi-Fi, Bluetooth and other capabilities, +which the host MCU uses through Hosted. + +ESP-Hosted is an open-source and modular code, and uses RPC (Remote +Procedure Calls) for passing commands from the host to the slave. This +RPC mechanism allows the slave capabilities to be provided to the +host. These RPC calls are sent through a reliable bus communication, +such as SPI or SDIO or UART. + +Data (network or Bluetooth) is encapsulated at the transport layer by +Hosted and passed through the interface, minimising overhead and +delays. + +#### 1.2.1. ESP-Hosted Features + +- **any MCU can be set-up as the host**. An ESP chipset is used here + as an example. For other MCUs, you can evaluate ESP-Hosted using an + ESP chip as the host first, and then follow-up by porting ESP-Hosted + to your desired MCU. +- **any ESP chip with Wi-Fi and/or Bluetooth capabilities can be used + as the Hosted slave**. Pick the desired slave device, depending on + your product requirements. The ESP Product Selector can guide you on + the proper ESP slave selection. +- **the RCP calls used by ESP-Hosted can be extended to provide any + function required by the Host**. As long as the slave can support + it. At present, the essential ESP-IDF Wi-Fi functions have been + implemented. +- **example of ESP-Hosted in action**. It runs on the + ESP32-P4-Function-EV-Board (see [DevKit Specific + Information](#21-devkit-specific-information)), running the standard + ESP-IDF Iperf example. + +#### 1.2.2. ESP-Hosted Bluetooth Support + +See [Bluetooth Implementation](docs/bluetooth_implementation.md) for +details on Bluetooth support by ESP-Hosted. + +
+ +Sequence Diagrams for Hosted System + +**Sequence Diagram for Wi-Fi on a Hosted System** + +On a ESP chipset with native Wi-Fi, a Wi-Fi api call or network data +from the application is processed internally on the chip and a Wi-Fi +response is returned to the application. + +```mermaid +sequenceDiagram + box Grey Host With Native WI-Fi + participant app as Application + participant api as ESP-IDF Wi-Fi Library + participant wifi as Wi-Fi Hardware + end + + app ->> api : esp_wifi_xxx() or Network Data + api ->> wifi : + Note over wifi : Do Wi-Fi action + wifi -->> api : Wi-Fi response or Data + api -->> app : Response or Network Data +``` -WiFi Remote is an API layer that provides the standard ESP-IDF Wi-Fi -calls to the application (`esp_wifi_init()`, etc.). WiFi Remote -forwards the Wi-Fi calls to ESP-Hosted, which transports the incoming -Wi-Fi calls as remote requests to the slave. +*Native Wi-Fi Call* + +Using Wi-Remote and ESP-Hosted, the Wi-Fi api call from the +application is converted into a Hosted Call and transported to the +slave. The slave converts the Hosted Call back into an Wi-Fi api +call. The response (optionally with data) is converted into a Hosted +Response and transported back to the host. On the host, the Hosted +Response is converted back into a Wi-Fi response (optionally with +data) is returned to the application. + +For Network Data, Hosted does not do data conversion and only +encapsulates the data for transport. + +```mermaid +sequenceDiagram + box Grey Host with ESP-Hosted + participant app as Application + participant remote as Wi-Fi Remote + participant hostedh as ESP-Hosted + participant transporth as Host Transport + end + + box SlateGrey Slave ESP-Hosted + participant transports as Slave Transport + participant hosteds as Slave Hosted + participant api as ESP-IDF Wi-Fi Library + participant wifi as Wi-Fi Hardware + end + + app ->> remote : esp_wifi_xxx() + remote ->> hostedh : esp_wifi_remote_xxx() + app ->> hostedh : Network Data + Note over hostedh : add Hosted header + hostedh ->> transporth : + + transporth ->> transports : SPI/SDIO + + transports ->> hosteds : + Note over hosteds : remove Hosted header + hosteds ->> api : esp_wifi_xxx() + api ->> wifi : Wi-Fi command + hosteds ->> wifi : Network Data + Note over wifi: Do Wi-Fi action + wifi -->> hosteds : Network Data + wifi -->> api : Wi-Fi response + api -->> hosteds : Response + Note over hosteds : add Hosted header + hosteds -->> transports : + + transports -->> transporth : SPI/SDIO + + transporth -->> hostedh : + Note over hostedh : remove Hosted header + hostedh -->> app : Network Data + hostedh -->> remote : Wi-Fi Command response + remote -->> app : Response +``` -Responses are received by ESP-Hosted and returned to WiFi Remote, -which returns the reponses to the calling app. To the calling app, it -is as if it made a standard ESP-IDF Wi-Fi api call. +*Hosted Wi-Fi Call* -Wi-Fi events are received by Hosted and send to the standard ESP-IDF -event loop on the host. +
-## Selecting hardware interface +
-Hosted can currently use the SPI or SDIO (on selected ESP chips) -interfaces. For testing Hosted, it is recommended to use the SPI -interface as it is easier to evaluate using jumper cables. SDIO and -UART are also supported. Among the interfaces, SDIO provides the -highest throughput. +Hosted on ESP32s with Native Wi-Fi -### Using the SPI interface +### 1.3. Hosted on ESP32s with Native Wi-Fi -The SPI interface can use almost any GPIO pins. But for maximum speed -and minimal delays, it is recommended to select the default SPI pins -configuration that use the dedicated `IO_MUX` pins. See these documents -for [SPI -host](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html#gpio-matrix-and-io-mux) -and [SPI -slave](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_slave.html#gpio-matrix-and-io-mux) -for more information. +You can also use Hosted on ESP chipsets that have native Wi-Fi. This +is useful for evaluating Hosted using current ESP chipsets before +migrating to ESP chipsets without native Wi-Fi as a host. This is +covered in more detail in the section [Disabling Native Wi-Fi +Support](#32-disabling-native-wi-fi-support). -This table summarises the recommended SPI GPIO pins for various ESP SoCs: +
-| GPIO | ESP-32 | ESP32-C2/C3/C6 | ESP32-S2/S3 | -| :--: | --: | --: | --: | -|------|--------|----------------|-------------| -| MOSI | 13 | 7 | 11 | -| MISO | 12 | 2 | 13 | -| CLK | 14 | 6 | 12 | -| CS | 15 | 10 | 10 | +## 2. Getting Started -Besides the standard SPI `CS`, `CLK`, `MOSI` and `MISO` -signals, additional GPIOs are required. These are for `Handshake` and -`Data Ready` and can be assigned to any GPIOs. +> [!NOTE] +> See [References](#9-references) for the links to ESP-IDF and +> ESP Registry Components -For prototyping, it is recommended to use short wires (5 to 10 cm in -length, shorter is better) to minimise propagation delay and noise. +**Set up ESP-IDF before trying Hosted**: see the *ESP-IDF Get Started +Guide* on getting and installing ESP-IDF on your operating system +(Linux, macOS, Windows). -### Using the SDIO interface +**Getting extra IDF components**: extra ESP Components are required to +integrate ESP-Hosted into your ESP-IDF project. Both are available in +the ESP Registry: -The SDIO interface has the same pull-up requirements as the SD -interface (10 kOhm resistors are recommended). See the [SD Pull-up -Requirements](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sd_pullup_requirements.html) -documentation for more details. Because of the pull-up requirements, -using jumper cables for SDIO is not recommended. +- `esp_wifi_remote` (Wi-Fi Remote) +- `esp_hosted` (ESP-Hosted) -If you use the ESP32 as the SDIO slave, fixing the SDIO pin voltage may -be required by buring the eFuses, depending on the ESP32 module used. See -the ["Overview of -Compatability"](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sd_pullup_requirements.html#compatibility-overview-espressif-hw-sdio) -documentation. +Wi-Fi Remote is an API layer that provides the standard ESP-IDF Wi-Fi +calls to the application (`esp_wifi_init()`, etc.). Wi-Fi Remote +forwards the Wi-Fi calls to ESP-Hosted, which transports the calls as +remote requests to the slave. -Only the ESP32-C6 and ESP32 can be used as the SDIO slave, while the -ESP32 and ESP32-S3 can be used as the SDIO host. +Responses are received from the slave by ESP-Hosted and returned to +Wi-Fi Remote, which returns the reponses to the calling app. To the +app, it is as if it made a standard ESP-IDF Wi-Fi API call. -On the ESP32 / ESP32-C6, the SDIO pins are fixed: +Wi-Fi events are received by ESP-Hosted from the slave and sent to the +standard ESP-IDF event loop on the host. -| | ESP32 | ESP32-C6 | -| :-- | --: | --: | -| Signal | GPIO | GPIO | -|--------|-------|----------| -| CLK | 14 | 19 | -| CMD | 15 | 18 | -| DAT0 | 2 | 20 | -| DAT1 | 4 | 21 | -| DAT2 | 12 | 22 | -| DAT3 | 13 | 23 | +Steps to integrate these components into your ESP-IDF project can be +found in the section [Preparing the Host to use +ESP-Hosted](#3-preparing-the-host-to-use-esp-hosted). -On the ESP32-S3 the GPIO pin assignments are flexible. +### 2.1. DevKit Specific Information -To summarize, **for SDIO**: +ESP-Hosted comes with a default configuration that can be directly +used with the following ESP DevKits: ---- +- [ESP32-P4-Function-EV-Board](docs/esp32_p4_function_ev_board.md) -> - using jumper cables is not recommended. -> - external pull-up are required. 10 kOhm resistors are recommended. -> - for ESP32, check if eFuse burning is required +## 3. Preparing the Host to use ESP-Hosted ---- +### 3.1. Adding required components to your ESP-IDF Project -### Reset signal for the slave +Check your project's `idf_component.yml` file. If it does not contain +`espressif/esp_wifi_remote` or `espressif/esp_hosted` as dependencies, +you can add them to your project: -The host also needs a signal to reset the slave during -initialization. This can be any GPIO on the host. This signal can be -connected to the `RST` / `EN` pin or to a GPIO pin on the slave. +``` +idf.py add-dependency "espressif/esp_wifi_remote" +idf.py add-dependency "espressif/esp_hosted" +``` -This is required for any hardware interface used. +
-## Preparing Host to use ESP-Hosted +3.2. Disabling Native Wi-Fi Support -### Disabling native Wi-Fi support +### 3.2. Disabling Native Wi-Fi Support -Hosts with native Wi-Fi support (ESP32 series, for example) need to -disable it before ESP Hosted can be enabled and used on the system. +For ESP Chipsets with native Wi-Fi support (the ESP32 series, for +example), you also have to disable native Wi-Fi before ESP-Hosted can used. To do this, edit the ESP-IDF -`components/soc//include/soc/Kconfig.soc_caps.in` file and change +`components/soc//include/soc/Kconfig.soc_caps.in` file and change all `WIFI` related configs to `n`. For example: ``` @@ -140,56 +263,156 @@ config SOC_WIFI_SUPPORTED default n ``` -This should be done for all `config SOC_WIFI_xxx` found in the file. +This should be done for all `SOC_WIFI_xxx` configs found in the file. -This is not required for ESP32-P4 as it has no native Wi-Fi and its -`Kconfig.soc_caps.in` reflects this configuration. +For ESP Chipsets without native Wi-FI, `SOC_WIFI_xxx` configs will be +`n` by default. -### Adding required components +
-To integrate the required components into the host code, add the -following dependencies to your host application `idf_component.yml` -file: +## 4. Getting the ESP-Hosted Slave Project + +The ESP-Hosted slave project can be checked out from the ESP-Hosted +Component's example project: ``` - espressif/esp_hosted: - version: "*" - pre_release: true - espressif/esp_wifi_remote: - version: "*" +idf.py create-project-from-example "espressif/esp_hosted:slave" ``` -ESP-Hosted is currently in pre-release, so the `pre_release: true` -line is required. Once ESP-Hosted is out of pre-release, it will not -be needed. +## 5. Selecting the Hardware Interface for Host and Slave + +ESP-Hosted can currently use the SPI or SDIO (on selected ESP chips) +interfaces. See the following pages for more information on these +interfaces: -## Preparing Slave for ESP-Hosted +- [SPI Full Duplex interface](docs/spi_full_duplex.md) +- [SDIO interface](docs/sdio.md) +- [SPI Half Duplex interface](docs/spi_half_duplex.md) -To build ESP-Hosted on the Slave, check out the slave as example code -from the [ESP-Hosted ESP -Registry](https://components.espressif.com/components/espressif/esp_hosted) -into an empty directory: +### 5.1. Evaluating ESP-Hosted Hardware Interface + +For evaluating ESP-Hosted, it is recommended to use the SPI interface +as it is easier to prototype using jumper cables. SDIO provides the +highest throughput but has tighter hardware requirements and requires +using the Host and Slave on a PCB to work correctly. + +## 6. Configuring the ESP-Hosted Components + +Ensure that both Host and Slave are configured to use the same +interface (SPI, SDIO) and GPIOs have been selected to match the +hardware connections. + +> [!NOTE] +> You can use a lower clock speed to verify the connections. For SPI, +> you can try 10 MHz. For SDIO you can use a clock speed between 400 +> kHz to 20 MHz. The actual clock used is determined by the +> hardware. Use an oscilloscope to check the actual clock frequency +> used. + +> [!NOTE] +> For SDIO testing, you can set the SDIO Bus Width to 1-Bit. In 1-Bit +> mode, only `DAT0` and `DAT1` signals are used for data and are less +> affected by noise on the signal lines. + +### 6.1. Configuring the Hosted Host + +To configure the host, go to the directory where your ESP-IDF project +is located and execute: + +```sh +idf.py set-target +idf.py menuconfig +``` -`idf.py create-project-from-example "espressif/esp_hosted:slave"` +The configuration options for Hosted Host can be found under **Component +config** ---> **ESP-Hosted config**. -## Configuring the Host and Slave +### 6.2. Configuring the Hosted Slave -To configure the host and slave, run `idf.py set-target ` and -`idf.py menuconfig`. +To configure the slave, go to the directory where you have checked out +the Hosted slave example project and execute: + +```sh +idf.py set-target +idf.py menuconfig +``` +The configuration options for the Hosted Slave can be found under **Example Configuration**. + +### 6.3. Flashing and Running ESP-Hosted + +Use the standard ESP-IDF `idf.py` to build, flash and (optionally) +monitor the debug output from the console on both the host and slave: + +```sh +idf.py build +idf.py -p flash monitor +``` + +## 7. Verifying that ESP-Hosted is Running + +> [!NOTE] +> If you are building and connecting the ESP-Hosted Host and Slave +> on the same development system, make sure to verify which +> Serial Port refers to the Host and Slave. + +### 7.1. Checking the Console Output + +Once both systems have been flashed and running, you should see output +similar to the following output on the console after start-up. For +example, if you are using the SPI Interface: + +For ESP-Hosted Master: + +``` +I (522) transport: Attempt connection with slave: retry[0] +I (525) transport: Reset slave using GPIO[54] +I (530) os_wrapper_esp: GPIO [54] configured +I (535) gpio: GPIO[54]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (1712) transport: Received INIT event from ESP32 peripheral +I (1712) transport: EVENT: 12 +I (1712) transport: EVENT: 11 +I (1715) transport: capabilities: 0xe8 +I (1719) transport: Features supported are: +I (1724) transport: - HCI over SPI +I (1728) transport: - BLE only +I (1732) transport: EVENT: 13 +I (1736) transport: ESP board type is : 13 + +I (1741) transport: Base transport is set-up +``` + +For ESP-Hosted Slave: + +``` +I (492) fg_mcu_slave: ********************************************************************* +I (501) fg_mcu_slave: ESP-Hosted-MCU Slave FW version :: 0.0.6 + +I (511) fg_mcu_slave: Transport used :: SPI only +I (520) fg_mcu_slave: ********************************************************************* +I (529) fg_mcu_slave: Supported features are: +I (534) fg_mcu_slave: - WLAN over SPI +I (538) h_bt: - BT/BLE +I (541) h_bt: - HCI Over SPI +I (545) h_bt: - BLE only +``` -The configuration for the Host can be found at `Component config ----> ESP-Hosted config`. +## 8. Troubleshooting -The configuration for the Slave can be found at `Example -Configuration`. +If you encounter issues with using ESP-Hosted, see the following guide: -Ensure that both are configured to use the same interface (SPI, SDIO) -and GPIOs have been selected to match the hardware connections. The -clock speed can be set to a lower speed (10 MHz for SPI, 20 MHz for -SDIO) first to verify the connections. +- [Troubleshooting Guide](docs/troubleshooting.md) -## Building and running +## 9. References -You can now run `idf.py build` to build both the host and slave, -`idf.py -p flash monitor` to flash the firmware and run -the terminal monitor. +- ESP Product Selector: https://products.espressif.com/ +- ESP-IDF Get Started Guide: +https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/ +- ESP-IDF Wi-Fi API: + https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html +- ESP-IDF Iperf Example: + https://github.com/espressif/esp-idf/tree/master/examples/wifi/iperf +- ESP-IDF NimBLE: https://github.com/espressif/esp-nimble +- ESP Registry: https://components.espressif.com/ +- `esp_wifi_remote` Component: + https://components.espressif.com/components/espressif/esp_wifi_remote +- esp_hosted` Component: https://components.espressif.com/components/espressif/esp_hosted diff --git a/docs/bluetooth_implementation.md b/docs/bluetooth_implementation.md new file mode 100644 index 0000000000..7b9a4ed713 --- /dev/null +++ b/docs/bluetooth_implementation.md @@ -0,0 +1,283 @@ +# Bluetooth Implementation in ESP-Hosted + +**Table of Contents** + +- [1. Introduction](#1-introduction) +- [2. Bluetooth Controller](#2-bluetooth-controller) +- [3. Bluetooth Interface](#3-bluetooth-interface) +- [4. NimBLE Host Stack](#4-nimble-host-stack) +- [5. Transporting HCI data using vHCI](#5-transporting-hci-data-using-vhci) + - [5.1. Bluetooth Host vHCI Initialization](#51-bluetooth-host-vhci-initialization) + - [5.2. Bluetooth Host Sending Data through vHCI](#52-bluetooth-host-sending-data-through-vhci) + - [5.3. Bluetooth Host Receiving Data from vHCI](#53-bluetooth-host-receiving-data-from-vhci) +- [6. Transporting HCI data using UART](#6-transporting-hci-data-using-uart) + - [6.1. Bluetooth Host HCI Initialization](#61-bluetooth-host-hci-initialization) + - [6.2. Bluetooth Host Sending Data using HCI](#62-bluetooth-host-sending-data-using-hci) + - [6.3. Bluetooth Host Receiving Data using HCI](#63-bluetooth-host-receiving-data-using-hci) +- [7. References](#7-references) + +## 1. Introduction + +ESP-Hosted can transport Bluetooth HCI packets between the Bluetooth +Host on the Hosted Master and the Bluetooth Controller on the Hosted +Slave. The Host MCU implement the Bluetooth app and Bluetooth Host +Stack and the Slave runs the Bluetooth controller and hardware. + +> [!NOTE] +> Check that the memory requirement for your preferred Bluetooth host +> stack can be satisfied on the Host. + +ESP-Hosted has not preferred Bluetooth stack. To showcase ESP-Hosted's +Bluetooth support, `esp-nimble` is used here. Users can use their own +preferred Bluetooth stack with some porting effort. + +`esp-nimble` is a fork of Apache NimBLE and available from +ESP-IDF. The NimBLE Bluetooth slack proves Bluetooth Low Energy (BLE) +only functionality. + +See [References](#7-references) for links with more information. + +## 2. Bluetooth Controller + +ESP-Hosted uses the Bluetooth controller running on the slave. The Slave +is expected to be configured to use BT Controller-only mode. + +As ESP-Hosted is just communication medium, it doesn't limit to BLE +only. Classic BT stacks are also supported, given the slave has +Classic-BT controller. The Classic-BT or BLE or both availability +depends upon the Bluetooth stack support and ESP chipset chosen. As of +today, ESP32 supports Classic-BT+BLE, whereas, the other ESP slave +chipsets support BLE only. + +## 3. Bluetooth Interface + +Hosted provides two ways to let the Bluetooth Host stack running on +the Host to communicate with the Bluetooth controller on the Slave. + +**vHCI** + +- vHCI is standard HCI with extra headers or metadata added +- vHCI embeds the ESP-Hosted header and re-uses the underlying + ESP-Hosted transport, such as SPI/SDIO +- this option is easier to set up. Once the existing SPI or SDIO + transport has been set up, Bluetooth works + +Use this option if you want: + +- complete control of Bluetooth messages +- extra flexibility of debugging +- no extra GPIOs (required for Standard HCI) + +**Standard HCI** + +- standard HCI is a transparent way of handling HCI messages +- HCI messages originating from the Bluetooth stack on the Host are + sent through an interface (like UART) to the Bluetooth controller on + the Slave +- requires extra GPIO for the HCI interface, independent of the GPIOs + used for the ESP-Hosted interface + +Use this option if you want: + +- transparency: no extra data added to the HCI messages +- portability: because it is standard HCI, you can replace the Slave + with any other co-processor (ESP or otherwise) that has a Bluetooth + controller + +> [!NOTE] +> If Hosted is configured as the Bluetooth transport (vHCI), then your +> Bluetooth over HCI configuration must be disabled, and vice +> versa. + +## 4. NimBLE Host Stack + +The ESP-Hosted Master implements the set of API calls required by the +NimBLE Bluetooth stack to initialize, send and receive Bluetooth data: + +- `hci_drv_init` +- `ble_transport_ll_init` +- `ble_transport_to_ll_acl_impl` +- `ble_transport_to_ll_cmd_impl` +- `ble_transport_to_hs_evt` +- `ble_transport_to_hs_acl` + +The following sequence diagrams show how to send and receive Bluetooth +on both the Hosted Master and Slave. + +## 5. Transporting HCI data using vHCI + +### 5.1. Bluetooth Host vHCI Initialization + +```mermaid +sequenceDiagram + box Grey Hosted Master + participant ble as NimBLE Host Bluetooth Stack + participant vhci as VHCI Driver + participant master as SPI/SDIO Interface + end + + box Grey Hosted Slave + participant sinterface as SPI/SDIO Interface + participant slave as Bluetooth Controller + end + + ble ->> +vhci : hci_drv_init() + Note over vhci: do any init required + vhci -->> -ble : + + ble ->> +vhci : ble_transport_ll_init() + Note over vhci : do any transport init required + vhci -->> -ble : +``` + +**Bluetooth Host Initialization** + +### 5.2. Bluetooth Host Sending Data through vHCI + +```mermaid +sequenceDiagram + box Grey Hosted Master + participant ble as NimBLE Host Bluetooth Stack + participant vhci as VHCI Driver + participant master as SPI/SDIO Interface + end + + box Grey Hosted Slave + participant sinterface as SPI/SDIO Interface + participant slave as Bluetooth Controller + end + + ble ->> +vhci : ble_transport_to_ll_acl_impl() + Note over vhci : convert ACL data to HCI + vhci ->> +master : esp_hosted_tx() + Note over master : add Hosted header + master ->> +sinterface: SPI/SDIO + Note over master,sinterface : (VHCI data) + master -->> -vhci : + vhci -->> -ble : + + Note over sinterface : remove Hosted header + sinterface ->> -slave : HCI data +``` + +**Bluetooth Host Sending Data** + +### 5.3. Bluetooth Host Receiving Data from vHCI + +```mermaid +sequenceDiagram + box Grey Hosted Master + participant ble as NimBLE Host Bluetooth Stack + participant vhci as VHCI Driver + participant master as SPI/SDIO Interface + end + + box Grey Hosted Slave + participant sinterface as SPI/SDIO Interface + participant slave as Bluetooth Controller + end + + slave ->> +sinterface : HCI data + Note over sinterface : Add Hosted header + sinterface ->> -master : SPI/SDIO + Note over sinterface,master : (VHCI data) + Note over master : Remove Hosted header + + master ->> +vhci : hci_rx_handler() + + alt Receive Event Data + Note over vhci: convert HCI data to Event + vhci ->> ble : ble_transport_to_hs_evt() + ble -->> vhci : + else Receive ACL Data + Note over vhci: convert HCI data to ACL + vhci ->> ble : ble_transport_to_hs_acl() + ble -->> vhci : + end + + vhci -->> -master : +``` + +**Bluetooth Host Receiving Data** + +## 6. Transporting HCI data using UART + +### 6.1. Bluetooth Host HCI Initialization + +```mermaid +sequenceDiagram + box Grey Master + participant ble as NimBLE Host Bluetooth Stack + participant huart as UART Driver + end + + box Grey Slave + participant slave as Bluetooth Controller with UART Interface + end + + ble ->> huart : hci_drv_init() + Note over huart : do any init required + huart -->> ble : + + ble ->> huart : ble_transport_ll_init() + Note over huart : do any transport init required + huart --> ble : +``` + +**Bluetooth Host Initialization** + +### 6.2. Bluetooth Host Sending Data using HCI + +```mermaid +sequenceDiagram + box Grey Master + participant ble as NimBLE Host Bluetooth Stack + participant huart as UART Driver + end + + box Grey Slave + participant slave as Bluetooth Controller with UART Interface + end + + ble ->> huart : ble_transport_to_ll_acl_impl() + Note over huart : convert ACL data to HCI + huart ->> slave : UART TX + Note over huart,slave : (standard HCI) + huart -->> ble : +``` + +**Bluetooth Host Sending Data** + +### 6.3. Bluetooth Host Receiving Data using HCI + +```mermaid +sequenceDiagram + box Grey Master + participant ble as NimBLE Host Bluetooth Stack + participant huart as UART Driver + end + + box Grey Slave + participant slave as Bluetooth Controller with UART Interface + end + + slave ->> huart : UART RX + Note over slave,huart: (standard HCI) + + alt Receive Event Data + Note over huart : convert HCI data to Event + huart ->> ble : ble_transport_to_hs_evt() + ble -->> huart : + else Receive ACL Data + Note over huart : convert HCI data to ACL + huart ->> ble : ble_transport_to_hs_acl() + ble -->> huart : + end +``` + +**Bluetooth Host Receiving Data** + +## 7. References + +- esp-nimble: https://github.com/espressif/esp-nimble +- ESP-IDF NimBLE-based Host APIs: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/bluetooth/nimble/index.html diff --git a/docs/design_consideration.md b/docs/design_consideration.md new file mode 100644 index 0000000000..ab128ba354 --- /dev/null +++ b/docs/design_consideration.md @@ -0,0 +1,181 @@ +# Design Considerations and Debugging ESP-Hosted + +**Table of Contents** + +- [1. Choosing the Correct ESP chip as Slave](#1-choosing-the-correct-esp-chip-as-slave) +- [1.1 Using ESP chip as Hosted Master](#11-using-esp-chip-as-hosted-master) +- [2. General Hardware Considerations](#2-general-hardware-considerations) + - [2.1. GPIOs used for interface](#21-gpios-used-for-interface) + - [2.2. Using SPI insted of SDIO](#22-using-spi-insted-of-sdio) + - [2.3. Whenever possible, Use `IO_MUX` GPIOs.](#23-whenever-possible-use-io_mux-gpios) + - [2.4. Signal Length and Noise Reduction](#24-signal-length-and-noise-reduction) +- [3. General Debugging Guidelines](#3-general-debugging-guidelines) + - [3.1. Add tapping points to your PCB prototype](#31-add-tapping-points-to-your-pcb-prototype) + - [3.2. Tap out additional GPIO signals as testing points and future expansion](#32-tap-out-additional-gpio-signals-as-testing-points-and-future-expansion) + - [3.3 Verifying Hosted Interface with Raw Throughput](#33-verifying-hosted-interface-with-raw-throughput) +- [4. Others](#4-others) +- [5. References](#5-references) + +There are several considerations that need to be taken into account +when implementing ESP-Hosted for your system. + +## 1. Choosing the Correct ESP chip as Slave + +For prototyping, any ESP32 chip can be used as the slave, provided it +has the required interface (SPI, SDIO). But when creating an actual +product, it is important to select the proper ESP32 chip as a Hosted +Slave. + +There are many ESP32 chips, each with difference features and +performance capabilities. Based on your product requirements +(interface to use, CPU, memory, power requirements, etc.), choose the +ESP32 chip(s) that can meet your requirements. + +Use the ESP Product Selector guide to help you decide which ESP32 +chips and/or modules are suitable for your product. + +> [!NOTE] +> See [References](#5-references) for links to the Selector Guide +> and other links. + +## 1.1 Using ESP chip as Hosted Master + +The project defaults to using an ESP chip as the Hosted Master. This +is to act as a reference platform and make it easier to evaluate and +test Hosted before porting it to your MCU of choice. + +## 2. General Hardware Considerations + +### 2.1. GPIOs used for interface + +Make sure the correct GPIOs pins on the Hosted Slave and Master are +connected together. Verify that the correct GPIOs are set-up in +`Menuconfig` for both the Slave and Master. + +> [!NOTE] +> In general most ESP GPIOs can be used for input and output. But on +> the ESP32, some GPIOs can only be used for input and are not usable +> under Hosted. Check the ESP datasheet to verify the GPIOs you select +> can be used as a Hosted interface. + +### 2.2. Using SPI insted of SDIO + +In general, SPI imposes fewer hardware requirements compared to +SDIO. SPI is easier to prototype, and available on more ESP chips and +MCUs compared to SDIO. + +However, if you need a high-speed interface, SDIO should be +considered. + +### 2.3. Whenever possible, Use `IO_MUX` GPIOs. + +In general, ESP peripheral interfaces can be assigned to any available +GPIO through a multiplexer. But some ESPs have dedicated GPIOs for +peripherals (`IO_MUX`). These `IO_MUX` GPIOs have better timing +characteristics and support higher frequencies. They should be use +when possible to minimise timing and skew issues when using the +interface for Hosted. + +> [!NOTE] +> The SDIO interface on the ESP32 and ESP32-C6 have fixed GPIO +> assignments and cannot be changed. + +### 2.4. Signal Length and Noise Reduction + +For best performance, a PCB with traces should be used to connect the +Hosted Slave and Master. For prototyping, jumper cables can be used, +but may only work at a lower `CLK` frequency. + +In general, keep the cable and PCB traces short and of the same +length, to minimise propogation delay and clock skew: + +- for SPI, keep them to 10 cm or less +- for SDIO, keep them to 5 cm or less + +Isolate the interface signals, expecially the `CLK` signal, from other +signals. For PCBs, surround the signal swith a ground plane, and keep +the `CLK` signal clean by not routing it close to other high frequency +signals. + +For jumper cables, you can try surrounding the signals, especially the +`CLK` signal, with grounded wires to shield them from interference. + +> [!NOTE] +> For SDIO, external pull-up resistors (recommended value: 51 kOhms) +> are required. Using jumper cable are not recommended for SDIO. You +> may be able to get SDIO working with jumper cables by using a lower +> `CLK` frequency and using 1-bit SDIO mode. + +> [!NOTE] +> Also check the Hosted documentation for SPI and SDIO for more +> information and guidelines on the interfaces. + +## 3. General Debugging Guidelines + +### 3.1. Add tapping points to your prototype + +Adding tapping points or headers to the Hosted interface signals on +your prototype will make it easier to check whether the Hosted +interface is working as expected. + +### 3.2. Tap out additional GPIO signals as testing points and future expansion + +Add tapping points to some unused GPIOs on both the Hosted Slave and +Host on your prototype PCB. This can later be use for debugging or +enhancing your own Hosted code. + +For example, add your own debugging code to the Hosted Slave and +Master code to set a GPIO value when a condition is met. This GPIO can +be used to light a LED or trigger a capture on an oscilloscope or +logic analyzer, for example. This is useful for capturing rare or +intermittent conditions while testing Hosted. + +In the future, Hosted may also offer more features, like controlling +power modes on the Host and Slave. These may require additional GPIOs +for control, so it would be good to keep some additional GPIOs +available and accesable for future use. + +### 3.3 Verifying Hosted Interface with Raw Throughput + +ESP-Hosted has a Raw Throughput Option to test sending of data between +the Host and Slave. This can be used to verify the hardware for signal +errors and to check the achievable throughput of Hosted. + +> [!IMPORTANT] +> Use this option to verify that Hosted hardware and software are +> working as expected before involving other software layers like +> networking. + +To enable the Raw Throughput Option on Slave, enter `Menuconfig` and +enable **Example Configuration** ---> **Hosted Debugging** ---> +**RawTP**. + +To enable the Raw Throughput Option and set Raw Throughput direction +on Host, enter `Menuconfig` and enable **Component config** ---> +**ESP-Hosted config** ---> **Debug Settings** ---> **RawTP**. Set +the data transfer direction: **Host to Slave**, **Slave to Host** or +**Bidirectional**. + +## 4. Others + +Check the References below for links to the Product Selector, and more +detailed information on the interfaces used in Hosted. If you have +other issues with Hosted, you can check the Troubleshooting Guide. + +You can also raise an Issue on the ESP-Hosted Github repository. Check +that the issue has not already been raised before submitting. The +solution to your problem may have already been provided. + +## 5. References + +**External Links** + +- ESP Product Selector: https://products.espressif.com/ +- ESP-Hosted Github Issues: https://github.com/espressif/esp-hosted/issues + +**ESP-Hosted Documentation Links** + +- SPI Full Duplex interface documentation: [spi_full_duplex.md](spi_full_duplex.md) +- SDIO interface documentation: [sdio.md](sdio.md) +- SPI Half Duplex interface documentation: [spi_half_duplex.md](spi_half_duplex.md) +- Troubleshooting Guide: [troubleshooting.md](troubleshooting.md) diff --git a/docs/esp32_p4_function_ev_board.md b/docs/esp32_p4_function_ev_board.md new file mode 100644 index 0000000000..1c62679f12 --- /dev/null +++ b/docs/esp32_p4_function_ev_board.md @@ -0,0 +1,244 @@ +# ESP-Hosted on the ESP32-P4-Function-EV-Board DevKit + +**Table of Contents** + +- [1. Introduction](#1-introduction) +- [2. Building ESP-Hosted as Host for the P4](#2-building-esp-hosted-as-host-for-the-p4) + - [2.1. Adding Wifi Remote and Hosted Components](#21-adding-wifi-remote-and-hosted-components) + - [2.2. Building the Firmware](#22-building-the-firmware) +- [3. Checking that ESP-Hosted is Running](#3-checking-that-esp-hosted-is-running) +- [4. Flashing the On-board ESP32-C6 using ESP-Prog](#4-flashing-the-on-board-esp32-c6-using-esp-prog) +- [5. Troubleshooting](#5-troubleshooting) +- [6. Flashing the On-board ESP32-P4 through the Serial Interface](#6-flashing-the-on-board-esp32-p4-through-the-serial-interface) +- [7. References](#7-references) + +## 1. Introduction + +This page documents using ESP-Hosted on the +ESP32-P4-Function-EV-Board. The board comes with an on-board ESP32-C6 +module, pre-flashed with ESP-Hosted slave code (v0.0.6). The board +provides a Wi-Fi connection to the on-board ESP32-P4, which acts as +the host. + +The image below shows the board. + + + +*ESP32-P4-Function-EV-Board* + +The ESP32-P4 communicates with the ESP32-C6 module using SDIO. + +## 2. Building ESP-Hosted as Host for the P4 + +### 2.1. Adding Wifi Remote and Hosted Components + +The Wi-Fi service is provided to the ESP32-P4 using the +`esp_wifi_remote` component. Check your project's `idf_component.yml` +file) to see if it is already present. If not, you can add this +component to your project: + +``` +idf.py add-dependency "espressif/esp_wifi_remote" +``` + +The `esp_wifi_remote` component has a dependency on ESP-Hosted and +will also add the `esp_hosted` component to your build. + +### 2.2. Building the Firmware + +Set the ESP32-P4 as the target, build, flash the firmware and +(optionally) monitor ESP32-P4 console output: + +```sh +idf.py set-target esp32p4 +idf.py build +idf.py -p flash monitor` +``` + +## 3. Checking that ESP-Hosted is Running + +When the P4 is running with Hosted, you should see console output similar to this after start-up: + +``` +I (498) H_API: esp_wifi_remote_init +I (498) transport: Attempt connection with slave: retry[0] +I (498) transport: Reset slave using GPIO[54] +I (498) os_wrapper_esp: GPIO [54] configured +I (508) gpio: GPIO[54]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (1678) sdio_wrapper: SDIO master: Data-Lines: 4-bit Freq(KHz)[40000 KHz] +I (1678) sdio_wrapper: GPIOs: CLK[18] CMD[19] D0[14] D1[15] D2[16] D3[17] Slave_Reset[54] +I (1678) H_SDIO_DRV: Starting SDIO process rx task +I (1678) sdio_wrapper: Queues: Tx[20] Rx[20] SDIO-Rx-Mode[3] +I (1718) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +I (1718) gpio: GPIO[17]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 +Name: +Type: SDIO +Speed: 40.00 MHz (limit: 40.00 MHz) +Size: 0MB +CSD: ver=1, sector_size=0, capacity=0 read_bl_len=0 +SCR: sd_spec=0, bus_width=0 +TUPLE: DEVICE, size: 3: D9 01 FF +TUPLE: MANFID, size: 4 + MANF: 0092, CARD: 6666 +TUPLE: FUNCID, size: 2: 0C 00 +TUPLE: FUNCE, size: 4: 00 00 02 32 +TUPLE: CONFIG, size: 5: 01 01 00 02 07 +TUPLE: CFTABLE_ENTRY, size: 8 + INDX: C1, Intface: 1, Default: 1, Conf-Entry-Num: 1 + IF: 41 + FS: 30, misc: 0, mem_space: 1, irq: 1, io_space: 0, timing: 0, power: 0 + IR: 30, mask: 1, IRQ: FF FF + LEN: FFFF +TUPLE: END +I (1768) sdio_wrapper: Function 0 Blocksize: 512 +I (1778) sdio_wrapper: Function 1 Blocksize: 512 +I (1778) H_SDIO_DRV: SDIO Host operating in PACKET MODE +I (1788) H_SDIO_DRV: generate slave intr +I (1798) transport: Received INIT event from ESP32 peripheral +I (1798) transport: EVENT: 12 +I (1798) transport: EVENT: 11 +I (1808) transport: capabilities: 0xd +I (1808) transport: Features supported are: +I (1818) transport: * WLAN +I (1818) transport: - HCI over SDIO +I (1818) transport: - BLE only +I (1828) transport: EVENT: 13 +I (1828) transport: ESP board type is : 13 + +I (1838) transport: Base transport is set-up + +I (1838) transport: Slave chip Id[12] +I (1848) hci_stub_drv: Host BT Support: Disabled +I (1848) H_SDIO_DRV: Received INIT event +I (1868) rpc_wrap: Received Slave ESP Init +``` + +## 4. Flashing the On-board ESP32-C6 using ESP-Prog + +> [!NOTE] +> ESP-Prog is only required if you want to flash firmware to the +> ESP32-C6 module using the standard ESP Tools. + +The image below shows the board with an ESP-Prog connected to the +header to communicate with the on-board ESP32-C6.. + + + +*ESP32-P4-Function-EV-Board with ESP-Prog Connected to ESP32-C6* + +If you need to update the ESP-Hosted slave firmware on the on-board +ESP32-C6 module using ESP-Prog, follow these steps: + +1. Check out the ESP-Hosted slave example project: + + +``` +idf.py create-project-from-example "espressif/esp_hosted:slave" +``` + +2. Set the target and start `Menuconfig`: + +```sh +idf.py set-target esp32c6 +idf.py menuconfig +``` + +3. Under **Example Configuration**, ensure that the Hosted transport + selected is `SDIO`. + +4. Build the firmware: + +```sh +idf.py build +``` + +5. Connect the Program Header on the ESP-Prog to the `PROG_C6` header + on the board. The connections are as follows: + +| ESP-Prog | PROG_C6 | Notes | +| --- | --- | --- | +| ESP\_EN | EN | | +| ESP\_TXD | TXD | | +| ESP\_RXD | RXD | | +| VDD | - | Do not connect | +| GND | GND | | +| ESP\_IO0 | IO0 | | + + +6. Flashing the firmware + +The on-board ESP32-P4 controls the reset signal for the ESP32-C6. To +prevent the P4 interfering with the C6 while flashing (by asserting +the C6 Reset signal during the firmware download), set the P4 into +Bootloader mode before flashing the firmware to the C6: + + 1. hold down the `BOOT` button on the board + 2. press and release the `RST` button on the board + 3. release the `BOOT` button + +You can now flash the firmware to the C6 (and monitor the console +output): + +```sh +idf.py -p flash monitor +``` + +## 5. Troubleshooting + +If you encounter issues with using ESP-Hosted, see the following guide: + +- [Troubleshooting Guide](troubleshooting.md) + +
+ +Flashing the On-board ESP32-P4 through the Serial Interface + +## 6. Flashing the On-board ESP32-P4 through the Serial Interface + +The USB connector on the board is the standard method for flashing the +firmware to the P4. An alternative method is to flash the P4 through +its serial interface using a ESP-Prog. + +The image below shows the connection between the ESP-Prog and the +serial port pins on the P4 header for programming. + + + +*ESP32-P4 Serial Connection with ESP-Prog* + +The connection between the ESP-Prog and the P4 header is as follows: + +| ESP-Prog | P4 Header | +| --- | --- | +| ESP\_TXD | U0TXD (GPIO 37) | +| ESP\_RXD | U0RXD (GPIO 38) | +| GND | GND | + +Leave the other ESP-Prog connected unconnected. + +To flash the P4: + +1. hold down the `BOOT` button on the board +2. press and release the `RST` button on the board +3. release the `BOOT` button + +You can now flash the firmware (and monitor the console output): + +```sh +idf.py -p flash monitor +``` + +To restart the P4 after flashing, press and release the `RST` button +on the board. + +
+ +## 7. References + +- ESP32-P4-Function-EV-Board: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/ +- ESP-Prog: https://docs.espressif.com/projects/esp-iot-solution/en/latest/hw-reference/ESP-Prog_guide.html +- `esp_wifi_remote` component: https://components.espressif.com/components/espressif/esp_wifi_remote/ +- `esp_hosted` component: https://components.espressif.com/components/espressif/esp_hosted/ diff --git a/docs/images/esp32-p4-esp-prog.jpg b/docs/images/esp32-p4-esp-prog.jpg new file mode 100644 index 0000000000..bffe26129c Binary files /dev/null and b/docs/images/esp32-p4-esp-prog.jpg differ diff --git a/docs/images/esp32-p4-function-ev-board-esp-prog.jpg b/docs/images/esp32-p4-function-ev-board-esp-prog.jpg new file mode 100644 index 0000000000..5c2b93bc96 Binary files /dev/null and b/docs/images/esp32-p4-function-ev-board-esp-prog.jpg differ diff --git a/docs/images/esp32-p4-function-ev-board.jpg b/docs/images/esp32-p4-function-ev-board.jpg new file mode 100644 index 0000000000..46fb92ef4d Binary files /dev/null and b/docs/images/esp32-p4-function-ev-board.jpg differ diff --git a/docs/images/hosted_diagram-ditaa.svg b/docs/images/hosted_diagram-ditaa.svg new file mode 100644 index 0000000000..cdb43767ab --- /dev/null +++ b/docs/images/hosted_diagram-ditaa.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ESP (Hosted Slave) + ESP Firmware + ESP HCI Driver + Standard ESP IDF + components + TCP/IP Stack + Host MCU/MPU + SPI/SDIO/UART + Application + ESP Host Driver + ESP Hosted + components + Bluetooth Stack + 3rd Party + components + ESP Wifi Driver + Legend + + \ No newline at end of file diff --git a/docs/images/hosted_diagram-ditaa.txt b/docs/images/hosted_diagram-ditaa.txt new file mode 100644 index 0000000000..c8fde3c036 --- /dev/null +++ b/docs/images/hosted_diagram-ditaa.txt @@ -0,0 +1,48 @@ + /----------------------------------------\ + | | + | | + | /----------------------------------\ | + | | cEEE | | + | | Application | | + | | | | + | +----------------+-----------------+ | + | | cEEE |cEEE | | + | | TCP/IP Stack |Bluetooth Stack | | + | | | | | + | +----------------+-----------------+ | + | | | | + | | cAFF ESP Host Driver | | + | | | | + | \----------------------------------/ | + | | + | Host MCU/MPU | + | | + \----------------------------------------/ + ^ + | + |SPI/SDIO/UART + | + v + /----------------------------------------\ + | | + | ESP (Hosted Slave) | + | | + | /----------------------------------\ | + | | | | + | | cAFF ESP Firmware | | + | | | | + | +-----------------+----------------+ | + | |cBLU |cBLU | | + | |ESP Wifi Driver |ESP HCI Driver | | + | | | | | + | \-----------------+----------------/ | + | | + | | + \----------------------------------------/ + +---------------------------------------------------------- +Legend + +/----\ /----\ /----\ +|cEEE|3rd Party |cAFF|ESP Hosted |cBLU| Standard ESP IDF +\----/ components \----/components \----/ components diff --git a/docs/images/hosted_wifi_call.svg b/docs/images/hosted_wifi_call.svg new file mode 100644 index 0000000000..11b54e3b1f --- /dev/null +++ b/docs/images/hosted_wifi_call.svg @@ -0,0 +1 @@ +Host with ESP-HostedSlave ESP-HostedApplicationApplicationWi-Fi RemoteWi-Fi RemoteESP HostedESP HostedHost TransportHost TransportSlave TransportSlave TransportSlave HostedSlave HostedESP-IDF Wi-Fi LibraryESP-IDF Wi-Fi LibraryWi-Fi HardwareWi-Fi Hardwareesp_wifi_xxx()esp_wifi_remote_xxx()SPI/SDIOesp_wifi_xxx()Wi-Fi actionresponsereturn value +data (if any)SPI/SDIOreturn value +data (if any) \ No newline at end of file diff --git a/docs/images/hosted_wifi_call.txt b/docs/images/hosted_wifi_call.txt new file mode 100644 index 0000000000..7d16b97f54 --- /dev/null +++ b/docs/images/hosted_wifi_call.txt @@ -0,0 +1,49 @@ +@startuml + +skinparam BoxPadding 20 + +box "Host with ESP-Hosted" #LightBlue +participant Application as app +participant "Wi-Fi Remote" as remote +participant "ESP Hosted" as hostedh +participant "Host Transport" as transporth +end box + +box "Slave ESP-Hosted" #LightGrey +participant "Slave Transport" as transports +participant "Slave Hosted" as hosteds +participant "ESP-IDF Wi-Fi Library" as api +participant "Wi-Fi Hardware" as wifi +end box + +skinparam ArrowThickness 1 + +app -> remote : esp_wifi_xxx() +remote -> hostedh : esp_wifi_remote_xxx() +hostedh -> transporth + +skinparam ArrowThickness 5 + +transporth -> transports : SPI/SDIO + +skinparam ArrowThickness 1 + +transports -> hosteds +hosteds -> api : esp_wifi_xxx() +api -> wifi +wifi -> wifi : Wi-Fi action +wifi --> api : response +api --> hosteds : return value +\ndata (if any) +hosteds --> transports + +skinparam ArrowThickness 5 + +transports --> transporth : SPI/SDIO + +skinparam ArrowThickness 1 + +transporth --> hostedh +hostedh --> remote +remote --> app : return value +\ndata (if any) + +@enduml diff --git a/docs/images/native_wifi_call.svg b/docs/images/native_wifi_call.svg new file mode 100644 index 0000000000..acbfb8df1f --- /dev/null +++ b/docs/images/native_wifi_call.svg @@ -0,0 +1 @@ +ApplicationApplicationESP-IDF Wi-Fi LibraryESP-IDF Wi-Fi LibraryWi-Fi HardwareWi-Fi Hardwareesp_wifi_xxx()Wi-Fi actionresponsereturn value +data (if any) \ No newline at end of file diff --git a/docs/images/native_wifi_call.txt b/docs/images/native_wifi_call.txt new file mode 100644 index 0000000000..86cdcf51f7 --- /dev/null +++ b/docs/images/native_wifi_call.txt @@ -0,0 +1,13 @@ +@startuml + +participant Application as app +participant "ESP-IDF Wi-Fi Library" as api +participant "Wi-Fi Hardware" as wifi + +app -> api : esp_wifi_xxx() +api -> wifi +wifi -> wifi : Wi-Fi action +wifi --> api : response +api --> app : return value +\ndata (if any) + +@enduml diff --git a/docs/sdio.md b/docs/sdio.md new file mode 100644 index 0000000000..7224a2a9ec --- /dev/null +++ b/docs/sdio.md @@ -0,0 +1,153 @@ +# ESP-Hosted SDIO Operation + +**Table of Contents** + +- [1. Introduction](#1-introduction) +- [2. SDIO Configuration](#2-sdio-configuration) + - [2.1. Extra GPIO Signals Required](#21-extra-gpio-signals-required) +- [3. Hardware Considerations](#3-hardware-considerations) + - [3.1. Pull-up Resistors](#31-pull-up-resistors) + - [3.2 PBC Traces](#32-pbc-traces) + - [3.3. Conflicts between SDIO and ESP hardware.](#33-conflicts-between-sdio-and-esp-hardware) + - [3.4. Testing the SDIO Connection](#34-testing-the-sdio-connection) + - [3.5. Summary of SDIO Hardware Requirements](#35-summary-of-sdio-hardware-requirements) + - [4. References](#4-references) + +## 1. Introduction + +SDIO is a high-speed bus. It uses the same SDMMC hardware protocol +used for SD Cards, but with its own set of commands for communicating +with SDIO aware peripherals. + +> [!NOTE] +> Only some ESP32 chips support the SDIO Protocol: +> +> - SDIO as Slave: ESP32-C6 +> - SDIO as Master: ESP32, ESP32-S3, ESP32-P4 + +## 2. SDIO Configuration + +For the ESP32 and ESP32-C6, the pin assignments for SDIO are fixed: + +| Signal | ESP32 GPIO | ESP32-C6 GPIO | +| :---- | :---: | :---: | +| CLK | 14 | 19 | +| CMD | 15 | 18 | +| DAT0 | 2 | 20 | +| DAT1 | 4 | 21 | +| DAT2 | 12 | 22 | +| DAT3 | 13 | 23 | + +For the ESP32-S3 and ESP32-P4, any GPIO pin can be configured for use +in SDIO. + +> [!NOTE] +> Check the ESP chip documentation for GPIO limitations that may +> prevent some GPIOs from being used for SDIO. + +To enable SDIO on the Host and Slave using `Menuconfig`: + +1. On Host: **Component config** ---> **ESP-Hosted config** ---> + **Transport layer** and choose **SDIO**. +2. On Slave: **Example configuration** ---> **Transport layer** and + choose **SDIO**. + +### 2.1. Extra GPIO Signals Required + +Extra GPIO signal are required for SDIO on Hosted. These can be +assigned to any free GPIO pins: + +- `Reset` signal: an output signal from the host to the slave. When + asserted, the host resets the slave. This is done when ESP-Hosted is + started on the host, to synchronise the state of the host and slave. + +> [!NOTE] +> The `Reset` signal can be configured to connect to the `EN` or `RST` +> pin on the slave, or assigned to a GPIO pin on the slave. +> +> To configure this, use `Menuconfig` on the Slave: **Example +> configuration** ---> **SDIO Configuration** and set **Slave GPIO pin +> to reset itself**. + +## 3. Hardware Considerations + +SDIO has several hardware requirements that must be met for proper +operation. + +### 3.1. Pull-up Resistors + +SDIO requires external pull-up resistor (51 kOhm recommended) and +clean signals for proper operation. For this reason, it is not +recommended to use jumper cables. Use PCB traces to connect between a +Hosted Master and Slave. + +### 3.2 PBC Traces + +The PCB traces for SDIO should be equal length and kept as short as +possible. The SDIO signals, especially the `CLK` signal, should be +isolated from other signals using a ground plane to minimise +crosstalk. + +If you must test SDIO using jumper cables, and you provide pull-up +resistors to the SDIO lines, you may be able to get SDIO working by +using a lower frequency and operating in 1-Bit SDIO mode. See +[3.4. Testing the SDIO Connection](#34-testing-the-sdio-connection) +for more information. + +### 3.3. Conflicts between SDIO and ESP hardware. + +SDIO requires pull-ups on signal lines which may conflict with the +pull state of hardware pins required for bootstrapping. For example +there is a conflict between the SDIO `DAT2` line and bootstrap +requirement for the EPS32 with the 3.3 V flash chip. This can be fixed +by burning the flash voltage selection eFuses. + +> [!WARNING] +> eFuse burning is irreversible and may cause your hardware to stop +> functioning. Check the documentation in +> [4. References](#4-references) carefully to make sure that burning +> the eFuses is the correct option. + +### 3.4. Testing the SDIO Connection + +**Using a Lower Clock Speed** + +You can use a lower clock speed to verify the connections. Start with +a clock speed between 400 kHz to 20 MHz. + +To configure this, use `Menuconfig` on the Host: **Component +config** ---> **ESP-Hosted config** ---> **Hosted SDIO Configuration** +and set **SDIO Clock Freq (in kHz)**. + +> [!NOTE] +> The actual clock frequency used is determined by the hardware. Use +> an oscilloscope or logic analyser to check the clock frequency. + +**3.4.2. Using 1-bit SDIO Mode** + +You can set the SDIO Bus Width to 1-Bit. In 1-Bit mode, only `DAT0` +and `DAT1` signals are used for data and are less affected by noise on +the signal lines. This can help you verify that the SDIO protocol is +working at the logical level, if you have issues getting 4-Bit SDIO to +work on your prototype board. + +To configure this, use `Menuconfig` on the Host: **Component config** +---> **ESP-Hosted config** ---> **Hosted SDIO Configuration** ---> +**SDIO Bus Width** to **1 Bit**. + +> [!NOTE] +> Pull-ups are still required on `DAT2` and `DAT3` lines to prevent +> the SDIO slave from going into SPI mode upon startup. + +### 3.5. Summary of SDIO Hardware Requirements + +> [!IMPORTANT] +> - using jumper cables is not recommended +> - external pull-up are required. 10 kOhm resistors are recommended +> - check for conflicts between SDIO pull-up and GPIO requirements +> - for ESP32, check if eFuse burning is required + +### 4. References + +- ESP-IDF SD Pull-up Requirements: +https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sd_pullup_requirements.html diff --git a/docs/spi_full_duplex.md b/docs/spi_full_duplex.md new file mode 100644 index 0000000000..55bf86c964 --- /dev/null +++ b/docs/spi_full_duplex.md @@ -0,0 +1,119 @@ +# ESP-Hosted SPI HD (Full Duplex) Operation + +**Table of Contents** + +- [1. Introduction](#1-introduction) +- [2. SPI FD Configuration](#2-spi-fd-configuration) + - [2.1. Clock and Phase](#21-clock-and-phase) + - [2.2. GPIO configuration for SPI FD](#22-gpio-configuration-for-spi-fd) + - [2.3. Extra GPIO Signals Required](#23-extra-gpio-signals-required) +- [3. Hardware Considerations](#3-hardware-considerations) + - [3.1. Jumper Wires](#31-jumper-wires) + - [3.2 PCB Design](#32-pcb-design) + - [3.3 Testing the SPI Connection](#33-testing-the-spi-connection) + - [4. References](#4-references) + +## 1. Introduction + +The ESP32 family of chips support the standard SPI FD (Full Duplex) +Mode Protocol. + +In this mode of operation, SPI uses 2 data lines to transfer data to +the slave and from the slave at the same time (full duplex) during an +SPI transaction. + +## 2. SPI FD Configuration + +To enable SPI FD on the Host and Slave using `Menuconfig`: + +1. On Host: **Component config** ---> **ESP-Hosted config** ---> + **Transport layer** and choose **SPI Full-duplex**. +2. On Slave: **Example configuration** ---> **Transport layer** and + choose **SPI Full-duplex**. + +### 2.1. Clock and Phase + +> [!NOTE] +> The standard SPI CPOL clock and CPHA phase must be the same on both +> the host and slave for the protocol to work. + +### 2.2. GPIO configuration for SPI FD + +The SPI interface can use almost any GPIO pins. For maximum speed and +minimal delays, it is recommended to select the SPI pin configuration +that uses the dedicated `IO_MUX` pins. See +[4. References](#4-references) for more information. + +This table summarises the recommended SPI GPIO pins for various ESP SoCs: + +| GPIO | ESP32 | ESP32-C2/C3/C6 | ESP32-S2/S3 | +| :--- | :--: | :--: | :--: | +| MOSI | 13 | 7 | 11 | +| MISO | 12 | 2 | 13 | +| CLK | 14 | 6 | 12 | +| CS | 15 | 10 | 10 | + +> [!NOTE] +> Check the ESP chip documentation for GPIO limitations that may +> prevent some GPIOs from being used for SPI. + +### 2.3. Extra GPIO Signals Required + +Extra GPIO signal are required for SPI FD on Hosted and can be +assigned to any free GPIO pins: + +- `Handshake` signal: an output signal from the slave to the + host. When asserted, it acts like the UART CTS (Clear to Send), + telling the host that the slave is ready for a SPI transaction. The + host should not perform a SPI transaction if the `Handshake` signal + is deasserted. +- `Data Ready` signal: an output signal from the slave to the + host. When asserted, the slave is telling the host that it has data + to send. The host should perform a SPI transaction to fetch the data + from the slave. +- `Reset` signal: an output signal from the host to the slave. When + asserted, the host resets the slave. This is done when ESP-Hosted is + started on the host, to synchronise the state of the host and slave. + +> [!NOTE] +> The `Reset` signal can be configured to connect to the `EN` or `RST` +> pin on the slave, or assigned to a GPIO pin on the slave. +> +> To configure this, use `Menuconfig` on the Slave: **Example +> configuration** ---> **SPI FUll-duplex Configuration** ---> **Host +> SPI GPIOs** and set **Slave GPIO pin to reset itself**. + + +## 3. Hardware Considerations + +### 3.1. Jumper Wires + +While jumper wires can be used to test SPI, it is recommended to use +short wires (5 to 10 cm in length, shorter is better) to +minimise propagation delay and noise on the signals. + +### 3.2 PCB Design + +The PCB traces for SPI should be equal length and kept as short as +possible. The signals, especially the `CLK` signal, should be isolated +from other signals using a ground plane to minimise crosstalk. + +### 3.3 Testing the SPI Connection + +**Using a Lower Clock Speed** + +You can use a lower clock speed to verify the connections. For SPI, +you can start with 10 MHz or lower. + +To configure this, use `Menuconfig` on the Host: **Component +config** ---> **ESP-Hosted config** ---> **SPI Configuration** +and set **SPI Clock Freq (MHz)**. + +> [!NOTE] +> The actual clock frequency used is determined by the hardware. Use +> an oscilloscope to check the clock frequency. + +### 4. References + +- GPIO Matrix and IO_MUX considerations for SPI Master: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html#gpio-matrix-and-io-mux +- GPIO Matrix and IO_MUX considerations for SPI Slave: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_slave.html#gpio-matrix-and-io-mux diff --git a/docs/spi_half_duplex.md b/docs/spi_half_duplex.md index 598e686513..d7aa029085 100644 --- a/docs/spi_half_duplex.md +++ b/docs/spi_half_duplex.md @@ -1,4 +1,31 @@ -# ESP Hosted SPI HD (Half Duplex) Operation +# ESP-Hosted SPI HD (Half Duplex) Operation + +**Table of Contents** + +- [1. Introduction](#1-introduction) +- [2. SPI HD Configuration](#2-spi-hd-configuration) + - [2.1. Clock and Phase](#21-clock-and-phase) + - [2.2. Number of Data Lines](#22-number-of-data-lines) + - [2.3. Extra GPIO Signal Required](#23-extra-gpio-signal-required) + - [2.4. Recommended Pin Assignments](#24-recommended-pin-assignments) +- [3. SPI HD protocol used by Hosted](#3-spi-hd-protocol-used-by-hosted) + - [3.1. Data IO Modes](#31-data-io-modes) + - [3.2. Supported Commands](#32-supported-commands) + - [3.2.1 Command Mask](#321-command-mask) + - [3.3. Registers Used](#33-registers-used) + - [3.4. Timing Diagrams](#34-timing-diagrams) +- [4. SPI HD Operation in Hosted](#4-spi-hd-operation-in-hosted) + - [4.1 Transport Initialization](#41-transport-initialization) + - [4.1.1. Slave and Host Initialization](#411-slave-and-host-initialization) + - [4.1.2. Number of Data Lines Used](#412-number-of-data-lines-used) + - [4.2. Slave Transfers Data to Host](#42-slave-transfers-data-to-host) + - [4.3. Host Transfers Data to the Slave](#43-host-transfers-data-to-the-slave) + - [4.4. Code Reference](#44-code-reference) +- [5. Hardware Considerations](#5-hardware-considerations) + - [5.1. Jumper Wires](#51-jumper-wires) + - [5.2 PCB Design](#52-pcb-design) + - [5.3 Testing the SPI Connection](#53-testing-the-spi-connection) +- [6. References](#6-references) ## 1. Introduction @@ -9,11 +36,27 @@ In this mode of operation, SPI supports 2 to 4 data lines to transfer data to the slave or from the slave (half duplex) during an SPI transaction. This is different from 'standard' SPI mode which transfers data bidirectionally (full duplex) over two data lines (one -for host to slave data, one for slave to host data) during an SPI +for host to slave data [MOSI], one for slave to host data [MISO]) during an SPI transaction. +> [!NOTE] +> SPI Half Duplex mode is not supported on the ESP32 + +> [!IMPORTANT] +> SPI Half Duplex is not an industry standard and has multiple +> implementations. Make sure your host processor supports the SPI HD +> protocol implemented by the Hosted slave before proceeding. See [SPI +> HD protocol used by Hosted](#3-spi-hd-protocol-used-by-hosted). + ## 2. SPI HD Configuration +To enable SPI HD on the Host and Slave using `Menuconfig`: + +1. On Host: **Component config** ---> **ESP-Hosted config** ---> + **Transport layer** and choose **SPI Half-duplex**. +2. On Slave: **Example configuration** ---> **Transport layer** and + choose **SPI Half-duplex**. + ### 2.1. Clock and Phase The standard SPI CPOL clock and CPHA phase must be configured @@ -29,16 +72,31 @@ four data lines. ### 2.3. Extra GPIO Signal Required -An extra GPIO signal (`Data_Ready`) is required from slave (output) to -host (input). This is used by the slave to signal to the host that it -has data to transfer to the host. +Extra GPIO signal are required for SPI HD on Hosted and can be +assigned to any free GPIO pins: + +- `Data_Ready` signal: an output signal from the slave to the + host. When asserted, the slave is telling the host that it has data + to send. The host should perform a data read SPI transaction to + fetch data from the slave. +- `Reset` signal: an output signal from the host to the slave. When + asserted, the host resets the slave. This is done when ESP-Hosted is + started on the host, to synchronise the state of the host and slave. + +> [!NOTE] +> The `Reset` signal can be configured to connect to the `EN` or `RST` +> pin on the slave, or assigned to a GPIO pin on the slave. +> +> To configure this, use `Menuconfig` on the Slave: **Example +> configuration** ---> **SPI Half-duplex Configuration** ---> +> **GPIOs** and set **Slave GPIO pin to reset itself**. ### 2.4. Recommended Pin Assignments -Using the pins already assigned to SPI signals (dedicated IO_MUX pins) -is recommended to minimise propagation delays. Using other GPIO pins -for SPI signals will route the signals through the GPIO matrix which -may limit the maximum clock frequency that can be used. +Using the pins already assigned to SPI signals (dedicated `IO_MUX` +pins) is recommended to minimise propagation delays. Using other GPIO +pins for SPI signals will route the signals through the GPIO matrix +which may limit the maximum clock frequency that can be used. The following table shows the mapping between the SPI bus signals and their SPI HD Function: @@ -57,7 +115,7 @@ slave. ## 3. SPI HD protocol used by Hosted Hosted uses the ESP SPI Slave HD (Half Duplex) Mode Protocol (see -References) with some modifications. +[References](#6-references)) with some modifications. ### 3.1. Data IO Modes @@ -65,14 +123,20 @@ When communicating with the slave, the master uses the Command, Address, Dummy and Data phases during an SPI transaction. The number of bits and number of data lines used in each phase are: -- Command: 8 bits, 1 data line -- Address: 8 bits, 2 or 4 data lines -- Dummy: 8 bits, 1 data line -- Data: variable length, 2 or 4 data lines +- **Command**: 8 bits, 1 data line +- **Address**: 8 bits, 2 or 4 data lines +- **Dummy**: 8 bits, 1 data line +- **Data**: variable length, 2 or 4 data lines + +> [!NOTE] +> The number of data lines used in the Address and Data phase depends +> on the Command Mask in the Command sent by the host. See [Command +> Mask](#321-command-mask). ### 3.2. Supported Commands -Hosted uses the following commands when communicating with the slave: +Hosted uses the following SPI HD commands when communicating with the +slave: | Command | OpCode | Purpose | | :--- | :--- | :--- | @@ -88,14 +152,28 @@ Hosted uses the following commands when communicating with the slave: The Commands are masked with a command mask to tell the slave the correct number of data lines to use during the transaction (2 or 4 -data lines). Hosted uses the following masks, which are ORed with the -command during a SPI transactions: +data lines). Hosted uses the following masks, which are bit ORed with +the command during a SPI transactions: | Mode | Mask | | :--- | :--- | | 2-bits | 0x50 | | 4-bits | 0xA0 | +For example, if the host sends command `0x51` (2-bit mask + WRBUF), +the host and slave will use 2 data lines to send the address and +data. If the host sends command `0xA1` (4-bit mask + WRBUF), the host +and slave will use 4 data lines to send the address and data. + +The Command Mask determines the number of data lines used for the +transaction. Even if there are four data lines between the host and +slave, the host can tell the slave to use only two data lines by +applying the 0x50 command mask. + +> [!WARNING] +> It is an error to apply the 4-bit data mask (0xA0) when there are +> only two data lines connecting the host and slave. + ### 3.3. Registers Used The ESP SPI Slave HD Mode Protocol defines a number of registers on @@ -143,24 +221,53 @@ opens the data path to the slave. Both host and slave are now ready to communicate. -The first packet the slave transfers to the host is a capabilities -packet, stating what the slave is capable of supporting: +The first packet the slave transfers to the host is a Capabilities +Packet, stating what the slave is capable of supporting: + - WLAN, Bluetooth, etc. - the number of data lines supported for SPI HD The host uses this packet to determine what the slave is capable of supporting. -![SPI HD Initialization Sequence](images/spi_hd_sequence_init.svg) +```mermaid +sequenceDiagram + participant h as Host + participant s as Slave + + note over s,h : Init + + loop Executed periodically + h ->> s : Read SLAVE_READY reg + s -->> h : Not Ready (!0xEE) + end + + note over s : Ready: SLAVE_READY = 0xEE + h ->> s : Read SLAVE_READY reg + s -->> h : Ready (0xEE) + note over h : Enable Data_Ready interrupt + h ->> s : Set SLAVE_CONTROL reg = 1 + + note over s : Open Data Path + note over s : Prepare Capability Data + + note over s : Assert Data_Ready + h ->> s : Read Data + s -->> h : Capability + note over s : Deassert Data_Ready + + note over s,h : SPI HD Transport Ready +``` *SPI HD Initialization Sequence* #### 4.1.2. Number of Data Lines Used -After initialization, the host communicates with the slave using two -data lines. If the slave is capable of supporting four data lines, and -the host is configured to also use four data lines, then four data -lines will be used for subsequent data transfers. +After initialization, the host initially communicates with the slave +using two data lines. If the slave is capable of supporting four data +lines (from the Capabilities Packet sent by the slave), and the host +is configured to also use four data lines, then four data lines will +be used for subsequent data transfers. If neither the host or slave is capable of transferring data using four data lines, then only two data lines will be used. @@ -171,9 +278,10 @@ Slave asserts `Data_Ready` to tell the host it has data to send. Host reads the TX\_BUF\_LEN register. -**Note**: The upper 8-bits of the TX\_BUF\_LEN register are reserved, -and should be masked out to get the correct read length from the -TX\_BUF\_LEN register. +> [!NOTE] +> The upper 8-bits of the TX\_BUF\_LEN register are reserved, and +> should be masked out to get the correct read length from the +> TX\_BUF\_LEN register. The host subtracts the read length from its cached read length (initial value is zero) to discover how much more data the slave wants @@ -181,12 +289,33 @@ to transfer to the host. The host can now read the data using the RDDMA command, ending the transfer with CMD8. The host now updates its cached read length with the slave's read length. -After reading TX\_BUF\_LEN register, host should send CMD9. This tells -the slave that the host has read the register and it is safe for the -slave to update the register as required and deassert the `Data_Ready` +After reading TX\_BUF\_LEN register, host sends CMD9. This tells the +slave that the host has read the register and it is safe for the slave +to update the register (if required) and deassert the `Data_Ready` signal. -![SPI HD Read Sequence](images/spi_hd_sequence_read.svg) +```mermaid +sequenceDiagram + participant h as Host + participant s as Slave + + note over s : Prepare data to send, update TX_BUF_LEN + + note over s : Assert Data_Ready + + h ->> s : Read TX_BUF_LEN + note over h : Bytes to transfer = TX_BUF_LEN - (cached)TX_BUF_LEN + + h ->> s : Send CMD9 + note over s : Deassert Data_Ready + + h ->> s : Send RDDMA + s -->> h : Transfer Data + + h ->> s : CMD8 (at end of transfer) + + note over h : update (cached)TX_BUF_LEN +``` *SPI HD Read Sequence* @@ -200,7 +329,24 @@ should wait and re-read the register until there are enough buffers. Once there are enough buffers, the host can use WRDMA to send data, ending each buffer transfer with WR_DONE. -![SPI HD Write Sequence](images/spi_hd_sequence_write.svg) +```mermaid +sequenceDiagram + participant h as Host + participant s as Slave + + note over h : Prepare data to send + + loop Read until got buffer space + h ->> s : Read RX_BUF_LEN + note over h : available buffers = RX_BUF_LEN - (cached)RX_BUF_LEN + end + + h ->> s : Send WRDMA + h ->> s : Transfer Data + h ->> s : WR_DONE (at end of transfer) + + note over h : Update (cached)RX_BUF_LEN +``` *SPI HD Write Sequence* @@ -213,7 +359,51 @@ ending each buffer transfer with WR_DONE. - `host/port/spi_hd_wrapper.c` implements the ESP-IDF specific code used by the generic SPI HD driver on the host -## 5. References +## 5. Hardware Considerations + +### 5.1. Jumper Wires + +While jumper wires can be used to test SPI, it is recommended to use +short wires (5 to 10 cm in length, shorter is better) to +minimise propagation delay and noise on the signals. + +### 5.2 PCB Design + +The PCB traces for SPI should be equal length and kept as short as +possible. The signals, especially the `CLK` signal, should be isolated +from other signals using a ground plane to minimise crosstalk. + +### 5.3 Testing the SPI Connection + +**Using a Lower Clock Speed** + +You can use a lower clock speed to verify the connections. For SPI, +you can start with 10 MHz or lower. + +To configure this, use `Menuconfig` on the Host: **Component +config** ---> **ESP-Hosted config** ---> **SPI Half-duplex Configuration** +and set **SPI HD Clock Freq (MHz)**. + +> [!NOTE] +> The actual clock frequency used is determined by the hardware. Use +> an oscilloscope or logic analyzer to check the clock frequency. + +**3.4.2. Using Two Data Lines** + +You can configure SPI HD to use two data line only instead of +four. This will reduce noise on the signal lines and help you verify +that the SPI HD protocol is working at the logical level. + +To configure this, use `Menuconfig` on the Host: **Component +config** ---> **ESP-Hosted config** ---> **SPI Half-duplex Configuration** +and set **Num Data Lines to use** to **2 data lines**. + +You can leave the SPI HD configuration on the Hosted Slave as four +data lines, as the host determines the number of data lines to use. If +you want to change this, then on the slave use `Menuconfig`: **Example +Configuration** ---> **SPI Half-duplex Configuration** and set **Num +Data Lines to use** to **2 data lines**. + +## 6. References -- ESP SPI Slave HD (Half Duplex) Mode Protocol: - [https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_spi_slave_protocol.html](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_spi_slave_protocol.html) +- ESP SPI Slave HD (Half Duplex) Mode Protocol: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_spi_slave_protocol.html diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000000..0e1c0454b9 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,122 @@ +# Troubleshooting ESP-Hosted + +**Table of Contents** + +- [1. Raw Throughput Testing Option](#1-raw-throughput-testing-option) +- [2. Make sure Hosted code is in sync for Master and Slave](#2-make-sure-hosted-code-is-in-sync-for-master-and-slave) +- [3. Make sure GPIOs match on both the Host and Slave](#3-make-sure-gpios-match-on-both-the-host-and-slave) +- [4. ESP-Hosted Master Not Connecting to Slave](#4-esp-hosted-master-not-connecting-to-slave) +- [5. Getting `Drop Packet` Errors](#5-getting-drop-packet-errors) +- [6. References](#6-references) + +## 1. Raw Throughput Testing Option + +ESP-Hosted has a Raw Throughput Option to test sending of data between +the Host and Slave. This can be used to verify the hardware for signal +errors and to check the achievable throughput of Hosted. + +> [!IMPORTANT] +> Use this option to verify that Hosted hardware and software are +> working as expected before involving other software layers like +> networking. + +To enable the Raw Throughput Option on Slave, enter `Menuconfig` and +enable **Example Configuration** ---> **Hosted Debugging** ---> +**RawTP**. + +To enable the Raw Throughput Option and set Raw Throughput direction +on Host, enter `Menuconfig` and enable **Component config** ---> +**ESP-Hosted config** ---> **Debug Settings** ---> **RawTP**. Set +the data transfer direction: **Host to Slave**, **Slave to Host** or +**Bidirectional**. + +## 2. Make sure Hosted code is in sync for Master and Slave + +The [README](../README.md) instructions will always fetch the latest +version of ESP-Hosted from the Component Registry. Generally, this +should be fine. But you can also fetch ESP-Hosted code based on a +revision to get a fixed version of the code: + +For example, to fetch version 0.0.9 of ESP-Hosted Master: + +``` +idf.py add-dependency "espressif/esp_hosted^0.0.9" +``` + +To fetch version 0.0.9 of the ESP-Hosted Slave: + +``` +idf.py create-project-from-example "espressif/esp_hosted^0.0.9:slave" +``` + +This will ensure that both the Master and Slave code are fixed and in +sync for your project. + +> ![NOTE] +> When you switch Hosted versions, make sure you use the same version +> of the Master and Slave code. There may be changes to the Hosted +> implementation that may make different versions of Hosted Master and +> Slave incompatible. + +## 3. Make sure GPIOs match on both the Host and Slave + +- check that the GPIOs you use on the Host and Slave are correct and + are connected together as expected +- verify that the GPIO values you set in `menuconfig` match the + hardware GPIOs you are actually using +- make sure you are not using incompatible GPIOs: + - on the ESP32, some GPIOs are input only and cannot be used for + output + - on the ESP32 and ESP32-C6, the GPIOs used for SDIO are fixed and + cannot be changed + +## 4. ESP-Hosted Master Not Connecting to Slave + +If you see the following error on the ESP-Hosted Master console using the SPI Interface: + +``` +E (10645) transport: Not able to connect with ESP-Hosted slave device +``` + +or this error on the ESP-Hosted Master console using the SDIO Interface: + +``` +E (1735) sdmmc_common: sdmmc_init_ocr: send_op_cond (1) returned 0x107 +``` + +It means that something is wrong with the SPI or SDIO connection and +the Host cannot communicate with the slave. + +- check your physical GPIO signals and verify that they are connected +- make sure you have selected the same transports for the slave and + host (both are using the same SPI or SDIO interface) +- verify that the physical GPIO signals is the same as those assigned + to the system using `Menuconfig` on both the Host and Slave +- if you selected SDIO as the interface and your host is a ESP32, + there may be conflict with the GPIO used to bootstrap the ESP32 and + used in SDIO. See "Conflicts Between Bootstrap and SDIO on DAT2" in + [References](#6-references) for more information +- for SDIO, verify that pull-ups and other signalling requirments + (short, shielded connections) are also met. See the [SDIO + interface](sdio.md) page for more information on SDIO requirements + +## 5. Getting `Drop Packet` Errors + +For the SPI interface, if you see an error similar to this: + +``` +I (478522) spi: rcvd_crc[30224] != exp_crc[36043], drop pkt +``` + +Your SPI interface is facing signal integrity errors. + +- try reducing the SPI `CLK` frequency (using `Menuconfig`). If the + problem goes away, it indicates that there is an issue with the + physcial SPI signals +- use an oscilloscope to check the physical signals on the SPI + interface for noise, ringing, etc. that may affect the signals + +## 6. References + +- Conflicts Between Bootstrap and SDIO on DAT2: + https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sd_pullup_requirements.html#conflicts-between-bootstrap-and-sdio-on-dat2)