diff options
author | Ulf Lilleengen <lulf@redhat.com> | 2022-08-23 08:48:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-23 08:48:14 +0200 |
commit | e6dbc368d2e75d5442f5f52fb8343ed04e7a6c7d (patch) | |
tree | 67c1824e23c96b7ddb4440ce895b37646618e6d4 | |
parent | e1e4e2a2c2e9a8243368214fac02532e79c127a8 (diff) | |
parent | 36d14808e2019556d502105081bd36f80aba06c0 (diff) | |
download | nrf-softdevice-e6dbc368d2e75d5442f5f52fb8343ed04e7a6c7d.zip |
Merge pull request #132 from embassy-rs/update-embassy
Update Embassy.
-rw-r--r-- | Cargo.lock | 51 | ||||
-rw-r--r-- | Cargo.toml | 9 | ||||
-rw-r--r-- | examples/Cargo.toml | 3 | ||||
-rw-r--r-- | examples/src/bin/ble_advertise.rs | 59 | ||||
-rw-r--r-- | examples/src/bin/ble_bas_central.rs | 68 | ||||
-rw-r--r-- | examples/src/bin/ble_bas_peripheral.rs | 94 | ||||
-rw-r--r-- | examples/src/bin/ble_dis_bas_peripheral_builder.rs | 75 | ||||
-rw-r--r-- | examples/src/bin/ble_l2cap_central.rs | 130 | ||||
-rw-r--r-- | examples/src/bin/ble_l2cap_peripheral.rs | 83 | ||||
-rw-r--r-- | examples/src/bin/ble_peripheral_onoff.rs | 108 | ||||
-rw-r--r-- | examples/src/bin/ble_scan.rs | 92 | ||||
-rw-r--r-- | examples/src/bin/flash.rs | 32 | ||||
-rw-r--r-- | nrf-softdevice/src/softdevice.rs | 19 |
13 files changed, 369 insertions, 454 deletions
@@ -303,7 +303,7 @@ dependencies = [ [[package]] name = "embassy-cortex-m" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "atomic-polyfill 1.0.1", "cfg-if", @@ -318,7 +318,7 @@ dependencies = [ [[package]] name = "embassy-embedded-hal" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "defmt", "embassy-util", @@ -333,31 +333,29 @@ dependencies = [ [[package]] name = "embassy-executor" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "atomic-polyfill 1.0.1", "cfg-if", "critical-section 1.1.0", "defmt", "embassy-macros", - "embedded-hal 0.2.7", - "embedded-hal-async", "futures-util", + "static_cell", ] [[package]] name = "embassy-hal-common" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ - "embassy-util", "num-traits", ] [[package]] name = "embassy-macros" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "darling 0.13.4", "proc-macro2", @@ -368,7 +366,7 @@ dependencies = [ [[package]] name = "embassy-nrf" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "cfg-if", "cortex-m", @@ -379,7 +377,7 @@ dependencies = [ "embassy-embedded-hal", "embassy-executor", "embassy-hal-common", - "embassy-macros", + "embassy-time", "embassy-usb", "embassy-util", "embedded-hal 0.2.7", @@ -395,9 +393,24 @@ dependencies = [ ] [[package]] +name = "embassy-time" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" +dependencies = [ + "atomic-polyfill 1.0.1", + "cfg-if", + "critical-section 1.1.0", + "defmt", + "embassy-macros", + "embedded-hal 0.2.7", + "embedded-hal-async", + "futures-util", +] + +[[package]] name = "embassy-usb" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "defmt", "embassy-util", @@ -407,7 +420,7 @@ dependencies = [ [[package]] name = "embassy-util" version = "0.1.0" -source = "git+https://github.com/embassy-rs/embassy?rev=d881f3ad9186cf3279aa1ba27093bad94035c186#d881f3ad9186cf3279aa1ba27093bad94035c186" +source = "git+https://github.com/embassy-rs/embassy?rev=53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f#53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" dependencies = [ "atomic-polyfill 1.0.1", "cfg-if", @@ -472,9 +485,9 @@ dependencies = [ [[package]] name = "fixed" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff8fc11090cf4e92c9f9052e778d3dc869d0fb943cdc5568df3d3b559a58787" +checksum = "ec8c4fbf8cd36f2a96740c31320902abbf0acbd733049b758707d842490c98c4" dependencies = [ "az", "bytemuck", @@ -703,6 +716,7 @@ dependencies = [ "defmt-rtt", "embassy-executor", "embassy-nrf", + "embassy-time", "embassy-util", "embedded-storage", "embedded-storage-async", @@ -1025,6 +1039,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] +name = "static_cell" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c37c250d21f53fa7165e76e5401d7e6539c211a8d2cf449e3962956a5cc2ce" +dependencies = [ + "atomic-polyfill 1.0.1", +] + +[[package]] name = "strsim" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -18,10 +18,11 @@ exclude = [ ] [patch.crates-io] -embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "d881f3ad9186cf3279aa1ba27093bad94035c186" } -embassy-util = { git = "https://github.com/embassy-rs/embassy", rev = "d881f3ad9186cf3279aa1ba27093bad94035c186" } -embassy-nrf = { git = "https://github.com/embassy-rs/embassy", rev = "d881f3ad9186cf3279aa1ba27093bad94035c186" } -embassy-macros = { git = "https://github.com/embassy-rs/embassy", rev = "d881f3ad9186cf3279aa1ba27093bad94035c186" } +embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" } +embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" } +embassy-util = { git = "https://github.com/embassy-rs/embassy", rev = "53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" } +embassy-nrf = { git = "https://github.com/embassy-rs/embassy", rev = "53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" } +embassy-macros = { git = "https://github.com/embassy-rs/embassy", rev = "53fbd0efb3e77e1e3de948afde2b5bf1a5a9735f" } [profile.release] codegen-units = 1 diff --git a/examples/Cargo.toml b/examples/Cargo.toml index ee34c58..75baa0a 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -16,7 +16,8 @@ ble-gatt-server = ["nrf-softdevice/ble-gatt-server"] ble-gatt-client = ["nrf-softdevice/ble-gatt-client"] [dependencies] -embassy-executor = { version = "0.1.0", features = ["nightly", "defmt", "defmt-timestamp-uptime"]} +embassy-executor = { version = "0.1.0", features = ["nightly", "defmt"]} +embassy-time = { version = "0.1.0", features = ["nightly", "defmt", "defmt-timestamp-uptime"]} embassy-util = { version = "0.1.0" } embassy-nrf = { version = "0.1.0", features = [ "nightly", "defmt", "nrf52840", "gpiote", "time-driver-rtc1" ]} cortex-m = "0.7.2" diff --git a/examples/src/bin/ble_advertise.rs b/examples/src/bin/ble_advertise.rs index 31804b3..685be91 100644 --- a/examples/src/bin/ble_advertise.rs +++ b/examples/src/bin/ble_advertise.rs @@ -7,44 +7,18 @@ mod example_common; use core::mem; -use cortex_m_rt::entry; -use defmt::{info, unreachable, *}; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use defmt::{info, *}; +use embassy_executor::Spawner; use nrf_softdevice::ble::peripheral; use nrf_softdevice::{raw, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } -#[embassy_executor::task] -async fn bluetooth_task(sd: &'static Softdevice) { - #[rustfmt::skip] - let adv_data = &[ - 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, - 0x03, 0x03, 0x09, 0x18, - 0x0a, 0x09, b'H', b'e', b'l', b'l', b'o', b'R', b'u', b's', b't', - ]; - #[rustfmt::skip] - let scan_data = &[ - 0x03, 0x03, 0x09, 0x18, - ]; - - let mut config = peripheral::Config::default(); - config.interval = 50; - let adv = peripheral::NonconnectableAdvertisement::ScannableUndirected { adv_data, scan_data }; - unwrap!(peripheral::advertise(sd, adv, &config).await); - - // advertise never returns - unreachable!(); -} - -#[entry] -fn main() -> ! { +#[embassy_executor::main] +async fn main(spawner: Spawner) { info!("Hello World!"); let config = nrf_softdevice::Config { @@ -78,10 +52,21 @@ fn main() -> ! { }; let sd = Softdevice::enable(&config); + unwrap!(spawner.spawn(softdevice_task(sd))); - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(bluetooth_task(sd))); - }); + #[rustfmt::skip] + let adv_data = &[ + 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, + 0x03, 0x03, 0x09, 0x18, + 0x0a, 0x09, b'H', b'e', b'l', b'l', b'o', b'R', b'u', b's', b't', + ]; + #[rustfmt::skip] + let scan_data = &[ + 0x03, 0x03, 0x09, 0x18, + ]; + + let mut config = peripheral::Config::default(); + config.interval = 50; + let adv = peripheral::NonconnectableAdvertisement::ScannableUndirected { adv_data, scan_data }; + unwrap!(peripheral::advertise(sd, adv, &config).await); } diff --git a/examples/src/bin/ble_bas_central.rs b/examples/src/bin/ble_bas_central.rs index 3594f55..2d307c1 100644 --- a/examples/src/bin/ble_bas_central.rs +++ b/examples/src/bin/ble_bas_central.rs @@ -7,18 +7,14 @@ mod example_common; use core::mem; -use cortex_m_rt::entry; use defmt::{info, *}; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use nrf_softdevice::ble::{central, gatt_client, Address, AddressType}; use nrf_softdevice::{raw, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } #[nrf_softdevice::gatt_client(uuid = "180f")] @@ -27,34 +23,8 @@ struct BatteryServiceClient { battery_level: u8, } -#[embassy_executor::task] -async fn ble_central_task(sd: &'static Softdevice) { - let addrs = &[&Address::new( - AddressType::RandomStatic, - [0x06, 0x6b, 0x71, 0x2c, 0xf5, 0xc0], - )]; - let mut config = central::ConnectConfig::default(); - config.scan_config.whitelist = Some(addrs); - let conn = unwrap!(central::connect(sd, &config).await); - info!("connected"); - - let client: BatteryServiceClient = unwrap!(gatt_client::discover(&conn).await); - - // Read - let val = unwrap!(client.battery_level_read().await); - info!("read battery level: {}", val); - - // Write, set it to 42 - unwrap!(client.battery_level_write(42).await); - info!("Wrote battery level!"); - - // Read to check it's changed - let val = unwrap!(client.battery_level_read().await); - info!("read battery level: {}", val); -} - -#[entry] -fn main() -> ! { +#[embassy_executor::main] +async fn main(spawner: Spawner) { info!("Hello World!"); let config = nrf_softdevice::Config { @@ -88,10 +58,28 @@ fn main() -> ! { }; let sd = Softdevice::enable(&config); + unwrap!(spawner.spawn(softdevice_task(sd))); + + let addrs = &[&Address::new( + AddressType::RandomStatic, + [0x06, 0x6b, 0x71, 0x2c, 0xf5, 0xc0], + )]; + let mut config = central::ConnectConfig::default(); + config.scan_config.whitelist = Some(addrs); + let conn = unwrap!(central::connect(sd, &config).await); + info!("connected"); + + let client: BatteryServiceClient = unwrap!(gatt_client::discover(&conn).await); + + // Read + let val = unwrap!(client.battery_level_read().await); + info!("read battery level: {}", val); + + // Write, set it to 42 + unwrap!(client.battery_level_write(42).await); + info!("Wrote battery level!"); - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(ble_central_task(sd))); - }); + // Read to check it's changed + let val = unwrap!(client.battery_level_read().await); + info!("read battery level: {}", val); } diff --git a/examples/src/bin/ble_bas_peripheral.rs b/examples/src/bin/ble_bas_peripheral.rs index 03fc603..685bfc5 100644 --- a/examples/src/bin/ble_bas_peripheral.rs +++ b/examples/src/bin/ble_bas_peripheral.rs @@ -7,18 +7,14 @@ mod example_common; use core::mem; -use cortex_m_rt::entry; use defmt::{info, *}; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use nrf_softdevice::ble::{gatt_server, peripheral}; use nrf_softdevice::{raw, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } #[nrf_softdevice::gatt_service(uuid = "180f")] @@ -39,8 +35,44 @@ struct Server { foo: FooService, } -#[embassy_executor::task] -async fn bluetooth_task(sd: &'static Softdevice, server: Server) { +#[embassy_executor::main] +async fn main(spawner: Spawner) { + info!("Hello World!"); + + let config = nrf_softdevice::Config { + clock: Some(raw::nrf_clock_lf_cfg_t { + source: raw::NRF_CLOCK_LF_SRC_RC as u8, + rc_ctiv: 4, + rc_temp_ctiv: 2, + accuracy: 7, + }), + conn_gap: Some(raw::ble_gap_conn_cfg_t { + conn_count: 6, + event_length: 24, + }), + conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 256 }), + gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { attr_tab_size: 32768 }), + gap_role_count: Some(raw::ble_gap_cfg_role_count_t { + adv_set_count: 1, + periph_role_count: 3, + central_role_count: 3, + central_sec_count: 0, + _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), + }), + gap_device_name: Some(raw::ble_gap_cfg_device_name_t { + p_value: b"HelloRust" as *const u8 as _, + current_len: 9, + max_len: 9, + write_perm: unsafe { mem::zeroed() }, + _bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1(raw::BLE_GATTS_VLOC_STACK as u8), + }), + ..Default::default() + }; + + let sd = Softdevice::enable(&config); + let server = unwrap!(Server::new(sd)); + unwrap!(spawner.spawn(softdevice_task(sd))); + #[rustfmt::skip] let adv_data = &[ 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, @@ -88,47 +120,3 @@ async fn bluetooth_task(sd: &'static Softdevice, server: Server) { } } } - -#[entry] -fn main() -> ! { - info!("Hello World!"); - - let config = nrf_softdevice::Config { - clock: Some(raw::nrf_clock_lf_cfg_t { - source: raw::NRF_CLOCK_LF_SRC_RC as u8, - rc_ctiv: 4, - rc_temp_ctiv: 2, - accuracy: 7, - }), - conn_gap: Some(raw::ble_gap_conn_cfg_t { - conn_count: 6, - event_length: 24, - }), - conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 256 }), - gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { attr_tab_size: 32768 }), - gap_role_count: Some(raw::ble_gap_cfg_role_count_t { - adv_set_count: 1, - periph_role_count: 3, - central_role_count: 3, - central_sec_count: 0, - _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), - }), - gap_device_name: Some(raw::ble_gap_cfg_device_name_t { - p_value: b"HelloRust" as *const u8 as _, - current_len: 9, - max_len: 9, - write_perm: unsafe { mem::zeroed() }, - _bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1(raw::BLE_GATTS_VLOC_STACK as u8), - }), - ..Default::default() - }; - - let sd = Softdevice::enable(&config); - - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - let server = unwrap!(Server::new(sd)); - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(bluetooth_task(sd, server))); - }); -} diff --git a/examples/src/bin/ble_dis_bas_peripheral_builder.rs b/examples/src/bin/ble_dis_bas_peripheral_builder.rs index 71ae849..b73b6d8 100644 --- a/examples/src/bin/ble_dis_bas_peripheral_builder.rs +++ b/examples/src/bin/ble_dis_bas_peripheral_builder.rs @@ -7,10 +7,8 @@ mod example_common; use core::mem; -use cortex_m_rt::entry; use defmt::{info, *}; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use nrf_softdevice::ble::gatt_server::builder::ServiceBuilder; use nrf_softdevice::ble::gatt_server::characteristic::{Attribute, Metadata, Properties}; use nrf_softdevice::ble::gatt_server::{CharacteristicHandles, RegisterError}; @@ -29,11 +27,9 @@ const SOFTWARE_REVISION: Uuid = Uuid::new_16(0x2a28); const MANUFACTURER_NAME: Uuid = Uuid::new_16(0x2a29); const PNP_ID: Uuid = Uuid::new_16(0x2a50); -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } #[repr(u8)] @@ -186,37 +182,8 @@ impl gatt_server::Server for Server { } } -#[embassy_executor::task] -async fn bluetooth_task(sd: &'static Softdevice, server: Server) { - #[rustfmt::skip] - let adv_data = &[ - 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, - 0x03, 0x03, 0x09, 0x18, - 0x0a, 0x09, b'H', b'e', b'l', b'l', b'o', b'R', b'u', b's', b't', - ]; - #[rustfmt::skip] - let scan_data = &[ - 0x03, 0x03, 0x09, 0x18, - ]; - - loop { - let config = peripheral::Config::default(); - let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { adv_data, scan_data }; - let conn = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); - - info!("advertising done!"); - - // Run the GATT server on the connection. This returns when the connection gets disconnected. - let res = gatt_server::run(&conn, &server, |_| {}).await; - - if let Err(e) = res { - info!("gatt_server run exited with error: {:?}", e); - } - } -} - -#[entry] -fn main() -> ! { +#[embassy_executor::main] +async fn main(spawner: Spawner) { info!("Hello World!"); let config = nrf_softdevice::Config { @@ -250,12 +217,32 @@ fn main() -> ! { }; let sd = Softdevice::enable(&config); - let server = unwrap!(Server::new(sd, "12345678")); + unwrap!(spawner.spawn(softdevice_task(sd))); + + #[rustfmt::skip] + let adv_data = &[ + 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, + 0x03, 0x03, 0x09, 0x18, + 0x0a, 0x09, b'H', b'e', b'l', b'l', b'o', b'R', b'u', b's', b't', + ]; + #[rustfmt::skip] + let scan_data = &[ + 0x03, 0x03, 0x09, 0x18, + ]; - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(bluetooth_task(sd, server))); - }); + loop { + let config = peripheral::Config::default(); + let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { adv_data, scan_data }; + let conn = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); + + info!("advertising done!"); + + // Run the GATT server on the connection. This returns when the connection gets disconnected. + let res = gatt_server::run(&conn, &server, |_| {}).await; + + if let Err(e) = res { + info!("gatt_server run exited with error: {:?}", e); + } + } } diff --git a/examples/src/bin/ble_l2cap_central.rs b/examples/src/bin/ble_l2cap_central.rs index 9b2cb5a..6f1a05d 100644 --- a/examples/src/bin/ble_l2cap_central.rs +++ b/examples/src/bin/ble_l2cap_central.rs @@ -8,78 +8,17 @@ mod example_common; use core::ptr::NonNull; use core::{mem, slice}; -use cortex_m_rt::entry; use defmt::{info, *}; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use nrf_softdevice::ble::l2cap::Packet as _; use nrf_softdevice::ble::{central, l2cap, Address, TxPower}; use nrf_softdevice::{raw, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - const PSM: u16 = 0x2349; #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; -} - -#[embassy_executor::task] -async fn ble_central_task(sd: &'static Softdevice) { - info!("Scanning for peer..."); - - let config = central::ScanConfig { - whitelist: None, - tx_power: TxPower::ZerodBm, - ..Default::default() - }; - let res = central::scan(sd, &config, |params| unsafe { - let mut data = slice::from_raw_parts(params.data.p_data, params.data.len as usize); - while data.len() != 0 { - let len = data[0] as usize; - if data.len() < len + 1 { - break; - } - if len < 1 { - break; - } - let key = data[1]; - let value = &data[2..len + 1]; - - if key == 0x06 - && value - == &[ - 0xeb, 0x04, 0x8b, 0xfd, 0x5b, 0x03, 0x21, 0xb5, 0xeb, 0x11, 0x65, 0x2f, 0x18, 0xce, 0x9c, 0x82, - ] - { - return Some(Address::from_raw(params.peer_addr)); - } - data = &data[len + 1..]; - } - None - }) - .await; - let address = unwrap!(res); - info!("Scan found address {:?}", address); - - let addrs = &[&address]; - - let mut config = central::ConnectConfig::default(); - config.scan_config.whitelist = Some(addrs); - let conn = unwrap!(central::connect(sd, &config).await); - info!("connected"); - - let l = l2cap::L2cap::<Packet>::init(sd); - let config = l2cap::Config { credits: 8 }; - let ch = unwrap!(l.setup(&conn, &config, PSM).await); - info!("l2cap connected"); - - for i in 0..10 { - unwrap!(ch.tx(Packet::new(&[i; Packet::MTU])).await); - info!("l2cap tx done"); - } - futures::future::pending::<()>().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } use atomic_pool::{pool, Box}; @@ -133,8 +72,8 @@ impl l2cap::Packet for Packet { } } -#[entry] -fn main() -> ! { +#[embassy_executor::main] +async fn main(spawner: Spawner) { info!("Hello World!"); let config = nrf_softdevice::Config { @@ -179,10 +118,59 @@ fn main() -> ! { }; let sd = Softdevice::enable(&config); + unwrap!(spawner.spawn(softdevice_task(sd))); + + info!("Scanning for peer..."); + + let config = central::ScanConfig { + whitelist: None, + tx_power: TxPower::ZerodBm, + ..Default::default() + }; + let res = central::scan(sd, &config, |params| unsafe { + let mut data = slice::from_raw_parts(params.data.p_data, params.data.len as usize); + while data.len() != 0 { + let len = data[0] as usize; + if data.len() < len + 1 { + break; + } + if len < 1 { + break; + } + let key = data[1]; + let value = &data[2..len + 1]; - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(ble_central_task(sd))); - }); + if key == 0x06 + && value + == &[ + 0xeb, 0x04, 0x8b, 0xfd, 0x5b, 0x03, 0x21, 0xb5, 0xeb, 0x11, 0x65, 0x2f, 0x18, 0xce, 0x9c, 0x82, + ] + { + return Some(Address::from_raw(params.peer_addr)); + } + data = &data[len + 1..]; + } + None + }) + .await; + let address = unwrap!(res); + info!("Scan found address {:?}", address); + + let addrs = &[&address]; + + let mut config = central::ConnectConfig::default(); + config.scan_config.whitelist = Some(addrs); + let conn = unwrap!(central::connect(sd, &config).await); + info!("connected"); + + let l = l2cap::L2cap::<Packet>::init(sd); + let config = l2cap::Config { credits: 8 }; + let ch = unwrap!(l.setup(&conn, &config, PSM).await); + info!("l2cap connected"); + + for i in 0..10 { + unwrap!(ch.tx(Packet::new(&[i; Packet::MTU])).await); + info!("l2cap tx done"); + } + futures::future::pending::<()>().await; } diff --git a/examples/src/bin/ble_l2cap_peripheral.rs b/examples/src/bin/ble_l2cap_peripheral.rs index 3e72725..486d1c3 100644 --- a/examples/src/bin/ble_l2cap_peripheral.rs +++ b/examples/src/bin/ble_l2cap_peripheral.rs @@ -8,53 +8,16 @@ mod example_common; use core::mem; use core::ptr::NonNull; -use cortex_m_rt::entry; use defmt::*; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use nrf_softdevice::ble::{l2cap, peripheral}; use nrf_softdevice::{ble, raw, RawError, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - const PSM: u16 = 0x2349; #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; -} - -#[embassy_executor::task] -async fn bluetooth_task(sd: &'static Softdevice) { - info!("My address: {:?}", ble::get_address(sd)); - - #[rustfmt::skip] - let adv_data = &[ - 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, - 0x11, 0x06, 0xeb, 0x04, 0x8b, 0xfd, 0x5b, 0x03, 0x21, 0xb5, 0xeb, 0x11, 0x65, 0x2f, 0x18, 0xce, 0x9c, 0x82, - 0x02, 0x09, b'H', - ]; - #[rustfmt::skip] - let scan_data = &[ ]; - - let l = l2cap::L2cap::<Packet>::init(sd); - - loop { - let config = peripheral::Config::default(); - let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { adv_data, scan_data }; - let conn = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); - - info!("advertising done!"); - - let config = l2cap::Config { credits: 8 }; - let ch = unwrap!(l.listen(&conn, &config, PSM).await); - info!("l2cap connected"); - - loop { - let pkt = unwrap!(ch.rx().await); - info!("rx: {:x}", pkt.as_bytes()); - } - } +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } use atomic_pool::{pool, Box}; @@ -100,8 +63,8 @@ impl l2cap::Packet for Packet { } } -#[entry] -fn main() -> ! { +#[embassy_executor::main] +async fn main(spawner: Spawner) { info!("Hello World!"); let config = nrf_softdevice::Config { @@ -146,12 +109,36 @@ fn main() -> ! { }; let sd = Softdevice::enable(&config); - unwrap!(RawError::convert(unsafe { raw::sd_clock_hfclk_request() })); + unwrap!(spawner.spawn(softdevice_task(sd))); + + info!("My address: {:?}", ble::get_address(sd)); + + #[rustfmt::skip] + let adv_data = &[ + 0x02, 0x01, raw::BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE as u8, + 0x11, 0x06, 0xeb, 0x04, 0x8b, 0xfd, 0x5b, 0x03, 0x21, 0xb5, 0xeb, 0x11, 0x65, 0x2f, 0x18, 0xce, 0x9c, 0x82, + 0x02, 0x09, b'H', + ]; + #[rustfmt::skip] + let scan_data = &[ ]; + + let l = l2cap::L2cap::<Packet>::init(sd); - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(bluetooth_task(sd))); - }); + loop { + let config = peripheral::Config::default(); + let adv = peripheral::ConnectableAdvertisement::ScannableUndirected { adv_data, scan_data }; + let conn = unwrap!(peripheral::advertise_connectable(sd, adv, &config).await); + + info!("advertising done!"); + + let config = l2cap::Config { credits: 8 }; + let ch = unwrap!(l.listen(&conn, &config, PSM).await); + info!("l2cap connected"); + + loop { + let pkt = unwrap!(ch.rx().await); + info!("rx: {:x}", pkt.as_bytes()); + } + } } diff --git a/examples/src/bin/ble_peripheral_onoff.rs b/examples/src/bin/ble_peripheral_onoff.rs index 99dcac4..6a626e4 100644 --- a/examples/src/bin/ble_peripheral_onoff.rs +++ b/examples/src/bin/ble_peripheral_onoff.rs @@ -7,21 +7,17 @@ mod example_common; use core::mem; -use cortex_m_rt::entry; use defmt::*; -use embassy_executor::executor::Executor; -use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull}; +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Input, Pin as _, Pull}; use embassy_nrf::interrupt::Priority; -use embassy_util::Forever; use futures::pin_mut; use nrf_softdevice::ble::{gatt_server, peripheral}; use nrf_softdevice::{raw, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } #[nrf_softdevice::gatt_service(uuid = "9e7312e0-2354-11eb-9f10-fbc30a62cf38")] @@ -73,52 +69,8 @@ async fn run_bluetooth(sd: &'static Softdevice, server: &Server) { } } -#[embassy_executor::task] -async fn bluetooth_task(sd: &'static Softdevice, server: Server, button1: AnyPin, button2: AnyPin) { - info!("Bluetooth is OFF"); - info!("Press nrf52840-dk button 1 to enable, button 2 to disable"); - - let button1 = Input::new(button1, Pull::Up); - let button2 = Input::new(button2, Pull::Up); - pin_mut!(button1); - pin_mut!(button2); - loop { - button1.as_mut().wait_for_low().await; - info!("Bluetooth ON!"); - - // Create a future that will run the bluetooth loop. - // Note the lack of `.await`! This creates the future but doesn't poll it yet. - let bluetooth_fut = run_bluetooth(sd, &server); - - // Create a future that will resolve when the OFF button is pressed. - let off_fut = async { - button2.as_mut().wait_for_low().await; - info!("Bluetooth OFF!"); - }; - - pin_mut!(bluetooth_fut); - pin_mut!(off_fut); - - // Select the two futures. - // - // select() returns when one of the two futures returns. The other future is dropped before completing. - // - // Since the bluetooth future never finishes, this can only happen when the Off button is pressed. - // This will cause the bluetooth future to be dropped. - // - // If it was advertising, the nested `peripheral::advertise_connectable` future will be dropped, which will cause - // the softdevice to stop advertising. - // If it was connected, it will drop everything including the `Connection` instance, which - // will tell the softdevice to disconnect it. - // - // This demonstrates the awesome power of Rust's async-await combined with nrf-softdevice's async wrappers. - // It's super easy to cancel a complex tree of operations: just drop its future! - futures::future::select(bluetooth_fut, off_fut).await; - } -} - -#[entry] -fn main() -> ! { +#[embassy_executor::main] +async fn main(spawner: Spawner) { info!("Hello World!"); let mut config = embassy_nrf::config::Config::default(); @@ -157,11 +109,47 @@ fn main() -> ! { }; let sd = Softdevice::enable(&config); + let server = unwrap!(Server::new(sd)); + unwrap!(spawner.spawn(softdevice_task(sd))); + + info!("Bluetooth is OFF"); + info!("Press nrf52840-dk button 1 to enable, button 2 to disable"); + + let button1 = Input::new(p.P0_11.degrade(), Pull::Up); + let button2 = Input::new(p.P0_12.degrade(), Pull::Up); + pin_mut!(button1); + pin_mut!(button2); + loop { + button1.as_mut().wait_for_low().await; + info!("Bluetooth ON!"); + + // Create a future that will run the bluetooth loop. + // Note the lack of `.await`! This creates the future but doesn't poll it yet. + let bluetooth_fut = run_bluetooth(sd, &server); + + // Create a future that will resolve when the OFF button is pressed. + let off_fut = async { + button2.as_mut().wait_for_low().await; + info!("Bluetooth OFF!"); + }; - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - let server = unwrap!(Server::new(sd)); - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(bluetooth_task(sd, server, p.P0_11.degrade(), p.P0_12.degrade()))); - }); + pin_mut!(bluetooth_fut); + pin_mut!(off_fut); + + // Select the two futures. + // + // select() returns when one of the two futures returns. The other future is dropped before completing. + // + // Since the bluetooth future never finishes, this can only happen when the Off button is pressed. + // This will cause the bluetooth future to be dropped. + // + // If it was advertising, the nested `peripheral::advertise_connectable` future will be dropped, which will cause + // the softdevice to stop advertising. + // If it was connected, it will drop everything including the `Connection` instance, which + // will tell the softdevice to disconnect it. + // + // This demonstrates the awesome power of Rust's async-await combined with nrf-softdevice's async wrappers. + // It's super easy to cancel a complex tree of operations: just drop its future! + futures::future::select(bluetooth_fut, off_fut).await; + } } diff --git a/examples/src/bin/ble_scan.rs b/examples/src/bin/ble_scan.rs index 7c33c31..e1f6698 100644 --- a/examples/src/bin/ble_scan.rs +++ b/examples/src/bin/ble_scan.rs @@ -7,22 +7,53 @@ mod example_common; use core::{mem, slice}; -use cortex_m_rt::entry; use defmt::*; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use nrf_softdevice::ble::central; use nrf_softdevice::{raw, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } -#[embassy_executor::task] -async fn ble_task(sd: &'static Softdevice) { +#[embassy_executor::main] +async fn main(spawner: Spawner) { + info!("Hello World!"); + + let config = nrf_softdevice::Config { + clock: Some(raw::nrf_clock_lf_cfg_t { + source: raw::NRF_CLOCK_LF_SRC_RC as u8, + rc_ctiv: 4, + rc_temp_ctiv: 2, + accuracy: 7, + }), + conn_gap: Some(raw::ble_gap_conn_cfg_t { + conn_count: 6, + event_length: 6, + }), + conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 128 }), + gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { attr_tab_size: 32768 }), + gap_role_count: Some(raw::ble_gap_cfg_role_count_t { + adv_set_count: 1, + periph_role_count: 3, + central_role_count: 3, + central_sec_count: 0, + _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), + }), + gap_device_name: Some(raw::ble_gap_cfg_device_name_t { + p_value: b"HelloRust" as *const u8 as _, + current_len: 9, + max_len: 9, + write_perm: unsafe { mem::zeroed() }, + _bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1(raw::BLE_GATTS_VLOC_STACK as u8), + }), + ..Default::default() + }; + + let sd = Softdevice::enable(&config); + unwrap!(spawner.spawn(softdevice_task(sd))); + let config = central::ScanConfig::default(); let res = central::scan(sd, &config, |params| unsafe { info!("AdvReport!"); @@ -63,46 +94,3 @@ async fn ble_task(sd: &'static Softdevice) { unwrap!(res); info!("Scan returned"); } - -#[entry] -fn main() -> ! { - info!("Hello World!"); - - let config = nrf_softdevice::Config { - clock: Some(raw::nrf_clock_lf_cfg_t { - source: raw::NRF_CLOCK_LF_SRC_RC as u8, - rc_ctiv: 4, - rc_temp_ctiv: 2, - accuracy: 7, - }), - conn_gap: Some(raw::ble_gap_conn_cfg_t { - conn_count: 6, - event_length: 6, - }), - conn_gatt: Some(raw::ble_gatt_conn_cfg_t { att_mtu: 128 }), - gatts_attr_tab_size: Some(raw::ble_gatts_cfg_attr_tab_size_t { attr_tab_size: 32768 }), - gap_role_count: Some(raw::ble_gap_cfg_role_count_t { - adv_set_count: 1, - periph_role_count: 3, - central_role_count: 3, - central_sec_count: 0, - _bitfield_1: raw::ble_gap_cfg_role_count_t::new_bitfield_1(0), - }), - gap_device_name: Some(raw::ble_gap_cfg_device_name_t { - p_value: b"HelloRust" as *const u8 as _, - current_len: 9, - max_len: 9, - write_perm: unsafe { mem::zeroed() }, - _bitfield_1: raw::ble_gap_cfg_device_name_t::new_bitfield_1(raw::BLE_GATTS_VLOC_STACK as u8), - }), - ..Default::default() - }; - - let sd = Softdevice::enable(&config); - - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(ble_task(sd))); - }); -} diff --git a/examples/src/bin/flash.rs b/examples/src/bin/flash.rs index 78cb42d..81e65e6 100644 --- a/examples/src/bin/flash.rs +++ b/examples/src/bin/flash.rs @@ -5,23 +5,24 @@ #[path = "../example_common.rs"] mod example_common; -use cortex_m_rt::entry; use defmt::*; -use embassy_executor::executor::Executor; -use embassy_util::Forever; +use embassy_executor::Spawner; use embedded_storage_async::nor_flash::*; use futures::pin_mut; use nrf_softdevice::{Flash, Softdevice}; -static EXECUTOR: Forever<Executor> = Forever::new(); - #[embassy_executor::task] -async fn softdevice_task(sd: &'static Softdevice) { - sd.run().await; +async fn softdevice_task(sd: &'static Softdevice) -> ! { + sd.run().await } -#[embassy_executor::task] -async fn flash_task(sd: &'static Softdevice) { +#[embassy_executor::main] +async fn main(spawner: Spawner) { + info!("Hello World!"); + + let sd = Softdevice::enable(&Default::default()); + unwrap!(spawner.spawn(softdevice_task(sd))); + let f = Flash::take(sd); pin_mut!(f); @@ -33,16 +34,3 @@ async fn flash_task(sd: &'static Softdevice) { unwrap!(f.as_mut().write(0x80000, &[1, 2, 3, 4]).await); info!("write done!"); } - -#[entry] -fn main() -> ! { - info!("Hello World!"); - - let sd = Softdevice::enable(&Default::default()); - - let executor = EXECUTOR.put(Executor::new()); - executor.run(move |spawner| { - unwrap!(spawner.spawn(softdevice_task(sd))); - unwrap!(spawner.spawn(flash_task(sd))); - }); -} diff --git a/nrf-softdevice/src/softdevice.rs b/nrf-softdevice/src/softdevice.rs index caad633..d744389 100644 --- a/nrf-softdevice/src/softdevice.rs +++ b/nrf-softdevice/src/softdevice.rs @@ -1,9 +1,8 @@ use core::marker::PhantomData; +use core::mem::MaybeUninit; use core::ptr; use core::sync::atomic::{AtomicBool, Ordering}; -use embassy_util::Forever; - use crate::{pac, raw, RawError, SocEvent}; unsafe extern "C" fn fault_handler(id: u32, pc: u32, info: u32) { @@ -85,13 +84,11 @@ fn cfg_set(id: u32, cfg: &raw::ble_cfg_t) { } static ENABLED: AtomicBool = AtomicBool::new(false); -static SOFTDEVICE: Forever<Softdevice> = Forever::new(); +static mut SOFTDEVICE: MaybeUninit<Softdevice> = MaybeUninit::uninit(); impl Softdevice { /// Enable the softdevice. /// - /// This function takes ownership of the softdevice-reserved peripherals to ensure application code doesn't attempt to use them after enabling. - /// /// # Panics /// - Panics if the requested configuration requires more memory than reserved for the softdevice. In that case, you can give more memory to the softdevice by editing the RAM start address in `memory.x`. The required start address is logged prior to panic. /// - Panics if the requested configuration has too high memory requirements for the softdevice. The softdevice supports a maximum dynamic memory size of 64kb. @@ -280,7 +277,7 @@ impl Softdevice { .map(|x| x.rx_mps) .unwrap_or(raw::BLE_L2CAP_MPS_MIN as u16); - SOFTDEVICE.put(Softdevice { + let sd = Softdevice { _private: PhantomData, #[cfg(feature = "ble-gatt")] @@ -288,7 +285,13 @@ impl Softdevice { #[cfg(feature = "ble-l2cap")] l2cap_rx_mps, - }) + }; + + unsafe { + let p = SOFTDEVICE.as_mut_ptr(); + p.write(sd); + &mut *p + } } /// Return an instance to the softdevice without checking whether @@ -296,7 +299,7 @@ impl Softdevice { /// (a call to [`enable`] has returned without error) and no `&mut` references /// to the softdevice are active pub unsafe fn steal() -> &'static Softdevice { - SOFTDEVICE.steal() + &*SOFTDEVICE.as_ptr() } /// Runs the softdevice event handling loop. |