2020-02-07 03:41 AM
Hello
i'm using STM32F746G with touchGfx and keil for a project. i have a working empty project (a blank screen with a button). but when i regenerate the project with cubeMX checking the option :"generate peripheral initialization as a pair of '.c/.h/' files per peripheral" i get HardFault Handler. My keil caller stack say is caused by: touchgfx_init ->setLanguage ->hardFault_Handler
2021-07-13 03:20 AM
I've got the same kind of problem using Keil. I've done the following:
I also tried the same with "Generate peripheral initialization as a pair of .c/.h files" disabled, no change. Keil gave one warning that might be related:
.\STM32F746G_DISCO.sct(18): warning: L6314W: No section matches pattern *.o(ExtFlashSection).
I compared the scatter file with the one generated by earlier projects made with v4.16, no difference.
Edit: went back to v4.16 and after a reset of my st-link (with J-LINK firmware) the projects works again, it think the external memory didn't get programmed. Will make a new topic if get further problems and not capture this topic.
2021-07-13 04:07 AM
I'm trying to understand what you are trying to understand ;) because you mentioned the exact bug that is breaking the project - any user code in peripheral init sections gets wiped out when checking the box.
The TouchGFX application templates contain such user code to initialize the QSPI, FMC etc. So when I try to clean up the main file by checking the "c/h pair" box, that all gets erased and my program hardfaults because the QSPI among others isn't initialized.
CubeMX should never remove user code unless the particular module is disabled!
2021-07-13 05:18 AM
What I am trying to understand is if it really is a bug and not just what is intended by CubeMX (i do also agree that CubeMX should never get rid of user code).
By checking the "c/h pair" box you are voluntarily removing the sections that contains that user code and then re initialize it in other c files, you are not moving the code somewhere else. CubeMX will not save the user code somewhere. I guess what you are asking for is that CubeMX saves that peripheral user code or transfers it. I don't know if it is somewhere in the documentation written that this option will not transfer user code. I think this is not really fair to the user as there are no warnings as well. Dont know if it is really a bug but it should be a easy/doable fix I suppose.
I guess what we could do for the TouchGFX application templates (edit: TouchGFX Board Setups, it changed name I have to get used to it :grinning_face_with_sweat:) to prevent facing this issue would be to set that user code elsewhere in the main.c .
/Romain
2021-07-13 05:59 AM
There's no way it's not a bug. Exhibit A: the checkbox two items down that says "Keep User Code when re-generating". That should also cover the situation where one goes from a monster main.c file to individual peripheral files.
"...set that user code elsewhere in the main.c"
Yup, that's probably a good option from the TouchGFX standpoint.
I appreciate your thoughts.
2021-07-13 06:17 AM
Sorry I missed this. The box I checked is highlighted.
2021-07-13 01:19 PM
Check that you are setting the QSPI in Memory-mapped mode in the USER CODE section right at the end of the MX_QUADSPI_Init().
It needs to be set immediately at the end of MX_QUADSPI_Init(), not earlier, and not later.
It was some issues before where "generate peripheral initialization as a pair of '.c/.h/' files per peripheral" would not generate the USER CODE section at the end of the MX_QUADSPI_Init(). But it seems that it is fixed in the last CubeMx version.
You should also check that MX_QUADSPI_Init() is called before MX_TouchGFX_Init();
Your QSPI setup should mostly look like this (config for N25QL128):
void MX_QUADSPI_Init(void)
{
/* USER CODE BEGIN QUADSPI_Init 0 */
/* USER CODE END QUADSPI_Init 0 */
/* USER CODE BEGIN QUADSPI_Init 1 */
/* USER CODE END QUADSPI_Init 1 */
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 1;
hqspi.Init.FifoThreshold = 4;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
hqspi.Init.FlashSize = 23;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_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 */
QSPI_Map();
/* USER CODE END QUADSPI_Init 2 */
}
bool QSPI_Map(void)
{
// Map QSPI
QSPI_CommandTypeDef s_command;
QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
// Configure the command for the read instruction
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = QUAD_INOUT_FAST_READ_CMD;
s_command.AddressMode = QSPI_ADDRESS_4_LINES;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DataMode = QSPI_DATA_4_LINES;
s_command.DummyCycles = N25Q128A_DUMMY_CYCLES_READ_QUAD;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
// Configure the memory mapped mode
s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
return HAL_QSPI_MemoryMapped(&hqspi, &s_command, &s_mem_mapped_cfg) == HAL_OK;
}
2021-07-14 05:19 AM
I agree this is a bug. Of course it should move the user code a long with the rest of the generated code.. We're following up on this.
2021-07-14 05:59 AM
Thanks @Martin KJELDSEN . By the way, the visible presence of you and @Romain DIELEMAN on this forum is really appreciated. You guys always reassure me that we are being heard and that our problems are being taken seriously inside ST.
2021-07-14 06:31 AM
Glad to hear that, @Michael K! <3 We enjoy being here. Community feedback is #1 ! :) Extremely valuable.