STM32WB55: Interaction with FUS
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-12-20 08:41 AM
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?
Solved! Go to Solution.
- Labels:
-
STM32WB series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-06 12:36 AM
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();
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-04 01:00 AM
Bump to the top after the holidays :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-06 12:36 AM
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();
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-01-10 04:52 AM
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