RF22 library support on Teensy 3.0 and Teensy 3.1

RF22 library (http://www.airspayce.com/mikem/arduino/RF22/) is working properly with Teensy 3.0 and 3.1.

The pinout is:

Code:
RFM22b  <->  T3 (#pin)
   SCK <---> SCK (14)
   SDO <---> DIN (12)
   SDI <---> DOUT (11)
  NSEL <---> CS (10)
  NIRQ <---> GPIO0 (0)

With this pinout, the construtor is RF22(10,0).

The RF22 library is nearly working out of the box, meanwhile the following must be added in RF22.cpp in the RF22::init()

Code:
    // Initialise the slave select pin
    pinMode(_slaveSelectPin, OUTPUT);
    digitalWrite(_slaveSelectPin, HIGH);

    // Add by Adrien van den Bossche <vandenbo@univ-tlse2.fr>
    #if defined (__MK20DX128__) || defined (__MK20DX256__)
    pinMode(_interrupt, INPUT);
    #endif

    // start the SPI library:
    // Note the RF22 wants mode 0, MSB first and default to 1 Mbps
    _spi->begin();
    _spi->setDataMode(SPI_MODE0);
    _spi->setBitOrder(MSBFIRST);
    _spi->setClockDivider(SPI_CLOCK_DIV16);  // (16 Mhz / 16) = 1 MHz

    // Add by Adrien van den Bossche <vandenbo@univ-tlse2.fr>
    #if defined (__MK20DX128__) || defined (__MK20DX256__)
    // First reassign pin 13 to Alt1 so that it is not SCK but the LED still works
    CORE_PIN13_CONFIG = PORT_PCR_MUX(1);
    // and then reassign pin 14 to SCK
    CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
    #endif

Note that the last lines released the pin 13 for the LED and other purpose.

Paul, do you plan to wrap-up this library with Teensyduino? We are wilingful to help you to support this library port since we got 30 nodes testbed based on T3.x+RFM22b.

Regards
 
Last edited:
I'm working with that library too - and the radios.
I'd love a breakout board -I have a messy breadboard now.
SparkFun's is too large and expensive.
This one http://www.ebay.com/itm/161205523748 is close to what I want, but it's a long way away.
Any others?
I don't want the cost of the RFM22B + breakout w/shipping to get too close to the cost of an XBee, though the impetus is the better range to be had with the 433MHz narrow-band RFM22B.

PS: level shifters shouldn't be needed, 3.3V common.
 
Last edited:
Adrien...
In the RF22.cpp code base I have, the SPI code you show uses:
Code:
_spi->begin();
whereas the code I downloaded has
Code:
    SPI.begin();
(etc. for the other function calls into the SPI library.

Either code would be equivalent, I suppose.

I wonder if there are more than one baselines of the code?
 
Are you using the raw RFM22B modules, without level-shifters?
Thx.

We are using raw RFM22B modules, Sparkfun breakout board (https://www.sparkfun.com/products/10154) and even Sparkfun shield (https://www.sparkfun.com/products/11018) without any level shifter since T3_1 is 5V tolerant.

Adrien...
In the RF22.cpp code base I have, the SPI code you show uses:
Code:
_spi->begin();
whereas the code I downloaded has
Code:
    SPI.begin();
(etc. for the other function calls into the SPI library.

Either code would be equivalent, I suppose.

I wonder if there are more than one baselines of the code?

My code is from http://www.airspayce.com/mikem/arduino/RF22/RF22-1.32.zip
 
ah, the version you point to is newer than what I have. I'll update mine. thanks.

A change I propose:
To support multiple RFM22B radios, the constructor's arguments:
Code:
RF22::RF22(uint8_t slaveSelectPin, uint8_t interrupt, GenericSPIClass *spi)
The desired slave select pin number is in the constructor initializer. But the interrupt argument as a value 0, 1 or 2 to depict which radio is intended for the instance.
Then in this
Code:
 // below, _interrupt contains a copy of the constructor param "interrupt"

	// Set up interrupt handler
    if (_interrupt == 0)
    {
	_RF22ForInterrupt[0] = this;
	attachInterrupt(0, RF22::isr0, LOW);  
    }
    else if (_interrupt == 1)
    {
	_RF22ForInterrupt[1] = this;
	attachInterrupt(1, RF22::isr1, LOW);  
    }
    else if (_interrupt == 2)
    {
	_RF22ForInterrupt[2] = this;
	attachInterrupt(2, RF22::isr2, LOW);  
    }
    else
	return false;
It seems that the external interrupt pins (to connect to the RFM22 NIRQ pins), are hard-coded to Teensy pins 0, 1, 2. Would be better to leave 0, 1, 2 as the logical choice of radio numbers and have an independent method to choose the interrupt pin number per radio. This could be a new param in the constructor initializer or table of pin numbers indexed by radio number, etc. I suppose too that the SS pin number could be in a similar table.
As is, using pin 0 for radio 0's interrupt costs the use of the RX1 UART function if I have it right.

Maybe pins 0, 1, 2 relate to AVR compatiblity for pin interrupts? Whereas the T3's can use any digital pin.
Agree?
 
Last edited:
Newer versions of Arduino, and of course Teensyduino, have a macro called digitalPinToInterrupt() which is intended to help library authors deal with pin to interrupt mapping across different hardware.

It's a preprocessor macro, so you can do things like this:

Code:
#ifdef digitalPinToInterrupt

  // automatically works on all hardware :-)

  attachInterrupt(digitalPinToInterrupt(pin), isr_function, LOW);

#else

  // something hard coded for specific Arduino boards with old versions of Arduino :-(

  if (pin == 2) attachInterrupt(0, isr_function, LOW);
  else if (pin == 3) attachInterrupt(1, isr_function, LOW);

#endif

You can also use digitalPinToInterrupt() to check if a pin supports interrupts. If not, you'll get a negative number. The attachInterrupt() function does nothing with invalid input, so it's ok to just use it without checking if you don't care are returning some sort of error.
 
Back
Top