V148

Fork of RadioHead-148 by David Rimer

Committer:
ilkaykozak
Date:
Wed Oct 25 05:14:09 2017 +0000
Revision:
1:b7641da2b203
Parent:
0:ab4e012489ef
V148

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davidr99 0:ab4e012489ef 1 // RH_RF24.cpp
davidr99 0:ab4e012489ef 2 //
davidr99 0:ab4e012489ef 3 // Copyright (C) 2011 Mike McCauley
davidr99 0:ab4e012489ef 4 // $Id: RH_RF24.cpp,v 1.14 2015/08/13 02:45:47 mikem Exp $
davidr99 0:ab4e012489ef 5
davidr99 0:ab4e012489ef 6 #include <RH_RF24.h>
davidr99 0:ab4e012489ef 7 // Generated with Silicon Labs WDS software:
davidr99 0:ab4e012489ef 8 #include "radio_config_Si4460.h"
davidr99 0:ab4e012489ef 9
davidr99 0:ab4e012489ef 10 // Interrupt vectors for the 3 Arduino interrupt pins
davidr99 0:ab4e012489ef 11 // Each interrupt can be handled by a different instance of RH_RF24, allowing you to have
davidr99 0:ab4e012489ef 12 // 2 or more RF24s per Arduino
davidr99 0:ab4e012489ef 13 RH_RF24* RH_RF24::_deviceForInterrupt[RH_RF24_NUM_INTERRUPTS] = {0, 0, 0};
davidr99 0:ab4e012489ef 14 uint8_t RH_RF24::_interruptCount = 0; // Index into _deviceForInterrupt for next device
davidr99 0:ab4e012489ef 15
davidr99 0:ab4e012489ef 16 // This configuration data is defined in radio_config_Si4460.h
davidr99 0:ab4e012489ef 17 // which was generated with the Silicon Labs WDS program
davidr99 0:ab4e012489ef 18 PROGMEM const uint8_t RFM26_CONFIGURATION_DATA[] = RADIO_CONFIGURATION_DATA_ARRAY;
davidr99 0:ab4e012489ef 19
davidr99 0:ab4e012489ef 20 // These configurations were all generated originally by the Silicon LAbs WDS configuration tool.
davidr99 0:ab4e012489ef 21 // The configurations were imported into RH_RF24, the complete properties set dumped to a file with printRegisters, then
davidr99 0:ab4e012489ef 22 // RH_RF24_property_data/convert.pl was used to generate the entry for this table.
davidr99 0:ab4e012489ef 23 // Contributions of new complete and tested ModemConfigs ready to add to this list will be readily accepted.
davidr99 0:ab4e012489ef 24 // Casual suggestions of new schemes without working examples will probably be passed over
davidr99 0:ab4e012489ef 25 PROGMEM static const RH_RF24::ModemConfig MODEM_CONFIG_TABLE[] =
davidr99 0:ab4e012489ef 26 {
davidr99 0:ab4e012489ef 27 // These were generated with convert.pl from data in RH_RF24_property_data
davidr99 0:ab4e012489ef 28 // FSK_Rb0_5Fd1
davidr99 0:ab4e012489ef 29 { 0x02, 0x00, 0x13, 0x88, 0x01, 0x00, 0x00, 0x46, 0x01, 0x34, 0x11, 0x02, 0x71, 0x00, 0xd1, 0xb7, 0x00, 0x69, 0x02, 0x36, 0x80, 0x01, 0x5a, 0xfc, 0xe2, 0x11, 0x89, 0x89, 0x00, 0x02, 0xff, 0xff, 0x00, 0x2b, 0x02, 0x81, 0x00, 0xad, 0x3a, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 30
davidr99 0:ab4e012489ef 31 // FSK_Rb5Fd10
davidr99 0:ab4e012489ef 32 { 0x02, 0x00, 0xc3, 0x50, 0x01, 0x00, 0x02, 0xbb, 0x01, 0x30, 0x20, 0x01, 0x77, 0x01, 0x5d, 0x86, 0x00, 0xaf, 0x02, 0x36, 0x80, 0x0f, 0x15, 0x87, 0xe2, 0x11, 0x52, 0x52, 0x00, 0x02, 0xff, 0xff, 0x00, 0x2a, 0x02, 0x83, 0x01, 0x20, 0x40, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 33
davidr99 0:ab4e012489ef 34 // FSK_Rb50Fd100
davidr99 0:ab4e012489ef 35 { 0x02, 0x07, 0xa1, 0x20, 0x01, 0x00, 0x1b, 0x4f, 0x01, 0x00, 0x10, 0x00, 0xc8, 0x02, 0x8f, 0x5c, 0x01, 0x48, 0x02, 0x36, 0x80, 0x92, 0x0a, 0x46, 0xe2, 0x11, 0x2c, 0x2c, 0x00, 0x02, 0xff, 0xff, 0x00, 0x29, 0x02, 0x83, 0x02, 0x7f, 0x40, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 36
davidr99 0:ab4e012489ef 37 //FSK_Rb150Fd300
davidr99 0:ab4e012489ef 38 { 0x02, 0x16, 0xe3, 0x60, 0x01, 0x00, 0x51, 0xec, 0x01, 0x00, 0x30, 0x00, 0xc8, 0x02, 0x8f, 0x5c, 0x01, 0x48, 0x02, 0x47, 0x83, 0x6a, 0x04, 0xb5, 0xe2, 0x22, 0x16, 0x16, 0x00, 0x02, 0xff, 0xff, 0x00, 0x29, 0x02, 0x83, 0x02, 0x7f, 0x40, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0x3f, 0x39, 0x04, 0x05, 0x04, 0x01, },
davidr99 0:ab4e012489ef 39
davidr99 0:ab4e012489ef 40 // GFSK_Rb0_5Fd1
davidr99 0:ab4e012489ef 41 { 0x03, 0x00, 0x4e, 0x20, 0x05, 0x00, 0x00, 0x46, 0x01, 0x34, 0x11, 0x02, 0x71, 0x00, 0xd1, 0xb7, 0x00, 0x69, 0x02, 0x36, 0x80, 0x01, 0x5a, 0xfc, 0xe2, 0x11, 0x89, 0x89, 0x00, 0x1a, 0xff, 0xff, 0x00, 0x2b, 0x02, 0x81, 0x00, 0x68, 0x3a, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 42
davidr99 0:ab4e012489ef 43 // GFSK_Rb5Fd10
davidr99 0:ab4e012489ef 44 { 0x03, 0x03, 0x0d, 0x40, 0x05, 0x00, 0x02, 0xbb, 0x01, 0x30, 0x20, 0x01, 0x77, 0x01, 0x5d, 0x86, 0x00, 0xaf, 0x02, 0x36, 0x80, 0x0f, 0x15, 0x87, 0xe2, 0x11, 0x52, 0x52, 0x00, 0x1a, 0xff, 0xff, 0x00, 0x2a, 0x02, 0x83, 0x00, 0xad, 0x40, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0xff, 0xba, 0x0f, 0x51, 0xcf, 0xa9, 0xc9, 0xfc, 0x1b, 0x1e, 0x0f, 0x01, 0xfc, 0xfd, 0x15, 0xff, 0x00, 0x0f, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 45
davidr99 0:ab4e012489ef 46 // GFSK_Rb50Fd100
davidr99 0:ab4e012489ef 47 { 0x03, 0x0f, 0x42, 0x40, 0x09, 0x00, 0x1b, 0x4f, 0x01, 0x00, 0x10, 0x00, 0xc8, 0x02, 0x8f, 0x5c, 0x01, 0x48, 0x02, 0x36, 0x80, 0x92, 0x0a, 0x46, 0xe2, 0x11, 0x2c, 0x2c, 0x00, 0x1a, 0xff, 0xff, 0x00, 0x29, 0x02, 0x83, 0x01, 0x7f, 0x40, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 48
davidr99 0:ab4e012489ef 49 // GFSK_Rb150Fd300
davidr99 0:ab4e012489ef 50 { 0x03, 0x2d, 0xc6, 0xc0, 0x09, 0x00, 0x51, 0xec, 0x01, 0x00, 0x30, 0x00, 0xc8, 0x02, 0x8f, 0x5c, 0x01, 0x48, 0x02, 0x47, 0x83, 0x6a, 0x04, 0xb5, 0xe2, 0x22, 0x16, 0x16, 0x00, 0x1a, 0xff, 0xff, 0x00, 0x29, 0x02, 0x83, 0x01, 0x7f, 0x40, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0xff, 0xc4, 0x30, 0x7f, 0xf5, 0xb5, 0xb8, 0xde, 0x05, 0x17, 0x16, 0x0c, 0x03, 0x00, 0x15, 0xff, 0x00, 0x00, 0x3f, 0x39, 0x04, 0x05, 0x04, 0x01, },
davidr99 0:ab4e012489ef 51
davidr99 0:ab4e012489ef 52 // OOK_Rb5Bw30
davidr99 0:ab4e012489ef 53 { 0x01, 0x00, 0xc3, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x34, 0x10, 0x00, 0x3f, 0x08, 0x31, 0x27, 0x04, 0x10, 0x02, 0x12, 0x00, 0x2c, 0x03, 0xf9, 0x62, 0x11, 0x0e, 0x0e, 0x00, 0x02, 0xff, 0xff, 0x00, 0x27, 0x00, 0x00, 0x07, 0xff, 0x40, 0xcc, 0xa1, 0x30, 0xa0, 0x21, 0xd1, 0xb9, 0xc9, 0xea, 0x05, 0x12, 0x11, 0x0a, 0x04, 0x15, 0xfc, 0x03, 0x00, 0xcc, 0xa1, 0x30, 0xa0, 0x21, 0xd1, 0xb9, 0xc9, 0xea, 0x05, 0x12, 0x11, 0x0a, 0x04, 0x15, 0xfc, 0x03, 0x00, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 54
davidr99 0:ab4e012489ef 55 // OOK_Rb10Bw40
davidr99 0:ab4e012489ef 56 { 0x01, 0x01, 0x86, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x32, 0x20, 0x00, 0x5e, 0x05, 0x76, 0x1a, 0x02, 0xb9, 0x02, 0x12, 0x00, 0x57, 0x02, 0xb0, 0x62, 0x11, 0x15, 0x15, 0x00, 0x02, 0xff, 0xff, 0x00, 0x28, 0x00, 0x00, 0x07, 0xff, 0x40, 0xa2, 0x81, 0x26, 0xaf, 0x3f, 0xee, 0xc8, 0xc7, 0xdb, 0xf2, 0x02, 0x08, 0x07, 0x03, 0x15, 0xfc, 0x0f, 0x00, 0xa2, 0x81, 0x26, 0xaf, 0x3f, 0xee, 0xc8, 0xc7, 0xdb, 0xf2, 0x02, 0x08, 0x07, 0x03, 0x15, 0xfc, 0x0f, 0x00, 0x3f, 0x2c, 0x0e, 0x04, 0x0c, 0x73, },
davidr99 0:ab4e012489ef 57
davidr99 0:ab4e012489ef 58 };
davidr99 0:ab4e012489ef 59
davidr99 0:ab4e012489ef 60 RH_RF24::RH_RF24(PINS slaveSelectPin, PINS interruptPin, PINS sdnPin, RHGenericSPI& spi)
davidr99 0:ab4e012489ef 61 :
davidr99 0:ab4e012489ef 62 RHSPIDriver(slaveSelectPin, spi),
davidr99 0:ab4e012489ef 63 _interruptPin(interruptPin),
davidr99 0:ab4e012489ef 64 _sdnPin(sdnPin)
davidr99 0:ab4e012489ef 65 {
davidr99 0:ab4e012489ef 66 _idleMode = RH_RF24_DEVICE_STATE_READY;
davidr99 0:ab4e012489ef 67 _myInterruptIndex = 0xff; // Not allocated yet
davidr99 0:ab4e012489ef 68 }
davidr99 0:ab4e012489ef 69
davidr99 0:ab4e012489ef 70 void RH_RF24::setIdleMode(uint8_t idleMode)
davidr99 0:ab4e012489ef 71 {
davidr99 0:ab4e012489ef 72 _idleMode = idleMode;
davidr99 0:ab4e012489ef 73 }
davidr99 0:ab4e012489ef 74
davidr99 0:ab4e012489ef 75 bool RH_RF24::init()
davidr99 0:ab4e012489ef 76 {
davidr99 0:ab4e012489ef 77 if (!RHSPIDriver::init())
davidr99 0:ab4e012489ef 78 return false;
davidr99 0:ab4e012489ef 79
davidr99 0:ab4e012489ef 80 #if (RH_PLATFORM != RH_PLATFORM_MBED)
davidr99 0:ab4e012489ef 81 // Determine the interrupt number that corresponds to the interruptPin
davidr99 0:ab4e012489ef 82 int interruptNumber = digitalPinToInterrupt(_interruptPin);
davidr99 0:ab4e012489ef 83 if (interruptNumber == NOT_AN_INTERRUPT)
davidr99 0:ab4e012489ef 84 return false;
davidr99 0:ab4e012489ef 85 #endif
davidr99 0:ab4e012489ef 86
davidr99 0:ab4e012489ef 87 // Initialise the radio
davidr99 0:ab4e012489ef 88 power_on_reset();
davidr99 0:ab4e012489ef 89 cmd_clear_all_interrupts();
davidr99 0:ab4e012489ef 90 // Here we use a configuration generated by the Silicon Las Wireless Development Suite
davidr99 0:ab4e012489ef 91 // in radio_config_Si4460.h
davidr99 0:ab4e012489ef 92 // WE override a few things later that we ned to be sure of.
davidr99 0:ab4e012489ef 93 configure(RFM26_CONFIGURATION_DATA);
davidr99 0:ab4e012489ef 94
davidr99 0:ab4e012489ef 95 // Get the device type and check it
davidr99 0:ab4e012489ef 96 // This also tests whether we are really connected to a device
davidr99 0:ab4e012489ef 97 uint8_t buf[8];
davidr99 0:ab4e012489ef 98 if (!command(RH_RF24_CMD_PART_INFO, 0, 0, buf, sizeof(buf)))
davidr99 0:ab4e012489ef 99 return false; // SPI error? Not connected?
davidr99 0:ab4e012489ef 100 _deviceType = (buf[1] << 8) | buf[2];
davidr99 0:ab4e012489ef 101 // Check PART to be either 0x4460, 0x4461, 0x4463, 0x4464
davidr99 0:ab4e012489ef 102 if (_deviceType != 0x4460 &&
davidr99 0:ab4e012489ef 103 _deviceType != 0x4461 &&
davidr99 0:ab4e012489ef 104 _deviceType != 0x4463 &&
davidr99 0:ab4e012489ef 105 _deviceType != 0x4464)
davidr99 0:ab4e012489ef 106 return false; // Unknown radio type, or not connected
davidr99 0:ab4e012489ef 107
davidr99 0:ab4e012489ef 108 #if (RH_PLATFORM != RH_PLATFORM_MBED)
davidr99 0:ab4e012489ef 109 // Add by Adrien van den Bossche <vandenbo@univ-tlse2.fr> for Teensy
davidr99 0:ab4e012489ef 110 // ARM M4 requires the below. else pin interrupt doesn't work properly.
davidr99 0:ab4e012489ef 111 // On all other platforms, its innocuous, belt and braces
davidr99 0:ab4e012489ef 112 pinMode(_interruptPin, INPUT);
davidr99 0:ab4e012489ef 113 #endif
davidr99 0:ab4e012489ef 114
davidr99 0:ab4e012489ef 115 // Set up interrupt handler
davidr99 0:ab4e012489ef 116 // Since there are a limited number of interrupt glue functions isr*() available,
davidr99 0:ab4e012489ef 117 // we can only support a limited number of devices simultaneously
davidr99 0:ab4e012489ef 118 // ON some devices, notably most Arduinos, the interrupt pin passed in is actuallt the
davidr99 0:ab4e012489ef 119 // interrupt number. You have to figure out the interruptnumber-to-interruptpin mapping
davidr99 0:ab4e012489ef 120 // yourself based on knwledge of what Arduino board you are running on.
davidr99 0:ab4e012489ef 121 if (_myInterruptIndex == 0xff)
davidr99 0:ab4e012489ef 122 {
davidr99 0:ab4e012489ef 123 // First run, no interrupt allocated yet
davidr99 0:ab4e012489ef 124 if (_interruptCount <= RH_RF24_NUM_INTERRUPTS)
davidr99 0:ab4e012489ef 125 _myInterruptIndex = _interruptCount++;
davidr99 0:ab4e012489ef 126 else
davidr99 0:ab4e012489ef 127 return false; // Too many devices, not enough interrupt vectors
davidr99 0:ab4e012489ef 128 }
davidr99 0:ab4e012489ef 129 _deviceForInterrupt[_myInterruptIndex] = this;
davidr99 0:ab4e012489ef 130
davidr99 0:ab4e012489ef 131 #if (RH_PLATFORM == RH_PLATFORM_MBED)
davidr99 0:ab4e012489ef 132 if (_myInterruptIndex == 0)
davidr99 0:ab4e012489ef 133 _interruptPin.fall(&isr0);
davidr99 0:ab4e012489ef 134 else if (_myInterruptIndex == 1)
davidr99 0:ab4e012489ef 135 _interruptPin.fall(&isr1);
davidr99 0:ab4e012489ef 136 else if (_myInterruptIndex == 2)
davidr99 0:ab4e012489ef 137 _interruptPin.fall(&isr2);
davidr99 0:ab4e012489ef 138 else
davidr99 0:ab4e012489ef 139 return false; // Too many devices, not enough interrupt vectors
davidr99 0:ab4e012489ef 140 #else
davidr99 0:ab4e012489ef 141 if (_myInterruptIndex == 0)
davidr99 0:ab4e012489ef 142 attachInterrupt(interruptNumber, isr0, FALLING);
davidr99 0:ab4e012489ef 143 else if (_myInterruptIndex == 1)
davidr99 0:ab4e012489ef 144 attachInterrupt(interruptNumber, isr1, FALLING);
davidr99 0:ab4e012489ef 145 else if (_myInterruptIndex == 2)
davidr99 0:ab4e012489ef 146 attachInterrupt(interruptNumber, isr2, FALLING);
davidr99 0:ab4e012489ef 147 else
davidr99 0:ab4e012489ef 148 return false; // Too many devices, not enough interrupt vectors
davidr99 0:ab4e012489ef 149 #endif
davidr99 0:ab4e012489ef 150 // Ensure we get the interrupts we need, irrespective of whats in the radio_config
davidr99 0:ab4e012489ef 151 uint8_t int_ctl[] = {RH_RF24_MODEM_INT_STATUS_EN | RH_RF24_PH_INT_STATUS_EN, 0xff, 0xff, 0x00 };
davidr99 0:ab4e012489ef 152 set_properties(RH_RF24_PROPERTY_INT_CTL_ENABLE, int_ctl, sizeof(int_ctl));
davidr99 0:ab4e012489ef 153
davidr99 0:ab4e012489ef 154 // RSSI Latching should be configured in MODEM_RSSI_CONTROL in radio_config
davidr99 0:ab4e012489ef 155
davidr99 0:ab4e012489ef 156 // PKT_TX_THRESHOLD and PKT_RX_THRESHOLD should be set to about 0x30 in radio_config
davidr99 0:ab4e012489ef 157
davidr99 0:ab4e012489ef 158 // Configure important RH_RF24 registers
davidr99 0:ab4e012489ef 159 // Here we set up the standard packet format for use by the RH_RF24 library:
davidr99 0:ab4e012489ef 160 // We will use FIFO Mode, with automatic packet generation
davidr99 0:ab4e012489ef 161 // We have 2 fields:
davidr99 0:ab4e012489ef 162 // Field 1 contains only the (variable) length of field 2, with CRC
davidr99 0:ab4e012489ef 163 // Field 2 contains the variable length payload and the CRC
davidr99 0:ab4e012489ef 164 // Hmmm, having no CRC on field 1 and CRC on field 2 causes CRC errors when resetting after an odd
davidr99 0:ab4e012489ef 165 // number of packets! Anyway its prob a good thing at the cost of some airtime.
davidr99 0:ab4e012489ef 166 // Hmmm, enabling WHITEN stops it working!
davidr99 0:ab4e012489ef 167 uint8_t pkt_config1[] = { 0x00 };
davidr99 0:ab4e012489ef 168 set_properties(RH_RF24_PROPERTY_PKT_CONFIG1, pkt_config1, sizeof(pkt_config1));
davidr99 0:ab4e012489ef 169
davidr99 0:ab4e012489ef 170 uint8_t pkt_len[] = { 0x02, 0x01, 0x00 };
davidr99 0:ab4e012489ef 171 set_properties(RH_RF24_PROPERTY_PKT_LEN, pkt_len, sizeof(pkt_len));
davidr99 0:ab4e012489ef 172
davidr99 0:ab4e012489ef 173 uint8_t pkt_field1[] = { 0x00, 0x01, 0x00, RH_RF24_FIELD_CONFIG_CRC_START | RH_RF24_FIELD_CONFIG_SEND_CRC | RH_RF24_FIELD_CONFIG_CHECK_CRC | RH_RF24_FIELD_CONFIG_CRC_ENABLE };
davidr99 0:ab4e012489ef 174 set_properties(RH_RF24_PROPERTY_PKT_FIELD_1_LENGTH_12_8, pkt_field1, sizeof(pkt_field1));
davidr99 0:ab4e012489ef 175
davidr99 0:ab4e012489ef 176 uint8_t pkt_field2[] = { 0x00, sizeof(_buf), 0x00, RH_RF24_FIELD_CONFIG_CRC_START | RH_RF24_FIELD_CONFIG_SEND_CRC | RH_RF24_FIELD_CONFIG_CHECK_CRC | RH_RF24_FIELD_CONFIG_CRC_ENABLE };
davidr99 0:ab4e012489ef 177 set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_12_8, pkt_field2, sizeof(pkt_field2));
davidr99 0:ab4e012489ef 178
davidr99 0:ab4e012489ef 179 // Clear all other fields so they are never used, irrespective of the radio_config
davidr99 0:ab4e012489ef 180 uint8_t pkt_fieldn[] = { 0x00, 0x00, 0x00, 0x00 };
davidr99 0:ab4e012489ef 181 set_properties(RH_RF24_PROPERTY_PKT_FIELD_3_LENGTH_12_8, pkt_fieldn, sizeof(pkt_fieldn));
davidr99 0:ab4e012489ef 182 set_properties(RH_RF24_PROPERTY_PKT_FIELD_4_LENGTH_12_8, pkt_fieldn, sizeof(pkt_fieldn));
davidr99 0:ab4e012489ef 183 set_properties(RH_RF24_PROPERTY_PKT_FIELD_5_LENGTH_12_8, pkt_fieldn, sizeof(pkt_fieldn));
davidr99 0:ab4e012489ef 184
davidr99 0:ab4e012489ef 185 // The following can be changed later by the user if necessary.
davidr99 0:ab4e012489ef 186 // Set up default configuration
davidr99 0:ab4e012489ef 187 setCRCPolynomial(CRC_16_IBM);
davidr99 0:ab4e012489ef 188 uint8_t syncwords[] = { 0x2d, 0xd4 };
davidr99 0:ab4e012489ef 189 setSyncWords(syncwords, sizeof(syncwords)); // Same as RF22's
davidr99 0:ab4e012489ef 190 // Reasonably fast and reliable default speed and modulation
davidr99 0:ab4e012489ef 191 setModemConfig(GFSK_Rb5Fd10);
davidr99 0:ab4e012489ef 192 // 3 would be sufficient, but this is the same as RF22's
davidr99 0:ab4e012489ef 193 // actualy, 4 seems to work much better for some modulations
davidr99 0:ab4e012489ef 194 setPreambleLength(4);
davidr99 0:ab4e012489ef 195 // An innocuous ISM frequency, same as RF22's
davidr99 0:ab4e012489ef 196 setFrequency(434.0);
davidr99 0:ab4e012489ef 197 // About 2.4dBm on RFM24:
davidr99 0:ab4e012489ef 198 setTxPower(0x10);
davidr99 0:ab4e012489ef 199
davidr99 0:ab4e012489ef 200 return true;
davidr99 0:ab4e012489ef 201 }
davidr99 0:ab4e012489ef 202
davidr99 0:ab4e012489ef 203 // C++ level interrupt handler for this instance
davidr99 0:ab4e012489ef 204 void RH_RF24::handleInterrupt()
davidr99 0:ab4e012489ef 205 {
davidr99 0:ab4e012489ef 206 uint8_t status[8];
davidr99 0:ab4e012489ef 207 command(RH_RF24_CMD_GET_INT_STATUS, NULL, 0, status, sizeof(status));
davidr99 0:ab4e012489ef 208
davidr99 0:ab4e012489ef 209 // Decode and handle the interrupt bits we are interested in
davidr99 0:ab4e012489ef 210 // if (status[0] & RH_RF24_INT_STATUS_CHIP_INT_STATUS)
davidr99 0:ab4e012489ef 211 if (status[0] & RH_RF24_INT_STATUS_MODEM_INT_STATUS)
davidr99 0:ab4e012489ef 212 {
davidr99 0:ab4e012489ef 213 // if (status[4] & RH_RF24_INT_STATUS_INVALID_PREAMBLE)
davidr99 0:ab4e012489ef 214 if (status[4] & RH_RF24_INT_STATUS_INVALID_SYNC)
davidr99 0:ab4e012489ef 215 {
davidr99 0:ab4e012489ef 216 // After INVALID_SYNC, sometimes the radio gets into a silly state and subsequently reports it for every packet
davidr99 0:ab4e012489ef 217 // Need to reset the radio and clear the RX FIFO, cause sometimes theres junk there too
davidr99 0:ab4e012489ef 218 _mode = RHModeIdle;
davidr99 0:ab4e012489ef 219 clearRxFifo();
davidr99 0:ab4e012489ef 220 clearBuffer();
davidr99 0:ab4e012489ef 221 }
davidr99 0:ab4e012489ef 222 }
davidr99 0:ab4e012489ef 223 if (status[0] & RH_RF24_INT_STATUS_PH_INT_STATUS)
davidr99 0:ab4e012489ef 224 {
davidr99 0:ab4e012489ef 225 if (status[2] & RH_RF24_INT_STATUS_CRC_ERROR)
davidr99 0:ab4e012489ef 226 {
davidr99 0:ab4e012489ef 227 // CRC Error
davidr99 0:ab4e012489ef 228 // Radio automatically went to _idleMode
davidr99 0:ab4e012489ef 229 _mode = RHModeIdle;
davidr99 0:ab4e012489ef 230 _rxBad++;
davidr99 0:ab4e012489ef 231
davidr99 0:ab4e012489ef 232 clearRxFifo();
davidr99 0:ab4e012489ef 233 clearBuffer();
davidr99 0:ab4e012489ef 234 }
davidr99 0:ab4e012489ef 235 if (status[2] & RH_RF24_INT_STATUS_PACKET_SENT)
davidr99 0:ab4e012489ef 236 {
davidr99 0:ab4e012489ef 237 _txGood++;
davidr99 0:ab4e012489ef 238 // Transmission does not automatically clear the tx buffer.
davidr99 0:ab4e012489ef 239 // Could retransmit if we wanted
davidr99 0:ab4e012489ef 240 // RH_RF24 configured to transition automatically to Idle after packet sent
davidr99 0:ab4e012489ef 241 _mode = RHModeIdle;
davidr99 0:ab4e012489ef 242 clearBuffer();
davidr99 0:ab4e012489ef 243 }
davidr99 0:ab4e012489ef 244 if (status[2] & RH_RF24_INT_STATUS_PACKET_RX)
davidr99 0:ab4e012489ef 245 {
davidr99 0:ab4e012489ef 246 // A complete message has been received with good CRC
davidr99 0:ab4e012489ef 247 // Get the RSSI, configured to latch at sync detect in radio_config
davidr99 0:ab4e012489ef 248 uint8_t modem_status[6];
davidr99 0:ab4e012489ef 249 command(RH_RF24_CMD_GET_MODEM_STATUS, NULL, 0, modem_status, sizeof(modem_status));
davidr99 0:ab4e012489ef 250 _lastRssi = modem_status[3];
davidr99 0:ab4e012489ef 251 _lastPreambleTime = millis();
davidr99 0:ab4e012489ef 252
davidr99 0:ab4e012489ef 253 // Save it in our buffer
davidr99 0:ab4e012489ef 254 readNextFragment();
davidr99 0:ab4e012489ef 255 // And see if we have a valid message
davidr99 0:ab4e012489ef 256 validateRxBuf();
davidr99 0:ab4e012489ef 257 // Radio will have transitioned automatically to the _idleMode
davidr99 0:ab4e012489ef 258 _mode = RHModeIdle;
davidr99 0:ab4e012489ef 259 }
davidr99 0:ab4e012489ef 260 if (status[2] & RH_RF24_INT_STATUS_TX_FIFO_ALMOST_EMPTY)
davidr99 0:ab4e012489ef 261 {
davidr99 0:ab4e012489ef 262 // TX FIFO almost empty, maybe send another chunk, if there is one
davidr99 0:ab4e012489ef 263 sendNextFragment();
davidr99 0:ab4e012489ef 264 }
davidr99 0:ab4e012489ef 265 if (status[2] & RH_RF24_INT_STATUS_RX_FIFO_ALMOST_FULL)
davidr99 0:ab4e012489ef 266 {
davidr99 0:ab4e012489ef 267 // Some more data to read, get it
davidr99 0:ab4e012489ef 268 readNextFragment();
davidr99 0:ab4e012489ef 269 }
davidr99 0:ab4e012489ef 270 }
davidr99 0:ab4e012489ef 271 }
davidr99 0:ab4e012489ef 272
davidr99 0:ab4e012489ef 273 // Check whether the latest received message is complete and uncorrupted
davidr99 0:ab4e012489ef 274 void RH_RF24::validateRxBuf()
davidr99 0:ab4e012489ef 275 {
davidr99 0:ab4e012489ef 276 // Validate headers etc
davidr99 0:ab4e012489ef 277 if (_bufLen >= RH_RF24_HEADER_LEN)
davidr99 0:ab4e012489ef 278 {
davidr99 0:ab4e012489ef 279 _rxHeaderTo = _buf[0];
davidr99 0:ab4e012489ef 280 _rxHeaderFrom = _buf[1];
davidr99 0:ab4e012489ef 281 _rxHeaderId = _buf[2];
davidr99 0:ab4e012489ef 282 _rxHeaderFlags = _buf[3];
davidr99 0:ab4e012489ef 283 if (_promiscuous ||
davidr99 0:ab4e012489ef 284 _rxHeaderTo == _thisAddress ||
davidr99 0:ab4e012489ef 285 _rxHeaderTo == RH_BROADCAST_ADDRESS)
davidr99 0:ab4e012489ef 286 {
davidr99 0:ab4e012489ef 287 // Its for us
davidr99 0:ab4e012489ef 288 _rxGood++;
davidr99 0:ab4e012489ef 289 _rxBufValid = true;
davidr99 0:ab4e012489ef 290 }
davidr99 0:ab4e012489ef 291 }
davidr99 0:ab4e012489ef 292 }
davidr99 0:ab4e012489ef 293
davidr99 0:ab4e012489ef 294 bool RH_RF24::clearRxFifo()
davidr99 0:ab4e012489ef 295 {
davidr99 0:ab4e012489ef 296 uint8_t fifo_clear[] = { 0x02 };
davidr99 0:ab4e012489ef 297 return command(RH_RF24_CMD_FIFO_INFO, fifo_clear, sizeof(fifo_clear));
davidr99 0:ab4e012489ef 298 }
davidr99 0:ab4e012489ef 299
davidr99 0:ab4e012489ef 300 void RH_RF24::clearBuffer()
davidr99 0:ab4e012489ef 301 {
davidr99 0:ab4e012489ef 302 _bufLen = 0;
davidr99 0:ab4e012489ef 303 _txBufSentIndex = 0;
davidr99 0:ab4e012489ef 304 _rxBufValid = false;
davidr99 0:ab4e012489ef 305 }
davidr99 0:ab4e012489ef 306
davidr99 0:ab4e012489ef 307 // These are low level functions that call the interrupt handler for the correct
davidr99 0:ab4e012489ef 308 // instance of RH_RF24.
davidr99 0:ab4e012489ef 309 // 3 interrupts allows us to have 3 different devices
davidr99 0:ab4e012489ef 310 void RH_RF24::isr0()
davidr99 0:ab4e012489ef 311 {
davidr99 0:ab4e012489ef 312 if (_deviceForInterrupt[0])
davidr99 0:ab4e012489ef 313 _deviceForInterrupt[0]->handleInterrupt();
davidr99 0:ab4e012489ef 314 }
davidr99 0:ab4e012489ef 315 void RH_RF24::isr1()
davidr99 0:ab4e012489ef 316 {
davidr99 0:ab4e012489ef 317 if (_deviceForInterrupt[1])
davidr99 0:ab4e012489ef 318 _deviceForInterrupt[1]->handleInterrupt();
davidr99 0:ab4e012489ef 319 }
davidr99 0:ab4e012489ef 320 void RH_RF24::isr2()
davidr99 0:ab4e012489ef 321 {
davidr99 0:ab4e012489ef 322 if (_deviceForInterrupt[2])
davidr99 0:ab4e012489ef 323 _deviceForInterrupt[2]->handleInterrupt();
davidr99 0:ab4e012489ef 324 }
davidr99 0:ab4e012489ef 325
davidr99 0:ab4e012489ef 326 bool RH_RF24::available()
davidr99 0:ab4e012489ef 327 {
davidr99 0:ab4e012489ef 328 if (_mode == RHModeTx)
davidr99 0:ab4e012489ef 329 return false;
davidr99 0:ab4e012489ef 330 if (!_rxBufValid)
davidr99 0:ab4e012489ef 331 setModeRx(); // Make sure we are receiving
davidr99 0:ab4e012489ef 332 return _rxBufValid;
davidr99 0:ab4e012489ef 333 }
davidr99 0:ab4e012489ef 334
davidr99 0:ab4e012489ef 335 bool RH_RF24::recv(uint8_t* buf, uint8_t* len)
davidr99 0:ab4e012489ef 336 {
davidr99 0:ab4e012489ef 337 if (!available())
davidr99 0:ab4e012489ef 338 return false;
davidr99 0:ab4e012489ef 339 // CAUTION: first 4 octets of _buf contain the headers
davidr99 0:ab4e012489ef 340 if (buf && len && (_bufLen >= RH_RF24_HEADER_LEN))
davidr99 0:ab4e012489ef 341 {
davidr99 0:ab4e012489ef 342 ATOMIC_BLOCK_START;
davidr99 0:ab4e012489ef 343 if (*len > _bufLen - RH_RF24_HEADER_LEN)
davidr99 0:ab4e012489ef 344 *len = _bufLen - RH_RF24_HEADER_LEN;
davidr99 0:ab4e012489ef 345 memcpy(buf, _buf + RH_RF24_HEADER_LEN, *len);
davidr99 0:ab4e012489ef 346 ATOMIC_BLOCK_END;
davidr99 0:ab4e012489ef 347 }
davidr99 0:ab4e012489ef 348 clearBuffer(); // Got the most recent message
davidr99 0:ab4e012489ef 349 return true;
davidr99 0:ab4e012489ef 350 }
davidr99 0:ab4e012489ef 351
davidr99 0:ab4e012489ef 352 bool RH_RF24::send(const uint8_t* data, uint8_t len)
davidr99 0:ab4e012489ef 353 {
davidr99 0:ab4e012489ef 354 if (len > RH_RF24_MAX_MESSAGE_LEN)
davidr99 0:ab4e012489ef 355 return false;
davidr99 0:ab4e012489ef 356
davidr99 0:ab4e012489ef 357 waitPacketSent(); // Make sure we dont interrupt an outgoing message
davidr99 0:ab4e012489ef 358 setModeIdle(); // Prevent RX while filling the fifo
davidr99 0:ab4e012489ef 359
davidr99 0:ab4e012489ef 360 // Put the payload in the FIFO
davidr99 0:ab4e012489ef 361 // First the length in fixed length field 1. This wont appear in the receiver fifo since
davidr99 0:ab4e012489ef 362 // we have turned off IN_FIFO in PKT_LEN
davidr99 0:ab4e012489ef 363 _buf[0] = len + RH_RF24_HEADER_LEN;
davidr99 0:ab4e012489ef 364 // Now the rest of the payload in variable length field 2
davidr99 0:ab4e012489ef 365 // First the headers
davidr99 0:ab4e012489ef 366 _buf[1] = _txHeaderTo;
davidr99 0:ab4e012489ef 367 _buf[2] = _txHeaderFrom;
davidr99 0:ab4e012489ef 368 _buf[3] = _txHeaderId;
davidr99 0:ab4e012489ef 369 _buf[4] = _txHeaderFlags;
davidr99 0:ab4e012489ef 370 // Then the message
davidr99 0:ab4e012489ef 371 memcpy(_buf + 1 + RH_RF24_HEADER_LEN, data, len);
davidr99 0:ab4e012489ef 372 _bufLen = len + 1 + RH_RF24_HEADER_LEN;
davidr99 0:ab4e012489ef 373 _txBufSentIndex = 0;
davidr99 0:ab4e012489ef 374
davidr99 0:ab4e012489ef 375 // Set the field 2 length to the variable payload length
davidr99 0:ab4e012489ef 376 uint8_t l[] = { len + RH_RF24_HEADER_LEN};
davidr99 0:ab4e012489ef 377 set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_7_0, l, sizeof(l));
davidr99 0:ab4e012489ef 378
davidr99 0:ab4e012489ef 379 sendNextFragment();
davidr99 0:ab4e012489ef 380 setModeTx();
davidr99 0:ab4e012489ef 381 return true;
davidr99 0:ab4e012489ef 382 }
davidr99 0:ab4e012489ef 383
davidr99 0:ab4e012489ef 384 // This is different to command() since we must not wait for CTS
davidr99 0:ab4e012489ef 385 bool RH_RF24::writeTxFifo(uint8_t *data, uint8_t len)
davidr99 0:ab4e012489ef 386 {
davidr99 0:ab4e012489ef 387 ATOMIC_BLOCK_START;
davidr99 0:ab4e012489ef 388 // First send the command
davidr99 0:ab4e012489ef 389 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 390 _spi.transfer(RH_RF24_CMD_TX_FIFO_WRITE);
davidr99 0:ab4e012489ef 391 // Now write any write data
davidr99 0:ab4e012489ef 392 while (len--)
davidr99 0:ab4e012489ef 393 _spi.transfer(*data++);
davidr99 0:ab4e012489ef 394 digitalWrite(_slaveSelectPin, HIGH);
davidr99 0:ab4e012489ef 395 ATOMIC_BLOCK_END;
davidr99 0:ab4e012489ef 396 return true;
davidr99 0:ab4e012489ef 397 }
davidr99 0:ab4e012489ef 398
davidr99 0:ab4e012489ef 399 void RH_RF24::sendNextFragment()
davidr99 0:ab4e012489ef 400 {
davidr99 0:ab4e012489ef 401 if (_txBufSentIndex < _bufLen)
davidr99 0:ab4e012489ef 402 {
davidr99 0:ab4e012489ef 403 // Some left to send?
davidr99 0:ab4e012489ef 404 uint8_t len = _bufLen - _txBufSentIndex;
davidr99 0:ab4e012489ef 405 // But dont send too much, see how much room is left
davidr99 0:ab4e012489ef 406 uint8_t fifo_info[2];
davidr99 0:ab4e012489ef 407 command(RH_RF24_CMD_FIFO_INFO, NULL, 0, fifo_info, sizeof(fifo_info));
davidr99 0:ab4e012489ef 408 // fifo_info[1] is space left in TX FIFO
davidr99 0:ab4e012489ef 409 if (len > fifo_info[1])
davidr99 0:ab4e012489ef 410 len = fifo_info[1];
davidr99 0:ab4e012489ef 411
davidr99 0:ab4e012489ef 412 writeTxFifo(_buf + _txBufSentIndex, len);
davidr99 0:ab4e012489ef 413 _txBufSentIndex += len;
davidr99 0:ab4e012489ef 414 }
davidr99 0:ab4e012489ef 415 }
davidr99 0:ab4e012489ef 416
davidr99 0:ab4e012489ef 417 void RH_RF24::readNextFragment()
davidr99 0:ab4e012489ef 418 {
davidr99 0:ab4e012489ef 419 // Get the packet length from the RX FIFO length
davidr99 0:ab4e012489ef 420 uint8_t fifo_info[1];
davidr99 0:ab4e012489ef 421 command(RH_RF24_CMD_FIFO_INFO, NULL, 0, fifo_info, sizeof(fifo_info));
davidr99 0:ab4e012489ef 422 uint8_t fifo_len = fifo_info[0];
davidr99 0:ab4e012489ef 423
davidr99 0:ab4e012489ef 424 // Check for overflow
davidr99 0:ab4e012489ef 425 if ((_bufLen + fifo_len) > sizeof(_buf))
davidr99 0:ab4e012489ef 426 {
davidr99 0:ab4e012489ef 427 // Overflow pending
davidr99 0:ab4e012489ef 428 _rxBad++;
davidr99 0:ab4e012489ef 429 setModeIdle();
davidr99 0:ab4e012489ef 430 clearRxFifo();
davidr99 0:ab4e012489ef 431 clearBuffer();
davidr99 0:ab4e012489ef 432 return;
davidr99 0:ab4e012489ef 433 }
davidr99 0:ab4e012489ef 434 // So we have room
davidr99 0:ab4e012489ef 435 // Now read the fifo_len bytes from the RX FIFO
davidr99 0:ab4e012489ef 436 // This is different to command() since we dont wait for CTS
davidr99 0:ab4e012489ef 437 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 438 _spi.transfer(RH_RF24_CMD_RX_FIFO_READ);
davidr99 0:ab4e012489ef 439 uint8_t* p = _buf + _bufLen;
davidr99 0:ab4e012489ef 440 uint8_t l = fifo_len;
davidr99 0:ab4e012489ef 441 while (l--)
davidr99 0:ab4e012489ef 442 *p++ = _spi.transfer(0);
davidr99 0:ab4e012489ef 443 digitalWrite(_slaveSelectPin, HIGH);
davidr99 0:ab4e012489ef 444 _bufLen += fifo_len;
davidr99 0:ab4e012489ef 445 }
davidr99 0:ab4e012489ef 446
davidr99 0:ab4e012489ef 447 uint8_t RH_RF24::maxMessageLength()
davidr99 0:ab4e012489ef 448 {
davidr99 0:ab4e012489ef 449 return RH_RF24_MAX_MESSAGE_LEN;
davidr99 0:ab4e012489ef 450 }
davidr99 0:ab4e012489ef 451
davidr99 0:ab4e012489ef 452 // Sets registers from a canned modem configuration structure
davidr99 0:ab4e012489ef 453 void RH_RF24::setModemRegisters(const ModemConfig* config)
davidr99 0:ab4e012489ef 454 {
davidr99 0:ab4e012489ef 455 // This list also generated with convert.pl
davidr99 0:ab4e012489ef 456 set_properties(0x2000, &config->prop_2000, 1);
davidr99 0:ab4e012489ef 457 set_properties(0x2003, &config->prop_2003, 1);
davidr99 0:ab4e012489ef 458 set_properties(0x2004, &config->prop_2004, 1);
davidr99 0:ab4e012489ef 459 set_properties(0x2005, &config->prop_2005, 1);
davidr99 0:ab4e012489ef 460 set_properties(0x2006, &config->prop_2006, 1);
davidr99 0:ab4e012489ef 461 set_properties(0x200b, &config->prop_200b, 1);
davidr99 0:ab4e012489ef 462 set_properties(0x200c, &config->prop_200c, 1);
davidr99 0:ab4e012489ef 463 set_properties(0x2018, &config->prop_2018, 1);
davidr99 0:ab4e012489ef 464 set_properties(0x201e, &config->prop_201e, 1);
davidr99 0:ab4e012489ef 465 set_properties(0x201f, &config->prop_201f, 1);
davidr99 0:ab4e012489ef 466 set_properties(0x2022, &config->prop_2022, 1);
davidr99 0:ab4e012489ef 467 set_properties(0x2023, &config->prop_2023, 1);
davidr99 0:ab4e012489ef 468 set_properties(0x2024, &config->prop_2024, 1);
davidr99 0:ab4e012489ef 469 set_properties(0x2025, &config->prop_2025, 1);
davidr99 0:ab4e012489ef 470 set_properties(0x2026, &config->prop_2026, 1);
davidr99 0:ab4e012489ef 471 set_properties(0x2027, &config->prop_2027, 1);
davidr99 0:ab4e012489ef 472 set_properties(0x2028, &config->prop_2028, 1);
davidr99 0:ab4e012489ef 473 set_properties(0x2029, &config->prop_2029, 1);
davidr99 0:ab4e012489ef 474 set_properties(0x202d, &config->prop_202d, 1);
davidr99 0:ab4e012489ef 475 set_properties(0x202e, &config->prop_202e, 1);
davidr99 0:ab4e012489ef 476 set_properties(0x202f, &config->prop_202f, 1);
davidr99 0:ab4e012489ef 477 set_properties(0x2030, &config->prop_2030, 1);
davidr99 0:ab4e012489ef 478 set_properties(0x2031, &config->prop_2031, 1);
davidr99 0:ab4e012489ef 479 set_properties(0x2035, &config->prop_2035, 1);
davidr99 0:ab4e012489ef 480 set_properties(0x2038, &config->prop_2038, 1);
davidr99 0:ab4e012489ef 481 set_properties(0x2039, &config->prop_2039, 1);
davidr99 0:ab4e012489ef 482 set_properties(0x203a, &config->prop_203a, 1);
davidr99 0:ab4e012489ef 483 set_properties(0x203b, &config->prop_203b, 1);
davidr99 0:ab4e012489ef 484 set_properties(0x203c, &config->prop_203c, 1);
davidr99 0:ab4e012489ef 485 set_properties(0x203d, &config->prop_203d, 1);
davidr99 0:ab4e012489ef 486 set_properties(0x203e, &config->prop_203e, 1);
davidr99 0:ab4e012489ef 487 set_properties(0x203f, &config->prop_203f, 1);
davidr99 0:ab4e012489ef 488 set_properties(0x2040, &config->prop_2040, 1);
davidr99 0:ab4e012489ef 489 set_properties(0x2043, &config->prop_2043, 1);
davidr99 0:ab4e012489ef 490 set_properties(0x2045, &config->prop_2045, 1);
davidr99 0:ab4e012489ef 491 set_properties(0x2046, &config->prop_2046, 1);
davidr99 0:ab4e012489ef 492 set_properties(0x2047, &config->prop_2047, 1);
davidr99 0:ab4e012489ef 493 set_properties(0x204e, &config->prop_204e, 1);
davidr99 0:ab4e012489ef 494 set_properties(0x2100, &config->prop_2100, 1);
davidr99 0:ab4e012489ef 495 set_properties(0x2101, &config->prop_2101, 1);
davidr99 0:ab4e012489ef 496 set_properties(0x2102, &config->prop_2102, 1);
davidr99 0:ab4e012489ef 497 set_properties(0x2103, &config->prop_2103, 1);
davidr99 0:ab4e012489ef 498 set_properties(0x2104, &config->prop_2104, 1);
davidr99 0:ab4e012489ef 499 set_properties(0x2105, &config->prop_2105, 1);
davidr99 0:ab4e012489ef 500 set_properties(0x2106, &config->prop_2106, 1);
davidr99 0:ab4e012489ef 501 set_properties(0x2107, &config->prop_2107, 1);
davidr99 0:ab4e012489ef 502 set_properties(0x2108, &config->prop_2108, 1);
davidr99 0:ab4e012489ef 503 set_properties(0x2109, &config->prop_2109, 1);
davidr99 0:ab4e012489ef 504 set_properties(0x210a, &config->prop_210a, 1);
davidr99 0:ab4e012489ef 505 set_properties(0x210b, &config->prop_210b, 1);
davidr99 0:ab4e012489ef 506 set_properties(0x210c, &config->prop_210c, 1);
davidr99 0:ab4e012489ef 507 set_properties(0x210d, &config->prop_210d, 1);
davidr99 0:ab4e012489ef 508 set_properties(0x210e, &config->prop_210e, 1);
davidr99 0:ab4e012489ef 509 set_properties(0x210f, &config->prop_210f, 1);
davidr99 0:ab4e012489ef 510 set_properties(0x2110, &config->prop_2110, 1);
davidr99 0:ab4e012489ef 511 set_properties(0x2111, &config->prop_2111, 1);
davidr99 0:ab4e012489ef 512 set_properties(0x2112, &config->prop_2112, 1);
davidr99 0:ab4e012489ef 513 set_properties(0x2113, &config->prop_2113, 1);
davidr99 0:ab4e012489ef 514 set_properties(0x2114, &config->prop_2114, 1);
davidr99 0:ab4e012489ef 515 set_properties(0x2115, &config->prop_2115, 1);
davidr99 0:ab4e012489ef 516 set_properties(0x2116, &config->prop_2116, 1);
davidr99 0:ab4e012489ef 517 set_properties(0x2117, &config->prop_2117, 1);
davidr99 0:ab4e012489ef 518 set_properties(0x2118, &config->prop_2118, 1);
davidr99 0:ab4e012489ef 519 set_properties(0x2119, &config->prop_2119, 1);
davidr99 0:ab4e012489ef 520 set_properties(0x211a, &config->prop_211a, 1);
davidr99 0:ab4e012489ef 521 set_properties(0x211b, &config->prop_211b, 1);
davidr99 0:ab4e012489ef 522 set_properties(0x211c, &config->prop_211c, 1);
davidr99 0:ab4e012489ef 523 set_properties(0x211d, &config->prop_211d, 1);
davidr99 0:ab4e012489ef 524 set_properties(0x211e, &config->prop_211e, 1);
davidr99 0:ab4e012489ef 525 set_properties(0x211f, &config->prop_211f, 1);
davidr99 0:ab4e012489ef 526 set_properties(0x2120, &config->prop_2120, 1);
davidr99 0:ab4e012489ef 527 set_properties(0x2121, &config->prop_2121, 1);
davidr99 0:ab4e012489ef 528 set_properties(0x2122, &config->prop_2122, 1);
davidr99 0:ab4e012489ef 529 set_properties(0x2123, &config->prop_2123, 1);
davidr99 0:ab4e012489ef 530 set_properties(0x2203, &config->prop_2203, 1);
davidr99 0:ab4e012489ef 531 set_properties(0x2300, &config->prop_2300, 1);
davidr99 0:ab4e012489ef 532 set_properties(0x2301, &config->prop_2301, 1);
davidr99 0:ab4e012489ef 533 set_properties(0x2303, &config->prop_2303, 1);
davidr99 0:ab4e012489ef 534 set_properties(0x2304, &config->prop_2304, 1);
davidr99 0:ab4e012489ef 535 set_properties(0x2305, &config->prop_2305, 1);
davidr99 0:ab4e012489ef 536 }
davidr99 0:ab4e012489ef 537
davidr99 0:ab4e012489ef 538 // Set one of the canned Modem configs
davidr99 0:ab4e012489ef 539 // Returns true if its a valid choice
davidr99 0:ab4e012489ef 540 bool RH_RF24::setModemConfig(ModemConfigChoice index)
davidr99 0:ab4e012489ef 541 {
davidr99 0:ab4e012489ef 542 if (index > (signed int)(sizeof(MODEM_CONFIG_TABLE) / sizeof(ModemConfig)))
davidr99 0:ab4e012489ef 543 return false;
davidr99 0:ab4e012489ef 544
davidr99 0:ab4e012489ef 545 ModemConfig cfg;
davidr99 0:ab4e012489ef 546 memcpy_P(&cfg, &MODEM_CONFIG_TABLE[index], sizeof(RH_RF24::ModemConfig));
davidr99 0:ab4e012489ef 547 setModemRegisters(&cfg);
davidr99 0:ab4e012489ef 548
davidr99 0:ab4e012489ef 549 return true;
davidr99 0:ab4e012489ef 550 }
davidr99 0:ab4e012489ef 551
davidr99 0:ab4e012489ef 552 void RH_RF24::setPreambleLength(uint16_t bytes)
davidr99 0:ab4e012489ef 553 {
davidr99 0:ab4e012489ef 554 uint8_t config[] = { bytes, 0x14, 0x00, 0x00,
davidr99 0:ab4e012489ef 555 RH_RF24_PREAMBLE_FIRST_1 | RH_RF24_PREAMBLE_LENGTH_BYTES | RH_RF24_PREAMBLE_STANDARD_1010};
davidr99 0:ab4e012489ef 556 set_properties(RH_RF24_PROPERTY_PREAMBLE_TX_LENGTH, config, sizeof(config));
davidr99 0:ab4e012489ef 557 }
davidr99 0:ab4e012489ef 558
davidr99 0:ab4e012489ef 559 bool RH_RF24::setCRCPolynomial(CRCPolynomial polynomial)
davidr99 0:ab4e012489ef 560 {
davidr99 0:ab4e012489ef 561 if (polynomial >= CRC_NONE &&
davidr99 0:ab4e012489ef 562 polynomial <= CRC_Castagnoli)
davidr99 0:ab4e012489ef 563 {
davidr99 0:ab4e012489ef 564 // Caution this only has effect if CRCs are enabled
davidr99 0:ab4e012489ef 565 uint8_t config[] = { (polynomial & RH_RF24_CRC_MASK) | RH_RF24_CRC_SEED_ALL_1S };
davidr99 0:ab4e012489ef 566 return set_properties(RH_RF24_PROPERTY_PKT_CRC_CONFIG, config, sizeof(config));
davidr99 0:ab4e012489ef 567 }
davidr99 0:ab4e012489ef 568 else
davidr99 0:ab4e012489ef 569 return false;
davidr99 0:ab4e012489ef 570 }
davidr99 0:ab4e012489ef 571
davidr99 0:ab4e012489ef 572 void RH_RF24::setSyncWords(const uint8_t* syncWords, uint8_t len)
davidr99 0:ab4e012489ef 573 {
davidr99 0:ab4e012489ef 574 if (len > 4 || len < 1)
davidr99 0:ab4e012489ef 575 return;
davidr99 0:ab4e012489ef 576 uint8_t config[] = { len-1, 0, 0, 0, 0};
davidr99 0:ab4e012489ef 577 memcpy(config+1, syncWords, len);
davidr99 0:ab4e012489ef 578 set_properties(RH_RF24_PROPERTY_SYNC_CONFIG, config, sizeof(config));
davidr99 0:ab4e012489ef 579 }
davidr99 0:ab4e012489ef 580
davidr99 0:ab4e012489ef 581 bool RH_RF24::setFrequency(float centre, float afcPullInRange)
davidr99 0:ab4e012489ef 582 {
davidr99 0:ab4e012489ef 583 // See Si446x Data Sheet section 5.3.1
davidr99 0:ab4e012489ef 584 // Also the Si446x PLL Synthesizer / VCO_CNT Calculator Rev 0.4
davidr99 0:ab4e012489ef 585 uint8_t outdiv;
davidr99 0:ab4e012489ef 586 uint8_t band;
davidr99 0:ab4e012489ef 587 if (_deviceType == 0x4460 ||
davidr99 0:ab4e012489ef 588 _deviceType == 0x4461 ||
davidr99 0:ab4e012489ef 589 _deviceType == 0x4463)
davidr99 0:ab4e012489ef 590 {
davidr99 0:ab4e012489ef 591 // Non-continuous frequency bands
davidr99 0:ab4e012489ef 592 if (centre <= 1050.0 && centre >= 850.0)
davidr99 0:ab4e012489ef 593 outdiv = 4, band = 0;
davidr99 0:ab4e012489ef 594 else if (centre <= 525.0 && centre >= 425.0)
davidr99 0:ab4e012489ef 595 outdiv = 8, band = 2;
davidr99 0:ab4e012489ef 596 else if (centre <= 350.0 && centre >= 284.0)
davidr99 0:ab4e012489ef 597 outdiv = 12, band = 3;
davidr99 0:ab4e012489ef 598 else if (centre <= 175.0 && centre >= 142.0)
davidr99 0:ab4e012489ef 599 outdiv = 24, band = 5;
davidr99 0:ab4e012489ef 600 else
davidr99 0:ab4e012489ef 601 return false;
davidr99 0:ab4e012489ef 602 }
davidr99 0:ab4e012489ef 603 else
davidr99 0:ab4e012489ef 604 {
davidr99 0:ab4e012489ef 605 // 0x4464
davidr99 0:ab4e012489ef 606 // Continuous frequency bands
davidr99 0:ab4e012489ef 607 if (centre <= 960.0 && centre >= 675.0)
davidr99 0:ab4e012489ef 608 outdiv = 4, band = 1;
davidr99 0:ab4e012489ef 609 else if (centre < 675.0 && centre >= 450.0)
davidr99 0:ab4e012489ef 610 outdiv = 6, band = 2;
davidr99 0:ab4e012489ef 611 else if (centre < 450.0 && centre >= 338.0)
davidr99 0:ab4e012489ef 612 outdiv = 8, band = 3;
davidr99 0:ab4e012489ef 613 else if (centre < 338.0 && centre >= 225.0)
davidr99 0:ab4e012489ef 614 outdiv = 12, band = 4;
davidr99 0:ab4e012489ef 615 else if (centre < 225.0 && centre >= 169.0)
davidr99 0:ab4e012489ef 616 outdiv = 16, band = 4;
davidr99 0:ab4e012489ef 617 else if (centre < 169.0 && centre >= 119.0)
davidr99 0:ab4e012489ef 618 outdiv = 24, band = 5;
davidr99 0:ab4e012489ef 619 else
davidr99 0:ab4e012489ef 620 return false;
davidr99 0:ab4e012489ef 621 }
davidr99 0:ab4e012489ef 622
davidr99 0:ab4e012489ef 623 // Set the MODEM_CLKGEN_BAND (not documented)
davidr99 0:ab4e012489ef 624 uint8_t modem_clkgen[] = { band+8 };
davidr99 0:ab4e012489ef 625 if (!set_properties(RH_RF24_PROPERTY_MODEM_CLKGEN_BAND, modem_clkgen, sizeof(modem_clkgen)))
davidr99 0:ab4e012489ef 626 return false;
davidr99 0:ab4e012489ef 627
davidr99 0:ab4e012489ef 628 centre *= 1000000.0; // Convert to Hz
davidr99 0:ab4e012489ef 629
davidr99 0:ab4e012489ef 630 // Now generate the RF frequency properties
davidr99 0:ab4e012489ef 631 // Need the Xtal/XO freq from the radio_config file:
davidr99 0:ab4e012489ef 632 uint32_t xtal_frequency[1] = RADIO_CONFIGURATION_DATA_RADIO_XO_FREQ;
davidr99 0:ab4e012489ef 633 unsigned long f_pfd = 2 * xtal_frequency[0] / outdiv;
davidr99 0:ab4e012489ef 634 unsigned int n = ((unsigned int)(centre / f_pfd)) - 1;
davidr99 0:ab4e012489ef 635 float ratio = centre / (float)f_pfd;
davidr99 0:ab4e012489ef 636 float rest = ratio - (float)n;
davidr99 0:ab4e012489ef 637 unsigned long m = (unsigned long)(rest * 524288UL);
davidr99 0:ab4e012489ef 638 unsigned int m2 = m / 0x10000;
davidr99 0:ab4e012489ef 639 unsigned int m1 = (m - m2 * 0x10000) / 0x100;
davidr99 0:ab4e012489ef 640 unsigned int m0 = (m - m2 * 0x10000 - m1 * 0x100);
davidr99 0:ab4e012489ef 641
davidr99 0:ab4e012489ef 642 // PROP_FREQ_CONTROL_GROUP
davidr99 0:ab4e012489ef 643 uint8_t freq_control[] = { n, m2, m1, m0 };
davidr99 0:ab4e012489ef 644 return set_properties(RH_RF24_PROPERTY_FREQ_CONTROL_INTE, freq_control, sizeof(freq_control));
davidr99 0:ab4e012489ef 645 }
davidr99 0:ab4e012489ef 646
davidr99 0:ab4e012489ef 647 void RH_RF24::setModeIdle()
davidr99 0:ab4e012489ef 648 {
davidr99 0:ab4e012489ef 649 if (_mode != RHModeIdle)
davidr99 0:ab4e012489ef 650 {
davidr99 0:ab4e012489ef 651 // Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch
davidr99 0:ab4e012489ef 652 uint8_t config[] = { RH_RF24_GPIO_HIGH, RH_RF24_GPIO_HIGH };
davidr99 0:ab4e012489ef 653 command(RH_RF24_CMD_GPIO_PIN_CFG, config, sizeof(config));
davidr99 0:ab4e012489ef 654
davidr99 0:ab4e012489ef 655 uint8_t state[] = { _idleMode };
davidr99 0:ab4e012489ef 656 command(RH_RF24_CMD_REQUEST_DEVICE_STATE, state, sizeof(state));
davidr99 0:ab4e012489ef 657 _mode = RHModeIdle;
davidr99 0:ab4e012489ef 658 }
davidr99 0:ab4e012489ef 659 }
davidr99 0:ab4e012489ef 660
davidr99 0:ab4e012489ef 661 bool RH_RF24::sleep()
davidr99 0:ab4e012489ef 662 {
davidr99 0:ab4e012489ef 663 if (_mode != RHModeSleep)
davidr99 0:ab4e012489ef 664 {
davidr99 0:ab4e012489ef 665 uint8_t state[] = { RH_RF24_DEVICE_STATE_SLEEP };
davidr99 0:ab4e012489ef 666 command(RH_RF24_CMD_REQUEST_DEVICE_STATE, state, sizeof(state));
davidr99 0:ab4e012489ef 667
davidr99 0:ab4e012489ef 668 _mode = RHModeSleep;
davidr99 0:ab4e012489ef 669 }
davidr99 0:ab4e012489ef 670 return true;
davidr99 0:ab4e012489ef 671 }
davidr99 0:ab4e012489ef 672
davidr99 0:ab4e012489ef 673 void RH_RF24::setModeRx()
davidr99 0:ab4e012489ef 674 {
davidr99 0:ab4e012489ef 675 if (_mode != RHModeRx)
davidr99 0:ab4e012489ef 676 {
davidr99 0:ab4e012489ef 677 // CAUTION: we cant clear the rx buffers here, else we set up a race condition
davidr99 0:ab4e012489ef 678 // with the _rxBufValid test in available()
davidr99 0:ab4e012489ef 679
davidr99 0:ab4e012489ef 680 // Tell the receiver the max data length we will accept (a TX may have changed it)
davidr99 0:ab4e012489ef 681 uint8_t l[] = { sizeof(_buf) };
davidr99 0:ab4e012489ef 682 set_properties(RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_7_0, l, sizeof(l));
davidr99 0:ab4e012489ef 683
davidr99 0:ab4e012489ef 684 // Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch
davidr99 0:ab4e012489ef 685 uint8_t gpio_config[] = { RH_RF24_GPIO_HIGH, RH_RF24_GPIO_LOW };
davidr99 0:ab4e012489ef 686 command(RH_RF24_CMD_GPIO_PIN_CFG, gpio_config, sizeof(gpio_config));
davidr99 0:ab4e012489ef 687
davidr99 0:ab4e012489ef 688 uint8_t rx_config[] = { 0x00, RH_RF24_CONDITION_RX_START_IMMEDIATE, 0x00, 0x00, _idleMode, _idleMode, _idleMode};
davidr99 0:ab4e012489ef 689 command(RH_RF24_CMD_START_RX, rx_config, sizeof(rx_config));
davidr99 0:ab4e012489ef 690 _mode = RHModeRx;
davidr99 0:ab4e012489ef 691 }
davidr99 0:ab4e012489ef 692 }
davidr99 0:ab4e012489ef 693
davidr99 0:ab4e012489ef 694 void RH_RF24::setModeTx()
davidr99 0:ab4e012489ef 695 {
davidr99 0:ab4e012489ef 696 if (_mode != RHModeTx)
davidr99 0:ab4e012489ef 697 {
davidr99 0:ab4e012489ef 698 // Set the antenna switch pins using the GPIO, assuming we have an RFM module with antenna switch
davidr99 0:ab4e012489ef 699 uint8_t config[] = { RH_RF24_GPIO_LOW, RH_RF24_GPIO_HIGH };
davidr99 0:ab4e012489ef 700 command(RH_RF24_CMD_GPIO_PIN_CFG, config, sizeof(config));
davidr99 0:ab4e012489ef 701
davidr99 0:ab4e012489ef 702 uint8_t tx_params[] = { 0x00,
davidr99 0:ab4e012489ef 703 (uint8_t)(_idleMode << 4) | RH_RF24_CONDITION_RETRANSMIT_NO | RH_RF24_CONDITION_START_IMMEDIATE};
davidr99 0:ab4e012489ef 704 command(RH_RF24_CMD_START_TX, tx_params, sizeof(tx_params));
davidr99 0:ab4e012489ef 705 _mode = RHModeTx;
davidr99 0:ab4e012489ef 706 }
davidr99 0:ab4e012489ef 707 }
davidr99 0:ab4e012489ef 708
davidr99 0:ab4e012489ef 709 void RH_RF24::setTxPower(uint8_t power)
davidr99 0:ab4e012489ef 710 {
davidr99 0:ab4e012489ef 711 uint8_t pa_bias_clkduty = 0;
davidr99 0:ab4e012489ef 712 // These calculations valid for advertised power from Si chips at Vcc = 3.3V
davidr99 0:ab4e012489ef 713 // you may get lower power from RFM modules, depending on Vcc voltage, antenna etc
davidr99 0:ab4e012489ef 714 if (_deviceType == 0x4460)
davidr99 0:ab4e012489ef 715 {
davidr99 0:ab4e012489ef 716 // 0x4f = 13dBm
davidr99 0:ab4e012489ef 717 pa_bias_clkduty = 0xc0;
davidr99 0:ab4e012489ef 718 if (power > 0x4f)
davidr99 0:ab4e012489ef 719 power = 0x4f;
davidr99 0:ab4e012489ef 720 }
davidr99 0:ab4e012489ef 721 else if (_deviceType == 0x4461)
davidr99 0:ab4e012489ef 722 {
davidr99 0:ab4e012489ef 723 // 0x7f = 16dBm
davidr99 0:ab4e012489ef 724 pa_bias_clkduty = 0xc0;
davidr99 0:ab4e012489ef 725 if (power > 0x7f)
davidr99 0:ab4e012489ef 726 power = 0x7f;
davidr99 0:ab4e012489ef 727 }
davidr99 0:ab4e012489ef 728 else if (_deviceType == 0x4463 || _deviceType == 0x4464 )
davidr99 0:ab4e012489ef 729 {
davidr99 0:ab4e012489ef 730 // 0x7f = 20dBm
davidr99 0:ab4e012489ef 731 pa_bias_clkduty = 0x00; // Per WDS suggestion
davidr99 0:ab4e012489ef 732 if (power > 0x7f)
davidr99 0:ab4e012489ef 733 power = 0x7f;
davidr99 0:ab4e012489ef 734 }
davidr99 0:ab4e012489ef 735 uint8_t power_properties[] = {0x18, 0x00, 0x00 }; // PA_MODE from WDS sugggestions (why?)
davidr99 0:ab4e012489ef 736 power_properties[1] = power;
davidr99 0:ab4e012489ef 737 power_properties[2] = pa_bias_clkduty;
davidr99 0:ab4e012489ef 738 set_properties(RH_RF24_PROPERTY_PA_MODE, power_properties, sizeof(power_properties));
davidr99 0:ab4e012489ef 739 }
davidr99 0:ab4e012489ef 740
davidr99 0:ab4e012489ef 741 // Caution: There was a bug in A1 hardware that will not handle 1 byte commands.
davidr99 0:ab4e012489ef 742 bool RH_RF24::command(uint8_t cmd, const uint8_t* write_buf, uint8_t write_len, uint8_t* read_buf, uint8_t read_len)
davidr99 0:ab4e012489ef 743 {
davidr99 0:ab4e012489ef 744 bool done = false;
davidr99 0:ab4e012489ef 745
davidr99 0:ab4e012489ef 746 ATOMIC_BLOCK_START;
davidr99 0:ab4e012489ef 747 // First send the command
davidr99 0:ab4e012489ef 748 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 749 _spi.transfer(cmd);
davidr99 0:ab4e012489ef 750
davidr99 0:ab4e012489ef 751 // Now write any write data
davidr99 0:ab4e012489ef 752 if (write_buf && write_len)
davidr99 0:ab4e012489ef 753 {
davidr99 0:ab4e012489ef 754 while (write_len--)
davidr99 0:ab4e012489ef 755 _spi.transfer(*write_buf++);
davidr99 0:ab4e012489ef 756 }
davidr99 0:ab4e012489ef 757 // Sigh, the RFM26 at least has problems if we deselect too quickly :-(
davidr99 0:ab4e012489ef 758 // Innocuous timewaster:
davidr99 0:ab4e012489ef 759 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 760 // And finalise the command
davidr99 0:ab4e012489ef 761 digitalWrite(_slaveSelectPin, HIGH);
davidr99 0:ab4e012489ef 762
davidr99 0:ab4e012489ef 763 uint16_t count; // Number of times we have tried to get CTS
davidr99 0:ab4e012489ef 764 for (count = 0; !done && count < RH_RF24_CTS_RETRIES; count++)
davidr99 0:ab4e012489ef 765 {
davidr99 0:ab4e012489ef 766 // Wait for the CTS
davidr99 0:ab4e012489ef 767 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 768
davidr99 0:ab4e012489ef 769 _spi.transfer(RH_RF24_CMD_READ_BUF);
davidr99 0:ab4e012489ef 770 if (_spi.transfer(0) == RH_RF24_REPLY_CTS)
davidr99 0:ab4e012489ef 771 {
davidr99 0:ab4e012489ef 772 // Now read any expected reply data
davidr99 0:ab4e012489ef 773 if (read_buf && read_len)
davidr99 0:ab4e012489ef 774 {
davidr99 0:ab4e012489ef 775 while (read_len--)
davidr99 0:ab4e012489ef 776 {
davidr99 0:ab4e012489ef 777 *read_buf++ = _spi.transfer(0);
davidr99 0:ab4e012489ef 778 }
davidr99 0:ab4e012489ef 779 }
davidr99 0:ab4e012489ef 780 done = true;
davidr99 0:ab4e012489ef 781 }
davidr99 0:ab4e012489ef 782 // Sigh, the RFM26 at least has problems if we deselect too quickly :-(
davidr99 0:ab4e012489ef 783 // Innocuous timewaster:
davidr99 0:ab4e012489ef 784 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 785 // Finalise the read
davidr99 0:ab4e012489ef 786 digitalWrite(_slaveSelectPin, HIGH);
davidr99 0:ab4e012489ef 787 }
davidr99 0:ab4e012489ef 788 ATOMIC_BLOCK_END;
davidr99 0:ab4e012489ef 789 return done; // False if too many attempts at CTS
davidr99 0:ab4e012489ef 790 }
davidr99 0:ab4e012489ef 791
davidr99 0:ab4e012489ef 792 bool RH_RF24::configure(const uint8_t* commands)
davidr99 0:ab4e012489ef 793 {
davidr99 0:ab4e012489ef 794 // Command strings are constructed in radio_config_Si4460.h
davidr99 0:ab4e012489ef 795 // Each command starts with a count of the bytes in that command:
davidr99 0:ab4e012489ef 796 // <bytecount> <command> <bytecount-2 bytes of args/data>
davidr99 0:ab4e012489ef 797 uint8_t next_cmd_len;
davidr99 0:ab4e012489ef 798
davidr99 0:ab4e012489ef 799 while (memcpy_P(&next_cmd_len, commands, 1), next_cmd_len > 0)
davidr99 0:ab4e012489ef 800 {
davidr99 0:ab4e012489ef 801 uint8_t buf[20]; // As least big as the biggest permitted command/property list of 15
davidr99 0:ab4e012489ef 802 memcpy_P(buf, commands+1, next_cmd_len);
davidr99 0:ab4e012489ef 803 command(buf[0], buf+1, next_cmd_len - 1);
davidr99 0:ab4e012489ef 804 commands += (next_cmd_len + 1);
davidr99 0:ab4e012489ef 805 }
davidr99 0:ab4e012489ef 806 return true;
davidr99 0:ab4e012489ef 807 }
davidr99 0:ab4e012489ef 808
davidr99 0:ab4e012489ef 809 void RH_RF24::power_on_reset()
davidr99 0:ab4e012489ef 810 {
davidr99 0:ab4e012489ef 811 // Sigh: its necessary to control the SDN pin to reset this ship.
davidr99 0:ab4e012489ef 812 // Tying it to GND does not produce reliable startups
davidr99 0:ab4e012489ef 813 // Per Si4464 Data Sheet 3.3.2
davidr99 0:ab4e012489ef 814 digitalWrite(_sdnPin, HIGH); // So we dont get a glitch after setting pinMode OUTPUT
davidr99 0:ab4e012489ef 815 #if (RH_PLATFORM != RH_PLATFORM_MBED)
davidr99 0:ab4e012489ef 816 pinMode(_sdnPin, OUTPUT);
davidr99 0:ab4e012489ef 817 #endif
davidr99 0:ab4e012489ef 818 delay(10);
davidr99 0:ab4e012489ef 819 digitalWrite(_sdnPin, LOW);
davidr99 0:ab4e012489ef 820 delay(10);
davidr99 0:ab4e012489ef 821 }
davidr99 0:ab4e012489ef 822
davidr99 0:ab4e012489ef 823 bool RH_RF24::cmd_clear_all_interrupts()
davidr99 0:ab4e012489ef 824 {
davidr99 0:ab4e012489ef 825 uint8_t write_buf[] = { 0x00, 0x00, 0x00 };
davidr99 0:ab4e012489ef 826 return command(RH_RF24_CMD_GET_INT_STATUS, write_buf, sizeof(write_buf));
davidr99 0:ab4e012489ef 827 }
davidr99 0:ab4e012489ef 828
davidr99 0:ab4e012489ef 829 bool RH_RF24::set_properties(uint16_t firstProperty, const uint8_t* values, uint8_t count)
davidr99 0:ab4e012489ef 830 {
davidr99 0:ab4e012489ef 831 uint8_t buf[15];
davidr99 0:ab4e012489ef 832
davidr99 0:ab4e012489ef 833 buf[0] = firstProperty >> 8; // GROUP
davidr99 0:ab4e012489ef 834 buf[1] = count; // NUM_PROPS
davidr99 0:ab4e012489ef 835 buf[2] = firstProperty & 0xff; // START_PROP
davidr99 0:ab4e012489ef 836 uint8_t i;
davidr99 0:ab4e012489ef 837 for (i = 0; i < 12 && i < count; i++)
davidr99 0:ab4e012489ef 838 buf[3 + i] = values[i]; // DATAn
davidr99 0:ab4e012489ef 839 return command(RH_RF24_CMD_SET_PROPERTY, buf, count + 3);
davidr99 0:ab4e012489ef 840 }
davidr99 0:ab4e012489ef 841
davidr99 0:ab4e012489ef 842 bool RH_RF24::get_properties(uint16_t firstProperty, uint8_t* values, uint8_t count)
davidr99 0:ab4e012489ef 843 {
davidr99 0:ab4e012489ef 844 if (count > 16)
davidr99 0:ab4e012489ef 845 count = 16;
davidr99 0:ab4e012489ef 846 uint8_t buf[3];
davidr99 0:ab4e012489ef 847 buf[0] = firstProperty >> 8; // GROUP
davidr99 0:ab4e012489ef 848 buf[1] = count; // NUM_PROPS
davidr99 0:ab4e012489ef 849 buf[2] = firstProperty & 0xff; // START_PROP
davidr99 0:ab4e012489ef 850 return command(RH_RF24_CMD_GET_PROPERTY, buf, sizeof(buf), values, count);
davidr99 0:ab4e012489ef 851 }
davidr99 0:ab4e012489ef 852
davidr99 0:ab4e012489ef 853 float RH_RF24::get_temperature()
davidr99 0:ab4e012489ef 854 {
davidr99 0:ab4e012489ef 855 uint8_t write_buf[] = { 0x10 };
davidr99 0:ab4e012489ef 856 uint8_t read_buf[8];
davidr99 0:ab4e012489ef 857 // Takes nearly 4ms
davidr99 0:ab4e012489ef 858 command(RH_RF24_CMD_GET_ADC_READING, write_buf, sizeof(write_buf), read_buf, sizeof(read_buf));
davidr99 0:ab4e012489ef 859 uint16_t temp_adc = (read_buf[4] << 8) | read_buf[5];
davidr99 0:ab4e012489ef 860 return ((800 + read_buf[6]) / 4096.0) * temp_adc - ((read_buf[7] / 2) + 256);
davidr99 0:ab4e012489ef 861 }
davidr99 0:ab4e012489ef 862
davidr99 0:ab4e012489ef 863 float RH_RF24::get_battery_voltage()
davidr99 0:ab4e012489ef 864 {
davidr99 0:ab4e012489ef 865 uint8_t write_buf[] = { 0x08 };
davidr99 0:ab4e012489ef 866 uint8_t read_buf[8];
davidr99 0:ab4e012489ef 867 // Takes nearly 4ms
davidr99 0:ab4e012489ef 868 command(RH_RF24_CMD_GET_ADC_READING, write_buf, sizeof(write_buf), read_buf, sizeof(read_buf));
davidr99 0:ab4e012489ef 869 uint16_t battery_adc = (read_buf[2] << 8) | read_buf[3];
davidr99 0:ab4e012489ef 870 return 3.0 * battery_adc / 1280;
davidr99 0:ab4e012489ef 871 }
davidr99 0:ab4e012489ef 872
davidr99 0:ab4e012489ef 873 float RH_RF24::get_gpio_voltage(uint8_t gpio)
davidr99 0:ab4e012489ef 874 {
davidr99 0:ab4e012489ef 875 uint8_t write_buf[] = { 0x04 };
davidr99 0:ab4e012489ef 876 uint8_t read_buf[8];
davidr99 0:ab4e012489ef 877 write_buf[0] |= (gpio & 0x3);
davidr99 0:ab4e012489ef 878 // Takes nearly 4ms
davidr99 0:ab4e012489ef 879 command(RH_RF24_CMD_GET_ADC_READING, write_buf, sizeof(write_buf), read_buf, sizeof(read_buf));
davidr99 0:ab4e012489ef 880 uint16_t gpio_adc = (read_buf[0] << 8) | read_buf[1];
davidr99 0:ab4e012489ef 881 return 3.0 * gpio_adc / 1280;
davidr99 0:ab4e012489ef 882 }
davidr99 0:ab4e012489ef 883
davidr99 0:ab4e012489ef 884 uint8_t RH_RF24::frr_read(uint8_t reg)
davidr99 0:ab4e012489ef 885 {
davidr99 0:ab4e012489ef 886 uint8_t ret;
davidr99 0:ab4e012489ef 887
davidr99 0:ab4e012489ef 888 // Do not wait for CTS
davidr99 0:ab4e012489ef 889 ATOMIC_BLOCK_START;
davidr99 0:ab4e012489ef 890 // First send the command
davidr99 0:ab4e012489ef 891 digitalWrite(_slaveSelectPin, LOW);
davidr99 0:ab4e012489ef 892 _spi.transfer(RH_RF24_PROPERTY_FRR_CTL_A_MODE + reg);
davidr99 0:ab4e012489ef 893 // Get the fast response
davidr99 0:ab4e012489ef 894 ret = _spi.transfer(0);
davidr99 0:ab4e012489ef 895 digitalWrite(_slaveSelectPin, HIGH);
davidr99 0:ab4e012489ef 896 ATOMIC_BLOCK_END;
davidr99 0:ab4e012489ef 897 return ret;
davidr99 0:ab4e012489ef 898 }
davidr99 0:ab4e012489ef 899
davidr99 0:ab4e012489ef 900 // List of command replies to be printed by prinRegisters()
davidr99 0:ab4e012489ef 901 PROGMEM static const RH_RF24::CommandInfo commands[] =
davidr99 0:ab4e012489ef 902 {
davidr99 0:ab4e012489ef 903 { RH_RF24_CMD_PART_INFO, 8 },
davidr99 0:ab4e012489ef 904 { RH_RF24_CMD_FUNC_INFO, 6 },
davidr99 0:ab4e012489ef 905 { RH_RF24_CMD_GPIO_PIN_CFG, 7 },
davidr99 0:ab4e012489ef 906 { RH_RF24_CMD_FIFO_INFO, 2 },
davidr99 0:ab4e012489ef 907 { RH_RF24_CMD_PACKET_INFO, 2 },
davidr99 0:ab4e012489ef 908 { RH_RF24_CMD_GET_INT_STATUS, 8 },
davidr99 0:ab4e012489ef 909 { RH_RF24_CMD_GET_PH_STATUS, 2 },
davidr99 0:ab4e012489ef 910 { RH_RF24_CMD_GET_MODEM_STATUS, 8 },
davidr99 0:ab4e012489ef 911 { RH_RF24_CMD_GET_CHIP_STATUS, 3 },
davidr99 0:ab4e012489ef 912 { RH_RF24_CMD_REQUEST_DEVICE_STATE, 2 },
davidr99 0:ab4e012489ef 913 };
davidr99 0:ab4e012489ef 914 #define NUM_COMMAND_INFO (sizeof(commands)/sizeof(CommandInfo))
davidr99 0:ab4e012489ef 915
davidr99 0:ab4e012489ef 916 // List of properties to be printed by printRegisters()
davidr99 0:ab4e012489ef 917 PROGMEM static const uint16_t properties[] =
davidr99 0:ab4e012489ef 918 {
davidr99 0:ab4e012489ef 919 RH_RF24_PROPERTY_GLOBAL_XO_TUNE,
davidr99 0:ab4e012489ef 920 RH_RF24_PROPERTY_GLOBAL_CLK_CFG,
davidr99 0:ab4e012489ef 921 RH_RF24_PROPERTY_GLOBAL_LOW_BATT_THRESH,
davidr99 0:ab4e012489ef 922 RH_RF24_PROPERTY_GLOBAL_CONFIG,
davidr99 0:ab4e012489ef 923 RH_RF24_PROPERTY_GLOBAL_WUT_CONFIG,
davidr99 0:ab4e012489ef 924 RH_RF24_PROPERTY_GLOBAL_WUT_M_15_8,
davidr99 0:ab4e012489ef 925 RH_RF24_PROPERTY_GLOBAL_WUT_M_7_0,
davidr99 0:ab4e012489ef 926 RH_RF24_PROPERTY_GLOBAL_WUT_R,
davidr99 0:ab4e012489ef 927 RH_RF24_PROPERTY_GLOBAL_WUT_LDC,
davidr99 0:ab4e012489ef 928 RH_RF24_PROPERTY_INT_CTL_ENABLE,
davidr99 0:ab4e012489ef 929 RH_RF24_PROPERTY_INT_CTL_PH_ENABLE,
davidr99 0:ab4e012489ef 930 RH_RF24_PROPERTY_INT_CTL_MODEM_ENABLE,
davidr99 0:ab4e012489ef 931 RH_RF24_PROPERTY_INT_CTL_CHIP_ENABLE,
davidr99 0:ab4e012489ef 932 RH_RF24_PROPERTY_FRR_CTL_A_MODE,
davidr99 0:ab4e012489ef 933 RH_RF24_PROPERTY_FRR_CTL_B_MODE,
davidr99 0:ab4e012489ef 934 RH_RF24_PROPERTY_FRR_CTL_C_MODE,
davidr99 0:ab4e012489ef 935 RH_RF24_PROPERTY_FRR_CTL_D_MODE,
davidr99 0:ab4e012489ef 936 RH_RF24_PROPERTY_PREAMBLE_TX_LENGTH,
davidr99 0:ab4e012489ef 937 RH_RF24_PROPERTY_PREAMBLE_CONFIG_STD_1,
davidr99 0:ab4e012489ef 938 RH_RF24_PROPERTY_PREAMBLE_CONFIG_NSTD,
davidr99 0:ab4e012489ef 939 RH_RF24_PROPERTY_PREAMBLE_CONFIG_STD_2,
davidr99 0:ab4e012489ef 940 RH_RF24_PROPERTY_PREAMBLE_CONFIG,
davidr99 0:ab4e012489ef 941 RH_RF24_PROPERTY_PREAMBLE_PATTERN_31_24,
davidr99 0:ab4e012489ef 942 RH_RF24_PROPERTY_PREAMBLE_PATTERN_23_16,
davidr99 0:ab4e012489ef 943 RH_RF24_PROPERTY_PREAMBLE_PATTERN_15_8,
davidr99 0:ab4e012489ef 944 RH_RF24_PROPERTY_PREAMBLE_PATTERN_7_0,
davidr99 0:ab4e012489ef 945 RH_RF24_PROPERTY_SYNC_CONFIG,
davidr99 0:ab4e012489ef 946 RH_RF24_PROPERTY_SYNC_BITS_31_24,
davidr99 0:ab4e012489ef 947 RH_RF24_PROPERTY_SYNC_BITS_23_16,
davidr99 0:ab4e012489ef 948 RH_RF24_PROPERTY_SYNC_BITS_15_8,
davidr99 0:ab4e012489ef 949 RH_RF24_PROPERTY_SYNC_BITS_7_0,
davidr99 0:ab4e012489ef 950 RH_RF24_PROPERTY_PKT_CRC_CONFIG,
davidr99 0:ab4e012489ef 951 RH_RF24_PROPERTY_PKT_CONFIG1,
davidr99 0:ab4e012489ef 952 RH_RF24_PROPERTY_PKT_LEN,
davidr99 0:ab4e012489ef 953 RH_RF24_PROPERTY_PKT_LEN_FIELD_SOURCE,
davidr99 0:ab4e012489ef 954 RH_RF24_PROPERTY_PKT_LEN_ADJUST,
davidr99 0:ab4e012489ef 955 RH_RF24_PROPERTY_PKT_TX_THRESHOLD,
davidr99 0:ab4e012489ef 956 RH_RF24_PROPERTY_PKT_RX_THRESHOLD,
davidr99 0:ab4e012489ef 957 RH_RF24_PROPERTY_PKT_FIELD_1_LENGTH_12_8,
davidr99 0:ab4e012489ef 958 RH_RF24_PROPERTY_PKT_FIELD_1_LENGTH_7_0,
davidr99 0:ab4e012489ef 959 RH_RF24_PROPERTY_PKT_FIELD_1_CONFIG,
davidr99 0:ab4e012489ef 960 RH_RF24_PROPERTY_PKT_FIELD_1_CRC_CONFIG,
davidr99 0:ab4e012489ef 961 RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_12_8,
davidr99 0:ab4e012489ef 962 RH_RF24_PROPERTY_PKT_FIELD_2_LENGTH_7_0,
davidr99 0:ab4e012489ef 963 RH_RF24_PROPERTY_PKT_FIELD_2_CONFIG,
davidr99 0:ab4e012489ef 964 RH_RF24_PROPERTY_PKT_FIELD_2_CRC_CONFIG,
davidr99 0:ab4e012489ef 965 RH_RF24_PROPERTY_PKT_FIELD_3_LENGTH_12_8,
davidr99 0:ab4e012489ef 966 RH_RF24_PROPERTY_PKT_FIELD_3_LENGTH_7_0,
davidr99 0:ab4e012489ef 967 RH_RF24_PROPERTY_PKT_FIELD_3_CONFIG,
davidr99 0:ab4e012489ef 968 RH_RF24_PROPERTY_PKT_FIELD_3_CRC_CONFIG,
davidr99 0:ab4e012489ef 969 RH_RF24_PROPERTY_PKT_FIELD_4_LENGTH_12_8,
davidr99 0:ab4e012489ef 970 RH_RF24_PROPERTY_PKT_FIELD_4_LENGTH_7_0,
davidr99 0:ab4e012489ef 971 RH_RF24_PROPERTY_PKT_FIELD_4_CONFIG,
davidr99 0:ab4e012489ef 972 RH_RF24_PROPERTY_PKT_FIELD_4_CRC_CONFIG,
davidr99 0:ab4e012489ef 973 RH_RF24_PROPERTY_PKT_FIELD_5_LENGTH_12_8,
davidr99 0:ab4e012489ef 974 RH_RF24_PROPERTY_PKT_FIELD_5_LENGTH_7_0,
davidr99 0:ab4e012489ef 975 RH_RF24_PROPERTY_PKT_FIELD_5_CONFIG,
davidr99 0:ab4e012489ef 976 RH_RF24_PROPERTY_PKT_FIELD_5_CRC_CONFIG,
davidr99 0:ab4e012489ef 977 RH_RF24_PROPERTY_PKT_RX_FIELD_1_LENGTH_12_8,
davidr99 0:ab4e012489ef 978 RH_RF24_PROPERTY_PKT_RX_FIELD_1_LENGTH_7_0,
davidr99 0:ab4e012489ef 979 RH_RF24_PROPERTY_PKT_RX_FIELD_1_CONFIG,
davidr99 0:ab4e012489ef 980 RH_RF24_PROPERTY_PKT_RX_FIELD_1_CRC_CONFIG,
davidr99 0:ab4e012489ef 981 RH_RF24_PROPERTY_PKT_RX_FIELD_2_LENGTH_12_8,
davidr99 0:ab4e012489ef 982 RH_RF24_PROPERTY_PKT_RX_FIELD_2_LENGTH_7_0,
davidr99 0:ab4e012489ef 983 RH_RF24_PROPERTY_PKT_RX_FIELD_2_CONFIG,
davidr99 0:ab4e012489ef 984 RH_RF24_PROPERTY_PKT_RX_FIELD_2_CRC_CONFIG,
davidr99 0:ab4e012489ef 985 RH_RF24_PROPERTY_PKT_RX_FIELD_3_LENGTH_12_8,
davidr99 0:ab4e012489ef 986 RH_RF24_PROPERTY_PKT_RX_FIELD_3_LENGTH_7_0,
davidr99 0:ab4e012489ef 987 RH_RF24_PROPERTY_PKT_RX_FIELD_3_CONFIG,
davidr99 0:ab4e012489ef 988 RH_RF24_PROPERTY_PKT_RX_FIELD_3_CRC_CONFIG,
davidr99 0:ab4e012489ef 989 RH_RF24_PROPERTY_PKT_RX_FIELD_4_LENGTH_12_8,
davidr99 0:ab4e012489ef 990 RH_RF24_PROPERTY_PKT_RX_FIELD_4_LENGTH_7_0,
davidr99 0:ab4e012489ef 991 RH_RF24_PROPERTY_PKT_RX_FIELD_4_CONFIG,
davidr99 0:ab4e012489ef 992 RH_RF24_PROPERTY_PKT_RX_FIELD_4_CRC_CONFIG,
davidr99 0:ab4e012489ef 993 RH_RF24_PROPERTY_PKT_RX_FIELD_5_LENGTH_12_8,
davidr99 0:ab4e012489ef 994 RH_RF24_PROPERTY_PKT_RX_FIELD_5_LENGTH_7_0,
davidr99 0:ab4e012489ef 995 RH_RF24_PROPERTY_PKT_RX_FIELD_5_CONFIG,
davidr99 0:ab4e012489ef 996 RH_RF24_PROPERTY_PKT_RX_FIELD_5_CRC_CONFIG,
davidr99 0:ab4e012489ef 997 RH_RF24_PROPERTY_MODEM_MOD_TYPE,
davidr99 0:ab4e012489ef 998 RH_RF24_PROPERTY_MODEM_MAP_CONTROL,
davidr99 0:ab4e012489ef 999 RH_RF24_PROPERTY_MODEM_DSM_CTRL,
davidr99 0:ab4e012489ef 1000 RH_RF24_PROPERTY_MODEM_DATA_RATE_2,
davidr99 0:ab4e012489ef 1001 RH_RF24_PROPERTY_MODEM_DATA_RATE_1,
davidr99 0:ab4e012489ef 1002 RH_RF24_PROPERTY_MODEM_DATA_RATE_0,
davidr99 0:ab4e012489ef 1003 RH_RF24_PROPERTY_MODEM_TX_NCO_MODE_3,
davidr99 0:ab4e012489ef 1004 RH_RF24_PROPERTY_MODEM_TX_NCO_MODE_2,
davidr99 0:ab4e012489ef 1005 RH_RF24_PROPERTY_MODEM_TX_NCO_MODE_1,
davidr99 0:ab4e012489ef 1006 RH_RF24_PROPERTY_MODEM_TX_NCO_MODE_0,
davidr99 0:ab4e012489ef 1007 RH_RF24_PROPERTY_MODEM_FREQ_DEV_2,
davidr99 0:ab4e012489ef 1008 RH_RF24_PROPERTY_MODEM_FREQ_DEV_1,
davidr99 0:ab4e012489ef 1009 RH_RF24_PROPERTY_MODEM_FREQ_DEV_0,
davidr99 0:ab4e012489ef 1010 RH_RF24_PROPERTY_MODEM_TX_RAMP_DELAY,
davidr99 0:ab4e012489ef 1011 RH_RF24_PROPERTY_MODEM_MDM_CTRL,
davidr99 0:ab4e012489ef 1012 RH_RF24_PROPERTY_MODEM_IF_CONTROL,
davidr99 0:ab4e012489ef 1013 RH_RF24_PROPERTY_MODEM_IF_FREQ_2,
davidr99 0:ab4e012489ef 1014 RH_RF24_PROPERTY_MODEM_IF_FREQ_1,
davidr99 0:ab4e012489ef 1015 RH_RF24_PROPERTY_MODEM_IF_FREQ_0,
davidr99 0:ab4e012489ef 1016 RH_RF24_PROPERTY_MODEM_DECIMATION_CFG1,
davidr99 0:ab4e012489ef 1017 RH_RF24_PROPERTY_MODEM_DECIMATION_CFG0,
davidr99 0:ab4e012489ef 1018 RH_RF24_PROPERTY_MODEM_BCR_OSR_1,
davidr99 0:ab4e012489ef 1019 RH_RF24_PROPERTY_MODEM_BCR_OSR_0,
davidr99 0:ab4e012489ef 1020 RH_RF24_PROPERTY_MODEM_BCR_NCO_OFFSET_2,
davidr99 0:ab4e012489ef 1021 RH_RF24_PROPERTY_MODEM_BCR_NCO_OFFSET_1,
davidr99 0:ab4e012489ef 1022 RH_RF24_PROPERTY_MODEM_BCR_NCO_OFFSET_0,
davidr99 0:ab4e012489ef 1023 RH_RF24_PROPERTY_MODEM_BCR_GAIN_1,
davidr99 0:ab4e012489ef 1024 RH_RF24_PROPERTY_MODEM_BCR_GAIN_0,
davidr99 0:ab4e012489ef 1025 RH_RF24_PROPERTY_MODEM_BCR_GEAR,
davidr99 0:ab4e012489ef 1026 RH_RF24_PROPERTY_MODEM_BCR_MISC1,
davidr99 0:ab4e012489ef 1027 RH_RF24_PROPERTY_MODEM_AFC_GEAR,
davidr99 0:ab4e012489ef 1028 RH_RF24_PROPERTY_MODEM_AFC_WAIT,
davidr99 0:ab4e012489ef 1029 RH_RF24_PROPERTY_MODEM_AFC_GAIN_1,
davidr99 0:ab4e012489ef 1030 RH_RF24_PROPERTY_MODEM_AFC_GAIN_0,
davidr99 0:ab4e012489ef 1031 RH_RF24_PROPERTY_MODEM_AFC_LIMITER_1,
davidr99 0:ab4e012489ef 1032 RH_RF24_PROPERTY_MODEM_AFC_LIMITER_0,
davidr99 0:ab4e012489ef 1033 RH_RF24_PROPERTY_MODEM_AFC_MISC,
davidr99 0:ab4e012489ef 1034 RH_RF24_PROPERTY_MODEM_AGC_CONTROL,
davidr99 0:ab4e012489ef 1035 RH_RF24_PROPERTY_MODEM_AGC_WINDOW_SIZE,
davidr99 0:ab4e012489ef 1036 RH_RF24_PROPERTY_MODEM_AGC_RFPD_DECAY,
davidr99 0:ab4e012489ef 1037 RH_RF24_PROPERTY_MODEM_AGC_IFPD_DECAY,
davidr99 0:ab4e012489ef 1038 RH_RF24_PROPERTY_MODEM_FSK4_GAIN1,
davidr99 0:ab4e012489ef 1039 RH_RF24_PROPERTY_MODEM_FSK4_GAIN0,
davidr99 0:ab4e012489ef 1040 RH_RF24_PROPERTY_MODEM_FSK4_TH1,
davidr99 0:ab4e012489ef 1041 RH_RF24_PROPERTY_MODEM_FSK4_TH0,
davidr99 0:ab4e012489ef 1042 RH_RF24_PROPERTY_MODEM_FSK4_MAP,
davidr99 0:ab4e012489ef 1043 RH_RF24_PROPERTY_MODEM_OOK_PDTC,
davidr99 0:ab4e012489ef 1044 RH_RF24_PROPERTY_MODEM_OOK_CNT1,
davidr99 0:ab4e012489ef 1045 RH_RF24_PROPERTY_MODEM_OOK_MISC,
davidr99 0:ab4e012489ef 1046 RH_RF24_PROPERTY_MODEM_RAW_SEARCH,
davidr99 0:ab4e012489ef 1047 RH_RF24_PROPERTY_MODEM_RAW_CONTROL,
davidr99 0:ab4e012489ef 1048 RH_RF24_PROPERTY_MODEM_RAW_EYE_1,
davidr99 0:ab4e012489ef 1049 RH_RF24_PROPERTY_MODEM_RAW_EYE_0,
davidr99 0:ab4e012489ef 1050 RH_RF24_PROPERTY_MODEM_ANT_DIV_MODE,
davidr99 0:ab4e012489ef 1051 RH_RF24_PROPERTY_MODEM_ANT_DIV_CONTROL,
davidr99 0:ab4e012489ef 1052 RH_RF24_PROPERTY_MODEM_RSSI_THRESH,
davidr99 0:ab4e012489ef 1053 RH_RF24_PROPERTY_MODEM_RSSI_JUMP_THRESH,
davidr99 0:ab4e012489ef 1054 RH_RF24_PROPERTY_MODEM_RSSI_CONTROL,
davidr99 0:ab4e012489ef 1055 RH_RF24_PROPERTY_MODEM_RSSI_CONTROL2,
davidr99 0:ab4e012489ef 1056 RH_RF24_PROPERTY_MODEM_RSSI_COMP,
davidr99 0:ab4e012489ef 1057 RH_RF24_PROPERTY_MODEM_ANT_DIV_CONT,
davidr99 0:ab4e012489ef 1058 RH_RF24_PROPERTY_MODEM_CLKGEN_BAND,
davidr99 0:ab4e012489ef 1059 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE13_7_0,
davidr99 0:ab4e012489ef 1060 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE12_7_0,
davidr99 0:ab4e012489ef 1061 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE11_7_0,
davidr99 0:ab4e012489ef 1062 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE10_7_0,
davidr99 0:ab4e012489ef 1063 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE9_7_0,
davidr99 0:ab4e012489ef 1064 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE8_7_0,
davidr99 0:ab4e012489ef 1065 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE7_7_0,
davidr99 0:ab4e012489ef 1066 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE6_7_0,
davidr99 0:ab4e012489ef 1067 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE5_7_0,
davidr99 0:ab4e012489ef 1068 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE4_7_0,
davidr99 0:ab4e012489ef 1069 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE3_7_0,
davidr99 0:ab4e012489ef 1070 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE2_7_0,
davidr99 0:ab4e012489ef 1071 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE1_7_0,
davidr99 0:ab4e012489ef 1072 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COE0_7_0,
davidr99 0:ab4e012489ef 1073 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COEM0,
davidr99 0:ab4e012489ef 1074 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COEM1,
davidr99 0:ab4e012489ef 1075 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COEM2,
davidr99 0:ab4e012489ef 1076 RH_RF24_PROPERTY_MODEM_CHFLT_RX1_CHFLT_COEM3,
davidr99 0:ab4e012489ef 1077 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE13_7_0,
davidr99 0:ab4e012489ef 1078 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE12_7_0,
davidr99 0:ab4e012489ef 1079 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE11_7_0,
davidr99 0:ab4e012489ef 1080 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE10_7_0,
davidr99 0:ab4e012489ef 1081 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE9_7_0,
davidr99 0:ab4e012489ef 1082 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE8_7_0,
davidr99 0:ab4e012489ef 1083 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE7_7_0,
davidr99 0:ab4e012489ef 1084 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE6_7_0,
davidr99 0:ab4e012489ef 1085 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE5_7_0,
davidr99 0:ab4e012489ef 1086 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE4_7_0,
davidr99 0:ab4e012489ef 1087 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE3_7_0,
davidr99 0:ab4e012489ef 1088 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE2_7_0,
davidr99 0:ab4e012489ef 1089 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE1_7_0,
davidr99 0:ab4e012489ef 1090 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COE0_7_0,
davidr99 0:ab4e012489ef 1091 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COEM0,
davidr99 0:ab4e012489ef 1092 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COEM1,
davidr99 0:ab4e012489ef 1093 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COEM2,
davidr99 0:ab4e012489ef 1094 RH_RF24_PROPERTY_MODEM_CHFLT_RX2_CHFLT_COEM3,
davidr99 0:ab4e012489ef 1095 RH_RF24_PROPERTY_PA_MODE,
davidr99 0:ab4e012489ef 1096 RH_RF24_PROPERTY_PA_PWR_LVL,
davidr99 0:ab4e012489ef 1097 RH_RF24_PROPERTY_PA_BIAS_CLKDUTY,
davidr99 0:ab4e012489ef 1098 RH_RF24_PROPERTY_PA_TC,
davidr99 0:ab4e012489ef 1099 RH_RF24_PROPERTY_SYNTH_PFDCP_CPFF,
davidr99 0:ab4e012489ef 1100 RH_RF24_PROPERTY_SYNTH_PFDCP_CPINT,
davidr99 0:ab4e012489ef 1101 RH_RF24_PROPERTY_SYNTH_VCO_KV,
davidr99 0:ab4e012489ef 1102 RH_RF24_PROPERTY_SYNTH_LPFILT3,
davidr99 0:ab4e012489ef 1103 RH_RF24_PROPERTY_SYNTH_LPFILT2,
davidr99 0:ab4e012489ef 1104 RH_RF24_PROPERTY_SYNTH_LPFILT1,
davidr99 0:ab4e012489ef 1105 RH_RF24_PROPERTY_SYNTH_LPFILT0,
davidr99 0:ab4e012489ef 1106 RH_RF24_PROPERTY_MATCH_VALUE_1,
davidr99 0:ab4e012489ef 1107 RH_RF24_PROPERTY_MATCH_MASK_1,
davidr99 0:ab4e012489ef 1108 RH_RF24_PROPERTY_MATCH_CTRL_1,
davidr99 0:ab4e012489ef 1109 RH_RF24_PROPERTY_MATCH_VALUE_2,
davidr99 0:ab4e012489ef 1110 RH_RF24_PROPERTY_MATCH_MASK_2,
davidr99 0:ab4e012489ef 1111 RH_RF24_PROPERTY_MATCH_CTRL_2,
davidr99 0:ab4e012489ef 1112 RH_RF24_PROPERTY_MATCH_VALUE_3,
davidr99 0:ab4e012489ef 1113 RH_RF24_PROPERTY_MATCH_MASK_3,
davidr99 0:ab4e012489ef 1114 RH_RF24_PROPERTY_MATCH_CTRL_3,
davidr99 0:ab4e012489ef 1115 RH_RF24_PROPERTY_MATCH_VALUE_4,
davidr99 0:ab4e012489ef 1116 RH_RF24_PROPERTY_MATCH_MASK_4,
davidr99 0:ab4e012489ef 1117 RH_RF24_PROPERTY_MATCH_CTRL_4,
davidr99 0:ab4e012489ef 1118 RH_RF24_PROPERTY_FREQ_CONTROL_INTE,
davidr99 0:ab4e012489ef 1119 RH_RF24_PROPERTY_FREQ_CONTROL_FRAC_2,
davidr99 0:ab4e012489ef 1120 RH_RF24_PROPERTY_FREQ_CONTROL_FRAC_1,
davidr99 0:ab4e012489ef 1121 RH_RF24_PROPERTY_FREQ_CONTROL_FRAC_0,
davidr99 0:ab4e012489ef 1122 RH_RF24_PROPERTY_FREQ_CONTROL_CHANNEL_STEP_SIZE_1,
davidr99 0:ab4e012489ef 1123 RH_RF24_PROPERTY_FREQ_CONTROL_CHANNEL_STEP_SIZE_0,
davidr99 0:ab4e012489ef 1124 RH_RF24_PROPERTY_FREQ_CONTROL_VCOCNT_RX_ADJ,
davidr99 0:ab4e012489ef 1125 RH_RF24_PROPERTY_RX_HOP_CONTROL,
davidr99 0:ab4e012489ef 1126 RH_RF24_PROPERTY_RX_HOP_TABLE_SIZE,
davidr99 0:ab4e012489ef 1127 RH_RF24_PROPERTY_RX_HOP_TABLE_ENTRY_0,
davidr99 0:ab4e012489ef 1128 };
davidr99 0:ab4e012489ef 1129 #define NUM_PROPERTIES (sizeof(properties)/sizeof(uint16_t))
davidr99 0:ab4e012489ef 1130
davidr99 0:ab4e012489ef 1131 bool RH_RF24::printRegisters()
davidr99 0:ab4e012489ef 1132 {
davidr99 0:ab4e012489ef 1133 #ifdef RH_HAVE_SERIAL
davidr99 0:ab4e012489ef 1134 uint8_t i;
davidr99 0:ab4e012489ef 1135 // First print the commands that return interesting data
davidr99 0:ab4e012489ef 1136 for (i = 0; i < NUM_COMMAND_INFO; i++)
davidr99 0:ab4e012489ef 1137 {
davidr99 0:ab4e012489ef 1138 CommandInfo cmd;
davidr99 0:ab4e012489ef 1139 memcpy_P(&cmd, &commands[i], sizeof(cmd));
davidr99 0:ab4e012489ef 1140 uint8_t buf[10]; // Big enough for the biggest command reply
davidr99 0:ab4e012489ef 1141 if (command(cmd.cmd, NULL, 0, buf, cmd.replyLen))
davidr99 0:ab4e012489ef 1142 {
davidr99 0:ab4e012489ef 1143 // Print the results:
davidr99 0:ab4e012489ef 1144 Serial.print("cmd: ");
davidr99 0:ab4e012489ef 1145 Serial.print(cmd.cmd, HEX);
davidr99 0:ab4e012489ef 1146 Serial.print(" : ");
davidr99 0:ab4e012489ef 1147 uint8_t j;
davidr99 0:ab4e012489ef 1148 for (j = 0; j < cmd.replyLen; j++)
davidr99 0:ab4e012489ef 1149 {
davidr99 0:ab4e012489ef 1150 Serial.print(buf[j], HEX);
davidr99 0:ab4e012489ef 1151 Serial.print(" ");
davidr99 0:ab4e012489ef 1152 }
davidr99 0:ab4e012489ef 1153 Serial.println("");
davidr99 0:ab4e012489ef 1154 }
davidr99 0:ab4e012489ef 1155 }
davidr99 0:ab4e012489ef 1156
davidr99 0:ab4e012489ef 1157 // Now print the properties
davidr99 0:ab4e012489ef 1158 for (i = 0; i < NUM_PROPERTIES; i++)
davidr99 0:ab4e012489ef 1159 {
davidr99 0:ab4e012489ef 1160 uint16_t prop;
davidr99 0:ab4e012489ef 1161 memcpy_P(&prop, &properties[i], sizeof(prop));
davidr99 0:ab4e012489ef 1162 uint8_t result;
davidr99 0:ab4e012489ef 1163 get_properties(prop, &result, 1);
davidr99 0:ab4e012489ef 1164 Serial.print("prop: ");
davidr99 0:ab4e012489ef 1165 Serial.print(prop, HEX);
davidr99 0:ab4e012489ef 1166 Serial.print(": ");
davidr99 0:ab4e012489ef 1167 Serial.print(result, HEX);
davidr99 0:ab4e012489ef 1168 Serial.println("");
davidr99 0:ab4e012489ef 1169 }
davidr99 0:ab4e012489ef 1170 #endif
davidr99 0:ab4e012489ef 1171 return true;
davidr99 0:ab4e012489ef 1172 }