Open salyzyn opened 1 year ago
Confirmed, code is not appropriate for a Category 4 stm32g4 device :-(, the code in mcu is only for Category 2 and Category 3 devices. Attempts to flash fail during the erase phase as it tries to use the Category 3 option. Is there anything I can do to help?
I was expecting the following to fix the 'problem' with stm32g491, but I still get an error:
Erase [ ] 0% 0 bytesDFU state(10) = dfuERROR, status(3) = Device is unable to write memory dfu-util: Wrong state after command "ERASE_PAGE" download
Here is the code adjustment:
/* calculating PNB[6:0]: ADDR[17:11] -> CR[9:3] */
lsrs r4, 11
bfi r5, r4, 3, 7
+#elif defined(STM32G491xx) //Cat4
+/* calculating PNB[7:0]: ADDR[18:11] -> CR[10:3] */
+ lsrs r4, 11
+ bfi r5, r4, 3, 8
#else // Cat3
/* check dual bank */
ldr r5, [r3, FLASH_OPTR]
Found out why we got the error, dfu-util insists on sending ERASE_PAGE and SET_ADDRESS DFU commands, which are not supported by src/bootblock.c, here is my hacky code adjustment following. I probably need to investigate what sboot_stm32 is doing that results in dfu-util wanting to use these two commands.
Add support for erase page and set address commands
Signed-off-by: Mark Salyzyn <mark.salyzyn@gmail.com>
diff --git a/src/bootloader.c b/src/bootloader.c
index b412b7b..cf93e48 100644
--- a/src/bootloader.c
+++ b/src/bootloader.c
@@ -16,6 +16,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
+#include <string.h>
#include "config.h"
#include "stm32.h"
#include "usb.h"
@@ -166,8 +167,38 @@ static usbd_respond dfu_dnload(void *buf, size_t blksize) {
dfu_data.bState = USB_DFU_STATE_DFU_ERROR;
return usbd_ack;
}
- aes_decrypt(buf, buf, blksize );
- dfu_data.bStatus = dfu_data.flash(dfu_data.dptr, buf, blksize);
+ if (blksize == 5) {
+ uint8_t *cp = buf;
+ uint8_t command = *cp;
+ if ((command == 0x41) || (command == 0x21)) {
+ uint32_t address = cp[1]
+ | (cp[2] << 8)
+ | (cp[3] << 16)
+ | (cp[4] << 24);
+ // stm32g491 specific
+ if ((0x08004000 <= address)
+ && (address < (0x08080000 - DFU_BLOCKSZ))) {
+ if (command == 0x41) {
+ memset(buf, 0xFF, sizeof(uint64_t));
+ dfu_data.bStatus = dfu_data.flash(
+ (void*)(uintptr_t)address,
+ buf,
+ sizeof(uint64_t));
+ } else {
+ dfu_data.dptr = (void*)(uintptr_t)address;
+ dfu_data.bStatus = USB_DFU_STATUS_OK;
+ }
+ blksize = 0;
+ } else {
+ dfu_data.bStatus = USB_DFU_STATUS_ERR_ADDRESS;
+ }
+ } else {
+ dfu_data.bStatus = USB_DFU_STATUS_ERR_TARGET;
+ }
+ } else {
+ aes_decrypt(buf, buf, blksize);
+ dfu_data.bStatus = dfu_data.flash(dfu_data.dptr, buf, blksize);
+ }
if (dfu_data.bStatus == USB_DFU_STATUS_OK) {
dfu_data.dptr += blksize;
Edit: my DFU_STR_FLASH had keys that optionally enabled ERASE cycle, before FLASH cycle, so I can turn that off. However the latest dfu-util will insist on using the SET_ADDRESS command blowing sboot_stm32's compatibility unless we add support for it first.
My WAG and heads up, stuff like (untested, I am a few weeks away from this being a priority) is missing:
But I am sure that is flawed since usb driver, albeit similar to stm32f4 from the HAL perspective, might not be from the lower level driver perspective. IDK. I have a NUCLEO-G491RE in my hands where I am working on porting an application from stm32f429 and noticed that to use sboot_stm32, it was borken. Once application port and bringup is done, then I can test sboot_stm32.