Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RadioHead-148 by
RH_NRF905.cpp
- Committer:
- davidr99
- Date:
- 2015-10-15
- Revision:
- 0:ab4e012489ef
File content as of revision 0:ab4e012489ef:
// RH_NRF905.cpp // // Copyright (C) 2012 Mike McCauley // $Id: RH_NRF905.cpp,v 1.5 2015/08/12 23:18:51 mikem Exp $ #include <RH_NRF905.h> RH_NRF905::RH_NRF905(PINS chipEnablePin, PINS txEnablePin, PINS slaveSelectPin, RHGenericSPI& spi) : RHNRFSPIDriver(slaveSelectPin, spi) { _chipEnablePin = chipEnablePin; _txEnablePin = txEnablePin; } bool RH_NRF905::init() { #if defined (__MK20DX128__) || defined (__MK20DX256__) // Teensy is unreliable at 8MHz: _spi.setFrequency(RHGenericSPI::Frequency1MHz); #else _spi.setFrequency(RHGenericSPI::Frequency8MHz); #endif if (!RHNRFSPIDriver::init()) return false; // Initialise the slave select pin and the tx Enable pin #if (RH_PLATFORM != RH_PLATFORM_MBED) pinMode(_chipEnablePin, OUTPUT); pinMode(_txEnablePin, OUTPUT); #endif digitalWrite(_chipEnablePin, LOW); digitalWrite(_txEnablePin, LOW); // Configure the chip // CRC 16 bits enabled. 16MHz crystal freq spiWriteRegister(RH_NRF905_CONFIG_9, RH_NRF905_CONFIG_9_CRC_EN | RH_NRF905_CONFIG_9_CRC_MODE_16BIT | RH_NRF905_CONFIG_9_XOF_16MHZ); // Make sure we are powered down setModeIdle(); // Some innocuous defaults setChannel(108, LOW); // 433.2 MHz setRF(RH_NRF905::TransmitPowerm10dBm); return true; } // Use the register commands to read and write the registers uint8_t RH_NRF905::spiReadRegister(uint8_t reg) { return spiRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG); } uint8_t RH_NRF905::spiWriteRegister(uint8_t reg, uint8_t val) { return spiWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, val); } uint8_t RH_NRF905::spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len) { return spiBurstRead((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_R_CONFIG, dest, len); } uint8_t RH_NRF905::spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len) { return spiBurstWrite((reg & RH_NRF905_REG_MASK) | RH_NRF905_REG_W_CONFIG, src, len); } uint8_t RH_NRF905::statusRead() { // The status is a byproduct of sending a command return spiCommand(0); } bool RH_NRF905::setChannel(uint16_t channel, bool hiFrequency) { spiWriteRegister(RH_NRF905_CONFIG_0, channel & RH_NRF905_CONFIG_0_CH_NO); // Set or clear the high bit of the channel uint8_t bit8 = (channel >> 8) & 0x01; uint8_t reg1 = spiReadRegister(RH_NRF905_CONFIG_1); reg1 = (reg1 & ~0x01) | bit8; // Set or clear the HFREQ_PLL bit reg1 &= ~RH_NRF905_CONFIG_1_HFREQ_PLL; if (hiFrequency) reg1 |= RH_NRF905_CONFIG_1_HFREQ_PLL; spiWriteRegister(RH_NRF905_CONFIG_1, reg1); return true; } bool RH_NRF905::setNetworkAddress(uint8_t* address, uint8_t len) { if (len < 1 || len > 4) return false; // Set RX_AFW and TX_AFW spiWriteRegister(RH_NRF905_CONFIG_2, len | (len << 4)); spiBurstWrite(RH_NRF905_REG_W_TX_ADDRESS, address, len); spiBurstWriteRegister(RH_NRF905_CONFIG_5, address, len); return true; } bool RH_NRF905::setRF(TransmitPower power) { // Enum definitions of power are the same numerical values as the register spiWriteRegister(RH_NRF905_CONFIG_1_PA_PWR, power); return true; } void RH_NRF905::setModeIdle() { if (_mode != RHModeIdle) { digitalWrite(_chipEnablePin, LOW); digitalWrite(_txEnablePin, LOW); _mode = RHModeIdle; } } void RH_NRF905::setModeRx() { if (_mode != RHModeRx) { digitalWrite(_txEnablePin, LOW); digitalWrite(_chipEnablePin, HIGH); _mode = RHModeRx; } } void RH_NRF905::setModeTx() { if (_mode != RHModeTx) { // Its the high transition that puts us into TX mode digitalWrite(_txEnablePin, HIGH); digitalWrite(_chipEnablePin, HIGH); _mode = RHModeTx; } } bool RH_NRF905::send(const uint8_t* data, uint8_t len) { if (len > RH_NRF905_MAX_MESSAGE_LEN) return false; // Set up the headers _buf[0] = _txHeaderTo; _buf[1] = _txHeaderFrom; _buf[2] = _txHeaderId; _buf[3] = _txHeaderFlags; _buf[4] = len; memcpy(_buf+RH_NRF905_HEADER_LEN, data, len); spiBurstWrite(RH_NRF905_REG_W_TX_PAYLOAD, _buf, len + RH_NRF905_HEADER_LEN); setModeTx(); // Radio will return to Standby mode after transmission is complete _txGood++; return true; } bool RH_NRF905::waitPacketSent() { if (_mode != RHModeTx) return false; while (!(statusRead() & RH_NRF905_STATUS_DR)) YIELD; setModeIdle(); return true; } bool RH_NRF905::isSending() { if (_mode != RHModeTx) return false; return !(statusRead() & RH_NRF905_STATUS_DR); } bool RH_NRF905::printRegister(uint8_t reg) { #ifdef RH_HAVE_SERIAL Serial.print(reg, HEX); Serial.print(": "); Serial.println(spiReadRegister(reg), HEX); #endif return true; } bool RH_NRF905::printRegisters() { uint8_t registers[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; uint8_t i; for (i = 0; i < sizeof(registers); i++) printRegister(registers[i]); return true; } // Check whether the latest received message is complete and uncorrupted void RH_NRF905::validateRxBuf() { // Check the length uint8_t len = _buf[4]; if (len > RH_NRF905_MAX_MESSAGE_LEN) return; // Silly LEN header // Extract the 4 headers _rxHeaderTo = _buf[0]; _rxHeaderFrom = _buf[1]; _rxHeaderId = _buf[2]; _rxHeaderFlags = _buf[3]; if (_promiscuous || _rxHeaderTo == _thisAddress || _rxHeaderTo == RH_BROADCAST_ADDRESS) { _rxGood++; _bufLen = len + RH_NRF905_HEADER_LEN; // _buf still includes the headers _rxBufValid = true; } } bool RH_NRF905::available() { if (!_rxBufValid) { if (_mode == RHModeTx) return false; setModeRx(); if (!(statusRead() & RH_NRF905_STATUS_DR)) return false; // Get the message into the RX buffer, so we can inspect the headers // we still dont know how long is the user message spiBurstRead(RH_NRF905_REG_R_RX_PAYLOAD, _buf, RH_NRF905_MAX_PAYLOAD_LEN); validateRxBuf(); if (_rxBufValid) setModeIdle(); // Got one } return _rxBufValid; } void RH_NRF905::clearRxBuf() { _rxBufValid = false; _bufLen = 0; } bool RH_NRF905::recv(uint8_t* buf, uint8_t* len) { if (!available()) return false; if (buf && len) { // Skip the 4 headers that are at the beginning of the rxBuf if (*len > _bufLen-RH_NRF905_HEADER_LEN) *len = _bufLen-RH_NRF905_HEADER_LEN; memcpy(buf, _buf+RH_NRF905_HEADER_LEN, *len); } clearRxBuf(); // This message accepted and cleared return true; } uint8_t RH_NRF905::maxMessageLength() { return RH_NRF905_MAX_MESSAGE_LEN; }