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