diff options
Diffstat (limited to 'peripheral/libupm/src/nrf24l01/nrf24l01.cxx')
-rw-r--r-- | peripheral/libupm/src/nrf24l01/nrf24l01.cxx | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/peripheral/libupm/src/nrf24l01/nrf24l01.cxx b/peripheral/libupm/src/nrf24l01/nrf24l01.cxx deleted file mode 100644 index 1b8b702..0000000 --- a/peripheral/libupm/src/nrf24l01/nrf24l01.cxx +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com> - * Copyright (c) 2014 Intel Corporation. - * BLE Beaconing based on http://dmitry.gr/index.php?r=05.Projects&proj=11.%20Bluetooth%20LE%20fakery - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <iostream> -#include <unistd.h> -#include <string> -#include <stdexcept> -#include <stdlib.h> - -#include "nrf24l01.h" - -using namespace upm; - - -NRF24L01::NRF24L01 (uint8_t cs, uint8_t ce) - : m_csnPinCtx(cs), m_cePinCtx(ce), m_spi(0) -{ - init (cs, ce); -} - -void -NRF24L01::init (uint8_t chip_select, uint8_t chip_enable) { - mraa::Result error = mraa::SUCCESS; - - m_csn = chip_select; - m_ce = chip_enable; - m_channel = 99; - - error = m_csnPinCtx.dir(mraa::DIR_OUT); - if (error != mraa::SUCCESS) { - mraa::printError (error); - } - - error = m_cePinCtx.dir(mraa::DIR_OUT); - if (error != mraa::SUCCESS) { - mraa::printError (error); - } - - ceLow(); - csOff (); -} - -void -NRF24L01::configure () { - /* Set RF channel */ - setRegister (RF_CH, m_channel); - - /* Set length of incoming payload */ - setRegister (RX_PW_P0, m_payload); - - /* Set length of incoming payload for broadcast */ - setRegister (RX_PW_P1, m_payload); - - /* Start receiver */ - rxPowerUp (); - rxFlushBuffer (); -} - -void -NRF24L01::send (uint8_t * value) { - uint8_t status; - status = getStatus(); - - while (m_ptx) { - status = getStatus(); - - if((status & ((1 << TX_DS) | (1 << MAX_RT)))){ - m_ptx = 0; - break; - } - } // Wait until last paket is send - - ceLow (); - txPowerUp (); // Set to transmitter mode , Power up - txFlushBuffer (); - - csOn (); - m_spi.writeByte(W_TX_PAYLOAD); // Write cmd to write payload - writeBytes (value, NULL, m_payload); // Write payload - csOff (); - ceHigh(); // Start transmission - - while (dataSending ()) { } - - usleep (10000); -} - -void -NRF24L01::send () { - send (m_txBuffer); -} - -void -NRF24L01::setSourceAddress (uint8_t * addr) { - ceLow (); - writeRegister (RX_ADDR_P0, addr, ADDR_LEN); - ceHigh (); -} - -void -NRF24L01::setDestinationAddress (uint8_t * addr) { - writeRegister (TX_ADDR, addr, ADDR_LEN); -} - -void -NRF24L01::setBroadcastAddress (uint8_t * addr) { - writeRegister (RX_ADDR_P1, addr, ADDR_LEN); -} - -void -NRF24L01::setPayload (uint8_t payload) { - m_payload = payload; -} - -#ifdef JAVACALLBACK -void -NRF24L01::setDataReceivedHandler (Callback *call_obj) -{ - callback_obj = call_obj; - dataReceivedHandler = &generic_callback; -} -#else -void -NRF24L01::setDataReceivedHandler (funcPtrVoidVoid handler) -{ - dataReceivedHandler = handler; -} -#endif - -bool -NRF24L01::dataReady () { - /* See note in getData() function - just checking RX_DR isn't good enough */ - uint8_t status = getStatus(); - /* We can short circuit on RX_DR, but if it's not set, we still need - * to check the FIFO for any pending packets */ - if ( status & (1 << RX_DR) ) { - return 1; - } - - return !rxFifoEmpty(); -} - -bool -NRF24L01::dataSending () { - uint8_t status; - if(m_ptx) { // Sending mode. - status = getStatus(); - /* if sending successful (TX_DS) or max retries exceded (MAX_RT). */ - if((status & ((1 << TX_DS) | (1 << MAX_RT)))){ - rxPowerUp (); - return false; - } - return true; - } - return false; -} - -void -NRF24L01::getData (uint8_t * data) { - csOn (); - /* Send cmd to read rx payload */ - m_spi.writeByte(R_RX_PAYLOAD); - /* Read payload */ - writeBytes (data, data, m_payload); - csOff (); - /* NVI: per product spec, p 67, note c: - * "The RX_DR IRQ is asserted by a new packet arrival event. The procedure - * for handling this interrupt should be: 1) read payload through SPI, - * 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more - * payloads available in RX FIFO, 4) if there are more data in RX FIFO, - * repeat from step 1)." - * So if we're going to clear RX_DR here, we need to check the RX FIFO - * in the dataReady() function */ - /* Reset status register */ - setRegister (STATUS, (1<<RX_DR)); -} - -uint8_t -NRF24L01::getStatus() { - return getRegister (STATUS); -} - -bool -NRF24L01::rxFifoEmpty () { - uint8_t fifoStatus = getRegister (FIFO_STATUS); - return (fifoStatus & (1 << RX_EMPTY)); -} - -void -NRF24L01::rxPowerUp () { - m_ptx = 0; - ceLow (); - setRegister (CONFIG, _CONFIG | ( (1 << PWR_UP) | (1 << PRIM_RX) )); - ceHigh (); - setRegister (STATUS, (1 << TX_DS) | (1 << MAX_RT)); -} - -void -NRF24L01::rxFlushBuffer () { - sendCommand (FLUSH_RX); -} - -void -NRF24L01::txPowerUp () { - m_ptx = 1; - setRegister (CONFIG, _CONFIG | ( (1 << PWR_UP) | (0 << PRIM_RX) )); -} - -void -NRF24L01::powerDown(){ - ceLow (); - setRegister (CONFIG, _CONFIG); -} - -void -NRF24L01::setChannel (uint8_t channel) { - m_channel = channel; - setRegister (RF_CH, channel); -} - -void -NRF24L01::setPower (power_t power) { - uint8_t setupRegisterData = 0; - - switch (power) { - case NRF_0DBM: - m_power = 3; - break; - case NRF_6DBM: - m_power = 2; - break; - case NRF_12DBM: - m_power = 1; - break; - case NRF_18DBM: - m_power = 0; - break; - } - - setupRegisterData = getRegister (RF_SETUP); // Read current value. - setupRegisterData &= 0xFC; // Erase the old value; - setupRegisterData |= (m_power & 0x3); - setRegister (RF_SETUP, setupRegisterData); // Write the new value. -} - -uint8_t -NRF24L01::setSpeedRate (speed_rate_t rate) { - uint8_t setupRegisterData = 0; - - setupRegisterData = getRegister (RF_SETUP); // Read current value. - setupRegisterData &= ~((1 << RF_DR_LOW) | (1 << RF_DR_HIGH)); - - switch (rate) { - case NRF_250KBPS: - setupRegisterData |= (1 << RF_DR_LOW) ; - break; - case NRF_1MBPS: - break; - case NRF_2MBPS: - setupRegisterData |= (1 << RF_DR_HIGH); - break; - } - - setRegister (RF_SETUP, setupRegisterData); // Write the new value. - - if (setupRegisterData == getRegister (RF_SETUP)) { - return 0x0; - } - - return 0x1; -} - -mraa::Result -NRF24L01::ceHigh () { - return m_cePinCtx.write(HIGH); -} - -mraa::Result -NRF24L01::ceLow () { - return m_cePinCtx.write(LOW); -} - -mraa::Result -NRF24L01::csOn () { - return m_csnPinCtx.write(LOW); -} - -mraa::Result -NRF24L01::csOff () { - return m_csnPinCtx.write(HIGH); -} - -void -NRF24L01::pollListener() { - if (dataReady()) { - getData (m_rxBuffer); -#ifdef JAVACALLBACK - dataReceivedHandler (callback_obj); /* let know that data arrived */ -#else - dataReceivedHandler (); /* let know that data arrived */ -#endif - } -} - -void -NRF24L01::txFlushBuffer () { - sendCommand (FLUSH_TX); -} - -void -NRF24L01::setBeaconingMode () { - setRegister (CONFIG, 0x12); // on, no crc, int on RX/TX done - setRegister (EN_AA, 0x00); // no auto-acknowledge - setRegister (EN_RXADDR, 0x00); // no RX - setRegister (SETUP_AW, 0x02); // 5-byte address - setRegister (SETUP_RETR, 0x00); // no auto-retransmit - setRegister (RF_SETUP, 0x06); // 1MBps at 0dBm - setRegister (STATUS, 0x3E); // clear various flags - setRegister (DYNPD, 0x00); // no dynamic payloads - setRegister (FEATURE, 0x00); // no features - setRegister (RX_PW_P0, 32); // always RX 32 bytes - setRegister (EN_RXADDR, 0x01); // RX on pipe 0 - - uint8_t addr[4] = { swapbits(0x8E), swapbits(0x89), swapbits(0xBE), swapbits(0xD6)}; - writeRegister (TX_ADDR, addr, 4); - writeRegister (RX_ADDR_P0, addr, 4); - - uint8_t index = 0; - m_bleBuffer[index++] = 0x42; // PDU type, given address is random - m_bleBuffer[index++] = 0x1B; // 6+3+2+16 = 27 bytes of payload - - m_bleBuffer[index++] = BLE_MAC_0; - m_bleBuffer[index++] = BLE_MAC_1; - m_bleBuffer[index++] = BLE_MAC_2; - m_bleBuffer[index++] = BLE_MAC_3; - m_bleBuffer[index++] = BLE_MAC_4; - m_bleBuffer[index++] = BLE_MAC_5; - - m_bleBuffer[index++] = 2; // flags (LE-only, limited discovery mode) - m_bleBuffer[index++] = 0x01; - m_bleBuffer[index++] = 0x05; - - m_bleBuffer[index++] = 17; - m_bleBuffer[index++] = 0x08; -} - -void -NRF24L01::sendBeaconingMsg (uint8_t * msg) { - const uint8_t chRf[] = {2, 26,80}; - const uint8_t chLe[] = {37,38,39}; - uint8_t index = BLE_PAYLOAD_OFFSET + 16; - - memcpy (&m_bleBuffer[BLE_PAYLOAD_OFFSET], msg, 16); - m_bleBuffer[index++] = 0x55; - m_bleBuffer[index++] = 0x55; - m_bleBuffer[index++] = 0x55; - - uint8_t channel = 0; - while (++channel != sizeof(chRf)) { - setRegister (RF_CH, chRf[channel]); - setRegister (STATUS, 0x6E); //clear flags - - blePacketEncode (m_bleBuffer, index, chLe[channel]); - - sendCommand (FLUSH_TX); // Clear RX Fifo - sendCommand (FLUSH_RX); // Clear TX Fifo - - csOn (); - m_spi.writeByte(W_TX_PAYLOAD); // Write cmd to write payload - writeBytes (m_bleBuffer, NULL, 32); // Write payload - csOff (); - - setRegister (CONFIG, 0x12); // tx on - ceHigh (); // Start transmission - usleep (10000); - ceLow (); - } -} - -/* - * --------------- - * PRIVATE SECTION - * --------------- - */ - -void -NRF24L01::writeBytes (uint8_t * dataout, uint8_t * datain, uint8_t len) { - if(len > MAX_BUFFER){ - len = MAX_BUFFER; - } - for (uint8_t i = 0; i < len; i++) { - if (datain != NULL) { - datain[i] = m_spi.writeByte(dataout[i]); - } else { - m_spi.writeByte(dataout[i]); - } - } -} - -void -NRF24L01::setRegister (uint8_t reg, uint8_t value) { - csOn (); - m_spi.writeByte(W_REGISTER | (REGISTER_MASK & reg)); - m_spi.writeByte(value); - csOff (); -} - -uint8_t -NRF24L01::getRegister (uint8_t reg) { - uint8_t data = 0; - - csOn (); - m_spi.writeByte(R_REGISTER | (REGISTER_MASK & reg)); - data = m_spi.writeByte(data); - csOff (); - - return data; -} - -void -NRF24L01::readRegister (uint8_t reg, uint8_t * value, uint8_t len) { - csOn (); - m_spi.writeByte(R_REGISTER | (REGISTER_MASK & reg)); - writeBytes (value, value, len); - csOff (); -} - -void -NRF24L01::writeRegister (uint8_t reg, uint8_t * value, uint8_t len) { - csOn (); - m_spi.writeByte(W_REGISTER | (REGISTER_MASK & reg)); - writeBytes (value, NULL, len); - csOff (); -} - -void -NRF24L01::sendCommand (uint8_t cmd) { - csOn (); - m_spi.writeByte(cmd); - csOff (); -} - -void -NRF24L01::bleCrc (const uint8_t* data, uint8_t len, uint8_t* dst) { - uint8_t v, t, d; - while(len--) { - d = *data++; - for(v = 0; v < 8; v++, d >>= 1){ - t = dst[0] >> 7; - dst[0] <<= 1; - if(dst[1] & 0x80) dst[0] |= 1; - dst[1] <<= 1; - if(dst[2] & 0x80) dst[1] |= 1; - dst[2] <<= 1; - - if(t != (d & 1)) { - dst[2] ^= 0x5B; - dst[1] ^= 0x06; - } - } - } -} - -void -NRF24L01::bleWhiten (uint8_t* data, uint8_t len, uint8_t whitenCoeff) { - uint8_t m; - while(len--) { - for(m = 1; m; m <<= 1) { - if(whitenCoeff & 0x80){ - whitenCoeff ^= 0x11; - (*data) ^= m; - } - whitenCoeff <<= 1; - } - data++; - } -} - -void -NRF24L01::blePacketEncode(uint8_t* packet, uint8_t len, uint8_t chan) { - if(len > MAX_BUFFER){ - len = MAX_BUFFER; - } - - //length is of packet, including crc. pre-populate crc in packet with initial crc value! - uint8_t i, dataLen = len - 3; - - bleCrc(packet, dataLen, packet + dataLen); - for(i = 0; i < 3; i++, dataLen++) { - packet[dataLen] = swapbits(packet[dataLen]); - } - - bleWhiten(packet, len, (swapbits(chan) | 2)); - for(i = 0; i < len; i++) { - packet[i] = swapbits(packet[i]); - } -} - -uint8_t -NRF24L01::swapbits(uint8_t a) { - uint8_t v = 0; - - if(a & 0x80) v |= 0x01; - if(a & 0x40) v |= 0x02; - if(a & 0x20) v |= 0x04; - if(a & 0x10) v |= 0x08; - if(a & 0x08) v |= 0x10; - if(a & 0x04) v |= 0x20; - if(a & 0x02) v |= 0x40; - if(a & 0x01) v |= 0x80; - - return v; -} |