This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to disable SPI to save power - nRF51822 on MBED

Hi,

I have a SPI sensor on an nRF51822, developed in mBED.  To save battery power, I want to disable SPI while in ble.waitForEvent().  The only reference I could find is an nRF call:

NRF_SPI0->ENABLE = 0;

When I do that, two things happen:

1)  Sensor no longer works when I wake up (I need to figure out how to properly re-enable and re-initizlie the sensor)

2)  More importantly, sleep current still at 300uA instead of under 4uA.

Am I improperly disabling SPI with this command?  I found it in the devzone forum, and maybe mBED needs to be performed differently?  I want to solve the power consumption issue first.  I've tested the code when not initilizing the SPI peripheral at all and things work correctly - I get under 4uA with the same sensor still attached.  So I don't think the sensor is consuming that much by itself.  I think the SPI peripheral isn't turning off properly, even though the SPI commands no longer function after wakeup.

This is a cross post on my mBED question here, where I post the code:

https://os.mbed.com/questions/81457/how-to-disable-SPI-for-power-savings-nRF/

#include "mbed.h"
#include "LIS3DH.h"
#include "ble/BLE.h"
 
#define MISO p4
#define CS p3
#define SCLK p7
 
static LIS3DH lis(MOSI, MISO, CS, SCLK);    
float x,y,z;
InterruptIn button1(p1);    //nRF51822 P0.0
 
AxesRaw_t accel_raw; 
bool flag_read_acc;
 
//ISR for I/O interrupt
void button1_int(void)
{
    //set flag on interrupt
    flag_read_acc=1;
 
int main ()
{
    //pc.baud(9600);
    //pc.printf("...started... \n\r");
 
    //Initialize SPI interface
    SPI spi(MOSI, MISO, SCLK); 
    spi.format(8,3);
    spi.frequency(8000000); 
 
    
    BLE &ble = BLE::Instance();
    ble.init(); //using this just for sleep
    
 
    //Initialize LIS3DH driver
    lis.InitLIS3DH(LIS3DH_NORMAL, LIS3DH_ODR_25Hz, LIS3DH_FULLSCALE_2);    //Init Acc-sensor
    //enable threshold to generate interrupt
    lis.SetLIS3DHActivityDetection(10, LIS3DH_INT_MODE_6D_MOVEMENT, 1);
 
    //set interrupt pin
    button1.mode(PullDown);
    button1.rise(button1_int);
    lis.LIS3DH_ResetInt1Latch();
 
    
while (1) { 
    if (flag_read_acc == 1)
    {
        //do stuff in this routine
        flag_read_acc=0;    //reset flag
    }//end if flag
    
    lis.LIS3DH_ResetInt1Latch();    //move this to when you really want to release
    NRF_SPI0->ENABLE = 0;           //disable SPI?
 
    ble.waitForEvent();
    NRF_SPI0->ENABLE = 1;           //re-enable SPI
 
    //Initialize LIS3DH driver
    lis.InitLIS3DH(LIS3DH_NORMAL, LIS3DH_ODR_25Hz, LIS3DH_FULLSCALE_2);    //Init Acc-sensor
    //enable threshold to generate interrupt
    lis.SetLIS3DHActivityDetection(10, LIS3DH_INT_MODE_6D_MOVEMENT, 1);
    
    }//end while
}//end main()

Related