Dual‐Core operation - Francerigo/STM32WL55JC1_end_node GitHub Wiki
Dual Core Communication and LoRa Transmission Flow in STM32WL55JC1
This document explains the dual core implementation that relies on MBMUX for LoRa transmissions in the STM32WL55JC1. In this architecture, the CM4 core handles the application level—making it easy for user intervention—while the CM0+ core manages the LoRa stacks and radio drivers.
Core Roles and Communication
-
CM4 Core (Application Level):
- Runs user interface and high-level processing.
- When a transmission is needed, CM4 sends a command (Cmd) to CM0+.
- CM4 registers features for:
MBMUXIF_IsrLoraRespRcvCb(LoRa Response Callback)MBMUXIF_IsrLoraNotifRcvCb(LoRa Notification Callback)
-
CM0+ Core (LoRa/Radio Management):
- Runs the LoRa stack and radio drivers.
- When CM0+ receives a command from CM4, it triggers the callback
MBMUXIF_IsrLoraCmdRcvCb. - CM0+ registers features for:
MBMUXIF_IsrLoraAckRcvCb(LoRa Acknowledgement Callback)MBMUXIF_IsrLoraCmdRcvCb(LoRa Command Callback)
Refer to the en.STM32WL-System-Mailbox_Multiplexer_MBXMUX.pdf for further details on the command, response, notification, and acknowledgement processes.
Communication Flow Details
1. CM4 to CM0+ (Command and Acknowledgement)
- Command (Cmd):
- CM4 calls a function (e.g.,
LmHandlerSendinlora_app.c). - It sets the values to be sent in the shared buffer (initialized during MBMUX initialization).
- CM4 then calls
LmHandlerSend, which internally callsMBMUXIF_LoRaSendCmdto send a command to CM0+.
- CM4 calls a function (e.g.,
- On the CM0+ Side:
- The reception of a command triggers the callback
MBMUXIF_IsrLoraCmdRcvCb. - This callback:
- Assigns a pointer to an
MBMUX_ComParam_tobject (passed as a parameter) to a global variable (e.g.,LoraComObj). - Sets the execution of the task associated with the bitmask
CFG_SEQ_Task_MbLoRaCmdRcv.
- Assigns a pointer to an
- The task
MBMUXIF_TaskLoraCmdRcvis registered with the sequencer and, when executed, callsProcess_Lora_Cmd(LoraComObj).
- The reception of a command triggers the callback
2. Processing the Command (Process_Lora_Cmd)
- The function
Process_Lora_Cmd(LoraComObj)examines theMsgIdfield within theMBMUX_ComParam_tstructure (with various types defined inmsg_id.h). - A switch statement determines the operation to perform based on the command.
- For example, if
MsgIdequalsLMHANDLER_SEND_ID, this indicates that CM4 is requesting a LoRa transmission.
3. Transmission Request on CM0+
When LmHandlerSend is called (with LMHANDLER_SEND_ID):
- MAC Checks:
- The function calls
LoRaMacIsBusy(). If busy, it returnsLORAMAC_HANDLER_BUSY_ERROR. - It checks if the MAC is stopped via
LoRaMacIsStopped(). If true, it returnsLORAMAC_HANDLER_NO_NETWORK_JOINED. - It verifies join status using
LmHandlerJoinStatus(). If not joined, it callsLmHandlerJoin()and returnsLORAMAC_HANDLER_NO_NETWORK_JOINED.
- The function calls
- Transmission Setup:
- The transmission type is set (confirmed or unconfirmed) based on the input.
- Global parameters, such as data rate (
LmHandlerParams.TxDatarate), are updated.
- Payload Size Validation:
- The function calls
LoRaMacQueryTxPossible()with the payload size. - If the payload is too long, an empty frame is prepared to flush pending MAC commands, and the status is set to
LORAMAC_HANDLER_PAYLOAD_LENGTH_RESTRICTED.
- The function calls
- Requesting Transmission:
- Global transmission parameters (TxParams) are updated.
- The function calls
LoRaMacMcpsRequest(), passing the request structure and anallowDelayedTxflag. - A global variable (
DutyCycleWaitTime) is updated to enforce duty cycle restrictions.
- Mapping and Returning Status:
- The returned MAC status is mapped to a handler status (e.g.,
LORAMAC_HANDLER_SUCCESS,LORAMAC_HANDLER_BUSY_ERROR, etc.) and returned to CM4.
- The returned MAC status is mapped to a handler status (e.g.,
4. Radio Transmission Sequence on CM0+
- After the MCPS request is configured, the CM0+ core starts the hardware transmission.
- While transmitting, CM0+ is in an idle state.
- When the transmission completes, an interrupt is fired:
SUBGHZ_Radio_IRQHandleris invoked (instm32wlxx_it.c).- This calls
HAL_SUBGHZ_IRQHandler(instm32wlxx_hal_subghz.c), which in turn callsHAL_SUBGHZ_TxCpltCallback(inradio_driver.c). - The chain continues with
RadioOnDioIrqandRadioIrqProcess(inradio.c), eventually triggeringOnRadioTxDone.
- Following transmission, CM0+ may also enter an idle state or process reception in one or two Rx windows, triggering Rx callbacks if necessary.
5. CM4 Post-Transmission
- Waiting:
- While waiting for a response, CM4 calls
UTIL_SEQ_WaitEvt, entering an idle state while executing queued tasks.
- While waiting for a response, CM4 calls
- Response Handling:
- When CM0+ sends back a response, CM4’s interrupt fires, and it resumes from the waiting state.
- The event flags used by
UTIL_SEQ_WaitEvtare cleared, and CM4 continues processing.
- Additional Notifications:
- After sending the response, CM0+ might also send notifications for other events, which CM4 handles via the registered callback
MBMUXIF_IsrLoraNotifRcvCb.
- After sending the response, CM0+ might also send notifications for other events, which CM4 handles via the registered callback
Efficiency Considerations
- CM4 Core:
Continues with ADC acquisition and peak processing, running the application tasks. - CM0+ Core:
Manages the LoRa transmission independently. This separation allows the CM4 to perform measurement-related tasks without waiting for the radio transmission to complete.
Optimizing Power Consumption by Modifying Reception Windows
To optimize power consumption, the user can prevent the two RX windows from being activated. This document explains how the reception windows work and how you can modify the behavior to disable one or both windows while still allowing subsequent transmissions.
How Reception Windows Work
In LoRaWAN Class A, after each uplink transmission, the device opens two reception windows (RX1 and RX2) to listen for potential downlink messages:
- Reception Window Behavior:
- At the beginning of each RX window, a timer is enabled.
- The device listens during this period for any downlink packets.
- If a packet is received, the callback function
OnRadioRxDoneis called. - If no packet is received before the timer expires,
OnRadioRxTimeoutis triggered. - Both functions update the reception parameters and then call
OnMacProcessNotify.
Role of OnMacProcessNotify and LmHandlerProcess
-
OnMacProcessNotify:
- This function signals the MAC layer that a reception event (either a successful RX or a timeout) has occurred.
- It schedules the execution of the MAC processing routine in the sequencer.
-
LmHandlerProcess:
- Called by
OnMacProcessNotify,LmHandlerProcessdrives the LoRaMAC state machine. - It performs key operations such as:
- Calling
LoRaMacProcess()to handle internal MAC events. - Calling
LmHandlerPackagesProcess()to process package-specific features. - Checking if a package transmission is pending and, if so, exiting early.
- For certain LoRaMAC versions, handling a scheduled uplink by sending an empty frame if an uplink is pending.
- Calling
- Called by
This chain ensures that after a reception window ends, the MAC state is refreshed and ready for the next transmission.
Modifying Reception Windows to Save Power
-
Disabling RX Window 1:
- To prevent RX Window 1 from being activated, you can comment out the call to
RxWindowSetupin theOnRxWindow1TimerEventfunction in theLoRaMac.cfile. - This will completely avoid activating RX1.
- To prevent RX Window 1 from being activated, you can comment out the call to
-
Handling RX Window 2:
- Before the next transmission, it is necessary to update the reception parameters as done in
OnRxWindow2TimerEventto allow another transmission. - In particular, within
OnRxWindow2TimerEvent, you can mimic the behavior ofOnRadioRxTimeoutso that the timer is not started and a timeout is recognized immediately. - Once the timeout parameters have been set, calling
OnMacProcessNotifywill update the MAC parameters and refresh the system state, thereby enabling a new transmission.
- Before the next transmission, it is necessary to update the reception parameters as done in
LoRaMAC Notification and Acknowledgement Process
OnMacProcessNotify ensures that the LoRaMAC state machine (driven by LmHandlerProcess) processes pending events and resets for further operation. The overall process for handling downlink notifications and acknowledgements involves both cores and a series of function calls and callbacks, as described below.
Notification Flow from CM0+ to CM4
-
CM0+ Initiates Notification:
- CM0+ sends a notification to CM4 when ending reception window 2, as part of its transmission cycle.
- The notification flow follows this sequence:
LmHandlerProcess→LoRaMacProcess→LoRaMacHandleRequestEvents→McpsConfirm→OnTxData_mbwrapper→MBMUXIF_LoraSendNotif
MBMUXIF_LoraSendNotifthen callsMBMUX_NotificationSnd, which sends the notification to CM4, passing the parameterFEAT_INFO_LORAWAN_ID.
-
CM4 Receives the Notification:
- Upon receiving the notification, CM4 triggers the callback
MBMUXIF_IsLoraNotifRcvCbthrough the mailbox multiplexer. - This callback sets the execution of the function
Process_Lora_Notif.
- Upon receiving the notification, CM4 triggers the callback
-
Processing the Notification on CM4:
- Inside
Process_Lora_Notif, a switch-case statement checks the message ID. - When
MsgIdequals58, like after reception window 2, the caseLMHANDLER_ON_TX_DATA_CB_IDis selected. - In this case, the following occurs:
- The function pointer
callback_mbwrapper.OnTxDatais set to0x8001E01. - It is then called as follows:
callback_mbwrapper.OnTxData((LmHandlerTxParams_t *) com_buffer[0]); - This call enters the function
OnTxDatainlora_app.c, which:- Verifies that the parameters indicate an MCPS confirmation.
- Restarts the transmission timer.
- Finally, the response buffer is cleared and an acknowledgement is sent.
- The function pointer
- Inside
Acknowledgement Flow Back to CM0+
- While CM4 processes the notification, CM0+ is waiting for an acknowledgement.
- The acknowledgement sequence on CM0+ follows this chain:
IPCC_C2_RX_C2_TX_IRQHandler→HAL_IPCC_TX_IRQHandler→IpccIfIsrTxCb→MBMUX_IsrAcknowledgeRcvCb→MBMUXIF_IsrTraceAckRcvCb- Then,
UTIL_SEQ_SetEvtis called, which finishes the waiting for the acknowledgement. - Next,
UTIL_SEQ_SetTask(... CFG_SEQ_Task_MbTraceAckRcv)is executed, which schedules the taskMBMUXIF_TaskTraceAckRcv. - Finally, this leads to the calls:
TraceUtilCpltCallback(NULL)followed byTRACE_TxCpltCallback.
This sequence ensures that both cores remain synchronized during the transmission cycle, allowing the system to refresh its parameters and proceed with further transmissions.
In essence:
- The RX windows are normally used to listen for downlinks, but you can disable one to save power (commenting, in
LoRaMac.cunderOnRxWindow1TimerEvent, the line with theRxWindowSetupfunction). - You must still update the MAC state (via the timeout handling in RX2) so that the system is ready for the next transmission. To do that, substitute
RxWindowSetupwithOnRadioRxTimeout(inLoRaMac.cunderOnRxWindow2TimerEvent).
Conclusion
This dual core architecture leverages MBMUX to facilitate efficient communication between the CM4 and CM0+ cores. CM4 handles high-level application functions and data processing while CM0+ manages the time-critical LoRa transmission. This division of tasks improves system responsiveness and ensures that radio operations do not interrupt or delay application-level processing.
An issue is that the CM4 core is re-enabling the comparator interrupt—which triggers ADC acquisitions—before the CM0+ core has received and processed the final acknowledgement. As a result, CM4 resumes ADC operations while the CM0+ is still waiting for that ACK, leading to a timing conflict. Instead of re-enabling the comparator interrupt immediately after transmission of the ack (inside Process_Lora_Notif), the user can add a controlled delay (using a non-blocking timer or waiting for a specific event) on CM4. This ensures that the ACK is fully processed by CM0+ before ADC acquisitions resume. The code in this github repository uses a 100 ms delay after Process_Lora_Notif, before reenabling the comparator interrupt. This delay allows the CM0+ to receive and process the ack.
When using low power you first enable low power in both sys_conf in both cores ( and also reset the DEBUGGER_ENABLED flag) Then you need to go to stm32_lpm_if.c and, when exiting stopMode, reinitialize the ADC in CM4. Use MX_ADC_Init and not HAL_ADC_Init, because the stop2 mode clears some registers that need to be restored.