/**
* author wulianwei
* title 一般工具
*/
#include "sys.h"
//C库
#include <stdarg.h>
#include <string.h>
#include <stdio.h>



uart_recv_t uart_recv = {0};


valid_data_t valid_data = {0};//有效数据

//字节流转HEX字符串
void byteToHexStr(const unsigned char* source, char* dest, int sourceLen)  
{  
    short i;  
    unsigned char highByte, lowByte;  
  
    for (i = 0; i < sourceLen; i++)  
    {  
        highByte = source[i] >> 4;  
        lowByte = source[i] & 0x0f ;  
  
        highByte += 0x30;  
  
        if (highByte > 0x39)  
                dest[i * 2] = highByte + 0x07;  
        else  
                dest[i * 2] = highByte;  
  
        lowByte += 0x30;  
        if (lowByte > 0x39)  
            dest[i * 2 + 1] = lowByte + 0x07;  
        else  
            dest[i * 2 + 1] = lowByte;  
    }  
    return ;  
}

/**
* 字母大小写转换, flag = 1 转大写, flag =0 转小写
*/
void letterSwitch(char *str, int flag)
{
    int data;
    while (*str != '\0')
    {
        if (flag)
        {
            if (*str >= 'a' && *str <= 'z')
            {
                *str = *str - 32;
            }
        }
        else
        {
            if (*str >= 'A' && *str <= 'Z')
            {
                *str = *str + 32;
            }
        }
        str++;
    }
}

void inttohex(u16 value,u8 *hex)
{
	u16 x1;
	hex[0]=value/(16*16*16)+'0';
	x1=value%(16*16*16);
	hex[1]=x1/(16*16)+'0';
	x1=value%(16*16);
	hex[2]=x1/16+'0';
	x1=value%16;
	hex[3]=x1+'0';	
	hex[4]=' ';		 

}

/**
* 整形字符串转整形数字
*/
int my_atoi(char *str)
{
    int n = 0;
    int flag = 0;
    if(*str == '-')
    {
        flag = 1;
        str++;
    }
    while(*str >= '0' && *str <= '9')
    {
        n = n*10 + (*str - '0');
        str++;
    }
    if(flag == 1)
    {
        n = -n;
    }
    return n;
}

/**
* 整形字符串转正整形64位数字
*/
uint64_t my_atoui64(char *str)
{
    uint64_t n = 0;
    int flag = 0;
    if(*str == '-')
    {
        str++;
    }
    while(*str >= '0' && *str <= '9')
    {
        n = n*10 + (*str - '0');
        str++;
    }
    return n;
}

/**
* 整形字符串转整形数字绝对值
*/
int my_atoabs(char *str)
{
    int n = 0;
    if(*str == '-')
    {
        str++;
    }
    while(*str >= '0' && *str <= '9')
    {
        n = n*10 + (*str - '0');
        str++;
    }
    return n;
}

/**
* 整形转字符串
* num:待转的数据,str:目标地址,radix:进制2,8,10,16
*/
char* my_itoa(int num,char* str,int radix)
{
    char index[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//索引表
    unsigned unum;//存放要转换的整数的绝对值,转换的整数可能是负数
    int i=0,j,k;//i用来指示设置字符串相应位，转换之后i其实就是字符串的长度；转换后顺序是逆序的，有正负的情况，k用来指示调整顺序的开始位置;j用来指示调整顺序时的交换。
 
    //获取要转换的整数的绝对值
    if(radix==10&&num<0)//要转换成十进制数并且是负数
    {
        unum=(unsigned)-num;//将num的绝对值赋给unum
        str[i++]='-';//在字符串最前面设置为'-'号，并且索引加1
    }
    else unum=(unsigned)num;//若是num为正，直接赋值给unum
 
    //转换部分，注意转换后是逆序的
    do
    {
        str[i++]=index[unum%(unsigned)radix];//取unum的最后一位，并设置为str对应位，指示索引加1
        unum/=radix;//unum去掉最后一位
 
    }while(unum);//直至unum为0退出循环
 
    str[i]='\0';//在字符串最后添加'\0'字符，c语言字符串以'\0'结束。
 
    //将顺序调整过来
    if(str[0]=='-') k=1;//如果是负数，符号不用调整，从符号后面开始调整
    else k=0;//不是负数，全部都要调整
 
    char temp;//临时变量，交换两个值时用到
    for(j=k;j<=(i-1)/2;j++)//头尾一一对称交换，i其实就是字符串的长度，索引最大值比长度少1
    {
        temp=str[j];//头部赋值给临时变量
        str[j]=str[i-1+k-j];//尾部赋值给头部
        str[i-1+k-j]=temp;//将临时变量的值(其实就是之前的头部值)赋给尾部
    }
 
    return str;//返回转换后的字符串
 
}



/**
* @Title split,分割字符串
* @Param src:源数据, separator:分割符, dest:目标地址, size:分割数量
*/
 void split(char *src,const char *separator,char *dest[],int size) 
{
   char *pNext;
   int count = 0;
   if (src == NULL || strlen(src) == 0)
      return;
   if (separator == NULL || strlen(separator) == 0)
       return;    
    pNext = strtok(src,separator);
    while(pNext != NULL) 
	{
         dest[count] = pNext;
         ++count;
				 if(size <= count)
					break;
         pNext = strtok(NULL,separator);  
		    
   }  
 } 

 /**
* @Title split,分割字符串
* @Param src:源数据, separator:分割符, dest:目标地址, limit:分割限制数量
*/
int splitCharLimit(char *str, char seprator, char *dest[], int limit) 
{
	int i, length, ct = 0, start = -1;
	length = strlen(str);
	for (i = 0; i <= length; i++) {
		if (start == -1 && limit <= ct + 1) {
			dest[ct] = &str[i];
			return ct+1;
		}
		if (str[i] == seprator) {
			if (start != -1) {
				dest[ct] = &str[start]; /* set up pointer */
				ct++;
			}
			str[i] = '\0'; /* add a null char; make a C string */
			start = -1;
		} else {
			if (start == -1) {
				start = i;

			}
		}

	}
	return ct+1;

}

 void delay_ms(uint32_t ms)
{
	unsigned int i,j;  
		for(j=0;j<ms;j++)
			{ 
		     for(i=0;i<1500;i++); 
			} 
}

/************************************************************
*	函数名称：	Usart_SendString
*
*	函数功能：	串口数据发送
*
*	入口参数：	USARTx：串口组
*				str：要发送的数据
*				len：数据长度
*
*	返回参数：	无
*
*	说明：		
************************************************************
*/
void Usart_SendString(USART_TypeDef *USARTx, unsigned char *str, unsigned short len)
{

	unsigned short count = 0;
	
	for(; count < len; count++)
	{
		USART_SendData(USARTx, *str++);									//发送数据
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);		//等待发送完成
	}

}

/*
************************************************************
*	函数名称：	UsartPrintf
*
*	函数功能：	格式化打印
*
*	入口参数：	USARTx：串口组
*				fmt：不定长参
*
*	返回参数：	无
*
*	说明：		
************************************************************
*/
void UsartPrintf(USART_TypeDef *USARTx, char *fmt,...)
{

	//return ;
	unsigned char UsartPrintfBuf[512];
	va_list ap;
	unsigned char *pStr = UsartPrintfBuf;
	
	va_start(ap, fmt);
	vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);							//格式化
	va_end(ap);
	
	while(*pStr != 0)
	{
		USART_SendData(USARTx, *pStr++);
		while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
	}

}

/**
*@Title 清空串口接收缓存
*/
void uart_recv_clear(void)
{
	memset(uart_recv.buf,0,sizeof(uart_recv.buf));
	uart_recv.len = 0;
	uart_recv.recv_flag = REV_WAIT;
}

void valid_data_clear(void)
{
	valid_data.len = 0;
	memset(valid_data.buf,0,sizeof(valid_data.buf));
}

/**
*@Title 串口接收数据
*@Param timeout:等待时间(ms)
*/
void uart_recv_wait(int timeout)
{
	int per = 5; //轮询间隔单位ms
	int prelen = 0;
	if(timeout<=0) return;
	timeout=timeout/per+(timeout%per==0? 0 : 1);
	while(timeout--)
	{
		if(uart_recv.len)
		{
			if(uart_recv.len == prelen)
			{
				uart_recv.recv_flag = REV_OK; //接收完成
				break;
			}
			else
			{
				prelen = uart_recv.len;
			}
		}
		delay_ms(per);
	}
	
}

/**
*@Title 串口接收数据匹配特定字符串
*@Param res:匹配的字符串,timeout:等待时间(ms)
**@Return 0:成功, -1:失败
*/
int uart_recv_match_wait(char *res,int timeout)
{
	int per = 5; //轮询间隔单位ms
	if(timeout<=0) return -1;
	timeout=timeout/per+(timeout%per==0? 0 : 1);
	while(timeout--)
	{
		if(strstr(uart_recv.buf,res))
		{
			uart_recv.recv_flag = REV_OK; //接收完成
			return 0;
		}
		delay_ms(per);
	}
	return -1;
}

