Trying to initialise the SEMC when the M7 core runs with a high clock frequency does lead to a crash of the CPU that I can't recover from (even JTAG doesn't work anymore). A power-cycle is required.
I have set up access to an external SRAM and an exteran SDRAM. Both access work when having the M7 core clock configured to 336 MHz and the SEMC clock to 198 MHz (no SEMC configuration patch). Changing the configured M7 core frequency of the project to 672 MHz does lead to the aforementioned crash.
All clocks are configured once on startup:
SEMC clock config from the MCUXpresso Config Tools:
Working M7 core clock config:
Core M7 clock config that leads to the crash:
The SEMC is configured for SRAM as follows:
void ext_sram_semc_init(void)
{
uint64_t root_clock_hz = CLOCK_GetRootClockFreq(kCLOCK_Root_Semc);
double clock_cycles_per_ns;
semc_config_t sdk_base_config;
semc_sram_cs_t sram_cs_pin;
semc_sram_config_t sdk_sram_config;
memset(&sdk_base_config, 0, sizeof(semc_config_t));
SEMC_GetDefaultConfig(&sdk_base_config);
SEMC_Init(SEMC, &sdk_base_config);
memset(&sdk_sram_config, 0, sizeof(semc_sram_config_t));
sram_cs_pin = kSEMC_SRAM_CS0;
sdk_sram_config.address = 0x98000000;
sdk_sram_config.cePinMux = kSEMC_MUXCSX0;
sdk_sram_config.memsize_kbytes = (512 * 16) / 8; // 8MBit = 512*16*1KBits = 1MB
sdk_sram_config.addrPortWidth = 19; //Address pins A0..A18
sdk_sram_config.advActivePolarity = kSEMC_AdvActiveLow;
sdk_sram_config.addrMode = kSEMC_AddrDataNonMux;
sdk_sram_config.burstLen = kSEMC_Nor_BurstLen1;
sdk_sram_config.portSize = kSEMC_PortSize16Bit;
sdk_sram_config.syncMode = kSEMC_AsyncMode;
sdk_sram_config.waitEnable = false;
sdk_sram_config.waitSample = false;
sdk_sram_config.advLevelCtrl = kSEMC_AdvLow;
sdk_sram_config.tCeSetup_Ns = 0;
sdk_sram_config.tCeHold_Ns = 3;
sdk_sram_config.tCeInterval_Ns = 10;
sdk_sram_config.readHoldTime_Ns = 0xFF;
sdk_sram_config.tAddrSetup_Ns = 0;
sdk_sram_config.tAddrHold_Ns = 10;
sdk_sram_config.tWeLow_Ns = 8;
sdk_sram_config.tWeHigh_Ns = 0;
sdk_sram_config.tReLow_Ns = 6;
sdk_sram_config.tReHigh_Ns = 5;
sdk_sram_config.tTurnAround_Ns = 3;
sdk_sram_config.tAddr2WriteHold_Ns = 0;
sdk_sram_config.tWriteSetup_Ns = 0;
sdk_sram_config.tWriteHold_Ns = 0;
sdk_sram_config.latencyCount = 0;
sdk_sram_config.readCycle = 0;
sdk_sram_config.delayChain = 10;
SEMC_ConfigureSRAMWithChipSelection(SEMC, sram_cs_pin, &sdk_sram_config, root_clock_hz);
}
Why does the CPU crash hard when I use the higher M7 core frequency and try to init the SEMC? The SEMC SDK function calls does finish but the crash happens immediately afterwards. How can I prevent the crash?
Can you please share your project linker file? are you debugging project in XIP Flash? or maybe Internal RAM?
The program is running only in internal flash. XIP isn't used. This here is the linker file:
/* Entry Point */
ENTRY(Reset_Handler)
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x200; /* required amount of stack 0x200 = 512 */
/* Memory areas */
MEMORY
{
m_flexspi_itcm (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000
m_flexspi_dtcm (RW) : ORIGIN = 0x20000000, LENGTH = 0x00040000
m_ocram (RW) : ORIGIN = 0x202C0000, LENGTH = 0x00080000
}
/* Define output sections */
SECTIONS
{
/* Interrupt vectors, startup code -> start of ITCM */
.interrupts :
{
__VECTOR_TABLE = .;
__Vectors = .;
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_flexspi_itcm
/* Program code behind ISR & startup */
.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 */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} > m_flexspi_itcm
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_flexspi_itcm
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_flexspi_itcm
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
__VECTOR_RAM = ORIGIN(m_flexspi_itcm);
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
__TEXT_END = .; /* End of text section */
text_end = ORIGIN(m_flexspi_itcm) + LENGTH(m_flexspi_itcm);
ASSERT(__TEXT_END <= text_end, "region m_flexspi_itcm overflowed with text")
/* Strings and constants into OCRAM */
.text2 :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
_etextrodata = .; /* define a global symbols at end of code */
} > m_ocram
__TEXT_END2 = .; /* End of text section */
ocram_end = ORIGIN(m_ocram) + LENGTH(m_ocram);
ASSERT(__TEXT_END2 <= ocram_end, "region m_ocram overflowed with text")
/* Initialised data */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(m_usb_dma_init_data)
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_flexspi_dtcm
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
/* Uninitialised data */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
. = ALIGN(4);
__START_BSS = .;
__bss_start__ = .;
*(m_usb_dma_noninit_data)
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__END_BSS = .;
} > m_flexspi_dtcm
PROVIDE ( end = __bss_end__ );
PROVIDE ( _end = __bss_end__ );
__NCACHE_REGION_START = ORIGIN(m_ocram);
__NCACHE_REGION_SIZE = 0;
/* Heap + Stack section, used to check that there is enough RAM left */
.heap_stack :
{
. = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
__heap_stack_ = .;
} > m_flexspi_dtcm
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_flexspi_dtcm) + LENGTH(m_flexspi_dtcm);
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__heap_stack_ <= __StackTop, "region m_flexspi_dtcm overflowed with data, stack and heap")
/* Remove information from the standard libraries */
/DISCARD/ :
{
libm.a ( * )
libc.a ( * )
libgcc.a ( * )
}
}