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.

[参考译文] CC1201:CC1201:监听模式-接收和校准

Guru**** 2500925 points
Other Parts Discussed in Thread: CC1201

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1013554/cc1201-cc1201-sniff-mode---receiving-and-calibration

器件型号:CC1201

大家好、

在我的应用中、电池供电的应答器(从设备)应通过无线电与有线远程站(主设备)通信。 CC1201用作两侧的射频芯片。

为了能够以节能的方式工作、从器件应在发送每条消息后的大约500ms 内以监听模式运行、以便能够接收确认或命令。 主器件发送的前导码为30字节。

问题1.)
如何在从器件上设置监听模式、以便能够接收到每条消息?

当从发送模式更改为监听模式时、合成器(SCAL)和 RC 振荡器(WOR_CFG0.RC_MODE = 0x02)始终会进行校准。 合成器校准通常失败、因为未建立 marcstate "idle"。 相反、读取状态0x11 (RX_FIFO_ERROR)。

问题2.)
为什么校准不会运行而没有错误?

问题3.)
在某些情况下、主器件的回答是否太早?

寄存器设置(默认):

/* default register set */
CC1201_REG_ENTRY(PREAMBLE_CFG1    , 0x14),
CC1201_REG_ENTRY(PREAMBLE_CFG0    , 0x8A),
CC1201_REG_ENTRY(IQIC             , 0xD8),
CC1201_REG_ENTRY(CHAN_BW          , 0x08),
CC1201_REG_ENTRY(MDMCFG1          , 0x40),
CC1201_REG_ENTRY(MDMCFG0          , 0x05),
CC1201_REG_ENTRY(SYMBOL_RATE2     , 0xA4),
CC1201_REG_ENTRY(SYMBOL_RATE1     , 0x7A),
CC1201_REG_ENTRY(SYMBOL_RATE0     , 0xE1),
CC1201_REG_ENTRY(AGC_REF          , 0x2A),
CC1201_REG_ENTRY(AGC_CS_THR       , 0xF6),
CC1201_REG_ENTRY(AGC_GAIN_ADJUST  , 0x00),
CC1201_REG_ENTRY(AGC_CFG3         , 0xB1),
CC1201_REG_ENTRY(AGC_CFG2         , 0x20),
CC1201_REG_ENTRY(AGC_CFG1         , 0x12),
CC1201_REG_ENTRY(AGC_CFG0         , 0x80),
CC1201_REG_ENTRY(FIFO_CFG         , 0x00),
CC1201_REG_ENTRY(DEV_ADDR         , 0x00),
CC1201_REG_ENTRY(SETTLING_CFG     , 0x0B),
CC1201_REG_ENTRY(FS_CFG           , 0x12),
CC1201_REG_ENTRY(WOR_CFG1         , 0x08),
CC1201_REG_ENTRY(WOR_CFG0         , 0x21),
CC1201_REG_ENTRY(WOR_EVENT0_MSB   , 0x00),
CC1201_REG_ENTRY(WOR_EVENT0_LSB   , 0x00),
CC1201_REG_ENTRY(RXDCM_TIME       , 0x00),
CC1201_REG_ENTRY(PKT_CFG2         , 0x00),
CC1201_REG_ENTRY(PKT_CFG1         , 0x42),
CC1201_REG_ENTRY(PKT_CFG0         , 0x20),
CC1201_REG_ENTRY(RFEND_CFG1       , 0x0F),
CC1201_REG_ENTRY(RFEND_CFG0       , 0x00),

在这里、我的当前代码:

void EnterSniffMode(void)
{
    cc1201.timeoutCalib = false;  // flag: calibration timeout
    TimerStart(&TimeoutCalib, OnSignalTimeoutCalib, 10, TIMER_TYPE_ONESHOT, TIMER_CONTEXT_MAINLOOP);

    cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_SYNTH;


    /* set sniff-mode configuration */
    SetRegisterValue(CC1201_REG_WOR_CFG0_RC_PD,                   0);
    SetRegisterValue(CC1201_REG_WOR_EVENT0_MSB_EVENT0_15_8,       0x00);
    SetRegisterValue(CC1201_REG_WOR_EVENT0_LSB_EVENT0_7_0,        0x54);

    SetRegisterValue(CC1201_REG_SETTLING_CFG_FS_AUTOCAL,          0);
    SetRegisterValue(CC1201_REG_AGC_CS_THR_AGC_CS_TH,             8);
    SetRegisterValue(CC1201_REG_AGC_CFG1_AGC_WIN_SIZE,            0);
    SetRegisterValue(CC1201_REG_AGC_CFG1_AGC_SETTLE_WAIT,         0);
    SetRegisterValue(CC1201_REG_RFEND_CFG0_TERM_ON_BAD_PACKET_EN, 1);
    SetRegisterValue(CC1201_REG_RFEND_CFG0_ANT_DIV_RX_TERM_CFG,   1);
    SetRegisterValue(CC1201_REG_FS_DIG1_FS_DIG1_RESERVED5_0,      7);
    SetRegisterValue(CC1201_REG_FS_DSM1_FS_DSM1_RESERVED2_0,      2);
    SetRegisterValue(CC1201_REG_FS_DVC1_FS_DVC1_RESERVED7_0,      0xF3);
    SetRegisterValue(CC1201_REG_FS_DVC0_FS_DVC0_RESERVED4_0,      0x13);
    SetRegisterValue(CC1201_REG_FS_VCO0_FS_VCO0_RESERVED7_0,      0xB8);

    ChipConfigurate();

    /* start calibration of synthesizer */
    Cc1201Strobe(CC1201_STROBE_SCAL);
    cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_SYNTH;
}

void ExecuteSniffMode(void)
{
    switch (cc1201.sniff_state)
    {
        case STATE_SNIFF_WAIT_CALIB_SYNTH:
        {
            /* wait for calibration of synthesizer */
            if (CheckMarcstate(CC1201_MARCSTATE_IDLE))
            {
                /* start calibration of rc osc (SWRA428A, page 6) */
                uint8_t tmp = 0;

                Cc1201Read(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp));
                tmp &= ~(0x03 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos);    // RC_MODE = 0
                tmp |= (0x02 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos);     // RC_MODE = 2
                Cc1201Write(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp));

                Cc1201Strobe(CC1201_STROBE_SIDLE);

                tmp &= ~(0x03 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos);    // RC_MODE = 0
                Cc1201Write(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp));

                cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_RCOSC;

                cc1201.timeoutCalib = 0;
                TimerStart(&TimeoutCalib, OnSignalTimeoutCalib, 10, TIMER_TYPE_ONESHOT, TIMER_CONTEXT_MAINLOOP);
            }
            else if (cc1201.timeoutCalib)
            {

                /* ignore calibration */

/* **************************** */
/* this case enters very often! */
/* **************************** */


                cc1201.timeoutCalib = 0;
                TimerStart(&TimeoutCalib, OnSignalTimeoutCalib, 10, TIMER_TYPE_ONESHOT, TIMER_CONTEXT_MAINLOOP);
            }
        }
        break;

        case STATE_SNIFF_WAIT_CALIB_RCOSC:
        {
            /* wait for calibration of rc osc */
            if (CheckMarcstate(CC1201_MARCSTATE_IDLE))
            {
                /* clear previous reception */
                ClearEvent(CC1201_EVENT_RECEIVED);

                /* start rx for sniff mode */
                Cc1201Strobe(CC1201_STROBE_SWOR);

                cc1201.sniff_state = STATE_SNIFF_WAIT_RX;
            }
            else if (cc1201.timeoutCalib)
            {
                /* ignore calibration */
                Cc1201Strobe(CC1201_STROBE_SWOR);
                cc1201.sniff_state = STATE_SNIFF_WAIT_RX;
            }
        }
        break;

        case STATE_SNIFF_WAIT_RX:
        {
            /* wait for reception */
            if (Machine.EventMask & CC1201_EVENT_RECEIVED)
            {
                ClearEvent(CC1201_EVENT_RECEIVED);

                HandleReception();

                Cc1201Strobe(CC1201_STROBE_SCAL);
                cc1201.sniff_state = STATE_SNIFF_WAIT_CALIB_SYNTH;
            }
            else if (cc1201.txqueue.busy)
            {
                // go to machine state STATE_SEND
            }
        }
    }
}

有人可以帮帮我吗? 非常感谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您输入的 RX FIFO 错误似乎没有得到正确处理。 您始终需要通过清除 FIFO (SFRX 和/或 SFTX)来响应 FIFO 错误。

    此外、我不明白为什么每次进入监听模式时都需要更改寄存器、因为您可以在 TX 中使用相同的设置。

    另一件事是、校准不需要任何超时、因为没有任何东西可以阻止校准完成。

    要正确配置监听模式,应使用 SmartRF Studio,请选择要使用的设置和“RX 监听模式”选项卡。 您可以在此处配置 RSSI 阈值、前导码长度等

    您的代码应执行如下操作:

    // Init MCU
    // Unit Radio with sniff mode settings from SmartRF Studio
    
    while(1)
    {
        // Calibrate radio
        trxSpiCmdStrobe(CC120X_SCAL);
        
        // Wait for calibration to be done (radio back in IDLE state)
        do {
            cc120xSpiReadReg(CC120X_MARCSTATE, &marcState, 1);
        } while (marcState != 0x41);
        
        // Calibrate the RCOSC
        calibrateRCOsc();
    
    	// Write a packet to the TX FIFO 
    
        // Enter TX Mode
        trxSpiCmdStrobe(CC120X_STX);
        
        // Wait for packet to be sent (Packet sent interrupt)
        
        // Enter Sniff mode
        trxSpiCmdStrobe(CC120X_SWOR);
        
        // Wait for packet to be received or for a 500 ms timeout
        
        // If packet received, read packet from RX FIFO. 
        // Here you should also check for RX FIFO errors, 
        // and flush the RX FIFO if an error has occurred
    }
    
    

    BR

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Siri、

    感谢您的回答。

    [引用 userid="2957" URL"~/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1013554/cc1201-cc1201-sniff-mode---receiving-and-calibration/3746335 #3746335"]此外,我不明白为什么每次进入监听模式时都需要更改寄存器,因为您可以在 TX 中使用相同的设置。

    我在 cc1201周围写了一个状态机、它应该是芯片内部状态机的副本。 因此、我无法发送 State_Sniff。 我更改了状态机、以便我也可以在"接收状态"下发送。 这还消除了在发送和接收之间(循环)写入完整配置的必要。

    [引用 userid="2957" URL"~/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1013554/cc1201-cc1201-sniff-mode---receiving-and-calibration/3746335 #3746335"]另一件事是,校准没有任何超时,因为没有任何东西可以阻止校准完成。

    我还省去了超时处理。 由于未达到 MARCSTATE_IDLE、我将其包括在内。 原因是进入了 MARC_State_RX_FIFO_ERR。 我现在已经由选通 SFRX 处理了这个问题。

    我的源代码当前如下所示:

    static void OnEnterSniff(struct SStateMachine *sm)
    {
        /* set sniff-mode configuration */
        AGC_CS_THR    = 0xF7;   /* -90dBm (value from SmartRF-Studio) */
        AGC_CFG1      = 0x00;   /* value from SmartRF-Studio */
        WOR_CFG0      = 0x20;   /* value from SmartRF-Studio */
        WOR_EVENT0    = 0x0054; /* value from SmartRF-Studio */
        SETTLING_CFG  = 0x03;   /* value from SmartRF-Studio */
        RFEND_CFG0    = 0x09;   /* value from SmartRF-Studio */
        FS_DIG1       = 0x07;   /* value from SmartRF-Studio */
        FS_DSM1       = 0x00;   /* value from SmartRF-Studio */
        FS_DVC1       = 0xFF;   /* value from SmartRF-Studio */
        FS_DVC0       = 0x17;   /* value from SmartRF-Studio */
        FS_VCO0       = 0xB5;   /* value from SmartRF-Studio */
    
        ChipConfigurate();
    
        cc1201.sniff_state = STATE_SNIFF_CALIB_SYNTH_START;    /* start calibration of synthesizer */
    }
    
    static void OnExecuteSniff(struct SStateMachine *sm)
    {
        switch (cc1201.sniff_state)
        {
            case STATE_SNIFF_CALIB_SYNTH_START:        /* start calibration of synthesizer */
                OnExecuteSniff_CalibSynthStart();
                //break;
    
            case STATE_SNIFF_CALIB_SYNTH_WAIT:         /* wait for calibration of synthesizer */
                OnExecuteSniff_CalibSynthWait();
                //break;
    
            case STATE_SNIFF_CALIB_RCOSC_START:        /* start calibration of rc oscillator */
                OnExecuteSniff_CalibRcoscStart();
                //break;
    
            case STATE_SNIFF_CALIB_RCOSC_WAIT:         /* wait for calibration of rc oscillator */
                OnExecuteSniff_CalibRcoscWait();
                //break;
    
            case STATE_SNIFF_RX_WAIT:                  /* wait for reception */
                OnExecuteSniff_RxWait();
                break;
        }
    }
    
    static void OnExecuteSniff_CalibSynthStart(void)
    {
        Cc1201Strobe(CC1201_STROBE_SCAL);
    }
    
    static void OnExecuteSniff_CalibSynthWait(void)
    {
        uint8_t marcstate = 0;
    
        Cc1201Read(Cc1201RegAddrTab[CC1201_REG_MARCSTATE].addr, &marcstate, sizeof(marcstate));
        marcstate &= 0x1F;
    
        switch (marcstate)
        {
            case CC1201_MARCSTATE_IDLE:
    			cc1201.sniff_state = STATE_SNIFF_CALIB_RCOSC_START;
    			break;
    
            case CC1201_MARCSTATE_TX_FIFO_ERR:
    			Cc1201Strobe(CC1201_STROBE_SFTX);
    			break;
    
            case CC1201_MARCSTATE_RX_FIFO_ERR:
    			Cc1201Strobe(CC1201_STROBE_SFRX);
    			break;
    
            case CC1201_MARCSTATE_REG_SETTLE_MC:
    			/* nothing to be done! (still calibrating) */
    			break;
        }
    }
    
    static void OnExecuteSniff_CalibRcoscStart(void)
    {
        /* start calibration of rc osc (SWRA428A, page 6) */
        uint8_t tmp = 0;
    
        Cc1201Read(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp));
        tmp &= ~(0x03 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos);    // RC_MODE = 0
        tmp |= (0x02 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos);     // RC_MODE = 2
        Cc1201Write(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp));
    
        Cc1201Strobe(CC1201_STROBE_SIDLE);
    
        tmp &= ~(0x03 << Cc1201RegDescTab[CC1201_REG_WOR_CFG0_RC_MODE].pos);    // RC_MODE = 0
        Cc1201Write(CC1201_REG_WOR_CFG0, &tmp, sizeof(tmp));
    
        cc1201.sniff_state = STATE_SNIFF_CALIB_RCOSC_WAIT;
    }
    
    static void OnExecuteSniff_CalibRcoscWait(void)
    {
        uint8_t marcstate = 0;
    
        Cc1201Read(Cc1201RegAddrTab[CC1201_REG_MARCSTATE].addr, &marcstate, sizeof(marcstate));
        marcstate &= 0x1F;
    
        switch (marcstate)
        {
            case CC1201_MARCSTATE_IDLE:
                cc1201.sniff_state = STATE_SNIFF_RX_WAIT;
    
                ClearEvent(CC1201_EVENT_RECEIVED);
                Cc1201Strobe(CC1201_STROBE_SWOR);
                break;
    
            case CC1201_MARCSTATE_TX_FIFO_ERR:
                Cc1201Strobe(CC1201_STROBE_SFTX);
                break;
    
            case CC1201_MARCSTATE_RX_FIFO_ERR:
                Cc1201Strobe(CC1201_STROBE_SFRX);
                break;
        }
    }
    
    static void OnExecuteSniff_RxWait(void)
    {
        if (DataReceived())    /* wait for reception */
        {
            HandleReception();
            cc1201.sniff_state = STATE_SNIFF_CALIB_SYNTH_START;
        }
        else if (cc1201.isSending)    /* waiting for finish transmission ? */
        {
            OnUpdateSending();
        }
        else if (cc1201.txqueue.busy)    /* waiting for data to be sent ? */
        {
            OnSendData();
        }
    }
    
    /**
     * @brief OnExitSniff exits machine state STATE_SNIFF
     * @param sm          pointer to state machine instance
     */
    static void OnExitSniff(struct SStateMachine *sm)
    {
        /* restore default configuration */
    }

    不幸的是、我没有收到每一条消息。 请参阅以下范围:

    Yello:发送器处的天线信号
    红色:GPIO0 (PKT_SYNC_RxTx)
    蓝色:GPIO2 (PQT_VALID)
    绿色:GPIO3 (WOR_EVENT0)

    为什么在 有标记的情况下 cc1201不设置 GPIO0 (PKT_SYNC_RxTx)? EVENT0上升到前导码中间(发送30字节)。
    为了仔细检查这种情况、我有一张来自逻辑器件的图片、它触发了相同的情况:

    CC1201_GPIO0是射频芯片上的信号(与上面的示波器红色通道相同)
    通道9是来自 CC1201评估板的相同信号、由 SmartRF-Studio 驱动。 (底线)

    如您所见、评估板通过 GPIO0发出"响应"接收信号、但我的应用板没有!

    是否有任何解释?

    此致、
    Andy

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好、Andy

    如果我理解正确、您已经制作了自己的硬件、使用此硬件、您无法接收数据包、但在 TI 的硬件上使用相同的软件、则您可以接收。 是这样吗?

    如果您已经制作了自己的硬件、我强烈建议您在开始使用监听模式等构建复杂软件之前验证硬件是否正常

    您应该使用 SmartRF Studio 设置发送器、以便使用其中一个默认设置永久传输数据包。

    在您的硬件上、您应该执行以下操作进行非常简单的测试:

    • 初始化 MCU
    • 使用与 SmartRF Studio 相同的设置初始化无线电
    • Strobe SRX

    监视 PKT_SYNC_RxTx。 您是否能够通过这种方法接收任何内容?

    如果是、请继续在 SmartRF Studio 和代码中更改设置、直到您在应用中具有要使用的射频设置。

    如果您仍然能够接收所有数据包,请开始实施监听模式。

    调试时、您应该在连续 TX 中设置发送器、然后在电路板和 TI 硬件上读取 RX 中的 RSSI。 如果您的设计有问题、则 RSSI 可能低于预期、因此在使用监听模式时、您不会收到任何内容。

    BR

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Siri、

    没错:我有自己设计的硬件。 同时、我将使用 TI 的 CC1201EM-868-930 (修订版1.1.1)和 SmartRF Studio。

    [引用 userid="2957" URL"~/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1013554/cc1201-cc1201-sniff-mode---receiving-and-calibration/3747948 #3747948"]监控 PKT_SYNC_RxTx。 您是否能够通过此方法接收任何内容?[/QUERT]

    我已经完成了这项测试、我可以接收主器件发送的每条消息。 就在"监听模式"下、我遇到了一些问题。

    从昨天起、我的硬件上的 CC1201似乎也会接收到每条消息。 SCAL 正在运行时出现时序问题。 但是、我的软件中似乎也存在一个问题、我实际上正在搜索该问题。

    主 shell 以最大前导码发送(前导码_CFG1.NUM_PREAMBLE = 30字节)。 如果我正确、则应配置从器件

    • WOR_EVENT0:0x5B (= 30字节(240位)- PQT_VALID 超时(11个符号))
    • WOR_CFG1.EVENT1:4 (= 100µs Ω)

    您建议使用哪种设置来设置嗅探模式?

    此致、
    Andy

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如前所述、我建议您使用 SmartRF Studio 为您提供的监听模式设置。 您无需自行设置。

    我注意到您的 CS 阈值非常高。 从发送器接收时、您是否确定 RSSI 高于-73 dBm?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Siri、

    感谢您的所有帮助。 监听模式现在是"启动并运行"。 我必须进行测试和(perhabs)以进行一些微调、但总的来说、这是在做的!

    [引用 userid="2957" URL"~/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1013554/cc1201-cc1201-sniff-mode---receiving-and-calibration/3748074 #3748074">我注意到您的 CS 阈值非常高。 从发送器接收时、您是否确定 RSSI 高于-73dBm?[/QUERP]

    SmartRF-Studio 的模板"100kbps、2-GFSK、ETSI 标准(868MHz)"建议在监听模式下为-90dBm。 用户手册说明:

     CS 阈 值  应 设置得足够高、以便在仅存在背景噪声时 CS 失效、并设置得足够低、以便在存在所需信号时 CS 有效。

    因此、我认为我必须使用该参数。

    此致、
    Andy