├── .cargo └── config ├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── tasks.json ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── examples └── test.rs ├── generate ├── bindgen.sh ├── coexist_wrapper.h ├── sdkconfig.h └── wifi_wrapper.h ├── partitions.csv └── src ├── binary ├── coexist.rs ├── ctypes.rs ├── mod.rs ├── phy.rs └── wifi.rs ├── compatibility ├── crypto.rs ├── implicit.rs ├── mod.rs └── osi.rs ├── lib.rs ├── log.rs ├── timer.rs └── wifi.rs /.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "xtensa-esp32-none-elf" 3 | 4 | rustflags = [ 5 | "-C", "link-arg=-nostartfiles", 6 | "-C", "link-arg=-Wl,-Tlink.x", 7 | ] 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | core -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "esp32-wifi-lib"] 2 | path = esp32-wifi-lib 3 | url = git@github.com:espressif/esp32-wifi-lib.git 4 | branch = release/v4.1 5 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | // more info at: https://github.com/Marus/cortex-debug/blob/master/package.json 9 | "name": "Attach", 10 | "type": "cortex-debug", 11 | "request": "attach", // attach instead of launch, because otherwise flash write is attempted, but fails 12 | "cwd": "${workspaceRoot}", 13 | "executable": "target/current.elf", 14 | "servertype": "openocd", 15 | "interface": "jtag", 16 | "svdFile": "../esp32/svd/esp32.svd", 17 | "toolchainPrefix": "xtensa-esp32-elf", 18 | "openOCDPreConfigLaunchCommands": [ 19 | "set ESP_RTOS none" 20 | ], 21 | "configFiles": [ 22 | "board/esp32-wrover-kit-3.3v.cfg" 23 | ], 24 | "overrideAttachCommands": [ 25 | "set remote hardware-watchpoint-limit 2", 26 | "mon halt", 27 | "flushregs" 28 | ], 29 | "overrideRestartCommands": [ 30 | "mon reset halt", 31 | "flushregs", 32 | "c", 33 | ] 34 | }, 35 | { 36 | // more info at: https://github.com/Marus/cortex-debug/blob/master/package.json 37 | "name": "Flash & Launch", 38 | "type": "cortex-debug", 39 | "preLaunchTask": "Build Example", 40 | "request": "launch", // attach instead of launch, because otherwise flash write is attempted, but fails 41 | "cwd": "${workspaceRoot}", 42 | "executable": "target/current.elf", 43 | "servertype": "openocd", 44 | "interface": "jtag", 45 | "svdFile": "../esp32/svd/esp32.svd", 46 | "toolchainPrefix": "xtensa-esp32-elf", 47 | "openOCDPreConfigLaunchCommands": [ 48 | "set ESP_RTOS none" 49 | ], 50 | "configFiles": [ 51 | "board/esp32-wrover-kit-3.3v.cfg" 52 | ], 53 | "overrideLaunchCommands": [ 54 | "mon program_esp32 target/current.bin 0x10000 verify reset hex", 55 | "flushregs", 56 | ], 57 | "postStartSessionCommands": [ 58 | "thb main", 59 | "continue" 60 | ], 61 | "overrideRestartCommands": [ 62 | "mon program_esp32 target/current.bin 0x10000 verify reset hex", 63 | "flushregs", 64 | "thb main", 65 | "continue", 66 | ] 67 | }, 68 | ] 69 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build and Flash Example", 8 | "type": "shell", 9 | "runOptions": { 10 | "reevaluateOnRerun": false 11 | }, 12 | "command": "../esp32-hal/flash -t --example ${input:example}", 13 | "problemMatcher": { 14 | "base": "$rustc", 15 | "fileLocation": [ 16 | "relative" 17 | ] 18 | }, 19 | "group": "build", 20 | "presentation": { 21 | "reveal": "silent", 22 | "panel": "shared", 23 | "clear": true 24 | } 25 | }, 26 | { 27 | "label": "Build Example", 28 | "type": "shell", 29 | "runOptions": { 30 | "reevaluateOnRerun": false 31 | }, 32 | "command": "../esp32-hal/flash -s --example ${input:example}", 33 | "problemMatcher": { 34 | "base": "$rustc", 35 | "fileLocation": [ 36 | "relative" 37 | ] 38 | }, 39 | "group": { 40 | "kind": "build", 41 | "isDefault": true 42 | }, 43 | "presentation": { 44 | "reveal": "silent", 45 | "panel": "shared", 46 | "clear": true 47 | } 48 | }, 49 | { 50 | "label": "Compile All Examples", 51 | "type": "shell", 52 | "command": "cargo xbuild --examples", 53 | "problemMatcher": { 54 | "base": "$rustc", 55 | "fileLocation": [ 56 | "relative" 57 | ] 58 | }, 59 | "group": "build", 60 | "presentation": { 61 | "reveal": "always", 62 | "panel": "shared", 63 | "clear": true 64 | } 65 | }, 66 | { 67 | "label": "Build Documentation", 68 | "type": "shell", 69 | "command": "cargo xdoc --open --all-features", 70 | "problemMatcher": { 71 | "base": "$rustc", 72 | "fileLocation": [ 73 | "relative" 74 | ] 75 | }, 76 | "group": "build", 77 | "presentation": { 78 | "reveal": "silent", 79 | "panel": "shared", 80 | "clear": true 81 | } 82 | } 83 | ], 84 | "inputs": [ 85 | // requires Tasks Shell Input extension 86 | { 87 | "id": "example", 88 | "type": "command", 89 | "command": "shellCommand.execute", 90 | "args": { 91 | "command": "cargo check --offline --example 2>&1 |egrep '^ '| sed -E 's/[ \t]*//g'", 92 | "cwd": "${workspaceFolder}/../esp32-wifi" 93 | } 94 | }, 95 | // alternatively type in manually 96 | { 97 | "id": "examplePrompt", 98 | "description": "Example:", 99 | "default": "serial", 100 | "type": "promptString" 101 | } 102 | ] 103 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "esp32-wifi" 3 | version = "0.1.0" 4 | authors = ["Arjan Mels "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | esp32-hal = { path = "../esp32-hal", features=["alloc"]} 11 | esp32 = "0.6.0" 12 | cstr_core = "0.2.0" 13 | cty = "0.2.1" 14 | xtensa-lx6 = "0.2.0" 15 | num-derive = "0.3" 16 | num-traits = { version="0.2", default-features = false } 17 | spin = "0.5.2" 18 | embedded-hal = { version = "0.2.3", features = ["unproven"] } 19 | nb = "0.1.2" 20 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright 2019-2020 Contributors to xtensa-lx6-rt 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esp32-wifi 2 | 3 | ## NOTE: Superceded by [esp-wifi](https://github.com/esp-rs/esp-wifi). 4 | 5 | A experimental wifi driver for the [esp32](https://en.wikipedia.org/wiki/ESP32) written in Rust. 6 | 7 | Contributions are welcome :) 8 | 9 | Join in on the discussion: https://matrix.to/#/#esp-rs:matrix.org! 10 | 11 | ## Building 12 | 13 | This crate uses the esp-idf binary blobs for wifi functionality. The C foreign function interface is generated with bindgen. This is done using the generate/bindgen.sh script, but only needs to be done again when the version of the binary blobs is changed. 14 | 15 | The generate/bindgen.sh can be called from the root directory to create the various files in 16 | src/binary. The version of esp-idf used should match the version of the binary blobs in the 17 | esp32-wifi-lib sub-repository. (Currently version v4.1 of the esp-idf is used.) 18 | 19 | ## License 20 | 21 | Licensed under either of 22 | 23 | - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or 24 | http://www.apache.org/licenses/LICENSE-2.0) 25 | - MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 26 | 27 | at your option. 28 | 29 | ### Contribution 30 | 31 | Unless you explicitly state otherwise, any contribution intentionally submitted 32 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 33 | dual licensed as above, without any additional terms or conditions. 34 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | // Add linker search path 3 | println!("cargo:rustc-link-search=esp32-wifi-lib/esp32"); 4 | 5 | //println!("cargo:rustc-link-lib=espnow"); 6 | // println!("cargo:rustc-link-lib=mesh"); 7 | println!("cargo:rustc-link-lib=net80211"); 8 | println!("cargo:rustc-link-lib=pp"); 9 | println!("cargo:rustc-link-lib=rtc"); 10 | // println!("cargo:rustc-link-lib=smartconfig"); 11 | println!("cargo:rustc-link-lib=core"); 12 | println!("cargo:rustc-link-lib=phy"); 13 | println!("cargo:rustc-link-lib=coexist"); 14 | } 15 | -------------------------------------------------------------------------------- /examples/test.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | #![feature(alloc_error_handler)] 4 | 5 | use core::{fmt::Write, panic::PanicInfo}; 6 | use cstr_core::CStr; 7 | 8 | use esp32_hal::{ 9 | clock_control::{sleep, ClockControl, ClockControlConfig, XTAL_FREQUENCY_AUTO}, 10 | dport::Split, 11 | dprintln, 12 | interrupt::Interrupt, 13 | prelude::*, 14 | serial::{config::Config, Pins, Serial}, 15 | target, 16 | timer::Timer, 17 | }; 18 | 19 | use esp32_wifi::timer::{TimerFactoryImpl, TimerInterruptHandler}; 20 | 21 | use esp32_hal::alloc::{Allocator, DEFAULT_ALLOCATOR}; 22 | 23 | #[global_allocator] 24 | pub static GLOBAL_ALLOCATOR: Allocator = DEFAULT_ALLOCATOR; 25 | 26 | #[alloc_error_handler] 27 | fn alloc_error_handler(layout: core::alloc::Layout) -> ! { 28 | panic!( 29 | "Error allocating {} bytes of memory with alignment {}", 30 | layout.size(), 31 | layout.align() 32 | ); 33 | } 34 | 35 | static TIMER_HANDLER: TimerInterruptHandler> = 36 | TimerInterruptHandler::new(); 37 | 38 | #[interrupt] 39 | fn TG0_LACT_LEVEL_INTR() { 40 | TIMER_HANDLER.handle(); 41 | } 42 | 43 | #[entry] 44 | fn main() -> ! { 45 | let dp = target::Peripherals::take().expect("Failed to obtain Peripherals"); 46 | 47 | let (_, dport_clock_control) = dp.DPORT.split(); 48 | 49 | let clkcntrl = ClockControl::new( 50 | dp.RTCCNTL, 51 | dp.APB_CTRL, 52 | dport_clock_control, 53 | XTAL_FREQUENCY_AUTO, 54 | ) 55 | .unwrap(); 56 | 57 | let (clkcntrl_config, mut watchdog) = clkcntrl.freeze().unwrap(); 58 | watchdog.disable(); 59 | 60 | let (_, _, wifi_timer, mut watchdog0) = Timer::new(dp.TIMG0, clkcntrl_config); 61 | let (_, _, _, mut watchdog1) = Timer::new(dp.TIMG1, clkcntrl_config); 62 | watchdog0.disable(); 63 | watchdog1.disable(); 64 | 65 | let pins = dp.GPIO.split(); 66 | 67 | let mut serial: Serial<_, _, _> = Serial::new( 68 | dp.UART0, 69 | Pins { 70 | tx: pins.gpio1, 71 | rx: pins.gpio3, 72 | cts: None, 73 | rts: None, 74 | }, 75 | Config { 76 | // default configuration is 19200 baud, 8 data bits, 1 stop bit & no parity (8N1) 77 | baudrate: 921600.Hz(), 78 | ..Config::default() 79 | }, 80 | clkcntrl_config, 81 | ) 82 | .unwrap(); 83 | 84 | writeln!(serial, "\n\nESP32 Started\n\n").unwrap(); 85 | 86 | // (&TX).lock(|tx| *tx = Some(serial.split().0)); 87 | 88 | interrupt::enable(Interrupt::TG0_LACT_LEVEL_INTR).unwrap(); 89 | 90 | unsafe { 91 | writeln!( 92 | serial, 93 | "Coexist library version: {}", 94 | CStr::from_ptr(esp32_wifi::binary::coexist::coex_version_get()) 95 | .to_str() 96 | .unwrap() 97 | ) 98 | .unwrap(); 99 | writeln!( 100 | serial, 101 | "Phy RF calibration data version: {}", 102 | esp32_wifi::binary::phy::phy_get_rf_cal_version() 103 | ) 104 | .unwrap(); 105 | writeln!( 106 | serial, 107 | "Wifi set_log_level result: {:8x}", 108 | esp32_wifi::binary::wifi::esp_wifi_internal_set_log_level( 109 | esp32_wifi::binary::wifi::wifi_log_level_t::WIFI_LOG_VERBOSE 110 | ) 111 | ) 112 | .unwrap(); 113 | 114 | writeln!(serial, "WiFi::new:").unwrap(); 115 | 116 | { 117 | writeln!(serial, "timer_factory pre-created").unwrap(); 118 | 119 | let mut timer_factory = TimerFactoryImpl::new(wifi_timer); 120 | 121 | writeln!(serial, "timer_factory created").unwrap(); 122 | 123 | TIMER_HANDLER.set_timer_factory(&mut timer_factory); 124 | 125 | writeln!(serial, "set_timer_factory").unwrap(); 126 | 127 | let wifi = esp32_wifi::wifi::WiFi::new(clkcntrl_config, &mut timer_factory).unwrap(); 128 | 129 | writeln!(serial, "set_mode:").unwrap(); 130 | 131 | wifi.set_mode(esp32_wifi::wifi::Mode::WIFI_MODE_STA) 132 | .unwrap(); 133 | 134 | writeln!(serial, "set_station_config:").unwrap(); 135 | 136 | wifi.set_station_config(&mut esp32_wifi::binary::wifi::wifi_sta_config_t { 137 | ..Default::default() 138 | }) 139 | .unwrap(); 140 | 141 | writeln!(serial, "start:").unwrap(); 142 | 143 | wifi.start().unwrap(); 144 | 145 | writeln!(serial, "start scan:").unwrap(); 146 | 147 | let count = wifi.scan().unwrap(); 148 | 149 | writeln!(serial, "\n\nAP's found: {}", count).unwrap(); 150 | 151 | writeln!(serial, "\n\nFinished wifi calls").unwrap(); 152 | } 153 | } 154 | 155 | writeln!(serial, "\n\nEntering loop...").unwrap(); 156 | 157 | loop { 158 | sleep(1.s()); 159 | } 160 | } 161 | 162 | #[panic_handler] 163 | fn panic(info: &PanicInfo) -> ! { 164 | // park the other core 165 | unsafe { ClockControlConfig {}.park_core(esp32_hal::get_other_core()) }; 166 | 167 | // print panic message 168 | dprintln!("\n\n*** Core: {:?} {:?}", esp32_hal::get_core(), info); 169 | 170 | // park this core 171 | unsafe { ClockControlConfig {}.park_core(esp32_hal::get_core()) }; 172 | 173 | dprintln!("\n\n Should not reached because core is parked!!!"); 174 | 175 | // this statement will not be reached, but is needed to make this a diverging function 176 | loop {} 177 | } 178 | -------------------------------------------------------------------------------- /generate/bindgen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$IDF_PATH" ] 4 | then 5 | IDF_PATH=~/esp/v4.1 6 | fi 7 | BASE=$IDF_PATH/components 8 | LIBS=$(find $BASE -name "include" |grep -v esp32s2| xargs -I{} echo -n "-I {} ") 9 | 10 | TOOLS=$(realpath $(dirname $(which xtensa-esp32-elf-gcc))/..) 11 | TOOL_INCLUDE=$TOOLS/xtensa-esp32-elf/include 12 | 13 | BINDGEN_OPTS="--no-layout-tests --use-core --size_t-is-usize --no-prepend-enum-name --ctypes-prefix cty --raw-line #![allow(non_camel_case_types)] --raw-line #![allow(intra_doc_link_resolution_failure)] --default-enum-style rust" 14 | BINDGEN_CLANG_OPTS="-- -D__GLIBC_USE(x)=0 -DSSIZE_MAX -I ./generate -I $TOOL_INCLUDE -I $BASE/freertos/include $LIBS -I $BASE/lwip/include/apps/sntp/ -I $BASE/lwip/include/apps" 15 | 16 | echo "Generating phy.rs" 17 | bindgen $BASE/esp_wifi/include/phy.h -o src/binary/phy.rs \ 18 | --whitelist-function "phy.*" --whitelist-function "coex.*" --whitelist-function ".*_phy" \ 19 | $BINDGEN_OPTS $BINDGEN_CLANG_OPTS 20 | 21 | WIFI_FUNCTIONS=$(xtensa-esp32-elf-objdump -t esp32-wifi-lib/esp32/libnet80211.a |grep esp_wifi|grep -v internal|grep "F .text"| awk '{printf("%s|",$6)}') 22 | 23 | echo "Generating wifi.rs" 24 | bindgen generate/wifi_wrapper.h -o src/binary/wifi.rs \ 25 | --with-derive-default \ 26 | --whitelist-function $WIFI_FUNCTIONS"(.*wifi.*internal.*)" \ 27 | $BINDGEN_OPTS $BINDGEN_CLANG_OPTS 28 | 29 | echo "Generating coexist.rs" 30 | bindgen generate/coexist_wrapper.h -o src/binary/coexist.rs \ 31 | --whitelist-function "coex.*" --whitelist-function "esp_coex.*" \ 32 | $BINDGEN_OPTS $BINDGEN_CLANG_OPTS 33 | -------------------------------------------------------------------------------- /generate/coexist_wrapper.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "esp_coexist_internal.h" -------------------------------------------------------------------------------- /generate/sdkconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Automatically generated file. DO NOT EDIT. 3 | * Espressif IoT Development Framework (ESP-IDF) Configuration Header 4 | */ 5 | #pragma once 6 | #define CONFIG_IDF_CMAKE 1 7 | #define CONFIG_IDF_TARGET "esp32" 8 | #define CONFIG_IDF_TARGET_ESP32 1 9 | #define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0000 10 | #define CONFIG_SDK_TOOLPREFIX "xtensa-esp32-elf-" 11 | #define CONFIG_APP_BUILD_TYPE_APP_2NDBOOT 1 12 | #define CONFIG_APP_BUILD_GENERATE_BINARIES 1 13 | #define CONFIG_APP_BUILD_BOOTLOADER 1 14 | #define CONFIG_APP_BUILD_USE_FLASH_SECTIONS 1 15 | #define CONFIG_APP_COMPILE_TIME_DATE 1 16 | #define CONFIG_APP_RETRIEVE_LEN_ELF_SHA 16 17 | #define CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE 1 18 | #define CONFIG_BOOTLOADER_LOG_LEVEL_INFO 1 19 | #define CONFIG_BOOTLOADER_LOG_LEVEL 3 20 | #define CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V 1 21 | #define CONFIG_BOOTLOADER_WDT_ENABLE 1 22 | #define CONFIG_BOOTLOADER_WDT_TIME_MS 9000 23 | #define CONFIG_BOOTLOADER_RESERVE_RTC_SIZE 0x0 24 | #define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 25 | #define CONFIG_ESPTOOLPY_FLASHMODE_DIO 1 26 | #define CONFIG_ESPTOOLPY_FLASHMODE "dio" 27 | #define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1 28 | #define CONFIG_ESPTOOLPY_FLASHFREQ "40m" 29 | #define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1 30 | #define CONFIG_ESPTOOLPY_FLASHSIZE "2MB" 31 | #define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1 32 | #define CONFIG_ESPTOOLPY_BEFORE_RESET 1 33 | #define CONFIG_ESPTOOLPY_BEFORE "default_reset" 34 | #define CONFIG_ESPTOOLPY_AFTER_RESET 1 35 | #define CONFIG_ESPTOOLPY_AFTER "hard_reset" 36 | #define CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B 1 37 | #define CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL 115200 38 | #define CONFIG_ESPTOOLPY_MONITOR_BAUD 115200 39 | #define CONFIG_PARTITION_TABLE_SINGLE_APP 1 40 | #define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv" 41 | #define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv" 42 | #define CONFIG_PARTITION_TABLE_OFFSET 0x8000 43 | #define CONFIG_PARTITION_TABLE_MD5 1 44 | #define CONFIG_ESP_WIFI_SSID "myssid" 45 | #define CONFIG_ESP_WIFI_PASSWORD "mypassword" 46 | #define CONFIG_ESP_MAXIMUM_RETRY 5 47 | #define CONFIG_COMPILER_OPTIMIZATION_DEFAULT 1 48 | #define CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 1 49 | #define CONFIG_COMPILER_STACK_CHECK_MODE_NONE 1 50 | #define CONFIG_APPTRACE_DEST_NONE 1 51 | #define CONFIG_APPTRACE_LOCK_ENABLE 1 52 | #define CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF 0 53 | #define CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF 0 54 | #define CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF 0 55 | #define CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF 0 56 | #define CONFIG_BTDM_CTRL_PINNED_TO_CORE 0 57 | #define CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF 1 58 | #define CONFIG_BT_RESERVE_DRAM 0x0 59 | #define CONFIG_COAP_MBEDTLS_PSK 1 60 | #define CONFIG_COAP_LOG_DEFAULT_LEVEL 0 61 | #define CONFIG_ADC_DISABLE_DAC 1 62 | #define CONFIG_SPI_MASTER_ISR_IN_IRAM 1 63 | #define CONFIG_SPI_SLAVE_ISR_IN_IRAM 1 64 | #define CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4 1 65 | #define CONFIG_EFUSE_MAX_BLK_LEN 192 66 | #define CONFIG_ESP_TLS_USING_MBEDTLS 1 67 | #define CONFIG_ESP32_REV_MIN_0 1 68 | #define CONFIG_ESP32_REV_MIN 0 69 | #define CONFIG_ESP32_DPORT_WORKAROUND 1 70 | #define CONFIG_ESP32_DEFAULT_CPU_FREQ_160 1 71 | #define CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 160 72 | #define CONFIG_ESP32_TRACEMEM_RESERVE_DRAM 0x0 73 | #define CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR 1 74 | #define CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES 4 75 | #define CONFIG_ESP32_ULP_COPROC_RESERVE_MEM 0 76 | #define CONFIG_ESP32_PANIC_PRINT_REBOOT 1 77 | #define CONFIG_ESP32_DEBUG_OCDAWARE 1 78 | #define CONFIG_ESP32_BROWNOUT_DET 1 79 | #define CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0 1 80 | #define CONFIG_ESP32_BROWNOUT_DET_LVL 0 81 | #define CONFIG_ESP32_REDUCE_PHY_TX_POWER 1 82 | #define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1 83 | #define CONFIG_ESP32_RTC_CLK_SRC_INT_RC 1 84 | #define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024 85 | #define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000 86 | #define CONFIG_ESP32_XTAL_FREQ_40 1 87 | #define CONFIG_ESP32_XTAL_FREQ 40 88 | #define CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL 5 89 | #define CONFIG_ADC_CAL_EFUSE_TP_ENABLE 1 90 | #define CONFIG_ADC_CAL_EFUSE_VREF_ENABLE 1 91 | #define CONFIG_ADC_CAL_LUT_ENABLE 1 92 | #define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1 93 | #define CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 32 94 | #define CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE 2304 95 | #define CONFIG_ESP_MAIN_TASK_STACK_SIZE 3584 96 | #define CONFIG_ESP_IPC_TASK_STACK_SIZE 1024 97 | #define CONFIG_ESP_IPC_USES_CALLERS_PRIORITY 1 98 | #define CONFIG_ESP_TIMER_TASK_STACK_SIZE 3584 99 | #define CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE 2048 100 | #define CONFIG_ESP_CONSOLE_UART_DEFAULT 1 101 | #define CONFIG_ESP_CONSOLE_UART_NUM 0 102 | #define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200 103 | #define CONFIG_ESP_INT_WDT 1 104 | #define CONFIG_ESP_INT_WDT_TIMEOUT_MS 300 105 | #define CONFIG_ESP_INT_WDT_CHECK_CPU1 1 106 | #define CONFIG_ESP_TASK_WDT 1 107 | #define CONFIG_ESP_TASK_WDT_TIMEOUT_S 5 108 | #define CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 1 109 | #define CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 1 110 | #define CONFIG_ETH_ENABLED 1 111 | #define CONFIG_ETH_USE_ESP32_EMAC 1 112 | #define CONFIG_ETH_PHY_INTERFACE_RMII 1 113 | #define CONFIG_ETH_RMII_CLK_INPUT 1 114 | #define CONFIG_ETH_RMII_CLK_IN_GPIO 0 115 | #define CONFIG_ETH_DMA_BUFFER_SIZE 512 116 | #define CONFIG_ETH_DMA_RX_BUFFER_NUM 10 117 | #define CONFIG_ETH_DMA_TX_BUFFER_NUM 10 118 | #define CONFIG_ETH_USE_SPI_ETHERNET 1 119 | #define CONFIG_ETH_SPI_ETHERNET_DM9051 1 120 | #define CONFIG_ESP_EVENT_POST_FROM_ISR 1 121 | #define CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR 1 122 | #define CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS 1 123 | #define CONFIG_HTTPD_MAX_REQ_HDR_LEN 512 124 | #define CONFIG_HTTPD_MAX_URI_LEN 512 125 | #define CONFIG_HTTPD_ERR_RESP_NO_DELAY 1 126 | #define CONFIG_HTTPD_PURGE_BUF_LEN 32 127 | #define CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL 120 128 | #define CONFIG_ESP_NETIF_TCPIP_LWIP 1 129 | #define CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER 1 130 | #define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10 131 | #define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32 132 | #define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1 133 | #define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1 134 | #define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32 135 | #define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 1 136 | #define CONFIG_ESP32_WIFI_TX_BA_WIN 6 137 | #define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 1 138 | #define CONFIG_ESP32_WIFI_RX_BA_WIN 6 139 | #define CONFIG_ESP32_WIFI_NVS_ENABLED 1 140 | #define CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 1 141 | #define CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN 752 142 | #define CONFIG_ESP32_WIFI_MGMT_SBUF_NUM 32 143 | #define CONFIG_ESP32_WIFI_IRAM_OPT 1 144 | #define CONFIG_ESP32_WIFI_RX_IRAM_OPT 1 145 | #define CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE 1 146 | #define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1 147 | #define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20 148 | #define CONFIG_ESP32_PHY_MAX_TX_POWER 20 149 | #define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1 150 | #define CONFIG_FATFS_CODEPAGE_437 1 151 | #define CONFIG_FATFS_CODEPAGE 437 152 | #define CONFIG_FATFS_LFN_NONE 1 153 | #define CONFIG_FATFS_FS_LOCK 0 154 | #define CONFIG_FATFS_TIMEOUT_MS 10000 155 | #define CONFIG_FATFS_PER_FILE_CACHE 1 156 | #define CONFIG_FMB_COMM_MODE_RTU_EN 1 157 | #define CONFIG_FMB_COMM_MODE_ASCII_EN 1 158 | #define CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND 150 159 | #define CONFIG_FMB_MASTER_DELAY_MS_CONVERT 200 160 | #define CONFIG_FMB_QUEUE_LENGTH 20 161 | #define CONFIG_FMB_SERIAL_TASK_STACK_SIZE 2048 162 | #define CONFIG_FMB_SERIAL_BUF_SIZE 256 163 | #define CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB 8 164 | #define CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS 1000 165 | #define CONFIG_FMB_SERIAL_TASK_PRIO 10 166 | #define CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT 20 167 | #define CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE 20 168 | #define CONFIG_FMB_CONTROLLER_STACK_SIZE 4096 169 | #define CONFIG_FMB_EVENT_QUEUE_TIMEOUT 20 170 | #define CONFIG_FMB_TIMER_PORT_ENABLED 1 171 | #define CONFIG_FMB_TIMER_GROUP 0 172 | #define CONFIG_FMB_TIMER_INDEX 0 173 | #define CONFIG_FREERTOS_NO_AFFINITY 0x7FFFFFFF 174 | #define CONFIG_FREERTOS_CORETIMER_0 1 175 | #define CONFIG_FREERTOS_HZ 100 176 | #define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1 177 | #define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1 178 | #define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1 179 | #define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 180 | #define CONFIG_FREERTOS_ASSERT_FAIL_ABORT 1 181 | #define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1536 182 | #define CONFIG_FREERTOS_ISR_STACKSIZE 1536 183 | #define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16 184 | #define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1 185 | #define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048 186 | #define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10 187 | #define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 188 | #define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1 189 | #define CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER 1 190 | #define CONFIG_FREERTOS_DEBUG_OCDAWARE 1 191 | #define CONFIG_HEAP_POISONING_DISABLED 1 192 | #define CONFIG_HEAP_TRACING_OFF 1 193 | #define CONFIG_LOG_DEFAULT_LEVEL_INFO 1 194 | #define CONFIG_LOG_DEFAULT_LEVEL 3 195 | #define CONFIG_LOG_COLORS 1 196 | #define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1 197 | #define CONFIG_LWIP_LOCAL_HOSTNAME "espressif" 198 | #define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES 1 199 | #define CONFIG_LWIP_TIMERS_ONDEMAND 1 200 | #define CONFIG_LWIP_MAX_SOCKETS 10 201 | #define CONFIG_LWIP_SO_REUSE 1 202 | #define CONFIG_LWIP_SO_REUSE_RXTOALL 1 203 | #define CONFIG_LWIP_IP_FRAG 1 204 | #define CONFIG_LWIP_ESP_GRATUITOUS_ARP 1 205 | #define CONFIG_LWIP_GARP_TMR_INTERVAL 60 206 | #define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32 207 | #define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1 208 | #define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 209 | #define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8 210 | #define CONFIG_LWIP_NETIF_LOOPBACK 1 211 | #define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 212 | #define CONFIG_LWIP_MAX_ACTIVE_TCP 16 213 | #define CONFIG_LWIP_MAX_LISTENING_TCP 16 214 | #define CONFIG_LWIP_TCP_MAXRTX 12 215 | #define CONFIG_LWIP_TCP_SYNMAXRTX 6 216 | #define CONFIG_LWIP_TCP_MSS 1440 217 | #define CONFIG_LWIP_TCP_TMR_INTERVAL 250 218 | #define CONFIG_LWIP_TCP_MSL 60000 219 | #define CONFIG_LWIP_TCP_SND_BUF_DEFAULT 5744 220 | #define CONFIG_LWIP_TCP_WND_DEFAULT 5744 221 | #define CONFIG_LWIP_TCP_RECVMBOX_SIZE 6 222 | #define CONFIG_LWIP_TCP_QUEUE_OOSEQ 1 223 | #define CONFIG_LWIP_TCP_OVERSIZE_MSS 1 224 | #define CONFIG_LWIP_MAX_UDP_PCBS 16 225 | #define CONFIG_LWIP_UDP_RECVMBOX_SIZE 6 226 | #define CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 3072 227 | #define CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY 1 228 | #define CONFIG_LWIP_TCPIP_TASK_AFFINITY 0x7FFFFFFF 229 | #define CONFIG_LWIP_MAX_RAW_PCBS 16 230 | #define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1 231 | #define CONFIG_LWIP_SNTP_UPDATE_DELAY 3600000 232 | #define CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC 1 233 | #define CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN 1 234 | #define CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN 16384 235 | #define CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN 4096 236 | #define CONFIG_MBEDTLS_HARDWARE_AES 1 237 | #define CONFIG_MBEDTLS_HARDWARE_MPI 1 238 | #define CONFIG_MBEDTLS_HARDWARE_SHA 1 239 | #define CONFIG_MBEDTLS_HAVE_TIME 1 240 | #define CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT 1 241 | #define CONFIG_MBEDTLS_TLS_SERVER 1 242 | #define CONFIG_MBEDTLS_TLS_CLIENT 1 243 | #define CONFIG_MBEDTLS_TLS_ENABLED 1 244 | #define CONFIG_MBEDTLS_PSK_MODES 1 245 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_PSK 1 246 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK 1 247 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK 1 248 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK 1 249 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_RSA 1 250 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA 1 251 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE 1 252 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA 1 253 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1 254 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA 1 255 | #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA 1 256 | #define CONFIG_MBEDTLS_SSL_RENEGOTIATION 1 257 | #define CONFIG_MBEDTLS_SSL_PROTO_TLS1 1 258 | #define CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 1 259 | #define CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 1 260 | #define CONFIG_MBEDTLS_SSL_PROTO_DTLS 1 261 | #define CONFIG_MBEDTLS_SSL_ALPN 1 262 | #define CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS 1 263 | #define CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS 1 264 | #define CONFIG_MBEDTLS_AES_C 1 265 | #define CONFIG_MBEDTLS_RC4_DISABLED 1 266 | #define CONFIG_MBEDTLS_CCM_C 1 267 | #define CONFIG_MBEDTLS_GCM_C 1 268 | #define CONFIG_MBEDTLS_PEM_PARSE_C 1 269 | #define CONFIG_MBEDTLS_PEM_WRITE_C 1 270 | #define CONFIG_MBEDTLS_X509_CRL_PARSE_C 1 271 | #define CONFIG_MBEDTLS_X509_CSR_PARSE_C 1 272 | #define CONFIG_MBEDTLS_ECP_C 1 273 | #define CONFIG_MBEDTLS_ECDH_C 1 274 | #define CONFIG_MBEDTLS_ECDSA_C 1 275 | #define CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED 1 276 | #define CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED 1 277 | #define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1 278 | #define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1 279 | #define CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED 1 280 | #define CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED 1 281 | #define CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED 1 282 | #define CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED 1 283 | #define CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED 1 284 | #define CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED 1 285 | #define CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED 1 286 | #define CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED 1 287 | #define CONFIG_MBEDTLS_ECP_NIST_OPTIM 1 288 | #define CONFIG_MDNS_MAX_SERVICES 10 289 | #define CONFIG_MDNS_TASK_PRIORITY 1 290 | #define CONFIG_MDNS_TASK_AFFINITY_CPU0 1 291 | #define CONFIG_MDNS_TASK_AFFINITY 0x0 292 | #define CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS 2000 293 | #define CONFIG_MDNS_TIMER_PERIOD_MS 100 294 | #define CONFIG_MQTT_PROTOCOL_311 1 295 | #define CONFIG_MQTT_TRANSPORT_SSL 1 296 | #define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 297 | #define CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE 1 298 | #define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1 299 | #define CONFIG_NEWLIB_STDIN_LINE_ENDING_CR 1 300 | #define CONFIG_OPENSSL_ASSERT_EXIT 1 301 | #define CONFIG_PTHREAD_TASK_PRIO_DEFAULT 5 302 | #define CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT 3072 303 | #define CONFIG_PTHREAD_STACK_MIN 768 304 | #define CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY 1 305 | #define CONFIG_PTHREAD_TASK_CORE_DEFAULT -1 306 | #define CONFIG_PTHREAD_TASK_NAME_DEFAULT "pthread" 307 | #define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 308 | #define CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS 1 309 | #define CONFIG_SPI_FLASH_YIELD_DURING_ERASE 1 310 | #define CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS 20 311 | #define CONFIG_SPI_FLASH_ERASE_YIELD_TICKS 1 312 | #define CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP 1 313 | #define CONFIG_SPI_FLASH_SUPPORT_GD_CHIP 1 314 | #define CONFIG_SPIFFS_MAX_PARTITIONS 3 315 | #define CONFIG_SPIFFS_CACHE 1 316 | #define CONFIG_SPIFFS_CACHE_WR 1 317 | #define CONFIG_SPIFFS_PAGE_CHECK 1 318 | #define CONFIG_SPIFFS_GC_MAX_RUNS 10 319 | #define CONFIG_SPIFFS_PAGE_SIZE 256 320 | #define CONFIG_SPIFFS_OBJ_NAME_LEN 32 321 | #define CONFIG_SPIFFS_USE_MAGIC 1 322 | #define CONFIG_SPIFFS_USE_MAGIC_LENGTH 1 323 | #define CONFIG_SPIFFS_META_LENGTH 4 324 | #define CONFIG_SPIFFS_USE_MTIME 1 325 | #define CONFIG_UNITY_ENABLE_FLOAT 1 326 | #define CONFIG_UNITY_ENABLE_DOUBLE 1 327 | #define CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER 1 328 | #define CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT 1 329 | #define CONFIG_VFS_SUPPORT_TERMIOS 1 330 | #define CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS 1 331 | #define CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN 128 332 | #define CONFIG_WL_SECTOR_SIZE_4096 1 333 | #define CONFIG_WL_SECTOR_SIZE 4096 334 | #define CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES 16 335 | #define CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT 30 336 | #define CONFIG_WPA_MBEDTLS_CRYPTO 1 337 | 338 | /* List of deprecated options */ 339 | #define CONFIG_ADC2_DISABLE_DAC CONFIG_ADC_DISABLE_DAC 340 | #define CONFIG_BROWNOUT_DET CONFIG_ESP32_BROWNOUT_DET 341 | #define CONFIG_BROWNOUT_DET_LVL_SEL_0 CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0 342 | #define CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT 343 | #define CONFIG_CONSOLE_UART_BAUDRATE CONFIG_ESP_CONSOLE_UART_BAUDRATE 344 | #define CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT 345 | #define CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE 346 | #define CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY 347 | #define CONFIG_ESP32_PTHREAD_STACK_MIN CONFIG_PTHREAD_STACK_MIN 348 | #define CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT CONFIG_PTHREAD_TASK_NAME_DEFAULT 349 | #define CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT CONFIG_PTHREAD_TASK_PRIO_DEFAULT 350 | #define CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT 351 | #define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC CONFIG_ESP32_RTC_CLK_SRC_INT_RC 352 | #define CONFIG_ESP_GRATUITOUS_ARP CONFIG_LWIP_ESP_GRATUITOUS_ARP 353 | #define CONFIG_FLASHMODE_DIO CONFIG_ESPTOOLPY_FLASHMODE_DIO 354 | #define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR 355 | #define CONFIG_GARP_TMR_INTERVAL CONFIG_LWIP_GARP_TMR_INTERVAL 356 | #define CONFIG_INT_WDT CONFIG_ESP_INT_WDT 357 | #define CONFIG_INT_WDT_CHECK_CPU1 CONFIG_ESP_INT_WDT_CHECK_CPU1 358 | #define CONFIG_INT_WDT_TIMEOUT_MS CONFIG_ESP_INT_WDT_TIMEOUT_MS 359 | #define CONFIG_IPC_TASK_STACK_SIZE CONFIG_ESP_IPC_TASK_STACK_SIZE 360 | #define CONFIG_LOG_BOOTLOADER_LEVEL_INFO CONFIG_BOOTLOADER_LOG_LEVEL_INFO 361 | #define CONFIG_MAIN_TASK_STACK_SIZE CONFIG_ESP_MAIN_TASK_STACK_SIZE 362 | #define CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE 363 | #define CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT 364 | #define CONFIG_MB_CONTROLLER_STACK_SIZE CONFIG_FMB_CONTROLLER_STACK_SIZE 365 | #define CONFIG_MB_EVENT_QUEUE_TIMEOUT CONFIG_FMB_EVENT_QUEUE_TIMEOUT 366 | #define CONFIG_MB_MASTER_DELAY_MS_CONVERT CONFIG_FMB_MASTER_DELAY_MS_CONVERT 367 | #define CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND 368 | #define CONFIG_MB_QUEUE_LENGTH CONFIG_FMB_QUEUE_LENGTH 369 | #define CONFIG_MB_SERIAL_BUF_SIZE CONFIG_FMB_SERIAL_BUF_SIZE 370 | #define CONFIG_MB_SERIAL_TASK_PRIO CONFIG_FMB_SERIAL_TASK_PRIO 371 | #define CONFIG_MB_SERIAL_TASK_STACK_SIZE CONFIG_FMB_SERIAL_TASK_STACK_SIZE 372 | #define CONFIG_MB_TIMER_GROUP CONFIG_FMB_TIMER_GROUP 373 | #define CONFIG_MB_TIMER_INDEX CONFIG_FMB_TIMER_INDEX 374 | #define CONFIG_MB_TIMER_PORT_ENABLED CONFIG_FMB_TIMER_PORT_ENABLED 375 | #define CONFIG_MONITOR_BAUD_115200B CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B 376 | #define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 377 | #define CONFIG_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT 378 | #define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR 379 | #define CONFIG_POST_EVENTS_FROM_ISR CONFIG_ESP_EVENT_POST_FROM_ISR 380 | #define CONFIG_REDUCE_PHY_TX_POWER CONFIG_ESP32_REDUCE_PHY_TX_POWER 381 | #define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS 382 | #define CONFIG_STACK_CHECK_NONE CONFIG_COMPILER_STACK_CHECK_MODE_NONE 383 | #define CONFIG_SUPPORT_TERMIOS CONFIG_VFS_SUPPORT_TERMIOS 384 | #define CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT 385 | #define CONFIG_SYSTEM_EVENT_QUEUE_SIZE CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 386 | #define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE 387 | #define CONFIG_TASK_WDT CONFIG_ESP_TASK_WDT 388 | #define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 389 | #define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 390 | #define CONFIG_TASK_WDT_TIMEOUT_S CONFIG_ESP_TASK_WDT_TIMEOUT_S 391 | #define CONFIG_TCPIP_RECVMBOX_SIZE CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 392 | #define CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY 393 | #define CONFIG_TCPIP_TASK_STACK_SIZE CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 394 | #define CONFIG_TCP_MAXRTX CONFIG_LWIP_TCP_MAXRTX 395 | #define CONFIG_TCP_MSL CONFIG_LWIP_TCP_MSL 396 | #define CONFIG_TCP_MSS CONFIG_LWIP_TCP_MSS 397 | #define CONFIG_TCP_OVERSIZE_MSS CONFIG_LWIP_TCP_OVERSIZE_MSS 398 | #define CONFIG_TCP_QUEUE_OOSEQ CONFIG_LWIP_TCP_QUEUE_OOSEQ 399 | #define CONFIG_TCP_RECVMBOX_SIZE CONFIG_LWIP_TCP_RECVMBOX_SIZE 400 | #define CONFIG_TCP_SND_BUF_DEFAULT CONFIG_LWIP_TCP_SND_BUF_DEFAULT 401 | #define CONFIG_TCP_SYNMAXRTX CONFIG_LWIP_TCP_SYNMAXRTX 402 | #define CONFIG_TCP_WND_DEFAULT CONFIG_LWIP_TCP_WND_DEFAULT 403 | #define CONFIG_TIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 404 | #define CONFIG_TIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY 405 | #define CONFIG_TIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 406 | #define CONFIG_TIMER_TASK_STACK_SIZE CONFIG_ESP_TIMER_TASK_STACK_SIZE 407 | #define CONFIG_TOOLPREFIX CONFIG_SDK_TOOLPREFIX 408 | #define CONFIG_UDP_RECVMBOX_SIZE CONFIG_LWIP_UDP_RECVMBOX_SIZE 409 | -------------------------------------------------------------------------------- /generate/wifi_wrapper.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "esp_private/wifi.h" 4 | #include "esp_wifi.h" 5 | -------------------------------------------------------------------------------- /partitions.csv: -------------------------------------------------------------------------------- 1 | # Partition table 2 | # Name, Type, SubType, Offset, Size, Flags 3 | factory, app, factory, 0x10000, 0x3f0000, 4 | -------------------------------------------------------------------------------- /src/binary/coexist.rs: -------------------------------------------------------------------------------- 1 | /* automatically generated by rust-bindgen 0.54.1 */ 2 | 3 | #![allow(non_camel_case_types)] 4 | #![allow(intra_doc_link_resolution_failure)] 5 | 6 | pub type __int32_t = cty::c_int; 7 | pub type __uint32_t = cty::c_uint; 8 | pub type __int64_t = cty::c_long; 9 | pub type esp_err_t = i32; 10 | #[repr(C)] 11 | #[derive(Debug, Copy, Clone)] 12 | pub struct coex_adapter_funcs_t { 13 | pub _version: i32, 14 | pub _spin_lock_create: ::core::option::Option *mut cty::c_void>, 15 | pub _spin_lock_delete: ::core::option::Option, 16 | pub _int_disable: ::core::option::Option u32>, 17 | pub _int_enable: ::core::option::Option, 18 | pub _task_yield_from_isr: ::core::option::Option, 19 | pub _semphr_create: 20 | ::core::option::Option *mut cty::c_void>, 21 | pub _semphr_delete: ::core::option::Option, 22 | pub _semphr_take_from_isr: ::core::option::Option< 23 | unsafe extern "C" fn(semphr: *mut cty::c_void, hptw: *mut cty::c_void) -> i32, 24 | >, 25 | pub _semphr_give_from_isr: ::core::option::Option< 26 | unsafe extern "C" fn(semphr: *mut cty::c_void, hptw: *mut cty::c_void) -> i32, 27 | >, 28 | pub _semphr_take: ::core::option::Option< 29 | unsafe extern "C" fn(semphr: *mut cty::c_void, block_time_tick: u32) -> i32, 30 | >, 31 | pub _semphr_give: ::core::option::Option i32>, 32 | pub _is_in_isr: ::core::option::Option i32>, 33 | pub _malloc_internal: 34 | ::core::option::Option *mut cty::c_void>, 35 | pub _free: ::core::option::Option, 36 | pub _timer_disarm: ::core::option::Option, 37 | pub _timer_done: ::core::option::Option, 38 | pub _timer_setfn: ::core::option::Option< 39 | unsafe extern "C" fn( 40 | ptimer: *mut cty::c_void, 41 | pfunction: *mut cty::c_void, 42 | parg: *mut cty::c_void, 43 | ), 44 | >, 45 | pub _timer_arm_us: ::core::option::Option< 46 | unsafe extern "C" fn(ptimer: *mut cty::c_void, us: u32, repeat: bool), 47 | >, 48 | pub _esp_timer_get_time: ::core::option::Option i64>, 49 | pub _magic: i32, 50 | } 51 | #[repr(u32)] 52 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 53 | pub enum coex_prefer_t { 54 | COEX_PREFER_WIFI = 0, 55 | COEX_PREFER_BT = 1, 56 | COEX_PREFER_BALANCE = 2, 57 | COEX_PREFER_NUM = 3, 58 | } 59 | pub type coex_func_cb_t = 60 | ::core::option::Option; 61 | extern "C" { 62 | #[doc = " @brief Pre-Init software coexist"] 63 | #[doc = " extern function for internal use."] 64 | #[doc = ""] 65 | #[doc = " @return Init ok or failed."] 66 | pub fn coex_pre_init() -> esp_err_t; 67 | } 68 | extern "C" { 69 | #[doc = " @brief Init software coexist"] 70 | #[doc = " extern function for internal use."] 71 | #[doc = ""] 72 | #[doc = " @return Init ok or failed."] 73 | pub fn coex_init() -> esp_err_t; 74 | } 75 | extern "C" { 76 | #[doc = " @brief De-init software coexist"] 77 | #[doc = " extern function for internal use."] 78 | pub fn coex_deinit(); 79 | } 80 | extern "C" { 81 | #[doc = " @brief Pause software coexist"] 82 | #[doc = " extern function for internal use."] 83 | pub fn coex_pause(); 84 | } 85 | extern "C" { 86 | #[doc = " @brief Resume software coexist"] 87 | #[doc = " extern function for internal use."] 88 | pub fn coex_resume(); 89 | } 90 | extern "C" { 91 | #[doc = " @brief Get software coexist version string"] 92 | #[doc = " extern function for internal use."] 93 | #[doc = " @return : version string"] 94 | pub fn coex_version_get() -> *const cty::c_char; 95 | } 96 | extern "C" { 97 | #[doc = " @brief Coexist performance preference set from libbt.a"] 98 | #[doc = " extern function for internal use."] 99 | #[doc = ""] 100 | #[doc = " @param prefer : the prefer enumeration value"] 101 | #[doc = " @return : ESP_OK - success, other - failed"] 102 | pub fn coex_preference_set(prefer: coex_prefer_t) -> esp_err_t; 103 | } 104 | extern "C" { 105 | #[doc = " @brief Get software coexist status."] 106 | #[doc = " @return : software coexist status"] 107 | pub fn coex_status_get() -> u32; 108 | } 109 | extern "C" { 110 | #[doc = " @brief Set software coexist condition."] 111 | #[doc = " @return : software coexist condition"] 112 | pub fn coex_condition_set(type_: u32, dissatisfy: bool); 113 | } 114 | extern "C" { 115 | #[doc = " @brief WiFi requests coexistence."] 116 | #[doc = ""] 117 | #[doc = " @param event : WiFi event"] 118 | #[doc = " @param latency : WiFi will request coexistence after latency"] 119 | #[doc = " @param duration : duration for WiFi to request coexistence"] 120 | #[doc = " @return : 0 - success, other - failed"] 121 | pub fn coex_wifi_request(event: u32, latency: u32, duration: u32) -> cty::c_int; 122 | } 123 | extern "C" { 124 | #[doc = " @brief WiFi release coexistence."] 125 | #[doc = ""] 126 | #[doc = " @param event : WiFi event"] 127 | #[doc = " @return : 0 - success, other - failed"] 128 | pub fn coex_wifi_release(event: u32) -> cty::c_int; 129 | } 130 | extern "C" { 131 | #[doc = " @brief Blue tooth requests coexistence."] 132 | #[doc = ""] 133 | #[doc = " @param event : blue tooth event"] 134 | #[doc = " @param latency : blue tooth will request coexistence after latency"] 135 | #[doc = " @param duration : duration for blue tooth to request coexistence"] 136 | #[doc = " @return : 0 - success, other - failed"] 137 | pub fn coex_bt_request(event: u32, latency: u32, duration: u32) -> cty::c_int; 138 | } 139 | extern "C" { 140 | #[doc = " @brief Blue tooth release coexistence."] 141 | #[doc = ""] 142 | #[doc = " @param event : blue tooth event"] 143 | #[doc = " @return : 0 - success, other - failed"] 144 | pub fn coex_bt_release(event: u32) -> cty::c_int; 145 | } 146 | extern "C" { 147 | #[doc = " @brief Register callback function for blue tooth."] 148 | #[doc = ""] 149 | #[doc = " @param cb : callback function"] 150 | #[doc = " @return : 0 - success, other - failed"] 151 | pub fn coex_register_bt_cb(cb: coex_func_cb_t) -> cty::c_int; 152 | } 153 | extern "C" { 154 | #[doc = " @brief Lock before reset base band."] 155 | #[doc = ""] 156 | #[doc = " @return : lock value"] 157 | pub fn coex_bb_reset_lock() -> u32; 158 | } 159 | extern "C" { 160 | #[doc = " @brief Unlock after reset base band."] 161 | #[doc = ""] 162 | #[doc = " @param restore : lock value"] 163 | pub fn coex_bb_reset_unlock(restore: u32); 164 | } 165 | extern "C" { 166 | #[doc = " @brief Register coexistence adapter functions."] 167 | #[doc = ""] 168 | #[doc = " @param funcs : coexistence adapter functions"] 169 | #[doc = " @return : ESP_OK - success, other - failed"] 170 | pub fn esp_coex_adapter_register(funcs: *mut coex_adapter_funcs_t) -> esp_err_t; 171 | } 172 | extern "C" { 173 | #[doc = " @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library"] 174 | #[doc = ""] 175 | #[doc = " @attention 1. It is used for internal CI version check"] 176 | #[doc = ""] 177 | #[doc = " @return"] 178 | #[doc = " - ESP_OK : succeed"] 179 | #[doc = " - ESP_WIFI_INVALID_ARG : MD5 check fail"] 180 | pub fn esp_coex_adapter_funcs_md5_check(md5: *const cty::c_char) -> esp_err_t; 181 | } 182 | -------------------------------------------------------------------------------- /src/binary/ctypes.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | 3 | pub type c_schar = i8; 4 | pub type c_char = i8; 5 | pub type c_uchar = u8; 6 | pub type c_ushort = u16; 7 | pub type c_int = i32; 8 | pub type c_uint = u32; 9 | pub type c_long = i64; 10 | pub type c_ulong = u64; 11 | pub type c_void = core::ffi::c_void; 12 | -------------------------------------------------------------------------------- /src/binary/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod coexist; 2 | pub mod phy; 3 | pub mod wifi; 4 | -------------------------------------------------------------------------------- /src/binary/phy.rs: -------------------------------------------------------------------------------- 1 | /* automatically generated by rust-bindgen 0.54.1 */ 2 | 3 | #![allow(non_camel_case_types)] 4 | #![allow(intra_doc_link_resolution_failure)] 5 | 6 | pub type __uint8_t = cty::c_uchar; 7 | pub type __uint32_t = cty::c_uint; 8 | #[doc = " @brief Structure holding PHY init parameters"] 9 | #[repr(C)] 10 | #[derive(Copy, Clone)] 11 | pub struct esp_phy_init_data_t { 12 | #[doc = "< opaque PHY initialization parameters"] 13 | pub params: [u8; 128usize], 14 | } 15 | #[doc = " @brief Opaque PHY calibration data"] 16 | #[repr(C)] 17 | #[derive(Copy, Clone)] 18 | pub struct esp_phy_calibration_data_t { 19 | #[doc = "< PHY version"] 20 | pub version: [u8; 4usize], 21 | #[doc = "< The MAC address of the station"] 22 | pub mac: [u8; 6usize], 23 | #[doc = "< calibration data"] 24 | pub opaque: [u8; 1894usize], 25 | } 26 | #[repr(u32)] 27 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 28 | pub enum esp_phy_calibration_mode_t { 29 | #[doc = "< Do part of RF calibration. This should be used after power-on reset."] 30 | PHY_RF_CAL_PARTIAL = 0, 31 | #[doc = "< Don't do any RF calibration. This mode is only suggested to be used after deep sleep reset."] 32 | PHY_RF_CAL_NONE = 1, 33 | #[doc = "< Do full RF calibration. Produces best results, but also consumes a lot of time and current. Suggested to be used once."] 34 | PHY_RF_CAL_FULL = 2, 35 | } 36 | extern "C" { 37 | #[doc = " @brief Return ROM function pointer table from PHY library."] 38 | pub fn phy_get_romfunc_addr(); 39 | } 40 | extern "C" { 41 | #[doc = " @brief Initialize PHY module and do RF calibration"] 42 | #[doc = " @param[in] init_data Initialization parameters to be used by the PHY"] 43 | #[doc = " @param[inout] cal_data As input, calibration data previously obtained. As output, will contain new calibration data."] 44 | #[doc = " @param[in] cal_mode RF calibration mode"] 45 | #[doc = " @return ESP_CAL_DATA_CHECK_FAIL if calibration data checksum fails, other values are reserved for future use"] 46 | pub fn register_chipv7_phy( 47 | init_data: *const esp_phy_init_data_t, 48 | cal_data: *mut esp_phy_calibration_data_t, 49 | cal_mode: esp_phy_calibration_mode_t, 50 | ) -> cty::c_int; 51 | } 52 | extern "C" { 53 | #[doc = " @brief Get the format version of calibration data used by PHY library."] 54 | #[doc = " @return Format version number, OR'ed with BIT(16) if PHY is in WIFI only mode."] 55 | pub fn phy_get_rf_cal_version() -> u32; 56 | } 57 | extern "C" { 58 | #[doc = " @brief Set RF/BB for only WIFI mode or coexist(WIFI & BT) mode"] 59 | #[doc = " @param[in] true is for only WIFI mode, false is for coexist mode. default is 0."] 60 | #[doc = " @return NULL"] 61 | pub fn phy_set_wifi_mode_only(wifi_only: bool); 62 | } 63 | extern "C" { 64 | #[doc = " @brief Set BT the highest priority in coexist mode."] 65 | #[doc = " @return NULL"] 66 | pub fn coex_bt_high_prio(); 67 | } 68 | extern "C" { 69 | #[doc = " @brief Shutdown PHY and RF."] 70 | pub fn phy_close_rf(); 71 | } 72 | -------------------------------------------------------------------------------- /src/compatibility/crypto.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | pub(crate) static mut WPA_CRYPTO_FUNCS: crate::binary::wifi::wpa_crypto_funcs_t = 4 | crate::binary::wifi::wpa_crypto_funcs_t { 5 | size: core::mem::size_of::() as u32, 6 | version: 0x00000001, 7 | aes_wrap: Some(aes_wrap), 8 | aes_unwrap: Some(aes_unwrap), 9 | hmac_sha256_vector: Some(hmac_sha256_vector), 10 | sha256_prf: Some(sha256_prf), 11 | hmac_md5: Some(hmac_md5), 12 | hamc_md5_vector: Some(hmac_md5_vector), 13 | hmac_sha1: Some(hmac_sha1), 14 | hmac_sha1_vector: Some(hmac_sha1_vector), 15 | sha1_prf: Some(sha1_prf), 16 | sha1_vector: Some(sha1_vector), 17 | pbkdf2_sha1: Some(pbkdf2_sha1), 18 | rc4_skip: Some(rc4_skip), 19 | 20 | md5_vector: Some(md5_vector), 21 | aes_encrypt: Some(aes_encrypt), 22 | aes_encrypt_init: Some(aes_encrypt_init), 23 | aes_encrypt_deinit: Some(aes_encrypt_deinit), 24 | aes_decrypt: Some(aes_decrypt), 25 | aes_decrypt_init: Some(aes_decrypt_init), 26 | aes_decrypt_deinit: Some(aes_decrypt_deinit), 27 | 28 | omac1_aes_128: Some(omac1_aes_128), 29 | ccmp_decrypt: Some(ccmp_decrypt), 30 | ccmp_encrypt: Some(ccmp_encrypt), 31 | }; 32 | 33 | pub unsafe extern "C" fn aes_wrap( 34 | kek: *const cty::c_uchar, 35 | n: cty::c_int, 36 | plain: *const cty::c_uchar, 37 | cipher: *mut cty::c_uchar, 38 | ) -> cty::c_int { 39 | unimplemented!(); 40 | } 41 | 42 | pub unsafe extern "C" fn aes_unwrap( 43 | kek: *const cty::c_uchar, 44 | n: cty::c_int, 45 | cipher: *const cty::c_uchar, 46 | plain: *mut cty::c_uchar, 47 | ) -> cty::c_int { 48 | unimplemented!(); 49 | } 50 | 51 | pub unsafe extern "C" fn hmac_sha256_vector( 52 | key: *const cty::c_uchar, 53 | key_len: cty::c_int, 54 | num_elem: cty::c_int, 55 | addr: *mut *const cty::c_uchar, 56 | len: *const cty::c_int, 57 | mac: *mut cty::c_uchar, 58 | ) -> cty::c_int { 59 | unimplemented!(); 60 | } 61 | 62 | pub unsafe extern "C" fn sha256_prf( 63 | key: *const cty::c_uchar, 64 | key_len: cty::c_int, 65 | label: *const cty::c_char, 66 | data: *const cty::c_uchar, 67 | data_len: cty::c_int, 68 | buf: *mut cty::c_uchar, 69 | buf_len: cty::c_int, 70 | ) -> cty::c_int { 71 | unimplemented!(); 72 | } 73 | 74 | pub unsafe extern "C" fn hmac_md5( 75 | key: *const cty::c_uchar, 76 | key_len: cty::c_uint, 77 | data: *const cty::c_uchar, 78 | data_len: cty::c_uint, 79 | mac: *mut cty::c_uchar, 80 | ) -> cty::c_int { 81 | unimplemented!(); 82 | } 83 | 84 | pub unsafe extern "C" fn hmac_md5_vector( 85 | key: *const cty::c_uchar, 86 | key_len: cty::c_uint, 87 | num_elem: cty::c_uint, 88 | addr: *mut *const cty::c_uchar, 89 | len: *const cty::c_uint, 90 | mac: *mut cty::c_uchar, 91 | ) -> cty::c_int { 92 | unimplemented!(); 93 | } 94 | 95 | pub unsafe extern "C" fn hmac_sha1( 96 | key: *const cty::c_uchar, 97 | key_len: cty::c_uint, 98 | data: *const cty::c_uchar, 99 | data_len: cty::c_uint, 100 | mac: *mut cty::c_uchar, 101 | ) -> cty::c_int { 102 | unimplemented!(); 103 | } 104 | 105 | pub unsafe extern "C" fn hmac_sha1_vector( 106 | key: *const cty::c_uchar, 107 | key_len: cty::c_uint, 108 | num_elem: cty::c_uint, 109 | addr: *mut *const cty::c_uchar, 110 | len: *const cty::c_uint, 111 | mac: *mut cty::c_uchar, 112 | ) -> cty::c_int { 113 | unimplemented!(); 114 | } 115 | 116 | pub unsafe extern "C" fn sha1_prf( 117 | key: *const cty::c_uchar, 118 | key_len: cty::c_uint, 119 | label: *const cty::c_char, 120 | data: *const cty::c_uchar, 121 | data_len: cty::c_uint, 122 | buf: *mut cty::c_uchar, 123 | buf_len: cty::c_uint, 124 | ) -> cty::c_int { 125 | unimplemented!(); 126 | } 127 | 128 | pub unsafe extern "C" fn sha1_vector( 129 | num_elem: cty::c_uint, 130 | addr: *mut *const cty::c_uchar, 131 | len: *const cty::c_uint, 132 | mac: *mut cty::c_uchar, 133 | ) -> cty::c_int { 134 | unimplemented!(); 135 | } 136 | 137 | pub unsafe extern "C" fn pbkdf2_sha1( 138 | passphrase: *const cty::c_char, 139 | ssid: *const cty::c_char, 140 | ssid_len: cty::c_uint, 141 | iterations: cty::c_int, 142 | buf: *mut cty::c_uchar, 143 | buflen: cty::c_uint, 144 | ) -> cty::c_int { 145 | unimplemented!(); 146 | } 147 | 148 | pub unsafe extern "C" fn rc4_skip( 149 | key: *const cty::c_uchar, 150 | keylen: cty::c_uint, 151 | skip: cty::c_uint, 152 | data: *mut cty::c_uchar, 153 | data_len: cty::c_uint, 154 | ) -> cty::c_int { 155 | unimplemented!(); 156 | } 157 | 158 | pub unsafe extern "C" fn md5_vector( 159 | num_elem: cty::c_uint, 160 | addr: *mut *const cty::c_uchar, 161 | len: *const cty::c_uint, 162 | mac: *mut cty::c_uchar, 163 | ) -> cty::c_int { 164 | unimplemented!(); 165 | } 166 | 167 | pub unsafe extern "C" fn aes_encrypt( 168 | ctx: *mut cty::c_void, 169 | plain: *const cty::c_uchar, 170 | crypt: *mut cty::c_uchar, 171 | ) { 172 | unimplemented!(); 173 | } 174 | 175 | pub unsafe extern "C" fn aes_encrypt_init( 176 | key: *const cty::c_uchar, 177 | len: cty::c_uint, 178 | ) -> *mut cty::c_void { 179 | unimplemented!(); 180 | } 181 | 182 | pub unsafe extern "C" fn aes_encrypt_deinit(ctx: *mut cty::c_void) { 183 | unimplemented!(); 184 | } 185 | 186 | pub unsafe extern "C" fn aes_decrypt( 187 | ctx: *mut cty::c_void, 188 | crypt: *const cty::c_uchar, 189 | plain: *mut cty::c_uchar, 190 | ) { 191 | unimplemented!(); 192 | } 193 | 194 | pub unsafe extern "C" fn aes_decrypt_init( 195 | key: *const cty::c_uchar, 196 | len: cty::c_uint, 197 | ) -> *mut cty::c_void { 198 | unimplemented!(); 199 | } 200 | 201 | pub unsafe extern "C" fn aes_decrypt_deinit(ctx: *mut cty::c_void) { 202 | unimplemented!(); 203 | } 204 | 205 | pub unsafe extern "C" fn omac1_aes_128( 206 | key: *const u8, 207 | data: *const u8, 208 | data_len: usize, 209 | mic: *mut u8, 210 | ) -> cty::c_int { 211 | unimplemented!(); 212 | } 213 | 214 | pub unsafe extern "C" fn ccmp_decrypt( 215 | tk: *const u8, 216 | ieee80211_hdr: *const u8, 217 | data: *const u8, 218 | data_len: usize, 219 | decrypted_len: *mut usize, 220 | ) -> *mut u8 { 221 | unimplemented!(); 222 | } 223 | 224 | pub unsafe extern "C" fn ccmp_encrypt( 225 | tk: *const u8, 226 | frame: *mut u8, 227 | len: usize, 228 | hdrlen: usize, 229 | pn: *mut u8, 230 | keyid: cty::c_int, 231 | encrypted_len: *mut usize, 232 | ) -> *mut u8 { 233 | unimplemented!(); 234 | } 235 | -------------------------------------------------------------------------------- /src/compatibility/implicit.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | use crate::wprintln; 4 | use cty::{c_char, c_int, c_uint, c_void}; 5 | use esp32_hal::units::*; 6 | 7 | #[repr(C)] 8 | #[derive(Debug)] 9 | pub struct StaticCString(*const u8); 10 | unsafe impl Sync for StaticCString {} 11 | 12 | // Functions from esp-idf 13 | #[no_mangle] 14 | pub static WIFI_EVENT: StaticCString = StaticCString(b"WIFI_EVENT\0" as *const u8); 15 | 16 | static mut INTERRUPT_MASK: u32 = 0; 17 | //static mut PHY_SPINLOCK: spin::Mutex<()> = spin::Mutex::new(()); 18 | //static mut PHY_SPINLOCK_GUARD: Option> = None; 19 | 20 | #[no_mangle] 21 | pub unsafe extern "C" fn phy_enter_critical() -> c_uint { 22 | wprintln!("phy_enter_critical()"); 23 | 24 | INTERRUPT_MASK = xtensa_lx6::interrupt::disable(); 25 | 26 | // unimplemented!(); 27 | // TODO: allow nesting on same core! 28 | //PHY_SPINLOCK_GUARD = Some(PHY_SPINLOCK.lock()); 29 | INTERRUPT_MASK 30 | } 31 | 32 | #[no_mangle] 33 | pub unsafe extern "C" fn phy_exit_critical(_level: c_uint) { 34 | wprintln!("phy_exit_critical({})", _level); 35 | 36 | // unimplemented!(); 37 | // TODO: allow nesting on same core! 38 | //PHY_SPINLOCK_GUARD = None; 39 | 40 | xtensa_lx6::interrupt::enable_mask(INTERRUPT_MASK); 41 | } 42 | 43 | #[no_mangle] 44 | unsafe extern "C" fn phy_printf(fmt: *const c_char, ...) -> c_int { 45 | wprintln!( 46 | "phy_printf({})", 47 | cstr_core::CStr::from_ptr(fmt).to_str().unwrap() 48 | ); 49 | 1 50 | // unimplemented!(); 51 | } 52 | 53 | #[no_mangle] 54 | unsafe extern "C" fn net80211_printf(fmt: *const c_char, ...) -> c_int { 55 | unimplemented!(); 56 | } 57 | 58 | #[no_mangle] 59 | unsafe extern "C" fn hexstr2bin(hex: *const c_char, buf: *const u8, len: usize) -> c_int { 60 | unimplemented!(); 61 | } 62 | 63 | #[no_mangle] 64 | pub unsafe extern "C" fn temprature_sens_read() -> u8 { 65 | // TODO: real temp sense read implementation 66 | 75 67 | //unimplemented!(); 68 | } 69 | 70 | #[no_mangle] 71 | pub unsafe extern "C" fn esp_dport_access_reg_read(mut reg: u32) -> u32 { 72 | wprintln!("esp_dport_access_reg_read({:x})", reg); 73 | // TODO: implement dport workaround 74 | 75 | let mut _apb: u32 = 0; 76 | let mut _int_lvl: u32 = 0; 77 | llvm_asm! (r#" 78 | rsil $2, 7 79 | movi $0, 0x3ff40078 80 | l32i $0, $0, 0 81 | l32i $1, $1, 0 82 | wsr $2, PS 83 | rsync"# 84 | : "+r"(_apb), "+r"(reg), "+r"(_int_lvl):::"volatile"); 85 | return reg; 86 | //unimplemented!(); 87 | } 88 | 89 | #[no_mangle] 90 | pub unsafe extern "C" fn rtc_get_xtal() -> u32 { 91 | wprintln!("rtc_get_xtal()"); 92 | 93 | esp32_hal::clock_control::ClockControlConfig {}.xtal_frequency() / Hertz(1_000_000) 94 | } 95 | 96 | // Functions available in ROM 97 | 98 | #[no_mangle] 99 | pub unsafe extern "C" fn roundup2(x: c_int, size: c_int) -> c_int { 100 | let res = (x + (size - 1)) & (-size); 101 | wprintln!("roundup2({}, {}) -> {}", x, size, res); 102 | res 103 | } 104 | 105 | #[no_mangle] 106 | pub unsafe extern "C" fn __popcountsi2(x: c_int) -> c_uint { 107 | let res = x.count_ones(); 108 | wprintln!("__popcountsi2({}) -> {}", x, res); 109 | res 110 | } 111 | 112 | #[no_mangle] 113 | pub unsafe extern "C" fn gpio_output_set( 114 | set_mask: c_uint, 115 | clear_mask: c_uint, 116 | enable_mask: c_uint, 117 | disable_mask: c_uint, 118 | ) { 119 | unimplemented!(); 120 | } 121 | 122 | #[no_mangle] 123 | pub unsafe extern "C" fn gpio_output_set_high( 124 | set_mask: c_uint, 125 | clear_mask: c_uint, 126 | enable_mask: c_uint, 127 | disable_mask: c_uint, 128 | ) { 129 | unimplemented!(); 130 | } 131 | 132 | #[no_mangle] 133 | pub unsafe extern "C" fn intr_matrix_set(cpu_no: c_int, model_num: c_uint, intr_num: c_uint) { 134 | wprintln!("intr_matrix_set({},{},{})", cpu_no, model_num, intr_num); 135 | // TODO: implement routine or refer to ROM 136 | //unimplemented!(); 137 | } 138 | 139 | #[no_mangle] 140 | pub unsafe extern "C" fn ets_delay_us(us: c_uint) { 141 | wprintln!("ets_delay_us({})", us); 142 | // let ticks = us.us() * esp32_hal::clock_control::ClockControlConfig {}.cpu_frequency(); 143 | // xtensa_lx6::timer::delay(ticks / Ticks(1)); 144 | } 145 | 146 | #[no_mangle] 147 | pub unsafe extern "C" fn phy_get_romfuncs() -> *const c_void { 148 | wprintln!("phy_get_romfuncs()"); 149 | 150 | // Hardcoded phy_get_romfuncs address in ROM 151 | core::mem::transmute::<_, unsafe extern "C" fn() -> *const c_void>(0x40004100)() 152 | } 153 | 154 | // Functions from libc 155 | 156 | #[no_mangle] 157 | pub unsafe extern "C" fn strnlen(cs: *const c_char, maxlen: usize) -> usize { 158 | wprintln!("strnlen({:x}, {})", cs as u32, maxlen); 159 | 160 | for i in 0..maxlen { 161 | if *cs.add(i) == 0 { 162 | return i; 163 | } 164 | } 165 | return maxlen; 166 | } 167 | 168 | #[no_mangle] 169 | pub unsafe extern "C" fn strlen(cs: *const c_char) -> usize { 170 | unimplemented!(); 171 | } 172 | 173 | #[no_mangle] 174 | pub unsafe extern "C" fn strncpy(dst: *mut c_char, src: *const c_char, n: usize) -> *mut c_char { 175 | wprintln!( 176 | "strncpy({:x}, {:x}, {}) -> {:x}", 177 | dst as u32, 178 | src as u32, 179 | n, 180 | dst as u32 181 | ); 182 | 183 | for i in 0..n { 184 | if *dst.add(i) == 0 { 185 | for j in i..n { 186 | *dst.add(j) = 0; 187 | } 188 | break; 189 | } 190 | *dst.add(i) = *src.add(i); 191 | } 192 | 193 | dst 194 | } 195 | 196 | #[no_mangle] 197 | pub unsafe extern "C" fn free(ptr: *const c_void) { 198 | unimplemented!(); 199 | } 200 | 201 | #[no_mangle] 202 | pub unsafe extern "C" fn abort() -> ! { 203 | unimplemented!(); 204 | } 205 | 206 | #[no_mangle] 207 | pub unsafe extern "C" fn strncmp(cs: *const c_char, ct: *const c_char, n: usize) -> c_int { 208 | unimplemented!(); 209 | } 210 | 211 | #[no_mangle] 212 | pub unsafe extern "C" fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int { 213 | wprintln!( 214 | "sprintf({:x}, {})", 215 | s as u32, 216 | cstr_core::CStr::from_ptr(format).to_str().unwrap() 217 | ); 218 | 219 | //unimplemented!(); 220 | let str = [0x44i8, 0x4d, 0x59, 0]; 221 | strncpy(s, str.as_ptr(), 4); 222 | 3 223 | } 224 | 225 | #[no_mangle] 226 | pub unsafe extern "C" fn puts(a: *const c_char) -> c_int { 227 | wprintln!("{}", cstr_core::CStr::from_ptr(a).to_str().unwrap()); 228 | true as c_int 229 | } 230 | -------------------------------------------------------------------------------- /src/compatibility/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod crypto; 2 | pub mod implicit; 3 | pub mod osi; 4 | -------------------------------------------------------------------------------- /src/compatibility/osi.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | use crate::binary::wifi::__va_list_tag; 4 | use crate::timer::TimerID; 5 | use crate::{fwprintln, wprintln}; 6 | use alloc::boxed::Box; 7 | use alloc::collections::BTreeMap; 8 | use alloc::raw_vec::RawVec; 9 | use cty::c_void; 10 | use esp32_hal::alloc::{Allocator, DEFAULT_ALLOCATOR, DRAM_ALLOCATOR}; 11 | use esp32_hal::prelude::*; 12 | 13 | static mut ALLOCATIONS: CriticalSectionSpinLockMutex>> = 14 | CriticalSectionSpinLockMutex::new(BTreeMap::new()); 15 | 16 | const TRUE: i32 = 1; 17 | const FALSE: i32 = 0; 18 | 19 | const PASS: i32 = TRUE; 20 | const ESP_OK: i32 = 0; 21 | 22 | struct Queue { 23 | wifi_queue: WifiStaticQueue, 24 | item_size: usize, 25 | count: usize, 26 | send_index: usize, 27 | receive_index: usize, 28 | } 29 | 30 | #[repr(C)] 31 | struct WifiStaticQueue { 32 | handle: *mut c_void, 33 | storage: *mut c_void, 34 | } 35 | 36 | #[repr(C)] 37 | struct SpinLock { 38 | owner: u32, 39 | count: u32, 40 | } 41 | const SPINLOCK_FREE: u32 = 0xB33FFFFF; 42 | 43 | impl SpinLock { 44 | fn new() -> Self { 45 | Self { 46 | owner: SPINLOCK_FREE, 47 | count: 0, 48 | } 49 | } 50 | } 51 | 52 | struct RecursiveMutex { 53 | count: CriticalSectionSpinLockMutex, 54 | } 55 | 56 | impl RecursiveMutex { 57 | const fn new() -> Self { 58 | Self { 59 | count: CriticalSectionSpinLockMutex::new(0), 60 | } 61 | } 62 | 63 | fn lock(&self) -> u32 { 64 | (&self.count).lock(|count| { 65 | *count += 1; 66 | *count 67 | }) 68 | } 69 | fn unlock(&self) -> u32 { 70 | (&self.count).lock(|count| { 71 | assert!(*count > 0); 72 | *count -= 1; 73 | *count 74 | }) 75 | } 76 | } 77 | 78 | struct Semaphore { 79 | count: CriticalSectionSpinLockMutex, 80 | max: u32, 81 | } 82 | 83 | impl Semaphore { 84 | const fn new(max: u32, initial: u32) -> Self { 85 | Self { 86 | max, 87 | count: CriticalSectionSpinLockMutex::new(initial), 88 | } 89 | } 90 | 91 | fn give(&self) -> bool { 92 | (&self.count).lock(|count| { 93 | if *count < self.max { 94 | *count += 1; 95 | true 96 | } else { 97 | false 98 | } 99 | }) 100 | } 101 | fn take(&self) -> bool { 102 | (&self.count).lock(|count| { 103 | if *count > 0 { 104 | *count -= 1; 105 | true 106 | } else { 107 | false 108 | } 109 | }) 110 | } 111 | } 112 | 113 | static mut QUEUES: CriticalSectionSpinLockMutex< 114 | BTreeMap<*mut c_void, Box>>, 115 | > = CriticalSectionSpinLockMutex::new(BTreeMap::new()); 116 | 117 | static mut SEMAPHORES: CriticalSectionSpinLockMutex>> = 118 | CriticalSectionSpinLockMutex::new(BTreeMap::new()); 119 | 120 | static mut MUTEXES: CriticalSectionSpinLockMutex>> = 121 | CriticalSectionSpinLockMutex::new(BTreeMap::new()); 122 | 123 | static mut SPINLOCKS: CriticalSectionSpinLockMutex>> = 124 | CriticalSectionSpinLockMutex::new(BTreeMap::new()); 125 | 126 | static mut TIMERS: CriticalSectionSpinLockMutex>> = 127 | CriticalSectionSpinLockMutex::new(BTreeMap::new()); 128 | 129 | fn alloc(size: usize, internal: bool, zero: bool) -> *mut c_void { 130 | let memory = RawVec::with_capacity_in( 131 | size, 132 | if internal { 133 | DRAM_ALLOCATOR 134 | } else { 135 | DEFAULT_ALLOCATOR 136 | }, 137 | ); 138 | if zero { 139 | unsafe { core::ptr::write_bytes(memory.ptr(), 0, size) }; 140 | } 141 | let address = memory.ptr() as *mut c_void; 142 | 143 | unsafe { 144 | (&ALLOCATIONS).lock(|allocations| allocations.insert(address, memory)); 145 | } 146 | 147 | wprintln!( 148 | "alloc({}, {}, {}) -> {:x}", 149 | size, 150 | internal, 151 | zero, 152 | address as u32 153 | ); 154 | address 155 | } 156 | 157 | pub(crate) static mut WIFI_OS_FUNCS: crate::binary::wifi::wifi_osi_funcs_t = 158 | crate::binary::wifi::wifi_osi_funcs_t { 159 | _version: 0x00000004, 160 | _set_isr: Some(_set_isr), 161 | _ints_on: Some(_ints_on), 162 | _ints_off: Some(_ints_off), 163 | _spin_lock_create: Some(_spin_lock_create), 164 | _spin_lock_delete: Some(_spin_lock_delete), 165 | _wifi_int_disable: Some(_wifi_int_disable), 166 | _wifi_int_restore: Some(_wifi_int_restore), 167 | _task_yield_from_isr: Some(_task_yield_from_isr), 168 | _semphr_create: Some(_semphr_create), 169 | _semphr_delete: Some(_semphr_delete), 170 | _semphr_take: Some(_semphr_take), 171 | _semphr_give: Some(_semphr_give), 172 | _wifi_thread_semphr_get: Some(_wifi_thread_semphr_get), 173 | _mutex_create: Some(_mutex_create), 174 | _recursive_mutex_create: Some(_recursive_mutex_create), 175 | _mutex_delete: Some(_mutex_delete), 176 | _mutex_lock: Some(_mutex_lock), 177 | _mutex_unlock: Some(_mutex_unlock), 178 | _queue_create: Some(_queue_create), 179 | _queue_delete: Some(_queue_delete), 180 | _queue_send: Some(_queue_send), 181 | _queue_send_from_isr: Some(_queue_send_from_isr), 182 | _queue_send_to_back: Some(_queue_send_to_back), 183 | _queue_send_to_front: Some(_queue_send_to_front), 184 | _queue_recv: Some(_queue_recv), 185 | _queue_msg_waiting: Some(_queue_msg_waiting), 186 | _event_group_create: Some(_event_group_create), 187 | _event_group_delete: Some(_event_group_delete), 188 | _event_group_set_bits: Some(_event_group_set_bits), 189 | _event_group_clear_bits: Some(_event_group_clear_bits), 190 | _event_group_wait_bits: Some(_event_group_wait_bits), 191 | _task_create_pinned_to_core: Some(_task_create_pinned_to_core), 192 | _task_create: Some(_task_create), 193 | _task_delete: Some(_task_delete), 194 | _task_delay: Some(_task_delay), 195 | _task_ms_to_tick: Some(_task_ms_to_tick), 196 | _task_get_current_task: Some(_task_get_current_task), 197 | _task_get_max_priority: Some(_task_get_max_priority), 198 | _malloc: Some(_malloc), 199 | _free: Some(_free), 200 | _event_post: Some(_event_post), 201 | _get_free_heap_size: Some(_get_free_heap_size), 202 | _rand: Some(_rand), 203 | _dport_access_stall_other_cpu_start_wrap: Some(_dport_access_stall_other_cpu_start_wrap), 204 | _dport_access_stall_other_cpu_end_wrap: Some(_dport_access_stall_other_cpu_end_wrap), 205 | _phy_rf_deinit: Some(_phy_rf_deinit), 206 | _phy_load_cal_and_init: Some(_phy_load_cal_and_init), 207 | _phy_common_clock_enable: Some(_phy_common_clock_enable), 208 | _phy_common_clock_disable: Some(_phy_common_clock_disable), 209 | _read_mac: Some(_read_mac), 210 | _timer_arm: Some(_timer_arm), 211 | _timer_disarm: Some(_timer_disarm), 212 | _timer_done: Some(_timer_done), 213 | _timer_setfn: Some(_timer_setfn), 214 | _timer_arm_us: Some(_timer_arm_us), 215 | _periph_module_enable: Some(_periph_module_enable), 216 | _periph_module_disable: Some(_periph_module_disable), 217 | _esp_timer_get_time: Some(_esp_timer_get_time), 218 | _nvs_set_i8: Some(_nvs_set_i8), 219 | _nvs_get_i8: Some(_nvs_get_i8), 220 | _nvs_set_u8: Some(_nvs_set_u8), 221 | _nvs_get_u8: Some(_nvs_get_u8), 222 | _nvs_set_u16: Some(_nvs_set_u16), 223 | _nvs_get_u16: Some(_nvs_get_u16), 224 | _nvs_open: Some(_nvs_open), 225 | _nvs_close: Some(_nvs_close), 226 | _nvs_commit: Some(_nvs_commit), 227 | _nvs_set_blob: Some(_nvs_set_blob), 228 | _nvs_get_blob: Some(_nvs_get_blob), 229 | _nvs_erase_key: Some(_nvs_erase_key), 230 | _get_random: Some(_get_random), 231 | _get_time: Some(_get_time), 232 | _random: Some(_random), 233 | _log_write: Some(_log_write), 234 | _log_writev: Some(_log_writev), 235 | _log_timestamp: Some(_log_timestamp), 236 | _malloc_internal: Some(_malloc_internal), 237 | _realloc_internal: Some(_realloc_internal), 238 | _calloc_internal: Some(_calloc_internal), 239 | _zalloc_internal: Some(_zalloc_internal), 240 | _wifi_malloc: Some(_wifi_malloc), 241 | _wifi_realloc: Some(_wifi_realloc), 242 | _wifi_calloc: Some(_wifi_calloc), 243 | _wifi_zalloc: Some(_wifi_zalloc), 244 | _wifi_create_queue: Some(_wifi_create_queue), 245 | _wifi_delete_queue: Some(_wifi_delete_queue), 246 | _modem_sleep_enter: Some(_modem_sleep_enter), 247 | _modem_sleep_exit: Some(_modem_sleep_exit), 248 | _modem_sleep_register: Some(_modem_sleep_register), 249 | _modem_sleep_deregister: Some(_modem_sleep_deregister), 250 | _coex_status_get: Some(_coex_status_get), 251 | _coex_condition_set: Some(_coex_condition_set), 252 | _coex_wifi_request: Some(_coex_wifi_request), 253 | _coex_wifi_release: Some(_coex_wifi_release), 254 | _magic: 0xDEADBEAFu32 as i32, 255 | }; 256 | 257 | pub unsafe extern "C" fn _set_isr(n: i32, f: *mut c_void, arg: *mut c_void) { 258 | wprintln!("_set_isr({}, {:x}, {:x})", n, f as u32, arg as u32); 259 | // unimplemented!() 260 | } 261 | pub unsafe extern "C" fn _ints_on(mask: u32) { 262 | wprintln!("_ints_on({})", mask); 263 | // unimplemented!() 264 | } 265 | pub unsafe extern "C" fn _ints_off(mask: u32) { 266 | unimplemented!() 267 | } 268 | pub unsafe extern "C" fn _spin_lock_create() -> *mut c_void { 269 | // unimplemented!() 270 | let mut spinlock = Box::new(SpinLock::new()); 271 | let address = &mut *spinlock as *mut _ as *mut c_void; 272 | 273 | (&SPINLOCKS).lock(|spinlocks| spinlocks.insert(address, spinlock)); 274 | wprintln!("_spin_lock_create() -> {:x}", address as u32); 275 | address 276 | } 277 | 278 | pub unsafe extern "C" fn _spin_lock_delete(lock: *mut c_void) { 279 | wprintln!("_spin_lock_delete"); 280 | // unimplemented!() 281 | } 282 | 283 | static mut INT_MASK: u32 = 0; 284 | 285 | pub unsafe extern "C" fn _wifi_int_disable(wifi_int_mux: *mut c_void) -> u32 { 286 | wprintln!("_wifi_int_disable({:x?})", wifi_int_mux as u32); 287 | 288 | // disable interrupts and store old mask 289 | INT_MASK = xtensa_lx6::interrupt::disable(); 290 | 291 | 0 292 | //unimplemented!() 293 | } 294 | 295 | pub unsafe extern "C" fn _wifi_int_restore(wifi_int_mux: *mut c_void, tmp: u32) { 296 | wprintln!("_wifi_int_restore({:x?}, {:x?})", wifi_int_mux as u32, tmp); 297 | 298 | // enable previously disable interrupts 299 | xtensa_lx6::interrupt::enable_mask(INT_MASK); 300 | 301 | //unimplemented!() 302 | } 303 | pub unsafe extern "C" fn _task_yield_from_isr() { 304 | unimplemented!() 305 | } 306 | 307 | fn create_mutex() -> *mut c_void { 308 | let mut mutex = Box::new(RecursiveMutex::new()); 309 | let address = &mut *mutex as *mut _ as *mut c_void; 310 | 311 | unsafe { (&MUTEXES).lock(|mutexes| mutexes.insert(address, mutex)) }; 312 | 313 | wprintln!("create_mutex() -> {:x}", address as u32); 314 | address 315 | } 316 | 317 | fn create_semaphore(max: u32, init: u32) -> *mut c_void { 318 | let mut semaphore = Box::new(Semaphore::new(max, init)); 319 | let address = &mut *semaphore as *mut _ as *mut c_void; 320 | 321 | unsafe { (&SEMAPHORES).lock(|semaphores| semaphores.insert(address, semaphore)) }; 322 | 323 | wprintln!( 324 | "create_semaphore({}, {}) -> {:x}", 325 | max, 326 | init, 327 | address as u32 328 | ); 329 | address 330 | } 331 | 332 | pub unsafe extern "C" fn _semphr_create(max: u32, init: u32) -> *mut c_void { 333 | let address = create_semaphore(max, init); 334 | wprintln!("_semphr_create({}, {}) -> {:x}", max, init, address as u32); 335 | address 336 | } 337 | 338 | pub unsafe extern "C" fn _semphr_delete(semphr: *mut c_void) { 339 | wprintln!("_semphr_delete({:x?})", semphr as u32); 340 | 341 | (&SEMAPHORES).lock(|semaphores| semaphores.remove(&semphr)); 342 | } 343 | pub unsafe extern "C" fn _semphr_take(semphr: *mut c_void, block_time_tick: u32) -> i32 { 344 | wprintln!("_semphr_take({:x?}, {})", semphr as u32, block_time_tick); 345 | 346 | if block_time_tick == 0 { 347 | (&SEMAPHORES).lock(|semaphores| { 348 | let semaphore = semaphores.get(&semphr).unwrap(); 349 | if semaphore.take() { 350 | wprintln!("_semphr_take -> {}", TRUE); 351 | return TRUE; 352 | } else { 353 | wprintln!("_semphr_take -> {}", FALSE); 354 | return FALSE; 355 | } 356 | }); 357 | }; 358 | 359 | loop { 360 | if (&SEMAPHORES).lock(|semaphores| { 361 | let semaphore = semaphores.get(&semphr).unwrap(); 362 | semaphore.take() 363 | }) { 364 | wprintln!("_semphr_take -> {}", TRUE); 365 | return TRUE; 366 | } 367 | } 368 | } 369 | pub unsafe extern "C" fn _semphr_give(semphr: *mut c_void) -> i32 { 370 | wprintln!("_semphr_give({:x?})", semphr as u32); 371 | 372 | (&SEMAPHORES).lock(|semaphores| { 373 | let semaphore = semaphores.get(&semphr).unwrap(); 374 | semaphore.give(); 375 | }); 376 | PASS 377 | } 378 | 379 | static mut THREAD_SEMAPHORE_APP: Option<*mut c_void> = None; 380 | static mut THREAD_SEMAPHORE_PRO: Option<*mut c_void> = None; 381 | 382 | pub unsafe extern "C" fn _wifi_thread_semphr_get() -> *mut c_void { 383 | let semaphore = match esp32_hal::get_core() { 384 | esp32_hal::Core::APP => &mut THREAD_SEMAPHORE_APP, 385 | esp32_hal::Core::PRO => &mut THREAD_SEMAPHORE_PRO, 386 | }; 387 | let address = match semaphore { 388 | None => { 389 | let address = create_semaphore(1, 0); 390 | *semaphore = Some(address); 391 | address 392 | } 393 | Some(address) => *address, 394 | }; 395 | 396 | wprintln!("_wifi_thread_semphr_get -> {:x}", address as u32); 397 | address 398 | // unimplemented!() 399 | } 400 | pub unsafe extern "C" fn _mutex_create() -> *mut c_void { 401 | unimplemented!() 402 | } 403 | pub unsafe extern "C" fn _recursive_mutex_create() -> *mut c_void { 404 | // unimplemented!() 405 | wprintln!("_recursive_mutex_create"); 406 | create_mutex() 407 | } 408 | pub unsafe extern "C" fn _mutex_delete(mutex: *mut c_void) { 409 | unimplemented!() 410 | } 411 | pub unsafe extern "C" fn _mutex_lock(mutex: *mut c_void) -> i32 { 412 | wprintln!("_mutex_lock ({:x?})", mutex); 413 | 414 | (&MUTEXES).lock(|mutexes| { 415 | let mutex = mutexes.get(&mutex).unwrap(); 416 | mutex.lock(); 417 | }); 418 | // unimplemented!() 419 | TRUE 420 | } 421 | pub unsafe extern "C" fn _mutex_unlock(mutex: *mut c_void) -> i32 { 422 | // unimplemented!() 423 | wprintln!("_mutex_unlock ({:x?})", mutex); 424 | (&MUTEXES).lock(|mutexes| { 425 | let mutex = mutexes.get(&mutex).unwrap(); 426 | mutex.unlock(); 427 | }); 428 | TRUE 429 | } 430 | pub unsafe extern "C" fn _queue_create(queue_len: u32, item_size: u32) -> *mut c_void { 431 | unimplemented!() 432 | } 433 | pub unsafe extern "C" fn _queue_delete(queue: *mut c_void) { 434 | unimplemented!() 435 | } 436 | pub unsafe extern "C" fn _queue_send( 437 | queue: *mut c_void, 438 | item: *mut c_void, 439 | block_time_tick: u32, 440 | ) -> i32 { 441 | wprintln!( 442 | "_queue_send({:x?}, {:x?}, {})", 443 | queue, 444 | item, 445 | block_time_tick, 446 | ); 447 | 448 | (&QUEUES).lock(|queues| { 449 | let queue = (*queues).get(&queue).unwrap(); 450 | 451 | (&(**queue)).lock(|queue| { 452 | if (queue.send_index + queue.count) % queue.count 453 | == (queue.receive_index + queue.count - 1) % queue.count 454 | { 455 | wprintln!("_queue_send -> FALSE"); 456 | return FALSE; 457 | } 458 | core::ptr::copy( 459 | item, 460 | queue 461 | .wifi_queue 462 | .storage 463 | .add(queue.send_index * queue.item_size), 464 | queue.item_size, 465 | ); 466 | queue.send_index = (queue.send_index + 1) % queue.count; 467 | wprintln!( 468 | "_queue_send {:08x} {:08x} {} -> TRUE", 469 | *(item as *mut u32), 470 | *((item as u32 + 4) as *mut u32), 471 | queue.item_size 472 | ); 473 | TRUE 474 | }) 475 | }) 476 | } 477 | 478 | pub unsafe extern "C" fn _queue_send_from_isr( 479 | queue: *mut c_void, 480 | item: *mut c_void, 481 | hptw: *mut c_void, 482 | ) -> i32 { 483 | unimplemented!() 484 | } 485 | pub unsafe extern "C" fn _queue_send_to_back( 486 | queue: *mut c_void, 487 | item: *mut c_void, 488 | block_time_tick: u32, 489 | ) -> i32 { 490 | unimplemented!() 491 | } 492 | pub unsafe extern "C" fn _queue_send_to_front( 493 | queue: *mut c_void, 494 | item: *mut c_void, 495 | block_time_tick: u32, 496 | ) -> i32 { 497 | unimplemented!() 498 | } 499 | pub unsafe extern "C" fn _queue_recv( 500 | queue: *mut c_void, 501 | item: *mut c_void, 502 | block_time_tick: u32, 503 | ) -> i32 { 504 | wprintln!( 505 | "_queue_recv({:x?}, {:x?}, {:x?})", 506 | queue, 507 | item, 508 | block_time_tick, 509 | ); 510 | 511 | loop { 512 | let res = (&QUEUES).lock(|queues| { 513 | let queue = (*queues).get(&queue).unwrap(); 514 | 515 | (&(**queue)).lock(|queue| { 516 | if queue.send_index == queue.receive_index { 517 | FALSE 518 | } else { 519 | core::ptr::copy( 520 | queue 521 | .wifi_queue 522 | .storage 523 | .add(queue.receive_index * queue.item_size), 524 | item, 525 | queue.item_size, 526 | ); 527 | queue.receive_index = (queue.receive_index + 1) % queue.count; 528 | wprintln!( 529 | "_queue_recv {:08x} {:08x} {} -> TRUE", 530 | *(item as *mut u32), 531 | *((item as u32 + 4) as *mut u32), 532 | queue.item_size 533 | ); 534 | TRUE 535 | } 536 | }) 537 | }); 538 | 539 | if res == TRUE || block_time_tick != u32::MAX { 540 | wprintln!("_queue_recv -> {}", res); 541 | 542 | return res; 543 | } 544 | } 545 | } 546 | pub unsafe extern "C" fn _queue_msg_waiting(queue: *mut c_void) -> u32 { 547 | wprintln!("_queue_msg_waiting({:x?})", queue,); 548 | 549 | (&QUEUES).lock(|queues| { 550 | let queue = (*queues).get(&queue).unwrap(); 551 | 552 | (&(**queue)) 553 | .lock(|queue| (queue.send_index + queue.count - queue.receive_index) % queue.count) 554 | }) as u32 555 | } 556 | pub unsafe extern "C" fn _event_group_create() -> *mut c_void { 557 | unimplemented!() 558 | } 559 | pub unsafe extern "C" fn _event_group_delete(event: *mut c_void) { 560 | unimplemented!() 561 | } 562 | pub unsafe extern "C" fn _event_group_set_bits(event: *mut c_void, bits: u32) -> u32 { 563 | unimplemented!() 564 | } 565 | pub unsafe extern "C" fn _event_group_clear_bits(event: *mut c_void, bits: u32) -> u32 { 566 | unimplemented!() 567 | } 568 | pub unsafe extern "C" fn _event_group_wait_bits( 569 | event: *mut c_void, 570 | bits_to_wait_for: u32, 571 | clear_on_exit: i32, 572 | wait_for_all_bits: i32, 573 | block_time_tick: u32, 574 | ) -> u32 { 575 | unimplemented!() 576 | } 577 | 578 | static mut TASK_FUNC: Option = None; 579 | 580 | fn cpu1_start() -> ! { 581 | unsafe { 582 | if let Some(func) = TASK_FUNC { 583 | func(0 as *mut c_void); 584 | } 585 | } 586 | wprintln!("Wifi Task returned!"); 587 | loop {} 588 | } 589 | 590 | pub unsafe extern "C" fn _task_create_pinned_to_core( 591 | task_func: *mut c_void, 592 | name: *const cty::c_char, 593 | stack_depth: u32, 594 | param: *mut c_void, 595 | prio: u32, 596 | task_handle: *mut c_void, 597 | core_id: u32, 598 | ) -> i32 { 599 | wprintln!( 600 | "_task_create_pinned_to_core({:x}, {}, {}, {}, {:x}, {:x}, {})", 601 | task_func as u32, 602 | cstr_core::CStr::from_ptr(name).to_str().unwrap(), 603 | stack_depth, 604 | param as u32, 605 | prio, 606 | task_handle as u32, 607 | core_id 608 | ); 609 | TASK_FUNC = Some(core::mem::transmute(task_func)); 610 | *(task_handle as *mut u32) = 2; 611 | 612 | esp32_hal::clock_control::ClockControlConfig {} 613 | .start_app_core(cpu1_start) 614 | .unwrap(); 615 | 616 | PASS 617 | //unimplemented!() 618 | } 619 | pub unsafe extern "C" fn _task_create( 620 | task_func: *mut c_void, 621 | name: *const cty::c_char, 622 | stack_depth: u32, 623 | param: *mut c_void, 624 | prio: u32, 625 | task_handle: *mut c_void, 626 | ) -> i32 { 627 | unimplemented!() 628 | } 629 | pub unsafe extern "C" fn _task_delete(task_handle: *mut c_void) { 630 | wprintln!("_task_delete({:x})", task_handle as u32); 631 | // unimplemented!(); 632 | } 633 | pub unsafe extern "C" fn _task_delay(tick: u32) { 634 | wprintln!("_task_delay({})", tick); 635 | 636 | xtensa_lx6::timer::delay(tick); 637 | // unimplemented!() 638 | } 639 | pub unsafe extern "C" fn _task_ms_to_tick(ms: u32) -> i32 { 640 | let ticks = ms.ms() * esp32_hal::clock_control::ClockControlConfig {}.cpu_frequency(); 641 | wprintln!("_task_ms_to_tick({}) -> {}", ms, ticks); 642 | (ticks / Ticks(1)) as i32 643 | } 644 | pub unsafe extern "C" fn _task_get_current_task() -> *mut c_void { 645 | // unimplemented!() 646 | esp32_hal::get_core() as u32 as *mut c_void 647 | } 648 | pub unsafe extern "C" fn _task_get_max_priority() -> i32 { 649 | wprintln!("_task_get_max_priority"); 650 | 1 651 | } 652 | pub unsafe extern "C" fn _malloc(size: u32) -> *mut c_void { 653 | unimplemented!() 654 | } 655 | 656 | pub unsafe extern "C" fn _free(p: *mut c_void) { 657 | wprintln!("_free({:x?})", p); 658 | (&ALLOCATIONS).lock(|allocations| allocations.remove(&p)); 659 | } 660 | 661 | pub unsafe extern "C" fn _event_post( 662 | event_base: *const cty::c_char, 663 | event_id: i32, 664 | event_data: *mut c_void, 665 | event_data_size: usize, 666 | ticks_to_wait: u32, 667 | ) -> i32 { 668 | unimplemented!() 669 | } 670 | pub unsafe extern "C" fn _get_free_heap_size() -> u32 { 671 | unimplemented!() 672 | } 673 | pub unsafe extern "C" fn _rand() -> u32 { 674 | unimplemented!() 675 | } 676 | pub unsafe extern "C" fn _dport_access_stall_other_cpu_start_wrap() { 677 | unimplemented!() 678 | } 679 | pub unsafe extern "C" fn _dport_access_stall_other_cpu_end_wrap() { 680 | unimplemented!() 681 | } 682 | pub unsafe extern "C" fn _phy_rf_deinit(module: u32) -> i32 { 683 | unimplemented!() 684 | } 685 | 686 | const CONFIG_ESP32_PHY_MAX_TX_POWER: u8 = 20; 687 | 688 | const fn limit(val: u8, low: u8, high: u8) -> u8 { 689 | if val < low { 690 | low 691 | } else if val > high { 692 | high 693 | } else { 694 | val 695 | } 696 | } 697 | 698 | const PHY_DEFAULT_CALIBRATION_DATA: crate::binary::phy::esp_phy_calibration_data_t = 699 | crate::binary::phy::esp_phy_calibration_data_t { 700 | version: [0; 4], 701 | mac: [0; 6], 702 | opaque: [0; 1894], 703 | }; 704 | 705 | const PHY_DEFAULT_INIT_DATA: crate::binary::phy::esp_phy_init_data_t = 706 | crate::binary::phy::esp_phy_init_data_t { 707 | params: [ 708 | 3, 709 | 3, 710 | 0x05, 711 | 0x09, 712 | 0x06, 713 | 0x05, 714 | 0x03, 715 | 0x06, 716 | 0x05, 717 | 0x04, 718 | 0x06, 719 | 0x04, 720 | 0x05, 721 | 0x00, 722 | 0x00, 723 | 0x00, 724 | 0x00, 725 | 0x05, 726 | 0x09, 727 | 0x06, 728 | 0x05, 729 | 0x03, 730 | 0x06, 731 | 0x05, 732 | 0x00, 733 | 0x00, 734 | 0x00, 735 | 0x00, 736 | 0x00, 737 | 0x00, 738 | 0x00, 739 | 0x00, 740 | 0xfc, 741 | 0xfc, 742 | 0xfe, 743 | 0xf0, 744 | 0xf0, 745 | 0xf0, 746 | 0xe0, 747 | 0xe0, 748 | 0xe0, 749 | 0x18, 750 | 0x18, 751 | 0x18, 752 | limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 78), 753 | limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 72), 754 | limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 66), 755 | limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 60), 756 | limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 56), 757 | limit(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 40, 52), 758 | 0, 759 | 1, 760 | 1, 761 | 2, 762 | 2, 763 | 3, 764 | 4, 765 | 5, 766 | 0, 767 | 0, 768 | 0, 769 | 0, 770 | 0, 771 | 0, 772 | 0, 773 | 0, 774 | 0, 775 | 0, 776 | 0, 777 | 0, 778 | 0, 779 | 0, 780 | 0, 781 | 0, 782 | 0, 783 | 0, 784 | 0, 785 | 0, 786 | 0, 787 | 0, 788 | 0, 789 | 0, 790 | 0, 791 | 0, 792 | 0, 793 | 0, 794 | 0, 795 | 0, 796 | 0, 797 | 0, 798 | 0, 799 | 0, 800 | 0, 801 | 0, 802 | 0, 803 | 0, 804 | 0, 805 | 0, 806 | 0, 807 | 0, 808 | 0, 809 | 0, 810 | 0, 811 | 0, 812 | 0, 813 | 0, 814 | 0, 815 | 0, 816 | 0, 817 | 0, 818 | 0, 819 | 0, 820 | 0, 821 | 0, 822 | 0, 823 | 0, 824 | 0, 825 | 0, 826 | 0, 827 | 0, 828 | 0, 829 | 0, 830 | 0, 831 | 0, 832 | 0, 833 | 0, 834 | 0, 835 | 0, 836 | ], 837 | }; 838 | 839 | pub unsafe extern "C" fn _phy_load_cal_and_init(module: u32) { 840 | wprintln!("_phy_load_cal_and_init({})", module); 841 | 842 | /* 843 | // TODO: implement timer correction routines 844 | 845 | // * @param uint32_t time_delta : time duration since the WiFi/BT common clock is disabled 846 | // esp_err_t esp_wifi_internal_update_mac_time( uint32_t time_delta ); 847 | // Update time stamp 848 | s_phy_rf_en_ts = esp_timer_get_time(); 849 | phy_update_wifi_mac_time(false, s_phy_rf_en_ts); 850 | 851 | */ 852 | 853 | _phy_common_clock_enable(); 854 | crate::binary::phy::phy_set_wifi_mode_only(false); 855 | 856 | // TODO: implement modem sleep 857 | 858 | //esp_phy_calibration_data_t* cal_data = 859 | //(esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1); 860 | // const esp_phy_init_data_t* init_data = esp_phy_get_init_data(); 861 | 862 | // if (ESP_CAL_DATA_CHECK_FAIL == 863 | let res = crate::binary::phy::register_chipv7_phy( 864 | &PHY_DEFAULT_INIT_DATA, 865 | &mut PHY_DEFAULT_CALIBRATION_DATA, 866 | crate::binary::phy::esp_phy_calibration_mode_t::PHY_RF_CAL_FULL, 867 | ); 868 | wprintln!("register_chipv7_phy -> {}", res); 869 | 870 | crate::binary::phy::coex_bt_high_prio(); 871 | 872 | // TODO: implement software coexistence 873 | // coex_init(); coex_resume(); 874 | 875 | //unimplemented!() 876 | } 877 | 878 | static mut PHY_COMMON_CLOCK_REF_COUNT: CriticalSectionSpinLockMutex = 879 | CriticalSectionSpinLockMutex::new(0); 880 | 881 | pub unsafe extern "C" fn _phy_common_clock_enable() { 882 | wprintln!("_phy_common_clock_enable"); 883 | 884 | (&PHY_COMMON_CLOCK_REF_COUNT).lock(|count| { 885 | esp32_hal::dport::enable_peripheral(esp32_hal::dport::Peripheral::WIFI_BT_COMMON); 886 | *count += 1; 887 | }); 888 | } 889 | pub unsafe extern "C" fn _phy_common_clock_disable() { 890 | wprintln!("_phy_common_clock_disable"); 891 | 892 | (&PHY_COMMON_CLOCK_REF_COUNT).lock(|count| { 893 | if *count == 0 { 894 | panic!("_phy_common_clock_disable called more often then _phy_common_clock_enable") 895 | } else if *count == 1 { 896 | esp32_hal::dport::disable_peripheral(esp32_hal::dport::Peripheral::WIFI_BT_COMMON); 897 | } 898 | 899 | *count -= 1; 900 | }); 901 | } 902 | 903 | #[allow(dead_code)] 904 | enum MACType { 905 | Station = 0, 906 | AccessPoint = 1, 907 | Bluetooth = 2, 908 | Ethernet = 3, 909 | } 910 | 911 | pub unsafe extern "C" fn _read_mac(mac: *mut u8, mac_type: u32) -> i32 { 912 | if mac_type > MACType::Ethernet as u32 { 913 | wprintln!("_read_mac({:x} , {}) -> FALSE ", mac as u32, mac_type); 914 | return FALSE; 915 | } 916 | 917 | let mut efuse_mac = esp32_hal::efuse::Efuse::get_mac_address(); 918 | efuse_mac[5] += mac_type as u8; 919 | 920 | core::ptr::copy( 921 | &mut efuse_mac as *mut _ as *mut u8, 922 | mac, 923 | core::mem::size_of_val(&efuse_mac), 924 | ); 925 | 926 | wprintln!( 927 | "_read_mac({:x} -> {:x?}, {}) -> TRUE ", 928 | mac as u32, 929 | efuse_mac, 930 | mac_type 931 | ); 932 | TRUE 933 | } 934 | pub unsafe extern "C" fn _timer_arm(ptimer: *mut c_void, tmout: u32, repeat: bool) { 935 | wprintln!("_timer_arm({:x}, {}, {})", ptimer as u32, tmout, repeat); 936 | 937 | (&TIMERS).lock(|timers| { 938 | let timer = timers.get_mut(&ptimer).unwrap(); 939 | timer.id = Some( 940 | crate::wifi::WiFi::get_timer_factory().add_single(MilliSeconds(tmout).into(), &**timer), 941 | ); 942 | }); 943 | } 944 | 945 | pub unsafe extern "C" fn _timer_disarm(ptimer: *mut c_void) { 946 | wprintln!("_timer_disarm({:x})", ptimer as u32); 947 | 948 | (&TIMERS).lock(|timers| { 949 | if let Some(timer) = timers.get_mut(&ptimer) { 950 | if let Some(id) = timer.id { 951 | crate::wifi::WiFi::get_timer_factory().cancel(id); 952 | } 953 | } 954 | }); 955 | } 956 | 957 | pub unsafe extern "C" fn _timer_done(ptimer: *mut c_void) { 958 | wprintln!("_timer_done({:x?}) ", ptimer); 959 | 960 | (&TIMERS).lock(|timers| { 961 | if let Some(timer) = timers.get_mut(&ptimer) { 962 | if let Some(id) = timer.id { 963 | crate::wifi::WiFi::get_timer_factory().cancel(id); 964 | } 965 | timers.remove(&ptimer); 966 | } 967 | }); 968 | } 969 | 970 | struct Timer { 971 | id: Option, 972 | pfunction: unsafe extern "C" fn(args: *mut c_void), 973 | parg: *mut c_void, 974 | } 975 | 976 | impl crate::timer::Callback for Timer { 977 | fn handle(&self) { 978 | fwprintln!("Timer Callback: {:x}", self.pfunction as u32); 979 | unsafe { (self.pfunction)(self.parg) }; 980 | } 981 | } 982 | 983 | pub unsafe extern "C" fn _timer_setfn( 984 | ptimer: *mut c_void, 985 | pfunction: *mut c_void, 986 | parg: *mut c_void, 987 | ) { 988 | (&TIMERS).lock(|timers| { 989 | if let Some(timer) = timers.get_mut(&ptimer) { 990 | timer.pfunction = core::mem::transmute(pfunction); 991 | timer.parg = parg; 992 | } else { 993 | let timer = Box::new(Timer { 994 | id: None, 995 | pfunction: core::mem::transmute(pfunction), 996 | parg, 997 | }); 998 | 999 | timers.insert(ptimer, timer); 1000 | }; 1001 | }); 1002 | 1003 | wprintln!("_timer_setfn({:x?}, {:x?}, {:x?})", ptimer, pfunction, parg); 1004 | } 1005 | 1006 | pub unsafe extern "C" fn _timer_arm_us(ptimer: *mut c_void, us: u32, repeat: bool) { 1007 | unimplemented!() 1008 | } 1009 | 1010 | const PERIPHERAL_WIFI: u32 = 27; 1011 | const PERIPHERAL_BT: u32 = 28; 1012 | const PERIPHERAL_WIFI_BT_COMMON: u32 = 29; 1013 | const PERIPHERAL_BT_BASEBAND: u32 = 30; 1014 | const PERIPHERAL_BT_LC: u32 = 31; 1015 | 1016 | fn map_to_peripheral(periph: u32) -> esp32_hal::dport::Peripheral { 1017 | match periph { 1018 | PERIPHERAL_WIFI => esp32_hal::dport::Peripheral::WIFI, 1019 | PERIPHERAL_BT => esp32_hal::dport::Peripheral::BT, 1020 | PERIPHERAL_WIFI_BT_COMMON => esp32_hal::dport::Peripheral::WIFI_BT_COMMON, 1021 | PERIPHERAL_BT_BASEBAND => esp32_hal::dport::Peripheral::BT_BASEBAND, 1022 | PERIPHERAL_BT_LC => esp32_hal::dport::Peripheral::BT_LC, 1023 | _ => unimplemented!(), 1024 | } 1025 | } 1026 | 1027 | pub unsafe extern "C" fn _periph_module_enable(periph: u32) { 1028 | wprintln!("_periph_module_enable({})", periph); 1029 | esp32_hal::dport::enable_peripheral(map_to_peripheral(periph)); 1030 | } 1031 | pub unsafe extern "C" fn _periph_module_disable(periph: u32) { 1032 | wprintln!("_periph_module_disable({})", periph); 1033 | esp32_hal::dport::disable_peripheral(map_to_peripheral(periph)); 1034 | } 1035 | pub unsafe extern "C" fn _esp_timer_get_time() -> i64 { 1036 | unimplemented!() 1037 | } 1038 | pub unsafe extern "C" fn _nvs_set_i8(handle: u32, key: *const cty::c_char, value: i8) -> i32 { 1039 | unimplemented!() 1040 | } 1041 | pub unsafe extern "C" fn _nvs_get_i8( 1042 | handle: u32, 1043 | key: *const cty::c_char, 1044 | out_value: *mut i8, 1045 | ) -> i32 { 1046 | unimplemented!() 1047 | } 1048 | pub unsafe extern "C" fn _nvs_set_u8(handle: u32, key: *const cty::c_char, value: u8) -> i32 { 1049 | unimplemented!() 1050 | } 1051 | pub unsafe extern "C" fn _nvs_get_u8( 1052 | handle: u32, 1053 | key: *const cty::c_char, 1054 | out_value: *mut u8, 1055 | ) -> i32 { 1056 | unimplemented!() 1057 | } 1058 | pub unsafe extern "C" fn _nvs_set_u16(handle: u32, key: *const cty::c_char, value: u16) -> i32 { 1059 | unimplemented!() 1060 | } 1061 | pub unsafe extern "C" fn _nvs_get_u16( 1062 | handle: u32, 1063 | key: *const cty::c_char, 1064 | out_value: *mut u16, 1065 | ) -> i32 { 1066 | unimplemented!() 1067 | } 1068 | pub unsafe extern "C" fn _nvs_open( 1069 | name: *const cty::c_char, 1070 | open_mode: u32, 1071 | out_handle: *mut u32, 1072 | ) -> i32 { 1073 | unimplemented!() 1074 | } 1075 | pub unsafe extern "C" fn _nvs_close(handle: u32) { 1076 | unimplemented!() 1077 | } 1078 | pub unsafe extern "C" fn _nvs_commit(handle: u32) -> i32 { 1079 | unimplemented!() 1080 | } 1081 | pub unsafe extern "C" fn _nvs_set_blob( 1082 | handle: u32, 1083 | key: *const cty::c_char, 1084 | value: *const c_void, 1085 | length: usize, 1086 | ) -> i32 { 1087 | unimplemented!() 1088 | } 1089 | pub unsafe extern "C" fn _nvs_get_blob( 1090 | handle: u32, 1091 | key: *const cty::c_char, 1092 | out_value: *mut c_void, 1093 | length: *mut usize, 1094 | ) -> i32 { 1095 | unimplemented!() 1096 | } 1097 | pub unsafe extern "C" fn _nvs_erase_key(handle: u32, key: *const cty::c_char) -> i32 { 1098 | unimplemented!() 1099 | } 1100 | pub unsafe extern "C" fn _get_random(buf: *mut u8, len: usize) -> i32 { 1101 | unimplemented!() 1102 | } 1103 | pub unsafe extern "C" fn _get_time(t: *mut c_void) -> i32 { 1104 | unimplemented!() 1105 | } 1106 | pub unsafe extern "C" fn _random() -> cty::c_ulong { 1107 | unimplemented!() 1108 | } 1109 | pub unsafe extern "C" fn _log_write( 1110 | level: u32, 1111 | tag: *const cty::c_char, 1112 | format: *const cty::c_char, 1113 | mut args: ... 1114 | ) { 1115 | let a: u32 = args.arg(); 1116 | wprintln!( 1117 | "_log_write({}, {}, {}, {:x?})", 1118 | level, 1119 | cstr_core::CStr::from_ptr(tag).to_str().unwrap(), 1120 | cstr_core::CStr::from_ptr(format).to_str().unwrap(), 1121 | a 1122 | ); 1123 | // unimplemented!() 1124 | } 1125 | pub unsafe extern "C" fn _log_writev( 1126 | level: u32, 1127 | tag: *const cty::c_char, 1128 | format: *const cty::c_char, 1129 | args: *mut __va_list_tag, 1130 | ) { 1131 | wprintln!( 1132 | "_log_writev({}, {}, {}, ...)", 1133 | level, 1134 | cstr_core::CStr::from_ptr(tag).to_str().unwrap(), 1135 | cstr_core::CStr::from_ptr(format).to_str().unwrap(), 1136 | ); 1137 | // unimplemented!() 1138 | } 1139 | pub unsafe extern "C" fn _log_timestamp() -> u32 { 1140 | // unimplemented!() 1141 | 1 1142 | } 1143 | 1144 | pub unsafe extern "C" fn _malloc_internal(size: usize) -> *mut c_void { 1145 | wprintln!("_malloc_internal({})", size); 1146 | alloc(size, true, false) 1147 | } 1148 | 1149 | pub unsafe extern "C" fn _realloc_internal(ptr: *mut c_void, size: usize) -> *mut c_void { 1150 | unimplemented!() 1151 | } 1152 | pub unsafe extern "C" fn _calloc_internal(n: usize, size: usize) -> *mut c_void { 1153 | unimplemented!() 1154 | } 1155 | pub unsafe extern "C" fn _zalloc_internal(size: usize) -> *mut c_void { 1156 | wprintln!("_zalloc_internal({})", size); 1157 | alloc(size, true, true) 1158 | } 1159 | pub unsafe extern "C" fn _wifi_malloc(size: usize) -> *mut c_void { 1160 | wprintln!("_wifi_malloc({})", size); 1161 | alloc(size, false, false) 1162 | } 1163 | pub unsafe extern "C" fn _wifi_realloc(ptr: *mut c_void, size: usize) -> *mut c_void { 1164 | unimplemented!() 1165 | } 1166 | pub unsafe extern "C" fn _wifi_calloc(n: usize, size: usize) -> *mut c_void { 1167 | wprintln!("_wifi_calloc({})", size); 1168 | alloc(n * size, false, true) 1169 | } 1170 | pub unsafe extern "C" fn _wifi_zalloc(size: usize) -> *mut c_void { 1171 | wprintln!("_wifi_zalloc({})", size); 1172 | alloc(size, false, true) 1173 | } 1174 | 1175 | pub unsafe extern "C" fn _wifi_create_queue(queue_len: i32, item_size: i32) -> *mut c_void { 1176 | let queue = Box::new(CriticalSectionSpinLockMutex::new(Queue { 1177 | wifi_queue: WifiStaticQueue { 1178 | handle: 0 as *mut c_void, 1179 | storage: alloc(queue_len as usize * item_size as usize, true, true), 1180 | }, 1181 | count: queue_len as usize, 1182 | item_size: item_size as usize, 1183 | send_index: 0, 1184 | receive_index: 0, 1185 | })); 1186 | let address = (&*queue).lock(|queue| { 1187 | let address = &mut (*queue).wifi_queue as *mut _ as *mut c_void; 1188 | (*queue).wifi_queue.handle = address; 1189 | address 1190 | }); 1191 | (&QUEUES).lock(|queues| queues.insert(address, queue)); 1192 | 1193 | wprintln!( 1194 | "_wifi_create_queue({}, {}) -> {:x?}", 1195 | queue_len, 1196 | item_size, 1197 | address 1198 | ); 1199 | address 1200 | } 1201 | pub unsafe extern "C" fn _wifi_delete_queue(queue: *mut c_void) { 1202 | wprintln!("_wifi_delete_queue({:x?})", queue as u32); 1203 | //unimplemented!() 1204 | } 1205 | 1206 | pub unsafe extern "C" fn _modem_sleep_enter(module: u32) -> i32 { 1207 | unimplemented!() 1208 | } 1209 | pub unsafe extern "C" fn _modem_sleep_exit(module: u32) -> i32 { 1210 | wprintln!("_modem_sleep_exit({})", module); 1211 | // unimplemented!() 1212 | ESP_OK 1213 | } 1214 | pub unsafe extern "C" fn _modem_sleep_register(module: u32) -> i32 { 1215 | wprintln!("_modem_sleep_register({})", module); 1216 | // unimplemented!() 1217 | ESP_OK 1218 | } 1219 | pub unsafe extern "C" fn _modem_sleep_deregister(module: u32) -> i32 { 1220 | unimplemented!() 1221 | } 1222 | pub unsafe extern "C" fn _coex_status_get() -> u32 { 1223 | wprintln!("_coex_status_get()"); 1224 | // unimplemented!() 1225 | 0 1226 | } 1227 | pub unsafe extern "C" fn _coex_condition_set(type_: u32, dissatisfy: bool) { 1228 | unimplemented!() 1229 | } 1230 | pub unsafe extern "C" fn _coex_wifi_request(event: u32, latency: u32, duration: u32) -> i32 { 1231 | wprintln!("_coex_wifi_request({}, {}, {})", event, latency, duration); 1232 | // unimplemented!() 1233 | return 0; // use hardware coexistance 1234 | } 1235 | pub unsafe extern "C" fn _coex_wifi_release(event: u32) -> i32 { 1236 | wprintln!("_coex_wifi_release({})", event); 1237 | // unimplemented!() 1238 | return 0; // use hardware coexistance 1239 | } 1240 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![feature(c_variadic)] 3 | #![feature(raw_vec_internals)] 4 | #![feature(const_btree_new)] 5 | #![feature(const_if_match)] 6 | #![feature(llvm_asm)] 7 | #![feature(associated_type_bounds)] 8 | #![feature(const_fn)] 9 | #![feature(binary_heap_retain)] 10 | 11 | extern crate alloc; 12 | 13 | pub mod binary; 14 | pub mod compatibility; 15 | pub mod timer; 16 | pub mod wifi; 17 | 18 | mod log; 19 | -------------------------------------------------------------------------------- /src/log.rs: -------------------------------------------------------------------------------- 1 | /// Macro for logging WIFI info. 2 | /// 3 | use xtensa_lx6::mutex::CriticalSectionSpinLockMutex; 4 | 5 | pub static LOCK: CriticalSectionSpinLockMutex<()> = CriticalSectionSpinLockMutex::new(()); 6 | 7 | #[macro_export] 8 | macro_rules! fwprintln { 9 | ($($arg:tt)*) => { 10 | { 11 | use esp32_hal::{dprint, dprintln}; 12 | use xtensa_lx6::mutex::mutex_trait::Mutex; 13 | (&crate::log::LOCK).lock(|_| { 14 | dprint!("WIFI core {:?}: ",esp32_hal::get_core()); 15 | dprintln!($($arg)*); 16 | }); 17 | } 18 | }; 19 | } 20 | 21 | #[macro_export] 22 | macro_rules! wprintln { 23 | ($($arg:tt)*) => { 24 | // crate::fwprintln!($($arg)*); 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /src/timer.rs: -------------------------------------------------------------------------------- 1 | use alloc::collections::binary_heap::BinaryHeap; 2 | use core::cell::Cell; 3 | use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; 4 | use esp32_hal::prelude::*; 5 | use esp32_hal::timer::{self, TimerWithInterrupt}; 6 | 7 | pub trait Callback { 8 | fn handle(&self); 9 | } 10 | 11 | struct Event<'a, Time: Ord> { 12 | next: Time, 13 | interval: Time, 14 | id: usize, 15 | callback: &'a dyn Callback, 16 | } 17 | 18 | #[derive(Copy, Clone)] 19 | pub struct TimerID { 20 | id: usize, 21 | } 22 | 23 | impl Ord for Event<'_, T> { 24 | fn cmp(&self, other: &Self) -> Ordering { 25 | self.next.cmp(&other.next).reverse() 26 | } 27 | } 28 | 29 | impl PartialOrd for Event<'_, T> { 30 | fn partial_cmp(&self, other: &Self) -> Option { 31 | Some(self.next.cmp(&other.next).reverse()) 32 | } 33 | } 34 | 35 | impl Eq for Event<'_, T> {} 36 | 37 | impl PartialEq for Event<'_, T> { 38 | fn eq(&self, other: &Self) -> bool { 39 | self.next == other.next 40 | } 41 | } 42 | 43 | pub struct TimerInterruptHandler<'a, TIMER: TimerWithInterrupt> { 44 | timer_factory: Cell<*mut TimerFactoryImpl<'a, TIMER>>, 45 | } 46 | 47 | unsafe impl<'a, TIMER: TimerWithInterrupt> Sync for TimerInterruptHandler<'a, TIMER> {} 48 | 49 | impl<'a, TIMER: TimerWithInterrupt> TimerInterruptHandler<'a, TIMER> { 50 | pub const fn new() -> Self { 51 | Self { 52 | timer_factory: Cell::new(core::ptr::null_mut()), 53 | } 54 | } 55 | 56 | pub fn handle(&self) { 57 | unsafe { 58 | if let Some(timer_factory) = self.timer_factory.get().as_mut() { 59 | timer_factory.handle_interrupt(); 60 | } 61 | } 62 | } 63 | 64 | pub fn set_timer_factory(&self, timer_factory: &mut TimerFactoryImpl<'a, TIMER>) { 65 | self.timer_factory.set(timer_factory as *mut _); 66 | timer_factory.set_interrupt_handler(self); 67 | } 68 | 69 | fn unset_timer_factory(&self) { 70 | self.timer_factory.set(core::ptr::null_mut()); 71 | } 72 | } 73 | 74 | impl<'a, TIMER: TimerWithInterrupt> Drop for TimerInterruptHandler<'a, TIMER> { 75 | fn drop(&mut self) { 76 | unsafe { 77 | if let Some(timer_factory) = self.timer_factory.get().as_mut() { 78 | timer_factory.unset_interrupt_handler(); 79 | } 80 | } 81 | } 82 | } 83 | 84 | pub trait TimerFactory<'a> { 85 | fn add_single(&mut self, time: NanoSecondsU64, callback: &'a dyn Callback) -> TimerID; 86 | fn add_periodic( 87 | &mut self, 88 | time: NanoSecondsU64, 89 | period: NanoSecondsU64, 90 | callback: &'a dyn Callback, 91 | ) -> TimerID; 92 | fn cancel(&mut self, id: TimerID); 93 | } 94 | 95 | pub struct TimerFactoryImpl<'a, TIMER: TimerWithInterrupt> { 96 | timer: Option, 97 | queue: BinaryHeap>, 98 | timer_interrupt_handler: Cell<*const TimerInterruptHandler<'a, TIMER>>, 99 | id: usize, 100 | } 101 | 102 | impl<'a, TIMER: TimerWithInterrupt> TimerFactoryImpl<'a, TIMER> { 103 | pub fn new(mut timer: TIMER) -> Self { 104 | timer 105 | .enable(false) 106 | .set_divider(3) 107 | .unwrap() 108 | .auto_reload(false) 109 | .set_value(0) 110 | .set_alarm(0) 111 | .enable_alarm(true) 112 | .enable(true); 113 | 114 | timer.clear_interrupt(); 115 | timer.listen(timer::Event::TimeOut); 116 | 117 | TimerFactoryImpl { 118 | timer: Some(timer), 119 | queue: BinaryHeap::new(), 120 | timer_interrupt_handler: Cell::new(core::ptr::null()), 121 | id: 0, 122 | } 123 | } 124 | 125 | pub fn release(mut self) -> TIMER { 126 | self.timer.take().unwrap() 127 | } 128 | 129 | fn handle_interrupt(&mut self) { 130 | // TODO: safe handling of queue: wrap in Mutex? 131 | let timer = self.timer.as_mut().unwrap(); 132 | 133 | loop { 134 | if let Some(event) = self.queue.peek() { 135 | let now = timer.get_value_in_ns(); 136 | if event.next <= now { 137 | event.callback.handle(); 138 | if let Some(mut event) = self.queue.pop() { 139 | if event.interval > NanoSecondsU64(0) { 140 | event.next = event.next + event.interval; 141 | self.queue.push(event); 142 | } 143 | } 144 | } 145 | } 146 | 147 | if let Some(next_event) = self.queue.peek() { 148 | timer.set_alarm_in_ns(next_event.next); 149 | timer.clear_interrupt(); 150 | if next_event.next > timer.get_value_in_ns() { 151 | break; 152 | } 153 | } else { 154 | timer.clear_interrupt(); 155 | break; 156 | } 157 | } 158 | } 159 | 160 | fn set_interrupt_handler(&self, handler: &TimerInterruptHandler<'a, TIMER>) { 161 | self.timer_interrupt_handler.set(handler as *const _); 162 | } 163 | 164 | fn unset_interrupt_handler(&mut self) { 165 | self.timer_interrupt_handler.set(core::ptr::null()); 166 | } 167 | } 168 | 169 | impl<'a, TIMER: TimerWithInterrupt> TimerFactory<'a> for TimerFactoryImpl<'a, TIMER> { 170 | fn add_single(&mut self, time: NanoSecondsU64, callback: &'a dyn Callback) -> TimerID { 171 | self.add_periodic(time, NanoSecondsU64(0), callback) 172 | } 173 | 174 | fn add_periodic( 175 | &mut self, 176 | time: NanoSecondsU64, 177 | period: NanoSecondsU64, 178 | callback: &'a dyn Callback, 179 | ) -> TimerID { 180 | // TODO: safe handling of queue: wrap in Mutex? 181 | 182 | let now = self.timer.as_ref().unwrap().get_value_in_ns(); 183 | self.id += 1; 184 | let event = Event { 185 | next: time + now, 186 | interval: period.into(), 187 | id: self.id, 188 | callback: callback, 189 | }; 190 | self.queue.push(event); 191 | self.handle_interrupt(); 192 | 193 | TimerID { id: self.id } 194 | } 195 | 196 | fn cancel(&mut self, id: TimerID) { 197 | self.queue.retain(|x| x.id != id.id); 198 | self.handle_interrupt(); 199 | } 200 | } 201 | 202 | impl<'a, TIMER: TimerWithInterrupt> Drop for TimerFactoryImpl<'a, TIMER> { 203 | fn drop(&mut self) { 204 | unsafe { 205 | if let Some(timer) = &mut self.timer { 206 | timer.enable_alarm(false); 207 | timer.enable(false); 208 | timer.clear_interrupt(); 209 | } 210 | 211 | if let Some(handler) = self.timer_interrupt_handler.get().as_ref() { 212 | handler.unset_timer_factory(); 213 | } 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/wifi.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | use crate::compatibility::crypto::WPA_CRYPTO_FUNCS; 4 | use crate::compatibility::osi::WIFI_OS_FUNCS; 5 | use crate::wprintln; 6 | use num_derive::FromPrimitive; 7 | use num_traits::FromPrimitive; 8 | 9 | pub struct WiFi<'a, 'b> { 10 | _apb_lock: esp32_hal::clock_control::dfs::LockAPB, 11 | timer_factory: &'a mut dyn crate::timer::TimerFactory<'b>, 12 | } 13 | 14 | use crate::binary::wifi::{ 15 | esp_err_t, esp_event_base_t, esp_interface_t, wifi_mode_t, wifi_sta_config_t, TickType_t, 16 | }; 17 | 18 | pub type Mode = wifi_mode_t; 19 | 20 | #[derive(FromPrimitive, Debug)] 21 | #[allow(non_camel_case_types)] 22 | pub enum Error { 23 | BASE = 0x3000, 24 | NOT_INIT, 25 | NOT_STARTED, 26 | NOT_STOPPED, 27 | IF, 28 | MODE, 29 | STATE, 30 | CONN, 31 | NVS, 32 | MAC, 33 | SSID, 34 | PASSWORD, 35 | TIMEOUT, 36 | WAKE_FAIL, 37 | WOULD_BLOCK, 38 | NOT_CONNECT, 39 | 40 | POST = 0x3000 + 18, 41 | INIT_STATE, 42 | STOP_STATE, 43 | 44 | Unknown, 45 | } 46 | 47 | impl Error { 48 | fn from(res: i32) -> Option { 49 | if res == 0 { 50 | None 51 | } else { 52 | if let Some(error) = FromPrimitive::from_i32(res) { 53 | Some(error) 54 | } else { 55 | Some(Self::Unknown) 56 | } 57 | } 58 | } 59 | fn check_and_return(res: i32, value: T) -> Result { 60 | match Error::from(res) { 61 | None => return Ok(value), 62 | Some(error) => Err(error), 63 | } 64 | } 65 | fn convert(res: i32) -> Result<(), Error> { 66 | Error::check_and_return(res, ()) 67 | } 68 | } 69 | 70 | unsafe extern "C" fn system_event_handler( 71 | event_base: esp_event_base_t, 72 | event_id: i32, 73 | event_data: *mut cty::c_void, 74 | event_data_size: usize, 75 | ticks_to_wait: TickType_t, 76 | ) -> esp_err_t { 77 | wprintln!( 78 | "system_event_handler({:x}, {}, {:x}, {}, {})", 79 | event_base as u32, 80 | event_id, 81 | event_data as u32, 82 | event_data_size, 83 | ticks_to_wait 84 | ); 85 | // unimplemented!(); 86 | 0 87 | } 88 | 89 | pub(crate) static mut WIFI: Option> = None; 90 | 91 | impl<'a, 'b> Drop for WiFi<'a, 'b> { 92 | fn drop(&mut self) { 93 | self.stop().unwrap(); 94 | unsafe { WIFI = None }; 95 | } 96 | } 97 | 98 | impl<'a, 'b> WiFi<'a, 'b> { 99 | pub(crate) fn get() -> &'a mut WiFi<'a, 'b> { 100 | unsafe { core::mem::transmute::<_, Option<&mut WiFi<'a, 'b>>>(WIFI.as_mut()).unwrap() } 101 | } 102 | 103 | pub(crate) fn get_timer_factory() -> &'a mut dyn crate::timer::TimerFactory<'b> { 104 | WiFi::get().timer_factory 105 | } 106 | 107 | pub fn new( 108 | clock_config: esp32_hal::clock_control::ClockControlConfig, 109 | timer_factory: &'a mut dyn crate::timer::TimerFactory<'b>, 110 | ) -> Result<&'a mut WiFi<'a, 'b>, Error> { 111 | let wifi = WiFi { 112 | _apb_lock: clock_config.lock_apb_frequency(), 113 | timer_factory: timer_factory, 114 | }; 115 | 116 | unsafe { 117 | let config = crate::binary::wifi::wifi_init_config_t { 118 | event_handler: Some(system_event_handler), 119 | osi_funcs: &mut WIFI_OS_FUNCS, 120 | wpa_crypto_funcs: WPA_CRYPTO_FUNCS, 121 | static_rx_buf_num: 10, 122 | dynamic_rx_buf_num: 32, 123 | tx_buf_type: 1, 124 | static_tx_buf_num: 0, 125 | dynamic_tx_buf_num: 32, 126 | csi_enable: 0, 127 | ampdu_rx_enable: 1, 128 | ampdu_tx_enable: 1, 129 | nvs_enable: 0, 130 | nano_enable: 0, 131 | tx_ba_win: 6, 132 | rx_ba_win: 6, 133 | wifi_task_core_id: 0, 134 | beacon_max_len: 752, 135 | mgmt_sbuf_num: 32, 136 | feature_caps: 1, // CONFIG_FEATURE_WPA3_SAE_BIT 137 | magic: 0x1F2F3F4F, 138 | }; 139 | 140 | wprintln!("test1"); 141 | let wifi_static = Some(core::mem::transmute::<_, WiFi<'static, 'static>>(wifi)); 142 | WIFI = wifi_static; 143 | wprintln!("test2"); 144 | 145 | if let Some(error) = Error::from(crate::binary::wifi::esp_wifi_init_internal(&config)) { 146 | return Err(error); 147 | } 148 | // enable all logging 149 | if let Some(error) = Error::from(crate::binary::wifi::esp_wifi_internal_set_log_mod( 150 | crate::binary::wifi::wifi_log_module_t::WIFI_LOG_MODULE_ALL, 151 | 0, 152 | true, 153 | )) { 154 | return Err(error); 155 | } 156 | 157 | Ok(core::mem::transmute::<_, Option<&mut WiFi<'a, 'b>>>(WIFI.as_mut()).unwrap()) 158 | } 159 | } 160 | 161 | pub fn set_mode(&self, mode: Mode) -> Result<(), Error> { 162 | Error::convert(unsafe { crate::binary::wifi::esp_wifi_set_mode(mode) }) 163 | } 164 | pub fn set_station_config(&self, config: &mut wifi_sta_config_t) -> Result<(), Error> { 165 | Error::convert(unsafe { 166 | crate::binary::wifi::esp_wifi_set_config( 167 | esp_interface_t::ESP_IF_WIFI_STA, 168 | config as *mut _ as *mut crate::binary::wifi::wifi_config_t, 169 | ) 170 | }) 171 | } 172 | 173 | pub fn start(&self) -> Result<(), Error> { 174 | Error::convert(unsafe { crate::binary::wifi::esp_wifi_start() }) 175 | } 176 | 177 | pub fn scan(&self) -> Result { 178 | if let Some(error) = 179 | Error::from(unsafe { crate::binary::wifi::esp_wifi_scan_start(0 as *const _, true) }) 180 | { 181 | return Err(error); 182 | } 183 | 184 | let mut count: u16 = 0; 185 | if let Some(error) = 186 | Error::from(unsafe { crate::binary::wifi::esp_wifi_scan_get_ap_num(&mut count) }) 187 | { 188 | return Err(error); 189 | } 190 | 191 | /* Error::convert(unsafe { 192 | crate::binary::wifi::esp_wifi_scan_get_ap_records(&mut count, true) 193 | });*/ 194 | // ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, true)); 195 | // ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count)); 196 | // ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info)); 197 | Ok(count) 198 | } 199 | 200 | pub fn stop(&self) -> Result<(), Error> { 201 | Error::convert(unsafe { crate::binary::wifi::esp_wifi_stop() }) 202 | } 203 | } 204 | --------------------------------------------------------------------------------