cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Bootloader in STM32L433 Nucleo-64

KAhmed
Associate II

Hi, 


I'm trying to use built in can bus bootloader in STM32L433 Nucleo Board. To enter the bootloader, I configure the Flash option byte as below:

 

 

 

void configure_bootloader_option_bytes(void) {

   // Define a structure to hold the option byte configuration
   FLASH_OBProgramInitTypeDef ob_config;
   
   // 1. Unlock the Flash control register access
    while(HAL_FLASH_Unlock() != HAL_OK)
    {
         printf("Waiting Flash Unlock\r\n");
    }

   // 2. Unlock the Option Byte register access and check busy bit
    while(HAL_FLASH_OB_Unlock() != HAL_OK)
    {
    	printf("Waiting OB Unlock\r\n");
    }

    while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)){}

   // 3. Get the current Option Bytes configuration
   HAL_FLASHEx_OBGetConfig(&ob_config);
   
   /*
    *__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)
    * FLASH_OPTR_nBOOT1 23
    * FLASH_OPTR_nBOOT0 27
    * FLASH_OPTR_nSWBOOT0 26
    * */
   // 4. Set the desired values for nBoot0, nBoot1, and nBoot0_SW
   // Set nBoot0 = 0 (so that the bootloader is controlled by BOOT0 pin)
   ob_config.OptionType = OPTIONBYTE_USER;

//   ob_config.USERType &=  (OB_USER_nBOOT1 | OB_USER_nSWBOOT0 | OB_USER_nBOOT0);
   ob_config.USERType |=  (OB_USER_nBOOT1 | OB_USER_nSWBOOT0 | OB_USER_nBOOT0);

   ob_config.USERConfig &= ~FLASH_OPTR_nBOOT0;  // This sets nBoot0 to 0

   // Set nBoot1 = 1 (boot from system memory - bootloader)
   ob_config.USERConfig |= FLASH_OPTR_nBOOT1; //  FLASH_OB_USER_nBOOT1 ;   // This sets nBoot1 to 1

   // Set nBoot0_SW = 0 (disable software override for BOOT0)
   ob_config.USERConfig &= ~FLASH_OPTR_nSWBOOT0; // FLASH_OB_USER_nSWBOOT0 ;   // This clears nBoot0_SW, making it 0

   // 5. Program the new Option Bytes configuration
   if (HAL_FLASHEx_OBProgram(&ob_config) != HAL_OK) {
       // Handle error if programming fails
	   HAL_FLASH_OB_Lock();
	   HAL_FLASH_Lock();
       Error_Handler();
   }

   // 6. Launch the option byte reload to apply changes
   HAL_FLASH_OB_Launch();

   /* We should not make it past the Launch, so lock
    * flash memory and return an error from function
    */

   // 7. Lock the Option Bytes and Flash control registers
   HAL_FLASH_OB_Lock();
   HAL_FLASH_Lock();

   // 8. Reset the microcontroller to apply the new boot settings
   NVIC_SystemReset();

//   return HAL_ERROR;
}

 

 

 

KAhmed_0-1727207197556.png

 

Then I made sure I'm in the bootloader from STM32 Programmer. That the PC (Program counter) in the Bootloader range (at 0x1FFF0000)

PCPC

And I followed the flow chart in AN2606, and AN3154(CAN protocol used in the stm32 bootloader).
But it not responding, I'm able to send and receive can messages between my STM32L433 Neucluo Board and Beagle Bone AI (using python in BB AI) before STM32 enter Bootloader mode, but AFTER the stm32 enter the bootloader mode it will not response to any message.
this is my simple python program to talk to the stm32L433 can bootloader:


 

 

 

class UpdateFirmware():
    def __init__(self):
        self.can_channel = 'can1'
        self.bus = can.interface.Bus(interface='socketcan', channel= self.can_channel, bitrate=125000)
       
    def TX_can_msg(self, ID, can_data, extended_id=False):
        self.TX_msg = can.Message( arbitration_id=ID, data=can_data, is_extended_id=extended_id)
        try:
            self.bus.send(self.TX_msg)
            # print(f"Message sent on {self.bus.channel_info}")
        except can.CanError:
            print("Error: Message NOT sent")
            traceback.print_exc()
            
    def RX_can_msg(self, timeout=0.1):
        try:
            msg = self.bus.recv(timeout)
            # if msg is None:
            #     print("No message recived")
            # else:
            if msg is not None:
               # print(f"Message Received: {msg}")
               # print(f"Message Received: STD ID: {msg.arbitration_id} --  DLC = {msg.dlc} -- Data = {' '.join(f'{byte:02x}' for byte in msg.data)}")
               pass
            return msg

        except can.CanError:
            print("Error: Message NOT received")
            traceback.print_exc()
if __name__=="__main__": 
  

    x = UpdateFirmware()

    # Send BL Start Message
    x.TX_can_msg(0x79, [])
    time. sleep(2)
    msg = x.RX_can_msg()
    if msg is not None:
            print(f"1 Message Received: STD ID: 0x{msg.arbitration_id:X} --  DLC = {msg.dlc} -- Data = {' '.join(f'{byte:02x}' for byte in msg.data)}")
   
    # Send BL Get command Message
    x.TX_can_msg(0x00, [0x79])
    time.sleep(0.1)

    # receive BL Can message  from Get Command (16 can massages should be received )
    while True: # Get command
        msg = x.RX_can_msg()
        time.sleep(0.1)
        if msg is not None:
            print(f"{i + 1} Message Received: STD ID: 0x{msg.arbitration_id:X} --  DLC = {msg.dlc} -- Data = {' '.join(f'{byte:02x}' for byte in msg.data)}")
            i += 1
            if i == 16:
                msg = None
                break
            if msg.data == 0x1F:
                print('NACK')
                raise
        msg = None

 

 

 

 

Am I doing something wrong here? Does anyone have a good example showing how to use the built-in can bootloader for the STM32L4XXX? 

Thank you.

 

4 REPLIES 4
Imen.D
ST Employee

Hello @KAhmed,

Let me first welcome you to the ST Community :)

Did you follow the "Table 148. STM32L43xxx/44xxx configuration in system memory boot mode" from AN2606 and set PB8 and PB9 for CAN1_RX and CAN1_TX pins?

Check the clock and HSE settings.

ImenD_0-1727256025868.png

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Hi Imen,
Thank you for your response.

Yes, I did configure CAN1 in PB8 and PB9 at 125 kbps , I'm able to send and receive can messages between my STM32L433 Nucleo Board and Beagle Bone AI (using python in BB AI) before STM32 enter Bootloader mode, but AFTER the stm32 enter the bootloader mode it will not response to any message.

Hi Imen,
I’m working with the Nucleo STM32L433 and don’t have an external clock available. Do I need to solder on an external clock, or can I use the internal HSI? I’ve configured the HSI to run at 60 MHz and set the CAN baud rate to 125 Kbps.

KAhmed_1-1727273331574.png

 

Roger SHIVELY
ST Employee

Hello @KAhmed 

 

This post has been escalated to the ST Online Support Team for additional assistance.  We'll contact you directly.

 

Regards,

Roger