-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor scanner again to avoid buffer copies * Add ble scanner example
- Loading branch information
Showing
13 changed files
with
186 additions
and
327 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use bt_hci::cmd::le::LeSetScanParams; | ||
use bt_hci::controller::ControllerCmdSync; | ||
use core::cell::RefCell; | ||
use embassy_futures::join::join; | ||
use embassy_time::{Duration, Timer}; | ||
use heapless::Deque; | ||
use trouble_host::prelude::*; | ||
|
||
/// Max number of connections | ||
const CONNECTIONS_MAX: usize = 1; | ||
const L2CAP_CHANNELS_MAX: usize = 1; | ||
const L2CAP_MTU: usize = 27; | ||
|
||
pub async fn 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<CONNECTIONS_MAX, L2CAP_CHANNELS_MAX, L2CAP_MTU> = 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(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use defmt::unwrap; | ||
use embassy_executor::Spawner; | ||
use embassy_nrf::peripherals::RNG; | ||
use embassy_nrf::{bind_interrupts, rng}; | ||
use embassy_time::{Duration, Timer}; | ||
use nrf_sdc::mpsl::MultiprotocolServiceLayer; | ||
use nrf_sdc::{self as sdc, mpsl}; | ||
use static_cell::StaticCell; | ||
use trouble_example_apps::ble_scanner; | ||
use {defmt_rtt as _, panic_probe as _}; | ||
|
||
bind_interrupts!(struct Irqs { | ||
RNG => rng::InterruptHandler<RNG>; | ||
EGU0_SWI0 => nrf_sdc::mpsl::LowPrioInterruptHandler; | ||
CLOCK_POWER => nrf_sdc::mpsl::ClockInterruptHandler; | ||
RADIO => nrf_sdc::mpsl::HighPrioInterruptHandler; | ||
TIMER0 => nrf_sdc::mpsl::HighPrioInterruptHandler; | ||
RTC0 => nrf_sdc::mpsl::HighPrioInterruptHandler; | ||
}); | ||
|
||
#[embassy_executor::task] | ||
async fn mpsl_task(mpsl: &'static MultiprotocolServiceLayer<'static>) -> ! { | ||
mpsl.run().await | ||
} | ||
|
||
fn build_sdc<'d, const N: usize>( | ||
p: nrf_sdc::Peripherals<'d>, | ||
rng: &'d mut rng::Rng<RNG>, | ||
mpsl: &'d MultiprotocolServiceLayer, | ||
mem: &'d mut sdc::Mem<N>, | ||
) -> Result<nrf_sdc::SoftdeviceController<'d>, nrf_sdc::Error> { | ||
sdc::Builder::new()? | ||
.support_scan()? | ||
.support_ext_scan()? | ||
.support_central()? | ||
.support_ext_central()? | ||
.central_count(1)? | ||
.build(p, rng, mpsl, mem) | ||
} | ||
|
||
#[embassy_executor::main] | ||
async fn main(spawner: Spawner) { | ||
let p = embassy_nrf::init(Default::default()); | ||
let mpsl_p = mpsl::Peripherals::new(p.RTC0, p.TIMER0, p.TEMP, p.PPI_CH19, p.PPI_CH30, p.PPI_CH31); | ||
let lfclk_cfg = mpsl::raw::mpsl_clock_lfclk_cfg_t { | ||
source: mpsl::raw::MPSL_CLOCK_LF_SRC_RC as u8, | ||
rc_ctiv: mpsl::raw::MPSL_RECOMMENDED_RC_CTIV as u8, | ||
rc_temp_ctiv: mpsl::raw::MPSL_RECOMMENDED_RC_TEMP_CTIV as u8, | ||
accuracy_ppm: mpsl::raw::MPSL_DEFAULT_CLOCK_ACCURACY_PPM as u16, | ||
skip_wait_lfclk_started: mpsl::raw::MPSL_DEFAULT_SKIP_WAIT_LFCLK_STARTED != 0, | ||
}; | ||
static MPSL: StaticCell<MultiprotocolServiceLayer> = StaticCell::new(); | ||
let mpsl = MPSL.init(unwrap!(mpsl::MultiprotocolServiceLayer::new(mpsl_p, Irqs, lfclk_cfg))); | ||
spawner.must_spawn(mpsl_task(&*mpsl)); | ||
|
||
let sdc_p = sdc::Peripherals::new( | ||
p.PPI_CH17, p.PPI_CH18, p.PPI_CH20, p.PPI_CH21, p.PPI_CH22, p.PPI_CH23, p.PPI_CH24, p.PPI_CH25, p.PPI_CH26, | ||
p.PPI_CH27, p.PPI_CH28, p.PPI_CH29, | ||
); | ||
|
||
let mut rng = rng::Rng::new(p.RNG, Irqs); | ||
|
||
let mut sdc_mem = sdc::Mem::<2712>::new(); | ||
let sdc = unwrap!(build_sdc(sdc_p, &mut rng, mpsl, &mut sdc_mem)); | ||
|
||
Timer::after(Duration::from_millis(200)).await; | ||
|
||
ble_scanner::run(sdc).await; | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.