text: /***************************************************************************//**
  * \file system_psoc6_cm4.c
  * \version 2.70
  *
  * The device system-source file.
  *
  ********************************************************************************
  * \copyright
  * Copyright 2016-2019 Cypress Semiconductor Corporation
  * SPDX-License-Identifier: Apache-2.0
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *******************************************************************************/
  
  #include <stdbool.h>
  #include "system_psoc6.h"
  #include "cy_device.h"
  #include "cy_device_headers.h"
  #include "cy_syslib.h"
  #include "cy_sysclk.h"
  #include "cy_wdt.h"
  
  #if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
      #include "cy_ipc_sema.h"
      #include "cy_ipc_pipe.h"
      #include "cy_ipc_drv.h"
  
      #if defined(CY_DEVICE_PSOC6ABLE2)
          #include "cy_flash.h"
      #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
  #endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
  
  
  /*******************************************************************************
  * SystemCoreClockUpdate()
  *******************************************************************************/
  
  /** Default HFClk frequency in Hz */
  #define CY_CLK_HFCLK0_FREQ_HZ_DEFAULT       (8000000UL)
  
  /** Default PeriClk frequency in Hz */
  #define CY_CLK_PERICLK_FREQ_HZ_DEFAULT      (4000000UL)
  
  /** Default FastClk system core frequency in Hz */
  #define CY_CLK_SYSTEM_FREQ_HZ_DEFAULT       (8000000UL)
  
  
  /**
  * Holds the SlowClk (Cortex-M0+) or FastClk (Cortex-M4) system core clock,
  * which is the system clock frequency supplied to the SysTick timer and the
  * processor core clock.
  * This variable implements CMSIS Core global variable.
  * Refer to the [CMSIS documentation]
  * (http://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html "System and Clock Configuration")
  * for more details.
  * This variable can be used by debuggers to query the frequency
  * of the debug timer or to configure the trace clock speed.
  *
  * \attention Compilers must be configured to avoid removing this variable in case
  * the application program is not using it. Debugging systems require the variable
  * to be physically present in memory so that it can be examined to configure the debugger. */
  uint32_t SystemCoreClock = CY_CLK_SYSTEM_FREQ_HZ_DEFAULT;
  
  /** Holds the HFClk0 clock frequency. Updated by \ref SystemCoreClockUpdate(). */
  uint32_t cy_Hfclk0FreqHz  = CY_CLK_HFCLK0_FREQ_HZ_DEFAULT;
  
  /** Holds the PeriClk clock frequency. Updated by \ref SystemCoreClockUpdate(). */
  uint32_t cy_PeriClkFreqHz = CY_CLK_PERICLK_FREQ_HZ_DEFAULT;
  
  /** Holds the Alternate high frequency clock in Hz. Updated by \ref Cy_BLE_EcoConfigure(). */
  uint32_t cy_BleEcoClockFreqHz = 0UL;
  
  /* SCB->CPACR */
  #define SCB_CPACR_CP10_CP11_ENABLE      (0xFUL << 20u)
  
  
  /*******************************************************************************
  * SystemInit()
  *******************************************************************************/
  
  /* CLK_FLL_CONFIG default values */
  #define CY_FB_CLK_FLL_CONFIG_VALUE      (0x01000000u)
  #define CY_FB_CLK_FLL_CONFIG2_VALUE     (0x00020001u)
  #define CY_FB_CLK_FLL_CONFIG3_VALUE     (0x00002800u)
  #define CY_FB_CLK_FLL_CONFIG4_VALUE     (0x000000FFu)
  
  /* IPC_STRUCT7->DATA configuration */
  #define CY_STARTUP_CM0_DP_STATE         (0x2uL)
  #define CY_STARTUP_IPC7_DP_OFFSET       (0x28u)
  
  
  /*******************************************************************************
  * SystemCoreClockUpdate (void)
  *******************************************************************************/
  
  /* Do not use these definitions directly in your application */
  #define CY_DELAY_MS_OVERFLOW_THRESHOLD  (0x8000u)
  #define CY_DELAY_1K_THRESHOLD           (1000u)
  #define CY_DELAY_1M_THRESHOLD           (1000000u)
  
  uint32_t cy_delayFreqKhz  = CY_SYSLIB_DIV_ROUNDUP(CY_CLK_SYSTEM_FREQ_HZ_DEFAULT, CY_DELAY_1K_THRESHOLD);
  
  uint8_t cy_delayFreqMhz  = (uint8_t)CY_SYSLIB_DIV_ROUNDUP(CY_CLK_SYSTEM_FREQ_HZ_DEFAULT, CY_DELAY_1M_THRESHOLD);
  
  uint32_t cy_delay32kMs    = CY_DELAY_MS_OVERFLOW_THRESHOLD *
                              CY_SYSLIB_DIV_ROUNDUP(CY_CLK_SYSTEM_FREQ_HZ_DEFAULT, CY_DELAY_1K_THRESHOLD);
  
  
  /*******************************************************************************
  * Function Name: SystemInit
  ****************************************************************************//**
  * \cond
  * Initializes the system:
  * - Restores FLL registers to the default state for single core devices.
  * - Unlocks and disables WDT.
  * - Calls Cy_PDL_Init() function to define the driver library.
  * - Calls the Cy_SystemInit() function, if compiled from PSoC Creator.
  * - Calls \ref SystemCoreClockUpdate().
  * \endcond
  *******************************************************************************/
  void SystemInit(void)
  {
      Cy_PDL_Init(CY_DEVICE_CFG);
  
  #ifdef __CM0P_PRESENT
      #if (__CM0P_PRESENT == 0)
          /* Restore FLL registers to the default state as they are not restored by the ROM code */
          uint32_t copy = SRSS->CLK_FLL_CONFIG;
          copy &= ~SRSS_CLK_FLL_CONFIG_FLL_ENABLE_Msk;
          SRSS->CLK_FLL_CONFIG = copy;
  
          copy = SRSS->CLK_ROOT_SELECT[0u];
          copy &= ~SRSS_CLK_ROOT_SELECT_ROOT_DIV_Msk; /* Set ROOT_DIV = 0*/
          SRSS->CLK_ROOT_SELECT[0u] = copy;
  
          SRSS->CLK_FLL_CONFIG  = CY_FB_CLK_FLL_CONFIG_VALUE;
          SRSS->CLK_FLL_CONFIG2 = CY_FB_CLK_FLL_CONFIG2_VALUE;
          SRSS->CLK_FLL_CONFIG3 = CY_FB_CLK_FLL_CONFIG3_VALUE;
          SRSS->CLK_FLL_CONFIG4 = CY_FB_CLK_FLL_CONFIG4_VALUE;
  
          /* Unlock and disable WDT */
          Cy_WDT_Unlock();
          Cy_WDT_Disable();
      #endif /* (__CM0P_PRESENT == 0) */
  #endif /* __CM0P_PRESENT */
  
      Cy_SystemInit();
      SystemCoreClockUpdate();
  
  #ifdef __CM0P_PRESENT
      #if (__CM0P_PRESENT == 0)
          /* Configure data register (as CM0p in deep sleep state) of IPC structure #7, reserved for the Deep-Sleep operations. */
          REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = (CY_STARTUP_CM0_DP_STATE << 
                                                                      CY_STARTUP_IPC7_DP_OFFSET);
  
          /* Release IPC structure #7 to avoid deadlocks in case of SW or WDT reset during Deep-Sleep entering. */
          REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0UL;
      #endif /* (__CM0P_PRESENT == 0) */
  #endif /* __CM0P_PRESENT */
  
  #if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
  
  #ifdef __CM0P_PRESENT
      #if (__CM0P_PRESENT == 0)
          /* Allocate and initialize semaphores for the system operations. */
          static uint32_t ipcSemaArray[CY_IPC_SEMA_COUNT / CY_IPC_SEMA_PER_WORD];
          (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, CY_IPC_SEMA_COUNT, ipcSemaArray);
      #else
          (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
      #endif /* (__CM0P_PRESENT) */
  #else
      (void) Cy_IPC_Sema_Init(CY_IPC_CHAN_SEMA, 0ul, NULL);
  #endif /* __CM0P_PRESENT */
  
  
      /********************************************************************************
      *
      * Initializes the system pipes. The system pipes are used by BLE and Flash.
      *
      * If the default startup file is not used, or SystemInit() is not called in your
      * project, call the following three functions prior to executing any flash or
      * EmEEPROM write or erase operation:
      *  -# Cy_IPC_Sema_Init()
      *  -# Cy_IPC_Pipe_Config()
      *  -# Cy_IPC_Pipe_Init()
      *  -# Cy_Flash_Init()
      *
      *******************************************************************************/
      /* Create an array of endpoint structures */
      static cy_stc_ipc_pipe_ep_t systemIpcPipeEpArray[CY_IPC_MAX_ENDPOINTS];
  
      Cy_IPC_Pipe_Config(systemIpcPipeEpArray);
  
      static cy_ipc_pipe_callback_ptr_t systemIpcPipeSysCbArray[CY_SYS_CYPIPE_CLIENT_CNT];
  
      static const cy_stc_ipc_pipe_config_t systemIpcPipeConfigCm4 =
      {
      /* .ep0ConfigData */
          {
              /* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP0,
              /* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP0,
              /* .ipcNotifierMuxNumber */  CY_SYS_INTR_CYPIPE_MUX_EP0,
              /* .epAddress            */  CY_IPC_EP_CYPIPE_CM0_ADDR,
              /* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP0
          },
      /* .ep1ConfigData */
          {
              /* .ipcNotifierNumber    */  CY_IPC_INTR_CYPIPE_EP1,
              /* .ipcNotifierPriority  */  CY_SYS_INTR_CYPIPE_PRIOR_EP1,
              /* .ipcNotifierMuxNumber */  0u,
              /* .epAddress            */  CY_IPC_EP_CYPIPE_CM4_ADDR,
              /* .epConfig             */  CY_SYS_CYPIPE_CONFIG_EP1
          },
      /* .endpointClientsCount     */  CY_SYS_CYPIPE_CLIENT_CNT,
      /* .endpointsCallbacksArray  */  systemIpcPipeSysCbArray,
      /* .userPipeIsrHandler       */  &Cy_SysIpcPipeIsrCm4
      };
  
      Cy_IPC_Pipe_Init(&systemIpcPipeConfigCm4);
  
  #if defined(CY_DEVICE_PSOC6ABLE2)
      Cy_Flash_Init();
  #endif /* defined(CY_DEVICE_PSOC6ABLE2) */
  
  #endif /* !defined(CY_IPC_DEFAULT_CFG_DISABLE) */
  }
  
  
  /*******************************************************************************
  * Function Name: Cy_SystemInit
  ****************************************************************************//**
  *
  * The function is called during device startup. Once project compiled as part of
  * the PSoC Creator project, the Cy_SystemInit() function is generated by the
  * PSoC Creator.
  *
  * The function generated by PSoC Creator performs all of the necessary device
  * configuration based on the design settings.  This includes settings from the
  * Design Wide Resources (DWR) such as Clocks and Pins as well as any component
  * configuration that is necessary.
  *
  *******************************************************************************/
  __WEAK void Cy_SystemInit(void)
  {
       /* Empty weak function. The actual implementation to be in the PSoC Creator
        * generated strong function.
       */
  }
  
  
  /*******************************************************************************
  * Function Name: SystemCoreClockUpdate
  ****************************************************************************//**
  *
  * Gets core clock frequency and updates \ref SystemCoreClock, \ref
  * cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz.
  *
  * Updates global variables used by the \ref Cy_SysLib_Delay(), \ref
  * Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles().
  *
  *******************************************************************************/
  void SystemCoreClockUpdate (void)
  {
      uint32 locHf0Clock = Cy_SysClk_ClkHfGetFrequency(0UL);
  
      if (0UL != locHf0Clock)
      {
          cy_Hfclk0FreqHz = locHf0Clock;
          cy_PeriClkFreqHz = locHf0Clock / (1UL + (uint32_t)Cy_SysClk_ClkPeriGetDivider());
          SystemCoreClock = locHf0Clock / (1UL + (uint32_t)Cy_SysClk_ClkFastGetDivider());
  
          /* Sets clock frequency for Delay API */
          cy_delayFreqMhz = (uint8_t)CY_SYSLIB_DIV_ROUNDUP(SystemCoreClock, CY_DELAY_1M_THRESHOLD);
          cy_delayFreqKhz = CY_SYSLIB_DIV_ROUNDUP(SystemCoreClock, CY_DELAY_1K_THRESHOLD);
          cy_delay32kMs   = CY_DELAY_MS_OVERFLOW_THRESHOLD * cy_delayFreqKhz;
      }
  }
  
  
  /*******************************************************************************
  * Function Name: Cy_SystemInitFpuEnable
  ****************************************************************************//**
  *
  * Enables the FPU if it is used. The function is called from the startup file.
  *
  *******************************************************************************/
  void Cy_SystemInitFpuEnable(void)
  {
      #if defined (__FPU_USED) && (__FPU_USED == 1U)
          uint32_t  interruptState;
          interruptState = Cy_SysLib_EnterCriticalSection();
          SCB->CPACR |= SCB_CPACR_CP10_CP11_ENABLE;
          __DSB();
          __ISB();
          Cy_SysLib_ExitCriticalSection(interruptState);
      #endif /* (__FPU_USED) && (__FPU_USED == 1U) */
  }
  
  
  #if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
  /*******************************************************************************
  * Function Name: Cy_SysIpcPipeIsrCm4
  ****************************************************************************//**
  *
  * This is the interrupt service routine for the system pipe.
  *
  *******************************************************************************/
  void Cy_SysIpcPipeIsrCm4(void)
  {
      Cy_IPC_Pipe_ExecuteCallback(CY_IPC_EP_CYPIPE_CM4_ADDR);
  }
  #endif
  
  
  /*******************************************************************************
  * Function Name: Cy_MemorySymbols
  ****************************************************************************//**
  *
  * The intention of the function is to declare boundaries of the memories for the
  * MDK compilers. For the rest of the supported compilers, this is done using
  * linker configuration files. The following symbols used by the cymcuelftool.
  *
  *******************************************************************************/
  #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050)
  __asm void Cy_MemorySymbols(void)
  {
      /* Flash */
      EXPORT __cy_memory_0_start
      EXPORT __cy_memory_0_length
      EXPORT __cy_memory_0_row_size
  
      /* Working Flash */
      EXPORT __cy_memory_1_start
      EXPORT __cy_memory_1_length
      EXPORT __cy_memory_1_row_size
  
      /* Supervisory Flash */
      EXPORT __cy_memory_2_start
      EXPORT __cy_memory_2_length
      EXPORT __cy_memory_2_row_size
  
      /* XIP */
      EXPORT __cy_memory_3_start
      EXPORT __cy_memory_3_length
      EXPORT __cy_memory_3_row_size
  
      /* eFuse */
      EXPORT __cy_memory_4_start
      EXPORT __cy_memory_4_length
      EXPORT __cy_memory_4_row_size
  
      /* Flash */
  __cy_memory_0_start     EQU __cpp(CY_FLASH_BASE)
  __cy_memory_0_length    EQU __cpp(CY_FLASH_SIZE)
  __cy_memory_0_row_size  EQU 0x200
  
      /* Flash region for EEPROM emulation */
  __cy_memory_1_start     EQU __cpp(CY_EM_EEPROM_BASE)
  __cy_memory_1_length    EQU __cpp(CY_EM_EEPROM_SIZE)
  __cy_memory_1_row_size  EQU 0x200
  
      /* Supervisory Flash */
  __cy_memory_2_start     EQU __cpp(CY_SFLASH_BASE)
  __cy_memory_2_length    EQU __cpp(CY_SFLASH_SIZE)
  __cy_memory_2_row_size  EQU 0x200
  
      /* XIP */
  __cy_memory_3_start     EQU __cpp(CY_XIP_BASE)
  __cy_memory_3_length    EQU __cpp(CY_XIP_SIZE)
  __cy_memory_3_row_size  EQU 0x200
  
      /* eFuse */
  __cy_memory_4_start     EQU __cpp(0x90700000)
  __cy_memory_4_length    EQU __cpp(0x100000)
  __cy_memory_4_row_size  EQU __cpp(1)
  }
  #endif /* defined (__ARMCC_VERSION) && (__ARMCC_VERSION < 6010050) */
  
  
  /* [] END OF FILE */
  