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

TWIM issue

Hello ,
I am working on a project which contains I2C communication,
When I test the twi scanner example on my sensor and it works fine
But when I do the combination with the usbd_ble_uart example to send the data to uart I encountered a problem during an I2C read operation. My code stuck in this infinite loop

bool transmission_finished = false;
        do {
            if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_SUSPENDED))
            {
                transmission_finished = true;
            }

            if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED))
            {
                nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED);
                transmission_finished = true;
            }

            if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR))
            {
                nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR);

                bool lasttx_triggered = nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_LASTTX);
                uint32_t shorts_mask = nrf_twim_shorts_get(p_twim);

                if (!(lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_STOP_MASK)))
                {
                    // Unless LASTTX event arrived and LASTTX_STOP shortcut is active,
                    // triggering of STOP task in case of error has to be done manually.
                    nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME);
                    nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP);

                    // Mark transmission as not finished yet,
                    // as STOPPED event is expected to arrive.
                    // If LASTTX_SUSPENDED shortcut is active,
                    // NACK has been received on last byte sent
                    // and SUSPENDED event happened to be checked before ERROR,
                    // transmission will be marked as finished.
                    // In such case this flag has to be overwritten.
                    transmission_finished = false;
                }

                if (lasttx_triggered && (shorts_mask & NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK))
                {
                    // When STOP task was triggered just before SUSPEND task has taken effect,
                    // SUSPENDED event may not arrive.
                    // However if SUSPENDED arrives it always arrives after ERROR.
                    // Therefore SUSPENDED has to be cleared
                    // so it does not cause premature termination of busy loop
                    // waiting for STOPPED event to arrive.
                    nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED);

                    // Mark transmission as not finished yet,
                    // for same reasons as above.
                    transmission_finished = false;
                }
            }
        } while (!transmission_finished);

Although I tried to copy all the configuration performed in the example of twi scanner

Please Help me .

Parents
  • Hello nikola,

    When I test the twi scanner example on my sensor and it works fine

    Thank you for clarifying this - then we know that there is no issue with your hardware connections. 

    But when I do the combination with the usbd_ble_uart example to send the data to uart I encountered a problem during an I2C read operation. My code stuck in this infinite loop

    Which priority are you using for your TWI and USBD IRQ's?
    The TWI peripheral examples does not have to account for the fact that it may be interrupted at any time (such as by the SoftDevice), so I suspect the issue here is that the TWI transfer or post-processing is being interrupted at an inopportune time, which causes it to get stuck in this loop. If this is the case, you will either have to change your tranmission_finished implementation, or add some sort of watchdog / timer / specific error handling to this loop, in order to break out if this occurs.
    Lets start by identifying exactly why it does wrong, and then look into what we may do to avoid it.

    Best regards,
    Karl

  • Thank you for answering me
    I solved this error
    but I have another problem concerning the execution of the two processes in the same while loop  when I put the two commands together in while (true) of main.c the sensor sends the data until a given moment and it stops the execution
    i want to know how i can run both codes in the same while loop

  • nd I strongly recommend that you look into how you may move 98% of your current main() code into interrupt handles or separate functions outside of main()

    how can I do this please

  • You can start by moving all function definitions outside of main(), for example. Then, you need to determine which of them should be called as part of an interrupt service routine, and then implement that routine.

    Are you familiar with interrupt service routines / IRQ's / callback functions?
    If not, I recommend that you familiarize yourself with this subject through either a video series or blog series on the topic, for example. The scope of it is too broad to cover here in a comment, but in essence; Interrupts lets the CPU be alerted to events that has occurs outside of the regular program flow (main), so that it can jump to a different section of the code to handle this event, before resuming its regular program flow (main). Interrupts are the cornerstone of an event-triggered embedded system.

    Bet regards,
    Karl

  • when I add APP_ERROR_CHECK I have got this error 

  • you need to determine which of them should be called as part of an interrupt service routine, and then implement that routine.

    I don't understand you very well Can you expalin to me in another way

  • nikola said:
    when I add APP_ERROR_CHECK I have got this error 

    Great, this means that the function actually did return an error. Please view the entire error message, it will say which line of your code that generated the NRF_ERROR_INVALID_ADDR error. Then you will need to look at the API reference for that function, to determine why it would return this particular error.

    nikola said:
    I don't understand you very well Can you expalin to me in another way

    I am not sure that my written text answers here might be the best way for you to learn about interrupts and events. Perhaps it could help you to take a look at this third party video tutorial on the topic.
    I strongly recommend that you get a good understanding of this fundamental embedded C concept before you continue the development of your application, as it will be impossible to create an application with the functionality and complexity that you describe above without understanding and using interrupts and events.

    Best regards,
    Karl

Reply
  • nikola said:
    when I add APP_ERROR_CHECK I have got this error 

    Great, this means that the function actually did return an error. Please view the entire error message, it will say which line of your code that generated the NRF_ERROR_INVALID_ADDR error. Then you will need to look at the API reference for that function, to determine why it would return this particular error.

    nikola said:
    I don't understand you very well Can you expalin to me in another way

    I am not sure that my written text answers here might be the best way for you to learn about interrupts and events. Perhaps it could help you to take a look at this third party video tutorial on the topic.
    I strongly recommend that you get a good understanding of this fundamental embedded C concept before you continue the development of your application, as it will be impossible to create an application with the functionality and complexity that you describe above without understanding and using interrupts and events.

    Best regards,
    Karl

Children
No Data
Related