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! }

  • Aha one more thing. IP0 and IP1 addresses are not located on 8-bit boundary hence sbits can not be used in Keil C51. This is very strange as in the manual they clearly have bit-per-bit settings. Omission on 8051 implementer or just annoyance?

    Cheers

    Adam

  • Hi Adam,

    Happy new year to you!

    Your understanding is correct. The IP0/IP1 have a reset value of 0, meaning all interrupts have the same priority. This is as intended, as it is up to you which interrupts you use and how to use them.

    The IPx register is located at a 16 bit address, but the value inside the registers are 8 bit. You can use "sbit", similar to what is done with the GPIOs (P00 for instance), but this register is mapped directly without sbit. Setting the register can be done like this: IPx |= (1 << BIT_x); // set bit IPx &= ~(1 << BIT_x); // Clear bit

    BR Håkon

  • here's some example code i'm using.

    //-------- UART begin
    IP0 = 0x10;	// make uart higher priority than RF.
    IP1 = 0x10;	// make uart higher priority than RF.
    P0DIR = (P0DIR & ~0x08) | 0x10; // bxxx1-0xxx
    hal_uart_init(UART_BAUD_38K4); 
    while(hal_clk_get_16m_source() != HAL_CLK_XOSC16M);
    ...
    ...
    ...
    //-------- do some UART stuff now. turn off RF IRQ
    RF = 0; // disable RF IRQ
    printf("print one thing here.");
    printf("print another thing here.");
    RF = 1; // enable RF IRQ
    
Related