#ifdef SUPPORT_AT_GYRO\r
#include "gyro_at_cmd.h"\r
#endif\r
+#ifdef SUPPORT_AT_BP\r
+#include "bp_at_cmd.h"\r
+#endif\r
static void register_at_service(void)\r
{\r
#ifdef SUPPORT_AT_GRAPHIC\r
at_cmd_table_t *gyro_table = get_gyro_cmd_table(&gyro_cmd_count);\r
at_cmd_add_moudle(gyro_table, gyro_cmd_count);\r
#endif\r
+#ifdef SUPPORT_AT_BP\r
+ uint32_t bp_cmd_count;\r
+ at_cmd_table_t *bp_table = get_bp_cmd_table(&bp_cmd_count);\r
+ at_cmd_add_moudle(bp_table, bp_cmd_count);\r
+#endif\r
}\r
\r
#ifdef CONFIG_OTA_UPDATE_SUPPORT\r
#include "lqbp_service.h"\r
#endif\r
\r
+#ifdef ENABLE_BN02\r
+#include "bp_service.h"\r
+#endif\r
+\r
#define EMMC_BASE_ADDR 0x52062000\r
#define TASK_PRIORITY_APP (osPriority_t)(17)\r
#define TICK_TEN_MS (10U)\r
#endif\r
\r
#ifdef ENABLE_CUSTOM_I2C\r
-\r
-#ifdef ENABLE_HP4507\r
-#ifdef BOARD_L22\r
-#define HP4570_I2C_BUS I2C_BUS_0\r
-#elif defined BOARD_U8\r
-#define HP4570_I2C_BUS I2C_BUS_3\r
-#endif\r
- custom_i2c_init(HP4570_I2C_BUS);\r
-#endif\r
+ custom_i2c_init(I2C_BUS_3);\r
+ custom_i2c_init(I2C_BUS_0);\r
custom_i2c_init(I2C_BUS_2);\r
\r
#ifdef MAG_MMC5603\r
uapi_lqbp_service_init();\r
#endif \r
\r
+#ifdef ENABLE_BN02\r
+ uapi_bp_service_init();\r
+#endif\r
+\r
#endif\r
\r
/*启动蓝牙ble服务,cywee有重置 mac地址的操作,会需要把 蓝牙服务开启放在cywee服务之后*/\r
'FT_SINGLE_UART',
# 'WEARABLE_LOG_DEBUG',
'SUPPORT_RC_CALIBRATION',
- 'PPG_HX3695',
+ #'PPG_HX3695',
'VIB_USE_PWM',
'CONFIG_PWM_SUPPORT',
# 'ACC_LIS2DOC',
'NANDFLASH_F35UQA',
#'BLE_INSTRUCT',
'FACTORYTEST_SERVICE',
+ 'PPG_GH3X2X',
],
'ram_component': [
#'baidumapsdk',
"factorytest_service",
"hid_service",
"producttest",
- "cywee"
+ "cywee",
+ "ppg_sensor_gh3x2x",
+ "bp_sensor",
],
'image_analysis': False,
'fs_image_path':'evb',
#include "gpio_porting.h"
#include "platform_types.h"
+#ifdef ENABLE_BN02
+extern void bp_int_callback(pin_t pin, uintptr_t param);
+#endif
+
/**
* @addtogroup connectivity_config_boards
* @{
{ HAL_PIO_FUNC_SPI1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_ENBALE }, // S_MGPIO9 SPI1 CS0
{ HAL_PIO_FUNC_SPI1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO10 SPI1 CS1 NC
- { HAL_PIO_FUNC_I2C0_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO11 i2c0 SCL NC
- { HAL_PIO_FUNC_I2C0_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO12 I2C0 SDA
+ { HAL_PIO_FUNC_I2C0_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO11 i2c0 SCL NC
+ { HAL_PIO_FUNC_I2C0_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO12 I2C0 SDA
{ HAL_PIO_FUNC_I2C1_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO13 I2C1 SCL touch i2c
{ HAL_PIO_FUNC_I2C1_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO14 I2C1 SDA
#ifdef BOARD_W9
// #else
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚
// #endif
- { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_AGPIO_R3 NC
+ { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_AGPIO_R3 NC
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_DISABLE }, // S_AGPIO_R4 tp reset
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_R5 touch int
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_R6 PRG_INT 心率中断
/**S_AGPIO_L32 GPO gps reset*/
// { S_AGPIO_L32, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
#endif
+#ifdef ENABLE_BN02
+ { S_AGPIO_R3, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_FALLING_EDGE, bp_int_callback },
+#endif
};
/**
* @}
{HAL_CLOCKS_APP_SPI2_MS_CLK, TURN_OFF}, // spi2 clock\r
{HAL_CLOCKS_APP_UART_H0_CLK, TURN_ON}, // uart h0 clock\r
{HAL_CLOCKS_APP_UART_H1_CLK, TURN_ON}, // uart h1 clock\r
+#ifdef ENABLE_BN02\r
+ {HAL_CLOCKS_APP_I2C0_CLK, TURN_ON}, // i2c0 clock\r
+#else\r
{HAL_CLOCKS_APP_I2C0_CLK, TURN_OFF}, // i2c0 clock\r
+#endif\r
{HAL_CLOCKS_APP_I2C1_CLK, TURN_ON}, // i2c1 clock\r
{HAL_CLOCKS_APP_I2C2_CLK, TURN_ON}, // i2c2 clock\r
{HAL_CLOCKS_APP_I2C3_CLK, TURN_ON}, // i2c3 clock\r
#endif
#include "pm_veto.h"
#include "pm.h"
+#ifdef PPG_VC9202
+ #include "vc9202_user.h"
+#endif
#ifdef __cplusplus
#if __cplusplus
}
static bool button_falg=true;
void testhrsenson1View:: setgrayvalue(int g,int r,int ir)
{
-
+#ifdef PPG_HX3695
if(label_hrsenson_value_vison!=NULL)
{
send_ppg_cmd_msg(md);
button_falg=true;
}
-
+#endif
}
void testhrsenson1View:: setlightvalue(int g,int r,int ir)
{
-
+ char buf[124]={0};
+
if(label_hrsenson_value_vison!=nullptr)
{
- char buf[124]={0};
+#ifdef PPG_HX3695
sprintf(buf,"leaklight:\ngreen:%d\nred:%d\nir:%d",g,r,ir);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s",buf);
label_hrsenson_value_vison->SetText(buf);
RootView::GetInstance()->Invalidate();
int8_t md = PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST;
send_ppg_cmd_msg(md);
- button_falg=true;
- }
-
+ button_falg=true;
+#elif defined PPG_VC9202
+ //漏光测试
+ // send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST);
+ LOS_Msleep(500);
+ uint32_t led_cur = 0;
+ uint32_t apre_val = 0;
+ uint32_t aps_val = 9;
+ vc9202_get_leaklight_data(&led_cur,&apre_val,&aps_val);
+ send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);
+ sprintf(buf,"leaklight:\ngreen:%d\nred:%d\nir:%d",led_cur,apre_val,aps_val);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s",buf);
+ label_hrsenson_value_vison->SetText(buf);
+ RootView::GetInstance()->Invalidate();
+ button_falg=true;
+#endif
+ }
}
UILabelButtonExt *testhrsenson1View::SetTheButton_ext(ButtonConfig_ext_t &buttonconfig)
int8_t md = PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST;
send_ppg_cmd_msg(md);
button_falg=false;
+#ifdef PPG_VC9202
+ testhrsenson1View::setlightvalue(0,0,0);
+#endif
}
+
}
UILabel *testhrsenson1View::InitLabel(LabelConfig &labelConfig)
add_subdirectory_if_exist(acc)
add_subdirectory_if_exist(mag)
add_subdirectory_if_exist(ppg)
-add_subdirectory_if_exist(ppg/vc9202)
-add_subdirectory_if_exist(ppg/vc921x)
add_subdirectory_if_exist(vibrator)
add_subdirectory_if_exist(slip)
add_subdirectory_if_exist(slip/cat1Service)
add_subdirectory_if_exist(charge)
add_subdirectory_if_exist(charge/hp4570)
add_subdirectory_if_exist(gyro)
+add_subdirectory_if_exist(bp)
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "bp_sensor")
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/bn02/bn02.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/bp_at_cmd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/bp_service.c
+)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/bn02/
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/
+
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+ TARGET_NAME="${TARGET_COMMAND}"
+ BUILD_TIME="${BUILD_TIME}"
+)
+
+set(PUBLIC_DEFINES
+SUPPORT_AT_BP
+ENABLE_BN02
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-16 12:35:15\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-01-17 14:35:00\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/bn02/bn02.c\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#include "stdint.h"\r
+#include "bn02.h"\r
+#include "custom_utils.h"\r
+#include "pinctrl_porting.h"\r
+#include "hal_gpio.h"\r
+#include "i2c.h"\r
+\r
+#define BN02_I2C_ADDR 0x05\r
+#define BN02_I2C_BUS I2C_BUS_0\r
+#define I2C_ADDR_BN02_W 0x0a\r
+#define I2C_ADDR_BN02_R 0x0b\r
+#define P_EN S_AGPIO_L24\r
+#define P_INT S_AGPIO_R3\r
+\r
+#define POWER_EN S_AGPIO_R0\r
+\r
+bool Bn02_write_reg(uint8_t data)\r
+{\r
+ i2c_data_t i2c_data;\r
+ i2c_data.send_buf = &data;\r
+ i2c_data.send_len = sizeof(data);\r
+ i2c_data.receive_buf = NULL;\r
+ i2c_data.receive_len = 0;\r
+ // custom_i2c_write_reg(BN02_I2C_ADDR, 0x00, 1, &data, 1, BN02_I2C_BUS);\r
+ errcode_t ret = uapi_i2c_master_write(BN02_I2C_BUS, BN02_I2C_ADDR, &i2c_data);\r
+ if (ret != ERRCODE_SUCC)\r
+ printf("i2c Write data write fail! ret=0x%x\n", ret);\r
+\r
+ return 1;\r
+}\r
+\r
+bool Bn02_reads(uint8_t *data,int len)\r
+{\r
+ i2c_data_t i2c_data;\r
+ i2c_data.send_buf = NULL;\r
+ i2c_data.send_len = 0;\r
+ i2c_data.receive_buf = data;\r
+ i2c_data.receive_len = len;\r
+ // custom_i2c_write_reg(BN02_I2C_ADDR, 0x00, 1, &data, 1, BN02_I2C_BUS);\r
+ errcode_t ret = uapi_i2c_master_read(BN02_I2C_BUS, BN02_I2C_ADDR, &i2c_data);\r
+ if (ret != ERRCODE_SUCC) \r
+ printf("i2c read data fail! ret=0x%x\n", ret);\r
+\r
+ return 1;\r
+}\r
+\r
+static void delay_ms(int cnt)\r
+{\r
+ LOS_Mdelay(cnt);\r
+}\r
+\r
+void Bn02_Power_Ctrl(int onoff)\r
+{\r
+ if(onoff == 1)\r
+ {\r
+ uapi_pin_set_mode(POWER_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(POWER_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(POWER_EN, GPIO_LEVEL_HIGH);\r
+ LOS_Mdelay(1);\r
+ uapi_pin_set_mode(P_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(P_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(P_EN, GPIO_LEVEL_HIGH);\r
+ // delay_ms(20);\r
+ LOS_Mdelay(50);\r
+ }\r
+ else\r
+ {\r
+ uapi_pin_set_mode(P_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(P_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(P_EN, GPIO_LEVEL_LOW);\r
+\r
+ uapi_pin_set_mode(POWER_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(POWER_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(POWER_EN, GPIO_LEVEL_LOW);\r
+ }\r
+}\r
+\r
+void bn02_int_handle(void)\r
+{\r
+ uint8_t bn02_buf[48] = {0};\r
+ int i;\r
+ memset(bn02_buf,0,sizeof(bn02_buf));\r
+ Bn02_reads(bn02_buf,48);\r
+ for(i = 0;i<48;i++)\r
+ {\r
+ printf("[%d]= 0x%x\n",i,bn02_buf[i]);\r
+ }\r
+}\r
+\r
+void bn02_start(void)\r
+{\r
+ Bn02_Power_Ctrl(1);\r
+ Bn02_write_reg(BN02_START_CMD);\r
+}\r
+\r
+void bn02_stop(void)\r
+{\r
+ Bn02_write_reg(BN02_STOP_CMD);\r
+ Bn02_Power_Ctrl(0);\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-16 12:35:15\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-01-16 14:55:48\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/bn02/bn02.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#ifndef _BN02_H_\r
+#define _BN02_H_\r
+\r
+enum\r
+{\r
+\r
+ BN02_INT_HANDLE,\r
+ BN02_INIT_ENABLE,\r
+ BN02_START,\r
+ BN02_POWER_DISABLE,\r
+ BN02_STOP,\r
+};\r
+\r
+#define BN02_START_CMD 0x04\r
+#define BN02_STOP_CMD 0x08\r
+\r
+void bn02_int_handle(void);\r
+\r
+void bn02_start(void);\r
+\r
+void bn02_stop(void);\r
+\r
+#endif // _HRS3300_H_\r
+\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-23 15:11:01
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-16 18:02:23
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/HP4570/service/bp_at_cmd.c
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "debug_print.h"
+#include "bp_service.h"
+#include "custom_utils.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define BP_MAX_ARGC 8
+#define BP_MAX_ARGV_LEN 64
+
+#define BP_SUCCESS 0
+#define BP_FAILED (-1)
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[BP_MAX_ARGC][BP_MAX_ARGV_LEN], uint32_t* argc)
+{
+ uint32_t pos = 0;
+ *argc = 0;
+
+ for (uint32_t i = 0; i < paraLen; i++) {
+ if ((para[i] == ' ' || para[i] == '\n') && pos != 0) {
+ argv[*argc][pos] = '\0';
+ *argc += 1;
+ pos = 0;
+ if (*argc >= BP_MAX_ARGC) {
+ return BP_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= BP_MAX_ARGV_LEN) {
+ return BP_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return BP_SUCCESS;
+}
+
+static uint8_t g_bp_test_started = 0;
+static uint32_t bn02_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t argv[BP_MAX_ARGC][BP_MAX_ARGV_LEN] = { 0 };
+ uint32_t argc = 0;
+
+ int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+ if (ret != BP_SUCCESS) {
+ PRINT("BPTEST ATCMD Convert Command Failed\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc != 1) {
+ PRINT("BPTEST ATCMD Set Parameter Failed argc %d\n",argc);
+ return ERRCODE_FAIL;
+ }
+ uint8_t start = (uint8_t)atoi((char*)argv[0]);
+ if (start == 1)
+ {
+ // if (g_bp_test_started == 1)
+ // {
+ // PRINT("SKIP bptest start, already start\r\n");
+ // return 0;
+ // }
+ do_bp_service_check_msg(BP_SERVICE_CMD_START_CHECK);
+ g_bp_test_started = 1;
+ }else if (start == 2){
+ // if (g_bp_test_started == 0)
+ // {
+ // PRINT("SKIP bptest stop, already stopped\r\n");
+ // return 0;
+ // }
+ do_bp_service_check_msg(BP_SERVICE_CMD_STOP_CHECK);
+ g_bp_test_started = 0 ;
+ }else if (start == 3){
+ // if (g_bp_test_started == 0)
+ // {
+ // PRINT("SKIP bptest stop, already stopped\r\n");
+ // return 0;
+ // }
+ do_bp_service_check_msg(BP_SERVICE_CMD_TIMER_CHECK);
+ g_bp_test_started = 0 ;
+ }else{
+ }
+ return ERRCODE_SUCC;
+}
+static const at_cmd_table_t g_bp_cmd[] = {
+ { (char *)"AT^BN02TEST", bn02_test, (char *)"1" },
+};
+
+at_cmd_table_t *get_bp_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_bp_cmd);
+ return (at_cmd_table_t *)g_bp_cmd;
+}
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-18 10:23:22
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-16 15:07:33
+ * @FilePath: /sdk615/code/sdk/drivers/peripheral/rotary_encoder/hx3509/hx3509_at_cmd.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef BP_AT_PROCESS_H
+#define BP_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_bp_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+#include "pinctrl.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+
+#include "tcxo.h"
+
+#include "cmsis_os2.h"
+#include "input_app.h"
+#include "bp_service.h"
+#include "custom_utils.h"
+#include "bn02.h"
+// #include "custom_runtime.h"
+/***
+ * 其他cmd在Header里定义,对外开放
+*/
+
+#define BP_CHECK_MS 40
+
+osTimerId_t g_bp_service_timer = NULL;
+
+static bool g_bp_sensor_exist = false;
+
+static bool g_bat_timer_is_running = false;
+
+static unsigned long g_app_queue= 0xFFFFFFFF;
+
+static bool bp_service_running_stat = false;
+
+void do_bp_service_check_msg(int cmd);
+
+static void bp_service_check_timer_callback(void* data)
+{
+ do_bp_service_check_msg(BP_SERVICE_CMD_TIMER_CHECK);
+}
+
+void do_bp_service_check_msg(int cmd)
+{
+ int ret;
+ if (g_bp_sensor_exist == false)
+ return ;
+ common_notify_mail_t mail = {0};
+ mail.comm.app = cmd;
+ ret = osal_msg_queue_write_copy(g_app_queue, (void *)&mail,
+ sizeof(common_notify_mail_t), 0);
+ if (ret != OSAL_SUCCESS) {
+ PRINT("Error bp Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret);
+ }
+
+}
+
+static void bp_service_check_task(void const *arg)
+{
+ unused(arg);
+ int32_t ret;
+ common_notify_mail_t mail;
+ uint32_t msgsize = (uint32_t)sizeof(common_notify_mail_t);
+ while (1) {
+ ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize,
+ OSAL_MSGQ_WAIT_FOREVER);
+ if (ret != OSAL_SUCCESS) {
+ continue;
+ }
+ if (mail.comm.app == BP_SERVICE_CMD_TIMER_CHECK) {
+ PRINT("bn02_int_handle \n");
+ bn02_int_handle();
+ }else if (mail.comm.app == BP_SERVICE_CMD_START_CHECK){
+ PRINT("bn02_start \n");
+ bn02_start();
+ if(g_bp_service_timer)
+ osTimerStart(g_bp_service_timer,150);
+ }else if (mail.comm.app == BP_SERVICE_CMD_STOP_CHECK){
+ PRINT("bn02_stop \n");
+ bn02_stop();
+ if(g_bp_service_timer)
+ osTimerStop(g_bp_service_timer);
+ }
+ }
+}
+void create_bp_queue(void)
+{
+
+ if (osal_msg_queue_create("bp_service_queue", APP_BOARD_MSG_COUNT, &g_app_queue,
+ 0, sizeof(common_notify_mail_t)) != ERRCODE_SUCC) {
+ PRINT("[bp][service] app create mail fail\n");
+ }
+}
+
+#define BP_BOARD_TASK_SIZE 0x1000
+errcode_t uapi_bp_service_init(void)
+{
+ PRINT("uapi_bp_service_init !\r\n");
+
+ g_bp_sensor_exist = true;
+
+ app_task_definition_t taskcfg={0};
+ taskcfg.create_queue_handle = create_bp_queue;
+ taskcfg.attr.name="bp_service";
+ taskcfg.attr.priority = osPriorityBelowNormal4;
+ taskcfg.attr.stack_size = BP_BOARD_TASK_SIZE;
+ taskcfg.func = bp_service_check_task;
+ taskcfg.use_mem = USE_EXTEND_MEM;
+
+ errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+ if(ret != ERRCODE_SUCC)
+ {
+ PRINT("create bp_service failed %d!\r\n",ret);
+ return ERRCODE_FAIL;
+ }
+
+ // g_bp_service_timer = osTimerNew((osTimerFunc_t)bp_service_check_timer_callback, osTimerPeriodic, NULL, NULL);
+
+ return ERRCODE_SUCC;
+}
+
+void bp_int_callback(pin_t pin, uintptr_t param)
+{
+ PRINT("bp_int_callback %d 0x%X\n",pin,param);
+ uapi_gpio_clear_interrupt(pin);
+ do_bp_service_check_msg(BP_SERVICE_CMD_TIMER_CHECK);
+}
+
+// void bp_service_service_resume(void)
+// {
+// MMC_LOG("bp_service_service resume!\r\n");
+// bp_service_check_timer_callback(0);
+// }
+// void bp_service_service_suspend(void)
+// {
+// MMC_LOG("bp_service_service suspend!\r\n");
+// }
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-23 15:11:01
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-16 17:39:43
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/charge/HP4570/service/charge_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Test adc header \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-08-16, Create file. \n
+ */
+
+#ifndef BP_SERVICE_H__
+#define BP_SERVICE_H__
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+
+#define BP_SERVICE_CMD_START_CHECK 0x12
+#define BP_SERVICE_CMD_STOP_CHECK 0x13
+#define BP_SERVICE_CMD_TIMER_CHECK 0x11
+
+errcode_t uapi_bp_service_init(void);
+void bp_int_callback(pin_t pin, uintptr_t param);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
set(PUBLIC_DEFINES
SUPPORT_AT_CHARGE
+ENABLE_HP4507
)
# use this when you want to add ccflags like -include xxx
* @Author: penglei 1624952103@qq.com
* @Date: 2024-12-18 10:23:22
* @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2024-12-24 17:58:19
+ * @LastEditTime: 2025-01-16 15:07:23
* @FilePath: /sdk615/code/sdk/drivers/peripheral/rotary_encoder/hx3509/hx3509_at_cmd.h
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
* History: \n
* 2022-07-20, Create file. \n
*/
-#ifndef HX3509_AT_PROCESS_H
-#define HX3509_AT_PROCESS_H
+#ifndef CHARGE_AT_PROCESS_H
+#define CHARGE_AT_PROCESS_H
#include <stdint.h>
#include <stdio.h>
add_subdirectory_if_exist(service)
add_subdirectory_if_exist(hx3695)
-add_subdirectory_if_exist(ppgBleService)
\ No newline at end of file
+add_subdirectory_if_exist(ppgBleService)
+add_subdirectory_if_exist(vc9202)
+add_subdirectory_if_exist(vc921x)
+add_subdirectory_if_exist(gh3x2x)
\ No newline at end of file
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "ppg_sensor_gh3x2x")
+
+if("PPG_GH3X2X" IN_LIST DEFINES)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc
+)
+
+set(SOURCES ${SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_adt.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_agc.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_demo.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_drv.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_lead_off.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_user.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_hal.c
+)
+
+else()
+set(SOURCES ${SOURCES}
+)
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+endif()
+
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
+
--- /dev/null
+#ifndef _GH3X2X_AFE_ADT_H_\r
+#define _GH3X2X_AFE_ADT_H_\r
+#include "gh3x2x_afe_drv.h"\r
+ \r
+\r
+#define __HARD_ADT_WAER_ON_THRD__ 8600000\r
+#define __HARD_ADT_WAER_OFF_THRD__ 8538608\r
+#define __HARD_ADT_WAER_ON_DIFF_THRD__ 100000\r
+\r
+\r
+\r
+typedef enum\r
+{\r
+ WEAR_DETECT_WEAR_ON = 0, /**< detect wear on */\r
+ WEAR_DETECT_WEAR_OFF, /**< detect wear off */\r
+} EMWearDetectType;\r
+\r
+typedef enum\r
+{\r
+ WEAR_STATUS_WEAR_ON = 0, /**< detect wear on */\r
+ WEAR_STATUS_WEAR_OFF, /**< detect wear off */\r
+} EMWearStatus;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+GS8 GH3x2xAdtAlgoInit(void);\r
+GS8 GH3x2xAdtAlgoDeinit(void);\r
+void GH3x2xAdtAlgoExe(GU32* punRawdata,EMWearStatus* pemWearStatus);\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef _GH3X2X_AFE_AGC_H_\r
+#define _GH3X2X_AFE_AGC_H_\r
+#include "gh3x2x_afe_drv.h"\r
+#include <string.h> \r
+\r
+\r
+#define __SUPPORT_SOFT_AGC_CONFIG__ 1\r
+#define GH3X2X_NEW_AGC_SLOT_NUM_LIMIT (8)\r
+#define GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT (32-8)\r
+\r
+#define GH3X2X_LED_AGC_DISABLE (0)\r
+#define GH3X2X_LED_AGC_ENABLE (1)\r
+\r
+\r
+/// led agc adc num max\r
+#define GH3X2X_AGC_ADC_NUM_MAX (4u)\r
+\r
+/// led agc gain limit number\r
+#define GH3X2X_AGC_LIMIT_NUM_MAX (4u)\r
+\r
+/// raw data base line value\r
+#define GH3X2X_DATA_BASE_LINE (8388608) //2^23 \r
+\r
+/// sys sample rate, 32kHz\r
+#define GH3X2X_SYS_SAMPLE_RATE (32000)\r
+ \r
+/* slot register ctrl index */\r
+#define GH3X2X_SLOT_REG_CTRL_0 (0) /**< slot x ctrl 0 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_1 (1) /**< slot x ctrl 1 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_2 (2) /**< slot x ctrl 2 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_3 (3) /**< slot x ctrl 3 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_4 (4) /**< slot x ctrl 4 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_5 (5) /**< slot x ctrl 5 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_6 (6) /**< slot x ctrl 6 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_7 (7) /**< slot x ctrl 7 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_8 (8) /**< slot x ctrl 8 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_9 (9) /**< slot x ctrl 9 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_10 (10) /**< slot x ctrl 10 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_11 (11) /**< slot x ctrl 11 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_12 (12) /**< slot x ctrl 12 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_13 (13) /**< slot x ctrl 13 reg */\r
+\r
+#define GH3X2X_BG_LEVEL_BIT_MASK (0x0030)\r
+#define GH3X2X_ADC_BG_CANCEL_32_UA (0x0)\r
+#define GH3X2X_ADC_BG_CANCEL_64_UA (0x1)\r
+#define GH3X2X_ADC_BG_CANCEL_128_UA (0x2)\r
+#define GH3X2X_ADC_BG_CANCEL_256_UA (0x3)\r
+\r
+/// amb slot select\r
+#define GH3X2X_AGC_AMB_SLOT_DISABLE (0x0)\r
+#define GH3X2X_AGC_AMB_SLOT_USER_DEFINED (0x1)\r
+#define GH3X2X_AGC_AMB_SLOT_FOLLOW_CFG (0x2)\r
+\r
+/// get bits data\r
+#define GH3X2X_GET_REG_BITS_U16(reg_data, lsb, msb) (((reg_data) & ((0xFFFF << (lsb)) & \\r
+ (0xFFFF >> (15 - (msb))))) >> (lsb))\r
+\r
+/// set bits data\r
+#define GH3X2X_SET_REG_BITS_U16(reg, lsb, msb, value) ((reg) = (((reg) & ((0xFFFF << (lsb)) ^ \\r
+ (0xFFFF >> (15 - (msb))))) | ((value) << (lsb))))\r
+\r
+/// get adc gain\r
+#define GH3X2X_GET_ADC_GAIN(reg_data, adc_no) GH3X2X_GET_REG_BITS_U16((reg_data), ((adc_no) * 4), \\r
+ ((adc_no) * 4 + 3))\r
+\r
+/// set adc gain\r
+#define GH3X2X_SET_ADC_GAIN(reg_data, adc_no, gain) GH3X2X_SET_REG_BITS_U16((reg_data), ((adc_no) * 4), \\r
+ ((adc_no) * 4 + 3), (gain))\r
+\r
+/// get bg cancel i_dacfs\r
+#define GH3X2X_GET_BGC_I_DACFS(reg_data, adc_no) GH3X2X_GET_REG_BITS_U16((reg_data), ((adc_no) << 1), \\r
+ ((adc_no) * 2 + 1))\r
+\r
+/// set bg cancel i_dacfs\r
+#define GH3X2X_SET_BGC_I_DACFS(reg_data, adc_no, i_dacfs) GH3X2X_SET_REG_BITS_U16((reg_data), ((adc_no) * 2), \\r
+ ((adc_no) * 2 + 1), (i_dacfs))\r
+ \r
+#define ABS(x) ((x) > 0 ? (x) : -(x))\r
+\r
+/// transfer int to float\r
+#define GH3X2X_TRANS_INT_TO_FLOAT (1.0f)\r
+\r
+/// agc calc seconds (250ms)\r
+#define GH3X2X_AGC_CALC_SECONDS (0.25f)\r
+\r
+/// agc bgc donw cnt, 5s\r
+#define GH3X2X_AGC_BGC_DOWN_CNT (20)\r
+\r
+/// slot tia gain val min\r
+#define GH3X2X_AGC_GAIN_MIN_VAL (0)\r
+\r
+/// slot tia gain val max, 5s, equal (GH3X2X_SLOT_TIA_GAIN_VAL_MAX - 1)\r
+#define GH3X2X_AGC_GAIN_MAX_VAL (12)\r
+\r
+/// Less than thr, include rawdata < thr\r
+#define GH3X2X_AGC_EXCD_FLAG_LESS (0x01)\r
+\r
+/// greater than thr, include rawdatamix > thr | rawdata > thr\r
+#define GH3X2X_AGC_EXCD_FLAG_GREATER (0x06)\r
+\r
+/// AGC failure reason\r
+#define GH3X2X_AGC_FAILURE_REASON_1 (0x1) \r
+#define GH3X2X_AGC_FAILURE_REASON_2 (0x2)\r
+#define GH3X2X_AGC_FAILURE_REASON_4 (0x4)\r
+#define GH3X2X_AGC_FAILURE_REASON_5 (0x5)\r
+#define GH3X2X_AGC_FAILURE_REASON_6 (0x6)\r
+\r
+#define GH3X2X_AGC_CHECK_EN_BITS(x) (((x) & (0x03 << 8)) != 0) /**< check enable bits of ctrl3 */\r
+#define GH3X2X_AGC_GET_SRC_BITS(x) (((x) >> 6) & 0x03) /**< get agc src bits of ctrl3 */\r
+#define GH3X2X_AGC_CHECK_BG_2X2_BITS(x) (((x) & (0x03 << 4)) == 0x03) /**< check 2x2 bg lvl bits of ctrl3 */\r
+#define GH3X2X_AGC_SET_SRC_BITS(x, n) (((x) & 0xFF3Fu) | ((n) << 6u)) /**< set agc src bits of ctrl3 */\r
+\r
+#define GH3X2X_AGC_GET_DONE_FAIL_BIT(x, i) (((x) >> (i)) & 0x01) /**< get tune done/fail bit of flag */\r
+#define GH3X2X_AGC_REG_BIT(x, i) (((x) >> (i)) & 0x01) /**< get reg bit value */\r
+#define GH3X2X_AGC_GET_RESULT_BITS(x, i) (((x) >> (i)) & 0x07) /**< get result bits of flag */\r
+#define GH3X2X_AGC_RESULT_BITS_SIZE (3u) /**< one result 3 bits size of flag */\r
+\r
+#define GH3X2X_FRAME_FLAG_NUM 8\r
+#define GH3X2X_AGC_MAIN_SLOT_NUM 8\r
+\r
+/**\r
+ * @brief soft lead result\r
+ */\r
+typedef struct\r
+{\r
+ GU8 uchAmbSampleEn : 2; /**< AMB sampling enable */\r
+ GU8 uchAmbSlot : 3; /**< slot of amb sampling */\r
+ GU8 uchRes : 3; /**< reserved */\r
+} STAmbSlotCtrl;\r
+ \r
+ /**\r
+ * @brief gain limit\r
+ */\r
+typedef struct\r
+{\r
+ GU8 uchGainLimitBg32uA : 4; /**< gain limit bg current */\r
+ GU8 uchGainLimitBg64uA : 4; \r
+ GU8 uchGainLimitBg128uA : 4; \r
+ GU8 uchGainLimitBg256uA : 4;\r
+} STSoftAgcGainLimit;\r
+\r
+ /**\r
+ * @brief soft agc parameter\r
+ */\r
+typedef struct\r
+{\r
+ GU8 uchSlotxSoftAgcAdjEn; /**< soft agc enable */\r
+ GU8 uchSlotxSoftBgAdjEn; /**< soft bg cancel adjust enable */\r
+ STAmbSlotCtrl stAmbSlotCtrl; /**< amb slot ctrl */\r
+ GU8 uchRes0; /**< reserved */\r
+ GU8 uchSpo2RedSlotCfgEn;\r
+ GU8 uchSpo2IrSlotCfgEn;\r
+ STSoftAgcGainLimit stSoftAgcGainLimit; /**< soft gain limit */\r
+ GU32 unAgcTrigThd_H; /**< trig threshold(high) of soft agc */\r
+ GU32 unAgcTrigThd_L; /**< trig threshold(low) of soft agc */\r
+ GU32 unAgcRestrainThd_H; /**< restrain threshold(high) of soft agc */\r
+ GU32 unAgcRestrainThd_L; /**< restrain threshold(low) of soft agc */\r
+} STSoftAgcCfg;\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+ GU8 uchEnable;\r
+ GU8 uchSpo2ChnlIndex; //0: is not spo2 channel N(N > 0): is spo2 channl \r
+ GU8 uchSlotAdc;\r
+ GU8 uchCurrentTiaGain;\r
+ GU8 uchCurrentDrv;\r
+ GU8 uchTiaGainUpLimit;\r
+ GU8 uchHaveBakRegFlag;\r
+ GU8 uchBakRegAgcEn;\r
+ GU8 uchBakRegAgcSrc;\r
+ GU8 uchBakRegLedCurrentMin;\r
+ GU8 uchBakRegLedCurrentMax;\r
+ GU8 uchBakTiaGain;\r
+} STGh3x2xNewAgcMainChnlInfo;\r
+\r
+typedef struct \r
+{\r
+ GU16 Sat_CheckCnt[GH3X2X_AGC_MAIN_SLOT_NUM]; /* num of data checked*/\r
+ GU16 Sat_cnt[GH3X2X_AGC_MAIN_SLOT_NUM]; /* sat num of each channel*/\r
+ GU8 Sat_flag; /* sat flag one bit each channel*/\r
+} STGh3x2xNewAgcMainChnlSat;\r
+\r
+typedef struct\r
+{\r
+ GU32 unMaxRawdata;\r
+ GU32 unMinRawdata;\r
+ GU32 unSumAdjust; // cacluate drv current and gain\r
+ GU32 unSumTrige; // judge whether AGC\r
+ GU32 unRawdataMean;\r
+ GU32 unLastRawdataMean;\r
+ GU16 usSampleRate;\r
+ GU16 usAnalysisCnt; // numble of nalysis data\r
+ GU8 uchHaveAgcAtLastReadPrd; //0: no agc action at last fifo read period 1: have agc action at last fifo read preiod\r
+ GU8 uchDropFlag;\r
+} STGh3x2xNewAgcMainChnlMeanInfo;\r
+\r
+typedef struct\r
+{\r
+ GU8 uchIniteFirst; // inite first time 0:yes 1:not\r
+ GU8 uchSeconsCnt; // \r
+} STGh3x2xNewAgcMainChnlIdaelAdjInfo;\r
+\r
+typedef struct\r
+{\r
+ GU32 unLastRawdata;\r
+ GU32 unLastLastRawdata;\r
+ GU32 unRawdataSum;\r
+ GU16 usAnalysisCnt;\r
+ GU16 usMoreThanUpLimitPointCnt;\r
+ GU16 usMoreThanUpLimitPointCntForBiggerGain;\r
+ GU16 usTrigeUpLimitForBiggerGain; // rawdate/256\r
+ GU8 uchEn;\r
+ GU8 uchSlotAdcNo;\r
+ GU8 uchCurrentGain;\r
+}STGh3x2xNewAgcSubChnlRxInfo;\r
+\r
+\r
+void GH3X2X_LedAgcReset(void);\r
+void GH3X2X_LedAgcPramWrite(GU16 usRegAddr, GU16 usRegData);\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgc_Close(void);\r
+void GH3X2X_LedAgc_Open(void);\r
+void Gh3x2xNewAgcSubChnlModuleReset(void);\r
+GU8 GH3x2xNewAgcSetNewSubChnl(GU8 uchSlotNo, GU8 uchRxEn, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcPramConfig(STSoftAgcCfg* stSoftAgcCfg);\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef __GH3X2X_AFE_DEMO_H__\r
+#define __GH3X2X_AFE_DEMO_H__\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+/**\r
+ * @brief channel map for function id\r
+ */\r
+#define GH3X2X_FUNC_OFFSET_ADT (0) /**<0 ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HR (1) /**<1 HR FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HRV (2) /**<2 HRV FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HSM (3) /**<3 HSM FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_FPBP (4) /**<4 BPD FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_PWA (5) /**<5 PFA FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SPO2 (6) /**<6 SPO2 FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_ECG (7) /**<7 ECG FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_PWTT (8) /**<8 PWTT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN (9) /**<9 SOFT ADT GREEN FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_BT (10) /**<10 BT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_RESP (11) /**<11 RESP FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_AF (12) /**<12 AF ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_TEST1 (13) /**<13 TEST1 FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_TEST2 (14) /**<14 TEST2 ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SOFT_ADT_IR (15) /**<15 SOFT ADT IR FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_RS0 (16) /**<16 */\r
+#define GH3X2X_FUNC_OFFSET_RS1 (17) /**<17 */\r
+#define GH3X2X_FUNC_OFFSET_RS2 (18) /**<18 */\r
+#define GH3X2X_FUNC_OFFSET_LEAD_DET (19) /**<19 */\r
+#define GH3X2X_FUNC_OFFSET_MAX (20) \r
+\r
+/* Function mode. */\r
+#define GH3X2X_NO_FUNCTION (0) /**<0x00000000 NO function */\r
+#define GH3X2X_FUNCTION_ADT ((0x1) << (GH3X2X_FUNC_OFFSET_ADT)) /**<0x00000001 ADT function */\r
+#define GH3X2X_FUNCTION_HR ((0x1) << (GH3X2X_FUNC_OFFSET_HR)) /**<0x00000002 HR function */\r
+#define GH3X2X_FUNCTION_HRV ((0x1) << (GH3X2X_FUNC_OFFSET_HRV)) /**<0x00000004 HRV function */\r
+#define GH3X2X_FUNCTION_HSM ((0x1) << (GH3X2X_FUNC_OFFSET_HSM)) /**<0x00000008 HSM function */\r
+#define GH3X2X_FUNCTION_FPBP ((0x1) << (GH3X2X_FUNC_OFFSET_FPBP)) /**<0x00000010 FPBP function */\r
+#define GH3X2X_FUNCTION_PWA ((0x1) << (GH3X2X_FUNC_OFFSET_PWA)) /**<0x00000020 PWA function */\r
+#define GH3X2X_FUNCTION_SPO2 ((0x1) << (GH3X2X_FUNC_OFFSET_SPO2)) /**<0x00000040 SPO2 function */\r
+#define GH3X2X_FUNCTION_ECG ((0x1) << (GH3X2X_FUNC_OFFSET_ECG)) /**<0x00000080 ECG function */\r
+#define GH3X2X_FUNCTION_PWTT ((0x1) << (GH3X2X_FUNC_OFFSET_PWTT)) /**<0x00000100 PWTT function */\r
+#define GH3X2X_FUNCTION_SOFT_ADT_GREEN ((0x1) << (GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN)) /**<0x00000200 SOFT ADT GREEN function */\r
+#define GH3X2X_FUNCTION_BT ((0x1) << (GH3X2X_FUNC_OFFSET_BT)) /**<0x00000400 BT function */\r
+#define GH3X2X_FUNCTION_RESP ((0x1) << (GH3X2X_FUNC_OFFSET_RESP)) /**<0x00000800 RESP function */\r
+#define GH3X2X_FUNCTION_AF ((0x1) << (GH3X2X_FUNC_OFFSET_AF)) /**<0x00001000 AF function */\r
+#define GH3X2X_FUNCTION_TEST1 ((0x1) << (GH3X2X_FUNC_OFFSET_TEST1)) /**<0x00002000 TEST1 function */\r
+#define GH3X2X_FUNCTION_TEST2 ((0x1) << (GH3X2X_FUNC_OFFSET_TEST2)) /**<0x00004000 TEST2 function */\r
+#define GH3X2X_FUNCTION_SOFT_ADT_IR ((0x1) << (GH3X2X_FUNC_OFFSET_SOFT_ADT_IR)) /**<0x00008000 SOFT ADT IR function */\r
+#define GH3X2X_FUNCTION_RS0 ((0x1) << (GH3X2X_FUNC_OFFSET_RS0))\r
+#define GH3X2X_FUNCTION_RS1 ((0x1) << (GH3X2X_FUNC_OFFSET_RS1))\r
+#define GH3X2X_FUNCTION_RS2 ((0x1) << (GH3X2X_FUNC_OFFSET_RS2))\r
+#define GH3X2X_FUNCTION_LEAD_DET ((0x1) << (GH3X2X_FUNC_OFFSET_LEAD_DET))\r
+\r
+#define GH3X2X_ADT_FUNC_ENABLE (1)\r
+#define GH3X2X_ECG_FUNC_ENABLE (1)\r
+\r
+#define GH3X2X_ECG_SLOT_NUM (0)\r
+#define GH3X2X_ADT_SLOT_NUM (1)\r
+\r
+#define GH3X2X_ADT_ADC_NUM (0)\r
+\r
+#define GH3X2X_ECG_DOWN_FS (250) //ecg fs:800, 320, 256\r
+#define GH3X2X_ECG_FS (320) //down sample ecg fs: 500 OR 250\r
+#define GH3X2X_PPG_DOWN_FS (250) //down sample ppg fs:\r
+\r
+void GH3X2X_DemoLedAgcPramConfig(void);\r
+\r
+#endif\r
+\r
--- /dev/null
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_drv.h\r
+ *\r
+ * @brief gh3x2x afe driver functions\r
+ *\r
+ * @version v3.2.4.6\r
+ *\r
+ * @author Gooidx Iot Team\r
+ *\r
+ */\r
+#ifndef __GH3X2X_AFE_DRV_H__\r
+#define __GH3X2X_AFE_DRV_H__\r
+\r
+#include "gh3x2x_afe_user.h"\r
+#include "gh3x2x_afe_version.h"\r
+\r
+#ifndef GH3X2X_AFE_UNUSED_VAR\r
+#define GH3X2X_AFE_UNUSED_VAR(X) ((void)(X))\r
+#endif // GH3X2X_AFE_UNUSED_VAR\r
+\r
+\r
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */\r
+ #ifndef __weak\r
+ #define __weak __attribute__((weak))\r
+ #endif /* __weak */\r
+ #ifndef __packed\r
+ #define __packed __attribute__((__packed__))\r
+ #endif /* __packed */\r
+#endif /* __GNUC__ */\r
+\r
+\r
+\r
+\r
+\r
+\r
+/* type redefine */\r
+typedef unsigned char GU8; /**< 8bit unsigned integer type */\r
+typedef signed char GS8; /**< 8bit signed integer type */\r
+typedef unsigned short GU16; /**< 16bit unsigned integer type */\r
+typedef signed short GS16; /**< 16bit signed integer type */\r
+typedef int GS32; /**< 32bit signed integer type */\r
+typedef unsigned int GU32; /**< 32bit unsigned integer type */\r
+typedef float GF32; /**< float type */\r
+typedef double GD64; /**< double type */\r
+typedef char GCHAR; /**< char type */\r
+typedef unsigned char GBOOL; \r
+typedef long long GS64; /**< 64bit signed integer type */\r
+\r
+\r
+\r
+\r
+#define GH3020_ID (0x00)\r
+#define GH3026_ID (0x01)\r
+\r
+#define GH3X2X_MP_DISABLE (0)\r
+#define GH3X2X_MP_ENABLE (1)\r
+\r
+/********************* communication interface type******************************/\r
+#define GH3X2X_AFE_COM_INTERFACE_SPI 0\r
+#define GH3X2X_AFE_COM_INTERFACE_I2C 1\r
+\r
+\r
+/********************* spi type ************************************************/\r
+#define GH3X2X_AFE_SPI_SOFTWARE_CS 0\r
+#define GH3X2X_AFE_SPI_HARDWEAR_CS 1\r
+\r
+\r
+/********************* chip process type ***************************************/\r
+#define GH3X2X_AFE_PRO_BY_INT 0\r
+#define GH3X2X_AFE_PRO_BY_POLLING 1\r
+\r
+/********************* chip reset type ***************************************/\r
+#define GH3X2X_AFE_RESET_HARDWARE 0\r
+#define GH3X2X_AFE_RESET_SOFTWARE 1 \r
+\r
+\r
+\r
+#define GH3X2X_AFE_SPI_CS_CTRL_LOW 0\r
+#define GH3X2X_AFE_SPI_CS_CTRL_HIGH 1\r
+\r
+\r
+\r
+\r
+#define GH3X2X_AFE_CMD_SLEEP 0xC4\r
+#define GH3X2X_AFE_CMD_WAKEUP 0xC3\r
+#define GH3X2X_AFE_CMD_RESET 0xC2\r
+#define GH3X2X_AFE_SPI_CMD_WRITE (0xF0)\r
+#define GH3X2X_AFE_SPI_CMD_READ (0xF1)\r
+\r
+\r
+\r
+#define GH3X2X_AFE_RET_OK (0) /**< there is no error */\r
+#define GH3X2X_AFE_RET_GENERIC_ERROR (-1) /**< a generic error happens */\r
+\r
+// special reg addr\r
+#define GH3X2X_AFE_FIFO_REG_ADDR (0xAAAA) /**< fifo reg addr */\r
+#define GH3X2X_AFE_I2C_CMD_ADDR (0xDDDD) /**< i2c cmd reg addr */\r
+\r
+\r
+#define GH3X2X_AFE_SPI_END_DELAY_X_US (3)\r
+#define GH3X2X_AFE_SPI_WAIT_DELAY_X_US (4)\r
+\r
+#define GH3X2X_AFE_WAKE_UP_CMD_DELAY_X_US (500)\r
+#define GH3X2X_AFE_HARD_RESET_DELAY_X_US (100)\r
+\r
+/// null val\r
+#define GH3X2X_PTR_NULL ((void *) 0)\r
+\r
+\r
+\r
+#define GH3X2X_AFE_CHANGE_BYTE_U16(x) ((((u16)(((u8*)(&x))[0]))<<8) + ((u16)(((u8 *)(&x))[1])))\r
+/// get high byte from word\r
+#define GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(sValue) ((GU8)(((sValue) >> 8) & 0xFFU))\r
+/// get low byte from word\r
+#define GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(sValue) ((GU8)((sValue) & 0xFFU))\r
+#define GH3X2X_AFE_MAKEUP_WORD(uchHighByte, uchLowByte) ((GU16)(((((GU16)(uchHighByte)) << 8)& 0xFF00) |\\r
+ (((GU16)(uchLowByte))& 0x00FF)))\r
+\r
+/// makeup dword from bytes\r
+#define GH3X2X_AFE_MAKEUP_DWORD(uchByte3, uchByte2, uchByte1, uchByte0) (((((GU32)(uchByte3)) << 24) & 0xFF000000U)|\\r
+ ((((GU32)(uchByte2)) << 16) & 0x00FF0000U) |\\r
+ ((((GU32)(uchByte1)) << 8) & 0x0000FF00U) |\\r
+ (((GU32)(uchByte0)) & 0x000000FFU))\r
+\r
+\r
+/// rawdata clear all flag\r
+#define GH3X2X_RAWDATA_CLEAR_ALL_FLAG(x) ((x) & 0x00FFFFFF)\r
+\r
+\r
+/// macro of val get bits\r
+#define GH3X2X_AFE_VAL_GET_BIT(x, b) ((x) &= (b))\r
+\r
+\r
+\r
+#define GH3X2X_AFE_EVENT_BIT(x) ((GU16)1 << x)\r
+\r
+\r
+\r
+#define GH3X2X_AFE_REG_IS_VALID(x) ((x) <= 0x0780)\r
+/// macro of val clear bits\r
+#define GH3X2X_VAL_CLEAR_BIT(x, b) ((x) &= (~(b)))\r
+/// macro of val set bits\r
+#define GH3X2X_VAL_SET_BIT(x, b) ((x) |= (b))\r
+\r
+\r
+#define GH3X2X_PIN_STATUS_CS_0_MISO_0 (0)\r
+#define GH3X2X_PIN_STATUS_CS_1_MISO_0 (1)\r
+#define GH3X2X_PIN_STATUS_CS_0_MISO_1 (2)\r
+#define GH3X2X_PIN_STATUS_CS_1_MISO_1 (3)\r
+\r
+\r
+/// get byte3 from dword\r
+#define GH3X2X_AFE_GET_BYTE3_FROM_DWORD(unValue) ((GU8)(((unValue) >> 24) & 0x000000FFU))\r
+/// get byte2 from dword\r
+#define GH3X2X_AFE_GET_BYTE2_FROM_DWORD(unValue) ((GU8)(((unValue) >> 16) & 0x000000FFU))\r
+/// get byte1 from dword\r
+#define GH3X2X_AFE_GET_BYTE1_FROM_DWORD(unValue) ((GU8)(((unValue) >> 8) & 0x000000FFU))\r
+/// get byte0 from dword\r
+#define GH3X2X_AFE_GET_BYTE0_FROM_DWORD(unValue) ((GU8)((unValue) & 0x000000FFU))\r
+\r
+/// macro of val set bits\r
+#define GH3X2X_VAL_SET_BIT(x, b) ((x) |= (b))\r
+\r
+/// macro of clear bits\r
+#define GH3X2X_CLEAR_BIT(x, b) ((x) & (~(b)))\r
+\r
+/// macro of val clear bits\r
+#define GH3X2X_VAL_CLEAR_BIT(x, b) ((x) &= (~(b)))\r
+\r
+/// macro of val get bits\r
+#define GH3X2X_VAL_GET_BIT(x, b) ((x) &= (b))\r
+\r
+\r
+#define GH3X2X_AFE_I2C_DEVICE_BASE (0x28)\r
+#define GH3X2X_AFE_I2C_DEVICE_ADDR (GH3X2X_AFE_I2C_DEVICE_BASE | (GH3X2X_AFE_I2C_DEVICE_CTRL_PIN_STATUS << 1))\r
+\r
+\r
+#define GH3X2X_AFE_FIFO_RAWDATA_SIZE (4)\r
+#define GH3X2X_AFE_SLOT_ADC_NUM_BITS (0xF8)\r
+#define GH3X2X_AFE_CHANNEL_MAP_GET(x) ((x) & GH3X2X_AFE_SLOT_ADC_NUM_BITS)\r
+\r
+/// number of channel map id\r
+#define CHANNEL_MAP_ID_NUM (32)\r
+/// number of channel map id\r
+#define CHANNEL_SLOT_NUM (8)\r
+\r
+\r
+/**\r
+ * @brief register struct\r
+ */\r
+typedef struct\r
+{\r
+ GU16 usRegAddr; /**< register address */\r
+ GU16 usRegData; /**< register val */\r
+} STGH3X2X_AFEReg;\r
+\r
+typedef struct\r
+{\r
+ GU8 uchAddrOffset;\r
+ GU8 uchMsb;\r
+ GU8 uchLsb;\r
+} STGh3x2xAgcReg;\r
+\r
+typedef struct\r
+{\r
+ /// save gain\r
+ GU8 uchTiaGainRecord[CHANNEL_MAP_ID_NUM];\r
+ GU8 uchTiaGainAfterSoftAgc[CHANNEL_MAP_ID_NUM];\r
+ /// save current of drv0 and drv1\r
+ GU16 uchDrvCurrentAfterSoftAgc[CHANNEL_SLOT_NUM];\r
+ GU16 uchDrvCurrentRecord[CHANNEL_SLOT_NUM];\r
+} STGh3x2xAgcInfo;\r
+\r
+extern void GH3X2X_AFE_SpiSendCmd(GU8 uchCmd);\r
+extern void GH3X2X_AFE_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue);\r
+extern GU16 GH3X2X_AFE_SpiReadReg(GU16 usRegAddr);\r
+extern void GH3X2X_AFE_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen);\r
+\r
+extern void GH3X2X_AFE_SpiWriteRegHardwareCs(GU16 usRegAddr, GU16 usRegValue);\r
+extern void GH3X2X_AFE_SpiReadRegsHardwareCs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen);\r
+extern GU16 GH3X2X_AFE_SpiReadRegHardwareCs(GU16 usRegAddr);\r
+extern void GH3X2X_AFE_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue);\r
+extern GU16 GH3X2X_AFE_I2cReadReg(GU16 usRegAddr);\r
+extern void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU8 uchLen);\r
+extern void GH3X2X_AFE_Reset(void);\r
+extern void GH3X2X_AFE_SpiSendCmdHardwareCs(GU8 uchCmd);\r
+extern void GH3X2X_AFE_I2cSendCmd(GU8 uchCmd);\r
+\r
+\r
+/**************** cmd/read/write funciton define **************************/\r
+#if(GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_SPI)\r
+#if(GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS)\r
+#define GH3X2X_AFE_SEND_CMD(cmd) GH3X2X_AFE_SpiSendCmd(cmd)\r
+#define GH3X2X_AFE_WRITE_REG(usRegAddr, usRegValue) GH3X2X_AFE_SpiWriteReg(usRegAddr, usRegValue)\r
+#define GH3X2X_AFE_READ_REG(usRegAddr) GH3X2X_AFE_SpiReadReg(usRegAddr)\r
+#define GH3X2X_AFE_READ_FIFO(buf, len) GH3X2X_AFE_SpiReadFifo(buf, len)\r
+#define GH3X2X_AFE_READ_REGS(usRegAddr,pusRegValueBuffer,uchLen) GH3X2X_AFE_SpiReadRegs(usRegAddr,pusRegValueBuffer,uchLen)\r
+#else\r
+#define GH3X2X_AFE_SEND_CMD(cmd) GH3X2X_AFE_SpiSendCmdHardwareCs(cmd)\r
+#define GH3X2X_AFE_WRITE_REG(usRegAddr, usRegValue) GH3X2X_AFE_SpiWriteRegHardwareCs(usRegAddr, usRegValue)\r
+#define GH3X2X_AFE_READ_REG(usRegAddr) GH3X2X_AFE_SpiReadRegHardwareCs(usRegAddr)\r
+#define GH3X2X_AFE_READ_FIFO(buf, len) GH3X2X_AFE_SpiReadFifoHardwareCs(buf, len)\r
+#define GH3X2X_AFE_READ_REGS(usRegAddr,pusRegValueBuffer,uchLen) GH3X2X_AFE_SpiReadRegsHardwareCs(usRegAddr,pusRegValueBuffer,uchLen)\r
+\r
+#endif\r
+#else\r
+#define GH3X2X_AFE_SEND_CMD(cmd) GH3X2X_AFE_I2cSendCmd(cmd)\r
+#define GH3X2X_AFE_WRITE_REG(usRegAddr, usRegValue) GH3X2X_AFE_I2cWriteReg(usRegAddr, usRegValue)\r
+#define GH3X2X_AFE_READ_REG(usRegAddr) GH3X2X_AFE_I2cReadReg(usRegAddr)\r
+#define GH3X2X_AFE_READ_FIFO(buf, len) GH3X2X_AFE_I2cReadFifo(buf, len)\r
+#define GH3X2X_AFE_READ_REGS(usRegAddr,pusRegValueBuffer,uchLen) GH3X2X_I2cReadRegs(usRegAddr,pusRegValueBuffer,uchLen)\r
+\r
+#endif\r
+\r
+\r
+/***************************** GH3X2X event *************************************************/\r
+\r
+#define GH3X2X_AFE_EVENT_COM_READY (0)\r
+#define GH3X2X_AFE_EVENT_LEAD_ON (1)\r
+#define GH3X2X_AFE_EVENT_LEAD_OFF (2)\r
+#define GH3X2X_AFE_EVENT_FAST_RECOVER_DONE (3)\r
+#define GH3X2X_AFE_EVENT_ADC_DONE (4)\r
+#define GH3X2X_AFE_EVENT_FIFO_FULL (5)\r
+#define GH3X2X_AFE_EVENT_FIFO_OV (6)\r
+#define GH3X2X_AFE_EVENT_FIFO_UN (7)\r
+#define GH3X2X_AFE_EVENT_LED_TUNE_FAIL (8)\r
+#define GH3X2X_AFE_EVENT_LED_TUNE_DONE (9)\r
+#define GH3X2X_AFE_EVENT_WEAR_ON (10)\r
+#define GH3X2X_AFE_EVENT_WEAR_OFF (11)\r
+#define GH3X2X_AFE_EVENT_SLOT_TIME_OUT (12)\r
+#define GH3X2X_AFE_EVENT_SAMPLE_RATE_ERROR (13)\r
+#define GH3X2X_AFE_EVENT_ERSET (14)\r
+\r
+\r
+\r
+\r
+\r
+\r
+/***************************** GH3X2X registers *********************************************/\r
+\r
+\r
+#define GH3X2X_AFE_REG_INT_EVENT_ADDR 0x0508\r
+#define GH3X2X_AFE_REG_FIFO_USE_ADDR 0x050A\r
+#define GH3X2X_AFE_REG_CHIP_READY_CODE_REG_ADDR 0x0036\r
+#define GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR 0x01EC\r
+#define GH3X2X_AFE_REG_INT_EVENT_EN_ADDR 0x0502\r
+\r
+#define GH3X2X_AFE_REG_SLOT_EN_ADDR 0x0108\r
+\r
+\r
+#define GH3X2X_AFE_REG_START_ADDR 0x0000\r
+#define GH3X2X_AFE_REG_START_MSB 0\r
+#define GH3X2X_AFE_REG_START_LSB 0\r
+\r
+\r
+/**************************** GH3X2X ppg control reg index ***********************************************/\r
+#define GH3X2X_AFE_PPG_CTRL_REG_AGC_EN 0\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_UP_LIMIT 1\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DOWN_LIMIT 2\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV0 3\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV1 4\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX0 5\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX1 6\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX2 7\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX3 8\r
+#define GH3X2X_AFE_PPG_CTRL_REG_AGC_SRC 9\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX0 10\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX1 11\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX2 12\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX3 13\r
+#define GH3X2X_AFE_PPG_CTRL_REG_SR_MULIPLIPER 14\r
+#define GH3X2X_AFE_PPG_CTRL_ECG_PPG_RX_EN 15\r
+\r
+#define GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB (4)\r
+#define GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB (5)\r
+\r
+#define GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB (0)\r
+#define GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB (1)\r
+\r
+#define GH3X2X_WHO_AM_I_LSB (5)\r
+#define GH3X2X_WHO_AM_I_MSB (7)\r
+\r
+#define GH3X2X_EFUSE_MODE_LSB (0)\r
+#define GH3X2X_EFUSE_MODE_MSB (1)\r
+\r
+#define GH3X2X_EFUSE_CHOOSE_LSB (2)\r
+#define GH3X2X_EFUSE_CHOOSE_MSB (3)\r
+\r
+#define GH3X2X_EFUSE_START_LSB (4)\r
+#define GH3X2X_EFUSE_START_MSB (4)\r
+\r
+#define GH3X2X_EFUSE_CLK_EN_LSB (5)\r
+#define GH3X2X_EFUSE_CLK_EN_MSB (5)\r
+\r
+\r
+\r
+\r
+#define GH3X2X_LED_DRV_AD_REG_REG_ADDR (0x0692)\r
+#define GH3X2X_WHO_AM_I_REG_ADDR (0x0724)\r
+\r
+\r
+// efuse_ctrl block, start addr: 0x0700\r
+#define GH3X2X_EFUSE_CTRL_CMD_REG_ADDR (0x0700)\r
+#define GH3X2X_EFUSE_CTRL_PASSWORD_REG_ADDR (0x0702)\r
+#define GH3X2X_EFUSE_CTRL_TIMING_CFG_0_REG_ADDR (0x0704)\r
+#define GH3X2X_EFUSE_CTRL_TIMING_CFG_1_REG_ADDR (0x0706)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_0_REG_ADDR (0x0708)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_1_REG_ADDR (0x070A)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_2_REG_ADDR (0x070C)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_3_REG_ADDR (0x070E)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR (0x0710)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_1_REG_ADDR (0x0712)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_2_REG_ADDR (0x0714)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_3_REG_ADDR (0x0716)\r
+#define GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR (0x0718)\r
+#define GH3X2X_EFUSE_CTRL_REG_MODE_REG_ADDR (0x071A)\r
+ \r
+\r
+extern GU8 g_uchGh3x2xAfeIntCallBackIsCalled;\r
+\r
+\r
+extern void GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(GU8 uchFlag);\r
+extern void hal_gh3x2x_afe_DelayUs(GU16 usUsec);\r
+extern void hal_gh3x2x_afe_DelayMs(GU16 usMsec);\r
+\r
+extern void hal_gh3x2x_afe_i2c_init(void);\r
+extern GU8 hal_gh3x2x_afe_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length);\r
+extern GU8 hal_gh3x2x_afe_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length);\r
+\r
+extern void hal_gh3x2x_afe_spi_init(void);\r
+extern GU8 hal_gh3x2x_afe_spi_write(GU8 write_buffer[], GU16 length);\r
+extern GU8 hal_gh3x2x_afe_spi_read(GU8 read_buffer[], GU16 length);\r
+extern GU8 hal_gh3x2x_afe_spi_write_F1_and_read(GU8 read_buffer[], GU16 length);\r
+extern void hal_gh3x2x_afe_spi_cs_ctrl(GU8 cs_pin_level);\r
+\r
+extern void hal_gh3x2x_afe_reset_pin_init(void);\r
+extern void hal_gh3x2x_afe_reset_pin_ctrl(GU8 pin_level);\r
+\r
+extern void hal_gh3x2x_afe_int_init(void);\r
+extern void hal_gh3x2x_afe_int_handler_call_back(void);\r
+\r
+extern void GH3X2X_AFE_Log(GCHAR *log_string);\r
+\r
+\r
+\r
+\r
+\r
+extern void GH3X2X_AFE_ChipPro(void);\r
+extern void GH3X2X_AFE_Init(void);\r
+extern void GH3X2X_AFE_StartSampling(GU8 SlotCfgEnable);\r
+extern void GH3X2X_AFE_StopSampling(void);\r
+extern void GH3X2X_AFE_SwitchSlot(GU8 SlotCfgEnable);\r
+\r
+extern void GH3x2xSetPpgCtrlReg(GU8 uchPpgCtrlReg, GU8 uchSlot, GU16 usValue);\r
+extern GU16 GH3x2xGetPpgCtrlReg(GU8 uchPpgCtrlReg, GU8 uchSlot);\r
+\r
+GU16 GH3X2X_AFE_SetLedDrvCurrent(GU8 uchCurrent_mA, GU8 uchDrvNum, GS8 chECODE);\r
+GF32 GH3X2X_AFE_GetLedDrvCurrent(GU16 usDrvCode, GU8 uchDrvNum, GS8 chECODE);\r
+void GH3X2X_AFE_GetEfuseCode(GS8* pchLedDrvEcode,GS8* pchTiaEcode,GS8* pchEcgEcode);\r
+GF32 GH3X2X_AFE_GetTiaCalCode(GS8 chECODE);\r
+GF32 GH3X2X_AFE_GetEcgCalCode(GS8 chECODE);\r
+GCHAR *GH3X2X_GetAfeLibVersion(void);\r
+GU8 GH3X2X_AFE_GetChipId(void);\r
+GS8 GH3X2X_AFE_CheckChipId(void);\r
+void GH3X2X_AFE_LoadEfuse(GU8* puchEfuseBuffer,GU16 EfuseByteLen);\r
+GS8 GH3X2X_AFE_CheckEfuseCrc(void);\r
+void GH3X2X_AFE_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue);\r
+GU16 GH3X2X_AFE_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb);\r
+GU8 GH3X2X_AFE_GetSoftEvent(void);\r
+void GH3X2X_AFE_SetSoftEvent(GU32 unEvent);\r
+void GH3X2X_AFE_ClearSoftEvent(GU32 unEvent);\r
+void GH3X2X_AFE_StartFunction(GU32 unFuncMode);\r
+\r
+void GH3x2x_AFESetAgcReg(GU8 uchAgcReg, GU8 uchSlot, GU16 usValue);\r
+GU16 GH3x2x_AFEGetAgcReg(GU8 uchAgcReg, GU8 uchSlot);\r
+void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize);\r
+void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize);\r
+void GH3X2X_RecordAgcInfo(void);\r
+void GH3X2X_UpdateAgcInfo(void);\r
+/*********************************************** master-slaver interface lib function *********************************/\r
+#define GH3X2X_INFO_LOG(...) do {\\r
+ char GH3X2X_AFE_GH3X2X_INFO_LOG[128] = {0};\\r
+ snprintf(GH3X2X_AFE_GH3X2X_INFO_LOG, 128, __VA_ARGS__);\\r
+ GH3X2X_AFE_Log((char *)GH3X2X_AFE_GH3X2X_INFO_LOG);\\r
+ } while(0)\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef __GH3X2X_AFE_ECG_H__\r
+#define __GH3X2X_AFE_ECG_H__\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+/**\r
+ * @brief Downsample Function\r
+*/\r
+typedef enum\r
+{\r
+ DOWNSAMPLE_ECG = 0,\r
+ DOWNSAMPLE_PPG,\r
+}EmDownSampleFunction;\r
+\r
+/**\r
+ * @brief Downsample type\r
+*/\r
+typedef enum\r
+{\r
+ DOWNSAMPLE_DEFAULT = 0,\r
+ DOWNSAMPLE_800HZ_TO_500HZ = 1,\r
+ DOWNSAMPLE_800HZ_TO_250HZ = 2,\r
+ DOWNSAMPLE_400HZ_TO_250HZ = 3,\r
+ DOWNSAMPLE_320HZ_TO_250HZ = 4,\r
+ DOWNSAMPLE_256HZ_TO_250HZ = 5,\r
+}EmDownSampleType;\r
+\r
+typedef struct\r
+{\r
+ GS32 snRsXbuf[100/1 + 1];\r
+ GS32 snBufHead;\r
+ GS32 snRsFirState;\r
+ GU32 nRsIcounter;\r
+ GU32 nRrsDcounter;\r
+ GU8 uchFlagFrPrev;\r
+ GU32 nRsLastRaw;\r
+ GU32 fDownStep;\r
+ GU8 uchLinearInterState;\r
+ GU8 uchLinearDataUpdate;\r
+} STGh3x2xRsInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+ GS32 snCounter;\r
+ GS32 sniqCounter;\r
+ long long snniVal;\r
+ long long snnqVal;\r
+ GU8 uchFlagFrPrev;\r
+ GU8 uchFastRecoryHistory;\r
+ long long snniqAmp[5];\r
+} STGh3x2xSoftLeadOffDetInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+ GU8 uchRsFirOrder;\r
+ GU8 uchRsI;\r
+ GU8 uchRsD;\r
+ GU8 uchRsFirCoefNum;\r
+ GU8 uchRsBufSize;\r
+ GU8 uchRsEnable;\r
+ GU32 ufStep;\r
+ GS32* rsFirCoef;\r
+ GU8 uchDownSampleType;\r
+} STGh3x2xDownSampleCalParamInfo;\r
+\r
+#define __SUPPORT_ECG_PPG_DOWNSAMP__ 0\r
+ \r
+/* ecg sample event type */\r
+#define ECG_SAMPLE_EVENT_TYPE_SAMPLE (0x01) /**< sample evt type sample config */\r
+#define ECG_SAMPLE_EVENT_TYPE_SLOT (0x02) /**< sample evt type slot config */\r
+#define ECG_SAMPLE_EVENT_TYPE_LEAD (0x04) /**< sample evt type lead irq */\r
+#define ECG_SAMPLE_EVENT_ALL (ECG_SAMPLE_EVENT_TYPE_SAMPLE | ECG_SAMPLE_EVENT_TYPE_SLOT | \\r
+ ECG_SAMPLE_EVENT_TYPE_LEAD) /**< sample evt all */\r
+\r
+#define GH3X2X_ECG_CTRL_REG_ADDR (0x01EA)\r
+#define GH3X2X_ECG_FAST_RECV_EN_LSB (10) /**< ecg fast recv en lsb @GH3X2X_ECG_CTRL_REG */\r
+#define GH3X2X_ECG_FAST_RECV_EN_MSB (10) /**< ecg fast recv en msb @GH3X2X_ECG_CTRL_REG */\r
+/// ecg fast recover enable config\r
+#define ECG_FAST_RECV_EN_CONFIG(en) do {\\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_ECG_CTRL_REG_ADDR, \\r
+ GH3X2X_ECG_FAST_RECV_EN_LSB, GH3X2X_ECG_FAST_RECV_EN_MSB, (en)); \\r
+ } while (0)\r
+\r
+#define GH3X2X_ADT_LEADON_CR_REG_ADDR (0x0400)\r
+#define GH3X2X_ECG_LEAD_DET_EN_LSB (0) /**< ecg lead det en lsb @GH3X2X_ADT_LEADON_CR_REG */\r
+#define GH3X2X_ECG_LEAD_DET_EN_MSB (0) /**< ecg lead det en msb @GH3X2X_ADT_LEADON_CR_REG */\r
+ \r
+ /// ecg lead detect enable config\r
+#define ECG_LEAD_DET_EN_CONFIG(en) do {\\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_ADT_LEADON_CR_REG_ADDR, \\r
+ GH3X2X_ECG_LEAD_DET_EN_LSB, GH3X2X_ECG_LEAD_DET_EN_MSB, (en)); \\r
+ } while (0) \r
+ \r
+ \r
+#define GET_ECG_LEAD_DET_EN_VAL() (GH3X2X_AFE_ReadRegBitField(GH3X2X_ADT_LEADON_CR_REG_ADDR, \\r
+ GH3X2X_ECG_LEAD_DET_EN_LSB, GH3X2X_ECG_LEAD_DET_EN_MSB))\r
+ \r
+ \r
+\r
+GU8 GH3X2X_AFE_EcgRsHandle(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum, GU16 usEcgSampleRate);\r
+GS32 GH3X2X_LeadOffDetectInit(void);\r
+void GH3X2X_ECGResampleConfig(GU16 usEcgSampleRate);\r
+void GH3X2X_PPGResampleConfig(GU16 usEcgSampleRate); \r
+GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum);\r
+void GH3X2X_AFE_Leadon_hook(void);\r
+void GH3X2X_AFE_Leadoff_hook(void);\r
+void GH3x2xSetEcgOutputFs(GU16 usEcgOutputFs);\r
+\r
+#endif\r
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-13 10:11:20\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-01-17 15:57:59\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/ppg/gh3x2x/inc/gh3x2x_afe_user.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#ifndef __GH3X2X_AFE_USER_H__\r
+#define __GH3X2X_AFE_USER_H__\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+\r
+#define GH3X2X_CHIP_ID GH3020_ID\r
+#define GH3X2X_AFE_MP_MODE GH3X2X_MP_ENABLE\r
+\r
+\r
+/****** communication type config **************************/\r
+#define GH3X2X_AFE_COM_INTERFACE_TYPE GH3X2X_AFE_COM_INTERFACE_I2C\r
+#define GH3X2X_AFE_SPI_TYPE GH3X2X_AFE_SPI_SOFTWARE_CS\r
+\r
+\r
+/****** I2C device id ***************************************/\r
+#define GH3X2X_AFE_I2C_DEVICE_CTRL_PIN_STATUS GH3X2X_PIN_STATUS_CS_0_MISO_0\r
+\r
+\r
+\r
+/****** chip process type config ***************************/\r
+#define GH3X2X_AFE_PRO_TYPE GH3X2X_AFE_PRO_BY_INT\r
+\r
+\r
+\r
+/****** chip reset type config ***************************/\r
+#define GH3X2X_AFE_RESET_TYPE GH3X2X_AFE_RESET_SOFTWARE\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_version.h\r
+ *\r
+ * @brief gh3x2x afe driver version and change log\r
+ *\r
+ * @par history:\r
+ * @verbatim\r
+ * Date Version Notes\r
+ * 2021-11-04 v3.2.4.2 1.add calibration code\r
+ * 2021-11-05 v3.2.4.4 1.fix Efuse calibration bug\r
+ * 2021-11-05 v3.2.4.5 1.add Ffuse Crc Process\r
+ * 2.add Check Chip Id process\r
+ *\r
+ * 2021-11-05 v3.2.4.6 1.update Head file\r
+ * 2021-11-05 v3.2.4.7 1.add ecg lead off det lib\r
+ * 2021-11-05 v3.2.4.8 1.add 5Hz adt\r
+ * 2023-12-06 v3.2.4.9 1.update ecg and agc\r
+ * @endverbatim */\r
+\r
+#ifndef _GH3X2X_AFE_VERSION_H_\r
+#define _GH3X2X_AFE_VERSION_H_\r
+\r
+\r
+#define GH3X2X_DRV_MAJOR_VERSION_NUMBER 3 /**< major version number */\r
+#define GH3X2X_DRV_MINOR_VERSION_NUMBER 2 /**< minor version number */\r
+#define GH3X2X_DRV_REVISION_VERSION_NUMBER 4 /**< revision version number */\r
+#define GH3X2X_DRV_FIXED_VERSION_NUMBER 9 /**< fixed version number */\r
+\r
+#define GH3X2X_TO_STRING(x) #x /**< number to char */\r
+#define GH3X2X_STR(x) GH3X2X_TO_STRING(x) /**< number to char */\r
+\r
+/// makeup version string\r
+#define GH3X2X_VERSION_STRING "v" GH3X2X_STR(GH3X2X_DRV_MAJOR_VERSION_NUMBER)\\r
+ "." GH3X2X_STR(GH3X2X_DRV_MINOR_VERSION_NUMBER)\\r
+ "." GH3X2X_STR(GH3X2X_DRV_REVISION_VERSION_NUMBER)\\r
+ "." GH3X2X_STR(GH3X2X_DRV_FIXED_VERSION_NUMBER)\\r
+ " (build:"__DATE__"_"__TIME__")"\r
+\r
+\r
+#endif /* _GH3X2X_AFE_VERSION_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-06-07 11:18:26
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-13 14:09:50
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.h
+ * @Description:
+ *
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
+ */
+#ifndef GH_3X2X_HAL_H__
+#define GH_3X2X_HAL_H__
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+
+typedef uint32_t PPG_CMD_TYPE_T ;
+
+void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable);
+
+uint32_t tyhx_poweron(void);
+uint32_t tyhx_poweroff(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_adt.c\r
+ *\r
+ * @brief gh3x2x led agc process functions\r
+ *\r
+ * @version \r
+ *\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include "gh3x2x_afe_adt.h"\r
+\r
+#define GH3X2X_MOVINF_AVA_WINDOW_SIZE 6\r
+\r
+\r
+\r
+EMWearDetectType g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+\r
+GU32 g_punGh3x2xMovingAvaFilterBuf[GH3X2X_MOVINF_AVA_WINDOW_SIZE];\r
+GU8 g_uchGh3x2xMovingAvaFilterPointCnt;\r
+GU8 g_Gh3x2xFilterHaveOutputFlag;\r
+\r
+\r
+\r
+void Gh3x2xMovingAvaFilterInit(void)\r
+{\r
+ g_uchGh3x2xMovingAvaFilterPointCnt = 0;\r
+ g_Gh3x2xFilterHaveOutputFlag = 0;\r
+}\r
+GU8 Gh3x2xMovingAvaFilter(GU32 *Rawdata, GU8 uchBypass)\r
+{\r
+ GU32 unSum = 0;\r
+\r
+ if(uchBypass)\r
+ {\r
+ return 1;\r
+ }\r
+ else\r
+ {\r
+ if(g_uchGh3x2xMovingAvaFilterPointCnt >= GH3X2X_MOVINF_AVA_WINDOW_SIZE)\r
+ {\r
+ for(GU8 uchCnt = 1; uchCnt < GH3X2X_MOVINF_AVA_WINDOW_SIZE; uchCnt ++)\r
+ {\r
+ g_punGh3x2xMovingAvaFilterBuf[uchCnt - 1] = g_punGh3x2xMovingAvaFilterBuf[uchCnt];\r
+ }\r
+ g_uchGh3x2xMovingAvaFilterPointCnt = GH3X2X_MOVINF_AVA_WINDOW_SIZE - 1;\r
+ }\r
+ g_punGh3x2xMovingAvaFilterBuf[g_uchGh3x2xMovingAvaFilterPointCnt] = Rawdata[0];\r
+ g_uchGh3x2xMovingAvaFilterPointCnt ++;\r
+ \r
+ if(g_uchGh3x2xMovingAvaFilterPointCnt > 1)\r
+ {\r
+ for(GU8 uchCnt = 0; uchCnt < g_uchGh3x2xMovingAvaFilterPointCnt - 1; uchCnt ++)\r
+ {\r
+ unSum += g_punGh3x2xMovingAvaFilterBuf[uchCnt];\r
+ }\r
+ Rawdata[0] = unSum/(g_uchGh3x2xMovingAvaFilterPointCnt - 1);\r
+ }\r
+ return 1;\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+GS8 GH3x2xAdtAlgoInit(void)\r
+{\r
+ Gh3x2xMovingAvaFilterInit();\r
+ g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+ return GH3X2X_AFE_RET_OK;\r
+}\r
+GS8 GH3x2xAdtAlgoDeinit(void)\r
+{\r
+ return GH3X2X_AFE_RET_OK;\r
+}\r
+\r
+void GH3x2xAdtAlgoExe(GU32* punRawdata,EMWearStatus* pemWearStatus)\r
+{\r
+ \r
+ GU32 unCurrentFrameRawdata;\r
+\r
+ GU32 unRawDataBeforeFilter;\r
+ unCurrentFrameRawdata = *punRawdata;\r
+ unRawDataBeforeFilter = *punRawdata;\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] punFrameRawdata = %d\r\n", unCurrentFrameRawdata);\r
+\r
+ Gh3x2xMovingAvaFilter(&unCurrentFrameRawdata, 0);\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] punFrameRawdata after filter = %d\r\n", unCurrentFrameRawdata);\r
+\r
+\r
+\r
+ GS32 snDiffRawdata;\r
+\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] start check...\r\n");\r
+\r
+ snDiffRawdata = (GS32)unRawDataBeforeFilter - (GS32)unCurrentFrameRawdata;\r
+\r
+ if(WEAR_DETECT_WEAR_ON == g_uchWearDetectStatus)\r
+ {\r
+ \r
+ *pemWearStatus = WEAR_STATUS_WEAR_OFF;\r
+ if((unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)&&((snDiffRawdata > (GS32)__HARD_ADT_WAER_ON_DIFF_THRD__)))\r
+ {\r
+ *pemWearStatus = WEAR_STATUS_WEAR_ON;\r
+ g_uchWearDetectStatus = WEAR_DETECT_WEAR_OFF;\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] wear on !\r\n");\r
+ }\r
+ else\r
+ {\r
+ if(unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)\r
+ {\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] wear on condition is not match ! r = %d, r_diff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);\r
+ }\r
+ }\r
+ if(snDiffRawdata > 30000)\r
+ {\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe]ppg 5Hz diff big event, Rawdata = %d, unRawdataDiff = %d\r\n",*punRawdata,snDiffRawdata);\r
+ }\r
+ }\r
+ else if(WEAR_DETECT_WEAR_OFF == g_uchWearDetectStatus)\r
+ {\r
+ *pemWearStatus = WEAR_STATUS_WEAR_ON;\r
+ if(unRawDataBeforeFilter < __HARD_ADT_WAER_OFF_THRD__)\r
+ {\r
+ *pemWearStatus = WEAR_STATUS_WEAR_OFF;\r
+ g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe]ppg 5Hz wear off event, Rawdata = %d, unRawdataDiff = %d\r\n",*punRawdata,snDiffRawdata);\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] wear off !\r\n");\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_agc.c\r
+ *\r
+ * @brief gh3x2x led agc process functions\r
+ *\r
+ * @version \r
+ *\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include "gh3x2x_afe_agc.h"\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+#define __GH3X2X_AGC_GENERAL_TRIG_H_THD__ ((8388608 + 8388608*0.85f))\r
+#define __GH3X2X_AGC_GENERAL_TRIG_L_THD__ ((8388608 + 8388608*0.15f))\r
+#define __GH3X2X_AGC_GENERAL_IDEAL_VALUE__ ((8388608 + 8388608*0.56f))\r
+#define __GH3X2X_AGC_SPO2_TRIG_H_THD__ ((8388608 + 8388608*0.9f))\r
+#define __GH3X2X_AGC_SPO2_TRIG_L_THD__ ((8388608 + 8388608*0.5f))\r
+#define __GH3X2X_AGC_SPO2_IDEAL_VALUE__ ((8388608 + 8388608*0.7f))\r
+#define __GH3X2X_AGC_CONVERGENCE_LEVEL__ (16) // The values that can be set are 8, 16 and 32, and the recommended value is 16. The larger the value, the smaller the convergence range of AGC. \r
+\r
+//sub channel\r
+\r
+#define GH3X2X_NEW_AGC_SUB_CHNNL_ANAYLSIS_TIME_SEC 1\r
+\r
+#define GH3X2X_AGC_REG_AGC_EN 0\r
+#define GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT 1\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT 2\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV0 3\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV1 4\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX0 5\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX1 6\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX2 7\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX3 8\r
+#define GH3X2X_AGC_REG_AGC_SRC 9\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX0 10\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX1 11\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX2 12\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX3 13\r
+#define GH3X2X_AGC_REG_SR_MULIPLIPER 14\r
+#define GH3X2X_AGC_ECG_PPG_RX_EN 15\r
+\r
+\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+//main chnl\r
+STGh3x2xNewAgcMainChnlInfo g_pstGh3x2xNewAgcMainChnlInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+STGh3x2xNewAgcMainChnlMeanInfo g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+STGh3x2xNewAgcMainChnlIdaelAdjInfo g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+//sub chnl\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+STGh3x2xNewAgcSubChnlRxInfo g_pstGh3x2xNewAgcSubChnlRxInfoEntity[GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT];\r
+#endif\r
+\r
+\r
+STGh3x2xNewAgcMainChnlSat g_pstGh3x2xNewAgcMainChnlSat;\r
+const GU32 g_unNewAgcSpo2Trig_H_Thd = __GH3X2X_AGC_SPO2_TRIG_H_THD__;\r
+const GU32 g_unNewAgcSpo2Trig_L_Thd = __GH3X2X_AGC_SPO2_TRIG_L_THD__;\r
+const GU32 g_unNewAgcSpo2Ideal_value = __GH3X2X_AGC_SPO2_IDEAL_VALUE__;\r
+const GU32 g_unNewAgcGeneTrig_H_Thd = __GH3X2X_AGC_GENERAL_TRIG_H_THD__;\r
+const GU32 g_unNewAgcGeneTrig_L_Thd = __GH3X2X_AGC_GENERAL_TRIG_L_THD__;\r
+const GU32 g_unNewAgcGeneIdeal_value = __GH3X2X_AGC_GENERAL_IDEAL_VALUE__;\r
+const GU8 g_uchAgcConvergence_level = __GH3X2X_AGC_CONVERGENCE_LEVEL__;\r
+\r
+\r
+// soft agc parameter\r
+static STSoftAgcCfg g_stSoftAgcCfg;\r
+extern const GU16 g_usGH3x2xTiaGainR[];\r
+\r
+GU8 g_Gh3x2xNewAgcInitFlag = 0;\r
+\r
+void GH3X2X_LedAgcPramConfig(STSoftAgcCfg* stSoftAgcCfg)\r
+{\r
+ g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn = stSoftAgcCfg->uchSlotxSoftAgcAdjEn; //bit0: slot0\r
+ g_stSoftAgcCfg.uchSlotxSoftBgAdjEn = stSoftAgcCfg->uchSlotxSoftBgAdjEn;\r
+ g_stSoftAgcCfg.stAmbSlotCtrl.uchAmbSampleEn = stSoftAgcCfg->stAmbSlotCtrl.uchAmbSampleEn;\r
+ g_stSoftAgcCfg.uchSpo2RedSlotCfgEn = stSoftAgcCfg->uchSpo2RedSlotCfgEn;\r
+ g_stSoftAgcCfg.uchSpo2IrSlotCfgEn = stSoftAgcCfg->uchSpo2IrSlotCfgEn;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg32uA;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg64uA;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg128uA;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg256uA;\r
+ g_stSoftAgcCfg.unAgcTrigThd_H = stSoftAgcCfg->unAgcTrigThd_H;\r
+ g_stSoftAgcCfg.unAgcTrigThd_L = stSoftAgcCfg->unAgcTrigThd_L;\r
+ g_stSoftAgcCfg.unAgcRestrainThd_H = stSoftAgcCfg->unAgcRestrainThd_H;\r
+ g_stSoftAgcCfg.unAgcRestrainThd_L = stSoftAgcCfg->unAgcRestrainThd_L;\r
+ \r
+ GH3X2X_INFO_LOG("uchSlotxSoftAgcAdjEn = 0x%X, uchSlotxSoftBgAdjEn = 0x%X\r\n",(int)g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn,(int)g_stSoftAgcCfg.uchSlotxSoftBgAdjEn);\r
+ GH3X2X_INFO_LOG("uchAmbSampleEn = 0x%X, uchAmbSlot = 0x%X\r\n",(int)g_stSoftAgcCfg.stAmbSlotCtrl.uchAmbSampleEn,(int)g_stSoftAgcCfg.stAmbSlotCtrl.uchAmbSlot);\r
+ GH3X2X_INFO_LOG("uchSpo2RedSlotCfgEn = 0x%X,uchSpo2IrSlotCfgEn = 0x%X\r\n",(int)g_stSoftAgcCfg.uchSpo2RedSlotCfgEn,(int)g_stSoftAgcCfg.uchSpo2IrSlotCfgEn);\r
+ GH3X2X_INFO_LOG("stSoftAgcGainLimit = 0x%X,0x%X,0x%X,0x%X\r\n",g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA,g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA,g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA,g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA);\r
+ GH3X2X_INFO_LOG("unAgcTrigThd_H = %d,unAgcTrigThd_L = %d\r\n",(int)g_stSoftAgcCfg.unAgcTrigThd_H,(int)g_stSoftAgcCfg.unAgcTrigThd_L);\r
+ GH3X2X_INFO_LOG("unAgcRestrainThd_H = %d,unAgcRestrainThd_L = %d\r\n",(int)g_stSoftAgcCfg.unAgcRestrainThd_H,(int)g_stSoftAgcCfg.unAgcRestrainThd_L);\r
+\r
+}\r
+\r
+void GH3X2X_StoreRxTiaGainAfterAgc(GU8 uchGain, GU8 uchSlotNo, GU8 uchAdcNo, GU8* puchGainRecord)\r
+{\r
+ puchGainRecord[uchSlotNo*4 + uchAdcNo] = uchGain;\r
+}\r
+\r
+void GH3X2X_StoreDrvCurrentAfterAgc(GU8 DrvCurrent, GU8 uchSlotNo, GU8 uchDrvIndex, GU16* puchDrvCurrentRecord)\r
+{\r
+ if(!uchDrvIndex)\r
+ {\r
+ puchDrvCurrentRecord[uchSlotNo] = (puchDrvCurrentRecord[uchSlotNo]&0xFF00)|DrvCurrent;\r
+ }\r
+ else\r
+ {\r
+ puchDrvCurrentRecord[uchSlotNo] = (puchDrvCurrentRecord[uchSlotNo]&0x00FF)|(DrvCurrent<<8);\r
+ } \r
+}\r
+\r
+\r
+void GH3x2xNewAgcModuleReset(void)\r
+{\r
+ g_Gh3x2xNewAgcInitFlag = 0;\r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlInfo));\r
+ GH3X2X_Memset( (GU8*)(&g_pstGh3x2xNewAgcMainChnlSat),0,sizeof(STGh3x2xNewAgcMainChnlSat)); // init variable\r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlMeanInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlMeanInfo)); \r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlIdaelAdjInfo)); \r
+ \r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ Gh3x2xNewAgcSubChnlModuleReset(); \r
+ #endif\r
+}\r
+ \r
+void GH3X2X_NewAgcRecoveryAgcRegToMainChnl(GU8 uchSlotIdx, STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo)\r
+{\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegLedCurrentMax);\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegLedCurrentMin);\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_AGC_SRC, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegAgcSrc);\r
+ GH3X2X_INFO_LOG("[NewAgc] recover agc src:agc_src = %d, SlotNo = %d\r\n",pstAgcMainChnlInfo ->uchBakRegAgcSrc,uchSlotIdx);\r
+}\r
+\r
+GU8 GH3X2X_NewAgcFindSubChnlSlotInfo(GU8 uchSlot)\r
+{\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ {\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ if(pstAgcMainChnlInfo ->uchEnable)\r
+ {\r
+ if(uchSlot == (pstAgcMainChnlInfo ->uchSlotAdc >> 2))\r
+ {\r
+ return uchSlotCnt;\r
+ }\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+GU16 GH3x2xCalTrigerUpLimitForBiggerGain(GU8 uchCurrentGain ,GU8 uchSlotNo)\r
+{\r
+ GU32 unTempRawdata;\r
+ GU32 unTempTrigThd_H;\r
+\r
+ GU8 uchSlotCnt = GH3X2X_NewAgcFindSubChnlSlotInfo(uchSlotNo);\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ if(pstAgcMainChnlInfo->uchSpo2ChnlIndex)\r
+ {\r
+ unTempTrigThd_H = g_unNewAgcSpo2Trig_H_Thd;\r
+ }else\r
+ {\r
+ unTempTrigThd_H = g_unNewAgcGeneTrig_H_Thd;\r
+ }\r
+ \r
+ if(12 <= uchCurrentGain)\r
+ {\r
+ return 0xFFFF;\r
+ }\r
+ else\r
+ {\r
+ unTempRawdata = unTempTrigThd_H - 8388608;\r
+ unTempRawdata = 8388608 + (GU32)(((float)unTempRawdata)/(float)1.3*(float)g_usGH3x2xTiaGainR[uchCurrentGain]/(float)g_usGH3x2xTiaGainR[uchCurrentGain + 1]);\r
+ return unTempRawdata>>8;\r
+ }\r
+}\r
+\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(GU8 uchSlotNo, GU8 uchRxEn ,GU8 uchNextGain)\r
+{\r
+ for(GU8 uchRxCnt = 0; uchRxCnt < 4; uchRxCnt ++)\r
+ {\r
+ if(uchRxEn&(1 << uchRxCnt))\r
+ {\r
+ for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+ {\r
+ STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn)\r
+ {\r
+ if(((uchSlotNo << 2) + uchRxCnt) == pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usAnalysisCnt = 0;\r
+ if(0xFF != uchNextGain)\r
+ {\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchRxCnt, uchSlotNo, 0);\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = uchNextGain;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(uchNextGain,pstSTGh3x2xNewAgcSubChnlRxInfo->uchSlotAdcNo >> 2);\r
+ }\r
+ } \r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+#endif\r
+ \r
+ \r
+void GH3x2xNewAgcMeanInfoReset(GU8 uchSlotEnChange)\r
+{\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt++)\r
+ {\r
+ if( uchSlotEnChange & (1<<uchSlotCnt)) // SlotEn Change \r
+ {\r
+ for(GU8 uchAgcSlotCnt = 0; uchAgcSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchAgcSlotCnt ++) //// uchAgcSlotCnt'??????slot????\r
+ {\r
+ GU8 uchSlotIdx = ((g_pstGh3x2xNewAgcMainChnlInfoEntity[uchAgcSlotCnt].uchSlotAdc >> 2) & 0x0f);\r
+ GU8 uchEnable = g_pstGh3x2xNewAgcMainChnlInfoEntity[uchAgcSlotCnt].uchEnable;\r
+ if( uchEnable ) \r
+ { \r
+ if( uchSlotIdx == uchSlotCnt) \r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchAgcSlotCnt].usAnalysisCnt = 0;\r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(uchSlotIdx, 0x0F, 0xFF); //clear all rx analysis cnt in this slot\r
+ #endif \r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+} \r
+\r
+GU8 GH3x2xGetDrvCurrent(GU8 uchSlotIdx ,GU8 uchAgcEn)\r
+{\r
+ GU8 uchTempDrv;\r
+ if(2 == uchAgcEn)\r
+ { \r
+ uchTempDrv = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV1, uchSlotIdx);\r
+ }\r
+ else\r
+ {\r
+ uchTempDrv = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV0, uchSlotIdx);\r
+ }\r
+ return uchTempDrv;\r
+}\r
+\r
+void GH3x2xNewAgcChnlInfoInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ if(0 == GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+ {\r
+ return;\r
+ }\r
+ if(0 == g_Gh3x2xNewAgcInitFlag)\r
+ {\r
+ GU8 uchNewAgcSlotCnt = 0;\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+ {\r
+ if((g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn & (1 << uchSlotCnt)))\r
+ {\r
+ if(uchNewAgcSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchEnable = 1;\r
+ g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchSlotAdc = (uchSlotCnt << 2); \r
+ \r
+ /******* slot function Distinguish START******************************************************/ \r
+ if((g_stSoftAgcCfg.uchSpo2RedSlotCfgEn & (1 << uchSlotCnt))||(g_stSoftAgcCfg.uchSpo2IrSlotCfgEn & (1 << uchSlotCnt)))\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchSpo2ChnlIndex = 1;\r
+ GH3X2X_INFO_LOG("[NewAgc] uchNewAgcSpo2SlotCnt = %d\r\n",uchNewAgcSlotCnt);\r
+ }\r
+ /******* slot function Distinguish END******************************************************/\r
+ GH3X2X_INFO_LOG("[NewAgc] uchNewAgcSlotCnt = %d\r\n",uchNewAgcSlotCnt);\r
+ uchNewAgcSlotCnt ++;\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("[NewAgc] error !!! main chnl info is no enough! \r\n");\r
+ while(1);\r
+ }\r
+ }\r
+ }\r
+ g_Gh3x2xNewAgcInitFlag = 1;\r
+ }\r
+\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ { \r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ //GH3X2X_INFO_LOG_PARAM("AGC_InitValue %d: Enable = %d, AgcAdjEn = %d\r\n",uchSlotCnt, pstAgcMainChnlInfo->uchEnable,g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn);\r
+ if(pstAgcMainChnlInfo->uchEnable)\r
+ {\r
+ GU8 uchSlotIdx;\r
+ uchSlotIdx = pstAgcMainChnlInfo ->uchSlotAdc >> 2;\r
+ //GH3X2X_INFO_LOG_PARAM("AGC_InitFlag%d: SlotCfgX=%d, Vaule = %d\r\n",uchSlotCnt, uchSlotIdx, pstAgcMainChnlInfo->uchHaveBakRegFlag);\r
+ if(0 == pstAgcMainChnlInfo ->uchHaveBakRegFlag)\r
+ {\r
+ GU8 uchBgCancel;\r
+ GU8 uchGainLimit;\r
+ GU16 usSampleRate;\r
+ GU16 usEcgPpgRxEn;\r
+\r
+ //bak reg\r
+ pstAgcMainChnlInfo ->uchBakRegAgcEn = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_AGC_EN, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchBakRegAgcSrc = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_AGC_SRC, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchSlotAdc = (uchSlotIdx << 2) + pstAgcMainChnlInfo ->uchBakRegAgcSrc;\r
+ pstAgcMainChnlInfo ->uchBakRegLedCurrentMax = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT, uchSlotIdx); \r
+ pstAgcMainChnlInfo ->uchBakRegLedCurrentMin = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT, uchSlotIdx); \r
+ pstAgcMainChnlInfo ->uchBakTiaGain = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchCurrentTiaGain = pstAgcMainChnlInfo ->uchBakTiaGain;\r
+ pstAgcMainChnlInfo ->uchCurrentDrv = GH3x2xGetDrvCurrent(uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcEn); \r
+ //GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+ uchBgCancel = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_BG_CANCEL_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+ GH3X2X_StoreRxTiaGainAfterAgc(pstAgcMainChnlInfo->uchBakTiaGain, uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcSrc, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ if(0 == uchBgCancel)\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA;\r
+ }\r
+ else if(1 == uchBgCancel)\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA;\r
+ }\r
+ else if(2 == uchBgCancel)\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA;\r
+ }\r
+ else\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA;\r
+ }\r
+ GH3X2X_INFO_LOG("[NewAgc] uchGainLimit = %d, uchSlotIdx = %d\r\n",uchGainLimit, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchTiaGainUpLimit = uchGainLimit;\r
+ usSampleRate = 1000/(GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_SR_MULIPLIPER, uchSlotIdx) + 1);\r
+ usEcgPpgRxEn = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_ECG_PPG_RX_EN, uchSlotIdx);\r
+ GH3X2X_INFO_LOG("[NewAgc] usEcgPpgRxEn = 0x%X\r\n",usEcgPpgRxEn);\r
+ if(usEcgPpgRxEn&0x0001) // ecg is enable\r
+ {\r
+ usEcgPpgRxEn = ((usEcgPpgRxEn>>1) & (~0x0008)); //clear RX3 enable bit\r
+ }\r
+ else\r
+ {\r
+ usEcgPpgRxEn = (usEcgPpgRxEn>>1);\r
+ }\r
+ usEcgPpgRxEn &= (~(1 << pstAgcMainChnlInfo ->uchBakRegAgcSrc)); //clear main channel RX enable bit\r
+ \r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].usSampleRate = usSampleRate; //init\r
+ GH3X2X_INFO_LOG("[AgcInit] SlotCnt = %d, SampleRate = %d\r\n", uchSlotCnt, usSampleRate); \r
+ //sub channel slot\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3x2xNewAgcSetNewSubChnl(uchSlotIdx,usEcgPpgRxEn,STGh3x2xAgcInfo);\r
+#endif\r
+ pstAgcMainChnlInfo ->uchHaveBakRegFlag = 1; \r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_AGC_EN, uchSlotIdx, 0); // disable hardware agc \r
+ }\r
+ else\r
+ {\r
+ pstAgcMainChnlInfo ->uchCurrentTiaGain = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchCurrentDrv = GH3x2xGetDrvCurrent(uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcEn);\r
+ //GH3X2X_INFO_LOG_PARAM("Drv Gian inite read %d: IniteDrv = %d, IniteGain = %d\r\n",uchSlotIdx, pstAgcMainChnlInfo ->uchCurrentDrv, pstAgcMainChnlInfo ->uchCurrentTiaGain);\r
+ ////get initial DRV and current in case them change before StartSampling()\r
+// GH3X2X_NewAgcRecoveryAgcRegToMainChnl(uchSlotIdx,pstAgcMainChnlInfo);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+GU32 GH32x2xMedSel(GU32 unData0, GU32 unData1, GU32 unData2)\r
+{\r
+ if((unData0 >= unData1)&&(unData0 <= unData2))\r
+ {\r
+ return unData0;\r
+ }\r
+ if((unData0 >= unData2)&&(unData0 <= unData1))\r
+ {\r
+ return unData0;\r
+ }\r
+ if((unData1 >= unData0)&&(unData1 <= unData2))\r
+ {\r
+ return unData1;\r
+ }\r
+ if((unData1 >= unData2)&&(unData1 <= unData0))\r
+ {\r
+ return unData1;\r
+ }\r
+ return unData2;\r
+}\r
+\r
+float GH3X2X_CalcfRelativeVpp(GU32 unRawdata, GU8 uchDrv, GU8 uchGain)\r
+{\r
+ return ((float)unRawdata/(float)uchDrv/(float)g_usGH3x2xTiaGainR[uchGain]);\r
+}\r
+\r
+void GH3X2X_StoreTiaGainAfterAgc(GU16 usGainRegValue, GU8 uchSlotNo, GU8* puchGainRecord)\r
+{\r
+ for(GU8 uchAdcCnt = 0; uchAdcCnt < 4; uchAdcCnt ++)\r
+ {\r
+ puchGainRecord[uchSlotNo*4 + uchAdcCnt] = (usGainRegValue>>(uchAdcCnt*4))&0x000F;\r
+ GH3X2X_INFO_LOG("StoreTiaGainAfterAgc slot no = %d, adc no = %d, usGainRegValue = %d\r\n", uchSlotNo,uchAdcCnt,usGainRegValue);\r
+ }\r
+}\r
+\r
+void GH3X_AgcGetThreshold( GU8 uchSpo2ChnlIndex, GU32* punTemp_H_Thd, GU32* punTemp_L_Thd )\r
+{ \r
+ if(uchSpo2ChnlIndex) // is spo2 slot\r
+ {\r
+ *punTemp_H_Thd = g_unNewAgcSpo2Trig_H_Thd; \r
+ *punTemp_L_Thd = g_unNewAgcSpo2Trig_L_Thd; \r
+ }else\r
+ { \r
+ *punTemp_H_Thd = g_unNewAgcGeneTrig_H_Thd;\r
+ *punTemp_L_Thd = g_unNewAgcGeneTrig_L_Thd; \r
+ }\r
+}\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void Gh3x2xNewAgcSubChnlModuleReset(void)\r
+{\r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcSubChnlRxInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT*sizeof(STGh3x2xNewAgcSubChnlRxInfo));\r
+ #endif\r
+}\r
+\r
+GU8 GH3x2xNewAgcSetNewSubChnl(GU8 uchSlotNo, GU8 uchRxEn, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GU8 uchSetSuccess = 1;\r
+ for(GU8 uchRxCnt = 0; uchRxCnt < 4; uchRxCnt ++)\r
+ {\r
+ if(uchRxEn&(1 << uchRxCnt))\r
+ {\r
+ uchSetSuccess = 0;\r
+ for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+ {\r
+ STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+ if(0 == pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn = 1;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->uchSlotAdcNo = (uchSlotNo << 2) + uchRxCnt;\r
+ //read current gain\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchRxCnt, uchSlotNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] Sub chnl current Gain = %d, Slot = %d, Rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain,uchSlotNo,uchRxCnt);\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain, uchSlotNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] usTrigeUpLimitForBiggerGain = %d, Slot = %d, Rx = %d\r\n",((GU32)pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain)<<8,uchSlotNo,uchRxCnt);\r
+ GH3X2X_StoreRxTiaGainAfterAgc(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain, uchSlotNo, uchRxCnt, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ uchSetSuccess = 1;\r
+ break;\r
+ }\r
+ }\r
+ if(0 == uchSetSuccess)\r
+ {\r
+ GH3X2X_INFO_LOG("[NewAgc] Set new sub chnl fail !!! Slot = %d, Rx = %d\r\n",uchSlotNo,uchRxCnt);\r
+ while(1);\r
+ }\r
+ }\r
+ }\r
+ return uchSetSuccess;\r
+}\r
+#endif\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void GH3X2X_NewAgcSubChnlGainAdj(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+ { \r
+ GU16 usAnalysisDiscardLen;\r
+ GU16 usAnalysisEndLen;\r
+ GU8 uchSlotCnt;\r
+ GU8 uchSlotIdx;\r
+ GU8 uchAdcNo;\r
+ GU32 unTempTrigThd_L;\r
+ GU32 unTempTrigThd_H;\r
+ STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+ uchSlotIdx = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo >> 2;\r
+ uchAdcNo = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo&0x03;\r
+ uchSlotCnt = GH3X2X_NewAgcFindSubChnlSlotInfo(uchSlotIdx);\r
+ GU16 usSampleRate = g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].usSampleRate;\r
+ GU8 uchTiaGainLimit = g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt].uchTiaGainUpLimit;\r
+ usAnalysisDiscardLen = (usSampleRate<<1)/5; // 2/5 Fs\r
+ usAnalysisEndLen = usAnalysisDiscardLen + usSampleRate * GH3X2X_NEW_AGC_SUB_CHNNL_ANAYLSIS_TIME_SEC;\r
+ \r
+ GH3X_AgcGetThreshold(g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt].uchSpo2ChnlIndex,&unTempTrigThd_H, &unTempTrigThd_L); \r
+ \r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchEn)\r
+ {\r
+ // prevent unRawdataSum(GU32) overflow\r
+ if( (usAnalysisEndLen - usAnalysisDiscardLen) > 200 ) \r
+ {\r
+ usAnalysisDiscardLen = usAnalysisEndLen - 200; // maximum number of accumulated rawdata is 200\r
+ }\r
+ \r
+ for (GU16 usIndex = 0; usIndex < usFifoLen; usIndex += GH3X2X_AFE_FIFO_RAWDATA_SIZE) \r
+ {\r
+ GU32 unFifoVal;\r
+ GU8 uchSlotAdcNo;\r
+ GU32 unDataRaw; \r
+ unFifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchReadFifoBuffer[usIndex], puchReadFifoBuffer[usIndex + 1], \r
+ puchReadFifoBuffer[usIndex + 2], puchReadFifoBuffer[usIndex + 3]);\r
+ uchSlotAdcNo = ((unFifoVal >> 27)&0x0000001F);\r
+ unDataRaw = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unFifoVal);\r
+ if(uchSlotAdcNo == pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo)\r
+ {\r
+ if(usAnalysisDiscardLen == pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt) //init\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum = 0;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata = unDataRaw;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata = unDataRaw;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt = 0;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain = 0;\r
+ }\r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt < usAnalysisEndLen) //analysising\r
+ { \r
+ GU32 unTempRawdata = GH32x2xMedSel(pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata, pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata, unDataRaw);\r
+ if(usAnalysisDiscardLen == pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt)\r
+ {\r
+ GH3X2X_INFO_LOG("[NewAgc] sub chnl unTempRawdata = %d, Slot = %d, rx = %d\r\n",unTempRawdata, uchSlotIdx, uchAdcNo);\r
+ }\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum += unTempRawdata;\r
+ if(unTempRawdata > unTempTrigThd_H)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usMoreThanUpLimitPointCnt ++;\r
+ }\r
+ if((unTempRawdata >> 8) > pstSTGh3x2xNewAgcSubChnlRxInfo->usTrigeUpLimitForBiggerGain)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usMoreThanUpLimitPointCntForBiggerGain ++;\r
+ }\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata = pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata = unDataRaw;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt ++; \r
+ }\r
+ else //anlysis finished\r
+ {\r
+ GU32 unAvaRawdata;\r
+ GU16 unRealAnaylsisNum = usAnalysisEndLen - usAnalysisDiscardLen;\r
+ GU8 uchNextGain = 0xFF;\r
+ GU8 uchCurrentGain = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain;\r
+ unAvaRawdata = pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum/unRealAnaylsisNum;\r
+ GH3X2X_INFO_LOG("[NewAgc] sub chnl rawdata ava = %d,DownLimit = %d, Slot = %d, rx = %d\r\n",unAvaRawdata, unTempTrigThd_L,uchSlotIdx, uchAdcNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] usMoreThanUpLimitPointCnt = %d,UpLimit = %d, Slot = %d, rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt, unTempTrigThd_H,uchSlotIdx, uchAdcNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] usMoreThanUpLimitPointCntForBiggerGain = %d,UpLimit = %d, Slot = %d, rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain, ((GU32)pstSTGh3x2xNewAgcSubChnlRxInfo->usTrigeUpLimitForBiggerGain)<<8, uchSlotIdx, uchAdcNo);\r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt > (unRealAnaylsisNum >> 3)) // 1/8 points is bigger than trige up limit\r
+ {\r
+ if(uchCurrentGain > 0)\r
+ {\r
+ uchNextGain = uchCurrentGain - 1;\r
+ }\r
+ }\r
+ if((pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain < (unRealAnaylsisNum >> 3))&&(unAvaRawdata < unTempTrigThd_L))\r
+ {\r
+ if(uchCurrentGain < uchTiaGainLimit)\r
+ {\r
+ uchNextGain = uchCurrentGain + 1;\r
+ }\r
+ }\r
+ if(0xFF != uchNextGain)\r
+ { \r
+ GH3X2X_INFO_LOG("[NewAgc] sub chnl gain change: NewGain = %d, OldGain = %d, Slot = %d, rx = %d\r\n",uchNextGain,uchCurrentGain, uchSlotIdx, uchAdcNo);\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchAdcNo, uchSlotIdx, uchNextGain);\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = uchNextGain;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(uchNextGain, uchSlotIdx); \r
+ GH3X2X_StoreRxTiaGainAfterAgc(uchNextGain, uchSlotIdx, uchAdcNo, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ }\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt = 0; \r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+#endif\r
+\r
+\r
+/*********************************************self-test function start*****************************************/\r
+#define GH3X2X_SPO2_SELF_TEST 0\r
+\r
+#if GH3X2X_SPO2_SELF_TEST\r
+const GU32 g_uchSpo2AgcSelftestSlotAdc = 0x01; //slot0, adc1\r
+const GU32 g_usSpo2AgcFifoLen = 25*4;\r
+const GU32 g_unSpo2AgcRawdata[] = \r
+{\r
+ 10111744,9818116,10074798,9832931,10038819,9812989,10067119,9791632,10220862,9843610,9888564,9974512,10041146,10117796,9858828,10260863,9900963,10159857,10259720,10054459,10247477,9957985,10078474,9916146,9821879\r
+};\r
+\r
+GU8 g_uchSpo2AgcFifoBuffer[4*100];\r
+\r
+void GH3X2X_Spo2AgcFifoDataGen(void)\r
+{\r
+ for (GU16 usIndex = 0; usIndex < g_usSpo2AgcFifoLen; usIndex += GH3X2X_AFE_FIFO_RAWDATA_SIZE) \r
+ {\r
+ if(usIndex >= sizeof(g_uchSpo2AgcFifoBuffer))\r
+ {\r
+ break;\r
+ }\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 0] = (g_uchSpo2AgcSelftestSlotAdc<<3);\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 1] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 16));\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 2] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 8));\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 3] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 0));\r
+ }\r
+}\r
+#endif\r
+/*********************************************self-test function end*****************************************/\r
+\r
+\r
+/****************************************************************\r
+* Description: calculate mean value of main channel \r
+* Input: rawdata \r
+* Return: none\r
+******************************************************************/\r
+static void GH3X2X_NewAgcMainChnlMeanValueCal(GU8* puchReadFifoBuffer, GU16 usFifoLen, GU32 *punRawdataMean, GU8 *pAdjFlag)\r
+{\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ {\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ GU8 uchMainChnlSlotAdcNo = pstAgcMainChnlInfo ->uchSlotAdc;\r
+ \r
+ if(pstAgcMainChnlInfo ->uchEnable) // is enabled slot\r
+ { \r
+ GU32 unTemp_Trig_H_Thd; \r
+ GU32 unTemp_Trig_L_Thd; \r
+ GU32 unTemp_Ideal_value;\r
+ GU16 usAnalysisEndLen; \r
+ GU16 usAnalysisDiscardLenAdjust = 0;\r
+ GU16 usAnalysisDiscardLenTrige;\r
+ GU32 TrigeMean = 0; \r
+\r
+ if(pstAgcMainChnlInfo->uchSpo2ChnlIndex) // is spo2 slot\r
+ {\r
+ unTemp_Ideal_value= g_unNewAgcSpo2Ideal_value;\r
+ }else\r
+ { \r
+ unTemp_Ideal_value= g_unNewAgcGeneIdeal_value;\r
+ }\r
+ GH3X_AgcGetThreshold( pstAgcMainChnlInfo->uchSpo2ChnlIndex, &unTemp_Trig_H_Thd, &unTemp_Trig_L_Thd); \r
+ \r
+ STGh3x2xNewAgcMainChnlMeanInfo *pstNewAgcMainChnlMeanInfo = &g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt];\r
+ STGh3x2xNewAgcMainChnlIdaelAdjInfo *pstNewAgcMainChnlIdaelAdjInfo = &g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity[uchSlotCnt];\r
+ GU16 usSampleRate = pstNewAgcMainChnlMeanInfo->usSampleRate;\r
+ usAnalysisEndLen = (usSampleRate<<2)/5; // 4/5 Fs \r
+ usAnalysisDiscardLenTrige = (usSampleRate<<1)/5; // drop the first 2/5 data \r
+ //have agc motion at last fifo read period or first init \r
+ if(pstNewAgcMainChnlMeanInfo->uchHaveAgcAtLastReadPrd) \r
+ {\r
+ usAnalysisDiscardLenAdjust = (usSampleRate<<1)/5; // drop the first 2/5 data\r
+ //// After AGC, the previous data is drop to calcluate precise mean\r
+ if(!pstNewAgcMainChnlMeanInfo->uchDropFlag)\r
+ { // The frame count is only cleared for the first time to prevent data num cannot to be SampleRate\r
+ pstNewAgcMainChnlMeanInfo->usAnalysisCnt = 0; \r
+ pstNewAgcMainChnlMeanInfo->uchDropFlag = 1;\r
+ } \r
+ }\r
+ //The data fluctuates when initializing the early stage \r
+ if(!pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst) \r
+ {\r
+ usAnalysisDiscardLenAdjust = (usSampleRate<<1)/5; // drop the first 2/5 data\r
+ }\r
+\r
+ // prevent unSumAdjust(GU32) overflow\r
+ if( (usAnalysisEndLen - usAnalysisDiscardLenAdjust) > 200 )\r
+ {\r
+ usAnalysisDiscardLenAdjust = usAnalysisEndLen - 200; // maximum number of accumulated rawdata is 200\r
+ }\r
+ \r
+ if( (usAnalysisEndLen - usAnalysisDiscardLenTrige) > 200 )\r
+ {\r
+ usAnalysisDiscardLenTrige = usAnalysisEndLen - 200;\r
+ }\r
+\r
+ for (GU16 usIndex = 0; usIndex < usFifoLen; usIndex += GH3X2X_AFE_FIFO_RAWDATA_SIZE) \r
+ {\r
+ GU32 unFifoVal;\r
+ GU8 uchSlotAdcNo;\r
+ GU32 unDataRaw; \r
+ unFifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchReadFifoBuffer[usIndex], puchReadFifoBuffer[usIndex + 1], \r
+ puchReadFifoBuffer[usIndex + 2], puchReadFifoBuffer[usIndex + 3]);\r
+ uchSlotAdcNo = ((unFifoVal >> 27)&0x0000001F);\r
+ unDataRaw = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unFifoVal); \r
+ //GH3X2X_INFO_LOG_SPO2("uchSlotAdcNo = %d\r\n",uchSlotAdcNo);\r
+ //GH3X2X_INFO_LOG_SPO2("uchMainChnlSlotAdcNo = %d\r\n",uchMainChnlSlotAdcNo);\r
+ if(uchSlotAdcNo == uchMainChnlSlotAdcNo)\r
+ {\r
+ // begin Saturation judge \r
+ { \r
+ GU16 usSat_Check_Num_Max = (usSampleRate<<2) + usSampleRate; //// 5 seconds window\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt]++;\r
+ if( unDataRaw > unTemp_Trig_H_Thd)\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt]++;\r
+ }\r
+ //// as soon as posible set the Saturation flag \r
+ if( g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] >= (usSat_Check_Num_Max>>4) ) // about 8% of all checked data\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_flag |= (1<<uchSlotCnt); \r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] = 0; \r
+ } \r
+\r
+ if(g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt] >= usSat_Check_Num_Max ) \r
+ { \r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] = 0;\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt] = 0; \r
+ } \r
+ } \r
+ // end Saturation judge \r
+ \r
+ //// begin mean calculate \r
+ ////GH3X2X_INFO_LOG_PARAM("slot = %d, uchSlotAdcNo = %d\r\n",uchSlotCnt,uchSlotAdcNo);\r
+ \r
+ if(usAnalysisDiscardLenAdjust == pstNewAgcMainChnlMeanInfo->usAnalysisCnt) //init\r
+ {\r
+ pstNewAgcMainChnlMeanInfo->unSumAdjust = 0;\r
+ pstNewAgcMainChnlMeanInfo->unMaxRawdata = 0; \r
+ pstNewAgcMainChnlMeanInfo->unMinRawdata = 16777216;\r
+ }\r
+ \r
+ if(usAnalysisDiscardLenTrige == pstNewAgcMainChnlMeanInfo->usAnalysisCnt) //init\r
+ {\r
+ pstNewAgcMainChnlMeanInfo->unSumTrige = 0;\r
+ } \r
+ \r
+ if(pstNewAgcMainChnlMeanInfo->usAnalysisCnt < usAnalysisEndLen) //analysising\r
+ {\r
+ pstNewAgcMainChnlMeanInfo->unSumAdjust += unDataRaw;\r
+ pstNewAgcMainChnlMeanInfo->unSumTrige += unDataRaw;\r
+ pstNewAgcMainChnlMeanInfo->usAnalysisCnt++; \r
+ pstNewAgcMainChnlMeanInfo->unMaxRawdata = ((unDataRaw > pstNewAgcMainChnlMeanInfo->unMaxRawdata)? unDataRaw: pstNewAgcMainChnlMeanInfo->unMaxRawdata ); // Max of rawdata\r
+ pstNewAgcMainChnlMeanInfo->unMinRawdata = ((unDataRaw < pstNewAgcMainChnlMeanInfo->unMinRawdata)? unDataRaw: pstNewAgcMainChnlMeanInfo->unMinRawdata ); // Min of rawdata\r
+ }\r
+ else //anlysis finished calculate mean and judge whether AGC\r
+ { \r
+ // mean value to calculate gain and current\r
+ if(usAnalysisEndLen > usAnalysisDiscardLenAdjust)\r
+ {\r
+ punRawdataMean[uchSlotCnt] = pstNewAgcMainChnlMeanInfo->unSumAdjust/(usAnalysisEndLen - usAnalysisDiscardLenAdjust); \r
+ TrigeMean = pstNewAgcMainChnlMeanInfo->unSumTrige / (usAnalysisEndLen - usAnalysisDiscardLenTrige);\r
+ }else // The normal case will not be executed, in case the division by 0 in abnormal case\r
+ {\r
+ punRawdataMean[uchSlotCnt] = unDataRaw; \r
+ TrigeMean = unDataRaw; \r
+ }\r
+ pstNewAgcMainChnlMeanInfo ->unRawdataMean = punRawdataMean[uchSlotCnt];\r
+ pstNewAgcMainChnlMeanInfo->usAnalysisCnt=0;\r
+ // The mean calculation key variable is cleared (Prevent mean calculation from being too small:Accumulation lost some data, but numble of raw is all) \r
+ usAnalysisDiscardLenAdjust = 0; \r
+ pstNewAgcMainChnlMeanInfo->uchHaveAgcAtLastReadPrd = 0; // clear after caculate mean!!! \r
+ //// end mean calculate\r
+\r
+ ///////////////////// whether AGC and adjust the mean value to calculate gain and current\r
+ if( (TrigeMean < unTemp_Trig_L_Thd) || (TrigeMean > unTemp_Trig_H_Thd) )\r
+ {\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ }\r
+ \r
+ if( g_pstGh3x2xNewAgcMainChnlSat.Sat_flag & (1<<uchSlotCnt)) //if the channel is saturation\r
+ {\r
+ GU32 unTempMean = 0; //Pay attention to initialization of local variables\r
+ if( pstNewAgcMainChnlMeanInfo->unMaxRawdata > unTemp_Trig_H_Thd)\r
+ {\r
+ /////////// Pay attention to data truncation, use 64-bi\r
+ unTempMean = (GS64)unTemp_Ideal_value*(GS64)(pstNewAgcMainChnlMeanInfo->unMaxRawdata)/15099494; // to adjust the max data to (0.8*2^23 + 2^23)\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ }\r
+ \r
+ if( punRawdataMean[uchSlotCnt] > unTemp_Ideal_value)\r
+ {\r
+ // adjust the mean value to calculate gain and current (reduce the DC amount)\r
+ punRawdataMean[uchSlotCnt] = ( (punRawdataMean[uchSlotCnt]>unTempMean)? punRawdataMean[uchSlotCnt]:unTempMean );\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ } \r
+ else if( pstNewAgcMainChnlMeanInfo->unMaxRawdata > unTemp_Trig_H_Thd)\r
+ {\r
+ punRawdataMean[uchSlotCnt] = unTempMean; // Increasing the mean value to reduce the DC amount\r
+ } \r
+ }\r
+ ////////////////////////////////////////////////////\r
+ //////////////begin ideal value adjust \r
+ if( (!((*pAdjFlag) & (1<<uchSlotCnt))) && (!( g_pstGh3x2xNewAgcMainChnlSat.Sat_flag & (1<<uchSlotCnt))))//if the channel not adjust and satuartion\r
+ {\r
+ //// The deviation of the mean and the ideal target value is above 1/16 and Data fluctuation is less than a certain value\r
+ if(((pstNewAgcMainChnlMeanInfo->unRawdataMean< ((unTemp_Ideal_value*(g_uchAgcConvergence_level-1))/g_uchAgcConvergence_level) ) \\r
+ || (pstNewAgcMainChnlMeanInfo->unRawdataMean > ((unTemp_Ideal_value*(g_uchAgcConvergence_level+1))/g_uchAgcConvergence_level))) \\r
+ &&( 10*pstNewAgcMainChnlMeanInfo->unMaxRawdata< 12*pstNewAgcMainChnlMeanInfo->unMinRawdata) ) \r
+ {\r
+ if( !pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst ) //// Inite First time \r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst = 1;\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ }\r
+ else\r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt++;\r
+ if(pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt >= 19)\r
+ {\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt = 0; \r
+ } \r
+ } \r
+ }\r
+ else\r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt = 0;\r
+ } \r
+ }\r
+ else\r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt = 0;\r
+ }\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst = 1; //// Must be set to 1 after the first second!!! \r
+ ////end ideal value adjust \r
+ //GH3X2X_INFO_LOG_PARAM("Mean cal: Slot_num = %d, Rawmean = %d, Adjmean = %d, TrigeMean = %d, AdjFlag= %d\r\n", uchSlotCnt,pstNewAgcMainChnlMeanInfo->unRawdataMean, punRawdataMean[uchSlotCnt]);\r
+ //GH3X2X_INFO_LOG_PARAM("Sat flag: SatCnt = %d, SatCheck = %d, CheckMaxNum = %d, Satflag = %d\r\n", g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_Check_Num_Max[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_flag);\r
+ //GH3X2X_INFO_LOG_PARAM("Ideal adjust: SeconsCnt = %d\r\n", pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt);\r
+ //GH3X2X_INFO_LOG_PARAM("Adj flag: Slot_num = %d, Trigmean = %d, L_Thd = %d, H_Thd = %d, Adjflag = %d\r\n", uchSlotCnt,TrigeMean, unTemp_Trig_L_Thd, unTemp_Trig_H_Thd, *pAdjFlag); \r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_flag &= (~(1<<uchSlotCnt)) ; ////clear the Sat flag \r
+\r
+ }\r
+ } \r
+ }\r
+ }\r
+ \r
+ }\r
+}\r
+\r
+/**\r
+ * @fn GU8 GH3X2X_NewAgcCalDrvCurrentAndGain(GU32 CurRawdata, GU32 IdealRawdata, STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo, GU8* puchIdealDrvCurrent, GU8* puchIdealGain)\r
+ *\r
+ * @brief mark abnormal chnl\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] CurRawdata, IdealRawdata, uchMainChnlInfoIndex\r
+ * @param[out] puchIdealDrvCurrent, puchIdealGain\r
+ *\r
+ * @return 0:DrvCurrent or gain will NOT change 1: DrvCurrent or gain will change\r
+ */\r
+GU8 GH3X2X_NewAgcCalDrvCurrentAndGain(GU32 CurRawdata, GU8 uchMainChnlInfoIndex, GU8* puchIdealDrvCurrent, GU8* puchIdealGain)\r
+{\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchMainChnlInfoIndex];\r
+ STGh3x2xNewAgcMainChnlMeanInfo *pstMainChnlExtralInfo = &g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchMainChnlInfoIndex];\r
+\r
+ GU8 uchDefaultGain = pstAgcMainChnlInfo->uchBakTiaGain;\r
+ GU8 uchGainUpLimit = pstAgcMainChnlInfo->uchTiaGainUpLimit;\r
+ GU8 uchLedCurrentMin = pstAgcMainChnlInfo->uchBakRegLedCurrentMin;\r
+ GU8 uchLedCurrentMax = pstAgcMainChnlInfo->uchBakRegLedCurrentMax;\r
+ GU8 uchCurrentDrv = pstAgcMainChnlInfo->uchCurrentDrv;\r
+ GU8 uchCurrentTiaGain = pstAgcMainChnlInfo->uchCurrentTiaGain;\r
+ \r
+ GU8 uchNewGain = uchDefaultGain;\r
+ GU32 unIdealRawdata_no;\r
+ GU32 unTempDrvCurrent;\r
+ GU8 uchChangeFlag = 0; //bit0: drv current flag bit1: gain flag\r
+ GU8 uchCalFinish = 0;\r
+ GU32 unTrigUpLimit;\r
+ GU8 unCalNum = 12;\r
+ \r
+ if(0 != pstAgcMainChnlInfo->uchSpo2ChnlIndex) // is spo2 slot\r
+ {\r
+ unTrigUpLimit = g_unNewAgcSpo2Trig_H_Thd;\r
+ unIdealRawdata_no= g_unNewAgcSpo2Ideal_value - 8388608;\r
+ }else\r
+ {\r
+ unTrigUpLimit = g_unNewAgcGeneTrig_H_Thd;\r
+ unIdealRawdata_no = g_unNewAgcGeneIdeal_value - 8388608;\r
+ }\r
+ \r
+ //GH3X2X_INFO_LOG_PARAM("Drv cal: UpLimit = %d, Mean = %d, LastMean = %d\r\n",unTrigUpLimit, pstMainChnlExtralInfo->unRawdataMean, pstMainChnlExtralInfo->unLastRawdataMean);\r
+ // reduce rawdata as soon as posible\r
+ if((unTrigUpLimit < pstMainChnlExtralInfo->unRawdataMean)&&(unTrigUpLimit < pstMainChnlExtralInfo->unLastRawdataMean)&&(uchCurrentTiaGain > 0)) \r
+ { \r
+ uchNewGain = 0; \r
+ unTempDrvCurrent = uchLedCurrentMin;\r
+ uchCalFinish = 1;\r
+ }\r
+ pstMainChnlExtralInfo ->unLastRawdataMean = pstMainChnlExtralInfo ->unRawdataMean;\r
+ \r
+ if(0 == uchCalFinish)\r
+ {\r
+ //remove offset\r
+ if(CurRawdata > (8388608 + 2048)) //// Can't open DC Cance !!!\r
+ {\r
+ CurRawdata -= 8388608;\r
+ }\r
+ else\r
+ {\r
+ //The value may be less than 2^23, preventing division by 0\r
+ CurRawdata = 2048; // Take an appropriately large number to prevent calculated DRV current overflow 32bit\r
+ }\r
+ //Rawdata stretch (The principle of magnification: the mean divided by the ideal target value is the data reduction factor )\r
+ if(CurRawdata < 8000000)\r
+ {\r
+ }\r
+ else if(CurRawdata < 8100000)\r
+ {\r
+ CurRawdata = 8000000 + (CurRawdata - 8000000)*6;\r
+ }\r
+ else if(CurRawdata < 8200000)\r
+ {\r
+ CurRawdata = 8000000 + ((CurRawdata - 8000000)<<3);\r
+ }\r
+ else\r
+ {\r
+ // The more saturated the data, the bigger the stretch, the key is that the data is really saturated\r
+ CurRawdata = 8000000 + (CurRawdata - 8000000)*14; // Blood oxygen drops 1 times, heart rate drops 2.5 times \r
+ }\r
+\r
+ //find new drv current and gain\r
+ do\r
+ { \r
+ unTempDrvCurrent = (GS64)(((GU32)uchCurrentDrv*(GU32)g_usGH3x2xTiaGainR[uchCurrentTiaGain]))* \\r
+ (GS64)unIdealRawdata_no/g_usGH3x2xTiaGainR[uchNewGain]/CurRawdata;\r
+\r
+#if 0\r
+ //GH3X2X_INFO_LOG_PARAM("Drv cal %d: CurrentDrv = %d, CurrentGain = %d, IdealRawdata_no = %d\r\n",uchMainChnlInfoIndex, uchCurrentDrv, uchCurrentTiaGain, unIdealRawdata_no);\r
+ //GH3X2X_INFO_LOG_PARAM("Drv cal %d: unTempDrvCurrent = %d, uchNewGain = %d, Meanraw = %d, CurRawdata = %d\r\n",uchMainChnlInfoIndex,unTempDrvCurrent, uchNewGain, pstMainChnlExtralInfo->unRawdataMean, CurRawdata);\r
+#endif\r
+ \r
+ if(unTempDrvCurrent > uchLedCurrentMax) //drv is too big, need increase gain\r
+ {\r
+ if(uchNewGain < uchGainUpLimit)\r
+ {\r
+ uchNewGain ++ ;\r
+ }\r
+ else\r
+ {\r
+ unTempDrvCurrent = uchLedCurrentMax;\r
+ break;\r
+ }\r
+ }\r
+ else if(unTempDrvCurrent < uchLedCurrentMin) //drv is too small, need dncrease gain\r
+ {\r
+ if(uchNewGain > 0)\r
+ {\r
+ uchNewGain -- ;\r
+ }\r
+ else\r
+ {\r
+ unTempDrvCurrent = uchLedCurrentMin;\r
+ break;\r
+ }\r
+ }\r
+ else //got right drv\r
+ {\r
+ break;\r
+ }\r
+ unCalNum --;\r
+ }\r
+ while (unCalNum);\r
+ }\r
+\r
+ puchIdealDrvCurrent[0] = (GU8)unTempDrvCurrent;\r
+ puchIdealGain[0] = (GU8)uchNewGain;\r
+\r
+ if(puchIdealDrvCurrent[0] != uchCurrentDrv)\r
+ {\r
+ uchChangeFlag |= 0x01;\r
+ //GH3X2X_INFO_LOG_PARAM("Drv change %d: CurrentDrv = %d, IdealDrv = %d\r\n",uchMainChnlInfoIndex, uchCurrentDrv, puchIdealDrvCurrent[0]);\r
+ }\r
+ if(puchIdealGain[0] != uchCurrentTiaGain)\r
+ {\r
+ uchChangeFlag |= 0x02;\r
+ //GH3X2X_INFO_LOG_PARAM("Gain change %d: CurrentGain = %d, IdealGain = %d\r\n",uchMainChnlInfoIndex, uchCurrentTiaGain, puchIdealGain[0]);\r
+ }\r
+ \r
+ return uchChangeFlag;\r
+}\r
+\r
+GU8 NewAgcMainChelFlag = 0;\r
+\r
+void GH3X2X_NewAgcMainChnlPro(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GU32 unNewAgcRawdataMeanChnl[8] = {0};\r
+ GU8 uchAdjFlag = 0; // Local variables used as judgments must be initialized to 0\r
+ GU8 uchNewDrvCurrent;\r
+ GU8 uchNewGain; \r
+ GU8 uchChangeFlag = 0; //bit0: drv current flag bit1: gain flag\r
+ \r
+ if(0 == GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+ {\r
+ return;\r
+ }\r
+\r
+#if GH3X2X_SPO2_SELF_TEST\r
+\r
+ GH3X2X_Spo2AgcFifoDataGen();\r
+ puchReadFifoBuffer = g_uchSpo2AgcFifoBuffer;\r
+ usFifoLen = g_usSpo2AgcFifoLen;\r
+#endif\r
+ \r
+ \r
+ GH3X2X_NewAgcMainChnlMeanValueCal( puchReadFifoBuffer,usFifoLen,unNewAgcRawdataMeanChnl,&uchAdjFlag); // caculate mean and whther adjust gain current \r
+ \r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ {\r
+ if( uchAdjFlag & (1<<uchSlotCnt)) // need to AGC\r
+ {\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ uchChangeFlag = GH3X2X_NewAgcCalDrvCurrentAndGain(unNewAgcRawdataMeanChnl[uchSlotCnt], uchSlotCnt, &uchNewDrvCurrent,&uchNewGain);\r
+ GU8 uchSlotIdx = ((pstAgcMainChnlInfo ->uchSlotAdc >> 2) & 0x0f);\r
+ if(uchChangeFlag&0x02) //write tia gain to chip\r
+ { \r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx, uchNewGain); \r
+ pstAgcMainChnlInfo->uchCurrentTiaGain = uchNewGain;\r
+ GH3X2X_StoreRxTiaGainAfterAgc(uchNewGain, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegAgcSrc, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ }\r
+ if(uchChangeFlag&0x01) //write drv current to chip\r
+ {\r
+ //change drv0/1\r
+ pstAgcMainChnlInfo ->uchCurrentDrv = uchNewDrvCurrent;\r
+ \r
+ if((pstAgcMainChnlInfo ->uchBakRegAgcEn)&0x01)\r
+ {\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV0, uchSlotIdx, uchNewDrvCurrent); \r
+ GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,0,STGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+ }\r
+ if((pstAgcMainChnlInfo ->uchBakRegAgcEn)&0x02)\r
+ {\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV1, uchSlotIdx, uchNewDrvCurrent); \r
+ GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,1,STGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+ }\r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(uchSlotIdx, 0x0F, 0xFF); //clear all rx analysis cnt in this slot\r
+ #endif\r
+ }\r
+ if(uchChangeFlag)\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].uchHaveAgcAtLastReadPrd = 1; // current or gain change at last time\r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].uchDropFlag = 0;\r
+ NewAgcMainChelFlag |= (1<<uchSlotCnt); // ADjFlag write to CSV file\r
+ } \r
+ } \r
+ } \r
+}\r
+\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+/**\r
+ * @fn static void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+ * \r
+ * @brief init led agc\r
+ *\r
+ * @attention just use to show function support\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GH3X2X_RecordAgcInfo(); //record agc info\r
+ GH3x2xNewAgcChnlInfoInit(STGh3x2xAgcInfo);\r
+}\r
+/**\r
+ * @fn void GH3X2X_LedAgcPramWrite(GU16 usRegVal, GU16 usRegPosi)\r
+ *\r
+ * @brief write AGC parameter\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegVal reg value\r
+ * @param[in] uchRegPosi reg posi\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_LedAgcPramWrite(GU16 usRegVal, GU16 usRegPosi)\r
+{\r
+\r
+ GU16 usByteOffset;\r
+ GU8 uchByteVal;\r
+ GU8 uchByteCnt;\r
+ for(uchByteCnt = 0; uchByteCnt < 2; uchByteCnt ++)\r
+ {\r
+ uchByteVal = ((usRegVal >> (8*uchByteCnt))&0x00FF);\r
+ usByteOffset = (usRegPosi * 2) + uchByteCnt;\r
+ if(usByteOffset < sizeof(g_stSoftAgcCfg))\r
+ {\r
+ GH3X2X_Memcpy(((GU8 *)(&g_stSoftAgcCfg)) + usByteOffset, (GU8*)(&uchByteVal), 1);\r
+ } \r
+ }\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_LedAgcReset(void)\r
+ *\r
+ * @brief reset agc parameter\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_LedAgcReset(void)\r
+{\r
+ GH3X2X_Memset(&g_stSoftAgcCfg, 0, sizeof(STSoftAgcCfg));\r
+ GH3x2xNewAgcModuleReset();\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen)\r
+ * \r
+ * @brief led agc process function\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchReadFifoBuffer pointer to read fifo data buffer\r
+ * @param[in] usFifoLen read fifo data buffer length\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GH3X2X_UpdateAgcInfo();\r
+ if(usFifoLen==0)\r
+ {\r
+ return;\r
+ }\r
+ \r
+ GH3X2X_NewAgcMainChnlPro(puchReadFifoBuffer, usFifoLen,STGh3x2xAgcInfo);\r
+ \r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3X2X_NewAgcSubChnlGainAdj(puchReadFifoBuffer, usFifoLen,STGh3x2xAgcInfo);\r
+#endif\r
+ \r
+}\r
+#endif\r
+#endif\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
--- /dev/null
+#include "gh3x2x_afe_ecg.h"\r
+#include "gh3x2x_afe_adt.h"\r
+#include "gh3x2x_afe_agc.h"\r
+#include "gh3x2x_afe_demo.h"\r
+\r
+\r
+\r
+GU32 g_unFuncMode = GH3X2X_NO_FUNCTION;\r
+\r
+\r
+\r
+void GH3X2X_AFE_StartFunction(GU32 unFuncMode)\r
+{\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ADT))\r
+ {\r
+ GH3x2xAdtAlgoInit();\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ADT_SLOT_NUM,GH3X2X_ADT_SLOT_NUM,1);\r
+ }\r
+ \r
+ if(unFuncMode & (GH3X2X_FUNCTION_ECG))\r
+ {\r
+ GH3X2X_LeadOffDetectInit(); \r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ECG_SLOT_NUM,GH3X2X_ECG_SLOT_NUM,1);\r
+ ECG_FAST_RECV_EN_CONFIG(1);\r
+ }\r
+ \r
+ if(g_unFuncMode == GH3X2X_NO_FUNCTION)\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,1);\r
+ }\r
+ g_unFuncMode |= unFuncMode;\r
+\r
+}\r
+\r
+\r
+void GH3X2X_AFE_StopFunction(GU32 unFuncMode)\r
+{\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ADT))\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ADT_SLOT_NUM,GH3X2X_ADT_SLOT_NUM,0);\r
+ GH3x2xAdtAlgoDeinit();\r
+ }\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ECG))\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ECG_SLOT_NUM,GH3X2X_ECG_SLOT_NUM,0);\r
+ ECG_FAST_RECV_EN_CONFIG(0);\r
+\r
+ }\r
+ g_unFuncMode &= (~unFuncMode);\r
+ if(g_unFuncMode == GH3X2X_NO_FUNCTION)\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,0);\r
+ }\r
+ \r
+}\r
+\r
+\r
+void GH3X2X_AFE_Leadon_hook(void)\r
+{\r
+ GH3X2X_AFE_StartFunction(GH3X2X_FUNCTION_ECG);\r
+}\r
+\r
+void GH3X2X_AFE_Leadoff_hook(void)\r
+{\r
+ GH3X2X_AFE_StopFunction(GH3X2X_FUNCTION_ECG);\r
+ ECG_LEAD_DET_EN_CONFIG(0);// enable lead detect\r
+ ECG_LEAD_DET_EN_CONFIG(1);// enable lead detect\r
+ \r
+}\r
+\r
+\r
+void GH3X2X_DemoLedAgcPramConfig(void)\r
+{\r
+ static STSoftAgcCfg stSoftAgcCfg;\r
+\r
+ stSoftAgcCfg.uchSlotxSoftAgcAdjEn = 1; //bit0-bit7: slot0 -slot7 \r
+ stSoftAgcCfg.uchSlotxSoftBgAdjEn = 0;\r
+ stSoftAgcCfg.stAmbSlotCtrl.uchAmbSampleEn = 0;\r
+ stSoftAgcCfg.uchSpo2RedSlotCfgEn = 2; //bit0-bit7: slot0 -slot7 for spo2 red \r
+ stSoftAgcCfg.uchSpo2IrSlotCfgEn = 4; //bit0-bit7: slot0 -slot7 for spo2 ir\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA = 8;\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA = 6;\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA = 5;\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA = 4;\r
+ stSoftAgcCfg.unAgcTrigThd_H = (GU32)(8388608 + 8388608*0.85f);\r
+ stSoftAgcCfg.unAgcTrigThd_L = (GU32)(8388608 + 8388608*0.15f);\r
+ stSoftAgcCfg.unAgcRestrainThd_H = 12868608;\r
+ stSoftAgcCfg.unAgcRestrainThd_L = 10692608;\r
+ \r
+ GH3X2X_LedAgcPramConfig(&stSoftAgcCfg);\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/**\r
+ * @copyright (c) 2019 - 2024, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file gh3x2x_afe_drv.c\r
+ * \r
+ * @brief gh3x2x driver example code\r
+ *\r
+ * @author Gooidx Iot Team\r
+ * \r
+ * @attention\r
+ * This file just show how to init and control gh3x2x sampling.\r
+ */\r
+#include "stdio.h"\r
+#include "gh3x2x_afe_drv.h"\r
+#include "gh3x2x_afe_user.h"\r
+#include "gh3x2x_afe_ecg.h"\r
+#include "gh3x2x_afe_agc.h"\r
+#include "gh3x2x_afe_adt.h"\r
+#include "gh3x2x_afe_demo.h"\r
+\r
+#include "custom_utils.h"\r
+\r
+ \r
+#define SWAP_SIZE_OF_GU16 (2)\r
+#define SWAP_INDEX_OF_NEXT_BYTE (1)\r
+\r
+#define GH3X2X_I2C_BUS I2C_BUS_2\r
+\r
+//extern void GH3X2X_SoftLedADJAutoADJInt(void);\r
+//extern void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen);\r
+//extern void GH3X2X_LedAgcReset(void);\r
+//extern void GH3X2X_LedAgcPramWrite(void);\r
+//extern void GH3X2X_LedAgcInit(void);\r
+\r
+STGh3x2xAgcInfo g_stGh3x2xAgcInfo = {0};\r
+STGh3x2xAgcInfo *g_pstGh3x2xAgcInfo = &g_stGh3x2xAgcInfo;\r
+\r
+GU8 g_uchNeedWakeUpGh3x2xAfe = 1; // 0: do not need wake up gh3x2x 1: need wake up gh3x2x\r
+GU8 g_uchGh3x2xAfeIntCallBackIsCalled = 0; //0: no new interrupt 1: have new interrupt\r
+\r
+/*********************************************** reg cfg package *******************************************/\r
+STGH3X2X_AFEReg GH3X2X_AFE_reg_list[] =\r
+{\r
+// {0x0000, 0x0610}, {0x0004, 0x001F}, {0x0006, 0x0001}, {0x000A, 0x0010}, {0x000E, 0x000D}, {0x0100, 0x0100},\r
+// {0x010A, 0x27FC}, {0x0110, 0x0F65}, {0x0114, 0x00AA}, {0x011E, 0x021F}, {0x0120, 0x041F}, {0x0122, 0x137F},\r
+// {0x0126, 0xC77C}, {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA}, {0x013A, 0x010C}, {0x013C, 0x0400},\r
+// {0x01EC, 0x027C}, {0x01EE, 0x00AC}, {0x0200, 0x0120}, {0x0208, 0x0551}, {0x0280, 0x0A00}, {0x0282, 0xF530},\r
+// {0x0284, 0x9388}, {0x0286, 0xC45C}, {0x0288, 0xA328}, {0x0408, 0x0001}, {0x0410, 0x49F0}, {0x0412, 0x0082},\r
+// {0x0414, 0x49F0}, {0x0416, 0x0082}, {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0108}, {0x0428, 0x0102},\r
+// {0x0502, 0x4360}, {0x0504, 0x000A}, {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0400}, {0x0698, 0x2310},\r
+// {0x0700, 0x0000}, \r
+ \r
+// {0x0000, 0x0602}, {0x0004, 0x0013}, {0x0006, 0x0201}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0048},\r
+// {0x0100, 0x0100}, {0x010A, 0x0462}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x0120, 0x0400},\r
+// {0x0126, 0xC73C}, {0x0128, 0x0404}, {0x012A, 0x0404}, {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA},\r
+// {0x0136, 0x00FF}, {0x013A, 0x000C}, {0x013C, 0x0400}, {0x01EA, 0x0033}, {0x01EC, 0x0030}, {0x01EE, 0x0098},\r
+// {0x0200, 0x1020}, {0x0402, 0x5555}, {0x0404, 0x4120}, {0x0406, 0x0041}, {0x0408, 0x0001}, {0x0410, 0x49F0},\r
+// {0x0412, 0x0082}, {0x0414, 0x49F0}, {0x0416, 0x0082}, {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0109},\r
+// {0x0428, 0x0108}, {0x0480, 0x6550}, {0x0502, 0x4C66}, {0x0506, 0x0020}, {0x0588, 0x0008}, {0x0692, 0x0233},\r
+// {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000}, {0x0400, 0x5557}, {0x1000, 0x0000},\r
+// {0x1002, 0x3197}, {0x1004, 0x0000}, {0x1006, 0x6C91}, {0x1008, 0x2CE1}, {0x100A, 0x0001}, {0x10E0, 0x0000},\r
+// {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202}, {0x10EC, 0x0202},\r
+// {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000}, {0x2000, 0x0004}, {0x2002, 0x2A22},\r
+// {0x2004, 0x3A32}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005}, {0x288E, 0x00FA}, {0x3000, 0x0101},\r
+// {0x3002, 0x0000}, {0x3004, 0x49F0}, {0x3006, 0x0082}, {0x4500, 0x46C9}, {0x4502, 0x0F0F}, {0x4504, 0x0002},\r
+// {0x4506, 0x0140}, {0xFFFF, 0x0001}\r
+\r
+ {0x0000, 0x0610}, {0x0004, 0x001F}, {0x0006, 0x0001}, {0x000A, 0x0050}, {0x000E, 0x000D}, {0x0100, 0x0100},\r
+ {0x010A, 0x277C}, {0x0110, 0x0D14}, {0x0112, 0x5555}, {0x0114, 0x00AA}, {0x011E, 0x0019}, {0x0120, 0x0400},\r
+ {0x0122, 0x0CFF}, {0x0126, 0xC704}, {0x0128, 0x0001}, {0x012A, 0x0000}, {0x012C, 0x0C10}, {0x012E, 0x4442},\r
+ {0x0130, 0x0002}, {0x0136, 0x0003}, {0x013A, 0x010C}, {0x013C, 0x0400}, {0x01EC, 0x0136}, {0x01EE, 0x00AC},\r
+ {0x0200, 0x0120}, {0x0208, 0x0551}, {0x0280, 0x0A00}, {0x0282, 0xF530}, {0x0284, 0x9388}, {0x0286, 0xC45C},\r
+ {0x0288, 0xA328}, {0x0408, 0x0001}, {0x0410, 0x49F0}, {0x0412, 0x0082}, {0x0414, 0x49F0}, {0x0416, 0x0082},\r
+ {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0108}, {0x0428, 0x0102}, {0x0502, 0x4F60}, {0x0504, 0x000A},\r
+ {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0400}, {0x0698, 0x2310}, {0x0700, 0x0000}, {0x1000, 0x0000},\r
+ {0x1002, 0x3197}, {0x1004, 0x0000}, {0x1006, 0x6904}, {0x1008, 0x2AF6}, {0x100A, 0x0001}, {0x10E0, 0x0000},\r
+ {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202}, {0x10EC, 0x0202},\r
+ {0x10EE, 0x0202}, {0x1100, 0x0004}, {0x1102, 0x0000}, {0x1120, 0x0050}, {0x1122, 0x0005}, {0x1124, 0x0000},\r
+ {0x1140, 0x0000}, {0x1142, 0x00C8}, {0x1144, 0x0001}, {0x1160, 0x0001}, {0x1162, 0x0000}, {0x1164, 0x0000},\r
+ {0x1166, 0x4568}, {0x1168, 0xCCCC}, {0x116A, 0x00EC}, {0x116C, 0x3333}, {0x116E, 0x0093}, {0x1170, 0x5C00},\r
+ {0x1172, 0x00C4}, {0x1174, 0x2800}, {0x1176, 0x00A3}, {0x2000, 0x0001}, {0x2002, 0x0022}, {0x2022, 0x0004},\r
+ {0x2024, 0x0901}, {0x2026, 0x1911}, {0x2880, 0x0005}, {0x2882, 0x0019}, {0x3000, 0x0001}, {0x3002, 0x0000},\r
+ {0x3004, 0x49F0}, {0x3006, 0x0082}, {0xFFFF, 0x0001}\r
+};\r
+\r
+GU16 GH3X2X_AFE_reg_list_len = sizeof(GH3X2X_AFE_reg_list) / sizeof(GH3X2X_AFE_reg_list[0]);\r
+\r
+\r
+void GH3X2X_SwapLittleBigEndianData(GU8 *puchDataBuffer, GU16 usDataLength)\r
+{\r
+ GU16 usIndex = 0;\r
+\r
+ for (usIndex = 0; usIndex < (usDataLength / SWAP_SIZE_OF_GU16); usIndex++)\r
+ {\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16] ^= \\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE];\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE] ^= \\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16];\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16] ^= \\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE];\r
+ }\r
+}\r
+\r
+\r
+#if ( GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_SPI )\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_SpiSendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief Send cmd via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] uchCmd spi cmd\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+void GH3X2X_AFE_SpiSendCmd(GU8 uchCmd)\r
+{\r
+ GU8 uchBuffArr[1];\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = uchCmd;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+#endif\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+void GH3X2X_AFE_SpiSendCmdHardwareCs(GU8 uchCmd)\r
+{\r
+ GU8 uchBuffArr[1];\r
+ uchBuffArr[0] = uchCmd;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+}\r
+#endif\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief Write register via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] usRegValue register data\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+void GH3X2X_AFE_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+ GU8 uchBuffArr[7];\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[3] = 0;\r
+ uchBuffArr[4] = 2;\r
+ uchBuffArr[5] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegValue);\r
+ uchBuffArr[6] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegValue);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 7);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+#endif\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+void GH3X2X_AFE_SpiWriteRegHardwareCs(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+ GU8 puchWriteBuf[7];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = usRegAddr>>8;\r
+ puchWriteBuf[2] = usRegAddr&0x00FF;\r
+ puchWriteBuf[3] = 0;\r
+ puchWriteBuf[4] = 2;\r
+ puchWriteBuf[5] = usRegValue>>8;\r
+ puchWriteBuf[6] = usRegValue&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 7);\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn static GU16 GH3X2X_AFE_SpiReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief Read register via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[out] None\r
+ *\r
+ * @return register data\r
+ */\r
+ \r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+GU16 GH3X2X_AFE_SpiReadReg(GU16 usRegAddr)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 3);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_READ;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_read(uchBuffArr, 2);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ return GH3X2X_AFE_MAKEUP_WORD(uchBuffArr[0], uchBuffArr[1]);\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen)\r
+ *\r
+ * @brief Read multi register via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] pusRegValueBuffer pointer to register value buffer\r
+ * @param[in] uchLen registers len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 3);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_READ;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_read((GU8 *)pusRegValueBuffer, uchLen * 2);\r
+ GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueBuffer, (GU16)((GU16)uchLen * 2));\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+\r
+#endif\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+GU16 GH3X2X_AFE_SpiReadRegHardwareCs(GU16 usRegAddr)\r
+{\r
+ GU8 puchWriteBuf[7];\r
+ GU8 puchReadBuf[2];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = usRegAddr>>8;\r
+ puchWriteBuf[2] = usRegAddr&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 3);\r
+ hal_gh3x2x_afe_spi_write_F1_and_read(puchReadBuf, 2);\r
+ return ((((GU16)puchReadBuf[0])<<8) + puchReadBuf[1]);\r
+}\r
+\r
+\r
+\r
+void GH3X2X_AFE_SpiReadRegsHardwareCs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen)\r
+{\r
+ GU8 puchWriteBuf[3];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = usRegAddr>>8;\r
+ puchWriteBuf[2] = usRegAddr&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 3);\r
+ hal_gh3x2x_afe_spi_write_F1_and_read((GU8 *)pusRegValueBuffer, uchLen * 2);\r
+ GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueBuffer, (GU16)((GU16)uchLen * 2));\r
+}\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_SpiReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief Read fifo via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchDataBuffer pointer to buffer for fifo rawdata\r
+ * @param[in] usLen fifo bytes len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+ \r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+static void GH3X2X_AFE_SpiReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 3);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_READ;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_read(puchDataBuffer, usLen);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+\r
+#endif\r
+\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+void GH3X2X_AFE_SpiReadFifoHardwareCs(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+ GU8 puchWriteBuf[3];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = 0xAAAA>>8;\r
+ puchWriteBuf[2] = 0xAAAA&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 3);\r
+ hal_gh3x2x_afe_spi_write_F1_and_read(puchDataBuffer, usLen);\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+#if ( GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_I2C )\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_I2cSendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief Send cmd via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] uchCmd i2c cmd\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_I2cSendCmd(GU8 uchCmd)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ uchBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(GH3X2X_AFE_I2C_CMD_ADDR);\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_I2C_CMD_ADDR);\r
+ uchBuffArr[2] = uchCmd;\r
+ hal_gh3x2x_afe_i2c_write(GH3X2X_AFE_I2C_DEVICE_ADDR, uchBuffArr, 3);\r
+ // custom_i2c_write_reg(GH3X2X_AFE_I2C_DEVICE_ADDR, GH3X2X_AFE_I2C_CMD_ADDR, 1 , &uchCmd, 1, GH3X2X_I2C_BUS);\r
+}\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief Write register via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] usRegValue register data\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+ GU8 uchBuffArr[4] = {0};\r
+\r
+ uchBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegValue);\r
+ uchBuffArr[3] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegValue);\r
+ hal_gh3x2x_afe_i2c_write(GH3X2X_AFE_I2C_DEVICE_ADDR, uchBuffArr, 4);\r
+ // custom_i2c_write_reg(GH3X2X_AFE_I2C_DEVICE_ADDR, usRegAddr, 1 , &usRegValue, szieof(usRegValue), GH3X2X_I2C_BUS);\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn static GU16 GH3X2X_I2cReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief Read register via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[out] None\r
+ *\r
+ * @return register data\r
+ */\r
+GU16 GH3X2X_AFE_I2cReadReg(GU16 usRegAddr)\r
+{\r
+ GU8 uchCmdBuffArr[2] = {0};\r
+ GU8 uchReadBuffArr[2] = {0};\r
+\r
+ uchCmdBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchCmdBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ hal_gh3x2x_afe_i2c_read(GH3X2X_AFE_I2C_DEVICE_ADDR, uchCmdBuffArr, 2, uchReadBuffArr, 2);\r
+\r
+ // custom_i2c_read_regs(GH3X2X_AFE_I2C_DEVICE_ADDR, usRegAddr, 1 , uchReadBuffArr, sizeof(uchReadBuffArr), GH3X2X_I2C_BUS);\r
+\r
+ return GH3X2X_AFE_MAKEUP_WORD(uchReadBuffArr[0], uchReadBuffArr[1]);\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU8 uchLen)\r
+ *\r
+ * @brief Read multi register via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] pusRegValueBuffer pointer to register value buffer\r
+ * @param[in] uchLen registers len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU8 uchLen)\r
+{\r
+ GU8 uchBuffArr[2] = {0};\r
+\r
+ // uchBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ // uchBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+\r
+ custom_i2c_read_regs(GH3X2X_AFE_I2C_DEVICE_ADDR, usRegAddr,1, pusRegValueArr, uchLen ,GH3X2X_I2C_BUS);\r
+\r
+ // hal_gh3x2x_afe_i2c_read(GH3X2X_AFE_I2C_DEVICE_ADDR, uchBuffArr, 2, \\r
+ // (GU8 *)pusRegValueArr, uchLen * 2);\r
+ GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueArr, (GU16)uchLen * 2);\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_I2cReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief Read fifo via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchDataBuffer pointer to buffer for fifo rawdata\r
+ * @param[in] usLen fifo bytes len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_I2cReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+ GU8 uchCmdBuffArr[2] = {0};\r
+\r
+ uchCmdBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ uchCmdBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ hal_gh3x2x_afe_i2c_read(GH3X2X_AFE_I2C_DEVICE_ADDR, uchCmdBuffArr, 2, puchDataBuffer, usLen);\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn void GH3X2X_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+ *\r
+ * @brief write register bit field via i2c or spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] uchLsb lsb of bit field\r
+ * @param[in] uchMsb msb of bit field\r
+ * @param[in] usRegValue register data\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+{\r
+ GU16 usMakData = ((((GU16)0x0001) << (uchMsb - uchLsb + 1)) - 1) << uchLsb;\r
+ GU16 usRegData = 0;\r
+ usRegData = GH3X2X_AFE_READ_REG(usRegAddr);\r
+ GH3X2X_VAL_CLEAR_BIT(usRegData, usMakData);\r
+ GH3X2X_VAL_SET_BIT(usRegData, (usValue << uchLsb) & usMakData);\r
+ GH3X2X_AFE_WRITE_REG(usRegAddr, usRegData);\r
+}\r
+\r
+/**\r
+ * @fn GU16 GH3X2X_AFE_READ_REGBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+ *\r
+ * @brief Read register bit field via i2c or spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] uchLsb lsb of bit field\r
+ * @param[in] uchMsb msb of bit field\r
+ * @param[out] None\r
+ *\r
+ * @return register bit field data\r
+ */\r
+GU16 GH3X2X_AFE_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+{\r
+ GU16 usMakData = ((((GU16)0x0001) << (uchMsb - uchLsb + 1)) - 1) << uchLsb;\r
+ GU16 usRegData = 0;\r
+ usRegData = GH3X2X_AFE_READ_REG(usRegAddr);\r
+ GH3X2X_AFE_VAL_GET_BIT(usRegData, usMakData);\r
+ usRegData >>= uchLsb;\r
+ return usRegData;\r
+}\r
+\r
+\r
+void GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(GU8 uchFlag)\r
+{\r
+ g_uchNeedWakeUpGh3x2xAfe = uchFlag;\r
+}\r
+\r
+GU8 GH3X2X_AFE_GetNeedWakeUpGh3x2xFlag(void)\r
+{\r
+ return g_uchNeedWakeUpGh3x2xAfe;\r
+}\r
+\r
+\r
+\r
+void GH3X2X_AFE_ExitLowPowerMode(void)\r
+{\r
+ GH3X2X_AFE_SEND_CMD(GH3X2X_AFE_CMD_WAKEUP);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_WAKE_UP_CMD_DELAY_X_US);\r
+}\r
+\r
+void GH3X2X_AFE_EnterLowPowerMode(void)\r
+{\r
+ GH3X2X_AFE_SEND_CMD(GH3X2X_AFE_CMD_SLEEP);\r
+ GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(1);\r
+}\r
+\r
+\r
+void GH3X2X_AFE_ClearEvent(GU16 usEvent)\r
+{\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_INT_EVENT_ADDR,usEvent);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_SendRegPackage(STGH3X2X_AFEReg* GH3X2X_AFE_reg_list, GU16 reg_list_len)\r
+ *\r
+ * @brief send register package (for initialize GH3X2X_AFE chip)\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GH3X2X_AFE_reg_list reg list that will be written to GH3X2X_AFE\r
+ * @param[in] reg_list_len reg count that contained in reg list\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_SendRegPackage(STGH3X2X_AFEReg* GH3X2X_AFE_reg_list, GU16 reg_list_len)\r
+{\r
+ GU16 luwIndex = 0;\r
+\r
+ if ((GH3X2X_AFE_reg_list != NULL) && (reg_list_len > 0))\r
+ {\r
+ for (luwIndex = 0; luwIndex < reg_list_len; luwIndex++)\r
+ {\r
+ if (GH3X2X_AFE_REG_IS_VALID(GH3X2X_AFE_reg_list->usRegAddr))\r
+ {\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_reg_list->usRegAddr, GH3X2X_AFE_reg_list->usRegData); \r
+ } \r
+ GH3X2X_AFE_reg_list++;\r
+ }\r
+ }\r
+\r
+ if(GH3X2X_AFE_PRO_TYPE == GH3X2X_AFE_PRO_BY_POLLING)\r
+ {\r
+ //int pin should not action when poling mode\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_INT_EVENT_EN_ADDR, 0); \r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn GS8 GH3X2X_HardReset(void)\r
+ *\r
+ * @brief Gh3x2x softreset via i2c/spi, can read&write reg with gh3x2x after reset\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ * @retval #GH3X2X_RET_OK return successfully\r
+ * @retval #GH3X2X_RET_GENERIC_ERROR reset pin control function not register\r
+ */\r
+void GH3X2X_AFE_Reset(void)\r
+{\r
+ GH3X2X_AFE_ClearEvent(0xFFFF);\r
+ #if(GH3X2X_AFE_RESET_TYPE == GH3X2X_AFE_RESET_HARDWARE)\r
+ hal_gh3x2x_afe_reset_pin_ctrl(0);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_HARD_RESET_DELAY_X_US); \r
+ hal_gh3x2x_afe_reset_pin_ctrl(1); \r
+ #else\r
+ GH3X2X_AFE_SEND_CMD(GH3X2X_AFE_CMD_RESET);\r
+ #endif\r
+ hal_gh3x2x_afe_DelayMs(10);\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn GS8 GH3X2X_CommunicateConfirm(void)\r
+ *\r
+ * @brief Communication operation interface confirm\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_CommunicateConfirm(void)\r
+{\r
+ GU16 uchReadData;\r
+ GU16 uchWriteData;\r
+ \r
+ if (GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_CHIP_READY_CODE_REG_ADDR) == 0xAA55)\r
+ {\r
+ uchReadData = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR);\r
+ GH3X2X_INFO_LOG("slot_time0 reg = %d\r\n", (int)uchReadData);\r
+ uchWriteData = ~uchReadData;\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR, uchWriteData);\r
+ uchReadData = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR);\r
+ GH3X2X_INFO_LOG("slot_time0 reg = %d\r\n", (int)uchReadData);\r
+ if (uchWriteData == uchReadData)\r
+ {\r
+ uchWriteData = ~uchReadData;\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR, uchWriteData);\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("[%s]read fail or write fail!!! \r\n", __FUNCTION__);\r
+ while(1);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("[%s]ready code reg is error !!! \r\n", __FUNCTION__);\r
+ while(1);\r
+ }\r
+\r
+ GH3X2X_INFO_LOG("[%s]Comunication confirm ok. \r\n", __FUNCTION__);\r
+ \r
+ \r
+ \r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*********************************************** init function*******************************************/\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_Init(void)\r
+ *\r
+ * @brief init GH3X2X_AFE chip\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_Init(void)\r
+{\r
+ /* Step 1: init communicate interface. */\r
+ #if(GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_SPI)\r
+ hal_gh3x2x_afe_spi_init();\r
+ #else\r
+ hal_gh3x2x_afe_i2c_init();\r
+ #endif\r
+\r
+ /* Step 2: init interupt pin */\r
+ #if(GH3X2X_AFE_PRO_TYPE == GH3X2X_AFE_PRO_BY_INT)\r
+ hal_gh3x2x_afe_int_init();\r
+ #endif\r
+ \r
+\r
+ /* Step 3: Reset GH3X2X_AFE chip */\r
+ #if(GH3X2X_AFE_RESET_TYPE == GH3X2X_AFE_RESET_HARDWARE)\r
+ hal_gh3x2x_afe_reset_pin_init();\r
+ #endif\r
+ GH3X2X_AFE_Reset();\r
+\r
+ /* Step 4: Check conmunication and chip id is ok or not */\r
+ GH3X2X_AFE_CommunicateConfirm();\r
+ GH3X2X_AFE_CheckChipId();\r
+ GH3X2X_AFE_CheckEfuseCrc();\r
+\r
+\r
+ /* Step 5: Init GH3X2X_AFE chip */\r
+ GH3X2X_AFE_SendRegPackage(GH3X2X_AFE_reg_list, GH3X2X_AFE_reg_list_len);\r
+\r
+ /* Step 6: agc module reset and set parm*/\r
+ GH3X2X_LedAgcReset();\r
+ GH3X2X_DemoLedAgcPramConfig();\r
+ //GH3X2X_LedAgcPramWrite();\r
+ \r
+ /* Step 7: enter low power mode */\r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+\r
+}\r
+\r
+/*********************************************** sample control handle function*******************************************/\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_StartSampling(GU8 SlotCfgEnable)\r
+ *\r
+ * @brief start sample\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] SlotCfgEnable slot enable bit bit0 control slot0, bit1 control slot1, bit2 control slot2...\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_StartSampling(GU8 SlotCfgEnable)\r
+{\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+\r
+ //agc init\r
+ GH3X2X_LedAgcInit(g_pstGh3x2xAgcInfo);\r
+ \r
+ //write slot enable\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_EN_ADDR, (GU16)SlotCfgEnable);\r
+ //start sample\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,1);\r
+ \r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_StopSampling(void)\r
+ *\r
+ * @brief stop sample\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_StopSampling(void)\r
+{\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+\r
+ //stop sample\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,0);\r
+\r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_SwitchSlot(GU8 SlotCfgEnable)\r
+ *\r
+ * @brief switch sample slot.\r
+ *\r
+ * @attention this function can only be used during sampling, after call GH3X2X_AFE_StartSampling\r
+ *\r
+ * @param[in] SlotCfgEnable slot enable bit bit0 control slot0, bit1 control slot1, bit2 control slot2...\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_SwitchSlot(GU8 SlotCfgEnable)\r
+{\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+ \r
+ //write slot enable\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_EN_ADDR, (GU16)SlotCfgEnable);\r
+ \r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+}\r
+\r
+/********************************* interrupt handle:fifo read and analysis ***************************/\r
+#define GH3X2X_AFE_READ_FIFO_BUF_LEN (800)\r
+GU32 GH3X2X_AFE_ReadFifoBuffer[(GU16)GH3X2X_AFE_READ_FIFO_BUF_LEN];\r
+\r
+/*\r
+ FIFO rawdata decode\r
+*/\r
+typedef struct\r
+{\r
+ GU32 uiAdcCode; //sampling rawdata of ADC\r
+ GU8 ubSlotNo; //slot number\r
+ GU8 ubAdcNo; //adc number\r
+ GU8 ubFlagLedAdjIsAgc_EcgRecover; //adj flag of ppg data or fast recover flag of ecg data\r
+ GU8 ubFlagLedAdjAgcUp; //adj up flag of ppg data\r
+}StFifoDataInformation;\r
+\r
+/**\r
+ * @fn GU32 EndienRev32(GU32 luiTempData)\r
+ *\r
+ * @brief reverse data endien\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] luiTempData input data\r
+ * @param[out] None\r
+ *\r
+ * @return output data\r
+ */\r
+static GU32 EndienRev32(GU32 luiTempData)\r
+{\r
+ GU8 *lpubIn;\r
+ GU8 *lpubOut;\r
+ \r
+ GU32 luiOutData;\r
+ \r
+ lpubIn = (GU8 *)(&luiTempData);\r
+ lpubOut = (GU8 *)(&luiOutData);\r
+ \r
+ for(GU8 i = 0; i < 4; i ++)\r
+ {\r
+ lpubOut[i] = lpubIn[3 - i];\r
+ }\r
+ \r
+ return luiOutData;\r
+}\r
+\r
+void GH3X2X_UpdateAgcInfo(void)\r
+{\r
+ GH3X2X_Memcpy(g_pstGh3x2xAgcInfo->uchTiaGainRecord, g_pstGh3x2xAgcInfo->uchTiaGainAfterSoftAgc, sizeof(g_pstGh3x2xAgcInfo->uchTiaGainRecord));\r
+ GH3X2X_Memcpy(g_pstGh3x2xAgcInfo->uchDrvCurrentRecord, g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc, sizeof(g_pstGh3x2xAgcInfo->uchDrvCurrentRecord));\r
+ \r
+ \r
+}\r
+\r
+void GH3X2X_RecordAgcInfo(void)\r
+{\r
+ GU16 usDrv0CurRegData = 0;\r
+ GU16 usDrv0CurRegAddr = 0; \r
+ GU16 usDrv1CurRegData = 0;\r
+ GU16 usDrv1CurRegAddr = 0;\r
+ GU16 uchTIAData = 0;\r
+\r
+ // record TIA\r
+ for (GU8 uchSlotIndex = 0; uchSlotIndex < 8; uchSlotIndex++)\r
+ {\r
+ uchTIAData = GH3X2X_AFE_READ_REG(0x0112 + (uchSlotIndex * 0x001C));\r
+ \r
+ for (GU8 nAdcCnt = 0; nAdcCnt < 4; nAdcCnt++)\r
+ {\r
+ uchTIAData = (GU8)(((uchTIAData) >> (4 * nAdcCnt)) & 0x000F);\r
+ g_pstGh3x2xAgcInfo->uchTiaGainAfterSoftAgc[uchSlotIndex*4 + nAdcCnt] = uchTIAData;\r
+ } \r
+ }\r
+ \r
+ //Record Drv \r
+ usDrv0CurRegAddr = 0x011E;\r
+ usDrv1CurRegAddr = 0x0120;\r
+ for (GU8 uchSlotIndexCnt = 0; uchSlotIndexCnt < 8; uchSlotIndexCnt++)\r
+ {\r
+ usDrv0CurRegData = (GH3X2X_AFE_READ_REG(usDrv0CurRegAddr + (uchSlotIndexCnt * 0x001C)) & 0xFF);\r
+ usDrv1CurRegData = (GH3X2X_AFE_READ_REG(usDrv1CurRegAddr + (uchSlotIndexCnt * 0x001C)) & 0xFF);\r
+ g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc[uchSlotIndexCnt] = (GU16)(usDrv0CurRegData << 0x0);\r
+ g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc[uchSlotIndexCnt] |= (GU16)(usDrv1CurRegData << 0x0);\r
+ }\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_FifoDataAnalysis(GU16 luwFifoDataCnt)\r
+ *\r
+ * @brief analysis fifo data\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] luwFifoDataCnt the number of rawdata \r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_FifoDataAnalysis(GU16 luwFifoDataCnt)\r
+{\r
+ StFifoDataInformation stTempFifoInfo = {0};\r
+ GU16 luwFifoCnt = 0;\r
+ \r
+ GU32 luiTempFifoData = 0;\r
+\r
+ GH3X2X_INFO_LOG("Received rawdata sample num = %d \r\n", (int)luwFifoDataCnt);\r
+ \r
+ for(luwFifoCnt = 0; luwFifoCnt < luwFifoDataCnt; luwFifoCnt++)\r
+ {\r
+ luiTempFifoData = EndienRev32(GH3X2X_AFE_ReadFifoBuffer[luwFifoCnt]); //big endien -> little endien\r
+ \r
+ stTempFifoInfo.uiAdcCode = ((luiTempFifoData >> 0) & 0x00FFFFFF);\r
+ stTempFifoInfo.ubSlotNo = ((luiTempFifoData >> 29) & 0x00000007);\r
+ stTempFifoInfo.ubAdcNo = ((luiTempFifoData >> 27) & 0x00000003);\r
+ stTempFifoInfo.ubFlagLedAdjIsAgc_EcgRecover = ((luiTempFifoData >> 26) & 0x00000001);\r
+ stTempFifoInfo.ubFlagLedAdjAgcUp = ((luiTempFifoData >> 25) & 0x00000001);\r
+ #if GH3X2X_ADT_FUNC_ENABLE\r
+ if(stTempFifoInfo.ubSlotNo == GH3X2X_ADT_SLOT_NUM && stTempFifoInfo.ubAdcNo == GH3X2X_ADT_ADC_NUM)\r
+ {\r
+ EMWearStatus emWearStatus;\r
+ GH3x2xAdtAlgoExe(&stTempFifoInfo.uiAdcCode,&emWearStatus);\r
+ }\r
+ #endif\r
+ GH3X2X_INFO_LOG("Received rawdata:slot:%d,adc:%d,data:%d\r\n", stTempFifoInfo.ubSlotNo, stTempFifoInfo.ubAdcNo,stTempFifoInfo.uiAdcCode);\r
+ //GH3X2X_INFO_LOG("drv = %d, g0 = %d,g1 = %d,g2 = %d,g0 = %d\r\n",(int)g_pstGh3x2xAgcInfo->uchDrvCurrentRecord[0],(int)g_pstGh3x2xAgcInfo->uchTiaGainRecord[0],(int)g_pstGh3x2xAgcInfo->uchTiaGainRecord[1],g_pstGh3x2xAgcInfo->uchTiaGainRecord[2],g_pstGh3x2xAgcInfo->uchTiaGainRecord[3]);\r
+ \r
+\r
+ \r
+ /******************************** add your fifo date process code******************************/\r
+ //you can combine frame rawdata according to stTempFifoInfo\r
+ //and then excute algorithm calculate\r
+ \r
+ \r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_ChipPro(void)\r
+ *\r
+ * @brief interrupt handle function\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_ChipPro(void)\r
+{\r
+ GU16 luwGH3X2X_AFEFifoLen = 0;\r
+ GU16 luwGotEvent = 0;\r
+\r
+\r
+#if (GH3X2X_AFE_PRO_TYPE == GH3X2X_AFE_PRO_BY_INT)\r
+ if(0 == g_uchGh3x2xAfeIntCallBackIsCalled)\r
+ {\r
+ GH3X2X_INFO_LOG("InterruptProcess:invalid call, do not process.\r\n");\r
+ return;\r
+ }\r
+ g_uchGh3x2xAfeIntCallBackIsCalled = 0; \r
+ \r
+#endif\r
+\r
+ if (GH3X2X_AFE_GetNeedWakeUpGh3x2xFlag())\r
+ {\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+ }\r
+\r
+\r
+ luwGH3X2X_AFEFifoLen = 0;\r
+\r
+ //read event\r
+ luwGotEvent = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_INT_EVENT_ADDR); \r
+ GH3X2X_INFO_LOG("Received irq = %d \r\n", (int)luwGotEvent);\r
+ //clear event\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_INT_EVENT_ADDR,luwGotEvent); //clear event\r
+\r
+ //read fifo use\r
+ luwGH3X2X_AFEFifoLen = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_FIFO_USE_ADDR);\r
+ if(luwGH3X2X_AFEFifoLen > GH3X2X_AFE_READ_FIFO_BUF_LEN)\r
+ {\r
+ luwGH3X2X_AFEFifoLen = GH3X2X_AFE_READ_FIFO_BUF_LEN;\r
+ }\r
+\r
+ // read fifo data\r
+ if(0 != luwGH3X2X_AFEFifoLen)\r
+ {\r
+ GH3X2X_AFE_READ_FIFO((GU8 *)GH3X2X_AFE_ReadFifoBuffer,luwGH3X2X_AFEFifoLen * 4);\r
+ } \r
+ \r
+ \r
+ //ECG_LEAD OFF DET & resample\r
+ #if GH3X2X_ECG_FUNC_ENABLE\r
+\r
+ GU16 luwGH3X2X_AFEFifoByteLen = luwGH3X2X_AFEFifoLen * 4;\r
+ luwGotEvent &= (~GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_OFF));\r
+ \r
+ GU8 lubRet = GH3X2X_LeadOffDetect((GU8 *)GH3X2X_AFE_ReadFifoBuffer, &luwGH3X2X_AFEFifoByteLen, 0);\r
+ if(lubRet != 0)\r
+ {\r
+ luwGotEvent |= (GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_OFF));\r
+ }\r
+ \r
+ GH3X2X_INFO_LOG("before Rs luwGH3X2X_AFEFifoLen = %d\r\n",luwGH3X2X_AFEFifoLen);\r
+ GH3X2X_AFE_EcgRsHandle((GU8 *)GH3X2X_AFE_ReadFifoBuffer, &luwGH3X2X_AFEFifoByteLen,0,GH3X2X_ECG_DOWN_FS);\r
+ luwGH3X2X_AFEFifoLen = luwGH3X2X_AFEFifoByteLen/4;\r
+ GH3X2X_INFO_LOG("after Rs luwGH3X2X_AFEFifoLen = %d\r\n",luwGH3X2X_AFEFifoLen);\r
+ #endif\r
+ \r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_WEAR_ON)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received wear on event\r\n");\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_WEAR_OFF)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received wear off event\r\n");\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_ON)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received lead on event\r\n");\r
+ GH3X2X_AFE_Leadon_hook();\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_OFF)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received lead off event\r\n");\r
+ GH3X2X_AFE_Leadoff_hook();\r
+\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LED_TUNE_FAIL)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received tune fail event\r\n");\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LED_TUNE_DONE)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received tune done event\r\n");\r
+ }\r
+\r
+\r
+ //you can add some code to adjust ppg sample parameter, such as led drv current GU16 usTempDrvCurrent;\r
+ \r
+ //GH3x2xSetPpgCtrlReg(GH3X2X_AFE_PPG_CTRL_REG_AGC_EN,1,0);\r
+ //GH3x2xSetPpgCtrlReg(GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV0,1,60);\r
+ //GH3X2X_INFO_LOG("change slot0 drv0 current.\r\n");\r
+ //GH3X2X_INFO_LOG("Get slot0 drv0 current = %d.\r\n",(int)GH3x2xGetPpgCtrlReg(GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV0,0));\r
+\r
+ GH3X2X_LedAgcProcess((GU8 *)GH3X2X_AFE_ReadFifoBuffer, luwGH3X2X_AFEFifoLen * 4, g_pstGh3x2xAgcInfo);\r
+ \r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+ \r
+\r
+ if(0 != luwGH3X2X_AFEFifoLen)\r
+ {\r
+ GH3X2X_AFE_FifoDataAnalysis(luwGH3X2X_AFEFifoLen);\r
+ } \r
+}\r
+\r
+const GU16 g_usGH3x2xTiaGainR[] = \r
+{\r
+ 10,\r
+ 25,\r
+ 50,\r
+ 75,\r
+ 100,\r
+ 250,\r
+ 500,\r
+ 750,\r
+ 1000,\r
+ 1250,\r
+ 1500,\r
+ 1750,\r
+ 2000,\r
+};\r
+\r
+const GU16 g_usGH3x2xSlotRegBase[8] = \r
+{\r
+ 0x0100,\r
+ 0x011C,\r
+ 0x0138,\r
+ 0x0154,\r
+ 0x0170,\r
+ 0x018C,\r
+ 0x01A8,\r
+ 0x01C4,\r
+};\r
+\r
+\r
+const STGh3x2xAgcReg g_pstGH3x2xAgcReg[] = \r
+{\r
+ {0x10, 9, 8}, //0: agc en\r
+ {0x22, 7, 0}, //1: led current up limit\r
+ {0x22, 15, 8}, //2: led current down limit\r
+ {0x1E, 7, 0}, //3: led current drv0\r
+ {0x20, 7, 0}, //4: led current drv1\r
+ {0x12, 3, 0}, //5: rx0 tia gain\r
+ {0x12, 7, 4}, //6: rx1 tia gain\r
+ {0x12, 11, 8}, //7: rx2 tia gain\r
+ {0x12, 15, 12}, //8: rx3 tia gain\r
+ {0x10, 7,6}, //9: agc src\r
+ {0x1A, 1,0}, //10: rx0 bg cancel\r
+ {0x1A, 3,2}, //11: rx1 bg cancel \r
+ {0x1A, 5,4}, //12: rx2 bg cancel\r
+ {0x1A, 7,6}, //13: rx2 bg cancel\r
+ {0x0A, 15,8}, //14: sr mulipliper\r
+ {0x0A, 5,1}, //15: ecg en& rx0~rx1 en\r
+};\r
+\r
+void GH3x2x_AFESetAgcReg(GU8 uchAgcReg, GU8 uchSlot, GU16 usValue)\r
+{\r
+ GH3X2X_AFE_WriteRegBitField(g_usGH3x2xSlotRegBase[uchSlot] + g_pstGH3x2xAgcReg[uchAgcReg].uchAddrOffset, g_pstGH3x2xAgcReg[uchAgcReg].uchLsb, g_pstGH3x2xAgcReg[uchAgcReg].uchMsb, usValue);\r
+}\r
+\r
+GU16 GH3x2x_AFEGetAgcReg(GU8 uchAgcReg, GU8 uchSlot)\r
+{\r
+ return GH3X2X_AFE_ReadRegBitField(g_usGH3x2xSlotRegBase[uchSlot] + g_pstGH3x2xAgcReg[uchAgcReg].uchAddrOffset, g_pstGH3x2xAgcReg[uchAgcReg].uchLsb, g_pstGH3x2xAgcReg[uchAgcReg].uchMsb);\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_GetEfuseCode(GS8* pchLedDrvEcode,GS8* pchTiaEcode,GS8* pchEcgEcode)\r
+ *\r
+ * @brief: Get Efuse Code\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] \r
+ * @param[out] pchLedDrvEcode\r
+ * pchTiaEcode\r
+ * pchEcgEcode\r
+ * @return : none\r
+ */\r
+void GH3X2X_AFE_GetEfuseCode(GS8* pchLedDrvEcode,GS8* pchTiaEcode,GS8* pchEcgEcode)\r
+{\r
+ GU16 usRegVal;\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,0x0020);\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,0x0030);\r
+\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_1_REG_ADDR);\r
+ *pchLedDrvEcode = (GS8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ *pchTiaEcode = (GS8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ *pchEcgEcode = (GS8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_2_REG_ADDR));\r
+}\r
+\r
+\r
+/**\r
+ * @fn GU16 GH3X2X_AFE_SetLedDrvCurrent(GU8 uchCurrent_mA,GU8 uchDrvNum, GS8 chECODE)\r
+ *\r
+ * @brief: led drv calibration\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GU8 uchCurrent_mA:led drv current, unit: mA\r
+ GU8 uchDrvNum :led Drv num,0 or 1\r
+ GS8 chECODE :Led Drv Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : Drv code\r
+ */\r
+GU16 GH3X2X_AFE_SetLedDrvCurrent(GU8 uchCurrent_mA, GU8 uchDrvNum, GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ GF32 fY;\r
+ GU8 uchN;\r
+ GU16 usDrvCode;\r
+ GU16 usDrvScale;\r
+ \r
+ if(uchDrvNum == 0)\r
+ {\r
+ fY = 0.1;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB);\r
+ }\r
+ else\r
+ {\r
+ fY = 0.01;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB);\r
+ \r
+ }\r
+ uchN = 1 << (3 - usDrvScale); \r
+ \r
+ fEr = (GF32)((GF32)chECODE/256) + 1.0f;\r
+ usDrvCode = (GU16)(0.5f+((GF32)fEr*255*(GF32)uchN)/(0.225f/((GF32)uchCurrent_mA/1000) - fY));\r
+ \r
+ return usDrvCode;\r
+}\r
+\r
+\r
+/**\r
+ * @fn GF32 GH3X2X_AFE_GetLedDrvCurrent(GU16 usDrvCode, GU8 uchDrvNum, GS8 chECODE)\r
+ *\r
+ * @brief: get led drv calibration current\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GU16 usDrvCode :led drv code\r
+ GU8 uchDrvNum :led Drv num,0 or 1\r
+ GS8 chECODE :Led Drv Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : calibration current\r
+ */\r
+\r
+GF32 GH3X2X_AFE_GetLedDrvCurrent(GU16 usDrvCode, GU8 uchDrvNum, GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ GF32 fY;\r
+ GU8 uchN;\r
+ GF32 fDrvCurrent;\r
+ GU16 usDrvScale;\r
+ \r
+ if(uchDrvNum == 0)\r
+ {\r
+ fY = 0.1;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB);\r
+ }\r
+ else\r
+ {\r
+ fY = 0.01;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB);\r
+ }\r
+ uchN = 1 << (3 - usDrvScale); \r
+ fEr = (GF32)((GF32)chECODE/256) + 1;\r
+ fDrvCurrent = 0.225f/(fEr*255*(GF32)uchN/(GF32)usDrvCode + fY);\r
+ return fDrvCurrent*1000;\r
+\r
+}\r
+\r
+/**\r
+ * @fn GF32 GH3X2X_AFE_GetTiaCalCode(GS8 chECODE)\r
+ \r
+ *\r
+ * @brief: Get Tia Calibration Code\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GS8 chECODE :Tia Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : calibration Code\r
+ */\r
+GF32 GH3X2X_AFE_GetTiaCalCode(GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ fEr = (GF32)((GF32)chECODE/512) + 1;\r
+ return fEr;\r
+}\r
+\r
+/**\r
+ * @fn GF32 GH3X2X_AFE_GetEcgCalCode(GS8 chECODE)\r
+ \r
+ *\r
+ * @brief: Get ECG Calibration Code\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GS8 chECODE :ECG Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : calibration Code\r
+ */\r
+GF32 GH3X2X_AFE_GetEcgCalCode(GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ fEr = (GF32)((GF32)chECODE/1024) + 1;\r
+ return fEr;\r
+}\r
+\r
+\r
+/**\r
+ * @fn GCHAR *GH3X2X_GetAfeLibVersion(void)\r
+ *\r
+ * @brief Get afe driver version\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return library version string\r
+ */\r
+GCHAR *GH3X2X_GetAfeLibVersion(void)\r
+{\r
+ return (GCHAR *)GH3X2X_VERSION_STRING;\r
+}\r
+\r
+\r
+GU8 GH3X2X_AFE_GetChipId(void)\r
+{\r
+ return (GU8)GH3X2X_AFE_ReadRegBitField(GH3X2X_WHO_AM_I_REG_ADDR,GH3X2X_WHO_AM_I_LSB,GH3X2X_WHO_AM_I_MSB);\r
+}\r
+\r
+GS8 GH3X2X_AFE_CheckChipId(void)\r
+{\r
+ GS8 chRet = GH3X2X_AFE_RET_OK;\r
+ GS8 chipd_id = GH3X2X_AFE_GetChipId();\r
+ if(GH3X2X_CHIP_ID != chipd_id)\r
+ {\r
+ GH3X2X_INFO_LOG("wrong chip id!!\r\n");\r
+ chRet = GH3X2X_AFE_RET_GENERIC_ERROR;\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("check chip id success!! 0x%x\r\n",chipd_id);\r
+ }\r
+ return chRet;\r
+}\r
+\r
+/**\r
+ * @fn void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+ *\r
+ * @brief memcpy() Re-implementation\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] pSrc pointer to source buffer\r
+ * @param[in] unByteSize source buffer byte size\r
+ * @param[out] pDest pointer to destination buffer\r
+ *\r
+ * @return pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+{\r
+ GU8 *puchSrc = (GU8 *)pSrc;\r
+ GU8 *puchDest = (GU8 *)pDest;\r
+ GU32 unAlign = ((GU32)puchDest | (GU32)puchSrc) << 30;\r
+\r
+ if ((pDest == GH3X2X_PTR_NULL) || (pSrc == GH3X2X_PTR_NULL) || (0 == unByteSize))\r
+ {\r
+ return GH3X2X_PTR_NULL;\r
+ }\r
+ if (unAlign == 0) // if align 4\r
+ {\r
+ while (unByteSize >= 4)\r
+ {\r
+ *(GU32 *)puchDest = *(GU32 *)puchSrc;\r
+ puchSrc += 4;\r
+ puchDest += 4;\r
+ unByteSize -= 4;\r
+ }\r
+ }\r
+ while (unByteSize) // bytes\r
+ {\r
+ *(GU8 *)puchDest = *(GU8 *)puchSrc;\r
+ puchSrc++;\r
+ puchDest++;\r
+ unByteSize--;\r
+ }\r
+ return pDest;\r
+}\r
+\r
+/**\r
+ * @fn void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+ *\r
+ * @brief memset() Re-implementation\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] chVal char val for set\r
+ * @param[in] unByteSize source buffer len\r
+ * @param[out] pDest pointer to destination buffer\r
+ *\r
+ * @return pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+{\r
+ GU8 *puchDest = (GU8 *)pDest;\r
+ GU32 unAlign = ((GU32)puchDest) << 30;\r
+ GU32 unWordVal = GH3X2X_AFE_MAKEUP_DWORD(chVal, chVal, chVal, chVal);\r
+\r
+ if (pDest == GH3X2X_PTR_NULL)\r
+ {\r
+ return GH3X2X_PTR_NULL;\r
+ }\r
+ if (unAlign == 0) // if align 4\r
+ {\r
+ while (unByteSize >= 4)\r
+ {\r
+ *(GU32 *)puchDest = unWordVal;\r
+ puchDest += 4;\r
+ unByteSize -= 4;\r
+ }\r
+ }\r
+ while (unByteSize) // bytes\r
+ {\r
+ *(GU8 *)puchDest = (GU8)chVal;\r
+ puchDest++;\r
+ unByteSize--;\r
+ }\r
+ return pDest;\r
+}\r
+\r
+GU8 _crc8(GU8 *ptr,GS32 len)\r
+{\r
+ GS32 i;\r
+ GU8 crc = 0x00;\r
+ while(len--)\r
+ {\r
+ crc ^= *ptr++;\r
+ for(i=8;i>0;--i)\r
+ {\r
+ if(crc&0x80)\r
+ {\r
+ crc = (crc<<1)^0x31;\r
+ }\r
+ else\r
+ {\r
+ crc = (crc<<1);\r
+ }\r
+ crc = crc & 0xff;\r
+ }\r
+ }\r
+ return (GU8)(crc);\r
+}\r
+\r
+void GH3X2X_AFE_LoadEfuse(GU8* puchEfuseBuffer,GU16 EfuseByteLen)\r
+{\r
+ if(EfuseByteLen < 24)\r
+ {\r
+ GH3X2X_INFO_LOG("EfuseByteLen is too short!!\r\n");\r
+ return;\r
+ }\r
+ \r
+ GU16 usRegVal;\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_MODE_LSB,GH3X2X_EFUSE_MODE_MSB,0);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CHOOSE_LSB,GH3X2X_EFUSE_CHOOSE_MSB,0);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CLK_EN_LSB,GH3X2X_EFUSE_CLK_EN_MSB,1);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_START_LSB,GH3X2X_EFUSE_START_MSB,1);\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ for(GU8 i = 0; i < 4; i++)\r
+ {\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR + 2 * i);\r
+ puchEfuseBuffer[2*i] = (GU8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ puchEfuseBuffer[2*i + 1] = (GU8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ }\r
+\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CHOOSE_LSB,GH3X2X_EFUSE_CHOOSE_MSB,1);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_START_LSB,GH3X2X_EFUSE_START_MSB,1);\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ for(GU8 i = 0; i < 4; i++)\r
+ {\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR + 2 * i);\r
+ puchEfuseBuffer[8 + 2*i] = (GU8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ puchEfuseBuffer[8 + 2*i + 1] = (GU8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ }\r
+\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CHOOSE_LSB,GH3X2X_EFUSE_CHOOSE_MSB,2);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_START_LSB,GH3X2X_EFUSE_START_MSB,1);\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ for(GU8 i = 0; i < 4; i++)\r
+ {\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR + 2 * i);\r
+ puchEfuseBuffer[16 + 2*i] = (GU8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ puchEfuseBuffer[16 + 2*i + 1] = (GU8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ }\r
+\r
+ \r
+}\r
+\r
+GS8 GH3X2X_AFE_CheckEfuseCrc(void)\r
+{\r
+ GS8 chRet = GH3X2X_AFE_RET_OK;\r
+ GU8 uchEfuseBuffArr[24];\r
+ GH3X2X_AFE_LoadEfuse(uchEfuseBuffArr,24);\r
+ GU8 uchCrcArr[3];\r
+ uchCrcArr[0] = _crc8(uchEfuseBuffArr,7);\r
+ uchCrcArr[1] = _crc8((uchEfuseBuffArr + 8),3);\r
+ uchCrcArr[2] = _crc8((uchEfuseBuffArr + 12),10);\r
+ if(uchCrcArr[0] != uchEfuseBuffArr[7] || uchCrcArr[1] != uchEfuseBuffArr[11] ||uchCrcArr[2] != uchEfuseBuffArr[22])\r
+ {\r
+ GH3X2X_INFO_LOG("Efuse crc error!!\r\n");\r
+ chRet = GH3X2X_AFE_RET_GENERIC_ERROR;\r
+ }\r
+ return chRet;\r
+}\r
+\r
+ \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#include "gh3x2x_afe_ecg.h"\r
+#include "gh3x2x_afe_demo.h"\r
+\r
+#define RESAMPLE_800HZ_TO_500HZ 0\r
+#define RESAMPLE_800HZ_TO_250HZ 0\r
+#define RESAMPLE_320HZ_TO_250HZ 1 \r
+#define RESAMPLE_256HZ_TO_250HZ 0 \r
+\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+#define RESAMPLE_400HZ_TO_250HZ 1 \r
+#else\r
+#define RESAMPLE_400HZ_TO_250HZ 0 \r
+#endif\r
+\r
+#define GH3X2X_PPG_START_SLOT 1\r
+#define GH3X2X_ECG_START_SLOT 0\r
+\r
+#define GH3X2X_AFE_GET_ECG_CHANNEL_MAP(slotNum) (((slotNum << 5) | (3 <<3)) &0xF8)\r
+#define GH3X2X_AFE_GET_PPG_CHANNEL_MAP(slotNum) (((slotNum << 5) | (0 <<3)) &0xF8)\r
+\r
+STGh3x2xSoftLeadOffDetInfo g_pstGh3x2xSoftLeadOffDetInfoEntity[1];\r
+STGh3x2xRsInfo g_pstGh3x2xEcgRsInfoEntity[1];\r
+const GU8 g_uchGh3x2xEcgChnlNumLimit = 1;\r
+STGh3x2xSoftLeadOffDetInfo * const g_pstGh3x2xSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfoEntity;\r
+STGh3x2xRsInfo * const g_pstGh3x2xEcgRsInfo = g_pstGh3x2xEcgRsInfoEntity;\r
+\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+#define GH3X2X_PPG_DOWNSAMP_CHNL_NUM 1\r
+const GU32 g_uchPPGDownSampleChnlNumLimit = GH3X2X_PPG_DOWNSAMP_CHNL_NUM;\r
+STGh3x2xRsInfo g_pstGh3x2xPPGRsInfoEntity[GH3X2X_PPG_DOWNSAMP_CHNL_NUM];\r
+STGh3x2xRsInfo * const g_pstGh3x2xPPGRsInfo = g_pstGh3x2xPPGRsInfoEntity;\r
+#endif\r
+\r
+//Ecg sample rate from hardware\r
+static GU16 g_usEcgInputFs = GH3X2X_ECG_FS; // ecg sample rate 800/320/256\r
+static GU16 g_usEcgOutputFs = GH3X2X_ECG_DOWN_FS; // ecg down sample rate 500/250\r
+\r
+/// down sample lead module(ECG PPG)\r
+static GU8 g_uchDownSampleModule = DOWNSAMPLE_ECG;\r
+\r
+#define ADCREF 1800 \r
+#define ADC_OFFSET (1<<23)\r
+#define PI 3.14159265\r
+#define ABS(x) ( (x)>0?(x):(-(x)) ) \r
+#define AMP_NUM 5 \r
+#define IQ_NUM 48 \r
+\r
+const int winCoef[IQ_NUM / 2] = { 0, 9580474, 38150933, 85201535, 149892663, 231069901, 327284639, 436819923, 557721094, 687830666, 824826833, 966264894, 1109620882, 1252336609, 1391865307, 1525717084, 1651503351, 1766979451, 1870084709, 1958979209, 2032076627, 2088072537, 2125967693, 2145085852};\r
+#define winAmpCoef 4082 \r
+//unsigned char gscFlagFrPrev = 0; \r
+GU32 g_nLeadOffDetIqAmpThr = 1500;//unit: uv\r
+long long g_lLeadOffDetIqAmp;\r
+long long g_lLeadOffDetIqAmpThrRaw;\r
+long long g_lLeadOffDetIqAmpFrThrRaw;\r
+\r
+GU32 g_nLeadOffDetIqAmpDiffThr = 1000;//unit: uv\r
+long long g_lLeadOffDetIqAmpDiff;\r
+long long g_lLeadOffDetIqAmpDiffThrRaw;\r
+long long g_lLeadOffDetIqAmpDiffFrThrRaw;\r
+\r
+int COND_VAL_VALID_TIME = 1; \r
+GU32 g_nLeadOffDetValThr = 80;//unit: mv\r
+int g_LeadOffDetValThrRaw;\r
+\r
+#define SHIFTBITS 30\r
+\r
+#if RESAMPLE_800HZ_TO_500HZ\r
+ const int rsFirCoef_800_500hz[] = { 58200, 102435, 156130, 215460, 274735, 326585, 362380, 372790, 348645, 281870, 166550, 0, -216285, -475850, -766815, -1071825, -1368460, -1630170, -1827760, -1931325, -1912605,\r
+ -1747635, -1419445, -920670, -255820, 557070, 1485515, 2482735, 3488860, 4433375, 5238695, 5824850, 6114965, 6041350, 5551740, 4615280, 3227790, 1415785, -761100, -3209770, -5805610, -8396875, -10811545, -12866385,\r
+ -14377925, -15174745, -15110485, -14076620, -12014295, -8924190, -4873605, 0, 5489625, 11323885, 17176845, 22682405, 27452740, 31100030, 33260510, 33619540, 31936265, 28066360, 21981325, 13782945, 3711580, -7852615,\r
+ -20396185, -33286830, -45795550, -57125820, -66448630, -72941905, -75832375, -74437800, -68207360, -56757870, -39903755, -17678885, 9651270, 41588185, 77410100, 116192965, 156841955, 198132190, 238757000, 277381455, 312698655, 343486005, 368658785, 387318230, 398791740, 402663190 };\r
+#endif\r
+#if RESAMPLE_800HZ_TO_250HZ \r
+ const int rsFirCoef_800_250hz[] = { -74905, -95385, -116975, -138740, -159540, -178080, -192900, -202440, -205060, -199120, -183040, -155365, -114830, -60455, 8370, 91845, 189655, 300920, 424150, 557225, 697345, 841065, 984315, 1122440, 1250290, 1362325,\r
+ 1452720, 1515555, 1544935, 1535220, 1481220, 1378385, 1223050, 1012615, 745780, 422705, 45175, -383265, -857210, -1369370, -1910565, -2469770, -3034240, -3589685, -4120510, -4610090, -5041145, -5396125, -5657660, -5809045, -5834740, -5720895, -5455890,\r
+ -5030825, -4440010, -3681420, -2757070, -1673325, -441140, 923805, 2401100, 3965690, 5588100, 7234765, 8868540, 10449275, 11934545, 13280495, 14442770, 15377525, 16042520, 16398240, 16409055, 16044325, 15279560, 14097430, 12488725, 10453225, 8000385,\r
+ 5149865, 1931900, -1612575, -5431990, -9464450, -13638290, -17872830, -22079425, -26162660, -30021820, -33552510, -36648435, -39203325, -41112955, -42277200, -42602135, -42002095, -40401670, -37737600, -33960495, -29036370, -22947970, -15695790,\r
+ -7298825, 2204995, 12758710, 24286615, 36694830, 49872305, 63692080, 78012930, 92681285, 107533410, 122397830, 137097950, 151454790, 165289835, 178427925, 190700125, 201946505, 212018845, 220783110, 228121755, 233935695, 238146055, 240695490, 241549195 };\r
+#endif\r
+\r
+#if RESAMPLE_400HZ_TO_250HZ \r
+//const int rsFirCoef_250hz1[] = { 0,-24495,-56710,-95045,-136775,-178125,-214440,-240490,-250920,-240760,-205965,-144050,-54555,60475,196250,345190,497105,639650,759070,841160,872410,841285,739500,563245,314150,0,-365010,-760510,-1160685,-1535620,-1853070,-2080745,-2188790,-2152475,-1954770,-1588670,-1058960,-383360,407260,1269625,2149850,2986210,3712890,4264415,4580525,4611280,4321835,3696680,2742865,1491895,0,-1653335,-3368750,-5032125,-6521320,-7714135,-8497040,-8774130,-8475685,-7565610,-6047220,-3966715,-1413955,1479820,4547350,7593800,10407850,12774895,14491705,15381495,15308470,14190830,12011055,8822720,4752940,0,-5174080,-10455925,-15497715,-19937805,-23423930,-25637735,-26318950,-25287690,-22463185,-17877445,-11682610,-4150955,4332910,13287805,22159230,30349170,37251070,42288110,44952645,44844420,41705155,35447110,26173540,14189250,0,-15699840,-32051440,-48066690,-62673020,-74765800,-83265770,-87178475,-85652480,-78033065,-63908265,-43144325,-15908305,17323970,55775495,98391360,143876925,190749335,237400000,282164985,323399855,359555130,389248460,411329760,424935830,429531605};\r
+const int rsFirCoef_250hz2[] = {-20165,29190,117750,248970,420650,623445,839855,1044105,1203060,1278285,1229350,1018175,614220,0,-823490,-1832200,-2975865,-4177020,-5332555,-6318335,-6996880,-7227970,-6881615,-5852620,-4075600,-1539030,1703020,5523035,9717440,14010255,18063685,21495860,23905235,24900525,24134595,21339975,16363405,9196555,0,-10882185,-22919440,-35404830,-47478995,-58167535,-66430495,-71221570,-71553685,-66566985,-55594615,-38221750,-14333265,15853795,51776230,92531020,136902815,183411755,230379530,276010140,318480795,356037520,387089565,410296710,424643805,429497860,};\r
+#endif\r
+ \r
+#if RESAMPLE_320HZ_TO_250HZ \r
+ const int rsFirCoef_320_250hz[] = {79095,936340,341760,-2712470,-2547785,4817105,8099190,-5170865,-17933790,0,30974265,15517780,-42765395,-45670380,44706790,92106715,-24021395,-152053275,-36768905,217784250,166596045,-277901355,-451953470,320248390,1667310365,2147483647,};\r
+#endif\r
+#if RESAMPLE_256HZ_TO_250HZ \r
+ const int rsFirCoef_256_250hz[]={194000,77770,-331070,-632290,-254280,769680,1439880,622640,-1454740,-2779600,-1303600,2436730,4847325,2461115,-3753755,-7872475,-4310105,5424840,12120690,7126740,-7444180,-17902495,-11265025,9777230,25594875,17187555,-12359260,-35689230,-25526795,15096890,48893725,37213545,-17872685,-66356185,-53763065,20552645,90184745,77974330,-22995885,-124828195,-115908245,25065740,181561700,183974820,-26641130,-299102515,-347934030,27626950,749679370,1463910805,1761638120,};\r
+#endif\r
+\r
+GS32* rsFirCoef;\r
+GS32* rsFirCoef1;\r
+ \r
+STGh3x2xDownSampleCalParamInfo pstECGDownSampCalParamInfo[1];\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+STGh3x2xDownSampleCalParamInfo pstPPGDownSampCalParamInfo[1];\r
+#endif\r
+\r
+void GH3X2X_DownSampleMarcoIni(GU16 usEcgSampleRate)\r
+{\r
+ switch (g_usEcgInputFs)\r
+ {\r
+ case 800:\r
+ if( usEcgSampleRate == 500)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_800HZ_TO_500HZ;\r
+ }\r
+ else\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_800HZ_TO_250HZ;\r
+ }\r
+ break;\r
+ case 320:\r
+ if( usEcgSampleRate == 250)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_320HZ_TO_250HZ;\r
+ }\r
+ break;\r
+ case 256:\r
+ if( usEcgSampleRate == 250)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_256HZ_TO_250HZ;\r
+ }\r
+ break;\r
+ default: // do nothing\r
+ break;\r
+ }\r
+\r
+ // ppg downsample ini\r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ pstPPGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_400HZ_TO_250HZ;\r
+ #endif\r
+}\r
+\r
+void RsFirResetSingle(GU8 uchChipIndex, GU8 uchMode)\r
+{\r
+ STGh3x2xRsInfo * pstRsInfo;\r
+ GU8 uchChnNum = 0;\r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ if(DOWNSAMPLE_PPG == uchMode)\r
+ {\r
+ pstRsInfo = g_pstGh3x2xPPGRsInfo;\r
+ uchChnNum = g_uchPPGDownSampleChnlNumLimit;\r
+ }\r
+ #endif\r
+\r
+ if(DOWNSAMPLE_ECG == uchMode)\r
+ {\r
+ pstRsInfo = g_pstGh3x2xEcgRsInfo;\r
+ uchChnNum = uchChipIndex+1;\r
+ }\r
+\r
+ for( GU8 i=0; i<uchChnNum;i++)\r
+ {\r
+ pstRsInfo[i].snBufHead = -1;\r
+ pstRsInfo[i].snRsFirState = 0;\r
+ pstRsInfo[i].nRsIcounter = 0;\r
+ pstRsInfo[i].nRrsDcounter = 0;\r
+ pstRsInfo[i].uchFlagFrPrev = 1;\r
+ pstRsInfo[i].nRsLastRaw = 0;\r
+ pstRsInfo[i].fDownStep = 0;\r
+ pstRsInfo[i].uchLinearInterState = 0;\r
+ pstRsInfo[i].uchLinearDataUpdate = 0;\r
+ }\r
+}\r
+\r
+void RsFirReset(GU8 uchMode)\r
+{\r
+ RsFirResetSingle(0,uchMode);\r
+}\r
+\r
+void GH3X2X_ECGResampleConfig(GU16 usEcgSampleRate)\r
+{\r
+ RsFirReset(DOWNSAMPLE_ECG);\r
+ GH3X2X_DownSampleMarcoIni(usEcgSampleRate);\r
+ if(usEcgSampleRate == 500)\r
+ {\r
+ #if RESAMPLE_800HZ_TO_500HZ\r
+ if(DOWNSAMPLE_800HZ_TO_500HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_800_500hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 182;\r
+ pstECGDownSampCalParamInfo->uchRsI = 5;\r
+ pstECGDownSampCalParamInfo->uchRsD = 8;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ }\r
+ #endif\r
+ }\r
+ else if(usEcgSampleRate == 250)\r
+ {\r
+ #if RESAMPLE_800HZ_TO_250HZ\r
+ if(DOWNSAMPLE_800HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_800_250hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 250;\r
+ pstECGDownSampCalParamInfo->uchRsI = 5;\r
+ pstECGDownSampCalParamInfo->uchRsD = 16;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_320HZ_TO_250HZ\r
+ if(DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_320_250hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 50;\r
+ pstECGDownSampCalParamInfo->uchRsI = 1;\r
+ pstECGDownSampCalParamInfo->uchRsD = 1;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ pstECGDownSampCalParamInfo->ufStep = 128;\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_256HZ_TO_250HZ\r
+ if(DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_256_250hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 100;\r
+ pstECGDownSampCalParamInfo->uchRsI = 1;\r
+ pstECGDownSampCalParamInfo->uchRsD = 1;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ pstECGDownSampCalParamInfo->ufStep = 1024;\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 0;\r
+ return;\r
+ }\r
+\r
+ if(pstECGDownSampCalParamInfo->uchRsFirOrder % 2)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchRsFirCoefNum = ((pstECGDownSampCalParamInfo->uchRsFirOrder+1)/2) ;\r
+ }\r
+ else\r
+ {\r
+ pstECGDownSampCalParamInfo->uchRsFirCoefNum = ((pstECGDownSampCalParamInfo->uchRsFirOrder+2)/2);\r
+ }\r
+ pstECGDownSampCalParamInfo->uchRsBufSize = (pstECGDownSampCalParamInfo->uchRsFirOrder / pstECGDownSampCalParamInfo->uchRsI + 1);\r
+}\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+void GH3X2X_PPGResampleConfig(GU16 usPPGSampleRate)\r
+{\r
+ RsFirReset(DOWNSAMPLE_PPG);\r
+ GH3X2X_DownSampleMarcoIni(usPPGSampleRate);\r
+ if(usPPGSampleRate == 250)\r
+ {\r
+ #if RESAMPLE_400HZ_TO_250HZ\r
+ pstPPGDownSampCalParamInfo->rsFirCoef = (GS32*)rsFirCoef_250hz2;\r
+ pstPPGDownSampCalParamInfo->uchRsFirOrder = 126;\r
+ pstPPGDownSampCalParamInfo->uchRsI = 5;\r
+ pstPPGDownSampCalParamInfo->uchRsD = 8;\r
+ pstPPGDownSampCalParamInfo->uchRsEnable = 1;\r
+ #else\r
+ pstPPGDownSampCalParamInfo->uchRsEnable = 0;\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ pstPPGDownSampCalParamInfo->uchRsEnable = 0;\r
+ return;\r
+ }\r
+\r
+ if(pstPPGDownSampCalParamInfo->uchRsFirOrder % 2)\r
+ {\r
+ pstPPGDownSampCalParamInfo->uchRsFirCoefNum = ((pstPPGDownSampCalParamInfo->uchRsFirOrder+1)/2) ;\r
+ }\r
+ else\r
+ {\r
+ pstPPGDownSampCalParamInfo->uchRsFirCoefNum = ((pstPPGDownSampCalParamInfo->uchRsFirOrder+2)/2);\r
+ }\r
+ pstPPGDownSampCalParamInfo->uchRsBufSize = (pstPPGDownSampCalParamInfo->uchRsFirOrder / pstPPGDownSampCalParamInfo->uchRsI + 1);\r
+}\r
+#else\r
+void GH3X2X_PPGResampleConfig(GU16 usPPGSampleRate)\r
+{\r
+ return;\r
+}\r
+#endif\r
+\r
+void GH3X2X_LeadOffDetectResetSingleChip(GU8 uchChipIndex)\r
+{\r
+ int i;\r
+ STGh3x2xSoftLeadOffDetInfo * pstSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfo + uchChipIndex;\r
+ pstSoftLeadOffDetInfo -> snCounter = 0;\r
+ pstSoftLeadOffDetInfo -> sniqCounter = 0;\r
+ pstSoftLeadOffDetInfo -> snniVal = 0;\r
+ pstSoftLeadOffDetInfo -> snnqVal = 0;\r
+ pstSoftLeadOffDetInfo -> uchFastRecoryHistory = 0;\r
+ for (i = 0; i < AMP_NUM; i++)\r
+ pstSoftLeadOffDetInfo -> snniqAmp[i] = 0;\r
+}\r
+\r
+void GH3X2X_LeadOffDetectReset(void)\r
+{\r
+ GH3X2X_LeadOffDetectResetSingleChip(0);\r
+}\r
+\r
+void GH3X2X_ConfigLeadOffThr(GU32 uIQAmpThr, GU32 uIQAmpDiffThr,GU32 uValThr)\r
+{\r
+ g_nLeadOffDetIqAmpThr = uIQAmpThr;\r
+ g_lLeadOffDetIqAmp = ((long long)g_nLeadOffDetIqAmpThr * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef);\r
+ g_lLeadOffDetIqAmpThrRaw = (g_lLeadOffDetIqAmp*g_lLeadOffDetIqAmp);\r
+ g_lLeadOffDetIqAmpFrThrRaw = (g_lLeadOffDetIqAmp*g_lLeadOffDetIqAmp / 20 / 20); \r
+\r
+ g_nLeadOffDetIqAmpDiffThr = uIQAmpDiffThr;\r
+ g_lLeadOffDetIqAmpDiff = ((long long)g_nLeadOffDetIqAmpDiffThr * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef);\r
+ g_lLeadOffDetIqAmpDiffThrRaw = (g_lLeadOffDetIqAmpDiff*g_lLeadOffDetIqAmpDiff);\r
+ g_lLeadOffDetIqAmpDiffFrThrRaw = (g_lLeadOffDetIqAmpDiff*g_lLeadOffDetIqAmpDiff / 20 / 20); \r
+\r
+ g_nLeadOffDetValThr = uValThr;\r
+ g_LeadOffDetValThrRaw = (g_nLeadOffDetValThr * (20 * ADC_OFFSET / ADCREF)); \r
+}\r
+\r
+GS32 GH3X2X_LeadOffDetectInit(void)\r
+{\r
+ GH3X2X_ECGResampleConfig(g_usEcgOutputFs);\r
+ \r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ GH3X2X_PPGResampleConfig(GH3X2X_PPG_DOWN_FS); \r
+ #endif\r
+ \r
+ GH3X2X_ConfigLeadOffThr(g_nLeadOffDetIqAmpThr, g_nLeadOffDetIqAmpDiffThr, g_nLeadOffDetValThr);\r
+ GH3X2X_LeadOffDetectReset();\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * @fn GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16 usFifoBufferLen)\r
+ *\r
+ * @brief Lead off Detection, suppose the increment of normal ECG value in LEADOFF_DET_POINT_NUM+1 samples point \r
+ * not exceed LEADOFF_DET_THR_mV\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchFifoBuffer pointer to read fifo data buffer\r
+ * @param[in] usFifoBufferLen read fifo buffer len\r
+ * @param[out] None\r
+ *\r
+ * @return lead off status output \r
+ * @retval #0 not detect lead off\r
+ * @retval bit0=1 AdcValue larger than thresh\r
+ * @retval bit1=1 IQ Value larger than thresh\r
+ */\r
+\r
+GU8 GH3X2X_LeadOffDetectSingleChip(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 unChipIndex, GU8 uchEcgSlotNum)\r
+{\r
+ GU16 usByteIndexTmp = 0;\r
+ GS32 j;\r
+ GU8 uchRet = 0;\r
+ GU32 fifoVal;\r
+ GS32 adcVal;\r
+ GU8 flagFastRecovery;\r
+ GS32 absAdcVal; //ABS of adcVal\r
+ GS64 temp;\r
+\r
+ STGh3x2xSoftLeadOffDetInfo * pstSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfo + unChipIndex;\r
+\r
+ for (usByteIndexTmp = 0; usByteIndexTmp < *pusFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+ {\r
+ if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == GH3X2X_AFE_GET_ECG_CHANNEL_MAP(uchEcgSlotNum))\r
+ {\r
+ fifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchFifoBuffer[usByteIndexTmp], puchFifoBuffer[usByteIndexTmp + 1],puchFifoBuffer[usByteIndexTmp + 2], puchFifoBuffer[usByteIndexTmp + 3]);\r
+ adcVal = (GS32)((fifoVal & 0x00FFFFFF)) - ADC_OFFSET; \r
+ flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+ if(flagFastRecovery)\r
+ {\r
+ pstSoftLeadOffDetInfo->uchFastRecoryHistory = 1;\r
+ //GH3X2X_INFO_LOG("has fast recovery!!!!\r\n");\r
+ }\r
+ if(0 == pstSoftLeadOffDetInfo->uchFastRecoryHistory)\r
+ {\r
+ //GH3X2X_INFO_LOG("Warning: No fast recovery!!!!\r\n");\r
+ continue;\r
+ }\r
+ if (pstSoftLeadOffDetInfo-> uchFlagFrPrev != flagFastRecovery)\r
+ {\r
+ GH3X2X_LeadOffDetectReset();\r
+ pstSoftLeadOffDetInfo->uchFastRecoryHistory = 1;\r
+ }\r
+ pstSoftLeadOffDetInfo-> uchFlagFrPrev = flagFastRecovery;\r
+\r
+ //sample counter\r
+ if (pstSoftLeadOffDetInfo -> snCounter < 20000)\r
+ pstSoftLeadOffDetInfo -> snCounter++;\r
+ \r
+ if (flagFastRecovery == 0 && pstSoftLeadOffDetInfo -> snCounter>COND_VAL_VALID_TIME)\r
+ {\r
+ absAdcVal = ABS(adcVal);\r
+ if (absAdcVal > g_LeadOffDetValThrRaw)\r
+ uchRet |= 0x01;\r
+ }\r
+ if (pstSoftLeadOffDetInfo -> sniqCounter < IQ_NUM / 2)\r
+ {\r
+ temp = (GS64)adcVal*winCoef[pstSoftLeadOffDetInfo -> sniqCounter];\r
+ }\r
+ else\r
+ {\r
+ temp = (GS64)adcVal*winCoef[IQ_NUM-1 - pstSoftLeadOffDetInfo -> sniqCounter];\r
+ }\r
+ switch (pstSoftLeadOffDetInfo -> sniqCounter%4)\r
+ {\r
+ case 0:\r
+ pstSoftLeadOffDetInfo -> snniVal += temp;\r
+ break;\r
+ case 1:\r
+ pstSoftLeadOffDetInfo -> snnqVal += temp;\r
+ break;\r
+ case 2:\r
+ pstSoftLeadOffDetInfo -> snniVal -= temp;\r
+ break;\r
+ case 3:\r
+ pstSoftLeadOffDetInfo -> snnqVal -= temp;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ if (pstSoftLeadOffDetInfo -> sniqCounter == (IQ_NUM - 1))\r
+ {\r
+ for (j = AMP_NUM-1; j >0; j--)\r
+ {\r
+ pstSoftLeadOffDetInfo -> snniqAmp[j] = pstSoftLeadOffDetInfo -> snniqAmp[j - 1];\r
+ }\r
+ pstSoftLeadOffDetInfo -> snniVal = pstSoftLeadOffDetInfo -> snniVal >> 31;\r
+ pstSoftLeadOffDetInfo -> snnqVal = pstSoftLeadOffDetInfo -> snnqVal >> 31;\r
+ pstSoftLeadOffDetInfo -> snniqAmp[0] = pstSoftLeadOffDetInfo -> snniVal*(int)pstSoftLeadOffDetInfo -> snniVal + pstSoftLeadOffDetInfo -> snnqVal*(int)pstSoftLeadOffDetInfo -> snnqVal;\r
+ pstSoftLeadOffDetInfo -> snniVal = 0;\r
+ pstSoftLeadOffDetInfo -> snnqVal = 0;\r
+ \r
+ if (flagFastRecovery == 0)\r
+ {\r
+ if (pstSoftLeadOffDetInfo -> snniqAmp[0] > g_lLeadOffDetIqAmpThrRaw && pstSoftLeadOffDetInfo -> snniqAmp[1] > g_lLeadOffDetIqAmpThrRaw)\r
+ uchRet |= 0x02;\r
+\r
+ if ((pstSoftLeadOffDetInfo -> snniqAmp[0] - pstSoftLeadOffDetInfo -> snniqAmp[2]) > g_lLeadOffDetIqAmpDiffThrRaw && (pstSoftLeadOffDetInfo -> snniqAmp[1] - pstSoftLeadOffDetInfo -> snniqAmp[2]) > g_lLeadOffDetIqAmpDiffThrRaw)\r
+ {\r
+ if(pstSoftLeadOffDetInfo ->snCounter > 2 * IQ_NUM)\r
+ {\r
+ uchRet |= 0x04;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (pstSoftLeadOffDetInfo -> snniqAmp[0] > g_lLeadOffDetIqAmpFrThrRaw && pstSoftLeadOffDetInfo -> snniqAmp[1] > g_lLeadOffDetIqAmpFrThrRaw)\r
+ uchRet |= 0x08;\r
+ }\r
+ }\r
+ pstSoftLeadOffDetInfo -> sniqCounter++;\r
+ pstSoftLeadOffDetInfo -> sniqCounter = pstSoftLeadOffDetInfo -> sniqCounter%(IQ_NUM);\r
+ } // end of if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == g_uchEcgLeadChannelMap)\r
+ } // end of for (usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+\r
+ return uchRet;\r
+}\r
+\r
+\r
+\r
+void GH3x2xSetEcgOutputFs(GU16 usEcgOutputFs)\r
+{\r
+ g_usEcgOutputFs = usEcgOutputFs;\r
+}\r
+\r
+GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum)\r
+{\r
+ GU8 uchRet = 0;\r
+ uchRet |= GH3X2X_LeadOffDetectSingleChip(puchFifoBuffer, pusFifoBufferLen, 0, uchEcgSlotNum);\r
+ if(g_uchGh3x2xEcgChnlNumLimit > 1)\r
+ {\r
+ uchRet |= GH3X2X_LeadOffDetectSingleChip(puchFifoBuffer, pusFifoBufferLen, 1, uchEcgSlotNum);\r
+ }\r
+ return uchRet;\r
+}\r
+\r
+void GH3X2X_DownSampleCal( GU8 *puchFifoBuffer, GU16 usByteIndexTmp, GU16 *usRawdataBufIdx, GU16 usSampleRate, STGh3x2xRsInfo * pstRsInfo ,STGh3x2xDownSampleCalParamInfo * pstDownSampCalParamInfo)\r
+{\r
+ GU32 fifoVal;\r
+ GS32 adcVal;\r
+ GU8 chNo;\r
+ GU8 flagFastRecovery;\r
+ GS32 j;\r
+\r
+ fifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchFifoBuffer[usByteIndexTmp], puchFifoBuffer[usByteIndexTmp + 1], puchFifoBuffer[usByteIndexTmp + 2], puchFifoBuffer[usByteIndexTmp + 3]);\r
+ chNo = (fifoVal >> 27); \r
+ adcVal = (GS32)((fifoVal & 0x00FFFFFF)) - ADC_OFFSET; \r
+ \r
+ if(g_uchDownSampleModule == DOWNSAMPLE_ECG)\r
+ {\r
+ flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+ if (pstRsInfo ->uchFlagFrPrev != flagFastRecovery)\r
+ {\r
+ GH3X2X_ECGResampleConfig(usSampleRate);\r
+ }\r
+ pstRsInfo ->uchFlagFrPrev = flagFastRecovery;\r
+ }\r
+\r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ else if(g_uchDownSampleModule == DOWNSAMPLE_PPG)\r
+ {\r
+ flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+ if (pstRsInfo ->uchFlagFrPrev != 1)\r
+ {\r
+ if(usSampleRate)\r
+ {\r
+ GH3X2X_PPGResampleConfig(usSampleRate);\r
+ }\r
+ }\r
+ pstRsInfo ->uchFlagFrPrev = 1;\r
+ }\r
+ #endif\r
+ \r
+ // ECG downsample\r
+ #if RESAMPLE_320HZ_TO_250HZ || RESAMPLE_256HZ_TO_250HZ\r
+ if((DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType) || (DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType))\r
+ { \r
+ GS32 LinerAdcVal;\r
+ if(pstDownSampCalParamInfo->uchRsEnable)\r
+ {\r
+ GS32 k;\r
+ GS64 y;\r
+\r
+ //??\r
+ if (pstRsInfo ->snRsFirState > 0)\r
+ {\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead - 1;\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead < 0 ? (pstDownSampCalParamInfo->uchRsBufSize - 1) : pstRsInfo ->snBufHead;\r
+ pstRsInfo ->snRsXbuf[pstRsInfo ->snBufHead] = adcVal;\r
+ }\r
+ else\r
+ {\r
+ for (j = 0; j < pstDownSampCalParamInfo->uchRsFirOrder / pstDownSampCalParamInfo->uchRsI + 1; j++)\r
+ pstRsInfo ->snRsXbuf[j] = adcVal;\r
+ pstRsInfo ->snBufHead = pstDownSampCalParamInfo->uchRsBufSize - 1;\r
+ }\r
+ \r
+ k = pstRsInfo ->snBufHead;\r
+ y = 0;\r
+ for (j = 1; j < pstDownSampCalParamInfo->uchRsFirCoefNum; j = j + 1) //\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+ for (; j <(pstDownSampCalParamInfo->uchRsFirOrder+1); j = j + 1) //\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[pstDownSampCalParamInfo->uchRsFirOrder - j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+\r
+ y = y >> SHIFTBITS;\r
+ k = (GS32)y + ADC_OFFSET; //\r
+ if (k < 0)\r
+ k = 0;\r
+ else if (k>=(ADC_OFFSET * 2))\r
+ k = (ADC_OFFSET * 2-1);\r
+\r
+ // ???????\r
+ if(pstRsInfo->uchLinearInterState >0)\r
+ {\r
+ #if RESAMPLE_320HZ_TO_250HZ\r
+ if(DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ if(pstRsInfo->fDownStep <=100)\r
+ {\r
+ LinerAdcVal = ((GU32)k*pstRsInfo->fDownStep + (100-pstRsInfo->fDownStep)*pstRsInfo->nRsLastRaw)/100;\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep - 100;\r
+ pstRsInfo->uchLinearDataUpdate = 1;\r
+ }\r
+ else\r
+ {\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep - 100;\r
+ pstRsInfo->uchLinearDataUpdate = 0;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_256HZ_TO_250HZ\r
+ if(DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ if(pstRsInfo->fDownStep <=1000)\r
+ {\r
+ LinerAdcVal = (GU32)(((GS64)(k)*(GS64)(pstRsInfo->fDownStep) + (GS64)((1000-pstRsInfo->fDownStep)*(GS64)(pstRsInfo->nRsLastRaw)))/1000);\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep - 1000;\r
+ pstRsInfo->uchLinearDataUpdate = 1;\r
+ }\r
+ else\r
+ {\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep - 1000;\r
+ pstRsInfo->uchLinearDataUpdate = 0;\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ LinerAdcVal = (GU32)k;\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep;\r
+ pstRsInfo->uchLinearInterState =1;\r
+ pstRsInfo->uchLinearDataUpdate = 1;\r
+ }\r
+\r
+ if(pstRsInfo->uchLinearDataUpdate == 1)\r
+ {\r
+ fifoVal = (((GU8)chNo)<<27) + (((GU8)flagFastRecovery)<<26) + ((GU32)LinerAdcVal/5);\r
+ puchFifoBuffer[*usRawdataBufIdx] = GH3X2X_AFE_GET_BYTE3_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 1] = GH3X2X_AFE_GET_BYTE2_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 2] = GH3X2X_AFE_GET_BYTE1_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 3] = GH3X2X_AFE_GET_BYTE0_FROM_DWORD(fifoVal);\r
+\r
+ *usRawdataBufIdx += GH3X2X_AFE_FIFO_RAWDATA_SIZE;\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_800HZ_TO_500HZ ||RESAMPLE_800HZ_TO_250HZ || (RESAMPLE_400HZ_TO_250HZ & (__SUPPORT_ECG_PPG_DOWNSAMP__))\r
+ if((DOWNSAMPLE_800HZ_TO_500HZ == pstECGDownSampCalParamInfo->uchDownSampleType)||(DOWNSAMPLE_800HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)||(DOWNSAMPLE_400HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType))\r
+ {\r
+ if(pstDownSampCalParamInfo->uchRsEnable)\r
+ {\r
+ GS32 k;\r
+ GS64 y;\r
+ GS32 delta;\r
+ if (pstRsInfo ->snRsFirState > 0)\r
+ {\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead - 1;\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead < 0 ? (pstDownSampCalParamInfo->uchRsBufSize - 1) : pstRsInfo ->snBufHead;\r
+ pstRsInfo ->snRsXbuf[pstRsInfo ->snBufHead] = adcVal;\r
+ pstRsInfo ->nRsIcounter += pstDownSampCalParamInfo->uchRsI;\r
+ }\r
+ else\r
+ {\r
+ for (j = 0; j < pstDownSampCalParamInfo->uchRsFirOrder / pstDownSampCalParamInfo->uchRsI + 1; j++)\r
+ pstRsInfo ->snRsXbuf[j] = adcVal;\r
+ pstRsInfo ->nRsIcounter = 0;\r
+ pstRsInfo ->snRsFirState = 1;\r
+ pstRsInfo ->snBufHead = pstDownSampCalParamInfo->uchRsBufSize - 1;\r
+ }\r
+\r
+ if (pstRsInfo ->nRrsDcounter >= pstRsInfo ->nRsIcounter && pstRsInfo ->nRrsDcounter < (pstRsInfo ->nRsIcounter + pstDownSampCalParamInfo->uchRsI))\r
+ {\r
+ delta = pstRsInfo ->nRrsDcounter - pstRsInfo ->nRsIcounter;\r
+ k = pstRsInfo ->snBufHead;\r
+ y = 0;\r
+ for (j = delta; j < pstDownSampCalParamInfo->uchRsFirCoefNum; j = j + pstDownSampCalParamInfo->uchRsI)\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+ for (j = j; j <(pstDownSampCalParamInfo->uchRsFirOrder+1); j = j + pstDownSampCalParamInfo->uchRsI)\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[pstDownSampCalParamInfo->uchRsFirOrder - j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+ pstRsInfo ->nRrsDcounter += pstDownSampCalParamInfo->uchRsD;\r
+\r
+ y = y >> SHIFTBITS;\r
+ k = (GS32)y + ADC_OFFSET;\r
+ if (k < 0)\r
+ k = 0;\r
+ else if (k>=(ADC_OFFSET * 2))\r
+ k = (ADC_OFFSET * 2-1); \r
+ fifoVal = (((GU8)chNo)<<27) + (((GU8)flagFastRecovery)<<26) + ((GU32)k);\r
+ puchFifoBuffer[*usRawdataBufIdx] = GH3X2X_AFE_GET_BYTE3_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 1] = GH3X2X_AFE_GET_BYTE2_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 2] = GH3X2X_AFE_GET_BYTE1_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 3] = GH3X2X_AFE_GET_BYTE0_FROM_DWORD(fifoVal);\r
+ *usRawdataBufIdx += GH3X2X_AFE_FIFO_RAWDATA_SIZE;\r
+ }\r
+ }\r
+ }\r
+#endif\r
+}\r
+\r
+void GH3X2X_EcgPPGRsHandleSingleChip(GU8 *puchFifoBuffer, GU16 *pusFifoBufferLen, GU8 uchChipIndex, GU8 uchEcgSlotNum ,GU16 usSampleRate)\r
+{\r
+ GU16 usByteIndexTmp = 0;\r
+ GU16 usRawdataBufIdx = 0;\r
+ GU8 usCheckDataType = 0; // 1:ECG 2:PPG 0:other\r
+\r
+ for (usByteIndexTmp = 0; usByteIndexTmp < *pusFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+ { \r
+ if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == GH3X2X_AFE_GET_ECG_CHANNEL_MAP((GU8)(GH3X2X_ECG_START_SLOT + uchEcgSlotNum)))\r
+ {\r
+ STGh3x2xRsInfo * pstRsInfo_ECG = g_pstGh3x2xEcgRsInfo + uchChipIndex;\r
+ g_uchDownSampleModule = DOWNSAMPLE_ECG;\r
+ GH3X2X_DownSampleCal( puchFifoBuffer, usByteIndexTmp, &usRawdataBufIdx, usSampleRate,pstRsInfo_ECG,pstECGDownSampCalParamInfo);\r
+ usCheckDataType =1;\r
+ }\r
+ \r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ if(g_uchPPGDownSampleChnlNumLimit && pstPPGDownSampCalParamInfo->uchRsEnable==1)\r
+ {\r
+ for(GU8 uchPPGSlotNumTmp = 0; uchPPGSlotNumTmp < g_uchPPGDownSampleChnlNumLimit; uchPPGSlotNumTmp++)\r
+ {\r
+ if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == GH3X2X_AFE_GET_PPG_CHANNEL_MAP((GU8)(GH3X2X_PPG_START_SLOT + uchPPGSlotNumTmp)))\r
+ {\r
+ STGh3x2xRsInfo * pstRsInfo_PPG = g_pstGh3x2xPPGRsInfo + uchPPGSlotNumTmp;\r
+ g_uchDownSampleModule = DOWNSAMPLE_PPG;\r
+ GH3X2X_DownSampleCal(puchFifoBuffer, usByteIndexTmp, &usRawdataBufIdx, usSampleRate,pstRsInfo_PPG,pstPPGDownSampCalParamInfo);\r
+ usCheckDataType =2;\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+ if(!usCheckDataType)\r
+ {\r
+ if(pstECGDownSampCalParamInfo->uchRsEnable)\r
+ {\r
+ //this rawdata is not ECG data\r
+ puchFifoBuffer[usRawdataBufIdx] = puchFifoBuffer[usByteIndexTmp];\r
+ puchFifoBuffer[usRawdataBufIdx + 1] = puchFifoBuffer[usByteIndexTmp + 1];\r
+ puchFifoBuffer[usRawdataBufIdx + 2] = puchFifoBuffer[usByteIndexTmp + 2];\r
+ puchFifoBuffer[usRawdataBufIdx + 3] = puchFifoBuffer[usByteIndexTmp + 3];\r
+ usRawdataBufIdx += GH3X2X_AFE_FIFO_RAWDATA_SIZE;\r
+ }\r
+ }\r
+ usCheckDataType = 0;\r
+ } // end of for (usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+ *pusFifoBufferLen = usRawdataBufIdx;\r
+}\r
+\r
+GU8 GH3X2X_AFE_EcgRsHandle(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum, GU16 usEcgSampleRate)\r
+{\r
+ if(pstECGDownSampCalParamInfo->uchRsEnable == 1)\r
+ {\r
+ GH3X2X_EcgPPGRsHandleSingleChip(puchFifoBuffer, pusFifoBufferLen, 0,uchEcgSlotNum,usEcgSampleRate);\r
+ return 1;\r
+ }\r
+ else\r
+ {\r
+ return 0;\r
+ }\r
+}\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
+\r
--- /dev/null
+#include "gh3x2x_afe_user.h"\r
+#include "gh3x2x_afe_drv.h"\r
+#include "pinctrl_porting.h"\r
+#include "hal_gpio.h"\r
+#include "i2c.h"\r
+#include "pm_definition.h"\r
+#if GH3X2X_AFE_MP_MODE\r
+// #include "gh3x2x_mp_common.h"\r
+#endif\r
+\r
+#include "los_tick.h"\r
+#include "debug_print.h"\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#include "gh3x2x_demo_goodix_PLATFORM.h"\r
+#else\r
+\r
+#include "spi.h"\r
+\r
+#define GOODIX_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length)\r
+#define GOODIX_PLATFORM_SPI_READ_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_CS_CTRL_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_RESET_PIN_ENTITY()\r
+#define GOODIX_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY()\r
+#define GOODIX_PLATFORM_LOG_ENTITY() \r
+#define GOODIX_PLATFORM_DELAY_US_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_MS_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_MS_ENTITY()\r
+#define GOODIX_PLATFORM_INT_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_RESET_PIN_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer,length)\r
+#define GOODIX_PLATFORM_I2C_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length)\r
+#endif\r
+\r
+#define GH3X2X_CS S_MGPIO3\r
+#define GH3X2X_CLK S_MGPIO2\r
+#define GH3X2X_MOSI S_MGPIO1\r
+#define GH3X2X_MISO S_MGPIO0\r
+\r
+#define GH3X2X_SPI_BUS SPI_BUS_0\r
+#define GH3X2X_I2C_BUS I2C_BUS_2\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_DelayUs(GU16 usUsec)\r
+ * \r
+ * @brief Delay in us,user should register this function into driver lib\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void hal_gh3x2x_afe_DelayUs(GU16 usUsec)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(usUsec);\r
+ // GOODIX_PLATFORM_DELAY_US_ENTITY();\r
+ LOS_Udelay(usUsec);\r
+\r
+}\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_BspDelayMs(GU16 usMsec)\r
+ * \r
+ * @brief Delay in ms\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void hal_gh3x2x_afe_DelayMs(GU16 usMsec)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(usMsec);\r
+ // GOODIX_PLATFORM_DELAY_MS_ENTITY();\r
+ LOS_Mdelay(usMsec);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+#if ( GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_I2C )\r
+\r
+/* i2c interface */\r
+/**\r
+ * @fn void hal_gh3x2x_afe_i2c_init(void)\r
+ * \r
+ * @brief hal i2c init for gh3x2x_afe\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void hal_gh3x2x_afe_i2c_init(void)\r
+{\r
+\r
+ /* code implement by user */\r
+ GOODIX_PLATFORM_I2C_INIT_ENTITY();\r
+\r
+}\r
+\r
+/**\r
+ * @fn uint8_t hal_gh3x2x_afe_i2c_write(uint8_t device_id, const uint8_t write_buffer[], uint16_t length)\r
+ * \r
+ * @brief hal i2c write for gh3x2x_afe\r
+ *\r
+ * @attention device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in] device_id device addr\r
+ * @param[in] write_buffer write data buffer\r
+ * @param[in] length write data len\r
+ * @param[out] None\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length)\r
+{\r
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 0) \r
+ {\r
+ uapi_pm_add_sleep_veto(PM_ID_HEART);\r
+ }\r
+ uint8_t ret = 1;\r
+\r
+ /* code implement by user */\r
+\r
+ // GOODIX_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer,length);\r
+ i2c_data_t i2c_data;\r
+ i2c_data.send_buf = write_buffer;\r
+ i2c_data.send_len = length;\r
+ i2c_data.receive_buf = NULL;\r
+ i2c_data.receive_len = 0;\r
+ // custom_i2c_write_reg(BN02_I2C_ADDR, 0x00, 1, &data, 1, BN02_I2C_BUS);\r
+ errcode_t result = uapi_i2c_master_write(GH3X2X_I2C_BUS, device_id, &i2c_data);\r
+ if (result != ERRCODE_SUCC) \r
+ printf("i2c write data fail! ret=0x%x\n", result);\r
+ // custom_i2c_read_regs(device_id, reg_addr, 1 , pBuffer, buf_size, VC9202_I2C_BUS);\r
+\r
+ cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 1) \r
+ {\r
+ uapi_pm_remove_sleep_veto(PM_ID_HEART);\r
+ }\r
+\r
+\r
+ return ret;\r
+}\r
+\r
+/**\r
+ * @fn uint8_t hal_gh3x2x_afe_i2c_read(uint8_t device_id, const uint8_t write_buffer[], uint16_t write_length,\r
+ * uint8_t read_buffer[], uint16_t read_length)\r
+ * \r
+ * @brief hal i2c read for gh3x2x_afe\r
+ *\r
+ * @attention device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in] device_id device addr\r
+ * @param[in] write_buffer write data buffer\r
+ * @param[in] write_length write data len\r
+ * @param[in] read_length read data len\r
+ * @param[out] read_buffer pointer to read buffer\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length)\r
+{\r
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 0) \r
+ {\r
+ uapi_pm_add_sleep_veto(PM_ID_HEART);\r
+ }\r
+ uint8_t ret = 1;\r
+\r
+ /* code implement by user */\r
+\r
+ // GOODIX_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length);\r
+\r
+ i2c_data_t i2c_data;\r
+ i2c_data.send_buf = write_buffer;\r
+ i2c_data.send_len = write_length;\r
+ i2c_data.receive_buf = read_buffer;\r
+ i2c_data.receive_len = read_length;\r
+\r
+ errcode_t result = uapi_i2c_master_writeread(GH3X2X_I2C_BUS, device_id, &i2c_data);\r
+ if (result != ERRCODE_SUCC) \r
+ printf("i2c read data fail! ret=0x%x\n", result);\r
+ // custom_i2c_read_regs(device_id, reg_addr, 1 , pBuffer, buf_size, VC9202_I2C_BUS);\r
+\r
+ cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 1) \r
+ {\r
+ uapi_pm_remove_sleep_veto(PM_ID_HEART);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+#else \r
+\r
+/* spi interface */\r
+/**\r
+ * @fn void hal_gh3x2x_afe_spi_init(void)\r
+ * \r
+ * @brief hal spi init for gh3x2x_afe\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void hal_gh3x2x_afe_spi_init(void)\r
+{\r
+ /* init spi and cs pin */\r
+ // GOODIX_PLATFORM_SPI_INIT_ENTITY();\r
+ spi_bus_t bus;\r
+ spi_attr_t attr;\r
+ bus = SPI_BUS_0;\r
+ attr.is_slave = false;\r
+ attr.slave_num = 1;\r
+ attr.bus_clk = 40000000;\r
+ attr.freq_mhz = 10;\r
+ attr.clk_polarity = (uint32_t)SPI_CFG_CLK_CPOL_1;\r
+ attr.clk_phase = (uint32_t)SPI_CFG_CLK_CPHA_1;\r
+ attr.frame_format = SPI_CFG_FRAME_FORMAT_MOTOROLA_SPI;\r
+ attr.spi_frame_format = (uint32_t)HAL_SPI_FRAME_FORMAT_STANDARD;\r
+ attr.frame_size = (uint32_t)HAL_SPI_FRAME_SIZE_8;\r
+ attr.tmod = HAL_SPI_TRANS_MODE_TXRX;\r
+ attr.sste = SPI_CFG_SSTE_DISABLE;\r
+ attr.ndf = 1;\r
+\r
+ uapi_spi_init(bus,&attr,NULL);\r
+}\r
+\r
+/**\r
+ * @fn GU8 hal_gh3x2x_afe_spi_write(GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief hal spi write for gh3x2x_afe\r
+ *\r
+ * @attention if __gh3x2x_afe_SPI_TYPE__ == __gh3x2x_afe_SPI_TYPE_SOFTWARE_CS__ , user need generate timming: write_buf[0](W) + write_buf[1](W) + ...\r
+ * @attention if __gh3x2x_afe_SPI_TYPE__ == __gh3x2x_afe_SPI_TYPE_HARDWARE_CS__ , user need generate timming: CS LOW + write_buf[0](W) + write_buf[1](W) + ... + CS HIGH\r
+ *\r
+ * @param[in] write_buffer write data buffer\r
+ * @param[in] length write data len\r
+ * @param[out] None\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_spi_write(GU8 write_buffer[], GU16 length)\r
+{\r
+ GU8 ret = 1;\r
+\r
+ \r
+ // GOODIX_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length);\r
+ spi_xfer_data_t sdata ={0} ;\r
+ sdata.tx_buff = write_buffer;\r
+ sdata.tx_bytes = length;\r
+ sdata.rx_buff = NULL;\r
+ sdata.rx_bytes = 0;\r
+\r
+ ret = uapi_spi_master_write(GH3X2X_SPI_BUS, &sdata, 0x100);\r
+\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+/**\r
+ * @fn GU8 hal_gh3x2x_afe_spi_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief hal spi read for gh3x2x_afe\r
+ *\r
+ * @attention user need generate timming: read_buf[0](R) + write_buf[1](R) + ... \r
+ *\r
+ * @param[in] read_length read data len\r
+ * @param[out] read_buffer pointer to read buffer\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_spi_read(GU8 read_buffer[], GU16 length)\r
+{\r
+ GU8 ret = 1;\r
+ // GH3X2X_AFE_UNUSED_VAR(read_buffer);\r
+ // GH3X2X_AFE_UNUSED_VAR(length);\r
+ // GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+\r
+ spi_xfer_data_t sdata ={0} ;\r
+ sdata.tx_buff = NULL;\r
+ sdata.tx_bytes = 0;\r
+ sdata.rx_buff = read_buffer;\r
+ sdata.rx_bytes = length;\r
+\r
+ ret = uapi_spi_master_read(GH3X2X_SPI_BUS, &sdata, 0x100);\r
+\r
+ return ret;\r
+}\r
+#elif (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS)\r
+/**\r
+ * @fn GU8 hal_gh3x2x_afe_spi_write_F1_and_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief hal spi write F1 and read for gh3x2x_afe\r
+ *\r
+ * @attention user need generate timming: CS LOW + F1(W) + read_buf[0](R) + read_buf[1](R) + ... + CS HIGH\r
+ *\r
+ * @param[in] write_buf write data\r
+ * @param[in] length write data len\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_spi_write_F1_and_read(GU8 read_buffer[], GU16 length)\r
+{\r
+ GU8 ret = 1;\r
+ GH3X2X_AFE_UNUSED_VAR(read_buffer);\r
+ GH3X2X_AFE_UNUSED_VAR(length);\r
+ GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+ \r
+ return ret;\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_spi_cs_ctrl(GU8 cs_pin_level)\r
+ * \r
+ * @brief hal spi cs pin ctrl for gh3x2x_afe\r
+ *\r
+ * @attention pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in] cs_pin_level spi cs pin level\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+void hal_gh3x2x_afe_spi_cs_ctrl(GU8 cs_pin_level)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(cs_pin_level);\r
+ // GOODIX_PLATFORM_SPI_CS_CTRL_ENTITY();\r
+\r
+ uapi_pin_set_mode(GH3X2X_CS, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(GH3X2X_CS, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(GH3X2X_CS, cs_pin_level);\r
+\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+#if (GH3X2X_AFE_RESET_TYPE == GH3X2X_AFE_RESET_HARDWARE)\r
+/**\r
+ * @fn void hal_gh3x2x_afe_int_init(void)\r
+ * \r
+ * @brief gh3x2x_afe int init\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+\r
+\r
+void hal_gh3x2x_afe_reset_pin_init(void)\r
+{\r
+ GOODIX_PLATFORM_RESET_PIN_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_reset_pin_ctrl(GU8 pin_level)\r
+ * \r
+ * @brief hal reset pin ctrl for gh3x2x_afe\r
+ *\r
+ * @attention pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in] pin_level reset pin level\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void hal_gh3x2x_afe_reset_pin_ctrl(GU8 pin_level)\r
+{\r
+ GH3X2X_AFE_UNUSED_VAR(pin_level);\r
+ GOODIX_PLATFORM_SPI_RESET_PIN_ENTITY();\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_int_init(void)\r
+ * \r
+ * @brief gh3x2x_afe int init\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+\r
+void hal_gh3x2x_afe_int_init(void)\r
+{\r
+ GOODIX_PLATFORM_INT_INIT_ENTITY();\r
+}\r
+\r
+#if (GH3X2X_AFE_PRO_BY_INT == GH3X2X_AFE_PRO_TYPE)\r
+/**\r
+ * @fn void hal_gh3x2x_afe_int_handler_call_back(void)\r
+ * \r
+ * @brief call back of gh3x2x_afe int handler\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void hal_gh3x2x_afe_int_handler_call_back(void)\r
+{\r
+/****************** DO NOT MODITY ****************************************************************/\r
+ GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(0); //not need wake up gh3x2x_afe when process int event\r
+ g_uchGh3x2xAfeIntCallBackIsCalled = 1;\r
+#if GH3X2X_AFE_MP_MODE\r
+ GH3X2X_MP_SET_INT_FLAG(); //gh3x2x mp test must call it\r
+#endif\r
+/****************** DO NOT MODITY ****************************************************************/\r
+ \r
+ \r
+ \r
+ GOODIX_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY();\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_Log(char *log_string)\r
+ * \r
+ * @brief for debug version, log\r
+ *\r
+ * @attention this function must define that use debug version lib\r
+ *\r
+ * @param[in] log_string pointer to log string\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_Log(GCHAR *log_string)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(log_string);\r
+ // GOODIX_PLATFORM_LOG_ENTITY();\r
+ PRINT("%s", log_string);\r
+}\r
+\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-03-13 15:08:38
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-17 17:57:09
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
+ * @Description:
+ *
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include "pm_control.h"
+#include "pinctrl_porting.h"
+#include "hal_gpio.h"
+
+// S_AGPIO_L26 心率复位 PPG reset
+#define GPIO_PIN_PRG_RESET S_AGPIO_L26
+// S_AGPIO_R0 PRG_LED_POWER ON 心率等电源控制脚
+#define GPIO_PIN_PRG_LED_ON S_AGPIO_R0
+
+uint32_t tyhx_poweron(void)
+{
+
+ uapi_pin_set_mode(S_AGPIO_L24, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(S_AGPIO_L24, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(S_AGPIO_L24, GPIO_LEVEL_LOW);
+ LOS_Mdelay(1);
+ uapi_pin_set_mode(S_MGPIO0, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(S_MGPIO0, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(S_MGPIO0, GPIO_LEVEL_LOW);
+ LOS_Mdelay(1);
+ uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_HIGH);
+ LOS_Mdelay(1);
+ uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_HIGH);
+
+ LOS_Mdelay(50);
+ return 0;
+}
+uint32_t tyhx_poweroff(void)
+{
+ uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_LOW);
+
+ uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_LOW);
+ LOS_Mdelay(50);
+ return 0;
+}
+
+void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable)
+{
+ // work_mode md = 1;
+ // if (strcmp(mode, "hrs") == 0) {
+ // md = WORK_MODE_HR;
+ // } else if (strcmp(mode, "hrv") == 0) {
+ // md = WORK_MODE_HRV;
+ // } else if (strcmp(mode, "spo2") == 0) {
+ // md = WORK_MODE_SPO2;
+ // } else if (strcmp(mode, "leaklight") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ // } else if (strcmp(mode, "graycard") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ // } else if (strcmp(mode, "ledoff") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ // } else if (strcmp(mode, "wear") == 0) {
+ // md = WORK_MODE_WEAR;
+ // } else if (strcmp(mode, "single") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ // }else if (strcmp(mode, "factory") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ // }else if (strcmp(mode, "fpc") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ // }else if (strcmp(mode, "int") == 0) {
+ // if(vc921x_device)
+ // vc921x_device->ops->dev_irq_handler(0,0);
+ // return;
+ // }
+
+ // if (enable == 1)
+ // {
+ // // ppg_service_running_stat = true;
+ // uapi_pm_control(PM_APP_WAKE_NEEDED);
+ // tyhx_poweron();
+
+ // vc921x_device = get_vc921x_device();
+ // if(!vc921x_device)
+ // {
+ // printf("get_vc921x_device failed !!!\n");
+ // tyhx_poweroff();
+ // return;
+ // }
+ // InitParamTypeDef pInit_Param = {0};
+ // pInit_Param.sampling_gap_time = 400;
+ // pInit_Param.work_mode = md;
+ // vc921x_device->ops->dev_init(&pInit_Param);
+
+ // } else {
+
+ // uapi_pm_control(PM_APP_WAKE_NONEED);
+ // vc921x_device->ops->stop_work();
+ // tyhx_poweroff();
+ // }
+}
\ No newline at end of file
#elif defined(PPG_VC921X)
#include "vc921x_hal.h"
#include "vc921x_user_app.h"
+#elif defined(PPG_GH3X2X)
+#include "gh3x2x_hal.h"
+#include "gh3x2x_afe_drv.h"
#else
#include "hx3695_hal.h"
#include "hx3695.h"
tyhx_poweroff();
return ERRCODE_FAIL;
}
+#elif defined(PPG_GH3X2X)
+ if (GH3X2X_AFE_CheckChipId() != 0)
+ {
+ //TODO 没找到3695,退出线程
+ PRINT("PPG_GH3X2X not exist!\r\n");
+ tyhx_poweroff();
+ return ERRCODE_FAIL;
+ }
#endif
tyhx_poweroff();
{
#if defined(BOARD_FD230)
return ( GPIO_LEVEL_HIGH == uapi_gpio_get_output_val(S_AGPIO_L23));
-#elif defined(BOARD_L22) || defined(BOARD_W9)
+#elif defined(BOARD_L22)
return ( GPIO_LEVEL_HIGH == uapi_gpio_get_output_val(S_AGPIO_L14));
+#elif defined(BOARD_W9)
+ return ( GPIO_LEVEL_HIGH == uapi_gpio_get_output_val(S_AGPIO_L17));
#endif
}
#define GPIO_PIN_CHARGE_STAT S_AGPIO_L29
void disable_charge(void)
{
-#ifdef BOARD_FD230
+#if defined(BOARD_FD230) || defined(BOARD_W9)
// PRINT("disable_charge\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE, GPIO_DIRECTION_OUTPUT);
void enable_charge(void)
{
-#ifdef BOARD_FD230
+#if defined(BOARD_FD230) || defined(BOARD_W9)
// PRINT("enable_charge\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE, GPIO_DIRECTION_OUTPUT);
void enable_02c(void)
{
-#ifdef BOARD_FD230
+#if defined(BOARD_FD230) || defined(BOARD_W9)
// PRINT("enable_charge_02c\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE_0_2C, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE_0_2C, GPIO_DIRECTION_OUTPUT);
}
void disable_02c(void)
{
-#ifdef BOARD_FD230
+#if defined(BOARD_FD230) || defined(BOARD_W9)
// PRINT("disable_charge_02c\r\n");
uapi_pin_set_mode(GPIO_PIN_ENABLE_CHARGE_0_2C, (pin_mode_t)HAL_PIO_FUNC_GPIO);
uapi_gpio_set_dir(GPIO_PIN_ENABLE_CHARGE_0_2C, GPIO_DIRECTION_OUTPUT);
* @Author: penglei 1624952103@qq.com\r
* @Date: 2024-06-17 14:31:08\r
* @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-01-09 16:57:54\r
+ * @LastEditTime: 2025-01-16 10:01:35\r
* @FilePath: /FD230/code/sdk/application/wearable/service/factorytest_service/factorytest_protocol.c\r
* @Description: \r
* \r
#ifdef ENABLE_HP4507\r
#include "hp4570.h"\r
#endif\r
-\r
+#ifdef PPG_VC9202\r
+#include "vc9202_user.h"\r
+#endif\r
+#ifdef SUPPORT_GNSS\r
+#include "gnss_ctl.h"\r
+#include "NMEA0183.h"\r
+static gps_data_t send_gps_data = {0};\r
+#endif\r
#pragma pack(1)\r
typedef struct factorytest_cmd_header_t\r
{\r
1);\r
LOS_Mdelay(100);\r
uapi_poweroff_device();\r
+ } else if(testitem == 0x06)\r
+ {\r
+ //切换vbus供电测电流\r
+ uint8_t send_data = 0x00;\r
+#ifdef ENABLE_HP4507\r
+ hp45xxx_init(HP4570C9);\r
+ hp45xxx_set_batfet_dis(true);\r
+ // hp45xxx_set_ceb_en(true);\r
+ hp45xxx_set_hiz_en(false);\r
+ LOS_Mdelay(50);\r
+ if (hp45xxx_read_status_vbus_pg()) \r
+ PRINT("VBUS is in Power Good state\n");\r
+ else \r
+ PRINT("VBUS is not in Power Good state\n");\r
+ \r
+#endif\r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_PM,\r
+ 0x06,\r
+ &send_data,\r
+ 1);\r
}\r
+ \r
\r
break;\r
\r
\r
break;\r
\r
+ case BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS:\r
+\r
+ if (testitem == 0x01)\r
+ {\r
+ //定位\r
+ uint8_t send_data = 0;\r
+ bool flag = 0;\r
+ char tmp[1024]={0};\r
+ char time[10]={0};\r
+#ifdef SUPPORT_GNSS\r
+ gnss_start();\r
+ LOS_Msleep(100);\r
+ do{\r
+ gps_data_t *gps_data = getGPSGlobaldata();\r
+ if(gps_data == NULL)\r
+ {\r
+ PRINT("gps_data == NULL \n");\r
+ return;\r
+ }\r
+ if (gps_data->last_gps_time_ms > 0)\r
+ {\r
+ memcpy_s(&send_gps_data,sizeof(gps_data_t),gps_data,sizeof(gps_data_t));\r
+ }\r
+ if(send_gps_data.status > 1)\r
+ {\r
+ flag = 1;\r
+ }\r
+ else\r
+ {\r
+ LOS_Msleep(1000);\r
+ send_data++;\r
+ }\r
+ memset_s(tmp,sizeof(tmp),0,sizeof(tmp)); \r
+ dump_location_data_to_factory(&send_gps_data,tmp,sizeof(tmp));\r
+ memset_s(time,sizeof(time),0,sizeof(time)); \r
+ sprintf_s(time,sizeof(time),"%d",send_data);\r
+ strcat_s(tmp,sizeof(tmp),time);\r
+ // PRINT("send_gps_data.status : %d time : %d\n",send_gps_data.status,send_data);\r
+ // PRINT("tmp : %s size : %d\n",tmp,strlen(tmp));\r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS,\r
+ 0x01,\r
+ (uint8_t*)tmp,\r
+ strlen(tmp));\r
+ }while(send_data <= 2 * 60 && !flag);\r
+ // PRINT("定位超时 关闭GPS\n");\r
+ gnss_stop();\r
+#endif\r
+\r
+ } else if(testitem == 0x02)\r
+ {\r
+ //获取可见星 有效星 信号增益 定位精度\r
+ uint8_t send_data[7] = {0};\r
+#ifdef SUPPORT_GNSS\r
+ // if(send_gps_data)\r
+ {\r
+ send_data[0] = send_gps_data.num_sats;\r
+ send_data[1] = send_gps_data.th001_valid_star_count;\r
+ send_data[2] = send_gps_data.th000_signal_vga;\r
+ send_data[3] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0xFF000000) >> 24);\r
+ send_data[4] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0x00FF0000) >> 16);\r
+ send_data[5] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0x0000FF00) >> 8);\r
+ send_data[6] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0x000000FF) >> 0);\r
+\r
+ // PRINT("gps_data->num_sats : %d,gps_data->th001_valid_star_count : %d,gps_data->th000_signal_vga : %d,gps_data->th001_quality : %f\n",\r
+ // send_gps_data.num_sats,send_gps_data.th001_valid_star_count,\r
+ // send_gps_data.th000_signal_vga,send_gps_data.th001_quality\r
+ // );\r
+ // PRINT("%2X %2X %2X\r\n",send_data[0],send_data[1],send_data[2]);\r
+ // PRINT("%2X %2X %2X %2X \r\n",send_data[3],send_data[4],send_data[5],send_data[6]);\r
+ }\r
+#endif\r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS,\r
+ 0x02,\r
+ send_data,\r
+ sizeof(send_data));\r
+ }\r
+\r
+ break;\r
+\r
default:\r
printf("");\r
break;\r
\r
printf("crc16 0x%04X vs 0x%04X\n",crc16,crc16_2);\r
\r
- // if( crc16 == crc16_2) //校验通过,开始正式解析\r
+ if( crc16 == crc16_2) //校验通过,开始正式解析\r
{\r
if(factorytest_mode_flag == 0 && header.submod != BLE_TEST_CMD_COMMON_SUB_MODE_SWITCH_MODE)\r
return ERRCODE_FAIL;\r
#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER 0x1B
//软件测试 子模式ID 气压计
#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_LQBP 0x1C
+//软件测试 子模式ID GPS
+#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS 0x1D
+
//软件测试 子模式ID 通讯录
#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_CONTACTS 0x30
//软件测试 子模式ID 支付宝
void dump_location_data_to_buf(gps_data_t *locationdata,char* buf,int max_buflen);\r
gps_data_t * getGPSGlobaldata(void);\r
\r
+void dump_location_data_to_factory(gps_data_t *locationdata,char* buf,int max_buflen);\r
+\r
#ifdef __cplusplus\r
}\r
#endif /* __cplusplus */\r
#endif\r
free(tmpbuf);\r
}\r
+\r
+void dump_location_data_to_factory(gps_data_t *locationdata,char* buf,int max_buflen)\r
+{\r
+ \r
+ char *tmpbuf=(char*)malloc(DUMP_BUF_SIZE);\r
+ if (tmpbuf == NULL) return;\r
+#ifndef NOUTILS\r
+\r
+ // memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ // sprintf_s(tmpbuf,DUMP_BUF_SIZE,"xx卫星[卫星数](strid,snr):\n");\r
+\r
+ if (locationdata->starcountP>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"G,%d",\r
+ locationdata->starcountP);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ for(int i=0;i<5;i++)\r
+ {\r
+ // printf("i : %d locationdata->startsP[i].starID : %d \n",i,locationdata->startsP[i].starID);\r
+ if (i< locationdata->startsP[i].starID>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",%d,%d",\r
+ locationdata->startsP[i].starID,\r
+ locationdata->startsP[i].snr);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"G,0,0,0,0,0,0,0,0,0,0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+\r
+ strcat_s(buf,max_buflen,";");\r
+\r
+\r
+ if (locationdata->starcountB>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"B,%d",\r
+ locationdata->starcountB);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ for(int i=0;i<5;i++)\r
+ {\r
+ // printf("i : %d locationdata->startsB[i].starID : %d \n",i,locationdata->startsB[i].starID);\r
+ if (i< locationdata->startsB[i].starID>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",%d,%d",\r
+ locationdata->startsB[i].starID,\r
+ locationdata->startsB[i].snr);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"B,0,0,0,0,0,0,0,0,0,0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ \r
+ strcat_s(buf,max_buflen,";");\r
+\r
+ if (locationdata->starcountN>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,";N,%d",\r
+ locationdata->starcountN);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ for(int i=0;i<5;i++)\r
+ {\r
+ // printf("i : %d locationdata->startsN[i].starID : %d \n",i,locationdata->startsN[i].starID);\r
+ if (i< locationdata->startsN[i].starID>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",%d,%d",\r
+ locationdata->startsN[i].starID,\r
+ locationdata->startsN[i].snr);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"N,0,0,0,0,0,0,0,0,0,0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+\r
+ strcat_s(buf,max_buflen,";");\r
+\r
+ if (locationdata->starcountL>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"L,%d",\r
+ locationdata->starcountL);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ for(int i=0;i<5;i++)\r
+ {\r
+ // printf("i : %d locationdata->startsL[i].starID : %d \n",i,locationdata->startsL[i].starID);\r
+ if (i< locationdata->startsL[i].starID>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",%d,%d",\r
+ locationdata->startsL[i].starID,\r
+ locationdata->startsL[i].snr);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"L,0,0,0,0,0,0,0,0,0,0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+\r
+ strcat_s(buf,max_buflen,";");\r
+\r
+ if (locationdata->starcountQ>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"Q,%d",\r
+ locationdata->starcountQ);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ for(int i=0;i<5;i++)\r
+ {\r
+ // printf("i : %d locationdata->startsQ[i].starID : %d \n",i,locationdata->startsQ[i].starID);\r
+ if (i< locationdata->startsQ[i].starID>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",%d,%d",\r
+ locationdata->startsQ[i].starID,\r
+ locationdata->startsQ[i].snr);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"Q,0,0,0,0,0,0,0,0,0,0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+\r
+ strcat_s(buf,max_buflen,";");\r
+ \r
+ if (locationdata->starcountA>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"A,%d",\r
+ locationdata->starcountA);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ for(int i=0;i<5;i++)\r
+ {\r
+ // printf("i : %d locationdata->startsA[i].starID : %d \n",i,locationdata->startsA[i].starID);\r
+ if (i< locationdata->startsA[i].starID>0)\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",%d,%d",\r
+ locationdata->startsA[i].starID,\r
+ locationdata->startsA[i].snr);\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,",0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ memset_s(tmpbuf,DUMP_BUF_SIZE,0,DUMP_BUF_SIZE);\r
+ sprintf_s(tmpbuf,DUMP_BUF_SIZE,"A,0,0,0,0,0,0,0,0,0,0,0");\r
+ strcat_s(buf,max_buflen,tmpbuf);\r
+ }\r
+ strcat_s(buf,max_buflen,";");\r
+#endif\r
+ free(tmpbuf);\r
+}\r
+\r
+\r
#define MSGBUF_LEN 1024\r
void dump_location_data(gps_data_t*locationdata)\r
{\r
uint32_t custom_i2c_suspend(void)
{
i2c_save_reg(I2C_BUS_2);
+#ifdef ENABLE_BN02
+ i2c_save_reg(I2C_BUS_0);
+#endif
return 0;
}
uint32_t custom_i2c_resume(void)
{
i2c_recovery_reg(I2C_BUS_2);
+#ifdef ENABLE_BN02
+ i2c_recovery_reg(I2C_BUS_0);
+#endif
return 0;
}
return ERRCODE_SUCC;
}
#include "cywee_hal.h"
-#include "hx3695_hrs_agc.h"
+
static uint32_t custom_gsensor_getdata(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
{
// gsenson_t *t;