mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-26 20:00:32 +00:00
Add BLE examples using trouBLE, move some Wi-Fi examples to qa-test
(#3999)
* Move `embassy_wifi_bench`, `wifi_bench`, and `wifi_csi` examples to `qa-test` package * Remove blocking BLE example, replace Embassy example with trouble-based scanner * Add BLE `bas_peripheral` example
This commit is contained in:
parent
588140a55f
commit
1ecb6f5f76
@ -1,19 +1,14 @@
|
||||
[package]
|
||||
name = "embassy-bench"
|
||||
name = "bas-peripheral"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
bt-hci = "0.4.0"
|
||||
embassy-executor = { version = "0.7.0", features = ["task-arena-size-20480"] }
|
||||
embassy-futures = "0.1.1"
|
||||
embassy-net = { version = "0.6.0", features = [
|
||||
"dhcpv4",
|
||||
"medium-ethernet",
|
||||
"tcp",
|
||||
"udp",
|
||||
] }
|
||||
embassy-sync = "0.7.2"
|
||||
embassy-time = "0.4.0"
|
||||
esp-alloc = { path = "../../../esp-alloc" }
|
||||
esp-backtrace = { path = "../../../esp-backtrace", features = [
|
||||
@ -24,15 +19,20 @@ esp-bootloader-esp-idf = { path = "../../../esp-bootloader-esp-idf" }
|
||||
esp-hal-embassy = { path = "../../../esp-hal-embassy" }
|
||||
esp-hal = { path = "../../../esp-hal", features = ["log-04", "unstable"] }
|
||||
esp-println = { path = "../../../esp-println", features = ["log-04"] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = [
|
||||
"log-04",
|
||||
] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = ["log-04"] }
|
||||
esp-radio = { path = "../../../esp-radio", features = [
|
||||
"ble",
|
||||
"log-04",
|
||||
"unstable",
|
||||
"wifi",
|
||||
] }
|
||||
static_cell = "2.1.0"
|
||||
heapless = "0.9.1"
|
||||
log = "0.4.27"
|
||||
trouble-host = { git = "https://github.com/embassy-rs/trouble", rev = "366ee88", features = [
|
||||
"default-packet-pool-mtu-255",
|
||||
"derive",
|
||||
"scan",
|
||||
] }
|
||||
static_cell = "2.1.1"
|
||||
|
||||
[features]
|
||||
esp32 = [
|
||||
@ -67,13 +67,13 @@ esp32c6 = [
|
||||
"esp-preempt/esp32c6",
|
||||
"esp-radio/esp32c6",
|
||||
]
|
||||
esp32s2 = [
|
||||
"esp-backtrace/esp32s2",
|
||||
"esp-bootloader-esp-idf/esp32s2",
|
||||
"esp-hal-embassy/esp32s2",
|
||||
"esp-hal/esp32s2",
|
||||
"esp-preempt/esp32s2",
|
||||
"esp-radio/esp32s2",
|
||||
esp32h2 = [
|
||||
"esp-backtrace/esp32h2",
|
||||
"esp-bootloader-esp-idf/esp32h2",
|
||||
"esp-hal-embassy/esp32h2",
|
||||
"esp-hal/esp32h2",
|
||||
"esp-preempt/esp32h2",
|
||||
"esp-radio/esp32h2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"esp-backtrace/esp32s3",
|
242
examples/ble/bas_peripheral/src/main.rs
Normal file
242
examples/ble/bas_peripheral/src/main.rs
Normal file
@ -0,0 +1,242 @@
|
||||
//! A bluetooth battery service example built using Embassy and trouBLE.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::{join::join, select::select};
|
||||
use embassy_time::Timer;
|
||||
use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{clock::CpuClock, timer::timg::TimerGroup};
|
||||
use esp_radio::ble::controller::BleConnector;
|
||||
use log::{info, warn};
|
||||
use static_cell::StaticCell;
|
||||
use trouble_host::prelude::*;
|
||||
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(_s: Spawner) {
|
||||
esp_println::logger::init_logger_from_env();
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default().with_cpu_clock(CpuClock::max()));
|
||||
esp_alloc::heap_allocator!(size: 72 * 1024);
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
esp_preempt::init(timg0.timer0);
|
||||
|
||||
static RADIO: StaticCell<esp_radio::Controller<'static>> = StaticCell::new();
|
||||
let radio = RADIO.init(esp_radio::init().unwrap());
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
{
|
||||
let systimer = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER);
|
||||
esp_hal_embassy::init(systimer.alarm0);
|
||||
}
|
||||
#[cfg(feature = "esp32")]
|
||||
{
|
||||
esp_hal_embassy::init(timg0.timer1);
|
||||
}
|
||||
|
||||
let bluetooth = peripherals.BT;
|
||||
let connector = BleConnector::new(radio, bluetooth);
|
||||
let controller: ExternalController<_, 20> = ExternalController::new(connector);
|
||||
|
||||
ble_bas_peripheral_run(controller).await;
|
||||
}
|
||||
|
||||
/// Max number of connections
|
||||
const CONNECTIONS_MAX: usize = 1;
|
||||
/// Max number of L2CAP channels.
|
||||
const L2CAP_CHANNELS_MAX: usize = 2; // Signal + att
|
||||
|
||||
// GATT Server definition
|
||||
#[gatt_server]
|
||||
struct Server {
|
||||
battery_service: BatteryService,
|
||||
}
|
||||
|
||||
/// Battery service
|
||||
#[gatt_service(uuid = service::BATTERY)]
|
||||
struct BatteryService {
|
||||
/// Battery Level
|
||||
#[descriptor(uuid = descriptors::VALID_RANGE, read, value = [0, 100])]
|
||||
#[descriptor(uuid = descriptors::MEASUREMENT_DESCRIPTION, name = "hello", read, value = "Battery Level")]
|
||||
#[characteristic(uuid = characteristic::BATTERY_LEVEL, read, notify, value = 10)]
|
||||
level: u8,
|
||||
#[characteristic(uuid = "408813df-5dd4-1f87-ec11-cdb001100000", write, read, notify)]
|
||||
status: bool,
|
||||
}
|
||||
|
||||
/// Run the BLE stack.
|
||||
pub async fn ble_bas_peripheral_run<C>(controller: C)
|
||||
where
|
||||
C: Controller,
|
||||
{
|
||||
// Using a fixed "random" address can be useful for testing. In real scenarios, one would
|
||||
// use e.g. the MAC 6 byte array as the address (how to get that varies by the platform).
|
||||
let address: Address = Address::random([0xff, 0x8f, 0x1a, 0x05, 0xe4, 0xff]);
|
||||
info!("Our address = {:?}", address);
|
||||
|
||||
let mut resources: HostResources<DefaultPacketPool, CONNECTIONS_MAX, L2CAP_CHANNELS_MAX> =
|
||||
HostResources::new();
|
||||
let stack = trouble_host::new(controller, &mut resources).set_random_address(address);
|
||||
let Host {
|
||||
mut peripheral,
|
||||
runner,
|
||||
..
|
||||
} = stack.build();
|
||||
|
||||
info!("Starting advertising and GATT service");
|
||||
let server = Server::new_with_config(GapConfig::Peripheral(PeripheralConfig {
|
||||
name: "TrouBLE",
|
||||
appearance: &appearance::power_device::GENERIC_POWER_DEVICE,
|
||||
}))
|
||||
.unwrap();
|
||||
|
||||
let _ = join(ble_task(runner), async {
|
||||
loop {
|
||||
match advertise("Trouble Example", &mut peripheral, &server).await {
|
||||
Ok(conn) => {
|
||||
// set up tasks when the connection is established to a central, so they don't
|
||||
// run when no one is connected.
|
||||
let a = gatt_events_task(&server, &conn);
|
||||
let b = custom_task(&server, &conn, &stack);
|
||||
// run until any task ends (usually because the connection has been closed),
|
||||
// then return to advertising state.
|
||||
select(a, b).await;
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("[adv] error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
/// This is a background task that is required to run forever alongside any other BLE tasks.
|
||||
///
|
||||
/// ## Alternative
|
||||
///
|
||||
/// If you didn't require this to be generic for your application, you could statically spawn this
|
||||
/// with i.e.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
///
|
||||
/// #[embassy_executor::task]
|
||||
/// async fn ble_task(mut runner: Runner<'static, SoftdeviceController<'static>>) {
|
||||
/// runner.run().await;
|
||||
/// }
|
||||
///
|
||||
/// spawner.must_spawn(ble_task(runner));
|
||||
/// ```
|
||||
async fn ble_task<C: Controller, P: PacketPool>(mut runner: Runner<'_, C, P>) {
|
||||
loop {
|
||||
if let Err(e) = runner.run().await {
|
||||
panic!("[ble_task] error: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stream Events until the connection closes.
|
||||
///
|
||||
/// This function will handle the GATT events and process them.
|
||||
/// This is how we interact with read and write requests.
|
||||
async fn gatt_events_task<P: PacketPool>(
|
||||
server: &Server<'_>,
|
||||
conn: &GattConnection<'_, '_, P>,
|
||||
) -> Result<(), Error> {
|
||||
let level = server.battery_service.level;
|
||||
let reason = loop {
|
||||
match conn.next().await {
|
||||
GattConnectionEvent::Disconnected { reason } => break reason,
|
||||
GattConnectionEvent::Gatt { event } => {
|
||||
match &event {
|
||||
GattEvent::Read(event) => {
|
||||
if event.handle() == level.handle {
|
||||
let value = server.get(&level);
|
||||
info!("[gatt] Read Event to Level Characteristic: {:?}", value);
|
||||
}
|
||||
}
|
||||
GattEvent::Write(event) => {
|
||||
if event.handle() == level.handle {
|
||||
info!(
|
||||
"[gatt] Write Event to Level Characteristic: {:?}",
|
||||
event.data()
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
// This step is also performed at drop(), but writing it explicitly is necessary
|
||||
// in order to ensure reply is sent.
|
||||
match event.accept() {
|
||||
Ok(reply) => reply.send().await,
|
||||
Err(e) => warn!("[gatt] error sending response: {:?}", e),
|
||||
};
|
||||
}
|
||||
_ => {} // ignore other Gatt Connection Events
|
||||
}
|
||||
};
|
||||
info!("[gatt] disconnected: {:?}", reason);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create an advertiser to use to connect to a BLE Central, and wait for it to connect.
|
||||
async fn advertise<'values, 'server, C: Controller>(
|
||||
name: &'values str,
|
||||
peripheral: &mut Peripheral<'values, C, DefaultPacketPool>,
|
||||
server: &'server Server<'values>,
|
||||
) -> Result<GattConnection<'values, 'server, DefaultPacketPool>, BleHostError<C::Error>> {
|
||||
let mut advertiser_data = [0; 31];
|
||||
let len = AdStructure::encode_slice(
|
||||
&[
|
||||
AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED),
|
||||
AdStructure::ServiceUuids16(&[[0x0f, 0x18]]),
|
||||
AdStructure::CompleteLocalName(name.as_bytes()),
|
||||
],
|
||||
&mut advertiser_data[..],
|
||||
)?;
|
||||
let advertiser = peripheral
|
||||
.advertise(
|
||||
&Default::default(),
|
||||
Advertisement::ConnectableScannableUndirected {
|
||||
adv_data: &advertiser_data[..len],
|
||||
scan_data: &[],
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
info!("[adv] advertising");
|
||||
let conn = advertiser.accept().await?.with_attribute_server(server)?;
|
||||
info!("[adv] connection established");
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
/// Example task to use the BLE notifier interface.
|
||||
/// This task will notify the connected central of a counter value every 2 seconds.
|
||||
/// It will also read the RSSI value every 2 seconds.
|
||||
/// and will stop when the connection is closed by the central or an error occurs.
|
||||
async fn custom_task<C: Controller, P: PacketPool>(
|
||||
server: &Server<'_>,
|
||||
conn: &GattConnection<'_, '_, P>,
|
||||
stack: &Stack<'_, C, P>,
|
||||
) {
|
||||
let mut tick: u8 = 0;
|
||||
let level = server.battery_service.level;
|
||||
loop {
|
||||
tick = tick.wrapping_add(1);
|
||||
info!("[custom_task] notifying connection of tick {}", tick);
|
||||
if level.notify(conn, &tick).await.is_err() {
|
||||
info!("[custom_task] error notifying connection");
|
||||
break;
|
||||
};
|
||||
// read RSSI (Received Signal Strength Indicator) of the connection.
|
||||
if let Ok(rssi) = conn.raw().rssi(stack).await {
|
||||
info!("[custom_task] RSSI: {:?}", rssi);
|
||||
} else {
|
||||
info!("[custom_task] error getting RSSI");
|
||||
break;
|
||||
};
|
||||
Timer::after_secs(2).await;
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
[package]
|
||||
name = "ble"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8", features = [
|
||||
"async",
|
||||
"macros",
|
||||
] }
|
||||
cfg-if = "1.0.0"
|
||||
esp-alloc = { path = "../../../esp-alloc" }
|
||||
esp-backtrace = { path = "../../../esp-backtrace", features = [
|
||||
"panic-handler",
|
||||
"println",
|
||||
] }
|
||||
esp-bootloader-esp-idf = { path = "../../../esp-bootloader-esp-idf" }
|
||||
esp-hal = { path = "../../../esp-hal", features = ["log-04", "unstable"] }
|
||||
esp-println = { path = "../../../esp-println", features = ["log-04"] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = [
|
||||
"log-04",
|
||||
] }
|
||||
esp-radio = { path = "../../../esp-radio", features = [
|
||||
"ble",
|
||||
"log-04",
|
||||
"unstable",
|
||||
] }
|
||||
|
||||
[features]
|
||||
esp32 = [
|
||||
"esp-backtrace/esp32",
|
||||
"esp-bootloader-esp-idf/esp32",
|
||||
"esp-hal/esp32",
|
||||
"esp-preempt/esp32",
|
||||
"esp-radio/esp32",
|
||||
]
|
||||
esp32c2 = [
|
||||
"esp-backtrace/esp32c2",
|
||||
"esp-bootloader-esp-idf/esp32c2",
|
||||
"esp-hal/esp32c2",
|
||||
"esp-preempt/esp32c2",
|
||||
"esp-radio/esp32c2",
|
||||
]
|
||||
esp32c3 = [
|
||||
"esp-backtrace/esp32c3",
|
||||
"esp-bootloader-esp-idf/esp32c3",
|
||||
"esp-hal/esp32c3",
|
||||
"esp-preempt/esp32c3",
|
||||
"esp-radio/esp32c3",
|
||||
]
|
||||
esp32c6 = [
|
||||
"esp-backtrace/esp32c6",
|
||||
"esp-bootloader-esp-idf/esp32c6",
|
||||
"esp-hal/esp32c6",
|
||||
"esp-preempt/esp32c6",
|
||||
"esp-radio/esp32c6",
|
||||
]
|
||||
esp32h2 = [
|
||||
"esp-backtrace/esp32h2",
|
||||
"esp-bootloader-esp-idf/esp32h2",
|
||||
"esp-hal/esp32h2",
|
||||
"esp-preempt/esp32h2",
|
||||
"esp-radio/esp32h2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"esp-backtrace/esp32s3",
|
||||
"esp-bootloader-esp-idf/esp32s3",
|
||||
"esp-hal/esp32s3",
|
||||
"esp-preempt/esp32s3",
|
||||
"esp-radio/esp32s3",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
@ -1,170 +0,0 @@
|
||||
//! BLE Example
|
||||
//!
|
||||
//! - starts Bluetooth advertising
|
||||
//! - offers one service with three characteristics (one is read/write, one is write only, one is
|
||||
//! read/write/notify)
|
||||
//! - pressing the boot-button on a dev-board will send a notification if it is subscribed
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use bleps::{
|
||||
Ble,
|
||||
HciConnector,
|
||||
ad_structure::{
|
||||
AdStructure,
|
||||
BR_EDR_NOT_SUPPORTED,
|
||||
LE_GENERAL_DISCOVERABLE,
|
||||
create_advertising_data,
|
||||
},
|
||||
attribute_server::{AttributeServer, NotificationData, WorkResult},
|
||||
gatt,
|
||||
};
|
||||
use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::CpuClock,
|
||||
gpio::{Input, InputConfig, Pull},
|
||||
main,
|
||||
time,
|
||||
timer::timg::TimerGroup,
|
||||
};
|
||||
use esp_println::println;
|
||||
use esp_radio::ble::controller::BleConnector;
|
||||
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
#[main]
|
||||
fn main() -> ! {
|
||||
esp_println::logger::init_logger_from_env();
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
let peripherals = esp_hal::init(config);
|
||||
|
||||
esp_alloc::heap_allocator!(size: 72 * 1024);
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
esp_preempt::init(timg0.timer0);
|
||||
|
||||
let esp_radio_ctrl = esp_radio::init().unwrap();
|
||||
|
||||
let config = InputConfig::default().with_pull(Pull::Down);
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(feature = "esp32", feature = "esp32s3"))] {
|
||||
let button = Input::new(peripherals.GPIO0, config);
|
||||
} else {
|
||||
let button = Input::new(peripherals.GPIO9, config);
|
||||
}
|
||||
}
|
||||
|
||||
let mut debounce_cnt = 500;
|
||||
|
||||
let mut bluetooth = peripherals.BT;
|
||||
|
||||
let now = || time::Instant::now().duration_since_epoch().as_millis();
|
||||
loop {
|
||||
let connector = BleConnector::new(&esp_radio_ctrl, bluetooth.reborrow());
|
||||
let hci = HciConnector::new(connector, now);
|
||||
let mut ble = Ble::new(&hci);
|
||||
|
||||
println!("{:?}", ble.init());
|
||||
println!("{:?}", ble.cmd_set_le_advertising_parameters());
|
||||
println!(
|
||||
"{:?}",
|
||||
ble.cmd_set_le_advertising_data(
|
||||
create_advertising_data(&[
|
||||
AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED),
|
||||
AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]),
|
||||
AdStructure::CompleteLocalName(esp_hal::chip!()),
|
||||
])
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
println!("{:?}", ble.cmd_set_le_advertise_enable(true));
|
||||
|
||||
println!("started advertising");
|
||||
|
||||
let mut rf = |_offset: usize, data: &mut [u8]| {
|
||||
data[..20].copy_from_slice(&b"Hello Bare-Metal BLE"[..]);
|
||||
17
|
||||
};
|
||||
let mut wf = |offset: usize, data: &[u8]| {
|
||||
println!("RECEIVED: {} {:?}", offset, data);
|
||||
};
|
||||
|
||||
let mut wf2 = |offset: usize, data: &[u8]| {
|
||||
println!("RECEIVED: {} {:?}", offset, data);
|
||||
};
|
||||
|
||||
let mut rf3 = |_offset: usize, data: &mut [u8]| {
|
||||
data[..5].copy_from_slice(&b"Hola!"[..]);
|
||||
5
|
||||
};
|
||||
let mut wf3 = |offset: usize, data: &[u8]| {
|
||||
println!("RECEIVED: Offset {}, data {:?}", offset, data);
|
||||
};
|
||||
|
||||
gatt!([service {
|
||||
uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
characteristics: [
|
||||
characteristic {
|
||||
uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
read: rf,
|
||||
write: wf,
|
||||
},
|
||||
characteristic {
|
||||
uuid: "957312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
write: wf2,
|
||||
},
|
||||
characteristic {
|
||||
name: "my_characteristic",
|
||||
uuid: "987312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
notify: true,
|
||||
read: rf3,
|
||||
write: wf3,
|
||||
},
|
||||
],
|
||||
},]);
|
||||
|
||||
let mut rng = bleps::no_rng::NoRng;
|
||||
let mut srv = AttributeServer::new(&mut ble, &mut gatt_attributes, &mut rng);
|
||||
|
||||
loop {
|
||||
let mut notification = None;
|
||||
|
||||
if button.is_low() && debounce_cnt > 0 {
|
||||
debounce_cnt -= 1;
|
||||
if debounce_cnt == 0 {
|
||||
let mut cccd = [0u8; 1];
|
||||
if let Some(1) = srv.get_characteristic_value(
|
||||
my_characteristic_notify_enable_handle,
|
||||
0,
|
||||
&mut cccd,
|
||||
) {
|
||||
// if notifications enabled
|
||||
if cccd[0] == 1 {
|
||||
notification = Some(NotificationData::new(
|
||||
my_characteristic_handle,
|
||||
&b"Notification"[..],
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if button.is_high() {
|
||||
debounce_cnt = 500;
|
||||
}
|
||||
|
||||
match srv.do_work_with_notification(notification) {
|
||||
Ok(res) => {
|
||||
if let WorkResult::GotDisconnected = res {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
println!("{:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
//! Embassy BLE Example
|
||||
//!
|
||||
//! - starts Bluetooth advertising
|
||||
//! - offers one service with three characteristics (one is read/write, one is write only, one is
|
||||
//! read/write/notify)
|
||||
//! - pressing the boot-button on a dev-board will send a notification if it is subscribed
|
||||
|
||||
// Embassy offers another compatible BLE crate [trouble](https://github.com/embassy-rs/trouble/tree/main/examples/esp32) with esp32 examples.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bleps::{
|
||||
ad_structure::{
|
||||
AdStructure,
|
||||
BR_EDR_NOT_SUPPORTED,
|
||||
LE_GENERAL_DISCOVERABLE,
|
||||
create_advertising_data,
|
||||
},
|
||||
async_attribute_server::AttributeServer,
|
||||
asynch::Ble,
|
||||
attribute_server::NotificationData,
|
||||
gatt,
|
||||
};
|
||||
use embassy_executor::Spawner;
|
||||
use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::CpuClock,
|
||||
gpio::{Input, InputConfig, Pull},
|
||||
time,
|
||||
timer::timg::TimerGroup,
|
||||
};
|
||||
use esp_println::println;
|
||||
use esp_radio::{Controller, ble::controller::BleConnector};
|
||||
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html
|
||||
macro_rules! mk_static {
|
||||
($t:ty,$val:expr) => {{
|
||||
static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new();
|
||||
#[deny(unused_attributes)]
|
||||
let x = STATIC_CELL.uninit().write(($val));
|
||||
x
|
||||
}};
|
||||
}
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
esp_println::logger::init_logger_from_env();
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
let peripherals = esp_hal::init(config);
|
||||
|
||||
esp_alloc::heap_allocator!(size: 72 * 1024);
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
esp_preempt::init(timg0.timer0);
|
||||
|
||||
let esp_radio_ctrl = &*mk_static!(Controller<'static>, esp_radio::init().unwrap());
|
||||
|
||||
let config = InputConfig::default().with_pull(Pull::Down);
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(feature = "esp32", feature = "esp32s3"))] {
|
||||
let button = Input::new(peripherals.GPIO0, config);
|
||||
} else {
|
||||
let button = Input::new(peripherals.GPIO9, config);
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "esp32")] {
|
||||
let timg1 = TimerGroup::new(peripherals.TIMG1);
|
||||
esp_hal_embassy::init(timg1.timer0);
|
||||
} else {
|
||||
use esp_hal::timer::systimer::SystemTimer;
|
||||
let systimer = SystemTimer::new(peripherals.SYSTIMER);
|
||||
esp_hal_embassy::init(systimer.alarm0);
|
||||
}
|
||||
}
|
||||
|
||||
let mut bluetooth = peripherals.BT;
|
||||
|
||||
let connector = BleConnector::new(esp_radio_ctrl, bluetooth.reborrow());
|
||||
|
||||
let now = || time::Instant::now().duration_since_epoch().as_millis();
|
||||
let mut ble = Ble::new(connector, now);
|
||||
println!("Connector created");
|
||||
|
||||
let pin_ref = RefCell::new(button);
|
||||
let pin_ref = &pin_ref;
|
||||
|
||||
loop {
|
||||
println!("{:?}", ble.init().await);
|
||||
println!("{:?}", ble.cmd_set_le_advertising_parameters().await);
|
||||
println!(
|
||||
"{:?}",
|
||||
ble.cmd_set_le_advertising_data(
|
||||
create_advertising_data(&[
|
||||
AdStructure::Flags(LE_GENERAL_DISCOVERABLE | BR_EDR_NOT_SUPPORTED),
|
||||
AdStructure::ServiceUuids16(&[Uuid::Uuid16(0x1809)]),
|
||||
AdStructure::CompleteLocalName(esp_hal::chip!()),
|
||||
])
|
||||
.unwrap()
|
||||
)
|
||||
.await
|
||||
);
|
||||
println!("{:?}", ble.cmd_set_le_advertise_enable(true).await);
|
||||
|
||||
println!("started advertising");
|
||||
|
||||
let mut rf = |_offset: usize, data: &mut [u8]| {
|
||||
data[..20].copy_from_slice(&b"Hello Bare-Metal BLE"[..]);
|
||||
17
|
||||
};
|
||||
let mut wf = |offset: usize, data: &[u8]| {
|
||||
println!("RECEIVED: {} {:?}", offset, data);
|
||||
};
|
||||
|
||||
let mut wf2 = |offset: usize, data: &[u8]| {
|
||||
println!("RECEIVED: {} {:?}", offset, data);
|
||||
};
|
||||
|
||||
let mut rf3 = |_offset: usize, data: &mut [u8]| {
|
||||
data[..5].copy_from_slice(&b"Hola!"[..]);
|
||||
5
|
||||
};
|
||||
let mut wf3 = |offset: usize, data: &[u8]| {
|
||||
println!("RECEIVED: Offset {}, data {:?}", offset, data);
|
||||
};
|
||||
|
||||
gatt!([service {
|
||||
uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
characteristics: [
|
||||
characteristic {
|
||||
uuid: "937312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
read: rf,
|
||||
write: wf,
|
||||
},
|
||||
characteristic {
|
||||
uuid: "957312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
write: wf2,
|
||||
},
|
||||
characteristic {
|
||||
name: "my_characteristic",
|
||||
uuid: "987312e0-2354-11eb-9f10-fbc30a62cf38",
|
||||
notify: true,
|
||||
read: rf3,
|
||||
write: wf3,
|
||||
},
|
||||
],
|
||||
},]);
|
||||
|
||||
let mut rng = bleps::no_rng::NoRng;
|
||||
let mut srv = AttributeServer::new(&mut ble, &mut gatt_attributes, &mut rng);
|
||||
|
||||
let counter = RefCell::new(0u8);
|
||||
let counter = &counter;
|
||||
|
||||
let mut notifier = || {
|
||||
// TODO how to check if notifications are enabled for the characteristic?
|
||||
// maybe pass something into the closure which just can query the characteristic
|
||||
// value probably passing in the attribute server won't work?
|
||||
|
||||
async {
|
||||
pin_ref.borrow_mut().wait_for_rising_edge().await;
|
||||
let mut data = [0u8; 13];
|
||||
data.copy_from_slice(b"Notification0");
|
||||
{
|
||||
let mut counter = counter.borrow_mut();
|
||||
data[data.len() - 1] += *counter;
|
||||
*counter = (*counter + 1) % 10;
|
||||
}
|
||||
NotificationData::new(my_characteristic_handle, &data)
|
||||
}
|
||||
};
|
||||
|
||||
srv.run(&mut notifier).await.unwrap();
|
||||
}
|
||||
}
|
@ -1,16 +1,14 @@
|
||||
[package]
|
||||
name = "embassy-ble"
|
||||
name = "scanner"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8", features = [
|
||||
"async",
|
||||
"macros",
|
||||
] }
|
||||
cfg-if = "1.0.0"
|
||||
bt-hci = "0.4.0"
|
||||
embassy-executor = { version = "0.7.0", features = ["task-arena-size-20480"] }
|
||||
embassy-futures = "0.1.1"
|
||||
embassy-time = "0.4.0"
|
||||
esp-alloc = { path = "../../../esp-alloc" }
|
||||
esp-backtrace = { path = "../../../esp-backtrace", features = [
|
||||
"panic-handler",
|
||||
@ -20,15 +18,20 @@ esp-bootloader-esp-idf = { path = "../../../esp-bootloader-esp-idf" }
|
||||
esp-hal-embassy = { path = "../../../esp-hal-embassy" }
|
||||
esp-hal = { path = "../../../esp-hal", features = ["log-04", "unstable"] }
|
||||
esp-println = { path = "../../../esp-println", features = ["log-04"] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = [
|
||||
"log-04",
|
||||
] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = ["log-04"] }
|
||||
esp-radio = { path = "../../../esp-radio", features = [
|
||||
"ble",
|
||||
"log-04",
|
||||
"unstable",
|
||||
] }
|
||||
static_cell = "2.1.0"
|
||||
heapless = "0.9.1"
|
||||
log = "0.4.27"
|
||||
trouble-host = { git = "https://github.com/embassy-rs/trouble", rev = "366ee88", features = [
|
||||
"default-packet-pool-mtu-255",
|
||||
"derive",
|
||||
"scan",
|
||||
] }
|
||||
static_cell = "2.1.1"
|
||||
|
||||
[features]
|
||||
esp32 = [
|
111
examples/ble/scanner/src/main.rs
Normal file
111
examples/ble/scanner/src/main.rs
Normal file
@ -0,0 +1,111 @@
|
||||
//! A bluetooth scanner built using Embassy and trouBLE.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use bt_hci::{cmd::le::LeSetScanParams, controller::ControllerCmdSync};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_alloc as _;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{clock::CpuClock, timer::timg::TimerGroup};
|
||||
use esp_radio::ble::controller::BleConnector;
|
||||
use heapless::Deque;
|
||||
use log::info;
|
||||
use static_cell::StaticCell;
|
||||
use trouble_host::prelude::*;
|
||||
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(_s: Spawner) {
|
||||
esp_println::logger::init_logger_from_env();
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default().with_cpu_clock(CpuClock::max()));
|
||||
esp_alloc::heap_allocator!(size: 72 * 1024);
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
esp_preempt::init(timg0.timer0);
|
||||
|
||||
static RADIO: StaticCell<esp_radio::Controller<'static>> = StaticCell::new();
|
||||
let radio = RADIO.init(esp_radio::init().unwrap());
|
||||
|
||||
#[cfg(not(feature = "esp32"))]
|
||||
{
|
||||
let systimer = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER);
|
||||
esp_hal_embassy::init(systimer.alarm0);
|
||||
}
|
||||
#[cfg(feature = "esp32")]
|
||||
{
|
||||
esp_hal_embassy::init(timg0.timer1);
|
||||
}
|
||||
|
||||
let bluetooth = peripherals.BT;
|
||||
let connector = BleConnector::new(radio, bluetooth);
|
||||
let controller: ExternalController<_, 20> = ExternalController::new(connector);
|
||||
|
||||
ble_scanner_run(controller).await;
|
||||
}
|
||||
|
||||
/// Max number of connections
|
||||
const CONNECTIONS_MAX: usize = 1;
|
||||
const L2CAP_CHANNELS_MAX: usize = 1;
|
||||
|
||||
async fn ble_scanner_run<C>(controller: C)
|
||||
where
|
||||
C: Controller + ControllerCmdSync<LeSetScanParams>,
|
||||
{
|
||||
// Using a fixed "random" address can be useful for testing. In real scenarios, one would
|
||||
// use e.g. the MAC 6 byte array as the address (how to get that varies by the platform).
|
||||
let address: Address = Address::random([0xff, 0x8f, 0x1b, 0x05, 0xe4, 0xff]);
|
||||
|
||||
info!("Our address = {:?}", address);
|
||||
|
||||
let mut resources: HostResources<DefaultPacketPool, CONNECTIONS_MAX, L2CAP_CHANNELS_MAX> =
|
||||
HostResources::new();
|
||||
let stack = trouble_host::new(controller, &mut resources).set_random_address(address);
|
||||
|
||||
let Host {
|
||||
central,
|
||||
mut runner,
|
||||
..
|
||||
} = stack.build();
|
||||
|
||||
let printer = Printer {
|
||||
seen: RefCell::new(Deque::new()),
|
||||
};
|
||||
let mut scanner = Scanner::new(central);
|
||||
let _ = join(runner.run_with_handler(&printer), async {
|
||||
let mut config = ScanConfig::default();
|
||||
config.active = true;
|
||||
config.phys = PhySet::M1;
|
||||
config.interval = Duration::from_secs(1);
|
||||
config.window = Duration::from_secs(1);
|
||||
let mut _session = scanner.scan(&config).await.unwrap();
|
||||
// Scan forever
|
||||
loop {
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
struct Printer {
|
||||
seen: RefCell<Deque<BdAddr, 128>>,
|
||||
}
|
||||
|
||||
impl EventHandler for Printer {
|
||||
fn on_adv_reports(&self, mut it: LeAdvReportsIter<'_>) {
|
||||
let mut seen = self.seen.borrow_mut();
|
||||
while let Some(Ok(report)) = it.next() {
|
||||
if seen.iter().find(|b| b.raw() == report.addr.raw()).is_none() {
|
||||
info!("discovered: {:?}", report.addr);
|
||||
if seen.is_full() {
|
||||
seen.pop_front();
|
||||
}
|
||||
seen.push_back(report.addr).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
[target.'cfg(target_arch = "riscv32")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlinkall.x",
|
||||
"-C", "force-frame-pointers",
|
||||
]
|
||||
|
||||
[target.'cfg(target_arch = "xtensa")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
# GNU LD
|
||||
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
|
||||
# LLD
|
||||
# "-C", "link-arg=-Tlinkall.x",
|
||||
# "-C", "linker=rust-lld",
|
||||
]
|
||||
|
||||
[env]
|
||||
ESP_LOG = "info"
|
||||
SSID = "SSID"
|
||||
PASSWORD = "PASSWORD"
|
||||
STATIC_IP = "1.1.1.1 "
|
||||
GATEWAY_IP = "1.1.1.1"
|
||||
HOST_IP = "1.1.1.1"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
@ -1,80 +0,0 @@
|
||||
[package]
|
||||
name = "bench"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
blocking-network-stack = { git = "https://github.com/bjoernQ/blocking-network-stack.git", rev = "b3ecefc" }
|
||||
embedded-io = { version = "0.6.1", default-features = false }
|
||||
esp-alloc = { path = "../../../esp-alloc" }
|
||||
esp-backtrace = { path = "../../../esp-backtrace", features = [
|
||||
"panic-handler",
|
||||
"println",
|
||||
] }
|
||||
esp-bootloader-esp-idf = { path = "../../../esp-bootloader-esp-idf" }
|
||||
esp-hal = { path = "../../../esp-hal", features = ["log-04", "unstable"] }
|
||||
esp-println = { path = "../../../esp-println", features = ["log-04"] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = [
|
||||
"log-04",
|
||||
] }
|
||||
esp-radio = { path = "../../../esp-radio", features = [
|
||||
"log-04",
|
||||
"smoltcp",
|
||||
"unstable",
|
||||
"wifi",
|
||||
] }
|
||||
smoltcp = { version = "0.12.0", default-features = false, features = [
|
||||
"medium-ethernet",
|
||||
"socket-raw",
|
||||
] }
|
||||
|
||||
[features]
|
||||
esp32 = [
|
||||
"esp-backtrace/esp32",
|
||||
"esp-bootloader-esp-idf/esp32",
|
||||
"esp-hal/esp32",
|
||||
"esp-preempt/esp32",
|
||||
"esp-radio/esp32",
|
||||
]
|
||||
esp32c2 = [
|
||||
"esp-backtrace/esp32c2",
|
||||
"esp-bootloader-esp-idf/esp32c2",
|
||||
"esp-hal/esp32c2",
|
||||
"esp-preempt/esp32c2",
|
||||
"esp-radio/esp32c2",
|
||||
]
|
||||
esp32c3 = [
|
||||
"esp-backtrace/esp32c3",
|
||||
"esp-bootloader-esp-idf/esp32c3",
|
||||
"esp-hal/esp32c3",
|
||||
"esp-preempt/esp32c3",
|
||||
"esp-radio/esp32c3",
|
||||
]
|
||||
esp32c6 = [
|
||||
"esp-backtrace/esp32c6",
|
||||
"esp-bootloader-esp-idf/esp32c6",
|
||||
"esp-hal/esp32c6",
|
||||
"esp-preempt/esp32c6",
|
||||
"esp-radio/esp32c6",
|
||||
]
|
||||
esp32s2 = [
|
||||
"esp-backtrace/esp32s2",
|
||||
"esp-bootloader-esp-idf/esp32s2",
|
||||
"esp-hal/esp32s2",
|
||||
"esp-preempt/esp32s2",
|
||||
"esp-radio/esp32s2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"esp-backtrace/esp32s3",
|
||||
"esp-bootloader-esp-idf/esp32s3",
|
||||
"esp-hal/esp32s3",
|
||||
"esp-preempt/esp32s3",
|
||||
"esp-radio/esp32s3",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
@ -1,29 +0,0 @@
|
||||
[target.'cfg(target_arch = "riscv32")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlinkall.x",
|
||||
"-C", "force-frame-pointers",
|
||||
]
|
||||
|
||||
[target.'cfg(target_arch = "xtensa")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
# GNU LD
|
||||
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
|
||||
# LLD
|
||||
# "-C", "link-arg=-Tlinkall.x",
|
||||
# "-C", "linker=rust-lld",
|
||||
]
|
||||
|
||||
[env]
|
||||
ESP_LOG = "info"
|
||||
SSID = "SSID"
|
||||
PASSWORD = "PASSWORD"
|
||||
STATIC_IP = "1.1.1.1 "
|
||||
GATEWAY_IP = "1.1.1.1"
|
||||
HOST_IP = "1.1.1.1"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
@ -1,80 +0,0 @@
|
||||
[package]
|
||||
name = "csi"
|
||||
version = "0.0.0"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
blocking-network-stack = { git = "https://github.com/bjoernQ/blocking-network-stack.git", rev = "b3ecefc" }
|
||||
esp-alloc = { path = "../../../esp-alloc" }
|
||||
esp-backtrace = { path = "../../../esp-backtrace", features = [
|
||||
"panic-handler",
|
||||
"println",
|
||||
] }
|
||||
esp-bootloader-esp-idf = { path = "../../../esp-bootloader-esp-idf" }
|
||||
esp-hal = { path = "../../../esp-hal", features = ["log-04", "unstable"] }
|
||||
esp-println = { path = "../../../esp-println", features = ["log-04"] }
|
||||
esp-preempt = { path = "../../../esp-preempt", features = [
|
||||
"log-04",
|
||||
] }
|
||||
esp-radio = { path = "../../../esp-radio", features = [
|
||||
"csi",
|
||||
"log-04",
|
||||
"smoltcp",
|
||||
"unstable",
|
||||
"wifi",
|
||||
] }
|
||||
smoltcp = { version = "0.12.0", default-features = false, features = [
|
||||
"medium-ethernet",
|
||||
"socket-raw",
|
||||
] }
|
||||
|
||||
[features]
|
||||
esp32 = [
|
||||
"esp-backtrace/esp32",
|
||||
"esp-bootloader-esp-idf/esp32",
|
||||
"esp-hal/esp32",
|
||||
"esp-preempt/esp32",
|
||||
"esp-radio/esp32",
|
||||
]
|
||||
esp32c2 = [
|
||||
"esp-backtrace/esp32c2",
|
||||
"esp-bootloader-esp-idf/esp32c2",
|
||||
"esp-hal/esp32c2",
|
||||
"esp-preempt/esp32c2",
|
||||
"esp-radio/esp32c2",
|
||||
]
|
||||
esp32c3 = [
|
||||
"esp-backtrace/esp32c3",
|
||||
"esp-bootloader-esp-idf/esp32c3",
|
||||
"esp-hal/esp32c3",
|
||||
"esp-preempt/esp32c3",
|
||||
"esp-radio/esp32c3",
|
||||
]
|
||||
esp32c6 = [
|
||||
"esp-backtrace/esp32c6",
|
||||
"esp-bootloader-esp-idf/esp32c6",
|
||||
"esp-hal/esp32c6",
|
||||
"esp-preempt/esp32c6",
|
||||
"esp-radio/esp32c6",
|
||||
]
|
||||
esp32s2 = [
|
||||
"esp-backtrace/esp32s2",
|
||||
"esp-bootloader-esp-idf/esp32s2",
|
||||
"esp-hal/esp32s2",
|
||||
"esp-preempt/esp32s2",
|
||||
"esp-radio/esp32s2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"esp-backtrace/esp32s3",
|
||||
"esp-bootloader-esp-idf/esp32s3",
|
||||
"esp-hal/esp32s3",
|
||||
"esp-preempt/esp32s3",
|
||||
"esp-radio/esp32s3",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
@ -1,29 +0,0 @@
|
||||
[target.'cfg(target_arch = "riscv32")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
"-C", "link-arg=-Tlinkall.x",
|
||||
"-C", "force-frame-pointers",
|
||||
]
|
||||
|
||||
[target.'cfg(target_arch = "xtensa")']
|
||||
runner = "espflash flash --monitor"
|
||||
rustflags = [
|
||||
# GNU LD
|
||||
"-C", "link-arg=-Wl,-Tlinkall.x",
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
|
||||
# LLD
|
||||
# "-C", "link-arg=-Tlinkall.x",
|
||||
# "-C", "linker=rust-lld",
|
||||
]
|
||||
|
||||
[env]
|
||||
ESP_LOG = "info"
|
||||
SSID = "SSID"
|
||||
PASSWORD = "PASSWORD"
|
||||
STATIC_IP = "1.1.1.1 "
|
||||
GATEWAY_IP = "1.1.1.1"
|
||||
HOST_IP = "1.1.1.1"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
@ -29,6 +29,11 @@ rustflags = [
|
||||
[env]
|
||||
ESP_LOG = "info"
|
||||
ESP_HAL_EMBASSY_CONFIG_TIMER_QUEUE="multiple-integrated"
|
||||
SSID = "SSID"
|
||||
PASSWORD = "PASSWORD"
|
||||
STATIC_IP = "1.1.1.1 "
|
||||
GATEWAY_IP = "1.1.1.1"
|
||||
HOST_IP = "1.1.1.1"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
||||
|
@ -6,34 +6,118 @@ license = "MIT OR Apache-2.0"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
embassy-executor = { version = "0.7.0", features = ["task-arena-size-12288"] }
|
||||
embassy-time = "0.4.0"
|
||||
embassy-futures = "0.1.1"
|
||||
embassy-sync = "0.6.1"
|
||||
embedded-graphics = "0.8.1"
|
||||
blocking-network-stack = { git = "https://github.com/bjoernQ/blocking-network-stack.git", rev = "b3ecefc", optional = true }
|
||||
cfg-if = "1.0.0"
|
||||
embassy-executor = { version = "0.7.0", features = ["task-arena-size-12288"] }
|
||||
embassy-time = "0.4.0"
|
||||
embassy-futures = "0.1.1"
|
||||
embassy-net = { version = "0.6.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] }
|
||||
embassy-sync = "0.6.1"
|
||||
embedded-graphics = "0.8.1"
|
||||
embedded-hal-async = "1.0.0"
|
||||
esp-alloc = { path = "../esp-alloc" }
|
||||
esp-backtrace = { path = "../esp-backtrace", features = ["panic-handler", "println"] }
|
||||
embedded-io = { version = "0.6.1", default-features = false }
|
||||
esp-alloc = { path = "../esp-alloc" }
|
||||
esp-backtrace = { path = "../esp-backtrace", features = [
|
||||
"panic-handler",
|
||||
"println",
|
||||
] }
|
||||
esp-bootloader-esp-idf = { path = "../esp-bootloader-esp-idf" }
|
||||
esp-hal = { path = "../esp-hal", features = ["unstable", "log-04"] }
|
||||
esp-hal-embassy = { path = "../esp-hal-embassy" }
|
||||
esp-println = { path = "../esp-println", features = ["log-04"] }
|
||||
lis3dh-async = "0.9.3"
|
||||
ssd1306 = "0.10.0"
|
||||
esp-hal = { path = "../esp-hal", features = ["log-04", "unstable"] }
|
||||
esp-hal-embassy = { path = "../esp-hal-embassy" }
|
||||
esp-preempt = { path = "../esp-preempt", features = [
|
||||
"log-04",
|
||||
], optional = true }
|
||||
esp-println = { path = "../esp-println", features = ["log-04"] }
|
||||
esp-radio = { path = "../esp-radio", features = [
|
||||
"log-04",
|
||||
"smoltcp",
|
||||
"unstable",
|
||||
"wifi",
|
||||
], optional = true }
|
||||
lis3dh-async = "0.9.3"
|
||||
ssd1306 = "0.10.0"
|
||||
smoltcp = { version = "0.12.0", default-features = false, features = [
|
||||
"medium-ethernet",
|
||||
"socket-raw",
|
||||
], optional = true }
|
||||
static_cell = "2.1.1"
|
||||
|
||||
[features]
|
||||
unstable = []
|
||||
esp32 = ["esp-backtrace/esp32", "esp-hal/esp32", "esp-hal-embassy/esp32", "esp-println/esp32", "esp-bootloader-esp-idf/esp32"]
|
||||
esp32c2 = ["esp-backtrace/esp32c2", "esp-hal/esp32c2", "esp-hal-embassy/esp32c2", "esp-println/esp32c2", "esp-bootloader-esp-idf/esp32c2"]
|
||||
esp32c3 = ["esp-backtrace/esp32c3", "esp-hal/esp32c3", "esp-hal-embassy/esp32c3", "esp-println/esp32c3", "esp-bootloader-esp-idf/esp32c3"]
|
||||
esp32c6 = ["esp-backtrace/esp32c6", "esp-hal/esp32c6", "esp-hal-embassy/esp32c6", "esp-println/esp32c6", "esp-bootloader-esp-idf/esp32c6"]
|
||||
esp32h2 = ["esp-backtrace/esp32h2", "esp-hal/esp32h2", "esp-hal-embassy/esp32h2", "esp-println/esp32h2", "esp-bootloader-esp-idf/esp32h2"]
|
||||
esp32s2 = ["esp-backtrace/esp32s2", "esp-hal/esp32s2", "esp-hal-embassy/esp32s2", "esp-println/esp32s2", "esp-bootloader-esp-idf/esp32s2"]
|
||||
esp32s3 = ["esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-hal-embassy/esp32s3", "esp-println/esp32s3", "esp-bootloader-esp-idf/esp32s3"]
|
||||
|
||||
esp-radio = [
|
||||
"dep:blocking-network-stack",
|
||||
"dep:esp-preempt",
|
||||
"dep:esp-radio",
|
||||
"dep:smoltcp",
|
||||
]
|
||||
|
||||
esp32 = [
|
||||
"esp-backtrace/esp32",
|
||||
"esp-bootloader-esp-idf/esp32",
|
||||
"esp-hal-embassy/esp32",
|
||||
"esp-hal/esp32",
|
||||
"esp-preempt?/esp32",
|
||||
"esp-println/esp32",
|
||||
"esp-radio?/esp32",
|
||||
]
|
||||
esp32c2 = [
|
||||
"esp-backtrace/esp32c2",
|
||||
"esp-bootloader-esp-idf/esp32c2",
|
||||
"esp-hal-embassy/esp32c2",
|
||||
"esp-hal/esp32c2",
|
||||
"esp-preempt?/esp32c2",
|
||||
"esp-println/esp32c2",
|
||||
"esp-radio?/esp32c2",
|
||||
]
|
||||
esp32c3 = [
|
||||
"esp-backtrace/esp32c3",
|
||||
"esp-bootloader-esp-idf/esp32c3",
|
||||
"esp-hal-embassy/esp32c3",
|
||||
"esp-hal/esp32c3",
|
||||
"esp-preempt?/esp32c3",
|
||||
"esp-println/esp32c3",
|
||||
"esp-radio?/esp32c3",
|
||||
]
|
||||
esp32c6 = [
|
||||
"esp-backtrace/esp32c6",
|
||||
"esp-bootloader-esp-idf/esp32c6",
|
||||
"esp-hal-embassy/esp32c6",
|
||||
"esp-hal/esp32c6",
|
||||
"esp-preempt?/esp32c6",
|
||||
"esp-println/esp32c6",
|
||||
"esp-radio?/esp32c6",
|
||||
]
|
||||
esp32h2 = [
|
||||
"esp-backtrace/esp32h2",
|
||||
"esp-bootloader-esp-idf/esp32h2",
|
||||
"esp-hal-embassy/esp32h2",
|
||||
"esp-hal/esp32h2",
|
||||
"esp-preempt?/esp32h2",
|
||||
"esp-println/esp32h2",
|
||||
"esp-radio?/esp32h2",
|
||||
]
|
||||
esp32s2 = [
|
||||
"esp-backtrace/esp32s2",
|
||||
"esp-bootloader-esp-idf/esp32s2",
|
||||
"esp-hal-embassy/esp32s2",
|
||||
"esp-hal/esp32s2",
|
||||
"esp-preempt?/esp32s2",
|
||||
"esp-println/esp32s2",
|
||||
"esp-radio?/esp32s2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"esp-backtrace/esp32s3",
|
||||
"esp-bootloader-esp-idf/esp32s3",
|
||||
"esp-hal-embassy/esp32s3",
|
||||
"esp-hal/esp32s3",
|
||||
"esp-preempt?/esp32s3",
|
||||
"esp-println/esp32s3",
|
||||
"esp-radio?/esp32s3",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
debug = 2
|
||||
debug = 2
|
||||
debug-assertions = true
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
|
@ -13,6 +13,9 @@
|
||||
//! Because of the huge task-arena size configured this won't work on ESP32-S2
|
||||
//! and ESP32-C2
|
||||
|
||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/unstable esp-hal/unstable
|
||||
//% CHIPS: esp32 esp32c3 esp32c6 esp32s2 esp32s3
|
||||
|
||||
#![allow(static_mut_refs)]
|
||||
#![no_std]
|
||||
#![no_main]
|
@ -10,6 +10,9 @@
|
||||
//! variable. E.g `HOST_IP="192.168.0.24"` and also set SSID and PASSWORD env
|
||||
//! variable before running this example.
|
||||
|
||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/unstable esp-hal/unstable
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32s2 esp32s3
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
@ -1,8 +1,11 @@
|
||||
//! CSI Example
|
||||
//!
|
||||
//!
|
||||
//! Set SSID and PASSWORD env variable before running this example.
|
||||
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32s2 esp32s3
|
||||
//% FEATURES: esp-radio esp-radio/wifi esp-radio/smoltcp esp-radio/log-04 esp-radio/csi
|
||||
//% FEATURES: esp-radio/unstable esp-hal/unstable
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
Loading…
x
Reference in New Issue
Block a user