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

TWI hanging in while (m_xfer_done == false); communicating with Arduino

I am trying to use I2C (TWI) to communicate between my custom nRF52811 board with an Arduino. Currently my program hangs at the while (m_xfer_done == false);  loop as m_xfer_done never gets set to true. I believe that the nrf chip gets stuck at the end of the transmission since the Arduino actually receives the message.

I based my code heavily on the twi_sensor example provided by Nordic and kept it very bare bone. It is using My Arduino is set as slave on address 0x08 and I am writing 0x016 (which gets received on the arduino side). The twi_init is also set as non-blocking.

Below is a snipet of my code that I believe are relevant to the problem.

// Arduino I2C test
#define ARDUI_ADDR          0x08U

void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{

    m_xfer_done = true;
    NRF_LOG_INFO("Handling....");
    NRF_LOG_FLUSH();
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                data_handler(m_sample);
            }
            m_xfer_done = true;
            break;
        default:
          break;
    }
}

/**
 * @brief UART initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_lm75b_config = {
       .scl                = 16,
       .sda                = 15, 
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

void test_i2c(void)
{
    ret_code_t err_code;

    uint8_t reg[1] = {0x016U};

    err_code = nrf_drv_twi_tx(&m_twi, ARDUI_ADDR, reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);

    while (m_xfer_done == false);

}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("\r\nTWI sensor example started.");
    NRF_LOG_FLUSH();
    twi_init();

    while (true)
    {
        nrf_delay_ms(500);

        test_i2c();

        do
        {
            __WFE();
        }while (m_xfer_done == false);

        NRF_LOG_FLUSH();
    }
}

/** @} */

Furthermore I added 1K pullup resistors for both communication line just in case. I also dont have any oscilloscope nor logic analyzer...so I cant provide any pictures of the actual signal.

Any help would be greatly appreciated!

  • Got it to work, it was a issues with converting pca10056 to pca10056e. This post was extremely helpful. TLDR quoting the solution:

     

    1. Right Click the project in the Project Explorer. In this case it will be named 'twi_scanner_pca10056' (or other twi pca10056 project)
    2. Select 'Open Solution in Editor' from the menu that appears.
    3. Change arm_fp_abi from "Hard" to "Soft"
    4. Change arm_fpu_type from "FPv4-SP-D16" to "Soft"
    5. Change arm_target_device_name from "nRF52840_xxAA" to "nRF52811_xxAA"
    6. Add in any directories you might want to use to c_user_include_directories
    7. Change in c_preprocessor_definitions:
      1. BOARD_PCA10056 to your custom board
      2. FLOAT_ABI_HARD to FLOAT_ABI_SOFT
      3. NRF52840_XXAA to NRF52811_XXAA
    8. Change debug_register_definition_file from "../../../../../../modules/nrfx/mdk/nrf52840.svd" to "../../../../../../modules/nrfx/mdk/nrf52811.svd"
    9. Change linker_section_placement_macros:
      1. FLASH_PH_SIZE=0x100000 to 0x30000
      2. RAM_PH_SIZE=0x40000 to 0x6000
      3. FLASH_SIZE=0x100000 to 0x30000
      4. RAM_SIZE=0x40000 to 0x6000
    10. Under <folder Name="None">
      1. <file file_name="../../../../../../modules/nrfx/mdk/ses_startup_nrf52840.s" /> change to <file file_name="../../../../../../modules/nrfx/mdk/ses_startup_nrf52811.s" />
      2. <file file_name="../../../../../../modules/nrfx/mdk/system_nrf52840.c" /> change to <file file_name="../../../../../../modules/nrfx/mdk/system_nrf52811.c" />

    sdk_config.h modifcations

    The reason I have included these is to use them as an example of the things you might have to change in a separate example.

    1. NRFX_TWIM0_ENABLED from 0 to 1
    2. NRFX_TWI0_ENABLED from 0 to 1
    3. TWI1_ENABLED from 1 to 0
    4. UART_LEGACY_SUPPORT from 1 to 0

    In order to get things printing in the Debug Terminal

    1. NRF_LOG_BACKEND_RTT_ENABLED from 0 to 1
    2. NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED from 1 to 0
    3. NRF_LOG_BACKEND_UART_ENABLED from 1 to 0

    main.c modifications

    1. Change your pin assignment
Related