/*往W25Q128写入数据*/
#include "system.h"
#include "W25Q128_Ins.h"
#include "USART.h"
#include "rtc.h"
#include "SysTick.h"
#include "myfreertos.h"


// extern u8 buf[51];

extern u8 RS485_RX_BUF[128]; //
extern u8 store_stage;
u8 read_stage = 1; // stage from flash
extern u8 now_stage;
extern u8 chour;
extern u8 cminute;
extern PID pid;
u16 current_minute = 0;
u16 total_minute = 0;
/*
六个阶段：每个阶段4个小时
初始值（十倍存储） ： 温度：25
					 湿度：70
										 光照：10
*/
u8 total[] = {0xEE, 0XEE, 0x01, 0x04, 0x00, 0x00, 0xFA, 0x02, 0xBC, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0xFF, 0xFF, 0xFF,
			  0xEE, 0XEE, 0x02, 0x04, 0x00, 0x00, 0xFA, 0x02, 0xBC, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0xFF, 0xFF, 0xFF,
			  0xEE, 0XEE, 0x03, 0x04, 0x00, 0x00, 0xFA, 0x02, 0xBC, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0xFF, 0xFF, 0xFF,
			  0xEE, 0XEE, 0x04, 0x04, 0x00, 0x00, 0xFA, 0x02, 0xBC, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0xFF, 0xFF, 0xFF,
			  0xEE, 0XEE, 0x05, 0x04, 0x00, 0x00, 0xFA, 0x02, 0xBC, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0xFF, 0xFF, 0xFF,
			  0xEE, 0XEE, 0x06, 0x04, 0x00, 0x00, 0xFA, 0x02, 0xBC, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0xFF, 0xFF, 0xFF};


void Array(u8 *n, u8 *hour, u8 *min, u16 *tem, u16 *hum, u16 *red, u16 *blue, u16 *white)
{
	*hour = (total[3 + 18 * (*n - 1)]);
	*min = (total[4 + 18 * (*n - 1)]);
	*tem = (total[5 + 18 * (*n - 1)] << 8 | total[6 + 18 * (*n - 1)]);	   // 温度
	*hum = (total[7 + 18 * (*n - 1)] << 8 | total[8 + 18 * (*n - 1)]);	   // 湿度
	*red = (total[9 + 18 * (*n - 1)] << 8 | total[10 + 18 * (*n - 1)]);	   // 红光
	*blue = (total[11 + 18 * (*n - 1)] << 8 | total[12 + 18 * (*n - 1)]);  // 蓝光
	*white = (total[13 + 18 * (*n - 1)] << 8 | total[14 + 18 * (*n - 1)]); // 白光
}

uint8_t ArrayRead[108];
uint8_t ArrayWrite[108];

uint8_t pidsRead[10];
uint8_t pidsWrite[10];

void Write_Init(void)
{

	W25QXX_Init();
	W25QXX_Erase_Sector(0x000000);

	
	W25QXX_Write(total, 0x000000, 108);		 // write data to flash
	if (store_stage <= 0 || store_stage > 6) {
		store_stage = 1;
	}
	W25QXX_Write(&store_stage, 0x001000, 1); // write current stage to flash

	pidsWrite[0] = (int)pid.Kp / 256;			  // Kp 110
	pidsWrite[1] = (int)(pid.Kp) % 256;			  // Kp 110
	pidsWrite[2] = ((int)(pid.Ki * 100000)) / 256; // Ti 0.001
	pidsWrite[3] = ((int)(pid.Ki * 100000)) % 256; // Ti 0.001
	pidsWrite[4] = (int)pid.Kd / 256;			  // Td 340
	pidsWrite[5] = (int)pid.Kd % 256;			  // Td 340

	int tem_offset_10times = (int)(pid.tem_offset * 10);

	if (tem_offset_10times < 0) {
		tem_offset_10times = (~(tem_offset_10times - 1)) & 0xFFFF;
	}
	pidsWrite[6] = tem_offset_10times / 256;
	pidsWrite[7] = tem_offset_10times % 256;

	pidsWrite[8] = ((int)(pid.tem_threshold * 10)) / 256;
	pidsWrite[9] = ((int)(pid.tem_threshold * 10)) % 256;


	// // wtite p i d
	W25QXX_Write(pidsWrite, 0x002000, 10); // p i d tem_offset tem_threshold, 2bytes for each

	W25QXX_Read(ArrayRead, 0x000000, 108);


}
void Read_Init(void)
{
	W25QXX_Init();
	W25QXX_Read(ArrayRead, 0x000000, 108);
	bufcut_Init(total, ArrayRead, 0, 108);
	W25QXX_Read(&read_stage, 0x001000, 1);
	now_stage = read_stage;
	// if (now_stage <= 0 || now_stage > 6) {
	// 	now_stage = 3;
	// }
	// now_stage = 3;

	// read p i d
	W25QXX_Read(pidsRead, 0x002000, 8); // p i d tem_offset tem_threshold, 2bytes for each
	float Kp = pidsRead[0] * 256.0 + pidsRead[1];
	float Ki = (pidsRead[2] * 256.0 + pidsRead[3]) / 100000.0;
	float Kd = pidsRead[4] * 256.0 + pidsRead[5];
	int tem_offset_10times = pidsRead[6] * 256.0 + pidsRead[7];
	// Negative tem offset treatment
	if (tem_offset_10times & 0x8000)
	{
		tem_offset_10times = ((~tem_offset_10times + 1) & 0xFFFF);
	}
	float tem_offset = tem_offset_10times / 10.0;
	
	float tem_threshold = (pidsRead[8] * 256.0 + pidsRead[9]) / 10.0;

	// pid.Kp = 120;
	if (Kp > 1e-3) { pid.Kp = Kp; }
	if (Ki > 1e-3) { pid.Ki = Ki; }
	if (Kd > 1e-3) { pid.Kd = Kd; }
	pid.tem_offset = tem_offset;
	if (tem_threshold > 1e-3) { pid.tem_threshold = tem_threshold; }
	// pid.Ki = 0.002;
	// pid.Kd = 300;
	// pid.Kp = pidsRead[0] * 256.0 + pidsRead[1];
	// pid.Ki = (pidsRead[2] * 256.0 + pidsRead[3]) / 100000.0;
	// pid.Kd = pidsRead[4] * 256.0 + pidsRead[5];


	// printf("%d\r\n",now_stage);
	// printf("\r\n");
	// printf("\r\n");
	//	for(int i=0;i<108;i++)
	//	 {
	//		printf("%d ",ArrayRead[i]);
	//	 }
}

void Analysis(u8 *n, u16 *i, u8 *rs485_rx_buf)
{
	*n = rs485_rx_buf[3];
	*i = rs485_rx_buf[4];

	if (*i == 2)
	{
		total[3 + 18 * (*n - 1)] = rs485_rx_buf[5]; // 时
	}
	if (*i == 3)
	{
		total[4 + 18 * (*n - 1)] = rs485_rx_buf[5]; // 分
	}
	if (*i >= 4 && *i <= 8) // 温湿度红蓝白光
	{
		total[(2 * (*i) - 3) + 18 * (*n - 1)] = rs485_rx_buf[5];
		total[(2 * (*i) - 2) + 18 * (*n - 1)] = rs485_rx_buf[6];
	}
}

void Batch_synchronization(u8 *n, u8 *rs485_rx_buf) // batch sync
{

	*n = rs485_rx_buf[3];
	u8 i = 4;
	for (i = 4; i < 16; i++)
	{
		total[(i - 1) + 18 * (*n - 1)] = rs485_rx_buf[i];
	}
}

u8 timelong_Compare()
{
	RTC_Get(&chour, &cminute); // 获得当前小时与分钟
	current_minute = chour * 60 + cminute;
	total_minute = total[18 * now_stage - 15] * 60 + total[18 * now_stage - 14];

	if (current_minute >= total_minute)
	{
		RTC_synchronization_ins(2023, 9, 1, 0, 00, 00);
		if (now_stage == 6)
		{
			store_stage = 1;
			Write_Init();
			return 1;
		}
		store_stage = now_stage + 1;
		Write_Init();
		return now_stage + 1;
	}
	store_stage = now_stage;
	return now_stage;
}

int isAllZeros(u8 arr[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (arr[i] != 0)
		{
			return 0; // 返回0表示不全为0
		}
	}
	return 1; // 返回1表示全为0
}
