cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB55: Interaction with FUS

Dominik Lorych
Associate III

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?

1 ACCEPTED SOLUTION

Accepted Solutions
Dominik Lorych
Associate III

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();
}

View solution in original post

3 REPLIES 3
Dominik Lorych
Associate III

Bump to the top after the holidays :)

Dominik Lorych
Associate III

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();
}

Christophe Arnal
ST Employee

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