Skip to main content
AMend.7
Associate III
October 23, 2023
Question

STM32H5 external loader

  • October 23, 2023
  • 60 replies
  • 15273 views

Hi,

 I need the project used to generate the external loader: MX25LM51245G_STM32H573I-DK.stldr. My custom board uses a STM32H563VIT6 and the same octo-spi flash from Macronix used in the STM32H573I-DK board. But with different gpios connections. So this project would be of great help to develop the external flash loader for my board.

 

Ari

This topic has been closed for replies.

60 replies

Associate
January 19, 2025

Hi,

i'm trying to develop a QuadSPI custom loader for STM32H563ZI with Macronix flash MX25L25645G. I started using the custom loader example attached in youtube video of ST (https://www.youtube.com/watch?v=XqCq0xtQmbI) ,porting library from QSPI to XSPI.

I found some differences in autopolling function:

  • HAL_StatusTypeDef HAL_QSPI_AutoPolling (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout);

 

  • HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg,
    uint32_t Timeout)

in XSPI autopolling funcion is missing the "cmd" parameter, how do I manage this for example in the function below?

 

static uint8_t QSPI_WriteEnable(void) {
QSPI_CommandTypeDef sCommand;
QSPI_AutoPollingTypeDef sConfig;

 

/* Enable write operations ------------------------------------------ */
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.Instruction = WRITE_ENABLE_CMD;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DummyCycles = 0;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

 

if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)
!= HAL_OK) {
return HAL_ERROR;
}

 

/* Configure automatic polling mode to wait for write enabling ---- */
sConfig.Match = 0x02;
sConfig.Mask = 0x02;
sConfig.MatchMode = QSPI_MATCH_MODE_AND;
sConfig.StatusBytesSize = 1;
sConfig.Interval = 0x10;
sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;

sCommand.Instruction = READ_STATUS_REG_CMD;
sCommand.DataMode = QSPI_DATA_1_LINE;


if (HAL_QSPI_AutoPolling(&hqspi, &sCommand, &sConfig,
HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
return HAL_ERROR;
}

return HAL_OK;
}

Thank you.

 

Tesla DeLorean
Guru
January 19, 2025

You can make your own wrapper, but the model now is that you send the command before calling the function, so the function just iterates on the matching against the data stream

https://github.com/STMicroelectronics/stm32-mx25lm51245g/blob/d2dc02bdadf6b9874384d8725694ef14c7b6988e/mx25lm51245g.c#L85

//****************************************************************************

/**
 * @brief This function read the SR of the memory and wait the EOP.
 * @PAram hospi: QSPI handle
 * @PAram Timeout
 * @retval None
 */
static uint8_t XSPI_AutoPollingMemReady(XSPI_HandleTypeDef *hospi, uint32_t Timeout)
{ // sourcer32@gmail.com
 XSPI_RegularCmdTypeDef sCommand = {0};
 XSPI_AutoPollingTypeDef sConfig = {0};

 sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
 sCommand.IOSelect = XSPI_IOSELECT;

 /* Configure automatic polling mode to wait for memory ready */
 sCommand.Instruction = READ_STATUS_REG1_CMD;
 sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
 sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
 sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
 sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
 sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
 sCommand.DataLength = 1;
 sCommand.DummyCycles = 0;
 sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

 if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return(XSPI_ERROR);
 }

 sConfig.MatchValue = 0; // 0=READY,1=BUSY
 sConfig.MatchMask = SR1_BUSY;
 sConfig.MatchMode = HAL_XSPI_MATCH_MODE_AND;
 sConfig.IntervalTime = AUTO_POLLING_INTERVAL;
 sConfig.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE;

 if (HAL_XSPI_AutoPolling(hospi, &sConfig, Timeout) != HAL_OK)
 {
 return(XSPI_ERROR);
 }

 return(XSPI_OK);
}

//****************************************************************************
//****************************************************************************

/**
 * @brief This function send a Write Enable and wait it is effective.
 * @PAram hospi: QSPI handle
 * @retval None
 */
static uint8_t XSPI_WriteEnable(XSPI_HandleTypeDef *hospi)
{ // sourcer32@gmail.com
 XSPI_RegularCmdTypeDef sCommand = {0};
 XSPI_AutoPollingTypeDef sConfig = {0};

 sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
 sCommand.IOSelect = XSPI_IOSELECT;

 /* Enable write operations */
 sCommand.Instruction = WRITE_ENABLE_CMD;
 sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
 sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.AddressMode = HAL_XSPI_ADDRESS_NONE;
 sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
 sCommand.DataMode = HAL_XSPI_DATA_NONE;
 sCommand.DummyCycles = 0;
 sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

 if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return(XSPI_ERROR);
 }

 sCommand.Instruction = READ_STATUS_REG1_CMD;
 sCommand.DataMode = HAL_XSPI_DATA_1_LINE;
 sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
 sCommand.DataLength = 1;

 if (HAL_XSPI_Command(hospi, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return(XSPI_ERROR);
 }

 /* Configure automatic polling mode to wait for write enabling */
 sConfig.MatchValue = SR1_WREN;
 sConfig.MatchMask = SR1_WREN;
 sConfig.MatchMode = HAL_XSPI_MATCH_MODE_AND;
 sConfig.IntervalTime = AUTO_POLLING_INTERVAL;
 sConfig.AutomaticStop = HAL_XSPI_AUTOMATIC_STOP_ENABLE;

 if (HAL_XSPI_AutoPolling(hospi, &sConfig, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return(XSPI_ERROR);
 }

 return(XSPI_OK);
}

//***************************************************************************
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Associate
January 20, 2025

Hi all,

Thank you so much, very helpful!

@Tesla DeLorean  i'm using the following pins:

  • OCTOSPI1_IO3 --> PF6
  • OCTOSPI1_IO2 --> PF7
  • OCTOSPI1_IO0 --> PF8
  • OCTOSPI1_IO1 --> PF9
  • OCTOSPI1_CLK --> PF10
  • OCTOSPI1_NCS --> PE11

@ABasi.2Can you share also your configuration for the CSP_QSPI_EnableMemoryMappedMode and CSP_QSPI_WriteMemory fuctions?

Thanks again.

ABasi.2
Senior
January 20, 2025

Hi Berto

yes no problem, keep in mind my memory is a MX25L512

uint8_t CSP_QSPI_EnableMemoryMappedMode(void)
{
 XSPI_RegularCmdTypeDef sCommand;
 XSPI_MemoryMappedTypeDef sMemMappedCfg;
 

 // Enable Memory-Mapped mode--------------------------------------------------
 sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
 sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
 sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
 sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
 sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.Address = 0;
 sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
 sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
 sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
 sCommand.AlternateBytes = 0;
 sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
 sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
 sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
 sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
 sCommand.DataLength = 0;
 sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
 sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
 sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

 sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;

 if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
 {
 return HAL_ERROR;
 }

 if (HAL_XSPI_MemoryMapped(&hospi1,&sMemMappedCfg) != HAL_OK)
 {
 return HAL_ERROR;
 }

 return HAL_OK;
}

 

uint8_t CSP_QSPI_WriteMemory(uint8_t* buffer, uint32_t address,uint32_t buffer_size)
{
 XSPI_RegularCmdTypeDef sCommand;
 uint32_t end_addr, current_size, current_addr;

 
 // Calculation of the size between the write address and the end of the page
 current_addr = 0;

 while(current_addr <= address)
 {
 current_addr += MEMORY_PAGE_SIZE;
 }
 current_size = current_addr - address;

 // Check if the size of the data is less than the remaining place in the page
 if(current_size > buffer_size)
 {
 current_size = buffer_size;
 }

 // Initialize the adress variables
 current_addr = address;
 end_addr = address + buffer_size;

 sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
 sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
 sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
 sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
 sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
 sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
 sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
 sCommand.AlternateBytes = 0;
 sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
 sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
 sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
 sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
 sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
 sCommand.DummyCycles = 0;
 sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

 // Perform the write page by page
 do
 {
 sCommand.Address = current_addr;
 sCommand.DataLength = current_size;

 if(current_size == 0)
 {
	 return HAL_OK;
 }

 // Enable write operations
 if(QSPI_WriteEnable() != HAL_OK)
 {
 return HAL_ERROR;
 }

 // Configure the command
 if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
 {
 return HAL_ERROR;
 }

 // Transmission of the data
 if(HAL_XSPI_Transmit(&hospi1, buffer,HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }

 // Configure automatic polling mode to wait for end of program
 if(QSPI_AutoPollingMemReady(HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }

 // Update the address and size variables for next page programming
 current_addr += current_size;
 buffer += current_size;
 current_size = ((current_addr + MEMORY_PAGE_SIZE) > end_addr) ?	(end_addr - current_addr) : MEMORY_PAGE_SIZE;

 }while(current_addr <= end_addr);

 return HAL_OK;
}

 

Associate
January 20, 2025

Hi @ABasi.2 ,

thanks, my configuration is similar as yours, it returns an error in the last check:

for(var = 0; var < SECTORS_COUNT; var++)
{
if(memcmp(buffer_test,(uint8_t*) (0x90000000 + var * MEMORY_SECTOR_SIZE),MEMORY_SECTOR_SIZE) != HAL_OK)
{
while(1); //breakpoint - error detected - otherwise QSPI works properly
}
}

Berto_0-1737385542720.png

Seems is not writing correctly data on the address 0x90000000

ABasi.2
Senior
January 20, 2025

Hi berto

i think there are some dummy clocks in your configuration that are wrong, another guy in this forum have an issue similar to yours and resolve managing the dummy clocks 

 

check the parameter 

sCommand.DummyCycles

 according to your memory datasheet

Associate
January 20, 2025

Hi @ABasi.2 ,

Thank you! I try to check this parameter, do i need to modify this just in the write funcion or in all commands functions?

Associate
January 21, 2025

Hi,

thanks so much for your suggestions, i'm trying to set up the correct dummycycles parameter.

Just a question, which is your clock configuration to peripheral and octospi prescaler?

 

ABasi.2
Senior
January 21, 2025

hello Berto!

here my ioc file, i'm using the nucleo-H563ZI

hope this helps

notice i have HCLK 250Mhz and the OctoSpi is feeded by the HCLK

 

Associate
January 21, 2025

Hi @ABasi.2

Thanks again, now i can debug the main code without errors but only setting the dummycycles in CSP_QSPI_EnableMemoryMappedMode to "26" but it's not a datasheet value i'm not sure is everything correct.

ABasi.2
Senior
January 21, 2025

Hello Berto

i don't know if its a valid value of dummy cycle, in my CSP_QSPI_EnableMemoryMappedMode i have 10 

in all the other function i have 0.

 

 

 

  

Associate
January 21, 2025

Yes you're right, i'm checking the datasheet if I find some errors with commands. I let you know,

Thanks again for support.

Associate
January 28, 2025

Hi All,

I found the error, it was an instruction command on Write funcion. Now i see that seems writing correctly but i have problem reading. Can I see how you set up your WriteMemory and EnableMemoryMappedMode functions?

Thanks.

ABasi.2
Senior
January 28, 2025

hello Berto!

i'm glad you found the error.

yes no problem for the functions, i hope this helps

uint8_t CSP_QSPI_WriteMemory(uint8_t* buffer, uint32_t address,uint32_t buffer_size)
{
 XSPI_RegularCmdTypeDef sCommand;
 uint32_t end_addr, current_size, current_addr; 

 // Calculation of the size between the write address and the end of the page
 current_addr = 0;

 while(current_addr <= address)
 {
 current_addr += MEMORY_PAGE_SIZE;
 }
 current_size = current_addr - address;

 // Check if the size of the data is less than the remaining place in the page
 if(current_size > buffer_size)
 {
 current_size = buffer_size;
 }

 // Initialize the adress variables
 current_addr = address;
 end_addr = address + buffer_size;

 sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
 sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
 sCommand.Instruction = QUAD_IN_FAST_PROG_CMD;
 sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
 sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.AddressMode = HAL_XSPI_ADDRESS_4_LINES;
 sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
 sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
 sCommand.AlternateBytes = 0;
 sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
 sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
 sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
 sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
 sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
 sCommand.DummyCycles = 0;
 sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

 // Perform the write page by page
 do
 {
 sCommand.Address = current_addr;
 sCommand.DataLength = current_size;

 if(current_size == 0)
 {
	 return HAL_OK;
 }

 // Enable write operations
 if(QSPI_WriteEnable() != HAL_OK)
 {
 return HAL_ERROR;
 }

 // Configure the command
 if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
 {
 return HAL_ERROR;
 }

 // Transmission of the data
 if(HAL_XSPI_Transmit(&hospi1, buffer,HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }

 // Configure automatic polling mode to wait for end of program
 if(QSPI_AutoPollingMemReady(HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }

 // Update the address and size variables for next page programming
 current_addr += current_size;
 buffer += current_size;
 current_size = ((current_addr + MEMORY_PAGE_SIZE) > end_addr) ?	(end_addr - current_addr) : MEMORY_PAGE_SIZE;

 }while(current_addr <= end_addr);

 return HAL_OK;
}
uint8_t CSP_QSPI_EnableMemoryMappedMode(void)
{
 XSPI_RegularCmdTypeDef sCommand;
 XSPI_MemoryMappedTypeDef sMemMappedCfg; 

 // Enable Memory-Mapped mode--------------------------------------------------
 sCommand.OperationType = HAL_XSPI_OPTYPE_COMMON_CFG;
 sCommand.IOSelect = HAL_XSPI_SELECT_IO_3_0;
 sCommand.Instruction = QUAD_OUT_FAST_READ_CMD;
 sCommand.InstructionMode = HAL_XSPI_INSTRUCTION_1_LINE;
 sCommand.InstructionWidth = HAL_XSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.Address = 0;
 sCommand.AddressMode = HAL_XSPI_ADDRESS_1_LINE;
 sCommand.AddressWidth = HAL_XSPI_ADDRESS_24_BITS;
 sCommand.AddressDTRMode = HAL_XSPI_ADDRESS_DTR_DISABLE;
 sCommand.AlternateBytes = 0;
 sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
 sCommand.AlternateBytesWidth = HAL_XSPI_ALT_BYTES_8_BITS;
 sCommand.AlternateBytesDTRMode = HAL_XSPI_ALT_BYTES_DTR_DISABLE;
 sCommand.DataMode = HAL_XSPI_DATA_4_LINES;
 sCommand.DataLength = 0;
 sCommand.DataDTRMode = HAL_XSPI_DATA_DTR_DISABLE;
 sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;
 sCommand.DQSMode = HAL_XSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_XSPI_SIOO_INST_EVERY_CMD;

 sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;

 if(HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE)!= HAL_OK)
 {
 return HAL_ERROR;
 }

 if (HAL_XSPI_MemoryMapped(&hospi1,&sMemMappedCfg) != HAL_OK)
 {
 return HAL_ERROR;
 }

 return HAL_OK;
}

 

Associate
February 27, 2025

Hi All,

Sorry for late reply, in meantime i got my own hardware with STM32H523RCT and Macronix MX25L25645G.

I'm testing the loader and having the results attached, seems working correctly.

But when I create the .stldr file and place in STM32CubeProgrammer I can't read neither erase. Do you have any suggestion on this issue?

Thanks in advance.

ABasi.2
Senior
February 27, 2025

Hello Berto!

it seems now your write and read functions work correctly

which is the error the programmer said?

 

if i have to guess:

 

1) did you have commented the "test function" you have used in your mail to test the read/write fuctionality?

2) is it possible to view the linker file the cube create for you and the custom linker you have created?

3) if you have created a new linker did you change the path to the new linker file?

 

best reguards

 

Associate
February 27, 2025

Hello,

Sure, attached you can find both linker files.

Yes i tried both, commenting testing functions and setting the path of created linker.

Cubeprorgrammer returns the following error:

Cubepro.png

Do i need to flash a test.bin before start reading the first time? 

Thanks so much

ABasi.2
Senior
February 27, 2025

hello

i didnt see the two linker file Berto

maybe there is an error in the Dev_Inf.c file or Loader_Src.c file?

i attach here mine, make sure in Loader_Src.c Init function to use the correct address for SCB->VTOR