/* USER CODE BEGIN Header */
/* you can remove the copyright */

/*
 *  Copyright 2020-2023 Yuntu Microelectronics co.,ltd
 *  All rights reserved.
 *
 *  YUNTU Confidential. This software is owned or controlled by Yuntu and may only be
 *  used strictly in accordance with the applicable license terms. By expressly
 *  accepting such terms or by downloading, installing, activating and/or otherwise
 *  using the software, you are agreeing that you have read, and that you agree to
 *  comply with, and are bound by, the license terms. If you do not agree to be
 *  bound by, the license terms, you may not retain, install, activate or otherwise
 *  use the software. The production use license in
 *  Section 2.3 is expressly granted for this software.
 *
 * @file main.c
 * @brief Voltage Range Monitor: 2.5V to 4.0V (5V reference)
 *
 */

/* USER CODE END Header */
#include "sdk_project_config.h"
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define BOARD_RED_LED      (GPIOD)
#define BOARD_RED_LED_PIN  (5)
#define BOARD_BLUE_LED     (GPIOD)
#define BOARD_BLUE_LED_PIN (7)
/* Red led */
#define RED_LED_OFF()      PINS_DRV_SetPins(BOARD_RED_LED, (1 << BOARD_RED_LED_PIN))
#define RED_LED_ON()       PINS_DRV_ClearPins(BOARD_RED_LED, (1 << BOARD_RED_LED_PIN))
/* Blue led */
#define BLUE_LED_OFF()     PINS_DRV_SetPins(BOARD_BLUE_LED, (1 << BOARD_BLUE_LED_PIN))
#define BLUE_LED_ON()      PINS_DRV_ClearPins(BOARD_BLUE_LED, (1 << BOARD_BLUE_LED_PIN))
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define ADC_INST (0) /* ADC instance */
#define SEQ_LEN  (1) /* channel number */

#define RUN_MODE       0
#define SLEEP_MODE     1
#define DEEPSLEEP_MODE 2

#define LOW_POWER_MODE DEEPSLEEP_MODE

/* Threshold definitions (5V reference) */
#define ADC_LOW_THRESHOLD  2048  /* 2.5V */
#define ADC_HIGH_THRESHOLD 3276  /* 4.0V */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint32_t data;
volatile uint8_t wakeupChannel = 0xFF;
volatile bool isOverVoltage = false;   /* true = >4.0V, false = <2.5V */
/* USER CODE END PV */

/* Private function declare --------------------------------------------------*/
/* USER CODE BEGIN PFDC */
/* USER CODE END PFDC */
static void Board_Init(void);

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* Off two red LEDs */
void LedOff(void)
{
    RED_LED_OFF();
    BLUE_LED_OFF();
}

void ADC0_IRQHandler(void) 
{
    /* Clear watchdog flag */
    ADC_DRV_ClearWdFlagCmd(ADC_INST); //effectiveMode�������Ƿ�Χ�ڻ��Ƿ�Χ�ⴥ���ж��¼�
    
    /* Read all channels to see which one triggered */
    for (int i = 0; i < SEQ_LEN; i++)
    {
        data = ADC_DRV_ReadFIFO(ADC_INST);
        
        /* Check for threshold violations */
        if (data > ADC_HIGH_THRESHOLD)
        {
            wakeupChannel = i;
            isOverVoltage = true;
            RED_LED_ON();
            BLUE_LED_OFF();
            PRINTF("Channel %d: %d (OVER VOLTAGE >4.0V)\n", i, data);
        }
        else if (data < ADC_LOW_THRESHOLD)
        {
            wakeupChannel = i;
            isOverVoltage = false;
            BLUE_LED_ON();
            RED_LED_OFF();
            PRINTF("Channel %d: %d (UNDER VOLTAGE <2.5V)\n", i, data);
        } else
           {
               LedOff();

           }
    }
    
    /* Clear any pending flags */
    ADC_DRV_ClearEoseqFlagCmd(ADC_INST);
    //PRINTF("ADC0_IRQHandler\r\n");
}


/* USER CODE END 0 */


/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
    /* USER CODE BEGIN 1 */
    status_t status = STATUS_SUCCESS;
    /* USER CODE END 1 */ 
    Board_Init();
    /* USER CODE BEGIN 2 */

    LedOff();
    OSIF_TimeDelay(1);

    INT_SYS_EnableIRQ(ADC0_IRQn);
    PRINTF("Build %s %s\n", __DATE__, __TIME__);
    PRINTF("ADC Voltage Range Monitor: 2.5V - 4.0V (5V reference)\n");
    PRINTF("Thresholds: %d (2.5V) to %d (4.0V)\n", ADC_LOW_THRESHOLD, ADC_HIGH_THRESHOLD);

    POWER_SYS_Init(&powerConfigsArr, POWER_MANAGER_CONFIG_CNT, NULL, POWER_MANAGER_CALLBACK_CNT);

    /* Wait for debugger to attach if needed */
    OSIF_TimeDelay(2000);


    /* Start ADC continuous conversion */
    ADC_DRV_Start(ADC_INST);


    while(1)
    {
        /* Enter low power mode - will wake up on ADC watchdog event */
        LedOff();
        OSIF_TimeDelay(1); /* Indicate sleeping */
        PRINTF("ADC monitoring started, entering DEEPSLEEP mode...\n");
        POWER_SYS_SetMode(LOW_POWER_MODE, POWER_MANAGER_POLICY_AGREEMENT);

        /* Woke up - process event */
        
        if (wakeupChannel != 0xFF)
        {
            PRINTF("Woke up from channel %d - %s event\n", 
                   wakeupChannel, 
                   isOverVoltage ? "OVER VOLTAGE" : "UNDER VOLTAGE");
            
            /* Add your application logic here */
            
            /* Reset wakeup state */
            wakeupChannel = 0xFF;
            
            /* Small delay before re-entering sleep */
            OSIF_TimeDelay(100);
        }
        
        /* Re-enter low power mode */
        PRINTF("Re-entering DEEPSLEEP mode...\n");
    }
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
        if (status != STATUS_SUCCESS)
        {
            break;
        }
        /* USER CODE END WHILE */
        /* USER CODE BEGIN 3 */
    }
    return status;
    /* USER CODE END 3 */
}

static void Board_Init(void)
{
    CLOCK_SYS_Init(g_clockManConfigsArr,CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr,CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(CLOCK_MANAGER_ACTIVE_INDEX,CLOCK_MANAGER_POLICY_AGREEMENT);
    PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0,g_pin_mux_InitConfigArr0);
    UTILITY_PRINT_Init();
    INT_SYS_ConfigInit();
    ADC_DRV_ConfigConverter(0,&adc_config0);
}

/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
