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.

CC1120: There is a communication problem between the CC1120 boards.

Part Number: CC1120

hello. experts

I am a person who wants to use the CC1120 for wireless communication.
I seem to be asking a lot of questions lately, but I'm really sorry. 
There is nowhere to turn for help.
I am trying to communicate between the currently developed CC1120 module board (TX) and booster pack (RX). (Figure 1.)

- Figure 1. development environment -

The development board (green) transmits the frequency loaded with data, and the booster pack (red) receives this data to check on the smart RF.

As a result of the execution, it was confirmed that the frequency loaded with data was being received in the Continous RX of Smart RF.
(Figure 2.)
- Figure 2. SmartRF Continuous RX screen
 

As a result of conducting the same experiment using two Boosterpacks before, the Continuous RX screen of SMART RF came out as shown in Figure 2,

and the data sent from the TX side appeared on the screen in Packet RX.

But now the packet I sent is not displayed on the packet rx screen.
The packet sent is the example packet shown in the userguide 49pg(Figure 3.).

- Figure 3. Example packet

I think the way to write the data to the tx fifo is wrong.

The code for writing data to the tx fifo is attached, 
so I would be very grateful if you could tell me if the process of loading data on the frequency is correct and if you have any other good opinions.
Thank you so much for reading.
- Kim -


void User_Guide_Packet_Create()
{
int i=0;

int j=0;

uint8_t packet[] = {0xAA,0xAA,0xAA,0xAA,0x93,0x0B,0x51,0xDE,0x54,0x61,0xE2,0x9A,0xF9,0x9D};

printf("--------- Create Packet -----------\r\n");
for(i=0;i<PKTLEN+1;i++)
{
printf("0x%02x ", packet[i]);
}
printf("\r\n");

while(1)
{
// SIDLE (Write 0x01,IDLE status enable)
Resgister_Write(0x00, 0x36, 0x01);

// Write packet to the txfifo
Resgister_Write(0x00, 0x3F, packet[j]);

// STX (write 0x01, TX status enable)
Resgister_Write(0X00, 0X35, 0X01);

j++;

if(i>PKTLEN)
{
j=0;
}
}
}
  • First of all, please be specific regarding the HW you use.

    If the two boards are boards bought from TI, please provide a link so that we know exactly what boards you are using.

    If you have made HW yourself, please post the link to the reference design you have used when developing the boards.

    If I understand correctly, you have a boards that runs from SmartRF Studio on the RX side, and then you run your own code on the TX side, is that correct?

    What register settings are you using in Studio and in your own code?

    How are you initializing the CC1120 before you try to transmit?

    Why do you write the preamble and sync word to the radio when this is normally added automatically by the CC1120?

    I have no knowledge as to what your “Resgister_Write” functions does so I cannot say if the code is OK or not (how does the function differs between sending a strobe command and doing a burst write to the FIFO?)

    I also so not understand how you are actually testing anything? If you want to receive a packet with SmartRF Studio, you cannot use Cont. RX, but need to use the Packet RX mode.

    I strongly recommend that you look at the

    TX code example found here:

    https://www.ti.com/lit/zip/swrc253

    The steps necessary to transmit a packet that can be received with SmartRF Studio are the following:

    uint8 txBuffer[] = {0x05, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; // Length byte = 5
                                                             // Payload = A1 A2 A3 A4 A5
    
    // Init MCU
    initMCU();
    
    // Init Radio (use register exported from SmartRF Studio from the mode used by the RX)
    registerConfig();
    
    cc112xSpiWriteTxFifo(txBuffer, sizeof(txBuffer)); // Write 6 bytes to the TX FIFO using burst mode
    
    trxSpiCmdStrobe(CC112X_STX);
    
    // Wait for packet to be sent (use an interrupt or check for example MARCSTATE)

    Siri

  • First of all thank you for your reply.

    Here is my answer to your question.

    1. As you said, you are right that I have a board running in SmartRF Studio and running my own code on the TX side.

    2. The RX side board was purchased from ti and the link is as follows.

    link : www.ti.com/.../BOOSTXL-CC1120-90

    3. The board on the TX side is a board developed by myside and the circuit diagram is as attached File 1. Circuit Diagram
    The board is designed to control the CC1120 chip with the STM32L151CMT6 MCU

    4. "Register Write" is as below, and actionbyte selects whether to write single (0x00) or burst (0x40).
    register_byte is the register address to write the value, and value_byte is the value to be written to the register.

    void Resgister_Write(uint8_t action_byte, uint8_t register_byte, uint8_t value_byte)
    {
    int i=0;

    uint8_t TX_Data[4] = {0,};

    uint8_t RX_Data[4] = {0,};

    TX_Data[0] = action_byte|register_byte;

    TX_Data[1] = value_byte;

    LL_GPIO_ResetOutputPin(CS_GPIO_Port, CS_Pin);

    for(i=0;i<2;i++)
    {
    while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
    LL_SPI_TransmitData8(SPI1, TX_Data[i]);

    while(!LL_SPI_IsActiveFlag_RXNE(SPI1)) {}
    RX_Data[i]=LL_SPI_ReceiveData8(SPI1);
    }

    LL_GPIO_SetOutputPin(CS_GPIO_Port, CS_Pin);

    printf(">> Write_Data : ");

    for(i=0;i<2;i++)
    {
    printf("0x%02x ", TX_Data[i]);
    }

    printf("\r\n");
    }

    5. The registers of our own code were extracted from SmartRF. At the very bottom, I will attach the code for writing register setting values.


    6. I did initialize the cc1120 before attempting the transfer. To be precise, 0x01 was written to SRES (0x30) of the strobe register before setting the register value.

    7. I didn't know that the CC1120 automatically adds the preface and synchronization words to the radio as the reason for writing the preface and synchronization words automatically added by the CC1120.

    I did my best to answer the questions you asked. If there is something missing, I will add more. Thank you so much for your help.

    * About Answer 5. Resgister setting

    void Freq_Tx ()
    {
    //Reset
    Resgister_Write(0x00, 0x30, 0x01);
    /* -------------------------------- */
    // Register Value Write(R0)
    /* -------------------------------- */
    //CC112X_IOCFG3, 0xB0
    Resgister_Write(0x00,0x00,0xB0);
    //CC112X_IOCFG2, 0x06
    Resgister_Write(0x00, 0x01, 0x06);
    //CC112X_IOCFG1, 0xB0
    Resgister_Write(0x00, 0x02, 0xB0);
    //CC112X_IOCFG10, 0xB0
    Resgister_Write(0x00, 0x03, 0xB0);
    //CC112X_SYNC_CFG1, 0x0B
    // Resgister_Write(0x00, 0x06, 0x0B);
    //CC112X_DCFILT_CFG, 0x1C
    Resgister_Write(0x00, 0x06, 0x0B);
    //CC112X_IQIC, 0xC6
    Resgister_Write(0x00, 0x10, 0xC6);
    //CC112X_CHAN_BW, 0x08
    Resgister_Write(0x00, 0x11, 0x08);
    //CC112X_MDMCFG0, 0x05
    Resgister_Write(0x00, 0x0B, 0x05);
    //CC112X_AGC_REF, 0x20
    Resgister_Write(0x00, 0x17, 0x20);
    //CC112X_AGC_CS_THR, 0x19
    Resgister_Write(0x00, 0x18, 0x19);
    //CC112X_AGC_CFG1, 0xA9
    Resgister_Write(0x00, 0x1C, 0xA9);
    //CC112X_AGC_CFG0, 0xCF
    Resgister_Write(0x00, 0x1D, 0xCF);
    //CC112X_FIFO_CFG, 0x00
    Resgister_Write(0x00, 0x1E, 0x00);
    //CC112X_SETTLING_CFG, 0x03
    Resgister_Write(0x00, 0x20, 0x03);
    //CC112X_FS_CFG, 0x12
    Resgister_Write(0x00, 0x21, 0x1B);
    //CC112X_SYMBOL_RATE2, 0x43
    Resgister_Write(0x00, 0x14, 0x43);
    //CC112X_SYMBOL_RATE1, 0xA9
    Resgister_Write(0x00, 0x15, 0xA0);
    //CC112X_SYMBOL_RATE0, 0x2A
    Resgister_Write(0x00, 0x16, 0x2A);
    //CC112X_PKT_CFG1, 0x05
    Resgister_Write(0x00, 0x27, 0xA9);
    //CC112X_PKT_CFG0, 0x40
    Resgister_Write(0x00, 0x28, 0x2A);
    //CC112X_PA_CFG2, 0x4F
    Resgister_Write(0x00, 0x2B, 0x4F);
    //CC112X_PA_CFG1, 0x56
    Resgister_Write(0x00, 0x2C, 0x56);
    //CC112X_PA_CFG0, 0x1C
    Resgister_Write(0x00, 0x2D, 0x1C);
    //CC112X_PKT_LEN, 0xFF
    Resgister_Write(0x00, 0x2E, 0xFF);
    //CC112X_IF_MIX_CFG, 0x00
    Extend_Resgister_write(0x00, 0x2F, 0x00, 0x00);
    //CC112X_FREQOFF_CFG, 0x22
    Extend_Resgister_write(0x00, 0x2F, 0x01, 0x22);
    //CC112X_FREQ2, 0x6C
    Extend_Resgister_write(0x00, 0x2F, 0x0C, 0x75);
    //CC112X_FREQ1, 0x80
    Extend_Resgister_write(0x00, 0x2F, 0x0D, 0x64);
    //CC112X_FREQ0, 0x00
    Extend_Resgister_write(0x00, 0x2F, 0x0E, 0xCC);
    //CC112X_FS_DIG1, 0x00
    Extend_Resgister_write(0x00, 0x2F, 0x12, 0x00);
    //CC112X_FS_DIG0, 0x5F
    Extend_Resgister_write(0x00, 0x2F, 0x13, 0x5F);
    //CC112X_FS_CAL0, 0x0E
    Extend_Resgister_write(0x00, 0x2F, 0x17, 0x0E);
    //CC112X_FS_DIVTWO, 0x03
    Extend_Resgister_write(0x00, 0x2F, 0x19, 0x03);
    //CC112X_FS_DSM0, 0x33
    Extend_Resgister_write(0x00, 0x2F, 0x1B, 0x33);
    //CC112X_FS_DVC0, 0x17
    Extend_Resgister_write(0x00, 0x2F, 0x1D, 0x17);
    //CC112X_FS_PFD, 0x50
    Extend_Resgister_write(0x00, 0x2F, 0x1F, 0x50);
    //CC112X_FS_PRE, 0x6E
    Extend_Resgister_write(0x00, 0x2F, 0x20, 0x6E);
    //CC112X_FS_REG_DIV_CML, 0x14
    Extend_Resgister_write(0x00, 0x2F, 0x20, 0x6E);
    //CC112X_FS_SPARE, 0xAC
    Extend_Resgister_write(0x00, 0x2F, 0x22, 0xAC);
    //CC112X_XOSC5, 0x0E
    Extend_Resgister_write(0x00, 0x2F, 0x32, 0x0E);
    //CC112X_XOSC3, 0xC7
    Extend_Resgister_write(0x00, 0x2F, 0x34, 0xC7);
    //CC112X_XOSC1, 0x07
    Extend_Resgister_write(0x00, 0x2F, 0x36, 0x07);
    }

  • First of all, when it comes to the schematic, it is not possible to look at that and tell if this is OK or not. Even if the schematic is OK, the layout of the PCB needs to be correct as well when working with RF.

    This is why I asked which reference design you have used as a reference for your HW.

    Assuming that your HW is OK, there are several potential problems with your code:

    When not being familiar with the MCU you are using, I cannot tell from your code if your SPI communication is OK or not.

    Have you verified with a logic analyzer that all your SPI communication is according to spec?

    Why are you using infinite packet length mode?

    If you want to transmit packets to SmartRF Studio, you should use the packet format that SmartRF Studio uses (variable packet length mode).

    You are also not doing calibration of the synth, and the autocal I turned off, and this will make the TX operate on an unknown frequency:

    Again, please use the same settings as given by SmartRF Studio:

    Below is the list of registers that you should write to the CC1120 after reset, to be able to transmit packets to Studio:

    // Address Config = No address check 
    // Bit Rate = 1.2 
    // Carrier Frequency = 868.000000 
    // Deviation = 3.997803 
    // Device Address = 0 
    // Manchester Enable = false 
    // Modulation Format = 2-FSK 
    // PA Ramping = true 
    // Packet Bit Length = 0 
    // Packet Length = 255 
    // Packet Length Mode = Variable 
    // Performance Mode = High Performance 
    // RX Filter BW = 25.000000 
    // Symbol rate = 1.2 
    // TX Power = 15 
    // Whitening = false 
    
    static const registerSetting_t preferredSettings[]= 
    {
    {CC1120_IOCFG3, 0xB0},
    {CC1120_IOCFG2, 0x06},
    {CC1120_IOCFG1, 0xB0},
    {CC1120_IOCFG0, 0x40},
    {CC1120_SYNC_CFG1, 0x0B},
    {CC1120_DCFILT_CFG, 0x1C},
    {CC1120_PREAMBLE_CFG1, 0x18},
    {CC1120_IQIC, 0xC6},
    {CC1120_CHAN_BW, 0x08},
    {CC1120_MDMCFG0, 0x05},
    {CC1120_AGC_REF, 0x20},
    {CC1120_AGC_CS_THR, 0x19},
    {CC1120_AGC_CFG1, 0xA9},
    {CC1120_AGC_CFG0, 0xCF},
    {CC1120_FIFO_CFG, 0x00},
    {CC1120_FS_CFG, 0x12},
    {CC1120_PKT_CFG0, 0x20},
    {CC1120_PKT_LEN, 0xFF},
    {CC1120_IF_MIX_CFG, 0x00},
    {CC1120_FREQOFF_CFG, 0x22},
    {CC1120_FREQ2, 0x6C},
    {CC1120_FREQ1, 0x80},
    {CC1120_FS_DIG1, 0x00},
    {CC1120_FS_DIG0, 0x5F},
    {CC1120_FS_CAL1, 0x40},
    {CC1120_FS_CAL0, 0x0E},
    {CC1120_FS_DIVTWO, 0x03},
    {CC1120_FS_DSM0, 0x33},
    {CC1120_FS_DVC0, 0x17},
    {CC1120_FS_PFD, 0x50},
    {CC1120_FS_PRE, 0x6E},
    {CC1120_FS_REG_DIV_CML, 0x14},
    {CC1120_FS_SPARE, 0xAC},
    {CC1120_FS_VCO0, 0xB4},
    {CC1120_XOSC5, 0x0E},
    {CC1120_XOSC1, 0x03},
    };
    

    I do not understand the loop where you are writing to the FIFO and are strobing IDLE and STX:

    You should only strobe STX once for every packet sent, and you cannot strobe SIDLE in the middle of the packet.

    After configuring the CC1120 with the registers above, you write your complete packet to the TX FIFO, for example 5, 1, 2, 3, 4, 5, and then you strobe STX, and wait for GPIO2 being asserted (sync sent) and then de-asserted (packet sent).

    Below is shown how the SPI trafic looks like when writing to the TX FIFO.

    This is the only thing you need to do, after initialization

    Siri

  • HW: Looking at your schematic indicates that you want to use 160 MHz. But the boosterpack you use for RX has a SAW filter and a frontend that is tuned for 869 MHz and will have very poor performance at 160 MHz? 

  • Thank you for your reply.

    The spi communication has previously been confirmed through a logic analyzer that it complies with the specification.

    And when only the carrier frequency was output without loading data,
    I confirmed that the frequency I wanted was displayed on the spectrum analyzer.
    It probably isn't a matter of writing a value to a register.

    As you said, it seems that the method of sending data is wrong. I didn't know the way you said before.
    I'll give it a try and let you know the result. Thank you very much.

  • Thanks for your reply. The current target carrier frequency is 156.525 MHz.
    If I set the same RX carrier frequency with smartRF in the booster pack, isn't it possible to communicate?
    Is the design of the booster pack itself designed to produce the best performance at 869MHZ?

  • you should not use a 868 Board for operation at 156 MHz.

    I am still confused, because the register settings you have posted is for 868 MHz.

    Also, if you compare recommended register settings for the 1.2 kbps case, you will see that there are more registers that differs between these two frequency bands other than the FREQ registers.

    Siri

  • A stated in previous post: 

    "HW: Looking at your schematic indicates that you want to use 160 MHz. But the boosterpack you use for RX has a SAW filter and a frontend that is tuned for 869 MHz and will have very poor performance at 160 MHz"

    This means that you might or might not be able to have a link.

    It is not something we test or give recommendations for, as a 868 board in not intended for use in the 160 MHz band.

    Siri

  • Thank you very much for your reply. 
    If so, I modified the code to wirte the data into the tx fifo.
    Could you take a look at it? Sorry for bothering you. Relevant functions will be replied below.


    void TI_Packet_Create()
    {
    int i=0;

    int j=0;

    uint8_t gpio2[8];

    uint8_t packet[] = {0xAA,0xAA,0xAA,0xAA,0x93,0x0B,0x51,0xDE,0x54,0x61,0xE2,0x9A,0xF9,0x9D};

    Resgister_Write(0X00, 0X36, 0X01);

    printf("--------- Create Packet -----------\r\n");
    for(i=0;i<PKTLEN+1;i++)
    {
    printf("0x%02x ", packet[i]);
    }
    printf("\r\n");

    printf("1\r\n");

    for(j=0;j<PKTLEN+1;j++)
    {

    Resgister_Write(0x40, 0x3F, packet[j]);
    LL_mDelay(500);
    }

    gpio2[8] = Resgister_read(0x80, 0x01);

    if(gpio2[8] > 0)
    {
    // STX (write 0x01, TX status enable)
    Resgister_Write(0X00, 0X35, 0X01);

    printf("txtx\r\n");
    }

    }




    - Used function code -
    //////////////////////////////////////////////////////////////////////////////////////////////

    void Resgister_Write(uint8_t action_byte, uint8_t register_byte, uint8_t value_byte)
    {
    int i=0;

    uint8_t TX_Data[4] = {0,};

    uint8_t RX_Data[4] = {0,};

    TX_Data[0] = action_byte|register_byte;

    TX_Data[1] = value_byte;

    LL_GPIO_ResetOutputPin(CS_GPIO_Port, CS_Pin);

    for(i=0;i<2;i++)
    {
    while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
    LL_SPI_TransmitData8(SPI1, TX_Data[i]);

    while(!LL_SPI_IsActiveFlag_RXNE(SPI1)) {}
    RX_Data[i]=LL_SPI_ReceiveData8(SPI1);
    }

    LL_GPIO_SetOutputPin(CS_GPIO_Port, CS_Pin);

    printf(">> Write_Data : ");

    for(i=0;i<2;i++)
    {
    printf("0x%02x ", TX_Data[i]);
    }

    printf("\r\n");
    }

    //////////////////////////////////////////////////////////////////////////////////////////////



    uint8_t Resgister_read(uint8_t action_byte, uint8_t register_byte)
    {
    int i=0;

    uint8_t TX_Data[4] = {0,};

    uint8_t RX_Data[2] = {0,};

    TX_Data[0] = action_byte|register_byte;

    LL_GPIO_ResetOutputPin(CS_GPIO_Port, CS_Pin);

    for(i=0;i<2;i++)
    {
    while(!LL_SPI_IsActiveFlag_TXE(SPI1)) {}
    LL_SPI_TransmitData8(SPI1, TX_Data[i]);

    while(!LL_SPI_IsActiveFlag_RXNE(SPI1)) {}
    RX_Data[i]=LL_SPI_ReceiveData8(SPI1);
    }

    LL_GPIO_SetOutputPin(CS_GPIO_Port, CS_Pin);

    printf(">> Read_Data : 0x%02x \r\n", RX_Data[1]);

    return RX_Data[1];
    }


    //////////////////////////////////////////////////////////////////////////////////////////////








  • I am not sure how I can help you further when you are not following my recommendations.

    Why are you writing preamble and sync to the FIFO?

    uint8_t packet[] = {0xAA,0xAA,0xAA,0xAA,0x93,0x0B,0x51,0xDE,0x54,0x61,0xE2,0x9A,0xF9,0x9D};

    Writing the above data to the FIFO, the radio will interpret 0xAA as the length, and it will underflow since you obviously not are trying to transmit a packet that is 170 bytes long.

    I also do not understand this code:

    for(j = 0; j < PKTLEN + 1; j++)
    {
        Resgister_Write(0x40, 0x3F, packet[j]);
        LL_mDelay(500);
    }

    The reason for using burst access is to be able to write all registers in one burst without pulling SCn high  between each byte. Also, why do you have a delay in there?

    Without logic analyzer plots I cannot say anything about your SPI functions, but from the above I can confirm that the radio will underflow, and that SmartRF Studio in packet RX mode will not receive the packet, since it uses packet length filtering

    Siri

  • I am sorry that I did not understand what you said. From what I understand, only data is written to the TX FIFO, and it should be written in single, not burst mode?

  • No.

    Only Data should be written to the FIFO and it should be written as 1 burst.

    You are writing 0xAA,0xAA,0xAA,0xAA,0x93,0x0B,0x51,0xDE,0x54,0x61,0xE2,0x9A,0xF9,0x9D, where I assume that 0xAA,0xAA,0xAA,0xAA is preamble and 0x93,0x0B,0x51,0xDE is sync.

    You should not write preamble and sync to the TX FIFO.

    Please use our code examples as reference

  • thank you very much 
    Finally, the packets we are sending now are the packets referenced in the userguide.



     Is there a way to distinguish between preamble and sync here?
  • What user guide are you referring to?

    The reason I said I assume you are writing the preamble and sync to the TX FIFO, is that 0xAAAAAAAA is the default preamble and 0x930B51DE is the default sync word (in the SYNC registers).

    This is all explained here:

    https://www.ti.com/lit/swru295

    What is the payload you are trying to send?

    Is that: 0x54,0x61,0xE2,0x9A,0xF9,0x9

    If it is, you either need to configure the radio for fixed packet length mode and set the length to 6, 

    or use variable packet length mode, as the settings in Studio does, and then start by writing the length to the TX FIFO.

    If you look at the user guide and the code examples available at TI.com all this is explained/implemented there.

    Siri

  • Sorry for the late reply due to business trip. 
    I think I understand what you mean now and I think I can give it a try. thank you