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.

CC1125 frequency registers NOT change

Other Parts Discussed in Thread: CC1125

Hello everybody.

I am working with the CC1125 transceiver, connected via SPI with an Atmel microcontroller (ATxmega256).

Atmel provides source files to access the CC1125 registers and configure them. The file I use is similar to this one. In my case, in the function trx_config I write to the registers:

/**
 * @brief Configures the transceiver
 *
 * This function is called to configure the transceiver after reset.
 */
static void trx_config(void)
{
    /*
     * Configuration of CSMA seed is done later in function trx_config_csma()
     * after the generation of a proper random seed for function rand();
     */

    pal_trx_reg_write(IOCFG3,0x06);
    pal_trx_reg_write(IOCFG2,0x0F);
    pal_trx_reg_write(IOCFG1,0xB0);
    pal_trx_reg_write(IOCFG0,0x06);
    pal_trx_reg_write(SYNC_CFG1,0x0B);

    pal_trx_reg_write(MODCFG_DEV_E,0x02);
    pal_trx_reg_write(DEVIATION_M,0xA3);

(continue...)

Function pal_trx_reg_write is located in this file and it reproduced here:

/**
 * @brief Writes data into a transceiver register
 *
 * This function writes a value into transceiver register.
 *
 * @param addr Address of the trx register
 * @param data Data to be written to trx register
 *
 */
void pal_trx_reg_write(uint8_t addr, uint8_t data)
{
    ENTER_TRX_REGION();

#ifdef NON_BLOCKING_SPI
    while (spi_state != SPI_IDLE)
    {
        /* wait until SPI gets available */
    }
#endif

    /* Prepare the command byte */
    addr |= WRITE_ACCESS_COMMAND;

    /* Start SPI transaction by pulling SEL low */
    SS_LOW();

    /* Send the Read command byte */
    SPDR = addr;
    SPI_WAIT();

    /* Write the byte in the transceiver data register */
    SPDR = data;
    SPI_WAIT();

    /* Stop the SPI transaction by setting SEL high */
    SS_HIGH();

    LEAVE_TRX_REGION();
}

The initialization of registers is OK just after transceiver reset. But if I want to change the registers values later (e.g. carrier frequency), the SPI write operation fails. That is to say, I write a certain value, then read the register and the value is different (wrong).

Thanks in advance for your help!

  • I assume that when you do initialization you manage to read back correct values from the chip. Reading out PARTVERSION and PARTNUMBER is a good test to see if the SPI read works.

    Where in your code do you try to set the FREQ word? Is the radio in IDLE?
  • I assume that when you do initialization you manage to read back correct values from the chip. Reading out PARTVERSION and PARTNUMBER is a good test to see if the SPI read works. 

    At this moment I cannot check this registers. But I have tried to write -> wait a moment -> and then read the register and it works OK.

    ___________________________

    Where in your code do you try to set the FREQ word? Is the radio in IDLE?

    The frequency change is made in file tal_pib.c, in function tal_pib_set (it is too long to paste here). The parameter is called 'phyCurrentChannel' (line #421 of previous indicated file). This is the fragment:

    (...)
                    case phyCurrentChannel:
                        if (tal_state != TAL_IDLE)
                        {
                            return TAL_BUSY;
                        }
                        if ((uint32_t)TRX_SUPPORTED_CHANNELS & ((uint32_t)0x01 << value->pib_value_8bit))
                        {
                            tal_trx_status_t previous_trx_status = TRX_OFF;
                            /*
                             * Set trx to "soft" off avoiding that ongoing
                             * transaction (e.g. ACK) are interrupted.
                             */
                            if (tal_trx_status != TRX_OFF)
                            {
                                previous_trx_status = RX_AACK_ON;   /* any other than TRX_OFF state */
                                do
                                {
                                    /* set TRX_OFF until it could be set;
                                     * trx might be busy */
                                } while (set_trx_state(CMD_TRX_OFF) != TRX_OFF);
                            }
                            tal_pib_CurrentChannel = value->pib_value_8bit;
                            pal_trx_bit_write(SR_CHANNEL, tal_pib_CurrentChannel);
                            /* Re-store previous trx state */
                            if (previous_trx_status != TRX_OFF)
                            {
                                /* Set to default state */
                                set_trx_state(CMD_RX_AACK_ON);
                            }
                        }
                        else
                        {
                            return MAC_INVALID_PARAMETER;
                        }
                        break;
    (...)

  • As far as I can see this is some functions taken from Atmels 802.15.4 MAC. It's not possible for me to see how this code actually sets the FREQ registers. Please provide a plot of the SPI bus traffic writing and reading back the FREQ registers.
  • At this moment I can not measure the SPI bus to check data.

    Which state should be the transceiver? The 'tal_pib_set' function checks if TAL is idle:

    typedef enum tal_state_tag
    {
        TAL_IDLE           = 0,
        TAL_ACK_PRE_TX     = 1,
        TAL_ACK_TX         = 2,
        TAL_TX_AUTO        = 3,
        TAL_TX_WAIT_ACK    = 4,
        TAL_TX_RETRY       = 5,
        TAL_TX_DONE        = 6,
        TAL_SLOTTED_CSMA   = 7,
        TAL_ED_RUNNING     = 8,
        TAL_ED_DONE        = 9
    } SHORTENUM tal_state_t;

    And it checks the transceiver commands:

    /** Transceiver commands */
    typedef enum trx_cmd_tag
    {
        /** Reset chip */
        SRES                        = (0x30),
        
        /** Enable and calibrate frequency synthesizer */
        SFSTXON                     = (0x31),
        
        /** Enter XOFF state when CSn is de-asserted */
        SXOFF                       = (0x32),
        
        /** Calibrate frequency synthesizer and turn it off */
        SCAL                        = (0x33),
        
        /** Enable RX */
        SRX                         = (0x34),
        
        /** Enable TX */
        STX                         = (0x35),
        
        /** Exit RX/TX, turn off frequency synthesizer and exit eWOR mode if applicable */
        SIDLE                       = (0x36),
        
        /** Automatic Frequency Compensation */
        SAFC                        = (0x37),
        
        /** Start automatic RX polling sequence (eWOR) */
        SWOR                        = (0x38),
        
        /** Enter SLEEP mode when CSn is de-asserted */
        SPWD                        = (0x39),
        
        /** Flush the RX FIFO. Only issue SFRX in IDLE or RX_FIFO_ERR states */
        SFRX                        = (0x3A),
        
        /** Flush the TX FIFO. Only issue SFTX in IDLE or TX_FIFO_ERR states */
        SFTX                        = (0x3B),
        
        /** Reset the eWOR timer to the Event1 value */
        SWORRST                     = (0x3C),
        
        /** No operation. May be used to get access to the chip status byte */
        SNOP                        = (0x3D)
    } SHORTENUM trx_cmd_t;

    I guess transceiver must be awake to change registers...

  • Jose,

    I think for us to be of any help you will need to produce a plot of what is on the SPI bus between the two devices.

    Regards,
    /TA
  • Hello,

    Now the registers changes work. I think it was a problem of transceiver status (it must be idle and awake).

    Regards,
    Jose A.