-
Notifications
You must be signed in to change notification settings - Fork 225
RMT Onewire Peripheral #454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
a37af47
d45b33f
4a62132
b9de421
cc879bf
0183797
6e3f9b0
7148db1
719911b
c72e53c
cb17743
af7827b
f2453a4
9696af5
a72fb45
d0f1185
389135b
f8145c1
831be2d
bcf0ddd
8a8d7fd
c110fef
a7e26a9
fd076e8
269f4f3
eb6b1c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| "name": "rmt_onewire", | ||
| // Select between image and build propieties to pull or build the image. | ||
| "image": "docker.io/espressif/idf-rust:esp32_latest", | ||
| "customizations": { | ||
| "vscode": { | ||
| "extensions": [ | ||
| "rust-lang.rust-analyzer", | ||
| "tamasfe.even-better-toml", | ||
| "serayuzgur.crates", | ||
| "mutantdino.resourcemonitor", | ||
| "yzhang.markdown-all-in-one", | ||
| "ms-vscode.cpptools", | ||
| "actboy168.tasks", | ||
| "Wokwi.wokwi-vscode", | ||
| "ms-azuretools.vscode-docker", | ||
| "ms-python.python" | ||
| ], | ||
| "settings": { | ||
| "editor.formatOnPaste": true, | ||
| "editor.formatOnSave": true, | ||
| "editor.formatOnSaveMode": "file", | ||
| "editor.formatOnType": true, | ||
| "lldb.executable": "/usr/bin/lldb", | ||
| "files.watcherExclude": { | ||
| "**/target/**": true | ||
| }, | ||
| "rust-analyzer.checkOnSave.command": "clippy", | ||
| "rust-analyzer.checkOnSave.allTargets": false, | ||
| "[rust]": { | ||
| "editor.defaultFormatter": "rust-lang.rust-analyzer" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "forwardPorts": [ | ||
| 3333, | ||
| 8000 | ||
| ], | ||
| "workspaceMount": "source=${localWorkspaceFolder},target=/home/esp/rmt_onewire,type=bind,consistency=cached", | ||
| "workspaceFolder": "/home/esp/rmt_onewire" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| #include "ds18b20.h" | ||
| #include "onewire_bus.h" | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| dependencies: | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| espressif/ds18b20: | ||
| component_hash: d676429d9f1f686b65ed895e418eb4b331477bcd5d63c27f43dc3d6a2de8f13b | ||
| source: | ||
| service_url: https://api.components.espressif.com/ | ||
| type: service | ||
| version: 0.1.1 | ||
| espressif/onewire_bus: | ||
| component_hash: c4c781940d8bd988432b47ac3ee68479c69e14e01fdfba0b61365b233a3ba5d6 | ||
| source: | ||
| service_url: https://api.components.espressif.com/ | ||
| type: service | ||
| version: 1.0.2 | ||
| idf: | ||
| component_hash: null | ||
| source: | ||
| type: idf | ||
| version: 5.1.2 | ||
| manifest_hash: f4c4d8dc4f9e0e9422ee45c389b14c8d3db5ce6258eaec379ea8d50430151679 | ||
| target: esp32 | ||
| version: 1.0.0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| use esp_idf_hal::delay::FreeRtos; | ||
| use esp_idf_hal::onewire::BusDriver; | ||
| use esp_idf_hal::peripherals::Peripherals; | ||
| use esp_idf_hal::rmt::{ | ||
| FixedLengthSignal, PinState, Pulse, PulseTicks, Receive, RmtReceiveConfig, RmtTransmitConfig, | ||
| RxRmtDriver, TxRmtDriver, | ||
|
DaneSlattery marked this conversation as resolved.
Outdated
|
||
| }; | ||
|
|
||
| fn main() -> anyhow::Result<()> { | ||
| println!("Starting APP!"); | ||
|
|
||
| let peripherals = Peripherals::take()?; | ||
|
|
||
| let onewire_pin = peripherals.pins.gpio16; | ||
|
|
||
| let mut rmt_onewire = BusDriver::new(onewire_pin)?; | ||
|
|
||
| let mut search = rmt_onewire.search()?; | ||
|
|
||
| let search_device = search.next_device()?; | ||
|
|
||
| println!("Found Device: {}", search_device.address()); | ||
| loop { | ||
| FreeRtos::delay_ms(3000); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| use core::marker::PhantomData; | ||
| use core::ptr; | ||
|
|
||
| use esp_idf_sys::*; | ||
|
|
||
| use crate::peripheral::Peripheral; | ||
|
|
||
| #[derive(Debug)] | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| pub struct Device<'b> { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| _device: onewire::onewire_device_t, | ||
| // _bus: &'b BusDriver<'b>, // not sure how I would hold a reference to this aside from the handle | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| _p: PhantomData<&'b ()>, // holds the lifetime since the device is linked to the lifetime of the bus | ||
| } | ||
|
|
||
| impl<'a> Device<'a> { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| fn new(device_handle: onewire::onewire_device_t) -> Self { | ||
| Self { | ||
| _device: device_handle, | ||
| _p: PhantomData, | ||
| } | ||
| } | ||
|
|
||
| /// get the handle of the bus the device is attached to | ||
| pub fn bus(&self) -> onewire::onewire_bus_handle_t { | ||
| self._device.bus | ||
| } | ||
|
|
||
| /// get the device address | ||
| pub fn address(&self) -> u64 { | ||
| self._device.address | ||
| } | ||
| } | ||
|
|
||
| /// wrapper around the device iterator to search for available devices on the bus | ||
| pub struct DeviceSearch { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| _search: onewire::onewire_device_iter_handle_t, | ||
| } | ||
|
|
||
| impl DeviceSearch { | ||
| fn new(bus: &mut BusDriver) -> Result<Self, EspError> { | ||
| let mut my_iter: onewire::onewire_device_iter_handle_t = ptr::null_mut(); | ||
|
|
||
| esp!(unsafe { onewire::onewire_new_device_iter(bus._bus, &mut my_iter) })?; | ||
|
|
||
| Ok(Self { _search: my_iter }) | ||
| } | ||
|
|
||
| pub fn next_device(&mut self) -> Result<Device, EspError> { | ||
| let mut next_onewire_device = onewire::onewire_device_t::default(); | ||
| esp!(unsafe { | ||
| onewire::onewire_device_iter_get_next(self._search, &mut next_onewire_device) | ||
| })?; | ||
|
|
||
| Ok(Device::new(next_onewire_device)) | ||
| } | ||
| } | ||
|
|
||
| impl Drop for DeviceSearch { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| fn drop(&mut self) { | ||
| esp!(unsafe { onewire::onewire_del_device_iter(self._search) }).unwrap(); | ||
| } | ||
| } | ||
|
|
||
| /// beep beep | ||
| pub struct BusDriver<'d> { | ||
| _bus: onewire::onewire_bus_handle_t, | ||
| _p: PhantomData<&'d ()>, | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| impl<'d> BusDriver<'d> { | ||
| pub fn new( | ||
| pin: impl Peripheral<P = impl crate::gpio::InputPin + crate::gpio::OutputPin> + 'd, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since internally the ESP IDF onewire driver uses the new RMT driver (a single channel for TX/RX) (plus the pin thst you already track) you need to somehow track the usage of the RMT channel peripheral, as it is still a peripheral - just like the pin which you track already. If you don't track it, nothing major would happen because the old and the new RMT driver cannot co-exist, yet would still be good to follow the pattern established with the other drivers. Now, some of the "new" (ESP IDF 5+) C drivers no longer take a peripheral "id"/"number". For example, the old RMT driver used to take a channel number, but the new C RMT driver doesn't as it internally manages what channel to be used. If you try to instantiate more driver instances than hardware channels you have available, it would likely return a runtime With that said, nothing stops us from continuing the old way and passing to the driver a RMT "peripheral" (note that you don't need "new" RMT channel peripherals for the new C RMT driver, because the peripherals are ghost structures which however model actual hardware on the chip and not higher-level C driver concepts). So what I suggest is to just enhance the
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Just mentioning that this comment ^^^ is still valid.)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I had planned to look into this. It becomes quite problematic as you mentioned below because I ifdef the whole rmt module.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I would not call it "quite problematic". #ifdef-ing only the driver inside
No big deal?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No big deal. It's done. |
||
| ) -> Result<Self, EspError> { | ||
| let mut bus: onewire::onewire_bus_handle_t = ptr::null_mut(); | ||
|
|
||
| let pin = pin.into_ref().pin(); | ||
| let bus_config = esp_idf_sys::onewire::onewire_bus_config_t { bus_gpio_num: pin }; | ||
|
|
||
| let rmt_config = esp_idf_sys::onewire::onewire_bus_rmt_config_t { max_rx_bytes: 10 }; | ||
|
DaneSlattery marked this conversation as resolved.
Outdated
|
||
|
|
||
| esp!(unsafe { onewire::onewire_new_bus_rmt(&bus_config, &rmt_config, &mut bus as _) })?; | ||
|
|
||
| Ok(Self { | ||
| _bus: bus, | ||
| _p: PhantomData, | ||
| }) | ||
| } | ||
| /// send reset pulse to the bus | ||
| pub fn reset_bus(&mut self) -> Result<(), EspError> { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| esp!(unsafe { onewire::onewire_bus_reset(self._bus) }) | ||
| } | ||
|
|
||
| pub fn search(&mut self) -> Result<DeviceSearch, EspError> { | ||
|
ivmarkov marked this conversation as resolved.
Outdated
|
||
| DeviceSearch::new(self) | ||
| } | ||
| } | ||
|
|
||
| impl<'d> Drop for BusDriver<'d> { | ||
| fn drop(&mut self) { | ||
| esp!(unsafe { onewire::onewire_bus_del(self._bus) }).unwrap(); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.