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

Sleep current: disabling TWI, pull-ups?

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);	
			
			
}
Parents
  • Thanks for taking a look Ole. The code that I pasted into the original post above was just a snippet - I was starting the LFCLK outside of this loop, so I also included he commands to start it within the loop, just before the command to start the RTC1 timer. Unfortunately I still measure current draw of ~240uA.

    I am now wondering whether there is something else that I am doing, outside of this loop, which is causing the problem, so have pasted the whole of my main.c below. Very grateful if you had the time to take a look - I'm getting close to giving up :/

    (Apologies for weird formatting of the code - the website doesn't seem to like <>s- happy to email you a raw copy if that would help)

    Gavin

    ////////////////////// Includes and defines ///////////////////
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include "micro_esb.h"
    #include "uesb_error_codes.h"
    #include "nrf51.h"
    #include "nrf_delay.h"
    #include "twi_master.h"
    #include "nrf_gpio.h"
    
    #define TMP102_ADDRESS 0x90 
    
    #define LED_RED        5
    #define LED_AMB        4
    #define LED_GRN        3
    #define SW_LED		2
    #define SW_TEST   1
    
    
    
    /////////////////////////// Globals ///////////////////////////
    
    static uesb_payload_t tx_payload, rx_payload;
    bool ackd;
    bool awake;
    
    /////////////////////////// Support routines /////////////////////
    
    void uesb_event_handler()
    {
        static uint32_t rf_interrupts;
        static uint32_t tx_attempts;
        
        uesb_get_clear_interrupts(&rf_interrupts);
        
        if(rf_interrupts & UESB_INT_TX_SUCCESS_MSK)
        {   
    		ackd=true;
    		// flash green LED if switch 2 set to ON
    		if (nrf_gpio_pin_read(SW_LED)==0) {	
    			nrf_gpio_pin_set(LED_GRN);
    			nrf_delay_ms(25);
    			nrf_gpio_pin_clear(LED_GRN);			
    		}
    	}
        
        if(rf_interrupts & UESB_INT_TX_FAILED_MSK)
        {
            uesb_flush_tx();
    		// flash red LED if switch 2 set to ON
    		if (nrf_gpio_pin_read(SW_LED)==0) {	
    			nrf_gpio_pin_set(LED_RED);
    			nrf_delay_ms(25);
    			nrf_gpio_pin_clear(LED_RED);
    		}
        }
        
        if(rf_interrupts & UESB_INT_RX_DR_MSK)
        {
            uesb_read_rx_payload(&rx_payload);
            NRF_GPIO->OUTCLR = 0xFUL << 8;
            NRF_GPIO->OUTSET = (uint32_t)((rx_payload.data[2] & 0x0F) << 8);
        }
        
        uesb_get_tx_attempts(&tx_attempts);
        NRF_GPIO->OUTCLR = 0xFUL << 12;
        NRF_GPIO->OUTSET = (tx_attempts & 0x0F) << 12;
    }
    
    void RTC1_IRQHandler(void)
    {
    // This handler will be run after wakeup from system ON (RTC wakeup)
    	if(NRF_RTC1->EVENTS_COMPARE[0])
    	{
    		NRF_RTC1->EVENTS_COMPARE[0] = 0;
    		awake=true;
    		NRF_RTC1->TASKS_CLEAR = 1;
    	}
    }
    
    /////////////////////////// Main  /////////////////////////////////
    
    int main(void)
    {
    	
    	// Declarations and initiations
    	uint8_t write_buffer[3];
    	uint8_t data_buffer[2];
    	uint8_t power;
    	power=0;
    			
    	// Set LED pins to high drive
    	NRF_GPIO->PIN_CNF[LED_RED] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
    																| (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos)
    																| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
    																| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
    																| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
    	NRF_GPIO->PIN_CNF[LED_AMB] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
    																| (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos)
    																| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
    																| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
    																| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
    	NRF_GPIO->PIN_CNF[LED_GRN] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
    																| (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos)
    																| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
    																| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
    																| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
    	
    	// Set switches as inputs pulled high
    	nrf_gpio_cfg_input(SW_LED,NRF_GPIO_PIN_PULLUP);
    	nrf_gpio_cfg_input(SW_TEST,NRF_GPIO_PIN_PULLUP);
    	
    	
    	// Put power up high for testing purposes
    	uesb_set_tx_power(UESB_TX_POWER_4DBM);
    
    	// Set receive address
    	uint8_t rx_addr_p0[] = {0xD2, 0xF0, 0xF0, 0xF0, 0xF0};
    	uint8_t rx_addr_p1[] = {0xE1, 0xF0, 0xF0, 0xF0, 0xF0};
    	uint8_t rx_addr_p2   = 0x66;	
    
    	// Start the high-frequency clock - we'll need it for the radio
    	NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    	NRF_CLOCK->TASKS_HFCLKSTART = 1;
    	while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);	
    
    	// Configure the radio
    	uesb_config_t uesb_config       = UESB_DEFAULT_CONFIG;
    	uesb_config.rf_channel          = 5;
    	uesb_config.crc                 = UESB_CRC_16BIT;
    	uesb_config.retransmit_count    = 6;
    	uesb_config.retransmit_delay    = 500;
    	uesb_config.dynamic_ack_enabled = true;
    	uesb_config.protocol            = UESB_PROTOCOL_ESB_DPL;
    	uesb_config.bitrate             = UESB_BITRATE_1MBPS;
    	uesb_config.event_handler       = uesb_event_handler;
    	
    	uesb_init(&uesb_config);
    	uesb_set_address(UESB_ADDRESS_PIPE0, rx_addr_p0);
    	uesb_set_address(UESB_ADDRESS_PIPE1, rx_addr_p1);
    	uesb_set_address(UESB_ADDRESS_PIPE2, &rx_addr_p2);
    
    	// Load the payload with some dummy information and chip ID
    	tx_payload.length  = 13;
    	tx_payload.pipe    = 0;
    	tx_payload.data[0] = 0x01;
    	tx_payload.data[1] = 0x02;
    	tx_payload.data[2] = 0x03;
    	tx_payload.data[3] = 0x04;
    
    	tx_payload.data[4] = NRF_FICR->DEVICEID[0] & 255;
    	tx_payload.data[5] = (NRF_FICR->DEVICEID[0] >> 8) &255;
    	tx_payload.data[6] = (NRF_FICR->DEVICEID[0] >> 16) &255;;
    	tx_payload.data[7] = (NRF_FICR->DEVICEID[0] >> 24) &255;;
    
    	tx_payload.data[8] = NRF_FICR->DEVICEID[1] & 255;
    	tx_payload.data[9] = (NRF_FICR->DEVICEID[1] >> 8) &255;
    	tx_payload.data[10] = (NRF_FICR->DEVICEID[1] >> 16) &255;;
    	tx_payload.data[11] = (NRF_FICR->DEVICEID[1] >> 24) &255;;
    	
    	tx_payload.data[12] = power;
    
    
    	// Configure RTC clock for SYSTEM ON sleep
    	
    	// Use internal 32kHz RC
    	NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos;
    	
    	// Start the 32 kHz clock, and wait for the start up to complete
    	NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    	NRF_CLOCK->TASKS_LFCLKSTART = 1;
    	while(NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
    	
    	// Configure the RTC to run at 5 second intervals, and make sure COMPARE0 generates an interrupt (this will be the wakeup source)
    	NRF_RTC1->PRESCALER = 0;
    	NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk; 
    	NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; 
    	NRF_RTC1->CC[0] = 32768;
    	NVIC_EnableIRQ(RTC1_IRQn);
    					
    	// Configure the RAM retention parameters
    	NRF_POWER->RAMON = POWER_RAMON_ONRAM0_RAM0On   << POWER_RAMON_ONRAM0_Pos
    									 | POWER_RAMON_ONRAM1_RAM1Off  << POWER_RAMON_ONRAM1_Pos
    									 | POWER_RAMON_OFFRAM0_RAM0Off << POWER_RAMON_OFFRAM0_Pos
    									 | POWER_RAMON_OFFRAM1_RAM1Off << POWER_RAMON_OFFRAM1_Pos;		 
    
    
    	// Initialise I2C
    	twi_master_init(); 
    
    	// Prepare data that will put TMP sensor into shutdown
    	write_buffer[0]=1; // i.e. Configuration register
    	write_buffer[1]=1; // MSB? 1=SHUTDOWN
    	write_buffer[2]=0; // LSB? 
    
    	if(twi_master_transfer(TMP102_ADDRESS , write_buffer, 3, TWI_ISSUE_STOP)){
    	}
    	
    	// Turn I2C peripheral off (it uses the high-frequency clock, which we will need to turn off later)
    	NRF_TWI1->ENABLE=0;
    	NRF_TWI1->ENABLE          = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
    	
    	// Prepare data that will trigger a one-shot conversion from the tmp sensor
    	write_buffer[0]=1; // i.e. Configuration register
    	write_buffer[1]=128; // MSB? 128=OS bit
    	write_buffer[2]=0; // LSB? 
    	
    	
    ///////////////////////// Main loop //////////////////////////////////
    
    	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];				
    				}
    
    				// Prepare data that will put TMP sensor into shutdown
    				write_buffer[0]=1; // i.e. Configuration register
    				write_buffer[1]=1; // MSB? 1=SHUTDOWN
    				write_buffer[2]=0; // LSB? 
    
    				if(twi_master_transfer(TMP102_ADDRESS , write_buffer, 3, TWI_ISSUE_STOP)){
    				}
    				
    				// 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
    
    				NRF_RTC1->PRESCALER = 0;
    				NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk; 
    				NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; 
    				
    				if (nrf_gpio_pin_read(SW_TEST)==0) {	
    						NRF_RTC1->CC[0] = 32768;				
    				}
    				else
    				{		
    						NRF_RTC1->CC[0] = 32768*60*5;						
    				}				
    
    				NVIC_EnableIRQ(RTC1_IRQn);				
    
    				
    				// Debug option: set switch pins to float? NRF_GPIO_PIN_NOPULL
    				
    				
    				// 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);	
    				
    				
        }
    }
    
  • Many thanks Ole. I finally got the opportunity to sit down with the laptop and a scope and after few things tracked it down to the two pins (SW_LED and SW_TEST) that I was leaving in a pulled-up state when going into SYSTEM ON. By setting to them to NRF_GPIO_PIN_NOPULL before going into sleep, the current usage drops off to ~3uA.

    So the 'main loop' section of the main routine is now:

    	while (true)
    {
        ackd=false;
    
    			// Set switches as inputs pulled high
    			nrf_gpio_cfg_input(SW_LED,NRF_GPIO_PIN_PULLUP);
    			nrf_gpio_cfg_input(SW_TEST,NRF_GPIO_PIN_PULLUP);
    
    		
    		
    			// -------------- 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];				
    			}
    
    			// Prepare data that will put TMP sensor into shutdown
    			write_buffer[0]=1; // i.e. Configuration register
    			write_buffer[1]=1; // MSB? 1=SHUTDOWN
    			write_buffer[2]=0; // LSB? 
    
    			if(twi_master_transfer(TMP102_ADDRESS , write_buffer, 3, TWI_ISSUE_STOP)){
    			}
    			
    			// 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);
    
    			// set switches to NOPULL before going to sleep
    			nrf_gpio_cfg_input(SW_LED, NRF_GPIO_PIN_NOPULL);
    			nrf_gpio_cfg_input(SW_TEST, NRF_GPIO_PIN_NOPULL);
    
    			
    			// --------------- SLEEP ------------------------
    			
    			// define length of sleep according to position of SW_TEST switch
    
    			NRF_RTC1->PRESCALER = 0;
    			NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk; 
    			NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; 
    			
    			if (nrf_gpio_pin_read(SW_TEST)==0) {	
    					NRF_RTC1->CC[0] = 32768;				
    			}
    			else
    			{		
    					NRF_RTC1->CC[0] = 32768*60*5;						
    			}				
    
    			NVIC_EnableIRQ(RTC1_IRQn);				
    
    			
    			// Debug option: set switch pins to float? NRF_GPIO_PIN_NOPULL
    			
    			
    			// 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);	
    			
    			
    }
    
Reply
  • Many thanks Ole. I finally got the opportunity to sit down with the laptop and a scope and after few things tracked it down to the two pins (SW_LED and SW_TEST) that I was leaving in a pulled-up state when going into SYSTEM ON. By setting to them to NRF_GPIO_PIN_NOPULL before going into sleep, the current usage drops off to ~3uA.

    So the 'main loop' section of the main routine is now:

    	while (true)
    {
        ackd=false;
    
    			// Set switches as inputs pulled high
    			nrf_gpio_cfg_input(SW_LED,NRF_GPIO_PIN_PULLUP);
    			nrf_gpio_cfg_input(SW_TEST,NRF_GPIO_PIN_PULLUP);
    
    		
    		
    			// -------------- 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];				
    			}
    
    			// Prepare data that will put TMP sensor into shutdown
    			write_buffer[0]=1; // i.e. Configuration register
    			write_buffer[1]=1; // MSB? 1=SHUTDOWN
    			write_buffer[2]=0; // LSB? 
    
    			if(twi_master_transfer(TMP102_ADDRESS , write_buffer, 3, TWI_ISSUE_STOP)){
    			}
    			
    			// 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);
    
    			// set switches to NOPULL before going to sleep
    			nrf_gpio_cfg_input(SW_LED, NRF_GPIO_PIN_NOPULL);
    			nrf_gpio_cfg_input(SW_TEST, NRF_GPIO_PIN_NOPULL);
    
    			
    			// --------------- SLEEP ------------------------
    			
    			// define length of sleep according to position of SW_TEST switch
    
    			NRF_RTC1->PRESCALER = 0;
    			NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk; 
    			NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; 
    			
    			if (nrf_gpio_pin_read(SW_TEST)==0) {	
    					NRF_RTC1->CC[0] = 32768;				
    			}
    			else
    			{		
    					NRF_RTC1->CC[0] = 32768*60*5;						
    			}				
    
    			NVIC_EnableIRQ(RTC1_IRQn);				
    
    			
    			// Debug option: set switch pins to float? NRF_GPIO_PIN_NOPULL
    			
    			
    			// 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);	
    			
    			
    }
    
Children
No Data
Related