AnsweredAssumed Answered

LPC 546 EEPROM data corruption after deep sleep exit

Question asked by Alex Tepliy on Oct 29, 2019
Latest reply on Nov 1, 2019 by Alex Tepliy

Working with LPC54605J512BD100 encountered a strange problem with on-chip EEPROM. After MCU exiting deep sleep mode and read from EEPROM, data get corrupted.

I used the SDK_2.6.0_LPC54605J512eeprom example and MCUXpresso IDE to demonstrate the problem. The code is straight forward, write data to EEPROM, switch the clock to fro, deep sleep, woke-up by RTC, switch to pll out, and first read returns corrupted data. The next 2 reads are ok, but if perform EEPROM write and try to read back the result will be 0. After that, write-read operations work fine. Here are Log messages.

EEPROM example begins...
EEPROM Write c0de
EEPROM Read Data Before Sleep = c0de
Enter Deep Sleep!
Sleep Time = 100 ms
EEPROM Read Data After Sleep = 99939b08
EEPROM Read Data After Sleep = c0de
EEPROM Read Data After Sleep = c0de
EEPROM Write Data After Sleep 1234
EEPROM Read Data After Sleep = 0
EEPROM Read Data After Sleep = 0
EEPROM Write Data After Sleep 5678
EEPROM Read Data After Sleep = 5678

I'm using libpower_softabi.a. Add project to attachments. 

 

/*******************************************************************************
* Includes
******************************************************************************/
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "board.h"

#include "fsl_eeprom.h"
#include "fsl_power.h"
#include "fsl_rtc.h"

#include "pin_mux.h"
#include <stdbool.h>
/*******************************************************************************
* Definitions
******************************************************************************/
#define EEPROM_SOURCE_CLOCK kCLOCK_BusClk
#define EEPROM_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk)
#define EXAMPLE_EEPROM EEPROM

/*******************************************************************************
* Prototypes
******************************************************************************/
#define FSL_FEATURE_EEPROM_PAGE_SIZE (FSL_FEATURE_EEPROM_SIZE / FSL_FEATURE_EEPROM_PAGE_COUNT)
#define DEEP_SLEEP_ENABLED_PERIPH (SYSCON_PDRUNCFG_PDEN_SRAM0_MASK | SYSCON_PDRUNCFG_PDEN_SRAM1_2_3_MASK |\
SYSCON_PDRUNCFG_PDEN_USB_RAM_MASK | SYSCON_PDRUNCFG_PDEN_SRAMX_MASK)
#define EEPROM_DATA 0xC0DE
#define DEEP_SLEEP_TIME 100U
/*******************************************************************************
* Code
******************************************************************************/
/*!
* @brief Main function
*/
int main(void)
{
eeprom_config_t config;
uint32_t sourceClock_Hz = 0;

/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

BOARD_InitPins();
BOARD_BootClockPLL180M();
BOARD_InitDebugConsole();

PRINTF("EEPROM example begins...\r\n");

/* Init EEPROM */
EEPROM_GetDefaultConfig(&config);
sourceClock_Hz = EEPROM_CLK_FREQ;
EEPROM_Init(EXAMPLE_EEPROM, &config, sourceClock_Hz);

PRINTF("EEPROM Write %x\n", EEPROM_DATA);
EEPROM_WriteWord(EXAMPLE_EEPROM, 0, EEPROM_DATA);

uint32_t readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data Before Sleep = %x\n", readData);

/* Init RTC */
RTC_Init(RTC);
RTC_Reset(RTC);
NVIC_ClearPendingIRQ(RTC_IRQn);
RTC_EnableInterrupts(RTC, RTC_CTRL_WAKEDPD_EN_MASK);
EnableIRQ(RTC_IRQn);
EnableDeepSleepIRQ(RTC_IRQn);

/* Enter Deep Sleep for 100 ms */
BOARD_BootClockFRO12M();

PRINTF("Enter Deep Sleep!\n");
RTC_SetWakeupCount(RTC, DEEP_SLEEP_TIME);
RTC_StartTimer(RTC);
POWER_EnterDeepSleep((uint64_t)(DEEP_SLEEP_ENABLED_PERIPH));
RTC_StopTimer(RTC);
uint16_t sleepCount = DEEP_SLEEP_TIME - RTC_GetWakeupCount(RTC);
PRINTF("Sleep Time = %d ms\n", sleepCount);

BOARD_BootClockPLL180M();

readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data After Sleep = %x\n", readData);

readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data After Sleep = %x\n", readData);

readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data After Sleep = %x\n", readData);

PRINTF("EEPROM Write Data After Sleep %x\n", 0x1234);
EEPROM_WriteWord(EXAMPLE_EEPROM, 0, 0x1234);

readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data After Sleep = %x\n", readData);

readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data After Sleep = %x\n", readData);

PRINTF("EEPROM Write Data After Sleep %x\n", 0x5678);
EEPROM_WriteWord(EXAMPLE_EEPROM, 0, 0x5678);

readData = *((uint32_t *)(FSL_FEATURE_EEPROM_BASE_ADDRESS));
PRINTF("EEPROM Read Data After Sleep = %x\n", readData);

while (1)
{
}
}

void RTC_IRQHandler(void)
{
RTC_ClearStatusFlags(RTC, RTC_CTRL_WAKE1KHZ_MASK);
}

 

Outcomes