Library for HopeRF RFM22 transceiver module ported to mbed. Original Software from Mike McCauley (mikem@open.com.au) . See http://www.open.com.au/mikem/arduino/RF22/
Fork of RF22 by
RF22.cpp@9:46fb41f4259d, 2013-08-29 (annotated)
- Committer:
- floha
- Date:
- Thu Aug 29 21:57:14 2013 +0000
- Revision:
- 9:46fb41f4259d
- Parent:
- 8:d9e2ca137f2e
changed the LED default numbers in the RF22 constructor as the former values interfered with pins used on an KL25Z board. The library didn't work with those.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
charly | 0:79c6d0071c4c | 1 | // RF22.cpp |
charly | 0:79c6d0071c4c | 2 | // |
charly | 0:79c6d0071c4c | 3 | // Copyright (C) 2011 Mike McCauley |
charly | 5:0386600f3408 | 4 | // $Id: RF22.cpp,v 1.17 2013/02/06 21:33:56 mikem Exp mikem $ |
charly | 0:79c6d0071c4c | 5 | // ported to mbed by Karl Zweimueller |
charly | 0:79c6d0071c4c | 6 | |
charly | 0:79c6d0071c4c | 7 | |
charly | 0:79c6d0071c4c | 8 | #include "mbed.h" |
charly | 0:79c6d0071c4c | 9 | #include "RF22.h" |
charly | 0:79c6d0071c4c | 10 | //#include <SPI.h> |
charly | 0:79c6d0071c4c | 11 | |
charly | 0:79c6d0071c4c | 12 | |
charly | 0:79c6d0071c4c | 13 | // Interrupt vectors for the 2 Arduino interrupt pins |
charly | 0:79c6d0071c4c | 14 | // Each interrupt can be handled by a different instance of RF22, allowing you to have |
charly | 0:79c6d0071c4c | 15 | // 2 RF22s per Arduino |
charly | 0:79c6d0071c4c | 16 | //RF22* RF22::_RF22ForInterrupt[2] = {0, 0}; |
charly | 0:79c6d0071c4c | 17 | |
charly | 0:79c6d0071c4c | 18 | // These are indexed by the values of ModemConfigChoice |
charly | 8:d9e2ca137f2e | 19 | // Canned modem configurations generated with |
charly | 5:0386600f3408 | 20 | // http://www.hoperf.com/upload/rf/RF22B%2023B%2031B%2042B%2043B%20Register%20Settings_RevB1-v5.xls |
charly | 0:79c6d0071c4c | 21 | // Stored in flash (program) memory to save SRAM |
charly | 8:d9e2ca137f2e | 22 | /*PROGMEM */ static const RF22::ModemConfig MODEM_CONFIG_TABLE[] = { |
charly | 0:79c6d0071c4c | 23 | { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x00, 0x08 }, // Unmodulated carrier |
charly | 0:79c6d0071c4c | 24 | { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x33, 0x08 }, // FSK, PN9 random modulation, 2, 5 |
charly | 0:79c6d0071c4c | 25 | |
charly | 5:0386600f3408 | 26 | // All the following enable FIFO with reg 71 |
charly | 0:79c6d0071c4c | 27 | // 1c, 1f, 20, 21, 22, 23, 24, 25, 2c, 2d, 2e, 58, 69, 6e, 6f, 70, 71, 72 |
charly | 0:79c6d0071c4c | 28 | // FSK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm |
charly | 0:79c6d0071c4c | 29 | { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x22, 0x08 }, // 2, 5 |
charly | 0:79c6d0071c4c | 30 | { 0x1b, 0x03, 0x41, 0x60, 0x27, 0x52, 0x00, 0x07, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x22, 0x3a }, // 2.4, 36 |
charly | 0:79c6d0071c4c | 31 | { 0x1d, 0x03, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x13, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x22, 0x48 }, // 4.8, 45 |
charly | 0:79c6d0071c4c | 32 | { 0x1e, 0x03, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x45, 0x40, 0x0a, 0x20, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x22, 0x48 }, // 9.6, 45 |
charly | 0:79c6d0071c4c | 33 | { 0x2b, 0x03, 0x34, 0x02, 0x75, 0x25, 0x07, 0xff, 0x40, 0x0a, 0x1b, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x22, 0x0f }, // 19.2, 9.6 |
charly | 0:79c6d0071c4c | 34 | { 0x02, 0x03, 0x68, 0x01, 0x3a, 0x93, 0x04, 0xd5, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x22, 0x1f }, // 38.4, 19.6 |
charly | 0:79c6d0071c4c | 35 | { 0x06, 0x03, 0x45, 0x01, 0xd7, 0xdc, 0x07, 0x6e, 0x40, 0x0a, 0x2d, 0x80, 0x60, 0x0e, 0xbf, 0x0c, 0x22, 0x2e }, // 57.6. 28.8 |
charly | 0:79c6d0071c4c | 36 | { 0x8a, 0x03, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x40, 0x0a, 0x50, 0x80, 0x60, 0x20, 0x00, 0x0c, 0x22, 0xc8 }, // 125, 125 |
charly | 0:79c6d0071c4c | 37 | |
charly | 0:79c6d0071c4c | 38 | // GFSK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm |
charly | 0:79c6d0071c4c | 39 | // These differ from FSK only in register 71, for the modulation type |
charly | 0:79c6d0071c4c | 40 | { 0x2b, 0x03, 0xf4, 0x20, 0x41, 0x89, 0x00, 0x36, 0x40, 0x0a, 0x1d, 0x80, 0x60, 0x10, 0x62, 0x2c, 0x23, 0x08 }, // 2, 5 |
charly | 0:79c6d0071c4c | 41 | { 0x1b, 0x03, 0x41, 0x60, 0x27, 0x52, 0x00, 0x07, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x23, 0x3a }, // 2.4, 36 |
charly | 0:79c6d0071c4c | 42 | { 0x1d, 0x03, 0xa1, 0x20, 0x4e, 0xa5, 0x00, 0x13, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x23, 0x48 }, // 4.8, 45 |
charly | 0:79c6d0071c4c | 43 | { 0x1e, 0x03, 0xd0, 0x00, 0x9d, 0x49, 0x00, 0x45, 0x40, 0x0a, 0x20, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x23, 0x48 }, // 9.6, 45 |
charly | 0:79c6d0071c4c | 44 | { 0x2b, 0x03, 0x34, 0x02, 0x75, 0x25, 0x07, 0xff, 0x40, 0x0a, 0x1b, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x23, 0x0f }, // 19.2, 9.6 |
charly | 0:79c6d0071c4c | 45 | { 0x02, 0x03, 0x68, 0x01, 0x3a, 0x93, 0x04, 0xd5, 0x40, 0x0a, 0x1e, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x23, 0x1f }, // 38.4, 19.6 |
charly | 0:79c6d0071c4c | 46 | { 0x06, 0x03, 0x45, 0x01, 0xd7, 0xdc, 0x07, 0x6e, 0x40, 0x0a, 0x2d, 0x80, 0x60, 0x0e, 0xbf, 0x0c, 0x23, 0x2e }, // 57.6. 28.8 |
charly | 0:79c6d0071c4c | 47 | { 0x8a, 0x03, 0x60, 0x01, 0x55, 0x55, 0x02, 0xad, 0x40, 0x0a, 0x50, 0x80, 0x60, 0x20, 0x00, 0x0c, 0x23, 0xc8 }, // 125, 125 |
charly | 0:79c6d0071c4c | 48 | |
charly | 0:79c6d0071c4c | 49 | // OOK, No Manchester, Max Rb err <1%, Xtal Tol 20ppm |
charly | 0:79c6d0071c4c | 50 | { 0x51, 0x03, 0x68, 0x00, 0x3a, 0x93, 0x01, 0x3d, 0x2c, 0x11, 0x28, 0x80, 0x60, 0x09, 0xd5, 0x2c, 0x21, 0x08 }, // 1.2, 75 |
charly | 0:79c6d0071c4c | 51 | { 0xc8, 0x03, 0x39, 0x20, 0x68, 0xdc, 0x00, 0x6b, 0x2a, 0x08, 0x2a, 0x80, 0x60, 0x13, 0xa9, 0x2c, 0x21, 0x08 }, // 2.4, 335 |
charly | 0:79c6d0071c4c | 52 | { 0xc8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x29, 0x04, 0x29, 0x80, 0x60, 0x27, 0x52, 0x2c, 0x21, 0x08 }, // 4.8, 335 |
charly | 0:79c6d0071c4c | 53 | { 0xb8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x82, 0x29, 0x80, 0x60, 0x4e, 0xa5, 0x2c, 0x21, 0x08 }, // 9.6, 335 |
charly | 0:79c6d0071c4c | 54 | { 0xa8, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x41, 0x29, 0x80, 0x60, 0x9d, 0x49, 0x2c, 0x21, 0x08 }, // 19.2, 335 |
charly | 0:79c6d0071c4c | 55 | { 0x98, 0x03, 0x9c, 0x00, 0xd1, 0xb7, 0x00, 0xd4, 0x28, 0x20, 0x29, 0x80, 0x60, 0x09, 0xd5, 0x0c, 0x21, 0x08 }, // 38.4, 335 |
charly | 0:79c6d0071c4c | 56 | { 0x98, 0x03, 0x96, 0x00, 0xda, 0x74, 0x00, 0xdc, 0x28, 0x1f, 0x29, 0x80, 0x60, 0x0a, 0x3d, 0x0c, 0x21, 0x08 }, // 40, 335 |
charly | 0:79c6d0071c4c | 57 | |
charly | 0:79c6d0071c4c | 58 | }; |
charly | 0:79c6d0071c4c | 59 | |
charly | 0:79c6d0071c4c | 60 | RF22::RF22(PinName slaveSelectPin, PinName mosi, PinName miso, PinName sclk, PinName interrupt) |
floha | 9:46fb41f4259d | 61 | : _slaveSelectPin(slaveSelectPin), _spi(mosi, miso, sclk), _interrupt(interrupt), led1(LED4), led2(LED2), led3(LED3), led4(LED4) |
charly | 0:79c6d0071c4c | 62 | { |
charly | 0:79c6d0071c4c | 63 | |
charly | 0:79c6d0071c4c | 64 | |
charly | 0:79c6d0071c4c | 65 | _idleMode = RF22_XTON; // Default idle state is READY mode |
charly | 0:79c6d0071c4c | 66 | _mode = RF22_MODE_IDLE; // We start up in idle mode |
charly | 0:79c6d0071c4c | 67 | _rxGood = 0; |
charly | 0:79c6d0071c4c | 68 | _rxBad = 0; |
charly | 0:79c6d0071c4c | 69 | _txGood = 0; |
charly | 8:d9e2ca137f2e | 70 | |
charly | 8:d9e2ca137f2e | 71 | |
charly | 0:79c6d0071c4c | 72 | } |
charly | 0:79c6d0071c4c | 73 | |
charly | 0:79c6d0071c4c | 74 | boolean RF22::init() |
charly | 0:79c6d0071c4c | 75 | { |
charly | 0:79c6d0071c4c | 76 | // Wait for RF22 POR (up to 16msec) |
charly | 0:79c6d0071c4c | 77 | //delay(16); |
charly | 0:79c6d0071c4c | 78 | wait_ms(16); |
charly | 0:79c6d0071c4c | 79 | |
charly | 0:79c6d0071c4c | 80 | // Initialise the slave select pin |
charly | 0:79c6d0071c4c | 81 | //pinMode(_slaveSelectPin, OUTPUT); |
charly | 0:79c6d0071c4c | 82 | //digitalWrite(_slaveSelectPin, HIGH); |
charly | 0:79c6d0071c4c | 83 | _slaveSelectPin = 1; |
charly | 8:d9e2ca137f2e | 84 | |
charly | 0:79c6d0071c4c | 85 | wait_ms(100); |
charly | 8:d9e2ca137f2e | 86 | |
charly | 0:79c6d0071c4c | 87 | // start the SPI library: |
charly | 0:79c6d0071c4c | 88 | // Note the RF22 wants mode 0, MSB first and default to 1 Mbps |
charly | 0:79c6d0071c4c | 89 | /*SPI.begin(); |
charly | 0:79c6d0071c4c | 90 | SPI.setDataMode(SPI_MODE0); |
charly | 0:79c6d0071c4c | 91 | SPI.setBitOrder(MSBFIRST); |
charly | 0:79c6d0071c4c | 92 | SPI.setClockDivider(SPI_CLOCK_DIV16); // (16 Mhz / 16) = 1 MHz |
charly | 0:79c6d0071c4c | 93 | */ |
charly | 0:79c6d0071c4c | 94 | |
charly | 0:79c6d0071c4c | 95 | // Setup the spi for 8 bit data : 1RW-bit 7 adressbit and 8 databit |
charly | 0:79c6d0071c4c | 96 | // second edge capture, with a 10MHz clock rate |
charly | 0:79c6d0071c4c | 97 | _spi.format(8,0); |
charly | 0:79c6d0071c4c | 98 | _spi.frequency(10000000); |
charly | 0:79c6d0071c4c | 99 | |
charly | 0:79c6d0071c4c | 100 | // Software reset the device |
charly | 0:79c6d0071c4c | 101 | reset(); |
charly | 0:79c6d0071c4c | 102 | |
charly | 0:79c6d0071c4c | 103 | // Get the device type and check it |
charly | 0:79c6d0071c4c | 104 | // This also tests whether we are really connected to a device |
charly | 0:79c6d0071c4c | 105 | _deviceType = spiRead(RF22_REG_00_DEVICE_TYPE); |
charly | 0:79c6d0071c4c | 106 | if ( _deviceType != RF22_DEVICE_TYPE_RX_TRX |
charly | 8:d9e2ca137f2e | 107 | && _deviceType != RF22_DEVICE_TYPE_TX) |
charly | 8:d9e2ca137f2e | 108 | return false; |
charly | 0:79c6d0071c4c | 109 | |
charly | 0:79c6d0071c4c | 110 | // Set up interrupt handler |
charly | 0:79c6d0071c4c | 111 | // if (_interrupt == 0) |
charly | 0:79c6d0071c4c | 112 | // { |
charly | 0:79c6d0071c4c | 113 | //_RF22ForInterrupt[0] = this; |
charly | 8:d9e2ca137f2e | 114 | //attachInterrupt(0, RF22::isr0, LOW); |
charly | 0:79c6d0071c4c | 115 | _interrupt.fall(this, &RF22::isr0); |
charly | 8:d9e2ca137f2e | 116 | /* } |
charly | 8:d9e2ca137f2e | 117 | else if (_interrupt == 1) |
charly | 8:d9e2ca137f2e | 118 | { |
charly | 8:d9e2ca137f2e | 119 | _RF22ForInterrupt[1] = this; |
charly | 8:d9e2ca137f2e | 120 | attachInterrupt(1, RF22::isr1, LOW); |
charly | 8:d9e2ca137f2e | 121 | } |
charly | 8:d9e2ca137f2e | 122 | else |
charly | 8:d9e2ca137f2e | 123 | return false; |
charly | 8:d9e2ca137f2e | 124 | */ |
charly | 0:79c6d0071c4c | 125 | clearTxBuf(); |
charly | 0:79c6d0071c4c | 126 | clearRxBuf(); |
charly | 8:d9e2ca137f2e | 127 | |
charly | 0:79c6d0071c4c | 128 | // Most of these are the POR default |
charly | 0:79c6d0071c4c | 129 | spiWrite(RF22_REG_7D_TX_FIFO_CONTROL2, RF22_TXFFAEM_THRESHOLD); |
charly | 0:79c6d0071c4c | 130 | spiWrite(RF22_REG_7E_RX_FIFO_CONTROL, RF22_RXFFAFULL_THRESHOLD); |
charly | 0:79c6d0071c4c | 131 | spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_ENPACRX | RF22_ENPACTX | RF22_ENCRC | RF22_CRC_CRC_16_IBM); |
charly | 0:79c6d0071c4c | 132 | // Configure the message headers |
charly | 0:79c6d0071c4c | 133 | // Here we set up the standard packet format for use by the RF22 library |
charly | 0:79c6d0071c4c | 134 | // 8 nibbles preamble |
charly | 0:79c6d0071c4c | 135 | // 2 SYNC words 2d, d4 |
charly | 0:79c6d0071c4c | 136 | // Header length 4 (to, from, id, flags) |
charly | 0:79c6d0071c4c | 137 | // 1 octet of data length (0 to 255) |
charly | 0:79c6d0071c4c | 138 | // 0 to 255 octets data |
charly | 0:79c6d0071c4c | 139 | // 2 CRC octets as CRC16(IBM), computed on the header, length and data |
charly | 0:79c6d0071c4c | 140 | // On reception the to address is check for validity against RF22_REG_3F_CHECK_HEADER3 |
charly | 0:79c6d0071c4c | 141 | // or the broadcast address of 0xff |
charly | 0:79c6d0071c4c | 142 | // If no changes are made after this, the transmitted |
charly | 0:79c6d0071c4c | 143 | // to address will be 0xff, the from address will be 0xff |
charly | 0:79c6d0071c4c | 144 | // and all such messages will be accepted. This permits the out-of the box |
charly | 0:79c6d0071c4c | 145 | // RF22 config to act as an unaddresed, unreliable datagram service |
charly | 0:79c6d0071c4c | 146 | spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_HEADER3 | RF22_HDCH_HEADER3); |
charly | 0:79c6d0071c4c | 147 | spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_4 | RF22_SYNCLEN_2); |
charly | 0:79c6d0071c4c | 148 | setPreambleLength(8); |
charly | 0:79c6d0071c4c | 149 | uint8_t syncwords[] = { 0x2d, 0xd4 }; |
charly | 0:79c6d0071c4c | 150 | setSyncWords(syncwords, sizeof(syncwords)); |
charly | 8:d9e2ca137f2e | 151 | setPromiscuous(false); |
charly | 0:79c6d0071c4c | 152 | // Check the TO header against RF22_DEFAULT_NODE_ADDRESS |
charly | 0:79c6d0071c4c | 153 | spiWrite(RF22_REG_3F_CHECK_HEADER3, RF22_DEFAULT_NODE_ADDRESS); |
charly | 0:79c6d0071c4c | 154 | // Set the default transmit header values |
charly | 0:79c6d0071c4c | 155 | setHeaderTo(RF22_DEFAULT_NODE_ADDRESS); |
charly | 0:79c6d0071c4c | 156 | setHeaderFrom(RF22_DEFAULT_NODE_ADDRESS); |
charly | 0:79c6d0071c4c | 157 | setHeaderId(0); |
charly | 0:79c6d0071c4c | 158 | setHeaderFlags(0); |
charly | 0:79c6d0071c4c | 159 | |
charly | 0:79c6d0071c4c | 160 | // Ensure the antenna can be switched automatically according to transmit and receive |
charly | 0:79c6d0071c4c | 161 | // This assumes GPIO0(out) is connected to TX_ANT(in) to enable tx antenna during transmit |
charly | 0:79c6d0071c4c | 162 | // This assumes GPIO1(out) is connected to RX_ANT(in) to enable rx antenna during receive |
charly | 0:79c6d0071c4c | 163 | spiWrite (RF22_REG_0B_GPIO_CONFIGURATION0, 0x12) ; // TX state |
charly | 0:79c6d0071c4c | 164 | spiWrite (RF22_REG_0C_GPIO_CONFIGURATION1, 0x15) ; // RX state |
charly | 0:79c6d0071c4c | 165 | |
charly | 0:79c6d0071c4c | 166 | // Enable interrupts |
charly | 8:d9e2ca137f2e | 167 | // this is original from arduion, which crashes on mbed after some hours |
charly | 8:d9e2ca137f2e | 168 | //see https://groups.google.com/forum/?fromgroups#!topic/rf22-arduino/Ezkw256yQI8 |
charly | 8:d9e2ca137f2e | 169 | //spiWrite(RF22_REG_05_INTERRUPT_ENABLE1, RF22_ENTXFFAEM | RF22_ENRXFFAFULL | RF22_ENPKSENT | RF22_ENPKVALID | RF22_ENCRCERROR | RF22_ENFFERR); |
charly | 8:d9e2ca137f2e | 170 | //without RF22_ENFFERR it works - Charly |
charly | 8:d9e2ca137f2e | 171 | spiWrite(RF22_REG_05_INTERRUPT_ENABLE1, RF22_ENTXFFAEM |RF22_ENRXFFAFULL | RF22_ENPKSENT |RF22_ENPKVALID| RF22_ENCRCERROR); |
charly | 8:d9e2ca137f2e | 172 | |
charly | 0:79c6d0071c4c | 173 | spiWrite(RF22_REG_06_INTERRUPT_ENABLE2, RF22_ENPREAVAL); |
charly | 0:79c6d0071c4c | 174 | |
charly | 8:d9e2ca137f2e | 175 | |
charly | 5:0386600f3408 | 176 | // Set some defaults. An innocuous ISM frequency, and reasonable pull-in |
charly | 5:0386600f3408 | 177 | setFrequency(434.0, 0.05); |
charly | 0:79c6d0071c4c | 178 | // setFrequency(900.0); |
charly | 0:79c6d0071c4c | 179 | // Some slow, reliable default speed and modulation |
charly | 0:79c6d0071c4c | 180 | setModemConfig(FSK_Rb2_4Fd36); |
charly | 0:79c6d0071c4c | 181 | // setModemConfig(FSK_Rb125Fd125); |
charly | 0:79c6d0071c4c | 182 | // Minimum power |
charly | 0:79c6d0071c4c | 183 | setTxPower(RF22_TXPOW_8DBM); |
charly | 0:79c6d0071c4c | 184 | // setTxPower(RF22_TXPOW_17DBM); |
charly | 0:79c6d0071c4c | 185 | |
charly | 8:d9e2ca137f2e | 186 | |
charly | 2:f6f42c2ba9f2 | 187 | |
charly | 0:79c6d0071c4c | 188 | return true; |
charly | 0:79c6d0071c4c | 189 | } |
charly | 0:79c6d0071c4c | 190 | |
charly | 0:79c6d0071c4c | 191 | // C++ level interrupt handler for this instance |
charly | 0:79c6d0071c4c | 192 | void RF22::handleInterrupt() |
charly | 0:79c6d0071c4c | 193 | { |
charly | 0:79c6d0071c4c | 194 | uint8_t _lastInterruptFlags[2]; |
charly | 8:d9e2ca137f2e | 195 | |
charly | 8:d9e2ca137f2e | 196 | led1 = 1; |
charly | 8:d9e2ca137f2e | 197 | |
charly | 0:79c6d0071c4c | 198 | // Read the interrupt flags which clears the interrupt |
charly | 0:79c6d0071c4c | 199 | spiBurstRead(RF22_REG_03_INTERRUPT_STATUS1, _lastInterruptFlags, 2); |
charly | 0:79c6d0071c4c | 200 | |
charly | 0:79c6d0071c4c | 201 | #if 0 |
charly | 5:0386600f3408 | 202 | // Caution: Serial printing in this interrupt routine can cause mysterious crashes |
charly | 5:0386600f3408 | 203 | Serial.print("interrupt "); |
charly | 0:79c6d0071c4c | 204 | Serial.print(_lastInterruptFlags[0], HEX); |
charly | 0:79c6d0071c4c | 205 | Serial.print(" "); |
charly | 0:79c6d0071c4c | 206 | Serial.println(_lastInterruptFlags[1], HEX); |
charly | 0:79c6d0071c4c | 207 | if (_lastInterruptFlags[0] == 0 && _lastInterruptFlags[1] == 0) |
charly | 8:d9e2ca137f2e | 208 | Serial.println("FUNNY: no interrupt!"); |
charly | 0:79c6d0071c4c | 209 | #endif |
charly | 0:79c6d0071c4c | 210 | |
charly | 5:0386600f3408 | 211 | #if 0 |
charly | 0:79c6d0071c4c | 212 | // TESTING: fake an RF22_IFFERROR |
charly | 0:79c6d0071c4c | 213 | static int counter = 0; |
charly | 8:d9e2ca137f2e | 214 | if (_lastInterruptFlags[0] & RF22_IPKSENT && counter++ == 10) { |
charly | 8:d9e2ca137f2e | 215 | _lastInterruptFlags[0] = RF22_IFFERROR; |
charly | 8:d9e2ca137f2e | 216 | counter = 0; |
charly | 0:79c6d0071c4c | 217 | } |
charly | 5:0386600f3408 | 218 | #endif |
charly | 0:79c6d0071c4c | 219 | |
charly | 8:d9e2ca137f2e | 220 | |
charly | 8:d9e2ca137f2e | 221 | if (_lastInterruptFlags[0] & RF22_IFFERROR) { |
charly | 8:d9e2ca137f2e | 222 | // Serial.println("IFFERROR"); |
charly | 8:d9e2ca137f2e | 223 | led4 = !led4; |
charly | 8:d9e2ca137f2e | 224 | resetFifos(); // Clears the interrupt |
charly | 8:d9e2ca137f2e | 225 | if (_mode == RF22_MODE_TX) |
charly | 8:d9e2ca137f2e | 226 | restartTransmit(); |
charly | 8:d9e2ca137f2e | 227 | else if (_mode == RF22_MODE_RX){ |
charly | 8:d9e2ca137f2e | 228 | clearRxBuf(); |
charly | 8:d9e2ca137f2e | 229 | //stop and start Rx |
charly | 8:d9e2ca137f2e | 230 | setModeIdle(); |
charly | 8:d9e2ca137f2e | 231 | setModeRx(); |
charly | 8:d9e2ca137f2e | 232 | } |
charly | 8:d9e2ca137f2e | 233 | // stop handling the remaining interruppts as something went wrong here |
charly | 8:d9e2ca137f2e | 234 | return; |
charly | 0:79c6d0071c4c | 235 | } |
charly | 8:d9e2ca137f2e | 236 | |
charly | 8:d9e2ca137f2e | 237 | // Caution, any delay here may cause a FF underflow or overflow |
charly | 8:d9e2ca137f2e | 238 | if (_lastInterruptFlags[0] & RF22_ITXFFAEM) { |
charly | 8:d9e2ca137f2e | 239 | // See if more data has to be loaded into the Tx FIFO |
charly | 8:d9e2ca137f2e | 240 | //led2 = !led2; |
charly | 8:d9e2ca137f2e | 241 | sendNextFragment(); |
charly | 8:d9e2ca137f2e | 242 | // Serial.println("ITXFFAEM"); |
charly | 0:79c6d0071c4c | 243 | } |
charly | 8:d9e2ca137f2e | 244 | |
charly | 8:d9e2ca137f2e | 245 | if (_lastInterruptFlags[0] & RF22_IRXFFAFULL) { |
charly | 8:d9e2ca137f2e | 246 | // Caution, any delay here may cause a FF overflow |
charly | 8:d9e2ca137f2e | 247 | // Read some data from the Rx FIFO |
charly | 8:d9e2ca137f2e | 248 | //led4 = !led4; |
charly | 8:d9e2ca137f2e | 249 | readNextFragment(); |
charly | 8:d9e2ca137f2e | 250 | // Serial.println("IRXFFAFULL"); |
charly | 8:d9e2ca137f2e | 251 | } |
charly | 8:d9e2ca137f2e | 252 | if (_lastInterruptFlags[0] & RF22_IEXT) { |
charly | 8:d9e2ca137f2e | 253 | // This is not enabled by the base code, but users may want to enable it |
charly | 8:d9e2ca137f2e | 254 | //led2 = !led2; |
charly | 8:d9e2ca137f2e | 255 | handleExternalInterrupt(); |
charly | 8:d9e2ca137f2e | 256 | // Serial.println("IEXT"); |
charly | 0:79c6d0071c4c | 257 | } |
charly | 8:d9e2ca137f2e | 258 | if (_lastInterruptFlags[1] & RF22_IWUT) { |
charly | 8:d9e2ca137f2e | 259 | // This is not enabled by the base code, but users may want to enable it |
charly | 8:d9e2ca137f2e | 260 | //led2 = !led2; |
charly | 8:d9e2ca137f2e | 261 | handleWakeupTimerInterrupt(); |
charly | 8:d9e2ca137f2e | 262 | // Serial.println("IWUT"); |
charly | 8:d9e2ca137f2e | 263 | } |
charly | 8:d9e2ca137f2e | 264 | if (_lastInterruptFlags[0] & RF22_IPKSENT) { |
charly | 8:d9e2ca137f2e | 265 | // Serial.println("IPKSENT"); |
charly | 8:d9e2ca137f2e | 266 | _txGood++; |
charly | 8:d9e2ca137f2e | 267 | //led4 = !led4; |
charly | 8:d9e2ca137f2e | 268 | // Transmission does not automatically clear the tx buffer. |
charly | 8:d9e2ca137f2e | 269 | // Could retransmit if we wanted |
charly | 8:d9e2ca137f2e | 270 | // RF22 transitions automatically to Idle |
charly | 8:d9e2ca137f2e | 271 | _mode = RF22_MODE_IDLE; |
charly | 0:79c6d0071c4c | 272 | } |
charly | 8:d9e2ca137f2e | 273 | |
charly | 8:d9e2ca137f2e | 274 | if (_lastInterruptFlags[0] & RF22_IPKVALID) { |
charly | 8:d9e2ca137f2e | 275 | uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH); |
charly | 8:d9e2ca137f2e | 276 | // Serial.println("IPKVALID"); |
charly | 8:d9e2ca137f2e | 277 | // Serial.println(len); |
charly | 8:d9e2ca137f2e | 278 | // Serial.println(_bufLen); |
charly | 5:0386600f3408 | 279 | |
charly | 8:d9e2ca137f2e | 280 | // May have already read one or more fragments |
charly | 8:d9e2ca137f2e | 281 | // Get any remaining unread octets, based on the expected length |
charly | 8:d9e2ca137f2e | 282 | // First make sure we dont overflow the buffer in the case of a stupid length |
charly | 8:d9e2ca137f2e | 283 | // or partial bad receives |
charly | 8:d9e2ca137f2e | 284 | |
charly | 8:d9e2ca137f2e | 285 | if ( len > RF22_MAX_MESSAGE_LEN |
charly | 8:d9e2ca137f2e | 286 | || len < _bufLen) { |
charly | 8:d9e2ca137f2e | 287 | _rxBad++; |
charly | 8:d9e2ca137f2e | 288 | led2 = !led2; |
charly | 8:d9e2ca137f2e | 289 | _mode = RF22_MODE_IDLE; |
charly | 8:d9e2ca137f2e | 290 | clearRxBuf(); |
charly | 8:d9e2ca137f2e | 291 | return; // Hmmm receiver buffer overflow. |
charly | 8:d9e2ca137f2e | 292 | } |
charly | 8:d9e2ca137f2e | 293 | |
charly | 8:d9e2ca137f2e | 294 | spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen); |
charly | 8:d9e2ca137f2e | 295 | //__disable_irq(); // Disable Interrupts |
charly | 8:d9e2ca137f2e | 296 | _rxGood++; |
charly | 8:d9e2ca137f2e | 297 | _bufLen = len; |
charly | 5:0386600f3408 | 298 | _mode = RF22_MODE_IDLE; |
charly | 8:d9e2ca137f2e | 299 | _rxBufValid = true; |
charly | 8:d9e2ca137f2e | 300 | // reset the fifo for next packet?? |
charly | 8:d9e2ca137f2e | 301 | //resetRxFifo(); |
charly | 8:d9e2ca137f2e | 302 | //__enable_irq(); // Enable Interrupts |
charly | 5:0386600f3408 | 303 | |
charly | 8:d9e2ca137f2e | 304 | led3 = !led3; |
charly | 5:0386600f3408 | 305 | |
charly | 0:79c6d0071c4c | 306 | } |
charly | 8:d9e2ca137f2e | 307 | |
charly | 8:d9e2ca137f2e | 308 | if (_lastInterruptFlags[0] & RF22_ICRCERROR) { |
charly | 8:d9e2ca137f2e | 309 | // Serial.println("ICRCERR"); |
charly | 8:d9e2ca137f2e | 310 | _rxBad++; |
charly | 8:d9e2ca137f2e | 311 | led2 = !led2; |
charly | 8:d9e2ca137f2e | 312 | clearRxBuf(); |
charly | 8:d9e2ca137f2e | 313 | resetRxFifo(); |
charly | 8:d9e2ca137f2e | 314 | _mode = RF22_MODE_IDLE; |
charly | 8:d9e2ca137f2e | 315 | setModeRx(); // Keep trying |
charly | 0:79c6d0071c4c | 316 | } |
charly | 8:d9e2ca137f2e | 317 | |
charly | 8:d9e2ca137f2e | 318 | if (_lastInterruptFlags[1] & RF22_IPREAVAL) { |
charly | 8:d9e2ca137f2e | 319 | // Serial.println("IPREAVAL"); |
charly | 8:d9e2ca137f2e | 320 | |
charly | 8:d9e2ca137f2e | 321 | _lastRssi = spiRead(RF22_REG_26_RSSI); |
charly | 8:d9e2ca137f2e | 322 | |
charly | 8:d9e2ca137f2e | 323 | |
charly | 8:d9e2ca137f2e | 324 | // why clear the rx-buf here? charly |
charly | 8:d9e2ca137f2e | 325 | clearRxBuf(); |
charly | 8:d9e2ca137f2e | 326 | |
charly | 8:d9e2ca137f2e | 327 | |
charly | 0:79c6d0071c4c | 328 | } |
charly | 7:b86825b9d74b | 329 | led1 = 0; |
charly | 0:79c6d0071c4c | 330 | } |
charly | 0:79c6d0071c4c | 331 | |
charly | 0:79c6d0071c4c | 332 | // These are low level functions that call the interrupt handler for the correct |
charly | 0:79c6d0071c4c | 333 | // instance of RF22. |
charly | 0:79c6d0071c4c | 334 | // 2 interrupts allows us to have 2 different devices |
charly | 0:79c6d0071c4c | 335 | void RF22::isr0() |
charly | 0:79c6d0071c4c | 336 | { |
charly | 0:79c6d0071c4c | 337 | //if (_RF22ForInterrupt[0]) |
charly | 0:79c6d0071c4c | 338 | //_RF22ForInterrupt[0]->handleInterrupt(); |
charly | 0:79c6d0071c4c | 339 | handleInterrupt(); |
charly | 0:79c6d0071c4c | 340 | } |
charly | 0:79c6d0071c4c | 341 | /* |
charly | 0:79c6d0071c4c | 342 | void RF22::isr1() |
charly | 0:79c6d0071c4c | 343 | { |
charly | 0:79c6d0071c4c | 344 | if (_RF22ForInterrupt[1]) |
charly | 0:79c6d0071c4c | 345 | _RF22ForInterrupt[1]->handleInterrupt(); |
charly | 0:79c6d0071c4c | 346 | } |
charly | 0:79c6d0071c4c | 347 | */ |
charly | 0:79c6d0071c4c | 348 | void RF22::reset() |
charly | 0:79c6d0071c4c | 349 | { |
charly | 0:79c6d0071c4c | 350 | spiWrite(RF22_REG_07_OPERATING_MODE1, RF22_SWRES); |
charly | 0:79c6d0071c4c | 351 | // Wait for it to settle |
charly | 0:79c6d0071c4c | 352 | //delay(1); // SWReset time is nominally 100usec |
charly | 0:79c6d0071c4c | 353 | wait_ms(1); |
charly | 0:79c6d0071c4c | 354 | } |
charly | 0:79c6d0071c4c | 355 | |
charly | 0:79c6d0071c4c | 356 | uint8_t RF22::spiRead(uint8_t reg) |
charly | 0:79c6d0071c4c | 357 | { |
charly | 7:b86825b9d74b | 358 | __disable_irq(); // Disable Interrupts |
charly | 0:79c6d0071c4c | 359 | //digitalWrite(_slaveSelectPin, LOW); |
charly | 0:79c6d0071c4c | 360 | _slaveSelectPin=0; |
charly | 0:79c6d0071c4c | 361 | //_spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the address with the write mask off |
charly | 0:79c6d0071c4c | 362 | _spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the address with the write mask off |
charly | 0:79c6d0071c4c | 363 | uint8_t val = _spi.write(0); // The written value is ignored, reg value is read |
charly | 0:79c6d0071c4c | 364 | //digitalWrite(_slaveSelectPin, HIGH); |
charly | 0:79c6d0071c4c | 365 | _slaveSelectPin = 1; |
charly | 7:b86825b9d74b | 366 | __enable_irq(); // Enable Interrupts |
charly | 0:79c6d0071c4c | 367 | return val; |
charly | 0:79c6d0071c4c | 368 | } |
charly | 0:79c6d0071c4c | 369 | |
charly | 0:79c6d0071c4c | 370 | void RF22::spiWrite(uint8_t reg, uint8_t val) |
charly | 0:79c6d0071c4c | 371 | { |
charly | 7:b86825b9d74b | 372 | __disable_irq(); // Disable Interrupts |
charly | 0:79c6d0071c4c | 373 | //digitalWrite(_slaveSelectPin, LOW); |
charly | 0:79c6d0071c4c | 374 | _slaveSelectPin = 0; |
charly | 0:79c6d0071c4c | 375 | _spi.write(reg | RF22_SPI_WRITE_MASK); // Send the address with the write mask on |
charly | 0:79c6d0071c4c | 376 | _spi.write(val); // New value follows |
charly | 0:79c6d0071c4c | 377 | //digitalWrite(_slaveSelectPin, HIGH); |
charly | 0:79c6d0071c4c | 378 | _slaveSelectPin = 1; |
charly | 7:b86825b9d74b | 379 | __enable_irq(); // Enable Interrupts |
charly | 0:79c6d0071c4c | 380 | } |
charly | 0:79c6d0071c4c | 381 | |
charly | 0:79c6d0071c4c | 382 | void RF22::spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len) |
charly | 0:79c6d0071c4c | 383 | { |
charly | 0:79c6d0071c4c | 384 | //digitalWrite(_slaveSelectPin, LOW); |
charly | 0:79c6d0071c4c | 385 | _slaveSelectPin = 0; |
charly | 0:79c6d0071c4c | 386 | _spi.write(reg & ~RF22_SPI_WRITE_MASK); // Send the start address with the write mask off |
charly | 0:79c6d0071c4c | 387 | while (len--) |
charly | 8:d9e2ca137f2e | 388 | *dest++ = _spi.write(0); |
charly | 0:79c6d0071c4c | 389 | //digitalWrite(_slaveSelectPin, HIGH); |
charly | 0:79c6d0071c4c | 390 | _slaveSelectPin = 1; |
charly | 0:79c6d0071c4c | 391 | } |
charly | 0:79c6d0071c4c | 392 | |
charly | 5:0386600f3408 | 393 | void RF22::spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len) |
charly | 0:79c6d0071c4c | 394 | { |
charly | 0:79c6d0071c4c | 395 | //digitalWrite(_slaveSelectPin, LOW); |
charly | 0:79c6d0071c4c | 396 | _slaveSelectPin = 0; |
charly | 0:79c6d0071c4c | 397 | _spi.write(reg | RF22_SPI_WRITE_MASK); // Send the start address with the write mask on |
charly | 0:79c6d0071c4c | 398 | while (len--) |
charly | 8:d9e2ca137f2e | 399 | _spi.write(*src++); |
charly | 0:79c6d0071c4c | 400 | //digitalWrite(_slaveSelectPin, HIGH); |
charly | 0:79c6d0071c4c | 401 | _slaveSelectPin = 1; |
charly | 0:79c6d0071c4c | 402 | } |
charly | 0:79c6d0071c4c | 403 | |
charly | 0:79c6d0071c4c | 404 | uint8_t RF22::statusRead() |
charly | 0:79c6d0071c4c | 405 | { |
charly | 0:79c6d0071c4c | 406 | return spiRead(RF22_REG_02_DEVICE_STATUS); |
charly | 0:79c6d0071c4c | 407 | } |
charly | 0:79c6d0071c4c | 408 | |
charly | 0:79c6d0071c4c | 409 | uint8_t RF22::adcRead(uint8_t adcsel, |
charly | 0:79c6d0071c4c | 410 | uint8_t adcref , |
charly | 8:d9e2ca137f2e | 411 | uint8_t adcgain, |
charly | 0:79c6d0071c4c | 412 | uint8_t adcoffs) |
charly | 0:79c6d0071c4c | 413 | { |
charly | 0:79c6d0071c4c | 414 | uint8_t configuration = adcsel | adcref | (adcgain & RF22_ADCGAIN); |
charly | 0:79c6d0071c4c | 415 | spiWrite(RF22_REG_0F_ADC_CONFIGURATION, configuration | RF22_ADCSTART); |
charly | 0:79c6d0071c4c | 416 | spiWrite(RF22_REG_10_ADC_SENSOR_AMP_OFFSET, adcoffs); |
charly | 0:79c6d0071c4c | 417 | |
charly | 0:79c6d0071c4c | 418 | // Conversion time is nominally 305usec |
charly | 0:79c6d0071c4c | 419 | // Wait for the DONE bit |
charly | 0:79c6d0071c4c | 420 | while (!(spiRead(RF22_REG_0F_ADC_CONFIGURATION) & RF22_ADCDONE)) |
charly | 8:d9e2ca137f2e | 421 | ; |
charly | 8:d9e2ca137f2e | 422 | // Return the value |
charly | 0:79c6d0071c4c | 423 | return spiRead(RF22_REG_11_ADC_VALUE); |
charly | 0:79c6d0071c4c | 424 | } |
charly | 0:79c6d0071c4c | 425 | |
charly | 0:79c6d0071c4c | 426 | uint8_t RF22::temperatureRead(uint8_t tsrange, uint8_t tvoffs) |
charly | 0:79c6d0071c4c | 427 | { |
charly | 0:79c6d0071c4c | 428 | spiWrite(RF22_REG_12_TEMPERATURE_SENSOR_CALIBRATION, tsrange | RF22_ENTSOFFS); |
charly | 0:79c6d0071c4c | 429 | spiWrite(RF22_REG_13_TEMPERATURE_VALUE_OFFSET, tvoffs); |
charly | 8:d9e2ca137f2e | 430 | return adcRead(RF22_ADCSEL_INTERNAL_TEMPERATURE_SENSOR | RF22_ADCREF_BANDGAP_VOLTAGE); |
charly | 0:79c6d0071c4c | 431 | } |
charly | 0:79c6d0071c4c | 432 | |
charly | 0:79c6d0071c4c | 433 | uint16_t RF22::wutRead() |
charly | 0:79c6d0071c4c | 434 | { |
charly | 0:79c6d0071c4c | 435 | uint8_t buf[2]; |
charly | 0:79c6d0071c4c | 436 | spiBurstRead(RF22_REG_17_WAKEUP_TIMER_VALUE1, buf, 2); |
charly | 0:79c6d0071c4c | 437 | return ((uint16_t)buf[0] << 8) | buf[1]; // Dont rely on byte order |
charly | 0:79c6d0071c4c | 438 | } |
charly | 0:79c6d0071c4c | 439 | |
charly | 0:79c6d0071c4c | 440 | // RFM-22 doc appears to be wrong: WUT for wtm = 10000, r, = 0, d = 0 is about 1 sec |
charly | 0:79c6d0071c4c | 441 | void RF22::setWutPeriod(uint16_t wtm, uint8_t wtr, uint8_t wtd) |
charly | 0:79c6d0071c4c | 442 | { |
charly | 0:79c6d0071c4c | 443 | uint8_t period[3]; |
charly | 0:79c6d0071c4c | 444 | |
charly | 0:79c6d0071c4c | 445 | period[0] = ((wtr & 0xf) << 2) | (wtd & 0x3); |
charly | 0:79c6d0071c4c | 446 | period[1] = wtm >> 8; |
charly | 0:79c6d0071c4c | 447 | period[2] = wtm & 0xff; |
charly | 0:79c6d0071c4c | 448 | spiBurstWrite(RF22_REG_14_WAKEUP_TIMER_PERIOD1, period, sizeof(period)); |
charly | 0:79c6d0071c4c | 449 | } |
charly | 0:79c6d0071c4c | 450 | |
charly | 0:79c6d0071c4c | 451 | // Returns true if centre + (fhch * fhs) is within limits |
charly | 5:0386600f3408 | 452 | // Caution, different versions of the RF22 support different max freq |
charly | 0:79c6d0071c4c | 453 | // so YMMV |
charly | 5:0386600f3408 | 454 | boolean RF22::setFrequency(float centre, float afcPullInRange) |
charly | 0:79c6d0071c4c | 455 | { |
charly | 0:79c6d0071c4c | 456 | uint8_t fbsel = RF22_SBSEL; |
charly | 5:0386600f3408 | 457 | uint8_t afclimiter; |
charly | 0:79c6d0071c4c | 458 | if (centre < 240.0 || centre > 960.0) // 930.0 for early silicon |
charly | 5:0386600f3408 | 459 | return false; |
charly | 8:d9e2ca137f2e | 460 | if (centre >= 480.0) { |
charly | 8:d9e2ca137f2e | 461 | if (afcPullInRange < 0.0 || afcPullInRange > 0.318750) |
charly | 8:d9e2ca137f2e | 462 | return false; |
charly | 8:d9e2ca137f2e | 463 | centre /= 2; |
charly | 8:d9e2ca137f2e | 464 | fbsel |= RF22_HBSEL; |
charly | 8:d9e2ca137f2e | 465 | afclimiter = afcPullInRange * 1000000.0 / 1250.0; |
charly | 8:d9e2ca137f2e | 466 | } else { |
charly | 8:d9e2ca137f2e | 467 | if (afcPullInRange < 0.0 || afcPullInRange > 0.159375) |
charly | 8:d9e2ca137f2e | 468 | return false; |
charly | 8:d9e2ca137f2e | 469 | afclimiter = afcPullInRange * 1000000.0 / 625.0; |
charly | 0:79c6d0071c4c | 470 | } |
charly | 0:79c6d0071c4c | 471 | centre /= 10.0; |
charly | 0:79c6d0071c4c | 472 | float integerPart = floor(centre); |
charly | 0:79c6d0071c4c | 473 | float fractionalPart = centre - integerPart; |
charly | 0:79c6d0071c4c | 474 | |
charly | 0:79c6d0071c4c | 475 | uint8_t fb = (uint8_t)integerPart - 24; // Range 0 to 23 |
charly | 0:79c6d0071c4c | 476 | fbsel |= fb; |
charly | 0:79c6d0071c4c | 477 | uint16_t fc = fractionalPart * 64000; |
charly | 0:79c6d0071c4c | 478 | spiWrite(RF22_REG_73_FREQUENCY_OFFSET1, 0); // REVISIT |
charly | 0:79c6d0071c4c | 479 | spiWrite(RF22_REG_74_FREQUENCY_OFFSET2, 0); |
charly | 0:79c6d0071c4c | 480 | spiWrite(RF22_REG_75_FREQUENCY_BAND_SELECT, fbsel); |
charly | 0:79c6d0071c4c | 481 | spiWrite(RF22_REG_76_NOMINAL_CARRIER_FREQUENCY1, fc >> 8); |
charly | 0:79c6d0071c4c | 482 | spiWrite(RF22_REG_77_NOMINAL_CARRIER_FREQUENCY0, fc & 0xff); |
charly | 5:0386600f3408 | 483 | spiWrite(RF22_REG_2A_AFC_LIMITER, afclimiter); |
charly | 0:79c6d0071c4c | 484 | return !(statusRead() & RF22_FREQERR); |
charly | 0:79c6d0071c4c | 485 | } |
charly | 0:79c6d0071c4c | 486 | |
charly | 0:79c6d0071c4c | 487 | // Step size in 10kHz increments |
charly | 0:79c6d0071c4c | 488 | // Returns true if centre + (fhch * fhs) is within limits |
charly | 0:79c6d0071c4c | 489 | boolean RF22::setFHStepSize(uint8_t fhs) |
charly | 0:79c6d0071c4c | 490 | { |
charly | 0:79c6d0071c4c | 491 | spiWrite(RF22_REG_7A_FREQUENCY_HOPPING_STEP_SIZE, fhs); |
charly | 0:79c6d0071c4c | 492 | return !(statusRead() & RF22_FREQERR); |
charly | 0:79c6d0071c4c | 493 | } |
charly | 0:79c6d0071c4c | 494 | |
charly | 0:79c6d0071c4c | 495 | // Adds fhch * fhs to centre frequency |
charly | 0:79c6d0071c4c | 496 | // Returns true if centre + (fhch * fhs) is within limits |
charly | 0:79c6d0071c4c | 497 | boolean RF22::setFHChannel(uint8_t fhch) |
charly | 0:79c6d0071c4c | 498 | { |
charly | 0:79c6d0071c4c | 499 | spiWrite(RF22_REG_79_FREQUENCY_HOPPING_CHANNEL_SELECT, fhch); |
charly | 0:79c6d0071c4c | 500 | return !(statusRead() & RF22_FREQERR); |
charly | 0:79c6d0071c4c | 501 | } |
charly | 0:79c6d0071c4c | 502 | |
charly | 0:79c6d0071c4c | 503 | uint8_t RF22::rssiRead() |
charly | 0:79c6d0071c4c | 504 | { |
charly | 0:79c6d0071c4c | 505 | return spiRead(RF22_REG_26_RSSI); |
charly | 0:79c6d0071c4c | 506 | } |
charly | 0:79c6d0071c4c | 507 | |
charly | 0:79c6d0071c4c | 508 | uint8_t RF22::ezmacStatusRead() |
charly | 0:79c6d0071c4c | 509 | { |
charly | 0:79c6d0071c4c | 510 | return spiRead(RF22_REG_31_EZMAC_STATUS); |
charly | 0:79c6d0071c4c | 511 | } |
charly | 0:79c6d0071c4c | 512 | |
charly | 0:79c6d0071c4c | 513 | void RF22::setMode(uint8_t mode) |
charly | 0:79c6d0071c4c | 514 | { |
charly | 0:79c6d0071c4c | 515 | spiWrite(RF22_REG_07_OPERATING_MODE1, mode); |
charly | 0:79c6d0071c4c | 516 | } |
charly | 0:79c6d0071c4c | 517 | |
charly | 0:79c6d0071c4c | 518 | void RF22::setModeIdle() |
charly | 0:79c6d0071c4c | 519 | { |
charly | 8:d9e2ca137f2e | 520 | if (_mode != RF22_MODE_IDLE) { |
charly | 8:d9e2ca137f2e | 521 | setMode(_idleMode); |
charly | 8:d9e2ca137f2e | 522 | _mode = RF22_MODE_IDLE; |
charly | 0:79c6d0071c4c | 523 | } |
charly | 0:79c6d0071c4c | 524 | } |
charly | 0:79c6d0071c4c | 525 | |
charly | 0:79c6d0071c4c | 526 | void RF22::setModeRx() |
charly | 0:79c6d0071c4c | 527 | { |
charly | 8:d9e2ca137f2e | 528 | if (_mode != RF22_MODE_RX) { |
charly | 8:d9e2ca137f2e | 529 | setMode(_idleMode | RF22_RXON); |
charly | 8:d9e2ca137f2e | 530 | _mode = RF22_MODE_RX; |
charly | 0:79c6d0071c4c | 531 | } |
charly | 0:79c6d0071c4c | 532 | } |
charly | 0:79c6d0071c4c | 533 | |
charly | 0:79c6d0071c4c | 534 | void RF22::setModeTx() |
charly | 0:79c6d0071c4c | 535 | { |
charly | 8:d9e2ca137f2e | 536 | if (_mode != RF22_MODE_TX) { |
charly | 8:d9e2ca137f2e | 537 | setMode(_idleMode | RF22_TXON); |
charly | 8:d9e2ca137f2e | 538 | _mode = RF22_MODE_TX; |
charly | 8:d9e2ca137f2e | 539 | // Hmmm, if you dont clear the RX FIFO here, then it appears that going |
charly | 8:d9e2ca137f2e | 540 | // to transmit mode in the middle of a receive can corrupt the |
charly | 8:d9e2ca137f2e | 541 | // RX FIFO |
charly | 8:d9e2ca137f2e | 542 | resetRxFifo(); |
charly | 8:d9e2ca137f2e | 543 | // clearRxBuf(); |
charly | 0:79c6d0071c4c | 544 | } |
charly | 8:d9e2ca137f2e | 545 | } |
charly | 5:0386600f3408 | 546 | |
charly | 5:0386600f3408 | 547 | uint8_t RF22::mode() |
charly | 5:0386600f3408 | 548 | { |
charly | 5:0386600f3408 | 549 | return _mode; |
charly | 0:79c6d0071c4c | 550 | } |
charly | 0:79c6d0071c4c | 551 | |
charly | 0:79c6d0071c4c | 552 | void RF22::setTxPower(uint8_t power) |
charly | 0:79c6d0071c4c | 553 | { |
charly | 0:79c6d0071c4c | 554 | spiWrite(RF22_REG_6D_TX_POWER, power); |
charly | 0:79c6d0071c4c | 555 | } |
charly | 0:79c6d0071c4c | 556 | |
charly | 0:79c6d0071c4c | 557 | // Sets registers from a canned modem configuration structure |
charly | 5:0386600f3408 | 558 | void RF22::setModemRegisters(const ModemConfig* config) |
charly | 0:79c6d0071c4c | 559 | { |
charly | 0:79c6d0071c4c | 560 | spiWrite(RF22_REG_1C_IF_FILTER_BANDWIDTH, config->reg_1c); |
charly | 0:79c6d0071c4c | 561 | spiWrite(RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE, config->reg_1f); |
charly | 0:79c6d0071c4c | 562 | spiBurstWrite(RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE, &config->reg_20, 6); |
charly | 0:79c6d0071c4c | 563 | spiBurstWrite(RF22_REG_2C_OOK_COUNTER_VALUE_1, &config->reg_2c, 3); |
charly | 0:79c6d0071c4c | 564 | spiWrite(RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING, config->reg_58); |
charly | 0:79c6d0071c4c | 565 | spiWrite(RF22_REG_69_AGC_OVERRIDE1, config->reg_69); |
charly | 0:79c6d0071c4c | 566 | spiBurstWrite(RF22_REG_6E_TX_DATA_RATE1, &config->reg_6e, 5); |
charly | 0:79c6d0071c4c | 567 | } |
charly | 0:79c6d0071c4c | 568 | |
charly | 0:79c6d0071c4c | 569 | // Set one of the canned FSK Modem configs |
charly | 0:79c6d0071c4c | 570 | // Returns true if its a valid choice |
charly | 0:79c6d0071c4c | 571 | boolean RF22::setModemConfig(ModemConfigChoice index) |
charly | 0:79c6d0071c4c | 572 | { |
charly | 0:79c6d0071c4c | 573 | if (index > (sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig))) |
charly | 0:79c6d0071c4c | 574 | return false; |
charly | 0:79c6d0071c4c | 575 | |
charly | 0:79c6d0071c4c | 576 | RF22::ModemConfig cfg; |
charly | 0:79c6d0071c4c | 577 | memcpy(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(RF22::ModemConfig)); |
charly | 0:79c6d0071c4c | 578 | setModemRegisters(&cfg); |
charly | 0:79c6d0071c4c | 579 | |
charly | 0:79c6d0071c4c | 580 | return true; |
charly | 0:79c6d0071c4c | 581 | } |
charly | 0:79c6d0071c4c | 582 | |
charly | 0:79c6d0071c4c | 583 | // REVISIT: top bit is in Header Control 2 0x33 |
charly | 0:79c6d0071c4c | 584 | void RF22::setPreambleLength(uint8_t nibbles) |
charly | 0:79c6d0071c4c | 585 | { |
charly | 0:79c6d0071c4c | 586 | spiWrite(RF22_REG_34_PREAMBLE_LENGTH, nibbles); |
charly | 0:79c6d0071c4c | 587 | } |
charly | 0:79c6d0071c4c | 588 | |
charly | 0:79c6d0071c4c | 589 | // Caution doesnt set sync word len in Header Control 2 0x33 |
charly | 5:0386600f3408 | 590 | void RF22::setSyncWords(const uint8_t* syncWords, uint8_t len) |
charly | 0:79c6d0071c4c | 591 | { |
charly | 0:79c6d0071c4c | 592 | spiBurstWrite(RF22_REG_36_SYNC_WORD3, syncWords, len); |
charly | 0:79c6d0071c4c | 593 | } |
charly | 0:79c6d0071c4c | 594 | |
charly | 0:79c6d0071c4c | 595 | void RF22::clearRxBuf() |
charly | 0:79c6d0071c4c | 596 | { |
charly | 7:b86825b9d74b | 597 | __disable_irq(); // Disable Interrupts |
charly | 0:79c6d0071c4c | 598 | _bufLen = 0; |
charly | 0:79c6d0071c4c | 599 | _rxBufValid = false; |
charly | 7:b86825b9d74b | 600 | __enable_irq(); // Enable Interrupts |
charly | 0:79c6d0071c4c | 601 | } |
charly | 0:79c6d0071c4c | 602 | |
charly | 0:79c6d0071c4c | 603 | boolean RF22::available() |
charly | 0:79c6d0071c4c | 604 | { |
charly | 5:0386600f3408 | 605 | if (!_rxBufValid) |
charly | 8:d9e2ca137f2e | 606 | setModeRx(); // Make sure we are receiving |
charly | 0:79c6d0071c4c | 607 | return _rxBufValid; |
charly | 0:79c6d0071c4c | 608 | } |
charly | 0:79c6d0071c4c | 609 | |
charly | 0:79c6d0071c4c | 610 | // Blocks until a valid message is received |
charly | 0:79c6d0071c4c | 611 | void RF22::waitAvailable() |
charly | 0:79c6d0071c4c | 612 | { |
charly | 0:79c6d0071c4c | 613 | while (!available()) |
charly | 8:d9e2ca137f2e | 614 | ; |
charly | 0:79c6d0071c4c | 615 | } |
charly | 0:79c6d0071c4c | 616 | |
charly | 0:79c6d0071c4c | 617 | // Blocks until a valid message is received or timeout expires |
charly | 0:79c6d0071c4c | 618 | // Return true if there is a message available |
charly | 0:79c6d0071c4c | 619 | bool RF22::waitAvailableTimeout(uint16_t timeout) |
charly | 0:79c6d0071c4c | 620 | { |
charly | 0:79c6d0071c4c | 621 | Timer t; |
charly | 0:79c6d0071c4c | 622 | t.start(); |
charly | 0:79c6d0071c4c | 623 | unsigned long endtime = t.read_ms() + timeout; |
charly | 0:79c6d0071c4c | 624 | while (t.read_ms() < endtime) |
charly | 8:d9e2ca137f2e | 625 | if (available()) |
charly | 8:d9e2ca137f2e | 626 | return true; |
charly | 0:79c6d0071c4c | 627 | return false; |
charly | 0:79c6d0071c4c | 628 | } |
charly | 0:79c6d0071c4c | 629 | |
charly | 0:79c6d0071c4c | 630 | void RF22::waitPacketSent() |
charly | 0:79c6d0071c4c | 631 | { |
charly | 5:0386600f3408 | 632 | while (_mode == RF22_MODE_TX) |
charly | 8:d9e2ca137f2e | 633 | ; // Wait for any previous transmit to finish |
charly | 5:0386600f3408 | 634 | } |
charly | 5:0386600f3408 | 635 | |
charly | 5:0386600f3408 | 636 | // Diagnostic help |
charly | 5:0386600f3408 | 637 | void RF22::printBuffer(const char* prompt, const uint8_t* buf, uint8_t len) |
charly | 5:0386600f3408 | 638 | { |
charly | 5:0386600f3408 | 639 | #ifdef RF22_HAVE_SERIAL |
charly | 5:0386600f3408 | 640 | uint8_t i; |
charly | 5:0386600f3408 | 641 | |
charly | 5:0386600f3408 | 642 | Serial.println(prompt); |
charly | 8:d9e2ca137f2e | 643 | for (i = 0; i < len; i++) { |
charly | 8:d9e2ca137f2e | 644 | if (i % 16 == 15) |
charly | 8:d9e2ca137f2e | 645 | Serial.println(buf[i], HEX); |
charly | 8:d9e2ca137f2e | 646 | else { |
charly | 8:d9e2ca137f2e | 647 | Serial.print(buf[i], HEX); |
charly | 8:d9e2ca137f2e | 648 | Serial.print(' '); |
charly | 8:d9e2ca137f2e | 649 | } |
charly | 5:0386600f3408 | 650 | } |
charly | 5:0386600f3408 | 651 | Serial.println(' '); |
charly | 5:0386600f3408 | 652 | #endif |
charly | 0:79c6d0071c4c | 653 | } |
charly | 0:79c6d0071c4c | 654 | |
charly | 0:79c6d0071c4c | 655 | boolean RF22::recv(uint8_t* buf, uint8_t* len) |
charly | 0:79c6d0071c4c | 656 | { |
charly | 0:79c6d0071c4c | 657 | if (!available()) |
charly | 8:d9e2ca137f2e | 658 | return false; |
charly | 8:d9e2ca137f2e | 659 | __disable_irq(); // Disable Interrupts |
charly | 0:79c6d0071c4c | 660 | if (*len > _bufLen) |
charly | 8:d9e2ca137f2e | 661 | *len = _bufLen; |
charly | 0:79c6d0071c4c | 662 | memcpy(buf, _buf, *len); |
charly | 0:79c6d0071c4c | 663 | clearRxBuf(); |
charly | 8:d9e2ca137f2e | 664 | __enable_irq(); // Enable Interrupts |
charly | 5:0386600f3408 | 665 | // printBuffer("recv:", buf, *len); |
charly | 5:0386600f3408 | 666 | // } |
charly | 0:79c6d0071c4c | 667 | return true; |
charly | 0:79c6d0071c4c | 668 | } |
charly | 0:79c6d0071c4c | 669 | |
charly | 0:79c6d0071c4c | 670 | void RF22::clearTxBuf() |
charly | 0:79c6d0071c4c | 671 | { |
charly | 7:b86825b9d74b | 672 | __disable_irq(); // Disable Interrupts |
charly | 0:79c6d0071c4c | 673 | _bufLen = 0; |
charly | 0:79c6d0071c4c | 674 | _txBufSentIndex = 0; |
charly | 0:79c6d0071c4c | 675 | _txPacketSent = false; |
charly | 7:b86825b9d74b | 676 | __enable_irq(); // Enable Interrupts |
charly | 0:79c6d0071c4c | 677 | } |
charly | 0:79c6d0071c4c | 678 | |
charly | 0:79c6d0071c4c | 679 | void RF22::startTransmit() |
charly | 0:79c6d0071c4c | 680 | { |
charly | 0:79c6d0071c4c | 681 | sendNextFragment(); // Actually the first fragment |
charly | 0:79c6d0071c4c | 682 | spiWrite(RF22_REG_3E_PACKET_LENGTH, _bufLen); // Total length that will be sent |
charly | 0:79c6d0071c4c | 683 | setModeTx(); // Start the transmitter, turns off the receiver |
charly | 0:79c6d0071c4c | 684 | } |
charly | 0:79c6d0071c4c | 685 | |
charly | 5:0386600f3408 | 686 | // Restart the transmission of a packet that had a problem |
charly | 0:79c6d0071c4c | 687 | void RF22::restartTransmit() |
charly | 0:79c6d0071c4c | 688 | { |
charly | 0:79c6d0071c4c | 689 | _mode = RF22_MODE_IDLE; |
charly | 0:79c6d0071c4c | 690 | _txBufSentIndex = 0; |
charly | 0:79c6d0071c4c | 691 | // Serial.println("Restart"); |
charly | 0:79c6d0071c4c | 692 | startTransmit(); |
charly | 0:79c6d0071c4c | 693 | } |
charly | 0:79c6d0071c4c | 694 | |
charly | 5:0386600f3408 | 695 | boolean RF22::send(const uint8_t* data, uint8_t len) |
charly | 0:79c6d0071c4c | 696 | { |
charly | 5:0386600f3408 | 697 | waitPacketSent(); |
charly | 5:0386600f3408 | 698 | // ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
charly | 5:0386600f3408 | 699 | { |
charly | 8:d9e2ca137f2e | 700 | if (!fillTxBuf(data, len)) |
charly | 8:d9e2ca137f2e | 701 | return false; |
charly | 8:d9e2ca137f2e | 702 | startTransmit(); |
charly | 5:0386600f3408 | 703 | } |
charly | 5:0386600f3408 | 704 | // printBuffer("send:", data, len); |
charly | 0:79c6d0071c4c | 705 | return true; |
charly | 0:79c6d0071c4c | 706 | } |
charly | 0:79c6d0071c4c | 707 | |
charly | 5:0386600f3408 | 708 | boolean RF22::fillTxBuf(const uint8_t* data, uint8_t len) |
charly | 0:79c6d0071c4c | 709 | { |
charly | 0:79c6d0071c4c | 710 | clearTxBuf(); |
charly | 5:0386600f3408 | 711 | if (!len) |
charly | 8:d9e2ca137f2e | 712 | return false; |
charly | 0:79c6d0071c4c | 713 | return appendTxBuf(data, len); |
charly | 0:79c6d0071c4c | 714 | } |
charly | 0:79c6d0071c4c | 715 | |
charly | 5:0386600f3408 | 716 | boolean RF22::appendTxBuf(const uint8_t* data, uint8_t len) |
charly | 0:79c6d0071c4c | 717 | { |
charly | 0:79c6d0071c4c | 718 | if (((uint16_t)_bufLen + len) > RF22_MAX_MESSAGE_LEN) |
charly | 8:d9e2ca137f2e | 719 | return false; |
charly | 8:d9e2ca137f2e | 720 | __disable_irq(); // Disable Interrupts |
charly | 0:79c6d0071c4c | 721 | memcpy(_buf + _bufLen, data, len); |
charly | 0:79c6d0071c4c | 722 | _bufLen += len; |
charly | 8:d9e2ca137f2e | 723 | __enable_irq(); // Enable Interrupts |
charly | 8:d9e2ca137f2e | 724 | |
charly | 5:0386600f3408 | 725 | // printBuffer("txbuf:", _buf, _bufLen); |
charly | 0:79c6d0071c4c | 726 | return true; |
charly | 0:79c6d0071c4c | 727 | } |
charly | 0:79c6d0071c4c | 728 | |
charly | 0:79c6d0071c4c | 729 | // Assumption: there is currently <= RF22_TXFFAEM_THRESHOLD bytes in the Tx FIFO |
charly | 0:79c6d0071c4c | 730 | void RF22::sendNextFragment() |
charly | 0:79c6d0071c4c | 731 | { |
charly | 8:d9e2ca137f2e | 732 | if (_txBufSentIndex < _bufLen) { |
charly | 8:d9e2ca137f2e | 733 | // Some left to send? |
charly | 8:d9e2ca137f2e | 734 | uint8_t len = _bufLen - _txBufSentIndex; |
charly | 8:d9e2ca137f2e | 735 | // But dont send too much |
charly | 8:d9e2ca137f2e | 736 | if (len > (RF22_FIFO_SIZE - RF22_TXFFAEM_THRESHOLD - 1)) |
charly | 8:d9e2ca137f2e | 737 | len = (RF22_FIFO_SIZE - RF22_TXFFAEM_THRESHOLD - 1); |
charly | 8:d9e2ca137f2e | 738 | spiBurstWrite(RF22_REG_7F_FIFO_ACCESS, _buf + _txBufSentIndex, len); |
charly | 8:d9e2ca137f2e | 739 | _txBufSentIndex += len; |
charly | 0:79c6d0071c4c | 740 | } |
charly | 0:79c6d0071c4c | 741 | } |
charly | 0:79c6d0071c4c | 742 | |
charly | 0:79c6d0071c4c | 743 | // Assumption: there are at least RF22_RXFFAFULL_THRESHOLD in the RX FIFO |
charly | 5:0386600f3408 | 744 | // That means it should only be called after a RXFFAFULL interrupt |
charly | 0:79c6d0071c4c | 745 | void RF22::readNextFragment() |
charly | 0:79c6d0071c4c | 746 | { |
charly | 0:79c6d0071c4c | 747 | if (((uint16_t)_bufLen + RF22_RXFFAFULL_THRESHOLD) > RF22_MAX_MESSAGE_LEN) |
charly | 8:d9e2ca137f2e | 748 | return; // Hmmm receiver overflow. Should never occur |
charly | 5:0386600f3408 | 749 | |
charly | 0:79c6d0071c4c | 750 | // Read the RF22_RXFFAFULL_THRESHOLD octets that should be there |
charly | 0:79c6d0071c4c | 751 | spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, RF22_RXFFAFULL_THRESHOLD); |
charly | 0:79c6d0071c4c | 752 | _bufLen += RF22_RXFFAFULL_THRESHOLD; |
charly | 0:79c6d0071c4c | 753 | } |
charly | 0:79c6d0071c4c | 754 | |
charly | 0:79c6d0071c4c | 755 | // Clear the FIFOs |
charly | 0:79c6d0071c4c | 756 | void RF22::resetFifos() |
charly | 0:79c6d0071c4c | 757 | { |
charly | 0:79c6d0071c4c | 758 | spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRRX | RF22_FFCLRTX); |
charly | 0:79c6d0071c4c | 759 | spiWrite(RF22_REG_08_OPERATING_MODE2, 0); |
charly | 0:79c6d0071c4c | 760 | } |
charly | 0:79c6d0071c4c | 761 | |
charly | 0:79c6d0071c4c | 762 | // Clear the Rx FIFO |
charly | 0:79c6d0071c4c | 763 | void RF22::resetRxFifo() |
charly | 0:79c6d0071c4c | 764 | { |
charly | 0:79c6d0071c4c | 765 | spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRRX); |
charly | 0:79c6d0071c4c | 766 | spiWrite(RF22_REG_08_OPERATING_MODE2, 0); |
charly | 0:79c6d0071c4c | 767 | } |
charly | 0:79c6d0071c4c | 768 | |
charly | 0:79c6d0071c4c | 769 | // CLear the TX FIFO |
charly | 0:79c6d0071c4c | 770 | void RF22::resetTxFifo() |
charly | 0:79c6d0071c4c | 771 | { |
charly | 0:79c6d0071c4c | 772 | spiWrite(RF22_REG_08_OPERATING_MODE2, RF22_FFCLRTX); |
charly | 0:79c6d0071c4c | 773 | spiWrite(RF22_REG_08_OPERATING_MODE2, 0); |
charly | 0:79c6d0071c4c | 774 | } |
charly | 0:79c6d0071c4c | 775 | |
charly | 0:79c6d0071c4c | 776 | // Default implmentation does nothing. Override if you wish |
charly | 0:79c6d0071c4c | 777 | void RF22::handleExternalInterrupt() |
charly | 0:79c6d0071c4c | 778 | { |
charly | 0:79c6d0071c4c | 779 | } |
charly | 0:79c6d0071c4c | 780 | |
charly | 0:79c6d0071c4c | 781 | // Default implmentation does nothing. Override if you wish |
charly | 0:79c6d0071c4c | 782 | void RF22::handleWakeupTimerInterrupt() |
charly | 0:79c6d0071c4c | 783 | { |
charly | 0:79c6d0071c4c | 784 | } |
charly | 0:79c6d0071c4c | 785 | |
charly | 0:79c6d0071c4c | 786 | void RF22::setHeaderTo(uint8_t to) |
charly | 0:79c6d0071c4c | 787 | { |
charly | 0:79c6d0071c4c | 788 | spiWrite(RF22_REG_3A_TRANSMIT_HEADER3, to); |
charly | 0:79c6d0071c4c | 789 | } |
charly | 0:79c6d0071c4c | 790 | |
charly | 0:79c6d0071c4c | 791 | void RF22::setHeaderFrom(uint8_t from) |
charly | 0:79c6d0071c4c | 792 | { |
charly | 0:79c6d0071c4c | 793 | spiWrite(RF22_REG_3B_TRANSMIT_HEADER2, from); |
charly | 0:79c6d0071c4c | 794 | } |
charly | 0:79c6d0071c4c | 795 | |
charly | 0:79c6d0071c4c | 796 | void RF22::setHeaderId(uint8_t id) |
charly | 0:79c6d0071c4c | 797 | { |
charly | 0:79c6d0071c4c | 798 | spiWrite(RF22_REG_3C_TRANSMIT_HEADER1, id); |
charly | 0:79c6d0071c4c | 799 | } |
charly | 0:79c6d0071c4c | 800 | |
charly | 0:79c6d0071c4c | 801 | void RF22::setHeaderFlags(uint8_t flags) |
charly | 0:79c6d0071c4c | 802 | { |
charly | 0:79c6d0071c4c | 803 | spiWrite(RF22_REG_3D_TRANSMIT_HEADER0, flags); |
charly | 0:79c6d0071c4c | 804 | } |
charly | 0:79c6d0071c4c | 805 | |
charly | 0:79c6d0071c4c | 806 | uint8_t RF22::headerTo() |
charly | 0:79c6d0071c4c | 807 | { |
charly | 0:79c6d0071c4c | 808 | return spiRead(RF22_REG_47_RECEIVED_HEADER3); |
charly | 0:79c6d0071c4c | 809 | } |
charly | 0:79c6d0071c4c | 810 | |
charly | 0:79c6d0071c4c | 811 | uint8_t RF22::headerFrom() |
charly | 0:79c6d0071c4c | 812 | { |
charly | 0:79c6d0071c4c | 813 | return spiRead(RF22_REG_48_RECEIVED_HEADER2); |
charly | 0:79c6d0071c4c | 814 | } |
charly | 0:79c6d0071c4c | 815 | |
charly | 0:79c6d0071c4c | 816 | uint8_t RF22::headerId() |
charly | 0:79c6d0071c4c | 817 | { |
charly | 0:79c6d0071c4c | 818 | return spiRead(RF22_REG_49_RECEIVED_HEADER1); |
charly | 0:79c6d0071c4c | 819 | } |
charly | 0:79c6d0071c4c | 820 | |
charly | 0:79c6d0071c4c | 821 | uint8_t RF22::headerFlags() |
charly | 0:79c6d0071c4c | 822 | { |
charly | 0:79c6d0071c4c | 823 | return spiRead(RF22_REG_4A_RECEIVED_HEADER0); |
charly | 0:79c6d0071c4c | 824 | } |
charly | 0:79c6d0071c4c | 825 | |
charly | 0:79c6d0071c4c | 826 | uint8_t RF22::lastRssi() |
charly | 0:79c6d0071c4c | 827 | { |
charly | 0:79c6d0071c4c | 828 | return _lastRssi; |
charly | 0:79c6d0071c4c | 829 | } |
charly | 0:79c6d0071c4c | 830 | |
charly | 0:79c6d0071c4c | 831 | void RF22::setPromiscuous(boolean promiscuous) |
charly | 0:79c6d0071c4c | 832 | { |
charly | 0:79c6d0071c4c | 833 | spiWrite(RF22_REG_43_HEADER_ENABLE3, promiscuous ? 0x00 : 0xff); |
charly | 0:79c6d0071c4c | 834 | } |