/* 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) 2023. 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.
 */
/******************************************************************************
 * @version: V1.0.0
 ******************************************************************************/

/*!
 * @file timer_link_mode.c
 *
 * @brief timer work on LINK mode.   LINK = CHAIN
 * ch0 timeout reprsent 1min, ch1 timeout represent 1h, ch2 timeout represent 1 day
 * ch3 work independent, T = 1s
 * channel: ch0----ch1----ch2    ch3
 *    link: dis    EN     EN     dis
 * [note]:The chain mode of channel 0 cannot be enabled, otherwise it has no clock source cause can't count!!!!!!!!
 * when CH[n]'s link enable, it count when CH[n-1] timeout, ch0 can't link to other channel(first ch, no ch to link)
 */

/* ===========================================  Includes  =========================================== */
#include <stdint.h>
#include <string.h>

#include "ac7803x_debugout.h"
#include "ac780x_timer.h"
#include "ac780x_timer_reg.h"

#include "timer_link_mode.h"

/* ============================================  Define  ============================================ */

/* ===========================================  Typedef  ============================================ */

/* ==========================================  Variables  =========================================== */
static uint32_t g_minute = 0;
static uint32_t g_hour   = 0;
static uint32_t g_day    = 0;

/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */

/*!
 * @brief Timer channel0 timeout callback function.
 *
 * @param device: the Timer channel0.
 * @param wpara: the value of TIMER_SR(Timer interrupt flag register).
 * @param lpara: unused.
 */
void TIMER_CH0CallBack(void* device, uint32_t wpara, uint32_t lpara)
{
    g_minute++;
}

/*!
 * @brief Timer channel1 timeout callback function.
 *
 * @param device: the Timer channel1.
 * @param wpara: the value of TIMER_SR(Timer interrupt flag register).
 * @param lpara: unused.
 */
void TIMER_CH1CallBack(void* device, uint32_t wpara, uint32_t lpara)
{
    g_hour++;
}

/*!
 * @brief Timer channel2 timeout callback function.
 *
 * @param device: the Timer channel2.
 * @param wpara: the value of TIMER_SR(Timer interrupt flag register).
 * @param lpara: unused.
 */
void TIMER_CH2CallBack(void* device, uint32_t wpara, uint32_t lpara)
{
    g_day++;
}

/*!
 * @brief Timer channel3 timeout callback function.
 *
 * @param device: the Timer channel3.
 * @param wpara: the value of TIMER_SR(Timer interrupt flag register).
 * @param lpara: unused.
 */
void TIMER_CH3CallBack(void* device, uint32_t wpara, uint32_t lpara)
{
    static uint32_t s_true1s = 0;
    s_true1s++;
    printf("the %d s: day = %d, hour = %d, min: %d\r\n", s_true1s, g_day, g_hour % 24, g_minute % 60);
}

/*!
 * @brief Init the timer.
 * 
 */
void Timer_Init(void)
{
    TIMER_ConfigType config;
    memset(&config, 0U, sizeof(config));

    /* Initialization, complete before operating other registers, otherwise a hardfault error occurs */
    TIMER_Init(TIMER_CLKSR_APB); /* timer sel：APB_BUS_FREQ */

    // channel 0, T = 1/(24*6)s, represent 1min
    config.timeMode    = TIMER_WORKMODE_TIMER;        /* timer mode */
    config.chainModeEn = DISABLE;                     /* The chain mode of channel 0 cannot be enabled, otherwise
                                                         it has no clock source and cannot count  */
    config.bypEn       = ENABLE;                      /* bypass the prescaler, */
    config.interruptEn = ENABLE;                      /* enable the channel interrupt */
    config.periodValue = APB_BUS_FREQ / (24 * 6) - 1; /* simulate the time of 1min, real 10s represent 1 day */
    config.callback    = TIMER_CH0CallBack;           /* set callback */
    config.cvalReadSel = TIMER_BCLK_FCLK_1;           /* BUSCLK/FUNCTION_CLK == 1 */

    TIMER_InitChannel(TIMER_CHANNEL0, &config);       /* TIMER_InitChannel will not change the para config */

    // channel 0, T = 10/(24)s, represent 1h
    config.callback    = TIMER_CH1CallBack; /* set callback */
    config.chainModeEn = ENABLE;            /* enable link mode */
    config.periodValue = 60 - 1;            /* 60*1min as 1h */

    TIMER_InitChannel(TIMER_CHANNEL1, &config);

    // channel 1, T = 10s, represent 1day
    config.callback    = TIMER_CH2CallBack; /* set callback */
    config.chainModeEn = ENABLE;            /* enable link mode */
    config.periodValue = 24 - 1;            /* 24*1h as 1day */

    TIMER_InitChannel(TIMER_CHANNEL2, &config);

    // channel 3, T = 1s,real time 1s
    config.chainModeEn = DISABLE;           /* disable link mode */
    config.callback    = TIMER_CH3CallBack; /* set callback */
    config.periodValue = APB_BUS_FREQ;      /* count to APB_BUS_FREQ time out, T = 1s */

    TIMER_InitChannel(TIMER_CHANNEL3, &config);
}

/* =============================================  EOF  ============================================== */
