├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── Data-Logger-PCB ├── Hardware.md ├── data_logger_esp32c3 │ ├── data_logger_esp32c3-backups │ │ ├── data_logger_esp32c3-2023-01-07_185947.zip │ │ ├── data_logger_esp32c3-2023-01-07_190541.zip │ │ ├── data_logger_esp32c3-2023-01-07_191944.zip │ │ ├── data_logger_esp32c3-2023-01-07_193510.zip │ │ ├── data_logger_esp32c3-2023-01-07_210022.zip │ │ ├── data_logger_esp32c3-2023-01-09_071126.zip │ │ ├── data_logger_esp32c3-2023-01-11_192632.zip │ │ ├── data_logger_esp32c3-2023-02-26_181754.zip │ │ ├── data_logger_esp32c3-2023-02-26_184543.zip │ │ ├── data_logger_esp32c3-2023-02-26_185756.zip │ │ ├── data_logger_esp32c3-2023-02-26_194926.zip │ │ ├── data_logger_esp32c3-2023-02-26_221651.zip │ │ ├── data_logger_esp32c3-2023-02-27_151622.zip │ │ ├── data_logger_esp32c3-2023-02-27_183340.zip │ │ ├── data_logger_esp32c3-2023-02-28_140739.zip │ │ └── data_logger_esp32c3-2023-03-01_072315.zip │ ├── data_logger_esp32c3.csv │ ├── data_logger_esp32c3.kicad_pcb │ ├── data_logger_esp32c3.kicad_prl │ ├── data_logger_esp32c3.kicad_pro │ ├── data_logger_esp32c3.kicad_sch │ ├── fp-info-cache │ ├── fp-lib-table │ ├── gerbers.zip │ ├── gerbers │ │ ├── data_logger_esp32c3-B_Cu.gbr │ │ ├── data_logger_esp32c3-B_Mask.gbr │ │ ├── data_logger_esp32c3-B_Paste.gbr │ │ ├── data_logger_esp32c3-B_Silkscreen.gbr │ │ ├── data_logger_esp32c3-Edge_Cuts.gbr │ │ ├── data_logger_esp32c3-F_Cu.gbr │ │ ├── data_logger_esp32c3-F_Mask.gbr │ │ ├── data_logger_esp32c3-F_Paste.gbr │ │ ├── data_logger_esp32c3-F_Silkscreen.gbr │ │ ├── data_logger_esp32c3-In1_Cu.gbr │ │ ├── data_logger_esp32c3-In2_Cu.gbr │ │ ├── data_logger_esp32c3-NPTH-drl_map.gbr │ │ ├── data_logger_esp32c3-NPTH.drl │ │ ├── data_logger_esp32c3-PTH-drl_map.gbr │ │ ├── data_logger_esp32c3-PTH.drl │ │ ├── data_logger_esp32c3-all-pos.csv │ │ └── data_logger_esp32c3-job.gbrjob │ ├── report.txt │ └── sym-lib-table ├── docs │ ├── datasheets │ │ ├── 1811062123_Diodes-Incorporated-AZ1117IH-3-3TRG1_C108495.pdf │ │ ├── ESP32-C3-DevKit-Lipo_Rev_B.pdf │ │ ├── esp32-c3-mini-1_datasheet_en.pdf │ │ └── mc33063a.pdf │ ├── esp32-c3_hardware_design_guidelines_en.pdf │ └── examples │ │ ├── ESP32-C3-DevKit-Lipo_Rev_B (1).pdf │ │ ├── ESP32-C3-DevKit-Lipo_Rev_B.pdf │ │ └── SCH_ESP32-C3-DEVKITM-1_V1_Schematic.pdf └── kicad_libraries │ ├── remote_data_logger.bak │ ├── remote_data_logger.kicad_sym │ └── remote_data_logger.pretty │ ├── 472192001.kicad_mod │ ├── 8-WDFN Exposed Pad.kicad_mod │ ├── B0530WS_SE.kicad_mod │ ├── DFN1610.kicad_mod │ ├── LM321MF.kicad_mod │ ├── QFN-28-EP(4x4).kicad_mod │ ├── SOT-223-4.kicad_mod │ ├── SOT-23.kicad_mod │ ├── USB-TYPE-C-018.kicad_mod │ └── WS2812B-2020.kicad_mod ├── LICENSE ├── README.md ├── Tutorials ├── p0-output │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p1-input │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p2-threads │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p3-adc │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p4-dht11 │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p5-i2c │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p6-spi │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── p7-uart │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs └── p8-cli │ ├── .cargo │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ ├── cli.rs │ └── main.rs ├── WIP ├── ch03-blinky-fsm │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── led_fsm.rs │ │ └── main.rs ├── ch04-blinky-button-hsm │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── led_fsm.rs │ │ └── main.rs ├── ch04-blinky-multi-thread │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── ch05-adc_to_ledc │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs ├── ch05-blinky-crossbeams │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── led_fsm.rs │ │ └── main.rs ├── ch06-blinky-adc │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── led_fsm.rs │ │ ├── main.rs │ │ └── tasks.rs ├── ch06-neopixel │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── main.rs │ │ └── neopixel.rs ├── ch06-wifi-mqtt │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── cloud.rs │ │ ├── main.rs │ │ ├── tasks.rs │ │ └── wifi.rs ├── ch07-blinky-mqtt │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ ├── cloud.rs │ │ ├── led_fsm.rs │ │ ├── main.rs │ │ └── tasks.rs ├── p4-neopixel │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ │ └── main.rs └── wifi │ ├── .cargo │ └── config.toml │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── rust-toolchain.toml │ ├── sdkconfig.defaults │ └── src │ ├── main.rs │ └── wifi.rs └── docs ├── DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf ├── ESP32-C3-DevKit-Lipo_Rev_B.pdf └── PSiCC2.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | .DS_STORE 13 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /Data-Logger-PCB/Hardware.md: -------------------------------------------------------------------------------- 1 | # Hardware 2 | 3 | This document is for the hardware portion of the project. 4 | 5 | ## Hardware Design Log 6 | 1. Import ESP32-C3-Mini-1 symbol and footprint from [Espressif KiCad Library](https://github.com/espressif/kicad-libraries) 7 | 2. Place `ESP32-CE-Mini-1` module with decoupling/bulking caps 8 | 3. Create `enable` circuit for ESP32C3 9 | 4. Create programming circuit for ESP32C3 10 | - Only need `USB D+/D-` pins `18/19` to program the ESP32-C3 because it has a `integrated USB Serial/JTAG Controller`, see [doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html) 11 | - [USB C plug vs recepticle](https://www.arrow.com/en/research-and-events/articles/usb-technology-c-plug-and-receptacle-pinouts) 12 | 5. Add power circuits 13 | - Linear LDO will do for the first version 14 | - Need `0.5A` max 15 | - Add [PMOS reverse polarity protection circuit](https://components101.com/articles/design-guide-pmos-mosfet-for-reverse-voltage-polarity-protection) 16 | 6. ADC circuit 17 | - Op-amp voltage follower 18 | - 5 voltage ranges monitored: 19 | - 2 x `3.3v` 20 | - 1 x `5v` 21 | - 1 x `12v` 22 | - 1 x `24v` 23 | 7. uSD card circuit 24 | - [pull-ups for all unused pins](https://electronics.stackexchange.com/questions/39571/how-to-do-pulling-up-or-down-correctly-when-interfacing-a-microsd-card) 25 | 26 | 27 | ## Convert EasyEDA footprints to KiCAD 28 | JLCPCB is the cheapest board house including assembly. But you have to use their specific [parts library](https://jlcpcb.com/parts). To easily get footprints for parts you can: 29 | 1. Open the footprint in EasyEDA 30 | 2. `File` > `Export` > `EasyEDA` 31 | 3. Insteall [lc2kicad](https://github.com/RigoLigoRLC/LC2KiCad) 32 | 4. Alias the command so it's easier to user 33 | ```bash 34 | alias lc2kicad="${Path_to_repo}/submodules/lc2kicad/build/lc2kicad" 35 | ``` 36 | 5. Convert `EasyEDA` footprint to KiCAD 37 | ```bash 38 | lc2kicad ~/Downloads/PCB_NEW_PCB_2022-12-04.json 39 | ``` 40 | 6. Open footprint in KiCAD 41 | 7. Create new footprint in KiCAD and copy/paste part 42 | 43 | https://jlcpcb.com/parts 44 | 45 | ## TODO 46 | - Page Documentation 47 | - Circuit documenations 48 | - spec specific passives 49 | 50 | ## Circuits 51 | - ESP32-C3 52 | - Power bulk cap 53 | - Power decoupling cap 54 | - `Enable` circuit 55 | - `RC` circuit 56 | - Programming circuit 57 | 58 | ## Notes 59 | - Use relative path libraries in KiCAD 60 | - Make sure all data sheets are saved 61 | - Add thermistor circuits 62 | - Add I2C power bus reset circuit 63 | - Add decoupling caps near USB trace switching planes 64 | - [info](https://electronics.stackexchange.com/questions/141264/can-differential-usb-traces-be-routed-relative-to-power-not-ground-planes) -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_185947.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_185947.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_190541.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_190541.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_191944.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_191944.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_193510.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_193510.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_210022.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-07_210022.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-09_071126.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-09_071126.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-11_192632.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-01-11_192632.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_181754.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_181754.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_184543.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_184543.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_185756.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_185756.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_194926.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_194926.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_221651.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-26_221651.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-27_151622.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-27_151622.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-27_183340.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-27_183340.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-28_140739.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-02-28_140739.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-03-01_072315.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3-backups/data_logger_esp32c3-2023-03-01_072315.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3.csv: -------------------------------------------------------------------------------- 1 | "Id";"Designator";"Package";"Quantity";"Designation";"Supplier and ref"; 2 | 1;"U5,U4,U8,U6,U7";"LM321MF";5;"LM321MF";;; 3 | 2;"IO13,DC-1,DC+1,IO11,IO5,VIN1,IO15,A2N1,A3N1,SDA1,TX0,IO0,IO1,A0N1,3V3,IO6,IO3,A3P1,A4P1,RX0,A4N1,IO10,I2SN1,I2SP1,NRESET1,SCL1,IO9,A0P1,IO8,IO2,IO4,A2P1,IO14,NINT1,IO7,IO12";"TestPoint_THTPad_1.0x1.0mm_Drill0.5mm";36;"TestPoint";;; 4 | 3;"R4,R1,R15,R3,R14,R9";"R_0402_1005Metric";6;"10k";;; 5 | 4;"C1";"C_0402_1005Metric";1;"1uF";;; 6 | 5;"R2,R7";"R_0402_1005Metric";2;"5.1k";;; 7 | 6;"C2,C5,C4";"C_0603_1608Metric";3;"10uF";;; 8 | 7;"SD1";"472192001";1;"472192001";;; 9 | 8;"R12";"R_0402_1005Metric";1;"7.5k";;; 10 | 9;"R18,R17";"R_0402_1005Metric";2;"30.1";;; 11 | 10;"R6,R5,R13";"R_0402_1005Metric";3;"1k";;; 12 | 11;"R16,R8";"R_0402_1005Metric";2;"4.7k";;; 13 | 12;"U1";"ESP32-C3-MINI-1";1;"ESP32-C3-MINI-1";;; 14 | 13;"R11";"R_0402_1005Metric";1;"3.92k";;; 15 | 14;"R10";"R_0402_1005Metric";1;"1.6k";;; 16 | 15;"U9,U10";"SOT-23";2;"A03401A";;; 17 | 16;"D1";"DFN1610";1;"LTVS16H5.0T5G";;; 18 | 17;"U2";"SOT-223-4";1;"AZ1117IH-3.3TRG1";;; 19 | 18;"U11";"QFN-28-EP(4x4)";1;"SX1509BIULTRT";;; 20 | 19;"C3,C7,C6";"C_0402_1005Metric";3;"0.1uF";;; 21 | 20;"USB-C1";"USB-TYPE-C-018";1;"USB-TYPE-C-018";;; 22 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/data_logger_esp32c3.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 37, 4 | "active_layer_preset": "", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 0, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 1.0, 13 | "tracks": 1.0, 14 | "vias": 1.0, 15 | "zones": 0.6 16 | }, 17 | "ratsnest_display_mode": 0, 18 | "selection_filter": { 19 | "dimensions": true, 20 | "footprints": true, 21 | "graphics": true, 22 | "keepouts": true, 23 | "lockedItems": true, 24 | "otherItems": true, 25 | "pads": true, 26 | "text": true, 27 | "tracks": true, 28 | "vias": true, 29 | "zones": true 30 | }, 31 | "visible_items": [ 32 | 0, 33 | 1, 34 | 2, 35 | 3, 36 | 4, 37 | 5, 38 | 8, 39 | 9, 40 | 10, 41 | 11, 42 | 12, 43 | 13, 44 | 14, 45 | 15, 46 | 16, 47 | 17, 48 | 18, 49 | 19, 50 | 20, 51 | 21, 52 | 22, 53 | 23, 54 | 24, 55 | 25, 56 | 26, 57 | 27, 58 | 28, 59 | 29, 60 | 30, 61 | 32, 62 | 33, 63 | 34, 64 | 35, 65 | 36 66 | ], 67 | "visible_layers": "ffdffff_ffffffff", 68 | "zone_display_mode": 0 69 | }, 70 | "meta": { 71 | "filename": "data_logger_esp32c3.kicad_prl", 72 | "version": 3 73 | }, 74 | "project": { 75 | "files": [] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/fp-info-cache: -------------------------------------------------------------------------------- 1 | 16774613692154 2 | 1_project_footprints 3 | 8-WDFN Exposed Pad 4 | 5 | 6 | 0 7 | 9 8 | 9 9 | 1_project_footprints 10 | 472192001 11 | 12 | 13 | 0 14 | 12 15 | 12 16 | 1_project_footprints 17 | B0530WS_SE 18 | 19 | 20 | 0 21 | 2 22 | 2 23 | 1_project_footprints 24 | DFN1610 25 | 26 | 27 | 0 28 | 2 29 | 2 30 | 1_project_footprints 31 | LM321MF 32 | 33 | 34 | 0 35 | 5 36 | 5 37 | 1_project_footprints 38 | QFN-28-EP(4x4) 39 | 40 | 41 | 0 42 | 29 43 | 29 44 | 1_project_footprints 45 | SOT-23 46 | 47 | 48 | 0 49 | 3 50 | 3 51 | 1_project_footprints 52 | SOT-223-4 53 | 54 | 55 | 0 56 | 4 57 | 4 58 | 1_project_footprints 59 | USB-TYPE-C-018 60 | 61 | 62 | 0 63 | 20 64 | 20 65 | 1_project_footprints 66 | WS2812B-2020 67 | 68 | 69 | 0 70 | 4 71 | 4 72 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name "1_project_footprints")(type "KiCad")(uri "${KIPRJMOD}/../kicad_libraries/remote_data_logger.pretty")(options "")(descr "")) 3 | (lib (name "1_espressif")(type "KiCad")(uri "${KIPRJMOD}/../../submodules/kicad-libraries/footprints/Espressif.pretty")(options "")(descr "")) 4 | ) 5 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/data_logger_esp32c3/gerbers.zip -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Mask.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,6.0.10-1.fc37*% 2 | %TF.CreationDate,2023-01-09T06:29:55-08:00*% 3 | %TF.ProjectId,data_logger_esp32c3,64617461-5f6c-46f6-9767-65725f657370,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Soldermask,Bot*% 6 | %TF.FilePolarity,Negative*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.10-1.fc37) date 2023-01-09 06:29:55* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %TA.AperFunction,Profile*% 15 | %ADD10C,0.100000*% 16 | %TD*% 17 | %ADD11R,1.000000X1.000000*% 18 | %ADD12C,0.750011*% 19 | %ADD13O,1.999996X1.199998*% 20 | %ADD14O,1.799996X1.199998*% 21 | G04 APERTURE END LIST* 22 | D10* 23 | X98856800Y-49606200D02* 24 | X142138400Y-49606200D01* 25 | X142138400Y-49606200D02* 26 | X142138400Y-81864200D01* 27 | X142138400Y-81864200D02* 28 | X98856800Y-81864200D01* 29 | X98856800Y-81864200D02* 30 | X98856800Y-49606200D01* 31 | D11* 32 | %TO.C,IO13*% 33 | X111157656Y-77292200D03* 34 | %TD*% 35 | %TO.C,DC-1*% 36 | X140157200Y-79502000D03* 37 | %TD*% 38 | %TO.C,DC+1*% 39 | X137820400Y-79502000D03* 40 | %TD*% 41 | %TO.C,IO11*% 42 | X106963028Y-77292200D03* 43 | %TD*% 44 | %TO.C,IO5*% 45 | X111157656Y-80391000D03* 46 | %TD*% 47 | %TO.C,VIN1*% 48 | X130175000Y-80518000D03* 49 | %TD*% 50 | %TO.C,IO15*% 51 | X115352286Y-77292200D03* 52 | %TD*% 53 | %TO.C,A2N1*% 54 | X101473000Y-50850800D03* 55 | %TD*% 56 | %TO.C,A3N1*% 57 | X100812600Y-56642000D03* 58 | %TD*% 59 | %TO.C,SDA1*% 60 | X119890000Y-79781400D03* 61 | %TD*% 62 | %TO.C,TX0*% 63 | X124739400Y-51587400D03* 64 | %TD*% 65 | %TO.C,IO0*% 66 | X100671086Y-80391000D03* 67 | %TD*% 68 | %TO.C,IO1*% 69 | X102768400Y-80391000D03* 70 | %TD*% 71 | %TO.C,A0N1*% 72 | X100812600Y-62306200D03* 73 | %TD*% 74 | %TO.C,3V3*% 75 | X127914400Y-80467200D03* 76 | %TD*% 77 | %TO.C,IO6*% 78 | X113254970Y-80391000D03* 79 | %TD*% 80 | %TO.C,IO3*% 81 | X106963028Y-80391000D03* 82 | %TD*% 83 | %TO.C,A3P1*% 84 | X100863400Y-54483000D03* 85 | %TD*% 86 | %TO.C,A4P1*% 87 | X100787200Y-65074800D03* 88 | %TD*% 89 | %TO.C,RX0*% 90 | X124739400Y-54533800D03* 91 | %TD*% 92 | %TO.C,A4N1*% 93 | X100812600Y-67792600D03* 94 | %TD*% 95 | %TO.C,IO10*% 96 | X104865714Y-77292200D03* 97 | %TD*% 98 | D12* 99 | %TO.C,USB-C1*% 100 | X135461756Y-72902318D03* 101 | X135461756Y-67102482D03* 102 | D13* 103 | X134961630Y-74327512D03* 104 | X134961630Y-65677288D03* 105 | D14* 106 | X139161520Y-65677288D03* 107 | X139161520Y-74327512D03* 108 | %TD*% 109 | D11* 110 | %TO.C,I2SN1*% 111 | X100914200Y-73533000D03* 112 | %TD*% 113 | %TO.C,I2SP1*% 114 | X100838000Y-70688200D03* 115 | %TD*% 116 | %TO.C,NRESET1*% 117 | X119659400Y-75488800D03* 118 | %TD*% 119 | %TO.C,SCL1*% 120 | X117652800Y-79730600D03* 121 | %TD*% 122 | %TO.C,IO9*% 123 | X102768400Y-77292200D03* 124 | %TD*% 125 | %TO.C,A0P1*% 126 | X100838000Y-59537600D03* 127 | %TD*% 128 | %TO.C,IO8*% 129 | X100671086Y-77292200D03* 130 | %TD*% 131 | %TO.C,IO2*% 132 | X104865714Y-80391000D03* 133 | %TD*% 134 | %TO.C,IO4*% 135 | X109060342Y-80391000D03* 136 | %TD*% 137 | %TO.C,A2P1*% 138 | X103606600Y-50850800D03* 139 | %TD*% 140 | %TO.C,IO14*% 141 | X113254970Y-77292200D03* 142 | %TD*% 143 | %TO.C,NINT1*% 144 | X117449600Y-75514200D03* 145 | %TD*% 146 | %TO.C,IO7*% 147 | X115352286Y-80391000D03* 148 | %TD*% 149 | %TO.C,IO12*% 150 | X109060342Y-77292200D03* 151 | %TD*% 152 | M02* 153 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Paste.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,6.0.10-1.fc37*% 2 | %TF.CreationDate,2023-01-09T06:29:55-08:00*% 3 | %TF.ProjectId,data_logger_esp32c3,64617461-5f6c-46f6-9767-65725f657370,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Paste,Bot*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.10-1.fc37) date 2023-01-09 06:29:55* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %TA.AperFunction,Profile*% 15 | %ADD10C,0.100000*% 16 | %TD*% 17 | G04 APERTURE END LIST* 18 | D10* 19 | X98856800Y-49606200D02* 20 | X142138400Y-49606200D01* 21 | X142138400Y-49606200D02* 22 | X142138400Y-81864200D01* 23 | X142138400Y-81864200D02* 24 | X98856800Y-81864200D01* 25 | X98856800Y-81864200D02* 26 | X98856800Y-49606200D01* 27 | M02* 28 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Silkscreen.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,6.0.10-1.fc37*% 2 | %TF.CreationDate,2023-01-09T06:29:55-08:00*% 3 | %TF.ProjectId,data_logger_esp32c3,64617461-5f6c-46f6-9767-65725f657370,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Legend,Bot*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 6.0.10-1.fc37) date 2023-01-09 06:29:55* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | %TA.AperFunction,Profile*% 15 | %ADD10C,0.100000*% 16 | %TD*% 17 | G04 APERTURE END LIST* 18 | D10* 19 | X98856800Y-49606200D02* 20 | X142138400Y-49606200D01* 21 | X142138400Y-49606200D02* 22 | X142138400Y-81864200D01* 23 | X142138400Y-81864200D02* 24 | X98856800Y-81864200D01* 25 | X98856800Y-81864200D02* 26 | X98856800Y-49606200D01* 27 | M02* 28 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,6.0.10-1.fc37*% 2 | %TF.CreationDate,2023-01-09T06:29:55-08:00*% 3 | %TF.ProjectId,data_logger_esp32c3,64617461-5f6c-46f6-9767-65725f657370,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW 6.0.10-1.fc37) date 2023-01-09 06:29:55* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X98856800Y-49606200D02* 19 | X142138400Y-49606200D01* 20 | X142138400Y-49606200D02* 21 | X142138400Y-81864200D01* 22 | X142138400Y-81864200D02* 23 | X98856800Y-81864200D01* 24 | X98856800Y-81864200D02* 25 | X98856800Y-49606200D01* 26 | M02* 27 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-NPTH.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad 6.0.10-1.fc37} date Mon 09 Jan 2023 06:29:53 AM PST 3 | ; FORMAT={-:-/ absolute / inch / decimal} 4 | ; #@! TF.CreationDate,2023-01-09T06:29:53-08:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,6.0.10-1.fc37 6 | ; #@! TF.FileFunction,NonPlated,1,4,NPTH 7 | FMAT,2 8 | INCH 9 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 10 | T1C0.0295 11 | % 12 | G90 13 | G05 14 | T1 15 | X5.3331Y-2.6418 16 | X5.3331Y-2.8702 17 | T0 18 | M30 19 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-PTH.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad 6.0.10-1.fc37} date Mon 09 Jan 2023 06:29:53 AM PST 3 | ; FORMAT={-:-/ absolute / inch / decimal} 4 | ; #@! TF.CreationDate,2023-01-09T06:29:53-08:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,6.0.10-1.fc37 6 | ; #@! TF.FileFunction,Plated,1,4,PTH 7 | FMAT,2 8 | INCH 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.0079 11 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 12 | T2C0.0157 13 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 14 | T3C0.0197 15 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 16 | T4C0.0197 17 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 18 | T5C0.0315 19 | % 20 | G90 21 | G05 22 | T1 23 | X4.111Y-2.677 24 | X4.132Y-2.196 25 | X4.134Y-2.29 26 | X4.188Y-2.116 27 | X4.206Y-2.69 28 | X4.24Y-2.631 29 | X4.248Y-2.416 30 | X4.248Y-2.571 31 | X4.248Y-2.815 32 | X4.269Y-2.821 33 | X4.291Y-2.823 34 | X4.299Y-2.597 35 | X4.3Y-2.146 36 | X4.3Y-2.741 37 | X4.335Y-2.875 38 | X4.363Y-2.885 39 | X4.386Y-2.885 40 | X4.394Y-2.363 41 | X4.397Y-2.655 42 | X4.404Y-2.558 43 | X4.437Y-2.555 44 | X4.465Y-2.666 45 | X4.529Y-2.56 46 | X4.548Y-2.631 47 | X4.573Y-2.764 48 | X4.593Y-2.656 49 | X4.61Y-3.048 50 | X4.647Y-2.88 51 | X4.656Y-2.556 52 | X4.689Y-2.554 53 | X4.697Y-3.048 54 | X4.72Y-2.557 55 | X4.733Y-2.881 56 | X4.749Y-2.554 57 | X4.935Y-2.43 58 | X4.943Y-2.292 59 | X4.947Y-2.223 60 | X4.948Y-2.885 61 | X4.967Y-2.465 62 | X4.995Y-2.972 63 | X5.007Y-2.661 64 | X5.039Y-2.28 65 | X5.062Y-2.85 66 | X5.08Y-2.241 67 | X5.093Y-2.366 68 | X5.093Y-2.404 69 | X5.094Y-2.324 70 | T2 71 | X4.041Y-2.714 72 | X4.061Y-2.318 73 | X4.096Y-2.111 74 | X4.121Y-2.487 75 | X4.209Y-2.026 76 | X4.28Y-2.308 77 | X4.295Y-2.529 78 | X4.383Y-2.797 79 | X4.384Y-2.745 80 | X4.436Y-2.746 81 | X4.439Y-2.798 82 | X4.867Y-3.092 83 | X4.905Y-2.986 84 | X4.935Y-3.093 85 | T3 86 | X5.369Y-2.246 87 | T4 88 | X3.9634Y-3.043 89 | X3.9634Y-3.165 90 | X3.968Y-2.562 91 | X3.969Y-2.23 92 | X3.969Y-2.453 93 | X3.969Y-2.669 94 | X3.97Y-2.344 95 | X3.97Y-2.783 96 | X3.971Y-2.145 97 | X3.973Y-2.895 98 | X3.995Y-2.002 99 | X4.046Y-3.043 100 | X4.046Y-3.165 101 | X4.079Y-2.002 102 | X4.1286Y-3.043 103 | X4.1286Y-3.165 104 | X4.2111Y-3.043 105 | X4.2111Y-3.165 106 | X4.2937Y-3.043 107 | X4.2937Y-3.165 108 | X4.3763Y-3.043 109 | X4.3763Y-3.165 110 | X4.4589Y-3.043 111 | X4.4589Y-3.165 112 | X4.5414Y-3.043 113 | X4.5414Y-3.165 114 | X4.624Y-2.973 115 | X4.632Y-3.139 116 | X4.711Y-2.972 117 | X4.7201Y-3.141 118 | X4.911Y-2.031 119 | X4.911Y-2.147 120 | X5.036Y-3.168 121 | X5.125Y-3.17 122 | X5.426Y-3.13 123 | X5.518Y-3.13 124 | T5 125 | G00X5.2977Y-2.5857 126 | M15 127 | G01X5.3292Y-2.5857 128 | M16 129 | G05 130 | G00X5.2977Y-2.9263 131 | M15 132 | G01X5.3292Y-2.9263 133 | M16 134 | G05 135 | G00X5.467Y-2.5857 136 | M15 137 | G01X5.4906Y-2.5857 138 | M16 139 | G05 140 | G00X5.467Y-2.9263 141 | M15 142 | G01X5.4906Y-2.9263 143 | M16 144 | G05 145 | T0 146 | M30 147 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-all-pos.csv: -------------------------------------------------------------------------------- 1 | Designator,Val,Package,Mid X,Mid Y,Rotation,Layer 2 | C1,1uF,C_0402_1005Metric,9.1694,19.05,-90,top 3 | C2,10uF,C_0603_1608Metric,9.017,25.0952,90,top 4 | C3,0.1uF,C_0402_1005Metric,10.3632,24.5618,90,top 5 | C4,10uF,C_0603_1608Metric,26.6954,12.7,90,top 6 | C5,10uF,C_0603_1608Metric,30.1498,7.0358,90,top 7 | C6,0.1uF,C_0402_1005Metric,16.637,11.2014,-90,top 8 | C7,0.1uF,C_0402_1005Metric,9.652,11.5824,90,top 9 | D1,LTVS16H5.0T5G,DFN1610,40.067458,9.4488,0,top 10 | R1,10k,R_0402_1005Metric,27.559,24.9174,90,top 11 | R2,5.1k,R_0402_1005Metric,33.0454,10.8458,-90,top 12 | R3,10k,R_0402_1005Metric,27.5844,26.9494,-90,top 13 | R4,10k,R_0402_1005Metric,10.3632,19.05,90,top 14 | R5,1k,R_0402_1005Metric,3.7084,25.2476,-90,top 15 | R6,1k,R_0402_1005Metric,4.5212,15.4432,-90,top 16 | R7,5.1k,R_0402_1005Metric,33.8836,15.5194,-90,top 17 | R8,4.7k,R_0402_1005Metric,18.7452,3.8354,180,top 18 | R9,10k,R_0402_1005Metric,28.1432,12.192,-90,top 19 | R10,1.6k,R_0402_1005Metric,6.5786,30.988,-90,top 20 | R11,3.92k,R_0402_1005Metric,3.683,27.2796,-90,top 21 | R12,7.5k,R_0402_1005Metric,4.5212,17.5006,-90,top 22 | R13,1k,R_0402_1005Metric,6.5786,28.956,-90,top 23 | R14,10k,R_0402_1005Metric,20.8534,7.9756,0,top 24 | R15,10k,R_0402_1005Metric,18.669,7.9502,0,top 25 | R16,4.7k,R_0402_1005Metric,20.9804,3.7846,180,top 26 | R17,30.1,R_0402_1005Metric,25.7302,18.5928,0,top 27 | R18,30.1,R_0402_1005Metric,25.7556,17.5006,0,top 28 | SD1,472192001,472192001,35.2552,12.472206,180,top 29 | U1,ESP32-C3-MINI-1,ESP32-C3-MINI-1,17.8054,23.6728,0,top 30 | U2,AZ1117IH-3.3TRG1,SOT-223-4,25.7302,-1.777994,180,top 31 | U4,LM321MF,LM321MF,6.146813,26.695056,0,top 32 | U5,LM321MF,LM321MF,9.017013,35.407256,0,top 33 | U6,LM321MF,LM321MF,6.096013,31.063856,0,top 34 | U7,LM321MF,LM321MF,6.807213,21.564256,0,top 35 | U8,LM321MF,LM321MF,5.562613,16.966856,0,top 36 | U9,A03401A,SOT-23,33.147,-0.654234,180,top 37 | U10,A03401A,SOT-23,35.833234,11.811,-90,top 38 | U11,SX1509BIULTRT,QFN-28-EP(4x4),18.01923,11.43,-90,top 39 | USB-C1,USB-TYPE-C-018,USB-TYPE-C-018,30.2006,11.8618,90,top 40 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/gerbers/data_logger_esp32c3-job.gbrjob: -------------------------------------------------------------------------------- 1 | { 2 | "Header": { 3 | "GenerationSoftware": { 4 | "Vendor": "KiCad", 5 | "Application": "Pcbnew", 6 | "Version": "6.0.10-1.fc37" 7 | }, 8 | "CreationDate": "2023-01-09T06:29:55-08:00" 9 | }, 10 | "GeneralSpecs": { 11 | "ProjectId": { 12 | "Name": "data_logger_esp32c3", 13 | "GUID": "64617461-5f6c-46f6-9767-65725f657370", 14 | "Revision": "rev?" 15 | }, 16 | "Size": { 17 | "X": 43.3816, 18 | "Y": 32.358 19 | }, 20 | "LayerNumber": 4, 21 | "BoardThickness": 4.69, 22 | "Finish": "None" 23 | }, 24 | "DesignRules": [ 25 | { 26 | "Layers": "Outer", 27 | "PadToPad": 0.1, 28 | "PadToTrack": 0.1, 29 | "TrackToTrack": 0.1, 30 | "MinLineWidth": 0.127, 31 | "TrackToRegion": 0.508, 32 | "RegionToRegion": 0.508 33 | }, 34 | { 35 | "Layers": "Inner", 36 | "PadToPad": 0.1, 37 | "PadToTrack": 0.1, 38 | "TrackToTrack": 0.1, 39 | "TrackToRegion": 0.508, 40 | "RegionToRegion": 0.508 41 | } 42 | ], 43 | "FilesAttributes": [ 44 | { 45 | "Path": "data_logger_esp32c3-F_Cu.gbr", 46 | "FileFunction": "Copper,L1,Top", 47 | "FilePolarity": "Positive" 48 | }, 49 | { 50 | "Path": "data_logger_esp32c3-In1_Cu.gbr", 51 | "FileFunction": "Copper,L2,Inr", 52 | "FilePolarity": "Positive" 53 | }, 54 | { 55 | "Path": "data_logger_esp32c3-In2_Cu.gbr", 56 | "FileFunction": "Copper,L3,Inr", 57 | "FilePolarity": "Positive" 58 | }, 59 | { 60 | "Path": "data_logger_esp32c3-B_Cu.gbr", 61 | "FileFunction": "Copper,L4,Bot", 62 | "FilePolarity": "Positive" 63 | }, 64 | { 65 | "Path": "data_logger_esp32c3-F_Paste.gbr", 66 | "FileFunction": "SolderPaste,Top", 67 | "FilePolarity": "Positive" 68 | }, 69 | { 70 | "Path": "data_logger_esp32c3-B_Paste.gbr", 71 | "FileFunction": "SolderPaste,Bot", 72 | "FilePolarity": "Positive" 73 | }, 74 | { 75 | "Path": "data_logger_esp32c3-F_Silkscreen.gbr", 76 | "FileFunction": "Legend,Top", 77 | "FilePolarity": "Positive" 78 | }, 79 | { 80 | "Path": "data_logger_esp32c3-B_Silkscreen.gbr", 81 | "FileFunction": "Legend,Bot", 82 | "FilePolarity": "Positive" 83 | }, 84 | { 85 | "Path": "data_logger_esp32c3-F_Mask.gbr", 86 | "FileFunction": "SolderMask,Top", 87 | "FilePolarity": "Negative" 88 | }, 89 | { 90 | "Path": "data_logger_esp32c3-B_Mask.gbr", 91 | "FileFunction": "SolderMask,Bot", 92 | "FilePolarity": "Negative" 93 | }, 94 | { 95 | "Path": "data_logger_esp32c3-Edge_Cuts.gbr", 96 | "FileFunction": "Profile", 97 | "FilePolarity": "Positive" 98 | } 99 | ], 100 | "MaterialStackup": [ 101 | { 102 | "Type": "Legend", 103 | "Name": "Top Silk Screen" 104 | }, 105 | { 106 | "Type": "SolderPaste", 107 | "Name": "Top Solder Paste" 108 | }, 109 | { 110 | "Type": "SolderMask", 111 | "Thickness": 0.01, 112 | "Name": "Top Solder Mask" 113 | }, 114 | { 115 | "Type": "Copper", 116 | "Thickness": 0.035, 117 | "Name": "F.Cu" 118 | }, 119 | { 120 | "Type": "Dielectric", 121 | "Thickness": 1.51, 122 | "Material": "FR4", 123 | "Name": "F.Cu/In1.Cu", 124 | "Notes": "Type: dielectric layer 1 (from F.Cu to In1.Cu)" 125 | }, 126 | { 127 | "Type": "Copper", 128 | "Thickness": 0.035, 129 | "Name": "In1.Cu" 130 | }, 131 | { 132 | "Type": "Dielectric", 133 | "Thickness": 1.51, 134 | "Material": "FR4", 135 | "Name": "In1.Cu/In2.Cu", 136 | "Notes": "Type: dielectric layer 2 (from In1.Cu to In2.Cu)" 137 | }, 138 | { 139 | "Type": "Copper", 140 | "Thickness": 0.035, 141 | "Name": "In2.Cu" 142 | }, 143 | { 144 | "Type": "Dielectric", 145 | "Thickness": 1.51, 146 | "Material": "FR4", 147 | "Name": "In2.Cu/B.Cu", 148 | "Notes": "Type: dielectric layer 3 (from In2.Cu to B.Cu)" 149 | }, 150 | { 151 | "Type": "Copper", 152 | "Thickness": 0.035, 153 | "Name": "B.Cu" 154 | }, 155 | { 156 | "Type": "SolderMask", 157 | "Thickness": 0.01, 158 | "Name": "Bottom Solder Mask" 159 | }, 160 | { 161 | "Type": "SolderPaste", 162 | "Name": "Bottom Solder Paste" 163 | }, 164 | { 165 | "Type": "Legend", 166 | "Name": "Bottom Silk Screen" 167 | } 168 | ] 169 | } 170 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/report.txt: -------------------------------------------------------------------------------- 1 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-F_Cu.gbr'. 2 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-In1_Cu.gbr'. 3 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-In2_Cu.gbr'. 4 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Cu.gbr'. 5 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-F_Paste.gbr'. 6 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Paste.gbr'. 7 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-F_Silkscreen.gbr'. 8 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Silkscreen.gbr'. 9 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-F_Mask.gbr'. 10 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-B_Mask.gbr'. 11 | Plotted to '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-Edge_Cuts.gbr'. 12 | Created Gerber job file '/home/shane/Desktop/remote_data_logger/hardware/data_logger_esp32c3/gerbers/data_logger_esp32c3-job.gbrjob'. 13 | Info: Done. 14 | -------------------------------------------------------------------------------- /Data-Logger-PCB/data_logger_esp32c3/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name "1_project_specific")(type "KiCad")(uri "${KIPRJMOD}/../kicad_libraries/remote_data_logger.kicad_sym")(options "")(descr "")) 3 | (lib (name "1_espressif")(type "KiCad")(uri "${KIPRJMOD}/../../submodules/kicad-libraries/libraries/Espressif.kicad_sym")(options "")(descr "")) 4 | ) 5 | -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/datasheets/1811062123_Diodes-Incorporated-AZ1117IH-3-3TRG1_C108495.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/datasheets/1811062123_Diodes-Incorporated-AZ1117IH-3-3TRG1_C108495.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/datasheets/ESP32-C3-DevKit-Lipo_Rev_B.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/datasheets/ESP32-C3-DevKit-Lipo_Rev_B.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/datasheets/esp32-c3-mini-1_datasheet_en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/datasheets/esp32-c3-mini-1_datasheet_en.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/datasheets/mc33063a.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/datasheets/mc33063a.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/esp32-c3_hardware_design_guidelines_en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/esp32-c3_hardware_design_guidelines_en.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/examples/ESP32-C3-DevKit-Lipo_Rev_B (1).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/examples/ESP32-C3-DevKit-Lipo_Rev_B (1).pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/examples/ESP32-C3-DevKit-Lipo_Rev_B.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/examples/ESP32-C3-DevKit-Lipo_Rev_B.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/docs/examples/SCH_ESP32-C3-DEVKITM-1_V1_Schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/Data-Logger-PCB/docs/examples/SCH_ESP32-C3-DEVKITM-1_V1_Schematic.pdf -------------------------------------------------------------------------------- /Data-Logger-PCB/kicad_libraries/remote_data_logger.pretty/8-WDFN Exposed Pad.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "8-WDFN Exposed Pad" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 638D0DDF) 4 | (attr through_hole) 5 | (fp_text reference "REF**" (at 0.675 -3.135) (layer "F.SilkS") hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp a595a79b-2710-4873-9cec-eb7b10609ee6) 8 | ) 9 | (fp_text value "8-WDFN Exposed Pad" (at 9.565 3.135) (layer "F.Fab") hide 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 4430d73d-c12e-450a-b00c-4bf030ff553c) 12 | ) 13 | (fp_poly (pts 14 | (xy -0.625 -0.95) 15 | (xy 0.625 -0.95) 16 | (xy 0.625 0.95) 17 | (xy -0.625 0.95) 18 | ) (layer "F.Paste") (width 0.01) (fill solid) (tstamp 4ea0017f-5d83-4fe2-8385-84dd4102b2fa)) 19 | (fp_line (start -2 2) (end 2 2) (layer "F.SilkS") (width 0.127) (tstamp 6e768bc4-8b8c-4b12-a554-40695aea432f)) 20 | (fp_line (start -2 -2) (end 2 -2) (layer "F.SilkS") (width 0.127) (tstamp 8b176ae5-7e00-4ea0-8fc9-7326b6c8b4aa)) 21 | (fp_circle (center -3 -1.2) (end -2.9 -1.2) (layer "F.SilkS") (width 0.2) (fill none) (tstamp d4874891-513e-4edf-b073-3fe26b0c6b2f)) 22 | (fp_line (start -2.75 2.25) (end 2.75 2.25) (layer "F.CrtYd") (width 0.05) (tstamp 42312dfd-879a-4c70-bfe0-7442cbfac792)) 23 | (fp_line (start -2.75 -2.25) (end -2.75 2.25) (layer "F.CrtYd") (width 0.05) (tstamp 66a23264-1a0f-4ae0-be2d-11ef871d8a28)) 24 | (fp_line (start -2.75 -2.25) (end 2.75 -2.25) (layer "F.CrtYd") (width 0.05) (tstamp 8453f9e8-f69b-4532-89a4-26c9f9523ac0)) 25 | (fp_line (start 2.75 -2.25) (end 2.75 2.25) (layer "F.CrtYd") (width 0.05) (tstamp e9cbb770-ec0b-4e80-b337-9ca827551707)) 26 | (fp_line (start 2 -2) (end 2 2) (layer "F.Fab") (width 0.127) (tstamp 2ee2cb2d-6c84-42f2-b6b3-bd1d2f688292)) 27 | (fp_line (start -2 2) (end 2 2) (layer "F.Fab") (width 0.127) (tstamp 544a3a9a-8675-44c5-af71-f1ea243c2f10)) 28 | (fp_line (start -2 -2) (end 2 -2) (layer "F.Fab") (width 0.127) (tstamp efa181d4-8886-4033-a9f9-7ededa341858)) 29 | (fp_line (start -2 -2) (end -2 2) (layer "F.Fab") (width 0.127) (tstamp f943f9ce-eb71-4f64-8fce-3fdf349fa461)) 30 | (fp_circle (center -3 -1.2) (end -2.9 -1.2) (layer "F.Fab") (width 0.2) (fill none) (tstamp 03996727-c67b-44f4-a103-b97b6bd17abd)) 31 | (pad "1" smd roundrect (at -1.935 -1.2) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp 84a17d95-7f09-42f4-9708-fc101783a2f9)) 32 | (pad "2" smd roundrect (at -1.935 -0.4) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp 3210a190-45f8-46df-a4e4-f86ad6c7bcad)) 33 | (pad "3" smd roundrect (at -1.935 0.4) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp 522a4ec8-5ce9-40ff-9866-dcff8870060a)) 34 | (pad "4" smd roundrect (at -1.935 1.2) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp 38335251-aa25-48d6-804b-ef1f776c3b72)) 35 | (pad "5" smd roundrect (at 1.935 1.2 180) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp f52dad47-5ba4-4f2e-b62c-57bbe08e4cd5)) 36 | (pad "6" smd roundrect (at 1.935 0.4 180) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp 7c1b5f95-fbdc-4a3c-9cd3-c881796d87a9)) 37 | (pad "7" smd roundrect (at 1.935 -0.4 180) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp dd4e7be3-d8d6-46b1-8c6a-1c74dbf81f3b)) 38 | (pad "8" smd roundrect (at 1.935 -1.2 180) (size 0.86 0.32) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.04) (tstamp 9f272093-3ed9-492f-8bcd-450991c3c88f)) 39 | (pad "9" smd rect (at 0 0) (size 1.98 3) (layers "F.Cu" "F.Mask") (tstamp 3c66e162-c378-45b7-a9f8-6a6eadd94ce2)) 40 | ) 41 | -------------------------------------------------------------------------------- /Data-Logger-PCB/kicad_libraries/remote_data_logger.pretty/B0530WS_SE.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "B0530WS_SE" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr smd) 5 | (fp_text reference "REF**" (at 0 -0.5 unlocked) (layer "F.SilkS") hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 08e61d28-824f-4308-8457-2143a58bee94) 8 | ) 9 | (fp_text value "B0530WS_SE" (at 0 1 unlocked) (layer "F.Fab") hide 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp da3a8a96-4451-4980-8dbd-3346e2b3df96) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0 2.5 unlocked) (layer "F.Fab") hide 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp e2a3cfa5-5bdf-47a3-90b4-a6b21a68a1e2) 16 | ) 17 | (fp_line (start -3.391205 4.353789) (end -1.638757 4.353789) (layer "F.SilkS") (width 0.1524) (tstamp 086db3f3-4361-4de3-a478-5320dff3b7fe)) 18 | (fp_line (start -3.391205 5.806211) (end -1.638757 5.806211) (layer "F.SilkS") (width 0.1524) (tstamp 12b1d69a-c6b6-42e9-9b56-acb497624295)) 19 | (fp_line (start -2.986761 4.353789) (end -2.986761 5.806211) (layer "F.SilkS") (width 0.1524) (tstamp 61d3753d-027d-4b5e-8d3c-c9dac2451915)) 20 | (fp_line (start -1.638757 5.806211) (end -1.638757 5.599989) (layer "F.SilkS") (width 0.151994) (tstamp 9df2d623-d5a6-4665-9c9a-50ac2672d5ef)) 21 | (fp_line (start -1.638757 4.353789) (end -1.638757 4.550004) (layer "F.SilkS") (width 0.151994) (tstamp 9e30f104-5845-407a-b138-1f4413d9902b)) 22 | (fp_poly (pts 23 | (xy -3.314979 5.882411) 24 | (xy -3.314979 5.530012) 25 | (xy -3.619779 5.530012) 26 | (xy -3.619779 5.882411) 27 | ) (layer "F.SilkS") (width 0) (fill solid) (tstamp 4ca3c319-29de-4501-8b1f-fc8d85f97dc4)) 28 | (fp_poly (pts 29 | (xy -3.314979 4.277589) 30 | (xy -3.314979 4.629988) 31 | (xy -3.619779 4.629988) 32 | (xy -3.619779 4.277589) 33 | ) (layer "F.SilkS") (width 0) (fill solid) (tstamp 92002a92-5963-4446-9184-ef6f9e0c1fc9)) 34 | (fp_poly (pts 35 | (xy -3.764966 5.009998) 36 | (xy -3.764966 5.166004) 37 | (xy -3.140964 5.166004) 38 | (xy -3.140964 5.009998) 39 | ) (layer "Cmts.User") (width 0) (fill solid) (tstamp 8150571e-d497-427f-a751-91eacbeb0a70)) 40 | (fp_poly (pts 41 | (xy -1.224991 4.990008) 42 | (xy -1.224991 5.146015) 43 | (xy -1.848993 5.146015) 44 | (xy -1.848993 4.990008) 45 | ) (layer "Cmts.User") (width 0) (fill solid) (tstamp 8dc7483b-2780-4cf0-883b-8f1a4f917c4b)) 46 | (fp_poly (pts 47 | (xy -1.456969 4.550004) 48 | (xy -1.456969 5.589981) 49 | (xy -1.612976 5.589981) 50 | (xy -1.612976 4.550004) 51 | ) (layer "Cmts.User") (width 0) (fill solid) (tstamp f7028ead-e17b-4e79-bc3d-731d45f99c94)) 52 | (fp_poly (pts 53 | (xy -1.66497 4.430014) 54 | (xy -1.66497 5.730011) 55 | (xy -3.364967 5.730011) 56 | (xy -3.364967 4.430014) 57 | ) (layer "F.CrtYd") (width 0.508) (fill none) (tstamp acaaa899-b058-47cf-b975-f967709f7e88)) 58 | (pad "1" smd rect (at -3.712591 5.08) (size 0.999998 0.750011) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 17f3c329-7bcf-4285-b25f-322744f5e662)) 59 | (pad "2" smd rect (at -1.367409 5.08) (size 0.999998 0.750011) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 36a36d04-aff4-45d2-b604-c95870b30d4c)) 60 | ) 61 | -------------------------------------------------------------------------------- /Data-Logger-PCB/kicad_libraries/remote_data_logger.pretty/DFN1610.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "DFN1610" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr smd) 5 | (fp_text reference "REF**" (at 0 -0.5 unlocked) (layer "F.SilkS") hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 0536ea8c-1ece-4777-8ee6-377fbdf829ee) 8 | ) 9 | (fp_text value "DFN1610" (at 0 1 unlocked) (layer "F.Fab") hide 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp e8392197-a596-48ea-b3e9-9f172db7bfa3) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0 2.5 unlocked) (layer "F.Fab") hide 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 194d04ec-05cf-41e0-82b5-44107f226f88) 16 | ) 17 | (fp_line (start -1.025016 4.380001) (end -1.025016 5.779999) (layer "F.SilkS") (width 0.1778) (tstamp 1720ee8c-3208-4761-8fab-cfb1bdcbaae0)) 18 | (fp_line (start -1.275003 5.779999) (end 1.275004 5.779999) (layer "F.SilkS") (width 0.1778) (tstamp 2f8ef023-328c-42f9-b34d-8b472cb3f073)) 19 | (fp_line (start 1.275004 4.380001) (end 1.275004 5.779999) (layer "F.SilkS") (width 0.1778) (tstamp 4a9c2061-1c41-4398-9f26-5a4e6e8db0f1)) 20 | (fp_line (start -1.275003 4.380001) (end -1.275003 5.779999) (layer "F.SilkS") (width 0.1778) (tstamp 7845ce8d-10d8-42a2-9ea3-c289aed9df04)) 21 | (fp_line (start -1.275003 4.380001) (end 1.275004 4.380001) (layer "F.SilkS") (width 0.1778) (tstamp caa18a94-0642-421e-ad3f-164ec49c65fd)) 22 | (fp_poly (pts 23 | (xy 0.599999 5.28) 24 | (xy 0.599999 4.780001) 25 | (xy 0.699999 4.780001) 26 | (xy 0.699999 5.28) 27 | ) (layer "Cmts.User") (width 0) (fill solid) (tstamp 6b5643ca-f6f5-47f2-9ea7-4b88feb4ddf1)) 28 | (fp_poly (pts 29 | (xy 0.399898 4.98) 30 | (xy 0.899897 4.98) 31 | (xy 0.899897 5.08) 32 | (xy 0.399898 5.08) 33 | ) (layer "Cmts.User") (width 0) (fill solid) (tstamp 8b8a5efb-a49d-4a9e-a571-780f5b44e6d9)) 34 | (fp_poly (pts 35 | (xy -0.799998 4.98) 36 | (xy -0.299999 4.98) 37 | (xy -0.299999 5.08) 38 | (xy -0.799998 5.08) 39 | ) (layer "Cmts.User") (width 0) (fill solid) (tstamp ec8fab92-7491-4a48-b552-18e64358776d)) 40 | (fp_poly (pts 41 | (xy -0.799998 4.580001) 42 | (xy 0.799998 4.580001) 43 | (xy 0.799998 5.579999) 44 | (xy -0.799998 5.579999) 45 | ) (layer "F.CrtYd") (width 0.508) (fill none) (tstamp 53b34f26-1d6b-492c-ad3c-41b4f3e61ec1)) 46 | (pad "1" smd rect (at -0.474954 5.08 90) (size 0.999998 0.699999) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 3c793bc0-81dc-4d07-b077-7add548d5a23)) 47 | (pad "2" smd rect (at 0.724942 5.08 90) (size 0.999998 0.699999) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 055a58c5-6d3e-41dc-9fc4-92f3a349daed)) 48 | ) 49 | -------------------------------------------------------------------------------- /Data-Logger-PCB/kicad_libraries/remote_data_logger.pretty/LM321MF.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "LM321MF" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr smd) 5 | (fp_text reference "REF**" (at 0 -0.5 unlocked) (layer "F.SilkS") hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 29f9fe36-8680-4285-a20f-718dd151654d) 8 | ) 9 | (fp_text value "LM321MF" (at 0 1 unlocked) (layer "F.Fab") hide 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 960696ec-6739-4edd-93cb-a098d3d89fe0) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0 2.5 unlocked) (layer "F.Fab") hide 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 9aa56cca-b3df-45c5-a8fb-867f9e1abfa7) 16 | ) 17 | (fp_line (start -0.381 4.191) (end 0.381 4.191) (layer "F.SilkS") (width 0.254) (tstamp d5c7c40c-9707-479e-9c91-18c66f2d5552)) 18 | (fp_line (start -1.524 4.3815) (end -1.524 5.7785) (layer "F.SilkS") (width 0.254) (tstamp ef3663f6-3e8f-498d-877c-9034dbba49be)) 19 | (fp_line (start 1.397 4.657598) (end 1.397 5.502377) (layer "F.SilkS") (width 0.254) (tstamp f78b85f7-dd0f-46e1-93ee-5770ce0ab05c)) 20 | (fp_circle (center -1.016 6.858) (end -1.016 7.008114) (layer "Cmts.User") (width 0.299999) (fill none) (tstamp 286e7524-4f10-432d-99c3-9b788fe55bce)) 21 | (fp_poly (pts 22 | (xy -1.45001 5.879998) 23 | (xy -1.45001 4.280002) 24 | (xy 1.449984 4.280002) 25 | (xy 1.449984 5.879998) 26 | ) (layer "F.CrtYd") (width 0.508) (fill none) (tstamp 7939f36d-fff9-4655-8123-0ad32c560c69)) 27 | (pad "1" smd rect (at -0.94996 6.180074) (size 0.599999 0.999998) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 6f366aa3-ca94-411e-8338-e8cbeb23a9c7)) 28 | (pad "2" smd rect (at 0 6.180074) (size 0.599999 0.999998) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 3950d40e-b8b7-4069-be6f-f60816d47a9e)) 29 | (pad "3" smd rect (at 0.94996 6.180074) (size 0.599999 0.999998) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp bf8574ef-a9bf-45b0-ac35-e14e1e8509a2)) 30 | (pad "4" smd rect (at 0.94996 3.979926) (size 0.599999 0.999998) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 6ff07b9a-92cd-461f-9b4f-5d9c4afb0996)) 31 | (pad "5" smd rect (at -0.94996 3.979926) (size 0.599999 0.999998) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp e21dbe45-9782-4c3e-a050-30bbd2721d73)) 32 | ) 33 | -------------------------------------------------------------------------------- /Data-Logger-PCB/kicad_libraries/remote_data_logger.pretty/SOT-223-4.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "SOT-223-4" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr smd) 5 | (fp_text reference "REF**" (at 0 -0.5 unlocked) (layer "F.SilkS") hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 28e20f80-d6d3-4011-9293-b546a27fcb87) 8 | ) 9 | (fp_text value "SOT-223-4" (at 0 1 unlocked) (layer "F.Fab") hide 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp a2ac7990-770b-4e3f-8fcd-7e80a4929073) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0 2.5 unlocked) (layer "F.Fab") hide 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp 7ebe7c5b-da0f-4d6c-931e-b78948008a7a) 16 | ) 17 | (fp_line (start -3.326206 9.286291) (end -3.326206 6.543497) (layer "F.SilkS") (width 0.1524) (tstamp 377f058b-4dbc-4e8a-aac8-78e5b4aa2d35)) 18 | (fp_line (start 3.326206 6.543497) (end 3.326206 9.286291) (layer "F.SilkS") (width 0.1524) (tstamp 586e4bc0-3fb5-4410-b47f-c0de36875e9b)) 19 | (fp_line (start -3.326206 6.543497) (end 3.326206 6.543497) (layer "F.SilkS") (width 0.1524) (tstamp 65d3c74c-87d8-4b61-8b14-65b94b660351)) 20 | (fp_line (start 3.326206 9.286291) (end -3.326206 9.286291) (layer "F.SilkS") (width 0.1524) (tstamp 92abb389-bf36-400f-aace-d112fe2b6dc0)) 21 | (fp_circle (center -2.413 11.470894) (end -2.662936 11.470894) (layer "Cmts.User") (width 0.499999) (fill none) (tstamp f0929e82-2a19-4d74-a1f6-d17294853eb3)) 22 | (fp_poly (pts 23 | (xy -3.250006 6.164885) 24 | (xy 3.250006 6.164885) 25 | (xy 3.250006 9.664903) 26 | (xy -3.250006 9.664903) 27 | ) (layer "F.CrtYd") (width 0.508) (fill none) (tstamp 224195cd-bf56-4054-b2b6-9abbcf9fb255)) 28 | (pad "1" smd rect (at -2.29997 10.749788 270) (size 2.469998 0.980008) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 59eb36cf-9b92-4ebb-8e74-edcadeefc2c8)) 29 | (pad "2" smd rect (at 0 10.749788 270) (size 2.469998 0.980008) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 41a6debe-e5db-4e2a-8d49-068af0e6d849)) 30 | (pad "3" smd rect (at 2.29997 10.749788 270) (size 2.469998 0.980008) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 47783ac1-bca6-4dc7-8146-067b1cd46bc2)) 31 | (pad "4" smd rect (at 0 5.08 270) (size 2.469998 3.599993) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 9b024985-d4ef-4d9d-8ee0-ab3daa2dd5b8)) 32 | ) 33 | -------------------------------------------------------------------------------- /Data-Logger-PCB/kicad_libraries/remote_data_logger.pretty/SOT-23.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "SOT-23" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 0) 4 | (attr smd) 5 | (fp_text reference "REF**" (at 0 -0.5 unlocked) (layer "F.SilkS") hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | (tstamp 2ebe3ed6-9b52-48a4-8742-09adbd773d6e) 8 | ) 9 | (fp_text value "SOT-23" (at 0 1 unlocked) (layer "F.Fab") hide 10 | (effects (font (size 1 1) (thickness 0.15))) 11 | (tstamp 076137d4-fbc5-4f8b-8a6e-ad44ecb97b35) 12 | ) 13 | (fp_text user "${REFERENCE}" (at 0 2.5 unlocked) (layer "F.Fab") hide 14 | (effects (font (size 1 1) (thickness 0.15))) 15 | (tstamp dfed70c5-5a63-4349-be5f-57e81be92ddf) 16 | ) 17 | (fp_line (start 0.455397 5.806211) (end -0.455397 5.806211) (layer "F.SilkS") (width 0.1524) (tstamp 348644e0-fb54-4765-9e01-66430c75e26a)) 18 | (fp_line (start -1.52621 5.806211) (end -1.52621 4.353789) (layer "F.SilkS") (width 0.1524) (tstamp 3a1a4fec-2c2f-4672-9b7d-f11d5a35f7df)) 19 | (fp_line (start 1.52621 4.353789) (end 0.494589 4.353789) (layer "F.SilkS") (width 0.1524) (tstamp 52f4919c-20b2-416c-a846-effb480ee07f)) 20 | (fp_line (start -1.52621 4.353789) (end -0.494589 4.353789) (layer "F.SilkS") (width 0.1524) (tstamp 74a905ef-6681-4c24-80b8-8869860aac65)) 21 | (fp_line (start 1.52621 5.806211) (end 1.52621 4.353789) (layer "F.SilkS") (width 0.1524) (tstamp cf8d931d-cb5e-4f2c-b461-03a9b0e9b387)) 22 | (fp_circle (center -1.100074 6.539992) (end -1.20015 6.539992) (layer "Cmts.User") (width 0.2) (fill none) (tstamp 15037d6e-a17b-4639-98d7-f81d8172776c)) 23 | (fp_poly (pts 24 | (xy -1.45001 4.429989) 25 | (xy 1.45001 4.429989) 26 | (xy 1.45001 5.730011) 27 | (xy -1.45001 5.730011) 28 | ) (layer "F.CrtYd") (width 0.508) (fill none) (tstamp 3122c2d5-2ba7-48ba-81ec-f41e05aecef7)) 29 | (pad "1" smd rect (at -0.94996 6.079998 270) (size 1.25001 0.699999) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp db6604b3-2c36-4f7c-a0e7-fe14296f823b)) 30 | (pad "2" smd rect (at 0.94996 6.079998 270) (size 1.25001 0.699999) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 66f90bdd-8f71-4077-bebc-25df32cd18a3)) 31 | (pad "3" smd rect (at 0 4.080002 270) (size 1.25001 0.699999) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp abe1c6c2-1573-4e7f-8461-6d88b5f93e13)) 32 | ) 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 shanemmattner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Tutorials/p0-output/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p0-output/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p0-output/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "output" 3 | version = "0.1.0" 4 | authors = ["Shane"] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.33.7", features = ["binstart"] } 20 | esp-idf-hal = "0.42.5" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | 23 | [build-dependencies] 24 | embuild = "0.30.4" 25 | -------------------------------------------------------------------------------- /Tutorials/p0-output/README.md: -------------------------------------------------------------------------------- 1 | # Output 2 | 3 | ## Goal 4 | Make simple blinky program 5 | 6 | ## Topics covered 7 | - [esp-idf-hal](https://github.com/esp-rs/esp-idf-hal) 8 | - [Peripheral Singleton](https://docs.rust-embedded.org/book/peripherals/singletons.html) 9 | - Configure GPIO as [output](https://esp-rs.github.io/esp-idf-hal/esp_idf_hal/gpio/struct.PinDriver.html#method.output) 10 | - [FreeRTOS delay](https://esp-rs.github.io/esp-idf-hal/esp_idf_hal/delay/struct.FreeRtos.html) 11 | - [esp-println](https://github.com/esp-rs/esp-println) 12 | 13 | 14 | ## ESP-IDF-HAL 15 | Espressif's Rust implementation for the `ESP-idf` that uses [Rust's STD support](https://esp-rs.github.io/book/overview/using-the-standard-library.html) 16 | 17 | ## Singleton 18 | 19 | Singleton: software design pattern that restricts the instantiation of a class to one object. 20 | >Why have a Singleton for peripherals? 21 | >There are two important factors in play here: 22 | >- Because we are using a singleton, there is only one way or place to obtain a SerialPort structure 23 | >- To call the read_speed() method, we must have ownership or a reference to a SerialPort structure 24 | 25 | >These two factors put together means that it is only possible to access the hardware if we have appropriately satisfied the borrow checker, meaning that at no point do we have multiple mutable references to the same hardware! 26 | 27 | ## Delays 28 | Note that we will need to use different delays depending on how long we want to delay for: 29 | 30 | - `Ets`: Espressif built-in delay provider Use only for very small delays (us or a few ms at most), or else the FreeRTOS IDLE tasks’ might starve and the IDLE tasks’ watchdog will trigger 31 | - `FreeRtos`: FreeRTOS-based delay provider Use for delays larger than 10ms (delays smaller than 10ms used in a loop would starve the FreeRTOS IDLE tasks’ as they are low prio tasks and hence the the IDLE tasks’ watchdog will trigger) 32 | 33 | -------------------------------------------------------------------------------- /Tutorials/p0-output/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p0-output/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p0-output/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p0-output/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::{delay::FreeRtos, gpio::PinDriver, peripherals::Peripherals}; 2 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 3 | use esp_println::println; 4 | 5 | fn main() { 6 | // It is necessary to call this function once. Otherwise some patches to the runtime 7 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 8 | esp_idf_sys::link_patches(); 9 | 10 | println!("Starting 0-output\nThis application is a basic blinky program that turns an LED on and off every 1 second.\n"); 11 | 12 | // Get all the peripherals 13 | let peripherals = Peripherals::take().unwrap(); 14 | // Initialize Pin 8 as an output to drive the LED 15 | let mut led_pin = PinDriver::output(peripherals.pins.gpio8).unwrap(); 16 | 17 | // Loop forever blinking the LED on/off every 500ms 18 | loop { 19 | // Inverse logic to turn LED on 20 | led_pin.set_low().unwrap(); 21 | println!("LED ON"); 22 | FreeRtos::delay_ms(1000); 23 | 24 | led_pin.set_high().unwrap(); 25 | println!("LED OFF"); 26 | FreeRtos::delay_ms(1000); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Tutorials/p1-input/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p1-input/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p1-input/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "input" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | 23 | 24 | [build-dependencies] 25 | embuild = "0.30.4" 26 | -------------------------------------------------------------------------------- /Tutorials/p1-input/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p1-input/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p1-input/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p1-input/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::{ 2 | delay::FreeRtos, 3 | gpio::{IOPin, PinDriver, Pull}, 4 | peripherals::Peripherals, 5 | }; 6 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 7 | use esp_println::println; 8 | 9 | fn main() { 10 | // It is necessary to call this function once. Otherwise some patches to the runtime 11 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 12 | esp_idf_sys::link_patches(); 13 | 14 | println!("Starting 1-output\nThis application adds a button to control an LED blinking on and off every 1 second.\n"); 15 | 16 | // Get all the peripherals 17 | let peripherals = Peripherals::take().unwrap(); 18 | // Initialize Pin 8 as an output to drive the LED 19 | let mut led_pin = PinDriver::output(peripherals.pins.gpio8).unwrap(); 20 | // Initialize Pin 6 as an input to read the button status 21 | // Downgrading the pin allows us to set the pull-down resistor 22 | let mut btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade()).unwrap(); 23 | btn_pin.set_pull(Pull::Down).unwrap(); 24 | 25 | loop { 26 | // If button is pressed then do then blink on and off ever 1 sec 27 | if btn_pin.is_high() { 28 | led_pin.set_low().unwrap(); 29 | println!("LED ON"); 30 | FreeRtos::delay_ms(1000); 31 | 32 | led_pin.set_high().unwrap(); 33 | println!("LED OFF"); 34 | } else { 35 | led_pin.set_high().unwrap(); 36 | } 37 | FreeRtos::delay_ms(1000); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Tutorials/p2-threads/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p2-threads/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p2-threads/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "threads" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | crossbeam = "0.8" 23 | crossbeam-channel = "0.5" 24 | 25 | [build-dependencies] 26 | embuild = "0.31" 27 | -------------------------------------------------------------------------------- /Tutorials/p2-threads/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p2-threads/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p2-threads/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p2-threads/src/main.rs: -------------------------------------------------------------------------------- 1 | use crossbeam_channel::bounded; 2 | use esp_idf_hal::{ 3 | delay::FreeRtos, 4 | gpio::{AnyIOPin, AnyOutputPin, IOPin, Input, Output, OutputPin, PinDriver, Pull}, 5 | peripherals::Peripherals, 6 | }; 7 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 8 | use esp_println::println; 9 | 10 | static BLINKY_STACK_SIZE: usize = 2000; 11 | static BUTTON_STACK_SIZE: usize = 2000; 12 | 13 | fn main() { 14 | // It is necessary to call this function once. Otherwise some patches to the runtime 15 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 16 | esp_idf_sys::link_patches(); 17 | 18 | println!("Starting 2-threads\nThis application separates the input button logic and blinky logic into their own threaads."); 19 | 20 | let peripherals = Peripherals::take().unwrap(); 21 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 22 | let mut btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade()).unwrap(); 23 | btn_pin.set_pull(Pull::Down).unwrap(); 24 | 25 | let (tx, rx) = bounded(1); 26 | 27 | let _blinky_thread = std::thread::Builder::new() 28 | .stack_size(BLINKY_STACK_SIZE) 29 | .spawn(move || blinky_thread_function(led_pin, rx)) 30 | .unwrap(); 31 | 32 | let _button_thread = std::thread::Builder::new() 33 | .stack_size(BUTTON_STACK_SIZE) 34 | .spawn(move || button_thread_function(btn_pin, tx)) 35 | .unwrap(); 36 | } 37 | 38 | // Thread function that will blink the LED on/off every 500ms 39 | fn blinky_thread_function( 40 | mut led_pin: PinDriver, 41 | rx: crossbeam_channel::Receiver, 42 | ) { 43 | let mut blinky_status = false; 44 | loop { 45 | match rx.try_recv() { 46 | Ok(x) => blinky_status = x, 47 | Err(_) => {} 48 | } 49 | if blinky_status { 50 | led_pin.set_low().unwrap(); 51 | println!("LED ON"); 52 | FreeRtos::delay_ms(1000); 53 | 54 | led_pin.set_high().unwrap(); 55 | println!("LED OFF"); 56 | } 57 | FreeRtos::delay_ms(1000); 58 | } 59 | } 60 | 61 | fn button_thread_function( 62 | btn_pin: PinDriver, 63 | tx: crossbeam_channel::Sender, 64 | ) { 65 | let mut btn_status = false; 66 | 67 | loop { 68 | if btn_pin.is_high() { 69 | if !btn_status { 70 | btn_status = true; 71 | println!("BUTTON ON"); 72 | tx.send(btn_status).unwrap(); 73 | } 74 | } else { 75 | if btn_status { 76 | btn_status = false; 77 | println!("BUTTON OFF"); 78 | tx.send(btn_status).unwrap(); 79 | } 80 | } 81 | FreeRtos::delay_ms(100); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Tutorials/p3-adc/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p3-adc/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p3-adc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "adc" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.33.7", features = ["binstart"] } 20 | esp-idf-hal = "0.42.5" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | 23 | [build-dependencies] 24 | embuild = "0.31" 25 | -------------------------------------------------------------------------------- /Tutorials/p3-adc/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p3-adc/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p3-adc/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p3-adc/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::{ 2 | adc::{self, *}, 3 | delay::FreeRtos, 4 | peripherals::Peripherals, 5 | }; 6 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 7 | use esp_println::println; 8 | 9 | fn main() { 10 | // It is necessary to call this function once. Otherwise some patches to the runtime 11 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 12 | esp_idf_sys::link_patches(); 13 | 14 | println!( 15 | "Starting 3-adc\nThis application reads 4 ADC pins and prints the values every 1 second.\n" 16 | ); 17 | 18 | let peripherals = Peripherals::take().unwrap(); 19 | 20 | // ADC init 21 | let mut adc1 = AdcDriver::new( 22 | peripherals.adc1, 23 | &adc::config::Config::new().calibration(true), 24 | ) 25 | .unwrap(); 26 | let mut a1_ch0 = 27 | adc::AdcChannelDriver::<{ adc::attenuation::DB_11 }, _>::new(peripherals.pins.gpio0) 28 | .unwrap(); 29 | 30 | loop { 31 | match adc1.read(&mut a1_ch0) { 32 | Ok(x) => println!("A1_CH0: {x}\n"), 33 | Err(e) => println!("err reading A1_CH0: {e}\n"), 34 | } 35 | FreeRtos::delay_ms(1000); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Tutorials/p4-dht11/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p4-dht11/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p4-dht11/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dht11" 3 | version = "0.1.0" 4 | authors = ["Shane "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-hal = "0.40" 20 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 21 | dht11 = "0.3.1" 22 | 23 | [build-dependencies] 24 | embuild = "0.30.4" 25 | -------------------------------------------------------------------------------- /Tutorials/p4-dht11/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p4-dht11/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p4-dht11/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p4-dht11/src/main.rs: -------------------------------------------------------------------------------- 1 | use dht11::Dht11; 2 | use esp_idf_hal::{ 3 | delay::{Ets, FreeRtos}, 4 | gpio::*, 5 | prelude::Peripherals, 6 | }; 7 | 8 | fn main() { 9 | esp_idf_sys::link_patches(); 10 | 11 | let peripherals = Peripherals::take().unwrap(); 12 | 13 | let dht11_pin = PinDriver::input_output_od(peripherals.pins.gpio5.downgrade()).unwrap(); 14 | 15 | let mut dht11 = Dht11::new(dht11_pin); 16 | 17 | loop { 18 | let mut dht11_delay = Ets; 19 | match dht11.perform_measurement(&mut dht11_delay) { 20 | Ok(measurement) => println!( 21 | "temp: {}C, humidity: {}%", 22 | (measurement.temperature as f32 / 10.0), 23 | (measurement.humidity as f32 / 10.0) 24 | ), 25 | Err(e) => println!("{:?}", e), 26 | } 27 | FreeRtos::delay_ms(2000); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tutorials/p5-i2c/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p5-i2c/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p5-i2c/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "i2c" 3 | version = "0.1.0" 4 | authors = ["Shane "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | sx1509 = "0.2.0" 23 | 24 | 25 | [build-dependencies] 26 | embuild = "0.30.4" 27 | -------------------------------------------------------------------------------- /Tutorials/p5-i2c/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p5-i2c/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p5-i2c/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p5-i2c/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::{delay::FreeRtos, i2c::*, peripherals::Peripherals, prelude::*}; 2 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 3 | use esp_println::println; 4 | use sx1509; 5 | 6 | fn main() { 7 | // It is necessary to call this function once. Otherwise some patches to the runtime 8 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 9 | esp_idf_sys::link_patches(); 10 | 11 | println!("Starting 5-i2c. This application talks to a SX1509 GPIO expander taking in 8 inputes and setting 8 outputs.\n"); 12 | 13 | let peripherals = Peripherals::take().unwrap(); 14 | let i2c = peripherals.i2c0; 15 | let sda = peripherals.pins.gpio10; 16 | let scl = peripherals.pins.gpio1; 17 | 18 | let config = I2cConfig::new().baudrate(400.kHz().into()); 19 | let mut i2c = I2cDriver::new(i2c, sda, scl, &config).unwrap(); 20 | 21 | let mut expander = sx1509::Sx1509::new(&mut i2c, sx1509::DEFAULT_ADDRESS); 22 | expander.borrow(&mut i2c).software_reset().unwrap(); 23 | expander.borrow(&mut i2c).set_bank_a_direction(0).unwrap(); 24 | expander.borrow(&mut i2c).set_bank_a_pullup(0xFF).unwrap(); 25 | 26 | expander 27 | .borrow(&mut i2c) 28 | .set_bank_b_direction(0xFF) 29 | .unwrap(); 30 | 31 | // The sx1509 driver currently doesn't have pull-down implemented so directly write with I2C 32 | i2c.write( 33 | sx1509::DEFAULT_ADDRESS, 34 | &[sx1509::Register::RegPullDownB as u8], 35 | 0xFF, 36 | ) 37 | .unwrap(); 38 | 39 | loop { 40 | let pins = expander.borrow(&mut i2c).get_bank_a_data().unwrap(); 41 | println!("bank a: {pins}"); 42 | 43 | expander.borrow(&mut i2c).set_bank_b_data(pins).unwrap(); 44 | 45 | FreeRtos::delay_ms(100); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "spi" 3 | version = "0.1.0" 4 | authors = ["Shane "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | embedded-sdmmc = "0.4.0" 23 | 24 | [build-dependencies] 25 | embuild = "0.30.4" 26 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Note that I am using updated names for SPI data lines. 4 | 5 | `PICO`: peripheral in/ controller out. Replaces `MOSI` 6 | `POCI`: peripheral out/ controller in. Replaces MISO 7 | 8 | https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/ 9 | https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all 10 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p6-spi/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p6-spi/src/main.rs: -------------------------------------------------------------------------------- 1 | use embedded_sdmmc::*; 2 | use esp_idf_hal::{ 3 | gpio::*, 4 | peripherals::Peripherals, 5 | prelude::*, 6 | spi::{config::Duplex, *}, 7 | }; 8 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 9 | use esp_println::println; 10 | 11 | const FILE_NAME: &'static str = "logs.txt"; 12 | 13 | pub struct SdMmcClock; 14 | 15 | impl TimeSource for SdMmcClock { 16 | fn get_timestamp(&self) -> Timestamp { 17 | Timestamp { 18 | year_since_1970: 0, 19 | zero_indexed_month: 0, 20 | zero_indexed_day: 0, 21 | hours: 0, 22 | minutes: 0, 23 | seconds: 0, 24 | } 25 | } 26 | } 27 | 28 | fn main() { 29 | // It is necessary to call this function once. Otherwise some patches to the runtime 30 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 31 | esp_idf_sys::link_patches(); 32 | 33 | println!("Starting 6-spi\nThis application writes to a micro-SD card\n"); 34 | 35 | let peripherals = Peripherals::take().unwrap(); 36 | 37 | // SPI sd card init 38 | let driver = SpiDriver::new( 39 | peripherals.spi2, 40 | peripherals.pins.gpio8, // SCK 41 | peripherals.pins.gpio7, // PICO 42 | Some(peripherals.pins.gpio9), // POCI 43 | Dma::Disabled, 44 | ) 45 | .unwrap(); 46 | 47 | let mut spi_config = SpiConfig::new(); 48 | spi_config.duplex = Duplex::Full; 49 | let _ = spi_config.baudrate(24.MHz().into()); 50 | let spi = SpiDeviceDriver::new(driver, Option::::None, &spi_config).unwrap(); 51 | let sdmmc_cs = PinDriver::output(peripherals.pins.gpio6).unwrap(); 52 | let mut sdmmc_spi = embedded_sdmmc::SdMmcSpi::new(spi, sdmmc_cs); 53 | 54 | match sdmmc_spi.acquire() { 55 | Ok(block) => { 56 | let mut controller = embedded_sdmmc::Controller::new(block, SdMmcClock); 57 | 58 | let mut volume = controller.get_volume(embedded_sdmmc::VolumeIdx(0)).unwrap(); 59 | 60 | let root_dir = controller.open_root_dir(&volume).unwrap(); 61 | 62 | let mut f = controller 63 | .open_file_in_dir( 64 | &mut volume, 65 | &root_dir, 66 | FILE_NAME, 67 | Mode::ReadWriteCreateOrAppend, 68 | ) 69 | .unwrap(); 70 | 71 | f.seek_from_end(0).unwrap(); 72 | let log_string: String = "Hello SD card!\n".to_string(); 73 | let _bytes_written = controller 74 | .write(&mut volume, &mut f, &log_string.as_bytes()[..]) 75 | .unwrap(); 76 | println!("String written: {log_string}"); 77 | 78 | controller.close_file(&volume, f).unwrap(); 79 | } 80 | Err(e) => println!("Error acquire SPI bus {:?}", e), 81 | }; 82 | } 83 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uart" 3 | version = "0.1.0" 4 | authors = ["Shane "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | 22 | [build-dependencies] 23 | embuild = "0.30.4" 24 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Links 4 | [Building a Basic Shell](https://interrupt.memfault.com/blog/firmware-shell) 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p7-uart/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p7-uart/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::{ 2 | delay::{FreeRtos, NON_BLOCK}, 3 | gpio, 4 | peripherals::Peripherals, 5 | prelude::*, 6 | uart::*, 7 | }; 8 | use esp_idf_sys as _; 9 | 10 | const CR: u8 = 13; 11 | 12 | fn main() { 13 | esp_idf_sys::link_patches(); 14 | 15 | let peripherals = Peripherals::take().unwrap(); 16 | let tx = peripherals.pins.gpio21; 17 | let rx = peripherals.pins.gpio20; 18 | 19 | let config = config::Config::new().baudrate(Hertz(115_200)); 20 | let uart = UartDriver::new( 21 | peripherals.uart1, 22 | tx, 23 | rx, 24 | Option::::None, 25 | Option::::None, 26 | &config, 27 | ) 28 | .unwrap(); 29 | 30 | let mut cli_buf: Vec = Vec::new(); 31 | 32 | loop { 33 | let mut buf: [u8; 10] = [0; 10]; 34 | match uart.read(&mut buf, NON_BLOCK) { 35 | Ok(bytes_read) => { 36 | if bytes_read > 0 { 37 | let b = buf[0]; 38 | cli_buf.push(b); 39 | if b == CR { 40 | match uart.write(&cli_buf) { 41 | Ok(_) => println!("{:?} written", cli_buf), 42 | Err(_) => {} 43 | } 44 | cli_buf.clear(); 45 | } 46 | } 47 | } 48 | Err(_) => {} 49 | } 50 | FreeRtos::delay_ms(100); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cli" 3 | version = "0.1.0" 4 | authors = ["Shane "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | anyhow = "1" 22 | lazy_static = "1.4.0" 23 | shell-words = "1.0.0" 24 | 25 | [build-dependencies] 26 | embuild = "0.30.4" 27 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Links 4 | 5 | [Building a Basic Shell](https://interrupt.memfault.com/blog/firmware-shell) 6 | 7 | [embedded command line interface](https://dojofive.com/blog/embedded-command-line-interfaces-and-why-you-need-them/) 8 | 9 | 10 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /Tutorials/p8-cli/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /Tutorials/p8-cli/src/main.rs: -------------------------------------------------------------------------------- 1 | mod cli; 2 | 3 | use esp_idf_hal::{delay::FreeRtos, gpio, peripherals::Peripherals, prelude::*, uart::*}; 4 | use esp_idf_sys as _; 5 | 6 | static CLI_STACK_SIZE: usize = 5000; 7 | 8 | fn main() -> anyhow::Result<()> { 9 | esp_idf_sys::link_patches(); 10 | 11 | let peripherals = Peripherals::take().unwrap(); 12 | let tx = peripherals.pins.gpio21; 13 | let rx = peripherals.pins.gpio20; 14 | 15 | let config = config::Config::new().baudrate(Hertz(115_200)); 16 | let uart = UartDriver::new( 17 | peripherals.uart1, 18 | tx, 19 | rx, 20 | Option::::None, 21 | Option::::None, 22 | &config, 23 | ) 24 | .unwrap(); 25 | 26 | let _cli_thread = std::thread::Builder::new() 27 | .stack_size(CLI_STACK_SIZE) 28 | .spawn(move || cli::uart_thread(uart)) 29 | .unwrap(); 30 | 31 | loop { 32 | FreeRtos::delay_ms(100); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky-fsm" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | statig = "0.2.0" 23 | 24 | [build-dependencies] 25 | embuild = "0.30.4" 26 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/README.md: -------------------------------------------------------------------------------- 1 | Need to use non-macro version of Statig to allow for generics: 2 | 3 | [issue on github](https://github.com/mdeloof/statig/issues/7) 4 | [no macro examples](https://github.com/mdeloof/statig/tree/main/examples/no_macro) -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/src/led_fsm.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::gpio::{AnyOutputPin, Output, PinDriver}; 2 | use esp_println::println; 3 | use statig::prelude::*; 4 | 5 | // #[derive(Debug, Default)] 6 | pub struct Blinky<'a> { 7 | pub led_pin: PinDriver<'a, AnyOutputPin, Output>, 8 | } 9 | 10 | // The event that will be handled by the state machine. 11 | #[derive(Debug)] 12 | pub enum Event { 13 | TimerElapsed, 14 | } 15 | 16 | #[derive(Debug)] 17 | pub enum State { 18 | LedOn, 19 | LedOff, 20 | } 21 | 22 | impl StateMachine for Blinky<'_> { 23 | type State = State; 24 | type Superstate<'a> = (); 25 | type Event<'a> = Event; 26 | const INITIAL: State = State::LedOff; 27 | const ON_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, source, target| { 28 | println!("Transitioned from {source:?} to {target:?}"); 29 | }; 30 | } 31 | 32 | impl statig::State> for State { 33 | fn call_handler(&mut self, blinky: &mut Blinky, event: &Event) -> Response { 34 | match self { 35 | State::LedOn => blinky.led_on(event), 36 | State::LedOff => blinky.led_off(event), 37 | } 38 | } 39 | 40 | fn call_entry_action(&mut self, blinky: &mut Blinky) { 41 | match self { 42 | State::LedOn => blinky.enter_led_on(), 43 | State::LedOff => blinky.enter_led_off(), 44 | } 45 | } 46 | } 47 | 48 | impl Blinky<'_> { 49 | fn enter_led_on(&mut self) { 50 | // Setting the pin high turns the LED off on my dev board 51 | self.led_gpio.set_low().unwrap(); 52 | } 53 | fn enter_led_off(&mut self) { 54 | // Setting the pin low turns the LED on for my dev board 55 | self.led_gpio.set_high().unwrap(); 56 | } 57 | 58 | fn led_on(&mut self, event: &Event) -> Response { 59 | match event { 60 | Event::TimerElapsed => Transition(State::LedOff), 61 | } 62 | } 63 | 64 | fn led_off(&mut self, event: &Event) -> Response { 65 | match event { 66 | Event::TimerElapsed => Transition(State::LedOn), 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /WIP/ch03-blinky-fsm/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::{ 2 | gpio::{OutputPin, PinDriver}, 3 | prelude::*, 4 | }; 5 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 6 | use statig::{prelude::*, InitializedStatemachine}; 7 | use std::{thread, time::Duration}; 8 | 9 | static BLINKY_STACK_SIZE: usize = 2000; 10 | 11 | mod led_fsm; 12 | 13 | fn main() { 14 | // It is necessary to call this function once. Otherwise some patches to the runtime 15 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 16 | esp_idf_sys::link_patches(); 17 | 18 | // Get all the peripherals 19 | let peripherals = Peripherals::take().unwrap(); 20 | // Initialize an output pin to drive the LED 21 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 22 | // Create and initialize the finitie state machine. Pass in the LED gpio pin 23 | let blinky_fsm = led_fsm::Blinky { led_pin }.state_machine().init(); 24 | // Create thread in which the fsm will run 25 | let _blinky_thread = std::thread::Builder::new() 26 | .stack_size(BLINKY_STACK_SIZE) 27 | .spawn(move || blinky_fsm_thread(blinky_fsm)) 28 | .unwrap(); 29 | } 30 | 31 | // Thread logic that will trigger TimerElapsed events in the blinky FSM which will 32 | // blinky the LED on/off 33 | fn blinky_fsm_thread(mut fsm: InitializedStatemachine) { 34 | loop { 35 | thread::sleep(Duration::from_millis(1000)); 36 | fsm.handle(&led_fsm::Event::TimerElapsed); 37 | thread::sleep(Duration::from_millis(1000)); 38 | fsm.handle(&led_fsm::Event::TimerElapsed); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky-button-hsm" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | statig = "0.2.0" 23 | critical-section = { version = "1.1.1", features = ["std"] } 24 | esp-println = { version = "0.3", features = ["esp32c3"] } 25 | 26 | [build-dependencies] 27 | embuild = "0.30.4" 28 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/src/led_fsm.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::gpio::{AnyOutputPin, Output, PinDriver}; 2 | use esp_println::println; 3 | use statig::prelude::*; 4 | 5 | // #[derive(Debug, Default)] 6 | pub struct Blinky<'a> { 7 | pub led_pin: PinDriver<'a, AnyOutputPin, Output>, 8 | } 9 | 10 | // The event that will be handled by the state machine. 11 | pub enum Event { 12 | TimerElapsed, 13 | ButtonPressed, 14 | } 15 | #[derive(Debug)] 16 | pub enum State { 17 | LedOn, 18 | LedOff, 19 | NotBlinking, 20 | } 21 | 22 | pub enum Superstate { 23 | Blinking, 24 | } 25 | 26 | impl StateMachine for Blinky<'_> { 27 | type State = State; 28 | type Superstate<'a> = Superstate; 29 | type Event<'a> = Event; 30 | const INITIAL: State = State::LedOff; 31 | const ON_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, source, target| { 32 | println!("Transitioned from {source:?} to {target:?}"); 33 | }; 34 | } 35 | 36 | impl statig::State> for State { 37 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 38 | match self { 39 | State::LedOn => Blinky::led_on(event), 40 | State::LedOff => Blinky::led_off(event), 41 | State::NotBlinking => Blinky::not_blinking(event), 42 | } 43 | } 44 | 45 | fn superstate(&mut self) -> Option { 46 | match self { 47 | State::LedOn => Some(Superstate::Blinking), 48 | State::LedOff => Some(Superstate::Blinking), 49 | State::NotBlinking => None, 50 | } 51 | } 52 | 53 | fn call_entry_action(&mut self, blinky: &mut Blinky) { 54 | match self { 55 | State::LedOn => blinky.enter_led_on(), 56 | State::LedOff => blinky.enter_led_off(), 57 | _ => (), 58 | } 59 | } 60 | } 61 | 62 | impl statig::Superstate> for Superstate { 63 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 64 | match self { 65 | Superstate::Blinking => Blinky::blinking(event), 66 | } 67 | } 68 | } 69 | 70 | impl Blinky<'_> { 71 | fn enter_led_on(&mut self) { 72 | // Setting the pin high turns the LED off on my dev board 73 | self.led_pin.set_low().unwrap(); 74 | } 75 | 76 | fn enter_led_off(&mut self) { 77 | // Setting the pin low turns the LED on for my dev board 78 | self.led_pin.set_high().unwrap(); 79 | } 80 | 81 | fn led_on(event: &Event) -> Response { 82 | match event { 83 | Event::TimerElapsed => Transition(State::LedOff), 84 | _ => Super, 85 | } 86 | } 87 | 88 | fn led_off(event: &Event) -> Response { 89 | match event { 90 | Event::TimerElapsed => Transition(State::LedOn), 91 | _ => Super, 92 | } 93 | } 94 | 95 | fn blinking(event: &Event) -> Response { 96 | match event { 97 | Event::ButtonPressed => Transition(State::NotBlinking), 98 | _ => Super, 99 | } 100 | } 101 | 102 | fn not_blinking(event: &Event) -> Response { 103 | match event { 104 | Event::ButtonPressed => Transition(State::LedOn), 105 | _ => Super, 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-button-hsm/src/main.rs: -------------------------------------------------------------------------------- 1 | <<<<<<< Updated upstream:WIP/ch04-blinky-button-hsm/src/main.rs 2 | use esp_idf_hal::{ 3 | gpio::{AnyInputPin, Input, InputPin, OutputPin, PinDriver}, 4 | ======= 5 | #![allow(dead_code)] 6 | #![allow(unused_variables, unused_imports)] 7 | 8 | use critical_section::{CriticalSection, Mutex}; 9 | use esp_idf_hal::{ 10 | gpio::{ 11 | AnyInputPin, AnyOutputPin, Input, InputMode, InputPin, InterruptType, Output, OutputPin, 12 | PinDriver, 13 | }, 14 | interrupt, 15 | >>>>>>> Stashed changes:ch04-blinky-button-hsm/src/main.rs 16 | prelude::*, 17 | }; 18 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 19 | use statig::{prelude::*, InitializedStatemachine}; 20 | use std::{cell::RefCell, thread, time::Duration}; 21 | 22 | static BLINKY_STACK_SIZE: usize = 2000; 23 | 24 | //static BUTTON_A: Mutex>>> = 25 | // Mutex::new(RefCell::new(None)); 26 | 27 | mod led_fsm; 28 | 29 | fn int_handler() { 30 | println!("int\n"); 31 | } 32 | 33 | fn main() { 34 | // It is necessary to call this function once. Otherwise some patches to the runtime 35 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 36 | esp_idf_sys::link_patches(); 37 | 38 | // Get all the peripherals 39 | let peripherals = Peripherals::take().unwrap(); 40 | <<<<<<< Updated upstream:WIP/ch04-blinky-button-hsm/src/main.rs 41 | // Initialize an output pin to drive the LED 42 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 43 | // Initialize an input pin for the button 44 | let btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade_input()).unwrap(); 45 | // Create and initialize the finitie state machine. Pass in the LED gpio pin 46 | let led_fsm = led_fsm::Blinky { led_pin }.state_machine().init(); 47 | 48 | // Create thread in which the fsm will run and the button status will be monitored 49 | let _blinky_thread = std::thread::Builder::new() 50 | .stack_size(BLINKY_STACK_SIZE) 51 | .spawn(move || blinky_fsm_thread(led_fsm, btn_pin)) 52 | .unwrap(); 53 | ======= 54 | let led = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 55 | // let mut btn = PinDriver::input(peripherals.pins.gpio6.downgrade_input()).unwrap(); 56 | //btn.set_interrupt_type(InterruptType::NegEdge).unwrap(); 57 | //unsafe { 58 | // btn.subscribe(on_push_a).unwrap(); 59 | //} 60 | // critical_section::with(|cs| { 61 | // BUTTON_A.replace(cs, Some(btn)); 62 | // }); 63 | 64 | let led_fsm = led_fsm::Blinky { led }.state_machine().init(); 65 | 66 | //let _blinky_thread = std::thread::Builder::new() 67 | // .stack_size(BLINKY_STACK_SIZE) 68 | // .spawn(move || blinky_fsm_thread(led_fsm, btn)) 69 | // .unwrap(); 70 | } 71 | 72 | fn on_push_a() { 73 | esp_println::println!("button a pushed"); 74 | 75 | //critical_section::with(|cs| { 76 | // BUTTON_A.borrow(cs).borrow().as_ref().and_then(|btn| { 77 | // println!("int\n"); 78 | // Some(()) 79 | // }); 80 | //}); 81 | >>>>>>> Stashed changes:ch04-blinky-button-hsm/src/main.rs 82 | } 83 | 84 | fn blinky_fsm_thread( 85 | mut fsm: InitializedStatemachine, 86 | btn_pin: PinDriver, 87 | ) { 88 | let mut btn_state = true; 89 | let mut led_count = 0; 90 | loop { 91 | led_count += 1; 92 | if led_count > 10 { 93 | led_count = 0; 94 | fsm.handle(&led_fsm::Event::TimerElapsed); 95 | } 96 | 97 | if btn_pin.is_high() { 98 | if !btn_state { 99 | btn_state = true; 100 | fsm.handle(&led_fsm::Event::ButtonPressed); 101 | } 102 | } else { 103 | btn_state = false; 104 | } 105 | 106 | thread::sleep(Duration::from_millis(100)); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky-multi-thread" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | crossbeam = "0.8" 23 | crossbeam-channel = "0.5" 24 | 25 | [build-dependencies] 26 | embuild = "0.31" 27 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch04-blinky-multi-thread/src/main.rs: -------------------------------------------------------------------------------- 1 | use crossbeam_channel::bounded; 2 | use esp_idf_hal::{ 3 | gpio::{AnyIOPin, AnyOutputPin, IOPin, Input, Output, OutputPin, PinDriver, Pull}, 4 | prelude::*, 5 | }; 6 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 7 | use esp_println::println; 8 | use std::{thread, time::Duration}; 9 | 10 | static BLINKY_STACK_SIZE: usize = 2000; 11 | static BUTTON_STACK_SIZE: usize = 2000; 12 | 13 | fn main() { 14 | // It is necessary to call this function once. Otherwise some patches to the runtime 15 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 16 | esp_idf_sys::link_patches(); 17 | 18 | let peripherals = Peripherals::take().unwrap(); 19 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 20 | let mut btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade()).unwrap(); 21 | btn_pin.set_pull(Pull::Down).unwrap(); 22 | 23 | let (tx, rx) = bounded(1); 24 | 25 | let _blinky_thread = std::thread::Builder::new() 26 | .stack_size(BLINKY_STACK_SIZE) 27 | .spawn(move || blinky_thread(led_pin, rx)) 28 | .unwrap(); 29 | 30 | let _button_thread = std::thread::Builder::new() 31 | .stack_size(BUTTON_STACK_SIZE) 32 | .spawn(move || button_thread(btn_pin, tx)) 33 | .unwrap(); 34 | } 35 | 36 | // Thread function that will blink the LED on/off every 500ms 37 | fn blinky_thread( 38 | mut led_pin: PinDriver, 39 | rx: crossbeam_channel::Receiver, 40 | ) { 41 | let mut blinky_status = false; 42 | loop { 43 | match rx.try_recv() { 44 | Ok(x) => blinky_status = x, 45 | Err(_) => {} 46 | } 47 | if blinky_status { 48 | led_pin.set_low().unwrap(); 49 | println!("LED ON"); 50 | thread::sleep(Duration::from_millis(1000)); 51 | 52 | led_pin.set_high().unwrap(); 53 | println!("LED OFF"); 54 | thread::sleep(Duration::from_millis(1000)); 55 | } 56 | thread::sleep(Duration::from_millis(100)); 57 | } 58 | } 59 | 60 | fn button_thread(btn_pin: PinDriver, tx: crossbeam_channel::Sender) { 61 | let mut btn_status = false; 62 | 63 | loop { 64 | if btn_pin.is_high() { 65 | if !btn_status { 66 | btn_status = true; 67 | println!("BUTTON ON"); 68 | tx.send(btn_status).unwrap(); 69 | } 70 | } else { 71 | if btn_status { 72 | btn_status = false; 73 | println!("BUTTON OFF"); 74 | tx.send(btn_status).unwrap(); 75 | } 76 | } 77 | thread::sleep(Duration::from_millis(100)); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "adc_to_ledc" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } 23 | crossbeam = "0.8" 24 | crossbeam-channel = "0.5" 25 | crossbeam-utils = "0.8" 26 | 27 | [build-dependencies] 28 | embuild = "0.31" 29 | -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/README.md: -------------------------------------------------------------------------------- 1 | In this chapter we will be using [Crossbeam AtomicCell](https://docs.rs/crossbeam/latest/crossbeam/atomic/struct.AtomicCell.html) to share data between threads. 2 | 3 | We will create a thread to read an [analog to digital](https://www.electronics-tutorials.ws/combination/analogue-to-digital-converter.html) reading, then the LED thread will take that reading and 4 | use it to adjust the brightness of the LED by controlling the PWM. 5 | 6 | In order to control the PWM of the LED we will need to use the ESP32-C3 [led controller](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html). 7 | 8 | -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch05-adc_to_ledc/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky-crossbeams" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | statig = "0.2.0" 23 | crossbeam = "0.8" 24 | crossbeam-channel = "0.5" 25 | 26 | [build-dependencies] 27 | embuild = "0.31" 28 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/src/led_fsm.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::gpio::{AnyOutputPin, Output, PinDriver}; 2 | use esp_println::println; 3 | use statig::prelude::*; 4 | 5 | // #[derive(Debug, Default)] 6 | pub struct Blinky<'a> { 7 | pub led_pin: PinDriver<'a, AnyOutputPin, Output>, 8 | } 9 | 10 | // The event that will be handled by the state machine. 11 | pub enum Event { 12 | TimerElapsed, 13 | ButtonPressed, 14 | } 15 | #[derive(Debug)] 16 | pub enum State { 17 | LedOn, 18 | LedOff, 19 | NotBlinking, 20 | } 21 | 22 | pub enum Superstate { 23 | Blinking, 24 | } 25 | 26 | impl StateMachine for Blinky<'_> { 27 | type State = State; 28 | type Superstate<'a> = Superstate; 29 | type Event<'a> = Event; 30 | const INITIAL: State = State::LedOff; 31 | const ON_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, source, target| { 32 | println!("Transitioned from {source:?} to {target:?}"); 33 | }; 34 | } 35 | 36 | impl statig::State> for State { 37 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 38 | match self { 39 | State::LedOn => Blinky::led_on(event), 40 | State::LedOff => Blinky::led_off(event), 41 | State::NotBlinking => Blinky::not_blinking(event), 42 | } 43 | } 44 | 45 | fn superstate(&mut self) -> Option { 46 | match self { 47 | State::LedOn => Some(Superstate::Blinking), 48 | State::LedOff => Some(Superstate::Blinking), 49 | State::NotBlinking => None, 50 | } 51 | } 52 | 53 | fn call_entry_action(&mut self, blinky: &mut Blinky) { 54 | match self { 55 | State::LedOn => blinky.enter_led_on(), 56 | State::LedOff => blinky.enter_led_off(), 57 | _ => (), 58 | } 59 | } 60 | } 61 | 62 | impl statig::Superstate> for Superstate { 63 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 64 | match self { 65 | Superstate::Blinking => Blinky::blinking(event), 66 | } 67 | } 68 | } 69 | 70 | impl Blinky<'_> { 71 | fn enter_led_on(&mut self) { 72 | self.led_pin.set_high().unwrap(); 73 | } 74 | 75 | fn enter_led_off(&mut self) { 76 | self.led_pin.set_low().unwrap(); 77 | } 78 | 79 | fn led_on(event: &Event) -> Response { 80 | match event { 81 | Event::TimerElapsed => Transition(State::LedOff), 82 | _ => Super, 83 | } 84 | } 85 | 86 | fn led_off(event: &Event) -> Response { 87 | match event { 88 | Event::TimerElapsed => Transition(State::LedOn), 89 | _ => Super, 90 | } 91 | } 92 | 93 | fn blinking(event: &Event) -> Response { 94 | match event { 95 | Event::ButtonPressed => Transition(State::NotBlinking), 96 | _ => Super, 97 | } 98 | } 99 | 100 | fn not_blinking(event: &Event) -> Response { 101 | match event { 102 | Event::ButtonPressed => Transition(State::LedOn), 103 | _ => Super, 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /WIP/ch05-blinky-crossbeams/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate crossbeam; 2 | extern crate crossbeam_channel; 3 | 4 | use crossbeam_channel::bounded; 5 | use esp_idf_hal::{ 6 | gpio::{AnyInputPin, Input, InputPin, OutputPin, PinDriver}, 7 | prelude::*, 8 | }; 9 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 10 | use esp_println::println; 11 | use statig::{prelude::*, InitializedStatemachine}; 12 | use std::{thread, time::Duration}; 13 | 14 | static BLINKY_STACK_SIZE: usize = 2000; 15 | static BUTTON_STACK_SIZE: usize = 2000; 16 | 17 | mod led_fsm; 18 | 19 | fn main() { 20 | // It is necessary to call this function once. Otherwise some patches to the runtime 21 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 22 | esp_idf_sys::link_patches(); 23 | 24 | let peripherals = Peripherals::take().unwrap(); 25 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 26 | let btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade_input()).unwrap(); 27 | 28 | let led_fsm = led_fsm::Blinky { led_pin }.state_machine().init(); 29 | 30 | let (tx, rx) = bounded(1); 31 | print_type_of(&tx); 32 | 33 | let _blinky_thread = std::thread::Builder::new() 34 | .stack_size(BLINKY_STACK_SIZE) 35 | .spawn(move || blinky_fsm_thread(led_fsm, rx)) 36 | .unwrap(); 37 | 38 | let _button_thread = std::thread::Builder::new() 39 | .stack_size(BUTTON_STACK_SIZE) 40 | .spawn(move || button_thread(btn_pin, tx)) 41 | .unwrap(); 42 | } 43 | 44 | fn blinky_fsm_thread( 45 | mut fsm: InitializedStatemachine, 46 | rx: crossbeam_channel::Receiver, 47 | ) { 48 | loop { 49 | fsm.handle(&led_fsm::Event::TimerElapsed); 50 | match rx.try_recv() { 51 | Ok(_) => fsm.handle(&led_fsm::Event::ButtonPressed), 52 | Err(_) => {} 53 | } 54 | 55 | thread::sleep(Duration::from_millis(1000)); 56 | } 57 | } 58 | 59 | fn button_thread(btn_pin: PinDriver<'_, AnyInputPin, Input>, tx: crossbeam_channel::Sender) { 60 | let mut btn_state = true; 61 | loop { 62 | if btn_pin.is_high() { 63 | if !btn_state { 64 | btn_state = true; 65 | tx.send(btn_state).unwrap(); 66 | } 67 | } else { 68 | btn_state = false; 69 | } 70 | 71 | thread::sleep(Duration::from_millis(100)); 72 | } 73 | } 74 | 75 | fn print_type_of(_: &T) { 76 | println!("{}", std::any::type_name::()) 77 | } 78 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky-adc" 3 | version = "0.1.0" 4 | authors = ["Shane"] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | statig = "0.2.0" 23 | crossbeam = "0.8" 24 | crossbeam-channel = "0.5" 25 | 26 | 27 | [build-dependencies] 28 | embuild = "0.31" 29 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/README.md: -------------------------------------------------------------------------------- 1 | # Blinky ADC 2 | 3 | In this example we'll use ADC values to blinky the LED at a certain PWM based on the ADC reading. 4 | 5 | Now that we have more tasks building up we should move them to another file `tasks.rs`. To use 6 | those tasks in main we'll just import with: 7 | 8 | ```rust 9 | mod tasks; 10 | ``` 11 | 12 | And to use `led_fsm.rs` functions in `tasks.rs` we'll need to use `led_fsm`: 13 | ```rust 14 | use crate::led_fsm; 15 | ``` 16 | 17 | 18 | 19 | 20 | ## setup debugging 21 | https://docs.espressif.com/projects/esp-idf/en/v5.0/esp32c3/api-guides/jtag-debugging/index.html 22 | 23 | ## TODO 24 | 3. incorporate the led pwm into the current blinky state machine 25 | a. mutex for adc readings 26 | b. When it's time to blink look at the ADC reading and calculate a pwm 27 | 28 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/src/led_fsm.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::gpio::{AnyOutputPin, Output, PinDriver}; 2 | use esp_println::println; 3 | use statig::prelude::*; 4 | 5 | pub struct Blinky<'a> { 6 | pub led_pin: PinDriver<'a, AnyOutputPin, Output>, 7 | } 8 | 9 | // The event that will be handled by the state machine. 10 | pub enum Event { 11 | TimerElapsed, 12 | ButtonPressed, 13 | } 14 | #[derive(Debug)] 15 | pub enum State { 16 | LedOn, 17 | LedOff, 18 | NotBlinking, 19 | } 20 | 21 | pub enum Superstate { 22 | Blinking, 23 | } 24 | 25 | impl StateMachine for Blinky<'_> { 26 | type State = State; 27 | type Superstate<'a> = Superstate; 28 | type Event<'a> = Event; 29 | const INITIAL: State = State::LedOff; 30 | const ON_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, source, target| { 31 | println!("Transitioned from {source:?} to {target:?}"); 32 | }; 33 | } 34 | 35 | impl statig::State> for State { 36 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 37 | match self { 38 | State::LedOn => Blinky::led_on(event), 39 | State::LedOff => Blinky::led_off(event), 40 | State::NotBlinking => Blinky::not_blinking(event), 41 | } 42 | } 43 | 44 | fn superstate(&mut self) -> Option { 45 | match self { 46 | State::LedOn => Some(Superstate::Blinking), 47 | State::LedOff => Some(Superstate::Blinking), 48 | State::NotBlinking => None, 49 | } 50 | } 51 | 52 | fn call_entry_action(&mut self, blinky: &mut Blinky) { 53 | match self { 54 | State::LedOn => blinky.enter_led_on(), 55 | State::LedOff => blinky.enter_led_off(), 56 | _ => (), 57 | } 58 | } 59 | } 60 | 61 | impl statig::Superstate> for Superstate { 62 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 63 | match self { 64 | Superstate::Blinking => Blinky::blinking(event), 65 | } 66 | } 67 | } 68 | 69 | impl Blinky<'_> { 70 | fn enter_led_on(&mut self) { 71 | self.led_pin.set_high().unwrap(); 72 | } 73 | 74 | fn enter_led_off(&mut self) { 75 | self.led_pin.set_low().unwrap(); 76 | } 77 | 78 | fn led_on(event: &Event) -> Response { 79 | match event { 80 | Event::TimerElapsed => Transition(State::LedOff), 81 | _ => Super, 82 | } 83 | } 84 | 85 | fn led_off(event: &Event) -> Response { 86 | match event { 87 | Event::TimerElapsed => Transition(State::LedOn), 88 | _ => Super, 89 | } 90 | } 91 | 92 | fn blinking(event: &Event) -> Response { 93 | match event { 94 | Event::ButtonPressed => Transition(State::NotBlinking), 95 | _ => Super, 96 | } 97 | } 98 | 99 | fn not_blinking(event: &Event) -> Response { 100 | match event { 101 | Event::ButtonPressed => Transition(State::LedOn), 102 | _ => Super, 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate crossbeam; 2 | extern crate crossbeam_channel; 3 | 4 | use crossbeam_channel::bounded; 5 | use esp_idf_hal::ledc::config::TimerConfig; 6 | use esp_idf_hal::{ 7 | adc::{self, AdcDriver}, 8 | gpio::{InputPin, OutputPin, PinDriver}, 9 | ledc::*, 10 | prelude::*, 11 | }; 12 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 13 | use statig::prelude::*; 14 | use std::sync::Arc; 15 | 16 | mod led_fsm; 17 | mod tasks; 18 | 19 | fn main() { 20 | // It is necessary to call this function once. Otherwise some patches to the runtime 21 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 22 | esp_idf_sys::link_patches(); 23 | 24 | let peripherals = Peripherals::take().unwrap(); 25 | 26 | // Config GPIO for input and output 27 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 28 | let btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade_input()).unwrap(); 29 | // TODO: how to make the `btn` pin pull-up or pull-down. 30 | // LED controller config 31 | let config = TimerConfig::new().frequency(25.kHz().into()); 32 | let timer = Arc::new(LedcTimerDriver::new(peripherals.ledc.timer0, &config).unwrap()); 33 | let channel0 = LedcDriver::new( 34 | peripherals.ledc.channel0, 35 | timer.clone(), 36 | peripherals.pins.gpio7, 37 | ) 38 | .unwrap(); 39 | 40 | let max_duty = channel0.get_max_duty(); 41 | 42 | let led_fsm = led_fsm::Blinky { led_pin }.state_machine().init(); 43 | 44 | let (tx1, rx1) = bounded(1); 45 | 46 | let a1_ch4 = 47 | adc::AdcChannelDriver::<_, adc::Atten11dB>::new(peripherals.pins.gpio4).unwrap(); 48 | 49 | let adc1 = AdcDriver::new( 50 | peripherals.adc1, 51 | &adc::config::Config::new().calibration(true), 52 | ) 53 | .unwrap(); 54 | 55 | let _blinky_thread = std::thread::Builder::new() 56 | .stack_size(tasks::BLINKY_STACK_SIZE) 57 | .spawn(move || tasks::blinky_fsm_thread(led_fsm, rx1)) 58 | .unwrap(); 59 | 60 | let _button_thread = std::thread::Builder::new() 61 | .stack_size(tasks::BUTTON_STACK_SIZE) 62 | .spawn(move || tasks::button_thread(btn, tx1)) 63 | .unwrap(); 64 | 65 | let _adc_thread = std::thread::Builder::new() 66 | .stack_size(tasks::ADC_STACK_SIZE) 67 | .spawn(move || tasks::adc_thread(adc1, a1_ch4, max_duty, channel0)) 68 | .unwrap(); 69 | } 70 | -------------------------------------------------------------------------------- /WIP/ch06-blinky-adc/src/tasks.rs: -------------------------------------------------------------------------------- 1 | extern crate crossbeam; 2 | extern crate crossbeam_channel; 3 | 4 | use esp_idf_hal::{ 5 | adc::{self, AdcDriver, Atten11dB, *}, 6 | gpio::{AnyInputPin, Input, PinDriver, *}, 7 | ledc::*, 8 | }; 9 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 10 | use esp_println::println; 11 | use statig::InitializedStatemachine; 12 | use std::{thread, time::Duration}; 13 | 14 | use crate::led_fsm; 15 | 16 | pub static ADC_MAX_COUNTS: u32 = 2850; 17 | pub static BLINKY_STACK_SIZE: usize = 2000; 18 | pub static BUTTON_STACK_SIZE: usize = 2000; 19 | pub static ADC_STACK_SIZE: usize = 5000; 20 | 21 | pub fn button_thread(btn: PinDriver<'_, AnyInputPin, Input>, tx: crossbeam_channel::Sender) { 22 | let mut btn_state = true; 23 | loop { 24 | if btn.is_high() { 25 | if !btn_state { 26 | btn_state = true; 27 | 28 | tx.send(btn_state).unwrap(); 29 | } 30 | } else { 31 | btn_state = false; 32 | } 33 | 34 | thread::sleep(Duration::from_millis(100)); 35 | } 36 | } 37 | 38 | pub fn blinky_fsm_thread( 39 | mut fsm: InitializedStatemachine, 40 | rx: crossbeam_channel::Receiver, 41 | ) { 42 | loop { 43 | fsm.handle(&led_fsm::Event::TimerElapsed); 44 | match rx.try_recv() { 45 | Ok(_) => fsm.handle(&led_fsm::Event::ButtonPressed), 46 | Err(_) => {} 47 | } 48 | 49 | thread::sleep(Duration::from_millis(1000)); 50 | } 51 | } 52 | 53 | pub fn adc_thread( 54 | mut adc: AdcDriver, 55 | mut pin: adc::AdcChannelDriver>, 56 | max_duty: u32, 57 | mut channel: LedcDriver<'_>, 58 | ) where 59 | Atten11dB: Attenuation<::Adc>, 60 | { 61 | loop { 62 | // Read ADC and and set the LED PWM to the percentage of full scale 63 | match adc.read(&mut pin) { 64 | Ok(x) => { 65 | let pwm = (x as u32 * max_duty) / ADC_MAX_COUNTS; 66 | match channel.set_duty(pwm) { 67 | Ok(_x) => (), 68 | Err(e) => println!("err setting duty of led: {e}\n"), 69 | } 70 | } 71 | Err(e) => println!("err reading ADC: {e}\n"), 72 | } 73 | 74 | thread::sleep(Duration::from_millis(100)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /WIP/ch06-neopixel/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch06-neopixel/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch06-neopixel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "neopixel" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } 23 | crossbeam = "0.8" 24 | crossbeam-channel = "0.5" 25 | crossbeam-utils = "0.8" 26 | anyhow = "1" 27 | 28 | [build-dependencies] 29 | embuild = "0.31" 30 | anyhow = "1" 31 | -------------------------------------------------------------------------------- /WIP/ch06-neopixel/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch06-neopixel/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch06-neopixel/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch06-neopixel/src/neopixel.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Result}; 2 | use esp_idf_hal::rmt::*; 3 | use std::time::Duration; 4 | 5 | pub struct RGB { 6 | pub r: u8, 7 | pub g: u8, 8 | pub b: u8, 9 | } 10 | 11 | fn ns(nanos: u64) -> Duration { 12 | Duration::from_nanos(nanos) 13 | } 14 | 15 | pub fn neopixel(rgb: RGB, tx: &mut TxRmtDriver) -> Result<()> { 16 | // e.g. rgb: (1,2,4) 17 | // G R B 18 | // 7 0 7 0 7 0 19 | // 00000010 00000001 00000100 20 | let color: u32 = ((rgb.g as u32) << 16) | ((rgb.r as u32) << 8) | rgb.b as u32; 21 | let ticks_hz = tx.counter_clock().unwrap(); 22 | let t0h = Pulse::new_with_duration(ticks_hz, PinState::High, &ns(350)).unwrap(); 23 | let t0l = Pulse::new_with_duration(ticks_hz, PinState::Low, &ns(800)).unwrap(); 24 | let t1h = Pulse::new_with_duration(ticks_hz, PinState::High, &ns(700)).unwrap(); 25 | let t1l = Pulse::new_with_duration(ticks_hz, PinState::Low, &ns(600)).unwrap(); 26 | let mut signal = FixedLengthSignal::<24>::new(); 27 | for i in (0..24).rev() { 28 | let p = 2_u32.pow(i); 29 | let bit = p & color != 0; 30 | let (high_pulse, low_pulse) = if bit { (t1h, t1l) } else { (t0h, t0l) }; 31 | signal 32 | .set(23 - i as usize, &(high_pulse, low_pulse)) 33 | .unwrap(); 34 | } 35 | tx.start_blocking(&signal).unwrap(); 36 | 37 | Ok(()) 38 | } 39 | 40 | /// Converts hue, saturation, value to RGB 41 | pub fn hsv2rgb(h: u32, s: u32, v: u32) -> Result { 42 | if h > 360 || s > 100 || v > 100 { 43 | bail!("The given HSV values are not in valid range"); 44 | } 45 | let s = s as f64 / 100.0; 46 | let v = v as f64 / 100.0; 47 | let c = s * v; 48 | let x = c * (1.0 - (((h as f64 / 60.0) % 2.0) - 1.0).abs()); 49 | let m = v - c; 50 | let (r, g, b); 51 | if h < 60 { 52 | r = c; 53 | g = x; 54 | b = 0.0; 55 | } else if h >= 60 && h < 120 { 56 | r = x; 57 | g = c; 58 | b = 0.0; 59 | } else if h >= 120 && h < 180 { 60 | r = 0.0; 61 | g = c; 62 | b = x; 63 | } else if h >= 180 && h < 240 { 64 | r = 0.0; 65 | g = x; 66 | b = c; 67 | } else if h >= 240 && h < 300 { 68 | r = x; 69 | g = 0.0; 70 | b = c; 71 | } else { 72 | r = c; 73 | g = 0.0; 74 | b = x; 75 | } 76 | 77 | Ok(RGB { 78 | r: ((r + m) * 255.0) as u8, 79 | g: ((g + m) * 255.0) as u8, 80 | b: ((b + m) * 255.0) as u8, 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wifi_mqtt" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | esp-idf-svc = "0.45" 23 | embedded-svc = "0.24" 24 | hex = "0.4.3" 25 | serde = {version = "1.0.152", features = ["derive"]} 26 | embedded-hal-0-2 = { package = "embedded-hal", version = "0.2.7", features = ["unproven"] } 27 | crossbeam = "0.8" 28 | crossbeam-channel = "0.5" 29 | crossbeam-utils = "0.8" 30 | anyhow = "1" 31 | mqtt-protocol = "0.11" 32 | 33 | [build-dependencies] 34 | embuild = "0.31" 35 | anyhow = "1" 36 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/README.md: -------------------------------------------------------------------------------- 1 | In this chapter we will be using [Crossbeam AtomicCell](https://docs.rs/crossbeam/latest/crossbeam/atomic/struct.AtomicCell.html) to share data between threads. 2 | 3 | We will create a thread to read an [analog to digital](https://www.electronics-tutorials.ws/combination/analogue-to-digital-converter.html) reading, then the LED thread will take that reading and 4 | use it to adjust the brightness of the LED by controlling the PWM. 5 | 6 | In order to control the PWM of the LED we will need to use the ESP32-C3 [led controller](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html). 7 | 8 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/src/cloud.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Result}; 2 | use embedded_svc::mqtt::client::{Connection, Event, MessageImpl, QoS}; 3 | use embedded_svc::{utils::mqtt::client::ConnState, wifi::*}; 4 | use esp_idf_hal::peripheral; 5 | use esp_idf_svc::mqtt::client::{EspMqttClient, LwtConfiguration, MqttClientConfiguration}; 6 | use esp_idf_svc::{eventloop::*, netif::*, wifi::*}; 7 | use esp_idf_sys::esp_efuse_mac_get_default; 8 | use esp_idf_sys::EspError; 9 | use esp_println::println; 10 | use serde::Serialize; 11 | use std::{env, thread, time::Duration}; 12 | 13 | const SSID: &str = env!("WIFI_SSID"); 14 | const PASS: &str = env!("WIFI_PASS"); 15 | 16 | #[derive(Serialize, Debug)] 17 | struct MqttData { 18 | distance: u16, 19 | temperature: f32, 20 | tds: f32, 21 | } 22 | 23 | #[cfg(not(feature = "qemu"))] 24 | pub fn wifi( 25 | modem: impl peripheral::Peripheral

+ 'static, 26 | sysloop: EspSystemEventLoop, 27 | ) -> Result>> { 28 | use std::net::Ipv4Addr; 29 | 30 | let mut wifi = Box::new(EspWifi::new(modem, sysloop.clone(), None)?); 31 | 32 | println!("Wifi created, about to scan"); 33 | 34 | let ap_infos = wifi.scan()?; 35 | 36 | let ours = ap_infos.into_iter().find(|a| a.ssid == SSID); 37 | 38 | let channel = if let Some(ours) = ours { 39 | println!( 40 | "Found configured access point {} on channel {}", 41 | SSID, ours.channel 42 | ); 43 | Some(ours.channel) 44 | } else { 45 | println!( 46 | "Configured access point {} not found during scanning, will go with unknown channel", 47 | SSID 48 | ); 49 | None 50 | }; 51 | 52 | wifi.set_configuration(&Configuration::Client(ClientConfiguration { 53 | ssid: SSID.into(), 54 | password: PASS.into(), 55 | channel, 56 | ..Default::default() 57 | }))?; 58 | 59 | wifi.start()?; 60 | 61 | println!("Starting wifi..."); 62 | 63 | if !WifiWait::new(&sysloop)? 64 | .wait_with_timeout(Duration::from_secs(20), || wifi.is_started().unwrap()) 65 | { 66 | bail!("Wifi did not start"); 67 | } 68 | 69 | println!("Connecting wifi..."); 70 | 71 | wifi.connect()?; 72 | 73 | if !EspNetifWait::new::(wifi.sta_netif(), &sysloop)?.wait_with_timeout( 74 | Duration::from_secs(20), 75 | || { 76 | wifi.is_connected().unwrap() 77 | && wifi.sta_netif().get_ip_info().unwrap().ip != Ipv4Addr::new(0, 0, 0, 0) 78 | }, 79 | ) { 80 | bail!("Wifi did not connect or did not receive a DHCP lease"); 81 | } 82 | 83 | let ip_info = wifi.sta_netif().get_ip_info()?; 84 | 85 | println!("Wifi DHCP info: {:?}", ip_info); 86 | 87 | Ok(wifi) 88 | } 89 | 90 | pub fn get_client(url: &str) -> Result>, EspError> { 91 | let client_id = format!("fishtank-rust_{}", get_unique_id()); 92 | let conf = MqttClientConfiguration { 93 | client_id: Some(&client_id), 94 | keep_alive_interval: Some(std::time::Duration::new(60, 0)), 95 | lwt: Some(LwtConfiguration { 96 | topic: "fishtank/status", 97 | payload: b"offline", 98 | qos: QoS::AtLeastOnce, 99 | retain: true, 100 | }), 101 | ..Default::default() 102 | }; 103 | 104 | let (mut client, mut connection) = EspMqttClient::new_with_conn(url, &conf).unwrap(); 105 | 106 | thread::spawn(move || { 107 | while let Some(msg) = connection.next() { 108 | let event = msg.as_ref().unwrap(); 109 | match event { 110 | Event::Received(_msg) => {} 111 | Event::Connected(_) => {} 112 | Event::Disconnected => {} 113 | Event::Subscribed(_x) => { 114 | // Do nothing 115 | } 116 | _event => println!("Got unknown MQTT event"), 117 | } 118 | } 119 | }); 120 | client 121 | .publish("fishtank/status", QoS::AtLeastOnce, true, b"online") 122 | .unwrap(); 123 | Ok(client) 124 | } 125 | 126 | pub fn get_unique_id() -> String { 127 | let mut mac: [u8; 6] = [0; 6]; 128 | unsafe { 129 | let ptr = &mut mac as *mut u8; 130 | esp_efuse_mac_get_default(ptr); 131 | } 132 | hex::encode(mac) 133 | } 134 | 135 | fn publish_data(data: MqttData, client: &mut EspMqttClient>) { 136 | let data = serde_json::to_string(&data).unwrap(); 137 | client 138 | .publish("fishtank/sensors", QoS::AtLeastOnce, false, data.as_bytes()) 139 | .unwrap(); 140 | } 141 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/src/tasks.rs: -------------------------------------------------------------------------------- 1 | use crossbeam_utils::atomic::AtomicCell; 2 | use esp_idf_hal::{ 3 | adc::{self, *}, 4 | gpio::{ADCPin, AnyIOPin, Input, PinDriver}, 5 | ledc::LedcDriver, 6 | }; 7 | use esp_println::println; 8 | use std::{sync::Arc, thread, time::Duration}; 9 | 10 | static ADC_MAX_COUNTS: u32 = 2850; 11 | 12 | pub fn adc_thread( 13 | adc_mutex: Arc>, 14 | mut adc: AdcDriver, 15 | mut pin: adc::AdcChannelDriver>, 16 | ) where 17 | Atten11dB: Attenuation<::Adc>, 18 | { 19 | loop { 20 | // Read ADC and and set the LED PWM to the percentage of full scale 21 | match adc.read(&mut pin) { 22 | Ok(x) => { 23 | adc_mutex.store(x); 24 | } 25 | 26 | Err(e) => println!("err reading ADC: {e}\n"), 27 | } 28 | 29 | thread::sleep(Duration::from_millis(100)); 30 | } 31 | } 32 | 33 | // Thread function that will blink the LED on/off every 500ms 34 | pub fn blinky_thread( 35 | rx: crossbeam_channel::Receiver, 36 | adc_mutex: Arc>, 37 | mut channel: LedcDriver<'_>, 38 | ) { 39 | let mut blinky_status = false; 40 | let max_duty = channel.get_max_duty(); 41 | loop { 42 | // Watch for button press messages 43 | match rx.try_recv() { 44 | Ok(x) => { 45 | blinky_status = x; 46 | } 47 | Err(_) => {} 48 | } 49 | 50 | // blinky if the button was pressed 51 | if blinky_status { 52 | match channel.set_duty(0) { 53 | Ok(_x) => (), 54 | Err(e) => println!("err setting duty of led: {e}\n"), 55 | } 56 | println!("LED ON"); 57 | thread::sleep(Duration::from_millis(1000)); 58 | 59 | match channel.set_duty(max_duty) { 60 | Ok(_x) => (), 61 | Err(e) => println!("err setting duty of led: {e}\n"), 62 | } 63 | println!("LED OFF"); 64 | thread::sleep(Duration::from_millis(1000)); 65 | } else { 66 | let duty = adc_mutex.load() as u32; 67 | let pwm = (duty as u32 * max_duty) / ADC_MAX_COUNTS; 68 | match channel.set_duty(pwm) { 69 | Ok(_x) => (), 70 | Err(e) => println!("err setting duty of led: {e}\n"), 71 | } 72 | } 73 | 74 | thread::sleep(Duration::from_millis(100)); 75 | } 76 | } 77 | 78 | pub fn button_thread(btn_pin: PinDriver, tx: crossbeam_channel::Sender) { 79 | let mut btn_status = false; 80 | 81 | loop { 82 | if btn_pin.is_high() { 83 | if !btn_status { 84 | btn_status = true; 85 | println!("BUTTON ON"); 86 | tx.send(btn_status).unwrap(); 87 | } 88 | } else { 89 | if btn_status { 90 | btn_status = false; 91 | println!("BUTTON OFF"); 92 | tx.send(btn_status).unwrap(); 93 | } 94 | } 95 | thread::sleep(Duration::from_millis(100)); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /WIP/ch06-wifi-mqtt/src/wifi.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Context}; 2 | use embedded_svc::wifi::{ClientConfiguration, Configuration}; 3 | use esp_idf_hal::modem::WifiModem; 4 | use esp_idf_svc::{ 5 | eventloop::EspEventLoop, 6 | netif::{EspNetif, EspNetifWait}, 7 | nvs::EspDefaultNvsPartition, 8 | wifi::{EspWifi, WifiWait}, 9 | }; 10 | use esp_println::println; 11 | use std::{net::Ipv4Addr, time::Duration}; 12 | 13 | pub fn connect(wifi_ssid: &str, wifi_pass: &str) -> anyhow::Result> { 14 | let sys_loop = EspEventLoop::take().unwrap(); 15 | let modem = unsafe { WifiModem::new() }; 16 | let nvs = EspDefaultNvsPartition::take().unwrap(); 17 | let mut wifi = EspWifi::new(modem, sys_loop.clone(), Some(nvs))?; 18 | 19 | println!("Wifi created, scanning available networks..."); 20 | 21 | let available_networks = wifi.scan()?; 22 | let target_network = available_networks 23 | .iter() 24 | .find(|network| network.ssid == wifi_ssid) 25 | .with_context(|| format!("Failed to detect the target network ({wifi_ssid})"))?; 26 | 27 | println!("Scan successfull, found '{wifi_ssid}', with config: {target_network:#?}"); 28 | 29 | wifi.set_configuration(&Configuration::Client(ClientConfiguration { 30 | ssid: wifi_ssid.into(), 31 | password: wifi_pass.into(), 32 | auth_method: target_network.auth_method, 33 | bssid: Some(target_network.bssid), 34 | channel: Some(target_network.channel), 35 | }))?; 36 | 37 | wifi.start()?; 38 | if !WifiWait::new(&sys_loop)? 39 | .wait_with_timeout(Duration::from_secs(20), || wifi.is_started().unwrap()) 40 | { 41 | bail!("Wifi did not start"); 42 | } 43 | 44 | wifi.connect()?; 45 | 46 | if !EspNetifWait::new::(wifi.sta_netif(), &sys_loop)?.wait_with_timeout( 47 | Duration::from_secs(20), 48 | || { 49 | wifi.driver().is_connected().unwrap() 50 | && wifi.sta_netif().get_ip_info().unwrap().ip != Ipv4Addr::new(0, 0, 0, 0) 51 | }, 52 | ) { 53 | bail!("Wifi did not connect or did not receive a DHCP lease"); 54 | } 55 | 56 | let ip_info = wifi.sta_netif().get_ip_info()?; 57 | 58 | println!("Wifi DHCP info: {:?}", ip_info); 59 | 60 | Ok(wifi) 61 | } 62 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wifi-mqtt" 3 | version = "0.1.0" 4 | authors = ["Shane"] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | esp-idf-svc = "0.45" 23 | embedded-svc = "0.24" 24 | statig = "0.2.0" 25 | crossbeam = "0.8" 26 | serde = { version = "1", features = ["derive"] } 27 | hex = "0.4.3" 28 | crossbeam-channel = "0.5" 29 | anyhow = { version = "1", features = ["backtrace"] } 30 | 31 | 32 | [build-dependencies] 33 | embuild = "0.31" 34 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/README.md: -------------------------------------------------------------------------------- 1 | # Blinky ADC 2 | 3 | In this example we'll use ADC values to blinky the LED at a certain PWM based on the ADC reading. 4 | 5 | Now that we have more tasks building up we should move them to another file `tasks.rs`. To use 6 | those tasks in main we'll just import with: 7 | 8 | ```rust 9 | mod tasks; 10 | ``` 11 | 12 | And to use `led_fsm.rs` functions in `tasks.rs` we'll need to use `led_fsm`: 13 | ```rust 14 | use crate::led_fsm; 15 | ``` 16 | 17 | 18 | 19 | 20 | ## setup debugging 21 | https://docs.espressif.com/projects/esp-idf/en/v5.0/esp32c3/api-guides/jtag-debugging/index.html 22 | 23 | ## TODO 24 | 3. incorporate the led pwm into the current blinky state machine 25 | a. mutex for adc readings 26 | b. When it's time to blink look at the ADC reading and calculate a pwm 27 | 28 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/src/cloud.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Result}; 2 | use embedded_svc::mqtt::client::{Connection, Event, MessageImpl, QoS}; 3 | use embedded_svc::{utils::mqtt::client::ConnState, wifi::*}; 4 | use esp_idf_hal::peripheral; 5 | use esp_idf_svc::mqtt::client::{EspMqttClient, LwtConfiguration, MqttClientConfiguration}; 6 | use esp_idf_svc::{eventloop::*, netif::*, wifi::*}; 7 | use esp_idf_sys::esp_efuse_mac_get_default; 8 | use esp_idf_sys::EspError; 9 | use esp_println::println; 10 | use std::{env, thread, time::Duration}; 11 | 12 | const SSID: &str = env!("WIFI_SSID"); 13 | const PASS: &str = env!("WIFI_PASS"); 14 | const _MQTT_URL: &str = env!("MQTT_URL"); 15 | 16 | #[cfg(not(feature = "qemu"))] 17 | pub fn wifi( 18 | modem: impl peripheral::Peripheral

+ 'static, 19 | sysloop: EspSystemEventLoop, 20 | ) -> Result>> { 21 | use std::net::Ipv4Addr; 22 | 23 | let mut wifi = Box::new(EspWifi::new(modem, sysloop.clone(), None)?); 24 | 25 | println!("Wifi created, about to scan"); 26 | 27 | let ap_infos = wifi.scan()?; 28 | 29 | let ours = ap_infos.into_iter().find(|a| a.ssid == SSID); 30 | 31 | let channel = if let Some(ours) = ours { 32 | println!( 33 | "Found configured access point {} on channel {}", 34 | SSID, ours.channel 35 | ); 36 | Some(ours.channel) 37 | } else { 38 | println!( 39 | "Configured access point {} not found during scanning, will go with unknown channel", 40 | SSID 41 | ); 42 | None 43 | }; 44 | 45 | wifi.set_configuration(&Configuration::Client(ClientConfiguration { 46 | ssid: SSID.into(), 47 | password: PASS.into(), 48 | channel, 49 | ..Default::default() 50 | }))?; 51 | 52 | wifi.start()?; 53 | 54 | println!("Starting wifi..."); 55 | 56 | if !WifiWait::new(&sysloop)? 57 | .wait_with_timeout(Duration::from_secs(20), || wifi.is_started().unwrap()) 58 | { 59 | bail!("Wifi did not start"); 60 | } 61 | 62 | println!("Connecting wifi..."); 63 | 64 | wifi.connect()?; 65 | 66 | if !EspNetifWait::new::(wifi.sta_netif(), &sysloop)?.wait_with_timeout( 67 | Duration::from_secs(20), 68 | || { 69 | wifi.is_connected().unwrap() 70 | && wifi.sta_netif().get_ip_info().unwrap().ip != Ipv4Addr::new(0, 0, 0, 0) 71 | }, 72 | ) { 73 | bail!("Wifi did not connect or did not receive a DHCP lease"); 74 | } 75 | 76 | let ip_info = wifi.sta_netif().get_ip_info()?; 77 | 78 | println!("Wifi DHCP info: {:?}", ip_info); 79 | 80 | Ok(wifi) 81 | } 82 | 83 | pub fn get_client(url: &str) -> Result>, EspError> { 84 | let client_id = format!("fishtank-rust_{}", get_unique_id()); 85 | let conf = MqttClientConfiguration { 86 | client_id: Some(&client_id), 87 | keep_alive_interval: Some(std::time::Duration::new(60, 0)), 88 | lwt: Some(LwtConfiguration { 89 | topic: "fishtank/status", 90 | payload: b"offline", 91 | qos: QoS::AtLeastOnce, 92 | retain: true, 93 | }), 94 | ..Default::default() 95 | }; 96 | 97 | let (mut client, mut connection) = EspMqttClient::new_with_conn(url, &conf).unwrap(); 98 | 99 | thread::spawn(move || { 100 | while let Some(msg) = connection.next() { 101 | let event = msg.as_ref().unwrap(); 102 | match event { 103 | Event::Received(_msg) => {} 104 | Event::Connected(_) => {} 105 | Event::Disconnected => {} 106 | Event::Subscribed(_x) => { 107 | // Do nothing 108 | } 109 | _event => println!("Got unknown MQTT event"), 110 | } 111 | } 112 | }); 113 | client 114 | .publish("fishtank/status", QoS::AtLeastOnce, true, b"online") 115 | .unwrap(); 116 | Ok(client) 117 | } 118 | 119 | pub fn get_unique_id() -> String { 120 | let mut mac: [u8; 6] = [0; 6]; 121 | unsafe { 122 | let ptr = &mut mac as *mut u8; 123 | esp_efuse_mac_get_default(ptr); 124 | } 125 | hex::encode(mac) 126 | } 127 | 128 | fn publish_data(data: MqttData, client: &mut EspMqttClient>) { 129 | let data = serde_json::to_string(&data).unwrap(); 130 | client 131 | .publish("fishtank/sensors", QoS::AtLeastOnce, false, data.as_bytes()) 132 | .unwrap(); 133 | } 134 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/src/led_fsm.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_hal::gpio::{AnyOutputPin, Output, PinDriver}; 2 | use esp_println::println; 3 | use statig::prelude::*; 4 | 5 | // #[derive(Debug, Default)] 6 | pub struct Blinky<'a> { 7 | pub led_pin: PinDriver<'a, AnyOutputPin, Output>, 8 | } 9 | 10 | // The event that will be handled by the state machine. 11 | pub enum Event { 12 | TimerElapsed, 13 | ButtonPressed, 14 | } 15 | #[derive(Debug)] 16 | pub enum State { 17 | LedOn, 18 | LedOff, 19 | NotBlinking, 20 | } 21 | 22 | pub enum Superstate { 23 | Blinking, 24 | } 25 | 26 | impl StateMachine for Blinky<'_> { 27 | type State = State; 28 | type Superstate<'a> = Superstate; 29 | type Event<'a> = Event; 30 | const INITIAL: State = State::LedOff; 31 | const ON_TRANSITION: fn(&mut Self, &Self::State, &Self::State) = |_, source, target| { 32 | println!("Transitioned from {source:?} to {target:?}"); 33 | }; 34 | } 35 | 36 | impl statig::State> for State { 37 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 38 | match self { 39 | State::LedOn => Blinky::led_on(event), 40 | State::LedOff => Blinky::led_off(event), 41 | State::NotBlinking => Blinky::not_blinking(event), 42 | } 43 | } 44 | 45 | fn superstate(&mut self) -> Option { 46 | match self { 47 | State::LedOn => Some(Superstate::Blinking), 48 | State::LedOff => Some(Superstate::Blinking), 49 | State::NotBlinking => None, 50 | } 51 | } 52 | 53 | fn call_entry_action(&mut self, blinky: &mut Blinky) { 54 | match self { 55 | State::LedOn => blinky.enter_led_on(), 56 | State::LedOff => blinky.enter_led_off(), 57 | _ => (), 58 | } 59 | } 60 | } 61 | 62 | impl statig::Superstate> for Superstate { 63 | fn call_handler(&mut self, _blinky: &mut Blinky, event: &Event) -> Response { 64 | match self { 65 | Superstate::Blinking => Blinky::blinking(event), 66 | } 67 | } 68 | } 69 | 70 | impl Blinky<'_> { 71 | fn enter_led_on(&mut self) { 72 | self.led_pin.set_high().unwrap(); 73 | } 74 | 75 | fn enter_led_off(&mut self) { 76 | self.led_pin.set_low().unwrap(); 77 | } 78 | 79 | fn led_on(event: &Event) -> Response { 80 | match event { 81 | Event::TimerElapsed => Transition(State::LedOff), 82 | _ => Super, 83 | } 84 | } 85 | 86 | fn led_off(event: &Event) -> Response { 87 | match event { 88 | Event::TimerElapsed => Transition(State::LedOn), 89 | _ => Super, 90 | } 91 | } 92 | 93 | fn blinking(event: &Event) -> Response { 94 | match event { 95 | Event::ButtonPressed => Transition(State::NotBlinking), 96 | _ => Super, 97 | } 98 | } 99 | 100 | fn not_blinking(event: &Event) -> Response { 101 | match event { 102 | Event::ButtonPressed => Transition(State::LedOn), 103 | _ => Super, 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate crossbeam; 2 | extern crate crossbeam_channel; 3 | 4 | use crossbeam_channel::bounded; 5 | use esp_idf_hal::{ 6 | adc::{self, AdcDriver}, 7 | gpio::{InputPin, PinDriver, *}, 8 | ledc::{config::TimerConfig, *}, 9 | prelude::*, 10 | }; 11 | use esp_idf_svc::eventloop::*; 12 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 13 | use esp_println::println; 14 | use serde::Serialize; 15 | use statig::prelude::*; 16 | use std::sync::Arc; 17 | 18 | mod cloud; 19 | mod led_fsm; 20 | mod tasks; 21 | 22 | #[derive(Serialize, Debug)] 23 | struct MqttData { 24 | distance: u16, 25 | temperature: f32, 26 | tds: f32, 27 | } 28 | 29 | const MQTT_URL: &str = env!("MQTT_URL"); 30 | 31 | fn main() { 32 | // It is necessary to call this function once. Otherwise some patches to the runtime 33 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 34 | esp_idf_sys::link_patches(); 35 | 36 | let peripherals = Peripherals::take().unwrap(); 37 | let (tx1, rx1) = bounded(1); // make channel to pass data 38 | 39 | // Config GPIO for input and output that will be passed to FSM 40 | let led_pin = PinDriver::output(peripherals.pins.gpio8.downgrade_output()).unwrap(); 41 | let btn_pin = PinDriver::input(peripherals.pins.gpio6.downgrade_input()).unwrap(); 42 | // TODO: how to make the `btn` pin pull-up or pull-down. 43 | let led_fsm = led_fsm::Blinky { led_pin }.state_machine().init(); 44 | 45 | // LED controller config 46 | let config = TimerConfig::new().frequency(25.kHz().into()); 47 | let timer = Arc::new(LedcTimerDriver::new(peripherals.ledc.timer0, &config).unwrap()); 48 | let channel0 = LedcDriver::new( 49 | peripherals.ledc.channel0, 50 | timer.clone(), 51 | peripherals.pins.gpio7, 52 | ) 53 | .unwrap(); 54 | let max_duty = channel0.get_max_duty(); 55 | // ADC config to change LED pwm 56 | let a1_ch4 = 57 | adc::AdcChannelDriver::<_, adc::Atten11dB>::new(peripherals.pins.gpio4).unwrap(); 58 | let adc1 = AdcDriver::new( 59 | peripherals.adc1, 60 | &adc::config::Config::new().calibration(true), 61 | ) 62 | .unwrap(); 63 | 64 | // Start WIFI and get MQTT client 65 | let sysloop = EspSystemEventLoop::take().unwrap(); 66 | let _wifi = cloud::wifi(peripherals.modem, sysloop).unwrap(); 67 | let mut _client = cloud::get_client(MQTT_URL).unwrap(); 68 | 69 | // Initialize threads 70 | let _blinky_thread = std::thread::Builder::new() 71 | .stack_size(tasks::BLINKY_STACK_SIZE) 72 | .spawn(move || tasks::blinky_fsm_thread(led_fsm, rx1)) 73 | .unwrap(); 74 | 75 | let _button_thread = std::thread::Builder::new() 76 | .stack_size(tasks::BUTTON_STACK_SIZE) 77 | .spawn(move || tasks::button_thread(btn_pin, tx1)) 78 | .unwrap(); 79 | 80 | let _adc_thread = std::thread::Builder::new() 81 | .stack_size(tasks::ADC_STACK_SIZE) 82 | .spawn(move || tasks::adc_thread(adc1, a1_ch4, max_duty, channel0)) 83 | .unwrap(); 84 | } 85 | -------------------------------------------------------------------------------- /WIP/ch07-blinky-mqtt/src/tasks.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(unused_variables, unused_imports)] 3 | extern crate crossbeam; 4 | extern crate crossbeam_channel; 5 | 6 | use crossbeam_channel::bounded; 7 | use esp_idf_hal::ledc::config::TimerConfig; 8 | use esp_idf_hal::{ 9 | adc::{self, config::Config, AdcDriver, Atten11dB, *}, 10 | gpio::{ 11 | self, AnyInputPin, AnyOutputPin, Input, InputMode, InputPin, Output, OutputPin, PinDriver, 12 | *, 13 | }, 14 | ledc::*, 15 | prelude::*, 16 | }; 17 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 18 | use esp_println::println; 19 | use statig::{prelude::*, InitializedStatemachine}; 20 | use std::{ 21 | sync::{mpsc::*, Arc}, 22 | thread, 23 | time::Duration, 24 | }; 25 | 26 | use crate::led_fsm; 27 | 28 | pub static ADC_MAX_COUNTS: u32 = 2850; 29 | pub static BLINKY_STACK_SIZE: usize = 2000; 30 | pub static BUTTON_STACK_SIZE: usize = 2000; 31 | pub static ADC_STACK_SIZE: usize = 5000; 32 | 33 | pub fn button_thread( 34 | btn_pin: PinDriver<'_, AnyInputPin, Input>, 35 | tx: crossbeam_channel::Sender, 36 | ) { 37 | let mut btn_state = true; 38 | loop { 39 | if btn_pin.is_high() { 40 | if !btn_state { 41 | btn_state = true; 42 | tx.send(btn_state).unwrap(); 43 | } 44 | } else { 45 | btn_state = false; 46 | } 47 | 48 | thread::sleep(Duration::from_millis(100)); 49 | } 50 | } 51 | 52 | pub fn blinky_fsm_thread( 53 | mut fsm: InitializedStatemachine, 54 | rx: crossbeam_channel::Receiver, 55 | ) { 56 | loop { 57 | fsm.handle(&led_fsm::Event::TimerElapsed); 58 | match rx.try_recv() { 59 | Ok(_) => fsm.handle(&led_fsm::Event::ButtonPressed), 60 | Err(_) => {} 61 | } 62 | 63 | thread::sleep(Duration::from_millis(1000)); 64 | } 65 | } 66 | 67 | pub fn adc_thread( 68 | mut adc: AdcDriver, 69 | mut pin: adc::AdcChannelDriver>, 70 | max_duty: u32, 71 | mut channel: LedcDriver<'_>, 72 | ) where 73 | Atten11dB: Attenuation<::Adc>, 74 | { 75 | loop { 76 | // Read ADC and and set the LED PWM to the percentage of full scale 77 | match adc.read(&mut pin) { 78 | Ok(x) => { 79 | let pwm = (x as u32 * max_duty) / ADC_MAX_COUNTS; 80 | match channel.set_duty(pwm) { 81 | Ok(x) => (), 82 | Err(e) => println!("err setting duty of led: {e}\n"), 83 | } 84 | } 85 | Err(e) => println!("err reading ADC: {e}\n"), 86 | } 87 | 88 | thread::sleep(Duration::from_millis(100)); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /WIP/p4-neopixel/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/p4-neopixel/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/p4-neopixel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "neopixel" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.32", features = ["binstart"] } 20 | esp-idf-hal = "0.40" 21 | esp-println = { version = "0.3.1", features = ["esp32c3"] } 22 | anyhow = "1" 23 | 24 | [build-dependencies] 25 | embuild = "0.31" 26 | -------------------------------------------------------------------------------- /WIP/p4-neopixel/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/p4-neopixel/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/p4-neopixel/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/wifi/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # Uncomment the relevant target for your chip here (ESP32, ESP32-S2, ESP32-S3 or ESP32-C3) 3 | #target = "xtensa-esp32-espidf" 4 | #target = "xtensa-esp32s2-espidf" 5 | #target = "xtensa-esp32s3-espidf" 6 | target = "riscv32imc-esp-espidf" 7 | 8 | [target.xtensa-esp32-espidf] 9 | linker = "ldproxy" 10 | runner = "espflash flash --monitor" 11 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 12 | 13 | [target.xtensa-esp32s2-espidf] 14 | linker = "ldproxy" 15 | runner = "espflash flash --monitor" 16 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 17 | 18 | [target.xtensa-esp32s3-espidf] 19 | linker = "ldproxy" 20 | runner = "espflash flash --monitor" 21 | #rustflags = ["--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 22 | 23 | [target.riscv32imc-esp-espidf] 24 | linker = "ldproxy" 25 | runner = "espflash flash --monitor" 26 | # Future - necessary for the experimental "native build" of esp-idf-sys with ESP32C3. See also https://github.com/ivmarkov/embuild/issues/16 27 | # For ESP-IDF 5 add `espidf_time64` and for earlier versions - remove this flag: https://github.com/esp-rs/rust/issues/110 28 | rustflags = ["-C", "default-linker-libraries"] 29 | 30 | [unstable] 31 | 32 | build-std = ["std", "panic_abort"] 33 | #build-std-features = ["panic_immediate_abort"] # Required for older ESP-IDF versions without a realpath implementation 34 | 35 | [env] 36 | # Note: these variables are not used when using pio builder (`cargo build --features pio`) 37 | # Builds against ESP-IDF stable (v4.4) 38 | ESP_IDF_VERSION = "release/v4.4" 39 | # Builds against ESP-IDF master (mainline) 40 | #ESP_IDF_VERSION = "master" 41 | -------------------------------------------------------------------------------- /WIP/wifi/.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /.embuild 3 | /target 4 | /Cargo.lock 5 | -------------------------------------------------------------------------------- /WIP/wifi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "blinky-wifi" 3 | version = "0.1.0" 4 | authors = ["Shane Mattner "] 5 | edition = "2021" 6 | resolver = "2" 7 | 8 | [profile.release] 9 | opt-level = "s" 10 | 11 | [profile.dev] 12 | debug = true # Symbols are nice and they don't increase the size on Flash 13 | opt-level = "z" 14 | 15 | [features] 16 | pio = ["esp-idf-sys/pio"] 17 | 18 | [dependencies] 19 | esp-idf-sys = { version = "0.31", features = ["binstart"] } 20 | esp-idf-hal = "0.38" 21 | embedded-hal = "0.2" 22 | esp-idf-svc="0.42" 23 | nb = "1.0.0" 24 | log="0.4" 25 | embedded-svc = "0.22" 26 | anyhow = "1" 27 | statig = "0.2.0" 28 | 29 | 30 | [build-dependencies] 31 | embuild = "0.30.4" 32 | anyhow = "1" 33 | 34 | -------------------------------------------------------------------------------- /WIP/wifi/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | export RUST_ESP32_STD_DEMO_WIFI_SSID='yourSSID' 3 | export RUST_ESP32_STD_DEMO_WIFI_PASS='yourPASS' 4 | cargo build 5 | espflash /dev/ttyACM0 target/riscv32imc-esp-espidf/debug/ch04-blinky-wifi 6 | espmonitor /dev/ttyACM0 7 | ``` -------------------------------------------------------------------------------- /WIP/wifi/build.rs: -------------------------------------------------------------------------------- 1 | // Necessary because of this issue: https://github.com/rust-lang/cargo/issues/9641 2 | fn main() -> Result<(), Box> { 3 | embuild::build::CfgArgs::output_propagated("ESP_IDF")?; 4 | embuild::build::LinkArgs::output_propagated("ESP_IDF")?; 5 | Ok(()) 6 | } 7 | -------------------------------------------------------------------------------- /WIP/wifi/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly" -------------------------------------------------------------------------------- /WIP/wifi/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) 2 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000 3 | 4 | # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). 5 | # This allows to use 1 ms granuality for thread sleeps (10 ms by default). 6 | #CONFIG_FREERTOS_HZ=1000 7 | 8 | # Workaround for https://github.com/espressif/esp-idf/issues/7631 9 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n 10 | #CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=n 11 | -------------------------------------------------------------------------------- /WIP/wifi/src/main.rs: -------------------------------------------------------------------------------- 1 | use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported 2 | 3 | use anyhow::bail; 4 | use anyhow::Result; 5 | use embedded_hal::digital::v2::OutputPin; 6 | use embedded_svc::wifi::*; 7 | use esp_idf_hal::{gpio::*, prelude::*}; 8 | use esp_idf_svc::netif::*; 9 | use esp_idf_svc::nvs::*; 10 | use esp_idf_svc::wifi::*; 11 | use esp_idf_svc::wifi::*; 12 | use statig::prelude::*; 13 | use std::sync::Arc; 14 | use std::{thread, time::Duration}; 15 | 16 | mod wifi; 17 | 18 | static BLINKY_STACK_SIZE: usize = 5000; 19 | 20 | fn main() { 21 | // It is necessary to call this function once. Otherwise some patches to the runtime 22 | // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 23 | esp_idf_sys::link_patches(); 24 | 25 | let peripherals = Peripherals::take().unwrap(); 26 | 27 | match wifi::test_wifi() { 28 | Ok(x) => println!("IP: {}", x), 29 | Err(x) => println!("{}", x), 30 | } 31 | // let mut led = PinDriver::output(peripherals.pins.gpio8).unwrap(); 32 | // let mut state_machine = Blinky { led }.state_machine().init(); 33 | 34 | // let _blinky_thread = std::thread::Builder::new() 35 | // .stack_size(BLINKY_STACK_SIZE) 36 | // .spawn(move || loop { 37 | // thread::sleep(Duration::from_millis(500)); 38 | // state_machine.handle(&Event::TimerElapsed); 39 | // thread::sleep(Duration::from_millis(500)); 40 | // state_machine.handle(&Event::TimerElapsed); 41 | // }) 42 | // .unwrap(); 43 | } 44 | -------------------------------------------------------------------------------- /WIP/wifi/src/wifi.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_imports, dead_code)] 2 | use anyhow::bail; 3 | use anyhow::Result; 4 | use embedded_svc::ipv4; 5 | use embedded_svc::ping::Ping; 6 | use embedded_svc::wifi::*; 7 | use esp_idf_svc::netif::*; 8 | use esp_idf_svc::nvs::*; 9 | use esp_idf_svc::ping; 10 | use esp_idf_svc::sntp; 11 | use esp_idf_svc::sysloop::*; 12 | use esp_idf_svc::wifi::*; 13 | use std::{cell::RefCell, env, sync::atomic::*, sync::Arc, thread, time::*}; 14 | 15 | const WIFI_SSID: &str = env!("RUST_ESP32_STD_WIFI_SSID"); 16 | const WIFI_PASS: &str = env!("RUST_ESP32_STD_WIFI_PASS"); 17 | 18 | pub fn test_wifi() -> Result { 19 | let netif_stack = Arc::new(EspNetifStack::new()?); 20 | let sys_look_stack = Arc::new(EspSysLoopStack::new()?); 21 | let nvs = Arc::new(EspDefaultNvs::new()?); 22 | 23 | let mut wifi = EspWifi::new(netif_stack, sys_look_stack, nvs)?; 24 | 25 | wifi.set_configuration(&Configuration::Client(ClientConfiguration { 26 | ssid: WIFI_SSID.into(), 27 | password: WIFI_PASS.into(), 28 | ..Default::default() 29 | }))?; 30 | 31 | wifi.wait_status_with_timeout(Duration::from_secs(30), |s| !s.is_transitional()) 32 | .map_err(|e| anyhow::anyhow!("Wait timeout: {:?}", e))?; 33 | 34 | let status = wifi.get_status(); 35 | 36 | println!("Status: {:?}", status); 37 | 38 | if let ClientStatus::Started(ClientConnectionStatus::Connected(ClientIpStatus::Done( 39 | client_settings, 40 | ))) = status.0 41 | { 42 | Ok(format!("{:?}", client_settings.ip)) 43 | } else { 44 | Err(anyhow::anyhow!("Failed to connect in time.")) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docs/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/docs/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf -------------------------------------------------------------------------------- /docs/ESP32-C3-DevKit-Lipo_Rev_B.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/docs/ESP32-C3-DevKit-Lipo_Rev_B.pdf -------------------------------------------------------------------------------- /docs/PSiCC2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemmattner/ESP32-C3_Rust_Tutorials/abe228df29f93bb43d22aee3868eb8bb2b03574a/docs/PSiCC2.pdf --------------------------------------------------------------------------------