rt-thread/bsp/airm2m/air105/libraries/HAL_Driver/Src/bsp_common.c

1262 lines
29 KiB
C
Raw Normal View History

/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "bsp_common.h"
const uint8_t ByteToAsciiTable[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void LoopBuffer_Init(Loop_Buffer *Buf, void *Src, uint32_t MaxLen, uint32_t DataSize)
{
uint8_t *Data = (uint8_t *)Src;
Buf->Data = Data;
Buf->Len = 0;
Buf->MaxLength = MaxLen;
Buf->Offset = 0;
Buf->DataSize = DataSize;
}
uint32_t LoopBuffer_Query(Loop_Buffer *Buf, void *Src, uint32_t Len)
{
uint32_t i, p;
uint8_t *Data = (uint8_t *)Src;
if (Buf->Len < Len)
{
Len = Buf->Len;
}
if (Buf->DataSize > 1)
{
for (i = 0, p = Buf->Offset; i < Len; i++, p++)
{
if (p >= Buf->MaxLength)
{
p -= Buf->MaxLength;
}
memcpy(Data + (i * Buf->DataSize), Buf->Data + (p * Buf->DataSize), Buf->DataSize);
}
}
else
{
for (i = 0, p = Buf->Offset; i < Len; i++, p++)
{
if (p >= Buf->MaxLength)
{
p -= Buf->MaxLength;
}
Data[i] = Buf->Data[p];
}
}
return Len;
}
uint32_t LoopBuffer_Read(Loop_Buffer *Buf, void *Src, uint32_t Len)
{
uint32_t l;
uint8_t *Data = (uint8_t *)Src;
l = LoopBuffer_Query(Buf, Data, Len);
Buf->Len -= l;
Buf->Offset += l;
if (Buf->Offset >= Buf->MaxLength)
{
Buf->Offset -= Buf->MaxLength;
}
if (!Buf->Len) {
Buf->Offset = 0;
}
return l;
}
void LoopBuffer_Del(Loop_Buffer *Buf, uint32_t Len)
{
if (Buf->Len < Len)
{
Len = Buf->Len;
}
Buf->Len -= Len;
Buf->Offset += Len;
if (Buf->Offset >= Buf->MaxLength)
{
Buf->Offset -= Buf->MaxLength;
}
if (!Buf->Len) {
Buf->Offset = 0;
}
}
uint32_t LoopBuffer_Write(Loop_Buffer *Buf, void *Src, uint32_t Len)
{
uint32_t i, p, cut_off = 0;
uint8_t *Data = (uint8_t *)Src;
if (!Buf->Len && !Buf->Offset && (Len <= Buf->Len))
{
memcpy(Buf->Data, Data, Len);
Buf->Len = Len;
return Len;
}
cut_off = Buf->MaxLength - Buf->Len;
if (cut_off >= Len)
{
cut_off = 0;
}
else
{
cut_off = Len - cut_off;
}
if (Buf->DataSize > 1)
{
for (i = 0, p = Buf->Offset + Buf->Len; i < Len; i++, p++)
{
if (p >= Buf->MaxLength)
{
p -= Buf->MaxLength;
}
memcpy(Buf->Data + (p * Buf->DataSize), Data + (i * Buf->DataSize), Buf->DataSize);
}
}
else
{
for (i = 0, p = Buf->Offset + Buf->Len; i < Len; i++, p++)
{
if (p >= Buf->MaxLength)
{
p -= Buf->MaxLength;
}
Buf->Data[p] = Data[i];
}
}
Buf->Offset += cut_off;
if (Buf->Offset >= Buf->MaxLength)
Buf->Offset -= Buf->MaxLength;
Buf->Len += Len;
if (Buf->Len > Buf->MaxLength)
Buf->Len = Buf->MaxLength;
return Len;
}
void Buffer_StaticInit(Buffer_Struct *Buf, void *Src, uint32_t MaxLen)
{
Buf->Data = Src;
Buf->Pos = 0;
Buf->MaxLen = MaxLen;
}
int32_t Buffer_StaticWrite(Buffer_Struct *Buf, void *Data, uint32_t Len)
{
if (!Len)
{
return -1;
}
if (!Buf)
{
return -1;
}
if ((Buf->Pos + Len) > Buf->MaxLen)
{
Len = Buf->MaxLen - Buf->Pos;
}
if (Len)
{
memcpy(&Buf->Data[Buf->Pos], Data, Len);
}
Buf->Pos += Len;
return Len;
}
//void Buffer_Remove(Buffer_Struct *Buf, uint32_t Len)
//{
// uint32_t RestLen;
// uint32_t i;
// if (!Buf)
// return ;
// if (!Buf->Data)
// return ;
// if (Len >= Buf->Pos)
// {
// Buf->Pos = 0;
// return ;
// }
// RestLen = Buf->Pos - Len;
// memmove(Buf->Data, Buf->Data + Len, RestLen);
// Buf->Pos = RestLen;
//}
/*****************************************************************************
* FUNCTION
* command_parse_param()
* DESCRIPTION
* Parse AT command string to parameters
* PARAMETERS
* char* pStr
* RETURNS
* pCmdParam
*****************************************************************************/
uint32_t CmdParseParam(int8_t* pStr, CmdParam *CP, int8_t Cut)
{
uint32_t paramStrLen = strlen((char *)pStr);
uint32_t paramIndex = 0;
uint32_t paramCharIndex = 0;
uint32_t index = 0;
while ((pStr[index] != '\r')
&& (index < paramStrLen)
&& (paramIndex < CP->param_max_num)) {
if (pStr[index] == Cut) {
/* Next param string */
paramCharIndex = 0;
paramIndex++;
}
else {
if (pStr[index] != '"')
{
if (paramCharIndex >= CP->param_max_len)
return (0);
/*Get each of command param char, the param char except char ' " '*/
CP->param_str[paramIndex * CP->param_max_len + paramCharIndex] = pStr[index];
paramCharIndex++;
}
}
index++;
}
CP->param_num = paramIndex + 1;
return (1);
}
__attribute__((weak)) uint8_t OS_CheckInIrq(void)
{
return __get_IPSR();
}
__attribute__((weak)) void OS_BufferRemove(Buffer_Struct *Buf, uint32_t Len)
{
uint32_t RestLen;
uint32_t i;
if (!Buf)
return ;
if (!Buf->Data)
return ;
if (Len >= Buf->Pos)
{
Buf->Pos = 0;
return ;
}
RestLen = Buf->Pos - Len;
memmove(Buf->Data, Buf->Data + Len, RestLen);
Buf->Pos = RestLen;
}
int32_t BSP_SetBit(uint8_t *Data, uint32_t Sn, uint8_t Value)
{
uint32_t Mask,Pos1,Pos2;
Pos1 = Sn/8;
Pos2 = Sn%8;
Mask = ~(1 << Pos2);
if (Value)
{
Value = (1 << Pos2);
}
Data[Pos1] = (Data[Pos1] & Mask) | Value;
//DBG("%d %d %d %d", Sn, Pos1, Pos2, Value);
return 0;
}
int32_t BSP_GetBit(uint8_t *Data, uint32_t Sn, uint8_t *Value)
{
uint32_t Mask,Pos1,Pos2;
Pos1 = Sn/8;
Pos2 = Sn%8;
Mask = (1 << Pos2);
if (Data[Pos1] & Mask)
{
*Value = 1;
}
else
{
*Value = 0;
}
return -1;
}
uint8_t BSP_TestBit(uint8_t *Data, uint32_t Sn)
{
uint32_t Mask,Pos1,Pos2;
Pos1 = Sn/8;
Pos2 = Sn%8;
Mask = (1 << Pos2);
if (Data[Pos1] & Mask)
{
return 1;
}
return 0;
}
uint8_t XorCheck(void *Src, uint32_t Len, uint8_t CheckStart)
{
uint8_t Check = CheckStart;
uint8_t *Data = (uint8_t *)Src;
uint32_t i;
for (i = 0; i < Len; i++)
{
Check ^= Data[i];
}
return Check;
}
uint8_t SumCheck(uint8_t *Data, uint32_t Len)
{
uint8_t Check = 0;
uint32_t i;
for (i = 0; i < Len; i++)
{
Check += Data[i];
}
return Check;
}
uint8_t CRC8Cal(void *Data, uint16_t Len, uint8_t CRC8Last, uint8_t CRCRoot, uint8_t IsReverse)
{
uint16_t i;
uint8_t CRC8 = CRC8Last;
uint8_t wTemp = CRCRoot;
uint8_t *Src = (uint8_t *)Data;
if (IsReverse)
{
CRCRoot = 0;
for (i = 0; i < 8; i++)
{
if (wTemp & (1 << (7 - i)))
{
CRCRoot |= 1 << i;
}
}
while (Len--)
{
CRC8 ^= *Src++;
for (i = 0; i < 8; i++)
{
if ((CRC8 & 0x01))
{
CRC8 >>= 1;
CRC8 ^= CRCRoot;
}
else
{
CRC8 >>= 1;
}
}
}
}
else
{
while (Len--)
{
CRC8 ^= *Src++;
for (i = 8; i > 0; --i)
{
if ((CRC8 & 0x80))
{
CRC8 <<= 1;
CRC8 ^= CRCRoot;
}
else
{
CRC8 <<= 1;
}
}
}
}
return CRC8;
}
/************************************************************************/
/* CRC16 */
/************************************************************************/
uint16_t CRC16Cal(void *Data, uint16_t Len, uint16_t CRC16Last, uint16_t CRCRoot, uint8_t IsReverse)
{
uint16_t i;
uint16_t CRC16 = CRC16Last;
uint16_t wTemp = CRCRoot;
uint8_t *Src = (uint8_t *)Data;
if (IsReverse)
{
CRCRoot = 0;
for (i = 0; i < 16; i++)
{
if (wTemp & (1 << (15 - i)))
{
CRCRoot |= 1 << i;
}
}
while (Len--)
{
for (i = 0; i < 8; i++)
{
if ((CRC16 & 0x0001) != 0)
{
CRC16 >>= 1;
CRC16 ^= CRCRoot;
}
else
{
CRC16 >>= 1;
}
if ((*Src&(1 << i)) != 0)
{
CRC16 ^= CRCRoot;
}
}
Src++;
}
}
else
{
while (Len--)
{
for (i = 8; i > 0; i--)
{
if ((CRC16 & 0x8000) != 0)
{
CRC16 <<= 1;
CRC16 ^= CRCRoot;
}
else
{
CRC16 <<= 1;
}
if ((*Src&(1 << (i - 1))) != 0)
{
CRC16 ^= CRCRoot;
}
}
Src++;
}
}
return CRC16;
}
uint32_t AsciiToU32(uint8_t *Src, uint32_t Len)
{
uint32_t i = 0;
uint32_t Temp = 0;
for (i = 0; i < Len; i++)
{
if (Src[i])
{
Temp *= 10;
Temp += Src[i] - '0';
}
else
{
break;
}
}
return Temp;
}
/**
* @brief
* @param ref
* @param ch
* @retval N反转后的数据
*/
static LongInt Reflect(LongInt ref, uint8_t ch)
{
LongInt value = 0;
LongInt i;
for (i = 1; i < (LongInt)(ch + 1); i++)
{
if (ref & 1)
value |= (LongInt)1 << (ch - i);
ref >>= 1;
}
return value;
}
/**
* @brief CRC32的查询表
* @param Tab
* @param Gen CRC32根
* @retval None
*/
void CRC32_CreateTable(uint32_t *Tab, uint32_t Gen)
{
uint32_t crc;
uint32_t i, j, temp, t1, t2, flag;
if (Tab[1] != 0)
return;
for (i = 0; i < 256; i++)
{
temp = Reflect(i, 8);
Tab[i] = temp << 24;
for (j = 0; j < 8; j++)
{
flag = Tab[i] & 0x80000000;
t1 = Tab[i] << 1;
if (0 == flag)
{
t2 = 0;
}
else
{
t2 = Gen;
}
Tab[i] = t1 ^ t2;
}
crc = Tab[i];
Tab[i] = Reflect(crc, 32);
}
}
/**
* @brief buffer的crc校验码
* @param CRC32_Table CRC32表
* @param Buf
* @param Size
* @param CRC32 CRC32值
* @retval CRC32
*/
uint32_t CRC32_Cal(uint32_t *CRC32_Table, uint8_t *Buf, uint32_t Size, uint32_t CRC32Last)
{
uint32_t i;
for (i = 0; i < Size; i++)
{
CRC32Last = CRC32_Table[(CRC32Last ^ Buf[i]) & 0xff] ^ (CRC32Last >> 8);
}
return CRC32Last;
}
/************************************************************************/
/*时间与时间戳转换C语言实现 */
/************************************************************************/
/************************************************************************/
uint8_t IsLeapYear(uint32_t Year)
{
if ((Year % 400) == 0)
return 1;
if ((((Year % 4) == 0) && (Year % 100) != 0))
return 1;
else
return 0;
}
const uint32_t DayTable[2][12] = { { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } };
//const uint32_t DayTable[2][12] = { { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } };
LongInt UTC2Tamp(Date_UserDataStruct *Date, Time_UserDataStruct *Time)
{
LongInt DYear, DDay, DSec;
uint32_t Year100;
DYear = Date->Year - 1970;
if (DYear) //1970年以后,1972是第一个闰年,1973年是第一年需要增加一天2100年是非闰年
{
DDay = DYear * 365 + ((DYear + 1) / 4) + DayTable[IsLeapYear(Date->Year)][Date->Mon - 1] + (Date->Day - 1);
// if (IsLeapYear(Date->Year))
// {
// DDay--;
// }
if (Date->Year >= 2100)
{
Year100 = Date->Year - 2100;
DDay -= (1 + Year100 / 100);
if (Date->Year >= 2400)
{
Year100 = Date->Year - 2400;
DDay += 1 + Year100 / 400;
}
}
}
else
{
DDay = DayTable[IsLeapYear(Date->Year)][Date->Mon - 1] + (Date->Day - 1);
}
DSec = DDay * 86400 + Time->Hour * 3600 + Time->Min * 60 + Time->Sec;
return DSec;
}
#define YEAR_1_DAY_BEFORE2000 365
#define YEAR_2_DAY_BEFORE2000 730
#define YEAR_3_DAY_BEFORE2000 1096
#define YEAR_1_DAY_AFTER2000 365
#define YEAR_2_DAY_AFTER2000 730
#define YEAR_3_DAY_AFTER2000 1095
#define YEAR_4_DAY 1461
#define YEAR_31_DAY 11323
#define YEAR_100_DAY 36524
#define YEAR_400_DAY 146097
uint32_t Tamp2UTC(LongInt Sec, Date_UserDataStruct *Date, Time_UserDataStruct *Time, uint32_t LastDDay)
{
uint32_t DYear,i, LeapFlag, Temp;
uint32_t DDay;
DDay = Sec / 86400;
if (DDay != LastDDay)
{
DYear = 0;
Time->Week = (4 + DDay) % 7;
if (DDay >= YEAR_31_DAY)
{
DDay -= YEAR_31_DAY;
DYear = 31;
if (DDay >= YEAR_400_DAY)
{
Temp = DDay / YEAR_400_DAY;
DYear += Temp * 400;
DDay -= Temp * YEAR_400_DAY;
}
if (DDay >= YEAR_100_DAY)
{
Temp = DDay / YEAR_100_DAY;
DYear += Temp * 100;
DDay -= Temp * YEAR_100_DAY;
}
if (DDay >= YEAR_4_DAY)
{
Temp = DDay / YEAR_4_DAY;
DYear += Temp * 4;
DDay -= Temp * YEAR_4_DAY;
}
if (DDay >= YEAR_3_DAY_AFTER2000)
{
DYear += 3;
DDay -= YEAR_3_DAY_AFTER2000;
}
else if (DDay >= YEAR_2_DAY_AFTER2000)
{
DYear += 2;
DDay -= YEAR_2_DAY_AFTER2000;
}
else if (DDay >= YEAR_1_DAY_AFTER2000)
{
DYear += 1;
DDay -= YEAR_1_DAY_AFTER2000;
}
}
else
{
if (DDay >= YEAR_4_DAY)
{
Temp = DDay / YEAR_4_DAY;
DYear += Temp * 4;
DDay -= Temp * YEAR_4_DAY;
}
if (DDay >= YEAR_3_DAY_BEFORE2000)
{
DYear += 3;
DDay -= YEAR_3_DAY_BEFORE2000;
}
else if (DDay >= YEAR_2_DAY_BEFORE2000)
{
DYear += 2;
DDay -= YEAR_2_DAY_BEFORE2000;
}
else if (DDay >= YEAR_1_DAY_BEFORE2000)
{
DYear += 1;
DDay -= YEAR_1_DAY_BEFORE2000;
}
}
Date->Year = DYear + 1970;
LeapFlag = IsLeapYear(Date->Year);
Date->Mon = 12;
for (i = 1; i < 12; i++)
{
if (DDay < DayTable[LeapFlag][i])
{
Date->Mon = i;
break;
}
}
Date->Day = DDay - DayTable[LeapFlag][Date->Mon - 1] + 1;
}
Sec = Sec % 86400;
Time->Hour = Sec / 3600;
Sec = Sec % 3600;
Time->Min = Sec / 60;
Time->Sec = Sec % 60;
return DDay;
}
/**
* \brief get a byte (8bits) from a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer
* \return the byte value
*/
uint8_t BytesGet8(const void *ptr)
{
const uint8_t *p = (const uint8_t *)ptr;
return p[0];
}
/**
* \brief put a byte (8bits) to a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer
* \param v the byte value
*/
void BytesPut8(void *ptr, uint8_t v)
{
uint8_t *p = (uint8_t *)ptr;
p[0] = v;
}
/**
* \brief get a big endian short (16bits) from a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \return the short value
*/
uint16_t BytesGetBe16(const void *ptr)
{
const uint8_t *p = (const uint8_t *)ptr;
return (p[0] << 8) | p[1];
}
/**
* \brief put a big endian short (16bits) to a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \param v the short value
*/
void BytesPutBe16(void *ptr, uint16_t v)
{
uint8_t *p = (uint8_t *)ptr;
p[0] = (v >> 8) & 0xff;
p[1] = v & 0xff;
}
/**
* \brief get a big endian word (32bits) from a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \return the word value
*/
uint32_t BytesGetBe32(const void *ptr)
{
const uint8_t *p = (const uint8_t *)ptr;
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
/**
* \brief put a big endian word (32bits) to a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \param v the word value
*/
void BytesPutBe32(void *ptr, uint32_t v)
{
uint8_t *p = (uint8_t *)ptr;
p[0] = (v >> 24) & 0xff;
p[1] = (v >> 16) & 0xff;
p[2] = (v >> 8) & 0xff;
p[3] = v & 0xff;
}
/**
* \brief get a little endian short (16bits) from a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \return the short value
*/
uint16_t BytesGetLe16(const void *ptr)
{
const uint8_t *p = (const uint8_t *)ptr;
return p[0] | (p[1] << 8);
}
/**
* \brief put a little endian short (16bits) to a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \param v the short value
*/
void BytesPutLe16(void *ptr, uint16_t v)
{
uint8_t *p = (uint8_t *)ptr;
p[0] = v & 0xff;
p[1] = (v >> 8) & 0xff;
}
/**
* \brief get a little endian word (32bits) from a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \return the word value
*/
uint32_t BytesGetLe32(const void *ptr)
{
const uint8_t *p = (const uint8_t *)ptr;
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
/**
* \brief put a little endian word (32bits) to a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \param v the word value
*/
void BytesPutLe32(void *ptr, uint32_t v)
{
uint8_t *p = (uint8_t *)ptr;
p[0] = v & 0xff;
p[1] = (v >> 8) & 0xff;
p[2] = (v >> 16) & 0xff;
p[3] = (v >> 24) & 0xff;
}
/**
* \brief get a little endian long long (64bits) from a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \return the long long value
*/
uint64_t BytesGetLe64(const void *ptr)
{
const uint8_t *p = (const uint8_t *)ptr;
return BytesGetLe32(p) | ((uint64_t)BytesGetLe32(p + 4) << 32);
}
/**
* \brief put a little endian long long (64bits) to a pointer
*
* Caller should ensure parameters are valid.
*
* \param ptr the pointer, may be unaligned
* \param v the long long value
*/
void BytesPutLe64(void *ptr, uint64_t v)
{
uint8_t *p = (uint8_t *)ptr;
BytesPutLe32(p, v & 0xffffffff);
BytesPutLe32(p + 4, (v >> 32) & 0xffffffff);
}
uint8_t BytesGet8FromBuf(Buffer_Struct *Buf)
{
Buf->Pos++;
return Buf->Data[Buf->Pos - 1];
}
void BytesPut8ToBuf(Buffer_Struct *Buf, uint8_t v)
{
Buf->Data[Buf->Pos] = v;
Buf->Pos++;
}
uint16_t BytesGetBe16FromBuf(Buffer_Struct *Buf)
{
Buf->Pos += 2;
return (Buf->Data[Buf->Pos - 2] << 8) | Buf->Data[Buf->Pos - 1];
}
void BytesPutBe16ToBuf(Buffer_Struct *Buf, uint16_t v)
{
Buf->Data[Buf->Pos] = (v >> 8) & 0xff;
Buf->Data[Buf->Pos + 1] = v & 0xff;
Buf->Pos += 2;
}
uint32_t BytesGetBe32FromBuf(Buffer_Struct *Buf)
{
Buf->Pos += 4;
return (Buf->Data[Buf->Pos - 4] << 24) | (Buf->Data[Buf->Pos - 3] << 16) | (Buf->Data[Buf->Pos - 2] << 8) | Buf->Data[Buf->Pos - 1];
}
void BytesPutBe32ToBuf(Buffer_Struct *Buf, uint32_t v)
{
Buf->Data[Buf->Pos] = (v >> 24) & 0xff;
Buf->Data[Buf->Pos + 1] = (v >> 16) & 0xff;
Buf->Data[Buf->Pos + 2] = (v >> 8) & 0xff;
Buf->Data[Buf->Pos + 3] = v & 0xff;
Buf->Pos += 4;
}
uint16_t BytesGetLe16FromBuf(Buffer_Struct *Buf)
{
Buf->Pos += 2;
return Buf->Data[Buf->Pos - 2] | (Buf->Data[Buf->Pos - 1] << 8);
}
void BytesPutLe16ToBuf(Buffer_Struct *Buf, uint16_t v)
{
Buf->Data[Buf->Pos] = v & 0xff;
Buf->Data[Buf->Pos + 1] = (v >> 8) & 0xff;
Buf->Pos+= 2;
}
uint32_t BytesGetLe32FromBuf(Buffer_Struct *Buf)
{
Buf->Pos += 4;
return Buf->Data[Buf->Pos - 4] | (Buf->Data[Buf->Pos - 3] << 8) | (Buf->Data[Buf->Pos - 2] << 16) | (Buf->Data[Buf->Pos - 1] << 24);
}
void BytesPutLe32ToBuf(Buffer_Struct *Buf, uint32_t v)
{
Buf->Data[Buf->Pos] = v & 0xff;
Buf->Data[Buf->Pos + 1] = (v >> 8) & 0xff;
Buf->Data[Buf->Pos + 2] = (v >> 16) & 0xff;
Buf->Data[Buf->Pos + 3] = (v >> 24) & 0xff;
Buf->Pos += 4;
}
uint64_t BytesGetLe64FromBuf(Buffer_Struct *Buf)
{
uint64_t Temp = BytesGetLe32FromBuf(Buf);
return Temp | ((uint64_t)BytesGetLe32FromBuf(Buf) << 32);
}
void BytesPutLe64ToBuf(Buffer_Struct *Buf, uint64_t v)
{
BytesPutLe32ToBuf(Buf, v & 0xffffffff);
BytesPutLe32ToBuf(Buf, (v >> 32) & 0xffffffff);
}
float BytesGetFloatFromBuf(Buffer_Struct *Buf)
{
float Temp;
Buf->Pos += 4;
memcpy(&Temp, &Buf->Data[Buf->Pos - 4], 4);
return Temp;
}
void BytesPutFloatToBuf(Buffer_Struct *Buf, float v)
{
memcpy(&Buf->Data[Buf->Pos], &v, 4);
Buf->Pos += 4;
}
double BytesGetDoubleFromBuf(Buffer_Struct *Buf)
{
double Temp;
Buf->Pos += 8;
memcpy(&Temp, &Buf->Data[Buf->Pos - 8], 8);
return Temp;
}
void BytesPutDoubleToBuf(Buffer_Struct *Buf, double v)
{
memcpy(&Buf->Data[Buf->Pos], &v, 8);
Buf->Pos += 8;
}
void BytesGetMemoryFromBuf(Buffer_Struct *Buf, uint8_t *Data, uint32_t Len)
{
memcpy(Data, &Buf->Data[Buf->Pos], Len);
Buf->Pos += Len;
}
/*
*
* FlagFlag
* Flag -> Code F1
* Code -> Code F2
*/
uint32_t TransferPack(uint8_t Flag, uint8_t Code, uint8_t F1, uint8_t F2, uint8_t *InBuf, uint32_t Len, uint8_t *OutBuf)
{
uint32_t TxLen = 0;
uint32_t i;
OutBuf[0] = Flag;
TxLen = 1;
for (i = 0; i < Len; i++)
{
if (InBuf[i] == Flag)
{
OutBuf[TxLen++] = Code;
OutBuf[TxLen++] = F1;
}
else if (InBuf[i] == Code)
{
OutBuf[TxLen++] = Code;
OutBuf[TxLen++] = F2;
}
else
{
OutBuf[TxLen++] = InBuf[i];
}
}
OutBuf[TxLen++] = Flag;
return TxLen;
}
/*
*
* FlagFlag
* Code F1 -> Flag
* Code F2 -> Code
* Flag 0
*/
uint32_t TransferUnpack(uint8_t Flag, uint8_t Code, uint8_t F1, uint8_t F2, uint8_t *InBuf, uint32_t Len, uint8_t *OutBuf)
{
uint32_t RxLen = 0;
uint32_t i = 0;
while (i < Len)
{
if (InBuf[i] == Code)
{
if (InBuf[i+1] == F1)
{
OutBuf[RxLen++] = Flag;
}
else if (InBuf[i+1] == F2)
{
OutBuf[RxLen++] = Code;
}
else
{
return 0;
}
i += 2;
}
else if (InBuf[i] == Flag)
{
return 0;
}
else
{
OutBuf[RxLen++] = InBuf[i++];
}
}
return RxLen;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
void __llist_add(llist_head *p,
llist_head *prev,
llist_head *next)
{
next->prev = p;
p->next = next;
p->prev = prev;
prev->next = p;
}
/**
* llist_add - add a new entry
* @new: new entry to be added
* @head: llist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
void llist_add(llist_head *p, llist_head *head)
{
__llist_add(p, head, head->next);
}
/**
* llist_add_tail - add a new entry
* @new: new entry to be added
* @head: llist head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
void llist_add_tail(llist_head *p, llist_head *head)
{
__llist_add(p, head->prev, head);
}
/*
* Delete a llist entry by making the prev/next entries
* point to each other.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
void __llist_del(llist_head * prev, llist_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* llist_del - deletes entry from llist.
* @entry: the element to delete from the llist.
* Note: llist_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
void llist_del(llist_head *entry)
{
if (entry->prev && entry->next)
{
__llist_del(entry->prev, entry->next);
}
entry->next = LLIST_POISON1;
entry->prev = LLIST_POISON2;
}
/**
* llist_del_init - deletes entry from llist and reinitialize it.
* @entry: the element to delete from the llist.
*/
void llist_del_init(llist_head *entry)
{
__llist_del(entry->prev, entry->next);
INIT_LLIST_HEAD(entry);
}
/**
* llist_move - delete from one llist and add as another's head
* @llist: the entry to move
* @head: the head that will precede our entry
*/
void llist_move(llist_head *llist, llist_head *head)
{
__llist_del(llist->prev, llist->next);
llist_add(llist, head);
}
/**
* llist_move_tail - delete from one llist and add as another's tail
* @llist: the entry to move
* @head: the head that will follow our entry
*/
void llist_move_tail(llist_head *llist,
llist_head *head)
{
__llist_del(llist->prev, llist->next);
llist_add_tail(llist, head);
}
void *llist_traversal(llist_head *head, CBFuncEx_t cb, void *pData)
{
llist_head *node = head->next;
llist_head *del;
int32_t result;
while (!llist_empty(head) && (node != head))
{
result = cb((void *)node, pData);
if (result > 0)
{
return node;
}
else
{
del = node;
node = node->next;
if (result < 0)
{
llist_del(del);
cb((void *)del, NULL);
}
}
}
return NULL;
}
/**
* llist_empty - tests whether a llist is empty
* @head: the llist to test.
*/
int llist_empty(const llist_head *head)
{
return head->next == head;
}
uint32_t llist_num(const llist_head *head)
{
llist_head *node = head->next;
uint32_t num = 0;
if (!node)
return num;
while(node != head)
{
num++;
node = node->next;
}
return num;
}