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

Problem using UART and radio in ESB mode on nRF24LE01.

Hi

for few days I seem to got stack in using together UART and radio on nRF21LE01 in ESB mode and I suspect irq_flags = hal_nrf_get_clear_irq_flags(); to be cause of my problem.

What I want to achieve is to communicate to terminal via UART messages every time my receiver gets message from transmitter (nRF51822). The radio part works flawlessly and on the TXs side i.e nRF51822 which works also in ESB mode the radio and UART work happily together.

On RX side the UART also works anywhere in the program but in the NRF_ISR() code section which services received packets. I suspect that irq_flags = hal_nrf_get_clear_irq_flags(); function which supposed to read and clear radio interrupts messes up all interrupts including UARTs.

Am I making some fundamental mistake here? Despite searching web for answers, Nordic FAQ and reading extensively nrf24LE01 related docs I am unable to make this work. Can anyone put me on the right path with this please?

Regards

Adam //----------------------------------------------------------------------------------- The code structure is simple.

main() // Initializes the UART hal_uart_init(UART_BAUD_9K6);

// Wait for XOSC to start to ensure proper UART baudrate while(hal_clk_get_16m_source() != HAL_CLK_XOSC16M) {} Blink(3); //<- just tests that anything happens

// Enable global interrupt EA = 1;

// Enable the radio clock RFCKEN = 1; // Enable RF interrupt RF = 1;

// Print "Hello World" at start-up putstring("\r\nXOSC has started!\r\n"); //<- works!

// Configure radio as primary receiver (PTX) hal_nrf_set_operation_mode(HAL_NRF_PRX);

//This has to be here for nrf24LE01 to receive from nrf51... in ESB hal_nrf_setup_dynamic_payload(0xFF); hal_nrf_enable_dynamic_payload(true); hal_nrf_enable_ack_payload(true); hal_nrf_set_rf_channel(10);

// Power up radio hal_nrf_set_power_mode(HAL_NRF_PWR_UP);

// Enable receiver CE_HIGH();

// Print "Hello World" at start-up putstring("\r\nHaha!\r\n"); //<- works!

for(;;){} }

// Radio interrupt NRF_ISR() { uint8_t irq_flags;

// Read and clear IRQ flags from radio irq_flags = hal_nrf_get_clear_irq_flags(); //<-- Is this my problem?

// If data received if((irq_flags & (1<<(uint8_t)HAL_NRF_RX_DR)) > 0) { // Read payload while(!hal_nrf_rx_fifo_empty()) { hal_nrf_read_rx_payload(payload); } } putstring("\r\nPacket received!\r\n"); //<- DOES NOT WORK! Blink(1); //<- works! }

  • Hi,

    Calling UART prints from interrupt context is not recommended. Note that your UART baudrate is quite low (9k6), which then uses almost 1 ms to send one byte. When sending 10-20 bytes while in the NRF_ISR() routine, you will get a timing error if your PTX is sending at a high frequency. You normally want to keep ISR routines as short as possible.

    Try using global flags and send UART prints in your main loop instead, and lower the frequency that you are pushing packets over the RF link (add a delay on the PTX side).

    -H

  • Hi Håkon

    sure they (ISR) should be kept short but I don't understand why my code dos not work in my case at all. I am sending packet of data only when I press a button on my RX side so in this case timing should not be a problem.

    Are you aware of any other restrictions while in ISR?

    Thanks you and Cheers

    Adam

  • Hi Håkon

    sure they (ISR) should be kept short but I don't understand why my code dos not work in my case at all. I am sending packet of data only when I press a button on my RX side so in this case timing should not be a problem.

    Are you aware of any other restrictions while in ISR?

    Thanks you and Cheers

    Adam

  • Hi Adam,

    The UART print routine will call on function "hal_uart_putchar", which again relies on the UART0_ISR. The hal_uart library is a blocking library, meaning it uses while-loops that needs UART0_ISR function to handle.

    When you are triggering an interrupt from another interrupt with the same priority, this will give you a deadlock-situation. This is the situation:

    • print function called from NRF-interrupt
    • print function will trigger UART-interrupt
    • print function will loop until UART-ISR is one
    • Cannot enter UART-ISR, as you are currently processing NRF_ISR.

    You have two ways of avoiding this:

    • Call print-routines only from main-context
    • Set a higher priority on UART interrupt (using IP0 and IP1 registers)

    Best regards Håkon

  • Hi Håkon,

    Merry Christmas! Thank you for explanation of what is going on in my ISR and of the dead-lock condition. Since then I am tinkering with IP0 and IP1 registers. When I read content of these two register upon power-up they all are 0. Does this mean that after power is supplied to nrf24LE1 the default priority of all priority groups is at its lowest level 0 that is that all interrupts are treated equally?

    Is this normal and desired? I am coming from java programming background and still consider myself as newbie embedded programmer.

    Regards

    Adam

Related