First commit

This commit is contained in:
Jonathan BAUDIN 2023-09-08 23:09:15 +02:00
commit 647182759a
5 changed files with 148 additions and 0 deletions

14
.cargo/config.toml Normal file
View 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
View file

@ -0,0 +1,2 @@
/target
/Cargo.lock

16
Cargo.toml Normal file
View 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
View 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
View 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,
})
}
}