Djordje Trajkovic
/
ccRF
Send&recive two byte over ccRF 2550
Diff: main.cpp
- Revision:
- 0:a669868d99dd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jun 30 21:47:55 2015 +0000 @@ -0,0 +1,538 @@ +#include "mbed.h" +#include "regssrf04.h" +#include "__Lib_RF_CC2550.h" + +#define _TX_MODE 0 +#define _RX_MODE 1 +#define _IDLE_MODE 2 + +/******************************************************************************* +* Connections for the ccRF module +*******************************************************************************/ +Serial pc(SERIAL_TX, SERIAL_RX); +//RF_STAT +DigitalIn RF_STAT(PA_10);//GDO2 +DigitalIn gdo0(PB_5); // pin connected to gdo0 pin for checking that received a new packet +//RF_CS +DigitalOut RF_CS(PB_3);//CS pin mikroelektronika +//Spi +SPI spi3(PB_15,PB_14,PB_13); + +unsigned char txBuffer[64]; +unsigned char rxBuffer[61]; // Length byte + 2 status bytes are not stored in this buffer +unsigned char paTable = 0xFE; + +/******************************************************************************* +* Default setting for the ccRF module +*******************************************************************************/ +RF_SETTINGS rfSettings = { + 0x0A, // FSCTRL1 Frequency synthesizer control. + 0x00, // FSCTRL0 Frequency synthesizer control. + 0x5D, // FREQ2 Frequency control word, high byte. + 0x93, // FREQ1 Frequency control word, middle byte. + 0xB1, // FREQ0 Frequency control word, low byte. + 0x2D, // MDMCFG4 Modem configuration. + 0x3B, // MDMCFG3 Modem configuration. + 0x73, // MDMCFG2 Modem configuration. + 0x22, // MDMCFG1 Modem configuration. + 0xF8, // MDMCFG0 Modem configuration. + 0x00, // CHANNR Channel number. + 0x01, // DEVIATN Modem deviation setting (when FSK modulation is enabled). + 0xB6, // FREND1 Front end RX configuration. + 0x10, // FREND0 Front end TX configuration. + 0x18, // MCSM0 Main Radio Control State Machine configuration. + 0x1D, // FOCCFG Frequency Offset Compensation Configuration. + 0x1C, // BSCFG Bit synchronization Configuration. + 0xC7, // AGCCTRL2 AGC control. + 0x00, // AGCCTRL1 AGC control. + 0xB0, // AGCCTRL0 AGC control. + 0xEA, // FSCAL3 Frequency synthesizer calibration. + 0x0A, // FSCAL2 Frequency synthesizer calibration. + 0x00, // FSCAL1 Frequency synthesizer calibration. + 0x11, // FSCAL0 Frequency synthesizer calibration. + 0x59, // FSTEST Frequency synthesizer calibration. + 0x88, // TEST2 Various test settings. + 0x31, // TEST1 Various test settings. + 0x0B, // TEST0 Various test settings. + 0x07, // FIFOTHR RXFIFO and TXFIFO thresholds. + 0x29, // IOCFG2 GDO2 output pin configuration. + 0x06, // IOCFG0D GDO0 output pin configuration. + 0x06, // PKTCTRL1 Packet automation control. //04 + 0x05, // PKTCTRL0 Packet automation control. + 0x30, // ADDR Device address. + 0xFF // PKTLEN Packet length. + }; + +// globals +unsigned char oldstate; +unsigned int primljeni_pod; +unsigned char len; +unsigned char modeSelected; + +//////////////////////////////////////////////////////////////////////////////////// +#include "regssrf04.h" +#include "__Lib_RF_CC2550.h" + +//------------------------------------------------------------------------------------------------------- +// Definitions to support burst/single access: +#define WRITE_BURST 0x40 +#define READ_SINGLE 0x80 +#define READ_BURST 0xC0 +//------------------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------------- +// Defines +#define CRC_OK 0x80 +#define RSSI 0 +#define LQI 1 +#define BYTES_IN_RXFIFO 0x7F +//------------------------------------------------------------------------------------------------------- + + +////////////////////////////////// +unsigned char spi3read(int address) { + int data; + RF_CS=0; //select the device + spi3.write(address); //select the register + data = spi3.write(0x00); //send a dummy byte to retrive data + RF_CS=1; //deselect the device + return data; //return the data + +} +////////////////////////////////// + + +unsigned char RfReceivePacket(unsigned char *rxBuffer, unsigned char *length); +//------------------------------------------------------------------------------------------------------- +// void RFInit() +// +// DESCRIPTION: +// Basic initialisation of RF pins. +// +//------------------------------------------------------------------------------------------------------- +void RFInit() +{ + RfWriteRfSettings(&rfSettings); + RfSpiWriteReg(CCxxx0_PATABLE, paTable); +} + +//------------------------------------------------------------------------------------------------------- +// void Reset_CCxxx0() +// +// DESCRIPTION: +// Function for reseting CCxxx0 chip via strobe command (CCxxx_SRES - strobe command). +// +//------------------------------------------------------------------------------------------------------- +void Reset_CCxxx0() +{ + RF_CS = 0; + while(RF_STAT); + spi3.write(CCxxx0_SRES); + RF_CS = 1; +} + + +//------------------------------------------------------------------------------------------------------- +// void Power_On_Reset_CCxxx0() +// +// DESCRIPTION: +// Function for manual reseting CCxxx0 chip. +// +//------------------------------------------------------------------------------------------------------- +void POWER_ON_RESET_CCxxx0() +{ + RF_CS = 1; + wait(1e-6); + RF_CS = 0; + wait(1e-6); + RF_CS = 1; + wait(41e-6); + Reset_CCxxx0(); +} + +//------------------------------------------------------------------------------------------------------- +// void RfSpiWriteReg(unsigned char addr, unsigned char value) +// +// DESCRIPTION: +// Function for writing to a single CCxxx0 register +// +// ARGUMENTS: +// unsigned char address +// Address of a specific CCxxx0 register to accessed. +// unsigned char value +// Value to be written to the specified CCxxx0 register. +//------------------------------------------------------------------------------------------------------- +void RfSpiWriteReg(unsigned char address, unsigned char value) +{ + RF_CS = 0; + while(RF_STAT); + spi3.write(address); + + spi3.write(value); + RF_CS = 1; +} + +//------------------------------------------------------------------------------------------------------- +// void RfSpiWriteBurstReg(unsigned char address, unsigned char *buffer, unsigned char count) +// +// DESCRIPTION: +// This function writes to multiple CCxxx0 register, using SPI burst access. +// +// ARGUMENTS: +// unsigned char addr +// Address of the first CCxxx0 register to be accessed. +// unsigned char *buffer +// Array of bytes to be written into a corresponding range of +// CCxx00 registers, starting by the address specified in _addr_. +// unsigned char count +// Number of bytes to be written to the subsequent CCxxx0 registers. +//------------------------------------------------------------------------------------------------------- +void RfSpiWriteBurstReg(unsigned char address, unsigned char *buffer, unsigned char count) { + unsigned char i; + RF_CS = 0; + while (RF_STAT); + + spi3.write(address | WRITE_BURST); + + spi3.write(count); + for (i = 0; i < count; i++) { + spi3.write(buffer[i]); + } + RF_CS = 1; +}// RfSpiWriteBurstReg + +//------------------------------------------------------------------------------------------------------- +// void RfSpiStrobe(unsigned char strobe) +// +// DESCRIPTION: +// Function for writing a strobe command to the CCxxx0 +// +// ARGUMENTS: +// unsigned char strobe +// Strobe command +//------------------------------------------------------------------------------------------------------- +void RfSpiStrobe(unsigned char strobe) { + RF_CS = 0; + while (RF_STAT); + spi3.write(strobe); + + RF_CS = 1; +}// RfSpiStrobe + +//------------------------------------------------------------------------------------------------------- +// unsigned char RfSpiReadStatus(usnigned char address) +// +// DESCRIPTION: +// This function reads a CCxxx0 status register. +// +// ARGUMENTS: +// unsigned char address +// Address of the CCxxx0 status register to be accessed. +// +// RETURN VALUE: +// usnigned char +// Value of the accessed CCxxx0 status register. +//------------------------------------------------------------------------------------------------------- +unsigned char RfSpiReadStatus(unsigned char address) { + unsigned char x; + RF_CS = 0; + while (RF_STAT); + x = spi3read(address | READ_BURST); + RF_CS = 1; + return x; +}// halSpiReadStatus + +//------------------------------------------------------------------------------------------------------- +// unsigned char RfSpiReadReg(unsigned char address) +// +// DESCRIPTION: +// This function gets the value of a single specified CCxxx0 register. +// +// ARGUMENTS: +// unsigned char addr +// Address of the CCxxx0 register to be accessed. +// +// RETURN VALUE: +// unsigned char +// Value of the accessed CCxxx0 register. +//------------------------------------------------------------------------------------------------------- +unsigned char RfSpiReadReg(unsigned char address) { + unsigned char x; + RF_CS = 0; + while (RF_STAT); + x = spi3read(address | READ_SINGLE); + RF_CS = 1; + return x; +}// RfSpiReadReg + +//------------------------------------------------------------------------------------------------------- +// void RfSpiReadBurstReg(unsigned char address, unsigned char *buffer, unsigned char count) +// +// DESCRIPTION: +// This function reads multiple CCxxx0 register, using SPI burst access. +// +// ARGUMENTS: +// unsigned char address +// Address of the first CCxxx0 register to be accessed. +// unsigned char *buffer +// Pointer to a byte array which stores the values read from a +// corresponding range of CCxxx0 registers. +// unsigned char count +// Number of bytes to be written to the subsequent CCxxx0 registers. +//------------------------------------------------------------------------------------------------------- +void RfSpiReadBurstReg(unsigned char address, unsigned char *buffer, unsigned char count) { + unsigned char i; + RF_CS = 0; + while (RF_STAT); + for (i = 0; i < count; i++) { + buffer[i] = spi3read(address | READ_BURST); + } + RF_CS = 1; +}// RfSpiReadBurstReg + +//------------------------------------------------------------------------------------------------------- +// void RfWriteRfSettings(RF_SETTINGS *pRfSettings) +// +// DESCRIPTION: +// This function is used to configure the CCxxx0 based on a given rf setting +// +// ARGUMENTS: +// RF_SETTINGS *pRfSettings +// Pointer to a struct containing rf register settings +//------------------------------------------------------------------------------------------------------- +void RfWriteRfSettings(RF_SETTINGS *pRfSettings) { + // Write register settings + RfSpiWriteReg(CCxxx0_FSCTRL1, pRfSettings->FSCTRL1); + RfSpiWriteReg(CCxxx0_FSCTRL0, pRfSettings->FSCTRL0); + RfSpiWriteReg(CCxxx0_FREQ2, pRfSettings->FREQ2); + RfSpiWriteReg(CCxxx0_FREQ1, pRfSettings->FREQ1); + RfSpiWriteReg(CCxxx0_FREQ0, pRfSettings->FREQ0); + RfSpiWriteReg(CCxxx0_MDMCFG4, pRfSettings->MDMCFG4); + RfSpiWriteReg(CCxxx0_MDMCFG3, pRfSettings->MDMCFG3); + RfSpiWriteReg(CCxxx0_MDMCFG2, pRfSettings->MDMCFG2); + RfSpiWriteReg(CCxxx0_MDMCFG1, pRfSettings->MDMCFG1); + RfSpiWriteReg(CCxxx0_MDMCFG0, pRfSettings->MDMCFG0); + RfSpiWriteReg(CCxxx0_CHANNR, pRfSettings->CHANNR); + RfSpiWriteReg(CCxxx0_DEVIATN, pRfSettings->DEVIATN); + RfSpiWriteReg(CCxxx0_FREND1, pRfSettings->FREND1); + RfSpiWriteReg(CCxxx0_FREND0, pRfSettings->FREND0); + RfSpiWriteReg(CCxxx0_MCSM0 , pRfSettings->MCSM0 ); + RfSpiWriteReg(CCxxx0_FOCCFG, pRfSettings->FOCCFG); + RfSpiWriteReg(CCxxx0_BSCFG, pRfSettings->BSCFG); + RfSpiWriteReg(CCxxx0_AGCCTRL2, pRfSettings->AGCCTRL2); + RfSpiWriteReg(CCxxx0_AGCCTRL1, pRfSettings->AGCCTRL1); + RfSpiWriteReg(CCxxx0_AGCCTRL0, pRfSettings->AGCCTRL0); + RfSpiWriteReg(CCxxx0_FSCAL3, pRfSettings->FSCAL3); + RfSpiWriteReg(CCxxx0_FSCAL2, pRfSettings->FSCAL2); + RfSpiWriteReg(CCxxx0_FSCAL1, pRfSettings->FSCAL1); + RfSpiWriteReg(CCxxx0_FSCAL0, pRfSettings->FSCAL0); + RfSpiWriteReg(CCxxx0_FSTEST, pRfSettings->FSTEST); + RfSpiWriteReg(CCxxx0_TEST2, pRfSettings->TEST2); + RfSpiWriteReg(CCxxx0_TEST1, pRfSettings->TEST1); + RfSpiWriteReg(CCxxx0_TEST0, pRfSettings->TEST0); + RfSpiWriteReg(CCxxx0_FIFOTHR, pRfSettings->FIFOTHR); + RfSpiWriteReg(CCxxx0_IOCFG2, pRfSettings->IOCFG2); + RfSpiWriteReg(CCxxx0_IOCFG0, pRfSettings->IOCFG0); + RfSpiWriteReg(CCxxx0_PKTCTRL1, pRfSettings->PKTCTRL1); + RfSpiWriteReg(CCxxx0_PKTCTRL0, pRfSettings->PKTCTRL0); + RfSpiWriteReg(CCxxx0_ADDR, pRfSettings->ADDR); + RfSpiWriteReg(CCxxx0_PKTLEN, pRfSettings->PKTLEN); +}// RfWriteRfSettings + + +//------------------------------------------------------------------------------------------------------- +// void RfWriteRfSettings2500() +// +// DESCRIPTION: +// This function is used for testing +// +// +//------------------------------------------------------------------------------------------------------- +void RfWriteRfSettings2500() { + RfSpiWriteReg(CCxxx0_IOCFG0,0x06); //GDO0Output Pin Configuration + RfSpiWriteReg(CCxxx0_PKTCTRL0,0x05);//Packet Automation Control + RfSpiWriteReg(CCxxx0_FSCTRL1,0x08); //Frequency Synthesizer Control + RfSpiWriteReg(CCxxx0_FREQ2,0x5D); //Frequency Control Word, High Byte + RfSpiWriteReg(CCxxx0_FREQ1,0x93); //Frequency Control Word, Middle Byte + RfSpiWriteReg(CCxxx0_FREQ0,0xB1); //Frequency Control Word, Low Byte + RfSpiWriteReg(CCxxx0_MDMCFG4,0x86); //Modem Configuration + RfSpiWriteReg(CCxxx0_MDMCFG3,0x83); //Modem Configuration + RfSpiWriteReg(CCxxx0_MDMCFG2,0x03); //Modem Configuration + RfSpiWriteReg(CCxxx0_DEVIATN,0x44); //Modem Deviation Setting + RfSpiWriteReg(CCxxx0_MCSM0,0x18); //Main Radio Control State Machine Configuration + RfSpiWriteReg(CCxxx0_FOCCFG,0x16); //Frequency Offset Compensation Configuration + RfSpiWriteReg(CCxxx0_FSCAL1,0x00); //Frequency Synthesizer Calibration + RfSpiWriteReg(CCxxx0_FSCAL0,0x11); //Frequency Synthesizer Calibration +}//RfWriteRfSettings2500 + + +//------------------------------------------------------------------------------------------------------- +// void RfSendPacket(unsigned char *txBuffer, unsigned char size) +// +// DESCRIPTION: +// This function can be used to transmit a packet with packet length up to 63 bytes. +// To use this function, GD00 must be configured to be asserted when sync word is sent and +// de-asserted at the end of the packet => halSpiWriteReg(CCxxx0_IOCFG0, 0x06); +// The function implements polling of GDO0. First it waits for GD00 to be set and then it waits +// for it to be cleared. +// +// ARGUMENTS: +// unsigned char *txBuffer +// Pointer to a buffer containing the data that are going to be transmitted +// +// unsigned char size +// The size of the txBuffer +//------------------------------------------------------------------------------------------------------- +void RfSendPacket(unsigned char *txBuffer, unsigned char size) { + + RfSpiWriteBurstReg(CCxxx0_TXFIFO, txBuffer, size); + + RfSpiStrobe(CCxxx0_STX); + + // Wait for GDO0 to be set -> sync transmitted + while(!RF_STAT); + + // Wait for GDO0 to be cleared -> end of packet + while(RF_STAT); + +}// RfSendPacket + +unsigned char RfTransmitPacketWithAddress(unsigned char *txBuffer, unsigned char size, unsigned char *attempts) { + unsigned char rxBuffer[61]; + unsigned char length; + //send data to receiver - address specified + RfSendPacket(txBuffer, size); + + length = sizeof(rxBuffer); + //switch to receive mode + switch(RfReceivePacket(rxBuffer, &length)) + { + case CCxxx0_RECEIVE_CRC_ERROR: + { + *attempts++; + RfTransmitPacketWithAddress(txBuffer, size, attempts); + break; + } + + case CCxxx0_RECEIVE_CRC_OK: + { + return *attempts; + break; + } + } +} +// RfSendPacketStatus + +//------------------------------------------------------------------------------------------------------- +// uunsiged char RfReceivePacket(unsigned char *rxBuffer, unsigned char *length) +// +// DESCRIPTION: +// This function can be used to receive a packet of variable packet length (first byte in the packet +// must be the length byte). The packet length should not exceed the RX FIFO size. +// To use this function, GD00 must be configured to be asserted when sync word is sent and +// de-asserted at the end of the packet => halSpiWriteReg(CCxxx0_IOCFG0, 0x06); +// Also, APPEND_STATUS in the PKTCTRL1 register must be enabled. +// The function implements polling of GDO0. First it waits for GD00 to be set and then it waits +// for it to be cleared. +// After the GDO0 pin has been de-asserted, the RXBYTES register is read to make sure that there +// are bytes in the FIFO. This is because the GDO signal will indicate sync received even if the +// FIFO is flushed due to address filtering, CRC filtering, or packet length filtering. +// +// ARGUMENTS: +// unsigned char *rxBuffer +// Pointer to the buffer where the incoming data should be stored +// unsigned char *length +// Pointer to a variable containing the size of the buffer where the incoming data should be +// stored. After this function returns, that variable holds the packet length. +// +// RETURN VALUE: +// unsigned char +// TRUE: CRC OK +// FALSE: CRC NOT OK (or no packet was put in the RX FIFO due to filtering) +//------------------------------------------------------------------------------------------------------- +unsigned char RfReceivePacket(unsigned char *rxBuffer, unsigned char *length) { + unsigned char status[2]; + unsigned char packetLength; + + RfSpiStrobe(CCxxx0_SRX); + + // Wait for GDO0 to be set -> sync received + if(!RF_STAT); + + // Wait for GDO0 to be cleared -> end of packet + while(RF_STAT); + + // This status register is safe to read since it will not be updated after + // the packet has been received (See the CC1100 and 2500 Errata Note) + if ((RfSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO)) { + + // Read length byte + packetLength = RfSpiReadReg(CCxxx0_RXFIFO); + + // Read data from RX FIFO and store in rxBuffer + if (packetLength <= *length) { + RfSpiReadBurstReg(CCxxx0_RXFIFO, rxBuffer, packetLength); + *length = packetLength; + + // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI) + RfSpiReadBurstReg(CCxxx0_RXFIFO, status, 2); + + // MSB of LQI is the CRC_OK bit + return (status[LQI] & CRC_OK); + } else { + *length = packetLength; + + // Make sure that the radio is in IDLE state before flushing the FIFO + // (Unless RXOFF_MODE has been changed, the radio should be in IDLE state at this point) + RfSpiStrobe(CCxxx0_SIDLE); + + // Flush RX FIFO + RfSpiStrobe(CCxxx0_SFRX); + return 0; + } + } else + return 0; +}// RfReceivePacket +//////////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* +* Main function +*******************************************************************************/ +int main() { + //Init SPI - treba da se provere par + spi3.format(8,0);//format(8,0); + spi3.frequency(1000000); //frekvencija(1000000); + wait(0.1); + // Reset ccRF chip + POWER_ON_RESET_CCxxx0(); + // Init RF module + RFInit(); + + modeSelected = _IDLE_MODE; + //Set_Text_Info(modeSelected); + + while(1){ + // switch to transmit mode + modeSelected = _TX_MODE;//mora da se komentarise ako prima + // switch to receive mode + modeSelected = _RX_MODE;//komentarise se ako salje + // switch to transmit mode + modeSelected = _TX_MODE; + switch(modeSelected){ + case _TX_MODE :{ + txBuffer[0] = 0xAD; // send broacast address, primer + txBuffer[1] = 0xFD; + RfSendPacket(txBuffer, 2); // send 2 bytes + }; break; + case _RX_MODE :{ // receive measured ADC value + len = sizeof(rxBuffer); + if(RfReceivePacket(rxBuffer, &len)){ // first byte is address + primljeni_pod = (((unsigned int)rxBuffer[1]) << 8) + rxBuffer[2]; + pc.printf("%i",primljeni_pod); + } + }; break; + } + } +} +/******************************************************************************* +* End +*******************************************************************************/ \ No newline at end of file