📄 radio.c
字号:
/*= radio.c ========================================================================================
*
* Copyright (C) 2004 Nordic VLSI ASA
*
* Author(s): Ole Saether
*
* DESCRIPTION:
*
* Packet format:
*
* [4bytes address][1byte msg ID][0-25bytes msg data][16bit CRC]
*
*
* COMPILER:
*
* This program has been tested with Keil C51 V7.08
*
* $Revision: 3 $
*
*==================================================================================================
*/
#include <reg24e1.h>
#include "util.h"
#include "radio.h"
const unsigned char code rnd_tab[256] =
{
// This table contains four each of the numbers 2 to 65 (0x02-0x41) randomly distributed.
// If you need longer random cycles than this you could use an 8-bit pseudo random generator
// and use it to index this table.
0x28, 0x29, 0x38, 0x07, 0x19, 0x17, 0x2F, 0x1F, 0x14, 0x16, 0x1F, 0x06, 0x38, 0x1B, 0x3B, 0x33,
0x33, 0x2F, 0x37, 0x1A, 0x32, 0x15, 0x19, 0x34, 0x1B, 0x2D, 0x13, 0x02, 0x3F, 0x18, 0x10, 0x10,
0x0A, 0x1D, 0x0D, 0x37, 0x3D, 0x0B, 0x2A, 0x25, 0x1F, 0x20, 0x41, 0x21, 0x2F, 0x2A, 0x36, 0x09,
0x1C, 0x2C, 0x0F, 0x1E, 0x39, 0x03, 0x06, 0x03, 0x2B, 0x0A, 0x1D, 0x02, 0x24, 0x3A, 0x32, 0x10,
0x16, 0x16, 0x13, 0x12, 0x20, 0x06, 0x13, 0x1F, 0x0D, 0x41, 0x1E, 0x08, 0x3D, 0x31, 0x09, 0x16,
0x23, 0x12, 0x2D, 0x12, 0x31, 0x1C, 0x36, 0x0B, 0x11, 0x21, 0x37, 0x13, 0x38, 0x41, 0x0B, 0x32,
0x1B, 0x33, 0x20, 0x29, 0x0E, 0x05, 0x41, 0x1E, 0x05, 0x0C, 0x38, 0x1D, 0x20, 0x2F, 0x29, 0x39,
0x3D, 0x04, 0x26, 0x10, 0x12, 0x36, 0x3B, 0x08, 0x3D, 0x3C, 0x1A, 0x24, 0x08, 0x07, 0x35, 0x15,
0x2A, 0x40, 0x2C, 0x11, 0x31, 0x28, 0x2A, 0x1E, 0x02, 0x07, 0x19, 0x32, 0x28, 0x39, 0x1A, 0x28,
0x19, 0x22, 0x03, 0x21, 0x39, 0x09, 0x03, 0x0F, 0x3E, 0x2D, 0x0D, 0x37, 0x18, 0x3E, 0x09, 0x25,
0x26, 0x11, 0x36, 0x1A, 0x18, 0x25, 0x3E, 0x29, 0x08, 0x3C, 0x2B, 0x33, 0x02, 0x0A, 0x05, 0x0A,
0x1C, 0x2C, 0x07, 0x23, 0x3E, 0x1B, 0x3F, 0x2E, 0x3B, 0x31, 0x2B, 0x24, 0x35, 0x26, 0x1D, 0x2E,
0x11, 0x3C, 0x15, 0x2B, 0x15, 0x24, 0x2C, 0x27, 0x0D, 0x34, 0x14, 0x23, 0x21, 0x04, 0x3A, 0x27,
0x0F, 0x40, 0x27, 0x0B, 0x30, 0x2E, 0x17, 0x25, 0x3C, 0x34, 0x40, 0x34, 0x0C, 0x2D, 0x30, 0x18,
0x40, 0x0F, 0x22, 0x26, 0x27, 0x3F, 0x30, 0x22, 0x30, 0x3F, 0x23, 0x14, 0x3A, 0x14, 0x3B, 0x0C,
0x06, 0x04, 0x05, 0x3A, 0x35, 0x0E, 0x0E, 0x0C, 0x17, 0x1C, 0x35, 0x0E, 0x04, 0x2E, 0x17, 0x22
};
#define ADDR_INDEX 8 // Index to default address bytes in RxTxConf.buf
#define ADDR_COUNT 4 // Number of address bytes
static unsigned char idata rfAddress[ADDR_COUNT];
struct RFConfig
{
unsigned char n;
unsigned char buf[15];
};
typedef struct RFConfig RFConfig;
const RFConfig RxTxConf =
{
15,
0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xcd, 0xef, 0x12, 0xaa, 0x83, 0x6c, 0x04
};
static unsigned char seq, hopIdx, nBytes;
static unsigned rxTout, txTout;
static void SetRxMode(void)
{
// Put the transceiver into receive mode on current hopping frequency:
unsigned char ch;
CS = 1;
Delay100us(0);
ch = rnd_tab[hopIdx] << 1;
SpiReadWrite(ch | 0x01);
CS = 0;
}
static void SetTxMode(void)
{
// Put the transceiver into transmit mode on current hopping frequency:
unsigned char ch;
CS = 1;
Delay100us(0);
ch = rnd_tab[hopIdx] << 1;
SpiReadWrite(ch);
CS = 0;
}
static void InitCommon(unsigned char *pAddr)
{
unsigned char i;
hopIdx = 0; // Start at index #0 in the channel table above
if (pAddr != 0)
{
for(i=2;i<ADDR_INDEX;i++)
SpiReadWrite(RxTxConf.buf[i]);
for(i=0;i<ADDR_COUNT;i++)
{
rfAddress[i] = pAddr[i];
SpiReadWrite(pAddr[i]);
}
for(i=0;i<3;i++)
SpiReadWrite(RxTxConf.buf[RxTxConf.n-3+i]);
} else
{
for (i=0;i<ADDR_COUNT;i++)
{
rfAddress[i] = RxTxConf.buf[ADDR_INDEX+i];
}
for(i=2;i<RxTxConf.n;i++)
{
SpiReadWrite(RxTxConf.buf[i]);
}
}
CS = 0;
PWR_UP = 1; // Turn on power on radio
Delay100us(30); // Wait > 3ms
}
static void TransmitBytes(unsigned char *pBuf, unsigned char msgid)
{
// Transmit one packet with the format specified in the header of this file:
unsigned char i;
SetTxMode();
CE = 1;
Delay100us(1);
for (i=0;i<ADDR_COUNT;i++)
{
SpiReadWrite(rfAddress[i]);
}
SpiReadWrite(msgid); // All packets start with a one byte ID
for (i=0;i<nBytes;i++)
{
SpiReadWrite(pBuf[i]);
}
CE = 0;
Delay100us(5); // Wait until finished transmitting (200us + 256us)
}
static void SendAck(unsigned char msgid)
{
// Send a one byte acknowledge
unsigned char i;
SetTxMode();
CE = 1;
Delay100us(1);
for (i=0;i<ADDR_COUNT;i++)
{
SpiReadWrite(rfAddress[i]);
}
SpiReadWrite(msgid); // An ACK contains only the ID and no data
CE = 0;
Delay100us(3); // Wait until finished transmitting
}
static unsigned char ReceiveBytes(unsigned char *pBuf)
{
unsigned char i, cmd;
SetRxMode();
CE = 1;
ResetTimer(1);
while(DR1 == 0)
{
if ((rxTout != 0) && (GetTimer(1) > rxTout))
{
CE = 0;
return 0;
}
}
cmd = SpiReadWrite(0);
i = 0;
while(DR1)
{
pBuf[i++] = SpiReadWrite(0);
if (i == nBytes)
break;
}
while(DR1)
{
SpiReadWrite(0);
}
CE = 0;
return cmd;
}
static unsigned char WaitAck(void)
{
unsigned char ack;
SetRxMode();
CE = 1;
ResetTimer(0);
while(DR1 == 0)
{
if (GetTimer(0) > 2) // 3ms time-out
{
CE = 0;
return 0;
}
}
ack = SpiReadWrite(0);
while(DR1)
{
SpiReadWrite(0);
}
CE = 0;
return ack;
}
unsigned char TransmitPacket(unsigned char *pBuf)
{
unsigned int i;
unsigned char cmdt, cmdr, j;
seq++;
cmdt = 0x10 | (seq & 0x0f);
cmdr = 0;
ResetTimer(1);
for(;;)
{
for (i=0;i<256;i++)
{
// Repeat two times on all channels if no ACK is received
for (j=0;j<2;j++)
{
TransmitBytes(pBuf, cmdt);
cmdr = WaitAck();
if ((cmdr != 0) && ((cmdr & 0x0f) == (cmdt & 0x0f)))
{
hopIdx++;
return 1;
}
}
hopIdx++;
if ((txTout != 0) && (GetTimer(1) > txTout))
return 0;
}
}
return 0;
}
unsigned char ReceivePacket(unsigned char *pBuf)
{
unsigned char cmd, done;
done = 0;
while(done == 0)
{
cmd = ReceiveBytes(pBuf);
cmd = (cmd & 0x0f) | 0x20;
SendAck(cmd);
hopIdx++;
if ((cmd & 0x0f) != seq)
{
seq = cmd & 0x0f;
done = 1;
}
}
return 1;
}
void ReceiverTimeout(unsigned tOut)
{
// Set the receiver timeout in ms.
// 1ms = min timeout, 65536ms is max, 0 means wait forever
rxTout = tOut;
}
void TransmitterTimeout(unsigned tOut)
{
// Set the transmitter timeout in ms
// 1ms is min timeout, 65536ms is max, 0 means wait forever
txTout = tOut;
}
void InitReceiver(unsigned char n, unsigned char *pAddr)
{
seq = 15;
rxTout = 3000; // Default 3s timeout
nBytes = n; // Number of data bytes (0-25)
SPICLK = 0; // Max SPI clock
SPI_CTRL = 0x02; // Connect internal SPI controller to Radio
CE = 0;
CS = 1; // RF SPI CS = 1
Delay100us(0);
SpiReadWrite(0x00); // We are not using the DuoCeiver functionallity
SpiReadWrite((n+1)*8); // Number of Rx data bits
InitCommon(pAddr);
}
void InitTransmitter(unsigned char n, unsigned char *pAddr)
{
seq = 0;
txTout = 3000; // Default 3s timeout
nBytes = n; // Number of data bytes (0-25)
SPICLK = 0; // Max SPI clock
SPI_CTRL = 0x02; // Connect internal SPI controller to Radio
CE = 0;
CS = 1; // RF SPI CS = 1
Delay100us(0);
SpiReadWrite(0x00); // We are not using the DuoCeiver functionallity
SpiReadWrite(8); // Number of Rx data bits is 8 for the transmitter
InitCommon(pAddr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -