#include "Problock_IO.h"
#include "LT8920.h"
#define CRC_ERROR_BIT 15
#define PKT_FLAG_BIT 6
#define LT8920_FIFO_LEN (63-2)
#define STS_IDEL 0
#define STS_TX 1
#define STS_RX 2
static uint8_t gs_u8rxModeFlag = 0;
static void LT_SPI_WriteReg(uint8_t u8reg, uint16_t u16dat);
static uint16_t LT_SPI_ReadReg(uint8_t u8reg);
static void LT8920_Set_Rf_Status(uint8_t ch, uint8_t sts);
static void LT8920_SetRxMode(uint8_t ch);
static uint8_t spi_send(uint8_t u8dat);
static void spi_setDataMode(uint32_t u32mode);
#ifdef LT8920_PKT
extern volatile uint8_t g_u8pkt_flag;
#endif
bool LT8920_Init()
{
uint16_t u16Val = 0;
GPIO_digitalWrite(RST,LOW);
Delay_ms(2);
GPIO_digitalWrite(RST,HIGH);
Delay_ms(5);
LT_SPI_WriteReg( 0, 0x6fe0 );
LT_SPI_WriteReg( 1, 0x5681 );
LT_SPI_WriteReg( 2, 0x6617 );
LT_SPI_WriteReg( 4, 0x9cc9 );
LT_SPI_WriteReg( 5, 0x6637 );
LT8920_Set_Rf_Status(0, STS_IDEL);//set RF=2402Mhz;status=idel
LT_SPI_WriteReg( 8, 0x6c90 );
LT_SPI_WriteReg( 9, 0x1840); //set Tx power level
LT_SPI_WriteReg( 10, 0x7ffd );//Crystal osc enable
LT_SPI_WriteReg( 11, 0x08 );
LT_SPI_WriteReg( 12, 0x00 );
LT_SPI_WriteReg( 13, 0x48bd );
LT_SPI_WriteReg( 22, 0xff );
LT_SPI_WriteReg( 23, 0x8005 ); //VCO check
LT_SPI_WriteReg( 24, 0x67 );
LT_SPI_WriteReg( 25, 0x1659 );
LT_SPI_WriteReg( 26, 0x19e0 );
LT_SPI_WriteReg( 27, 0x1300 );
LT_SPI_WriteReg( 28, 0x1800 );
LT_SPI_WriteReg( 32, 0x4800 ); //data packet format:PREAMBLE(3bytes);SYNCWORD(32bits);TRAILER(4bits):DATA_TYPE(NRZ raw data)
LT_SPI_WriteReg( 33, 0x3fc7 );
LT_SPI_WriteReg( 34, 0x2000 );
LT_SPI_WriteReg( 35, 0x0a00 );//idle mode;if enable auto_ack,Tx retries=10(max Tx retries=15)
////set unique sync words for each over-the-air network(similar to a MAC addr) start
// //NOTE:if SYNCWORD_LEN(in Reg32) is 32bits,the value should be written into {Reg39[15:0],Reg36[15:0]}
// LT_SPI_WriteReg( 36, SYNC_PRE_CODE );
//// LT_SPI_WriteReg( 37, 0x0000 );
//// LT_SPI_WriteReg( 38, 0x0000 );
// LT_SPI_WriteReg( 39, 0x0000 );
////set unique sync words for each over-the-air network(similar to a MAC addr) end
LT_SPI_WriteReg( 40, 0x2101 );//FIFO thershold;SYNCWORD thershold(allow 0 error bits)
LT_SPI_WriteReg( 41, 0xb800 );//enable CRC;1st byte of payload is data length(max=255bytes);AUTO_ACK is ON;PKT_flag and FIFO_flag HIGH effective
LT_SPI_WriteReg( 42, 0xfdff );//if enable auto_ack,255us to wait for RX_ACK(@62.5Kbps)
LT_SPI_WriteReg( 43, 0x000f );
//set data rate=62.5Kbps
LT_SPI_WriteReg( 44, 0x1000 );
LT_SPI_WriteReg( 45, 0x0552 );
Delay_ms(100);
u16Val = LT_SPI_ReadReg(32);
#ifdef DEBUG_LT8920
printf("[LT8920](r32):0x%x\n",u16Val);
#endif
if(0x4800 != u16Val)
{
#ifdef DEBUG_LT8920
printf("[LT8920]Init Error!!\n");
#endif
return false;
}
return true;
}
static void LT_SPI_WriteReg(uint8_t u8reg, uint16_t u16dat)
{
uint8_t u8dat;
//SPI_MODE1(CPOL=0,CPHA=1)
spi_setDataMode(SPI_MODE_1);
//enable SPI tranaction
GPIO_digitalWrite(SS1,LOW);
//Select register to write
spi_send(u8reg);
//write high byte
u8dat = u16dat >> 8;
spi_send(u8dat);
//write low byte
u8dat = (uint8_t)u16dat & 0xFF;
spi_send(u8dat);
//disable SPI tranaction
GPIO_digitalWrite(SS1,HIGH);
//SPI_MODE0(CPOL=0,CPHA=0)
spi_setDataMode(SPI_MODE_0);
}
static uint16_t LT_SPI_ReadReg(uint8_t u8reg)
{
uint16_t u16Val;
//SPI_MODE1(CPOL=0,CPHA=1)
spi_setDataMode(SPI_MODE_1);
//enable SPI tranaction
GPIO_digitalWrite(SS1,LOW);
// delay(2);
//when reading a Register,the Address should be added with 0x80.
u8reg += 0x80;
spi_send(u8reg);
//read data from reg
u16Val = spi_send(0);
u16Val <<= 8;
u16Val += spi_send(0);
//disable SPI tranaction
GPIO_digitalWrite(SS1,HIGH);
//SPI_MODE0(CPOL=0,CPHA=0)
spi_setDataMode(SPI_MODE_0);
return u16Val;
}
//set unique sync words for each over-the-air network(similar to a MAC addr)
//NOTE:SYNCWORD_LEN(in Reg32) is 32bits
void LT8920_Set_Sync_Code(uint32_t u32code)
{
uint16_t u16code = 0;
LT8920_Set_Rf_Status(0, STS_IDEL);//set RF=2402Mhz;status=idel
u16code = (uint16_t)u32code;
LT_SPI_WriteReg( 36, u16code );
u16code = (uint16_t)(u32code >> 16);
LT_SPI_WriteReg( 39, u16code );
}
uint32_t LT8920_Get_Sync_Code()
{
uint32_t u32code;
u32code = LT_SPI_ReadReg(39);
u32code <<= 16;
u32code = u32code + LT_SPI_ReadReg(36);
return u32code;
}
static void LT8920_Set_Rf_Status(uint8_t ch, uint8_t sts)
{
uint16_t u16code = 0;
gs_u8rxModeFlag = 0;
switch(sts)
{
case STS_IDEL:
u16code = 0;
break;
case STS_TX:
u16code = 0x0100 + (ch & 0x7F);
break;
case STS_RX:
u16code = (ch & 0x7F) | 0x80;
gs_u8rxModeFlag = 1;
break;
default:
u16code = 0;//idel
break;
}
LT_SPI_WriteReg( 7, u16code );//set RF=(2402+ch)Mhz and status
}
uint8_t LT8920_Send(uint8_t ch, uint8_t *pbuf, uint8_t u8len)
{
uint8_t i;
uint16_t u16sts = 0;
uint8_t TxFlag = 0;
if(NULL == pbuf)
{
return TxFlag;
}
if(u8len > LT8920_FIFO_LEN)
{
#ifdef DEBUG_LT8920
printf("[LT8920]length exceeds the limit(61bytes)\n");
#endif
return TxFlag;
}
//stop Tx and Rx
LT8920_Set_Rf_Status(ch, STS_IDEL);//set RF;status=idel
//clean FIFO
LT_SPI_WriteReg( 52, 0x8080 );
//Select TXRX_FIFO_REG
spi_setDataMode(SPI_MODE_1);
GPIO_digitalWrite(SS1,LOW);
// delay(2);
spi_send(50);
//1st byte is Tx_package length
spi_send(u8len);
//write data to FIFO
for(i=0; i<u8len; i++)
{
spi_send(*pbuf);
pbuf++;
}
GPIO_digitalWrite(SS1,HIGH);
//set RF channel;enable Tx and start to transfer
LT8920_Set_Rf_Status(ch, STS_TX);//set RF;status=TX
#ifdef LT8920_PKT
g_u8pkt_flag = 0;
while(0 == g_u8pkt_flag);//PKT and PKT_flag=1 after Tx packet has been sent
#else
while(1)
{
u16sts = LT_SPI_ReadReg(48);
if (u16sts & (1 << PKT_FLAG_BIT))
{
break;
}
}
#endif
u16sts = LT_SPI_ReadReg(52);
u16sts = u16sts & 0x3F;//FIFO_RD_PTR
if(0 == u16sts)
{
#ifdef DEBUG_LT8920
printf("[LT8920]TX_ACK\n");
#endif
TxFlag = TX_ACK;
}
else if(u8len + 2 == u16sts)
{
#ifdef DEBUG_LT8920
printf("[LT8920]TX_NOACK\n");
#endif
TxFlag = TX_NOACK;
}
else
{
#ifdef DEBUG_LT8920
printf("[LT8920]TX_UNKNOW\n");
#endif
}
return TxFlag;
}
static void LT8920_SetRxMode(uint8_t ch)
{
LT8920_Set_Rf_Status(ch, STS_IDEL);//set RF;status=idel
//clean FIFO
LT_SPI_WriteReg( 52, 0x8080 );
//set RF channel;enable Rx and start to receive
LT8920_Set_Rf_Status(ch, STS_RX);//set RF;status=RX
Delay_ms(1);
}
//NOTE:before first calling LT8920_Receive();should call LT8920_SetRxMode()
//return val:0(none data),-1(data exception)
int LT8920_Receive(uint8_t ch, uint8_t *pbuf, int nsize, unsigned long timeout_ms)
{
int i;
uint16_t u16sts = 0;
int nlen = 0;
if(!gs_u8rxModeFlag)
{
LT8920_SetRxMode(ch);
}
Set_Timer(timeout_ms);
while(1)
{
if( Is_Timer_Arrived() )
{
return nlen;
}
#ifdef LT8920_PKT
if(1 == g_u8pkt_flag)//PKT and PKT_flag=1 when Rx packet has been received by framer
{
g_u8pkt_flag = 0;
u16sts = LT_SPI_ReadReg(48);
break;
}
#else
u16sts = LT_SPI_ReadReg(48);
if( u16sts & (1 << PKT_FLAG_BIT) )
{
break;
}
#endif
}
//CRC check
if( u16sts & (1 << CRC_ERROR_BIT) )
{
#ifdef DEBUG_LT8920
printf("[LT8920]CRC_ERROR\n");
#endif
nlen = -1;
goto END;
}
//SPI_MODE1(CPOL=0,CPHA=1)
spi_setDataMode(SPI_MODE_1);
//enable SPI tranaction
GPIO_digitalWrite(SS1,LOW);
// delay(2);
//when reading a Register,the
评论0
最新资源