PDA

View Full Version : RF22 library support on Teensy 3.0 and Teensy 3.1



Adrien van den Bossche
01-29-2014, 09:20 PM
RF22 library (http://www.airspayce.com/mikem/arduino/RF22/) is working properly with Teensy 3.0 and 3.1.

The pinout is:



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()



// 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

dpharris
01-29-2014, 10:08 PM
Are you using the raw RFM22B modules, without level-shifters?
Thx.

stevech
01-30-2014, 12:08 AM
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.

stevech
01-30-2014, 12:33 AM
Adrien...
In the RF22.cpp code base I have, the SPI code you show uses:

_spi->begin();
whereas the code I downloaded has
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?

Adrien van den Bossche
01-30-2014, 06:17 PM
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:

_spi->begin();
whereas the code I downloaded has
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

stevech
01-30-2014, 06:43 PM
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:

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

// 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?

PaulStoffregen
01-31-2014, 04:33 PM
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:



#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.