//接口部分

//#include <string.h>

//#include "stm32f10x_flash.h"
#include "YModem.h"
#include "common.h"
//#include "Download.h"
//#include "nrf24l01.h"
//#include "bsp.h"

//static FunVoidType JumpToApplication;
static FunU32Type FunReceEnter = NULL;
static FunU32Type FunReceExit = NULL;
//static FunWriteType FunWrite = NULL;
static FunProcessType FunCurrentProcess = NULL;

//static u32 m_JumpAddress;
//static u32 m_ProgramAddr = ApplicationAddress;
//volatile SerialBuffType m_ReceData = SerialBuffDefault();

static volatile eCOM_STATUS m_Mode = eCOMChoose;
//static vu32 m_FlashAddress = 0;
//static vu32 m_ExtFlashCounter = 0;//外部FLASH擦除的扇区号
//static u8 echo = 1;

u8 file_name[FILE_NAME_LENGTH];

////打印消息  串口发送
//static void Print(u8 *str)
//{
//    u16 len = strlen((const char *)str);
//    while (BspUsart1Send(str, len) != TRUE);
//}

////接收到一个字符
//static void ReceOneChar(u8 ReceCharacter)
//{
//    if (m_ReceData.ind >= USART1_BUFF_LANGTH)
//        return;
//        
//    if (m_ReceData.len > 0)
//        return;
//        
//    m_ReceData.buf[m_ReceData.ind++] = ReceCharacter;
//	if (echo)
//		USART1_SendByte(ReceCharacter);//串口1发送一个字符
//    BspTim3Open();//定时器重新计数
//}

////接收字符超时回调函数
//static void TimEndHandle(void)
//{
//    BspTim3Close();

//    m_ReceData.len = m_ReceData.ind;
//    m_ReceData.ind = 0;
//}

////跳转到应用程序区
//static void JumpToApp(void)
//{
//    if (((*(vu32*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
//    { 
//		LedOff(LED_0);
//        BspClose();

//        m_JumpAddress = *(vu32*) (ApplicationAddress + 4);
//        JumpToApplication = (FunVoidType) m_JumpAddress;
//        __MSR_MSP(*(vu32*) ApplicationAddress);
//        JumpToApplication();
//    }
//}

void PrintAddr(char *str,u8 *addr)
{
//	u8 i;

//	printf("%s:",str);
//	for(i=0;i<MAC_LEN;i++)
//	{
//		printf("%02x,",addr[i]);
//	}
//	printf("\r\n");
//}

////操作选择 200ms内有收到指令 进入bootload区
//static void AppChoose(u8 *pData, u32 *pLen, volatile eCOM_STATUS *peStat)
//{
//    static u8 flg = 0;
//	u8 mac_buf[MAC_LEN+1]={0};
//    
//    if (*pLen > 0)
//    {
//		if (m_ReceData.len > 1)
//		{
//			if(strstr((char *)m_ReceData.buf,"nrf-addr?"))
//			{
//				printf("=========NRF ADDR=========\r\n");
//				NRF_ReadBuf(TX_ADDR,mac_buf,MAC_LEN);//读出TX地址
//				PrintAddr("TX_ADDR",mac_buf);
//				NRF_ReadBuf(RX_ADDR_P0,mac_buf,MAC_LEN);//读出Pipe0地址
//				PrintAddr("Pipe0_ADDR",mac_buf);
//				NRF_ReadBuf(RX_ADDR_P1,mac_buf,MAC_LEN);//读出Pipe1地址
//				PrintAddr("Pipe1_ADDR",mac_buf);
//				NRF_ReadBuf(RX_ADDR_P2,mac_buf,1);//读出Pipe2地址
//				PrintAddr("Pipe2_ADDR",mac_buf);
//				NRF_ReadBuf(RX_ADDR_P3,mac_buf,1);//读出Pipe3地址
//				PrintAddr("Pipe3_ADDR",mac_buf);
//				NRF_ReadBuf(RX_ADDR_P4,mac_buf,1);//读出Pipe4地址
//				PrintAddr("Pipe4_ADDR",mac_buf);
//				NRF_ReadBuf(RX_ADDR_P5,mac_buf,1);//读出Pipe5地址
//				PrintAddr("Pipe5_ADDR",mac_buf);
//				printf("==========================\r\n");
//			}
//			else if(strstr((char *)m_ReceData.buf,"nrf-s"))
//			{
//				//printf("send_addr=%d value=%d\r\n",NodeStatus.addr,value);
//				SendData(NodeStatus.addr,ONE_DATA,255,NULL,NULL);
//				printf("pack_idx=%d pack_num=%d last_len=%d\r\n",pack_idx,pack_num,last_len);
//			}
//			else if(strstr((char *)m_ReceData.buf,"nrf-reg"))
//			{
//				printf("======NRF REG======\r\n");
//				printf("CONFIG=%02x\r\n",NRF_ReadReg(CONFIG));
//				printf("EN_AA=%02x\r\n",NRF_ReadReg(EN_AA));
//				printf("EN_RXADDR=%02x\r\n",NRF_ReadReg(EN_RXADDR));
//				printf("SETUP_AW=%02x\r\n",NRF_ReadReg(SETUP_AW));
//				printf("SETUP_RETR=%02x\r\n",NRF_ReadReg(SETUP_RETR));
//				printf("RF_SETUP=%02x\r\n",NRF_ReadReg(RF_SETUP));
//				printf("STATUS=%02x\r\n",NRF_ReadReg(STATUS));
//				printf("RX_PW_P0=%02x\r\n",NRF_ReadReg(RX_PW_P0));
//				printf("RX_PW_P1=%02x\r\n",NRF_ReadReg(RX_PW_P1));
//				printf("FIFO_STATUS=%02x\r\n",NRF_ReadReg(FIFO_STATUS));
//				printf("CD=%02x\r\n",NRF_ReadReg(CD));
//				printf("==================\r\n");
//			}
//		}
//		else
//		{
//			if (*pData == 0x04)
//			{
//				if (flg == 0)
//					flg++;
//	
//				if (flg && IS_TIMEOUT_1MS(eTim1, 200))  //二次确认
//					*peStat = eCOMDisplay;
//			}
//			else
//			{
//				Print("\r\nInput Ctrl + D\r\n");
//			}
//		}
//        *pLen = 0;
//    }
}

//显示提示消息
static void DisplayMessage(u8 *pData, u32 *pLen, volatile eCOM_STATUS *peStat)
{
//    *pLen = 1;
//    strcpy((char *)pData, "\r\n1-更新应用区程序\r\n");
//    strcat((char *)pData, "2-运行APP程序\r\n");
//    strcat((char *)pData, "请选择:\r\n");
//    *peStat = eCOMInput;
//    
//    Print(pData);
//    *pLen = 0;
}

//操作选择
static void InputSelect(u8 *pData, u32 *pLen, volatile eCOM_STATUS *peStat)
{
//    if (*pLen > 0)
//    {
//        switch (*pData)
//        {
//			case '1': 
//				m_ProgramAddr = ApplicationAddress; 
//				FunReceEnter = NRF_SendStart;
//				FunWrite = NRF_SendBank;
//				FunReceExit = NRF_SendDone;
//				*peStat = eCOMReceive;
//				Print("\r\n请选择要发送文件\r\n");
//				echo = 0;
//				break;    
//				
//			case '2': 
//				*peStat = eCOMChoose; 
//				Print("\r\n运行程序...\r\n");
//				break;    
//				
//			default :
//				Print("\r\n错误...\r\n");
//				break;
//        }
//        *pLen = 0;
//    }
}

//YModem协议接收数据，并存储数据
static void ReceiveData(u8 *pData, u32 *pLen, volatile eCOM_STATUS *peStat)
{
    u8 pArray[1028] = {0,};
	u8 file_size[FILE_SIZE_LENGTH];
	u8 *file_ptr;
	u32 binSize;
    int i, len = 0;
    
    switch (YmodemReceive((char *)(pData), (int *)pLen, (char *)pArray, (int *)&len))
    {
		case YM_FILE_INFO: 
            if (pArray[PACKET_HEADER] != 0)//文件名数据包
            {
                //文件名数据包有效数据区域
                for (i = 0, file_ptr = pArray + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
                {
                    file_name[i++] = *file_ptr++;
                }
                file_name[i++] = '\0';
				
                for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);)
                {
                    file_size[i++] = *file_ptr++;
                }
                file_size[i++] = '\0';
				binSize = strtol((char *)file_size,NULL,10);

                //测试数据包是否过大
                if (binSize > (1024 * 50 - 1))
                {
					binSize = 0;
					//FunReceEnter = NULL;
                }
            }
			if (FunReceEnter) (*FunReceEnter)(binSize);//开始函数
			break;
			
		case YM_FILE_DATA: 
//			if (FunWrite) (*FunWrite)(pArray, m_ProgramAddr, len);//接收数据函数
//			m_ProgramAddr += len;
			break;
			
		case YM_EXIT: 
			if (FunReceExit) (*FunReceExit)(binSize);//接收完毕函数
			
			FunReceEnter = NULL;
//			FunWrite = NULL;
			FunReceExit = NULL;
			*peStat = eCOMChoose;
//			Print("\r\n接收完成...");
			break;
		
		default :break;
    }
}

//接口初始化
void CommonInit(void)
{
//    BspTim3SetIRQCallBack(TimEndHandle);
//    BspUsart1IRQCallBack(ReceOneChar);
}

//接口函数
void CommonExec(void)
{
    switch (m_Mode)
    {
		case eCOMChoose:    //判断进入 IAP程序 还是APP程序
//			FunCurrentProcess = AppChoose;
			break;
			
		case eCOMDisplay:   //IAP操作显示
			FunCurrentProcess = DisplayMessage;
			break;
			
		case eCOMInput:     //IAP操作选择
			FunCurrentProcess = InputSelect;
			break;
	
		case eCOMReceive:   //YMODEM 接收数据
			FunCurrentProcess = ReceiveData;
			break;
			
		default:
			m_Mode = eCOMChoose;
			break;
    }
//	(*FunCurrentProcess)((u8 *)(m_ReceData.buf), (u32 *)&(m_ReceData.len), &m_Mode);
    (*FunCurrentProcess)((u8 *)(USART1_Recv_Buff), (u32 *)&(USART1_ReceDatalen), &m_Mode);
}
