PSoC®Creator™:PLLを駆動する水晶振動子とセラミック共振子に関するECO / EXCOの問題 - KBA231127 - Community Translated (JA)

Version 1

    Community Translated by NoTa_4591161 Expert      Version: **

     

    Translation - English: PSoC® Creator™: ECO/EXCO Issue with Quartz Crystals and Ceramic Resonators Driving the PLL - KBA231127

     

    問題:

    PSoC 4100SPlusおよびPSoC4500デバイスファミリでは、ECOクロックがDWRまたはcy_boot APIを使用して構成されている場合、冗長なEXCO_PGM_CLK操作によってPLLが不安定になります。これによりロックが切れ、出力周波数の変動によりCPUのハードフォールトが発生する可能性があります。

     

    影響を受けるデバイス:

    PSoC 4100S PlusPSoC 4500

     

    影響を受けるソフトウェア:

    PSoC Creator4.2および4.3

     

    問題を明らかにする可能性のあるDWR構成の例:

     

     

    回避策:

    使用するソフトウェア、およびクロック構成に使用する方法に応じて、適用できるいくつかの回避策があります。

     

    回避策#1 –利用可能になったらPSoC Creator4.4に移行する

     

    利用可能になると、PSoC Creator 4.4リリースは、クロックを構成するためのDWRアプローチに使用されます。cy_boot 6.0をパッケージ化します。これは、cy_bootAPIを介して構成が行われる場合の問題に対処します。

     

    回避策#2 –コード生成を無効にし、生成されたコードを微調整する

     

    PSoC Creator 4.3または4.2を使用している場合は、このオプションをこのまたは同様のDWR構成に使用します

     

    コード生成を無効にしないと、コードが再生成されることに注意してください。この回避策の使用には注意が必要です。

     

    コンポーネントとDWRの構成が完了したら、コード生成を無効にします。[Project ]メニューに移動し(またはワークスペースエクスプローラーでプロジェクトを右クリックして)、Build Settings > Code Generation > Skip Code Generation > True選択します。

     

     

    次のコードは、Generated_Source\PSoC4\cyfitter_cfg.c生成されます

     

    static void ClockSetup(void)

    {

    uint8 ecoStatus;

    uint8 pllTimeouti;

     

    /* ClockSetup()中にグリッチが発生した場合に備えて、可能な最大周波数に基づいてフラッシュサイクルを設定します。 */

    CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL), (0x0012u));

    /* IMOを新しいクロック速度に更新します。 */

    CySysClkWriteImoFreq(24u);

     

    /* ECOトリムを構成します */

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_ECO_CONFIG), (0x00000000u));

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_ECO_TRIM0), (0x0000001Fu));

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_ECO_TRIM1), (0x0000001Fu));

    /* ECOを開始し、HFCLKに必要なのでステータスを確認します */

    ecoStatus = CySysClkEcoStart(2000u;

    if(ecoStatus != CYRET_SUCCESS)

    {

    CyClockStartupError(CYCLOCKSTART_XTAL_ERROR);

        }

    CyDelayUs(1500u); /* 安定するのを待ちます */

    CySysClkPllSetSource(0u, CY_SYS_PLL_SOURCE_ECO);

    CY_SET_REG32(CYREG_EXCO_PLL_CONFIG0x80020118u;

    CyDelayCycles(120u);

    CY_SET_REG32(CYREG_EXCO_PLL_CONFIG, 0xC0020118u);

    for(pllTimeout = 0u;(pllTimeout <25u)&&(CY_GET_REG32(CYREG_EXCO_PLL_STATUS)== 0u); pllTimeout ++)

    {

    CyDelayCycles(240u);

    }

    if(CY_GET_REG32(CYREG_EXCO_PLL_STATUS)== 0u)

    {

    CyClockStartupError(CYCLOCKSTART_PLL_ERROR;

    }

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_CLK_SELECT), (0x00000001u));

    /* CYREG_EXCO_CLK_SELECTのクロックソースを変更するためのクロックシーケンスを生成します */

    CY_SYS_EXCO_PGM_CLK_REG | = CY_SYS_EXCO_PGM_CLK_ENABLE_MASK;

    for(i = 0u; i <CY_SYS_EXCO_PGM_CLK_SEQ_GENERATOR; i ++)

    {

    CY_SYS_EXCO_PGM_CLK_REG | = CY_SYS_EXCO_PGM_CLK_CLK_ECO_MASK;

    CY_SYS_EXCO_PGM_CLK_REG &= CY_SYS_EXCO_PGM_CLK_CLK_ECO_MASK;

    }

    CY_SYS_EXCO_PGM_CLK_REG &= ~CY_SYS_EXCO_PGM_CLK_ENABLE_MASK;

     

    /* 位相調整されたクロックを設定します */

     

    /* CYDEV_CLK_SELECT開始アドレス:CYDEV_CLK_SELECT */

    CY_SET_REG32((void *)(CYREG_CLK_SELECT), 0x00000002u);

     

    (void)CyIntSetVector(13u, &CySysTimerIsr);

    CyIntEnable(13u;

    CY_SET_REG32((void *)(CYREG_WCO_WDT_CONFIG), 0x00000000u);

    CySysClkSetTimerSource(CY_SYS_CLK_TIMER_SRC_ILO;

     

    }

     

    次のように変更する必要があります(赤文字のコード削除またはコメントアウトします)。

     

    static void ClockSetup(void

    {

    uint8 ecoStatus;

    uint8 pllTimeout, i;

     

    /* ClockSetup()中にグリッチが発生した場合に備えて、可能な最大周波数に基づいてフラッシュサイクルを設定します。*/

    CY_SET_REG32((void CYXDATA *)(CYREG_CPUSS_FLASH_CTL),(0x0012u));

    /* IMOを新しいクロック速度に更新します。*/

    CySysClkWriteImoFreq(24u);

     

    /* ECOトリムを構成します */

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_ECO_CONFIG), (0x00000000u));

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_ECO_TRIM0), (0x0000001Fu));

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_ECO_TRIM1), (0x0000001Fu));

    /* ECOを開始し、HFCLKに必要なのでステータスを確認します */

    ecoStatus = CySysClkEcoStart(2000u;

    if(ecoStatus != CYRET_SUCCESS)

    {

    CyClockStartupError(CYCLOCKSTART_XTAL_ERROR);

    }

    CyDelayUs(1500u); /* 安定するのを待ちます */

    CySysClkPllSetSource(0u, CY_SYS_PLL_SOURCE_ECO);

    CY_SET_REG32(CYREG_EXCO_PLL_CONFIG0x80020118u);

    CyDelayCycles(120u;

    CY_SET_REG32(CYREG_EXCO_PLL_CONFIG0xC0020118u);

    for(pllTimeout = 0u;(pllTimeout <25u)&&(CY_GET_REG32(CYREG_EXCO_PLL_STATUS)== 0u); pllTimeout ++)

    {

    CyDelayCycles(240u);

    }

    if(CY_GET_REG32(CYREG_EXCO_PLL_STATUS)== 0u)

    {

    CyClockStartupError(CYCLOCKSTART_PLL_ERROR);

    }

    CY_SET_REG32((void CYXDATA *)(CYREG_EXCO_CLK_SELECT), (0x00000001u));

     

       

    ///* CYREG_EXCO_CLK_SELECTのクロックソースを変更するためのクロックシーケンスを生成します*/

    // CY_SYS_EXCO_PGM_CLK_REG | = CY_SYS_EXCO_PGM_CLK_ENABLE_MASK;

    // for(i = 0u; i <CY_SYS_EXCO_PGM_CLK_SEQ_GENERATOR; i ++

           //{

    // CY_SYS_EXCO_PGM_CLK_REG | = CY_SYS_EXCO_PGM_CLK_CLK_ECO_MASK;

    // CY_SYS_EXCO_PGM_CLK_REG= ~CY_SYS_EXCO_PGM_CLK_CLK_ECO_MASK;

           //}

    // CY_SYS_EXCO_PGM_CLK_REG= ~CY_SYS_EXCO_PGM_CLK_ENABLE_MASK;

     

    /* 位相調整されたクロックを設定します */

     

    /* CYDEV_CLK_SELECT開始アドレス:CYDEV_CLK_SELECT */

    CY_SET_REG32((void *)(CYREG_CLK_SELECT), 0x00000002u);

     

    (void)CyIntSetVector(13u&CySysTimerIsr;

    CyIntEnable(13u);

    CY_SET_REG32((void *)(CYREG_WCO_WDT_CONFIG), 0x00000000u);

    CySysClkSetTimerSource(CY_SYS_CLK_TIMER_SRC_ILO;

     

    }

     

    回避策#3 – HFClkクロックを手動で切り替え、PSoC Creator4.2では更新されたcy_boot5.81を使用し、PSoC Creator4.3または4.4ではcy_boot6.0を使用します

     

    次のDWRスナップショットで説明されているようにクロッキングを設定するとします。PLLECOから供給され、高周波クロックはPLLから供給されます。

     

     

    ステップ1HFClkIMOに切り替えます。

      

     

    ステップ2cy_boot v5.81およびv6.00からのCySysClkWriteHfclkDirect呼び出しを使用して、main.cで回避策を適用します。

     

    int main()

    {

    /* cyfitter_cfgの実行後にPLLが安定するまで、ある程度の遅延を行います */

    CyDelay(1);

     

    /* HFCLK周波数のソースとしてPLL0を設定(増加) */

    CySysFlashSetWaitCycles(CLK_PLL_MHZ);

     

    CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_PLL0);

     

    /* CyDelay関数の調整 */

    CyDelayFreq(CLK_PLL_MHZ * HZ_IN_MHZ);

     

    /* ここで残りのアプリケーションコードを実行します*/

    for(;;)

    {

    Led_Blink();

    }

     

    }