0

NRF52 ESB RX-TX

Ronan gravatar image

asked 2017-03-17 14:47:13 +0100

how to change RX and TX operations ? i wrote next code:

#include "nrf_esb.h"
#include <stdbool.h>
#include <stdint.h>
#include "sdk_common.h"
#include "nrf.h"
#include "nrf_esb_error_codes.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "nrf_error.h"
#include "nrf_log.h"
#include "boards.h"
#include "nrf_log.h"

#define RX 0 
#define TX 1 

uint8_t RX_MODE_FLAG = 0;
uint8_t TX_MODE_FLAG = 0;

const uint8_t leds_list[LEDS_NUMBER] = LEDS_LIST;
uint8_t led_nr;

nrf_esb_payload_t               rx_payload;
nrf_esb_payload_t           tx_payload = NRF_ESB_CREATE_PAYLOAD(0, 0xC1, 0x00, 0x05);

void nrf_esb_error_handler(uint32_t err_code, uint32_t line)
{
    NRF_LOG_PRINTF("App failed at line %d with error code: 0x%08x\r\n",
                   line, err_code);
#if DEBUG 
    while(true);
#else
    NVIC_SystemReset();
#endif
}

#define APP_ERROR_CHECK(err_code) if(err_code) nrf_esb_error_handler(err_code, __LINE__);

void nrf_esb_event_handler(nrf_esb_evt_t const * p_event)
{
    switch (p_event->evt_id)
    {
        case NRF_ESB_EVENT_TX_SUCCESS:
            NRF_LOG("TX SUCCESS EVENT\r\n");
                    // Toggle one of the LEDs.
                        nrf_gpio_pin_toggle(LED_2);
            break;
        case NRF_ESB_EVENT_TX_FAILED:
            NRF_LOG("TX FAILED EVENT\r\n");
                        nrf_gpio_pin_toggle(LED_3);
                        nrf_esb_flush_tx();
            break;
        case NRF_ESB_EVENT_RX_RECEIVED:
            NRF_LOG("RX RECEIVED EVENT\r\n");
            if (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS)
            {
                            // Set LEDs identical to the ones on the PTX.
                            nrf_gpio_pin_toggle(LED_4);
            }
                        nrf_esb_flush_rx();
                        TX_MODE_FLAG = 1;
            break;
    }
        //NRF_GPIO->OUTCLR = 0xFUL << 12;
    //NRF_GPIO->OUTSET = (p_event->tx_attempts & 0x0F) << 12;
}

void clocks_start( void )
{
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
}

void gpio_init( void )
{
    LEDS_CONFIGURE(LEDS_MASK);
}

uint32_t esb_init( uint8_t state )
{
    uint32_t err_code;
    uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 };

    nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
    nrf_esb_config.payload_length           = 32;
        nrf_esb_config.retransmit_delay         = 1000;
        nrf_esb_config.retransmit_count                 = 2;
    nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB;
    nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS;
        switch(state){
            case RX:
                        nrf_esb_config.mode                     = NRF_ESB_MODE_PRX;
            break;
            case TX:
                        nrf_esb_config.mode                     = NRF_ESB_MODE_PTX;
            break;  
        }
    nrf_esb_config.event_handler            = nrf_esb_event_handler;
        nrf_esb_config.crc                                          = NRF_ESB_CRC_16BIT;    
    nrf_esb_config.selective_auto_ack       = true;

        err_code = nrf_esb_set_rf_channel(14);
        VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_init(&nrf_esb_config);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_0(base_addr_0);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_base_address_1(base_addr_1);
    VERIFY_SUCCESS(err_code);

    err_code = nrf_esb_set_prefixes(addr_prefix, 8);
    VERIFY_SUCCESS(err_code);

    return err_code;
}

int main(void)
{
    uint32_t err_code;

    gpio_init();

    err_code = NRF_LOG_INIT();
    APP_ERROR_CHECK(err_code);

    clocks_start();

    err_code = esb_init(RX);
    APP_ERROR_CHECK(err_code);

    NRF_LOG("Enhanced ShockBurst Receiver Example running.\r\n");

      err_code = nrf_esb_start_rx();
    APP_ERROR_CHECK(err_code);
    while (true)
    {

            if(TX_MODE_FLAG)
            {
                //err_code = nrf_esb_stop_rx();
                err_code = esb_init(TX);

              tx_payload.length = 32;
                tx_payload.pipe = 0;
                tx_payload.noack = true;
                tx_payload.data[1]++;

                err_code = nrf_esb_start_tx();
        if (nrf_esb_write_payload(&tx_payload) == NRF_SUCCESS)
        {
                        nrf_gpio_pin_toggle(LED_1); 
                }   

                TX_MODE_FLAG = 0;
                err_code = esb_init(RX);
                err_code = nrf_esb_start_rx();
            }
        __WFE();
    }
}

Recieve is working nice. But there is TX error event. And after 4th time tx stopted.

edit retag flag offensive close delete report spam

Comments

@amigo: Please describe your set-up more clearly. When you switch nRF52 with RX and TX mode, which device will act as peer device ? How would they sync ?

Hung Bui ( 2017-03-20 16:17:56 +0100 )editconvert to answer

@amigo: You have another case here you mentioned that it worked for you. Could you confirm the issue is fixed ?

For your setup I would suggest you configure the server as PRX and clients as PTXs. Instead of server initially send to client commands , you can use it the reversed way, the client sends packets to ping the server periodically and if the server has a command to send to the client, the server can send the command as ACK payload. This way the server always PRX and the client is always PTX. This make it easier to implement and most power efficient as only the server stay in RX mode.

You can do what you are doing, meaning all will stay mainly in PRX mode, all the time, and this will cause lots of power consumption.

Hung Bui ( 2017-03-21 10:47:53 +0100 )editconvert to answer

2 answers

Sort by » oldest newest most voted
0
Ronan gravatar image

answered 2017-03-20 18:16:48 +0100

updated 2017-03-20 18:17:23 +0100

@Hung Bui:

i'm using NRF24l01 with stm32 as server. nrf52-dk board with some sensors as a client. Server send to a client (clients) request packet (any user protocol). Client (nrf52) cheks an itsef's address, command and execute required functions. Then client sends data back to master (NRF24L01). Server uses ADDRESS_P0[] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; pipe. Client may use one of other pipes adresses.

NRF24 configuration: 2Mbps, auto ACK, 2byte CRC

void Radio_Config(void) 
{
  Radio_Write_Reg(STATUS, NOP);
  Radio_Write_Reg(CONFIG, 0x00);

  NRF_CSN_LO();
  SPI_rw(FLUSH_RX);
  NRF_CSN_HI();

  NRF_CSN_LO();
  SPI_rw(FLUSH_TX);
  NRF_CSN_HI();

  //RF settings 0 dBm, 2 Mbps, LNA Set up
  Radio_Write_Reg(RF_SETUP, 0x0F);
  //Channel settings - #4 0 to 125  
  Radio_Write_Reg(RF_CH, NRF_CHANNEL);
  //ACK settings - with ACK
  Radio_Write_Reg(EN_AA, 0xFF);
  //1000 us retransmission up to 2 times
  Radio_Write_Reg(SETUP_RETR, 0x50);

 //32 byte fifo
  Radio_Write_Reg(RX_PW_P0, NRF_BUFF_SIZE);
  Radio_Write_Reg(RX_PW_P1, NRF_BUFF_SIZE);

  //for RX_MODE
  //enable Pipe0, Pipe1
  Radio_Write_Reg(EN_RXADDR, 0x03);

  Radio_WrRXAddr(RX_ADDR_P0, ADDRESS_P0, 5);
  Radio_WrRXAddr(RX_ADDR_P1, ADDRESS_P1, 5);
  Radio_WrRXAddr(RX_ADDR_P2, ADDRESS_P2, 5);
  Radio_WrRXAddr(RX_ADDR_P3, ADDRESS_P3, 5);
  Radio_WrRXAddr(RX_ADDR_P4, ADDRESS_P4, 5);
  Radio_WrRXAddr(RX_ADDR_P5, ADDRESS_P5, 5);

//for TX_MODE       
  //Radio_WrTXAddr(ADDRESS_P0, 5);
  Radio_WrTXAddr(ADDRESS_P1, 5);
}
edit flag offensive delete publish link more

Comments

@amigo : Please edit your question and add your explanation or code in. What you wrote here is not an answer for your question. You can either comment or edit question to add information. please remove this answer after you have done.

Hung Bui ( 2017-03-21 10:03:59 +0100 )editconvert to answer
0
jorg1 gravatar image

answered 2017-03-17 15:29:57 +0100

Ronan gravatar image

updated 2017-03-18 05:38:49 +0100

TX error means that the packet was not ACKed by the receiver. If you don't have a receiver/RX set up you will get TX failed event for every payload you send.

edit flag offensive delete publish link more

Comments

My 2nd device is nrf24l01 was set up with auto ack with retransmition (1000 us up to 2 times). It works well with nrf52 only in TX mode or in Rx mode separatly. but i need nrf52 to start to works in rx mode. By request nrf52 has to answer on request, that means nrf52 runs in tx mode. then it turns back in RX mode.

Amigo ( 2017-03-17 17:38:30 +0100 )editconvert to answer

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

User menu

    or sign up

Recent questions

Question Tools

1 follower

Stats

Asked: 2017-03-17 14:47:13 +0100

Seen: 39 times

Last updated: Mar 20