lpcware

flash write after wakeup from deep-sleep

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by tbelo on Fri Feb 14 05:48:41 MST 2014
Hi all,

I'm experiencing the following issue that I haven't managed to overtake.

On lpc1115 I use flash write for some variables. Whanever I write to flash in the beggining of the program (before deep sleep) it works well. Whenever I flash write after wakeup from deepsleep the mcu hungs.

I include some important parts of the code if someone has the time to examine:

Note that after wakeup I use the systeminit(); function (the one from the examples).



#define CLOCK_SETUP           1
#define SYSCLK_SETUP          1
#define SYSOSC_SETUP          0
#define SYSOSCCTRL_Val        0x00000000
#define WDTOSC_SETUP          0
#define WDTOSCCTRL_Val        0x000000A0
#define SYSPLLCLKSEL_Val      0x00000000
#define SYSPLL_SETUP          0
#define SYSPLLCTRL_Val        0x00000023
#define MAINCLKSEL_Val        0x00000000
#define SYSAHBCLKDIV_Val      0x00000001
#define AHBCLKCTRL_Val        0x0001005F
#define SSP0CLKDIV_Val        0x00000001
#define UARTCLKDIV_Val        0x00000001
#define SSP1CLKDIV_Val        0x00000000



typedef struct eeprom {
signed long calMin;
signed long calMax;
char password[PASSWORDSIZE];
char phoneNo[PHONENOSIZE];
char testPhoneNo[TESTPHONENOSIZE];
char testSmsMsg[TESTSMSMSGSIZE];
char ussdCommand[USSDCOMMANDSIZE];
char wakeUpTime[WAKEUPTIMESIZE];
char apn[APNSIZE];
char timezone[TIMEZONESIZE];
} eeprom_data;
eeprom_data  my_eeprom_data;


void sc_write_conf(eeprom_data *eeprom) {
        IAP iap_entry;
        iap_entry = (IAP)IAP_LOCATION;

        unsigned int iapCommand[5] = {0};
        unsigned int iapResult[4] = {0};
        uint32_t write_buffer[64] = {0}; /* 256 byte block min write size */

        /* prepare for erase */
        iapCommand[0] = 50;                                     // command to prepare
        iapCommand[1] = 7;                                      // from sector 7
        iapCommand[2] = 7;                                      // to sector 7
        iap_entry (iapCommand, iapResult);      // send the commands
        delayMs(1);

        /* do the erase */
        iapCommand[0] = 52;                                     // command to erase
        iapCommand[1] = 7;                                      // from sector 7
        iapCommand[2] = 7;                                      // to sector 7
        iapCommand[3] = 12000;                          // clock rate in khz
        iap_entry (iapCommand, iapResult);      // send the commands
        delayMs(120);                                     // wait for it to be done

        /* prepare for write */
        iapCommand[0] = 50;                                     // command to prepare
        iapCommand[1] = 7;                                      // from sector 7
        iapCommand[2] = 7;                                      // to sector 7
        iap_entry (iapCommand, iapResult);      // send the commands
        delayMs(1);

        memcpy(write_buffer, eeprom, sizeof(eeprom_data));

        /* actually do the write */
        iapCommand[0] = 51;                                     // write to flash command
        iapCommand[1] = 0x00007000;                     // write starting from this flash address
        iapCommand[2] = (uint32_t)(&write_buffer);              // read from this memory address
        iapCommand[3] = 256;                            // 256 bytes is the minimum size we can write to at once
        iapCommand[4] = 12000;                          // clock speed in khz - 12000
        iap_entry (iapCommand, iapResult);
        delayMs(100);
}



void deepSleep (uint32_t match, uint16_t alarmSensor)
{
configSleepIos(alarmSensor);//todo:

    LPC_SYSCON->SYSAHBCLKCTRL       = /* Enable SYSCLK Peripherals, SYS Clock CANNOT BE DISABLED */
                                                                    (1<<2)         //RAM
                                                                    |(1<<3)         //FLASHREG
                                                                    |(1<<4)         //FLASHARRAY
                                                                    |(1<<6)         //GPIO
                                                                    |(1<<7)         //CT16B0
//                                                                    |(1<<9)         //CT32B0
//                                                                    |(1<<12)         //uart
                                                                    |(1<<16)        //IOCON
                                                            ;
//    LPC_SYSCON->SYSAHBCLKCTRL       = 0x215;

    LPC_SYSCON->SYSAHBCLKDIV = 1;

//     /* timer 16 port0.8*/
    LPC_SYSCON->STARTAPRP0          |=      (1<<(8));       // Rising edge
    LPC_SYSCON->STARTRSRP0CLR       |=      (1<<(8));       // Clear pending bit, the STARTRSRP0CLR register resets the start logic state
    LPC_SYSCON->STARTERP0           |=      (1<<(8));       // Enable Start Logic, Enable start signal for start logic input PIO0_n: PIO0_11
    NVIC_EnableIRQ(WAKEUP8_IRQn);

    if (alarmSensor){
/* pio1_0 tilt */
LPC_SYSCON->STARTAPRP0          |=      (1<<(12));
LPC_SYSCON->STARTRSRP0CLR       |=      (1<<(12));
LPC_SYSCON->STARTERP0           |=      (1<<(12));
NVIC_EnableIRQ(WAKEUP12_IRQn);
}
else
LPC_SYSCON->STARTERP0           &=      ~(1<<(12)); //disable start logic for tilt input

#if ENABLE_CLKOUT
        /* Output the Clk onto the CLKOUT Pin PIO0_1 to monitor the freq on a scope */
        LPC_IOCON->PIO0_1       = (1<<0);
        /* Select the MAIN clock as the clock out selection since it's driving the core */
        LPC_SYSCON->CLKOUTCLKSEL = 3;
        /* Set CLKOUTDIV to 10 */
        LPC_SYSCON->CLKOUTDIV = 10;
        /* Enable CLKOUT */
        LPC_SYSCON->CLKOUTUEN = 0;
        LPC_SYSCON->CLKOUTUEN = 1;
        while (!(LPC_SYSCON->CLKOUTUEN & 0x01));
#endif /* ENABLE_CLKOUT */


    Init_Timer(0, 19600, match);//60=1 minute,9350

    LPC_SYSCON->SSP0CLKDIV = 0;
    LPC_SYSCON->SSP1CLKDIV = 0;
    LPC_SYSCON->UARTCLKDIV = 0;
    LPC_SYSCON->WDTCLKDIV = 0;
    LPC_SYSCON->SYSTICKCLKDIV = 0;

    LPC_SYSCON->PDRUNCFG &= ~(1<<6);

    LPC_SYSCON->WDTOSCCTRL = (0x1<<5) | 0x1F;       //SLOWEST WDT FREQ, 0.6 MHz | Select divider for Fclkana=64  -> 9.35khz

    LPC_SYSCON->MAINCLKSEL  = 2;    //0x2 WDT oscillator
    LPC_SYSCON->MAINCLKUEN  = 0;
    LPC_SYSCON->MAINCLKUEN  = 1;
    while (!(LPC_SYSCON->MAINCLKUEN & 0x01));

    LPC_SYSCON->PDRUNCFG = 0xED00;//0xEDBF;

LPC_TMR16B0->TCR = (1<<0);

LPC_PMU->PCON |= (1<<8);

    LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;  //Wake-up configuration register = Power-down configuration register

LPC_SYSCON->PDSLEEPCFG  =  0x000018BF;//WDT ENABLED AND BOD OFF

/* Specify Deep Sleep mode before entering mode */
   SCB->SCR |= (1<<2);

__WFI();
return;
}

void WAKEUP_IRQHandler(void){
/*CLEAR sleepdeep bit */
SCB->SCR&=~(1<<2);

/* Clear the match output register value */
LPC_TMR16B0->EMR  &= ~(1<<0);

/* Disable and Reset Timer */
LPC_TMR16B0->TCR = (1<<1);

uint32_t regVal;
regVal = LPC_SYSCON->STARTSRP0;
  if ((regVal & (1 << 8)) != 0){
  LPC_SYSCON->STARTRSRP0CLR|=(1<<(8));
  LPC_SYSCON->STARTRSRP0CLR|=(1<<(12));

  if (wakeFromAlarmFlag>0 && wakeFromAlarmFlag<3)
  wakeFromAlarmFlag++;
  else wakeFromAlarmFlag=0;

  }
  else {
  LPC_SYSCON->STARTRSRP0CLR|=(1<<(12)); //AD1 TILT
  wakeFromAlarmFlag++;
  }

  NVIC_DisableIRQ(WAKEUP8_IRQn);
  NVIC_DisableIRQ(WAKEUP12_IRQn);
  NVIC_ClearPendingIRQ(WAKEUP12_IRQn);
  NVIC_ClearPendingIRQ(WAKEUP8_IRQn);

return;
}

Outcomes