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

Undesired behavior when enabling/disabling TWI + timer and scheduler

Hi there,

On my application, I have multiple sensors attached to the nRF52 and I read them every 5 seconds scheduling the read inside a timer handler, then when the Softdevice have free time slots I got the scheduler event (now the main context) where I call my routine to enable Twi, do Twi reads/writes and finally disabling Twi.

My basics are:

  define a timer per sensor

  define a scheduler per sensor

  handle the scheduler per sensor

 call my Twi routine from the main context

But my program gets stuck passed some time, then I used app_sched_queue_space_get() and app_sched_queue_utilization_get()  to look what happens inside the scheduler

space: 5 utilization: 1

space: 4 utilization: 2

space: 3 utilization: 3

space: 2 utilization: 4

space: 1 utilization: 5

then the program crash

when I add a small delay to the  TWI uninitialization app_sched_queue_space_get() and app_sched_queue_utilization_get() returns for 2 sensors and the program works fine

space: 5 utilization: 1

space: 5 utilization: 2

space: 5 utilization: 2

space: 5 utilization: 2

space: 5 utilization: 2

 

I am disabling Twi in the following way: (because I am using gpiote too)

	nrf_drv_twi_disable(&m_twi_master);
	nrf_drv_twi_uninit(&m_twi_master);
	
	NRF_TWI1->TASKS_STOP = 1;
	NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
	NRF_TWI1->INTENCLR =(TWI_INTENCLR_STOPPED_Disabled << TWI_INTENCLR_STOPPED_Pos) | \
						(TWI_INTENCLR_RXDREADY_Disabled << TWI_INTENCLR_RXDREADY_Pos) | \
						(TWI_INTENCLR_TXDSENT_Disabled << TWI_INTENCLR_TXDSENT_Pos) | \
						(TWI_INTENCLR_ERROR_Disabled << TWI_INTENCLR_ERROR_Pos) | \
						(TWI_INTENCLR_BB_Disabled << TWI_INTENCLR_BB_Pos);	
	
		//https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52832_Rev2%2FERR%2FnRF52832%2FRev2%2Flatest%2Fanomaly_832_89.html&cp=3_1_1_0_1_26
		//[89] GPIOTE: Static 400 µA current while using GPIOTE
		*(volatile uint32_t *)0x40003FFC = 0;
		*(volatile uint32_t *)0x40003FFC;
		*(volatile uint32_t *)0x40003FFC = 1;

why I am experimenting that behavior? I dont want add delays in my program but at least it is solving that issue at the moment

my program only calls app_sched_event_put inside the timer handler and exits from it very quickly also it exits very quickly from the scheduler handler

Regards,

Arepa

Parents
  • Hi 

    I assume you are using the app_timer library for your timers?

    What queue size do you initialize the scheduler library to use?

    You mention that you exit the scheduler handler very quickly, but if you enable TWI and run communication before disabling it again I assume all this will take some time?

    Any particular reason you have to disable TWI all the time?
    To the best of my knowledge there are no dependencies between the TWI driver and the GPIOTE. 

    Best regards
    Torbjørn

  • 1- Yes, I am using app_timer

    2 - Actually, my queue size is 40, for the example above it was 5, it seems the scheduler is being filled, but not being handled

    3- Yes, I enable TWI, run the communication and disable it again before putting the nRF52 in sleep mode, probably this whole process takes 10-30ms maybe less

    4-Yes, I want to save battery consumption it is critical for my application

    5-I use GPIOTE to enable my TWI slaves before read them, but I noticed an extra 1mA consumption when using TWI and GPIOTE together that is the way I am setting 0x40003FFC [89] GPIOTE

    I am thinking it is something related to enable and disable TWI too often, that is the way I added 1ms delay after disabled TWI, it seems to work at the moment, but I would like to have a better solution for this issue

  • Hi

    Apparently there is a second workaround you can try that doesn't require disabling the TWI interface completely. 

    Setting the ENABLE register to 9 will try to enable the SPIS interface, and if you set the register to 9 and then immediately set it back to TWI_ENABLE_ENABLE_Enabled, it should clear the condition that leads to higher current consumption. 

    A better solution yet I think would be to use the nrf_twi_mngr.c module, which is purpose made to handle situations where you want to read multiple sensors over the same bus. With this module you can essentially queue multiple TWI transactions from multiple sources, and have the manager handled them one after the other until the queue is empty. 

    For an example of how to use this module you can have a look at the example in the SDK, located here:
    \nRF5_SDK_15.3.0_59ac345\examples\peripheral\twi_master_using_nrf_twi_mngr

    Best regards
    Torbjørn

Reply
  • Hi

    Apparently there is a second workaround you can try that doesn't require disabling the TWI interface completely. 

    Setting the ENABLE register to 9 will try to enable the SPIS interface, and if you set the register to 9 and then immediately set it back to TWI_ENABLE_ENABLE_Enabled, it should clear the condition that leads to higher current consumption. 

    A better solution yet I think would be to use the nrf_twi_mngr.c module, which is purpose made to handle situations where you want to read multiple sensors over the same bus. With this module you can essentially queue multiple TWI transactions from multiple sources, and have the manager handled them one after the other until the queue is empty. 

    For an example of how to use this module you can have a look at the example in the SDK, located here:
    \nRF5_SDK_15.3.0_59ac345\examples\peripheral\twi_master_using_nrf_twi_mngr

    Best regards
    Torbjørn

Children
No Data
Related