Wireless Remote Control : CC2500 application

You are currently viewing Wireless Remote Control : CC2500 application
  • Post author:
  • Reading time:5 mins read


The aim of this article is to serve as a quick reference guide to use CC2500 2.4Ghz wireless transceiver IC along with a Microcontroller using SPI interface.

The CC2500 operates in a half duplex mode and the maximum data rate is 500Kbaud.

Functional Blocks : Transmit Mode

Functional description : The above diagram represents a high level functional diagram of using the CC2500 with a Microcontroller.

In this example we are using it in a wireless transmitter mode, The variable which needs to be transmitted is a 16 bit value from the Microcontroller.

Since the CC2500 TX FIFO can be written with only a 8 bit register, we need to split the 16 bit variable from the MCU into 2 bytes : MSB byte and LSB byte and store them in buffers.

Splitting of the 16 bit variable “x” to two bytes can be done by the bitwise operators in C as below example :

MSB = x & 0xFF, perform binary AND and masking.

LSB = x >> 8, perform shifting to the right by 8 bits.

These bytes are then transferred to the TX FIFO register in the CC2500 using the packet length counter.

The MCU can send the STX strobe to the CC2500 to start transmitting the bytes from the FIFO to the antenna.

Functional Blocks : Receive Mode

Functional description : The above diagram shows the logical blocks of using the CC2500 with Microcontroller in a receive mode.

The RF packets are received into the RX FIFO in the CC2500 chip.

The CC2500 generates an interrupt to the Microcontroller to start receiving the bytes according to the received byte count.

These bytes are then transferred to the MCU buffers for further combining them into one single 16 bit variable as below :

x = LSB << 8 | MSB, perform left shift by 8 bits and binary OR MSB.

The received variable “x” can be further processed by the Microcontroller as per the desired application.


SPI transfer

The CC2500 can be configured through simple 4 wire SPI interface using SCLK,SI,SO, CSn pins.

All transactions on the SPI interface starts with a header byte containing a Read/Write bit, burst access bit, and a 6 bit address. The CSn pin must be low during transfers on the SPI, after the transfer of the data the CSn should be pulled high.

The transfer between the MCU and the CC2500 can be done using array and loop function by using the packet length counter.

High Level Instruction

  1. Configure the control Registers with parameters.
  2. System Reset strobe command.
  3. Read/Write Operation to the Registers.
  4. Read/Write bytes to/from the MCU through serial interface.
  5. STX/SRX strobe command for start transmitting or receiving.


Transceiver : A Transceiver is a transmitter and receiver in the same package.

MSB : Most significant byte which is the left 8 bit from a 16 bit data.

LSB : Least significant byte which is the right 8 bit from a 16 bit data.

SPI : Serial Peripheral Interface used to interface the Module peripheral with the Microcontroller.

FIFO : First in First Out shift register.

Firmware Code

The C code which can be used to program the modules can contain 3 basic files :

1.) main.c : The main application code can be included here and the variables can be used to send the data to the CC2500 or receive the data from the CC2500.

example pseudocode :

#include “include.h”

extern char paTable[];

extern char paTableLen;

char txBuffer[4];

char rxBuffer[4];

unsigned int i = 0;

void main (void)


  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT


    // Build packet

    txBuffer[0] = 2;                        // Packet length

    txBuffer[1] = 0x01;                     // Packet address

    txBuffer[2] = (~TI_CC_SW_PxIFG << 1) & 0x02; // Load switch inputs

    RFSendPacket(txBuffer, 3);              // Send value over RF

    __delay_cycles(5000);                   // Switch debounce


  TI_CC_SW_PxIFG &= ~(TI_CC_SW1);           // Clr flag that caused int


2.) CC2500.c : Th CC2500 function library can be built here.

example pseudocode :

char RFReceivePacket(char *rxBuffer, char *length)


  char status[2];

  char pktLen;

  if ((TI_CC_SPIReadStatus(TI_CCxxx0_RXBYTES) & TI_CCxxx0_NUM_RXBYTES))


    pktLen = TI_CC_SPIReadReg(TI_CCxxx0_RXFIFO); // Read length byte

    if (pktLen <= *length)                  // If pktLen size <= rxBuffer


      TI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, rxBuffer, pktLen); // Pull data

      *length = pktLen;                     // Return the actual size

 TI_CC_SPIReadBurstReg(TI_CCxxx0_RXFIFO, status, 2);

                                            // Read appended status bytes

 return (char)(status[TI_CCxxx0_LQI_RX]&TI_CCxxx0_CRC_OK);

    }                                       // Return CRC_OK bit



      *length = pktLen;                     // Return the large size

      TI_CC_SPIStrobe(TI_CCxxx0_SFRX);      // Flush RXFIFO

      return 0;                             // Error




      return 0;                             // Error


3.) SPI.c : The low level SPI code can be included in this file.

example  :

void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count)



//  Writes values to multiple configuration registers, the first register being

//  at address “addr”.  First data byte is at “buffer”, and both addr and

//  buffer are incremented sequentially (within the CCxxxx and MSP430,

//  respectively) until “count” writes have been performed.

Farees Ahmed

The aim of this blog is to serve as a quick reference guide for the Curious. Appreciate your feedback and comments !