├── .gitignore ├── README.md ├── Cargo.toml ├── CHANGELOG.md └── src ├── serial.rs ├── timing.rs └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Esp01 2 | 3 | Crate for communicating with the esp01 variant of the esp8266 wifi module using 4 | the embedded hal traits. 5 | 6 | For now the crate is a bit barebones, for example, only running as a client and 7 | sending TCP/UDP messages is supported. 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["TheZoq2 "] 3 | edition = "2018" 4 | name = "esp-01" 5 | version = "0.1.1" 6 | description = "Crate to communicate with the esp01 variant of the esp8266 module" 7 | readme = "README.md" 8 | keywords = ["embedded-hal", "esp8266", "esp01"] 9 | license = "MIT OR Apache-2.0" 10 | repository = "https://github.com/TheZoq2/esp01-rs" 11 | 12 | [dependencies] 13 | embedded-hal = "0.2.3" 14 | arrayvec = {version = "0.4.11", default-features = false} 15 | nb = "0.1.2" 16 | itoa = {version = "0.4.4", default-features = false} 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/). 7 | 8 | ## [Unreleased] 9 | 10 | ## [v0.1.1] - 2018-12-17 11 | 12 | ### Changed 13 | 14 | - Fix readme and metadata 15 | 16 | ## [v0.1.0] - 2018-12-17 17 | 18 | ### Added 19 | 20 | - Initial release 21 | 22 | [Unreleased]: https://github.com/stm32-rs/stm32f1xx-hal/compare/v0.1.1...HEAD 23 | [v0.1.1]: https://github.com/thezoq2/esp01-rs/compare/v0.1.1...v0.1.0 24 | -------------------------------------------------------------------------------- /src/serial.rs: -------------------------------------------------------------------------------- 1 | use embedded_hal as hal; 2 | use nb::{self, block}; 3 | 4 | use crate::timing::{Millisecond, LongTimer}; 5 | 6 | 7 | #[derive(Debug)] 8 | pub enum Error { 9 | /// Serial interface error 10 | Serial(E), 11 | /// Timeout before receiving reply 12 | TimedOut, 13 | } 14 | 15 | pub fn read_with_timeout( 16 | serial: &mut S, 17 | timer: &mut T, 18 | timeout: Millisecond, 19 | ) -> Result> 20 | where 21 | T: LongTimer, 22 | S: hal::serial::Read, 23 | { 24 | timer.start(timeout); 25 | loop { 26 | match serial.read() { 27 | // raise error 28 | Err(nb::Error::Other(e)) => return Err(Error::Serial(e)), 29 | Err(nb::Error::WouldBlock) => { 30 | // no data available yet, check the timer below 31 | }, 32 | Ok(byte) => return Ok(byte), 33 | } 34 | 35 | match timer.wait() { 36 | Err(nb::Error::Other(_e)) => { 37 | // The error type specified by `timer.wait()` is `!`, which 38 | // means no error can actually occur. The Rust compiler 39 | // still forces us to provide this match arm, though. 40 | unreachable!("Error was !, something has gone horribly wrong") 41 | }, 42 | // no timeout yet, try again 43 | Err(nb::Error::WouldBlock) => continue, 44 | Ok(()) => { 45 | return Err(Error::TimedOut); 46 | } 47 | } 48 | } 49 | } 50 | 51 | /** 52 | */ 53 | pub fn read_until_message( 54 | rx: &mut S, 55 | timer: &mut T, 56 | timeout: Millisecond, 57 | buffer: &mut [u8], 58 | parser: &C 59 | ) -> Result> 60 | where 61 | T: LongTimer, 62 | S: hal::serial::Read, 63 | C: Fn(&[u8], usize) -> Option, 64 | { 65 | let mut ptr = 0; 66 | loop { 67 | match read_with_timeout(rx, timer, timeout) { 68 | Ok(byte) => { 69 | buffer[ptr] = byte; 70 | ptr = (ptr+1) % buffer.len(); 71 | 72 | if let Some(val) = parser(buffer, ptr) { 73 | return Ok(val); 74 | } 75 | }, 76 | Err(Error::TimedOut) => { 77 | // If the remote end has already sent bytes and has now 78 | // stopped, we assume the transmission has ended 79 | return Err(Error::TimedOut); 80 | }, 81 | Err(e) => { 82 | return Err(e) 83 | } 84 | }; 85 | } 86 | } 87 | 88 | pub fn write_all(serial: &mut S, buffer: &[u8]) -> Result<(), S::Error> 89 | where 90 | S: hal::serial::Write 91 | { 92 | for &byte in buffer { 93 | block!(serial.write(byte))?; 94 | } 95 | 96 | Ok(()) 97 | } 98 | 99 | -------------------------------------------------------------------------------- /src/timing.rs: -------------------------------------------------------------------------------- 1 | use nb; 2 | use core::convert::Infallible; 3 | 4 | /** 5 | A countdown timer which nonblockingly waits until the specified countdown 6 | is completed. The countdown is started by calling `start`. 7 | 8 | This trait is needed because `embedded_hal` currently does not have a standardised 9 | measure of time. 10 | 11 | The implementation of this trait will depend on your HAL implementation, but 12 | here is a sample impl for the stm32f1xx_hal 13 | 14 | 15 | ```rust 16 | struct LongTimer { 17 | timer: Timer, 18 | milliseconds_remaining: u32, 19 | } 20 | 21 | impl LongTimer 22 | where Timer: CountDown