/*
*  Copyright(c) 2012-2020     微嵌电子 http://Tonvon.taobao.com
*
*  QQ: 30611966    旺旺：twd3621576   Email: tangweidong2004@163.com
*
* 硬件平台：陆航MiniStm32开发板
*
* 硬件连接：
*===========================================文件信息=======================================================
* 文件名称:
* 功    能:
*
* 编译软件：Keil MDK for ARM 4.12
* 当前版本: V5.0.0.0
* 作    者: Tonvdon(a dong)
* 完成日期: 2012-03-03
*
* 取代版本:
* 原作者  :
* 完成日期:
*********************************************************************************************************
*/
#include "main.h"


#include "Led.h"
#include "Key.h"

#include "Delay.h"

#include "nokia_5110.h"
//#include "bmp_pixel.h"

#include "ds1302.h"
#include "ds1302_config.h"

#include "wifi9113.h"
#include "wifi_gpio_conf.h"

#include "TEA5767_main.h"

#include "DHT11.h"

#include "YX5200/YX5200_main.h"
#include "YX5200/YX5200_uart.h"

//#include "SPI-SD/Lcd/107_32_Driver_IO16.h"
#include "SPI-SD/SD/sddriver.h"
//#include "SPI-SD/Fatfs/ff.h"

#include "SPI-SD/Lcd/lcd_5110_solution.h"

unsigned int  SystemClockFreq;

void GPIO_ConfigurationSYSLed ( void )
{
#if SYSLed_def
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd ( LED_RCC_CONFIG , ENABLE );
    /**
     *	LED -> PB1
     */
    GPIO_InitStructure.GPIO_Pin = LED_PIN_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init ( LED_PORT_CONFIG, &GPIO_InitStructure );
#endif
}


void GPIO_ConfigurationSolen ( void )
{
#if Solen_def
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd ( SOLEN_RCC_CONFIG , ENABLE );
    /**
     *	Solen -> PE8 PE9
     */
    GPIO_InitStructure.GPIO_Pin = SOLEN_PIN_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init ( SOLEN_PORT_CONFIG, &GPIO_InitStructure );

    SOLEN_PE8_HIGH();
    SOLEN_PE9_HIGH();
#endif
}

void GpioConfigurationLCD ( void )
{
#if LCD_def
    GPIO_InitTypeDef  GPIO_InitStructure;

    /* Enable the GPIO_LED Clock */
    RCC_APB2PeriphClockCmd ( LCD_N5110_RCC, ENABLE );

    /* Configure the GPIO_LED pin */
    GPIO_InitStructure.GPIO_Pin = LCD_N5110_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( LCD_N5110_PORT, &GPIO_InitStructure );
#endif
}

void GpioConfiguration_Pull_up_down ( void )
{
#if Pull_up_down_def
    GPIO_InitTypeDef  GPIO_InitStructure;

    /* Enable the GPIO_LED Clock */
    RCC_APB2PeriphClockCmd ( PULL_RCC_CONFIG, ENABLE );

    /* Configure the GPIO_LED pin */
    GPIO_InitStructure.GPIO_Pin = PULL_PIN_CONFIG;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( PULL_PORT_CONFIG, &GPIO_InitStructure );
    GPIO_SetBits ( PULL_PORT_CONFIG, PULL_UP_PIN );
    GPIO_ResetBits ( PULL_PORT_CONFIG, PULL_DOWN_PIN );
#endif
}

void GpioConfigurationDS1302 ( void )
{
#if DS1302_def
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd ( DS1302_IORCC, ENABLE );

    GPIO_InitStructure.GPIO_Pin = ( DS1302_SCK_PIN | DS1302_IO_PIN | DS1302_CE_PIN );
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( DS1302_PORT, &GPIO_InitStructure );
#endif
}

bool DS1302ReadIO ( void )
{
#if DS1302_def
    bool read_res;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd ( DS1302_IORCC, ENABLE );

    //切换为输入口
    GPIO_InitStructure.GPIO_Pin = DS1302_IO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( DS1302_PORT, &GPIO_InitStructure );

    //读取并处理;
    read_res = GPIO_ReadInputDataBit ( DS1302_PORT, DS1302_IO_PIN );

    //还原成输出口
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init ( DS1302_PORT, &GPIO_InitStructure );

    //返回读取的值；
    return read_res;
#endif
}


void GpioConfigurationTEA5767 ( void )
{
#if TEA5767_def
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd ( TEA5767_RCC_CONFIG, ENABLE );

    GPIO_InitStructure.GPIO_Pin = ( TEA5767_PIN_CONFIG );
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( TEA5767_PORT_CONFIG, &GPIO_InitStructure );
#endif
}

bool TEA5767ReadSDA ( void )
{
#if TEA5767_def
    bool read_res;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOD, ENABLE );

    //切换为输入口
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( GPIOD, &GPIO_InitStructure );

    //读取并处理;
    read_res = GPIO_ReadInputDataBit ( GPIOD, GPIO_Pin_12 );

    //还原成输出口
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init ( GPIOD, &GPIO_InitStructure );

    //返回读取的值；
    return read_res;
#endif
}

#define SYSTICK_TIME		(1000000/1000)		//最小10us，推荐1000us
void SYSTICK_Configuration ( void )
{
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq ( &RCC_Clocks );
    SystemClockFreq = RCC_Clocks.SYSCLK_Frequency;

    if ( SysTick_Config ( SystemClockFreq / SYSTICK_TIME ) )
    {
        while ( 1 );
    }
}
/***************************************************************************************/
//配置结束

/***************************************************************************************/


/**************************************************************************************
默认72Mh 主频 ：
在文件 system_stm32f10x.c中有定义
#define SYSCLK_FREQ_72MHz  72000000	 可根据需要自行修改
****************************************************************************************/
DHT11_Data_TypeDef DHT11_Data;
char sendDataBuff[50];


void AutoSend_Time_Temp ( void )
{
#if WIFI_Uart1_def

    //20s自动发送，time + 温湿度
    if ( WifiProcessStep == WIFI_STEP_CHAT )
    {
        sprintf ( sendDataBuff, "20%02d-%02d-%02d ", DS1302_DateTime.Year, DS1302_DateTime.Month, DS1302_DateTime.Date );
        sprintf ( sendDataBuff, "%s%02d:%02d:%02d %02d", sendDataBuff, DS1302_DateTime.Hour, DS1302_DateTime.Minute, DS1302_DateTime.Second, DS1302_DateTime.Day );
        sprintf ( sendDataBuff, "%s|%02d%% - %02dC|", sendDataBuff, DHT11_Data.humi_int, DHT11_Data.temp_int );
        sendto_server0824 ( AIM_ID, REGMY_ID, ( u8 * ) sendDataBuff, strlen ( sendDataBuff ) );
    }

#endif
}

void Get_DS1302_Time ( void )
{
#if DS1302_def
    if ( WifiProcessStep != WIFI_STEP_CHAT )
    {
	    //rtc 获取
	    DS1302_GetDateTime();
	    sys_rtc_time = Date_TO_Sec ( DS1302_DateTime.Year, DS1302_DateTime.Month, DS1302_DateTime.Date, DS1302_DateTime.Hour, DS1302_DateTime.Minute, DS1302_DateTime.Second );
	}
#endif
}

void Get_DHT11_Temp ( void )
{
#if DHT11_def
    //温湿度获取
    Read_DHT11 ( &DHT11_Data );
#endif
}

void Pri_Sys_Time ( char LinePos )
{
    //rtc 200ms刷新
    Sec_TO_Date ( sys_rtc_time );
    sprintf ( n5110_string[LinePos + 0], "20%02d-%02d-%02d", DS1302_DateTime.Year, DS1302_DateTime.Month, DS1302_DateTime.Date );
    sprintf ( n5110_string[LinePos + 1], "%02d:%02d:%02d %02d", DS1302_DateTime.Hour, DS1302_DateTime.Minute, DS1302_DateTime.Second, DS1302_DateTime.Day );
}


void Pri_DHT11_Temp ( char LinePos )
{
#if DHT11_def
    sprintf ( n5110_string[LinePos + 0], "%02d%% - %02dC", DHT11_Data.humi_int, DHT11_Data.temp_int );
#endif
}

void Pri_Key_State ( char LinePos )
{
#if key16_def
    u8 i;
    for ( i = 0; i < 16; i++ )
    {
        if ( Keys[i].Res != NO_KEY_FLAG )
        {
            sprintf ( n5110_string[LinePos + 0], "-->K%02d:%1d", i + 1, Keys[i].Res );
        }
    }
#endif	
}

void Pri_Wifi_State ( char LinePos )
{
#if WIFI_Uart1_def
    //3.wifi状态显示
    if ( if_wifi_msg_come )
    {
        if_wifi_msg_come = false;

        if ( WifiProcessStep == WIFI_STEP_CHECK )
        {
            sprintf ( n5110_string[LinePos + 0], "%d,%d,%d", WifiProcessStep, WifiCheckStep, WifiTimeReset );
        }
        else if ( WifiProcessStep == WIFI_STEP_CONNECT )
        {
            sprintf ( n5110_string[LinePos + 0], "%d,%d,%d", WifiProcessStep, WifiConnectStep, WifiTimeReset );
        }
        else if ( WifiProcessStep == WIFI_STEP_CHAT )
        {
            sprintf ( n5110_string[LinePos + 0], "%d,%d,%d", WifiProcessStep, WIFI_LED_FLAG, WifiTimeReset );
        }
    }
#endif	
}



void TEA5767_main ( void )
{
#if TEA5767_def

//UART_Init();//串口初始化
//UART_Send_Str("调频收音机\n");
//radio_write();
//while(1)
    {
        if ( Keys[11 - 1].Res == SHORT_KEY_FLAG )
        {
            Keys[11 - 1].Res = NO_KEY_FLAG;
            search ( 1 );
            radio_read();

            sprintf ( n5110_string[4], "FM:%.1fMHz  ", frequency * 1.0 / 1000 );
        }

        if ( Keys[12 - 1].Res == SHORT_KEY_FLAG )
        {
            Keys[12 - 1].Res = NO_KEY_FLAG;
            search ( 0 );
            radio_read();

            sprintf ( n5110_string[4], "FM:%.1fMHz  ", frequency * 1.0 / 1000 );
        }
    }
#endif
}




void wifi_Handler ( u8 data[] )
{
#if WIFI_Uart1_def

    /*
    	data[3]  应该 = COMMD_TRANSMIT(0x03)
    	data[4]  应该 = REGMY_ID(0x03)
    	data[5]  应该 = AIM_ID(0x02)	或其他人
    */
    if ( ( data[3] == COMMD_TRANSMIT ) && ( data[4] == REGMY_ID ) )
    {

        BACKLIGHT = 1;//开启背光灯

        switch ( data[6] )
        {
        case 0x01://电磁阀控制
            if ( data[7] == 0x01 )	//阀1
            {
                if ( data[8] == 0 )
                    SOLEN_PE8_LOW();
                else if ( data[8] == 1 )
                    SOLEN_PE8_HIGH();
            }
            else if ( data[7] == 0x02 ) //阀2
            {
                if ( data[8] == 0 )
                    SOLEN_PE9_LOW();
                else if ( data[8] == 1 )
                    SOLEN_PE9_HIGH();
            }

            break;

        case 0x02://rtc时钟设置


            break;


        default:
            break;
        }
    }

#endif
}

void sysLed_main ( void )
{
#if SYSLed_def
    static bool sysLedOn = false;
    //200ms
    sysLedOn = !sysLedOn;

    if ( sysLedOn )
        LED_PC7_LOW();
    else
        LED_PC7_HIGH();

#endif
}

void If_NoKey_Backlight_Off ( void )
{
#if LCD_def
    static u16 LCD_Backlight_AutoOff_Time = LCD_Backlight_AutoOff_Time_DEF;

    if ( 0 == LCD_Backlight_AutoOff_Time )
    {
        if ( BACKLIGHT )
        {
            LCD_Backlight_AutoOff_Time = LCD_Backlight_AutoOff_Time_DEF;
        }
    }
    else
    {
        LCD_Backlight_AutoOff_Time--;

        if ( 1 == LCD_Backlight_AutoOff_Time )
        {
            //关闭背光灯
            BACKLIGHT = 0;
        }
    }
#endif
}

void If_KeyDown_Backlight_On ( void )
{
#if LCD_def
    u8 i;
    for ( i = 0; i < 16; i++ )
    {
        if ( Keys[i].Res != NO_KEY_FLAG )
        {
            BACKLIGHT = 1;//开启背光灯
        }
    }
#endif
}


void Long_key_Change_Function ( void )
{
    //切换显示
    if ( Keys[11].Res == ONE_HITS_KEY_FLAG )
    {
        Keys[11].Res = NO_KEY_FLAG;
        memset ( n5110_string, 0x20, sizeof ( n5110_string ) );

        if ( System_Flag_Prin_Music )
        {
            System_Flag_Prin_Time_Temp = 1;
            System_Flag_Prin_Music = 0;
            sprintf ( n5110_string[1], "*************" );
            sprintf ( n5110_string[2], "*   NORMA   *" );
            sprintf ( n5110_string[3], "*************" );
        }
        else
        {
            System_Flag_Prin_Time_Temp = 0;
            System_Flag_Prin_Music = 1;
            sprintf ( n5110_string[1], "*************" );
            sprintf ( n5110_string[2], "*   MUSIC   *" );
            sprintf ( n5110_string[3], "*************" );
        }
    }

}

void Key_Random_play_music ( u8 fold )
{
    if ( Keys[12].Res == ONE_HITS_KEY_FLAG )
    {
        Keys[12].Res = NO_KEY_FLAG;
        //随机播放
        //Random_play_music ( 2 ); //02	TF卡
		Let_One_Music_play ( fold, rand() % 12 );
    }	
}

void key16_main ( void )
{
#if key16_def
    //如果有键按下，打开LCD背光灯
    If_KeyDown_Backlight_On();

    //K0-K9/K0-K5: 数字/播放
    //K10: 模式切换
    YX5200_Key_handler();
	
    //K11: 切换功能
    Long_key_Change_Function();
	
    //K12: 随机播放
    Key_Random_play_music(00);//00文件夹

    //K14: 复位时间
    DS1302_Key_Handler();
#endif

	//12秒没有键，关闭LCD背光灯
	If_NoKey_Backlight_Off();

}

void ESP8266_main ( void )
{
#if WIFI_Uart1_def
    //1.连接服务器
    wifi_main();

    //2.命令处理
    if ( WifiDatCome )
    {
        WifiDatCome = false;
        wifi_Handler ( Wifi_Rec_Buff );
		memset ( Wifi_Rec_Buff, 0, TotalRecvBytes );
    }

#endif
}

/*
	0-5点不报时
	6-23点报时
*/
bool BitH24_0[24]={
	0,0,0,0,0,0,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1	
};
void  Set_time_for_announce_the_hour(void)
{
    if ( ( 59 == DS1302_DateTime.Minute ) && \
            ( 58 == DS1302_DateTime.Second ) )
    {
        if ( BitH24_0[DS1302_DateTime.Hour] )
        {
            Let_One_Music_play ( 24, DS1302_DateTime.Hour + 1 );
        }
    }
}

typedef struct {
	u8 hour;
	u8 min;
	u8 sec;
}tPlay;

//设置一个定时播放
tPlay PlayList[]={
	{6,45,0},
	{255,255,255}
};

void  Set_time_for_play_music(void)
{
	u8 i;
	for(i=0; i<sizeof(PlayList)/sizeof(tPlay); i++)
	{
		if (	( PlayList[i].hour == DS1302_DateTime.Hour ) && \
				( PlayList[i].min == DS1302_DateTime.Minute ) && \
				( PlayList[i].sec == DS1302_DateTime.Second ) )
		{
			Let_One_Music_play ( 00, rand() % 12 );
		}
	}	
}

void Announce_the_hour_and_play_music_Task ( void )
{
#if xy5200_Uart2_def

    //1.整点报时
    Set_time_for_announce_the_hour();

    //2.定时闹钟
    Set_time_for_play_music();

#endif
}



void Timer_TASK1 ( void )
{
    if ( System_Flag_2Ms )
    {
        System_Flag_2Ms = 0;

        //出队列msg
        MSG_Task();

        //wifi连接服务器
        ESP8266_main();
    }

    if ( System_Flag_10Ms )
    {
        System_Flag_10Ms = 0;
        //按键扫描
        KeyHander();

        //uart2接收，进队列msg
        YX5200_UART_Handler();
    }

    if ( System_Flag_100Ms )
    {
        System_Flag_100Ms = 0;
        //系统信号灯
        sysLed_main();

        //按键执行
        key16_main();

        //LCD刷新
        RefreshLCD();

        //music 100ms任务
        Time_Task();
    }

    if ( System_Flag_200Ms )
    {
        System_Flag_200Ms = 0;

    }

    if ( System_Flag_500Ms )
    {
        System_Flag_500Ms = 0;

    }

    if ( System_Flag_1s )
    {
        System_Flag_1s = 0;

        //报时任务
        Announce_the_hour_and_play_music_Task();

        if ( System_Flag_Prin_Time_Temp )
        {
            //显示系统时间
            Pri_Sys_Time ( 0 ); //0-1
            //显示温湿度
            Pri_DHT11_Temp ( 3 ); //3-3
        }

        //显示按下的按键
        Pri_Key_State ( 4 ); //4-4
        //显示wifi状态
        Pri_Wifi_State ( 5 ); //5-5
    }

    if ( System_Flag_8s )
    {
        System_Flag_8s = 0;

        //获取温湿度
        Get_DHT11_Temp();
        //获取时间日期
        Get_DS1302_Time();
    }

    if ( System_Flag_20s )
    {
        System_Flag_20s = 0;
        //自动发送系统信息到控制端
        AutoSend_Time_Temp();
    }
}



extern u32 T1_Val;
extern u32 T2_Val;
extern u32 T3_Val;
extern u32 T4_Val;              

int main ( void )
{
    SystemInit();
	//sysTick
    SYSTICK_Configuration();
	//定时器2
	//TIM2_Configuration();
	//TIM2_NVIC_Configuration();
	
	//测试延时，精确
    sys_ms = 0;
    T1_Val = 0;
	delay_us(1000);
	
    sys_ms = 0;
    T1_Val = 0;
	delay_us(5000);
    
	//上下拉一些端口
    GpioConfiguration_Pull_up_down();
    //4*4按键扫描
    GPIO_ConfigurationKey();
    //电磁阀初始化
    GPIO_ConfigurationSolen();
    //LED D4 ->  GPIOC7
    GPIO_ConfigurationSYSLed();
    //RTC初始化
    GpioConfigurationDS1302();
    DS1302_Init();
    //初始化液晶
    GpioConfigurationLCD();
    InitLcd();
    //初始化wifi	:led、硬复位、UART1
    Configuration_WifiLed();
    Configuration_WIFI_Usart1();
    NVIC_Configuration_WIFI_USART1();
    //Configuration_ResetWifi();
    //WifiHardReset();

	//MP3解码器
    Configuration_YX5200_Usart2();
    NVIC_Configuration_YX5200_USART2();

	//1.SPI1-DMA SD 
	//SPI1_GPIO_Configuration();
	//2.SPI2-DMA

	if(!SD_Init()){
		GUI_Put(0,0, "SD Init OK!", RED, BLACK);	// BLUE
		delay_ms(500);
		GUI_Put(0,0, "故人西辞黄鹤楼", RED, BLACK);	// BLUE
		GUI_Put(0,1, "烟花三月下扬州", RED, BLACK);	// BLUE
		GUI_Put(0,2, "孤帆远影碧空尽", RED, BLACK);	// BLUE
		GUI_Put(0,3, "唯见长江天际流", RED, BLACK);	// BLUE
	}
	else{
		GUI_Put(0,0,  "SD Init Fail!", RED, BLACK);	// BLUE
	}	
    //写入初始化电台频率
    //GpioConfigurationTEA5767();
    //IIC_Init();
    //Set_Frequency(101800); //设置电台频率为101.8MHz
    //radio_write();

    System_Flag_Prin_Time_Temp = 1;
#if (UART1_SD_def&&SPI1_DMA_SD_def)
	//printf("\n\rThe SPI-Flash ID:0x%04X\r\n",SPI_Flash_ReadID());
#endif
	LcdClearAll();
    while ( 1 )
    {
        Timer_TASK1();
    }

}

