Wake-up function using RTC1. This revision, current consumption is around 80uA at deep sleep mode and this is not enough!! I cannot reduce it until today. This is a temporary revision which I need your help.

Dependents:   BLE_LoopbackUART_low_pwr_w_RTC1 BLE_Uart_Server

Please refer following notebook.
/users/kenjiArai/notebook/ty51822r3-current-consumption-using-nrf51_wakeup-l/#

nRF51_WakeUp.cpp

Committer:
kenjiArai
Date:
2016-06-11
Revision:
1:cc54cd1df555
Parent:
0:f50677171f2d

File content as of revision 1:cc54cd1df555:

/*
 * mbed library program
 *  Wake-Up function only at Sleep mode
 *
 * Copyright (c) 2016 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created:    March     24th, 2016
 *      Revised:    June      11th, 2016
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "nRF51_WakeUp.h"

#define MAX_RTC_TASKS_DELAY     47  // Maximum delay until an RTC task is executed

nRF51_WakeUp::nRF51_WakeUp(PinName p_trigger, PinName p_interrupt):
                           _pin0(p_trigger), _pin1(p_interrupt), _pin2(p_interrupt)
{
    _pin0 = 0;                  // Trigger output
    _pin2.mode(PullDown);       // Interrupt
    p_name_trgr = p_trigger;    // keep pin name(number)
}

void nRF51_WakeUp::set_and_wait(uint32_t t_sec){
    //----- Set interrupt condition and calling routine ---
    _pin1.rise(this, &nRF51_WakeUp::action4restart);
    //----- Set wakeup timer using RTC1 -------------------
    NVIC_ClearPendingIRQ(RTC1_IRQn);
    NVIC_DisableIRQ(RTC1_IRQn);
    NRF_RTC1->TASKS_STOP  = 1;
    nrf_delay_us(MAX_RTC_TASKS_DELAY);
    NRF_RTC1->TASKS_CLEAR = 1;
    nrf_delay_us(MAX_RTC_TASKS_DELAY);
    NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
    NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
    NRF_RTC1->INTENCLR = RTC_INTENSET_OVRFLW_Msk;
    NRF_RTC1->EVTENCLR = RTC_EVTEN_OVRFLW_Msk;
    NRF_RTC1->EVENTS_COMPARE[0] = 0;
    NRF_RTC1->EVTENCLR = 0x000f0003; // all clear
    NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk;
    do {
        NRF_RTC1->PRESCALER = 4095;
    } while (NRF_RTC1->PRESCALER != 4095);
    // Set wake-up time
    NRF_RTC1->CC[0] = t_sec * 8;   // 125mS clock -> seconds (1Sec/125mS = 8)
    //----- Connection RTC1 trigger to Interrupt pin ------
    // GPIOE
    NRF_GPIOTE->CONFIG[0] =
          (GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos)
        | (p_name_trgr << GPIOTE_CONFIG_PSEL_Pos)
        | (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos);
    // Set PPI
    NRF_PPI->CH[0].EEP = (uint32_t)&NRF_RTC1->EVENTS_COMPARE[0];
    NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];
    // Enable only PPI channels 0
    NRF_PPI->CHEN = PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos;
    //----- Start RTC1 for next wake-up -------------------
    NRF_RTC1->TASKS_START = 1;
    nrf_delay_us(MAX_RTC_TASKS_DELAY);
    //----- Goto Deep Sleep mode --------------------------
    // RADIO
    NRF_RADIO->POWER            = 0;
    nrf_delay_us(5);
    // UART
    NRF_UART0->POWER            = 0;
    nrf_delay_us(5);
    // I2C
    NRF_TWI1->POWER             = 0;
    nrf_delay_us(5);
    // SPI
    NRF_SPI0->POWER             = 0;
    nrf_delay_us(5);
    NRF_SPI1->POWER             = 0;
    nrf_delay_us(5);
    NRF_SPIS1->POWER            = 0;
    nrf_delay_us(5);
    // PWM(Timer0,1,2)
    NRF_TIMER0->POWER           = 0;
    nrf_delay_us(5);
    NRF_TIMER1->POWER           = 0;
    nrf_delay_us(5);
    NRF_TIMER2->POWER           = 0;
    nrf_delay_us(5);
    // PPI (use CH[0])
    NRF_PPI->TASKS_CHG[1].DIS   = 1;
    NRF_PPI->TASKS_CHG[2].DIS   = 1;
    NRF_PPI->TASKS_CHG[3].DIS   = 1;
    for (uint8_t n = 1; n <16 ; n++){
        NRF_PPI->CH[n].TEP = 0;
        NRF_PPI->CH[n].EEP = 0;
    }
    // ADC
    NRF_ADC->POWER              = 0;
    nrf_delay_us(5);
    // Temperature senosr
    NRF_TEMP->TASKS_STOP        = 1;
    nrf_delay_us(5);
    // Others
    NRF_RNG->POWER              = 0;
    NRF_ECB->POWER              = 0;
    NRF_AAR->POWER              = 0;
    NRF_CCM->POWER              = 0;
    NRF_WDT->POWER              = 0;
    NRF_QDEC->POWER             = 0;
    NRF_LPCOMP->POWER           = 0;
    // Cock & Power
    NRF_CLOCK->TASKS_HFCLKSTOP  = 1;
    NRF_POWER->DCDCEN           = 0;
    //sd_power_system_off();
    //NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter;
    while(true){
        deepsleep();
    }
}

void nRF51_WakeUp::action4restart(void){
    NVIC_SystemReset();
    deepsleep();        // Not come here (Just in case)
}