stm32/wpan: use new ownership model
This commit is contained in:
		| @@ -1,3 +1,5 @@ | |||||||
|  | use core::marker::PhantomData; | ||||||
|  |  | ||||||
| use embassy_stm32::ipcc::Ipcc; | use embassy_stm32::ipcc::Ipcc; | ||||||
|  |  | ||||||
| use crate::cmd::CmdPacket; | use crate::cmd::CmdPacket; | ||||||
| @@ -7,10 +9,12 @@ use crate::tables::BleTable; | |||||||
| use crate::unsafe_linked_list::LinkedListNode; | use crate::unsafe_linked_list::LinkedListNode; | ||||||
| use crate::{channels, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; | use crate::{channels, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; | ||||||
|  |  | ||||||
| pub struct Ble; | pub struct Ble { | ||||||
|  |     phantom: PhantomData<Ble>, | ||||||
|  | } | ||||||
|  |  | ||||||
| impl Ble { | impl Ble { | ||||||
|     pub(super) fn enable() { |     pub(crate) fn new() -> Self { | ||||||
|         unsafe { |         unsafe { | ||||||
|             LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); |             LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); | ||||||
|  |  | ||||||
| @@ -21,9 +25,11 @@ impl Ble { | |||||||
|                 phci_acl_data_buffer: HCI_ACL_DATA_BUFFER.as_mut_ptr().cast(), |                 phci_acl_data_buffer: HCI_ACL_DATA_BUFFER.as_mut_ptr().cast(), | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         Self { phantom: PhantomData } | ||||||
|     } |     } | ||||||
|     /// `HW_IPCC_BLE_EvtNot` |     /// `HW_IPCC_BLE_EvtNot` | ||||||
|     pub async fn read() -> EvtBox { |     pub async fn read(&self) -> EvtBox { | ||||||
|         Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { |         Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { | ||||||
|             if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { |             if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { | ||||||
|                 Some(EvtBox::new(node_ptr.cast())) |                 Some(EvtBox::new(node_ptr.cast())) | ||||||
| @@ -35,7 +41,7 @@ impl Ble { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// `TL_BLE_SendCmd` |     /// `TL_BLE_SendCmd` | ||||||
|     pub async fn write(opcode: u16, payload: &[u8]) { |     pub async fn write(&self, opcode: u16, payload: &[u8]) { | ||||||
|         Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { |         Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { | ||||||
|             CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); |             CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); | ||||||
|         }) |         }) | ||||||
| @@ -43,7 +49,7 @@ impl Ble { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// `TL_BLE_SendAclData` |     /// `TL_BLE_SendAclData` | ||||||
|     pub async fn acl_write(handle: u16, payload: &[u8]) { |     pub async fn acl_write(&self, handle: u16, payload: &[u8]) { | ||||||
|         Ipcc::send(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, || unsafe { |         Ipcc::send(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, || unsafe { | ||||||
|             CmdPacket::write_into( |             CmdPacket::write_into( | ||||||
|                 HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, |                 HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ pub mod fmt; | |||||||
| use core::mem::MaybeUninit; | use core::mem::MaybeUninit; | ||||||
| use core::sync::atomic::{compiler_fence, Ordering}; | use core::sync::atomic::{compiler_fence, Ordering}; | ||||||
|  |  | ||||||
|  | use ble::Ble; | ||||||
| use cmd::CmdPacket; | use cmd::CmdPacket; | ||||||
| use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | ||||||
| use embassy_stm32::interrupt; | use embassy_stm32::interrupt; | ||||||
| @@ -16,9 +17,10 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | |||||||
| use embassy_sync::channel::Channel; | use embassy_sync::channel::Channel; | ||||||
| use embassy_sync::signal::Signal; | use embassy_sync::signal::Signal; | ||||||
| use evt::{CcEvt, EvtBox}; | use evt::{CcEvt, EvtBox}; | ||||||
|  | use mm::MemoryManager; | ||||||
|  | use sys::Sys; | ||||||
| use tables::{ | use tables::{ | ||||||
|     BleTable, DeviceInfoTable, Mac802_15_4Table, MemManagerTable, RefTable, SysTable, ThreadTable, TracesTable, |     BleTable, DeviceInfoTable, Mac802_15_4Table, MemManagerTable, RefTable, SysTable, ThreadTable, TracesTable, | ||||||
|     WirelessFwInfoTable, |  | ||||||
| }; | }; | ||||||
| use unsafe_linked_list::LinkedListNode; | use unsafe_linked_list::LinkedListNode; | ||||||
|  |  | ||||||
| @@ -142,6 +144,10 @@ static STATE: Signal<CriticalSectionRawMutex, ()> = Signal::new(); | |||||||
|  |  | ||||||
| pub struct TlMbox<'d> { | pub struct TlMbox<'d> { | ||||||
|     _ipcc: PeripheralRef<'d, IPCC>, |     _ipcc: PeripheralRef<'d, IPCC>, | ||||||
|  |  | ||||||
|  |     pub sys_subsystem: Sys, | ||||||
|  |     pub mm_subsystem: MemoryManager, | ||||||
|  |     pub ble_subsystem: Ble, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<'d> TlMbox<'d> { | impl<'d> TlMbox<'d> { | ||||||
| @@ -226,9 +232,9 @@ impl<'d> TlMbox<'d> { | |||||||
|  |  | ||||||
|         Ipcc::enable(config); |         Ipcc::enable(config); | ||||||
|  |  | ||||||
|         sys::Sys::enable(); |         let sys = sys::Sys::new(); | ||||||
|         ble::Ble::enable(); |         let ble = ble::Ble::new(); | ||||||
|         mm::MemoryManager::enable(); |         let mm = mm::MemoryManager::new(); | ||||||
|  |  | ||||||
|         // enable interrupts |         // enable interrupts | ||||||
|         interrupt::typelevel::IPCC_C1_RX::unpend(); |         interrupt::typelevel::IPCC_C1_RX::unpend(); | ||||||
| @@ -239,18 +245,11 @@ impl<'d> TlMbox<'d> { | |||||||
|  |  | ||||||
|         STATE.reset(); |         STATE.reset(); | ||||||
|  |  | ||||||
|         Self { _ipcc: ipcc } |         Self { | ||||||
|     } |             _ipcc: ipcc, | ||||||
|  |             sys_subsystem: sys, | ||||||
|     /// Returns CPU2 wireless firmware information (if present). |             ble_subsystem: ble, | ||||||
|     pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> { |             mm_subsystem: mm, | ||||||
|         let info = unsafe { &(*(*TL_REF_TABLE.as_ptr()).device_info_table).wireless_fw_info_table }; |  | ||||||
|  |  | ||||||
|         // Zero version indicates that CPU2 wasn't active and didn't fill the information table |  | ||||||
|         if info.version != 0 { |  | ||||||
|             Some(*info) |  | ||||||
|         } else { |  | ||||||
|             None |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| //! Memory manager routines | //! Memory manager routines | ||||||
|  |  | ||||||
| use core::future::poll_fn; | use core::future::poll_fn; | ||||||
|  | use core::marker::PhantomData; | ||||||
| use core::task::Poll; | use core::task::Poll; | ||||||
|  |  | ||||||
| use cortex_m::interrupt; | use cortex_m::interrupt; | ||||||
| @@ -17,10 +18,12 @@ use crate::{ | |||||||
|  |  | ||||||
| static MM_WAKER: AtomicWaker = AtomicWaker::new(); | static MM_WAKER: AtomicWaker = AtomicWaker::new(); | ||||||
|  |  | ||||||
| pub struct MemoryManager; | pub struct MemoryManager { | ||||||
|  |     phantom: PhantomData<MemoryManager>, | ||||||
|  | } | ||||||
|  |  | ||||||
| impl MemoryManager { | impl MemoryManager { | ||||||
|     pub fn enable() { |     pub(crate) fn new() -> Self { | ||||||
|         unsafe { |         unsafe { | ||||||
|             LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); |             LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); | ||||||
|             LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); |             LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); | ||||||
| @@ -35,10 +38,12 @@ impl MemoryManager { | |||||||
|                 tracespoolsize: 0, |                 tracespoolsize: 0, | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         Self { phantom: PhantomData } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// SAFETY: passing a pointer to something other than an event packet is UB |     /// SAFETY: passing a pointer to something other than an event packet is UB | ||||||
|     pub unsafe fn drop_event_packet(evt: *mut EvtPacket) { |     pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) { | ||||||
|         interrupt::free(|_| unsafe { |         interrupt::free(|_| unsafe { | ||||||
|             LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); |             LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); | ||||||
|         }); |         }); | ||||||
| @@ -46,7 +51,7 @@ impl MemoryManager { | |||||||
|         MM_WAKER.wake(); |         MM_WAKER.wake(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub async fn run_queue() { |     pub async fn run_queue(&self) { | ||||||
|         loop { |         loop { | ||||||
|             poll_fn(|cx| unsafe { |             poll_fn(|cx| unsafe { | ||||||
|                 MM_WAKER.register(cx.waker()); |                 MM_WAKER.register(cx.waker()); | ||||||
|   | |||||||
| @@ -1,16 +1,20 @@ | |||||||
|  | use core::marker::PhantomData; | ||||||
|  |  | ||||||
| use crate::cmd::CmdPacket; | use crate::cmd::CmdPacket; | ||||||
| use crate::consts::TlPacketType; | use crate::consts::TlPacketType; | ||||||
| use crate::evt::EvtBox; | use crate::evt::EvtBox; | ||||||
| use crate::shci::{ShciBleInitCmdParam, SCHI_OPCODE_BLE_INIT}; | use crate::shci::{ShciBleInitCmdParam, SCHI_OPCODE_BLE_INIT}; | ||||||
| use crate::tables::SysTable; | use crate::tables::{SysTable, WirelessFwInfoTable}; | ||||||
| use crate::unsafe_linked_list::LinkedListNode; | use crate::unsafe_linked_list::LinkedListNode; | ||||||
| use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_SYS_TABLE}; | use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; | ||||||
|  |  | ||||||
| pub struct Sys; | pub struct Sys { | ||||||
|  |     phantom: PhantomData<Sys>, | ||||||
|  | } | ||||||
|  |  | ||||||
| impl Sys { | impl Sys { | ||||||
|     /// TL_Sys_Init |     /// TL_Sys_Init | ||||||
|     pub fn enable() { |     pub(crate) fn new() -> Self { | ||||||
|         unsafe { |         unsafe { | ||||||
|             LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); |             LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); | ||||||
|  |  | ||||||
| @@ -19,30 +23,33 @@ impl Sys { | |||||||
|                 sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), |                 sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         Self { phantom: PhantomData } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //    pub async fn shci_c2_ble_init(&mut self, param: ShciBleInitCmdParam) -> SchiCommandStatus { |     /// Returns CPU2 wireless firmware information (if present). | ||||||
|     //        let command_event = self |     pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> { | ||||||
|     //            .write_and_get_response(TlPacketType::SysCmd, ShciOpcode::BleInit as u16, param.payload()) |         let info = unsafe { TL_DEVICE_INFO_TABLE.as_mut_ptr().read_volatile().wireless_fw_info_table }; | ||||||
|     //            .await; |  | ||||||
|     // |  | ||||||
|     //        let payload = command_event.payload[0]; |  | ||||||
|     //        // info!("payload: {:x}", payload); |  | ||||||
|     // |  | ||||||
|     //        payload.try_into().unwrap() |  | ||||||
|     //    } |  | ||||||
|  |  | ||||||
|     pub fn write(opcode: u16, payload: &[u8]) { |         // Zero version indicates that CPU2 wasn't active and didn't fill the information table | ||||||
|  |         if info.version != 0 { | ||||||
|  |             Some(info) | ||||||
|  |         } else { | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     pub fn write(&self, opcode: u16, payload: &[u8]) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode, payload); |             CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode, payload); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub async fn shci_c2_ble_init(param: ShciBleInitCmdParam) { |     pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) { | ||||||
|         debug!("sending SHCI"); |         debug!("sending SHCI"); | ||||||
|  |  | ||||||
|         Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || { |         Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || { | ||||||
|             Self::write(SCHI_OPCODE_BLE_INIT, param.payload()); |             self.write(SCHI_OPCODE_BLE_INIT, param.payload()); | ||||||
|         }) |         }) | ||||||
|         .await; |         .await; | ||||||
|  |  | ||||||
| @@ -50,7 +57,7 @@ impl Sys { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// `HW_IPCC_SYS_EvtNot` |     /// `HW_IPCC_SYS_EvtNot` | ||||||
|     pub async fn read() -> EvtBox { |     pub async fn read(&self) -> EvtBox { | ||||||
|         Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { |         Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { | ||||||
|             if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { |             if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { | ||||||
|                 Some(EvtBox::new(node_ptr.cast())) |                 Some(EvtBox::new(node_ptr.cast())) | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) { | |||||||
|     let mbox = TlMbox::init(p.IPCC, Irqs, config); |     let mbox = TlMbox::init(p.IPCC, Irqs, config); | ||||||
|  |  | ||||||
|     loop { |     loop { | ||||||
|         let wireless_fw_info = mbox.wireless_fw_info(); |         let wireless_fw_info = mbox.sys_subsystem.wireless_fw_info(); | ||||||
|         match wireless_fw_info { |         match wireless_fw_info { | ||||||
|             None => info!("not yet initialized"), |             None => info!("not yet initialized"), | ||||||
|             Some(fw_info) => { |             Some(fw_info) => { | ||||||
|   | |||||||
| @@ -6,8 +6,6 @@ use defmt::*; | |||||||
| use embassy_executor::Spawner; | use embassy_executor::Spawner; | ||||||
| use embassy_stm32::bind_interrupts; | use embassy_stm32::bind_interrupts; | ||||||
| use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | ||||||
| use embassy_stm32_wpan::ble::Ble; |  | ||||||
| use embassy_stm32_wpan::sys::Sys; |  | ||||||
| use embassy_stm32_wpan::TlMbox; | use embassy_stm32_wpan::TlMbox; | ||||||
| use {defmt_rtt as _, panic_probe as _}; | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
| @@ -46,15 +44,18 @@ async fn main(_spawner: Spawner) { | |||||||
|     info!("Hello World!"); |     info!("Hello World!"); | ||||||
|  |  | ||||||
|     let config = Config::default(); |     let config = Config::default(); | ||||||
|     let _ = TlMbox::init(p.IPCC, Irqs, config); |     let mbox = TlMbox::init(p.IPCC, Irqs, config); | ||||||
|  |  | ||||||
|     Sys::shci_c2_ble_init(Default::default()).await; |     let sys_event = mbox.sys_subsystem.read().await; | ||||||
|  |     info!("sys event: {}", sys_event.payload()); | ||||||
|  |  | ||||||
|  |     mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; | ||||||
|  |  | ||||||
|     info!("starting ble..."); |     info!("starting ble..."); | ||||||
|     Ble::write(0x0c, &[]).await; |     mbox.ble_subsystem.write(0x0c, &[]).await; | ||||||
|  |  | ||||||
|     info!("waiting for ble..."); |     info!("waiting for ble..."); | ||||||
|     let ble_event = Ble::read().await; |     let ble_event = mbox.ble_subsystem.read().await; | ||||||
|  |  | ||||||
|     info!("ble event: {}", ble_event.payload()); |     info!("ble event: {}", ble_event.payload()); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,8 +13,6 @@ use embassy_executor::Spawner; | |||||||
| use embassy_futures::poll_once; | use embassy_futures::poll_once; | ||||||
| use embassy_stm32::bind_interrupts; | use embassy_stm32::bind_interrupts; | ||||||
| use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; | ||||||
| use embassy_stm32_wpan::ble::Ble; |  | ||||||
| use embassy_stm32_wpan::sys::Sys; |  | ||||||
| use embassy_stm32_wpan::{mm, TlMbox}; | use embassy_stm32_wpan::{mm, TlMbox}; | ||||||
| use embassy_time::{Duration, Timer}; | use embassy_time::{Duration, Timer}; | ||||||
|  |  | ||||||
| @@ -24,8 +22,8 @@ bind_interrupts!(struct Irqs{ | |||||||
| }); | }); | ||||||
|  |  | ||||||
| #[embassy_executor::task] | #[embassy_executor::task] | ||||||
| async fn run_mm_queue() { | async fn run_mm_queue(memory_manager: mm::MemoryManager) { | ||||||
|     mm::MemoryManager::run_queue().await; |     memory_manager.run_queue().await; | ||||||
| } | } | ||||||
|  |  | ||||||
| #[embassy_executor::main] | #[embassy_executor::main] | ||||||
| @@ -33,50 +31,41 @@ async fn main(spawner: Spawner) { | |||||||
|     let p = embassy_stm32::init(config()); |     let p = embassy_stm32::init(config()); | ||||||
|     info!("Hello World!"); |     info!("Hello World!"); | ||||||
|  |  | ||||||
|     spawner.spawn(run_mm_queue()).unwrap(); |  | ||||||
|  |  | ||||||
|     let config = Config::default(); |     let config = Config::default(); | ||||||
|     let mbox = TlMbox::init(p.IPCC, Irqs, config); |     let mbox = TlMbox::init(p.IPCC, Irqs, config); | ||||||
|  |  | ||||||
|     let ready_event = Sys::read().await; |     spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); | ||||||
|     let _ = poll_once(Sys::read()); // clear rx not |  | ||||||
|  |     let ready_event = mbox.sys_subsystem.read().await; | ||||||
|  |     let _ = poll_once(mbox.sys_subsystem.read()); // clear rx not | ||||||
|  |  | ||||||
|     info!("coprocessor ready {}", ready_event.payload()); |     info!("coprocessor ready {}", ready_event.payload()); | ||||||
|  |  | ||||||
|     // test memory manager |     // test memory manager | ||||||
|     mem::drop(ready_event); |     mem::drop(ready_event); | ||||||
|  |  | ||||||
|     loop { |     let fw_info = mbox.sys_subsystem.wireless_fw_info().unwrap(); | ||||||
|         let wireless_fw_info = mbox.wireless_fw_info(); |     let version_major = fw_info.version_major(); | ||||||
|         match wireless_fw_info { |     let version_minor = fw_info.version_minor(); | ||||||
|             None => {} |     let subversion = fw_info.subversion(); | ||||||
|             Some(fw_info) => { |  | ||||||
|                 let version_major = fw_info.version_major(); |  | ||||||
|                 let version_minor = fw_info.version_minor(); |  | ||||||
|                 let subversion = fw_info.subversion(); |  | ||||||
|  |  | ||||||
|                 let sram2a_size = fw_info.sram2a_size(); |     let sram2a_size = fw_info.sram2a_size(); | ||||||
|                 let sram2b_size = fw_info.sram2b_size(); |     let sram2b_size = fw_info.sram2b_size(); | ||||||
|  |  | ||||||
|                 info!( |     info!( | ||||||
|                     "version {}.{}.{} - SRAM2a {} - SRAM2b {}", |         "version {}.{}.{} - SRAM2a {} - SRAM2b {}", | ||||||
|                     version_major, version_minor, subversion, sram2a_size, sram2b_size |         version_major, version_minor, subversion, sram2a_size, sram2b_size | ||||||
|                 ); |     ); | ||||||
|  |  | ||||||
|                 break; |     Timer::after(Duration::from_millis(50)).await; | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Timer::after(Duration::from_millis(50)).await; |     mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Sys::shci_c2_ble_init(Default::default()).await; |  | ||||||
|  |  | ||||||
|     info!("starting ble..."); |     info!("starting ble..."); | ||||||
|     Ble::write(0x0c, &[]).await; |     mbox.ble_subsystem.write(0x0c, &[]).await; | ||||||
|  |  | ||||||
|     info!("waiting for ble..."); |     info!("waiting for ble..."); | ||||||
|     let ble_event = Ble::read().await; |     let ble_event = mbox.ble_subsystem.read().await; | ||||||
|  |  | ||||||
|     info!("ble event: {}", ble_event.payload()); |     info!("ble event: {}", ble_event.payload()); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user