I have spoken about this here : https://community.st.com/t5/stm32-mcus- ... d-p/887913
There is an interesting HW solution , but my project is actually prototypal , so I probably (unfortunately) will have to use the reset button , and in the case of this HW solution , the STM32 will resume in DFU upload mode , not that I want .
The SW solution I have adopted works this way :
1) at the setup , one tests the nSWBOOT0 bit in the flash . This bit in set by default (this lead the PB8 pin to enter the DFU upload mode as it is HIGH) . This is not that one need , so in this case , one call a function which clears nSWBOOT0 bit : → the STM32 will start normally , ie. it will boot from user program in flash . If the nSWBOOT0 is already cleared , → one do nothing .
2) at this point , CAN works , the STM32 works , but it is bricked , because one can no more program it through USB DFU . If one want to program it , one have to put PB8 back in BOOT0 mode , by setting again the nSWBOOT0 ; this can be done by several ways , button for example . I my case , I do this after receiving a given code from USB CDC : the function is called that will set the nSWBOOT0 bit ; after cycling the STM32 , it will enter USB DFU mode , and accept one uploading .
In any cases , one have to ensure not to catch the writing to to the flash in an (infinite) loop , this might destroy the STM32
Code: Select all
#define LED PC6
String ze_string;
void setup() {
Serial.begin(115200); // USB CDC
pinMode(LED, OUTPUT);
while (!Serial) { // wait for USB CDC → ok
delay(50);
}
// if not cleard , clear the nSWBOOT0 in the setup , in order to allow normal CAN operation
Serial.print("FLASH->OPTR before setup: ");
Serial.println(FLASH->OPTR, HEX);
if (FLASH->OPTR |= FLASH_OPTR_nSWBOOT0) { // is nSWBOOT0 set ?
set_clear_nSWBOOT0(false); // then clear it
digitalWrite(LED, HIGH);
}
Serial.print("FLASH->OPTR after setup , must be FBEFF8AA : ");
Serial.println(FLASH->OPTR, HEX);
}
void loop() {
while (Serial.available()) {
ze_string = Serial.readString(); // read the incoming data as string
Serial.print(" Serial: ");
Serial.println(ze_string);
if (ze_string.equals("Please dear STM32 , would you be so kind and allow BOOT0 pin to be in use , thank you !")) {
if ((FLASH->OPTR & FLASH_OPTR_nSWBOOT0) == 0) { // isn't nSWBOOT0 set ?
set_clear_nSWBOOT0(true); // then set it
Serial.println(FLASH->OPTR, HEX);
Serial.println(" : FFEFF8AA → BOOT0 pin in use , please cycle STM32 before uploading in DFU mode");
digitalWrite(LED, LOW);
}
}
}
Serial.print("i"); /// debug
Serial.println(FLASH->OPTR, HEX); /// debug
delay(500); /// debug
}
// https://github.com/T-K-233/Notes/blob/main/stm32/misc/changing-stm32-default-boot-option.md
void set_clear_nSWBOOT0(bool set_nSWBOOT0) {
// 1. Unlock the FLASH_CR with the LOCK clearing sequence
// Check that no Flash memory operation is on going by checking the BSY bit in the Flash status register (FLASH_SR).
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {}
HAL_FLASH_Unlock();
// 2. Unlock the FLASH Option Byte with the LOCK clearing sequence
// Check that no Flash memory operation is on going by checking the BSY bit in the Flash status register (FLASH_SR).
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {}
HAL_FLASH_OB_Unlock();
// 3. program OPTR
if (set_nSWBOOT0) { // → set nSWBOOT0 bit
if (FLASH->OPTR | FLASH_OPTR_nSWBOOT0) // is nSWBOOT0 set ?
FLASH->OPTR |= FLASH_OPTR_nSWBOOT0; // default to boot according BOOT0 pin
} else { // → clear nSWBOOT0 bit
if (FLASH->OPTR | FLASH_OPTR_nSWBOOT0 == 0) // isn't nSWBOOT0 set ?
FLASH->OPTR &= ~FLASH_OPTR_nSWBOOT0; // default to boot from flash
}
// 4. Set the Options Start bit OPTSTRT in the Flash control register (FLASH_CR).
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
// 4.1 clear status register
SET_BIT(FLASH->SR, FLASH_SR_OPTVERR | FLASH_SR_RDERR);
// 5. Wait for the BSY bit to be cleared.
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {}
// 6. Lock Flash
// If LOCK is set by software, OPTLOCK is automatically set too
HAL_FLASH_Lock();
// 7. reload the new settings
// seems this line will cause error when put before FLASH_Lock(), which will then corrupt all Flash settings
// so putting it here
// can also comment out this line and just power cycle to update the flash settings
HAL_FLASH_OB_Launch();
}