Jesse Braham 3079d9cc49
Feature gate embedded-hal@0.2.x implementations, rename eh1 feature to embedded-hal (#1273)
* Create an `embedded-hal-02` feature and gate implementations, rename `eh1` to `embedded-hal`

* Use native `Delay` APIs in examples where applicable

* Fix example imports, be explicit about about `embedded-hal-02` feature requirements

* Update `CHANGELOG.md`
2024-03-14 15:40:44 +00:00

102 lines
3.4 KiB
Rust

//! This example sends a CAN message to another ESP and receives it back.
//!
//! Wiring:
//! This example works without CAN Transceivers by:
//! * setting the tx pins to open drain
//! * connecting all rx and tx pins together
//! * adding a pull-up to the signal pins
//!
//! ESP1/GND --- ESP2/GND
//! ESP1/IO0 --- ESP1/IO1 --- ESP2/IO0 --- ESP2/IO1 --- 4.8kOhm --- ESP1/5V
//!
//! `IS_FIRST_SENDER` below must be set to false on one of the ESP's
//% CHIPS: esp32c3 esp32s3
#![no_std]
#![no_main]
const IS_FIRST_SENDER: bool = true;
// Run this example with the embedded-hal feature enabled to use embedded-can instead of
// embedded-hal-0.2.7. embedded-can was split off from embedded-hal before it's
// upgrade to 1.0.0. cargo run --example twai --features embedded-hal --release
#[cfg(feature = "embedded-hal")]
use embedded_can::{nb::Can, Frame, StandardId};
// Run this example without the embedded-hal flag to use the embedded-hal 0.2.7 CAN traits.
// cargo run --example twai --release
#[cfg(not(feature = "embedded-hal"))]
use embedded_hal_02::can::{Can, Frame, StandardId};
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
gpio::IO,
peripherals::Peripherals,
prelude::*,
twai,
twai::filter::SingleStandardFilter,
};
use esp_println::println;
use nb::block;
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
// Set the tx pin as open drain. Skip this if using transceivers.
let can_tx_pin = io.pins.gpio0.into_open_drain_output();
let can_rx_pin = io.pins.gpio1;
// The speed of the CAN bus.
const CAN_BAUDRATE: twai::BaudRate = twai::BaudRate::B1000K;
// Begin configuring the TWAI peripheral. The peripheral is in a reset like
// state that prevents transmission but allows configuration.
let mut can_config = twai::TwaiConfiguration::new(
peripherals.TWAI0,
can_tx_pin,
can_rx_pin,
&clocks,
CAN_BAUDRATE,
);
// 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.
const FILTER: SingleStandardFilter =
SingleStandardFilter::new(b"00000000000", b"x", [b"xxxxxxxx", b"xxxxxxxx"]);
can_config.set_filter(FILTER);
// 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 can = can_config.start();
if IS_FIRST_SENDER {
// Send a frame to the other ESP
let frame = Frame::new(StandardId::ZERO, &[1, 2, 3]).unwrap();
block!(can.transmit(&frame)).unwrap();
println!("Sent a frame");
}
// Wait for a frame to be received.
let frame = block!(can.receive()).unwrap();
println!("Received a frame: {frame:?}");
if !IS_FIRST_SENDER {
// Transmit the frame back to the other ESP
block!(can.transmit(&frame)).unwrap();
println!("Sent a frame");
}
loop {}
}