2019-09-05 08:47 AM
When developing touchGFX applications you tend to get a pretty high memory need.
I'm working with the CubeIDE integration of TouchGFX and tried to add a third screen (with a third background image). I got an error saying that the application would not fit in my FLASH.
After a bit of digging it seems that the linker files don't mention the QSPI at all.
I can add that to the linker files but I would like to know if there is an official way of doing this?
I found some documentation on this but I'm not sure if this is the right way to go about it.
What goes where in the memory and how do I control it? if at all?
Thanks!
Solved! Go to Solution.
2019-09-10 06:39 AM
Having the same issue over here, I don't think its an issue with the contents of the QSPI as the images will display fine when running through the debugger- as configured in the thread by charles. Something about running in debug fixes the issue but if you try to run out of debug then the images are garbage.
Anyone know how debug mode differs from normal? the only thing i can think of is that there will be longer delays.
2019-09-10 08:08 AM
That is quite interesting.. I'm working in debug mode all along and I can't for the life of me get the damn memory to work as expected.
Did you change the linker script in the same way I did?
Did you have problems with adding the external loader as Charles did? I could find it through the list after pressing 'scan' but he mentioned that he was having trouble with that process.
2019-09-10 08:24 AM
Looking with a fresh pair of eyes I could not believe that I could take a complex application example from touchGFX Designer and see it work directly on my F746 board while my painstakingly pieced together code running in CubeIDE would not.
I have now looked into the TouchGFX Designer code and look what I found:
This is the QSPI init code:
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 1;
hqspi.Init.FifoThreshold = 4;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
hqspi.Init.FlashSize = 24;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
A quick look at my (CubeMX generated) code revealed that THEY ARE NOT THE SAME!!!!!!!!!!!!11111oneoneone
Please, can someone verify that this is not just me?
I have now changed my MX_QUADSPI_Init() code for the above one and hey. It works!
I now have external flash programming as part of the debugging routine as per Charles' post mentioned above. No need for external loaders.
I'm still en debug though...
2019-09-10 09:40 AM
I'm posting this for continuity in the thread. This have solved my issue with not being able to load from QSPI outside the debugging environment:
I'm running my application from cubeIDE so that's a prerequisite.
You will need to do the following:
#include <stm32746g_discovery_qspi.h>
6. change your MX_QUADSPI_Init to this:
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 1;
hqspi.Init.FifoThreshold = 4;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
hqspi.Init.FlashSize = 24;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
if (HAL_QSPI_Init(&hqspi) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN QUADSPI_Init 2 */
BSP_QSPI_Init();
BSP_QSPI_MemoryMappedMode();
HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
MPU_Region_InitTypeDef MPU_InitStruct;
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Configure the MPU attributes as WT for QSPI (used 16Mbytes) */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16MB; /* NOTE! Change this if you change QSPI flash size! */
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
The code should be able to compile and debug. Try unplugging the board and plugging it back in. Does it work now?
2019-09-10 10:08 AM
Yep, changed the linker script in the same way, although my QSPI stuff generated with the same parameters as below. I didn't have a problem finding the external loader.
Does your program run properly if you restart the board (i.e. reboots to the correct screen and loads images fine)?
2019-09-10 11:17 AM
Yes, after I implemented the changes in the QSPI init and qspi driver files. Can you see my post below this comment?
2019-09-11 03:32 AM
Worked for me too, thanks!
2019-09-11 03:33 AM
Thank you HP,
Has completely fixed my issues! Knight in shining armour.
2019-09-11 05:33 AM
@George Journeaux and @BPark.3
Nice to know! I was pretty excited when I got my board to run yesterday evening so thank you both for verifying this!
I did a video of the initial configuration for youtube and during the preparation of that (remember the step where you copy the touchscreen driver?) there is also a qspi driver, but in the original video Martin deletes those files.
I had to delete it too since the video guide I did only covers the initial config with internal memory.
Seeing this it raises another question - the SDRAM driver is also not loaded. could it be possible to run without external SDRAM? That would make a PCB design even cheaper :)
2019-09-12 12:06 AM
Yeah, you have to enable SDRAM bank 1 in CubeMX and then tell your LTDC layer + TouchGFX 1 to use the start of SDRAM. It is possibe to use internal as well, no problem. Instead of providing an address you just declare an array (framebuffer) in internal ram and provide that address instead.
/Martin