2024-08-28 05:58 AM - last edited on 2024-08-29 08:07 AM by SofLit
HI,
For testing and debugging FMC_norflash(MT28EW01aba) with custom h753 board, I used h743i-eval example as it is for read,write,erase, hence, i could read Manufactring code in memory browser, but in live expression i see address is different, so, where should i check for proper tx and rx data to be match.
#include "main.h"
#include "stm32h7xx_hal.h"
#include "stdio.h"
#define BUFFER_SIZE ((uint32_t)0x1000) // Buffer size for read/write operations
#define NOR_BANK_ADDR ((uint32_t)0x60000000) // Base address of the NOR flash
#define ERASE_TIMEOUT 0x00A00000U // Timeout for erase operation
#define PROGRAM_TIMEOUT 0x00001000U // Timeout for program operation
#define WRITE_READ_ADDR ((uint32_t)0x8000) // Address offset for read/write operations
#define MANUFACTURER_CODE ((uint16_t)0x0089) // Expected Manufacturer code
#define DEVICE_CODE1 ((uint16_t)0x227E) // Expected Device code 1
#define DEVICE_CODE2 ((uint16_t)0x2221) // Expected Device code 2
#define DEVICE_CODE3 ((uint16_t)0x2200) // Expected Device code 3
#define NOR_STATUS_READ_ID_ERROR 0x01 // Custom error code for read ID error
#define NOR_STATUS_ID_ERROR 0x02 // Custom error code for ID mismatch
/* Private variables ---------------------------------------------------------*/
uint16_t aTxBuffer[BUFFER_SIZE];
uint16_t aRxBuffer[BUFFER_SIZE];
__IO uint32_t uwWriteReadStatus = 0;
uint32_t uwIndex = 0;
NOR_HandleTypeDef hnor1;
NOR_IDTypeDef NOR_Id;
FMC_NORSRAM_TimingTypeDef NOR_Timing;
/* Private typedef -----------------------------------------------------------*/
typedef enum
{
FAILED = 0,
PASSED = !FAILED
} TestStatus;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
HAL_StatusTypeDef MX_FMC_Init(void);
void Error_Handler(void);
static void Fill_Buffer(uint16_t *pBuffer, uint32_t uwBufferLenght, uint16_t uwOffset);
static TestStatus Buffercmp(uint16_t *pBuffer1, uint16_t *pBuffer2, uint16_t BufferLength);
static void CPU_CACHE_Enable(void);
static void MPU_Config(void);
/* Main Program --------------------------------------------------------------*/
int main(void)
{
/* Enable CPU Cache */
CPU_CACHE_Enable();
/* MPU Configuration */
MPU_Config();
/* HAL Initialization */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize GPIO */
MX_GPIO_Init();
/* Initialize FMC (NOR flash) */
if (MX_FMC_Init() != HAL_OK)
{
Error_Handler();
}
/* Fill the buffer to write */
Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xD20F);
for (int i = 0; i < BUFFER_SIZE; i++) {
printf("aTxBuffer[%d] = 0x%X\n", i, aTxBuffer[i]);
}
/* Erase the NOR flash block */
if (HAL_NOR_Erase_Block(&hnor1, WRITE_READ_ADDR, NOR_BANK_ADDR) != HAL_OK)
{
Error_Handler();
}
/* Wait until NOR is ready */
if(HAL_NOR_GetStatus(&hnor1, NOR_BANK_ADDR, ERASE_TIMEOUT) != HAL_NOR_STATUS_SUCCESS)
{
Error_Handler();
}
/* Write data to the NOR memory */
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
if (HAL_NOR_Program(&hnor1, (uint32_t *)(NOR_BANK_ADDR + WRITE_READ_ADDR + 2 * uwIndex), &aTxBuffer[uwIndex]) != HAL_OK)
{
Error_Handler();
}
/* Check the status after each write operation */
if(HAL_NOR_GetStatus(&hnor1, NOR_BANK_ADDR, PROGRAM_TIMEOUT) != HAL_NOR_STATUS_SUCCESS)
{
Error_Handler();
}
}
/* Read data back from NOR flash */
if(HAL_NOR_ReadBuffer(&hnor1, NOR_BANK_ADDR + WRITE_READ_ADDR, aRxBuffer, BUFFER_SIZE) != HAL_OK)
{
Error_Handler();
}
/* Checking data integrity */
uwWriteReadStatus = Buffercmp(aTxBuffer, aRxBuffer, BUFFER_SIZE);
if (uwWriteReadStatus != PASSED)
{
/* Toggle the LED connected to GPIOI Pin 8 to indicate an error */
while(1)
{
HAL_GPIO_TogglePin(GPIOI, GPIO_PIN_8);
HAL_Delay(500);
}
}
else
{
// Optionally, indicate success by turning on an LED or similar
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_8, GPIO_PIN_SET);
}
/* Infinite loop */
while (1)
{
}
}
/* Helper Functions ----------------------------------------------------------*/
/* Function to fill the buffer with test data */
static void Fill_Buffer(uint16_t *pBuffer, uint32_t uwBufferLenght, uint16_t uwOffset)
{
uint16_t tmpIndex = 0;
/* Put in global buffer different values */
for (tmpIndex = 0; tmpIndex < uwBufferLenght; tmpIndex++ )
{
pBuffer[tmpIndex] = tmpIndex + uwOffset;
}
}
/* Function to compare two buffers */
static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)
{
while (BufferLength--)
{
if (*pBuffer1 != *pBuffer2)
{
return FAILED;
}
pBuffer1++;
pBuffer2++;
}
return PASSED;
}
HAL_StatusTypeDef MX_FMC_Init(void)
{
FMC_NORSRAM_TimingTypeDef Timing = {0};
hnor1.Instance = FMC_NORSRAM_DEVICE;
hnor1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
hnor1.Init.NSBank = FMC_NORSRAM_BANK1;
hnor1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hnor1.Init.MemoryType = FMC_MEMORY_TYPE_NOR;
hnor1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hnor1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hnor1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hnor1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hnor1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hnor1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hnor1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hnor1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;
hnor1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hnor1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hnor1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;
hnor1.Init.PageSize = FMC_PAGE_SIZE_NONE;
Timing.AddressSetupTime = 15;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 255;
Timing.BusTurnAroundDuration = 15;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FMC_ACCESS_MODE_A;
if (HAL_NOR_Init(&hnor1, &Timing, NULL) != HAL_OK)
{
Error_Handler();
}
/* Read & Check the NOR device IDs */
if (HAL_NOR_Read_ID(&hnor1, &NOR_Id) != HAL_OK)
{
/* NOR read ID Error */
return NOR_STATUS_READ_ID_ERROR;
}
/* Test the NOR ID correctness */
if ((NOR_Id.Manufacturer_Code != MANUFACTURER_CODE) ||
(NOR_Id.Device_Code1 != DEVICE_CODE1) ||
(NOR_Id.Device_Code2 != DEVICE_CODE2) ||
(NOR_Id.Device_Code3 != DEVICE_CODE3))
{
/* NOR ID not correct */
return NOR_STATUS_ID_ERROR;
}
printf("Manufacturer Code: 0x%X\n", NOR_Id.Manufacturer_Code);
printf("Device Code 1: 0x%X\n", NOR_Id.Device_Code1);
printf("Device Code 2: 0x%X\n", NOR_Id.Device_Code2);
printf("Device Code 3: 0x%X\n", NOR_Id.Device_Code3);
return HAL_OK;
}
Solved! Go to Solution.
2024-09-02 06:40 AM
@jr_engr_mbed wrote:
After successfully testing read, write, and erase functions in CubeIDE,
@jr_engr_mbed wrote:
I created a loader that appears to be working correctly. I tested this by programming a bin file of a GPIO example at 0x60000000 and verified its functionality.
Is this the correct approach?
If you succeeded with your own loader you can go ahead. Just noticed you are using the old tool STLink-Utility, I suggest to use STM32CubeProgrammer instead. See how you can add your loader in it in this tread.
Also, this article as it may help you.
Additionally, I need guidance on how to implement image data in NOR Flash for TouchGFX. Where should I make the necessary changes to see the results on the display?
I suggest to open a new thread regarding TouchGFX.
2024-08-29 08:11 AM
Hello @jr_engr_mbed ,
First, in next time please paste your code using </> button. Review the tips on how to post a thread here.
I've edited your post then.
Second, what if you disable the cache? do you have the same behavior?
2024-08-30 05:38 AM
Subject: NOR Flash Testing Update and Questions
Hi [SofLit_st employee],
Thank you for guiding me on how to post code. I wanted to provide you with an update. I was able to see the TX buffer and RX buffer data at the address 0x60000000. I believe this indicates that I am successfully writing and reading data from the NOR flash.
I set breakpoints before the erase, write, and read operations. When I reached the erase function, I saw 0xFFFFFFFF, and I observed data in the TX and RX buffers. Could you please confirm if this indicates that the NOR flash is functioning correctly? This is my first time working with NOR flash and FMC, so I want to make sure everything is as expected.
I also have a few questions:
I’ve attached all relevant images and code for your reference.Thank you for your assistance!
Best regards,
[jr_mbed_engr
]
2024-08-30 08:21 AM
>> "target not responding"
Tends to be indicative that you've crash the core, or it's stalling with wait-states trying to access a memory that isn't responding, or timeout is longer than the debugger is willing to wait around.
2024-08-30 08:57 AM
Thank you for your prompt response. When I debug without breakpoints, I don't encounter the "target not responding" error.,shall I confirm that my flash memory can perform read, write, and erase operations successfully, and can be used as a BSP for creating an external loader to store my TouchGFX assets?
Following your guidance from the previous post, I've made these adjustments. How should I proceed from here? Should I keep this same project file for creating loader by including loader.c src.c loader.h and generate Elf.file? Right
2024-09-02 06:21 AM
Hi,
After successfully testing read, write, and erase functions in CubeIDE, I moved forward without following all the steps in EWARM. Instead, I used a similar example( M29W128GH) from GitHub for MT28EW01GABA specifically the FMC_norflash example, which I imported into EWARM. I modified the def.c file according to the memory datasheet, updating the size and page read size from 16MB to 32MB. After building the project, I created a loader that appears to be working correctly. I tested this by programming a bin file of a GPIO example at 0x60000000 and verified its functionality.
Is this the correct approach? Since the loader.c file is similar to my tested application code using the HAL library, should I proceed with this loader to store my TouchGFX images? Additionally, I need guidance on how to implement image data in NOR Flash for TouchGFX. Where should I make the necessary changes to see the results on the display?
2024-09-02 06:40 AM
@jr_engr_mbed wrote:
After successfully testing read, write, and erase functions in CubeIDE,
@jr_engr_mbed wrote:
I created a loader that appears to be working correctly. I tested this by programming a bin file of a GPIO example at 0x60000000 and verified its functionality.
Is this the correct approach?
If you succeeded with your own loader you can go ahead. Just noticed you are using the old tool STLink-Utility, I suggest to use STM32CubeProgrammer instead. See how you can add your loader in it in this tread.
Also, this article as it may help you.
Additionally, I need guidance on how to implement image data in NOR Flash for TouchGFX. Where should I make the necessary changes to see the results on the display?
I suggest to open a new thread regarding TouchGFX.