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

How can I make nrf51822 talk to Microbit by RADIO

Dear Nordic Semiconductor support team.

I tried to make my nrf51822 DK to talk to Micro:bit by using Gazell library. ( from nRF5_SDK_12.3.0_d7731ad\examples\proprietary_rf\gzll\gzll_ack_payload\host)

I've read your support using micro:bit with nrf52832 by RADIO in the past as follows.

https://devzone.nordicsemi.com/f/nordic-q-a/41770/how-can-i-make-nrf52832-talk-to-microbit-by-radio-gazell

So I rewrite a simple function base on your code, hoping to receive wireless data from Microbit. And insert the breakpoint in nrf_gzll_host_rx_data_ready() function.  Use the MDK 5.20 and Jlink V9

#include "nrf_gzll.h"
#include "bsp.h"
#include "app_timer.h"
#include "app_error.h"
#include "nrf_gzll_error.h"

#define NRF_LOG_MODULE_NAME "APP"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"

/*****************************************************************************/
/** @name Configuration  */
/*****************************************************************************/
#define PIPE_NUMBER             0  ///< Pipe 0 is used in this example.

#define TX_PAYLOAD_LENGTH       1  ///< 1-byte payload length is used when transmitting.

#define APP_TIMER_PRESCALER     0  ///< Value of the RTC PRESCALER register.
#define APP_TIMER_OP_QUEUE_SIZE 8u ///< Size of timer operation queues.


#define MICROBIT_RADIO_MAX_PACKET_SIZE          32


static uint8_t m_data_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; ///< Placeholder for data payload received from host.
static uint8_t m_ack_payload[TX_PAYLOAD_LENGTH];                  ///< Payload to attach to ACK sent to device.

extern nrf_gzll_error_code_t nrf_gzll_error_code;                 ///< Error code.



/**
 * @brief Initialize the BSP modules.
 */
static void ui_init(void)
{
    // Initialize application timer.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);

    // BSP initialization.
    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS,
                                 APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),
                                 NULL);
    APP_ERROR_CHECK(err_code);

    // Set up logger.
    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_INFO("Gazell ACK payload example. Host mode.\r\n");
    NRF_LOG_FLUSH();

}


/*****************************************************************************/
/** @name Gazell callback function definitions.  */
/*****************************************************************************/
/**
 * @brief RX data ready callback.
 *
 * @details If a data packet was received, the first byte is written to LEDS.
 */
void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
{
    uint32_t data_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;

    // Pop packet and write first byte of the payload to the GPIO port.
    bool result_value = nrf_gzll_fetch_packet_from_rx_fifo(pipe,
                                                           m_data_payload,
                                                           &data_payload_length);
    if (!result_value)// I Insert the breakpoint here. 
    {
        NRF_LOG_ERROR("RX fifo error \r\n");
        NRF_LOG_FLUSH();
    }


    m_ack_payload[0] = 0xFD;

    result_value = nrf_gzll_add_packet_to_tx_fifo(pipe, m_ack_payload, TX_PAYLOAD_LENGTH);
    if (!result_value)
    {
        NRF_LOG_ERROR("TX fifo error \r\n");
        NRF_LOG_FLUSH();
    }
}


/**
 * @brief Gazelle callback.
 * @warning Required for successful Gazell initialization.
 */
void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
{
}


/**
 * @brief Gazelle callback.
 * @warning Required for successful Gazell initialization.
 */
void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
{
}


/**
 * @brief Gazelle callback.
 * @warning Required for successful Gazell initialization.
 */
void nrf_gzll_disabled()
{
}



#define NRF_GZLL_TEST_CHANNEL_TABLE_SIZE   1

#define MICROBIT_RADIO_BASE_ADDRESS 0x75626974

static uint8_t Test_chanel_table[] = {7};

static uint32_t swap_bits(uint32_t inp)
{
    uint32_t i;
    uint32_t retval = 0;

    inp = (inp & 0x000000FFUL);

    for (i = 0; i < 8; i++)
    {
        retval |= ((inp >> i) & 0x01) << (7 - i);
    }

    return retval;
}

static uint32_t bytewise_bitswap(uint32_t inp)
{
      return (swap_bits(inp >> 24) << 24)
           | (swap_bits(inp >> 16) << 16)
           | (swap_bits(inp >> 8) << 8)
           | (swap_bits(inp));
}



/*****************************************************************************/
/**
 * @brief Main function.
 * @return ANSI required int return type.
 */
/*****************************************************************************/
int main()
{
    // Set up the user interface.
    ui_init();

    // Initialize Gazell.
    nrf_gzll_init(NRF_GZLL_MODE_HOST);


    // Load data into TX queue.
    m_ack_payload[0] = 0xFD;//I have no idea what that data for...

    nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, m_data_payload, TX_PAYLOAD_LENGTH);

		
		 //Edit //by Bob
    nrf_gzll_set_channel_table(Test_chanel_table,NRF_GZLL_TEST_CHANNEL_TABLE_SIZE);
    nrf_gzll_set_base_address_0(bytewise_bitswap(0x74696275));
    nrf_gzll_set_address_prefix_byte(0, 0);// pipe, address_prefix_byte
    nrf_gzll_set_datarate(NRF_GZLL_DATARATE_1MBIT);


    // Enable Gazell to start sending over the air.
    nrf_gzll_enable();

        NRF_RADIO->PCNF0 = 0x00000008;
        NRF_RADIO->PCNF1 = 0x02040000 | MICROBIT_RADIO_MAX_PACKET_SIZE;
        NRF_RADIO->DATAWHITEIV = 0x18;
    

    while (1)
    {
        __WFE();
    }
}

The code can run, but never receive any data from MicroBit, cause the breakpoint has not been triggered.

MicroBit  code:

radio.setGroup(0)
basic.forever(function () {
    radio.sendNumber(1)
    basic.pause(100)
})

Thanks.

Parents
  • Hi 

    I believe this is the implementation of the radio library for MicroBit:
    https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitRadio.cpp

    Looking at this code I see that it has nothing to do with Gazell. 

    Instead this is a very low level RF protocol implemented on top of the RADIO peripheral, and does not include Gazell features such as auto ACK, ACK payload, frequency jumping, multiple pipes etc. 

    In other words I would not recommend using the Gazell library in the nRF51 if you want to interface to the MicroBit. 

    Rather I would try to port the code from the link I included above to run on the kit. 
    Since most of the code is accessing hardware registers only this should be relatively straight forward, but you would need to change the code interfacing other MicroBit support libraries. 

    The radio receiver example in the nRF5 SDK v12.3.0 can also be used for reference:
    \nRF5_SDK_12.3.0_d7731ad\examples\peripheral\radio\receiver

    Best regards
    Torbjørn

Reply
  • Hi 

    I believe this is the implementation of the radio library for MicroBit:
    https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitRadio.cpp

    Looking at this code I see that it has nothing to do with Gazell. 

    Instead this is a very low level RF protocol implemented on top of the RADIO peripheral, and does not include Gazell features such as auto ACK, ACK payload, frequency jumping, multiple pipes etc. 

    In other words I would not recommend using the Gazell library in the nRF51 if you want to interface to the MicroBit. 

    Rather I would try to port the code from the link I included above to run on the kit. 
    Since most of the code is accessing hardware registers only this should be relatively straight forward, but you would need to change the code interfacing other MicroBit support libraries. 

    The radio receiver example in the nRF5 SDK v12.3.0 can also be used for reference:
    \nRF5_SDK_12.3.0_d7731ad\examples\peripheral\radio\receiver

    Best regards
    Torbjørn

Children
Related