From 7177e7ea1aae2eb6973816a158e714b4fcd5b9a6 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 08:37:26 -0500 Subject: [PATCH 1/9] stm32/wpan: cleanup and expand shci --- embassy-stm32-wpan/src/evt.rs | 65 +----- embassy-stm32-wpan/src/shci.rs | 348 ++++++++++++++++++++++++++++++--- embassy-stm32-wpan/src/sys.rs | 35 ++-- tests/stm32/src/bin/tl_mbox.rs | 8 +- 4 files changed, 349 insertions(+), 107 deletions(-) diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs index 3a9d03576..a7b99e540 100644 --- a/embassy-stm32-wpan/src/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs @@ -62,6 +62,7 @@ pub struct EvtSerial { } #[derive(Copy, Clone, Default)] +#[repr(C, packed)] pub struct EvtStub { pub kind: u8, pub evt_code: u8, @@ -114,7 +115,7 @@ impl EvtBox { } } - pub fn payload<'a>(&self) -> &'a [u8] { + pub fn payload<'a>(&'a self) -> &'a [u8] { unsafe { let p_payload_len = &(*self.ptr).evt_serial.evt.payload_len as *const u8; let p_payload = &(*self.ptr).evt_serial.evt.payload as *const u8; @@ -124,72 +125,10 @@ impl EvtBox { slice::from_raw_parts(p_payload, payload_len as usize) } } - - // TODO: bring back acl - - // /// writes an underlying [`EvtPacket`] into the provided buffer. - // /// Returns the number of bytes that were written. - // /// Returns an error if event kind is unknown or if provided buffer size is not enough. - // #[allow(clippy::result_unit_err)] - // pub fn write(&self, buf: &mut [u8]) -> Result { - // unsafe { - // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; - // - // let evt_data: *const EvtPacket = self.ptr.cast(); - // let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; - // let evt_serial_buf: *const u8 = evt_serial.cast(); - // - // let acl_data: *const AclDataPacket = self.ptr.cast(); - // let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; - // let acl_serial_buf: *const u8 = acl_serial.cast(); - // - // if let TlPacketType::AclData = evt_kind { - // let len = (*acl_serial).length as usize + 5; - // if len > buf.len() { - // return Err(()); - // } - // - // core::ptr::copy(evt_serial_buf, buf.as_mut_ptr(), len); - // - // Ok(len) - // } else { - // let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE; - // if len > buf.len() { - // return Err(()); - // } - // - // core::ptr::copy(acl_serial_buf, buf.as_mut_ptr(), len); - // - // Ok(len) - // } - // } - // } - // - // /// returns the size of a buffer required to hold this event - // #[allow(clippy::result_unit_err)] - // pub fn size(&self) -> Result { - // unsafe { - // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; - // - // let evt_data: *const EvtPacket = self.ptr.cast(); - // let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; - // - // let acl_data: *const AclDataPacket = self.ptr.cast(); - // let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; - // - // if let TlPacketType::AclData = evt_kind { - // Ok((*acl_serial).length as usize + 5) - // } else { - // Ok((*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE) - // } - // } - // } } impl Drop for EvtBox { fn drop(&mut self) { - trace!("evt box drop packet"); - unsafe { mm::MemoryManager::drop_event_packet(self.ptr) }; } } diff --git a/embassy-stm32-wpan/src/shci.rs b/embassy-stm32-wpan/src/shci.rs index cdf027d5e..f4e9ba84c 100644 --- a/embassy-stm32-wpan/src/shci.rs +++ b/embassy-stm32-wpan/src/shci.rs @@ -2,38 +2,345 @@ use core::{mem, slice}; use super::{TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE}; -pub const SCHI_OPCODE_BLE_INIT: u16 = 0xfc66; +const SHCI_OGF: u16 = 0x3F; -#[derive(Debug, Clone, Copy)] +const fn opcode(ogf: u16, ocf: u16) -> isize { + ((ogf << 10) + ocf) as isize +} + +#[allow(dead_code)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum SchiCommandStatus { + ShciSuccess = 0x00, + ShciUnknownCmd = 0x01, + ShciMemoryCapacityExceededErrCode = 0x07, + ShciErrUnsupportedFeature = 0x11, + ShciErrInvalidHciCmdParams = 0x12, + ShciErrInvalidParams = 0x42, /* only used for release < v1.13.0 */ + ShciErrInvalidParamsV2 = 0x92, /* available for release >= v1.13.0 */ + ShciFusCmdNotSupported = 0xFF, +} + +impl TryFrom for SchiCommandStatus { + type Error = (); + + fn try_from(v: u8) -> Result { + match v { + x if x == SchiCommandStatus::ShciSuccess as u8 => Ok(SchiCommandStatus::ShciSuccess), + x if x == SchiCommandStatus::ShciUnknownCmd as u8 => Ok(SchiCommandStatus::ShciUnknownCmd), + x if x == SchiCommandStatus::ShciMemoryCapacityExceededErrCode as u8 => { + Ok(SchiCommandStatus::ShciMemoryCapacityExceededErrCode) + } + x if x == SchiCommandStatus::ShciErrUnsupportedFeature as u8 => { + Ok(SchiCommandStatus::ShciErrUnsupportedFeature) + } + x if x == SchiCommandStatus::ShciErrInvalidHciCmdParams as u8 => { + Ok(SchiCommandStatus::ShciErrInvalidHciCmdParams) + } + x if x == SchiCommandStatus::ShciErrInvalidParams as u8 => Ok(SchiCommandStatus::ShciErrInvalidParams), /* only used for release < v1.13.0 */ + x if x == SchiCommandStatus::ShciErrInvalidParamsV2 as u8 => Ok(SchiCommandStatus::ShciErrInvalidParamsV2), /* available for release >= v1.13.0 */ + x if x == SchiCommandStatus::ShciFusCmdNotSupported as u8 => Ok(SchiCommandStatus::ShciFusCmdNotSupported), + _ => Err(()), + } + } +} + +#[allow(dead_code)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ShciOpcode { + // 0x50 reserved + // 0x51 reserved + FusGetState = opcode(SHCI_OGF, 0x52), + // 0x53 reserved + FusFirmwareUpgrade = opcode(SHCI_OGF, 0x54), + FusFirmwareDelete = opcode(SHCI_OGF, 0x55), + FusUpdateAuthKey = opcode(SHCI_OGF, 0x56), + FusLockAuthKey = opcode(SHCI_OGF, 0x57), + FusStoreUserKey = opcode(SHCI_OGF, 0x58), + FusLoadUserKey = opcode(SHCI_OGF, 0x59), + FusStartWirelessStack = opcode(SHCI_OGF, 0x5a), + // 0x5b reserved + // 0x5c reserved + FusLockUserKey = opcode(SHCI_OGF, 0x5d), + FusUnloadUserKey = opcode(SHCI_OGF, 0x5e), + FusActivateAntirollback = opcode(SHCI_OGF, 0x5f), + // 0x60 reserved + // 0x61 reserved + // 0x62 reserved + // 0x63 reserved + // 0x64 reserved + // 0x65 reserved + BleInit = opcode(SHCI_OGF, 0x66), + ThreadInit = opcode(SHCI_OGF, 0x67), + DebugInit = opcode(SHCI_OGF, 0x68), + FlashEraseActivity = opcode(SHCI_OGF, 0x69), + ConcurrentSetMode = opcode(SHCI_OGF, 0x6a), + FlashStoreData = opcode(SHCI_OGF, 0x6b), + FlashEraseData = opcode(SHCI_OGF, 0x6c), + RadioAllowLowPower = opcode(SHCI_OGF, 0x6d), + Mac802_15_4Init = opcode(SHCI_OGF, 0x6e), + ReInit = opcode(SHCI_OGF, 0x6f), + ZigbeeInit = opcode(SHCI_OGF, 0x70), + LldTestsInit = opcode(SHCI_OGF, 0x71), + ExtraConfig = opcode(SHCI_OGF, 0x72), + SetFlashActivityControl = opcode(SHCI_OGF, 0x73), + BleLldInit = opcode(SHCI_OGF, 0x74), + Config = opcode(SHCI_OGF, 0x75), + ConcurrentGetNextBleEvtTime = opcode(SHCI_OGF, 0x76), + ConcurrentEnableNext802_15_4EvtNotification = opcode(SHCI_OGF, 0x77), + Mac802_15_4DeInit = opcode(SHCI_OGF, 0x78), +} + +pub const SHCI_C2_CONFIG_EVTMASK1_BIT0_ERROR_NOTIF_ENABLE: u8 = 1 << 0; +pub const SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE: u8 = 1 << 1; +pub const SHCI_C2_CONFIG_EVTMASK1_BIT2_THREAD_NVM_RAM_UPDATE_ENABLE: u8 = 1 << 2; +pub const SHCI_C2_CONFIG_EVTMASK1_BIT3_NVM_START_WRITE_ENABLE: u8 = 1 << 3; +pub const SHCI_C2_CONFIG_EVTMASK1_BIT4_NVM_END_WRITE_ENABLE: u8 = 1 << 4; +pub const SHCI_C2_CONFIG_EVTMASK1_BIT5_NVM_START_ERASE_ENABLE: u8 = 1 << 5; +pub const SHCI_C2_CONFIG_EVTMASK1_BIT6_NVM_END_ERASE_ENABLE: u8 = 1 << 6; + +#[derive(Clone, Copy)] +#[repr(C, packed)] +pub struct ShciConfigParam { + pub payload_cmd_size: u8, + pub config: u8, + pub event_mask: u8, + pub spare: u8, + pub ble_nvm_ram_address: u32, + pub thread_nvm_ram_address: u32, + pub revision_id: u16, + pub device_id: u16, +} + +impl ShciConfigParam { + pub fn payload<'a>(&self) -> &'a [u8] { + unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::()) } + } +} + +impl Default for ShciConfigParam { + fn default() -> Self { + Self { + payload_cmd_size: (mem::size_of::() - 1) as u8, + config: 0, + event_mask: SHCI_C2_CONFIG_EVTMASK1_BIT0_ERROR_NOTIF_ENABLE + + SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE + + SHCI_C2_CONFIG_EVTMASK1_BIT2_THREAD_NVM_RAM_UPDATE_ENABLE + + SHCI_C2_CONFIG_EVTMASK1_BIT3_NVM_START_WRITE_ENABLE + + SHCI_C2_CONFIG_EVTMASK1_BIT4_NVM_END_WRITE_ENABLE + + SHCI_C2_CONFIG_EVTMASK1_BIT5_NVM_START_ERASE_ENABLE + + SHCI_C2_CONFIG_EVTMASK1_BIT6_NVM_END_ERASE_ENABLE, + spare: 0, + ble_nvm_ram_address: 0, + thread_nvm_ram_address: 0, + revision_id: 0, + device_id: 0, + } + } +} + +#[derive(Clone, Copy)] #[repr(C, packed)] pub struct ShciBleInitCmdParam { - /// NOT USED CURRENTLY + /// NOT USED - shall be set to 0 pub p_ble_buffer_address: u32, - - /// Size of the Buffer allocated in pBleBufferAddress + /// NOT USED - shall be set to 0 pub ble_buffer_size: u32, - + /// Maximum number of attribute records related to all the required characteristics (excluding the services) + /// that can be stored in the GATT database, for the specific BLE user application. + /// For each characteristic, the number of attribute records goes from two to five depending on the characteristic properties: + /// - minimum of two (one for declaration and one for the value) + /// - add one more record for each additional property: notify or indicate, broadcast, extended property. + /// The total calculated value must be increased by 9, due to the records related to the standard attribute profile and + /// GAP service characteristics, and automatically added when initializing GATT and GAP layers + /// - Min value: + 9 + /// - Max value: depending on the GATT database defined by user application pub num_attr_record: u16, + /// Defines the maximum number of services that can be stored in the GATT database. Note that the GAP and GATT services + /// are automatically added at initialization so this parameter must be the number of user services increased by two. + /// - Min value: + 2 + /// - Max value: depending GATT database defined by user application pub num_attr_serv: u16, + /// NOTE: This parameter is ignored by the CPU2 when the parameter "Options" is set to "LL_only" ( see Options description in that structure ) + /// + /// Size of the storage area for the attribute values. + /// Each characteristic contributes to the attrValueArrSize value as follows: + /// - Characteristic value length plus: + /// + 5 bytes if characteristic UUID is 16 bits + /// + 19 bytes if characteristic UUID is 128 bits + /// + 2 bytes if characteristic has a server configuration descriptor + /// + 2 bytes * NumOfLinks if the characteristic has a client configuration descriptor + /// + 2 bytes if the characteristic has extended properties + /// Each descriptor contributes to the attrValueArrSize value as follows: + /// - Descriptor length pub attr_value_arr_size: u16, + /// Maximum number of BLE links supported + /// - Min value: 1 + /// - Max value: 8 pub num_of_links: u8, + /// Disable/enable the extended packet length BLE 5.0 feature + /// - Disable: 0 + /// - Enable: 1 pub extended_packet_length_enable: u8, - pub pr_write_list_size: u8, - pub mb_lock_count: u8, - + /// NOTE: This parameter is ignored by the CPU2 when the parameter "Options" is set to "LL_only" ( see Options description in that structure ) + /// + /// Maximum number of supported "prepare write request" + /// - Min value: given by the macro DEFAULT_PREP_WRITE_LIST_SIZE + /// - Max value: a value higher than the minimum required can be specified, but it is not recommended + pub prepare_write_list_size: u8, + /// NOTE: This parameter is overwritten by the CPU2 with an hardcoded optimal value when the parameter "Options" is set to "LL_only" + /// ( see Options description in that structure ) + /// + /// Number of allocated memory blocks for the BLE stack + /// - Min value: given by the macro MBLOCKS_CALC + /// - Max value: a higher value can improve data throughput performance, but uses more memory + pub block_count: u8, + /// NOTE: This parameter is ignored by the CPU2 when the parameter "Options" is set to "LL_only" ( see Options description in that structure ) + /// + /// Maximum ATT MTU size supported + /// - Min value: 23 + /// - Max value: 512 pub att_mtu: u16, + /// The sleep clock accuracy (ppm value) that used in BLE connected slave mode to calculate the window widening + /// (in combination with the sleep clock accuracy sent by master in CONNECT_REQ PDU), + /// refer to BLE 5.0 specifications - Vol 6 - Part B - chap 4.5.7 and 4.2.2 + /// - Min value: 0 + /// - Max value: 500 (worst possible admitted by specification) pub slave_sca: u16, + /// The sleep clock accuracy handled in master mode. It is used to determine the connection and advertising events timing. + /// It is transmitted to the slave in CONNEC_REQ PDU used by the slave to calculate the window widening, + /// see SlaveSca and Bluetooth Core Specification v5.0 Vol 6 - Part B - chap 4.5.7 and 4.2.2 + /// Possible values: + /// - 251 ppm to 500 ppm: 0 + /// - 151 ppm to 250 ppm: 1 + /// - 101 ppm to 150 ppm: 2 + /// - 76 ppm to 100 ppm: 3 + /// - 51 ppm to 75 ppm: 4 + /// - 31 ppm to 50 ppm: 5 + /// - 21 ppm to 30 ppm: 6 + /// - 0 ppm to 20 ppm: 7 pub master_sca: u8, + /// Some information for Low speed clock mapped in bits field + /// - bit 0: + /// - 1: Calibration for the RF system wakeup clock source + /// - 0: No calibration for the RF system wakeup clock source + /// - bit 1: + /// - 1: STM32W5M Module device + /// - 0: Other devices as STM32WBxx SOC, STM32WB1M module + /// - bit 2: + /// - 1: HSE/1024 Clock config + /// - 0: LSE Clock config pub ls_source: u8, + /// This parameter determines the maximum duration of a slave connection event. When this duration is reached the slave closes + /// the current connections event (whatever is the CE_length parameter specified by the master in HCI_CREATE_CONNECTION HCI command), + /// expressed in units of 625/256 µs (~2.44 µs) + /// - Min value: 0 (if 0 is specified, the master and slave perform only a single TX-RX exchange per connection event) + /// - Max value: 1638400 (4000 ms). A higher value can be specified (max 0xFFFFFFFF) but results in a maximum connection time + /// of 4000 ms as specified. In this case the parameter is not applied, and the predicted CE length calculated on slave is not shortened pub max_conn_event_length: u32, + /// Startup time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 µs (~2.44 µs). + /// - Min value: 0 + /// - Max value: 820 (~2 ms). A higher value can be specified, but the value that implemented in stack is forced to ~2 ms pub hs_startup_time: u16, + /// Viterbi implementation in BLE LL reception. + /// - 0: Enable + /// - 1: Disable pub viterbi_enable: u8, - pub ll_only: u8, + /// - bit 0: + /// - 1: LL only + /// - 0: LL + host + /// - bit 1: + /// - 1: no service change desc. + /// - 0: with service change desc. + /// - bit 2: + /// - 1: device name Read-Only + /// - 0: device name R/W + /// - bit 3: + /// - 1: extended advertizing supported + /// - 0: extended advertizing not supported + /// - bit 4: + /// - 1: CS Algo #2 supported + /// - 0: CS Algo #2 not supported + /// - bit 5: + /// - 1: Reduced GATT database in NVM + /// - 0: Full GATT database in NVM + /// - bit 6: + /// - 1: GATT caching is used + /// - 0: GATT caching is not used + /// - bit 7: + /// - 1: LE Power Class 1 + /// - 0: LE Power Classe 2-3 + /// - other bits: complete with Options_extension flag + pub options: u8, + /// Reserved for future use - shall be set to 0 pub hw_version: u8, + // /** + // * Maximum number of connection-oriented channels in initiator mode. + // * Range: 0 .. 64 + // */ + // pub max_coc_initiator_nbr: u8, + // + // /** + // * Minimum transmit power in dBm supported by the Controller. + // * Range: -127 .. 20 + // */ + // pub min_tx_power: i8, + // + // /** + // * Maximum transmit power in dBm supported by the Controller. + // * Range: -127 .. 20 + // */ + // pub max_tx_power: i8, + // + // /** + // * RX model configuration + // * - bit 0: 1: agc_rssi model improved vs RF blockers 0: Legacy agc_rssi model + // * - other bits: reserved ( shall be set to 0) + // */ + // pub rx_model_config: u8, + // + // /* Maximum number of advertising sets. + // * Range: 1 .. 8 with limitation: + // * This parameter is linked to max_adv_data_len such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based + // * on Max Extended advertising configuration supported. + // * This parameter is considered by the CPU2 when Options has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set + // */ + // pub max_adv_set_nbr: u8, + // + // /* Maximum advertising data length (in bytes) + // * Range: 31 .. 1650 with limitation: + // * This parameter is linked to max_adv_set_nbr such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based + // * on Max Extended advertising configuration supported. + // * This parameter is considered by the CPU2 when Options has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set + // */ + // pub max_adv_data_len: u16, + // + // /* RF TX Path Compensation Value (16-bit signed integer). Units: 0.1 dB. + // * Range: -1280 .. 1280 + // */ + // pub tx_path_compens: i16, + // + // /* RF RX Path Compensation Value (16-bit signed integer). Units: 0.1 dB. + // * Range: -1280 .. 1280 + // */ + // pub rx_path_compens: i16, + // + // /* BLE core specification version (8-bit unsigned integer). + // * values as: 11(5.2), 12(5.3) + // */ + // pub ble_core_version: u8, + // + // /** + // * Options flags extension + // * - bit 0: 1: appearance Writable 0: appearance Read-Only + // * - bit 1: 1: Enhanced ATT supported 0: Enhanced ATT not supported + // * - other bits: reserved ( shall be set to 0) + // */ + // pub options_extension: u8, } impl ShciBleInitCmdParam { - pub fn payload<'a>(&self) -> &'a [u8] { + pub fn payload<'a>(&'a self) -> &'a [u8] { unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::()) } } } @@ -48,8 +355,8 @@ impl Default for ShciBleInitCmdParam { attr_value_arr_size: 1344, num_of_links: 2, extended_packet_length_enable: 1, - pr_write_list_size: 0x3A, - mb_lock_count: 0x79, + prepare_write_list_size: 0x3A, + block_count: 0x79, att_mtu: 156, slave_sca: 500, master_sca: 0, @@ -57,25 +364,12 @@ impl Default for ShciBleInitCmdParam { max_conn_event_length: 0xFFFFFFFF, hs_startup_time: 0x148, viterbi_enable: 1, - ll_only: 0, + options: 0, hw_version: 0, } } } -#[derive(Debug, Clone, Copy, Default)] -#[repr(C, packed)] -pub struct ShciHeader { - metadata: [u32; 3], -} - -#[derive(Debug, Clone, Copy)] -#[repr(C, packed)] -pub struct ShciBleInitCmdPacket { - pub header: ShciHeader, - pub param: ShciBleInitCmdParam, -} - pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; #[allow(dead_code)] // Not used currently but reserved const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs index a185cd4f1..5fe09a20f 100644 --- a/embassy-stm32-wpan/src/sys.rs +++ b/embassy-stm32-wpan/src/sys.rs @@ -1,9 +1,10 @@ use core::marker::PhantomData; +use core::ptr; use crate::cmd::CmdPacket; use crate::consts::TlPacketType; -use crate::evt::EvtBox; -use crate::shci::{ShciBleInitCmdParam, SCHI_OPCODE_BLE_INIT}; +use crate::evt::{CcEvt, EvtBox, EvtPacket}; +use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; use crate::tables::{SysTable, WirelessFwInfoTable}; use crate::unsafe_linked_list::LinkedListNode; use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; @@ -39,21 +40,29 @@ impl Sys { } } - pub fn write(&self, opcode: u16, payload: &[u8]) { + pub async fn write(&self, opcode: ShciOpcode, payload: &[u8]) { + Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || unsafe { + CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload); + }) + .await; + } + + /// `HW_IPCC_SYS_CmdEvtNot` + pub async fn write_and_get_response(&self, opcode: ShciOpcode, payload: &[u8]) -> SchiCommandStatus { + self.write(opcode, payload).await; + Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; + unsafe { - CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode, payload); + let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket; + let p_command_event = &((*p_event_packet).evt_serial.evt.payload) as *const _ as *const CcEvt; + let p_payload = &((*p_command_event).payload) as *const u8; + + ptr::read_volatile(p_payload).try_into().unwrap() } } - pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) { - debug!("sending SHCI"); - - Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || { - self.write(SCHI_OPCODE_BLE_INIT, param.payload()); - }) - .await; - - Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; + pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> SchiCommandStatus { + self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await } /// `HW_IPCC_SYS_EvtNot` diff --git a/tests/stm32/src/bin/tl_mbox.rs b/tests/stm32/src/bin/tl_mbox.rs index f6641ae31..f47a89b6f 100644 --- a/tests/stm32/src/bin/tl_mbox.rs +++ b/tests/stm32/src/bin/tl_mbox.rs @@ -39,7 +39,7 @@ async fn main(spawner: Spawner) { 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!("sys event {:x} : {:x}", ready_event.stub().kind, ready_event.payload()); // test memory manager mem::drop(ready_event); @@ -59,7 +59,8 @@ async fn main(spawner: Spawner) { Timer::after(Duration::from_millis(50)).await; - mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; + let result = mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; + info!("subsystem initialization: {}", result); info!("starting ble..."); mbox.ble_subsystem.write(0x0c, &[]).await; @@ -67,9 +68,8 @@ async fn main(spawner: Spawner) { info!("waiting for ble..."); let ble_event = mbox.ble_subsystem.read().await; - info!("ble event: {}", ble_event.payload()); + info!("ble event {:x} : {:x}", ble_event.stub().kind, ble_event.payload()); - Timer::after(Duration::from_millis(150)).await; info!("Test OK"); cortex_m::asm::bkpt(); } From 39334f72804ad83c90cde53d328be779af9f1b92 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 09:43:07 -0500 Subject: [PATCH 2/9] stm32/wpan: add ble, mac features and cleanup --- embassy-stm32-wpan/Cargo.toml | 3 +++ embassy-stm32-wpan/src/lib.rs | 37 +++-------------------------------- tests/stm32/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 1c1b57b36..f9023ed79 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -27,6 +27,9 @@ bit_field = "0.10.2" [features] defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"] +ble = [] +mac = [] + stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ] stm32wb15cc = [ "embassy-stm32/stm32wb15cc" ] stm32wb30ce = [ "embassy-stm32/stm32wb30ce" ] diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index 833db0df3..035b130c8 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -10,13 +10,8 @@ use ble::Ble; use cmd::CmdPacket; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_stm32::interrupt; -use embassy_stm32::interrupt::typelevel::Interrupt; use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::peripherals::IPCC; -use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; -use embassy_sync::channel::Channel; -use embassy_sync::signal::Signal; -use evt::{CcEvt, EvtBox}; use mm::MemoryManager; use sys::Sys; use tables::{ @@ -129,19 +124,6 @@ static mut BLE_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); // fuck these "magic" numbers from ST ---v---v static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); -// TODO: remove these items - -#[allow(dead_code)] -/// current event that is produced during IPCC IRQ handler execution -/// on SYS channel -static EVT_CHANNEL: Channel = Channel::new(); - -#[allow(dead_code)] -/// last received Command Complete event -static LAST_CC_EVT: Signal = Signal::new(); - -static STATE: Signal = Signal::new(); - pub struct TlMbox<'d> { _ipcc: PeripheralRef<'d, IPCC>, @@ -232,24 +214,11 @@ impl<'d> TlMbox<'d> { Ipcc::enable(config); - let sys = sys::Sys::new(); - let ble = ble::Ble::new(); - let mm = mm::MemoryManager::new(); - - // enable interrupts - interrupt::typelevel::IPCC_C1_RX::unpend(); - interrupt::typelevel::IPCC_C1_TX::unpend(); - - unsafe { interrupt::typelevel::IPCC_C1_RX::enable() }; - unsafe { interrupt::typelevel::IPCC_C1_TX::enable() }; - - STATE.reset(); - Self { _ipcc: ipcc, - sys_subsystem: sys, - ble_subsystem: ble, - mm_subsystem: mm, + sys_subsystem: sys::Sys::new(), + ble_subsystem: ble::Ble::new(), + mm_subsystem: mm::MemoryManager::new(), } } } diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 487ef4626..539ee265f 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -29,7 +29,7 @@ embassy-executor = { version = "0.2.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "tick-hz-32_768", "defmt-timestamp-uptime"] } embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } -embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg"] } +embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } defmt = "0.3.0" defmt-rtt = "0.4" From 748d1ea89da160df927ea3dd597704ba236e0fb6 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 10:10:05 -0500 Subject: [PATCH 3/9] stm32/ipcc: minor cleanup --- embassy-stm32/src/ipcc.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 609c4d2c3..f481a5955 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -122,7 +122,6 @@ impl Ipcc { let regs = IPCC::regs(); Self::flush(channel).await; - compiler_fence(Ordering::SeqCst); f(); @@ -138,7 +137,7 @@ impl Ipcc { // This is a race, but is nice for debugging if unsafe { regs.cpu(0).sr().read() }.chf(channel as usize) { - trace!("ipcc: ch {}: wait for tx free", channel as u8); + trace!("ipcc: ch {}: wait for tx free", channel as u8); } poll_fn(|cx| { @@ -167,7 +166,7 @@ impl Ipcc { loop { // This is a race, but is nice for debugging if !unsafe { regs.cpu(1).sr().read() }.chf(channel as usize) { - trace!("ipcc: ch {}: wait for rx occupied", channel as u8); + trace!("ipcc: ch {}: wait for rx occupied", channel as u8); } poll_fn(|cx| { @@ -188,8 +187,7 @@ impl Ipcc { }) .await; - trace!("ipcc: ch {}: read data", channel as u8); - compiler_fence(Ordering::SeqCst); + trace!("ipcc: ch {}: read data", channel as u8); match f() { Some(ret) => return ret, @@ -239,7 +237,7 @@ pub(crate) mod sealed { } } - pub fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { + pub const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { match channel { IpccChannel::Channel1 => &self.rx_wakers[0], IpccChannel::Channel2 => &self.rx_wakers[1], @@ -250,7 +248,7 @@ pub(crate) mod sealed { } } - pub fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { + pub const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { match channel { IpccChannel::Channel1 => &self.tx_wakers[0], IpccChannel::Channel2 => &self.tx_wakers[1], From 9f63158aad81486b4bd0ffe6f8d7103458ba360f Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 10:11:36 -0500 Subject: [PATCH 4/9] stm32/wpan: reorg modules --- embassy-stm32-wpan/src/consts.rs | 34 +++++++++++ embassy-stm32-wpan/src/lib.rs | 97 +------------------------------- embassy-stm32-wpan/src/mm.rs | 13 +++-- embassy-stm32-wpan/src/shci.rs | 2 +- embassy-stm32-wpan/src/tables.rs | 77 +++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 103 deletions(-) diff --git a/embassy-stm32-wpan/src/consts.rs b/embassy-stm32-wpan/src/consts.rs index caf26c06b..9a107306c 100644 --- a/embassy-stm32-wpan/src/consts.rs +++ b/embassy-stm32-wpan/src/consts.rs @@ -1,5 +1,8 @@ use core::convert::TryFrom; +use crate::evt::CsEvt; +use crate::PacketHeader; + #[derive(Debug)] #[repr(C)] pub enum TlPacketType { @@ -53,3 +56,34 @@ impl TryFrom for TlPacketType { } } } + +pub const TL_PACKET_HEADER_SIZE: usize = core::mem::size_of::(); +pub const TL_EVT_HEADER_SIZE: usize = 3; +pub const TL_CS_EVT_SIZE: usize = core::mem::size_of::(); + +/** + * Queue length of BLE Event + * This parameter defines the number of asynchronous events that can be stored in the HCI layer before + * being reported to the application. When a command is sent to the BLE core coprocessor, the HCI layer + * is waiting for the event with the Num_HCI_Command_Packets set to 1. The receive queue shall be large + * enough to store all asynchronous events received in between. + * When CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE is set to 27, this allow to store three 255 bytes long asynchronous events + * between the HCI command and its event. + * This parameter depends on the value given to CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE. When the queue size is to small, + * the system may hang if the queue is full with asynchronous events and the HCI layer is still waiting + * for a CC/CS event, In that case, the notification TL_BLE_HCI_ToNot() is called to indicate + * to the application a HCI command did not receive its command event within 30s (Default HCI Timeout). + */ +pub const CFG_TL_BLE_EVT_QUEUE_LENGTH: usize = 5; +pub const CFG_TL_BLE_MOST_EVENT_PAYLOAD_SIZE: usize = 255; +pub const TL_BLE_EVENT_FRAME_SIZE: usize = TL_EVT_HEADER_SIZE + CFG_TL_BLE_MOST_EVENT_PAYLOAD_SIZE; + +pub const POOL_SIZE: usize = CFG_TL_BLE_EVT_QUEUE_LENGTH * 4 * divc(TL_PACKET_HEADER_SIZE + TL_BLE_EVENT_FRAME_SIZE, 4); + +pub const fn divc(x: usize, y: usize) -> usize { + (x + y - 1) / y +} + +pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; +#[allow(dead_code)] +pub const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index 035b130c8..1ddb3f2e0 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -7,16 +7,13 @@ use core::mem::MaybeUninit; use core::sync::atomic::{compiler_fence, Ordering}; use ble::Ble; -use cmd::CmdPacket; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_stm32::interrupt; use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::peripherals::IPCC; use mm::MemoryManager; use sys::Sys; -use tables::{ - BleTable, DeviceInfoTable, Mac802_15_4Table, MemManagerTable, RefTable, SysTable, ThreadTable, TracesTable, -}; +use tables::*; use unsafe_linked_list::LinkedListNode; pub mod ble; @@ -30,100 +27,8 @@ pub mod sys; pub mod tables; pub mod unsafe_linked_list; -#[link_section = "TL_REF_TABLE"] -pub static mut TL_REF_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_DEVICE_INFO_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_BLE_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_THREAD_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_SYS_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_MEM_MANAGER_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_TRACES_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM1"] -static mut TL_MAC_802_15_4_TABLE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -static mut FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); - -// Not in shared RAM -static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); - -#[allow(dead_code)] // Not used currently but reserved -#[link_section = "MB_MEM2"] -static mut TRACES_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); - type PacketHeader = LinkedListNode; -const TL_PACKET_HEADER_SIZE: usize = core::mem::size_of::(); -const TL_EVT_HEADER_SIZE: usize = 3; -const TL_CS_EVT_SIZE: usize = core::mem::size_of::(); - -#[link_section = "MB_MEM2"] -static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = - MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -pub static mut SYS_CMD_BUF: MaybeUninit = MaybeUninit::uninit(); - -/** - * Queue length of BLE Event - * This parameter defines the number of asynchronous events that can be stored in the HCI layer before - * being reported to the application. When a command is sent to the BLE core coprocessor, the HCI layer - * is waiting for the event with the Num_HCI_Command_Packets set to 1. The receive queue shall be large - * enough to store all asynchronous events received in between. - * When CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE is set to 27, this allow to store three 255 bytes long asynchronous events - * between the HCI command and its event. - * This parameter depends on the value given to CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE. When the queue size is to small, - * the system may hang if the queue is full with asynchronous events and the HCI layer is still waiting - * for a CC/CS event, In that case, the notification TL_BLE_HCI_ToNot() is called to indicate - * to the application a HCI command did not receive its command event within 30s (Default HCI Timeout). - */ -const CFG_TLBLE_EVT_QUEUE_LENGTH: usize = 5; -const CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE: usize = 255; -const TL_BLE_EVENT_FRAME_SIZE: usize = TL_EVT_HEADER_SIZE + CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE; - -const fn divc(x: usize, y: usize) -> usize { - ((x) + (y) - 1) / (y) -} - -const POOL_SIZE: usize = CFG_TLBLE_EVT_QUEUE_LENGTH * 4 * divc(TL_PACKET_HEADER_SIZE + TL_BLE_EVENT_FRAME_SIZE, 4); - -#[link_section = "MB_MEM2"] -static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = - MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = - MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -static mut BLE_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); - -#[link_section = "MB_MEM2"] -// fuck these "magic" numbers from ST ---v---v -static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); - pub struct TlMbox<'d> { _ipcc: PeripheralRef<'d, IPCC>, diff --git a/embassy-stm32-wpan/src/mm.rs b/embassy-stm32-wpan/src/mm.rs index 21f42409a..dc499c1e7 100644 --- a/embassy-stm32-wpan/src/mm.rs +++ b/embassy-stm32-wpan/src/mm.rs @@ -1,22 +1,23 @@ //! Memory manager routines - use core::future::poll_fn; use core::marker::PhantomData; +use core::mem::MaybeUninit; use core::task::Poll; use cortex_m::interrupt; use embassy_stm32::ipcc::Ipcc; use embassy_sync::waitqueue::AtomicWaker; +use crate::channels; +use crate::consts::POOL_SIZE; use crate::evt::EvtPacket; -use crate::tables::MemManagerTable; -use crate::unsafe_linked_list::LinkedListNode; -use crate::{ - channels, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF, - TL_MEM_MANAGER_TABLE, +use crate::tables::{ + MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, }; +use crate::unsafe_linked_list::LinkedListNode; static MM_WAKER: AtomicWaker = AtomicWaker::new(); +static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); pub struct MemoryManager { phantom: PhantomData, diff --git a/embassy-stm32-wpan/src/shci.rs b/embassy-stm32-wpan/src/shci.rs index f4e9ba84c..b60158b1b 100644 --- a/embassy-stm32-wpan/src/shci.rs +++ b/embassy-stm32-wpan/src/shci.rs @@ -1,6 +1,6 @@ use core::{mem, slice}; -use super::{TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE}; +use crate::consts::{TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE}; const SHCI_OGF: u16 = 0x3F; diff --git a/embassy-stm32-wpan/src/tables.rs b/embassy-stm32-wpan/src/tables.rs index 151216958..81873b147 100644 --- a/embassy-stm32-wpan/src/tables.rs +++ b/embassy-stm32-wpan/src/tables.rs @@ -1,6 +1,9 @@ +use core::mem::MaybeUninit; + use bit_field::BitField; use crate::cmd::{AclDataPacket, CmdPacket}; +use crate::consts::{POOL_SIZE, TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE}; use crate::unsafe_linked_list::LinkedListNode; #[derive(Debug, Copy, Clone)] @@ -173,3 +176,77 @@ pub struct RefTable { pub traces_table: *const TracesTable, pub mac_802_15_4_table: *const Mac802_15_4Table, } + +// --------------------- ref table --------------------- +#[link_section = "TL_REF_TABLE"] +pub static mut TL_REF_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_DEVICE_INFO_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_BLE_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_THREAD_TABLE: MaybeUninit = MaybeUninit::uninit(); + +// #[link_section = "MB_MEM1"] +// pub static mut TL_LLD_TESTS_TABLE: MaybeUninit = MaybeUninit::uninit(); + +// #[link_section = "MB_MEM1"] +// pub static mut TL_BLE_LLD_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_SYS_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_MEM_MANAGER_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_TRACES_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut TL_MAC_802_15_4_TABLE: MaybeUninit = MaybeUninit::uninit(); + +// #[link_section = "MB_MEM1"] +// pub static mut TL_ZIGBEE_TABLE: MaybeUninit = MaybeUninit::uninit(); + +// --------------------- tables --------------------- +#[link_section = "MB_MEM1"] +pub static mut FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); + +#[allow(dead_code)] +#[link_section = "MB_MEM1"] +pub static mut TRACES_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +pub static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = + MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +pub static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +pub static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); + +// --------------------- app tables --------------------- +#[link_section = "MB_MEM2"] +pub static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +pub static mut SYS_CMD_BUF: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +pub static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = + MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +pub static mut BLE_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +pub static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = + MaybeUninit::uninit(); + +#[link_section = "MB_MEM2"] +// fuck these "magic" numbers from ST ---v---v +pub static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); From b95c0210b83d0742fa4663b2726e4e7b82a4e068 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 18:51:14 -0500 Subject: [PATCH 5/9] stm32/wpan: add draft mac mbox --- embassy-stm32-wpan/src/ble.rs | 4 +- embassy-stm32-wpan/src/evt.rs | 15 ++- embassy-stm32-wpan/src/lib.rs | 12 +- embassy-stm32-wpan/src/mac.rs | 109 ++++++++++++++++++ embassy-stm32-wpan/src/mm.rs | 3 +- embassy-stm32-wpan/src/tables.rs | 9 ++ examples/stm32wb/Cargo.toml | 14 +++ .../bin/{tl_mbox_tx_rx.rs => tl_mbox_ble.rs} | 0 examples/stm32wb/src/bin/tl_mbox_mac.rs | 64 ++++++++++ 9 files changed, 223 insertions(+), 7 deletions(-) create mode 100644 embassy-stm32-wpan/src/mac.rs rename examples/stm32wb/src/bin/{tl_mbox_tx_rx.rs => tl_mbox_ble.rs} (100%) create mode 100644 examples/stm32wb/src/bin/tl_mbox_mac.rs diff --git a/embassy-stm32-wpan/src/ble.rs b/embassy-stm32-wpan/src/ble.rs index f0bd6f48c..60e0cbdf8 100644 --- a/embassy-stm32-wpan/src/ble.rs +++ b/embassy-stm32-wpan/src/ble.rs @@ -2,12 +2,12 @@ use core::marker::PhantomData; use embassy_stm32::ipcc::Ipcc; +use crate::channels; use crate::cmd::CmdPacket; use crate::consts::TlPacketType; use crate::evt::EvtBox; -use crate::tables::BleTable; +use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; use crate::unsafe_linked_list::LinkedListNode; -use crate::{channels, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; pub struct Ble { phantom: PhantomData, diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs index a7b99e540..ee108ec88 100644 --- a/embassy-stm32-wpan/src/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs @@ -1,7 +1,6 @@ use core::{ptr, slice}; use super::PacketHeader; -use crate::mm; /** * The payload of `Evt` for a command status event @@ -129,6 +128,18 @@ impl EvtBox { impl Drop for EvtBox { fn drop(&mut self) { - unsafe { mm::MemoryManager::drop_event_packet(self.ptr) }; + #[cfg(feature = "ble")] + unsafe { + use crate::mm; + + mm::MemoryManager::drop_event_packet(self.ptr) + }; + + #[cfg(feature = "mac")] + unsafe { + use crate::mac; + + mac::Mac::drop_event_packet(self.ptr) + } } } diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index 1ddb3f2e0..5aec9933c 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -6,7 +6,6 @@ pub mod fmt; use core::mem::MaybeUninit; use core::sync::atomic::{compiler_fence, Ordering}; -use ble::Ble; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_stm32::interrupt; use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; @@ -16,11 +15,14 @@ use sys::Sys; use tables::*; use unsafe_linked_list::LinkedListNode; +#[cfg(feature = "ble")] pub mod ble; pub mod channels; pub mod cmd; pub mod consts; pub mod evt; +#[cfg(feature = "mac")] +pub mod mac; pub mod mm; pub mod shci; pub mod sys; @@ -34,7 +36,10 @@ pub struct TlMbox<'d> { pub sys_subsystem: Sys, pub mm_subsystem: MemoryManager, - pub ble_subsystem: Ble, + #[cfg(feature = "ble")] + pub ble_subsystem: ble::Ble, + #[cfg(feature = "mac")] + pub mac_subsystem: mac::Mac, } impl<'d> TlMbox<'d> { @@ -122,7 +127,10 @@ impl<'d> TlMbox<'d> { Self { _ipcc: ipcc, sys_subsystem: sys::Sys::new(), + #[cfg(feature = "ble")] ble_subsystem: ble::Ble::new(), + #[cfg(feature = "mac")] + mac_subsystem: mac::Mac::new(), mm_subsystem: mm::MemoryManager::new(), } } diff --git a/embassy-stm32-wpan/src/mac.rs b/embassy-stm32-wpan/src/mac.rs new file mode 100644 index 000000000..9fbf37473 --- /dev/null +++ b/embassy-stm32-wpan/src/mac.rs @@ -0,0 +1,109 @@ +use core::future::poll_fn; +use core::marker::PhantomData; +use core::ptr; +use core::sync::atomic::{AtomicBool, Ordering}; +use core::task::Poll; + +use embassy_futures::poll_once; +use embassy_stm32::ipcc::Ipcc; +use embassy_sync::waitqueue::AtomicWaker; + +use crate::cmd::CmdPacket; +use crate::consts::TlPacketType; +use crate::evt::{EvtBox, EvtPacket}; +use crate::tables::{ + Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE, +}; +use crate::unsafe_linked_list::LinkedListNode; +use crate::{channels, EVT_QUEUE}; + +static MAC_WAKER: AtomicWaker = AtomicWaker::new(); +static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); + +pub struct Mac { + phantom: PhantomData, +} + +impl Mac { + pub(crate) fn new() -> Self { + unsafe { + LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); + + TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table { + p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(), + p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(), + evt_queue: ptr::null_mut(), + }); + } + + Self { phantom: PhantomData } + } + + /// SAFETY: passing a pointer to something other than a managed event packet is UB + pub(crate) unsafe fn drop_event_packet(_: *mut EvtPacket) { + // Write the ack + CmdPacket::write_into(MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), TlPacketType::OtAck, 0, &[]); + + // Clear the rx flag + let _ = poll_once(Ipcc::receive::( + channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, + || None, + )); + + // Allow a new read call + MAC_EVT_OUT.store(false, Ordering::SeqCst); + MAC_WAKER.wake(); + } + + /// `HW_IPCC_MAC_802_15_4_EvtNot` + /// + /// This function will stall if the previous `EvtBox` has not been dropped + pub async fn read(&self) -> EvtBox { + // Wait for the last event box to be dropped + poll_fn(|cx| { + MAC_WAKER.register(cx.waker()); + if MAC_EVT_OUT.load(Ordering::SeqCst) { + Poll::Pending + } else { + Poll::Ready(()) + } + }) + .await; + + // Return a new event box + Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe { + // The closure is not async, therefore the closure must execute to completion (cannot be dropped) + // Therefore, the event box is guaranteed to be cleaned up if it's not leaked + MAC_EVT_OUT.store(true, Ordering::SeqCst); + + Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _)) + }) + .await + } + + /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` + pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { + self.write(opcode, payload).await; + Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; + + unsafe { + let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; + let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; + + ptr::read_volatile(p_mac_rsp_evt) + } + } + + /// `TL_MAC_802_15_4_SendCmd` + pub async fn write(&self, opcode: u16, payload: &[u8]) { + Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { + CmdPacket::write_into( + MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), + TlPacketType::OtCmd, + opcode, + payload, + ); + }) + .await; + } +} diff --git a/embassy-stm32-wpan/src/mm.rs b/embassy-stm32-wpan/src/mm.rs index dc499c1e7..047fddcd4 100644 --- a/embassy-stm32-wpan/src/mm.rs +++ b/embassy-stm32-wpan/src/mm.rs @@ -43,7 +43,8 @@ impl MemoryManager { Self { phantom: PhantomData } } - /// SAFETY: passing a pointer to something other than an event packet is UB + #[allow(dead_code)] + /// SAFETY: passing a pointer to something other than a managed event packet is UB pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) { interrupt::free(|_| unsafe { LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); diff --git a/embassy-stm32-wpan/src/tables.rs b/embassy-stm32-wpan/src/tables.rs index 81873b147..2064910f0 100644 --- a/embassy-stm32-wpan/src/tables.rs +++ b/embassy-stm32-wpan/src/tables.rs @@ -230,6 +230,15 @@ pub static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); pub static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); // --------------------- app tables --------------------- +#[cfg(feature = "mac")] +#[link_section = "MB_MEM2"] +pub static mut MAC_802_15_4_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); + +#[cfg(feature = "mac")] +#[link_section = "MB_MEM2"] +pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = + MaybeUninit::uninit(); + #[link_section = "MB_MEM2"] pub static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 83a443754..e41424aad 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -20,3 +20,17 @@ embedded-hal = "0.2.6" panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } + + +[features] +default = ["ble"] +mac = ["embassy-stm32-wpan/mac"] +ble = ["embassy-stm32-wpan/ble"] + +[[bin]] +name = "tl_mbox_ble" +required-features = ["ble"] + +[[bin]] +name = "tl_mbox_mac" +required-features = ["mac"] \ No newline at end of file diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs similarity index 100% rename from examples/stm32wb/src/bin/tl_mbox_tx_rx.rs rename to examples/stm32wb/src/bin/tl_mbox_ble.rs diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs new file mode 100644 index 000000000..f13f260b5 --- /dev/null +++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs @@ -0,0 +1,64 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::bind_interrupts; +use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; +use embassy_stm32_wpan::TlMbox; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs{ + IPCC_C1_RX => ReceiveInterruptHandler; + IPCC_C1_TX => TransmitInterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + /* + How to make this work: + + - Obtain a NUCLEO-STM32WB55 from your preferred supplier. + - Download and Install STM32CubeProgrammer. + - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from + gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x + - Open STM32CubeProgrammer + - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. + - Once complete, click connect to connect to the device. + - On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services". + - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file + - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the + stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. + - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Select "Start Wireless Stack". + - Disconnect from the device. + - In the examples folder for stm32wb, modify the memory.x file to match your target device. + - Run this example. + + Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. + */ + + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let config = Config::default(); + let mbox = TlMbox::init(p.IPCC, Irqs, config); + + 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..."); +// mbox.ble_subsystem.write(0x0c, &[]).await; +// +// info!("waiting for ble..."); +// let ble_event = mbox.ble_subsystem.read().await; +// +// info!("ble event: {}", ble_event.payload()); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} From 72fd648d92738546b03166922defd4bee2d5fa9d Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 18:56:53 -0500 Subject: [PATCH 6/9] stm32/wpan: add shci mac init --- embassy-stm32-wpan/src/sys.rs | 6 ++++++ examples/stm32wb/src/bin/tl_mbox_mac.rs | 18 +++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs index 5fe09a20f..65a64e090 100644 --- a/embassy-stm32-wpan/src/sys.rs +++ b/embassy-stm32-wpan/src/sys.rs @@ -61,6 +61,12 @@ impl Sys { } } + #[cfg(feature = "mac")] + pub async fn shci_c2_mac_802_15_4_init(&self) -> SchiCommandStatus { + self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await + } + + #[cfg(feature = "ble")] pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> SchiCommandStatus { self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await } diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs index f13f260b5..a42939bbd 100644 --- a/examples/stm32wb/src/bin/tl_mbox_mac.rs +++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs @@ -49,15 +49,15 @@ async fn main(_spawner: Spawner) { 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..."); -// mbox.ble_subsystem.write(0x0c, &[]).await; -// -// info!("waiting for ble..."); -// let ble_event = mbox.ble_subsystem.read().await; -// -// info!("ble event: {}", ble_event.payload()); + mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; + // + // info!("starting ble..."); + // mbox.ble_subsystem.write(0x0c, &[]).await; + // + // info!("waiting for ble..."); + // let ble_event = mbox.ble_subsystem.read().await; + // + // info!("ble event: {}", ble_event.payload()); info!("Test OK"); cortex_m::asm::bkpt(); From 0122b813d3dfe90bad7d307f4f0c7adcbae0a7a5 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 18 Jun 2023 19:03:50 -0500 Subject: [PATCH 7/9] stm32/wpan: fix lifetime param --- embassy-stm32-wpan/src/shci.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32-wpan/src/shci.rs b/embassy-stm32-wpan/src/shci.rs index b60158b1b..30d689716 100644 --- a/embassy-stm32-wpan/src/shci.rs +++ b/embassy-stm32-wpan/src/shci.rs @@ -113,7 +113,7 @@ pub struct ShciConfigParam { } impl ShciConfigParam { - pub fn payload<'a>(&self) -> &'a [u8] { + pub fn payload<'a>(&'a self) -> &'a [u8] { unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of::()) } } } From 978e7b5e77f86dc82c393442702defa38b516f4b Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 19 Jun 2023 21:17:31 -0500 Subject: [PATCH 8/9] stm32/wpan: fix bugs --- embassy-stm32-wpan/src/evt.rs | 8 ++++---- embassy-stm32-wpan/src/mac.rs | 12 +++++++----- embassy-stm32-wpan/src/sys.rs | 1 + 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs index ee108ec88..47bdc49bf 100644 --- a/embassy-stm32-wpan/src/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs @@ -45,15 +45,15 @@ pub struct AsynchEvt { payload: [u8; 1], } -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone)] #[repr(C, packed)] pub struct Evt { pub evt_code: u8, pub payload_len: u8, - pub payload: [u8; 1], + pub payload: [u8; 255], } -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone)] #[repr(C, packed)] pub struct EvtSerial { pub kind: u8, @@ -75,7 +75,7 @@ pub struct EvtStub { /// Be careful that the asynchronous events reported by the CPU2 on the system channel do /// include the header and shall use `EvtPacket` format. Only the command response format on the /// system channel is different. -#[derive(Copy, Clone, Default)] +#[derive(Copy, Clone)] #[repr(C, packed)] pub struct EvtPacket { pub header: PacketHeader, diff --git a/embassy-stm32-wpan/src/mac.rs b/embassy-stm32-wpan/src/mac.rs index 9fbf37473..d2be1b85c 100644 --- a/embassy-stm32-wpan/src/mac.rs +++ b/embassy-stm32-wpan/src/mac.rs @@ -8,14 +8,13 @@ use embassy_futures::poll_once; use embassy_stm32::ipcc::Ipcc; use embassy_sync::waitqueue::AtomicWaker; +use crate::channels; use crate::cmd::CmdPacket; use crate::consts::TlPacketType; use crate::evt::{EvtBox, EvtPacket}; use crate::tables::{ Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE, }; -use crate::unsafe_linked_list::LinkedListNode; -use crate::{channels, EVT_QUEUE}; static MAC_WAKER: AtomicWaker = AtomicWaker::new(); static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); @@ -27,8 +26,6 @@ pub struct Mac { impl Mac { pub(crate) fn new() -> Self { unsafe { - LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); - TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table { p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(), p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(), @@ -42,7 +39,12 @@ impl Mac { /// SAFETY: passing a pointer to something other than a managed event packet is UB pub(crate) unsafe fn drop_event_packet(_: *mut EvtPacket) { // Write the ack - CmdPacket::write_into(MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), TlPacketType::OtAck, 0, &[]); + CmdPacket::write_into( + MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _, + TlPacketType::OtAck, + 0, + &[], + ); // Clear the rx flag let _ = poll_once(Ipcc::receive::( diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs index 65a64e090..2b699b725 100644 --- a/embassy-stm32-wpan/src/sys.rs +++ b/embassy-stm32-wpan/src/sys.rs @@ -4,6 +4,7 @@ use core::ptr; use crate::cmd::CmdPacket; use crate::consts::TlPacketType; use crate::evt::{CcEvt, EvtBox, EvtPacket}; +#[allow(unused_imports)] use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; use crate::tables::{SysTable, WirelessFwInfoTable}; use crate::unsafe_linked_list::LinkedListNode; From 5247c1c795a8b37be485aeeaa99a79eece678fba Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 21 Jun 2023 16:34:56 -0500 Subject: [PATCH 9/9] stm32/wpan: fix data alignment --- embassy-stm32-wpan/src/cmd.rs | 2 +- embassy-stm32-wpan/src/tables.rs | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/embassy-stm32-wpan/src/cmd.rs b/embassy-stm32-wpan/src/cmd.rs index edca82390..c8056aaa7 100644 --- a/embassy-stm32-wpan/src/cmd.rs +++ b/embassy-stm32-wpan/src/cmd.rs @@ -37,7 +37,7 @@ pub struct CmdSerialStub { } #[derive(Copy, Clone, Default)] -#[repr(C, packed)] +#[repr(C, packed(4))] pub struct CmdPacket { pub header: PacketHeader, pub cmdserial: CmdSerial, diff --git a/embassy-stm32-wpan/src/tables.rs b/embassy-stm32-wpan/src/tables.rs index 2064910f0..3f26282c6 100644 --- a/embassy-stm32-wpan/src/tables.rs +++ b/embassy-stm32-wpan/src/tables.rs @@ -164,6 +164,9 @@ pub struct Mac802_15_4Table { pub evt_queue: *const u8, } +#[repr(C, align(4))] +pub struct AlignedData([u8; L]); + /// Reference table. Contains pointers to all other tables. #[derive(Debug, Copy, Clone)] #[repr(C)] @@ -219,9 +222,10 @@ pub static mut FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit #[link_section = "MB_MEM1"] pub static mut TRACES_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); +const CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; + #[link_section = "MB_MEM2"] -pub static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = - MaybeUninit::uninit(); +pub static mut CS_BUFFER: MaybeUninit> = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] pub static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); @@ -234,9 +238,12 @@ pub static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::unin #[link_section = "MB_MEM2"] pub static mut MAC_802_15_4_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); +#[cfg(feature = "mac")] +const MAC_802_15_4_NOTIF_RSP_EVT_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255; + #[cfg(feature = "mac")] #[link_section = "MB_MEM2"] -pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = +pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit> = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] @@ -245,17 +252,21 @@ pub static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] pub static mut SYS_CMD_BUF: MaybeUninit = MaybeUninit::uninit(); +const SYS_SPARE_EVT_BUF_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255; + #[link_section = "MB_MEM2"] -pub static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = - MaybeUninit::uninit(); +pub static mut SYS_SPARE_EVT_BUF: MaybeUninit> = MaybeUninit::uninit(); #[link_section = "MB_MEM1"] pub static mut BLE_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); +const BLE_SPARE_EVT_BUF_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255; + #[link_section = "MB_MEM2"] -pub static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = - MaybeUninit::uninit(); +pub static mut BLE_SPARE_EVT_BUF: MaybeUninit> = MaybeUninit::uninit(); + +const HCI_ACL_DATA_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + 5 + 251; #[link_section = "MB_MEM2"] // fuck these "magic" numbers from ST ---v---v -pub static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); +pub static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; HCI_ACL_DATA_BUFFER_SIZE]> = MaybeUninit::uninit();