cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G474 SPI DFU mode not working

AShel.1
Associate III

I'm using STM32H753 eval board as master and STM32G474RE Nucleo board as slave over SPI1 communication. I've created a DFU for LED blink on Nucleo board which works fine if I download it through USB(connected PA11, PA12, 5V and GND) usinf DeFuseDemo tool. have set BOOT pin and all option bytes to enter into bootloader(system memory). If I connect it in SPI mode, I get ACK for all commands there is no single error in communication, all 5704 bytes from DFU file are written successfully. here is my code,

	/* boot loader process starts */
	blInit(&hspi1);
 
	blGetCommand(spiRxBuffer);
 
	version = blGetVersionCommand();
 
	chipID = blGetIDCommand();
 
	/* Check GetVersion is equal to GetCommand version */
	if (version != spiRxBuffer[0])
	{
	  /* TODO : exception handler */
	}
 
	/* Erase, write & verify loop #########################################*/
	/* @note The Flash has to be erased before it can be written to */
 
	/* (0x44) Erase Sector 0 (2 KBytes) */
	blEraseMemoryCommand(0x0002, 0x00);	
	/* (0x31) Write firmware image */
	if(blFWUpdateFlags.bUpdateImage)
	{
		copyImagefromFlash(devType, fname, buffer);
		blFWUpdateFlags.bUpdateImage = 0;
	}
uint8_t copyImagefromFlash(uint8_t devType, char *filename, uint8_t* buffer)
{
	uint32_t len, temp;
 
	if(lfs_file_open(&lfs, &slaveImageFile, filename, LFS_O_CREAT | LFS_O_RDWR | LFS_O_APPEND) != 0)
	{
		MPC_TRACE("\nSlaveFW.txt cannot be open\n");
		return FILE_ERROR;
	}
	else
	{
		MPC_TRACE("\nSlaveFW.txt is open\n");
 
		lfs_file_read(&lfs, &slaveImageFile, &dfuFilePrefix, ELEMENT_HEADER);
		stDword(&slvElement.dwElementAddress, &dfuFilePrefix[3]);
		stDword(&slvElement.dwElementSize, &dfuFilePrefix[7]);
 
		//if(devType < STM32G07_DEV)
		{
			len = slvElement.dwElementSize;//(slaveImageFile.ctz.size - (OPTBYTE_STM32G47x + 8));
		}
		//else
		//{
		//	len = (slaveImageFile.ctz.size - (OPTBYTE_STM32G07x + 8));
		//}
 
		len = (len / SLAVE_PAGEMEMORY_SIZE);
 
		for (int i = 0; i < len; i++)
		{
			lfs_file_read(&lfs, &slaveImageFile, buffer, SLAVE_PAGEMEMORY_SIZE);
 
			blWriteMemoryCommand(slvElement.dwElementAddress, SLAVE_PAGEMEMORY_SIZE, buffer);
			slvElement.dwElementAddress += (SLAVE_PAGEMEMORY_SIZE);
		}
 
		len = slvElement.dwElementSize;
		len = (len % SLAVE_PAGEMEMORY_SIZE);
 
		lfs_file_read(&lfs, &slaveImageFile, buffer, len);
		temp = (slaveImageFile.ctz.size - slvElement.dwElementSize);
		if(devType < STM32G07_DEV)
		{
			if((temp) > (OPTBYTE_STM32G47x + 8))
			{
				temp = 1;
			}
		}
		else
		{
			if((temp) > (OPTBYTE_STM32G07x + 8))
			{
				temp = 1;
			}
		}
		if(temp == 1)
		{
			lfs_file_read(&lfs, &slaveImageFile, &dfuFilePrefix, ELEMENT_HEADER);
			//stDword(&slvElement.dwElementAddress, &dfuFilePrefix[3]);
			stDword(&slvElement.dwElementSize, &dfuFilePrefix[7]);
			temp = (SLAVE_PAGEMEMORY_SIZE - len);
			buffer = (buffer + len);
			lfs_file_read(&lfs, &slaveImageFile, buffer, temp);
			buffer = (buffer - len);
			blWriteMemoryCommand(slvElement.dwElementAddress, SLAVE_PAGEMEMORY_SIZE, buffer);
			slvElement.dwElementAddress += (SLAVE_PAGEMEMORY_SIZE);
			len = slvElement.dwElementSize;
 
			len = (len / SLAVE_PAGEMEMORY_SIZE);
 
			for (int i = 0; i < len; i++)
			{
				lfs_file_read(&lfs, &slaveImageFile, buffer, SLAVE_PAGEMEMORY_SIZE);
 
				blWriteMemoryCommand(slvElement.dwElementAddress, SLAVE_PAGEMEMORY_SIZE, buffer);
				slvElement.dwElementAddress += (SLAVE_PAGEMEMORY_SIZE);
			}
			buffer = (buffer + len);
 
			for (int i = len; i < SLAVE_PAGEMEMORY_SIZE; i++)
			{
				*buffer++ = 0xFF;
			}
 
			blWriteMemoryCommand(slvElement.dwElementAddress, SLAVE_PAGEMEMORY_SIZE, buffer);
 
		}
		else
		{
			buffer = (buffer + len);
 
			for (int i = len; i < SLAVE_PAGEMEMORY_SIZE; i++)
			{
				*buffer++ = 0xFF;
			}
 
			blWriteMemoryCommand(slvElement.dwElementAddress, SLAVE_PAGEMEMORY_SIZE, buffer);
		}
		lfs_file_close(&lfs, &slaveImageFile);
		return FILE_OK;
	}
 
}

Did anyone use DFU - SPI mode to update slave FW, would you please let me know where could be the issue.

thanks,

3 REPLIES 3
TDK
Guru

> If I connect it in SPI mode, I get ACK for all commands there is no single error in communication, all 5704 bytes from DFU file are written successfully.

Okay, so it sounds like you're able to use the bootloader just fine. Then what is the issue specifically? Try to be more specific than just "X isn't working".

A DFU file is different from the firmware binary file. You're not trying to flash the actual DFU file into memory, are you? You should be putting the BIN file there.

If you feel a post has answered your question, please click "Accept as Solution".
AShel.1
Associate III

AN4286 says max 256 bytes can be written, so I'm writing data into iteration of 256 bytes. I've programmed STM32G474 nucleo board through STM32H753 master on SPI with above posted code, then read back DFU file from DeFuseDemo tool and I see first 256 bytes are written correctly but after that all bytes shows 0xFF value so may be next write operation was not successful but I've put breakpoint in ACK and for all iteration it hits this breakpoint, so no clue on why the write operation is not successful, could it be timing issue?

static void waitForACK(void)
{
  uint8_t resp;
  uint8_t dummy = 0x00U;
  uint8_t ack = BL_ACK;
  uint32_t ack_received = 0U;
 
  HAL_SPI_Transmit(&hspi1, &dummy, 1U, 1000U);//HAL_SPI_Transmit_DMA
  while(ack_received != 1U)
  {
    HAL_SPI_TransmitReceive(&hspi1, &dummy, &resp, 1U, 1000U);//HAL_SPI_TransmitReceive_DMA
    if(resp == BL_ACK)
    {
      /* Received ACK: send ACK */
      HAL_SPI_Transmit(&hspi1, &ack, 1U, 1000U);//HAL_SPI_Transmit_DMA
      ack_received = 1U;
    }
    else if (resp == BL_NAK)
    {
      /* Received NACK */
      Error_Handler();
    }
    else
    {
      /* Received junk */
    }
  }
}

here left side file is file read back after slave is programmed using DeFuseDemo over USB and right side file is file read back after slave is programmed using STM32H7 over SPI

If the second write operation is not working, step through the code to see what the issue is. Make sure you're sending the correct address to write.

There appear to be other issues in your code logic, although it's difficult to trace with missing function definitions. I'm not convinced "buffer" is pointing to the memory you want to write.

Why would it be a timing issue? The first write worked just fine.

If you feel a post has answered your question, please click "Accept as Solution".