直接通过Radio寄存器发送BLE广播数据包

51822模拟ble广播-实践-ifndef-ChinaUnix博客

nrf5x radio射频模拟ble广播数据_一颗偏执的心-CSDN博客

#include "nrf51.h"
 
#include "nrf_gpio.h"
 
#include <stdio.h>
 
#include <string.h>
 
#include "nrf_delay.h"
 
 
uint8_t adv_data[10] = {0x02,0x01,0x04,   0x06,0x09,0x4e,0x6f,0x48,0x52,0x3d};
 
uint8_t device_add[6]={0xFF,0x01,0x02,0x03,0x05,0xff};
 
 
static uint8_t adv_array[37] = {0};
 
 
void  init_clock(void){
 
       NRF_CLOCK->XTALFREQ = 0xff;             //16M
 
       NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
 
       NRF_CLOCK->TASKS_HFCLKSTART = 1;
 
       while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0){     
 
       }      //等待启振完成    
 
}
 
void radio_init(void){
 
       //这里设置8个逻辑地址的实际地址,因为我们只是做广播,所以把全部地址都设置成0x8E89BED6,
 
       NRF_RADIO->BASE0 = (0x89BED600);
 
       NRF_RADIO->BASE1 = (0x89BED600); 
 
       NRF_RADIO->PREFIX0 = 0x8E8E8E8E;
 
       NRF_RADIO->PREFIX1 = 0x8E8E8E8E;
 
 
       NRF_RADIO->TXADDRESS = 0; //使用逻辑地址0
      
 
       NRF_RADIO->CRCCNF = (3<<0) | (1<<8);     //3字节crc,计算不包括接入地址部分
 
       NRF_RADIO->CRCPOLY = 0x100065b;//crc多项式为 x^24+x^10+x^9+x^6+x^4+x^3+x^1+x^0
 
       NRF_RADIO->CRCINIT =  0x555555;    //广播信道的数据包中crc初始值为0x555555
 
       NRF_RADIO->PACKETPTR = (uint32_t)&adv_array[0];
 
       NRF_RADIO->FREQUENCY = 2;       //链路层信道编号 37:2402MHz, 38:2426MHz, 39:2480MHz
 
       NRF_RADIO->TXPOWER = 0x04;
 
       NRF_RADIO->MODE = 0x03;   //ble_1Mbit
 
      
 
       //8bit长度的LENGTH  1字节长度的S0,不需要s1,因为广播格式里面负载数据前面只需要2字节头,一个是报头,一个是长度。
 
       NRF_RADIO->PCNF0 = (8<<0) | (1<<8);
 
       //payload最大长度37,没有静态长度,基础地址为3字节,所以加一字节头后为四字节,就是蓝牙规范中接入地址.字节序为小端(CRC不在这里设置)
 
       //使能数据白化
 
       NRF_RADIO->PCNF1 = (31<<0) | (3<<16) | (1<<25) ;
 
       NRF_RADIO->DATAWHITEIV = 0x25;//0x25;        //初始值由报文所在链路层信道号决定,这里为37
 
}
 
 
 
void set_advdata(void){
 
       adv_array[0] = 2;       //PDU Type为ADV_NONCONN_IND,如果设置成普通广播的话,手机可能会发扫描包,因为这里没有做扫描回应,手机就会过滤该设备,导致手机搜不到设备。
 
       adv_array[1] = 0;//最后再计算长度
 
       memcpy(adv_array+2, device_add, 6);
 
       memcpy(adv_array+2+6, adv_data, sizeof(adv_data));
 
       adv_array[1] = 6+sizeof(adv_data);
 
}
 
void send_data(void){
 
       NRF_RADIO->EVENTS_READY = 0;
 
       NRF_RADIO->TASKS_TXEN = 1;
 
       while(NRF_RADIO->EVENTS_READY == 0){}       //等待准备好
 
      
       NRF_RADIO->EVENTS_END = 0;
 
 
       NRF_RADIO->TASKS_START = 1;           
 
       while(NRF_RADIO->EVENTS_END == 0)//等待发送完成
 
      
       NRF_RADIO->EVENTS_DISABLED = 0;
 
       NRF_RADIO->TASKS_DISABLE = 1;
 
       while(NRF_RADIO->EVENTS_DISABLED == 0){}//等待停止完成
}
 
int main(void)
{
 
       uint32_t data;
 
       init_clock();
 
       radio_init();
 
       set_advdata();
 
       while(1){
 
              nrf_delay_ms(50);
 
              send_data();     
 
       }
 
       return 0;
 
}
/**
 * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
*
* @defgroup nrf_dev_button_radio_tx_example_main main.c
* @{
* @ingroup nrf_dev_button_radio_tx_example
*
* @brief Radio Transceiver Example Application main file.
*
* This file contains the source code for a sample application using the NRF_RADIO peripheral.
*
*/

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "radio_config.h"
#include "nrf_gpio.h"
#include "app_timer.h"
#include "boards.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_error.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

static uint32_t                   packet;                    /**< Packet to transmit. */


typedef struct
{
    uint8_t tag_id[6];
    uint8_t packet_len;
    uint8_t invariant_byte[4];
    uint8_t header;
    uint8_t tag_type;
	uint8_t data_payload[24];
}tag_packet_data_t;

static tag_packet_data_t df_tx_packet; 

const static uint8_t invariant_bytes[4] = {0xFF, 0xD1, 0x07, 0x00}; // ¹Ì¶¨×Ö½Ú£¨0xFF:×Ô¶¨ÒåÊý¾Ý£» 0x07D1£ºÅÍÆô΢À¶ÑÀID£» 0x00£º¹«Ë¾´úÂ룩
const static uint8_t df_packet_37[20] = {0x2F, 0x61, 0xAC, 0xCC, 0x27, 0x45, 0x67, 0xF7, 0xDB, 0x34, 0xC4, 0x03, 0x8E, 0x5C, 0x0B, 0xAA, 0x97, 0x30, 0x56, 0xE6};	// 37ÐŵÀ¼ÓÃܶ¨Î»°ü

#define BLE_PHY_MAX_PDU_LEN         (257)
static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];

static void send_packet(const void *p_packet)
{
    NRF_RADIO->PACKETPTR = (uint32_t)p_packet;
    
	//set frequency and datawhiteiv
	NRF_RADIO->FREQUENCY = 0x02; 
	NRF_RADIO->DATAWHITEIV  = 37;   
	
    // send the packet:
    NRF_RADIO->EVENTS_READY = 0U;
    NRF_RADIO->TASKS_TXEN   = 1;

    while (NRF_RADIO->EVENTS_READY == 0U)
    {
        // wait
    }
    NRF_RADIO->EVENTS_END  = 0U;
    NRF_RADIO->TASKS_START = 1U;

    while (NRF_RADIO->EVENTS_END == 0U)
    {
        // wait
    }

    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;

    while (NRF_RADIO->EVENTS_DISABLED == 0U)
    {
        // wait
    }
}


void receive_packet(const void *p_packet)
{
    NRF_RADIO->PACKETPTR = (uint32_t)p_packet;
    NRF_RADIO->FREQUENCY = 0x02;          
    NRF_RADIO->DATAWHITEIV  = 0x25;
    NRF_RADIO->EVENTS_READY = 0U;
    // Enable radio and wait for ready
    NRF_RADIO->TASKS_RXEN = 1U;

    //NRF_LOG_INFO("Line:%d", __LINE__);
    
    while (NRF_RADIO->EVENTS_READY == 0U)
    {
        // wait
    }
    NRF_RADIO->EVENTS_END = 0U;
    // Start listening and wait for address received event
    NRF_RADIO->TASKS_START = 1U;
    //NRF_LOG_INFO("Line:%d", __LINE__);
    // Wait for end of packet or buttons state changed
    while (NRF_RADIO->EVENTS_END == 0U)
    {
        // wait
    }
    //NRF_LOG_INFO("Line:%d", __LINE__);
    if (NRF_RADIO->CRCSTATUS == 1U)
    {
        // result = packet;
    }
    
    if (NRF_RADIO->EVENTS_ADDRESS == 1U)
    {
        NRF_LOG_INFO("AS");
    }
    
    if (NRF_RADIO->EVENTS_PAYLOAD == 1U)
    {
        NRF_LOG_INFO("PL");
    }
    NRF_LOG_INFO("CRX:0x%08x", NRF_RADIO->RXCRC);
    NRF_LOG_INFO("RSSI:%d", NRF_RADIO->RSSISAMPLE);
    NRF_LOG_INFO("Line:%d, crc:%d", __LINE__, NRF_RADIO->CRCSTATUS);
    
    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;

    while (NRF_RADIO->EVENTS_DISABLED == 0U)
    {
        // wait
    }
    
}


/**@brief Function for handling bsp events.
 */
void bsp_evt_handler(bsp_event_t evt)
{
    uint32_t prep_packet = 0;
    switch (evt)
    {
        case BSP_EVENT_KEY_0:
            /* Fall through. */
        case BSP_EVENT_KEY_1:
            /* Fall through. */
        case BSP_EVENT_KEY_2:
            /* Fall through. */
        case BSP_EVENT_KEY_3:
            /* Fall through. */
        case BSP_EVENT_KEY_4:
            /* Fall through. */
        case BSP_EVENT_KEY_5:
            /* Fall through. */
        case BSP_EVENT_KEY_6:
            /* Fall through. */
        case BSP_EVENT_KEY_7:
            /* Get actual button state. */
            for (int i = 0; i < BUTTONS_NUMBER; i++)
            {
                prep_packet |= (bsp_board_button_state_get(i) ? (1 << i) : 0);
            }
            break;
        default:
            /* No implementation needed. */
            break;
    }
    packet = prep_packet;
}


/**@brief Function for initialization oscillators.
 */
void clock_initialization()
{
    /* Start 16 MHz crystal oscillator */
    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.
    }

    /* Start low frequency crystal oscillator for app_timer(used by bsp)*/
    NRF_CLOCK->LFCLKSRC            = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_LFCLKSTART    = 1;

    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
        // Do nothing.
    }
}

/* These are set to zero as ShockBurst packets don't have corresponding fields. */
#define PACKET_S1_FIELD_SIZE      (0UL)  /**< Packet S1 field size in bits. */
#define PACKET_S0_FIELD_SIZE      (0UL)  /**< Packet S0 field size in bits. */
#define PACKET_LENGTH_FIELD_SIZE  (0UL)  /**< Packet length field size in bits. */

static void jw_radio_config(void)
{
	NRF_POWER->DCDCEN  = 1; 	// Enable DC/DC
    NRF_RADIO->POWER   = 1;
    NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
    NRF_RADIO->MODE    = (RADIO_MODE_MODE_Ble_1Mbit << RADIO_MODE_MODE_Pos);

    NRF_RADIO->PREFIX0 = 0x0000008e;    // access_addr[3]
    NRF_RADIO->BASE0   = 0x89bed600;    // access_addr[0:3]
    
    //NRF_RADIO->BASE0 = (0x89BED600);
    //NRF_RADIO->BASE1 = (0x89BED600); 
    //NRF_RADIO->PREFIX0 = 0x8E8E8E8E;
    //NRF_RADIO->PREFIX1 = 0x8E8E8E8E;
    
    NRF_RADIO->TXADDRESS   = 0x00UL;
    NRF_RADIO->RXADDRESSES = 0x01UL;

    // 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);

    // Packet configuration
    NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Enabled << RADIO_PCNF1_WHITEEN_Pos) |
                       (RADIO_PCNF1_ENDIAN_Little << 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);

    NRF_RADIO->SHORTS |= (0x1UL << 4);

    // CRC Config
    //NRF_RADIO->CRCCNF = (((RADIO_CRCCNF_SKIPADDR_Skip) << RADIO_CRCCNF_SKIPADDR_Pos) & RADIO_CRCCNF_SKIPADDR_Msk) | (((RADIO_CRCCNF_LEN_Three) << RADIO_CRCCNF_LEN_Pos) & RADIO_CRCCNF_LEN_Msk);
    NRF_RADIO->CRCCNF = (3<<0) | (1<<8);
    NRF_RADIO->CRCPOLY = 0x100065b;
    NRF_RADIO->CRCINIT = 0x00555555;
}


/**
 * @brief Function for application main entry.
 * @return 0. int return type required by ANSI/ISO standard.
 */
int main(void)
{
    uint32_t err_code = NRF_SUCCESS;

    clock_initialization();

    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();

//    err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);
//    APP_ERROR_CHECK(err_code);

    
    uint8_t tag_id[6];
    memset(tag_id, 0x06, 6);
    memset(&df_tx_packet, 0, sizeof(tag_packet_data_t));
    memcpy(df_tx_packet.tag_id, tag_id, 6);
	df_tx_packet.packet_len = 0x1E;
	memcpy(df_tx_packet.invariant_byte, invariant_bytes, 4);
	df_tx_packet.header |= 0x02;
	df_tx_packet.tag_type = 0x0D;
	memcpy(df_tx_packet.data_payload+4, df_packet_37, 20);
    
    jw_radio_config();
    uint8_t tx_packet[39], rx_packet[39];
    tx_packet[0]=0x02;
    tx_packet[1]=0x25;
    memcpy(tx_packet+2, &df_tx_packet, sizeof(df_tx_packet));
    // Set radio configuration parameters
//    radio_configure();
    // Set payload pointer
//    NRF_RADIO->PACKETPTR = (uint32_t)&packet;

//    err_code = bsp_indication_set(BSP_INDICATE_USER_STATE_OFF);
    NRF_LOG_INFO("Radio transmitter example started.");
    NRF_LOG_INFO("Press Any Button");
//    APP_ERROR_CHECK(err_code);

    while (true)
    {
//        if (packet != 0)
//        {
//            send_packet();
//            NRF_LOG_INFO("The contents of the package was %u", (unsigned int)packet);
//            packet = 0;
//        }
        //send_packet(tx_packet);
        receive_packet(g_ble_phy_rx_buf);
        NRF_LOG_RAW_HEXDUMP_INFO(g_ble_phy_rx_buf, sizeof(g_ble_phy_rx_buf)); 
        NRF_LOG_FLUSH();
//        __WFE();
    }
}


/**
 *@}
 **/
#ifndef RADIO_CONFIG_H
#define RADIO_CONFIG_H

#ifdef __cplusplus
extern "C" {
#endif

#define PACKET_BASE_ADDRESS_LENGTH  (4UL)                   //!< Packet base address length field size in bytes
//#define PACKET_STATIC_LENGTH        (1UL)                   //!< Packet static length in bytes
#define PACKET_STATIC_LENGTH        (27UL)//(255UL)//payload
#define PACKET_PAYLOAD_MAXSIZE      (PACKET_STATIC_LENGTH)  //!< Packet payload maximum size in bytes

void radio_configure(void);


#ifdef __cplusplus
}
#endif

#endif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值