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

twi fail in second msg attempt

hello

i am using nrf52832, with ble (s132 softdevice), pwm drv, saadc drcm uart, and using app_timers

i have added the twi drv to work with an expander for start.

this is how my function looks like

void i2c_transmit(uint8_t address, uint8_t * data)
{
    ret_code_t err_code = nrf_drv_twi_tx(&m_twi, address, data, sizeof(data), true);
    APP_ERROR_CHECK(err_code);
}

this is where i call the function:

uint8_t ex_config_reg_init_val = EXPANDER_CONFIG_PIN_AS_OUTPUT_MASK;

//configur expander pins as output via configure register
i2c_transmit(EXPANDER_CONFIGURATION_REGISTER_ADDRESS, &ex_config_reg_init_val);
// if send was success -> 
i2c_transmit(EXPANDER_OUTPUT_PORT_REGISTER_ADDRESS, &expander_data_byte);

first message gets ok, second fails (error 17) ->  [is there some file that shows what every error number is refering to ??? i could not find ]

this is my init:

void i2c_init(void)
{
   ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .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_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

i have read in this forom that i should config some event handler in my init but it is not clear to me what should be done in this event handler because i have nointtention to creat some loop that waits for some 'OK' event

also, when i run in debug mode i see that i am not entering the event handler at all so it is not so clear to me what i am doing wrong ???

how can i solve this ?

Best regards

Ziv

Parents
  • The first I would recommend it simply drag in the example code as-is from the nRF5 SDK twi example to check that it works as intended. For instance a logic analyzer is very valuable to check if data is sent and acked as intended. In your case you have set 'twi_handler' in nrf_drv_twi_init() so this means that the 'twi_handler()' should execute after transfer to indicate if data was sent successfully or not. The error code 17 from nrf_drv_twi_tx() I can see from nrf_drv_twi.h is NRF_ERROR_BUSY, which make sense since the previous call is not yet finished here. Make sure you have included all 'TWI' defines from the nRF5 SDK twi example sdk_config.h to your sdk_config.h. Make sure that the TWI pins have pull-up resistors.

  • hi Kenneth

    i added 10 ms delay between one call to the next and i so everything passing good on the ociloscop

    still, it is not something i want to do in my program to creat a delay or configure another timer just for the second twi tx, is there anyway to avoide that or any mechanism, like using the DMA as buffer for the next message and the driver will collect and transmit the msg from there once the first message receivs the desirable Ack ??

    best regards

    Ziv

  • If you look at \examples\peripheral\twi_sensor you can for instance find how to use a 'm_xfer_done' flag to notify when the previous transaction is finished.

  • I am sorry if my replay maybe a bit rude but I wonder if you think I am stupid :/

    i am sorry to say but the use of a bool flag in a while loop is not the most clever solution one can think of..

    let's say that for some reason there is a malfunction in the twi tx and i never get the event of type ' NRF_DRV_TWI_EVT_DONE ',  the way it is implemented in the example i get stuck in the while loop forever and i am sure my employer will not like that so much, also there is no functional difference if i wait in delay or wait in a loop, still my program is missing a whole many things that maybe happening now

    this is why I asked if there is a way to let the "hardware" do that work ,of waiting and managing the send of the buffered msg, which is always a good practice in embedded

    best regards

    Ziv

  • Feel free to modify this the best to your needs and requirement. It may be twi sensors that based on your experience malfunction, and you want to handle this gracefully in your application. You may for instance add a down counter in your while() loop, and that way get out of a stuck situation or your twi callback handler can handle a twi que, and thereby you may avoid having a while() all together in main(). Having the soc hardware handle this all by itself isn't really possible if you assume that a malfunction can occur, since the hardware will not be able to identify such an occurrence either. So you will need (at least the way I see it) add additional handling of errors and timeouts for transfer in your application, if  based on your experience see that this occurs from time to time. My impression is that these kind of error occurs frequently during development due to timing constrains not followed, pull-ups not mounted, register access is not allowed or errors in twi transfers break for instance the usage of twi either on the master or slave, however once these have been identified during development, then simple while() loops do work. 

  • all together in main(). Having the soc hardware handle this all by itself isn't really possible

    i do not expect the hardware to deal with a malfunction if it accurse but to alert and maybe abort pervious operation, but like the saadc driver knows to read one pin (channel) and after finishing its readings move to the next defined pin and so on and can even trigger a high or low limit compar.. then i do belive some things can be done without CPU intervention on the driver side.. i understand that the current twi driver can not do that ?

Reply
  • all together in main(). Having the soc hardware handle this all by itself isn't really possible

    i do not expect the hardware to deal with a malfunction if it accurse but to alert and maybe abort pervious operation, but like the saadc driver knows to read one pin (channel) and after finishing its readings move to the next defined pin and so on and can even trigger a high or low limit compar.. then i do belive some things can be done without CPU intervention on the driver side.. i understand that the current twi driver can not do that ?

Children
No Data
Related