#include "main.h"
#include "sram.h"
#include "nandflash.h"
#include "usart.h"
#include "malloc.h"
#include "demo_nand_fatfs.h"
#include "cjson.h" 
#include "delay.h"
#include "string.h"
#include "includes.h"
#include "lwip/timers.h"
#include "led.h"

#include "sys_tcpdemo.h"
#include "sys_mqtt.h"
#include "sys_http.h"
#include "task.h"
#include "sys_sx1278.h"
#include "node_data_acquisition.h"
#include "log.h"
#include "tcp_server.h"


#define UNIQUE_ID 0x1fff7a10



/*关于任务优先级分配（上限为12个、需要增加请修改上限）
*  0: 保留
*  1: 用于ucos的软件定时器
*	 2: 保留
*  3: 用于 以太网的网卡数据包读取  ETHERNETIF_THREAD_PRO
*  4: LWIP 核心线程    TCPIP_THREAD_PRIO
*  5: 用于 ota升级
*  6: 用于 MQTT数据发送线程  APP_TASK_MQTTMAIN_PRIO
*  7: 用于 MQTT数据接收线程  APP_TASK_MQTTRECEIVE_PRIO
*  8: 用于 sx1278发送/接收处理数据	DATA_TASK_PRIO
*  9: 用于 本机状态led显示      / 现用于tcpServer_init   TCP_TASK_PRIO /
* 10：用于网络状态led显示
* 11：用于轮询读出本机保存信息发送到sx1278发送接收线程
* 12：用于管理所有线程
*/



///////////////////////////////////////
#define  PERIOD_TASK_PRIO     2
#define  PERIOD_STK_SIZE  	 	2048
OS_STK 	 PERIOD_TASK_STK[PERIOD_STK_SIZE];
void period_taskFuntcion(void *arg);

//////////////////////////////////////////////
//LED
//LED优先级
#define LED_TASK_PRIO       	28
//LED栈空间大小
#define LED_STK_SIZE  	    	128
//任务堆栈
OS_STK LED_TASK_STK[LED_STK_SIZE];
//led运行任务
void led_taskFuntcion(void *pdata);
////////////////////////////////////////////////////////

/*---------------------------本地数据线程堆栈----------------------------------------------------------------*/
__align(8) OS_STK DATA_TASK_STK[DATA_STK_SIZE];
/*---------------------------lora通信线程堆栈----------------------------------------------------------------*/
__align(8) OS_STK SX1278_TASK_STK[SX1278_STK_SIZE];

void NVIC_Configuration(void);
void load_unique(void);

char  gatewayId[11];
int main(void)
{
	int status;
	load_unique();
	sprintf(gatewayId,"DTtest0001");//DT8pd3ac6h  DTbma5ac6h  DTtest0001
	NVIC_Configuration();
	my_mem_init(SRAMEX);
	my_mem_init(SRAMIN);
	delay_init();
 
	//nandflash并不用初始化，调用fafts时会初始化
	NET_STATUS_LED_Config();
	USART_485_config();	
  USART_485_DE_TX();
  USART_232_config();	
	status = NAND_Init();
	while(status){
		NAND_Format();
		status = NAND_Init();
	}
	OSInit();
	#if 0
	//OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO);
	OSTaskCreate(period_taskFuntcion,(void*)0,(OS_STK*)&PERIOD_TASK_STK[PERIOD_STK_SIZE-1],PERIOD_TASK_PRIO);
	OSTaskCreate(led_taskFuntcion,(void*)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);
	OSTaskCreate(sx1278_send_task,(void *)0,(OS_STK*)&SX1278_TASK_STK[SX1278_STK_SIZE-1],SX1278_TASK_PRIO);
	#endif
	OSTaskCreate(period_taskFuntcion,(void*)0,(OS_STK*)&PERIOD_TASK_STK[PERIOD_STK_SIZE-1],PERIOD_TASK_PRIO);
	OSTaskCreate(data_task,(void*)0,(OS_STK*)&DATA_TASK_STK[DATA_STK_SIZE-1],DATA_TASK_PRIO);
	printf("system start \r\n");
	OSStart(); //ucos启动
  /* Infinite loop */
  while (1)
  {
		
  }
	
}

void period_taskFuntcion(void *arg)
{
	OS_CPU_SR cpu_sr;

#if OS_TASK_STAT_EN > 0u
  OSStatInit();
#endif

	int time1,time2;
	time1 = OSTimeGet();
	lwIP_Init();

	// 输出日志
//	log_init();
//	tcp_server_init();
	
//	LogPrint(LOG_INFO,__FILE__, __FUNCTION__, __LINE__, "system start");
	time2 = OSTimeGet() - time1;
	http_getDemo();
	http_postDemo();

	mqtt_threadCreate();
	
	OSTaskSuspend(OS_PRIO_SELF); 
}

//测试任务
void led_taskFuntcion(void *pdata)
{
	int tms;
	
	while(1)
	{
		tms = hd_netledOpen();
		OSTimeDly(tms);				
	
		tms = hd_netledClose();
		OSTimeDly(tms);	
	}
}



void bsp_Idle(void)
{
	/* --- 喂狗 */

	/* --- 让CPU进入休眠，由Systick定时中断唤醒或者其他中断唤醒 */
}
 /**
  * @brief  配置嵌套向量中断控制器NVIC分组
  * @param  无
  * @retval 无
  */
void NVIC_Configuration(void)
{
//  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
 // while (1)
 //{}
}
#endif
/*
 *  函数名：void readID()
 *  输入参数：无
 *  输出参数：strId
 *  返回值：无
 *  函数作用：读取长度12的芯片Id并组合从中取出对应字符防止其重复
 */

void load_unique(void)
{
	char *hex_table = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN";
	uint32_t CpuID1, CpuID2, CpuID3;
	CpuID1 = *(volatile uint32_t *)(UNIQUE_ID);
	CpuID2 = *(volatile uint32_t *)(UNIQUE_ID+8);
	CpuID3 = *(volatile uint32_t *)(UNIQUE_ID+16);
	char strId[11];

	for (uint8_t i = 0, j = 0; i < 8; i += 2)
	{
		uint32_t sum1 = (CpuID1 >> ((j % 4) * 8)) & 0xFF; // 按字节取出
		uint8_t index1 = sum1 / 16;
		uint8_t remainder1 = sum1 % 16;

		uint32_t sum2 = (CpuID2 >> ((j % 4) * 8)) & 0xFF; // 按字节取出
		uint8_t index2 = sum2 / 16;
		uint8_t remainder2 = sum2 % 16;

		uint32_t sum3 = (CpuID3 >> ((j % 4) * 8)) & 0xFF; // 按字节取出
		uint8_t index3 = sum3 / 16;
		uint8_t remainder3 = sum3 % 16;

		strId[i + 2] = hex_table[index1 + index2 + index3];
		strId[i + 1 + 2] = hex_table[remainder1 + remainder2 + remainder3];

		j++;
	}
	strId[10] = '\0';
	strId[0]='L';
	strId[1]='R';
	strcpy(gatewayId,strId);
}
/*
 *  函数名：void load_232_config()
 *  输入参数：无
 *  输出参数：strId
 *  返回值：无
 *  函数作用：加载本地存储配置如果上位机配置过则不走http配置路线，防止两线冲突
 */

