/****************************************	头文件	*********************************************/

#include <stdio.h>
#include "delay.h"
#include "usart.h"
#include "EC800M.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "gps.h"
#include "string.h"	  
#include "sdram.h"
#include "ff.h"
#include "diskio.h"
#include "sdio.h"
#include "spi.h"
#include "Function.h"
#include "gpio.h"

#include "w25qxx.h"
#include "malloc.h"
#include "exfuns.h"
#include "usmart.h"
#include "cnn_model.h" 
#include "debug.h"
#include "cnn.h"




void run_dataset(){
	char* modelusearr[] = {
		"C1autosave00095_right_new_2",
		"C1autosave00096_right_new_2",
		"C1autosave00097_right_new_2",
		"C1autosave00098_right_new_2",
		"C1autosave00099_right_new_2",
		"C1autosave00100_right_new_2",
		"C1autosave00101_right_new_2",
		"C1autosave00102_right_new_2",
		"C1autosave00103_right_new_2",
		"C1autosave00104_right_new_2",
		"C1autosave00105_right_new_2",
		"C1autosave00106_right_new_2",
		"C1autosave00107_right_new_2",
		"C1autosave00108_right_new_2",
		"C1autosave00109_right_new_2",
		"C1autosave00110_right_new_2",
		"C1autosave00111_right_new_2",
		"C1autosave00112_right_new_2",
		"C1autosave00113_right_new_2",
		"C1autosave00114_right_new_2",
		"C1autosave00115_right_new_2",
		"C1autosave00116_right_new_2",
		"C1autosave00117_right_new_2",
		"C1autosave00118_right_new_2",
		"C1autosave00119_right_new_2",
		"C1autosave00120_right_new_2",
		"C1autosave00121_right_new_2",
		"C1autosave00122_right_new_2",
		"C1autosave00123_right_new_2",
		"C1autosave00124_right_new_2",

		"filtered_C1autosave00011_right_new",
		"filtered_C1autosave00015_right_new",
		"filtered_C1autosave00043_right_new",
		"filtered_C1autosave00067_right_new",
		"filtered_C1autosave00090_right_new",
		"filtered_C1autosave00106_right_new",
		"filtered_C1autosave00118_right_new",

		"filtered_C1autosave00007_right_new",
		"filtered_C1autosave00035_right_new",
		"filtered_C1autosave00036_right_new",
		"filtered_C1autosave00040_right_new",
		"filtered_C1autosave00053_right_new",
		"filtered_C1autosave00061_right_new",
		"filtered_C1autosave00074_right_new",
		"filtered_C1autosave00077_right_new",
		"filtered_C1autosave00080_right_new",
		"filtered_C1autosave00085_right_new",
		"filtered_C1autosave00098_right_new",
		"filtered_C1autosave00100_right_new",
		"filtered_C1autosave00104_right_new",
		"filtered_C1autosave00122_right_new",
		"filtered_C1autosave00124_right_new",

		"filtered_C1autosave00108_right_new",

		"filtered_C1autosave00004_right_new",
		"filtered_C1autosave00039_right_new",
		"filtered_C1autosave00062_right_new",
	};
	for(int a=0;a<(sizeof(modelusearr) / sizeof(modelusearr[0]));a++){
		SDRAM_USED();
		model_switchdata(modelusearr[a]);
		cnn_run();
	}
	printf("\r\n运行完成\r\n");
}



/****************************************	北斗+4G模块	*********************************************/

unsigned char flag_spi = 0;

extern uint32_t UTC;  			// UTC时间
nmea_msg gpsx;        			// GPS信息
extern int month_def;				//云端下发的时间信息					
extern int date_def;
extern int hour_def;
extern int min_def;
extern int sec_def;
const char* data_identifier = "data_string";			//处理完的100*100数据标识
const char* kind_identifier = "kind_string";			//放电类型标识

/****************************************	FatFs文件系统变量	*********************************************/

FIL file1;                       // 文件对象
FATFS fatfs;                    // 逻辑驱动器的工作区
FILINFO  fno;
FRESULT res;             // FRESULT函数公共结果代码
UINT fnum;            					  /* 文件成功读写数量 */

/****************************************	测试函数	***************************************************/

void SDRAM_test(void);
void SDRAM_SD_test(void);
void FatFs_test(void);
void test__(void);

/*****************************************	主函数	******************************************/

int main(void) 
{
	/*	变量定义	*/
	unsigned char key;
	/************************************* 	外设初始化	******************************************************/
	
	HAL_Init();                     //初始化HAL库   
	Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
	delay_init(180);                //初始化延时函数
	LED_Init();                     //初始化LED 
	KEY_Init();                     //初始化按键
	GPIO_Init();				 //串口初始化
	SDRAM_Init();				 //SDRAM初始化
	SD_Init();					 //SD卡初始化
	SPI_Init();					 //FPGA_STM32通信
 	usart_init1(115200); //pc
	usart_init2(115200); //4g		TX:PA2	Rx:PA3
	usart_init3(115200); //gps
	TIM3_Init(4999,8999);
	
	my_mem_init(SRAMEX);
	model_init();
	usmart_dev.init(90);
	SDRAM_USED();

	Formatting_test();							//SD卡初始化

	model_write("all");

	if( CSTX_4G_Init() )//对设备初始化
	{
		CSTX_4G_RegALiYunIOT(0);//注册到阿里云
	}
	

/************************************************************************************************************/
	
	while (1) {
	/*	按键控制部分	*/
		key = KEY_Scan(0);
		switch (key){
			case KEY1_PRES:
				SPI_Read_SDRAM();		//采集数据存入SDRAM中 32位浮点数
				break;
			case KEY2_PRES:
				SDRAM_TO_SD();		  //将SDRAM的数据存入SD卡	32位浮点数
				break;
			case KEY3_PRES:
				test__();						//一次完整的采集判读	上云+存SD
				break;
			case KEY4_PRES:
				CSTX_4G_RegALiYunIOT(1);	//订阅到物模型 用于数据的上报
				CSTX_4G_ALiYunIOTSenddata_string("21367984",data_identifier);	//上报数据
				CSTX_4G_RegALiYunIOT(0);	//订阅到自定义主题 用于信息的下发
				break;
			default:
				break;
		}
		//若串口接收到北斗下发的信息 则开始数据解包
		if (USART3_RX_STA & 0X8000) {
			GPS_Analysis(&gpsx, USART3_RX_BUF);  // 解析GPS数据
			if (gpsx.utc.hour > 24) {
					gpsx.utc.hour -= 24;
					gpsx.utc.date += 1;
			}
			USART3_RX_STA = 0;  // 重置接收状态
			memset(USART3_RX_BUF, 0, USART3_MAX_RECV_LEN);  //清空缓存
			//显示GPS时间
			printf("year:%u\r\n",gpsx.utc.year);
			printf("month:%u\r\n",gpsx.utc.month);
			printf("date:%u\r\n",gpsx.utc.date);
			printf("hour:%u\r\n",gpsx.utc.hour);
			printf("min:%u\r\n",gpsx.utc.min);
			printf("sec:%u\r\n\r\n",gpsx.utc.sec);
		}
		// 检查是否到达了一个新的整点
		if(CSTX_4G_RECData() == 1){
			while(1){
				if (USART3_RX_STA & 0X8000) {
				GPS_Analysis(&gpsx, USART3_RX_BUF);  // 解析GPS数据
				if (gpsx.utc.hour > 24) {
						gpsx.utc.hour -= 24;
						gpsx.utc.date += 1;
				}
					USART3_RX_STA = 0;  // 重置接收状态
					memset(USART3_RX_BUF, 0, USART3_MAX_RECV_LEN);  //清空缓存
				}
				CSTX_4G_RECData();
				// 若下发定时的时间与北斗下发的时间一致 则启动采集
				if (month_def == gpsx.utc.month && date_def == gpsx.utc.date && hour_def == gpsx.utc.hour && min_def ==gpsx.utc.min && sec_def == gpsx.utc.sec ) {  
					flag_spi = 1;
					while(flag_spi != 0)	printf("……");
					HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);           // 失能中断
					SPI_Read_SDRAM();
					SDRAM_TO_SD();
					HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);           // 使能中断
					month_def = 0;
					break;
				}
			}	
		}
	}
}

/****************************************	以下为测试程序	*********************************************/

void FatFs_test(void)
{
	float tempt;
	res = f_open(&file1,"test.bin",FA_CREATE_ALWAYS | FA_WRITE | FA_READ); // 打开驱动器0上的源文件
	if(res != RES_OK)
	{
		printf("f_open error!\r\n");	// 打开文件失败
		while(1)
		{
			delay_ms(500);
			LED_R=!LED_R;	// 红灯闪烁
		}
	}
	else
	{
		printf("f_open successful!\r\n");// 成功打开文件
	}
	printf("xierukaishi\r\n");
	for(int i=0;i<1300000;i++){
		tempt = i%100 + 0.0;
		res=f_write(&file1,&tempt,4,&fnum);
	}
	printf("xierujieshu\r\n");
	f_sync(&file1);
	res = f_lseek(&file1,0);
	if(res == FR_OK){
		for(int j=0;j<100000;j++){
			res = f_read(&file1, "FatFs_2.txt", 2, &fnum);
		}
	}
	else{
		printf("！！打开文件失败。\r\n");
	}	
	f_close(&file1);
	f_mount(NULL,"0:",1);
}

void SDRAM_test(void)
{
	uint16_t i;
	uint16_t temp;
	printf("开始写入\r\n");
	for(i=0;i<13000;i++)
	{
		*(uint16_t*)(Bank5_SDRAM_ADDR+2*i)=i%1000; 
	}
	printf("写入结束\r\n");
	// 依次读出之前写入的数据,进行校验		  
	for(i=0;i<1024;i++)
	{	
		temp=*(uint16_t*)(Bank5_SDRAM_ADDR+2*i);
		printf("》SDRAM读到的数据：0x%x\r\n",temp);
	}		
}

void SDRAM_SD_test(void)
{
	uint32_t i;
	uint16_t temp;
	Formatting_test();
	res = f_open(&file1,"FatFs.txt",FA_CREATE_ALWAYS | FA_WRITE | FA_READ); // 打开驱动器0上的源文件
	if(res == FR_OK){
		printf("文件打开成功\r\n");
	}
	else{
		printf("文件打开失败\r\n");
	}
	printf("开始写入\r\n");
	for(i=0;i<13000;i++)
	{
		*(uint16_t*)(Bank5_SDRAM_ADDR+2*i)=i%1000; 
	}
	for(i=0;i<13000;i++)
	{	
		temp=*(uint16_t*)(Bank5_SDRAM_ADDR+2*i);
		
		res=f_write(&file1,&temp,2,&fnum);
	}
	f_sync(&file1);
	res = f_lseek(&file1,0);
	if(res == FR_OK){
		uint16_t read_dat;
		for(short int j=0;j<1000;j++){
			res = f_read(&file1, &read_dat, 2, &fnum);
			printf("》文件读取成功,读到字节数据：%d\r\n",read_dat);
		}
	}
	f_close(&file1);
	f_mount(NULL,"0:",1);
}

void test__(void)
{
	SPI_Read_SDRAM();
	cnn_run();													//处理完的10000个数据也在该函数中上传云端
}

void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}


