This commit is contained in:
huangruiqiao 2025-04-11 09:36:54 +08:00
parent 279263248c
commit 9e54941ff9
193 changed files with 85253 additions and 19215 deletions

View File

@ -142,7 +142,7 @@ for /f "tokens=1,* delims=-" %%a in ("%parameterStr%") do (
if "%%a"=="driver_example" (
set PROJECT_NAME=driver_example
set BUILD_OPTION=no_merge
set BUILD_OPTION=merge
)
if "%%a"=="dhrystone" (
@ -322,7 +322,7 @@ echo "==========================================================================
echo " "
echo " >> HOW TO BUILD A PROJECT << "
echo " "
echo "==============================================================================================¡±
echo "==============================================================================================<EFBFBD><EFBFBD>
echo " "
echo " @FORMAT : Gccbuild.bat [<board>[-<core>[-<project>[-<option>]]]] "
echo " @CAUTION: All parameters (<board>/<core>/<project>/<option>) are optional, "
@ -341,11 +341,11 @@ echo " list list all supported boards and supported projects for eve
echo " help display this help message. "
echo " "
echo " >> Advanced "
echo " NULL(default) full feature support£¨no ims£©, AP lib: full, CP image£ºoc "
echo " open_cpu for open dev, more ram, AP lib: oc, CP image£ºoc "
echo " isms open_cpu + ims sms, AP lib: isms, CP image£ºoc "
echo " ims volte feature support, AP lib: ims, CP image£ºaudio "
echo " audio audio support(e.g. local MP3 play), AP lib: oc, CP image£ºaudio "
echo " NULL(default) full feature support<EFBFBD><EFBFBD>no ims<6D><73>, AP lib: full, CP image<67><65>oc "
echo " open_cpu for open dev, more ram, AP lib: oc, CP image<EFBFBD><EFBFBD>oc "
echo " isms open_cpu + ims sms, AP lib: isms, CP image<EFBFBD><EFBFBD>oc "
echo " ims volte feature support, AP lib: ims, CP image<EFBFBD><EFBFBD>audio "
echo " audio audio support(e.g. local MP3 play), AP lib: oc, CP image<EFBFBD><EFBFBD>audio "
echo "**********************************************************************************************"
echo " Examples: "
echo "----------------------- For Internal Full Source Build----------------------------------------"

View File

@ -82,7 +82,7 @@ void i2sSlp1Cb();
#endif
extern void OsaFreeDlPduBlockList(DlPduBlock **pDlPduBlk);
extern HalCodecSts_e halCodecEnablePA(HalCodecFuncList_t* codecHal, bool enable, bool needLock);
/*----------------------------------------------------------------------------*
* GLOBAL VARIABLES *

View File

@ -870,7 +870,7 @@ int audioAppStartPlaySound(uint8_t type, uint8_t *pSpeechBuf, uint16_t speechBuf
if (retValue != CCIO_EOK)
{
ECPLAT_PRINTF_OPT(UNILOG_CCIO, VOLTEH_StartPlaySound_1, P_ERROR, "VOLTE_P: start play lock fail");
return;
return retValue;
}
startPlayIntern(type, pSpeechBuf, speechBufSize, sampleRate, pcmBitWidth);

View File

@ -1,8 +1,8 @@
#if !defined _DB_VERSION_H
#define _DB_VERSION_H
//The file was automatically generated by the PrePass Application Ver 2.2.81.216, Wed Jan 8 17:08:16 2025
//The file was automatically generated by the PrePass Application Ver 2.2.81.216, Fri Apr 11 09:33:10 2025
#define DB_VERSION_UNIQ_ID "0x4b40134e"
#define DB_VERSION_UNIQ_ID "0x05c12d37"
#endif //_DB_VERSION_H

View File

@ -10,12 +10,12 @@ BIN_COMPRESS = y
DRIVER_CPFLASH_ENABLE = n
DRIVER_VPU_ENABLE = y
DRIVER_EEPROM_ENABLE = n
DRIVER_SPI_ENABLE = n
DRIVER_I2C_ENABLE = n
DRIVER_SPI_ENABLE = y
DRIVER_I2C_ENABLE = y
DRIVER_PSRAM_ENABLE = n
DRIVER_PCACHE_ENABLE = y
DRIVER_EXSTORAGE_ENABLE = n
#DRIVER_LPUART_ENABLE = n
DRIVER_LPUART_ENABLE = y
DRIVER_ONEWIRE_ENABLE = n
DRIVER_APM_ENABLE = y

View File

@ -160,13 +160,51 @@ BUILD_PLAT_FOTA_AT_ENABLE = n
BUILD_PLAT_ECOTA_AT_ENABLE = n
endif
APP_DIR := $(TOP)/PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)
APP_LIBS := $(APP_DIR)/src/ppg/libgh3x2x_drv_common.a
#lib-y += $(APP_LIBS)
PREBUILDLIBS += $(APP_LIBS)
APP_SRC_DIRS += $(APP_DIR)/src/ppg \
$(APP_DIR)/src/gps/nmea_parse \
$(APP_DIR)/src/gps/adaptation \
$(APP_DIR)/src/gps/offline_eph \
$(APP_DIR)/src/gps/offline_eph/ext/aes \
$(APP_DIR)/gps
APP_EXCLUDE_FILES :=
APP_CSRC = $(foreach dir, $(APP_SRC_DIRS), $(wildcard $(dir)/*.c))
APP_CFILES = $(filter-out $(APP_EXCLUDE_FILES), $(APP_CSRC))
APP_COBJSTEMP := $(patsubst %.c, %.o, $(APP_CFILES))
CFLAGS_INC += -I ../inc \
-I $(TOP)/FIRMWARE/SRC/CAT1/Common/Inc \
-I $(TOP)/PLAT/driver/chip/$(CHIP)/ap/src/usb
-I $(TOP)/PLAT/driver/chip/$(CHIP)/ap/src/usb \
-I $(APP_DIR)/src/gps \
-I $(APP_DIR)/src/gps/adaptation \
-I $(APP_DIR)/src/gps/nmea_parse \
-I $(APP_DIR)/src/gps/offline_eph \
-I $(APP_DIR)/src/ppg
obj-y += PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/app.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/rawData.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/bsp_custom.o
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/bsp_custom.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_socket.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_temp.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_ppg.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_comm.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_command.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_location.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_gsensor.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/gps_uart_read.o \
PLAT/project/$(TARGET)/$(CORE)/apps/$(PROJECT)/src/sk_main.o
obj-y += $(APP_COBJSTEMP)
#CONFIG_PROJ_APP_SECURITY_BOOT = y

View File

@ -38,7 +38,7 @@
#if (defined MID_FEATURE_MODE) || (defined FEATURE_AUDIO_ENABLE)
#define RTE_I2C0 1
#else
#define RTE_I2C0 0
#define RTE_I2C0 1
#endif
// { PAD_PIN30}, // 0 : gpio15 / 2: I2C0_SCL
@ -183,7 +183,7 @@
// SPI0 (Serial Peripheral Interface) [Driver_SPI0]
// Configuration settings for Driver_SPI0 in component ::Drivers:SPI
#define RTE_SPI0 0
#define RTE_SPI0 1
// { PAD_PIN23}, // 0 : gpio8 / 1 : SPI0 SSn
// { PAD_PIN24}, // 0 : gpio9 / 1 : SPI0 MOSI
@ -295,7 +295,7 @@ static configuration for USB/UART relatded feature
#else
/* device */
#define RTE_SPI_EN 0
#define RTE_SPI_EN 1
#define RTE_USB_EN 1
#define RTE_ONE_UART_AT 1
#define RTE_TWO_UART_AT 0

View File

@ -0,0 +1,19 @@
#ifndef __GPS_UART_READ_H__
#define __GPS_UART_READ_H__
void gps_uart_set_baudrate(unsigned int rate);
char gps_uart_read_char(unsigned int ms);
char *gps_uart_read_string();
int gps_uart_send_byte(char byte);
int gps_uart_send_buf(char *pBuf,int len);
void gps_report_satellites_num(u16 type,u16 num);
void SK_SendMsg_ToGpsUart(Enum_SK_Msg msg_id,void *param,int len);
#endif

View File

@ -0,0 +1,47 @@
#ifndef __HEALTH_DATA_H__
#define __HEALTH_DATA_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "FreeRTOS.h"
#include "ostask.h"
#include "commontypedef.h"
#include "sk_comm.h"
typedef struct
{
u8 rate;
int timestamp;
}HEALTH_HeartRate_S;
typedef struct
{
u8 oxygen;
int timestamp;
}HEALTH_BloodOxygen_S;
typedef struct
{
u8 temp;
int timestamp;
}HEALTH_Temp_S;
typedef struct
{
}HEALTH_Ecg_S;
typedef struct
{
}HEALTH_MedicalReport_S;
#ifdef __cplusplus
}
#endif
#endif /* MODE_CONFIG_H */

View File

@ -0,0 +1,168 @@
#ifndef __SK_COMM_H__
#define __SK_COMM_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "FreeRTOS.h"
#include "ostask.h"
#include "commontypedef.h"
#include "stdint.h"
#define SW_VERSION "V1.0.0"
#undef u16
#undef u8
#undef u32
#define u16 uint16_t
#define u8 uint8_t
#define u32 uint32_t
#define IMEI_StrLen_Max 20
#define IMSI_StrLen_Max 20
#define ICCID_StrLen_Max 24
#define SN_StrLen_Max 10
typedef enum
{
E_SK_WorkMode_Init,
E_SK_WorkMode_Inside,
E_SK_WorkMode_Outside,
E_SK_WorkMode_Max
}Enum_SK_WorkMode_Type;
typedef enum
{
E_SK_Msg_Main_init,
E_SK_Msg_Main_ready,
E_SK_Msg_Main_Led,
E_SK_Msg_Main_PSEvent,
E_SK_Msg_Main_DataRead,
E_SK_Msg_Main_NetReport,
E_SK_Msg_Main_config_save,
E_SK_Msg_FS_Ready,
E_SK_Msg_Realtime_Timeout,
E_SK_Msg_Gsensor_Read_Xmotion,
E_SK_Msg_Gsensor_Read_stepcount,
E_SK_Msg_Key,
E_SK_Msg_Fota_CheckVer,
E_SK_Msg_Fota_Tcp_Connected,
E_SK_Msg_Fota_Tcp_RecvData,
E_SK_Msg_Fota_Upgrade,
E_SK_Msg_Socket_ipnet_ready,
E_SK_Msg_Socket_ipnet_unready,
//socket task msg
E_SK_Msg_Socket_Pdp_Ready,
E_SK_Msg_Socket_send_data,
E_SK_Msg_Socket_recv_data,
E_SK_Msg_Socket_Disconnected,
E_SK_Msg_Socket_Connected,
E_SK_Msg_Socket_Login,
E_SK_Msg_Socket_Sos,
E_SK_Msg_Socket_Warning,
E_SK_Msg_Socket_HeartBeat,
E_SK_Msg_Socket_DataReport,
E_SK_Msg_Socket_LocationReport,
E_SK_Msg_Socket_HealthReport,
E_SK_Msg_PPG_ADT,
//
E_SK_Msg_Command_recv,
E_SK_Msg_setLocationMode,
E_SK_Msg_Location_setInfo,
E_SK_Msg_Location_req,
E_SK_Msg_Location_report,
E_SK_Msg_Location_Timeout,
E_SK_Msg_Location_WifiScan_req,
E_SK_Msg_Location_CellInfo,
E_SK_Msg_Location_Gps_start,
E_SK_Msg_Location_Gps_update,
E_SK_Msg_Location_Gps_LocInfo,
E_SK_Msg_Location_Fs_ready,
E_SK_Msg_Location_offline_update,
E_SK_Msg_Location_Gps_test,
E_SK_Msg_Gps_firmware_dl,
E_SK_Msg_Gps_OfflineEph_dl,
E_SK_Msg_Gps_Eph_Inject,
E_SK_Msg_Gps_Uart_recv,
E_SK_Msg_Gps_Nmea_recv,
E_SK_Msg_Cmd_Login_Success,
E_SK_Msg_Cmd_Login_Failed,
E_SK_Msg_Cmd_Setting,
E_SK_Msg_Cmd_LocateReq,
E_SK_Msg_Cmd_SosConfirm,
E_SK_Msg_Cmd_Mode,
E_SK_Msg_Cmd_Monitor,
E_SK_Msg_Reset_factory, //恢复出厂设置
E_SK_Msg_Reboot, //重启终端
E_SK_Msg_Max
}Enum_SK_Msg;
typedef struct
{
Enum_SK_Msg msg_id;
void * param;
uint32_t len;
}SK_Msg_S;
typedef struct
{
int year;
int mon;
int day;
int hour;
int min;
int sec;
int msec;
int usec;
int wday;
}SK_Time_T;
int getCurTime(SK_Time_T *pSysTime);
void yak_strlog(char *logstr);
#define YAK_LOGBUF_maxLen 1024
extern char yak_logbuf[];
#define yak_log(fmt, ...) do{\
snprintf(yak_logbuf,YAK_LOGBUF_maxLen,fmt,##__VA_ARGS__);\
yak_strlog(yak_logbuf);\
}while(0)
char *getImei(void);
char *getImsi(void);
char *getIccid(void);
char* getSn(void);
int getBatVolume(void);
#ifdef __cplusplus
}
#endif
#endif /* MODE_CONFIG_H */

View File

@ -0,0 +1,624 @@
#ifndef __COMMAND_H__
#define __COMMAND_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "sk_comm.h"
#include "cjson.h"
#ifdef _WINDOWS
//#include "win_com.h"
#else
//#include "icoe_gnss_types.h"
#endif
/*
v76 sk终端和服务器通讯接口
//终端和服务器保持tcp长连接未来可以加密连接
//5分钟心跳断网续传缓存上限按1天算json格式
tcp
"##”开头,以“**”结尾,紧接着"##"的4个字节表示的是长度高位在前表示的是包内容数据的总长度从第六个字节开始到"**"之间是数据内容,
(1):01json格式
(json格式) +
=
{
id,
imei
:Base64/str/,
,
}
{
"数据项名字1"[1]
"数据项名字2"[2]
"数据项名字3"[3]
}
IDreqc_开头4 int
IDreqs_开头4 int
ID以resp_开头
1
cmd_id reqc_Login
sequence
imei imei
timestamp
data_type Base64/str/,Json
data_len ,Json格式下=0
data
{"data":{
{"mode":0},
{"sn":""},
{"iccid":""},
{"sw_version":""},
{"hw_version":""},
{"batVolume":80},
{"charging":0},
}
}
cmd_id resp_Login
sequence
imei imei
timestamp
data_type Base64/str/,
data_len
data {"data":"ok"}/{"data":"fail"}
2
cmd_id reqc_HeartBeat
head部分...
data部分
{"data":{
{"mode":0},
{"sn":""},
{"iccid":""},
{"sw_version":"V1.0.0"},
{"hw_version":""},
{"batVolume":80},
{"charging":0},
}
}
cmd_id resp_HeartBeat
head部分...
data {"data":"ok"}/{"data":"fail"}
3
cmd_id reqc_HealthReport
head部分...
data部分
{"data":{
"HeartRate"{
"values": [100,89],
"times":[1648111394,1648111394]
},
"SkinTemp"{
"values": [100,89],
"times":[1648111394,1648111394]
},
"EnvirTemp"{
"values": [100,89],
"times":[1648111394,1648111394]
},
"BloodOxygen"{
"values": [100,89],
"times":[1648111394,1648111394]
},
"ACC" {
"values": [100,89],
"times":[1648111394,1648111394]
},
"ECG" {
//保留
},
"Report" {
//医学报告等保留
},
"Sports" {
//保留
//"times":[1648111394,1648111394]
},
"Sleep" {
//保留
//"times":[1648111394,1648111394]
}
}
}
cmd_id resp_HealthReport
head部分...
data {"data":"ok"}/{"data":"fail"}
4
cmd_id reqc_PosReport
head部分...
data部分如下
{
"data":{"sos":0, //sos状态0正常1sos
"location":
[
{ "lbs" [{
"mcc": 460,
"mnc": 0,
"lac": 9475,
"cid": 61009,
"rssi": 51,
},
{
"mcc": 460,
"mnc": 0,
"lac": 9475,
"cid": 61009,
"rssi": 51,
},
{
"mcc": 460,
"mnc": 0,
"lac": 9475,
"cid": 61009,
"rssi": 51,
}
]
"gps" {//gps定位数据
"lon": "113.4201386", //[str] //经度 DDD.DDDDDD格式
"lat": "23.1782397", //[str] //纬度 DD.DDDDDD格式
"altitude": 100, //[int] //海拔 单位为米
"satelliteNum": 5, //[int] //表明 GPS 卫星个数
"hdop": 10, //定位精度 单位为米
"speed": 0.3, //速度 km/h
},
"wifis"[
{
"rssi": "-75", //[int] //wifi信号强度
"mac": "f8:8c:21:ef:fd:83" //[str] //wifi的MAC地址
},
{
"rssi": "-52",
"mac": "c8:3a:35:ba:f1:23"
}
],
"time":1288883332
},
{ //同上
},
{ //同上
}
]
}
}
cmd_id resp_PosReport
head部分...
data {"data":"ok"}/{"data":"fail"}
5 /
cmd_id reqc_Warning
head部分...
data部分如下
{
"data":{
"HeartRate"1, // 0,预警无效1有效
"HeartRate_Value":100,
"Temp"1, // 0,预警无效1有效
"Temp_Value":100,
"BloodOxygen"1, // 0,预警无效1有效
"BloodOxygen_Value":100,
"ACC"1 // 0,预警无效1有效
}
}
cmd_id resp_Warning
head部分...
data {"data":"ok"}/{"data":"fail"}
6,
cmd_id reqs_StopWarning
head部分...
data
cmd_id resp_StopWarning
head部分...
data {"data":"ok"}/{"data":"fail"}
7 SOS请求
cmd_id reqc_Sos
head部分...
data SOS内容(
{
"data":{
"lbs" [{
"mcc": 460,
"mnc": 0,
"lac": 9475,
"cid": 61009,
"rssi": 51,
},
{
"mcc": 460,
"mnc": 0,
"lac": 9475,
"cid": 61009,
"rssi": 51,
},
{
"mcc": 460,
"mnc": 0,
"lac": 9475,
"cid": 61009,
"rssi": 51,
}
],
"wifis"[
{
"rssi": "-75", //[int] //wifi信号强度
"mac": "f8:8c:21:ef:fd:83" //[str] //wifi的MAC地址
},
{
"rssi": "-52",
"mac": "c8:3a:35:ba:f1:23"
}
],
"time":1288883332
}
}
SOS请求回复
cmd_id resp_Sos
head部分...
data {"data":"ok"}/{"data":"fail"}
8, SOS确认指令
cmd_id reqs_SosConfirm
head部分...
data
SOS确认指令回复
cmd_id reqs_SosConfirm
head部分...
data {"data":"ok"}/{"data":"fail"}
9 ip/port,//userid//
cmd_id reqs_Setting
head部分...
data部分如下
{
"data":{
"data_interval"1,
"report_intervl"1,
"heartbeat_interval"1,
"server_ip": "XXX.XXX.XXX",
"server_port": XXXX,
"heartrate_range": [],
"temp_range": [],
"oxygen_min":xxx,
"acc_max":xxxx
}
}
cmd_id resp_Setting
head部分...
data {"data":"ok"}/{"data":"fail"}
10
cmd_id reqs_Mode
head部分...
data部分如下
{
"data":0 //0室内定位模式1外出定位模式
}
cmd_id resp_Mode
head部分...
data {"data":"ok"}/{"data":"fail"}
11
cmd_id reqs_Monitor
head部分...
data部分如下
{
"data":0 //0普通1审讯>1,其他,保留
}
cmd_id resp_Monitor
head部分...
data {"data":"ok"}/{"data":"fail"}
12///
cmd_id reqs_Control
head部分...
data ()
data部分如下
{
"data":{
"operation":"poweroff" //"reset" //"factory"
}
}
cmd_id resp_Control
head部分...
data {"data":"ok"}/{"data":"fail"}
13
cmd_id reqs_Locate
head部分...
data :gps+lbs+wifi,lbs+wifi
cmd_id resp_Locate
head部分...
data {"data":"ok"}/{"data":"fail"}
*/
#define TCP_DATA_PACK_Head "##"
#define TCP_DATA_PACK_Tail "**"
#define TCP_DATA_RECV_PACK_maxLen 2048
//#define DataPacket_MaxBufLen 1200
#define CMD_TYPE_Server_Req "reqs"
#define CMD_TYPE_Client_Req "reqc"
#define CMD_TYPE_Resp "resp"
#define CMD_TYPEStr_Len 4
#define CmdName_maxLen 50
#define CmdName_Login "Login"
#define CmdName_Location "Location"
#define CmdName_PosReport "PosReport"
#define CmdName_HealthReport "HealthReport"
#define CmdName_Sos "Sos"
#define CmdName_SosConfirm "SosConfirm"
#define CmdName_Warning "Warning"
#define CmdName_WarningStop "WarningStop"
#define CmdName_Mode "Mode"
#define CmdName_Monitor "Monitor"
#define CmdName_HeartBeat "HeartBeat"
#define CmdName_Setting "Setting"
#define CmdName_Contral "Contral"
#define JSON_HeadKey_CmdId "cmd_id"
#define JSON_HeadKey_Sequence "sequence"
#define JSON_HeadKey_Imei "imei"
#define JSON_HeadKey_TimeStamp "timestamp"
#define JSON_HeadKey_DataType "data_type"
#define JSON_HeadKey_DataLen "data_len"
#define JSON_HeadKey_ContentData "data"
#define JSON_ContentKey_Location "location"
#define JSON_ContentKey_HeartRate "HeartRate"
#define JSON_ContentKey_HeartRateValue "HeartRate_Value"
#define JSON_ContentKey_SkinTemp "SkinTemp"
#define JSON_ContentKey_EnvirTemp "EnvirTemp"
#define JSON_ContentKey_ACC "ACC"
#define JSON_ContentKey_BloodOxygen "BloodOxygen"
#define JSON_ContentKey_BloodOxygenVal "BloodOxygen_Value"
#define JSON_ContentKey_Temp "Temp"
#define JSON_ContentKey_TempValue "Temp_Value"
#define JSON_ContentKey_Ecg "ecg"
#define JSON_ContentKey_MedicalReport "medicalreport"
#define JSON_ContentKey_Warning "warning"
#define JSON_ContentKey_mode "mode"
#define JSON_ContentKey_sn "sn"
#define JSON_ContentKey_sw_version "sw_version"
#define JSON_ContentKey_hw_version "hw_version"
#define JSON_ContentKey_batvolume "batVolume"
#define JSON_ContentKey_charging "charging"
#define JSON_ContentKey_sos "sos"
#define JSON_ContentKey_lbs "lbs"
#define JSON_ContentKey_gps "gps"
#define JSON_ContentKey_wifi "wifi"
#define JSON_ContentKey_time "time"
// reqs_Setting
#define JSON_ContentKey_insideInterval "inside_interval"
#define JSON_ContentKey_outsideInterval "outside_interval"
#define JSON_ContentKey_monitorinterval "monitor_interval"
#define JSON_ContentKey_locateinterval "locate_interval"
#define JSON_ContentKey_healthinterval "health_interval"
#define JSON_ContentKey_reportInterval "report_interval"
#define JSON_ContentKey_heartbeatInterval "heartbeat_interval"
#define JSON_ContentKey_serverip "server_ip"
#define JSON_ContentKey_serverport "server_port"
#define JSON_ContentKey_heartrange "heartrate_range"
#define JSON_ContentKey_temprange "temp_range"
#define JSON_ContentKey_oxygenmin "oxygen_min"
#define JSON_ContentKey_accmax "acc_max"
// reqs_control
#define JSON_ContentKey_poweroff "poweroff"
#define JSON_ContentKey_reset "reset"
#define JSON_ContentKey_factory "factory"
// response
#define JSON_ContentKey_ok "ok"
#define JSON_ContentKey_fail "fail"
/*
{
"mcc": 460,
"mnc" : 0,
"lac" : 9475,
"cid" : 61009,
"rssi" : 51,
}
*/
#define JSON_LbsKey_mcc "mcc"
#define JSON_LbsKey_mnc "mnc"
#define JSON_LbsKey_lac "lac"
#define JSON_LbsKey_cid "cid"
#define JSON_LbsKey_rssi "rssi"
#define JSON_WifiKey_mac "mac"
#define JSON_WifiKey_rssi "rssi"
/*
"gps"{//gps定位数据
"lon": "113.4201386", //[str] //经度 DDD.DDDDDD格式
"lat" : "23.1782397", //[str] //纬度 DD.DDDDDD格式
"altitude" : 100, //[int] //海拔 单位为米
"satelliteNum" : 5, //[int] //表明 GPS 卫星个数
"hdop" : 10, //定位精度 单位为米
"speed" : 0.3, //速度 km/h
},
*/
#define JSON_GpsKey_longitude "lon"
#define JSON_GpsKey_latitude "lat"
#define JSON_GpsKey_altitude "altitude"
#define JSON_GpsKey_speed "speed"
#define JSON_GpsKey_hdop "hdop"
#define JSON_GpsKey_gsv_count "satelliteNum"
#define JSON_ContentKey_values "values"
#define JSON_ContentKey_times "times"
#define SEQ_NUM_LEN 4
#define SEQ_NUM_Max 10000//0-9999
#define TimeStamp_Str_Len 10
#define CMD_NameStr_maxLen 30
typedef void (*cmd_content_disp_func)(char* pStr, int len);
typedef enum
{
E_CMD_ID_Login, //"Login"
E_CMD_ID_Location, //"Location"
E_CMD_ID_PosReport, //"PosReport":report location
E_CMD_ID_HealthReport, //"HealthReport":report health data
E_CMD_ID_Sos, //"Sos":SOS
E_CMD_ID_SosConfirm, //"SosConfirm":sos confirm
E_CMD_ID_Warning, //"Waring"
E_CMD_ID_WarningStop, //"WaringStop"
E_CMD_ID_Mode, //"ModeSwitch"
E_CMD_ID_Monitor, //"Monitor"
E_CMD_ID_HeartBeat, //"HeartBeat"
E_CMD_ID_Setting, //"Setting"
E_CMD_ID_Contral, //"Contral":remote contral
E_CMD_ID_Max
}Enum_COMMAND_ID;
typedef enum
{
E_CMD_TYPE_SERVER_REQUEST,
E_CMD_TYPE_CLIENT_REQUEST,
E_CMD_TYPE_RESPONSE,
E_CMD_TYPE_MAX
} Enum_Command_Type_E;
typedef struct
{
Enum_COMMAND_ID id;
char name[CMD_NameStr_maxLen + 1];
}SK_CmdIdStr_S;
typedef struct
{
int data_interval;
int heartrate_max;
int heartrate_min;
int temp_max;
int temp_min;
int oxygen_min;
int report_interval;
int heartbeat_interval;
} SK_Command_Setting_S;
typedef struct
{
Enum_COMMAND_ID cmd_id; //命令ID
Enum_Command_Type_E cmd_type;
char cmd_name[CMD_NameStr_maxLen + 1]; //ignore
//char* pCmdStrBuf;
char* pImei;
int sequence;
int timestamp;
int mode;
int monitor;
int reqc_result;
SK_Command_Setting_S *pSetting;
char* pack_buf;
int pack_len;
void * pJsonRoot;
void * pJsonContent;
#ifdef _WINDOWS
cmd_content_disp_func win_finc;
#endif
}SK_Command_S;
typedef enum
{
E_SK_Warning_Lowpower = 1, //低电量,低于电量的阈值(平台自定义),触发报警
E_SK_Warning_Shutdown, //关机报警
E_SK_Warning_Lowpower_Shutdown, //低电量自动关机报警
E_SK_Warning_PowerOn, //开机报警
E_SK_Warning_Charging, //充电报警
E_SK_Warning_unCharging, //未充电报警
E_SK_Warning_Fullpower, //电池满电报警
}Enum_SK_Warning_Type;
int RecvData_SplitePack(char *recv_data, u32 recv_len);
void Command_parse(char *pData,int len);
void Command_Login_gen(SK_Command_S* pCmd);
void Command_HealthReport_gen(SK_Command_S * pCmd);
void Command_PosReport_gen(SK_Command_S *pCmd);
void Command_Sos_gen(SK_Command_S *pCmd);
void Command_HeartBeat_gen(SK_Command_S *pCmd);
void Command_Warning_gen(SK_Command_S *pCmd);
//int Command_getFamily_gen(SK_Command_S* pCmd);
//int Command_getIncomeCall_gen(SK_Command_S* pCmd);
//void setCmd_Log_Func(cmd_content_disp_func pRecvCb, cmd_content_disp_func pSendCb);
//int Data_Pack(SK_Command_S* pCmd);
int Data_unPack(void *pData,u32 data_len);
int Command_Send(SK_Command_S *pCmd);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif

View File

@ -0,0 +1,20 @@
/******************************************************************************/
/* */
/* Copyright 2024 by YAK TECHNOLOGIES CO.,LTD. All rights reserved. */
/* */
/******************************************************************************/
/**
* DESCRIPTION
*
* This file is entry of sms test
*/
#ifndef __SK_FOTA_H__
#define __SK_FOTA_H__
#define Fota_Version_Check_Http_Url ""
#endif

View File

@ -0,0 +1,46 @@
/******************************************************************************/
/* */
/* Copyright 2024 by YAK TECHNOLOGIES CO.,LTD. All rights reserved. */
/* */
/******************************************************************************/
/**
* DESCRIPTION
*
* This file is entry of sms test
*/
#ifndef __LBS_H__
#define __LBS_H__
#ifdef __cplusplus
extern "C" {
#endif
#define AM_LOCATION_SERVICE_LOCATION_BCD_LEN 5
#define LBSLOC_SUCCESS 0x0
#define UNKNOWN_LOCATION 0x1
#define PERMISSION_ERROR 0x2
#define UNKNOWN_ERROR 0x4
#define WIFILOC_SUCCESS 0xff
#define MOBILE_MNC (0)
#define UNICOM_MNC (1)
#define TELE_MNC (11)
#define IMSI_LEN (18)
#define MOBILE_NUM (6)
#define UNICOM_NUM (4)
#define TELE_NUM (4)
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif

View File

@ -0,0 +1,119 @@
/******************************************************************************/
/* */
/* Copyright 2024 by YAK TECHNOLOGIES CO.,LTD. All rights reserved. */
/* */
/******************************************************************************/
/**
* DESCRIPTION
*
* This file is entry of sms test
*/
#ifndef __SK_LOCATION_H__
#define __SK_LOCATION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "sk_comm.h"
#include "cmidev.h"
#include "sk_command.h"
#define MOBILE_MNC (0)
#define UNICOM_MNC (1)
#define TELE_MNC (11)
#define IMSI_LEN (18)
#define MOBILE_NUM (6)
#define UNICOM_NUM (4)
#define TELE_NUM (4)
#define WIFI_DEV_MAC_MAX_LEN (18)
#define WIFI_DEV_SSID_MAX_LEN CMI_DEV_MAX_SSID_HEX_LENGTH /* 32 */
//#define WIFI_SCAN_CHANNEL_MAX_NUM (13) /* 2.4G wifi channel*/
#define WIFI_SCAN_MaxNum 10
#define WIFISCAN_Ssid_len
typedef struct
{
char ssid[WIFI_DEV_SSID_MAX_LEN+1]; //探测到的wifi ssid
char mac[WIFI_DEV_MAC_MAX_LEN+1]; //探测到的wifi mac地址
int rssi; //wifi信号强度
}WIFI_Dev_Info_S;
typedef struct
{
int num;
WIFI_Dev_Info_S wifi_devs[WIFI_SCAN_MaxNum];
}WIFISCAN_S;
typedef struct
{
int tac;
int cellid;
int rssi;
}CELL_Info_S;
typedef struct
{
int mcc;
int mnc;
CELL_Info_S cur_cell;
int neighbor_num;
CELL_Info_S neighbor_cell[3];
}LBS_Info_S;
#define GNSS_GSV_maxNum 12
#define GNSS_CONSTELLATION_num 4
typedef struct
{
int type;
int total;
int index[GNSS_GSV_maxNum];
int elevation[GNSS_GSV_maxNum];
int azimuth[GNSS_GSV_maxNum];
int prn[GNSS_GSV_maxNum];
}GNSS_GSV_S;
typedef struct
{
double longitude; //"lon": "113.4201386", //经度 DDD.DDDDDD格式正数表示东半球负数表示西半球
double latitude; //"lat": "23.1782397", //纬度 DD.DDDDDD格式正数表示北半球负数表示南半球
double altitude; //"altitude": 100, //海拔 单位为米
int hdop; //"hdop": 10, //定位精度 单位为米
float speed; //"speed": 0.3, //速度 km/h
int gsv_count; //"satelliteNum": 5, //表明 GPS 卫星个数
}GPS_Info_S;
//
typedef struct
{
//lbs
LBS_Info_S lbs;
WIFISCAN_S wifiscan_devs;
//gps
GPS_Info_S gpsInfo;
//timestamp
int timestamp;
}Location_Info_S;
//void SK_SendMsg_toLocation(Enum_SK_Msg msg_id,void *param,int len);
int SK_SendMsg_toLocation(Enum_SK_Msg msg_id, void *pData, int len);
Location_Info_S * Location_get_curloc_info();
int SK_LocationTask_Init(void);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif

View File

@ -0,0 +1,139 @@
#ifndef __SK_MAIN_H__
#define __SK_MAIN_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "FreeRTOS.h"
#include "ostask.h"
#include "sk_comm.h"
#include "sk_location.h"
#define RealTimeEph_FileName "RealTimeEph.pgl"
#define OfflineEph_FileName "OfflineEph.pgl"
#define HealthData_FileName "HealthData"
#define LocateData_FileName "LocateData"
#define Configure_FileName "config_file"
/*
1,wifiscan: appGetWifiScanInfo ,wifiscan是否会跟网络使用冲突吗,
2,lbs:CmiDevGetBasicCellListInfoCnf cellIdGet appGetUeExtStatusInfoSync
3,json
4,bootloader里面检测charge pin的电平 slpManGetchargePinValue
5,atRilRegisterUrcCallback(atUrcCallback);
*/
typedef enum
{
E_LED_MODE_poweron = 0, //开机,红灯亮2秒
E_LED_MODE_offline, //离线,蓝灯闪烁
E_LED_MODE_online, //连接服务器成功,绿灯亮2秒
E_LED_MODE_charging, //充电中,红灯常亮
E_LED_MODE_charge_full, //充电已满,绿灯常亮
E_LED_MODE_idle, //空闲,灯不亮,按键时绿灯闪一下
E_LED_MODE_low_power, //低电,红灯闪烁
E_LED_MODE_sos, //sos,红灯快闪2分钟
E_LED_MODE_fota, //升级中,红绿蓝依次不停的循环闪烁
}ENUM_LED_Mode_Type;
typedef enum
{
E_HEALTH_DATA_TYPE_None = 0,
E_HEALTH_DATA_TYPE_HeartRate, //心率
E_HEALTH_DATA_TYPE_BloodOxygen, //血氧
E_HEALTH_DATA_TYPE_Temp, //体温
E_HEALTH_DATA_TYPE_Ecg, //心电图数据
E_HEALTH_DATA_TYPE_BloodPressure, //血压
E_HEALTH_DATA_TYPE_BodyMove, //体动,Gsensor data
E_HEALTH_DATA_TYPE_MedicalReport, //中医疗报告
E_HEALTH_DATA_TYPE_PPGData, //ppg data
E_HEALTH_DATA_TYPE_Max,
}ENUM_HEALTH_DATA_TYPE;
typedef struct
{
char imei_str[IMEI_StrLen_Max + 1];
char sn_str[SN_StrLen_Max + 1];
int data_type; //包含的数据类型
int timestamp;
}HEALTH_DATA_S;
typedef struct
{
int locate_interval;
int health_interval;
int report_interval;
}SK_Timer_Interval_S;
typedef struct
{
//int isOffline;
int gpseph_timestamp;
//int gpseph_filename;
int mode; //0:正常1外出
SK_Timer_Interval_S inside_interval;
SK_Timer_Interval_S outside_interval;
SK_Timer_Interval_S sos_interval;
SK_Timer_Interval_S Monitor_interval; //主动监控时间间隔
SK_Timer_Interval_S Emergency_interval; //健康紧急状态时间间隔
int hr_max;
int hr_min;
char test_str[10];
int xxygen_min;
int temp_max;
int temp_min;
}Config_Info_S;
typedef struct
{
BOOL bCharging; //充电状态
BOOL bBatFull; //充电完成
BOOL bPowerOn; //开机,TRUE正在开机FALSE已经开机
BOOL bLowPower; //电量不足
uint8_t sim_status;
BOOL mobile_status;
BOOL bPDP;
BOOL bConnected;
BOOL bLogin;
int data_interval;
int locate_interval;
int net_interval;
Location_Info_S loc_info; //当前定位信息
BOOL bOutside; //室内模式,0 室内1外出
BOOL bSOS; //SOS状态
BOOL bEmergency; //健康紧急状态
BOOL bMonitoring; //主动监控状态
Config_Info_S config_info;
}SK_MainDev_S;
SK_MainDev_S *getMainDevInfo(void);
int SK_SendMsg_ToMainTask(Enum_SK_Msg msg_id, void *pData, int len);
void Led_Show_Update(void);
int32_t SK_MainTask_Init(void);
int SK_PPG_Task_Init(void);
int SK_GPS_UART_Task_Init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,29 @@
/******************************************************************************/
/* */
/* Copyright 2024 by YAK TECHNOLOGIES CO.,LTD. All rights reserved. */
/* */
/******************************************************************************/
/**
* DESCRIPTION
*
* This file is entry of sms test
*/
#ifndef __SK_NET_H__
#define __SK_NET_H__
#include "sk_comm.h"
typedef enum
{
E_Socket_State_Init,
E_Socket_State_Disconneted,
E_Socket_State_Conneting, //正在连接(重连)中
E_Socket_State_Conneted, //连接已经建立,尝试登录
E_Socket_State_Login, //已经登录
E_Socket_State_Max
} Enum_Socket_State;
int32_t SK_SocketTask_Init(void);
int SK_SendMsg_ToSocket(Enum_SK_Msg msg_id, void *pData, int len);
#endif

View File

@ -0,0 +1,35 @@
/******************************************************************************/
/* */
/* Copyright 2024 by YAK TECHNOLOGIES CO.,LTD. All rights reserved. */
/* */
/******************************************************************************/
/**
* DESCRIPTION
*
* This file is entry of sms test
*/
#ifndef __TEMP_H__
#define __TEMP_H__
#ifdef __cplusplus
extern "C" {
#endif
void Temp_PowerOn(void);
void Temp_PowerOff(void);
void Temp_Gpio_Init(void);
int32_t get_bytemp(void);
void Temp_Gpio_Init_test(void);
int32_t BodyTempRead(void);
void gpio_test();
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif

View File

@ -32,9 +32,12 @@
#include "ctw_task.h"
#endif
#include "version.h"
#include "sk_net.h"
#define USRAPP_TASK_STACK_SIZE (1024)
int32_t SK_SocketApp_Init(void);
#if defined FEATURE_FREERTOS_ENABLE
static StaticTask_t usrapp_task;
static uint8_t usrapp_task_stack[USRAPP_TASK_STACK_SIZE];
@ -75,6 +78,7 @@ void daemonTaskInit(void)
}
extern int32_t SK_MainTask_Init(void);
static void appInit(void *arg)
{
ECPLAT_PRINTF(UNILOG_PLA_APP, EC_CHIP_VERSION_1, P_INFO, "%s", EC_CHIP_VERSION);
@ -114,6 +118,8 @@ static void appInit(void *arg)
apPrintIdlePercent();
#endif
SK_MainTask_Init();
}
/**

View File

@ -987,12 +987,14 @@ void BSP_CustomInit(void)
ResetLockupCfg(true, true);
else
ResetLockupCfg(false, false);
#if 1 //lkg modified
#if ((RTE_ONE_UART_AT == 1) || (RTE_TWO_UART_AT == 1))
SetAtUart(PORT_USART_1);
#if (RTE_TWO_UART_AT == 1)
SetAtUart(PORT_USART_2);
#endif
#endif
#endif
if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_CONTROL) != 0)

View File

@ -0,0 +1,302 @@
#ifdef _WINDOWS
#include "win_com.h"
#else
#include "aic_size.h"
#include <aic_osa_ex.h>
#endif
#include "com_list.h"
u16 List_Init(LIST_HEAD_T *pList)
{
pList->num = 0;
pList->pHeadNode = NULL;
return 0;
}
u16 List_AddNode_ToHead(LIST_HEAD_T *pList,COM_LIST_Node_T *pNode)
{
if ((NULL == pList)||(NULL == pNode))
{
return -1;
}
if (0 == pList->num)
{
pNode->next = NULL;
pNode->prev = NULL;
pList->pHeadNode = pNode;
}
else
{
pNode->next = pList->pHeadNode;
pNode->prev = NULL;
pList->pHeadNode->prev = pNode;
pList->pHeadNode = pNode;
}
pList->num++;
return 0;
}
u16 List_AddToHead(LIST_HEAD_T *pList,void *pData)
{
COM_LIST_Node_T *pNode = NULL;
if ((NULL == pList)||(NULL == pData))
{
return -1;
}
pNode = (COM_LIST_Node_T *)aic_zalloc(sizeof(COM_LIST_Node_T));
if (NULL == pNode)
{
return -1;
}
pNode->data = pData;
List_AddNode_ToHead(pList,pNode);
return 0;
}
u16 List_AddNode_ToTail(LIST_HEAD_T *pList,COM_LIST_Node_T *pNode)
{
COM_LIST_Node_T *pCurNode = NULL;
if ((NULL == pList)||(NULL == pNode))
{
return -1;
}
if (0 == pList->num)
{
pNode->next = NULL;
pNode->prev = NULL;
pList->pHeadNode = pNode;
pList->num++;
return 0;
}
pCurNode = pList->pHeadNode;
while( NULL != pCurNode->next)
{
pCurNode = pCurNode->next;
}
pCurNode->next = pNode;
pNode->prev = pCurNode;
pList->num++;
return 0;
}
u16 List_AddToTail(LIST_HEAD_T *pList,void *pData)
{
COM_LIST_Node_T *pNode = NULL;
if ((NULL == pList)||(NULL == pData))
{
return -1;
}
pNode = (COM_LIST_Node_T *)aic_zalloc(sizeof(COM_LIST_Node_T));
if (NULL == pNode)
{
return -1;
}
pNode->data = pData;
List_AddNode_ToTail(pList,pNode);
return 0;
}
u16 List_InsertNode_ByIndex(LIST_HEAD_T *pList,int index,COM_LIST_Node_T *pNode)
{
COM_LIST_Node_T *pCurNode = NULL;
if ((NULL == pList)||(NULL == pNode))
{
return -1;
}
if (0 == pList->num)
{
pNode->next = NULL;
pNode->prev = NULL;
pList->pHeadNode = pNode;
pList->num++;
return 0;
}
if (index > pList->num)
{
index = pList->num;
}
pCurNode = pList->pHeadNode;
while(index > 1)
{
pCurNode = pCurNode->next;
index--;
}
pCurNode->next = pNode;
pNode->prev = pCurNode;
pList->num++;
return 0;
}
u16 List_DelNode_FromHead(LIST_HEAD_T *pList)
{
COM_LIST_Node_T *pCurNode = NULL;
if (NULL == pList)
{
return -1;
}
if (pList->num == 0)
{
pList->pHeadNode = NULL;
return 0;
}
pCurNode = pList->pHeadNode;
pList->pHeadNode = pCurNode->next;
pList->pHeadNode->prev = NULL;
pList->num--;
//pCurNode->next = NULL;
aic_free(pCurNode->data);
aic_free(pCurNode);
return 0;
}
u16 List_DelNode_FromTail(LIST_HEAD_T *pList)
{
COM_LIST_Node_T *pCurNode = NULL;
if (NULL == pList)
{
return -1;
}
if (0 == pList->num)
{
pList->pHeadNode = NULL;
return 0;
}
pCurNode = pList->pHeadNode;
while( NULL != pCurNode->next)
{
pCurNode = pCurNode->next;
}
pCurNode->prev->next = NULL;
pList->num--;
aic_free(pCurNode->data);
aic_free(pCurNode);
return 0;
}
u16 List_DelNode_ByIndex(LIST_HEAD_T *pList,int index,COM_LIST_Node_T *pNode)
{
COM_LIST_Node_T *pCurNode = NULL;
if ((NULL == pList)||(NULL == pNode))
{
return -1;
}
if (index > pList->num)
{
index = pList->num;
}
return 0;
}
COM_LIST_Node_T *List_getNode_FromHead(LIST_HEAD_T *pList)
{
COM_LIST_Node_T *pCurNode = NULL;
if (NULL == pList)
{
return NULL;
}
if (0 == pList->num)
{
pList->pHeadNode = NULL;
return NULL;
}
pCurNode = pList->pHeadNode;
pList->pHeadNode = pCurNode->next;
pList->pHeadNode->prev = NULL;
pList->num--;
return pCurNode;
}
void *List_getFromHead(LIST_HEAD_T *pList)
{
void *pData = NULL;
COM_LIST_Node_T *pCurNode = List_getNode_FromHead(pList);
if (NULL == pCurNode)
{
return NULL;
}
pData = pCurNode->data;
aic_free(pCurNode);
return pData;
}
u16 List_ClearAll(LIST_HEAD_T *pList)
{
COM_LIST_Node_T *pCurNode = NULL;
if (NULL == pList)
{
return -1;
}
if (pList->num == 0)
{
pList->pHeadNode = NULL;
return 0;
}
pCurNode = pList->pHeadNode;
while(NULL != pCurNode)
{
pList->pHeadNode = pCurNode->next;
pList->pHeadNode->prev = NULL;
pList->num--;
//pCurNode->next = NULL;
aic_free(pCurNode->data);
aic_free(pCurNode);
pCurNode = pList->pHeadNode;
}
return 0;
}
COM_LIST_Node_T * List_GetNode_ByIndex(LIST_HEAD_T *pList,int index)
{
COM_LIST_Node_T *pCurNode = NULL;
if (NULL == pList)
{
return NULL;
}
pCurNode = pList->pHeadNode;
if (index >= pList->num)
{
return NULL;
}
while(index > 0)
{
if (NULL == pCurNode)
{
return NULL;
}
pCurNode = pCurNode->next;
index--;
}
return pCurNode;
}

View File

@ -0,0 +1,402 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
// #include <launcher/user_config.h>
#include <board_cfg.h>
#include <drivers/gpio.h>
// #include <drivers/hrtimer.h>
#if 1
#define ERR_NC -100
#define ERR_DONE -101
#define ERR_DAT -102
#define ERR_CRC -103
#define GPIO_TEMP_NUM 63
extern void soc_udelay(uint32_t us);
/*===========================================================================*/
// extern s32_t os_sleep(int timeout);
// #define CONFIG_PANEL_NTCCHECK_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_A_NAME, 20, GPIO_ACTIVE_HIGH, 1) //GPIO63 采集
#define CONFIG_PANEL_NTCCHECK_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_B_NAME, 31, GPIO_ACTIVE_HIGH, 1) //GPIO63 采集
#define CONFIG_PANEL_NTCPOWER_62_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_B_NAME, 25, GPIO_ACTIVE_HIGH, 1) //GPIO62 POWER
// #define CONFIG_PANEL_NTCPOWER_61_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_B_NAME, 29, GPIO_ACTIVE_LOW, 1) //GPIO61 POWER
// #define CONFIG_PANEL_NTCPOWER_60_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_B_NAME, 24, GPIO_ACTIVE_HIGH, 1) //GPIO56 POWER
// #define CONFIG_PANEL_BP6APOWER_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_B_NAME, GPIO_TEMP_NUM, GPIO_ACTIVE_HIGH, 1) //GPIO53
// #define CONFIG_PANEL_BP6ARESET_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_A_NAME, 26, GPIO_ACTIVE_HIGH, 1) //GPIO53
// #define CONFIG_PANEL_BP6ABOOTMODE_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_A_NAME, 27, GPIO_ACTIVE_HIGH, 1) //GPIO53
// #define CONFIG_MOTOR_GPIO GPIO_CFG_MAKE(CONFIG_GPIO_B_NAME, 24, GPIO_ACTIVE_HIGH, 0) //GPIO62 POWER
#ifdef CONFIG_PANEL_BP6APOWER_GPIO
static const struct gpio_cfg bp6apower_gpio_cfg = CONFIG_PANEL_BP6APOWER_GPIO;
const struct device *bp6apower_gpio_dev;
static const struct gpio_cfg bp6areset_gpio_cfg = CONFIG_PANEL_BP6ARESET_GPIO;
const struct device *bp6areset_gpio_dev;
static const struct gpio_cfg bp6abootmode_gpio_cfg = CONFIG_PANEL_BP6ABOOTMODE_GPIO;
const struct device *bp6abootmode_gpio_dev;
#endif
#ifdef CONFIG_MOTOR_GPIO
static const struct gpio_cfg motor_gpio_cfg = CONFIG_MOTOR_GPIO;
const struct device *motor_gpio_dev;
#endif
#ifdef CONFIG_PANEL_NTCPOWER_62_GPIO
static const struct gpio_cfg ntcpower_62_gpio_cfg = CONFIG_PANEL_NTCPOWER_62_GPIO;
const struct device *ntcpower_62_gpio_dev;
#endif
#ifdef CONFIG_PANEL_NTCPOWER_61_GPIO
static const struct gpio_cfg ntcpower_61_gpio_cfg = CONFIG_PANEL_NTCPOWER_61_GPIO;
const struct device *ntcpower_61_gpio_dev;
#endif
#ifdef CONFIG_PANEL_NTCPOWER_60_GPIO
static const struct gpio_cfg ntcpower_60_gpio_cfg = CONFIG_PANEL_NTCPOWER_60_GPIO;
const struct device *ntcpower_60_gpio_dev;
#endif
#ifdef CONFIG_PANEL_NTCCHECK_GPIO
static const struct gpio_cfg ntccheck_gpio_cfg = CONFIG_PANEL_NTCCHECK_GPIO;
const struct device *ntccheck_gpio_dev;
#endif
#define GPIO_BSR(x) GPIO_REG_BSR(GPIO_REG_BASE, x)//高
#define GPIO_BRR(x) GPIO_REG_BRR(GPIO_REG_BASE, x)//低
//-----------------by usr ----------------------
// #define pin_write(x,y) gpio_pin_set(ntcpower_gpio_dev, ntcpower_gpio_cfg.gpion, y)
// #define pin_mode(x,y) NULL
// #define pin_read(x) gpio_pin_get(ntccheck_gpio_dev,ntccheck_gpio_cfg.gpion)
#define DQ_PIN NULL
// #define delay_ms(x) k_msleep(x)
// #define delay_us(x) soc_udelay(x)
//---------------------------------------
static uint8_t reversal(uint8_t data)
{
uint8_t _data = data;
uint8_t i, retValue = 1;
for (i = 0; i < 8; i++)
{
unsigned char temp = _data & 0x01;
if (temp)
retValue |= 0x01;
else
retValue &= ~0x01;
if (i == 7)
break;
retValue <<= 1;
_data >>= 1;
}
return retValue;
}
// crc8_maxim input and output reversal
//x8+x5+x4+1 0x131
static uint8_t crc8_maxim(uint8_t *pdat, uint8_t len)
{
uint8_t ret;
uint8_t uCRC = 0x00; //CRC
for (uint8_t num = 0; num < len; num++)
{
ret = reversal(*pdat++);
uCRC = (ret) ^ uCRC; //
for (uint8_t x = 0; x < 8; x++)
{
if (uCRC & 0x80)
{
uCRC = uCRC << 1; //
uCRC = uCRC ^ 0x31; //
}
else //
{
uCRC = uCRC << 1; //
}
}
}
ret = reversal(uCRC);
return ret;
}
int nst1002_read_cal(uint16_t *pcal)
{
int retry = 0;
uint8_t crc;
uint8_t i,j;
uint8_t bit0 = 1;
uint8_t data[3] = { 0, 0, 0 };
uint8_t swap[2];
uint8_t read[4];
//--------------power up------------------------
// pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD);
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_OUTPUT);
sys_write32(GPIO_BIT(GPIO_TEMP_NUM), GPIO_BSR(GPIO_TEMP_NUM));
k_msleep(15);//15
//--------------send start convert ------------------------------
sys_write32(GPIO_BIT(GPIO_TEMP_NUM), GPIO_BRR(GPIO_TEMP_NUM)); //DQ low
soc_udelay(300);
sys_write32(GPIO_BIT(GPIO_TEMP_NUM), GPIO_BSR(GPIO_TEMP_NUM));
soc_udelay(10);
//-----------------check DQ pin status should be high---------------------------------------
// pin_mode(DQ_PIN, PIN_MODE_INPUT);
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_INPUT|GPIO_PULL_UP);//GPIO_PULL_UP
soc_udelay(100);
// k_msleep(1);
if (gpio_pin_get(ntccheck_gpio_dev,ntccheck_gpio_cfg.gpion) == 0)
{
*pcal = (uint16_t)(ERR_NC*128);
return-1;
}
// k_msleep(GPIO_TEMP_NUM);
k_msleep(20);
//--------------wait for done pulse---------------
do
{
bit0 = gpio_pin_get(ntccheck_gpio_dev,ntccheck_gpio_cfg.gpion);
soc_udelay(2);
retry++;
if (retry > 20000)// time out 40ms
{
*pcal = (uint16_t)(ERR_DONE*128);
return -2;
}
} while (bit0);
soc_udelay(10);
printk("bit0:%x\r\n",bit0);
//--------------read 24bit data---------------
sys_write32(GPIO_BIT(GPIO_TEMP_NUM), GPIO_BSR(GPIO_TEMP_NUM));
// pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD);
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_OUTPUT);
soc_udelay(200);
for (i = 0; i < 24; i++)
{
sys_write32(GPIO_BIT(GPIO_TEMP_NUM), GPIO_BRR(GPIO_TEMP_NUM)); //Falling edge
soc_udelay(1); // Adjust according to the mcu clock cycle,It's not necessary
// pin_mode(DQ_PIN, PIN_MODE_INPUT);
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_INPUT|GPIO_PULL_UP);//GPIO_PULL_UP
// If the output bit is 0, the DQ will remain low for about 14us
for(j=0;j<4;j++) // It's not necessary to read it 4 timers , adjust according to the mcu clock cycle
{
read[j]= gpio_pin_get(ntccheck_gpio_dev,ntccheck_gpio_cfg.gpion);
}
if(read[0]==read[1]) // It's not necessary
{
bit0 = read[1];
}
else
{
*pcal = (uint16_t)(ERR_DAT*128);
return -3;
}
data[i / 8] <<= 1;
data[i / 8] |= bit0;
sys_write32(GPIO_BIT(GPIO_TEMP_NUM), GPIO_BSR(GPIO_TEMP_NUM)); //DQ low
// pin_mode(DQ_PIN, PIN_MODE_OUTPUT_OD);
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_OUTPUT);
soc_udelay(60);
}
printk("---------data %02x %02x %02x \r\n",data[0],data[1],data[2]);
//------------------- NST1002 Big Endian,but mcu Little Endian
swap[0] = data[1];
swap[1] = data[0];
*pcal = *((uint16_t *) swap);// output data need swap
crc = crc8_maxim(data, 2);
if (crc == data[2])
return 0;
else
{
printk("data %02x %02x %02x CRC %02x\r\n",data[0],data[1],data[2],crc);
*pcal=ERR_CRC*128;
return-4;
}
}
char err_code[4][20]={"NOT Connected","No DONE signal","DAT Recv Err","CRC Err"};
int32_t read_temp(void)
{ int err,ei;
double dtmp;
int16_t cal;
int32_t value = 0;
printk("NST read_temp START\r\n");
err=nst1002_read_cal((uint16_t *)&cal);
if(err<0)
{
ei=-1-err;
if(ei<4)
printk("NST1002 err %s\r\n",err_code[ei]);
return 0;
}
dtmp = cal / 128.0;
value = dtmp*10;
printk("NST Temp %3.7f\r\n",dtmp);
printk("NST Temp %d\r\n",value);
printk("NST read_temp END\r\n");
return value;
}
int16_t APP_read_temp(void)
{ int err,ei;
double dtmp;
int16_t cal;
int32_t value = 0;
printk("NST read_temp START\r\n");
err=nst1002_read_cal((uint16_t *)&cal);
if(err<0)
{
ei=-1-err;
if(ei<4)
printk("NST1002 err %s\r\n",err_code[ei]);
return 0;
}
dtmp = cal / 128.0;
value = dtmp*100;
printk("NST Temp %3.7f\r\n",dtmp);
printk("NST Temp %d\r\n",value);
printk("NST read_temp END\r\n");
return value;
}
void change_check_tempmode(uint8_t ch)
{
}
void Temp_NST1002_init(void)
{
printk("Temp_NST1002_init !!!\r\n");
#ifdef CONFIG_PANEL_NTCPOWER_60_GPIO
ntcpower_60_gpio_dev = device_get_binding(ntcpower_60_gpio_cfg.gpio_dev_name);
if (ntcpower_60_gpio_dev == NULL) {
printk("Couldn't find ntc power pin");
}
if (gpio_pin_configure(ntcpower_60_gpio_dev, ntcpower_60_gpio_cfg.gpion,
GPIO_OUTPUT_ACTIVE | ntcpower_60_gpio_cfg.flag)) {
printk("Couldn't configure ntc power pin");
}
#endif
#ifdef CONFIG_PANEL_NTCPOWER_62_GPIO
ntcpower_62_gpio_dev = device_get_binding(ntcpower_62_gpio_cfg.gpio_dev_name);
if (ntcpower_62_gpio_dev == NULL) {
printk("Couldn't find ntc power pin");
}
if (gpio_pin_configure(ntcpower_62_gpio_dev, ntcpower_62_gpio_cfg.gpion,
GPIO_OUTPUT_ACTIVE | ntcpower_62_gpio_cfg.flag)) {
printk("Couldn't configure ntc power pin");
}
#endif
gpio_pin_set(ntcpower_62_gpio_dev, ntcpower_62_gpio_cfg.gpion, 0);
ntccheck_gpio_dev = device_get_binding(ntccheck_gpio_cfg.gpio_dev_name);
if (ntccheck_gpio_dev == NULL) {
printk("Couldn't find ntc check pin");
}
if (gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_OUTPUT)) {
printk("Couldn't configure ntc check pin");
}
change_check_tempmode(0xff);
}
int32_t get_bytemp(void)
{
int32_t value = 0;
gpio_pin_set(ntcpower_62_gpio_dev, ntcpower_62_gpio_cfg.gpion, 0);
// gpio_pin_set(ntcpower_60_gpio_dev, ntcpower_60_gpio_cfg.gpion, 1);
printk("1111get_bytemp:%d\r\n",value);
#if 1
// gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_OUTPUT);
// //切换传感器供电
// change_check_tempmode(0);
// printk("2222get_bytemp:%d\r\n",value);
// sys_write32(GPIO_BIT(20), GPIO_BSR(20));
// //等待供电稳定
// k_msleep(100);
//测温
value = read_temp();
printk("3333get_bytemp:%d\r\n",value);
change_check_tempmode(0xff);
gpio_pin_set(ntcpower_62_gpio_dev, ntcpower_62_gpio_cfg.gpion, 0);
// gpio_pin_set(ntcpower_60_gpio_dev, ntcpower_60_gpio_cfg.gpion, 0);
#endif
return value;
}
int16_t skin_algo_temp(void)
{
int16_t body_temp=0;
#if 0
int32_t value = 0;
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_OUTPUT);
//切换传感器供电
change_check_tempmode(2);
sys_write32(GPIO_BIT(20), GPIO_BSR(20));
//等待供电稳定
k_msleep(100);
//测温
value = read_temp();
change_check_tempmode(0xff);
printk("skin_algo_temp:%d\r\n",value);
body_temp=app_convert_body_temp(value);
printk("body_temp:%d\r\n",body_temp);
// tempout = 4200;
#endif
gpio_pin_configure(ntccheck_gpio_dev, ntccheck_gpio_cfg.gpion,GPIO_INPUT);
body_temp=gpio_pin_get(ntccheck_gpio_dev,ntccheck_gpio_cfg.gpion);
printk("body_temp:%x\r\n",body_temp);
return body_temp;
}
#endif

View File

@ -0,0 +1,511 @@
#ifndef Goodix_DSP_EXPORTS
#include "goodix_type.h"
#define NET_VERSION "GH3228T_cd023f"
#define NET_SIZE 3924
const uint32_t Spo2WRWeights[] = {
0, 1073741329, 3999574012, 3471442047, 3780214886, 4000178303, 2929950804, 2495143628,
2970290559, 2156167122, 619404616, 789348584, 3319933902, 2136996736, 3954499501, 2155844344,
4260807495, 1448902467, 3148709986, 3708372977, 3363859666, 1082112248, 3206147517, 1058585058,
1058107101, 1058524726, 1058716434, 1060996767, 1057088519, 1062156363, 1060983320, 1064176116,
1051455998, 1059839158, 1063356877, 1065353216, 1058338418, 1058483133, 1062110265, 1060347853,
4096437775, 4173578114, 96249287, 142302726, 46176432, 4279652685, 4201656531, 120110439,
112533895, 4131872153, 4251881560, 4259020204, 4058346203, 268435456, 4187527169, 4110472463,
3229969796, 1082486148, 3221450872, 1073899927, 888286203, 1051730340, 3366000070, 85295127,
1387195297, 3675960313, 333756164, 333536896, 3441354296, 856907113, 3363813340, 183520783,
601333949, 3803309266, 3584077349, 2157104088, 3210167754, 1062573886, 1063109708, 1065353216,
1064663899, 1063962545, 4056203542, 27958070, 268435456, 240853462, 3222753533, 1075269885,
0, 1080528951, 150957696, 4169099135, 1745584307, 3212691973, 1065078385, 1056383158,
1065353216, 1059458681, 1059967368, 43763034, 36959618, 29778676, 268435456, 3221610982,
1074127334, 0, 1074752954, 1082923648, 52227200, 4221369216, 2135430759, 2159638586,
3531608289, 4135525715, 2715809664, 209761226, 2771812447, 3622469461, 773619865, 2162688333,
2206207203, 1937762878, 2160061178, 3207675224, 1060100829, 1054674996, 1052144291, 1065353216,
1059417531, 1049044443, 1059058566, 1055481670, 1065001480, 1055421370, 1051162596, 1058362508,
1050752920, 1053679741, 1061351470, 1058995308, 1058531701, 4181018345, 4261061511, 4178568690,
147835997, 155989941, 4121771723, 84695956, 4165806231, 4123362933, 4145569003, 217143882,
4292846979, 4156635296, 268435456, 22989955, 4148329231, 3218508640, 1071024992, 3215272250,
1066893384, 0, 1073250996, 2161419784, 232790274, 3435180006, 1200405713, 2278343415,
3087714316, 3456860347, 951516346, 1377696222, 4062543713, 3579915609, 4084432880, 1108686887,
876234790, 2136013639, 820272608, 3209444426, 1061856209, 1065348550, 1061910582, 1063509064,
1065353216, 4281893116, 4026531840, 74441011, 4282719262, 3228146934, 1080663286, 0,
1082660499, 2153771647, 4033469177, 2145588608, 3208234995, 1060656227, 1061204640, 1063926475,
1059131310, 1065353216, 4293907511, 4285572924, 23145812, 4026531840, 3223207109, 1075723461,
0, 1073459757, 2161707529, 562037750, 2161642503, 2148857586, 142607599, 276888280,
2021710558, 2148950699, 2407560104, 176169955, 981508607, 2161648597, 562031577, 612433660,
1573617582, 4109220736, 3208800200, 1061217016, 1060271586, 1052288904, 1062534431, 1065353216,
1052662144, 1043946311, 1043405011, 1049353392, 1041199451, 1049562776, 1046290015, 1051475883,
1044370844, 1050045716, 1050591949, 1049566002, 4026531840, 4091904097, 4112926457, 4256521358,
4274151182, 4129422542, 4107332473, 4137344156, 4163127615, 4050213461, 4283471552, 4288776512,
4148506786, 88599912, 4191362814, 4205773158, 3214316959, 1066833311, 3197379088, 1035358543,
0, 1072226857, 3188088941, 1045560072, 3180863642, 1049821279, 1057142566, 1053751385,
1034609895, 3198056750, 3190147577, 3203025485, 1060921984, 1044424167, 3125393333, 1052072978,
3178442557, 1044065743, 3187014746, 1059069745, 1036939185, 1055180309, 3181306100, 3171395037,
1049596484, 1053454790, 1042198871, 3185582551, 3195715016, 1047497607, 3163126620, 1028103420,
3182220766, 3163506534, 3148835688, 3193581754, 3183899052, 3174627705, 1030714171, 3172964331,
1052302730, 3182509810, 1045909100, 3179631113, 1039075737, 3172805854, 1056014575, 3157871968,
3179349434, 1047930853, 998135196, 3179998868, 1049233863, 1036866499, 3170565541, 1030639566,
1045211681, 993360752, 1024130666, 3185090281, 3188860645, 1037967182, 1014993599, 1035674196,
3188308867, 3192352835, 1043485487, 3199297430, 1040354856, 1033474467, 3199990705, 1045841800,
3175429609, 1044661920, 3199880136, 1029998133, 1021794559, 1021463703, 1033271914, 1034820233,
1029709998, 3181645919, 3147799899, 1049963030, 3199184164, 3199077444, 3155900674, 3203313546,
1037468479, 3192183590, 1044285232, 3198823559, 3205993607, 3197838891, 3205617185, 3172102450,
1053477708, 3195074063, 3191169307, 1043668327, 3183488291, 1052728242, 1034022353, 1046113422,
1044279750, 1041054848, 3191620331, 3187156697, 1041035348, 1034087071, 1032813201, 1023877648,
1042245215, 3188129766, 3167637752, 1043168907, 3203998333, 3191339179, 3162300078, 3202238577,
3163295464, 1032097768, 1052482054, 3179969028, 3203547446, 3132765183, 993714416, 999208604,
1045959648, 3174859416, 3195910896, 1041232965, 3155232172, 1051441667, 3196366384, 3196841661,
1048244070, 3192420112, 1033124028, 1048715737, 1044820215, 1044733986, 3188801261, 3187447003,
3187977533, 1049484017, 1047212308, 3167346802, 1046109428, 1040397796, 3180521555, 3191611651,
1031928783, 1037162464, 3189617626, 3193939535, 1026923543, 3187748320, 1049254874, 1035633574,
3197885329, 3189034114, 3175164678, 1045463575, 3197861566, 3188564876, 1050754530, 3182087459,
1045174693, 3189564905, 3144047360, 3183190091, 3191713387, 3171598323, 1029072817, 3212869761,
1065287423, 1935179521, 1420445853, 880764287, 1469249464, 3231250559, 1149484672, 904494893,
2160514461, 18154881, 3051126562, 2071985661, 388267929, 478137793, 3995744738, 2135774750,
1630175210, 3179323535, 3472780780, 3414159926, 2158349285, 3206592775, 1059026837, 1060511955,
1059792811, 1064969570, 1061210391, 1062931313, 1064696255, 1064581728, 1065353216, 1060282289,
1064066905, 1058351370, 1061899575, 1062189625, 1061840365, 1061057472, 1064851025, 4279120814,
98907296, 4164514887, 31336640, 4137201817, 4255047186, 4141284609, 122038685, 4254578309,
4138156253, 30501590, 4266867559, 4026531840, 57387976, 4221338006, 4223451414, 3226551897,
1079068249, 3220028740, 1071256481, 394255882, 4277088757, 3472631835, 1875497511, 4110793252,
536542958, 3436300312, 2145178391, 2158366636, 3144058459, 537956298, 3794362566, 620970623,
1015229128, 944261495, 3755134293, 3213671024, 1066115323, 1062815108, 1065353216, 1057691518,
1058210830, 4027065002, 171977037, 4198783646, 268435456, 3212988257, 1065504609, 0,
1084488549, 3902088064, 2131984401, 1105101007, 3211491700, 1063887489, 1060175172, 1061331196,
1061379347, 1065353216, 268435456, 159007971, 4235757866, 53669661, 3230840635, 1083356987,
0, 1068453332, 3873210587, 2137524409, 4005986557, 922452116, 260001295, 3239346407,
2135560412, 3502473221, 4118787726, 3656089621, 2159492934, 2134693288, 2154043287, 545238010,
1954486799, 337575808, 3218290695, 1070698903, 1058037646, 1046971298, 1051851149, 1053039682,
1047134333, 1057149333, 1049680280, 1052161499, 1045619643, 1065353216, 1054905987, 1044675046,
1049074662, 1044604299, 1049352733, 1050360702, 44440324, 4058223431, 4077551628, 4172568318,
118086542, 4130925078, 10311762, 4181443929, 1676601, 12985021, 4278335127, 4122072537,
4280091991, 4167096920, 4026531840, 4063318117, 3214821567, 1067337919, 3216110490, 1061298437,
0, 1078092990, 847190350, 487543542, 4044517401, 148893302, 652227143, 53421900,
1110843663, 3078575385, 3673671144, 3565223828, 3352014834, 3852175336, 2138860898, 273174138,
1076509756, 812991063, 3213074511, 1065523470, 1065353216, 1062390299, 1062765183, 1059857864,
4246158256, 4131911022, 4026531840, 4249656307, 3223861647, 1076377999, 0, 1091265068,
2132605823, 2145683408, 2142110530, 3208989910, 1061405244, 1065353216, 1059505525, 1064833704,
1059611897, 4026531840, 230433096, 4294700819, 163168176, 3224217651, 1076734003, 0,
1081132085, 3205163904, 3856695501, 4260593700, 3151986704, 2147692478, 2509275153, 2162720964,
368869587, 2160706589, 3538821504, 2147228912, 752910368, 2901246143, 2934893184, 2549530240,
269254657, 3208962441, 1061377990, 1056990552, 1061548569, 1063123537, 1060051909, 1058543253,
1053995739, 1058039691, 1065353216, 1054629078, 1052946365, 1044676395, 1062117442, 1059064284,
1062187328, 1059471454, 1060631745, 60177608, 4229137977, 4139826956, 4087864650, 4166052301,
4026531840, 4194234425, 4163332493, 4124766682, 4240524033, 4127614679, 4122431874, 4116267497,
4109987968, 4102945804, 4148880372, 3218808151, 1071324503, 3224008600, 1058411404, 0,
1078148423, 1044206622, 1053430767, 1056639557, 1049911082, 1058440975, 1045600926, 1051295666,
1049504051, 1037647009, 3191770066, 3176605117, 1050932703, 3174820307, 1061602744, 1059485086,
1064398268, 3186784299, 1057080053, 3202219812, 1056136033, 1046105521, 1043444907, 3205015334,
3189649948, 3188307446, 3196246667, 3179146919, 3203560180, 3179822049, 3187058748, 3128552276,
1041648308, 3174100737, 1045517449, 1019777518, 1034703778, 1045043416, 1034437962, 3196975499,
3191496178, 3185590886, 1045498901, 3197404380, 1048020441, 1040863381, 3197627345, 1042614714,
1046713908, 3198131318, 3198766142, 996709457, 3181169656, 1045292443, 1044576779, 1050344993,
1056386536, 3184294258, 3197472383, 3175578921, 3199081539, 3144412053, 1043539774, 1044330652,
3202181394, 1041005636, 1045004977, 3205629050, 1049268002, 3182377285, 3190240943, 1037542947,
3197596410, 3195379236, 1052643436, 3199977501, 1047425113, 3197377786, 3181277733, 3182788862,
1042819476, 1026024375, 1052178452, 1062627375, 1048699344, 3190138415, 1046713891, 3186239350,
1045117425, 1034666791, 1053827024, 1033318928, 1046457723, 1046647845, 3185454146, 1045705785,
1051733151, 3200514160, 1057248131, 3182674871, 3200709601, 1037699909, 1031837487, 1006291401,
3197752302, 3199361146, 3168744842, 3166192477, 3202962896, 3195819441, 1045525673, 1051631453,
3193334791, 1046767212, 3206113678, 3200771626, 1043584866, 3202866770, 1050384903, 1033989224,
3190094361, 3198226275, 3179364448, 3194067628, 3193627120, 3179984256, 1026714116, 1046937217,
3191408781, 1048741869, 1039644997, 3175093253, 1006261299, 3201985755, 1050332211, 1046510808,
3180478847, 1032136374, 3147490039, 3156853076, 3202540773, 1034998490, 1041386093, 1042093516,
3194414963, 1048838842, 1047218431, 3203886903, 3173541244, 3199707043, 1044541491, 1032495013,
3195946982, 3204284267, 3192613026, 3202755777, 3206369496, 3206167038, 3182001609, 1044610496,
3206695141, 1025742914, 3207162995, 3190237992, 1033926510, 3204469703, 1016325476, 1033196987,
1040847229, 986556084, 1039213138, 1037606384, 1033852052, 1043964737, 3175299710, 3172095444,
1046889179, 1041888244, 1045016466, 3167606236, 1031985124, 1043137086, 3152091620, 1035225234,
1029004097, 1035840556, 1045419555, 1038176065, 1036759116, 3193383753, 3188076789, 3193863542,
3194250162, 3204539587, 3201202884, 3192855357, 3196890203, 3189559290, 3203621266, 3199361486,
3191882711, 3197672037, 3195932476, 3191936557, 1041818141, 1041447921, 1052296868, 1048900640,
1045096180, 1048559016, 1046109303, 1045536288, 1049935330, 1028920180, 1048808803, 1049970427,
1036946671, 1044396132, 1048702558, 3192069902, 1044104997, 1022692071, 3193325444, 1040833267,
3170947908, 1045648860, 3157772117, 1039307701, 3163570032, 1034065563, 1028958764, 1041991661,
1041505426, 1043325243, 3171254946, 3180657300, 3194866221, 3190525733, 3199294064, 3196193870,
3199463310, 3196699841, 3202505541, 3198385079, 3198841009, 3172321174, 3196908579, 3198066250,
3200562002, 1029039458, 3170488326, 3199063454, 3187399720, 3201782278, 3161592482, 3196159509,
1008079504, 3198130902, 3173718175, 3188626816, 1004013736, 3187779319, 3190829947, 3196738791,
3189437767, 3206028153, 3201468674, 3199812335, 3211043262, 3204331987, 3204601631, 3198182051,
3201707061, 3204439094, 3201442752, 3192164362, 3204467515, 3206090076, 3198740671, 1046161400,
1045564701, 1026276283, 3190402442, 1018197843, 3174632526, 3193869603, 3184000161, 3196683500,
3185404950, 1039001050, 3167076693, 3173466538, 1038680372, 3187921736, 1036676703, 1045938084,
1045468858, 1048130775, 1039122045, 1043784999, 1041528726, 1041340713, 1046668346, 1041075353,
1043825556, 1049114319, 1047971032, 1032753709, 1029313411, 1021024999, 1033845186, 1049189557,
1056089301, 1044848926, 1041702435, 1051597150, 1050162489, 1051415908, 1048625733, 1049561815,
1051443101, 1049143972, 1054139670, 3138858509, 3154556626, 3188469329, 1033956264, 1022012934,
3163202846, 1016265402, 1027188642, 998388144, 3180865784, 3174574579, 1020684772, 3190393756,
3167259554, 3187329222, 3169705938, 1049869081, 1019289287, 1039851497, 1043585296, 1040284624,
3165753304, 3178708555, 1020028387, 1030497791, 3179713020, 3185570936, 3165444715, 3172774915,
3194711444, 3170019297, 3185565280, 1035067722, 1044192046, 1033560582, 1047646454, 1044225917,
1050325943, 1051781471, 1046614709, 1047472258, 1049488996, 1047448175, 1046005850, 1054123539,
1051552878, 3186433140, 1051908342, 1045315252, 1045900478, 1042618624, 1035767247, 1037349445,
1035625772, 1038703266, 3164920472, 1044664539, 1032962103, 1040455550, 1045053896, 1047505183,
1028626938, 1055238670, 1051567784, 1053226593, 1052511397, 1045555688, 1049611594, 1052122819,
1050461323, 1050747069, 1053543742, 1053701710, 1053314115, 1055454149, 1045603921, 3185700550,
1034118762, 1027765029, 1046001850, 1049282518, 1054410027, 1053263099, 1053190200, 1057085518,
1052260264, 1051294782, 1054363497, 1055658395, 1057376650, 1050397602, 1028055967, 3204779168,
1051165283, 3199060034, 1015434586, 3196551670, 3190132881, 3189400146, 3201557818, 1040310059,
3194891954, 3198020784, 1042232259, 3181103636, 3205506871, 3146463807, 3192915333, 3194937428,
3192271919, 3179929049, 3186448911, 3186279824, 3196884664, 1038624074, 3198972795, 3190574441,
3192791220, 1034949164, 3204879704, 1035713159, 3178805024, 3133200509, 1043005022, 1046042573,
3180108603, 1036066567, 1043876296, 1040412273, 992157139, 1044931277, 1033801378, 1001993338,
1051125452, 980588432, 1047165106, 1057725852, 3177620055, 1046745785, 3197840192, 1046115287,
3187051345, 1021989603, 3207838666, 1050298803, 3174591865, 3205121642, 3185729240, 1019092800,
3199477566, 3196132125, 3187210762, 3173990450, 3191146073, 3189666804, 1038903322, 3190308133,
3179104991, 3174745173, 3155812486, 3196784355, 3162974800, 3173762762, 1032730548, 3204351099,
1048602922, 3190191614, 1043808995, 3173691608, 1042183865, 1044401976, 1035975904, 3136504981,
1036386957, 1022102768, 1000442227, 1037334864, 3162021683, 1041669038, 3181804227, 1044662075,
3167439520, 1045482859, 1010268806, 3149675267, 1041230354, 1019399719, 1035211372, 995671644,
1049385789, 3193399728, 1030167322, 3113291125, 1048739671, 3198390191, 1044077803, 3197902777,
3196276819, 3198122390, 3191125423, 3126098112, 1016084564, 3188874343, 1035048294, 3193480122,
3193145197, 3164712549, 3188617304, 3193860309, 3196117929, 1036064769, 1051661908, 1032188600,
1045186531, 1054389045, 3175841084, 1050507500, 1045537066, 1043422537, 1038651935, 1033697223,
1048076991, 1052289794, 1043678328, 1051875333, 1051148103, 3182219426, 3191026425, 1051155526,
1014529312, 3197471896, 1048256321, 3182283607, 3181555839, 3166493318, 3191864542, 3185462581,
3148655300, 3195309716, 1043065123, 3198356886, 1037220351, 1041224640, 1038807009, 1049769968,
1035933299, 1039053252, 1034235137, 1030846339, 1035455333, 1032758431, 3183481625, 1041247586,
1025314249, 1015899369, 1048522195, 1040284473, 1032055917, 1044294601, 1037530753, 1024632712,
1052729858, 3162615869, 1037842888, 1051211259, 1005153287, 1043196842, 1050936932, 1017828821,
1044944134, 1049632166, 3195436656, 3200984197, 3196697582, 3212183823, 3198202226, 3203718804,
3209612534, 3199582069, 3207084980, 3209087248, 3204462988, 3201434064, 3204801848, 3201482707,
3204837220, 3198621381, 3187627553, 3195440504, 3204991436, 3193740726, 3206330529, 3199337545,
3198560827, 3201107288, 3199916300, 3193448608, 3201745551, 3192450750, 3196203269, 3200762595,
3192819433, 3197923589, 1050501025, 3190096331, 3198603341, 1032496965, 3200603316, 3190204723,
3190643421, 3203532039, 1025674547, 3196354077, 3199364556, 1034065596, 3202148342, 3203154387,
3197692596, 3209586531, 3207841881, 3197351592, 3209082851, 3201045638, 3208168413, 3210373688,
3189032283, 3213289782, 3211010264, 3189432870, 3211333506, 3208521700, 1032716729, 1050173237,
1048898507, 1051464987, 1046295172, 1049973526, 1049368198, 1046414740, 1044121406, 1047777361,
1048117580, 1052919503, 1043261441, 1045446692, 1028110394, 1033360188, 1042727732, 1045751540,
1056423025, 1045486825, 1048266443, 1050749906, 1042419437, 1052495743, 1034977604, 1048993759,
1051418716, 1043760254, 1052140847, 1019473235, 1001972890, 3188194230, 1030239043, 3176823834,
3187886460, 3169649097, 3175421077, 1023293770, 3188238475, 3162779693, 3182244277, 3188165602,
3187266789, 3188505129, 3158647493, 1049340214, 1036246129, 1045203528, 1046410823, 1043449254,
1042160287, 3172768984, 1015004516, 1043640645, 1040537647, 3184383089, 1046223398, 1028774538,
998725771, 3164426960, 3171524895, 1035360170, 1042227534, 1033992100, 1050334975, 1043073259,
1042674138, 1048807858, 1049048218, 1042115330, 1047576118, 1046729989, 1052142071, 1050487457,
1051491421, 3175920747, 1047604945, 1046070889, 1040853765, 1044564089, 1037023894, 1032866137,
1033981886, 1036121231, 3180634922, 1041130457, 1043426704, 1039041979, 1031952783, 1044234397,
1033005365, 1052567121, 1051354653, 1052900593, 1050031550, 1043388381, 1049033602, 1048503284,
1051047274, 1045013712, 1049188731, 1052923496, 1046377299, 1051520170, 1045920031, 3147280754,
1040203027, 1040178504, 1049771827, 1049299982, 1053689343, 1054889314, 1057068609, 1059017659,
1052815469, 1054388783, 1057544204, 1056136604, 1056430081, 1056237455, 3169737096, 1049973056,
1050399358, 1046807571, 1043600306, 1043358631, 1044801181, 1047240286, 1037783048, 1046674652,
1049479734, 1048773843, 1035072451, 1043313556, 1033684521, 3163759900, 1040143336, 1038231753,
1053475346, 1040323086, 1041911000, 1047091104, 1040247968, 1048738566, 1037459201, 1034193965,
1050918962, 1040227319, 1042141734, 1033020758, 1029229935, 3193842629, 1019700490, 3176917567,
3179431951, 3179178771, 3188805048, 3188362836, 3192324531, 3185084962, 3189019769, 3189894041,
3180724413, 3192685802, 3188355481, 1036228514, 1028421515, 1032123534, 1046014261, 1043465920,
1037814260, 3183988309, 1012572891, 1034057770, 1032584172, 3162695548, 1034781229, 3180237885,
3185382693, 993286166, 3182310819, 1034701037, 1040931252, 1042254767, 1050674764, 1048527338,
1048990504, 1049819508, 1049256551, 1050310939, 1046969642, 1048953125, 1052289122, 1050843332,
1049720731, 1031846553, 1042483255, 1032854077, 1044231991, 1043771010, 1034718409, 1041841208,
1041580632, 1032484616, 1030497807, 1046210822, 1037999566, 1044006432, 1036088836, 1042863688,
1027521358, 1049729157, 1045082474, 1048962873, 1037731815, 1036796590, 1048696336, 1036981464,
1044510972, 1032952177, 1041377669, 1049456077, 1045246971, 1045600846, 1040251117, 1035551108,
1046507324, 1047398059, 1051543372, 1051166886, 1051833353, 1053820519, 1057139990, 1056990300,
1055558368, 1055450437, 1058293270, 1053459194, 1057871613, 1053449162, 1026138942, 3190167889,
3191423136, 3190683684, 3171113677, 3196446282, 3200834728, 3172858666, 3197980465, 3196183840,
3193316845, 3199425640, 3194175025, 3198595565, 1043299162, 1042129328, 3204851658, 1037737646,
3200834962, 3187284228, 3200002512, 3121932675, 3190675541, 3191803152, 3184063066, 1006676693,
3188883558, 3192587960, 1029740715, 3192605891, 1033842321, 1049496923, 1044862670, 1045882303,
1050980333, 1048183766, 1046802477, 1052195702, 1052357963, 1035010380, 1054084234, 1031839003,
1054722260, 1032548184, 1051087954, 998732181, 3202667250, 3195078426, 3199348838, 3188526538,
3204664114, 3179745501, 1035686162, 3208962187, 3196344259, 3193415550, 3193756453, 3207590110,
1040064693, 3203671919, 1042647661, 3194730913, 1040422604, 3191340680, 3188371633, 3188050244,
1033914753, 3201703704, 1033585034, 3192766723, 3171844171, 3196996847, 3182808383, 3183905805,
3193759903, 1015949976, 1030755443, 1036575166, 1038461322, 3182272123, 1040318116, 1042815152,
3190493698, 1043854485, 1015428818, 1041689573, 3148795534, 1037194163, 1041843435, 3173560096,
1017409889, 3196411331, 1047593033, 1000387082, 3169113002, 3181310469, 1042389779, 3191034007,
1030265944, 1037257198, 1023730041, 3141168233, 1024450665, 1040913847, 3171416337, 1046292303,
1033658642, 1023981880, 3184023859, 3193383397, 3175681605, 3189042250, 3201471034, 3184055630,
3197183239, 3187873815, 3199793398, 3163396373, 3201487995, 3183595323, 3203137822, 3202383670,
1048033567, 3204275934, 3190682401, 3198087147, 3191764083, 3205411923, 3187739479, 3181333612,
3195330661, 3205379335, 1043938329, 3201181611, 3180246764, 3187712199, 1039035122, 3203581012,
1006868833, 3196322688, 3166586407, 3202467903, 3171053354, 3196180438, 3189666994, 3181444776,
3168684324, 3180274502, 3196087082, 3159641575, 3187684872, 1050917058, 1046156752, 1047837667,
1045866057, 1046736654, 1050668130, 1042330045, 1041931608, 1051368716, 1043094894, 1052422369,
1036165861, 1051563601, 3196503342, 3200849562, 1051798261, 3205020948, 3183357029, 3197685524,
1042759053, 3210945082, 3195522268, 1039501385, 3205953021, 3191008998, 3200598810, 3173281656,
3205181114, 3181542370, 1040771994, 1023700762, 3195749284, 1024097870, 3184333535, 3167500355,
3196759833, 1036062220, 3191504221, 3145556754, 3186025936, 1043022611, 3196756625, 3115379818,
3171226787, 1037457982, 1045898466, 3164855577, 1043164619, 1035451364, 1008430291, 1038878743,
1042511315, 3180005580, 1049555390, 1033331682, 1041133336, 1015265610, 1049987107, 3157669850,
1040793024, 1049299024, 3185165484, 1041199497, 978290741, 1041483279, 3187071413, 1045552314,
3175735214, 1034995668, 1041600615, 1048301256, 1016619073, 1032517731, 1040238546, 3189845619,
3189916697, 3196039522, 3189865147, 3192920927, 3191402493, 3175012595, 3181820255, 3198587732,
3180345726, 3197576417, 3188589283, 3200615573, 3179210314, 3197256450, 1042155692, 3189309723,
1032363984, 1018500878, 3193882249, 3194285598, 1052854574, 1049265288, 1051254334, 1045361756,
3204793168, 1050610659, 1049784114, 1049691483, 3210713230, 3207200828, 1037038493, 3205761095,
1037409618, 3201944327, 3201961443, 3204711049, 1049744176, 1046308492, 3204460996, 1042569851,
1052205389, 1016513416, 1040316657, 996501061, 1034323772, 1050639436, 3199320743, 1039531669,
1042829232, 1111117364, 2149990248, 777591337, 3358533396, 3254321102, 2983108973, 3065035952,
1222876594, 2827844265, 2291229330, 1837324924, 3094267265, 2378335676, 1400335952, 1197948730,
2863343299, 1706984858, 1683776622, 2772465771, 2141747833, 2173928653, 1229814389, 2777105781,
2611072195, 1953920086, 2254928516, 2807953247, 2596388233, 1956814937, 2156175248, 1704914551,
1637242449, 1635413117, 2405796988, 2845998491, 2644298163, 3368466879, 3452747959, 2593239250,
2525661577, 2038135166, 2373419162, 3366294705, 3184236681, 3120353203, 2695807939, 2628035258,
2526973079, 2342297744, 1890549905, 2440614010, 3549607601, 2932452563, 2694226108, 3283003903,
3587691493, 3118590155, 2308151726, 2206963355, 2442235522, 2508289405, 1701341915, 2505725806,
2576338523, 2136572829, 3510272401, 1196400051, 3048597937, 3890472158, 2474210205, 1016379025,
1851478891, 3831259980, 2189339040, 2408547247, 3254352722, 1689958305, 3247155865, 2558621669,
2457832845, 1960050541, 2260430478, 2808391346, 2710414272, 3864011039, 2233036145, 2680141954,
2796530302, 2843506307, 1500088452, 1097880914, 2003587659, 1230789455, 2186966618, 2373139350,
1903005561, 3804199065, 3083445445, 4293654218, 2161372917, 2189918605, 2256568700, 1884969835,
2609805423, 3547107743, 2359854972, 2630136968, 2341179604, 2911732629, 2124650634, 2493154701,
1869323172, 3062675574, 2141958543, 1639093670, 2462673249, 2491267744, 2611999187, 2139738040,
2039047534, 1785363298, 1952270685, 2210295398, 1531199818, 2491180142, 1431398471, 2171765334,
2142403448, 1836483208, 1887408777, 2558833307, 2341107604, 2508425872, 2039384451, 2271909750,
2443263102, 2108268918, 1956811398, 2357426045, 2039780731, 2123204233, 2373086867, 1501915481,
2138283921, 2358215340, 2054849178, 2442959465, 2460003221, 2526121119, 2660342165, 1972741495,
2139267980, 2492364146, 1703411550, 2070639970, 2778770052, 1819186264, 1550218879, 2306443389,
2692260787, 2139392879, 1940758429, 811109762, 1836752673, 1079864206, 2828180887, 2593948840,
2991362161, 2492965040, 2526581905, 1900308591, 2358482852, 2661706620, 2275702945, 2357891996,
2661335393, 2156162721, 2862125706, 2289870275, 2322495618, 1649315495, 167788401, 2153997177,
1078091104, 2524599454, 2157689946, 3582033098, 2744295573, 186917543, 3045219351, 1702053480,
456610604, 3234329290, 3900347517, 2748226787, 1622856910, 1249784392, 2358620269, 2105529774,
3819073186, 3249975234, 2393429409, 3619001254, 1919947462, 3461437845, 1275033977, 1167691412,
1400936112, 2631236758, 2412367272, 3047141747, 1402456769, 2091277411, 3365041313, 1400082328,
3502086711, 3703500006, 3236479999, 2531035089, 2271234656, 2442229363, 1752993913, 2757845062,
1194350248, 1479298472, 2912033799, 2070584942, 3107700841, 2862410113, 1542675116, 902407013,
1750415902, 503670358, 1854908756, 2442096695, 3700791416, 2324742052, 1904246955, 3352142714,
2646971575, 1654958800, 2946456716, 2539148441, 759705156, 1956423737, 2042436515, 2422761836,
2021740140, 1686396763, 2472174180, 3265368761, 3333996209, 3286093780, 2022423754, 1971017073,
1417042008, 1685093230, 2291912569, 2894645439, 2360971919, 3215431839, 2319871376, 1670014563,
2173868641, 3095557485, 3030739327, 2444861055, 2543751607, 2793975463, 2949904833, 3903444713,
3940789227, 1703321521, 1198019684, 1549233492, 1632325223, 2927886197, 2508892836, 2624632478,
2458876549, 1346078079, 1868173568, 792088922, 537990706, 1838303526, 1851148686, 2391047054,
2340389258, 1412522829, 2085578849, 2188789642, 1265132169, 1701278596, 2358141547, 2359400074,
1700115360, 1533632860, 1634956650, 1636724550, 1768978530, 2456309041, 1215920216, 1902923086,
1565288244, 1564944669, 1718837317, 1180334695, 1331834412, 1433764687, 1564503915, 2355516547,
2877127762, 2745215412, 3031407008, 2947916194, 1163820900, 1399155555, 2119200132, 3162135398,
2259844457, 1685754493, 2542308525, 2173346178, 1784111940, 2138928259, 1719309403, 1500563332,
2508357027, 2308335240, 2525007773, 3565118831, 2912126604, 2630920594, 2108215220, 1769175172,
1903389298, 1532846687, 4285034327, 1635683442, 2372627610, 3228469174, 2811086481, 2965727397,
3501491319, 4141477046, 2966145504, 2372505452, 2272551059, 1700222336, 2377811112, 3413412755,
1989904779, 2562168722, 2238624430, 2307749759, 1719115883, 2677633629, 2122225337, 2895957630,
2040428942, 2173801892, 1941206176, 2293603442, 3216179111, 1787938189, 2325375371, 1886938210,
2119656039, 2594463613, 2275706022, 2060298141, 2490334888, 630882969, 1311375411, 1232238713,
993998919, 2505132868, 925523786, 1883662651, 1935105142, 678907262, 1331655537, 2220980106,
1634108564, 1919385177, 2422890082, 2845476236, 2208738956, 2255835777, 2475583048, 2407352175,
1837260903, 1717577567, 1870098066, 1601136456, 846012779, 588318279, 1767718457, 1180119623,
1614612821, 2477631107, 1115383905, 759452742, 3416796011, 3504144315, 3083321054, 2209067432,
1751679634, 1719493991, 2105636486, 2793573747, 2927128658, 1583984752, 2356101233, 2457166144,
1786411375, 2037089166, 2173668453, 2454162574, 2288702313, 896160361, 2319018314, 2342742384,
2425864632, 2493481126, 1584680582, 2022732671, 2474743171, 2089911170, 1988727199, 1268753554,
1467264624, 2710288209, 3637497735, 2506132184, 1949973209, 3566796462, 3970942906, 1656789670,
1166126516, 944326451, 3293797983, 901094506, 2862400673, 2229712601, 1844100510, 3218442156,
1451327628, 1635415407, 2109331564, 2496004258, 3671826044, 3654458239, 3210432655, 2354656570,
2176683133, 3250364823, 3612320676, 694325381, 2003591995, 2706264634, 1499211951, 861548880,
1531192931, 1261254685, 3569398709, 3151614091, 3300514766, 3116874699, 3855797174, 3228878027,
2327294314, 1089271502, 3364732262, 2377019827, 2604061524, 2309391019, 2610351581, 2445140088,
3718948818, 2204193740, 2407774876, 2893252220, 3017374804, 4290299352, 3439119571, 3598823641,
3117336275, 3620251838, 2646847915, 2629740961, 2878656717, 1819768949, 2578809745, 1707053952,
664174746, 487325741, 760885315, 1279933007, 2996005182, 2088024438, 3097334965, 3030826897,
1065372625, 1133548844, 1748926079, 2139328417, 2692724361, 2846331527, 3720922328, 2614539224,
3677309339, 2057729641, 2324991852, 2340586654, 2054773605, 2406175870, 2640477832, 2093250207,
2339795349, 2173997925, 2258733225, 2373281383, 1855358086, 1939246202, 2005700718, 1534167410,
1347833425, 1130318949, 1163480924, 2170640224, 2356765295, 2105503599, 2005166985, 2054122607,
1182107228, 1935832191, 2036881027, 2107280240, 2694424987, 2258140294, 1635812493, 2271707741,
2325965969, 2190377345, 458708857, 977351740, 688923175, 792079145, 2105440588, 2072080771,
1752921975, 1601798784, 2206297088, 1938786670, 2507696259, 2022612873, 2006021278, 1734314363,
2643489681, 2040500876, 1651406425, 2188869762, 1919511170, 1618506349, 1296655711, 1986023761,
1934791552, 1751862630, 1431729757, 1952414308, 1937597287, 1514953336, 1683246179, 1854434640,
2019070042, 2407884648, 1484810613, 2138147968, 2287434121, 2104135310, 1871212434, 2273347976,
4285501818, 2324862358, 1990690691, 2290460286, 2358547115, 202664216, 621427538, 890710548,
2281719571, 2141033373, 2863969720, 2897393336, 2861545646, 2428028053, 3483608242, 2999172776,
2595331240, 3199307168, 3015166907, 3116284350, 3166473348, 2695277738, 3182021837, 3100155093,
2690957191, 2693501329, 2796719511, 1654357951, 2021823860, 2627904409, 2509936304, 1305291913,
2930222277, 2491854493, 2625282459, 1923593134, 1077359941, 642992697, 758725936, 184575782,
1547517526, 2253613667, 1264870491, 2339078749, 1954710625, 2542626953, 1837394070, 1319003013,
2339473272, 1701733024, 2491178865, 2508565144, 2258085249, 2710287539, 1112966826, 1512063053,
522074657, 1077033237, 2289966907, 2675669872, 2190965140, 2860810108, 2373475141, 2545983158,
2713241244, 3772356778, 2154607530, 1698393446, 1417034578, 1618826812, 2643500134, 2074984086,
3551505103, 3115427245, 1314416128, 1538732647, 1433974890, 2207425946, 2125174685, 2844292241,
2561316236, 1795204742, 1248355606, 2808894835, 1670874207, 1415137704, 1482439501, 1098604686,
2176429160, 2293269200, 3265176985, 2795475098, 2746991773, 2678107592, 3197154461, 2832311439,
2728899759, 2947782318, 3133059741, 2445387429, 2358618535, 672609337, 1512439889, 207890728,
2369147188, 3213867453, 2728840079, 2879492521, 1095477668, 1246973495, 1681936743, 2169585988,
2107285306, 2611913103, 2609091737, 2679015560, 2676789651, 2056498826, 2323746486, 77496215,
825433623, 1010186796, 909328980, 2809480526, 2795158417, 3100091827, 3516721593, 2945490326,
3602499001, 3521434557, 3751929072, 753121683, 419439893, 775045944, 1531849792, 3079364431,
2496697562, 1973347978, 2642321331, 640560010, 576069938, 1650806093, 1535203697, 1640872121,
2742803123, 2613072042, 2124727423, 2189133933, 4139494075, 2759041935, 1381329031, 541404433,
1362906426, 1429748777, 2084009323, 2373626259, 2593100193, 2358686598, 2091621790, 1465539671,
1583706204, 1886347898, 975208294, 1363632487, 1935823956, 946229594, 2240895555, 2191888225,
2390983306, 1887403645, 2124250210, 1870566243, 1835953539, 1599108460, 1904251790, 2742060194,
2490533256, 811960975, 1363095601, 1280002383, 1145782846, 1736329302, 1734109795, 1668510046,
2103997315, 1517617249, 1600877909, 2003913305, 1516531857, 3452262745, 3050230728, 3687631796,
3485124796, 3247605169, 3198919588, 2965625026, 3553933556, 3488455591, 3298668501, 3386900417,
1121444523, 2053138312, 1718514047, 2156231292, 2156107905, 2576979157, 3451559576, 3197732814,
2574951854, 2712578788, 3469650659, 2175774899, 2662191000, 3233334209, 3569590192, 2932189900,
2343098844, 2174452335, 2474345851, 2541326462, 1986957694, 2071952761, 2087875199, 2239597415,
1279146752, 994597186, 995314506, 1581011300, 2254015349, 2307685542, 1920107661, 1500542585,
1699104851, 1346648656, 1112095576, 2357881129, 2088986228, 2273866093, 2004582007, 1347845258,
1499752782, 1313368927, 1416781386, 2004314753, 1870237053, 2440464782, 2809296265, 3974676367,
3034044631, 3219968496, 3538808828, 1466729846, 2171362715, 1650950509, 1347116883, 1514950752,
2474345068, 2426119528, 2726913926, 1907078051, 3366226121, 2077145027, 1788913854, 2726201197,
2646515330, 2659885501, 3032376487, 2409982665, 3113932444, 2613536936, 3064319093, 3148848293,
3435626432, 1264616120, 1617652041, 2139587416, 1754302577, 1493124980, 3266606493, 2055952974,
942770025, 2654488926, 2429653944, 2727262856, 1718530920, 2521332559, 1869572497, 2982395019,
2359020923, 3831675295, 1388429980, 3853345485, 2057997418, 663837184, 1329178416, 2672133019,
2210686602, 2439425599, 1436110957, 2237248153, 1467562333, 1783271337, 2352829833, 507061085,
1656697378, 2071754653, 3165563541, 3432497078, 3014483563, 3182796473, 2845743270, 2659362218,
1482271664, 1397761126, 976052517, 1614623286, 1954046781, 2341045138, 3043857568, 2528088937,
3164848518, 3230631632, 2511779257, 2311367643, 1192971871, 879320619, 927683133, 2644597295,
2424998574, 2361438377, 2494993306, 2947061721, 2827385508, 2760146854, 2056292473, 1953075585,
1801416554, 2241429610, 1499626084, 2831427327, 2912991444, 2748104621, 3434459344, 3161544120,
1664705917, 2775807885, 2156959882, 1802470534, 1465475970, 1010910569, 3411826774, 2038477945,
2793114267, 2609870749, 2361099882, 1704755056, 2172754054, 1869896306, 2304166993, 1704104343,
3145826197, 2574557301, 3264116098, 2759949672, 2983825051, 2777467548, 2186236261, 1801604946,
1566390840, 4280958268, 1785490758, 1804433024, 2052623457, 2004834940, 2222097040, 2189126280,
2440661612, 1351709822, 1130246730, 1130194513, 1211847250, 739138121, 1345060934, 875769619,
1194143310, 864310579, 1061902375, 943671629, 927675969, 542131476, 538788109, 573515071,
1429625127, 1515676251, 2135580280, 1633899336, 2052940633, 1616800352, 1735155578, 2038328956,
1952077162, 2839269486, 2119645570, 2725013096, 4285231246, 2295176626, 2761989708, 1604161102,
966568612, 3267982262, 2225164192, 1347116168, 3245959801, 2657584094, 3532534226, 1706116206,
2699781753, 1250918771, 1050030948, 2053276023, 918602396, 914198086, 1898361320, 1866741664,
778275680, 1648073342, 2391638842, 2788266378, 2896942728, 2926406523, 2627297685, 2158414518,
2708508564, 2909497989, 2524941698, 2205649541, 2239069841, 2390390668, 2540801420, 1515998570,
1566665821, 1635676260, 1902737760, 1400857176, 2589749109, 1788577386, 1819446894, 876615474,
992625688, 1293895265, 1901145910, 1231390343, 1851948656, 1900967827, 2590921597, 2376958095,
1904918399, 2342233514, 2441053353, 1735165321, 2440784515, 1735491702, 2155964927, 2809035625,
2207021692, 2391313012, 1249743499, 2141939554, 1398433898, 2002222160, 2423817607, 2593560180,
2559676062, 1837791107, 2676520331, 2425207181, 2007142294, 2390396557, 2558495127, 2626919816,
2106040464, 2578083216, 2358220702, 2191168897, 2393341342, 1550940322, 2609680023, 1834781078,
1687181943, 2022471058, 2289994103, 2207745666, 11769496, 2104785526, 2038461581, 2390787979,
2138083961, 2425919856, 2391572612, 2124258192, 1854112381, 1919186302, 2037154420, 2088340613,
1904572291, 2577176979, 2594207860, 2475263097, 1717803133, 2071298422, 2005502830, 2323027084,
2071490969, 2156299407, 2207742336, 2021094813, 1702917467, 2153674376, 2005760908, 2021748099,
2205124980, 2037937263, 2004123778, 1979665789, 1737061246, 1483829864, 2237367414, 2170718853,
1433098856, 1129205354, 1380020832, 2846591605, 2946477235, 3115751121, 2493300110, 1618776233,
2104186204, 1903711346, 1752848788, 2763242619, 2846612917, 3183319212, 2124066722, 1467123354,
2238617961, 2106619292, 2190176922, 1952082786, 1567981668, 2322754423, 2576310150, 2460917402,
2310643867, 2459206795, 2341011636, 2341242488, 2290315126, 1718583914, 1804363632, 2457436529,
1786020992, 1734768745, 2391313524, 2290124416, 2407762799, 1937016713, 2290256022, 2526188679,
2022207338, 2020243055, 2155711111, 1888518269, 2155181436, 2375125370, 2591846588, 1803588502,
2019004298, 2240511109, 2173013875, 1938199673, 2136703357, 2037088638, 2037476992, 2173467254,
2928182152, 1767476480, 2155047513, 1855028091, 1635546487, 1802851469, 1684236373, 1418168434,
1654559071, 880038190, 2976928192, 75192611, 1613852210, 2474148006, 2352785008, 880696421,
1735030632, 1347906854, 926234289, 1580011651, 2072011858, 2342615406, 2106360925, 2424725858,
2456856203, 2057729147, 2425914512, 680491924, 942351872, 272386370, 1075784532, 223417400,
2289732708, 2172745070, 2292015768, 2610265726, 1801557383, 2288616595, 2123206755, 2579280554,
2141693038, 2055368836, 1704106869, 2036489087, 1933993607, 1586067040, 2205979278, 2359462758,
2893644984, 1871816835, 1819967618, 2321196126, 1938321270, 2390337650, 2391567492, 1011969389,
1145269829, 2323997046, 2474934148, 2593821583, 1903919745, 1718452331, 2566869134, 2088336735,
1768584045, 1853705074, 2002814825, 1854174350, 2070637173, 1836217955, 1531271273, 1817731670,
1835885418, 1719427165, 1380998524, 1615548297, 1802988386, 1112762726, 1513177969, 1635863131,
1617198709, 2036233325, 1550869597, 1653106536, 1584953955, 1735017571, 2322237857, 2289654926,
2155444618, 1818526043, 2172937324, 2155645287, 1787329928, 1869348720, 1098010173, 1148665649,
1313635206, 3335604065, 2932261844, 3114845123, 2997408686, 3650455245, 3232730563, 3101084331,
2879444479, 3655836344, 2813510858, 3167485386, 1120457130, 2053340558, 2558880905, 2257675878,
2509735775, 3029969598, 3197283208, 3298792929, 2591989965, 2190385618, 2881268924, 2611122603,
3368475064, 2831270849, 3703754194, 3570382547, 1938086085, 2708768431, 2072483460, 1720615574,
2760598124, 2122485382, 2676594091, 1955110036, 927681913, 1480077163, 1548242512, 2540127291,
1869904749, 2170515820, 2455537023, 1650360439, 71970048, 1260926013, 1648570958, 1884395568,
1972672891, 2069392758, 1987211647, 3031992940, 2308616065, 2426509711, 2691531403, 1550022497,
1481662574, 1669364825, 4134232422, 1920696147, 2339077758, 2123470965, 1888064142, 2272499073,
2141162872, 2273148287, 2592964984, 2006024310, 2122154631, 2289992831, 2692189323, 2188411008,
1803191189, 2424212098, 2325052307, 1786680201, 2424997243, 2340128124, 2022150764, 1801871991,
2222153081, 2039052897, 2474019987, 2642646396, 2357489284, 2290449762, 2240055403, 2340582794,
1903979392, 1929426571, 1904683390, 1314475352, 1044483653, 2991021142, 3436952475, 2896471235,
2846083495, 2897586346, 3467424449, 3537093822, 3819892156, 4285577177, 1891735724, 4058949567,
3051859857, 2140376362, 2287844469, 3046086063, 2479464615, 2794902639, 2340459195, 3396725189,
2526901393, 2592393647, 2979576224, 2440727990, 2376300652, 2896734613, 3015024300, 3148593599,
2161810079, 2207148628, 1820629361, 2808320918, 1853394335, 2051175227, 1870219117, 2274139258,
3016012905, 2410185614, 2258350715, 2828306350, 1532043376, 1835222294, 2334538587, 1867272248,
2758511294, 2088539050, 1869257847, 1383179632, 1363236976, 2370921837, 1265923928, 2592969026,
1821940347, 3013586096, 3686909375, 2795350881, 2040229548, 2205188980, 2641720451, 1886936832,
2039181460, 1902744431, 1987279791, 3092998801, 2036499098, 2375320456, 2425455008, 2356647313,
1569099900, 1954051435, 2490395244, 1584506484, 2239524255, 2842187113, 1470325370, 1719432537,
1970367889, 1834708810, 1835576928, 2108056430, 2088668568, 1684643688, 2523425654, 1920307807,
2377092483, 2576527989, 2574682761, 2323547290, 2003332214, 4283989105, 3245645450, 2577700237,
2709294219, 2879559284, 1499356190, 1417251931, 1415146332, 2540791913, 2997988319, 3028726678,
2914025632, 1016510371, 1900834320, 1953045363, 459109902, 1133927031, 1044604272, 2122724961,
1380737870, 1744834395, 774586206, 2198613563, 2808887637, 2526395809, 2845610679, 2175177603,
2143455165, 2036883313, 1803310215, 1736806497, 2033138769, 1297424747, 2415935416, 1931540780,
1757513703, 2201366702, 3960144790, 7451984, 2398906593, 1584018595, 1308642221, 2487153475,
2373280234, 1330859195, 3003149514, 1849472584, 1906872750, 2132886965, 3423542948, 257147962,
1543480244, 3346745405, 1023423147, 1635630660, 2094875592, 4151293244, 3329097804, 1521713574,
1975071628, 3814904908, 3848274005, 1892310492, 882795605, 2636013235, 3358261394, 794732382,
2012245681, 867059345, 3710660, 4267028797, 3328486025, 2553571745, 2986475666, 1046724188,
1357339829, 1353462935, 2571075042, 2101018428, 746684145, 2774308270, 2050839654, 2608513905,
820248761, 2450813546, 2283360694, 1061349960, 1711240436, 1503020695, 1442866602, 2469389101,
1218267894, 6501194, 1011708036, 2939926537, 3465139899, 1773323985, 4286869911, 1819226277,
3393746494, 2899755879, 4007692349, 46477823, 1214127959, 1389576518, 1736760831, 137411092,
1424663764, 4259163648, 3063949428, 298340022, 2257280323, 4287679930, 4137826648, 381962183,
1554979893, 1167162935, 2074607499, 2256830053, 3309878399, 3124619724, 1624671488, 2007867337,
1086023072, 986556891, 1255764104, 3905581392, 2785046313, 2942366121, 4287853618, 210129331,
2090798413, 3730287724, 2957508689, 72732548, 2143486161, 4150722403, 3196078125, 817854965,
1970947411, 3849551872, 766776677, 2614774200, 2244268868, 3329145982, 3227726106, 963616429,
2008219753, 3617624641, 4286462585, 182998183, 2108975468, 2461093632, 1174236838, 1005588121,
879032648, 2250709088, 3050805628, 2952816472, 1227059541, 2277181184, 3978962151, 1446378264,
23989941, 693851024, 1331647425, 2591576943, 3330867072, 2434662316, 3017015599, 3015839999,
3660537922, 3080935749, 2234515604, 159229807, 1388531909, 3412166836, 3479531887, 1132169352,
1485963396, 2415897180, 2341820502, 4170597793, 1747209811, 1167275888, 1571195834, 2804706048,
2994048137, 4282560159, 796494437, 2744807375, 1102536364, 1266442358, 427520663, 3683148434,
3042049944, 3563430995, 3677103954, 76133281, 1473773731, 1016280682, 110192578, 3551362407,
3209953153, 1434764287, 4106205274, 543906461, 2400339489, 3011815829, 3192863069, 542478470,
2092433573, 362132874, 1504362403, 4284052855, 2416740432, 1519585536, 793081533, 3295196228,
1818725023, 28410624, 1188719201, 3211149326, 1968088164, 1047930258, 1058077054, 3195213762,
3172068641, 1037083392, 3199290160, 3190810010, 3191101268, 3177867394, 3216281462, 1034079538,
1037628998, 3216993604, 1051294694, 1040306213, 1054331623, 3195193217, 3205042508, 1013177149,
3174890906, 3204078746, 1055382020, 1048493948, 3192172859, 3199930841, 1066843317, 1040417215,
3202514636, 1043437172, 3196864225, 3191710319, 3196627622, 1041420978, 1032051425, 1033969306,
1034689191, 1045201520, 1030816114, 3196743503, 1036266732, 3188901321, 1058093398, 3190885268,
3166849516, 1053422227, 3154349190, 1044440478, 3185250501, 3185433520, 3191817392, 3173354491,
3189560285, 1050689749, 1041869260, 3181591239, 1019383768, 3192930724, 1058101848, 3190464064,
1024318092, 1041742650, 3168562461, 1048195374, 3184696862, 3216057297, 1068482953, 3214881081,
1067315927, 3234987196, 1087503548, 1057921567, 1059576087, 1057527962, 1059869773, 1059935257,
1062565932, 1054567980, 1055934164, 1060113955, 1063546876, 1063286439, 1062820932, 1065353216,
1059717957, 1055044951, 1056698388, 1059235467, 1060375340, 1060677206, 1057916914, 1057652166,
1053917533, 1059083774, 1052269900, 1060184169, 1059124754, 1061477498, 1056532185, 1052272069,
1055281643, 1057635352, 1060379793, 1051204302, 1058416541, 1060006691, 1061419975, 1054937523,
1061235429, 1052790966, 1055892888, 1060132037, 1058809836, 1058539090, 1061701273, 1056931618,
1053633995, 1059829230, 1055759650, 1062913075, 1053071356, 1059480047, 1061441591, 1059342007,
1055999485, 1060575684, 1057885457, 1063821826, 1052438328, 1065353216, 1059979609, 1063429017,
1053774029, 1062372751, 1057072245, 1050815640, 1050033265, 1043018837, 1058087866, 1057225763,
1057472273, 1051448397, 1046388967, 1053507959, 1054771718, 1056329752, 1053123053, 1055555522,
1057584925, 1047416510, 1047729929, 1046796289, 1051578329, 1048401007, 1053878631, 1058587683,
1051487216, 1060015917, 1053785070, 1056318049, 1057975118, 1054732544, 1050208612, 1057288790,
1053033657, 1050682586, 1048891004, 1046460132, 3189681285, 1041024799, 3196711699, 1049163915,
1040619896, 1028321096, 1031040341, 3193175832, 3171861617, 3196079026, 1049402785, 1032310106,
1047353772, 3197765313, 3180313333, 1035898995, 1029101441, 1037491068, 1016311807, 1029377976,
3181481127, 1046606139, 1046980825, 3170404254, 3129182093, 1044579493, 3194416252, 1032688604,
1044922561, 988133882, 1047356562, 3190925225, 1043887229, 3174346728, 1051735017, 3192145061,
3172751232, 1017827586, 1028093246, 1038227108, 1001421494, 1054986195, 3192711542, 990419090,
3195085887, 1041128997, 3192068156, 3184379530, 3188617818, 3173074324, 1041456962, 1009650467,
990787154, 1041447534, 3196348620, 3196943026, 3180609328, 3188344222, 1033624404, 3188267753,
3190436579, 1011796963, 3173869973, 1033920345, 3199742386, 3184478387, 3185633928, 3181073513,
3190901377, 1057583437, 3188456474, 3189327578, 3181075734, 3187278857, 1041613697, 3176336589,
3183609472, 1024654348, 3196639283, 3188975902, 1047228155, 1043238559, 1026972482, 1017758561,
1040265668, 1048281270, 1045654027, 3171579020, 3179324414, 3171683725, 1023724961, 1036536208,
1041774111, 3185681164, 3162958865, 1044762653, 3185853448, 1040950808, 3183031591, 1037163404,
3181097716, 3192944701, 3184692725, 3183998343, 1048008498, 3190456268, 1040353281, 1045661915,
1039646220, 3169876660, 3188798258, 1016365490, 1038780111, 3187706760, 1044572204, 1034158982,
3181052333, 1020570210, 3188436346, 3186692277, 3169791380, 1024201487, 1031101508, 3190939499,
1033361538, 3163140062, 1043798465, 3180771913, 1042875665, 1054349203, 3183265110, 3170239690,
1049288213, 1030572887, 3173707204, 1040251286, 1033934290, 1024237712, 1041888006, 3179315546,
1016084168, 3194920421, 1047469739, 1033404872, 1023265531, 1049500085, 3198488456, 1046243196,
3182480057, 1036598369, 1016299742, 3180404920, 3178300419, 3195842785, 1049630190, 1044212751,
1050209738, 3201718112, 1036951145, 3174397558, 1011283832, 1048922550, 3190459611, 1037349260,
1043032796, 3172570506, 3192970395, 1019381837, 3179074634, 3171671988, 1053123825, 3155715284,
3176653376, 3197451892, 1040528991, 1025842119, 3172699243, 3159077121, 3190454845, 1036579691,
1034102014, 3184608221, 3173236380, 3187247908, 1040835651, 3191247130, 1049566217, 1048694648,
1019362177, 3187510235, 1014081150, 1025985867, 3166942466, 1029963407, 1018500061, 3167145142,
1015247949, 1046534753, 3146050964, 1042003374, 1021866089, 3163759270, 1049638554, 1045233032,
1038264781, 1041385495, 3188168587, 3199635024, 1042193764, 1044473208, 3165704205, 1046415037,
1045263052, 1034938499, 1046903359, 1047791629,
};
uint32_t* get_Spo2WRWeights_addr()
{
return (uint32_t *)(Spo2WRWeights);
}
uint32_t get_Spo2WRWeights_size()
{
return sizeof(Spo2WRWeights) / sizeof(Spo2WRWeights[0]);
}
void get_Spo2WRWeights_version(char* ver, uint8_t len)
{
memcpy(ver, NET_VERSION, len);
}
#endif //#ifndef Goodix_DSP_EXPORTS

View File

@ -0,0 +1,445 @@
#include "icoe_adap.h"
#include "ps_lib_api.h"
#include "gps_uart_read.h"
static icoe_ring_struct icoe_ring_data;
icoe_file_struct icoe_file_info[] =
{
#ifdef ICOE_SUPPORT_FILE_FS
{ICOE_UPGRADE_FILE_BOOTLOADER, ICOE_UPGRADE_FILE_BOOTLOADER_ADDR},
{ICOE_UPGRADE_FILE_FIREWARE, ICOE_UPGRADE_FILE_FIREWARE_ADDR},
#ifdef _ICOE_APFLASH_
{ICOE_UPGRADE_FILE_APFLASH, ICOE_PGL_FILE_APFLASH_PATH},
#endif
#ifdef SUPPORT_RNX_PGLITE
#ifndef RNX_EPH_FILE_ALLONE
{ICOE_PGL_FILE_GPS, ICOE_PGL_FILE_GPS_PATH},
{ICOE_PGL_FILE_BDS, ICOE_PGL_FILE_BDS_PATH},
{ICOE_PGL_FILE_GAL, ICOE_PGL_FILE_GAL_PATH},
{ICOE_PGL_FILE_GLO, ICOE_PGL_FILE_GLO_PATH},
{ICOE_PGL_FILE_QZS, ICOE_PGL_FILE_QZS_PATH},
#else
{ICOE_PGL_FILE_ALLONE, ICOE_PGL_FILE_ALLONE_PATH},
#endif
#endif
#else
{ICOE_UPGRADE_FILE_BOOTLOADER, ICOE_UPGRADE_FILE_BOOTLOADER_ADDR, ICOE_UPGRADE_FILE_BOOTLOADER_SIZE},
{ICOE_UPGRADE_FILE_FIREWARE, ICOE_UPGRADE_FILE_FIREWARE_ADDR, ICOE_UPGRADE_FILE_FIREWARE_SIZE},
#ifdef _ICOE_APFLASH_
{ICOE_UPGRADE_FILE_APFLASH, NULL, 0},
#endif
#ifdef SUPPORT_RNX_PGLITE
#ifndef RNX_EPH_FILE_ALLONE
{ICOE_PGL_FILE_GPS, ICOE_PGL_FILE_GPS_PATH, ICOE_PGL_FILE_GPS_SIZE},
{ICOE_PGL_FILE_BDS, ICOE_PGL_FILE_BDS_PATH, ICOE_PGL_FILE_BDS_SIZE},
{ICOE_PGL_FILE_GAL, ICOE_PGL_FILE_GAL_PATH, ICOE_PGL_FILE_GAL_SIZE},
{ICOE_PGL_FILE_GLO, ICOE_PGL_FILE_GLO_PATH, ICOE_PGL_FILE_GLO_SIZE},
{ICOE_PGL_FILE_QZS, ICOE_PGL_FILE_QZS_PATH, ICOE_PGL_FILE_QZS_SIZE},
#else
{ICOE_PGL_FILE_ALLONE, ICOE_PGL_FILE_ALLONE_PATH, ICOE_PGL_FILE_ALLONE_SIZE},
#endif
#endif
#endif
};
int icoe_adap_ring_write(unsigned char *data, unsigned int len)
{
int i;
if (len > ICOE_RING_BUF_LEN)
{
ICOE_DEBUG_LOG("write input size out of length");
return 0;
}
for (i = 0; i < len; i++)
{
icoe_ring_data.p[icoe_ring_data.tail] = *(data + i);
icoe_ring_data.tail = (icoe_ring_data.tail + 1) % ICOE_RING_BUF_LEN;
}
return i;
}
int icoe_adap_ring_read(unsigned char *data, unsigned int len)
{
int i;
if (len > ICOE_RING_BUF_LEN)
{
ICOE_DEBUG_LOG("read input size out of length");
return 0;
}
for (i = 0; i < len; i++)
{
if (icoe_ring_data.head == icoe_ring_data.tail)
{
break;
}
*(data + i) = icoe_ring_data.p[icoe_ring_data.head];
icoe_ring_data.head = (icoe_ring_data.head + 1) % ICOE_RING_BUF_LEN;
}
return i;
}
void icoe_adap_delay_ms(unsigned int ms)
{
//vTaskDelay(pdMS_TO_TICKS(ms));
osDelay(ms);
}
void icoe_adap_set_reset_or_power_low(void)
{
}
void icoe_adap_set_reset_or_power_high(void)
{
}
int icoe_adap_uart_clear_data(void)
{
#ifdef WIN32
WINComClearBuffer();
#endif
memset(&icoe_ring_data, 0, sizeof(icoe_ring_data));
return 0;
}
int icoe_adap_uart_set_baudrate(unsigned int rate)
{
#ifdef WIN32
WINComSetBaud(rate);
#else
gps_uart_set_baudrate(rate);
#endif
return 0;
}
int icoe_adap_uart_send_char(unsigned char chr)
{
#ifdef WIN32
return WINComWrite(&chr, 1);
#else
return gps_uart_send_byte(chr);
#endif
}
int icoe_adap_uart_send_bytes(unsigned char *str, unsigned int len)
{
#ifdef WIN32
return WINComWrite(str, len);
#else
return gps_uart_send_buf((char *)str,len);
#endif
}
int icoe_adap_uart_get_bytes(unsigned char *str, unsigned int len)
{
int ret = 0;
#ifdef WIN32
ret = WINComRead(str, len);
// ret = icoe_adap_ring_read(str,len);
#endif
return ret;
}
char icoe_adap_uart_get_char(unsigned int ms)
{
unsigned char data = 0;
#ifdef WIN32
unsigned int count = 0;
do
{
if (icoe_adap_uart_get_bytes(&data, 1) > 0)
{
return data;
}
count++;
icoe_adap_delay_ms(1);
} while (count < ms);
#endif
return data;
}
char *icoe_adap_mem_malloc(unsigned int size)
{
char *addr = NULL;
#ifdef WIN32
addr = malloc(size);
#else
addr = malloc(size);
#endif
return addr;
}
void icoe_adap_mem_free(char *addr)
{
if (addr != NULL)
{
#ifdef WIN32
free(addr);
#else
free(addr);
#endif
addr = NULL;
}
}
unsigned char *icoe_adap_get_addr_by_tpye(icoe_upgrede_flile_enum type)
{
unsigned int i;
for (i = 0; i < sizeof(icoe_file_info) / sizeof(icoe_file_struct); i++)
{
if (icoe_file_info[i].type == type)
{
return (unsigned char *)icoe_file_info[i].path;
}
}
return NULL;
}
#if 0
int icoe_adap_read_flash(unsigned char *addr, unsigned int offset, unsigned char *buf, unsigned int size, unsigned char from)
{
if (addr == NULL)
{
ICOE_DEBUG_LOG("error :addr is null \r\n");
return -1;
}
if (from == ICOE_DATA_FROM_RAM)
{
memcpy(buf, (unsigned char *)addr + offset, size);
return size;
}
#ifndef ICOE_SUPPORT_FILE_FS
memcpy(buf, (unsigned char *)addr + offset, size);
#else
#ifdef WIN32
int rlen;
FILE *f = NULL;
f = fopen(addr, "rb");
if (f == NULL)
{
ICOE_DEBUG_LOG(" %s file open error \r\n", addr);
return -1;
}
fseek(f, offset, SEEK_SET);
rlen = fread(buf, size, 1, f);
fclose(f);
if (rlen > 0)
{
size = rlen;
}
else
{
ICOE_DEBUG_LOG("%s read file offset %d read %d error %d\r\n", addr, offset, size, rlen);
return -1;
}
#endif //<WIN32>
#endif
return size;
}
#else
int icoe_adap_read_flash(unsigned char *addr, unsigned int offset, unsigned char *buf, unsigned int size, unsigned char from)
{
if (addr == NULL)
{
ICOE_DEBUG_LOG("error :addr is null \r\n");
return -1;
}
if (from == ICOE_DATA_FROM_RAM)
{
memcpy(buf, (unsigned char *)addr + offset, size);
return size;
}
#ifndef ICOE_SUPPORT_FILE_FS
memcpy(buf, (unsigned char *)addr + offset, size);
#else
#ifdef WIN32
int rlen;
FILE *f = NULL;
f = fopen(addr, "rb");
if (f == NULL)
{
ICOE_DEBUG_LOG(" %s file open error \r\n", addr);
return -1;
}
fseek(f, offset, SEEK_SET);
rlen = fread(buf, size, 1, f);
fclose(f);
if (rlen > 0)
{
size = rlen;
}
else
{
ICOE_DEBUG_LOG("%s read file offset %d read %d error %d\r\n", addr, offset, size, rlen);
return -1;
}
#endif //<WIN32>
#endif
return size;
}
#endif
int ioce_adap_get_file_size(icoe_upgrede_flile_enum type)
{
int size = 0;
#ifndef ICOE_SUPPORT_FILE_FS
for (int i = 0; i < sizeof(icoe_file_info) / sizeof(icoe_file_struct); i++)
{
if (icoe_file_info[i].type == type)
{
size = icoe_file_info[i].size;
break;
}
}
#else
#ifdef WIN32
unsigned char *addr;
addr = icoe_adap_get_addr_by_tpye(type);
FILE *f;
if (addr == NULL)
{
ICOE_DEBUG_LOG("cant find the file \r\n");
return -1;
}
f = fopen(addr, "rb");
if (f == NULL)
{
ICOE_DEBUG_LOG("file open error \r\n");
return -1;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fclose(f);
#endif // <WIN32>
#endif
return size;
}
unsigned char *ioce_adap_get_file_addr(icoe_upgrede_flile_enum type)
{
unsigned char *addr = NULL;
addr = icoe_adap_get_addr_by_tpye(type);
return addr;
}
void ioce_adap_set_file_addr_size(icoe_upgrede_flile_enum type, unsigned char *addr, unsigned int size)
{
int i;
for (i = 0; i < sizeof(icoe_file_info) / sizeof(icoe_file_struct); i++)
{
if (icoe_file_info[i].type == type)
{
icoe_file_info[i].path = (char *)addr;
#ifndef ICOE_SUPPORT_FILE_FS
icoe_file_info[i].size = size;
#endif
return;
}
}
}
#ifdef WIN32
int ioce_adap_save_data_to_file(char *filename, char *data, unsigned int len)
{
int ret = 0;
#ifdef WIN32
FILE *f;
ICOE_DEBUG_LOG("ioce_adap_save_data_to_file len %d \r\n", len);
f = fopen(filename, "wb");
ret = fwrite(data, len, 1, f);
fclose(f);
#endif
return ret;
}
#endif
unsigned int icoe_adap_get_utc_time(void)
{
unsigned int t = 0;
#ifdef WIN32
t = time(NULL);
#else
utc_timer_value_t utc_time = {0};
while(0 == utc_time.UTCtimer1)
{
appGetSystemTimeUtcSync(&utc_time);
ICOE_DEBUG_LOG("utc_time:time1=%d,time2=%d,secs=%d,cms=%d,zone=%d\r\n",utc_time.UTCtimer1,utc_time.UTCtimer2,utc_time.UTCsecs,utc_time.UTCms,utc_time.timeZone);
if (0 == utc_time.UTCtimer1) osDelay(200);
}
t = utc_time.UTCsecs;
#endif
return t;
}
int icoe_adap_get_time(icoe_time_struct *t)
{
#ifdef WIN32
time_t tstem;
struct tm *utcTime;
if (t == NULL)
{
return -1;
}
tstem = time(NULL);
utcTime = gmtime(&tstem);
t->year = utcTime->tm_year + 1900;
t->month = utcTime->tm_mon + 1;
t->day = utcTime->tm_mday;
t->hour = utcTime->tm_hour;
t->min = utcTime->tm_min;
t->sec = utcTime->tm_sec;
#endif
return 0;
}

View File

@ -0,0 +1,247 @@
#ifndef ICOE_ADAP_H
#define ICOE_ADAP_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Windows PC Simulation
//#define WIN32
#ifdef WIN32
#include <time.h>
#include "simulator_read.h"
//PC ComPort
#define ICOE_COM_PORT (16)
#endif
#include "sk_comm.h"
//open debug log bps
#define APP_DEBUG_BAUDRATE (460800)
//sys print log
//#define ICOE_DEBUG_LOG printf
#define ICOE_DEBUG_LOG yak_log
#ifndef WIN32
#define ICOE_ENTRY_LOADMODE_HW
#endif
/*gnss have flash or not */
#define ICOE_ROM_ONLY
/*support ap flash*/
#ifdef ICOE_ROM_ONLY
// #define _ICOE_APFLASH_
#endif
//uart work bps
#define APP_RUNING_BAUDRATE (115200)
//loading bps
#ifdef ICOE_ROM_ONLY
#define FW_DOWNLOAD_BAUDRATE (2000000)
#else
#define FW_DOWNLOAD_BAUDRATE (460800)
#endif
#define ICOE_DATA_FROM_ROM (0)
#define ICOE_DATA_FROM_RAM (1)
/*set debug mode*/
// #define ICOE_SUPPORT_DEBUG
/*write gnss data to file*/
#ifdef WIN32
// #define ICOE_SAVE_LOG
#endif
/*support file system*/
#define ICOE_SUPPORT_FILE_FS
/*Support PGlite */
#define SUPPORT_RNX_PGLITE
#ifdef SUPPORT_RNX_PGLITE
/******************PGlite Test Account*****************************
EndTime : 2024.9.30
Customer_ID: Io5M29BWVS
Customer_Key: v1zNs03SlKb8apnD
Seed_Host: starcourse.rx-networks.cn (in China)
           starcourse.location.io (outside China)
Seed_Filename: f1e1G7C7J7.pgl
URL: starcourse.rx-networks.cn/Io5M29BWVS/f1e1G7C7J7.pgl
*******************************************************************/
#define ICOE_PGLITE_KEY "v1zNs03SlKb8apnD"
/*support all statille ehp in one file*/
#define RNX_EPH_FILE_ALLONE
#endif
#ifndef ICOE_SUPPORT_FILE_FS
/*bootloader*/
#define ICOE_UPGRADE_FILE_BOOTLOADER_ADDR (0)
#define ICOE_UPGRADE_FILE_BOOTLOADER_SIZE (0)
/*firmware*/
#define ICOE_UPGRADE_FILE_FIREWARE_ADDR (0)
#define ICOE_UPGRADE_FILE_FIREWARE_SIZE (0)
#ifdef _ICOE_APFLASH_
#define ICOE_PGL_FILE_APFLASH_PATH (0)
#endif
#ifdef SUPPORT_RNX_PGLITE//Support PGlite
#ifndef RNX_EPH_FILE_ALLONE
/*gps eph*/
#define ICOE_PGL_FILE_GPS_PATH (0)
#define ICOE_PGL_FILE_GPS_SIZE (0)
/*bds eph*/
#define ICOE_PGL_FILE_BDS_PATH (0)
#define ICOE_PGL_FILE_BDS_SIZE (0)
/*gal eph*/
#define ICOE_PGL_FILE_GAL_PATH (0)
#define ICOE_PGL_FILE_GAL_SIZE (0)
/*glo eph*/
#define ICOE_PGL_FILE_GLO_PATH (0)
#define ICOE_PGL_FILE_GLO_SIZE (0)
/*qzs eph*/
#define ICOE_PGL_FILE_QZS_PATH (0)
#define ICOE_PGL_FILE_QZS_SIZE (0)
#else
/*all eph*/
#define ICOE_PGL_FILE_ALLONE_PATH (0)
#define ICOE_PGL_FILE_ALLONE_SIZE (0)
#endif
#endif
#else
#ifdef ICOE_ROM_ONLY
#define ICOE_UPGRADE_FILE_BOOTLOADER_ADDR ("..\\Resource\\CC11_Bootloader_R2.0.0.0Build10295_APFLASH_AUTO.pkg")
#else
#define ICOE_UPGRADE_FILE_BOOTLOADER_ADDR ("..\\Resource\\CC11_Bootloader_R2.0.0.0Build10295_update_460800.pkg")
#endif
#define ICOE_UPGRADE_FILE_FIREWARE_ADDR ("..\\Resource\\CC1165W_Firmware_N1000R3.35.1.1165Build12546_Release.pkg")
#ifdef _ICOE_APFLASH_
#define ICOE_PGL_FILE_APFLASH_PATH ("..\\Resource\\apdata")
#endif
#ifdef SUPPORT_RNX_PGLITE//Support PGlite
#ifndef RNX_EPH_FILE_ALLONE
#define ICOE_PGL_FILE_GPS_PATH ("..\\Resource\\f1e1G3.pgl")
#define ICOE_PGL_FILE_BDS_PATH ("..\\Resource\\f1e1C3.pgl")
#define ICOE_PGL_FILE_GAL_PATH ("..\\Resource\\f1e1E3.pgl")
#define ICOE_PGL_FILE_GLO_PATH ("..\\Resource\\f1e1R3.pgl")
#define ICOE_PGL_FILE_QZS_PATH ("..\\Resource\\f1e1J3.pgl")
#else
#define ICOE_PGL_FILE_ALLONE_PATH ("..\\Resource\\f1e1G7C7J7.pgl")
#endif
#endif
#endif
typedef enum
{
ICOE_UPGRADE_FILE_BOOTLOADER,
ICOE_UPGRADE_FILE_FIREWARE,
#ifdef _ICOE_APFLASH_
ICOE_UPGRADE_FILE_APFLASH,
#endif
#ifdef SUPPORT_RNX_PGLITE//Support PGlite
#ifndef RNX_EPH_FILE_ALLONE
ICOE_PGL_FILE_GPS,
ICOE_PGL_FILE_BDS,
ICOE_PGL_FILE_GAL,
ICOE_PGL_FILE_GLO,
ICOE_PGL_FILE_QZS,
#else
ICOE_PGL_FILE_ALLONE,
#endif
#endif
ICOE_FILE_MAX
}icoe_upgrede_flile_enum;
typedef struct
{
/* data */
icoe_upgrede_flile_enum type;
const char *path;
#ifndef ICOE_SUPPORT_FILE_FS
unsigned int size;
#endif
}icoe_file_struct;
typedef struct
{
/* data */
unsigned short year;
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char min;
unsigned char sec;
}icoe_time_struct;
#define ICOE_RING_BUF_LEN (256)
typedef struct
{
/* data */
unsigned int head;
unsigned int tail;
unsigned char p[ICOE_RING_BUF_LEN];
}icoe_ring_struct;
int icoe_adap_ring_write(unsigned char *data, unsigned int len);
void icoe_adap_delay_ms(unsigned int ms);
void icoe_adap_set_reset_or_power_low(void);
void icoe_adap_set_reset_or_power_high(void);
int icoe_adap_uart_clear_data(void);
int icoe_adap_uart_set_baudrate(unsigned int rate);
int icoe_adap_uart_send_bytes(unsigned char *str,unsigned int len);
int icoe_adap_uart_get_bytes(unsigned char *str,unsigned int len);
char icoe_adap_uart_get_char(unsigned int ms);
int icoe_adap_uart_send_char(unsigned char chr);
char *icoe_adap_mem_malloc(unsigned int size);
void icoe_adap_mem_free(char *addr);
int icoe_adap_read_flash(unsigned char *addr ,unsigned int offset,unsigned char *buf, unsigned int size,unsigned char from);
int ioce_adap_get_file_size(icoe_upgrede_flile_enum type);
unsigned char *ioce_adap_get_file_addr(icoe_upgrede_flile_enum type);
void ioce_adap_set_file_addr_size(icoe_upgrede_flile_enum type,unsigned char *addr, unsigned int size);
#ifdef WIN32
int ioce_adap_save_data_to_file(char *filename,char *data, unsigned int len);
#endif
unsigned int icoe_adap_get_utc_time(void);
int icoe_adap_get_time(icoe_time_struct *t);
#endif

View File

@ -0,0 +1,53 @@
#ifndef __ICOE_GPS_H__
#define __ICOE_GPS_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <string.h>
#include "ec7xx.h"
#include "bsp.h"
#include "lspi.h"
#define GPS_POWER_ON sns_gpio_write(SNS_GpioPortB,SNS_GpioPin14,true)
#define GPS_POWER_OFF sns_gpio_write(SNS_GpioPortB,SNS_GpioPin14,false)
//StarCourse测试账号:
//Customer_ID: TempEvaluation2024Q4
//Customer_Key: kphduKNbQAYJV259
//Seed_Filename: f1e1G7C7J7.pgl
//Seed_Host: starcourse.rx-networks.cn (国内)
// starcourse.location.io (国外)
#define GPS_OFFLINE_EPH_CustomerID "Ice2ASNuV6"
#define GPS_OFFLINE_EPH_CustomerKey "TnEw5XaV6umdszFK"
#define GPS_OFFLINE_EPH_HostDoMain "http://starcourse.rx-networks.cn" //(国内)
#define GPS_OFFLINE_EPH_HostDoMain_Foreign "http://starcourse.location.io" //(国外)
#define GPS_OFFLINE_EPH_Filename_7 "f1e1G7R7C7E7J7.pgl" //七天
#define GPS_OFFLINE_EPH_Filename_3 "f1e1G3C3E3J3.pgl" //三天
//#define GPS_OFFLINE_EPH_URL_F3 "http://starcourse.rx-networks.cn/Ice2ASNuV6/f1e1G3C3J3.pgl" //(国内)
#define GPS_OFFLINE_EPH_URL_F7 "http://starcourse.rx-networks.cn/Ice2ASNuV6/f1e1G7R7C7E7J7.pgl" //(国内)
//#define GPS_OFFLINE_EPH_URL_F3 "http://starcourse.rx-networks.cn/Ice2ASNuV6/f1e1G3C3J3.pgl" //(国内)
#define GPS_OFFLINE_EPH_URL_F3 "http://starcourse.rx-networks.cn/Ice2ASNuV6/f1e1G3C3E3J3.pgl"
//#define GPS_OFFLINE_EPH_URL_F7 "http://starcourse.rx-networks.cn/TempEvaluation2025Q1/f1e1G7C7J7.pgl" //(国内)测试账号4:30号到期
int icoe_load_fw(char *bl_filename,char *fw_filename);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,515 @@
#include "icoe_adap.h"
char* gps_dl_send_buf;
int gps_file_exist;
#define WRITE_BUF_SIZE Gps_DL_Send_Buf_len
int icoe_entry_load_mode_by_hw(void)
{
char c = 0;
int i = 0, cnt = 0;
unsigned char cmd[] = {"M!TM!TM!T"};
icoe_adap_uart_set_baudrate(FW_DOWNLOAD_BAUDRATE); //TODO
while (1)
{
if (i == 0) //reset firebird
{
icoe_adap_set_reset_or_power_low();
icoe_adap_delay_ms(50);
icoe_adap_set_reset_or_power_high(); //TODO: set reset pin high or power on
icoe_adap_delay_ms(22); //TO DO: make sure chip power down
cnt ++;
}
icoe_adap_uart_send_muti(cmd,strlen(cmd)+1); //TODO
c = icoe_adap_uart_get_char(5); //TODO timeout is 5ms
if (c == 'Y')
{
ICOE_DEBUG_LOG("------ Gps bootloader waiting for YC OK,cnt=%d,i=%d;\r\n",cnt,i);
c = icoe_adap_uart_get_char(5);//把c读出来
return 0;
}
if (cnt > 20)
{
ICOE_DEBUG_LOG("------ Gps bootloader waiting for YC Error..\r\n");
return -1;
}
if (i++ > 5)
{
i = 0;
}
}
return -1;
}
int icoe_load_fw(char *bl_filename,char *fw_filename)
{
int ret = 0;
FILE* pBL_File = NULL;
FILE* pFW_File = NULL;
unsigned char baudrate_cmd[] = {"$CFGPRT,,h0,921600,1,35\r\n"};
unsigned char cmd[] = {"2\n"};
uint32_t boot_size = 0;
uint32_t fw_size = 0;
u32 read_size = 0;
uint32_t send_size = 0;
int send_cnt = 0;
int ack_id = 0;
uint8_t succ_flag = 1;
uint8_t retry_num;
uint8_t recv_len;
gps_dl_send_buf = aic_zalloc(Gps_DL_Send_Buf_len+1);
if (NULL == gps_dl_send_buf)
{
yak_log("-----------gps dl send buf zalloc fail");
return -1;
}
//===========================
// tick = xTaskGetTickCount();
if ((NULL == bl_filename)||(NULL == fw_filename))
{
return -1;
}
pBL_File = fopen(bl_filename, "rb");
if (pBL_File == NULL)
{
yak_log("------------ read gps bootloader (%s) fopen error!\n",bl_filename);
gps_file_exist = 0;
fclose(pBL_File);
return -1;
}
else
{
gps_file_exist = 1;
fseek(pBL_File,0,SEEK_END);
boot_size = ftell(pBL_File);
yak_log("------------ read gps bootloader (%s) fopen ok! size = %d\n",bl_filename,boot_size);
}
pFW_File = fopen(fw_filename, "rb");
if (pFW_File == NULL)
{
yak_log("------------ read gps firmware (%s) fopen error!\n",fw_filename);
gps_file_exist = 0;
fclose(pBL_File);
fclose(pFW_File);
return -1;
}
else
{
fseek(pFW_File,0,SEEK_END);
fw_size = ftell(pFW_File);
gps_file_exist = 1;
yak_log("------------ read gps firmware (%s) fopen ok! size = %d\n",fw_filename,fw_size);
}
if(icoe_entry_load_mode_by_hw() < 0)
{
gps_file_exist = 0;
fclose(pBL_File);
fclose(pFW_File);
return -1;
}
//===================================
ICOE_DEBUG_LOG("------------- Gps get YC, ready to download bootloader...\r\n");
fseek(pBL_File,0,SEEK_SET);
fseek(pFW_File,0,SEEK_SET);
send_size = 0;
send_cnt = 0;
succ_flag = 1;
ack_id = XMODEM_ACK;
retry_num = 0;
while (1)
{
//ICOE_DEBUG_LOG("------------- boot_size:%d send_size:%d====\r\n",boot_size,send_size);
if((send_size + WRITE_BUF_SIZE) <= boot_size)
{
if(ack_id == XMODEM_ACK)
{
memset(gps_dl_send_buf,0,WRITE_BUF_SIZE+1);
read_size = fread(gps_dl_send_buf,1,WRITE_BUF_SIZE,pBL_File);
if (0 == read_size)
{
ICOE_DEBUG_LOG("------------- boot loader fail:=1=\r\n");
fclose(pBL_File);
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
//ICOE_DEBUG_LOG("temp_buf[0]:%x %x %x %x %x\r\n",temp_buf[0],temp_buf[1],temp_buf[2],temp_buf[3],temp_buf[4]);
}
send_cnt++;
icoe_xmodem_send_frame(gps_dl_send_buf,send_cnt,WRITE_BUF_SIZE);
ack_id = icoe_adap_uart_get_char(10);
ICOE_DEBUG_LOG("------------- boot loader recv:=%x\r\n",ack_id);
if (ack_id == XMODEM_ACK)
{
send_size += WRITE_BUF_SIZE;
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
succ_flag=0;
return -1;
}
}
else
{
if(ack_id == XMODEM_ACK)
{
memset(gps_dl_send_buf,0,WRITE_BUF_SIZE + 1);
read_size = fread(gps_dl_send_buf,1,WRITE_BUF_SIZE,pBL_File);
if (0 == read_size)
{
ICOE_DEBUG_LOG("------------- boot loader fail:=2=\r\n");
fclose(pBL_File);
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
//ICOE_DEBUG_LOG("temp_buf[0]:%x %x %x %x %x\r\n",temp_buf[0],temp_buf[1],temp_buf[2],temp_buf[3],temp_buf[4]);
}
send_cnt++;
icoe_xmodem_send_frame(gps_dl_send_buf,send_cnt,boot_size-send_size);
ack_id = icoe_adap_uart_get_char(10);
if (ack_id == XMODEM_ACK)
{
send_size+=boot_size-send_size;
ack_id = XMODEM_EOT;
while (ack_id != XMODEM_ACK)
{
if(retry_num++ > 3)
{
ICOE_DEBUG_LOG("------------- boot loader fail:=3=\r\n");
fclose(pBL_File);
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
ack_id = XMODEM_EOT;
icoe_adap_uart_send_char(ack_id);
ICOE_DEBUG_LOG("------------- boot loader eot:=3=\r\n");
ack_id = icoe_adap_uart_get_char(10);
}
break;
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
ICOE_DEBUG_LOG("------------- boot loader fail:=4=\r\n");
fclose(pBL_File);
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
}
}
fclose(pBL_File);
if(succ_flag)
{
ICOE_DEBUG_LOG("------------- boot loader ok:=5=\r\n");
}
else
{
ICOE_DEBUG_LOG("------------- boot loader fail:=6=\r\n");
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
ret = 0;
ICOE_DEBUG_LOG("------------- wait for gps chip to run bootloader\r\n");
succ_flag = 0;
#if 0
do
{
recv_len = icoe_adap_uart_get_string(gps_dl_recv_buf,WRITE_BUF_SIZE);
gps_dl_recv_buf[recv_len] = 0;
if(recv_len > 0)
{
ICOE_DEBUG_LOG("------------- recv(%d):%s\r\n",recv_len,gps_dl_recv_buf);
for(int i = 0;i<recv_len;i++)ICOE_DEBUG_LOG("------------- recv(%d):%x\r\n",recv_len,gps_dl_recv_buf[i]);
if(NULL != strstr(gps_dl_recv_buf,"C"))
{
succ_flag = 1;
gps_dl_recv_buf[0] = 0;
break;
}
}
icoe_adap_delay_ms(2);
ret ++;
}
while(ret < 1000);
#else
do
{
char c = icoe_adap_uart_get_char(5);
//gps_dl_recv_buf[recv_len] = 0;
if ('C' == c)
{
ICOE_DEBUG_LOG("------------- recv=%c\r\n",c);
succ_flag = 1;
//gps_dl_recv_buf[0] = 0;
break;
}
icoe_adap_delay_ms(2);
ret ++;
}
while(ret < 1000);
#endif
if(succ_flag)
{
ICOE_DEBUG_LOG("------------- bootloader run ok.\r\n");
}
else
{
ICOE_DEBUG_LOG("------------- bootloader run fail.\r\n");
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
ICOE_DEBUG_LOG("------------- Download firmware...\r\n");
//icoe_adap_delay_ms(5);
//memcpy(cmd,"2\n",3);
icoe_adap_uart_send_muti(cmd,2);
succ_flag = 0;
recv_len = 0;
#if 0
do
{
recv_len = icoe_adap_uart_get_string(gps_dl_recv_buf,WRITE_BUF_SIZE);
gps_dl_recv_buf[recv_len] = 0;
if(recv_len > 0)
{
ICOE_DEBUG_LOG("------------- recv(%d):%s\r\n",recv_len,gps_dl_recv_buf);
if(NULL != strstr(gps_dl_recv_buf,"2"))
{
succ_flag = 1;
gps_dl_recv_buf[0] = 0;
break;
}
}
icoe_adap_delay_ms(10);
ret ++;
}
while(ret < 3000);
if(succ_flag)
{
ICOE_DEBUG_LOG("------------- find char '2' ok.\r\n");
}
else
{
ICOE_DEBUG_LOG("------------- find char '2' fail.\r\n");
fclose(pFW_File);
gps_file_exist = 0;
return -1;
}
icoe_adap_delay_ms(25);
#endif
icoe_adap_delay_ms(5);
//icoe_adap_uart_send_muti(baudrate_cmd,2);
//icoe_adap_delay_ms(5);
//icoe_adap_uart_set_baudrate(921600);
send_size = 0;
send_cnt = 0;
succ_flag = 1;
ack_id = XMODEM_ACK;
retry_num = 0;
//=================================
while (1)
{
ICOE_DEBUG_LOG("------------- fw_size:%d send_size:%d====\r\n",fw_size,send_size);
if((send_size + WRITE_BUF_SIZE) <= fw_size)
{
if(ack_id == XMODEM_ACK)
{
memset(gps_dl_send_buf,0,WRITE_BUF_SIZE+1);
read_size = fread(gps_dl_send_buf,1,WRITE_BUF_SIZE,pFW_File);
if (0 == read_size)
{
ICOE_DEBUG_LOG("------------- gps firmware fail:=1=\r\n");
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
//ICOE_DEBUG_LOG("temp_buf[0]:%x %x %x %x %x\r\n",temp_buf[0],temp_buf[1],temp_buf[2],temp_buf[3],temp_buf[4]);
}
send_cnt++;
icoe_xmodem_send_frame(gps_dl_send_buf,send_cnt,WRITE_BUF_SIZE);
ack_id = icoe_adap_uart_get_char(10);
if (ack_id == XMODEM_ACK)
{
send_size += WRITE_BUF_SIZE;
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
succ_flag=0;
return -1;
}
}
else
{
if(ack_id == XMODEM_ACK)
{
memset(gps_dl_send_buf,0,WRITE_BUF_SIZE + 1);
read_size = fread(gps_dl_send_buf,1,WRITE_BUF_SIZE,pFW_File);
if (0 == read_size)
{
ICOE_DEBUG_LOG("------------- gps firmware fail:=2=\r\n");
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
//ICOE_DEBUG_LOG("temp_buf[0]:%x %x %x %x %x\r\n",temp_buf[0],temp_buf[1],temp_buf[2],temp_buf[3],temp_buf[4]);
}
send_cnt++;
icoe_xmodem_send_frame(gps_dl_send_buf,send_cnt,fw_size-send_size);
ack_id = icoe_adap_uart_get_char(10);
if (ack_id == XMODEM_ACK)
{
send_size += boot_size-send_size;
ack_id = XMODEM_EOT;
while (ack_id != XMODEM_ACK)
{
if(retry_num++ > 3)
{
ICOE_DEBUG_LOG("------------- gps firmware fail:=3=\r\n");
fclose(pBL_File);
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
ack_id = XMODEM_EOT;
icoe_adap_uart_send_char(ack_id);
ICOE_DEBUG_LOG("------------- gps firmware eot:\r\n");
ack_id = icoe_adap_uart_get_char(10);
}
break;
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
ICOE_DEBUG_LOG("------------- gps firmware fail:=4=\r\n");
fclose(pFW_File);
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
}
}
fclose(pFW_File);
if(succ_flag)
{
ICOE_DEBUG_LOG("------------- gps firmware ok:=5=\r\n");
}
else
{
ICOE_DEBUG_LOG("------------- gps firmware fail:=6=\r\n");
succ_flag = 0;
gps_file_exist = 0;
return -1;
}
//icoe_adap_delay_ms(5000);
//cmd[0] = '5';
//icoe_adap_uart_send_muti(cmd,2);
//icoe_adap_delay_ms(1000);
gps_file_exist = 0;
if (NULL != gps_dl_send_buf) aic_free(gps_dl_send_buf);
//icoe_adap_uart_set_baudrate(APP_RUNING_BAUDRATE); //TODO
icoe_adap_uart_set_baudrate(115200);
return 0;
}

View File

@ -0,0 +1,202 @@
#include <string.h>
#include "icoe_xmodem.h"
#include "icoe_adap.h"
static char xmodem_buff[XMODEM_BLOCKSIZE + 2 + 2 + 1 + 1];
static const unsigned short xmodem_crc16tab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
unsigned short icoe_xmodem_crc16_ccitt(const unsigned char *buf, int len)
{
register int counter;
register unsigned short crc = 0;
for (counter = 0; counter < len; counter++)
crc = (crc << 8) ^ xmodem_crc16tab[((crc >> 8) ^ *(char *)buf++) & 0x00FF];
return crc;
}
void icoe_xmodem_send_frame(char* data, char pack_counter,unsigned int len)
{
unsigned short crc;
// int i = 0;
memset(xmodem_buff, 0x1A, sizeof(xmodem_buff));
xmodem_buff[0] = XMODEM_STX;
xmodem_buff[1] = pack_counter; //package number
xmodem_buff[2] = 0xff - pack_counter; //package number complement
memcpy(&xmodem_buff[3], data, len);
crc = icoe_xmodem_crc16_ccitt((unsigned char*)&xmodem_buff[3], XMODEM_BLOCKSIZE);
xmodem_buff[XMODEM_BLOCKSIZE+3] = (unsigned char)(crc >> 8);
xmodem_buff[XMODEM_BLOCKSIZE+4] = (unsigned char)crc;
//TODO:modify according to your uart driver
icoe_adap_uart_send_muti(xmodem_buff,XMODEM_BLOCKSIZE+3+2);
icoe_adap_delay_ms(5);
}
int icoe_xmodem_send(char *data, unsigned int data_size)
{
int pack_count = 0, complete = 0, retry_num = 0;
int ack_id = 0;
int return_value = 0, send_size = 0;
unsigned int need_send = 0;
ack_id = XMODEM_ACK;
while(!complete)
{
ICOE_DEBUG_LOG("====82:%d====\r\n",ack_id);
switch(ack_id)
{
case XMODEM_ACK:
pack_count ++;
retry_num = 0;
need_send = (data_size - send_size);
ICOE_DEBUG_LOG("====need_send:%d send_size:%d data_size:%d pack_count:%d====\r\n",need_send,send_size,data_size,pack_count);
if (send_size == data_size) //send over
{
ack_id = XMODEM_EOT;
complete = 1;
return_value = 0;
ICOE_DEBUG_LOG("====96====\r\n");
while (ack_id != XMODEM_ACK)
{
if(retry_num++ > 3)
{
ICOE_DEBUG_LOG("====101====\r\n");
return -1;
}
ack_id = XMODEM_EOT;
icoe_adap_uart_send_char(ack_id);
ack_id = icoe_adap_uart_get_char(1000);
}
ICOE_DEBUG_LOG("====109====\r\n");
return return_value;
}
else if(need_send >= XMODEM_BLOCKSIZE)
{
icoe_xmodem_send_frame(data+send_size, pack_count,XMODEM_BLOCKSIZE);
}
else
{
icoe_xmodem_send_frame(data+send_size, pack_count,need_send);
}
ICOE_DEBUG_LOG("====120====\r\n");
ack_id = icoe_adap_uart_get_char(1000);
if (ack_id == XMODEM_ACK)
{
ICOE_DEBUG_LOG("====124 need_send:%d====\r\n",need_send);
if(need_send >= XMODEM_BLOCKSIZE){
send_size += XMODEM_BLOCKSIZE;
}else{
send_size += need_send;
}
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
ICOE_DEBUG_LOG("====137====\r\n");
return -1;
}
ICOE_DEBUG_LOG("====140====\r\n");
break;
case XMODEM_NAK:
ICOE_DEBUG_LOG("====retry_num:%d====\r\n",retry_num);
if (retry_num++ > 3)
{
complete = -2;
}
else
{
if((data_size - send_size) >= XMODEM_BLOCKSIZE){
icoe_xmodem_send_frame(data+send_size, pack_count,XMODEM_BLOCKSIZE);
}else{
icoe_xmodem_send_frame(data+send_size, pack_count,need_send);
}
ack_id = icoe_adap_uart_get_char(1000);
if (ack_id == XMODEM_ACK)
{
if(need_send >= XMODEM_BLOCKSIZE){
send_size += XMODEM_BLOCKSIZE;
}else{
send_size += need_send;
}
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
ICOE_DEBUG_LOG("====172====\r\n");
return -1;
}
}
break;
default:
ICOE_DEBUG_LOG("====178====\r\n");
ack_id = icoe_adap_uart_get_char(1000);
if (ack_id == XMODEM_ACK)
{
send_size += XMODEM_BLOCKSIZE;
}
else if(ack_id == 0)
{
ack_id = XMODEM_NAK;
}
else if (ack_id == XMODEM_CAN)
{
ICOE_DEBUG_LOG("====190====\r\n");
return -1;
}
ICOE_DEBUG_LOG("====192====\r\n");
break;
}
}
ICOE_DEBUG_LOG("====197====\r\n");
return return_value;
}

View File

@ -0,0 +1,15 @@
#ifndef XMODEM_H
#define XMODEM_H
#define XMODEM_ACK 0x06
#define XMODEM_NAK 0x15
#define XMODEM_STX 0x02
#define XMODEM_EOT 0x04
#define XMODEM_CAN 0x18
#define XMODEM_BLOCKSIZE 1024
int icoe_xmodem_send(char *data, unsigned int data_size);
void icoe_xmodem_send_frame(char* data, char pack_counter,unsigned int len);
#endif

View File

@ -0,0 +1,84 @@
/************************************************************************
* Copyright © 2022, ICOE (Shanghai) Technologies Co.,Ltd. All rights reserved. *
* Information in this document is provided in connection with ICOEs products. *
* No license, express or implied, by estoppels or otherwise, to any intellectual property *
* rights is granted by this document. Except as provided in ICOEs Terms and *
* Conditions of Sale for such products, ICOE assumes no liability whatsoever, and *
* ICOE disclaims any express or implied warranty, relating to sale and/or use of *
* ICOE products including liability or warranties relating to fitness for a particular *
* purpose, merchantability, or infringement of any patent, copyright or other *
* intellectual property right. ICOE products are not intended for use in medical, life *
* saving, or life sustaining applications. *
* ICOE (Shanghai) Technologies Co.,Ltd may make changes to specifications and *
* product descriptions at any time, without notice. *
* You may obtain copies of documents which have a document number and are *
* referenced in this document, or other ICOE literature may be obtained by *
* mailing to xiaopingjiang@icoe-tech.com. *
************************************************************************/
#ifndef __ICOE_AP_FLASH_H_
#define __ICOE_AP_FLASH_H_
/*****************************************************************************
* macro definition
*****************************************************************************/
#ifdef _ICOE_APFLASH_
#define EPHEMERIS_MAGIC 0xf0f1f2f3
typedef struct icoe_image_header{
unsigned int magic;
unsigned int load_address;
unsigned int run_address;
unsigned int size;
unsigned int time;
unsigned int cfg;
unsigned int image_num;
unsigned short head_crc;
unsigned short project_name;
} icoe_image_header;
typedef enum {
ICOE_APFLASH_IDLE,
ICOE_APFLASH_SEND_REQ,
ICOE_APFLASH_HEADER_NOT_FOUND,
ICOE_APFLASH_PART_OF_HEADER_FOUND,
ICOE_APFLASH_HEADER_FOUND,
ICOE_APFLASH_RECV_FINISH,
ICOE_APFLASH_STATE_MAX
}apflash_flag_enum;;
typedef struct
{
unsigned int apflash_len;
unsigned int apflash_pos;
apflash_flag_enum apflash_flag;
unsigned char apflash_buf[1024*6];
}apflash_data_struct;
#ifdef __cplusplus
extern "C" {
#endif
//reset apflash data
void icoe_apflash_reset(void);
//send cmd req apflash data
void icoe_apflash_req_data(void);
//rev data from uart
int icoe_apflash_rev_data(unsigned char *data,unsigned int len);
//get apflash size
int icoe_apflash_get_size(void);
//get apflash buffer
unsigned char *icoe_apflash_get_buffer(void);
#ifdef WIN32
//save data to file
void icoe_apflash_save_data(void);
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif //__UNICORE_AP_FLASH_H_

View File

@ -0,0 +1,886 @@
/************************************************************************
* Copyright © 2022, ICOE (Shanghai) Technologies Co.,Ltd. All rights reserved. *
* Information in this document is provided in connection with ICOEs products. *
* No license, express or implied, by estoppels or otherwise, to any intellectual property *
* rights is granted by this document. Except as provided in ICOEs Terms and *
* Conditions of Sale for such products, ICOE assumes no liability whatsoever, and *
* ICOE disclaims any express or implied warranty, relating to sale and/or use of *
* ICOE products including liability or warranties relating to fitness for a particular *
* purpose, merchantability, or infringement of any patent, copyright or other *
* intellectual property right. ICOE products are not intended for use in medical, life *
* saving, or life sustaining applications. *
* ICOE (Shanghai) Technologies Co.,Ltd may make changes to specifications and *
* product descriptions at any time, without notice. *
* You may obtain copies of documents which have a document number and are *
* referenced in this document, or other ICOE literature may be obtained by *
* mailing to xiaopingjiang@icoe-tech.com. *
************************************************************************/
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "icoe_gnss_nmea.h"
#include "icoe_gnss_apflash.h"
GnssCallbacks icoeGnssfun, *icoeGnssCallbacks;
static NmeaReader nmeaReader;
void nmea_gnss_set_callback(gnss_location_callback location_cb,
gnss_sv_status_callback sv_cb,
gnss_nmea_callback nmea)
{
icoeGnssCallbacks = &icoeGnssfun;
icoeGnssCallbacks->gnss_sv_status_cb = sv_cb;
icoeGnssCallbacks->location_cb = location_cb;
icoeGnssCallbacks->nmea_cb = nmea;
}
int gps_update_svstatus(GnssSvInfo *sv_list)
{
if (!icoeGnssCallbacks || icoeGnssCallbacks->gnss_sv_status_cb == NULL)
{
return -1;
}
icoeGnssCallbacks->gnss_sv_status_cb(sv_list);
return 0;
}
void gps_update_location(GpsLocation fix)
{
if (!icoeGnssCallbacks || icoeGnssCallbacks->location_cb == NULL)
{
return;
}
icoeGnssCallbacks->location_cb(&fix);
}
static int nmea_tokenizer_init( NmeaTokenizer* t, const char* p, const char* end )
{
int count = 0;
// the initial '$' is optional
if (p < end && p[0] == '$')
p += 1;
// remove trailing newline
if (end > p && end[-1] == '\n') {
end -= 1;
if (end > p && end[-1] == '\r')
end -= 1;
}
// get rid of checksum at the end of the sentecne
if (end >= p+3 && end[-3] == '*') {
end -= 3;
}
const char *q = NULL;
while (p < end) {
q = p;
q = memchr(p, ',', end-p);
if (q == NULL)
q = end;
if (count < MAX_NMEA_TOKENS) {
t->tokens[count].p = p;
t->tokens[count].end = q;
count += 1;
}
if (q < end)
q += 1;
p = q;
}
if(end[-1] == ',') {
t->tokens[count].p = end;
t->tokens[count].end = end;
count += 1;
}
t->count = count;
return count;
}
static Token nmea_tokenizer_get( NmeaTokenizer* t, int index )
{
Token tok;
static const char* dummy = "";
if (index < 0 || index >= t->count) {
tok.p = tok.end = dummy;
} else
tok = t->tokens[index];
return tok;
}
static int str2int( const char* p, const char* end )
{
int result = 0;
int len = end - p;
int sign = 1;
if(len > 10 || len <= 0) {
return 0;
}
if (*p == '-') {
sign = -1;
p++;
len = end - p;
}
int c;
for ( ; len > 0; len--, p++ )
{
if (p >= end) {
return -1;
}
c = *p - '0';
if ((unsigned)c >= 10) {
return -1;
}
result = result*10 + c;
}
return result*sign;
}
/*
* this function only calculate the milliseconds since Jan 1, 1970
* parameter tm is UTC time
*/
time_t mktime(struct tm *tm)
{
long totalSecs = 0;
long sec1;
long sec2;
U32 leapYearCnt = 0;
U32 yearsNotInLeap = 0;
U32 dayInYear;
int leapYearDaysOfMonthList[] = {
31,
29,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
};
int daysOfMonthList[] = {
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
};
leapYearCnt = (tm->tm_year - 1972) / 4;
yearsNotInLeap = (tm->tm_year - 1972) % 4 + 2; /* 1970 and 1971 is not leap year */
totalSecs = leapYearCnt * 1461 * SECS_IN_DAY; /* seconds in four years */
if(yearsNotInLeap > 2) {
sec1 = 366 * SECS_IN_DAY + (yearsNotInLeap - 1) * 365 * SECS_IN_DAY;
} else {
sec1 = yearsNotInLeap * 365 * SECS_IN_DAY;
}
dayInYear = 0;
if(tm->tm_mon <= 0 || tm->tm_mon > 12) {
ICOE_DEBUG_LOG( "abnormal date!!!");
return 0;
}
if(yearsNotInLeap != 2) {
for(int i = 0; i < tm->tm_mon - 1; i ++ ) {
dayInYear += daysOfMonthList[i];
}
} else {
for(int i = 0; i < tm->tm_mon - 1; i ++ ) {
dayInYear += leapYearDaysOfMonthList[i];
}
}
dayInYear += (tm->tm_mday - 1);
sec2 = dayInYear * SECS_IN_DAY + tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
totalSecs += sec1 + sec2;
return totalSecs;
}
static double str2float( const char* p, const char* end )
{
int len = end - p + 1;
char temp[32];
if (len <= 0) {
return -1.0;
}
if (len >= (int)sizeof(temp))
return 0.;
memcpy(temp, p, len );
temp[len] = 0;
return (double)strtod(temp, NULL);
}
/*****************************************************************/
/*****************************************************************/
/***** *****/
/***** N M E A P A R S E R *****/
/***** *****/
/*****************************************************************/
/*****************************************************************/
void nmea_reader_init()
{
nmeaReader.pos = 0;
nmeaReader.overflow = 0;
nmeaReader.nmea_mode = POS_MODE_GN;
nmeaReader.utc_time.tm_mday = -1;
nmeaReader.utc_time.tm_mon = -1;
nmeaReader.utc_time.tm_year = -1;
nmeaReader.fix.flags = 0;
nmeaReader.sv_status_changed = 0;
nmeaReader.sv_status_commit = 0;
memset(nmeaReader.sv_list, 0, GNSS_MAX_SVS*sizeof(GnssSvInfo));
}
static int nmea_reader_get_timestamp(NmeaReader* r, Token tok, time_t *timestamp)
{
if (tok.p + 6 > tok.end)
return -1;
if (r->utc_time.tm_year < 0) {
return -1;
}
r->utc_time.tm_hour = str2int(tok.p, tok.p+2);
r->utc_time.tm_min = str2int(tok.p+2, tok.p+4);
r->utc_time.tm_sec = (int)str2float(tok.p+4, tok.end);
r->utc_time.tm_isdst = -1;
*timestamp = mktime(&(r->utc_time));
return 0;
}
static int nmea_reader_update_time( NmeaReader* r, Token tok )
{
/*
* to do check time_t size
*/
time_t timestamp = 0;
int ret = nmea_reader_get_timestamp( r, tok, &timestamp);
if (0 == ret) {
r->fix.timestamp = timestamp;
}
return ret;
}
static int nmea_reader_update_cdate( NmeaReader* r, Token tok_d, Token tok_m, Token tok_y )
{
if ( (tok_d.p + 2 > tok_d.end) ||
(tok_m.p + 2 > tok_m.end) ||
(tok_y.p + 4 > tok_y.end) )
return -1;
r->utc_time.tm_mday = str2int(tok_d.p, tok_d.p+2);
r->utc_time.tm_mon = str2int(tok_m.p, tok_m.p+2);
r->utc_time.tm_year = str2int(tok_y.p, tok_y.end+4);
return 0;
}
static int nmea_reader_update_date( NmeaReader* r, Token date, Token mtime )
{
Token tok = date;
int day, mon, year;
/*
* nmea Date INfo length == 6
*/
if (tok.p + 6 != tok.end) {
return -1;
}
/* normal case */
day = str2int(tok.p, tok.p+2);
mon = str2int(tok.p+2, tok.p+4);
year = str2int(tok.p+4, tok.p+6) + 2000;
if ((day|mon|year) < 0) {
return -1;
}
r->utc_time.tm_year = year;
r->utc_time.tm_mon = mon;
r->utc_time.tm_mday = day;
return nmea_reader_update_time( r, mtime );
}
static double convert_from_hhmm( Token tok )
{
double val = str2float(tok.p, tok.end);
//int degrees = (int)(floor(val) / 100);
int degrees = (int)val;
degrees = degrees/100;
double minutes = val - degrees*(double)100.0;
double dcoord = degrees + minutes / (double)60.0;
return dcoord;
}
static int nmea_reader_update_latlong( NmeaReader* r,
Token latitude,
char latitudeHemi,
Token longitude,
char longitudeHemi )
{
double lat, lon;
Token tok;
tok = latitude;
if (tok.p + 6 > tok.end) {
return -1;
}
lat = convert_from_hhmm(tok);
if (latitudeHemi == 'S')
lat = -lat;
tok = longitude;
if (tok.p + 6 > tok.end) {
return -1;
}
lon = convert_from_hhmm(tok);
if (longitudeHemi == 'W')
lon = -lon;
r->fix.latitude = lat;
r->fix.longitude = lon;
r->fix.flags |= GPS_LOCATION_HAS_LAT_LONG;
return 0;
}
static int nmea_reader_update_altitude( NmeaReader* r,
Token altitude,
Token hem )
{
Token tok = altitude;
if (tok.p >= tok.end)
return -1;
r->fix.altitude = str2float(tok.p, tok.end);
r->fix.flags |= GPS_LOCATION_HAS_ALTITUDE;
/*
* Hemisphere height
*/
if(hem.p < hem.end) {
r->fix.altitude += (double)str2float(hem.p, hem.end);
}
return 0;
}
static int nmea_reader_update_accuracy( NmeaReader* r,
Token pdop, Token hdop, Token vdop)
{
Token pdoptok = pdop;
Token hdoptok = hdop;
Token vdoptok = vdop;
if (pdoptok.p >= pdoptok.end || hdoptok.p >= hdoptok.end || vdoptok.p >= vdoptok.end)
return -1;
//tok is cep*cc, we only want cep
r->fix.accuracy = str2float(pdoptok.p, pdoptok.end);
r->fix.hdop = str2float(hdoptok.p, hdoptok.end);
r->fix.vdop = str2float(vdoptok.p, vdoptok.end);
if (r->fix.accuracy == 99.99){
return 0;
}
r->fix.flags |= GPS_LOCATION_HAS_ACCURACY;
return 0;
}
static int nmea_reader_update_bearing( NmeaReader* r,
Token bearing )
{
Token tok = bearing;
if (tok.p >= tok.end)
return -1;
r->fix.bearing = str2float(tok.p, tok.end);
r->fix.flags |= GPS_LOCATION_HAS_BEARING;
return 0;
}
static int nmea_reader_update_speed( NmeaReader* r,
Token speed )
{
Token tok = speed;
if (tok.p >= tok.end)
return -1;
r->fix.speed = str2float(tok.p, tok.end);
r->fix.speed *= 0.514444; // fix for Speed Unit form Knots to Meters per Second
r->fix.flags |= GPS_LOCATION_HAS_SPEED;
return 0;
}
static int nmea_verify_packet(char *buf, int len)
{
char sum = 0, crc;
char *bufend = buf + len;
if(len < NMEA_MINLEN) return -1;
if(buf[0] != '$' || bufend[-3] != '*')
return -1;
buf++;
len -= 4; /* 3 + 1 */
while(len--)
sum ^= buf[len];
crc = (char)strtoul(&bufend[-2], NULL, 16);
return sum != crc;
}
static void nmea_parse_gga(NmeaReader* r,NmeaTokenizer *tzer)
{
if(tzer->count == GGA_TOKEN_COUNT) {
// GPS fix
Token tok_fixstaus = nmea_tokenizer_get(tzer,6);
/*
* fix flag only valid from 0 to 7
*/
if (tok_fixstaus.p[0] > '0' && tok_fixstaus.p[0] < '8') {
Token tok_time = nmea_tokenizer_get(tzer,1);
Token tok_latitude = nmea_tokenizer_get(tzer,2);
Token tok_latitudeHemi = nmea_tokenizer_get(tzer,3);
Token tok_longitude = nmea_tokenizer_get(tzer,4);
Token tok_longitudeHemi = nmea_tokenizer_get(tzer,5);
Token tok_altitude = nmea_tokenizer_get(tzer,9);
Token tok_altHemOffset = nmea_tokenizer_get(tzer,11);
nmea_reader_update_time(r, tok_time);
nmea_reader_update_latlong(r, tok_latitude,
tok_latitudeHemi.p[0],
tok_longitude,
tok_longitudeHemi.p[0]);
nmea_reader_update_altitude(r, tok_altitude, tok_altHemOffset);
if ((r->fix.flags & GPS_LOCATION_HAS_LAT_LONG)
&& (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE)) {
gps_update_location(r->fix);
r->fix.flags = 0;
}
}
}
}
static void nmea_parse_gll(NmeaReader* r,NmeaTokenizer *tzer)
{
Token tok_fixstaus = nmea_tokenizer_get(tzer,6);
if (tok_fixstaus.p[0] == 'A') {
Token tok_latitude = nmea_tokenizer_get(tzer,1);
Token tok_latitudeHemi = nmea_tokenizer_get(tzer,2);
Token tok_longitude = nmea_tokenizer_get(tzer,3);
Token tok_longitudeHemi = nmea_tokenizer_get(tzer,4);
Token tok_time = nmea_tokenizer_get(tzer,5);
nmea_reader_update_time(r, tok_time);
nmea_reader_update_latlong(r, tok_latitude,
tok_latitudeHemi.p[0],
tok_longitude,
tok_longitudeHemi.p[0]);
}
}
static void nmea_parse_gsa(NmeaReader* r,NmeaTokenizer *tzer,int rtype)
{
if(tzer->count == GSA_TOKEN_COUNT)
{
Token tok_fixStatus = nmea_tokenizer_get(tzer, 2);
int i;
Token tok_systemID = nmea_tokenizer_get(tzer, tzer->count-1);
if( tok_systemID.p != tok_systemID.end) {
if(tok_systemID.p[0] == '1' && tok_systemID.p[1] == '*')
rtype = GNSS_CONSTELLATION_GPS;
else if(tok_systemID.p[0] == '3' && tok_systemID.p[1] == '*')
rtype = GNSS_CONSTELLATION_GALILEO;
else if(tok_systemID.p[0] == '4' && tok_systemID.p[1] == '*')
rtype = GNSS_CONSTELLATION_BEIDOU;
else if (tok_systemID.p[0] == '2' && tok_systemID.p[1] == '*')
rtype = GNSS_CONSTELLATION_GLONASS;
}
if (tok_fixStatus.p[0] != '\0' && tok_fixStatus.p[0] != '1') {
Token tok_pdop = nmea_tokenizer_get(tzer, 15);
Token tok_hdop = nmea_tokenizer_get(tzer, 16);
Token tok_vdop = nmea_tokenizer_get(tzer, 17);
nmea_reader_update_accuracy(r, tok_pdop, tok_hdop, tok_vdop);
for (i = 3; i <= 14; ++i) {
Token tok_prn = nmea_tokenizer_get(tzer, i);
int prn = str2int(tok_prn.p, tok_prn.end);
/* available for PRN 1-255 */
// TODO
// check PRN for BD2 satellites not starting from 160, or greater than 192
// check PRN for GLONASS or GALILEO satellites PRN numbering
if(prn > 0 && prn < GNSS_MAX_SVS) {
// BDS maxium sv num :64
if(rtype == GNSS_CONSTELLATION_BEIDOU && prn < BDS_MAX_SVS) {
prn += BDS_SV_OFFSET;
}
else if(rtype == GNSS_CONSTELLATION_GALILEO && prn < GAL_MAX_SVS) {
prn += GAL_SV_OFFSET;
}
else if (rtype == GNSS_CONSTELLATION_GLONASS && prn < GLN_MAX_SVS)
{
prn += GLN_SV_OFFSET;
}
r->sv_list[prn].flags |= GNSS_SV_FLAGS_USED_IN_FIX;
r->sv_list[prn].svid = prn;
/* mark this parameter to identify the GSA is in fixed state */
r->gsa_fixed = 1;
}
} // end for(;;)
} else {
if (r->gsa_fixed == 1) {
for(i = 0; i < GNSS_MAX_SVS; i++) {
r->sv_list[i].flags &= ~GNSS_SV_FLAGS_USED_IN_FIX;
}
r->gsa_fixed = 0;
}
}
}
}
static void nmea_parse_gsv(NmeaReader* r,NmeaTokenizer *tzer,int rtype)
{
Token tok_noSatellites = nmea_tokenizer_get(tzer, 3);
int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end);
Token tok_noSentences = nmea_tokenizer_get(tzer, 1);
Token tok_sentence = nmea_tokenizer_get(tzer, 2);
if (noSatellites > 0 && (tzer->count % 4) == 1) {
int sentence = str2int(tok_sentence.p, tok_sentence.end);
int totalSentences = str2int(tok_noSentences.p, tok_noSentences.end);
static int num_svs;
int i;
int prn;
static int ff = 0; // first found
if (sentence == 1) {
for(i = 0; i < GNSS_MAX_SVS; i++) {
if(r->sv_list[i].constellation == rtype) {
r->sv_list[i].svid = 0;
}
}
num_svs = 0;
ff = 1;
} else {
if(!ff || num_svs != (sentence-1)*4) {
ICOE_DEBUG_LOG( "partial GSV, %s", r->in);
return;
}
}
i = 0;
while (i < (tzer->count/4 - 1) && num_svs < noSatellites)
{
Token tok_prn = nmea_tokenizer_get(tzer, i * 4 + 4);
Token tok_elevation = nmea_tokenizer_get(tzer, i * 4 + 5);
Token tok_azimuth = nmea_tokenizer_get(tzer, i * 4 + 6);
Token tok_snr = nmea_tokenizer_get(tzer, i * 4 + 7);
prn = str2int(tok_prn.p, tok_prn.end);
if(prn >= 0 && prn < GNSS_MAX_SVS)
{
if(rtype == GNSS_CONSTELLATION_BEIDOU) {
// * 124 ~ 187 BDS
if(prn < BDS_MAX_SVS) prn += BDS_SV_OFFSET;
}
else if(rtype == GNSS_CONSTELLATION_GALILEO) {
// * * 88~123 GAL
if(prn < GAL_MAX_SVS) prn += GAL_SV_OFFSET;
}
else if(rtype == GNSS_CONSTELLATION_GLONASS) {
// * * 65~87 GLN
if(prn < GLN_MAX_SVS) prn += GLN_SV_OFFSET;
}
r->sv_list[prn].svid = prn;
r->sv_list[prn].elevation = str2float(tok_elevation.p, tok_elevation.end);
r->sv_list[prn].azimuth = str2float(tok_azimuth.p, tok_azimuth.end);
r->sv_list[prn].c_n0_dbhz = str2float(tok_snr.p, tok_snr.end);
r->sv_list[prn].constellation = rtype;
num_svs++;
}
i++;
}
if (sentence == totalSentences) {
r->sv_status_commit = 1;
num_svs = 0;
ff = 0;
}
}
if(r->sv_status_changed)
{
gps_update_svstatus(r->sv_list);
r->sv_status_changed = 0;
r->sv_status_commit = 0;
}
}
static void nmea_parse_rmc(NmeaReader* r,NmeaTokenizer *tzer)
{
if(tzer->count == RMC_TOKEN_COUNT) {
// SEE ALSO "GSV" COMMENTS
// EPOCH begin, if last epoch not sent out, mark it as changed
if(r->sv_status_commit) {
gps_update_svstatus(r->sv_list);
r->sv_status_commit = 0;
}
Token tok_fixStatus = nmea_tokenizer_get(tzer,2);
if (tok_fixStatus.p[0] == 'A')
{
Token tok_time = nmea_tokenizer_get(tzer,1);
Token tok_latitude = nmea_tokenizer_get(tzer,3);
Token tok_latitudeHemi = nmea_tokenizer_get(tzer,4);
Token tok_longitude = nmea_tokenizer_get(tzer,5);
Token tok_longitudeHemi = nmea_tokenizer_get(tzer,6);
Token tok_speed = nmea_tokenizer_get(tzer,7);
Token tok_bearing = nmea_tokenizer_get(tzer,8);
Token tok_date = nmea_tokenizer_get(tzer,9);
nmea_reader_update_date( r, tok_date, tok_time );
nmea_reader_update_latlong( r, tok_latitude,
tok_latitudeHemi.p[0],
tok_longitude,
tok_longitudeHemi.p[0] );
nmea_reader_update_bearing( r, tok_bearing );
nmea_reader_update_speed( r, tok_speed );
if ((r->fix.flags & GPS_LOCATION_HAS_LAT_LONG)
&& (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE)) {
gps_update_location(r->fix);
r->fix.flags = 0;
}
}
}
}
static void nmea_parse_vtg(NmeaReader* r,NmeaTokenizer *tzer)
{
Token tok_fixStatus = nmea_tokenizer_get(tzer,9);
if (tok_fixStatus.p[0] != '\0' && tok_fixStatus.p[0] != 'N')
{
Token tok_bearing = nmea_tokenizer_get(tzer,1);
Token tok_speed = nmea_tokenizer_get(tzer,5);
nmea_reader_update_bearing( r, tok_bearing );
nmea_reader_update_speed ( r, tok_speed );
}
}
static void nmea_parse_zda(NmeaReader* r,NmeaTokenizer *tzer)
{
Token tok_time;
Token tok_year = nmea_tokenizer_get(tzer,4);
if (tok_year.p[0] != '\0') {
Token tok_day = nmea_tokenizer_get(tzer,2);
Token tok_mon = nmea_tokenizer_get(tzer,3);
nmea_reader_update_cdate( r, tok_day, tok_mon, tok_year );
}
tok_time = nmea_tokenizer_get(tzer,1);
if (tok_time.p[0] != '\0') {
nmea_reader_update_time(r, tok_time);
}
}
static void nmea_reader_parse(NmeaReader* r)
{
/*
* we received a complete sentence in NmeaReader
* now parse it to generate a new GPS fix or SV information ...
*/
NmeaTokenizer tzer[1];
Token tok;
int rtype;
char *pbuf = r->in;
int len = r->pos;
/*
* Nmea sentence will be less than NMEA_MAX_SIZE
*/
if (len < NMEA_MINLEN || len >= NMEA_MAX_SIZE) {
return;
}
// crc check except \r\n
if(nmea_verify_packet(pbuf, len - 2) != 0) {
ICOE_DEBUG_LOG( "crc error: %s\n", pbuf);
return;
}
if (icoeGnssCallbacks && icoeGnssCallbacks->nmea_cb != NULL) {
/*
* to avoid to use U64 for handling milliseconds, here only report seconds which will be valid for more than 10 years from 2024
*/
icoeGnssCallbacks->nmea_cb(r->timemap.timestamp, pbuf, len);
}
nmea_tokenizer_init(tzer, pbuf, pbuf + len);
tok = nmea_tokenizer_get(tzer, 0);
/*
* check first token, such as XXRMC, XXGSA, XXGSV, XXGGA
*/
if (tok.p + 5 > tok.end) {
ICOE_DEBUG_LOG( "short sentences");
return;
}
// check for RNSS type
if (!memcmp(tok.p, "BD", 2) || !memcmp(tok.p, "GB", 2))
{
rtype = GNSS_CONSTELLATION_BEIDOU;
}
else if (!memcmp(tok.p, "GA", 2))
{
rtype = GNSS_CONSTELLATION_GALILEO;
}
else if (!memcmp(tok.p, "GL", 2))
{
rtype = GNSS_CONSTELLATION_GLONASS;
}
else
{
rtype = GNSS_CONSTELLATION_GPS;
}
// ignore first two characters.
tok.p += 2;
if(!memcmp(tok.p, "GGA", 3)){
nmea_parse_gga(r,tzer);
} else if ( !memcmp(tok.p, "GLL", 3) ) {
nmea_parse_gll(r,tzer);
} else if ( !memcmp(tok.p, "GSA", 3) ) {
nmea_parse_gsa(r,tzer,rtype);
} else if ( !memcmp(tok.p, "GSV", 3) ) {
nmea_parse_gsv(r,tzer,rtype);
} else if ( !memcmp(tok.p, "RMC", 3) ) {
nmea_parse_rmc(r,tzer);
} else if ( !memcmp(tok.p, "VTG", 3) ) {
nmea_parse_vtg(r,tzer);
} else if ( !memcmp(tok.p, "ZDA", 3) ) {
nmea_parse_zda(r,tzer);
} else {
tok.p -= 2;
}
}
static void nmea_reader_addc(NmeaReader *reader, char c)
{
if(reader->overflow) {
reader->overflow = (c != '\n');
return;
}
if(reader->pos >= NMEA_MAX_SIZE - 1) {
reader->overflow = 1;
reader->pos = 0;
return;
}
if(reader->pos == 0 && c != '$' ) {
return;
}
reader->in[reader->pos++] = c;
if(c == '\n') {
/*
* to do
* exclude $NOTICE
*/
reader->in[reader->pos] = '\0';
nmea_reader_parse(reader);
reader->pos = 0;
memset(reader->in, 0x0, NMEA_MAX_SIZE);
}
}
void icoe_gps_nmea_parse(unsigned char *buf, unsigned int len)
{
NmeaReader *reader = &nmeaReader;
if(len <= 0 || buf == NULL) {
return;
}
#ifdef _ICOE_APFLASH_
if(icoe_apflash_rev_data(buf,len) >= 0 ){
return ;
}
#endif
for(int bufIndex = 0; bufIndex < len; bufIndex++) {
nmea_reader_addc(reader, buf[bufIndex]);
}
}

View File

@ -0,0 +1,121 @@
/************************************************************************
* Copyright © 2022, ICOE (Shanghai) Technologies Co.,Ltd. All rights reserved. *
* Information in this document is provided in connection with ICOEs products. *
* No license, express or implied, by estoppels or otherwise, to any intellectual property *
* rights is granted by this document. Except as provided in ICOEs Terms and *
* Conditions of Sale for such products, ICOE assumes no liability whatsoever, and *
* ICOE disclaims any express or implied warranty, relating to sale and/or use of *
* ICOE products including liability or warranties relating to fitness for a particular *
* purpose, merchantability, or infringement of any patent, copyright or other *
* intellectual property right. ICOE products are not intended for use in medical, life *
* saving, or life sustaining applications. *
* ICOE (Shanghai) Technologies Co.,Ltd may make changes to specifications and *
* product descriptions at any time, without notice. *
* You may obtain copies of documents which have a document number and are *
* referenced in this document, or other ICOE literature may be obtained by *
* mailing to xiaopingjiang@icoe-tech.com. *
************************************************************************/
#ifndef _GPS_NMEA_H_
#define _GPS_NMEA_H_
#include "../adaptation/icoe_adap.h"
#include "icoe_gnss_types.h"
#define GGA_TOKEN_COUNT (15)
#define RMC_TOKEN_COUNT (14)
#define GSA_TOKEN_COUNT (19)
#define MAX_NMEA_TOKENS (32)
#define NMEA_MINLEN (12)
#define SECS_IN_DAY (24*60*60)
enum{
NMEA_GGA = 0x0001,
NMEA_GLL = 0x0002,
NMEA_GSA = 0x0004,
NMEA_GSV = 0x0008,
NMEA_RMC = 0x0010,
NMEA_VTG = 0x0020,
NMEA_ZDA = 0x0040,
NAV_POS = 0x0080,
NAV_VEL = 0x0100,
NAV_TIME = 0x0200,
NAV_ACC = 0x0400,
};
enum {
GNSS_SV_FLAGS_NONE = 0,
GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = 1, // (1 << 0)
GNSS_SV_FLAGS_HAS_ALMANAC_DATA = 2, // (1 << 1)
GNSS_SV_FLAGS_USED_IN_FIX = 4, // (1 << 2)
GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = 8, // (1 << 3)
};
enum {
GPS_LOCATION_HAS_LAT_LONG = 1, // 0x0001
GPS_LOCATION_HAS_ALTITUDE = 2, // 0x0002
GPS_LOCATION_HAS_SPEED = 4, // 0x0004
GPS_LOCATION_HAS_BEARING = 8, // 0x0008
GPS_LOCATION_HAS_HORIZONTAL_ACCURACY = 16, // 0x0010
GPS_LOCATION_HAS_VERTICAL_ACCURACY = 32, // 0x0020
GPS_LOCATION_HAS_SPEED_ACCURACY = 64, // 0x0040
GPS_LOCATION_HAS_BEARING_ACCURACY = 128, // 0x0080
GPS_LOCATION_HAS_DATE_TIME = 256,
};
#define GPS_LOCATION_HAS_ACCURACY GPS_LOCATION_HAS_HORIZONTAL_ACCURACY
/* commands sent to the gps thread */
enum {
POS_MODE_GPS = 1,
POS_MODE_BD = 2,
POS_MODE_GAL = 3,
POS_MODE_GLO = 4,
POS_MODE_GN = 5,
};
typedef struct
{
int valid;
double systime;
GpsUtcTime timestamp;
} UmTimemap_t;
typedef struct {
int pos;
int overflow;
struct tm utc_time;
GpsLocation fix;
GnssSvInfo sv_list[GNSS_MAX_SVS];
int sv_status_changed;
int sv_status_commit;
char in[NMEA_MAX_SIZE];
int gsa_fixed;
UmTimemap_t timemap;
int nmea_mode;
} NmeaReader;
typedef struct {
const char* p;
const char* end;
} Token;
typedef struct {
int count;
Token tokens[MAX_NMEA_TOKENS];
} NmeaTokenizer;
//init data
void nmea_reader_init();
//get data from uart
void icoe_gps_nmea_parse(unsigned char *buf, unsigned int len);
//set parse callback
void nmea_gnss_set_callback(gnss_location_callback location_cb,
gnss_sv_status_callback sv_cb,
gnss_nmea_callback nmea
);
#endif /* _GPS_NMEA_H_ */

View File

@ -0,0 +1,253 @@
/************************************************************************
* Copyright © 2022, ICOE (Shanghai) Technologies Co.,Ltd. All rights reserved. *
* Information in this document is provided in connection with ICOEs products. *
* No license, express or implied, by estoppels or otherwise, to any intellectual property *
* rights is granted by this document. Except as provided in ICOEs Terms and *
* Conditions of Sale for such products, ICOE assumes no liability whatsoever, and *
* ICOE disclaims any express or implied warranty, relating to sale and/or use of *
* ICOE products including liability or warranties relating to fitness for a particular *
* purpose, merchantability, or infringement of any patent, copyright or other *
* intellectual property right. ICOE products are not intended for use in medical, life *
* saving, or life sustaining applications. *
* ICOE (Shanghai) Technologies Co.,Ltd may make changes to specifications and *
* product descriptions at any time, without notice. *
* You may obtain copies of documents which have a document number and are *
* referenced in this document, or other ICOE literature may be obtained by *
* mailing to xiaopingjiang@icoe-tech.com. *
************************************************************************/
#ifndef _GPS_TYPES_H_
#define _GPS_TYPES_H_
#include <stdio.h>
#include <stdint.h>
#include <time.h>
typedef char S8; /* Signed 8 bits integer */
typedef unsigned char U8; /* Unsigned 8 bits integer */
typedef signed short S16; /* Signed 16 bits integer */
typedef unsigned short U16; /* Unsigned 16 bits integer */
typedef signed int S32; /* Signed 32 bits integer */
typedef unsigned int U32; /* Unsigned 32 bits integer */
typedef signed long long S64; /* Signed 64 bits integer */
typedef unsigned long long U64; /* Unsigned 64 bits integer */
#define HAL_GNSS_RING_BUFF_SIZE (4096)
#define HAL_GNSS_RX_BUF_SIZE (2048)
#define GPS_NMEA_STRING_MAXLEN 1024
#define MAX_CMD_LEN 256
#define MAX_BUFFER_NUM 2
#define MAX_OFFLINE_EPH_SIZE_PER_SYS (4096)
#define GPS_MAX_SVS 64 // gps + SBAS`
#define GLN_MAX_SVS 24
#define GAL_MAX_SVS 36
#define BDS_MAX_SVS 64
#define GNSS_RESV_SVS 4
#define QZSS_MAX_SVS 12
#define QZSS_ARRAY_START_INDEX (GPS_MAX_SVS + GLN_MAX_SVS + GAL_MAX_SVS + BDS_MAX_SVS + GNSS_RESV_SVS)
#define GNSS_MAX_SVS (GPS_MAX_SVS + GLN_MAX_SVS + GAL_MAX_SVS + BDS_MAX_SVS + GNSS_RESV_SVS + QZSS_MAX_SVS)
#define NMEA_MAX_SIZE 256
#define BDS_SV_OFFSET (GPS_MAX_SVS + GLN_MAX_SVS + GAL_MAX_SVS)
#define GAL_SV_OFFSET (GPS_MAX_SVS + GLN_MAX_SVS)
#define GLN_SV_OFFSET (GPS_MAX_SVS)
#define MAX_SVS (256)
enum {
GNSS_CONSTELLATION_UNKNOWN = 0,
GNSS_CONSTELLATION_GPS = 1,
GNSS_CONSTELLATION_SBAS = 2,
GNSS_CONSTELLATION_GLONASS = 3,
GNSS_CONSTELLATION_QZSS = 4,
GNSS_CONSTELLATION_BEIDOU = 5,
GNSS_CONSTELLATION_GALILEO = 6,
};
enum {
GPS_STATUS_NONE = 0,
GPS_STATUS_SESSION_BEGIN = 1,
GPS_STATUS_SESSION_END = 2,
GPS_STATUS_ENGINE_ON = 3,
GPS_STATUS_ENGINE_OFF = 4,
};
typedef struct {
/** set to sizeof(GpsStatus) */
size_t size;
uint16_t status;
} GpsStatus;
/*
* Milliseconds since January 1, 1970
*/
typedef unsigned long GpsUtcTime;
/*
* Represents a location.
*/
typedef struct {
/*
* set to sizeof(GpsLocation)
*/
size_t size;
/*
* Contains GpsLocationFlags bits.
*/
uint16_t flags;
/*
* Represents latitude in degrees.
*/
double latitude;
/*
* Represents longitude in degrees.
*/
double longitude;
/**
* Represents altitude in meters above the WGS 84 reference ellipsoid.
*/
double altitude;
/** Represents speed in meters per second. */
float speed;
/** Represents heading in degrees. */
float bearing;
/** Represents expected accuracy in meters. */
float accuracy;
float hdop;
float vdop;
/**
* only record seconds, if milliseconds required, need to use U64 data struct
* Timestamp for the location fix.
*/
GpsUtcTime timestamp;
} GpsLocation;
/** * Constellation type of GnssSvInfo */
typedef uint8_t GnssConstellationType;
typedef uint8_t GnssSvFlags;
typedef struct {
/** set to sizeof(GnssSvInfo) */
size_t size;
/**
* Pseudo-random number for the SV, or FCN/OSN number for Glonass. The
* distinction is made by looking at constellation field. Values should be
* in the range of:
*
* - GPS: 1-32
* - SBAS: 120-151, 183-192
* - GLONASS: 1-24, the orbital slot number (OSN), if known. Or, if not:
* 93-106, the frequency channel number (FCN) (-7 to +6) offset by + 100
* i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6 as 106.
* - QZSS: 193-200
* - Galileo: 1-36
* - Beidou: 1-37 */
int16_t svid;
/**
* Defines the constellation of the given SV. Value should be one of those
* GNSS_CONSTELLATION_* constants
*/
GnssConstellationType constellation;
/** * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
* It contains the measured C/N0 value for the signal at the antenna port.
* * This is a mandatory value.
*/
float c_n0_dbhz;
/** Elevation of SV in degrees. */
float elevation;
/** Azimuth of SV in degrees. */
float azimuth;
/** * Contains additional data about the given SV. Value should be one of those * GNSS_SV_FLAGS_* constants */
GnssSvFlags flags;
} GnssSvInfo;
/**
* Represents SV status.
*/
typedef struct {
/** set to sizeof(GnssSvStatus) */
size_t size;
/** Number of GPS SVs currently visible, refers to the SVs stored in sv_list */
int num_svs;
/**
* Pointer to an array of SVs information for all GNSS constellations,
* except GPS, which is reported using sv_list
*/
GnssSvInfo gnss_sv_list[GNSS_MAX_SVS];
} GnssSvStatus;
/**
* Callback with location information. Can only be called from a thread created
* by create_thread_cb.
*/
typedef void (*gnss_location_callback)(GpsLocation* location);
/**
* Callback with status information. Can only be called from a thread created by
* create_thread_cb.
*/
typedef void (* gnss_status_callback)(GpsStatus* status);
/**
* Callback with SV status information.
* Can only be called from a thread created by create_thread_cb.
*/
typedef void (* gnss_sv_status_callback)(GnssSvInfo* sv_info);
/**
* Callback for reporting NMEA sentences. Can only be called from a thread
* created by create_thread_cb.
*/
typedef void (* gnss_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);
typedef struct {
/** set to sizeof(GpsCallbacks) */
size_t size;
gnss_location_callback location_cb;
gnss_status_callback status_cb;
gnss_sv_status_callback gnss_sv_status_cb;
gnss_nmea_callback nmea_cb;
} GnssCallbacks;
typedef float FLT; /* 4 bytes floating point */
typedef double DBL; /* 8 bytes floating point */
#define PARAMETER_NOT_USED(p) ((void)(p))
#ifndef VOID
#define VOID void /* void data type */
#endif
/* Macros */
#ifndef NULL
#define NULL ((VOID *)0) /* NULL pointer */
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
/* maximum & minimum value macros */
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#endif
#endif /* _GPS_TYPES_H_ */

View File

@ -0,0 +1,345 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
* This header documents the core library function calls.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
/**
* \file
* \brief
* Unified application programming interface for Rx Networks predictive system.
*
* \details
* RXN API is a facade for users of the system. It hides the implementation
* details behind a simple API. The goal is to allow users to integrate
* into their target platform easily.
*
*
* \since
* 1.0.0
*/
#ifndef RXN_API_H
#define RXN_API_H
#include "RXN_structs.h"
#include "RXN_constants.h"
#include "RXN_API_calls.h"
/**
* \brief
* Retrieve the API version.
*
* \param version [OUT]
* A memory location to be filled with the current API version.
* This is a null terminated string and is at most
* RXN_CONSTANT_VERSION_STRING_LENGTH (50) characters long.
*
* \return RXN_SUCCESS
* If the version is returned successfully.
*
* \return RXN_FAIL
* If the version cannot be returned.
*
* \details
* <b>Description</b>\n
* This function returns the version of the PG Lite API library.
* The version number will be incremented as new features, enhancements,
* and bug fixes are added to the library. The version number is an important
* identification when reporting and troubleshooting issues.
* Rx Networks' revision numbering convention are described within the
* Integration User's Manuals.
*
* \since
* 1.0.0
* <b>Example Usage</b>
* \code
* // Declare a string to hold version information.
* char version[RXN_CONSTANT_VERSION_STRING_LENGTH];
*
* // Retrieve and output version information.
* RXN_Get_API_Version(&version[0]);
* printf("RXN_Get_API_Version(): %s\n", version);
* \endcode
*
* <b>Output</b>\n
* \code
* RXN_Get_API_Version(): PG Lite API 1.0.0
* \endcode
*/
U16 RXN_Get_API_Version(char version[RXN_CONSTANT_VERSION_STRING_LENGTH]);
/**
* \brief
* Decodes the binary data received from location.io server.
*
* \param data [IN]
* A pointer to the bytes received from location.io server. In order to
* minimize the size of the network transmission, data is sent from the
* server in a packed format, and needs to be decoded on the
* client. After the data is decoded to the internal data structures,
* the library will call the appropriate abstraction functions to save the
* prediction data permanently. The library will also call RT assistance handlers
* to decode RT assistance data. RT assistance handlers need to be implemented by
* the system integrator.
*
* \param size [IN]
* The length of the response byte buffer response points to.
*
* \return RXN_SUCCESS
* If the function completes successfully.
*
* \return RXN_FAIL
* Other errors.
*
* \details
* This function will decode the binary data in packed format received from
* location.io server and save prediction data to flash.
*
* \note
* This method parses the payload of the HTTP response message and not the entire
* HTTP response message. Parsing the HTTP response message and handling of the
* HTTP status codes must be handled by the integrator.
*
* \since
* 1.0.0
*
*/
U16 RXN_Decode(
U08* data,
const U32 size
);
/**
* \brief
* Get EE in RTCM format from the prediction buffer.
*
* \param constel [IN]
* The constellation to get EE for.
*
* \param time [IN]
* The current constellation time.
*
* \param rtcmData [OUT]
* RTCM data for the constellation requested and the time of interest.
*
* \param rtcmLength [OUT]
* The length of RTCM data.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE for the specified constellation and time.
*
* \return RXN_FAIL
* Any errors.
*
* \since
* 1.0.0
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Get the current GPS time (num sec since GPS start at midnight on
* // Jan 6, 1980).
* U32 currGpsTime = RXN_MSL_GetBestGPSTime();
*
* // Convert to other constellation time if the requested constellation is not GPS.
* U32 currBdsTime = MSL_ConvertGPSTimeToBeidouTime(currGpsTime);
*
* // Setup an array to store EE (ensure array elements are clear).
* U08 rtcmData[4096];
* U32 rtcmLength;
* memset(rtcmData, 0, sizeof(rtcmData));
*
* // Get ephemeris in RTCM format.
* if(RXN_Get_Ephemeris_Rtcm(RXN_BDS_CONSTEL, currBdsTime, rtcmData, &rtcmLength)) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject RTCM data into the GNSS receiver.
* }
* \endcode
*
*/
/**
* \brief
* Get EE file information from the stored prediction file.
*
* \param constel [IN]
* The constellation to get EE information for.
*
* \param eeInfo [OUT]
* A RXN_ee_info_t structure with the EE file information.
*
* \returns RXN_SUCCESS
* If the function completes successfully.
*
* \return RXN_FAIL
* Any errors.
*
* \details
* Use this to get the EE file information in the RXN_ee_info_t structure.
*
* \since
* 1.0.0
*
* <b>Example Usage</b>
* \code
* RXN_ee_info_t eeInfo;
* memset(&eeInfo, 0, sizeof(eeInfo));
* RXN_Get_EE_Info(RXN_GPS_CONSTEL, &eeInfo);
* \endcode
*
*/
/**
* \brief
* Set configuration structure
*
* \param config [IN]
* A RXN_config_t structure with time offsets & configuration parameters.
*
* \return RXN_SUCCESS
* If the function completes successfully.
*
* \return RXN_FAIL
* Any errors.
*
* \details
* Use this to set the configuration parameters in the RXN_config_t
* structure after reading the configuration parameters.
*
* \note
* However the library *does* need leap_secs for Glonass and will use nextLeapSecs
* if not zero. The user is therefore advised not zero either of these out when
* calling RXN_Set_Configuration().
*
* The best practice is to call RXN_Get_Configuration() and then alter the ephemeris
* duration parameters. It is not a good idea to declare a config instance, memset
* and then set.
*
* \since
* 1.0.0
*
* \see
* RXN_Get_Configuration()
*
* <b>Example Usage</b>
* \code
* RXN_config_t config;
* RXN_Get_Configuration(&config);
* config.timeOfNextLeapSecInGpsWeek = 0;
* config.timeOfNextLeapSecInGpsTowInSecs = 0;
* config.currentLeapSecs = 18;
* config.nextLeapSecs = 0;
* RXN_Set_Configuration(&config);
* \endcode
*
*/
U16 RXN_Set_Configuration(const RXN_config_t* config);
/**
* \brief
* Get current configuration structure
*
* \param config [OUT]
* A RXN_config_t structure with the current configuration parameters.
*
* \returns RXN_SUCCESS
* If the function completes successfully.
*
* \return RXN_FAIL
* Any errors.
*
* \details
* Use this to get the configuration parameters in the RXN_config_t structure.
*
* \note
* The configuration parameters will be set to default values
* if RXN_Read_Config() abstraction function call fails.
*
* \since
* 1.0.0
*
* \see
* RXN_Get_Configuration()
*
* <b>Example Usage</b>
* \code
* RXN_config_t config;
* RXN_Get_Configuration(&config);
* \endcode
*
*/
U16 RXN_Get_Configuration(RXN_config_t* config);
/**
* \brief
* Provide the customer key to the library.
*
* \param customerKey [IN]
* The pointer to a block of memory containing the customer key.
* The key length, strlen(key) must be 16.
*
* \return RXN_SUCCESS
* If the function completes successfully.
*
* \return RXN_FAIL
* If the function fails.
*
* \attention
* This function must be called with a valid key before
* RXN_Decode() can be used.
*
* \since
* 1.0.0
*
*/
U16 RXN_Set_Customer_Key(
const char* customerKey
);
/**
* \brief
* Returns the maximum number of possible PRNs for this constellation.
*
* \param constel [IN]
* The constellation
* \return The number of PRNs this constellation can hold
*
* \since
* 1.0.0
*/
U08 getMaxNumPrns(RXN_constel_t constel);
#endif // RXN_API_H

View File

@ -0,0 +1,249 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
* Abstraction functions to be implemented in a target by target basis.
*
*************************************************************************
* $LastChangedDate: 2021-03-17 23:33:54 +0000 (Wed, 17 Mar 2021) $
* $Revision: 164561 $
*************************************************************************
*
*/
/**
* \file
* \brief
* Functions to be implemented by the client.
* Contains prototypes which must be implemented by an integrator.
*
* \since
* 1.0.0
*
*/
#ifndef RXN_API_CALLS_H
#define RXN_API_CALLS_H
#include "RXN_structs.h"
#include <stdlib.h>
/**
* \brief
* Called by PG Lite library to read the prediction data.
*
* \param constel
* [IN] which constellation to read.
*
* \param offset
* [IN] byte offset from the beginning of the store.
*
* \param size
* [IN] The size in bytes of the prediction data to be read.
*
* \param p_data
* [OUT] A pointer to the prediction data.
*
* \return RXN_SUCCESS
* If the data is read successfully.
*
* \return RXN_FAIL
* If the data has not been read successfully.
*
* \since
* 1.0.0
*
* \see
* RXN_Write_Prediction().
*/
/**
* \brief
* Called by PG Lite library to write the prediction data.
*
* \param constel
* [IN] constellation for which the prediction data is written.
*
* \param offset
* [IN] byte offset from the beginning of the store.
*
* \param size
* [IN] number of bytes to be written.
*
* \param p_data
* [IN] A pointer to the prediction data.
*
* \return RXN_SUCCESS
* If the value is read successfully.
*
* \return RXN_FAIL
* If the value has not been read successfully.
*
* \since
* 1.0.0
*
* \see
* RXN_Read_Prediction().
*/
U16 RXN_Write_Prediction(
RXN_constel_t constel,
size_t offset,
size_t size,
const void* p_data
);
/**
* \brief
* Called by PG Lite library to write config data such as leap_secs etc as
* described by RXN_config_t in RXN_structs.h.
*
* \param offset
* [IN] byte offset from the beginning of the store.
*
* \param size
* [IN] number of bytes to be read.
*
* \param p_data
* [IN] Pointer to buffer which has the bytes starting from offset upto offset + size.
*
* \return RXN_SUCCESS
* If the value is read successfully.
*
* \return RXN_FAIL
* If the value has not been read successfully.
*
* \since
* 1.0.0
*
* \see
* RXN_Read_Config().
*/
U16 RXN_Write_Config(
size_t offset,
size_t size,
const void* p_data
);
/**
* \brief
* Called by PG Lite library to read config data such as leap_secs as
* described by RXN_config_t in RXN_structs.h.
*
* \param offset
* [IN] byte offset from the beginning of the store.
*
* \param size
* [IN] number of bytes to be read.
*
* \param p_data
* [IN] Pointer to buffer which has the bytes starting from offset upto offset + size.
*
* \return RXN_SUCCESS
* If the value is read successfully.
*
* \return RXN_FAIL
* If the value has not been read successfully.
*
* \since
* 1.0.0
*
* \see
* RXN_Write_Config().
*/
U16 RXN_Read_Config(
size_t offset,
size_t size,
void* p_data
);
/**
* \brief
* Called by PG Lite library to request the allocation of a memory block.
*
* \param size
* [IN] The number of bytes to allocate.
*
* \returns
* Pointer to an available chunk of memory.
*
* \note
* This function defines the memory management interface only.
* It is dependent on a 3rd party memory manager (to be implemented by
* the system integrator).
*
* \since
* 1.0.0
*
* \see
* RXN_Mem_Free().
*/
void* RXN_Mem_Alloc(
size_t size
);
/**
* \brief
* Called by PG Lite library to request the deallocation of a memory block.
*
* \param p
* [IN] The pointer to the allocated memory block to be freed.
*
* \note
* This function defines the memory management interface only.
* It is dependent on a 3rd party memory manager (to be implemented by
* the system integrator).
*
* \since
* 1.0.0
*
* \see
* RXN_Mem_Alloc().
*/
void RXN_Mem_Free(
void* p
);
/**
* \brief
* Called by PG Lite library to decode real-time data.
*
* \param sectionId
* [IN] section data types.
*
* \param payload
* [IN] A pointer to the real-time data.
*
* \param payloadLen
* [IN] number of bytes the data.
*
* \return RXN_SUCCESS
* If the data is decoded successfully.
*
* \return RXN_FAIL
* Any errors.
*
* \since
* 1.0.0
*
*/
U16 RXN_Decode_Rt_Data(
const U08 sectionId,
const U08* payload,
const U32 payloadLen
);
#endif // RXN_API_CALLS_H

View File

@ -0,0 +1,894 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT distribute
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
* This file contains sample code only and the code carries no
* warranty whatsoever.
* Sample code is used at your own risk and may not be functional.
* It is not intended for commercial use.
*
* Example code to illustrate how to integrate Rx Networks PG Lite
* System into a client application.
*
* The emphasis is in trying to explain what goes on in the software,
* and how to the various API functions relate to each other,
* rather than providing a fully optimized implementation.
*
*************************************************************************
* $LastChangedDate: 2021-11-17 19:56:59 +0000 (Wed, 17 Nov 2021) $
* $Revision: 164883 $
*************************************************************************
*/
/**
* \file
* \brief
* The Mobile Suite API for PG Lite.
*
*/
#ifndef RXN_MSL_H
#define RXN_MSL_H
#include "RXN_data_types.h" /* Defines RXN Data Types. */
#include "RXN_constants.h" /* Defines RXN Constants. */
#include "RXN_structs.h" /* Defines RXN Data Structs. */
#ifdef MSL_DECODE_RTCM
#include "RXN_MSL_Ephemeris.h"
#endif
#ifdef RXN_GLONASS_ENABLED
#include "RXN_glonass.h"
#include "RXN_MSL_GlonassEphemeris.h"
#endif
#include <time.h>
/**
* \brief
* Structure to store reference time data.
*/
typedef struct RXN_RefTime
{
U16 weekNum; /*!< Week number in extended format (i.e. > 1024). */
U32 TOWmSec; /*!< Time-Of-Week in mSec. */
U32 TOWnSec; /*!< Time-Of-Week in nSec. Set to 0, if nSec accuracy not supported. */
U32 TAccmSec; /*!< Time-Accuracy in mSec. Set to 0, if accuracy cannot be specified. */
U32 TAccnSec; /*!< Time-Accuracy in nSec. Set to 0, if nSec accuracy cannot be specified. */
} RXN_RefTime_t;
/**
* \brief
* Defines a max length for a string containing Mobile Suite config parameters.
*/
#define RXN_MSL_MAX_CONFIG_PATH_LEN 512
/**
* \brief
* Defines a max length for a string describing the file path.
*/
#define RXN_MSL_MAX_PATH_LEN RXN_MSL_MAX_CONFIG_PATH_LEN
/**
* \brief
* Defines a max length for a string describing the port or file path to open
* or other config params.
*/
#define RXN_MSL_CONFIG_MAX_STR_LEN 256
/*************************
** Error codes follow. **
*************************/
/**
* \brief
* Defines an error that results when a configPath does not support opening
* a config file.
*/
#define RXN_MSL_CONFIG_FORMAT_ERR 1
/**
* \brief
* Defines an error that results when a configPath does not support opening
* a config file.
*/
#define RXN_MSL_CONFIG_READ_ERR 2
/**
* \brief
* Defines a general error that can result during Mobile Suite startup.
*/
#define RXN_MSL_INIT_ERR 3
/**
* \brief
* Defines a general error that can result during Mobile Suite shutdown.
*/
#define RXN_MSL_UNINIT_ERR 4
/**
* \brief
* Defines a general error that can result when acquiring assistance.
*/
#define RXN_MSL_GET_ASSIST_ERR 5
/**
* \brief
* Defines an error indicating that a log is already open.
*/
#define RXN_MSL_TOO_MANY_INSTANCES_ERR 6
/**
* \brief
* Defines an error indicating that a log cannot be opened.
*/
#define RXN_MSL_FILE_OPEN_OR_CLOSE_ERR 7
/**
* \brief
* Defines an error indicating that a network connection is unavailable.
*/
#define RXN_MSL_SKT_COMMS_ERR 8
/**
* \brief
* Enumeration of factory reset type.
*
*/
enum MSL_Reset_Type
{
MSL_RESET_INVALID, /*!< Invalid reset type. No factory reset will be executed. */
MSL_RESET_PRED, /*!< Remove all data from eph and pred folders. */
MSL_RESET_TIME, /*!< Reset all sources of GPS time supplied (SNTP and through the API call RXN_MSL_SetGPSTime(). */
MSL_RESET_PRED_AND_TIME /*!< Remove all data from eph and pred folders and reset time. */
};
/**
* \brief
* Retrieve the Mobile Suite Library (MSL) API version.
*
* \param version [OUT] A memory location to be filled with the current API version.
* This is a null terminated string and is at most RXN_CONSTANT_VERSION_STRING_LENGTH
* (50) characters long.
*
* \return RXN_SUCCESS If the version is returned successfully (always).
*
* \details
* <b>Description</b>\n
* This function returns the version of the MSL API. The version number will be
* incremented as new features, enhancements, and bug fixes are added to the MSL API.
* The version number is an important identification when reporting and troubleshooting issues.
* Rx Networks version numbers are broken down within Integration Users Manuals and API Manuals.
*
* <b>Example Usage</b>
* \code
* // Declare a string to hold version info.
* CHAR version[RXN_CONSTANT_VERSION_STRING_LENGTH];
*
* // Retrieve and output version information.
* RXN_MSL_GetApiVersion(version);
* printf("RXN_MSL_GetApiVersion(): %s\n", version);
* \endcode
*
* <b>Output</b>\n
* RXN_MSL_GetApiVersion(): 1.0.0
*/
U16 RXN_MSL_GetApiVersion(CHAR version[RXN_CONSTANT_VERSION_STRING_LENGTH]);
#ifdef MSL_LOG_ENABLED
/**
* \brief
* Initialize a log for MSL use.
*
* \return RXN_SUCCESS if the log is initialized successfully or if the log is disabled.
* \return RXN_MSL_FILE_OPEN_OR_CLOSE_ERR if a log file cannot be opened.
*
* \details
* <b>Description</b>\n
* Open a log file that can be used by the MSL for logging. If the log file
* exists, it will be appended. If the log file does not exist, it will be created.
* Note that all instances of the MSL will share a common log.
*
* <b>Example Usage</b>
* \code
* if(RXN_MSL_LogInit() != RXN_SUCCESS)
* {
* exit(EXIT_FAILURE);
* }
* \endcode
*/
U16 RXN_MSL_LogInit();
/**
* \brief
* Un-Initialize a log that has been opened for MSL use.
*
* \details
* <b>Description</b>\n
* Close a previously opened log file (if opened).
*
* <b>Example Usage</b>
* \code
* // Shutdown the MSL logger. Always shutdown logging last to ensure that
* // any MSL issues that precedes this call are logged.
* RXN_MSL_LogUninit();
* \endcode
*/
void RXN_MSL_LogUninit();
#endif
/**
* \brief
* Load the configuration file. This must be called before RXN_MSL_Initialize().
*
* \param configPath
* [In] Specifies the path to a config file. This file will contain config
* parameters used by the MSL. Detail on the MSL config file can be found within
* the PG Lite Integration Guide.
*
* \return RXN_SUCCESS if the configuration file is loaded successfully.
* \return RXN_MSL_CONFIG_FORMAT_ERR if the configPath string does not support opening a config file.
* \return RXN_FAIL for all other errors.
*
* \details
* <b>Description</b>\n
* Read the MSLConfig.txt and configure the MSL to operate based on those inputs.
*
* <b>See Also</b>\n
* RXN_MSL_Initialize()
*
* <b>Example Usage</b>
* \code
* #define RXN_CONFIG_FILE ".\\MSLConfig.txt"
* if(RXN_MSL_LoadConfig(RXN_CONFIG_FILE) != RXN_SUCCESS)
* {
* exit(EXIT_FAILURE);
* }
* \endcode
*/
U16 RXN_MSL_LoadConfig(CHAR configPath[RXN_MSL_MAX_CONFIG_PATH_LEN]);
/**
* \brief
* Initialize the Mobile Suite Library to support generating synthetic EE.
*
* \return RXN_SUCCESS if the MSL is initialized successfully.
* \return RXN_MSL_INIT_ERR for all other errors.
*
* \details
* <b>Description</b>\n
* Initialize the O/S abstraction layer and spawning a messaging thread if needed.
*
* <b>Example Usage</b>
* \code
* // Initialize the MSL.
* if(RXN_MSL_Initialize() != RXN_SUCCESS)
* {
* // Shutdown the MSL logger.
* RXN_MSL_LogUninit();
*
* exit(EXIT_FAILURE);
* }
* \endcode
*/
U16 RXN_MSL_Initialize(void);
/**
* \brief
* Un-Initialize Mobile Suite Library (MSL).
*
* \return RXN_SUCCESS if the MSL is stopped successfully.
* \return RXN_FAIL for all errors.
*
* \details
* <b>Description</b>\n
* Un-initialize the MSL component including freeing cache memory, aborting any ephemeris
* generation that may be underway, un-initializing thread protection, un-initializing the
* O/S abstraction to free resources and stopping the MSL logger.
*
* <b>See Also</b>\n
* RXN_MSL_Initialize()
*
* <b>Example Usage</b>
* \code
* // Stop the MSL.
* if(RXN_MSL_Uninitialize()!= RXN_SUCCESS)
* {
* exit(EXIT_FAILURE);
* }
* \endcode
*/
U16 RXN_MSL_Uninitialize(void);
/**
* \brief
* Give the Mobile Suite Library implementation time to perform PGNSS tasks.
*
* \details
* <b>Description</b>\n
* Give the MSL a chance to work. Perform a single step towards any outstanding tasks
* required to support generation of EE. Tasks will depend on the MSL state machine.
*
* <b>Example Usage</b>
* \code
* // Declare a flag to control exit
* static BOOL gRun = TRUE;
*
* while(gRun)
* {
* // Give other threads some cycles.
* Sleep(50);
*
* RXN_MSL_Work();
* }
* \endcode
*/
void RXN_MSL_Work(void);
/**
* \brief
* Get EE in RTCM format from the prediction buffer.
*
* \param constel [IN]
* The constellation to get EE for.
*
* \param rtcmData [OUT]
* RTCM data for the constellation requested at the time of interest.
*
* \param rtcmLength [OUT]
* The length of RTCM data.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE for the specified constellation and time.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Setup an array to store EE (ensure array elements are clear).
* U08 rtcmData[4096];
* U32 rtcmLength = 0;
* memset(rtcmData, 0, sizeof(rtcmData));
*
* // Get ephemeris in RTCM format.
* if(RXN_MSL_GetEphemerisRtcm(RXN_GPS_CONSTEL, rtcmData, &rtcmLength)) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject RTCM data into the GNSS receiver.
* }
* \endcode
*
*/
U16 RXN_MSL_GetEphemerisRtcm(
const RXN_constel_t constel,
U08* rtcmData,
U32* rtcmLength
);
#ifdef MSL_RTCM_TRANSPORT_LAYER
/**
* \brief
* Get EE in RTCM format from the prediction buffer. Wrap RTCM data with the
* transport layer frame and send it to the GNSS receiver.
*
* \param constel [IN]
* The constellation to get EE for.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE for the specified constellation and time.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* if(RXN_MSL_GetRtcmWithTransportLayer(RXN_GPS_CONSTEL)) != RXN_SUCCESS)
* {
* // Handle errors.
* }
* }
* \endcode
*
*/
U16 RXN_MSL_GetRtcmWithTransportLayer(
const RXN_constel_t constel,
U08 *rtcmWithTransportLayer,
U32 *buffLen
);
#endif
#ifdef MSL_DECODE_RTCM
/**
* \brief
* Get GPS ephemeris from the prediction buffer.
*
* \param ephemeris [OUT]
* A RXN_MSL_GPS_Ephem_t structure with current GPS EE for all PRNs. This EE will
* be scaled to match broadcast ephemeris as specified within the RTCM 10403.3
* specification.
*
* \param maxPrnNum [IN]
* The maximum number of PRNs to get from this function.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Setup an array to store EE (ensure array elements are clear).
* RXN_MSL_GPS_Ephem_t ephemeris[RXN_MAX_NUM_GPS_PRNS];
* memset(ephemeris, 0, sizeof(ephemeris));
*
* // Get ephemeris.
* if(RXN_MSL_GetGpsEphemeris(ephemeris, RXN_MAX_NUM_GPS_PRNS) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject GPS ephemeris into the GNSS receiver.
* }
* \endcode
*
* \note
* The caller needs to allocate enough buffer to store the ephemeris.
*
*/
U16 RXN_MSL_GetGpsEphemeris(
RXN_MSL_GPS_Ephem_t* ephemeris,
U08 maxPrnNum
);
/**
* \brief
* Get Beidou ephemeris from the prediction buffer.
*
* \param ephemeris [OUT]
* A RXN_MSL_Beidou_Ephem_t structure with current Beidou EE for all PRNs.
* This EE will be scaled to match broadcast ephemeris as specified within the
* RTCM 10403.3 specification.
*
* \param maxPrnNum [IN]
* The maximum number of PRNs to get from this function.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Setup an array to store EE (ensure array elements are clear).
* RXN_MSL_Beidou_Ephem_t ephemeris[RXN_MAX_NUM_BEIDOU_PRNS];
* memset(ephemeris, 0, sizeof(ephemeris));
*
* // Get ephemeris.
* if(RXN_MSL_GetBeidouEphemeris(ephemeris, RXN_MAX_NUM_BEIDOU_PRNS) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject Beidou ephemeris into the GNSS receiver.
* }
* \endcode
*
* \note
* The caller needs to allocate enough buffer to store the ephemeris.
*
*/
U16 RXN_MSL_GetBeidouEphemeris(
RXN_MSL_Beidou_Ephem_t* ephemeris,
U08 maxPrnNum
);
/**
* \brief
* Get Galileo ephemeris from the prediction buffer.
*
* \param ephemeris [OUT]
* A RXN_MSL_Galileo_Ephem_t structure with current Galileo EE for all PRNs.
* This EE will be scaled to match broadcast ephemeris as specified within the
* RTCM 10403.3 specification.
*
* \param maxPrnNum [IN]
* The maximum number of PRNs to get from this function.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Setup an array to store EE (ensure array elements are clear).
* RXN_MSL_Galileo_Ephem_t ephemeris[RXN_MAX_NUM_GALILEO_PRNS];
* memset(ephemeris, 0, sizeof(ephemeris));
*
* // Get ephemeris.
* if(RXN_MSL_GetGalileoEphemeris(ephemeris, RXN_MAX_NUM_GALILEO_PRNS) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject Galileo ephemeris into the GNSS receiver.
* }
* \endcode
*
* \note
* The caller needs to allocate enough buffer to store the ephemeris.
*
*/
U16 RXN_MSL_GetGalileoEphemeris(
RXN_MSL_Galileo_Ephem_t* ephemeris,
U08 maxPrnNum
);
/**
* \brief
* Get QZSS ephemeris from the prediction buffer.
*
* \param ephemeris [OUT]
* A RXN_MSL_QZSS_Ephem_t structure with current QZSS EE for all PRNs.
* This EE will be scaled to match broadcast ephemeris as specified within the
* RTCM 10403.3 specification.
*
* \param maxPrnNum [IN]
* The maximum number of PRNs to get from this function.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Setup an array to store EE (ensure array elements are clear).
* RXN_MSL_QZSS_Ephem_t ephemeris[RXN_MAX_NUM_QZSS_PRNS];
* memset(ephemeris, 0, sizeof(ephemeris));
*
* // Get ephemeris.
* if(RXN_MSL_GetQzssEphemeris(ephemeris, RXN_MAX_NUM_QZSS_PRNS) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject QZSS ephemeris into the GNSS receiver.
* }
* \endcode
*
* \note
* The caller needs to allocate enough buffer to store the ephemeris.
*
*/
U16 RXN_MSL_GetQzssEphemeris(
RXN_MSL_QZSS_Ephem_t* ephemeris,
U08 maxPrnNum
);
#endif // MSL_DECODE_RTCM
#ifdef RXN_GLONASS_ENABLED
/**
* \brief
* Get Glonass ephemeris from the prediction buffer.
*
* \param ephemeris [OUT]
* A RXN_glonass_ephem_t structure with current Glonass EE for all PRNs. This EE will
* be scaled to match broadcast ephemeris as specified within the the Glonass ICD 5.1
* specification.
*
* \return RXN_SUCCESS
* If the function succeeds in getting EE.
*
* \return RXN_FAIL
* Any errors.
*
* <b>Example Usage</b>
* \code
* // Example. Utilize a flag to signal when EE is required by the GNSS receiver.
* // This flag must be set by integration code when the GNSS receiver needs EE.
* bool needEE;
*
* // Wait until signalled by the GNSS receiver that EE is required. The needEE
* // signal may be checked within a thread loop or timer event as required by
* // the integration application.
* if(needEE)
* {
* // Setup an array to store EE (ensure array elements are clear).
* RXN_glonass_ephem_t ephemeris[RXN_MAX_NUM_GLONASS_PRNS];
* memset(ephemeris, 0, sizeof(ephemeris));
*
* // Get ephemeris.
* if(RXN_MSL_GetGlonassEphemeris(ephemeris) != RXN_SUCCESS)
* {
* // Handle errors.
* }
*
* // Inject Glonass ephemeris into the GNSS receiver.
* }
* \endcode
*
* \note
* The caller needs to allocate enough buffer to store the ephemeris.
*
*/
U16 RXN_MSL_GetGlonassEphemeris(
RXN_glonass_ephem_t* ephemeris
);
#endif // RXN_GLONASS_ENABLED
/**
* \brief
* Get the current GPS time.
*
* \return The number of seconds since GPS start.
*
* \details
* <b>Description</b>\n
* MSL implementation requires target-specific support for getting the
* current GPS time. This value may also be required outside the MSL
* by integration applications. It is for the above reason that this
* function is exposed. The best GPS time is determined by checking if
* we have an accurate GPS time from the receiver. If not, we will try
* SNTP time. We may not get any time update from the receiver and SNTP.
* We will fall back to the most recent valid time. If the old GPS time
* is not good to use, fall back to the old SNTP time. If we don't have
* an accurate time, system time will be returned instead.
*
* <b>Example Usage</b>
* \code
* // Declare an integer to hold the current GPS time.
* U32 GPSTime;
*
* // Get the GPS time from the system.
* GPSTime = RXN_MSL_GetBestGPSTime();
* \endcode
*/
U32 RXN_MSL_GetBestGPSTime(void);
/**
* \brief
* Set the current GPS time.
*
* \param pRefTime
* [In] The current GPS time in RXN_RefTime_t format
*
* \return RXN_SUCCESS if time has been set successfully (always).
*
* \attention Integrators have the responsibility to provide accurate time to the system.
*
* \details
* <b>Description</b>\n
* MSL implementation requires target-specific support for setting the
* current GPS time. This value may also be required outside the MSL
* by integration applications. It is for the above reason that this
* function is exposed.
*
* <b>Example Usage</b>
* \code
* // Declare an integer to hold the GPS time retrieved from receiver in seconds.
* U32 actualGPSTime;
*
* // Declare a storage to hold the GPS time in RXN_RefTime_t format.
* RXN_RefTime_t refTime;
*
* // Get actual GPS time from receiver.
* actualGPSTime = GetActualGPSTime();
*
* refTime.weekNum = actualGPSTime / RXN_SECONDS_PER_WEEK;
* refTime.TOWmSec = (actualGPSTime % RXN_SECONDS_PER_WEEK) * RXN_MILLISECONDS_PER_SECOND;
* refTime.TAccmSec = 1;
*
* // Set time from receiver.
* RXN_MSL_SetGPSTime(&refTime);
* \endcode
*/
U16 RXN_MSL_SetGPSTime(RXN_RefTime_t* pRefTime);
/**
* \brief
* Get the current GPS time derived from SNTP time.
*
* \param pRefTime
* [Out] The current GPS time derived from SNTP time in RXN_RefTime_t format.
*
* \return RXN_SUCCESS if SNTP time is the current time source.
* \return RXN_FAIL if current time source isn't SNTP.
*
* \details
* <b>Description</b>\n
* This function obtains the current time received from a SNTP server and returns it in RXN_RefTime_t format.
*
* <b>Example Usage</b>
* \code
* // Declare a storage to hold the current GPS time in RXN_RefTime_t format.
* RXN_RefTime_t refTime;
*
* if(RXN_MSL_GetSNTPTime(&refTime) != RXN_SUCCESS)
* {
* printf("The current time source isn't SNTP.\n");
* }
* \endcode
*/
U16 RXN_MSL_GetSNTPTime(RXN_RefTime_t* pRefTime);
/*
* This function returns the uncertainty of accurate GPS time in milliseconds,
* it effectively adds 1 second of uncertainty per 8 hours.
*/
U32 MSL_GetAccGPSTimeUncert(void);
/*
* This converts UTC to GPS time and also adds the UTC / GPS offset.
*/
U32 MSL_ConvertUTCToGPSTime(time_t tTime);
/*
* This converts GPS time to Galileo time.
*/
U32 MSL_ConvertGPSTimeToGalileoTime(U32 currentGPSTime);
/*
* This converts Galileo time to GPS time.
*/
U32 MSL_ConvertGalileoTimeToGPSTime(U32 galileoTime);
/*
* This converts GPS time to Beidou time.
*/
U32 MSL_ConvertGPSTimeToBeidouTime(U32 currentGPSTime);
/*
* This converts Beidou time to GPS time.
*/
U32 MSL_ConvertBeidouTimeToGPSTime(U32 beidouTime);
/*
* This converts GPS time to IRNSS time.
*/
U32 MSL_ConvertGPSTimeToIrnssTime(U32 currentGPSTime);
/*
* This converts IRNSS time to GPS time.
*/
U32 MSL_ConvertIrnssTimeToGPSTime(U32 irnssTime);
/*
* This converts GPS time to other constellations' time.
*/
U32 MSL_ConvertGpsTimeToNativeTime(const RXN_constel_t constel, U32 currentGPSTime);
/*
* This converts native constellation time to GPS time.
*/
U32 MSL_ConvertNativeTimeToGpsTime(const RXN_constel_t constel, U32 nativeTime);
/*
* This returns the current GPS leap seconds value.
*/
U32 MSL_GetGPSLeapSec();
/**
* \brief
* Delete all pantry data from file system.
*
* \param resetType
* [In] The enumeration of reset type.
*
* \details
* <b>Description</b>\n
* This will remove all data from eph and pred folders and/or reset time.
*
* <b>Example Usage</b>
* \code
* // Delete all pantry data from file system and reset time.
* RXN_MSL_FactoryReset(MSL_RESET_PRED_AND_TIME);
* \endcode
*/
void RXN_MSL_FactoryReset(enum MSL_Reset_Type resetType);
/*
* This will clear all time parameters sent by the receiver or obtained using SNTP.
*/
void MSL_Time_Reset();
/*
* \brief
* Initialize the O/S abstraction layer.
*
* \param pantryPath
* [In] Explicit or relative path to the pantry files.
* \param verbose
*
* \returns
* RXN_SUCCESS if the abstraction layer functions are initialized successfully.
* RXN_FAIL if an error is encountered.
*/
U16 RXN_Init_Abstraction(CHAR pantryPath[]);
/*
* \brief
* Uninitialize the O/S abstraction layer.
*
* \returns
* RXN_SUCCESS always at present.
*/
U16 RXN_Uninit_Abstraction(void);
#endif /* RXN_MSL_H */

View File

@ -0,0 +1,305 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT distribute
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
* This file contains sample code only and the code carries no
* warranty whatsoever.
* Sample code is used at your own risk and may not be functional.
* It is not intended for commercial use.
*
* Example code to illustrate how to integrate Rx Networks PG Lite
* System into a client application.
*
* The emphasis is in trying to explain what goes on in the software,
* and how to the various API functions relate to each other,
* rather than providing a fully optimized implementation.
*
*************************************************************************
* $LastChangedDate: 2021-04-22 23:41:06 +0000 (Thu, 22 Apr 2021) $
* $Revision: 164641 $
*************************************************************************
*
*/
#ifndef RXN_MSL_COMMON_H
#define RXN_MSL_COMMON_H
#include <string.h> /* Required for string funcs such as strlen. */
#include "RXN_API.h"
/************************************************
* Max Internal String And Other Array Lengths. *
************************************************/
#define MAX_FIELD_LENGTH 50 /* The maximum length for fields */
#define MSL_MAX_FILE_CONFIG_STR_LEN 32 /* Config file path max chars. */
#define MSL_MAX_LINE_STR_LEN 256 /* Config file line max chars. */
#define MSL_MAX_PARAM_STR_LEN 256 /* Config file param max chars. */
#define MSL_MAX_HOST_STR_LEN 256 /* Host URL max chars. */
#define MSL_MAX_PATH_LEN 400 /* Max path to log file, key file, etc. */
#define MSL_MAX_FOLDER_NAME_LEN 50 /* Max length of folder name. */
#define MSL_MAX_FILE_NAME_LEN 50
#define MSL_MAX_SEED_FILE_NAME_LEN MSL_MAX_FILE_NAME_LEN /* Max length of seed filename. */
#define MSL_MAX_FULL_FILE_PATH_LEN MSL_MAX_PATH_LEN + MSL_MAX_FOLDER_NAME_LEN + MSL_MAX_FILE_NAME_LEN
#define MSL_MAX_LOG_TIME_ELEMENT_LEN 64 /* Log entry time string max chars. */
#define MSL_MAX_CUSTOMER_ID_STR_LEN MAX_FIELD_LENGTH /* Customer ID string max chars. */
#define MSL_MAX_DEVICE_ID_STR_LEN MAX_FIELD_LENGTH /* Device ID string max chars. */
#define MSL_MAX_CUSTOMER_KEY_STR_LEN 17 /* Customer key max chars. 16 bytes plus null terminator. */
#define MSL_SKT_REQ_MSG_MAX_LEN 512 /* PG Lite request msg max chars. */
#define MSL_RSP_MSG_HEADER_LEN 12
/* The integrator needs to allocate a sufficient buffer for PG Lite response message.
* The message size depends on the number of constellations and how many days of data to
* be downloaded. The size is approximately 46 KB per 7 days for GPS. The size varies
* in different constellations due to the different number of PRNs.
* 256 KB = 262144. Please adjust this number during software integratioin if necessary.
*/
#define MSL_SKT_RESP_MSG_MAX_LEN (262144*3)
#define MSL_SKT_ADDR_MAX_LEN 64 /* Server IP or host nam max length. */
#define MSL_MAX_PRN_STR_LEN 4
#define MSL_MAX_RT_CMD_NAME_STR_LEN 32
/*****************************
* Internal MSL Error Codes. *
****************************/
#define MSL_FILE_OPENCLOSE_ERROR 101 /* File Open/Close error. */
#define MSL_FILE_IO_ERROR 102 /* File Read/Write error. */
#define MSL_FILE_EOF_ERROR 103 /* EOF reached during read or write. */
#define MSL_FILE_OVER_CAP_ERROR 104 /* Write to a log cannot be compeleted - over capacity. */
#define MSL_SKT_HOST_RESOLVE_ERROR 105 /* Error resolving an IP address from a host name. */
#define MSL_SKT_CREATE_ERROR 106 /* Error creating a socket. */
#define MSL_SKT_SETUP_ERROR 107 /* Error setting up a socket. */
#define MSL_SKT_CONNECT_ERROR 108 /* Error connecting a socket to a host. */
#define MSL_SKT_READ_ERROR 109 /* Error reading on a socket. */
#define MSL_SKT_WRITE_ERROR 110 /* Error writing on a socket. */
#define MSL_SKT_TIMEOUT_ERROR 111 /* Timeout while reading or writing. */
#define MSL_STATE_INVALID_ERROR 113 /* An invalid state was somehow entered. */
#define MSL_PGPS_RESP_PROC_ERROR 114 /* Error processing a clock or seed response. */
#define MSL_PGPS_HOST_FMT_ERROR 115 /* Error with the host string format. */
/************************************
* Config value min and max limits. *
************************************/
#define MSL_URE_THREASHOLD_MIN 20
#define MSL_URE_THREASHOLD_MAX 200
#define MSL_SEED_CHECK_MIN 60
#define MSL_SEED_CHECK_MAX 86400
#define MSL_SEED_DURATION_MIN 1
#define MSL_SEED_DURATION_MAX 31
#define MSL_SEED_UPDATE_AGE_MIN 28800
#define MSL_SEED_UPDATE_AGE_MAX 2678400
#define MSL_SEED_UPDATE_AGE_OFFSET_MIN 0
#define MSL_SEED_UPDATE_AGE_OFFSET_MAX 86400
#define MSL_SEED_UPDATE_RETRY_MAX 5
#define MSL_SEED_AGE_MIN 0
#define MSL_SEED_AGE_MAX 31
#define MSL_RETRY_PERIOD_MIN 0
#define MSL_RETRY_PERIOD_MAX 604800
#define MSL_RETRY_TIMER_MIN 86400
#define MSL_RETRY_TIMER_MAX 604800
#define MSL_SNTP_GPSTIME_UNCERT_MAX 7200
#define MSL_SNTP_RETRY_MAX 5
#define MSL_SNTP_PKT_SIZE 48
#define MSL_INVALID_CLK_OFFSET 0x0
#define MSL_INVALID_GPS_TIME 0x0
#define MSL_INVALID_GPS_TIME_UNCERTAINTY 604800000
#define MSL_SNTPTIME_VALID_DURATION_SECOND 24 * RXN_SECONDS_PER_HOUR /* SNTP sync at least once per day */
/* Number of seconds between Jan 1, 1900 and Jan 1, 1970. ((365 * 70) + 17) * 24 * 60 * 60 = 2208988800 = 0x83aa7e80 */
#define MSL_OFFSET_1900_TO_1970 0x83aa7e80
/* Number of seconds between Jan 1, 1970. and Jan 1 1996 minus 3 hrs*/
#define MSL_GPS_GLO_OFFSET 504478800
/**
* The difference in the number of accumulated UTC leap seconds, between the GPS and Galileo time systems.
* I.e. For a given point in time, if there are N leap seconds since the GPS origin,
* then there are N - MSL_GPS_GALILEO_LEAP_SECOND_OFFSET leap seconds since the Galileo origin.
*/
#define MSL_GPS_GALILEO_LEAP_SECOND_OFFSET 13
/**
* Time offset between GPS system start time in UTC and
* GALILEO system start time in UTC (seconds).
* Note: This does not take into account leap second between GPS and UTC.
*
* GPS start time in UTC: 1980-01-06 00:00:00 (UTC)
* GALILEO start time in UTC: 1999-08-21 23:59:47 (UTC)
*/
#define MSL_GPS_GAL_OFFSET 619315187
/**
* The difference in the number of accumulated UTC leap seconds, between the GPS and BeiDou time systems.
* I.e. For a given point in time, if there are N leap seconds since the GPS origin,
* then there are N - MSL_GPS_BEIDOU_LEAP_SECOND_OFFSET leap seconds since the BeiDou origin.
*/
#define MSL_GPS_BEIDOU_LEAP_SECOND_OFFSET 14
/**
* The difference in the number of accumulated UTC leap seconds, between the GPS and IRNSS time systems.
* I.e. For a given point in time, if there are N leap seconds since the GPS origin,
* then there are N - GPS_IRNSS_LEAP_SECOND_OFFSET leap seconds since the IRNSS origin.
*/
#define MSL_GPS_IRNSS_LEAP_SECOND_OFFSET 13
/**
* Time offset between GPS system start time in UTC and
* BEIDOU system start time in UTC (seconds).
* Note: This does not take into account leap second between GPS and UTC.
*
* GPS start time in UTC: 1980-01-06 00:00:00 (UTC)
* BEIDOU start time in UTC: 2006-01-01 00:00:00 (UTC)
*/
#define MSL_GPS_BDS_OFFSET 820108800
/**
* Time offset between GPS system start time in UTC and
* IRNSS system start time in UTC (seconds).
* Note: This does not take into account leap second between GPS and UTC.
*
* GPS start time in UTC: 1980-01-06 00:00:00 (UTC)
* IRNSS start time in UTC: 1999-08-21 23:59:47 (UTC)
*/
#define MSL_GPS_IRN_OFFSET 619315187
/* Seconds between Jan 1 1970 and GPS Jan 6 1980 */
#define MSL_SYSTEM_GPS_OFFSET 315964800
#define MSL_SYSTEM_GPS_LEAPSECONDS 18
/* list delimitter character used in the MSLConfig.txt */
#define RXN_MSL_DELIMITER " "
/****************
* MSL Includes *
****************/
#include "RXN_MSL.h" /* Defines the MSL interface. */
/* Include RXN constant values. */
#include "RXN_constants.h"
/* Max number of constellations. */
#define MSL_MAX_CONSTEL RXN_UNKNOWN_CONSTEL
/****************************
* MSL Config Structures. *
****************************/
typedef struct MSL_Config_Net
{
/* Host name */
CHAR host[MSL_MAX_HOST_STR_LEN];
/* Host port */
U16 port;
/* If set to FALSE MSL will blindly try to download seed, if set to TRUE MSL
* will smartly try only when data connectivity and roaming settings permit
* data transfer. */
U32 respect_Data_Settings;
/* How frequent we hit the seed server after a failed initial attempt (in seconds). */
U32 downloadRetryPeriod;
/* Duration until next set of retries */
U32 downloadRetryTimer;
/* Maximum number of failed retries */
U08 downloadRetryMax;
} MSL_Config_Net_t;
typedef struct MSL_Config_Security
{
/* Customer ID store */
CHAR customerId[MSL_MAX_CUSTOMER_ID_STR_LEN];
/* Customer Key store */
CHAR customerKey[MSL_MAX_CUSTOMER_KEY_STR_LEN];
} MSL_Config_Security_t;
typedef struct MSL_Config_Seed
{
/* The list of constellations in priority order to process. */
RXN_constel_t constelList[MSL_MAX_CONSTEL];
/* The number of constellations configured. */
U08 numConstels;
/* The seed file to be downloaded. */
CHAR seedFilename[MSL_MAX_SEED_FILE_NAME_LEN];
/* How often to download a new seed (in seconds). */
U32 updateAge;
/* How maximum offset used by a random function to added to the
* Seed_Update_Age for server access load balancing. */
U32 updateAgeOffset;
} MSL_Config_Seed_t;
typedef struct MSL_Config_SNTP
{
/* SNTP Host URL string. */
CHAR host[MSL_MAX_HOST_STR_LEN];
/* SNTP Host port. */
U16 port;
/* How frequent we hit the SNTP server after a failed initial attempt (in seconds). */
U32 requestRetryPeriod;
/* Duration until next set of retries */
U32 requestRetryTimer;
/* Maximum number of failed retries */
U08 requestRetryMax;
} MSL_Config_SNTP_t;
/* If you change this struct, you must also change the initialization in RXN_MSL_Common.c */
typedef struct MSL_Config
{
/* Time to wait during start up before making seed or SNTP request */
U32 startupDataWaitDuration;
/* How frequently (in seconds) to check seeds for required updates. */
U32 systemCheckFreq;
/* Version of the config file */
CHAR version[MSL_MAX_FILE_CONFIG_STR_LEN];
/* Pantry file path store */
CHAR pantryPath[MSL_MAX_PATH_LEN];
MSL_Config_Seed_t seed;
MSL_Config_Net_t net;
MSL_Config_Security_t sec;
MSL_Config_SNTP_t SNTP;
} MSL_Config_t;
static const U08 numOfPRNs[MSL_MAX_CONSTEL] =
{
RXN_MAX_NUM_GPS_PRNS,
RXN_MAX_NUM_GLONASS_PRNS,
RXN_MAX_NUM_GALILEO_PRNS,
RXN_MAX_NUM_BEIDOU_PRNS,
};
/***************************
* Utility Functions Below *
***************************/
/* Read and process config file contents. */
U16 MSL_ProcessConfig(void);
/* Read a delimited parameter from within the config file. */
U16 MSL_ReadParam(CHAR* paramLabel, double* paramData, CHAR paramStr[MSL_MAX_PARAM_STR_LEN]);
/**
* \brief
* Print the MSL configurable parameters in MSL_Log.txt.
*
* \details
* <b>Description</b>\n
* Regardless of if a parameter is missing from the MSLConfig and
* therefore used hardcode default parameters, the MSL_Log.txt should
* capture the MSL configurable parameters to allow for better debugging.
*/
void MSL_PrintConfig(void);
#endif /* RXN_MSL_COMMON_H */

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT distribute
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
* This file contains sample code only and the code carries no
* warranty whatsoever.
* Sample code is used at your own risk and may not be functional.
* It is not intended for commercial use.
*
* Example code to illustrate how to integrate Rx Networks PG Lite
* System into a client application.
*
* The emphasis is in trying to explain what goes on in the software,
* and how to the various API functions relate to each other,
* rather than providing a fully optimized implementation.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 01:56:36 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162558 $
*************************************************************************
*
*/
#ifndef RXN_MSL_TIME_H
#define RXN_MSL_TIME_H
#include "RXN_data_types.h"
#include "RXN_structs.h"
#include "RXN_MSL_Common.h"
enum MSL_Current_Time_Source
{
MSL_CURRENT_TIME_SOURCE_GPS = 0,
MSL_CURRENT_TIME_SOURCE_SNTP,
MSL_CURRENT_TIME_SOURCE_SYSTEM,
MSL_CURRENT_TIME_SOURCE_NO,
};
/* The default current value of GPS leap seconds. */
#define MSL_DEFAULT_GPS_LEAP_SECOND_OFFSET 18
/**
* \brief
* Get the best GPS time. If an accurate GPS time is provided by
* the GNSS chipset, this function will return the GPS time. If no
* GPS time, MSL will try to get SNTP time. If MSL is unable to get
* SNTP time, this function will return the system time.
*/
U32 MSL_GetBestGPSTime(enum MSL_Current_Time_Source* pTimeSource);
U16 MSL_SetGPSTime(RXN_RefTime_t* pRefTime);
void MSL_SetSNTPTime(U32 sntpTime);
U16 MSL_GetSNTPTime(RXN_RefTime_t* pRefTime);
void MSL_SetTimeUncertThresh(U32 thresh);
U32 MSL_GetTimeUncertThresh();
U32 MSL_IsGPSTimeAcceptable();
U32 MSL_IsSNTPTimeAcceptable();
#endif /* RXN_MSL_TIME_H */

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
#include "RXN_bits.h"
#include "RXN_constants_internal.h"
#include "../adaptation/icoe_adap.h"
/* Bit operation */
U08 RXN_Get_Bit(U08* byte, U16 bitIndex)
{
U32 byteIndex = bitIndex / RXN_NUM_BITS_PER_BYTE;
if(byteIndex > 0)
{
bitIndex = bitIndex - (U16) (byteIndex * RXN_NUM_BITS_PER_BYTE);
}
U08 result = (U08) (byte[byteIndex] >> (7 - bitIndex)) & 0x01;
return result;
}
/* Unsigned operations */
U64 RXN_Get_U64_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
U64 dec = 0;
U64 power = 1;
bp->to = bp->from + numBits - 1;
for(int i = bp->to; i >= bp->from; i--)
{
dec += RXN_Get_Bit(bp->buf, (U16) i) * power;
power *= 2;
}
U64 temp = (U64)0x1 << (bp->to - bp->from + 1);
dec &= (U64) (temp -1) ; // replace pow(2.0, (to - from + 1)) - 1;
bp->from = bp->from + numBits;
return dec;
}
U08 RXN_Get_U08_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (U08) RXN_Get_U64_Bits(bp, numBits);
}
U16 RXN_Get_U16_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (U16) RXN_Get_U64_Bits(bp, numBits);
}
U32 RXN_Get_U32_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (U32) RXN_Get_U64_Bits(bp, numBits);
}
/* Signed operations */
S08 RXN_Get_S08_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (S08) RXN_Get_S64_Bits(bp, numBits);
}
S16 RXN_Get_S16_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (S16) RXN_Get_S64_Bits(bp, numBits);
}
S32 RXN_Get_S32_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (S32) RXN_Get_S64_Bits(bp, numBits);
}
S64 RXN_Get_S64_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
S64 dec = 0;
S64 power = 1;
bp->to = bp->from + numBits - 1;
for(int i = bp->to; i >= bp->from; i--)
{
dec += RXN_Get_Bit(bp->buf, (U16) i) * power;
power *= 2;
}
U16 totalBits = 64;
U16 shift = totalBits - (bp->to - bp->from + 1);
S64 newTemp = dec << shift;
dec = newTemp >> shift;
bp->from = bp->from + numBits;
return dec;
}
/* Corresponding set methods */
void RXN_Set_Bit(U08* stream, U08 input, U16 bit)
{
U08 highMask[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
U08 lowMask[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
U32 byteIndex = bit / RXN_NUM_BITS_PER_BYTE;
if(byteIndex > 0)
{
bit = bit - (U16) (byteIndex * RXN_NUM_BITS_PER_BYTE); // find remainder
}
if(input & 0x1) // eg bit 7 goes to slot 0 MSB-> LSB
stream[byteIndex] |= highMask[7 - bit];
else
stream[byteIndex] &= lowMask[7 - bit];
}
void RXN_Set_S64_Bits(RXN_bit_parse_t* bp, S64 input, U16 numBits)
{
bp->to = bp->from + numBits - 1;
S64 maskedIn = input;
maskedIn <<= 64 - numBits;
maskedIn >>= 64 - numBits;
int cnt = 0;
for(int i = bp->to; i >= bp->from; i--) // read in LSB first
{
U08 temp = ((U08)(maskedIn >> ( cnt))) & 0x1;
cnt++;
RXN_Set_Bit(bp->buf,temp , (U16) i);
}
bp->from = bp->from + numBits;
}
void RXN_Set_U64_Bits(RXN_bit_parse_t* bp, U64 input, U16 numBits)
{
bp->to = bp->from + numBits - 1;
int cnt = 0;
for(int i = bp->to; i >= bp->from; i--) // read in LSB first
{
U08 temp = ((U08)(input >> ( cnt))) & 0x1;
cnt++;
RXN_Set_Bit(bp->buf,temp , (U16) i);
}
bp->from = bp->from + numBits;
}
U32 RXN_CRC32( U08* addr,unsigned int offset, U32 n)
{
#define CRC32_POLYNOMIAL 0xEDB88320UL /* Reversed polynomial */
U32 i, j, r;
unsigned char data;
r = 0xFFFFFFFFUL;
for(i = 0; i < n; i++)
{
icoe_adap_read_flash(addr,offset++,&data,1,ICOE_DATA_FROM_RAM);
r ^= data;
//r ^= data[i];
for(j = 0; j < 8; j++)
{
if(r & 1)
{
r = (r >> 1) ^ CRC32_POLYNOMIAL;
}
else
{
r >>= 1;
}
}
}
return r ^ 0xFFFFFFFFUL;
}

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
#include "RXN_bits.h"
#include "RXN_constants_internal.h"
#include "../adaptation/icoe_adap.h"
/* Bit operation */
U08 RXN_Get_Bit(U08* byte, U16 bitIndex)
{
U32 byteIndex = bitIndex / RXN_NUM_BITS_PER_BYTE;
if(byteIndex > 0)
{
bitIndex = bitIndex - (U16) (byteIndex * RXN_NUM_BITS_PER_BYTE);
}
U08 result = (U08) (byte[byteIndex] >> (7 - bitIndex)) & 0x01;
return result;
}
/* Unsigned operations */
U64 RXN_Get_U64_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
U64 dec = 0;
U64 power = 1;
bp->to = bp->from + numBits - 1;
for(int i = bp->to; i >= bp->from; i--)
{
dec += RXN_Get_Bit(bp->buf, (U16) i) * power;
power *= 2;
}
U64 temp = (U64)0x1 << (bp->to - bp->from + 1);
dec &= (U64) (temp -1) ; // replace pow(2.0, (to - from + 1)) - 1;
bp->from = bp->from + numBits;
return dec;
}
U08 RXN_Get_U08_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (U08) RXN_Get_U64_Bits(bp, numBits);
}
U16 RXN_Get_U16_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (U16) RXN_Get_U64_Bits(bp, numBits);
}
U32 RXN_Get_U32_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (U32) RXN_Get_U64_Bits(bp, numBits);
}
/* Signed operations */
S08 RXN_Get_S08_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (S08) RXN_Get_S64_Bits(bp, numBits);
}
S16 RXN_Get_S16_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (S16) RXN_Get_S64_Bits(bp, numBits);
}
S32 RXN_Get_S32_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
return (S32) RXN_Get_S64_Bits(bp, numBits);
}
S64 RXN_Get_S64_Bits(RXN_bit_parse_t* bp, U16 numBits)
{
S64 dec = 0;
S64 power = 1;
bp->to = bp->from + numBits - 1;
for(int i = bp->to; i >= bp->from; i--)
{
dec += RXN_Get_Bit(bp->buf, (U16) i) * power;
power *= 2;
}
U16 totalBits = 64;
U16 shift = totalBits - (bp->to - bp->from + 1);
S64 newTemp = dec << shift;
dec = newTemp >> shift;
bp->from = bp->from + numBits;
return dec;
}
/* Corresponding set methods */
void RXN_Set_Bit(U08* stream, U08 input, U16 bit)
{
U08 highMask[] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
U08 lowMask[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
U32 byteIndex = bit / RXN_NUM_BITS_PER_BYTE;
if(byteIndex > 0)
{
bit = bit - (U16) (byteIndex * RXN_NUM_BITS_PER_BYTE); // find remainder
}
if(input & 0x1) // eg bit 7 goes to slot 0 MSB-> LSB
stream[byteIndex] |= highMask[7 - bit];
else
stream[byteIndex] &= lowMask[7 - bit];
}
void RXN_Set_S64_Bits(RXN_bit_parse_t* bp, S64 input, U16 numBits)
{
bp->to = bp->from + numBits - 1;
S64 maskedIn = input;
maskedIn <<= 64 - numBits;
maskedIn >>= 64 - numBits;
int cnt = 0;
for(int i = bp->to; i >= bp->from; i--) // read in LSB first
{
U08 temp = ((U08)(maskedIn >> ( cnt))) & 0x1;
cnt++;
RXN_Set_Bit(bp->buf,temp , (U16) i);
}
bp->from = bp->from + numBits;
}
void RXN_Set_U64_Bits(RXN_bit_parse_t* bp, U64 input, U16 numBits)
{
bp->to = bp->from + numBits - 1;
int cnt = 0;
for(int i = bp->to; i >= bp->from; i--) // read in LSB first
{
U08 temp = ((U08)(input >> ( cnt))) & 0x1;
cnt++;
RXN_Set_Bit(bp->buf,temp , (U16) i);
}
bp->from = bp->from + numBits;
}
U32 RXN_CRC32( U08* addr,unsigned int offset, U32 n)
{
#define CRC32_POLYNOMIAL 0xEDB88320UL /* Reversed polynomial */
U32 i, j, r;
unsigned char data;
r = 0xFFFFFFFFUL;
for(i = 0; i < n; i++)
{
icoe_adap_read_flash(addr,offset++,&data,1,ICOE_DATA_FROM_RAM);
r ^= data;
//r ^= data[i];
for(j = 0; j < 8; j++)
{
if(r & 1)
{
r = (r >> 1) ^ CRC32_POLYNOMIAL;
}
else
{
r >>= 1;
}
}
}
return r ^ 0xFFFFFFFFUL;
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
#ifndef RXN_BITS_H
#define RXN_BITS_H
#include "RXN_data_types.h"
typedef struct RXN_bit_parse
{
U08 *buf;
U16 from;
U16 to;
} RXN_bit_parse_t;
U08 RXN_Get_Bit(U08* byte, U16 bitIndex);
U64 RXN_Get_U64_Bits(RXN_bit_parse_t* bp, U16 numBits);
U32 RXN_Get_U32_Bits(RXN_bit_parse_t* bp, U16 numBits);
U16 RXN_Get_U16_Bits(RXN_bit_parse_t* bp, U16 numBits);
U08 RXN_Get_U08_Bits(RXN_bit_parse_t* bp, U16 numBits);
S64 RXN_Get_S64_Bits(RXN_bit_parse_t* bp, U16 numBits);
S32 RXN_Get_S32_Bits(RXN_bit_parse_t* bp, U16 numBits);
S16 RXN_Get_S16_Bits(RXN_bit_parse_t* bp, U16 numBits);
S08 RXN_Get_S08_Bits(RXN_bit_parse_t* bp, U16 numBits);
//functions for setting bits.
void RXN_Set_Bit(U08* stream, U08 input, U16 bit);
void RXN_Set_S64_Bits(RXN_bit_parse_t* bp, S64 input, U16 numBits);
void RXN_Set_U64_Bits(RXN_bit_parse_t* bp, U64 input, U16 numBits);
// Calculates the CRC-32 of data.
// U32 RXN_CRC32( U08* data, U32 n);
U32 RXN_CRC32( U08* addr,unsigned int offset, U32 n);
#endif // RXN_BITS_H

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
/**
* \file
* \brief
* Defines the constants used in the library.
*
* \since
* 1.0.0
*/
#ifndef RXN_CONSTANTS_H
#define RXN_CONSTANTS_H
#include "RXN_structs.h"
/**
* \brief
* Defines the maximum number of characters for a version string.
*
* \since
* 1.0.0
*/
#define RXN_CONSTANT_VERSION_STRING_LENGTH 50
/**
* \brief
* Defines the maximum number of GPS PRNs.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_GPS_PRNS 32
/**
* \brief
* Defines the maximum number of Glonass PRNs.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_GLONASS_PRNS 24
/**
* \brief
* Defines the maximum number of Beidou PRNs according to the ICD.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_BEIDOU_PRNS 63
/**
* \brief
* Defines the maximum number of Galileo PRNs according to the ICD.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_GALILEO_PRNS 36
/**
* \brief
* Defines the maximum number of QZSS PRNs according to the section 3.2.1 in IS-QZSS-PNT-003 Nov 5, 2018.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_QZSS_PRNS 10
/**
* \brief
* Defines the maximum number of IRNSS PRNs according to the section 4 IRNSS PRN CODES in ISRO-IRNSS-ICD-SPS-1.1 Aug, 2017.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_IRNSS_PRNS 14
/**
* \brief
* Defines the maximum number of SBAS PRNs.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_SBAS_PRNS 39
/**
* \brief
* Defines the maximum number of PRNs.
*
* \since
* 1.0.0
*/
#define RXN_MAX_NUM_PRNS 63
/**
* \brief
* Defines the return code for functions that complete successfully.
*
* \since
* 1.0.0
*/
#define RXN_SUCCESS 0
/**
* \brief
* Defines the return code for functions that complete unsuccessfully.
*
* \since
* 1.0.0
*/
#define RXN_FAIL 255
#define RXN_MILLISECONDS_PER_SECOND 1000
#define RXN_MICROSECONDS_PER_MILLISECOND 1000
#define RXN_NANOSECONDS_PER_MICROSECOND 1000
#define RXN_MICROSECONDS_PER_SECOND 1000000
#define RXN_NANOSECONDS_PER_MILLISECOND 1000000
#define RXN_SECONDS_PER_HOUR 3600
#define RXN_SECONDS_PER_WEEK 604800
#endif // RXN_CONSTANTS_H

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-05-04 22:46:16 +0000 (Tue, 04 May 2021) $
* $Revision: 164648 $
*************************************************************************
*
*/
/**
* \file
* \brief
* Defines the constants used internally in the library.
*
* \since
* 1.0.0
*/
#ifndef RXN_CONSTANTS_INTERNAL_H
#define RXN_CONSTANTS_INTERNAL_H
#include "RXN_constants.h"
#if 0
const U08 RXN_CURRENT_EE_VERSION = 1; // TODO: Update this number if the EE version changes.
const U08 RXN_DEFAULT_CURRENT_LEAP_SECS = 18; // TODO: Update this number if a new leap second is introduced.
const U08 RXN_NUM_BITS_PER_BYTE = 8;
/* PG Lite binary file header. */
const U16 RXN_FILE_VERSION_BITS = 8;
const U16 RXN_REGION_ID_BITS = 8;
const U16 RXN_GENERATION_TIME_BITS = 32;
const U16 RXN_CURRENT_LEAP_SECS_BITS = 8;
const U16 RXN_NEXT_LEAP_SECS_BITS = 8;
const U16 RXN_NEXT_LEAP_SECS_GPS_WEEK_BITS = 16;
const U16 RXN_NEXT_LEAP_SECS_TOW_BITS = 32;
const U16 RXN_RXN_UNCOMPRESSED_FLAG_BITS = 1;
const U16 RXN_RESERVED_BITS = 16;
const U16 RXN_PAYLOAD_CRC32_BITS = 32;
const U16 RXN_HEADER_CRC32_BITS = 32;
const U16 RXN_HEADER_BYTES = (RXN_FILE_VERSION_BITS + RXN_REGION_ID_BITS +
RXN_GENERATION_TIME_BITS + RXN_CURRENT_LEAP_SECS_BITS +
RXN_NEXT_LEAP_SECS_BITS + RXN_NEXT_LEAP_SECS_GPS_WEEK_BITS +
RXN_NEXT_LEAP_SECS_TOW_BITS + RXN_RESERVED_BITS +
RXN_PAYLOAD_CRC32_BITS + RXN_HEADER_CRC32_BITS) / RXN_NUM_BITS_PER_BYTE;
const U16 RXN_SECTION_ID_BITS = 8;
const U16 RXN_SECTION_LEN_BITS = 32;
const U16 RXN_SECTION_ID_AND_LEN_BYTES = (RXN_SECTION_ID_BITS + RXN_SECTION_LEN_BITS) / RXN_NUM_BITS_PER_BYTE;
/* PG Lite EE header. */
const U16 RXN_EE_VERSION_BITS = 8;
const U16 RXN_CONSTELLATION_BITS = 8;
const U16 RXN_EPOCH_BLOCK_START_TIME_BITS = 32;
const U16 RXN_TOTAL_NUMBER_OF_BLOCKS_BITS = 8;
const U16 RXN_EPOCH_BLOCK_DURATION_IN_HOURS_BITS = 8;
const U16 RXN_EE_RESERVED_BITS = 16;
const U16 RXN_EE_HEADER_BYTES = (RXN_EE_VERSION_BITS + RXN_CONSTELLATION_BITS +
RXN_EPOCH_BLOCK_START_TIME_BITS + RXN_TOTAL_NUMBER_OF_BLOCKS_BITS +
RXN_EPOCH_BLOCK_DURATION_IN_HOURS_BITS + RXN_EE_RESERVED_BITS) / RXN_NUM_BITS_PER_BYTE;
const U16 RXN_BLOCK_SIZE_BITS = 16;
const U16 RXN_BLOCK_SIZE_BYTES = RXN_BLOCK_SIZE_BITS / RXN_NUM_BITS_PER_BYTE;
const U08 RXN_MAX_NUM_OF_BLOCKS = 255;
#endif
#define RXN_CURRENT_EE_VERSION 1 // TODO: Update this number if the EE version changes.
#define RXN_DEFAULT_CURRENT_LEAP_SECS 18 // TODO: Update this number if a new leap second is introduced.
#define RXN_NUM_BITS_PER_BYTE 8
/* PG Lite binary file header. */
#define RXN_FILE_VERSION_BITS 8
#define RXN_REGION_ID_BITS 8
#define RXN_GENERATION_TIME_BITS 32
#define RXN_CURRENT_LEAP_SECS_BITS 8
#define RXN_NEXT_LEAP_SECS_BITS 8
#define RXN_NEXT_LEAP_SECS_GPS_WEEK_BITS 16
#define RXN_NEXT_LEAP_SECS_TOW_BITS 32
#define RXN_RXN_UNCOMPRESSED_FLAG_BITS 1
#define RXN_RESERVED_BITS 16
#define RXN_PAYLOAD_CRC32_BITS 32
#define RXN_HEADER_CRC32_BITS 32
#define RXN_HEADER_BYTES (RXN_FILE_VERSION_BITS + RXN_REGION_ID_BITS + \
RXN_GENERATION_TIME_BITS + RXN_CURRENT_LEAP_SECS_BITS + \
RXN_NEXT_LEAP_SECS_BITS + RXN_NEXT_LEAP_SECS_GPS_WEEK_BITS +\
RXN_NEXT_LEAP_SECS_TOW_BITS + RXN_RESERVED_BITS +\
RXN_PAYLOAD_CRC32_BITS + RXN_HEADER_CRC32_BITS) / RXN_NUM_BITS_PER_BYTE
#define RXN_SECTION_ID_BITS 8
#define RXN_SECTION_LEN_BITS 32
#define RXN_SECTION_ID_AND_LEN_BYTES (RXN_SECTION_ID_BITS + RXN_SECTION_LEN_BITS) / RXN_NUM_BITS_PER_BYTE
/* PG Lite EE header. */
#define RXN_EE_VERSION_BITS 8
#define RXN_CONSTELLATION_BITS 8
#define RXN_EPOCH_BLOCK_START_TIME_BITS 32
#define RXN_TOTAL_NUMBER_OF_BLOCKS_BITS 8
#define RXN_EPOCH_BLOCK_DURATION_IN_HOURS_BITS 8
#define RXN_EE_RESERVED_BITS 16
#define RXN_EE_HEADER_BYTES (RXN_EE_VERSION_BITS + RXN_CONSTELLATION_BITS + \
RXN_EPOCH_BLOCK_START_TIME_BITS + RXN_TOTAL_NUMBER_OF_BLOCKS_BITS + \
RXN_EPOCH_BLOCK_DURATION_IN_HOURS_BITS + RXN_EE_RESERVED_BITS) / RXN_NUM_BITS_PER_BYTE
#define RXN_BLOCK_SIZE_BITS 16
#define RXN_BLOCK_SIZE_BYTES RXN_BLOCK_SIZE_BITS / RXN_NUM_BITS_PER_BYTE
#define RXN_MAX_NUM_OF_BLOCKS 255
#ifndef RXN_NO_COMPRESSION
/* LZMA header: 5 bytes of LZMA properties and 8 bytes of uncompressed size. */
#define RXN_LZMA_UNCOMPRESSED_SIZE_BYTES 8
/* The maximum uncomppressed data size. No single epoch of EE or any section of RT data
should ever exceed 16 KB (16384 bytes, just to be safe, although it should be smaller).
Use this number to check if the uncompressed size decoded from LZMA header is invalid.
If an incorrect customer key is provided, bytes 6 to 13 of LZMA header (uncompressed
size) could be decoded into a very huge U64 number. */
#define RXN_MAX_UNCOMPRESSED_DATA_SIZE_BYTES 16384
#endif
#endif // RXN_CONSTANTS_INTERNAL_H

View File

@ -0,0 +1,198 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
/**
* \file
* \brief
* Defines the primitive data types and their sizes.
*
* \since
* 1.0.0
*/
#ifndef RXN_DATA_TYPES_H
#define RXN_DATA_TYPES_H
/**
* \brief
* 1 byte character type.
*
* \since
* 1.0.0
*/
#ifndef CHAR_DEFINED
#define CHAR_DEFINED
typedef char CHAR;
#endif
// --- Unsigned integer types: 8 bits, 16 bits, 32 bits
/**
* \brief
* 1 byte unsigned integer value.
*
* \since
* 1.0.0
*/
typedef unsigned char U08;
/**
* \brief
* 2 byte unsigned integer value.
*
* \since
* 1.0.0
*/
typedef unsigned short U16;
/**
* \brief
* 4 byte unsigned integer value.
*
* \since
* 1.0.0
*/
typedef unsigned int U32;
/**
* \brief
* 8 byte unsigned integer value.
*
* \since
* 1.0.0
*/
#if defined(_MSC_VER) && (_MSC_VER == 1200) /* Microsoft Visual C++ 6.0 */
typedef unsigned __int64 U64;
#else
typedef unsigned long long U64;
#endif
// --- Signed integer types: 8 bits, 16 bits, 32 bits
/**
* \brief
* 1 byte signed integer value.
*
* \since
* 1.0.0
*/
typedef signed char S08;
/**
* \brief
* 2 byte signed integer value.
*
* \since
* 1.0.0
*/
typedef signed short S16;
/**
* \brief
* 4 byte signed integer value.
*
* \since
* 1.0.0
*/
typedef signed int S32;
/**
* \brief
* 8 byte signed integer value.
*
* \since
* 1.0.0
*/
#if defined(_MSC_VER) && (_MSC_VER == 1200) /* Microsoft Visual C++ 6.0 */
typedef signed __int64 S64;
#else
typedef signed long long S64;
#endif
// --- Float point types: 32 bits, 64 bits
/**
* \brief
* 4 byte floating point value.
*
* \since
* 1.0.0
*/
typedef float R32;
/**
* \brief
* 8 byte floating point value.
*
* \since
* 1.0.0
*/
typedef double R64;
// Boolean type
/**
* \brief
* Boolean value
*
* \since
* 1.0.0
*/
// Boolean values: TRUE, FALSE
/**
* \brief
* Boolean TRUE value.
*
* \since
* 1.0.0
*/
#ifndef TRUE
#define TRUE 1
#endif
/**
* \brief
* Boolean FALSE value.
*
* \since
* 1.0.0
*/
#ifndef FALSE
#define FALSE 0
#endif
// NULL
/**
* \brief
* NULL pointer value.
*
* \since
* 1.0.0
*/
#ifndef NULL
#define NULL (void*)0
#endif
#endif // RXN_DATA_TYPES_H

View File

@ -0,0 +1,157 @@
/*
* Copyright (c) 2021 Rx Networks, Inc. All rights reserved.
*
* Property of Rx Networks
* Proprietary and Confidential
* Do NOT modify. Do NOT distribute.
*
* Any use, distribution, or copying of this document requires a
* license agreement with Rx Networks.
* Any product development based on the contents of this document
* requires a license agreement with Rx Networks.
* If you have received this document in error, please notify the
* sender immediately by telephone and email, delete the original
* document from your electronic files, and destroy any printed
* versions.
*
*************************************************************************
* $LastChangedDate: 2021-02-12 02:00:26 +0000 (Fri, 12 Feb 2021) $
* $Revision: 162562 $
*************************************************************************
*
*/
/**
* \file
* \brief
* Defines the assistance data structures.
*
* \since
* 1.0.0
*/
#ifndef RXN_STRUCTS_H
#define RXN_STRUCTS_H
#include "RXN_data_types.h"
#include "RXN_constants.h"
/**
* \brief
* Enumeration of section data types.
*
* \since
* 1.0.0
*/
typedef enum RXN_section_types
{
RXN_GPS_EE = 0, /*!< Prediction.*/
RXN_GPS_1NAC, /*!< Navigation Model Message in native format.*/
RXN_GPS_1ALM, /*!< Almanac.*/
RXN_GPS_1ION, /*!< Ionosphere.*/
RXN_GPS_1UTC, /*!< UTC Model.*/
RXN_GPS_1RTC, /*!< Reference Time.*/
RXN_GPS_1SGH, /*!< Satellite Global Health.*/
RXN_GLO_EE = 10, /*!< Prediction.*/
RXN_GLO_2NAC, /*!< Navigation Model Message in native format.*/
RXN_GLO_2ALM, /*!< Almanac.*/
RXN_GLO_2TIM, /*!< Time Model.*/
RXN_GLO_2AIO, /*!< Additional Ionosphere.*/
RXN_GLO_2AUT, /*!< Addition UTC.*/
RXN_GLO_2RTM, /*!< Reference Time.*/
RXN_GLO_2AUX, /*!< Auxiliary.*/
RXN_GLO_2NKC, /*!< Navigation Model Message in Keplerian format.*/
RXN_GLO_9NAC, /*!< Navigation Model Message that includes all raw string navigation data.*/
RXN_BDS_EE = 20, /*!< Prediction.*/
RXN_BDS_2NAC, /*!< Navigation Model Message in native format.*/
RXN_BDS_2ALM, /*!< Almanac.*/
RXN_BDS_2TIM_B1C, /*!< Time Model.*/
RXN_BDS_2AIO, /*!< Additional Ionosphere.*/
RXN_BDS_2AUT, /*!< Addition UTC.*/
RXN_BDS_2RTM, /*!< Reference Time.*/
RXN_GAL_EE = 30, /*!< Prediction.*/
RXN_GAL_2NAC, /*!< Navigation Model Message in native format.*/
RXN_GAL_2ALM, /*!< Almanac.*/
RXN_GAL_2TIM, /*!< Time Model.*/
RXN_GAL_2AIO, /*!< Additional Ionosphere.*/
RXN_GAL_2AUT, /*!< Addition UTC.*/
RXN_GAL_2RTM, /*!< Reference Time.*/
RXN_GAL_9NAC, /*!< Navigation Model Message that includes all raw string navigation data.*/
RXN_QZS_EE = 40, /*!< Prediction.*/
RXN_QZS_2NAC, /*!< Navigation Model Message in native format.*/
RXN_QZS_2ALM, /*!< Almanac.*/
RXN_QZS_2TIM, /*!< Time Model.*/
RXN_QZS_2AIO, /*!< Additional Ionosphere.*/
RXN_QZS_2AUT, /*!< Addition UTC.*/
RXN_QZS_2RTM, /*!< Reference Time.*/
RXN_IRN_EE = 50, /*!< Prediction.*/
RXN_IRN_2NAC, /*!< Navigation Model Message in native format.*/
RXN_IRN_2ALM, /*!< Almanac.*/
RXN_IRN_2TIM, /*!< Time Model.*/
RXN_IRN_2AIO, /*!< Additional Ionosphere.*/
RXN_IRN_2AUT, /*!< Addition UTC.*/
RXN_IRN_2RTM, /*!< Reference Time.*/
RXN_IRN_2EOP, /*!< Earth Orientation Parameters.*/
RXN_SBA_EE = 60, /*!< Prediction.*/
RXN_SBA_2NAC, /*!< Navigation Model Message in native format.*/
RXN_SBA_2ALM, /*!< Almanac.*/
RXN_SBA_2RTM, /*!< Reference Time.*/
} RXN_section_types_t;
/**
* \brief
* Enumeration used to select the constellation from which to draw or
* generate assistance.
*
* \since
* 1.0.0
*/
typedef enum RXN_constel
{
RXN_GPS_CONSTEL = 0, /*!< NAVSTAR constellation.*/
RXN_GLO_CONSTEL, /*!< GLONASS constellation.*/
RXN_GAL_CONSTEL, /*!< GALILEO constellation.*/
RXN_BDS_CONSTEL, /*!< BEIDOU constellation.*/
RXN_IRN_CONSTEL, /*!< IRNSS constellation.*/
RXN_QZS_CONSTEL, /*!< QZSS constellation.*/
RXN_SBA_CONSTEL, /*!< SBAS constellation.*/
RXN_UNKNOWN_CONSTEL
} RXN_constel_t;
/**
* \brief
* A structure for overriding configuration defaults / getting information
* from the server regarding leap seconds.
*
* The library *does* need leap_secs for Glonass and will use nextLeapSecs
* if not zero. The integrator is therefore advised not to zero either of
* these out when calling RXN_Set_Configuration().
*
* \since
* 1.0.0
*/
typedef struct RXN_config
{
U16 timeOfNextLeapSecInGpsWeek; /*!< \brief Time of next leap second in GPS Week if known; otherwise the value is set to 0. Based on International Earth Rotation and Reference Systems Service (IERS) bulletin.*/
U32 timeOfNextLeapSecInGpsTowInSecs; /*!< \brief Time of next leap second in GPS TOW (seconds).*/
U08 currentLeapSecs; /*!< \brief Current leap seconds between UTC and GPS.*/
U08 nextLeapSecs; /*!< \brief Number of leap seconds at next change.*/
} RXN_config_t;
/**
* \brief
* A structure for EE file information.
*
* \since
* 1.0.0
*/
typedef struct RXN_ee_info
{
U08 eeVersion; /*!< \brief EE version number.*/
U08 constellation; /*!< \brief 0:GPS 1:GLONASS 2:GALILEO 3:BDS 4:IRNSS 5:QZSS 6:SBAS.*/
U32 firstEpochBlockStartTime; /*!< \brief The native start time of the first epoch block.*/
U08 totalNumberOfBlocks; /*!< \brief The total number of epoch blocks.*/
U08 epochBlockDurationInHours; /*!< \brief The validity duration in hours of the ephemeris in all epoch blocks.*/
} RXN_ee_info_t;
#endif // RXN_STRUCTS_H

View File

@ -0,0 +1,568 @@
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
ECB-AES128
----------
plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710
key:
2b7e151628aed2a6abf7158809cf4f3c
resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the key size is proportionally larger.
*/
/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <string.h> // CBC mode, for memset
#include "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4
#if defined(AES256) && (AES256 == 1)
#define Nk 8
#define Nr 14
#elif defined(AES192) && (AES192 == 1)
#define Nk 6
#define Nr 12
#else
#define Nk 4 // The number of 32 bit words in a key.
#define Nr 10 // The number of rounds in AES Cipher.
#endif
// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used up to rcon[10] for AES-128 (as 11 round keys are needed),
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/
/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
/*
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
*/
#define getSBoxValue(num) (sbox[(num)])
/*
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
*/
#define getSBoxInvert(num) (rsbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
for (i = 0; i < Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// All other round keys are found from the previous round keys.
for (i = Nk; i < Nb * (Nr + 1); ++i)
{
{
k = (i - 1) * 4;
tempa[0]=RoundKey[k + 0];
tempa[1]=RoundKey[k + 1];
tempa[2]=RoundKey[k + 2];
tempa[3]=RoundKey[k + 3];
}
if (i % Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
#if defined(AES256) && (AES256 == 1)
if (i % Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
j = i * 4; k=(i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
{
KeyExpansion(ctx->RoundKey, key);
}
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
{
KeyExpansion(ctx->RoundKey, key);
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
{
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
#endif
// This function adds the round key to state.
// The round key is added to the state by an XOR function.
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void SubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
static void ShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;
// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
static void MixColumns(state_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}
// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// Cipher is the main function that encrypts the PlainText.
static void Cipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(0, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without MixColumns()
for (round = 1; ; ++round)
{
SubBytes(state);
ShiftRows(state);
if (round == Nr) {
break;
}
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}
// Add round key to last round
AddRoundKey(Nr, state, RoundKey);
}
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static void InvCipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without InvMixColumn()
for (round = (Nr - 1); ; --round)
{
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(round, state, RoundKey);
if (round == 0) {
break;
}
InvMixColumns(state);
}
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES algorithm.
Cipher((state_t*)buf, ctx->RoundKey);
}
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES algorithm.
InvCipher((state_t*)buf, ctx->RoundKey);
}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
}
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t *Iv = ctx->Iv;
for (i = 0; i < length; i += AES_BLOCKLEN)
{
XorWithIv(buf, Iv);
Cipher((state_t*)buf, ctx->RoundKey);
Iv = buf;
buf += AES_BLOCKLEN;
}
/* store Iv in ctx for next call */
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t storeNextIv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN)
{
memcpy(storeNextIv, buf, AES_BLOCKLEN);
InvCipher((state_t*)buf, ctx->RoundKey);
XorWithIv(buf, ctx->Iv);
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
buf += AES_BLOCKLEN;
}
}
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uint8_t buffer[AES_BLOCKLEN];
unsigned i;
int bi;
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
{
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
{
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
Cipher((state_t*)buffer,ctx->RoundKey);
/* Increment Iv and handle overflow */
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
{
/* inc will overflow */
if (ctx->Iv[bi] == 255)
{
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += 1;
break;
}
bi = 0;
}
buf[i] = (buf[i] ^ buffer[bi]);
}
}
#endif // #if defined(CTR) && (CTR == 1)

View File

@ -0,0 +1,568 @@
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
ECB-AES128
----------
plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710
key:
2b7e151628aed2a6abf7158809cf4f3c
resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the key size is proportionally larger.
*/
/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <string.h> // CBC mode, for memset
#include "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4
#if defined(AES256) && (AES256 == 1)
#define Nk 8
#define Nr 14
#elif defined(AES192) && (AES192 == 1)
#define Nk 6
#define Nr 12
#else
#define Nk 4 // The number of 32 bit words in a key.
#define Nr 10 // The number of rounds in AES Cipher.
#endif
// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
// The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used up to rcon[10] for AES-128 (as 11 round keys are needed),
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/
/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
/*
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
*/
#define getSBoxValue(num) (sbox[(num)])
/*
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
*/
#define getSBoxInvert(num) (rsbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
for (i = 0; i < Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// All other round keys are found from the previous round keys.
for (i = Nk; i < Nb * (Nr + 1); ++i)
{
{
k = (i - 1) * 4;
tempa[0]=RoundKey[k + 0];
tempa[1]=RoundKey[k + 1];
tempa[2]=RoundKey[k + 2];
tempa[3]=RoundKey[k + 3];
}
if (i % Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
#if defined(AES256) && (AES256 == 1)
if (i % Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
j = i * 4; k=(i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
{
KeyExpansion(ctx->RoundKey, key);
}
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
{
KeyExpansion(ctx->RoundKey, key);
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
{
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
#endif
// This function adds the round key to state.
// The round key is added to the state by an XOR function.
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void SubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
static void ShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;
// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
static void MixColumns(state_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}
// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// Cipher is the main function that encrypts the PlainText.
static void Cipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(0, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without MixColumns()
for (round = 1; ; ++round)
{
SubBytes(state);
ShiftRows(state);
if (round == Nr) {
break;
}
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}
// Add round key to last round
AddRoundKey(Nr, state, RoundKey);
}
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static void InvCipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without InvMixColumn()
for (round = (Nr - 1); ; --round)
{
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(round, state, RoundKey);
if (round == 0) {
break;
}
InvMixColumns(state);
}
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES algorithm.
Cipher((state_t*)buf, ctx->RoundKey);
}
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES algorithm.
InvCipher((state_t*)buf, ctx->RoundKey);
}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
}
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t *Iv = ctx->Iv;
for (i = 0; i < length; i += AES_BLOCKLEN)
{
XorWithIv(buf, Iv);
Cipher((state_t*)buf, ctx->RoundKey);
Iv = buf;
buf += AES_BLOCKLEN;
}
/* store Iv in ctx for next call */
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uintptr_t i;
uint8_t storeNextIv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN)
{
memcpy(storeNextIv, buf, AES_BLOCKLEN);
InvCipher((state_t*)buf, ctx->RoundKey);
XorWithIv(buf, ctx->Iv);
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
buf += AES_BLOCKLEN;
}
}
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
{
uint8_t buffer[AES_BLOCKLEN];
unsigned i;
int bi;
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
{
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
{
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
Cipher((state_t*)buffer,ctx->RoundKey);
/* Increment Iv and handle overflow */
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
{
/* inc will overflow */
if (ctx->Iv[bi] == 255)
{
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += 1;
break;
}
bi = 0;
}
buf[i] = (buf[i] ^ buffer[bi]);
}
}
#endif // #if defined(CTR) && (CTR == 1)

View File

@ -0,0 +1,90 @@
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
#ifndef CTR
#define CTR 1
#endif
#define AES128 1
//#define AES192 1
//#define AES256 1
#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYLEN 24
#define AES_keyExpSize 208
#else
#define AES_KEYLEN 16 // Key length in bytes
#define AES_keyExpSize 176
#endif
struct AES_ctx
{
uint8_t RoundKey[AES_keyExpSize];
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
};
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length);
#endif // #if defined(CTR) && (CTR == 1)
#endif // _AES_H_

View File

@ -0,0 +1,12 @@
#ifndef _AES_HPP_
#define _AES_HPP_
#ifndef __cplusplus
#error Do not include the hpp header in a c project!
#endif //__cplusplus
extern "C" {
#include "aes.h"
}
#endif //_AES_HPP_

View File

@ -0,0 +1,375 @@
/* 7zTypes.h -- Basic types
2018-08-04 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#ifdef _WIN32
/* #include <windows.h> */
#endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else
typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int BoolInt;
/* typedef BoolInt Bool; */
#define True 1
#define False 0
#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_NO_INLINE
#define MY_FORCE_INLINE
#define MY_CDECL
#define MY_FAST_CALL
/* inline keyword : for C++ / C99 */
/* GCC, clang: */
/*
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline))
#endif
*/
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct IByteIn IByteIn;
struct IByteIn
{
Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
};
#define IByteIn_Read(p) (p)->Read(p)
typedef struct IByteOut IByteOut;
struct IByteOut
{
void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
};
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{
size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
};
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{
SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
};
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
typedef struct
{
ILookInStream vt;
const ISeekInStream *realStream;
size_t pos;
size_t size; /* it's data size */
/* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
typedef struct
{
ISeqInStream vt;
const ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream vt;
const ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct ICompressProgress ICompressProgress;
struct ICompressProgress
{
SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
};
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{
void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
};
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef MY_container_of
/*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
EXTERN_C_END
#endif

View File

@ -0,0 +1,451 @@
/* Alloc.c -- Memory allocation functions
2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Alloc.h"
//#include "gps/adaptation/icoe_adap.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
int g_allocCount = 0;
int g_allocCountMid = 0;
int g_allocCountBig = 0;
#define CONVERT_INT_TO_STR(charType, tempSize) \
unsigned char temp[tempSize]; unsigned i = 0; \
while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
*s++ = (charType)('0' + (unsigned)val); \
while (i != 0) { i--; *s++ = temp[i]; } \
*s = 0;
static void ConvertUInt64ToString(UInt64 val, char *s)
{
CONVERT_INT_TO_STR(char, 24);
}
#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
static void ConvertUInt64ToHex(UInt64 val, char *s)
{
UInt64 v = val;
unsigned i;
for (i = 1;; i++)
{
v >>= 4;
if (v == 0)
break;
}
s[i] = 0;
do
{
unsigned t = (unsigned)(val & 0xF);
val >>= 4;
s[--i] = GET_HEX_CHAR(t);
}
while (i);
}
#define DEBUG_OUT_STREAM stderr
static void Print(const char *s)
{
fputs(s, DEBUG_OUT_STREAM);
}
static void PrintAligned(const char *s, size_t align)
{
size_t len = strlen(s);
for(;;)
{
fputc(' ', DEBUG_OUT_STREAM);
if (len >= align)
break;
++len;
}
Print(s);
}
static void PrintLn()
{
Print("\n");
}
static void PrintHex(UInt64 v, size_t align)
{
char s[32];
ConvertUInt64ToHex(v, s);
PrintAligned(s, align);
}
static void PrintDec(UInt64 v, size_t align)
{
char s[32];
ConvertUInt64ToString(v, s);
PrintAligned(s, align);
}
static void PrintAddr(void *p)
{
PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
}
#define PRINT_ALLOC(name, cnt, size, ptr) \
Print(name " "); \
PrintDec(cnt++, 10); \
PrintHex(size, 10); \
PrintAddr(ptr); \
PrintLn();
#define PRINT_FREE(name, cnt, ptr) if (ptr) { \
Print(name " "); \
PrintDec(--cnt, 10); \
PrintAddr(ptr); \
PrintLn(); }
#else
#define PRINT_ALLOC(name, cnt, size, ptr)
#define PRINT_FREE(name, cnt, ptr)
#define Print(s)
#define PrintLn()
#define PrintHex(v, align)
#define PrintDec(v, align)
#define PrintAddr(p)
#endif
#if 0
void *MyAlloc(size_t size)
{
if (size == 0)
return NULL;
#ifdef _SZ_ALLOC_DEBUG
{
void *p = malloc(size);
PRINT_ALLOC("Alloc ", g_allocCount, size, p);
return p;
}
#else
// printf("MyAlloc %d \r\n",size);
return icoe_adap_mem_malloc(size);
#endif
}
void MyFree(void *address)
{
PRINT_FREE("Free ", g_allocCount, address);
icoe_adap_mem_free(address);
}
#endif
#if 0//def _WIN32
void *MidAlloc(size_t size)
{
if (size == 0)
return NULL;
PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
}
void MidFree(void *address)
{
PRINT_FREE("Free-Mid", g_allocCountMid, address);
if (!address)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#ifndef MEM_LARGE_PAGES
#undef _7ZIP_LARGE_PAGES
#endif
#ifdef _7ZIP_LARGE_PAGES
SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
#endif
void SetLargePageSize()
{
#ifdef _7ZIP_LARGE_PAGES
SIZE_T size;
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
if (!largePageMinimum)
return;
size = largePageMinimum();
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
#endif
}
void *BigAlloc(size_t size)
{
if (size == 0)
return NULL;
PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
#ifdef _7ZIP_LARGE_PAGES
{
SIZE_T ps = g_LargePageSize;
if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
{
size_t size2;
ps--;
size2 = (size + ps) & ~ps;
if (size2 >= size)
{
void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
if (res)
return res;
}
}
}
#endif
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
}
void BigFree(void *address)
{
PRINT_FREE("Free-Big", g_allocCountBig, address);
if (!address)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#endif
static void * SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
const ISzAlloc g_Alloc = { SzAlloc, SzFree };
#if 0//def _WIN32
static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#endif
/*
uintptr_t : <stdint.h> C99 (optional)
: unsupported in VS6
*/
#if 0//def _WIN32
typedef UINT_PTR UIntPtr;
#else
/*
typedef uintptr_t UIntPtr;
*/
typedef ptrdiff_t UIntPtr;
#endif
#define ADJUST_ALLOC_SIZE 0
/*
#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
*/
/*
Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
MyAlloc() can return address that is NOT multiple of sizeof(void *).
*/
/*
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
*/
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
#define USE_posix_memalign
#endif
/*
This posix_memalign() is for test purposes only.
We also need special Free() function instead of free(),
if this posix_memalign() is used.
*/
/*
static int posix_memalign(void **ptr, size_t align, size_t size)
{
size_t newSize = size + align;
void *p;
void *pAligned;
*ptr = NULL;
if (newSize < size)
return 12; // ENOMEM
p = MyAlloc(newSize);
if (!p)
return 12; // ENOMEM
pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
((void **)pAligned)[-1] = p;
*ptr = pAligned;
return 0;
}
*/
/*
ALLOC_ALIGN_SIZE >= sizeof(void *)
ALLOC_ALIGN_SIZE >= cache_line_size
*/
#define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
{
#ifndef USE_posix_memalign
void *p;
void *pAligned;
size_t newSize;
UNUSED_VAR(pp);
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
if (newSize < size)
return NULL;
p = MyAlloc(newSize);
if (!p)
return NULL;
pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(p);
Print(" a_ptr="); PrintAddr(pAligned);
PrintLn();
((void **)pAligned)[-1] = p;
return pAligned;
#else
void *p;
UNUSED_VAR(pp);
if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
return NULL;
Print(" posix_memalign="); PrintAddr(p);
PrintLn();
return p;
#endif
}
static void SzAlignedFree(ISzAllocPtr pp, void *address)
{
UNUSED_VAR(pp);
#ifndef USE_posix_memalign
if (address)
MyFree(((void **)address)[-1]);
#else
free(address);
#endif
}
const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
/*
#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
*/
static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
{
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
void *adr;
void *pAligned;
size_t newSize;
size_t extra;
size_t alignSize = (size_t)1 << p->numAlignBits;
if (alignSize < sizeof(void *))
alignSize = sizeof(void *);
if (p->offset >= alignSize)
return NULL;
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
extra = p->offset & (sizeof(void *) - 1);
newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
if (newSize < size)
return NULL;
adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
if (!adr)
return NULL;
pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
PrintLn();
Print("- Aligned: ");
Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(adr);
Print(" a_ptr="); PrintAddr(pAligned);
PrintLn();
REAL_BLOCK_PTR_VAR(pAligned) = adr;
return pAligned;
}
static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
{
if (address)
{
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
PrintLn();
Print("- Aligned Free: ");
PrintLn();
ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
}
}
#if 0
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
{
p->vt.Alloc = AlignOffsetAlloc_Alloc;
p->vt.Free = AlignOffsetAlloc_Free;
}
#endif

View File

@ -0,0 +1,451 @@
/* Alloc.c -- Memory allocation functions
2018-04-27 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Alloc.h"
//#include "gps/adaptation/icoe_adap.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
int g_allocCount = 0;
int g_allocCountMid = 0;
int g_allocCountBig = 0;
#define CONVERT_INT_TO_STR(charType, tempSize) \
unsigned char temp[tempSize]; unsigned i = 0; \
while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
*s++ = (charType)('0' + (unsigned)val); \
while (i != 0) { i--; *s++ = temp[i]; } \
*s = 0;
static void ConvertUInt64ToString(UInt64 val, char *s)
{
CONVERT_INT_TO_STR(char, 24);
}
#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
static void ConvertUInt64ToHex(UInt64 val, char *s)
{
UInt64 v = val;
unsigned i;
for (i = 1;; i++)
{
v >>= 4;
if (v == 0)
break;
}
s[i] = 0;
do
{
unsigned t = (unsigned)(val & 0xF);
val >>= 4;
s[--i] = GET_HEX_CHAR(t);
}
while (i);
}
#define DEBUG_OUT_STREAM stderr
static void Print(const char *s)
{
fputs(s, DEBUG_OUT_STREAM);
}
static void PrintAligned(const char *s, size_t align)
{
size_t len = strlen(s);
for(;;)
{
fputc(' ', DEBUG_OUT_STREAM);
if (len >= align)
break;
++len;
}
Print(s);
}
static void PrintLn()
{
Print("\n");
}
static void PrintHex(UInt64 v, size_t align)
{
char s[32];
ConvertUInt64ToHex(v, s);
PrintAligned(s, align);
}
static void PrintDec(UInt64 v, size_t align)
{
char s[32];
ConvertUInt64ToString(v, s);
PrintAligned(s, align);
}
static void PrintAddr(void *p)
{
PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
}
#define PRINT_ALLOC(name, cnt, size, ptr) \
Print(name " "); \
PrintDec(cnt++, 10); \
PrintHex(size, 10); \
PrintAddr(ptr); \
PrintLn();
#define PRINT_FREE(name, cnt, ptr) if (ptr) { \
Print(name " "); \
PrintDec(--cnt, 10); \
PrintAddr(ptr); \
PrintLn(); }
#else
#define PRINT_ALLOC(name, cnt, size, ptr)
#define PRINT_FREE(name, cnt, ptr)
#define Print(s)
#define PrintLn()
#define PrintHex(v, align)
#define PrintDec(v, align)
#define PrintAddr(p)
#endif
#if 0
void *MyAlloc(size_t size)
{
if (size == 0)
return NULL;
#ifdef _SZ_ALLOC_DEBUG
{
void *p = malloc(size);
PRINT_ALLOC("Alloc ", g_allocCount, size, p);
return p;
}
#else
// printf("MyAlloc %d \r\n",size);
return icoe_adap_mem_malloc(size);
#endif
}
void MyFree(void *address)
{
PRINT_FREE("Free ", g_allocCount, address);
icoe_adap_mem_free(address);
}
#endif
#if 0//def _WIN32
void *MidAlloc(size_t size)
{
if (size == 0)
return NULL;
PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
}
void MidFree(void *address)
{
PRINT_FREE("Free-Mid", g_allocCountMid, address);
if (!address)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#ifndef MEM_LARGE_PAGES
#undef _7ZIP_LARGE_PAGES
#endif
#ifdef _7ZIP_LARGE_PAGES
SIZE_T g_LargePageSize = 0;
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
#endif
void SetLargePageSize()
{
#ifdef _7ZIP_LARGE_PAGES
SIZE_T size;
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
if (!largePageMinimum)
return;
size = largePageMinimum();
if (size == 0 || (size & (size - 1)) != 0)
return;
g_LargePageSize = size;
#endif
}
void *BigAlloc(size_t size)
{
if (size == 0)
return NULL;
PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
#ifdef _7ZIP_LARGE_PAGES
{
SIZE_T ps = g_LargePageSize;
if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
{
size_t size2;
ps--;
size2 = (size + ps) & ~ps;
if (size2 >= size)
{
void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
if (res)
return res;
}
}
}
#endif
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
}
void BigFree(void *address)
{
PRINT_FREE("Free-Big", g_allocCountBig, address);
if (!address)
return;
VirtualFree(address, 0, MEM_RELEASE);
}
#endif
static void * SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
const ISzAlloc g_Alloc = { SzAlloc, SzFree };
#if 0//def _WIN32
static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
#endif
/*
uintptr_t : <stdint.h> C99 (optional)
: unsupported in VS6
*/
#if 0//def _WIN32
typedef UINT_PTR UIntPtr;
#else
/*
typedef uintptr_t UIntPtr;
*/
typedef ptrdiff_t UIntPtr;
#endif
#define ADJUST_ALLOC_SIZE 0
/*
#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
*/
/*
Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
MyAlloc() can return address that is NOT multiple of sizeof(void *).
*/
/*
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
*/
#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
#define USE_posix_memalign
#endif
/*
This posix_memalign() is for test purposes only.
We also need special Free() function instead of free(),
if this posix_memalign() is used.
*/
/*
static int posix_memalign(void **ptr, size_t align, size_t size)
{
size_t newSize = size + align;
void *p;
void *pAligned;
*ptr = NULL;
if (newSize < size)
return 12; // ENOMEM
p = MyAlloc(newSize);
if (!p)
return 12; // ENOMEM
pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
((void **)pAligned)[-1] = p;
*ptr = pAligned;
return 0;
}
*/
/*
ALLOC_ALIGN_SIZE >= sizeof(void *)
ALLOC_ALIGN_SIZE >= cache_line_size
*/
#define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
{
#ifndef USE_posix_memalign
void *p;
void *pAligned;
size_t newSize;
UNUSED_VAR(pp);
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
if (newSize < size)
return NULL;
p = MyAlloc(newSize);
if (!p)
return NULL;
pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(p);
Print(" a_ptr="); PrintAddr(pAligned);
PrintLn();
((void **)pAligned)[-1] = p;
return pAligned;
#else
void *p;
UNUSED_VAR(pp);
if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
return NULL;
Print(" posix_memalign="); PrintAddr(p);
PrintLn();
return p;
#endif
}
static void SzAlignedFree(ISzAllocPtr pp, void *address)
{
UNUSED_VAR(pp);
#ifndef USE_posix_memalign
if (address)
MyFree(((void **)address)[-1]);
#else
free(address);
#endif
}
const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
/*
#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
*/
static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
{
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
void *adr;
void *pAligned;
size_t newSize;
size_t extra;
size_t alignSize = (size_t)1 << p->numAlignBits;
if (alignSize < sizeof(void *))
alignSize = sizeof(void *);
if (p->offset >= alignSize)
return NULL;
/* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
block to prevent cache line sharing with another allocated blocks */
extra = p->offset & (sizeof(void *) - 1);
newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
if (newSize < size)
return NULL;
adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
if (!adr)
return NULL;
pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
PrintLn();
Print("- Aligned: ");
Print(" size="); PrintHex(size, 8);
Print(" a_size="); PrintHex(newSize, 8);
Print(" ptr="); PrintAddr(adr);
Print(" a_ptr="); PrintAddr(pAligned);
PrintLn();
REAL_BLOCK_PTR_VAR(pAligned) = adr;
return pAligned;
}
static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
{
if (address)
{
CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
PrintLn();
Print("- Aligned Free: ");
PrintLn();
ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
}
}
#if 0
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
{
p->vt.Alloc = AlignOffsetAlloc_Alloc;
p->vt.Free = AlignOffsetAlloc_Free;
}
#endif

View File

@ -0,0 +1,51 @@
/* Alloc.h -- Memory allocation functions
2018-02-19 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
void *MyAlloc(size_t size);
void MyFree(void *address);
#if 0//def _WIN32
void SetLargePageSize();
void *MidAlloc(size_t size);
void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
#else
#define MidAlloc(size) MyAlloc(size)
#define MidFree(address) MyFree(address)
#define BigAlloc(size) MyAlloc(size)
#define BigFree(address) MyFree(address)
#endif
extern const ISzAlloc g_Alloc;
extern const ISzAlloc g_BigAlloc;
extern const ISzAlloc g_MidAlloc;
extern const ISzAlloc g_AlignedAlloc;
typedef struct
{
ISzAlloc vt;
ISzAllocPtr baseAlloc;
unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
} CAlignOffsetAlloc;
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
EXTERN_C_END
#endif

View File

@ -0,0 +1,33 @@
/* Compiler.h
2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
#ifdef _MSC_VER
#ifdef UNDER_CE
#define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
#endif
#if _MSC_VER >= 1300
#pragma warning(disable : 4996) // This function or variable may be unsafe
#else
#pragma warning(disable : 4511) // copy constructor could not be generated
#pragma warning(disable : 4512) // assignment operator could not be generated
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif

View File

@ -0,0 +1,234 @@
/* LzmaDec.h -- LZMA Decoder
2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
typedef
#ifdef _LZMA_PROB32
UInt32
#else
UInt16
#endif
CLzmaProb;
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
Byte lc;
Byte lp;
Byte pb;
Byte _pad_;
UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
/* Don't change this structure. ASM code can use it. */
CLzmaProps prop;
CLzmaProb *probs;
CLzmaProb *probs_1664;
Byte *dic;
SizeT dicBufSize;
SizeT dicPos;
const Byte *buf;
UInt32 range;
UInt32 code;
UInt32 processedPos;
UInt32 checkDicSize;
UInt32 reps[4];
UInt32 state;
UInt32 remainLen;
UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
- Stream with end mark. That end mark adds about 6 bytes to compressed size.
- Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Construct()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END
#endif

View File

@ -0,0 +1,76 @@
/* LzmaEnc.h -- LZMA Encoder
2017-07-27 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaEncProps
{
int level; /* 0 <= level <= 9 */
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (3 << 29) for 64-bit version
default = (1 << 24) */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
int algo; /* 0 - fast, 1 - normal, default = 1 */
int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
Encoder uses this value to reduce dictionary size */
} CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p);
void LzmaEncProps_Normalize(CLzmaEncProps *p);
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc* functions can return the following exit codes:
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/
typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
/* ---------- One Call Interface ---------- */
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
EXTERN_C_END
#endif

View File

@ -0,0 +1,10 @@
/* Precomp.h -- StdAfx
2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "Compiler.h"
/* #include "7zTypes.h" */
#endif

View File

@ -0,0 +1,28 @@
The lib_lzma functionality was written by Igor Pavlov.
The original source cames from the LZMA SDK web page:
URL: http://www.7-zip.org/sdk.html
Author: Igor Pavlov
The import is made using the import_lzmasdk.sh script that:
* untars the lzmaXYY.tar.bz2 file (from the download web page)
* copies the files LzmaDec.h, Types.h, LzmaDec.c, history.txt,
and lzma.txt from source archive into the lib_lzma directory (pwd).
Example:
. import_lzmasdk.sh ~/lzma465.tar.bz2
Notice: The files from lzma sdk are _not modified_ by this script!
The files LzmaTools.{c,h} are provided to export the lzmaBuffToBuffDecompress()
function that wraps the complex LzmaDecode() function from the LZMA SDK. The
do_bootm() function uses the lzmaBuffToBuffDecopress() function to expand the
compressed image.
The directory U-BOOT/include/lzma contains stubs files that permit to use the
library directly from U-BOOT code without touching the original LZMA SDK's
files.
Luigi 'Comio' Mantellini <luigi.mantellini@idf-hit.com>

View File

@ -0,0 +1,234 @@
/* Types.h -- Basic types
2010-10-09 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#include <stddef.h>
#ifdef _WIN32
#include <windows.h>
#endif
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _WIN32
typedef DWORD WRes;
#else
typedef int WRes;
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_CDECL
#define MY_FAST_CALL
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct
{
SRes (*Look)(void *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ILookInStream;
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
size_t pos;
size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR u'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR u"/"
#endif
#endif

View File

@ -0,0 +1,271 @@
HISTORY of the LZMA SDK
-----------------------
9.18 beta 2010-11-02
-------------------------
- New small SFX module for installers (SfxSetup).
9.12 beta 2010-03-24
-------------------------
- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
if more than 10 threads were used (or more than 20 threads in some modes).
9.11 beta 2010-03-15
-------------------------
- PPMd compression method support
9.09 2009-12-12
-------------------------
- The bug was fixed:
Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
- Some bugs were fixed
9.06 2009-08-17
-------------------------
- Some changes in ANSI-C 7z Decoder interfaces.
9.04 2009-05-30
-------------------------
- LZMA2 compression method support
- xz format support
4.65 2009-02-03
-------------------------
- Some minor fixes
4.63 2008-12-31
-------------------------
- Some minor fixes
4.61 beta 2008-11-23
-------------------------
- The bug in ANSI-C LZMA Decoder was fixed:
If encoded stream was corrupted, decoder could access memory
outside of allocated range.
- Some changes in ANSI-C 7z Decoder interfaces.
- LZMA SDK is placed in the public domain.
4.60 beta 2008-08-19
-------------------------
- Some minor fixes.
4.59 beta 2008-08-13
-------------------------
- The bug was fixed:
LZMA Encoder in fast compression mode could access memory outside of
allocated range in some rare cases.
4.58 beta 2008-05-05
-------------------------
- ANSI-C LZMA Decoder was rewritten for speed optimizations.
- ANSI-C LZMA Encoder was included to LZMA SDK.
- C++ LZMA code now is just wrapper over ANSI-C code.
4.57 2007-12-12
-------------------------
- Speed optimizations in Ñ++ LZMA Decoder.
- Small changes for more compatibility with some C/C++ compilers.
4.49 beta 2007-07-05
-------------------------
- .7z ANSI-C Decoder:
- now it supports BCJ and BCJ2 filters
- now it supports files larger than 4 GB.
- now it supports "Last Write Time" field for files.
- C++ code for .7z archives compressing/decompressing from 7-zip
was included to LZMA SDK.
4.43 2006-06-04
-------------------------
- Small changes for more compatibility with some C/C++ compilers.
4.42 2006-05-15
-------------------------
- Small changes in .h files in ANSI-C version.
4.39 beta 2006-04-14
-------------------------
- The bug in versions 4.33b:4.38b was fixed:
C++ version of LZMA encoder could not correctly compress
files larger than 2 GB with HC4 match finder (-mfhc4).
4.37 beta 2005-04-06
-------------------------
- Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined.
4.35 beta 2005-03-02
-------------------------
- The bug was fixed in C++ version of LZMA Decoder:
If encoded stream was corrupted, decoder could access memory
outside of allocated range.
4.34 beta 2006-02-27
-------------------------
- Compressing speed and memory requirements for compressing were increased
- LZMA now can use only these match finders: HC4, BT2, BT3, BT4
4.32 2005-12-09
-------------------------
- Java version of LZMA SDK was included
4.30 2005-11-20
-------------------------
- Compression ratio was improved in -a2 mode
- Speed optimizations for compressing in -a2 mode
- -fb switch now supports values up to 273
- The bug in 7z_C (7zIn.c) was fixed:
It used Alloc/Free functions from different memory pools.
So if program used two memory pools, it worked incorrectly.
- 7z_C: .7z format supporting was improved
- LZMA# SDK (C#.NET version) was included
4.27 (Updated) 2005-09-21
-------------------------
- Some GUIDs/interfaces in C++ were changed.
IStream.h:
ISequentialInStream::Read now works as old ReadPart
ISequentialOutStream::Write now works as old WritePart
4.27 2005-08-07
-------------------------
- The bug in LzmaDecodeSize.c was fixed:
if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
decompressing worked incorrectly.
4.26 2005-08-05
-------------------------
- Fixes in 7z_C code and LzmaTest.c:
previous versions could work incorrectly,
if malloc(0) returns 0
4.23 2005-06-29
-------------------------
- Small fixes in C++ code
4.22 2005-06-10
-------------------------
- Small fixes
4.21 2005-06-08
-------------------------
- Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
- New additional version of ANSI-C LZMA Decoder with zlib-like interface:
- LzmaStateDecode.h
- LzmaStateDecode.c
- LzmaStateTest.c
- ANSI-C LZMA Decoder now can decompress files larger than 4 GB
4.17 2005-04-18
-------------------------
- New example for RAM->RAM compressing/decompressing:
LZMA + BCJ (filter for x86 code):
- LzmaRam.h
- LzmaRam.cpp
- LzmaRamDecode.h
- LzmaRamDecode.c
- -f86 switch for lzma.exe
4.16 2005-03-29
-------------------------
- The bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder):
If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
decoder could access memory outside of allocated range.
- Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
Old version of LZMA Decoder now is in file LzmaDecodeSize.c.
LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
- Small speed optimization in LZMA C++ code
- filter for SPARC's code was added
- Simplified version of .7z ANSI-C Decoder was included
4.06 2004-09-05
-------------------------
- The bug in v4.05 was fixed:
LZMA-Encoder didn't release output stream in some cases.
4.05 2004-08-25
-------------------------
- Source code of filters for x86, IA-64, ARM, ARM-Thumb
and PowerPC code was included to SDK
- Some internal minor changes
4.04 2004-07-28
-------------------------
- More compatibility with some C++ compilers
4.03 2004-06-18
-------------------------
- "Benchmark" command was added. It measures compressing
and decompressing speed and shows rating values.
Also it checks hardware errors.
4.02 2004-06-10
-------------------------
- C++ LZMA Encoder/Decoder code now is more portable
and it can be compiled by GCC on Linux.
4.01 2004-02-15
-------------------------
- Some detection of data corruption was enabled.
LzmaDecode.c / RangeDecoderReadByte
.....
{
rd->ExtraBytes = 1;
return 0xFF;
}
4.00 2004-02-13
-------------------------
- Original version of LZMA SDK
HISTORY of the LZMA
-------------------
2001-2008: Improvements to LZMA compressing/decompressing code,
keeping compatibility with original LZMA format
1996-2001: Development of LZMA compression format
Some milestones:
2001-08-30: LZMA compression was added to 7-Zip
1999-01-02: First version of 7-Zip was released
End of document

View File

@ -0,0 +1,36 @@
#!/bin/sh
usage() {
echo "Usage: $0 lzmaVERSION.tar.bz2" >&2
echo >&2
exit 1
}
if [ "$1" = "" ] ; then
usage
fi
if [ ! -f $1 ] ; then
echo "$1 doesn't exist!" >&2
exit 1
fi
BASENAME=`basename $1 .tar.bz2`
TMPDIR=/tmp/tmp_lib_$BASENAME
FILES="C/LzmaDec.h
C/Types.h
C/LzmaDec.c
history.txt
lzma.txt"
mkdir -p $TMPDIR
echo "Untar $1 -> $TMPDIR"
tar -jxf $1 -C $TMPDIR
for i in $FILES; do
echo Copying $TMPDIR/$i \-\> `basename $i`
cp $TMPDIR/$i .
chmod -x `basename $i`
done
echo "done!"

View File

@ -0,0 +1,3 @@
License
LZMA SDK is placed in the public domain.

View File

@ -0,0 +1,598 @@
LZMA SDK 9.20
-------------
LZMA SDK provides the documentation, samples, header files, libraries,
and tools you need to develop applications that use LZMA compression.
LZMA is default and general compression method of 7z format
in 7-Zip compression program (www.7-zip.org). LZMA provides high
compression ratio and very fast decompression.
LZMA is an improved version of famous LZ77 compression algorithm.
It was improved in way of maximum increasing of compression ratio,
keeping high decompression speed and low memory requirements for
decompressing.
LICENSE
-------
LZMA SDK is written and placed in the public domain by Igor Pavlov.
Some code in LZMA SDK is based on public domain code from another developers:
1) PPMd var.H (2001): Dmitry Shkarin
2) SHA-256: Wei Dai (Crypto++ library)
LZMA SDK Contents
-----------------
LZMA SDK includes:
- ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing
- Compiled file->file LZMA compressing/decompressing program for Windows system
UNIX/Linux version
------------------
To compile C++ version of file->file LZMA encoding, go to directory
CPP/7zip/Bundles/LzmaCon
and call make to recompile it:
make -f makefile.gcc clean all
In some UNIX/Linux versions you must compile LZMA with static libraries.
To compile with static libraries, you can use
LIB = -lm -static
Files
---------------------
lzma.txt - LZMA SDK description (this file)
7zFormat.txt - 7z Format description
7zC.txt - 7z ANSI-C Decoder description
methods.txt - Compression method IDs for .7z
lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
7zr.exe - 7-Zip with 7z/lzma/xz support.
history.txt - history of the LZMA SDK
Source code structure
---------------------
C/ - C files
7zCrc*.* - CRC code
Alloc.* - Memory allocation functions
Bra*.* - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
LzFind.* - Match finder for LZ (LZMA) encoders
LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding
LzHash.h - Additional file for LZ match finder
LzmaDec.* - LZMA decoding
LzmaEnc.* - LZMA encoding
LzmaLib.* - LZMA Library for DLL calling
Types.h - Basic types for another .c files
Threads.* - The code for multithreading.
LzmaLib - LZMA Library (.DLL for Windows)
LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder).
Archive - files related to archiving
7z - 7z ANSI-C Decoder
CPP/ -- CPP files
Common - common files for C++ projects
Windows - common files for Windows related code
7zip - files related to 7-Zip Project
Common - common files for 7-Zip
Compress - files related to compression/decompression
Archive - files related to archiving
Common - common files for archive handling
7z - 7z C++ Encoder/Decoder
Bundles - Modules that are bundles of other modules
Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
LzmaCon - lzma.exe: LZMA compression/decompression
Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
UI - User Interface files
Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll
Common - Common UI files
Console - Code for console archiver
CS/ - C# files
7zip
Common - some common files for 7-Zip
Compress - files related to compression/decompression
LZ - files related to LZ (Lempel-Ziv) compression algorithm
LZMA - LZMA compression/decompression
LzmaAlone - file->file LZMA compression/decompression
RangeCoder - Range Coder (special code of compression/decompression)
Java/ - Java files
SevenZip
Compression - files related to compression/decompression
LZ - files related to LZ (Lempel-Ziv) compression algorithm
LZMA - LZMA compression/decompression
RangeCoder - Range Coder (special code of compression/decompression)
C/C++ source code of LZMA SDK is part of 7-Zip project.
7-Zip source code can be downloaded from 7-Zip's SourceForge page:
http://sourceforge.net/projects/sevenzip/
LZMA features
-------------
- Variable dictionary size (up to 1 GB)
- Estimated compressing speed: about 2 MB/s on 2 GHz CPU
- Estimated decompressing speed:
- 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64
- 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC
- Small memory requirements for decompressing (16 KB + DictionarySize)
- Small code size for decompressing: 5-8 KB
LZMA decoder uses only integer operations and can be
implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
Some critical operations that affect the speed of LZMA decompression:
1) 32*16 bit integer multiply
2) Misspredicted branches (penalty mostly depends from pipeline length)
3) 32-bit shift and arithmetic operations
The speed of LZMA decompressing mostly depends from CPU speed.
Memory speed has no big meaning. But if your CPU has small data cache,
overall weight of memory speed will slightly increase.
How To Use
----------
Using LZMA encoder/decoder executable
--------------------------------------
Usage: LZMA <e|d> inputFile outputFile [<switches>...]
e: encode file
d: decode file
b: Benchmark. There are two tests: compressing and decompressing
with LZMA method. Benchmark shows rating in MIPS (million
instructions per second). Rating value is calculated from
measured speed and it is normalized with Intel's Core 2 results.
Also Benchmark checks possible hardware errors (RAM
errors in most cases). Benchmark uses these settings:
(-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.
Also you can change the number of iterations. Example for 30 iterations:
LZMA b 30
Default number of iterations is 10.
<Switches>
-a{N}: set compression mode 0 = fast, 1 = normal
default: 1 (normal)
d{N}: Sets Dictionary size - [0, 30], default: 23 (8MB)
The maximum value for dictionary size is 1 GB = 2^30 bytes.
Dictionary size is calculated as DictionarySize = 2^N bytes.
For decompressing file compressed by LZMA method with dictionary
size D = 2^N you need about D bytes of memory (RAM).
-fb{N}: set number of fast bytes - [5, 273], default: 128
Usually big number gives a little bit better compression ratio
and slower compression process.
-lc{N}: set number of literal context bits - [0, 8], default: 3
Sometimes lc=4 gives gain for big files.
-lp{N}: set number of literal pos bits - [0, 4], default: 0
lp switch is intended for periodical data when period is
equal 2^N. For example, for 32-bit (4 bytes)
periodical data you can use lp=2. Often it's better to set lc0,
if you change lp switch.
-pb{N}: set number of pos bits - [0, 4], default: 2
pb switch is intended for periodical data
when period is equal 2^N.
-mf{MF_ID}: set Match Finder. Default: bt4.
Algorithms from hc* group doesn't provide good compression
ratio, but they often works pretty fast in combination with
fast mode (-a0).
Memory requirements depend from dictionary size
(parameter "d" in table below).
MF_ID Memory Description
bt2 d * 9.5 + 4MB Binary Tree with 2 bytes hashing.
bt3 d * 11.5 + 4MB Binary Tree with 3 bytes hashing.
bt4 d * 11.5 + 4MB Binary Tree with 4 bytes hashing.
hc4 d * 7.5 + 4MB Hash Chain with 4 bytes hashing.
-eos: write End Of Stream marker. By default LZMA doesn't write
eos marker, since LZMA decoder knows uncompressed size
stored in .lzma file header.
-si: Read data from stdin (it will write End Of Stream marker).
-so: Write data to stdout
Examples:
1) LZMA e file.bin file.lzma -d16 -lc0
compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)
and 0 literal context bits. -lc0 allows to reduce memory requirements
for decompression.
2) LZMA e file.bin file.lzma -lc0 -lp2
compresses file.bin to file.lzma with settings suitable
for 32-bit periodical data (for example, ARM or MIPS code).
3) LZMA d file.lzma file.bin
decompresses file.lzma to file.bin.
Compression ratio hints
-----------------------
Recommendations
---------------
To increase the compression ratio for LZMA compressing it's desirable
to have aligned data (if it's possible) and also it's desirable to locate
data in such order, where code is grouped in one place and data is
grouped in other place (it's better than such mixing: code, data, code,
data, ...).
Filters
-------
You can increase the compression ratio for some data types, using
special filters before compressing. For example, it's possible to
increase the compression ratio on 5-10% for code for those CPU ISAs:
x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
You can find C source code of such filters in C/Bra*.* files
You can check the compression ratio gain of these filters with such
7-Zip commands (example for ARM code):
No filter:
7z a a1.7z a.bin -m0=lzma
With filter for little-endian ARM code:
7z a a2.7z a.bin -m0=arm -m1=lzma
It works in such manner:
Compressing = Filter_encoding + LZMA_encoding
Decompressing = LZMA_decoding + Filter_decoding
Compressing and decompressing speed of such filters is very high,
so it will not increase decompressing time too much.
Moreover, it reduces decompression time for LZMA_decoding,
since compression ratio with filtering is higher.
These filters convert CALL (calling procedure) instructions
from relative offsets to absolute addresses, so such data becomes more
compressible.
For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
LZMA compressed file format
---------------------------
Offset Size Description
0 1 Special LZMA properties (lc,lp, pb in encoded form)
1 4 Dictionary size (little endian)
5 8 Uncompressed size (little endian). -1 means unknown size
13 Compressed data
ANSI-C LZMA Decoder
~~~~~~~~~~~~~~~~~~~
Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58.
If you want to use old interfaces you can download previous version of LZMA SDK
from sourceforge.net site.
To use ANSI-C LZMA Decoder you need the following files:
1) LzmaDec.h + LzmaDec.c + Types.h
LzmaUtil/LzmaUtil.c is example application that uses these files.
Memory requirements for LZMA decoding
-------------------------------------
Stack usage of LZMA decoding function for local variables is not
larger than 200-400 bytes.
LZMA Decoder uses dictionary buffer and internal state structure.
Internal state structure consumes
state_size = (4 + (1.5 << (lc + lp))) KB
by default (lc=3, lp=0), state_size = 16 KB.
How To decompress data
----------------------
LZMA Decoder (ANSI-C version) now supports 2 interfaces:
1) Single-call Decompressing
2) Multi-call State Decompressing (zlib-like interface)
You must use external allocator:
Example:
void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
void SzFree(void *p, void *address) { p = p; free(address); }
ISzAlloc alloc = { SzAlloc, SzFree };
You can use p = p; operator to disable compiler warnings.
Single-call Decompressing
-------------------------
When to use: RAM->RAM decompressing
Compile files: LzmaDec.h + LzmaDec.c + Types.h
Compile defines: no defines
Memory Requirements:
- Input buffer: compressed size
- Output buffer: uncompressed size
- LZMA Internal Structures: state_size (16 KB for default settings)
Interface:
int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
In:
dest - output data
destLen - output data size
src - input data
srcLen - input data size
propData - LZMA properties (5 bytes)
propSize - size of propData buffer (5 bytes)
finishMode - It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
You can use LZMA_FINISH_END, when you know that
current output buffer covers last bytes of stream.
alloc - Memory allocator.
Out:
destLen - processed output size
srcLen - processed input size
Output:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
If LZMA decoder sees end_marker before reaching output limit, it returns OK result,
and output value of destLen will be less than output buffer size limit.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
Multi-call State Decompressing (zlib-like interface)
----------------------------------------------------
When to use: file->file decompressing
Compile files: LzmaDec.h + LzmaDec.c + Types.h
Memory Requirements:
- Buffer for input stream: any size (for example, 16 KB)
- Buffer for output stream: any size (for example, 16 KB)
- LZMA Internal Structures: state_size (16 KB for default settings)
- LZMA dictionary (dictionary size is encoded in LZMA properties header)
1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header:
unsigned char header[LZMA_PROPS_SIZE + 8];
ReadFile(inFile, header, sizeof(header)
2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties
CLzmaDec state;
LzmaDec_Constr(&state);
res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
if (res != SZ_OK)
return res;
3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop
LzmaDec_Init(&state);
for (;;)
{
...
int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
...
}
4) Free all allocated structures
LzmaDec_Free(&state, &g_Alloc);
For full code example, look at C/LzmaUtil/LzmaUtil.c code.
How To compress data
--------------------
Compile files: LzmaEnc.h + LzmaEnc.c + Types.h +
LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h
Memory Requirements:
- (dictSize * 11.5 + 6 MB) + state_size
Lzma Encoder can use two memory allocators:
1) alloc - for small arrays.
2) allocBig - for big arrays.
For example, you can use Large RAM Pages (2 MB) in allocBig allocator for
better compression speed. Note that Windows has bad implementation for
Large RAM Pages.
It's OK to use same allocator for alloc and allocBig.
Single-call Compression with callbacks
--------------------------------------
Check C/LzmaUtil/LzmaUtil.c as example,
When to use: file->file decompressing
1) you must implement callback structures for interfaces:
ISeqInStream
ISeqOutStream
ICompressProgress
ISzAlloc
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
CFileSeqInStream inStream;
CFileSeqOutStream outStream;
inStream.funcTable.Read = MyRead;
inStream.file = inFile;
outStream.funcTable.Write = MyWrite;
outStream.file = outFile;
2) Create CLzmaEncHandle object;
CLzmaEncHandle enc;
enc = LzmaEnc_Create(&g_Alloc);
if (enc == 0)
return SZ_ERROR_MEM;
3) initialize CLzmaEncProps properties;
LzmaEncProps_Init(&props);
Then you can change some properties in that structure.
4) Send LZMA properties to LZMA Encoder
res = LzmaEnc_SetProps(enc, &props);
5) Write encoded properties to header
Byte header[LZMA_PROPS_SIZE + 8];
size_t headerSize = LZMA_PROPS_SIZE;
UInt64 fileSize;
int i;
res = LzmaEnc_WriteProperties(enc, header, &headerSize);
fileSize = MyGetFileLength(inFile);
for (i = 0; i < 8; i++)
header[headerSize++] = (Byte)(fileSize >> (8 * i));
MyWriteFileAndCheck(outFile, header, headerSize)
6) Call encoding function:
res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
NULL, &g_Alloc, &g_Alloc);
7) Destroy LZMA Encoder Object
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
If callback function return some error code, LzmaEnc_Encode also returns that code
or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
Single-call RAM->RAM Compression
--------------------------------
Single-call RAM->RAM Compression is similar to Compression with callbacks,
but you provide pointers to buffers instead of pointers to stream callbacks:
HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
Return code:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
Defines
-------
_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for
some structures will be doubled in that case.
_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit.
_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
C++ LZMA Encoder/Decoder
~~~~~~~~~~~~~~~~~~~~~~~~
C++ LZMA code use COM-like interfaces. So if you want to use it,
you can study basics of COM/OLE.
C++ LZMA code is just wrapper over ANSI-C code.
C++ Notes
~~~~~~~~~~~~~~~~~~~~~~~~
If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling),
you must check that you correctly work with "new" operator.
7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator.
So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator:
operator new(size_t size)
{
void *p = ::malloc(size);
if (p == 0)
throw CNewException();
return p;
}
If you use MSCV that throws exception for "new" operator, you can compile without
"NewHandler.cpp". So standard exception will be used. Actually some code of
7-Zip catches any exception in internal code and converts it to HRESULT code.
So you don't need to catch CNewException, if you call COM interfaces of 7-Zip.
---
http://www.7-zip.org
http://www.7-zip.org/sdk.html
http://www.7-zip.org/support.html

View File

@ -0,0 +1,92 @@
/************************************************************************
* Copyright © 2022, ICOE (Shanghai) Technologies Co.,Ltd. All rights reserved. *
* Information in this document is provided in connection with ICOEs products. *
* No license, express or implied, by estoppels or otherwise, to any intellectual property *
* rights is granted by this document. Except as provided in ICOEs Terms and *
* Conditions of Sale for such products, ICOE assumes no liability whatsoever, and *
* ICOE disclaims any express or implied warranty, relating to sale and/or use of *
* ICOE products including liability or warranties relating to fitness for a particular *
* purpose, merchantability, or infringement of any patent, copyright or other *
* intellectual property right. ICOE products are not intended for use in medical, life *
* saving, or life sustaining applications. *
* ICOE (Shanghai) Technologies Co.,Ltd may make changes to specifications and *
* product descriptions at any time, without notice. *
* You may obtain copies of documents which have a document number and are *
* referenced in this document, or other ICOE literature may be obtained by *
* mailing to xiaopingjiang@icoe-tech.com. *
************************************************************************/
#ifndef _ICOE_OFFLINE_EPH_H_
#define _ICOE_OFFLINE_EPH_H_
#include "RXN_structs.h"
/*
* gps seed start address in flash
*/
#define RXN_GPS_OFFLINE_EPH_ADDRESS (0x3000000)
#if 0
/*
* below address should consider the align of address, such as 4Bytes or 8Bytes align,
*/
/*
* qzss seed start address in flash
*/
#define RXN_QZSS_OFFLIE_EPH (RXN_GPS_OFFLIE_EPH + RXN_GPS_OFFLIE_EPH_SIZE)
/*
* bds seed start address in flash
*/
#define RXN_BDS_OFFLIE_EPH (RXN_QZSS_OFFLIE_EPH + RXN_QZSS_OFFLIE_EPH_SIZE)
/*
* gal seed start address in flash
*/
#define RXN_GAL_OFFLIE_EPH (RXN_BDS_OFFLIE_EPH + RXN_BDS_OFFLIE_EPH_SIZE)
#endif
/*
* load key and initialize AES
*
* the key should be the same as the one used to fetch seed(such as file pred_gps) from server
*
* @Parameter: name - type, description
* customerKey - in, pointer to the NULL terminated char array
* @return:
* 0 : success
* -1: Failed
*/
int icoe_offline_eph_init( unsigned char * customerKey);
/*
* icoe_extract_offline_eph
*
* extract eph from seed file which located in address
*
* @Parameter: name - type, description
* constel - in, specified the constellation of seed
* address - in, pointer to the seed file located in memory
* time - in, use the time specified to extract the interested ephemeris
* rtcmData - in & out, pointer to the buffer used to store the ephemeris
* length - in & out, provide the length of eph file size and point out pointer used to store the length of Ephemeris
* @return:
* 0 : success
* -1: Failed
*/
int icoe_extract_offline_eph( RXN_constel_t constel, char* address,\
unsigned int time, unsigned char * rtcmData, unsigned int * length);
int icoe_extract_offline_eph_Ex(RXN_constel_t constel, char *address,
unsigned int utc_time, unsigned char *rtcmData, unsigned int *length);
unsigned int RXN_Get_Ephemer_Available_Time(RXN_constel_t constel,unsigned int utctime,char *address,unsigned int filesize);
#endif //_ICOE_OFFLINE_EPH_H_

View File

@ -0,0 +1,591 @@
#include "bsp.h"
#include "sk_comm.h"
#include "sk_main.h"
#include "gpio.h"
#include "gps_uart_read.h"
#include "sk_location.h"
#include "icoe_gps.h"
#include "icoe_adap.h"
#include "icoe_gnss_nmea.h"
#include "RXN_Api.h"
#include "psram.h"
#include "HTTPClient.h"
#include "icoe_offline_eph.h"
#define GPS_EN_GPIO_INSTANCE (1)
#define GPS_EN_GPIO_PIN (8)
#define GPS_EN_PAD_INDEX (49)
#define GPS_EN_PAD_ALT_FUNC (PAD_MUX_ALT0)
#define GPIO_OUTPUT_SET_High(instance, pin) GPIO_pinWrite(instance, 1 << (pin), 1 << (pin))
#define GPIO_OUTPUT_SET_Low(instance, pin) GPIO_pinWrite(instance, 1 << (pin), 0)
// #define GPIO_CFG_Input(instance,pin) GPIO_pinWrite(instance, 1 << (pin), 0)
#define GPIO_Read(instance, pin) GPIO_pinRead(instance, pin)
#define GPS_UART_READ_Buf_MaxLen (1024)
#define GPS_UART_TASK_STACK_SIZE (8*1024)
#define GPS_UART_TASK_QUEUE_SIZE (10)
#define GPS_BOOTLOAD_PKG_NAME "/O/CC11_Bootloader.pkg"
#define GPS_FIRMWARE_PKG_NAME "/O/CC1165W_Firmware.pkg"
#define HTTP_GET_URL_Maxlen 100
#define GPS_UART_RX_IO_MODE RTE_UART1_RX_IO_MODE
#define GPS_UART_TX_IO_MODE RTE_UART1_TX_IO_MODE
#define HTTP_RECV_BUF_SIZE (6000+1)
#define HTTP_HEAD_BUF_SIZE (800)
#define HTTP_GET_URL_Maxlen 100
#define PGL_DATA_Maxlen (80*1024)
#define RTCM_DATA_Buflen (20*4096)
typedef enum
{
E_GPS_State_init,
E_GPS_State_downloading,
E_GPS_State_check_version,
E_GPS_State_locate_once, //单次定位
E_GPS_State_locate_continue, //持续定位
E_GPS_State_stop,
E_GPS_State_max
}Enum_Gps_State;
UINT8 http_recvBuf[HTTP_RECV_BUF_SIZE];
char pgl_data[PGL_DATA_Maxlen] = {0};
//UINT8 pgl_data_ex[PGL_DATA_Maxlen];
//PLAT_FPSRAM_ZI_CUST UINT8 pgl_data_ex[PGL_DATA_Maxlen] = {0};
UINT32 pgl_len = 0;
//static UINT8 rtcm_data[MSL_MAX_RTCM_DATA_SIZE] = {0};
//static UINT8 rtcm_data[4096] = {0};
//UINT32 rtcm_len = 4096;
UINT8 rtcm_data[RTCM_DATA_Buflen] = {0};
UINT32 rtcm_len = RTCM_DATA_Buflen;
static HttpClientContext gHttpClient = {0};
extern ARM_DRIVER_USART Driver_USART1;
static ARM_DRIVER_USART *gps_uart_drv = &Driver_USART1;
//#endif
static osThreadId_t gGpsUartTaskId = NULL;
static osMessageQueueId_t gGpsUartTaskQueque = NULL;
char read_buf[GPS_UART_READ_Buf_MaxLen+1] = {0};
int data_len = 0;
/** \brief receive timeout flag */
volatile bool isRecvTimeout = false;
/** \brief receive complete flag */
volatile bool isRecvComplete = false;
/** \brief send complete flag */
volatile bool isSendComplete = false;
GPS_Info_S gps_info = {0};
uint8_t gps_result = 0;
Enum_Gps_State gps_state = 0;
char gps_ver_str[] = {"N1000R3.35.1.1165Build12546"};
void SK_SendMsg_ToGpsUart(Enum_SK_Msg msg_id,void *param,int len)
{
SK_Msg_S msg = {0};
msg.msg_id = msg_id;
msg.param = param;
msg.len = len;
//yak_log("--------msg to main:id=%d,param = %d,len = %d",msg.msg_id,msg.param,msg.len);
//aos_send_to_queue(task_queque_gps, &msg, AOS_NO_WAIT);
osMessageQueuePut(gGpsUartTaskQueque, &msg, 0, 0);
}
void gps_uart_set_baudrate(unsigned int rate)
{
gps_uart_drv->Control(ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 |
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1 |
ARM_USART_FLOW_CONTROL_NONE, rate);
}
void gps_power_on()
{
GPIO_OUTPUT_SET_High(GPS_EN_GPIO_INSTANCE,GPS_EN_GPIO_PIN);
}
void gps_power_off()
{
GPIO_OUTPUT_SET_Low(GPS_EN_GPIO_INSTANCE,GPS_EN_GPIO_PIN);
}
void gps_power_gpio_init()
{
PadConfig_t pad_Cfg;
GpioPinConfig_t gpio_pinCfg;
//agpio4->gpio24 pad 49
PAD_getDefaultConfig(&pad_Cfg);
pad_Cfg.mux = GPS_EN_PAD_ALT_FUNC;
PAD_setPinConfig(GPS_EN_PAD_INDEX, &pad_Cfg);
gpio_pinCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
gpio_pinCfg.misc.initOutput = 0;
GPIO_pinConfig(GPS_EN_GPIO_INSTANCE, GPS_EN_GPIO_PIN, &gpio_pinCfg);
PAD_setPinPullConfig(GPS_EN_PAD_INDEX, PAD_INTERNAL_PULL_DOWN);
}
void gps_start()
{
if ((E_GPS_State_stop != gps_state)||(E_GPS_State_stop != gps_state))
{
gps_power_on();
gps_state = E_GPS_State_downloading;
SK_SendMsg_ToGpsUart(E_SK_Msg_Gps_firmware_dl,NULL,0);
}
}
void gps_stop()
{
gps_power_off();
gps_state = E_GPS_State_stop;
}
void gps_report_satellites_num(u16 type,u16 num)
{
//yak_log("----- nmea satellites_num = %d,type=%d",num,type);
if (E_GPS_State_stop != gps_state)
{
//gps_info.Satellites_num[type] = num;
}
}
char gps_uart_read_char(unsigned int ms)
{
char ret_char = 0;
#if 0
u8 ret_num = 0;
unsigned int t = ms/2;
aos_sleep(t);
if (NULL == gps_uart_handle) return ret_char;
ret_num = uart_read_dir(gps_uart_handle,&ret_char,1);
if (ret_num >0) return ret_char;
aos_sleep(ms-t);
ret_num = uart_read_dir(gps_uart_handle,&ret_char,1);
#endif
return ret_char;
}
char *gps_uart_read_string()
{
return read_buf;
}
int gps_uart_send_byte(char byte)
{
return gps_uart_drv->Send((const void *)&byte,1);
}
int gps_uart_send_buf(char *pBuf,int len)
{
return gps_uart_drv->Send((const void *)&pBuf,len);
}
void gps_uart_cb(uint32_t event)
{
if(event & ARM_USART_EVENT_RX_TIMEOUT)
{
isRecvTimeout = true;
}
if(event & ARM_USART_EVENT_RECEIVE_COMPLETE)
{
isRecvComplete = true;
}
if(event & ARM_USART_EVENT_SEND_COMPLETE)
{
isSendComplete = true;
}
if(event & (ARM_USART_EVENT_RX_BREAK | ARM_USART_EVENT_RX_FRAMING_ERROR | ARM_USART_EVENT_RX_PARITY_ERROR))
{
gps_uart_drv->Control(ARM_USART_CONTROL_PURGE_COMM, 0);
}
//SK_SendMsg_ToGpsUart(E_SK_Msg_Gps_Uart_recv,NULL,);
}
static void gps_uart_init(void)
{
/*Initialize the USART driver */
gps_uart_drv->Initialize(gps_uart_cb);
/*Power up the USART peripheral */
gps_uart_drv->PowerControl(ARM_POWER_FULL);
/*Configure the USART to 115200 Bits/sec */
gps_uart_drv->Control(ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 |
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1 |
ARM_USART_FLOW_CONTROL_NONE, 115200);
}
bool gps_firmware_version_check()
{
char* pVer = strstr(read_buf, gps_ver_str);
if (NULL == pVer)
{
return false;
}
else
{
return true;
}
}
void gnss_location_cb(GpsLocation* location)
{//定位回调函数
}
int gps_icoe_firmware_download()
{
int ret = 0;
icoe_load_fw(GPS_BOOTLOAD_PKG_NAME,GPS_FIRMWARE_PKG_NAME);
return ret;
}
static char *httpget_url_gen()
{
static char url_str[HTTP_GET_URL_Maxlen+1];
sprintf(url_str,"%s/%s/%s",GPS_OFFLINE_EPH_HostDoMain,GPS_OFFLINE_EPH_CustomerID,GPS_OFFLINE_EPH_Filename_3);
yak_log("http url=%s\r\n",url_str);
return url_str;
}
static int save_pgl_file(uint8_t *buf,uint32_t len)
{
return 0;
}
//pgl文件不存文件系统
static INT32 httpGetDataEx(CHAR *getUrl, CHAR *buf, UINT32 len)
{
HTTPResult result = HTTP_INTERNAL;
HttpClientData clientData = {0};
UINT32 count = 0;
uint16_t headerLen = 0;
memset(pgl_data,0,PGL_DATA_Maxlen);
pgl_len = 0;
EC_ASSERT(buf != NULL, 0, 0, 0);
clientData.headerBuf = malloc(HTTP_HEAD_BUF_SIZE);
clientData.headerBufLen = HTTP_HEAD_BUF_SIZE;
clientData.respBuf = buf;
clientData.respBufLen = len;
result = httpSendRequest(&gHttpClient,getUrl,HTTP_GET,&clientData);
yak_log("send request result=%d\r\n", result);
if (result != HTTP_OK)
{
free(clientData.headerBuf);
return result;
}
yak_log("recvResponse loop.\r\n");
do
{
memset(clientData.headerBuf, 0, clientData.headerBufLen);
memset(clientData.respBuf, 0, clientData.respBufLen);
result = httpRecvResponse(&gHttpClient, &clientData);
//yak_log("httpRecvResponse result=%d\r\n",result);
if (result == HTTP_OK || result == HTTP_MOREDATA)
{
headerLen = strlen(clientData.headerBuf);
if (headerLen > 0)
{
yak_log("total content length=%d,blockContentLen=%d\r\n", clientData.recvContentLength,clientData.blockContentLen);
}
if (clientData.blockContentLen > 0)
{
memcpy(pgl_data+count,clientData.respBuf,clientData.blockContentLen);
}
count += clientData.blockContentLen;
//yak_log("has recv=%d blockContentLen=%d,need len=%d\r\n", count, clientData.blockContentLen,clientData.needObtainLen);
}
} while (result == HTTP_MOREDATA || result == HTTP_CONN);
yak_log("result=%d\r\n", result);
if (gHttpClient.httpResponseCode < 200 || gHttpClient.httpResponseCode > 404)
{
yak_log("invalid http response code=%d result=%d\r\n", gHttpClient.httpResponseCode, result);
}
else if (count == 0 || count != clientData.recvContentLength)
{
yak_log("data not receive complete result=%d\r\n", result);
}
else
{
yak_log("receive success.result=%d\r\n", result);
pgl_len = count;
SK_SendMsg_ToGpsUart(E_SK_Msg_Gps_Eph_Inject,NULL,0);
}
free(clientData.headerBuf);
return result;
}
static void gps_uart_task_entry(void *thread_input)
{
//int ret;
nmea_reader_init();
nmea_gnss_set_callback(gnss_location_cb,NULL,NULL);
gps_uart_init();
gps_power_gpio_init();
while(1)
{
yak_strlog("gps read...");
gps_uart_drv->Receive(read_buf,10);
read_buf[10] = 0;
yak_strlog(read_buf);
}
gps_state = E_GPS_State_init;
while(1)
{
SK_Msg_S msg = {0};
memset(&msg, 0, sizeof(SK_Msg_S));
if (osMessageQueueGet(gGpsUartTaskQueque, &msg, 0, osWaitForever) == osOK)
{
//消息处理
switch (msg.msg_id)
{
case E_SK_Msg_Gps_Uart_recv:
{
//uint32_t r_len = 0;
uint32_t len = gps_uart_drv->GetRxCount();
while(len)
{
if (GPS_UART_READ_Buf_MaxLen<len)
{
gps_uart_drv->Receive(read_buf, GPS_UART_READ_Buf_MaxLen);
len -= GPS_UART_READ_Buf_MaxLen;
}
else
{
gps_uart_drv->Receive(read_buf, len);
read_buf[len] = 0;
len = 0;
}
yak_strlog(read_buf);
}
}
break;
case E_SK_Msg_Gps_Nmea_recv:
break;
case E_SK_Msg_Gps_firmware_dl:
{
if ((E_GPS_State_init == gps_state)||(E_GPS_State_stop == gps_state))
{
gps_state = E_GPS_State_downloading;
gps_icoe_firmware_download();
if (E_GPS_State_stop != gps_state)
{
gps_state = E_GPS_State_check_version;
}
}
}
break;
case E_SK_Msg_Gps_Eph_Inject:
{
int ret = 0;
yak_log("E_SK_Msg_Gps_Eph_Inject\r\n");
//Set the clock for the PSRAM (Physical Static RAM)
//PSRAM_setClk102M();
//Enable DMA access to the PSRAM
//PSRAM_dmaAccessClkCtrl(true);
//char *pPglData = malloc();
//memcpy(pgl_data_ex,pgl_data,PGL_DATA_Maxlen);
//log_hex(pgl_data,48);
#if 1
icoe_offline_eph_init((unsigned char * )GPS_OFFLINE_EPH_CustomerKey);
//icoe_extract_offline_eph_Ex(RXN_GPS_CONSTEL,pgl_data,0,rtcm_data,&rtcm_len);
unsigned char gps_com[] = "$AIDEPHTYPE,2\r\n";
//sns_uart_write(SNS_UART2,(uint8_t *)str,len);
icoe_adap_uart_send_bytes(gps_com,strlen((char *)gps_com));
//icoe_adap_delay_ms(10);
//ret = icoe_extract_offline_eph_Ex(RXN_BDS_CONSTEL,pgl_data,0,rtcm_data,&rtcm_len);
ret = icoe_extract_offline_eph_Ex(RXN_GPS_CONSTEL,pgl_data,0,rtcm_data,( unsigned int *)&rtcm_len);
if (ret >= 0)
{
yak_log("RXN_GPS_CONSTEL rtcm data to inject len =%d\r\n",rtcm_len);
icoe_adap_uart_send_bytes(rtcm_data,rtcm_len);
icoe_adap_delay_ms(10);
}
#if 1
rtcm_len = RTCM_DATA_Buflen;
ret = icoe_extract_offline_eph_Ex(RXN_BDS_CONSTEL,pgl_data,0,rtcm_data,(unsigned int *)&rtcm_len);
if (ret >= 0)
{
yak_log("RXN_BDS_CONSTEL rtcm data to inject len =%d\r\n",rtcm_len);
icoe_adap_uart_send_bytes(rtcm_data,rtcm_len);
//icoe_adap_delay_ms(10);
}
#endif
//SK_SendMsg_ToGpsUart(E_TASK_MSG_GPS_Locate_start,NULL,0);
//
icoe_adap_uart_send_bytes((unsigned char *)"$AIDINFO\r\n",sizeof("$AIDINFO\r\n"));
#endif
}
break;
case E_SK_Msg_Gps_OfflineEph_dl:
{
//int tt = (int)msg.param;
HTTPResult result = HTTP_OK;
result = httpConnect(&gHttpClient,GPS_OFFLINE_EPH_HostDoMain);
if (HTTP_OK == result)
{
SK_MainDev_S* pMain = getMainDevInfo();
yak_log("http client connect ok!\r\n");
httpGetDataEx(httpget_url_gen(),(char *)http_recvBuf,HTTP_RECV_BUF_SIZE);
httpClose(&gHttpClient);
save_pgl_file((uint8_t *)pgl_data,pgl_len);
pMain->config_info.gpseph_timestamp = getCurTime(NULL);
SK_SendMsg_ToMainTask(E_SK_Msg_Main_config_save,NULL,0);
}
else
{
yak_log("http client connect erro:%d\r\n", result);
}
}
break;
default:
{
}
break;
}
}
}
}
int SK_GPS_UART_Task_Init(void)
{
osThreadAttr_t threadAttr = {0};
threadAttr.name = "GPS UART Task";
threadAttr.stack_size = GPS_UART_TASK_STACK_SIZE;
threadAttr.priority = osPriorityBelowNormal5;
gGpsUartTaskId = osThreadNew(gps_uart_task_entry, NULL, &threadAttr);
if (NULL == osThreadNew(gps_uart_task_entry, NULL, &threadAttr))
{
yak_strlog("############## Failed to create gps uart thread\n");
}
else
{
gGpsUartTaskQueque = osMessageQueueNew(GPS_UART_TASK_QUEUE_SIZE, sizeof(SK_Msg_S), NULL);
}
return 0;
}

View File

@ -0,0 +1,23 @@
/****************************************************************************
*
* Copy right: 2017-, Copyrigths of EigenComm Ltd.
* File name: app.c
* Description: EC718 at command demo entry source file
* History: Rev1.0 2018-07-12
*
****************************************************************************/
#include "string.h"
#include "bsp.h"
#include "bsp_custom.h"
#include "os_common.h"
#include "ostask.h"
#include DEBUG_LOG_HEADER_FILE
#include "plat_config.h"
#include "slpman.h"
#define HealthData_MaxLen (10000)
HEALTH_HeartRate_S healthData[HealthData_MaxLen];

View File

@ -0,0 +1,217 @@
/********************************Copyright(c)***********************************
*******************************************************************************/
#ifndef __ECG_DETECT__
#define __ECG_DETECT__
#ifdef _WIN64
#define MATLAB_PLOT (0)
#endif // DEBUG
//#include "Vp_MallocAlgTypeLocation.h"
#include <stdint.h>
/*
* 20190225-01010254(YQW):
* * Global: 1237(Bytes) + 105(Bytes-resp_ecg) = 1342(Bytes)
* * Malloc: 7600(Bytes)
* * Local: 2399(Bytes)
* * Const: 55(Bytes)
*/
#define AFE4900_ECG_ALG_VERSION (0x03000000)
#define ECG_SAMOLING_RETE ( 512 )
#define ECG_ANALYSIS_TIME_SEC ( 6 )
#define DELAY_POINTS_LEN ( 100 )
#define ECG_WAVELET_ADD_LEN ( 164 )
#define ECG_WAVELET_TOP_LEN ( 19 )
#define ECG_DATA_LEN ( ECG_SAMOLING_RETE *ECG_ANALYSIS_TIME_SEC )
#define REAL_DATA_LE ( ECG_DATA_LEN - DELAY_POINTS_LEN )
#define G_SIZE ( ECG_DATA_LEN )
#define FILTER_TIMES ( 7 )
#define FILTER_LEN ( 20 )
#define LOCAL_LEN ( (G_SIZE + FILTER_LEN + 10) / 2 )
#define ECG_MAX_CYCLE ( 24 )
#define ECG_LD_JUDGE_VALUE ( 7000000 )
#define SAMPLE_LEN ( ECG_DATA_LEN/8 ) //抽样长度
#define INDEX_LEN ( 26 ) //10秒内最大的QRS个数
extern int32_t ecg_filter_data[ECG_SAMOLING_RETE];//心电数据的显示缓存
typedef struct
{
uint16_t register_scale;
}tag_ecg_afemaxim_parameter_t;
typedef struct
{
uint8_t errey_flag; //测量标志 1 测量成功 0 测量失败
uint16_t BMI; //BMI 18.5 ,24 , 27
uint16_t body_fat_rate; //体脂率 10% , 20% , 25%
uint16_t fat_mass; //脂肪量 - 体脂率计算
uint16_t fat_free_mass; //去脂体重45.8 , 55.6
uint16_t muscle_rate; //肌肉率 68.1% , 84.8%
uint16_t muscle_mass; //肌肉量 (40.8 , 50.8)
uint16_t subcutaneous_fat_rate; //皮下脂肪8.6% , 16.7%
//uint16_t visceral_fat_rate; //内脏脂肪10
uint16_t body_water_rate; //体内水分 (53.4% , 66.6%)
uint16_t water_mass; //含水量 - 体内水分计算 32.0 , 39.9
uint16_t skeletal_muscle_rate; //骨骼肌率 ()
uint16_t bone_mass; //骨量 (2.9 , 3.7)
uint16_t protein_rate; //蛋白质占比 (14.1% , 17.4%)
uint16_t protein_mass; //蛋白质含量 - 蛋白质占比计算8.7 , 10.9
uint16_t basal_metabolism_mass; //基础代谢 - 16 , 19
//uint16_t physical_age; //身体年龄 - 用户输入
}body_composition;
typedef struct tag_ecg_result
{
// 心率相关
uint8_t heart_rate; // 每秒HR
uint8_t hr_per_min_result; // 每分钟HR均值对应日常数据心率1~5
// HRV相关
uint8_t hrv;// 每秒HRV
// RR相关
uint8_t rr;// 每秒rr
uint8_t rr_per_6sec_result;// 每6秒RR
uint8_t ary;// 心率不齐
// 呼吸率相关
uint8_t resp_per_second_result;// 每秒呼吸率
uint8_t resp_per_min_result;// 每分钟呼吸率均值对应日常数据呼吸率1~5
// 导联脱落标志位
uint8_t lead_off_detec_res;
// 诊断进度标志位
uint8_t measurement_progress;// 说明该进度标志位非每秒计数该进度标志位最大值为30软件在识别到该值为30后即可诊断结束不再识别其后的值
uint16_t QTC_sec;
// Afe4900校准信息
uint8_t adjust_flag;//校准的标志位0,3表示不需要对寄存器的参数进行修改1,2需要修改
tag_ecg_afemaxim_parameter_t ecg_afemaxim_parameter_new;//寄存器的参数的值
//test
uint8_t RR_cnt;
uint8_t ecg_ld_judge_flag; // 0:佩戴通过 1:佩戴不通过
// 增加PWV的计算
float ecg_pwv_val; //改参数在手表端显示是两位小数的浮点显示
//增加ST幅度的计算
float ecg_st_amp; //st段振幅 单位mv
//身体成分相关
body_composition out_body_result; //身体成分
}ecg_result_t;
typedef struct tag_ecg_result_info
{
uint8_t lead_off_type;
uint8_t diag_param1;
uint8_t diag_param2;
uint8_t diag_param3;
uint8_t diag_param4;
uint8_t diag_param5;
uint8_t diag_param6;
uint8_t diag_param7;
uint8_t diag_param8;
uint8_t heart_rate; //心率
uint8_t resp_rate; //呼吸率,未赋值
uint8_t hrv; //心率变异性
uint8_t disease_risk; //疾病风险,[1,99]
uint8_t pressure_index; //压力指数,[1,99]
uint8_t fatigue_index; //疲劳指数,[1,99]
uint8_t myocarditis_risk; //心肌炎风险,[1,99]
uint8_t chd_risk; //冠心病风险,[1,99]
uint8_t angiosclerosis_risk; //血管硬化风险[1,99]
uint16_t QT_time; //QTC
uint16_t qrs_time; //QRS时长 单位ms
float qrs_amp; //QRS振幅 单位mv
float pwv_mean_val; //pwv的实时均值测量范围[6,20]m/s,动脉粥样硬化指标,异常范围 > 15m/s
float st_mean_amp; //平均st段振幅 单位mv[-0.05,0.1]mv为正常范围
uint32_t disease_sdnn; //SDNN 窦性心搏间标准差,正常值为(141±39)ms
uint32_t disease_rmssd; //RMSSD 相邻正常心动周期差值的均方根正常值范围为27±12ms
uint32_t rese1;
}ecg_result_info_t;
typedef struct ecg_risk_ratio_info_t
{
uint8_t risk_param1; // 停搏 YYY
uint8_t risk_param2; // 心律不齐 YYY
uint8_t risk_param3; // 心动过缓 YYY
uint8_t risk_param4; // 心动过速 YYY
uint8_t risk_param5; // 房性早搏 Y
uint8_t risk_param6; // 三联律 YYY
uint8_t risk_param7; // 二联律 YYY
uint8_t risk_param8; // 室性早搏 YYY
uint8_t risk_param9; // 心房扑动 N
uint8_t risk_param10; // 阵发性室性心动过速 YYY
uint8_t risk_param11; // 阵发性室上性心动过速 Y
uint8_t risk_param12; // 交界性早搏 Y
uint8_t risk_param13; // 心房肥大 Y
uint8_t risk_param14; // 心室颤动 N
uint8_t risk_param15; // 心室扑动 N
uint8_t risk_param16; // 心房颤动 YYY
uint8_t risk_param17; // 心肌梗死(损伤型) Y
uint8_t risk_param18; // 心肌梗死(缺血型) Y
uint8_t risk_param19; // 心肌缺血 YY
uint8_t risk_param20; // 心室肥大 YY
uint8_t risk_param21; // 房性逸搏 Y
uint8_t risk_param22; // 室性逸搏 Y
uint8_t risk_param23; // 交界性逸搏 Y
uint8_t risk_param24; // 心肌梗死(坏死型) Y
uint8_t risk_param25; // 三度房室传导阻滞 Y
uint8_t risk_param26; // 二度房室传导阻滞---二度II型 Y
uint8_t risk_param27; // 二度房室传导阻滞---二度I型 Y
uint8_t risk_param28; // 一度房室传导阻滞 Y
uint8_t risk_param29; // 预激综合征(WPW) YY
uint8_t risk_param30; // 左前分支传导阻滞(LAFB) Y
uint8_t risk_param31; // 右束支传导阻滞(RBBB) YY
uint8_t risk_param32; // 左束支传导阻滞(LBBB) YY
}ecg_risk_ratio_info_t;
typedef struct tag_ecg_diag_result
{
uint8_t ecg_result_save_flag;
ecg_result_info_t ecg_result_info_s;
ecg_risk_ratio_info_t ecg_risk_ratio_info_s;
}ecg_diag_result_t;
typedef struct tag_ecg_enter
{
uint8_t diga_mode; //0自动模式1手动模式
uint8_t age; //输入的年龄
uint8_t func_times;
uint8_t ecg_leadoff;//1182只有一个
uint16_t sampling_len; // app抽样显示仅支持256128
uint16_t ID_weight_KG;//输入的是KG
uint16_t ID_hight_CM;//输入的是身高cm
tag_ecg_afemaxim_parameter_t tag_ecg_afemaxim_parameter_s;
}ecg_enter_t;
typedef struct
{
uint8_t move_5s;
uint8_t move_15s;
uint8_t move_30s;
uint8_t move_60s;
uint8_t move_120s;
}ecg_move_index_t;
/*
* functions declarations for external call
*/
extern void Ecg_DetectInit(void);
extern int32_t Ecg_DetectEntry(const int32_t* ede_ecg_signal,
ecg_move_index_t* movement_struct_s,
ecg_enter_t ecg_enter_info
);
extern void Ecg_GetResult(ecg_result_t* egr_result_s);
extern void Ecg_GetDiagResult(ecg_diag_result_t* ecg_diag_result_s);
#endif //

View File

@ -0,0 +1,106 @@
#ifndef _GOODIX_ECG_RC_COMPENSATION_H
#define _GOODIX_ECG_RC_COMPENSATION_H
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifndef PI
#define PI 3.14159265358979
#endif
#ifndef EPS
#define EPS 0.000001f
#endif
#define GOODIX_ABS(a) ((a) < 0 ? -(a) : (a))
#define MALLOC(x) malloc(x)
#define FREE(x) free(x)
/////////////////////buffer///////////////////////
typedef struct
{
float *buf;
uint32_t size;
uint32_t num;
}goodix_buffer_instance_f32;
void goodix_buffer_init_f32(goodix_buffer_instance_f32* b, uint32_t size);
void goodix_buffer_add_f32(goodix_buffer_instance_f32 *b, float d);
uint32_t goodix_buffer_get_num_f32(goodix_buffer_instance_f32 *b);
uint32_t goodix_buffer_is_full_f32(goodix_buffer_instance_f32 *b);
void goodix_buffer_deinit_f32(goodix_buffer_instance_f32* b);
/////////////////////buffer///////////////////////
/////////////////////RC Compensation///////////////////////
typedef struct
{
float coff;
float Vo_p;
float Vi_p;
float fs;
float fcut;
}goodix_RC_Compensation_instance_f32;
void goodix_RC_Compensation_init(goodix_RC_Compensation_instance_f32 *rcCom, float fs, float fcut);
void goodix_RC_Compensation_calc(goodix_RC_Compensation_instance_f32 *rcCom, float dataIn, float *dataOut);
/////////////////////RC Compensation///////////////////////
/////////////////////RC HPF///////////////////////
typedef struct
{
float coff;
float Vo_p;
float Vi_p;
float fs;
float fcut;
}goodix_RC_HPF_instance_f32;
void goodix_RC_HPF_init(goodix_RC_HPF_instance_f32 *rcHpf, float fs, float fcut);
void goodix_RC_HPF_calc(goodix_RC_HPF_instance_f32 *rcHpf, float dataIn, float *dataOut);
/////////////////////RC HPF///////////////////////
/////////////////////RC LPF///////////////////////
typedef struct
{
float coff;
float Vo_p;
float fs;
float fcut;
}goodix_RC_LPF_instance_f32;
void goodix_RC_LPF_init(goodix_RC_LPF_instance_f32 *rcLpf, float fs, float fcut);
void goodix_RC_LPF_calc(goodix_RC_LPF_instance_f32 *rcLpf, float dataIn, float *dataOut);
/////////////////////RC LPF///////////////////////
/////////////////////Med///////////////////////
void goodix_Med_calc(goodix_buffer_instance_f32 *b_compute, goodix_buffer_instance_f32 *b_index, goodix_buffer_instance_f32 *b_values, float dataIn, float *dataOut);
/////////////////////Med///////////////////////
/////////////////////Square Compensation///////////////////////
typedef struct
{
float fs;
float hpf1_fcut;
float com_fcut;
float med_size;
float lpf_fcut;
float hpf2_fcut;
}goodix_ecg_RC_config;
typedef struct
{
goodix_RC_HPF_instance_f32 rcHpf;
goodix_RC_Compensation_instance_f32 rcCom;
goodix_buffer_instance_f32 medRaw;
goodix_buffer_instance_f32 medIndex;
goodix_buffer_instance_f32 medValue;
goodix_RC_LPF_instance_f32 rcLpf;
goodix_RC_HPF_instance_f32 rcHpf2;
}goodix_ecg_RC_instance;
void goodix_ecg_RC_init(goodix_ecg_RC_config* cfg, goodix_ecg_RC_instance* ecg);
void goodix_ecg_RC_update(goodix_ecg_RC_instance* ecg, float dataIn, float *dataOut);
void goodix_ecg_RC_deinit(goodix_ecg_RC_instance* ecg);
/////////////////////Square Compensation///////////////////////
#endif

View File

@ -0,0 +1,764 @@
#ifndef Goodix_DSP_EXPORTS
#include "goodix_type.h"
#define NET_VERSION " "
#define NET_SIZE 5951
const uint32_t knSceneSwitchWeightsArr[] = {
2, 6, 2929173119, 1838977409, 2206830696, 2103752849, 2457310537, 1515215977,
2811811196, 2237056382, 1684371076, 2257486694, 1731950425, 2426440230, 1922012297, 2691137378,
2116849796, 2320317042, 2315299217, 1133804943, 2789563011, 3129909130, 2291646890, 2421136241,
1917667007, 1787194713, 2473625453, 2759940428, 1168285044, 1135565855, 2491136671, 2677432771,
1600222125, 2908711109, 1753191550, 2308535659, 2304015303, 1858966595, 2626663869, 2536150678,
2271393926, 2122270784, 2072672922, 2912643770, 2207750822, 2374206101, 2142413227, 1652777302,
2403123067, 1750859876, 1250716845, 2389656433, 2956992829, 3451291010, 1227459686, 2846062271,
1553077107, 1169005976, 1707538100, 1702293897, 2997659751, 2914751191, 3512102510, 3082592332,
3047579197, 2102614633, 2610775895, 2438480755, 2743660658, 2358274730, 2721143349, 1837780053,
9696970, 2270656948, 2940303176, 1418694317, 2674614625, 2843697799, 1820619400, 1784382077,
1839299466, 1819182173, 2039189132, 2005432681, 1534824058, 1886486669, 2105055391, 1258321795,
2943514991, 1951300720, 2071037531, 2055115645, 2290987398, 2121905297, 1501324447, 2156953237,
2273996610, 2290653827, 2208609694, 2425532853, 2475719824, 2155894401, 1853373013, 2337497467,
2272421009, 3359804338, 2624281202, 1817943168, 2974973149, 2528034751, 1467266153, 2457566128,
2470275222, 2410068627, 1179751543, 1618763660, 1468494694, 2826015860, 2315281967, 3030429797,
2830015388, 2573825175, 1990102879, 2474352276, 2306631019, 1635954835, 2624104292, 2934578310,
2006760618, 609127264, 2339743671, 1148280981, 1803122244, 2784999553, 1565943933, 1766824090,
2843704205, 2339758502, 2748485310, 1888973198, 2120696452, 1162177393, 2842654573, 2761192574,
2712115357, 3208816482, 1786732764, 1051812727, 3090122108, 3038604643, 1739225717, 3025501260,
1350456491, 1975614826, 372930669, 2258271481, 1500671608, 2527365243, 2307764816, 2930620603,
3041802189, 2653853545, 1145020029, 2192272945, 541154990, 2070241896, 1982433684, 3243464851,
946763520, 2678805562, 3045883789, 1333687096, 2007595915, 2711389598, 1531139496, 2912728459,
2858667862, 1362828916, 1366854963, 2351409232, 2306179944, 2221586808, 2138858900, 2274721654,
1266191722, 2141955476, 2170053059, 1788320861, 3163112504, 1245577363, 2288214873, 2004125561,
2504690786, 2490341304, 278495397, 2489885790, 2844348498, 949059976, 2573567327, 2256042360,
1335192746, 2423020656, 1936483621, 2361493876, 2475073967, 1942471800, 1586143536, 3142018850,
3566846553, 1186178449, 2203276997, 2170330988, 1128677187, 2358486098, 1550158207, 1952730980,
948990804, 2289013878, 1448315960, 1168286320, 2674570667, 2842976768, 1485336194, 2370867344,
2391677567, 1568901719, 2440349039, 3452645286, 392664472, 2931002931, 1550846128, 661558870,
1212751201, 3748116891, 2270196051, 2523095651, 1751891228, 1132484235, 2072018310, 2553417158,
1721520810, 2358999076, 10572182, 3032451990, 3061164215, 2407291224, 965103502, 1735949573,
2185469818, 1888469842, 2272686183, 2071613829, 1850619750, 2324140449, 3007807610, 1786738284,
1667332900, 2596436630, 2523034994, 2073476244, 1216455786, 2165847946, 1028895098, 2407167352,
1314945706, 1955089497, 2304015745, 2356700253, 1560286606, 1720363894, 2158065815, 1890802490,
1233608539, 2493243073, 2221374897, 2005631101, 2222761339, 2777037470, 2717892476, 2557578149,
3789783463, 1250520293, 2372555389, 2747370609, 1669221213, 2361956975, 2259897940, 2246042254,
1804499063, 4047128143, 1199340374, 2358861929, 1900433261, 1786290541, 2458991971, 2440209803,
2743454576, 1652926826, 2019778713, 3502998667, 1853122957, 2290212728, 1518738738, 2138670777,
2852158332, 2274075070, 1918847372, 1439535972, 2964363412, 1804636589, 1558744992, 1975608158,
2669173353, 2222636913, 1427677300, 1987343739, 2676190090, 2574549672, 2653183384, 1536062860,
2088803748, 1180633396, 2038582891, 2424690604, 2758243275, 2607643482, 2089319556, 1854900359,
2472701832, 1601081985, 2002235005, 2220721549, 2321789566, 1383829125, 2235341714, 2642715258,
2345514927, 1654099391, 2962459996, 1687763031, 1901820250, 2020376930, 2346215054, 1187401483,
1469413988, 2490789692, 2474273173, 2743955335, 2291432448, 1970830139, 1837083484, 2372882803,
2342563467, 2645995373, 2525518540, 1804584337, 997421926, 2674675300, 1989384618, 2021305734,
2541523841, 2428283242, 2073142941, 1756309294, 1066951283, 2069520696, 2372115811, 3128897111,
1433645477, 2039980621, 2256565896, 2071611904, 814651272, 2874976134, 2591902094, 1601868453,
2490820716, 2172614300, 2339937956, 2608429473, 1738439288, 2136701587, 4068242599, 1619088896,
2322837587, 2488489099, 2141545309, 2844622770, 1401002098, 1468291130, 1835621482, 1599768193,
2223218824, 2454801792, 2776984735, 2290651298, 2254331498, 1401002379, 2121304730, 2792449453,
2122676335, 2206775421, 2779892969, 2826012559, 1696811145, 3835204515, 2071553424, 2540935569,
3094847855, 2156951981, 1988610638, 2662177612, 1318896276, 2627765125, 1713137972, 1532657264,
2141936010, 2475786123, 3214126122, 2074443962, 2926531248, 3300821641, 1135427945, 2711911545,
2305127536, 1721528456, 2758344540, 2477033777, 2611259816, 1765704789, 3048701836, 2725813355,
2342094500, 1904316055, 1636747653, 1754617463, 2544413612, 3036688223, 1871497903, 2628426880,
1566207360, 1768463433, 2228366895, 2586124633, 2392405374, 2307408533, 2105376106, 1904566905,
2201702534, 2306499397, 2844229973, 2356085109, 2188490919, 1755087241, 1956945278, 1049119448,
2087018108, 2744098921, 2189852829, 2640937853, 1933414995, 1429778806, 1058977452, 1638320038,
1921610088, 1900834410, 2793513869, 2390922113, 1207984991, 2103195722, 2405398108, 1986167965,
2053989031, 2354201694, 1517784035, 1954110825, 2105691012, 2373885034, 2256965742, 1836153200,
2157362798, 1701086829, 1264100444, 2557767776, 2140515438, 2674626707, 2320659075, 654860923,
2826400633, 1620082281, 1785100169, 1367312264, 2221833324, 2013277063, 814709366, 2137684894,
1922977352, 1837805161, 2257289870, 2053076920, 2004969090, 2205762685, 3373354636, 2323416255,
410482607, 2177291424, 271548035, 4053735844, 3182136664, 2006419830, 4233117153, 2763427961,
3578834903, 2514592341, 2739637036, 2068400012, 788556140, 2843767952, 2037624857, 2392946560,
3415315388, 3722004362, 1958335131, 2946954675, 2085530001, 1403155834, 3125784902, 1646446159,
2594022803, 2635162726, 2103619536, 2407932079, 2426200503, 2289273243, 3145026163, 442806623,
2205395528, 527197888, 2357091153, 830234389, 2485927568, 1163766567, 2271579251, 1996516454,
2088921749, 2020895615, 2708694597, 2189387403, 2189136512, 2068982190, 2944820626, 2155830912,
4285626383, 2793108156, 815409957, 1353497483, 1268289936, 3431046443, 1707973281, 2944894780,
2486200427, 2830395026, 2160628818, 2091354686, 1940565366, 1437296471, 274818939, 2474408510,
985983158, 2256591226, 2442488785, 1818400633, 2156778201, 2487392105, 1554755226, 3165042038,
2490749548, 2695976020, 2628229315, 3243543718, 1651289478, 1718702676, 2676672417, 2695798639,
2695082124, 2530298792, 2177214368, 2019596408, 2979463030, 962546513, 2019325847, 1934453618,
1917084239, 1529964869, 930901667, 2136571574, 1770671428, 2055175043, 2525011334, 1464556633,
326396792, 2155924864, 2405586716, 2140115371, 1647297670, 2512911781, 1768377429, 1349225145,
3348926321, 2055960918, 1586919744, 2609860757, 2302899553, 1837556355, 2183499328, 1733527375,
1566991762, 2152678528, 4105796210, 1552390077, 2494923950, 2825874309, 714304391, 2290273023,
1883476859, 3232470128, 2390203250, 2326504309, 2913560964, 3040132976, 2909629323, 1686661763,
1392538271, 2459083118, 2473103993, 1535148709, 2231268508, 2322224726, 2087285328, 1085707919,
2123005842, 1568778091, 1889428351, 1864195470, 1753656158, 1888450203, 1999782841, 1535631515,
2103671193, 2438038873, 2221885765, 2039038855, 2743507293, 2440988557, 2386070620, 1550366848,
1938586218, 2562302838, 2188612223, 2121311634, 1685230219, 2426887507, 1180914827, 2021035369,
1000176953, 1971357825, 2357685901, 1409301652, 1650093895, 2290830435, 2155245711, 2118536556,
1971004513, 2065858453, 2256555065, 2341039474, 2155714176, 4176781174, 2575414432, 2272880553,
2509347227, 1869177195, 2221046887, 3214576792, 2408541837, 2725412981, 2305724758, 2086634363,
2055841425, 4290232235, 1416008836, 2289529472, 1938190231, 2440592985, 2441766517, 2475987335,
2221374849, 2257158273, 2254011813, 2275971681, 2777317236, 2323149942, 1907337936, 2123864688,
1216778897, 3515395216, 2643307825, 3264070045, 3350355600, 1818733858, 1738256501, 2169739416,
2877332877, 2088923797, 2857806461, 2450622636, 1902222950, 2238949251, 2638727554, 2962320025,
2103605605, 2103902074, 1987666788, 2175198606, 1934978213, 2239519634, 2189324926, 270805370,
2238333977, 2153678184, 3274671464, 2966259609, 1890743949, 1351204661, 1452771695, 2025881188,
2576446241, 1939964065, 2072348470, 1903890317, 2290252338, 2291302230, 2544993715, 2156505233,
2324643203, 2232638015, 3382022529, 1871511503, 2340646729, 1949988004, 2139705721, 2373156211,
2288611221, 1537125730, 2946397285, 2287631726, 62622365, 1953266867, 2881379660, 1415365293,
3079505314, 2149804512, 2490795153, 2459341442, 2657782605, 1773296300, 2726590567, 2186191028,
2316730491, 1971024260, 2135061913, 1783266686, 1652915045, 2287574177, 1415372432, 2675535994,
2256600954, 1868916565, 2678291592, 1371431024, 1399434143, 1303832716, 3211380921, 2407298118,
1584886347, 2117828476, 1972789649, 2444928949, 1183148650, 3100153705, 2272169607, 1132974690,
2457169070, 2547108531, 2289090977, 1937069195, 1754573664, 2742712914, 2225570459, 1990955377,
2760817561, 2122776449, 2476442472, 1939116451, 3113838170, 2160820152, 2624421016, 1853850078,
2056612435, 2220200629, 2559404210, 2022140546, 2021026170, 3179064526, 2826133099, 1683975602,
2659287692, 2085183860, 2053795102, 1887730573, 2324786809, 2374661198, 1769884254, 2044651519,
1687596462, 2139515000, 2156034688, 2039170467, 2204082554, 2993513862, 2473566324, 1903528339,
1584803137, 2823333886, 2588779699, 1473225124, 2225112217, 2560403788, 1619149648, 1792193899,
2587784703, 2893972592, 2224396147, 2866377543, 2911260258, 2172428186, 1621791873, 3263733129,
2146604653, 2339975514, 2491437426, 2189053311, 3264968003, 3284167563, 1720358251, 1668654720,
1870578566, 1521122694, 1737520270, 1820564713, 3527514761, 2326367124, 1397533812, 2088480908,
2175778410, 2121497404, 2754982512, 1719810048, 2056027220, 2843697348, 2004365430, 1988928326,
2188874357, 2209792995, 2675866002, 2995433177, 2071822981, 3283877707, 2510407125, 2137948505,
2881005374, 2124920218, 3368983219, 2225646503, 2341832517, 2457172586, 2457916064, 1919671980,
2256328063, 3355415160, 1520653527, 2438178401, 1901940516, 1160752523, 2693838965, 2022851950,
1954642100, 2524151917, 2084212097, 1751106459, 2189335966, 2105490051, 2405741942, 2478013574,
2019658120, 2155253880, 2040113261, 2258466816, 2862326259, 2321979988, 1741136190, 2222890922,
2309535380, 2357299069, 1247575945, 1387692958, 1119054220, 2336912979, 1904388524, 1871090277,
2370858880, 1634765999, 2358293387, 2217375863, 3028961942, 2877011832, 2255902841, 3434778781,
3234047152, 2001579927, 2842686101, 2010308076, 2594139980, 1805539897, 2037742772, 1775526285,
2181035467, 2883713433, 2592090453, 3262658840, 2509529259, 917779526, 1668905595, 1437635450,
1970385758, 2139725192, 2219798496, 981447079, 1910814093, 2972753272, 2356050752, 2106443906,
3449516411, 1701931387, 2259386755, 1467187090, 1854169716, 1426088092, 1938390873, 2725937289,
2259122063, 2406702458, 3483523942, 2240307842, 1652185475, 2089907855, 2244107649, 2056153946,
2408143209, 2138339233, 2124648328, 2121697147, 1451714952, 2107086279, 1886947939, 2037939321,
2189482622, 2238876360, 2389601432, 2560661691, 2386199341, 2496691807, 1936691620, 2322828150,
2022538644, 2141294210, 2197786527, 2429384842, 2357680530, 1903449681, 2424469449, 2428285590,
2457693300, 3035881595, 2743701870, 2356509327, 1789430639, 2760813701, 2472640634, 2716968572,
2911866273, 2339480181, 2753904211, 1200573826, 1669466980, 4104816296, 3829450374, 2474567533,
2310627481, 3929361297, 2643308292, 2374078345, 1092972386, 1333625525, 4287460488, 2453317477,
1318869148, 1687186352, 2423549504, 2473776287, 1735886968, 1805569422, 2239202409, 2261820538,
1419104639, 2708629186, 2022022280, 1901775796, 3936464775, 2610082245, 1685165173, 1855671463,
2363450972, 2292867121, 2793765283, 2221241502, 2074438024, 3017567875, 1938380421, 1302505320,
2154935178, 2340977545, 2169530747, 2189435824, 1854368887, 2305459633, 1399859099, 1835943228,
2066236308, 2388797302, 2928318589, 2189426558, 2648079754, 2221257635, 2091233407, 3312616084,
2190050963, 1070887808, 3402222828, 1668251003, 2555992723, 1968613809, 2475540407, 2036821413,
3833643332, 2692526956, 2540392858, 1701214051, 2425133954, 2808964472, 1566411846, 894993365,
2474803019, 2164283465, 3483600234, 2842972037, 1955556493, 1796894343, 1889890635, 2745592477,
3335611812, 540644488, 2444731289, 2744417334, 1537769809, 2342280333, 2017549672, 1935199436,
2391115934, 4285823180, 2184922823, 2276820881, 2257166246, 1334345293, 1769847006, 2174136189,
2492900767, 1903238228, 2050843791, 945793683, 1518430867, 2122237058, 2863636879, 2997731723,
2710401390, 2474670986, 2122749900, 3992938639, 2369943330, 1983217008, 2874570398, 2256710700,
1854452362, 2575998104, 1599103593, 1754380443, 2322755708, 1951559047, 1299753551, 1182950994,
2036236433, 1332047798, 1349215586, 2152226195, 2934272331, 2710281886, 2172675456, 1700220210,
1470264426, 194800987, 2677457347, 3294732615, 1077874768, 3062012325, 3326583433, 2485426772,
2206157629, 2782693215, 1502675095, 3638920855, 1557537171, 2856888687, 2239973518, 1768320821,
3079499620, 2427552344, 2826329195, 2844491408, 2252572940, 3179690850, 2157675171, 2306162807,
2058983216, 1602406008, 2755877702, 2572064174, 2457299885, 1786673000, 3196285740, 2039396789,
2002608541, 2310042707, 795224102, 2944959595, 1419311492, 1453696403, 2255328863, 2396149439,
3679864392, 1586634169, 2154595511, 2309589363, 1115776930, 2372764110, 2020819968, 2660183898,
2323340918, 2625113404, 2762098802, 513348468, 1636329638, 710208210, 2415853395, 1550674436,
2771155351, 1363965503, 2576821608, 1332711806, 1519745685, 1307989054, 492222066, 3795219508,
1834843326, 1940960424, 3212421242, 1784971181, 2306844279, 1399153806, 2356050860, 1489924414,
1099070630, 2139420545, 3044561826, 2358734252, 1579916352, 2440333444, 680162428, 1687788686,
2710820685, 1233815665, 1232252415, 2475128954, 1386587750, 1955030392, 2004818052, 1515692948,
2575146413, 1952090040, 2340922727, 2491906662, 2539413905, 2084587175, 1820760223, 2149281189,
2226153546, 2023652200, 2339749749, 3129765995, 2055705195, 1100109750, 1617734049, 2879222971,
4135739728, 2801838633, 2007263669, 3155586924, 2431678327, 2259382107, 2543210092, 1302437761,
1736219460, 2069658266, 2139526009, 1487251072, 2021826232, 2054063237, 1721598605, 1299541619,
2189579661, 2223914838, 728847532, 2155429504, 1537107598, 1904252260, 2052886131, 3350619815,
2924428894, 2358099802, 2638445406, 3228459917, 3911013, 2139321704, 2268104119, 2909759605,
3313733955, 2040434822, 663907771, 1770155936, 2524036683, 1584938852, 2119329636, 1602266262,
1754692488, 2126656637, 1383627884, 1686654737, 2172161919, 3616312752, 1703459956, 2571325324,
3211767232, 1532912326, 1580489324, 4287076230, 2424544333, 381448280, 2476910698, 2627301500,
1485779492, 1220322946, 1490429392, 816791163, 2624342634, 2674952519, 3550705461, 1948935820,
2392356953, 1484277402, 2589045986, 1398899784, 3581638508, 2340020597, 1368153288, 2664075896,
1009983297, 2644342659, 1464985039, 2376269173, 1784444219, 2571225442, 3422586409, 2392817262,
2155527385, 2995088516, 2289934775, 1838760335, 2705225582, 2542049740, 2216071291, 1654110542,
2052301438, 2206625092, 644637791, 2138203755, 1403547527, 1956337723, 2256205946, 2645519773,
3147795548, 2254075785, 984268661, 2422720965, 2449439908, 1535870048, 3343681457, 1675247491,
2136897885, 1523692905, 2139718284, 1718785884, 2309131920, 2359066221, 2005368974, 2847651686,
2424535658, 2255590538, 1986689094, 1635669870, 2342087042, 2294066286, 1685298088, 2206050685,
3311175060, 2307034833, 677625213, 2076808341, 3196086079, 1824959403, 2093537004, 3517291361,
1344711038, 2521810136, 1516456342, 863544962, 1590987663, 3749859671, 1603654600, 1633122116,
2151696553, 3364576933, 2474267041, 1215655267, 2844026696, 1869977764, 3047650272, 4288770983,
2256442491, 412264870, 2271636141, 1939835214, 2960701061, 1350665190, 3419510196, 1144917892,
2376497226, 2323729355, 2353026417, 1618386079, 1720085356, 2219745865, 1368614593, 2491988879,
2311696113, 607077284, 2542112879, 2058017961, 2439337840, 2272225154, 1990173092, 730526719,
2139467663, 2138859905, 2275570575, 2357498728, 1710132586, 679844234, 2460257626, 2871110035,
3585892628, 2424536176, 3424628820, 1537567311, 2697543795, 2105566640, 1658488437, 2092613963,
1537909145, 1902545347, 2946655712, 1449424803, 2205255324, 2371049359, 1903255393, 2253147791,
1835222604, 1385125996, 2072969093, 2256042904, 1938852000, 2408480611, 175203439, 1599577701,
2024510108, 1499099001, 1803917919, 2054913434, 2003187355, 1900041847, 2791415959, 9271191,
1367360081, 2593300372, 1802597000, 1552314785, 1080919184, 1672051092, 1972203898, 2288537762,
1900251806, 1166378388, 2725730636, 1804571029, 2449801373, 1150781321, 3553131637, 2444259721,
56963042, 3576784537, 845635803, 1318812833, 2239263933, 3160969462, 1516615809, 1603625561,
2256618061, 371767114, 1166711955, 2254795639, 2884854126, 1955623819, 2172803524, 2645971323,
1953704848, 1805157761, 3165829788, 1804904576, 2322708342, 1727170995, 1888459875, 2485695140,
2354635458, 1549486548, 2446966488, 1582995749, 1986960745, 2861465211, 2593217379, 2573308842,
2172820842, 9796214, 845641398, 3268250554, 2170516112, 2152295043, 2359585126, 2277937542,
2241960563, 560809801, 1898483639, 3181138819, 1853319779, 2223142780, 2678429011, 1940164265,
2083538542, 1131131237, 2897859382, 1184610745, 3047130237, 1817737336, 1334468735, 1937334598,
2728286632, 2458944168, 1437812584, 1518757744, 2123006847, 2087352956, 2374680575, 2021826955,
2576976275, 1970296923, 3013037673, 2659216511, 2711056772, 2257294230, 2390294385, 3047373682,
1267760239, 1653249434, 3501064103, 3970318483, 1104311728, 2194834343, 3569177174, 2040088955,
2412672574, 3452145596, 664830584, 2464898939, 3982114132, 2006269670, 2304551526, 1713664377,
4186482595, 2623772469, 1298315218, 1086165060, 2581239939, 2906678398, 1347781749, 2557443177,
2122343060, 2308076659, 1734447748, 2893124744, 2004057930, 2374345341, 2222095231, 2172750983,
2372702849, 2239791483, 1954452079, 2591524972, 2492229759, 2356965771, 1738569592, 2223340654,
1855095296, 1921738112, 2156163420, 2188675418, 2340445312, 2157020049, 2172359038, 2391311481,
2171937407, 2425048762, 2744868968, 1883860338, 2205190487, 2643156796, 2507576213, 2036968585,
1752070800, 1467510860, 2063567704, 3032374595, 2525580137, 1326929081, 2571601489, 2155884918,
2442042955, 3047845154, 1751589580, 2270334570, 2273548077, 932465278, 2160752553, 1919036507,
2307298942, 2206185341, 2136167814, 2124574866, 1817672317, 3097006959, 3208087126, 1474411564,
2372629145, 2505998971, 1593815124, 2321454668, 1716490880, 2540273062, 2995431278, 2792376481,
2224655252, 2005627541, 2677583531, 1452050233, 1903591281, 1419482752, 2441123433, 2187496278,
1702204821, 2122285194, 2089053060, 2942266506, 2324464002, 2578155916, 210534015, 3047250071,
2324013724, 1634562726, 2343004030, 2457901416, 2459794348, 1752785021, 1854451327, 1371062167,
2189472897, 3462106507, 2054261855, 1736992167, 2122080129, 2256037003, 2458426465, 2424598676,
2223872210, 1687570800, 3062863238, 2239823738, 2728486551, 1737659249, 2258473320, 2724677025,
1146478059, 2257697817, 3364907146, 1451408461, 3515249710, 2021314202, 616093367, 1937998716,
67153011, 1619562914, 1487235388, 1941864056, 3347386767, 3566976201, 1887546995, 2124312936,
441413763, 2170922389, 2390525512, 1450207147, 2089394819, 2684268185, 1180945290, 2910206753,
2815471721, 1463590629, 1632660002, 2475998539, 2424470129, 2370412193, 2620105766, 2991954572,
1452597878, 2789576100, 410622291, 2739752844, 2008071365, 1582235761, 2827835760, 2374806198,
3314785728, 2156427185, 2089252470, 1967413871, 2172087337, 2289505657, 2471456388, 2344257893,
2544238713, 261860960, 2772339609, 2726672435, 2457576820, 3077416074, 3326836585, 1943768456,
188317592, 1872200290, 734697132, 3759329189, 1725059388, 1886295964, 1859802426, 2844511603,
2375199341, 2441046388, 1014076293, 2628353650, 1972796781, 2440198605, 2238972283, 1853264784,
2038533498, 2292023438, 1885967486, 2509597041, 2625997472, 2325247296, 2309454471, 2222945415,
1856013175, 2172675216, 2290247781, 1566534785, 2291759220, 1770615444, 2288352119, 1919991471,
1719107469, 2170392194, 1850564474, 2055364478, 2291168379, 1937539995, 2541714789, 2156330880,
1752127356, 1854698619, 2056877718, 3965542266, 636038329, 3340544404, 3579867245, 1872331141,
1754288769, 2109431681, 2541923490, 2476506009, 2053141597, 1184137641, 1503056206, 3029113231,
2322112620, 2861009025, 1835634323, 1905958294, 1415865530, 2258146746, 2325248337, 2340577679,
2256863098, 3511385434, 2493439416, 3175912551, 2965189218, 2171125985, 4290631911, 4058374418,
1981779370, 2451067809, 2359934876, 748630103, 2308021568, 2791455928, 1586603736, 1666408558,
2677371451, 2424648787, 2426226110, 2520804875, 2190376016, 1602056871, 2385940641, 3050145101,
2710864041, 2439677294, 2126550382, 1583194518, 1771603320, 1564502135, 1239302840, 2267977262,
2392147306, 2158928272, 2300022618, 2254808689, 3164180368, 1551206238, 4755881, 1927599477,
1683967070, 2257027700, 1512263512, 3262796695, 1600739972, 2469551480, 2507252657, 1800510289,
1688016711, 2036645210, 1921518479, 2638371227, 2240853388, 2310756709, 2524683684, 2005641577,
2775386777, 4292635677, 1550277803, 3494657652, 1991872650, 1755821422, 2678136504, 1621586785,
3476730279, 2051856160, 1985185717, 3367898144, 2087696270, 2337247622, 2372899175, 1451446167,
2712953208, 1300204891, 2460117040, 2340068981, 2107282551, 2122809227, 1870362248, 2825878150,
2223084177, 1718770306, 2559013502, 1954645368, 2022342012, 2257096317, 2106625670, 2156169831,
2170777735, 2139133829, 2173141114, 2394005381, 2169993623, 2424272257, 2155118966, 2004853137,
2189851013, 2175110791, 2189591414, 2525002610, 2206596989, 2208909220, 2023585169, 1670540177,
4293432709, 2105108326, 2023538036, 2459019880, 1836941678, 2559803762, 2272166015, 2556257380,
1788052348, 3870452824, 1432319389, 1941737847, 2068676473, 2226163761, 2442495331, 2610716013,
1735630705, 1081435762, 2020640958, 2191898513, 2140040576, 2339750261, 1790019187, 1686474389,
1946117765, 1971669086, 2187566453, 1534614731, 2408207491, 2138812293, 2791421296, 1868265312,
2656339625, 2659417202, 2157224805, 1387941607, 2915607217, 2439545189, 2310054557, 1954260916,
1970965390, 2054656648, 2155033462, 2139122822, 1603569582, 2859885920, 2105853059, 1690728031,
2225173655, 1905695312, 2411938940, 2745570759, 4287734999, 2742379067, 2125606544, 2507898470,
2243067506, 1647401858, 2644145263, 3122488456, 3308414416, 2170914215, 1918608508, 2413280890,
2675671619, 2489286258, 2340378519, 1434867571, 2337954194, 2158201148, 1771991375, 2390075762,
1030184851, 1819309083, 2857526420, 2343205758, 2741134591, 1739619957, 1349624467, 2827301854,
1659073148, 2174058346, 3144509822, 1935502989, 1675543635, 746951594, 2212840148, 1992644261,
3267598451, 1702512982, 1752469421, 2276941941, 1954784954, 1883128458, 1904241477, 2256427074,
2039010952, 2186905670, 2809041757, 2706932861, 4095317098, 3183110058, 1503712588, 2841022516,
2105505673, 1756546079, 2260020575, 2046849447, 1687368065, 477666890, 3460574647, 3764303686,
2743971467, 1394255788, 2777776717, 1685829262, 1381266607, 1415659918, 2253092292, 3142875490,
2726392190, 2240081276, 2373296267, 2041602472, 206666071, 595965309, 1407353089, 3356745896,
1267298994, 1904110209, 2348857013, 1872716194, 3778354234, 2121948834, 1419084408, 2594252343,
2440061006, 2073857391, 1396876160, 2254787029, 2410250640, 2103815087, 3416233361, 2107914669,
943359136, 2356523662, 2123349633, 1366193063, 2605479274, 2897176767, 4131802226, 3019938480,
1098574972, 2376250258, 3527699012, 1297256585, 1990819164, 507139428, 2591401071, 3882400101,
1363652974, 1536731783, 2560212142, 3265429327, 1518554741, 1921028015, 1791727213, 3025502567,
1953648288, 2845151349, 2309453711, 2022150280, 2344449660, 1786282619, 2132505018, 1636459147,
2742196560, 1419217274, 2241701815, 1936957025, 1850697849, 2269487445, 1149531563, 1803719013,
9482324, 1950375029, 1984065384, 1936104316, 2122493589, 2794150476, 2257286006, 2069671535,
1517644874, 1953254537, 1501063804, 2206616905, 2122668162, 3101995343, 1920099519, 3211284291,
2458304873, 2003594673, 4293836665, 1970902736, 2928174694, 2812512346, 2370530626, 794129811,
1738041944, 2242807083, 1617832101, 2106029146, 2190762558, 220558951, 1720846940, 2476641592,
2507559009, 360394122, 2202887296, 1112967283, 1284408751, 2323055734, 1191203977, 1955240363,
2389868244, 1262442865, 2105158799, 2030903180, 2810299545, 1946625739, 1061632686, 3127944707,
3298761609, 3080418767, 1412936960, 2629265800, 2343473730, 1472175701, 1230605056, 2239132784,
2122401401, 2475648472, 1950912386, 3263212288, 2394263863, 1903217359, 1247303323, 1159363459,
1699295090, 2435681381, 2667601426, 1088396933, 1161804624, 703674431, 2641635735, 3175040321,
2742524276, 2526426222, 1431952929, 3764940161, 1496454938, 3731834879, 1870882168, 2934388264,
2369625471, 1500401663, 3011939715, 3056503623, 2880585603, 1211071532, 1501466040, 3316541026,
2138581704, 2461468273, 2142877582, 2510487386, 1633844583, 658878294, 1200394299, 1707234339,
2912209295, 3162707828, 4288497139, 1785109843, 3329587363, 339781753, 2237214699, 3781642057,
1014592256, 1098680484, 2624106367, 742339976, 2827129911, 1988857438, 2899089794, 2422171849,
2573891744, 1116169052, 4282832728, 4288506684, 1285838456, 627289458, 3211895840, 3082178692,
1889108647, 1903532940, 2443222114, 1785799232, 2543189865, 2824695164, 1954174689, 2489937028,
3193662140, 1811117894, 1100119552, 2003490451, 3211220602, 2223219032, 1417636225, 2624166765,
2106040742, 2217292962, 1876670975, 2771959511, 3047465151, 3352415964, 813334347, 4018543999,
1144977837, 1068906639, 2360528851, 1795157602, 1535153533, 964314414, 2051496058, 2035378790,
2236846221, 2590145074, 1318977603, 1675250046, 2556403790, 1902743090, 2013173345, 939575425,
2441293386, 1581588171, 1561361029, 3770183846, 3193140353, 2073143174, 2239542085, 2356513259,
992904321, 2946393976, 771800391, 1987930368, 1558739267, 2136697059, 2672585493, 2839684665,
558785909, 2401082480, 2917037459, 1775669248, 609856409, 2136759395, 3711732619, 1763207604,
3749539221, 2182578625, 1563571175, 3257728949, 2235071624, 1870112181, 3143764135, 2556720440,
2019675821, 1663990892, 2761293583, 2774026109, 2771797725, 2910084661, 2562158198, 1934596448,
2698755697, 1836890408, 1751348653, 1813721087, 1752393802, 2927108515, 3691395436, 1048613632,
2766392642, 678978084, 1638801063, 2686868080, 1933134441, 1025872765, 2394203219, 1416600956,
2035186297, 1476433047, 2656120876, 2136635261, 2425909614, 2105450899, 2231414705, 2404087228,
2267912855, 1806471060, 2075110195, 3920968535, 233162555, 1839070993, 2077853009, 2410888913,
1938666341, 1905178446, 1953272743, 1821527398, 2849089956, 2541709176, 2608237210, 2857387888,
4287920736, 1610630546, 1651347054, 2205463412, 3029037653, 1886412205, 2774898516, 2407892092,
2352116717, 1627416253, 2626368141, 2649261907, 2110635930, 2175539923, 2541500091, 3069614518,
2525191331, 900037759, 3783424928, 3450383668, 3149676519, 3070187387, 4279647061, 2225438550,
2540341178, 2118475852, 3732764725, 1561751984, 1838563102, 2479458885, 2880655147, 2692192191,
2842441131, 1716885312, 3180240079, 2827995392, 1420019076, 2073580381, 1386938129, 3137825392,
2909114758, 2572384617, 2474347691, 2521912064, 1541169851, 998547163, 2613622350, 3043373741,
2788859781, 1755815643, 1635015021, 1955750345, 3918171254, 3816332930, 1383428032, 2575712942,
2056680703, 3372200759, 612800090, 911595941, 1127652435, 2240170538, 4073760224, 2607564237,
1701409132, 2348844364, 2841553990, 2753642603, 2929418051, 1233421435, 2760005936, 2453298730,
2529558406, 589788846, 583550111, 3060303907, 2476447436, 1227143636, 1969062219, 1873293389,
2394457507, 3452397824, 2994811337, 1798922650, 2576480896, 4291143661, 2863055992, 2241150544,
3245269275, 2827255060, 1568244655, 2565823067, 1868855401, 2063105399, 1296913027, 2861145384,
2304869228, 2147524252, 2073664337, 4285038484, 2170184524, 3184343952, 1925420381, 3899823965,
2171366744, 3114418550, 3142811071, 1917091539, 2293727744, 2676335767, 2794022340, 1368945986,
2726724476, 2079811974, 2465492603, 1905553594, 3566706494, 3043229842, 1838250702, 2239701396,
4281773477, 2221277607, 3668622454, 2596505697, 2990777083, 3143914868, 3568404009, 2812180223,
2014872191, 1451657084, 2356591239, 3465916182, 1456646989, 1973648204, 1015317428, 2039449780,
4052785765, 2877261398, 1199186291, 2573645567, 2306352769, 2785051806, 2191981735, 1265793066,
1858588212, 3347196019, 993634108, 1084398283, 1851293823, 2176225908, 2068610161, 2576381255,
2390847869, 1828748144, 2156097717, 3372900004, 2523104382, 2491843222, 2070241503, 2812790214,
1733124906, 4287795043, 3359804398, 2323688949, 1538999988, 2818604506, 2658962577, 1030824800,
2380427905, 1808220844, 1617351625, 1045706020, 2811196928, 795120336, 136136575, 2342675032,
2865929280, 1941827655, 8564891, 1566095241, 3078784577, 2891393102, 2743436174, 3148313653,
1571392831, 2214568625, 2762186602, 1956152641, 2573631062, 3348135552, 1302626303, 2621991057,
2926681402, 2000135116, 2139858825, 1519157089, 1419613486, 1659240306, 2730566219, 1621984609,
2217949605, 2154603419, 1448964510, 2207932014, 2852095324, 1722779201, 1263440605, 1852873407,
1737001571, 1538770297, 1786487353, 2001438567, 2039545789, 576422830, 862375056, 2355657800,
2053993528, 2153937857, 2455151615, 2689957326, 2775670089, 1820573031, 3433743244, 2573698482,
1052804747, 4020211558, 2006581198, 1146776187, 560967300, 2906935114, 3008329912, 1736689592,
2154780989, 1995155638, 5996260, 1869767228, 1916622138, 1797553301, 2067241354, 1772520894,
3830680947, 4286467911, 2304534931, 2171448144, 1990884516, 2525396844, 3015927138, 1984643954,
2379743425, 2661713478, 2526725752, 1453290219, 2209243753, 1718067840, 2075745363, 3820505696,
2340618343, 2233888149, 2038653536, 2931047569, 2494005361, 2460768866, 1870490815, 2075438956,
3063126937, 3331954836, 4288059241, 2490677409, 4052172911, 4290394443, 1971427132, 1214271430,
2558543481, 3077739165, 1486190959, 2030672525, 2092849502, 1097529356, 2296487216, 2193405012,
7697236, 4291984815, 2421021300, 1586386542, 2908903042, 4258709045, 1390259128, 1617853832,
1699896692, 2239409502, 2155068033, 1811960487, 2084117094, 2538055240, 3045568082, 1911066943,
1354906466, 1957819542, 4285092977, 1852459875, 3416548519, 3535713903, 1736602214, 1451581311,
1986199446, 2742907022, 1216107227, 2091097470, 2810548041, 3972373648, 2774370190, 1705008521,
1434058690, 2459211675, 1787532743, 1569483557, 1335925333, 2085772891, 2941235626, 2709356118,
2969543471, 2254800535, 2477354939, 3125577623, 2054422430, 1666554990, 1099026539, 2207945054,
1853976161, 1365023683, 2847259986, 3441704080, 2610972821, 1968978340, 2810445671, 2378854130,
2105783391, 2372107689, 2235792087, 3233904486, 2427226036, 1990757810, 2153513091, 1571441262,
1758895930, 2240655733, 704649372, 1588488801, 1640678148, 2104157102, 1283451538, 4073406476,
1417228088, 4067863163, 4176416052, 3822533833, 352301549, 4225008883, 2966856794, 2387956347,
3288297085, 3196146242, 2240578680, 2846126266, 2560068444, 1577812100, 2121388969, 1248421723,
933199050, 1617205394, 1787916615, 1855652043, 2863544983, 11309689, 1692072544, 3819010226,
1206629859, 2373470079, 1528175445, 3128369192, 1217357376, 2346349500, 3884545400, 2509736813,
2707850581, 4288565558, 1042932473, 1036046868, 1044706087, 3151670974, 1044635600, 1050108320,
1047335586, 1041338286, 1038329480, 3171199086, 1027458487, 1026846921, 3170955028, 1038272791,
1042099733, 1023631841, 1045623678, 1036850238, 3169992935, 1024287600, 1049767013, 995219795,
1040643307, 998947591, 1036960834, 3179608228, 3141474354, 1039120063, 1014755058, 1037214547,
1026831299, 3161435107, 989095806, 1012618819, 3173055039, 3167954080, 1029698723, 3161365798,
1020350416, 1035914227, 3175887125, 1016829433, 3183727383, 3158569601, 985916898, 1030089263,
1036454680, 3156054842, 1034743508, 3150866466, 1001270247, 1034190346, 1026856113, 1023816386,
1025003399, 3154975140, 3159031758, 3181516378, 1017520469, 1006920169, 1026471603, 1026108426,
995969210, 1009538160, 3159696075, 1016583445, 3150715858, 1014529258, 1008555538, 981846227,
1015419886, 1023845324, 3171510193, 1019527226, 1020908842, 1025199819, 3154815959, 1020766835,
3162250959, 1007879529, 3145757836, 3162556466, 3145088904, 1022244160, 3162319549, 1033161556,
3170004997, 3179242728, 3171476541, 3168027689, 1010205841, 3174575065, 1025535253, 1034040803,
3154321149, 3185116122, 1015042743, 3171072761, 1042197925, 1031880174, 1041379394, 3173578024,
1036593162, 3156042609, 3177068509, 1034306201, 1021755086, 1037171564, 3166520301, 3174861139,
1042442184, 1039408677, 3211598967, 1063993918, 3214289855, 1066729320, 3215091656, 1067608008,
1058473425, 1055736216, 1054558327, 1063297440, 1055686113, 1053456059, 1053046526, 1058930617,
1055175399, 1055547741, 1060943505, 1053020745, 1057992678, 1058329294, 1057580897, 1059872046,
1053422499, 1058662413, 1057713315, 1063441270, 1051529937, 1057582539, 1055260105, 1058488996,
1056874455, 1059299483, 1064722701, 1062051663, 1058006609, 1057492867, 1057124224, 1059576570,
1059172961, 1057011907, 1058954562, 1058304555, 1058634745, 1053874528, 1064950885, 1058061724,
1055327304, 1057684010, 1057613151, 1057127010, 1057215669, 1054258060, 1058885185, 1054363004,
1057714069, 1058454715, 1055368282, 1056380665, 1056908842, 1060970973, 1055869444, 1056191281,
1052282792, 1057108079, 1049390702, 1050919932, 1053250032, 1048624365, 1060940324, 1053426578,
1054342651, 1057317567, 1050209903, 1049810963, 1050441118, 1058141981, 1053128956, 1048935443,
1051213622, 1049666355, 1065353216, 1055890495, 1053174472, 1049231492, 1050745898, 1047192366,
1050786723, 1049574412, 1053562360, 1053072316, 1057507729, 1057367590, 1056079662, 1058463884,
1052494894, 1052580291, 1055205078, 1060115266, 1058303732, 1057790119, 1057549084, 1055993629,
1059989068, 1058558954, 1051178684, 1051282195, 1058567206, 1057040208, 1059791824, 1059472539,
1053583692, 1053931205, 1052483939, 1059790662, 1053767605, 1061726074, 1060099530, 1052563253,
1058779104, 1060662324, 1052805962, 1052883783, 1054990562, 1055979719, 1056028454, 1051613030,
1054551384, 1049019091, 1054663780, 1053511956, 1054675325, 1049570100, 1055518538, 1055157628,
1058903396, 1055315307, 1054629148, 1057311364, 1056336387, 1056296286, 1065353216, 1054265834,
1049974239, 1047653313, 1057291978, 1054848638, 1060135905, 1057007033, 1056277221, 1058717363,
1058149170, 1055662652, 1056756865, 1059471026, 1057994776, 1057341594, 1061162024, 1058353051,
1053481820, 1055676362, 1058285050, 1057169197, 1060750194, 1058895947, 1058298761, 1060738436,
1055935944, 1058929747, 1055845734, 1051893656, 1058198359, 1058048579, 1054462770, 1056562600,
7, 2154921508, 1770887538, 1804571171, 1655211415, 2260834924, 1233620849, 2977933677,
1719370851, 1966699904, 1851498616, 2471624773, 2124326201, 2058003269, 1484223343, 1618630048,
2540060241, 1482408865, 2828046186, 2774821528, 2340195995, 3515246248, 2522589317, 1752967824,
2256904302, 2423408752, 2462826355, 1502910374, 999581839, 2341698925, 2558685392, 2906629262,
1854834319, 2208474045, 4280128122, 2173539967, 2152229394, 2744758398, 1717462646, 1452905860,
1601664399, 1539743144, 2535755862, 1871590026, 2659737564, 2123405764, 2458221663, 2171823953,
1803395948, 1870633160, 2306248567, 2610895255, 3164963712, 2033815449, 2911135387, 1370579833,
2022673047, 1704893083, 2460899476, 2507711131, 2748544220, 247032917, 1937937467, 2744607828,
2257874561, 2294385269, 1719141738, 2578311758, 2460375673, 2441442209, 2090906229, 1937913994,
2187869291, 1132366848, 2006871379, 2457064046, 2777546974, 2324276870, 1451790152, 2624298133,
2088872309, 992761999, 2743576689, 1552185754, 2198630813, 1921418225, 2422624023, 2810410386,
2035250813, 2338811502, 2422774663, 2036441023, 2128242228, 1485211460, 2257605976, 2643372192,
2474677117, 2309851065, 1183029565, 1970551655, 2122408834, 1485082263, 2172753038, 2152033083,
1654829726, 4288965760, 2865163625, 3146361924, 2347001747, 1301052555, 2107875722, 2288537007,
1737642078, 1183092587, 2173196165, 2274521769, 2356300089, 2372447354, 2879031210, 2775694482,
1788444768, 1284874646, 2422168912, 2189786489, 2710268793, 2473573741, 2192800790, 1988804739,
293228591, 2796140543, 1102156389, 1687245194, 2239063437, 2373227152, 1636399502, 2697687020,
1454804295, 2141090924, 1787006353, 2170778741, 1582460057, 2291359616, 2950115127, 2611061721,
2562696639, 2307030171, 3163209639, 2406381717, 1383270777, 1990425954, 2540559977, 1617987909,
1520741015, 1934182148, 1870571438, 2263191878, 572029663, 2741595192, 2392037987, 1866488439,
2187826822, 772964329, 2560654669, 1317234560, 2525066066, 2151322479, 2546118292, 2961888539,
2913242276, 3149902509, 2329787746, 3970778155, 2732289398, 1795180381, 1939053954, 2707740767,
979011488, 2255907109, 1755610219, 1769185461, 1483965842, 2746907525, 1462598810, 1622568591,
2426826903, 2269073620, 2155452320, 2659935864, 1333218110, 1820167796, 2677121381, 2575608480,
2286980761, 1955747436, 2324928369, 2105711616, 2927650436, 2290981454, 2290581371, 1770952573,
2322826614, 2873980190, 2190776189, 1075212380, 264273020, 2440129406, 1482463052, 2845215077,
2641598565, 1194813072, 2072289781, 1378852159, 1889543242, 1181527352, 1768772473, 2286330723,
2207619705, 1950315395, 1956164180, 3064690785, 3230703252, 2627272619, 2779029918, 1600945778,
2493090377, 2573909607, 2878559618, 261198202, 2707396774, 1083603568, 866758773, 2630988166,
3399518860, 1566874535, 1638037890, 1921688468, 2488615719, 1986362755, 2389484062, 8214936,
1804435812, 24270281, 1972357758, 1567938942, 2070716812, 2091680912, 2691007906, 2218496814,
2004405390, 848203120, 1904901263, 1802969929, 391347813, 1831237726, 2574176673, 2609351630,
3377882274, 2996872203, 1351183803, 2064616288, 2119854450, 1385380125, 1922075485, 1737523799,
2440315259, 2535951742, 2069326294, 4291274249, 1972695382, 2423222935, 2813313889, 2072599221,
2419946080, 994535765, 2104396104, 2256195705, 2335928403, 2141815418, 1979490700, 3450666350,
2707136719, 3513501313, 2875632295, 2424562061, 2694482286, 2711977945, 1535836159, 2862242756,
2676074839, 1752791408, 2139240570, 2320542803, 1969518683, 1990046305, 2487452980, 2675018597,
2829216855, 2411886905, 2156376044, 1167166071, 2573974887, 1553299249, 2459211152, 2306963115,
2306453383, 2323150464, 2741924217, 2979500606, 2609618603, 2063569570, 2108258901, 2553758585,
2291489676, 1585085052, 1399223141, 2021809279, 2037560194, 2087145370, 1333884116, 2696899250,
1570539408, 2593879371, 2350285444, 1347281378, 1249599598, 2339880565, 2528212602, 2241235878,
2049084598, 1971874173, 2676259218, 3079923353, 2290059429, 2373686941, 1687590761, 1998959259,
308084676, 2829285469, 2391712086, 1987276359, 980772221, 2289225372, 1835522662, 1721005357,
2725095816, 2003268963, 1770478491, 2371261531, 2171167329, 1131906653, 2389738354, 2103796906,
1854509716, 1597790395, 2592442029, 2123990438, 2134552005, 2641336430, 2105241241, 1666678874,
2508303509, 2036119236, 2645454938, 1299082614, 1615561586, 1935047525, 2219152483, 2958063376,
2056222534, 2657836433, 1634043562, 1654946419, 2678950292, 2121820287, 1518375333, 2557280104,
2372682871, 2138333520, 1669242482, 2274071426, 2322950513, 2087874944, 2476196096, 1923196798,
1734973818, 2010349880, 1785230206, 1887275142, 2172280179, 2342351706, 1335009155, 1920299378,
1902077295, 2139456810, 2425387439, 2308028778, 2055048352, 2223870844, 1295400058, 2274186837,
2206387068, 2008123203, 1786097004, 1347782048, 1904910775, 1836090801, 2404746422, 2791208323,
2792852630, 2521653145, 2526399127, 2579138234, 3048437650, 1404142483, 2035573340, 1450930791,
2187323747, 3326237230, 1737780798, 2694405715, 3127870338, 2694422188, 2505353611, 521221768,
2089188928, 2590834534, 3550164856, 1216124814, 1533757741, 2510589352, 1282450825, 1263557503,
2560663113, 2238427801, 1363163282, 2544021418, 779042895, 2343749529, 4056112771, 2288013424,
2116854109, 2037098389, 3025826385, 2005270378, 2426492817, 2322237881, 2845398833, 2541654334,
1418765958, 980592442, 2473202797, 1953923482, 2559478143, 1869120855, 1434933929, 2426120079,
2122171757, 1756004245, 1820028040, 1667660184, 1769307753, 2433310848, 2004121164, 1985770158,
2305588577, 1516860769, 2055183224, 1754617948, 1668786812, 2200730229, 1972283285, 2374225574,
2072793234, 2140445602, 2406964331, 2038890631, 1702914459, 3214112360, 3429342342, 2055264393,
2958852445, 2288682496, 1633399897, 1837025911, 3248630198, 2370604193, 2408545234, 2910092679,
1083144036, 2337378665, 1782347883, 2186725478, 2959876129, 967664210, 2640746830, 2628601891,
1150045552, 2155033544, 424175001, 613768992, 2372895603, 3583279464, 2827983503, 1485993883,
1938140817, 2137019030, 822192309, 3216420526, 2138476936, 1300407645, 2427227782, 1971499941,
2979953039, 2156956294, 1516193392, 2503503984, 1971674714, 4289765193, 1973262472, 2895089524,
2005022639, 2208001471, 2741289846, 527267928, 1604290160, 2624057956, 1952542329, 3450451058,
2689044128, 2993976474, 1768249716, 2182529479, 1518178387, 2103208044, 1347466326, 2206629571,
1989148830, 2289732987, 2055171682, 2674088330, 2389934964, 1920292210, 3161958251, 981420655,
2190452616, 2660805738, 2744336750, 1970766425, 1748907886, 1818840461, 2122428290, 4168389400,
2142414533, 1334602905, 763011745, 1703574044, 3266630285, 2995232165, 1939193210, 1080721499,
2292040009, 1802805884, 1806854515, 1533379710, 962888276, 2287951708, 1418151942, 2640569875,
3180714357, 2964443016, 1266848054, 3095178095, 2667550414, 1770083928, 2139920733, 2473759853,
2288862355, 1972340624, 3494220704, 2424928915, 2340322419, 2186654305, 2978849913, 1890960315,
2546696843, 2141603175, 730686066, 2828177500, 1449548136, 1450544222, 1840020365, 1752732019,
2436874551, 963772527, 2157095045, 2523040659, 1551658344, 2310309593, 1109475686, 276443443,
2139218048, 1766475112, 1972472476, 675057256, 2894167451, 2341436293, 2547554697, 2980354951,
1735286424, 2638905473, 2773193805, 2470996347, 2727575380, 2219474532, 2086232441, 1462798436,
2220771665, 2877862766, 1470562349, 2423155080, 2711279230, 2374649965, 2474295943, 1563784342,
2561318767, 2557133160, 1952599891, 2137624669, 1934281068, 2508301948, 2695984006, 3143600407,
1385604229, 2610869914, 3548025713, 2559932276, 2139901267, 1451532080, 1953264766, 2358276778,
1033345674, 1098562523, 2813549214, 8696966, 1767146576, 2258141828, 2088013734, 1820906160,
2489802899, 759581011, 1922077839, 2426222997, 3080880504, 2302903154, 1602071460, 2190183056,
1887664970, 2474157949, 2489675133, 1933086559, 2306504562, 862073108, 2440722220, 1030985329,
2256044398, 2290519135, 1493198208, 2207292272, 1669749602, 2190175857, 2828775312, 1635744405,
2054850221, 1939634507, 1904302636, 2139058561, 3094284299, 2325980387, 1918543740, 2777636541,
3313075818, 2896191354, 2221442502, 1854570364, 3967967588, 2556399938, 460876167, 2675932850,
3855194707, 2069553590, 2378081125, 1942891090, 2397130594, 1720481850, 2325438370, 2490653506,
2139661490, 2214607796, 2442283853, 2677236830, 2339859829, 2019785348, 2477689448, 2924644935,
3114222480, 1786314544, 2793840243, 2858969414, 1568130117, 1137797259, 2137694310, 1549835404,
2776609635, 4001855894, 1434550678, 1317634191, 2396829062, 2590542933, 1083355813, 2262069120,
2557055108, 2710408584, 2341634184, 1818002269, 2961535356, 2289599864, 933966180, 2425252720,
2084664443, 2757399667, 2141688730, 1850572914, 2726516374, 1535672987, 2358205851, 2037869175,
1097103972, 2223863350, 1811974015, 2525386925, 2288803430, 2376172967, 2038135656, 2038502974,
2284625792, 2658300786, 2442257835, 2426124925, 2074451802, 1769356401, 2239464827, 2187155711,
2592242517, 2173208443, 2860628608, 1531932081, 880961954, 2242935572, 1805162900, 2508615063,
2288869086, 1637129856, 1920952944, 3263216475, 2257672619, 4083659658, 2155121841, 1651478388,
3397309043, 1889772196, 2056101796, 2239711628, 2089053584, 2119206295, 1500871779, 2089203588,
1937546371, 2558880106, 2457238143, 1870639216, 2258345067, 2389610339, 2743038272, 1738254927,
1952215422, 2156360023, 2275312321, 2004454799, 2456259677, 1837537665, 1199346295, 2288876671,
2174124173, 2458149968, 2074700414, 1838320993, 2139127155, 2223803040, 2054316421, 2794362761,
2172714879, 1699889497, 3967468425, 1863287722, 2397617568, 1721325567, 1840140897, 1936233335,
2815077810, 1474320297, 2306119295, 1241557617, 2238985828, 2377408310, 2976341191, 2355060837,
2558403405, 1600041019, 3851571295, 2208125546, 2880218476, 2475326855, 2087230088, 1817090414,
2861445196, 2256253562, 1331584617, 2642850707, 2690737015, 2204532669, 2154405315, 1951158961,
1817028271, 2658842232, 1672441537, 2358078534, 1969389983, 1735094137, 1085708672, 2742076600,
2155186316, 2220907890, 2340946084, 2609064509, 1883059567, 2288018806, 2726533281, 1769895764,
2022210960, 2356905317, 2022075784, 2672965297, 2642835354, 2612905040, 1686869124, 2306574461,
1555926192, 1887985209, 1786290588, 3431824798, 2374661273, 2067305340, 3163325044, 2741731994,
2169863526, 3427650697, 1586474912, 2089453437, 1667375039, 1985526660, 2812581512, 2105391289,
2121304933, 1194411998, 1417986669, 2072117125, 2946665926, 2085835412, 2524079720, 2054397258,
2324725144, 3349715362, 2120669951, 1858628200, 2528337552, 2406388729, 2422174823, 3297623432,
1892188547, 1600818810, 2622845100, 2188153742, 2205055717, 1268030278, 2340717432, 2341322216,
2911338634, 2291307381, 2139796446, 1434766716, 2306173559, 2140443765, 1536722045, 3296291659,
3029043840, 2257039454, 2190500926, 3046078378, 2509744459, 1040150360, 1917889152, 1905491587,
1970902654, 2390002304, 1487174550, 1672434559, 2188547478, 2289539714, 2072633958, 2291101310,
1515886968, 2558956428, 2172757913, 1987412806, 2859700089, 2155809408, 2561555057, 2897394007,
1265204662, 1636394631, 1153973124, 3562585995, 2960097174, 1070307220, 1926069101, 2050730334,
1536684171, 1973455469, 1970263158, 1705864102, 2072927841, 1924575872, 2107043431, 3112762488,
2345512031, 2087808148, 2508421551, 2293135419, 1885040701, 1465954201, 2222980987, 2726395500,
1937865323, 1717984363, 1668845694, 2224912037, 1396991120, 2206173612, 2460113030, 1708289659,
2259578766, 3398857271, 2508099199, 1656982889, 2072339862, 2021153155, 2225560757, 2222504291,
1333955521, 2055238544, 2090505668, 1870622037, 2156555111, 2101765667, 1283027094, 2122579842,
2315274734, 2539097709, 972527262, 3780456226, 2304526463, 981898142, 2684076660, 2913363320,
1902344847, 2226618704, 1552957160, 1367432503, 3167333538, 3294386168, 3213933436, 2386646839,
1871458717, 3883588910, 1934908778, 1872407505, 2860526696, 2265448547, 2594167219, 2726426765,
2138972800, 1999078590, 2526510513, 1899576692, 3409402516, 2372459381, 1667084150, 1685540668,
3614557334, 2522638433, 2258206094, 1748075147, 1787941302, 2905843610, 2788793192, 1968013413,
2021103033, 2052800057, 2793060510, 1969979843, 3502346592, 2256435299, 1989955001, 4838118,
1348830747, 2072228997, 2893572863, 4037250455, 2355406772, 1990488189, 2274193505, 1603760257,
2338684021, 2977330323, 2538574457, 2545188080, 2510654886, 2424189775, 1065254278, 2221062254,
2794091422, 2059706926, 2042053482, 1838188921, 2223610717, 2086099609, 1199269225, 2241543829,
1870680953, 3533274457, 2306393719, 3215945564, 1585884312, 1409324174, 2787284100, 3780225349,
2427626898, 2739315403, 2034222154, 2756541028, 2136240025, 2520667252, 2271761564, 2892465561,
1503491124, 1651283354, 1470326958, 3347409297, 795961286, 1565276798, 2171846572, 1601460551,
2190059185, 3160389476, 2003779462, 1888584080, 2137877880, 2021553003, 2610720593, 2289932171,
2273555853, 3364191305, 2087474533, 2223736433, 2994303855, 2106683279, 2278278822, 2140251609,
2759150480, 2676909210, 3012718702, 2277030043, 2983768715, 2257190862, 2530262393, 2172825227,
2575670684, 2223544686, 1836481677, 1870821021, 2306181239, 2762728906, 2625998502, 3009312398,
2629747520, 2742211719, 4290201284, 2020439859, 2838418820, 3947261887, 2473361637, 1363366523,
2559120954, 2361940151, 1804321395, 2352712581, 2059505747, 1586007944, 1519615592, 2208866654,
2138607469, 2642271897, 2262992250, 2875959709, 2023319194, 2339790710, 2108600679, 2106617503,
2891028901, 2242283186, 3042947701, 1887526047, 2354410435, 2941627473, 2021230690, 2120580984,
2054225809, 3129123509, 3081231233, 1656118904, 2555041624, 2159637568, 1822019992, 1853727624,
2192146259, 2222037874, 2525934158, 2093050218, 1195093447, 1367239279, 2155882368, 1871421082,
1685226608, 2258919516, 2388116372, 2205526128, 1990551906, 3078191992, 2220286356, 2709828730,
2160029075, 1346722345, 2642908289, 2021710455, 1906475686, 2075890792, 2713289918, 2939639461,
1535923677, 2341759653, 1954909857, 2978442353, 2390255785, 4002491679, 2207083655, 2323185526,
2524918865, 2591710359, 1604093803, 2003997577, 1805490347, 1419155813, 1116769098, 1872004502,
2157418612, 2676839766, 1435075451, 2961601414, 2778687890, 1215272811, 3411702896, 1901100664,
2426841019, 2038209700, 1873580161, 2056754080, 1887275380, 2109640633, 1802468559, 578515553,
2156003200, 1066561703, 2172217230, 2992935598, 3315182694, 1554805086, 3115739814, 2190251604,
396457304, 1609498544, 2154591823, 2188750740, 1920363680, 2587713365, 1965599103, 2075300238,
2459141997, 2307526059, 2258225079, 2375337363, 2842589730, 2240717743, 2190897407, 2093334393,
2407355538, 2272923769, 2141038568, 3130628727, 1086094200, 1703515023, 3784060550, 2410721191,
2372901809, 3114411373, 883659909, 2160753648, 1664668558, 2357560932, 1084776092, 1855885173,
10777198, 2092330873, 2033807582, 1082100881, 2004171331, 1921343634, 594838929, 2206310820,
2832171175, 1768841580, 2072082821, 2507315236, 2507978204, 2605564800, 3747456188, 3479725379,
1849162380, 3198640784, 2801828210, 1936618614, 1756736557, 3057549515, 2793604897, 3798739301,
915188799, 1589784736, 1647539254, 848335769, 2053843124, 2660186773, 1405127048, 1151062442,
2391514040, 1923135342, 3061923347, 2289269881, 2527566893, 2192087168, 3070255978, 1782476119,
1870237526, 1465091997, 2523571079, 2491135851, 601470046, 1755164546, 1550952362, 2205066365,
898861484, 1559459995, 2443076544, 2074426524, 2525269926, 1853539758, 2188903005, 2003981978,
2677048169, 2138147396, 2209322065, 1818591170, 2039055495, 1820361875, 2642111296, 1320061065,
3047195779, 1571212620, 1719130763, 2105960229, 2405339533, 2552547258, 1959488153, 1285915559,
2340060039, 2708898659, 2107210159, 1674937195, 2419631426, 1497980568, 1500762460, 2188620923,
2859288894, 2021090195, 1993035963, 1224721795, 3096467260, 2122512002, 2492050092, 3077010785,
2340977552, 1149995360, 1617870217, 1400273812, 1015054668, 2824055219, 2801745579, 2323474063,
1904193925, 2407372158, 1819968116, 2643548085, 2915529091, 1637265526, 1857332292, 2625538323,
2040505205, 3463552385, 2574864037, 1942777947, 2728621489, 912426837, 2055645318, 3211094310,
1703250075, 666139728, 2290259882, 1185439053, 1266445866, 3435050158, 3034798423, 1778431866,
2090760771, 1818039886, 1905358735, 3338107997, 2993314909, 1633728680, 2037733459, 2170596478,
2274762177, 2690217877, 2225038419, 1719440755, 2402587539, 1584161900, 2879221432, 2373311603,
806944897, 1987205744, 2247143258, 2714739803, 1317051297, 2072536939, 1199594111, 1419353724,
2022093952, 2391624890, 2180147018, 2206750599, 3010094939, 1903455641, 2694635664, 2389500603,
1773510078, 2542767239, 2303708522, 3248981060, 2508493984, 2243070073, 2211283856, 1602853042,
2306167927, 1784448679, 1618110327, 1168537200, 1604753553, 3062597688, 3497373793, 2644413247,
2608043896, 2491062084, 1906482858, 2794417055, 2274191963, 2612105362, 2158407016, 411992717,
2069674050, 1750288463, 2222933619, 2489823899, 1922335643, 2071815266, 2260425630, 1836208512,
1871613585, 2273116025, 2490005188, 1956811373, 3267331686, 11109028, 1615629127, 2877506717,
1134987809, 1365607016, 3092811140, 2442932415, 2406124687, 2607313301, 10777502, 406487391,
1770628753, 2084273752, 1720875371, 1316936115, 1820096625, 2291701088, 2339604886, 1934524576,
2659541960, 3062379904, 2021950088, 2711249154, 1906221964, 2646382688, 2072010880, 75968947,
2711445351, 1756267957, 1618032808, 2859631773, 2557585727, 2156103066, 2759690618, 1368355967,
691386680, 2072414615, 1567013749, 2391431818, 2541307296, 1836707969, 1902944896, 1752001187,
1829866628, 2558472448, 1315868266, 1971981963, 1805092476, 2911802243, 2236330108, 2087619202,
1567521215, 1757776519, 1533511493, 2005300918, 2231016057, 2374522251, 1394515801, 2474797154,
1172337523, 812933275, 4290670517, 2608110740, 2408760983, 1470117217, 2361555604, 2659356266,
1736845453, 2292228252, 1757389993, 1468220250, 2356575092, 2070323168, 2526251371, 1952022186,
1537051271, 2038799668, 1683261574, 1821014896, 1583988072, 1634896529, 2025689004, 3062001093,
2005035909, 1737129838, 1819766862, 2223272322, 2290457678, 1666029994, 1903869328, 2475057280,
1432253083, 2140760667, 2274261130, 2893975489, 3314652063, 2306473847, 2055976371, 2140959606,
1702395265, 2290402467, 4290930048, 1555729118, 2037023806, 2226409650, 1821139850, 2292146616,
2644668562, 2141747845, 1438954649, 2758115673, 1584943327, 2642903940, 1619117649, 1367979890,
2694472080, 1802858329, 2342608495, 2527753409, 2288480374, 1703315333, 2557146472, 2038994564,
1669039227, 2290254479, 2675801736, 1770096234, 2574164612, 2390918045, 2324988270, 2020382868,
2106750602, 1803516280, 1819963262, 2508550769, 2356310911, 1385859712, 2238211174, 2562826911,
2375267936, 2290182546, 2206371441, 2474791553, 2206495134, 2323617645, 2458150250, 2222456956,
1937409903, 2140376168, 2424992636, 2258935951, 2525659767, 1867415927, 1754475776, 1750561182,
2522976374, 2191944527, 2274731341, 1719755653, 1867343466, 1517715070, 1988978549, 2257033041,
2326433294, 2406641841, 2105515907, 2459392281, 1149342847, 2039184514, 1853713242, 2608812664,
2139266434, 2674883552, 2610725230, 1933206662, 3565768059, 2976284748, 713212208, 1957410478,
3311568764, 916247095, 2172615028, 2835359305, 2088792154, 2523036296, 2471976360, 1622112934,
2441558185, 2206441895, 1820349108, 2020510571, 2493213504, 1451048019, 2307091289, 1568399329,
2910805124, 2155910784, 2555018111, 1587042200, 2415887972, 949779840, 2679595430, 1419211144,
1335589948, 2510636419, 3023672425, 2377088607, 2675130721, 2123722648, 1168735144, 2960893799,
3093473172, 2224248174, 2378535775, 1264925048, 2119980703, 1551660172, 2189226099, 2258342291,
1719118799, 2358301333, 2189545597, 1434608147, 1266839681, 2461760145, 2427870612, 1820975463,
3816992152, 2204659276, 2102772831, 3902971193, 2125044337, 1390587093, 2157813125, 1249082243,
1615901632, 2330214758, 2708585611, 2776706866, 2559334755, 2141622890, 2037484902, 1534106494,
2013226317, 2305122651, 1298112178, 2222898300, 2059451994, 1987552427, 1703381877, 1165403482,
2625225109, 3110303626, 2000854636, 2270650738, 2886362762, 2037364991, 2292221277, 2357371322,
1321048712, 1822075947, 1565101210, 1672376516, 2457709976, 1820626562, 2275240623, 2372243606,
2340000356, 2053160785, 1534467418, 1081171582, 2055566982, 2655877304, 2645127826, 3114880407,
1182627950, 2154261353, 3458634355, 1249285819, 3213140630, 2364711239, 2269539712, 937341530,
1987349895, 935162240, 3493180022, 1674604641, 1685032068, 1146854526, 1416467045, 1568782753,
2507249525, 1063503231, 2003801557, 1738370122, 1986320549, 1838153875, 2251317482, 2675934578,
1376881844, 2072485279, 2742380347, 2074187683, 2072614712, 2207671420, 1754495611, 2313449101,
2639558273, 2305834060, 1165002076, 2578402890, 1520469146, 2344854861, 1347708818, 2273342633,
2006686849, 2056355733, 1400930666, 2221746901, 2067750591, 3650506859, 2172845951, 2089917269,
2811725174, 1482512228, 3464390535, 1172111520, 2999158160, 2454877826, 1002465691, 868397946,
2478082435, 1237631336, 1919118172, 2020179286, 1719097502, 1474469218, 2945221520, 1819121006,
2593161138, 1603172014, 2390788665, 2339792780, 2054171049, 2393336675, 3632817050, 2106089603,
2425588325, 2138995593, 2309326964, 2224520845, 2390995605, 3819739515, 2006478261, 1905107076,
2291437681, 2004651198, 2122036635, 2139273666, 2808628134, 2057006455, 4287985768, 2272513133,
3280887938, 2038211830, 2254671463, 2021750857, 2222489983, 2073276288, 1550742711, 2004976051,
2122434434, 1171807789, 1551534467, 3301754493, 2356044664, 1201372566, 2826875477, 2541307358,
1150976652, 1638248548, 1825022583, 2785002676, 2323882903, 2187172227, 1488226968, 2158526842,
2339148692, 2122619265, 1769500252, 2037676946, 2003458393, 2860361396, 2040641861, 2630240314,
1180411297, 2022052232, 2201646527, 2526067070, 887058089, 2188807038, 1330148197, 3263972054,
2641583462, 1949007815, 3289272676, 2477485937, 2271730049, 1954505846, 1639800454, 2906429010,
1747955485, 2176212605, 1319707781, 2876740250, 1985701276, 2574487426, 1635642458, 2206884296,
3076510604, 2913231529, 2206203774, 1955112824, 2189786235, 2055040379, 2373092220, 2239988605,
1618774413, 2559012216, 2021885819, 2105503878, 2108521329, 1717201300, 2273542528, 2071427718,
2239596933, 2089320573, 2611122847, 2589552786, 2441178518, 2205781384, 2207024006, 2306836103,
2226221976, 2474871936, 2407757944, 2189557630, 2709012529, 1854633070, 2323225962, 3917642384,
727801713, 1585422927, 3183182920, 2423870565, 2024703868, 2155701070, 1571202190, 2089592214,
3470095246, 1817141158, 1657177703, 2032102749, 2631330614, 1905630846, 2491263385, 2441326208,
2659139949, 2254276233, 1869545366, 1686597745, 2339809397, 3698300255, 2524618087, 2904255053,
2071683222, 2637085317, 10044178, 1098286929, 2218442887, 648360530, 2107790746, 3344149434,
1902147967, 2010796174, 938086050, 3181813675, 2275253861, 3110235298, 2339546558, 2024619955,
2028472993, 2039582343, 1984525176, 3082855873, 3197138307, 2072361349, 2575209727, 2240904582,
1504675166, 2676989571, 1318995867, 2879880575, 2409261661, 1891124129, 2977724555, 2308531866,
2315817629, 2408612719, 2271580529, 2656857494, 2371977918, 2124119697, 2628093555, 2525465772,
2274856322, 2323798918, 1232816756, 2373280145, 1756164272, 1871998824, 2306315383, 2629340024,
2755753126, 2223202177, 2221897070, 2608019191, 1765508470, 2051511951, 2788398238, 2816180095,
2323207110, 3078334873, 1466143417, 9079949, 996040402, 2009737411, 2021938053, 2509825414,
1737077898, 1668574336, 1233688491, 2154119750, 1886544300, 1920364726, 1970970510, 1988867978,
2791868097, 1518697831, 2689242520, 3780621151, 3668478904, 702454125, 2304159055, 2175428001,
12171294, 2751352532, 2101569632, 2122025586, 608926822, 3694410692, 3748500790, 2440395124,
1518198645, 2576592845, 1853640578, 2307750305, 1601858656, 2135237502, 1923932540, 4036444507,
2289806201, 2288556421, 2372822626, 1184197538, 1149806449, 1962894376, 1331862360, 2256305020,
2160354406, 2890323564, 1435665763, 3213244727, 2425180039, 1754623612, 2345287555, 2272555571,
2628293768, 2117639325, 1986841759, 2521334641, 2376755128, 1249793916, 2324792484, 1936742293,
2995302027, 2172949631, 1433756965, 1636140400, 3148706689, 3412224372, 2841088578, 2052737439,
2843710586, 3004985402, 2116993182, 2156034628, 2327532699, 1903061914, 2324012170, 1832637833,
1285602205, 2509471881, 2459369629, 1904704438, 1989314958, 2759172456, 1635015775, 2037074326,
2543880593, 3062778486, 2105763203, 2573560374, 1771411568, 1195541942, 2305408384, 1065068688,
1333625260, 3294995835, 2405463903, 1584358795, 2224320849, 6374572, 2308466520, 1047033175,
2136045392, 2203735903, 1587849063, 2156578868, 2375827593, 2710679669, 2288035717, 1668772229,
2238464108, 1282157177, 612912978, 2323174006, 2558333835, 979916202, 3350760263, 2842591022,
1616687762, 1837670013, 2223278718, 1486325383, 2106698605, 2089045695, 1200961299, 2577251801,
3734346868, 1850323066, 3211688060, 1999726739, 1871034287, 327698785, 2401005621, 3129507896,
2458363548, 2294913897, 1888791174, 7436930, 2239507835, 3556773989, 1280750197, 2745590423,
2092136732, 3232268944, 3746449554, 770404223, 1585271939, 1549483657, 2794766702, 3012309430,
1737008024, 2622926848, 2681036496, 2843119995, 1627346810, 2743114265, 1700676584, 1753789856,
3955383429, 679011248, 2990952448, 2862923113, 1941548709, 2226029602, 2956800901, 2079338463,
3293290317, 3103818603, 1923273578, 1384013420, 2153477943, 2024633460, 1032680384, 2572848767,
2175945318, 1421962613, 1856416151, 2022796439, 2273933734, 2713603438, 3067230976, 2555743988,
1651876334, 2709947723, 2809818937, 3234636429, 2506734395, 6328955, 2930928769, 1435990356,
2998733932, 1974322980, 2696179351, 2776491586, 591265879, 1332447808, 1618770243, 4289187933,
2630642471, 2326073587, 2386853427, 2874310332, 860946201, 2630895537, 3601366349, 1183465093,
1565707681, 3533391625, 2256475273, 1552521049, 1265861249, 3297507672, 2824041601, 2124107175,
949779492, 4283015498, 3195810954, 1808102063, 10260578, 2573174385, 3098044526, 2589172165,
1137659976, 1432525391, 1920607307, 3713908341, 2344325542, 1117350399, 3114285947, 3046466660,
2697178624, 1469400133, 1018346829, 3364572269, 2722871343, 2203681438, 3192858491, 2860033993,
1653503127, 2693529439, 1717103959, 2225365204, 1992329380, 1405073044, 3345361276, 1385347656,
1382711207, 2624298121, 2714598252, 1968927231, 1136148325, 1516188555, 1857148235, 2036465570,
1940158499, 2312373015, 2797311137, 2575350282, 3362178900, 1793946273, 1956336232, 3232378713,
4285234829, 1515874396, 2959175365, 2216918394, 1121693891, 1452380502, 3360519858, 2415961817,
3698093449, 2568575144, 3093522225, 1677699661, 918467746, 3060034130, 2122534493, 2135257691,
3795297377, 2963508121, 1758461804, 1600486064, 1753528370, 3451336513, 2604685378, 3151733148,
490446002, 1839163313, 3613383055, 1979745587, 1149519033, 1884776668, 2537928767, 2204202668,
1443445940, 1796319490, 2736031231, 2008496109, 1664912700, 274426251, 2165220168, 2188694921,
2241830756, 1801758679, 2539879561, 2571734528, 3345068202, 3610914264, 661651308, 3821455937,
2760091725, 2145534935, 1982628627, 2819985027, 207857496, 2759608752, 2714995517, 2127796658,
1611282339, 3292069893, 2521465364, 997564252, 2714004048, 2686954154, 1750620002, 2034597517,
2003386255, 4285436061, 1950824079, 1270978123, 196472356, 2824288891, 1351696300, 3379000680,
8283087, 1280626807, 2020952738, 3132857809, 2221558584, 3347994111, 1849845361, 2507653670,
1140865758, 1797424729, 3290014446, 2404955627, 1282258216, 3699809965, 2395048317, 3070282315,
2059898905, 2342407719, 2609274981, 1602063781, 1518699149, 3143115775, 3519283083, 2290848904,
2542358882, 2407498101, 3885203331, 2187696987, 714515832, 4228133751, 2561545728, 2338660537,
2591261821, 2088782959, 2127861183, 2192776039, 2662572907, 2602016201, 2317514784, 1904309220,
1566363738, 2640750125, 1744791320, 2073927293, 2410634592, 2539488111, 2113959865, 1718978178,
1650565981, 2907012201, 1178228430, 8385631, 1682878645, 2853608800, 2089159494, 2042536710,
2105498812, 1145929081, 1644865535, 1464895263, 1723698756, 2054769565, 2671916662, 1966304186,
2139002700, 1532849267, 1900001180, 2121230986, 2225107838, 4283738209, 2292084642, 1353020501,
1804017475, 4288326814, 2421699006, 3096099010, 2829615666, 2917744265, 1972411288, 1778359937,
2656350603, 1485337203, 2320926088, 1469283965, 2451484359, 2089380790, 1480425056, 1670804375,
2055956224, 2710536062, 1563980894, 2378269055, 2542555117, 3622879908, 2840052501, 2376884551,
2207307261, 716012600, 1617741055, 2302443368, 2223160951, 2370002534, 1905289042, 2387502592,
1579244906, 2771896778, 1686862969, 2208307675, 3604650034, 2577761926, 2709624953, 1782142207,
1954627394, 2238257019, 2139707275, 1723048704, 2536860283, 1886708924, 358896727, 2591582535,
816023710, 2488419508, 2508951966, 2707330870, 2238986110, 2288149176, 1768720896, 2405867153,
2071017852, 4287647363, 2238420369, 2339023522, 1585275966, 3061079918, 3147272046, 2798673664,
1820318554, 1781381344, 2961811035, 1453965715, 4016731931, 2257808551, 2039647062, 2746695572,
2309599430, 3111625301, 2355526144, 2610408856, 1229945511, 2216925695, 1519022679, 2632627578,
3382755695, 1385969740, 2096080592, 2085286875, 2423444735, 2137340290, 2441511082, 3293355161,
2080868661, 2807014397, 1377670588, 1602067406, 3361185970, 2087681182, 1822699180, 7678039,
2306563232, 4286883658, 2951644222, 1502283397, 2502917553, 3127086436, 2879752064, 2887672259,
2424078764, 2564583381, 3145613605, 2321961242, 1934932139, 1041721020, 3980293887, 2778295456,
1711001676, 427092058, 1703328603, 3364963464, 2892404285, 1442895523, 2978784811, 1775951155,
1320794686, 2664759127, 2239714694, 1748078745, 3172971224, 2544233727, 2306178759, 3382288242,
2082704806, 3365632418, 1027445803, 1082838362, 1702866265, 3378142868, 2415155968, 2174696594,
2625876406, 364850539, 1717793422, 2392337227, 1706252359, 2781923, 2071495041, 1301058896,
1655543448, 2456972349, 1833978707, 2478293849, 6724236, 2024397704, 2256110157, 2125359268,
2355065230, 2827412475, 2794417407, 2794268733, 1631230122, 3112473523, 1682851686, 11913348,
4170298970, 1996482948, 1665296241, 1720029840, 3629408804, 3295192692, 2092617610, 1481543611,
2095766947, 4632936, 1703721519, 2017297711, 1715890060, 3380377470, 2658956152, 4287721118,
2995801212, 1955830207, 2153889678, 2492101782, 1802668905, 3858515781, 2158968333, 1221027890,
1472443665, 2425482102, 1727047117, 2761529344, 1334016350, 2196263712, 3599383671, 2061045569,
2385018111, 1030828935, 3091822708, 2055376944, 2188266622, 2738721199, 2274719839, 2844358807,
2392489809, 4288768845, 1987485572, 3476172682, 3388964423, 2474209923, 1953399209, 2924099710,
2763940199, 1919899306, 2217318337, 2135312962, 1939919912, 2343287610, 1603311991, 13741232,
4287845516, 3033573206, 1836211584, 2426162088, 3516711062, 1204330067, 1147516826, 1587097172,
2329713931, 1130273523, 2718970812, 2534241536, 2053600824, 3165431399, 2138290339, 1248354540,
2162743146, 3829645408, 3181719672, 1430157818, 2577380864, 1016257645, 1597325192, 2912344501,
2454613621, 326238367, 2341502821, 3514077506, 4292571811, 2844490191, 1818968502, 1616894888,
3432523854, 2159964359, 96576865, 1452566834, 1751518720, 3599463368, 3684531569, 3455277973,
1971354493, 1148659286, 2351717321, 2039349174, 1517392953, 1938721892, 1837989481, 1735612292,
1467250856, 3519318318, 3332457593, 899109258, 2005041567, 2694094965, 2063555837, 1388072462,
1970099083, 2425063844, 2029227870, 1836150403, 1788191625, 2036465789, 2292611902, 1704884370,
2179438272, 1478269767, 1404474753, 2291119216, 2956097622, 478538239, 2591293510, 2008895238,
1872815007, 2994481024, 1671122913, 514348717, 2865722267, 3268064565, 2339982138, 2633979956,
2742496818, 1514962397, 2709546836, 2827590401, 1262698628, 2224535198, 1831237214, 2072406954,
1651354209, 1721063261, 1316618464, 2489073573, 595034021, 2046799449, 3528220021, 1826254820,
3450365833, 1882542135, 2085653129, 1144509186, 3199656829, 2789834314, 2389190804, 2400761658,
4288219442, 1042603771, 1035037192, 1041392947, 3164289839, 1046133844, 1043842840, 1049253840,
1038666594, 1045196835, 3188215987, 1031619627, 1043727733, 1036661432, 1041622745, 1048824264,
1027215517, 1044437848, 1042579783, 3184765682, 1038538413, 1046623258, 3161780724, 1041333690,
3133471355, 1047941070, 3185256064, 3166288194, 1035189116, 1034632125, 1032433335, 3175298323,
1016157480, 1028214081, 3183157347, 3176333289, 1036100462, 3140557907, 1026715857, 3169469313,
3140780796, 3173586778, 1037662361, 3188986036, 1039576831, 1035604195, 3144976527, 1040946940,
3147460742, 1031203383, 3177400140, 1026939978, 3180900631, 3164026658, 3179952814, 1040399131,
1038638804, 1024325640, 3171885748, 3174632920, 1029056305, 1030626655, 1037954418, 1023838274,
3154441571, 975676812, 1008935137, 1016051759, 3165650861, 3180035793, 1006108728, 3161897497,
3160511518, 3171917153, 1008931655, 1019814600, 1027394841, 3159197524, 1029224297, 3172138065,
1019901034, 998804741, 3159419213, 1024485164, 1017952167, 1033292974, 1023102610, 1031625448,
3162349529, 3189807112, 1032258975, 996297794, 3192633393, 3172214307, 1005434591, 3142289465,
3194658873, 3155884751, 3175317487, 1028443888, 1040680368, 1028102661, 1009508181, 1049361173,
3165825931, 3182975263, 3184573791, 3178033442, 1023036774, 1033860938, 3182882872, 1051482665,
3180928322, 3216852834, 1069272275, 3215652575, 1068081393, 3224132137, 1076648489, 1055061328,
1054288735, 1051767353, 1055610908, 1056235109, 1051364641, 1051988695, 1055917768, 1051640368,
1052716616, 1053584217, 1050503795, 1053217794, 1055124746, 1055481068, 1057849754, 1050736347,
1052631439, 1059168410, 1052699872, 1051648261, 1053599727, 1050728257, 1054429730, 1054853351,
1051224648, 1058913120, 1051715525, 1055926313, 1057521500, 1058137826, 1061106812, 1052258613,
1056772553, 1056274931, 1054951367, 1058243306, 1054113033, 1058428496, 1050662770, 1052985765,
1057450288, 1053636028, 1058040582, 1052837560, 1053268369, 1057973469, 1057709983, 1053742492,
1055400157, 1048639099, 1055581633, 1055583205, 1056668019, 1054602533, 1057288882, 1053916600,
1053254942, 1051689684, 1052825094, 1057840440, 1053405299, 1060887946, 1057854803, 1051358457,
1052326119, 1052071987, 1051411977, 1050359446, 1056069785, 1052857365, 1058765902, 1052870840,
1051167150, 1065353216, 1053149242, 1048327183, 1057028737, 1050414344, 1049655702, 1052345901,
1051917585, 1050662169, 1052720943, 1053410517, 1060671004, 1052717848, 1058143277, 1055671864,
1059147617, 1057690383, 1051027184, 1055805121, 1053202246, 1060001178, 1058611761, 1057931336,
1056542414, 1056528372, 1058820523, 1054097365, 1056104341, 1057812339, 1059682903, 1054673906,
1057804793, 1052857407, 1057913727, 1053763454, 1053354143, 1061551273, 1056275317, 1056290864,
1052376167, 1056612059, 1059516478, 1055004151, 1051314504, 1062125645, 1051562457, 1054867885,
1059712089, 1058499250, 1058644908, 1059517997, 1052621846, 1057995597, 1056730257, 1057096118,
1058712602, 1061231925, 1055228442, 1058262020, 1057093883, 1056638879, 1056603106, 1053564184,
1052400578, 1056714055, 1049950300, 1060693726, 1057772180, 1061522783, 1063238506, 1058120451,
1059110739, 1060393616, 1061234807, 1057869693, 1059789631, 1064658576, 1061967263, 1060844497,
1061052711, 1058771597, 1055671998, 1059544269, 1057948895, 1058230096, 1065353216, 1058033139,
1062183242, 1059375690, 1058814743, 1057741551, 1062971927, 1059964249, 1057398139,
};
uint32_t* get_knSceneSwitchWeightsArr_addr()
{
return (uint32_t *)(knSceneSwitchWeightsArr);
}
uint32_t get_knSceneSwitchWeightsArr_size()
{
return sizeof(knSceneSwitchWeightsArr) / sizeof(knSceneSwitchWeightsArr[0]);
}
void get_knSceneSwitchWeightsArr_version(char* ver, uint8_t len)
{
memcpy(ver, NET_VERSION, len);
}
#endif //#ifndef Goodix_DSP_EXPORTS

View File

@ -0,0 +1,21 @@
#ifndef _PPG_BREATH_RATE_Math_H
#define _PPG_BREATH_RATE_Math_H
#include "stdlib.h"
#include "stdint.h"
typedef struct
{
//加速度的信号先不考虑,先是静息的状态
uint8_t hr_val;//输入心率,可以是当前的也可以是平均的,反正都是通过心率预估,不准!
uint32_t first_point_time;//第一个点的时间是一个数字:(时*3600+分*60+秒)*100应该是整秒开始读取时间内部有用到,对应的是多少秒
}ppg_breath_rate_in_t;
typedef struct
{
uint8_t breath_rate_val;//输出的呼吸率
}ppg_breath_rate_os_t;
void PPG_BreathRateDetection(ppg_breath_rate_in_t* breath_char, ppg_breath_rate_os_t*breath_rate_res);
#endif

View File

@ -0,0 +1,44 @@
#ifndef __PLATFORM_IF_H__
#define __PLATFORM_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stdint.h"
#include "platform_if.h"
typedef unsigned char GBOOL;
typedef char GCHAR;
typedef unsigned char GUCHAR;
typedef signed char GS8;
typedef unsigned char GU8;
typedef signed short GS16;
typedef unsigned short GU16;
typedef signed int GS32;
typedef unsigned int GU32;
typedef signed long long GS64;
typedef unsigned long long GU64;
typedef float GF32;
typedef double GF64;
typedef long double GF128;
typedef double GD64; /**< double type */
#ifdef __cplusplus
}
#endif
#endif /* MODE_CONFIG_H */

View File

@ -0,0 +1,391 @@
#include "Ecg_GoodixForFrequence.h"
#include "Ecg_DetectionForGDH3220.h"
// #include "Vp_MallocAlgTypeLocation.h"
#include "breath_rate_math.h"
// #include <mem_manager.h>
// extern void Ecg_DetectInit(void);
extern void send_ecg_data(int data[512]);
extern uint8_t ecg_modeing;
int32_t ecg_data[8 * 512] = {0};
extern uint8_t RealTime_Data_ecg; // ble实时ecg数据,0波形数据1rawdata数据
ecg_move_index_t ecg_move = {
.move_5s = 0,
};
ecg_enter_t ecg_enter = {
.diga_mode = 1,
.func_times = 0,
.sampling_len = 512,
.ecg_leadoff = 0,
};
ecg_result_t ecg_result;
ecg_diag_result_t ecg_diag;
/*导棉脱落设置*/
void set_ecg_enter_ecg_leadoff(uint8_t value)
{
ecg_enter.ecg_leadoff = value;
}
// typedef struct tag_ecg_enter
// {
// uint8_t diga_mode; //1手动模式
// uint8_t func_times;
// uint8_t ecg_leadoff;//1182只有一个0 通过 1脱落
// uint16_t sampling_len; // app抽样显示仅支持256128512
// tag_ecg_afemaxim_parameter_t tag_ecg_afemaxim_parameter_s;
// }ecg_enter_t;
// 抽样下标
#if 1
const uint16_t ecg_index[256] = {0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 49, 50, 52, 53, 55, 56, 58, 59, 61, 63, 64, 66, 67, 69, 70, 72, 74, 75, 77, 78, 80, 81, 83, 84, 86, 88, 89, 91, 92, 94, 95, 97, 99, 100, 102, 103, 105, 106, 108, 109, 111, 113, 114, 116, 117, 119, 120, 122, 124, 125, 127, 128, 130, 131, 133, 134, 136, 138, 139, 141, 142, 144, 145, 147, 149, 150, 152, 153, 155, 156, 158, 159, 161, 163, 164, 166, 167, 169, 170, 172, 174, 175, 177, 178, 180, 181, 183, 184, 186, 188, 189, 191, 192, 194, 195, 197, 199, 200, 202, 203, 205, 206, 208, 209, 211, 213, 214, 216, 217, 219, 220, 222, 224, 225, 227, 228, 230, 231, 233, 234, 236, 238, 239, 241, 242, 244, 245, 247, 249, 250, 252, 253, 255, 256, 258, 259, 261, 263, 264, 266, 267, 269, 270, 272, 274, 275, 277, 278, 280, 281, 283, 284, 286, 288, 289, 291, 292, 294, 295, 297, 299, 300, 302, 303, 305, 306, 308, 309, 311, 313, 314, 316, 317, 319, 320, 322, 324, 325, 327, 328, 330, 331, 333, 334, 336, 338, 339, 341, 342, 344, 345, 347, 349, 350, 352, 353, 355, 356, 358, 359, 361, 363, 364, 366, 367, 369, 370, 372, 374, 375, 377, 378, 380, 381, 383, 384, 386, 388, 389, 391, 392, 394, 395, 397, 399};
#else
const uint8_t ecg_index[256] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249};
#endif
/*没用上*/
void ECG_init(void)
{
ecg_enter.diga_mode = 1;
ecg_enter.func_times = 0;
ecg_enter.sampling_len = 512;
ecg_enter.ecg_leadoff = 0;
Ecg_DetectInit();
// printk("ECG_initECG_initECG_initECG_initECG_init\r\n");
}
extern void *ui_mem_res_alloc(size_t size);
extern void ui_mem_res_free(void *ptr);
void *Vp_MallocAlgorithm(uint32_t malloc_size, uint8_t alg_type, uint16_t alg_location)
{
void *p = NULL;
// printk("ui_mem_res_alloc:%d\r\n",malloc_size);
if (malloc_size != 0)
{
// printk("****************\r\n");
p = (void *)ui_mem_res_alloc(malloc_size);
}
// 后续增加对等信息统计
return p;
}
void Vp_FreeAlgorithm(void *malloc_p, uint8_t alg_type, uint16_t alg_location)
{
// printk("ui_mem_res_free\r\n");
if (malloc_p != NULL)
{
ui_mem_res_free(malloc_p);
// printk("----------------------\r\n");
}
// 后续增加对等信息统计
}
extern void ecg_irs(void);
uint16_t datain_cnt = 0; // 输入计数 //每次调用都需要清0
uint16_t current_data_cnt = 0; // 取整数400
int32_t current_ecg_data[512] = {0};
int32_t ecg_sourcedata_fifo[1000] = {0};
int32_t ppg_sourcedata_fifo[200] = {0};
uint16_t ecg_sourcedata_index = 0;
uint16_t ppg_sourcedata_index = 0;
void blesend_ecgdata_event(uint8_t *data, uint16_t len);
/*****ecg中断调用****/
// 调用频率500ms
void sync_ecg_data(int32_t *data, uint16_t len)
{
// printk("sync_ecg_data len:%d \r\n",len);
// 卡512长度
if (len > 450 && len < 395)
{
// printk("sync_ecg_data lazy weight\r\n");
return;
}
else
{
if (len < 400) // 398
{
for (uint16_t i = len; i < 400; i++)
{
data[i] = data[i - 1];
// printk("---data[i]--%d-------\n",i);
}
}
}
for (uint16_t k = 0; k < 256; k++)
{
current_ecg_data[k + current_data_cnt] = data[ecg_index[k]];
}
#if 0 // 打开发送512原始数据
blesend_ecgdata_event((void *)&current_ecg_data[current_data_cnt],256*4);
#endif
current_data_cnt += 256;
if (current_data_cnt >= 512)
{ // 数据满了便进行数据存储并且偏移
current_data_cnt = 0;
// if(datain_cnt==0){ //第一次调用时初始化
// ecg_enter.func_times=0;
// ECG_init();
// }
if (datain_cnt < 6)
{ // 判断是否保存6s数据不足6s时持续累加
memcpy(&ecg_data[0] + (datain_cnt * 512), current_ecg_data, 512 * 4);
datain_cnt++;
//printk("#4-");
}
else
{
for (uint8_t i = 0; i < 6; i++)
{
if (i < 5)
{
for (uint16_t j = 0; j < 512; j++)
ecg_data[(i * 512) + j] = ecg_data[((i + 1) * 512) + j];
}
else
{
for (uint16_t j = 0; j < 512; j++)
ecg_data[(i * 512) + j] = current_ecg_data[j];
}
// memcpy(&ecg_data[i*512],&ecg_data[(i+1)*512],512*4);
}
// memcpy(&ecg_data[5*512],current_ecg_data,512*4);
//printk("#5-");
ecg_irs(); // 发送事件计算算法
// printk("----------------\r\n");
}
}
//printk("#1-");
// 清除fifo
// printk("ecg_sourcedata_index:%d \r\n",ecg_sourcedata_index);
// memset(ecg_sourcedata_fifo,0,sizeof(ecg_sourcedata_fifo));
ecg_sourcedata_index = 0;
}
void ecg_algodata_handle(void)
{
sync_ecg_data(ecg_sourcedata_fifo, ecg_sourcedata_index);
}
// // 心率相关
// uint8_t heart_rate; // 每秒HR
// uint8_t hr_per_min_result; // 每分钟HR均值对应日常数据心率1~5
// // HRV相关
// uint8_t hrv;// 每秒HRV
// // RR相关
// uint8_t rr;// 每秒rr
// uint8_t rr_per_6sec_result;// 每6秒RR
// uint8_t ary;// 心率不齐
// // 呼吸率相关
// uint8_t resp_per_second_result;// 每秒呼吸率
// uint8_t resp_per_min_result;// 每分钟呼吸率均值对应日常数据呼吸率1~5
// // 导联脱落标志位
// uint8_t lead_off_detec_res;
// // 诊断进度标志位
// uint8_t measurement_progress;// 说明该进度标志位非每秒计数该进度标志位最大值为30软件在识别到该值为30后即可诊断结束不再识别其后的值
// uint16_t QTC_sec;
// // Afe4900校准信息
// uint8_t adjust_flag;//校准的标志位0,3表示不需要对寄存器的参数进行修改1,2需要修改
// tag_ecg_afemaxim_parameter_t ecg_afemaxim_parameter_new;//寄存器的参数的值
// //test
// uint8_t RR_cnt;
// uint8_t ecg_ld_judge_flag; // 0:佩戴通过 1:佩戴不通过
// void send_Ecgtestdata(uint8_t process,uint8_t hr,uint8_t hrv,uint8_t rr,uint8_t rr6);
// void User_ecgdata_sync(uint8_t *buf, uint16_t size);
// uint8_t ecg_sync_flag=0;
extern void set_hr_rate(uint8_t value);
void ecg_algo_handle(void)
{
// 调用算法
// printk("----------------------\r\n");
#if 1
//printk("#a-");
Ecg_DetectEntry(&ecg_data[0], &ecg_move, ecg_enter);
// ecg_enter.func_times++;
// printk("-*******************\r\n");
// 获取结果
Ecg_GetResult(&ecg_result);
// send_Ecgtestdata(ecg_result.measurement_progress,
// ecg_result.heart_rate,ecg_result.hr_per_min_result,
// ecg_result.rr,ecg_result.rr_per_6sec_result);
// for(uint8_t i = 0;i<=50;i++)
// {
// printk(" ecg_filter_data:%d \r",ecg_filter_data[i]);
// }
if (RealTime_Data_ecg)
{
send_ecg_data((int *)current_ecg_data);
}
else
{
send_ecg_data((int *)ecg_filter_data);
}
set_hr_rate(ecg_result.heart_rate);
// memcpy((void *)&ecg_result,(void *)&ecg_appresult,sizeof(ecg_appresult));
// printk("progress:%d \r\n",ecg_result.measurement_progress);
// printk("heart_rate :%d hrv :%d \r\n",ecg_result.heart_rate,ecg_result.hr_per_min_result);
// printk("rr :%d rr_per_6sec_result :%d \r\n",ecg_result.rr,ecg_result.rr_per_6sec_result);
// printk("resp_per_second_result:%d resp_per_min_result:%d \r\n",ecg_result.resp_per_second_result,ecg_result.resp_per_min_result);
// printk("QTC: %d\r\n",ecg_result.QTC_sec);
#else
ecg_sync_flag++;
if ((ecg_sync_flag >= 5) && ((ecg_sync_flag != 5)))
{
ecg_sync_flag = 0xff;
User_ecgdata_sync((void *)ecg_data, 0x3000);
}
else
{
printk("3333333333333333333333333333333333333\r\n");
}
#endif
}
// typedef struct tag_ecg_result
// {
// // 心率相关
// uint8_t heart_rate; // 每秒HR
// uint8_t hr_per_min_result; // 每分钟HR均值对应日常数据心率1~5
// // HRV相关
// uint8_t hrv;// 每秒HRV
// // RR相关
// uint8_t rr;// 每秒rr
// uint8_t rr_per_6sec_result;// 每6秒RR
// uint8_t ary;// 心率不齐
// // 呼吸率相关
// uint8_t resp_per_second_result;// 每秒呼吸率
// uint8_t resp_per_min_result;// 每分钟呼吸率均值对应日常数据呼吸率1~5
// // 导联脱落标志位
// uint8_t lead_off_detec_res;
// // 诊断进度标志位
// uint8_t measurement_progress;// 说明该进度标志位非每秒计数该进度标志位最大值为30软件在识别到该值为30后即可诊断结束不再识别其后的值
// uint16_t QTC_sec;
// // Afe4900校准信息
// uint8_t adjust_flag;//校准的标志位0,3表示不需要对寄存器的参数进行修改1,2需要修改
// tag_ecg_afemaxim_parameter_t ecg_afemaxim_parameter_new;//寄存器的参数的值
// //test
// uint8_t RR_cnt;
// uint8_t ecg_ld_judge_flag; // 0:佩戴通过 1:佩戴不通过
// uint32_t reserve4;
// }ecg_result_t;
uint8_t get_ecg_result_heart_rate(void)
{
return ecg_result.heart_rate;
}
uint8_t get_ecg_result_hrv(void)
{
return ecg_result.hrv;
}
uint16_t get_ecg_result_qtc(void)
{
return ecg_result.QTC_sec;
}
/*************hook内调用************/
void sync_ecg_sourcedata(int32_t *data, uint16_t len)
{
/*source 1600/4=400*/
ecg_sourcedata_fifo[ecg_sourcedata_index] = data[0] - 0x800000;
ecg_sourcedata_index++;
if (ecg_sourcedata_index >= 1000)
ecg_sourcedata_index = 1000;
}
extern void send_ppg_data(int32_t data[100]);
void sync_ppg_sourcedata(int32_t *data, uint16_t len)
{
/*source 1600/4=400*/
ppg_sourcedata_fifo[ppg_sourcedata_index] = data[0];
ppg_sourcedata_index++;
if (ppg_sourcedata_index >= 100)
{
// send_ppg_data(ppg_sourcedata_fifo);
ppg_sourcedata_index = 0;
}
}
/************清理标志位************/
void Ecg_algo_start(void)
{
ecg_modeing = 1;
set_hr_rate(0);
memset((void *)&ecg_result, 0, sizeof(ecg_result));
// 清除fifo
memset(ecg_sourcedata_fifo, 0, sizeof(ecg_sourcedata_fifo));
ecg_sourcedata_index = 0;
datain_cnt = 0;
current_data_cnt = 0;
memset(current_ecg_data, 0, sizeof(current_ecg_data));
memset(ecg_data, 0, sizeof(ecg_data));
ECG_init();
}
void Ecg_algo_stop(void)
{
ecg_modeing = 0;
// 清除fifo
memset(ecg_sourcedata_fifo, 0, sizeof(ecg_sourcedata_fifo));
ecg_sourcedata_index = 0;
}
#if 0
/*ble 定时发送*/
struct hrtimer time_ms;
os_work Msblesend_callback_work;
void hrtimer_blesend_loop(struct k_work *work)
{
/*user demo*/
}
static void htimer_Mssend_fun(struct hrtimer *ttimer, void *expiry_fn_arg)
{
sys_wake_lock(PARTIAL_WAKE_LOCK);
os_work_init(&Msblesend_callback_work, hrtimer_blesend_loop);
os_work_submit(&Msblesend_callback_work);
sys_wake_unlock(PARTIAL_WAKE_LOCK);
}
static uint8_t apptimer_cnt=50;//unit:ms
void appSendTimerInit(uint8_t uchPeriodMs)
{
hrtimer_init(&time_ms, htimer_Mssend_fun, NULL);
apptimer_cnt=uchPeriodMs;
// hrtimer_start(&time_ms, 1000 * uchPeriodMs, 1000 * uchPeriodMs);
}
void appSendTimerStart(void)
{
hrtimer_start(&time_ms, 1000 * apptimer_cnt, 1000 * apptimer_cnt);
}
void appSendTimerStop(void)
{
hrtimer_stop(&time_ms);
}
#endif
extern int get_sync_time(void);
uint8_t breath_rate_algo_handle(uint8_t heartval)
{
ppg_breath_rate_in_t in_val;
ppg_breath_rate_os_t out_val;
in_val.hr_val = heartval;
in_val.first_point_time = get_sync_time(); // 时间戳
PPG_BreathRateDetection(&in_val, &out_val);
//printk("heart:%d\r\n", heartval);
//printk("breath val:%d\r\n", out_val.breath_rate_val);
return out_val.breath_rate_val;
}

View File

@ -0,0 +1,39 @@
#include <stdio.h>
//#include "gh3x2x_demo_inner.h"
#include "gh3x2x_demo_algo_config.h"
#include "gh3x2x_demo_accppg_sync.h"
#include "gh3x2x_demo_common.h"
GU8 GH3X2X_TimestampSyncGetFrameDataFlag(void)
{
return 1;
}
void GH3X2X_TimestampSyncSetPpgIntFlag(GU8 uchPpgIntFlag)
{
}
void GH3X2X_TimestampSyncAccInit(void)
{
}
void GH3X2X_TimestampSyncPpgInit(GU32 unFunctionID)
{
}
void GH3X2X_TimestampSyncSend2AlgoCall(GU8 uchFuncOffsetID)
{
}
void GH3X2X_TimestampSyncFillAccSyncBuffer(GU32 unTimeStamp,
GS16 usAccX,
GS16 usAccY,
GS16 usAccZ)
{
}
void GH3X2X_TimestampSyncFillPpgSyncBuffer(GU32 unTimeStamp,
const STGh3x2xFrameInfo * const pstFrameInfo)
{
}

View File

@ -0,0 +1,20 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_accppg_sync.h
*
* @brief gh3x2x algo call demo code version
*
* @version ref gh3x2x_demo_algo_call_version.h
*
*/
#ifndef _GH3X2X_DEMO_ACCPPG_SYNC_H_
#define _GH3X2X_DEMO_ACCPPG_SYNC_H_
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algo_config.h"
#endif

View File

@ -0,0 +1,367 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_memory.h"
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algo_config.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_call_version.h"
#include "goodix_algo.h"
#include "goodix_mem.h"
#include "goodix_type.h"
#include "goodix_hba.h"
#include "goodix_ecg.h"
#include "goodix_af.h"
#include "goodix_hsm.h"
#include "goodix_resp.h"
#include "goodix_hrv.h"
#include "goodix_spo2.h"
#include "goodix_nadt.h"
#include "goodix_algo_bt.h"
#if (__GOODIX_ALGO_CALL_MODE__)
extern const STGh3x2xInitConfig g_stGoodixAlgoCfgListArr[__GOODIX_ALGO_CFG_LIST_MAX_NUM__];
STGh3x2xFrameInfo ** g_pstGh3x2xAlgoFrameInfo = GH3X2X_PTR_NULL;
static GU32 g_unAlgoFuncStartedBitmap = 0;
static GU8 g_uchAlgInitFlag[GH3X2X_FUNC_OFFSET_MAX] = {0};
static const pfnAlgorithmCallFunc g_pfnAlgorithmCallFunc[GH3X2X_FUNC_OFFSET_MAX][GH3X2X_ALGO_FUNCTION_NUM_MAX] = {
//adt
#if __USE_GOODIX_ADT_ALGORITHM__
{ GH3x2xAdtAlgoInit, GH3x2xAdtAlgoExe, GH3x2xAdtAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//hr
#if __USE_GOODIX_HR_ALGORITHM__
{ GH3x2xHrAlgoInit, GH3x2xHrAlgoExe, GH3x2xHrAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//hrv
#if __USE_GOODIX_HRV_ALGORITHM__
{ GH3x2xHrvAlgoInit, GH3x2xHrvAlgoExe, GH3x2xHrvAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//hsm
#if __USE_GOODIX_HSM_ALGORITHM__
{ GH3x2xHsmAlgoInit, GH3x2xHsmAlgoExe, GH3x2xHsmAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//fpbp
//pwa
#if __USE_GOODIX_BP_ALGORITHM__
{ GH3x2xBpAlgoInit, GH3x2xBpAlgoExe, GH3x2xBpAlgoDeinit },
{ GH3x2xBpAlgoInit, GH3x2xBpAlgoExe, GH3x2xBpAlgoDeinit },
#else
{ 0, 0, 0 },
{ 0, 0, 0 },
#endif
//spo2
#if __USE_GOODIX_SPO2_ALGORITHM__
{ GH3x2xSpo2AlgoInit, GH3x2xSpo2AlgoExe, GH3x2xSpo2AlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//ecg
#if __USE_GOODIX_ECG_ALGORITHM__
{ GH3x2xEcgAlgoInit, GH3x2xEcgAlgoExe, GH3x2xEcgAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//pwtt
{ 0, 0, 0 },
//soft adt green
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
{ GH3x2xSoftAdtAlgoInit, GH3x2xSoftAdtAlgoExe, GH3x2xSoftAdtAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//bt
#if __USE_GOODIX_BT_ALGORITHM__
{ GH3x2xBtAlgoInit, GH3x2xBtAlgoExe, GH3x2xBtAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//resp
#if __USE_GOODIX_RESP_ALGORITHM__
{ GH3x2xRespAlgoInit, GH3x2xRespAlgoExe, GH3x2xRespAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//af
#if __USE_GOODIX_AF_ALGORITHM__ && __USE_GOODIX_HRV_ALGORITHM__
{ GH3x2xAfAlgoInit, GH3x2xAfAlgoExe, GH3x2xAfAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
//test
{ 0, 0, 0 },
{ 0, 0, 0 },
//soft adt ir
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
{ GH3x2xSoftAdtAlgoInit, GH3x2xSoftAdtAlgoExe, GH3x2xSoftAdtAlgoDeinit },
#else
{ 0, 0, 0 },
#endif
};
GCHAR* GH3X2X_GetAlgoCallDemoVersion(void)
{
return GOODIX_ALGO_CALL_VERSION_STRING;
}
void GH3X2X_RegisterFuncInfoStruct(const STGh3x2xFrameInfo * const pstGh3x2xFrameInfo[])
{
g_pstGh3x2xAlgoFrameInfo = (STGh3x2xFrameInfo **)pstGh3x2xFrameInfo;
}
void GH3X2X_AlgoCallConfigInit(const STGh3x2xFrameInfo * const pstGh3x2xFrameInfo[], GU8 uchAlgoCfgIndex)
{
if (pstGh3x2xFrameInfo != GH3X2X_PTR_NULL)
{
g_pstGh3x2xAlgoFrameInfo = (STGh3x2xFrameInfo **)pstGh3x2xFrameInfo;
}
GH3X2X_AlgoMemConfig(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL);
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem size = %d\r\n",(int)GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL);
if(uchAlgoCfgIndex < __GOODIX_ALGO_CFG_LIST_MAX_NUM__)
{
GH3X2X_LoadGoodixAlgoRegConfigArr(&g_stGoodixAlgoCfgListArr[uchAlgoCfgIndex]);
}
}
void GH3X2X_AlgoVersion(GU8 uchFunctionID, GCHAR version[120])
{
if (version == 0)
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:version buffer is NULL!!!\r\n", __FUNCTION__);
return;
}
GCHAR chNoVersion[10] = "no_ver";
switch (uchFunctionID)
{
#if __USE_GOODIX_ADT_ALGORITHM__
case GH3X2X_FUNC_OFFSET_ADT:
GH3X2X_Memcpy(version, GH3x2xAdtVersion(), strlen((const GCHAR *)GH3x2xAdtVersion()) + 1);
break;
#endif
#if __USE_GOODIX_HR_ALGORITHM__
case GH3X2X_FUNC_OFFSET_HR:
goodix_hba_version((uint8_t*)version);
break;
#endif
#if __USE_GOODIX_HRV_ALGORITHM__
case GH3X2X_FUNC_OFFSET_HRV:
GH3X2X_Memcpy(version, goodix_hrv_version(), strlen((const GCHAR *)goodix_hrv_version()) + 1);
break;
#endif
#if __USE_GOODIX_SPO2_ALGORITHM__
case GH3X2X_FUNC_OFFSET_SPO2:
goodix_spo2_version((uint8_t*)version);
break;
#endif
#if __USE_GOODIX_ECG_ALGORITHM__
case GH3X2X_FUNC_OFFSET_ECG:
goodix_ecg_version((uint8_t*)version);
break;
#endif
#if __USE_GOODIX_HSM_ALGORITHM__
case GH3X2X_FUNC_OFFSET_HSM:
GH3X2X_Memcpy(version, HSMAlgoVersion(), strlen((const GCHAR *)HSMAlgoVersion()) + 1);
break;
#endif
#if __USE_GOODIX_AF_ALGORITHM__
case GH3X2X_FUNC_OFFSET_AF:
GH3X2X_Memcpy(version, AFVersion(), strlen((const GCHAR *)AFVersion()) + 1);
break;
#endif
#if __USE_GOODIX_RESP_ALGORITHM__
case GH3X2X_FUNC_OFFSET_RESP:
GH3X2X_Memcpy(version, RespAlgoVersion(), strlen((const GCHAR *)RespAlgoVersion()) + 1);
break;
#endif
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
case GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN:
case GH3X2X_FUNC_OFFSET_SOFT_ADT_IR:
GetNadtVersion((uint8_t *)version);
break;
#endif
#if __USE_GOODIX_BP_ALGORITHM__
case GH3X2X_FUNC_OFFSET_PWA:
case GH3X2X_FUNC_OFFSET_FPBP:
//GH3X2X_Memcpy(version, GoodixBpAlgoVersion(), strlen((const GCHAR *)GoodixBpAlgoVersion()) + 1);
break;
#endif
#if __USE_GOODIX_BT_ALGORITHM__
case GH3X2X_FUNC_OFFSET_BT:
#if!__USE_GOODIX_DRV_NTC_Convert
GH3X2X_Memcpy(version, GoodixBtAlgoVersion(), strlen((const GCHAR *)GoodixBtAlgoVersion()) + 1);
#endif
break;
#endif
default:
GH3X2X_Memcpy(version, (GCHAR *)chNoVersion,\
strlen((const GCHAR *)chNoVersion) + 1);
break;
}
//GH3X2X_INFO_ALGO_LOG("version = %s\n", version);
}
GS8 GH3X2X_AlgoInit(GU32 unFunctionID)
{
GU8 chRet = GH3X2X_RET_OK;
if(GH3X2X_PTR_NULL == g_pstGh3x2xAlgoFrameInfo)
{
GH3X2X_INFO_ALGO_LOG("[%s]: Warning!!! g_pstGh3x2xAlgoFrameInfo is not init!\r\n", __FUNCTION__);
return GH3X2X_RET_OK;
}
/* set started bit */
g_unAlgoFuncStartedBitmap |= unFunctionID;
/* init mem pool */
if (GH3X2X_GetAlgoMemStatus() != ALGO_MEM_INIT_OK)
{
return -1;
}
for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)
{
if (((1<<uchFunCnt) & unFunctionID) == (1<<uchFunCnt))
{
/* int algo */
const STGh3x2xFrameInfo * const pstFrameInfo = g_pstGh3x2xAlgoFrameInfo[uchFunCnt];
if (1 == g_uchAlgInitFlag[uchFunCnt])
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) already init!\r\n", __FUNCTION__, (int)uchFunCnt);
}
else
{
if (g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_INIT_FUNCTION] != GH3X2X_PTR_NULL)
{
chRet = g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_INIT_FUNCTION](pstFrameInfo);
if (chRet != GH3X2X_RET_OK)
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) init fail! errcode = %d\r\n", __FUNCTION__, (int)uchFunCnt, (int)chRet);
}
else
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) init success!\r\n", __FUNCTION__, (int)uchFunCnt);
g_uchAlgInitFlag[uchFunCnt] = 1;
}
}
else
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) init func null!\r\n", __FUNCTION__, (int)uchFunCnt);
}
Gh3x2xOutputValueStrategyInit(unFunctionID);
}
GH3X2X_RET_ERROR_CHECK(chRet);
}
}
return chRet;
}
GS8 GH3X2X_AlgoDeinit(GU32 unFunctionID)
{
GS32 chRet = GH3X2X_RET_OK;
if(GH3X2X_PTR_NULL == g_pstGh3x2xAlgoFrameInfo)
{
GH3X2X_INFO_ALGO_LOG("[%s]: Warning!!! g_pstGh3x2xAlgoFrameInfo is not init!\r\n", __FUNCTION__);
return GH3X2X_RET_OK;
}
/* clear started bit */
g_unAlgoFuncStartedBitmap &= (~unFunctionID);
/* deint algo */
for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)
{
if (((1<<uchFunCnt) & unFunctionID) == (1<<uchFunCnt))
{
/* deint algo */
const STGh3x2xFrameInfo * const pstFrameInfo = g_pstGh3x2xAlgoFrameInfo[uchFunCnt];
if (0 == g_uchAlgInitFlag[uchFunCnt])
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) didn't init!\r\n", __FUNCTION__, (int)uchFunCnt);
}
else
{
if (g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_DEINIT_FUNCTION] != GH3X2X_PTR_NULL)
{
chRet = g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_DEINIT_FUNCTION](pstFrameInfo);
if (chRet != GH3X2X_RET_OK)
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) deinit fail! errcode = %d\r\n", __FUNCTION__, (int)uchFunCnt, (int)chRet);
}
else
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) deinit success!\r\n", __FUNCTION__, (int)uchFunCnt);
g_uchAlgInitFlag[uchFunCnt] = 0;
}
}
else
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) deinit func null!\r\n", __FUNCTION__, (int)uchFunCnt);
}
}
GH3X2X_RET_ERROR_CHECK(chRet);
}
}
return chRet;
}
GS8 GH3X2X_AlgoCalculate(GU32 unFunctionID)
{
if (g_unAlgoFuncStartedBitmap == GH3X2X_NO_FUNCTION)
{
return GH3X2X_RET_OK;
}
GS32 chRet = GH3X2X_RET_GENERIC_ERROR;
for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)
{
if (((1<<uchFunCnt) & unFunctionID) == (1<<uchFunCnt))
{
/* calc algo */
if (GH3X2X_CHECK_BIT_SET(g_unAlgoFuncStartedBitmap, unFunctionID))
{
const STGh3x2xFrameInfo * const pstFrameInfo = g_pstGh3x2xAlgoFrameInfo[uchFunCnt];
if(GH3x2xSleepFlagGet())
{
pstFrameInfo->punFrameFlag[2] |= ((GU32)1)<<3;
}
if (0 == g_uchAlgInitFlag[uchFunCnt])
{
//GH3X2X_DEBUG_ALGO_LOG("Function(funcition id = %d) didn't init!\r\n",(int)uchFunCnt);
}
else
{
if (g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_CALCULATE_FUNCTION] != GH3X2X_PTR_NULL)
{
chRet = g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_CALCULATE_FUNCTION](pstFrameInfo);
if( *(pstFrameInfo->punFrameCnt) == 0 && pstFrameInfo->pstAlgoResult->uchUpdateFlag == 0 )
{
GH3X2X_Memset(pstFrameInfo->pstAlgoResult,0,sizeof(STGh3x2xAlgoResult));
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->usResultBit = 0xFF;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
}
}
}
}
}
else
{
chRet = GH3X2X_RET_OK;
}
}
return chRet;
}
#endif

View File

@ -0,0 +1,76 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_algo_call.h
*
* @brief gh3x2x algo call
*
* @version ref gh3x2x_demo_algo_call.h
*
*/
#ifndef _GH3X2X_DEMO_ALGO_CALL_H_
#define _GH3X2X_DEMO_ALGO_CALL_H_
#include "gh_drv.h"
extern GCHAR* GH3X2X_GetAlgoCallDemoVersion(void);
extern void GH3X2X_AlgoVersion(GU8 uchFunctionID, GCHAR version[120]);
extern GS8 GH3X2X_AlgoInit(GU32 unFunctionID);
extern GS8 GH3X2X_AlgoDeinit(GU32 unFunctionID);
extern GS8 GH3X2X_AlgoCalculate(GU32 unFunctionID);
extern void GH3X2X_AlgoCallConfigInit(const STGh3x2xFrameInfo * const pstGh3x2xFrameInfo[], GU8 uchAlgoCfgIndex);
extern void GH3X2X_InitAlgoConfigParameters(void);
extern void GH3X2X_AlgoSensorEnable(GU8 uchAlgoGsensorEnable,GU8 uchAlgoCapEnable,GU8 uchAlgoTempEnable);
extern void GH3X2X_SoftAdtParaInit(void);
extern void GH3X2X_WriteAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);
/**
* @fn GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nOutputTime)
*
* @brief Hb algorithm output time config
*
* @attention None
*
* @param[in] nOutputTime valid 7~GS32_MAX
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_ALGO_NO_SUPPORTED return algorithm no supported error
*/
extern GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nLatestOutputTime, GS32 nEarliestOutputTime);
/**
* @fn GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario)
*
* @brief Hb algorithm scenario config
*
* @attention None
*
* @param[in] uchScenario @ref EMHbaScenesConfigType
* others: fixed 0(default) and return GH3X2X_RET_PARAMETER_ERROR
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_PARAMETER_ERROR return paramters error
* @retval #GH3X2X_RET_ALGO_NO_SUPPORTED return algorithm no supported error
*/
extern GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario);
extern GS8 GH3X2X_BTAlgorithmRTConfig(GU16 *nRTtable);
extern GU8 GH3X2X_TimestampSyncGetFrameDataFlag(void);
extern void GH3X2X_TimestampSyncAccInit(void);
extern void GH3X2X_TimestampSyncPpgInit(GU32 unFunctionID);
extern void GH3X2X_TimestampSyncSetPpgIntFlag(GU8 uchPpgIntFlag);
extern void GH3X2X_TimestampSyncFillAccSyncBuffer(GU32 unTimeStamp,
GS16 usAccX,
GS16 usAccY,
GS16 usAccZ);
extern void GH3X2X_TimestampSyncFillPpgSyncBuffer(GU32 unTimeStamp,
const STGh3x2xFrameInfo * const pstFrameInfo);
#endif /* _GH3X2X_DEMO_ALGO_CALL_H_ */
/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/

View File

@ -0,0 +1,154 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#if (__USE_GOODIX_ADT_ALGORITHM__)
#define __HARD_ADT_WAER_ON_THRD__ 9000000
#define __HARD_ADT_WAER_OFF_THRD__ 8800000
#define __HARD_ADT_WAER_ON_DIFF_THRD__ -8000000
#define __HARD_ADT_WAER_BIG_DIFF__ 30000
#define GH3X2X_MOVINF_AVA_WINDOW_SIZE 6
static EMWearDetectType g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;
static GU32 g_punGh3x2xMovingAvaFilterBuf[GH3X2X_MOVINF_AVA_WINDOW_SIZE];
static GU8 g_uchGh3x2xMovingAvaFilterPointCnt;
void Gh3x2xMovingAvaFilterInit(void)
{
g_uchGh3x2xMovingAvaFilterPointCnt = 0;
}
GU8 Gh3x2xMovingAvaFilter(GU32 *Rawdata, GU8 uchBypass)
{
GU32 unSum = 0;
if(uchBypass)
{
return 1;
}
else
{
if(g_uchGh3x2xMovingAvaFilterPointCnt >= GH3X2X_MOVINF_AVA_WINDOW_SIZE)
{
for(GU8 uchCnt = 1; uchCnt < GH3X2X_MOVINF_AVA_WINDOW_SIZE; uchCnt ++)
{
g_punGh3x2xMovingAvaFilterBuf[uchCnt - 1] = g_punGh3x2xMovingAvaFilterBuf[uchCnt];
}
g_uchGh3x2xMovingAvaFilterPointCnt = GH3X2X_MOVINF_AVA_WINDOW_SIZE - 1;
}
g_punGh3x2xMovingAvaFilterBuf[g_uchGh3x2xMovingAvaFilterPointCnt] = Rawdata[0];
g_uchGh3x2xMovingAvaFilterPointCnt ++;
if(g_uchGh3x2xMovingAvaFilterPointCnt > 1)
{
for(GU8 uchCnt = 0; uchCnt < g_uchGh3x2xMovingAvaFilterPointCnt - 1; uchCnt ++)
{
unSum += g_punGh3x2xMovingAvaFilterBuf[uchCnt];
}
Rawdata[0] = unSum/(g_uchGh3x2xMovingAvaFilterPointCnt - 1);
}
return 1;
}
}
#define ADT_CHECK_ALGO_VERSION "GX_HARDADT_SOFTCHECK_v0.1"
GU8* GH3x2xAdtVersion (void)
{
return (GU8*)ADT_CHECK_ALGO_VERSION;
}
GS8 GH3x2xAdtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
Gh3x2xMovingAvaFilterInit();
g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;
return GH3X2X_RET_OK;
}
GS8 GH3x2xAdtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
Gh3x2xMovingAvaFilterInit();
g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;
return GH3X2X_RET_OK;
}
GS8 GH3x2xAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GU32 unCurrentFrameRawdata = 0;
GS32 snDiffRawdata = 0;
GU32 unRawDataBeforeFilter = 0;
unCurrentFrameRawdata = pstFrameInfo->punFrameRawdata[0];
unRawDataBeforeFilter = pstFrameInfo->punFrameRawdata[0];
GH3X2X_DEBUG_ALGO_LOG("[GH3x2xAdtAlgoExe]:punFrameRawdata = %d\r\n", unCurrentFrameRawdata);
Gh3x2xMovingAvaFilter(&unCurrentFrameRawdata, 0);
GH3X2X_DEBUG_ALGO_LOG("[GH3x2xAdtAlgoExe]:punFrameRawdata after filter = %d\r\n", unCurrentFrameRawdata);
GH3X2X_DEBUG_ALGO_LOG("[GH3x2xAdtAlgoExe]:g_emAlgoWearStatus = %d, start check...\r\n",g_emAlgoWearStatus);
snDiffRawdata = (GS32)unRawDataBeforeFilter - (GS32)unCurrentFrameRawdata;
pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_DEFULT;
if(WEAR_DETECT_WEAR_ON == g_emAlgoWearStatus)
{
#if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__) //penetration model
if(unRawDataBeforeFilter < __HARD_ADT_WAER_ON_THRD__)
#else //reflex model
if((unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)&&((snDiffRawdata > (GS32)__HARD_ADT_WAER_ON_DIFF_THRD__)))
#endif
{
g_emAlgoWearStatus = WEAR_DETECT_WEAR_OFF;
GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:wear on event, Rawdata = %d, unRawdataDiff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_WAER_ON;
}
else
{
#if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__) //penetration model
#else //reflex model
if(unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)
{
GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:wear on condition is not match ! r = %d, r_diff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);
}
#endif
}
#if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__) //penetration model
#else //reflex model
if(snDiffRawdata > __HARD_ADT_WAER_BIG_DIFF__)
{
//pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
//pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_DIFF_BIG;
GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:ppg 5Hz diff big event, Rawdata = %d, unRawdataDiff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);
}
#endif
}
else if(WEAR_DETECT_WEAR_OFF == g_emAlgoWearStatus)
{
#if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__) //penetration model
if(unRawDataBeforeFilter > __HARD_ADT_WAER_OFF_THRD__)
#else //reflex model
if(unRawDataBeforeFilter < __HARD_ADT_WAER_OFF_THRD__)
#endif
{
g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;
GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:wear off event, Rawdata = %d, unRawdataDiff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_WAER_OFF;
}
}
pstFrameInfo->pstAlgoResult->usResultBit = 0x7;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
pstFrameInfo->pstAlgoResult->snResult[1] = snDiffRawdata;
pstFrameInfo->pstAlgoResult->snResult[2] = pstFrameInfo->punFrameCnt[0];
GH3X2X_AdtAlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);
return GH3X2X_RET_OK;
}
#endif

View File

@ -0,0 +1,124 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_hba.h"
#include "goodix_hrv.h"
#include "goodix_af.h"
#if (__USE_GOODIX_HRV_ALGORITHM__ && __USE_GOODIX_AF_ALGORITHM__)
extern GU32 g_unHrvLastHrResult;
extern goodix_hrv_ret goodix_hrv_init_func(GU32 fs);
extern goodix_hrv_ret goodix_hrv_deinit_func(void);
GS8 GH3x2xAfAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
for (GU8 uchChMapCnt = 0; uchChMapCnt < g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_AF]->pstFunctionInfo->uchChnlNum; ++uchChMapCnt)
{
g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_RESP]->puchFrameLastGain[uchChMapCnt] = GH3X2X_GAIN_VALUE_INVALID;
}
GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,\r\n", __FUNCTION__, g_nAfParamsArr[0]);
if ((AFInit((GS32)g_nAfParamsArr[0]) == GX_ALGO_HBA_SUCCESS) &&\
(goodix_hrv_init_func(pstFrameInfo ->pstFunctionInfo ->usSampleRate) == GX_ALGO_HBA_SUCCESS))
{
pstFrameInfo->pstAlgoResult->usResultBit = 0xFF;
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("af deinit error!\r\n");
}
g_unHrvLastHrResult = 0;
return chRet;
}
GS8 GH3x2xAfAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
if ((goodix_hrv_deinit_func() == GX_ALGO_HBA_SUCCESS) && (AFDeInit() == GX_ALGO_HBA_SUCCESS))
{
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("af deinit error!\r\n");
}
return chRet;
}
GS8 GH3x2xAfAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)
{
if(0 == pstFrameInfo )
{
return GH3X2X_RET_GENERIC_ERROR;
}
GU32 unResult[3] = {0};
GS32 nOutputData[6] = {0};
GS32 nAfInputData[6] = {0};
ST_HRV_INPUT_INFO siRawdataInput;
memset((GU8*)&siRawdataInput, 0, sizeof(ST_HRV_INPUT_INFO));
GU8 uchGainValue = 0;
for (int nRawdatacnt = 0 ; nRawdatacnt< HRV_CHNL_MAX_NUM ; nRawdatacnt ++)
{
siRawdataInput.ppg_green[nRawdatacnt] = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(pstFrameInfo->punFrameRawdata[nRawdatacnt]);
siRawdataInput.ppg_green[nRawdatacnt] = GH3X2X_GET_RAWDATA_FOR_ALGO(siRawdataInput.ppg_green[nRawdatacnt]);
uchGainValue = GH3X2X_GET_LOW_4BITS(pstFrameInfo->punFrameAgcInfo[nRawdatacnt]);
if ((pstFrameInfo->puchFrameLastGain[nRawdatacnt] != uchGainValue) && \
(pstFrameInfo->puchFrameLastGain[nRawdatacnt] != GH3X2X_GAIN_VALUE_INVALID))
{
siRawdataInput.green_gain_adj_flag[nRawdatacnt] = 1;
pstFrameInfo->puchFrameLastGain[nRawdatacnt] = uchGainValue;
}
siRawdataInput.green_cur_adj_flag[nRawdatacnt] = ((pstFrameInfo->punFrameFlag[0]) & 0x01);
}
siRawdataInput.acc_x = pstFrameInfo->pusFrameGsensordata[0];
siRawdataInput.acc_y = pstFrameInfo->pusFrameGsensordata[1];
siRawdataInput.acc_z = pstFrameInfo->pusFrameGsensordata[2];
siRawdataInput.frame_id = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));
if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)
{
g_unHrvLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];
}
siRawdataInput.hr = g_unHrvLastHrResult;
GU8 uchHrvUpdateFlag = HRVCalculateAlgo(&siRawdataInput, nOutputData);
if (uchHrvUpdateFlag && (nOutputData[5] != 0))
{
for (int i = 0 ; i < 6 ; i ++)
{
nAfInputData[i] = nOutputData[i];
}
pstFrameInfo->pstAlgoResult->uchUpdateFlag = AF_Detection_Module(nAfInputData, unResult);
if(pstFrameInfo->pstAlgoResult->uchUpdateFlag == 1)
{
pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)unResult[0];
pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)unResult[1];
pstFrameInfo->pstAlgoResult->snResult[2] = (GS32)unResult[2];
pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)nOutputData[0];
pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)nOutputData[1];
pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)nOutputData[2];
pstFrameInfo->pstAlgoResult->snResult[6] = (GS32)nOutputData[3];
pstFrameInfo->pstAlgoResult->snResult[7] = (GS32)nOutputData[4];
pstFrameInfo->pstAlgoResult->usResultBit = 0xFF;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
GH3X2X_DEBUG_ALGO_LOG("[%s]af = %d,UpdateFlag = %d\r\n",__FUNCTION__,(int)pstFrameInfo->pstAlgoResult->snResult[0],(int)pstFrameInfo->pstAlgoResult->uchUpdateFlag);
//GH3X2X_HrAlgorithmResultReport(pstFrameInfo->pstAlgoResult,stRawdata.frameid);
}
}
return GH3X2X_RET_OK;
}
#endif

View File

@ -0,0 +1,293 @@
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_call.h"
#include "goodix_mem.h"
#include "goodix_algo.h"
#include "goodix_algo_bt.h"
#if (__USE_GOODIX_BT_ALGORITHM__)
#define NTCSecondResult 0
/*****体温全局变量*****/
//NTC R-T table
#define NTC_TYPE CB62K552D
#if (CB62K928D==NTC_TYPE)
GU16 RT_Table[] = {25992,24742,23559,22437,21375,20367,19413,18507,17648,16833,16060,15325,14628,13965,13336,12738,12169,11629,11115,10625,10160,9717,9295,8894,8512,8147,7800,7469,7154,6853,6566,6293,6032,5783,5545,5318,5101,4894,4696,4507};
#elif(CB62K552D==NTC_TYPE)
GU16 RT_Table[] = {25837,24594,23418,22303,21247,20246,19297,18397,17543,16733,15964,15234,14540,13882,13256,12662,12097,11559,11048,10562,10099,9659,9240,8841,8461,8099,7754,7425,7111,6812,6527,6255,5996,5748,5512,5286,5071,4865,4668,4480};
#elif(DT104D3950==NTC_TYPE)
GU16 RT_Table[] = {26630,25340,24130,22980,21890,20850,19880,18950,18070,17240,16450,15700,14990,14320,13680,13070,12490,11940,11420,10920,10450,10000,9572,9165,8777,8408,8056,7720,7401,7096,6805,6528,6263,6011,5769,5539,5319,5109,4908,4717};
#endif
GU16 unSensorNtcRT_Len = sizeof(RT_Table)/sizeof(RT_Table[0]);
GU16 unSensorNtcRef = 3000; // NTC ref resistance (unit : 10ohm)
GS16 unTempRangeLower = 4*100;
GS16 unTempRangeUpper = 43*100;
GU8 unNTCChnalRes = 156;
GU32 g_unBtLastHrResult = 0;
GU16 uFs =0;
#if !__USE_GOODIX_DRV_NTC_Convert
STGoodixAlgorithmBtControlConfigParametersBuffer gstBtCFG;
STGoodixAlgorithmBtInputRef gstBtInputRef;
STGoodixAlgorithmBtCalculateOutputResult gstBtAlgoOUT;
//STGoodixAlgorithmBtFinalOutputResult gstBtAlgoFinal;
STGoodixAlgorithmInfo gstBtAlgoInfo;
/**
* @brief memory malloc function
* @param size
* @return pointer of memory
*/
void* GoodixSensorAlgoMalloc(GS32 size)
{
return goodix_mem_malloc(size);
}
/**
* @brief memory free function
* @param addr
*/
void GoodixSensorAlgoFree(void* addr)
{
goodix_mem_free(addr);
}
/**
* @brief algorithm log function
* @param addr
*/
void GoodixSensorAlgoLog(GCHAR* pLogStr)
{
//GH3X2X_DEBUG_ALGO_LOG("[%s]:%s\n", __FUNCTION__, pLogStr);
}
#else
STGH3x2xDrvBtOutputResult gstDrvBtOutRes;
GU16 GetRTIndex(GS32 R, GU16* pR, GU16 len)
{
GU16 i =0;
while(R <= pR[i]*10)
{
i++;
if(len == i)
{
i = 0xFFFF;
break;
}
}
return i;
}
/**
* @fn GS16 GH3x2xBtRTConvert(GS32* pnRawdata,STGH3x2xDrvBtOutputResult* pstDrvBtOutRes)
*
* @brief calc byte check rawdata
*
* @attention
*
* @param[in] punRawdata one rawdata addr IDEL REF NTC0 NTC1
* @param[out] None
*
* @return target rawdata
*/
static GS16 GH3x2xBtRTConvert(GS32* pnRawdata,STGH3x2xDrvBtOutputResult* pstDrvBtOutRes)
{
GU8 uchIdx = 0;
GU16 uRTIdx =0;
GS32 nRestemp0, nRestemp1;
GS16 nRawTemp =0;
GU8 chRet=0;
for(uchIdx=0;uchIdx <BT_MAX_CH_NUM;uchIdx++)
{
nRestemp0 = pnRawdata[1] - pnRawdata[0]; // ref - idle
nRestemp1 = pnRawdata[2+ uchIdx] - pnRawdata[0]; // ntc - idle
if(0==nRestemp1)
{
GH3X2X_DEBUG_ALGO_LOG("BT input rawdata error: ZERO! \r\n");
nRawTemp = 0;
chRet = EM_TEMP_OUT_RANGE_WRONG_INPUT;
}
else
{
nRestemp0 = ((GS64)nRestemp0 * (unSensorNtcRef*10 + unNTCChnalRes)) / nRestemp1 - unNTCChnalRes;
if(nRestemp0<0)
{
GH3X2X_DEBUG_ALGO_LOG("BT input rawdata error: NEGATIVE! \r\n");
nRawTemp = 0;
chRet = EM_TEMP_OUT_RANGE_WRONG_INPUT;
}
else
{
uRTIdx = GetRTIndex(nRestemp0,RT_Table,unSensorNtcRT_Len);
if(0 == uRTIdx)
{
nRawTemp = 0;
chRet = EM_TEMP_OUT_RANGE_L;
}
else if(0xFFFF == uRTIdx)
{
nRawTemp = 0;
chRet = EM_TEMP_OUT_RANGE_H;
}
else
{
nRawTemp = (GS16)(100*(RT_Table[uRTIdx-1]*10 - nRestemp0)/(RT_Table[uRTIdx-1]*10-RT_Table[uRTIdx]*10)) + (GS16) unTempRangeLower + (GS16)(uRTIdx-1)*100;
}
}
}
pstDrvBtOutRes->nFrameTemperature[uchIdx] = nRawTemp;
if(0 == pstDrvBtOutRes->chFrameIndex)
{
pstDrvBtOutRes->stRawTemp[uchIdx].nMin = nRawTemp;
pstDrvBtOutRes->stRawTemp[uchIdx].nMax = nRawTemp;
pstDrvBtOutRes->stRawTemp[uchIdx].nSum = nRawTemp;
GH3X2X_DEBUG_ALGO_LOG("[%s]:index: %d rawdata sum %d: %d \n", __FUNCTION__,pstDrvBtOutRes->chFrameIndex,uchIdx, pstDrvBtOutRes->stRawTemp[uchIdx].nSum);
}
else
{
pstDrvBtOutRes->stRawTemp[uchIdx].nMin = (pstDrvBtOutRes->stRawTemp[uchIdx].nMin>nRawTemp)?nRawTemp:pstDrvBtOutRes->stRawTemp[uchIdx].nMin;
pstDrvBtOutRes->stRawTemp[uchIdx].nMax = (pstDrvBtOutRes->stRawTemp[uchIdx].nMax<nRawTemp)?nRawTemp:pstDrvBtOutRes->stRawTemp[uchIdx].nMax;
pstDrvBtOutRes->stRawTemp[uchIdx].nSum += nRawTemp;
GH3X2X_DEBUG_ALGO_LOG("[%s]:index: %d rawdata sum %d: %d \n", __FUNCTION__,pstDrvBtOutRes->chFrameIndex,uchIdx, pstDrvBtOutRes->stRawTemp[uchIdx].nSum);
}
}
++pstDrvBtOutRes->chFrameIndex;
if(pstDrvBtOutRes->chFrameIndex == uFs)
{
pstDrvBtOutRes->chFrameIndex=0;
for(uchIdx=0;uchIdx <BT_MAX_CH_NUM;uchIdx++)
{
if(chRet)
{
pstDrvBtOutRes->nSecTemperature[uchIdx] = 0;
}
else
{
if(uFs>2)
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:rawdata sum: %d \n", __FUNCTION__, pstDrvBtOutRes->stRawTemp[uchIdx].nSum);
pstDrvBtOutRes->nSecTemperature[uchIdx] = (pstDrvBtOutRes->stRawTemp[uchIdx].nSum - pstDrvBtOutRes->stRawTemp[uchIdx].nMin - pstDrvBtOutRes->stRawTemp[uchIdx].nMax +((uFs-2)>>1))/(uFs-2);
}
else
{
pstDrvBtOutRes->nSecTemperature[uchIdx] = (pstDrvBtOutRes->stRawTemp[uchIdx].nMin + pstDrvBtOutRes->stRawTemp[uchIdx].nMax)>>1;
}
chRet = EM_CONVER_OK;
}
}
}
return chRet;
}
#endif
GS8 GH3x2xBtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
#if !__USE_GOODIX_DRV_NTC_Convert
//gstBtAlgoInfo.stAlgorithmConfig.pnParametersBuffer = &gstBtCFG;
gstBtAlgoInfo.stAlgorithmCalcOutput.pnResult = &gstBtAlgoOUT;
gstBtAlgoInfo.stAlgorithmCalcInput.pnRefBuffer = &gstBtInputRef;
gstBtCFG.unChannelNum = 2;
if(BT_ERRORCODE_OK != GoodixBtAlgoInit(&gstBtAlgoInfo))
{
return GH3X2X_RET_GENERIC_ERROR;
}
pstFrameInfo->pstAlgoResult->usResultBit = 0x1F;
g_unBtLastHrResult = 0;
uFs = pstFrameInfo ->pstFunctionInfo ->usSampleRate;
GH3X2X_Memset(&gstBtAlgoOUT, 0, sizeof(STGoodixAlgorithmBtCalculateOutputResult));
GH3X2X_Memset(&gstBtInputRef, 0, sizeof(STGoodixAlgorithmBtInputRef));
#else
//drv calculate bt
GH3X2X_Memset(&gstDrvBtOutRes, 0, sizeof(STGH3x2xDrvBtOutputResult));
//GH3X2X_Memcpy(RT_Table, g_nBtParamsArr, GOODIX_BT_PARAMS_NUM_MAX * sizeof(GU16));
//unSensorNtcRT_Len = sizeof(RT_Table)/sizeof(RT_Table[0]);
#endif
return GH3X2X_RET_OK;
}
GS8 GH3x2xBtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
#if !__USE_GOODIX_DRV_NTC_Convert
if(BT_ERRORCODE_OK != GoodixBtAlgoDeinit(&gstBtAlgoInfo))
{
return GH3X2X_RET_GENERIC_ERROR;
}
#endif
return GH3X2X_RET_OK;
}
GS8 GH3x2xBtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GS32 TempRawdata[4] = {0};
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
for(GU8 i = 0; i < 4; i++)
{
TempRawdata[i] = (int)(pstFrameInfo->pstFrameTempdata->unTempData[i]);
}
if (g_uchAlgoTempEnable == 0)
{
for(GU8 i = 0; i < 4; i++)
{
TempRawdata[i] = (int)(pstFrameInfo->punFrameRawdata[i]);
}
}
#if !__USE_GOODIX_DRV_NTC_Convert
gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata = TempRawdata;
if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)
{
g_unBtLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];
}
gstBtInputRef.unHR = g_unBtLastHrResult;
//GH3X2X_DEBUG_ALGO_LOG("[%s]:%d,%d,%d,%d\n", __FUNCTION__, gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[0], gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[1], gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[2], gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[3]);
if(BT_ERRORCODE_OK == GoodixBtAlgoCalculate(&gstBtAlgoInfo))
{
//if(gstBtAlgoOUT.uchRefresh)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->usResultBit = 0x3F;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
if (0!=gstBtAlgoInfo.stAlgorithmCalcOutput.pnMiddleBaseBuffer)
{
for (int i =0; i < 2; i++)
{
pstFrameInfo->pstAlgoResult->snResult[i] = gstBtAlgoInfo.stAlgorithmCalcOutput.pnMiddleBaseBuffer[i];//ntc0
//pstFrameInfo->pstAlgoResult->snResult[1] = gstBtAlgoOUT.nFPCBT;//ntc1
}
}
pstFrameInfo->pstAlgoResult->snResult[2] = gstBtAlgoOUT.uchState;
pstFrameInfo->pstAlgoResult->snResult[3] = gstBtAlgoOUT.uchConfidence;
pstFrameInfo->pstAlgoResult->snResult[4] = gstBtAlgoOUT.nCBT;
pstFrameInfo->pstAlgoResult->snResult[5] = g_unBtLastHrResult;
}
chRet = GH3X2X_RET_OK;
}
#else
// drv calculate bt
chRet =GH3x2xBtRTConvert( TempRawdata, &gstDrvBtOutRes);
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->usResultBit = 0x03;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
for (int i =0; i < 2; i++)
{
#if NTCSecondResult
pstFrameInfo->pstAlgoResult->snResult[i] = gstDrvBtOutRes.nSecTemperature[i];//ntc0 ntc1 per second
GH3X2X_DEBUG_ALGO_LOG("[%s]:rawdata: %d %d %d %d.second temp: %d %d\n", __FUNCTION__, TempRawdata[0],TempRawdata[1],TempRawdata[2],TempRawdata[3],gstDrvBtOutRes.nSecTemperature[0],gstDrvBtOutRes.nSecTemperature[1]);
#else
pstFrameInfo->pstAlgoResult->snResult[i] = gstDrvBtOutRes.nFrameTemperature[i];//ntc0 ntc1 per frame
GH3X2X_DEBUG_ALGO_LOG("[%s]:rawdata: %d %d %d %d.frame temp: %d %d\n", __FUNCTION__, TempRawdata[0],TempRawdata[1],TempRawdata[2],TempRawdata[3],gstDrvBtOutRes.nFrameTemperature[0],gstDrvBtOutRes.nFrameTemperature[1]);
#endif
}
#endif
return chRet;
}
#endif

View File

@ -0,0 +1,207 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_ecg.h"
#if (__USE_GOODIX_ECG_ALGORITHM__)
#define GH3X2X_SINGLE_CLASSIFICATION_TIME 32
goodix_ecg_ret goodix_ecg_init_func(GU32 fs)
{
goodix_ecg_config stEcgCfg = {0};
goodix_ecg_init_result stInitResult = {0};
GCHAR uchEcgVersion[100] = {0};
goodix_ecg_version((uint8_t*)uchEcgVersion);
GH3X2X_DEBUG_ALGO_LOG("ecg algorithm version : %s\r\n", uchEcgVersion);
#if (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_ENABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_DISABLE)
if (500 != fs)
{
GH3X2X_DEBUG_ALGO_LOG("[%s] fail! The sampling rate(%d) does not match the macro settings.\r\n", __FUNCTION__, fs);
return GX_ALGO_ECG_RWONG_INPUT;
}
#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_ENABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_DISABLE)
if (250 != fs)
{
GH3X2X_DEBUG_ALGO_LOG("[%s] fail! The sampling rate(%d) does not match the macro settings.\r\n", __FUNCTION__, fs);
return GX_ALGO_ECG_RWONG_INPUT;
}
#else
#error "please define __GOODIX_ECG_ALGO_CONFIG__ in gh3x2x_demo_algo_config.h !"
#endif
#if (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_ENABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_ENABLE)
stEcgCfg.qrs_flag = 1;
#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_DISABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_DISABLE)
stEcgCfg.qrs_flag = 0;
#else
#error "please define __GOODIX_ECG_ALGO_CONFIG__ in gh3x2x_demo_algo_config.h !"
#endif
stEcgCfg.fs = fs;
stEcgCfg.valid_channel_num = (uint32_t)g_nEcgParamsArr[1];
stEcgCfg.mode_type = (uint32_t)g_nEcgParamsArr[3];
stEcgCfg.ic_type = (uint32_t)g_nEcgParamsArr[4];
GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,%d,%d,%d,%d\r\n", __FUNCTION__,
stEcgCfg.fs,
stEcgCfg.valid_channel_num,
stEcgCfg.qrs_flag,
stEcgCfg.mode_type,
stEcgCfg.ic_type);
const void *p_CfgInstance = (void *)&stEcgCfg;
char chVer[ECG_INTERFACE_VERSION_LEN_MAX] = {0};
goodix_ecg_config_get_version(chVer, ECG_INTERFACE_VERSION_LEN_MAX);
const char *p_InterfaceVer = chVer;
goodix_ecg_ret ret = goodix_ecg_init(p_CfgInstance, &stInitResult, sizeof(stEcgCfg), p_InterfaceVer);
g_uchClassificationFlag = 0;
g_unEcgTimeSeconds = 0;
return ret;
}
goodix_ecg_ret goodix_ecg_deinit_func(void)
{
return goodix_ecg_deinit();
}
GS8 GH3x2xEcgAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GU16 usSampleRate = pstFrameInfo->pstFunctionInfo->usSampleRate;
goodix_ecg_ret ret = goodix_ecg_init_func(usSampleRate);
if (GX_ALGO_ECG_SUCCESS == ret)
{
chRet = GH3X2X_RET_OK;
}
else
{
chRet = GH3X2X_RET_PARAMETER_ERROR;
GH3X2X_DEBUG_ALGO_LOG("ecg init error! ret = 0x%x\r\n", ret);
}
g_unEcgFrameCnt = 0;
GH3X2X_SetNewDataFlag(GH3X2X_FUNC_OFFSET_ECG, GH3X2X_IS_NEW_RAWDATA);
*(pstFrameInfo->punFrameCnt) = 0;
return chRet;
}
GS8 GH3x2xEcgAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
goodix_ecg_ret ret = goodix_ecg_deinit_func();
if (ret == GX_ALGO_ECG_SUCCESS)
{
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("ecg deinit error! ret = 0x%x\r\n", ret);
}
return chRet;
}
GS8 GH3x2xEcgAlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)
{
if (0 == pstFrameInfo)
{
return GH3X2X_RET_GENERIC_ERROR;
}
goodix_ecg_input_rawdata stRawdata = {0};
goodix_ecg_result stResult;
GS8 chAlgoRet = 0;
GU32 unRawdata[ECG_CHANNEL_NUM] = {0};
GF32 fEcgOutData[ECG_CHANNEL_NUM] = {0};
goodix_stage unEcgStage[ECG_CHANNEL_NUM] = {stage_noneffect_out, stage_noneffect_out};
GF32 fEcgSnr[ECG_CHANNEL_NUM] = {0};
GF32 fEcgPowerLineOut[ECG_CHANNEL_NUM] = {0};
GF32 fEcgBlwOut[ECG_CHANNEL_NUM] = {0};
GF32 fEcgBpmCh[ECG_CHANNEL_NUM] = {0};
stResult.ecg_out = fEcgOutData;
stResult.ecg_stage = unEcgStage;
stResult.ecg_snr = fEcgSnr;
stResult.ecg_powerline_out = fEcgPowerLineOut;
stResult.ecg_blw_out = fEcgBlwOut;
stResult.ecg_bpm_ch = fEcgBpmCh;
stRawdata.ecg_rawdata = (GS32 *)&unRawdata;
stRawdata.frameid = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));
stRawdata.acc_x = pstFrameInfo->pusFrameGsensordata[0];
stRawdata.acc_y = pstFrameInfo->pusFrameGsensordata[1];
stRawdata.acc_z = pstFrameInfo->pusFrameGsensordata[2];
stRawdata.ecg_rawdata[0] = pstFrameInfo->punFrameRawdata[0];
stRawdata.ecg_rawdata[1] = pstFrameInfo->punFrameRawdata[1];
stRawdata.ecg_qc_flag = GH3X2X_CHECK_BIT_IS_SET(pstFrameInfo->punFrameFlag[2], 0x01);
GH3X2X_DEBUG_ALGO_LOG("[%s]ecg ecg_rawdata = %d, %d, ecg_qc_flag = %d\r\n", __FUNCTION__, stRawdata.ecg_rawdata[0], stRawdata.ecg_rawdata[1], \
stRawdata.ecg_qc_flag);
if (g_unEcgFrameCnt <= ECG_FRAME_UNUSED) /* the first 5 frame data can't be used for algo */
{
g_unEcgFrameCnt++;
stRawdata.ecg_qc_flag = 1;
}
if (1 == stRawdata.ecg_qc_flag) /* when fast recovery,data can't be used for algo */
{
return chAlgoRet;
}
goodix_ecg_ret stRet = goodix_ecg_update(&stRawdata, &stResult);
if (stRet == GX_ALGO_ECG_SUCCESS)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->snResult[0] = GH3x2x_Round(stResult.ecg_out[0] * ECG_OUT_FACTOR);
pstFrameInfo->pstAlgoResult->snResult[2] = GH3x2x_Round(stResult.ecg_out[1] * ECG_OUT_FACTOR);
GH3X2X_DEBUG_ALGO_LOG("ecg out0 = %.3f\r\n", stResult.ecg_out[0]);
GH3X2X_DEBUG_ALGO_LOG("ecg out1 = %.3f\r\n", stResult.ecg_out[1]);
//GH3X2X_INFO_ALGO_LOG("bpm result = %d\r\n",(GS32)(stResult.ecg_bpm + 0.5f));
pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)(stResult.ecg_bpm + 0.5f);
pstFrameInfo->pstAlgoResult->usResultBit = 0x1 | \
((0x1 << 1) * (pstFrameInfo->pstAlgoResult->snResult[1] != 0)) | \
((0x1 << 2) * (g_nEcgParamsArr[1] == 2));
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
GH3X2X_EcgAlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);
}
else
{
GH3X2X_DEBUG_ALGO_LOG("GH3x2xEcgAlgoExe error! error code:0x%x\r\n", stRet);
GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");
chAlgoRet = GH3X2X_RET_RESOURCE_ERROR;
}
return chAlgoRet;
}
GU8 GH3x2xEcgAlgoClassification(void)
{
goodix_ecg_classification_update((goodix_classification_flag *)&g_uchClassificationFlag);
return g_uchClassificationFlag;
}
#else
GU8 GH3x2xEcgAlgoClassification(void)
{
return 0;
}
#endif

View File

@ -0,0 +1,224 @@
/**
* @copyright (c) 2003 - 2024, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_algo_call_hr.c
*
* @brief gh3x2x algo hr interface
*
*/
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_hba.h"
#if (__USE_GOODIX_HR_ALGORITHM__)
void Gh3x2xSetHbaMode(GS32 nHbaScenario)
{
g_unHrParamsArr[1] = nHbaScenario;
}
goodix_hba_ret goodix_hba_init_func(GU32 fs)
{
goodix_hba_config stHbCfg;
goodix_hba_ret stAlgoRet = GX_ALGO_HBA_SUCCESS;
GCHAR uchHrVersion[120] = {0};
goodix_hba_ret ret = goodix_hba_version((uint8_t *)uchHrVersion);
if (GX_ALGO_HBA_SUCCESS != ret)
{
GH3X2X_DEBUG_ALGO_LOG("hba algorithm init fail : 0x%x\r\n", ret);
return ret;
}
GH3X2X_HbaAlgoChnlMapDefultSet();
GH3X2X_DEBUG_ALGO_LOG("hba algorithm version : %s\r\n", uchHrVersion);
GH3X2X_DEBUG_ALGO_LOG("hba algorithm legal chnl num : %d\r\n", g_stHbaAlgoChnlMap.uchNum);
if (g_stHbaAlgoChnlMap.uchNum > Gh3x2xGetHrAlgoSupportChnl())
{
GH3X2X_DEBUG_ALGO_LOG("ERROR: hr algorithm legal chnl num is too big, check cfg !!! \r\n");
return GX_ALGO_HBA_RWONG_INPUT;
}
stHbCfg.mode = (hba_test_mode)g_unHrParamsArr[0];
stHbCfg.scence = (hba_scenes_e)g_unHrParamsArr[1];
stHbCfg.fs = fs;
stHbCfg.valid_channel_num = g_stHbaAlgoChnlMap.uchNum;
stHbCfg.back_track_len = g_unHrParamsArr[2];
stHbCfg.hba_latest_output_time = g_unHrParamsArr[3];
stHbCfg.hba_earliest_output_time = g_unHrParamsArr[4];
stHbCfg.hba_lowerest_confidence = g_unHrParamsArr[5];
stHbCfg.hba_out_step_second = g_unHrParamsArr[6];
stHbCfg.hba_convergence_rate = g_unHrParamsArr[7];
stHbCfg.senseless_mode_step = g_unHrParamsArr[8];
stHbCfg.senseless_mode_duration = g_unHrParamsArr[9];
GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", __FUNCTION__,
stHbCfg.mode,
stHbCfg.scence,
stHbCfg.fs,
stHbCfg.valid_channel_num,
stHbCfg.back_track_len,
stHbCfg.hba_latest_output_time,
stHbCfg.hba_earliest_output_time,
stHbCfg.hba_lowerest_confidence,
stHbCfg.hba_out_step_second,
stHbCfg.hba_convergence_rate,
stHbCfg.senseless_mode_step,
stHbCfg.senseless_mode_duration);
const void *p_CfgInstance = (void *)&stHbCfg;
char chVer[HBA_INTERFACE_VERSION_LEN_MAX] = {0};
goodix_hba_config_get_version(chVer, HBA_INTERFACE_VERSION_LEN_MAX);
const char *p_InterfaceVer = chVer;
stAlgoRet = goodix_hba_init(p_CfgInstance, sizeof(stHbCfg), p_InterfaceVer);
return stAlgoRet;
}
goodix_hba_ret goodix_hba_deinit_func(void)
{
return goodix_hba_deinit();
}
GS8 GH3x2xHrAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
goodix_hba_ret ret = goodix_hba_init_func(pstFrameInfo->pstFunctionInfo->usSampleRate);
if (GX_ALGO_HBA_SUCCESS == ret)
{
chRet = GH3X2X_RET_OK;
GH3X2X_DEBUG_ALGO_LOG("[%s]GH3X2X_HbaInit success!!\r\n", __FUNCTION__);
}
else
{
GH3X2X_DEBUG_ALGO_LOG("hba init error! error code:0x%x\r\n", ret);
}
pstFrameInfo->pstAlgoRecordResult->uchUpdateFlag = 0;
pstFrameInfo->pstAlgoRecordResult->snResult[0] = 0;
return chRet;
}
GS8 GH3x2xHrAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
goodix_hba_ret ret = goodix_hba_deinit_func();
if (GX_ALGO_HBA_SUCCESS == ret)
{
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("hba deinit error! error code:0x%x\r\n", ret);
}
return chRet;
}
//call algo 2-level interface
GS8 GH3x2xHrAlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)
{
if (0 == pstFrameInfo)
{
return GH3X2X_RET_GENERIC_ERROR;
}
GS32 ppg_rawdata[3 * PPG_CHANNEL_NUM] = {0};
GS32 cur_adj_flg[3 * PPG_CHANNEL_NUM] = {0};
GS32 gain_adj_flg[3 * PPG_CHANNEL_NUM] = {0};
GS32 enable_flg[3 * PPG_CHANNEL_NUM] = {0};
goodix_hba_input_rawdata stRawdata = {0};
goodix_hba_result stResult = {0};
stRawdata.ppg_rawdata = (int32_t *)ppg_rawdata;
stRawdata.cur_adj_flg = (int32_t *)cur_adj_flg;
stRawdata.gain_adj_flg = (int32_t *)gain_adj_flg;
stRawdata.enable_flg = (int32_t *)enable_flg;
stRawdata.frameid = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));
stRawdata.acc_x = pstFrameInfo->pusFrameGsensordata[0];
stRawdata.acc_y = pstFrameInfo->pusFrameGsensordata[1];
stRawdata.acc_z = pstFrameInfo->pusFrameGsensordata[2];
stRawdata.sleep_flg = GH3x2xSleepFlagGet();
GU8 uchChMapCnt = 0;
GU8 uchRawdataIndex = 0;
GU8 uchTotalChannelNum = 0;
GS8 chAlgoRet = GH3X2X_RET_OK;
for (uchChMapCnt = 0; uchChMapCnt < 3 * PPG_CHANNEL_NUM; ++uchChMapCnt)
{
if (g_stHbaAlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)] < 0xff)
{
uchRawdataIndex = g_stHbaAlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)];
//make gain_adj_flg and cur_adj_flg to 0 for algo 1.0.5.0(alpha).
stRawdata.gain_adj_flg[uchChMapCnt] = 0;
stRawdata.cur_adj_flg[uchChMapCnt] = 0;
stRawdata.enable_flg[uchChMapCnt] = 1;
stRawdata.ppg_rawdata[uchChMapCnt] = pstFrameInfo->punFrameRawdata[uchRawdataIndex];
uchTotalChannelNum++;
GH3X2X_DEBUG_ALGO_LOG("[%s]ppg_rawdata = %d,gain_adj_flg = %d,cur_adj_flg = %d\r\n", __FUNCTION__, \
(int)stRawdata.ppg_rawdata[uchChMapCnt], (int)stRawdata.gain_adj_flg[uchChMapCnt], \
(int)stRawdata.cur_adj_flg[uchChMapCnt]);
}
}
stRawdata.total_channel_num = uchTotalChannelNum;
/* call algorithm, update result */
goodix_hba_ret ret = goodix_hba_update(&stRawdata, &stResult);
if (GX_ALGO_HBA_SUCCESS == ret)
{
if (1 == stResult.hba_out_flag)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = (GU8)stResult.hba_out_flag;
pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)stResult.hba_out;
pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stResult.valid_score;
pstFrameInfo->pstAlgoResult->snResult[2] = GH3X2X_ALGORITHM_GF32_2_GS32(stResult.hba_snr);
pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)stResult.valid_level;
pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)stResult.hba_acc_info;
pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)stResult.hba_acc_scence;
GH3X2X_DEBUG_ALGO_LOG("[%s]hr = %d,UpdateFlag = %d\r\n", __FUNCTION__, \
(int)pstFrameInfo->pstAlgoResult->snResult[0], (int)pstFrameInfo->pstAlgoResult->uchUpdateFlag);
pstFrameInfo->pstAlgoResult->usResultBit = 0x3F;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
#if __GH3X2X_HR_OUTPUT_VALUE_STRATEGY_EN__
Gh3x2xHrOutputValueStrategyPro(pstFrameInfo->pstAlgoResult,pstFrameInfo->punFrameCnt[0]);
#endif
GH3X2X_HrAlgorithmResultReport(pstFrameInfo->pstAlgoResult,pstFrameInfo->punFrameCnt[0]);
pstFrameInfo->pstAlgoRecordResult->uchUpdateFlag = (GU8)stResult.hba_out_flag;
pstFrameInfo->pstAlgoRecordResult->snResult[0] = (GS32)stResult.hba_out;
}
}
else
{
chAlgoRet = GH3X2X_RET_RESOURCE_ERROR;
GH3X2X_DEBUG_ALGO_LOG("GH3x2xHrAlgoExe error! error code = 0x%x\r\n", ret);
GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");
}
return chAlgoRet;
}
#endif

View File

@ -0,0 +1,172 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "goodix_hba.h"
#include "goodix_hrv.h"
#if (__USE_GOODIX_HRV_ALGORITHM__)
GU32 g_unHrvLastHrResult = 0;
//hrv
goodix_hrv_ret goodix_hrv_init_func(GU32 fs)
{
goodix_hrv_ret stAlgoRet = GX_HRV_ALGO_OK;
goodix_hrv_config stHrvConfig = {
g_nHrvParamsArr[0],
fs,
{g_nHrvParamsArr[1] * 10000, g_nHrvParamsArr[2] * 10000, g_nHrvParamsArr[3] * 10000, g_nHrvParamsArr[4] * 10000}
};
GCHAR uchHrvVersion[100] = {0};
GH3X2X_Memcpy(uchHrvVersion, goodix_hrv_version(), strlen((GCHAR *)goodix_hrv_version()) + 1);
GH3X2X_DEBUG_ALGO_LOG("hrv algorithm version : %s\r\n", uchHrvVersion);
GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,%d,%d,%d,%d,%d,\r\n", __FUNCTION__,
stHrvConfig.need_ipl,
stHrvConfig.fs,
stHrvConfig.acc_thr[0],
stHrvConfig.acc_thr[1],
stHrvConfig.acc_thr[2],
stHrvConfig.acc_thr[3]);
const void *p_CfgInstance = (void *)&stHrvConfig;
char chVer[HRV_INTERFACE_VERSION_LEN_MAX] = {0};
goodix_hrv_config_get_version(chVer, HRV_INTERFACE_VERSION_LEN_MAX);
const char *p_InterfaceVer = chVer;
stAlgoRet = goodix_hrv_init(p_CfgInstance, sizeof(stHrvConfig), p_InterfaceVer);
return stAlgoRet;
}
uint32_t goodix_hrv_deinit_func(void)
{
uint32_t nRet = GX_HRV_ALGO_OK;
nRet = goodix_hrv_deinit();
if (GX_HRV_ALGO_OK != nRet)
{
GH3X2X_DEBUG_ALGO_LOG("hrv init errorcode : 0x%x\r\n", nRet);
}
return nRet;
}
GS8 GH3x2xHrvAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
uint32_t ret = goodix_hrv_init_func(pstFrameInfo->pstFunctionInfo->usSampleRate);
if (GX_ALGO_HBA_SUCCESS == ret)
{
pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("hrv init error! error code = 0x%x\r\n", ret);
}
g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag = 0;
g_unHrvLastHrResult = 0;
return chRet;
}
GS8 GH3x2xHrvAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
if (GX_ALGO_HBA_SUCCESS == goodix_hrv_deinit_func())
{
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("hrv deinit error!\r\n");
}
return chRet;
}
GS8 GH3x2xHrvAlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)
{
if (0 == pstFrameInfo)
{
return GH3X2X_RET_GENERIC_ERROR;
}
GS8 chAlgoRet = GH3X2X_RET_OK;
GU8 uchGainValue = 0;
GS32 ppg_rawdata[PPG_CHANNEL_NUM] = {0};
GS32 cur_adj_flg[PPG_CHANNEL_NUM] = {0};
GS32 gain_adj_flg[PPG_CHANNEL_NUM] = {0};
goodix_hrv_result stResult = {0};
goodix_hrv_input_rawdata stRawdataInput = {0};
stRawdataInput.ppg_rawdata = (int32_t *)ppg_rawdata;
stRawdataInput.cur_adj_flg = (int32_t *)cur_adj_flg;
stRawdataInput.gain_adj_flg = (int32_t *)gain_adj_flg;
stRawdataInput.bit_num = 24;
stRawdataInput.acc_x = pstFrameInfo->pusFrameGsensordata[0];
stRawdataInput.acc_y = pstFrameInfo->pusFrameGsensordata[1];
stRawdataInput.acc_z = pstFrameInfo->pusFrameGsensordata[2];
stRawdataInput.frame_id = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));
if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)
{
g_unHrvLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];
}
stRawdataInput.hr = g_unHrvLastHrResult;
for (GS32 nRawdatacnt = 0; nRawdatacnt < PPG_CHANNEL_NUM; nRawdatacnt++)
{
stRawdataInput.ppg_rawdata[nRawdatacnt] = pstFrameInfo->punFrameRawdata[nRawdatacnt];
uchGainValue = GH3X2X_GET_LOW_4BITS(pstFrameInfo->punFrameAgcInfo[nRawdatacnt]);
if ((pstFrameInfo->puchFrameLastGain[nRawdatacnt] != uchGainValue) && \
(pstFrameInfo->puchFrameLastGain[nRawdatacnt] != GH3X2X_GAIN_VALUE_INVALID))
{
stRawdataInput.gain_adj_flg[nRawdatacnt] = 1;
pstFrameInfo->puchFrameLastGain[nRawdatacnt] = uchGainValue;
}
stRawdataInput.cur_adj_flg[nRawdatacnt] = ((pstFrameInfo->punFrameFlag[0]) & 0x01);
GH3X2X_DEBUG_ALGO_LOG("[%s]ppg_rawdata = %d, gain_adj_flg = %d, cur_adj_flg = %d\r\n", __FUNCTION__, \
(int)stRawdataInput.ppg_rawdata[nRawdatacnt], (int)stRawdataInput.gain_adj_flg[nRawdatacnt], \
(int)stRawdataInput.cur_adj_flg[nRawdatacnt]);
}
goodix_hrv_ret ret = goodix_hrv_calc(&stRawdataInput, &stResult);
if (GX_HRV_ALGO_OK == ret || GX_HRV_ALGO_UPDATE == ret)
{
if (GX_HRV_ALGO_UPDATE == ret)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)stResult.rri[0];
pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stResult.rri[1];
pstFrameInfo->pstAlgoResult->snResult[2] = (GS32)stResult.rri[2];
pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)stResult.rri[3];
pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)stResult.rri_confidence;
pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)stResult.rri_valid_num;
pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
GH3X2X_HrvAlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);
}
}
else
{
chAlgoRet = GH3X2X_RET_RESOURCE_ERROR;
GH3X2X_DEBUG_ALGO_LOG("GH3x2xHrAlgoExe error! error code = 0x%x\r\n", ret);
GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");
}
return chAlgoRet;
}
#endif

View File

@ -0,0 +1,131 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_hsm.h"
#if (__USE_GOODIX_HSM_ALGORITHM__)
GS8 GH3x2xHsmAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
int32_t nRet = GH3X2X_RET_GENERIC_ERROR;
#if (GH3X2X_ALGORITHM_HSM_SUPPORT)
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
//g_uchLastGainOfChannel[0] = GH3X2X_GAIN_VALUE_INVALID;
//int nHSMFs = (int)pstFrameInfo ->pstFunctionInfo ->usSampleRate;
int32_t nHSMFs = 25;
nRet = HSMAlgoInit(&nHSMFs);
if (nRet != GH3X2X_RET_OK)
{
GH3X2X_DEBUG_ALGO_LOG("hsm process error! error code : %d\r\n", (int)nRet);
}
else
{
pstFrameInfo->pstAlgoResult->usResultBit = 0x1;
}
g_unHsmLastHrResult = 0;
#else
nRet = GH3X2X_RET_ALGO_NO_SUPPORTED;
GH3X2X_DEBUG_ALGO_LOG("hsm algorithm no supported error!\r\n");
#endif
return (GS8)nRet;
}
GS8 GH3x2xHsmAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
#if (GH3X2X_ALGORITHM_HSM_SUPPORT)
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
ST_HSM_DATA_OUT stHSMDataOut;
ST_HSM_SCORE stHSMScore;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
GU8 uchHsmResultSendBuffer[235] = {0};
GU8 uchHsmPackLen = 140;
if (HSMLastDataProc(&stHSMDataOut, &stHSMScore) == GH3X2X_RET_OK)
{
uchHsmResultSendBuffer[4] = 2;
if (stHSMDataOut.uchStageDataFlag != 0)
{
GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4, (GU8*)&stHSMScore, 18);
uchHsmResultSendBuffer[23] = stHSMDataOut.uchStageOutNum;
GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4 + 19, stHSMDataOut.puchHSMStageOut, 120);
}
GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_HSM_RESULT_UPDATE, uchHsmResultSendBuffer,
&uchHsmResultSendBuffer[4], uchHsmPackLen);
Gh3x2xDemoSendProtocolData(uchHsmResultSendBuffer,usRespondLen);
chRet = HSMAlgoDeInit();
}
else
{
chRet = HSMAlgoDeInit();
GH3X2X_RET_ERROR_CHECK(chRet);
chRet = GH3X2X_RET_GENERIC_ERROR;
}
#else
GS8 chRet = GH3X2X_RET_ALGO_NO_SUPPORTED;
GH3X2X_DEBUG_ALGO_LOG("hsm algorithm no supported error!\r\n");
#endif
return chRet;
}
GS8 GH3x2xHsmAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)
{
if(0 == pstFrameInfo )
{
return 0;
}
#if (GH3X2X_ALGORITHM_HSM_SUPPORT)
ST_HSM_DATA_IN stHSMDataIn;
ST_HSM_DATA_OUT stHSMDataOut;
ST_HSM_SCORE stHSMScore;
if(GH3X2X_RET_OK != GH3x2xCheckAndFreeMem(pstFrameInfo))
{
return;
}
stHSMDataIn.IPpgRaw = (int)GH3X2X_GET_RAWDATA_FOR_ALGO((int)pstFrameInfo->punFrameRawdata[0] - GH3X2X_RAWDATA_BASE_VALUE);
stHSMDataIn.IACCx = pstFrameInfo->pusFrameGsensordata[0];
stHSMDataIn.IACCy = pstFrameInfo->pusFrameGsensordata[1];
stHSMDataIn.IACCz = pstFrameInfo->pusFrameGsensordata[2];
if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->usResultBit = 0x1;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)g_unHsmLastHrResult;
g_unHsmLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];
}
stHSMDataIn.IHeart = g_unHsmLastHrResult;
if (HSMProc(&stHSMDataIn, &stHSMDataOut, &stHSMScore) == GH3X2X_RET_OK)
{
if (stHSMDataOut.uchStageDataFlag != 0)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->snResult[0] = 1;
GU8 uchHsmResultSendBuffer[235] = {0};
GU8 uchHsmPackLen = 140;
uchHsmResultSendBuffer[4] = stHSMDataOut.uchStageDataFlag;
GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4, (GU8*)&stHSMScore, 18);
uchHsmResultSendBuffer[23] = stHSMDataOut.uchStageOutNum;
GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4 + 19, stHSMDataOut.puchHSMStageOut, 120);
GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_HSM_RESULT_UPDATE, uchHsmResultSendBuffer,
&uchHsmResultSendBuffer[4], uchHsmPackLen);
Gh3x2xDemoSendProtocolData(uchHsmResultSendBuffer,usRespondLen);
}
}
else
{
GH3X2X_DEBUG_ALGO_LOG("hsm process error!\r\n");
}
#else
return;
#endif
}
#endif

View File

@ -0,0 +1,282 @@
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "goodix_mem.h"
#include "goodix_nadt.h"
#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)
#define NADT_CONFIG_SAMPLE_RATE_TYPE (0)
#define NADT_CONFIG_MULTI_SAMPLE_RATE_TYPE (0)
#define SOFT_WEAR_INPUT_DATA_CHNL0_INDEX (0)
#define SOFT_WEAR_INPUT_DATA_ACCX_INDEX (1)
#define SOFT_WEAR_INPUT_DATA_ACCY_INDEX (2)
#define SOFT_WEAR_INPUT_DATA_ACCZ_INDEX (3)
#define SOFT_WEAR_INPUT_COLOR_INDEX (4)
#define SOFT_WEAR_INPUT_DATA_ADT_INDEX (5) //ir adt data
#define SOFT_WEAR_INPUT_DATA_BG_INDEX (6)
#define SOFT_WEAR_INPUT_DATA_CAP0_INDEX (7)
#define SOFT_WEAR_INPUT_DATA_CAP1_INDEX (8)
#define SOFT_WEAR_INPUT_DATA_CAP2_INDEX (9)
#define SOFT_WEAR_INPUT_DATA_CAP3_INDEX (10)
#define SOFT_WEAR_INPUT_DATA_INDEX_TOTAL (11)
#define SOFT_WEAR_OUTPUT_DATA_INDEX_TOTAL (8)
#define WATCH_NUM (3)
#if (WATCH_NUM == 1)
static GS32 lWearCap1 = 16400;
static GS32 lUnwearCap1 = 12400;
static GS32 lNoise1 = 300;
static GS32 lWearCap2 = 0;
static GS32 lUnwearCap2 = 0;
static GS32 lNoise2 = 0;
#elif (WATCH_NUM == 2)
static GS32 lWearCap1 = 20000;
static GS32 lUnwearCap1 = 16000;
static GS32 lNoise1 = 200;
static GS32 lWearCap2 = 3700;
static GS32 lUnwearCap2 = 1200;
static GS32 lNoise2 = 200;
#elif (WATCH_NUM == 3)
static GS32 lWearCap1 = 42500;
static GS32 lUnwearCap1 = 39500;
//static GS32 lNoise1 = 150;
static GS32 lWearCap2 = 42500;
static GS32 lUnwearCap2 = 39500;
//static GS32 lNoise2 = 150;
#endif
//static GS32 ghbrelsult[10];
//static GS32 glConfig[3] = { 0 };
static GU8 g_uchSoftAdtChannl0Color; // 0: green 1: ir
static GU32 g_unNadtIrDefaultTimeOutRecord = 0;
static GU32 g_unNadtIrDefaultTimeOutSecondsThrd = __SOFT_ADT_IR_DETECT_TIMEOUT__;
static GU8 g_SoftWearQuality = 0;
NADT_ST_MID_INFO stMidInfo;
extern GU8 g_SoftAdtWearState;
void Gh3x2x_SetIRDetectTimeThreshold(GU32 unIRDetectTimeThreshold)
{
g_unNadtIrDefaultTimeOutSecondsThrd = unIRDetectTimeThreshold;
}
void SoftWearControlInit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_DEFAULT;
GCHAR uchNadtVersion[100] = {0};
GetNadtVersion((uint8_t *)uchNadtVersion);
GH3X2X_DEBUG_ALGO_LOG("[%s]nadt algorithm version : %s\r\n", __FUNCTION__, uchNadtVersion);
goodix_nadt_config stNadtCfg = {
pstFrameInfo->pstFunctionInfo->usSampleRate, // 采样率
3, // 佩戴等级
0, // 睡眠状态
1200, // 活体检测超时时间
4, // 脱落确认时间
2, // 活体确认时间
8638608, // ADT wear on阈值
8588608, // ADT wear off阈值
25, // ACC阈值
1, // 活体检测使能标记
300, // 高次谐波含量阈值
50, // 心率下限
140, // 心率上限
8, // 心率周期差异阈值
50, // 信号平稳性分数阈值
30, // 基线单调性阈值
15, // 基线平坦性阈值
1000, // 归一化信号阈值放大系数
1, // 环境光突变检测使能标记
100, // 突变环境光变化量阈值
12, // 突变环境光峰谷个数阈值
1, // 环境光周期检测使能标记
10, // 周期环境光变化量阈值
10, // 环境光周期阈值
5 // 环境光周期差异阈值
};
GH3X2X_DEBUG_ALGO_LOG("[%s]nadt param0 : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,\r\n", __FUNCTION__, stNadtCfg.sampleRateNADT, \
stNadtCfg.unwearDetectLevel, stNadtCfg.sleepStatus, stNadtCfg.checkTimeoutThr, stNadtCfg.unwearCheckCntThr, stNadtCfg.wearCheckCntThr, \
stNadtCfg.adtWearOnThr, stNadtCfg.adtWearOffThr, stNadtCfg.accStdThr, stNadtCfg.liveDetectEnable, stNadtCfg.rawPVLenThr, \
stNadtCfg.heartBeatThrLow, stNadtCfg.heartBeatThrHigh, stNadtCfg.difRrInterThr, stNadtCfg.wearAcfScoreThr);
GH3X2X_DEBUG_ALGO_LOG("[%s]nadt param1 : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,\r\n", __FUNCTION__, stNadtCfg.baseLinePosRatioThr, \
stNadtCfg.baseLineDiffThr, stNadtCfg.sigScaleThr, stNadtCfg.bgJumpDetectEnable, stNadtCfg.jumpBgDiffThr, stNadtCfg.bgPeakValleyNumThr, \
stNadtCfg.bgPeriodDetectEnable, stNadtCfg.periodBgDiffThr, stNadtCfg.bgPeriodThr, stNadtCfg.bgPeriodDiffThr);
const void *p_CfgInstance = (void *)&stNadtCfg;
char chVer[NADT_INTERFACE_VERSION_LEN_MAX] = {0};
goodix_nadt_config_get_version(chVer, NADT_INTERFACE_VERSION_LEN_MAX);
const char *p_InterfaceVer = chVer;
NADTProcInit(p_CfgInstance, sizeof(stNadtCfg), p_InterfaceVer);
memset(&stMidInfo, 0, sizeof(NADT_ST_MID_INFO));
}
void GH3x2xCapNadtResultPro(const STGh3x2xFrameInfo * const pstFrameInfo,GS32 pnSoftWearOffDetResult[])
{
if (pnSoftWearOffDetResult[3]) // 电容更新标记,更新佩戴检测阈值
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
lUnwearCap1 = pnSoftWearOffDetResult[4];
lWearCap1 = pnSoftWearOffDetResult[5];
lUnwearCap2 = pnSoftWearOffDetResult[6];
lWearCap2 = pnSoftWearOffDetResult[7];
}
if(g_SoftWearQuality != pnSoftWearOffDetResult[2])
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
g_SoftWearQuality = pnSoftWearOffDetResult[2];
}
if(pstFrameInfo->punFrameCnt == 0)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
}
if(pstFrameInfo->pstAlgoResult->uchUpdateFlag == 1)
{
pstFrameInfo->pstAlgoResult->usResultBit = 0x7;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
pstFrameInfo->pstAlgoResult->snResult[0] = pnSoftWearOffDetResult[0]; // (bit0-bit1)佩戴状态0默认1佩戴2脱落3非活体 (bit2)疑似脱落标记0正常1疑似脱落
pstFrameInfo->pstAlgoResult->snResult[1] = pnSoftWearOffDetResult[1]; //活体检测置信度
pstFrameInfo->pstAlgoResult->snResult[2] = pnSoftWearOffDetResult[2]; //佩戴质量1紧佩戴2松佩戴3极度松佩戴4脱落
if(pstFrameInfo->punFrameCnt == 0)
{
pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;
pstFrameInfo->pstAlgoResult->snResult[3] = lUnwearCap1; //脱落电容值1
pstFrameInfo->pstAlgoResult->snResult[4] = lWearCap1; //佩戴电容值1
pstFrameInfo->pstAlgoResult->snResult[5] = lUnwearCap2; //脱落电容值2
pstFrameInfo->pstAlgoResult->snResult[6] = lWearCap2; //佩戴电容值2
}
else
{
pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;
pstFrameInfo->pstAlgoResult->snResult[3] = pnSoftWearOffDetResult[4]; //脱落电容值1
pstFrameInfo->pstAlgoResult->snResult[4] = pnSoftWearOffDetResult[5]; //佩戴电容值1
pstFrameInfo->pstAlgoResult->snResult[5] = pnSoftWearOffDetResult[6]; //脱落电容值2
pstFrameInfo->pstAlgoResult->snResult[6] = pnSoftWearOffDetResult[7]; //佩戴电容值2
}
}
}
GS8 GH3x2xSoftAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GS32 nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_INDEX_TOTAL] = {0};
GS32 pnSoftWearOffDetResult[SOFT_WEAR_OUTPUT_DATA_INDEX_TOTAL] = {0};
if(pstFrameInfo)
{
GU32 unLedAdjFlag = 0;
if(pstFrameInfo->punFrameFlag[0]&0x00000001) //led current change
{
unLedAdjFlag = 1;
}
if((0xFF != pstFrameInfo->puchFrameLastGain[0])&&((pstFrameInfo->punFrameAgcInfo[0]&0x0000000F) != pstFrameInfo->puchFrameLastGain[0])) //tia gain change
{
unLedAdjFlag = 1;
}
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ACCX_INDEX] = pstFrameInfo->pusFrameGsensordata[0];
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ACCY_INDEX] = pstFrameInfo->pusFrameGsensordata[1];
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ACCZ_INDEX] = pstFrameInfo->pusFrameGsensordata[2];
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_CHNL0_INDEX] = pstFrameInfo->punFrameRawdata[0];
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_CHNL0_INDEX] |= (unLedAdjFlag << 26); //led adj flag
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_COLOR_INDEX] = g_uchSoftAdtChannl0Color; //0:GREEN 1:IR
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ADT_INDEX] = pstFrameInfo->punFrameRawdata[1];
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_BG_INDEX] = pstFrameInfo->punFrameRawdata[2];
if (g_uchAlgoCapEnable == 1)
{
for (int k = 0; k < 4; k++)
{
nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_CAP0_INDEX + k] = pstFrameInfo->pstFrameCapdata->unCapData[k];// [PPGACCLEN + ALGOLEN + guchCompareNum + k]; //电容
}
}
goodix_nadt_ret uchRet = NADTProc(nSoftWearOffInputBuf, pnSoftWearOffDetResult, &stMidInfo);
GU32 unNadtIrDefaultTimeOutThrd = g_unNadtIrDefaultTimeOutSecondsThrd * pstFrameInfo->pstFunctionInfo->usSampleRate;
if (g_unNadtIrDefaultTimeOutRecord >= unNadtIrDefaultTimeOutThrd && ((pnSoftWearOffDetResult[0] & 0x3) == 0))
{
pnSoftWearOffDetResult[0] = pnSoftWearOffDetResult[0] | 0x1;
g_unNadtIrDefaultTimeOutRecord = 0;
}
if ((pnSoftWearOffDetResult[0] & 0x2) == 0)
{
if (GH3X2X_FUNCTION_SOFT_ADT_IR == pstFrameInfo->unFunctionID)
{
g_unNadtIrDefaultTimeOutRecord++;
}
}
if (GX_ALGO_NADT_SUCCESS != uchRet)
{
GH3X2X_DEBUG_ALGO_LOG("[GH3x2xSoftAdtAlgoExe]NADTProc: error! error code = 0x%x\r\n", uchRet);
}
if (g_uchAlgoCapEnable == 1)
{
GH3x2xCapNadtResultPro(pstFrameInfo, pnSoftWearOffDetResult);
}
else
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->usResultBit = 0x3;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
pstFrameInfo->pstAlgoResult->snResult[0] = pnSoftWearOffDetResult[0]; // (bit0-bit1)佩戴状态0默认1佩戴2脱落3非活体 (bit2)疑似脱落标记0正常1疑似脱落
pstFrameInfo->pstAlgoResult->snResult[1] = pnSoftWearOffDetResult[1]; // 活体检测置信度
GH3X2X_DEBUG_ALGO_LOG("[nadt] wear status:%d %d, confiidence = %d\r\n", pstFrameInfo->pstAlgoResult->snResult[0] & 0x3, \
(pstFrameInfo->pstAlgoResult->snResult[0] >> 2) & 0x1, pstFrameInfo->pstAlgoResult->snResult[1]);
}
//report
if (g_uchSoftAdtChannl0Color == 0)
{
GH3X2X_SoftAdtGreenAlgorithmResultReport(pstFrameInfo->pstAlgoResult, GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt)));
}
else if(g_uchSoftAdtChannl0Color == 1)
{
GH3X2X_SoftAdtIrAlgorithmResultReport(pstFrameInfo->pstAlgoResult, GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt)));
}
}
return GH3X2X_RET_OK;
}
GS8 GH3x2xSoftAdtAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
if (pstFrameInfo)
{
g_SoftWearQuality = 0;
g_uchSoftAdtChannl0Color = 1 * (GH3X2X_FUNCTION_SOFT_ADT_IR == (pstFrameInfo ->unFunctionID));
GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]CH0 slot = %d, rx = %d\r\n", GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(pstFrameInfo ->pchChnlMap[0]), \
GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(pstFrameInfo ->pchChnlMap[0]));
GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]CH1 slot = %d, rx = %d\r\n", GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(pstFrameInfo ->pchChnlMap[1]), \
GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(pstFrameInfo ->pchChnlMap[1]));
GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]CH2 slot = %d, rx = %d\r\n", GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(pstFrameInfo ->pchChnlMap[2]), \
GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(pstFrameInfo ->pchChnlMap[2]));
GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]g_uchSoftAdtChannl0Color = %d\r\n", g_uchSoftAdtChannl0Color);
SoftWearControlInit(pstFrameInfo);
}
return GH3X2X_RET_OK;
}
GS8 GH3x2xSoftAdtAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]%s\r\n", __FUNCTION__);
goodix_nadt_ret ret = NADTProcDeinit();
g_unNadtIrDefaultTimeOutRecord = 0;
if (GX_ALGO_NADT_SUCCESS != ret)
{
GH3X2X_DEBUG_ALGO_LOG("[%s] fail! error code = 0x%x\r\n", __FUNCTION__, ret);
return GH3X2X_RET_GENERIC_ERROR;
}
return GH3X2X_RET_OK;
}
#endif

View File

@ -0,0 +1,72 @@
#include <stdio.h>
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_resp.h"
#if (__USE_GOODIX_RESP_ALGORITHM__)
GS8 GH3x2xRespAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_RESP]->puchFrameLastGain[0] = GH3X2X_GAIN_VALUE_INVALID;
GS32 nRespFs = ((GS32)(pstFrameInfo ->pstFunctionInfo ->usSampleRate) & 0xFFFF);
chRet = RespInit(&nRespFs);
if (chRet == GH3X2X_RET_OK)
{
pstFrameInfo->pstAlgoResult->usResultBit = 0x3;
}
return chRet;
}
GS8 GH3x2xRespAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
RespDeInit();
chRet = GH3X2X_RET_OK;
return chRet;
}
GS8 GH3x2xRespAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)
{
if(0 == pstFrameInfo )
{
return GH3X2X_RET_GENERIC_ERROR;
}
RESP_ST_DATA_IN stRespDataIn = {0};
RESP_ST_DATA_OUT stRespDataOut = {0};
GU8 uchGainValue = 0;
stRespDataIn.IPpgRaw = GH3X2X_GET_RAWDATA_FOR_ALGO(pstFrameInfo->punFrameRawdata[0] - GH3X2X_RAWDATA_BASE_VALUE);
stRespDataIn.IACCx = pstFrameInfo->pusFrameGsensordata[0];
stRespDataIn.IACCy = pstFrameInfo->pusFrameGsensordata[1];
stRespDataIn.IACCz = pstFrameInfo->pusFrameGsensordata[2];
uchGainValue = GH3X2X_GET_LOW_4BITS(pstFrameInfo->punFrameAgcInfo[0]);
if (((pstFrameInfo->puchFrameLastGain[0] != uchGainValue) && \
(pstFrameInfo->puchFrameLastGain[0] != GH3X2X_GAIN_VALUE_INVALID)) ||\
((pstFrameInfo->punFrameFlag[0]) & 0x01))
{
stRespDataIn.IAdjFlag = 1;
pstFrameInfo->puchFrameLastGain[0] = uchGainValue;
}
GU8 chRet = RespProc(&stRespDataIn, &stRespDataOut);
if (1 == stRespDataOut.nRespOutFlag && chRet == 0)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;
pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)stRespDataOut.nRespRate;
pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stRespDataOut.nBelieve;
pstFrameInfo->pstAlgoResult->usResultBit = 0x3;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
//GH3X2X_HrvAlgorithmResultReport(pstFrameInfo->pstAlgoResult,stRawdata.frameid);
}
return chRet;
}
#endif

View File

@ -0,0 +1,218 @@
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_algo.h"
#include "goodix_spo2.h"
#if (__USE_GOODIX_SPO2_ALGORITHM__)
goodix_spo2_ret goodix_spo2_init_func(GU32 fs)
{
goodix_spo2_ret stAlgoRet = GX_ALGO_SPO2_SUCCESS;
GCHAR uchSpo2Version[150] = {0};
GH3X2X_Spo2AlgoChnlMapDefultSet();
goodix_spo2_version((uint8_t *)uchSpo2Version);
GH3X2X_DEBUG_ALGO_LOG("spo2 algorithm version : %s\r\n", uchSpo2Version);
GH3X2X_DEBUG_ALGO_LOG("spo2 algorithm legal chnl num : %d\r\n", g_stSpo2AlgoChnlMap.uchNum);
if (g_stSpo2AlgoChnlMap.uchNum > Gh3x2xGetSpo2AlgoSupportChnl())
{
GH3X2X_DEBUG_ALGO_LOG("ERROR: spo2 algorithm legal chnl num is too big, check cfg !!! \r\n");
return GX_ALGO_SPO2_RWONG_INPUT;
}
goodix_spo2_config stSpo2Cfg = {
g_stSpo2AlgoChnlMap.uchNum, // 有效通道数
fs, // 采样率
g_nSpo2ParamssArr[0], g_nSpo2ParamssArr[1], g_nSpo2ParamssArr[2], g_nSpo2ParamssArr[3],
g_nSpo2ParamssArr[4], g_nSpo2ParamssArr[5], g_nSpo2ParamssArr[6], g_nSpo2ParamssArr[7],
g_nSpo2ParamssArr[8], g_nSpo2ParamssArr[9], g_nSpo2ParamssArr[10], g_nSpo2ParamssArr[11],
g_nSpo2ParamssArr[12], g_nSpo2ParamssArr[13], g_nSpo2ParamssArr[14], g_nSpo2ParamssArr[15],
g_nSpo2ParamssArr[16], g_nSpo2ParamssArr[17], g_nSpo2ParamssArr[18], g_nSpo2ParamssArr[19],
g_nSpo2ParamssArr[20], g_nSpo2ParamssArr[21], g_nSpo2ParamssArr[22], g_nSpo2ParamssArr[23],
g_nSpo2ParamssArr[24], g_nSpo2ParamssArr[25]
};
GH3X2X_INFO_ALGO_LOG("[%s]: params1 = %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", __FUNCTION__,
stSpo2Cfg.valid_chl_num,
stSpo2Cfg.raw_fs,
stSpo2Cfg.cali_coef_a4,
stSpo2Cfg.cali_coef_a3,
stSpo2Cfg.cali_coef_a2,
stSpo2Cfg.cali_coef_a1,
stSpo2Cfg.cali_coef_a0,
stSpo2Cfg.hb_en_flg,
stSpo2Cfg.wear_mode,
stSpo2Cfg.acc_thr_max,
stSpo2Cfg.acc_thr_min,
stSpo2Cfg.acc_thr_scale,
stSpo2Cfg.acc_thr_num,
stSpo2Cfg.acc_thr_angle,
stSpo2Cfg.ctr_en_flg,
stSpo2Cfg.ctr_red_thr);
GH3X2X_INFO_ALGO_LOG("[%s]: params2 = %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", __FUNCTION__,
stSpo2Cfg.ppg_jitter_thr,
stSpo2Cfg.ppg_noise_thr,
stSpo2Cfg.ppg_coeff_thr,
stSpo2Cfg.quality_module_key,
stSpo2Cfg.low_spo2_thr,
stSpo2Cfg.fast_out_time,
stSpo2Cfg.slow_out_time,
stSpo2Cfg.min_stable_time_high,
stSpo2Cfg.min_stable_time_low,
stSpo2Cfg.max_spo2_variation_high,
stSpo2Cfg.max_spo2_variation_low,
stSpo2Cfg.ouput_module_key);
const void *p_CfgInstance = (void *)&stSpo2Cfg;
char chVer[SPO2_INTERFACE_VERSION_LEN_MAX] = {0};
goodix_spo2_config_get_version(chVer, SPO2_INTERFACE_VERSION_LEN_MAX);
//const char *p_InterfaceVer = chVer;
stAlgoRet = goodix_spo2_init(p_CfgInstance, sizeof(stSpo2Cfg), chVer);
return stAlgoRet;
}
goodix_spo2_ret goodix_spo2_deinit_func(void)
{
return goodix_spo2_deinit();
}
GS8 GH3x2xSpo2AlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
goodix_spo2_ret ret = goodix_spo2_init_func(pstFrameInfo->pstFunctionInfo->usSampleRate);
if (GX_ALGO_SPO2_SUCCESS == ret)
{
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("spo2 init error! error code:0x%x\r\n", ret);
}
return chRet;
}
GS8 GH3x2xSpo2AlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)
{
GS8 chRet = GH3X2X_RET_GENERIC_ERROR;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
goodix_spo2_ret ret = goodix_spo2_deinit_func();
if (GX_ALGO_SPO2_SUCCESS == ret)
{
chRet = GH3X2X_RET_OK;
}
else
{
GH3X2X_DEBUG_ALGO_LOG("spo2 deinit error! error code:0x%x\r\n", ret);
}
return chRet;
}
GS8 GH3x2xSpo2AlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)
{
if (0 == pstFrameInfo)
{
return GH3X2X_RET_GENERIC_ERROR;
}
GU8 uchChannelNum = 0;
GS32 ppg_rawdata[3 * CHIP_PPG_CHL_NUM] = {0};
GS8 cur_adj_flg[3 * CHIP_PPG_CHL_NUM] = {0};
GS8 gain_adj_flg[3 * CHIP_PPG_CHL_NUM] = {0};
GS8 enable_flg[3 * CHIP_PPG_CHL_NUM] = {0};
GS32 ch_agc_drv0[3 * CHIP_PPG_CHL_NUM] = {0};
GS32 ch_agc_drv1[3 * CHIP_PPG_CHL_NUM] = {0};
GS8 ch_agc_gain[3 * CHIP_PPG_CHL_NUM] = {0};
goodix_spo2_input_rawdata stRawdata = {0};
goodix_spo2_result stResult = {0};
GS8 emAlgoRet = GH3X2X_RET_OK;
stRawdata.frameid = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));
stRawdata.bit_num = 24;
stRawdata.ppg_rawdata = (int32_t *)ppg_rawdata;
stRawdata.cur_adj_flg = cur_adj_flg;
stRawdata.gain_adj_flg = gain_adj_flg;
stRawdata.enable_flg = enable_flg;
stRawdata.ch_agc_drv0 = (int32_t *)ch_agc_drv0;
stRawdata.ch_agc_drv1 = (int32_t *)ch_agc_drv1;
stRawdata.ch_agc_gain = ch_agc_gain;
stRawdata.acc_x = pstFrameInfo->pusFrameGsensordata[0]; // 46
stRawdata.acc_y = pstFrameInfo->pusFrameGsensordata[1]; // -183
stRawdata.acc_z = pstFrameInfo->pusFrameGsensordata[2]; // 482
stRawdata.wear_on_flag = 1;
/* call algorithm, update result */
for (GU8 uchChMapCnt = 0; uchChMapCnt < CHIP_PPG_CHL_NUM * 3; ++uchChMapCnt)
{
if (g_stSpo2AlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)] < 0xff)
{
GU8 uchRawdataIndex = g_stSpo2AlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)];
stRawdata.ch_agc_drv0[uchChMapCnt] = ((pstFrameInfo->punFrameAgcInfo[uchRawdataIndex] >> 8) & 0xFF);
stRawdata.ch_agc_drv1[uchChMapCnt] = ((pstFrameInfo->punFrameAgcInfo[uchRawdataIndex] >> 16) & 0xFF);
stRawdata.ch_agc_gain[uchChMapCnt] = (pstFrameInfo->punFrameAgcInfo[uchRawdataIndex] & 0xF);
if (((pstFrameInfo->puchFrameLastGain[uchRawdataIndex] != stRawdata.ch_agc_gain[uchChMapCnt]) && \
(pstFrameInfo->puchFrameLastGain[uchRawdataIndex] != GH3X2X_GAIN_VALUE_INVALID)) || \
((pstFrameInfo->punFrameFlag[0]) & 0x01))
{
stRawdata.gain_adj_flg[uchChMapCnt] = 1;
pstFrameInfo->puchFrameLastGain[uchRawdataIndex] = stRawdata.ch_agc_gain[uchChMapCnt];
}
stRawdata.cur_adj_flg[uchChMapCnt] = (((pstFrameInfo->punFrameFlag[0]) >> uchRawdataIndex) & 0x01);
stRawdata.enable_flg[uchChMapCnt] = 1;
stRawdata.ppg_rawdata[uchChMapCnt] = pstFrameInfo->punFrameRawdata[uchRawdataIndex];
uchChannelNum++;
GH3X2X_DEBUG_ALGO_LOG("[%s] ch%d ppg_rawdata = %d,gain_adj_flg = %d,cur_adj_flg = %d\r\n", __FUNCTION__, uchChMapCnt, \
(int)stRawdata.ppg_rawdata[uchChMapCnt], (int)stRawdata.gain_adj_flg[uchChMapCnt], \
(int)stRawdata.cur_adj_flg[uchChMapCnt]);
}
}
stRawdata.ch_num = CHIP_PPG_CHL_NUM;
goodix_spo2_ret ret = goodix_spo2_calc(&stRawdata, &stResult);
// goodix_spo2_essential_info_print(&stRawdata);
if (GX_ALGO_SPO2_SUCCESS == ret || GX_ALGO_SPO2_FRAME_UNCOMPLETE == ret || GX_ALGO_SPO2_WIN_UNCOMPLETE == ret)
{
if (1 == stResult.final_calc_flg)
{
pstFrameInfo->pstAlgoResult->uchUpdateFlag = (GU8)stResult.final_calc_flg;
pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)(GH3x2x_Round((float)stResult.final_spo2 / 10000));
pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stResult.final_r_val;
pstFrameInfo->pstAlgoResult->snResult[2] = (GS32)stResult.final_confi_coeff;
pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)stResult.final_valid_level;
pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)stResult.final_hb_mean;
pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)stResult.final_invalidFlg;
pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;
pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);
GH3X2X_Spo2AlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);
GH3X2X_DEBUG_ALGO_LOG("[%s] final_spo2:%d, r = %d, final_valid_level:%d\r\n", __FUNCTION__, pstFrameInfo->pstAlgoResult->snResult[0], \
pstFrameInfo->pstAlgoResult->snResult[1], pstFrameInfo->pstAlgoResult->snResult[3]);
}
}
else
{
emAlgoRet = GH3X2X_RET_RESOURCE_ERROR;
GH3X2X_DEBUG_ALGO_LOG("GH3x2xSpo2AlgoExe error! error code = 0x%x\r\n", ret);
GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");
}
return (GS8)emAlgoRet;
}
#endif

View File

@ -0,0 +1,25 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_version.h
*
* @brief gh3x2x algo call demo code version
*
* @version ref gh3x2x_demo_algo_call_version.h
*
*/
#ifndef _GH3X2X_DEMO_ALGO_CALL_VERSION_H_
#define _GH3X2X_DEMO_ALGO_CALL_VERSION_H_
#define GOODIX_DEMO_MAJOR_VERSION_NUMBER 0 /**< major version number */
#define GOODIX_DEMO_MINOR_VERSION_NUMBER 5 /**< minor version number */
#define GOODIX_TO_STRING(x) #x /**< number to char */
#define GOODIX_STR(x) GOODIX_TO_STRING(x) /**< number to char */
/// makeup version string
#define GOODIX_ALGO_CALL_VERSION_STRING "Goodix_Algocall_"\
"v"GOODIX_STR(GOODIX_DEMO_MAJOR_VERSION_NUMBER)\
"."GOODIX_STR(GOODIX_DEMO_MINOR_VERSION_NUMBER)
#endif

View File

@ -0,0 +1,648 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_drv_algorithm_calc.c
*
* @brief gh3x2x algorithm calc functions
*
* @version ref gh3x2x_drv_version.h
*
*/
#include <stdio.h>
#include "gh3x2x_demo_algorithm_calc.h"
#include "gh3x2x_demo_algo_config.h"
#include "goodix_algo.h"
#include "goodix_mem.h"
#include "goodix_type.h"
#include "goodix_hba.h"
#include "goodix_hrv.h"
#include "goodix_spo2.h"
#include "goodix_nadt.h"
#include "goodix_algo_bt.h"
#if (__GOODIX_ALGO_CALL_MODE__)
/* hb algorithm */
#if (__USE_GOODIX_HR_ALGORITHM__)
GS32 g_unHrParamsArr[GOODIX_HR_PARAMS_NUM_MAX] = {
0, // 测试模式
0, // 运动场景
0, // 预留未使用
20, // 最晚出值时间
8, // 最早出值时间
0, // 预留未使用
0, // 预留未使用
0, // 预留未使用
0, // 预留未使用
0 // 预留未使用
};
/// hbd rawdata channel map
STAlgoChnlMap g_stHbaAlgoChnlMap = {0};
#endif
/* hrv algorithm */
#if (__USE_GOODIX_HRV_ALGORITHM__)
GS32 g_nHrvParamsArr[GOODIX_HRV_PARAMS_NUM_MAX] = {
0, // 需要分辨率为1ms的输出
200000, 100000, 300000, 300000 // ACC相关阈值
};
#endif
/* spo2 algorithm */
#if (__USE_GOODIX_SPO2_ALGORITHM__)
#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))
GS32 g_nSpo2ParamssArr[GOODIX_SPO2_PARAMS_NUM_MAX] = {
0, 0, -134717, -115284, 1097668, // 校准参数
0, // 心率使能标志
0, // 佩戴模式
30, 15, 4, 3, 90, // ACC运动判断阈值
1, 65, // 备用
30, 10, 90, // PPG参数
253, // 质量评估模块使能开关
95, // 低氧阈值
10, 25, 3, 6, 10, 5, // 出值策略
3 // 出值相关模块使能开关
};
#elif ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))
GS32 g_nSpo2ParamssArr[GOODIX_SPO2_PARAMS_NUM_MAX] = {
0, 0, 0, -239878, 1111827, // 校准参数
1, // 心率使能标志
0, // 佩戴模式
50, 25, 3, 3, 90, // ACC运动判断阈值
0, 160, // 备用
35, 25, 85, // PPG参数
0xFD, // 质量评估模块使能开关
95, // 低氧阈值
12, 18, 2, 7, 10, 5, // 出值策略
3 // 出值相关模块使能开关
};
#endif
/// spo2 rawdata channel map
STAlgoChnlMap g_stSpo2AlgoChnlMap = {0};
#endif
/* ecg algorithm */
#if (__USE_GOODIX_ECG_ALGORITHM__)
GS32 g_nEcgParamsArr[GOODIX_ECG_PARAMS_NUM_MAX] = {
0, // 采样率
1, // 算法有效通道数
1, // QRS检测标志
0, // ECG耦合方式
0 // 芯片类型
};
/// ecg frame data cnt
GU32 g_unEcgFrameCnt = 0;
GU8 g_uchClassificationFlag;
GU8 g_unEcgTimeSeconds = 0;
#endif
/* bt algorithm */
#if (__USE_GOODIX_BT_ALGORITHM__)
GS32 g_nBtParamsArr[GOODIX_BT_PARAMS_NUM_MAX] = {0};
#endif
/* af algorithm */
#if (__USE_GOODIX_AF_ALGORITHM__)
GS32 g_nAfParamsArr[GOODIX_AF_PARAMS_NUM_MAX] = {45, 0};
#endif
/// new data flag
GU8 g_uchNewDataFlag = 0;
GU8 g_uchGh3x2xSleepFlag = 0;
//sensor enable
GU8 g_uchAlgoGsensorEnable = 0;
GU8 g_uchAlgoCapEnable = 0;
GU8 g_uchAlgoTempEnable = 0;
GS32 GH3x2x_Round(GF32 fValue)
{
GS32 nRet = 0;
float fEpsinon = 0.00001;
if((fValue >= -fEpsinon)&&(fValue <= fEpsinon))
{
nRet = 0;
}
else if(fValue < -fEpsinon)
{
nRet = (GS32)(fValue - 0.5f);
}
else if(fValue > fEpsinon)
{
nRet = (GS32)(fValue + 0.5f);
}
return nRet;
}
GU8 GH3x2x_BitCount(GU32 n)
{
GU8 c =0 ; // 计数器
while (n >0)
{
if((n &1) ==1) // 当前位是1
++c ; // 计数器加1
n >>=1 ; // 移位
}
return c ;
}
void GH3x2xSleepFlagSet(GU8 uchSleepFlag)
{
g_uchGh3x2xSleepFlag = uchSleepFlag;
}
GU8 GH3x2xSleepFlagGet(void)
{
return g_uchGh3x2xSleepFlag;
}
void GH3X2X_AlgoSensorEnable(GU8 uchAlgoGsensorEnable,
GU8 uchAlgoCapEnable,
GU8 uchAlgoTempEnable)
{
g_uchAlgoGsensorEnable = uchAlgoGsensorEnable;
g_uchAlgoCapEnable = uchAlgoCapEnable;
g_uchAlgoTempEnable = uchAlgoTempEnable;
}
/**
* @fn GS8 GH3X2X_BTAlgorithmRTConfig(GS32 nOutputTime)
*
* @brief BT algorithm RT table
*
* @attention None
*
* @param[in] nRTtable
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_ALGO_NO_SUPPORTED return algorithm no supported error
*/
GS8 GH3X2X_BTAlgorithmRTConfig(GU16 *nRTtable)
{
#if (__USE_GOODIX_BT_ALGORITHM__)
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
GH3X2X_Memcpy(g_nBtParamsArr, nRTtable, GOODIX_BT_PARAMS_NUM_MAX * sizeof(GU16));
return GH3X2X_RET_OK;
#else
GH3X2X_DEBUG_ALGO_LOG("BT algorithm no supported error!\r\n");
return GH3X2X_RET_ALGO_NO_SUPPORTED;
#endif
}
/**
* @fn void GH3X2X_SetNewDataFlag(EMChannelMapId emFuncId, GU8 uchFlag)
*
* @brief Set new sampling data flag
*
* @attention None
*
* @param[in] emFuncId function id
* @param[in] uchFlag new data or not
* @param[out] None
*
* @return None
*/
void GH3X2X_SetNewDataFlag(GU8 emFuncId, GU8 uchFlag)
{
if (GH3X2X_IS_NOT_NEW_RAWDATA == uchFlag)
{
GH3X2X_VAL_CLEAR_LEFT_BIT(g_uchNewDataFlag, emFuncId);
}
else
{
GH3X2X_VAL_SET_BIT(g_uchNewDataFlag, GH3X2X_GET_LEFT_SHIFT_VAL(emFuncId));
}
}
/**
* @fn GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario)
*
* @brief Hb algorithm scenario config
*
* @attention None
*
* @param[in] uchScenario @ref EMHbaScenesConfigType
* others: fixed 0(default) and return GH3X2X_RET_PARAMETER_ERROR
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_PARAMETER_ERROR return paramters error
* @retval #GH3X2X_RET_ALGO_NO_SUPPORTED return algorithm no supported error
*/
GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario)
{
#if (__USE_GOODIX_HR_ALGORITHM__)
GS8 chRet = GH3X2X_RET_OK;
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
if (uchScenario > GH3X2X_HBA_SCENARIO_CONFIG_MAX_VAL)
{
GH3X2X_DEBUG_ALGO_LOG("hb algorithm scenario param error!\r\n");
g_unHrParamsArr[1] = HBA_SCENES_DEFAULT;
chRet = GH3X2X_RET_PARAMETER_ERROR;
}
else
{
g_unHrParamsArr[1] = uchScenario;
}
#else
GS8 chRet = GH3X2X_RET_ALGO_NO_SUPPORTED;
GH3X2X_DEBUG_ALGO_LOG("hba algorithm no supported error!\r\n");
#endif
return chRet;
}
/**
* @fn GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nOutputTime)
*
* @brief Hb algorithm output time config
*
* @attention None
*
* @param[in] nOutputTime valid 7~GS32_MAX
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_ALGO_NO_SUPPORTED return algorithm no supported error
*/
GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nLatestOutputTime, GS32 nEarliestOutputTime)
{
#if (__USE_GOODIX_HR_ALGORITHM__)
GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);
g_unHrParamsArr[3] = nLatestOutputTime;
g_unHrParamsArr[4] = nEarliestOutputTime;
return GH3X2X_RET_OK;
#else
GH3X2X_DEBUG_ALGO_LOG("hba algorithm no supported error!\r\n");
return GH3X2X_RET_ALGO_NO_SUPPORTED;
#endif
}
GU16 GH3X2X_ReadSpo2CorrectionFactor(GU16 usVirtualRegAddr)
{
#if 0
GU16 usVirtualRegData = 0;
GU16 usValIndex = 0;
if(usVirtualRegAddr >= GH3X2X_VSPO2_CH0_CORFAC0_L_REG_ADDR && usVirtualRegAddr <= GH3X2X_VSPO2_CH0_CORFAC2_H_REG_ADDR)
{
usValIndex = (usVirtualRegAddr - GH3X2X_VSPO2_CH0_CORFAC0_L_REG_ADDR) / GH3X2X_REG_ADDR_SIZE;
}
else if(usVirtualRegAddr >= GH3X2X_VSPO2_CH0_CORFAC3_L_REG_ADDR && usVirtualRegAddr <= GH3X2X_VSPO2_CH3_CORFAC4_H_REG_ADDR)
{
usValIndex = (usVirtualRegAddr - GH3X2X_VSPO2_CH0_CORFAC3_L_REG_ADDR) / GH3X2X_REG_ADDR_SIZE + 6;
}
else
{
return usVirtualRegData;
}
if ((usValIndex % GH3X2X_REG_ADDR_SIZE) == 0) // low word
{
usVirtualRegData = GH3X2X_GET_LOW_WORD_FROM_DWORD(
g_nSpo2ParamssArr[usValIndex / (SP02_CORR_FAC_NUM * 2)][(usValIndex % (SP02_CORR_FAC_NUM * 2)) / GH3X2X_REG_ADDR_SIZE]);
}
else // high word
{
usVirtualRegData = GH3X2X_GET_HIGH_WORD_FROM_DWORD(
g_nSpo2ParamssArr[usValIndex / (SP02_CORR_FAC_NUM * 2)][(usValIndex % (SP02_CORR_FAC_NUM * 2)) / GH3X2X_REG_ADDR_SIZE]);
}
return usVirtualRegData;
#else
return 0;
#endif
}
/**
* @fn void GH3X2X_AlgoChnlMapInit(STAlgoChnlMap stAlgoChnlMap)
*
* @brief Init algo channel group struct
*
* @attention
*
*
* @return None
*/
void GH3X2X_AlgoChnlMapInit(STAlgoChnlMap *pstAlgoChnlMap)
{
(*pstAlgoChnlMap).uchFlag = 0;
(*pstAlgoChnlMap).uchNum = 0;
for (GU32 num = 0 ; num < ALGO_CHNL_NUM ; num ++)
{
(*pstAlgoChnlMap).uchAlgoChnlMap[num] = 0xff;
}
}
/**
* @fn void GH3X2X_HbaAlgoChnlMapDefultSet(void)
*
* @brief Set algo channel group Defult value
*
* @attention
*
*
* @return None
*/
void GH3X2X_HbaAlgoChnlMapDefultSet(void)
{
#if (__USE_GOODIX_HR_ALGORITHM__)
if (!g_stHbaAlgoChnlMap.uchFlag)
{
GH3X2X_AlgoChnlMapInit(&g_stHbaAlgoChnlMap);
g_stHbaAlgoChnlMap.uchNum = __HR_ALGORITHM_SUPPORT_CHNL_NUM__;
for (GU8 cnt = 0; cnt < __HR_ALGORITHM_SUPPORT_CHNL_NUM__; cnt++)
{
g_stHbaAlgoChnlMap.uchAlgoChnlMap[ALGO_GREEN_CHNL_POS + cnt] = cnt;
}
}
#endif
}
/**
* @fn void GH3X2X_HrvAlgoChnlMapDefultSet(void)
*
* @brief Set algo channel group Defult value
*
* @attention
*
*
* @return None
*/
void GH3X2X_HrvAlgoChnlMapDefultSet(void)
{
#if (0)
if (!g_stHrvAlgoChnlMap.uchFlag)
{
GH3X2X_AlgoChnlMapInit(&g_stHrvAlgoChnlMap);
g_stHrvAlgoChnlMap.uchNum = 1;
g_stHrvAlgoChnlMap.uchAlgoChnlMap[ALGO_GREEN_CHNL_POS + 0] = 0;
}
#endif
}
/**
* @fn void GH3X2X_Spo2AlgoChnlMapDefultSet(void)
*
* @brief Set algo channel group Defult value
*
* @attention
*
*
* @return None
*/
void GH3X2X_Spo2AlgoChnlMapDefultSet(void)
{
#if (__USE_GOODIX_SPO2_ALGORITHM__)
if (!g_stSpo2AlgoChnlMap.uchFlag)
{
GH3X2X_AlgoChnlMapInit(&g_stSpo2AlgoChnlMap);
g_stSpo2AlgoChnlMap.uchNum = 1;
g_stSpo2AlgoChnlMap.uchAlgoChnlMap[ALGO_RED_CHNL_POS + 0] = 0;
g_stSpo2AlgoChnlMap.uchAlgoChnlMap[ALGO_IR_CHNL_POS + 0] = __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__;
}
#endif
}
void GH3X2X_BpAlgoChnlMapDefultSet(void)
{
#if (__USE_GOODIX_BP_ALGORITHM__)
if (!g_stBpAlgoChnlMap.uchFlag)
{
GH3X2X_AlgoChnlMapInit(&g_stBpAlgoChnlMap);
g_stBpAlgoChnlMap.uchNum = 1;
g_stBpAlgoChnlMap.uchAlgoChnlMap[ALGO_GREEN_CHNL_POS + 0] = 1;
g_stBpAlgoChnlMap.uchEcgAlgoChnlMap = 0;
}
#endif
}
void GH3X2X_WriteAlgParametersWithVirtualReg(GU8 uchParasIndex, GU32 unFunctionID, GS32* nAlgParametersBuffer, GU8 nBufferMaxLen, GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
GU16 usValIndex = (usVirtualRegAddr - (unFunctionID * GH3X2X_VREG_FUNCTION_OFFSET + GH3X2X_ADT_ALG_CFG_ADDR)) / GH3X2X_REG_ADDR_SIZE;
if ((GS16)((GS16)usValIndex / (GS16)GH3X2X_REG_ADDR_SIZE - (GS16)uchParasIndex < 0) ||\
(usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex >= nBufferMaxLen))
{
return;
}
if ((usValIndex % GH3X2X_REG_ADDR_SIZE) != 0) // high word
{
nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex] = \
GH3X2X_MAKEUP_DWORD2(usVirtualRegValue, GH3X2X_GET_LOW_WORD_FROM_DWORD(nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex]));
}
else // low word
{
nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex] = \
GH3X2X_MAKEUP_DWORD2(GH3X2X_GET_HIGH_WORD_FROM_DWORD(nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex]), usVirtualRegValue);
}
}
void GH3X2X_WriteAlgChnlMapWithVirtualReg(GU32 unFunctionID, STAlgoChnlMap* pstAlgChnlMap, GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
GU16 usVirtualRegAddrOffset = usVirtualRegAddr - (unFunctionID * GH3X2X_VREG_FUNCTION_OFFSET + GH3X2X_ADT_ALG_CFG_ADDR);
switch (usVirtualRegAddrOffset)
{
case GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET:
GH3X2X_AlgoChnlMapInit(pstAlgChnlMap);
pstAlgChnlMap->uchNum = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);
if (pstAlgChnlMap->uchNum)
{
pstAlgChnlMap->uchFlag = 1;
}
break;
case GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET + GH3X2X_REG_ADDR_SIZE:
pstAlgChnlMap->uchEcgAlgoChnlMap = (GU8)(usVirtualRegValue & 0x000000FF);
break;
default:
pstAlgChnlMap->uchAlgoChnlMap[usVirtualRegAddrOffset - GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET - 2 * GH3X2X_REG_ADDR_SIZE]\
= GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);
pstAlgChnlMap->uchAlgoChnlMap[usVirtualRegAddrOffset - GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET - 2 * GH3X2X_REG_ADDR_SIZE + 1]\
= GH3X2X_GET_HIGH_BYTE_FROM_WORD(usVirtualRegValue);
}
}
void GH3X2X_WriteHrAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_HR_ALGORITHM__) // hr
if (usVirtualRegAddr < GH3X2X_HR_ALGO_CHNL_NUM_ADDR)
{
if(!g_stHbaAlgoChnlMap.uchFlag)
{
GH3X2X_AlgoChnlMapInit(&g_stHbaAlgoChnlMap);
}
//GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_HR, (GS32*)&g_unHrParamsArr, GOODIX_HR_PARAMS_NUM_MAX, usVirtualRegAddr,usVirtualRegValue);
//GH3X2X_DEBUG_ALGO_LOG("[%s]:Hba Scenario = %d\r\n", __FUNCTION__, g_unHrParamsArr[1]);
if(HBA_SCENES_SLEEP == g_unHrParamsArr[1])
{
GH3x2xSleepFlagSet(1);
}
}
else
{
GH3X2X_WriteAlgChnlMapWithVirtualReg(GH3X2X_FUNC_OFFSET_HR, &g_stHbaAlgoChnlMap, usVirtualRegAddr, usVirtualRegValue);
}
#endif
}
void GH3X2X_WriteHrvAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_HRV_ALGORITHM__) // hrv
GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_HRV, (GS32*)g_nHrvParamsArr, GOODIX_HRV_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);
#endif
}
void GH3X2X_WriteSpo2AlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_SPO2_ALGORITHM__) // spo2
if (usVirtualRegAddr < GH3X2X_SPO2_ALGO_CHNL_NUM_ADDR)
{
GH3X2X_AlgoChnlMapInit(&g_stSpo2AlgoChnlMap);
//GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_SPO2, (GS32*)g_nSpo2ParamssArr, GOODIX_SPO2_PARAMS_NUM_MAX, usVirtualRegAddr,usVirtualRegValue);
}
else
{
GH3X2X_WriteAlgChnlMapWithVirtualReg(GH3X2X_FUNC_OFFSET_SPO2, &g_stSpo2AlgoChnlMap, usVirtualRegAddr, usVirtualRegValue);
}
#endif
}
void GH3X2X_WriteEcgAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_ECG_ALGORITHM__) // ecg
GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_ECG, (GS32*)g_nEcgParamsArr, GOODIX_ECG_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);
#endif
}
void GH3X2X_WriteBtAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_BT_ALGORITHM__) // bt
GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_BT, (GS32*)g_nBtParamsArr, GOODIX_BT_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);
#endif
}
void GH3X2X_WriteAfAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_AF_ALGORITHM__) // af
GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_AF, (GS32*)&g_nAfParamsArr, GOODIX_AF_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);
#endif
}
void GH3X2X_WriteBpAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
#if (__USE_GOODIX_BP_ALGORITHM__) // fpbp
#endif
}
/**
* @fn GU16 GH3X2X_ReadAlgorithmConfigWithVirtualReg(GU16 usVirtualRegAddr)
*
* @brief Read algorithm param config with virtual reg
*
* @attention Virtual reg addr has del control bits, so reg addr is [0:11] valid.
*
* @param[in] usVirtualRegAddr virtual reg addr
* @param[out] None
*
* @return virtual reg val
*/
GU16 GH3X2X_ReadAlgorithmConfigWithVirtualReg(GU16 usVirtualRegAddr)
{
GU16 usVirtualRegData = 0;
return usVirtualRegData;
}
void GH3X2X_WriteAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)
{
if (usVirtualRegAddr < GH3X2X_REG_IS_VIRTUAL0X3_BIT)
{
return;
}
GU32 unFunctionID = (usVirtualRegAddr - GH3X2X_REG_IS_VIRTUAL0X3_BIT) / GH3X2X_VREG_FUNCTION_OFFSET;
if (usVirtualRegAddr >= GH3X2X_ADT_ALG_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * unFunctionID &&\
usVirtualRegAddr < GH3X2X_ADT_DRV_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * (unFunctionID + 1))
{
switch (unFunctionID)
{
case GH3X2X_FUNC_OFFSET_HR:
GH3X2X_WriteHrAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
case GH3X2X_FUNC_OFFSET_HRV:
GH3X2X_WriteHrvAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
case GH3X2X_FUNC_OFFSET_FPBP:
case GH3X2X_FUNC_OFFSET_PWA:
//GH3X2X_WriteBpAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
case GH3X2X_FUNC_OFFSET_SPO2:
GH3X2X_WriteSpo2AlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
case GH3X2X_FUNC_OFFSET_ECG:
GH3X2X_WriteEcgAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
case GH3X2X_FUNC_OFFSET_BT:
GH3X2X_WriteBtAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
case GH3X2X_FUNC_OFFSET_AF:
GH3X2X_WriteAfAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);
break;
default:
break;
}
}
}
void GH3X2X_LoadGoodixAlgoRegConfigArr(const STGh3x2xInitConfig *pstGoodixAlgoCfgListArr)
{
const STGh3x2xReg *pstRegConfigArr = pstGoodixAlgoCfgListArr->pstRegConfigArr;
GU16 usRegConfigLen = pstGoodixAlgoCfgListArr->usConfigArrLen;
GU16 usIndex = 0;
if ((pstRegConfigArr != GH3X2X_PTR_NULL) && (usRegConfigLen != 0))
{
for (usIndex = 0; usIndex < usRegConfigLen; usIndex++) // write GH3X2X reg.
{
GH3X2X_WriteAlgConfigWithVirtualReg(pstRegConfigArr[usIndex].usRegAddr, pstRegConfigArr[usIndex].usRegData);
}
}
}
#endif
/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/

View File

@ -0,0 +1,131 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_algo_config.h
*
* @brief gh3x2x algo config
*
* @version ref gh3x2x_demo_algo_config.h
*
*/
#ifndef _GH3X2X_DEMO_ALGO_CONFIG_H_
#define _GH3X2X_DEMO_ALGO_CONFIG_H_
#ifdef GOODIX_DEMO_PLATFORM
//#include "Goodix_Platform_config.h"
#endif
#define GH3X2X_ALGO_FUNCTION_GROUP_0 (GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_SPO2|GH3X2X_FUNCTION_HRV|GH3X2X_FUNCTION_SOFT_ADT_GREEN)
#define GH3X2X_ALGO_FUNCTION_GROUP_1 (GH3X2X_FUNCTION_SPO2)
#define GH3X2X_ALGO_FUNCTION_GROUP_2 (GH3X2X_FUNCTION_ECG)
#define GH3X2X_ALGO_FUNCTION_GROUP_3 (GH3X2X_FUNCTION_HRV)
#define GH3X2X_ALGO_FUNCTION_GROUP_4 (GH3X2X_NO_FUNCTION)
#define GOODIX_ALGO_BASIC (1)
#define GOODIX_ALGO_MEDIUM (2)
#define GOODIX_ALGO_PREMIUM (3)
#define GOODIX_ALGO_EXCLUSIVE (4)
#define GOODIX_ECG_ALGO_500FS_QRS_ENABLE (1)
#define GOODIX_ECG_ALGO_500FS_QRS_DISABLE (2)
#define GOODIX_ECG_ALGO_250FS_QRS_ENABLE (3)
#define GOODIX_ECG_ALGO_250FS_QRS_DISABLE (4)
#ifndef __GOODIX_HR_ALGO_VERISON__
#define __GOODIX_HR_ALGO_VERISON__ (GOODIX_ALGO_EXCLUSIVE)
#endif
#ifndef __GOODIX_SPO2_ALGO_VERISON__
#define __GOODIX_SPO2_ALGO_VERISON__ (GOODIX_ALGO_EXCLUSIVE)
#endif
#ifndef __GOODIX_ECG_ALGO_CONFIG__
#define __GOODIX_ECG_ALGO_CONFIG__ (GOODIX_ECG_ALGO_250FS_QRS_ENABLE)
#endif
#if ((__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))
#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))
#error "HR algo BASIC\MEDIUM version should adapt to SPO2 BASIC\MEDIUM version"
#endif
#endif
#if ((__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))
#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))
#error "HR algo PREMIUM\EXCLUSIVE version should adapt to SPO2 PREMIUM\EXCLUSIVE version"
#endif
#endif
/* 0: global buffer for goodix algorithm mem pool
* 1: user dynamic buffer for goodix algorithm mem pool */
#define __USER_DYNAMIC_ALGO_MEM_EN__ (0)
#if __USER_DYNAMIC_ALGO_MEM_EN__
#define GH3X2X_ALGORITHMS_MEMORY_SIZE_USERSET (0)
#endif
/* function algo enable config */
#define __USE_GOODIX_ADT_ALGORITHM__ (0)
#define __USE_GOODIX_HR_ALGORITHM__ (1)
#define __USE_GOODIX_HRV_ALGORITHM__ (1)
#define __USE_GOODIX_HSM_ALGORITHM__ (0)
#define __USE_GOODIX_SPO2_ALGORITHM__ (1)
#define __USE_GOODIX_ECG_ALGORITHM__ (0)
#define __USE_GOODIX_BT_ALGORITHM__ (0)
#define __USE_GOODIX_RESP_ALGORITHM__ (0)
#define __USE_GOODIX_AF_ALGORITHM__ (0)
#define __USE_GOODIX_BP_ALGORITHM__ (0)
#define __USE_GOODIX_SOFT_ADT_ALGORITHM__ (1)
/* algorithm log */
#define __GH3X2X_ALGO_LOG_LV_0__ (0) /** no log **/
#define __GH3X2X_ALGO_LOG_LV_1__ (1) /** include EXAMPLE LOG information **/
#define __GH3X2X_ALGO_LOG_LV_2__ (2) /** include EXAMPLE LOG debug **/
#define __ALGO_LOG_CONFIG__ (__GH3X2X_ALGO_LOG_LV_1__)
/* BT NTC Drv Convert config*/
#if __USE_GOODIX_BT_ALGORITHM__
#define __USE_GOODIX_DRV_NTC_Convert (1)
#endif
/* algorithm config max number */
#define __GOODIX_ALGO_CFG_LIST_MAX_NUM__ (1)
/*algorithm output value process strategy config*/
#define __GH3X2X_HR_OUTPUT_VALUE_STRATEGY_EN__ (0)
/* algoritm channel nunber config*/
#define __HR_ALGORITHM_SUPPORT_CHNL_NUM__ (2) /* range 1~4 */
#define __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ (1) /* range 1-4 */
/* algo and drv interactivity*/
#define __GH_MSG_WTIH_DRV_LAYER_EN__ (0)
#define __GH_SEPARATE_ALGO_EN__ (0)
#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)
#define __SOFT_ADT_IR_DETECT_TIMEOUT__ (30) /** (recomended value = 30 seconds) ir detect timeout **/
#endif
#define GH_SEND_MSG_WEAR_EVENT(event) //add your code to send message to drv layer
/*********************************** DO NOT MODIFY FOLLOWING CODE *******************************/
#if (\
__USE_GOODIX_HR_ALGORITHM__ ||\
__USE_GOODIX_HRV_ALGORITHM__ ||\
__USE_GOODIX_HSM_ALGORITHM__ ||\
__USE_GOODIX_SPO2_ALGORITHM__ ||\
__USE_GOODIX_ECG_ALGORITHM__ ||\
__USE_GOODIX_BT_ALGORITHM__ ||\
__USE_GOODIX_RESP_ALGORITHM__ ||\
__USE_GOODIX_AF_ALGORITHM__ ||\
__USE_GOODIX_BP_ALGORITHM__ ||\
__USE_GOODIX_SOFT_ADT_ALGORITHM__\
)
#define __GOODIX_ALGO_CALL_MODE__ (1)
#else
#define __GOODIX_ALGO_CALL_MODE__ (0)
#endif
#endif /* _GH3X2X_DEMO_ALGO_CALL_H_ */
/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/

View File

@ -0,0 +1,817 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh2x2x_demo_algo_frame.c
*
* @brief gh3x2x algo frame info
*
* @author Gooidx Iot Team
*
*/
/* includes */
#include "gh3x2x_demo_algo_config.h"
#include "gh_demo_config.h"
#include "gh_drv.h"
#if __GH_SEPARATE_ALGO_EN__
#if __FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
#if __USE_GOODIX_HR_ALGORITHM__
GU32 g_pun_HR_FrameIncompleteRawdata[GH3X2X_HR_CHNL_NUM];
GU32 g_un_HR_FrameIncompleteChnlMapBit;
GU8 g_puch_HR_FrameLastGain[GH3X2X_HR_CHNL_NUM];
GU32 g_un_HR_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HR;
#endif
#if __USE_GOODIX_HRV_ALGORITHM__
GU32 g_pun_HRV_FrameIncompleteRawdata[GH3X2X_HRV_CHNL_NUM];
GU32 g_un_HRV_FrameIncompleteChnlMapBit;
GU8 g_puch_HRV_FrameLastGain[GH3X2X_HRV_CHNL_NUM];
GU32 g_un_HRV_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HRV;
#endif
#if __USE_GOODIX_HSM_ALGORITHM__
GU32 g_pun_HSM_FrameIncompleteRawdata[GH3X2X_HSM_CHNL_NUM];
GU32 g_un_HSM_FrameIncompleteChnlMapBit;
GU8 g_puch_HSM_FrameLastGain[GH3X2X_HSM_CHNL_NUM];
GU32 g_un_HSM_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HSM;
#endif
#if __USE_GOODIX_SPO2_ALGORITHM__
GU32 g_pun_SPO2_FrameIncompleteRawdata[GH3X2X_SPO2_CHNL_NUM];
GU32 g_un_SPO2_FrameIncompleteChnlMapBit;
GU8 g_puch_SPO2_FrameLastGain[GH3X2X_SPO2_CHNL_NUM];
GU32 g_un_SPO2_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_SPO2;
#endif
#if __USE_GOODIX_ECG_ALGORITHM__
GU32 g_pun_ECG_FrameIncompleteRawdata[GH3X2X_ECG_CHNL_NUM];
GU32 g_un_ECG_FrameIncompleteChnlMapBit;
GU8 g_puch_ECG_FrameLastGain[GH3X2X_ECG_CHNL_NUM];
GU32 g_un_ECG_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_ECG;
#endif
#if 0
GU32 g_pun_PWTT_FrameIncompleteRawdata[GH3X2X_PWTT_CHNL_NUM];
GU32 g_un_PWTT_FrameIncompleteChnlMapBit;
GU8 g_puch_PWTT_FrameLastGain[GH3X2X_PWTT_CHNL_NUM];
GU32 g_un_PWTT_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_PWTT;
#endif
#if __USE_GOODIX_BT_ALGORITHM__
GU32 g_pun_BT_FrameIncompleteRawdata[GH3X2X_BT_CHNL_NUM];
GU32 g_un_BT_FrameIncompleteChnlMapBit;
GU8 g_puch_BT_FrameLastGain[GH3X2X_BT_CHNL_NUM];
GU32 g_un_BT_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_BT;
#endif
#if __USE_GOODIX_RESP_ALGORITHM__
GU32 g_pun_RESP_FrameIncompleteRawdata[GH3X2X_RESP_CHNL_NUM];
GU32 g_un_RESP_FrameIncompleteChnlMapBit;
GU8 g_puch_RESP_FrameLastGain[GH3X2X_RESP_CHNL_NUM];
GU32 g_un_RESP_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_RESP;
#endif
#if __USE_GOODIX_AF_ALGORITHM__
GU32 g_pun_AF_FrameIncompleteRawdata[GH3X2X_AF_CHNL_NUM];
GU32 g_un_AF_FrameIncompleteChnlMapBit;
GU8 g_puch_AF_FrameLastGain[GH3X2X_AF_CHNL_NUM];
GU32 g_un_AF_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_AF;
#endif
#if __USE_GOODIX_BP_ALGORITHM__
GU32 g_pun_BP_FrameIncompleteRawdata[GH3X2X_BP_CHNL_NUM];
GU32 g_un_BP_FrameIncompleteChnlMapBit;
GU8 g_puch_BP_FrameLastGain[GH3X2X_BP_CHNL_NUM];
GU32 g_un_BP_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_BP;
#endif
#if 0
GU32 g_pun_TEST1_FrameIncompleteRawdata[GH3X2X_TEST_CHNL_NUM];
GU32 g_un_TEST1_FrameIncompleteChnlMapBit;
GU8 g_puch_TEST1_FrameLastGain[GH3X2X_TEST_CHNL_NUM];
GU32 g_un_TEST1_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_TEST1;
GU32 g_pun_TEST2_FrameIncompleteRawdata[GH3X2X_TEST_CHNL_NUM];
GU32 g_un_TEST2_FrameIncompleteChnlMapBit;
GU8 g_puch_TEST2_FrameLastGain[GH3X2X_TEST_CHNL_NUM];
GU32 g_un_TEST2_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_TEST2;
#endif
#else
GU32 g_pun_MAIN_FUNC_FrameIncompleteRawdata[GH3X2X_MAIN_FUNC_CHNL_NUM];
GU32 g_un_MAIN_FUNC_FrameIncompleteChnlMapBit;
GU8 g_puch_MAIN_FUNC_FrameLastGain[GH3X2X_MAIN_FUNC_CHNL_NUM];
GU32 g_un_MAIN_FUNC_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_MAIN_FUNC;
#endif
#if __USE_GOODIX_ADT_ALGORITHM__
GU32 g_pun_ADT_FrameIncompleteRawdata[GH3X2X_ADT_CHNL_NUM];
GU32 g_un_ADT_FrameIncompleteChnlMapBit;
GU8 g_puch_ADT_FrameLastGain[GH3X2X_ADT_CHNL_NUM];
GU32 g_un_ADT_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_ADT;
#endif
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
GU32 g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata[GH3X2X_SOFT_ADT_CHNL_NUM];
GU32 g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit;
GU8 g_puch_SOFT_ADT_GREEN_FrameLastGain[GH3X2X_SOFT_ADT_CHNL_NUM];
GU32 g_un_SOFT_ADT_GREEN_TimeStamp;
STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN;
#endif
#if __USE_GOODIX_HR_ALGORITHM__
GU8 g_pch_HR_ChnlMap[GH3X2X_HR_CHNL_NUM];
STGh3x2xFunctionInfo g_st_HR_FuncitonInfo;
STGh3x2xAlgoResult g_st_HR_AlgoRecordResult;
#endif
#if __USE_GOODIX_HRV_ALGORITHM__
GU8 g_pch_HRV_ChnlMap[GH3X2X_HRV_CHNL_NUM];
STGh3x2xFunctionInfo g_st_HRV_FuncitonInfo;
STGh3x2xAlgoResult g_st_HRV_AlgoRecordResult;
#endif
#if __USE_GOODIX_HSM_ALGORITHM__
GU8 g_pch_HSM_ChnlMap[GH3X2X_HSM_CHNL_NUM];
STGh3x2xFunctionInfo g_st_HSM_FuncitonInfo;
#endif
#if __USE_GOODIX_SPO2_ALGORITHM__
GU8 g_pch_SPO2_ChnlMap[GH3X2X_SPO2_CHNL_NUM];
STGh3x2xFunctionInfo g_st_SPO2_FuncitonInfo;
STGh3x2xAlgoResult g_st_SPO2_AlgoRecordResult;
#endif
#if __USE_GOODIX_ECG_ALGORITHM__
GU8 g_pch_ECG_ChnlMap[GH3X2X_ECG_CHNL_NUM];
STGh3x2xFunctionInfo g_st_ECG_FuncitonInfo;
#endif
#if 0
GU8 g_pch_PWTT_ChnlMap[GH3X2X_PWTT_CHNL_NUM];
STGh3x2xFunctionInfo g_st_PWTT_FuncitonInfo;
#endif
#if __USE_GOODIX_BT_ALGORITHM__
GU8 g_pch_BT_ChnlMap[GH3X2X_BT_CHNL_NUM];
STGh3x2xFunctionInfo g_st_BT_FuncitonInfo;
#endif
#if __USE_GOODIX_RESP_ALGORITHM__
GU8 g_pch_RESP_ChnlMap[GH3X2X_RESP_CHNL_NUM];
STGh3x2xFunctionInfo g_st_RESP_FuncitonInfo;
#endif
#if __USE_GOODIX_AF_ALGORITHM__
GU8 g_pch_AF_ChnlMap[GH3X2X_AF_CHNL_NUM];
STGh3x2xFunctionInfo g_st_AF_FuncitonInfo;
#endif
#if __USE_GOODIX_ADT_ALGORITHM__
GU8 g_pch_ADT_ChnlMap[GH3X2X_ADT_CHNL_NUM];
STGh3x2xFunctionInfo g_st_ADT_FuncitonInfo;
#endif
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
GU8 g_pch_SOFT_ADT_GREEN_ChnlMap[GH3X2X_SOFT_ADT_CHNL_NUM];
STGh3x2xFunctionInfo g_st_SOFT_ADT_GREEN_FuncitonInfo;
#endif
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
GU8 g_pch_SOFT_ADT_IR_ChnlMap[GH3X2X_SOFT_ADT_CHNL_NUM];
STGh3x2xFunctionInfo g_st_SOFT_ADT_IR_FuncitonInfo;
#endif
#if __FUNC_TYPE_BP_ENABLE__
GU8 g_pch_BP_ChnlMap[GH3X2X_BP_CHNL_NUM];
STGh3x2xFunctionInfo g_st_BP_FuncitonInfo;
#endif
#if 0
GU8 g_pch_TEST1_ChnlMap[GH3X2X_TEST_CHNL_NUM];
STGh3x2xFunctionInfo g_st_TEST1_FuncitonInfo;
GU8 g_pch_TEST2_ChnlMap[GH3X2X_TEST_CHNL_NUM];
STGh3x2xFunctionInfo g_st_TEST2_FuncitonInfo;
#endif
GU32 g_punGh3x2xFrameRawdata[GH3X2X_FUNC_CHNL_NUM_MAX];
#if __GS_GYRO_ENABLE__
GS16 g_psGh3x2xFrameGsensorData[6];
#else
GS16 g_psGh3x2xFrameGsensorData[3];
#endif
GU32 g_punGh3x2xFrameAgcInfo[GH3X2X_FUNC_CHNL_NUM_MAX];
GU32 g_punGh3x2xFrameFlag[8];
STGh3x2xAlgoResult g_stGh3x2xAlgoResult;
STCapRawdata g_pstGh3x2xFrameCapData;
STTempRawdata g_pstGh3x2xFrameTempData;
//HR data info
#if __USE_GOODIX_HR_ALGORITHM__
const STGh3x2xFrameInfo g_stHR_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_HR,
.pstFunctionInfo = &g_st_HR_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_HR_CHNL_NUM,
.pchChnlMap = g_pch_HR_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = &g_st_HR_AlgoRecordResult,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_HR_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_HR_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_HR_FrameLastGain,
.punFrameCnt = &g_un_HR_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HR,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xHR_FrameInfo = &g_stHR_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xHR_FrameInfo = 0;
#endif
//HRV data info
#if __USE_GOODIX_HRV_ALGORITHM__
const STGh3x2xFrameInfo g_stHRV_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_HRV,
.pstFunctionInfo = &g_st_HRV_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_HRV_CHNL_NUM,
.pchChnlMap = g_pch_HRV_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = &g_st_HRV_AlgoRecordResult,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_HRV_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_HRV_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_HRV_FrameLastGain,
.punFrameCnt = &g_un_HRV_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HRV,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xHRV_FrameInfo = &g_stHRV_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xHRV_FrameInfo = 0;
#endif
//HSM data info
#if __USE_GOODIX_HSM_ALGORITHM__
const STGh3x2xFrameInfo g_stHSM_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_HSM,
.pstFunctionInfo = &g_st_HSM_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_HSM_CHNL_NUM,
.pchChnlMap = g_pch_HSM_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_HSM_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_HSM_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_HSM_FrameLastGain,
.punFrameCnt = &g_un_HSM_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HSM,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xHSM_FrameInfo = &g_stHSM_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xHSM_FrameInfo = 0;
#endif
//SPO2 data info
#if __USE_GOODIX_SPO2_ALGORITHM__
const STGh3x2xFrameInfo g_stSPO2_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_SPO2,
.pstFunctionInfo = &g_st_SPO2_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_SPO2_CHNL_NUM,
.pchChnlMap = g_pch_SPO2_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = &g_st_SPO2_AlgoRecordResult,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_SPO2_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_SPO2_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_SPO2_FrameLastGain,
.punFrameCnt = &g_un_SPO2_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SPO2,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xSPO2_FrameInfo = &g_stSPO2_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xSPO2_FrameInfo = 0;
#endif
//ECG data info
#if __USE_GOODIX_ECG_ALGORITHM__
const STGh3x2xFrameInfo g_stECG_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_ECG,
.pstFunctionInfo = &g_st_ECG_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_ECG_CHNL_NUM,
.pchChnlMap = g_pch_ECG_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_ECG_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_ECG_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_ECG_FrameLastGain,
.punFrameCnt = &g_un_ECG_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_ECG,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xECG_FrameInfo = &g_stECG_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xECG_FrameInfo = 0;
#endif
#if 0
const STGh3x2xFrameInfo g_stPWTT_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_PWTT,
.pstFunctionInfo = &g_st_PWTT_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_PWTT_CHNL_NUM,
.pchChnlMap = g_pch_PWTT_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_PWTT_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_PWTT_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_PWTT_FrameLastGain,
.punFrameCnt = &g_un_PWTT_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_PWTT,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xECG_FrameInfo = &g_stECG_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xECG_FrameInfo = 0;
#endif
//BT data info
#if __USE_GOODIX_BT_ALGORITHM__
const STGh3x2xFrameInfo g_stBT_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_BT,
.pstFunctionInfo = &g_st_BT_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_BT_CHNL_NUM,
.pchChnlMap = g_pch_BT_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_BT_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_BT_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_BT_FrameLastGain,
.punFrameCnt = &g_un_BT_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BT,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xBT_FrameInfo = &g_stBT_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xBT_FrameInfo = 0;
#endif
//RESP data info
#if __USE_GOODIX_RESP_ALGORITHM__
const STGh3x2xFrameInfo g_stRESP_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_RESP,
.pstFunctionInfo = &g_st_RESP_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_RESP_CHNL_NUM,
.pchChnlMap = g_pch_RESP_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_RESP_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_RESP_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_RESP_FrameLastGain,
.punFrameCnt = &g_un_RESP_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_RESP,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xRESP_FrameInfo = &g_stRESP_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xRESP_FrameInfo = 0;
#endif
//AF data info
#if __USE_GOODIX_AF_ALGORITHM__
const STGh3x2xFrameInfo g_stAF_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_AF,
.pstFunctionInfo = &g_st_AF_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_AF_CHNL_NUM,
.pchChnlMap = g_pch_AF_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_AF_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_AF_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_AF_FrameLastGain,
.punFrameCnt = &g_un_AF_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_AF,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xAF_FrameInfo = &g_stAF_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xAF_FrameInfo = 0;
#endif
#if __USE_GOODIX_BP_ALGORITHM__
const STGh3x2xFrameInfo g_stFPBP_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_FPBP,
.pstFunctionInfo = &g_st_BP_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_BP_CHNL_NUM,
.pchChnlMap = g_pch_BP_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_BP_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_BP_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_BP_FrameLastGain,
.punFrameCnt = &g_un_BP_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BP,
#endif
};
const STGh3x2xFrameInfo g_stPWA_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_PWA,
.pstFunctionInfo = &g_st_BP_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_PWA_CHNL_NUM,
.pchChnlMap = g_pch_BP_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_BP_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_BP_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_BP_FrameLastGain,
.punFrameCnt = &g_un_BP_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BP,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xFPBP_FrameInfo = &g_stFPBP_FrameInfo;
//const STGh3x2xFrameInfo * const g_pstGh3x2xPWA_FrameInfo = &g_stPWA_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xFPBP_FrameInfo = 0;
//const STGh3x2xFrameInfo * const g_pstGh3x2xPWA_FrameInfo = 0;
#endif
#if 0
const STGh3x2xFrameInfo g_stTEST1_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_TEST1,
.pstFunctionInfo = &g_st_TEST1_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_TEST_CHNL_NUM,
.pchChnlMap = g_pch_TEST1_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_TEST1_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_TEST1_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_TEST1_FrameLastGain,
.punFrameCnt = &g_un_TEST1_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_TEST1,
#endif
};
const STGh3x2xFrameInfo g_stTEST2_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_TEST2,
.pstFunctionInfo = &g_st_TEST2_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_TEST_CHNL_NUM,
.pchChnlMap = g_pch_TEST2_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.pstAlgoRecordResult = 0,
#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__
.punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,
.punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,
#else
.punIncompleteRawdata = g_pun_TEST2_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_TEST2_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_TEST2_FrameLastGain,
.punFrameCnt = &g_un_TEST2_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_TEST2,
#endif
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xTEST1_FrameInfo = &g_stTEST1_FrameInfo;
//const STGh3x2xFrameInfo * const g_pstGh3x2xTEST2_FrameInfo = &g_stTEST2_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xTEST1_FrameInfo = 0;
//const STGh3x2xFrameInfo * const g_pstGh3x2xTEST2_FrameInfo = 0;
#endif
//ADT data info
#if __USE_GOODIX_ADT_ALGORITHM__
const STGh3x2xFrameInfo g_stADT_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_ADT,
.pstFunctionInfo = &g_st_ADT_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_ADT_CHNL_NUM,
.pchChnlMap = g_pch_ADT_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.punIncompleteRawdata = g_pun_ADT_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_ADT_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_ADT_FrameLastGain,
.punFrameCnt = &g_un_ADT_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_ADT,
.pstAlgoRecordResult = 0,
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xADT_FrameInfo = &g_stADT_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xADT_FrameInfo = 0;
#endif
//SOFT ADT data info
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
const STGh3x2xFrameInfo g_stSOFT_ADT_GREEN_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_GREEN,
.pstFunctionInfo = &g_st_SOFT_ADT_GREEN_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_SOFT_ADT_CHNL_NUM,
.pchChnlMap = g_pch_SOFT_ADT_GREEN_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.punIncompleteRawdata = g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_SOFT_ADT_GREEN_FrameLastGain,
.punFrameCnt = &g_un_SOFT_ADT_GREEN_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN,
.pstAlgoRecordResult = 0,
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xSOFT_ADT_GREEN_FrameInfo = &g_stSOFT_ADT_GREEN_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xSOFT_ADT_GREEN_FrameInfo = 0;
#endif
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
const STGh3x2xFrameInfo g_stSOFT_ADT_IR_FrameInfo =
{
.unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_IR,
.pstFunctionInfo = &g_st_SOFT_ADT_IR_FuncitonInfo,
.pstAlgoResult = &g_stGh3x2xAlgoResult,
.uchFuntionChnlLimit = GH3X2X_SOFT_ADT_CHNL_NUM,
.pchChnlMap = g_pch_SOFT_ADT_IR_ChnlMap,
.punFrameRawdata = g_punGh3x2xFrameRawdata,
.pusFrameGsensordata = g_psGh3x2xFrameGsensorData,
.pstFrameCapdata = &g_pstGh3x2xFrameCapData,
.pstFrameTempdata = &g_pstGh3x2xFrameTempData,
.punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,
.punFrameFlag = g_punGh3x2xFrameFlag,
.punIncompleteRawdata = g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata,
.punIncompleteChnlMapBit = &g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit,
.puchFrameLastGain = g_puch_SOFT_ADT_GREEN_FrameLastGain,
.punFrameCnt = &g_un_SOFT_ADT_GREEN_TimeStamp,
.pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN,
.pstAlgoRecordResult = 0,
};
//const STGh3x2xFrameInfo * const g_pstGh3x2xSOFT_ADT_IR_FrameInfo = &g_stSOFT_ADT_IR_FrameInfo;
#else
//const STGh3x2xFrameInfo * const g_pstGh3x2xSOFT_ADT_IR_FrameInfo = 0;
#endif
//Function data info struct
const STGh3x2xFrameInfo * const g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_MAX] =
{
//adt
#if __USE_GOODIX_ADT_ALGORITHM__
&g_stADT_FrameInfo,
#else
0,
#endif
//hr
#if __USE_GOODIX_HR_ALGORITHM__
&g_stHR_FrameInfo,
#else
0,
#endif
//hrv
#if __USE_GOODIX_HRV_ALGORITHM__
&g_stHRV_FrameInfo,
#else
0,
#endif
//hsm
#if __USE_GOODIX_HSM_ALGORITHM__
&g_stHSM_FrameInfo,
#else
0,
#endif
//fpbp
//pwa
#if __USE_GOODIX_BP_ALGORITHM__
&g_stFPBP_FrameInfo,
&g_stPWA_FrameInfo,
#else
0,
0,
#endif
//spo2
#if __USE_GOODIX_SPO2_ALGORITHM__
&g_stSPO2_FrameInfo,
#else
0,
#endif
//ecg
#if __USE_GOODIX_ECG_ALGORITHM__
&g_stECG_FrameInfo,
#else
0,
#endif
//pwtt
#if 0
&g_stPWTT_FrameInfo,
#else
0,
#endif
//soft adt green
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
&g_stSOFT_ADT_GREEN_FrameInfo,
#else
0,
#endif
//bt
#if __USE_GOODIX_BT_ALGORITHM__
&g_stBT_FrameInfo,
#else
0,
#endif
//resp
#if __USE_GOODIX_RESP_ALGORITHM__
&g_stRESP_FrameInfo,
#else
0,
#endif
//af
#if __USE_GOODIX_AF_ALGORITHM__
&g_stAF_FrameInfo,
#else
0,
#endif
#if 0
&g_stTEST1_FrameInfo,
&g_stTEST2_FrameInfo,
#else
0,
0,
#endif
//soft adt ir
#if __USE_GOODIX_SOFT_ADT_ALGORITHM__
&g_stSOFT_ADT_IR_FrameInfo,
#else
0,
#endif
0, //GH3X2X_FUNCTION_RS0
0, //GH3X2X_FUNCTION_RS1
0, //GH3X2X_FUNCTION_RS2
0, //GH3X2X_FUNCTION_LEAD_DET
};
#endif
/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/

View File

@ -0,0 +1,301 @@
#include <stdio.h>
#include "gh3x2x_demo_common.h"
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algo_config.h"
#include "gh3x2x_demo_algo_hook.h"
#include "stdint.h"
#include "string.h"
#include "gh_drv.h"
#include "gh_demo_config.h"
#include "gh_demo_inner.h"
#include "gh_demo.h"
//#include "hr_algo.h"
// #include "yak/user_funtion.h"
#define DBG(...)
// extern void set_auto_measurement_heart_value(uint8_t value);
// extern void set_auto_measurement_spo2_value(uint8_t value);
#if (__GOODIX_ALGO_CALL_MODE__)
/**
* @fn void GH3X2X_AlgoLog(char *log_string)
*
* @brief for debug version, log
*
* @attention this function must define that use debug version lib
*
* @param[in] log_string pointer to log string
* @param[out] None
*
* @return None
*/
extern uint8_t hr_wear;
extern void set_sleep_wear(uint8_t value);
void GH3X2X_AlgoLog(GCHAR *log_string)
{
DBG("%s", log_string);
GOODIX_PLATFORM_LOG_ENTITY();
}
/**
* @fn void GH3X2X_AdtAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate hb algorithm.
*
* @attention None
*
* @param[in] stHbAlgoRes hb algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_AdtAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_ADT_ALGORITHM__)
if (pstAlgoResult->uchUpdateFlag)
{
if (pstAlgoResult->snResult[0] == 1) //wear on
{
#if __GH_MSG_WTIH_DRV_LAYER_EN__
GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);
#else
GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);
GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);
#endif
/* code implement by user */
}
else if (pstAlgoResult->snResult[0] == 2) //wear off
{
#if __GH_MSG_WTIH_DRV_LAYER_EN__
GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);
#else
GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);
GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);
#endif
/* code implement by user */
}
DBG("[%s]:====wear:%d======\r\n", __FUNCTION__,pstAlgoResult->snResult[0]);
}
#endif
}
extern void Set_heart_now(uint8_t now);
extern void blood_algo(uint8_t hr_val);
extern void Set_spo2_now(uint8_t now);
/**
* @fn void GH3X2X_HrAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate hb algorithm.
*
* @attention None
*
* @param[in] stHbAlgoRes hb algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
uint8_t hr_algo=0;
extern void set_hr_value(uint8_t hr_value);
extern void set_spo2_value(uint8_t spo2_value);
void GH3X2X_HrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_HR_ALGORITHM__)
/* code implement by user */
hr_algo = pstAlgoResult->snResult[0];
DBG("w:%d hr%d\n",hr_algo,pstAlgoResult->snResult[0]);
if(hr_algo)
{
set_hr_value(pstAlgoResult->snResult[0]);
// blood_algo(pstAlgoResult->snResult[0]);
}
#endif
}
/**
* @fn void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult)
*
*
* @brief This function will be called after calculate spo2 algorithm.
*
* @attention None
*
* @param[in] stSpo2AlgoRes spo2 algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_SPO2_ALGORITHM__)
/* code implement by user */
DBG("spo2:%d\r\n",pstAlgoResult->snResult[0]);
if(pstAlgoResult->snResult[0])
{
set_spo2_value(pstAlgoResult->snResult[0]);
}
#endif
}
/**
* @fn void GH3X2X_HrvAlgorithmResultReport(STHrvAlgoResult stHrvAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate hrv algorithm.
*
* @attention None
*
* @param[in] stHrvAlgoRes hrv algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_HrvAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_HRV_ALGORITHM__)
DBG("hrv:%d,%d,%d,%d\r\n",pstAlgoResult->snResult[0],pstAlgoResult->snResult[1],pstAlgoResult->snResult[2],pstAlgoResult->snResult[3]);
/* code implement by user */
//SLAVER_LOG("snHrvOut0=%d,snHrvOut1=%d,snHrvOut2=%d,snHrvOut3=%d,snHrvNum=%d,snHrvConfi=%d\r\n",
// stHrvAlgoRes[0].snHrvOut0,stHrvAlgoRes[0].snHrvOut1,stHrvAlgoRes[0].snHrvOut2,stHrvAlgoRes[0].snHrvOut3,stHrvAlgoRes[0].snHrvNum,stHrvAlgoRes[0].snHrvNum);
#endif
}
/**
* @fn void GH3X2X_EcgAlgorithmResultReport(STEcgAlgoResult stEcgAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate ecg algorithm.
*
* @attention None
*
* @param[in] stEcgAlgoRes ecg algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_EcgAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_ECG_ALGORITHM__)
/* code implement by user */
//GOODIX_PLATFORM_ECG_RESULT_REPORT_ENTITY();
#endif
}
/**
* @fn void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
*
* @brief This function will be called after calculate ecg algorithm.
*
* @attention None
*
* @param[in] stEcgAlgoRes ecg algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
GU8 g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_DEFAULT; // 0:default 1: wear on 1: wear off
void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)
// DBG("[%s]:result = %d,%d\r\n", __FUNCTION__, pstAlgoResult->snResult[0], pstAlgoResult->snResult[1]);
//live object
if (pstAlgoResult->snResult[0] == 0x1 && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_ON)
{
DBG("[%s]:get algo wear on event\r\n", __FUNCTION__);
#if __GH_MSG_WTIH_DRV_LAYER_EN__
GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_ON);
#else
GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);
GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);
#endif
g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_ON;
/* code implement by user */
}
//non live object
else if ((pstAlgoResult->snResult[0] & 0x2) && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_OFF)
{
DBG("[%s]:get algo wear off event\r\n", __FUNCTION__);
#if __GH_MSG_WTIH_DRV_LAYER_EN__
GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_OFF);
#else
GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);
GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);
#endif
g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_OFF;
/* code implement by user */
}
GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY();
#endif
}
/**
* @fn void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
*
* @brief This function will be called after calculate ecg algorithm.
*
* @attention None
*
* @param[in] stEcgAlgoRes ecg algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
{
#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)
GH3X2X_DEBUG_ALGO_LOG("[%s]:result = %d,%d\r\n", __FUNCTION__, pstAlgoResult->snResult[0], pstAlgoResult->snResult[1]);
//live object
if (pstAlgoResult->snResult[0] == 0x1 && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_ON)
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:get algo wear on event\r\n", __FUNCTION__);
//Gh3x2xDemoStopSampling(GH3X2X_FUNCTION_SOFT_ADT_IR);
//Gh3x2xDemoStartSampling(GH3X2X_FUNCTION_SOFT_ADT_GREEN|GH3X2X_FUNCTION_HR);
#if __GH_MSG_WTIH_DRV_LAYER_EN__
GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_ON);
#else
GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);
GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);
#endif
g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_ON;
/* code implement by user */
}
//non live object
else if ((pstAlgoResult->snResult[0] & 0x2) && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_OFF)
{
GH3X2X_DEBUG_ALGO_LOG("[%s]:get algo wear off event\r\n", __FUNCTION__);
#if __GH_MSG_WTIH_DRV_LAYER_EN__
GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_OFF);
#else
GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);
GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);
#endif
g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_OFF;
/* code implement by user */
}
GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY();
#endif
}
#endif // end else #if (__DRIVER_LIB_MODE__==__DRV_LIB_WITHOUT_ALGO__)

View File

@ -0,0 +1,128 @@
#include <stdio.h>
#include "gh_drv.h"
#include "gh3x2x_demo_algo_config.h"
#ifdef GOODIX_DEMO_PLATFORM
#include "gh3x2x_demo_goodix_PLATFORM.h"
#else
#define GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY()
#define GOODIX_PLATFORM_LOG_ENTITY()
#endif
#if (__GOODIX_ALGO_CALL_MODE__)
/**
* @fn void GH3X2X_AdtAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate adt algorithm.
*
* @attention None
*
* @param[in] stHbAlgoRes hb algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_AdtAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
/**
* @fn void GH3X2X_HrAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate hb algorithm.
*
* @attention None
*
* @param[in] stHbAlgoRes hb algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_HrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
/**
* @fn void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult)
*
*
* @brief This function will be called after calculate spo2 algorithm.
*
* @attention None
*
* @param[in] stSpo2AlgoRes spo2 algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
/**
* @fn void GH3X2X_HrvAlgorithmResultReport(STHrvAlgoResult stHrvAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate hrv algorithm.
*
* @attention None
*
* @param[in] stHrvAlgoRes hrv algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_HrvAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
/**
* @fn void GH3X2X_EcgAlgorithmResultReport(STEcgAlgoResult stEcgAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)
*
* @brief This function will be called after calculate ecg algorithm.
*
* @attention None
*
* @param[in] stEcgAlgoRes ecg algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_EcgAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
/**
* @fn void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
*
* @brief This function will be called after calculate ecg algorithm.
*
* @attention None
*
* @param[in] stEcgAlgoRes ecg algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
/**
* @fn void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)
*
* @brief This function will be called after calculate ecg algorithm.
*
* @attention None
*
* @param[in] stEcgAlgoRes ecg algorithm result array
* @param[in] pusAlgoResIndexArr frame index of every algo result
* @param[in] usAlgoResCnt number of algo result
* @param[out] None
*
* @return None
*/
void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
#endif // end else #if (__DRIVER_LIB_MODE__==__DRV_LIB_WITHOUT_ALGO__)

View File

@ -0,0 +1,334 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_algorithm.c
*
* @brief gh3x2x driver lib demo code for algorithm
*
* @author Gooidx Iot Team
*
*/
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algo_memory.h"
#include "gh3x2x_demo_algo_config.h"
#include "gh3x2x_demo_algorithm_calc.h"
#include "goodix_algo.h"
#include "goodix_mem.h"
#if (__GOODIX_ALGO_CALL_MODE__)
#if __USER_DYNAMIC_ALGO_MEM_EN__
GU32 *g_punGh3x2xAlgoMemBufferPointer = GH3X2X_ALGORITHMS_MEMORY_SIZE_USERSET;
#else
GU32 g_punGh3x2xAlgoMemBuffer[GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL/4] = {0};
GU32 *g_punGh3x2xAlgoMemBufferPointer = g_punGh3x2xAlgoMemBuffer;
#endif
#else //without algorithm
GU32 *g_punGh3x2xAlgoMemBufferPointer = 0;
#endif
void GH3X2X_MemFree(void* mem_addr)
{
goodix_mem_free(mem_addr);
}
void* GH3X2X_MemMalloc(GS32 nSize)
{
return goodix_mem_malloc(nSize);
}
void Gh3x2xPoolIsNotEnough(void)
{
while(1)
{
GH3X2X_DEBUG_ALGO_LOG("MEMORY ERROR!!!PLEASE RESET HARDWARE!!!\n");
}
}
#if (__GOODIX_ALGO_CALL_MODE__)
#if __GH3X2X_MEM_POOL_CHECK_EN__
const GU32 g_unGh3z2xMemCheckAreaStart[17] =
{
0,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*1/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*2/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*3/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*4/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*5/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*6/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*7/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*8/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*9/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*10/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*11/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*12/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*13/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*14/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*15/16,
GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL,
};
GU32 g_unGh3x2xLastMemPoolCheckSumArea[16];
GU8 g_uchGh3x2xMemPollHaveGetCheckSum = 0;
GU16 g_usGh3x2xMemPollErrorFlag = 0;
GU32 Gh3x2xGetMemPoolCheckSum(GU8 *lunMemPool, GU32 lunByteSize)
{
GU32 lunCheckSum = 0;
for(GU32 lunByteCnt = 0; lunByteCnt < lunByteSize; lunByteCnt += 4)
{
lunCheckSum += *((GU32*)(lunMemPool+lunByteCnt));
}
return lunCheckSum;
}
void Gh3x2xMemPoolCheckSumWrite(GU8 *lunMemPool)
{
for(GU8 uchAreaCnt = 0; uchAreaCnt < 16; uchAreaCnt ++)
{
g_unGh3x2xLastMemPoolCheckSumArea[uchAreaCnt] = Gh3x2xGetMemPoolCheckSum(lunMemPool + ((g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4), (g_unGh3z2xMemCheckAreaStart[uchAreaCnt + 1]/4)*4 - (g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4);
}
g_uchGh3x2xMemPollHaveGetCheckSum = 1;
}
GU16 Gh3x2xMemPoolCheckSumCheck(GU8 *lunMemPool)
{
GU16 usErrorFlag = 0;
if(0 == g_usGh3x2xMemPollErrorFlag)
{
for(GU8 uchAreaCnt = 0; uchAreaCnt < 16; uchAreaCnt ++)
{
if(g_unGh3x2xLastMemPoolCheckSumArea[uchAreaCnt] != Gh3x2xGetMemPoolCheckSum(lunMemPool + ((g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4), (g_unGh3z2xMemCheckAreaStart[uchAreaCnt + 1]/4)*4 - (g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4))
{
usErrorFlag |= (((GU16)1) << uchAreaCnt);
}
}
}
g_usGh3x2xMemPollErrorFlag = usErrorFlag;
return usErrorFlag;
}
void Gh3x2xCheckMemPollBeforeAlgoCal(void)
{
if(g_uchGh3x2xMemPollHaveGetCheckSum)
{
if(Gh3x2xMemPoolCheckSumCheck((GU8*)g_punGh3x2xAlgoMemBufferPointer))
{
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check error!!! error flag = 0x%X\r\n", g_usGh3x2xMemPollErrorFlag);
while(1); //error !!! mem pool is be destroy
}
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 0 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[0]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 1 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[1]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 2 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[2]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 3 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[3]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 4 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[4]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 5 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[5]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 6 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[6]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 7 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[7]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 8 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[8]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 9 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[9]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 10 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[10]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 11 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[11]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 12 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[12]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 13 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[13]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 14 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[14]);
GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 15 = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[15]);
}
}
void Gh3x2xUpdataMemPollChkSumAfterAlgoCal(void)
{
Gh3x2xMemPoolCheckSumWrite((GU8*)g_punGh3x2xAlgoMemBufferPointer);
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*1/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*2/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*3/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*4/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*5/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*6/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*7/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*8/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*9/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*10/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*11/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*12/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*13/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*14/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*15/16)/4 - 1] = 0x3333; //test
//g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*16/16)/4 - 1] = 0x3333; //test
}
#endif
#if __USER_DYNAMIC_ALGO_MEM_EN__
void* Gh3x2xAlgoMemApply(GU32 unMemSize)
{
return Gh3x2xMallocUser(unMemSize)
}
void Gh3x2xAlgoMemFree(void* MemAddr)
{
Gh3x2xFreeUser(MemAddr);
}
#else
void* Gh3x2xAlgoMemApply(GU32 unMemSize)
{
return &g_punGh3x2xAlgoMemBuffer[0];
}
void Gh3x2xAlgoMemFree(void* MemAddr)
{
}
#endif
/// algorithm memory is inited or not
GU8 g_uchAlgoMemStatus = ALGO_MEM_NO_INIT;
/// buffer for algorithm, this addr is import from outer
//void* g_unAlgorithmMemBuffer = 0;
/// buffer size(byte) for algorithm, this size is import from outer
GU32 g_unAlgorithmMemBufferSize = 0;
/**
* @fn GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize)
*
* @brief Config algorithm memory.
*
* @attention Mem can only be static,such as global array
*
* @param[in] unMemSize memory size(unit:byte)
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_RESOURCE_ERROR return algorithm mem config error
*/
GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize)
{
GS8 chRet = GH3X2X_RET_OK;
if (unMemSize > 0)
{
GH3X2X_AlgoDeinit(0xFFFFFFFF);
g_unAlgorithmMemBufferSize = unMemSize;
chRet = GH3X2X_RET_OK;
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem Config complete!Size:%d\r\n", (int)unMemSize);
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init start...\r\n");
chRet = GH3X2X_AlgoMemInit();
}
else
{
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem config fail!\r\n");
chRet = GH3X2X_RET_RESOURCE_ERROR;
}
return chRet;
}
/**
* @fn GS8 GH3X2X_AlgoMemInit(void)
*
* @brief algorithm memory init
*
* @attention None
*
* @param[in] None
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_RESOURCE_ERROR return algorithm mem init error
*/
GS8 GH3X2X_AlgoMemInit(void)
{
GS8 chRet = GH3X2X_RET_OK;
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init start...\r\n");
if (ALGO_MEM_NO_INIT == g_uchAlgoMemStatus)
{
g_punGh3x2xAlgoMemBufferPointer = (GU32*)Gh3x2xAlgoMemApply(g_unAlgorithmMemBufferSize);
if ((g_punGh3x2xAlgoMemBufferPointer != 0) && (g_unAlgorithmMemBufferSize > 0))
{
if(MEMPOOL_IS_OK_E != goodix_mem_init((void*)g_punGh3x2xAlgoMemBufferPointer, g_unAlgorithmMemBufferSize))
{
chRet = GH3X2X_RET_RESOURCE_ERROR;
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init error!\r\n");
}
else
{
g_uchAlgoMemStatus = ALGO_MEM_INIT_OK;
chRet = GH3X2X_RET_OK;
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init success.Addr:0x%x,Size:%d\r\n", (unsigned int)g_punGh3x2xAlgoMemBufferPointer, \
(int)g_unAlgorithmMemBufferSize);
}
}
else
{
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem para error!\r\n");
chRet = GH3X2X_RET_RESOURCE_ERROR;
}
}
return chRet;
}
/**
* @fn void GH3X2X_AlgoMemDeinit(void)
*
* @brief algorithm memory deinit
*
* @attention None
*
* @param[in] None
* @param[out] None
*
* @return None
*/
void GH3X2X_AlgoMemDeinit(void)
{
if (ALGO_MEM_INIT_OK == g_uchAlgoMemStatus)
{
goodix_mem_deinit(); //destroy all memory
if(g_punGh3x2xAlgoMemBufferPointer)
{
Gh3x2xAlgoMemFree((void*)g_punGh3x2xAlgoMemBufferPointer);
g_punGh3x2xAlgoMemBufferPointer = 0;
}
g_uchAlgoMemStatus = ALGO_MEM_NO_INIT;
GH3X2X_DEBUG_ALGO_LOG("Algorithm mem deinit!\r\n");
}
}
GU8 GH3X2X_GetAlgoMemStatus(void)
{
return g_uchAlgoMemStatus;
}
GU8 Gh3x2xGetHrAlgoSupportChnl(void)
{
return __HR_ALGORITHM_SUPPORT_CHNL_NUM__;
}
GU8 Gh3x2xGetSpo2AlgoSupportChnl(void)
{
return __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__;
}
#endif

View File

@ -0,0 +1,394 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_algo_memory.h
*
* @brief gh3x2x algo memory set
*
* @version ref gh3x2x_demo_algo_memory.h
*
*/
#ifndef _GH3X2X_DEMO_ALGO_MEMORY_H_
#define _GH3X2X_DEMO_ALGO_MEMORY_H_
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algo_config.h"
#if (__GOODIX_ALGO_CALL_MODE__)
/* algorithm run mode:simultaneously or not */
#define GH3X2X_ALGORITHM_RUN_ALONE (0) /**< only excute one algorithm at the same time */
#define GH3X2X_ALGORITHM_RUN_SIMULTANEOUSLY (1) /**< excute more than one algorithm */
/* algorithm mem size in byte */
#if (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_BASIC)
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL (2116) /**< HB 1 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL (2116) /**< HB 2 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL (2116) /**< HB 3 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL (2116) /**< HB 4 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL (1196) /**< HB 1 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL (1196) /**< HB 2 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL (1196) /**< HB 3 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL (1196) /**< HB 4 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_HR_ALGORITHM_ROM (20212)
#define GH3X2X_HR_ALGORITHM_STACK (556)
#define GH3X2X_HR_ALGORITHM_MIPS_MS (2.61)
#elif (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM)
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL (3248) /**< HB 1 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL (3248) /**< HB 2 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL (3248) /**< HB 3 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL (3248) /**< HB 4 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL (2060) /**< HB 1 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL (2060) /**< HB 2 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL (2060) /**< HB 3 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL (2060) /**< HB 4 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_HR_ALGORITHM_ROM (25988)
#define GH3X2X_HR_ALGORITHM_STACK (612)
#define GH3X2X_HR_ALGORITHM_MIPS_MS (3.25)
#elif (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM)
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL (8944) /**< HB 1 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL (8944) /**< HB 2 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL (8944) /**< HB 3 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL (8944) /**< HB 4 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL (3932) /**< HB 1 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL (3932) /**< HB 2 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL (3932) /**< HB 3 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL (3932) /**< HB 4 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_HR_ALGORITHM_ROM (76424)
#define GH3X2X_HR_ALGORITHM_STACK (676)
#define GH3X2X_HR_ALGORITHM_MIPS_MS (21)
#elif (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE)
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL (15584) /**< HB 1 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL (15584) /**< HB 2 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL (15584) /**< HB 3 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL (15584) /**< HB 4 chnl algorithm peak memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL (5248) /**< HB 1 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL (5248) /**< HB 2 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL (5248) /**< HB 3 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL (5248) /**< HB 4 chnl algorithm desident memory size in byte */
#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_HR_ALGORITHM_ROM (57176)
#define GH3X2X_HR_ALGORITHM_STACK (552)
#define GH3X2X_HR_ALGORITHM_MIPS_MS (38)
#else
#error "please define __GOODIX_HR_ALGO_VERISON__ in gh3x2x_demo_algo_config.h !"
#endif
#if (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM)
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_1CHNL (2736) /**< SPO2 1 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_2CHNL (2736) /**< SPO2 2 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_3CHNL (2736) /**< SPO2 3 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_4CHNL (2736) /**< SPO2 4 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_1CHNL (1956) /**< SPO2 1 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_2CHNL (1956) /**< SPO2 2 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_3CHNL (1956) /**< SPO2 3 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_4CHNL (1956) /**< SPO2 4 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_SPO2_ALGORITHM_ROM (12596)
#define GH3X2X_SPO2_ALGORITHM_STACK (376)
#define GH3X2X_SPO2_ALGORITHM_MIPS_MS (/)
#elif (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE)
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_1CHNL (7864) /**< SPO2 1 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_2CHNL (7864) /**< SPO2 2 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_3CHNL (7864) /**< SPO2 3 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_4CHNL (7864) /**< SPO2 4 chnl algorithm peak memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_1CHNL (5020) /**< SPO2 1 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_2CHNL (5020) /**< SPO2 2 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_3CHNL (5020) /**< SPO2 3 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_4CHNL (5020) /**< SPO2 4 chnl algorithm memory size in byte */
#define GH3X2X_SPO2_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_SPO2_ALGORITHM_ROM (49084)
#define GH3X2X_SPO2_ALGORITHM_STACK (492)
#define GH3X2X_SPO2_ALGORITHM_MIPS_MS (26)
#else
#error "please define __GOODIX_SPO2_ALGO_VERISON__ in gh3x2x_demo_algo_config.h !"
#endif
#if (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_ENABLE)
#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK (38360) /**< ECG algorithm peak memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT (37176) /**< ECG algorithm resident memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_ECG_ALGORITHM_ROM (33784)
#define GH3X2X_ECG_ALGORITHM_STACK (5128)
#define GH3X2X_ECG_ALGORITHM_MIPS_MS (216)
#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_DISABLE)
#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK (32024) /**< ECG algorithm peak memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT (30640) /**< ECG algorithm resident memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_ECG_ALGORITHM_ROM (33784)
#define GH3X2X_ECG_ALGORITHM_STACK (5128)
#define GH3X2X_ECG_ALGORITHM_MIPS_MS (161)
#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_ENABLE)
#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK (23476) /**< ECG algorithm peak memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT (22132) /**< ECG algorithm resident memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_ECG_ALGORITHM_ROM (33784)
#define GH3X2X_ECG_ALGORITHM_STACK (5128)
#define GH3X2X_ECG_ALGORITHM_MIPS_MS (151)
#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_DISABLE)
#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK (19464) /**< ECG algorithm peak memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT (18120) /**< ECG algorithm resident memory size in byte */
#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_ECG_ALGORITHM_ROM (33784)
#define GH3X2X_ECG_ALGORITHM_STACK (5128)
#define GH3X2X_ECG_ALGORITHM_MIPS_MS (126)
#else
#error "please define __GOODIX_ECG_ALGO_CONFIG__ in gh3x2x_demo_algo_config.h !"
#endif
#define GH3X2X_HRV_ALGORITHM_MEMORY_PEAK (3008) /**< HRV algorithm peak memory size in byte */
#define GH3X2X_HRV_ALGORITHM_MEMORY_RESIDENT (2844) /**< HRV algorithm resident memory size in byte */
#define GH3X2X_HRV_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_HRV_ALGORITHM_ROM (13320)
#define GH3X2X_HRV_ALGORITHM_STACK (964)
#define GH3X2X_HRV_ALGORITHM_MIPS_MS (/)
#define GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_PEAK (1128) /**< SOFT ADT algorithm peak memory size in byte */
#define GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_RESIDENT (104) /**< SOFT ADT algorithm resident memory size in byte */
#define GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_REDUNDANCY (100) /**< SOFT ADT algorithm redundancy memory size in byte */
#define GH3X2X_SOFT_ADT_ALGORITHM_ROM (16889)
#define GH3X2X_SOFT_ADT_ALGORITHM_STACK (4088)
#define GH3X2X_SOFT_ADT_ALGORITHM_MIPS_MS (/)
#define GH3X2X_HSM_ALGORITHM_MEMORY_PEAK (944) /**< HSM algorithm memory peak size in byte */
#define GH3X2X_HSM_ALGORITHM_MEMORY_RESIDENT (944) /**< HSM algorithm memory resident size in byte */
#define GH3X2X_HSM_ALGORITHM_MEMORY_REDUNDANCY (100)
#define GH3X2X_BT_ALGORITHM_MEMORY_PEAK (1600) /**< BT algorithm memory peak size in byte */
#define GH3X2X_BT_ALGORITHM_MEMORY_RESIDENT (1500) /**< BT algorithm memory resident size in byte */
#define GH3X2X_BT_ALGORITHM_MEMORY_REDUNDANCY (200)
#define GH3X2X_RESP_ALGORITHM_MEMORY_PEAK (5435) /**< RESP algorithm memory peak size in byte */
#define GH3X2X_RESP_ALGORITHM_MEMORY_RESIDENT (2363) /**< RESP algorithm memory resident size in byte */
#define GH3X2X_RESP_ALGORITHM_MEMORY_REDUNDANCY (500)
#define GH3X2X_AF_ALGORITHM_MEMORY_PEAK (3262) /**< AF algorithm memory peak size in byte */
#define GH3X2X_AF_ALGORITHM_MEMORY_RESIDENT (1102) /**< AF algorithm memory resident size in byte */
#define GH3X2X_AF_ALGORITHM_MEMORY_REDUNDANCY (300)
/* algorithm mem config */
#if (__GOODIX_ALGO_CALL_MODE__)
#if (__USE_GOODIX_HR_ALGORITHM__)
#if __HR_ALGORITHM_SUPPORT_CHNL_NUM__ <= 1
#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL
#define GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL
#elif __HR_ALGORITHM_SUPPORT_CHNL_NUM__ == 2
#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL
#define GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL
#elif __HR_ALGORITHM_SUPPORT_CHNL_NUM__ == 3
#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL
#define GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL
#elif __HR_ALGORITHM_SUPPORT_CHNL_NUM__ >= 4
#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL
#define GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL
#endif
#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_ALGORITHM_HR_MEMORY_PEAK - GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_HR_MEMORY_REDUNDANCY GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_HR_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_HSM_ALGORITHM__)
#define GH3X2X_ALGORITHM_HSM_MEMORY_RESIDENT (GH3X2X_HSM_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_HSM_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_HSM_ALGORITHM_MEMORY_PEAK - GH3X2X_HSM_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_HSM_MEMORY_REDUNDANCY GH3X2X_HSM_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_HSM_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_HSM_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_HSM_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_SPO2_ALGORITHM__)
#if __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ <= 1
#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_1CHNL
#define GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_1CHNL
#elif __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ == 2
#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_2CHNL
#define GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_2CHNL
#elif __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ == 3
#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_3CHNL
#define GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_3CHNL
#elif __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ >= 4
#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_4CHNL
#define GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_4CHNL
#endif
#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK - GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_SPO2_MEMORY_REDUNDANCY GH3X2X_SPO2_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_SPO2_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_ECG_ALGORITHM__)
#define GH3X2X_ALGORITHM_ECG_MEMORY_RESIDENT (GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_ECG_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_ECG_ALGORITHM_MEMORY_PEAK - GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_ECG_MEMORY_REDUNDANCY GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_ECG_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_ECG_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_ECG_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_HRV_ALGORITHM__)
#define GH3X2X_ALGORITHM_HRV_MEMORY_RESIDENT (GH3X2X_HRV_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_HRV_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_HRV_ALGORITHM_MEMORY_PEAK - GH3X2X_HRV_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_HRV_MEMORY_REDUNDANCY GH3X2X_HRV_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_HRV_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_HRV_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_HRV_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_BT_ALGORITHM__)
#define GH3X2X_ALGORITHM_BT_MEMORY_RESIDENT (GH3X2X_BT_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_BT_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_BT_ALGORITHM_MEMORY_PEAK - GH3X2X_BT_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_BT_MEMORY_REDUNDANCY GH3X2X_BT_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_BT_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_BT_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_BT_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_RESP_ALGORITHM__)
#define GH3X2X_ALGORITHM_RESP_MEMORY_RESIDENT (GH3X2X_RESP_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_RESP_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_RESP_ALGORITHM_MEMORY_PEAK - GH3X2X_RESP_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_RESP_MEMORY_REDUNDANCY GH3X2X_RESP_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_RESP_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_RESP_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_RESP_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_AF_ALGORITHM__)
#define GH3X2X_ALGORITHM_AF_MEMORY_RESIDENT (GH3X2X_AF_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_AF_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_AF_ALGORITHM_MEMORY_PEAK - GH3X2X_AF_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_AF_MEMORY_REDUNDANCY GH3X2X_AF_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_AF_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_AF_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_AF_MEMORY_REDUNDANCY (0)
#endif
#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)
#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_RESIDENT (GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_PEAK_WITHOUT_RESIDENT (GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_PEAK - GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_RESIDENT)
#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_REDUNDANCY GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_REDUNDANCY
#else
#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_RESIDENT (0)
#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_PEAK_WITHOUT_RESIDENT (0)
#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_REDUNDANCY (0)
#endif
#endif
#define MAX2(a0, a1) (((a0) > (a1)) ? (a0) : (a1))
#define ADD2(a0, a1) ((a0) + (a1))
#define MAX4(a0,a1,a2,a3) (MAX2(MAX2(a0, a1),MAX2(a2, a3)))
#define MAX5(a0,a1,a2,a3,a4) (MAX2(MAX4(a0,a1,a2,a3),a4))
#define MAX9(a0, a1, a2, a3, a4, a5 ,a6, a7, a8) (MAX2(MAX5(a0,a1,a2,a3,a4),MAX4(a5,a6,a7,a8))))
#define GH3X2X_FUNCTION_SOFT_ADT (GH3X2X_FUNCTION_SOFT_ADT_GREEN|GH3X2X_FUNCTION_SOFT_ADT_IR)
#define GH3X2X_ALGORITHMS_MEMORY_RESIDENT_(x) (\
((0 != (x & GH3X2X_FUNCTION_HR)) * __USE_GOODIX_HR_ALGORITHM__ * GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_SPO2)) * __USE_GOODIX_SPO2_ALGORITHM__ * GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_ECG)) * __USE_GOODIX_ECG_ALGORITHM__ * GH3X2X_ALGORITHM_ECG_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_HRV)) * __USE_GOODIX_HRV_ALGORITHM__ * GH3X2X_ALGORITHM_HRV_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_HSM)) * __USE_GOODIX_HSM_ALGORITHM__ * GH3X2X_ALGORITHM_HSM_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_BT)) * __USE_GOODIX_BT_ALGORITHM__ * GH3X2X_ALGORITHM_BT_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_RESP)) * __USE_GOODIX_RESP_ALGORITHM__ * GH3X2X_ALGORITHM_RESP_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_AF)) * __USE_GOODIX_AF_ALGORITHM__ * GH3X2X_ALGORITHM_AF_MEMORY_RESIDENT) + \
((0 != (x & GH3X2X_FUNCTION_SOFT_ADT)) * __USE_GOODIX_SOFT_ADT_ALGORITHM__ * GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_RESIDENT))
#define GH3X2X_ALGORITHMS_MEMORY_PEAK_WITHOUT_RESIDENT_(x) (MAX9(\
ADD2(((0 != (x & GH3X2X_FUNCTION_HR))* __USE_GOODIX_HR_ALGORITHM__ * GH3X2X_ALGORITHM_HR_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_HR))* __USE_GOODIX_HR_ALGORITHM__ * GH3X2X_ALGORITHM_HR_MEMORY_REDUNDANCY)),\
ADD2(((0 != (x & GH3X2X_FUNCTION_SPO2))* __USE_GOODIX_SPO2_ALGORITHM__* GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_SPO2))* __USE_GOODIX_SPO2_ALGORITHM__* GH3X2X_ALGORITHM_SPO2_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_ECG))* __USE_GOODIX_ECG_ALGORITHM__* GH3X2X_ALGORITHM_ECG_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_ECG))* __USE_GOODIX_ECG_ALGORITHM__* GH3X2X_ALGORITHM_ECG_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_HRV))* __USE_GOODIX_HRV_ALGORITHM__* GH3X2X_ALGORITHM_HRV_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_HRV))* __USE_GOODIX_HRV_ALGORITHM__* GH3X2X_ALGORITHM_HRV_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_HSM))* __USE_GOODIX_HSM_ALGORITHM__* GH3X2X_ALGORITHM_HSM_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_HSM))* __USE_GOODIX_HSM_ALGORITHM__* GH3X2X_ALGORITHM_HSM_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_BT))* __USE_GOODIX_BT_ALGORITHM__* GH3X2X_ALGORITHM_BT_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_BT))* __USE_GOODIX_BT_ALGORITHM__* GH3X2X_ALGORITHM_BT_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_RESP))* __USE_GOODIX_RESP_ALGORITHM__* GH3X2X_ALGORITHM_RESP_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_RESP))* __USE_GOODIX_RESP_ALGORITHM__* GH3X2X_ALGORITHM_RESP_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_AF))* __USE_GOODIX_AF_ALGORITHM__* GH3X2X_ALGORITHM_AF_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_AF))* __USE_GOODIX_AF_ALGORITHM__* GH3X2X_ALGORITHM_AF_MEMORY_REDUNDANCY)), \
ADD2(((0 != (x & GH3X2X_FUNCTION_SOFT_ADT))* __USE_GOODIX_SOFT_ADT_ALGORITHM__ * GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_PEAK_WITHOUT_RESIDENT),\
((0 != (x & GH3X2X_FUNCTION_SOFT_ADT))* __USE_GOODIX_SOFT_ADT_ALGORITHM__ * GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_REDUNDANCY)))
#define GH3X2X_ALGORITHMS_MEMORY_(x) (GH3X2X_ALGORITHMS_MEMORY_RESIDENT_(x) + GH3X2X_ALGORITHMS_MEMORY_PEAK_WITHOUT_RESIDENT_(x))
#define __GH3X2X_ALGORITHMS_MEMORY (\
MAX5(\
GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_0),\
GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_1),\
GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_2),\
GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_3),\
GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_4)\
)\
)
//final size
#define GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL (((GU32)((__GH3X2X_ALGORITHMS_MEMORY + 3) / 4)) * 4)
/**
* @fn GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize)
*
* @brief Config algorithm memory.
*
* @attention Mem can only be static,such as global array
*
* @param[in] unMemSize memory size(unit:byte)
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_RESOURCE_ERROR return algorithm mem config error
*/
GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize);
#endif
#endif /* _GH3X2X_DEMO_ALGO_CALL_H_ */
/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/

View File

@ -0,0 +1,126 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_reg_array.c
*
* @brief gh3x2x driver lib reg config array
*
* @author Gooidx Iot Team
*
*/
#include "gh3x2x_demo_algo_config.h"
#include "gh_drv.h"
/// HR
const STGh3x2xReg gh3x2x_algo_reg_list0[] =
{
#if 0
{0x33C0, 0x0000}, {0x33C2, 0x0000}, {0x33C4, 0x0000}, {0x33C6, 0x0000}, {0x33C8, 0x0000}, {0x33CA, 0x0000},
{0x33CC, 0x0000}, {0x33CE, 0x0000}, {0x33D0, 0x0000}, {0x33D2, 0x0000}, {0x35C0, 0x0002}, {0x35C4, 0x0100},
{0x36C0, 0x0000}, {0x36C2, 0x0000}, {0x36C4, 0x0020}, {0x36C6, 0x0000}, {0x36C8, 0x0010}, {0x36CA, 0x0000},
{0x36CC, 0x0003}, {0x36CE, 0x0000}, {0x36D0, 0x0003}, {0x36D2, 0x0000}, {0x42C0, 0x846C}, {0x42C2, 0xFFFD},
{0x42C4, 0x87E3}, {0x42C6, 0xFFFF}, {0x42C8, 0xCC38}, {0x42CA, 0x000F}, {0x42CC, 0x0001}, {0x42CE, 0x0000},
{0x42D0, 0x0000}, {0x42D2, 0x0000}, {0x42D4, 0x001E}, {0x42D6, 0x0000}, {0x42D8, 0x000F}, {0x42DA, 0x0000},
{0x42DC, 0x0004}, {0x42DE, 0x0000}, {0x42E0, 0x0003}, {0x42E2, 0x0000}, {0x42E4, 0x0000}, {0x42E6, 0x0000},
{0x42E8, 0x0000}, {0x42EA, 0x0000}, {0x44C0, 0x0001}, {0x44CC, 0xFF01}, {0x44D4, 0xFF00}, {0xFFFF, 0x0001}
#else
// {0x33C0, 0x0000}, {0x33C2, 0x0000}, {0x33C4, 0x0000}, {0x33C6, 0x0000}, {0x33C8, 0x0000}, {0x33CA, 0x0000},
// {0x33CC, 0x0000}, {0x33CE, 0x0000}, {0x33D0, 0x0000}, {0x33D2, 0x0000}, {0x35C0, 0x0002}, {0x35C4, 0x0100},
// {0x36C0, 0x0000}, {0x36C2, 0x0000}, {0x36C4, 0x0020}, {0x36C6, 0x0000}, {0x36C8, 0x0010}, {0x36CA, 0x0000},
// {0x36CC, 0x0003}, {0x36CE, 0x0000}, {0x36D0, 0x0003}, {0x36D2, 0x0000}, {0x42C0, 0x846C}, {0x42C2, 0xFFFD},
// {0x42C4, 0x87E3}, {0x42C6, 0xFFFF}, {0x42C8, 0xCC38}, {0x42CA, 0x000F}, {0x42CC, 0x0001}, {0x42CE, 0x0000},
// {0x42D0, 0x0000}, {0x42D2, 0x0000}, {0x42D4, 0x001E}, {0x42D6, 0x0000}, {0x42D8, 0x000F}, {0x42DA, 0x0000},
// {0x42DC, 0x0004}, {0x42DE, 0x0000}, {0x42E0, 0x0003}, {0x42E2, 0x0000}, {0x42E4, 0x0000}, {0x42E6, 0x0000},
// {0x42E8, 0x0000}, {0x42EA, 0x0000}, {0x44C0, 0x0001}, {0x44CC, 0xFF01}, {0x44D4, 0xFF00}, {0xFFFF, 0x0001}
{0x33C0, 0x0000}, {0x33C2, 0x0000}, {0x33C4, 0x0000}, {0x33C6, 0x0000}, {0x33C8, 0x0000}, {0x33CA, 0x0000},
{0x33CC, 0x0000}, {0x33CE, 0x0000}, {0x33D0, 0x0000}, {0x33D2, 0x0000}, {0x35C0, 0x0002}, {0x35C4, 0x0100},
{0x36C0, 0x0000}, {0x36C2, 0x0000}, {0x36C4, 0x0020}, {0x36C6, 0x0000}, {0x36C8, 0x0010}, {0x36CA, 0x0000},
{0x36CC, 0x0003}, {0x36CE, 0x0000}, {0x36D0, 0x0003}, {0x36D2, 0x0000}, {0x42C0, 0x846C}, {0x42C2, 0xFFFD},
{0x42C4, 0x87E3}, {0x42C6, 0xFFFF}, {0x42C8, 0xCC38}, {0x42CA, 0x000F}, {0x42CC, 0x0001}, {0x42CE, 0x0000},
{0x42D0, 0x0000}, {0x42D2, 0x0000}, {0x42D4, 0x001E}, {0x42D6, 0x0000}, {0x42D8, 0x000F}, {0x42DA, 0x0000},
{0x42DC, 0x0004}, {0x42DE, 0x0000}, {0x42E0, 0x0003}, {0x42E2, 0x0000}, {0x42E4, 0x0000}, {0x42E6, 0x0000},
{0x42E8, 0x0000}, {0x42EA, 0x0000}, {0x44C0, 0x0001}, {0x44CC, 0xFF01}, {0x44D4, 0xFF00}, {0xFFFF, 0x0001}
#endif
};
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1)
const STGh3x2xReg gh3x2x_algo_reg_list1[] =
{
{0x45C0, 0x01F4}, {0x45C2, 0x0000}, {0x45C4, 0x0001}, {0x45C6, 0x0000}, {0x45C8, 0x0001}, {0x45CA, 0x0000},
{0xFFFF, 0x0001}
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2)
const STGh3x2xReg gh3x2x_algo_reg_list2[] =
{
{0,0},
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3)
const STGh3x2xReg gh3x2x_algo_reg_list3[] =
{
{0,0},
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4)
const STGh3x2xReg gh3x2x_algo_reg_list4[] =
{
{0,0},
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5)
const STGh3x2xReg gh3x2x_algo_reg_list5[] =
{
{0,0},
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6)
const STGh3x2xReg gh3x2x_algo_reg_list6[] =
{
{0,0},
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7)
const STGh3x2xReg gh3x2x_algo_reg_list7[] =
{
{0,0},
};
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7) */
const STGh3x2xInitConfig g_stGoodixAlgoCfgListArr[__GOODIX_ALGO_CFG_LIST_MAX_NUM__] =
{
{gh3x2x_algo_reg_list0,sizeof(gh3x2x_algo_reg_list0) / sizeof(gh3x2x_algo_reg_list0[0])},
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1)
{gh3x2x_algo_reg_list1,sizeof(gh3x2x_algo_reg_list1) / sizeof(gh3x2x_algo_reg_list1[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2)
{gh3x2x_algo_reg_list2,sizeof(gh3x2x_algo_reg_list2) / sizeof(gh3x2x_algo_reg_list2[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3)
{gh3x2x_algo_reg_list3,sizeof(gh3x2x_algo_reg_list3) / sizeof(gh3x2x_algo_reg_list3[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4)
{gh3x2x_algo_reg_list4,sizeof(gh3x2x_algo_reg_list4) / sizeof(gh3x2x_algo_reg_list4[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5)
{gh3x2x_algo_reg_list5,sizeof(gh3x2x_algo_reg_list5) / sizeof(gh3x2x_algo_reg_list5[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6)
{gh3x2x_algo_reg_list6,sizeof(gh3x2x_algo_reg_list6) / sizeof(gh3x2x_algo_reg_list6[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6) */
#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7)
{gh3x2x_algo_reg_list7,sizeof(gh3x2x_algo_reg_list7) / sizeof(gh3x2x_algo_reg_list7[0])},
#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7) */
};

View File

@ -0,0 +1,355 @@
/**
* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.
*
* @file gh3x2x_demo_algorithm_calc.h
*
* @brief gh3x2x algorithm calc define & declaration
*
* @version ref gh3x2x_demo_algorithm_calc.h
*
*/
#ifndef _GH3X2X_DEMO_ALGORITHM_CALC_H_
#define _GH3X2X_DEMO_ALGORITHM_CALC_H_
#include "gh3x2x_demo_algo_config.h"
#include "gh3x2x_demo_algo_call.h"
#include "gh3x2x_demo_algo_hook.h"
#include "gh3x2x_demo_common.h"
/// algorithm calculate hook type
typedef GS8 (*pfnAlgorithmCallFunc)(const STGh3x2xFrameInfo * const pstFrameInfo);
extern STGh3x2xFrameInfo ** g_pstGh3x2xAlgoFrameInfo;
#define GOODIX_HR_PARAMS_NUM_MAX (10)
#define GOODIX_HRV_PARAMS_NUM_MAX (5)
#define GOODIX_SPO2_PARAMS_NUM_MAX (26)
#define GOODIX_ECG_PARAMS_NUM_MAX (5)
#define GOODIX_BT_PARAMS_NUM_MAX (20)
#define GOODIX_AF_PARAMS_NUM_MAX (2)
#define GH3X2X_RAWDATA_BASE_VALUE (1<<23)
#define GH3X2X_GAIN_VALUE_INVALID (0xFF)
/// xor val for xor num in encrypt & decrypt
#define GH3X2X_CRYP_XOR_XOR_VAL (0xFF)
/// fixed val in encrypt & decrypt
#define GH3X2X_CRYP_FIXED_VAL (0x55)
/// header len in encrypt & decrypt
#define GH3X2X_CRYP_HEADER_LEN (5u)
/// cryp rawdata len to index
#define GH3X2X_ENCRYPT_LEN2INDEX (1u)
/* encrypt & decrypt header index */
#define GH3X2X_CRYP_HEADER_0 (0u) /**< cryp header index 0 */
#define GH3X2X_CRYP_HEADER_1 (1u) /**< cryp header index 1 */
#define GH3X2X_CRYP_HEADER_2 (2u) /**< cryp header index 2 */
#define GH3X2X_CRYP_HEADER_3 (3u) /**< cryp header index 3 */
#define GH3X2X_CRYP_HEADER_4 (4u) /**< cryp header index 4 */
/// encrypt data min len, min len is 4
#define GH3X2X_ENCRYPT_CHECK_MIN_LEN(x) ((x) > 3)
/// encrypt source add magic bytes, add after source buffer & len must >= 4, magic bytes len align to cryp header len
#define GH3X2X_ENCRYPT_SRC_ADD_MAGIC(src, len) do {\
(src)[(len)] = ((src)[0] ^ (src)[(len) - 1]);\
(src)[(len) + 1] = ((src)[1] ^ (src)[(len) - 3]);\
(src)[(len) + 2] = GH3X2X_CRYP_FIXED_VAL;\
(src)[(len) + 3] = ((src)[2] ^ (src)[(len) - 2]);\
(src)[(len) + 4] = ((src)[3] ^ (src)[(len) - 4]);\
} while (0)
/// encrypt source verify magic bytes, add after source buffer & len must >= 4
#define GH3X2X_ENCRYPT_VERIFY_SRC_MAGIC(src, len) (((src)[(len)] == ((src)[0] ^ (src)[(len) - 1])) &&\
((src)[(len) + 1] == ((src)[1] ^ (src)[(len) - 3])) &&\
((src)[(len) + 2] == GH3X2X_CRYP_FIXED_VAL) &&\
((src)[(len) + 3] == ((src)[2] ^ (src)[(len) - 2])) &&\
((src)[(len) + 4] == ((src)[3] ^ (src)[(len) - 4])))
/// hba scenario mcaro max val
#define GH3X2X_HBA_SCENARIO_CONFIG_MAX_VAL (HBA_SCENES_SIZE)
/* rawdata package for algorithm */
#define GH3X2X_ALGO_RAW_GX_INDEX (0u) /**< rawdata gsensor x-asix index */
#define GH3X2X_ALGO_RAW_GY_INDEX (1u) /**< rawdata gsensor y-asix index */
#define GH3X2X_ALGO_RAW_GZ_INDEX (2u) /**< rawdata gsensor z-asix index */
#define GH3X2X_ALGO_RAW_CH0_INDEX (3u) /**< rawdata ch0 data index */
#define GH3X2X_ALGO_RAW_CH1_INDEX (4u) /**< rawdata ch1 data index */
#define GH3X2X_ALGO_RAW_CH2_INDEX (5u) /**< rawdata ch2 data index */
#define GH3X2X_ALGO_RAW_CH3_INDEX (6u) /**< rawdata ch3 data index */
#define GH3X2X_ALGO_RAW_CH4_INDEX (7u) /**< rawdata ch4 data index */
#define GH3X2X_ALGO_RAW_CH5_INDEX (8u) /**< rawdata ch5 data index */
#define GH3X2X_ALGO_RAW_CH6_INDEX (9u) /**< rawdata ch6 data index */
#define GH3X2X_ALGO_RAW_CH7_INDEX (10u) /**< rawdata ch7 data index */
#define GH3X2X_ALGO_RAW_CH8_INDEX (11u) /**< rawdata ch8 data index */
#define GH3X2X_ALGO_RAW_CH9_INDEX (12u) /**< rawdata ch9 data index */
#define GH3X2X_ALGO_RAW_CH10_INDEX (13u) /**< rawdata ch10 data index */
#define GH3X2X_ALGO_RAW_CH11_INDEX (14u) /**< rawdata ch11 data index */
#define GH3X2X_ALGO_RAWDATA_LEN (35u) /**< rawdata packet len for algorithm */
/// algorithm channel max cnt support
#define GH3X2X_CHANNEL_MAP_MAX_CNT (32u)
/// get slot & adc num from rawdata flag byte, equal channel map formats
#define GH3X2X_CHANNEL_MAP_GET(x) ((x) & GH3X2X_SLOT_ADC_NUM_BITS)
/// channel map invalid val
#define GH3X2X_CHANNEL_MAP_INVALID_VAL (0x07)
/// channel map is ecg channel
#define GH3X2X_CHANNEL_MAP_ISNOT_ECG_CH(x) (GH3X2X_CHECK_BIT_NOT_SET((x), GH3X2X_CHANNEL_MAP_ADC3))
/// algorithm output GF32 to GS32, multiply by (100)
#define GH3X2X_ALGORITHM_GF32_2_GS32(x) ((GS32)((x) * 100))
/// rawdata is new sampling data
#define GH3X2X_IS_NEW_RAWDATA (1)
/// rawdata is new sampling data
#define GH3X2X_IS_NOT_NEW_RAWDATA (0)
/// number of ECG algorithm output
#define GH3X2X_ECG_ALGO_OUTPUT_NUM (sizeof(STEcgAlgoResult))
/// number of spo2 algorithm output
#define GH3X2X_SPO2_ALGO_OUTPUT_NUM (sizeof(STSpo2AlgoResult))
/// number of hb algorithm output
#define GH3X2X_HB_ALGO_OUTPUT_NUM (sizeof(STHbAlgoResult))
/// number of hrv algorithm output
#define GH3X2X_HRV_ALGO_OUTPUT_NUM (sizeof(STHrvAlgoResult))
/// memory for algorithm is not inited
#define ALGO_MEM_NO_INIT (0)
/// memory for algorithm is already inited
#define ALGO_MEM_INIT_OK (1)
// algo chnl map num
#define ALGO_CHNL_NUM (32)
// algo green chnl pos
#define ALGO_GREEN_CHNL_POS (0)
// algo ir chnl pos
#define ALGO_IR_CHNL_POS (8)
// algo red chnl pos
#define ALGO_RED_CHNL_POS (16)
/* ecg algorithm */
// ECG 采样率
#ifndef ECG_FS
#define ECG_FS 500
#endif
#define ECG_OUT_FACTOR (100)
#define ECG_SNR_FACTOR (10000000)
#define ECG_FRAME_UNUSED (5)
#define GH3X2X_REG_IS_VIRTUAL0X3_BIT (0x3000)
#define GH3X2X_VREG_FUNCTION_OFFSET (0X0300)
#define GH3X2X_ADT_DRV_CFG_ADDR (0x3000)
#define GH3X2X_ADT_ALG_CFG_ADDR (0x30C0)
#define GH3X2X_REG_ADDR_SIZE (0x0002) /**< reg addr size */
#define GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET (0X0200)
#define GH3X2X_HR_SCENARIO_CFG_L_ADDR (0x33C0)
#define GH3X2X_HR_ALGO_CHNL_NUM_ADDR (0x35C0)
#define GH3X2X_SPO2_ALGO_CHNL_NUM_ADDR (0x44C0)
#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR4_H_ADDR (0x430E)
#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR0_L_ADDR (0x42C0)
#define GH3X2X_HSM_FLAG_BUFF_LEN (120)
typedef enum
{
ADT_ALGO_RESULT_DEFULT = 0,
ADT_ALGO_RESULT_WAER_ON, /**< detect wear on */
ADT_ALGO_RESULT_WAER_OFF,
} EMAdtAlgoStatus;
/**
* @brief gh3x2x algo function id
*/
typedef enum
{
GH3X2X_ALGO_INIT_FUNCTION = 0,
GH3X2X_ALGO_CALCULATE_FUNCTION,
// GH3X2X_ALGO_FINAL_CALCULATE_FUNCTION,
GH3X2X_ALGO_DEINIT_FUNCTION,
GH3X2X_ALGO_FUNCTION_NUM_MAX,
} EMAlgoFunctionID;
// algo chnl map struct
typedef struct
{
GU8 uchFlag;
GU8 uchNum;
GU8 uchEcgAlgoChnlMap;
GU8 uchAlgoChnlMap[ALGO_CHNL_NUM];
} STAlgoChnlMap;
typedef struct
{
GS32 nHbaScenario;
GS32 nHbaCalcOutputTime;
GS32 nFrequency;
}STAlgoHrParas;
/* hb algorithm */
#if (__USE_GOODIX_HR_ALGORITHM__)
extern GS32 g_unHrParamsArr[GOODIX_HR_PARAMS_NUM_MAX];
/// hbd rawdata channel map
extern STAlgoChnlMap g_stHbaAlgoChnlMap;
#endif
/* hrv algorithm */
#if (__USE_GOODIX_HRV_ALGORITHM__)
extern GS32 g_nHrvParamsArr[GOODIX_HRV_PARAMS_NUM_MAX];
#endif
/* spo2 algorithm */
#if (__USE_GOODIX_SPO2_ALGORITHM__)
extern GS32 g_nSpo2ParamssArr[GOODIX_SPO2_PARAMS_NUM_MAX];
/// spo2 rawdata channel map
extern STAlgoChnlMap g_stSpo2AlgoChnlMap;
#endif
/* ecg algorithm */
#if (__USE_GOODIX_ECG_ALGORITHM__)
extern GS32 g_nEcgParamsArr[GOODIX_ECG_PARAMS_NUM_MAX];
/// ecg frame data cnt
extern GU32 g_unEcgFrameCnt;
extern GU8 g_uchClassificationFlag;
extern GU8 g_unEcgTimeSeconds;
#endif
/* bt algorithm */
#if (__USE_GOODIX_BT_ALGORITHM__)
extern GS32 g_nBtParamsArr[GOODIX_BT_PARAMS_NUM_MAX];
#endif
/* af algorithm */
#if (__USE_GOODIX_AF_ALGORITHM__)
extern GS32 g_nAfParamsArr[GOODIX_AF_PARAMS_NUM_MAX];
#endif
extern GU8 g_uchAlgoGsensorEnable;
extern GU8 g_uchAlgoCapEnable;
extern GU8 g_uchAlgoTempEnable;
extern GU8 GH3X2X_GetAlgoMemStatus(void);
/**
* @fn GS8 GH3X2X_AlgoMemInit(void)
*
* @brief algorithm memory init
*
* @attention None
*
* @param[in] None
* @param[out] None
*
* @return error code
* @retval #GH3X2X_RET_OK return successfully
* @retval #GH3X2X_RET_RESOURCE_ERROR return algorithm mem init error
*/
GS8 GH3X2X_AlgoMemInit(void);
/**
* @fn void GH3X2X_AlgoMemDeinit(void)
*
* @brief algorithm memory deinit
*
* @attention None
*
* @param[in] None
* @param[out] None
*
* @return None
*/
void GH3X2X_AlgoMemDeinit(void);
/**
* @fn void GH3X2X_SetNewDataFlag(EMChannelMapId emFuncId, GU8 uchFlag)
*
* @brief Set new sampling data flag
*
* @attention None
*
* @param[in] emFuncId function id
* @param[in] uchFlag new data or not
* @param[out] None
*
* @return None
*/
void GH3X2X_SetNewDataFlag(GU8 emFuncId, GU8 uchFlag);
extern void Gh3x2xOutputValueStrategyInit(GU32 unFunctionID);
extern void GH3x2xSleepFlagSet(GU8 uchSleepFlag);
extern GU8 GH3x2xSleepFlagGet(void);
extern GS32 GH3x2x_Round(GF32 fValue);
extern GU8 GH3x2x_BitCount(GU32 n);
extern void GH3X2X_LoadGoodixAlgoRegConfigArr(const STGh3x2xInitConfig *pstGoodixAlgoCfgListArr);
extern GU8* GH3x2xAdtVersion(void);
extern GS8 GH3x2xAdtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAdtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHrAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHrAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHrAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern void GH3X2X_HbaAlgoChnlMapDefultSet(void);
extern void Gh3x2xHrOutputValueStrategyPro(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);
extern GS8 GH3x2xHrvAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHrvAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHrvAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xSpo2AlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xSpo2AlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xSpo2AlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern void GH3X2X_Spo2AlgoChnlMapDefultSet(void);
extern GS8 GH3x2xAfAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAfAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAfAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAfAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAfAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xAfAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xRespAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xRespAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xRespAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xBtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xBtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xBtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHsmAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHsmAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xHsmAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xSoftAdtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xSoftAdtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xSoftAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xEcgAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xEcgAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GS8 GH3x2xEcgAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);
extern GU8 GH3x2xEcgAlgoClassification(void);
#endif /* _GH3X2X_DRV_ALGORITHM_CALC_H_ */
/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/

Some files were not shown because too many files have changed in this diff Show More