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.

[参考译文] CC1310:在没有 LP OSC 的情况下动态更改 CAP_array_Delta

Guru**** 2487425 points
Other Parts Discussed in Thread: CC1310, LAUNCHXL-CC1310

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1175626/cc1310-changing-cap_array_delta-on-the-fly-without-a-lp-osc

器件型号:CC1310

您好!

我们在 cc1310中实现了基站无线电模块、该模块可连接到许多对等器件(所有 cc1310)。 我们发现、我们对基站的调优越准确、通信就越好。

对等器件能够使用  OSC_AdjustxoscHfCapArray 功能设置其电容阵列增量、这些器件切换到低功耗模式、从而关闭 HS XOSC; 从低功耗模式唤醒时、HS XOSC 再次打开、以假定新的电容阵列增量。 这很好。

基站器件不需要进入低功耗模式、因此无需低功耗 OSC (使用 HS XOSC 进行低速时钟)即可构建。 这对于他们的大部分日常功能来说似乎是不错的、除了即时调整 CAP 阵列增量。 如果器件未挂起、我们无法关闭和打开 HS XOSC、或者切换从未真正发生、因为切换没有发生。

在播放一些代码片段时、我设法获得了其中的一部分、它似乎改变了电容阵列增量、但在器件的功率周期内它并不总是稳定、并且传输频率可能会变化3-4kHz -如果发生这种情况、它就不会改变 在 ccfg 部分中手动设置电容阵列增量。

是否有办法可靠地实现这一目标?

似乎主要起作用的代码位于此处(主要来自 OSC_AdjustXoscHfCapArray)

void set_cap_array_delta(int8_t capArrDelta)
{
    uint32_t ccfg_ModeConfReg;

    if (capArrDelta < -20)
        capArrDelta = -20;
    if (capArrDelta > 20)
        capArrDelta = 20;

    // read the MODE_CONF register in CCFG
    ccfg_ModeConfReg = HWREG( CCFG_BASE_DEFAULT + CCFG_O_MODE_CONF );
    ccfg_ModeConfReg &= CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M;
    ccfg_ModeConfReg >>= CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_S;

    //
    // No change, then no need to update
    //
    if (( int8_t ) ccfg_ModeConfReg != capArrDelta )
    {
        uint32_t ccfg_Mod;

        // read the MODE_CONF register in CCFG        
        // Clear CAP_MODE and the CAPARRAY_DELATA field
        ccfg_ModeConfReg = HWREG( CCFG_BASE_DEFAULT + CCFG_O_MODE_CONF );
        ccfg_ModeConfReg &= ~( CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M |
                               CCFG_MODE_CONF_XOSC_CAP_MOD_M );

        // Insert new delta value
        ccfg_Mod = ( uint8_t ) capArrDelta;
        ccfg_Mod <<= CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_S;
        ccfg_Mod &= CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M;

        ccfg_ModeConfReg |= ccfg_Mod;

        //
        // Update the HW register with the new delta value
        // Can't seem to use DDI32RegWrite here, call hangs otherwise
        //
        HWREG( AUX_DDI0_OSC_BASE + DDI_0_OSC_O_ANABYPASSVAL1 ) = SetupGetTrimForAnabypassValue1( ccfg_ModeConfReg );

        //
        // Disable Interrupts
        //
        bool fIntDisabled = IntMasterDisable( );

        // Force power on AUX to ensure CPU has access
        AONWUCAuxWakeupEvent( AONWUC_AUX_WAKEUP );
        while( !( AONWUCPowerStatusGet( ) & AONWUC_AUX_POWER_ON )){ }

        // Enable the AUX domain OSC clock and wait for it to be ready
        AUXWUCClockEnable( AUX_WUC_OSCCTRL_CLOCK );
        while( AUXWUCClockStatus( AUX_WUC_OSCCTRL_CLOCK ) != AUX_WUC_CLOCK_READY ){ }

        // 
        // Turn Xosc off and on again, while it doesn't actually do this, the
        // calls still seem to be required
        //
        OSCHF_SwitchToRcOscTurnOffXosc( );       
        OSCHF_TurnOnXosc( );
        while ( !OSCHF_AttemptToSwitchToXosc( ));
        
        // Disable clock for OSC_DIG
        AUXWUCClockDisable( AUX_WUC_OSCCTRL_CLOCK );

        // Release the 'force power' on AUX
        AONWUCAuxWakeupEvent( AONWUC_AUX_ALLOW_SLEEP );

        //
        // Retrim XOSC
        // This is required otherwise the cap array delta is not assumed correctly.
        // after this call, new value is assumed.
        //
        SetupTrimDevice( );

        // Reenable IRQs
        if ( !fIntDisabled )
        {
            IntMasterEnable( );
        }
    }
}

问题可能是 SetupTrimDevice 被多次调用?  

感谢你的任何帮助。

此致、

-奥利弗

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

    今天我有更多的时间、因此我可以用一些真实的数据来演示这个问题。

    我有一个测试应用、使用上述函数(在本例中为-1)应用电容阵列增量、然后输出恒定载波。 每次器件复位(使用编程器上的 EM 复位按钮)并重新启动时、载波跳转到稍微不同的位置。 此处的图像显示了我的频谱分析仪绘制的最大保持时间、以目标频率为中心、超过大约10次复位。  

    如果在 ccfg 中应用相同的电容阵列增量、并且不使用设置动态增量的函数、则不会发生这种情况。 但是、在制造过程中调整 ccfg 并不是一种长期解决方案。  

    希望这能更清楚地解释这个问题。

    此致、

    -奥利弗

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

    我似乎找到了解决不稳定问题的办法,但它显示了另一个可能的问题。

    稍微更改代码的顺序并自定义 SetupTrimDevice 函数似乎可以正常工作。 实质上、我绝不允许任何内容(包括 TrimAfterColdResetWakeupFromShutDown)使用 CCFG_O_MODE_CONF 寄存器中的 CAP 阵列增量值。 修改后的 SetupTrimDevice (称为 SetupReTrimDevice)也始终执行完整的调整(调用 All the TrimAfter... 功能)。

    以下是经更改的函数:

    static int8_t sg_nCapArrayDelta = 0; // Default should be equal to CCFG value 
    
    void regulatory_set_cap_array_delta(int8_t capArrDelta)
    {
        uint32_t ccfg_ModeConfReg;
    
        if (capArrDelta < -20)
            capArrDelta = -20;
        if (capArrDelta > 20)
            capArrDelta = 20;
    
        //
        // No change, then no need to update 
        //
        if ( sg_nCapArrayDelta != capArrDelta )
        {
            uint32_t ccfg_Mod;
    
            bool fIntDisabled = IntMasterDisable();
    
            // read the MODE_CONF register in CCFG        
            // Clear CAP_MODE and the CAPARRAY_DELATA field
            ccfg_ModeConfReg = HWREG( CCFG_BASE_DEFAULT + CCFG_O_MODE_CONF );
            ccfg_ModeConfReg &= ~( CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M |
                                   CCFG_MODE_CONF_XOSC_CAP_MOD_M );
    
            // Insert new delta value
            ccfg_Mod = ( uint8_t ) capArrDelta;
            ccfg_Mod <<= CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_S;
            ccfg_Mod &= CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M;
    
            ccfg_ModeConfReg |= ccfg_Mod;
    
            // Update current value
            sg_nCapArrayDelta = capArrDelta;
    
            //
            // Update the HW register with the new delta value
            //
            HWREG( AUX_DDI0_OSC_BASE + DDI_0_OSC_O_ANABYPASSVAL1 ) = SetupGetTrimForAnabypassValue1( ccfg_ModeConfReg );
    
            // Force power on AUX to ensure CPU has access
            AONWUCAuxWakeupEvent(AONWUC_AUX_WAKEUP);
            while (!(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON)) {}
    
            // Enable the AUX domain OSC clock and wait for it to be ready
            AUXWUCClockEnable(AUX_WUC_OSCCTRL_CLOCK);
            while (AUXWUCClockStatus(AUX_WUC_OSCCTRL_CLOCK) != AUX_WUC_CLOCK_READY) {}
    
            // Turn of Xosc (doesn't actually turn off fully as it's the only clock we have)
            OSCHF_SwitchToRcOscTurnOffXosc();
    
            //
            // Retrim the device
            // Retrim function is the same as SetupReTrimDevice with two changes
            // - Instead of reading CCFG_O_MODE_CONF it uses the value passed in
            // - Always assumes hard reset and calls 
            //			 TrimAfterColdReset();
            //		         TrimAfterColdResetWakeupFromShutDown(ui32Fcfg1Revision);
            //		         TrimAfterColdResetWakeupFromShutDownWakeupFromPowerDown();
            //
            SetupReTrimDevice(ccfg_ModeConfReg);
            SetupReTrimDevice(ccfg_ModeConfReg); // x2, may not be necessary
    
            // Turn on Xosc again
            OSCHF_TurnOnXosc();
            while (!OSCHF_AttemptToSwitchToXosc());
    
            // Disable clock for OSC_DIG
            AUXWUCClockDisable(AUX_WUC_OSCCTRL_CLOCK);
    
            // Release the 'force power' on AUX
            AONWUCAuxWakeupEvent(AONWUC_AUX_ALLOW_SLEEP);
    
            if ( !fIntDisabled )
            {
                IntMasterEnable( );
            }
        }
    }

    这种方法在  复位和断电过程中为我提供了稳定且可重复的调整电容阵列偏移。

    但是 、如果我使用此函数来设置它、则增量现在与仅使用 ccfg 不同。 它始终低约3KHz。 有报警铃振铃、并向我建议仍然有问题-或者 XOSC 未被(重新)适当修整。 感觉非常接近、有什么想法吗?

    此致

    -奥利弗

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

    您好、Oliver、

    您能否测试以下代码以更改电容阵列增量:

    int8_t capArrDelta= -10;
    
    // read the MODE_CONF register in CCFG
    uint32_t ccfg_ModeConfReg = HWREG( CCFG_BASE + CCFG_O_MODE_CONF );
    // Clear CAP_MODE and the CAPARRAY_DELATA field
    ccfg_ModeConfReg &= ~( CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M | CCFG_MODE_CONF_XOSC_CAP_MOD_M );
    // Insert new delta value
    ccfg_ModeConfReg |= ((((uint32_t)capArrDelta) << CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_S ) & CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M );
    // Update the HW register with the new delta value
    DDI32RegWrite(AUX_DDI0_OSC_BASE, DDI_0_OSC_O_ANABYPASSVAL1, SetupGetTrimForAnabypassValue1( ccfg_ModeConfReg ));
    
    // Switch to RC oscillator and turn off Xosc
    OSCHF_SwitchToRcOscTurnOffXosc();
    
    //Turn on Xosc
    OSCHF_TurnOnXosc();
    
    // Try to switch to Xosc
    while(OSCHF_AttemptToSwitchToXosc() == 0){}

    您还需要在文件顶部添加此头文件:

    #include <ti/devices/cc13x0/driverlib/osc.h>
    #include <ti/devices/cc13x0/driverlib/ddi.h>
    #include <ti/devices/cc13x0/driverlib/setup_rom.h>
    #include <ti/devices/cc13x0/inc/hw_ccfg.h>
    

    我实现了一个 for 循环、该循环将电容阵列增量从-43更改为10、增量为1、并传输载波、并获得以下结果。

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

    您好、Diego、

    感谢您的回复。

    是的、这适用于具有备用振荡器的器件(例如、在我们的移动设备上、它是外部低功耗振荡器)、我们在这些设备上精确使用该代码。 但是、我们的基站器件无需切换到低功耗模式、因此为了节省成本、我们没有第二个振荡器。 如果没有第二个振荡器、我们就不会看到 XOSC 关闭、而对电容阵列增量的更改是不可靠的。

      仍需要调用尝试关闭和打开 XOSC、但 它们本身会使调整变化不可预测且不一致。 重新修整调用似乎使它稳定下来。  

    我们还发现、为了使用 DDI32RegWrite 、它需要我们强制 AUX 上电并启用 AUC 时钟域、否则 DDI32RegWrite 中的信号量是不可访问的、器件挂起(因此、这种方法稍有不同); 尽管这本身似乎没有什么影响。

    您能否在物理上没有第二个时钟源的电路板上尝试此操作?

    谢谢

    -奥利弗

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

    我上一个帖子中的代码也适用于从 LAUNCHXL-CC1310 LaunchPad 上去色的 LF XOSC、并使用 LF RC 振荡器作为 LF 时钟的源。

    我明白为什么您没有 LF XOSC、但您是否有理由不使用内部 LF RC 振荡 器作为 LF 时钟的源?

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

    我认为这源于 cc1310的勘误表、建议不要使用它。 如果该勘误表不再适用、我将在今天晚些时候使用 LF RCOSC 设置对其进行测试。

    如果可行、是否可以在不更新 ccfg 部分的情况下轻松在 LF XOSC 和 LF RCOSC 之间切换? 我们有一个引导加载程序、该引导加载程序会忽略 ccfg 部分、因此 该字段中已有的所有器件都需要此操作。

    感谢 Diego。

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

    勘误表仅适用于修订版 A 器件:

    《CC1310 SimpleLink 无线 MCU 器件勘误表》(修订版 E)(TI.com)

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

    您好、Diego、

    这似乎工作了一点、但并不是很稳定。 至少它不会挂起。

    下面是我看到的:我可以升高和降低电容阵列增量并对其进行更改、而在示波器上、它看起来是在更改-我可以再现您显示的扫描。  但是、如果我在两个电容阵列增量偏移之间来回切换、就会显示稳定性问题。 在下图中、我在0和1的电容阵列增量(大约 x10)之间切换。 输出频率的可重复性非常差:

     

    只需在 CCFG 中设置电容阵列增量就不会出现这种不稳定性。

    请注意、我不会在 ccfg 中将 LF 从 XOSC 直接设置为 RCOSC。 但是、如果我 在更新寄存器和切换 HF OSC 之前立即发出 OSCClockSourceSet (OSC_SRC_CLK_LF、OSC_RCOSC_LF)、似乎允许我进行切换。 据我所知、我们不会将 LF 时钟用于任何用途、因此这应该足够安全、除非您另有建议。

    注2:如果我在 ccfg 中将 LF OSC 设置为 RCOSC、也会发生这种情况。

    您能否确认您的终端也会发生这种情况?

    谢谢

    -奥利弗

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

    您好、Diego、

    在关闭 XOSC 后添加一个小延迟似乎是为了达到目的并消除不稳定:

    (笑声)

    OSCHF_SwitchToRcOscTurnOffXosc();

    CPUdelay (32000);

    OSCHF_TurnOnXosc();

    (笑声)

    感谢你的帮助。

    此致

    -奥利弗