TWIM 1 Timeslot no interrupt

Hi,

As i2c communication + computation takes 45ms in my timer interrupt that happen each 100ms and gave issue with SD, I decided to set a flag in the interrupt and execute sensors operation in the main loop.

It works but...it was estonishing slow.

Timer is properly called each 100ms. I see on scope my debug pin toggling.

But my second debug pin that should toggle in the main loop if flag is set, toogle only each 490ms ! It means that something is taking the lead in paralelle, is taking a lot of time and is not  allowing me to reach the main each 100ms like I would like.

I guess Soft Device (s113 in my case) take this time. For example, communication that should take 13ms when no sd is running ( on the 45ms in total for my sensors tasks, rest is big float computation) takes 350ms ! 26 times the time it should !

After some search, i discovered Timeslot, that seems to be appropriate for perdiodic reading in real time. It should avoid radio interupt during the 45ms i need to communicate, compute and update my ble caracteristic.

I have implemented the code that blinks the pin each 100ms, it works fine and it is quiet precise even when i'm connected to my app.

Now, i have added my sensors task after the toggling of my debug pin. I have an issue because after the first byte sent via TWIM1, the program is stuck on : 

    while(nrfx_twim_is_busy(&my_twi)){;}

So i guess it is related to TWIM1 interrupt that should be disabled may be.

 So i enable interrupt this way, but i'm still stuck on the same line:

nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)
{
ret_code_t err_code;

    switch(signal_type)
    {
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
            //Start of the timeslot - set up timer interrupt
            signal_callback_return_param.params.request.p_next = NULL;
            signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
            
            NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
            NRF_TIMER0->CC[0] = m_slot_length - 1000;
            NVIC_EnableIRQ(TIMER0_IRQn); 
            
            //I add these lines below:
            NVIC_ClearPendingIRQ(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn);
            NRF_TWI1->INTENSET = TWIM_INTENSET_LASTRX_Msk|TWIM_INTENSET_LASTTX_Msk ;
            NVIC_EnableIRQ(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn); 

            nrf_gpio_pin_toggle(DEBUG_PIN2); //flo Toggle DEBUG_PIN

Is there something else to be able to communicate on twim1 ( with dma) during a timeslot please ?

I see on Power Profile kit a big spike to 45mA each 18ms (i'mat +8dBm). I wonder if it is not the source of the delay it occurs on my sensors task executed in the main:

Do you know what it could be? It looks likes a connection packet or something to acknowledge connexion is still alive, but it' s increasing consumption a lot ! I dont't think it is advertising cause i set it to 400ms and i confirm it with nrf Connect mobil app. I'm using the basic ble_peripheral example with S113. I'm peripheral and GATT server.

Thank you!

Parents
  • Hi, 

    I finally tried the scheduler without improvement.

    So i decided to check with the scope what happens during transmision when it is done into the main, but i it is the same effect in interrupt app timer handler.

    It seems twim communication is interrupted each 184us, during 34us and sometime even more.

    So iguess timeslot is the own solution.

  • Hi,

    1)

    Are you reading 1 and 1 byte?

    The TWIM peripheral have EasyDMA, https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf52833%2Ftwim.html so you can transfer multiple bytes without CPU involvement.

    2)

    I guess Soft Device (s113 in my case) take this time. For example, communication that should take 13ms when no sd is running ( on the 45ms in total for my sensors tasks, rest is big float computation) takes 350ms ! 26 times the time it should !

    Are you in a connection when doing this test? Have you tried increasing the connection interval? Even as a BLE peripheral, you can request a higher connection interval. If you are advertising, try temporarily disabling the adverting.

  • Are you reading 1 and 1 byte?

    No i'm using Easy DMA with TWIM1 . Here is the function i'm using:

    As it is 16bit register , i need to switch msb and lsb by using a for loop at the end of the function.

    ret_code_t I2CRead(uint8_t slaveAddr, uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data){
    
        ret_code_t err_code; 
        uint8_t addr[2] = {0,0};
        uint16_t lsb,msb;
    
        addr[0] = startAddress >> 8;       //msb first
        addr[1] = startAddress & 0x00FF;   //lsb first
    
    
        const nrfx_twim_xfer_desc_t    my_xfer   =    {.type = NRFX_TWIM_XFER_TXRX,
                                                        .address=slaveAddr,
                                                        .primary_length   = 2,
                                                        .secondary_length = (nMemAddressRead<<1),
                                                        .p_primary_buf    = &addr,
                                                        .p_secondary_buf  = data
                                                      };
    
        err_code = nrfx_twim_xfer(&my_twi, &my_xfer ,0);
        APP_ERROR_CHECK(err_code);
    
    
        while(nrfx_twim_is_busy(&my_twi)){;}
    
        for(int i=0; i < nMemAddressRead; i++){
    
            lsb = (data[i]&0xff00) >> 8;
            msb=  data[i] &  0xff;
            data[i] = (msb<<8) | lsb;
        }
    
        return err_code;
      
    } 

    Are you in a connection when doing this test?

    Yes i'm connected when i read the sensor for sure.

    Have you tried increasing the connection interval?

    Yes here is my settings. But is doesn't impact the 184us periodic interval i see on scope. But i se impact on power consumption with PPK.

    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(100, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(200, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.2 second). */

    Remember, when i do this communication at the entry point of the program, just after main ( first operation) it takes only 45ms for this test. 

    So from what this periodic interrupt can comes from?

    And did you already succed in using timeslot with twim please ?

    As tried scheduler but it doesn't bring any advantages compared to execute in timer handler.

    I'm losing a bit hope at the moment i hope you will have answer to this issue.

    Thanks a lot

Reply
  • Are you reading 1 and 1 byte?

    No i'm using Easy DMA with TWIM1 . Here is the function i'm using:

    As it is 16bit register , i need to switch msb and lsb by using a for loop at the end of the function.

    ret_code_t I2CRead(uint8_t slaveAddr, uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data){
    
        ret_code_t err_code; 
        uint8_t addr[2] = {0,0};
        uint16_t lsb,msb;
    
        addr[0] = startAddress >> 8;       //msb first
        addr[1] = startAddress & 0x00FF;   //lsb first
    
    
        const nrfx_twim_xfer_desc_t    my_xfer   =    {.type = NRFX_TWIM_XFER_TXRX,
                                                        .address=slaveAddr,
                                                        .primary_length   = 2,
                                                        .secondary_length = (nMemAddressRead<<1),
                                                        .p_primary_buf    = &addr,
                                                        .p_secondary_buf  = data
                                                      };
    
        err_code = nrfx_twim_xfer(&my_twi, &my_xfer ,0);
        APP_ERROR_CHECK(err_code);
    
    
        while(nrfx_twim_is_busy(&my_twi)){;}
    
        for(int i=0; i < nMemAddressRead; i++){
    
            lsb = (data[i]&0xff00) >> 8;
            msb=  data[i] &  0xff;
            data[i] = (msb<<8) | lsb;
        }
    
        return err_code;
      
    } 

    Are you in a connection when doing this test?

    Yes i'm connected when i read the sensor for sure.

    Have you tried increasing the connection interval?

    Yes here is my settings. But is doesn't impact the 184us periodic interval i see on scope. But i se impact on power consumption with PPK.

    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(100, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(200, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.2 second). */

    Remember, when i do this communication at the entry point of the program, just after main ( first operation) it takes only 45ms for this test. 

    So from what this periodic interrupt can comes from?

    And did you already succed in using timeslot with twim please ?

    As tried scheduler but it doesn't bring any advantages compared to execute in timer handler.

    I'm losing a bit hope at the moment i hope you will have answer to this issue.

    Thanks a lot

Children
No Data
Related