mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
103 lines
3.7 KiB
Rust
103 lines
3.7 KiB
Rust
//! This example sends a TWAI message to another ESP and receives it back.
|
|
//!
|
|
//! `IS_FIRST_SENDER` below must be set to false on one of the ESP's
|
|
//!
|
|
//! In case you want to use `self-testing`, get rid of everything related to the aforementioned `IS_FIRST_SENDER`
|
|
//! and follow the advice in the comments related to this mode.
|
|
//!
|
|
//! The following wiring is assumed:
|
|
//! - TX/RX => GPIO2, connected internally and with internal pull-up resistor.
|
|
//!
|
|
//! ESP1/GND --- ESP2/GND
|
|
//! ESP1/GPIO2 --- ESP2/GPIO2
|
|
//!
|
|
//! Notes for external transceiver use:
|
|
//!
|
|
//! The default setup assumes that two microcontrollers are connected directly without an external
|
|
//! transceiver. If you want to use an external transceiver, you need to:
|
|
//! * uncomment the `rx_pin` line
|
|
//! * use `new()` function to create the TWAI configuration.
|
|
//! * change the `tx_pin` and `rx_pin` to the appropriate pins for your boards.
|
|
|
|
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
|
//% FEATURES: esp-hal/unstable
|
|
|
|
#![no_std]
|
|
#![no_main]
|
|
|
|
const IS_FIRST_SENDER: bool = true;
|
|
|
|
use esp_backtrace as _;
|
|
use esp_hal::{
|
|
delay::Delay,
|
|
entry,
|
|
twai::{self, filter::SingleStandardFilter, EspTwaiFrame, StandardId, TwaiMode},
|
|
};
|
|
use esp_println::println;
|
|
use nb::block;
|
|
|
|
#[entry]
|
|
fn main() -> ! {
|
|
let peripherals = esp_hal::init(esp_hal::Config::default());
|
|
|
|
// Without an external transceiver, we only need a single line between the two MCUs.
|
|
let (rx_pin, tx_pin) = peripherals.GPIO2.split();
|
|
// Use these if you want to use an external transceiver:
|
|
// let tx_pin = peripherals.GPIO2;
|
|
// let rx_pin = peripherals.GPIO0;
|
|
|
|
// The speed of the bus.
|
|
const TWAI_BAUDRATE: twai::BaudRate = twai::BaudRate::B125K;
|
|
|
|
// !!! Use `new` when using a transceiver. `new_no_transceiver` sets TX to open-drain
|
|
// Self-testing also works using the regular `new` function.
|
|
|
|
// Begin configuring the TWAI peripheral. The peripheral is in a reset like
|
|
// state that prevents transmission but allows configuration.
|
|
// For self-testing use `SelfTest` mode of the TWAI peripheral.
|
|
let mut twai_config = twai::TwaiConfiguration::new_no_transceiver(
|
|
peripherals.TWAI0,
|
|
rx_pin,
|
|
tx_pin,
|
|
TWAI_BAUDRATE,
|
|
TwaiMode::Normal,
|
|
);
|
|
|
|
// Partially filter the incoming messages to reduce overhead of receiving
|
|
// undesired messages. Note that due to how the hardware filters messages,
|
|
// standard ids and extended ids may both match a filter. Frame ids should
|
|
// be explicitly checked in the application instead of fully relying on
|
|
// these partial acceptance filters to exactly match.
|
|
// A filter that matches StandardId::ZERO.
|
|
twai_config.set_filter(
|
|
const { SingleStandardFilter::new(b"xxxxxxxxxx1", b"x", [b"xxxxxxxx", b"xxxxxxxx"]) },
|
|
);
|
|
|
|
// Start the peripheral. This locks the configuration settings of the peripheral
|
|
// and puts it into operation mode, allowing packets to be sent and
|
|
// received.
|
|
let mut twai = twai_config.start();
|
|
|
|
if IS_FIRST_SENDER {
|
|
// Send a frame to the other ESP
|
|
// Use `new_self_reception` if you want to use self-testing.
|
|
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
|
block!(twai.transmit(&frame)).unwrap();
|
|
println!("Sent a frame");
|
|
}
|
|
|
|
let delay = Delay::new();
|
|
loop {
|
|
// Wait for a frame to be received.
|
|
let frame = block!(twai.receive()).unwrap();
|
|
|
|
println!("Received a frame: {frame:?}");
|
|
delay.delay_millis(250);
|
|
|
|
let frame = EspTwaiFrame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
|
|
// Transmit a new frame back to the other ESP
|
|
block!(twai.transmit(&frame)).unwrap();
|
|
println!("Sent a frame");
|
|
}
|
|
}
|