448 lines
10 KiB
C
448 lines
10 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
||
|
|
||
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
||
|
be copied by any method or incorporated into another program without
|
||
|
the express written consent of Aerospace C.Power. This Information or any portion
|
||
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
||
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
||
|
liability for its use in any way and conveys no license or title under
|
||
|
any patent or copyright and makes no representation or warranty that this
|
||
|
Information is free from patent or copyright infringement.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
|
||
|
/* os shim includes */
|
||
|
#include "os_types.h"
|
||
|
#include "os_mem.h"
|
||
|
#include "os_utils_api.h"
|
||
|
|
||
|
/* common includes */
|
||
|
#include "iot_utils.h"
|
||
|
#include "iot_errno.h"
|
||
|
#include "iot_utils_api.h"
|
||
|
|
||
|
/* define length of BCD length */
|
||
|
#define IOT_BCD_LEN_MAX 4
|
||
|
|
||
|
uint8_t iot_bcd_data_check(uint8_t *data, uint8_t len)
|
||
|
{
|
||
|
uint8_t i;
|
||
|
for (i = 0; i < len; i++) {
|
||
|
if ((data[i] & 0xF) > 9)
|
||
|
return 0;
|
||
|
if (((data[i] >> 4) & 0xF) > 9)
|
||
|
return 0;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_bcd_check(uint8_t v)
|
||
|
{
|
||
|
if ((v & 0xF) > 9)
|
||
|
return 0;
|
||
|
if (((v >> 4) & 0xF) > 9)
|
||
|
return 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_wait_timeout_fun(iot_timeout_func obj_func, \
|
||
|
int arg, int target_value, uint32_t wait_time_ms)
|
||
|
{
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
uint64_t time_span = 0;
|
||
|
int flag;
|
||
|
|
||
|
IOT_ASSERT(obj_func);
|
||
|
|
||
|
start_time = os_boot_time32();
|
||
|
do {
|
||
|
end_time = os_boot_time32();
|
||
|
time_span = end_time - start_time;
|
||
|
/* time out */
|
||
|
if (time_span > wait_time_ms) {
|
||
|
return ERR_TIMEOVER;
|
||
|
}
|
||
|
|
||
|
flag = obj_func(arg);
|
||
|
} while (flag != target_value);
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_uint32_to_bcd(uint32_t value, uint8_t bcd_len,
|
||
|
uint8_t *bcd)
|
||
|
{
|
||
|
uint8_t len = 0, i;
|
||
|
uint32_t v_max = 0;
|
||
|
uint32_t mul, div = 0;
|
||
|
for (i = 0, mul = 1; i < bcd_len; i++) {
|
||
|
v_max += 99 * mul;
|
||
|
div = mul;
|
||
|
mul *= 100;
|
||
|
}
|
||
|
if (value > v_max) {
|
||
|
return 0;
|
||
|
}
|
||
|
while (div) {
|
||
|
bcd[len++] = iot_byte_to_bcd((uint8_t)(value / div));
|
||
|
value %= div;
|
||
|
div /= 100;
|
||
|
}
|
||
|
IOT_ASSERT(bcd_len == len);
|
||
|
iot_data_reverse(bcd, len);
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_bcd_to_uint32(uint8_t *bcd, uint8_t bcd_len,
|
||
|
uint8_t flag_big, uint32_t *value)
|
||
|
{
|
||
|
uint8_t len = 0, i;
|
||
|
uint32_t v = 0;
|
||
|
|
||
|
if (bcd_len > IOT_BCD_LEN_MAX || !bcd_len || !bcd) {
|
||
|
goto out;
|
||
|
}
|
||
|
if (flag_big) {
|
||
|
for (i = 0; i < bcd_len; i++) {
|
||
|
if (!iot_bcd_check(bcd[i])) {
|
||
|
goto out;
|
||
|
}
|
||
|
v += iot_bcd_to_byte(bcd[i]);
|
||
|
if (i != (bcd_len - 1)) {
|
||
|
v *= 100;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
for (i = bcd_len; i != 0; i--) {
|
||
|
if (!iot_bcd_check(bcd[i - 1])) {
|
||
|
goto out;
|
||
|
}
|
||
|
v += iot_bcd_to_byte(bcd[i - 1]);
|
||
|
if ((i - 1) != 0) {
|
||
|
v *= 100;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
len = bcd_len;
|
||
|
*value = v;
|
||
|
out:
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_byte_reverse(uint8_t value)
|
||
|
{
|
||
|
static const uint8_t array[16] ={0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06,
|
||
|
0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F};
|
||
|
uint8_t ret = 0;
|
||
|
ret |= (array[value & 0xF]) << 4;
|
||
|
ret |= array[value >> 4];
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void iot_data_reverse(uint8_t *data, uint32_t len)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
uint8_t tmp;
|
||
|
|
||
|
for (; i < (uint32_t)(len / 2); i++) {
|
||
|
tmp = data[i];
|
||
|
data[i] = data[len - 1 - i];
|
||
|
data[len - 1 - i] = tmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t iot_wait_timeout_fun2(iot_timeout_func2 obj_func, \
|
||
|
void *arg, int target_value, uint32_t wait_time_ms)
|
||
|
{
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
uint64_t time_span = 0;
|
||
|
int flag;
|
||
|
|
||
|
IOT_ASSERT(obj_func);
|
||
|
|
||
|
start_time = os_boot_time32();
|
||
|
do {
|
||
|
end_time = os_boot_time32();
|
||
|
time_span = end_time - start_time;
|
||
|
/* time out */
|
||
|
if (time_span > wait_time_ms) {
|
||
|
return ERR_TIMEOVER;
|
||
|
}
|
||
|
|
||
|
flag = obj_func(arg);
|
||
|
} while (flag != target_value);
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
int iot_atoi(const char *s)
|
||
|
{
|
||
|
uint32_t ret = 0;
|
||
|
uint32_t d;
|
||
|
int neg = 0;
|
||
|
int tmp = 0;
|
||
|
|
||
|
if (*s == '-') {
|
||
|
neg = 1;
|
||
|
s++;
|
||
|
}
|
||
|
|
||
|
while (1) {
|
||
|
d = (*s++) - '0';
|
||
|
if (d > 9) {
|
||
|
break;
|
||
|
}
|
||
|
ret *= 10;
|
||
|
ret += d;
|
||
|
}
|
||
|
tmp = (int)ret;
|
||
|
return neg ? -tmp : tmp;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_atoi_to_uint8(const char *s, uint8_t *value)
|
||
|
{
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
if (iot_atoi_to_uint32(s, &tmp) || tmp > 0xff) {
|
||
|
*value = 0;
|
||
|
return ERR_FAIL;
|
||
|
} else {
|
||
|
*value = (uint8_t)tmp;
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t iot_atoi_to_uint16(const char *s, uint16_t *value)
|
||
|
{
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
if (iot_atoi_to_uint32(s, &tmp) || tmp > 0xffff) {
|
||
|
*value = 0;
|
||
|
return ERR_FAIL;
|
||
|
} else {
|
||
|
*value = (uint16_t)tmp;
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t iot_atoi_to_uint32(const char *s, uint32_t *value)
|
||
|
{
|
||
|
uint8_t flag_valid = 0;
|
||
|
uint32_t ret = 0;
|
||
|
uint32_t d;
|
||
|
|
||
|
while (1) {
|
||
|
if (*s < '0' || *s > '9') {
|
||
|
break;
|
||
|
}
|
||
|
d = *s - '0';
|
||
|
ret *= 10;
|
||
|
ret += d;
|
||
|
s++;
|
||
|
flag_valid = 1;
|
||
|
}
|
||
|
if (flag_valid) {
|
||
|
*value = ret;
|
||
|
return ERR_OK;
|
||
|
} else {
|
||
|
*value = 0;
|
||
|
return ERR_FAIL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t iot_calc_week(uint16_t year, uint8_t mon, uint8_t mday)
|
||
|
{
|
||
|
if (mon < 3) {
|
||
|
year -= 1;
|
||
|
mon += 12;
|
||
|
}
|
||
|
int32_t c = year / 100;
|
||
|
int32_t y = year % 100;
|
||
|
int32_t ans = (c / 4 - 2 * c + y + y / 4 + (26 * (mon + 1)) \
|
||
|
/ 10 + mday - 1) % 7;
|
||
|
|
||
|
if (ans < 0)
|
||
|
ans += 7;
|
||
|
return (uint8_t)ans;
|
||
|
}
|
||
|
|
||
|
void iot_bubble_sort_int32(int32_t *data, uint32_t cnt, uint8_t increase)
|
||
|
{
|
||
|
uint32_t i, j;
|
||
|
int32_t tmp;
|
||
|
uint8_t sw;
|
||
|
|
||
|
/* bubble sort */
|
||
|
for (i = 0; i < cnt - 1; i++) {
|
||
|
for (j = 0; j < cnt - 1 - i; j++) {
|
||
|
sw = 0;
|
||
|
if (increase) {
|
||
|
if (data[j] > data[j + 1]) {
|
||
|
sw = 1;
|
||
|
}
|
||
|
} else {
|
||
|
if (data[j] < data[j + 1]) {
|
||
|
sw = 1;
|
||
|
}
|
||
|
}
|
||
|
if (sw) {
|
||
|
tmp = data[j];
|
||
|
data[j] = data[j + 1];
|
||
|
data[j + 1] = tmp;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void iot_bubble_sort_int8(int8_t *data, uint32_t cnt, uint8_t increase)
|
||
|
{
|
||
|
uint32_t i, j;
|
||
|
int8_t tmp;
|
||
|
uint8_t sw;
|
||
|
|
||
|
/* bubble sort */
|
||
|
for (i = 0; i < cnt - 1; i++) {
|
||
|
for (j = 0; j < cnt - 1 - i; j++) {
|
||
|
sw = 0;
|
||
|
if (increase) {
|
||
|
if (data[j] > data[j + 1]) {
|
||
|
sw = 1;
|
||
|
}
|
||
|
} else {
|
||
|
if (data[j] < data[j + 1]) {
|
||
|
sw = 1;
|
||
|
}
|
||
|
}
|
||
|
if (sw) {
|
||
|
tmp = data[j];
|
||
|
data[j] = data[j + 1];
|
||
|
data[j + 1] = tmp;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int32_t iot_math_sqrt(int64_t x)
|
||
|
{
|
||
|
int64_t s1, s2;
|
||
|
|
||
|
/* check valid */
|
||
|
if (x < 0) {
|
||
|
return 0;
|
||
|
} else {
|
||
|
s1 = 16000;
|
||
|
}
|
||
|
|
||
|
do {
|
||
|
s2 = s1;
|
||
|
s1 = (s1 + x / s1) >> 1;
|
||
|
} while (IOT_ABS(s1 - s2) > 5);
|
||
|
|
||
|
return (int)s1;
|
||
|
}
|
||
|
|
||
|
void iot_mac_addr_reverse(uint8_t* addr)
|
||
|
{
|
||
|
uint8_t tmp;
|
||
|
|
||
|
tmp = addr[0];
|
||
|
addr[0] = addr[5];
|
||
|
addr[5] = tmp;
|
||
|
|
||
|
tmp = addr[1];
|
||
|
addr[1] = addr[4];
|
||
|
addr[4] = tmp;
|
||
|
|
||
|
tmp = addr[2];
|
||
|
addr[2] = addr[3];
|
||
|
addr[3] = tmp;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_mac_addr_valid(uint8_t* addr)
|
||
|
{
|
||
|
if (!addr) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return !!(addr[0] || addr[1] || addr[2] || addr[3] || addr[4] || addr[5]);
|
||
|
}
|
||
|
|
||
|
uint8_t iot_mac_addr_range_check(uint8_t *addr, uint8_t *start_addr,
|
||
|
uint8_t *end_addr)
|
||
|
{
|
||
|
|
||
|
uint64_t start_value = iot_mac_addr_uint8_array_to_long_int(start_addr);
|
||
|
uint64_t end_value = iot_mac_addr_uint8_array_to_long_int(end_addr);
|
||
|
uint64_t value = iot_mac_addr_uint8_array_to_long_int(addr);
|
||
|
|
||
|
return (uint8_t)((start_value <= value) && (end_value >= value));
|
||
|
}
|
||
|
|
||
|
uint32_t iot_bytes_to_uint32(uint8_t* data, uint8_t flag_big_endian)
|
||
|
{
|
||
|
uint32_t result = 0;
|
||
|
|
||
|
if (flag_big_endian) {
|
||
|
result = data[3] + (data[2] << 8) + (data[1] << 16) + (data[0] << 24);
|
||
|
} else {
|
||
|
result = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
void iot_uint32_to_bytes(uint32_t value, uint8_t *data, uint8_t flag_big_endian)
|
||
|
{
|
||
|
if (flag_big_endian) {
|
||
|
data[3] = value & 0xFF;
|
||
|
data[2] = (value >> 8) & 0xFF;
|
||
|
data[1] = (value >> 16) & 0xFF;
|
||
|
data[0] = (value >> 24) & 0xFF;
|
||
|
} else {
|
||
|
data[0] = value & 0xFF;
|
||
|
data[1] = (value >> 8) & 0xFF;
|
||
|
data[2] = (value >> 16) & 0xFF;
|
||
|
data[3] = (value >> 24) & 0xFF;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void iot_uint16_to_bytes(uint16_t value, uint8_t *data, uint8_t flag_big_endian)
|
||
|
{
|
||
|
if (flag_big_endian) {
|
||
|
data[1] = value & 0xFF;
|
||
|
data[0] = (value >> 8) & 0xFF;
|
||
|
} else {
|
||
|
data[0] = value & 0xFF;
|
||
|
data[1] = (value >> 8) & 0xFF;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
uint8_t iot_ascii_to_byte(const char value)
|
||
|
{
|
||
|
uint8_t ret = 0;
|
||
|
if(value >= '0' && value <= '9') {
|
||
|
ret = value - '0';
|
||
|
}else if(value >= 'A' && value <= 'F') {
|
||
|
ret = value - 'A' + 0x0A;
|
||
|
}else if(value >= 'a' && value <= 'f') {
|
||
|
ret = value - 'a' + 0x0A;
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
uint8_t iot_byte_to_ascii(const uint8_t value, uint8_t flag_uppercase)
|
||
|
{
|
||
|
uint8_t ret = 0;
|
||
|
if (value >= 0 && value <= 9) {
|
||
|
ret = value + '0';
|
||
|
} else if (value >= 0x0A && value <= 0x0F) {
|
||
|
if (flag_uppercase) {
|
||
|
ret = value - 0x0A + 'A';
|
||
|
} else {
|
||
|
ret = value - 0x0A + 'a';
|
||
|
}
|
||
|
}
|
||
|
return ret;
|
||
|
}
|