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

NRF52 ESB RX-TX

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.

  • @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.

Related