cancel
Showing results for 
Search instead for 
Did you mean: 

Can't communicate with ROM Bootloader via SPI

FLewz.1
Associate III

Hi,

I am trying to use the ROM bootloader on the STM32G071 to change the contents of specific flash sections. I was able to enter the bootloader just fine, at least I think so because I can see in the debugger how different points in the address space above 1fff0000 are accessed.

I am using this library on another STM32 as a master:

https://github.com/glegrain/STM32-SPI-Bootloader-host

​Since it's written by an STM employee and the commands are exactly like in AN2606 I am confident this is correct. However I can't even get past the first synchronization sequence. The bootloader only responds with seemingly random data.

The baud rate is below 8MHz ​as necessary. Is there some additional timing I have to adhere to, or anything else that I am missing?

I rechecked this on an STM32F446 Nucleo and am having the same problems.

I used the CubeMX configuration for SPI on master side with CPOL Low, CPHA Edge 1, MSB first 8bit.

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
FLewz.1
Associate III

To anyone who might face the same issue:

I was under the impression, all interrupts need to be disabled before entering the ROM bootloader. This is mentioned in AN2606

In addition to patterns described above, user can execute bootloader by performing a jump to system memory from user code. Before jumping to bootloader user must:

• Disable all peripheral clocks

• Disable used PLL

• Disable interrupts

• Clear pending interrupts

However disabling interrupts and relocating the vector table seems to have caused the issue.

This was what my function to enter BL now looks like without disabling irqs and leaving the vector table at application entry:

static void jump_to_bl()
{
	void (*SysMemBootJump)(void);
	volatile uint32_t addr = 0x1FFF0000;
	HAL_RCC_DeInit();
	HAL_DeInit();
 
	SysTick->CTRL = 0;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
 
//	__disable_irq();
	__HAL_RCC_SYSCFG_CLK_ENABLE();           //make sure syscfg clocked
	__DSB();
	__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();  //remap system memory to address 0x0000000
	__DSB();
	__ISB();
//	SCB->VTOR = 0;                           //set vector table offset to 0
	SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
	__set_MSP(*(uint32_t *)addr);
	SysMemBootJump();
}

View solution in original post

4 REPLIES 4
MM..1
Chief II

In AN2606 is complete info. Your design need meet this condition.

Diagram for detection interface show SPI as not first interface and if an before detected interface is active SPI isnt activated. Too example github code use

void BL_Init(SPI_HandleTypeDef *hspi)
{
  uint8_t sync_byte = BL_SPI_SOF;
 
  /* Associate SPI handle */
  SpiHandle = hspi;
 
  /* Send synchronization Byte */
  HAL_SPI_Transmit(SpiHandle, &sync_byte, 1U, 1000U);
 
  /* Get SYNC Byte ACK*/
  wait_for_ack();
}

but you need handle right moment to call this init...

REMARK Dont create duplicate

FLewz.1
Associate III

I am calling BL_Init a moment after I am sure the slave uC has entered the BL. Is there specific timing to adhere to? I am not using any other periphery to connect to the BL. I can see that the bootloader sends a dummy while the master sends the sync byte. However after that the master loops in wait_for_ack() because the bootloader just sends garbage data while the master sends dummies

FLewz.1
Associate III

This is a scope snippet of the MISO line for BL_INIT. You can see when the master sends the sync byte the slave still sends its dummy byte A5. After that, when the master sends dummy bytes, the slave bootloader just sends garbage data, instead of ACK. ACK would be 0x790693W00000NsmxzQAB.png

FLewz.1
Associate III

To anyone who might face the same issue:

I was under the impression, all interrupts need to be disabled before entering the ROM bootloader. This is mentioned in AN2606

In addition to patterns described above, user can execute bootloader by performing a jump to system memory from user code. Before jumping to bootloader user must:

• Disable all peripheral clocks

• Disable used PLL

• Disable interrupts

• Clear pending interrupts

However disabling interrupts and relocating the vector table seems to have caused the issue.

This was what my function to enter BL now looks like without disabling irqs and leaving the vector table at application entry:

static void jump_to_bl()
{
	void (*SysMemBootJump)(void);
	volatile uint32_t addr = 0x1FFF0000;
	HAL_RCC_DeInit();
	HAL_DeInit();
 
	SysTick->CTRL = 0;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
 
//	__disable_irq();
	__HAL_RCC_SYSCFG_CLK_ENABLE();           //make sure syscfg clocked
	__DSB();
	__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();  //remap system memory to address 0x0000000
	__DSB();
	__ISB();
//	SCB->VTOR = 0;                           //set vector table offset to 0
	SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
	__set_MSP(*(uint32_t *)addr);
	SysMemBootJump();
}