I'm developing some simple wireless temperature sensors based on NRF51822s. In essence, they take a temperature measurement from a sensor over TWI, send it to a base-station using the micro_esb libraries, and then go into SYSTEM ON sleep for a period, before waking up and repeating. All without softdevice.
I've written code to do just the radio / sleeping part, which successfully puts the NRF51822 into SYSTEM ON with a current usage of ~3uA (incl. about 0.5uA for the temp sensor (also sleeping)). When I add into the code to read the temperature, the sleep mode uses ~230uA. I suspect I am not stopping and disabling the TWI correctly.
The code includes a command to disable TWI before sleeping:
NRF_TWI1->ENABLE= TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
Should I be 'stopping' TWI first? And if so, with what command? Is it:
NRF_TWI1->TASKS_STOP=1;
I have also seen the following command used in some people's code. Is it part of the solution?
NRF_TWI1->POWER = 0;
Any advice on the correct sequence of commands to shutdown TWI (and wake it up after SYSTEM ON sleep) would be really appreciated
UPDATE: another thought, i'm also using pull-ups on some of the pins - could this cause the additional ~200uA of current drain? If so, what state should I try and leave the pins in before going into SYSTEM ON sleep if I want to minimise current usage?
main loop code below:
while (true)
{
ackd=false;
// -------------- SENSE ---------------------
twi_master_init();
// Trigger a one-shot conversion from the temperature sensor
write_buffer[0]=1; // i.e. Configuration register
write_buffer[1]=129; // MSB 128=OS bit, 1=SD bit
write_buffer[2]=0; // LSB
if(twi_master_transfer(TMP102_ADDRESS , write_buffer, 3, TWI_ISSUE_STOP)){
}
// Wait for OS bit to be re-set to 1 to signal end of conversion
data_buffer[0]=0;
while (data_buffer[0] && 128!=128) {
if (twi_master_transfer(TMP102_ADDRESS | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP)) {
}
}
// Switch to temperature register (from config register)
write_buffer[0]=0; // i.e. Temperature register
write_buffer[1]=0; // MSB?
write_buffer[2]=0; // LSB?
if(twi_master_transfer(TMP102_ADDRESS , write_buffer, 3, TWI_ISSUE_STOP)){
}
// Read the temperature and place in the payload ready to send
if (twi_master_transfer(TMP102_ADDRESS | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP)) {
tx_payload.data[2] = data_buffer[0];
tx_payload.data[3] = data_buffer[1];
}
// Disable TWI ready for sleep
NRF_TWI1->ENABLE= TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
// -------------- TRANSMIT ---------------------
if(uesb_write_tx_payload(&tx_payload) == UESB_SUCCESS)
{
tx_payload.data[0]++;
}
nrf_delay_ms(10);
// --------------- SLEEP ------------------------
// define length of sleep according to position of SW_TEST switch
if (nrf_gpio_pin_read(SW_TEST)==0) {
NRF_RTC1->CC[0] = 32768;
}
else
{
NRF_RTC1->CC[0] = 32768*60*5;
}
// Start the RTC timer
NRF_RTC1->TASKS_START = 1;
// shut down the high-frequency clock
NRF_CLOCK->TASKS_HFCLKSTOP = 1;
awake=false;
while(!awake)
{
// Enter System ON sleep mode
__WFE();
// Make sure any pending events are cleared
__SEV();
__WFE();
}
// Stop and clear the RTC timer
NRF_RTC1->TASKS_STOP = 1;
NRF_RTC1->TASKS_CLEAR = 1;
// Restart the hi-frequency clock
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
}