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

Stream data over TWI with start signal only in the beginning of the frame, and one stop at the end of the frame

Hello,

I am working on a sensor which requires data transfer over with data length over 255 bytes. I am using nRF52832 uC and and from what I see from nordic infocenter by using the following portion of code:

ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,
                          uint8_t               address,
                          uint8_t const *       p_data,
                          uint8_t               length,
                          bool                  no_stop);

I can send up to 255 bytes and it is possible to set no_stop to true to not send a stop signal. However as you know, the simple write burst operation has a message similar to this message,  , but that case isn't true, when Data Frame xxx is bigger than 255, since after each data frame, no start signal is resent.

Parents
  • I have also noticed this function in nrfx_twi.c:

    typedef struct
    {
        nrfx_twi_evt_handler_t  handler;
        void *                  p_context;
        volatile uint32_t       int_mask;
        nrfx_twi_xfer_desc_t    xfer_desc;
        uint32_t                flags;
        uint8_t *               p_curr_buf;
        size_t                  curr_length;
        bool                    curr_tx_no_stop;
        twi_suspend_t           prev_suspend;
        nrfx_drv_state_t        state;
        bool                    error;
        volatile bool           busy;
        bool                    repeated;
        size_t                  bytes_transferred;
        bool                    hold_bus_uninit;
    } twi_control_block_t;
    
    static bool twi_transfer(NRF_TWI_Type           * p_twi,
                             twi_control_block_t    * p_cb)
    {
        bool stopped = false;
        if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
        {
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
            NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
    
            // Delay handling of STOPPED event till the end of events processing procedure.
            // If penultimate byte is received and function gets interrupted for long enough
            // after enabling BB_STOP shortcut, RXDREADY for last byte as well as STOPPED
            // may be active at the same time. Therefore RXREADY has to be processed before STOPPED to
            // acquire last byte before finishing transmission by returning 'false'.
            stopped = true;
        }
    
        if (p_cb->error)
        {
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
        }
        else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
        {
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
            NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
            nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
            p_cb->error = true;
        }
        else
        {
            if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT))
            {
                nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
                ++(p_cb->bytes_transferred);
                NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_TXDSENT));
                if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
                {
                    nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
                    NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
                    nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
                    p_cb->error = true;
                }
                else
                {
                    if (!twi_send_byte(p_twi, p_cb))
                    {
                        return false;
                    }
                }
            }
            else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_RXDREADY))
            {
                nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
                NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_RXDREADY));
                if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
                {
                    NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
                    nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
                    nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
                    p_cb->error = true;
                }
                else
                {
                    if (!twi_receive_byte(p_twi, p_cb))
                    {
                        return false;
                    }
                }
            }
        }
    
        if (stopped)
        {
            p_cb->prev_suspend = TWI_NO_SUSPEND;
            if (!p_cb->error)
            {
                p_cb->error = !xfer_completeness_check(p_twi, p_cb);
            }
            return false;
        }
    
        return true;
    }

    Is it possible to solve my issue? Is there any documentation to read for this function? I would appreciate any example as well.

    Thanks!

Reply
  • I have also noticed this function in nrfx_twi.c:

    typedef struct
    {
        nrfx_twi_evt_handler_t  handler;
        void *                  p_context;
        volatile uint32_t       int_mask;
        nrfx_twi_xfer_desc_t    xfer_desc;
        uint32_t                flags;
        uint8_t *               p_curr_buf;
        size_t                  curr_length;
        bool                    curr_tx_no_stop;
        twi_suspend_t           prev_suspend;
        nrfx_drv_state_t        state;
        bool                    error;
        volatile bool           busy;
        bool                    repeated;
        size_t                  bytes_transferred;
        bool                    hold_bus_uninit;
    } twi_control_block_t;
    
    static bool twi_transfer(NRF_TWI_Type           * p_twi,
                             twi_control_block_t    * p_cb)
    {
        bool stopped = false;
        if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED))
        {
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED);
            NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED));
    
            // Delay handling of STOPPED event till the end of events processing procedure.
            // If penultimate byte is received and function gets interrupted for long enough
            // after enabling BB_STOP shortcut, RXDREADY for last byte as well as STOPPED
            // may be active at the same time. Therefore RXREADY has to be processed before STOPPED to
            // acquire last byte before finishing transmission by returning 'false'.
            stopped = true;
        }
    
        if (p_cb->error)
        {
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
        }
        else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
        {
            nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
            NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
            nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
            p_cb->error = true;
        }
        else
        {
            if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT))
            {
                nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT);
                ++(p_cb->bytes_transferred);
                NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_TXDSENT));
                if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
                {
                    nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
                    NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
                    nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
                    p_cb->error = true;
                }
                else
                {
                    if (!twi_send_byte(p_twi, p_cb))
                    {
                        return false;
                    }
                }
            }
            else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_RXDREADY))
            {
                nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY);
                NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_RXDREADY));
                if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR))
                {
                    NRFX_LOG_DEBUG("TWI: Event: %s.", EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR));
                    nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR);
                    nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP);
                    p_cb->error = true;
                }
                else
                {
                    if (!twi_receive_byte(p_twi, p_cb))
                    {
                        return false;
                    }
                }
            }
        }
    
        if (stopped)
        {
            p_cb->prev_suspend = TWI_NO_SUSPEND;
            if (!p_cb->error)
            {
                p_cb->error = !xfer_completeness_check(p_twi, p_cb);
            }
            return false;
        }
    
        return true;
    }

    Is it possible to solve my issue? Is there any documentation to read for this function? I would appreciate any example as well.

    Thanks!

Children
No Data
Related