SAM3U4E KIT: sleep mode exit problem

Discussion around product based on ARM Cortex M3 core.

Moderators: nferre, ncollot

krunalwin
Posts: 3
Joined: Fri Apr 24, 2015 9:09 am

SAM3U4E KIT: sleep mode exit problem

Wed Jun 10, 2015 11:13 am

Hi all,
I am trying to implement to use SLEEP MODE in my SAM3U4E-KIT.

My effort is to use switch connected at PB2 as normal input to get entered into SLEEP MODE (WFE) and then PB2 itself will be configured as WAKEUP15 to get exited from SLEEP MODE.
I can enter into sleep mode but exit is not being performed upon pressing the switch at PB2.

Following is my code :

Code: Select all

void init_sleep(void)
{
	uint32_t oldPll0;
	//uint32_t oldPll1;
	//uint32_t oldOsc;
	uint32_t oldMck;
	uint32_t oldPeriphClk;
	uint32_t temp;
	ui_com_close();
	
	// Save current working clock
	// SaveWorkingClock(&oldPll, &oldMck);
	oldPll0 = PMC->CKGR_PLLAR;
	oldMck = PMC->PMC_MCKR;
	
    // Save previous values peripheral clock then disable all
    oldPeriphClk = PMC->PMC_PCSR0;
    pmc_disable_all_periph_clk();
	
	// Stop UTMI
	PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN;
		
	// Disable Brownout Detector
	SUPC->SUPC_MR |= (0xA5 << 24) | (0x01 << 13);
	
	// Configure PIO for wakeup
	// PB2(WAKEUP15) has been configured as WAKEUP source.
	// for reference : #define PIN_WAKEUP	PIO_PB2_IDX	 
	// for reference : #define KEYIO_FLAGS	(PIO_INPUT | PIO_DEBOUNCE | PIO_PULLUP | PIO_DEFAULT)
	gpio_configure_pin(PIN_WAKEUP, KEYIO_FLAGS);	
	//supc_set_wakeup_inputs(SUPC, SUPC_WUIR_WKUPEN15_ENABLE, SUPC_WUIR_WKUPT15_HIGH_TO_LOW);
	// set Debounce time for wakeup pin to be detected.
	SUPC->SUPC_WUMR = (SUPC->SUPC_WUMR & (~SUPC_WUMR_WKUPDBC_Msk)) | SUPC_WUMR_WKUPDBC_512_SCLK;
	//SUPC->SUPC_WUMR = (SUPC->SUPC_WUMR & (~SUPC_WUMR_WKUPDBC_Msk)) | SUPC_WUMR_WKUPDBC_4096_SCLK;
	
	    PMC->PMC_FSMR &= ~0xFFFFFFFF;		// This register can only be written if the WPEN bit is cleared in the “PMC Write Protect Mode Register”.
	    PMC->PMC_FSMR |= SUPC_WUIR_WKUPEN15_ENABLE;
		
	 // Switch clock frequency
	 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk)
	 | PMC_MCKR_CSS_SLOW_CLK;
	 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

	 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk)
	 | PMC_MCKR_PRES_CLK_64;
	 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
	 // Stop PLL A
	 // MULA: PLL A Multiplier 0 = The PLL A is deactivated.
	 PMC->CKGR_PLLAR &= ~(CKGR_PLLAR_MULA_Msk);
	 // Stop Main Oscillator
	 PMC->CKGR_MOR = (0x37 << 16) | (0x3F << 8);
	 
	// Enter Sleep Mode
	PMC->PMC_FSMR &= ~PMC_FSMR_LPM;		// LPM=0
	SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;		// SLEEPDEEP =0
	__WFE();
			
	// Restore working clock
		 // Switch to slow clock first
		 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk)
		 | PMC_MCKR_CSS_SLOW_CLK;
		 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

		 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk)
		 | PMC_MCKR_PRES_CLK_1;
		 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
	 
		 // Restart Main Oscillator
		 PMC->CKGR_MOR = (0x37 << 16) | (0x3F<<8) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
		 while (!(PMC->PMC_SR & PMC_SR_MOSCXTS));
		 // Switch to moscsel
		 PMC->CKGR_MOR = (0x37 << 16) | (0x3F<<8) | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
		 while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));

		 // Switch to main oscillator
		 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_CSS_Msk) |
		 PMC_MCKR_CSS_MAIN_CLK;
		 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

		 PMC->PMC_MCKR = (PMC->PMC_MCKR & ~PMC_MCKR_PRES_Msk)
		 | PMC_MCKR_PRES_CLK_1;
		 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

		 // Restart PLL A
		 PMC->CKGR_PLLAR = oldPll0;
		 while(!(PMC->PMC_SR & PMC_SR_LOCKA));

		 // Switch to fast clock
		 PMC->PMC_MCKR = (oldMck & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
		 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));

		 PMC->PMC_MCKR = oldMck;
		 while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
		
	// disable wakeup feature on relevant input pin. and re-configure as normal GPIO input pin.
	supc_set_wakeup_inputs(SUPC, SUPC_WUIR_WKUPEN15_NOT_ENABLE, SUPC_WUIR_WKUPT15_HIGH_TO_LOW);
	//configure_wakeup_input_pin();
		pio_set_writeprotect(WAKEUP_KEY_PORT, 0);	// disable the write protection for the input filter enable register (write protected) to be modified.
		gpio_configure_pin(PIN_WAKEUP, KEYIO_FLAGS);	// configure the input as normal GPIO input (NOT as wakeup input).
		pmc_enable_periph_clk(WAKEUP_KEY_PORTID);		// It is must to enable the PIO clock before setting the debounce time for Input pin.
		pio_set_debounce_filter(WAKEUP_KEY_PORT, (1<< (PIN_WAKEUP & 0x1F)), (1000/DEBOUCE_TIME));
	
	// Restore peripheral clock
	PMC->PMC_PCER0 = oldPeriphClk;
	
	// Start UTMI
	PMC->CKGR_UCKR |= (CKGR_UCKR_UPLLCOUNT_Msk & (3 << 20)) | CKGR_UCKR_UPLLEN;
	while (!(PMC->PMC_SR & PMC_SR_LOCKU));
	
	// Enable Brownout Detector
	temp = SUPC->SUPC_MR & 0x00FFFFFF;
	SUPC->SUPC_MR = (0xA5 << 24) | (temp & (~(0x01 << 13)));
	
	// stay here until wakeup key has been released.
	while(0 == (((WAKEUP_KEY_PORT->PIO_PDSR) >> (PIN_WAKEUP & 0x1F)) & 0x01));
		
}




Kindly suggest me where I am lacking the logic to make it happen.

Your answers may help me a lot.

Update ::

Code: Select all

I solved my problem  but still  I do have little confusion.
I can exit from the SLEEP MODE by replacing following lines
supc_set_wakeup_inputs(SUPC, SUPC_WUIR_WKUPEN15_ENABLE, SUPC_WUIR_WKUPT15_HIGH_TO_LOW);
with

Code: Select all

PMC->PMC_FSMR &= ~0xFFFF;		// This register can only be written if the WPEN bit is cleared in the “PMC Write Protect Mode Register”.
PMC->PMC_FSMR |= PC_WUIR_WKUPEN15_ENABLE;
Is that not enough to enable wakeup function on the relevant pin in the SUPC_WUIR ??

Thanks.

Return to “SAM3 Cortex-M3 MCU”

Who is online

Users browsing this forum: No registered users and 3 guests