/*
 * mcu_rcc.h
 *
 *  Created on: 22/04/2021 г.
 *      Author: alexraynepe196@gmail.com
  ------------------------------------------------------------------------
    Copyright (c) alexrayne

   All rights reserved.
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
   - Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   - Neither the name of ARM nor the names of its contributors may be used
     to endorse or promote products derived from this software without
     specific prior written permission.
   *
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. *
   -----------------------------------------------------------------------
    this is renesas CGC API wrapper to STM RCC-like API
 */

#ifndef BSP_CPU_MCU_RCC_H_
#define BSP_CPU_MCU_RCC_H_

#include <mcu-chip.h>
#include "cslr.h"

#include "bsp_api.h"


#if 1
// this startup frequencies not change by APP
#define BSP_CLK_STATIC          1

/* Startup clock frequency of each system clock. These macros are only helpful if the system clock and dividers have
 * not changed since startup. These macros are not used in FSP modules except for the clock startup code. */
#define BSP_ICLK_HZ             BSP_STARTUP_ICLK_HZ
#define BSP_PCLKA_HZ            BSP_STARTUP_PCLKA_HZ
#define BSP_PCLKB_HZ            BSP_STARTUP_PCLKB_HZ
#define BSP_PCLKC_HZ            BSP_STARTUP_PCLKC_HZ
#define BSP_PCLKD_HZ            BSP_STARTUP_PCLKD_HZ
#define BSP_BCLK_HZ             BSP_STARTUP_BCLK_HZ
#define BSP_FCLK_HZ             BSP_STARTUP_FCLK_HZ

#elif 0
// there frequencies only source clock by APP, but PCLKx divs a keep origin
#define BSP_CLK_STATIC         0

#define BSP_ICLK_HZ                    (SystemCoreClock)
#define BSP_SOURCE_CLOCK_HZ            (SystemCoreClock << BSP_CFG_ICLK_DIV)
#define BSP_PCLKA_HZ                   (BSP_SOURCE_CLOCK_HZ >> BSP_CFG_PCLKA_DIV)
#define BSP_PCLKB_HZ                   (BSP_SOURCE_CLOCK_HZ >> BSP_CFG_PCLKB_DIV)
#define BSP_PCLKC_HZ                   (BSP_SOURCE_CLOCK_HZ >> BSP_CFG_PCLKC_DIV)
#define BSP_PCLKD_HZ                   (BSP_SOURCE_CLOCK_HZ >> BSP_CFG_PCLKD_DIV)
#define BSP_BCLK_HZ                    (BSP_SOURCE_CLOCK_HZ >> BSP_CFG_BCLK_DIV)
#define BSP_FCLK_HZ                    (BSP_SOURCE_CLOCK_HZ >> BSP_CFG_FCLK_DIV)

#else
// there app changes frequencyes free
#define BSP_CLK_STATIC         0

#define BSP_ICLK_HZ                    (SystemCoreClock)
#define BSP_SOURCE_CLOCK_HZ            (SystemCoreClock << R_SYSTEM->SCKDIVCR_b.ICK)
#define BSP_PCLKA_HZ                   (BSP_SOURCE_CLOCK_HZ >> R_SYSTEM->SCKDIVCR_b.PCKA)
#define BSP_PCLKB_HZ                   (BSP_SOURCE_CLOCK_HZ >> R_SYSTEM->SCKDIVCR_b.PCKB)
#define BSP_PCLKC_HZ                   (BSP_SOURCE_CLOCK_HZ >> R_SYSTEM->SCKDIVCR_b.PCKC)
#define BSP_PCLKD_HZ                   (BSP_SOURCE_CLOCK_HZ >> R_SYSTEM->SCKDIVCR_b.PCKD)
#define BSP_BCLK_HZ                    (BSP_SOURCE_CLOCK_HZ >> R_SYSTEM->SCKDIVCR_b.BCK)
#define BSP_FCLK_HZ                    (BSP_SOURCE_CLOCK_HZ >> R_SYSTEM->SCKDIVCR_b.FCK)

#endif


#define RCC_GetTimClockFreq(tim)        BSP_PCLKB_HZ
#define RCC_GetGPTClockFreq(tim)        BSP_PCLKD_HZ
#define RCC_GetUSARTClockFreq(uart)     BSP_PCLKB_HZ

#define FCPU                    BSP_ICLK_HZ



#ifdef __cplusplus
extern "C" {
#endif



void RCC_EnableClock_SPIn( unsigned chanel );
void RCC_DisableClock_SPIn( unsigned chanel );
void RCC_EnableClock_UARTn( unsigned chanel );
void RCC_DisableClock_UARTn( unsigned chanel ) ;
void RCC_EnableClock_I2Cn( unsigned chanel );
void RCC_DisableClock_I2Cn( unsigned chanel ) ;
void RCC_EnableClock_ADCn( unsigned chanel );
void RCC_DisableClock_ADCn( unsigned chanel ) ;

void RCC_EnableClock_DMA();
void RCC_DisableClock_DMA();

void RCC_EnableClock_TRNG();
void RCC_DisableClock_TRNG();

void RCC_EnableClock_AES();
void RCC_DisableClock_AES();



//================================================================================================
//          RESET source API



#define RES_RSTSR1(field)   CSL_FMK(R_SYSTEM_RSTSR1_##field, 1ul)


enum RCCResetSourceFlag{
    RCC_RESET_ERR_SP        =  RES_RSTSR1(SPERF),
    RCC_RESET_ERR_BUSMASTER =  RES_RSTSR1(BUSMRF),
    RCC_RESET_ERR_BUSLAVE   =  RES_RSTSR1(BUSSRF),
    RCC_RESET_ERR_ECC       =  RES_RSTSR1(REERF),
    RESET_ERR_PARITY        =  RES_RSTSR1(RPERF),

    RCC_RESET_SW            =  RES_RSTSR1(SWRF),
    RCC_RESET_WDT           =  RES_RSTSR1(WDTRF),
    RCC_RESET_IWDT          =  RES_RSTSR1(IWDTRF),

    RCC_RESET_WDT_ANY       =  RCC_RESET_WDT | RCC_RESET_IWDT,

//#define R_SYSTEM_RSTSR1_TZERF_Pos               (13UL)         /*!< TZERF (Bit 13)                                        */
//#define R_SYSTEM_RSTSR1_TZERF_Msk               (0x2000UL)     /*!< TZERF (Bitfield-Mask: 0x01)                           */
//#define R_SYSTEM_RSTSR1_CPERF_Pos               (15UL)         /*!< CPERF (Bit 15)                                        */
//#define R_SYSTEM_RSTSR1_CPERF_Msk               (0x8000UL)     /*!< CPERF (Bitfield-Mask: 0x01)                           */


    RCC_RESET_RES           =  1ul << 16,       // reset signal
    RCC_RESET_POR           =  1ul << 24,       // power reset
};
typedef enum RCCResetSourceFlag    RCCResetSourceFlag;
typedef uint32_t    RCCResetSources;

static inline
RCCResetSources    RCC_RES_source(){
    return R_SYSTEM->RSTSR1
            | ( R_SYSTEM->RSTSR0 << 24)
            | ( R_SYSTEM->RSTSR2 << 16)
            ;
}



//========================================================================================================
//      STM32 HAL RCC api

static inline
bool __HAL_RCC_GET_FLAG( RCCResetSources x ){
    if ((x & 0xffff) != 0)
        if ( (R_SYSTEM->RSTSR1 & x) != 0)
            return true;

    if ( (x & RCC_RESET_RES) != 0)
        if (R_SYSTEM->RSTSR2_b.CWSF)
            return true;

    if ( (x & RCC_RESET_POR) != 0)
        if (R_SYSTEM->RSTSR0_b.PORF)
            return true;

    return false;
}

typedef enum RCCFlags{
    RCC_FLAG_BORRST = RCC_RESET_POR,    //*            @arg RCC_FLAG_BORRST: POR/PDR or BOR reset.
    RCC_FLAG_PINRST = RCC_RESET_RES,    //*            @arg RCC_FLAG_PINRST: Pin reset.
    RCC_FLAG_SFTRST = RCC_RESET_SW,     //*            @arg RCC_FLAG_SFTRST: Software reset.
    RCC_FLAG_IWDGRST= RCC_RESET_IWDT,     //*            @arg RCC_FLAG_IWDGRST: Independent Watchdog reset.
    RCC_FLAG_WWDGRST= RCC_RESET_WDT,     //*            @arg RCC_FLAG_WWDGRST: Window Watchdog reset.
} RCCFlags;


#ifdef __cplusplus
}
#endif



#endif /* BSP_CPU_MCU_RCC_H_ */
