feat: Only remove nb from stabilizing drivers
This commit is contained in:
parent
b75e215b94
commit
45d6e64f95
@ -44,10 +44,12 @@ esp-synopsys-usb-otg = { version = "0.4.2", optional = true, features = ["fs
|
|||||||
fugit = "0.3.7"
|
fugit = "0.3.7"
|
||||||
instability = "0.3"
|
instability = "0.3"
|
||||||
log = { version = "0.4.22", optional = true }
|
log = { version = "0.4.22", optional = true }
|
||||||
|
nb = "1.1.0"
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
portable-atomic = { version = "1.9.0", default-features = false }
|
portable-atomic = { version = "1.9.0", default-features = false }
|
||||||
procmacros = { version = "0.15.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
|
procmacros = { version = "0.15.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
|
||||||
strum = { version = "0.26.3", default-features = false, features = ["derive"] }
|
strum = { version = "0.26.3", default-features = false, features = ["derive"] }
|
||||||
|
void = { version = "1.0.2", default-features = false }
|
||||||
usb-device = { version = "0.3.2", optional = true }
|
usb-device = { version = "0.3.2", optional = true }
|
||||||
rand_core = "0.6.4"
|
rand_core = "0.6.4"
|
||||||
ufmt-write = "0.1.0"
|
ufmt-write = "0.1.0"
|
||||||
|
|||||||
@ -288,7 +288,7 @@ where
|
|||||||
/// This method takes an [AdcPin](super::AdcPin) reference, as it is
|
/// This method takes an [AdcPin](super::AdcPin) reference, as it is
|
||||||
/// expected that the ADC will be able to sample whatever channel
|
/// expected that the ADC will be able to sample whatever channel
|
||||||
/// underlies the pin.
|
/// underlies the pin.
|
||||||
pub fn read_oneshot<PIN>(&mut self, _pin: &mut super::AdcPin<PIN, ADCI>) -> Option<u16>
|
pub fn read_oneshot<PIN>(&mut self, _pin: &mut super::AdcPin<PIN, ADCI>) -> nb::Result<u16, ()>
|
||||||
where
|
where
|
||||||
PIN: super::AdcChannel,
|
PIN: super::AdcChannel,
|
||||||
{
|
{
|
||||||
@ -301,7 +301,7 @@ where
|
|||||||
// - if it's for a different channel try again later
|
// - if it's for a different channel try again later
|
||||||
// - if it's for the given channel, go ahead and check progress
|
// - if it's for the given channel, go ahead and check progress
|
||||||
if active_channel != PIN::CHANNEL {
|
if active_channel != PIN::CHANNEL {
|
||||||
return None;
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no conversions are in progress, start a new one for given channel
|
// If no conversions are in progress, start a new one for given channel
|
||||||
@ -316,7 +316,7 @@ where
|
|||||||
// Wait for ADC to finish conversion
|
// Wait for ADC to finish conversion
|
||||||
let conversion_finished = ADCI::read_done_sar();
|
let conversion_finished = ADCI::read_done_sar();
|
||||||
if !conversion_finished {
|
if !conversion_finished {
|
||||||
return None;
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get converted value
|
// Get converted value
|
||||||
@ -325,7 +325,7 @@ where
|
|||||||
// Mark that no conversions are currently in progress
|
// Mark that no conversions are currently in progress
|
||||||
self.active_channel = None;
|
self.active_channel = None;
|
||||||
|
|
||||||
Some(converted_value)
|
Ok(converted_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,11 +43,7 @@
|
|||||||
//! let mut delay = Delay::new();
|
//! let mut delay = Delay::new();
|
||||||
//!
|
//!
|
||||||
//! loop {
|
//! loop {
|
||||||
//! let pin_value: u16 = loop {
|
//! let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut pin)).unwrap();
|
||||||
//! if let Some(value) = adc1.read_oneshot(&mut pin) {
|
|
||||||
//! break value;
|
|
||||||
//! }
|
|
||||||
//! };
|
|
||||||
//!
|
//!
|
||||||
//! delay.delay_millis(1500);
|
//! delay.delay_millis(1500);
|
||||||
//! }
|
//! }
|
||||||
|
|||||||
@ -433,7 +433,10 @@ where
|
|||||||
/// This method takes an [AdcPin](super::AdcPin) reference, as it is
|
/// This method takes an [AdcPin](super::AdcPin) reference, as it is
|
||||||
/// expected that the ADC will be able to sample whatever channel
|
/// expected that the ADC will be able to sample whatever channel
|
||||||
/// underlies the pin.
|
/// underlies the pin.
|
||||||
pub fn read_oneshot<PIN, CS>(&mut self, pin: &mut super::AdcPin<PIN, ADCI, CS>) -> Option<u16>
|
pub fn read_oneshot<PIN, CS>(
|
||||||
|
&mut self,
|
||||||
|
pin: &mut super::AdcPin<PIN, ADCI, CS>,
|
||||||
|
) -> nb::Result<u16, ()>
|
||||||
where
|
where
|
||||||
PIN: super::AdcChannel,
|
PIN: super::AdcChannel,
|
||||||
CS: super::AdcCalScheme<ADCI>,
|
CS: super::AdcCalScheme<ADCI>,
|
||||||
@ -447,7 +450,7 @@ where
|
|||||||
// - if it's for a different channel try again later
|
// - if it's for a different channel try again later
|
||||||
// - if it's for the given channel, go ahead and check progress
|
// - if it's for the given channel, go ahead and check progress
|
||||||
if active_channel != PIN::CHANNEL {
|
if active_channel != PIN::CHANNEL {
|
||||||
return None;
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no conversions are in progress, start a new one for given channel
|
// If no conversions are in progress, start a new one for given channel
|
||||||
@ -473,7 +476,7 @@ where
|
|||||||
// Wait for ADC to finish conversion
|
// Wait for ADC to finish conversion
|
||||||
let conversion_finished = ADCI::is_done();
|
let conversion_finished = ADCI::is_done();
|
||||||
if !conversion_finished {
|
if !conversion_finished {
|
||||||
return None;
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get converted value
|
// Get converted value
|
||||||
@ -496,7 +499,7 @@ where
|
|||||||
// Mark that no conversions are currently in progress
|
// Mark that no conversions are currently in progress
|
||||||
self.active_channel = None;
|
self.active_channel = None;
|
||||||
|
|
||||||
Some(converted_value)
|
Ok(converted_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -502,7 +502,10 @@ where
|
|||||||
/// This method takes an [AdcPin](super::AdcPin) reference, as it is
|
/// This method takes an [AdcPin](super::AdcPin) reference, as it is
|
||||||
/// expected that the ADC will be able to sample whatever channel
|
/// expected that the ADC will be able to sample whatever channel
|
||||||
/// underlies the pin.
|
/// underlies the pin.
|
||||||
pub fn read_oneshot<PIN, CS>(&mut self, pin: &mut super::AdcPin<PIN, ADCI, CS>) -> Option<u16>
|
pub fn read_oneshot<PIN, CS>(
|
||||||
|
&mut self,
|
||||||
|
pin: &mut super::AdcPin<PIN, ADCI, CS>,
|
||||||
|
) -> nb::Result<u16, ()>
|
||||||
where
|
where
|
||||||
PIN: super::AdcChannel,
|
PIN: super::AdcChannel,
|
||||||
CS: super::AdcCalScheme<ADCI>,
|
CS: super::AdcCalScheme<ADCI>,
|
||||||
@ -512,7 +515,7 @@ where
|
|||||||
// - if it's for a different channel try again later
|
// - if it's for a different channel try again later
|
||||||
// - if it's for the given channel, go ahead and check progress
|
// - if it's for the given channel, go ahead and check progress
|
||||||
if active_channel != PIN::CHANNEL {
|
if active_channel != PIN::CHANNEL {
|
||||||
return None;
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no conversions are in progress, start a new one for given channel
|
// If no conversions are in progress, start a new one for given channel
|
||||||
@ -524,7 +527,7 @@ where
|
|||||||
// Wait for ADC to finish conversion
|
// Wait for ADC to finish conversion
|
||||||
let conversion_finished = ADCI::is_done();
|
let conversion_finished = ADCI::is_done();
|
||||||
if !conversion_finished {
|
if !conversion_finished {
|
||||||
return None;
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get converted value
|
// Get converted value
|
||||||
@ -537,7 +540,7 @@ where
|
|||||||
// Mark that no conversions are currently in progress
|
// Mark that no conversions are currently in progress
|
||||||
self.active_channel = None;
|
self.active_channel = None;
|
||||||
|
|
||||||
Some(converted_value)
|
Ok(converted_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_sample<PIN, CS>(&mut self, pin: &mut AdcPin<PIN, ADCI, CS>)
|
fn start_sample<PIN, CS>(&mut self, pin: &mut AdcPin<PIN, ADCI, CS>)
|
||||||
|
|||||||
@ -34,6 +34,8 @@
|
|||||||
//!
|
//!
|
||||||
//! [HMAC]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/hmac.rs
|
//! [HMAC]: https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/hmac.rs
|
||||||
|
|
||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::HMAC,
|
peripherals::HMAC,
|
||||||
@ -131,7 +133,7 @@ impl<'d> Hmac<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Step 2. Configure HMAC keys and key purposes.
|
/// Step 2. Configure HMAC keys and key purposes.
|
||||||
pub fn configure(&mut self, m: HmacPurpose, key_id: KeyId) -> Result<(), Error> {
|
pub fn configure(&mut self, m: HmacPurpose, key_id: KeyId) -> nb::Result<(), Error> {
|
||||||
self.hmac
|
self.hmac
|
||||||
.set_para_purpose()
|
.set_para_purpose()
|
||||||
.write(|w| unsafe { w.purpose_set().bits(m as u8) });
|
.write(|w| unsafe { w.purpose_set().bits(m as u8) });
|
||||||
@ -143,33 +145,39 @@ impl<'d> Hmac<'d> {
|
|||||||
.write(|w| w.set_para_end().set_bit());
|
.write(|w| w.set_para_end().set_bit());
|
||||||
|
|
||||||
if self.hmac.query_error().read().query_check().bit_is_set() {
|
if self.hmac.query_error().read().query_check().bit_is_set() {
|
||||||
return Err(Error::KeyPurposeMismatch);
|
return Err(nb::Error::Other(Error::KeyPurposeMismatch));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process the msg block after block
|
/// Process the msg block after block
|
||||||
pub fn update<'a>(&mut self, msg: &'a [u8]) -> &'a [u8] {
|
///
|
||||||
while (*self).is_busy() {}
|
/// Call this function as many times as necessary (msg.len() > 0)
|
||||||
|
pub fn update<'a>(&mut self, msg: &'a [u8]) -> nb::Result<&'a [u8], Infallible> {
|
||||||
|
if self.is_busy() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
self.next_command();
|
self.next_command();
|
||||||
|
|
||||||
let remaining = self.write_data(msg);
|
let remaining = self.write_data(msg).unwrap();
|
||||||
|
|
||||||
remaining
|
Ok(remaining)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalizes the HMAC computation and retrieves the resulting hash output.
|
/// Finalizes the HMAC computation and retrieves the resulting hash output.
|
||||||
pub fn finalize(&mut self, output: &mut [u8]) {
|
pub fn finalize(&mut self, output: &mut [u8]) -> nb::Result<(), Infallible> {
|
||||||
while (*self).is_busy() {}
|
if self.is_busy() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
self.next_command();
|
self.next_command();
|
||||||
|
|
||||||
let msg_len = self.byte_written as u64;
|
let msg_len = self.byte_written as u64;
|
||||||
|
|
||||||
self.write_data(&[0x80]);
|
nb::block!(self.write_data(&[0x80])).unwrap();
|
||||||
self.flush_data();
|
nb::block!(self.flush_data()).unwrap();
|
||||||
self.next_command();
|
self.next_command();
|
||||||
debug_assert!(self.byte_written % 4 == 0);
|
debug_assert!(self.byte_written % 4 == 0);
|
||||||
|
|
||||||
@ -196,6 +204,7 @@ impl<'d> Hmac<'d> {
|
|||||||
.write(|w| w.set_result_end().set_bit());
|
.write(|w| w.set_result_end().set_bit());
|
||||||
self.byte_written = 64;
|
self.byte_written = 64;
|
||||||
self.next_command = NextCommand::None;
|
self.next_command = NextCommand::None;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_busy(&mut self) -> bool {
|
fn is_busy(&mut self) -> bool {
|
||||||
@ -219,7 +228,7 @@ impl<'d> Hmac<'d> {
|
|||||||
self.next_command = NextCommand::None;
|
self.next_command = NextCommand::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_data<'a>(&mut self, incoming: &'a [u8]) -> &'a [u8] {
|
fn write_data<'a>(&mut self, incoming: &'a [u8]) -> nb::Result<&'a [u8], Infallible> {
|
||||||
let mod_length = self.byte_written % 64;
|
let mod_length = self.byte_written % 64;
|
||||||
|
|
||||||
let (remaining, bound_reached) = self.alignment_helper.aligned_volatile_copy(
|
let (remaining, bound_reached) = self.alignment_helper.aligned_volatile_copy(
|
||||||
@ -248,11 +257,13 @@ impl<'d> Hmac<'d> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remaining
|
Ok(remaining)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush_data(&mut self) {
|
fn flush_data(&mut self) -> nb::Result<(), Infallible> {
|
||||||
while self.is_busy() {}
|
if self.is_busy() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
let flushed = self.alignment_helper.flush_to(
|
let flushed = self.alignment_helper.flush_to(
|
||||||
#[cfg(esp32s2)]
|
#[cfg(esp32s2)]
|
||||||
@ -270,6 +281,8 @@ impl<'d> Hmac<'d> {
|
|||||||
while self.is_busy() {}
|
while self.is_busy() {}
|
||||||
self.next_command = NextCommand::MessagePad;
|
self.next_command = NextCommand::MessagePad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn padding(&mut self, msg_len: u64) {
|
fn padding(&mut self, msg_len: u64) {
|
||||||
|
|||||||
@ -81,13 +81,10 @@
|
|||||||
/// Attenuation::Attenuation11dB
|
/// Attenuation::Attenuation11dB
|
||||||
/// );
|
/// );
|
||||||
/// let mut adc1 = Adc::<ADC1>::new(peripherals.ADC1, adc1_config);
|
/// let mut adc1 = Adc::<ADC1>::new(peripherals.ADC1, adc1_config);
|
||||||
/// let pin_value: u16 = loop {
|
/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap();
|
||||||
/// if let Some(value) = adc1.read_oneshot(&mut adc1_pin) {
|
|
||||||
/// break value;
|
|
||||||
/// }
|
|
||||||
/// };
|
|
||||||
/// rng.read(&mut buf);
|
/// rng.read(&mut buf);
|
||||||
/// true_rand = rng.random();
|
/// true_rand = rng.random();
|
||||||
|
/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap();
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use crate::rsa::{
|
use crate::rsa::{
|
||||||
implement_op,
|
implement_op,
|
||||||
Multi,
|
Multi,
|
||||||
@ -12,8 +14,11 @@ impl<Dm: crate::DriverMode> Rsa<'_, Dm> {
|
|||||||
/// After the RSA Accelerator is released from reset, the memory blocks
|
/// After the RSA Accelerator is released from reset, the memory blocks
|
||||||
/// needs to be initialized, only after that peripheral should be used.
|
/// needs to be initialized, only after that peripheral should be used.
|
||||||
/// This function would return without an error if the memory is initialized
|
/// This function would return without an error if the memory is initialized
|
||||||
pub fn ready(&mut self) {
|
pub fn ready(&mut self) -> nb::Result<(), Infallible> {
|
||||||
while !self.rsa.clean().read().clean().bit_is_clear() {}
|
if self.rsa.clean().read().clean().bit_is_clear() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the multi-mode configuration to the RSA hardware.
|
/// Writes the multi-mode configuration to the RSA hardware.
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use crate::rsa::{
|
use crate::rsa::{
|
||||||
implement_op,
|
implement_op,
|
||||||
Multi,
|
Multi,
|
||||||
@ -12,8 +14,11 @@ impl<Dm: crate::DriverMode> Rsa<'_, Dm> {
|
|||||||
/// After the RSA Accelerator is released from reset, the memory blocks
|
/// After the RSA Accelerator is released from reset, the memory blocks
|
||||||
/// needs to be initialized, only after that peripheral should be used.
|
/// needs to be initialized, only after that peripheral should be used.
|
||||||
/// This function would return without an error if the memory is initialized
|
/// This function would return without an error if the memory is initialized
|
||||||
pub fn ready(&mut self) {
|
pub fn ready(&mut self) -> nb::Result<(), Infallible> {
|
||||||
while !self.rsa.query_clean().read().query_clean().bit_is_clear() {}
|
if self.rsa.query_clean().read().query_clean().bit_is_clear() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables/disables rsa interrupt.
|
/// Enables/disables rsa interrupt.
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use core::convert::Infallible;
|
||||||
|
|
||||||
use crate::rsa::{
|
use crate::rsa::{
|
||||||
implement_op,
|
implement_op,
|
||||||
Multi,
|
Multi,
|
||||||
@ -13,8 +15,11 @@ impl<Dm: crate::DriverMode> Rsa<'_, Dm> {
|
|||||||
/// needs to be initialized, only after that peripheral should be used.
|
/// needs to be initialized, only after that peripheral should be used.
|
||||||
/// This function would return without an error if the memory is
|
/// This function would return without an error if the memory is
|
||||||
/// initialized.
|
/// initialized.
|
||||||
pub fn ready(&mut self) {
|
pub fn ready(&mut self) -> nb::Result<(), Infallible> {
|
||||||
while !self.rsa.clean().read().clean().bit_is_clear() {}
|
if self.rsa.clean().read().clean().bit_is_clear() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables/disables rsa interrupt.
|
/// Enables/disables rsa interrupt.
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
#![doc = crate::before_snippet!()]
|
#![doc = crate::before_snippet!()]
|
||||||
//! # use esp_hal::sha::Sha;
|
//! # use esp_hal::sha::Sha;
|
||||||
//! # use esp_hal::sha::Sha256;
|
//! # use esp_hal::sha::Sha256;
|
||||||
|
//! # use nb::block;
|
||||||
//! let mut source_data = "HELLO, ESPRESSIF!".as_bytes();
|
//! let mut source_data = "HELLO, ESPRESSIF!".as_bytes();
|
||||||
//! let mut sha = Sha::new(peripherals.SHA);
|
//! let mut sha = Sha::new(peripherals.SHA);
|
||||||
//! let mut hasher = sha.start::<Sha256>();
|
//! let mut hasher = sha.start::<Sha256>();
|
||||||
@ -41,18 +42,21 @@
|
|||||||
//! let mut output = [0u8; 32];
|
//! let mut output = [0u8; 32];
|
||||||
//!
|
//!
|
||||||
//! while !source_data.is_empty() {
|
//! while !source_data.is_empty() {
|
||||||
//! source_data = hasher.update(source_data);
|
//! // All the HW Sha functions are infallible so unwrap is fine to use if
|
||||||
//! };
|
//! // you use block!
|
||||||
|
//! source_data = block!(hasher.update(source_data)).unwrap();
|
||||||
|
//! }
|
||||||
//!
|
//!
|
||||||
//! // Finish can be called as many times as desired to get multiple copies of
|
//! // Finish can be called as many times as desired to get multiple copies of
|
||||||
//! // the output.
|
//! // the output.
|
||||||
//! hasher.finish(output.as_mut_slice());
|
//! block!(hasher.finish(output.as_mut_slice())).unwrap();
|
||||||
|
//!
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//! ## Implementation State
|
//! ## Implementation State
|
||||||
//! - DMA-SHA Mode is not supported.
|
//! - DMA-SHA Mode is not supported.
|
||||||
|
|
||||||
use core::{borrow::BorrowMut, marker::PhantomData, mem::size_of};
|
use core::{borrow::BorrowMut, convert::Infallible, marker::PhantomData, mem::size_of};
|
||||||
|
|
||||||
/// Re-export digest for convenience
|
/// Re-export digest for convenience
|
||||||
#[cfg(feature = "digest")]
|
#[cfg(feature = "digest")]
|
||||||
@ -204,7 +208,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the SHA digest with the provided data buffer.
|
/// Updates the SHA digest with the provided data buffer.
|
||||||
pub fn update<'a>(&mut self, incoming: &'a [u8]) -> &'a [u8] {
|
pub fn update<'a>(&mut self, incoming: &'a [u8]) -> nb::Result<&'a [u8], Infallible> {
|
||||||
self.finished = false;
|
self.finished = false;
|
||||||
|
|
||||||
self.write_data(incoming)
|
self.write_data(incoming)
|
||||||
@ -217,11 +221,10 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
|
|||||||
/// Typically, output is expected to be the size of
|
/// Typically, output is expected to be the size of
|
||||||
/// [ShaAlgorithm::DIGEST_LENGTH], but smaller inputs can be given to
|
/// [ShaAlgorithm::DIGEST_LENGTH], but smaller inputs can be given to
|
||||||
/// get a "short hash"
|
/// get a "short hash"
|
||||||
pub fn finish(&mut self, output: &mut [u8]) {
|
pub fn finish(&mut self, output: &mut [u8]) -> nb::Result<(), Infallible> {
|
||||||
// Store message length for padding
|
// Store message length for padding
|
||||||
let length = (self.cursor as u64 * 8).to_be_bytes();
|
let length = (self.cursor as u64 * 8).to_be_bytes();
|
||||||
// Append "1" bit
|
nb::block!(self.update(&[0x80]))?; // Append "1" bit
|
||||||
self.update(&[0x80]);
|
|
||||||
|
|
||||||
// Flush partial data, ensures aligned cursor
|
// Flush partial data, ensures aligned cursor
|
||||||
{
|
{
|
||||||
@ -304,12 +307,16 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
|
|||||||
self.first_run = true;
|
self.first_run = true;
|
||||||
self.cursor = 0;
|
self.cursor = 0;
|
||||||
self.alignment_helper.reset();
|
self.alignment_helper.reset();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save the current state of the digest for later continuation.
|
/// Save the current state of the digest for later continuation.
|
||||||
#[cfg(not(esp32))]
|
#[cfg(not(esp32))]
|
||||||
pub fn save(&mut self, context: &mut Context<A>) {
|
pub fn save(&mut self, context: &mut Context<A>) -> nb::Result<(), Infallible> {
|
||||||
while self.is_busy() {}
|
if self.is_busy() {
|
||||||
|
return Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
context.alignment_helper = self.alignment_helper.clone();
|
context.alignment_helper = self.alignment_helper.clone();
|
||||||
context.cursor = self.cursor;
|
context.cursor = self.cursor;
|
||||||
@ -332,6 +339,8 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
|
|||||||
32,
|
32,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Discard the current digest and return the peripheral.
|
/// Discard the current digest and return the peripheral.
|
||||||
@ -371,19 +380,19 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_data<'a>(&mut self, incoming: &'a [u8]) -> &'a [u8] {
|
fn write_data<'a>(&mut self, incoming: &'a [u8]) -> nb::Result<&'a [u8], Infallible> {
|
||||||
if self.message_buffer_is_full {
|
if self.message_buffer_is_full {
|
||||||
while (*self).is_busy() {
|
if self.is_busy() {
|
||||||
// The message buffer is full and the hardware is still
|
// The message buffer is full and the hardware is still processing the previous
|
||||||
// processing the previous message. There's
|
// message. There's nothing to be done besides wait for the hardware.
|
||||||
// nothing to be done besides wait for the hardware.
|
return Err(nb::Error::WouldBlock);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// Submit the full buffer.
|
// Submit the full buffer.
|
||||||
self.process_buffer();
|
self.process_buffer();
|
||||||
// The buffer is now free for filling.
|
// The buffer is now free for filling.
|
||||||
self.message_buffer_is_full = false;
|
self.message_buffer_is_full = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mod_cursor = self.cursor % A::CHUNK_LENGTH;
|
let mod_cursor = self.cursor % A::CHUNK_LENGTH;
|
||||||
let chunk_len = A::CHUNK_LENGTH;
|
let chunk_len = A::CHUNK_LENGTH;
|
||||||
@ -410,7 +419,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remaining
|
Ok(remaining)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +538,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d
|
|||||||
fn update(&mut self, data: &[u8]) {
|
fn update(&mut self, data: &[u8]) {
|
||||||
let mut remaining = data.as_ref();
|
let mut remaining = data.as_ref();
|
||||||
while !remaining.is_empty() {
|
while !remaining.is_empty() {
|
||||||
remaining = self.update(remaining);
|
remaining = nb::block!(Self::update(self, remaining)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,7 +546,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d
|
|||||||
#[cfg(feature = "digest")]
|
#[cfg(feature = "digest")]
|
||||||
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> {
|
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> {
|
||||||
fn finalize_into(mut self, out: &mut digest::Output<Self>) {
|
fn finalize_into(mut self, out: &mut digest::Output<Self>) {
|
||||||
self.finish(out);
|
nb::block!(self.finish(out)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
//! # use esp_hal::twai::TwaiConfiguration;
|
//! # use esp_hal::twai::TwaiConfiguration;
|
||||||
//! # use esp_hal::twai::BaudRate;
|
//! # use esp_hal::twai::BaudRate;
|
||||||
//! # use esp_hal::twai::TwaiMode;
|
//! # use esp_hal::twai::TwaiMode;
|
||||||
|
//! # use nb::block;
|
||||||
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI
|
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI
|
||||||
//! // transceiver.
|
//! // transceiver.
|
||||||
//! let twai_rx_pin = peripherals.GPIO3;
|
//! let twai_rx_pin = peripherals.GPIO3;
|
||||||
@ -61,14 +62,10 @@
|
|||||||
//!
|
//!
|
||||||
//! loop {
|
//! loop {
|
||||||
//! // Wait for a frame to be received.
|
//! // Wait for a frame to be received.
|
||||||
//! let frame = loop {
|
//! let frame = block!(twai.receive()).unwrap();
|
||||||
//! if let Ok(frame) = twai.receive() {
|
|
||||||
//! break frame;
|
|
||||||
//! }
|
|
||||||
//! };
|
|
||||||
//!
|
//!
|
||||||
//! // Transmit the frame back.
|
//! // Transmit the frame back.
|
||||||
//! while twai.transmit(&frame).is_err() {}
|
//! let _result = block!(twai.transmit(&frame)).unwrap();
|
||||||
//! }
|
//! }
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
@ -84,6 +81,7 @@
|
|||||||
//! # use esp_hal::twai::EspTwaiFrame;
|
//! # use esp_hal::twai::EspTwaiFrame;
|
||||||
//! # use esp_hal::twai::StandardId;
|
//! # use esp_hal::twai::StandardId;
|
||||||
//! # use esp_hal::twai::TwaiMode;
|
//! # use esp_hal::twai::TwaiMode;
|
||||||
|
//! # use nb::block;
|
||||||
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI
|
//! // Use GPIO pins 2 and 3 to connect to the respective pins on the TWAI
|
||||||
//! // transceiver.
|
//! // transceiver.
|
||||||
//! let can_rx_pin = peripherals.GPIO3;
|
//! let can_rx_pin = peripherals.GPIO3;
|
||||||
@ -113,11 +111,7 @@
|
|||||||
//!
|
//!
|
||||||
//! let frame = EspTwaiFrame::new_self_reception(StandardId::ZERO,
|
//! let frame = EspTwaiFrame::new_self_reception(StandardId::ZERO,
|
||||||
//! &[1, 2, 3]).unwrap(); // Wait for a frame to be received.
|
//! &[1, 2, 3]).unwrap(); // Wait for a frame to be received.
|
||||||
//! let frame = loop {
|
//! let frame = block!(can.receive()).unwrap();
|
||||||
//! if let Ok(frame) = can.receive() {
|
|
||||||
//! break frame;
|
|
||||||
//! }
|
|
||||||
//! };
|
|
||||||
//!
|
//!
|
||||||
//! # loop {}
|
//! # loop {}
|
||||||
//! # }
|
//! # }
|
||||||
@ -1146,12 +1140,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sends the specified `EspTwaiFrame` over the TWAI bus.
|
/// Sends the specified `EspTwaiFrame` over the TWAI bus.
|
||||||
pub fn transmit(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
|
pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> {
|
||||||
self.tx.transmit(frame)
|
self.tx.transmit(frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receives a TWAI frame from the TWAI bus.
|
/// Receives a TWAI frame from the TWAI bus.
|
||||||
pub fn receive(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
|
pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
|
||||||
self.rx.receive()
|
self.rx.receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,16 +1179,18 @@ where
|
|||||||
/// NOTE: TODO: This may not work if using the self reception/self test
|
/// NOTE: TODO: This may not work if using the self reception/self test
|
||||||
/// functionality. See notes 1 and 2 in the "Frame Identifier" section
|
/// functionality. See notes 1 and 2 in the "Frame Identifier" section
|
||||||
/// of the reference manual.
|
/// of the reference manual.
|
||||||
pub fn transmit(&mut self, frame: &EspTwaiFrame) -> Result<(), EspTwaiError> {
|
pub fn transmit(&mut self, frame: &EspTwaiFrame) -> nb::Result<(), EspTwaiError> {
|
||||||
let register_block = self.twai.register_block();
|
let register_block = self.twai.register_block();
|
||||||
let status = register_block.status().read();
|
let status = register_block.status().read();
|
||||||
|
|
||||||
// Check that the peripheral is not in a bus off state.
|
// Check that the peripheral is not in a bus off state.
|
||||||
if status.bus_off_st().bit_is_set() {
|
if status.bus_off_st().bit_is_set() {
|
||||||
return Err(EspTwaiError::BusOff);
|
return nb::Result::Err(nb::Error::Other(EspTwaiError::BusOff));
|
||||||
}
|
}
|
||||||
// Check that the peripheral is not already transmitting a packet.
|
// Check that the peripheral is not already transmitting a packet.
|
||||||
while !status.tx_buf_st().bit_is_set() {}
|
if !status.tx_buf_st().bit_is_set() {
|
||||||
|
return nb::Result::Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
write_frame(register_block, frame);
|
write_frame(register_block, frame);
|
||||||
|
|
||||||
@ -1214,24 +1210,28 @@ where
|
|||||||
Dm: DriverMode,
|
Dm: DriverMode,
|
||||||
{
|
{
|
||||||
/// Receive a frame
|
/// Receive a frame
|
||||||
pub fn receive(&mut self) -> Result<EspTwaiFrame, EspTwaiError> {
|
pub fn receive(&mut self) -> nb::Result<EspTwaiFrame, EspTwaiError> {
|
||||||
let register_block = self.twai.register_block();
|
let register_block = self.twai.register_block();
|
||||||
let status = register_block.status().read();
|
let status = register_block.status().read();
|
||||||
|
|
||||||
// Check that the peripheral is not in a bus off state.
|
// Check that the peripheral is not in a bus off state.
|
||||||
if status.bus_off_st().bit_is_set() {
|
if status.bus_off_st().bit_is_set() {
|
||||||
return Err(EspTwaiError::BusOff);
|
return nb::Result::Err(nb::Error::Other(EspTwaiError::BusOff));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that we actually have packets to receive.
|
// Check that we actually have packets to receive.
|
||||||
while !status.rx_buf_st().bit_is_set() {}
|
if !status.rx_buf_st().bit_is_set() {
|
||||||
|
return nb::Result::Err(nb::Error::WouldBlock);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the packet in the receive buffer is valid or overrun.
|
// Check if the packet in the receive buffer is valid or overrun.
|
||||||
if status.miss_st().bit_is_set() {
|
if status.miss_st().bit_is_set() {
|
||||||
return Err(EspTwaiError::EmbeddedHAL(ErrorKind::Overrun));
|
return nb::Result::Err(nb::Error::Other(EspTwaiError::EmbeddedHAL(
|
||||||
|
ErrorKind::Overrun,
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
read_frame(register_block)
|
Ok(read_frame(register_block)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1302,21 +1302,18 @@ where
|
|||||||
type Error = EspTwaiError;
|
type Error = EspTwaiError;
|
||||||
|
|
||||||
/// Transmit a frame.
|
/// Transmit a frame.
|
||||||
fn transmit(
|
fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
|
||||||
&mut self,
|
|
||||||
frame: &Self::Frame,
|
|
||||||
) -> embedded_hal_nb::nb::Result<Option<Self::Frame>, Self::Error> {
|
|
||||||
self.tx.transmit(frame)?;
|
self.tx.transmit(frame)?;
|
||||||
|
|
||||||
// Success in readying packet for transmit. No packets can be replaced in the
|
// Success in readying packet for transmit. No packets can be replaced in the
|
||||||
// transmit buffer so return None in accordance with the
|
// transmit buffer so return None in accordance with the
|
||||||
// embedded-can/embedded-hal trait.
|
// embedded-can/embedded-hal trait.
|
||||||
embedded_hal_nb::nb::Result::Ok(None)
|
nb::Result::Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a received frame if there are any available.
|
/// Return a received frame if there are any available.
|
||||||
fn receive(&mut self) -> embedded_hal_nb::nb::Result<Self::Frame, Self::Error> {
|
fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
|
||||||
Ok(self.rx.receive()?)
|
self.rx.receive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -672,7 +672,7 @@ where
|
|||||||
|
|
||||||
/// Flush the transmit buffer of the UART
|
/// Flush the transmit buffer of the UART
|
||||||
pub fn flush(&mut self) {
|
pub fn flush(&mut self) {
|
||||||
while self.is_tx_idle() {}
|
while !self.is_tx_idle() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the TX line is idle for this UART instance.
|
/// Checks if the TX line is idle for this UART instance.
|
||||||
|
|||||||
@ -112,7 +112,7 @@
|
|||||||
//!
|
//!
|
||||||
//! writeln!(usb_serial, "USB serial interrupt").unwrap();
|
//! writeln!(usb_serial, "USB serial interrupt").unwrap();
|
||||||
//!
|
//!
|
||||||
//! while let Some(c) = usb_serial.read_byte() {
|
//! while let nb::Result::Ok(c) = usb_serial.read_byte() {
|
||||||
//! writeln!(usb_serial, "Read byte: {:02x}", c).unwrap();
|
//! writeln!(usb_serial, "Read byte: {:02x}", c).unwrap();
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
@ -198,6 +198,28 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write data to the serial output in a non-blocking manner
|
||||||
|
/// Requires manual flushing (automatically flushed every 64 bytes)
|
||||||
|
pub fn write_byte_nb(&mut self, word: u8) -> nb::Result<(), Error> {
|
||||||
|
let reg_block = USB_DEVICE::register_block();
|
||||||
|
|
||||||
|
if reg_block
|
||||||
|
.ep1_conf()
|
||||||
|
.read()
|
||||||
|
.serial_in_ep_data_free()
|
||||||
|
.bit_is_set()
|
||||||
|
{
|
||||||
|
// the FIFO is not full
|
||||||
|
unsafe {
|
||||||
|
reg_block.ep1().write(|w| w.rdwr_byte().bits(word));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(nb::Error::WouldBlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Flush the output FIFO and block until it has been sent
|
/// Flush the output FIFO and block until it has been sent
|
||||||
pub fn flush_tx(&mut self) -> Result<(), Error> {
|
pub fn flush_tx(&mut self) -> Result<(), Error> {
|
||||||
let reg_block = USB_DEVICE::register_block();
|
let reg_block = USB_DEVICE::register_block();
|
||||||
@ -209,6 +231,18 @@ where
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flush the output FIFO but don't block if it isn't ready immediately
|
||||||
|
pub fn flush_tx_nb(&mut self) -> nb::Result<(), Error> {
|
||||||
|
let reg_block = USB_DEVICE::register_block();
|
||||||
|
reg_block.ep1_conf().modify(|_, w| w.wr_done().set_bit());
|
||||||
|
|
||||||
|
if reg_block.ep1_conf().read().bits() & 0b011 == 0b000 {
|
||||||
|
Err(nb::Error::WouldBlock)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, Dm> UsbSerialJtagRx<'d, Dm>
|
impl<'d, Dm> UsbSerialJtagRx<'d, Dm>
|
||||||
@ -224,7 +258,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read a byte from the UART in a non-blocking manner
|
/// Read a byte from the UART in a non-blocking manner
|
||||||
pub fn read_byte(&mut self) -> Option<u8> {
|
pub fn read_byte(&mut self) -> nb::Result<u8, Error> {
|
||||||
let reg_block = USB_DEVICE::register_block();
|
let reg_block = USB_DEVICE::register_block();
|
||||||
|
|
||||||
// Check if there are any bytes to read
|
// Check if there are any bytes to read
|
||||||
@ -236,9 +270,9 @@ where
|
|||||||
{
|
{
|
||||||
let value = reg_block.ep1().read().rdwr_byte().bits();
|
let value = reg_block.ep1().read().rdwr_byte().bits();
|
||||||
|
|
||||||
Some(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(nb::Error::WouldBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +281,7 @@ where
|
|||||||
/// number of bytes in the FIFO is larger than `buf`.
|
/// number of bytes in the FIFO is larger than `buf`.
|
||||||
pub fn drain_rx_fifo(&mut self, buf: &mut [u8]) -> usize {
|
pub fn drain_rx_fifo(&mut self, buf: &mut [u8]) -> usize {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
while let Some(value) = self.read_byte() {
|
while let Ok(value) = self.read_byte() {
|
||||||
buf[count] = value;
|
buf[count] = value;
|
||||||
count += 1;
|
count += 1;
|
||||||
if count == buf.len() {
|
if count == buf.len() {
|
||||||
@ -373,13 +407,24 @@ where
|
|||||||
self.tx.write_bytes(data)
|
self.tx.write_bytes(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write data to the serial output in a non-blocking manner
|
||||||
|
/// Requires manual flushing (automatically flushed every 64 bytes)
|
||||||
|
pub fn write_byte_nb(&mut self, word: u8) -> nb::Result<(), Error> {
|
||||||
|
self.tx.write_byte_nb(word)
|
||||||
|
}
|
||||||
|
|
||||||
/// Flush the output FIFO and block until it has been sent
|
/// Flush the output FIFO and block until it has been sent
|
||||||
pub fn flush_tx(&mut self) -> Result<(), Error> {
|
pub fn flush_tx(&mut self) -> Result<(), Error> {
|
||||||
self.tx.flush_tx()
|
self.tx.flush_tx()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flush the output FIFO but don't block if it isn't ready immediately
|
||||||
|
pub fn flush_tx_nb(&mut self) -> nb::Result<(), Error> {
|
||||||
|
self.tx.flush_tx_nb()
|
||||||
|
}
|
||||||
|
|
||||||
/// Read a single byte but don't block if it isn't ready immediately
|
/// Read a single byte but don't block if it isn't ready immediately
|
||||||
pub fn read_byte(&mut self) -> Option<u8> {
|
pub fn read_byte(&mut self) -> nb::Result<u8, Error> {
|
||||||
self.rx.read_byte()
|
self.rx.read_byte()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +543,71 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::ErrorType for UsbSerialJtag<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::ErrorType for UsbSerialJtagTx<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::ErrorType for UsbSerialJtagRx<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::Read for UsbSerialJtag<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
|
embedded_hal_nb::serial::Read::read(&mut self.rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::Read for UsbSerialJtagRx<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
|
self.read_byte()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::Write for UsbSerialJtag<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
|
embedded_hal_nb::serial::Write::write(&mut self.tx, word)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
embedded_hal_nb::serial::Write::flush(&mut self.tx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Dm> embedded_hal_nb::serial::Write for UsbSerialJtagTx<'_, Dm>
|
||||||
|
where
|
||||||
|
Dm: DriverMode,
|
||||||
|
{
|
||||||
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
|
self.write_byte_nb(word)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
|
self.flush_tx_nb()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(doc, feature = "unstable"))]
|
#[cfg(any(doc, feature = "unstable"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
|
||||||
impl<Dm> embedded_io::ErrorType for UsbSerialJtag<'_, Dm>
|
impl<Dm> embedded_io::ErrorType for UsbSerialJtag<'_, Dm>
|
||||||
|
|||||||
@ -46,13 +46,8 @@ pub unsafe fn conjure() -> LpUart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// UART Error
|
/// UART Error
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
pub enum Error {}
|
||||||
#[non_exhaustive]
|
|
||||||
pub enum Error {
|
|
||||||
/// This operation requires blocking behavior to complete
|
|
||||||
WouldBlock,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
#[cfg(feature = "embedded-hal")]
|
||||||
impl embedded_hal_nb::serial::Error for Error {
|
impl embedded_hal_nb::serial::Error for Error {
|
||||||
@ -174,23 +169,24 @@ pub struct LpUart {
|
|||||||
|
|
||||||
impl LpUart {
|
impl LpUart {
|
||||||
/// Read a single byte from the UART in a non-blocking manner.
|
/// Read a single byte from the UART in a non-blocking manner.
|
||||||
pub fn read_byte(&mut self) -> Option<u8> {
|
pub fn read_byte(&mut self) -> nb::Result<u8, Error> {
|
||||||
if self.rx_fifo_count() > 0 {
|
if self.rx_fifo_count() > 0 {
|
||||||
Some(self.uart.fifo().read().rxfifo_rd_byte().bits())
|
let byte = self.uart.fifo().read().rxfifo_rd_byte().bits();
|
||||||
|
Ok(byte)
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(nb::Error::WouldBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a single byte to the UART in a non-blocking manner.
|
/// Write a single byte to the UART in a non-blocking manner.
|
||||||
pub fn write_byte(&mut self, byte: u8) -> Option<()> {
|
pub fn write_byte(&mut self, byte: u8) -> nb::Result<(), Error> {
|
||||||
if self.tx_fifo_count() < UART_FIFO_SIZE {
|
if self.tx_fifo_count() < UART_FIFO_SIZE {
|
||||||
self.uart
|
self.uart
|
||||||
.fifo()
|
.fifo()
|
||||||
.write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
|
.write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
|
||||||
Some(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(nb::Error::WouldBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,21 +195,18 @@ impl LpUart {
|
|||||||
pub fn write_bytes(&mut self, data: &[u8]) -> Result<usize, Error> {
|
pub fn write_bytes(&mut self, data: &[u8]) -> Result<usize, Error> {
|
||||||
let count = data.len();
|
let count = data.len();
|
||||||
|
|
||||||
for &byte in data {
|
data.iter()
|
||||||
if self.write_byte(byte).is_none() {
|
.try_for_each(|c| nb::block!(self.write_byte(*c)))?;
|
||||||
return Err(Error::WouldBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Flush the transmit buffer of the UART
|
/// Flush the UART's transmit buffer in a non-blocking manner.
|
||||||
pub fn flush(&mut self) -> Option<()> {
|
pub fn flush_tx(&mut self) -> nb::Result<(), Error> {
|
||||||
if self.is_tx_idle() {
|
if self.is_tx_idle() {
|
||||||
Some(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(nb::Error::WouldBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,21 +238,19 @@ impl embedded_hal_nb::serial::ErrorType for LpUart {
|
|||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
#[cfg(feature = "embedded-hal")]
|
||||||
impl embedded_hal_nb::serial::Read for LpUart {
|
impl embedded_hal_nb::serial::Read for LpUart {
|
||||||
fn read(&mut self) -> embedded_hal_nb::nb::Result<u8, Self::Error> {
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
self.read_byte()
|
self.read_byte()
|
||||||
.ok_or(embedded_hal_nb::nb::Error::WouldBlock)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "embedded-hal")]
|
#[cfg(feature = "embedded-hal")]
|
||||||
impl embedded_hal_nb::serial::Write for LpUart {
|
impl embedded_hal_nb::serial::Write for LpUart {
|
||||||
fn write(&mut self, word: u8) -> embedded_hal_nb::nb::Result<(), Self::Error> {
|
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
|
||||||
self.write_byte(word)
|
self.write_byte(word)
|
||||||
.ok_or(embedded_hal_nb::nb::Error::WouldBlock)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> embedded_hal_nb::nb::Result<(), Self::Error> {
|
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||||
self.flush().ok_or(embedded_hal_nb::nb::Error::WouldBlock)
|
self.flush_tx()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,9 +295,11 @@ impl embedded_io::Write for LpUart {
|
|||||||
|
|
||||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
loop {
|
loop {
|
||||||
match self.flush() {
|
match self.flush_tx() {
|
||||||
Some(_) => break,
|
Ok(_) => break,
|
||||||
None => { /* Wait */ }
|
Err(nb::Error::WouldBlock) => { /* Wait */ }
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
Err(nb::Error::Other(e)) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,7 @@ use esp_hal::{
|
|||||||
};
|
};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
use hmac::{Hmac as HmacSw, Mac};
|
use hmac::{Hmac as HmacSw, Mac};
|
||||||
|
use nb::block;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
|
|
||||||
type HmacSha256 = HmacSw<Sha256>;
|
type HmacSha256 = HmacSw<Sha256>;
|
||||||
@ -92,14 +93,12 @@ fn main() -> ! {
|
|||||||
let (nsrc, _) = src.split_at(i);
|
let (nsrc, _) = src.split_at(i);
|
||||||
let mut remaining = nsrc;
|
let mut remaining = nsrc;
|
||||||
hw_hmac.init();
|
hw_hmac.init();
|
||||||
hw_hmac
|
block!(hw_hmac.configure(HmacPurpose::ToUser, KeyId::Key0)).expect("Key purpose mismatch");
|
||||||
.configure(HmacPurpose::ToUser, KeyId::Key0)
|
|
||||||
.expect("Key purpose mismatch");
|
|
||||||
let pre_hw_hmac = esp_hal::time::now();
|
let pre_hw_hmac = esp_hal::time::now();
|
||||||
while remaining.len() > 0 {
|
while remaining.len() > 0 {
|
||||||
remaining = hw_hmac.update(remaining);
|
remaining = block!(hw_hmac.update(remaining)).unwrap();
|
||||||
}
|
}
|
||||||
hw_hmac.finalize(output.as_mut_slice());
|
block!(hw_hmac.finalize(output.as_mut_slice())).unwrap();
|
||||||
let post_hw_hmac = esp_hal::time::now();
|
let post_hw_hmac = esp_hal::time::now();
|
||||||
let hw_time = post_hw_hmac - pre_hw_hmac;
|
let hw_time = post_hw_hmac - pre_hw_hmac;
|
||||||
let mut sw_hmac = HmacSha256::new_from_slice(key).expect("HMAC can take key of any size");
|
let mut sw_hmac = HmacSha256::new_from_slice(key).expect("HMAC can take key of any size");
|
||||||
|
|||||||
@ -34,6 +34,7 @@ use esp_hal::{
|
|||||||
twai::{self, filter::SingleStandardFilter, EspTwaiFrame, StandardId, TwaiMode},
|
twai::{self, filter::SingleStandardFilter, EspTwaiFrame, StandardId, TwaiMode},
|
||||||
};
|
};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
|
use nb::block;
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
@ -81,22 +82,21 @@ fn main() -> ! {
|
|||||||
// Send a frame to the other ESP
|
// Send a frame to the other ESP
|
||||||
// Use `new_self_reception` if you want to use self-testing.
|
// Use `new_self_reception` if you want to use self-testing.
|
||||||
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
||||||
twai.transmit(&frame).unwrap();
|
block!(twai.transmit(&frame)).unwrap();
|
||||||
|
|
||||||
println!("Sent a frame");
|
println!("Sent a frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
loop {
|
loop {
|
||||||
// Wait for a frame to be received.
|
// Wait for a frame to be received.
|
||||||
let frame = twai.receive().unwrap();
|
let frame = block!(twai.receive()).unwrap();
|
||||||
|
|
||||||
println!("Received a frame: {frame:?}");
|
println!("Received a frame: {frame:?}");
|
||||||
delay.delay_millis(250);
|
delay.delay_millis(250);
|
||||||
|
|
||||||
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
||||||
// Transmit a new frame back to the other ESP
|
// Transmit a new frame back to the other ESP
|
||||||
twai.transmit(&frame).unwrap();
|
block!(twai.transmit(&frame)).unwrap();
|
||||||
println!("Sent a frame");
|
println!("Sent a frame");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -223,6 +223,7 @@ embassy-executor = { version = "0.6.0", default-features = false }
|
|||||||
embedded-test = { version = "0.5.0", git = "https://github.com/probe-rs/embedded-test.git", rev = "7109473", default-features = false }
|
embedded-test = { version = "0.5.0", git = "https://github.com/probe-rs/embedded-test.git", rev = "7109473", default-features = false }
|
||||||
fugit = "0.3.7"
|
fugit = "0.3.7"
|
||||||
hex-literal = "0.4.1"
|
hex-literal = "0.4.1"
|
||||||
|
nb = "1.1.0"
|
||||||
p192 = { version = "0.13.0", default-features = false, features = ["arithmetic"] }
|
p192 = { version = "0.13.0", default-features = false, features = ["arithmetic"] }
|
||||||
p256 = { version = "0.13.2", default-features = false, features = ["arithmetic"] }
|
p256 = { version = "0.13.2", default-features = false, features = ["arithmetic"] }
|
||||||
sha1 = { version = "0.10.6", default-features = false }
|
sha1 = { version = "0.10.6", default-features = false }
|
||||||
|
|||||||
@ -56,7 +56,7 @@ mod tests {
|
|||||||
fn init() -> Context<'static> {
|
fn init() -> Context<'static> {
|
||||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||||
let mut rsa = Rsa::new(peripherals.RSA);
|
let mut rsa = Rsa::new(peripherals.RSA);
|
||||||
rsa.ready();
|
nb::block!(rsa.ready()).unwrap();
|
||||||
|
|
||||||
Context { rsa }
|
Context { rsa }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ mod tests {
|
|||||||
fn init() -> Context<'static> {
|
fn init() -> Context<'static> {
|
||||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||||
let mut rsa = Rsa::new(peripherals.RSA).into_async();
|
let mut rsa = Rsa::new(peripherals.RSA).into_async();
|
||||||
rsa.ready();
|
nb::block!(rsa.ready()).unwrap();
|
||||||
|
|
||||||
Context { rsa }
|
Context { rsa }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ use esp_hal::{
|
|||||||
sha::{Sha, Sha1, Sha256, ShaAlgorithm, ShaDigest},
|
sha::{Sha, Sha1, Sha256, ShaAlgorithm, ShaDigest},
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
use nb::block;
|
||||||
|
|
||||||
/// Dummy data used to feed the hasher.
|
/// Dummy data used to feed the hasher.
|
||||||
const SOURCE_DATA: &[u8] = &[b'a'; 258];
|
const SOURCE_DATA: &[u8] = &[b'a'; 258];
|
||||||
@ -34,9 +35,9 @@ fn assert_sw_hash<D: Digest>(input: &[u8], expected_output: &[u8]) {
|
|||||||
fn hash_sha<S: ShaAlgorithm>(sha: &mut Sha<'static>, mut input: &[u8], output: &mut [u8]) {
|
fn hash_sha<S: ShaAlgorithm>(sha: &mut Sha<'static>, mut input: &[u8], output: &mut [u8]) {
|
||||||
let mut digest = sha.start::<S>();
|
let mut digest = sha.start::<S>();
|
||||||
while !input.is_empty() {
|
while !input.is_empty() {
|
||||||
input = digest.update(input);
|
input = block!(digest.update(input)).unwrap();
|
||||||
}
|
}
|
||||||
digest.finish(output);
|
block!(digest.finish(output)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_digest<'a, S: ShaAlgorithm>(sha: &'a mut Sha<'static>, input: &[u8], output: &mut [u8]) {
|
fn hash_digest<'a, S: ShaAlgorithm>(sha: &'a mut Sha<'static>, input: &[u8], output: &mut [u8]) {
|
||||||
@ -268,22 +269,22 @@ mod tests {
|
|||||||
let mut all_done = true;
|
let mut all_done = true;
|
||||||
if !sha1_remaining.is_empty() {
|
if !sha1_remaining.is_empty() {
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha1);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha1);
|
||||||
sha1_remaining = digest.update(sha1_remaining);
|
sha1_remaining = block!(digest.update(sha1_remaining)).unwrap();
|
||||||
digest.save(&mut sha1);
|
block!(digest.save(&mut sha1));
|
||||||
all_done = false;
|
all_done = false;
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "esp32"))]
|
#[cfg(not(feature = "esp32"))]
|
||||||
if !sha224_remaining.is_empty() {
|
if !sha224_remaining.is_empty() {
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha224);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha224);
|
||||||
sha224_remaining = digest.update(sha224_remaining);
|
sha224_remaining = block!(digest.update(sha224_remaining)).unwrap();
|
||||||
digest.save(&mut sha224);
|
block!(digest.save(&mut sha224));
|
||||||
all_done = false;
|
all_done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sha256_remaining.is_empty() {
|
if !sha256_remaining.is_empty() {
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha256);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha256);
|
||||||
sha256_remaining = digest.update(sha256_remaining);
|
sha256_remaining = block!(digest.update(sha256_remaining)).unwrap();
|
||||||
digest.save(&mut sha256);
|
block!(digest.save(&mut sha256));
|
||||||
all_done = false;
|
all_done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,15 +292,15 @@ mod tests {
|
|||||||
{
|
{
|
||||||
if !sha384_remaining.is_empty() {
|
if !sha384_remaining.is_empty() {
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha384);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha384);
|
||||||
sha384_remaining = digest.update(sha384_remaining);
|
sha384_remaining = block!(digest.update(sha384_remaining)).unwrap();
|
||||||
digest.save(&mut sha384);
|
block!(digest.save(&mut sha384));
|
||||||
all_done = false;
|
all_done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sha512_remaining.is_empty() {
|
if !sha512_remaining.is_empty() {
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha512);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha512);
|
||||||
sha512_remaining = digest.update(sha512_remaining);
|
sha512_remaining = block!(digest.update(sha512_remaining)).unwrap();
|
||||||
digest.save(&mut sha512);
|
block!(digest.save(&mut sha512));
|
||||||
all_done = false;
|
all_done = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,17 +311,17 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha1);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha1);
|
||||||
digest.finish(sha1_p.1);
|
block!(digest.finish(sha1_p.1)).unwrap();
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha224);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha224);
|
||||||
digest.finish(sha224_p.1);
|
block!(digest.finish(sha224_p.1)).unwrap();
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha256);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha256);
|
||||||
digest.finish(sha256_p.1);
|
block!(digest.finish(sha256_p.1)).unwrap();
|
||||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||||
{
|
{
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha384);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha384);
|
||||||
digest.finish(sha384_p.1);
|
block!(digest.finish(sha384_p.1)).unwrap();
|
||||||
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha512);
|
let mut digest = ShaDigest::restore(&mut ctx.sha, &mut sha512);
|
||||||
digest.finish(sha512_p.1);
|
block!(digest.finish(sha512_p.1)).unwrap();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use esp_hal::{
|
|||||||
Blocking,
|
Blocking,
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
use nb::block;
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
twai: twai::Twai<'static, Blocking>,
|
twai: twai::Twai<'static, Blocking>,
|
||||||
@ -51,9 +52,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_send_receive(mut ctx: Context) {
|
fn test_send_receive(mut ctx: Context) {
|
||||||
let frame = EspTwaiFrame::new_self_reception(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
let frame = EspTwaiFrame::new_self_reception(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
||||||
ctx.twai.transmit(&frame).unwrap();
|
block!(ctx.twai.transmit(&frame)).unwrap();
|
||||||
|
|
||||||
let frame = ctx.twai.receive().unwrap();
|
let frame = block!(ctx.twai.receive()).unwrap();
|
||||||
|
|
||||||
assert_eq!(frame.data(), &[1, 2, 3])
|
assert_eq!(frame.data(), &[1, 2, 3])
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user