cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401RE Hangs working with 1BPP

CFern.1724
Associate II

Hi, TouchGFX community

I'm trying to get TouchGFX working on a STM32F401RE device with a 200x200 screen.

I've created a simple project with one screen and text as 1bit color depth (Idither_algorithm := 2, opaque_image_format := BW, non_opaque_image_format := BW on app.mk) and I use these configuration on BoardConfiguration.cpp:

uint8_t frameBuffer[5000]; //200 * 200 / 8

uint32_t frameBuf0 = (uint32_t)& frameBuffer[0];

namespace touchgfx

{

NoDMA dma;

NoTouchController tc;

LCD1bpp display;

void touchgfx_init()

{

  HAL& hal = touchgfx_generic_init<MyFakeHAL>(dma, display, tc, 200, 200, 0, 0);

  hal.setFrameBufferStartAddress((uint8_t*)frameBuf0, 1, false, false);

  hal.registerTaskDelayFunction(&OSWrappers::taskDelay);

   // Enable strategy.

   hal.setFrameRefreshStrategy(HAL::REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL);

  hal.setFrameRateCompensation(false);

  hal.lockDMAToFrontPorch(false);

}

I think that framebuffer big is enough for a 1 bit per pixel ( 200 * 200 / 8 bytes). Everything compiles OK but at debug system crashes always when trying to draw at touchgfx::LCD1bpp::drawGlyph()

I've seen other examples and they always use uint16 [width *height] arrays for creating the frame buffer, but this should only be needed in case of 16BPP. Its also needed for working with 1BPP? If not, what's happening?

Thanks,

1 ACCEPTED SOLUTION

Accepted Solutions
CFern.1724
Associate II

Hi Martin,

I've found the origin of the error. Despite configuring my TouchGFX as 1bpp, when text is added the default font is set as 4bpp, that was the origin of the error.

Thanks,

View solution in original post

11 REPLIES 11
Martin KJELDSEN
Chief III

How did you create the project?

Where are your Glyphs located? If LCD1 is trying to read data from memory that is not addressable you'll get a hard fault.

Is this what's going on when you debug? "Crash" = Hardfault?

/Martin

CFern.1724
Associate II

Hi Martin,

I import the project from an existing one using Atollic. So, how can I check where are the Glyphs located? And how do I check from where is LCD1 reading?

Also, the system does nor really crash, it ends on and exit() function.

Thanks,

CFern.1724
Associate II

Hi Martin,

I've changed the project to a 175x175 in order to get a uint16_t framebuffer that fits in the inner RAM and I stll get the same error, so it does not seem to be some memory overflow problem.

Here I attach you the image of the current function where my code gets stuck (exit() function in syscall after LCD1bpp:drawGlyph())

0690X00000AsVmTQAV.jpg

Martin KJELDSEN
Chief III

Check your linker script. Here's an example from EWARM. You can tell here that the linker places this code in Text- and FontFlashSection.

  TextFlashSection       const    0x080085c4     0x14  Texts.o [1]
  .rodata                const    0x080085d8     0x10  screenPresenter.o [1]
  .rodata                const    0x080085e8     0x10  TouchGFXConfiguration.o [1]
  .rodata                const    0x080085f8     0x10  TextProvider.o [8]
  .rodata                const    0x08008608     0x10  TextProvider.o [8]
  .rodata                const    0x08008618     0x10  TextProvider.o [8]
  .rodata                const    0x08008628     0x10  TextProvider.o [8]
  .text                  ro code  0x08008638     0x10  startup_stm32f746xx.o [1]
  .text                  ro code  0x08008648     0x10  TouchGFXGeneratedHAL.o [1]
  FontFlashSection       const    0x08008658     0x10  Kerning_verdana_20_4bpp.o [1]
  FontFlashSection       const    0x08008668     0x10  Table_verdana_10_4bpp.o [1]
  FontFlashSection       const    0x08008678     0x10  Table_verdana_40_4bpp.o [1]
  .rodata                const    0x08008688      0xc  TextProvider.o [8]

Default is internal flash, but you can manipulate where they're placed by naming this section in your linker script e.g..

define symbol __region_QSPI_start__ = 0x90000000;
define symbol __region_QSPI_end__   = 0x90FFFFFF;
 
define region QSPI_region   = mem:[from __region_QSPI_start__ to __region_QSPI_end__];
place in QSPI_region { section ExtFlashSection };

Check your linker script - If you're expecting something to be in external flash, like QSPI, but you have not configured QSPI properly - Maybe it is not addressable, then you're in trouble.

/Martin

CFern.1724
Associate II

Hi Martin,

Looking on other projects that are working I found the "Override default buffer" on TouchGFX editor. I've checked it and settled to 5000 Bytes and now system does not exit on Glyph function, now execution arrives to my void MyFakeHAL::flushFrameBuffer(const touchgfx::Rect& rect) function that links TouchGFX to my screen flush process.

What could be happening here, I do not understand what does this "Override default buffer" function.

Thanks,

Martin KJELDSEN
Chief III

"Override" just means that you specify the size of the buffer rather than using the default size given by the designer.

/Martin

CFern.1724
Associate II

Sorry Martin,

It was an error from my side, the project wich I was working had an empty screen, that's why there was no error on glyph. But now I've added text to it and its crashing again.

It crashes on LCD1bpp::drawGlyph() inside __assert_func()

I've taken a look at my linker script, but it's not even like the one you post here. I attach my .ld here:

/*
*****************************************************************************
**
**  File        : stm32_flash.ld
**
**  Abstract    : Linker script for STM32F401RE Device with
**                512KByte FLASH, 96KByte RAM
**
**                Set heap size, stack size and stack location according
**                to application requirements.
**
**                Set memory bank area and size if external memory is used.
**
**  Target      : STMicroelectronics STM32
**
**  Environment : Atollic TrueSTUDIO(R)
**
**  Distribution: The file is distributed "as is", without any warranty
**                of any kind.
**
**  (c)Copyright Atollic AB.
**  You may use this file as-is or modify it according to the needs of your
**  project. This file may only be built (assembled or compiled and linked)
**  using the Atollic TrueSTUDIO(R) product. The use of this file together
**  with other tools than Atollic TrueSTUDIO(R) is not permitted.
**
*****************************************************************************
*/
 
/* Entry Point */
ENTRY(Reset_Handler)
 
/* Highest address of the user mode stack */
_estack = 0x20018000;    /* end of 96K RAM */
 
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */
 
/* Specify the memory areas */
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 512K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 96K
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
  CCMRAM (rw)     : ORIGIN = 0x10000000, LENGTH = 64K
}
 
/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH
 
  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)
 
    KEEP (*(.init))
    KEEP (*(.fini))
 
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH
 
  /* Constant data goes into FLASH */
  .rodata :
  {
    . = ALIGN(4);
    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
    . = ALIGN(4);
  } >FLASH
 
  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH
 
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH
  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH
  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >FLASH
 
  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);
 
  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
 
    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */
  } >RAM AT> FLASH
  
  _siccmram = LOADADDR(.ccmram);
 
  /* CCM-RAM section 
  * 
  * IMPORTANT NOTE! 
  * If initialized variables will be placed in this section, 
  * the startup code needs to be modified to copy the init-values.  
  */
  .ccmram :
  {
    . = ALIGN(4);
    _sccmram = .;       /* create a global symbol at ccmram start */
    *(.ccmram)
    *(.ccmram*)
    
    . = ALIGN(4);
    _eccmram = .;       /* create a global symbol at ccmram end */
  } >CCMRAM AT> FLASH
 
  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss secion */
    _sbss = .;         /* define a global symbol at bss start */
    __bss_start__ = _sbss;
    *(.bss)
    *(.bss*)
    *(COMMON)
 
    . = ALIGN(4);
    _ebss = .;         /* define a global symbol at bss end */
    __bss_end__ = _ebss;
  } >RAM
 
  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    . = ALIGN(4);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Heap_Size;
    . = . + _Min_Stack_Size;
    . = ALIGN(4);
  } >RAM
 
  /* MEMORY_bank1 section, code must be located here explicitly            */
  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
  .memory_b1_text :
  {
    *(.mb1text)        /* .mb1text sections (code) */
    *(.mb1text*)       /* .mb1text* sections (code)  */
    *(.mb1rodata)      /* read-only data (constants) */
    *(.mb1rodata*)
  } >MEMORY_B1
 
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }
 
  .ARM.attributes 0 : { *(.ARM.attributes) }
}

CFern.1724
Associate II

Hi Martin,

I've found the origin of the error. Despite configuring my TouchGFX as 1bpp, when text is added the default font is set as 4bpp, that was the origin of the error.

Thanks,

Ofcourse - nice catch 🙂