SPIFI driver initialization failure for LPC54018 microcontroller

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPIFI driver initialization failure for LPC54018 microcontroller

684 Views
FFOXZ
Contributor III

Hello everyone!
I am using the lpcxpresso54018_spifi_polling_transfer example to write a buffer to the external flash (MX25L12835FM2I-10G) and allocate this buffer from address 0x10001000. For the same example for the LPC54628 microcontroller, I was able to write, read and clear the external flash. On the LPC54018 microcontroller, the same example is only working when the code is saved in SRAM and is not working when the code is saved in the external flash.
When saved in the external flash, the code crashes when entering the RESET_PeripheralReset function. So I mapped where the crash is occurring and the result was this:
Clock configuration --> RESET_PeripheralReset --> RESET_SetPeripheralReset --> Within this function, the code enters the "else" and performs the set bit operation on the SYSCON reset register (SYSCON->PRESETCTRLSET[regIndex] = bitMask) and this is where the crash occurs. After this topic, the FW does not continue.
The only answer to this occurrence was: when the code goes to perform the peripheral reset operation, it ends up resetting the external flash itself and therefore cannot "call" it back. Literally, I can summarize it as "pulling the rug out from under itself".
Please, does anyone have a solution for this problem?

Labels (1)
0 Kudos
Reply
5 Replies

507 Views
FFOXZ
Contributor III

Hello @Harry_Zhang !!!

I would like to know if you have any news on this topic?

TKS,

FFOXZ.

0 Kudos
Reply

664 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @FFOXZ 

When the code is stored in external flash, it can't interact directly with the peripheral because the microcontroller is resetting the peripheral during its initialization process.

Here are some potential solutions you can try to:

1. Use Delay: After performing the reset operation, add a delay before accessing the peripheral. This will give the peripheral time to initialize itself after the reset.

2. Check for Peripheral Ready: Before accessing the peripheral, check if it's ready to accept commands. Some peripherals have a status register that indicates whether they are ready or not.

3. Software Initialization: Instead of using hardware reset, try initializing the peripheral manually by writing the necessary configuration values to its registers. This might involve writing the correct clock frequencies, enabling the required features, etc.

Hope this will help you.

BR

hang

644 Views
FFOXZ
Contributor III

Hi @Harry_Zhang!

Following your instructions, I tried to use a delay before the peripheral's reset function, as you can see in the attachment, but I got the same result as before (the microcontroller was frozen).
I used a delay of 1s and also of 10s, and both had no change in the result.
This peripheral has this status check, but can I do this check before the peripheral is even initialized? I haven't done this test yet, but I believe it won't work. Because the peripheral will not be initialized and the lockup occurs before that.
I didn't understand how the software initialization that you mentioned would work, I'm using an example from NXP and I've already made this example work on the LPC54628 microcontroller.

0 Kudos
Reply

621 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @FFOXZ 

I think when the code is executed from the external flash and the external flash itself is reset, the execution is disrupted, causing the program to crash. Here are some possible solutions.

1. Execute Critical Code from SRAM: Ensure that critical sections of the code, especially those involving peripheral resets and flash operations, are executed from SRAM. You can copy these critical functions to SRAM before execution.

2. Modify Linker Script: Modify the linker script to place the functions that handle flash operations and resets in SRAM. This ensures that these functions are not executed from the external flash, preventing the reset issue.

And i will also test the first solution.

Hope this will help you.

BR

Hang

582 Views
FFOXZ
Contributor III

Hello @Harry_Zhang!

So you came to the same conclusion I had reached previously.

I placed the clear, set and reset functions of the fsl_reset driver in SRAM to isolate this part and let it work in SRAM, but the microcontroller still crashed.

Here are the functions I placed in SRAM and the define to enable these functions.

#include <cr_section_macros.h>
//fsl_reset.c
__RAMFUNC(RAM) void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
__RAMFUNC(RAM) void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
__RAMFUNC(RAM) void RESET_PeripheralReset(reset_ip_name_t peripheral);

//fsl_spifi.c
__RAMFUNC(RAM) uint32_t SPIFI_GetInstance(SPIFI_Type *base);
__RAMFUNC(RAM) void SPIFI_GetDefaultConfig(spifi_config_t *config);
__RAMFUNC(RAM) void SPIFI_Init(SPIFI_Type *base, const spifi_config_t *config);
__RAMFUNC(RAM) void SPIFI_Deinit(SPIFI_Type *base);
__RAMFUNC(RAM) void SPIFI_SetCommand(SPIFI_Type *base, spifi_command_t *cmd);
__RAMFUNC(RAM) void SPIFI_SetMemoryCommand(SPIFI_Type *base, spifi_command_t *cmd);
__RAMFUNC(RAM) void SPIFI_WriteDataHalfword(SPIFI_Type *base, uint16_t data);
__RAMFUNC(RAM) uint16_t SPIFI_ReadDataHalfword(SPIFI_Type *base);

//fsl_spifi.h
__RAMFUNC(RAM) static inline void SPIFI_SetCommandAddress(SPIFI_Type *base, uint32_t addr);
__RAMFUNC(RAM) static inline void SPIFI_SetIntermediateData(SPIFI_Type *base, uint32_t val);
__RAMFUNC(RAM) static inline void SPIFI_SetCacheLimit(SPIFI_Type *base, uint32_t val);
__RAMFUNC(RAM) static inline void SPIFI_ResetCommand(SPIFI_Type *base);
__RAMFUNC(RAM) static inline void SPIFI_EnableInterrupt(SPIFI_Type *base, uint32_t mask);
__RAMFUNC(RAM) static inline void SPIFI_DisableInterrupt(SPIFI_Type *base, uint32_t mask);
__RAMFUNC(RAM) static inline uint32_t SPIFI_GetStatusFlag(SPIFI_Type *base);
__RAMFUNC(RAM) static inline void SPIFI_EnableDMA(SPIFI_Type *base, bool enable);
__RAMFUNC(RAM) static inline uint32_t SPIFI_GetDataRegisterAddress(SPIFI_Type *base);
__RAMFUNC(RAM) static inline void SPIFI_WriteData(SPIFI_Type *base, uint32_t data);
__RAMFUNC(RAM) static inline void SPIFI_WriteDataByte(SPIFI_Type *base, uint8_t data);
__RAMFUNC(RAM) static inline uint32_t SPIFI_ReadData(SPIFI_Type *base);
__RAMFUNC(RAM) static inline uint8_t SPIFI_ReadDataByte(SPIFI_Type *base);

 

And here is the forum link I followed to allocate the functions in SRAM.

https://community.nxp.com/t5/LPCXpresso-IDE-FAQs/Relocating-code-from-FLASH-to-RAM/m-p/473993 

I also did a test allocating the entire SPIFI driver in SRAM, just like I did for the reset driver, but it didn't change the result.

When you mentioned modifying the linker script, I didn't quite understand. Would it be possible to explain better how to make this modification to the linker script?

Thanks for now.

0 Kudos
Reply