First commit
This commit is contained in:
commit
647182759a
5 changed files with 148 additions and 0 deletions
14
.cargo/config.toml
Normal file
14
.cargo/config.toml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[build]
|
||||||
|
# Set the default target to match the Cortex-M0+ in the RP2040
|
||||||
|
target = "thumbv6m-none-eabi"
|
||||||
|
|
||||||
|
[target.thumbv6m-none-eabi]
|
||||||
|
rustflags = [
|
||||||
|
"-C", "link-arg=--nmagic",
|
||||||
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
"-C", "inline-threshold=5",
|
||||||
|
"-C", "no-vectorize-loops",
|
||||||
|
]
|
||||||
|
|
||||||
|
runner = "elf2uf2-rs -d"
|
||||||
|
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/Cargo.lock
|
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "rp-dht"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
embedded-hal = { version = "0.2.5" }
|
||||||
|
cortex-m = { version = "0.7.6"}
|
||||||
|
cortex-m-rt = "0.7.3"
|
||||||
|
rp2040-boot2 = "0.2.1"
|
||||||
|
rp2040-hal = { version = "0.9.0", features = ["rp2040-e5"] }
|
||||||
|
pio-proc = "0.2.2"
|
||||||
|
pio = "0.2.1"
|
||||||
|
# embedded-alloc = "0.5.0"
|
29
src/dht.pio
Normal file
29
src/dht.pio
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
.program dht
|
||||||
|
; Clock must be set for 1µs per instruction
|
||||||
|
|
||||||
|
pull block ; Wait for start
|
||||||
|
|
||||||
|
set x, 31 ; set x register with 31 (for 31 * 32 µS)
|
||||||
|
set pindirs, 1 ; set pin as output
|
||||||
|
set pins, 0 ; set pin to low
|
||||||
|
loop_init_low: ; wait 992 ms
|
||||||
|
jmp x-- loop_init_low [31]
|
||||||
|
|
||||||
|
set pins, 1 ; set pin to high
|
||||||
|
set pindirs, 0 ; set pin as input
|
||||||
|
|
||||||
|
wait 0 pin 0 ; Wait for low
|
||||||
|
wait 1 pin 0 ; wait for high
|
||||||
|
|
||||||
|
set x, 31 ; Set number bit to received (ignore CRC :( sorry )
|
||||||
|
loop_data:
|
||||||
|
wait 0 pin 0 ; Wait for low
|
||||||
|
wait 1 pin 0 ; wait for high
|
||||||
|
|
||||||
|
nop [29] ; wait for ~ 30 µS
|
||||||
|
|
||||||
|
in pins, 1 ; read the pin state and store bit value
|
||||||
|
|
||||||
|
jmp x--, loop_data ; Run until read all bits
|
||||||
|
|
||||||
|
push ; send result
|
87
src/lib.rs
Normal file
87
src/lib.rs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use cortex_m::delay::Delay;
|
||||||
|
use pio_proc::pio_file;
|
||||||
|
use rp2040_hal::gpio::AnyPin;
|
||||||
|
use rp2040_hal::pio::{PIOExt, Running, StateMachine, StateMachineIndex, Tx};
|
||||||
|
use rp2040_hal::pio::{Rx, UninitStateMachine};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DhtError {
|
||||||
|
/// DHT never aswer to start signal
|
||||||
|
StartTimout,
|
||||||
|
/// Timeout during communication.
|
||||||
|
Timeout,
|
||||||
|
/// CRC mismatch.
|
||||||
|
CrcMismatch,
|
||||||
|
/// Failed to get pin state (low or high)
|
||||||
|
ReadPinError,
|
||||||
|
/// Internal state error
|
||||||
|
InternatError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DhtResult {
|
||||||
|
pub temperature: f32,
|
||||||
|
pub humidity: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PicoDht<P: PIOExt, STI: StateMachineIndex> {
|
||||||
|
// sm: PicoStateMachine<P, STI>,
|
||||||
|
sm: StateMachine<(P, STI), Running>,
|
||||||
|
rx_fifo: Rx<(P, STI)>,
|
||||||
|
tx_fifo: Tx<(P, STI)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: PIOExt, STI: StateMachineIndex> PicoDht<P, STI> {
|
||||||
|
pub fn new<I: AnyPin<Function = P::PinFunction>>(
|
||||||
|
mut pio: rp2040_hal::pio::PIO<P>,
|
||||||
|
sm: UninitStateMachine<(P, STI)>,
|
||||||
|
dht_pin: I,
|
||||||
|
) -> Self {
|
||||||
|
let program = pio_file!("./src/dht.pio");
|
||||||
|
|
||||||
|
let pin = dht_pin.into();
|
||||||
|
|
||||||
|
let installed = pio.install(&program.program).unwrap();
|
||||||
|
|
||||||
|
let (int, frac) = (125, 0);
|
||||||
|
let (mut sm, rx, tx) = rp2040_hal::pio::PIOBuilder::from_program(installed)
|
||||||
|
.set_pins(pin.id().num, 1)
|
||||||
|
.clock_divisor_fixed_point(int, frac)
|
||||||
|
.build(sm);
|
||||||
|
sm.set_pindirs([(pin.id().num, rp2040_hal::pio::PinDir::Output)]);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
sm: sm.start(),
|
||||||
|
rx_fifo: rx,
|
||||||
|
tx_fifo: tx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_data(&mut self, delay: &mut Delay) -> Result<DhtResult, DhtError> {
|
||||||
|
let mut timeout = 2000;
|
||||||
|
|
||||||
|
self.tx_fifo.write(1);
|
||||||
|
|
||||||
|
while timeout > 0 && self.rx_fifo.is_empty() {
|
||||||
|
delay.delay_ms(1);
|
||||||
|
timeout -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if timeout <= 0 {
|
||||||
|
self.sm.restart();
|
||||||
|
return Err(DhtError::Timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
let raw = self.rx_fifo.read().unwrap_or_default();
|
||||||
|
|
||||||
|
let t_raw = raw & 0x0000FFFF;
|
||||||
|
let h_raw = (raw & 0xFFFF0000) >> 16;
|
||||||
|
|
||||||
|
Ok(DhtResult {
|
||||||
|
temperature: t_raw as f32 / 10.0,
|
||||||
|
humidity: h_raw as f32 / 10.0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue