Skip to main content
Dominik Lorych
Associate III
December 20, 2021
Solved

STM32WB55: Interaction with FUS

Hi,

I am trying to get the FUS to work with a minimal bootloader, without Interrupts. But even with Interrupts I did not manage to get it working yet. Is there a simple approach to implementing it without needing any of the BT code? I only want to be able to save, load and lock keys.

I tried to re-use parts of STM32WPAN (IPCC from CubeMX, combined with SHCI) and the SBSFU (IPCC & TL Initialization, SHCI) to get the desired functionality, but so far i did not manage to do it.

Is there some better way to do this?

This topic has been closed for replies.
Dominik Lorych
Dominik LorychBest answer
Associate III
January 6, 2022

I now have figured out how to initialize the Mailbox and CPU2 manually. For anyone else wondering, this is the rudimentary way:

//initialize Mailbox
uint8_t* devInfoTable = (uint8_t*) 0x20030024;
uint32_t* systemTable = (uint32_t*) (0x20030024 + 52); //device info table is 50 bytes, plus 2 bytes for alignment
uint32_t* pMailbox = (uint32_t*) 0x20030000;
*pMailbox = (uint32_t) devInfoTable;
*(pMailbox + 3) = (uint32_t) systemTable; //pointer to system table gets written to pMailbox + 12 bytes
//boot CPU2
SET_BIT(PWR->CR4, PWR_CR4_C2BOOT);
 
HAL_Delay(200);
uint8_t* systemCommand = (uint8_t *) (systemTable + 2);
//write FUS_GET_STATE command to buffer just after system table
*systemCommand = 0x10;
*(systemCommand+1) = 0xFC;
*(systemCommand+2) = 0x52;
*(systemCommand+3) = 0;
//write pointer to system command buffer into system table
*systemTable = (uint32_t) systemCommand;
//Check if TX channel is free
if (HAL_IPCC_GetChannelStatus(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) {
 Error_handler();
}
 
//Notify CPU2
HAL_StatusTypeDef status = HAL_IPCC_NotifyCPU(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_TX);
if (status != HAL_OK) {
 Error_handler();
}
 
int i = 0;
//wait until CPU2 releaes the TX channel to acknowledge the command
while (HAL_IPCC_GetChannelStatus(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_TX) != IPCC_CHANNEL_STATUS_FREE) {
 i++;
 HAL_Delay(200);
}
 
//wait till CPU2 notifies CPU1 via RX channel
while (HAL_IPCC_GetChannelStatus(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX) != IPCC_CHANNEL_STATUS_OCCUPIED) {
 i++;
 HAL_Delay(200);
}
 
//clear notification from RX channel
status = HAL_IPCC_NotifyCPU(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX);
if (status != HAL_OK) {
 Error_handler();
}

3 replies

Dominik Lorych
Associate III
January 4, 2022

Bump to the top after the holidays :)

Dominik Lorych
Dominik LorychAuthorBest answer
Associate III
January 6, 2022

I now have figured out how to initialize the Mailbox and CPU2 manually. For anyone else wondering, this is the rudimentary way:

//initialize Mailbox
uint8_t* devInfoTable = (uint8_t*) 0x20030024;
uint32_t* systemTable = (uint32_t*) (0x20030024 + 52); //device info table is 50 bytes, plus 2 bytes for alignment
uint32_t* pMailbox = (uint32_t*) 0x20030000;
*pMailbox = (uint32_t) devInfoTable;
*(pMailbox + 3) = (uint32_t) systemTable; //pointer to system table gets written to pMailbox + 12 bytes
//boot CPU2
SET_BIT(PWR->CR4, PWR_CR4_C2BOOT);
 
HAL_Delay(200);
uint8_t* systemCommand = (uint8_t *) (systemTable + 2);
//write FUS_GET_STATE command to buffer just after system table
*systemCommand = 0x10;
*(systemCommand+1) = 0xFC;
*(systemCommand+2) = 0x52;
*(systemCommand+3) = 0;
//write pointer to system command buffer into system table
*systemTable = (uint32_t) systemCommand;
//Check if TX channel is free
if (HAL_IPCC_GetChannelStatus(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) {
 Error_handler();
}
 
//Notify CPU2
HAL_StatusTypeDef status = HAL_IPCC_NotifyCPU(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_TX);
if (status != HAL_OK) {
 Error_handler();
}
 
int i = 0;
//wait until CPU2 releaes the TX channel to acknowledge the command
while (HAL_IPCC_GetChannelStatus(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_TX) != IPCC_CHANNEL_STATUS_FREE) {
 i++;
 HAL_Delay(200);
}
 
//wait till CPU2 notifies CPU1 via RX channel
while (HAL_IPCC_GetChannelStatus(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX) != IPCC_CHANNEL_STATUS_OCCUPIED) {
 i++;
 HAL_Delay(200);
}
 
//clear notification from RX channel
status = HAL_IPCC_NotifyCPU(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX);
if (status != HAL_OK) {
 Error_handler();
}

ST Employee
January 10, 2022

Hello,

I believe what your are looking for is the example :

\Projects\P-NUCLEO-WB55.Nucleo\Applications\CKS\CKS_Crypt.

This application does not use any wireless protocol stack ( BLE, Thread, Zigbee, etc...)

It only uses CPU2 to work with key stored.

Regards