📄 nrfdriver.c
字号:
#include "nRFConfig.h"
#include "HardWare_NRF.h"
INT8U nRF_Init(void);
void SwitchRX(void);
void SwitchTX(void);
INT8U WriteCFG(INT8U* buf, INT8U size);
INT8U ReadBuf_FromCH1(INT8U* buf, INT8U size, INT16U ticks);
INT8U ReadBuf_FromCH2(INT8U* buf, INT8U size, INT16U ticks);
INT8U SendBuf(INT8U* buf, INT8U size);
#if UCOS_NRF != 0
void NRF_Dr_ISR(void);
#endif
static void WriteBuf(INT8U* buf, INT8U size);
static INT8U GetBuf_FromCH1(INT8U* buf, INT8U size); //仅此文件内部使用
static INT8U GetBuf_FromCH2(INT8U* buf, INT8U size); //仅此文件内部使用
#if UCOS_NRF !=0
OS_EVENT *RecNrf_CH1Flag;
OS_EVENT *RecNrf_CH2Flag;
OS_EVENT *SendNrf_Flag;
static INT8U nRF_Buf_CH1[BUFSIZE][DATA1_LEN_BYTE];
static INT8U nRF_Buf_CH2[BUFSIZE][DATA2_LEN_BYTE];
static INT8U front_CH1 = 0;
static INT8U rear_CH1 = 0;
static INT8U front_CH2 = 0;
static INT8U rear_CH2 = 0;
static INT8U HaveInit = 0;
#endif
/*******************************************************************************************************************
** 函数名称: nRF_Init()
**
** 功能描述: nRF无线模块初始化
**
** 输 入: 无
**
** 输 出: 无
**
** 返 回 值: 1: 正确 , 0: 错误
********************************************************************************************************************/
INT8U nRF_Init(void)
{
INT8U nRF_CFG[15] =
{
DATA2_W,DATA1_W, //通道1、2数据长度
ADDR2_0,ADDR2_1,ADDR2_2,ADDR2_3,ADDR2_4, //通道2地址
ADDR1_0,ADDR1_1,ADDR1_2,ADDR1_3,ADDR1_4, //通道1地址
(INT8U)((ADDR_W<<2) + (CRC_L<<1) + CRC_EN), //6位地址位数 1位CRC 8 OR 16位选择 1位CRC使能
(INT8U)((RX2_EN<<7) + (CM<<6) + (RFDR_SB<<5) + (XO_F<<2) + RF_PWR),//通道2允许 通信模式、速率 晶振频率 发射功率设置
(INT8U)((RF_CH<<1) + RXEN) //7位频点设置 1位发射/接收选择
};
#if UCOS_NRF != 0
if(HaveInit !=0)
{
return 0; //判断初始化是否成功
}
else
{
HaveInit = 1; //初始化成功
}
#endif
HardWareIntialize(); //nRF无线模块硬件配置函数
WriteCFG(nRF_CFG, 15); //写配置字
CS_CLR();
NOP(); //Td----min 50ns
CE_SET(); //Switch to Work Mode
#if UCOS_NRF != 0 /* 保证软件的可移植性 */
RecNrf_CH1Flag = OSSemCreate(0);
RecNrf_CH2Flag = OSSemCreate(0);
SendNrf_Flag = OSSemCreate(1);
INT_EN_DR1();
INT_EN_DR2();
SetISR_OWN(INT_NRF_DR_NO, INT_NRF_DR_PRIO, (INT32U)NRF_Dr_ISR);
#endif /* 保证软件的可移植性 */
return 1;
}
/*******************************************************************************************************************
** 函数名称: WriteCFG()
**
** 功能描述: 写工作模式配置字
**
** 输 入: INT8U* buf ,INT8U size
**
** 输 出: 无
**
** 返 回 值: 1: 正确 , 0: 错误
********************************************************************************************************************/
INT8U WriteCFG(INT8U* buf, INT8U size)
{
if(size != 15)
{
return 0;
}
#if UCOS_NRF != 0
OS_ENTER_CRITICAL();
#endif
CE_CLR();
CS_CLR();
CLK1_CLR();
SI_CLR();
PWRUP_SET();
//DelayUS(1); //Tpd2cfgm------max 3ms
CS_SET(); //Switch to Cfg Mode
DelayUS(5); //Tcs2data---min 5us
WriteBuf(buf, size); //Write Configuration
DelayUS(1);
CS_CLR(); //Tell nRF to Update Configuration
#if UCOS_NRF != 0
OS_EXIT_CRITICAL();
#endif
return 1;
}
/*******************************************************************************************************************
** 函数名称: SwitchRX()
**
** 功能描述: 模式切换至接收状态
**
** 输 入: 无
**
** 输 出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
void SwitchRX(void)
{
#if UCOS_NRF != 0
OS_ENTER_CRITICAL();
#endif
PWRUP_SET();
CE_CLR();
CS_CLR();
CLK1_CLR();
NOP(); //Td---min 50ns
CS_SET();
DelayUS(5); //Tcs2data---min 5us
SI_SET(); //Set to Recv Mode
DelayUS(1); //Ts----min 500ns
CLK1_SET();
DelayUS(1); //Thmin---min 500ns
CLK1_CLR();
CS_CLR();
NOP(); //Td----min 50ns
CE_SET(); //Update Configuration
DelayUS(1); //Tsby2rx---max 202us
#if UCOS_NRF != 0
OS_EXIT_CRITICAL();
#endif
}
/*******************************************************************************************************************
** 函数名称: SwitchTX()
**
** 功能描述: 模式切换至发送状态
**
** 输 入: 无
**
** 输 出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
void SwitchTX(void)
{
#if UCOS_NRF != 0
OS_ENTER_CRITICAL();
#endif
PWRUP_SET();
CE_CLR();
CS_CLR();
CLK1_CLR();
NOP(); //Td---min 50ns
CS_SET();
DelayUS(5); //Tcs2data---min 5us
SI_CLR(); //Set to Send Mode
DelayUS(1); //Ts----min 500ns
CLK1_SET();
DelayUS(1); //Thmin---min 500ns
CLK1_CLR();
CS_CLR();
NOP(); //Td----min 50ns
CE_SET(); //Update Configuration
DelayUS(1); //Tsby2rx---max 202us
#if UCOS_NRF != 0
OS_EXIT_CRITICAL();
#endif
}
/*******************************************************************************************************************
** 函数名称: WriteBuf()
**
** 功能描述: 写数据到缓冲区
**
** 输 入: INT8U* buf, INT8U size
**
** 输 出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
static void WriteBuf(INT8U* buf, INT8U size)
{
INT8U i, j, dat;
CLK1_CLR();
for(i=0;i<size;i++)
{
dat = buf[i];
for(j=0;j<8;j++)
{
CLK1_CLR();
if(dat & 0x80)
{
SI_SET();
}
else
{
SI_CLR();
}
DelayUS(1); //Ts--min 500ns
CLK1_SET();
DelayUS(1); //Th--min 500ns
dat = dat << 1;
}
}
}
/*******************************************************************************************************************
** 函数名称: SendBuf()
**
** 功能描述: 从缓冲区发送数据
**
** 输 入: INT8U* buf, INT8U size
**
** 输 出: 无
**
** 返 回 值: 0
********************************************************************************************************************/
INT8U SendBuf(INT8U* buf, INT8U size)
{
INT8U send_len;
#if UCOS_NRF != 0
INT8U err;
OSSemPend(SendNrf_Flag, OS_TICKS_PER_SEC, &err);
if(err != OS_NO_ERR)
{
return 0;
}
#endif
if(size > (DATA1_LEN_BYTE + 4))
{
send_len = DATA1_LEN_BYTE + 4;
}
else
{
send_len = size;
}
CE_SET();
DelayUS(5); //Tce2data---min 5us
WriteBuf(buf, send_len);
CE_CLR(); //发送需要一段时间的延迟
#if UCOS_NRF != 0
OSTimeDly(1);
OSSemPost(SendNrf_Flag);
#else
#if RFDR_SB == 1 //1Mbps
DelayUS(750);
#else //250Kbps
DelayUS(1400);
#endif
#endif
return 0;
}
/*******************************************************************************************************************
** 函数名称: ReadBuf_FromCH1()
**
** 功能描述: 从通道1 读取数据
**
** 输 入: INT8U* buf, INT8U size, INT16U ticks
**
** 输 出: 无
**
** 返 回 值: 1: 正确 , 0: 错误
********************************************************************************************************************/
INT8U ReadBuf_FromCH1(INT8U* buf, INT8U size, INT16U ticks)
{
#if UCOS_NRF != 0 /* 保证软件的可移植性 */
INT8U err;
OSSemPend(RecNrf_CH1Flag, ticks, &err);
if(err != OS_NO_ERR)
{
return 0;
}
OS_ENTER_CRITICAL();
if(rear_CH1 != front_CH1)
{
front_CH1 = (front_CH1 + 1) % BUFSIZE;
if(size >= DATA1_LEN_BYTE)
{
memcpy(buf, nRF_Buf_CH1[front_CH1], DATA1_LEN_BYTE);
}
else
{
memcpy(buf, nRF_Buf_CH1[front_CH1], size);
}
}
OS_EXIT_CRITICAL();
return 1; /* 保证软件的可移植性 */
#else
ticks = ticks;
if (GET_DR1_STAT() == 0)
{
return 0; //未使能通道一中断输出
}
return GetBuf_FromCH1(buf, size); //将数据写入缓冲区
#endif
}
/*******************************************************************************************************************
** 函数名称: ReadBuf_FromCH2()
**
** 功能描述: 从通道2 读取数据
**
** 输 入: INT8U* buf, INT8U size, INT16U ticks
**
** 输 出: 无
**
** 返 回 值: 1: 正确 , 0: 错误
********************************************************************************************************************/
INT8U ReadBuf_FromCH2(INT8U* buf, INT8U size, INT16U ticks)
{
#if UCOS_NRF != 0 /* 保证软件的可移植性 */
INT8U err;
OSSemPend(RecNrf_CH2Flag, ticks, &err);
if(err != OS_NO_ERR)
{
return 0;
}
OS_ENTER_CRITICAL();
if(rear_CH2 != front_CH2)
{
front_CH2 = (front_CH2 + 1) % BUFSIZE;
if(size >= DATA2_LEN_BYTE)
{
memcpy(buf, nRF_Buf_CH2[front_CH2], DATA2_LEN_BYTE);
}
else
{
memcpy(buf, nRF_Buf_CH2[front_CH2], size);
}
}
else
{
return 0;
}
OS_EXIT_CRITICAL();
return 1; /* 保证软件的可移植性 */
#else
ticks = ticks;
if (GET_DR2_STAT()==0)
{
return 0; //未使能通道2中断输出
}
return GetBuf_FromCH2(buf, size); //将数据写入缓冲区
#endif
}
/*******************************************************************************************************************
** 函数名称: GetBuf_FromCH1()
**
** 功能描述: 根据时序配置按位将数据写入通道1Buf
**
** 输 入: INT8U* buf, INT8U size
**
** 输 出: 无
**
** 返 回 值: 1: 正确 , 0: 错误
********************************************************************************************************************/
static INT8U GetBuf_FromCH1(INT8U* buf, INT8U size) //仅此文件内部使用
{
INT8U i, j;
INT8U dat;
if (DATA1_LEN_BYTE > size)
{
return 0;
}
DelayUS(50); //Tdr2clk---min 50us
for(i=0;i<DATA1_LEN_BYTE;i++)
{
dat = 0;
for(j=0;j<8;j++)
{
dat = dat << 1;
CLK1_SET();
DelayUS(1); //Thmin---min 500ns
if(GET_SO_STAT() != 0)
{
dat += 1;
}
CLK1_CLR();
DelayUS(1); // Tclk2data Max=50us ADD
}
buf[i] = dat;
}
return 1;
}
/*******************************************************************************************************************
** 函数名称: GetBuf_FromCH2()
**
** 功能描述: 根据时序配置按位将数据写入通道2Buf
**
** 输 入: INT8U* buf, INT8U size
**
** 输 出: 无
**
** 返 回 值: 1: 正确 , 0: 错误
********************************************************************************************************************/
static INT8U GetBuf_FromCH2(INT8U* buf, INT8U size) //仅此文件内部使用
{
INT8U i, j;
INT8U dat;
if (DATA2_LEN_BYTE > size)
{
return 0;
}
DelayUS(50); //Tdr2clk---min 50us
for(i=0;i<DATA2_LEN_BYTE;i++)
{
dat = 0;
for(j=0;j<8;j++)
{
dat = dat << 1;
CLK2_SET();
DelayUS(1); //Thmin---min 500ns
if(GET_DOUT2_STAT() != 0)
{
dat += 1;
}
CLK2_CLR();
DelayUS(1); // Tclk2data Max=50us ADD
}
buf[i] = dat;
}
return 1;
}
/*******************************************************************************************************************
** 函数名称: NRF_Dr_ISR()
**
** 功能描述: nRF无线模块驱动 中断服务函数
**
** 输 入: 无
**
** 输 出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
#if UCOS_NRF != 0
void NRF_Dr_ISR(void) /* 保证软件的可移植性 */
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
if(GET_INT_DR1_STAT() != 0)
{
INT_CLR_DR1();
OSIntEnter();
if (((rear_CH1+1)%BUFSIZE) == front_CH1) //如果队列已满,则丢弃最远的数据
{
front_CH1 = (front_CH1 + 1) % BUFSIZE;
}
else
{
OSSemPost(RecNrf_CH1Flag);
}
rear_CH1 = (rear_CH1 + 1) % BUFSIZE;
GetBuf_FromCH1(nRF_Buf_CH1[rear_CH1], DATA1_LEN_BYTE);
VIC_CLR();
OSIntExit();
}
else if(GET_INT_DR2_STAT() != 0)
{
INT_CLR_DR2();
OSIntEnter();
if (((rear_CH2+1)%BUFSIZE) == front_CH2) //如果队列已满,则丢弃最远的数据
{
front_CH2 = (front_CH2 + 1) % BUFSIZE;
}
else
{
OSSemPost(RecNrf_CH2Flag);
}
rear_CH2 = (rear_CH2 + 1) % BUFSIZE;
GetBuf_FromCH2(nRF_Buf_CH2[rear_CH2], DATA2_LEN_BYTE);
VIC_CLR();
OSIntExit();
}
} /* 保证软件的可移植性 */
#endif //#if UCOS_NRF != 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -