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

TWI Slave and APP_TIMER issues

Hi,

I'm working on a custom bootloader which does DFU over I2C. As a fail safe mechanism I want to have a timer running that gets reset between each Image data block, so incase we dont get a new image data block in 5-10 seconds (unless we have received the entire image) time the nRF52832 resets itself and goes back to the bootloader and waiting for a complete transfer.

The problems I'm seeing is that the I2C transfers stops working when I try to reset the timer in the I2C interrupt. If I start the timer at boot it runs and reaches its handler for as long as I dont transfer anything over I2C. But as soon as I transfer something it does not hit the handler and the I2C transfers stops.

I'm not quite sure what's happening here as I dont seem to hit any error handlers. Since the timer is not supposed to hit hits handler (if the DFU proccess is successful) they dont run in the same context either. But I have tried changing so that the TWI uses a higher interrupt priority than the APP_TIMER_MODULE, but that does not seem to help.

Here's my TWIS evt handler:

static void twis_event_handler(nrfx_twis_evt_t const * const p_event)
{
    ret_code_t err_code;
    switch(p_event->type)
    {
    case NRFX_TWIS_EVT_READ_REQ:
        if(p_event->data.buf_req)
        {
            err_code = nrfx_twis_tx_prepare(&instance, tx_buff, tx_len);
            NRF_LOG_DEBUG("TX prepare returned err_code: %d", err_code);
        }
        break;
    case NRFX_TWIS_EVT_READ_DONE:
        break;
    case NRFX_TWIS_EVT_READ_ERROR:
        NRF_LOG_DEBUG("I2C read error!")
        break;
    case NRFX_TWIS_EVT_WRITE_REQ:
        if(p_event->data.buf_req)
        {
            err_code = nrfx_twis_rx_prepare(&instance, rx_buff, sizeof(uint8_t) * 128);
            NRF_LOG_DEBUG("RX prepare returned err_code: %d", err_code);
        }
        break;
    case NRFX_TWIS_EVT_WRITE_DONE:
        if (p_event->data.rx_amount > 2)
        {
            NRF_LOG_DEBUG("Received data, DECODING");
            comm_timer_restart();
            handleData(rx_buff, (uint16_t) p_event->data.rx_amount);
        }
        break;
    case NRFX_TWIS_EVT_WRITE_ERROR:
        NRF_LOG_DEBUG("I2C Write error!");
        break;
    case NRFX_TWIS_EVT_GENERAL_ERROR:
        NRF_LOG_DEBUG("I2C Error!");
        break;
    default:
        NRF_LOG_DEBUG("I2C handler default case??");
        break;
    }
}

Parents
  • Hi,

    Sorry for the late reply,

    I have a couple questions I would like you to answer :) : 

    • Which SDK and Softdevice (if you are) version are you using?
    • Could you provide a bit more code? I'm specifically interested in the initialization of the Timer and the I2C modules. Could you also share the timer handler, and how you reset the timer? I can make the case private if you prefer it. 
    • Where exactly is the code stuck? Have you tried using the debugger and single step through the code?

    best regards

    Jared

  • Also,

    Since I'm not using Segger Embedded Studio I'm working on getting the debugging working. I'm having some issues with Ozone. Will update you as soon as I get it to work..

  • But as soon as I transfer something it does not hit the handler and the I2C transfers stops.

     Could you elaborate on this? My understanding of your project is that you don't want the timer to hit its handler when you transfer as this would cause a reset of the nRF. Instead, you would want to reset the timer after the transfer is complete in the NRFX_TWIS_EVT_WRITE_DONE case.  Is the problem that the I2C transfer doesn't start again after the timer is reset? again, it would be good to know where in the code it stops.

Reply
  • But as soon as I transfer something it does not hit the handler and the I2C transfers stops.

     Could you elaborate on this? My understanding of your project is that you don't want the timer to hit its handler when you transfer as this would cause a reset of the nRF. Instead, you would want to reset the timer after the transfer is complete in the NRFX_TWIS_EVT_WRITE_DONE case.  Is the problem that the I2C transfer doesn't start again after the timer is reset? again, it would be good to know where in the code it stops.

Children
Related