diff --git a/esp_hosted_fg/README.md b/esp_hosted_fg/README.md index 677882f9cd..793df37668 100644 --- a/esp_hosted_fg/README.md +++ b/esp_hosted_fg/README.md @@ -104,7 +104,7 @@ The below table explains which feature is supported on which transport interface | ESP device | Transport Interface | WLAN support | Virtual serial interface | Bluetooth support | |:------------:|:-------:|:---------:|:--------:|:--------:| -| ESP32 | SDIO | No | No | No | +| ESP32 | SDIO | Yes | Yes | BT/BLE 4.2\* | | ESP32 | SPI | Yes | Yes | BT/BLE 4.2\* | | ESP32 | UART | No | No | BT/BLE 4.2\*\* | | ESP32-S2 | SDIO | NA | NA | NA | diff --git a/esp_hosted_fg/common/include/adapter.h b/esp_hosted_fg/common/include/adapter.h index b208610b06..7d719055ca 100644 --- a/esp_hosted_fg/common/include/adapter.h +++ b/esp_hosted_fg/common/include/adapter.h @@ -53,6 +53,7 @@ typedef enum { ESP_OPEN_DATA_PATH, ESP_CLOSE_DATA_PATH, ESP_RESET, + ESP_MAX_HOST_INTERRUPT, } ESP_HOST_INTERRUPT; diff --git a/esp_hosted_fg/docs/MCU_based_host/Getting_started.md b/esp_hosted_fg/docs/MCU_based_host/Getting_started.md index 30c581bbb3..c21766acfe 100644 --- a/esp_hosted_fg/docs/MCU_based_host/Getting_started.md +++ b/esp_hosted_fg/docs/MCU_based_host/Getting_started.md @@ -1,6 +1,6 @@ -# Getting started with STM32F469I(MCU based Host) +# Getting started with MCU based Host -This section elaborates about setting up the control path, Wi-Fi connectivity and Bluetooth/BLE connectivity. Before proceeding, ensure pre-requisites [Hardware Setup and Compilation](MCU_based_readme.md#2-wi-fi-connectivity-setup-over-spi) are done. +This section elaborates about setting up the control path, Wi-Fi connectivity and Bluetooth/BLE connectivity. Before proceeding, ensure pre-requisites [Hardware Setup and Compilation](MCU_based_readme.md#2-setup) are done. ## 1. Control Path @@ -33,26 +33,41 @@ Host firmware provides Wi-Fi connectivity using control path and data path. Cont ### 2.1 Start Project with STM32 -We have tested project with STM32F469I-Discovery board. If other than STM32F469I-Discovery board is used, peripheral like SPI, USART need to change as per board needs. STM32CubeIDE would be needed to follow next steps. +#### 2.1.1 Supported Hardware +We have tested project for `SPI` transport with STM32F469I-Discovery board and `SDIO` transport with STM32F412ZGT6-Nucleo 144 board. If other than STM32F469I-Discovery board and STM32F412ZGT6-Nucleo 144 board are used, peripheral like SDIO, SPI, USART need to change as per board needs. + +| ESP32 Board | STM32 Board | Transport | +|:---------:|:------:|:----------:| +| ESP32 | STM32F412ZGT6-Nucleo 144 | SDIO | +| ESP32/S2/S3/C2/C3 | STM32F469I-Discovery | SPI | + +:warning: **Note1:** For SDIO, please check [pull up requirements](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sd_pullup_requirements.html) while choosing ESP module + +#### 2.1.2 STM32CubeIDE would be needed to follow next steps. * Create a workspace_directory outside of `ESP-Hosted` git cloned directory. * Browse and Open Workspace directory in STM32CubeIDE. It will take few seconds to open STM32CubeIDE. -* From `Information Center` tab select `Start new project` from existing STM32CubeMX configuration file, i.e. ioc file option. It will take few seconds to open dialog box. In STM32CubeMX .ioc file field, choose appropriate .ioc file from `/esp_hosted_fg/host/stm32/proj/` directory. +* From `Information Center` tab select `Start new project` from existing STM32CubeMX configuration file, i.e. ioc file option. It will take few seconds to open dialog box. In STM32CubeMX .ioc file field, choose appropriate .ioc file from `/esp_hosted_fg/host/stm32/proj/` directory. +* For SPI transport: ``` For ESP32 peripheral: Select stm_spi_host_v1.ioc file For ESP32-C2/ESP32-C3/ESP32-S2/ESP32-S3 peripheral: Select stm_spi_host_v2.ioc file ``` +* For SDIO transport: +``` +For ESP32 peripheral: Select stm_sdio_host.ioc file +``` * Once file is selected, click `Open` and `Finish`. New dialog box will open as Open Associated Perspective, click on `Yes`. It may take 2-3 minutes to open. * Close ioc tab then close STM32CubeIDE and click on `exit`. * For Linux and Mac development hosts, In terminal, run ``` $ cd /esp_hosted_fg/host/stm32/proj -$ bash ./prepare_project.sh +$ bash ./prepare_project.sh ``` For Windows based systems, open "cmd.exe" or Windows Power Shell and run - ``` > cd \esp_hosted_fg\host\stm32\proj -> prepare_project.bat +> prepare_project.bat ``` This will copy the project configuration files into workspace_directory @@ -67,7 +82,7 @@ $ minicom -D /dev/ttyACM0 ``` Note: /dev/ttyACM0 is used for For Linux, /dev/cu.usbmodemXXXXXX for Mac and COM port for Windows development host. Baud rate used is 115200. Parity bits configuration is 8N1. -* In STM32CubeIDE, go to `Project Explorer`, right click on `stm_spi_host` project. Then `menu -> Run -> Run as -> STM32 Cortex-M C/C++ Application `. This will open Edit Configuration box, Click `OK`. +* In STM32CubeIDE, go to `Project Explorer`, right click on `stm__host` project. Then `menu -> Run -> Run as -> STM32 Cortex-M C/C++ Application `. This will open Edit Configuration box, Click `OK`. `Debug as` option can also be alternatively used if debugging is desired. Expected output on `Console` tab in STM32CubeIDE as follows: @@ -138,7 +153,7 @@ started ESPWifi softAP ### 2.2 User configuration parameter -Host firmware has basic user configuration parameters. User needs to manually configure these values. Click on `stm_spi_host` under `Project Explorer` tab. Then `menu -> Project -> Properties -> C/C++ Build -> Build Variables -> < select variable> -> Edit -> OK -> Apply`. +Host firmware has basic user configuration parameters. User needs to manually configure these values. Click on `stm__host` under `Project Explorer` tab. Then `menu -> Project -> Properties -> C/C++ Build -> Build Variables -> < select variable> -> Edit -> OK -> Apply`. Build Variables are as follows: @@ -206,6 +221,10 @@ ARP response is triggered for requests received. You should be able see ARP resp XX bytes from 3c:71:bf:9a:bc:b8 (192.168.1.233): index=0 time=199.144 msec ``` +## 2.4 RAW throughput Testing : + +For raw throughput please check [Raw_TP_Testing.md](./Raw_TP_Testing.md) + ## 3. BT/BLE connectivity Bluetooth and BLE handling could be easily ported. Porting details could be found at [ 1.5.2 MCU Host](../../README.md#152-mcu-host) on [README.md](../../README.md) diff --git a/esp_hosted_fg/docs/MCU_based_host/MCU_based_architecture.md b/esp_hosted_fg/docs/MCU_based_host/MCU_based_architecture.md index f7cf59f080..2b587d1d24 100644 --- a/esp_hosted_fg/docs/MCU_based_host/MCU_based_architecture.md +++ b/esp_hosted_fg/docs/MCU_based_host/MCU_based_architecture.md @@ -7,11 +7,13 @@ Following diagram depicts building blocks of MCU based ESP-Hosted solution. ## 1. ESP Host Software The host software mainly consists of following building blocks. -### 1.1 SPI Host Driver +### 1.1 SPI/SDIO Host Driver -* ESP-Hosted solution provides thin SPI host interface layer which transmits/receives data from SPI hardware driver and makes it available to serial or network interface +* ESP-Hosted solution provides thin SPI/SDIO host interface layer which transmits/receives data from SPI/SDIO hardware driver and makes it available to serial or network interface * Asynchrounous in nature, higher layers have flexibility to transmit and/or receive data as needed -* Currently, Maximum 1600 bytes of data can be trasmitted in single transmit or receive transaction +* Currently, Maximum bytes of data trasmitted in single transmit or receive transaction is as follows: + * SPI - 1600 bytes + * SDIO - 4096 bytes --- @@ -35,15 +37,15 @@ The host software mainly consists of following building blocks. ### 1.4 Network interface layer [netif] -* This is an abstraction layer between SPI host driver and a network stack. +* This is an abstraction layer between SDIO/SPI host driver and a network stack. * This gives flexibility of using any network stack with ESP-Hosted solution. -* This interface layer defines set of APIs and data structure that network stack must implement in order to make it work with SPI host driver. +* This interface layer defines set of APIs and data structure that network stack must implement in order to make it work with SDIO/SPI host driver. --- ### 1.5 Network stack stub -* This is a simple network stack stub which demonstrates how a network stack can implement network interface layer and work with SPI host driver. +* This is a simple network stack stub which demonstrates how a network stack can implement network interface layer and work with SDIO/SPI host driver. * This does not represent actual network stack. This should be used as a reference for developing network interface layer [netif] provided by ESP-Hosted solution --- diff --git a/esp_hosted_fg/docs/MCU_based_host/MCU_based_design.png b/esp_hosted_fg/docs/MCU_based_host/MCU_based_design.png index 2239b2cc66..04d57744b9 100644 Binary files a/esp_hosted_fg/docs/MCU_based_host/MCU_based_design.png and b/esp_hosted_fg/docs/MCU_based_host/MCU_based_design.png differ diff --git a/esp_hosted_fg/docs/MCU_based_host/MCU_based_readme.md b/esp_hosted_fg/docs/MCU_based_host/MCU_based_readme.md index 01681f9058..ce264264bc 100644 --- a/esp_hosted_fg/docs/MCU_based_host/MCU_based_readme.md +++ b/esp_hosted_fg/docs/MCU_based_host/MCU_based_readme.md @@ -1,4 +1,4 @@ -# Getting Started with MCU based host (STM32F469I) +# Getting Started with MCU based host - Directory structure for microprocessor based host is explained [here](directory_structure.md) - Below diagram shows hardware and software block diagram for a typical MCU based system built with ESP-Hosted. @@ -36,146 +36,21 @@ $ cd esp-hosted $ git submodule update --init --recursive ``` -# 2. Wi-Fi connectivity Setup over SPI -## 2.1 Hardware Setup/Connections -In this setup, ESP board acts as a SPI peripheral and provides Wi-Fi capabilities to host. Please connect ESP peripheral to STM32F469I board's CN12 Extension connecter with jumper cables as mentioned below. It may be good to use small length cables to ensure signal integrity. -BT/BLE support will be added in upcoming release. -Power ESP peripheral and STM32F469I separately with a power supply that provide sufficient power. ESP peripheral can be powered through PC using micro-USB cable. STM32 can be powered with mini-B cable. It is also used as USART connection for debug logs from host. Serial port communicaton program like tera term or minicom used to print the logs. +# 2. Setup +Prepare connections based on interface requirements and setup ESP peripheral as below. -#### Hardware connections for ESP32 -| STM32 Pin | ESP32 Pin | Function | -|:----------:|:---------:|:--------:| -| PB4 (pin5) | IO19 | MISO | -| PA5 (pin7) | IO18 | CLK | -| PB5 (pin9) | IO23 | MOSI | -| PA15 (pin11) | IO5 | CS | -| GND (pin2) | GND | GND | -| PC6 (pin6) | IO2 | Handshake | -| PC7 (pin8) | IO4 | Data Ready from ESP | -| PB13 (pin10) | EN | Reset ESP | +* **Wifi over SDIO on STM32F412ZGT6-Nucleo 144** + * Connection Setup + * Prepare connections as per section [1.1 Hardware Setup](SDIO_setup.md#11-hardware-setupconnections) of [SDIO setup document](SDIO_setup.md) + * ESP peripheral setup + * ESP peripheral setup as per section [2.2 ESP peripheral setup](SDIO_setup.md#22-setup) of [SDIO setup document](SDIO_setup.md) -Setup image is here. - -![alt text](stm32_esp_setup.jpg "setup of STM32F469I as host and ESP32 as peripheral") - -#### Hardware connections for ESP32-S2 -| STM32 Pin | ESP32-S2 Pin | Function | -|:---------:|:-----------:|:--------:| -| PB4 (pin5) | IO13 | MISO | -| PA5 (pin7) | IO12 | CLK | -| PB5 (pin9) | IO11 | MOSI | -| PA15 (pin11)| IO10 | CS | -| GND (pin2) | GND | GND | -| PC6 (pin6) | IO2 | Handshake | -| PC7 (pin8) | IO4 | Data ready from ESP | -| PB13 (pin10) | RST | Reset ESP | - -Setup image is here. - -![alt text](stm_esp32_s2_setup.jpg "Setup of STM32F469I as host and ESP32-S2 as peripheral") - -#### Hardware connections for ESP32-C2 -| STM32 Pin | ESP32-C2 Pin | Function | -|:---------:|:-----------:|:--------:| -| PB4 (pin5) | IO02 | MISO | -| PA5 (pin7) | IO06 | CLK | -| PB5 (pin9) | IO07 | MOSI | -| PA15 (pin11)| IO10 | CS | -| GND (pin2) | GND | GND | -| PC6 (pin6) | IO03 | Handshake | -| PC7 (pin8) | IO04 | Data ready from ESP | -| PB13 (pin10) | RST | Reset ESP | - -Setup image is here. - -![alt text](stm_esp32_c2_setup.png "Setup of STM32F469I as host and ESP32-C2 as peripheral") - -#### Hardware connections for ESP32-C3 -| STM32 Pin | ESP32-C3 Pin | Function | -|:---------:|:-----------:|:--------:| -| PB4 (pin5) | IO02 | MISO | -| PA5 (pin7) | IO06 | CLK | -| PB5 (pin9) | IO07 | MOSI | -| PA15 (pin11)| IO10 | CS | -| GND (pin2) | GND | GND | -| PC6 (pin6) | IO03 | Handshake | -| PC7 (pin8) | IO04 | Data ready from ESP | -| PB13 (pin10) | RST | Reset ESP | - -Setup image is here. - -![alt text](stm_esp32_c3_setup.jpg "Setup of STM32F469I as host and ESP32-C3 as peripheral") - -#### Hardware connections for ESP32-S3 -| STM32 Pin | ESP32-S3 Pin | Function | -|:---------:|:-----------:|:--------:| -| PB4 (pin5) | IO13 | MISO | -| PA5 (pin7) | IO12 | CLK | -| PB5 (pin9) | IO11 | MOSI | -| PA15 (pin11)| IO10 | CS | -| GND (pin2) | GND | GND | -| PC6 (pin6) | IO02 | Handshake | -| PC7 (pin8) | IO04 | Data ready from ESP | -| PB13 (pin10) | RST | Reset ESP | - -Setup image is here. - -![alt text](stm_esp32_s3_setup.jpg "Setup of STM32F469I as host and ESP32-S3 as peripheral") - -# 2. ESP peripheral setup -## 2.1 ESP-IDF requirement -:warning:`Note: ESP-IDF is needed to compile ESP-Hosted firmware source. Skip this step if you are planning to use pre-built release binaries.` - -- Clone the ESP-IDF [release/v5.0](https://github.com/espressif/esp-idf/tree/release/v5.0) and checkout to `release/v5.0` branch. -- The control path between MCU host and ESP peripheral is based on `protobuf`. For that, corresponding stack layer, `protocomm` from ESP-IDF is used. It will be already present in ESP-IDF, no extra setup required for that. - -### 2.2 Setup -#### 2.2.1 Using pre-built binary -* Download pre-built firmware binaries from [releases](https://github.com/espressif/esp-hosted/releases) -* Follow `readme.txt` from release tarball to flash the ESP binary -* :warning: Make sure that you use `Source code (zip)` in `Assets` fold with associated release for host building. -* Windows user can use ESP Flash Programming Tool to flash the pre-built binary. - -#### 2.2.2 Compilation using source - -- Note: Please use the same git commit both at ESP and Host -- Clone the ESP-IDF [release/v5.0](https://github.com/espressif/esp-idf/tree/release/v5.0) and git checkout to `release/v5.0` branch. -- [Set-up the ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/release-v5.0/esp32/get-started/index.html) -- Navigate to `esp_hosted_fg/esp/esp_driver/network_adapter` directory. - -##### Using cmake - -``` -$ idf.py fullclean -``` -:warning: Skip this step for ESP32. Run for ESP32-S2 / ESP32-C2 / ESP32-C3 -``` -$ idf.py set-target esp32s2 -``` -or -``` -$ idf.py set-target esp32c2 -``` -or -``` -$ idf.py set-target esp32c3 -``` - -Run following command and navigate to `Example Configuration -> Transport layer -> SPI interface -> select` and exit from menuconfig. Read more about [idf.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/build-system.html#using-the-build-system) here. -``` -$ idf.py menuconfig -``` - -:warning: Skip below step for ESP32-S2 / ESP32-C2 / ESP32-C3. Run for ESP32 only. - -Change SPI controller to VSPI. Please navigate to `Example Configuration → SPI Configuration` and change value of `SPI controller to use` to `3` - -To build and flash the app on ESP peripheral, run - -```sh -$ idf.py -p build flash -``` +* **Wifi over SPI on STM32F469I-Discovery** + * Connection Setup + * Prepare connections as per section [1.1 Hardware Setup](SPI_setup.md#11-hardware-setupconnections) of [SPI Setup document](SPI_setup.md) + * ESP peripheral setup + * ESP peripheral setup as per section [2.2 ESP peripheral setup](SPI_setup.md#22-setup) of [SPI setup document](SPI_setup.md) # 3. ESP-Hosted Usage Guide Following guide explains how to use ESP-Hosted soultion with MCU based platform. diff --git a/esp_hosted_fg/docs/MCU_based_host/Raw_TP_Testing.md b/esp_hosted_fg/docs/MCU_based_host/Raw_TP_Testing.md new file mode 100644 index 0000000000..747c09ef71 --- /dev/null +++ b/esp_hosted_fg/docs/MCU_based_host/Raw_TP_Testing.md @@ -0,0 +1,34 @@ +# Raw Throughput testing + +- This is the optional feature to test throughput over required transport layer (SPI or SDIO). +- When ENABLED, this will bypass Wi-Fi traffic and push the dummy data traffic on transport layer directly to check maximum throughput on the current transport. +- This feature will also help you to check if transport layer is properly configured or not. +- This requires ESP firmware to be manually flashed with below steps. + +## Steps to test Raw TP + +- On Host side: + 1. Go to `esp_hosted_fg/host/stm32/common/stats.h` + 2. Enable raw throughput tetsing feature by making `TEST_RAW_TP` value to `1`. + 3. There are two directions to test raw throughput and at a time, throughput can be tested only in one direction (simplex). + - ESP to Host : For this, make `TEST_RAW_TP__ESP_TO_HOST` value to 1 + - Host to ESP : For this, make `TEST_RAW_TP__ESP_TO_HOST` value to 0 + 4. Build and flash ESP firmware again. + +- On ESP side: + 1. Go to `esp_hosted_fg/esp/esp_driver/network_adapter/main/stats.h` + 2. Enable raw throughput tetsing feature by making `TEST_RAW_TP` value to `1`. + 3. There are two directions to test raw throughput and at a time, throughput can be tested only in one direction (simplex). + - ESP to Host : For this, make `TEST_RAW_TP__ESP_TO_HOST` value to 1 + - Host to ESP : For this, make `TEST_RAW_TP__ESP_TO_HOST` value to 0 + 4. Build and flash ESP firmware again. + +**Note** +Please revert these configurations once raw throughput testing is done + +## Raw Throughput Numbers + +| ESP32 Board | STM32 Board | Transport | TX case | RX case | +|:---------:|:------:|:----------:|:---:|:--:| +| ESP32 | STM32F412ZGT6-Nucleo 144 | SDIO | 5.22 Mbps | 5.32 Mbps | +| ESP32/ESP32S2/ESP32S3/ESP32C2/ESP32C3 | STM32F469I-Discovery | SPI | 2.88 Mbps | 2.28 Mbps | \ No newline at end of file diff --git a/esp_hosted_fg/docs/MCU_based_host/SDIO_setup.md b/esp_hosted_fg/docs/MCU_based_host/SDIO_setup.md new file mode 100644 index 0000000000..1ea3c6140b --- /dev/null +++ b/esp_hosted_fg/docs/MCU_based_host/SDIO_setup.md @@ -0,0 +1,60 @@ +# Wi-Fi connectivity Setup over SDIO +## 1. Setup +### 1.1 Hardware Setup/Connections +* In this setup, ESP board acts as a SDIO peripheral and provides Wi-Fi capabilities to host. Please connect ESP peripheral to STM32F412ZGT6-Nucleo 144 board's CN8 Extension connecter with jumper cables as mentioned below. It may be good to use small length cables to ensure signal integrity. +* Power ESP peripheral and STM32F412ZGT6-Nucleo 144 separately with a power supply that provide sufficient power. ESP peripheral and STM32 can be powered through USB-Hub using micro-USB cable. It is also used as USART connection for debug logs from host. Serial port communicaton program like tera term or minicom used to print the logs. +* BT/BLE support will be added in upcoming release. + +#### Hardware connections for ESP32 +| STM32 Pin | ESP32 Pin | Function | +|:----------:|:---------:|:--------:| +| PC8 (pin2) | IO2 | DATA0 | +| PC9 (pin4) | IO4 | DATA1 | +| PC10 (pin6) | IO12 | DATA2 | +| PC11 (pin8) | IO13 | DATA3 | +| PC12 (pin10)| IO14 | Clock | +| PD2 (pin12) | IO15 | Command | +| GND (pin13) | GND | Ground | +| PG2 (pin14) | EN | Reset ESP | + +Setup image is here. + +![alt text](stm32_esp32_sdio_setup.jpg "setup of STM32F412ZGT6-Nucleo 144 as host and ESP32 as peripheral") + +# 2. ESP peripheral setup +## 2.1 ESP-IDF requirement +:warning:`Note: ESP-IDF is needed to compile ESP-Hosted firmware source. Skip this step if you are planning to use pre-built release binaries.` + +- Clone the ESP-IDF [release/v5.0](https://github.com/espressif/esp-idf/tree/release/v5.0) and checkout to `release/v5.0` branch. +- The control path between MCU host and ESP peripheral is based on `protobuf`. For that, corresponding stack layer, `protocomm` from ESP-IDF is used. It will be already present in ESP-IDF, no extra setup required for that. + +### 2.2 Setup +#### 2.2.1 Using pre-built binary +* Download pre-built firmware binaries from [releases](https://github.com/espressif/esp-hosted/releases) +* Follow `readme.txt` from release tarball to flash the ESP binary +* :warning: Make sure that you use `Source code (zip)` in `Assets` fold with associated release for host building. +* Windows user can use ESP Flash Programming Tool to flash the pre-built binary. + +#### 2.2.2 Compilation using source + +- Note: Please use the same git commit both at ESP and Host +- Clone the ESP-IDF [release/v5.0](https://github.com/espressif/esp-idf/tree/release/v5.0) and git checkout to `release/v5.0` branch. +- [Set-up the ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/release-v5.0/esp32/get-started/index.html) +- Navigate to `esp_hosted_fg/esp/esp_driver/network_adapter` directory. + +##### Using cmake + +``` +$ idf.py fullclean +``` + +Run following command and navigate to `Example Configuration -> Transport layer -> SDIO interface -> select` and exit from menuconfig. Read more about [idf.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/build-system.html#using-the-build-system) here. +``` +$ idf.py menuconfig +``` + +To build and flash the app on ESP peripheral, run + +```sh +$ idf.py -p build flash +``` diff --git a/esp_hosted_fg/docs/MCU_based_host/SPI_setup.md b/esp_hosted_fg/docs/MCU_based_host/SPI_setup.md new file mode 100644 index 0000000000..4843572074 --- /dev/null +++ b/esp_hosted_fg/docs/MCU_based_host/SPI_setup.md @@ -0,0 +1,141 @@ +# Wi-Fi connectivity Setup over SPI +## 1. Setup +### 1.1 Hardware Setup/Connections +* In this setup, ESP board acts as a SPI peripheral and provides Wi-Fi capabilities to host. Please connect ESP peripheral to STM32F469I board's CN12 Extension connecter with jumper cables as mentioned below. It may be good to use small length cables to ensure signal integrity. +* Power ESP peripheral and STM32F469I separately with a power supply that provide sufficient power. ESP peripheral can be powered through PC using micro-USB cable. STM32 can be powered with mini-B cable. It is also used as USART connection for debug logs from host. Serial port communicaton program like tera term or minicom used to print the logs. +* BT/BLE support will be added in upcoming release. + +#### Hardware connections for ESP32 +| STM32 Pin | ESP32 Pin | Function | +|:----------:|:---------:|:--------:| +| PB4 (pin5) | IO19 | MISO | +| PA5 (pin7) | IO18 | CLK | +| PB5 (pin9) | IO23 | MOSI | +| PA15 (pin11) | IO5 | CS | +| GND (pin2) | GND | GND | +| PC6 (pin6) | IO2 | Handshake | +| PC7 (pin8) | IO4 | Data Ready from ESP | +| PB13 (pin10) | EN | Reset ESP | + +Setup image is here. + +![alt text](stm32_esp_setup.jpg "setup of STM32F469I as host and ESP32 as peripheral") + +#### Hardware connections for ESP32-S2 +| STM32 Pin | ESP32-S2 Pin | Function | +|:---------:|:-----------:|:--------:| +| PB4 (pin5) | IO13 | MISO | +| PA5 (pin7) | IO12 | CLK | +| PB5 (pin9) | IO11 | MOSI | +| PA15 (pin11)| IO10 | CS | +| GND (pin2) | GND | GND | +| PC6 (pin6) | IO2 | Handshake | +| PC7 (pin8) | IO4 | Data ready from ESP | +| PB13 (pin10) | RST | Reset ESP | + +Setup image is here. + +![alt text](stm_esp32_s2_setup.jpg "Setup of STM32F469I as host and ESP32-S2 as peripheral") + +#### Hardware connections for ESP32-C2 +| STM32 Pin | ESP32-C2 Pin | Function | +|:---------:|:-----------:|:--------:| +| PB4 (pin5) | IO02 | MISO | +| PA5 (pin7) | IO06 | CLK | +| PB5 (pin9) | IO07 | MOSI | +| PA15 (pin11)| IO10 | CS | +| GND (pin2) | GND | GND | +| PC6 (pin6) | IO03 | Handshake | +| PC7 (pin8) | IO04 | Data ready from ESP | +| PB13 (pin10) | RST | Reset ESP | + +Setup image is here. + +![alt text](stm_esp32_c2_setup.png "Setup of STM32F469I as host and ESP32-C2 as peripheral") + +#### Hardware connections for ESP32-C3 +| STM32 Pin | ESP32-C3 Pin | Function | +|:---------:|:-----------:|:--------:| +| PB4 (pin5) | IO02 | MISO | +| PA5 (pin7) | IO06 | CLK | +| PB5 (pin9) | IO07 | MOSI | +| PA15 (pin11)| IO10 | CS | +| GND (pin2) | GND | GND | +| PC6 (pin6) | IO03 | Handshake | +| PC7 (pin8) | IO04 | Data ready from ESP | +| PB13 (pin10) | RST | Reset ESP | + +Setup image is here. + +![alt text](stm_esp32_c3_setup.jpg "Setup of STM32F469I as host and ESP32-C3 as peripheral") + +#### Hardware connections for ESP32-S3 +| STM32 Pin | ESP32-S3 Pin | Function | +|:---------:|:-----------:|:--------:| +| PB4 (pin5) | IO13 | MISO | +| PA5 (pin7) | IO12 | CLK | +| PB5 (pin9) | IO11 | MOSI | +| PA15 (pin11)| IO10 | CS | +| GND (pin2) | GND | GND | +| PC6 (pin6) | IO02 | Handshake | +| PC7 (pin8) | IO04 | Data ready from ESP | +| PB13 (pin10) | RST | Reset ESP | + +Setup image is here. + +![alt text](stm_esp32_s3_setup.jpg "Setup of STM32F469I as host and ESP32-S3 as peripheral") + +# 2. ESP peripheral setup +## 2.1 ESP-IDF requirement +:warning:`Note: ESP-IDF is needed to compile ESP-Hosted firmware source. Skip this step if you are planning to use pre-built release binaries.` + +- Clone the ESP-IDF [release/v5.0](https://github.com/espressif/esp-idf/tree/release/v5.0) and checkout to `release/v5.0` branch. +- The control path between MCU host and ESP peripheral is based on `protobuf`. For that, corresponding stack layer, `protocomm` from ESP-IDF is used. It will be already present in ESP-IDF, no extra setup required for that. + +### 2.2 Setup +#### 2.2.1 Using pre-built binary +* Download pre-built firmware binaries from [releases](https://github.com/espressif/esp-hosted/releases) +* Follow `readme.txt` from release tarball to flash the ESP binary +* :warning: Make sure that you use `Source code (zip)` in `Assets` fold with associated release for host building. +* Windows user can use ESP Flash Programming Tool to flash the pre-built binary. + +#### 2.2.2 Compilation using source + +- Note: Please use the same git commit both at ESP and Host +- Clone the ESP-IDF [release/v5.0](https://github.com/espressif/esp-idf/tree/release/v5.0) and git checkout to `release/v5.0` branch. +- [Set-up the ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/release-v5.0/esp32/get-started/index.html) +- Navigate to `esp_hosted_fg/esp/esp_driver/network_adapter` directory. + +##### Using cmake + +``` +$ idf.py fullclean +``` +:warning: Skip this step for ESP32. Run for ESP32-S2 / ESP32-C2 / ESP32-C3 +``` +$ idf.py set-target esp32s2 +``` +or +``` +$ idf.py set-target esp32c2 +``` +or +``` +$ idf.py set-target esp32c3 +``` + +Run following command and navigate to `Example Configuration -> Transport layer -> SPI interface -> select` and exit from menuconfig. Read more about [idf.py](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/build-system.html#using-the-build-system) here. +``` +$ idf.py menuconfig +``` + +:warning: Skip below step for ESP32-S2 / ESP32-C2 / ESP32-C3. Run for ESP32 only. + +Change SPI controller to VSPI. Please navigate to `Example Configuration → SPI Configuration` and change value of `SPI controller to use` to `3` + +To build and flash the app on ESP peripheral, run + +```sh +$ idf.py -p build flash +``` + diff --git a/esp_hosted_fg/docs/MCU_based_host/directory_structure.md b/esp_hosted_fg/docs/MCU_based_host/directory_structure.md index 56cb55ecd4..c5fca67a5e 100644 --- a/esp_hosted_fg/docs/MCU_based_host/directory_structure.md +++ b/esp_hosted_fg/docs/MCU_based_host/directory_structure.md @@ -21,7 +21,9 @@ │ │ │   │   ├── network (Contain netdev API implementation and network stub. Network stub │ │ │   │ │ should be replace by actual network stub like lwip by user) │ │ │   │   ├── serial (Contain Virtual Serial Interface implemented over SPI transport) -│ │ │   │   └── spi (Contain driver for SPI transport) +│ │ │   │   └── transport +│ │ │   │   ├── SDIO (Contain driver for SDIO transport) +│ │ │   │   └── SPI (Contain driver for SPI transport) │ │ │   ├── proj (Contain windows 'batch'(.bat) file and sh scripts for project setup. Also contain │ │ │ │ `.ioc` file which is HAL layer for STM32, used in project installation in STM32CubeIDE) │   │ │   └── port (Porting files for OS abstraction, contains wrappers diff --git a/esp_hosted_fg/docs/MCU_based_host/stm32_esp32_sdio_setup.jpg b/esp_hosted_fg/docs/MCU_based_host/stm32_esp32_sdio_setup.jpg new file mode 100644 index 0000000000..28f2f1d47d Binary files /dev/null and b/esp_hosted_fg/docs/MCU_based_host/stm32_esp32_sdio_setup.jpg differ diff --git a/esp_hosted_fg/esp/esp_driver/network_adapter/main/app_main.c b/esp_hosted_fg/esp/esp_driver/network_adapter/main/app_main.c index 4ef5cfc848..1bff625982 100644 --- a/esp_hosted_fg/esp/esp_driver/network_adapter/main/app_main.c +++ b/esp_hosted_fg/esp/esp_driver/network_adapter/main/app_main.c @@ -77,7 +77,6 @@ static const char TAG_TX_S[] = "CONTROL S -> H"; #define ETH_DATA_LEN 1500 -volatile uint8_t action = 0; volatile uint8_t datapath = 0; volatile uint8_t station_connected = 0; volatile uint8_t softap_started = 0; @@ -423,7 +422,7 @@ void process_rx_pkt(interface_buffer_handle_t *buf_handle) /* Get data from host */ void recv_task(void* pvParameters) { - interface_buffer_handle_t buf_handle; + interface_buffer_handle_t buf_handle = {0}; for (;;) { @@ -738,7 +737,9 @@ void app_main() protocomm_pserial_start(pc_pserial, serial_write_data, serial_read_data); if_context = interface_insert_driver(event_handler); +#if CONFIG_ESP_SPI_HOST_INTERFACE datapath = 1; +#endif if (!if_context || !if_context->if_ops) { ESP_LOGE(TAG, "Failed to insert driver\n"); @@ -752,10 +753,10 @@ void app_main() return; } - sleep(1); - +#if CONFIG_ESP_SPI_HOST_INTERFACE /* send capabilities to host */ generate_startup_event(capa); +#endif meta_to_host_queue = xQueueCreate(TO_HOST_QUEUE_SIZE*3, sizeof(uint8_t)); assert(meta_to_host_queue); @@ -780,6 +781,13 @@ void app_main() ESP_LOGI(TAG,"Initial set up done"); - sleep(1); + while(!datapath) { + vTaskDelay(10); + } + +#if CONFIG_ESP_SDIO_HOST_INTERFACE + /* send capabilities to host */ + generate_startup_event(capa); +#endif send_event_to_host(CTRL_MSG_ID__Event_ESPInit); } diff --git a/esp_hosted_fg/esp/esp_driver/network_adapter/main/sdio_slave_api.c b/esp_hosted_fg/esp/esp_driver/network_adapter/main/sdio_slave_api.c index a66c4500c8..da1fbc57a7 100644 --- a/esp_hosted_fg/esp/esp_driver/network_adapter/main/sdio_slave_api.c +++ b/esp_hosted_fg/esp/esp_driver/network_adapter/main/sdio_slave_api.c @@ -26,9 +26,10 @@ #include "mempool.h" #include "stats.h" -#define SDIO_SLAVE_QUEUE_SIZE 20 -#define BUFFER_SIZE 1536 /* 512*3 */ -#define BUFFER_NUM 10 +#define SDIO_SLAVE_QUEUE_SIZE 20 +#define BUFFER_SIZE 1536 /* 512*3 */ +#define BUFFER_NUM 10 +#define SDIO_BLOCK_SIZE 512 static uint8_t sdio_slave_rx_buffer[BUFFER_NUM][BUFFER_SIZE]; static struct mempool * buf_mp_g; @@ -135,6 +136,11 @@ void generate_startup_event(uint8_t cap) /* TLVs start */ + /* TLV - Board type */ + *pos = ESP_PRIV_FIRMWARE_CHIP_ID; pos++;len++; + *pos = LENGTH_1_BYTE; pos++;len++; + *pos = CONFIG_IDF_FIRMWARE_CHIP_ID; pos++;len++; + /* TLV - Capability */ *pos = ESP_PRIV_CAPABILITY; pos++;len++; *pos = LENGTH_1_BYTE; pos++;len++; @@ -298,6 +304,7 @@ static int32_t sdio_write(interface_handle_t *handle, interface_buffer_handle_t static int sdio_read(interface_handle_t *if_handle, interface_buffer_handle_t *buf_handle) { + esp_err_t ret = ESP_OK; struct esp_payload_header *header = NULL; #if CONFIG_ESP_SDIO_CHECKSUM uint16_t rx_checksum = 0, checksum = 0; @@ -306,17 +313,19 @@ static int sdio_read(interface_handle_t *if_handle, interface_buffer_handle_t *b size_t sdio_read_len = 0; - if (!if_handle) { + if (!if_handle || !buf_handle) { ESP_LOGE(TAG, "Invalid arguments to sdio_read"); return ESP_FAIL; } - if (if_handle->state != ACTIVE) { + if (if_handle->state != ACTIVE) return ESP_FAIL; - } - sdio_slave_recv(&(buf_handle->sdio_buf_handle), &(buf_handle->payload), + ret = sdio_slave_recv(&(buf_handle->sdio_buf_handle), &(buf_handle->payload), &(sdio_read_len), portMAX_DELAY); + if (ret) + return ESP_FAIL; + buf_handle->payload_len = sdio_read_len & 0xFFFF; header = (struct esp_payload_header *) buf_handle->payload; @@ -338,7 +347,6 @@ static int sdio_read(interface_handle_t *if_handle, interface_buffer_handle_t *b buf_handle->if_type = header->if_type; buf_handle->if_num = header->if_num; buf_handle->free_buf_handle = sdio_read_done; - return len; } @@ -366,7 +374,7 @@ static esp_err_t sdio_reset(interface_handle_t *handle) if (handle) { ret = sdio_slave_recv_load_buf(handle); - ESP_ERROR_CHECK(ret); + ESP_ERROR_CHECK_WITHOUT_ABORT(ret); } } diff --git a/esp_hosted_fg/host/control_lib/src/ctrl_core.c b/esp_hosted_fg/host/control_lib/src/ctrl_core.c index acd05e16d2..747364b788 100644 --- a/esp_hosted_fg/host/control_lib/src/ctrl_core.c +++ b/esp_hosted_fg/host/control_lib/src/ctrl_core.c @@ -11,7 +11,7 @@ #include -#ifdef STM32F469xx +#ifdef MCU #include "common.h" #define command_log(...) printf(__VA_ARGS__); printf("\r"); #else @@ -20,7 +20,7 @@ #define min(X, Y) (((X) < (Y)) ? (X) : (Y)) #endif -#ifndef STM32F469xx +#ifndef MCU #define MAX_INTERFACE_LEN IFNAMSIZ #define MAC_SIZE_BYTES 6 #define MIN_MAC_STR_LEN 17 @@ -160,7 +160,7 @@ static inline int is_ctrl_lib_state(int state) } -#ifndef STM32F469xx +#ifndef MCU /* Function converts mac string to byte stream */ static int convert_mac_to_bytes(uint8_t *out, size_t out_size, char *s) { @@ -1534,7 +1534,7 @@ int deinit_hosted_control_lib_internal(void) int init_hosted_control_lib_internal(void) { int ret = SUCCESS; -#ifndef STM32F469xx +#ifndef MCU if(getuid()) { printf("Please re-run program with superuser access\n"); return FAILURE; @@ -1582,7 +1582,7 @@ int init_hosted_control_lib_internal(void) -#ifndef STM32F469xx +#ifndef MCU /* Function ups in given interface */ int interface_up(int sockfd, char* iface) diff --git a/esp_hosted_fg/host/stm32/app/app_main.c b/esp_hosted_fg/host/stm32/app/app_main.c index 12e4b07d80..4e2eb4beba 100644 --- a/esp_hosted_fg/host/stm32/app/app_main.c +++ b/esp_hosted_fg/host/stm32/app/app_main.c @@ -15,13 +15,12 @@ /** Includes **/ #include "usart.h" -#include "cmsis_os.h" -#include "spi_drv.h" +#include "transport_drv.h" #include "control.h" #include "trace.h" #include "app_main.h" -#include "netdev_api.h" #include "arp_server_stub.h" +#include "stats.h" /** Constants/Macros **/ #define ARPING_PATH_TASK_STACK_SIZE 4096 @@ -42,6 +41,11 @@ static void init_ap(void); static void reset_slave(void); static void arping_task(void const *arg); +/* Needed for timer task */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); + + /* GetIdleTaskMemory prototype (linked to static allocation support) */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); @@ -118,17 +122,20 @@ static void control_path_event_handler(uint8_t event) } /** - * @brief SPI driver event handler callback + * @brief transport driver event handler callback * @param event - spi_drv_events_e event to be handled * @retval None */ -static void spi_driver_event_handler(uint8_t event) +static void transport_driver_event_handler(uint8_t event) { switch(event) { - case SPI_DRIVER_ACTIVE: + case TRANSPORT_ACTIVE: { /* Initiate control path now */ +#if DEBUG_TRANSPORT + printf("Base transport is set-up\n\r"); +#endif control_path_init(control_path_event_handler); break; } @@ -153,13 +160,14 @@ void MX_FREERTOS_Init(void) network_init(); /* init spi driver */ - stm_spi_init(spi_driver_event_handler); - - /* This thread's priority shouls be >= spi driver's transaction task priority */ + transport_init(transport_driver_event_handler); +#if !TEST_RAW_TP + /* This thread's priority shouls be >= transport driver's transaction task priority */ osThreadDef(Arping_Thread, arping_task, osPriorityAboveNormal, 0, ARPING_PATH_TASK_STACK_SIZE); arping_task_id = osThreadCreate(osThread(Arping_Thread), NULL); assert(arping_task_id); +#endif } /** @@ -208,6 +216,26 @@ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; } +/** + * @brief FreeRTOS hook function for timer task stack + * @param None + * @retval None + */ +void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) +{ + /* USER CODE BEGIN GET_TIMER_TASK_MEMORY */ + static StaticTask_t xTimerTaskTCBBuffer; + static StackType_t xTimerStack[configTIMER_TASK_STACK_DEPTH]; + + + *ppxTimerTaskTCBBuffer = &xTimerTaskTCBBuffer; + *ppxTimerTaskStackBuffer = &xTimerStack[0]; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; + /* place for user code */ +} + + /** * @brief Station mode rx callback * @param net_handle - station network handle @@ -357,7 +385,6 @@ static void arping_task(void const *arg) if(ap_handle) send_arp_req(ap_handle, get_self_mac_softap(), &softap_ip, dst_mac_bytes, &softap_dest_ip); - osDelay(1000); } } diff --git a/esp_hosted_fg/host/stm32/app/app_main.h b/esp_hosted_fg/host/stm32/app/app_main.h index 6eae9e7bc1..de97a0c858 100644 --- a/esp_hosted_fg/host/stm32/app/app_main.h +++ b/esp_hosted_fg/host/stm32/app/app_main.h @@ -21,7 +21,6 @@ extern "C" { #endif /** Includes **/ -#include "common.h" #include "netdev_api.h" /** Exported macros **/ diff --git a/esp_hosted_fg/host/stm32/app/app_main_api.h b/esp_hosted_fg/host/stm32/app/app_main_api.h index 9106e05399..bf833cfad8 100644 --- a/esp_hosted_fg/host/stm32/app/app_main_api.h +++ b/esp_hosted_fg/host/stm32/app/app_main_api.h @@ -20,7 +20,6 @@ extern "C" { #endif /** Includes **/ -#include "common.h" /** Exported Structures **/ diff --git a/esp_hosted_fg/host/stm32/app/control/control.h b/esp_hosted_fg/host/stm32/app/control/control.h index be025c8315..cb552d10fb 100644 --- a/esp_hosted_fg/host/stm32/app/control/control.h +++ b/esp_hosted_fg/host/stm32/app/control/control.h @@ -126,7 +126,6 @@ typedef enum control_path_events_s { #define INPUT_SOFTAP_ARP_DEST_IP "192.168.2.22" #endif - #define WIFI_MAX_STR_LEN 19 /** Exported Structures **/ diff --git a/esp_hosted_fg/host/stm32/app/control/control_utils.c b/esp_hosted_fg/host/stm32/app/control/control_utils.c index cb5fdb20f9..360746239b 100644 --- a/esp_hosted_fg/host/stm32/app/control/control_utils.c +++ b/esp_hosted_fg/host/stm32/app/control/control_utils.c @@ -32,9 +32,6 @@ /***** Please Read *****/ /* Before use : User must enter user configuration parameter in "ctrl_config.h" file */ -#define STA_INTERFACE "ethsta0" -#define AP_INTERFACE "ethap0" - #define WIFI_VENDOR_IE_ELEMENT_ID 0xDD #define OFFSET 4 #define VENDOR_OUI_0 1 diff --git a/esp_hosted_fg/host/stm32/app/data/arp_server_stub.c b/esp_hosted_fg/host/stm32/app/data/arp_server_stub.c index bb581575c3..ad487940e7 100644 --- a/esp_hosted_fg/host/stm32/app/data/arp_server_stub.c +++ b/esp_hosted_fg/host/stm32/app/data/arp_server_stub.c @@ -271,16 +271,17 @@ static void display_arp(uint8_t *pkt, uint16_t pkt_len, uint8_t arp_msg) char mac_s[30]; uint8_t *mac = NULL; char str_req[2][20] = {"ARP_REQ_RCVD", "ARP_RSP_RCVD"}; + static uint32_t count = 0; if (arp_msg < MAX_MSG_TYPE_ARPING) { ipv4_addr_ntoa(arping_get_ipaddr(pkt, IP_ADDR_TYPE_SRC), ip_addr_s, 20); mac = arping_get_mac(pkt, MAC_ADDR_TYPE_SRC); - snprintf(mac_s, 30, "%2x:%2x:%2x:%2x:%2x:%2x", + snprintf(mac_s, 30, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - printf("%s: %u bytes from %s (%s)\n\r", - str_req[arp_msg-1], pkt_len, ip_addr_s, mac_s); + printf("0x%05lX %s: %u bytes from %s (%s)\n\r", + ++count, str_req[arp_msg-1], pkt_len, ip_addr_s, mac_s); } } diff --git a/esp_hosted_fg/host/stm32/common/common.h b/esp_hosted_fg/host/stm32/common/common.h index 942f0678cf..0be0ad7d17 100644 --- a/esp_hosted_fg/host/stm32/common/common.h +++ b/esp_hosted_fg/host/stm32/common/common.h @@ -22,28 +22,52 @@ extern "C" { /** Includes **/ #include "stdint.h" -#include "stddef.h" +#include "stdio.h" /** Constants/Macros **/ +#define MAX_NETWORK_INTERFACES 2 +#define STA_INTERFACE "ESP_STATION" +#define SOFTAP_INTERFACE "ESP_SOFTAP" + #define UNUSED_VAR(x) (void)(x); + #define MAX_SPI_BUFFER_SIZE 1600 +/* TODO: SDIO buffers to be set same at both, ESP and host side */ +#define MAX_SDIO_BUFFER_SIZE 1536 + +#define MAX_SUPPORTED_SDIO_CLOCK_MHZ 40 + #define malloc pvPortMalloc #define free vPortFree #define htole16(x) ((uint16_t)(x)) #define le16toh(x) ((uint16_t)(x)) -#define IP_ADDR_LEN 4 +#define IP_ADDR_LEN 4 #define MAC_LEN 6 #define MIN_MAC_STRING_LEN 17 +#ifndef BIT +#define BIT(x) (1UL << (x)) +#endif +#define FREQ_IN_MHZ(x) ((x)*1000000) typedef enum stm_ret_s { - STM_FAIL = -1, - STM_OK = 0 + STM_OK = 0, + STM_FAIL = -1, + STM_FAIL_TIMEOUT = -2, + STM_FAIL_INVALID_ARG = -3, + STM_FAIL_NO_MEMORY = -4, + STM_FAIL_NOT_FOUND = -5, + STM_FAIL_NOT_FINISHED = -6, + STM_FAIL_ALIGNMENT = -7 }stm_ret_t; +typedef enum { + TRANSPORT_INACTIVE, + TRANSPORT_ACTIVE +} transport_drv_events_e; /** Exported Structures **/ /* interface header */ diff --git a/esp_hosted_fg/host/stm32/common/stats.c b/esp_hosted_fg/host/stm32/common/stats.c new file mode 100644 index 0000000000..c986646770 --- /dev/null +++ b/esp_hosted_fg/host/stm32/common/stats.c @@ -0,0 +1,145 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** Includes **/ + +#include "stats.h" +#if TEST_RAW_TP +#include "platform_wrapper.h" +#include "transport_drv.h" +#endif +/** Constants/Macros **/ +#define RAW_TP_TX_TASK_STACK_SIZE 4096 + +/** Exported variables **/ + +/** Function declaration **/ + +/** Exported Functions **/ + +#if TEST_RAW_TP +static int test_raw_tp = 0; +static int test_raw_tp__host_to_esp = 0; +static uint8_t log_raw_tp_stats_timer_running = 0; +static uint32_t raw_tp_timer_count = 0; +void *hosted_timer_handler = NULL; +static osThreadId raw_tp_tx_task_id = 0; +static uint64_t test_raw_tp_len = 0; + +void test_raw_tp_cleanup(void) +{ + int ret = 0; + + if (log_raw_tp_stats_timer_running) { + ret = hosted_timer_stop(hosted_timer_handler); + if (!ret) { + log_raw_tp_stats_timer_running = 0; + } + raw_tp_timer_count = 0; + } + + if (raw_tp_tx_task_id) { + ret = osThreadTerminate(raw_tp_tx_task_id); + raw_tp_tx_task_id = 0; + } +} + +void raw_tp_timer_func(void const * arg) +{ + double actual_bandwidth = 0; + int32_t div = 1024; + + actual_bandwidth = (test_raw_tp_len*8); + printf("%lu-%lu sec %.5f Kbits/sec\n\r", raw_tp_timer_count, raw_tp_timer_count + 1, actual_bandwidth/div); + raw_tp_timer_count++; + test_raw_tp_len = 0; +} + +static void raw_tp_tx_task(void const* pvParameters) +{ + int ret; + static uint16_t seq_num = 0; + uint8_t *raw_tp_tx_buf = NULL; + sleep(5); + while (1) { + + raw_tp_tx_buf = (uint8_t*)hosted_calloc(1, TEST_RAW_TP__BUF_SIZE); + ret = send_to_slave(ESP_TEST_IF, 0, raw_tp_tx_buf, TEST_RAW_TP__BUF_SIZE); + if (ret != STM_OK) { + printf("Failed to send to queue\n"); + continue; + } + test_raw_tp_len += (TEST_RAW_TP__BUF_SIZE+sizeof(struct esp_payload_header)); + seq_num++; + } +} + +static void process_raw_tp_flags(void) +{ + test_raw_tp_cleanup(); + + if (test_raw_tp) { + hosted_timer_handler = hosted_timer_start(TEST_RAW_TP__TIMEOUT, CTRL__TIMER_PERIODIC, raw_tp_timer_func, NULL); + if (!hosted_timer_handler) { + printf("Failed to create timer\n\r"); + return; + } + log_raw_tp_stats_timer_running = 1; + + if (test_raw_tp__host_to_esp) { + osThreadDef(raw_tp_tx_thread, raw_tp_tx_task, + osPriorityAboveNormal, 0, RAW_TP_TX_TASK_STACK_SIZE); + raw_tp_tx_task_id = osThreadCreate(osThread(raw_tp_tx_thread), NULL); + assert(raw_tp_tx_task_id); + } + } +} + +static void start_test_raw_tp(int raw_tp__host_to_esp) +{ + test_raw_tp = 1; + test_raw_tp__host_to_esp = raw_tp__host_to_esp; +} + +static void stop_test_raw_tp(void) +{ + test_raw_tp = 0; + test_raw_tp__host_to_esp = 0; +} + +void process_test_capabilities(uint8_t cap) +{ + printf("ESP peripheral capabilities: 0x%x\n\r", cap); + if ((cap & ESP_TEST_RAW_TP) == ESP_TEST_RAW_TP) { + if ((cap & ESP_TEST_RAW_TP__ESP_TO_HOST) == ESP_TEST_RAW_TP__ESP_TO_HOST) { + start_test_raw_tp(ESP_TEST_RAW_TP__RX); + printf("esp32: start testing of ESP->Host raw throughput\n\r"); + } else { + start_test_raw_tp(ESP_TEST_RAW_TP__TX); + printf("esp32: start testing of Host->ESP raw throughput\n\r"); + } + } else { + printf("esp32: stop raw throuput test if running\n"); + stop_test_raw_tp(); + } + process_raw_tp_flags(); +} + +void update_test_raw_tp_rx_len(uint16_t len) +{ + test_raw_tp_len+=len; +} + +#endif diff --git a/esp_hosted_fg/host/stm32/common/stats.h b/esp_hosted_fg/host/stm32/common/stats.h new file mode 100644 index 0000000000..358e6d8a27 --- /dev/null +++ b/esp_hosted_fg/host/stm32/common/stats.h @@ -0,0 +1,79 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef __STATS__H +#define __STATS__H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "common.h" + +/* Stats CONFIG: + * + * 1. TEST_RAW_TP + * These are debug stats which show the raw throughput + * performance of transport like SPI or SDIO + * (a) TEST_RAW_TP__ESP_TO_HOST + * When this enabled, throughput will be measured from ESP to Host + * + * (b) TEST_RAW_TP__HOST_TO_ESP + * This is opposite of TEST_RAW_TP__ESP_TO_HOST. when (a) TEST_RAW_TP__ESP_TO_HOST + * is disabled, it will automatically mean throughput to be measured from host to ESP + */ +#define TEST_RAW_TP 0 + + +/* TEST_RAW_TP is disabled on production. + * This is only to test the throughout over transport + * like SPI or SDIO. In this testing, dummy task will + * push the packets over transport. + * Currently this testing is possible on one direction + * at a time + */ + +#if TEST_RAW_TP +/* +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "esp_timer.h" +#include "interface.h" */ + +/* Raw throughput is supported only one direction + * at a time + * i.e. ESP to Host OR + * Host to ESP + */ +#define TEST_RAW_TP__ESP_TO_HOST 1 +#define TEST_RAW_TP__HOST_TO_ESP !TEST_RAW_TP__ESP_TO_HOST + +#define TEST_RAW_TP__TIMEOUT 1 + +void update_test_raw_tp_rx_len(uint16_t len); +void process_test_capabilities(uint8_t cap); + +#define TEST_RAW_TP__BUF_SIZE 1460 + +#define ESP_TEST_RAW_TP__RX 0 +#define ESP_TEST_RAW_TP__TX 1 + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/esp_hosted_fg/host/stm32/common/trace.h b/esp_hosted_fg/host/stm32/common/trace.h index 36a2675874..13eb11ec61 100644 --- a/esp_hosted_fg/host/stm32/common/trace.h +++ b/esp_hosted_fg/host/stm32/common/trace.h @@ -24,9 +24,12 @@ extern "C" { #include "stdio.h" /** constants/macros **/ +#define DEBUG_TRANSPORT 1 #define DEBUG_HEX_STREAM_PRINT 0 +#ifndef assert #define assert(x) do { if (!(x)) { \ printf("Aborting at: %s:%u\n", __FILE__, __LINE__); while(1);}} while (0); +#endif /** Exported Structures **/ diff --git a/esp_hosted_fg/host/stm32/common/util.c b/esp_hosted_fg/host/stm32/common/util.c index ff14a940a2..2eef9eccd1 100644 --- a/esp_hosted_fg/host/stm32/common/util.c +++ b/esp_hosted_fg/host/stm32/common/util.c @@ -17,7 +17,6 @@ #include "util.h" #include "ctype.h" #include "string.h" -#include "trace.h" /** Constants/Macros **/ @@ -82,7 +81,7 @@ int ipv4_addr_aton(const char *cp, uint32_t *ip_uint32) /* * Check for trailing characters. */ - if (*cp && (!isascii(*cp) || !isspace(*cp))) + if (*cp && (!isascii((uint8_t)*cp) || !isspace((uint8_t)*cp))) return (0); /* * Concoct the address according to diff --git a/esp_hosted_fg/host/stm32/driver/network/netdev_api.c b/esp_hosted_fg/host/stm32/driver/network/netdev_api.c index 026e54296b..c349d92bae 100644 --- a/esp_hosted_fg/host/stm32/driver/network/netdev_api.c +++ b/esp_hosted_fg/host/stm32/driver/network/netdev_api.c @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "common.h" -#include "trace.h" -#include "netdev_if.h" #include "netdev_api.h" /** diff --git a/esp_hosted_fg/host/stm32/driver/network/netdev_stub.c b/esp_hosted_fg/host/stm32/driver/network/netdev_stub.c index 55ac14fd17..a6f80937eb 100644 --- a/esp_hosted_fg/host/stm32/driver/network/netdev_stub.c +++ b/esp_hosted_fg/host/stm32/driver/network/netdev_stub.c @@ -13,10 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "trace.h" #include "string.h" #include "cmsis_os.h" -#include "netdev_if.h" #include "app_main.h" struct netdev *ndev_db[MAX_INTERFACE]; diff --git a/esp_hosted_fg/host/stm32/driver/serial/serial_drv.h b/esp_hosted_fg/host/stm32/driver/serial/serial_drv.h index 40dda66cfe..063834f0c4 100644 --- a/esp_hosted_fg/host/stm32/driver/serial/serial_drv.h +++ b/esp_hosted_fg/host/stm32/driver/serial/serial_drv.h @@ -21,7 +21,6 @@ extern "C" { #endif /** includes **/ -#include "common.h" #include "serial_ll_if.h" /** Exported Functions **/ diff --git a/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.c b/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.c index 009373e937..e10b904ee5 100644 --- a/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.c +++ b/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.c @@ -15,12 +15,8 @@ /** Includes **/ #include "string.h" -#include "serial_drv.h" #include "serial_ll_if.h" -#include "adapter.h" -#include "spi_drv.h" #include "trace.h" -#include "platform_wrapper.h" /** Macros / Constants **/ #define MAX_SERIAL_INTF 2 diff --git a/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.h b/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.h index 73be161b82..84c669343f 100644 --- a/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.h +++ b/esp_hosted_fg/host/stm32/driver/serial/serial_ll_if.h @@ -21,8 +21,7 @@ extern "C" { #endif /** includes **/ -#include "cmsis_os.h" -#include "common.h" +#include "transport_drv.h" struct serial_ll_operations; diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_api.c b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_api.c new file mode 100644 index 0000000000..6016d455a8 --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_api.c @@ -0,0 +1,159 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** Includes **/ +#include "common.h" +#include "sdio_ll.h" + +/** Constants/Macros **/ + +#define CLK_IN_MHZ 1000000 +#define SDIO_CLOCK 10*CLK_IN_MHZ +#define MAX_SUPPORTED_SDIO_CLOCK 10*CLK_IN_MHZ + +/** + * @brief Probe and initialize SDIO slave using given host + * @param None + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_init(void) +{ + sdio_init_t sdio_init = { + .width = WIDTH_4, + /* Max supported now is MAX_SUPPORTED_SDIO_CLOCK + * Anything beyond MAX_SUPPORTED_SDIO_CLOCK will automatically be limited + **/ + .clock = SDIO_CLOCK + }; + + if (sdio_init.clock > MAX_SUPPORTED_SDIO_CLOCK) { + /* Limit clock to maximum supported */ + sdio_init.clock = MAX_SUPPORTED_SDIO_CLOCK; + } + + STM32SdioInit(sdio_init); + return STM_OK; +} + +/** + * @brief Read multiple bytes from an SDIO card using CMD53 + * @param function - IO function number + * addr - byte address within IO function where reading starts + * buffer - buffer which receives the data read from card + * len - number of bytes to read + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_read_bytes(uint32_t function, uint32_t addr, void* buffer, + uint32_t len, uint8_t multi_blocks) +{ + int ret = 0; + ret = STM32ReadData(function, addr, buffer, len, multi_blocks); + if (ret) { + printf("%s %d CMD53 error\r\n",__func__, __LINE__); + return STM_FAIL; + } + + return STM_OK; +} + +/** + * @brief Write multiple bytes to an SDIO card using CMD53 + * @param function - IO function number + * addr - byte address within IO function where writing starts + * buffer - data to be written + * len - number of bytes to write + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_write_bytes(uint32_t function, uint32_t addr, + void* buffer, uint32_t len) +{ + int ret = STM32WriteData(function, addr, buffer, len); + if (ret < 0) { + printf("%s CMD53 write error\r\n",__func__); + return STM_FAIL; + } + return STM_OK; +} + +/** + * @brief Write blocks of data to an SDIO card using CMD53 + * @param function - IO function number + * addr - byte address within IO function where writing starts + * buffer - data to be written + * len - number of bytes to read, must be divisible by the card block size. + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_write_blocks(uint32_t function, uint32_t addr, + void* buffer, uint32_t len) +{ + return sdio_driver_write_bytes(function, addr, buffer, len); +} + +/** + * @brief Read blocks of data from an SDIO card using CMD53 + * @param function - IO function number + * addr - byte address within IO function where writing starts + * buffer - buffer which receives the data read from card + * len - number of bytes to read, must be divisible by the card block size. + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_read_blocks(uint32_t function, uint32_t addr, + void* buffer, uint32_t len, uint8_t multi_blocks) +{ + stm_ret_t ret = STM_OK; + + ret = sdio_driver_read_bytes(function, addr, buffer, len, multi_blocks); + if (ret) { + printf("%s %d CMD53 error\r\n",__func__, __LINE__); + return STM_FAIL; + } + return ret; +} + +/** + * @brief Read one byte from SDIO slave using CMD52 + * @param function - IO function number + * reg - byte address within IO function + * [out]out_byte - output, receives the value read from the card + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_read_byte(uint32_t function, uint32_t reg, uint8_t *out_byte) +{ + uint8_t func = function & 0xf; + uint8_t result = STM32ReadReg(func, reg); + if (out_byte) { + *out_byte = result; + } + return STM_OK; +} + +/** + * @brief Write one byte to SDIO slave using CMD52 + * @param function - IO function number + * reg - byte address within IO function + * in_byte - value to be written + * [out]out_byte - if not NULL, receives new byte value read from + * the card (read-after-write). + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_write_byte(uint32_t function, uint32_t reg, + uint8_t in_byte, uint8_t* out_byte) +{ + uint8_t func = function & 0xf; + uint8_t result = STM32WriteReg(func, reg, in_byte); + if (out_byte) { + *out_byte = result; + } + return STM_OK; +} diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_api.h b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_api.h new file mode 100644 index 0000000000..df1d5810de --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_api.h @@ -0,0 +1,116 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** prevent recursive inclusion **/ +#ifndef __SDIO_API_H +#define __SDIO_API_H + +/** Includes **/ + +/** constants/macros **/ + +/** Exported Structures **/ + +/** Exported variables **/ + +/** Inline functions **/ + +/** Exported Functions **/ + +/** + * Probe and initialize SDIO slave using given host + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_init(void); + +/** + * Write blocks of data to an SDIO card using CMD53 + * + * This function performs write operation using CMD53 in block mode + * For byte mode, see sdio_driver_write_bytes + * + * @param function - IO function number + * addr - byte address within IO function where writing starts + * buffer - data to be written + * len - number of bytes to read, must be divisible by the card block size + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_write_blocks(uint32_t function, uint32_t addr, void* buffer, uint32_t len); + +/** + * Read blocks of data from an SDIO card using CMD53 + * + * This function performs read operation using CMD53 in block mode + * For byte mode, see sdio_driver_read_bytes + * + * @param function - IO function number + * addr - byte address within IO function where writing starts + * buffer - buffer which receives the data read from card + * len - number of bytes to read, must be divisible by the card block size + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_read_blocks(uint32_t function, uint32_t addr, void* buffer, uint32_t len, uint8_t multi_blocks); + +/** + * Read multiple bytes from an SDIO card using CMD53 + * + * This function performs read operation using CMD53 in byte mode + * For block mode, see sdio_driver_read_blocks + * + * @param function - IO function number + * addr - byte address within IO function where reading starts + * buffer - buffer which receives the data read from card + * len - number of bytes to read + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_read_bytes(uint32_t function, uint32_t addr, void* buffer, uint32_t len, uint8_t multi_blocks); + +/** + * Write multiple bytes to an SDIO card using CMD53 + * + * This function performs write operation using CMD53 in byte mode + * For block mode, see sdio_driver_write_blocks + * + * @param function - IO function number + * addr - byte address within IO function where writing starts + * buffer - data to be written + * len - number of bytes to write + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_write_bytes(uint32_t function, uint32_t addr, void* buffer, uint32_t len); + +/** + * Read one byte from SDIO slave using CMD52 + * + * @param function - IO function number + * reg - byte address within IO function + * [out]out_byte - output, receives the value read from the card + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_read_byte(uint32_t function, uint32_t reg, uint8_t *out_byte); + +/** + * Write one byte to SDIO slave using CMD52 + * + * @param function - IO function number + * reg - byte address within IO function + * in_byte - value to be written + * [out]out_byte - if not NULL, receives new byte value read from the + * card (read-after-write) + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_driver_write_byte(uint32_t function, uint32_t reg, uint8_t in_byte, uint8_t* out_byte); + +#endif /* __SDIO_API_H */ diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_drv.c b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_drv.c new file mode 100644 index 0000000000..a32208b926 --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_drv.c @@ -0,0 +1,667 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** Includes **/ +#include "string.h" +#include "sdio.h" + +#include "sdio_drv.h" +#include "sdio_reg.h" +#include "sdio_host.h" +#include "sdio_ll.h" +#include "serial_drv.h" +#include "stats.h" + +/** Constants/Macros **/ +#define TO_SLAVE_QUEUE_SIZE 10 +#define FROM_SLAVE_QUEUE_SIZE 10 + +#define RX_TASK_STACK_SIZE 4096 +#define TX_TASK_STACK_SIZE 4096 +#define PROCESS_RX_TASK_STACK_SIZE 4096 +#define RX_TIMEOUT_TICKS 50 + +#define MAX_PAYLOAD_SIZE (MAX_SDIO_BUFFER_SIZE-sizeof(struct esp_payload_header)) + +/** Enumeration **/ +enum hardware_type_e { + HARDWARE_TYPE_ESP32, + HARDWARE_TYPE_INVALID, +}; + +/** Function declaration **/ + +static void sdio_recv(void); +static stm_ret_t io_init_seq(void); +static stm_ret_t sdio_rx_esp32(void); +static stm_ret_t generate_slave_intr(uint8_t intr_no); + +static struct esp_private * esp_priv[MAX_NETWORK_INTERFACES]; +static struct esp_private * get_priv(uint8_t if_type, uint8_t if_num); + +static struct netdev_ops esp_net_ops = { + .netdev_open = esp_netdev_open, + .netdev_close = esp_netdev_close, + .netdev_xmit = esp_netdev_xmit, +}; + +static int init_netdev(void); +static void deinit_netdev(void); + +static void rx_task(void const* pvParameters); +static void tx_task(void const* pvParameters); +static void process_rx_task(void const* pvParameters); + +static void set_hardware_type(void); + +/* SDIO transaction functions for different hardware types */ +static stm_ret_t (*sdio_trans_func[])(void) = { + sdio_rx_esp32, +}; + +/** Exported variables **/ +SemaphoreHandle_t sdio_recv_SemHandle; + +/** Global static variables **/ +static uint8_t hardware_type = HARDWARE_TYPE_INVALID; +static osMutexId transmit_mux; +static osThreadId process_rx_task_id = 0; +static osThreadId rx_task_id = 0; +static osThreadId tx_task_id = 0; + +/* Queue declaration */ +static QueueHandle_t to_slave_queue = NULL; +static QueueHandle_t from_slave_queue = NULL; + +/* callback of event handler */ +static void (*sdio_drv_evt_handler_fp) (uint8_t); + +/** function definition **/ + +/** Local Functions **/ + +/** + * @brief get private interface of expected type and number + * @param if_type - interface type + * if_num - interface number + * @retval interface handle if found, else NULL + */ +static struct esp_private * get_priv(uint8_t if_type, uint8_t if_num) +{ + for (int i = 0; i < MAX_NETWORK_INTERFACES; i++) { + if((esp_priv[i]) && + (esp_priv[i]->if_type == if_type) && + (esp_priv[i]->if_num == if_num)) + return esp_priv[i]; + } + + return NULL; +} + + +/** + * @brief create virtual network device + * @param None + * @retval 0 on success + * -1 on failure + */ +static int init_netdev(void) +{ + void *ndev = NULL; + struct esp_private *priv = NULL; + char *if_name[MAX_NETWORK_INTERFACES] = {STA_INTERFACE, SOFTAP_INTERFACE, }; + uint8_t if_type[MAX_NETWORK_INTERFACES] = {ESP_STA_IF, ESP_AP_IF, }; + + for (int i = 0; i < MAX_NETWORK_INTERFACES; i++) { + /* Alloc and init netdev */ + ndev = netdev_alloc(sizeof(struct esp_private), if_name[i]); + if (!ndev) { + deinit_netdev(); + return STM_FAIL; + } + + priv = (struct esp_private *) netdev_get_priv(ndev); + if (!priv) { + deinit_netdev(); + return STM_FAIL; + } + + priv->netdev = ndev; + priv->if_type = if_type[i]; + priv->if_num = 0; + + if (netdev_register(ndev, &esp_net_ops)) { + deinit_netdev(); + return STM_FAIL; + } + + esp_priv[i] = priv; + } + + return STM_OK; +} + +/** + * @brief destroy virtual network device + * @param None + * @retval None + */ +static void deinit_netdev(void) +{ + for (int i = 0; i < MAX_NETWORK_INTERFACES; i++) { + if (esp_priv[i]) { + if (esp_priv[i]->netdev) { + netdev_unregister(esp_priv[i]->netdev); + netdev_free(esp_priv[i]->netdev); + } + esp_priv[i] = NULL; + } + } +} + +/** + * @brief Set hardware type + * This may be used when driver need differntiation based on hardware + * @param None + * @retval None + */ +static void set_hardware_type(void) +{ + /* currently supporting only ESP32 type */ + hardware_type = HARDWARE_TYPE_ESP32; +} + +/** + * @brief Generate slave interrupt + * Notify slave about important event + * @param intr_no - Bit value of notification + * @retval register value on success + * STM_FAIL_INVALID_ARG on failure + */ +static stm_ret_t generate_slave_intr(uint8_t intr_no) +{ + uint32_t intr_mask = BIT(intr_no + ESP_SDIO_CONF_OFFSET); + stm_ret_t ret = STM_OK; + + if (intr_no >= BIT(ESP_MAX_HOST_INTERRUPT)) { + printf("Invalid slave interrupt number\n\r"); + return STM_FAIL_INVALID_ARG; + } + xSemaphoreTake(transmit_mux, portMAX_DELAY); + ret = STM32WriteReg(SDIO_FUNC_1, SDIO_REG(ESP_SLAVE_SCRATCH_REG_7), intr_mask); + xSemaphoreGive(transmit_mux); + + return ret; +} + +/** + * @brief I/O initialization command sequence + * @param None + * @retval + * STM_OK for success or failure from enum stm_ret_t + */ +static stm_ret_t io_init_seq(void) +{ + stm_ret_t retval = STM_OK; + + hard_delay(100000); + /* sdio host mode init */ + retval = sdio_host_init(); + if (retval != STM_OK) { + printf("sdio init error,ret:%d\n\r", retval); + return STM_FAIL; + } + /* notify slave application that host driver is ready */ + generate_slave_intr(ESP_OPEN_DATA_PATH); + + return STM_OK; +} + + + +/** Local functions **/ + +/** + * @brief Full duplex transaction sdio transaction for ESP32 hardware + * @param txbuff: TX sdio buffer + * @retval STM_OK for success or failure from enum stm_ret_t + */ +static stm_ret_t sdio_rx_esp32(void) +{ + stm_ret_t ret = STM_FAIL; + uint8_t *rxbuff = NULL; + interface_buffer_handle_t buf_handle = {0}; + struct esp_payload_header *payload_header = NULL; + uint16_t len = 0, offset = 0; + size_t size_read = MAX_SDIO_BUFFER_SIZE; + + /* Allocate rx buffer */ + rxbuff = (uint8_t *)malloc(MAX_SDIO_BUFFER_SIZE); + assert(rxbuff); + memset(rxbuff, 0, MAX_SDIO_BUFFER_SIZE); + + while (1) { + + /* Receive buffer from slave */ + ret = sdio_host_get_packet(rxbuff, MAX_SDIO_BUFFER_SIZE, + &size_read, RX_TIMEOUT_TICKS); + + if (ret == STM_FAIL_NOT_FOUND) { + printf("interrupt but no data can be read\n\r"); + break; + } else if (ret == STM_FAIL_TIMEOUT) { + continue; + } else if (ret && ret != STM_FAIL_NOT_FINISHED) { + printf("rx packet error: %d\n\r", ret); + continue; + } + +#if DEBUG_TRANSPORT + /* Read buffer is easily accesible here, before processing */ + //printf("data: %s size %u\n\r", (char*)(rxbuff), size_read); +#endif + + if (ret == STM_OK) { + break; + } + } + + if (ret == STM_OK) { + /* Transaction successful */ + + /* create buffer rx handle, used for processing */ + payload_header = (struct esp_payload_header *) rxbuff; + + /* Fetch length and offset from payload header */ + len = le16toh(payload_header->len); + offset = le16toh(payload_header->offset); + + if ((!len) || + (len > MAX_PAYLOAD_SIZE) || + (offset != sizeof(struct esp_payload_header))) { + + /* Free up buffer, as one of following - + * 1. no payload to process + * 2. input packet size > driver capacity + * 3. payload header size mismatch, + * wrong header/bit packing? + * */ + if (rxbuff) { + free(rxbuff); + rxbuff = NULL; + } + /* Give chance to other tasks */ + osDelay(0); + + } else { + + buf_handle.priv_buffer_handle = rxbuff; + buf_handle.free_buf_handle = free; + buf_handle.payload_len = len; + buf_handle.if_type = payload_header->if_type; + buf_handle.if_num = payload_header->if_num; + buf_handle.payload = rxbuff + offset; + if (pdTRUE != xQueueSend(from_slave_queue, + &buf_handle, portMAX_DELAY)) { + printf("Failed to send buffer\n\r"); + goto done; + } + } + } else { + goto done; + } + + return STM_OK; + +done: + /* error cases, return failure */ + if (rxbuff) { + free(rxbuff); + rxbuff = NULL; + } + return STM_FAIL; +} + +/** + * @brief Schedule sdio transaction if - + * a. valid TX buffer is ready at sdio host (STM) + * b. valid TX buffer is ready at sdio peripheral (ESP) + * c. Dummy transaction is expected from sdio peripheral (ESP) + * @param argument: Not used + * @retval None + */ + +static void sdio_recv(void) +{ + uint32_t intr_st = 0; + stm_ret_t ret = STM_OK; + + /* Get interrupt value */ + ret = sdio_host_get_intr(&intr_st); + if (ret || !intr_st) { + hard_delay(30); + return; + } + + /* Clear interrupt */ + xSemaphoreTake(transmit_mux, portMAX_DELAY); + /* Clear interrupt */ + ret = sdio_host_clear_intr(intr_st); + if (ret) { + //printf("clear intr %lx ret %x\n\r", intr_st, ret); + __SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_DATA_FLAGS); + } + xSemaphoreGive(transmit_mux); + + /* Fetch interrupt to check if new RX packet pending */ + if ((intr_st & HOST_SLC0_RX_NEW_PACKET_INT_ST)) { + + /* receive the packet */ + sdio_trans_func[hardware_type](); + } +} + +/** + * @brief Task for SDIO RX + * @param argument: Not used + * @retval None + */ +static void rx_task(void const* pvParameters) +{ + if (hardware_type == HARDWARE_TYPE_ESP32) { + printf("\n\rESP-Hosted for ESP32\n\r"); + } else { + printf("Unsupported slave hardware\n\r"); + assert(hardware_type != HARDWARE_TYPE_INVALID); + } + + for (;;) { + sdio_recv(); + } +} + +/** + * @brief RX processing task + * @param argument: Not used + * @retval None + */ +static void process_rx_task(void const* pvParameters) +{ + stm_ret_t ret = STM_OK; + interface_buffer_handle_t buf_handle = {0}; + uint8_t *payload = NULL, *serial_buf = NULL; + struct pbuf *buffer = NULL; + struct esp_priv_event *event = NULL; + struct esp_private *priv = NULL; + + while (1) { + ret = xQueueReceive(from_slave_queue, &buf_handle, portMAX_DELAY); + + if (ret != pdTRUE) { + continue; + } + + /* point to payload */ + payload = buf_handle.payload; + /* process received buffer for all possible interface types */ + if (buf_handle.if_type == ESP_SERIAL_IF) { + + serial_buf = (uint8_t *)malloc(buf_handle.payload_len); + assert(serial_buf); + + memcpy(serial_buf, payload, buf_handle.payload_len); + + /* serial interface path */ + serial_rx_handler(&buf_handle); + + } else if ((buf_handle.if_type == ESP_STA_IF) || + (buf_handle.if_type == ESP_AP_IF)) { + priv = get_priv(buf_handle.if_type, buf_handle.if_num); + + if (priv) { + buffer = (struct pbuf *)malloc(sizeof(struct pbuf)); + assert(buffer); + + buffer->len = buf_handle.payload_len; + buffer->payload = malloc(buf_handle.payload_len); + assert(buffer->payload); + + memcpy(buffer->payload, buf_handle.payload, + buf_handle.payload_len); + + netdev_rx(priv->netdev, buffer); + } + + } else if (buf_handle.if_type == ESP_PRIV_IF) { + buffer = (struct pbuf *)malloc(sizeof(struct pbuf)); + assert(buffer); + + buffer->len = buf_handle.payload_len; + buffer->payload = malloc(buf_handle.payload_len); + assert(buffer->payload); + + memcpy(buffer->payload, buf_handle.payload, + buf_handle.payload_len); + + + process_priv_communication(buffer); + /* priv transaction received */ + printf("Received INIT event\n\r"); + event = (struct esp_priv_event *) (payload); + if (event->event_type == ESP_PRIV_EVENT_INIT) { + /* User can re-use this type of transaction */ + if (sdio_drv_evt_handler_fp) { + sdio_drv_evt_handler_fp(TRANSPORT_ACTIVE); + } + } else { + /* User can re-use this type of transaction */ + } + } else if (buf_handle.if_type == ESP_TEST_IF) { +#if TEST_RAW_TP + update_test_raw_tp_rx_len(buf_handle.payload_len); +#endif + } else { + printf("unknown type %d \n\r", buf_handle.if_type); + } + /* Free buffer handle */ + /* When buffer offloaded to other module, that module is + * responsible for freeing buffer. In case not offloaded or + * failed to offload, buffer should be freed here + */ + if (buf_handle.free_buf_handle) { + buf_handle.free_buf_handle(buf_handle.priv_buffer_handle); + } + } +} + + +/** + * @brief Task for SDIO TX + * @param argument: Not used + * @retval None + */ +static void tx_task(void const* pvParameters) +{ + stm_ret_t ret = STM_OK; + struct esp_payload_header *payload_header; + uint8_t *sendbuf = NULL, *payload = NULL; + interface_buffer_handle_t buf_handle = {0}; + uint32_t total_len = 0; + + if (hardware_type == HARDWARE_TYPE_ESP32) { + printf("\n\rESP-Hosted for ESP32\n\r"); + } else { + printf("Unsupported slave hardware\n\r"); + assert(hardware_type != HARDWARE_TYPE_INVALID); + } + + for (;;) { + + /* Check if higher layers have anything to transmit */ + if (xQueueReceive(to_slave_queue, &buf_handle, portMAX_DELAY)) { + + if (!buf_handle.payload_len) + continue; + if (buf_handle.payload_len > MAX_PAYLOAD_SIZE) { + printf("Pkt dropped. Size[%u] > Max pkt size for SDIO interface[%u]\n\r", + buf_handle.payload_len, MAX_PAYLOAD_SIZE); + continue; + } + + total_len = buf_handle.payload_len + sizeof(struct esp_payload_header); + + /* Allocate tx buffer */ + sendbuf = (uint8_t *)malloc(total_len); + + if (!sendbuf) { + printf("malloc failed\n\r"); + goto done; + } + memset(sendbuf, 0, total_len); + + /* Attach interface header */ + payload_header = (struct esp_payload_header *) sendbuf; + payload = sendbuf + sizeof(struct esp_payload_header); + payload_header->len = htole16(buf_handle.payload_len); + payload_header->offset = htole16(sizeof(struct esp_payload_header)); + payload_header->if_type = buf_handle.if_type; + payload_header->if_num = buf_handle.if_num; + payload_header->reserved2 = 0; + + /* Copy payload */ + memcpy(payload, buf_handle.payload, buf_handle.payload_len); + /* Send packet */ + xSemaphoreTake(transmit_mux, portMAX_DELAY); + ret = sdio_host_send_packet(sendbuf, total_len); + xSemaphoreGive(transmit_mux); + + if (ret == STM_FAIL_TIMEOUT) { + printf("send timeout, maybe SDIO slave restart, reinit SDIO slave\n\r"); + } else if (ret != STM_OK) { + printf("sdio send err 0x%x\n\r", ret); + } + /* De-allocate tx buffer */ + free(sendbuf); + sendbuf = NULL; +done: + /* free allocated buffer */ + if (buf_handle.free_buf_handle) + buf_handle.free_buf_handle(buf_handle.priv_buffer_handle); + } + } +} + +/** Exported Function **/ + +/** + * @brief transport initializes + * @param transport_evt_handler_fp - event handler + * @retval None + */ +void transport_init(void(*transport_evt_handler_fp)(uint8_t)) +{ + stm_ret_t retval = STM_OK; + + /* Check if supported board */ + set_hardware_type(); + + /* register callback */ + sdio_drv_evt_handler_fp = transport_evt_handler_fp; + + retval = init_netdev(); + if (retval) { + printf("netdev failed to init\n\r"); + assert(retval==STM_OK); + } + + transmit_mux = xSemaphoreCreateMutex(); + assert(transmit_mux); + + sdio_recv_SemHandle = xSemaphoreCreateBinary(); + assert(sdio_recv_SemHandle); + + /* Queue - tx */ + to_slave_queue = xQueueCreate(TO_SLAVE_QUEUE_SIZE, + sizeof(interface_buffer_handle_t)); + assert(to_slave_queue); + + /* Queue - rx */ + from_slave_queue = xQueueCreate(FROM_SLAVE_QUEUE_SIZE, + sizeof(interface_buffer_handle_t)); + assert(from_slave_queue); + + /* Task - sdio rx task */ + osThreadDef(rx_thread, rx_task, + osPriorityAboveNormal, 0, RX_TASK_STACK_SIZE); + rx_task_id = osThreadCreate(osThread(rx_thread), NULL); + assert(rx_task_id); + + /* Task - RX processing */ + osThreadDef(process_rx_thread, process_rx_task, + osPriorityAboveNormal, 0, PROCESS_RX_TASK_STACK_SIZE); + process_rx_task_id = osThreadCreate(osThread(process_rx_thread), NULL); + assert(process_rx_task_id); + + /* Task - sdio tx task */ + osThreadDef(tx_thread, tx_task, + osPriorityAboveNormal, 0, TX_TASK_STACK_SIZE); + tx_task_id = osThreadCreate(osThread(tx_thread), NULL); + assert(tx_task_id); + + /* IO initialization towards slave */ + io_init_seq(); + +} + +/** + * @brief Send to slave via sdio + * @param iface_type - type of interface + * iface_num - interface number + * wbuffer - tx buffer + * wlen - size of wbuffer + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t send_to_slave(uint8_t iface_type, uint8_t iface_num, + uint8_t * wbuffer, uint16_t wlen) +{ + interface_buffer_handle_t buf_handle = {0}; + + if (!wbuffer || !wlen || (wlen > MAX_PAYLOAD_SIZE)) { + printf("write fail: buff(%p) 0? OR (0= sdio_esp_rx_bytes) { + len = (len + ESP_RX_BYTE_MAX - sdio_esp_rx_bytes)%ESP_RX_BYTE_MAX; + } else { + temp = ESP_RX_BYTE_MAX - sdio_esp_rx_bytes; + len = temp + len; + if (len > MAX_SDIO_BUFFER_SIZE) { + printf("%s: Len from slave[%lu] exceeds max [%d]\n", + __func__, len, MAX_SDIO_BUFFER_SIZE); + } + } +#if 0 + /* length is expected to be in multiple of ESP_BLOCK_SIZE */ + if(len&(ESP_BLOCK_SIZE-1)) + return STM_FAIL; +#endif + + if (rx_size) + *rx_size = len; + return STM_OK; +} + +/** + * @brief Get a packet from SDIO slave + * @param [out] out_data - Data output address + * size - The size of the output buffer, + * if the buffer is smaller than + * the size of data to receive from slave, + * the driver returns ESP_ERR_NOT_FINISHED + * [out] out_length - Output of length the data received from slave + * wait_ms - Time to wait before timeout, in ms + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_get_packet(void* out_data, size_t size, + size_t* out_length, uint32_t wait_ms) +{ + stm_ret_t err = STM_OK; + uint32_t len = 0, wait_time = 0, len_remain = 0; + uint8_t* start_ptr = NULL; + int len_to_send = 0, block_n = 0; + + if (size <= 0) { + printf("Invalid size:%d\n\r", size); + return STM_FAIL_INVALID_ARG; + } + + for (;;) { + err = esp_sdio_slave_get_rx_data_size(&len); + + if (err == STM_OK && len > 0) { +#if DEBUG_TRANSPORT + // printf("Expected length to be read %lu\n\n",len); +#endif + break; + } + + /* If no error and no data, retry */ + wait_time++; + + if (wait_time >= wait_ms) { + return STM_FAIL_TIMEOUT; + } + + hard_delay(1); + } + + if (len > size) { + printf("Pkt size to be read[%lu] > max sdio size supported[%u]\n\r",len, size); + return STM_OK; + } + + len_remain = len; + start_ptr = (uint8_t*)out_data; + + do { + /* currently driver supports only block size of 512 */ + + block_n = len_remain / ESP_BLOCK_SIZE; + + if (block_n != 0) { + len_to_send = ESP_BLOCK_SIZE; +#if DEBUG_TRANSPORT + // printf("block_n %u, len-to_send %lu\n\r",block_n,len_to_send); +#endif + + err = sdio_driver_read_blocks(SDIO_FUNC_1, + ESP_SLAVE_CMD53_END_ADDR - len_remain, + start_ptr, len_to_send, block_n); + } else { + len_to_send = len_remain; + /* though the driver supports to split packet of unaligned size into length + * of 4x and 1~3, we still get aligned size of data to get higher + * efficiency. The length is determined by the SDIO address, and the + * remaining will be ignored by the slave hardware + */ + err = sdio_driver_read_bytes(SDIO_FUNC_1, + ESP_SLAVE_CMD53_END_ADDR - len_remain, start_ptr, + (len_to_send + 3) & (~3), block_n); + } + + if (err) { +#if DEBUG_TRANSPORT + printf("Err from read bytes %x\n\r",err); +#endif + return err; + } + + start_ptr += len_to_send; + len_remain -= len_to_send; + } while (len_remain != 0); + + *out_length = len; + sdio_esp_rx_bytes += len; + if (sdio_esp_rx_bytes >= ESP_RX_BYTE_MAX) { + sdio_esp_rx_bytes -= ESP_RX_BYTE_MAX; + } + + return STM_OK; +} + +/** + * @brief Clear interrupt bits of SDIO slave + * @param intr_mask - Mask of interrupt bits to clear + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_clear_intr(uint32_t intr_mask) +{ + return sdio_driver_write_bytes(SDIO_FUNC_1, + SDIO_REG(ESP_SLAVE_INT_CLR_REG), (uint8_t*)&intr_mask, 4); +} + +/** + * @brief Get interrupt bits of SDIO slave + * + * @param intr_st - Output of the masked interrupt bits + * set to NULL if only raw bits are read + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_get_intr(uint32_t* intr_st) +{ + stm_ret_t ret = STM_OK; + + if (intr_st == NULL) { + return STM_FAIL_INVALID_ARG; + } + + if (intr_st != NULL) { + ret = sdio_driver_read_bytes(SDIO_FUNC_1, + SDIO_REG(ESP_SLAVE_INT_ST_REG), (uint8_t*)intr_st, 4, 0); + if (ret) { + return ret; + } + } + + return STM_OK; +} + +/** send functions **/ + +/** + * @brief Get available buffer to write to slave before transmit + * @param None + * @retval + * Number of buffers available at slave + */ +static uint32_t esp_sdio_host_get_buffer_size(void) +{ + stm_ret_t ret = STM_OK; + uint32_t len = 0; + + ret = sdio_driver_read_bytes(SDIO_FUNC_1, + SDIO_REG(ESP_SLAVE_TOKEN_RDATA), &len, 4, 0); + if (ret) { + printf("Read length error, ret=%d\n\r", ret); + return 0; + } + + len = (len >> ESP_SDIO_SEND_OFFSET) & ESP_TX_BUFFER_MASK; + len = (len + ESP_TX_BUFFER_MAX - sdio_esp_tx_bytes) % ESP_TX_BUFFER_MAX; +#if DEBUG_TRANSPORT + /*printf("%s len %lu \n\r", __func__, len);*/ +#endif + return len; +} + +/** + * @brief Send a interrupt signal to the SDIO slave + * @param intr_no - interrupt number, now only support 0 + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_send_intr(uint8_t intr_no) +{ + uint32_t intr_mask = 0; + if (intr_no >= MAX_SDIO_SCRATCH_REG_SUPPORTED) { + printf(" Error interrupt number\n\r"); + return STM_FAIL_INVALID_ARG; + } + + intr_mask = 0x1 << (intr_no + ESP_SDIO_CONF_OFFSET); + return STM32WriteReg(SDIO_FUNC_1, SDIO_REG(ESP_SLAVE_SCRATCH_REG_7), intr_mask); +} + +/** + * @brief Send a packet to the SDIO slave + * @param start - Start address of the packet to send + * length - Length of data to send, if the packet is over-size, + * the it will be divided into blocks and hold into different + * buffers automatically + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_send_packet(const void* start, uint32_t length) +{ + stm_ret_t err; + uint8_t* start_ptr = (uint8_t*)start; + uint32_t len_remain = length, num = 0, cnt = 300; +// printf("length received %d %lu \n\r", length, len_remain); + + int buffer_used, block_n = 0,len_to_send = 0; + + buffer_used = (length + ESP_BLOCK_SIZE - 1) / ESP_BLOCK_SIZE; + +#if 0 + while (1) { + num = esp_sdio_host_get_buffer_size(); +#if DEBUG_TRANSPORT + //printf("Buffer size %lu can be send, input len: %u, len_remain: %lu\n\r", num, length, len_remain); +#endif + + if (num * ESP_BLOCK_SIZE < length) { + if (!--cnt) { + printf("buff not enough: curr[%lu], exp[%d]\n\r", num, buffer_used); + return STM_FAIL_TIMEOUT; + } else { + printf("buff not enough: curr[%lu], exp[%d], retry..\n\r", num, buffer_used); + } + + hard_delay(1); + } else { + break; + } + } + +#endif + do { + /* Though the driver supports to split packet of unaligned size into + * length of 4x and 1~3, we still send aligned size of data to get + * higher effeciency. The length is determined by the SDIO address, and + * the remainning will be discard by the slave hardware + */ + block_n = len_remain / ESP_BLOCK_SIZE; + + if (block_n) { + len_to_send = block_n * ESP_BLOCK_SIZE; + err = sdio_driver_write_blocks(SDIO_FUNC_1, + ESP_SLAVE_CMD53_END_ADDR - len_remain, + start_ptr, len_to_send); + } else { + len_to_send = len_remain; + err = sdio_driver_write_bytes(SDIO_FUNC_1, + ESP_SLAVE_CMD53_END_ADDR - len_remain, + start_ptr, (len_to_send + 3) & (~3)); + } + + if (err) { + return err; + } + + start_ptr += len_to_send; + len_remain -= len_to_send; + } while (len_remain); + + if (sdio_esp_tx_bytes >= ESP_TX_BUFFER_MAX) { + sdio_esp_tx_bytes -= ESP_TX_BUFFER_MAX; + } + + sdio_esp_tx_bytes += buffer_used; + return STM_OK; +} diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_host.h b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_host.h new file mode 100644 index 0000000000..ac9f45af9a --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_host.h @@ -0,0 +1,96 @@ +// Copyright 2016-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** prevent recursive inclusion **/ +#ifndef __SDIO_HOST_H +#define __SDIO_HOST_H + +/** Includes **/ + +/** constants/macros **/ +#define MAX_SDIO_SCRATCH_REG_SUPPORTED 8 + +/** Exported Structures **/ + +/** Exported variables **/ + +/** Inline functions **/ + +/** Exported Functions **/ + +/** + * Init SDIO host and slave + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_init(void); + +/** + * Block until an SDIO interrupt is received + * + * Slave uses D1 line to signal interrupt condition to the host + * This function can be used to wait for the interrupt + * + * @param timeout - time to wait for the interrupt, in ms + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_wait_int(uint32_t timeout); + +/** Get interrupt bits of SDIO slave + * + * @param intr_st - Output of the masked interrupt bits. set to NULL if only raw bits are read + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_get_intr(uint32_t *intr_st); + +/** Clear interrupt bits of SDIO slave. All the bits set in the mask will be cleared, while other bits will stay the same + * + * @param intr_mask - Mask of interrupt bits to clear + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_clear_intr(uint32_t intr_mask); + +/** Get a packet from SDIO slave + * + * @param [out] out_data - Data output address + * size - The size of the output buffer, if the buffer is smaller than + * the size of data to receive from slave, the driver returns ``ESP_ERR_NOT_FINISHED`` + * [out] out_length - Output of length the data actually received from slave + * wait_ms - Time to wait before timeout, in ms + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_get_packet(void* out_data, size_t size, size_t *out_length, uint32_t wait_ms); + +/** Send a packet to the SDIO slave + * + * @param start - Start address of the packet to send + * length - Length of data to send, if the packet is over-size, + * the it will be divided into blocks and hold into different buffers automatically + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_send_packet(const void* start, uint32_t length); + +/** Send a interrupt signal to the SDIO slave + * + * @param intr_no - interrupt number, now only support 0 + * + * @retval STM_OK for success or failure from enum stm_ret_t + */ +stm_ret_t sdio_host_send_intr(uint8_t intr_no); + +#endif /* __SDIO_HOST_H */ diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_ll.c b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_ll.c new file mode 100644 index 0000000000..07fbbd8f1c --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_ll.c @@ -0,0 +1,981 @@ +/** + ****************************************************************************** + * File Name : sdio_ll.c + * Description : This file provides code for the configuration + * of the SDIO instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +//TODO: DMA is not working yet +#define WIFI_USEDMA (0) + +/** Includes **/ +#include "sdio_reg.h" +#include "sdio_ll.h" +#include "trace.h" +#include "FreeRTOS.h" +#include "semphr.h" +#include "gpio.h" + +#if WIFI_USEDMA +#include "stm32f4xx_ll_dma.h" +#endif + + +/** Constants/Macros **/ +#define SDMMC_R4_READYBIT BIT(31) +#define SDMMC_R4_ERRORBITS ((uint32_t)0x7F000000U) +#define SDMMC_R4_NOERROR ((uint32_t)0x20000000U) +#define SDMMC_R4_OCRBITS ((uint32_t)0x00FFFFFFU) + +#define ESP_DATA_MIN_ADDRESS (0x1e800) + +#define CMD52_WRITE BIT(31) +#define CMD52_READAFTERWRITE BIT(27) +#define CMD53_WRITE BIT(31) +#define CMD53_BLOCKMODE BIT(27) +#define CMD53_INCREMENTING BIT(26) +#define CMD53_TIMEOUT (10000000) +#define CCCR_BUS_WIDTH_4 (2<<0) + +#define SDIO_IO_RESET_FUNC (6) +#define SDIO_IO_RESET_VAL (0x8) +#define SDIO_CMD_SEND_RETRY (3) + +#define SDIO_CLK_DIV (238) + +/** Macros/Constants **/ +#define CHECK_SDIO_PRINT_ERR(ErR) {\ + if (ErR) { \ + printf("%s: %u err %lu\r\n",__func__,__LINE__,ErR); \ + } \ +} + +/** Global Variables **/ +static SDIO_CmdInitTypeDef sdio_cmd = {0}; +static SemaphoreHandle_t semahandle = {0}; +static SD_HandleTypeDef hsd = {0}; + +/** External variables **/ +extern SemaphoreHandle_t sdio_recv_SemHandle; + + +/** function definition **/ + +/** Local Functions **/ + +/** + * @brief Calculates clock divider to be used from expected clock + * frequency and hardware reference frequency + * + * @param freq - Input frequency for which divider to be calculated + * preal - [OUT] Frequency to be set after calculating divider + * @retval Divider value + */ +static uint8_t CalcClockDivider(uint32_t freq, uint32_t *preal) +{ + int divider; + uint32_t sdioclk; + + sdioclk = HAL_RCC_GetPCLK2Freq(); + if (freq == 0) + freq = 1; + + divider = sdioclk / freq - 2; + if (sdioclk % freq != 0) + divider++; + if (divider < 0) + divider = 0; + else if (divider > 255) + divider = 255; + + if (preal) { + *preal = sdioclk / (divider + 2); +#if DEBUG_TRANSPORT + printf("sdioclk=%luHz\n\rreq_freq=%luHz\n\rout_freq=%luHz\n\rdiv=%d\n\r", + sdioclk, freq, *preal, divider); + } else { + printf("sdioclk=%luHz\n\rreq_freq=%luHz\n\rdiv=%d\n\r", + sdioclk, freq, divider); +#endif + } + return divider & 0xff; +} + +/** + * @brief Send CMD52 + * + * @param func - SDIO function + * addr - SDIO address + * data - data byte to be read/write + * flag - SDIO CMD52 flags + * @retval None + */ +static void SendCMD52(uint8_t func, uint32_t addr, uint8_t data, uint32_t flags) +{ + sdio_cmd.Argument = (func << 28) | (addr << 9) | data | flags; + sdio_cmd.CmdIndex = 52; + sdio_cmd.CPSM = SDIO_CPSM_ENABLE; + sdio_cmd.Response = SDIO_RESPONSE_SHORT; + sdio_cmd.WaitForInterrupt = SDIO_WAIT_NO; + SDIO_SendCommand(SDIO, &sdio_cmd); +} + +/** + * @brief Send CMD53 + * + * @param func - SDIO function + * addr - SDIO address + * count - [IN] number of bytes/blocks to be set to read/write + * flag - SDIO CMD53 flags + * @retval None + */ +static void SendCMD53(uint8_t func, uint32_t addr, uint16_t count, uint32_t flags) +{ + sdio_cmd.Argument = (func << 28) | (addr << 9) | (count & 0x1ff) | flags; + sdio_cmd.CmdIndex = 53; + sdio_cmd.CPSM = SDIO_CPSM_ENABLE; + sdio_cmd.Response = SDIO_RESPONSE_SHORT; + sdio_cmd.WaitForInterrupt = SDIO_WAIT_NO; + SDIO_SendCommand(SDIO, &sdio_cmd); +} + +/** + * @brief Initialize GPSIO in SDIO AF + * Please check sdio_reg.h for pin definitions + * + * @param None + * @retval None + */ +static void SdioGpioInit(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + __HAL_RCC_SDIO_GPIO_ENABLE(); + + GPIO_InitStruct.Pin = USR_SDIO_D0_Pin_Pin | USR_SDIO_D1_Pin_Pin | \ + USR_SDIO_D2_Pin_Pin|USR_SDIO_D3_Pin_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = USR_SDIO_CLK_Pin_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(USR_SDIO_CLK_Pin_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = USR_SDIO_CMD_Pin_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; + HAL_GPIO_Init(USR_SDIO_CMD_Pin_GPIO_Port, &GPIO_InitStruct); +} + +/** + * @brief This function checks if data read/written is failed and for what cause + * + * @param msg_title - function name, who is checking + * line - line number, who is checking + * @retval 0 on success, number of err count otherwise + */ +static int CheckError(const char *msg_title, uint32_t line) +{ + int err = 0; + + if ((__SDIO_GET_FLAG(SDIO, SDIO_FLAG_CCRCFAIL) != RESET) && + (sdio_cmd.CmdIndex != 5)) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_CCRCFAIL); + err++; + printf("%s:%lu CMD%lu CRC failed!\n\r", msg_title, line, sdio_cmd.CmdIndex); + } + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_CTIMEOUT) != RESET) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_CTIMEOUT); + err++; +#if !DEBUG_TRANSPORT + if(sdio_cmd.CmdIndex != 5) +#endif + printf("%s:%lu CMD%lu timeout!\n\r", msg_title, line, sdio_cmd.CmdIndex); + } + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_DCRCFAIL) != RESET) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_DCRCFAIL); + err++; + printf("%s:%lu data CRC failed!\n\r", msg_title, line); + } + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_DTIMEOUT) != RESET) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_DTIMEOUT); + err++; + printf("%s:%lu data timeout!\n\r", msg_title, line); + } +#if defined(SDIO_STA_STBITERR) + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_STBITERR) != RESET) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_STBITERR); + err++; + printf("%s:%lu start bit error!\n\r", msg_title, line); + } +#endif + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_TXUNDERR) != RESET) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_TXUNDERR); + err++; + printf("%s:%lu data underrun!\n\r", msg_title, line); + } + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_RXOVERR) != RESET) + { + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_RXOVERR); + err++; + printf("%s:%lu data overrun!\n\r", msg_title, line); + } +#if WIFI_USEDMA + if (LL_DMA_IsActiveFlag_TE4(DMA2)) + { + LL_DMA_ClearFlag_TE4(DMA2); + err++; + printf("%s:%lu DMA transfer error!\n\r", msg_title, line); + } +#endif + return err; +} + +/** + * @brief This function checks if response recieved + * It retries till SDIO_CMD_SEND_RETRY times to send command for getting response + * + * @param SDIOx - SDIO peripheral + * @retval 0 on success + */ +static int WaitForResponse(const char *msg_title, uint32_t line) +{ + uint8_t cmd_retry = 0; + int err = 0; + /* TODO: Give breathing space for command response + * Although, this is trade-off for higher response time + * Need to get proper fix for this + * */ + hard_delay(1); + + do { + if (cmd_retry == SDIO_CMD_SEND_RETRY) + break; + + if (cmd_retry != 0) { + /* re-send */ + SDIO_SendCommand(SDIO, &sdio_cmd); + } + cmd_retry++; + + /* Wait till command send completed */ + while (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_CMDACT) != RESET); + err = CheckError(msg_title, line); + + /* Check untill no response condition */ + } while (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_CMDREND) == RESET); + __SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_CMD_FLAGS); + + return err; +} + + +/** + * @brief This function checks if command is sent successfully or not + * + * @param SDIOx - SDIO peripheral + * @retval 0 on success + */ +static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx) +{ + /* 8 is the number of required instructions cycles for the below loop statement + * The SDIO_CMDTIMEOUT is expressed in ms + */ + register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + + }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT)); + + /* Clear all the static flags */ + __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_CMD_FLAGS); + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Low level function to init SDIO peripheral + * + * This function may need to be ported if the host/slave hardware is changed + * + * @param sd_init - structure holds the SDIO parameters to initialize slave + * @retval None + */ +static void port_MX_SDIO_SD_Init(SD_InitTypeDef sd_init) +{ + hsd.Instance = SDIO; + hsd.Init.ClockEdge = sd_init.ClockEdge; + hsd.Init.ClockBypass = sd_init.ClockBypass; + hsd.Init.ClockPowerSave = sd_init.ClockPowerSave; + hsd.Init.BusWide = sd_init.BusWide; + hsd.Init.HardwareFlowControl = sd_init.HardwareFlowControl; + hsd.Init.ClockDiv = sd_init.ClockDiv; + HAL_SD_Init(&hsd); +} + +/** + * @brief Low level function to init SDIO peripheral + * + * This function may need to be ported if the host/slave hardware is changed + * + * @param init_para - structure holds the SDIO parameters to initialize slave + * @retval STM_OK for success or failure from enum stm_ret_t + */ +static stm_ret_t SdioDriverInit(SD_InitTypeDef init_para) +{ + SD_InitTypeDef Init = {0}; + uint16_t sdio_rca; + uint8_t bus_width; + __HAL_RCC_SDIO_CLK_ENABLE(); +#if WIFI_USEDMA + __HAL_RCC_DMA2_CLK_ENABLE(); +#endif + + __SDIO_ENABLE_IT(SDIO, SDIO_IT_SDIOIT); + + /* Default SDIO peripheral config for SD card initialization */ + /* Keep clock lower (<400k) for initial command sequence */ + Init.ClockDiv = SDIO_CLK_DIV; + + Init.BusWide = init_para.BusWide; + + /* Initialize SDIO peripheral interface with default config */ + port_MX_SDIO_SD_Init(Init); + + /* SDIO interrupt Init */ + HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(SDIO_IRQn); + + /* Enable SDIO */ + __SDIO_OPERATION_ENABLE(SDIO); + +#if WIFI_USEDMA + /* Enable DMA */ + __SDIO_DMA_ENABLE(SDIO); +#endif + + /** SDIO IO specific slave initialization command sequence **/ + + /* SDIO slave reset - I/O reset: CCCR I/O Abort register bit 3 */ + SendCMD52(SDIO_FUNC_0, SDIO_IO_RESET_FUNC, SDIO_IO_RESET_VAL, CMD52_WRITE); + + /* Command 0 - SD reset */ + sdio_cmd.Argument = 0U; + sdio_cmd.CmdIndex = 0; + sdio_cmd.Response = SDIO_RESPONSE_NO; + sdio_cmd.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmd.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(SDIO, &sdio_cmd); + CHECK_SDIO_PRINT_ERR(SDMMC_GetCmdError(SDIO)); + + /* Command 5 - IO_SEND_OP_COND */ + sdio_cmd.Argument = 0U; + sdio_cmd.CmdIndex = 5; + sdio_cmd.Response = SDIO_RESPONSE_SHORT; + sdio_cmd.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmd.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(SDIO, &sdio_cmd); + WaitForResponse(__FUNCTION__,__LINE__); + HAL_Delay(20); + + /* Command 5 - Set VDD Voltage Window: 3.2~3.4V */ +// sdio_cmd.Argument = 0x200000; + sdio_cmd.Argument = 0x00ff8000; + + SDIO_SendCommand(SDIO, &sdio_cmd); + WaitForResponse(__FUNCTION__,__LINE__); + SDIO_GetResponse(SDIO, SDIO_RESP1); + + /* Command 3 - Get WiFi address (CMD3: SEND_RELATIVE_ADDR, + * Ask the card to publish a new relative address (RCA)) */ + sdio_cmd.Argument = 0; + sdio_cmd.CmdIndex = 3; + SDIO_SendCommand(SDIO, &sdio_cmd); + WaitForResponse(__FUNCTION__,__LINE__); + sdio_rca = SDIO_GetResponse(SDIO, SDIO_RESP1) >> 16; +#if DEBUG_TRANSPORT + printf("Relative Card Address: 0x%04x\n\r", sdio_rca); +#endif + + /* Command 7 - Select WiFi (SELECT/DESELECT_CARD) */ + //sdio_cmd.Argument = sdio_rca << 16; + sdio_cmd.Argument = 0x00010000; + sdio_cmd.CmdIndex = 7; + SDIO_SendCommand(SDIO, &sdio_cmd); + WaitForResponse(__FUNCTION__,__LINE__); +#if DEBUG_TRANSPORT + printf("Card selected! RESP1_%08lx\n\r", SDIO_GetResponse(SDIO, SDIO_RESP1)); +#endif + + /* Above sequence is needed while communicating to IO only device. + * In case of failure/timeouts despite of maximum retry, IO would be unusable + */ + + SDIO_Init(SDIO, init_para); + + bus_width = STM32ReadReg(SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH); + + if(init_para.BusWide == SDIO_BUS_WIDE_4B){ +#if DEBUG_TRANSPORT + printf("Use 4bit bus width\n\r"); +#endif + bus_width |= CCCR_BUS_WIDTH_4; + }else if(init_para.BusWide == SDIO_BUS_WIDE_1B){ +#if DEBUG_TRANSPORT + printf("Use 1bit bus width\n\r"); +#endif + bus_width &= ~CCCR_BUS_WIDTH_4; + } else { + printf("Illegal bus width\n\r"); + return STM_FAIL; + } + //STM32WriteReg(SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH, bus_width); + STM32WriteReg(SDIO_FUNC_0, SD_IO_CCCR_BUS_WIDTH, 0x02); + STM32WriteReg(SDIO_FUNC_0, 0x02, 0x02); + STM32WriteReg(SDIO_FUNC_0, 0x10, 0x00); + STM32WriteReg(SDIO_FUNC_0, 0x11, 0x02); + STM32WriteReg(SDIO_FUNC_0, 0x110, 0x00); + STM32WriteReg(SDIO_FUNC_0, 0x111, 0x02); + + return STM_OK; +} + +/** + * @brief Calculate block number for expected number of bytes + * + * @param func - SDIO function + * psize - [IN] number of bytes + * write_flag - In case called from Write functions + * @retval Number of blocks + */ +static uint16_t GetBlockNum(uint8_t func, uint32_t *psize, + uint8_t write_flag, SDIO_DataInitTypeDef *sdio_data) + +{ + uint16_t block_num = 0; + uint16_t blocksize = ESP_BLOCK_SIZE; + + if(*psize == 4) { + + sdio_data->DataBlockSize = SDIO_DATABLOCK_SIZE_4B; + + } else if (*psize >= blocksize|| write_flag) { + + sdio_data->DataBlockSize = SDIO_DATABLOCK_SIZE_512B; + + block_num = *psize / blocksize; + if (*psize % blocksize != 0) + block_num++; + *psize = block_num * blocksize; + + } else { + + sdio_data->DataBlockSize = SDIO_DATABLOCK_SIZE_1B; + *psize = (*psize + 3) & ~3; + } + + return block_num; +} + +/** Exported Function **/ + +/** + * @brief Intended Empty function + * + * This function will be automatically invoked by default + * We want to delay the initialization and do it manually + * + * @param None + * @retval None + */ +void MX_SDIO_SD_Init(void) +{ + /* This function is set blank intentionally. + * IOC file import generates main.c, which invokes + * this function automatically. + * As ST driver does not correctly initialize I/O part, + * Init sequence and SDIO initialization is done manually. + * While porting to another hardware, + * may want to remove this definition to avoid duplicate + */ +} + +/** + * @brief Write data of exp size with expected SDIO register address and SDIO function + * + * This function checks if slave has sufficient buffer to write the data + * If yes, it further writes data to specified register. + * Note : data greater than 4 bytes is expected to be aligned of ESP_BLOCK_SIZE + * + * @param func - SDIO function + * addr - SDIO address + * data - Buffer to written + * size - Buffer size in bytes + * @retval STM_OK for success or failure from enum stm_ret_t + */ +int STM32WriteData(uint8_t func, uint32_t addr, const void *data, uint32_t len) +{ + int i, err = 0; + uint32_t size = len; + uint16_t block_num = 0; + static SDIO_DataInitTypeDef sdio_data = {0}; + uint32_t cmd53_flags = CMD53_WRITE; + + /* Data timeout is kept sufficiently high + * Depending upon use case, this could be optimized lower + * */ + sdio_data.DataTimeOut = SDMMC_DATATIMEOUT; + +#if WIFI_USEDMA + LL_DMA_InitTypeDef dma; +#else + const uint32_t *p = data; +#endif + + if ((uintptr_t)data & 3) + { + printf("%s: data must be 4-byte aligned!\n\r", __FUNCTION__); + return STM_FAIL_ALIGNMENT; + } + if (size == 0) + { + printf("%s: size cannot be 0!\n\r", __FUNCTION__); + return STM_FAIL_INVALID_ARG; + } + xSemaphoreTake(semahandle, portMAX_DELAY); + + block_num = GetBlockNum(func, &size, 1, &sdio_data); + + cmd53_flags |= CMD53_INCREMENTING; + +#if WIFI_USEDMA + //SDIO->DCTRL = SDIO_DCTRL_SDIOEN | SDIO_DCTRL_DMAEN; + SDIO->DCTRL = SDIO_DCTRL_DMAEN; +#else + //SDIO->DCTRL = SDIO_DCTRL_SDIOEN; + //SDIO->DCTRL = 0; +#endif + do { + if (block_num) + { + sdio_data.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + SendCMD53(func, addr, block_num, cmd53_flags | CMD53_BLOCKMODE); + } + else + { + sdio_data.TransferMode = SDIO_TRANSFER_MODE_STREAM; + SendCMD53(func, addr, size, cmd53_flags); + } + } while(WaitForResponse(__FUNCTION__,__LINE__)); + + /* TODO: This delay is needed so that reader task would + * get breathing time for checking new packets + * */ + while((uint32_t)HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8) == (uint32_t)RESET); +#if DEBUG_TRANSPORT + //printf("CMD53 response\n\r"); +#endif + +#if WIFI_USEDMA + + dma.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma.MemoryOrM2MDstAddress = (uint32_t)data; + dma.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma.Mode = LL_DMA_MODE_NORMAL; + dma.NbData = size / 4; + dma.PeriphOrM2MSrcAddress = (uint32_t)&SDIO->FIFO; + dma.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma.Priority = LL_DMA_PRIORITY_VERYHIGH; + LL_DMA_Init(DMA2, LL_DMA_CHANNEL_4, &dma); + LL_DMA_EnableChannel(DMA2, LL_DMA_CHANNEL_4); +#endif + + sdio_data.DataLength = size; + sdio_data.DPSM = SDIO_DPSM_ENABLE; + sdio_data.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; + SDIO_ConfigData(SDIO, &sdio_data); + + +#if !WIFI_USEDMA + while (size > 0) + { + while (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_TXFIFOF) != RESET); + size -= 4; + /* Write 4 bytes */ + SDIO_WriteFIFO(SDIO, (uint32_t *)p); + p++; + /* Wait untill there is space in FIFO */ + err += CheckError(__FUNCTION__,__LINE__); + if (err) { +#if DEBUG_TRANSPORT + printf("err while writing FIFO\n\r"); +#endif + break; + } + } +#endif + + while (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_TXACT) != RESET); + + i = 0; + while (1) + { + if ((__SDIO_GET_FLAG(SDIO, SDIO_FLAG_DATAEND)) || + (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_DBCKEND))) + break; + + err += CheckError(__FUNCTION__,__LINE__); + if (err) { +#if DEBUG_TRANSPORT + printf("err before completing DATA END\n\r"); +#endif + break; + } + + i++; + if (i == CMD53_TIMEOUT) + { + printf("%s: timeout!\n\r", __FUNCTION__); + err++; + break; + } + } + +#if DEBUG_TRANSPORT + //printf("\n\rData:\n\r===> Data : %s\n\r",(char*)data); +#endif + + sdio_data.DPSM = SDIO_DPSM_DISABLE; + SDIO_ConfigData(SDIO, &sdio_data); +#if WIFI_USEDMA + /* Clear DMA flag */ + LL_DMA_ClearFlag_GI4(DMA2); + /* Close DMA */ + LL_DMA_DisableChannel(DMA2, LL_DMA_CHANNEL_4); +#endif + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_DATAEND | SDIO_FLAG_DBCKEND); + //SDIO->DCTRL = SDIO_DCTRL_DTEN | SDIO_DCTRL_RWSTART | + // SDIO_DCTRL_SDIOEN | SDIO_DCTRL_DTDIR; + + err += CheckError(__FUNCTION__,__LINE__); + xSemaphoreGive(semahandle); + if (err != 0) { +#if DEBUG_TRANSPORT + printf("err while writing\n\r"); +#endif + return STM_FAIL; + } + return STM_OK; +} + +/** + * @brief Write byte value to expected SDIO register address and SDIO function + * + * This function triggers CMD52 to write byte to expected SDIO register + * For multi-byte write, please refer STM32WriteData + * + * @param func - SDIO function + * addr - SDIO address + * value - Byte to be written + * @retval SDIO R1 response + */ +uint8_t STM32WriteReg(uint8_t func, uint32_t addr, uint8_t value) +{ + SendCMD52(func, addr, value, CMD52_WRITE | CMD52_READAFTERWRITE); + WaitForResponse(__FUNCTION__,__LINE__); + return SDIO_GetResponse(SDIO, SDIO_RESP1) & 0xff; +} + +/** + * @brief Read byte value with expected SDIO register address and SDIO function + * + * This function triggers CMD52 to read byte from expected SDIO register + * For multi-byte read, please refer STM32ReadData + * + * @param func - SDIO function + * addr - SDIO address + * @retval Byte read + */ +uint8_t STM32ReadReg(uint8_t func, uint32_t addr) +{ + SendCMD52(func, addr, 0, 0); + WaitForResponse(__FUNCTION__,__LINE__); + return SDIO_GetResponse(SDIO, SDIO_RESP1) & 0xff; +} + +/** + * @brief Read data of specified size with expected SDIO register address and SDIO function + * + * This function should be called only after HOST_SLC0_RX_NEW_PACKET_INT_ST is set + * by the slave on ESP_SLAVE_INT_ST_REG register. + * This function checks how many bytes to be read first, + * followed by read in ESP_BLOCK_SIZE steps + * Note : Slave should take care if data greater than 4 bytes, it is expected to + * write in ESP_BLOCK_SIZE alignement + * + * @param func - SDIO function + * addr - SDIO address + * data - Buffer to store input data + * size - Num of bytes to read + * @retval STM_OK for success or failure from enum stm_ret_t + */ +int STM32ReadData(uint8_t func, uint32_t addr, void *data, + uint32_t size, uint8_t multi_blocks) +{ + int i, err = 0; + uint16_t block_num = 0; + static SDIO_DataInitTypeDef sdio_data = {0}; + uint32_t cmd53_flags = 0; + + /* Data timeout is kept sufficiently high + * Depending upon use case, this could be optimized lower + * */ + sdio_data.DataTimeOut = SDMMC_DATATIMEOUT; + +#if WIFI_USEDMA + LL_DMA_InitTypeDef dma; +#else + uint32_t *p = data; +#endif + + if ((uintptr_t)data & 3) + { + printf("%s: data must be 4-byte aligned!\n\r", __FUNCTION__); + return STM_FAIL_ALIGNMENT; + } + if (size == 0) + { + printf("%s: size cannot be 0!\n\r", __FUNCTION__); + return STM_FAIL_INVALID_ARG; + } + + xSemaphoreTake(semahandle, portMAX_DELAY); + + block_num = GetBlockNum(func, &size, 0, &sdio_data); +#if DEBUG_TRANSPORT + if (size > 4) { + // printf("size after getblocknum: %lu\n\r",size); + } +#endif + +#if WIFI_USEDMA + //SDIO->DCTRL = SDIO_DCTRL_SDIOEN | SDIO_DCTRL_DMAEN; + SDIO->DCTRL = SDIO_DCTRL_DMAEN; + //__SDIO_DISABLE_IT(SDIO, SDIO_FLAG_SDIOIT); +#else + //SDIO->DCTRL = 0; +#endif + +#if WIFI_USEDMA + dma.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; + dma.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma.Mode = LL_DMA_MODE_NORMAL; + dma.NbData = size / 4; + dma.PeriphOrM2MSrcAddress = (uint32_t)&SDIO->FIFO; + dma.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma.Priority = LL_DMA_PRIORITY_VERYHIGH; + dma.MemoryOrM2MDstAddress = (uint32_t)data; + dma.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + + LL_DMA_Init(DMA2, LL_DMA_CHANNEL_4, &dma); + LL_DMA_EnableChannel(DMA2, LL_DMA_CHANNEL_4); +#endif + cmd53_flags |= CMD53_INCREMENTING; + + // May need in case of DMA? + if (block_num) + { + sdio_data.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + SendCMD53(func, addr, block_num, cmd53_flags | CMD53_BLOCKMODE); + } + else + { + sdio_data.TransferMode = SDIO_TRANSFER_MODE_STREAM; + SendCMD53(func, addr, size, cmd53_flags); + } + + sdio_data.DataLength = size; + sdio_data.DPSM = SDIO_DPSM_ENABLE; + sdio_data.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + SDIO_ConfigData(SDIO, &sdio_data); + + { + volatile int delay = 50; + while(delay--); + } + +#if !WIFI_USEDMA + int timeout_not_reached = 1000000; + while (size > 0 && timeout_not_reached) + { + if (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_RXDAVL) != RESET) + { + size -= 4; + *p++ = SDIO_ReadFIFO(SDIO); + + } + else + { + + err += CheckError(__FUNCTION__,__LINE__); + if (err) { +#if DEBUG_TRANSPORT + printf("Err while Reading from FIFO\n\r"); +#endif + break; + } + } + timeout_not_reached--; + } + if (!timeout_not_reached) { + printf("timed out while reading!!!\n\r"); + /* try to rectify the situation */ + sdio_data.DPSM = SDIO_DPSM_DISABLE; + SDIO_ConfigData(SDIO, &sdio_data); + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_CMDREND | \ + SDIO_FLAG_DATAEND | SDIO_FLAG_DBCKEND); + __SDIO_CLEAR_FLAG(SDIO, SDIO_STATIC_CMD_FLAGS); + xSemaphoreGive(semahandle); + return STM_FAIL; + } +#endif + + i = 0; + while (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_CMDACT) != RESET || + __SDIO_GET_FLAG(SDIO, SDIO_FLAG_DATAEND) == RESET) + { + err += CheckError(__FUNCTION__,__LINE__); + if (err) + break; + + i++; + if (i == CMD53_TIMEOUT) + { + printf("%s: timeout!\n\r", __FUNCTION__); + err++; + break; + } + } + + { + volatile int delay = 50; + while(delay--); + } + + /* Disable DPSM */ + sdio_data.DPSM = SDIO_DPSM_DISABLE; + SDIO_ConfigData(SDIO, &sdio_data); + +#if WIFI_USEDMA + LL_DMA_ClearFlag_GI4(DMA2); + LL_DMA_DisableChannel(DMA2, LL_DMA_CHANNEL_4); +#endif + + __SDIO_CLEAR_FLAG(SDIO, SDIO_FLAG_CMDREND | \ + SDIO_FLAG_DATAEND | SDIO_FLAG_DBCKEND); + + //SDIO->DCTRL = SDIO_DCTRL_DTEN | SDIO_DCTRL_RWSTART | + // SDIO_DCTRL_SDIOEN | SDIO_DCTRL_DTDIR; + + if(addr > ESP_DATA_MIN_ADDRESS) { + __SDIO_ENABLE_IT(SDIO, SDIO_FLAG_SDIOIT); + } + + err += CheckError(__FUNCTION__,__LINE__); + xSemaphoreGive(semahandle); + if (err != 0) + return STM_FAIL; + return STM_OK; +} + +/** + * @brief Initialization for SDIO peripheral + * + * This function communicates with slave peripheral and initializes with + * expected frequency and bus width + * + * @param sdio_init - structure holds the SDIO parameters to initialize slave + * @retval None + */ +void STM32SdioInit(sdio_init_t sdio_init) +{ + uint32_t freq; + SD_InitTypeDef Init; + SdioGpioInit(); + semahandle = xSemaphoreCreateMutex(); + assert(semahandle); + Init.ClockEdge = SDIO_CLOCK_EDGE_FALLING; + Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; + Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; + if(sdio_init.width == WIDTH_4){ + Init.BusWide = SDIO_BUS_WIDE_4B; + } else { + Init.BusWide = SDIO_BUS_WIDE_1B; + } + Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE; + Init.ClockDiv = CalcClockDivider(sdio_init.clock, &freq); + + if (SdioDriverInit(Init)) + { + printf("STM32 SDIO driver init error\n\r"); + return; + } +} + +/** + * @brief This function handles SDIO interrupt request + * @param hsd: Pointer to SD handle + * @retval None + */ +void SDIO_IRQHandler(void) +{ + uint32_t intrpt_raised = (__SDIO_GET_FLAG(SDIO, SDIO_FLAG_SDIOIT) != RESET); + BaseType_t xHigherPriorityTaskWoken; + + if(intrpt_raised){ + + __HAL_SD_DISABLE_IT(&hsd, SDIO_IT_SDIOIT); + /* Unblock receive task, to check if interrupt is servable */ + xSemaphoreGiveFromISR(sdio_recv_SemHandle,&xHigherPriorityTaskWoken); + if(xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_ll.h b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_ll.h new file mode 100644 index 0000000000..884d596049 --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_ll.h @@ -0,0 +1,110 @@ +/** + ****************************************************************************** + * File Name : sdio_ll.h + * Description : This file provides code for the configuration + * of the SDIO instances. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SDIO_LL_H +#define __SDIO_LL_H + +/** Includes **/ + +/** Constants/Macros **/ +typedef enum { + WIDTH_1, // 1 Bit + WIDTH_4 // 4 Bit +} sdio_width_t; + +/** Structures/Unions **/ +typedef struct { + sdio_width_t width; + uint32_t clock; +}sdio_init_t; + +/** function declarations **/ +/** + * @brief Initialization for SDIO peripheral + * + * This function communicates with slave peripheral and initializes with + * expected frequency and bus width + * + * @param sdio_init - structure holds the SDIO parameters to initialize slave + * @retval None + */ +void STM32SdioInit(sdio_init_t sdio_init); + +/** + * @brief Read byte value with expected SDIO register address and SDIO function + * + * This function triggers CMD52 to read byte from expected SDIO register + * For multi-byte read, please refer STM32ReadData + * + * @param func - SDIO function + * addr - SDIO address + * @retval Byte read + */ +uint8_t STM32ReadReg(uint8_t func, uint32_t addr); + +/** + * @brief Write byte value to expected SDIO register address and SDIO function + * + * This function triggers CMD52 to write byte to expected SDIO register + * For multi-byte write, please refer STM32WriteData + * + * @param func - SDIO function + * addr - SDIO address + * value - Byte to be written + * @retval SDIO R1 response + */ +uint8_t STM32WriteReg(uint8_t func, uint32_t addr, uint8_t value); + +/** + * @brief Write data of exp size with expected SDIO register address and SDIO function + * + * This function checks if slave has sufficient buffer to write the data + * If yes, it further writes data to specified register. + * Note : data greater than 4 bytes is expected to be aligned of ESP_BLOCK_SIZE + * + * @param func - SDIO function + * addr - SDIO address + * data - Buffer to written + * size - Buffer size in bytes + * @retval STM_OK for success or failure from enum stm_ret_t + */ +int STM32WriteData(uint8_t func, uint32_t addr, const void *data, uint32_t size); + +/** + * @brief Read data of specified size with expected SDIO register address and SDIO function + * + * This function should be called only after HOST_SLC0_RX_NEW_PACKET_INT_ST is set + * by the slave on ESP_SLAVE_INT_ST_REG register. + * This function checks how many bytes to be read first, + * followed by read in ESP_BLOCK_SIZE steps + * Note : Slave should take care if data greater than 4 bytes, it is expected to + * write in ESP_BLOCK_SIZE alignement + * + * @param func - SDIO function + * addr - SDIO address + * data - Buffer to store input data + * size - Num of bytes to read + * @retval STM_OK for success or failure from enum stm_ret_t + */ +int STM32ReadData(uint8_t func, uint32_t addr, void *data, uint32_t size, uint8_t multi_blocks); + +#endif /*__SDIO_LL_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_reg.h b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_reg.h new file mode 100644 index 0000000000..88243e97ab --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/sdio/sdio_reg.h @@ -0,0 +1,174 @@ +/* + * Espressif Systems Wireless LAN device driver + * + * Copyright (C) 2015-2021 Espressif Systems (Shanghai) PTE LTD + * + * This software file (the "File") is distributed by Espressif Systems (Shanghai) + * PTE LTD under the terms of the GNU General Public License Version 2, June 1991 + * (the "License"). You may use, redistribute and/or modify this File in + * accordance with the terms and conditions of the License, a copy of which + * is available by writing to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the + * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE + * ARE EXPRESSLY DISCLAIMED. The License provides additional details about + * this warranty disclaimer. + */ + +#ifndef __SDIO_REG_H +#define __SDIO_REG_H + +/** Includes **/ +#include "common.h" + +/** constants/macros **/ +#define SD_IO_CCCR_FN_ENABLE 0x02 +#define SD_IO_CCCR_FN_READY 0x03 +#define SD_IO_CCCR_INT_ENABLE 0x04 +#define SD_IO_CCCR_BUS_WIDTH 0x07 + +#define CCCR_BUS_WIDTH_ECSI (1<<5) + +#define SD_IO_CCCR_BLKSIZEL 0x10 +#define SD_IO_CCCR_BLKSIZEH 0x11 + +/* Interrupt Status */ +#define ESP_SLAVE_BIT0_INT BIT(0) +#define ESP_SLAVE_BIT1_INT BIT(1) +#define ESP_SLAVE_BIT2_INT BIT(2) +#define ESP_SLAVE_BIT3_INT BIT(3) +#define ESP_SLAVE_BIT4_INT BIT(4) +#define ESP_SLAVE_BIT5_INT BIT(5) +#define ESP_SLAVE_BIT6_INT BIT(6) +#define ESP_SLAVE_BIT7_INT BIT(7) +#define ESP_SLAVE_RX_UNDERFLOW_INT BIT(16) +#define ESP_SLAVE_TX_OVERFLOW_INT BIT(17) +#define ESP_SLAVE_RX_NEW_PACKET_INT BIT(23) + + +#define ESP_SLAVE_CMD53_END_ADDR 0x1F800 +#define ESP_SLAVE_LEN_MASK 0xFFFFF +#define ESP_BLOCK_SIZE 512 +#define ESP_RX_BYTE_MAX 0x100000 +#define ESP_RX_BUFFER_SIZE 2048 + +#define ESP_TX_BUFFER_MASK 0xFFF +#define ESP_TX_BUFFER_MAX 0x1000 +#define ESP_MAX_BUF_CNT 10 + +#define ESP_SLAVE_SLCHOST_BASE 0x3FF55000 + +#define ESP_SLAVE_SCRATCH_REG_7 (ESP_SLAVE_SLCHOST_BASE + 0x8C) +/* SLAVE registers */ +/* Interrupt Registers */ +#define ESP_SLAVE_INT_RAW_REG (ESP_SLAVE_SLCHOST_BASE + 0x50) +#define ESP_SLAVE_INT_ST_REG (ESP_SLAVE_SLCHOST_BASE + 0x58) +#define ESP_SLAVE_INT_CLR_REG (ESP_SLAVE_SLCHOST_BASE + 0xD4) + +/* Data path registers*/ +#define ESP_SLAVE_PACKET_LEN_REG (ESP_SLAVE_SLCHOST_BASE + 0x60) +#define ESP_SLAVE_TOKEN_RDATA (ESP_SLAVE_SLCHOST_BASE + 0x44) + +/* Scratch registers*/ +#define ESP_SLAVE_SCRATCH_REG_0 (ESP_SLAVE_SLCHOST_BASE + 0x6C) +#define ESP_SLAVE_SCRATCH_REG_1 (ESP_SLAVE_SLCHOST_BASE + 0x70) +#define ESP_SLAVE_SCRATCH_REG_2 (ESP_SLAVE_SLCHOST_BASE + 0x74) +#define ESP_SLAVE_SCRATCH_REG_3 (ESP_SLAVE_SLCHOST_BASE + 0x78) +#define ESP_SLAVE_SCRATCH_REG_4 (ESP_SLAVE_SLCHOST_BASE + 0x7C) +#define ESP_SLAVE_SCRATCH_REG_6 (ESP_SLAVE_SLCHOST_BASE + 0x88) +#define ESP_SLAVE_SCRATCH_REG_8 (ESP_SLAVE_SLCHOST_BASE + 0x9C) +#define ESP_SLAVE_SCRATCH_REG_9 (ESP_SLAVE_SLCHOST_BASE + 0xA0) +#define ESP_SLAVE_SCRATCH_REG_10 (ESP_SLAVE_SLCHOST_BASE + 0xA4) +#define ESP_SLAVE_SCRATCH_REG_11 (ESP_SLAVE_SLCHOST_BASE + 0xA8) +#define ESP_SLAVE_SCRATCH_REG_12 (ESP_SLAVE_SLCHOST_BASE + 0xAC) +#define ESP_SLAVE_SCRATCH_REG_13 (ESP_SLAVE_SLCHOST_BASE + 0xB0) +#define ESP_SLAVE_SCRATCH_REG_14 (ESP_SLAVE_SLCHOST_BASE + 0xB4) +#define ESP_SLAVE_SCRATCH_REG_15 (ESP_SLAVE_SLCHOST_BASE + 0xB8) + +#define ESP_ADDRESS_MASK (0x3FF) + +#define ESP_VENDOR_ID (0x6666) +#define ESP_DEVICE_ID_1 (0x2222) +#define ESP_DEVICE_ID_2 (0x3333) + + +#define SDIO_REG(x) ((x)&ESP_ADDRESS_MASK) + +#define SDIO_FUNC_0 (0) +#define SDIO_FUNC_1 (1) + +#define ESP_SDIO_CONF_OFFSET (0) +#define ESP_SDIO_SEND_OFFSET (16) + +/* New slave packet incoming bit */ +#define HOST_SLC0_RX_NEW_PACKET_INT_ST (BIT(23)) + +/* SDIO pin configuration */ +/* In case of different board than STM32 Nucleo-F412ZG, + * User need to update pins as per hardware*/ + +/* SDIO D0 - PC8 */ +#ifndef USR_SDIO_D0_Port +#define USR_SDIO_D0_Port GPIOC +#endif +#ifndef USR_SDIO_D0_Pin +#define USR_SDIO_D0_Pin GPIO_PIN_8 +#endif + +/* SDIO D1 - PC9 */ +#ifndef USR_SDIO_D1_Port +#define USR_SDIO_D1_Port GPIOC +#endif +#ifndef USR_SDIO_D1_Pin +#define USR_SDIO_D1_Pin GPIO_PIN_9 +#endif + +/* SDIO D2 - PC10 */ +#ifndef USR_SDIO_D2_Port +#define USR_SDIO_D2_Port GPIOC +#endif +#ifndef USR_SDIO_D2_Pin +#define USR_SDIO_D2_Pin GPIO_PIN_10 +#endif + +/* SDIO D3 - PC11 */ +#ifndef USR_SDIO_D3_Port +#define USR_SDIO_D3_Port GPIOC +#endif +#ifndef USR_SDIO_D3_Pin +#define USR_SDIO_D3_Pin GPIO_PIN_11 +#endif + +/* SDIO CLK - PC12 */ +#ifndef USR_SDIO_CLK_Port +#define USR_SDIO_CLK_Port GPIOC +#endif +#ifndef USR_SDIO_CLK_Pin +#define USR_SDIO_CLK_Pin GPIO_PIN_12 +#endif + +/* SDIO CMD - PD2 */ +#ifndef USR_SDIO_CMD_Port +#define USR_SDIO_CMD_Port GPIOD +#endif +#ifndef USR_SDIO_CMD_Pin +#define USR_SDIO_CMD_Pin GPIO_PIN_2 +#endif + +/* SDIO Reset slave - PG2 */ +#ifndef GPIO_RESET_GPIO_Port +#define GPIO_RESET_GPIO_Port GPIOG +#endif +#ifndef GPIO_RESET_Pin +#define GPIO_RESET_Pin GPIO_PIN_2 +#endif + +#define __HAL_RCC_SDIO_GPIO_ENABLE() \ +{ \ + __HAL_RCC_GPIOC_CLK_ENABLE(); \ + __HAL_RCC_GPIOD_CLK_ENABLE(); \ +} + +#endif /* __SDIO_REG_H */ diff --git a/esp_hosted_fg/host/stm32/driver/spi/spi_drv.c b/esp_hosted_fg/host/stm32/driver/transport/spi/spi_drv.c similarity index 93% rename from esp_hosted_fg/host/stm32/driver/spi/spi_drv.c rename to esp_hosted_fg/host/stm32/driver/transport/spi/spi_drv.c index 53da67c134..7b9810b831 100644 --- a/esp_hosted_fg/host/stm32/driver/spi/spi_drv.c +++ b/esp_hosted_fg/host/stm32/driver/transport/spi/spi_drv.c @@ -22,6 +22,7 @@ #include "adapter.h" #include "serial_drv.h" #include "netdev_if.h" +#include "stats.h" /** Constants/Macros **/ #define TO_SLAVE_QUEUE_SIZE 10 @@ -32,11 +33,12 @@ #define MAX_PAYLOAD_SIZE (MAX_SPI_BUFFER_SIZE-sizeof(struct esp_payload_header)) -typedef enum hardware_type_e { +/** Enumeration **/ +enum hardware_type_e { HARDWARE_TYPE_ESP32, HARDWARE_TYPE_OTHER_ESP_CHIPSETS, HARDWARE_TYPE_INVALID, -}hardware_type_t; +}; static stm_ret_t spi_transaction_v1(uint8_t * txbuff); static stm_ret_t spi_transaction_v2(uint8_t * txbuff); @@ -53,10 +55,6 @@ static stm_ret_t (*spi_trans_func[])(uint8_t * txbuff) = { spi_transaction_v2 }; -static int esp_netdev_open(netdev_handle_t netdev); -static int esp_netdev_close(netdev_handle_t netdev); -static int esp_netdev_xmit(netdev_handle_t netdev, struct pbuf *net_buf); - static struct esp_private *esp_priv[MAX_NETWORK_INTERFACES]; static uint8_t hardware_type = HARDWARE_TYPE_INVALID; @@ -88,6 +86,7 @@ static void process_rx_task(void const* pvParameters); static uint8_t * get_tx_buffer(uint8_t *is_valid_tx_buf); static void deinit_netdev(void); +/** Local Functions **/ /** * @brief get private interface of expected type and number * @param if_type - interface type @@ -108,51 +107,6 @@ static struct esp_private * get_priv(uint8_t if_type, uint8_t if_num) return NULL; } -/** - * @brief open virtual network device - * @param netdev - network device - * @retval 0 on success - */ -static int esp_netdev_open(netdev_handle_t netdev) -{ - return STM_OK; -} - -/** - * @brief close virtual network device - * @param netdev - network device - * @retval 0 on success - */ -static int esp_netdev_close(netdev_handle_t netdev) -{ - return STM_OK; -} - -/** - * @brief transmit on virtual network device - * @param netdev - network device - * net_buf - buffer to transmit - * @retval None - */ -static int esp_netdev_xmit(netdev_handle_t netdev, struct pbuf *net_buf) -{ - struct esp_private *priv; - int ret; - - if (!netdev || !net_buf) - return STM_FAIL; - priv = (struct esp_private *) netdev_get_priv(netdev); - - if (!priv) - return STM_FAIL; - - ret = send_to_slave(priv->if_type, priv->if_num, - net_buf->payload, net_buf->len); - free(net_buf); - - return ret; -} - /** * @brief create virtual network device * @param None @@ -271,18 +225,18 @@ static void set_hardware_type(void) /** Exported Functions **/ /** - * @brief spi driver initialize - * @param spi_drv_evt_handler - event handler of type spi_drv_events_e + * @brief transport initializes + * @param transport_evt_handler_fp - event handler * @retval None */ -void stm_spi_init(void(*spi_drv_evt_handler)(uint8_t)) +void transport_init(void(*transport_evt_handler_fp)(uint8_t)) { stm_ret_t retval = STM_OK; /* Check if supported board */ set_hardware_type(); /* register callback */ - spi_drv_evt_handler_fp = spi_drv_evt_handler; + spi_drv_evt_handler_fp = transport_evt_handler_fp; osSemaphoreDef(SEM); retval = init_netdev(); @@ -774,7 +728,19 @@ static void process_rx_task(void const* pvParameters) } } else if (buf_handle.if_type == ESP_PRIV_IF) { + buffer = (struct pbuf *)malloc(sizeof(struct pbuf)); + assert(buffer); + + buffer->len = buf_handle.payload_len; + buffer->payload = malloc(buf_handle.payload_len); + assert(buffer->payload); + + memcpy(buffer->payload, buf_handle.payload, + buf_handle.payload_len); + + process_priv_communication(buffer); /* priv transaction received */ + printf("Received INIT event\n\r"); event = (struct esp_priv_event *) (payload); if (event->event_type == ESP_PRIV_EVENT_INIT) { @@ -783,11 +749,17 @@ static void process_rx_task(void const* pvParameters) * time to slave before spi trans start */ stop_spi_transactions_for_msec(50000); if (spi_drv_evt_handler_fp) { - spi_drv_evt_handler_fp(SPI_DRIVER_ACTIVE); + spi_drv_evt_handler_fp(TRANSPORT_ACTIVE); } } else { /* User can re-use this type of transaction */ } + } else if (buf_handle.if_type == ESP_TEST_IF) { +#if TEST_RAW_TP + update_test_raw_tp_rx_len(buf_handle.payload_len); +#endif + } else { + printf("unknown type %d \n\r", buf_handle.if_type); } /* Free buffer handle */ diff --git a/esp_hosted_fg/host/stm32/driver/spi/spi_drv.h b/esp_hosted_fg/host/stm32/driver/transport/spi/spi_drv.h similarity index 73% rename from esp_hosted_fg/host/stm32/driver/spi/spi_drv.h rename to esp_hosted_fg/host/stm32/driver/transport/spi/spi_drv.h index 3a2b2fe1d4..da88b0d378 100644 --- a/esp_hosted_fg/host/stm32/driver/spi/spi_drv.h +++ b/esp_hosted_fg/host/stm32/driver/transport/spi/spi_drv.h @@ -22,11 +22,9 @@ extern "C" { /** Includes **/ #include "common.h" +#include "transport_drv.h" /** constants/macros **/ -#define MAX_NETWORK_INTERFACES 2 -#define STA_INTERFACE "ESP_STATION" -#define SOFTAP_INTERFACE "ESP_SOFTAP" /* NSS or CS0 configuration (Pin 11) */ /* In case of different board than STM32F469I, @@ -38,10 +36,6 @@ extern "C" { #define USR_SPI_CS_Pin GPIO_PIN_15 #endif -typedef enum spi_drv_events_s { - SPI_DRIVER_ACTIVE -} spi_drv_events_e; - /** Exported Structures **/ /** Exported variables **/ @@ -49,15 +43,6 @@ typedef enum spi_drv_events_s { /** Inline functions **/ /** Exported Functions **/ -void stm_spi_init(void(*spi_drv_evt_handler)(uint8_t)); -stm_ret_t send_to_slave(uint8_t iface_type, uint8_t iface_num, - uint8_t * wbuffer, uint16_t wlen); - -struct esp_private { - uint8_t if_type; - uint8_t if_num; - void *netdev; -}; #ifdef __cplusplus } diff --git a/esp_hosted_fg/host/stm32/driver/transport/transport_drv.c b/esp_hosted_fg/host/stm32/driver/transport/transport_drv.c new file mode 100644 index 0000000000..2c94ac95a4 --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/transport_drv.c @@ -0,0 +1,193 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** Includes **/ +#include "transport_drv.h" +#include "stats.h" +/** + * @brief Slave capabilities are parsed + * Currently no added functionality to that + * @param None + * @retval None + */ +static char chip_type = ESP_PRIV_FIRMWARE_CHIP_UNRECOGNIZED; + +/** + * @brief open virtual network device + * @param netdev - network device + * @retval 0 on success + */ +int esp_netdev_open(netdev_handle_t netdev) +{ + return STM_OK; +} + +/** + * @brief close virtual network device + * @param netdev - network device + * @retval 0 on success + */ +int esp_netdev_close(netdev_handle_t netdev) +{ + return STM_OK; +} + + +/** + * @brief transmit on virtual network device + * @param netdev - network device + * net_buf - buffer to transmit + * @retval STM_OK for success or failure from enum stm_ret_t + */ +int esp_netdev_xmit(netdev_handle_t netdev, struct pbuf *net_buf) +{ + struct esp_private *priv = NULL; + int ret = 0; + + if (!netdev || !net_buf) + return STM_FAIL; + priv = (struct esp_private *) netdev_get_priv(netdev); + + if (!priv) + return STM_FAIL; + + ret = send_to_slave(priv->if_type, priv->if_num, + net_buf->payload, net_buf->len); + free(net_buf); + + return ret; +} + +void process_capabilities(uint8_t cap) +{ +#if DEBUG_TRANSPORT + printf("capabilities: 0x%x\n\r",cap); +#else + /* warning suppress */ + if(cap); +#endif +} + +void process_priv_communication(struct pbuf *pbuf) +{ + struct esp_priv_event *header = NULL; + + uint8_t *payload = NULL; + uint16_t len = 0; + + if (!pbuf || !pbuf->payload) + return; + + header = (struct esp_priv_event *) pbuf->payload; + + payload = pbuf->payload; + len = pbuf->len; + + if (header->event_type == ESP_PRIV_EVENT_INIT) { + printf("event packet type\n\r"); + process_event(payload, len); + } + + hosted_free(pbuf); +} + +void print_capabilities(uint32_t cap) +{ + printf("Features supported are:\n\r"); + if (cap & ESP_WLAN_SDIO_SUPPORT) + printf("\t * WLAN\n\r"); + if ((cap & ESP_BT_UART_SUPPORT) || (cap & ESP_BT_SDIO_SUPPORT)) { + printf("\t * BT/BLE\n\r"); + if (cap & ESP_BT_UART_SUPPORT) + printf("\t - HCI over UART\n\r"); + if (cap & ESP_BT_SDIO_SUPPORT) + printf("\t - HCI over SDIO\n\r"); + if ((cap & ESP_BLE_ONLY_SUPPORT) && (cap & ESP_BR_EDR_ONLY_SUPPORT)) + printf("\t - BT/BLE dual mode\n\r"); + else if (cap & ESP_BLE_ONLY_SUPPORT) + printf("\t - BLE only\n\r"); + else if (cap & ESP_BR_EDR_ONLY_SUPPORT) + printf("\t - BR EDR only\n\r"); + } +} + +void process_event(uint8_t *evt_buf, uint16_t len) +{ + int ret = 0; + struct esp_priv_event *event; + + if (!evt_buf || !len) + return; + + event = (struct esp_priv_event *) evt_buf; + + if (event->event_type == ESP_PRIV_EVENT_INIT) { + + printf("Received INIT event from ESP32 peripheral\n\r"); + + print_hex_dump(event->event_data, event->event_len, "process event"); + + ret = process_init_event(event->event_data, event->event_len); + if (ret) { + printf("failed to init event\n\r"); + } + } else { + printf("Drop unknown event\n\r"); + } +} + +int process_init_event(uint8_t *evt_buf, uint8_t len) +{ + uint8_t len_left = len, tag_len; + uint8_t *pos; + if (!evt_buf) + return STM_FAIL; + pos = evt_buf; + while (len_left) { + tag_len = *(pos + 1); + printf("EVENT: %d\n\r", *pos); + if (*pos == ESP_PRIV_CAPABILITY) { + printf("priv capabilty \n\r"); + process_capabilities(*(pos + 2)); + print_capabilities(*(pos + 2)); + } else if (*pos == ESP_PRIV_SPI_CLK_MHZ) { + // adjust spi clock + } else if (*pos == ESP_PRIV_FIRMWARE_CHIP_ID) { + chip_type = *(pos+2); + } else if (*pos == ESP_PRIV_TEST_RAW_TP) { + printf("priv test raw tp\n\r"); +#if TEST_RAW_TP + process_test_capabilities(*(pos + 2)); +#endif + } else { + printf("Unsupported tag in event\n\r"); + } + pos += (tag_len+2); + len_left -= (tag_len+2); + } + + if ((chip_type != ESP_PRIV_FIRMWARE_CHIP_ESP32) && + (chip_type != ESP_PRIV_FIRMWARE_CHIP_ESP32S2) && + (chip_type != ESP_PRIV_FIRMWARE_CHIP_ESP32C2) && + (chip_type != ESP_PRIV_FIRMWARE_CHIP_ESP32C3) && + (chip_type != ESP_PRIV_FIRMWARE_CHIP_ESP32S3)) { + printf("ESP board type is not mentioned, ignoring [%d]\n\r", chip_type); + chip_type = ESP_PRIV_FIRMWARE_CHIP_UNRECOGNIZED; + return -1; + } else { + printf("ESP board type is : %d \n\r", chip_type); + } + + return STM_OK; +} diff --git a/esp_hosted_fg/host/stm32/driver/transport/transport_drv.h b/esp_hosted_fg/host/stm32/driver/transport/transport_drv.h new file mode 100644 index 0000000000..47e2ad0861 --- /dev/null +++ b/esp_hosted_fg/host/stm32/driver/transport/transport_drv.h @@ -0,0 +1,68 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** prevent recursive inclusion **/ +#ifndef __TRANSPORT_DRV_H +#define __TRANSPORT_DRV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Includes **/ + +#include "common.h" +#include "adapter.h" +#include "netdev_if.h" +#include "platform_wrapper.h" +#include "trace.h" + +/* ESP in sdkconfig has CONFIG_IDF_FIRMWARE_CHIP_ID entry. + * supported values of CONFIG_IDF_FIRMWARE_CHIP_ID are - */ +#define ESP_PRIV_FIRMWARE_CHIP_UNRECOGNIZED (0xff) +#define ESP_PRIV_FIRMWARE_CHIP_ESP32 (0x0) +#define ESP_PRIV_FIRMWARE_CHIP_ESP32S2 (0x2) +#define ESP_PRIV_FIRMWARE_CHIP_ESP32C3 (0x5) +#define ESP_PRIV_FIRMWARE_CHIP_ESP32S3 (0x9) +#define ESP_PRIV_FIRMWARE_CHIP_ESP32C2 (0xC) + +struct esp_private { + uint8_t if_type; + uint8_t if_num; + void *netdev; +}; + +/* netdev APIs*/ +int esp_netdev_open(netdev_handle_t netdev); +int esp_netdev_close(netdev_handle_t netdev); +int esp_netdev_xmit(netdev_handle_t netdev, struct pbuf *net_buf); + + +void process_capabilities(uint8_t cap); +void transport_init(void(*transport_evt_handler)(uint8_t)); + +void process_event(uint8_t *evt_buf, uint16_t len); +void process_priv_communication(struct pbuf *pbuf); +void print_capabilities(uint32_t cap); +int process_init_event(uint8_t *evt_buf, uint8_t len); + +stm_ret_t send_to_slave(uint8_t iface_type, uint8_t iface_num, + uint8_t * wbuffer, uint16_t wlen); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/esp_hosted_fg/host/stm32/port/src/platform_wrapper.c b/esp_hosted_fg/host/stm32/port/src/platform_wrapper.c index e51ad77388..f21d1d38f9 100644 --- a/esp_hosted_fg/host/stm32/port/src/platform_wrapper.c +++ b/esp_hosted_fg/host/stm32/port/src/platform_wrapper.c @@ -316,6 +316,7 @@ void *hosted_timer_start(int duration, int type, os_timer_type timer_type = osTimerOnce; osTimerDef (timerNew, timeout_handler); + /* alloc */ timer_handle = (struct timer_handle_t *)hosted_malloc( sizeof(struct timer_handle_t)); @@ -462,7 +463,7 @@ uint8_t * serial_drv_read(struct serial_drv_handle_t *serial_drv_handle, print_hex_dump(read_buf, rx_buf_len, "Serial read data"); /* - * Read Operation happens in two steps because total read length is unkown + * Read Operation happens in two steps because total read length is unknown * at first read. * 1) Read fixed length of RX data * 2) Read variable length of RX data diff --git a/esp_hosted_fg/host/stm32/proj/prepare_project.bat b/esp_hosted_fg/host/stm32/proj/prepare_project.bat index 081d4febac..ccd4cdb04c 100755 --- a/esp_hosted_fg/host/stm32/proj/prepare_project.bat +++ b/esp_hosted_fg/host/stm32/proj/prepare_project.bat @@ -1,26 +1,39 @@ @echo off -rem ### This is windows platform script to copy the project files and +rem ### This is windows platform script to copy the project files and rem ### make them aligned to STM32CubeIDE needs -set WORKSPACE=%1 -set PROJ_NAME=stm_spi_host +set TRANSPORT=%1 +set WORKSPACE=%2 +set PROJ_NAME=stm_%TRANSPORT%_host set CWD=%CD% +rem ### Check incorrect number of argument passed +set argC=0 +for %%x in (%*) do Set /A argC+=1 + +if %argC% gtr 2 ( +echo Invalid number of arguments entered +goto error +) + rem ### Check argument passed ### -IF "%1"=="" ( -echo usage: %0 Workspace_directory_absolute_path +if (%1% == "" or %2% == "") ( +echo usage: %0 Transport Workspace_directory_absolute_path +echo Transport - either spi or sdio +echo Workspace_directory_absolute_path - Workspace directory created for STM32CubeIDE goto error ) rem ### store git repo base path### cd ..\..\.. set CODE_BASE=%CD% +echo code base %CD% cd %CWD% rem ### check workspace directory exist ### IF not exist %WORKSPACE% ( echo %WORKSPACE% does not exist -echo Please follow documentation to import STM project from stm_spi_host_.ioc, if not already done +echo Please follow documentation to import STM project from stm__host_.ioc, if not already done goto error ) @@ -28,7 +41,7 @@ rem ### check project directory exist ### IF not exist %WORKSPACE%\%PROJ_NAME% ( echo %WORKSPACE%\%PROJ_NAME% does not exist echo Either incorrect workspace directory or ioc project not imported -echo Please follow documentation to import STM project from stm_spi_host_.ioc, if not already done +echo Please follow documentation to import STM project from stm__host_.ioc, if not already done goto error ) @@ -37,7 +50,7 @@ DEL %WORKSPACE%\%PROJ_NAME%\.project 2>NUL DEL %WORKSPACE%\%PROJ_NAME%\.cproject 2>NUL setLocal EnableDelayedExpansion -For /f "tokens=* delims= " %%a in (.project) do ( +For /f "tokens=* delims= " %%a in (%TRANSPORT%\.project) do ( Set str=%%a set str=!str:CODE_BASE_PLACE_HOLDER=%CODE_BASE%! echo !str!>> %WORKSPACE%\%PROJ_NAME%\.project @@ -46,7 +59,7 @@ ENDLOCAL setLocal EnableDelayedExpansion -For /f "tokens=* delims= " %%a in (.cproject) do ( +For /f "tokens=* delims= " %%a in (%TRANSPORT%\.cproject) do ( Set str=%%a set str=!str:CODE_BASE_PLACE_HOLDER=%CODE_BASE%! echo !str!>> %WORKSPACE%\%PROJ_NAME%\.cproject diff --git a/esp_hosted_fg/host/stm32/proj/prepare_project.sh b/esp_hosted_fg/host/stm32/proj/prepare_project.sh index e7ecb1678f..def595ceb3 100755 --- a/esp_hosted_fg/host/stm32/proj/prepare_project.sh +++ b/esp_hosted_fg/host/stm32/proj/prepare_project.sh @@ -3,11 +3,13 @@ # This script copies and touches the .project, .cproject and .mxproject files # This is required to make STM32CubeIDE recognize the new project import -PROJ_NAME=stm_spi_host +PROJ_NAME= CODE_BASE= function usage() { - echo "$0 " + echo "$0 " + echo "Transport - either spi or sdio" + echo "Workspace_directory - Workspace directory created for STM32CubeIDE" } function copy_and_touch_files() { @@ -15,37 +17,49 @@ function copy_and_touch_files() { cd ../../../ CODE_BASE=`pwd` cd $CWD - cp ./.project $WORKSPACE/$PROJ_NAME/ - cp ./.cproject $WORKSPACE/$PROJ_NAME/ + cp ./${TRANSPORT}/.project $WORKSPACE/$PROJ_NAME/ + cp ./${TRANSPORT}/.cproject $WORKSPACE/$PROJ_NAME/ sed -i.bak "s#CODE_BASE_PLACE_HOLDER#$CODE_BASE#" $WORKSPACE/$PROJ_NAME/.project sed -i.bak "s#CODE_BASE_PLACE_HOLDER#$CODE_BASE#" $WORKSPACE/$PROJ_NAME/.cproject touch $WORKSPACE/$PROJ_NAME/.mxproject echo "success. Now, please open STM32CubeIDE with $WORKSPACE" } -if [ "$#" != "1" ] ; then - echo "Err: Workspace directory created for STM32CubeIDE to be passed as argument" +if [ "$1" == '-h' ] || [ "$1" == '--help' ] ; then usage - exit 1; -else - WORKSPACE=$1 + exit 0 fi -if [ "$1" == '-h' ] || [ "$1" == '--help' ] ; then +if [ "$#" != "2" ] ; then + echo "Err: Incorrect number of arguments passed" usage - exit 0 + exit 1 +else + if [ "$1" != "spi" -a "$1" != "sdio" ] ; then + echo "ERR: Invalid transport value" + usage + exit 1 + fi + TRANSPORT=$1 + WORKSPACE=$2 + PROJ_NAME=stm_${TRANSPORT}_host fi + if [ ! -d $WORKSPACE ]; then - echo "Err: $WORKSPACE directory not found. Please follow documentation to import STM project from stm_spi_host_.ioc first" + echo "Err: $WORKSPACE directory not found. Please follow documentation to import STM project from stm__host_.ioc first" + echo " is applicable only for SPI transport" + echo "SPI : for ESP32 wroom/wrover use stm_spi_host_v1.ioc " + echo " : for other ESP modules use stm_spi_host_v2.ioc" + echo "SDIO: for ESP32 use stm_sdio_host.ioc" usage exit 1; fi if [ ! -d $WORKSPACE/$PROJ_NAME ]; then echo "Err: Either incorrect Workspace directory or ioc project not imported." - echo "Please follow documentation to import STM project from stm_spi_host_.ioc if not already done" + echo "Please follow documentation to import STM project from stm__host_.ioc if not already done" usage exit 1; fi diff --git a/esp_hosted_fg/host/stm32/proj/sdio/.cproject b/esp_hosted_fg/host/stm32/proj/sdio/.cproject new file mode 100644 index 0000000000..e8aafe7f7a --- /dev/null +++ b/esp_hosted_fg/host/stm32/proj/sdio/.cproject @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/esp_hosted_fg/host/stm32/proj/sdio/.project b/esp_hosted_fg/host/stm32/proj/sdio/.project new file mode 100644 index 0000000000..17bb064695 --- /dev/null +++ b/esp_hosted_fg/host/stm32/proj/sdio/.project @@ -0,0 +1,51 @@ + + + stm_sdio_host + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + com.st.stm32cube.ide.mcu.MCUCubeProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature + com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + common + 2 + CODE_BASE/common + + + host + 2 + CODE_BASE/host + + + + + CODE_BASE + file:CODE_BASE_PLACE_HOLDER + + + diff --git a/esp_hosted_fg/host/stm32/proj/sdio/stm_sdio_host.ioc b/esp_hosted_fg/host/stm32/proj/sdio/stm_sdio_host.ioc new file mode 100644 index 0000000000..0431c2a607 --- /dev/null +++ b/esp_hosted_fg/host/stm32/proj/sdio/stm_sdio_host.ioc @@ -0,0 +1,331 @@ +#MicroXplorer Configuration settings - do not modify +FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,configUSE_TIMERS,configTIMER_TASK_PRIORITY +FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL +FREERTOS.configTIMER_TASK_PRIORITY=5 +FREERTOS.configTOTAL_HEAP_SIZE=131072 +FREERTOS.configUSE_TIMERS=1 +File.Version=6 +GPIO.groupedBy=Group By Peripherals +KeepUserPlacement=false +Mcu.CPN=STM32F412ZGT6 +Mcu.Family=STM32F4 +Mcu.IP0=FREERTOS +Mcu.IP1=NVIC +Mcu.IP2=RCC +Mcu.IP3=SDIO +Mcu.IP4=SYS +Mcu.IP5=USART3 +Mcu.IPNb=6 +Mcu.Name=STM32F412Z(E-G)Tx +Mcu.Package=LQFP144 +Mcu.Pin0=PC13 +Mcu.Pin1=PC14-OSC32_IN +Mcu.Pin10=PG6 +Mcu.Pin11=PG7 +Mcu.Pin12=PC8 +Mcu.Pin13=PC9 +Mcu.Pin14=PA8 +Mcu.Pin15=PA9 +Mcu.Pin16=PA10 +Mcu.Pin17=PA11 +Mcu.Pin18=PA12 +Mcu.Pin19=PA13 +Mcu.Pin2=PC15-OSC32_OUT +Mcu.Pin20=PA14 +Mcu.Pin21=PC10 +Mcu.Pin22=PC11 +Mcu.Pin23=PC12 +Mcu.Pin24=PD2 +Mcu.Pin25=PB3 +Mcu.Pin26=PB7 +Mcu.Pin27=VP_FREERTOS_VS_CMSIS_V1 +Mcu.Pin28=VP_SYS_VS_tim2 +Mcu.Pin3=PH0 - OSC_IN +Mcu.Pin4=PH1 - OSC_OUT +Mcu.Pin5=PB0 +Mcu.Pin6=PB14 +Mcu.Pin7=PD8 +Mcu.Pin8=PD9 +Mcu.Pin9=PG2 +Mcu.PinsNb=29 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32F412ZGTx +MxCube.Version=6.2.1 +MxDb.Version=DB.6.0.21 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.EXTI15_10_IRQn=true\:5\:0\:false\:false\:true\:false\:true\:true\:true +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false +NVIC.SavedPendsvIrqHandlerGenerated=true +NVIC.SavedSvcallIrqHandlerGenerated=true +NVIC.SavedSystickIrqHandlerGenerated=true +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:true\:true\:false +NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true\:true +NVIC.TimeBase=TIM2_IRQn +NVIC.TimeBaseIP=TIM2 +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false +PA10.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Mode +PA10.GPIO_Mode=GPIO_MODE_AF_PP +PA10.GPIO_PuPd=GPIO_NOPULL +PA10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA10.Locked=true +PA10.Signal=USB_OTG_FS_ID +PA11.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Mode +PA11.GPIO_Mode=GPIO_MODE_AF_PP +PA11.GPIO_PuPd=GPIO_NOPULL +PA11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA11.Locked=true +PA11.Signal=USB_OTG_FS_DM +PA12.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Mode +PA12.GPIO_Mode=GPIO_MODE_AF_PP +PA12.GPIO_PuPd=GPIO_NOPULL +PA12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA12.Locked=true +PA12.Signal=USB_OTG_FS_DP +PA13.Locked=true +PA13.Mode=Serial_Wire +PA13.Signal=SYS_JTMS-SWDIO +PA14.Locked=true +PA14.Mode=Serial_Wire +PA14.Signal=SYS_JTCK-SWCLK +PA8.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Mode +PA8.GPIO_Mode=GPIO_MODE_AF_PP +PA8.GPIO_PuPd=GPIO_NOPULL +PA8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA8.Locked=true +PA8.Signal=USB_OTG_FS_SOF +PA9.Locked=true +PA9.Signal=USB_OTG_FS_VBUS +PB0.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_ModeDefaultOutputPP +PB0.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP +PB0.GPIO_PuPd=GPIO_NOPULL +PB0.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PB0.Locked=true +PB0.PinState=GPIO_PIN_RESET +PB0.Signal=GPIO_Output +PB14.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_ModeDefaultOutputPP +PB14.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP +PB14.GPIO_PuPd=GPIO_NOPULL +PB14.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PB14.Locked=true +PB14.PinState=GPIO_PIN_RESET +PB14.Signal=GPIO_Output +PB3.Locked=true +PB3.Signal=SYS_JTDO-SWO +PB7.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_ModeDefaultOutputPP +PB7.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP +PB7.GPIO_PuPd=GPIO_NOPULL +PB7.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PB7.Locked=true +PB7.PinState=GPIO_PIN_RESET +PB7.Signal=GPIO_Output +PC10.GPIOParameters=GPIO_PuPd,GPIO_Label +PC10.GPIO_Label=USR_SDIO_D2_Pin +PC10.GPIO_PuPd=GPIO_PULLUP +PC10.Locked=true +PC10.Mode=SD_4_bits_Wide_bus +PC10.Signal=SDIO_D2 +PC11.GPIOParameters=GPIO_PuPd,GPIO_Label +PC11.GPIO_Label=USR_SDIO_D3_Pin +PC11.GPIO_PuPd=GPIO_PULLUP +PC11.Locked=true +PC11.Mode=SD_4_bits_Wide_bus +PC11.Signal=SDIO_D3 +PC12.GPIOParameters=GPIO_Label +PC12.GPIO_Label=USR_SDIO_CLK_Pin +PC12.Locked=true +PC12.Mode=SD_4_bits_Wide_bus +PC12.Signal=SDIO_CK +PC13.GPIOParameters=GPIO_PuPd,GPIO_ModeDefaultEXTI +PC13.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING +PC13.GPIO_PuPd=GPIO_NOPULL +PC13.Locked=true +PC13.Signal=GPXTI13 +PC14-OSC32_IN.Locked=true +PC14-OSC32_IN.Mode=LSE-External-Oscillator +PC14-OSC32_IN.Signal=RCC_OSC32_IN +PC15-OSC32_OUT.Locked=true +PC15-OSC32_OUT.Mode=LSE-External-Oscillator +PC15-OSC32_OUT.Signal=RCC_OSC32_OUT +PC8.GPIOParameters=GPIO_PuPd,GPIO_Label +PC8.GPIO_Label=USR_SDIO_D0_Pin +PC8.GPIO_PuPd=GPIO_PULLUP +PC8.Locked=true +PC8.Mode=SD_4_bits_Wide_bus +PC8.Signal=SDIO_D0 +PC9.GPIOParameters=GPIO_PuPd,GPIO_Label +PC9.GPIO_Label=USR_SDIO_D1_Pin +PC9.GPIO_PuPd=GPIO_PULLUP +PC9.Locked=true +PC9.Mode=SD_4_bits_Wide_bus +PC9.Signal=SDIO_D1 +PD2.GPIOParameters=GPIO_PuPd,GPIO_Label +PD2.GPIO_Label=USR_SDIO_CMD_Pin +PD2.GPIO_PuPd=GPIO_PULLUP +PD2.Locked=true +PD2.Mode=SD_4_bits_Wide_bus +PD2.Signal=SDIO_CMD +PD8.GPIOParameters=GPIO_ModeDefaultPP,GPIO_Speed,GPIO_PuPd +PD8.GPIO_ModeDefaultPP=GPIO_MODE_AF_PP +PD8.GPIO_PuPd=GPIO_NOPULL +PD8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PD8.Locked=true +PD8.Mode=Asynchronous +PD8.Signal=USART3_TX +PD9.GPIOParameters=GPIO_ModeDefaultPP,GPIO_Speed,GPIO_PuPd +PD9.GPIO_ModeDefaultPP=GPIO_MODE_AF_PP +PD9.GPIO_PuPd=GPIO_NOPULL +PD9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PD9.Locked=true +PD9.Mode=Asynchronous +PD9.Signal=USART3_RX +PG2.GPIOParameters=GPIO_Label +PG2.GPIO_Label=GPIO_RESET +PG2.Locked=true +PG2.Signal=GPIO_Output +PG6.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_ModeDefaultOutputPP +PG6.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP +PG6.GPIO_PuPd=GPIO_NOPULL +PG6.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PG6.Locked=true +PG6.PinState=GPIO_PIN_RESET +PG6.Signal=GPIO_Output +PG7.GPIOParameters=GPIO_PuPd,GPIO_Mode +PG7.GPIO_Mode=GPIO_MODE_INPUT +PG7.GPIO_PuPd=GPIO_NOPULL +PG7.Locked=true +PG7.Signal=GPIO_Input +PH0\ -\ OSC_IN.Locked=true +PH0\ -\ OSC_IN.Mode=HSE-External-Clock-Source +PH0\ -\ OSC_IN.Signal=RCC_OSC_IN +PH1\ -\ OSC_OUT.Mode=HSE-External-Clock-Source +PH1\ -\ OSC_OUT.Signal=RCC_OSC_OUT +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32F412ZGTx +ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.26.1 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x1A000 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain=STM32CubeIDE +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=stm_sdio_host.ioc +ProjectManager.ProjectName=stm_sdio_host +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.ToolChainLocation= +ProjectManager.UnderRoot=true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART3_UART_Init-USART3-false-HAL-true,4-MX_SDIO_SD_Init-SDIO-false-HAL-true +RCC.48MHZClocksFreq_Value=24000000 +RCC.ADC12outputFreq_Value=72000000 +RCC.ADC34outputFreq_Value=72000000 +RCC.AHBFreq_Value=96000000 +RCC.APB1CLKDivider=RCC_HCLK_DIV2 +RCC.APB1Freq_Value=48000000 +RCC.APB1TimFreq_Value=96000000 +RCC.APB2Freq_Value=96000000 +RCC.APB2TimFreq_Value=96000000 +RCC.CortexFreq_Value=96000000 +RCC.DFSDMAudioFreq_Value=400000000 +RCC.DFSDMFreq_Value=96000000 +RCC.EthernetFreq_Value=8000000 +RCC.FCLKCortexFreq_Value=96000000 +RCC.FMPI2C1Freq_Value=48000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=96000000 +RCC.HSE_VALUE=16000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=8000000 +RCC.I2C2Freq_Value=8000000 +RCC.I2C3Freq_Value=8000000 +RCC.I2S1Freq_Value=400000000 +RCC.I2S2Freq_Value=400000000 +RCC.I2SClocksFreq_Value=48000000 +RCC.IPParameters=48MHZClocksFreq_Value,ADC12outputFreq_Value,ADC34outputFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,DFSDMAudioFreq_Value,DFSDMFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FMPI2C1Freq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2S1Freq_Value,I2S2Freq_Value,I2SClocksFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MCO2PinFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLI2SM,PLLI2SN,PLLI2SPCLKFreq_Value,PLLI2SQCLKFreq_Value,PLLI2SQoutputFreq_Value,PLLI2SRCLKFreq_Value,PLLI2SoutputFreq_Value,PLLM,PLLMCOFreq_Value,PLLMUL,PLLP,PLLQ,PLLQCLKFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLRoutputFreq_Value,PRESCALERUSB,PWRFreq_Value,RNGFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SDIOFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,SYSCLKSourceVirtual,TIM15Freq_Value,TIM16Freq_Value,TIM17Freq_Value,TIM1Freq_Value,TIM20Freq_Value,TIM2Freq_Value,TIM3Freq_Value,TIM8Freq_Value,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOI2SInputFreq_Value,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOInputMFreq_Value,VCOOutput2Freq_Value,VCOOutputFreq_Value,VcooutputI2S,WatchDogFreq_Value +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=16000000 +RCC.MCO2PinFreq_Value=96000000 +RCC.MCOFreq_Value=72000000 +RCC.PLLCLKFreq_Value=96000000 +RCC.PLLI2SM=2 +RCC.PLLI2SN=100 +RCC.PLLI2SPCLKFreq_Value=400000000 +RCC.PLLI2SQCLKFreq_Value=400000000 +RCC.PLLI2SQoutputFreq_Value=400000000 +RCC.PLLI2SRCLKFreq_Value=400000000 +RCC.PLLI2SoutputFreq_Value=400000000 +RCC.PLLM=8 +RCC.PLLMCOFreq_Value=72000000 +RCC.PLLMUL=RCC_PLL_MUL9 +RCC.PLLP=RCC_PLLP_DIV4 +RCC.PLLQ=8 +RCC.PLLQCLKFreq_Value=48000000 +RCC.PLLQoutputFreq_Value=48000000 +RCC.PLLRCLKFreq_Value=192000000 +RCC.PLLRoutputFreq_Value=192000000 +RCC.PRESCALERUSB=RCC_USBCLKSOURCE_PLL_DIV1_5 +RCC.PWRFreq_Value=100000000 +RCC.RNGFreq_Value=48000000 +RCC.RTCFreq_Value=32000 +RCC.RTCHSEDivFreq_Value=4000000 +RCC.SDIOFreq_Value=48000000 +RCC.SYSCLKFreq_VALUE=96000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.SYSCLKSourceVirtual=RCC_SYSCLKSOURCE_PLLCLK +RCC.TIM15Freq_Value=72000000 +RCC.TIM16Freq_Value=72000000 +RCC.TIM17Freq_Value=72000000 +RCC.TIM1Freq_Value=72000000 +RCC.TIM20Freq_Value=72000000 +RCC.TIM2Freq_Value=72000000 +RCC.TIM3Freq_Value=72000000 +RCC.TIM8Freq_Value=72000000 +RCC.UART4Freq_Value=36000000 +RCC.UART5Freq_Value=36000000 +RCC.USART1Freq_Value=72000000 +RCC.USART2Freq_Value=36000000 +RCC.USART3Freq_Value=36000000 +RCC.USBFreq_Value=48000000 +RCC.VCOI2SInputFreq_Value=8000000 +RCC.VCOI2SOutputFreq_Value=800000000 +RCC.VCOInputFreq_Value=2000000 +RCC.VCOInputMFreq_Value=500000 +RCC.VCOOutput2Freq_Value=8000000 +RCC.VCOOutputFreq_Value=384000000 +RCC.VcooutputI2S=48000000 +RCC.WatchDogFreq_Value=32000 +SDIO.ClockEdge=SDIO_CLOCK_EDGE_FALLING +SDIO.ClockPowerSave=SDIO_CLOCK_POWER_SAVE_DISABLE +SDIO.HardwareFlowControl=SDIO_HARDWARE_FLOW_CONTROL_ENABLE +SDIO.IPParameters=HardwareFlowControl,ClockEdge,ClockPowerSave +SH.GPXTI13.0=GPIO_EXTI13 +SH.GPXTI13.ConfNb=1 +USART3.IPParameters=VirtualMode +USART3.VirtualMode=VM_ASYNC +VP_FREERTOS_VS_CMSIS_V1.Mode=CMSIS_V1 +VP_FREERTOS_VS_CMSIS_V1.Signal=FREERTOS_VS_CMSIS_V1 +VP_SYS_VS_tim2.Mode=TIM2 +VP_SYS_VS_tim2.Signal=SYS_VS_tim2 +board=NUCLEO-F412ZG +boardIOC=true +isbadioc=false diff --git a/esp_hosted_fg/host/stm32/proj/.cproject b/esp_hosted_fg/host/stm32/proj/spi/.cproject similarity index 97% rename from esp_hosted_fg/host/stm32/proj/.cproject rename to esp_hosted_fg/host/stm32/proj/spi/.cproject index 690840a7ec..8f84aacbea 100644 --- a/esp_hosted_fg/host/stm32/proj/.cproject +++ b/esp_hosted_fg/host/stm32/proj/spi/.cproject @@ -46,6 +46,7 @@ @@ -170,7 +174,7 @@ - + diff --git a/esp_hosted_fg/host/stm32/proj/.project b/esp_hosted_fg/host/stm32/proj/spi/.project similarity index 100% rename from esp_hosted_fg/host/stm32/proj/.project rename to esp_hosted_fg/host/stm32/proj/spi/.project diff --git a/esp_hosted_fg/host/stm32/proj/stm_spi_host_v1.ioc b/esp_hosted_fg/host/stm32/proj/spi/stm_spi_host_v1.ioc similarity index 98% rename from esp_hosted_fg/host/stm32/proj/stm_spi_host_v1.ioc rename to esp_hosted_fg/host/stm32/proj/spi/stm_spi_host_v1.ioc index a719f13a9a..c602da2fcc 100644 --- a/esp_hosted_fg/host/stm32/proj/stm_spi_host_v1.ioc +++ b/esp_hosted_fg/host/stm32/proj/spi/stm_spi_host_v1.ioc @@ -23,9 +23,11 @@ Dma.SPI1_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.SPI1_TX.1.Priority=DMA_PRIORITY_LOW Dma.SPI1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode FREERTOS.BinarySemaphores01=myBinarySem01,Dynamic,NULL -FREERTOS.IPParameters=Tasks01,BinarySemaphores01,configTOTAL_HEAP_SIZE +FREERTOS.IPParameters=Tasks01,BinarySemaphores01,configTOTAL_HEAP_SIZE,configUSE_TIMERS,configTIMER_TASK_PRIORITY FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL +FREERTOS.configTIMER_TASK_PRIORITY=4 FREERTOS.configTOTAL_HEAP_SIZE=196608 +FREERTOS.configUSE_TIMERS=1 File.Version=6 GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false diff --git a/esp_hosted_fg/host/stm32/proj/stm_spi_host_v2.ioc b/esp_hosted_fg/host/stm32/proj/spi/stm_spi_host_v2.ioc similarity index 98% rename from esp_hosted_fg/host/stm32/proj/stm_spi_host_v2.ioc rename to esp_hosted_fg/host/stm32/proj/spi/stm_spi_host_v2.ioc index 23d46b5378..6af65d1cc3 100644 --- a/esp_hosted_fg/host/stm32/proj/stm_spi_host_v2.ioc +++ b/esp_hosted_fg/host/stm32/proj/spi/stm_spi_host_v2.ioc @@ -23,9 +23,11 @@ Dma.SPI1_TX.1.PeriphInc=DMA_PINC_DISABLE Dma.SPI1_TX.1.Priority=DMA_PRIORITY_LOW Dma.SPI1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode FREERTOS.BinarySemaphores01=myBinarySem01,Dynamic,NULL -FREERTOS.IPParameters=Tasks01,BinarySemaphores01,configTOTAL_HEAP_SIZE +FREERTOS.IPParameters=Tasks01,BinarySemaphores01,configTOTAL_HEAP_SIZE,configUSE_TIMERS,configTIMER_TASK_PRIORITY FREERTOS.Tasks01=defaultTask,0,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL +FREERTOS.configTIMER_TASK_PRIORITY=4 FREERTOS.configTOTAL_HEAP_SIZE=196608 +FREERTOS.configUSE_TIMERS=1 File.Version=6 GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false diff --git a/esp_hosted_fg/host/virtual_serial_if/src/serial_if.c b/esp_hosted_fg/host/virtual_serial_if/src/serial_if.c index e4a77682d6..34e50e13a0 100644 --- a/esp_hosted_fg/host/virtual_serial_if/src/serial_if.c +++ b/esp_hosted_fg/host/virtual_serial_if/src/serial_if.c @@ -14,7 +14,7 @@ #define PROTO_PSER_TLV_T_EPNAME 0x01 #define PROTO_PSER_TLV_T_DATA 0x02 -#ifdef STM32F469xx +#ifdef MCU #define command_log(format, ...) printf(format "\r", ##__VA_ARGS__); #else #define command_log(...) printf("%s:%u ",__func__,__LINE__); \