/***********************************************************************
 * Copyright (c)  2017 - 2020, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : app.c
 * Description : app driver source file
 * Author(s)   : wanyi
 * version     : V1.0
 * Modify date : 2020-07-27
 ***********************************************************************/
#include  "system_um800x.h"
#include  "app.h"
#include  "config.h"
#include  "common.h"
#include  "uart0.h"

volatile uint8_t rx_flag ;
volatile uint8_t uart0_rx_buf[32];
volatile uint8_t uart0_tx_buf[32];
volatile uint16_t rx_count = 0;
volatile uint16_t tx_count = 0;
/************************************************************************
 * function   : uart0_rec_pro
 * Description: uart0_rec_pro 串口接收处理回调函数
 * input : none
 * return: none
 ************************************************************************/
void uart0_rec_pro(void)
{
	uart0_rx_buf[rx_count++]= uart0_recv_byte();
	rx_flag = 1;	
}

/************************************************************************
 * function   : uart_init
 * Description: uart_init 串口初始化
 * input : none
 * return: none
 ************************************************************************/
void uart_init(void)
{
	rx_flag = 0;
	uart0_init(UART0_BAUD_RATE);
    uart0_irq_init(UART0_IRQ_ENABLE,uart0_rec_pro);
}
/************************************************************************
 * function   : gpio_enable_interrupt
 * Description: GPIO 中断使能
 * input : none
 * return: none
 ************************************************************************/
void gpio_enable_interrupt(void)
{
	EA = 0x1;				//EA总中断开启
    EX0 = 0x1;             //外部中断使能
    P0IEN |= (0x1<<4);     //使能P04端口中断

}
/************************************************************************
 * function   : GPIO_IRQHandler
 * Description: GPIO 中断处理
 * input : none
 * return: none
 ************************************************************************/
	
void GPIO_IRQHandler(void) interrupt 0
{ 
    if((P0IRQ&0x10)==0x10)
    {    
        P0IRQ &= ~(0x1<<4);		
				
    }
}

/************************************************************************
 * function   : lowpower_test
 * Description: lowpower 低功耗测试
 * input : none
 * return: none
 ************************************************************************/
void lowpower_test(void)
{
	
	uint8_t chs = 2;
	
	switch(chs)
	{ 
	
	case 0:             //SLEEP mode,wake up by GPIO inerrupt
		printfS("SLEEP  MODE------Enter SLEEP mode------Wake up by P04!\n");
	
		POREN |= (1<<0);				//关闭LVR
	    LVDCON |= (1<<4);				//关闭LVD
		
		CLKCON &= ~(0x1<<3);				//RCL时钟关闭
		
		PCLK0 &=~(0xff<<0);			    //关闭所有模块时钟
		PCLK1 |= (0x01<<0);				//关闭除唤醒管脚IO之外所有模块时钟
		PRESET0 &=~(0xff<<0);		    //复位所有模块(除GPIO0)
		PRESET1 |= (0x01<<0);		    //复位所有模块(除GPIO0)
	
		P0IE = 0x14; 					//输入禁止(除P04、NRST)
		P1IE = 0x00;					//输入禁止	
		P2IE = 0x00;					//输入禁止		
		
		P0PU &= ~(1<<4);  				//使能P04内部上拉
	
		gpio_enable_interrupt();		//P04中断使能
		
		sys_entersleep();               //enter SLEEP mode
		
		uart_init();	                //重新打开UART0，通过打印信息判断是否唤醒
		printfS("SLEEP MODE------Exit SLEEP mode------Pass!\n");	
		break;
	case 1:             //Deepsleep  mode，wake up by GPIO(rising edge or falling edge ) inerrupt or Timer
		printfS("Deepsleep MODE------Enter Deepsleep mode------Wake up by P04!\n");
		
		POREN |= (1<<0);				//关闭LVR
	    LVDCON |= (1<<4);				//关闭LVD
				
		PCLK0 &=~(0xff<<0);			    //关闭所有模块时钟
		PCLK1 |= (0x01<<0);				//关闭除唤醒管脚IO之外所有模块时钟
		PRESET0 &=~(0xff<<0);		    //复位所有模块(除GPIO0)
		PRESET1 |= (0x01<<0);		    //复位所有模块(除GPIO0)
	
		P0IE = 0x14; 					//输入禁止(除P04、NRST)
		P1IE = 0x00;					//输入禁止	
		P2IE = 0x00;					//输入禁止		
		
		P0PU &= ~(1<<4);  				//使能P04内部上拉
			
		gpio_enable_interrupt();		//P04中断使能
	
		sys_enterdeepsleep();  			//enter deepsleep mode

		uart_init();	                //重新打开UART0，通过打印信息判断是否唤醒
		printfS("Deepsleep MODE------Exit Deepsleep mode------Pass!\n");
	
		break;
	case 2:             //stop mode，wake up by GPIO(rising edge or falling edge ) inerrupt
		printfS("STOP MODE------Enter STOP mode------Wake up by P04!\n");
		
		POREN |= (1<<0);				//关闭LVR
	    LVDCON |= (1<<4);				//关闭LVD
				
		PCLK0 &=~(0xff<<0);			    //关闭所有模块时钟
		PCLK1 |= (0x01<<0);				//关闭除唤醒管脚IO之外所有模块时钟
		PRESET0 &=~(0xff<<0);		    //复位所有模块(除GPIO0)
		PRESET1 |= (0x01<<0);		    //复位所有模块(除GPIO0)
	
		P0IE = 0x14; 					//输入禁止(除P04、NRST)
		P1IE = 0x00;					//输入禁止	
		P2IE = 0x00;					//输入禁止		
		
		P0PU &= ~(1<<4);  				//使能P04内部上拉	
		
		gpio_enable_interrupt();		//P04中断使能
	
		sys_enterstop();            	//enter stop mode
	
		uart_init();	                //重新打开UART0，通过打印信息判断是否唤醒
		printfS("STOP MODE------Exit STOP mode------Pass!\n");
		break;
	default:
			break;
	
    }        
    
}
/************************************************************************
 * function   : active_test
 * Description: active 正常工作模式功耗测试
 * input : none
 * return: none
 ************************************************************************/
void active_test(void)
{
    printfS("测试工作电流，所有功能模块都关闭，只保留外部复位功能!\n");
    CLKCON &= ~(1<<3);				//关闭RC32K
    POREN |= (1<<0);				//关闭LVR
    LVDCON |= (1<<4);				//关闭LVD

    PCLK0 &=~ (0xff<<0);			//关闭所有模块时钟
	PCLK1 &=~ (0xff<<0);		    //关闭所有模块时钟
    PRESET0 &=~ (0xff<<0);			//复位所有模块
    PRESET1 &=~ (0xff<<0);			//复位所有模块

    P0IE = 0x04;  					//输入禁止(除P02)
    P1IE = 0x00;					//输入禁止	
    P2IE = 0x00;					//输入禁止		
        
    while(1)
    {
        
    }

}
