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

Radio Receiver with Timeslot Problem

Hello

I am trying to implement  radio receiver using the time slot API and I am facing some problems to make it work. I am using nrf51822 with SD130 (sdk8) and the device is configured in central mode. I want to receive some data sent from another nrf device which runs nrf radio transmitter example.In order to run the RF radio i am using time slot api which is tested and working fine.However, when i try to run the radio receiver code in the time slot the radio is unable to receive any data and from debugging  i can see that it gets stuck in the following line  even though the transmitter is continuously sending the data. 

 // Start listening and wait for address received event
    NRF_RADIO->TASKS_START = 1U;
    // Wait for end of packet or buttons state changed
    while ((NRF_RADIO->EVENTS_END == 0U)&&(error!=0))
    {
        // wait
		
    }

Please have look at the below code snippet.

timeslot code.

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;
					
				
						NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer;  
						NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_32Bit;  
						NRF_TIMER0->PRESCALER = 4;  
            NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
            NRF_TIMER0->CC[0] = m_slot_length - 1000;
            NVIC_EnableIRQ(TIMER0_IRQn); 
						
						Timeslot=true;  		
            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
           signal_callback_return_param.params.extend.length_us = m_slot_length;
					 signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;
						
            break;
        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
            //No implementation needed
						NRF_TIMER0->TASKS_CLEAR = 1;
            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);
}

And i am reading the radio as shown below.

            
            
/**@brief Function for reading packet.
 */
uint32_t read_packet()
{
    uint32_t result = 0;
		uint32_t error=0;

    NRF_RADIO->EVENTS_READY = 0U;
    // Enable radio and wait for ready
    NRF_RADIO->TASKS_RXEN = 1U;
		error=10000;
    while ((NRF_RADIO->EVENTS_READY == 0U)&&(error!=0))
    {
        // wait
			error--;
    }
    NRF_RADIO->EVENTS_END = 0U;
    // Start listening and wait for address received event
    NRF_RADIO->TASKS_START = 1U;
		error=10000;
    // Wait for end of packet or buttons state changed
    while ((NRF_RADIO->EVENTS_END == 0U)&&(error!=0))
    {
        // wait
			error--;
    }

    if (NRF_RADIO->CRCSTATUS == 1U)
    {
        //result = packet;
    }
    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;
		error=10000;
    while ((NRF_RADIO->EVENTS_DISABLED == 0U)&&(error!=0))
    {
        // wait
			error--;
    }
	
    return result;
}
            
            
            if(Timeslot)
			{
				//clock_initialization();
				radio_configure();
				read_packet();
				Timeslot=false;
				//printf("ok");
				printf("%c",packet[0]);
				printf("%c",packet[9]);
				configure_next_event_normal();
			}

Could you please help me to understand the issue with this implementation or suggest me the best method to realize this.

Parents
  • Hi,

     

    Is the radio configuration 100 % equal on both transmitter and receiver? CRC settings, data rate, RF channel, and so forth?

    Could you show the radio configuration for both sides?

    Kind regards,

    Håkon

  • Sorry for the late reply. Yes I believe that I have configured both sides with same settings. Please have a look at the below code. 

    Receiver side

    
    #define PACKET_BASE_ADDRESS_LENGTH  (4UL)                   //!< Packet base address length field size in bytes
    #define PACKET_STATIC_LENGTH        (10UL)                   //!< Packet static length in bytes
    #define PACKET_PAYLOAD_MAXSIZE      (PACKET_STATIC_LENGTH)  //!< Packet payload maximum size in bytes
    
    
    void radio_configure()
    {
        // Radio config
        NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_Pos4dBm<< RADIO_TXPOWER_TXPOWER_Pos);
        NRF_RADIO->FREQUENCY = 7UL;  // Frequency bin 7, 2407MHz
        NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_250Kbit << RADIO_MODE_MODE_Pos);
    
        // Radio address config
        NRF_RADIO->PREFIX0 = 
            ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC1) << 8)  // Prefix byte of address 1 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
      
        NRF_RADIO->PREFIX1 = 
            ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format
    
        NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL);  // Base address for prefix 0 converted to nRF24L series format
        NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL);  // Base address for prefix 1-7 converted to nRF24L series format
      
        NRF_RADIO->TXADDRESS   = 0x00UL;  // Set device address 0 to use when transmitting
        NRF_RADIO->RXADDRESSES = 0x01UL;  // Enable device address 0 to use to select which addresses to receive
    
        // Packet configuration
        NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE     << RADIO_PCNF0_S1LEN_Pos) |
                           (PACKET_S0_FIELD_SIZE     << RADIO_PCNF0_S0LEN_Pos) |
                           (PACKET_LENGTH_FIELD_SIZE << 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)  |
                           (PACKET_BASE_ADDRESS_LENGTH   << RADIO_PCNF1_BALEN_Pos)   |
                           (PACKET_STATIC_LENGTH         << RADIO_PCNF1_STATLEN_Pos) |
                           (PACKET_PAYLOAD_MAXSIZE       << 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_RADIO->PACKETPTR = (uint32_t)&packet;
    		NRF_RADIO->POWER=(RADIO_POWER_POWER_Enabled<<RADIO_POWER_POWER_Pos);
    }
    Transmitter side

    #define PACKET_BASE_ADDRESS_LENGTH  (4UL)                   //!< Packet base address length field size in bytes
    #define PACKET_STATIC_LENGTH        (10UL)                   //!< Packet static length in bytes
    #define PACKET_PAYLOAD_MAXSIZE      (PACKET_STATIC_LENGTH)  //!< Packet payload maximum size in bytes
    
    
    void radio_configure()
    {
        // Radio config
        NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_Pos4dBm<< RADIO_TXPOWER_TXPOWER_Pos);
        NRF_RADIO->FREQUENCY = 7UL;  // Frequency bin 7, 2407MHz
        NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_250Kbit << RADIO_MODE_MODE_Pos);
    
        // Radio address config
        NRF_RADIO->PREFIX0 = 
            ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC1) << 8)  // Prefix byte of address 1 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
      
        NRF_RADIO->PREFIX1 = 
            ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format
    
        NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL);  // Base address for prefix 0 converted to nRF24L series format
        NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL);  // Base address for prefix 1-7 converted to nRF24L series format
      
        NRF_RADIO->TXADDRESS   = 0x00UL;  // Set device address 0 to use when transmitting
        NRF_RADIO->RXADDRESSES = 0x01UL;  // Enable device address 0 to use to select which addresses to receive
    
        // Packet configuration
        NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE     << RADIO_PCNF0_S1LEN_Pos) |
                           (PACKET_S0_FIELD_SIZE     << RADIO_PCNF0_S0LEN_Pos) |
                           (PACKET_LENGTH_FIELD_SIZE << 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)  |
                           (PACKET_BASE_ADDRESS_LENGTH   << RADIO_PCNF1_BALEN_Pos)   |
                           (PACKET_STATIC_LENGTH         << RADIO_PCNF1_STATLEN_Pos) |
                           (PACKET_PAYLOAD_MAXSIZE       << 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
        }
    }

    Thank you so much for the support.

Reply
  • Sorry for the late reply. Yes I believe that I have configured both sides with same settings. Please have a look at the below code. 

    Receiver side

    
    #define PACKET_BASE_ADDRESS_LENGTH  (4UL)                   //!< Packet base address length field size in bytes
    #define PACKET_STATIC_LENGTH        (10UL)                   //!< Packet static length in bytes
    #define PACKET_PAYLOAD_MAXSIZE      (PACKET_STATIC_LENGTH)  //!< Packet payload maximum size in bytes
    
    
    void radio_configure()
    {
        // Radio config
        NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_Pos4dBm<< RADIO_TXPOWER_TXPOWER_Pos);
        NRF_RADIO->FREQUENCY = 7UL;  // Frequency bin 7, 2407MHz
        NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_250Kbit << RADIO_MODE_MODE_Pos);
    
        // Radio address config
        NRF_RADIO->PREFIX0 = 
            ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC1) << 8)  // Prefix byte of address 1 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
      
        NRF_RADIO->PREFIX1 = 
            ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format
    
        NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL);  // Base address for prefix 0 converted to nRF24L series format
        NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL);  // Base address for prefix 1-7 converted to nRF24L series format
      
        NRF_RADIO->TXADDRESS   = 0x00UL;  // Set device address 0 to use when transmitting
        NRF_RADIO->RXADDRESSES = 0x01UL;  // Enable device address 0 to use to select which addresses to receive
    
        // Packet configuration
        NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE     << RADIO_PCNF0_S1LEN_Pos) |
                           (PACKET_S0_FIELD_SIZE     << RADIO_PCNF0_S0LEN_Pos) |
                           (PACKET_LENGTH_FIELD_SIZE << 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)  |
                           (PACKET_BASE_ADDRESS_LENGTH   << RADIO_PCNF1_BALEN_Pos)   |
                           (PACKET_STATIC_LENGTH         << RADIO_PCNF1_STATLEN_Pos) |
                           (PACKET_PAYLOAD_MAXSIZE       << 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_RADIO->PACKETPTR = (uint32_t)&packet;
    		NRF_RADIO->POWER=(RADIO_POWER_POWER_Enabled<<RADIO_POWER_POWER_Pos);
    }
    Transmitter side

    #define PACKET_BASE_ADDRESS_LENGTH  (4UL)                   //!< Packet base address length field size in bytes
    #define PACKET_STATIC_LENGTH        (10UL)                   //!< Packet static length in bytes
    #define PACKET_PAYLOAD_MAXSIZE      (PACKET_STATIC_LENGTH)  //!< Packet payload maximum size in bytes
    
    
    void radio_configure()
    {
        // Radio config
        NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_Pos4dBm<< RADIO_TXPOWER_TXPOWER_Pos);
        NRF_RADIO->FREQUENCY = 7UL;  // Frequency bin 7, 2407MHz
        NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_250Kbit << RADIO_MODE_MODE_Pos);
    
        // Radio address config
        NRF_RADIO->PREFIX0 = 
            ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC1) << 8)  // Prefix byte of address 1 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
      
        NRF_RADIO->PREFIX1 = 
            ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
          | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format
    
        NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL);  // Base address for prefix 0 converted to nRF24L series format
        NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL);  // Base address for prefix 1-7 converted to nRF24L series format
      
        NRF_RADIO->TXADDRESS   = 0x00UL;  // Set device address 0 to use when transmitting
        NRF_RADIO->RXADDRESSES = 0x01UL;  // Enable device address 0 to use to select which addresses to receive
    
        // Packet configuration
        NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE     << RADIO_PCNF0_S1LEN_Pos) |
                           (PACKET_S0_FIELD_SIZE     << RADIO_PCNF0_S0LEN_Pos) |
                           (PACKET_LENGTH_FIELD_SIZE << 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)  |
                           (PACKET_BASE_ADDRESS_LENGTH   << RADIO_PCNF1_BALEN_Pos)   |
                           (PACKET_STATIC_LENGTH         << RADIO_PCNF1_STATLEN_Pos) |
                           (PACKET_PAYLOAD_MAXSIZE       << 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
        }
    }

    Thank you so much for the support.

Children
  • The configuration looks similar on both receiver and transmitter.

    Could it be that you haven't started the HFCLK? By default, the HFCLK will be sourced by the internal RC oscillator, which is not accurate enough to be used with the radio.

    Could you try to add this function on both receiver and transmitter, prior to starting the radio, to see if that helps?

        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    
        /* Wait for the external oscillator to start up */
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        {
            // Do nothing.
        }

    Kind regards,

    Håkon

Related