Hmm Its been a while since I revisited the RFM12 tutorials, so I thought I’d better write the next one.  Unfortunately it’s going to be too long to fit in one post so I’ll be splitting it across a couple of posts.

The last two tutorials covered a brief introduction and the physical connection to the MCU.  In this article I’m going to cover the internal commands and how we go about controlling to the RFM12 module.

It’s all done with Smoke and Mirrors!

Well not really, I wish it were that simple…as mentioned previously that the RFM12 needs to be connected as described in the previous article via SPI, the second thing we need to do is access the the internal registers of the RFM12 for it to be useful. 

The SPI transfers 16-bit commands to the RFM12, as part of the SPI transfer process it will receive results (if any) back to the MCU.  These commands do specific things, such as set the band, turn on the Transmitter and so on, therefore to get an understanding of what we need to do, we need to understand what the various commands do.

It also helps if you to have the RFM12 data sheet open as go through this as I’ll be explaining  things in roughly the same order as found on the current data sheet, most of this information is direct out of the datasheet.

SPI Interface

Just before we go through the commands, we need to be able to talk to the RFM12, and seeing that we have the SPI and NSEL correctly setup as described in Part 2 we need some routines to talk to the RFM12 and it’s registers. 

There are basically two ways to do this, 1) Bit banging the SPI or  2) using on-board hardware SPI peripheral.  The Hope RF programming guide offers a solution to bit banging the SPI interface so I won’t cover it here.

The following function for the AVR will provide hardware SPI support.  The important thing to note is the RFM12 SPI speed needs to be kept within the RFM12 Specs <=2.5MHz

// pins used for the RFM12B interface
#define RFM_IRQ  2
#define SPI_SS   10
#define SPI_MOSI 11
#define SPI_MISO 12
#define SPI_SCK  13
 
static void spi_initialize () { 
    DDRB &= ((1<<DDB2)|(1<<DDB1)|(1<<DDB0)); //spi pins on port b MOSI SCK,SS outputs     
#if F_CPU <= 10000000
    // clk/4 is ok for the RF12's SPI
    SPCR = _BV(SPE) | _BV(MSTR);
#else
    // use clk/8 (2x 1/16th) to avoid exceeding RF12's SPI specs of 2.5 MHz
    SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
    SPSR |= _BV(SPI2X);
#endif
    digitalWrite(SPI_SS, 1);   // Pull SPI_SS High
}
 
static uint16_t rf12_xfer (uint16_t cmd) {
    // the 2 loops below each spin 4 usec with a 2 MHz SPI clock
    uint16_t reply;
    digitalWrite(SPI_SS, 0);      // SPI_SS Low
    SPDR = cmd >> 8;
    while (!(SPSR & _BV(SPIF)))
        ;
    reply = SPDR << 8;
    SPDR = cmd;
    while (!(SPSR & _BV(SPIF)))
        ;
    reply |= SPDR;
    digitalWrite(SPI_SS, 1);     // SPI_SS High
    return reply;
}

Communicating with the RFM12

Before sending any commands the the RFM12 the NSEL Pin needs to be pulled low, then pulled high when the command has been sent.

The MPU communicates with the RFM12 over the SPI by clocking 16-bit commands serially in via the SDI (MOSI) pin on the rising edge of the SCK. 

The data sent to the RFM12 consist of a command code then followed by a number of parameter or data bits, this command code and parameter/data bits total 16-bits in length.  

The command/data structure is then send MSB first so bit 15 is the first bit to be sent followed by bit14 and so on.  At the same time data is being clocked into the RFM12 on the SDI Pin, results (if any) are also being clocked out via the SDO (MISO) pin into the MCU MSB first, e.g. bit15 is clocked out first, then bit14 and so on.

clip_image002

RFM12 communicates back -NIRQ

While the NIRQ is not a required connection, it is handy for the RFM12 module to let the MPU know than an event of significance has occurred, and should be handled, instead of tying the MPU up with polling the RFM12 module to see if things have happened. 

But suffice to say, the NIRQ is an interrupt generated by the RFM12 module which pulls the NIRQ pin low whenever the following occur:

  • The TX register is ready to receive the next byte (RGIT)
  • The FIFO has received the pre-programmed amount of bits (FFIT)
  • Power-on reset (POR)
  • FIFO overflow (FFOV) / TX register under run (RGUR)
  • Wake-up timer timeout (WKUP)
  • Negative pulse on the interrupt input pin nINT (EXT)
  • Supply voltage below the pre-0programmed value is detected (LBD)

Handling the NIRQ will be covered in a future Transmitting and Receiving article.

Onto the Commands

There are 15 commands that deal with configuration, control and status of the RFM12 module.  these are listed below:

UPDATE:  Try this handy utility as you play with registers, it’s a RFM12b command  calculator  (thanks Frans, aka fotoopa, for the link!)  http://www.technofun.org/blog/2009/01/24/rfm12-rfm12b-calculator/

  Command Description
1 Configuration Setting Frequency band, crystal oscillator load capacitance, baseband filter bandwidth, etc
2 Power Management Receiver/Transmitter mode change, synthesizer, xtal osc, PA, wake-up timer, clock output can be enabled here
3 Frequency Setting Data frequency of the local oscillator/carrier signal
4 Data Rate Bit rate
5 Receiver Control Function of pin 20, Valid Data Indicator, baseband bw, LNA gain, digital RSSI threshold
6 Data Filter Data filter type, clock recovery parameters
7 FIFO and Reset Mode Data FIFO IT level, FIFO start control, FIFO enable and FIFO fill enable
8 Receiver FIFO Read RX FIFO can be read with this command
9 AFC AFC parameters
10 TX Configuration Control Modulation parameters, output power, ea
11 Transmitter Register Write TX data register can be written with this command
12 Wake-Up Timer Command Wake-up time period
13 Low Duty-Cycle Command Enable low duty-cycle mode. Set duty-cycle
14 Low Battery Detector and Microcontroller Clock Divider LBD voltage and microcontroller clock division ratio
15 Status Read Command Status bits can be read out

 

1) Configuration Settings Command

 

The configuration command as the name suggests is used to configure the RFM12  (POR denotes the Power on Reset Values)

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

POR

1

0

0

1

0

0

0

el

ef

b1

b0

x3

x2

x1

x0

0×8008

 

el (bit 8): Enable internal data register. 

ef (bit 7): Enable fifo mode.

The el and ef bits are used to determine how the data is moved out of the RFM module.  Most of the time you will be using FIFO mode as this simplifies things.

bits 6 – 1 (b1 – b0): This determines the band of the RFM12 module being used and needs to match the physical RFM12 module you are physically using  e.g. you don’t set the band for 433 if you are using 915Mhz module.

b1

b0

Frequency Band (MHz)

0

0

315

0

1

433

1

0

868

1

1

915

 

bits 4 – 1 (x3 – x0): Determines the load capacitance of the onboard crystal.  This allows fine tuning of the crystal frequency.  Defaults of 12.5pf should be used.

The calibration procedure uses these settings to adjust the CLK output to 10Mhz. This procedure is in the data sheet, but is pretty vague, basically hook up a frequency counter or Oscilloscope up to the CLK pin of the RFM12B module, change the Frequency of CLK to 10mhz and measure it, it it’s not at 10MHz then use the load capacitance (x3-x0) to adjust it so it reads 10MHz.  From the couple of modules I’ve tested they have all been ok at the default of 12.5pF

x3

x2

x1

x0

Load Capacitance (pF)

0

0

0

0

8.5

0

0

0

1

8.0

0

0

1

0

9.5

0

0

1

1

10.0

 

 

 

 

1

1

1

0

15.6

1

1

1

1

16.0

 

2) Power Management Command

 

The power management command controls the power to the RFM12 sub-modules, it allows you to select what circuit within the RFM12 is turned on/off.  So by disabling these circuits when not required you can control the amount power savings of the device.

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

POR

1

0

0

0

0

0

1

0

er

ebb

et

es

ex

eb

ew

dc

0×8208

 
 

Bit

Function of the control bit

Related blocks

er

Enables the whole receiver chain

RF front end, baseband, synthesizer, oscillator

ebb

The receiver baseband circuit can be separately switched on

Baseband

et

Switches on the PLL, the power amplifier, and starts the transmission (If TX register is enabled)

Power amplifier, synthesizer, oscillator

es

Turns on the synthesizer

Synthesizer

ex

Turns on the crystal oscillator

Crystal oscillator

eb

Enables the low battery detector

Low battery detector

ew

Enables the wake-up timer

Wake-up timer

dc

Disables the clock output (CLK)

Clock output buffer

 

The ebb, es, and ex bits are provided to optimize the TX to RX or RX to TX turnaround time as shown in the table below

Symbol Parameter Notes Min Typ Max Units
tsx Crystal oscillator startup time Crystal ESR < 100     5 ms
T tx_rx_XTAL_ON Transmitter -Receiver turnover time Synthesizer off, crystal oscillator on during TX/RX change with 10 MHz step   450   us
T rx_tx_XTAL_ON Receiver -Transmitter turnover time Synthesizer off, crystal oscillator on during RX/TX change with 10 MHz step   350   us
tx_rx_SYNT_ON Transmitter -Receiver turnover time Synthesizer and crystal oscillator on during TX/RX change with 10 MHz step   425   us
T rx_tx_SYNT_ON Receiver -Transmitter turnover time Synthesizer and crystal oscillator on during RX/TX change with 10 MHz step   300   us

 

This gives you an idea how the control bits are logically connected:

clip_image002

3) Frequency Control Command

 

Within each band (433, 868 or 915Mhz) we have control over what frequency the RFM12 module communicates on.  So we can have various communication links occurring at the same time on the same band, but using different frequencies, or if we are getting interference on one frequency we can switch to another clear one.

Depending on what the band is determines the resolution of the frequency steps.

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

POR

 

1

0

1

0

f11

f10

f9

f8

f7

f6

f5

f4

f3

f2

f1

f0

0xA680

 

The frequencies available to each band are described below in this table

Band (MHz) Resolution (KHz) Min (MHz) Max (MHz)
433 2.5 430.24 439.75
868 5.0 860.48 879.51
915 7.5 900.72 929.37
 

The 12-bit number representing the frequency can be calculated by:

#define RF12_FREQUENCY_CALC_433(f) (((f)-430000000UL)/2500UL)  // Calculate the RFM12 register value for a given Frequency at 433MHz in 2.5khz increments
#define RF12_FREQUENCY_CALC_868(f) (((f)-860000000UL)/5000UL)    // Calculate the RFM12 register value for a given Frequency at 868MHz in 5.0Khz increments
#define RF12_FREQUENCY_CALC_915(f) (((f)-900000000UL)/7500UL)    // Calculate the RFM12 register value for a given Frequency at 915MHz in 7.5Khz increments
 
 

The 12-bit frequency value must be between 96 and 3903, if not then they will be set to these values automatically.

IMPORTANT: It is also important that you keep within your countries ISM spectrum management guidelines i.e. allowable frequencies and their use when selecting your operating frequencies.

4) Data Rate Command

This command sets the bitrate of the transmitted data or the expected bitrate of the received data.  This is the RAW physical bitrate of the module.

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

POR

1

1

0

0

0

1

1

0

cs

r6

r5

r4

r3

r2

r1

r0

0xC623

cs: is set if the bitrate is < 2700 bps

Here is a table I’ve prepared for common values.

Bit Rate

r6 – r0 Value

115200

0×02

57600

0×05

38400

0×08

28800

0×0B

19200

0×11

9600

0×23

4800

0×47

2400

cs =1  0×11

1200

cs = 1  0×1E

 

If you want to calculate your own bitrates use the formula:

//calculate setting for datarates >= 2700 Baud
#define RF12_DATARATE_CALC_HIGH(baud) ((uint8_t)(344828UL/baud)-1)
//calculate setting for datarates < 2700 Baud
#define RF12_DATARATE_CALC_LOW(baud) ((uint8_t)(43104/baud)-1)
 

When setting bitrates you also need to take into account the receiver bandwidth settings (See  Receiver control command below)

5) Receiver Control Command

 

bit

15

14

13

12

11

10

9

8

7

6

5  

4

3

2

1

0

POR

1

0

0

1

0

p20

d1

d0

i2

i1

i0  

g1

g0

r2

r1

r0

0×9080

 

Bit 10 (P20): sets the function of INT/VDI pin on the RFM12 module, it configures it as input (Interrupt from MPU) or output (VDI Valid Data Indicator).  The VDI is the default setting.  This goes high when valid data has been detected by the RFM12 module, valid data is data that has made it past the Sync pattern.  If set as Interrupt input, we can use this to send an interrupt the RFM12.  The RFM12 will then stop what it’s doing and wait for the next command.

p20

Function of pin 20

0

Interrupt input

1

VDI output

 

Bits 9-8 (d1 to d0): VDI (valid data indicator) signal response time setting:

d1

d0

Response

0

0

Fast

0

1

Medium

1

0

Slow

1

1

Always on

clip_image002[1]

 

Bits 7-5 (i2 to i0): Receiver baseband bandwidth (BW) select:

The receiver bandwidth is the amount of frequency above and below centre frequency we are receiving on (See the Frequency command for more information on changing the frequency)  that the receiver is sensitive to.  So if 400Khz is select as the Receiver bandwidth and 915Mhz is the centre frequency, then the receiver will looking for a signal anywhere +200Khz above 915 and 200Khz below, i.e. 914.800 – 915.200.

The bandwidth settings is linked to both the data rate, and Tx Modulation (Deviation)commands.  When data rate is fastest a higher bandwidth is required.   There are optimal settings for the Bandwidth and Modulation for different data rates as shown below.  Having too much bandwidth can cause a higher SNR and can cause packet corruption.  Not enough bandwidth and the incorrect signal is not received.

Incorrectly setting Bandwidth and Deviation (Modulation) is usually one of the common problems.

Table of optimal bandwidth and transmitter deviation settings for given data rates (the data sheet was a bit vague in this area and did not specify frequencies etc so I don’t know how valid they are at different frequency bands but they could be used as a starting point)

Data Rate [bps] Bandwidth [KHz] Modulation (Deviation) [KHz]
1200 67 45
2400 67 45
4800 67 45
9600 67 45
19200 67 45
38400 134 90
57600 145 90
115200 200 120

i2

i1

i0

BW [kHz]

0

0

0

reserved

0

0

1

400

0

1

0

340

0

1

1

270

1

0

0

200

1

0

1

134

1

1

0

67

1

1

1

reserved

 

Bits 4-3 (g1 to g0): LNA gain select:

The LNA gain (Low Noise Amplifier) can be selected according to RF signal strength. It can be useful in an environment with strong interferers.  Or alternately if you have two RFM12 modules in close proximity then you can drop the sensitivity of the Low Noise Amplifier.

g1

g0

relative to maximum [dB]

0

0

0

0

1

-6

1

0

-14

1

1

-20

 
 
Bits 2-0 (r2 to r0): RSSI detector threshold:
 
r2 r1 r0 RSSIsetth [dBm]

0 0 0 -103
0 0 1 -97
0 1 0 -91
0 1 1 -85
1 0 0 -79
1 0 1 -73
1 1 0 -67
1 1 1 -61
No TweetBacks yet. (Be the first to Tweet this post)