diff --git a/.gitignore b/.gitignore index 93871a3d..8671949c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ **/target **/target_ci -Cargo.lock \ No newline at end of file +Cargo.lock +.idea \ No newline at end of file diff --git a/examples/serial-hci/README.md b/examples/serial-hci/README.md new file mode 100644 index 00000000..704b23fa --- /dev/null +++ b/examples/serial-hci/README.md @@ -0,0 +1,4 @@ +# Serial HCI example + +These examples require two Bluetooth dongles with a Host Controller Interface (HCI). +The examples have been tested with two nRF52840 dongles running the [HIC UART example](https://github.com/nrfconnect/sdk-zephyr/tree/main/samples/bluetooth/hci_uart). diff --git a/examples/serial-hci/src/bin/ble_bas_central.rs b/examples/serial-hci/src/bin/ble_bas_central.rs new file mode 100644 index 00000000..49531d2f --- /dev/null +++ b/examples/serial-hci/src/bin/ble_bas_central.rs @@ -0,0 +1,55 @@ +// Use with any serial HCI +use bt_hci::controller::ExternalController; +use bt_hci::transport::SerialTransport; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use log::*; +use tokio::time::Duration; +use tokio_serial::{DataBits, Parity, SerialStream, StopBits}; +use trouble_example_apps::ble_bas_central; + +#[tokio::main] +async fn main() { + env_logger::builder() + .filter_level(log::LevelFilter::Trace) + .format_timestamp_nanos() + .init(); + + let baudrate = 1000000; + + if std::env::args().len() != 2 { + println!("Provide the serial port as the one and only command line argument."); + return; + } + + let args: Vec = std::env::args().collect(); + + let mut port = SerialStream::open( + &tokio_serial::new(args[1].as_str(), baudrate) + .baud_rate(baudrate) + .data_bits(DataBits::Eight) + .parity(Parity::None) + .stop_bits(StopBits::One), + ) + .unwrap(); + + // Drain input + tokio::time::sleep(Duration::from_secs(1)).await; + loop { + let mut buf = [0; 1]; + match port.try_read(&mut buf[..]) { + Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => break, + _ => {} + } + } + info!("Ready!"); + + let (reader, writer) = tokio::io::split(port); + + let reader = embedded_io_adapters::tokio_1::FromTokio::new(reader); + let writer = embedded_io_adapters::tokio_1::FromTokio::new(writer); + + let driver: SerialTransport = SerialTransport::new(reader, writer); + let controller: ExternalController<_, 10> = ExternalController::new(driver); + + ble_bas_central::run::<_, 128>(controller).await; +} diff --git a/examples/serial-hci/src/bin/ble_l2cap_central.rs b/examples/serial-hci/src/bin/ble_l2cap_central.rs new file mode 100644 index 00000000..4711b62b --- /dev/null +++ b/examples/serial-hci/src/bin/ble_l2cap_central.rs @@ -0,0 +1,55 @@ +// Use with any serial HCI +use bt_hci::controller::ExternalController; +use bt_hci::transport::SerialTransport; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use log::*; +use tokio::time::Duration; +use tokio_serial::{DataBits, Parity, SerialStream, StopBits}; +use trouble_example_apps::ble_l2cap_central; + +#[tokio::main] +async fn main() { + env_logger::builder() + .filter_level(log::LevelFilter::Trace) + .format_timestamp_nanos() + .init(); + + let baudrate = 1000000; + + if std::env::args().len() != 2 { + println!("Provide the serial port as the one and only command line argument."); + return; + } + + let args: Vec = std::env::args().collect(); + + let mut port = SerialStream::open( + &tokio_serial::new(args[1].as_str(), baudrate) + .baud_rate(baudrate) + .data_bits(DataBits::Eight) + .parity(Parity::None) + .stop_bits(StopBits::One), + ) + .unwrap(); + + // Drain input + tokio::time::sleep(Duration::from_secs(1)).await; + loop { + let mut buf = [0; 1]; + match port.try_read(&mut buf[..]) { + Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => break, + _ => {} + } + } + info!("Ready!"); + + let (reader, writer) = tokio::io::split(port); + + let reader = embedded_io_adapters::tokio_1::FromTokio::new(reader); + let writer = embedded_io_adapters::tokio_1::FromTokio::new(writer); + + let driver: SerialTransport = SerialTransport::new(reader, writer); + let controller: ExternalController<_, 10> = ExternalController::new(driver); + + ble_l2cap_central::run::<_, 128>(controller).await; +} diff --git a/examples/serial-hci/src/bin/ble_l2cap_peripheral.rs b/examples/serial-hci/src/bin/ble_l2cap_peripheral.rs new file mode 100644 index 00000000..c250f1a3 --- /dev/null +++ b/examples/serial-hci/src/bin/ble_l2cap_peripheral.rs @@ -0,0 +1,55 @@ +// Use with any serial HCI +use bt_hci::controller::ExternalController; +use bt_hci::transport::SerialTransport; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use log::*; +use tokio::time::Duration; +use tokio_serial::{DataBits, Parity, SerialStream, StopBits}; +use trouble_example_apps::ble_l2cap_peripheral; + +#[tokio::main] +async fn main() { + env_logger::builder() + .filter_level(log::LevelFilter::Trace) + .format_timestamp_nanos() + .init(); + + let baudrate = 1000000; + + if std::env::args().len() != 2 { + println!("Provide the serial port as the one and only command line argument."); + return; + } + + let args: Vec = std::env::args().collect(); + + let mut port = SerialStream::open( + &tokio_serial::new(args[1].as_str(), baudrate) + .baud_rate(baudrate) + .data_bits(DataBits::Eight) + .parity(Parity::None) + .stop_bits(StopBits::One), + ) + .unwrap(); + + // Drain input + tokio::time::sleep(Duration::from_secs(1)).await; + loop { + let mut buf = [0; 1]; + match port.try_read(&mut buf[..]) { + Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => break, + _ => {} + } + } + info!("Ready!"); + + let (reader, writer) = tokio::io::split(port); + + let reader = embedded_io_adapters::tokio_1::FromTokio::new(reader); + let writer = embedded_io_adapters::tokio_1::FromTokio::new(writer); + + let driver: SerialTransport = SerialTransport::new(reader, writer); + let controller: ExternalController<_, 10> = ExternalController::new(driver); + + ble_l2cap_peripheral::run::<_, 128>(controller).await; +}