This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR5994: Integrate CC1101 BoosterPack - RF Module

Part Number: MSP430FR5994
Other Parts Discussed in Thread: CC1101,

Hi guys,

I am working with MSP430FR5994 with CC1101 BoosterPack using Anaren chip. I have look through all of the examples and go through lines of code but I still haven't figured out how to get it working.

My application is fairly simple, pushing a button will send a packet contain char data = 'a' to other MSP430FR5994. The receiver side will process the packet and extract that char, then if it is 'a' , turn on an LED.

Has anyone successfully work with two module above? 

Thanks

  • Hi Hau,

    I assume you have already looked through the CC112x-CC1190 Boost Software Examples (SWRA493). The MSP430FRBoot (SLAA721) resources contain example code that successfully demonstrate communication using the 430BOOST-CC110L.

    Regards,
    Ryan
  • Hello Ryan,

    I have spent 4 days looking over that project, and try my best to follow the sequence but nothing seem to work. Is there any other example of simple TX and RX for MSP430FR5994?

    This is the repo for the TX side, would you mind looking at it and give me some guidance?

    github.com/.../RF-RemoteControl

    Thanks in advance!

    Alex

  • Can you share your code? Both Tx and Rx? Could It be something as simple as using strcmp() to compare a string to a char?
  • Hello Keith,

    This is the TX side

    #include <msp430fr5994.h>
    #include <stdint.h>
    #include "radio_drv.h"
    #include "cc1x_utils.h"
    #include "cc1101_def.h"
    #include "hal_spi_rf.h"
    #include "hal_timer.h"
    
    // Global Variables
    
    #define TX_BUF_SIZE 1
    #define FREQUENCY	902750
    unsigned char txBuffer[TX_BUF_SIZE];
    unsigned char response;
    uint16_t ii, cc;
    unsigned short rx_length;
    unsigned int status;
    //extern unsigned char rand_data = 'a';
    // Global Functions
    
    void Init_CLK(void);
    void Init_Radio(void);
    void Init_GPIO(void);
    
    
    int main(void) {
    	WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    	Init_GPIO();
    
    	Init_CLK();
    	Init_Radio();
    
    	while (1)
    	{
    		P5IFG &= ~BIT6; // Clear button flag before going to sleep
    		__bis_SR_register(LPM0_bits + GIE);
    		__disable_interrupt();
    		while (performTX == true)
    		{
    
    			hal_timer_init(8000);
    
    
    			txBuffer[0] = 0x01;
    			//for (ii = 0; ii < TX_BUF_SIZE - 1; ii++) txBuffer[ii + 1] = 0;
    
    			radio_send(txBuffer, TX_BUF_SIZE);
    			radio_wait_for_idle(0);         // 0 = no timeout, just wait
    
    			radio_receive_on();
    			hal_timer_stop();
    
    			performTX = false;
    			P3OUT ^= (BIT1);
    			//__delay_cycles(2500000);
    			P3OUT ^= (BIT1);
    			//__delay_cycles(2500000);
    			P3OUT ^= (BIT1);
    			//__delay_cycles(2500000);
    			P3OUT ^= (BIT1);
    		}
    	}
    }
    
    //--------------------------- Init CLK -----------------------------//
    
    void Init_CLK(void) {
    
    	CSCTL0_H = CSKEY_H;
    	CSCTL1 = DCOFSEL_6;                                     // Set DCO = 8Mhz
    	CSCTL2 = SELA__VLOCLK + SELM__DCOCLK + SELS__DCOCLK;
    	CSCTL3 = DIVA__1 + DIVS__1 + DIVM__1;
    
    }
    
    //--------------------------- Init Radio -----------------------------//
    
    void Init_Radio(void){
    
    	radio_init(3);
    
    	radio_set_freq(FREQUENCY);
    
    	set_rf_packet_length(TX_BUF_SIZE);
    
    }
    
    //--------------------------- Init GPIO -----------------------------//
    
    void Init_GPIO(void) {
    	P5OUT |= (BIT6);
    	P5REN |= BIT6;
    	P5IES &= ~BIT6;
    	P5IFG &= ~BIT6;
    	P5IE |= BIT6;
    
    	P1OUT &= ~(BIT0 + BIT1);
    	P1DIR |= BIT0 + BIT1;
    
    	P3DIR |= BIT0 + BIT1 + BIT3;
    	P3OUT &= ~(BIT0 + BIT1 + BIT3);
    	PM5CTL0 &= ~LOCKLPM5;
    }
    
    //--------------------------- Port 5 Interrupt Function -----------------------------//
    /*#pragma vector=RF_PORT_VECTOR
    __interrupt void radio_isr(void) {
    
    	if(RF_GDO_PxIFG & RF_GDO_PIN) {
    
    		// Clear LPM0 bits from 0(SR)
    		//__bic_SR_register_on_exit(LPM3_bits);
    
    		// clear the interrupt flag
    		RF_GDO_PxIFG &= ~RF_GDO_PIN;
    
    		// indicate that end of packet has been found
    		//rf_end_packet = 1;
    		P1OUT ^= BIT1                                     ;
    	}
    
    	else if(BUTTON_PxIFG & BUTTON1_PIN)
    	{
    		 // reset the RF_GDO_PIN /
    		BUTTON_PxIFG &= ~BUTTON1_PIN;
    
    		// indicate button event /
    		P1OUT ^= BIT0;
    		radio_send(rand_data, 1);
    		// exit from low power mode on ISR exit /
    		//__bic_SR_register_on_exit(LPM0_bits);
    	}
    
    }*/
    
    

    This is the RX

    #include <msp430.h>
    #include <stdint.h>
    #include "driverlib.h"
    #include <ff.h>
    #include <diskio.h>
    #include "HAL_SDCard.h"
    #include "cc1101_def.h"
    #include "radio_drv.h"
    #include "cc1x_utils.h"
    #include "hal_spi_rf.h"
    #include "hal_timer.h"
    
    #define TX_BUF_SIZE 1
    #define FREQUENCY	902750
    #define CHECK_MSEC_TA 10			// Interval of timer A count to check button state
    #define CHECK_MSEC_TB 35			// Interval of timer A count to check button state
    #define PRESS_MSEC 10			// stable time before registering pressed
    #define RELEASE_MSEC 100		// stable time before registering release
    /*---------------- Global Variables ---------------------*/
    volatile char TXData;
    FIL file;                                               /* Opened file object */
    FATFS fatfs;                                            /* File system object */
    DIRS dir;                                               /* Directory object   */
    FRESULT errCode;                                        /* Error code object  */
    FRESULT res;                                            /* Result object      */
    UINT bytesRead;                                         /* Bytes read object  */
    UINT read;                                              /* Read bytes object  */
    Calendar calendar;
    FRESULT WriteFile(char*, char*, WORD);
    unsigned char MST_Data,SLV_Data;
    BYTE buffer[32];
    int result=1;
    volatile unsigned char buttonPressed;
    volatile unsigned char currentState = 0;
    volatile unsigned char count;
    unsigned char check_rf_end_packet = 0;
    unsigned short rx_length;
    unsigned char txBuffer[TX_BUF_SIZE];
    /******************************************************************************
     * LOCAL VARIABLES */
    
    /*---------------- Function Called ----------------------*/
    
    void Init_GPIO(void);
    void Init_I2C(void);
    void Init_CLK(void);
    void Init_FAT(void);
    void Init_RTC(void);
    void Init_TimerA(void);
    void Init_TimerB(void);
    void Log_SDCard(char data);
    void Init_Radio(void);
    void Init_SPI_Radio(void);
    
    int main(void)
    {
    
    	WDT_A_hold(WDT_A_BASE);			// Stop WatchDog Timer
    	Init_GPIO();					// Initialization GPIO
    	Init_CLK();						// Initialization system clocks
    	//Init_SPI_Radio();				// Initialization SPI communication for Radio Communication
    	Init_Radio();					// Initialization Radio Module
    	Init_TimerA();					// Initialization TimerA
    	Init_TimerB();
    	//Init_RTC();					// Initialize real time will cause problem with polling I2C Photon data request
    	Init_FAT();						// Initialization SD Card
    	Init_I2C();						// Initialization I2C communication with Photon Board
    	while (1) {
    
    
    		hal_timer_init(32768);
    		radio_receive_on();
    		if(radio_wait_for_idle(1024) < 1024) {
    			rx_length = TX_BUF_SIZE;
    			P2OUT ^= BIT6;
    			radio_read(txBuffer, &rx_length);
    			if(txBuffer[0] == 0x01) {
    				P1OUT ^= BIT5;
    			}
    		}
    		__bis_SR_register(LPM0_bits | GIE);
    		__disable_interrupt();
    	}
    	//_no_operation();
    
    }
    /*---------------------------------------------------------------------------------
     * --------------------------- Initialization SPI ---------------------------
     * --------------------------------------------------------------------------------
     */
    void Init_SPI_Radio(void) {
    	// Configure USCI_B1 for SPI operation
    	UCB1CTLW0 = UCSWRST;                    // **Put state machine in reset**
    	UCB1CTLW0 |= UCSYNC | UCCKPL | UCMSB;   // 3-pin, 8-bit SPI slave
    	// Clock polarity high, MSB
    	UCB1CTLW0 |= UCSSEL__SMCLK;             // SMCLK
    	UCB1BRW = 0x02;                         // /2
    	//UCB1MCTLW = 0;                        // No modulation
    	UCB1CTLW0 &= ~UCSWRST;                  // **Initialize USCI state machine**
    	UCB1IE |= UCRXIE;                       // Enable USCI_B1 RX interrupt
    }
    
    
    /*---------------------------------------------------------------------------------
     * --------------------------- Initialization Radio Register ---------------------------
     * --------------------------------------------------------------------------------
     */
    void Init_Radio(void) {
    	radio_init(3);
    
    	radio_set_freq(FREQUENCY);
    
    	set_rf_packet_length(TX_BUF_SIZE);
    
    }
    
    
    
    /*---------------------------------------------------------------------------------
     * --------------------------- Initialization Timer --------------------------
     * --------------------------------------------------------------------------------
     */
    void Init_TimerA(void) {
    	//Start timer in continuous mode sourced by SMCLK
    	TA0CCTL0 = CCIE;                        						// TACCR0 interrupt enabled
    	TA0CCR0 = (CHECK_MSEC_TA * 32768 ) / 1000;							// Counting time
    	TA0CTL = TASSEL__ACLK | MC__UP; 								// ACLK, up_down mode
    }
    
    void Init_TimerB(void) {
    	//Start timer in continuous mode sourced by SMCLK
    	TB0CCTL0 = CCIE;                        						// TACCR0 interrupt enabled
    	TB0CCR0 = (CHECK_MSEC_TB * 32768 ) / 1000;							// Counting time
    	TB0CTL = TASSEL__ACLK | MC__UP; 								// ACLK, up_down mode
    }
    //******************************************************************************
    //
    //This is the Timer B0 interrupt vector service routine.
    //
    //******************************************************************************
    #pragma vector=TIMER0_B0_VECTOR
    __interrupt void TIMER0_B0_ISR (void)
    {
    	if(UCB2TXBUF == TXData){
    		P1OUT ^= BIT0;
    	}
    	if(TA0CCTL0 |= CCIFG){
    		P1OUT ^= BIT1;
    	}
    	if (FR_OK){
    		P2OUT ^= BIT6;
    	}
    	__bic_SR_register(LPM0_bits);
    
    }
    
    //******************************************************************************
    //
    //This is the Timer A0 interrupt vector service routine.
    //
    //******************************************************************************
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void TIMER0_A0_ISR (void)
    {
    	TA0CCTL0 &= ~CCIFG;
    
    	volatile unsigned char buttonState = 0x0E;
    	currentState = (P3IN & 0x0E);
    	if (currentState != buttonState){
    		count++;
    		if (count >= 4){			// <-- fix this
    			buttonState = currentState;
    			if (currentState != 0){
    				buttonPressed = 1;
    			}
    			count = 0;
    		}
    	} else {
    		count = 0;
    		buttonPressed = 0;
    	}
    	__bic_SR_register(LPM0_bits);
    	//P1OUT ^= BIT1;
    }
    
    
    /*---------------------------------------------------------------------------------
     * --------------------------- Initialization GPIO --------------------------------
     * --------------------------------------------------------------------------------
     */
    
    void Init_GPIO(void){
    	// Configure GPIO
    	P7SEL0 |= BIT0 | BIT1;
    	P7SEL1 &= ~(BIT0 | BIT1);
    
    	// Configure Button RGY and LED
    
    	P3DIR = ~(BIT1 + BIT2 + BIT3);		// Set input P3.1,2,3
    	P3OUT |= BIT1 + BIT2 + BIT3;		// Set pull-up resistor
    	P3REN |= BIT1 + BIT2 + BIT3;		// Enable internal resistor at P3.1,2,3
    	P3IE |= BIT1 + BIT2 + BIT3;			// P3.1,2,3 Interrupt Enable
    	P3IES &= ~(BIT1 + BIT2 + BIT3);		// P3.1,2,3 Hi/Lo edge
    	P3IFG &= ~(BIT1 + BIT2 + BIT3);		// Clear Flag
    
    	P1DIR |= BIT1 + BIT0 + BIT5;
    	P1OUT = 0x00;
    	P2DIR |= BIT5 + BIT6;
    	P2OUT = 0x00;
    
    	P5SEL1 &= ~(BIT0 | BIT1 | BIT2);        // USCI_B1 SCLK, MOSI, and MISO pin
    	P5SEL0 |= (BIT0 | BIT1 | BIT2);
    	// Set PJ.4 and PJ.5 as Primary Module Function Input, LFXT.
    	GPIO_setAsPeripheralModuleFunctionInputPin(
    			GPIO_PORT_PJ,
    			GPIO_PIN4 + GPIO_PIN5,
    			GPIO_PRIMARY_MODULE_FUNCTION
    	);
    
    	// Disable the GPIO power-on default high-impedance mode to activate
    	// previously configured port settings
    	PM5CTL0 &= ~LOCKLPM5;				// or PMM_unlockLPM5;
    }
    
    
    /*---------------------------------------------------------------------------------
     * --------------------------- Initialization Clock ---------------------------------
     * --------------------------------------------------------------------------------
     */
    
    void Init_CLK(void) {
    	// Set DCO frequency to 8 MHz
    	CS_setDCOFreq(CS_DCORSEL_0, CS_DCOFSEL_6);
    	//Set external clock frequency to 32.768 KHz
    	CS_setExternalClockSource(32768, 0);
    	//Set ACLK=LFXT
    	CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); // CS_LFXTCLK_SELECT,CS_VLOCLK_SELECT
    	// Set SMCLK = DCO with frequency divider of 1
    	CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    	// Set MCLK = DCO with frequency divider of 1
    	CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    	//Start XT1 with no time out
    	CS_turnOnLFXT(CS_LFXT_DRIVE_3);
    }
    
    
    And this is the repo if you want to pull it down and test it
    https://github.com/alextran1502/Embedded101

    Thank you very much,
    Alex

  • I don't see where you are sending 'a' or checking to see if you received 'a'.
  • Keith,

    This is where I send, It is on line 44 of the TX side

                txBuffer[0] = 0x01;
                //for (ii = 0; ii < TX_BUF_SIZE - 1; ii++) txBuffer[ii + 1] = 0;
    
                radio_send(txBuffer, TX_BUF_SIZE);
    

    Is there any step I MUST do before and after sending a packet?

    Thanks,

    Alex

  • 0x01 is not 'a'.
  • Keith,

    I was sending a dummy data. Would it make a different? More over, can you help me look over the sequence to see if it is right?

    Thanks,
    Alex
  • Alex,

    Here is a proof of concept that I got working on my station.  TX:

    #include <stdint.h>
    #include "radio_drv.h"
    #include "cc1x_utils.h"
    #include "cc1101_def.h"
    #include "hal_spi_rf.h"
    #include "hal_timer.h"
    
    // Global Variables
    
    #define TX_BUF_SIZE 1
    #define FREQUENCY   902750
    unsigned char txBuffer[TX_BUF_SIZE];
    
    // Global Functions
    
    void Init_CLK(void);
    void Init_Radio(void);
    void Init_GPIO(void);
    
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
        Init_GPIO();
    
        Init_CLK();
        Init_Radio();
    
        while (1)
        {
    
                hal_timer_init(8000);
    
    
                txBuffer[0] = 0x01;
                //for (ii = 0; ii < TX_BUF_SIZE - 1; ii++) txBuffer[ii + 1] = 0;
    
                radio_send(txBuffer, TX_BUF_SIZE);
                radio_wait_for_idle(0);         // 0 = no timeout, just wait
    
                radio_receive_on();
                hal_timer_stop();
    
                P1OUT ^= (BIT0);
                __delay_cycles(4000000);
                P1OUT ^= (BIT0);
                __delay_cycles(4000000);
    
        }
    }
    
    //--------------------------- Init CLK -----------------------------//
    
    void Init_CLK(void) {
    
        CSCTL0_H = CSKEY_H;
        CSCTL1 = DCOFSEL_6;                                     // Set DCO = 8Mhz
        CSCTL2 = SELA__VLOCLK + SELM__DCOCLK + SELS__DCOCLK;
        CSCTL3 = DIVA__1 + DIVS__1 + DIVM__1;
    
    }
    
    //--------------------------- Init Radio -----------------------------//
    
    void Init_Radio(void){
    
        radio_init(3);
    
        radio_set_freq(FREQUENCY);
    
        set_rf_packet_length(TX_BUF_SIZE);
    
    }
    
    //--------------------------- Init GPIO -----------------------------//
    
    void Init_GPIO(void) {
    
        P1DIR |= BIT0;
        P1OUT &= ~BIT0;
        PM5CTL0 &= ~LOCKLPM5;
    }

    RX:

    #include <msp430.h>
    #include <stdint.h>
    #include "cc1101_def.h"
    #include "radio_drv.h"
    #include "cc1x_utils.h"
    #include "hal_spi_rf.h"
    #include "hal_timer.h"
    
    #define TX_BUF_SIZE 1
    #define FREQUENCY   902750
    /*---------------- Global Variables ---------------------*/
    unsigned short rx_length;
    unsigned char txBuffer[TX_BUF_SIZE];
    /******************************************************************************
     * LOCAL VARIABLES */
    
    int main(void)
    {
    
        WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
    
        CSCTL0_H = CSKEY_H;
        CSCTL1 = DCOFSEL_6;                         // Set DCO = 8Mhz
        CSCTL2 = SELA__VLOCLK + SELM__DCOCLK + SELS__DCOCLK;  // set ACLK = VLO
                                                              // MCLK=SMCLK=DCO
    
        P1DIR |= BIT0;
        P1OUT &= BIT0;
        PM5CTL0 &= ~LOCKLPM5;
    
        /* initialize the radio subsystem */
        radio_init(3);
    
        /* configure the rx frequency to 902750 */
        radio_set_freq(902750);
    
        // Set the packet length to a fixed packet size
        set_rf_packet_length(TX_BUF_SIZE);
    
        while(1)
        {
            unsigned char txBuffer[TX_BUF_SIZE];
            /* configure the timer for a 1 second tick */
            hal_timer_init(32768);
    
            /* Initialize the RX chain, receive packet */
            radio_receive_on();
    
            // wait until end_of_packet is found, no timeout
            //status = radio_wait_for_idle(640);
    
            if(radio_wait_for_idle(1024) < 1024)
            {
                rx_length = TX_BUF_SIZE;
                radio_read(txBuffer, &rx_length);         // read content of FIFO
    
                if(txBuffer[0] == 0x01) P1OUT ^= BIT0;
    
            }
            else
            {
                // Check to see if we have lost the connection and we need to stop and hold
                radio_idle();                          // force idle and flush fifos
                // if max_wait == 0 that means we are waiting for first sync burst to appear
            }
    
        }
    }

    See if you can get this working and then add your additional functions.

    Regards, Ryan

  • Ryan,

    Thank you so much! I see it working. However, I cannot detect the frequency using spectrum analyzer, if I am not mistaken, it is transmitting on 902.75 MHz, correct?
  • That is correct.

    Regards,
    Ryan

**Attention** This is a public forum