cancel
Showing results for 
Search instead for 
Did you mean: 

How to store the touchGFX data to nand flash extended by FMC?

Junde
Senior II

Hi there,

I want to try touchGFX on my homemade board with the STM32F429BIT6 and a band flash chip H27U1G8F2B.

After config by cubeMx and TouchGFX designer, my demo can work as well.

However, I checked the map file and found the image is still stored in the internal flash.

Junde_0-1711692909496.png

Junde_2-1711693384029.png

Junde_1-1711693366322.png

Need I change the "config.hpp" file to complete this function?

How can I restore the data to external NAND flash?

Could this step be done automatically, or need some tools to finish it?

If possible, please give me some documents about it.

Thanks for your help!

1 ACCEPTED SOLUTION

Accepted Solutions
Junde
Senior II

I am sorry, the last solution proved does NOT work...

but this one can work well, I found the way by referring HERE.

 

View solution in original post

8 REPLIES 8
MM..1
Chief II

Need I change the "config.hpp" file to complete this function?

no your change be in linker file

How can I restore the data to external NAND flash?

two ways external programmer for flash IC or writed loader code GitHub - STMicroelectronics/stm32-external-loader: Provides drivers, examples, loader files and testing routines for external loaders for STM32 series of microcontrollers.

Could this step be done automatically, or need some tools to finish it?

when you configure all right yes load sw is auto, but manege code and objects is manual job

 

Good examples is TGFX demo projects fer discovery eval boards...

Junde
Senior II

As I said above, I want to write data to Nand Flash extended by FMC by MDK directly.

After reading(LAT1198), I know an algorithm for Flash can program the data to extFlash by MDK.

I followed the steps one by one:

1. I created a project by cubeMx that can read and write the NAND flash normally by MDK;

2. I copy the template in the "ARM\Flash" folder and port the NAND flash driver to the template, it builds with no error and generates the FLM file, the code as below;

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_FMC_Init();
    HAL_NAND_Reset(&hnand1);
    return (0);
}

int UnInit (unsigned long fnc) {
    HAL_NAND_MspDeInit(&hnand1);
    return (0);
}

int EraseChip (void) {
   NAND_FLASH_erase_chip();
    return (0);
}

int EraseSector (unsigned long adr) {
   NAND_FLASH_erase_block(adr);
    return (0);
}

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
  NAND_FLASH_write_page(adr, sz, buf);
  return (0);
}

NAND_FLASH_STA_t NAND_FLASH_erase_block(unsigned long adr)
{
    HAL_StatusTypeDef hal_sta = HAL_OK;
    adr -= NAND_FLASH_ADDR;
    NAND_AddressTypeDef nand_addr = {.Page = 0, .Block = adr / BLOCK_SIZE, .Plane = 0};    // blockSize=128KB
    hal_sta = HAL_NAND_Erase_Block(&hnand1, &nand_addr);
    if(hal_sta != HAL_OK) {
        //NAND_FLASH_ERR("Nand Flash erese block err[%d]\n", hal_sta);
        return NAND_FLASH_ERASE_BLOCK_ERR;
    }
    //NAND_FLASH_DBG("Nand Flash erase block OK\n");
    return NAND_FLASH_STA_OK;
}

NAND_FLASH_STA_t NAND_FLASH_erase_chip(void)
{
    HAL_StatusTypeDef hal_sta = HAL_OK;
    for(uint32_t i = 0; i < BLOCK_NUM; i++) {
        NAND_AddressTypeDef nand_addr = {.Page = 0, .Block = i, .Plane = 0}; 
        hal_sta = HAL_NAND_Erase_Block(&hnand1, &nand_addr);
        if(hal_sta != HAL_OK) {
            //NAND_FLASH_ERR("Nand Flash erese block err[%d]\n", hal_sta);
            return NAND_FLASH_ERASE_CHIP_ERR;
        }
    }
    //NAND_FLASH_DBG("Nand Flash erase chip OK\n");
    return NAND_FLASH_STA_OK;
}

NAND_FLASH_STA_t NAND_FLASH_write_page(unsigned long adr, unsigned long sz, unsigned char *buf)
{
    HAL_StatusTypeDef hal_sta = HAL_OK;
    adr -= NAND_FLASH_ADDR;
    NAND_AddressTypeDef nand_addr = {.Page = adr % BLOCK_SIZE / PAGE_SIZE, .Block = adr / BLOCK_SIZE, .Plane = 0};
    hal_sta = HAL_NAND_Write_Page_8b(&hnand1, &nand_addr, buf, 1);
    if(hal_sta != HAL_OK) {
        //NAND_FLASH_ERR("Nand Flash write err[%d]\n", hal_sta);
        return NAND_FLASH_WRITE_ERR;
    }
    //NAND_FLASH_DBG("Nand Flash write OK\n");
    return NAND_FLASH_STA_OK;
}

3. I tested the FLM file, but the download always failed.

Junde_0-1712543677313.png

I don't know what details I missed led me to fail.

Could you help me, thank you!

 

On Keil the scatter file (.SCT) would drive the data placement. Check the sections via the .MAP output from the linker, or a dump of the .AXF via FROMELF tool

Is the FMC/NAND on the F429 at 0x70000000 ? Or one of the four 0x60000000 banks?

The .FLM needs to actually work, what part of the download process fails?

Do you have the NAND writable from a regular application? Perhaps you can build a test app that can write .HEX data into NAND, either by decoding a stream of data, or perhaps a .BIN you can feed with X/Y-MODEM. Prove you can get data successfully into the NAND, and validate the data on PC vs STM32 with perhaps checksums or CRC.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks @Tesla DeLorean 

I already checked the map file and the data at 0x70000000.

Junde_0-1712552904182.png

I also tested the interfaces that are used in FlashPrg.c, seems all the interfaces are passed:

Junde_1-1712553408285.png

I am helpless because I already tried all the things in my mind.

I want to debug it, but I don't know how.

Do you have any other ideas to check what I am wrong, thanks a lot.

Junde
Senior II

Now, I can split this question into 3 parts:

1. the FLM file has some problems;

2. the way I use the FLM file has some problems;

3. of course, maybe both 1 & 2 have problems;

But I don't have a work-well FLM file for testing, I can't make sure which part I was wrong.

 

Junde
Senior II

Thanks GOD, I find the way at last.

The key point is we can NOT use interrupt in the FLM file, so we must rewrite the HAL_GetTick() function:

 

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  return HAL_OK;
}

uint32_t HAL_GetTick(void)
{
  static uint32_t ticks = 0U;
  uint32_t i;
  for(i = (SystemCoreClock >> 14U); i > 0U; i--)
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
  ticks += 1;
  return ticks;
}

 

The following is the test code and the link file .sct:

 

//The "const" is a must, otherwise, the data will be stored in RAM.
static const uint8_t nand_flash_test_data[PAGE_SIZE] __attribute__((section("ExtFlashSec"))) __attribute__((aligned(4))) = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
};
NAND_FLASH_STA_t NAND_FLASH_algorithm_result_test(void)
{
    LOG_DBG("extFlash data addr[0x%08x]\n", nand_flash_test_data);
    uint8_t nand_read_data[PAGE_SIZE] = {0};
    NAND_FLASH_read_page((unsigned long)nand_flash_test_data, PAGE_SIZE, nand_read_data);
   for(uint16_t i = 0; i < PAGE_SIZE; i++) {
        if(nand_read_data[i] != nand_flash_test_data[i]) {
            NAND_FLASH_ERR("Nand Flash algorithm result err at [%d]\n", i);
            return NAND_FLASH_STA_OK;
}
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00030000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {
   .ANY (+RW +ZI)
  }
}

LR_ROM1 0x70000000 0x08000000  {
  ER_ROM1 0x70000000 0x08000000  {  ; load address = execution address
   *.o (ExtFlashSec)
  }
}

 

or test as this code(the .sct file can be same with above one, one just delete the last LR_ROM1 part):

 

 

#define NAND_FLASH_TEST_DATA_ADDR   0x70003800      // page5
//The "const" is NOT a must, because we already point the addr.
static const uint8_t nand_flash_test_data[PAGE_SIZE] __attribute__((at(NAND_FLASH_TEST_DATA_ADDR))) = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
};
NAND_FLASH_STA_t NAND_FLASH_algorithm_result_test(void)
{
    LOG_DBG("extFlash data addr[0x%08x]\n", nand_flash_test_data);
    uint8_t nand_read_data[PAGE_SIZE] = {0};
    NAND_FLASH_read_page(NAND_FLASH_TEST_DATA_ADDR, PAGE_SIZE, nand_read_data);
   for(uint16_t i = 0; i < PAGE_SIZE; i++) {
        if(nand_read_data[i] != nand_flash_test_data[i]) {
            NAND_FLASH_ERR("Nand Flash algorithm result err at [%d]\n", i);
            return NAND_FLASH_STA_OK;
}

 

Junde
Senior II

I find a template project with FMC config in the MDK install path: 

D:\keil5_ARM\Packs\Keil\STM32H7xx_DFP\3.1.1\CMSIS\Flash\STM32H750_FMC
Junde
Senior II

I am sorry, the last solution proved does NOT work...

but this one can work well, I found the way by referring HERE.