NRF52832 development: RF driver

NRF52832 development: RF driver

This article blog link:http://blog.csdn.net/jdh99 , author: jdh, reprint please specify.

 

surroundings:

Development environment: MDK5.23


Description:
Write NRF52832 radio frequency driver. In this design, the radio frequency module is always receiving. If there is sending, it will automatically switch to receiving after sending.
RF module state machine:


Source code:

drv_radio.h

/**
* Copyright (c), 2015-2025
* @file drv_radio.h
* @brief 射频模块驱动层头文件
* @author jdh
* @date 2017/6/28
* @update 2017/8/17
* @update 2017/8/28
*/

#ifndef _DRV_RADIO_H_
#define _DRV_RADIO_H_

/*********************************************************************
*							头文件
**********************************************************************/

#include "def.h"

/*********************************************************************
*							宏定义
**********************************************************************/

/**
* @brief 缓存字节数
*/

#define RADIO_BUF_SIZE				256

/*********************************************************************
*							数据结构
**********************************************************************/

/**
* @brief 发送功率
*/

typedef enum
{
	RADIO_TXPOWER_0DBM = 0x00,
	RADIO_TXPOWER_POS3DBM = 0x03,
	RADIO_TXPOWER_POS4DBM = 0x04,
	RADIO_TXPOWER_NEG40DBM = 0xD8,
	RADIO_TXPOWER_NEG20DBM = 0xEC,
	RADIO_TXPOWER_NEG16DBM = 0xF0,
	RADIO_TXPOWER_NEG12DBM = 0xF4,
	RADIO_TXPOWER_NEG8DBM = 0xF8,
	RADIO_TXPOWER_NEG4DBM = 0xFC
} TxPower;

/**
* @brief 波特率
*/

typedef enum
{
	RADIO_BAUDRATE_1M = 0,
	RADIO_BAUDRATE_2M = 1
} RadioBaudrate;

/**
* @brief 中断类型
*/

typedef enum
{
	RADIO_IRQ_NULL = 0,
	RADIO_IRQ_EVENTS_READY = 1,
	RADIO_IRQ_EVENTS_END = 2,
	RADIO_IRQ_EVENTS_DISABLED = 3
} RadioIrqEvents;

/**
* @brief 射频状态
*/
typedef enum
{
	RADIO_STATE_DISABLE = 0,
	RADIO_STATE_RXRU = 1,
	RADIO_STATE_RXIDLE = 2,
	RADIO_STATE_RX = 3,
	RADIO_STATE_RXDISABLE = 4,
	RADIO_STATE_TXRU = 9,
	RADIO_STATE_TXIDLE = 10,
	RADIO_STATE_TX = 11,
	RADIO_STATE_TXDISABLE = 12
} RadioState;

/*********************************************************************
*							函数
**********************************************************************/

/**
* @brief 设置射频模块发射功率
* @param txpower: 发射功率
*/

void drv_radio_set_txpower(TxPower tx_power);

/**
* @brief 读取射频模块发射功率
* @retval 发射功率
*/

TxPower drv_radio_get_txpower(void);

/**
* @brief 设置射频模块频点
* @param 工作频率.范围:[2360,2500]
*/

void drv_radio_set_frequency(uint16_t frequency);

/**
* @brief 读取射频模块频点
* @retval 工作频率
*/

uint16_t drv_radio_get_frequency(void);

/**
* @brief 设置射频模块通讯速率
* @param baudrate: 波特率
*/

void drv_radio_set_baudrate(RadioBaudrate baudrate);

/**
* @brief 读取射频模块通讯速率
* @retval 通讯速率
*/

RadioBaudrate drv_radio_get_baudrate(void);

/**
* @brief 设置射频模块通讯地址
* @param address: 地址
*/

void drv_radio_set_address(uint32_t address);

/**
* @brief 设置射频模块通讯地址
* @retval 地址
*/

uint32_t drv_radio_get_address(void);

/**
* @brief 设置载荷长度
* @param length: 载荷字节数
*/

void drv_radio_set_playload_length(uint8_t length);

/**
* @brief 读取载荷长度
* @retval 字节数
*/

uint8_t drv_radio_get_playload_length(void);

/**
* @brief 使能crc
*/

void drv_radio_enable_crc(void);

/**
* @brief 禁止crc
*/

void drv_radio_disable_crc(void);

/**
* @brief 使能中断
* @note 使能EVENTS_READY,EVENTS_END,EVENTS_DISABLED中断
*/

void drv_radio_enable_irq(void);

/**
* @brief 向buf中写入数据
* @param buf: 发送数据
* @param length: 数据长度
*/

void drv_radio_write_buf(uint8_t *buf, uint8_t length);

/**
* @brief 从buf中读取数据
* @param buf: 读取数据存放缓存
* @param length: 数据长度
*/

void drv_radio_read_buf(uint8_t *buf, uint8_t length);

/**
* @brief 使能发送
* @note 使能成功后产生事件EVENTS_READY
*/

void drv_radio_enable_tx(void);

/**
* @brief 开始工作
* @note 成功后产生事件EVENTS_END
*/

void drv_radio_start_work(void);

/**
* @brief 关闭射频模块
* @note 关闭成功后产生事件EVENTS_DISABLED
*/

void drv_radio_disable(void);

/**
* @brief 使能接收
* @note 使能成功后产生事件EVENTS_READY
*/

void drv_radio_enable_rx(void);

/**
* @brief 读取射频状态
* @retval 射频状态
*/

RadioState drv_radio_get_state(void);

/**
* @brief 读取接收RSSI
* @retval RSSI.单位-1dBm
*/

uint8_t drv_radio_get_rssi(void);

///**
//* @brief 中断处理
//* @retval 中断类型
//*/

//RadioIrqEvents drv_radio_irq_handle(void);

/**
* @brief 配置射频模块
* @param tx_power: 发射功率
* @param frequency: 通讯频点
* @param baudrate: 通讯波特率
* @param address: 地址
* @param playload_length: 载荷长度
*/

void drv_radio_config(TxPower tx_power, uint16_t frequency, RadioBaudrate baudrate, uint32_t address, uint8_t playload_length);

/**
* @brief 设置回调函数: 射频中断
* @param function: 回调函数.回调函数的第一个参数有效,值为RadioIrqEvents
*/

void drv_radio_set_callback_irq_handle(T_Callback function);

#endif 

drv_radio.c

/**
* Copyright (c), 2015-2025
* @file drv_radio.c
* @brief 射频模块驱动层主文件
* @author jdh
* @date 2017/6/28
* @update 2017/8/17
* @update 2017/8/28
* @update 2017/10/11
*/

#include "drivers.h"
#include "drivers/drv_rfx2401c.h"

/**
* @brief 基础频率.单位MHz
*/

#define BASE_FREQUENCY1				2360
#define BASE_FREQUENCY2				2400

/**
* @brief S0, S1设置
*/

#define PACKET_S1_FIELD_SIZE      	0
#define PACKET_S0_FIELD_SIZE      	0
#define PACKET_LENGTH_FIELD_SIZE  	0

#define PACKET_BASE_ADDRESS_LENGTH  4
#define PACKET_PAYLOAD_MAXSIZE      255

/**
* @brief 发送接收缓存
*/

static uint8_t radio_buf[RADIO_BUF_SIZE] = {0};

static T_Callback Callback = 0;

static RadioIrqEvents deal_irq_handle(void);

/**
* @brief 设置射频模块发射功率
* @param txpower: 发射功率
*/

void drv_radio_set_txpower(TxPower tx_power)
{
    NRF_RADIO->TXPOWER = tx_power;
}

/**
* @brief 读取射频模块发射功率
* @retval 发射功率
*/

TxPower drv_radio_get_txpower(void)
{
    return (TxPower)NRF_RADIO->TXPOWER;
}

/**
* @brief 设置射频模块频点
* @param frequency: 工作频率.范围:[2360,2500]
*/

void drv_radio_set_frequency(uint16_t frequency)
{
	uint8_t mode;
	uint8_t offset;
	if (frequency >= BASE_FREQUENCY2)
	{
		mode = 0;
		offset = frequency - BASE_FREQUENCY2;
	}
	else
	{
		mode = 1;
		offset = frequency - BASE_FREQUENCY1;
	}
	NRF_RADIO->FREQUENCY = ((mode << 8) + offset) & 0xffff;
}

/**
* @brief 读取射频模块频点
* @retval 工作频率
*/

uint16_t drv_radio_get_frequency(void)
{
	uint16_t value = NRF_RADIO->FREQUENCY;
	
	if (value & 0x100)
	{
		value &= 0xff;
		return BASE_FREQUENCY1 + value;
	}
	else
	{
		return BASE_FREQUENCY2 + value;
	}
}

/**
* @brief 设置射频模块通讯速率
* @param baudrate: 波特率
*/

void drv_radio_set_baudrate(RadioBaudrate baudrate)
{
	NRF_RADIO->MODE = baudrate;
}

/**
* @brief 读取射频模块通讯速率
* @retval 通讯速率
*/

RadioBaudrate drv_radio_get_baudrate(void)
{
    return (RadioBaudrate)NRF_RADIO->MODE;
}

/**
* @brief 设置射频模块通讯地址
* @param address: 地址
*/

void drv_radio_set_address(uint32_t address)
{
	NRF_RADIO->BASE0 = address;
	NRF_RADIO->BASE1 = address;
	
	NRF_RADIO->PREFIX0 = 0;
	NRF_RADIO->PREFIX1 = 0;
  
	NRF_RADIO->TXADDRESS   = 0x0;
	NRF_RADIO->RXADDRESSES = 0x1;
}

/**
* @brief 读取射频模块通讯地址
* @retval 地址
*/

uint32_t drv_radio_get_address(void)
{
	return NRF_RADIO->BASE0;
}

/**
* @brief 设置载荷长度
* @param length: 载荷字节数
*/

void drv_radio_set_playload_length(uint8_t length)
{
	uint32_t value = NRF_RADIO->PCNF1;
	value &= ~RADIO_PCNF1_STATLEN_Msk;
	value |= (length << RADIO_PCNF1_STATLEN_Pos);
	NRF_RADIO->PCNF1 = value;
}

/**
* @brief 读取载荷长度
* @retval 字节数
*/

uint8_t drv_radio_get_playload_length(void)
{
	return ((NRF_RADIO->PCNF1 & RADIO_PCNF1_STATLEN_Msk) >> RADIO_PCNF1_STATLEN_Pos);
}

/**
* @brief 使能crc
*/

void drv_radio_enable_crc(void)
{
	NRF_RADIO->CRCCNF = (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
}

/**
* @brief 禁止crc
*/

void drv_radio_disable_crc(void)
{
	NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Disabled << RADIO_CRCCNF_LEN_Pos);
}


/**
* @brief 使能中断
* @note 使能EVENTS_READY,EVENTS_END,EVENTS_DISABLED中断
*/

void drv_radio_enable_irq(void)
{
	NVIC_SetPriority(RADIO_IRQn, IRQ_PRIORITY_LOW);
	NVIC_EnableIRQ(RADIO_IRQn);
	NRF_RADIO->INTENSET = (RADIO_INTENSET_READY_Enabled << RADIO_INTENSET_READY_Pos) | 
						  (RADIO_INTENSET_END_Enabled << RADIO_INTENSET_END_Pos) | 
						  (RADIO_INTENSET_DISABLED_Enabled << RADIO_INTENSET_DISABLED_Pos);
}

/**
* @brief 向buf中写入数据
* @param buf: 发送数据
* @param length: 数据长度
*/

void drv_radio_write_buf(uint8_t *buf, uint8_t length)
{
	memcpy(radio_buf, buf, length);
}

/**
* @brief 从buf中读取数据
* @param buf: 读取数据存放缓存
* @param length: 数据长度
*/

void drv_radio_read_buf(uint8_t *buf, uint8_t length)
{
	memcpy(buf, radio_buf, length);
}

/**
* @brief 使能发送
* @note 使能成功后产生事件EVENTS_READY
*/

void drv_radio_enable_tx(void)
{
	drv_rfx2401c_disable_rx();
	drv_rfx2401c_enable_tx();
	
	NRF_RADIO->EVENTS_READY = 0;
    NRF_RADIO->TASKS_TXEN   = 1;
}

/**
* @brief 开始工作
* @note 成功后产生事件EVENTS_END
*/

void drv_radio_start_work(void)
{
	NRF_RADIO->EVENTS_END  = 0;
    NRF_RADIO->TASKS_START = 1;
}

/**
* @brief 关闭射频模块
* @note 关闭成功后产生事件EVENTS_DISABLED
*/

void drv_radio_disable(void)
{
	drv_rfx2401c_disable_rx();
	drv_rfx2401c_disable_tx();
	
	NRF_RADIO->EVENTS_DISABLED = 0;
    NRF_RADIO->TASKS_DISABLE = 1;
}

/**
* @brief 使能接收
* @note 使能成功后产生事件EVENTS_READY
*/

void drv_radio_enable_rx(void)
{
	drv_rfx2401c_enable_rx();
	drv_rfx2401c_disable_tx();
	
	NRF_RADIO->EVENTS_READY = 0;
    NRF_RADIO->TASKS_RXEN   = 1;
}

/**
* @brief 读取射频状态
* @retval 射频状态
*/

RadioState drv_radio_get_state(void)
{
	return (RadioState)NRF_RADIO->STATE;
}

/**
* @brief 读取接收RSSI
* @retval RSSI.单位-1dBm
*/

uint8_t drv_radio_get_rssi(void)
{
	return NRF_RADIO->RSSISAMPLE;
}

/**
* @brief 配置射频模块
* @param tx_power: 发射功率
* @param frequency: 通讯频点
* @param baudrate: 通讯波特率
* @param address: 地址
* @param playload_length: 载荷长度
*/

void drv_radio_config(TxPower tx_power, uint16_t frequency, RadioBaudrate baudrate, uint32_t address, uint8_t playload_length)
{
	drv_rfx2401c_init();
	
	drv_radio_set_txpower(tx_power);
	drv_radio_set_frequency(frequency);
	drv_radio_set_baudrate(baudrate);
	drv_radio_set_address(address);

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

    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)   |
                       (playload_length         	 << RADIO_PCNF1_STATLEN_Pos) |
                       (PACKET_PAYLOAD_MAXSIZE       << RADIO_PCNF1_MAXLEN_Pos);
	
	NRF_RADIO->SHORTS = RADIO_SHORTS_ADDRESS_RSSISTART_Enabled << RADIO_SHORTS_ADDRESS_RSSISTART_Pos;
	
	drv_radio_enable_crc();
	drv_radio_enable_irq();
	
	NRF_RADIO->PACKETPTR = (uint32_t) radio_buf;
}

/**
* @brief 设置回调函数: 射频中断
* @param function: 回调函数.回调函数的第一个参数有效,值为RadioIrqEvents
*/

void drv_radio_set_callback_irq_handle(T_Callback function)
{
    Callback = function;
}

void RADIO_IRQHandler()
{
    if (Callback != 0)
    {
        Callback(deal_irq_handle(), NULL, 0);
    }
}

static RadioIrqEvents deal_irq_handle(void)
{
    if (NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk))
    {
        NRF_RADIO->EVENTS_READY = 0;
		return RADIO_IRQ_EVENTS_READY;
    }

    if (NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk))
    {
        NRF_RADIO->EVENTS_END = 0;
		return RADIO_IRQ_EVENTS_END;
    }

    if (NRF_RADIO->EVENTS_DISABLED && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk))
    {
        NRF_RADIO->EVENTS_DISABLED = 0;
		return RADIO_IRQ_EVENTS_DISABLED;
    }
	
	return RADIO_IRQ_NULL;
}

radio.h

/**
* Copyright (c), 2015-2025
* @file radio.h
* @brief 射频模块头文件
* @author jdh
* @verbatim 
* Change Logs:
* Date           Author       Notes
* 2017-12-14     jdh          新建
* @endverbatim 
*/

#ifndef _RADIO_H_
#define _RADIO_H_

#include "drivers.h"
#include "clock.h"

#pragma pack(1)

/**
* @brief 接收数据结构
*/

struct _Radio_Rx
{
	uint8_t buf[RADIO_BUF_SIZE];
	uint8_t length;
	uint8_t rssi;
    
    // 本地周期时间
    uint32_t local_cycle_time;
    T_Time local_time;
};

#pragma pack()

typedef enum
{
    RADIO_EVENTS_TX_END,
    RADIO_EVENTS_RX_END
} RadioEvents;

/**
* @brief 观察者模式: 射频模块事件处理函数指针
* @note 在事件是接收完成时接收数据参数有效
* @param events: 中断事件
* @param rx: 接收数据
*/

typedef void (*T_Radio_Deal_Event)(RadioEvents events, struct _Radio_Rx rx);

/**
* @brief 模块载入
*/

void radio_load(void);

/**
* @brief 模块运行
*/

void radio_run(void);

/**
* @brief 注册观察者
* @param function: 回调函数指针
*/

void radio_register_observer(T_Radio_Deal_Event function);

/**
* @brief 设置接收参数
* @param frequency: 接收频点.单位:MHz
* @param length: 接收数据定长
*/

void radio_set_rx_parameter(uint16_t frequency, uint8_t length);

/**
* @brief 射频模块是否空闲状态
* @param true: 是.0: 否
*/

bool radio_is_free(void);

/**
* @brief 射频模块是否接收状态
* @param true: 是.0: 否
*/

bool radio_is_rx(void);

/**
* @brief 射频模块是否发送状态
* @param true: 是.0: 否
*/

bool radio_is_tx(void);

/**
* @brief 射频模块停止工作
* @note 发送之前必须调用本函数
*/

void radio_stop(void);

/**
* @brief 发送数据
* @note 调用本函数前必须调用radio_stop()函数
* @param frequency: 接收频点.单位:MHz
* @param buf: 发送数据
* @param length: 数据长度
*/

void radio_send(uint16_t frequency, uint8_t *buf, uint8_t length);

#endif 

radio.c

/**
* Copyright (c), 2015-2025
* @file radio.c
* @brief 射频模块主文件
* @author jdh
* @verbatim 
* 说明:
* 为提高效率,由本模块将需要转发的数据存储到仓库
*
* Change Logs:
* Date           Author       Notes
* 2017-12-14     jdh          新建
* 2018-01-17     jdh          将需要转发的数据存储到仓库
* @endverbatim 
*/

#include "framework.h"
#include "repository/node_repository.h"

/**
* @brief 观察者最大个数
*/

#define MAX_OBSERVER				4

enum
{
    S_FREE,
    S_TX,
    S_RX
} State_Machine = S_FREE;

/**
* @brief 接收数据观察者列表
*/

static T_Radio_Deal_Event Observer[MAX_OBSERVER];
static uint8_t Len_Observer = 0;

/**
* @brief 接收参数
*/

static uint16_t Rx_Frequency;
static uint8_t Rx_Len;

/**
* @brief 中断参数
*/

static RadioEvents Radio_Events;
static struct _Radio_Rx Radio_Rx;
static bool Is_Irq = false;

static void deal_radio_irq(uint8_t index, uint8_t *buf, uint8_t len);
static void deal_events_ready(void);
static void deal_events_end(void);
static void deal_rx(struct _Radio_Rx *rx);
static void deal_events_disabled(void);
static void enable_rx(void);

static void save_repository(void);

/**
* @brief 模块载入
*/

void radio_load(void)
{
    drv_radio_set_callback_irq_handle(deal_radio_irq);
}

static void deal_radio_irq(uint8_t index, uint8_t *buf, uint8_t len)
{
    switch (index)
    {
        case RADIO_IRQ_EVENTS_READY:
        {
            deal_events_ready();
            break;
        }
        case RADIO_IRQ_EVENTS_END:
        {
            deal_events_end();
            break;
        }
        case RADIO_IRQ_EVENTS_DISABLED:
        {
            deal_events_disabled();
            break;
        }
        default:
        {
            break;
        }
    }
}

static void deal_events_ready(void)
{
    switch (State_Machine)
    {
        case S_FREE:
        {
            drv_radio_disable();
            break;
        }
        case S_TX:
        {
            drv_radio_start_work();
            break;
        }
        case S_RX:
        {
            drv_radio_start_work();
            break;
        }
    }
}

static void deal_events_end(void)
{   
    switch (State_Machine)
    {
        case S_FREE:
        {
            drv_radio_disable();
            break;
        }
        case S_TX:
        {
            if (!Is_Irq)
            {
                Radio_Events = RADIO_EVENTS_TX_END;
                Is_Irq = true;
            }
            drv_radio_disable();
            break;
        }
        case S_RX:
        {
            if (!Is_Irq)
            {
                deal_rx(&Radio_Rx);
                if (Radio_Rx.length > 0)
                {
                    Radio_Events = RADIO_EVENTS_RX_END;
                    Is_Irq = true;
                }
            }
            drv_radio_start_work();
            //drv_radio_disable();
            break;
        }
    }
}

static void deal_rx(struct _Radio_Rx *rx)
{	
	if (NRF_RADIO->CRCSTATUS == 1)
	{
        rx->local_cycle_time = get_local_cycle_time();
        rx->local_time = get_local_time();
		rx->rssi = drv_radio_get_rssi();
		rx->length = drv_radio_get_playload_length();
		if (rx->length > PTRUP_LEN_FRAME_HEAD)
		{
			drv_radio_read_buf(rx->buf, rx->length);
		}
        
        log_add_num_radio_rx();
	}
	else
	{
		rx->length = 0;
	}
}

static void deal_events_disabled(void)
{
    switch (State_Machine)
    {
        case S_FREE:
        {
            break;
        }
        case S_TX:
        {
            enable_rx();
            State_Machine = S_RX;
            break;
        }
        case S_RX:
        {
            enable_rx();
            break;
        }
    }
}

static void enable_rx(void)
{
    drv_radio_set_frequency(Rx_Frequency);
    drv_radio_set_playload_length(Rx_Len);
    drv_radio_enable_rx();
}

/**
* @brief 模块运行
*/

void radio_run(void)
{
    if (Is_Irq)
    {
        save_repository();
        
        for (uint8_t i = 0;i < Len_Observer;i++)
        {
            Observer[i](Radio_Events, Radio_Rx);
        }
        Is_Irq = false;
    }
}

static void save_repository(void)
{
    T_Link_Node_Ptr node = link_list_init_node();
    node->device = Radio_Rx.buf[PTRUP_SRC_DEVICE_POS];
    node->channel = Rx_Frequency;
    node->rssi = Radio_Rx.rssi;
    node->slot = get_system_time() / SLOT_TIME;
    node->body_len = Radio_Rx.length - PTRUP_LEN_FRAME_HEAD;
    node->time = get_local_time_us();
    node->body = malloc(node->body_len);
    memcpy(node->body, Radio_Rx.buf + PTRUP_LEN_FRAME_HEAD, node->body_len);
    node_repository_append(true, node);
}

/**
* @brief 注册观察者
* @param function: 回调函数指针
*/

void radio_register_observer(T_Radio_Deal_Event function)
{
	Observer[Len_Observer++] = function;
}

/**
* @brief 设置接收参数
* @param frequency: 接收频点.单位:MHz
* @param length: 接收数据定长
*/

void radio_set_rx_parameter(uint16_t frequency, uint8_t length)
{	
    radio_stop();
    
    Rx_Frequency = frequency;
    Rx_Len = length;
    
    State_Machine = S_RX;
    enable_rx();
}

/**
* @brief 射频模块是否空闲状态
* @param true: 是.0: 否
*/

bool radio_is_free(void)
{
    return State_Machine == S_RX;
}

/**
* @brief 射频模块是否接收状态
* @param true: 是.0: 否
*/

bool radio_is_rx(void)
{
    return State_Machine == S_RX;
}

/**
* @brief 射频模块是否发送状态
* @param true: 是.0: 否
*/

bool radio_is_tx(void)
{
    return State_Machine == S_TX;
}

/**
* @brief 射频模块停止工作
* @note 发送之前必须调用本函数
*/

void radio_stop(void)
{
    if (State_Machine != S_FREE)
    {
        State_Machine = S_FREE;
        drv_radio_disable();
        while (drv_radio_get_state() != RADIO_STATE_DISABLE){}
    }
}

/**
* @brief 发送数据
* @note 调用本函数前必须调用radio_stop()函数
* @param frequency: 接收频点.单位:MHz
* @param buf: 发送数据
* @param length: 数据长度
*/

void radio_send(uint16_t frequency, uint8_t *buf, uint8_t length)
{
	if (State_Machine != S_FREE)
	{
		return;
	}
    State_Machine = S_TX;
	
	drv_radio_set_frequency(frequency);
	drv_radio_write_buf(buf, length);
	drv_radio_set_playload_length(length);
	drv_radio_enable_tx();
    
    log_add_num_radio_tx();
}

Test code: initialization 

drv_radio_config(RADIO_TXPOWER_POS4DBM, 
                     config_para.listen_channel + RADIO_BASE_FREQUENCY, 
                     RADIO_BAUDRATE_1M, RADIO_ADDRESS, 
                     config_para.listen_len);


Test code: send

static void uart_forward_radio(void)
{
    if (!radio_is_free())
    {
        return;
    }
    
    uint64_t time_now = get_local_time_us();
    while (1)
    {
        node_repository_get(false, &_node);
        if (_node.body_len == 0)
        {
            return;
        }
        
        if (time_now - _node.time < _downstream_timeout_us)
        {
            break;
        }
        log_add_num_radio_tx_timeout();
    }
    
    memcpy(_buffer.buf + PTRDP_LEN_FRAME_HEAD, _node.body, _node.body_len);
    _buffer.len = PTRDP_LEN_FRAME_HEAD + _node.body_len;
    
    radio_stop();
    
    _buffer.buf[PTRDP_DST_DEVICE_POS] = _node.device;
    
    uint32_t time = get_system_time();
    _buffer.buf[PTRDP_TIMESTAMP_POS] = time >> 16;
    _buffer.buf[PTRDP_TIMESTAMP_POS + 1] = time >> 8;
    _buffer.buf[PTRDP_TIMESTAMP_POS + 2] = time;
    
    radio_send(_node.channel, _buffer.buf, _buffer.len); 
}


This article blog link:http://blog.csdn.net/jdh99 , author: jdh, reprint please specify.

 

surroundings:

Development environment: MDK5.23


Description:
Write NRF52832 radio frequency driver. In this design, the radio frequency module is always receiving. If there is sending, it will automatically switch to receiving after sending.

Guess you like

Origin blog.csdn.net/jdh99/article/details/79172742