kopia lustrzana https://github.com/bertrik/picoballoon
223 wiersze
5.5 KiB
C++
223 wiersze
5.5 KiB
C++
//RFM22 Lib - edited by James Coxon jacoxon@googlemail.com 2011
|
|
#include "RFM22.h"
|
|
|
|
uint8_t rfm22::read(uint8_t addr) const {
|
|
//write ss low to start
|
|
digitalWrite(pin, LOW);
|
|
|
|
// make sure the msb is 0 so we do a read, not a write
|
|
addr &= 0x7F;
|
|
SPI.transfer(addr);
|
|
uint8_t val = SPI.transfer(0x00);
|
|
|
|
//write ss high to end
|
|
digitalWrite(pin, HIGH);
|
|
|
|
return val;
|
|
}
|
|
|
|
void rfm22::write(uint8_t addr, uint8_t data) const {
|
|
//write ss low to start
|
|
digitalWrite(pin, LOW);
|
|
|
|
// make sure the msb is 1 so we do a write
|
|
addr |= 0x80;
|
|
SPI.transfer(addr);
|
|
SPI.transfer(data);
|
|
|
|
//write ss high to end
|
|
digitalWrite(pin, HIGH);
|
|
}
|
|
|
|
void rfm22::read(uint8_t start_addr, uint8_t buf[], uint8_t len) {
|
|
//write ss low to start
|
|
digitalWrite(pin, LOW);
|
|
|
|
// make sure the msb is 0 so we do a read, not a write
|
|
start_addr &= 0x7F;
|
|
SPI.transfer(start_addr);
|
|
for (int i = 0; i < len; i++) {
|
|
buf[i] = SPI.transfer(0x00);
|
|
}
|
|
|
|
//write ss high to end
|
|
digitalWrite(pin, HIGH);
|
|
}
|
|
void rfm22::write(uint8_t start_addr, uint8_t data[], uint8_t len) {
|
|
//write ss low to start
|
|
digitalWrite(pin, LOW);
|
|
|
|
// make sure the msb is 1 so we do a write
|
|
start_addr |= 0x80;
|
|
SPI.transfer(start_addr);
|
|
for (int i = 0; i < len; i++) {
|
|
SPI.transfer(data[i]);
|
|
}
|
|
|
|
//write ss high to end
|
|
digitalWrite(pin, HIGH);
|
|
}
|
|
|
|
void rfm22::resetFIFO() {
|
|
write(0x08, 0x03);
|
|
write(0x08, 0x00);
|
|
}
|
|
|
|
// Returns true if centre + (fhch * fhs) is within limits
|
|
// Caution, different versions of the RF22 suport different max freq
|
|
// so YMMV
|
|
boolean rfm22::setFrequency(float centre)
|
|
{
|
|
uint8_t fbsel = 0x40;
|
|
if (centre < 240.0 || centre > 960.0) // 930.0 for early silicon
|
|
return false;
|
|
if (centre >= 480.0)
|
|
{
|
|
centre /= 2;
|
|
fbsel |= 0x20;
|
|
}
|
|
centre /= 10.0;
|
|
float integerPart = floor(centre);
|
|
float fractionalPart = centre - integerPart;
|
|
|
|
uint8_t fb = (uint8_t)integerPart - 24; // Range 0 to 23
|
|
fbsel |= fb;
|
|
uint16_t fc = fractionalPart * 64000;
|
|
write(0x73, 0); // REVISIT
|
|
write(0x74, 0);
|
|
write(0x75, fbsel);
|
|
write(0x76, fc >> 8);
|
|
write(0x77, fc & 0xff);
|
|
}
|
|
|
|
void rfm22::init() {
|
|
// disable all interrupts
|
|
write(0x06, 0x00);
|
|
|
|
// move to ready mode
|
|
write(0x07, 0x01);
|
|
|
|
// set crystal oscillator cap to 12.5pf (but I don't know what this means)
|
|
write(0x09, 0x7f);
|
|
|
|
// GPIO setup - not using any, like the example from sfi
|
|
// Set GPIO clock output to 2MHz - this is probably not needed, since I am ignoring GPIO...
|
|
write(0x0A, 0x05);//default is 1MHz
|
|
|
|
// GPIO 0-2 are ignored, leaving them at default
|
|
write(0x0B, 0x00);
|
|
write(0x0C, 0x00);
|
|
write(0x0D, 0x00);
|
|
// no reading/writing to GPIO
|
|
write(0x0E, 0x00);
|
|
|
|
// ADC and temp are off
|
|
write(0x0F, 0x70);
|
|
write(0x10, 0x00);
|
|
write(0x12, 0x00);
|
|
write(0x13, 0x00);
|
|
|
|
// no whiting, no manchester encoding, data rate will be under 30kbps
|
|
// subject to change - don't I want these features turned on?
|
|
write(0x70, 0x20);
|
|
|
|
// RX Modem settings (not, apparently, IF Filter?)
|
|
// filset= 0b0100 or 0b1101
|
|
// fuck it, going with 3e-club.ru's settings
|
|
write(0x1C, 0x04);
|
|
write(0x1D, 0x40);//"battery voltage" my ass
|
|
write(0x1E, 0x08);//apparently my device's default
|
|
|
|
// Clock recovery - straight from 3e-club.ru with no understanding
|
|
write(0x20, 0x41);
|
|
write(0x21, 0x60);
|
|
write(0x22, 0x27);
|
|
write(0x23, 0x52);
|
|
// Clock recovery timing
|
|
write(0x24, 0x00);
|
|
write(0x25, 0x06);
|
|
|
|
// Tx power to max
|
|
write(0x6D, 0x04);//or is it 0x03?
|
|
|
|
// Tx data rate (1, 0) - these are the same in both examples
|
|
write(0x6E, 0x27);
|
|
write(0x6F, 0x52);
|
|
|
|
// "Data Access Control"
|
|
// Enable CRC
|
|
// Enable "Packet TX Handling" (wrap up data in packets for bigger chunks, but more reliable delivery)
|
|
// Enable "Packet RX Handling"
|
|
write(0x30, 0x8C);
|
|
|
|
// "Header Control" - appears to be a sort of 'Who did i mean this message for'
|
|
// we are opting for broadcast
|
|
write(0x32, 0xFF);
|
|
|
|
// "Header 3, 2, 1, 0 used for head length, fixed packet length, synchronize word length 3, 2,"
|
|
// Fixed packet length is off, meaning packet length is part of the data stream
|
|
write(0x33, 0x42);
|
|
|
|
// "64 nibble = 32 byte preamble" - write this many sets of 1010 before starting real data. NOTE THE LACK OF '0x'
|
|
write(0x34, 64);
|
|
// "0x35 need to detect 20bit preamble" - not sure why, but this needs to match the preceeding register
|
|
write(0x35, 0x20);
|
|
|
|
// synchronize word - apparently we only set this once?
|
|
write(0x36, 0x2D);
|
|
write(0x37, 0xD4);
|
|
write(0x38, 0x00);
|
|
write(0x39, 0x00);
|
|
|
|
// 4 bytes in header to send (note that these appear to go out backward?)
|
|
write(0x3A, 's');
|
|
write(0x3B, 'o');
|
|
write(0x3C, 'n');
|
|
write(0x3D, 'g');
|
|
|
|
// Packets will have 1 bytes of real data
|
|
write(0x3E, 1);
|
|
|
|
// 4 bytes in header to recieve and check
|
|
write(0x3F, 's');
|
|
write(0x40, 'o');
|
|
write(0x41, 'n');
|
|
write(0x42, 'g');
|
|
|
|
// Check all bits of all 4 bytes of the check header
|
|
write(0x43, 0xFF);
|
|
write(0x44, 0xFF);
|
|
write(0x45, 0xFF);
|
|
write(0x46, 0xFF);
|
|
|
|
//No channel hopping enabled
|
|
write(0x79, 0x00);
|
|
write(0x7A, 0x00);
|
|
|
|
// FSK, fd[8]=0, no invert for TX/RX data, FIFO mode, no clock
|
|
write(0x71, 0x22);
|
|
|
|
// "Frequency deviation setting to 45K=72*625"
|
|
write(0x72, 0x48);
|
|
|
|
// "No Frequency Offet" - channels?
|
|
write(0x73, 0x00);
|
|
write(0x74, 0x00);
|
|
|
|
// "frequency set to 434MHz" board default
|
|
write(0x75, 0x53);
|
|
write(0x76, 0x64);
|
|
write(0x77, 0x00);
|
|
|
|
resetFIFO();
|
|
}
|
|
|
|
void rfm22::initSPI() {
|
|
SPI.begin();
|
|
// RFM22 seems to speak spi mode 0
|
|
SPI.setDataMode(SPI_MODE0);
|
|
// Setting clock speed to 8mhz, as 10 is the max for the rfm22
|
|
SPI.setClockDivider(SPI_CLOCK_DIV2);
|
|
// MSB first
|
|
//SPI.setBitOrder(MSBFIRST);
|
|
} |