LowPowerLab Forum
Hardware support => RF - Range - Antennas - RFM69 library => Topic started by: Ttech on December 15, 2013, 07:50:01 AM
-
Hi ,
I am trying to write my own code to get RFM69 into RX mode and want to recive large packets over 433Mhz .
My question is what sequence to follow , e.g
After i send all the base parameters to RFM69 via SPI like : Bit rate setting , Frequency deviation , RX Bandwidth , Carrier frequency,
Preamble, Sync values and Payload lenght .
I then map DIO pins to sense Payload ready on DIO0 and then read FIFO .
Although i have confirmed my TX is working as its fires off Packet send , but RX does not toggle Pay load ready ???
Do i have to wait for a certain time to sense Payload Ready signal ???
Thanks
-
Are you trying to write your own library?
Have you seen how it's done in my library?
-
Hi Felix ,
Yes i am writing my library or function , its for PIC microcontroller .
See the code below :
int i;
RxLed = 1;
TxLed = 0;
SpiWriteByte(RegDIOMap1, 0x44); // DIO0=Payload Ready
SpiWriteByte(RegFIFOThresh, PKLENGTH+7);
SpiWriteByte(RegOpMode, OM_RX); // RX Mode
SysTime = 0;
while(1)
{
if (SpiReadByte(RegIRQFlag1)&0x80); //Rx mode ready
printf("\n\r RX Mode = Ready");
{
if(nIRQ) // DIO0=Payload Ready
{
/// RX Ready , Now read data ///////////////
BurstRead(RegFIFO, RxData, PKLENGTH+7);
RxLed = 0;
SpiWriteByte(RegOpMode, OM_STANDBY);
Read_fifo();
break;
}
else
{
RxLed = 1;
printf("\n\r IRQ not detected");
continue;
}
}
}
}
-
The send/receive routines are quite different. There are a lot of things you have to set just right before it will work. Both radios have to have the exact same settings (mostly). The datasheet will be helpful in determining what these params are. I would point you to my library rather than try to explain what needs to be done. I think the code is pretty self explanatory and besides that I don't recall all the register values and all the settings. I will just say that it's a finely tuned assembly of code (think fragile) that took some time to get right and even a missing register can make the whole thing work partially or not at all.
-
Hi Felix ,
Thanks for your reply , can you direct me to a particular file where you have followed that sequence in your library .
HopeRF gave me an example and they are settiing these base parameters to configure RFM69 :
const word RFM69ConfigTbl[20] = {
0x0200, //RegDataModul : Packet Mode, FSK, No Shaping
0x0502, //RegFdevMsb 241*61Hz = 35KHz
0x0641, //RegFdevLsb
0x0334, //RegBitrateMsb 32MHz/0x3410 = 2.4kpbs
0x0410, //RegBitrateLsb
0x130F, //RegOcp Disable OCP
0x1888, //RegLNA 200R
0x1952, //RegRxBw RxBW 83KHz
0x2C00, //RegPreambleMsb
0x2D05, //RegPreambleLsb 5Byte Preamble
0x2E90, //enable Sync.Word 2+1=3bytes
0x2FAA, //0xAA SyncWord = aa2dd4
0x302D, //0x2D
0x31D4, //0xD4
0x3700, //RegPacketConfig1 Disable CRC£¬NRZ encode
0x3815, //RegPayloadLength 21bytes for length & Fixed length
0x3C95, //RegFiFoThresh
0x581B, //RegTestLna Normal sensitivity
//0x582D, //RegTestLna increase sensitivity with LNA (Note: consumption also increase!)
0x6F30, //RegTestDAGC Improved DAGC
//0x6F00, //RegTestDAGC Normal DAGC
0x0104, // RegOpMode = Standby
};
/// <<<<<< RX Entry parameters >>>>> /////
const word RFM69RxTable[5] = {
0x119F, //RegPaLevel : Pa0=0n, Pa1 and Pa2=off, Pout=11111
0x2544, //DIO Mapping for Rx : DIO0=Payload Ready, DIO1=Fifo level
0x5A55, //RegTestPa1=Normal mode and Rx mode
0x5C70, //RegTestPa2=Normal mode and Rx mode
0x0110, //RegOpMode=RX mode
};
/////////////////////////////////////////////////////////////
///// <<< TX Entry Parameters >>> /////
const word RFM69TxTable[5] = {
0x2504, //
0x119F, //RegPaLevel 13dBm
0x5A55, //Normal and TRx
0x5C70, //Normal and TRx
0x010C, //Entry to Tx mode
};
-
Check out these three files:
https://github.com/LowPowerLab/RFM69/blob/master/RFM69registers.h
https://github.com/LowPowerLab/RFM69/blob/master/RFM69.h
https://github.com/LowPowerLab/RFM69/blob/master/RFM69.cpp
Your "const word RFM69ConfigTbl[20]" lines up fairly closely with Felix's "bool RFM69::initialize(byte freqBand, byte nodeID, byte networkID)" in RFM69.cpp.
-
Hi A ,
Thanks for the link to RFM69.cpp
I must admit i am new to this coding , therefore i am asking for help from you or anyone to explain a few lines
e.g this is sending all base parameters :
for (byte i = 0; CONFIG[0] != 255; i++)
writeReg(CONFIG[0], CONFIG[1]);
And over here we are entering RX mode :
case RF69_MODE_RX:
writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER);
And here it is sensing if Payload Ready is high :
void RFM69::interruptHandler() {
//pinMode(4, OUTPUT);
//digitalWrite(4, 1);
if (_mode == RF69_MODE_RX && (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY))
{
setMode(RF69_MODE_STANDBY);
select();
SPI.transfer(REG_FIFO & 0x7f);
PAYLOADLEN = SPI.transfer(0);
PAYLOADLEN = PAYLOADLEN > 66 ? 66 : PAYLOADLEN; //precaution
TARGETID = SPI.transfer(0);
if(!(_promiscuousMode || TARGETID==_address || TARGETID==0)) //match this node's address, or broadcast addr 0x0 or anything in promiscuous mode
{
PAYLOADLEN = 0;
unselect();
//digitalWrite(4, 0);
return;
}
Am i right ?
-
I think you got it. Keep in mind that whole piece of code represents a state machine that goes in/out of different states depending on a few factors. By default the radio will be in RX mode and the interrupt will service any receptions and fill the buffers. The user should then periodically check if something was received using the receiveDone() function and empty the buffers (otherwise buffers get overwritten when new packets arrive). Everything you need is in the 2 files that A linked.
-
Hi Felix,
I tried to clean up code and put it the way it is written in RFM69Registers.h but my TX has stopped working , so here's is my main() routine :
void main(void)
{
InitSfr(); // To initialize my special function registers of PIC
InitPort(); // To initialize IO ports of PIC
ChkSel(); // to check selection
for(SysTime=0; SysTime<26; ) // Creating a POR delay
TimerQuery();
while(1)
{
ChkSel();
SetRfm(); // Base parameters for RFM69
RCCalStart(); // a routine to check if the oscillator has locked
TestTxMode(); // TX routine
}
}
Here's SetRfm()
void SetRfm(void)
{
SpiWriteByte(RegDataModul, DM_FSK+DM_PH_MODE); //FSK and Packet mode
// SpiWriteByte(RegDataModul, DM_OOK+DM_PH_MODE); //OOK and Packet mode
//Frequency Dev
SpiWriteByte(RegFdevMsb, 0x01); //18KHz
SpiWriteByte(RegFdevLsb, 0x27);
// Bit rate
SpiWriteByte(RegBitRateMsb, 0x68); //1.2
SpiWriteByte(RegBitRateLsb, 0x2B);
SpiWriteByte(RegOcp,0x0f); // Ocp Off
SpiWriteByte(0x5a,0x55); // RegTestPa1=off
SpiWriteByte(0x5c,0x70); // RegTestPa2=off
// RX Sensitivity
SpiWriteByte(RegLNA, 0x1B); // LNA setting
//RxBW
SpiWriteByte(RegRxBW, 0x4C); //25K
//Premable
SpiWriteByte(RegPreambleMsb, 0x00);
SpiWriteByte(RegPreambleLsb, 0x05); //0xAA*5
//Sync
BurstWrite(RegSyncValue, SyncTable, 2);
SpiWriteByte(RegPacketConfig1, PH_VAR+PH_NRZ+PH_CRC_OFF);
//Payload Length
SpiWriteByte(RegPayloadLength, PKLENGTH+7);
SpiWriteByte(RegFIFOThresh, PKLENGTH+7);
//Carrier Freq
BurstWrite(RegFreqMsb, FreqTable[FreqSel], 3); // For 433Mhz : 0x6C,0x80,0x00
SpiWriteByte(RegTestLNA,0x1B); //RegTestLna:Normal sensitivity
SpiWriteByte(RegTestDagc,0x30);
// TX Power
SpiWriteByte(RegPaLevel, 0x8E); // Odbm
}
Here's the listing for RCCalStart
void RCCalStart(void)
{
byte tmp;
SpiWriteByte(RegOpMode, OM_STANDBY); //STANDBY mode, Address RegOpMode=0x01
SpiWriteByte(RegOsc1, 0x81); //RegOSC1=Address'0x0A', 0x81=RC Oscillator Calibration start
do
{
//for(SysTime=0; SysTime<1; )
for(SysTime=0; SysTime<9;)
TimerQuery();
tmp = SpiReadByte(RegOsc1);//Reading RC Osc calibration status
}
while(tmp!=0x41); //Check if RC Osc calibration over
}
And here's the main TX listing :
void TestTxMode (void)
{
byte tmp;
byte i;
RxLed = 0;
TxLed = 1;
// Setting base parameters
SetRfm();
tmp = SpiReadByte(RegIRQFlag2); // Address RegIRQFlag2=0x28
tmp |= 0x40;
SpiWriteByte(RegIRQFlag2, tmp); // FIFO
SpiWriteByte(RegOpMode, OM_TX);
for(SysTime=0; SysTime<35; )
TimerQuery();
// Checking TX ready and Mode
while((SpiReadByte(RegIRQFlag1)&0xA0)!=0xA0) ; //Status OK?
SpiWriteByte(RegDIOMap1, 0x24); //GIO0 PacketSend/ GIO1 FIFONotEmpty/ GIO2 Data
BurstWrite(RegFIFO, TxFiFoData, 57); //Send first Packet
///////////////////////////////////////////////////////////////
SysTime = 0;
while(!nIRQ)
{
TimerQuery();
if(SysTime>=40) //OverTime
break;
}
TxLed = 0;
SpiWriteByte(RegOpMode, OM_STANDBY);
for(SysTime=0; SysTime<5; )
TimerQuery();
}
//////////////////////////////////////////////////////
Here's the listing for the interrupt based counter
void TimerQuery(void)
{
if(TMR0_7)
{
TMR0_7 = 0;
SysTime++;
}
}
///////////////////////////
Can you take a look and point why TX is not working
Regards
-
I would be really at a loss to try to guess my way through the code.
Here's why:
- i don't have your compiler/tools to try this code
- even if I had the compiler to try this code myself I don't have the hardware
So given this I'm afraid I cannot help.
-
Hi Felix ,
I think you are right , its the same with me , as i cantt understand fully how your code is working .
But you can help understand the sequence in which to configure RFM69 so that it works .
e.g
Step 1 : there should be Power-on-Reset delay before any config data is send i.e 10ms
Step 2 : send all the base parameters i.e 1. Mode and Modualtion
2. Frequency deviation
3. Bit rate
4. Over-current protection
5. TestPa1 & 2
6. LNA
7. Rx BW
8. Preamble
9. Sync Value
10. Packet Config1
11. Payload lenght
12. Fifo Threshold
13. Carrier Freq
14. TestLNA
15. TestDagc
16. PaLevel
Step 3: 1. set RFM69 in standby mode
2. Start RC Oscillator Calibration
3. Check if it locked
Step 4: 1. set RFM69 in TX mode
2. Wait for a few millisecs
3. Read IRQFlag1 and confirm Mode ready
4. Write data into Fifo to be Transmitted
5. Map DIO pins
6. Sense Packet Sense
7. set RFM69 in standby mode
8. Wait for a few millisecs
9. Loop back
If you think i am missing any step let me know
Regards ,
-
Ttech - did you get your pic library working? I'm starting a project with this transceiver and a PIC18 or PIC32.
Thanks,
Phil