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.

Issue in setting up the RF link cc1101

Other Parts Discussed in Thread: CC1101, MSP430F5529, TEST2

Hi,

 I have established RF link between CC1101 evaluation module <--> CC debugger <--> SmartRF Studio (PC) as transmitter node and CC1101 evaluation modue <--> CC1101DK433 Development kit <--> SmartRF Studio (PC)  at the receiver node. I am able to transmit and receive packets and able to confirm the same using SmartRF studio. 

   Now, I want to use MSP430F5529 launchpad<--> CC1101 Evaluation module at the TX side with the same receiver setup at the RX side. I have successfully interfaced the microcontroller with the RF module via SPI channel and I'm able to read/write registers. Also I can strobe STX and can see the peaks in the spectrum for BFSK scheme using spectrum analyzer. But I'm unable to receive the data at the RX mode. I have used the same RF settings that has been generated by the SmartRF studio while using CC debugger at the TX side. I have attached the block diagram of the scenario for reference. It would be of great help if someone can help me in providing suggestions with this regard.

  • - Could you post the spectrum you see and state which datarate and deviation you are using? Use lowest possible RBW to clearly show the modulation.
    - Try to set up the receiver with 0xAA as sync word and turn on carrier sense if required. Use fix length packet and "RF device commands" in SmartRF Studio to see what you are actually sending. Test this with the working transmitter first.
    - If you have trouble with the TX FIFO you could be sending just a preamble, if this is the case you will see it on the spectrum (compare with the working transmitter)
    - See www.ti.com/.../swra109c.pdf and processors.wiki.ti.com/.../Perf_value_line_easylink on how to send a packet using the FIFO.
  • Thanks for the reply!

    Please find the image of the spectrum below. The RF specs are:

    Carrier Frequency: 403.5 MHz

    Deviation: 10 kHz

    TX power: 0 dBm

    data rate: 1kBaud

    Please find the code below:

    #include <msp430.h> 
    #include "config_registers.h"
    
    
    int SLV_DATA[25] = {0};
    int ALL_DATA[47]={0};
    int status = 0;
    int status1 = 0;
    
    int MST_DATA[25] = {IOCFG2_DATA, IOCFG0_DATA, PKTCTRL1_DATA, PKTCTRL0_DATA, ADDR_DATA, FSCTRL1_DATA, FREQ2_DATA, FREQ1_DATA, MDMCFG4_DATA, MDMCFG3_DATA, MDMCFG2_DATA,
    					MDMCFG1_DATA, MDMCFG0_DATA, DEVIATN_DATA, MCSM1_DATA, MCSM0_DATA, FOCCFG_DATA, WORCTRL_DATA, FREND0_DATA, FSCAL3_DATA,
    					FSCAL2_DATA, FSCAL1_DATA, FSCAL0_DATA, TEST2_DATA, TEST1_DATA};
    
    //CC1101 register values
    int MST_REG[25] = {IOCFG2_ADDR, IOCFG0_ADDR, PKTCTRL1_ADDR, PKTCTRL0_ADDR, ADDR_ADDR, FSCTRL1_ADDR, FREQ2_ADDR, FREQ1_ADDR,MDMCFG4_ADDR, MDMCFG3_ADDR, MDMCFG2_ADDR, MDMCFG1_ADDR, MDMCFG0_ADDR, DEVIATN_ADDR, MCSM1_ADDR, MCSM0_ADDR, FOCCFG_ADDR, WORCTRL_ADDR,
    				 	FREND0_ADDR, FSCAL3_ADDR, FSCAL2_ADDR, FSCAL1_ADDR, FSCAL0_ADDR, TEST2_ADDR, TEST1_ADDR};
    
    int ALL_REG[47]={  IOCFG2_ADDR,
    				   IOCFG1_ADDR,
    		IOCFG0_ADDR,
    		FIFOTHR_ADDR,
    		SYNC1_ADDR,
    		SYNC0_ADDR,
    		PKTLEN_ADDR,
    		PKTCTRL1_ADDR,
    		PKTCTRL0_ADDR,
    		ADDR_ADDR,
    		CHANNR_ADDR,
    		FSCTRL1_ADDR,
    		FSCTRL0_ADDR,
    		FREQ2_ADDR,
    		FREQ1_ADDR,
    		FREQ0_ADDR,
    		MDMCFG4_ADDR,
    		MDMCFG3_ADDR,
    		MDMCFG2_ADDR,
    		MDMCFG1_ADDR,
    		MDMCFG0_ADDR,
    		DEVIATN_ADDR,
    		MCSM2_ADDR,
    		MCSM1_ADDR,
    		MCSM0_ADDR,
    		FOCCFG_ADDR,
    		BSCFG_ADDR,
    		AGCCTRL2_ADDR,
    		AGCCTRL1_ADDR,
    		AGCCTRL0_ADDR,
    		WOREVT1_ADDR,
    		WOREVT0_ADDR,
    		WORCTRL_ADDR,
    		FREND1_ADDR,
    		FREND0_ADDR,
    		FSCAL3_ADDR,
    		FSCAL2_ADDR,
    		FSCAL1_ADDR,
    		FSCAL0_ADDR,
    		RCCTRL1_ADDR,
    		RCCTRL0_ADDR,
    		FSTEST_ADDR,
    		PTEST_ADDR,
    		AGCTEST_ADDR,
    		TEST2_ADDR,
    		TEST1_ADDR,
    		TEST0_ADDR };
    
    //RF Data
    char RF_DATA[5] = {0xD2, 0x2D, 0xD2,0x2D, 0xD2};
    char RF_DATA_len = 5;
    char RF_DATA_ADDR = 0x67;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
        config_CLOCK();
        SPI_SETUP();
        CC1101_RST();
        CC1101_init();
      	SPI_REG_WRITE(PKTLEN_ADDR, 5);
      	SPI_REG_WRITE(PATABLE_ADDR, 0x1D);
        // Reading the set registers
          int k;
              	for(k = 0; k < 25; k++)
             	{
             		SLV_DATA[k] = SPI_REG_READ(MST_REG[k]);
             		__delay_cycles(80);
             	}
    
           int q;
            for(q = 0; q < 48; q++)
             {
              	  ALL_DATA[q] = SPI_REG_READ(ALL_REG[q]);
              	  __delay_cycles(80);
             }
    
            SPI_STROBE(SIDLE);
            status = SPI_REG_READ(SIDLE);
            SPI_STROBE(SFTX);
            status = SPI_REG_READ(SFTX);
    
            //while(1)
            int p;
            for(p=0;p<2000;p++)
            {
            	SendPacket(RF_DATA, RF_DATA_len);
            }
    
    
    
    }
    
    void config_CLOCK(void)  //SMCLK CONFIGURAATION
    {
      volatile unsigned int i;
    
      P1DIR |= BIT1;                            // P1.1 output
      P1DIR |= BIT0;                            // ACLK set out to pins
      P1SEL |= BIT0;
      P2DIR |= BIT2;                            // SMCLK set out to pins
      P2SEL |= BIT2;
      P7DIR |= BIT7;                            // MCLK set out to pins
      P7SEL |= BIT7;
    
      UCSCTL3 = SELREF_2;                       // Set DCO FLL reference = REFO
      UCSCTL4 |= SELA_2;                        // Set ACLK = REFO
      UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
    
      // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                                // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
      }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
      __bis_SR_register(SCG0);                  // Disable the FLL control loop
      UCSCTL1 = DCORSEL_5;                      // Select DCO range 16MHz operation
      UCSCTL2 |= 249;                           // Set DCO Multiplier for 8MHz
                                                // (N + 1) * FLLRef = Fdco
                                                // (249 + 1) * 32768 = 8MHz
      __bic_SR_register(SCG0);                  // Enable the FLL control loop
    
      // Worst-case settling time for the DCO when the DCO range bits have been
      // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
      // UG for optimization.
      // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
      __delay_cycles(250000);
    
      }
    
    void SPI_SETUP(void)  //SPI initialization
    {
        UCB0CTL1 |= UCSWRST;                            //set software reset to 1 so we can configure SPI
    
        //UCB0STAT |= UCLISTEN;                           //the launchpad listens to itself (use for testing)
        UCB0CTL0 |= UCCKPH+UCMSB + UCMST + UCSYNC;    //clkphase,clkpolarity,MSBfirst,8-bit,master mode, 3-pin, synchronous SPI
        UCB0CTL1 |= UCSSEL_2;                           //choose SMCLK as our clock. SMCLK is 1.1 MHz. We divise it with the baud register
        UCB0BR0 |= 0x02;                                //Baud rate is 1.1MHZ/(2+1) = 366 KHz
        UCB0BR1 = 0;                                    //upper byte of br register. set to zero
        P8SEL |= BIT2;
        P8DIR &= ~BIT2;
        P3SEL |= BIT7;
        P3DIR &= ~BIT7;
        P3SEL |= (BIT0 | BIT1 | BIT2);          //configures pins for three pin SPI. MISO P1.1, MOSI P1.2, CLK P1.4
        P2SEL |= BIT6;                //P2.6 CS
        P3DIR |= BIT0+BIT2;       //3.0-MOSI, 3.2-SCLK OUTPUT
        	P2DIR |= BIT6;				//2.7 output (CS)
        	P3DIR &= ~BIT1;             //3.1 MISO INPUT
        	P2OUT |= BIT6;				//CS high
        UCB0CTL1 &= ~UCSWRST;                   //enables the SPI to work
    
    
        UCB0IE |= UCTXIE+UCRXIE;                        // Enable USCI0 RX interrupt
    
    }
    
    void CC1101_RST(void)  //Reset CC1101
    
    {   //8 CYCLES = 1 us
    	P2OUT &= ~BIT6;							//CS = low
    	__delay_cycles(40);                    //5us delay
    	P2OUT |= BIT6;							//CS high
    	__delay_cycles(280);                    //35us delay
    	P2OUT &= ~BIT6;							//CS = low
    	while (!(UCB0IFG & UCTXIFG));					//Wait till transmit buffer is empty
    	UCB0IFG &= ~(UCRXIFG);                                         //Erase RX-Flag of previous Byte
    	UCB0TXBUF= SRES;							//Strobe command for Chip Reset
    	while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
    	UCB0IFG &= ~(UCRXIFG); 						//Erase RX-Flag of previous Byte
    	while(P3IN & SPI_SOMI);						//Wait till SO = low //GOES TO INTERRUPT ROUTINE
    	P2OUT |= BIT6;							//CS high
    }
    
    void CC1101_init(void) //Configuration of CC1101
    {
    int k1 = 0;
    	for(k1 = 0; k1 < 25; k1++)
    	{
    		SPI_REG_WRITE(MST_REG[k1], MST_DATA[k1]);
    		__delay_cycles(8); //20 us delay
    	}
    }
    
    void SPI_REG_WRITE(char tx_addr, char tx_data) //Function for SPI writing of registers
    
    {
    	P2OUT &= ~BIT6;							//CS = low
    	while(P3IN & SPI_SOMI);						//Wait till SO = low
    	while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
    		__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
    	UCB0TXBUF = tx_addr;						//Send register address  [GOES TO INTERRUPT FUNCTION]
    	while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
    	while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
    		__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
    	UCB0TXBUF = tx_data;						//Send Data
    	while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
    	while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
    	__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);					//Wait till whole word is received (SO status byte)
    	P2OUT |= BIT6;							//CS = high for acknowledgement
    }
    
    char SPI_REG_READ(char reg_addr) //Function for SPI reading of registers
    {
    	char rx_data;
    
    	P2OUT &= ~BIT6;							//CS = low
    	while(P3IN & SPI_SOMI);						//Wait till SO = low
    	while (!(UCB0IFG & UCTXIFG));						//Wait till UTXBUF is empty (UTXIFG1 = 1)
       __delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
    	UCB0TXBUF  = (reg_addr | 0x80);					//Send addresse + R/W bit = 1 for read operation
    	while (!(UCB0IFG & UCTXIFG));						//Wait till UTXBUF is empty (UTXIFG1 = 1)
    	while (!(UCB0IFG & UCRXIFG));						//Wait till whole word is received (SO status byte)
    		__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);							//Erase RX-Flag of previous Byte
    	UCB0TXBUF = 0x00;							//Send dummy bits for read operation
    	status = P8IN & BIT2;
    	while (!(UCB0IFG & UCTXIFG));						//Wait till whole word is received (SO status byte)
    		__delay_cycles(80);
    	rx_data = UCB0RXBUF;						//Read Data
    	P2OUT |= BIT6;							//CS = high for acknowledgement
    	return rx_data;
    }
    
    void SPI_STROBE(char strobe)
    {
    	P2OUT &= ~BIT6;							//CS = low
    	while(P3IN & SPI_SOMI);						//Wait till SO = low
    	while (!(UCB0IFG & UCTXIFG));						//Wait till UTXBUF is empty (UTXIFG1 = 1)
    	__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
    	//IFG2 &= ~UTXIFG1;						//Erase TX-Flag of previous Byte
    	UCB0TXBUF = strobe;						//Send register address
    	while (!(UCB0IFG & UCTXIFG));						//Wait till whole word is received (SO status byte)
    	__delay_cycles(80);
    	while (!(UCB0IFG & UCRXIFG));						//Wait till whole word is received (SO status byte)
    	__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);					//Erase RX-Flag of previous Byte
    	P2OUT |= BIT6;							//CS = high for acknowledgement
    }
    
    char SPI_STATUS_READ(char reg_addr)
    {
    	char rx_data;
    
    	P2OUT &= ~BIT6;							//CS = low
    	while(P3IN & SPI_SOMI);						//Wait till SO = low
    	while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
    	__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);					//Erase RX-Flag of previous Byte
    	UCB0TXBUF = (reg_addr | 0xC0);
    	while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
    	__delay_cycles(80);
    	while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
    	__delay_cycles(80);
    	UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
    	UCB0TXBUF = 0x00;							//Send dummy bits for read operation
    	while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
    	__delay_cycles(80);
    	rx_data = UCRXIFG;						//Read Data
    	P2OUT |= BIT6;							//CS = high for acknowledgement
    	return rx_data;
    }
    void SPI_BURST_WRITE(char addr,char *buffer, char count)
    {
        unsigned char i;
        P2OUT &= ~BIT6;							//CS = low
        while(P3IN & SPI_SOMI);						//Wait till SO = low
        while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
        __delay_cycles(80);
        UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
        UCB0TXBUF = addr|BURST;						//Send register address  [GOES TO INTERRUPT FUNCTION]
        while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
        while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
        __delay_cycles(80);
        UCB0IFG &= ~(UCRXIFG);						//Erase RX-Flag of previous Byte
    
        for(i=0;i<count;i++)
        {
        UCB0TXBUF = buffer[i];						//Send Data
        }
        while (!(UCB0IFG & UCTXIFG));					//Wait till UTXBUF is empty (UTXIFG1 = 1)
        while (!(UCB0IFG & UCRXIFG));					//Wait till whole word is received (SO status byte)
        __delay_cycles(80);
        UCB0IFG &= ~(UCRXIFG);					//Wait till whole word is received (SO status byte)
        P2OUT |= BIT6;							//CS = high for acknowledgement
     }// WriteBurstReg
    void RFSend(char *tx_buffer, char length, char address)
    {
    
    
    	    int i;
    		int k;
    		k = length - 1;
    		SPI_REG_WRITE(FIFO, length); 					//Write packetlength to TX FIFO if variable packetlength is activated
    		SPI_REG_WRITE(FIFO, address);					//Write address to TX FIFO if address check is activated
    		for(i = 0; i < k; i++)						//Write data to TX FIFO
    		{
    			SPI_REG_WRITE(FIFO, tx_buffer[i]);
    		}
    	SPI_STROBE(STX);
    	status = SPI_REG_READ(STX);
    	status = P8IN & BIT2;
    	//status = SPI_REG_READ(STX);
    	//while (!(P8IN & BIT2));  // Wait for GDO0 to be set -> sync transmitted
    	//while (P8IN & BIT2); // Wait for GDO0 to be cleared -> end of packet
       // status = SPI_REG_READ(STX);
    	SPI_STROBE(SIDLE);
    	status = SPI_REG_READ(SIDLE);
    }
    
    void SendPacket(char *txBuffer,  char size)
    {
        unsigned char i;
    
        for (i = size; i > 0; i--)
         txBuffer[i] = txBuffer[i-1];
        txBuffer[0] = size;
        SPI_BURST_WRITE(FIFO, txBuffer, size+1);
    
        SPI_STROBE(SIDLE);
        status = SPI_REG_READ(SIDLE);
        SPI_STROBE(STX);
        status = SPI_REG_READ(STX);
     }
    

    The settings are taken from SmartRF Studio:

    #ifndef CONFIG_REGISTERS_H_
    #define CONFIG_REGISTERS_H_
    
    #define IOCFG2_ADDR 0x00
    #define IOCFG1_ADDR 0x01
    #define IOCFG0_ADDR 0x02
    #define FIFOTHR_ADDR 0x03
    #define SYNC1_ADDR 0x04
    #define SYNC0_ADDR 0x05
    #define PKTLEN_ADDR 0x06
    #define PKTCTRL1_ADDR 0x07
    #define PKTCTRL0_ADDR 0x08
    #define ADDR_ADDR 0x09
    #define CHANNR_ADDR 0x0A
    #define FSCTRL1_ADDR 0x0B
    #define FSCTRL0_ADDR 0x0C
    #define FREQ2_ADDR 0x0D
    #define FREQ1_ADDR 0x0E
    #define FREQ0_ADDR 0x0F
    #define MDMCFG4_ADDR 0x10
    #define MDMCFG3_ADDR 0x11
    #define MDMCFG2_ADDR 0x12
    #define MDMCFG1_ADDR 0x13
    #define MDMCFG0_ADDR 0x14
    #define DEVIATN_ADDR 0x15
    #define MCSM2_ADDR 0x16
    #define MCSM1_ADDR 0x17
    #define MCSM0_ADDR 0x18
    #define FOCCFG_ADDR 0x19
    #define BSCFG_ADDR 0x1A
    #define AGCCTRL2_ADDR 0x1B
    #define AGCCTRL1_ADDR 0x1C
    #define AGCCTRL0_ADDR 0x1D
    #define WOREVT1_ADDR 0x1E
    #define WOREVT0_ADDR 0x1F
    #define WORCTRL_ADDR 0x20
    #define FREND1_ADDR 0x21
    #define FREND0_ADDR 0x22
    #define FSCAL3_ADDR 0x23
    #define FSCAL2_ADDR 0x24
    #define FSCAL1_ADDR 0x25
    #define FSCAL0_ADDR 0x26
    #define RCCTRL1_ADDR 0x27
    #define RCCTRL0_ADDR 0x28
    #define FSTEST_ADDR 0x29
    #define PTEST_ADDR 0x2A
    #define AGCTEST_ADDR 0x2B
    #define TEST2_ADDR 0x2C
    #define TEST1_ADDR 0x2D
    #define TEST0_ADDR 0x2E
    
    #define IOCFG2 0x29
    #define IOCFG1 0x2E
    #define IOCFG0 0x06
    #define FIFOTHR 0x07
    #define SYNC1 0xD3
    #define SYNC0 0x91
    #define PKTLEN 0x01
    #define PKTCTRL1 0x04
    #define PKTCTRL0 0x05
    #define ADDR 0x00
    #define CHANNR 0x00
    #define FSCTRL1 0x06
    #define FSCTRL0 0x00
    #define FREQ2 0x0F
    #define FREQ1 0x84
    #define FREQ0 0xEC
    #define MDMCFG4 0x15
    #define MDMCFG3 0x83
    #define MDMCFG2 0x03
    #define MDMCFG1 0x23
    #define MDMCFG0 0x7A
    #define DEVIATN 0x34
    #define MCSM2 0x07
    #define MCSM1 0x30
    #define MCSM0 0x18
    #define FOCCFG 0x16
    #define BSCFG 0x6C
    #define AGCCTRL2 0x03
    #define AGCCTRL1 0x40
    #define AGCCTRL0 0x91
    #define WOREVT1 0x87
    #define WOREVT0 0x6B
    #define WORCTRL 0xFB
    #define FREND1 0x56
    #define FREND0 0x10
    #define FSCAL3 0xE9
    #define FSCAL2 0x2A
    #define FSCAL1 0x00
    #define FSCAL0 0x1F
    #define RCCTRL1 0x41
    #define RCCTRL0 0x00
    #define FSTEST 0x59
    #define PTEST 0x7F
    #define AGCTEST 0x3F
    #define TEST2 0x88
    #define TEST1 0x31
    #define TEST0 0x0B
    
    //General declarations
    #define SPI_SOMI 0x02
    #define SPI_SIMO 0x01
    #define SPI_CLK 0x04
    #define CS 0x80
    #define RWbit 0x80
    #define BURST 0x40
    #define RX_OK 0x00
    #define RX_LENGTH_VIOLATION 0x01
    #define RX_CRCMISMATCH 0x10
    #define RX_FIFO_OVERFLOW 0x11
    #define GDO0 0x01
    
    //CC1101 Power Settings Register
    #define PATABLE_ADDR 0x3E
    
    //Various Status Register
    #define RXBYTES 0x3B
    #define MARCSTATE 0x35
    #define PKTSTATUS 0x38
    #define TXBYTES 0x3A
    
    //CC1101 command strobes
    #define SRES 0x30			//Chip Reset
    #define SFSTXON 0x31			//Enable and calibrate frequency synthesizer
    #define SXOFF 0x32			//Turn Off OSC
    #define SCAL 0x33			//Calibrate frequency synthesizer
    #define SRX 0x34			//Enable RX
    #define STX 0x35			//Enable TX
    #define SIDLE 0x36			//Exit RX/TX, go to idle mode
    #define SWOR 0x38			//Start automatic polling sequence
    #define SPWD 0x39			//Enter power down mode
    #define SFRX 0x3A			//Flush RX FIFO
    #define SFTX 0x3B			//Flush TX FIFO
    #define SWORRST 0x3C			//Reset real time clock
    #define SNOP 0x3D			//no operation
    #define MARCSTATE 0x35
    
    //Address of FIFO
    #define FIFO 0x3F
    
    //SPI functions
    void SPI_SETUP(void);
    void SPI_REG_WRITE(char tx_addr, char tx_data);
    char SPI_REG_READ(char reg_addr);
    void SPI_STROBE(char strobe);
    char SPI_STATUS_READ(char reg_addr);
    void initLED(void);                                 //initializes led so we can toggle it
    void CC1101_RST(void);
    void config_CLOCK(void);
    void CC1101_init(void);
    void RFSend(char *tx_buffer, char length, char address);
    #endif /* CONFIG_REGISTERS_H_ */
    

    One more issue is that after transmission, it doesn't come back to the IDLE state. I have set MCSM1 ro 0x30. 

  • Hi Vignesh,

    Do you calibrate CC1101 in your MPS430?

    CC1101 should be calibrated before start TX or RX.

    BR,

    Jack

  • Hi Jack,

    Thanks for the reply!

    I have configured MCSM0.FS_AUTOCAL[1:0] = 01 so that it automatically calibrates when going from IDLE to TX or RX

  • I briefly looked at your MDMCFG settings and they give the following
    Data rate: 1.2 kbps
    Deviation: +/-5.16 kHz
    RX filter BW: 650 kHz

    Why are you using such a large RX filter BW? Do you have a large crystal tolerance in your system?

    Your IF frequency (FSCTRL1 register) is approx 150 kHz and this is too low for RX BW of 650 kHz.

    I assume you have used 1.2 kBaud "typical settings" as a starting point to generate the settings. If you change the system parameters (e.g RX filter BW, deviation, data rate, modulation, ....) manually under "RF parameters" some registers (e.g FREND1, AGCCTRL, FSCTRL1....) will not change. Only those registers that are calculated based on your manual entry (e.g MDMCFG when changing data rate and RX filter BW) will change. FREND1, AGCCTRL, FSCTRL1 and a few other registers settings are not calculated by SmartRF Studio, but they still need to be set according to the RX BW used.

    What you need to do is to select the "typical setting", which has the same or greater RX filter BW than you are going to use as the FREND1, AGCCTRL, FSCTRL1, FIFOTHR, TEST2, and TEST1 settings to use depend on the RX BW. As an example, assuming the desired RX BW is 650 kHz you should start with the the 500 kbps preferred setting (812 kHz RX BW) and change the data rate, deviation, RX BW, and modulation format manually you get the right settings.
  • Did you test with SmartRF Studio what you are actually sending?
  • Thanks for the suggestion Sverre

    I'll follow the procedure that you have mentioned to see if the RF link is working. But for the same set of register values, the RF link is established for CC debugger based TX as shown in the figure in previous post. Should register mismatch be the issue? The thing that I'm skeptical about is packet formation at TX side.

    I did a small experiment with the following setup operating in fixed length mode( PKTCTRL0. LENGTH_CONFIG[1:0]=0).

    Using SmartRF studio, I first sent a single byte which needs to be transmitted using Packet TX command tab. I found that if this byte is greater than decimal 64, there is no reception at the RX side. If it is less than decimal 64, the RX receives a random byte with the expected power level. Further, if I increase the number of bytes at TX, the RX assumes that the first byte is length field, discards second byte(I assume that 2nd byte is considered as address field), reads the number of bytes after the second byte that is equal to the length (first byte) and always receives a random last byte. I made fixed length mode in both TX and RX side. So does that mean that in fixed length mode too, I need to add length fields ? The data sheet says that in fixed packet length mode, the length entirely depends on PKTLEN register value. 

    And in regard with writing to FIFO, I don't use burst write function. Since it is FIFO, I assume that the address pointer automatically increments each time I write to the FIFO address (0x3F)

  • TER,

    I checked it in SmartRF Studio using CC debugger but not with the MSP430 microcontroller setup

    - If you have trouble with the TX FIFO you could be sending just a preamble, if this is the case you will see it on the spectrum (compare with the working transmitter)

    How can the spectrum be different for preamble transmission and packet transmission? Both will show two peaks corresponding to f1 and f2 for BFSK. Do you mean that preamble transmission will show continuous peaks without any fluctuation and packets will have a fluctuation since its not a continuous transmission?

  • Hi Sverre,
    I tried the RF settings as per your suggestion. Still it is the same. I'm not receiving anything at RX.
  • Hi Sverre,
    Your reply was very much helpful in generating the register values. I am able to establish the RF link in asynchronous serial mode. However, I still face issue in setting up the link in packet handing mode. Since the only difference between asynchronous and packet handler is the use of FIFO buffer from the firmware point of view, I suspect the issue with the FIFO buffer. I used TXBYTES to read the FIFO and it shows 0x4F. What does it mean
  •  

    It is not only the use of the FIFO that is different between the modes. The register settings are not the same either (use typical settings from SmartRF Studio). Reading 0x4F from the TXBYTES register means that you have written 79 bytes to the TX FIFO.

    Please take a look at the example code we have for the cc1101. It shows how to transmit a packet via the FIFO:

    http://www.ti.com/lit/zip/swrc021

    http://processors.wiki.ti.com/index.php/Perf_value_line_easylink

    Siri

  • In the example CC1101 on trxEB for IAR, packetcounter is added to every packet. Is it compulsory?
  • The sequence number is optinal and is just added since SmartRf Studio uses it.

    It is just a part of the payload and can be replaced/removed.

    The only thing that is important is that the numbers of byte written to the TXFIFO after the length byte is equal to the length byte:

    ex: 5, 1, 2, 3, 4, 5

    if you write: 5, 1, 2, 3, 4 the TX FIFO will underflow

    If you write:

    5, 1, 2, 3, 4, 5, 6, the last byte (6) will be left in the FIFO after the packet (5, 1, 2, 3, 4, 5) has been sent on the air.

    Siri

     

     

  • Thank you very much for the explanation!
    I haven't used interrupts for confirmation of packet being sent. I'm adding that part to my code now and see if the link works.

    Thanks
  • HI,

    the issue has been resolved. upon checking the SPI waveforms, I came to know that the CSn signal is always low. Since it always remains low, it allowed me to perform read/write operations. Upon changing the configurations, I was able to see the transitions in GDO0 pin(configured as 0x06) as well as the RF link is established in packet mode. Just for knowing the reason, can you explain if cs signal plays a role in writing to FIFO/sending sync words or packet transmission.

    Thanks
  • Hi

    If you do a burst write, as you typically do to the TX FIFO, and then strobe STX, you must pull CSn high between the burst access to the FIFO and the STX strobe. If not, the radio do not know that the STX strobe is a strobe command and not just another byte written to the FIFO.

    Siri