#include /** * Copyright (c) 2011 panStamp * * This file is part of the panStamp project. * * panStamp is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * any later version. * * panStamp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with panStamp; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA * * Author: Daniel Berenguer * Creation date: 03/03/2011 */ extern "C" { #include "cc1101.h" } #define PORT_GDO0 5 #define byte uint8_t /** * Macros */ // Select (SPI) CC1101 #define cc1101_Select() spi.begin() // Deselect (SPI) CC1101 #define cc1101_Deselect() spi.end() // Wait until SPI MISO line goes low #define wait_Miso() delay(10) //while(digitalRead(PORT_SPI_MISO)) // Get GDO0 pin state #define getGDO0state() digitalRead(PORT_GDO0) // Wait until GDO0 line goes high #define wait_GDO0_high() while(!getGDO0state()) {delay(1);} // Wait until GDO0 line goes low #define wait_GDO0_low() while(getGDO0state()) {delay(1);} /** * PATABLE */ const byte paTable[8] = {0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /** * CC1101 * * Class constructor */ CC1101::CC1101(void) { carrierFreq = CFREQ_868; channel = CC1101_DEFVAL_CHANNR; syncWord[0] = CC1101_DEFVAL_SYNC1; syncWord[1] = CC1101_DEFVAL_SYNC0; devAddress = CC1101_DEFVAL_ADDR; paTableByte = PA_LowPower; // Priority = Low power } /** * wakeUp * * Wake up CC1101 from Power Down state */ void CC1101::wakeUp(void) { cc1101_Select(); // Select CC1101 wait_Miso(); // Wait until MISO goes low cc1101_Deselect(); // Deselect CC1101 } /** * writeReg * * Write single register into the CC1101 IC via SPI * * 'regAddr' Register address * 'value' Value to be writen */ void CC1101::writeReg(byte regAddr, byte value) { cc1101_Select(); // Select CC1101 wait_Miso(); // Wait until MISO goes low spi.transfer(regAddr); // Send register address spi.transfer(value); // Send value cc1101_Deselect(); // Deselect CC1101 } /** * writeBurstReg * * Write multiple registers into the CC1101 IC via SPI * * 'regAddr' Register address * 'buffer' Data to be writen * 'len' Data length */ void CC1101::writeBurstReg(byte regAddr, byte* buffer, byte len) { byte addr, i; addr = regAddr | WRITE_BURST; // Enable burst transfer cc1101_Select(); // Select CC1101 wait_Miso(); // Wait until MISO goes low spi.transfer(addr); // Send register address for(i=0 ; i 0) { // Set data length at the first position of the TX FIFO writeReg(CC1101_TXFIFO, packet.length); // Write data into the TX FIFO writeBurstReg(CC1101_TXFIFO, packet.data, packet.length); // CCA enabled: will enter TX state only if the channel is clear setTxState(); } // Check that TX state is being entered (state = RXTX_SETTLING) marcState = readStatusReg(CC1101_MARCSTATE) & 0x1F; if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15)) { setIdleState(); // Enter IDLE state flushTxFifo(); // Flush Tx FIFO setRxState(); // Back to RX state // Declare to be in Rx state rfState = RFSTATE_RX; return false; } // Wait for the sync word to be transmitted wait_GDO0_high(); // Wait until the end of the packet transmission wait_GDO0_low(); // Check that the TX FIFO is empty if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0) res = true; setIdleState(); // Enter IDLE state flushTxFifo(); // Flush Tx FIFO // Enter back into RX state setRxState(); // Declare to be in Rx state rfState = RFSTATE_RX; return res; } /** * receiveData * * Read data packet from RX FIFO * * 'packet' Container for the packet received * * Return: * Amount of bytes received */ byte CC1101::receiveData(CCPACKET * packet) { byte val; byte rxBytes = readStatusReg(CC1101_RXBYTES); // Any byte waiting to be read and no overflow? if (rxBytes & 0x7F) { // Read data length packet->length = readConfigReg(CC1101_RXFIFO); // If packet is too long if (packet->length > CCPACKET_DATA_LEN) packet->length = 0; // Discard packet else { // Read data packet readBurstReg(packet->data, CC1101_RXFIFO, packet->length); // Read RSSI packet->rssi = readConfigReg(CC1101_RXFIFO); // Read LQI and CRC_OK val = readConfigReg(CC1101_RXFIFO); packet->lqi = val & 0x7F; packet->crc_ok = bitRead(val, 7); } } else packet->length = 0; setIdleState(); // Enter IDLE state flushRxFifo(); // Flush Rx FIFO //cmdStrobe(CC1101_SCAL); // Back to RX state setRxState(); return packet->length; } /** * setRxState * * Enter Rx state */ void CC1101::setRxState(void) { cmdStrobe(CC1101_SRX); rfState = RFSTATE_RX; } /** * setTxState * * Enter Tx state */ void CC1101::setTxState(void) { cmdStrobe(CC1101_STX); rfState = RFSTATE_TX; }