Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

CAN I Customize my adv packet Absolutely?

I think this is a very weird requirement

Normally , I use manufacturer data to do this like picture below

it's easy and quick

but it contains len and type occupying 2 bytes

I'm wondering if there is a way to make my packet have no len and type

I know that Texas's chip can do this like picture below

it will shows malformed packet

Thanks

  • hi,

    I tried but failed,

    i combine the RADIO part into my original timeslot.c

    here is my new timeslot.c

    #include <stdint.h>
    #include <stdbool.h>
    #include "nrf.h"
    #include "app_error.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    #include "nrf_delay.h"
    #define PACKET_LENGTH 4
    static uint8_t packet[PACKET_LENGTH] = {1};
    /**Constants for timeslot API
    */
    static nrf_radio_request_t  m_timeslot_request;
    static uint32_t             m_slot_length;
    
    static nrf_radio_signal_callback_return_param_t signal_callback_return_param;
    
    
    void radio_configure()
    {
        // Radio config
        NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
        NRF_RADIO->FREQUENCY = 80UL;                // Frequency bin 7, 2407MHz
        NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_2Mbit << RADIO_MODE_MODE_Pos);
        // Radio address config
        NRF_RADIO->PREFIX0     = 0x4c494c49;  // Prefix byte of addresses 3 to 0
        NRF_RADIO->PREFIX1     = 0x4c494c49;  // Prefix byte of addresses 7 to 4
        NRF_RADIO->BASE0       = 0x44444444;  // Base address for prefix 0
        NRF_RADIO->BASE1       = 0x44444444;  // Base address for prefix 1-7
        NRF_RADIO->TXADDRESS   = 0x00UL;        // Set device address 0 to use when transmitting
        NRF_RADIO->RXADDRESSES = 0x01UL;        // Enable device address 0 to use which receiving
        // Packet configuration
        NRF_RADIO->PCNF0 = (1 << RADIO_PCNF0_S1LEN_Pos) |
                           (2 << RADIO_PCNF0_S0LEN_Pos) |
                           (6 << RADIO_PCNF0_LFLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"
        // Packet configuration
        NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
                           (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos)        |
                           (2 << RADIO_PCNF1_BALEN_Pos)                              |
                           ((PACKET_LENGTH) << RADIO_PCNF1_STATLEN_Pos)              |
                           ((PACKET_LENGTH) << RADIO_PCNF1_MAXLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"
        // CRC Config
        NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
        if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos))
        {
            NRF_RADIO->CRCINIT = 0xFFFFUL;   // Initial value      
            NRF_RADIO->CRCPOLY = 0x11021UL;  // CRC poly: x^16+x^12^x^5+1
        }
        else if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_One << RADIO_CRCCNF_LEN_Pos))
        {
            NRF_RADIO->CRCINIT = 0xFFUL;   // Initial value
            NRF_RADIO->CRCPOLY = 0x107UL;  // CRC poly: x^8+x^2^x^1+1
        }
        nrf_delay_ms(3);
    }
    
    
    
    /**@brief Request next timeslot event in earliest configuration
     */
    uint32_t request_next_event_earliest(void)
    {
        m_slot_length                                  = 25000;
        m_timeslot_request.request_type                = NRF_RADIO_REQ_TYPE_EARLIEST;
        m_timeslot_request.params.earliest.hfclk       = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
        m_timeslot_request.params.earliest.priority    = NRF_RADIO_PRIORITY_NORMAL;
        m_timeslot_request.params.earliest.length_us   = m_slot_length;
        m_timeslot_request.params.earliest.timeout_us  = 1000000;
        return sd_radio_request(&m_timeslot_request);
    }
    
    
    /**@brief Configure next timeslot event in earliest configuration
     */
    void configure_next_event_earliest(void)
    {
        m_slot_length                                  = 25000;
        m_timeslot_request.request_type                = NRF_RADIO_REQ_TYPE_EARLIEST;
        m_timeslot_request.params.earliest.hfclk       = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
        m_timeslot_request.params.earliest.priority    = NRF_RADIO_PRIORITY_NORMAL;
        m_timeslot_request.params.earliest.length_us   = m_slot_length;
        m_timeslot_request.params.earliest.timeout_us  = 1000000;
    }
    
    
    /**@brief Configure next timeslot event in normal configuration
     */
    void configure_next_event_normal(void)
    {
        m_slot_length                                 = 25000;
        m_timeslot_request.request_type               = NRF_RADIO_REQ_TYPE_NORMAL;
        m_timeslot_request.params.normal.hfclk        = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
        m_timeslot_request.params.normal.priority     = NRF_RADIO_PRIORITY_HIGH;
        m_timeslot_request.params.normal.distance_us  = 300000;
        m_timeslot_request.params.normal.length_us    = m_slot_length;
    }
    
    
    /**@brief Timeslot signal handler
     */
    void nrf_evt_signal_handler(uint32_t evt_id)
    {
        uint32_t err_code;
        
        switch (evt_id)
        {
            case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
                //No implementation needed
                break;
            case NRF_EVT_RADIO_SESSION_IDLE:
                //No implementation needed
                break;
            case NRF_EVT_RADIO_SESSION_CLOSED:
                //No implementation needed, session ended
                break;
            case NRF_EVT_RADIO_BLOCKED:
                //Fall through
            case NRF_EVT_RADIO_CANCELED:
                err_code = request_next_event_earliest();
                APP_ERROR_CHECK(err_code);
                break;
            default:
                break;
        }
    }
    
    
    /**@brief Timeslot event handler
     */
    nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)
    {
        switch(signal_type)
        {
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
                //Start of the timeslot - set up timer interrupt
                signal_callback_return_param.params.request.p_next = NULL;
                signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
    
    #if 1            
                NRF_TIMER0->TASKS_STOP          = 1;
                NRF_TIMER0->TASKS_CLEAR         = 1;
                NRF_TIMER0->MODE                = (TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos);
                NRF_TIMER0->EVENTS_COMPARE[0]   = 0;
                NRF_TIMER0->INTENSET            = TIMER_INTENSET_COMPARE0_Msk ;
                NRF_TIMER0->CC[0]               = m_slot_length - 1000;
                NRF_TIMER0->BITMODE             = (TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos);
                NRF_TIMER0->TASKS_START         = 1;
                //非常重要,    reset all status in the radio peripheral
                radio_configure();
                NRF_RADIO->POWER                = (RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos);
    #else
                NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
                NRF_TIMER0->CC[0] = m_slot_length - 1000;
    #endif
                NVIC_EnableIRQ(TIMER0_IRQn);
                NRF_RADIO->EVENTS_DISABLED = 0;
                NRF_RADIO->TASKS_DISABLE = 1;
                while( NRF_RADIO->EVENTS_DISABLED == 0 );
                NRF_RADIO->PACKETPTR = (uint32_t)&packet;
                        NRF_RADIO->EVENTS_READY = 0U;  				
                        NRF_RADIO->TASKS_TXEN   = 1;
                        while (NRF_RADIO->EVENTS_READY == 0U)
                       {
                       }
                       NRF_RADIO->TASKS_START = 1U;
                       NRF_RADIO->EVENTS_END  = 0U;  
                       while (NRF_RADIO->EVENTS_END == 0U)
                       {
                       }
                       NRF_RADIO->EVENTS_DISABLED = 0U;
                       // Disable radio
                       NRF_RADIO->TASKS_DISABLE = 1U;
                       while (NRF_RADIO->EVENTS_DISABLED == 0U)
                       {
                       }		 
                       NRF_RADIO->POWER = 0;
                
                nrf_gpio_pin_toggle(20); //Toggle LED4
                break;
    
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
                signal_callback_return_param.params.request.p_next = NULL;
                signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
                break;
    
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
                //Timer interrupt - do graceful shutdown - schedule next timeslot
                configure_next_event_normal();
                signal_callback_return_param.params.request.p_next = &m_timeslot_request;
                signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
                break;
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
                //No implementation needed
                break;
            case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
                //Try scheduling a new timeslot
                configure_next_event_earliest();
                signal_callback_return_param.params.request.p_next = &m_timeslot_request;
                signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
                break;
            default:
                //No implementation needed
                break;
        }
        return (&signal_callback_return_param);
    }
    
    
    /**@brief Function for initializing the timeslot API.
     */
    uint32_t timeslot_sd_init(void)
    {
        uint32_t err_code;
        
        err_code = sd_radio_session_open(radio_callback);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        
        err_code = request_next_event_earliest();
        if (err_code != NRF_SUCCESS)
        {
            (void)sd_radio_session_close();
            return err_code;
        }
        return NRF_SUCCESS;
    }
    
    
    
    

    it can still request a timeslot to blink the led,

    but it seems that RADIO is not working

    and i am so confused about some of the settings(registers),even i read the product specification

     Any suggestions will be appreciated

  • Hello,

    Thank you for your patience!

    Aku said:
    I tried but failed,

    I am sorry to hear that! Lets see if we cant resolve this issue together.

    Aku said:

    it can still request a timeslot to blink the led,

    but it seems that RADIO is not working

    Then we know that the device is not resetting, or otherwise failing, at least.
    How have you verified that the radio is not working? 

    Aku said:
    and i am so confused about some of the settings(registers),even i read the product specification

    Do you mean that you read the nRF52832 RADIO peripheral's documentation, but you are still confused about some of the configurations? Is there any register / configuration in particular you would like me to explain?

    You could use the nrf_radio_event_check function to see whether a certain event has occurred, or nrf_radio_state_get to check whether the configuration was a success, or in general which state the radio is in at that time. The transmit sequence diagram indicates how the state-transitions should be during a transfer.
    Could you these conditional checks, so that you are sure not to proceed to start the next RADIO TASK, before the radio is ready?

    Best regards,
    Karl

Related