123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 |
- /* Copyright Statement:
- *
- * This software/firmware and related documentation ("AutoChips Software") are
- * protected under relevant copyright laws. The information contained herein is
- * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
- * the prior written permission of AutoChips inc. and/or its licensors, any
- * reproduction, modification, use or disclosure of AutoChips Software, and
- * information contained herein, in whole or in part, shall be strictly
- * prohibited.
- *
- * AutoChips Inc. (C) 2020. All rights reserved.
- *
- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
- * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
- * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
- * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
- * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
- * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
- * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
- * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
- * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
- * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
- * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
- * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
- * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
- * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
- * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
- */
- /*!
- * @file system_ac780x.c
- *
- * @brief This file provides system clock config integration functions.
- *
- */
- /* =========================================== Includes =========================================== */
- #include "ac780x.h"
- /* ============================================ Define ============================================ */
- #define XTAL ( USE_XTAL ) /* Oscillator frequency */
- #define SYSTEM_CLOCK ( SYSCLK_FREQ ) /* system clock frequency */
- #define MAX_SYSTICK_COUNT (SysTick_LOAD_RELOAD_Msk + 1) /* systemTick max count value */
- /* for eFlash clock config */
- #define SYS_EFLSH_UNLOCK_KEY1 0xac7811
- #define SYS_EFLSH_UNLOCK_KEY2 0x01234567
- #define Eflash_KEY_REG 0x40002000
- #define EFLASH_INFO_REG 0x40002004
- #define EFLASH_CTRL1_REG 0x40002014
- #define EFLASH_CTRL2_REG 0x40002040
- #define SYSTEM_CLOCK_SRC_HSI 0UL
- #define SYSTEM_CLOCK_SRC_PLL 1UL
- #define SYSTEM_CLOCK_SRC_HSE 2UL
- /* =========================================== Typedef ============================================ */
- /* ========================================== Variables =========================================== */
- /* systemTick us delay factor */
- static uint32_t s_facus = 0;
- /* systemTick ms delay factor */
- static uint32_t s_facms = 0;
- /* system clock frequency save */
- uint32_t SystemCoreClock = SYSTEM_CLOCK;
- /* apbclk frequency save */
- uint32_t g_periphAPBClock = SYSTEM_CLOCK / 2;
- /* define system pll prediv value */
- static __IOM uint8_t s_pllPREDIV[] = {1, 2, 4};
- /* ==================================== Functions declaration ===================================== */
- /* Externals declaration */
- #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
- extern uint32_t __Vectors;
- #endif
- /* ====================================== Functions define ======================================== */
- /*!
- * @brief Init Delay count factor, 1s = TICKS * (1/f) s;
- *
- * @param[in] none
- * @return none
- */
- void InitDelay(void)
- {
- s_facus = __SYSTEM_CLOCK / 1000000;
- s_facms = s_facus * 1000;
- }
- /*!
- * @brief Set HSE bypass mode. if xosc enable fail then change system clock to HSI(8m).
- *
- * @param[in] none
- * @return none
- */
- void SetHSEBYPClock(void)
- {
- __IO PLL_ReferenceType pllReference = PLL_REF_INTERAL_OSC;
- /* enable xosc bypass mode */
- SPM_EnableXOSCBypassMode(ENABLE);
- CKGEN_SetSysclkDiv(SYSCLK_DIV);
- /* check if xosc enable success? */
- if (SPM_EnableXOSC(ENABLE) == SUCCESS)
- {
- CKGEN_SetPLLReference(PLL_REF_EXTERNAL_OSC);
- pllReference = PLL_REF_EXTERNAL_OSC;
- }
- else
- {
- /* xosc enable fail, use hsi(8m) as pll clock(default) */
- CKGEN_SetPLLReference(PLL_REF_INTERAL_OSC);
- pllReference = PLL_REF_INTERAL_OSC;
- }
- /* check if pll enable success? */
- if (SPM_EnablePLL(ENABLE) == SUCCESS)
- {
- CKGEN_SetPllPrevDiv(PLL_PREDIV);
- CKGEN_SetPllPostDiv(PLL_POSDIV);
- CKGEN_SetPllFeedbackDiv(PLL_FBKDIV);
- CKGEN_SetSysclkSrc(SYSCLK_SRC_PLL_OUTPUT);
- }
- else /* pll enable fail */
- {
- if (pllReference == PLL_REF_EXTERNAL_OSC)
- {
- CKGEN_SetSysclkSrc(SYSCLK_SRC_EXTERNAL_OSC); /* set external osc as sysclk src */
- }
- else
- {
- CKGEN_SetSysclkSrc(SYSCLK_SRC_INTERNAL_OSC); /* set internal osc as sysclk src */
- }
- }
- }
- /*!
- * @brief Set XOSC Clock. if xosc enable fail, change system clock to HSI(8m).
- *
- * @param[in] none
- * @return none
- */
- void SetXOSCClock(void)
- {
- CKGEN_SetSysclkDiv(SYSCLK_DIV);
- /* check if xosc enable success? */
- if (SPM_EnableXOSC(ENABLE) == SUCCESS)
- {
- /* xosc enable success, use external osc as system clock */
- CKGEN_SetSysclkSrc(SYSCLK_SRC_EXTERNAL_OSC);
- }
- else
- {
- /* xosc enable fail, use hsi(8m) as system clock(default) */
- CKGEN_SetSysclkSrc(SYSCLK_SRC_INTERNAL_OSC);
- }
- }
- /*!
- * @brief Use HSE mode, set the system clock.
- * pll reference clock default use xosc,if xosc enable fail,change to hsi(8m).
- * system clock source default use pll output. if pll enable fail, then
- * stop change system clock source to osc(HSI or HSE).
- *
- * @param[in] none
- * @return none
- */
- void SetHSEClock(void)
- {
- __IO PLL_ReferenceType pllReference = PLL_REF_INTERAL_OSC;
- /* check if xosc enable success? */
- if (SPM_EnableXOSC(ENABLE) == SUCCESS)
- {
- CKGEN_SetPLLReference(PLL_REF_EXTERNAL_OSC);
- pllReference = PLL_REF_EXTERNAL_OSC;
- }
- else /* if xosc enable fail,change pll reference clock to HSI 8M */
- {
- CKGEN_SetPLLReference(PLL_REF_INTERAL_OSC);
- pllReference = PLL_REF_INTERAL_OSC;
- }
- /* set system clock divider */
- CKGEN_SetSysclkDiv(SYSCLK_DIV);
- /* check if pll enable success? */
- if (SPM_EnablePLL(ENABLE) == SUCCESS)
- {
- CKGEN_SetPllPrevDiv(PLL_PREDIV);
- CKGEN_SetPllPostDiv(PLL_POSDIV);
- CKGEN_SetPllFeedbackDiv(PLL_FBKDIV);
- CKGEN_SetSysclkSrc(SYSCLK_SRC_PLL_OUTPUT);
- }
- else /* pll enable fail */
- {
- if (pllReference == PLL_REF_EXTERNAL_OSC)
- {
- CKGEN_SetSysclkSrc(SYSCLK_SRC_EXTERNAL_OSC); /* set external osc as sysclk src */
- }
- else
- {
- CKGEN_SetSysclkSrc(SYSCLK_SRC_INTERNAL_OSC); /* set internal osc as sysclk src */
- }
- }
- }
- /*!
- * @brief Use HSI Mode.Default set pll output as system clock;if pll enable fail
- * ,change system clock to HSI(8m).
- *
- * @param[in] none
- * @return none
- */
- void SetHSIClock(void)
- {
- CKGEN_SetPLLReference(PLL_REF_INTERAL_OSC);
- CKGEN_SetPllPrevDiv(PLL_PREDIV);
- CKGEN_SetPllPostDiv(PLL_POSDIV);
- CKGEN_SetPllFeedbackDiv(PLL_FBKDIV);
- CKGEN_SetSysclkDiv(SYSCLK_DIV);
- /* check if pll enable success? */
- if (SPM_EnablePLL(ENABLE) == SUCCESS)
- {
- /* pll enable success,use pll output as system clock src */
- CKGEN_SetSysclkSrc(SYSCLK_SRC_PLL_OUTPUT);
- }
- else
- {
- /* pll enable fail,use hsi(8m) as system clock src */
- CKGEN_SetSysclkSrc(SYSCLK_SRC_INTERNAL_OSC);
- }
- }
- /*!
- * @brief set system clock
- *
- * @param[in] none
- * @return none
- */
- void SetSysClock(void)
- {
- #if AC780X_CLOCK_SRC == IC_CLOCK_SRC_XOSC
- SetXOSCClock();
- #elif AC780X_CLOCK_SRC == IC_CLOCK_SRC_HSI
- SetHSIClock();
- #elif AC780X_CLOCK_SRC == IC_CLOCK_SRC_HSE
- SetHSEClock();
- #elif AC780X_CLOCK_SRC == IC_CLOCK_SRC_XOSC_BYPASS
- SetHSEBYPClock();
- #else
- SetHSIClock();
- #endif
- }
- /**
- * SetEflashClock
- *
- * @param[in] none
- * @return none
- *
- * @brief Set eflash clock.
- *
- **/
- void SetEflashClock(void)
- {
- uint32_t eflashCKDIV = 0;
- uint32_t ctrl1 = 0x0;
- int32_t timeout = 500;
- do
- {
- WRITE_MEM32(Eflash_KEY_REG, SYS_EFLSH_UNLOCK_KEY1);
- WRITE_MEM32(Eflash_KEY_REG, SYS_EFLSH_UNLOCK_KEY2);
- timeout--;
- } while ((READ_MEM32(EFLASH_INFO_REG) & ((uint32_t)1 << 31)) && (0 < timeout));
- eflashCKDIV = (SYSCLK_FREQ / 1000000 + 1) & 0x7F;
- ctrl1 = 0x2000 | eflashCKDIV;
- WRITE_MEM32(EFLASH_CTRL1_REG, ctrl1);
- SET_BIT32((*(uint32_t*)EFLASH_CTRL1_REG), (uint32_t)1 << 8);
- SET_BIT32((*(uint32_t*)EFLASH_INFO_REG), (uint32_t)1 << 31);
- }
- /*!
- * @brief delay until the syctick count tick to 0
- *
- * @param[in] tick : systick count value
- * @return none
- */
- static void SysTickDelay(uint32_t tick)
- {
- __IO uint32_t tickFlag = 0;
- SysTick->LOAD = tick - 1;
- SysTick->VAL = 0x00;
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
- do
- {
- tickFlag = SysTick->CTRL;
- } while((tickFlag & SysTick_CTRL_ENABLE_Msk) &&
- (!(tickFlag & SysTick_CTRL_COUNTFLAG_Msk)));
- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
- SysTick->VAL = 0X00;
- }
- /*!
- * @brief Repeatlly delay the ticks for the given times
- *
- * @param[in] param : times, the times of delay the tick
- * @param[in] param : tick, each tick to delay
- * @return none
- */
- static void SysTickRepeatDelay(uint32_t times, uint32_t tick)
- {
- uint32_t i = 0;
- for (i = 0; i < times; i++)
- {
- SysTickDelay(tick);
- }
- }
- /*!
- * @brief delay us
- *
- * @param[in] param : us, us for delay
- * @return none
- */
- void udelay(uint32_t us)
- {
- uint32_t tick = us * s_facus;
- SysTickRepeatDelay(tick / MAX_SYSTICK_COUNT, MAX_SYSTICK_COUNT);
- SysTickDelay(tick % MAX_SYSTICK_COUNT);
- }
- /*!
- * @brief delay ms
- *
- * @param[in] param : ms, ms for delay
- * @return none
- */
- void mdelay(uint32_t ms)
- {
- uint32_t tick = ms * s_facms;
- SysTickRepeatDelay(tick / MAX_SYSTICK_COUNT, MAX_SYSTICK_COUNT);
- SysTickDelay(tick % MAX_SYSTICK_COUNT);
- }
- /*!
- * @brief get system clock frequence
- *
- * @param[in] none
- * @return none
- */
- void SystemCoreClockUpdate(void)
- {
- __IO uint8_t clkSrc = 0, postDiv = 0, feedbackDiv = 0, sysclkDiv = 0;
- __IO uint8_t pllRef = 0, preDiv = 0, apbClkDiv = 0;
- __IO uint32_t vcoClk = 0;
- clkSrc = CKGEN->CTRL & CKGEN_CTRL_SYSCLK_SEL_Msk;
- apbClkDiv = ((CKGEN->CTRL & CKGEN_CTRL_APBCLK_DIV_Msk) >> CKGEN_CTRL_APBCLK_DIV_Pos) + 1;
- switch (clkSrc)
- {
- case SYSTEM_CLOCK_SRC_HSI:
- SystemCoreClock = HSI_FREQ; /* HSI RC */
- break;
- case SYSTEM_CLOCK_SRC_PLL:
- /* PLL Output */
- pllRef = (CKGEN->CTRL & CKGEN_CTRL_PLL_REF_SEL_Msk) >> CKGEN_CTRL_PLL_REF_SEL_Pos;
- sysclkDiv = ((CKGEN->CTRL & CKGEN_CTRL_SYSCLK_DIV_Msk) >> CKGEN_CTRL_SYSCLK_DIV_Pos) + 1;
- preDiv = s_pllPREDIV[(CKGEN->SYSPLL1_CFG0 & CKGEN_SYSPLL1_CFG0_SYSPLL1_PREDIV_Msk) >> CKGEN_SYSPLL1_CFG0_SYSPLL1_PREDIV_Pos];
- postDiv = ((CKGEN->SYSPLL1_CFG0 & CKGEN_SYSPLL1_CFG0_SYSPLL1_POSDIV_Msk) >> CKGEN_SYSPLL1_CFG0_SYSPLL1_POSDIV_Pos) * 2;
- feedbackDiv = (CKGEN->SYSPLL1_CFG0 & CKGEN_SYSPLL1_CFG0_SYSPLL1_FBKDIV_Msk) >> CKGEN_SYSPLL1_CFG0_SYSPLL1_FBKDIV_Pos;
- if (pllRef)
- {
- /* ext xosc clock */
- SystemCoreClock = USE_XTAL;
- }
- else
- {
- /* internal RC */
- SystemCoreClock = HSI_FREQ;
- }
- vcoClk = (SystemCoreClock * feedbackDiv) / preDiv; /* pll vco clock */
- SystemCoreClock = vcoClk / (postDiv * sysclkDiv); /* system clock freq */
- break;
- case SYSTEM_CLOCK_SRC_HSE:
- SystemCoreClock = USE_XTAL; /* HSE XTAL */
- break;
- default:
- break;
- }
- g_periphAPBClock = SystemCoreClock / apbClkDiv; /* apb clock freq */
- }
- /*!
- * @brief Setup the microcontroller system. Initialize the System.
- *
- * @param[in] none
- * @return none
- */
- void SystemInit (void)
- {
- #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
- SCB->VTOR = (uint32_t) &__Vectors;
- #endif
- SystemCoreClock = SYSTEM_CLOCK;
- SetEflashClock();
- SetSysClock();
- CKGEN_SetAPBClockDivider(APBCLK_DIV);
- //SPM_EnableLVD(DISABLE); //disable LVD if need
- }
- /*!
- * @brief change the current menu and display
- *
- * @param[in]
- * @return return the CPUID
- */
- uint32_t GetCPUID(void)
- {
- return SCB->CPUID;
- }
- /*!
- * @brief enter the Standby mode
- *
- * @param[in] none
- * @return none
- */
- void SysStandby(void)
- {
- SPM_SetLowPowerMode(LOW_POWER_MODE_STANDBY);
- /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */
- SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
- #if defined ( __ICCARM__ )
- asm("WFI");
- #elif defined ( __GNUC__)
- asm("WFI");
- #elif defined (__CC_ARM)
- // If using KEIL's uVision, use the CMSIS intrinsic
- __wfi();
- #endif
- }
- /*!
- * @brief enter the Stop mode
- *
- * @param[in] none
- * @return none
- */
- void SysStop(void)
- {
- SPM_SetLowPowerMode(LOW_POWER_MODE_STOP);
- /* Set the SLEEPDEEP bit to enable deep sleep mode (STOP) */
- SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
- #if defined ( __ICCARM__ )
- asm("WFI");
- #elif defined ( __GNUC__)
- asm("WFI");
- #elif defined (__CC_ARM)
- // If using KEIL's uVision, use the CMSIS intrinsic
- __wfi();
- #endif
- // Add Debug Interface to enable printf after wakeup
- }
- /*!
- * @brief enter the Sleep mode
- *
- * @param[in] none
- * @return none
- */
- void SysSleep(void)
- {
- /* Clear the SLEEPDEEP bit to make sure we go into WAIT (sleep) mode instead
- * of deep sleep.
- */
- SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
- #if defined ( __ICCARM__ )
- asm("WFI");
- #elif defined ( __GNUC__)
- asm("WFI");
- #elif defined (__CC_ARM)
- // If using KEIL's uVision, use the CMSIS intrinsic
- __wfi();
- #endif
- }
- /*!
- * @brief get uuid from device
- *
- * @param[in] uuidBuffer: uuid buffer
- * @return none
- */
- void GetUUID(uint32_t *uuidBuffer)
- {
- #define UUID_BASE_ADDRESS 0x4000202C
- uint8_t i = 0;
- if(0 != uuidBuffer)
- {
- for (i = 0; i < 4; i++)
- {
- uuidBuffer[i] = (*(__IO uint32_t *)(UUID_BASE_ADDRESS + i * 4));
- }
- }
- }
- /*!
- * @brief get cpu type from device
- *
- * @param[in] none
- * @return cpu type: AC7801(0xFFAC7801)/AC7811(0xFFAC7811)
- */
- uint32_t GetCpuType(void)
- {
- #define CPU_TYPE_BASE_ADDRESS 0x40002028
- return (*(__IO uint32_t *)(CPU_TYPE_BASE_ADDRESS));
- }
- /*!
- * @brief get reset status
- *
- * @param[in] none
- * @return reset status
- * - bit0: POR_RESET_STATUS
- * - bit1: LVD_RESET_STATUS
- * - bit2: EXT_RESET_STATUS
- * - bit4: WDT_RESET_STATUS
- * - bit5: WDT_32K_RESET_STATUS
- * - bit6: CPU_SYSRESET_STATUS
- * - bit7: CPU_LOCKUP_RST_STATUS
- * - bit8: PLL_UNLOCK_RST_STATUS
- * - bit9: XOSC_LOSS_STATUS
- * - bit16: CLEAR_ALL_RESET_STATUS
- */
- uint32_t GetResetStatus(void)
- {
- return (CKGEN->RESET_STATUS);
- }
- /*!
- * @brief clear all reset status
- *
- * @param[in] none
- * @return none
- */
- void ClearAllResetStatus(void)
- {
- CKGEN->RESET_STATUS |= (1 << 16);
- }
- /* ============================================= EOF ============================================== */
|