]> Git Repo - esp-hosted.git/blob - README.md
Merge branch 'feature/update_readme' into 'master'
[esp-hosted.git] / README.md
1 # Hosted solution with ESP32
2 This project adds a capability to use ESP32 as a communication processor for Wi-Fi and bluetooth/BLE connectivity with an external host. The project provides ESP32 side firmware, example Linux driver and protocol description. This can directly be used with Linux based hosts or can easily be ported to other MCUs with available open protocol description.
3
4 ## Wi-Fi connectivity solution
5 This project uses a protobuf based command-set for control path and uses a separate connection (currently supported on SDIO) for data path. The ESP32 provides a simple interface to the host to provide ethernet interface that can transmit and receive 802.3 frames. This allows the TCP/IP and higher level protocol stack to run on the host.
6
7 ## Bluetooth/BLE connectivity solution
8 This functionality is provided through standard HCI interface created either over SDIO or UART. Linux based host can use standard hci tools/commands to control this interface.
9
10 # Setup
11 Currently we support ESP32 WROVER-Kit with Raspberry-Pi (3 Model B+, 4 Model B) for evaluation with Raspbian operating system.
12
13 ## Raspberry-Pi Software Setup
14 We recommend full version Raspbian install on Raspberry-Pi to ensure easy driver compilation. In addition for driver compilation, kernel headers are required. Please install them as:
15 ```sh
16 $ sudo apt update
17 $ sudo apt-get install raspberrypi-kernel-headers
18 ```
19 Verify that kernel headers are installed properly by running following command. Failure of this command indicates that kernel headers are not installed. In such case, upgrade/downgrade kernel and reinstall kernel headers.
20 ```sh
21 $ ls /lib/modules/$(uname -r)/build
22 ```
23 Python is required to run utility scripts. Please install it as:
24 ```sh
25 $ sudo apt-get install python
26 ```
27 To start with control path on Raspberry-Pi, `protobuf` and `utils` python modules are needed. User can install these modules by running following commands.
28 ```
29 pip install utils
30 pip install protobuf
31 ```
32 Raspi-gpio utility is required to configure GPIO pins. Please install it as:
33 ```sh
34 $ sudo apt-get install raspi-gpio
35 ```
36
37 To test BT/BLE functionality on Raspberry-Pi `bluez`(official Linux Bluetooth protocol stack) is needed. check if Raspberry-Pi has installed `bluez` or not.
38 [link that can help to install bluez](https://scribles.net/updating-bluez-on-raspberry-pi-from-5-43-to-5-50/)
39
40 ### Note
41 ```
42 We have tested BT/BLE solution at bluez 5.43 and 5.45.
43 ```
44 make sure Raspberry-Pi should have `bluetoothctl`, `bluetoothd`, `hcitool`, `hciconfig` utilities.
45
46 ## Wi-Fi and BT/BLE connectivity Setup over SDIO
47 ### Hardware Setup/Connections
48 In this setup, ESP32 board acts as a SDIO peripheral and provides Wi-FI capabilities to host. Please connect ESP32 board to Raspberry-Pi with jumper cables as mentioned below. It may be good to use small length cables to ensure signal integrity.
49
50 | RPi Pin | ESP32 Pin | Function |
51 |:-------:|:---------:|:--------:|
52 | 13 | IO13 | DAT3 |
53 | 15 | IO14 | CLK |
54 | 16 | IO15 | CMD |
55 | 18 | IO2 | DAT0 |
56 | 22 | IO4 | DAT1 |
57 | 37 | IO12 | DAT2 |
58 | 39 | GND | GND |
59
60 RPI pinout can be found [here!](https://pinout.xyz/pinout/sdio)
61
62 Setup image is here.
63
64 ![alt text](setup_image/rpi_esp_setup.jpeg "setup of RPI as host and ESP32 as slave")
65
66 Power ESP32 and Raspberry Pi separately with a power supply that provide sufficient power. ESP32 can be powered through PC using micro-USB cable.
67
68 ### Software setup
69 By default, the SDIO pins of Raspberry-pi are not configured and are internally used for built-in Wi-Fi interface. Please enable SDIO pins by appending following line to _/boot/config.txt_ file
70 ```
71 dtoverlay=sdio,poll_once=off
72 dtoverlay=disable-bt
73 ```
74 Please reboot Raspberry-Pi after changing this file.
75
76 ## Bluetooth/BLE connectivity Setup over UART
77 ### Hardware Setup/Connections
78 In this setup, ESP32 board provides Bluetooth/BLE capabilities to host over UART interface. Please connect ESP32 board to Raspberry-Pi with jumper cables as below. As mentioned above, use small length cables.
79
80 | RPi Pin Function | RPi Pin | ESP32 Pin | ESP32 Pin Function |
81 |:-------:|:--------:|:---------:|:--------:|
82 | RX | 10 | IO5 | TX |
83 | TX | 8 | IO18 | RX |
84 | CTS | 36 | IO19 | RTS |
85 | RTS | 11 | IO23 | CTS |
86 | Ground | 39 | GND | Ground |
87
88 ### Software setup
89 By default, the UART pins on Raspberry-Pi are in disabled state. In order to enable UART and setup it for bluetooth connection, follow below steps.
90 1. Enable UART pins and disable in built bluetooth on Raspberry-Pi by appending following lines to _/boot/config.txt_ file
91 ```
92 enable_uart=1
93 dtoverlay=disable-bt
94 ```
95 2. Remove following from _/boot/cmdline.txt_. Leave everything else untouched.
96 ```
97 console=serial0,115200
98 ```
99 e.g. If _/boot/cmdline.txt_ is as below:
100 ```
101 # cat /boot/cmdline.txt
102 dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=PARTUUID=5c2c80d1-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles spidev.bufsiz=32768
103 ````
104 Then after removal of above mentioned arguments, it should look as below:
105 ```
106 # cat /boot/cmdline.txt
107 dwc_otg.lpm_enable=0 console=tty1 root=PARTUUID=5c2c80d1-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles spidev.bufsiz=32768
108 ```
109 3. Disable hciuart on Raspberry-Pi
110 ```
111 # systemctl disable hciuart
112 ```
113 4. Reboot Raspberry-Pi
114
115 ## ESP32 Setup
116 The control path between Raspberry-Pi and ESP32 is based on `protobuf`. For that `protocomm` layer from ESP-IDF is used. Make sure ESP-IDF on branch `release/v4.0`. Run following command on esp32 to make `protocomm_priv.h` available for control path.
117 ```
118 git mv components/protocomm/src/common/protocomm_priv.h components/protocomm/include/common/
119 ```
120
121 On ESP32 either use pre-provided hosted mode firmware binary or if you have source, compile the app against ESP-IDF 4.0 release by running command as `make` in `slave_driver/network_adapter` directory. Program the WROVER-KIT using standard flash programming procedure with
122 ```sh
123 $ make flash
124 ```
125
126 ## Checking the Setup
127 Once ESP32 has a valid firmware and booted successfully, you should be able to see successful enumeration on Raspberry Pi side as:
128 ```sh
129 $ dmesg
130 [  143.606119] mmc1: queuing unknown CIS tuple 0x01 (3 bytes)
131 [  143.613524] mmc1: queuing unknown CIS tuple 0x1a (5 bytes)
132 [  143.617844] mmc1: queuing unknown CIS tuple 0x1b (8 bytes)
133 [  143.620070] mmc1: queuing unknown CIS tuple 0x80 (1 bytes)
134 [  143.620167] mmc1: queuing unknown CIS tuple 0x81 (1 bytes)
135 [  143.620265] mmc1: queuing unknown CIS tuple 0x82 (1 bytes)
136 [  143.622073] mmc1: queuing unknown CIS tuple 0x80 (1 bytes)
137 [  143.622169] mmc1: queuing unknown CIS tuple 0x81 (1 bytes)
138 [  143.622266] mmc1: queuing unknown CIS tuple 0x82 (1 bytes)
139 [  143.622461] mmc1: new SDIO card at address 0001
140 [  148.095780] esp32: loading out-of-tree module taints kernel.
141 [  148.314969] Initialising ESP Serial support
142 [  148.320686] esp32_probe: ESP network device detected
143 ```
144 Once the module is inserted, you should see ethap0 and ethsta0 interfaces using _ifconfig_ command.
145
146 # Protocol Definition
147 This driver is divided in 3 parts:
148 1. Network driver - This part registers a network interface with linux kernel and implements netdev ops
149 2. SDIO driver - This is a transport layer. It interacts with wlan module on ESP32 through sdio interface
150 3. Serial driver - This provides a control interface through which wlan module on ESP32 can be controlled. This basically uses SDIO for low level transport.
151
152 The following section explains the protocol of SDIO driver i.e. transport layer.
153 ESP32 module advertises 2 SDIO functions, of which function 1 implements WLAN slave device. Though function 2 is advertised, it is not in use.
154
155 ## Important registers provided by ESP32 wlan device
156 * 0x3FF5508C: Interrupt vector used by host to interrupt slave
157 * 0x3FF55058: Interrupt status register used by slave to interrupt host
158 * 0x3FF55060: Accumulated value of data length sent by slave
159 * 0x3FF55044: Accumulated number of buffers for receiving packets at slave
160
161 ## Initialization of slave device
162 1. Soft reset sdio slave
163         1. Host resets sdio part of slave by setting bit 2 of register at 0x3FF5508C
164         2. This generates an interrupt for slave device, on which firmware on slave resets its sdio related data structures.
165 2. Host reads accumulated length and buffer count at slave.
166         1. Host reads and processes 0x3FF55060 and 0x3FF55044 registers and stores the values in it's data structure
167         2. These counters are required while performing read and write operation on SDIO interface
168 3. Open data path on slave
169         1. Host sets 0th bit of 0x3FF5508C interrupt register
170         2. This indicates slave that host is ready for data transmission
171
172 ## Data transfer from Host to slave
173 1. Get Buffer count
174         1. Host reads the current buffer count from slave [0x3FF55044]
175         2. Based on that value, host calculates the number of available buffers at slave
176         3. The host transfers the packet only when slave has required number of free buffers.
177         4. Size of a buffer at slave is 2048 bytes
178 2. The host transfers data in multiples of 512 bytes and max data length per write operation is limited to buffer size [2048 bytes]
179 3. Host then updates it's own counter that keeps track of number of buffers it has transmitted.
180
181 ## Data transfer from slave to host
182 1. Whenever slave has data to tranfser, it updates the length in 0x3FF55060 registers and generates an interrupt for host.
183 2. On interruption, host reads interrupt status register [0x3FF55058]. Bit 23 of this register tells host that slave desires to send data.
184 3. Host then gets the length set by slave by reading register mentioned in step 1. Based on previous received byte count and this length, host understands the actual length of data packet.
185 4. Host performs read operation to get data from slave
186 5. Once it receives the data, it updates it's counter that stores byte count received from slave.
187
188 `Note: Slave stays in blocked state during steps 1 to 4 [ i.e till host reads the data packet]`
189
190 ## Deinit slave device
191 Host sets bit 1 of 0x3FF5508C interrupt register. This tells slave device to stop the data path.
192
193 ## Payload format for data transfer
194 * Host and slave makes use of 8 byte payload header which preceeds every data packet. This payload header provides additional information about the data packet. Based on this header, host/slave consumes transmitted data packet.
195
196 * Payload format is as below
197
198 | Field | Length | Description |
199 |:-------:|:---------:|:--------:|
200 | packet type | 2 bits | Not in use |
201 | interface type | 3 bits | possible values: STA(0), AP(1), Serial interface(2). Rest all values are reserved |
202 | interface number | 3 bits | Not in use |
203 | reserved | 1 byte | Not in use |
204 | packet length | 2 bytes | Actual length of data packet |
205 | offset to packet | 2 bytes | Offset of actual data packet |
206 | reserved | 2 bytes  | Not in use |
207
208 # How to Run scripts on Raspberry-Pi(rpi)
209 ## For Wi-Fi Connectivity
210 There is `host_comm` folder in which `host_commands` python library is present. It contains following functions.
211 ```
212 get_mac(mode)
213 get_wifi_mode()
214 set_wifi_mode(mode)
215 wifi_set_ap_config(ssid, pwd, bssid)
216 wifi_get_ap_config()
217 wifi_disconnect_ap()
218 wifi_set_softap_config(ssid, pwd, chnl, ecn, max_conn, ssid_hidden, bw)
219 wifi_get_softap_config()
220 wifi_ap_scan_list()
221 wifi_connected_stations_list()
222 ```
223
224 User can make use of these python functions to get access of wifi functionalities of ESP32. Also in `host_comm/host_commands` folder `test.py` python script present to try those python functions. User can use it by running following command.
225 ```
226 python test.py
227 ```
228
229 first run `./rpi_init.sh` to compile and insert ESP32 host driver on rpi. This script also creates `/dev/esps0` which is used as a WLAN/BT/BLE control interface.
230
231 There are six python scripts for station connect to AP, station disconnect from AP ,start softAP, stop softAP, scan available APs and list stations connected to softAP.
232
233 1. `station_connect.py` is a python script which configures ESP32 in `station mode`, connects rpi to external AP with credentials the user has provided. Also it ups the station interface and runs DHCP client. User should provide parameters like ssid, password, mac address of AP(Its optional parameter).
234
235 ```
236 ex. python station_connect.py 'xyz' 'xyz123456' --bssid='e5:6c:67:3c:cf:65'
237 ```
238 2. `station_disconnect.py` is a python script to disconnect ESP32 station from AP.
239
240 ```
241 python station_disconnect.py
242 ```
243 3. `softap_config.py` is a python script for configuring ESP32 `softAP mode`. User should provide parameters like ssid, password(password length should be 8~64 bytes ASCII), channel ID (It can be any numberbetween 1 to 11), encryption method (0 : OPEN, 2: WPA_PSK, 3:WPA2_PSK, 4: WPA_WPA2_PSK), max connection count( number of Stations to which ESP32 SoftAP can be connected, within the range of [1, 10]) and ssid hidden (it can set to 1 if softAP shouldnt broadcast its ssid else 0). max connection count and ssid hidden parameters are optional.
244
245 ```
246 ex. python softap_config.py 'xyz' 'xyz123456' 1 3 --max_conn=4 --ssid_hidden=0
247 ```
248 ---
249 Note: To start data connection, user needs to setup a DHCP server on rpi or set static IP address for AP interface i.e. ethap0
250
251 ---
252 4. `softap_stop.py` is a python script to stop ESP32 softap. This script will change wifi mode to `null` if only softAP is running or to `station` mode if softAP and station both are on.
253
254 ```
255 ex. python softap_stop.py
256 ```
257 5. `ap_scan_list.py` is a python script which gives a scanned list of available APs. list contains ssid, channel number, rssi, mac address and authentication mode of AP.
258 ```
259 ex. python ap_scan_list.py
260 ```
261 ---
262 Note: To start data connection, user needs to setup a DHCP server on rpi or set static IP address for AP interface i.e. ethap0
263
264 ---
265 6. `connected_stations_list.py` is a python script that returns list of mac addresses of stations connected to softAP.
266
267 ```
268 ex. python connected_stations_list.py
269 ```
270 ### Open air throughput test results for WLAN
271 Following are the test results conducted in open air.
272 ```
273 UDP Tx: 16.4 Mbps
274 UDP Rx: 16.8 Mbps
275 TCP Tx: 14 Mbps
276 TCP Rx: 12 Mbps
277 ```
278
279 ## For Bluetooth/BLE functionality
280 ### UART based setup
281 1. Execute `./rpi_init.sh btuart` to prepare RPi for Bluetooth operation
282 2. Execute `hciattach` command as below to add hci interface
283 ```
284 $ sudo hciattach -s 115200 /dev/serial0 any 115200 flow
285 ```
286
287 ### SDIO based setup
288 HCI interface will be available for use as soon as host driver detects esp32 device over SDIO interface.
289 User can use standard hci utilities over this interface to make use of BT/BLE feature.
290
291 ## For Testing of BT/BLE connection
292
293 We have used [nRF connect for mobile APP](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&hl=en_IN) for testing of BT/BLE.
294
295 ### GATT server
296
297 1. `sudo modprobe bluetooth` on rpi
298 2. run `hciconfig`. Output should show only one `SDIO` interface.
299 ```
300 hci0:   Type: Primary  Bus: SDIO
301         BD Address: 3C:71:BF:9A:C2:46  ACL MTU: 1021:9  SCO MTU: 255:4
302         UP RUNNING PSCAN
303         RX bytes:8801 acl:1000 sco:0 events:406 errors:0
304         TX bytes:5097 acl:147 sco:0 commands:52 errors:0
305 ```
306 3. Go to `bluez-5.xx` folder. Run `./test/example-gatt-server`. This will start gatt server on Raspberry-Pi.
307
308 4. Now start advertising. Run `sudo hciconfig hci0 leadv`.
309
310 5. Now esp32's mac address should be listed in scan list of mobile app.
311
312 6. Connect to esp32's mac address with mobile as gatt client.
313
314 7. User can check read/write characteristics fields in `Heart Rate` service.
315
316 ## GATT Client
317
318 1. User can run `./test/example-gatt-client` on rpi. This will start gatt client on Raspberry-Pi.
319
320 2. User will receive `Heart Rate Measurement` field in rpi console.
321
322 ## BT scan
323
324 User can run `hcitool scan` for BT device scanning.
325
326 ## BLE scan
327
328 User can run `hcitool lescan` for BLE device scanning.
This page took 0.042952 seconds and 4 git commands to generate.