?? 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 + -