4 second current spikes during sleep

Hello All,

I am getting these ~3.5mA current spikes very 4 seconds and I can't seem to figure what the cause of them is. some of the spikes have a single spike/pulse while other have multiple. please see the attached images. I have commented out everything except the while in the main function and no difference. I have also commented out the enabling of the DCDC and still the same issue. any help would be greatly appreciate. I have a feeling its in the project config setting but tried commenting out what I thought may be the cause but no change either. 

I am using a custom board with 52833 and nRF Connect SDK 2.0.0. the board does have other ICs(hall sensors) but I measured their consumption and had no spikes.

while (1) {
		//k_sleep(K_SECONDS(1));
		//k_msleep(500);
		
		__WFE();
}

my project config file



#CONFIG_DK_LIBRARY=y

# Config logger
CONFIG_LOG=n
CONFIG_USE_SEGGER_RTT=n
CONFIG_LOG_BACKEND_RTT=n
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG_DEFAULT_LEVEL=3
CONFIG_DEBUG_OPTIMIZATIONS=n
# CONFIG_LOG_MODE_IMMEDIATE=n


CONFIG_SERIAL=n
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n

# Config Bluetooth
CONFIG_BT=y
##CONFIG_BT_DEBUG_LOG=y
##CONFIG_BT_SMP=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DIS=y
CONFIG_BT_DIS_PNP=n
# CONFIG_BT_BAS=y
# CONFIG_BT_HRS=y
CONFIG_BT_DEVICE_NAME="XXX Sensor"
CONFIG_BT_DEVICE_APPEARANCE=0
#CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_LL_SOFTDEVICE=y
CONFIG_BT_MAX_CONN=1
CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS=y
CONFIG_BT_PERIPHERAL_PREF_MIN_INT=40
CONFIG_BT_PERIPHERAL_PREF_MAX_INT=45

CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_TX_COUNT=10



# CONFIG_CLOCK_CONTROL_NRF_FORCE_ALT=y wh
CONFIG_CLOCK_CONTROL_NRF=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n
# CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL is not set
# CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH is not set
# CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_LOW_SWING is not set
# CONFIG_CLOCK_CONTROL_NRF_K32SRC_EXT_FULL_SWING is not set
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y
CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_LF_ALWAYS_ON=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_500PPM=y
CONFIG_GPIO_AS_PINRESET=n


CONFIG_GPIO=y
CONFIG_GPIO_NRFX=y
CONFIG_NRFX_GPIOTE=y
CONFIG_SPI=y

#CONFIG_ASSERT=y

#CONFIG_NRFX_PRS_BOX_2=y

# CONFIG_NRFX_TIMER0=y
CONFIG_NRFX_TIMER1=y
CONFIG_NRFX_TIMER2=y
CONFIG_NRFX_TIMER3=y
CONFIG_NRFX_TIMER4=y
CONFIG_NRFX_PPI=y
CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS=2
CONFIG_NRFX_SPIM0=y
CONFIG_NRFX_SPIM1=y
CONFIG_COUNTER=y
#CONFIG_COUNTER_TIMER1=y


CONFIG_NRFX_RTC2=y
CONFIG_NRFX_POWER=y




##CONFIG_PM=y
# Required to disable default behavior of deep sleep on timeout
##CONFIG_PM_DEVICE=y
#CONFIG_GPIO=y
# Optional select RAM retention (nRF52 only)
#CONFIG_APP_RETENTION=y








  • Hi Vidar,

    Thank you for your suggestion, but I am not using the 5340 which is what your link, I am using 52833 and SDK 2.0.0.

    with that said, here is my function that initializes the GPIOTE pin

    void configure_imu_int1_gpiote(void)
    {
        nrfx_err_t err = NRFX_SUCCESS;
    
         __ASSERT (!nrfx_gpiote_is_init(),"nrfx_gpiote_is_init Failed");
        
        static const nrfx_gpiote_input_config_t input_config = {
    		.pull = NRF_GPIO_PIN_PULLDOWN,
    	};
    
    	const nrfx_gpiote_trigger_config_t trigger_config = {
    		.trigger = NRFX_GPIOTE_TRIGGER_LOTOHI,
    		.p_in_channel = NULL, //&in_channel,
    	};
    
        err = nrfx_gpiote_input_configure(IMU_INT1_PIN,
    					  &input_config,
    					  &trigger_config,
    					  NULL);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("Failed to nrfx_gpiote_input_configure, error: 0x%08X", err);
    		return;
    	}
    
        //nrfx_gpiote_in_event_enable(IMU_INT1_PIN, false);
        nrfx_gpiote_trigger_enable(IMU_INT1_PIN, false);
    }

    I am NOT using IN Event per my configuration. Please note this power issue only happens after all configurations and ONLY after the IMU int pin is triggered. so after power on for approx 8 seconds, the current level is as expected. only after the int trigger this issue happens. again, this issue is driving me crazy and eating lots of my time. any other suggestions please? as always, your help is greatly appreciated.

    Regards,

    here is some of my code

    timers setup

    static const nrfx_timer_t m_imu_acq_cnt_timer = NRFX_TIMER_INSTANCE(1);
    static const nrfx_timer_t m_fram_hibernate_delay_timer = NRFX_TIMER_INSTANCE(2);
    static const nrfx_timer_t m_fram_spim_start_cnt_timer = NRFX_TIMER_INSTANCE(3);
    static const nrfx_timer_t m_fram_spim_end_cnt_timer = NRFX_TIMER_INSTANCE(4);
    
    
    void configure_imu_ppi_timer(void)
    {
        nrfx_err_t err = NRFX_SUCCESS;
    
    
        // configure imu/ppi timer
        nrfx_timer_config_t timer_cfg_0 = NRFX_TIMER_DEFAULT_CONFIG;
        timer_cfg_0.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER; //NRF_TIMER_MODE_COUNTER;
        //IRQ_DIRECT_CONNECT(TIMER1_IRQn, 0, nrfx_timer_1_irq_handler, 0);
    
        IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer1)), 
    		    DT_IRQ(DT_NODELABEL(timer1), priority),
    		    nrfx_isr, nrfx_timer_1_irq_handler, 0);
    
        if(!nrfx_timer_is_enabled(&m_imu_acq_cnt_timer)) {
            err = nrfx_timer_init(&m_imu_acq_cnt_timer,
                                        &timer_cfg_0,
                                        imu_ppi_timer_event_handler);    
            if (err != NRFX_SUCCESS) {
    		    LOG_ERR("nrf_drv_timer_init error: %08x", err);
    		    return;
    	    }                              
        }
    
        nrfx_timer_extended_compare(&m_imu_acq_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL0,
                                       1 /*IMU_SPIM_TRANSFER_COUNT*/,
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, 
                                       true);
    
        if(!nrfx_timer_is_enabled(&m_imu_acq_cnt_timer))
            nrfx_timer_enable(&m_imu_acq_cnt_timer);    
    }

    void configure_fram_ppi_timer()
    {
        nrfx_err_t err = NRFX_SUCCESS;
    
        IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer2)), 
    		    DT_IRQ(DT_NODELABEL(timer2), priority),
    		    nrfx_isr, nrfx_timer_2_irq_handler, 0);
    
        // the fram hibernate timer ~6ms
        nrfx_timer_config_t timer_cfg_1 = NRFX_TIMER_DEFAULT_CONFIG;
        timer_cfg_1.mode = NRF_TIMER_MODE_TIMER;
        timer_cfg_1.frequency = NRF_TIMER_FREQ_31250Hz;
        //timer_cfg_1.bit_width = NRF_TIMER_BIT_WIDTH_32;
    
        if(!nrfx_timer_is_enabled(&m_fram_hibernate_delay_timer)) {
            err = nrfx_timer_init(&m_fram_hibernate_delay_timer,
                                        &timer_cfg_1,
                                        fram_ppi_timer_event_handler);    
            if (err != NRFX_SUCCESS) {
    		    LOG_ERR("nrf_drv_timer_init error: %08x", err);
    		    return;
    	    }                              
        }
        uint32_t ticks = nrfx_timer_ms_to_ticks(&m_fram_hibernate_delay_timer, 8);
        nrfx_timer_extended_compare(&m_fram_hibernate_delay_timer,
                                       NRF_TIMER_CC_CHANNEL2,
                                       ticks,
                                       (NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE2_STOP_MASK), 
                                       false);    
    
        nrfx_timer_clear(&m_fram_hibernate_delay_timer);
        //  if(!nrfx_timer_is_enabled(&m_fram_hibernate_delay_timer))
        //  {
        //     nrfx_timer_enable(&m_fram_hibernate_delay_timer);
        //     nrfx_timer_pause(&m_fram_hibernate_delay_timer);
        //     nrfx_timer_clear(&m_fram_hibernate_delay_timer);
        //  }
    
        IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer3)), 
    		    DT_IRQ(DT_NODELABEL(timer3), priority),
    		    nrfx_isr, nrfx_timer_3_irq_handler, 0);
    
        // configure fram spim start count ppi timer
        nrfx_timer_config_t timer_cfg_2 = NRFX_TIMER_DEFAULT_CONFIG;
        timer_cfg_2.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER; //NRF_TIMER_MODE_COUNTER;
        if(!nrfx_timer_is_enabled(&m_fram_spim_start_cnt_timer)) {
            err = nrfx_timer_init(&m_fram_spim_start_cnt_timer,
                                        &timer_cfg_2,
                                        fram_spim_start_count_ppi_timer_event_handler);    
            if (err != NRFX_SUCCESS) {
    		    LOG_ERR("nrf_drv_timer_init error: %08x", err);
    		    return;
    	    }                              
        }
        nrfx_timer_compare(&m_fram_spim_start_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL0,
                                       1 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                       true);
    
        nrfx_timer_compare(&m_fram_spim_start_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL1,
                                       2 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                       true);
    
        nrfx_timer_compare(&m_fram_spim_start_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL2,
                                       3 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                       true);
        nrfx_timer_extended_compare(&m_fram_spim_start_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL3,
                                       4 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                       NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK,
                                       true);                               
    
        if(!nrfx_timer_is_enabled(&m_fram_spim_start_cnt_timer))
            nrfx_timer_enable(&m_fram_spim_start_cnt_timer);  
    
        nrfx_timer_clear(&m_fram_spim_start_cnt_timer);
    
        IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer4)), 
    		    DT_IRQ(DT_NODELABEL(timer4), priority),
    		    nrfx_isr, nrfx_timer_4_irq_handler, 0);
    
        // configure fram spim end count ppi timer
        nrfx_timer_config_t timer_cfg_3 = NRFX_TIMER_DEFAULT_CONFIG;
        timer_cfg_3.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER; //NRF_TIMER_MODE_COUNTER;
        if(!nrfx_timer_is_enabled(&m_fram_spim_end_cnt_timer)) {
            err = nrfx_timer_init(&m_fram_spim_end_cnt_timer,
                                        &timer_cfg_3,
                                        fram_spim_end_count_ppi_timer_event_handler);    
            if (err != NRFX_SUCCESS) {
    		    LOG_ERR("nrf_drv_timer_init error: %08x", err);
    		    return;
    	    }                              
        }
        // we start the 3rd FRAM write
        nrfx_timer_compare(&m_fram_spim_end_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL0,
                                       2 /*SPIM END EVENT COUNT*/,  
                                       false);
        // we start the 4th FRAM write
        nrfx_timer_compare(&m_fram_spim_end_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL1,
                                       3 /*SPIM END EVENT COUNT*/,
                                       false);
        // we want to clear the timer on the end of the 4th spim end 
         nrfx_timer_extended_compare(&m_fram_spim_end_cnt_timer,
                                       NRF_TIMER_CC_CHANNEL2,
                                       4 /*SPIM END EVENT COUNT*/,
                                       NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK,  
                                       false);
                                 
        if(!nrfx_timer_is_enabled(&m_fram_spim_end_cnt_timer))
            nrfx_timer_enable(&m_fram_spim_end_cnt_timer);     
    
        nrfx_timer_clear(&m_fram_spim_end_cnt_timer); 
    
    }

    void fram_spim_start_count_ppi_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
    {
        uint32_t timer_value = 0;
        uint8_t CMD_WRITE_ENABLE;
        uint8_t CMD_HIBERNATE;
    
        if(event_type == NRF_TIMER_EVENT_COMPARE0) // for 2nd fram write
        {
            timer_value = nrfx_timer_capture_get(&m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL0);
            CMD_WRITE_ENABLE = ENUM_TO_UINT8(FRAM_CMD_WRITE_ENABLE);
            spim1_fram.p_reg->TXD.PTR = (uint32_t)&CMD_WRITE_ENABLE;
            spim1_fram.p_reg->TXD.MAXCNT = 1;
            spim1_fram.p_reg->RXD.MAXCNT = 0; 
           // LOG_INF("Setup for 2nd fram write.........");
    
            //nrfx_timer_clear(&m_imu_acq_cnt_timer);
            // LOG_HEXDUMP_INF(IMU_Recv_ArrayList->buffer,364,"received FIFO Data");
        }
        else if(event_type == NRF_TIMER_EVENT_COMPARE1) // for 3rd fram write
        {
            timer_value = nrfx_timer_capture_get(&m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL1);
            IMU_RX_BUFFER[0] = ENUM_TO_UINT8(FRAM_CMD_WRITE_DATA);
            IMU_RX_BUFFER[1] = (m_current_fram_addr & 0x00FF0000) >> 16;
            IMU_RX_BUFFER[2] = (m_current_fram_addr & 0x0000FF00) >> 8;
            IMU_RX_BUFFER[3] = (m_current_fram_addr & 0x000000FF);
    
            m_current_fram_addr += ADL_MODE_BUFFER_IMU_RXD_SIZE;
    
            spim1_fram.p_reg->TXD.PTR = (uint32_t)&IMU_RX_BUFFER;
            spim1_fram.p_reg->TXD.MAXCNT = ADL_MODE_BUFFER_IMU_RXD_SIZE + 4;
            spim1_fram.p_reg->RXD.MAXCNT = 0;
           // LOG_INF("Setup for 3rd fram write.........");
        }
        else if(event_type == NRF_TIMER_EVENT_COMPARE2) // for 4th fram write
        {
            timer_value = nrfx_timer_capture_get(&m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL2);
            CMD_HIBERNATE = ENUM_TO_UINT8(FRAM_CMD_HIBERNATE);
            spim1_fram.p_reg->TXD.PTR = (uint32_t)&CMD_HIBERNATE;
            spim1_fram.p_reg->TXD.MAXCNT = 1;
            spim1_fram.p_reg->RXD.MAXCNT = 0; 
           // LOG_INF("Setup for 4th fram write.........");
        }
        else if(event_type == NRF_TIMER_EVENT_COMPARE3) // for 1st fram write
        {
            timer_value = nrfx_timer_capture_get(&m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL3);
          //  nrfx_timer_clear(&m_fram_spim_start_cnt_timer);
            spim1_fram.p_reg->TXD.PTR = (uint32_t)&FRAM_ADL_TX_ArrayList;
            spim1_fram.p_reg->TXD.MAXCNT = 4;
            spim1_fram.p_reg->RXD.MAXCNT = 0; 
            //LOG_INF("Setup for 1st fram write.........");
        }
        else
            LOG_INF("Unknown timer event...............");
    }
    void fram_spim_end_count_ppi_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
    {
        if(event_type == NRF_TIMER_EVENT_COMPARE0) // the 3rd spim end trigger
        {
            LOG_INF("2nd spim end trigger.........");
        }
        else if(event_type == NRF_TIMER_EVENT_COMPARE1) // the 3rd spim end trigger
        {
            //nrfx_timer_clear(&m_fram_spim_end_cnt_timer);
            LOG_INF("3rd spim end trigger.........");
        }
        else
            LOG_INF("Undefind FRAM SPIM End Count Event Type.........");
    }

    void setup_ADL_mode_imu_ppi_spi_transfer(void)
    {
        nrfx_err_t err = NRFX_SUCCESS;
      
        // IMU SPI setup
        spim0_imu.p_reg->TXD.LIST = SPIM_TXD_LIST_LIST_ArrayList;
        spim0_imu.p_reg->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;
        spim0_imu.p_reg->TXD.MAXCNT = ADL_MODE_BUFFER_IMU_TXD_SIZE;
        spim0_imu.p_reg->RXD.MAXCNT = ADL_MODE_BUFFER_IMU_RXD_SIZE; 
        nrfx_spim_xfer_desc_t imu_xfer = NRFX_SPIM_XFER_TRX((uint8_t*)IMU_ChannelSwitch_ArrayList,
                                                                            ADL_MODE_BUFFER_IMU_TXD_SIZE,
                                                                            (uint8_t*)&IMU_RX_BUFFER[4],
                                                                            ADL_MODE_BUFFER_IMU_RXD_SIZE);
    
        uint32_t flags = (NRFX_SPIM_FLAG_HOLD_XFER
                          |NRFX_SPIM_FLAG_TX_POSTINC
                          |NRFX_SPIM_FLAG_RX_POSTINC
                          |NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER
                          |NRFX_SPIM_FLAG_REPEATED_XFER);
                          
        err = nrfx_spim_xfer(&spim0_imu, &imu_xfer, flags);
        if (err != NRFX_SUCCESS) {
            LOG_INF("nrfx_spim_xfer error: %08x", err);
    		LOG_ERR("nrfx_spim_xfer error: %08x", err);
    		return;
    	}
    }
    
    void setup_ADL_mode_fram_ppi_spi_transfer(void)
    {
        nrfx_err_t err = NRFX_SUCCESS;
      
        uint32_t flags = (NRFX_SPIM_FLAG_HOLD_XFER
                          |NRFX_SPIM_FLAG_TX_POSTINC
                          |NRFX_SPIM_FLAG_RX_POSTINC
                          |NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER
                          |NRFX_SPIM_FLAG_REPEATED_XFER);
                          
        // FRAM SPI setup
        spim1_fram.p_reg->TXD.LIST = SPIM_TXD_LIST_LIST_ArrayList;
        spim1_fram.p_reg->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;
        spim1_fram.p_reg->TXD.MAXCNT = 4;
        spim1_fram.p_reg->RXD.MAXCNT = 0; 
        nrfx_spim_xfer_desc_t fram_xfer = NRFX_SPIM_XFER_TRX((uint8_t*)FRAM_ADL_TX_ArrayList,
                                                                            4,
                                                                            NULL,
                                                                            0);                  
        err = nrfx_spim_xfer(&spim1_fram, &fram_xfer, flags);
        if (err != NRFX_SUCCESS) {
            LOG_INF("nrfx_spim_xfer error: %08x", err);
    		LOG_ERR("nrfx_spim_xfer error: %08x", err);
    		return;
    	}
    }

    void start_ADL_mode_acq()
    {
        //setup_imu_ppi_spi_transfer();
        setup_ADL_mode_imu_ppi_spi_transfer();
        setup_ADL_mode_fram_ppi_spi_transfer();
    	nrfx_ppi_group_enable(imu_trigger_group);
        
        // k_timer_stop(&m_start_imu_conv_timer_id);
        // k_timer_start(&m_start_imu_conv_timer_id, K_MSEC(1010), K_NO_WAIT);
        LOG_INF("started ADL Mode Acquisition...............");
    }
    
    void ADL_mode_ppi_init(void)
    {
        nrfx_err_t err = NRFX_SUCCESS;
    
        nrf_ppi_channel_t imu_int1_trigger_ppi_channel;
        nrf_ppi_channel_t imu_count_ppi_channel;
        nrf_ppi_channel_t imu_trigger_disable_channel;
        nrf_ppi_channel_t fram_spim_end_trigger_ppi_channel;
        nrf_ppi_channel_t fram_spim_start_trigger_ppi_channel;
        nrf_ppi_channel_t fram_hibernate_timer_ppi_channel;
        nrf_ppi_channel_t fram_spim_start_count_ppi_channel;
        nrf_ppi_channel_t fram_spim_end_count_ppi_channel;
    
        nrf_ppi_channel_t fram_1st_write_ppi_channel;
        nrf_ppi_channel_t fram_2nd_write_ppi_channel;
        nrf_ppi_channel_t fram_3rd_write_ppi_channel;
        nrf_ppi_channel_t fram_4th_write_ppi_channel;
    
        uint32_t imu_int1_trigger_pin_evt_addr;
        uint32_t imu_spim_start_task_addr;
        uint32_t imu_spim_end_evt_addr;
        uint32_t timer_count_task_addr;
        uint32_t timer_cc_event_addr;
        uint32_t group_imu_disable_task_addr;
        
        uint32_t imu_ss_pin_toggle_task_addr;
        uint32_t fram_timer_spim_start_count_task_addr;
        uint32_t fram_timer_spim_end_count_task_addr;
        uint32_t fram_timer_spim_start_cc1_event_addr;
        uint32_t fram_timer_spim_end_cc2_event_addr;
        uint32_t fram_timer_spim_end_cc3_event_addr;
       
        uint32_t fram_spim_start_task_addr;
        uint32_t fram_spim_end_evt_addr;
        uint32_t fram_spim_started_evt_addr;
        uint32_t fram_ss_pin_toggle_task_addr;
        // uint32_t group_fram_disable_task_addr;
    
        uint32_t fram_hibernate_timer_start_task_addr;
        uint32_t fram_hibernate_timer_cc_evt_addr;   
    
        err = nrfx_ppi_channel_alloc(&imu_int1_trigger_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
    
        // this ppi channel will toggle the fram spim cs at the end of the transaction to the fram
        err = nrfx_ppi_channel_alloc(&fram_spim_end_trigger_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        
        err = nrfx_ppi_channel_alloc(&fram_spim_start_trigger_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        
        err = nrfx_ppi_channel_alloc(&fram_hibernate_timer_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&imu_count_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}  
        err = nrfx_ppi_channel_alloc(&fram_spim_start_count_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&fram_spim_end_count_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&fram_1st_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&fram_2nd_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&fram_3rd_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&fram_4th_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_alloc(&imu_trigger_disable_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_alloc error: %08x", err);
    		return;
    	}
    
        err = nrfx_ppi_group_alloc(&imu_trigger_group);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_group_alloc error: %08x", err);
    		return;
    	}
    
        imu_int1_trigger_pin_evt_addr   = nrfx_gpiote_in_event_addr_get(IMU_INT1_PIN);
        imu_spim_start_task_addr        = nrf_spim_task_address_get(spim0_imu.p_reg, NRF_SPIM_TASK_START);
        imu_spim_end_evt_addr           = nrf_spim_event_address_get(spim0_imu.p_reg, NRF_SPIM_EVENT_END);
        timer_count_task_addr       = nrfx_timer_task_address_get(&m_imu_acq_cnt_timer, NRF_TIMER_TASK_COUNT);
        timer_cc_event_addr         = nrfx_timer_compare_event_address_get(&m_imu_acq_cnt_timer, NRF_TIMER_CC_CHANNEL0);
        // group_disable_task_addr = (uint32_t) nrf_ppi_task_group_disable_address_get(trigger_group);
        group_imu_disable_task_addr = (uint32_t) nrfx_ppi_task_addr_group_disable_get(imu_trigger_group);
        
        fram_spim_start_task_addr    = nrf_spim_task_address_get(spim1_fram.p_reg, NRF_SPIM_TASK_START); 
        fram_spim_end_evt_addr       = nrf_spim_event_address_get(spim1_fram.p_reg, NRF_SPIM_EVENT_END);
        fram_spim_started_evt_addr   = nrf_spim_event_address_get(spim1_fram.p_reg, NRF_SPIM_EVENT_STARTED);
     //   group_fram_disable_task_addr = (uint32_t) nrfx_ppi_task_addr_group_disable_get(fram_trigger_group);
        
        fram_hibernate_timer_start_task_addr = nrfx_timer_task_address_get(&m_fram_hibernate_delay_timer, NRF_TIMER_TASK_START);
        fram_hibernate_timer_cc_evt_addr     = nrfx_timer_compare_event_address_get(&m_fram_hibernate_delay_timer, NRF_TIMER_CC_CHANNEL2);
    
        fram_timer_spim_start_count_task_addr = nrfx_timer_task_address_get(&m_fram_spim_start_cnt_timer, NRF_TIMER_TASK_COUNT);
        fram_timer_spim_end_count_task_addr = nrfx_timer_task_address_get(&m_fram_spim_end_cnt_timer, NRF_TIMER_TASK_COUNT);
    
        //fram_timer_spim_start_cc1_event_addr         = nrfx_timer_compare_event_address_get(&m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL0);
        fram_timer_spim_end_cc2_event_addr         = nrfx_timer_compare_event_address_get(&m_fram_spim_end_cnt_timer, NRF_TIMER_CC_CHANNEL0);
        fram_timer_spim_end_cc3_event_addr         = nrfx_timer_compare_event_address_get(&m_fram_spim_end_cnt_timer, NRF_TIMER_CC_CHANNEL1);
    
        // IMU SS
        // The SS pin will be driven by a GPIOTE task.
        // have the ppi spim start/end event control the slave select       
        nrfx_gpiote_out_config_t imu_ss_pin_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
        err = nrfx_gpiote_out_init(IMU_CS_PIN, &imu_ss_pin_config);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_out_init error: %08x", err);
    		return;
    	}
        imu_ss_pin_toggle_task_addr = nrfx_gpiote_out_task_addr_get(IMU_CS_PIN);
    
        // FRAM SS
        // The SS pin will be driven by a GPIOTE task.
        // have the ppi spim start/end event control the slave select   
        nrfx_gpiote_out_config_t fram_ss_pin_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
        err = nrfx_gpiote_out_init(FRAM_CS_PIN, &fram_ss_pin_config);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_gpiote_out_init error: %08x", err);
    		return;
    	}
        fram_ss_pin_toggle_task_addr = nrfx_gpiote_out_task_addr_get(FRAM_CS_PIN);
    
        // this channel will trigger the imu spim task off the imu int1 pin event 
        err = nrfx_ppi_channel_assign(imu_int1_trigger_ppi_channel,
                                              imu_int1_trigger_pin_evt_addr,
                                              imu_spim_start_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
    
        // fork the imu ss pin off of the start(to assert) of imu spim channel
        err = nrfx_ppi_channel_fork_assign(imu_int1_trigger_ppi_channel, imu_ss_pin_toggle_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_fork_assign error: %08x", err);
    		return;
    	}
    
        err = nrfx_ppi_channel_assign(imu_count_ppi_channel,
                                              imu_spim_end_evt_addr,
                                              timer_count_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        // fork the imu ss pin off of the end of imu spim channel(to de-assert))
        err = nrfx_ppi_channel_fork_assign(imu_count_ppi_channel, imu_ss_pin_toggle_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_fork_assign error: %08x", err);
    		return;
    	}
     ////////   
        // first FRAM write. dummy read instruction. toggle ss pin, start spi, toggle ss pin  
        err = nrfx_ppi_channel_assign(fram_1st_write_ppi_channel,
                                              imu_spim_end_evt_addr,
                                              fram_spim_start_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_assign(fram_spim_start_trigger_ppi_channel,
                                              fram_spim_started_evt_addr,
                                              fram_ss_pin_toggle_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_assign(fram_spim_end_trigger_ppi_channel,
                                              fram_spim_end_evt_addr,
                                              fram_ss_pin_toggle_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        
        // count the FRAM SPI writes off of the SPI start
        err = nrfx_ppi_channel_assign(fram_spim_start_count_ppi_channel,
                                              fram_spim_started_evt_addr,
                                              fram_timer_spim_start_count_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	} 
        err = nrfx_ppi_channel_assign(fram_spim_end_count_ppi_channel,
                                              fram_spim_end_evt_addr,
                                              fram_timer_spim_end_count_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
       
        // start the FRAM hibernate timer off of the IMU SPI end Event
        err = nrfx_ppi_channel_assign(fram_hibernate_timer_ppi_channel,
                                              imu_spim_end_evt_addr,
                                              fram_hibernate_timer_start_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        // now we want to start the 2nd, 3rd and 4th FRAM SPI transactions
        // we start the 2nd off of the end of te hibernate timer
        err = nrfx_ppi_channel_assign(fram_2nd_write_ppi_channel,
                                              fram_hibernate_timer_cc_evt_addr,
                                              fram_spim_start_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_assign(fram_3rd_write_ppi_channel,
                                              fram_timer_spim_end_cc2_event_addr,
                                              fram_spim_start_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_assign(fram_4th_write_ppi_channel,
                                              fram_timer_spim_end_cc3_event_addr,
                                              fram_spim_start_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
    
        err = nrfx_ppi_channel_enable(fram_spim_start_trigger_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(fram_spim_end_trigger_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(imu_count_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(fram_spim_start_count_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(fram_spim_end_count_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(fram_1st_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(fram_2nd_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        err = nrfx_ppi_channel_enable(fram_3rd_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
         err = nrfx_ppi_channel_enable(fram_4th_write_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
        
        err = nrfx_ppi_channel_enable(fram_hibernate_timer_ppi_channel);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    		return;
    	}
     
        err = nrfx_ppi_channel_assign(imu_trigger_disable_channel,
                                              timer_cc_event_addr,
                                              group_imu_disable_task_addr);
        if (err != NRFX_SUCCESS) {
    		LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    		return;
    	}
        // err = nrfx_ppi_channel_assign(fram_trigger_disable_channel,
        //                                       timer_fram_cc_event_addr,
        //                                       group_fram_disable_task_addr);
        // if (err != NRFX_SUCCESS) {
    	// 	LOG_ERR("nrfx_ppi_channel_assign error: %08x", err);
    	// 	return;
    	// }
    
      
    //    err_code = nrfx_ppi_channel_enable(trigger_ppi_channel);
    //    APP_ERROR_CHECK(err_code);
     
    //     err = nrfx_ppi_channel_enable(imu_trigger_disable_channel);
    //     if (err != NRFX_SUCCESS) {
    // 		LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    // 		return;
    // 	}
        
        // disable for testing
        // err = nrfx_ppi_channel_enable(fram_trigger_disable_channel);
        // if (err != NRFX_SUCCESS) {
    	// 	LOG_ERR("nrfx_ppi_channel_enable error: %08x", err);
    	// 	return;
    	// }
    
        nrfx_ppi_channel_include_in_group(imu_int1_trigger_ppi_channel, imu_trigger_group);
        // nrfx_ppi_channel_include_in_group(fram_spim_trigger_ppi_channel, fram_trigger_group);
        // nrfx_ppi_channel_include_in_group(fram_spim_end_trigger_ppi_channel, fram_trigger_group);
        
    //    nrf_ppi_group_enable(trigger_group);
    
        nrfx_gpiote_out_task_enable(IMU_CS_PIN);  
        nrfx_gpiote_out_task_enable(FRAM_CS_PIN); 
    }

  • Hi Wael,

    Sorry, I thought you were using the nRF5340 for some reason. A current draw in the 5-600 uA range on the nRF52 series usually indicates that a peripheral keep requesting the 16 MHz clock. For instance, a running TIMER instance. However, this should have led to a more constant draw, not like the waveform shown in your screenshot.

    The DMA current is closer to 2 mA with VDD @ 1.8 v. But as you said, this current should only be seen during transmissions when the CPU is idle.   

    Either way, to try narrow down the problem, could try to issue the TIMER SHUTDOWN tasks for your timers after the transaction is complete by calling nrfx_timer_disable(). Also, is it possible to power off the IMU and FRAM IC (make sure you do not have any floating inputs if you do this)?  

    Best regards,

    Vidar

  • hi Vidar,

    thanks for the reply. I did try TIMER SHUTDOWN and that did not work. what did work was the following:

    // nRF52833 Revision 2 Errata
    // [246] System: Intermittent extra current consumption when going to sleep
    // Extra current consumption in the range of 350 µA when in System On Idle.
    // A high-speed peripheral (CPU for example) accesses a RAM block which is being accessed by
    // a low-speed peripheral through the DMA bus, with a specific timing, and the high-speed peripheral has
    // higher priority than the low-speed peripheral.
    // NOTE: Workaround consequences: Up to 40 µA current increase when the 16 MHz clock is used.
    *(volatile uint32_t *)0x4007AC84ul = 0x00000002ul;
    I placed that line of code in my main function and the current went back down close to what's expected. still need to figure out where about 20uA is going.
    having said that, I now have the issue where if I increase my FRAM SPIM frequency to anything above 1 MHz, the PPI logic does not work. IMU SPIM frequency is set to 8 MHz. recall that the IMU and FRAM are on separate buses. recall, my app does the following using PPI

    the PPI configuration is as follow:

    1) Upon receiving a GPIOTE trigger from an IMU(every 8.3 seconds), read its data (this is operating on a dedicated spi bus, SPIM0) (~3500 bytes)

    2) write a dummy read command to an FRAM IC to wake it up from hibernate state (SPIM1 bus)(4 bytes)

    3) trigger timer for 8ms from the start of the FRAM SPIM transaction(step 2)(8ms is the period for FRAM to become stable from hibernate state)

    4) write the WREN(write enable) command(1 Byte) to the FRAM upon completion of the 8ms timer

    5) write the (write command, address, data) to the FRAM(~3500 bytes)

    6) write the hibernate command to the FRAM(1 byte)

    so when the FRAM SPIM freq=1 MHz, everything looks good and I can see things operating as expected on a scope.
    when I change the freq. to say 2 MHz or more, it does everything as expected with the exception of step 5. it only writes ONE byte. its seems as though the fram_spim_start_count_ppi_timer_event_handler is not getting executed on when the count=2(to setup for the 3rd FRAM write) to update the SPIM ptr and tx/rx parameters. I am assuming the 2nd spi transaction(which is one byte) got executed so fast that the spi parameters never get updated for the next transaction. Not sure on how to handle this issue. I need the speed to save on power. any thoughts and/or hints? As always, your help would be greatly appreciated. 
    Regards,
    Wael
  • Hi Vidar,

    Just confirmed my feeling from my previous post where the time to write one byte(step 4 only from previous post) was creating a timing issue. when I changed that to 10 bytes and the FRAM SPIM freq to 8MHz, it worked. anything under 10 bytes will not. Not sure how I'm suppose to handle this issue. I need to only write one byte, which is a command, and the CS line needs to be toggled. Your help will be greatly appreciated.

    Regards,

    Wael

  • Hi Wael,

    I am happy to hear you found the errata which caused the issue. This errata is quite rare and is usually more intermittent due to the accurate timing conditions needed for it to arise. 

    Wael said:
    Just confirmed my feeling from my previous post where the time to write one byte(step 4 only from previous post) was creating a timing issue. when I changed that to 10 bytes and the FRAM SPIM freq to 8MHz, it worked. anything under 10 bytes will not.

    I wonder if the problem could be caused by a race where PPI is triggering the FRAM SPI start task before the CPU has had time to update the transaction details from your timer ISR. Thus, causing the WREN byte to be sent twice instead of proceeding with IMU data transfer as it is supposed to. Or does this not match with what you are seeing on the oscilloscope? 

    As a test, maybe you can read out 10 dummy bytes in the WREN transaction to see if it has the same effect as sending 10 bytes.

    Best regards,

    Vidar

Related