From: SnickerSun Date: Sat, 20 Jan 2024 10:26:25 +0000 (+0800) Subject: 同步m_master代码: X-Git-Tag: release_V1.2.70_20241020_135402~1352 X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.css?a=commitdiff_plain;h=4e64c5b0e9e53911bae58b7260ebe52703c3e899;p=mirrors%2FFD230.git 同步m_master代码: 添加驱动:lis2doc,mmc5603,hx3659,hx3507,优化batteryservice,添加SN写号指令。 修复xts执行失败问题 --- diff --git a/code/sdk/application/battery/service/battery_service.c b/code/sdk/application/battery/service/battery_service.c index 7c9065a9e..7ff854a07 100644 --- a/code/sdk/application/battery/service/battery_service.c +++ b/code/sdk/application/battery/service/battery_service.c @@ -177,7 +177,7 @@ static bool adc_get_sample_result(float *voltage, uint8_t channel) *voltage = adc_trans_systick_to_battery_ntc(stick); else if (channel == 5) *voltage = adc_trans_systick_to_pcb_ntc(stick); - ///osal_printk("channel = %d , tick = %d , voltage = %.04f.\r\n", channel,stick,*voltage); + // osal_printk("channel = %d , tick = %d , voltage = %.04f.\r\n", channel,stick,*voltage); UNUSED(discard_number); return true; @@ -299,7 +299,7 @@ void disable_02c(void) uint8_t get_charge_stat(void) { uint16_t vbus_status = reg32_getbit(ULP_WKUP_INT_STS, 0x4); - uint16_t g_ulp_wkup_flag = readw(ULP_WKUP_INT_STS); + uint16_t g_ulp_wkup_flag = reg32_getbit(ULP_WKUP_INT_STS, 0x5); PRINT("get_charge_stat %02X %02X\r\n",vbus_status,g_ulp_wkup_flag); if (vbus_status == 1) { return 1; @@ -312,14 +312,6 @@ errcode_t uapi_battery_init(void); #include "tcxo.h" uint8_t batteryservice_get_voltage(float *voltage) { - - // if (g_batter_service_initialled == false) - // { - // uapi_battery_init(); - // g_batter_service_initialled = true; - // *voltage = 0; - // return 0; - // } uint8_t percent = 0; *voltage = current_battery_info.battery_voltage; if (*voltage <= batteryservice_VOLTAGE_MIN) @@ -332,28 +324,12 @@ uint8_t batteryservice_get_voltage(float *voltage) uint8_t batteryservice_get_battery_temp(float *temp) { - // if (g_batter_service_initialled == false) - // { - // uapi_battery_init(); - // g_batter_service_initialled = true; - // *temp = 0; - // return 0; - // } - *temp = current_battery_info.battery_ntc_temp; return 0; } uint8_t batteryservice_get_pcb_temp(float *temp) { - - // if (g_batter_service_initialled == false) - // { - // uapi_battery_init(); - // g_batter_service_initialled = true; - // *temp = 0; - // return 0; - // } *temp = current_battery_info.pcb_ntc_temp; return 0; } @@ -362,68 +338,49 @@ uint8_t batteryservice_get_pcb_temp(float *temp) * 电池电压读取逻辑: * 充电10秒,停止充电1秒,并读取电压。之后再开始充电10秒,再停止充电一秒,读取电压,然后再开始充电。。。。依此类推。 * **/ -#define USE_APP_TIMER 1 #include "cmsis_os2.h" #include "input_app.h" -#if USE_APP_TIMER + osTimerId_t g_battery_timer = NULL; -#else -timer_handle_t g_battery_timer = {0}; -#endif + static bool g_bat_timer_is_running = false; #define DISABLE_CHARGE_CHECK_MS 1000 #define ENABLE_CHARGE_TIMEOUT_MS 10000 -bool last_battery_charge_enable_status=false; // true上次刚设置在充电状态,false 上次设置不在充电状态。注意这个是充电IC的充电开关设置,并非真正处于充电状态的标识。 +bool last_battery_charge_enable_status=true; // true上次刚设置在充电状态,false 上次设置不在充电状态。注意这个是充电IC的充电开关设置,并非真正处于充电状态的标识。 static unsigned long g_app_queue; #define BATTERY_CMD_CHECK_VOLTAGE 0x11 #define BATTERY_CMD_DISABLE_CHARGE 0x12 -#if USE_APP_TIMER + static void battery_check_timer_callback(void* data); -#else -static void battery_check_timer_callback(uint32_t data); -#endif + static void battery_timer_start_check_released(uint32_t rtc_ms) { - // bool start = false; - // if (!g_bat_timer_is_running) { - // g_bat_timer_is_running = true; - // start = true; - // } - - -#if USE_APP_TIMER - if (g_bat_timer_is_running) osTimerStop(g_battery_timer); - osTimerStart(g_battery_timer, rtc_ms); -#else - if (g_bat_timer_is_running) uapi_rtc_stop(g_battery_timer); - uapi_rtc_start(g_battery_timer, rtc_ms, battery_check_timer_callback, 1); -#endif + if (g_bat_timer_is_running) osTimerStop(g_battery_timer); + osTimerStart(g_battery_timer, rtc_ms); g_bat_timer_is_running = true; } void do_battery_check_msg(int cmd); static void battery_check_and_enable_charge(void); -#if USE_APP_TIMER + + static void battery_check_timer_callback(void * data) -#else -static void battery_check_timer_callback(uint32_t data) -#endif { unused(data); g_bat_timer_is_running = false; if(last_battery_charge_enable_status == true){ - // do_battery_check_msg(BATTERY_CMD_DISABLE_CHARGE); - disable_charge(); - uapi_tcxo_delay_ms(20); + do_battery_check_msg(BATTERY_CMD_DISABLE_CHARGE); + // disable_charge(); + // uapi_tcxo_delay_ms(20); battery_timer_start_check_released(DISABLE_CHARGE_CHECK_MS); last_battery_charge_enable_status = false; }else{ - // do_battery_check_msg(BATTERY_CMD_CHECK_VOLTAGE); - battery_check_and_enable_charge(); - uapi_tcxo_delay_ms(20); + do_battery_check_msg(BATTERY_CMD_CHECK_VOLTAGE); + // battery_check_and_enable_charge(); + // uapi_tcxo_delay_ms(20); battery_timer_start_check_released(ENABLE_CHARGE_TIMEOUT_MS); last_battery_charge_enable_status = true; } @@ -432,13 +389,8 @@ static void battery_check_timer_callback(uint32_t data) void uapi_battery_deinit(void) { /* Stop the time and clear the pin map */ -#if USE_APP_TIMER osTimerStop(g_battery_timer); osTimerDelete(g_battery_timer); -#else - uapi_rtc_stop(g_battery_timer); - uapi_rtc_delete(g_battery_timer); -#endif g_bat_timer_is_running = false; g_battery_timer = NULL; } @@ -476,27 +428,6 @@ static void battery_check_task(void const *arg) common_notify_mail_t mail; uint32_t msgsize = (uint32_t)sizeof(common_notify_mail_t); -#if USE_APP_TIMER - g_battery_timer = osTimerNew((osTimerFunc_t)battery_check_timer_callback, osTimerPeriodic, NULL, NULL); -#else - // ret = uapi_rtc_init(); - - // ret |= uapi_rtc_adapter(0, RTC_0_IRQN, irq_prio(RTC_0_IRQN)); /* 1: using timer1 */ - // if (ret != ERRCODE_SUCC) { - // PRINT("uapi_rtc_init FAILED 0x%x", ret); - // return ; - // } - ret = uapi_rtc_create(RTC_1, &g_battery_timer); /* 1: using timer1 */ - if (ret != ERRCODE_SUCC) { - PRINT("uapi_rtc_create FAILED 0x%x", ret); - return ; - } - -#endif - - //开始timer - battery_timer_start_check_released(ENABLE_CHARGE_TIMEOUT_MS); - while (1) { ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize, OSAL_MSGQ_WAIT_FOREVER); @@ -504,7 +435,14 @@ static void battery_check_task(void const *arg) continue; } + #ifdef XTS_SUPPORT + extern uint8_t is_xts_test_done(void); + if (is_xts_test_done() == 0) + continue; + #endif + // get_charge_stat(); if (mail.comm.app == BATTERY_CMD_CHECK_VOLTAGE) { + battery_check_and_enable_charge(); uapi_tcxo_delay_ms(20); }else if (mail.comm.app == BATTERY_CMD_DISABLE_CHARGE) { @@ -531,7 +469,11 @@ errcode_t uapi_battery_init(void) return ERRCODE_FAIL; } - osal_kthread_set_priority(task_handle, APP_BOARD_TASK_PRIO); + // osal_kthread_set_priority(task_handle, APP_BOARD_TASK_PRIO); + osal_kthread_set_priority(task_handle, 10); + g_battery_timer = osTimerNew((osTimerFunc_t)battery_check_timer_callback, osTimerPeriodic, NULL, NULL); + //开始timer + battery_timer_start_check_released(DISABLE_CHARGE_CHECK_MS); return ERRCODE_SUCC; } diff --git a/code/sdk/application/battery/service/battery_service.h b/code/sdk/application/battery/service/battery_service.h index 5e64cc8da..3aa4a8027 100644 --- a/code/sdk/application/battery/service/battery_service.h +++ b/code/sdk/application/battery/service/battery_service.h @@ -7,8 +7,8 @@ * 2022-08-16, Create file. \n */ -#ifndef BATTERY_H__ -#define BATTERY_H__ +#ifndef BATTERY_SERVICE_H__ +#define BATTERY_SERVICE_H__ #ifdef __cplusplus #if __cplusplus diff --git a/code/sdk/application/brandy/brandy_standard/service_init.c b/code/sdk/application/brandy/brandy_standard/service_init.c index 359fe53ff..ff107e246 100755 --- a/code/sdk/application/brandy/brandy_standard/service_init.c +++ b/code/sdk/application/brandy/brandy_standard/service_init.c @@ -37,6 +37,35 @@ #ifdef SUPPORT_AT_MEDIA #include "media_cmd_manager.h" #endif + +#ifdef SUPPORT_AT_HX3695 +#include "hx3695_at_cmd.h" +#endif + +#ifdef SUPPORT_AT_VIBRATOR +#include "vibrator_at_cmd.h" +#endif + +#ifdef SUPPORT_AT_HX3507 +#include "hx3507_at_cmd.h" +#endif + +#ifdef SUPPORT_AT_BATTERY +#include "battery_at_cmd.h" +#endif + +#ifdef SUPPORT_AT_LIS2DOC +#include "lis2doc_at_cmd.h" +#endif + +#ifdef SUPPORT_AT_MMC5603 +#include "mmc5603_at_cmd.h" +#endif + +#ifdef SUPPORT_AT_CUSTOMUTILS +#include "custom_utils_at_cmd.h" +#endif + #include "log_file.h" #ifdef CONFIG_OTA_UPDATE_SUPPORT #include "upg.h" @@ -75,6 +104,49 @@ static void register_at_service(void) at_cmd_table_t *media_table = get_media_cmd_table(&media_cmd_count); at_cmd_add_moudle(media_table, media_cmd_count); #endif + +#ifdef SUPPORT_AT_HX3695 + uint32_t hx3695_cmd_count; + at_cmd_table_t *hx3695_table = get_hx3695_cmd_table(&hx3695_cmd_count); + at_cmd_add_moudle(hx3695_table, hx3695_cmd_count); +#endif + +#ifdef SUPPORT_AT_VIBRATOR + uint32_t vibrator_cmd_count; + at_cmd_table_t *vibrator_table = get_vibrator_cmd_table(&vibrator_cmd_count); + at_cmd_add_moudle(vibrator_table, vibrator_cmd_count); +#endif + +#ifdef SUPPORT_AT_HX3507 + uint32_t hx3507_cmd_count; + at_cmd_table_t *hx3507_table = get_hx3507_cmd_table(&hx3507_cmd_count); + at_cmd_add_moudle(hx3507_table, hx3507_cmd_count); +#endif + +#ifdef SUPPORT_AT_BATTERY + uint32_t battery_cmd_count; + at_cmd_table_t *battery_table = get_battery_cmd_table(&battery_cmd_count); + at_cmd_add_moudle(battery_table, battery_cmd_count); +#endif + +#ifdef SUPPORT_AT_CUSTOMUTILS + uint32_t custom_utils_cmd_count; + at_cmd_table_t *custom_utils_table = get_custom_utils_cmd_table(&custom_utils_cmd_count); + at_cmd_add_moudle(custom_utils_table, custom_utils_cmd_count); +#endif + +#ifdef SUPPORT_AT_LIS2DOC + uint32_t lis2doc_cmd_count; + at_cmd_table_t *lis2doc_table = get_lis2doc_cmd_table(&lis2doc_cmd_count); + at_cmd_add_moudle(lis2doc_table, lis2doc_cmd_count); +#endif + +#ifdef SUPPORT_AT_MMC5603 + uint32_t mmc5603_cmd_count; + at_cmd_table_t *mmc5603_table = get_mmc5603_cmd_table(&mmc5603_cmd_count); + at_cmd_add_moudle(mmc5603_table, mmc5603_cmd_count); +#endif + } #ifdef CONFIG_OTA_UPDATE_SUPPORT diff --git a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c index df411ad5d..e215a2ee8 100755 --- a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c +++ b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c @@ -55,7 +55,12 @@ #ifdef SUPPORT_BATTERY_SERVICE #include "battery_service.h" #endif - +#ifdef MAG_MMC5603 +#include "mag_service.h" +#endif +#ifdef ACC_LIS2DOC +#include "acc_service.h" +#endif #define EMMC_BASE_ADDR 0x52062000 #define TASK_PRIORITY_APP (osPriority_t)(17) #define TICK_TEN_MS (10U) @@ -271,6 +276,12 @@ static void thread_main(const void *unused) #ifdef SUPPORT_BATTERY_SERVICE uapi_battery_init(); +#endif +#ifdef MAG_MMC5603 + uapi_mag_service_init(); +#endif +#ifdef ACC_LIS2DOC + uapi_acc_service_init(); #endif set_startup_finish_flag(); } diff --git a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c.bak b/code/sdk/application/brandy/brandy_standard/thread_pri_init.c.bak deleted file mode 100755 index d0b58dc12..000000000 --- a/code/sdk/application/brandy/brandy_standard/thread_pri_init.c.bak +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) CompanyNameMagicTag 2021-2022. All rights reserved. - * Description: Application Core OS Priority Initialize Interface for Standard - * Author: - * Create: 2022-12-03 - */ -#include "debug_print.h" -#include "thread_init.h" -#include "common_def.h" -#include "pm.h" -#include "watchdog.h" -#ifdef CFG_DRIVERS_MMC -#ifdef __LITEOS__ -#include "soc/mmc.h" -#endif -#include "soc_mmc.h" -#endif -#include "soc_lcd_api.h" -#ifdef CFG_DRIVERS_NANDFLASH -#include "nandflash_config.h" -#endif -#if defined(TPTYPE_TMA525B) -#include "tma525b_drv1.h" -#elif defined(TPTYPE_ZTW523) -#include "ztw523_touch1.h" -#else -#include "ztw523_touch1.h" -#endif -#include "thread_pri_init.h" -#if DSP_EXIST == YES -#include "soc_uapi_audio_sys.h" -#include "soc_uapi_vendor.h" -#include "soc_uapi_sound.h" -/* Audio codec vendor select according to hardware connection: - * define AUDIO_SMARTPA_AW88166 : macro to init smartpa aw88166; - * define AUDIO_SMARTPA_AW88166_I2S_ID UAPI_SND_OUT_PORT_I2S0 : macro to specify i2s id connecting to smartpa aw88166; - */ -#define AUDIO_SMARTPA_AW88262 -#define AUDIO_SMARTPA_AW88262_I2S_ID UAPI_SND_OUT_PORT_I2S2 - -#endif /* DSP_EXIST */ -#include "panic.h" -#include "board_init.h" -#include "kernel_init.h" -#ifdef SUPPORT_AT_OHOSFWK -#include "ohosfwk_startup.h" -#endif - -#define EMMC_BASE_ADDR 0x52062000 -#define TASK_PRIORITY_APP (osPriority_t)(17) -#define TICK_TEN_MS (10U) - -static void thread_main(const void *unused); -void bt_acore_btc_ipc_receive_init(void); - -app_task_definition_t g_thread_pri = { { "thread_pri", 0, NULL, 0, NULL, (0x1000), TASK_PRIORITY_APP, 0, 0 }, - (osThreadFunc_t)thread_main, NULL, NULL, USE_DTCM_MEM }; -store_class g_store_init_select = STORE_CLASS_NAND; - -#if defined(ENABLE_UIKIT) || defined(ENABLE_LVGL) -static void sample_gfx_init(void) -{ -#if defined(TPTYPE_TMA525B) - tma525b_host_init_sample(); -#elif defined(TPTYPE_ZTW523) - ztw523_host_init_sample(); -#else - ztw523_host_init_sample(); -#endif - uapi_lcd_init(); -#ifdef SUPPORT_GPU_GMMU - drv_gmmu_module_init(); -#endif - uapi_vau_module_init(); - uapi_dpu_module_init(); -#ifdef SUPPORT_GPU_JPEG - uapi_jpeg_module_init(); -#endif -} -#endif - -#ifdef CFG_DRIVERS_MMC -static void emmc_init(void) -{ - /** - * FPGA解复位, 设置CMD_CONFLICT_CHECK - * 之后才能设置管脚 - */ - writew(EMMC_BASE_ADDR + 0x508, 0); - init_emmc_pinmux(); - int ret = emmc_drv_context_init(); - if (ret != ENOERR) { - PRINT("emmc init error:[%d]"NEWLINE, ret); - } - mmc_set_first_init_flag(true); - mmc_set_sleep_init_flag(true); - PRINT("emmc init success\r\n"); -} -#endif - -#ifdef CFG_DRIVERS_NANDFLASH -static void nandflash_init(void) -{ - int32_t ret = 0; - ret = nandflash_filesystem_init(); - if (ret != 0) { - PRINT("nandflash init error[%d]"NEWLINE, ret); - } - PRINT("nandflash init success\r\n"); -} -#endif - -static void board_version_class_print(void) -{ - PRINT("**********startup info**********\r\n"); - PRINT("os init class is %s."NEWLINE, (g_os_init_select == OS_CLASS_LITEOS) ? "liteos" : "freertos"); - PRINT("store init class is %s."NEWLINE, (g_store_init_select == STORE_CLASS_NAND) ? "nandflash" : "emmc"); - PRINT("display init class is %s."NEWLINE, (g_display_init_select == DISPLAY_CLASS_QSPI) ? "QSPI" : "MIPI"); - PRINT("board init class is %s."NEWLINE, (g_board_init_select == BOARD_CLASS_E0B2) ? "E0B2" : "E0B4"); - PRINT("psram density is %s."NEWLINE, (get_psram_density() == PSRAM_DENSITY_16M) ? "16MB" : "32MB"); - PRINT("**********startup info**********\r\n"); -} - -#if DSP_EXIST == YES -/** - * The sample code of the vendor, - * which will be implemented by the customer in the future - */ -#ifdef AUDIO_SMARTPA_AW88262 -td_s32 audio_aw88262_init(const uapi_vendor_codec_attr *attr); -td_s32 audio_aw88262_deinit(td_void); - -static uapi_vendor_driver g_aw88262_driver = { - .out_port = AUDIO_SMARTPA_AW88262_I2S_ID, - .init = audio_aw88262_init, - .deinit = audio_aw88262_deinit, - .set_aef_profile = TD_NULL, -}; - -static td_s32 audio_aw88262_register_driver(void) -{ - return uapi_audio_vendor_register(&g_aw88262_driver); -} -#endif /* AUDIO_SMARTPA_AW88262 */ - -#ifdef AUDIO_SMARTPA_AW88166 -td_s32 audio_aw88166_init(const uapi_vendor_codec_attr *attr); -td_s32 audio_aw88166_deinit(td_void); /* Call when device power off */ -td_s32 audio_aw88166_start(const uapi_vendor_codec_attr *attr); -td_s32 audio_aw88166_stop(td_void); -td_s32 audio_aw88166_set_aef_profile(uapi_snd_aef_profile aef_profile); - -static uapi_vendor_driver g_aw88166_driver = { - .out_port = AUDIO_SMARTPA_AW88166_I2S_ID, - .init = audio_aw88166_start, - .deinit = audio_aw88166_stop, - .set_aef_profile = audio_aw88166_set_aef_profile, -}; - -static td_s32 audio_aw88166_register_driver(void) -{ - const uapi_vendor_codec_attr attr = {}; - - audio_aw88166_init(&attr); /* Init aw88166 once when device power on */ - - return uapi_audio_vendor_register(&g_aw88166_driver); -} -#endif /* AUDIO_SMARTPA_AW88166 */ - -static void audio_smartpa_init(void) -{ - uint32_t ret; - -#ifdef AUDIO_SMARTPA_AW88262 - ret = (uint32_t)audio_aw88262_register_driver(); - if (ret != 0) { - PRINT("aw88262 register driver error\r\n"); - } -#endif /* AUDIO_SMARTPA_AW88262 */ - -#ifdef AUDIO_SMARTPA_AW88166 - ret = (uint32_t)audio_aw88166_register_driver(); - if (ret != 0) { - PRINT("aw88166 register driver error\r\n"); - } -#endif /* AUDIO_SMARTPA_AW88166 */ -} -#endif /* DSP_EXIST */ - -#if DSP_EXIST == YES -static void audio_init() -{ - (void)osDelay(TICK_TEN_MS); - uapi_watchdog_kick(); - - audio_smartpa_init(); - - uint32_t ret = (uint32_t)uapi_audio_init(); - if (ret != 0) { - PRINT("audio init error:[%d]\r\n", ret); - } else { - PRINT("audio init OK\r\n"); - } -} -#endif - -static void thread_main(const void *unused) -{ - PRINT("thread_main start "NEWLINE); - unused(unused); - bt_acore_btc_ipc_receive_init(); - uapi_pm_control(PM_BT_POWER_UP_AND_RUN); - los_vfs_init(); - uint32_t ret = dpal_driver_base_init(); - if (ret != 0) { - PRINT("dpal driver base init error"NEWLINE); - panic(PANIC_ASSERT, __LINE__); - } -#ifdef CFG_DRIVERS_MMC - emmc_init(); - g_store_init_select = STORE_CLASS_EMMC; - sdiom_internal_freq_handler_register(mmc_set_internal_clk); -#endif -#ifdef CFG_DRIVERS_NANDFLASH - nandflash_init(); - g_store_init_select = STORE_CLASS_NAND; -#endif - uapi_pm_control(PM_DISPLAY_POWER_UP_AND_RUN); - (void)osDelay(TICK_TEN_MS); - -#if defined(ENABLE_UIKIT) || defined(ENABLE_LVGL) - sample_gfx_init(); -#else - uapi_pm_control(PM_DISPLAY_POWER_OFF); -#endif - -#if DSP_EXIST == YES - audio_init(); -#endif - board_version_class_print(); - uapi_watchdog_kick(); - thread_init(); - button_app_init(); - uapi_calendar_init(); -#ifdef SUPPORT_AT_OHOSFWK - ohos_startup(); -#endif - uapi_pm_remove_sleep_veto(PM_ID_DEBUG); - set_startup_finish_flag(); -} - -void thread_pri_init(void) -{ - /* Create tasks */ - g_thread_pri.task_handle = osThreadNew(g_thread_pri.func, NULL, &(g_thread_pri.attr)); - if (g_thread_pri.task_handle == NULL) { - PRINT("create thread pri failed!"); - } -} diff --git a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp index 1675aa814..da7921d5a 100755 --- a/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp +++ b/code/sdk/application/wearable/nativeapp/nativeui/compass/src/CompassModel.cpp @@ -12,6 +12,8 @@ #ifdef __cplusplus extern "C" { #endif +#include "mag_service.h" + using namespace OHOS; @@ -28,20 +30,21 @@ CompassModel *CompassModel::GetInstance(void) void CompassModel::SetCalibrationStatus(uint8_t status) { + calibrationStatus = status; } uint8_t CompassModel::GetCalibrationStatus(void) { - return 0; + if( mag_service_get_iAccuracy() < 3) + return 1; + else + return 0; } void CompassModel::SetDisplayAngle(uint16_t angle) { - displayAngle += angle; - if (displayAngle > 359) { - displayAngle = 0; - } + displayAngle = (int16_t)mag_service_get_fAzimuth(); } uint16_t CompassModel::GetDisplayAngle(void) @@ -68,11 +71,14 @@ time_t CompassModel::GetCurrentTime(void) bool CompassModel::OpenCompassSensor(void) { + + do_mag_service_check_msg(MAG_SERVICE_CMD_START_CHECK); return true; } bool CompassModel::CloseCompassSensor(void) { + do_mag_service_check_msg(MAG_SERVICE_CMD_STOP_CHECK); return true; } } diff --git a/code/sdk/build/config/target_config/brandy/config.py b/code/sdk/build/config/target_config/brandy/config.py index 868d40a07..8fc0ccccd 100755 --- a/code/sdk/build/config/target_config/brandy/config.py +++ b/code/sdk/build/config/target_config/brandy/config.py @@ -115,7 +115,11 @@ target = { 'SW_UART_DEBUG', 'SAVE_EXC_INFO', 'HASH_MEM_COPY', 'JS_ENABLE', 'CONFIG_LOW_POWER_TEST', 'ENABLE_ECC', - 'FT_SINGLE_UART', + 'FT_SINGLE_UART', + 'PPG_HX3695', + 'ACC_LIS2DOC', + 'MAG_MMC5603', + # 'ENABLE_SLIP', #'CONFIG_ADC_SUPPORT_AUTO_SCAN','CONFIG_ADC_SUPPORT_LONG_SAMPLE', 'MIPI_ULPS_SUPPORT', 'TPTYPE_FT6X46'], 'ram_component': ["algorithm", "dfx_port_brandy", "dfx_update", 'dfx_nv', "osal", "arch_port", "-:testsuite", @@ -123,8 +127,24 @@ target = { 'psram', 'hal_mipi', 'mipi_tx', 'non_os', 'touch', 'ulp_aon', 'hal_l2ram', 'x_dpal', 'x_vfs', 'x_disk', 'x_fat', 'drv_mmc', 'fs_yaffs2', 'x_vfs_private', - 'pm_service', 'pm_brandy', 'cmn_header', 'at_cmd', 'graphic_at_service', 'app_at_service', 'ohosfwk_at_service', - "audio_proc", "audio_dump", "audio_probe", "power_manager", "gpu_proc","batterry_service"], + 'pm_service', 'pm_brandy', 'cmn_header', + 'at_cmd', + # 'graphic_at_service', + 'app_at_service', + 'ohosfwk_at_service', + 'audio_at_service', + 'media_at_service', + # 'bt_manager_at_service', + "audio_proc", "audio_dump", "audio_probe", "power_manager", "gpu_proc", + "ppg_sensor", + "acc_sensor", + "mag_sensor", + "vibrator", + # "lwIP", + "audio_manager", + "custom_utils", + "rotary_encoder", + "batterry_service"], 'ram_component_set': ['bgh', 'media', 'gpu', 'graphic_uikit', 'bgh_audio', 'dfx_set', 'ohos_set', 'wearable_set', 'alipay_set'], 'dsp_version': 'max', 'packet': True, @@ -142,14 +162,28 @@ target = { 'SW_UART_DEBUG', 'SAVE_EXC_INFO', 'HASH_MEM_COPY', 'JS_ENABLE', 'CONFIG_LOW_POWER_TEST', 'FT_SINGLE_UART', + 'PPG_HX3695', + 'ACC_LIS2DOC', + 'MAG_MMC5603', 'ENABLE_ECC', 'XTS_SUPPORT', 'TPTYPE_FT6X46'], 'ram_component': ["algorithm", "dfx_port_brandy", "dfx_update", 'dfx_nv', "osal", "arch_port", "-:testsuite", "liteos_port", 'lcd', 'qspi_display', 'psram', 'hal_mipi', 'mipi_tx', 'non_os', 'touch', 'ulp_aon', 'hal_l2ram', 'x_dpal', 'x_vfs', 'x_disk', 'x_fat', 'drv_mmc', 'fs_yaffs2', 'x_vfs_private', - 'pm_service', 'pm_brandy', 'cmn_header', 'at_cmd', 'graphic_at_service', 'app_at_service', 'ohosfwk_at_service', - "audio_proc", "audio_dump", "audio_probe", "power_manager", "gpu_proc","batterry_service"], + 'pm_service', 'pm_brandy', 'cmn_header', 'at_cmd', + 'graphic_at_service', + 'app_at_service', + 'ohosfwk_at_service', + "audio_proc", "audio_dump", "audio_probe", "power_manager", "gpu_proc", + "ppg_sensor", + "acc_sensor", + "mag_sensor", + "vibrator", + "audio_manager", + "custom_utils", + "rotary_encoder", + "batterry_service"], 'ram_component_set': ['bgh', 'media', 'gpu', 'graphic_uikit', 'bgh_audio', 'dfx_set', 'ohos_set', 'wearable_set', 'xts_set', 'xts_test_set', 'alipay_set'], 'dsp_version': 'max', 'packet': True, diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.moji.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.moji.bin deleted file mode 100644 index 48141c7e1..000000000 Binary files a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.moji.bin and /dev/null differ diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.navigate.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.navigate.bin deleted file mode 100644 index c298b15b8..000000000 Binary files a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.navigate.bin and /dev/null differ diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.tingshu.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.tingshu.bin deleted file mode 100644 index 2b9ebbcf0..000000000 Binary files a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/cn.tingshu.bin and /dev/null differ diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/com.vendor.voiceassistant.bin b/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/com.vendor.voiceassistant.bin deleted file mode 100644 index 4c628753f..000000000 Binary files a/code/sdk/build/config/target_config/brandy/mk_fs_image/fs/user/js/com.vendor.voiceassistant.bin and /dev/null differ diff --git a/code/sdk/drivers/CMakeLists.txt b/code/sdk/drivers/CMakeLists.txt index bf356eba1..73b930185 100755 --- a/code/sdk/drivers/CMakeLists.txt +++ b/code/sdk/drivers/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory_if_exist(drivers) add_subdirectory_if_exist(boards) add_subdirectory_if_exist(chips) -add_subdirectory_if_exist(adapter) \ No newline at end of file +add_subdirectory_if_exist(adapter) +add_subdirectory_if_exist(peripheral) diff --git a/code/sdk/drivers/boards/brandy_evb/board_config/board_evb.h b/code/sdk/drivers/boards/brandy_evb/board_config/board_evb.h index 2e28e1ae4..c67ea8f43 100755 --- a/code/sdk/drivers/boards/brandy_evb/board_config/board_evb.h +++ b/code/sdk/drivers/boards/brandy_evb/board_config/board_evb.h @@ -150,18 +150,18 @@ const hal_pio_config_t g_pio_function_config[PIN_MAX_NUMBER] = { { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L9 dsp uart TP35 { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L10 dsp uart TP36 #endif - { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L11 a+g int1 + { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L11 G_INT1 { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L12 i2c data HX3507_SDIO - { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L13 i2c CLK HX3507_SCLK + { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L13 i2c CLK HX3507_SCLK { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L14 NC { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L15 NC { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L16 NC { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L17 HX3507_INT - { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L18 VDDEN //暂时无用,采用VDDIO 默认开启 EXt V3.0 EXt V1.8 - { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L19 a+g int1 + { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L18 VDDEN //暂时无用,采用VDDIO 默认开启 EXt V3.0 EXt V1.8 + { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_L19 G_INT2 { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L20 0.2C_CHRG { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_L21 NTC_VDD_ON 给低打开 NTC上拉电源 @@ -183,7 +183,12 @@ const hal_pio_config_t g_pio_function_config[PIN_MAX_NUMBER] = { { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_R0 PRG_LED_POWER ON 心率等电源控制脚 { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_R1 SE_REST 安全芯片复位唤醒脚 - { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚 + #if VIB_USE_PWM + // { HAL_PIO_FUNC_PWMP1_M2, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_NONE, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚 + // { HAL_PIO_FUNC_PWMN1_M3, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_NONE, HAL_PIO_IE_DISABLE }, // S_AGPIO_R2 VIBR_PWM 马达控制脚 兼容预留马达驱动复位脚 + #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_MAX, 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 @@ -241,17 +246,36 @@ const hal_gpio_config_t g_gpio_function_config[PIN_MAX_NUMBER] = { // S_AGPIO_L28 Cat1 reset ---- low reset { S_AGPIO_L28, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, #endif - // // S_AGPIO_L17 HX3507_INT - // { S_AGPIO_L17, HAL_GPIO_DIRECTION_INPUT, NULL, 0, NULL }, - // // S_AGPIO_L12 SDIO_BT - // { S_AGPIO_L12, HAL_GPIO_DIRECTION_INPUT, NULL, 0, NULL }, - // // S_AGPIO_L13 SCLK_BT - // { S_AGPIO_L13, HAL_GPIO_DIRECTION_INPUT, NULL, 0, NULL }, + // S_AGPIO_L17 HX3507_INT + { S_AGPIO_L17, HAL_GPIO_DIRECTION_INPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + // S_AGPIO_L12 SDIO_BT + { S_AGPIO_L12, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + // S_AGPIO_L13 SCLK_BT + { S_AGPIO_L13, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + + // S_AGPIO_L26 心率复位 PPG reset + { S_AGPIO_L26, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + // S_AGPIO_R0 PRG_LED_POWER ON 心率等电源控制脚 + { S_AGPIO_R0, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + //S_AGPIO_L21 NTC_VDD_ON 给低打开 NTC上拉电源 - { S_AGPIO_L21, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + { S_AGPIO_L21, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + +// #define GPIO_PIN_ENABLE_CHARGE S_AGPIO_R9 +// #define GPIO_PIN_ENABLE_CHARGE_0_2C S_AGPIO_L20 //低电流充电 + { S_AGPIO_R9, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, + { S_AGPIO_L20, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, +//默认关闭马达 + { S_AGPIO_R2, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, +//默认开启 EXT LDO V3.0 V1.8 + { S_AGPIO_L18, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, + + + /**G sensor G_INT1 S_AGPIO_L11 G_INT2 S_AGPIO_L19*/ + { S_AGPIO_L11, HAL_GPIO_DIRECTION_INPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, + { S_AGPIO_L19, HAL_GPIO_DIRECTION_INPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, - }; /** * @} diff --git a/code/sdk/drivers/boards/brandy_evb/product/product.h b/code/sdk/drivers/boards/brandy_evb/product/product.h index eeabd6293..ddddd2aa8 100755 --- a/code/sdk/drivers/boards/brandy_evb/product/product.h +++ b/code/sdk/drivers/boards/brandy_evb/product/product.h @@ -72,5 +72,5 @@ #define EMMC_SD_BUSWIDTH MMCSD_BUSWIDTH_8 #define PARTITION_EXIST YES #define ALIPAY_SEC_I2C_INDEX I2C_BUS_3 -#define ALIPAY_SEC_GPIO S_AGPIO_L29 +#define ALIPAY_SEC_GPIO S_AGPIO_R1 #endif diff --git a/code/sdk/drivers/boards/brandy_evb/product/product_evb4_standard.h b/code/sdk/drivers/boards/brandy_evb/product/product_evb4_standard.h index 4b44e60c7..0c8f915fa 100755 --- a/code/sdk/drivers/boards/brandy_evb/product/product_evb4_standard.h +++ b/code/sdk/drivers/boards/brandy_evb/product/product_evb4_standard.h @@ -159,32 +159,32 @@ // 音频外挂输入设备 #define EXTERNAL_AI_PORT 1 // 参考 soc_uapi_ai.h 中 UAPI_AI_PORT_I2S1 枚举 -#define EXTERNAL_AI_I2S_ATTR_MASTER 1 // 1:主设备,0:从设备 -#define EXTERNAL_AI_I2S_ATTR_I2S_MODE 0 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_STD_MODE 枚举 -#define EXTERNAL_AI_I2S_ATTR_MCLK 4 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_768_FS 枚举 -#define EXTERNAL_AI_I2S_ATTR_BCLK 24 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_24_DIV 枚举 +#define EXTERNAL_AI_I2S_ATTR_MASTER 0 // 1:主设备,0:从设备 +#define EXTERNAL_AI_I2S_ATTR_I2S_MODE 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_PCM_MODE 枚举 +#define EXTERNAL_AI_I2S_ATTR_MCLK 6 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_1536_FS 枚举 +#define EXTERNAL_AI_I2S_ATTR_BCLK 48 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_48_DIV 枚举 #define EXTERNAL_AI_I2S_ATTR_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举 #define EXTERNAL_AI_I2S_ATTR_AUDIO_CH 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举 #define EXTERNAL_AI_I2S_ATTR_SAMPLE_RISE_EDGE 1 // 参考 soc_uapi_audio.h 中 pcm_sample_rise_edge 成员 #define EXTERNAL_AI_I2S_ATTR_PCM_DELAY_CYCLE 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_PCM_1_DELAY 枚举 -#define EXTERNAL_AI_PCM_ATTR_CHANNELS 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举 +#define EXTERNAL_AI_PCM_ATTR_CHANNELS 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举 #define EXTERNAL_AI_PCM_ATTR_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举 -#define EXTERNAL_AI_PCM_ATTR_SAMPLE_RATE 16000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举 -#define EXTERNAL_AI_PCM_ATTR_FRAME_PER_SEC 100 // 每秒帧数 +#define EXTERNAL_AI_PCM_ATTR_SAMPLE_RATE 8000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举 +#define EXTERNAL_AI_PCM_ATTR_FRAME_PER_SEC 50 // 每秒帧数 , EG810 pcm 20ms 一帧 // 音频外挂输出设备 #define EXTERNAL_SND_OUT_PORT 0x11 // 参考 soc_uapi_sound.h 中 UAPI_SND_OUT_PORT_I2S1 枚举 -#define EXTERNAL_SND_OUT_AUDIO_CHANNEL 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举 +#define EXTERNAL_SND_OUT_AUDIO_CHANNEL 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举 #define EXTERNAL_SND_OUT_AUDIO_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举 -#define EXTERNAL_SND_OUT_AUDIO_SAMPLE_RATE 16000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举 +#define EXTERNAL_SND_OUT_AUDIO_SAMPLE_RATE 8000 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_SAMPLE_RATE_16K 枚举 #define EXTERNAL_SND_OUT_PORT_NUM 1 // 端口个数 #define EXTERNAL_SND_OUT_I2S_ATTR_BIT_DEPTH 16 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_BIT_DEPTH_16 枚举 #define EXTERNAL_SND_OUT_I2S_ATTR_CHANNEL 2 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_CHANNEL_2 枚举 -#define EXTERNAL_SND_OUT_I2S_ATTR_I2S_MODE 0 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_STD_MODE 枚举 -#define EXTERNAL_SND_OUT_I2S_ATTR_MCLK 4 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_768_FS 枚举 -#define EXTERNAL_SND_OUT_I2S_ATTR_MASTER 1 // 1:主设备,0:从设备 +#define EXTERNAL_SND_OUT_I2S_ATTR_I2S_MODE 1 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_PCM_MODE 枚举 +#define EXTERNAL_SND_OUT_I2S_ATTR_MCLK 6 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_MCLK_1536_FS 枚举 12.288M /16k = +#define EXTERNAL_SND_OUT_I2S_ATTR_MASTER 0 // 1:主设备,0:从设备 #define EXTERNAL_SND_OUT_I2S_ATTR_SAMPLE_RISE_EDGE 1 // 参考 soc_uapi_audio.h 中 pcm_sample_rise_edge 成员 -#define EXTERNAL_SND_OUT_I2S_ATTR_BCLK 24 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_24_DIV 枚举 +#define EXTERNAL_SND_OUT_I2S_ATTR_BCLK 48 // 参考 soc_uapi_audio.h 中 UAPI_AUDIO_I2S_BCLK_48_DIV 枚举 12.288M / 256k = 48 // Sleep option #define CONFIG_PM_TICKLESS_EN YES @@ -198,6 +198,7 @@ // LCD VCI_EN #define VCI_LCD_GPIO S_AGPIO_L24 +//#define VCI_LCD_GPIO S_AGPIO_L6 /** * @} */ diff --git a/code/sdk/drivers/chips/brandy/clocks/drivers/acore/clocks_config_priv.c b/code/sdk/drivers/chips/brandy/clocks/drivers/acore/clocks_config_priv.c index 99b1a1b8f..861e30cf7 100755 --- a/code/sdk/drivers/chips/brandy/clocks/drivers/acore/clocks_config_priv.c +++ b/code/sdk/drivers/chips/brandy/clocks/drivers/acore/clocks_config_priv.c @@ -371,7 +371,7 @@ static const system_mcu_perip_clk_t g_system_mcu_perp_clk_set_config[] = { {HAL_CLOCKS_APP_UART_H1_CLK, TURN_ON}, // uart h1 clock {HAL_CLOCKS_APP_I2C0_CLK, TURN_OFF}, // i2c0 clock {HAL_CLOCKS_APP_I2C1_CLK, TURN_ON}, // i2c1 clock - {HAL_CLOCKS_APP_I2C2_CLK, TURN_OFF}, // i2c2 clock + {HAL_CLOCKS_APP_I2C2_CLK, TURN_ON}, // i2c2 clock {HAL_CLOCKS_APP_I2C3_CLK, TURN_ON}, // i2c3 clock {HAL_CLOCKS_APP_QSPI_1CS_CLK, TURN_ON}, // qspi clock {HAL_CLOCKS_APP_XIP_BUS_CLK, TURN_ON}, // xip bus clock diff --git a/code/sdk/drivers/chips/brandy/porting/uart/uart_porting.c b/code/sdk/drivers/chips/brandy/porting/uart/uart_porting.c index a97d70d3e..113d914be 100755 --- a/code/sdk/drivers/chips/brandy/porting/uart/uart_porting.c +++ b/code/sdk/drivers/chips/brandy/porting/uart/uart_porting.c @@ -298,7 +298,9 @@ void irq_uart1_handler(void) static void at_cmd_uart_rx_callback(const void *buf, uint16_t buf_len, bool remaining) { unused(remaining); + #ifndef FT_SINGLE_UART at_cmd_msg_receive_handler((uint8_t *)buf, buf_len); + #endif hal_uart_clear_pending(SW_DEBUG_UART_BUS); } #endif diff --git a/code/sdk/drivers/drivers/driver/i2c/i2c.c b/code/sdk/drivers/drivers/driver/i2c/i2c.c index 002dc1778..30701aff6 100755 --- a/code/sdk/drivers/drivers/driver/i2c/i2c.c +++ b/code/sdk/drivers/drivers/driver/i2c/i2c.c @@ -904,7 +904,7 @@ static void i2c_writeread_mutex_unlock(i2c_bus_t bus) } #if defined(CONFIG_I2C_SUPPORT_MASTER) && (CONFIG_I2C_SUPPORT_MASTER == 1) -static errcode_t i2c_master_init_check(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode) +errcode_t i2c_master_init_check(i2c_bus_t bus, uint32_t baudrate, uint8_t hscode) { if (unlikely(bus >= I2C_BUS_MAX_NUM)) { return ERRCODE_I2C_INVALID_PARAMETER; diff --git a/code/sdk/drivers/drivers/driver/rtc_unified/rtc.c b/code/sdk/drivers/drivers/driver/rtc_unified/rtc.c index 6cc3253d2..e711265fd 100755 --- a/code/sdk/drivers/drivers/driver/rtc_unified/rtc.c +++ b/code/sdk/drivers/drivers/driver/rtc_unified/rtc.c @@ -102,14 +102,14 @@ hal_rtc_funcs_t *g_hal_rtc_func[CONFIG_RTC_MAX_NUM]; rtcs_manager_t g_rtcs_manager[CONFIG_RTC_MAX_NUM] = { 0 }; -/* ¼ÆËã¶ÔÆëºóµÄcycleºÍÆ«²îÖµ */ +/* 计算对齐后的cycle和偏差值 */ STATIC uint64_t rtc_get_cycle_with_mask(rtc_index_t index, uint64_t cycle, int32_t *cycle_deviation) { #if defined(CONFIG_RTC_USING_OLD_VERSION) - /* ÄÚ²¿º¯Êý, ²»½øÐпÕÖ¸Õë¼ì²é */ + /* 内部函数, 不进行空指针检查 */ int32_t rtc_load_cycle_deviation = g_rtcs_manager[index].rtc_load_cycle_deviation; - /* cycleֵСÓÚµÈÓÚ0xF, »òµ±Ç°ÀÛ»ýÆ«²îÖµ²»µ½0xFʱ, cycleÏòÉÏ¶ÔÆëµ½0xF */ + /* cycle值小于等于0xF, 或当前累积偏差值不到0xF时, cycle向上对齐到0xF */ if (cycle <= RTC_OLD_VERSION_LOAD_COUNT_MASK || rtc_load_cycle_deviation <= (int32_t)RTC_OLD_VERSION_LOAD_COUNT_MASK) { *cycle_deviation = @@ -117,7 +117,7 @@ STATIC uint64_t rtc_get_cycle_with_mask(rtc_index_t index, uint64_t cycle, int32 return (cycle | RTC_OLD_VERSION_LOAD_COUNT_MASK); } - /* µ±Ç°ÀÛ»ýÆ«²îÖµ³¬¹ý0xFʱ, cycleÏòÏÂ¶ÔÆëµ½(0xF - 0x10) */ + /* 当前累积偏差值超过0xF时, cycle向下对齐到(0xF - 0x10) */ *cycle_deviation = -1 - (int32_t)(cycle & RTC_OLD_VERSION_LOAD_COUNT_MASK); return (cycle | RTC_OLD_VERSION_LOAD_COUNT_MASK) - (RTC_OLD_VERSION_LOAD_COUNT_MASK + 1); #else @@ -127,7 +127,7 @@ STATIC uint64_t rtc_get_cycle_with_mask(rtc_index_t index, uint64_t cycle, int32 #endif } -/* load¶ÔÆëºóµÄcycleºÍÆ«²îÖµ */ +/* load对齐后的cycle和偏差值 */ STATIC void rtc_load_cycle_with_mask(rtc_index_t index, uint64_t cycle_with_mask, int32_t cycle_deviation) { #if defined(CONFIG_RTC_USING_OLD_VERSION) @@ -525,7 +525,7 @@ errcode_t uapi_rtc_stop(rtc_handle_t rtc) rtc_info->callback = NULL; rtc_info->data = 0; - /* ¼ì²éµ±Ç°ÊÇ·ñ»¹ÓÐÔÚÔËÐеĶ¨Ê±Æ÷, ÈôûÓж¨Ê±Æ÷ÔòÍ£Ö¹Ó²¼þ¼ÆÊ± */ + /* 检查当前是否还有在运行的定时器, 若没有定时器则停止硬件计时 */ rtc_index_t index = rtc_info->index; uint32_t rtc_found = rtc_get_next_rtc(index); if (rtc_found >= g_rtcs_manager[index].soft_rtc_num) { diff --git a/code/sdk/drivers/drivers/driver/touch/CMakeLists.txt.bak b/code/sdk/drivers/drivers/driver/touch/CMakeLists.txt.bak deleted file mode 100755 index 6782d9cc1..000000000 --- a/code/sdk/drivers/drivers/driver/touch/CMakeLists.txt.bak +++ /dev/null @@ -1,80 +0,0 @@ -#=============================================================================== -# @brief cmake file -# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. -#=============================================================================== -set(COMPONENT_NAME "touch") - -set(SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/touch_screen_drv.c - ${CMAKE_CURRENT_SOURCE_DIR}/touch_screen_queue1.c -) - -if("TPTYPE_TMA525B" IN_LIST DEFINES) -set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_SOURCE_DIR}/tma525b_touch/tma525b_ctrl.c - ${CMAKE_CURRENT_SOURCE_DIR}/tma525b_touch/tma525b_drv1.c - ${CMAKE_CURRENT_SOURCE_DIR}/tma525b_touch/tma525b_touch1.c -) -elseif("TPTYPE_ZTW523" IN_LIST DEFINES) -set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_ctrl.c - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_drv1.c - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_touch1.c -) -else() -set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_ctrl.c - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_drv1.c - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_touch1.c -) -endif() - -if("TPTYPE_TMA525B" IN_LIST DEFINES) -set(PUBLIC_HEADER - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/tma525b_touch - ${ROOT_DIR}/middleware/services/gui/hal/input/include -) -elseif("TPTYPE_ZTW523" IN_LIST DEFINES) -set(PUBLIC_HEADER - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch - ${ROOT_DIR}/middleware/services/gui/hal/input/include -) -else() -set(PUBLIC_HEADER - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch - ${ROOT_DIR}/middleware/services/gui/hal/input/include -) -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 - -Wno-incompatible-function-pointer-types - -Wno-unused-function -) - -set(WHOLE_LINK - true -) - -set(MAIN_COMPONENT - false -) - -build_component() - -install_sdk(${CMAKE_CURRENT_SOURCE_DIR} "*") diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.h.bak b/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.h.bak deleted file mode 100755 index 2e66c5931..000000000 --- a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.h.bak +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) @CompanyNameMagicTag 2021-2022. All rights reserved. - * Description: ztw523 touch driver. - * Author: @CompanyNameTag - * Create: 2022-04-12 - */ - -#ifndef FT6X46_CTRL_H -#define FT6X46_CTRL_H - -#include "stdio.h" -#include "debug_print.h" -#include "stdint.h" -#include "td_base.h" -#include "platform_core.h" -#include "ft6x46_touch1.h" - -/* host peripheral definitions */ -#if 0//CHIP_ASIC -#define ZTW523_I2C_BUS I2C_BUS_1 -#define ZTW523_INT_GPIO S_AGPIO5 -#define ZTW523_RESET_GPIO S_AGPIO4 -#else -#define ZTW523_I2C_BUS I2C_BUS_5 -#define ZTW523_INT_GPIO S_MGPIO11 -#define ZTW523_RST_REG 0x5600201c -#define ZTW523_RST_HIGH 3 -#define ZTW523_RST_LOW 0 -#endif - -#define ZTW523_I2C_ADDR 0x20 -#define FT6X46_I2C_ADDR 0x38 -#define ZTW523_I2C_SPEED I2C_SPEED_MODE_SS -#define ZTW523_REG_BYTE_LEN 2 -#define OFFSET_8_BITS 8 -#define ZTW523_REG_WRITE_LEN 4 - -#define ZTW523_CMD_SEND_LEN 2 -#define FT6X46_CMD_SEND_LEN 1 - -#define ZTW523_REG_DATA_LEN 2 -#define ZTW523_I2C_TIME_MAX 3 - -#define ZTW523_I2C_SEND_INDEX0 0 -#define ZTW523_I2C_SEND_INDEX1 1 -#define ZTW523_I2C_SEND_INDEX2 2 -#define ZTW523_I2C_SEND_INDEX3 3 -typedef struct { - uint32_t int_gpio; - i2c_bus_t i2c_id; - uint32_t i2c_speed; -} ztw523_ctrl_attr; - -typedef ext_errno (*ztw523_bus_init)(ztw523_ctrl_attr *attr); - -typedef struct { - ztw523_ctrl_attr attr; - ztw523_bus_init bus_init; -} ztw523_ctrl_ops; - -ext_errno ztw523_host_peripheral_init(ztw523_ctrl_attr *attr); -ext_errno ztw523_register_handle(const ztw523_ctrl_ops *peri_data, touch_callback func); -ext_errno ztw523_unregister_handle(const ztw523_ctrl_ops *peri_data); -ext_errno ztw523_reset(void); -void ztw523_resume_reset(void); -void ztw523_delay(uint32_t ms); - -ext_errno tp_i2c_data_read(uint16_t reg_addr, uint8_t *data_buf, uint32_t data_len); -ext_errno tp_i2c_cmd_write(uint16_t cmd); -ext_errno tp_i2c_reg_write(uint16_t reg_addr, uint16_t reg_cfg); -ext_errno tp_i2c_data_write(uint16_t reg_addr, uint8_t *data_buf, uint32_t data_len); - - -ext_errno tp_ft6x46_i2c_data_read(uint8_t reg_addr, uint8_t *data_buf, uint32_t data_len); -ext_errno tp_ft6x46_i2c_data_write(uint8_t reg_addr, uint8_t *data_buf, uint16_t data_len); -ext_errno tp_ft6x46_i2c_data_write_reg(uint8_t addr, uint8_t val); - -#endif diff --git a/code/sdk/drivers/drivers/driver/touch/touch_screen_drv.c.bak b/code/sdk/drivers/drivers/driver/touch/touch_screen_drv.c.bak deleted file mode 100755 index c98e7c30e..000000000 --- a/code/sdk/drivers/drivers/driver/touch/touch_screen_drv.c.bak +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (c) @CompanyNameMagicTag 2021-2021. All rights reserved. - * Description: touch screen driver. - * Author: @CompanyNameTag - * Create: 2022-04-12 - */ - -#include "touch_screen_drv.h" -#include "tcxo.h" -#include "common_def.h" -#include "soc_osal.h" -#include "touch_screen_def.h" -#include "input_app.h" -#if defined(TPTYPE_TMA525B) -#include "tma525b_drv1.h" -#elif defined(TPTYPE_ZTW523) -#include "ztw523_drv1.h" -#else -#include "ztw523_drv1.h" -#endif - -#define TOUCH_SCREEN_DEV_NAME_LEN 16 -#define TOUCH_SCREEN_DEVNAME "input/event" -#define TOUCH_SCREEN_DYNAMIC_MINOR 65 -#define TOUCH_SCREEN_CMDID_MAX 16 - -#define TOUCH_SCREEN_TASK_PRIO 5 -#define TOUCH_SCREEN_TASK_SIZE 0x800 -#define TOUCH_SCREEN_QUEUE_MAX_SIZE 60 -#define TOUCH_SCREEN_READY_EVENT (1 << 0) - -struct ts_driver_data g_touch_drv = {0}; -struct ts_driver_data *g_attr = NULL; - -report_event_cb g_report_event_cb = NULL; - -#if defined(SUPPORT_POWER_MANAGER) -event_callback_func g_power_manager_cb = NULL; -#endif - -static struct ts_driver_data *touch_screen_get_driver_data(void) -{ - return &g_touch_drv; -} - -static uint32_t touch_screen_get_state(struct ts_driver_data *tsdd) -{ - if (tsdd != NULL && tsdd->queue != NULL) { - return (uint32_t)ts_queue_is_empty(tsdd->queue); - } - - if (tsdd == NULL) { - tp_err("tsdd is null!"); - return EXT_ERR_FAILURE; - } - if (tsdd->queue == NULL) { - tp_err("tsdd queue is null!"); - } - - return EXT_ERR_FAILURE; -} - -static void convert_touch_info(input_dev_data_t* data, input_event_info* touch_info) -{ - data->x = (int16_t)touch_info->tp_event_info.x_axis[0]; - data->y = (int16_t)touch_info->tp_event_info.y_axis[0]; - data->type = INDEV_TYPE_TOUCH; - data->timestamp = (uint32_t)touch_info->tv_usec; - if ((touch_info->tp_event == MC_TP_PRESS) || (touch_info->tp_event == MC_TP_MOVE)) { - data->state = INDEV_STATE_PRESS; - } else if (touch_info->tp_event == MC_TP_RELEASE) { - data->state = INDEV_STATE_RELEASE; - } else { - data->state = INDEV_STATE_UNKNOWN; - } -} - -static void report_or_enqueue_event(input_event_info* touch_info, struct ts_driver_data *tsdd) -{ - if (g_report_event_cb != NULL) { - input_dev_data_t data; - convert_touch_info(&data, touch_info); - if (data.state == INDEV_STATE_UNKNOWN) { - return; - } - g_report_event_cb(&data); - } else { - int32_t ret = ts_en_queue(tsdd->queue, touch_info); - if (ret != EXT_ERR_SUCCESS) { - tp_err("Failed to enqueue ts queue! ret=0x%x", ret); - } - } -} -#if defined(SUPPORT_POWER_MANAGER) -static void report_event_to_power_manager(input_event_info *touch_info) -{ - if (g_power_manager_cb != NULL) { - input_dev_data_t data; - convert_touch_info(&data, touch_info); - if (data.state == INDEV_STATE_UNKNOWN) { - return; - } - g_power_manager_cb(data.state, 0); - } - return; -} - -uint32_t ts_register_power_manager_cb(event_callback_func callback) -{ - if (g_power_manager_cb != NULL) { - return EXT_ERR_FAILURE; - } - g_power_manager_cb = callback; - return EXT_ERR_SUCCESS; -} -#endif -ext_errno touch_info_process(void) -{ - struct ts_driver_data *tsdd = touch_screen_get_driver_data(); - input_event_info touch_info; - int32_t ret = 0; - - if (tsdd->touch_api->touch_get_tpinfo != NULL) { - ret = tsdd->touch_api->touch_get_tpinfo((uint8_t *)(&touch_info), sizeof(input_event_info)); - if (ret != EXT_ERR_SUCCESS) { - tp_err("get touch info fail! ret=0x%x", ret); - } - - report_or_enqueue_event(&touch_info, tsdd); -#if defined(SUPPORT_POWER_MANAGER) - report_event_to_power_manager(&touch_info); -#endif - } - - return EXT_ERR_SUCCESS; -} - -static void ts_callback_func(void) -{ - ext_errno ret; - if (g_attr != NULL) { - common_notify_mail_t mail = {0}; - mail.comm.app = APP_TOUCH; - ret = osal_msg_queue_write_copy(get_app_queue_id(), (void *)&mail, - sizeof(common_notify_mail_t), 0); - if (ret != OSAL_SUCCESS) { - tp_err("touch app msg send failed! err=0x%x! \r\n", ret); - } - } -} - -static ext_errno ts_register_callback(struct ts_driver_data *attr) -{ - ext_errno ret = EXT_ERR_FAILURE; - g_attr = attr; - - if (attr->touch_api->register_callback != NULL) { - ret = attr->touch_api->register_callback(attr->private_data, ts_callback_func); - if (ret != EXT_ERR_SUCCESS) { - tp_err("register touch screen callback fail! ret=0x%x", ret); - return ret; - } - } else { - tp_err("touch screen callback register func is empty!"); - } - - return ret; -} - -static ext_errno ts_unregister_callback(struct ts_driver_data *attr) -{ - ext_errno ret = EXT_ERR_FAILURE; - - if (attr->touch_api->unregister_callback != NULL) { - ret = attr->touch_api->unregister_callback(attr->private_data); - if (ret != EXT_ERR_SUCCESS) { - tp_err("unregister touch screen callback fail! ret=0x%x", ret); - return ret; - } - g_attr = NULL; - } else { - tp_err("touch screen callback unregister func is empty!"); - } - - return ret; -} - -static int32_t ts_dev_open(const void *private_data) -{ - int32_t ret; - struct ts_driver_data *tsdd = NULL; - if (private_data == NULL) { - tp_err("ts_open: invalid dev or driver_data!\n"); - return EXT_ERR_FAILURE; - } - - // todo: get tsdd from private_data - tsdd = touch_screen_get_driver_data(); - tsdd->queue = ts_init_queue(TOUCH_SCREEN_QUEUE_MAX_SIZE); - if (tsdd->queue == NULL) { - tp_err("create touch screen queue fail!\r\n"); - return EXT_ERR_FAILURE; - } - ret = osal_event_init(&(tsdd->event)); - if (ret != EXT_ERR_SUCCESS) { - tp_err("touch osal_event_init fail! ret=0x%x\r\n", ret); - return ret; - } - - tsdd->task_handle = osal_kthread_create((osal_kthread_handler)touch_info_process, - (void *)touch_screen_get_driver_data(), - "touch_screen", TOUCH_SCREEN_TASK_SIZE); - if (tsdd->task_handle == NULL) { - tp_err("create touch screen thread fail!\r\n"); - return EXT_ERR_FAILURE; - } - osal_kthread_set_priority(tsdd->task_handle, TOUCH_SCREEN_TASK_PRIO); - - if (tsdd->touch_api->touch_init != NULL) { - ret = tsdd->touch_api->touch_init(tsdd->private_data); - if (ret != EXT_ERR_SUCCESS) { - tp_err("touch_init fail! ret=0x%x\r\n", ret); - return ret; - } - } - - ret = ts_register_callback(tsdd); - if (ret != EXT_ERR_SUCCESS) { - tp_err("register callback fail! ret=0x%x\r\n", ret); - return ret; - } - - return EXT_ERR_SUCCESS; -} - -static int32_t ts_dev_release(const void *private_data) -{ - int32_t ret; - struct ts_driver_data *tsdd = NULL; - if (private_data == NULL) { - tp_err("ts_dev_release: invalid dev or driver_data!\n"); - return EXT_ERR_FAILURE; - } - - // todo: get tsdd from private_data - tsdd = touch_screen_get_driver_data(); - ret = ts_unregister_callback(tsdd); - if (ret != EXT_ERR_SUCCESS) { - tp_err("unregister callback fail! ret=0x%x\r\n", ret); - return ret; - } - return EXT_ERR_SUCCESS; -} - -static uint32_t ts_dev_poll(const osal_poll *osal_poll, const void *private_data) -{ - unused(osal_poll); - unused(private_data); - // todo: get tsdd from private_data - struct ts_driver_data *tsdd = NULL; - tsdd = touch_screen_get_driver_data(); - if (tsdd == NULL) { - tp_err("ts_driver_data is NULL"); - return EXT_ERR_FAILURE; - } - - if (tsdd->ops->priv_operator != NULL && tsdd->ops->priv_operator(tsdd) == 0) { - return OSAL_POLLIN | OSAL_POLLRDNORM; - } - - return EXT_ERR_SUCCESS; -} - -static int32_t ts_ioctl_read_touch_info(uint32_t cmd, void *arg, const void *private_data) -{ - unused(cmd); - ext_errno ret; - struct ts_driver_data *tsdd = NULL; - input_event_info *touch_info = (input_event_info *)arg; - - if (private_data == NULL) { - tp_err("invalid dev or driver_data!"); - return EXT_ERR_FAILURE; - } - - // todo: get tsdd from private_data - tsdd = touch_screen_get_driver_data(); - if (tsdd->queue == NULL) { - tp_err("invalid touch screen queue!"); - return EXT_ERR_FAILURE; - } - - ret = ts_de_queue(tsdd->queue, touch_info); - if (ret != EXT_ERR_SUCCESS) { - tp_err("get touch info fail! ret=0x%x", ret); - return ret; - } - - return EXT_ERR_SUCCESS; -} - -static osal_ioctl_cmd g_ts_cmd_list[TOUCH_SCREEN_CMDID_MAX] = { - {TOUCH_SCREEN_GET_EVENT, ts_ioctl_read_touch_info}, -}; - -static osal_dev *g_ts_dev = NULL; -static osal_fileops g_ts_ops = { - .open = ts_dev_open, - .release = ts_dev_release, - .poll = ts_dev_poll, - .cmd_list = g_ts_cmd_list, - .cmd_cnt = sizeof(g_ts_cmd_list) / sizeof(g_ts_cmd_list[0]), -}; - -struct ts_ops g_ts_status_ops = { - .priv_operator = touch_screen_get_state, -}; - -static ext_errno touch_screen_register_device(void) -{ - ext_errno ret; - - g_touch_drv.private_data = touch_screen_get_peri_attr(); - g_touch_drv.touch_api = touch_screen_get_api(); - g_touch_drv.ops = &g_ts_status_ops; - g_ts_dev = osal_dev_create(TOUCH_SCREEN_DEVNAME); - g_ts_dev->minor = TOUCH_SCREEN_DYNAMIC_MINOR; - g_ts_dev->fops = &g_ts_ops; - - ret = osal_dev_register(g_ts_dev); - if (ret != 0) { - tp_err("touch screen osal_dev_register --------failed! ret=0x%x\n", ret); - return EXT_ERR_FAILURE; - } - - return EXT_ERR_SUCCESS; -} - -ext_errno touch_screen_module_init(void) -{ - ext_errno ret; - - ret = touch_screen_register_device(); - if (ret != EXT_ERR_SUCCESS) { - tp_err("touch_screen_register_device ----------failed! ret=0x%x\n", ret); - } - tp_err("touch_screen_register_device ----------succ!!!\n"); - - return EXT_ERR_SUCCESS; -} - -ext_errno touch_screen_module_deinit(void) -{ - return EXT_ERR_SUCCESS; -} - -uint32_t ts_register_report_event_cb(report_event_cb callback) -{ - if (g_report_event_cb != NULL) { - return EXT_ERR_FAILURE; - } - g_report_event_cb = callback; - return EXT_ERR_SUCCESS; -} - -uint32_t ts_unregister_report_event_cb(void) -{ - g_report_event_cb = NULL; - return EXT_ERR_SUCCESS; -} - -uint32_t ts_init(void) -{ - int32_t ret; - struct ts_driver_data *tsdd = NULL; - - g_touch_drv.private_data = touch_screen_get_peri_attr(); - g_touch_drv.touch_api = touch_screen_get_api(); - g_touch_drv.ops = &g_ts_status_ops; - tsdd = touch_screen_get_driver_data(); - tsdd->queue = ts_init_queue(TOUCH_SCREEN_QUEUE_MAX_SIZE); - if (tsdd->queue == NULL) { - tp_err("create touch screen queue fail!\r\n"); - return EXT_ERR_FAILURE; - } - - ret = ts_register_callback(tsdd); - if (ret != EXT_ERR_SUCCESS) { - tp_err("register callback fail! ret=0x%x\r\n", ret); - return EXT_ERR_FAILURE; - } - - return EXT_ERR_SUCCESS; -} - -uint32_t ts_read(const input_dev_data_t* data) -{ - unused(data); - return EXT_ERR_SUCCESS; -} - -uint32_t ts_close(void) -{ - return EXT_ERR_SUCCESS; -} diff --git a/code/sdk/drivers/peripheral/CMakeLists.txt b/code/sdk/drivers/peripheral/CMakeLists.txt new file mode 100644 index 000000000..52ee4c8ab --- /dev/null +++ b/code/sdk/drivers/peripheral/CMakeLists.txt @@ -0,0 +1,15 @@ +#=============================================================================== +# @brief cmake make file +# Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. +#=============================================================================== +# add_subdirectory(hal ${PROJECT_BINARY_DIR}/hal) +add_subdirectory_if_exist(acc) +add_subdirectory_if_exist(button) +add_subdirectory_if_exist(lcd) +add_subdirectory_if_exist(mag) +add_subdirectory_if_exist(ppg) +add_subdirectory_if_exist(touch) +add_subdirectory_if_exist(vibrator) +add_subdirectory_if_exist(slip) +add_subdirectory_if_exist(utils) +add_subdirectory_if_exist(rotary_encoder) diff --git a/code/sdk/drivers/peripheral/acc/CMakeLists.txt b/code/sdk/drivers/peripheral/acc/CMakeLists.txt new file mode 100644 index 000000000..4bff8c819 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/CMakeLists.txt @@ -0,0 +1,87 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "acc_sensor") + +if("ACC_LIS2DOC" IN_LIST DEFINES) +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/lis2doc_porting.c + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/lis2doc_at_cmd.c + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/driver/lis2doc_reg.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_activity.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_free_fall.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_orientation.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_read_data_polling.c + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_read_data_single.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_read_fifo.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_self_test.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_wake_up.c + ${CMAKE_CURRENT_SOURCE_DIR}/service/acc_service.c +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/service + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC +) +set(PUBLIC_DEFINES + SUPPORT_AT_LIS2DOC +) +set(PRIVATE_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/driver +) + +else() + +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/lis2doc_porting.c + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/lis2doc_at_cmd.c + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/driver/lis2doc_reg.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_activity.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_free_fall.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_orientation.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_read_data_polling.c + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_read_data_single.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_read_fifo.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_self_test.c + # ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/examples/lis2doc_wake_up.c + ${CMAKE_CURRENT_SOURCE_DIR}/service/acc_service.c +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/service + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC +) +set(PUBLIC_DEFINES + SUPPORT_AT_LIS2DOC +) +set(PRIVATE_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/lis2doc_STdC/driver +) + +endif() + + +set(PRIVATE_DEFINES +) + + + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-incompatible-function-pointer-types + -Wno-unused-function +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +build_component() + +install_sdk(${CMAKE_CURRENT_SOURCE_DIR} "*") diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/README.txt b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/README.txt new file mode 100644 index 000000000..ba5523067 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/README.txt @@ -0,0 +1,18 @@ + +In the 'driver' folder there are the driver files of Mems Sensor (.h and .c) +to be included in your project. + +Driver documentation can be generate using Doxigen tool. + +The driver is platform independent, you need only to complete the two functions +for write and read from Mems Hardware Bus. + +The files (.c) in 'example' folder, are examples showing how to integrate +the Standard C driver in a project. They are written for STM32 +Microcontroller using CubeMX API, but you can use it as a guideline for +every hardware. + +www.st.com/mems + +LIS2DOC DS rev1 + diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/driver/lis2doc_reg.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/driver/lis2doc_reg.c new file mode 100644 index 000000000..886eedee0 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/driver/lis2doc_reg.c @@ -0,0 +1,3196 @@ +/** + ****************************************************************************** + * @file lis2doc_reg.c + * @author Sensors Software Solution Team + * @brief LIS2DOC driver file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +#include "lis2doc_reg.h" + +/** + * @defgroup LIS2DOC + * @brief This file provides a set of functions needed to drive the + * lis2doc enhanced inertial module. + * @{ + * + */ + +/** + * @defgroup LIS2DOC_Interfaces_Functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +/** + * @brief Read generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to read + * @param data pointer to buffer that store the data read(ptr) + * @param len number of consecutive register to read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +// int32_t __weak lis2doc_read_reg(stmdev_ctx_t *ctx, uint8_t reg, +int32_t lis2doc_read_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len) +{ + int32_t ret; + + ret = ctx->read_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @brief Write generic device register + * + * @param ctx read / write interface definitions(ptr) + * @param reg register to write + * @param data pointer to data to write in register reg(ptr) + * @param len number of consecutive register to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t __weak lis2doc_write_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len) +{ + int32_t ret; + + ret = ctx->write_reg(ctx->handle, reg, data, len); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Sensitivity + * @brief These functions convert raw-data into engineering units. + * @{ + * + */ + +float_t lis2doc_from_fs2_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.061f; +} + +float_t lis2doc_from_fs4_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.122f; +} + +float_t lis2doc_from_fs8_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.244f; +} + +float_t lis2doc_from_fs16_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.488f; +} + +float_t lis2doc_from_fs2_lp1_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.061f; +} + +float_t lis2doc_from_fs4_lp1_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.122f; +} + +float_t lis2doc_from_fs8_lp1_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.244f; +} + +float_t lis2doc_from_fs16_lp1_to_mg(int16_t lsb) +{ + return ((float_t)lsb) * 0.488f; +} + +float_t lis2doc_from_lsb_to_celsius(int16_t lsb) +{ + return (((float_t)lsb / 256.0f) + 25.0f); +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Data_Generation + * @brief This section groups all the functions concerning + * data generation + * @{ + * + */ + +/** + * @brief Select accelerometer operating modes.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of mode / lp_mode in reg CTRL1 + * and low_noise in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_power_mode_set(stmdev_ctx_t *ctx, + lis2doc_mode_t val) +{ + lis2doc_ctrl1_t ctrl1; + lis2doc_ctrl6_t ctrl6; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL1, (uint8_t *) &ctrl1, 1); + if (ret != 0) { return ret; } + + ctrl1.sdrc_en = val.sdrc; + ctrl1.lpm_en = val.lpm; + ctrl1.hpm_en = val.hpm; + + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL1, (uint8_t *) &ctrl1, 1); + if (ret != 0) { return ret; } + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) &ctrl6, 1); + ctrl6.low_noise = val.low_noise; + ret += lis2doc_write_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) &ctrl6, 1); + + return ret; +} + +/** + * @brief Select accelerometer operating modes.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of mode / lp_mode in reg CTRL1 + * and low_noise in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_power_mode_get(stmdev_ctx_t *ctx, + lis2doc_mode_t *val) +{ + lis2doc_ctrl1_t ctrl1; + lis2doc_ctrl6_t ctrl6; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL1, (uint8_t *) &ctrl1, 1); + ret += lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) &ctrl6, 1); + if (ret != 0) { return ret; } + + val->sdrc = ctrl1.sdrc_en; + val->lpm = ctrl1.lpm_en; + val->hpm = ctrl1.hpm_en; + val->low_noise = ctrl6.low_noise; + + return ret; +} + +/** + * @brief Accelerometer data rate selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of odr in reg CTRL1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_data_rate_set(stmdev_ctx_t *ctx, lis2doc_odr_t val) +{ + lis2doc_ctrl1_t ctrl1; + lis2doc_ctrl3_t ctrl3; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL1, (uint8_t *) &ctrl1, 1); + + if (ret == 0) + { + ctrl1.odr = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL1, (uint8_t *) &ctrl1, 1); + } + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) &ctrl3, 1); + } + + if (ret == 0) + { + ctrl3.slp_mode = ((uint8_t) val & 0x30U) >> 4; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) &ctrl3, 1); + } + + return ret; +} + +/** + * @brief Accelerometer data rate selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of odr in reg CTRL1 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_data_rate_get(stmdev_ctx_t *ctx, lis2doc_odr_t *val) +{ + lis2doc_ctrl1_t ctrl1; + lis2doc_ctrl3_t ctrl3; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL1, (uint8_t *) &ctrl1, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) &ctrl3, 1); + + switch ((ctrl3.slp_mode << 4) + ctrl1.odr) + { + case LIS2DOC_XL_ODR_OFF: + *val = LIS2DOC_XL_ODR_OFF; + break; + + case LIS2DOC_XL_ODR_1Hz6_LP_ONLY: + *val = LIS2DOC_XL_ODR_1Hz6_LP_ONLY; + break; + + case LIS2DOC_XL_ODR_12Hz5: + *val = LIS2DOC_XL_ODR_12Hz5; + break; + + case LIS2DOC_XL_ODR_25Hz: + *val = LIS2DOC_XL_ODR_25Hz; + break; + + case LIS2DOC_XL_ODR_50Hz: + *val = LIS2DOC_XL_ODR_50Hz; + break; + + case LIS2DOC_XL_ODR_100Hz: + *val = LIS2DOC_XL_ODR_100Hz; + break; + + case LIS2DOC_XL_ODR_200Hz: + *val = LIS2DOC_XL_ODR_200Hz; + break; + + case LIS2DOC_XL_ODR_400Hz: + *val = LIS2DOC_XL_ODR_400Hz; + break; + + case LIS2DOC_XL_ODR_800Hz: + *val = LIS2DOC_XL_ODR_800Hz; + break; + + case LIS2DOC_XL_ODR_1k6Hz: + *val = LIS2DOC_XL_ODR_1k6Hz; + break; + + case LIS2DOC_XL_SET_SW_TRIG: + *val = LIS2DOC_XL_SET_SW_TRIG; + break; + + case LIS2DOC_XL_SET_PIN_TRIG: + *val = LIS2DOC_XL_SET_PIN_TRIG; + break; + + default: + *val = LIS2DOC_XL_ODR_OFF; + break; + } + } + + return ret; +} + +/** + * @brief Block data update.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of bdu in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_block_data_update_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.bdu = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Block data update.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of bdu in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_block_data_update_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + *val = reg.bdu; + + return ret; +} + +/** + * @brief Accelerometer full-scale selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fs in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_full_scale_set(stmdev_ctx_t *ctx, lis2doc_fs_t val) +{ + lis2doc_ctrl6_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.fs = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer full-scale selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fs in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_full_scale_get(stmdev_ctx_t *ctx, lis2doc_fs_t *val) +{ + lis2doc_ctrl6_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) ®, 1); + + switch (reg.fs) + { + case LIS2DOC_2g: + *val = LIS2DOC_2g; + break; + + case LIS2DOC_4g: + *val = LIS2DOC_4g; + break; + + case LIS2DOC_8g: + *val = LIS2DOC_8g; + break; + + case LIS2DOC_16g: + *val = LIS2DOC_16g; + break; + + default: + *val = LIS2DOC_2g; + break; + } + + return ret; +} + +/** + * @brief The STATUS_REG register of the device.[get] + * + * @param ctx read / write interface definitions + * @param val union of registers from STATUS to + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_status_reg_get(stmdev_ctx_t *ctx, + lis2doc_status_t *val) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_STATUS, (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief Accelerometer new data available.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of drdy in reg STATUS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_flag_data_ready_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_status_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_STATUS, (uint8_t *) ®, 1); + *val = reg.drdy; + + return ret; +} +/** + * @brief Read all the interrupt/status flag of the device.[get] + * + * @param ctx read / write interface definitions + * @param val registers STATUS_DUP, WAKE_UP_SRC, + * TAP_SRC, SIXD_SRC, ALL_INT_SRC + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_all_sources_get(stmdev_ctx_t *ctx, + lis2doc_all_sources_t *val) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_STATUS_DUP, (uint8_t *) val, 5); + + return ret; +} + +/** + * @brief Accelerometer X-axis user offset correction expressed in two’s + * complement, weight depends on bit USR_OFF_W. The value must be + * in the range [-127 127].[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_usr_offset_x_set(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_write_reg(ctx, LIS2DOC_X_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer X-axis user offset correction expressed in two’s + * complement, weight depends on bit USR_OFF_W. The value must be + * in the range [-127 127].[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_usr_offset_x_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_X_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Y-axis user offset correction expressed in two’s + * complement, weight depends on bit USR_OFF_W. The value must be + * in the range [-127 127].[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_usr_offset_y_set(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_write_reg(ctx, LIS2DOC_Y_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Y-axis user offset correction expressed in two’s + * complement, weight depends on bit USR_OFF_W. The value must be + * in the range [-127 127].[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_usr_offset_y_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_Y_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Z-axis user offset correction expressed in two’s + * complement, weight depends on bit USR_OFF_W. The value must be + * in the range [-127 127].[set] + * + * @param ctx read / write interface definitions + * @param buff buffer that contains data to write + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_usr_offset_z_set(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_write_reg(ctx, LIS2DOC_Z_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Accelerometer Z-axis user offset correction expressed in two’s + * complement, weight depends on bit USR_OFF_W. The value must be + * in the range [-127 127].[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_usr_offset_z_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_Z_OFS_USR, buff, 1); + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers X_OFS_USR, + * Y_OFS_USR, Z_OFS_USR.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of usr_off_w in + * reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_offset_weight_set(stmdev_ctx_t *ctx, + lis2doc_usr_off_w_t val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.usr_off_w = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Weight of XL user offset bits of registers X_OFS_USR, + * Y_OFS_USR, Z_OFS_USR.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of usr_off_w in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_offset_weight_get(stmdev_ctx_t *ctx, + lis2doc_usr_off_w_t *val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + switch (reg.usr_off_w) + { + case LIS2DOC_LSb_977ug: + *val = LIS2DOC_LSb_977ug; + break; + + case LIS2DOC_LSb_15mg6: + *val = LIS2DOC_LSb_15mg6; + break; + + default: + *val = LIS2DOC_LSb_977ug; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Data_Output + * @brief This section groups all the data output functions. + * @{ + * + */ + +/** + * @brief Temperature data output register (r). L and H registers + * together express a 16-bit word in two’s complement.[get] + * + * @param ctx read / write interface definitions + * @param val buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_temperature_raw_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[2]; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_OUT_T_L, buff, 2); + *val = (int16_t)buff[1]; + *val = (*val * 256) + (int16_t)buff[0]; + + return ret; +} + +/** + * @brief Linear acceleration output register. The value is expressed as + * a 16-bit word in two’s complement.[get] + * + * @param ctx read / write interface definitions + * @param val buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_acceleration_raw_get(stmdev_ctx_t *ctx, int16_t *val) +{ + uint8_t buff[6]; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_OUT_X_L, buff, 6); + val[0] = (int16_t)buff[1]; + val[0] = (val[0] * 256) + (int16_t)buff[0]; + val[1] = (int16_t)buff[3]; + val[1] = (val[1] * 256) + (int16_t)buff[2]; + val[2] = (int16_t)buff[5]; + val[2] = (val[2] * 256) + (int16_t)buff[4]; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Common + * @brief This section groups common useful functions. + * @{ + * + */ + +/** + * @brief Device Who am I.[get] + * + * @param ctx read / write interface definitions + * @param buff buffer that stores data read + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_device_id_get(stmdev_ctx_t *ctx, uint8_t *buff) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WHO_AM_I, buff, 1); + + return ret; +} + +/** + * @brief Register address automatically incremented during multiple byte + * access with a serial interface.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of if_add_inc in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_auto_increment_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.if_add_inc = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Register address automatically incremented during multiple + * byte access with a serial interface.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of if_add_inc in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_auto_increment_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + *val = reg.if_add_inc; + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of soft_reset in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_reset_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.soft_reset = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Software reset. Restore the default values in user registers.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of soft_reset in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_reset_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + *val = reg.soft_reset; + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of boot in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_boot_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.boot = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Reboot memory content. Reload the calibration parameters.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of boot in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_boot_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + *val = reg.boot; + + return ret; +} + +/** + * @brief Sensor self-test enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of st in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_self_test_set(stmdev_ctx_t *ctx, lis2doc_st_t val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.st = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Sensor self-test enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of st in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_self_test_get(stmdev_ctx_t *ctx, lis2doc_st_t *val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + switch (reg.st) + { + case LIS2DOC_XL_ST_DISABLE: + *val = LIS2DOC_XL_ST_DISABLE; + break; + + case LIS2DOC_XL_ST_POSITIVE: + *val = LIS2DOC_XL_ST_POSITIVE; + break; + + case LIS2DOC_XL_ST_NEGATIVE: + *val = LIS2DOC_XL_ST_NEGATIVE; + break; + + default: + *val = LIS2DOC_XL_ST_DISABLE; + break; + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of drdy_pulsed in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_data_ready_mode_set(stmdev_ctx_t *ctx, + lis2doc_drdy_pulsed_t val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.drdy_pulsed = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Data-ready pulsed / letched mode.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of drdy_pulsed in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_data_ready_mode_get(stmdev_ctx_t *ctx, + lis2doc_drdy_pulsed_t *val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + switch (reg.drdy_pulsed) + { + case LIS2DOC_DRDY_LATCHED: + *val = LIS2DOC_DRDY_LATCHED; + break; + + case LIS2DOC_DRDY_PULSED: + *val = LIS2DOC_DRDY_PULSED; + break; + + default: + *val = LIS2DOC_DRDY_LATCHED; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Filters + * @brief This section group all the functions concerning the filters + * configuration. + * @{ + * + */ + +/** + * @brief Accelerometer filtering path for outputs.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fds in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_filter_path_set(stmdev_ctx_t *ctx, + lis2doc_fds_t val) +{ + lis2doc_ctrl6_t ctrl6; + lis2doc_ctrl_reg7_t ctrl_reg7; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) &ctrl6, 1); + + if (ret == 0) + { + ctrl6.fds = ((uint8_t) val & 0x10U) >> 4; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) &ctrl6, 1); + } + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, + (uint8_t *) &ctrl_reg7, 1); + } + + if (ret == 0) + { + ctrl_reg7.usr_off_on_out = (uint8_t) val & 0x01U; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, + (uint8_t *) &ctrl_reg7, 1); + } + + return ret; +} + +/** + * @brief Accelerometer filtering path for outputs.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fds in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_filter_path_get(stmdev_ctx_t *ctx, + lis2doc_fds_t *val) +{ + lis2doc_ctrl6_t ctrl6; + lis2doc_ctrl_reg7_t ctrl_reg7; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) &ctrl6, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, + (uint8_t *) &ctrl_reg7, 1); + + switch ((ctrl6.fds << 4) + ctrl_reg7.usr_off_on_out) + { + case LIS2DOC_LPF_ON_OUT: + *val = LIS2DOC_LPF_ON_OUT; + break; + + case LIS2DOC_USER_OFFSET_ON_OUT: + *val = LIS2DOC_USER_OFFSET_ON_OUT; + break; + + case LIS2DOC_HIGH_PASS_ON_OUT: + *val = LIS2DOC_HIGH_PASS_ON_OUT; + break; + + default: + *val = LIS2DOC_LPF_ON_OUT; + break; + } + } + + return ret; +} + +/** + * @brief Accelerometer cutoff filter frequency. Valid for low and high + * pass filter.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of bw_filt in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_filter_bandwidth_set(stmdev_ctx_t *ctx, + lis2doc_bw_filt_t val) +{ + lis2doc_ctrl6_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.bw_filt = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Accelerometer cutoff filter frequency. Valid for low and + * high pass filter.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of bw_filt in reg CTRL6 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_filter_bandwidth_get(stmdev_ctx_t *ctx, + lis2doc_bw_filt_t *val) +{ + lis2doc_ctrl6_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL6, (uint8_t *) ®, 1); + + switch (reg.bw_filt) + { + case LIS2DOC_ODR_DIV_2: + *val = LIS2DOC_ODR_DIV_2; + break; + + case LIS2DOC_ODR_DIV_4: + *val = LIS2DOC_ODR_DIV_4; + break; + + case LIS2DOC_ODR_DIV_10: + *val = LIS2DOC_ODR_DIV_10; + break; + + case LIS2DOC_ODR_DIV_20: + *val = LIS2DOC_ODR_DIV_20; + break; + + default: + *val = LIS2DOC_ODR_DIV_2; + break; + } + + return ret; +} + +/** + * @brief Enable HP filter reference mode.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of hp_ref_mode in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_reference_mode_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.hp_ref_mode = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Enable HP filter reference mode.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of hp_ref_mode in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_reference_mode_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + *val = reg.hp_ref_mode; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Serial_Interface + * @brief This section groups all the functions concerning main serial + * interface management (not auxiliary) + * @{ + * + */ + +/** + * @brief SPI Serial Interface Mode selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sim in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_spi_mode_set(stmdev_ctx_t *ctx, lis2doc_sim_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.sim = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief SPI Serial Interface Mode selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sim in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_spi_mode_get(stmdev_ctx_t *ctx, lis2doc_sim_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + switch (reg.sim) + { + case LIS2DOC_SPI_4_WIRE: + *val = LIS2DOC_SPI_4_WIRE; + break; + + case LIS2DOC_SPI_3_WIRE: + *val = LIS2DOC_SPI_3_WIRE; + break; + + default: + *val = LIS2DOC_SPI_4_WIRE; + break; + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of i2c_disable in + * reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_i2c_interface_set(stmdev_ctx_t *ctx, + lis2doc_i2c_disable_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.i2c_disable = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Disable / Enable I2C interface.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of i2c_disable in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_i2c_interface_get(stmdev_ctx_t *ctx, + lis2doc_i2c_disable_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + switch (reg.i2c_disable) + { + case LIS2DOC_I2C_ENABLE: + *val = LIS2DOC_I2C_ENABLE; + break; + + case LIS2DOC_I2C_DISABLE: + *val = LIS2DOC_I2C_DISABLE; + break; + + default: + *val = LIS2DOC_I2C_ENABLE; + break; + } + + return ret; +} + +/** + * @brief Disconnect CS pull-up.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of cs_pu_disc in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_cs_mode_set(stmdev_ctx_t *ctx, + lis2doc_cs_pu_disc_t val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.cs_pu_disc = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Disconnect CS pull-up.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of cs_pu_disc in reg CTRL2 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_cs_mode_get(stmdev_ctx_t *ctx, + lis2doc_cs_pu_disc_t *val) +{ + lis2doc_ctrl2_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL2, (uint8_t *) ®, 1); + + switch (reg.cs_pu_disc) + { + case LIS2DOC_PULL_UP_CONNECT: + *val = LIS2DOC_PULL_UP_CONNECT; + break; + + case LIS2DOC_PULL_UP_DISCONNECT: + *val = LIS2DOC_PULL_UP_DISCONNECT; + break; + + default: + *val = LIS2DOC_PULL_UP_CONNECT; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Interrupt_Pins + * @brief This section groups all the functions that manage interrupt pins + * @{ + * + */ + +/** + * @brief Interrupt active-high/low.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of h_lactive in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_polarity_set(stmdev_ctx_t *ctx, + lis2doc_h_lactive_t val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.h_lactive = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Interrupt active-high/low.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of h_lactive in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_polarity_get(stmdev_ctx_t *ctx, + lis2doc_h_lactive_t *val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + switch (reg.h_lactive) + { + case LIS2DOC_ACTIVE_HIGH: + *val = LIS2DOC_ACTIVE_HIGH; + break; + + case LIS2DOC_ACTIVE_LOW: + *val = LIS2DOC_ACTIVE_LOW; + break; + + default: + *val = LIS2DOC_ACTIVE_HIGH; + break; + } + + return ret; +} + +/** + * @brief Latched/pulsed interrupt.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of lir in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_int_notification_set(stmdev_ctx_t *ctx, + lis2doc_lir_t val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.lir = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Latched/pulsed interrupt.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of lir in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_int_notification_get(stmdev_ctx_t *ctx, + lis2doc_lir_t *val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + switch (reg.lir) + { + case LIS2DOC_INT_PULSED: + *val = LIS2DOC_INT_PULSED; + break; + + case LIS2DOC_INT_LATCHED: + *val = LIS2DOC_INT_LATCHED; + break; + + default: + *val = LIS2DOC_INT_PULSED; + break; + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of pp_od in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_mode_set(stmdev_ctx_t *ctx, lis2doc_pp_od_t val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.pp_od = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Push-pull/open drain selection on interrupt pads.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of pp_od in reg CTRL3 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_mode_get(stmdev_ctx_t *ctx, + lis2doc_pp_od_t *val) +{ + lis2doc_ctrl3_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL3, (uint8_t *) ®, 1); + + switch (reg.pp_od) + { + case LIS2DOC_PUSH_PULL: + *val = LIS2DOC_PUSH_PULL; + break; + + case LIS2DOC_OPEN_DRAIN: + *val = LIS2DOC_OPEN_DRAIN; + break; + + default: + *val = LIS2DOC_PUSH_PULL; + break; + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int1 pad.[set] + * + * @param ctx read / write interface definitions + * @param val register CTRL4_INT1_PAD_CTRL. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_int1_route_set(stmdev_ctx_t *ctx, + lis2doc_ctrl4_int1_pad_ctrl_t *val) +{ + lis2doc_ctrl5_int2_pad_ctrl_t ctrl5_int2_pad_ctrl; + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL5_INT2_PAD_CTRL, + (uint8_t *)&ctrl5_int2_pad_ctrl, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + if (ret == 0) + { + if ((val->int1_tap | + val->int1_ff | + val->int1_wu | + val->int1_single_tap | + val->int1_6d | + ctrl5_int2_pad_ctrl.int2_sleep_state | + ctrl5_int2_pad_ctrl.int2_sleep_chg) != PROPERTY_DISABLE) + { + reg.interrupts_enable = PROPERTY_ENABLE; + } + + else + { + reg.interrupts_enable = PROPERTY_DISABLE; + } + + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL4_INT1_PAD_CTRL, + (uint8_t *) val, 1); + } + + if (ret == 0) + { + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int1 pad.[get] + * + * @param ctx read / write interface definitions + * @param val register CTRL4_INT1_PAD_CTRL. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_int1_route_get(stmdev_ctx_t *ctx, + lis2doc_ctrl4_int1_pad_ctrl_t *val) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL4_INT1_PAD_CTRL, + (uint8_t *) val, 1); + + return ret; +} + +/** + * @brief Select the signal that need to route on int2 pad.[set] + * + * @param ctx read / write interface definitions + * @param val register CTRL5_INT2_PAD_CTRL. + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_int2_route_set(stmdev_ctx_t *ctx, + lis2doc_ctrl5_int2_pad_ctrl_t *val) +{ + lis2doc_ctrl4_int1_pad_ctrl_t ctrl4_int1_pad_ctrl; + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL4_INT1_PAD_CTRL, + (uint8_t *) &ctrl4_int1_pad_ctrl, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + if (ret == 0) + { + if ((ctrl4_int1_pad_ctrl.int1_tap | + ctrl4_int1_pad_ctrl.int1_ff | + ctrl4_int1_pad_ctrl.int1_wu | + ctrl4_int1_pad_ctrl.int1_single_tap | + ctrl4_int1_pad_ctrl.int1_6d | + val->int2_sleep_state | val->int2_sleep_chg) != PROPERTY_DISABLE) + { + reg.interrupts_enable = PROPERTY_ENABLE; + } + + else + { + reg.interrupts_enable = PROPERTY_DISABLE; + } + + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL5_INT2_PAD_CTRL, + (uint8_t *) val, 1); + } + + if (ret == 0) + { + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Select the signal that need to route on int2 pad.[get] + * + * @param ctx read / write interface definitions + * @param val register CTRL5_INT2_PAD_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_pin_int2_route_get(stmdev_ctx_t *ctx, + lis2doc_ctrl5_int2_pad_ctrl_t *val) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL5_INT2_PAD_CTRL, + (uint8_t *) val, 1); + + return ret; +} +/** + * @brief All interrupt signals become available on INT1 pin.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of int2_on_int1 in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_all_on_int1_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.int2_on_int1 = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief All interrupt signals become available on INT1 pin.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of int2_on_int1 in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_all_on_int1_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + *val = reg.int2_on_int1; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Wake_Up_Event + * @brief This section groups all the functions that manage the Wake + * Up event generation. + * @{ + * + */ + +/** + * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of wk_ths in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_wkup_threshold_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_wake_up_ths_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_THS, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.wk_ths = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_THS, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Threshold for wakeup.1 LSB = FS_XL / 64.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of wk_ths in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_wkup_threshold_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_wake_up_ths_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_THS, (uint8_t *) ®, 1); + *val = reg.wk_ths; + + return ret; +} + +/** + * @brief Wake up duration event.1LSb = 1 / ODR.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of wake_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_wkup_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_wake_up_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.wake_dur = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_DUR, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Wake up duration event.1LSb = 1 / ODR.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of wake_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_wkup_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_wake_up_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, (uint8_t *) ®, 1); + *val = reg.wake_dur; + + return ret; +} + +/** + * @brief Data sent to wake-up interrupt function.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of usr_off_on_wu in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_wkup_feed_data_set(stmdev_ctx_t *ctx, + lis2doc_usr_off_on_wu_t val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.usr_off_on_wu = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Data sent to wake-up interrupt function.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of usr_off_on_wu in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_wkup_feed_data_get(stmdev_ctx_t *ctx, + lis2doc_usr_off_on_wu_t *val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + switch (reg.usr_off_on_wu) + { + case LIS2DOC_HP_FEED: + *val = LIS2DOC_HP_FEED; + break; + + case LIS2DOC_USER_OFFSET_FEED: + *val = LIS2DOC_USER_OFFSET_FEED; + break; + + default: + *val = LIS2DOC_HP_FEED; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Activity/Inactivity_Detection + * @brief This section groups all the functions concerning + * activity/inactivity detection. + * @{ + * + */ + +/** + * @brief Config activity / inactivity or + * stationary / motion detection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_on / stationary in + * reg WAKE_UP_THS / WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_act_mode_set(stmdev_ctx_t *ctx, + lis2doc_sleep_on_t val) +{ + lis2doc_wake_up_ths_t wake_up_ths; + lis2doc_wake_up_dur_t wake_up_dur; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_THS, + (uint8_t *) &wake_up_ths, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, + (uint8_t *) &wake_up_dur, 1); + } + + if (ret == 0) + { + wake_up_ths.sleep_on = (uint8_t) val & 0x01U; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_THS, + (uint8_t *) &wake_up_ths, 1); + } + + if (ret == 0) + { + wake_up_dur.stationary = ((uint8_t)val & 0x02U) >> 1; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_DUR, + (uint8_t *) &wake_up_dur, 1); + } + + return ret; +} + +/** + * @brief Config activity / inactivity or + * stationary / motion detection. [get] + * + * @param ctx read / write interface definitions + * @param val Get the values of sleep_on in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_act_mode_get(stmdev_ctx_t *ctx, + lis2doc_sleep_on_t *val) +{ + lis2doc_wake_up_ths_t wake_up_ths; + lis2doc_wake_up_dur_t wake_up_dur;; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_THS, + (uint8_t *) &wake_up_ths, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, + (uint8_t *) &wake_up_dur, 1); + + switch ((wake_up_dur.stationary << 1) + wake_up_ths.sleep_on) + { + case LIS2DOC_NO_DETECTION: + *val = LIS2DOC_NO_DETECTION; + break; + + case LIS2DOC_DETECT_ACT_INACT: + *val = LIS2DOC_DETECT_ACT_INACT; + break; + + case LIS2DOC_DETECT_STAT_MOTION: + *val = LIS2DOC_DETECT_STAT_MOTION; + break; + + default: + *val = LIS2DOC_NO_DETECTION; + break; + } + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode (1 LSb = 512 / ODR).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_act_sleep_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_wake_up_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.sleep_dur = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_DUR, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Duration to go in sleep mode (1 LSb = 512 / ODR).[get] + * + * @param ctx read / write interface definitions + * @param val change the values of sleep_dur in reg WAKE_UP_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_act_sleep_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_wake_up_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, (uint8_t *) ®, 1); + *val = reg.sleep_dur; + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Tap_Generator + * @brief This section groups all the functions that manage the tap + * and double tap event generation. + * @{ + * + */ + +/** + * @brief Threshold for tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_thsx in reg TAP_THS_X + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_threshold_x_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_tap_ths_x_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_thsx = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Threshold for tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_thsx in reg TAP_THS_X + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_threshold_x_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_tap_ths_x_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + *val = reg.tap_thsx; + + return ret; +} + +/** + * @brief Threshold for tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_thsy in reg TAP_THS_Y + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_threshold_y_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_tap_ths_y_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Y, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_thsy = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_Y, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Threshold for tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_thsy in reg TAP_THS_Y + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_threshold_y_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_tap_ths_y_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Y, (uint8_t *) ®, 1); + *val = reg.tap_thsy; + + return ret; +} + +/** + * @brief Selection of axis priority for TAP detection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_prior in reg TAP_THS_Y + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_axis_priority_set(stmdev_ctx_t *ctx, + lis2doc_tap_prior_t val) +{ + lis2doc_tap_ths_y_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Y, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_prior = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_Y, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Selection of axis priority for TAP detection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of tap_prior in reg TAP_THS_Y + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_axis_priority_get(stmdev_ctx_t *ctx, + lis2doc_tap_prior_t *val) +{ + lis2doc_tap_ths_y_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Y, (uint8_t *) ®, 1); + + switch (reg.tap_prior) + { + case LIS2DOC_XYZ: + *val = LIS2DOC_XYZ; + break; + + case LIS2DOC_YXZ: + *val = LIS2DOC_YXZ; + break; + + case LIS2DOC_XZY: + *val = LIS2DOC_XZY; + break; + + case LIS2DOC_ZYX: + *val = LIS2DOC_ZYX; + break; + + case LIS2DOC_YZX: + *val = LIS2DOC_YZX; + break; + + case LIS2DOC_ZXY: + *val = LIS2DOC_ZXY; + break; + + default: + *val = LIS2DOC_XYZ; + break; + } + + return ret; +} + +/** + * @brief Threshold for tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_thsz in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_threshold_z_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_thsz = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Threshold for tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_thsz in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_threshold_z_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + *val = reg.tap_thsz; + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_z_en in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_detection_on_z_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_z_en = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Enable Z direction in tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_z_en in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_detection_on_z_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + *val = reg.tap_z_en; + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_y_en in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_detection_on_y_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_y_en = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Enable Y direction in tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_y_en in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_detection_on_y_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + *val = reg.tap_y_en; + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_x_en in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_detection_on_x_set(stmdev_ctx_t *ctx, + uint8_t val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.tap_x_en = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Enable X direction in tap recognition.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of tap_x_en in reg TAP_THS_Z + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_detection_on_x_get(stmdev_ctx_t *ctx, + uint8_t *val) +{ + lis2doc_tap_ths_z_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_Z, (uint8_t *) ®, 1); + *val = reg.tap_x_en; + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an overthreshold signal + * detection to be recognized as a tap event. The default value + * of these bits is 00b which corresponds to 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different value, 1LSB + * corresponds to 8*ODR_XL time.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of shock in reg INT_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_shock_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_int_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.shock = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Maximum duration is the maximum time of an overthreshold signal + * detection to be recognized as a tap event. The default value + * of these bits is 00b which corresponds to 4*ODR_XL time. + * If the SHOCK[1:0] bits are set to a different value, 1LSB + * corresponds to 8*ODR_XL time.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of shock in reg INT_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_shock_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_int_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + *val = reg.shock; + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected tap in which + * there must not be any overthreshold event. + * The default value of these bits is 00b which corresponds + * to 2*ODR_XL time. If the QUIET[1:0] bits are set to a different + * value, 1LSB corresponds to 4*ODR_XL time.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of quiet in reg INT_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_quiet_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_int_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.quiet = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Quiet time is the time after the first detected tap in which + * there must not be any overthreshold event. + * The default value of these bits is 00b which corresponds + * to 2*ODR_XL time. If the QUIET[1:0] bits are set to a different + * value, 1LSB corresponds to 4*ODR_XL time.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of quiet in reg INT_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_quiet_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_int_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + *val = reg.quiet; + + return ret; +} + +/** + * @brief When double tap recognition is enabled, this register expresses + * the maximum time between two consecutive detected taps to + * determine a double tap event. + * The default value of these bits is 0000b which corresponds + * to 16*ODR_XL time. If the DUR[3:0] bits are set to a different + * value, 1LSB corresponds to 32*ODR_XL time.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of latency in reg INT_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_int_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.latency = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief When double tap recognition is enabled, this register expresses + * the maximum time between two consecutive detected taps to + * determine a double tap event. + * The default value of these bits is 0000b which corresponds + * to 16*ODR_XL time. If the DUR[3:0] bits are set to a different + * value, 1LSB corresponds to 32*ODR_XL time.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of latency in reg INT_DUR + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_int_dur_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_INT_DUR, (uint8_t *) ®, 1); + *val = reg.latency; + + return ret; +} + +/** + * @brief Single/double-tap event enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of single_double_tap in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_mode_set(stmdev_ctx_t *ctx, + lis2doc_single_double_tap_t val) +{ + lis2doc_wake_up_ths_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_THS, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.single_double_tap = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_THS, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Single/double-tap event enable.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of single_double_tap in reg WAKE_UP_THS + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_mode_get(stmdev_ctx_t *ctx, + lis2doc_single_double_tap_t *val) +{ + lis2doc_wake_up_ths_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_THS, (uint8_t *) ®, 1); + + switch (reg.single_double_tap) + { + case LIS2DOC_ONLY_SINGLE: + *val = LIS2DOC_ONLY_SINGLE; + break; + + case LIS2DOC_BOTH_SINGLE_DOUBLE: + *val = LIS2DOC_BOTH_SINGLE_DOUBLE; + break; + + default: + *val = LIS2DOC_ONLY_SINGLE; + break; + } + + return ret; +} + +/** + * @brief Read the tap / double tap source register.[get] + * + * @param ctx read / write interface definitions + * @param lis2doc_tap_src: union of registers from TAP_SRC to + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_tap_src_get(stmdev_ctx_t *ctx, + lis2doc_tap_src_t *val) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_SRC, (uint8_t *) val, 1); + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Six_Position_Detection(6D/4D) + * @brief This section groups all the functions concerning six + * position detection (6D). + * @{ + * + */ + +/** + * @brief Threshold for 4D/6D function.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of 6d_ths in reg TAP_THS_X + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_6d_threshold_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_tap_ths_x_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg._6d_ths = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Threshold for 4D/6D function.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of 6d_ths in reg TAP_THS_X + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_6d_threshold_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_tap_ths_x_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + *val = reg._6d_ths; + + return ret; +} + +/** + * @brief 4D orientation detection enable.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of 4d_en in reg TAP_THS_X + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_4d_mode_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_tap_ths_x_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg._4d_en = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief 4D orientation detection enable.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of 4d_en in reg TAP_THS_X + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_4d_mode_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_tap_ths_x_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_TAP_THS_X, (uint8_t *) ®, 1); + *val = reg._4d_en; + + return ret; +} + +/** + * @brief Read the 6D tap source register.[get] + * + * @param ctx read / write interface definitions + * @param val union of registers from SIXD_SRC + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_6d_src_get(stmdev_ctx_t *ctx, + lis2doc_sixd_src_t *val) +{ + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_SIXD_SRC, (uint8_t *) val, 1); + + return ret; +} +/** + * @brief Data sent to 6D interrupt function.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of lpass_on6d in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_6d_feed_data_set(stmdev_ctx_t *ctx, + lis2doc_lpass_on6d_t val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.lpass_on6d = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Data sent to 6D interrupt function.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of lpass_on6d in reg CTRL_REG7 + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_6d_feed_data_get(stmdev_ctx_t *ctx, + lis2doc_lpass_on6d_t *val) +{ + lis2doc_ctrl_reg7_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_CTRL_REG7, (uint8_t *) ®, 1); + + switch (reg.lpass_on6d) + { + case LIS2DOC_ODR_DIV_2_FEED: + *val = LIS2DOC_ODR_DIV_2_FEED; + break; + + case LIS2DOC_LPF2_FEED: + *val = LIS2DOC_LPF2_FEED; + break; + + default: + *val = LIS2DOC_ODR_DIV_2_FEED; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Free_Fall + * @brief This section group all the functions concerning + * the free fall detection. + * @{ + * + */ + +/** + * @brief Free fall duration event(1LSb = 1 / ODR).[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ff_dur in reg + * WAKE_UP_DUR /F REE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_ff_dur_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_wake_up_dur_t wake_up_dur; + lis2doc_free_fall_t free_fall; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, + (uint8_t *) &wake_up_dur, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_FREE_FALL, + (uint8_t *) &free_fall, 1); + } + + if (ret == 0) + { + wake_up_dur.ff_dur = ((uint8_t) val & 0x20U) >> 5; + free_fall.ff_dur = (uint8_t) val & 0x1FU; + ret = lis2doc_write_reg(ctx, LIS2DOC_WAKE_UP_DUR, + (uint8_t *) &wake_up_dur, 1); + } + + if (ret == 0) + { + ret = lis2doc_write_reg(ctx, LIS2DOC_FREE_FALL, + (uint8_t *) &free_fall, 1); + } + + return ret; +} + +/** + * @brief Free fall duration event(1LSb = 1 / ODR).[get] + * + * @param ctx read / write interface definitions + * @param val change the values of ff_dur in + * reg WAKE_UP_DUR /F REE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_ff_dur_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_wake_up_dur_t wake_up_dur; + lis2doc_free_fall_t free_fall; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_WAKE_UP_DUR, + (uint8_t *) &wake_up_dur, 1); + + if (ret == 0) + { + ret = lis2doc_read_reg(ctx, LIS2DOC_FREE_FALL, + (uint8_t *) &free_fall, 1); + *val = (wake_up_dur.ff_dur << 5) + free_fall.ff_dur; + } + + return ret; +} + +/** + * @brief Free fall threshold setting.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of ff_ths in reg FREE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_ff_threshold_set(stmdev_ctx_t *ctx, + lis2doc_ff_ths_t val) +{ + lis2doc_free_fall_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FREE_FALL, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.ff_ths = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_FREE_FALL, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief Free fall threshold setting.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of ff_ths in reg FREE_FALL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_ff_threshold_get(stmdev_ctx_t *ctx, + lis2doc_ff_ths_t *val) +{ + lis2doc_free_fall_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FREE_FALL, (uint8_t *) ®, 1); + + switch (reg.ff_ths) + { + case LIS2DOC_FF_TSH_5LSb_FS2g: + *val = LIS2DOC_FF_TSH_5LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_7LSb_FS2g: + *val = LIS2DOC_FF_TSH_7LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_8LSb_FS2g: + *val = LIS2DOC_FF_TSH_8LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_10LSb_FS2g: + *val = LIS2DOC_FF_TSH_10LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_11LSb_FS2g: + *val = LIS2DOC_FF_TSH_11LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_13LSb_FS2g: + *val = LIS2DOC_FF_TSH_13LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_15LSb_FS2g: + *val = LIS2DOC_FF_TSH_15LSb_FS2g; + break; + + case LIS2DOC_FF_TSH_16LSb_FS2g: + *val = LIS2DOC_FF_TSH_16LSb_FS2g; + break; + + default: + *val = LIS2DOC_FF_TSH_5LSb_FS2g; + break; + } + + return ret; +} + +/** + * @} + * + */ + +/** + * @defgroup LIS2DOC_Fifo + * @brief This section group all the functions concerning the fifo usage + * @{ + * + */ + +/** + * @brief FIFO watermark level selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fth in reg FIFO_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_watermark_set(stmdev_ctx_t *ctx, uint8_t val) +{ + lis2doc_fifo_ctrl_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_CTRL, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.fth = val; + ret = lis2doc_write_reg(ctx, LIS2DOC_FIFO_CTRL, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief FIFO watermark level selection.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fth in reg FIFO_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_watermark_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_fifo_ctrl_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_CTRL, (uint8_t *) ®, 1); + *val = reg.fth; + + return ret; +} + +/** + * @brief FIFO mode selection.[set] + * + * @param ctx read / write interface definitions + * @param val change the values of fmode in reg FIFO_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_mode_set(stmdev_ctx_t *ctx, + lis2doc_fmode_t val) +{ + lis2doc_fifo_ctrl_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_CTRL, (uint8_t *) ®, 1); + + if (ret == 0) + { + reg.fmode = (uint8_t) val; + ret = lis2doc_write_reg(ctx, LIS2DOC_FIFO_CTRL, (uint8_t *) ®, 1); + } + + return ret; +} + +/** + * @brief FIFO mode selection.[get] + * + * @param ctx read / write interface definitions + * @param val Get the values of fmode in reg FIFO_CTRL + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_mode_get(stmdev_ctx_t *ctx, + lis2doc_fmode_t *val) +{ + lis2doc_fifo_ctrl_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_CTRL, (uint8_t *) ®, 1); + + switch (reg.fmode) + { + case LIS2DOC_BYPASS_MODE: + *val = LIS2DOC_BYPASS_MODE; + break; + + case LIS2DOC_FIFO_MODE: + *val = LIS2DOC_FIFO_MODE; + break; + + case LIS2DOC_STREAM_TO_FIFO_MODE: + *val = LIS2DOC_STREAM_TO_FIFO_MODE; + break; + + case LIS2DOC_BYPASS_TO_STREAM_MODE: + *val = LIS2DOC_BYPASS_TO_STREAM_MODE; + break; + + case LIS2DOC_STREAM_MODE: + *val = LIS2DOC_STREAM_MODE; + break; + + default: + *val = LIS2DOC_BYPASS_MODE; + break; + } + + return ret; +} + +/** + * @brief Number of unread samples stored in FIFO.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of diff in reg FIFO_SAMPLES + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_data_level_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_fifo_samples_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_SAMPLES, (uint8_t *) ®, 1); + *val = reg.diff; + + return ret; +} +/** + * @brief FIFO overrun status.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_ovr in reg FIFO_SAMPLES + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_ovr_flag_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_fifo_samples_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_SAMPLES, (uint8_t *) ®, 1); + *val = reg.fifo_ovr; + + return ret; +} +/** + * @brief FIFO threshold status flag.[get] + * + * @param ctx read / write interface definitions + * @param val change the values of fifo_fth in reg FIFO_SAMPLES + * @retval interface status (MANDATORY: return 0 -> no Error) + * + */ +int32_t lis2doc_fifo_wtm_flag_get(stmdev_ctx_t *ctx, uint8_t *val) +{ + lis2doc_fifo_samples_t reg; + int32_t ret; + + ret = lis2doc_read_reg(ctx, LIS2DOC_FIFO_SAMPLES, (uint8_t *) ®, 1); + *val = reg.fifo_fth; + + return ret; +} + +/** + * @} + * + */ + +/** + * @} + * + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/driver/lis2doc_reg.h b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/driver/lis2doc_reg.h new file mode 100644 index 000000000..285f3d760 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/driver/lis2doc_reg.h @@ -0,0 +1,1071 @@ +/** + ****************************************************************************** + * @file lis2doc_reg.h + * @author Sensors Software Solution Team + * @brief This file contains all the functions prototypes for the + * lis2doc_reg.c driver. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef LIS2DOC_REGS_H +#define LIS2DOC_REGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include + +/** @addtogroup LIS2DOC + * @{ + * + */ + +/** @defgroup Endianness definitions + * @{ + * + */ + +#ifndef DRV_BYTE_ORDER +#ifndef __BYTE_ORDER__ + +#define DRV_LITTLE_ENDIAN 1234 +#define DRV_BIG_ENDIAN 4321 + +/** if _BYTE_ORDER is not defined, choose the endianness of your architecture + * by uncommenting the define which fits your platform endianness + */ +//#define DRV_BYTE_ORDER DRV_BIG_ENDIAN +#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN + +#else /* defined __BYTE_ORDER__ */ + +#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#define DRV_BYTE_ORDER __BYTE_ORDER__ + +#endif /* __BYTE_ORDER__*/ +#endif /* DRV_BYTE_ORDER */ + +/** + * @} + * + */ + +/** @defgroup STMicroelectronics sensors common types + * @{ + * + */ + +#ifndef MEMS_SHARED_TYPES +#define MEMS_SHARED_TYPES + +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t bit0 : 1; + uint8_t bit1 : 1; + uint8_t bit2 : 1; + uint8_t bit3 : 1; + uint8_t bit4 : 1; + uint8_t bit5 : 1; + uint8_t bit6 : 1; + uint8_t bit7 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bit7 : 1; + uint8_t bit6 : 1; + uint8_t bit5 : 1; + uint8_t bit4 : 1; + uint8_t bit3 : 1; + uint8_t bit2 : 1; + uint8_t bit1 : 1; + uint8_t bit0 : 1; +#endif /* DRV_BYTE_ORDER */ +} bitwise_t; + +#define PROPERTY_DISABLE (0U) +#define PROPERTY_ENABLE (1U) + +/** @addtogroup Interfaces_Functions + * @brief This section provide a set of functions used to read and + * write a generic register of the device. + * MANDATORY: return 0 -> no Error. + * @{ + * + */ + +typedef int32_t (*stmdev_write_ptr)(void *, uint8_t, const uint8_t *, uint16_t); +typedef int32_t (*stmdev_read_ptr)(void *, uint8_t, uint8_t *, uint16_t); +typedef void (*stmdev_mdelay_ptr)(uint32_t millisec); + +typedef struct +{ + /** Component mandatory fields **/ + stmdev_write_ptr write_reg; + stmdev_read_ptr read_reg; + /** Component optional fields **/ + stmdev_mdelay_ptr mdelay; + /** Customizable optional pointer **/ + void *handle; +} stmdev_ctx_t; + +/** + * @} + * + */ + +#endif /* MEMS_SHARED_TYPES */ + +#ifndef MEMS_UCF_SHARED_TYPES +#define MEMS_UCF_SHARED_TYPES + +/** @defgroup Generic address-data structure definition + * @brief This structure is useful to load a predefined configuration + * of a sensor. + * You can create a sensor configuration by your own or using + * Unico / Unicleo tools available on STMicroelectronics + * web site. + * + * @{ + * + */ + +typedef struct +{ + uint8_t address; + uint8_t data; +} ucf_line_t; + +/** + * @} + * + */ + +#endif /* MEMS_UCF_SHARED_TYPES */ + +/** + * @} + * + */ + +/** @defgroup LIS2DOC_Infos + * @{ + * + */ + +/** I2C Device Address 8 bit format if SA0=0 -> 31 if SA0=1 -> 33 **/ +#define LIS2DOC_I2C_ADD_L 0x31U +#define LIS2DOC_I2C_ADD_H 0x33U + +/** Device Identification (Who am I) **/ +#define LIS2DOC_ID 0x44U + +/** + * @} + * + */ + +#define LIS2DOC_OUT_T_L 0x0DU +#define LIS2DOC_OUT_T_H 0x0EU +#define LIS2DOC_WHO_AM_I 0x0FU +#define LIS2DOC_CTRL1 0x20U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_00 : 1; + uint8_t lpm_en : 1; + uint8_t hpm_en : 1; + uint8_t sdrc_en : 1; + uint8_t odr : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t odr : 4; + uint8_t sdrc_en : 1; + uint8_t hpm_en : 1; + uint8_t lpm_en : 1; + uint8_t not_used_00 : 1; +#endif /* DRV_BYTE_ORDER */ + +} lis2doc_ctrl1_t; + +#define LIS2DOC_CTRL2 0x21U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sim : 1; + uint8_t i2c_disable : 1; + uint8_t if_add_inc : 1; + uint8_t bdu : 1; + uint8_t cs_pu_disc : 1; + uint8_t not_used_01 : 1; + uint8_t soft_reset : 1; + uint8_t boot : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t boot : 1; + uint8_t soft_reset : 1; + uint8_t not_used_01 : 1; + uint8_t cs_pu_disc : 1; + uint8_t bdu : 1; + uint8_t if_add_inc : 1; + uint8_t i2c_disable : 1; + uint8_t sim : 1; +#endif /* DRV_BYTE_ORDER */ + +} lis2doc_ctrl2_t; + +#define LIS2DOC_CTRL3 0x22U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN +uint8_t slp_mode : + 2; /* slp_mode_sel + slp_mode_1 */ + uint8_t not_used_01 : 1; + uint8_t h_lactive : 1; + uint8_t lir : 1; + uint8_t pp_od : 1; + uint8_t st : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t st : 2; + uint8_t pp_od : 1; + uint8_t lir : 1; + uint8_t h_lactive : 1; + uint8_t not_used_01 : 1; +uint8_t slp_mode : + 2; /* slp_mode_sel + slp_mode_1 */ +#endif /* DRV_BYTE_ORDER */ + +} lis2doc_ctrl3_t; + +#define LIS2DOC_CTRL4_INT1_PAD_CTRL 0x23U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int1_drdy : 1; + uint8_t int1_fth : 1; + uint8_t int1_diff5 : 1; + uint8_t int1_tap : 1; + uint8_t int1_ff : 1; + uint8_t int1_wu : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_6d : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int1_6d : 1; + uint8_t int1_single_tap : 1; + uint8_t int1_wu : 1; + uint8_t int1_ff : 1; + uint8_t int1_tap : 1; + uint8_t int1_diff5 : 1; + uint8_t int1_fth : 1; + uint8_t int1_drdy : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_ctrl4_int1_pad_ctrl_t; + +#define LIS2DOC_CTRL5_INT2_PAD_CTRL 0x24U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t int2_drdy : 1; + uint8_t int2_fth : 1; + uint8_t int2_diff5 : 1; + uint8_t int2_ovr : 1; + uint8_t int2_drdy_t : 1; + uint8_t int2_boot : 1; + uint8_t int2_sleep_chg : 1; + uint8_t int2_sleep_state : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t int2_sleep_state : 1; + uint8_t int2_sleep_chg : 1; + uint8_t int2_boot : 1; + uint8_t int2_drdy_t : 1; + uint8_t int2_ovr : 1; + uint8_t int2_diff5 : 1; + uint8_t int2_fth : 1; + uint8_t int2_drdy : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_ctrl5_int2_pad_ctrl_t; + +#define LIS2DOC_CTRL6 0x25U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t not_used_01 : 2; + uint8_t low_noise : 1; + uint8_t fds : 1; + uint8_t fs : 2; + uint8_t bw_filt : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t bw_filt : 2; + uint8_t fs : 2; + uint8_t fds : 1; + uint8_t low_noise : 1; + uint8_t not_used_01 : 2; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_ctrl6_t; + +#define LIS2DOC_OUT_T 0x26U +#define LIS2DOC_STATUS 0x27U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t drdy : 1; + uint8_t ff_ia : 1; + uint8_t _6d_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t sleep_state : 1; + uint8_t wu_ia : 1; + uint8_t fifo_ths : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fifo_ths : 1; + uint8_t wu_ia : 1; + uint8_t sleep_state : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t _6d_ia : 1; + uint8_t ff_ia : 1; + uint8_t drdy : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_status_t; + +#define LIS2DOC_OUT_X_L 0x28U +#define LIS2DOC_OUT_X_H 0x29U +#define LIS2DOC_OUT_Y_L 0x2AU +#define LIS2DOC_OUT_Y_H 0x2BU +#define LIS2DOC_OUT_Z_L 0x2CU +#define LIS2DOC_OUT_Z_H 0x2DU +#define LIS2DOC_FIFO_CTRL 0x2EU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t fth : 5; + uint8_t fmode : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fmode : 3; + uint8_t fth : 5; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_fifo_ctrl_t; + +#define LIS2DOC_FIFO_SAMPLES 0x2FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t diff : 6; + uint8_t fifo_ovr : 1; + uint8_t fifo_fth : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t fifo_fth : 1; + uint8_t fifo_ovr : 1; + uint8_t diff : 6; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_fifo_samples_t; + +#define LIS2DOC_TAP_THS_X 0x30U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_thsx : 5; + uint8_t _6d_ths : 2; + uint8_t _4d_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t _4d_en : 1; + uint8_t _6d_ths : 2; + uint8_t tap_thsx : 5; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_tap_ths_x_t; + +#define LIS2DOC_TAP_THS_Y 0x31U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_thsy : 5; + uint8_t tap_prior : 3; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t tap_prior : 3; + uint8_t tap_thsy : 5; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_tap_ths_y_t; + +#define LIS2DOC_TAP_THS_Z 0x32U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t tap_thsz : 5; + uint8_t tap_z_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_x_en : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t tap_x_en : 1; + uint8_t tap_y_en : 1; + uint8_t tap_z_en : 1; + uint8_t tap_thsz : 5; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_tap_ths_z_t; + +#define LIS2DOC_INT_DUR 0x33U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t shock : 2; + uint8_t quiet : 2; + uint8_t latency : 4; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t latency : 4; + uint8_t quiet : 2; + uint8_t shock : 2; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_int_dur_t; + +#define LIS2DOC_WAKE_UP_THS 0x34U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t wk_ths : 6; + uint8_t sleep_on : 1; + uint8_t single_double_tap : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t single_double_tap : 1; + uint8_t sleep_on : 1; + uint8_t wk_ths : 6; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_wake_up_ths_t; + +#define LIS2DOC_WAKE_UP_DUR 0x35U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t sleep_dur : 4; + uint8_t stationary : 1; + uint8_t wake_dur : 2; + uint8_t ff_dur : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 1; + uint8_t wake_dur : 2; + uint8_t stationary : 1; + uint8_t sleep_dur : 4; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_wake_up_dur_t; + +#define LIS2DOC_FREE_FALL 0x36U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ff_ths : 3; + uint8_t ff_dur : 5; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ff_dur : 5; + uint8_t ff_ths : 3; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_free_fall_t; + +#define LIS2DOC_STATUS_DUP 0x37U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t drdy : 1; + uint8_t ff_ia : 1; + uint8_t _6d_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t sleep_state_ia : 1; + uint8_t drdy_t : 1; + uint8_t ovr : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t ovr : 1; + uint8_t drdy_t : 1; + uint8_t sleep_state_ia : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t _6d_ia : 1; + uint8_t ff_ia : 1; + uint8_t drdy : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_status_dup_t; + +#define LIS2DOC_WAKE_UP_SRC 0x38U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_wu : 1; + uint8_t y_wu : 1; + uint8_t x_wu : 1; + uint8_t wu_ia : 1; + uint8_t sleep_state_ia : 1; + uint8_t ff_ia : 1; + uint8_t not_used_01 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 2; + uint8_t ff_ia : 1; + uint8_t sleep_state_ia : 1; + uint8_t wu_ia : 1; + uint8_t x_wu : 1; + uint8_t y_wu : 1; + uint8_t z_wu : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_wake_up_src_t; + +#define LIS2DOC_TAP_SRC 0x39U +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t z_tap : 1; + uint8_t y_tap : 1; + uint8_t x_tap : 1; + uint8_t tap_sign : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t tap_ia : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t tap_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t tap_sign : 1; + uint8_t x_tap : 1; + uint8_t y_tap : 1; + uint8_t z_tap : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_tap_src_t; + +#define LIS2DOC_SIXD_SRC 0x3AU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t xl : 1; + uint8_t xh : 1; + uint8_t yl : 1; + uint8_t yh : 1; + uint8_t zl : 1; + uint8_t zh : 1; + uint8_t _6d_ia : 1; + uint8_t not_used_01 : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 1; + uint8_t _6d_ia : 1; + uint8_t zh : 1; + uint8_t zl : 1; + uint8_t yh : 1; + uint8_t xh : 1; + uint8_t yl : 1; + uint8_t xh : 1; + uint8_t xl : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_sixd_src_t; + +#define LIS2DOC_ALL_INT_SRC 0x3BU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t ff_ia : 1; + uint8_t wu_ia : 1; + uint8_t single_tap : 1; + uint8_t double_tap : 1; + uint8_t _6d_ia : 1; + uint8_t sleep_change_ia : 1; + uint8_t not_used_01 : 2; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t not_used_01 : 2; + uint8_t sleep_change_ia : 1; + uint8_t _6d_ia : 1; + uint8_t double_tap : 1; + uint8_t single_tap : 1; + uint8_t wu_ia : 1; + uint8_t ff_ia : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_all_int_src_t; + +#define LIS2DOC_X_OFS_USR 0x3CU +#define LIS2DOC_Y_OFS_USR 0x3DU +#define LIS2DOC_Z_OFS_USR 0x3EU +#define LIS2DOC_CTRL_REG7 0x3FU +typedef struct +{ +#if DRV_BYTE_ORDER == DRV_LITTLE_ENDIAN + uint8_t lpass_on6d : 1; + uint8_t hp_ref_mode : 1; + uint8_t usr_off_w : 1; + uint8_t usr_off_on_wu : 1; + uint8_t usr_off_on_out : 1; + uint8_t interrupts_enable : 1; + uint8_t int2_on_int1 : 1; + uint8_t drdy_pulsed : 1; +#elif DRV_BYTE_ORDER == DRV_BIG_ENDIAN + uint8_t drdy_pulsed : 1; + uint8_t int2_on_int1 : 1; + uint8_t interrupts_enable : 1; + uint8_t usr_off_on_out : 1; + uint8_t usr_off_on_wu : 1; + uint8_t usr_off_w : 1; + uint8_t hp_ref_mode : 1; + uint8_t lpass_on6d : 1; +#endif /* DRV_BYTE_ORDER */ +} lis2doc_ctrl_reg7_t; + +/** + * @defgroup LIS2DOC_Register_Union + * @brief This union group all the registers having a bit-field + * description. + * This union is useful but it's not needed by the driver. + * + * REMOVING this union you are compliant with: + * MISRA-C 2012 [Rule 19.2] -> " Union are not allowed " + * + * @{ + * + */ +typedef union +{ + lis2doc_ctrl1_t ctrl1; + lis2doc_ctrl2_t ctrl2; + lis2doc_ctrl3_t ctrl3; + lis2doc_ctrl4_int1_pad_ctrl_t ctrl4_int1_pad_ctrl; + lis2doc_ctrl5_int2_pad_ctrl_t ctrl5_int2_pad_ctrl; + lis2doc_ctrl6_t ctrl6; + lis2doc_status_t status; + lis2doc_fifo_ctrl_t fifo_ctrl; + lis2doc_fifo_samples_t fifo_samples; + lis2doc_tap_ths_x_t tap_ths_x; + lis2doc_tap_ths_y_t tap_ths_y; + lis2doc_tap_ths_z_t tap_ths_z; + lis2doc_int_dur_t int_dur; + lis2doc_wake_up_ths_t wake_up_ths; + lis2doc_wake_up_dur_t wake_up_dur; + lis2doc_free_fall_t free_fall; + lis2doc_status_dup_t status_dup; + lis2doc_wake_up_src_t wake_up_src; + lis2doc_tap_src_t tap_src; + lis2doc_sixd_src_t sixd_src; + lis2doc_all_int_src_t all_int_src; + lis2doc_ctrl_reg7_t ctrl_reg7; + bitwise_t bitwise; + uint8_t byte; +} lis2doc_reg_t; + +/** + * @} + * + */ + +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ + +/* + * These are the basic platform dependent I/O routines to read + * and write device registers connected on a standard bus. + * The driver keeps offering a default implementation based on function + * pointers to read/write routines for backward compatibility. + * The __weak directive allows the final application to overwrite + * them with a custom implementation. + */ + +int32_t lis2doc_read_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len); +int32_t lis2doc_write_reg(stmdev_ctx_t *ctx, uint8_t reg, + uint8_t *data, + uint16_t len); + +float_t lis2doc_from_fs2_to_mg(int16_t lsb); +float_t lis2doc_from_fs4_to_mg(int16_t lsb); +float_t lis2doc_from_fs8_to_mg(int16_t lsb); +float_t lis2doc_from_fs16_to_mg(int16_t lsb); + +float_t lis2doc_from_fs2_lp1_to_mg(int16_t lsb); +float_t lis2doc_from_fs4_lp1_to_mg(int16_t lsb); +float_t lis2doc_from_fs8_lp1_to_mg(int16_t lsb); +float_t lis2doc_from_fs16_lp1_to_mg(int16_t lsb); + +float_t lis2doc_from_lsb_to_celsius(int16_t lsb); + +typedef struct +{ + uint8_t sdrc : 1; + uint8_t lpm : 1; + uint8_t hpm : 1; + uint8_t low_noise : 1; +} lis2doc_mode_t; +int32_t lis2doc_power_mode_set(stmdev_ctx_t *ctx, + lis2doc_mode_t val); +int32_t lis2doc_power_mode_get(stmdev_ctx_t *ctx, + lis2doc_mode_t *val); + +typedef enum +{ + LIS2DOC_XL_ODR_OFF = 0x00, + LIS2DOC_XL_ODR_1Hz6_LP_ONLY = 0x01, + LIS2DOC_XL_ODR_12Hz5 = 0x02, + LIS2DOC_XL_ODR_25Hz = 0x03, + LIS2DOC_XL_ODR_50Hz = 0x04, + LIS2DOC_XL_ODR_100Hz = 0x05, + LIS2DOC_XL_ODR_200Hz = 0x06, + LIS2DOC_XL_ODR_400Hz = 0x07, + LIS2DOC_XL_ODR_800Hz = 0x08, + LIS2DOC_XL_ODR_1k6Hz = 0x09, + LIS2DOC_XL_SET_SW_TRIG = 0x32, /* Use this only in SINGLE mode */ + LIS2DOC_XL_SET_PIN_TRIG = 0x12, /* Use this only in SINGLE mode */ +} lis2doc_odr_t; +int32_t lis2doc_data_rate_set(stmdev_ctx_t *ctx, lis2doc_odr_t val); +int32_t lis2doc_data_rate_get(stmdev_ctx_t *ctx, + lis2doc_odr_t *val); + +int32_t lis2doc_block_data_update_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lis2doc_block_data_update_get(stmdev_ctx_t *ctx, + uint8_t *val); + +typedef enum +{ + LIS2DOC_2g = 0, + LIS2DOC_4g = 1, + LIS2DOC_8g = 2, + LIS2DOC_16g = 3, +} lis2doc_fs_t; +int32_t lis2doc_full_scale_set(stmdev_ctx_t *ctx, lis2doc_fs_t val); +int32_t lis2doc_full_scale_get(stmdev_ctx_t *ctx, + lis2doc_fs_t *val); + +int32_t lis2doc_status_reg_get(stmdev_ctx_t *ctx, + lis2doc_status_t *val); + +int32_t lis2doc_flag_data_ready_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef struct +{ + lis2doc_status_dup_t status_dup; + lis2doc_wake_up_src_t wake_up_src; + lis2doc_tap_src_t tap_src; + lis2doc_sixd_src_t sixd_src; + lis2doc_all_int_src_t all_int_src; +} lis2doc_all_sources_t; +int32_t lis2doc_all_sources_get(stmdev_ctx_t *ctx, + lis2doc_all_sources_t *val); + +int32_t lis2doc_usr_offset_x_set(stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lis2doc_usr_offset_x_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lis2doc_usr_offset_y_set(stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lis2doc_usr_offset_y_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lis2doc_usr_offset_z_set(stmdev_ctx_t *ctx, uint8_t *buff); +int32_t lis2doc_usr_offset_z_get(stmdev_ctx_t *ctx, uint8_t *buff); + +typedef enum +{ + LIS2DOC_LSb_977ug = 0, + LIS2DOC_LSb_15mg6 = 1, +} lis2doc_usr_off_w_t; +int32_t lis2doc_offset_weight_set(stmdev_ctx_t *ctx, + lis2doc_usr_off_w_t val); +int32_t lis2doc_offset_weight_get(stmdev_ctx_t *ctx, + lis2doc_usr_off_w_t *val); + +int32_t lis2doc_temperature_raw_get(stmdev_ctx_t *ctx, int16_t *val); + +int32_t lis2doc_acceleration_raw_get(stmdev_ctx_t *ctx, + int16_t *val); + +int32_t lis2doc_device_id_get(stmdev_ctx_t *ctx, uint8_t *buff); + +int32_t lis2doc_auto_increment_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_auto_increment_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_reset_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_reset_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_boot_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_boot_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_XL_ST_DISABLE = 0, + LIS2DOC_XL_ST_POSITIVE = 1, + LIS2DOC_XL_ST_NEGATIVE = 2, +} lis2doc_st_t; +int32_t lis2doc_self_test_set(stmdev_ctx_t *ctx, lis2doc_st_t val); +int32_t lis2doc_self_test_get(stmdev_ctx_t *ctx, lis2doc_st_t *val); + +typedef enum +{ + LIS2DOC_DRDY_LATCHED = 0, + LIS2DOC_DRDY_PULSED = 1, +} lis2doc_drdy_pulsed_t; +int32_t lis2doc_data_ready_mode_set(stmdev_ctx_t *ctx, + lis2doc_drdy_pulsed_t val); +int32_t lis2doc_data_ready_mode_get(stmdev_ctx_t *ctx, + lis2doc_drdy_pulsed_t *val); + +typedef enum +{ + LIS2DOC_LPF_ON_OUT = 0x00, + LIS2DOC_USER_OFFSET_ON_OUT = 0x01, + LIS2DOC_HIGH_PASS_ON_OUT = 0x10, +} lis2doc_fds_t; +int32_t lis2doc_filter_path_set(stmdev_ctx_t *ctx, + lis2doc_fds_t val); +int32_t lis2doc_filter_path_get(stmdev_ctx_t *ctx, + lis2doc_fds_t *val); + +typedef enum +{ + LIS2DOC_ODR_DIV_2 = 0, + LIS2DOC_ODR_DIV_4 = 1, + LIS2DOC_ODR_DIV_10 = 2, + LIS2DOC_ODR_DIV_20 = 3, +} lis2doc_bw_filt_t; +int32_t lis2doc_filter_bandwidth_set(stmdev_ctx_t *ctx, + lis2doc_bw_filt_t val); +int32_t lis2doc_filter_bandwidth_get(stmdev_ctx_t *ctx, + lis2doc_bw_filt_t *val); + +int32_t lis2doc_reference_mode_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_reference_mode_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_SPI_4_WIRE = 0, + LIS2DOC_SPI_3_WIRE = 1, +} lis2doc_sim_t; +int32_t lis2doc_spi_mode_set(stmdev_ctx_t *ctx, lis2doc_sim_t val); +int32_t lis2doc_spi_mode_get(stmdev_ctx_t *ctx, lis2doc_sim_t *val); + +typedef enum +{ + LIS2DOC_I2C_ENABLE = 0, + LIS2DOC_I2C_DISABLE = 1, +} lis2doc_i2c_disable_t; +int32_t lis2doc_i2c_interface_set(stmdev_ctx_t *ctx, + lis2doc_i2c_disable_t val); +int32_t lis2doc_i2c_interface_get(stmdev_ctx_t *ctx, + lis2doc_i2c_disable_t *val); + +typedef enum +{ + LIS2DOC_PULL_UP_CONNECT = 0, + LIS2DOC_PULL_UP_DISCONNECT = 1, +} lis2doc_cs_pu_disc_t; +int32_t lis2doc_cs_mode_set(stmdev_ctx_t *ctx, + lis2doc_cs_pu_disc_t val); +int32_t lis2doc_cs_mode_get(stmdev_ctx_t *ctx, + lis2doc_cs_pu_disc_t *val); + +typedef enum +{ + LIS2DOC_ACTIVE_HIGH = 0, + LIS2DOC_ACTIVE_LOW = 1, +} lis2doc_h_lactive_t; +int32_t lis2doc_pin_polarity_set(stmdev_ctx_t *ctx, + lis2doc_h_lactive_t val); +int32_t lis2doc_pin_polarity_get(stmdev_ctx_t *ctx, + lis2doc_h_lactive_t *val); + +typedef enum +{ + LIS2DOC_INT_PULSED = 0, + LIS2DOC_INT_LATCHED = 1, +} lis2doc_lir_t; +int32_t lis2doc_int_notification_set(stmdev_ctx_t *ctx, + lis2doc_lir_t val); +int32_t lis2doc_int_notification_get(stmdev_ctx_t *ctx, + lis2doc_lir_t *val); + +typedef enum +{ + LIS2DOC_PUSH_PULL = 0, + LIS2DOC_OPEN_DRAIN = 1, +} lis2doc_pp_od_t; +int32_t lis2doc_pin_mode_set(stmdev_ctx_t *ctx, + lis2doc_pp_od_t val); +int32_t lis2doc_pin_mode_get(stmdev_ctx_t *ctx, + lis2doc_pp_od_t *val); + +int32_t lis2doc_pin_int1_route_set(stmdev_ctx_t *ctx, + lis2doc_ctrl4_int1_pad_ctrl_t *val); +int32_t lis2doc_pin_int1_route_get(stmdev_ctx_t *ctx, + lis2doc_ctrl4_int1_pad_ctrl_t *val); + +int32_t lis2doc_pin_int2_route_set(stmdev_ctx_t *ctx, + lis2doc_ctrl5_int2_pad_ctrl_t *val); +int32_t lis2doc_pin_int2_route_get(stmdev_ctx_t *ctx, + lis2doc_ctrl5_int2_pad_ctrl_t *val); + +int32_t lis2doc_all_on_int1_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_all_on_int1_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_wkup_threshold_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_wkup_threshold_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_wkup_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_wkup_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_HP_FEED = 0, + LIS2DOC_USER_OFFSET_FEED = 1, +} lis2doc_usr_off_on_wu_t; +int32_t lis2doc_wkup_feed_data_set(stmdev_ctx_t *ctx, + lis2doc_usr_off_on_wu_t val); +int32_t lis2doc_wkup_feed_data_get(stmdev_ctx_t *ctx, + lis2doc_usr_off_on_wu_t *val); + +typedef enum +{ + LIS2DOC_NO_DETECTION = 0, + LIS2DOC_DETECT_ACT_INACT = 1, + LIS2DOC_DETECT_STAT_MOTION = 3, +} lis2doc_sleep_on_t; +int32_t lis2doc_act_mode_set(stmdev_ctx_t *ctx, + lis2doc_sleep_on_t val); +int32_t lis2doc_act_mode_get(stmdev_ctx_t *ctx, + lis2doc_sleep_on_t *val); + +int32_t lis2doc_act_sleep_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_act_sleep_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_tap_threshold_x_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_tap_threshold_x_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_tap_threshold_y_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_tap_threshold_y_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_XYZ = 0, + LIS2DOC_YXZ = 1, + LIS2DOC_XZY = 2, + LIS2DOC_ZYX = 3, + LIS2DOC_YZX = 5, + LIS2DOC_ZXY = 6, +} lis2doc_tap_prior_t; +int32_t lis2doc_tap_axis_priority_set(stmdev_ctx_t *ctx, + lis2doc_tap_prior_t val); +int32_t lis2doc_tap_axis_priority_get(stmdev_ctx_t *ctx, + lis2doc_tap_prior_t *val); + +int32_t lis2doc_tap_threshold_z_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_tap_threshold_z_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_tap_detection_on_z_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lis2doc_tap_detection_on_z_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lis2doc_tap_detection_on_y_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lis2doc_tap_detection_on_y_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lis2doc_tap_detection_on_x_set(stmdev_ctx_t *ctx, + uint8_t val); +int32_t lis2doc_tap_detection_on_x_get(stmdev_ctx_t *ctx, + uint8_t *val); + +int32_t lis2doc_tap_shock_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_tap_shock_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_tap_quiet_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_tap_quiet_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_tap_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_tap_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_ONLY_SINGLE = 0, + LIS2DOC_BOTH_SINGLE_DOUBLE = 1, +} lis2doc_single_double_tap_t; +int32_t lis2doc_tap_mode_set(stmdev_ctx_t *ctx, + lis2doc_single_double_tap_t val); +int32_t lis2doc_tap_mode_get(stmdev_ctx_t *ctx, + lis2doc_single_double_tap_t *val); + +int32_t lis2doc_tap_src_get(stmdev_ctx_t *ctx, + lis2doc_tap_src_t *val); + +int32_t lis2doc_6d_threshold_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_6d_threshold_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_4d_mode_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_4d_mode_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_6d_src_get(stmdev_ctx_t *ctx, + lis2doc_sixd_src_t *val); + +typedef enum +{ + LIS2DOC_ODR_DIV_2_FEED = 0, + LIS2DOC_LPF2_FEED = 1, +} lis2doc_lpass_on6d_t; +int32_t lis2doc_6d_feed_data_set(stmdev_ctx_t *ctx, + lis2doc_lpass_on6d_t val); +int32_t lis2doc_6d_feed_data_get(stmdev_ctx_t *ctx, + lis2doc_lpass_on6d_t *val); + +int32_t lis2doc_ff_dur_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_ff_dur_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_FF_TSH_5LSb_FS2g = 0, + LIS2DOC_FF_TSH_7LSb_FS2g = 1, + LIS2DOC_FF_TSH_8LSb_FS2g = 2, + LIS2DOC_FF_TSH_10LSb_FS2g = 3, + LIS2DOC_FF_TSH_11LSb_FS2g = 4, + LIS2DOC_FF_TSH_13LSb_FS2g = 5, + LIS2DOC_FF_TSH_15LSb_FS2g = 6, + LIS2DOC_FF_TSH_16LSb_FS2g = 7, +} lis2doc_ff_ths_t; +int32_t lis2doc_ff_threshold_set(stmdev_ctx_t *ctx, + lis2doc_ff_ths_t val); +int32_t lis2doc_ff_threshold_get(stmdev_ctx_t *ctx, + lis2doc_ff_ths_t *val); + +int32_t lis2doc_fifo_watermark_set(stmdev_ctx_t *ctx, uint8_t val); +int32_t lis2doc_fifo_watermark_get(stmdev_ctx_t *ctx, uint8_t *val); + +typedef enum +{ + LIS2DOC_BYPASS_MODE = 0, + LIS2DOC_FIFO_MODE = 1, + LIS2DOC_STREAM_TO_FIFO_MODE = 3, + LIS2DOC_BYPASS_TO_STREAM_MODE = 4, + LIS2DOC_STREAM_MODE = 6, +} lis2doc_fmode_t; +int32_t lis2doc_fifo_mode_set(stmdev_ctx_t *ctx, + lis2doc_fmode_t val); +int32_t lis2doc_fifo_mode_get(stmdev_ctx_t *ctx, + lis2doc_fmode_t *val); + +int32_t lis2doc_fifo_data_level_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_fifo_ovr_flag_get(stmdev_ctx_t *ctx, uint8_t *val); + +int32_t lis2doc_fifo_wtm_flag_get(stmdev_ctx_t *ctx, uint8_t *val); + +/** + * @} + * + */ + +#ifdef __cplusplus +} +#endif + +#endif /*LIS2DOC_REGS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_activity.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_activity.c new file mode 100644 index 000000000..2a9b5fca2 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_activity.c @@ -0,0 +1,180 @@ +/* + ****************************************************************************** + * @file activity.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect activity/inactivity + * from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +#if defined(STEVAL_MKI109V3) +/* MKI109V3: Define communication interface */ +#define SENSOR_BUS hspi2 +/* MKI109V3: Vdd and Vddio power supply values */ +#define PWM_3V3 915 + +#elif defined(NUCLEO_F411RE) +/* NUCLEO_F411RE: Define communication interface */ +#define SENSOR_BUS hi2c1 + +#elif defined(SPC584B_DIS) +/* DISCOVERY_SPC584B: Define communication interface */ +#define SENSOR_BUS I2CD1 + +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_activity(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + /* Configure filtering chain + * Accelerometer - filter path / bandwidth + */ + lis2doc_filter_path_set(&dev_ctx, LIS2DOC_LPF_ON_OUT); + lis2doc_filter_bandwidth_set(&dev_ctx, LIS2DOC_ODR_DIV_4); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set wake-up duration + * Wake up duration event 1LSb = 1 / ODR + */ + lis2doc_wkup_dur_set(&dev_ctx, 2); + /* Set sleep duration + * Duration to go in sleep mode (1 LSb = 512 / ODR) + */ + lis2doc_act_sleep_dur_set(&dev_ctx, 2); + /* Set Activity wake-up threshold + * Threshold for wake-up 1 LSB = FS_XL / 64 + */ + lis2doc_wkup_threshold_set(&dev_ctx, 2); + /* Data sent to wake-up interrupt function */ + lis2doc_wkup_feed_data_set(&dev_ctx, LIS2DOC_HP_FEED); + /* Config activity / inactivity or stationary / motion detection */ + lis2doc_act_mode_set(&dev_ctx, LIS2DOC_DETECT_ACT_INACT); + /* Enable activity detection interrupt */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_wu = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_200Hz); + + /* Wait Events */ + while (1) { + lis2doc_all_sources_t all_source; + /* Read status register */ + lis2doc_all_sources_get(&dev_ctx, &all_source); + + /* Check if Activity/Inactivity events */ + if (all_source.wake_up_src.sleep_state_ia) { + sprintf((char *)tx_buffer, "Inactivity Detected\r\n"); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + + if (all_source.wake_up_src.wu_ia) { + sprintf((char *)tx_buffer, "Activity Detected\r\n"); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_common.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_common.c new file mode 100644 index 000000000..de5b372f8 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_common.c @@ -0,0 +1,163 @@ +/* + ****************************************************************************** + * @file activity.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect activity/inactivity + * from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +#if defined(STEVAL_MKI109V3) +/* MKI109V3: Define communication interface */ +#define SENSOR_BUS hspi2 +/* MKI109V3: Vdd and Vddio power supply values */ +#define PWM_3V3 915 + +#elif defined(NUCLEO_F411RE) +/* NUCLEO_F411RE: Define communication interface */ +#define SENSOR_BUS hi2c1 + +#elif defined(SPC584B_DIS) +/* DISCOVERY_SPC584B: Define communication interface */ +#define SENSOR_BUS I2CD1 + +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_init(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + /* Configure filtering chain + * Accelerometer - filter path / bandwidth + */ + lis2doc_filter_path_set(&dev_ctx, LIS2DOC_LPF_ON_OUT); + lis2doc_filter_bandwidth_set(&dev_ctx, LIS2DOC_ODR_DIV_4); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set wake-up duration + * Wake up duration event 1LSb = 1 / ODR + */ + lis2doc_wkup_dur_set(&dev_ctx, 2); + /* Set sleep duration + * Duration to go in sleep mode (1 LSb = 512 / ODR) + */ + lis2doc_act_sleep_dur_set(&dev_ctx, 2); + /* Set Activity wake-up threshold + * Threshold for wake-up 1 LSB = FS_XL / 64 + */ + lis2doc_wkup_threshold_set(&dev_ctx, 2); + /* Data sent to wake-up interrupt function */ + lis2doc_wkup_feed_data_set(&dev_ctx, LIS2DOC_HP_FEED); + /* Config activity / inactivity or stationary / motion detection */ + lis2doc_act_mode_set(&dev_ctx, LIS2DOC_DETECT_ACT_INACT); + /* Enable activity detection interrupt */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_wu = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_200Hz); + +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_free_fall.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_free_fall.c new file mode 100644 index 000000000..9e7ed5e6b --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_free_fall.c @@ -0,0 +1,157 @@ +/* + ****************************************************************************** + * @file free_fall.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect free fall events + * from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +#if defined(STEVAL_MKI109V3) +/* MKI109V3: Define communication interface */ +#define SENSOR_BUS hspi2 +/* MKI109V3: Vdd and Vddio power supply values */ +#define PWM_3V3 915 + +#elif defined(NUCLEO_F411RE) +/* NUCLEO_F411RE: Define communication interface */ +#define SENSOR_BUS hi2c1 + +#elif defined(SPC584B_DIS) +/* DISCOVERY_SPC584B: Define communication interface */ +#define SENSOR_BUS I2CD1 + +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_free_fall(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Configure power mode */ + pm.hpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_200Hz); + /* Set full scale to 2 g */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + /* Configure Free Fall duration and samples count */ + lis2doc_ff_dur_set(&dev_ctx, 0x06); + lis2doc_ff_threshold_set(&dev_ctx, LIS2DOC_FF_TSH_10LSb_FS2g); + /* Enable free fall interrupt */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_ff = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + /* Set latched interrupt */ + lis2doc_int_notification_set(&dev_ctx, LIS2DOC_INT_LATCHED); + + /* Wait Events */ + while (1) { + /* Check Free Fall events */ + lis2doc_all_sources_t src; + lis2doc_all_sources_get(&dev_ctx, &src); + + if (src.wake_up_src.ff_ia) { + sprintf((char *)tx_buffer, "free fall detected\r\n"); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_orientation.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_orientation.c new file mode 100644 index 000000000..d982e5e33 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_orientation.c @@ -0,0 +1,167 @@ +/* + ****************************************************************************** + * @file orientation.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect 6D orientation from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_orientation(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set threshold to 60 degrees */ + lis2doc_6d_threshold_set(&dev_ctx, 0x02); + /* LPF2 on 6D function selection. */ + lis2doc_6d_feed_data_set(&dev_ctx, LIS2DOC_LPF2_FEED); + /* Enable interrupt generation on 6D INT1 pin. */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_6d = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_200Hz); + + /* Wait Events. */ + while (1) { + lis2doc_all_sources_t all_source; + lis2doc_all_sources_get(&dev_ctx, &all_source); + + /* Check 6D Orientation events */ + if (all_source.sixd_src._6d_ia) { + sprintf((char *)tx_buffer, "6D Or. switched to "); + + if (all_source.sixd_src.xh) { + strcat((char *)tx_buffer, "XH"); + } + + if (all_source.sixd_src.xl) { + strcat((char *)tx_buffer, "XL"); + } + + if (all_source.sixd_src.yh) { + strcat((char *)tx_buffer, "YH"); + } + + if (all_source.sixd_src.yl) { + strcat((char *)tx_buffer, "YL"); + } + + if (all_source.sixd_src.zh) { + strcat((char *)tx_buffer, "ZH"); + } + + if (all_source.sixd_src.zl) { + strcat((char *)tx_buffer, "ZL"); + } + + strcat((char *)tx_buffer, "\r\n"); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} + diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_data_polling.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_data_polling.c new file mode 100644 index 000000000..a66b1b0c3 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_data_polling.c @@ -0,0 +1,159 @@ +/* + ****************************************************************************** + * @file read_data_polling.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to get data from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ + +static lis2doc_mode_t pm; +static int16_t data_raw_acceleration[3]; +static float acceleration_mg[3]; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_read_data_polling(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Enable Block Data Update */ + lis2doc_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); + /* Set full scale */ + //lis2doc_full_scale_set(&dev_ctx, LIS2DOC_8g); + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + /* Configure filtering chain + * Accelerometer - filter path / bandwidth + */ + lis2doc_filter_path_set(&dev_ctx, LIS2DOC_LPF_ON_OUT); + lis2doc_filter_bandwidth_set(&dev_ctx, LIS2DOC_ODR_DIV_4); + + /* Configure power mode */ + pm.hpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_25Hz); + + /* Read samples in polling mode (no int) */ + while (1) { + uint8_t reg; + /* Read output only if new value is available */ + lis2doc_flag_data_ready_get(&dev_ctx, ®); + + if (reg) { + /* Read acceleration data */ + memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t)); + lis2doc_acceleration_raw_get(&dev_ctx, data_raw_acceleration); + //acceleration_mg[0] = lis2doc_from_fs8_lp1_to_mg(data_raw_acceleration[0]); + //acceleration_mg[1] = lis2doc_from_fs8_lp1_to_mg(data_raw_acceleration[1]); + //acceleration_mg[2] = lis2doc_from_fs8_lp1_to_mg(data_raw_acceleration[2]); + acceleration_mg[0] = lis2doc_from_fs2_to_mg( + data_raw_acceleration[0]); + acceleration_mg[1] = lis2doc_from_fs2_to_mg( + data_raw_acceleration[1]); + acceleration_mg[2] = lis2doc_from_fs2_to_mg( + data_raw_acceleration[2]); + sprintf((char *)tx_buffer, + "Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n", + acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_data_single.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_data_single.c new file mode 100644 index 000000000..e21c0500e --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_data_single.c @@ -0,0 +1,224 @@ +/* + ****************************************************************************** + * @file read_data_simple.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to get data from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + +#include "pinctrl.h" +#include "platform_core.h" +#include "gpio.h" +#include "gpio_porting.h" +#include "errcode.h" +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static int16_t data_raw_acceleration[3]; +// static float acceleration_mg[3]; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; +static lis2doc_ctrl4_int1_pad_ctrl_t ctrl4_int1_pad; +static stmdev_ctx_t dev_ctx; +#define G_INT1_PIN S_AGPIO_L11 +#define G_INT2_PIN S_AGPIO_L19 + +static int lis2doc_install_success = -1; + +/*初始化GPIO*/ +int gpio_int_pin_init(void) +{ + if ((uapi_pin_set_mode(G_INT1_PIN, (pin_mode_t)HAL_PIO_FUNC_GPIO) != ERRCODE_SUCC) || + (uapi_pin_set_pull(G_INT1_PIN, (pin_pull_t)HAL_PIO_PULL_UP) != ERRCODE_SUCC) || + (uapi_gpio_set_dir(G_INT1_PIN, GPIO_DIRECTION_INPUT) != ERRCODE_SUCC)) { + PRINT("gpio G_INT1_PIN config failed\r\n"); + return ERRCODE_FAIL; + } + if ((uapi_pin_set_mode(G_INT2_PIN, (pin_mode_t)HAL_PIO_FUNC_GPIO) != ERRCODE_SUCC) || + (uapi_pin_set_pull(G_INT2_PIN, (pin_pull_t)HAL_PIO_PULL_UP) != ERRCODE_SUCC) || + (uapi_gpio_set_dir(G_INT2_PIN, GPIO_DIRECTION_INPUT) != ERRCODE_SUCC)) { + PRINT("gpio G_INT2_PIN config failed\r\n"); + return ERRCODE_FAIL; + } + return ERRCODE_SUCC; +} + + +int lis2doc_read_data_single_init(void) +{ + /* Initialize mems driver interface */ + if(lis2doc_install_success == 1) return ERRCODE_SUCC; + + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + + gpio_int_pin_init(); + + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + lis2doc_install_success = 0; + return ERRCODE_FAIL; + } + + lis2doc_install_success = 1; + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + // uint8_t count=0; + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Enable Block Data Update */ + lis2doc_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); + //lis2doc_cs_mode_set(&dev_ctx, LIS2DOC_PULL_UP_DISCONNECT); + //lis2doc_i2c_interface_set(&dev_ctx, LIS2DOC_I2C_DISABLE); + //lis2doc_spi_mode_set(&dev_ctx, LIS2DOC_SPI_3_WIRE); + lis2doc_int_notification_set(&dev_ctx, LIS2DOC_INT_LATCHED); + lis2doc_pin_polarity_set(&dev_ctx, LIS2DOC_ACTIVE_LOW); + lis2doc_pin_int1_route_get(&dev_ctx, &ctrl4_int1_pad); + ctrl4_int1_pad.int1_drdy = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &ctrl4_int1_pad); + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + /* Configure filtering chain accelerometer */ + lis2doc_filter_path_set(&dev_ctx, LIS2DOC_LPF_ON_OUT); + lis2doc_filter_bandwidth_set(&dev_ctx, LIS2DOC_ODR_DIV_10); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_SET_SW_TRIG); + return ERRCODE_SUCC; +} +int lis2doc_read_data_single(float *x,float *y ,float *z) +{ + + + if(lis2doc_install_success == -1) + { + lis2doc_read_data_single_init(); + } + if(lis2doc_install_success == 0) + { + return ERRCODE_FAIL; + } + /* Read samples in polling mode (no int) */ + + /* polling on DRDY signal */ + // if (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0)) { + uint8_t val = uapi_gpio_get_val(G_INT1_PIN); + uint8_t val2 = uapi_gpio_get_val(G_INT2_PIN); + // PRINT("G_INT1_PIN %u,G_INT2_PIN %u \r\n",val,val2); + if( val == 0 || val2 == 0) + { + /* Read acceleration data */ + memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t)); + lis2doc_acceleration_raw_get(&dev_ctx, data_raw_acceleration); + *x = lis2doc_from_fs2_lp1_to_mg( + data_raw_acceleration[0]); + *y = lis2doc_from_fs2_lp1_to_mg( + data_raw_acceleration[1]); + *z = lis2doc_from_fs2_lp1_to_mg( + data_raw_acceleration[2]); + *x = (*x)/1000.0f; + *y = (*y)/1000.0f; + *z = (*z)/1000.0f; + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_SET_SW_TRIG); + + } + return ERRCODE_SUCC; + +} +/* Main Example --------------------------------------------------------------*/ +void lis2doc_read_data(void) +{ + float x,y,z; + if(lis2doc_read_data_single(&x,&y,&z)==ERRCODE_SUCC) + { + + sprintf((char *)tx_buffer, + "Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n", + x, y, z); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + +} + diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_fifo.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_fifo.c new file mode 100644 index 000000000..af1eb8d72 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_read_fifo.c @@ -0,0 +1,164 @@ +/* + ****************************************************************************** + * @file read_fifo.c + * @author Sensors Software Solution Team + * @brief This file show how to get data from sensor FIFO. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static int16_t data_raw_acceleration[3]; +static float acceleration_mg[3]; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_read_data_fifo(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Enable Block Data Update */ + lis2doc_block_data_update_set(&dev_ctx, PROPERTY_ENABLE); + /* Set full scale */ + //lis2doc_full_scale_set(&dev_ctx, LIS2DOC_8g); + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + /* Configure filtering chain + * Accelerometer - filter path / bandwidth + */ + lis2doc_filter_path_set(&dev_ctx, LIS2DOC_LPF_ON_OUT); + lis2doc_filter_bandwidth_set(&dev_ctx, LIS2DOC_ODR_DIV_4); + /* Configure FIFO */ + lis2doc_fifo_watermark_set(&dev_ctx, 10); + lis2doc_fifo_mode_set(&dev_ctx, LIS2DOC_STREAM_MODE); + + /* Configure power mode */ + pm.hpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + //lis2doc_power_mode_set(&dev_ctx, LIS2DOC_CONT_LOW_PWR_LOW_NOISE_12bit); + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_25Hz); + + /* Read samples in polling mode (no int) */ + while (1) { + uint8_t val, i; + /* Read output only if new value is available */ + lis2doc_fifo_wtm_flag_get(&dev_ctx, &val); + + if (val) { + lis2doc_fifo_data_level_get(&dev_ctx, &val); + + for (i = 0; i < val; i++) { + /* Read acceleration data */ + memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t)); + lis2doc_acceleration_raw_get(&dev_ctx, data_raw_acceleration); + //acceleration_mg[0] = lis2doc_from_fs8_lp1_to_mg(data_raw_acceleration[0]); + //acceleration_mg[1] = lis2doc_from_fs8_lp1_to_mg(data_raw_acceleration[1]); + //acceleration_mg[2] = lis2doc_from_fs8_lp1_to_mg(data_raw_acceleration[2]); + acceleration_mg[0] = lis2doc_from_fs2_to_mg( + data_raw_acceleration[0]); + acceleration_mg[1] = lis2doc_from_fs2_to_mg( + data_raw_acceleration[1]); + acceleration_mg[2] = lis2doc_from_fs2_to_mg( + data_raw_acceleration[2]); + sprintf((char *)tx_buffer, + "Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n", + acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } + } +} + diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_self_test.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_self_test.c new file mode 100644 index 000000000..2b20bbd9e --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_self_test.c @@ -0,0 +1,266 @@ +/* + ****************************************************************************** + * @file test_self_test.c + * @author Sensors Software Solution Team + * @brief This file run selt test procedure + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +#if defined(STEVAL_MKI109V3) +/* MKI109V3: Define communication interface */ +#define SENSOR_BUS hspi2 +/* MKI109V3: Vdd and Vddio power supply values */ +#define PWM_3V3 915 + +#elif defined(NUCLEO_F411RE) +/* NUCLEO_F411RE: Define communication interface */ +#define SENSOR_BUS hi2c1 + +#elif defined(SPC584B_DIS) +/* DISCOVERY_SPC584B: Define communication interface */ +#define SENSOR_BUS I2CD1 + +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + +typedef union { + int16_t i16bit[3]; +} axis3bit16_t; + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Self-test recommended samples */ +#define SELF_TEST_SAMPLES 5 + +/* Self-test positive difference */ +#define ST_MIN_POS 70.0f +#define ST_MAX_POS 1500.0f + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static axis3bit16_t data_raw_acceleration[SELF_TEST_SAMPLES]; +static float acceleration_mg[SELF_TEST_SAMPLES][3]; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + +/* Utility functions ---------------------------------------------------------*/ +static inline float ABSF(float _x) +{ + return (_x < 0.0f) ? -(_x) : _x; +} + +static int flush_samples(stmdev_ctx_t *dev_ctx) +{ + lis2doc_reg_t reg; + axis3bit16_t dummy; + int samples = 0; + /* + * Discard old samples + */ + lis2doc_status_reg_get(dev_ctx, ®.status); + + if (reg.status.drdy) { + lis2doc_acceleration_raw_get(dev_ctx, dummy.i16bit); + samples++; + } + + return samples; +} + +static void test_self_test_lis2doc(stmdev_ctx_t *dev_ctx) +{ + lis2doc_reg_t reg; + float media[3] = { 0.0f, 0.0f, 0.0f }; + float mediast[3] = { 0.0f, 0.0f, 0.0f }; + uint8_t match[3] = { 0, 0, 0 }; + uint8_t j = 0; + uint16_t i = 0; + uint8_t k = 0; + uint8_t axis; + /* Restore default configuration */ + lis2doc_reset_set(dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(dev_ctx, &rst); + } while (rst); + + lis2doc_block_data_update_set(dev_ctx, PROPERTY_ENABLE); + lis2doc_full_scale_set(dev_ctx, LIS2DOC_4g); + + /* Configure power mode */ + pm.hpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(dev_ctx, pm); + + lis2doc_data_rate_set(dev_ctx, LIS2DOC_XL_ODR_50Hz); + platform_delay(100); + /* Flush old samples */ + flush_samples(dev_ctx); + + do { + lis2doc_status_reg_get(dev_ctx, ®.status); + + if (reg.status.drdy) { + /* Read accelerometer data */ + memset(data_raw_acceleration[i].i16bit, 0x00, 3 * sizeof(int16_t)); + lis2doc_acceleration_raw_get(dev_ctx, + data_raw_acceleration[i].i16bit); + + for (axis = 0; axis < 3; axis++) { + acceleration_mg[i][axis] = + lis2doc_from_fs4_to_mg(data_raw_acceleration[i].i16bit[axis]); + } + + i++; + } + } while (i < SELF_TEST_SAMPLES); + + for (k = 0; k < 3; k++) { + for (j = 0; j < SELF_TEST_SAMPLES; j++) { + media[k] += acceleration_mg[j][k]; + } + + media[k] = (media[k] / j); + } + + /* Enable self test mode */ + lis2doc_self_test_set(dev_ctx, LIS2DOC_XL_ST_POSITIVE); + platform_delay(100); + i = 0; + /* Flush old samples */ + flush_samples(dev_ctx); + + do { + lis2doc_status_reg_get(dev_ctx, ®.status); + + if (reg.status.drdy) { + /* Read accelerometer data */ + memset(data_raw_acceleration[i].i16bit, 0x00, 3 * sizeof(int16_t)); + lis2doc_acceleration_raw_get(dev_ctx, + data_raw_acceleration[i].i16bit); + + for (axis = 0; axis < 3; axis++) + acceleration_mg[i][axis] = + lis2doc_from_fs4_to_mg(data_raw_acceleration[i].i16bit[axis]); + + i++; + } + } while (i < SELF_TEST_SAMPLES); + + for (k = 0; k < 3; k++) { + for (j = 0; j < SELF_TEST_SAMPLES; j++) { + mediast[k] += acceleration_mg[j][k]; + } + + mediast[k] = (mediast[k] / j); + } + + /* Check for all axis self test value range */ + for (k = 0; k < 3; k++) { + if ((ABSF(mediast[k] - media[k]) >= ST_MIN_POS) && + (ABSF(mediast[k] - media[k]) <= ST_MAX_POS)) { + match[k] = 1; + } + + sprintf((char *)tx_buffer, "%d: |%f| <= |%f| <= |%f| %s\r\n", k, + ST_MIN_POS, ABSF(mediast[k] - media[k]), ST_MAX_POS, + match[k] == 1 ? "PASSED" : "FAILED"); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + + /* Disable self test mode */ + lis2doc_data_rate_set(dev_ctx, LIS2DOC_XL_ODR_OFF); + lis2doc_self_test_set(dev_ctx, LIS2DOC_XL_ST_DISABLE); +} + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_self_test(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Start self test */ + while (1) { + test_self_test_lis2doc(&dev_ctx); + } +} + diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_tap_double.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_tap_double.c new file mode 100644 index 000000000..3d4fd5937 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_tap_double.c @@ -0,0 +1,189 @@ +/* + ****************************************************************************** + * @file double_tap.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect double tap from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_double_tap(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_400Hz); + /* Enable Tap detection on X, Y, Z */ + lis2doc_tap_detection_on_z_set(&dev_ctx, PROPERTY_ENABLE); + lis2doc_tap_detection_on_y_set(&dev_ctx, PROPERTY_ENABLE); + lis2doc_tap_detection_on_x_set(&dev_ctx, PROPERTY_ENABLE); + /* Set Tap threshold on all axis */ + lis2doc_tap_threshold_x_set(&dev_ctx, 12); + lis2doc_tap_threshold_y_set(&dev_ctx, 12); + lis2doc_tap_threshold_z_set(&dev_ctx, 12); + /* Configure Double Tap parameter */ + lis2doc_tap_dur_set(&dev_ctx, 7); + lis2doc_tap_quiet_set(&dev_ctx, 3); + lis2doc_tap_shock_set(&dev_ctx, 3); + /* Enable Double Tap detection */ + lis2doc_tap_mode_set(&dev_ctx, LIS2DOC_BOTH_SINGLE_DOUBLE); + /* Enable single tap detection interrupt */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_tap = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + + /* Wait Events. */ + while (1) { + lis2doc_all_sources_t all_source; + /* Check Double Tap events */ + lis2doc_all_sources_get(&dev_ctx, &all_source); + + if (all_source.tap_src.double_tap) { + sprintf((char *)tx_buffer, "Double Tap Detected: Sign %s", + all_source.tap_src.tap_sign ? "positive" : "negative"); + + if (all_source.tap_src.x_tap) { + sprintf((char *)tx_buffer, "%s on X", tx_buffer); + } + + if (all_source.tap_src.y_tap) { + sprintf((char *)tx_buffer, "%s on Y", tx_buffer); + } + + if (all_source.tap_src.z_tap) { + sprintf((char *)tx_buffer, "%s on Z", tx_buffer); + } + + sprintf((char *)tx_buffer, "%s axis\r\n", tx_buffer); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + + /* Check Single Tap events */ + if (all_source.tap_src.single_tap) { + sprintf((char *)tx_buffer, "Tap Detected: Sign %s", + all_source.tap_src.tap_sign ? "positive" : "negative"); + + if (all_source.tap_src.x_tap) { + sprintf((char *)tx_buffer, "%s on X", tx_buffer); + } + + if (all_source.tap_src.y_tap) { + sprintf((char *)tx_buffer, "%s on Y", tx_buffer); + } + + if (all_source.tap_src.z_tap) { + sprintf((char *)tx_buffer, "%s on Z", tx_buffer); + } + + sprintf((char *)tx_buffer, "%s axis\r\n", tx_buffer); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_tap_single.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_tap_single.c new file mode 100644 index 000000000..d1ced84a9 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_tap_single.c @@ -0,0 +1,166 @@ +/* + ****************************************************************************** + * @file single_tap.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect single tap from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" + + +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + + + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_single_tap(void) +{ + /* Initialize mems driver interface. */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_400Hz); + /* Enable Tap detection on X, Y, Z */ + lis2doc_tap_detection_on_z_set(&dev_ctx, PROPERTY_ENABLE); + lis2doc_tap_detection_on_y_set(&dev_ctx, PROPERTY_ENABLE); + lis2doc_tap_detection_on_x_set(&dev_ctx, PROPERTY_ENABLE); + /* Set Tap threshold on all axis */ + lis2doc_tap_threshold_x_set(&dev_ctx, 9); + lis2doc_tap_threshold_y_set(&dev_ctx, 9); + lis2doc_tap_threshold_z_set(&dev_ctx, 9); + /* Configure Single Tap parameter */ + lis2doc_tap_quiet_set(&dev_ctx, 1); + lis2doc_tap_shock_set(&dev_ctx, 2); + /* Enable Single Tap detection only */ + lis2doc_tap_mode_set(&dev_ctx, LIS2DOC_ONLY_SINGLE); + /* Enable single tap detection interrupt */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_single_tap = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + + /* Wait Events */ + while (1) { + lis2doc_all_sources_t all_source; + /* Check Single Tap events */ + lis2doc_all_sources_get(&dev_ctx, &all_source); + + if (all_source.tap_src.single_tap) { + sprintf((char *)tx_buffer, "Tap Detected: Sign %s", + all_source.tap_src.tap_sign ? "positive" : "negative"); + + if (all_source.tap_src.x_tap) { + sprintf((char *)tx_buffer, "%s on X axis\r\n", tx_buffer); + } + + if (all_source.tap_src.y_tap) { + sprintf((char *)tx_buffer, "%s on Y axis\r\n", tx_buffer); + } + + if (all_source.tap_src.z_tap) { + sprintf((char *)tx_buffer, "%s on Z axis\r\n", tx_buffer); + } + + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_wake_up.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_wake_up.c new file mode 100644 index 000000000..39c6074f6 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/examples/lis2doc_wake_up.c @@ -0,0 +1,177 @@ +/* + ****************************************************************************** + * @file lis2doc_wake_up.c + * @author Sensors Software Solution Team + * @brief This file show the simplest way to detect wake_up from sensor. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +/* STMicroelectronics evaluation boards definition + * + * Please uncomment ONLY the evaluation boards in use. + * If a different hardware is used please comment all + * following target board and redefine yours. + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +#if defined(STEVAL_MKI109V3) +/* MKI109V3: Define communication interface */ +#define SENSOR_BUS hspi2 +/* MKI109V3: Vdd and Vddio power supply values */ +#define PWM_3V3 915 + +#elif defined(NUCLEO_F411RE) +/* NUCLEO_F411RE: Define communication interface */ +#define SENSOR_BUS hi2c1 + +#elif defined(SPC584B_DIS) +/* DISCOVERY_SPC584B: Define communication interface */ +#define SENSOR_BUS I2CD1 + +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Private variables ---------------------------------------------------------*/ +static lis2doc_mode_t pm; +static uint8_t whoamI, rst; +static uint8_t tx_buffer[1000]; + +/* Main Example --------------------------------------------------------------*/ +void lis2doc_wake_up(void) +{ + /* Initialize mems driver interface */ + stmdev_ctx_t dev_ctx; + lis2doc_reg_t int_route; + dev_ctx.write_reg = platform_write; + dev_ctx.read_reg = platform_read; + dev_ctx.handle = &SENSOR_BUS; + /* Initialize platform specific hardware */ + platform_init(); + /* Wait sensor boot time */ + platform_delay(BOOT_TIME); + /* Check device ID */ + lis2doc_device_id_get(&dev_ctx, &whoamI); + + if (whoamI != LIS2DOC_ID) + { + /* manage here device not found */ + LIS_ERROR("read lis2doc id 0x%02X != 0x%02X\r\n",whoamI,LIS2DOC_ID); + return ; + } + + + /* Restore default configuration */ + lis2doc_reset_set(&dev_ctx, PROPERTY_ENABLE); + + do { + lis2doc_reset_get(&dev_ctx, &rst); + } while (rst); + + /* Set full scale */ + lis2doc_full_scale_set(&dev_ctx, LIS2DOC_2g); + + /* Configure power mode */ + pm.lpm = 1; + pm.low_noise = 1; + lis2doc_power_mode_set(&dev_ctx, pm); + + /* Set Output Data Rate */ + lis2doc_data_rate_set(&dev_ctx, LIS2DOC_XL_ODR_200Hz); + /* Apply high-pass digital filter on Wake-Up function */ + lis2doc_filter_path_set(&dev_ctx, LIS2DOC_HIGH_PASS_ON_OUT); + /* Apply high-pass digital filter on Wake-Up function + * Duration time is set to zero so Wake-Up interrupt signal + * is generated for each X,Y,Z filtered data exceeding the + * configured threshold + */ + lis2doc_wkup_dur_set(&dev_ctx, 0); + /* Set wake-up threshold + * Set Wake-Up threshold: 1 LSb corresponds to FS_XL/2^6 + */ + lis2doc_wkup_threshold_set(&dev_ctx, 2); + /* Enable interrupt generation on Wake-Up INT1 pin */ + lis2doc_pin_int1_route_get(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + int_route.ctrl4_int1_pad_ctrl.int1_wu = PROPERTY_ENABLE; + lis2doc_pin_int1_route_set(&dev_ctx, &int_route.ctrl4_int1_pad_ctrl); + + /* Wait Events */ + while (1) { + lis2doc_all_sources_t all_source; + /* Check Wake-Up events */ + lis2doc_all_sources_get(&dev_ctx, &all_source); + + if (all_source.wake_up_src.wu_ia) { + sprintf((char *)tx_buffer, "Wake-Up event on "); + + if (all_source.wake_up_src.x_wu) { + strcat((char *)tx_buffer, "X"); + } + + if (all_source.wake_up_src.y_wu) { + strcat((char *)tx_buffer, "Y"); + } + + if (all_source.wake_up_src.z_wu) { + strcat((char *)tx_buffer, "Z"); + } + + strcat((char *)tx_buffer, " direction\r\n"); + tx_com(tx_buffer, strlen((char const *)tx_buffer)); + } + } +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_at_cmd.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_at_cmd.c new file mode 100644 index 000000000..ea0b9838e --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_at_cmd.c @@ -0,0 +1,78 @@ + +// #include "lis2doc.h" + +#include "at_cmd_api.h" +#include "pm_control.h" +#include "lis2doc_porting.h" +#include "acc_service.h" + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define LIS2DOC_MAX_ARGC 8 +#define LIS2DOC_MAX_ARGV_LEN 64 + +#define LIS2DOC_SUCCESS 0 +#define LIS2DOC_FAILED (-1) + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[LIS2DOC_MAX_ARGC][LIS2DOC_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 >= LIS2DOC_MAX_ARGC) { + return LIS2DOC_FAILED; + } + } else { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= LIS2DOC_MAX_ARGV_LEN) { + return LIS2DOC_FAILED; + } + } + } + if (pos != 0) { + *argc += 1; + } + + return LIS2DOC_SUCCESS; +} + + +static uint32_t lis2doc_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t argv[LIS2DOC_MAX_ARGC][LIS2DOC_MAX_ARGV_LEN] = { 0 }; + uint32_t argc = 0; + + int ret = ConvertCmdToParam(para, paraLen, argv, &argc); + if (ret != LIS2DOC_SUCCESS) { + LIS_ERROR("LIS2DOCTEST ATCMD Convert Command Failed\n"); + return ERRCODE_FAIL; + } + if (argc != 1) { + LIS_ERROR("LIS2DOCTEST ATCMD Set Parameter Failed\n"); + return ERRCODE_FAIL; + } + char *mode = (char*)argv[0]; + if (strcmp(mode, "start") == 0) { + do_acc_service_check_msg(ACC_SERVICE_CMD_START_CHECK); + } else if (strcmp(mode, "stop") == 0) { + do_acc_service_check_msg(ACC_SERVICE_CMD_STOP_CHECK); + } + return ERRCODE_SUCC; +} + +static const at_cmd_table_t g_lis2doc_cmd[] = { + { (char *)"AT^LIS2DOCTEST", lis2doc_do_test, (char *)"aac enable" }, +}; + +at_cmd_table_t *get_lis2doc_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_lis2doc_cmd); + return (at_cmd_table_t *)g_lis2doc_cmd; +} diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_at_cmd.h b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_at_cmd.h new file mode 100644 index 000000000..fc4000adc --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 LIS2DOC_AT_PROCESS_H +#define LIS2DOC_AT_PROCESS_H + +#include +#include +#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_lis2doc_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_porting.c b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_porting.c new file mode 100644 index 000000000..91bf6cbba --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_porting.c @@ -0,0 +1,228 @@ +/* + * This example was developed using the following STMicroelectronics + * evaluation boards: + * + * - STEVAL_MKI109V3 + STEVAL-MKI179V1 + * - NUCLEO_F411RE + X_NUCLEO_IKS01A3 + * - DISCOVERY_SPC584B + X_NUCLEO_IKS01A3 + * + * and STM32CubeMX tool with STM32CubeF4 MCU Package + * + * Used interfaces: + * + * STEVAL_MKI109V3 - Host side: USB (Virtual COM) + * - Sensor side: SPI(Default) / I2C(supported) + * + * NUCLEO_STM32F411RE - Host side: UART(COM) to USB bridge + * - I2C(Default) / SPI(supported) + * + * DISCOVERY_SPC584B - Host side: UART(COM) to USB bridge + * - Sensor side: I2C(Default) / SPI(supported) + * + * If you need to run this example on a different hardware platform a + * modification of the functions: `platform_write`, `platform_read`, + * `tx_com` and 'platform_init' is required. + * + */ + +//#define STEVAL_MKI109V3 /* little endian */ +//#define NUCLEO_F411RE /* little endian */ +//#define SPC584B_DIS /* big endian */ + +/* ATTENTION: By default the driver is little endian. If you need switch + * to big endian please see "Endianness definitions" in the + * header file of the driver (_reg.h). + */ + + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include "lis2doc_reg.h" +#include "lis2doc_porting.h" +#include "osal_timer.h" +#include "osal_mutex.h" +#include "pinctrl.h" +#include "chip_io.h" +#include "time.h" +#include "i2c.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "hal_i2c.h" +#include "soc_osal.h" +#include "tcxo.h" +uint8_t SENSOR_BUS = 0; +/* Private macro -------------------------------------------------------------*/ +#define BOOT_TIME 20 //ms + +/* Self-test recommended samples */ +#define SELF_TEST_SAMPLES 5 + +/* Self-test positive difference */ +#define ST_MIN_POS 70.0f +#define ST_MAX_POS 1500.0f + +/* Private variables ---------------------------------------------------------*/ +uint8_t g_acc_handle=0; +static uint8_t g_acc_installed = 0; + +#define LIS2DOC_I2C_BUS I2C_BUS_2 +#define LIS2DOC_I2C_DEV_7ADDR 0x19 +#define LIS2DOC_I2C_TIME_MAX 3 + +/* + * @brief platform specific initialization (platform dependent) + */ +void platform_init(void) +{ + errcode_t result; + /* init i2c */ + if ( g_acc_installed == 1 ) + return ; + result = uapi_i2c_master_init(LIS2DOC_I2C_BUS, 400000, I2C_SPEED_MODE_FS); + if ( result == ERRCODE_I2C_ALREADY_INIT) + { + g_acc_installed = 1; + LIS_WARNING("lis2doc:i2c_id = %d i2c_speed = %d slave_addr = 0x%x ,already initiallized\r\n", + LIS2DOC_I2C_BUS, 400000, LIS2DOC_I2C_DEV_7ADDR); + return ; + } + + result = uapi_i2c_master_init(LIS2DOC_I2C_BUS, 400000, I2C_SPEED_MODE_FS); /* 400000: 400KHz */ + if (result != ERRCODE_SUCC) { + LIS_ERROR("lis2doc i2c init fail! ret=0x%x", result); + return ; + } + + LIS_WARNING("lis2doc:i2c_id = %d i2c_speed = %d slave_addr = 0x%x \r\n", + LIS2DOC_I2C_BUS, 400000, LIS2DOC_I2C_DEV_7ADDR); + + g_acc_installed = 1; + + return ; +} + +/* + * @brief Write generic device register (platform dependent) + * + * @param handle customizable argument. In this examples is used in + * order to select the correct sensor bus handler. + * @param reg register to write + * @param bufp pointer to data to write in register reg + * @param len number of consecutive register to write + * + */ +int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, + uint16_t len) +{ + + errcode_t ret; + uint32_t retry; + i2c_data_t data; + uint8_t *write_data = NULL; + uint16_t send_len; + uint8_t *data_buf=bufp; + uint16_t data_len=len; + + platform_init(); + send_len = data_len + sizeof(uint8_t); + write_data = (uint8_t *)osal_kmalloc(send_len, OSAL_GFP_KERNEL); + if (write_data == NULL) { + LIS_ERROR("lis2doc send buff malloc fail!"); + return ERRCODE_FAIL; + } + write_data[0] = reg; + ret = (uint32_t)memcpy_s(write_data + sizeof(uint8_t), send_len - sizeof(uint8_t), data_buf, data_len); + if (ret != EOK) { + LIS_ERROR("lis2doc send_buf content copy fail! ret=0x%x", ret); + return ret; + } + + data.send_buf = write_data; + data.send_len = send_len; + data.receive_buf = NULL; + data.receive_len = 0; + + for (retry = 0; retry < LIS2DOC_I2C_TIME_MAX; retry++) { + ret = uapi_i2c_master_write(LIS2DOC_I2C_BUS, LIS2DOC_I2C_DEV_7ADDR, &data); + if (ret == ERRCODE_SUCC) { + break; + } + } + if (ret != ERRCODE_SUCC) { + LIS_ERROR("lis2doc data write fail! ret=0x%x", ret); + return ret; + } + + osal_kfree(write_data); + return 0; +} + +/* + * @brief Read generic device register (platform dependent) + * + * @param handle customizable argument. In this examples is used in + * order to select the correct sensor bus handler. + * @param reg register to read + * @param bufp pointer to buffer that store the data read + * @param len number of consecutive register to read + * + */ +int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, + uint16_t len) +{ + errcode_t ret; + uint32_t retry; + i2c_data_t data; + + platform_init(); + memset_s(bufp, len, 0, len); + data.send_buf = ® + data.send_len = 1; + data.receive_buf = bufp; + data.receive_len = len; + + for (retry = 0; retry < LIS2DOC_I2C_TIME_MAX; retry++) { + ret = uapi_i2c_master_writeread(LIS2DOC_I2C_BUS, LIS2DOC_I2C_DEV_7ADDR, &data); + if (ret == ERRCODE_SUCC) { + break; + } + } + if (ret != ERRCODE_SUCC) { + LIS_ERROR("lis2doc data read fail! ret=0x%x", ret); + return ret; + } + + return ERRCODE_SUCC; +} + +/* + * @brief Write generic device register (platform dependent) + * + * @param tx_buffer buffer to transmit + * @param len number of byte to send + * + */ +void tx_com(uint8_t *tx_buffer, uint16_t len) +{ + //TODO : 打印日志 + LIS_LOG("%s",tx_buffer); +} + +/* + * @brief platform specific delay (platform dependent) + * + * @param ms delay in ms + * + */ +#include "tcxo.h" +void platform_delay(uint32_t ms) +{ + uapi_tcxo_delay_ms(ms); +} + + + + + diff --git a/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_porting.h b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_porting.h new file mode 100644 index 000000000..a7470dcd4 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/lis2doc_STdC/lis2doc_porting.h @@ -0,0 +1,47 @@ +#ifndef __LIS2DOC_PORTING_H__ +#define __LIS2DOC_PORTING_H__ +#include +#include +#include "debug_print.h" +#include "lis2doc_reg.h" + +#define LIS_DEBUG + +#ifdef LIS_DEBUG +#define LIS_LOG(fmt, ...) \ + do { \ + PRINT(fmt"\r\n", ##__VA_ARGS__); \ + } while (0) +#else +#define LIS_LOG(ftm, ...) +#endif + +#define LIS_ERROR(x, ...) \ + do { \ + PRINT("[ERROR]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define LIS_WARNING(x, ...) \ + do { \ + PRINT("[WARNING]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + + + +int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len); +int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len); +void tx_com( uint8_t *tx_buffer, uint16_t len ); +void platform_delay(uint32_t ms); +void platform_init(void); + +extern uint8_t SENSOR_BUS ; + +/******test functions********/ + +// void lis2doc_activity(void); +// void lis2doc_wake_up(void); +// void lis2doc_self_test(void); +// void lis2doc_read_data_single(void); + + +#endif \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/acc/service/acc_service.c b/code/sdk/drivers/peripheral/acc/service/acc_service.c new file mode 100644 index 000000000..849a5add4 --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/service/acc_service.c @@ -0,0 +1,170 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n + * + * Description: Test adc source \n + * Author: @CompanyNameTag \n + * History: \n + * 2022-08-16, Create file. \n + */ + +#include "pinctrl.h" +#include "debug_print.h" +#include "soc_osal.h" +#include "tcxo.h" +#include "irmalloc.h" +#include "errcode.h" +#include "common_def.h" + +#include "chip_core_irq.h" +#include "chip_io.h" +#include "gpio.h" +#include "pm_veto.h" + +#include "rtc.h" +#include "timer.h" +#include "systick.h" + +#include "lis2doc_porting.h" + +static bool g_batter_service_initialled = false; + +#include "tcxo.h" + +#include "cmsis_os2.h" +#include "input_app.h" +#include "mmc5603_hal.h" +#include "acc_service.h" + + +/*** + * 其他cmd在Header里定义,对外开放 +*/ +#define ACC_SERVICE_CMD_TIMER_CHECK 0x11 + +osTimerId_t g_acc_service_timer = NULL; + +static bool g_bat_timer_is_running = false; +#define ACC_CHECK_MS 100 +static unsigned long g_app_queue; + +static bool acc_service_running_stat = false; +static void acc_service_check_timer_callback(void* data); + +static void acc_service_timer_start_check(uint32_t rtc_ms) +{ + + if (g_bat_timer_is_running ) osTimerStop(g_acc_service_timer); + if (acc_service_running_stat == true) osTimerStart(g_acc_service_timer, rtc_ms); + g_bat_timer_is_running = true; + +} +void do_acc_service_check_msg(int cmd); + +static void acc_service_check_timer_callback(void * data) +{ + unused(data); + + g_bat_timer_is_running = false; + + if(acc_service_running_stat == true){ + // mmc5603_check(); + lis2doc_read_data(); + acc_service_timer_start_check(ACC_CHECK_MS); + } + // do_acc_service_check_msg(ACC_SERVICE_CMD_TIMER_CHECK); + // uapi_tcxo_delay_ms(20); + + + +} +void uapi_acc_service_deinit(void) +{ + /* Stop the time and clear the pin map */ + osTimerStop(g_acc_service_timer); + osTimerDelete(g_acc_service_timer); + + g_bat_timer_is_running = false; + g_acc_service_timer = NULL; +} + + + +void do_acc_service_check_msg(int cmd) +{ + int ret; + + 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 mag Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret); + } + +} + +static void acc_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 == ACC_SERVICE_CMD_TIMER_CHECK) { + // acc_service_check_and_enable_charge(); + // mmc5603_check(); + PRINT("ACC_SERVICE_CMD_TIMER_CHECK\r\n"); + }else if (mail.comm.app == ACC_SERVICE_CMD_START_CHECK){ + acc_service_running_stat = true; + // lis2doc_read_data_single_init(); + acc_service_timer_start_check(ACC_CHECK_MS); + }else if (mail.comm.app == ACC_SERVICE_CMD_STOP_CHECK){ + acc_service_running_stat = false; + osTimerStop(g_acc_service_timer); + + } + } +} + +errcode_t uapi_acc_service_init(void) +{ + if (osal_msg_queue_create("acc_service_queue", APP_BOARD_MSG_COUNT, &g_app_queue, + 0, sizeof(common_notify_mail_t)) != ERRCODE_SUCC) { + PRINT("[mag][service] app create mail fail\n"); + return ERRCODE_FAIL; + } + + + osal_task *task_handle = osal_kthread_create((osal_kthread_handler)acc_service_check_task, NULL, + "acc_service_service", APP_BOARD_TASK_SIZE); + if (task_handle == NULL) { + osal_msg_queue_is_full(g_app_queue); + PRINT("create mag service thread fail!\r\n"); + return ERRCODE_FAIL; + } + + // osal_kthread_set_priority(task_handle, APP_BOARD_TASK_PRIO); + osal_kthread_set_priority(task_handle, 10); + + g_acc_service_timer = osTimerNew((osTimerFunc_t)acc_service_check_timer_callback, osTimerPeriodic, NULL, NULL); + + + return ERRCODE_SUCC; +} + +// void acc_service_service_resume(void) +// { +// PRINT("acc_service_service resume!\r\n"); +// acc_service_check_timer_callback(0); +// } +// void acc_service_service_suspend(void) +// { +// PRINT("acc_service_service suspend!\r\n"); +// } \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/acc/service/acc_service.h b/code/sdk/drivers/peripheral/acc/service/acc_service.h new file mode 100644 index 000000000..2aaa5186d --- /dev/null +++ b/code/sdk/drivers/peripheral/acc/service/acc_service.h @@ -0,0 +1,43 @@ +/** + * 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 ACC_SERVICE_H__ +#define ACC_SERVICE_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#include "stdint.h" +#include "errcode.h" + + +#define ACC_SERVICE_CMD_START_CHECK 0x12 +#define ACC_SERVICE_CMD_STOP_CHECK 0x13 + +errcode_t uapi_acc_service_init(void); +void uapi_acc_service_deinit(void); +/** + * 测试指令 参数cmd 选项: ACC_SERVICE_CMD_START_CHECK,ACC_SERVICE_CMD_STOP_CHECK +*/ +void do_acc_service_check_msg(int cmd); + +int lis2doc_read_data_single(float *x,float *y,float *z); + +void lis2doc_read_data(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/code/sdk/drivers/drivers/driver/button/CMakeLists.txt b/code/sdk/drivers/peripheral/button/CMakeLists.txt old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/button/CMakeLists.txt rename to code/sdk/drivers/peripheral/button/CMakeLists.txt diff --git a/code/sdk/drivers/drivers/driver/button/button.c b/code/sdk/drivers/peripheral/button/button.c old mode 100755 new mode 100644 similarity index 99% rename from code/sdk/drivers/drivers/driver/button/button.c rename to code/sdk/drivers/peripheral/button/button.c index ee0ddb214..93c6355ca --- a/code/sdk/drivers/drivers/driver/button/button.c +++ b/code/sdk/drivers/peripheral/button/button.c @@ -247,8 +247,6 @@ errcode_t uapi_button_gpio_register(pin_t pin) if (ret != ERRCODE_SUCC) { return ret; } - PRINT("uapi_button_gpio_register %d\r\n", pin); - /* GPIO set input and pull up */ if ((uapi_pin_set_mode(pin, (pin_mode_t)HAL_PIO_FUNC_GPIO) != ERRCODE_SUCC) || (uapi_pin_set_pull(pin, (pin_pull_t)HAL_PIO_PULL_UP) != ERRCODE_SUCC) || diff --git a/code/sdk/drivers/drivers/driver/button/button.h b/code/sdk/drivers/peripheral/button/button.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/button/button.h rename to code/sdk/drivers/peripheral/button/button.h diff --git a/code/sdk/drivers/drivers/driver/lcd/CMakeLists.txt b/code/sdk/drivers/peripheral/lcd/CMakeLists.txt old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/CMakeLists.txt rename to code/sdk/drivers/peripheral/lcd/CMakeLists.txt diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_bus.c b/code/sdk/drivers/peripheral/lcd/lcd_bus.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_bus.c rename to code/sdk/drivers/peripheral/lcd/lcd_bus.c diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_bus.h b/code/sdk/drivers/peripheral/lcd/lcd_bus.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_bus.h rename to code/sdk/drivers/peripheral/lcd/lcd_bus.h diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_common.c b/code/sdk/drivers/peripheral/lcd/lcd_common.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_common.c rename to code/sdk/drivers/peripheral/lcd/lcd_common.c diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_common.h b/code/sdk/drivers/peripheral/lcd/lcd_common.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_common.h rename to code/sdk/drivers/peripheral/lcd/lcd_common.h diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_config.c b/code/sdk/drivers/peripheral/lcd/lcd_config.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_config.c rename to code/sdk/drivers/peripheral/lcd/lcd_config.c diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_config.h b/code/sdk/drivers/peripheral/lcd/lcd_config.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_config.h rename to code/sdk/drivers/peripheral/lcd/lcd_config.h diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_mipi.c b/code/sdk/drivers/peripheral/lcd/lcd_mipi.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_mipi.c rename to code/sdk/drivers/peripheral/lcd/lcd_mipi.c diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_mipi.h b/code/sdk/drivers/peripheral/lcd/lcd_mipi.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_mipi.h rename to code/sdk/drivers/peripheral/lcd/lcd_mipi.h diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_private.c b/code/sdk/drivers/peripheral/lcd/lcd_private.c old mode 100755 new mode 100644 similarity index 92% rename from code/sdk/drivers/drivers/driver/lcd/lcd_private.c rename to code/sdk/drivers/peripheral/lcd/lcd_private.c index 349135a18..a28b69377 --- a/code/sdk/drivers/drivers/driver/lcd/lcd_private.c +++ b/code/sdk/drivers/peripheral/lcd/lcd_private.c @@ -14,6 +14,7 @@ #include "product.h" #ifdef PRE_ASIC +//#define RESET_LCD_GPIO S_AGPIO_R3 #define RESET_LCD_GPIO S_AGPIO_L27 #else #define RESET_LCD_GPIO S_HGPIO0 @@ -55,7 +56,7 @@ static void lcd_drv_power_off(void) #endif #else uapi_gpio_set_val(RESET_LCD_GPIO, GPIO_LEVEL_LOW); - uapi_gpio_set_dir(RESET_LCD_GPIO, GPIO_DIRECTION_INPUT); + uapi_gpio_set_dir(RESET_LCD_GPIO, GPIO_DIRECTION_INPUT); //设置成Input,是为了解决漏电 ?? #ifndef QSPI_DISPLAY uapi_gpio_set_val(VCI_LCD_GPIO, GPIO_LEVEL_LOW); uapi_gpio_set_dir(VCI_LCD_GPIO, GPIO_DIRECTION_INPUT); diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_private.h b/code/sdk/drivers/peripheral/lcd/lcd_private.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_private.h rename to code/sdk/drivers/peripheral/lcd/lcd_private.h diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_qspi.c b/code/sdk/drivers/peripheral/lcd/lcd_qspi.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_qspi.c rename to code/sdk/drivers/peripheral/lcd/lcd_qspi.c diff --git a/code/sdk/drivers/drivers/driver/lcd/lcd_qspi.h b/code/sdk/drivers/peripheral/lcd/lcd_qspi.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/lcd_qspi.h rename to code/sdk/drivers/peripheral/lcd/lcd_qspi.h diff --git a/code/sdk/drivers/drivers/driver/lcd/soc_lcd_api.c b/code/sdk/drivers/peripheral/lcd/soc_lcd_api.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/soc_lcd_api.c rename to code/sdk/drivers/peripheral/lcd/soc_lcd_api.c diff --git a/code/sdk/drivers/drivers/driver/lcd/soc_lcd_api.h b/code/sdk/drivers/peripheral/lcd/soc_lcd_api.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/lcd/soc_lcd_api.h rename to code/sdk/drivers/peripheral/lcd/soc_lcd_api.h diff --git a/code/sdk/drivers/peripheral/mag/CMakeLists.txt b/code/sdk/drivers/peripheral/mag/CMakeLists.txt new file mode 100644 index 000000000..0ef2a2753 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/CMakeLists.txt @@ -0,0 +1,70 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "mag_sensor") + + +if("MAG_MMC5603" IN_LIST DEFINES) +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/Customer.c + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/mmc5603_main.c + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/MMC5603.c + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/mmc5603_at_cmd.c + ${CMAKE_CURRENT_SOURCE_DIR}/service/mag_service.c +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603 + ${CMAKE_CURRENT_SOURCE_DIR}/service +) +set(PUBLIC_DEFINES + MAG_MMC5603 + SUPPORT_AT_MMC5603 +) +else() +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/Customer.c + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/mmc5603_main.c + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/MMC5603.c + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603/mmc5603_at_cmd.c + ${CMAKE_CURRENT_SOURCE_DIR}/service/mag_service.c +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/mmc5603 + ${CMAKE_CURRENT_SOURCE_DIR}/service +) +set(PUBLIC_DEFINES + MAG_MMC5603 + SUPPORT_AT_MMC5603 +) +endif() + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-incompatible-function-pointer-types + -Wno-unused-function +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +build_component() + +install_sdk(${CMAKE_CURRENT_SOURCE_DIR} "*") + +find_library(LIB_PATH_MMC5603 mmc5603/MemsicAlgo.a ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive ${LIB_PATH_MMC5603} PRIVATE -Wl,--whole-archive) \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/Customer.c b/code/sdk/drivers/peripheral/mag/mmc5603/Customer.c new file mode 100644 index 000000000..3fb542e82 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/Customer.c @@ -0,0 +1,195 @@ +#include "Customer.h" +#include "osal_timer.h" +#include "osal_mutex.h" +#include "pinctrl.h" +#include "chip_io.h" +#include "time.h" +#include "i2c.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "hal_i2c.h" +#include "soc_osal.h" +#include "tcxo.h" +#define MMC5603_I2C_BUS I2C_BUS_2 +#define MMC5603_I2C_TIME_MAX 3 +void mmc5603_Delay_Ms(int cnt) +{ + /* cnt is the time to wait */ + + uapi_tcxo_delay_ms(cnt); + return; +} +void mmc5603_Delay_Us(int cnt) +{ + /* cnt is the time to wait */ + + uapi_tcxo_delay_us(cnt); + + return; +} +static uint8_t g_mmc_installed = 0; +/* + * @brief platform specific initialization (platform dependent) + */ +static void mmc5603_i2c_init(void) +{ + errcode_t result; + /* init i2c */ + if ( g_mmc_installed == 1 ) + return ; + + result = uapi_i2c_master_init(MMC5603_I2C_BUS, 400000, I2C_SPEED_MODE_FS); /* 400000: 400KHz */ + if (result != ERRCODE_SUCC) { + MMC_ERROR("mmc5603 i2c init fail! ret=0x%x", result); + return ; + } + + MMC_WARNING("mmc5603:i2c_id = %d i2c_speed = %d \r\n", + MMC5603_I2C_BUS, 400000); + + g_mmc_installed = 1; + + return ; +} + +/* + * @brief Write generic device register (platform dependent) + * + * @param handle customizable argument. In this examples is used in + * order to select the correct sensor bus handler. + * @param reg register to write + * @param bufp pointer to data to write in register reg + * @param len number of consecutive register to write + * + */ +static int32_t mmc5603_platform_write(unsigned char i2c_add, uint8_t reg, const uint8_t *bufp, + uint16_t len) +{ + + errcode_t ret; + uint32_t retry; + i2c_data_t data; + uint8_t *write_data = NULL; + uint16_t send_len; + uint8_t *data_buf=bufp; + uint16_t data_len=len; + + mmc5603_i2c_init(); + send_len = data_len + sizeof(uint8_t); + write_data = (uint8_t *)osal_kmalloc(send_len, OSAL_GFP_KERNEL); + if (write_data == NULL) { + MMC_ERROR("mmc5603 send buff malloc fail!"); + return ERRCODE_FAIL; + } + write_data[0] = reg; + ret = (uint32_t)memcpy_s(write_data + sizeof(uint8_t), send_len - sizeof(uint8_t), data_buf, data_len); + if (ret != EOK) { + MMC_ERROR("mmc5603 send_buf content copy fail! ret=0x%x", ret); + return ret; + } + + data.send_buf = write_data; + data.send_len = send_len; + data.receive_buf = NULL; + data.receive_len = 0; + + for (retry = 0; retry < MMC5603_I2C_TIME_MAX; retry++) { + ret = uapi_i2c_master_write(MMC5603_I2C_BUS, i2c_add, &data); + if (ret == ERRCODE_SUCC) { + break; + } + } + if (ret != ERRCODE_SUCC) { + MMC_ERROR("mmc5603 data write fail! ret=0x%x", ret); + return ret; + } + + osal_kfree(write_data); + return 0; +} + +/* + * @brief Read generic device register (platform dependent) + * + * @param handle customizable argument. In this examples is used in + * order to select the correct sensor bus handler. + * @param reg register to read + * @param bufp pointer to buffer that store the data read + * @param len number of consecutive register to read + * + */ +static int32_t mmc5603_platform_read( unsigned char i2c_add,uint8_t reg, uint8_t *bufp, + uint16_t len) +{ + errcode_t ret; + uint32_t retry; + i2c_data_t data; + + mmc5603_i2c_init(); + memset_s(bufp, len, 0, len); + data.send_buf = ® + data.send_len = 1; + data.receive_buf = bufp; + data.receive_len = len; + + for (retry = 0; retry < MMC5603_I2C_TIME_MAX; retry++) { + ret = uapi_i2c_master_writeread(MMC5603_I2C_BUS, i2c_add, &data); + if (ret == ERRCODE_SUCC) { + break; + } + } + if (ret != ERRCODE_SUCC) { + MMC_ERROR("mmc5603 data read fail! ret=0x%x", ret); + return ret; + } + + return ERRCODE_SUCC; +} +int I2C_Write_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char cmd) +{ + /* i2c_add is the 7-bit i2c address of the sensor + * reg_add is the register address to wtite + * cmd is the value that need to be written to the register + * I2C operating successfully, return 1, otherwise return 0; + */ + + if ( ERRCODE_SUCC == mmc5603_platform_write(i2c_add,reg_add,&cmd,1)) + { + return 1; + }else{ + return 0; + } +} +int I2C_Read_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char *data) +{ + /* i2c_add is the 7-bit i2c address of the sensor + * reg_add is the register address to read + * data is the first address of the buffer that need to store the register value + * I2C operating successfully, return 1, otherwise return 0; + */ + + if ( ERRCODE_SUCC == mmc5603_platform_read(i2c_add,reg_add,data,1)) + { + return 1; + }else{ + return 0; + } + +} +int I2C_MultiRead_Reg(unsigned char i2c_add, unsigned char reg_add, int num, unsigned char *data) +{ + /* i2c_add is the 7-bit i2c address of the sensor + * reg_add is the first register address to read + * num is the number of the register to read + * data is the first address of the buffer that need to store the register value + * I2C operating successfully, return 1, otherwise return 0; + */ + + if ( ERRCODE_SUCC == mmc5603_platform_read(i2c_add,reg_add,data,num)) + { + return 1; + }else{ + return 0; + } +} + diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/Customer.h b/code/sdk/drivers/peripheral/mag/mmc5603/Customer.h new file mode 100644 index 000000000..585668424 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/Customer.h @@ -0,0 +1,53 @@ +#ifndef __MMC5603_PORTING_H__ +#define __MMC5603_PORTING_H__ +#include +#include +#include "debug_print.h" + +#define MMC_DEBUG + +#ifdef MMC_DEBUG +#define MMC_LOG(fmt, ...) \ + do { \ + PRINT(fmt"\r\n", ##__VA_ARGS__); \ + } while (0) +#else +#define MMC_LOG(ftm, ...) +#endif + +#define MMC_ERROR(x, ...) \ + do { \ + PRINT("[ERROR]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define MMC_WARNING(x, ...) \ + do { \ + PRINT("[WARNING]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +/** + * @brief Delay function. + */ +void mmc5603_Delay_Ms(int cnt); + +/** + * @brief Delay function. + */ +void mmc5603_Delay_Us(int cnt); + +/** + * @brief I2C write register. + */ +int I2C_Write_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char cmd); + +/** + * @brief I2C read register. + */ +int I2C_Read_Reg(unsigned char i2c_add, unsigned char reg_add, unsigned char *data); + +/** + * @brief I2C multi read. + */ +int I2C_MultiRead_Reg(unsigned char i2c_add, unsigned char reg_add, int num, unsigned char *data); + +#endif diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/MMC5603.c b/code/sdk/drivers/peripheral/mag/mmc5603/MMC5603.c new file mode 100644 index 000000000..8b5ab4163 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/MMC5603.c @@ -0,0 +1,461 @@ +/***************************************************************************** + * Copyright Statement: + * -------------------- + * This software is protected by Copyright, and the information and source code + * contained herein is confidential. The software including the source code + * may not be copied and the information contained herein may not be used or + * disclosed except with the written permission of MEMSIC Inc. (C) 2019 + *****************************************************************************/ + + /** + * @brief + * This file implement magnetic sensor driver APIs. + * Modified history: + * V1.5: Update to 1 step factory selftest on 20190619 + */ + +#include "MMC5603.h" +#include "Customer.h" + +#include "math.h" + +/* Indicate working mode of sensor */ +static uint8_t sensor_state = 1; + +/* Function declaration */ + +/** + * @brief Factory test mode + */ +int MMC5603_Factory_Test_Mode(void); + +/** + * @brief SET operation + */ +void MMC5603_SET(void); + +/** + * @brief RESET operation + */ +void MMC5603_RESET(void); + +/** + * @brief OTP read done check + */ +int MMC5603_Check_OTP(void); + +/** + * @brief Check Product ID + */ +int MMC5603_CheckID(void); + +/** + * @brief Auto self-test registers configuration + */ +void MMC5603_Auto_SelfTest_Configuration(void); + +/** + * @brief Auto self-test + */ +int MMC5603_Auto_SelfTest(void); + +/********************************************************************************* +* decription: Factory test mode +*********************************************************************************/ +int MMC5603_Factory_Test_Mode(void) +{ + int i; + uint8_t data_reg[6] ={0}; + uint16_t data_set[3] = {0}; + uint16_t data_reset[3] = {0}; + uint32_t delta_data[3] = {0}; + + const uint16_t thr_srst_low = 100; + + /* Write reg 0x1D */ + /* Set Cmm_en bit '0', Disable continuous mode */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL2, 0x00); + + mmc5603_Delay_Ms(20); + + /* Write reg 0x1B */ + /* Set Auto_SR_en bit '0', Disable the function of automatic set/reset */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL0, 0x00); + + /* Write reg 0x1C, Set BW<1:0> = 00 */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL1, 0x00); + + /* Do RESET operation */ + MMC5603_RESET(); + /* Write 0x01 to register 0x1B, set Take_meas_M bit '1' */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL0, MMC5603_CMD_TMM); + /* Delay 10 ms to finish the TM operation */ + mmc5603_Delay_Ms(10); + /* Read register data */ + I2C_MultiRead_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_DATA, 6, data_reg); + /* Get high 16bits data */ + data_reset[0] = (uint16_t)(data_reg[0] << 8 | data_reg[1]); //X axis + data_reset[1] = (uint16_t)(data_reg[2] << 8 | data_reg[3]); //Y axis + data_reset[2] = (uint16_t)(data_reg[4] << 8 | data_reg[5]); //Z axis + + /* Do SET operation */ + MMC5603_SET(); + /* Write 0x01 to register 0x1B, set Take_meas_M bit '1' */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS,MMC5603_REG_CTRL0,MMC5603_CMD_TMM); + /* Delay 10 ms to finish the TM operation */ + mmc5603_Delay_Ms(10); + /* Read register data */ + I2C_MultiRead_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_DATA, 6, data_reg); + /* Get high 16bits data */ + data_set[0] = (uint16_t)(data_reg[0] << 8 | data_reg[1]); //X axis + data_set[1] = (uint16_t)(data_reg[2] << 8 | data_reg[3]); //Y axis + data_set[2] = (uint16_t)(data_reg[4] << 8 | data_reg[5]); //Z axis + + for(i=0;i<3;i++) + { + if(data_set[i] >= data_reset[i]) + delta_data[i] = data_set[i] - data_reset[i]; + else + delta_data[i] = data_reset[i] - data_set[i]; + } + + /* If output < 100lsb, fail*/ + if(delta_data[0]255) + st_thd_reg[i] = 0xFF; + else + st_thd_reg[i] = (uint8_t)st_thd[i]; + } + /* Write threshold into the reg 0x1E-0x20 */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_X_THD, st_thd_reg[0]); + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_Y_THD, st_thd_reg[1]); + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_Z_THD, st_thd_reg[2]); + + return; +} + +/********************************************************************************* +* decription: Auto self-test +*********************************************************************************/ +int MMC5603_Auto_SelfTest(void) +{ + uint8_t reg_status = 0; + + /* Write 0x40 to register 0x1B, set Auto_st_en bit high */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL0, MMC5603_CMD_AUTO_ST_EN); + + /* Delay 15ms to finish the selftest process */ + mmc5603_Delay_Ms(15); + + /* Read register 0x18, check Sat_sensor bit */ + I2C_Read_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_STATUS1, ®_status); + if((reg_status&MMC5603_SAT_SENSOR)) + { + return -1; + } + + return 1; +} + +/********************************************************************************* +* decription: Continuous mode configuration with auto set and reset +*********************************************************************************/ +void MMC5603_Continuous_Mode_With_Auto_SR(uint8_t bandwith, uint8_t sampling_rate) +{ + /* Write reg 0x1C, Set BW<1:0> = bandwith */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL1, bandwith); + + /* Write reg 0x1A, set ODR<7:0> = sampling_rate */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_ODR, sampling_rate); + + /* Write reg 0x1B */ + /* Set Auto_SR_en bit '1', Enable the function of automatic set/reset */ + /* Set Cmm_freq_en bit '1', Start the calculation of the measurement period according to the ODR*/ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL0, MMC5603_CMD_CMM_FREQ_EN|MMC5603_CMD_AUTO_SR_EN); + + /* Write reg 0x1D */ + /* Set Cmm_en bit '1', Enter continuous mode */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL2, MMC5603_CMD_CMM_EN); + + return; +} + +/********************************************************************************* +* decription: Do selftest operation periodically +*********************************************************************************/ +int MMC5603_Saturation_Checking(void) +{ + int ret = 0; //1 pass, -1 fail, 0 elapsed time is less 5 seconds + + /* If sampling rate is 50Hz, then do saturation checking every 250 loops, i.e. 5 seconds */ + static int NumOfSamples = 250; + static int cnt = 0; + + if((cnt++)>=NumOfSamples) + { + cnt = 0; + ret = MMC5603_Auto_SelfTest(); + if(ret == -1) + { + /* Sensor is saturated, need to do SET operation */ + MMC5603_SET(); + } + + /* Do TM_M after selftest operation */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS,MMC5603_REG_CTRL0,MMC5603_CMD_TMM); + mmc5603_Delay_Ms(8); + } + + return ret; +} + +/********************************************************************************* +* decription: Auto switch the working mode between Auto_SR and SETonly +*********************************************************************************/ +void MMC5603_Auto_Switch(uint16_t *mag) +{ + float mag_out[3]; + + mag_out[0] = ((float)mag[0] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY; + mag_out[1] = ((float)mag[1] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY; + mag_out[2] = ((float)mag[2] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY; + + if(sensor_state == 1) + { + /* If X or Y axis output exceed 10 Gauss, then switch to single mode */ + if((fabs(mag_out[0])>10.0f) || (fabs(mag_out[1])>10.0f)) + { + sensor_state = 2; + + /* Disable continuous mode */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL2, 0x00); + mmc5603_Delay_Ms(15);//Delay 15ms to finish the last sampling + + /* Do SET operation */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL0, MMC5603_CMD_SET); + mmc5603_Delay_Ms(1);//Delay 1ms to finish the SET operation + + /* Do TM_M before next data reading */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS,MMC5603_REG_CTRL0,MMC5603_CMD_TMM); + mmc5603_Delay_Ms(8);//Delay 8ms to finish the TM_M operation + } + } + else if(sensor_state == 2) + { + /* If both of X and Y axis output less than 8 Gauss, then switch to continuous mode with Auto_SR */ + if((fabs(mag_out[0])<8.0f) && (fabs(mag_out[1])<8.0f)) + { + sensor_state = 1; + + /* Enable continuous mode with Auto_SR */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL0, MMC5603_CMD_CMM_FREQ_EN|MMC5603_CMD_AUTO_SR_EN); + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL2, MMC5603_CMD_CMM_EN); + } + else + { + /* Sensor checking */ + if(MMC5603_Saturation_Checking()==0) + { + /* Do TM_M before next data reading */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS,MMC5603_REG_CTRL0,MMC5603_CMD_TMM); + } + } + } + + return; +} + +/********************************************************************************* +* decription: Disable sensor continuous mode +*********************************************************************************/ +void MMC5603_Disable(void) +{ + /* Write reg 0x1D */ + /* Set Cmm_en bit '0', Disable continuous mode */ + I2C_Write_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_CTRL2, 0x00); + + mmc5603_Delay_Ms(20); + + return; +} + +/********************************************************************************* +* decription: Enable sensor +*********************************************************************************/ +void MMC5603_Enable(void) +{ + int ret = 0; + + /* Inite the sensor state */ + sensor_state = 1; + + /* Check product ID */ + ret = MMC5603_CheckID(); + if(ret<0) + return; + + /* Auto self-test registers configuration */ + MMC5603_Auto_SelfTest_Configuration(); + + /* Do SET operation */ + MMC5603_SET(); + + /* Work mode setting */ + MMC5603_Continuous_Mode_With_Auto_SR(MMC5603_CMD_BW00, 50); + + mmc5603_Delay_Ms(20); + + return; +} +/****************滤波函数******************/ +#define BUFFER_LEN 10 +typedef struct { + float x[BUFFER_LEN]; + float y[BUFFER_LEN]; + float z[BUFFER_LEN]; +} mag_data_buf_t; +static int g_mag_data_buf_index = 0; +static mag_data_buf_t g_mag_data_temp_buf={0}; +static void filter_index_plus(void) +{ + g_mag_data_buf_index++; + if (g_mag_data_buf_index >= BUFFER_LEN) g_mag_data_buf_index = 0; +} +static float get_filter_data_x( float inputx) +{ + // if (g_mag_data_buf_index >= BUFFER_LEN) g_mag_data_buf_index = 0; + g_mag_data_temp_buf.x[g_mag_data_buf_index] = inputx; + int i = 0 ; + float sum = 0.0f; + for( i =0 ; i < BUFFER_LEN ; i++) + { + sum += g_mag_data_temp_buf.x[i]; + } + return sum / BUFFER_LEN ; +} +static float get_filter_data_y( float inputx) +{ + // if (g_mag_data_buf_index >= BUFFER_LEN) g_mag_data_buf_index = 0; + g_mag_data_temp_buf.y[g_mag_data_buf_index] = inputx; + int i = 0 ; + float sum = 0.0f; + for( i =0 ; i < BUFFER_LEN ; i++) + { + sum += g_mag_data_temp_buf.y[i]; + } + return sum / BUFFER_LEN ; +} +static float get_filter_data_z( float inputx) +{ + // if (g_mag_data_buf_index >= BUFFER_LEN) g_mag_data_buf_index = 0; + g_mag_data_temp_buf.z[g_mag_data_buf_index] = inputx; + int i = 0 ; + float sum = 0.0f; + for( i =0 ; i < BUFFER_LEN ; i++) + { + sum += g_mag_data_temp_buf.z[i]; + } + return sum / BUFFER_LEN ; +} + +/********************************************************************************* +* decription: Read the data register and convert to magnetic field +*********************************************************************************/ +void MMC5603_GetData(float *mag_out) +{ + uint8_t data_reg[6] ={0}; + uint16_t data_temp[3] = {0}; + + /* Read register data */ + I2C_MultiRead_Reg(MMC5603_7BITI2C_ADDRESS, MMC5603_REG_DATA, 6, data_reg); + + /* Get high 16bits data */ + data_temp[0] = (uint16_t)(data_reg[0] << 8 | data_reg[1]); + data_temp[1] = (uint16_t)(data_reg[2] << 8 | data_reg[3]); + data_temp[2] = (uint16_t)(data_reg[4] << 8 | data_reg[5]); + + /* Transform to unit Gauss */ + mag_out[0] = ((float)data_temp[0] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY; + mag_out[1] = ((float)data_temp[1] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY; + mag_out[2] = ((float)data_temp[2] - MMC5603_16BIT_OFFSET)/MMC5603_16BIT_SENSITIVITY; + + mag_out[0] = get_filter_data_x(mag_out[0]); + mag_out[1] = get_filter_data_y(mag_out[1]); + mag_out[2] = get_filter_data_z(mag_out[2]); + filter_index_plus(); + + MMC5603_Auto_Switch(data_temp); + + return; +} diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/MMC5603.h b/code/sdk/drivers/peripheral/mag/mmc5603/MMC5603.h new file mode 100644 index 000000000..a7461d4d8 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/MMC5603.h @@ -0,0 +1,127 @@ +/***************************************************************************** + * Copyright Statement: + * -------------------- + * This software is protected by Copyright and the information and source code + * contained herein is confidential. The software including the source code + * may not be copied and the information contained herein may not be used or + * disclosed except with the written permission of MEMSIC Inc. (C) 2019 + *****************************************************************************/ + + /** + * @brief + * This file implement magnetic sensor driver APIs. + * Modified history: + * V1.5: Update to 1 step factory selftest on 20190619 + */ + +#ifndef _MMC5603_H +#define _MMC5603_H + +#include +#include +#include +#include +// typedef signed char int8_t; // signed 8-bit number (-128 to +127) +// typedef unsigned char uint8_t; // unsigned 8-bit number (+0 to +255) +// typedef signed short int16_t; // signed 16-bt number (-32768 to +32767) +// typedef unsigned short uint16_t; // unsigned 16-bit number (+0 to +65535) +// typedef signed int int32_t; // signed 32-bt number (-2,147,483,648 to +2,147,483,647) +// typedef unsigned int uint32_t; // unsigned 32-bit number (+0 to +4,294,967,295) + +#define MMC5603_7BITI2C_ADDRESS 0x30 + +#define MMC5603_REG_DATA 0x00 + +#define MMC5603_REG_STATUS1 0x18 +#define MMC5603_REG_STATUS0 0x19 + +#define MMC5603_REG_ODR 0x1A +#define MMC5603_REG_CTRL0 0x1B +#define MMC5603_REG_CTRL1 0x1C +#define MMC5603_REG_CTRL2 0x1D + +#define MMC5603_REG_X_THD 0x1E +#define MMC5603_REG_Y_THD 0x1F +#define MMC5603_REG_Z_THD 0x20 + +#define MMC5603_REG_ST_X_VAL 0x27 +#define MMC5603_REG_ST_Y_VAL 0x28 +#define MMC5603_REG_ST_Z_VAL 0x29 + +#define MMC5603_REG_PRODUCTID1 0x39 + +/* Bit definition for control register ODR 0x1A */ +#define MMC5603_CMD_ODR_1HZ 0x01 +#define MMC5603_CMD_ODR_5HZ 0x05 +#define MMC5603_CMD_ODR_10HZ 0x0A +#define MMC5603_CMD_ODR_50HZ 0x32 +#define MMC5603_CMD_ODR_100HZ 0x64 +#define MMC5603_CMD_ODR_200HZ 0xC8 +#define MMC5603_CMD_ODR_255HZ 0xFF + +/* Bit definition for control register 0 0x1B */ +#define MMC5603_CMD_TMM 0x01 +#define MMC5603_CMD_TMT 0x02 +#define MMC5603_CMD_START_MDT 0x04 +#define MMC5603_CMD_SET 0x08 +#define MMC5603_CMD_RESET 0x10 +#define MMC5603_CMD_AUTO_SR_EN 0x20 +#define MMC5603_CMD_AUTO_ST_EN 0x40 +#define MMC5603_CMD_CMM_FREQ_EN 0x80 + +/* Bit definition for control register 1 0x1C */ +#define MMC5603_CMD_BW00 0x00 +#define MMC5603_CMD_BW01 0x01 +#define MMC5603_CMD_BW10 0x02 +#define MMC5603_CMD_BW11 0x03 +#define MMC5603_CMD_ST_ENP 0x20 +#define MMC5603_CMD_ST_ENM 0x40 +#define MMC5603_CMD_SW_RST 0x80 + +/* Bit definition for control register 2 0x1D */ +#define MMC5603_CMD_PART_SET1 0x00 +#define MMC5603_CMD_PART_SET25 0x01 +#define MMC5603_CMD_PART_SET75 0x02 +#define MMC5603_CMD_PART_SET100 0x03 +#define MMC5603_CMD_PART_SET250 0x04 +#define MMC5603_CMD_PART_SET500 0x05 +#define MMC5603_CMD_PART_SET1000 0x06 +#define MMC5603_CMD_PART_SET2000 0x07 +#define MMC5603_CMD_EN_PART_SET 0x08 +#define MMC5603_CMD_CMM_EN 0x10 +#define MMC5603_CMD_INT_MDT_EN 0x20 +#define MMC5603_CMD_INT_MD_EN 0x40 +#define MMC5603_CMD_HPOWER 0x80 + +#define MMC5603_PRODUCT_ID 0x10 +#define MMC5603_MM_DONE_INT 0x01 +#define MMC5603_MT_DONE_INT 0x02 +#define MMC5603_MDT_FLAG_INT 0x04 +#define MMC5603_ST_FAIL_INT 0x08 +#define MMC5603_OTP_READ_DONE 0x10 +#define MMC5603_SAT_SENSOR 0x20 +#define MMC5603_MM_DONE 0x40 +#define MMC5603_MT_DONE 0x80 + +// 16-bit mode, null field output (32768) +#define MMC5603_16BIT_OFFSET 32768 +#define MMC5603_16BIT_SENSITIVITY 1024 + +/** + * @brief Enable the sensor + */ +void MMC5603_Enable(void); + +/** + * @brief Disable the sensor + */ +void MMC5603_Disable(void); + +/** + * @brief Get sensor data + * @param mag_out is the magnetic field vector, unit is gauss + */ +void MMC5603_GetData(float *mag_out); + +#endif + diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/MemsicAlgo.a b/code/sdk/drivers/peripheral/mag/mmc5603/MemsicAlgo.a new file mode 100644 index 000000000..9af3d8c04 Binary files /dev/null and b/code/sdk/drivers/peripheral/mag/mmc5603/MemsicAlgo.a differ diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/MemsicAlgo.h b/code/sdk/drivers/peripheral/mag/mmc5603/MemsicAlgo.h new file mode 100644 index 000000000..ce1166575 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/MemsicAlgo.h @@ -0,0 +1,119 @@ +/***************************************************************************** +* Copyright (C), 2018, MEMSIC Inc. +* File Name : MemsicAlgo.h +* Author : MEMSIC AE Algoritm Team +* Description : This file is the head file of MemsicAlgo.lib. It provides the +* interface function declarations of the lib. +* History : 1. Data : 20180801 +* 2. Author : YGP +* 3. Modification : +*****************************************************************************/ +#ifndef _MEMSICALGORITHM_H_ +#define _MEMSICALGORITHM_H_ + +#define ANDROID_PLATFORM 1 +#define EVB_PLATFORM 2 +#define WINDOWS_PLATFORM 3 +#define PLATFORM EVB_PLATFORM + +#if((PLATFORM == ANDROID_PLATFORM)||(PLATFORM == EVB_PLATFORM)) +#define DLL_API +#define _stdcall +#elif(PLATFORM == WINDOWS_PLATFORM) +#define DLL_API extern "C" __declspec(dllexport) +#endif + +#if(PLATFORM == ANDROID_PLATFORM) +#include "MemsicConfig.h" +#include //ALOGE +#endif + +#ifndef MEMSIC_ALGORITHM_DATA_TYPES +#define MEMSIC_ALGORITHM_DATA_TYPES +typedef signed char int8; // signed 8-bit number (-128 to +127) +typedef unsigned char uint8; // unsigned 8-bit number (+0 to +255) +typedef signed short int16; // signed 16-bt number (-32,768 to +32,767) +typedef unsigned short uint16; // unsigned 16-bit number (+0 to +65,535) +typedef signed int int32; // signed 32-bit number (-2,147,483,648 to +2,147,483,647) +typedef unsigned int uint32; // unsigned 32-bit number (+0 to +4,294,967,295) +#endif + +#if(PLATFORM == ANDROID_PLATFORM) +/******************************************************************************************* +* Function Name : AlgoInitial +* Description : Initialize the algorithm. +* Input : None +* Output : None. +* Return : 1 --- succeed. +* -1 --- fail. +********************************************************************************************/ +int AlgoInitial(void); +#elif((PLATFORM == EVB_PLATFORM)||(PLATFORM == WINDOWS_PLATFORM)) +/******************************************************************************************* +* Function Name : InitialAlgorithm +* Description : Initial the corrected parameters for magnetic sensor. +* Input : sim[0-8] ---soft iron corrected parameters; +* mag_para[0-2]---mag offset; +* mag_para[3] ---mag radius or magnetic field strength; +* Output : None. +* Return : 1 --- succeed. +* -1 --- fail. +********************************************************************************************/ +DLL_API int _stdcall InitialAlgorithm(float *sim, float *mag_para); +#endif +/******************************************************************************************* +* Function Name : MainAlgorithmProcess +* Description : Pass the Acc and Mag raw data to the algorithm library. +* Input : acc[0-2] --- Acceleration raw data of three axis, unit is g; +* mag[0-2] --- Magnetic raw data of three axis, unit is gauss; +* enable_cali --- 1 means automatic mag calibration is enabled, 0 not; +* Output : None. +* Return : 1 --- succeed. +* -1 --- fail. +********************************************************************************************/ +DLL_API int _stdcall MainAlgorithmProcess(float *acc, float *mag, int enable_cali); + +/******************************************************************************************* +* Function Name : GetMagAccuracy +* Description : Get the accuracy of the calibration algorithm. +* Input : None +* Output : None +* Return : 0 --- Unreliable. +* : 1 --- Low. +* : 2 --- Medium. +* : 3 --- High. +********************************************************************************************/ +DLL_API int _stdcall GetMagAccuracy(void); + +/******************************************************************************************* +* Function Name : GetMagSaturation +* Description : Get the magnetic sensor saturation status. +* Input : None +* Output : None +* Return : 0 --- Indicate that magnetic sensor works normally. +* : 1 --- Indicate that magnetic sensor is saturated, need to do SET action. +********************************************************************************************/ +DLL_API int _stdcall GetMagSaturation(void); + +/******************************************************************************************* +* Function Name : GetCalPara +* Description : Get the calibrated parameters of magnetic sensor. +* Input : None +* Output : cp[0-2] --- magnetic field offset, unit is gauss. +* cp[3] --- strength of the magnetic field, unit is gauss. +* Return : 0 --- no need to save the calibrated magnetometer parameter. +* 1 --- need to save the new reliable calibrated magnetometer parameter. +********************************************************************************************/ +DLL_API int _stdcall GetCalPara(float *cp); + +/******************************************************************************************* +* Function Name : GetCalMag +* Description : Get the MEMSIC calibrated magnetic output. +* Input : None +* Output : cm[0-2] --- calibrated magnetic sensor data, unit is gauss. +* Return : debug use +********************************************************************************************/ +DLL_API int _stdcall GetCalMag(float *cm); + +#endif + diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/MemsicCompass.h b/code/sdk/drivers/peripheral/mag/mmc5603/MemsicCompass.h new file mode 100644 index 000000000..4b48c9252 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/MemsicCompass.h @@ -0,0 +1,64 @@ +/***************************************************************************** +* Copyright (C), 2018, MEMSIC Inc. +* File Name : MemsicAlgo.h +* Author : MEMSIC AE Algoritm Team +* Description : This file is the head file of MemsicAlgo.lib. It provides the +* interface function declarations of the lib. +* History : 1. Data : 20180424 +* 2. Author : Yan Guopu +* 3. Modification : +*****************************************************************************/ +#ifndef _MEMSIC_COMPASS_H_ +#define _MEMSIC_COMPASS_H_ + +#define ANDROID_PLATFORM 1 +#define EVB_PLATFORM 2 +#define WINDOWS_PLATFORM 3 +#define PLATFORM EVB_PLATFORM + +#if((PLATFORM == ANDROID_PLATFORM)||(PLATFORM == EVB_PLATFORM)) +#define DLL_API +#define _stdcall +#elif(PLATFORM == WINDOWS_PLATFORM) +#define DLL_API extern "C" __declspec(dllexport) +#endif + +#if(PLATFORM == ANDROID_PLATFORM) +#include //ALOGE +#endif + +#ifndef MEMSIC_COMPASS_DATA_TYPES +#define MEMSIC_COMPASS_DATA_TYPES +// typedef signed char int8_t; // signed 8-bit number (-128 to +127) +// typedef unsigned char uint8_t; // unsigned 8-bit number (+0 to +255) +// typedef signed short int16_t; // signed 16-bt number (-32,768 to +32,767) +// typedef unsigned short uint16_t; // unsigned 16-bit number (+0 to +65,535) +// typedef signed int int32_t; // signed 32-bit number (-2,147,483,648 to +2,147,483,647) +// typedef unsigned int uint32_t; // unsigned 32-bit number (+0 to +4,294,967,295) +#endif + +/******************************************************************************************* +* Function Name : InitialCompassAlgo +* Description : Initial the filter coeficient for the compass filter. +* Input : sim[0-8] ---soft iron corrected parameters; +* mag_para[0-2]---mag offset; +* mag_para[3] ---mag radius or magnetic field strength; +* Output : None. +* Return : 1 --- succeed. +* -1 --- fail. +********************************************************************************************/ +DLL_API int _stdcall InitialCompassAlgo(float fc); + +/******************************************************************************************* +* Function Name : GetCalOri +* Description : Get the MEMSIC calibrated orientation vector. +* Input : acc[0-2] --- Accelerometer data of three axis, unit is gauss. +* : mag[0-2] --- Magnetic raw data of three axis, unit is gauss. +* Output : co[0-2] --- orientation data, azimuth, pitch, roll, unit is degree. +* Return : 1 --- succeed. +* -1 --- fail. +********************************************************************************************/ +DLL_API int _stdcall GetCalOri(float *acc, float *mag, float *co); + +#endif + diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_at_cmd.c b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_at_cmd.c new file mode 100644 index 000000000..869c7c2ca --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_at_cmd.c @@ -0,0 +1,72 @@ + +// #include "mmc5603.h" + + +#include "at_cmd_api.h" +#include "pm_control.h" +#include "MMC5603.h" +#include "Customer.h" +#include "mag_service.h" + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define MMC5603_MAX_ARGC 8 +#define MMC5603_MAX_ARGV_LEN 64 + +#define MMC5603_SUCCESS 0 +#define MMC5603_FAILED (-1) + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[MMC5603_MAX_ARGC][MMC5603_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 >= MMC5603_MAX_ARGC) { + return MMC5603_FAILED; + } + } else { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= MMC5603_MAX_ARGV_LEN) { + return MMC5603_FAILED; + } + } + } + if (pos != 0) { + *argc += 1; + } + + return MMC5603_SUCCESS; +} + +static uint32_t mmc5603_start_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + UNUSED(paraLen); + UNUSED(para); + do_mag_service_check_msg(MAG_SERVICE_CMD_START_CHECK); + return ERRCODE_SUCC; +} +static uint32_t mmc5603_stop_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + UNUSED(paraLen); + UNUSED(para); + do_mag_service_check_msg(MAG_SERVICE_CMD_STOP_CHECK); + return ERRCODE_SUCC; +} +static const at_cmd_table_t g_mmc5603_cmd[] = { + { (char *)"AT^MMC5603TESTSTART", mmc5603_start_test, (char *)"1" }, + { (char *)"AT^MMC5603TESTSTOP", mmc5603_stop_test, (char *)"1" }, +}; + +at_cmd_table_t *get_mmc5603_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_mmc5603_cmd); + return (at_cmd_table_t *)g_mmc5603_cmd; +} diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_at_cmd.h b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_at_cmd.h new file mode 100644 index 000000000..1f2dd30ce --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 MMC5603_AT_PROCESS_H +#define MMC5603_AT_PROCESS_H + +#include +#include +#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_mmc5603_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_hal.h b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_hal.h new file mode 100644 index 000000000..8f769a5f9 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_hal.h @@ -0,0 +1,34 @@ +/** + * 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 MMC5603_HAL_H +#define MMC5603_HAL_H + +#include +#include +#include "errcode.h" +#include "soc_osal.h" +#include "at_cmd_api.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +int mmc5603_stop(void); +int mmc5603_check(void); +int mmc5603_start(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_main.c b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_main.c new file mode 100644 index 000000000..7f3aa4fd0 --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/mmc5603/mmc5603_main.c @@ -0,0 +1,390 @@ +/* This sample code teaches developer how to operate the MEMSIC alogrithm library + * to get Yaw, Pitch and Roll respectively. if developer want to use it as a part + * of his codes, he need to declare and define 3 functions by himself: + * ReadPara; + * Savepara; + * please NOTE it is ONLY a sample code and can be changed freely by developers. + */ + +#include "MemsicAlgo.h" +#include "MemsicCompass.h" +#include "Customer.h" +#include "MMC5603.h" + +#ifdef ACC_LIS2DOC +#include "acc_service.h" +#endif +float magnetic_field_x; +float magnetic_field_y; +float magnetic_field_z; + +#define A_LAYOUT 0 +#define M_LAYOUT 5 + +/* These variables are used to save the magnetic sensor calibrated data. */ +float calMagX, calMagY, calMagZ; + +/* These variables are used to save the calibrated orientation output. */ +float fAzimuth, fPitch, fRoll; + +/* This variable is used to save the calibration accuracy. */ +int iAccuracy; + +/* Read saved calibration parameters. These para is saved in somewhere that can not disappear when power-off + * ReadPara function should be create by customer.If customer can not implement this function, should comment it out + * If there is no parameter saved, ReadPara() should return -1, else return 1; + * If there is no para saved, pass the default value to the algorithm library + */ +int ReadPara(float *p); + +/* Save calibration parameters in somewhere that can not lose after power-off. + * When the system power on next time, need to read this parameters by the function ReadPara() for algorithm initial. + * If save parameter successfully, return 1, else return -1; + */ +int SavePara(float *p); + + +/** + * @brief Convert the sensor coordinate to right-front-up coordinate system; + */ +void acc_coordinate_raw_to_real(int layout, float *in, float *out); + +/** + * @brief Convert the sensor coordinate to right-front-up coordinate system; + */ +void mag_coordinate_raw_to_real(int layout, float *in, float *out); + +/** + * 校准数据 + */ +static float g_MagPara[4] = {0.0f}; + +/******************************************************************************* +* Function Name : main +* Description : the main function +*******************************************************************************/ + + + /* This variable is used to save calibrated mag para that need to be saved in system file */ +static float saveData[4] = {0.0f}; + +int mmc5603_start(void) +{ + int i; + /* magnetic sensor soft iron calibration matrix, default is unit matrix */ + float mag_smm[9] = { 1.0f, 0.0f, 0.0f, \ + 0.0f, 1.0f, 0.0f, \ + 0.0f, 0.0f, 1.0f}; + + /* default hard iron offset and magnetic field strength*/ + float mag_hmm[4] = {0.0f,0.0f,0.0f,0.5f}; + /* Read saved calibration parameters. These para is saved in somewhere that can not disappear when power-off + * ReadPara function should be create by customer.If customer can not implement this function, should comment it out + * If there is no parameter saved, ReadPara() should return -1, else return 1; + * If there is no para saved, pass the default value to the algorithm library + */ + if(ReadPara(saveData)==1){ + for(i=0;i<4;i++){ + mag_hmm[i] = saveData[i]; + } + } + + /* Initial the acc, mag, and calibrated parameters + * if already saved the calibrated offset and radius last time, read it out and init the magOffset and magRadius + */ + InitialAlgorithm(mag_smm, mag_hmm); + + /* Enable the sensor. */ + MMC5603_Enable(); + return 0; +} + + + + +int mmc5603_check(void) +{ + +#ifdef XTS_SUPPORT +extern uint8_t is_xts_test_done(void); + if (is_xts_test_done() == 0) + return 0; +#endif + int i; + + /* This variable is used to store the accelerometer and magnetometer raw data. + * please NOTE that the data is going to store here MUST has been transmitted + * to match the Right-Handed coordinate sytem already. + */ + + float acc_raw_data[3] = {0.0f}; //accelerometer field vector, unit is g + float acc_real_data[3] = {0.0f}; + + float mag_raw_data[3] = {0.0f}; //magnetic field vector, unit is gauss + float mag_real_data[3] = {0.0f}; + + /* This variable is used to judge whether or not the developer + * should save the parameters in one place where will be read + * by the algorithm every time when the device restart. + * save_flag is a flag to if we need to save algorithm parameter into the system file. + */ + int save_flag=0; + /* Get the acc raw data, unit is g*/ + #ifdef ACC_LIS2DOC + lis2doc_read_data_single(&acc_raw_data[0],&acc_raw_data[1],&acc_raw_data[2]); + #endif + //acc_raw_data[0] = ; + //acc_raw_data[1] = ; + //acc_raw_data[2] = ; + + /* This variable is used to save the calibrated mag sensor XYZ output. */ + float caliMag[3] = {0.0f}; + + /* This variable is used to save the calibrated orientation data. */ + float caliOri[3] = {0.0f}; + + /* This variable is used to save calibrated mag sensor parameters */ + float caliMagPara[4] = {0.0f}; + /* convert the coordinate system */ + acc_coordinate_raw_to_real(A_LAYOUT, acc_raw_data, acc_real_data); + + /* Get the MMC5603 mag raw data, unit is gauss */ + MMC5603_GetData(mag_raw_data); + + /* Convert the coordinate system */ + mag_coordinate_raw_to_real(M_LAYOUT, mag_raw_data, mag_real_data); + + /* Below functions are algorithm interface. + * input acc, mag data into algorithm + * make sure that acc and mag XYZ data meet the right-hand(right-front-up) coordinate system + */ + MainAlgorithmProcess(acc_real_data, mag_real_data, 1); + + /* Get calibrated mag data */ + GetCalMag(caliMag); + + /* Calibrated magnetic sensor output, unit is gauss */ + calMagX = caliMag[0]; + calMagY = caliMag[1]; + calMagZ = caliMag[2]; + + + /* Get orientation vector */ + if (GetCalOri(acc_real_data, caliMag, caliOri) == 1 ) + { + + /* Get the accuracy of the algorithm */ + iAccuracy = GetMagAccuracy(); + + /* Get the fAzimuth Pitch Roll for the eCompass */ + fAzimuth = caliOri[0]; + fPitch = caliOri[1]; + fRoll = caliOri[2]; + if(iAccuracy == 3){ + PRINT("== Mag x %.02F,y %.02F , z %.02F\r\n", + calMagX,//高斯X + calMagY,//高斯Y + calMagZ//高斯Z + ); + PRINT("iAccuracy %d== Acc Azimuth %.02F,Pitch %.02F , Roll %.02F\r\n", + iAccuracy,//可信度 + fAzimuth, //水平方向角,左转右转 + fPitch,//上下俯仰角 + fRoll//左右翻滚角 + ); + }else{ + PRINT("iAccuracy %d < 3 skip\r\n", + iAccuracy //可信度 + ); + + } + } + + + /* Get the SET Flag from algorithm */ + if(GetMagSaturation()) + { + //MEMSIC_Magnetic_Sensor_SET(); //Do SET action + PRINT("Do SET action MMC5603_SET\r\n"); + MMC5603_SET(); + } + + /* Get corrected mag data */ + save_flag = GetCalPara(caliMagPara); + + if(save_flag == 1) + { + /* Get the offset and radius that need to be saved in system file */ + for(i=0;i<4;i++) + { + saveData[i] = caliMagPara[i]; + } + /* Save the calpara buffer into the system file */ + /* This function should be create by customer.If customer can not implement this function, should comment it out */ + SavePara(saveData); + PRINT("save para \r\n"); + } + + /* Sampling interval is 20ms. */ + // mmc5603_Delay_Ms(20); + + return 0; +} + +/* Read saved calibration parameters. These para is saved in somewhere that can not disappear when power-off + * ReadPara function should be create by customer.If customer can not implement this function, should comment it out + * If there is no parameter saved, ReadPara() should return -1, else return 1; + * If there is no para saved, pass the default value to the algorithm library + */ +int ReadPara(float *p) +{ + int i; + /* + . + . Need to be implemented by user. + . + */ + + for(i=0;i<4;i++){ + p[i] = g_MagPara[i]; + } + return 1; +} + +/* Save calibration parameters in somewhere that can not lose after power-off. + * When the system power on next time, need to read this parameters by the function ReadPara() for algorithm initial. + * If save parameter successfully, return 1, else return -1; + */ +int SavePara(float *p) +{ + /* + . + . Need to be implemented by user. + . + */ + int i=0; + for(i=0;i<4;i++){ + g_MagPara[i] = p[i]; + } + + return 1; +} + +/* Convert the sensor coordinate to right-front-up coordinate system; + */ +void acc_coordinate_raw_to_real(int layout, float *in, float *out) +{ + switch (layout) { + case 0: + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + break; + case 1: + out[0] = -in[1]; + out[1] = in[0]; + out[2] = in[2]; + break; + case 2: + out[0] = -in[0]; + out[1] = -in[1]; + out[2] = in[2]; + break; + case 3: + out[0] = in[1]; + out[1] = -in[0]; + out[2] = in[2]; + break; + case 4: + out[0] = in[1]; + out[1] = in[0]; + out[2] = -in[2]; + break; + case 5: + out[0] = -in[0]; + out[1] = in[1]; + out[2] = -in[2]; + break; + case 6: + out[0] = -in[1]; + out[1] = -in[0]; + out[2] = -in[2]; + break; + case 7: + out[0] = in[0]; + out[1] = -in[1]; + out[2] = -in[2]; + break; + default: + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + break; + } +} +/* Convert the sensor(MMC3630KJ) coordinate to right-front-up coordinate system; + */ +void mag_coordinate_raw_to_real(int layout, float *in, float *out) +{ + switch (layout) { + case 0: + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + break; + case 1: + out[0] = -in[1]; + out[1] = in[0]; + out[2] = in[2]; + break; + case 2: + out[0] = -in[0]; + out[1] = -in[1]; + out[2] = in[2]; + break; + case 3: + out[0] = in[1]; + out[1] = -in[0]; + out[2] = in[2]; + break; + case 4: + out[0] = in[1]; + out[1] = in[0]; + out[2] = -in[2]; + break; + case 5: + out[0] = -in[0]; + out[1] = in[1]; + out[2] = -in[2]; + break; + case 6: + out[0] = -in[1]; + out[1] = -in[0]; + out[2] = -in[2]; + break; + case 7: + out[0] = in[0]; + out[1] = -in[1]; + out[2] = -in[2]; + break; + default: + out[0] = in[0]; + out[1] = in[1]; + out[2] = -in[2]; + break; + } +} +float mag_service_get_fAzimuth(void) +{ + return fAzimuth ; +} +int mag_service_get_iAccuracy(void) +{ + return iAccuracy ; +} + +int mmc5603_stop(void) +{ + MMC5603_Disable(); + return 0; +} diff --git a/code/sdk/drivers/peripheral/mag/service/mag_service.c b/code/sdk/drivers/peripheral/mag/service/mag_service.c new file mode 100644 index 000000000..dd008efca --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/service/mag_service.c @@ -0,0 +1,203 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n + * + * Description: Test adc source \n + * Author: @CompanyNameTag \n + * History: \n + * 2022-08-16, Create file. \n + */ + +#include "adc.h" +#define TEST_PARAM_ARGC_1 1 +#define TEST_PARAM_ARGC_2 2 +#define TEST_PARAM_ARGC_3 3 +#define TEST_PARAM_ARGC_4 4 +#define TEST_PARAM_ARGC_5 5 +#define TEST_PARAM_ARGC_6 6 +#define TEST_PARAM_ARGC_7 7 +#define TEST_PARAM_4_BYTES 4 +#define TEST_PARAM_8_BYTES 8 +typedef enum { + SUITE_OK = 0, + SUITE_UNKNOWN_FUNCTION = -1, + SUITE_ERROR_TIMED_OUT = -2, + SUITE_ERROR_BAD_PARAMS = -3, + SUITE_ERROR_PIN_ALLOCATION = -4, + SUITE_ERROR_PIN_DEALLOCATION = -5, + SUITE_ERROR_UNEXPECTED_INTERRUPT = -6, + SUITE_ALLOC_FAILED = -7, + SUITE_CONFIG_FAILED = -8, + SUITE_TEST_FAILED = -254, +} magservice_error_e; + +#if defined(CONFIG_ADC_SUPPORT_AFE) + +#error CONFIG_ADC_SUPPORT_AFE + +#include "hal_adc_v152.h" +#include "hal_adc_v152_regs_op.h" +#else +#include "hal_adc_v151.h" +#include "hal_adc_v151_regs_op.h" +#endif + +#include "adc_porting.h" +#include "pinctrl.h" +#include "debug_print.h" +#include "soc_osal.h" +#include "tcxo.h" +#include "irmalloc.h" +#include "errcode.h" +#include "common_def.h" + +#include "chip_core_irq.h" +#include "chip_io.h" +#include "gpio.h" +#include "pm_veto.h" + +#include "rtc.h" +#include "timer.h" +#include "systick.h" + + +static bool g_batter_service_initialled = false; + +#include "tcxo.h" + +#include "cmsis_os2.h" +#include "input_app.h" +#include "mmc5603_hal.h" +#include "mag_service.h" + + +/*** + * 其他cmd在Header里定义,对外开放 +*/ +#define MAG_SERVICE_CMD_TIMER_CHECK 0x11 + +osTimerId_t g_mag_service_timer = NULL; + +static bool g_bat_timer_is_running = false; +#define MAG_CHECK_MS 200 +static unsigned long g_app_queue; + +static bool mag_service_running_stat = false; +static void mag_service_check_timer_callback(void* data); + +static void mag_service_timer_start_check(uint32_t rtc_ms) +{ + + if (g_bat_timer_is_running ) osTimerStop(g_mag_service_timer); + if (mag_service_running_stat == true) osTimerStart(g_mag_service_timer, rtc_ms); + g_bat_timer_is_running = true; + +} +void do_mag_service_check_msg(int cmd); + +static void mag_service_check_timer_callback(void * data) +{ + unused(data); + + g_bat_timer_is_running = false; + + if(mag_service_running_stat == true){ + mmc5603_check(); //此处只能直接加到timer callback中,采用queue的话,新能跟不上,系统资源会挂掉。 + // mag_service_timer_start_check(MAG_CHECK_MS); + } + // do_mag_service_check_msg(MAG_SERVICE_CMD_TIMER_CHECK); + // uapi_tcxo_delay_ms(20); + + + +} +void uapi_mag_service_deinit(void) +{ + /* Stop the time and clear the pin map */ + osTimerStop(g_mag_service_timer); + osTimerDelete(g_mag_service_timer); + + g_bat_timer_is_running = false; + g_mag_service_timer = NULL; +} + + + +void do_mag_service_check_msg(int cmd) +{ + int ret; + + 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 mag Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret); + } + +} + +static void mag_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 == MAG_SERVICE_CMD_TIMER_CHECK) { + // mag_service_check_and_enable_charge(); + // mmc5603_check(); + PRINT("MAG_SERVICE_CMD_TIMER_CHECK\r\n"); + }else if (mail.comm.app == MAG_SERVICE_CMD_START_CHECK){ + mag_service_running_stat = true; + mmc5603_start(); + mag_service_timer_start_check(MAG_CHECK_MS); + }else if (mail.comm.app == MAG_SERVICE_CMD_STOP_CHECK){ + mag_service_running_stat = false; + osTimerStop(g_mag_service_timer); + mmc5603_stop(); + } + } +} + +errcode_t uapi_mag_service_init(void) +{ + if (osal_msg_queue_create("mag_service_queue", APP_BOARD_MSG_COUNT, &g_app_queue, + 0, sizeof(common_notify_mail_t)) != ERRCODE_SUCC) { + PRINT("[mag][service] app create mail fail\n"); + return ERRCODE_FAIL; + } + + + osal_task *task_handle = osal_kthread_create((osal_kthread_handler)mag_service_check_task, NULL, + "mag_service_service", APP_BOARD_TASK_SIZE); + if (task_handle == NULL) { + osal_msg_queue_is_full(g_app_queue); + PRINT("create mag service thread fail!\r\n"); + return ERRCODE_FAIL; + } + + // osal_kthread_set_priority(task_handle, APP_BOARD_TASK_PRIO); + osal_kthread_set_priority(task_handle, 10); + + g_mag_service_timer = osTimerNew((osTimerFunc_t)mag_service_check_timer_callback, osTimerPeriodic, NULL, NULL); + + + return ERRCODE_SUCC; +} + +// void mag_service_service_resume(void) +// { +// PRINT("mag_service_service resume!\r\n"); +// mag_service_check_timer_callback(0); +// } +// void mag_service_service_suspend(void) +// { +// PRINT("mag_service_service suspend!\r\n"); +// } \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/mag/service/mag_service.h b/code/sdk/drivers/peripheral/mag/service/mag_service.h new file mode 100644 index 000000000..ffc1fdd1f --- /dev/null +++ b/code/sdk/drivers/peripheral/mag/service/mag_service.h @@ -0,0 +1,42 @@ +/** + * 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 MAG_SERVICE_H__ +#define MAG_SERVICE_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#include "stdint.h" +#include "errcode.h" + + +#define MAG_SERVICE_CMD_START_CHECK 0x12 +#define MAG_SERVICE_CMD_STOP_CHECK 0x13 + +errcode_t uapi_mag_service_init(void); +void uapi_mag_service_deinit(void); +/** + * 测试指令 参数cmd 选项: MAG_SERVICE_CMD_START_CHECK,MAG_SERVICE_CMD_STOP_CHECK +*/ +void do_mag_service_check_msg(int cmd); + +float mag_service_get_fAzimuth(void); +int mag_service_get_iAccuracy(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/ppg/CMakeLists.txt b/code/sdk/drivers/peripheral/ppg/CMakeLists.txt new file mode 100644 index 000000000..6d67b878e --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/CMakeLists.txt @@ -0,0 +1,60 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "ppg_sensor") + +if("PPG_HX3695" IN_LIST DEFINES) +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_check_touch.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_factory_test.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_hrs_agc.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_hrv_agc.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_spo2_agc.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_hrs_custom.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695/hx3695_at_cmd.c +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/hx3695 +) + +else() +set(SOURCES ${SOURCES} + # ${CMAKE_CURRENT_SOURCE_DIR}/ztw523_touch/ztw523_ctrl.c +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) +endif() + + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +SUPPORT_AT_HX3695 +) + +# 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() + +find_library(LIB_PATH_HX3695 hx3695/libhx3695.a ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive ${LIB_PATH_HX3695} PRIVATE -Wl,--whole-archive) \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/Gcc_HaiSiLib_hx3695_Hrs_Spo2_hrv_20231215_v0.1.a b/code/sdk/drivers/peripheral/ppg/hx3695/Gcc_HaiSiLib_hx3695_Hrs_Spo2_hrv_20231215_v0.1.a new file mode 100644 index 000000000..4ef4b515d Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/hx3695/Gcc_HaiSiLib_hx3695_Hrs_Spo2_hrv_20231215_v0.1.a differ diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695.c new file mode 100644 index 000000000..a88f9d2b4 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695.c @@ -0,0 +1,3229 @@ +#include +#include +#include +#include +#include + +#include "tyhx_hrs_custom.h" +// #include "tyhx_mems.h" + +#ifdef CHIP_HX3695 +#include "hx3695.h" +#ifdef HRS_ALG_LIB +#include "hx3695_hrs_agc.h" +#include "tyhx_hrs_alg.h" +#endif +#ifdef SPO2_ALG_LIB +#include "hx3695_spo2_agc.h" +#include "tyhx_spo2_alg.h" +#endif +#ifdef HRV_ALG_LIB +#include "hx3695_hrv_agc.h" +#include "tyhx_hrv_alg.h" +#endif +#ifdef CHECK_TOUCH_LIB +#include "hx3695_check_touch.h" +#endif +#include "hx3695_factory_test.h" + +FT_CUSTOM_RESULTS_t hrsresult ={0}; + +int16_t gsen_fifo_x[64]={0}; +int16_t gsen_fifo_y[64]={0}; +int16_t gsen_fifo_z[64]={0}; + +#ifdef SPO2_VECTOR +#include "spo2_vec.h" +uint32_t spo2_send_cnt = 0; +uint32_t spo2_send_cnt1 = 0; +int32_t red_buf_vec[8]; +int32_t ir_buf_vec[8]; +int32_t green_buf_vec[8]; +#endif + +#ifdef HR_VECTOR +#include "hr_vec.h" +uint32_t vec_send_cnt = 0; +int32_t PPG_buf_vec[8]; +#endif + +#ifdef HRV_TESTVEC +#include "hrv_testvec.h" +#endif + +int32_t s_buf[256]; +uint32_t cnt_num = 0; +uint32_t phase3_rdy_num = 0; +uint8_t fifo_data_buf[768]; +uint8_t hrs_phase_num= 3; +uint8_t spo2_phase_num= 4; +uint8_t hrv_phase_num = 4; +extern uint8_t data_count; +// extern uint8_t hr_no_living_dur; +uint8_t hr_no_living_dur; +// extern int tyhx_long_timer_tick; +//spo2 agc +const uint8_t hx3695_spo2_agc_red_idac = RED_AGC_OFFSET; +const uint8_t hx3695_spo2_agc_ir_idac = IR_AGC_OFFSET; +const uint8_t hx3695_spo2_agc_ir_idac1 = IR_AGC_OFFSET; +const uint8_t hx3695_spo2_agc_ir_idac2 = IR_AGC_OFFSET; +const uint8_t hx3695_spo2_agc_green_idac = GREEN_AGC_OFFSET; +//hrs agc +const uint8_t hx3695_hrs_agc_idac = HR_GREEN_AGC_OFFSET; +const uint8_t hx3695_hrs_g1_agc_idac = HR_GREEN1_AGC_OFFSET; +const uint8_t hx3695_hrs_g2_agc_idac = HR_GREEN2_AGC_OFFSET; +const uint8_t hx3695_hrs_g3_agc_idac = HR_GREEN3_AGC_OFFSET; +//hrv agc +const uint8_t hx3695_hrv_agc_idac = HR_GREEN_AGC_OFFSET; + +const uint8_t green_led_max_init = 128; +const uint8_t red_led_max_init = 255; +const uint8_t ir_led_max_init = 128; + +uint8_t low_vbat_flag =0; +WORK_MODE_T work_mode_flag = HRS_MODE; +const uint16_t static_thre_val = 150; +const uint8_t gsen_lv_val = 0; +uint8_t read_fifo_first_flg = 0; + +//HRS_INFRARED_THRES +const int32_t hrs_ir_unwear_thres = 4000; +const int32_t hrs_ir_wear_thres = 5000; +//HRV_INFRARED_THRES +const int32_t hrv_ir_unwear_thres = 4000; //demo143b 25000 +const int32_t hrv_ir_wear_thres = 5000; +//SPO2_INFRARED_THRES +const int32_t spo2_ir_unwear_thres = 4000; //demo143b 25000 30000 +const int32_t spo2_ir_wear_thres = 5000; +const uint8_t spo2_ir_wear_offset = 15; +//CHECK_WEAR_MODE_THRES +const int32_t check_mode_unwear_thre = 20000; +const int32_t check_mode_wear_thre = 30000; + +uint8_t alg_ram[11 * 1024] __attribute__((aligned(4))); +//uint8_t alg_ram[10] = {0}; +ppg_sensor_data_t ppg_s_data; + + +//////// spo2 para and switches +const uint8_t COUNT_BLOCK_NUM = 25; //delay the block of some single good signal after a series of bad signal +const uint8_t SPO2_LOW_XCORR_THRE = 30; //(64*xcorr)'s square below this threshold, means error signal +const uint8_t SPO2_CALI = 1; //spo2_result cali mode +const uint8_t XCORR_MODE = 1; //xcorr mode switch +const uint8_t QUICK_RESULT = 1; //come out the spo2 result quickly ;0 is normal,1 is quick +const uint16_t MEAN_NUM = 32; //the length of smooth-average ;the value of MEAN_NUM can be given only 256 and 512 +const uint8_t G_SENSOR = 0; //if =1, open the gsensor mode +const uint8_t SPO2_GSEN_POW_THRE = 150; //gsen pow judge move, range:0-200; +const uint32_t SPO2_BASE_LINE_INIT = 135500; //spo2 baseline init, = 103000 + ratio(a variable quantity,depends on different cases)*SPO2_SLOPE +const int32_t SOP2_DEGLITCH_THRE = 100000; //remove signal glitch over this threshold +const int32_t SPO2_REMOVE_JUMP_THRE = 50000; //remove signal jump over this threshold +const uint32_t SPO2_SLOPE = 50000; //increase this slope, spo2 reduce more +const uint16_t SPO2_LOW_CLIP_END_TIME = 1500; //low clip mode before this data_cnt, normal clip mode after this +const uint16_t SPO2_LOW_CLIP_DN = 150; //spo2 reduce 0.15/s at most in low clip mode +const uint16_t SPO2_NORMAL_CLIP_DN = 500; //spo2 reduce 0.5/s at most in normal clip mode +const uint8_t SPO2_LOW_SNR_THRE = 40; //snr below this threshold, means error signal +const uint16_t IR_AC_TOUCH_THRE = 200; //AC_min*0.3 +const uint16_t IR_FFT_POW_THRE = 500; //fft_pow_min +const uint8_t SLOPE_PARA_MAX = 28; +const uint8_t SLOPE_PARA_MIN = 3; + +#ifdef SPO2_DATA_CALI +static int32_t red_data_fifo[4] = {0}; +static int32_t ir_data_fifo[4] = {0}; +static int32_t red_dc_temp = 0; +static int32_t ir_dc_temp = 0; +static int32_t red_data_pre = 0; +static int32_t ir_data_pre = 0; +static int32_t red_jump_delta = 0; +static int32_t ir_jump_delta = 0; +static int32_t cali_data_cnt = 0; +#endif + + + +// us 延时函数, 客户需填写 +void hx3695_delay_us(uint32_t us) +{ + tyhx_delay_us(us); +} + + +void hx3695_delay_ms(uint32_t ms) +{ + tyhx_delay_ms(ms); +} + +// i2c 写函数, 客户需填写, 地址0x44(7bit) +bool hx3695_write_reg(uint8_t addr, uint8_t data) +{ + + tyhx_write_reg(addr,data); + return true; +} + +// i2c 读函数, 客户需填写 +uint8_t hx3695_read_reg(uint8_t addr) +{ + uint8_t data_buf = 0; + + tyhx_read_regs(addr,&data_buf,1); + return data_buf; +} + +// i2c 连读函数, 客户需填写 +bool hx3695_brust_read_reg(uint8_t addr, uint8_t *buf, uint8_t length) +{ + //TYHX_LOG("brust read\r\n"); + tyhx_read_regs(addr,buf,length); + return true; +} + + + +uint32_t hx3695_timers_start(void) +{ + tyhx_timer_start(TYHX_TIMER_320MS); + return 0; +} +uint32_t hx3695_timers_stop(void) +{ + tyhx_timer_stop(TYHX_TIMER_320MS); + return 0; +} + +uint32_t gsen_read_timers_start(void) +{ + tyhx_timer_start(TYHX_TIMER_40MS); + return 0; +} +uint32_t gsen_read_timers_stop(void) +{ + tyhx_timer_stop(TYHX_TIMER_40MS); + return 0; +} + + +/* 完成读取PPG数据定时器接口, 循环调用, 默认320ms +void heart_rate_meas_timeout_handler(void * p_context) +*/ +void hx3695_320ms_timer_cfg(bool en) +{ + if(en) + { + hx3695_timers_start(); + } + else + { + hx3695_timers_stop(); + } + +} + +void hx3695_40ms_timer_cfg(bool en) +{ + if(en) + { + gsen_read_timers_start(); + } + else + { + gsen_read_timers_stop(); + } +} + +#if defined(INT_MODE) +/* 如采用中断模式, 如完成中断开启和关闭接口 +void hx3695_ppg_Int_handle(void) +*/ +void hx3695_gpioint_cfg(bool en) +{ + if(en) + { + hx3695_gpioint_enable(); + } + else + { + hx3695_gpioint_disable(); + } +} +#endif + + + +#define RA_MEM_WRDATA_7_0 0x50 +#define RA_MEM_WRDATA_15_8 0x51 +#define RA_MEM_WRDATA_23_16 0x52 +#define RA_MEM_WRDATA_31_24 0x53 +#define RA_MEM_WRDATA_39_32 0x54 +#define RA_MEM_WRDATA_47_40 0x55 +#define RA_MEM_WRDATA_55_48 0x56 +#define RA_MEM_WRDATA_63_56 0x57 +#define RA_MEM_PWE_PULSE_CYCLE7_0 0x58 +#define RA_MEM_PWE_PULSE_CYCLE10_8 0x59 +#define RA_MEM_GLOBAL_CTRL 0x5A +#define RA_MEM_MANNUAL_CTRL 0x5B +#define RA_DEBUG_CFG0 0x5C +#define RA_DEBUG_CFG1 0x5D + +uint8_t REG_50_E, REG_51_E, REG_52_E, REG_53_E; + +void Efuse_Mode_Check(void) +{ + uint8_t efuse0, efuse1, efuse2, efuse3; + + hx3695_write_reg(RA_DEBUG_CFG0, 0x8) ; //0x5c + hx3695_write_reg(RA_DEBUG_CFG1, 0x2) ; //0x5d + hx3695_delay_us(1000); + + hx3695_write_reg(RA_MEM_GLOBAL_CTRL,0x10); //0x5A +// delay_us(2000); + + hx3695_write_reg(RA_MEM_MANNUAL_CTRL,0x04); + hx3695_write_reg(RA_MEM_MANNUAL_CTRL,0x00); + + hx3695_write_reg(RA_MEM_MANNUAL_CTRL,0x44); + hx3695_write_reg(RA_MEM_MANNUAL_CTRL,0x40); + + REG_50_E = hx3695_read_reg(0x50); + REG_51_E = hx3695_read_reg(0x51); + REG_52_E = hx3695_read_reg(0x52); + REG_53_E = hx3695_read_reg(0x53); + +// AGC_LOG("0x50=0x%x\r\n", REG_50_E); +// hal_gpt_delay_ms(100); +// AGC_LOG("0x51=0x%x\r\n", REG_51_E); +// hal_gpt_delay_ms(100); +// AGC_LOG("0x52=0x%x\r\n", REG_52_E); +// hal_gpt_delay_ms(100); +// AGC_LOG("0x53=0x%x\r\n", REG_53_E); +// hal_gpt_delay_ms(100); + + hx3695_write_reg(RA_MEM_GLOBAL_CTRL,0x20); //0x5A + hx3695_write_reg(0x50,REG_50_E); + hx3695_write_reg(0x51,REG_51_E); + hx3695_write_reg(0x52,REG_52_E); + hx3695_write_reg(0x53,REG_53_E); + + + hx3695_write_reg(RA_MEM_GLOBAL_CTRL,0x0); + + hx3695_write_reg(RA_DEBUG_CFG0, 0x0); //0x5c + hx3695_write_reg(RA_DEBUG_CFG1, 0x0); //0x5d + +} +bool hx3695_chip_check(void) +{ + uint8_t i = 0; + uint8_t chip_id = 0; + for(i=0; i<5; i++) + { + hx3695_write_reg(0x5c, 0x00); + hx3695_delay_ms(5); + chip_id = hx3695_read_reg(0x00); + + if (chip_id == 0x65) + { + TYHX_LOG("hx3695_chip_check ok chip_id: 0x%x \r\n",chip_id); + Efuse_Mode_Check(); + return true; + } + } + + TYHX_LOG(" hx3695_chip_check fail! chip_id: 0x%x \r\n", chip_id); + + return false; +} + +uint8_t hx3695_get_chip_id(void) +{ + uint8_t i = 0; + uint8_t chip_id = 0; + for(i=0; i<5; i++) + { + hx3695_write_reg(0x5c, 0x00); + hx3695_delay_ms(5); + chip_id = hx3695_read_reg(0x00); + + if (chip_id == 0x65) + { + TYHX_LOG("hx3695_chip_check ok chip_id: 0x%x \r\n",chip_id); + return chip_id; + } + } + + TYHX_LOG(" hx3695_chip_check fail! chip_id: 0x%x \r\n", chip_id); + + return chip_id; +} + +uint8_t hx3695_read_fifo_size(void) +{ + uint8_t data_len_h,data_len_l; + uint16_t fifo_data_length; + data_len_h = hx3695_read_reg(0x21); + data_len_l = hx3695_read_reg(0x20); + fifo_data_length = (((data_len_h&0x01)<<8)|data_len_l); + + return fifo_data_length; +} + + +uint16_t hx3695_read_fifo_data(int32_t *buf, uint8_t phase_num, uint8_t sig) +{ + uint8_t data_flg_start = 0; + uint8_t data_flg_end = 0; +// int32_t data; + uint8_t databuf[3]; + uint32_t ii=0; + uint16_t data_len_h = 0; + uint16_t data_len_l = 0; + uint16_t fifo_data_length = 0; + uint16_t fifo_read_length = 0; + uint16_t fifo_read_bytes = 0; + uint16_t fifo_out_length = 0; + uint16_t fifo_out_count = 0; + + data_len_h = hx3695_read_reg(0x21); + data_len_l = hx3695_read_reg(0x20); + fifo_data_length = (((data_len_h&0x01)<<8)|data_len_l); +// AGC_LOG("fifo_data_length = %d\r\n", fifo_data_length); + if(fifo_data_length<2*phase_num) + { + return 0; + } + fifo_read_length = ((fifo_data_length-phase_num)/phase_num)*phase_num; +// AGC_LOG("fifo_data_length_change = %d\r\n", fifo_read_length); + fifo_read_bytes = fifo_read_length*3; + if(read_fifo_first_flg == 1) + { + hx3695_brust_read_reg(0x22, databuf, 3); + read_fifo_first_flg = 0; + } + hx3695_brust_read_reg(0x22, fifo_data_buf, fifo_read_bytes); +// for(ii=0; ii>5); + } + data_flg_start = fifo_data_buf[2]>>5; + data_flg_end = fifo_data_buf[fifo_read_bytes-1]>>5; + fifo_out_length = fifo_read_length; + if(data_flg_start>0) + { + fifo_out_length = fifo_read_length-phase_num + data_flg_start; + for(ii=0; ii6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + +// hx3695_write_reg(0X4e, thred_value); +// hx3695_write_reg(0X4f, thred_value>>5); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92); // bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release + read_fifo_first_flg = 1; + return ; +} +#endif + +#ifdef SPO2_ALG_LIB +// 血氧模式下 初始化配置 +void hx3695_spo2_ppg_init(void) //20200615 ericy ppg fs=25hz, phase3 conversion ready interupt en +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + +// uint16_t fifo_watermark= 250 ; + uint8_t adc_rst_post_num=0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; /* phase7 and phase8 prf internal cfg */ + +// uint16_t thred_value = 32500; + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 1; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 1; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 1; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 1; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = 0X50; //GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0x00; + uint8_t phase2_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = 0; //RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = 0x80; //0x20 //IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0x00; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0x20; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x02; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0x20; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x02; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 20; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 4 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x08); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //(FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x91);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X36, 0x00); + + hx3695_write_reg(0X38, 0x00); // int sel,00=close almost full int,01= prf int 04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + + hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release +// uint8_t fifo_data_temp[3] = {0}; +// hx3695_brust_read_reg(0x22, fifo_data_temp, 3); + read_fifo_first_flg = 1; + return ; + +} +#endif + +#ifdef HRV_ALG_LIB +// HRV模式下 初始化配置 +void hx3695_hrv_ppg_init(void) //20200615 ericy ppg fs=25hz, phase3 conversion ready interupt en +{ + uint16_t sample_rate = 125; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + +; + uint8_t adc_rst_post_num=0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; /* phase7 and phase8 prf internal cfg */ + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0X10; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = 0; //GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0; + uint8_t phase2_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = 0x08; //0x40 //RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = 0; //IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 4 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x00);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x08); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //(FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X36, 0x00); + + hx3695_write_reg(0X38, 0x00); // int sel,00=close almost full int,01= prf int 04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + + hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release +// uint8_t fifo_data_temp[3] = {0}; +// hx3695_brust_read_reg(0x22, fifo_data_temp, 3); + read_fifo_first_flg = 1; + return ; +} +#endif + +#ifdef CHECK_TOUCH_LIB +void hx3695_check_touch_init(void) // +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + +// uint16_t fifo_watermark= 250 ; + uint8_t adc_rst_post_num= 0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; //0x18; /* phase7 and phase8 prf internal cfg */ + +// uint16_t thred_value = 32500; + + uint8_t phase1_enable = 0; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 0; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 0; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 0; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 1; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 1; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = 0; //GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0; + uint8_t phase2_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = 0; //RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 4; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 4; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x00; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0x20;//0x40; //IR_LED_SLE /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 20; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 4 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x08); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //(FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X36, 0x00); //intrupt + + hx3695_write_reg(0X38, 0x00); // int sel,00=close almost full int,01= prf int 04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + + hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release +// uint8_t fifo_data_temp[3] = {0}; +// hx3695_brust_read_reg(0x22, fifo_data_temp, 3); + read_fifo_first_flg = 1; + return ; +} +#endif + +// 初始化调用入口函数 +bool hx3695_init(WORK_MODE_T mode) +{ + TYHX_LOG(" hx3695_init mode : %d \n", mode); + + work_mode_flag = mode; + hx3695_data_reset(); + hx3695_vin_check(3800); + switch (work_mode_flag) + { + case HRS_MODE: + TYHX_LOG(" hx3695_init mode : HRS_MODE \n"); +#ifdef HRS_ALG_LIB + tyhx_hrs_set_alg_para(NORMAL_MODE, 150, 1); + + tyhx_hrs_set_living(1, 15, 30); + if(hx3695_hrs_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + break; + + case LIVING_MODE: +#ifdef CHECK_LIVING_LIB + if(hx3695_hrs_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + break; + + case SPO2_MODE: +#ifdef SPO2_DATA_CALI +// hx3695_spo2_data_cali_init(); +#endif + +#ifdef SPO2_ALG_LIB + tyhx_spo2_para_usuallyadjust(SPO2_LOW_XCORR_THRE,SPO2_LOW_SNR_THRE,COUNT_BLOCK_NUM,SPO2_BASE_LINE_INIT,SPO2_SLOPE,SPO2_GSEN_POW_THRE); + tyhx_spo2_para_barelychange(MEAN_NUM,SOP2_DEGLITCH_THRE,SPO2_REMOVE_JUMP_THRE, \ + SPO2_LOW_CLIP_END_TIME,SPO2_LOW_CLIP_DN,SPO2_NORMAL_CLIP_DN, \ + IR_AC_TOUCH_THRE,IR_FFT_POW_THRE,SPO2_CALI,SLOPE_PARA_MAX,SLOPE_PARA_MIN); + tyhx_spo2_set_living(1, 15, 30); + if(hx3695_spo2_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + break; + + case HRSPO2_MODE: +#if defined(HRS_ALG_LIB) && defined (SPO2_ALG_LIB) + tyhx_spo2_para_usuallyadjust(SPO2_LOW_XCORR_THRE,SPO2_LOW_SNR_THRE,COUNT_BLOCK_NUM,SPO2_BASE_LINE_INIT,SPO2_SLOPE,SPO2_GSEN_POW_THRE); + tyhx_spo2_para_barelychange(MEAN_NUM,SOP2_DEGLITCH_THRE,SPO2_REMOVE_JUMP_THRE, \ + SPO2_LOW_CLIP_END_TIME,SPO2_LOW_CLIP_DN,SPO2_NORMAL_CLIP_DN, \ + IR_AC_TOUCH_THRE,IR_FFT_POW_THRE,SPO2_CALI,SLOPE_PARA_MAX,SLOPE_PARA_MIN); + if(hx3695_spo2_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + + case HRV_MODE: +#ifdef HRV_ALG_LIB + if(hx3695_hrv_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + break; + + case WEAR_MODE: +#ifdef CHECK_TOUCH_LIB + if(hx3695_check_touch_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + break; + + case FT_LEAK_LIGHT_MODE: + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return false; + } + hx3695_factroy_test(LEAK_LIGHT_TEST); + return true; + + break; + + case FT_GRAY_CARD_MODE: + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return false; + } + hx3695_factroy_test(GRAY_CARD_TEST); + break; + + case FT_INT_TEST_MODE: + hx3695_factroy_test(FT_INT_TEST); + break; + + case FT_SINGLE_CHECK_MODE: + hx3695_factroy_test(SINGLE_CHECK_TEST); + break; + + case FT_LED_OFF_MODE: + hx3695_factroy_test(LED_OFF_TEST); + break; + + case FT_WEAR_MODE: + hx3695_factroy_test(WEAR_MODE_TEST); + break; + + case LAB_TEST_MODE: +#ifdef LAB_TEST + if(hx3695_lab_test_enable()== SENSOR_OP_FAILED) + { + return false; + } +#endif + break; + + default: + break; + } + return true; +} + +void hx3695_agc_Int_handle(void) +{ + switch (work_mode_flag) + { + case HRS_MODE: +#ifdef HRS_ALG_LIB + PPG_hrs_agc(); +#endif + break; + + case LIVING_MODE: +#ifdef HRS_ALG_LIB + PPG_hrs_agc(); +#endif + break; + + case HRV_MODE: +#ifdef HRV_ALG_LIB + PPG_hrv_agc(); +#endif + break; + + case SPO2_MODE: +#ifdef SPO2_ALG_LIB + PPG_spo2_agc(); +#endif + break; + + case HRSPO2_MODE: +#if defined(HRS_ALG_LIB) && defined (SPO2_ALG_LIB) + PPG_spo2_agc(); +#endif + + case LAB_TEST_MODE: +#ifdef LAB_TEST + hx3695_lab_test_Int_handle(); +#endif + + default: + break; + } +} + +void agc_timeout_handler(void * p_context) +{ + hx3695_agc_Int_handle(); + +#if defined(GSEN_40MS_TIMMER) + hx3695_gesensor_Int_handle(); +#endif +} + + +void hx3695_factory_test_process(uint8_t data[], uint8_t mode, uint8_t* ppg_src) +{ + extern bool factory_test_flag; + extern bool factory_test_aging; + extern bool factory_test_sensor_on; + if(factory_test_flag == false || factory_test_aging != false) return; + if(factory_test_sensor_on == true ) return; + + static uint8_t ppg_data[15] = {0}; + + if(ppg_src == NULL) + { + memcpy(ppg_data, data, 3); + return; + } + + // switch(mode) + // { + // case APP_FACTORY_TEST_HR_START: + // memcpy((void *)&ppg_data[3], ppg_src, 4); + // factory_test_send_data(ppg_data, 7); + // break; + // case APP_FACTORY_TEST_SPO2_START: + // memcpy((void *)&ppg_data[3], ppg_src, 4); + // factory_test_send_data(ppg_data, 7); + // break; + // case APP_FACTORY_TEST_LEAKING_START: + // memcpy((void *)&ppg_data[3], ppg_src, 12); + // factory_test_send_data(ppg_data, 15); + // break; + // case APP_FACTORY_TEST_GRAY_CARD: + // memcpy((void *)&ppg_data[3], ppg_src, 12); + // factory_test_send_data(ppg_data, 15); + // break; + // default: + // break; + // } +} + +void heart_rate_meas_timeout_handler(void * p_context) +{ + switch(work_mode_flag) + { + case HRS_MODE: +#ifdef HRS_ALG_LIB + hx3695_hrs_ppg_Int_handle(); +#endif + break; + + case HRV_MODE: +#ifdef HRV_ALG_LIB + hx3695_hrv_ppg_Int_handle(); +#endif + break; + + case SPO2_MODE: +#ifdef SPO2_ALG_LIB + hx3695_spo2_ppg_Int_handle(); +#endif + break; + + case WEAR_MODE: +#ifdef CHECK_TOUCH_LIB + hx3695_wear_ppg_Int_handle(); +#endif + break; + + case LIVING_MODE: +#ifdef CHECK_LIVING_LIB + hx3695_living_Int_handle(); +#endif + break; + + case HRSPO2_MODE: +#if defined(HRS_ALG_LIB) && defined (SPO2_ALG_LIB) + hx3695_hrspo2_ppg_Int_handle(); +#endif + + case FT_LEAK_LIGHT_MODE: + hx3695_factroy_test(LEAK_LIGHT_TEST); + break; + + case FT_GRAY_CARD_MODE: + { + FT_RESULTS_t ft_result = hx3695_factroy_test(GRAY_CARD_TEST); + uint8_t data[12] = {0}; + memcpy(data, (void *)&ft_result.gr_data_final, 12); + // hx3695_factory_test_process(NULL, APP_FACTORY_TEST_GRAY_CARD, data); + } + break; + + default: + break; + } +} + +void hx3695_ppg_Int_handle(void) +{ + hx3695_agc_Int_handle(); +#if defined(INT_MODE) + switch(work_mode_flag) + { + case HRS_MODE: +#ifdef HRS_ALG_LIB + hx3695_hrs_ppg_Int_handle(); +#endif + break; + + case SPO2_MODE: +#ifdef SPO2_ALG_LIB + hx3695_spo2_ppg_Int_handle(); +#endif + break; + + case HRV_MODE: +#ifdef HRV_ALG_LIB + hx3695_hrv_ppg_Int_handle(); +#endif + break; + + case WEAR_MODE: +#ifdef CHECK_TOUCH_LIB + hx3695_wear_ppg_Int_handle(); +#endif + break; + + case LAB_TEST_MODE: +#ifdef LAB_TEST + hx3695_lab_test_Int_handle(); +#endif + + default: + break; + } +#endif +} + + + +#ifdef HRS_ALG_LIB +/*TYHX 心率模式下 读取PPG, 默认320ms*/ +hrs_sensor_data_t hrs_s_dat; +//hx3695_results_t alg_results_pre; +/*** + * typedef struct { + hrs_alg_msg_code_t hrs_alg_status; + living_msg_code_t living_status; + uint32_t data_cnt; + uint8_t hr_result; + uint16_t cal_result; + uint8_t hr_result_qual; + uint32_t hr_result_std; +} hrs_results_t; +*/ +void hx3695_hrs_ppg_Int_handle(void) +{ + uint8_t ii=0; + hrs_results_t alg_results = {MSG_HRS_ALG_NOT_OPEN,0,0,0,0,0,0}; + hrs_wear_msg_code_t hrs_wear_status = MSG_HRS_NO_WEAR; + int32_t *PPG_buf = &(hrs_s_dat.green_data[0]); + int32_t *ir_buf = &(hrs_s_dat.ir_data[0]); + uint8_t *count = &(hrs_s_dat.count); + //int32_t *s_buf = &(ppg_s_data.s_buf[0]); + int16_t gsen_fifo_x_send[32]= {0}; + int16_t gsen_fifo_y_send[32]= {0}; + int16_t gsen_fifo_z_send[32]= {0}; + + HRS_CAL_SET_T cal; + cal = get_hrs_agc_status(); + +#ifdef HR_VECTOR + for(ii=0; ii<8; ii++) + { + PPG_buf_vec[ii] = hrm_input_data[vec_send_cnt+ii]; + gsen_fifo_x_send[ii] = gsen_input_data_x[vec_send_cnt+ii]; + gsen_fifo_y_send[ii] = gsen_input_data_y[vec_send_cnt+ii]; + gsen_fifo_z_send[ii] = gsen_input_data_z[vec_send_cnt+ii]; + } + vec_send_cnt = vec_send_cnt+8; + *count = 8; + tyhx_hrs_alg_send_data(PPG_buf_vec,*count, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send); + +#else + if(hx3695_hrs_read(&hrs_s_dat) == 0) + { + AGC_LOG("hx3695_hrs_read(&hrs_s_dat) == 0\r\n"); + return; + } + +#ifndef GSEN_40MS_TIMMER + readFifoByHrsModule(); +#endif +// DEBUG_PRINTF("\r\nsend jlink cnt=%d\r\n",*count); + + for(ii=0; ii<*count; ii++) + { + gsen_fifo_x_send[ii] = gsen_fifo_x[32-*count+ii]; + gsen_fifo_y_send[ii] = gsen_fifo_y[32-*count+ii]; + gsen_fifo_z_send[ii] = gsen_fifo_z[32-*count+ii]; + +// DEBUG_PRINTF("gr,ir,gsen:%d/%d %d %d %d %d %d %d\r\n" ,1+ii,*count,PPG_buf[ii],ir_buf[0],gsen_fifo_x[ii],gsen_fifo_y[ii],gsen_fifo_z[ii],ppg_s_data.green_cur); + } + + hrs_wear_status = hx3695_hrs_get_wear_status(); + AGC_LOG("hrs_wear_status: %d !!\r\n", hrs_wear_status); + if(hrs_wear_status == MSG_HRS_WEAR) + { + tyhx_hrs_alg_send_data(PPG_buf, *count, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send, cal.Group1_Ledidac); + } +#endif + + alg_results = tyhx_hrs_alg_get_results(); + hrsresult.lastesthrs = alg_results.hr_result; + hrsresult.hr_living = alg_results.living_status; + hrsresult.hr_living_qu = alg_results.hr_result_qual; + hrsresult.hr_living_std = alg_results.hr_result_std; + + AGC_LOG("hx3695 data_cnt: %d, hr_living: %d, hr_living_qu: %d, hr_living_std: %d, hr_result:%d \r\n", + alg_results.data_cnt, hrsresult.hr_living, hrsresult.hr_living_qu, hrsresult.hr_living_std, hrsresult.lastesthrs); + if(hrs_wear_status == MSG_HRS_WEAR && hrsresult.hr_living == MSG_LIVING_TRUE) + { +// app_hr_reset_stop_timer(); + if(alg_results.hr_result) + { + + // app_hr_cal_hr_values(alg_results.hr_result); + // AGC_LOG("app_hr_cal_hr_values tick:%d hr:%d", xTaskGetTickCount(), alg_results.hr_result); + AGC_LOG("app_hr_cal_hr_values hr:%d", alg_results.hr_result); + //hr_sensor_notify_factory_test(); + } + hr_no_living_dur = 0; + } + else if(hrs_wear_status == MSG_HRS_WEAR && hrsresult.hr_living != MSG_LIVING_TRUE) + { + // if (++hr_no_living_dur > 12 * 1000 / tyhx_long_timer_tick) + { + // hr_stop_detect(); + // AGC_LOG("tyhx_hrs_module_start(WEAR_MODE) wear:%d liv:%d", hrs_wear_status, hrsresult.hr_living); + // hr_no_living_dur = 0; + } + } + else if(hrs_wear_status == MSG_HRS_NO_WEAR || hrsresult.hr_living == MSG_LIVING_FAIL) + { + // hr_stop_detect(); + AGC_LOG("tyhx_hrs_module_start(WEAR_MODE) wear:%d liv:%d", hrs_wear_status, hrsresult.hr_living); + hr_no_living_dur = 0; + } +#ifdef BP_CUSTDOWN_ALG_LIB + bp_results_t bp_alg_results; + bp_alg_results = tyhx_alg_get_bp_results(); +#endif + +////////////////////////////////////////BLE+DISPLAY///////////////////////////////// + + +#ifdef HRS_BLE_APP + { + rawdata_vector_t rawdata; + for(ii=0; ii<*count; ii++) + { + rawdata.vector_flag = HRS_VECTOR_FLAG; + rawdata.data_cnt = alg_results.data_cnt-*count+ii; + rawdata.hr_result = alg_results.hr_result; + rawdata.red_raw_data = PPG_buf[ii]; + rawdata.ir_raw_data = ir_buf[ii]; + rawdata.gsensor_x = gsen_fifo_x_send[ii]; + rawdata.gsensor_y = gsen_fifo_y_send[ii]; + rawdata.gsensor_z = gsen_fifo_z_send[ii]; + rawdata.red_cur = cal.Group1_Cur; + rawdata.ir_cur = cal.Group1_Ledidac; + + ble_rawdata_vector_push(rawdata); + } + } + ble_rawdata_send_handler(); +#endif + +//////////////////////////////////////////////////////////////////////////////////// +} +#endif + +#ifdef CHECK_LIVING_LIB +hrs_sensor_data_t hrs_s_dat; + +void hx3695_living_Int_handle(void) +{ + uint8_t ii=0; + hx3695_living_results_t living_alg_results = {MSG_LIVING_NO_WEAR,0,0,0}; + int32_t *PPG_buf = &(hrs_s_dat.green_data[0]); + int32_t *ir_buf = &(hrs_s_dat.ir_data[0]); + uint8_t *count = &(hrs_s_dat.count); + hrs_wear_msg_code_t hrs_wear_status = MSG_HRS_NO_WEAR; + int16_t gsen_fifo_x_send[32]= {0}; + int16_t gsen_fifo_y_send[32]= {0}; + int16_t gsen_fifo_z_send[32]= {0}; + + if(hx3695_hrs_read(&hrs_s_dat) == 0) + { + return; + } + +#ifndef GSEN_40MS_TIMMER + readFifoByHrsModule(); +#endif + DEBUG_PRINTF("\r\nsend jlink cnt=%d\r\n",*count); + + + for(ii=0; ii<*count; ii++) + { + gsen_fifo_x_send[ii] = gsen_fifo_x[32-*count+ii]; + gsen_fifo_y_send[ii] = gsen_fifo_y[32-*count+ii]; + gsen_fifo_z_send[ii] = gsen_fifo_z[32-*count+ii]; + + DEBUG_PRINTF("ger:%d/%d %d %d %d %d %d %d\r\n" ,1+ii,*count,PPG_buf[ii],ir_buf[0],gsen_fifo_x[ii],gsen_fifo_y[ii],gsen_fifo_z[ii],ppg_s_data.green_cur); + } + hrs_wear_status = hx3695_hrs_get_wear_status(); + if(hrs_wear_status == MSG_HRS_WEAR) + { + hx3695_living_send_data(PPG_buf, *count, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send); + } + living_alg_results = hx3695_living_get_results(); + DEBUG_PRINTF("res:%d %d %d %d\r\n",living_alg_results.data_cnt,living_alg_results.motion_status,living_alg_results.signal_quality,hrs_wear_status); +} +#endif + + +#ifdef SPO2_ALG_LIB + +#ifdef SPO2_DATA_CALI +void hx3695_spo2_data_cali_init(void) +{ + uint8_t ii; + for(ii=0; ii<4; ii++) + { + red_data_fifo[ii] = 0; + ir_data_fifo[ii] = 0; + } + red_dc_temp = 0; + ir_dc_temp = 0; + red_data_pre = 0; + ir_data_pre = 0; + red_jump_delta = 0; + ir_jump_delta = 0; + cali_data_cnt = 0; +} + +int32_t hx3695_red_data_cali(int32_t red_new_raw_data) +{ + uint8_t ii; + int32_t red_data_final; + int32_t red_data_cali; + spo2_wear_msg_code_t touch_status; + touch_status = hx3695_spo2_get_wear_status(); + if(touch_status == MSG_SPO2_NO_WEAR) + { + cali_data_cnt = 0; + red_data_cali = red_new_raw_data; + for(ii=0; ii<4; ii++) + { + red_data_fifo[ii] = 0; + } + red_dc_temp = 0; + } + else + { + for(ii=3; ii>0; ii--) + { + red_data_fifo[ii] = red_data_fifo[ii-1]; + } + red_data_fifo[0] = red_new_raw_data; + if(cali_data_cnt>=25) + { + if ((((red_data_fifo[1] - red_data_fifo[2]) > SOP2_DEGLITCH_THRE) && ((red_data_fifo[1] - red_new_raw_data) > SOP2_DEGLITCH_THRE)) || \ + (((red_data_fifo[1] - red_data_fifo[2]) < -SOP2_DEGLITCH_THRE) && ((red_data_fifo[1] - red_new_raw_data) < -SOP2_DEGLITCH_THRE))) + { + red_new_raw_data = red_data_fifo[2]; + red_data_fifo[1] = red_data_fifo[2]; + } + else + { + red_new_raw_data = red_data_fifo[1]; + } + if ((abs((red_new_raw_data - red_jump_delta) - red_data_pre) > SPO2_REMOVE_JUMP_THRE)) + { + red_jump_delta = red_new_raw_data - red_data_pre; + } + red_data_cali = red_new_raw_data - red_jump_delta; + red_data_pre = red_data_cali; + } + else + { + red_data_cali = red_data_fifo[1]; + red_data_pre = red_data_fifo[1]; + } + } + if(cali_data_cnt<=30) + { + red_dc_temp = red_data_cali; + red_data_final = red_new_raw_data; + } + else + { + //red_dc_temp = (red_dc_temp*31 + red_data_cali)>>5; + red_dc_temp = 0; + red_data_final = red_data_cali - red_dc_temp + 2608*50*hx3695_spo2_agc_red_idac; + } + //DEBUG_PRINTF("%d %d %d %d %d %d\r\n", cali_data_cnt, red_new_raw_data, red_data_final, red_data_cali, red_dc_temp, hx3695_spo2_agc_red_idac); + return red_data_final; +} +int32_t hx3695_ir_data_cali(int32_t ir_new_raw_data) +{ + uint8_t ii; + int32_t ir_data_final; + int32_t ir_data_cali; + spo2_wear_msg_code_t touch_status; + touch_status = hx3695_spo2_get_wear_status(); + if(touch_status == MSG_SPO2_NO_WEAR) + { + cali_data_cnt = 0; + ir_data_cali = ir_new_raw_data; + for(ii=0; ii<4; ii++) + { + ir_data_fifo[ii] = 0; + } + ir_dc_temp = 0; + } + else + { + for(ii=3; ii>0; ii--) + { + ir_data_fifo[ii] = ir_data_fifo[ii-1]; + } + ir_data_fifo[0] = ir_new_raw_data; + cali_data_cnt++; + if(cali_data_cnt>=25) + { + if ((((ir_data_fifo[1] - ir_data_fifo[2]) > SOP2_DEGLITCH_THRE) && ((ir_data_fifo[1] - ir_new_raw_data) > SOP2_DEGLITCH_THRE)) || \ + (((ir_data_fifo[1] - ir_data_fifo[2]) < -SOP2_DEGLITCH_THRE) && ((ir_data_fifo[1] - ir_new_raw_data) < -SOP2_DEGLITCH_THRE))) + { + ir_new_raw_data = ir_data_fifo[2]; + ir_data_fifo[1] = ir_data_fifo[2]; + } + else + { + ir_new_raw_data = ir_data_fifo[1]; + } + if ((abs((ir_new_raw_data - ir_jump_delta) - ir_data_pre) > SPO2_REMOVE_JUMP_THRE)) + { + ir_jump_delta = ir_new_raw_data - ir_data_pre; + } + ir_data_cali = ir_new_raw_data - ir_jump_delta; + ir_data_pre = ir_data_cali; + } + else + { + ir_data_cali = ir_data_fifo[1]; + ir_data_pre = ir_data_fifo[1]; + } + } + if(cali_data_cnt<=30) + { + ir_dc_temp = ir_data_cali; + ir_data_final = ir_new_raw_data; + } + else + { + //ir_dc_temp = (ir_dc_temp*31 + ir_data_cali)>>5; + ir_dc_temp = 0; + ir_data_final = ir_data_cali - ir_dc_temp + 2608*50*hx3695_spo2_agc_ir_idac; + } + //DEBUG_PRINTF("%d %d %d %d %d %d\r\n", cali_data_cnt, ir_new_raw_data, ir_data_final, ir_data_cali, ir_dc_temp, hx3695_spo2_agc_ir_idac); + return ir_data_final; +} +#endif //SPO2_DATA_CALI + +//#ifdef SPO2_ALG_LIB +spo2_sensor_data_t spo2_s_dat; + +/**** + * +typedef struct { + spo2_alg_msg_code_t spo2_alg_status; + spo2_living_code_t spo2_living_status; + uint32_t data_cnt; + uint8_t spo2_result; + uint8_t hr_result; + uint8_t block_cnt; + uint8_t ir_quality; + uint16_t reliable_score_result; + + uint8_t screen_up; + uint8_t motion; + uint8_t poor_signal; + + uint8_t signal_snr; + uint32_t signal_std; + +} spo2_results_t; + +*/ +/*TYHX 血氧模式下 读取PPG, 默认320ms*/ +void hx3695_spo2_ppg_Int_handle(void) +{ + uint8_t ii=0; + spo2_results_t spo2_alg_results = {MSG_SPO2_ALG_NOT_OPEN,0,0,0,0,0,0,1,0,0,0,0,0}; + spo2_wear_msg_code_t spo2_wear_status = MSG_SPO2_NO_WEAR; + SPO2_CAL_SET_T cal = get_spo2_agc_status(); + int32_t *red_buf = &(spo2_s_dat.red_data[0]); + int32_t *ir_buf = &(spo2_s_dat.ir_data1[0]); + int32_t *green_buf = &(spo2_s_dat.green_data[0]); + uint8_t *count = &(spo2_s_dat.count); + int16_t gsen_fifo_x_send[32]= {0}; + int16_t gsen_fifo_y_send[32]= {0}; + int16_t gsen_fifo_z_send[32]= {0}; +#ifdef SPO2_DATA_CALI + int32_t red_data_cali, ir_data_cali; +#endif + +#ifdef SPO2_VECTOR + for(ii=0; ii<8; ii++) + { + red_buf_vec[ii] = vec_red_data[spo2_send_cnt+ii]; + ir_buf_vec[ii] = vec_ir_data[spo2_send_cnt+ii]; + green_buf_vec[ii] = vec_green_data[spo2_send_cnt+ii]; + } + spo2_send_cnt = spo2_send_cnt+8; + *count = 8; + tyhx_spo2_alg_send_data(red_buf, ir_buf, green_buf, cal.R_LEDDAC, cal.IR_LEDDAC1, cal.R_LEDDAC, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send, *count); + +#else + if(hx3695_spo2_read(&spo2_s_dat) == 0) + { + return; + } + + +#ifndef GSEN_40MS_TIMMER + readFifoByHrsModule(); +#endif + DEBUG_PRINTF("\r\n send1 jlink cnt=%d\r\n",*count); + + for(ii=0; ii<*count; ii++) + { + gsen_fifo_x_send[ii] = gsen_fifo_x[32-*count+ii]; + gsen_fifo_y_send[ii] = gsen_fifo_y[32-*count+ii]; + gsen_fifo_z_send[ii] = gsen_fifo_z[32-*count+ii]; + //DEBUG_PRINTF("%d/%d %d %d %d %d %d %d\r\n" ,1+ii,*count,red_buf[ii],ir_buf[ii],green_buf[ii],gsen_fifo_x[ii],gsen_fifo_y[ii],gsen_fifo_z[ii]); + // hx3695_factory_test_process(NULL, APP_FACTORY_TEST_SPO2_START, (uint8_t *)&red_buf[ii]); + + } + AGC_LOG("hx3695 current value: %d %d %d %d %d %d\r\n", cal.R_LED, cal.IR_LED1, cal.G_LED, cal.R_LEDDAC, cal.IR_LEDDAC1, cal.G_LEDDAC); + spo2_wear_status = hx3695_spo2_get_wear_status(); + if(spo2_wear_status == MSG_SPO2_WEAR) + { + tyhx_spo2_alg_send_data(red_buf, ir_buf, green_buf, cal.R_LEDDAC, cal.IR_LEDDAC1, cal.G_LEDDAC, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send, *count); + } +#endif + + spo2_alg_results = tyhx_spo2_alg_get_results(); +//------------------------adjust------------------- + //DEBUG_PRINTF("block_cnt: %d, data_cnt:%d, hr_result:%d,ir_quality:%d,motion:%d,poor_signal:%d,reliable_score_result:%d,screen_up:%d,spo2_result:%d\r\n",spo2_alg_results.block_cnt,spo2_alg_results.data_cnt,spo2_alg_results.hr_result,spo2_alg_results.ir_quality,spo2_alg_results.motion,spo2_alg_results.poor_signal,spo2_alg_results.reliable_score_result,spo2_alg_results.screen_up,spo2_alg_results.spo2_result); + + hrsresult.lastestspo2 = spo2_alg_results.spo2_result; +// if(hrsresult.lastestspo2) + { + // store_latest_spo2(hrsresult.lastestspo2); + // app_hr_cal_hr_values(hrsresult.lastesthrs); +// gui_send_message_by_data(MSG_SPO2_DATA, &hrsresult.lastestspo2, 1); +// hr_sensor_notify_factory_test(); + } + + + +/////////////////////////////////////////BLE+DISPLAY////////////////////////////////////////// + + +#ifdef HRS_BLE_APP + { + rawdata_vector_t rawdata; + SPO2_CAL_SET_T cal= get_spo2_agc_status(); + for(ii=0; ii<*count; ii++) + { +#ifdef SPO2_DATA_CALI + ir_data_cali = hx3695_ir_data_cali(ir_buf[ii]); + red_data_cali = hx3695_red_data_cali(red_buf[ii]); + rawdata.red_raw_data = red_data_cali>>2; + rawdata.ir_raw_data = ir_data_cali>>2; +#else + rawdata.red_raw_data = red_buf[ii]; + rawdata.ir_raw_data = ir_buf[ii]; +#endif + rawdata.vector_flag = SPO2_VECTOR_FLAG; + rawdata.data_cnt = cal.G_LEDDAC; + rawdata.hr_result = spo2_alg_results.spo2_result; + rawdata.gsensor_x = (int16_t)(green_buf[ii]>>5); + rawdata.gsensor_y = cal.R_LEDDAC; + rawdata.gsensor_z = cal.IR_LEDDAC1; + rawdata.red_cur = cal.R_LED; + rawdata.ir_cur = cal.IR_LED1; + ble_rawdata_vector_push(rawdata); + } + ble_rawdata_send_handler(); + } +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////// +} +#endif //SPO2_ALG_LIB + + + +#if defined(HRS_ALG_LIB) && defined (SPO2_ALG_LIB) +spo2_sensor_data_t hrspo2_s_data; + +void hx3695_hrspo2_ppg_Int_handle(void) +{ + uint8_t ii=0; + spo2_results_t spo2_alg_results = {MSG_SPO2_ALG_NOT_OPEN,0,0,0,0,0,0,0,0,0,0,0,0}; + hrs_results_t alg_results = {MSG_HRS_ALG_NOT_OPEN,0,0,0,0,0,0}; + spo2_wear_msg_code_t spo2_wear_status = MSG_SPO2_NO_WEAR; + SPO2_CAL_SET_T cal = get_spo2_agc_status(); + int32_t *red_buf = &(hrspo2_s_data.red_data[0]); + int32_t *ir_buf = &(hrspo2_s_data.ir_data1[0]); + int32_t *green_buf = &(hrspo2_s_data.red_data[0]); // &(hrspo2_s_data.green_data[0]); + uint8_t *count = &(ppg_s_data.count); + int16_t gsen_fifo_x_send[32]= {0}; + int16_t gsen_fifo_y_send[32]= {0}; + int16_t gsen_fifo_z_send[32]= {0}; +#ifdef SPO2_DATA_CALI + int32_t red_data_cali, ir_data_cali; +#endif + + if(hx3695_spo2_read(&hrspo2_s_data) == 0) + { + return; + } + +#ifndef GSEN_40MS_TIMMER + readFifoByHrsModule(); +#endif + DEBUG_PRINTF("\r\nsend jlink cnt=%d\r\n",*count); + + + for(ii=0; ii<*count; ii++) + { + gsen_fifo_x_send[ii] = gsen_fifo_x[32-*count+ii]; + gsen_fifo_y_send[ii] = gsen_fifo_y[32-*count+ii]; + gsen_fifo_z_send[ii] = gsen_fifo_z[32-*count+ii]; + + } + spo2_wear_status = hx3695_spo2_get_wear_status(); + if(spo2_wear_status == MSG_SPO2_WEAR) + { + tyhx_spo2_alg_send_data(red_buf, ir_buf, green_buf, cal.R_LEDDAC, cal.IR_LEDDAC1, cal.R_LEDDAC, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send, *count); + //tyhx_hrs_alg_send_data(green_buf,*count, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send); + //DEBUG_PRINTF("%d/%d %d %d %d %d %d %d\r\n" ,1+ii,*count,red_buf[ii],ir_buf[ii],green_buf[ii],gsen_fifo_x[ii],gsen_fifo_y[ii],gsen_fifo_z[ii]); + } + //DEBUG_PRINTF("%d %d %d %d %d %d\r\n", cal.R_LED, cal.IR_LED, cal.G_LED, cal.R_LEDDAC, cal.IR_LEDDAC, cal.G_LEDDAC); + + spo2_alg_results = tyhx_spo2_alg_get_results(); + alg_results = tyhx_hrs_alg_get_results(); + //DEBUG_PRINTF("spo2_wear_status: %d, hr_result:%d, spo2_result:%d\r\n" ,spo2_wear_status, spo2_alg_results.hr_result,spo2_alg_results.spo2_result); + +/////////////////////////////////////////BLE+DISPLAY////////////////////////////////////////// + +#ifdef HRS_BLE_APP + { + rawdata_vector_t rawdata; + SPO2_CAL_SET_T cal= get_spo2_agc_status(); + for(ii=0; ii<*count; ii++) + { +#ifdef SPO2_DATA_CALI + ir_data_cali = hx3695_ir_data_cali(ir_buf[ii]); + red_data_cali = hx3695_red_data_cali(red_buf[ii]); + rawdata.red_raw_data = red_data_cali>>2; + rawdata.ir_raw_data = ir_data_cali>>2; +#else + rawdata.red_raw_data = red_buf[ii]; + rawdata.ir_raw_data = ir_buf[ii]; +#endif + rawdata.vector_flag = SPO2_VECTOR_FLAG; + rawdata.data_cnt = cal.G_LEDDAC; + rawdata.hr_result = spo2_alg_results.spo2_result; + rawdata.gsensor_x = (int16_t)(green_buf[ii]>>5); + rawdata.gsensor_y = cal.R_LEDDAC; + rawdata.gsensor_z = cal.IR_LEDDAC1; + rawdata.red_cur = cal.R_LED; + rawdata.ir_cur = cal.IR_LED1; + ble_rawdata_vector_push(rawdata); + } + ble_rawdata_send_handler(); + } +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////// +} +#endif //defined(HRS_ALG_LIB) && defined (SPO2_ALG_LIB) + +#ifdef HRV_ALG_LIB +hrv_sensor_data_t hrv_s_dat; +void hx3695_hrv_ppg_Int_handle(void) +{ + uint8_t ii=0; + hrv_results_t hrv_alg_results= {MSG_HRV_ALG_NOT_OPEN,0,0,0,0,0,1,0,0}; + int32_t *PPG_buf = &(hrv_s_dat.green_data[0]); + int32_t *ir_buf = &(hrv_s_dat.ir_data[0]); + uint8_t *count = &(hrv_s_dat.count); + hrv_wear_msg_code_t hrv_wear_status = MSG_HRV_NO_WEAR; + int16_t gsen_fifo_x_send[64]= {0}; + int16_t gsen_fifo_y_send[64]= {0}; + int16_t gsen_fifo_z_send[64]= {0}; + + // DEBUG_PRINTF("1111 \r\n" ); +#ifdef HRV_TESTVEC + int32_t hrm_raw_data; + hrm_raw_data = vec_data[vec_data_cnt]; + vec_data_cnt++; + alg_hrv_results = hx3695_hrv_alg_send_data(hrm_raw_data, 0, 0); +#else + if(hx3695_hrv_read(&hrv_s_dat) == 0) + { + TYHX_LOG("read ppg_s data invalid\r\n"); + return; + } + +#ifndef GSEN_40MS_TIMMER + readFifoByHrsModule(); +#endif + DEBUG_PRINTF("\r\nsend jlink cnt=%d\r\n",*count); + + for(ii=0; ii<*count; ii++) + { + gsen_fifo_x_send[ii] = gsen_fifo_x[32-8+ii%8]; + gsen_fifo_y_send[ii] = gsen_fifo_y[32-8+ii%8]; + gsen_fifo_z_send[ii] = gsen_fifo_z[32-8+ii%8]; + // DEBUG_PRINTF("%d/%d %d %d %d %d %d \r\n" ,1+ii,*count,PPG_buf[ii],ir_buf[0],gsen_fifo_x_send[ii] ,gsen_fifo_y_send[ii] ,gsen_fifo_z_send[ii] ); + + } + hrv_wear_status = hx3695_hrv_get_wear_status(); +// DEBUG_PRINTF("wear:%d \r\n" ,hrv_wear_status); + if(hrv_wear_status==MSG_HRS_WEAR) + { + hrv_alg_results = tyhx_hrv_alg_send_bufdata(PPG_buf, *count, gsen_fifo_x_send, gsen_fifo_y_send, gsen_fifo_z_send); + hrsresult.lastesthrv = hrv_alg_results.hrv_result; + TYHX_LOG("get the hrv = %d\r\n",hrv_alg_results.hrv_result); + } + //--------------adjust---------------- +// hrv_alg_results.motion,hrv_alg_results.screen_up; + //DEBUG_PRINTF("data_cnt:%d hrv_result:%d motion:%d p_m:%d screen_up:%d signal_quality:%d \r\n", hrv_alg_results.data_cnt,hrv_alg_results.hrv_result,hrv_alg_results.motion,hrv_alg_results.p_m,hrv_alg_results.screen_up,hrv_alg_results.signal_quality); +#endif + +/////////////////////////////////////////BLE+DISPLAY////////////////////////////////////////// + + +#ifdef HRS_BLE_APP + { + rawdata_vector_t rawdata; + HRS_CAL_SET_T cal= get_hrs_agc_status(); + for(ii=0; ii<*count; ii++) + { + rawdata.vector_flag = HRS_VECTOR_FLAG; + rawdata.data_cnt = 0; + rawdata.hr_result = hrv_alg_results.hrv_result; + rawdata.red_raw_data = PPG_buf[ii]; + rawdata.ir_raw_data = 0; + rawdata.gsensor_x = gsen_fifo_x_send[ii]; + rawdata.gsensor_y = gsen_fifo_y_send[ii]; + rawdata.gsensor_z = gsen_fifo_z_send[ii]; + rawdata.red_cur = cal.Group1_Cur; + rawdata.ir_cur = 0; + ble_rawdata_vector_push(rawdata); + } + } + + ble_rawdata_send_handler(); +#endif + +////////////////////////////////////////////////////////////////////////////////////////////// +} +#endif + +#ifdef CHECK_TOUCH_LIB +void hx3695_wear_ppg_Int_handle(void) +{ + uint8_t *count = &(ppg_s_data.count); + int32_t *ir_buf = &(ppg_s_data.ir_data[0]); + hx3695_wear_msg_code_t hx3695_wear_status; + + hx3695_check_touch_read(&ppg_s_data); + hx3695_wear_status = hx3695_check_touch_send_data(ir_buf,*count); + hrsresult.wearstatus = hx3695_wear_status; + extern uint8_t notouch_cnt; + extern uint8_t touch_cnt; + + if (hrsresult.wearstatus) + { + cwm_gsensor_enable(); + } + else + { + cwm_gsensor_disable(); + } +// AGC_LOG("===> touch_cnt: %d, notouch_cnt: %d, wear status: %d, \r\n", touch_cnt, notouch_cnt, hx3695_wear_status); + +// AGC_LOG("hx3695_wear_ppg_Int_handle wearstatus = %d\r\n", hrsresult.wearstatus); + +// for(int i=0;i<*count;i++) +// { +// DEBUG_PRINTF("%d,%d,%d,%d,%d,%d\r\n",1+i,*count,ir_buf[i],ppg_s_data.s_buf[i*2],ppg_s_data.s_buf[i*2+1],hx3695_wear_status); +// } +} +#endif + +#ifdef LAB_TEST +void hx3695_lab_test_Int_handle(void) +{ + NOISE_PS_T ps_noise; + ps_noise = hx3695_lab_test_read_packet(); + DEBUG_PRINTF("%d %d %d %d\r\n", ps_noise.p1_noise, ps_noise.p2_noise, ps_noise.p3_noise, ps_noise.p4_noise); +} +#endif + + +#endif //CHIP_HX3695 diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695.h new file mode 100644 index 000000000..ba6c31bae --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695.h @@ -0,0 +1,299 @@ +#ifndef _hx3695_H_ +#define _hx3695_H_ +#include +#include + +/********************* alg_swi ********************* +HRS_ALG_LIB 心率功能 +SPO2_ALG_LIB 血氧功能 +HRV_ALG_LIB HRV功能 +CHECK_TOUCH_LIB 纯佩戴功能(非心率血氧模式) +CHECK_LIVING_LIB 纯物体识别功能(非心率血氧模式) +BP_CUSTDOWN_ALG_LIB 血压功能 + +TIMMER_MODE 定时器模式, 读PPG数据, 默认采用定时器模式 +INT_MODE 中断模式,读PPG数据 + +DEMO_MI demo相关配置, 客户关闭, 在下面else里进行配置 +HRS_BLE_APP DEMO蓝牙控制宏, 客户关闭 +SPO2_DATA_CALI 血氧DC补偿模式, 客户关闭 +HRS_DEBUG 调试宏, 根据平台定义打印函数 +AGC_DEBUG 调试宏, 根据平台定义打印函数 +GSEN_40MS_TIMMER DEMO调试使用, 客户关闭 +NEW_GSEN_SCHME DEMO调试使用, 客户关闭 +*/ +#define HRS_ALG_LIB +#define SPO2_ALG_LIB +// #define HRV_ALG_LIB +//#define CHECK_TOUCH_LIB +//#define CHECK_LIVING_LIB +#define BP_CUSTDOWN_ALG_LIB + +//**************** read_data_mode ******************// +#define TIMMER_MODE //timmer read fifo +//#define INT_MODE //fifo_all_most_full + +//****************** gsen_cgf *********************// +// #define GSEN_40MS_TIMMER +//#define NEW_GSEN_SCHME + +//****************** other_cgf ********************// +#define DEMO_COMMON +//#define HRS_BLE_APP +//#define SPO2_DATA_CALI + +//***************** vecter_swi ********************// +//#define SPO2_VECTOR +//#define HR_VECTOR +//#define HRV_TESTVEC + +//**************** lab_test_mode ******************// +//#define LAB_TEST +//#define LAB_TEST_AGC + +//****************** print_swi ********************// +#define HRS_DEBUG +#define AGC_DEBUG + +//**************************************************// +#include "debug_print.h" + +#ifdef AGC_DEBUG +#define AGC_LOG(fmt, ...) \ + do { \ + PRINT(fmt" ", ##__VA_ARGS__); \ + } while (0) +#else +#define AGC_LOG(...) +#endif + +#ifdef HRS_DEBUG +#define DEBUG_PRINTF(fmt, ...) \ + do { \ + PRINT(fmt" ", ##__VA_ARGS__); \ + } while (0) +#else +#define DEBUG_PRINTF(...) +#endif + + +#if defined(DEMO_COMMON) + #define HRS4100_IIC_CLK 30 + #define HRS4100_IIC_SDA 0 + #define LIS3DH_IIC_CLK 18 + #define LIS3DH_IIC_SDA 16 + #define EXT_INT_PIN 1 + #define GREEN_LED_SLE 0x10 + #define RED_LED_SLE 0x20 + #define IR_LED_SLE 0x40 + #define RED_AGC_OFFSET 64 //32 + #define IR_AGC_OFFSET 64 //32 + #define GREEN_AGC_OFFSET 4 //10 + #define HR_GREEN_AGC_OFFSET 20 + #define HR_GREEN1_AGC_OFFSET 24 + #define HR_GREEN2_AGC_OFFSET 24 + #define HR_GREEN3_AGC_OFFSET 24 + + + + #define BIG_SCREEN + +#elif defined(DEMO_MI) + #define HRS4100_IIC_CLK 30 + #define HRS4100_IIC_SDA 0 + #define LIS3DH_IIC_CLK 18 + #define LIS3DH_IIC_SDA 16 + #define EXT_INT_PIN 1 + #define GREEN_LED_SLE 1 + #define RED_LED_SLE 2 + #define IR_LED_SLE 4 + #define RED_AGC_OFFSET 50 + #define IR_AGC_OFFSET 50 + #define GREEN_AGC_OFFSET 4 + #define HR_GREEN_AGC_OFFSET 4 + #define BIG_SCREEN + +#elif defined(DEMO_NEW) + #define HRS4100_IIC_CLK 30 + #define HRS4100_IIC_SDA 0 + #define LIS3DH_IIC_CLK 18 + #define LIS3DH_IIC_SDA 16 + #define EXT_INT_PIN 1 + #define GREEN_LED_SLE 1 + #define RED_LED_SLE 2 + #define IR_LED_SLE 4 + #define RED_AGC_OFFSET 75 + #define IR_AGC_OFFSET 75 + #define GREEN_AGC_OFFSET 4 + #define HR_GREEN_AGC_OFFSET 8 + #define BIG_SCREEN + +#elif defined(EVB) + #define HRS4100_IIC_CLK 9 + #define HRS4100_IIC_SDA 10 + #define LIS3DH_IIC_CLK 13 + #define LIS3DH_IIC_SDA 14 + #define EXT_INT_PIN 11 + #define GREEN_LED_SLE 1 + #define RED_LED_SLE 2 + #define IR_LED_SLE 4 + #define RED_AGC_OFFSET 64 + #define IR_AGC_OFFSET 64 + #define GREEN_AGC_OFFSET 8 + #define HR_GREEN_AGC_OFFSET 10 + +#else + #define GREEN_LED_SLE 1 + #define RED_LED_SLE 4 + #define IR_LED_SLE 2 + #define RED_AGC_OFFSET 64 + #define IR_AGC_OFFSET 64 + #define GREEN_AGC_OFFSET 8 + +#endif + +typedef enum { + PPG_INIT, + PPG_OFF, + PPG_LED_OFF, + CAL_INIT, + CAL_OFF, + RECAL_INIT +} hx3695_mode_t; + +typedef enum { + SENSOR_OK, + SENSOR_OP_FAILED, +} SENSOR_ERROR_T; + + +typedef enum { + DATA_TYPE_PPG, + DATA_TYPE_GSEN, +} SENSOR_TYPE_T; + +typedef enum { + HRS_MODE, + SPO2_MODE, + HRSPO2_MODE, + WEAR_MODE, + HRV_MODE, + LIVING_MODE, + LAB_TEST_MODE, + FT_LEAK_LIGHT_MODE, + FT_GRAY_CARD_MODE, + FT_INT_TEST_MODE, + FT_SINGLE_CHECK_MODE, + FT_LED_OFF_MODE, + FT_WEAR_MODE, + NULL_MODE, +} WORK_MODE_T; + + +//typedef struct { +// uint8_t count; +// int32_t green_data[64]; +// int32_t ir_data[64]; +// int32_t s_buf[64]; +// uint32_t als; +// uint32_t agc_green; +//} hrs_sensor_data_t; + + +typedef struct { + uint8_t count; + int32_t red_data[64]; + int32_t green_data[64]; + int32_t ir_data[64]; + int32_t s_buf[64]; + uint8_t green_cur; + uint8_t red_cur; + uint8_t ir_cur; + uint8_t green_offset; + uint8_t red_offset; + uint8_t ir_offset; +}ppg_sensor_data_t; + +typedef enum { + MSG_LIVING_INIT, + MSG_LIVING_NO_WEAR, + MSG_LIVING_WEAR +} hx3695_living_wear_msg_code_t; + +typedef enum { + MSG_NO_WEAR, + MSG_WEAR +} hx3695_wear_msg_code_t; + +typedef struct { + hx3695_living_wear_msg_code_t wear_status; + uint32_t data_cnt; + uint8_t signal_quality; + uint8_t motion_status; +} hx3695_living_results_t; + +typedef struct { + int32_t p1_noise; + int32_t p2_noise; + int32_t p3_noise; + int32_t p4_noise; +}NOISE_PS_T; + + +extern uint8_t alg_ram[11*1024]; +//extern uint8_t alg_ram[10]; + +void hx3695_delay_us(uint32_t us); +void hx3695_delay_ms(uint32_t ms); +bool hx3695_write_reg(uint8_t addr, uint8_t data); +uint8_t hx3695_read_reg(uint8_t addr); +bool hx3695_brust_read_reg(uint8_t addr , uint8_t *buf, uint8_t length); +bool hx3695_chip_check(void); +uint8_t hx3695_read_fifo_size(void); +uint16_t hx3695_read_fifo_data(int32_t *s_buf, uint8_t size, uint8_t phase_num); +void hx3695_ppg_off(void); +void hx3695_ppg_on(void); +void hx3695_320ms_timer_cfg(bool en); +void hx3695_40ms_timer_cfg(bool en); +void hx3695_gpioint_cfg(bool en); +bool hx3695_init(WORK_MODE_T mode); +void hx3695_agc_Int_handle(void); +void hx3695_gesensor_Int_handle(void); +void hx3695_spo2_ppg_init(void); +void hx3695_spo2_data_cali_init(void); +void hx3695_spo2_ppg_Int_handle(void); +void hx3695_check_touch_init(void); +void hx3695_wear_ppg_Int_handle(void); +void hx3695_hrs_ppg_init(void); +void hx3695_hrs_ppg_Int_handle(void); +void hx3695_hrv_ppg_init(void); +void hx3695_hrv_ppg_Int_handle(void); +void hx3695_living_Int_handle(void); +void hx3695_hrspo2_ppg_Int_handle(void); + +void hx3695_ppg_Int_handle(void); +uint32_t hx3695_timers_start(void); +uint32_t hx3695_timers_stop(void); +uint32_t hx3695_gpioint_init(void); + +uint32_t hx3695_gpioint_enable(void); +uint32_t hx3695_gpioint_disable(void); +uint32_t gsen_read_timers_start(void); +uint32_t gsen_read_timers_stop(void); + +void hx3695_vin_check(uint16_t led_vin); + +#ifdef LAB_TEST +void hx3695_lab_test_init(void); +void hx3695_test_alg_cfg(void); +SENSOR_ERROR_T hx3695_lab_test_enable(void); +void hx3695_lab_test_Int_handle(void); +NOISE_PS_T hx3695_lab_test_read_packet(void); +#endif + +bool hx3695_living_send_data(int32_t *new_raw_data, uint8_t dat_len, int16_t *gsen_data_x, int16_t *gsen_data_y, int16_t *gsen_data_z); +hx3695_living_results_t hx3695_living_get_results(void); +void agc_timeout_handler(void * p_context); +void heart_rate_meas_timeout_handler(void * p_context); + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_at_cmd.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_at_cmd.c new file mode 100644 index 000000000..630f41488 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_at_cmd.c @@ -0,0 +1,113 @@ + +#include "hx3695.h" +#include "tyhx_hrs_custom.h" +#include "at_cmd_api.h" +#include "pm_control.h" + + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define HX3695_MAX_ARGC 8 +#define HX3695_MAX_ARGV_LEN 64 + +#define HX3695_SUCCESS 0 +#define HX3695_FAILED (-1) + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[HX3695_MAX_ARGC][HX3695_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 >= HX3695_MAX_ARGC) { + return HX3695_FAILED; + } + } else { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= HX3695_MAX_ARGV_LEN) { + return HX3695_FAILED; + } + } + } + if (pos != 0) { + *argc += 1; + } + + return HX3695_SUCCESS; +} + + +static uint32_t hx3695_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t argv[HX3695_MAX_ARGC][HX3695_MAX_ARGV_LEN] = { 0 }; + uint32_t argc = 0; + + int ret = ConvertCmdToParam(para, paraLen, argv, &argc); + if (ret != HX3695_SUCCESS) { + TYHX_ERROR("HX3695TEST ATCMD Convert Command Failed\n"); + return ERRCODE_FAIL; + } + + if (argc != 2) { + TYHX_ERROR("HX3695TEST ATCMD Set Parameter Failed\n"); + return ERRCODE_FAIL; + } + char *mode = (char*)argv[0]; + WORK_MODE_T md = NULL_MODE; + if (strcmp(mode, "hrs") == 0) { + md = HRS_MODE; + } else if (strcmp(mode, "hrv") == 0) { + md = HRV_MODE; + } else if (strcmp(mode, "spo2") == 0) { + md = SPO2_MODE; + } else if (strcmp(mode, "leaklight") == 0) { + md = FT_LEAK_LIGHT_MODE; + } else if (strcmp(mode, "graycard") == 0) { + md = FT_GRAY_CARD_MODE; + } + char *enable = (char *)argv[1]; + if (strcmp(enable, "enable") == 0) { + + uapi_pm_control(PM_APP_WAKE_NEEDED); + tyhx_poweron(); + hx3695_init(md); + } else { + if(md == HRS_MODE|| md == FT_LEAK_LIGHT_MODE || md == FT_GRAY_CARD_MODE) + { +#ifdef HRS_ALG_LIB + hx3695_hrs_disable(); +#endif + }else if(md == HRV_MODE) + { +#ifdef HRV_ALG_LIB + hx3695_hrv_disable(); +#endif + }else if(md == SPO2_MODE) + { +#ifdef SPO2_ALG_LIB + hx3695_spo2_disable(); +#endif + } + + uapi_pm_control(PM_APP_WAKE_NONEED); + tyhx_poweroff(); + } + + return ERRCODE_SUCC; +} + +static const at_cmd_table_t g_hx3695_cmd[] = { + { (char *)"AT^HX3695TEST", hx3695_do_test, (char *)"hrs enable" }, +}; + +at_cmd_table_t *get_hx3695_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_hx3695_cmd); + return (at_cmd_table_t *)g_hx3695_cmd; +} diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_at_cmd.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_at_cmd.h new file mode 100644 index 000000000..6d7574b12 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 HX3695_AT_PROCESS_H +#define HX3695_AT_PROCESS_H + +#include +#include +#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_hx3695_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_check_touch.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_check_touch.c new file mode 100644 index 000000000..ea1817a75 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_check_touch.c @@ -0,0 +1,207 @@ +#include +#include +#include +#include +#include + + +#include "tyhx_hrs_custom.h" +#include "hx3695.h" +#include "hx3695_check_touch.h" + + + +hx3695_wear_msg_code_t hx3695_wear_status = MSG_NO_WEAR; +hx3695_wear_msg_code_t hx3695_wear_status_pre = MSG_NO_WEAR; +extern uint8_t hrs_phase_num; +extern const int32_t check_mode_unwear_thre; +extern const int32_t check_mode_wear_thre; +static uint8_t notouch_cnt = 0; +static uint8_t touch_cnt = 0; + +#ifdef CHECK_TOUCH_LIB + + +SENSOR_ERROR_T hx3695_check_touch_enable(void) +{ + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return SENSOR_OP_FAILED; + } + + AGC_LOG("hx3695 check id success!\r\n"); + + hx3695_check_touch_init(); + hx3695_delay_ms(100); +// uint16_t i,reg_value ; +// for(i = 0;i < 0x7f; i++) +// { +// reg_value = hx3695_read_reg(i); +// AGC_LOG("Reg_value: %x, 0x%x \r\n",i,reg_value); +// +// hx3695_delay_ms(5); +// } + + +// AGC_LOG("hx3695 here!\r\n"); + hx3695_delay_ms(100); + + hx3695_320ms_timer_cfg(true); + + return SENSOR_OK; +} + +//uint8_t hx3695_check_touch_read_fifo(int32_t *ir_buf) +//{ +// uint8_t data_flg = 127; +// int32_t data; +// uint8_t databuf[3]; +// uint8_t ii=0; +// uint8_t data_size=0; +// uint8_t count=0; +// int32_t buf[64]; + +// data_size = hx3695_read_fifo_size(); +// count = data_size>>1; +// data_size = count*2; + +// for(ii=0; ii>5; +// data = (int32_t)(databuf[0]|(databuf[1]<<8)|((databuf[2]&0x1f)<<16)); + +// if(ii==0) +// { +// if(data_flg ==3) +// { +// ii=3; +// buf[0] = 0; +// buf[1] = 0; +// buf[2] = 0; +// } +// if(data_flg ==2) +// { +// ii=2; +// buf[0] = 0; +// buf[1] = 0; +// } +// if(data_flg ==1) +// { +// ii=1; +// buf[0] = 0; +// } +// } + +// if(data_flg == 0) +// { +// buf[ii]= data; +// } +// else if(data_flg == 1) +// { +// buf[ii]= data; +// } +// else if(data_flg == 2) +// { +// buf[ii]= data; +// } +// else if(data_flg == 3) +// { +// buf[ii]= data; +// } +// } +// for (ii=0; iibuf[ii*2+1]) +// { +// ir_buf[ii] = buf[ii*2] - buf[ii*2+1]; +// } +// else +// { +// ir_buf[ii] = 0; +// } +// } +// return count; +//} + + +uint8_t hx3695_check_touch_read(ppg_sensor_data_t *s_dat) +{ + uint8_t i=0; + uint8_t size = 0; + uint8_t fifo_out_size = 0; + int32_t *green_data = &(s_dat->green_data[0]); + int32_t *ir_buf = &(s_dat->ir_data[0]); + int32_t *s_buf = &(s_dat->s_buf[0]); + +// size = hx3695_read_fifo_size(); +// +// if(size<2) +// { +// return 0; +// } + +// if (size && size <= 256) +// { + fifo_out_size = hx3695_read_fifo_data(s_buf,hrs_phase_num,2); + s_dat->count = fifo_out_size; + for (i=0; icheck_mode_wear_thre) + { + notouch_cnt = 0; + if(touch_cnt>=2) + { + hx3695_wear_status = MSG_WEAR; + touch_cnt=0; + } + else + { + touch_cnt++; + } + } + else if(ir_data=2) + { + hx3695_wear_status = MSG_NO_WEAR; + notouch_cnt=0; + } + else + { + notouch_cnt++; + } + } + return hx3695_wear_status; +} +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_check_touch.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_check_touch.h new file mode 100644 index 000000000..e4a19c55f --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_check_touch.h @@ -0,0 +1,17 @@ +#ifndef _HX3695_CHECK_TOUCH_H_ +#define _HX3695_CHECK_TOUCH_H_ + +#include +#include +#include "hx3695.h" +#include "hx3695.h" +#include "hx3695_hrv_agc.h" + + +hx3695_wear_msg_code_t check_touch_alg(int32_t ir_data); +SENSOR_ERROR_T hx3695_check_touch_enable(void); +uint8_t hx3695_check_touch_read(ppg_sensor_data_t *s_dat); +hx3695_wear_msg_code_t hx3695_check_touch_send_data(int32_t *ir_data, uint8_t count); +hx3695_wear_msg_code_t check_touch_alg(int32_t ir_data); + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_factory_test.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_factory_test.c new file mode 100644 index 000000000..9b2b56f84 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_factory_test.c @@ -0,0 +1,2917 @@ +#include +#include +#include +#include +#include + +#include "tyhx_hrs_custom.h" +#include "hx3695.h" +#include "hx3695_factory_test.h" + + +void hx3695_factory_wear_mode_config(void) +{ + uint16_t sample_rate = 10; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t adc_rst_post_num=0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; /* phase7 and phase8 prf internal cfg */ + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 0; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 0; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0x10; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 64; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = 0; //GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0; + uint8_t phase2_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; //IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 5 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + +// hx3695_write_reg(0X4e, thred_value); +// hx3695_write_reg(0X4f, thred_value>>5); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel)); //<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92); // bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release +// read_fifo_first_flg = 1; + return ; + + + +} + +void hx3695_factory_ft_card_test_config(void)//灰卡15mm高度测试配置 +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + +// uint16_t fifo_watermark= 250 ; + uint8_t adc_rst_post_num= 0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; //0x18; /* phase7 and phase8 prf internal cfg */ + +// uint16_t thred_value = 32500; + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 32; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0x00; + uint8_t phase2_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 32; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 32; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 32; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0a; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 4; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x00; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 4 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x00);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x08); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //(FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X36, 0x00); //intrupt + + hx3695_write_reg(0X38, 0x00); // int sel,00=close almost full int,01= prf int 04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release + + return ; +} + +void hx3695_factory_ft_single_check_config(void)//灰卡10mm高度测试配置 +{ + + uint16_t sample_rate = 200; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t adc_rst_post_num=0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; /* phase7 and phase8 prf internal cfg */ + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = GREEN_LED_SLE; //GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0x00; + uint8_t phase2_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 16; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 16; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 16; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; //IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 5 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + +// hx3695_write_reg(0X4e, thred_value); +// hx3695_write_reg(0X4f, thred_value>>5); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel)); //<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92); // bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release + + return ; +} + +void hx3695_factory_ft_leak_light_test_config(void)//漏光测试配置 +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + + uint8_t adc_rst_post_num= 0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; //0x18; /* phase7 and phase8 prf internal cfg */ + +// uint16_t thred_value = 32500; + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0x00; + uint8_t phase2_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 64; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 64; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 64; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 4; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 0; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 4; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 0; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x00; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 0; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 50; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 0; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 4 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x00);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x08); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //(FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X36, 0x00); //intrupt + + hx3695_write_reg(0X38, 0x00); // int sel,00=close almost full int,01= prf int 04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release + + return ; +} + +void hx3695_factory_led_off_config(void) +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t adc_rst_post_num=0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; /* phase7 and phase8 prf internal cfg */ + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0; + uint8_t phase2_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 5; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; //IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 20; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 5 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + +// hx3695_write_reg(0X4e, thred_value); +// hx3695_write_reg(0X4f, thred_value>>5); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel)); //<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92); // bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release +// read_fifo_first_flg = 1; + return ; +} + +void hx3695_factory_ft_int_test_config(void)//中断测试配置 +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t adc_rst_post_num=0; /* 00=16,01=32,10=64,11=128*/ + uint8_t samp_delay_leden_num = 0; /* 00=8,01=16,10=32,11=64*/ + uint8_t samp_copy_avg = 0; /* 0=1, 1=2, 2=4 ,3=8, 4=16*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase7_8_internal = 0; /* phase7 and phase8 prf internal cfg */ + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase5_enable = 0; /*phase5_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase6_enable = 0; /*phase6_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase7_enable = 0; /*phase7_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase8_enable = 0; /*phase8_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase5_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase6_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase7_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase8_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; /* sel phase5*/ + uint8_t phase6_mux_sel = 5; /* sel phase6*/ + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + + uint8_t phase1_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase1_tia_res = 3; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase1_led_drv1_cha_sel = 0; /* 1 = ldr1 NG; 2 = ldr2 GR; 4 = ldr3 IR; 8 = ldr4 RED; */ + uint8_t phase1_led_drv2_cha_sel = 0; /*ldr5:0x20 ldr6: 0x40 red ldr8 0x80 ir */ + uint8_t phase1_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase1_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase1_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase1_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase1_ldr2_cur = 0; +// uint8_t phase1_of_idac1_cur = 0; +// uint8_t phase1_of_idac2_cur = 0; + uint8_t phase1_ad_inr_ctrl = 3; + uint8_t phase1_ad_of_idac_ctrl = 0; +// uint8_t afe_offset = 0; + uint8_t phase1_led_en = 1; /* phase1 led enable*/ + + uint8_t phase1_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase1_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + + uint8_t phase2_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase2_tia_res = 3; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase2_led_drv1_cha_sel = GREEN_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase2_led_drv2_cha_sel = 0; + uint8_t phase2_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase2_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase2_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase2_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase2_ldr2_cur = 0; +// uint8_t phase2_of_idac1_cur = 0; +// uint8_t phase2_of_idac2_cur = 0; + uint8_t phase2_ad_inr_ctrl = 3; + uint8_t phase2_ad_of_idac_ctrl = 0; +// uint8_t phase2_afe_offset = 0; + uint8_t phase2_led_en = 1; /* phase1 led enable*/ + + uint8_t phase2_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase2_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase3_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase3_tia_res = 3; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase3_led_drv1_cha_sel = RED_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase3_led_drv2_cha_sel = 0; + uint8_t phase3_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase3_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase3_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase3_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase3_ldr2_cur = 0; +// uint8_t phase3_of_idac1_cur = 0; +// uint8_t phase3_of_idac2_cur = 0; + uint8_t phase3_ad_inr_ctrl = 3; + uint8_t phase3_ad_of_idac_ctrl = 0; +// uint8_t phase3_afe_offset = 0; + uint8_t phase3_led_en = 1; /* phase1 led enable*/ + + uint8_t phase3_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase3_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + + uint8_t phase4_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase4_tia_res = 3; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase4_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase4_led_drv1_cha_sel = IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase4_led_drv2_cha_sel = 0; + uint8_t phase4_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; 4 = pd3*/ + uint8_t phase4_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase4_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase4_ldr1_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase4_ldr2_cur = 0; +// uint8_t phase4_of_idac1_cur = 0; +// uint8_t phase4_of_idac2_cur = 0; + uint8_t phase4_ad_inr_ctrl = 3; + uint8_t phase4_ad_of_idac_ctrl = 0; +// uint8_t phase4_afe_offset = 0; + uint8_t phase4_led_en = 1; /* phase1 led enable*/ + + uint8_t phase4_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase4_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase5_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase5_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase5_led_drv2_cha_sel = 0; + uint8_t phase5_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase5_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase5_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase5_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase5_ldr2_cur = 0; +// uint8_t phase5_of_idac1_cur = 0; +// uint8_t phase5_of_idac2_cur = 0; + uint8_t phase5_ad_inr_ctrl = 3; + uint8_t phase5_ad_of_idac_ctrl = 0; +// uint8_t phase5_afe_offset = 0; + uint8_t phase5_led_en = 1; /* phase1 led enable*/ + + uint8_t phase5_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase5_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase6_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase6_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase6_led_drv2_cha_sel = 0; + uint8_t phase6_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase6_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase6_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase6_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase6_ldr2_cur = 0; +// uint8_t phase6_of_idac1_cur = 0; +// uint8_t phase6_of_idac2_cur = 0; + uint8_t phase6_ad_inr_ctrl = 3; + uint8_t phase6_ad_of_idac_ctrl = 0; +// uint8_t phase6_afe_offset = 0; + uint8_t phase6_led_en = 1; /* phase1 led enable*/ + + uint8_t phase6_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase6_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase7_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase7_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase7_led_drv1_cha_sel = 0; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase7_led_drv2_cha_sel = 0; + uint8_t phase7_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase7_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase7_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase7_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase7_ldr2_cur = 0; +// uint8_t phase7_of_idac1_cur = 0; +// uint8_t phase7_of_idac2_cur = 0; + uint8_t phase7_ad_inr_ctrl = 3; + uint8_t phase7_ad_of_idac_ctrl = 0; +// uint8_t phase7_afe_offset = 0; + uint8_t phase7_led_en = 1; /* phase1 led enable*/ + + uint8_t phase7_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase7_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t phase8_inner_avg = 0; /* phase1 adc avg num 0=1, 1=2, 2=4, 3=8 , 4=16*/ + uint8_t phase8_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase8_tia_cap = 4; /* 0= ; 1= ; 2= ; 3= ; 4= ; 5= ; 6= ; 7= */ + uint8_t phase8_led_drv1_cha_sel = 0; //IR_LED_SLE; /* 1 = ldr1; 2 = ldr2; 4 = ldr3; 8 = ldr4 ; */ + uint8_t phase8_led_drv2_cha_sel = 0; + uint8_t phase8_pd_sel = 0x0c; /* 1 = pd1; 2 = pd2; */ + uint8_t phase8_als_offset_idac = 0; /* 0~255 = 0 ~ 128ua , step = 0.5ua */ + uint8_t phase8_led_offset_idac = 0; /* 0~255 = 0 ~ 64ua , step = 0.25ua */ + uint8_t phase8_ldr1_cur = 0; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + uint8_t phase8_ldr2_cur = 0; +// uint8_t phase8_of_idac1_cur = 0; +// uint8_t phase8_of_idac2_cur = 0; + uint8_t phase8_ad_inr_ctrl = 3; + uint8_t phase8_ad_of_idac_ctrl = 0; +// uint8_t phase8_afe_offset = 0; + uint8_t phase8_led_en = 1; /* phase1 led enable*/ + + uint8_t phase8_dsp_mov_avg_num = 0; /* 0=bypass ; 1=2 ; 2=4 ; 3=8 */ + uint8_t phase8_dsp_iir_lp_coeff = 0; /* 0=bypass ; 1=1/2 ; 2=1/4 ; 3=1/8 ,...,7=1/128 */ + + uint8_t init_wait_delay = 5 ; /* 0 = 31clk ; 1 = 64clk ; 2 = 127clk ; 3 = 255clk(d) ; + 4 = 511clk; 5 = 1023clk; 6 = 2047; 7 = 4095clk */ + + uint8_t afe_reset = 3; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d) ; + 4 = 255clk; 5 = 511clk; 6 = 1024; 7 = 2047clk */ + + uint8_t afe_rst_cnvt = 1; /* 0 = 15clk ; 1 = 31clk ; 2 = 63clk ; 3 = 127clk(d)*/ + + uint8_t led_en_idac_pre = 2; /* 0 = 8clk ; 1 = 16clk ; 2 = 32clk ; 3 = 64clk(d)*/ + + uint8_t led_en_idac = 1; /* 0 = 4clk ; 1 = 8clk ; 2 = 16clk ; 3 = 32clk(d)*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_delay_ms(10); + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0>6 + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X25, (afe_rst_cnvt<<4| led_en_idac_pre<<2|led_en_idac)); + hx3695_write_reg(0X2d, phase7_8_internal); + hx3695_write_reg(0X2e, 0x33);// gpio ctrl + hx3695_write_reg(0X2f, ((afe_reset<<4)| init_wait_delay)); + hx3695_write_reg(0X30, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + hx3695_write_reg(0X72, (phase8_led_en<<7 | phase7_led_en<<6 |phase6_led_en<<5 |phase5_led_en<<4 |phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + hx3695_write_reg(0X33, 0x83);// 中断极性及宽度配置; + hx3695_write_reg(0X34, 0x00);// 中断特殊配置; + hx3695_write_reg(0X36, 0x00);// phase data ready 标志设置; + hx3695_write_reg(0X38, 0x00); + + hx3695_write_reg(0X3a, (phase1_inner_avg | (phase2_inner_avg<<4))); + hx3695_write_reg(0X3b, (phase3_inner_avg | (phase4_inner_avg<<4))); + hx3695_write_reg(0X3c, (phase5_inner_avg | (phase6_inner_avg<<4))); + hx3695_write_reg(0X3d, (phase7_inner_avg | (phase8_inner_avg<<4))); + hx3695_write_reg(0X3e, adc_rst_post_num<<6 | samp_delay_leden_num<<4 | samp_copy_avg); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, phase1_tia_cap<<4|phase1_tia_res); + hx3695_write_reg(0X45, phase1_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase1_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase1_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase1_als_offset_idac); + hx3695_write_reg(0X48, phase1_led_offset_idac); + + hx3695_write_reg(0X49, phase1_ad_inr_ctrl<<4|phase1_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase1_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase1_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase1_dsp_mov_avg_num | phase1_dsp_iir_lp_coeff<<4); + +// hx3695_write_reg(0X4e, thred_value); +// hx3695_write_reg(0X4f, thred_value>>5); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, phase2_tia_cap<<4|phase2_tia_res); + hx3695_write_reg(0X45, phase2_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase2_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase2_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase2_als_offset_idac); + hx3695_write_reg(0X48, phase2_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase2_ad_inr_ctrl<<4|phase2_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase2_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase2_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase2_dsp_mov_avg_num | phase2_dsp_iir_lp_coeff<<4); + +//phase3 sel + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, phase3_tia_cap<<4|phase3_tia_res); + hx3695_write_reg(0X45, phase3_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase3_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase3_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase3_als_offset_idac); + hx3695_write_reg(0X48, phase3_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase3_ad_inr_ctrl<<4|phase3_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase3_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase3_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase3_dsp_mov_avg_num | phase3_dsp_iir_lp_coeff<<4); + +//phase4 sel + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, phase4_tia_cap<<4|phase4_tia_res); + hx3695_write_reg(0X45, phase4_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase4_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase4_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase4_als_offset_idac); + hx3695_write_reg(0X48, phase4_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase4_ad_inr_ctrl<<4|phase4_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase4_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase4_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase4_dsp_mov_avg_num | phase4_dsp_iir_lp_coeff<<4); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, phase5_tia_cap<<4|phase5_tia_res); + hx3695_write_reg(0X45, phase5_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase5_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase5_pd_sel)); //<<4 | 0x00)); + hx3695_write_reg(0X47, phase5_als_offset_idac); + hx3695_write_reg(0X48, phase5_led_offset_idac); +// hx3695_write_reg(0X48, phase1_led_offset_idac); + hx3695_write_reg(0X49, phase5_ad_inr_ctrl<<4|phase5_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase5_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase5_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase5_dsp_mov_avg_num | phase5_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, phase6_tia_cap<<4|phase6_tia_res); + hx3695_write_reg(0X45, phase6_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase6_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase6_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase6_als_offset_idac); + hx3695_write_reg(0X48, phase6_led_offset_idac); +// hx3695_write_reg(0X48, phase6_led_offset_idac); + hx3695_write_reg(0X49, phase6_ad_inr_ctrl<<4|phase6_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase6_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase6_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase6_dsp_mov_avg_num | phase6_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, phase7_tia_cap<<4|phase7_tia_res); + hx3695_write_reg(0X45, phase7_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase7_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase7_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase7_als_offset_idac); + hx3695_write_reg(0X48, phase7_led_offset_idac); +// hx3695_write_reg(0X48, phase7_led_offset_idac); + hx3695_write_reg(0X49, phase7_ad_inr_ctrl<<4|phase7_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase7_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase7_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase7_dsp_mov_avg_num | phase7_dsp_iir_lp_coeff<<4); + + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, phase8_tia_cap<<4|phase8_tia_res); + hx3695_write_reg(0X45, phase8_ldr1_cur); //LED_DRV1_CUR + hx3695_write_reg(0x70, phase8_ldr2_cur); //ps8--ps1 led_drv2_cur + hx3695_write_reg(0X46, (phase8_pd_sel<<4 | 0x00)); + hx3695_write_reg(0X47, phase8_als_offset_idac); + hx3695_write_reg(0X48, phase8_led_offset_idac); +// hx3695_write_reg(0X48, phas8_led_offset_idac); + hx3695_write_reg(0X49, phase8_ad_inr_ctrl<<4|phase8_ad_of_idac_ctrl); + hx3695_write_reg(0X4a, phase8_led_drv1_cha_sel); + hx3695_write_reg(0X4b, phase8_led_drv2_cha_sel); + hx3695_write_reg(0X71, phase8_dsp_mov_avg_num | phase8_dsp_iir_lp_coeff<<4); + + +// analog circuit cfg + hx3695_write_reg(0X60, 0x14); // + hx3695_write_reg(0X61, 0xf0); + hx3695_write_reg(0X62, 0x22); + hx3695_write_reg(0X63, 0x15); + + hx3695_write_reg(0X64, 0x08); + hx3695_write_reg(0X65, 0x88); //bug + + hx3695_write_reg(0X66, 0x30); // bits<3>=adc selftest en 0x30 + hx3695_write_reg(0X67, 0x23); + hx3695_write_reg(0X68, 0x46); + hx3695_write_reg(0X69, 0x42); + + hx3695_write_reg(0X39, 0xff); // ofset idac1 phase enable cfg + hx3695_write_reg(0x73, 0xff); //led_offset_idac phase enable + + hx3695_write_reg(0X6a, 0X0f); + hx3695_write_reg(0X6b, 0X22); + hx3695_write_reg(0X6c, 0X00); + hx3695_write_reg(0X6d, 0X37); + hx3695_write_reg(0X6e, 0X82); + hx3695_write_reg(0X6f, 0X08); +/////////FIFO and adc conversion ready config//////// +/////////FIFO and adc conversion ready config//////// +#if defined(PPG_INT_MODE) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int +#elif defined(INT_MODE) //FIFO_ALL_MOST_FULL) + hx3695_write_reg(0X1b, 0x92);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X1c, (fifo_watermark&0xff)); //fifo_watermark + hx3695_write_reg(0X1d, fifo_watermark<<8); //bit<0>=fifo_watermark[8] + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x04); // int sel,00=close almost full int,04=enable almost full int + +#else + hx3695_write_reg(0X1b, 0x92); // bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X38, 0x01); // int sel,00=close almost full int,04=enable almost full int + +#endif + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + hx3695_write_reg(0X28,(phase5_enable<<3)|(phase5_adc_osr)|(phase6_enable<<7)|(phase6_adc_osr<<4) ); + hx3695_write_reg(0X29,(phase7_enable<<3)|(phase7_adc_osr)|(phase8_enable<<7)|(phase8_adc_osr<<4) ); + +// hx3695_write_reg(0X5c, 0x02);//soft reset + hx3695_delay_ms(5); + hx3695_write_reg(0X5c, 0x00);//release + + +} + +bool hx3695_factory_test_read(int32_t *phase_data) +{ + uint8_t databuf[12] = {0}; + int32_t P1 = 0, P2 = 0,P3 = 0,P4 = 0; + hx3695_brust_read_reg(0x03, databuf, 12); + P1 = ((databuf[0])|(databuf[1]<<8)|(databuf[2]<<16)); + P2 = ((databuf[3])|(databuf[4]<<8)|(databuf[5]<<16)); + P3 = ((databuf[6])|(databuf[7]<<8)|(databuf[8]<<16)); + P4 = ((databuf[9])|(databuf[10]<<8)|(databuf[11]<<16)); + + phase_data[0] = P1 ; + phase_data[1] = P2 ; + phase_data[2] = P3 ; + phase_data[3] = P4 ; + + DEBUG_PRINTF("p1,p2,p3,p4 %d %d %d %d\r\n", P1, P2, P3, P4); + return true; +} + +int32_t hx3695_sort_cal(int32_t *data) +{ + uint8_t ii,jj; + int32_t data_temp = 0; + int32_t data_final = 0; + for(ii=0; ii<3; ii++) + { + for(jj=0; jj<3-ii; jj++) + { + if(data[jj]>=data[jj+1]) + { + data_temp = data[jj]; + data[jj] = data[jj+1]; + data[jj+1] = data_temp; + } + } + } + data_final = (data[1]+data[2])>>1; + return data_final; +} + + +bool hx3695_chip_check_id(void) +{ + uint8_t i = 0; + uint8_t chip_id =0; + for(i=0; i<10; i++) + { + chip_id = hx3695_read_reg(0x00); + TYHX_LOG("chip id = 0x%x\r\n",chip_id); + if (chip_id == 0x65) + { + return true; + } + } + return false; +} + +FT_RESULTS_t hx3695_factory_led_off_get_result(void) +{ + uint8_t ii = 0; + int32_t phase_data[4] = {0,0,0,0}; + int32_t phase1_data[4] = {0,0,0,0}; + int32_t phase2_data[4] = {0,0,0,0}; + int32_t phase3_data[4] = {0,0,0,0}; + int32_t phase4_data[4] = {0,0,0,0}; + int32_t gr_buffer[4] = {0,0,0,0}; + int32_t red_buffer[4] = {0,0,0,0}; + int32_t ir_buffer[4] = {0,0,0,0}; + FT_RESULTS_t ft_result = {0,0,0,0,0,0,0,0,0,0,0,0}; + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(40); + hx3695_factory_test_read(phase_data); + gr_buffer[ii] = phase_data[1] - phase_data[0]; + red_buffer[ii] = phase_data[2] - phase_data[0]; + ir_buffer[ii] = phase_data[3] - phase_data[0]; + phase1_data[ii] = phase_data[0]; + phase2_data[ii] = phase_data[1]; + phase3_data[ii] = phase_data[2]; + phase4_data[ii] = phase_data[3]; + } + ft_result.phase1_data_avg = hx3695_sort_cal(phase1_data); + ft_result.phase2_data_avg = hx3695_sort_cal(phase2_data); + ft_result.phase3_data_avg = hx3695_sort_cal(phase3_data); + ft_result.phase4_data_avg = hx3695_sort_cal(phase4_data); + ft_result.gr_ps_dif = hx3695_sort_cal(gr_buffer); + ft_result.red_ps_dif = hx3695_sort_cal(red_buffer); + ft_result.ir_ps_dif = hx3695_sort_cal(ir_buffer); + + return ft_result; +} + +FT_RESULTS_t hx3695_factory_wear_mode_get_result(void) +{ + uint8_t ii = 0; + int32_t phase_data[4] = {0,0,0,0}; + int32_t data_buffer[4] = {0,0,0,0}; + FT_RESULTS_t ft_result = {0,0,0,0,0,0,0,0,0,0,0,0}; + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(110); + hx3695_factory_test_read(phase_data); + data_buffer[ii] = phase_data[0] - phase_data[1]; + } + ft_result.gr_data_final = hx3695_sort_cal(data_buffer); + if(data_buffer[0]==data_buffer[1] && data_buffer[0]==data_buffer[2] && data_buffer[0]==data_buffer[3]) + { + ft_result.gr_data_final = 0; + } + + return ft_result; +} + +FT_RESULTS_t hx3695_factory_ft_leak_light_test_get_result(void) +{ + uint8_t ii = 0; + int32_t phase_data[4] = {0,0,0,0}; + int32_t gr_buffer[4] = {0,0,0,0}; + int32_t red_buffer[4] = {0,0,0,0}; + int32_t ir_buffer[4] = {0,0,0,0}; + int32_t gr_data_ledoff = 0; + int32_t red_data_ledoff = 0; + int32_t ir_data_ledoff = 0; + int32_t gr_data_ledon = 0; + int32_t red_data_ledon = 0; + int32_t ir_data_ledon = 0; + FT_RESULTS_t ft_result = {0,0,0,0,0,0,0,0,0,0,0,0}; + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(40); + hx3695_factory_test_read(phase_data); + gr_buffer[ii] = phase_data[1] - phase_data[0]; + red_buffer[ii] = phase_data[2] - phase_data[0]; + ir_buffer[ii] = phase_data[3] - phase_data[0]; + } + gr_data_ledon = hx3695_sort_cal(gr_buffer); + red_data_ledon = hx3695_sort_cal(red_buffer); + ir_data_ledon = hx3695_sort_cal(ir_buffer); + + hx3695_write_reg(0x30, 0x00); + hx3695_write_reg(0x72, 0x00); + hx3695_delay_ms(100); + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(40); + hx3695_factory_test_read(phase_data); + gr_buffer[ii] = phase_data[1] - phase_data[0]; + red_buffer[ii] = phase_data[2] - phase_data[0]; + ir_buffer[ii] = phase_data[3] - phase_data[0]; + } + gr_data_ledoff = hx3695_sort_cal(gr_buffer); + red_data_ledoff = hx3695_sort_cal(red_buffer); + ir_data_ledoff = hx3695_sort_cal(ir_buffer); + + ft_result.gr_ps_dif = gr_data_ledoff; + ft_result.red_ps_dif = red_data_ledoff; + ft_result.ir_ps_dif = ir_data_ledoff; + ft_result.gr_data_final = gr_data_ledon - gr_data_ledoff; + ft_result.red_data_final = red_data_ledon - red_data_ledoff; + ft_result.ir_data_final = ir_data_ledon - ir_data_ledoff; + if(ft_result.gr_data_final<0) + { + ft_result.gr_data_final = 0; + } + if(ft_result.red_data_final<0) + { + ft_result.red_data_final = 0; + } + if(ft_result.ir_data_final<0) + { + ft_result.ir_data_final = 0; + } + //TYHX_LOG("leaking result=%d\r\n",ft_result.gr_data_final ); + //hrsresult.leak_green =ft_result.gr_data_final; + + + + return ft_result; +} + +FT_RESULTS_t hx3695_factory_ft_card_test_get_result(void) +{ + uint8_t ii = 0; + int32_t phase_data[4] = {0,0,0,0}; + int32_t gr_buffer[4] = {0,0,0,0}; + int32_t red_buffer[4] = {0,0,0,0}; + int32_t ir_buffer[4] = {0,0,0,0}; + FT_RESULTS_t ft_result = {0,0,0,0,0,0,0,0,0,0,0,0}; + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(40); + hx3695_factory_test_read(phase_data); + gr_buffer[ii] = phase_data[1] - phase_data[0]; + red_buffer[ii] = phase_data[2] - phase_data[0]; + ir_buffer[ii] = phase_data[3] - phase_data[0]; + } + ft_result.gr_data_final = hx3695_sort_cal(gr_buffer); + ft_result.red_data_final = hx3695_sort_cal(red_buffer); + ft_result.ir_data_final = hx3695_sort_cal(ir_buffer); + DEBUG_PRINTF("ft card,g%d,r%d,ir%d\r\n",ft_result.gr_data_final,ft_result.red_data_final,ft_result.ir_data_final ); + + if(gr_buffer[0] == gr_buffer[1] && gr_buffer[0] == gr_buffer[2] && gr_buffer[0] == gr_buffer[3]) + { + ft_result.gr_data_final = 0; + ft_result.red_data_final = 0; + ft_result.ir_data_final = 0; + } + if(ft_result.gr_data_final < 0) + { + ft_result.gr_data_final = 0; + } + if(ft_result.red_data_final < 0) + { + ft_result.red_data_final = 0; + } + if(ft_result.ir_data_final < 0) + { + ft_result.ir_data_final = 0; + } + + return ft_result; +} + +FT_RESULTS_t hx3695_factory_ft_single_check_get_result(void) +{ + uint8_t ii = 0; + int32_t phase_data[4] = {0,0,0,0}; + int32_t gr_buffer[4] = {0,0,0,0}; + int32_t red_buffer[4] = {0,0,0,0}; + int32_t ir_buffer[4] = {0,0,0,0}; + FT_RESULTS_t ft_result = {0,0,0,0,0,0,0,0,0,0,0,0}; + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(12); + hx3695_factory_test_read(phase_data); + gr_buffer[ii] = phase_data[1] - phase_data[0]; + red_buffer[ii] = phase_data[2] - phase_data[0]; + ir_buffer[ii] = phase_data[3] - phase_data[0]; + } + ft_result.gr_data_final = hx3695_sort_cal(gr_buffer); + ft_result.red_data_final = hx3695_sort_cal(red_buffer); + ft_result.ir_data_final = hx3695_sort_cal(ir_buffer); + + hx3695_write_reg(0x33, 0xff); + hx3695_delay_ms(10); + + for(ii=0; ii<4; ii++) + { + hx3695_delay_ms(12); + hx3695_factory_test_read(phase_data); + gr_buffer[ii] = phase_data[1] - phase_data[0]; + red_buffer[ii] = phase_data[2] - phase_data[0]; + ir_buffer[ii] = phase_data[3] - phase_data[0]; + } + ft_result.gr_data_high = hx3695_sort_cal(gr_buffer); + + if(gr_buffer[0] == gr_buffer[1] && gr_buffer[0] == gr_buffer[2] && gr_buffer[0] == gr_buffer[3]) + { + ft_result.gr_data_final = 0; + ft_result.red_data_final = 0; + ft_result.ir_data_final = 0; + } + if(ft_result.gr_data_final < 0) + { + ft_result.gr_data_final = 0; + } + if(ft_result.red_data_final < 0) + { + ft_result.red_data_final = 0; + } + if(ft_result.ir_data_final < 0) + { + ft_result.ir_data_final = 0; + } + if(ft_result.gr_data_final > 0) + { + ft_result.single_gr_led_judge = ft_result.gr_data_high*100/ft_result.gr_data_final; + } + + return ft_result; +} + +FT_RESULTS_t hx3695_factroy_test(TEST_MODE_t test_mode) +{ + FT_RESULTS_t ft_result = {0,0,0,0,0,0,0,0,0,0,0,0}; + + //if (hx3695_chip_check_id() == false) + { + // return ft_result; + } + switch(test_mode) + { + case LED_OFF_TEST: + hx3695_factory_led_off_config(); + hx3695_delay_ms(50); + ft_result = hx3695_factory_led_off_get_result(); + break; + case WEAR_MODE_TEST: + hx3695_factory_wear_mode_config(); + hx3695_delay_ms(50); + ft_result = hx3695_factory_wear_mode_get_result(); + break; + case LEAK_LIGHT_TEST: + hx3695_factory_ft_leak_light_test_config(); + hx3695_delay_ms(50); + ft_result = hx3695_factory_ft_leak_light_test_get_result(); + hrsresult.leak_green = ft_result.gr_data_final; + hrsresult.leak_red = ft_result.red_data_final; + hrsresult.leak_ir = ft_result.ir_data_final; + TYHX_LOG("leak g=%d\r\n",hrsresult.leak_green); + break; + case GRAY_CARD_TEST: + hx3695_factory_ft_card_test_config(); + hx3695_delay_ms(50); + ft_result = hx3695_factory_ft_card_test_get_result(); + hrsresult.card_green = ft_result.gr_data_final; + hrsresult.card_red = ft_result.red_data_final; + hrsresult.card_ir = ft_result.ir_data_final; + break; + case FT_INT_TEST: + hx3695_factory_ft_int_test_config(); + break; + case SINGLE_CHECK_TEST: + hx3695_factory_ft_single_check_config(); + hx3695_delay_ms(50); + ft_result = hx3695_factory_ft_single_check_get_result(); + break; + default: + break; + } + + //hx3695_ppg_off(); + DEBUG_PRINTF("%d %d %d %d %d %d %d %d %d %d %d %d\r\n", ft_result.phase1_data_avg, ft_result.phase2_data_avg, ft_result.phase3_data_avg, ft_result.phase4_data_avg, \ + ft_result.gr_ps_dif, ft_result.red_ps_dif, ft_result.ir_ps_dif, ft_result.gr_data_final, ft_result.red_data_final, ft_result.ir_data_final, ft_result.gr_data_high, \ + ft_result.single_gr_led_judge); + + return ft_result; +} diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_factory_test.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_factory_test.h new file mode 100644 index 000000000..7abd190f5 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_factory_test.h @@ -0,0 +1,46 @@ +#ifndef _HX3695_FACTORY_TEST_H_ +#define _HX3695_FACTORY_TEST_H_ + +#include +#include + +typedef enum { + LEAK_LIGHT_TEST = 1, + GRAY_CARD_TEST = 2, + FT_INT_TEST = 3, + SINGLE_CHECK_TEST = 4, + LED_OFF_TEST = 5, + WEAR_MODE_TEST = 6 +} TEST_MODE_t; + +typedef struct { + int32_t phase1_data_avg; + int32_t phase2_data_avg; + int32_t phase3_data_avg; + int32_t phase4_data_avg; + int32_t gr_ps_dif; + int32_t red_ps_dif; + int32_t ir_ps_dif; + int32_t gr_data_final; + int32_t red_data_final; + int32_t ir_data_final; + int32_t gr_data_high; + int32_t single_gr_led_judge; +} FT_RESULTS_t; + +void hx3695_factory_ft_leak_light_test_config(void); +void hx3695_factory_ft_card_test_config(void); +void hx3695_factory_ft_int_test_config(void); + +bool hx3695_factory_test_read(int32_t *phase_data); +FT_RESULTS_t hx3695_factroy_test(TEST_MODE_t test_mode); + +void hx3695_lab_test(uint32_t test_mode); +void hx3695_lab_test_read(void); + + +#endif // _HX3695_FACTORY_TEST_H_ + + + + diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_agc.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_agc.c new file mode 100644 index 000000000..7ea0bc334 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_agc.c @@ -0,0 +1,971 @@ + +#include +#include +#include +#include +#include + +#include "tyhx_hrs_custom.h" + +#include "hx3695.h" +#include "hx3695_hrs_agc.h" +#include "tyhx_hrs_alg.h" + + +#ifdef HRS_ALG_LIB +extern const uint8_t hx3695_hrs_agc_idac; +extern uint8_t hx3695_hrs_g1_agc_idac; +extern uint8_t hx3695_hrs_g2_agc_idac; +extern uint8_t hx3695_hrs_g3_agc_idac; + +extern const uint8_t green_led_max_init; +extern uint8_t low_vbat_flag; +extern uint8_t hrs_phase_num; +extern uint8_t read_fifo_first_flg; + + +//HRS_INFRARED_THRES +extern const int32_t hrs_ir_unwear_thres; +extern const int32_t hrs_ir_wear_thres; + +static uint8_t s_ppg_state = 0; +static uint8_t hrs_cal_state = 0; + +static int32_t s_buf[64] = {0}; +static int32_t agc_buf[8] = {0}; +static uint8_t fifo_data_temp[3] = {0}; + +static uint8_t cal_delay = CAL_DELAY_COUNT; +static HRS_CAL_SET_T calReg_Hrs;; +// +static hrs_wear_msg_code_t hrs_wear_status = MSG_HRS_NO_WEAR; +static hrs_wear_msg_code_t hrs_wear_status_pre = MSG_HRS_NO_WEAR; + +static uint8_t no_touch_cnt = 0; + +void Init_hrs_PPG_Calibration_Routine(HRS_CAL_SET_T *calR) +{ + calR->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + calR->Group1_Ledidac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->Group2_Ledidac = 0; +// calR->Group3_Ledidac = 0; + + calR->Group1_AMBDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->Group2_AMBDAC = 0; +// calR->Group3_AMBDAC = 0; + + + calR->Group1_RF = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + calR->Group2_RF = 0; +// calR->Group3_RF = 0; + + calR->Group1_Cur = HRS_CAL_INIT_LED; + calR->Group2_Cur = HRS_CAL_INIT_LED; +// calR->Group3_Cur = HRS_CAL_INIT_LED; + + + calR->state = hrsCalStart; + calR->int_cnt = 0; + calR->cur255_cnt =0; + if(low_vbat_flag==1) + { +// calR->led_max_cur = 128; + calR->Group1_max_cur = 128; + calR->Group2_max_cur = 128; +// calR->Group3_max_cur = 128; + } + else + { + calR->Group1_max_cur = green_led_max_init; + calR->Group2_max_cur = green_led_max_init; +// calR->Group3_max_cur = green_led_max_init; + + } +} + +void Restart_hrs_PPG_Calibration_Routine(HRS_CAL_SET_T *calR) +{ + calR->flag = CAL_FLG_LED_DAC; + calR->state = hrsCalLed; + calR->int_cnt = 0; +} + +hrs_wear_msg_code_t hx3695_hrs_wear_mode_check(WORK_MODE_T mode, int32_t infrared_data) +{ + if(infrared_data > hrs_ir_wear_thres) + { + if(no_touch_cnt < NO_TOUCH_CHECK_NUM) + { + no_touch_cnt++; + } + if(no_touch_cnt >= NO_TOUCH_CHECK_NUM) + { + hrs_wear_status = MSG_HRS_WEAR; + } + } + else if(infrared_data < hrs_ir_unwear_thres) + { + if(no_touch_cnt>0) + { + no_touch_cnt--; + } + if(no_touch_cnt == 0) + { + hrs_wear_status = MSG_HRS_NO_WEAR; + } + } +// AGC_LOG("hrs ir_data: %d, hrs_wear_status_pre=%d, hrs_wear_status=%d\r\n", + // infrared_data,hrs_wear_status_pre,hrs_wear_status); + if(mode == WEAR_MODE) + { + return hrs_wear_status; + } + if(hrs_wear_status_pre != hrs_wear_status) + { + hrs_wear_status_pre = hrs_wear_status; + if(hrs_wear_status_pre == MSG_HRS_NO_WEAR) + { + AGC_LOG("run here_low_pow!! \r\n"); + hx3695_hrs_low_power(); + + + } + else if(hrs_wear_status_pre == MSG_HRS_WEAR) + { + tyhx_hrs_alg_open_deep(); + hx3695_hrs_set_mode(PPG_INIT); + hx3695_hrs_set_mode(CAL_INIT); + } + } + return hrs_wear_status; +} + + + + +//void PPG_hrs_Calibration_Routine(HRS_CAL_SET_T *calR, int32_t g1_led,int32_t g2_led,int32_t g3_led, int32_t g1_amb, int32_t g2_amb,int32_t g3_amb) +void PPG_hrs_Calibration_Routine(HRS_CAL_SET_T *calR, int32_t g1_led,int32_t g2_led, int32_t g1_amb, int32_t g2_amb) + +{ + switch(calR->state) + { + case hrsCalStart: + calR->state = hrsCalStart1; + break; + + case hrsCalStart1: + if(g1_amb>525000) + { + calR->Group1_AMBDAC = (g1_amb-525000)/1300; + } + else + { + calR->Group1_AMBDAC = 0; + } + + if(g2_amb > 525000) + { + calR->Group2_AMBDAC = (g2_amb - 525000)/1300; + } + else + { + calR->Group2_AMBDAC = 0; + } +// if(g3_amb>525000) +// { +// calR->Group3_AMBDAC = (g3_amb-525000)/1300; +// } +// else +// { +// calR->Group3_AMBDAC = 0; +// } + + if(g1_led > g1_amb+256) + { + calR->Group1_step = (g1_led - g1_amb)/(HRS_CAL_INIT_LED); + calR->Group1_Cur = 1300*(hx3695_hrs_g1_agc_idac + calR->Group1_AMBDAC)/(calR->Group1_step); + AGC_LOG("AGC1: calR->Group1_Cur = %d,\r\n",calR->Group1_Cur); + + if(calR->Group1_Cur > calR->Group1_max_cur) + { + calR->Group1_Cur = calR->Group1_max_cur; + } + if(calR->Group1_Cur != calR->Group1_max_cur) + { + calR->Group1_Ledidac = (hx3695_hrs_g1_agc_idac*3)>>2; + } + else + { + calR->Group1_Ledidac = hx3695_hrs_g1_agc_idac>>1; + } + } + + if(g2_led > g2_amb+256) + { + calR->Group2_step = (g2_led - g2_amb)/(HRS_CAL_INIT_LED); + calR->Group2_Cur = 1300*(hx3695_hrs_g2_agc_idac + calR->Group2_AMBDAC)/(calR->Group2_step); + AGC_LOG("AGC2: calR->Group2_Cur = %d,\r\n",calR->Group2_Cur); + + if(calR->Group2_Cur > calR->Group2_max_cur) + { + calR->Group2_Cur = calR->Group2_max_cur; + } + if(calR->Group2_Cur != calR->Group2_max_cur) + { + calR->Group2_Ledidac = (hx3695_hrs_g2_agc_idac*3)>>2; + } + else + { + calR->Group2_Ledidac = hx3695_hrs_g2_agc_idac>>1; + } + } + + +// if(g3_led > g3_amb+256) +// { +// calR->Group3_step = (g3_led - g3_amb)/(HRS_CAL_INIT_LED); +// calR->Group3_Cur = 1300*(hx3695_hrs_g3_agc_idac + calR->Group3_AMBDAC)/(calR->Group3_step); +// AGC_LOG("AGC3: calR->Group3_Cur = %d,\r\n",calR->Group3_Cur); + +// if(calR->Group3_Cur > calR->Group3_max_cur) +// { +// calR->Group3_Cur = calR->Group3_max_cur; +// } +// if(calR->Group3_Cur != calR->Group3_max_cur) +// { +// calR->Group3_Ledidac = (hx3695_hrs_g3_agc_idac*3)>>2; +// } +// else +// { +// calR->Group3_Ledidac = hx3695_hrs_g3_agc_idac>>1; +// } +// } + + calR->Group1_RF = 5; + calR->Group2_RF = 5; +// calR->Group3_RF = 6; + + calR->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + calR->state = hrsCalLed; + + break; + + case hrsCalLed: + + if(g1_led>900000 && calR->Group1_Ledidac<= 55) + { + calR->Group1_Ledidac = calR->Group1_Ledidac + 6; + } + if(g2_led>900000 && calR->Group2_Ledidac<= 55) + { + calR->Group2_Ledidac = calR->Group2_Ledidac + 6; + } +// if(g3_led>900000 && calR->Group3_Ledidac<= 55) +// { +// calR->Group3_Ledidac = calR->Group3_Ledidac + 6; +// } + + if(g1_led < 900000 && g2_led < 900000) + { + calR->state = hrsCalLed2; + } + else if(calR->Group1_Ledidac >120 || calR->Group2_Ledidac > 120) + { + calR->state = hrsCalLed3; + } + else + { + calR->state = hrsCalLed; + } + calR->flag = CAL_FLG_LED_DAC; + break; + + case hrsCalLed2: + + if(g1_led>650000 && calR->Group1_Ledidac<=120) + { + calR->Group1_Ledidac = calR->Group1_Ledidac + 3; + } + else if(g1_led < 400000 && calR->Group1_Ledidac >= 3) + { + calR->Group1_Ledidac = calR->Group1_Ledidac - 3; + } + else if(g1_led < 400000 && calR->Group1_Ledidac>0) + { + calR->Group1_Ledidac = calR->Group1_Ledidac - 1; + + } + + if(g2_led>650000 && calR->Group2_Ledidac<=120) + { + calR->Group2_Ledidac = calR->Group2_Ledidac + 3; + + } + if(g2_led<400000 && calR->Group2_Ledidac >= 3) + { + calR->Group2_Ledidac = calR->Group2_Ledidac - 3; + + } + if(g2_led < 400000 && calR->Group2_Ledidac>0) + { + calR->Group2_Ledidac = calR->Group2_Ledidac - 1; + } + + +// if(g3_led>750000 && calR->Group3_Ledidac<=120) +// { +// calR->Group3_Ledidac = calR->Group3_Ledidac + 3; +// } +// if(g3_led<350000 && calR->Group3_Ledidac >= 3) +// { +// calR->Group3_Ledidac = calR->Group3_Ledidac - 3; +// } +// if(g3_led < 350000 && calR->Group3_Ledidac>0) +// { +// calR->Group3_Ledidac = calR->Group3_Ledidac - 1; +// } + + +// if(g1_led<750000 && g1_led>350000 && g2_led<750000 && g2_led>350000 && g3_led<750000 && g3_led>350000) + if(g1_led<650000 && g1_led>400000 && g2_led<650000 && g2_led>400000 ) + { + calR->state = hrsCalFinish; + } +// else if(calR->Group1_Ledidac >= 120 || calR->Group2_Ledidac >= 120 || calR->Group3_Ledidac >= 120) + else if(calR->Group1_Ledidac >= 120 || calR->Group2_Ledidac >= 120) + + { + calR->state = hrsCalLed3; + } + else + { + calR->state = hrsCalLed2; + } + calR->flag = CAL_FLG_LED_DAC; + break; + + case hrsCalLed3: + if(calR->Group1_Ledidac >=120) + { + calR->Group1_Cur = (calR->Group1_Cur*3)>>2; + } + if(calR->Group2_Ledidac>=120) + { + calR->Group2_Cur = (calR->Group2_Cur*3)>>2; + } +// if(calR->Group3_Ledidac>=120) +// { +// calR->Group3_Cur = (calR->Group3_Cur*3)>>2; +// } + calR->flag = CAL_FLG_LED_DR; + calR->state = hrsCalLed; + break; + + case hrsCalRfEnd: + calR->state = hrsCalFinish; + calR->flag = 0; + break; + + default: + break; + } + AGC_LOG("AGC111: led_drv=%d,ledDac=%d,ambDac=%d,ledstep=%d,rf=%d,state = %d\r\n",\ + calR->Group1_Cur, calR->Group1_Ledidac, calR->Group1_AMBDAC,calR->Group1_step,calR->Group1_RF,calR->state); + AGC_LOG("AGC222: led_drv=%d,ledDac=%d,ambDac=%d,ledstep=%d,rf=%d,state = %d\r\n",\ + calR->Group2_Cur, calR->Group2_Ledidac, calR->Group2_AMBDAC,calR->Group2_step,calR->Group2_RF,calR->state); +// AGC_LOG("AGC333: led_drv=%d,ledDac=%d,ambDac=%d,ledstep=%d,rf=%d,state = %d\r\n",\ +// calR->Group3_Cur, calR->Group3_Ledidac, calR->Group3_AMBDAC,calR->Group3_step,calR->Group3_RF,calR->state); +} + + +HRS_CAL_SET_T PPG_hrs_agc(void) +{ + int32_t g1_led_val, g2_led_val, g1_amb_val, g2_amb_val; + + //AGC_LOG("agc in\r\n"); + calReg_Hrs.work = false; + if (!hrs_cal_state) + { +// AGC_LOG("s_cal_state1: %d \r\n", hrs_cal_state); + return calReg_Hrs; + } + //AGC_LOG("agc in\r\n"); + #ifdef INT_MODE + calReg_Hrs.int_cnt ++; + if(calReg_Hrs.int_cnt < 8) + { + return calReg_Hrs; + } + calReg_Hrs.int_cnt = 0; + hx3695_gpioint_cfg(false); + #endif + calReg_Hrs.work = true; + + read_hrs_data_packet(agc_buf); + TYHX_LOG("phase_0x03 %d,%d,%d,%d,%d,%d,%d,%d \r\n", + agc_buf[0], agc_buf[1], agc_buf[2], agc_buf[3],agc_buf[4], agc_buf[5],agc_buf[6], agc_buf[7]); + + g1_led_val = agc_buf[1]; + g1_amb_val = (agc_buf[0] + agc_buf[2])/2 ; + + g2_led_val = agc_buf[4]; + g2_amb_val = (agc_buf[3] + agc_buf[5])/2 ; + + TYHX_LOG("cal dat g1=%d,g2=%d, a1=%d,a2=%d \r\n", + g1_led_val, g1_amb_val, g2_led_val, g2_amb_val ); + + PPG_hrs_Calibration_Routine(&calReg_Hrs, g1_led_val, g2_led_val, g1_amb_val, g2_amb_val ); + + if (calReg_Hrs.state == hrsCalFinish) + { + hx3695_hrs_set_mode(CAL_OFF); +// AGC_LOG("hrs_state = %d \r\n",calReg_Hrs.state); + #if defined(TIMMER_MODE) + #else + hx3695_gpioint_cfg(true); + #endif + } + else + { + hx3695_hrs_updata_reg(); +// AGC_LOG("hrs_state1 = %d \r\n",calReg_Hrs.state); + #if defined(INT_MODE) + hx3695_gpioint_cfg(true); + #endif + } + return calReg_Hrs; +} + +void hx3695_hrs_cal_init(void) +{ + uint16_t sample_rate = 200; //200 /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + uint8_t data_avg_num = 0; + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0x1b,0x92); //FIFO bypass mode enable old 0x10 + hx3695_write_reg(0x36,0x08); // phase4 convertion ready enable + + #if defined(INT_MODE) +// hx3695_write_reg(0x36,0x88); //phase8 phase4 convertion ready enable + hx3695_write_reg(0x38,0x01); + #endif + + hx3695_write_reg(0x5c,0x0a); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x5c,0x08); //Chip state machine work normal + hx3695_delay_ms(10); //Delay for reset time +} + +void hx3695_hrs_cal_off(void) +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + uint8_t data_avg_num = 0; + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + #if defined(INT_MODE) + hx3695_write_reg(0x1b,0x92); //FIFO mode enable + hx3695_write_reg(0x36,0x00); //phase convertion ready disable + hx3695_write_reg(0x38,0x04); + #endif + hx3695_write_reg(0x1b, 0x92); + hx3695_write_reg(0x5c,0x0a); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x1b, 0x92); + + hx3695_write_reg(0x5c,0x08); //Chip state machine work normal + hx3695_delay_ms(5); + read_fifo_first_flg = 1; +// AGC_LOG("caloff_fifo: %d\r\n", (fifo_data_temp[0]|(fifo_data_temp[1]<<8)|(fifo_data_temp[2]<<16))); +} + +void read_hrs_data_packet(int32_t *s_buf) +{ + uint8_t databuf1[6] = {0}; + uint8_t databuf2[6] = {0}; + uint8_t databuf3[6] = {0}; + uint8_t databuf4[6] = {0}; + + hx3695_brust_read_reg(0x03, databuf1, 6); + hx3695_delay_ms(5); + hx3695_brust_read_reg(0x09, databuf2, 6); + hx3695_brust_read_reg(0x0f, databuf3, 6); + hx3695_brust_read_reg(0x15, databuf4, 6); + + s_buf[0] = ((databuf1[0])|(databuf1[1]<<8)|(databuf1[2]<<16)); + s_buf[1] = ((databuf1[3])|(databuf1[4]<<8)|(databuf1[5]<<16)); + s_buf[2] = ((databuf2[0])|(databuf2[1]<<8)|(databuf2[2]<<16)); + s_buf[3] = ((databuf2[3])|(databuf2[4]<<8)|(databuf2[5]<<16)); + s_buf[4] = ((databuf3[0])|(databuf3[1]<<8)|(databuf3[2]<<16)); + s_buf[5] = ((databuf3[3])|(databuf3[4]<<8)|(databuf3[5]<<16)); + s_buf[6] = ((databuf4[0])|(databuf4[1]<<8)|(databuf4[2]<<16)); + s_buf[7] = ((databuf4[3])|(databuf4[4]<<8)|(databuf4[5]<<16)); + +// AGC_LOG("phase7_data: %d, phase8_data: %d\r\n", s_buf[6],s_buf[7]); + +} + +void read_hrs_ir_packet(int32_t *buf) +{ + uint8_t dataBuf[6]; + + hx3695_brust_read_reg(0x06, dataBuf, 6); + + for (uint8_t i=0; i<2; i++) + { + buf[i] = (int32_t)(dataBuf[3*i]|(dataBuf[3*i+1]<<8)|(dataBuf[3*i+2]<<16)); + } +} + +void hx3695_hrs_read_data_packet(int32_t *buf) +{ + uint8_t databuf1[6] = {0}; + uint8_t databuf2[6] = {0}; + uint32_t P1 = 0,P2 = 0,P3 = 0,P4 =0 ; + + hx3695_brust_read_reg(0x03, databuf1, 6); + hx3695_brust_read_reg(0x09, databuf2, 6); + + P1 = ((databuf1[0])|(databuf1[1]<<8)|(databuf1[2]<<16)); + P2 = ((databuf1[3])|(databuf1[4]<<8)|(databuf1[5]<<16)); + P3 = ((databuf2[0])|(databuf2[1]<<8)|(databuf2[2]<<16)); + P4 = ((databuf2[3])|(databuf2[4]<<8)|(databuf2[5]<<16)); + + buf[0] = P1; + buf[1] = P2; + buf[2] = P3; + buf[3] = P4; + +// TYHX_LOG("tyhx_here ! \r\n"); + +// AGC_LOG("P1~P4: %x, %x %x, %x \r\n", P1,P2,P3,P4); + +} + +void hx3695_hrs_low_power(void) +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t phase2_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase5_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase2_ldr_cur = 0; + uint8_t phase5_ldr_cur = 0; + + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_res = 0; + uint8_t phase3_tia_res = 0; + + uint8_t phase4_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase5_tia_res = 0; + uint8_t phase6_tia_res = 0; + + uint8_t phase1_led_en = 1; + uint8_t phase2_led_en = 1; + uint8_t phase3_led_en = 1; + uint8_t phase4_led_en = 1; + uint8_t phase5_led_en = 1; + uint8_t phase6_led_en = 1; + uint8_t phase7_led_en = 1; + uint8_t phase8_led_en = 1; + + uint8_t phase1_mux_sel = 0; + uint8_t phase2_mux_sel = 1; + uint8_t phase3_mux_sel = 2; + uint8_t phase4_mux_sel = 3; + uint8_t phase5_mux_sel = 4; + uint8_t phase6_mux_sel = 5; + uint8_t phase7_mux_sel = 6; + uint8_t phase8_mux_sel = 7; + + uint8_t phase8_ldr_cur = 25; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + + uint8_t led_on_time = 1; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase1_tia_res)); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase2_tia_res)); + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase3_tia_res)); + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase1_tia_res)); + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase2_tia_res)); + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase3_tia_res)); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X47, phase2_offset_idac); + hx3695_write_reg(0X45, phase2_ldr_cur); +// hx3695_write_reg(0X70, phase2_ldr_cur); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X47, phase5_offset_idac); + hx3695_write_reg(0X45, phase5_ldr_cur); + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X46, 0XC0); + hx3695_write_reg(0X45, phase8_ldr_cur); + + hx3695_write_reg(0X31, led_on_time<<4|(hx3695_read_reg(0X31)&0x0f)); + hx3695_write_reg(0X30, phase8_led_en<<7 | phase7_led_en<<6 | phase6_led_en<<5 | phase5_led_en<<4 | phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en); + + //hx3695_write_reg(0X69, 0xa2); //bit<0>: rc_comb_en bits<1>=rc_rbp_en bits<7>= vcom_clamp_en bits<6:4>= LED_vdesl + + #ifdef INT_MODE + + hx3695_write_reg(0x1b,0x92); //FIFO bypass mode enable +// hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable +// hx3695_write_reg(0X33, 0x83); // int width +// hx3695_write_reg(0X21,0x04); // fifo almostfull cfg ,max=0x40; + hx3695_write_reg(0X38,0x04); // fifo almostfull cfg ,max=0x40; + #else + hx3695_write_reg(0x1b,0x92); //FIFO bypass mode enable + hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable + #endif + hx3695_write_reg(0x5c,0x0a); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x5c,0x00); //Chip state machine work normal + hx3695_delay_ms(5); + calReg_Hrs.Group1_Cur = 0; + calReg_Hrs.Group2_Cur = 0; + calReg_Hrs.Group3_Cur = 0; + + TYHX_LOG(" chip3 go to low power mode \r\n" ); + +} + +void hx3695_hrs_updata_reg(void) +{ + uint8_t phase1_mux_sel = 0; + uint8_t phase2_mux_sel = 1; + uint8_t phase3_mux_sel = 2; + uint8_t phase4_mux_sel = 3; + uint8_t phase5_mux_sel = 4; + uint8_t phase6_mux_sel = 5; + uint8_t phase7_mux_sel = 6; + uint8_t phase8_mux_sel = 7; + + + if (calReg_Hrs.flag & CAL_FLG_LED_DR) + { + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X45, calReg_Hrs.Group1_Cur); // phase1 led driver config +// hx3695_write_reg(0X70, calReg_Hrs.LED); +// AGC_LOG(" phase2_led_cur_0x45 = %d \r\n",hx3695_read_reg(0x45) ); +// hx3695_write_reg(0X43, phase4_mux_sel); +// hx3695_write_reg(0X45, calReg_Hrs.Group2_Cur); // phase1 led driver config +// + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X45, calReg_Hrs.Group2_Cur); // phase1 led driver config + AGC_LOG(" phase2_led_cur_0x45 = %d \r\n",hx3695_read_reg(0x45) ); + } + + if (calReg_Hrs.flag & CAL_FLG_LED_DAC) + { + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X48, calReg_Hrs.Group1_Ledidac); +// AGC_LOG(" Phase2_LEDDAC_0x47 = %d \r\n",hx3695_read_reg(0x47) ); +// hx3695_write_reg(0X43, phase4_mux_sel); +// hx3695_write_reg(0X48, calReg_Hrs.Group2_Ledidac); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X48, calReg_Hrs.Group2_Ledidac); + } + + if (calReg_Hrs.flag & CAL_FLG_AMB_DAC) + { + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X48, calReg_Hrs.Group1_AMBDAC); // phase1 offset idac cfg +// AGC_LOG(" PHASE1_AMBDAC_0x47 = %d \r\n",hx3695_read_reg(0x47) ); + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X48, calReg_Hrs.Group1_AMBDAC); // phase3 offset idac cfg +// AGC_LOG(" PHASE3_AMBDAC_0x47 = %d \r\n",hx3695_read_reg(0x47) ); + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X48, calReg_Hrs.Group2_AMBDAC); // phase5 offset idac cfg + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X48, calReg_Hrs.Group2_AMBDAC); // phase5 offset idac cfg + } + + if (calReg_Hrs.flag & CAL_FLG_RF) + { + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_Hrs.Group1_RF)); +// AGC_LOG(" PHASE1_RF_0x44 = %d \r\n",(hx3695_read_reg(0x44)&0x0f) ); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_Hrs.Group1_RF)); +// AGC_LOG(" PHASE2_RF_0x44 = %d \r\n",(hx3695_read_reg(0x44)&0x0f) ); + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_Hrs.Group1_RF)); +// AGC_LOG(" PHASE3_RF_0x44 = %d \r\n",(hx3695_read_reg(0x44)&0x0f) ); + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_Hrs.Group2_RF)); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_Hrs.Group2_RF)); + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_Hrs.Group2_RF)); + } +} + +void hx3695_hrs_set_mode(uint8_t mode_cmd) +{ + switch (mode_cmd) + { + case PPG_INIT: + hx3695_hrs_ppg_init(); +#if defined(TIMMER_MODE) + hx3695_320ms_timer_cfg(true); +#if defined(GSEN_40MS_TIMMER) + hx3695_40ms_timer_cfg(true); + #endif +#else + hx3695_gpioint_cfg(true); +#endif + s_ppg_state = 1; + AGC_LOG("ppg init mode\r\n"); + break; + + case PPG_OFF: + hx3695_ppg_off(); + s_ppg_state = 0; + AGC_LOG("ppg off mode\r\n"); + break; + + case PPG_LED_OFF: + hx3695_hrs_low_power(); + s_ppg_state = 0; + AGC_LOG("ppg led off mode\r\n"); + break; + + case CAL_INIT: + Init_hrs_PPG_Calibration_Routine(&calReg_Hrs); + hx3695_hrs_cal_init(); + hx3695_hrs_updata_reg(); + #if defined(TIMMER_MODE) + #if defined(GSEN_40MS_TIMMER) + #else + hx3695_40ms_timer_cfg(true); + #endif + #endif + hrs_cal_state = 1; + AGC_LOG("cal init mode\r\n"); + break; + + case RECAL_INIT: + Restart_hrs_PPG_Calibration_Routine(&calReg_Hrs); + hx3695_hrs_cal_init(); + hx3695_hrs_updata_reg(); +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(true); +#endif +#endif + hrs_cal_state = 1; + AGC_LOG("Recal init mode\r\n"); + break; + + case CAL_OFF: +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(false); +#endif +#endif + hx3695_hrs_cal_off(); + hrs_cal_state = 0; + AGC_LOG("cal off mode\r\n"); + break; + + default: + break; + } +} + +SENSOR_ERROR_T hx3695_hrs_enable(void) +{ + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return SENSOR_OP_FAILED; + } + + AGC_LOG("hx3695 check id success!\r\n"); + + if (s_ppg_state) + { + AGC_LOG("ppg already on!\r\n"); + return SENSOR_OP_FAILED; + } + if(!tyhx_hrs_alg_open()) + { + AGC_LOG("hrs alg open fail,or dynamic ram not enough!\r\n"); + } + + hrs_wear_status = MSG_HRS_NO_WEAR; + hrs_wear_status_pre = MSG_HRS_NO_WEAR; + + hx3695_hrs_set_mode(PPG_INIT); + + AGC_LOG("hx3695 enable!\r\n"); + + return SENSOR_OK; +} + +void hx3695_hrs_disable(void) +{ +#if defined(TIMMER_MODE) + hx3695_320ms_timer_cfg(false); + hx3695_40ms_timer_cfg(false); +#elif defined(INT_MODE) + hx3695_gpioint_cfg(false); +#endif + hx3695_hrs_set_mode(PPG_OFF); + s_ppg_state = 0; + hrs_cal_state = 0; + tyhx_hrs_alg_close(); + AGC_LOG("hx3695 disable!\r\n"); +} + +void hx3695_hrs_data_reset(void) +{ + s_ppg_state = 0; + hrs_cal_state = 0; + tyhx_hrs_alg_close(); +} + +hrs_wear_msg_code_t hx3695_hrs_get_wear_status(void) +{ + return hrs_wear_status; +} + +HRS_CAL_SET_T get_hrs_agc_status(void) +{ + HRS_CAL_SET_T cal; +// cal.flag = calReg_Hrs.flag; +// cal.int_cnt = calReg_Hrs.int_cnt; +// cal.cur255_cnt = calReg_Hrs.cur255_cnt; +// +// cal.led_idac = calReg_Hrs.led_idac; +// +// cal.Group1_Ledidac = calReg_Hrs.Group1_Ledidac; +// +// cal.LEDDAC = calReg_Hrs.LEDDAC; +// cal.AMBDAC = calReg_Hrs.AMBDAC; +// cal.RF = calReg_Hrs.RF; +// cal.led_step = calReg_Hrs.led_step; +// cal.state = calReg_Hrs.state; +// cal.led_max_cur = calReg_Hrs.led_max_cur; +// cal.work = calReg_Hrs.work; + cal = calReg_Hrs; + return cal; +} + +uint8_t hx3695_hrs_read(hrs_sensor_data_t * s_dat) +{ + int32_t PPG_src_data, PPG_src_data2; + int32_t Ir_src_data; + bool recal = false; + uint8_t size = 0; + uint16_t data_count = 0; + uint8_t size_byte = 0; + int32_t *PPG_buf = &(s_dat->green_data[0]); + int32_t *ir_buf = &(s_dat->ir_data[0]); + int32_t *s_buf = &(s_dat->s_buf[0]); + + int32_t ps_data[8] = {0}; + int32_t ps_green_data = 0; + s_dat->agc_green = calReg_Hrs.Group1_Cur; + + if (!s_ppg_state || hrs_cal_state) + { +// TYHX_LOG("ppg_state: %d ,hrs_cal_state: %d\r\n",s_ppg_state,hrs_cal_state); + return 0; + } +// TYHX_LOG("ppg_state: %d ,hrs_cal_state: %d\r\n",s_ppg_state,hrs_cal_state); + data_count = hx3695_read_fifo_data(s_buf,hrs_phase_num,1); + //AGC_LOG("ppg data size: %d %d\r\n", data_count,hrs_phase_num); +// AGC_LOG("af_hx3695_read_fifo_data:::%d %d %d\r\n", hx3695_read_reg(0X2a),hx3695_read_reg(0X2b),hx3695_read_reg(0X2c)); + s_dat->count = data_count; + + read_hrs_data_packet(ps_data); + for (uint8_t i=0; i>1); +// AGC_LOG("ps_green_data: %d PS8: %d, PS7: %d\r\n", ps_green_data,ps_data[7],ps_data[6]); + if (ps_green_data<300000 || ps_green_data>800000) + { + recal = true; + + if(hrs_wear_status==MSG_HRS_NO_WEAR) + { + recal = false; + } + } + if (recal) + //if (0) + { + cal_delay--; + + if (cal_delay <= 0) + { + cal_delay = CAL_DELAY_COUNT; + hx3695_hrs_set_mode(RECAL_INIT); + AGC_LOG("========>>>>LED_IDAC = %d %d %d\r\n",calReg_Hrs.Group1_Ledidac,calReg_Hrs.Group2_Ledidac,calReg_Hrs.Group3_Ledidac); + } + } + else + { + cal_delay = CAL_DELAY_COUNT; + } +// } + return 1; +} + + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_agc.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_agc.h new file mode 100644 index 000000000..0a7004975 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_agc.h @@ -0,0 +1,115 @@ +#ifndef _hx3695_hrs_agc_H_ +#define _hx3695_hrs_agc_H_ +#include +#include +#include "hx3695.h" + +#define CAL_FLG_LED_DR 0x01 +#define CAL_FLG_LED_DAC 0x02 +#define CAL_FLG_AMB_DAC 0x04 +#define CAL_FLG_RF 0x08 + +#define HRS_CAL_INIT_LED 128 +#define NO_TOUCH_CHECK_NUM 2 +#define CAL_DELAY_COUNT 2 + +typedef enum { + MSG_HRS_NO_WEAR, + MSG_HRS_WEAR +} hrs_wear_msg_code_t; + +typedef struct { + uint8_t count; + int32_t green_data[64]; + int32_t ir_data[64]; + int32_t s_buf[64]; + uint32_t als; + uint32_t agc_green; +} hrs_sensor_data_t; + + +//typedef struct { +// SENSOR_TYPE_T type; +// uint8_t count; +// int32_t ppg_data[64]; +// int32_t ir_data[64]; +// int32_t s_buf[64]; +// uint32_t als; +// uint32_t agc_green; +//}hrs_sensor_data_t; + +//typedef enum { +// hrsCalStart, +// hrsCalLedCur, +// hrsCalLed, +// hrsCalLed2, +// hrsCalLed3, +// hrsCalFinish, +//} HRS_STATE_T; + + +typedef enum { + hrsCalStart, + hrsCalStart1, + hrsCalLed, + hrsCalLed2, + hrsCalLed3, + hrsCalRf, + hrsCalRfEnd, + hrsCalFinish, +}HRS_STATE_T; + +typedef struct { + uint8_t flag; + bool work; + uint8_t int_cnt; + uint8_t cur255_cnt; + uint8_t Group1_Ledidac; //led_idac + uint8_t Group2_Ledidac; + uint8_t Group3_Ledidac; + uint16_t Group1_Cur; //LED; + uint16_t Group2_Cur; //LED; + uint16_t Group3_Cur; //LED; +// uint8_t LEDDAC; + uint8_t Group1_AMBDAC; + uint8_t Group2_AMBDAC; + uint8_t Group3_AMBDAC; + uint8_t Group1_RF; + uint8_t Group2_RF; + uint8_t Group3_RF; + uint32_t Group1_step; + uint32_t Group2_step; + uint32_t Group3_step; + uint8_t state; + uint8_t Group1_max_cur; + uint8_t Group2_max_cur; + uint8_t Group3_max_cur; +} HRS_CAL_SET_T; + +HRS_CAL_SET_T PPG_hrs_agc(void); +void Init_hrs_PPG_Calibration_Routine(HRS_CAL_SET_T *calR); +void Restart_hrs_PPG_Calibration_Routine(HRS_CAL_SET_T *calR); +//void PPG_hrs_Calibration_Routine(HRS_CAL_SET_T *calR, int32_t g1_led,int32_t g2_led,int32_t g3_led, int32_t g1_amb, int32_t g2_amb,int32_t g3_amb); +void PPG_hrs_Calibration_Routine(HRS_CAL_SET_T *calR, int32_t g1_led,int32_t g2_led, int32_t g1_amb, int32_t g2_amb); + +void hx3695_hrs_cal_init(void); +void hx3695_hrs_cal_off(void); +uint8_t hx3695_read_fifo_size(void); +void read_hrs_data_packet(int32_t *buf); +void read_hrs_ir_packet(int32_t *buf); +void hx3695_hrs_read_data_packet(int32_t *buf); +void hx3695_hrs_low_power(void); +void hx3695_hrs_normal_power(void); +void hx3695_hrs_updata_reg(void); +void hx3695_hrs_set_mode(uint8_t mode_cmd); +SENSOR_ERROR_T hx3695_hrs_enable(void); +void hx3695_hrs_disable(void); +hrs_wear_msg_code_t hx3695_hrs_get_wear_status(void); +uint8_t hx3695_hrs_read(hrs_sensor_data_t *s_dat); +bool hx3695_hrs_init(void); +hrs_wear_msg_code_t hx3695_hrs_wear_mode_check(WORK_MODE_T mode, int32_t infrared_data); + +HRS_CAL_SET_T get_hrs_agc_status(void); +void hx3695_hrs_data_reset(void); + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_custom.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_custom.c new file mode 100644 index 000000000..6a6224b15 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrs_custom.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include + +#include "tyhx_hrs_custom.h" +#include "osal_timer.h" +#include "osal_mutex.h" +#include "pinctrl.h" +#include "chip_io.h" +#include "time.h" +#include "i2c.h" +#include "gpio.h" +#include "hal_gpio.h" +#include "hal_i2c.h" +#include "soc_osal.h" +#include "tcxo.h" + +typedef struct { + i2c_bus_t i2c_id; + uint32_t i2c_speed; +} hx3695_ctrl_attr; + +static hx3695_ctrl_attr g_hx3695_ctl_handler={HX3695_I2C_BUS,400000}; +static uint8_t g_hx3695_installed = 0; +static errcode_t hx3695_i2c_init(void) +{ + errcode_t result; + /* init i2c */ + if ( g_hx3695_installed == 1 ) + return ERRCODE_SUCC; + + result = uapi_i2c_master_init(HX3695_I2C_BUS, 400000, I2C_SPEED_MODE_FS); /* 400000: 400KHz */ + if (result != ERRCODE_SUCC) { + TYHX_ERROR("hx3695 i2c init fail! ret=0x%x", result); + return ERRCODE_FAIL; + } + + TYHX_WARNING("hx3695:i2c_id = %d i2c_speed = %d slave_addr = 0x%x \r\n", + HX3695_I2C_BUS, 400000, HX3695_I2C_DEV_8ADDR); + + g_hx3695_installed = 1; + + return ERRCODE_SUCC; +} + +uint32_t tyhx_write_reg(uint8_t reg_addr, uint8_t reg) +{ + errcode_t ret; + uint32_t retry; + i2c_data_t data; + uint8_t *write_data = NULL; + uint16_t send_len; + uint8_t *data_buf=® + uint16_t data_len=1; + + hx3695_i2c_init(); + send_len = data_len + sizeof(uint8_t); + write_data = (uint8_t *)osal_kmalloc(send_len, OSAL_GFP_KERNEL); + if (write_data == NULL) { + TYHX_ERROR("hx3695 send buff malloc fail!"); + return ERRCODE_FAIL; + } + write_data[0] = reg_addr; + ret = (uint32_t)memcpy_s(write_data + sizeof(uint8_t), send_len - sizeof(uint8_t), data_buf, data_len); + if (ret != EOK) { + TYHX_ERROR("hx3695 send_buf content copy fail! ret=0x%x", ret); + return ret; + } + + data.send_buf = write_data; + data.send_len = send_len; + data.receive_buf = NULL; + data.receive_len = 0; + + for (retry = 0; retry < HX3695_I2C_TIME_MAX; retry++) { + ret = uapi_i2c_master_write(HX3695_I2C_BUS, HX3695_I2C_DEV_8ADDR, &data); + if (ret == ERRCODE_SUCC) { + break; + } + } + if (ret != ERRCODE_SUCC) { + TYHX_ERROR("hx3695 data write fail! ret=0x%x", ret); + return ret; + } + + osal_kfree(write_data); + return ERRCODE_SUCC; +} + +uint32_t tyhx_read_regs(uint8_t reg_addr, uint8_t *data_buf, uint8_t data_len) +{ + errcode_t ret; + uint32_t retry; + i2c_data_t data; + + hx3695_i2c_init(); + memset_s(data_buf, data_len, 0, data_len); + data.send_buf = ®_addr; + data.send_len = 1; + data.receive_buf = data_buf; + data.receive_len = data_len; + + for (retry = 0; retry < HX3695_I2C_TIME_MAX; retry++) { + ret = uapi_i2c_master_writeread(HX3695_I2C_BUS, HX3695_I2C_DEV_8ADDR, &data); + if (ret == ERRCODE_SUCC) { + break; + } + } + if (ret != ERRCODE_SUCC) { + TYHX_ERROR("hx3695 data read fail! ret=0x%x", ret); + return ret; + } + + return ERRCODE_SUCC; +} + + +// us 延时函数, 客户需填写 +void tyhx_delay_us(uint32_t us) +{ + uapi_tcxo_delay_us(us); +} +void tyhx_delay_ms(uint32_t ms) +{ + uapi_tcxo_delay_ms(ms); +} + + + + +#include "cmsis_os2.h" +#define BUTTON_APP_TIMER_INTERVAL 20 +osTimerId_t g_timer40_timer = NULL; +osTimerId_t g_timer320_timer = NULL; +static uint8_t g_hx3695_timer_installed = 0; + +static void timer40_func(void) +{ + agc_timeout_handler(NULL); +} + +static void timer320_func(void) +{ + heart_rate_meas_timeout_handler(NULL); +} +bool tyhx_timer_init(void) +{ + if (g_hx3695_timer_installed == 1) + return true; + g_timer40_timer = osTimerNew((osTimerFunc_t)timer40_func, osTimerPeriodic, NULL, NULL); + g_timer320_timer = osTimerNew((osTimerFunc_t)timer320_func, osTimerPeriodic, NULL, NULL); + g_hx3695_timer_installed = true; + return true; +} + +void readFifoByHrsModule(void) +{ + +} + +bool tyhx_timer_start(uint32_t ms) +{ + tyhx_timer_init(); + if( ms == TYHX_TIMER_40MS) + { + if(osTimerIsRunning(g_timer40_timer)==0) + osTimerStart(g_timer40_timer, TYHX_TIMER_40MS); + }else if (ms == TYHX_TIMER_320MS) + { + if(osTimerIsRunning(g_timer320_timer)==0) + osTimerStart(g_timer320_timer, TYHX_TIMER_320MS); + } + return 1; +} +bool tyhx_timer_stop(uint32_t ms) +{ + tyhx_timer_init(); + if( ms == TYHX_TIMER_40MS) + { + if(osTimerIsRunning(g_timer40_timer)) + osTimerStop(g_timer40_timer); + }else if (ms == TYHX_TIMER_320MS) + { + if(osTimerIsRunning(g_timer320_timer)) + osTimerStop(g_timer320_timer); + } + return 1; +} + +uint32_t tyhx_suspend(void) +{ + + return 0; +} +uint32_t tyhx_resume(void) +{ + + return 0; +} + +// 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(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); + + 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); + 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_HIGH); + + 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); + return 0; +} + + diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrv_agc.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrv_agc.c new file mode 100644 index 000000000..1bf291643 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrv_agc.c @@ -0,0 +1,784 @@ +#include +#include +#include +#include +#include + +#include "tyhx_hrs_custom.h" +#include "hx3695.h" +#include "hx3695_hrv_agc.h" +#include "tyhx_hrv_alg.h" + + +#ifdef HRV_ALG_LIB + +extern const uint8_t hx3695_hrs_agc_idac; +extern const uint8_t green_led_max_init; +extern uint8_t low_vbat_flag; +extern uint8_t hrv_phase_num; +extern uint8_t read_fifo_first_flg; + +//hrv_INFRARED_THRES +extern const int32_t hrv_ir_unwear_thres; +extern const int32_t hrv_ir_wear_thres; + +static uint8_t s_ppg_state = 0; +static uint8_t s_cal_state = 0; +static int32_t agc_buf[4] = {0}; + +static uint8_t cal_delay = HRV_CAL_DELAY_COUNT; +static HRV_CAL_SET_T calReg; +// +static hrv_wear_msg_code_t hrv_wear_status = MSG_HRV_NO_WEAR; +static hrv_wear_msg_code_t hrv_wear_status_pre = MSG_HRV_NO_WEAR; + +static uint8_t no_touch_cnt = 0; + +hrv_wear_msg_code_t hx3695_hrv_wear_mode_check(int32_t infrared_data) +{ + if(infrared_data > hrv_ir_wear_thres) + { + if(no_touch_cnt < NO_TOUCH_CHECK_NUM) + { + no_touch_cnt++; + } + if(no_touch_cnt >= NO_TOUCH_CHECK_NUM) + { + hrv_wear_status = MSG_HRV_WEAR; + } + } + else if(infrared_data < hrv_ir_unwear_thres) + { + if(no_touch_cnt>0) + { + no_touch_cnt--; + } + if(no_touch_cnt == 0) + { + hrv_wear_status = MSG_HRV_NO_WEAR; + } + } + + if(hrv_wear_status_pre != hrv_wear_status) + { + hrv_wear_status_pre = hrv_wear_status; + if(hrv_wear_status_pre == MSG_HRV_NO_WEAR) + { + hx3695_hrv_low_power(); + } + else if(hrv_wear_status_pre == MSG_HRV_WEAR) + { + tyhx_hrv_alg_open_deep(); + hx3695_hrv_set_mode(PPG_INIT); + hx3695_hrv_set_mode(CAL_INIT); + } + } + + return hrv_wear_status; +} + +void Init_hrv_PPG_Calibration_Routine(HRV_CAL_SET_T *calR,uint8_t led) +{ + calR->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + + calR->LEDDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->AMBDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->RF = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + calR->LED = HRV_CAL_INIT_LED; + calR->state = hrvCalStart; + calR->int_cnt = 0; + calR->cur255_cnt =0; + if(low_vbat_flag==1) + { + calR->led_max_cur = 128; + } + else + { + calR->led_max_cur = green_led_max_init; + } +} + +void Restart_hrv_PPG_Calibration_Routine(HRV_CAL_SET_T *calR) +{ + calR->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + calR->state = hrvCalLed; + calR->int_cnt = 0; +} + +void PPG_hrv_Calibration_Routine(HRV_CAL_SET_T *calR, int32_t led, int32_t amb) +{ + switch(calR->state) + { + case hrvCalStart: + calR->state = hrvLedCur; + break; + + case hrvLedCur: + if(amb>525000) + { + calR->AMBDAC = (amb-525000)/1300; + } + else + { + calR->AMBDAC = 0; + } + if(led>amb+256) + { + calR->led_step = (led-amb)/HRV_CAL_INIT_LED; + calR->LED = 1300*(hx3695_hrs_agc_idac+calR->AMBDAC)/calR->led_step; + if(calR->LED > calR->led_max_cur) + { + calR->LED = calR->led_max_cur; + } + else if(calR->LED < 15) + { + calR->LED = 15; + } + if(calR->LED != calR->led_max_cur) + { + calR->LEDDAC = (hx3695_hrs_agc_idac*3)>>2; + } + else + { + calR->LEDDAC = hx3695_hrs_agc_idac>>1; + } + calR->RF = 5; + calR->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + calR->state = hrvCalLed; + } + else + { + calR->state = hrvCalFinish; + } + break; + + case hrvCalLed: + if(led>800000 && calR->LEDDAC<=120) + { + calR->LEDDAC = calR->LEDDAC + 2; + calR->state = hrvCalLed; + } + else if(led<350000 && calR->LEDDAC>=2) + { + calR->LEDDAC = calR->LEDDAC - 2; + calR->state = hrvCalLed; + } + else if(led<350000 && calR->LEDDAC>0) + { + calR->LEDDAC = calR->LEDDAC - 1; + calR->state = hrvCalLed; + } + else + { + calR->state = hrvCalLed2; + } + calR->flag = CAL_FLG_LED_DAC; + break; + + case hrvCalLed2: + if(led+calR->LEDDAC*26000 < (amb+calR->AMBDAC*26000)+((26000*hx3695_hrs_agc_idac*3)>>2) && calR->LED < calR->led_max_cur) + { + calR->LED = calR->led_max_cur; + calR->state = hrvCalLed; + calR->flag = CAL_FLG_LED_DR; + } + else + { + calR->state = hrvCalFinish; + calR->flag = 0; + } + break; + + default: + break; + + } + AGC_LOG("AGC: led_drv=%d,ledDac=%d,ambDac=%d,ledstep=%d,rf=%d,\r\n",\ + calR->LED, calR->LEDDAC, calR->AMBDAC,calR->led_step,calR->RF); +} + +HRV_CAL_SET_T PPG_hrv_agc(void) +{ + int32_t led_val, amb_val; + calReg.work = false; + if (!s_cal_state) + { + return calReg; + } + +#ifdef INT_MODE + calReg.int_cnt ++; + if(calReg.int_cnt < 8) + { + return calReg; + } + calReg.int_cnt = 0; + hx3695_gpioint_cfg(false); +#endif + + calReg.work = true; + + hx3695_hrv_read_data_packet(agc_buf); + + led_val = agc_buf[0]; + amb_val = agc_buf[1]; + + AGC_LOG("cal dat ch1=%d,ch2=%d,led_val=%d,amb_val=%d \r\n",\ + agc_buf[0], agc_buf[1], led_val, amb_val); + + PPG_hrv_Calibration_Routine(&calReg, led_val, amb_val); + + if (calReg.state == hrvCalFinish) + { + hx3695_hrv_set_mode(CAL_OFF); +#if defined(TIMMER_MODE) +#else + hx3695_gpioint_cfg(true); +#endif + } + else + { + hx3695_hrv_updata_reg(); +#if defined(INT_MODE) + hx3695_gpioint_cfg(true); +#endif + } + return calReg; +} + +void hx3695_hrv_cal_init(void) // 20200615 ericy afe cali online +{ +uint16_t sample_rate = 200; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> +// AGC_LOG("prf_clk_num =%d %d %d\r\n", hx3695_read_reg(0X2a), hx3695_read_reg(0X2b), hx3695_read_reg(0X2c)); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0x1b,0x90); //FIFO mode enable + hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable + + #if defined(INT_MODE) + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0x38,0x04); + #endif + hx3695_write_reg(0x1b, 0x90); + hx3695_write_reg(0x5c,0x0a); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x5c,0x08); //Chip state machine work normal + hx3695_delay_ms(5); +// hx3695_brust_read_reg(0x22, fifo_data_buf, 3); + read_fifo_first_flg = 1; +// AGC_LOG("herehere %d,%d,%d \r\n",hx3695_read_reg(0X2a),hx3695_read_reg(0X2b),hx3695_read_reg(0X2c)); +} + +void hx3695_hrv_cal_off(void) // 20200615 ericy afe cali offline +{ + uint16_t sample_rate = 125; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> +// AGC_LOG("prf_clk_num =%d %d %d\r\n", hx3695_read_reg(0X2a), hx3695_read_reg(0X2b), hx3695_read_reg(0X2c)); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0x1b,0x90); //FIFO mode enable + hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable + + #if defined(INT_MODE) + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0x38,0x04); + #endif + + hx3695_write_reg(0x5c,0x0a); //Chip reset + hx3695_delay_ms(5); //Delay for reset time +// hx3695_write_reg(0x1b, 0x10); +// hx3695_delay(5); + hx3695_write_reg(0x1b, 0x90); + hx3695_write_reg(0x5c,0x08); //Chip state machine work normal + hx3695_delay_ms(5); +// hx3695_brust_read_reg(0x22, fifo_data_buf, 3); + read_fifo_first_flg = 1; +// AGC_LOG("herehere %d,%d,%d \r\n",hx3695_read_reg(0X2a),hx3695_read_reg(0X2b),hx3695_read_reg(0X2c)); +} + +void read_hrv_data_packet(int32_t *buf) +{ + uint8_t dataBuf[6]; + + hx3695_brust_read_reg(0x03, dataBuf, 3); + hx3695_brust_read_reg(0x0c, dataBuf+3, 3); + + for (uint8_t i=0; i<2; i++) + { + buf[i] = (int32_t)(dataBuf[3*i]|(dataBuf[3*i+1]<<8)|(dataBuf[3*i+2]<<16)); + } +} + +void read_hrv_ir_packet(int32_t *buf) +{ + uint8_t dataBuf[6]; + + hx3695_brust_read_reg(0x06, dataBuf, 6); + + for (uint8_t i=0; i<2; i++) + { + buf[i] = (int32_t)(dataBuf[3*i]|(dataBuf[3*i+1]<<8)|(dataBuf[3*i+2]<<16)); + } +} + +void hx3695_hrv_read_data_packet(int32_t *buf) +{ + uint8_t databuf1[6] = {0}; + uint8_t databuf2[6] = {0}; + uint32_t P1 = 0,P2 = 0,P3 = 0,P4 =0 ; + + hx3695_brust_read_reg(0x03, databuf1, 6); + hx3695_brust_read_reg(0x09, databuf2, 6); + + P1 = ((databuf1[0])|(databuf1[1]<<8)|(databuf1[2]<<16)); + P2 = ((databuf1[3])|(databuf1[4]<<8)|(databuf1[5]<<16)); + P3 = ((databuf2[0])|(databuf2[1]<<8)|(databuf2[2]<<16)); + P4 = ((databuf2[3])|(databuf2[4]<<8)|(databuf2[5]<<16)); + + buf[0] = P1; + buf[1] = P2; + buf[2] = P3; + buf[3] = P4; + + AGC_LOG("Reg_data_0x03 %d,%d,%d,%d\r\n",P1,P2,P3,P4); +} + +void hx3695_hrv_low_power(void) +{ + uint16_t sample_rate = 10; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase1_led_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase1_ldr_cur = 0; + + uint8_t phase1_enable = 1; /*phase1_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase2_enable = 1; /*phase2_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase3_enable = 1; /*phase3_enable , 1 mean enable ; 0 mean disable */ + uint8_t phase4_enable = 1; /*phase4_enable , 1 mean enable ; 0 mean disable */ + + uint8_t phase1_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase2_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase3_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + uint8_t phase4_adc_osr = 3; /* 0 = 128 ; 1 = 256 ; 2 = 512 ; 3 = 1024 ; 4 = 2048*/ + + uint8_t phase1_mux_sel = 0; /* sel phase1*/ + uint8_t phase2_mux_sel = 1; /* sel phase2*/ + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + + + uint8_t phase1_led_en = 0; + uint8_t phase2_led_en = 0; + uint8_t phase3_led_en = 1; + uint8_t phase4_led_en = 0; + + uint8_t phase3_tia_res = 0; + uint8_t phase4_tia_res = 0; + + uint8_t phase3_ldr_cur = 15; /* 0~255 = 0 ~ 200ma, step = 0.8ma */ + + uint8_t led_on_time = 1; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X3a, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X3b, data_avg_num<<4 | data_avg_num ); + + + + hx3695_write_reg(0X30, (phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); +// hx3695_write_reg(0X72, (|phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en) ); + + hx3695_write_reg(0X31, (led_on_time<<4| 0x00)); + + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, (0x04<<4 | phase3_tia_res)); + hx3695_write_reg(0X45, phase3_ldr_cur); //cur + + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, (0x04<<4 | phase4_tia_res)); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, (0x04<<4 | phase4_tia_res)); + hx3695_write_reg(0X48, phase1_led_idac); + hx3695_write_reg(0X45, phase1_ldr_cur); + + + hx3695_write_reg(0X26,(phase1_enable<<3)|(phase1_adc_osr)|(phase2_enable<<7)|(phase2_adc_osr<<4) ); + hx3695_write_reg(0X27,(phase3_enable<<3)|(phase3_adc_osr)|(phase4_enable<<7)|(phase4_adc_osr<<4) ); + +#ifdef INT_MODE + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3;\ + 0011=p4;0100=p5;0101=p6;0110=p7;\ + bits<7> fifo enble + hx3695_write_reg(0X33, 0x83); // int width +// hx3695_write_reg(0X21, 0x00); // fifo int sel,00=FIFO INT config clear + hx3695_write_reg(0X38, 0x081); // int sel,00=close almost full int,04=enable almost full int +#else + hx3695_write_reg(0X1b, 0x90);// bits<3:0> fifo data sel, 0000 = p1;0001= p2;0010=p3; + // 0011=p4;0100=p5;0101=p6;0110=p7; + // bits<7> fifo enble + hx3695_write_reg(0X36, 0x00); + + hx3695_write_reg(0X38, 0x00); // int sel,00=close almost full int,01= prf int 04=enable almost full int +#endif + + hx3695_write_reg(0x5c,0x02); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x5c,0x00); //Chip state machine work normal + hx3695_delay_ms(5); + + calReg.LED = phase1_ldr_cur; + AGC_LOG(" chip go to low power mode \r\n" ); +} + +void hx3695_hrv_updata_reg(void) +{ + uint8_t phase1_mux_sel = 0; + uint8_t phase2_mux_sel = 1; + uint8_t phase3_mux_sel = 2; + uint8_t phase4_mux_sel = 3; + if (calReg.flag & CAL_FLG_LED_DR) + { + //AGC_LOG("CAL_FLG_LED_DR\r\n"); + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X45, calReg.LED); + +// hx3695_write_reg(0X43, phase3_mux_sel); +// hx3695_write_reg(0X45, calReg.R_LED); +// hx3695_write_reg(0X43, phase4_mux_sel); +// hx3695_write_reg(0X45, calReg.IR_LED); + } + + if (calReg.flag & CAL_FLG_LED_DAC) + { + //AGC_LOG("CAL_FLG_LED_DAC\r\n"); + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X48, calReg.LEDDAC); +// hx3695_write_reg(0X43, phase3_mux_sel); +// hx3695_write_reg(0X48, calReg.R_LEDDAC); +// hx3695_write_reg(0X43, phase4_mux_sel); +// hx3695_write_reg(0X48, calReg.IR_LEDDAC); + // AGC_LOG("IR_LEDDAC:%d \r\n",hx3695_read_reg(0X47)); + + } + + if (calReg.flag & CAL_FLG_AMB_DAC) + { + //AGC_LOG("CAL_FLG_AMB_DAC\r\n"); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X48, calReg.AMBDAC); // phase2 offset idac cfg + + } + + if (calReg.flag & CAL_FLG_RF) + { + //AGC_LOG("CAL_FLG_RF\r\n"); + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg.RF)); + //AGC_LOG("RF:%x \r\n",hx3695_read_reg(0X44)); +// hx3695_write_reg(0X44, (hx3695_read_reg(0X44)| 0x07)&(calReg.R_RF|0xff)); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg.RF)); + //AGC_LOG("RF:%x \r\n",hx3695_read_reg(0X44)); + } + +} + +void hx3695_hrv_set_mode(uint8_t mode_cmd) +{ + switch (mode_cmd) + { + case PPG_INIT: + hx3695_hrv_ppg_init(); +#if defined(TIMMER_MODE) + hx3695_320ms_timer_cfg(true); +#if defined(GSEN_40MS_TIMMER) + hx3695_40ms_timer_cfg(true); +#endif +#else + hx3695_gpioint_cfg(true); +#endif + s_ppg_state = 1; + + AGC_LOG("ppg init mode\r\n"); + break; + + case PPG_OFF: + hx3695_ppg_off(); + s_ppg_state = 0; + AGC_LOG("ppg off mode\r\n"); + break; + + case PPG_LED_OFF: + hx3695_hrv_low_power(); + s_ppg_state = 0; + AGC_LOG("ppg led off mode\r\n"); + break; + + case CAL_INIT: + Init_hrv_PPG_Calibration_Routine(&calReg, 64); + hx3695_hrv_cal_init(); + hx3695_hrv_updata_reg(); +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(true); +#endif +#endif + s_cal_state = 1; + AGC_LOG("cal init mode\r\n"); + break; + + case RECAL_INIT: + Restart_hrv_PPG_Calibration_Routine(&calReg); + hx3695_hrv_cal_init(); + hx3695_hrv_updata_reg(); +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(true); +#endif +#endif + s_cal_state = 1; + AGC_LOG("Recal init mode\r\n"); + break; + + case CAL_OFF: +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(false); +#endif +#endif + hx3695_hrv_cal_off(); + s_cal_state = 0; + AGC_LOG("cal off mode\r\n"); + break; + + default: + break; + } +} + +SENSOR_ERROR_T hx3695_hrv_enable(void) +{ + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return SENSOR_OP_FAILED; + } + + AGC_LOG("hx3695 check id success!\r\n"); + + if (s_ppg_state) + { + AGC_LOG("ppg already on!\r\n"); + return SENSOR_OP_FAILED; + } + if(!tyhx_hrv_alg_open()) + { + AGC_LOG("hrv alg open fail,or dynamic ram not enough!\r\n"); + } + + hrv_wear_status = MSG_HRV_NO_WEAR; + hrv_wear_status_pre = MSG_HRV_NO_WEAR; + + hx3695_hrv_set_mode(PPG_INIT); + + AGC_LOG("hx3695 enable!\r\n"); + + return SENSOR_OK; +} + + +void hx3695_hrv_disable(void) +{ + hx3695_320ms_timer_cfg(false); + hx3695_40ms_timer_cfg(false); + + hx3695_hrv_set_mode(CAL_OFF); + hx3695_hrv_set_mode(PPG_OFF); + tyhx_hrv_alg_close(); + + AGC_LOG("hx3695 disable!\r\n"); +} + +void hx3695_hrv_data_reset(void) +{ + s_ppg_state = 0; + s_cal_state = 0; + tyhx_hrv_alg_close(); +} + +hrv_wear_msg_code_t hx3695_hrv_get_wear_status(void) +{ + return hrv_wear_status; +} + +hrv_wear_msg_code_t hx3695_hrv_get_wear_status_pre(void) +{ + return hrv_wear_status_pre; +} + +HRV_CAL_SET_T get_hrv_agc_status(void) +{ + HRV_CAL_SET_T cal; + + cal.flag = calReg.flag; + cal.int_cnt = calReg.int_cnt; + cal.LED= calReg.LED; // phasex led driver config + cal.LEDDAC= calReg.LEDDAC; // phasex led offset idac cfg + cal.AMBDAC= calReg.AMBDAC; // phasex offset idac cfg + cal.RF= calReg.RF; // phasex tia feed back resister cfg + cal.led_step= calReg.led_step; + cal.state= calReg.state; + + return cal; +} + +//void hx3695_hrv_read_fifo_data(uint8_t read_fifo_size,int32_t *buf) +//{ +// uint8_t data_flg = 127; +// int32_t data; +// uint8_t databuf[3]; +// uint8_t ii=0; +// for(ii=0; ii>5; +// data = (int32_t)(databuf[0]|(databuf[1]<<8)|((databuf[2]&0x1f)<<16)); + +// if(ii==0) +// { +// if(data_flg ==3) +// { +// ii=3; +// buf[0] = 0; +// buf[1] = 0; +// buf[2] = 0; +// } +// if(data_flg ==2) +// { +// ii=2; +// buf[0] = 0; +// buf[1] = 0; +// } +// if(data_flg ==1) +// { +// ii=1; +// buf[0] = 0; +// } +// } + +// if(data_flg == 0) +// { +// buf[ii]= data; +// } +// else if(data_flg == 1) +// { +// buf[ii]= data; +// } +// else if(data_flg == 2) +// { +// buf[ii]= data; +// } +// else if(data_flg == 3) +// { +// buf[ii]= data; +// } +// } +//} + +uint8_t hx3695_hrv_read(hrv_sensor_data_t *s_dat) +{ + uint8_t i = 0; + int32_t PPG_src_data = 0; + int32_t Ir_src_data = 0; + bool recal = false; + uint8_t size = 0; + uint8_t fifo_out_size = 0; + int32_t *PPG_buf = &(s_dat->green_data[0]); + int32_t *ir_buf = &(s_dat->ir_data[0]); + int32_t *s_buf = &(s_dat->s_buf[0]); + s_dat->green_cur = calReg.LED; + int32_t ps_data[4]; + + if (!s_ppg_state || s_cal_state) + { + DEBUG_PRINTF("ppg state = %d, cal_state = %d\r\n",s_ppg_state,s_cal_state); + return 0; + } +// size = hx3695_read_fifo_size(); +// DEBUG_PRINTF("size = %d\r\n",size); + +// if(size<1) +// { +// return 0; +// } + + hx3695_hrv_read_data_packet(ps_data); + Ir_src_data = ps_data[2]-ps_data[3]; + DEBUG_PRINTF("%d %d \r\n" ,ps_data[2],ps_data[3]); + ir_buf[0] = Ir_src_data; + //DEBUG_PRINTF("111: %d \r\n" ,ir_buf[0] ); + hx3695_hrv_wear_mode_check(Ir_src_data); + +// if ((size) && (size <= 64)) +// { + fifo_out_size = hx3695_read_fifo_data(s_buf,hrv_phase_num,1); + s_dat->count = fifo_out_size; + for (i=0; i750000) + { + recal = true; + + if(hrv_wear_status==MSG_HRV_NO_WEAR) + { + recal = false; + } + } + PPG_buf[i] = PPG_src_data; + //AGC_LOG("%d/%d %d %d %d\r\n" ,1+i,size, s_buf[i],calReg.LED,recal); + } + + if (recal) + { + cal_delay--; + if (cal_delay <= 0) + { + cal_delay = HRV_CAL_DELAY_COUNT; + hx3695_hrv_set_mode(RECAL_INIT); + } + } + else + { + cal_delay = HRV_CAL_DELAY_COUNT; + } +// } + return 1; +} + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrv_agc.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrv_agc.h new file mode 100644 index 000000000..3804a5bce --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hrv_agc.h @@ -0,0 +1,84 @@ +#ifndef _hx3695_hrv_agc_H_ +#define _hx3695_hrv_agc_H_ +//#endif + +#include +#include +#include "hx3695.h" +#define HRV_CAL_DELAY_COUNT 2 + +#define CAL_FLG_LED_DR 0x01 +#define CAL_FLG_LED_DAC 0x02 +#define CAL_FLG_AMB_DAC 0x04 +#define CAL_FLG_RF 0x08 + +#define HRV_CAL_INIT_LED 128 +#define HRV_OFFSET_IDAC 64 + +#define NO_TOUCH_CHECK_NUM 2 + +#ifdef HRV_ALG_LIB +typedef enum { + hrvCalStart, + hrvLedCur, + hrvCalLed, + hrvCalLed2, + hrvCalLed3, + hrvCalFinish, +}HRV_STATE_T; + +typedef struct { + uint8_t count; + uint8_t green_cur; + int32_t green_data[64]; + int32_t ir_data[64]; + int32_t s_buf[64]; + uint32_t als; + uint32_t agc_green; +}hrv_sensor_data_t; + +typedef struct { + uint8_t flag; + bool work; + uint8_t int_cnt; + uint8_t cur255_cnt; + uint8_t led_idac; + uint16_t LED; + uint8_t LEDDAC; + uint8_t AMBDAC; + uint8_t RF; + uint32_t led_step; + uint8_t state; + uint8_t led_max_cur; +} HRV_CAL_SET_T; + +typedef enum { + MSG_HRV_NO_WEAR, + MSG_HRV_WEAR +} hrv_wear_msg_code_t; + +void Init_hrv_PPG_Calibration_Routine(HRV_CAL_SET_T *calR,uint8_t led); +void Restart_hrv_PPG_Calibration_Routine(HRV_CAL_SET_T *calR); +void PPG_hrv_Calibration_Routine(HRV_CAL_SET_T *calR, int32_t led, int32_t amb); + +void hx3695_hrv_cal_init(void); +void hx3695_hrv_cal_off(void); +uint8_t hx3695_read_fifo_size(void); +void read_hrv_data_packet(int32_t *buf); +void read_hrv_ir_packet(int32_t *buf); +void hx3695_hrv_read_data_packet(int32_t *buf); + +void hx3695_hrv_low_power(void); +void hx3695_hrv_updata_reg(void); +void hx3695_hrv_set_mode(uint8_t mode_cmd); +SENSOR_ERROR_T hx3695_hrv_enable(void); +void hx3695_hrv_disable(void); +hrv_wear_msg_code_t hx3695_hrv_get_wear_status(void); +uint8_t hx3695_hrv_read(hrv_sensor_data_t * s_dat); +bool hx3695_hrv_init(void); +HRV_CAL_SET_T PPG_hrv_agc(void); +hrv_wear_msg_code_t hx3695_hrv_wear_mode_check(int32_t infrared_data); +HRV_CAL_SET_T get_hrv_agc_status(void); +void hx3695_hrv_data_reset(void); +#endif +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_spo2_agc.c b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_spo2_agc.c new file mode 100644 index 000000000..fa030eeea --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_spo2_agc.c @@ -0,0 +1,1126 @@ +#include +#include +#include +#include +#include + +#include "hx3695.h" +#include "hx3695_spo2_agc.h" +#include "tyhx_spo2_alg.h" +#include "tyhx_hrs_alg.h" + + +#include "tyhx_hrs_custom.h" + + + +#ifdef SPO2_ALG_LIB + +extern const uint8_t hx3695_spo2_agc_red_idac; // 6,7,8... +extern const uint8_t hx3695_spo2_agc_ir_idac; // 6,7,8... +extern const uint8_t hx3695_spo2_agc_green_idac; // 6,7,8... +extern const uint8_t green_led_max_init; +extern const uint8_t red_led_max_init; +extern const uint8_t ir_led_max_init; +extern uint8_t low_vbat_flag; +extern uint8_t spo2_phase_num; + +//SPO2_INFRARED_THRES +extern const int32_t spo2_ir_unwear_thres; +extern const int32_t spo2_ir_wear_thres; +extern const uint8_t spo2_ir_wear_offset; +extern uint8_t read_fifo_first_flg; + +static uint8_t s_ppg_state = 0; +static uint8_t s_cal_state = 0; +static int32_t agc_buf[8] = {0}; + +static uint8_t cal_delay = SPO2_CAL_DELAY_COUNT; +static SPO2_CAL_SET_T calReg_SPO2; + +static spo2_wear_msg_code_t spo2_wear_status = MSG_SPO2_NO_WEAR; +static spo2_wear_msg_code_t spo2_wear_status_pre = MSG_SPO2_NO_WEAR; + +void Init_Spo2_PPG_Calibration_Routine(SPO2_CAL_SET_T *calR,uint8_t led) +{ + calR->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + calR->G_LEDDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->R_LEDDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->IR_LEDDAC1 = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->AMBDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->RED_AMBDAC = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + calR->IR_AMBDAC1 = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + + calR->G_RF = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + calR->R_RF = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + calR->IR_RF1 = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + calR->G_LED = SPO2_CAL_INIT_LED_GREEN; + calR->R_LED = SPO2_CAL_INIT_LED_RED; + calR->IR_LED1 = SPO2_CAL_INIT_LED_IR; + calR->state = sCalStart; + calR->int_cnt = 0; + calR->cur255_cnt =0; + if(low_vbat_flag == 1) + { + calR->green_idac = (hx3695_spo2_agc_green_idac)>>1; + calR->red_idac = (hx3695_spo2_agc_red_idac*3)>>2; + calR->ir_idac1 = (hx3695_spo2_agc_ir_idac*3)>>2; + calR->green_max_cur = (green_led_max_init)>>1; + calR->red_max_cur = (red_led_max_init*3)>>2; + calR->ir_max_cur = (ir_led_max_init*3)>>2; + } + else + { + calR->green_idac = hx3695_spo2_agc_green_idac; + calR->red_idac = hx3695_spo2_agc_red_idac; + calR->ir_idac1 = hx3695_spo2_agc_ir_idac; + calR->green_max_cur = green_led_max_init; + calR->red_max_cur = red_led_max_init; + calR->ir_max_cur = ir_led_max_init; + } + +} + +void Restart_Spo2_PPG_Calibration_Routine(SPO2_CAL_SET_T *calR) +{ + calR->flag = CAL_FLG_LED_DAC; + calR->state = sCalLed; + calR->int_cnt = 0; +} + +bool hx3695_spo2_check_unwear(int32_t infrared_data) +{ + if( infrared_data < spo2_ir_unwear_thres) + { + spo2_wear_status = MSG_SPO2_NO_WEAR; + if(spo2_wear_status_pre != MSG_SPO2_NO_WEAR) + { + spo2_wear_status_pre = MSG_SPO2_NO_WEAR; + hx3695_spo2_low_power(); + return true; + } + } + return false; +} + +bool hx3695_spo2_check_wear(int32_t infrared_data) +{ + if(infrared_data > spo2_ir_wear_thres) + { + spo2_wear_status = MSG_SPO2_WEAR; + if(spo2_wear_status_pre != MSG_SPO2_WEAR) + { + spo2_wear_status_pre = MSG_SPO2_WEAR; + tyhx_spo2_alg_open_deep(); + hx3695_spo2_set_mode(PPG_INIT); + hx3695_spo2_set_mode(CAL_INIT); +// DEBUG_PRINTF("check_wear\r\n"); + return true; + } + } + return false; +} + + +//void PPG_Spo2_Calibration_Routine(SPO2_CAL_SET_T *calR, int32_t g_led, int32_t r_led, int32_t amb, int32_t ir_led) +void PPG_Spo2_Calibration_Routine(SPO2_CAL_SET_T *calRS, int32_t g_led, int32_t r_led, int32_t ir_led1, int32_t g_amb, int32_t red_amb, int32_t ir_amb1) + +{ + int32_t g_led_temp = 0, r_led_temp = 0, ir_led_temp1 = 0,ir_led_temp2 = 0; + + switch(calRS->state) + { + case sCalStart: + calRS->state = sCalStart1; + break; + + case sCalStart1: + if(spo2_wear_status == MSG_SPO2_NO_WEAR) + { + calRS->state = sCalFinish; + break; + } + + if(g_amb>525000) + { + calRS->GREEN_AMBDAC = (g_amb - 525000)/1100; + } + else + { + calRS->GREEN_AMBDAC = 0; + } + + + + if(red_amb>525000) + { + calRS->RED_AMBDAC = (red_amb - 525000)/1100; + } + else + { + calRS->RED_AMBDAC = 0; + } + + if(ir_amb1>525000) + { + calRS->IR_AMBDAC1 = (ir_amb1 - 525000)/1300; + } + else + { + calRS->IR_AMBDAC1 = 0; + } + + + + if(r_led> (red_amb+256)) + { + calRS->R_led_step = (r_led - red_amb)/SPO2_CAL_INIT_LED_RED*3/4; //64 + r_led_temp = 1100*(hx3695_spo2_agc_red_idac+calRS->RED_AMBDAC)/calRS->R_led_step; + + if(r_led_temp>calRS->red_max_cur) + { + r_led_temp = calRS->red_max_cur; + } + calRS->R_LED = r_led_temp; + if(calRS->R_LED != calRS->red_max_cur) + { + calRS->R_LEDDAC = (hx3695_spo2_agc_red_idac*3)>>2; + } + else + { + calRS->R_LEDDAC = hx3695_spo2_agc_red_idac>>1; + } + } + if(ir_led1>(ir_amb1+256)) + { + calRS->IR_led_step1 = (ir_led1 - ir_amb1)/SPO2_CAL_INIT_LED_IR; //32 + ir_led_temp1 = 1300*(hx3695_spo2_agc_ir_idac + calRS->IR_AMBDAC1)/calRS->IR_led_step1; + + if(ir_led_temp1>calRS->ir_max_cur) + { + ir_led_temp1 = calRS->ir_max_cur; + } + calRS->IR_LED1 = ir_led_temp1; + if(calRS->IR_LED1 != calRS->ir_max_cur) + { + calRS->IR_LEDDAC1 = (hx3695_spo2_agc_ir_idac*3)>>2; + } + else + { + calRS->IR_LEDDAC1 = hx3695_spo2_agc_ir_idac>>1; + } + TYHX_LOG("calRS->R_IR_LED1: %d %d\r\n",calRS->R_LED,calRS->IR_LED1); + + } + if(g_led >g_amb + 256) + { + calRS->G_led_step = (g_led-g_amb)/(SPO2_CAL_INIT_LED_GREEN); + g_led_temp = 1300*(hx3695_spo2_agc_green_idac+calRS->GREEN_AMBDAC)/calRS->G_led_step; + if(g_led_temp>calRS->green_max_cur) + { + g_led_temp = calRS->green_max_cur; + } + calRS->G_LED = g_led_temp; + if(calRS->G_LED != calRS->green_max_cur) + { + calRS->G_LEDDAC = (hx3695_spo2_agc_green_idac*3)>>2; + } + else + { + calRS->G_LEDDAC = hx3695_spo2_agc_green_idac>>1; + } + } + calRS->G_RF = 6; + calRS->R_RF = 6; + calRS->IR_RF1 = 6; + calRS->flag = CAL_FLG_LED_DR|CAL_FLG_LED_DAC|CAL_FLG_AMB_DAC|CAL_FLG_RF; + calRS->state = sCalLed; + break; + + case sCalLed: + if(r_led>900000 && calRS->R_LEDDAC < 120) //110 + { + calRS->R_LEDDAC = calRS->R_LEDDAC+6; + } + + if(ir_led1>900000 && calRS->IR_LEDDAC1 < 120) //110 + { + calRS->IR_LEDDAC1 = calRS->IR_LEDDAC1+6; + } + + if(g_led>900000 && calRS->G_LEDDAC < 110) //110 + { + calRS->G_LEDDAC = calRS->G_LEDDAC+6; + } + + if(ir_led1 <= 900000 && r_led <= 900000 && g_led<=900000) + { + calRS->state = sCalLed2; + } + else if(calRS->R_LEDDAC>=120 || calRS->IR_LEDDAC1 >= 120 || calRS->G_LEDDAC >= 120) + { + calRS->state = sCalLed3; + } + else + { + calRS->state = sCalLed; + } + calRS->flag = CAL_FLG_LED_DAC; + break; + + case sCalLed2: + if(r_led > 650000 && calRS->R_LEDDAC < 120) + { + calRS->R_LEDDAC = calRS->R_LEDDAC+3; + } + else if(r_led <400000 && calRS->R_LEDDAC >= 3) + { + calRS->R_LEDDAC = calRS->R_LEDDAC-3; + } + else if(r_led<400000 && calRS->R_LEDDAC > 0) + { + calRS->R_LEDDAC = calRS->R_LEDDAC-1; + } + + if(ir_led1>650000 && calRS->IR_LEDDAC1 < 120) + { + calRS->IR_LEDDAC1 = calRS->IR_LEDDAC1+3; + } + else if(ir_led1<400000 && calRS->IR_LEDDAC1 >= 3) + { + calRS->IR_LEDDAC1 = calRS->IR_LEDDAC1-3; + } + else if(ir_led1 <400000 && calRS->IR_LEDDAC1 > 0) + { + calRS->IR_LEDDAC1 = calRS->IR_LEDDAC1 -1; + } + + if(g_led>650000 && calRS->G_LEDDAC < 120) + { + calRS->G_LEDDAC = calRS->G_LEDDAC+3; + } + else if(g_led<400000 && calRS->G_LEDDAC >= 3) + { + calRS->G_LEDDAC = calRS->G_LEDDAC-3; + } + else if(g_led<400000 && calRS->G_LEDDAC > 0) + { + calRS->G_LEDDAC = calRS->G_LEDDAC-1; + } + + if(ir_led1 <650000 && ir_led1 > 400000 && r_led<650000 && r_led>400000 && g_led<650000 && g_led>400000) +// if(ir_led1 <750000 && ir_led1 > 500000 && r_led<750000 && r_led>500000 ) + { + calRS->state = sCalFinish; + } +// else if(calR->R_LEDDAC >= 120 || calR->IR_LEDDAC1 >= 120 || calR->G_LEDDAC >= 120) + else if(calRS->R_LEDDAC >= 120 || calRS->IR_LEDDAC1 >= 120 ) + { + calRS->state = sCalLed3; + } + else + { + calRS->state = sCalLed2; + } + calRS->flag = CAL_FLG_LED_DAC; + break; + + case sCalLed3: + if(calRS->R_LEDDAC>=120) + { + calRS->R_LED = (calRS->R_LED*3)>>2; + } + if(calRS->IR_LEDDAC1>=120) + { + calRS->IR_LED1 = (calRS->IR_LED1*3)>>2; + } +// if(calR->G_LEDDAC>=120) +// { +// calR->G_LED = (calR->G_LED*3)>>2; +// } + calRS->flag = CAL_FLG_LED_DR; + calRS->state = sCalLed; + break; + + case sCalRfEnd: + calRS->state = sCalFinish; + break; + + default: + break; + + } +// AGC_LOG("AGC: R_cur=%d,G_cur=%d,Ir_cur=%d,ambDac=%d,R_Dac=%d,G_Dac=%d,Ir_Dac=%d,R_step=%d,G_step=%d,Ir_step=%d,state=%d\r\n",\ +// calR->R_LED,calR->G_LED,calR->IR_LED,calR->AMBDAC,calR->R_LEDDAC,calR->G_LEDDAC,calR->IR_LEDDAC,\ +// calR->R_led_step,calR->G_led_step,calR->IR_led_step,calR->state); + + TYHX_LOG("AGC:R_cur=%d, Ir_cur=%d,R_ambDac=%d, IR_ambDac=%d, R_Dac=%d,Ir_Dac=%d,R_step=%d,Ir_step=%d,state=%d \r\n",\ + calRS->R_LED,calRS->IR_LED1,calRS->RED_AMBDAC, calRS->IR_AMBDAC1, calRS->R_LEDDAC,calRS->IR_LEDDAC1,\ + calRS->R_led_step,calRS->IR_led_step1,calRS->state); +} + +SPO2_CAL_SET_T PPG_spo2_agc(void) +{ + int32_t green_amb_val, green_led_val, red_led_val, red_amb_val; + int32_t ir_led_val1, ir_amb_val1, ir_led_val2, ir_amb_val2; + + calReg_SPO2.work = false; + + if (!s_cal_state) + { + return calReg_SPO2; + } + +#ifdef INT_MODE + calReg_SPO2.int_cnt ++; + if(calReg_SPO2.int_cnt < 8) + { + return calReg_SPO2; + } + calReg_SPO2.int_cnt = 0; + hx3695_gpioint_cfg(false); +#endif + calReg_SPO2.work = true; + + hx3695_spo2_read_data(agc_buf); + + green_amb_val = (agc_buf[0]); // + agc_buf[2])>>1; + green_led_val = agc_buf[1]; + red_amb_val = (agc_buf[2]); // + agc_buf[2])>>1; + red_led_val = agc_buf[3]; + ir_amb_val1 = (agc_buf[4]); // + agc_buf[5])>>1; + ir_led_val1 = agc_buf[5]; + +// ir_amb_val2 = agc_buf[6]; +// ir_led_val2 = agc_buf[7]; + TYHX_LOG("cal_ch= %d,%d, %d,%d, %d,%d \r\n", green_amb_val,green_led_val, red_amb_val, red_led_val, ir_amb_val1, ir_led_val1); + + PPG_Spo2_Calibration_Routine(&calReg_SPO2, green_led_val,red_led_val, ir_led_val1, green_amb_val, red_amb_val, ir_amb_val1 ); + + if (calReg_SPO2.state == sCalFinish) + { + hx3695_spo2_set_mode(CAL_OFF); + if(spo2_wear_status == MSG_SPO2_NO_WEAR) + { + hx3695_spo2_low_power(); + + } + #if defined(TIMMER_MODE) + + #else + hx3695_gpioint_cfg(true); + #endif + } + else + { + hx3695_spo2_updata_reg(); +#if defined(INT_MODE) + hx3695_gpioint_cfg(true); +#endif + } +// TYHX_LOG("calReg_spo2.R_LED %d, ir_led %d \r\n",calReg_SPO2.R_LED,calReg_SPO2.IR_LED1); + return calReg_SPO2; +} + + +void hx3695_spo2_cal_init(void) +{ + uint16_t sample_rate = 200; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> + + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + + hx3695_write_reg(0x1b,0x91); //FIFO bypass mode enable old 0x10 + hx3695_write_reg(0x36,0x08); // phase4 convertion ready enable + + #if defined(INT_MODE) +// hx3695_write_reg(0x36,0x88); //phase8 phase4 convertion ready enable + hx3695_write_reg(0x38,0x01); + #endif + hx3695_write_reg(0x1b,0x91); + hx3695_delay_ms(5); + hx3695_write_reg(0x5c,0x02); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x5c,0x00); //Chip state machine work normal + hx3695_delay_ms(10); //Delay for reset time + + +} + + + +void hx3695_spo2_cal_off(void) +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> +// AGC_LOG("prf_clk_num =%d %d %d\r\n", hx3695_read_reg(0X2a), hx3695_read_reg(0X2b), hx3695_read_reg(0X2c)); + hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X41, data_avg_num<<4 | data_avg_num ); + hx3695_write_reg(0X42, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0x1b,0x91); //FIFO mode enable + hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable + + #if defined(INT_MODE) + hx3695_write_reg(0X33, 0x83); // int width + hx3695_write_reg(0x38,0x04); + #endif + + hx3695_write_reg(0x5c,0x02); //Chip reset + hx3695_delay_ms(5); //Delay for reset time + hx3695_write_reg(0x1b, 0x91); + hx3695_write_reg(0x5c,0x00); //Chip state machine work normal + hx3695_delay_ms(5); +// hx3695_brust_read_reg(0x22, fifo_data_buf, 3); + read_fifo_first_flg = 1; +// AGC_LOG("herehere %d,%d,%d \r\n",hx3695_read_reg(0X2a),hx3695_read_reg(0X2b),hx3695_read_reg(0X2c)); +} + +void hx3695_spo2_read_data(int32_t *s_buf) +{ + uint8_t databuf1[6] = {0}; + uint8_t databuf2[6] = {0}; + uint8_t databuf3[6] = {0}; + uint8_t databuf4[6] = {0}; + + hx3695_brust_read_reg(0x03, databuf1, 6); + + hx3695_brust_read_reg(0x09, databuf2, 6); + hx3695_delay_ms(5); + hx3695_brust_read_reg(0x0f, databuf3, 6); + hx3695_brust_read_reg(0x15, databuf4, 6); + hx3695_delay_ms(5); + + s_buf[0] = ((databuf1[0])|(databuf1[1]<<8)|(databuf1[2]<<16)); + s_buf[1] = ((databuf1[3])|(databuf1[4]<<8)|(databuf1[5]<<16)); + s_buf[2] = ((databuf2[0])|(databuf2[1]<<8)|(databuf2[2]<<16)); + s_buf[3] = ((databuf2[3])|(databuf2[4]<<8)|(databuf2[5]<<16)); + s_buf[4] = ((databuf3[0])|(databuf3[1]<<8)|(databuf3[2]<<16)); + s_buf[5] = ((databuf3[3])|(databuf3[4]<<8)|(databuf3[5]<<16)); + s_buf[6] = ((databuf4[0])|(databuf4[1]<<8)|(databuf4[2]<<16)); + s_buf[7] = ((databuf4[3])|(databuf4[4]<<8)|(databuf4[5]<<16)); + hx3695_delay_ms(5); + +// return 1; +} + + + + +void hx3695_spo2_low_power(void) +{ + uint16_t sample_rate = 25; /*config the data rate of chip alps2_fm ,uint is Hz*/ + uint8_t data_avg_num = 0; /* 0 = 1 ; 1 = 2; 2 =4 ; 3 =8 ; 4 =16 ;*/ + uint32_t prf_clk_num = 32000/sample_rate; /*period in clk num, num = Fclk/fs */ + + uint8_t phase1_led_en = 1; + uint8_t phase2_led_en = 1; + uint8_t phase3_led_en = 1; + uint8_t phase4_led_en = 1; + uint8_t phase5_led_en = 1; + uint8_t phase6_led_en = 1; + uint8_t phase7_led_en = 1; + uint8_t phase8_led_en = 1; + + uint8_t phase1_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase2_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase3_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase4_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase5_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase6_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase7_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + uint8_t phase8_offset_idac = 0; /* 0~127 = 0 ~ 32ua , step = 0.25ua */ + + uint8_t phase1_ldr_cur = 0; + uint8_t phase2_ldr_cur = 0; + uint8_t phase3_ldr_cur = 0; + uint8_t phase4_ldr_cur = 0; + uint8_t phase5_ldr_cur = 0; + uint8_t phase6_ldr_cur = 0; + uint8_t phase7_ldr_cur = 0; + uint8_t phase8_ldr_cur = 32; + + + uint8_t phase1_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase2_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase3_tia_res = 0; + uint8_t phase4_tia_res = 0; + uint8_t phase5_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase6_tia_res = 0; /* 0= 10K; 1= 20k; 2= 50k; 3= 100k; 4= 150k; 5= 200k; 6= 500k; 7= 1M*/ + uint8_t phase7_tia_res = 0; + uint8_t phase8_tia_res = 0; + + uint8_t phase1_mux_sel = 0; + uint8_t phase2_mux_sel = 1; + uint8_t phase3_mux_sel = 2; /* sel phase3*/ + uint8_t phase4_mux_sel = 3; /* sel phase4*/ + uint8_t phase5_mux_sel = 4; + uint8_t phase6_mux_sel = 5; + uint8_t phase7_mux_sel = 6; /* sel phase7*/ + uint8_t phase8_mux_sel = 7; /* sel phase8*/ + + uint8_t led_on_time = 2; /* 0 = 32clk=8us ; 1 = 64clk=16us; 2=128clk=32us ; 3 = 256clk=64us ; + 4 = 512clk=128us ; 5 = 1024clk=256us; 6= 2048clk=512us; 7 = 4096clk=1024us */ +// hx3695_write_reg(0X6a, 0X0f); //rest int + hx3695_delay_ms(10); + hx3695_write_reg(0X2a, (uint8_t)prf_clk_num); // prf bit<7:0> + hx3695_write_reg(0X2b, (uint8_t)(prf_clk_num>>8)); // prf bit<15:8> + hx3695_write_reg(0X2c, (uint8_t)(prf_clk_num>>16)); // prf bit<23:16> +// hx3695_write_reg(0X3f, data_avg_num<<4 | data_avg_num ); +// hx3695_write_reg(0X40, data_avg_num<<4 | data_avg_num ); + + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase1_tia_res)); + hx3695_write_reg(0X45, phase1_ldr_cur); +// hx3695_write_reg(0X70, phase1_ldr2_cur); + hx3695_write_reg(0X48, phase1_offset_idac); + + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase2_tia_res)); + hx3695_write_reg(0X45, phase2_ldr_cur); + hx3695_write_reg(0X48, phase2_offset_idac); + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase3_tia_res)); + hx3695_write_reg(0X45, phase3_ldr_cur); + hx3695_write_reg(0X48, phase3_offset_idac); + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase4_tia_res)); + hx3695_write_reg(0X45, phase4_ldr_cur); + hx3695_write_reg(0X48, phase4_offset_idac); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase4_tia_res)); + hx3695_write_reg(0X45, phase5_ldr_cur); + hx3695_write_reg(0X48, phase5_offset_idac); + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase6_tia_res)); + hx3695_write_reg(0X45, phase6_ldr_cur); + hx3695_write_reg(0X48, phase6_offset_idac); + + hx3695_write_reg(0X43, phase7_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase7_tia_res)); + hx3695_write_reg(0X45, phase7_ldr_cur); + hx3695_write_reg(0X48, phase7_offset_idac); + + hx3695_write_reg(0X43, phase8_mux_sel); + hx3695_write_reg(0X44, (0x40 | phase8_tia_res)); + hx3695_write_reg(0X45, phase8_ldr_cur); + hx3695_write_reg(0X48, phase8_offset_idac); + + + + hx3695_write_reg(0X30, phase8_led_en<<7 | phase7_led_en<<6 | phase6_led_en<<5 | phase5_led_en<<4 | phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en); + hx3695_write_reg(0X72, phase8_led_en<<7 | phase7_led_en<<6 | phase6_led_en<<5 | phase5_led_en<<4 | phase4_led_en<<3 | phase3_led_en<<2 | phase2_led_en<<1 | phase1_led_en); + hx3695_write_reg(0X31, led_on_time<<4 | (0x0f&hx3695_read_reg(0X31))); + + hx3695_write_reg(0X6a, 0X0f); + + + #ifdef INT_MODE + hx3695_write_reg(0X1c,0x14); // fifo almostfull cfg ,max=0x40; + hx3695_write_reg(0x1b,0x91); //FIFO bypass mode enable + hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable + + #else + hx3695_write_reg(0x1b,0x91); //FIFO bypass mode enable + hx3695_write_reg(0x36,0x00); //phase3 convertion ready disable + + #endif + + hx3695_write_reg(0x5c,0x02); //Chip reset + hx3695_delay_ms(5); //Delay for reset time +// hx3695_write_reg(0x1b, 0x10); +// hx3695_delay_ms(5); +// hx3695_write_reg(0x1b, 0x90); + hx3695_write_reg(0x5c,0x00); //Chip state machine work normal + + hx3695_delay_ms(5); + + calReg_SPO2.G_LED = phase2_ldr_cur; + calReg_SPO2.G_LEDDAC = phase2_offset_idac; + calReg_SPO2.R_LED = phase4_ldr_cur; + calReg_SPO2.R_LEDDAC = phase4_offset_idac; + + calReg_SPO2.IR_LED1 = phase6_ldr_cur; + calReg_SPO2.IR_LEDDAC1 = phase6_offset_idac; +// hx3695_brust_read_reg(0x22, fifo_data_buf, 3); + read_fifo_first_flg = 1; + AGC_LOG(" chip1 go to low power mode \r\n" ); +} + + + +void hx3695_spo2_updata_reg(void) +{ + uint8_t phase1_mux_sel = 0; + uint8_t phase2_mux_sel = 1; + uint8_t phase3_mux_sel = 2; + uint8_t phase4_mux_sel = 3; + uint8_t phase5_mux_sel = 4; + uint8_t phase6_mux_sel = 5; + uint8_t phase7_mux_sel = 6; + uint8_t phase8_mux_sel = 7; + if (calReg_SPO2.flag & CAL_FLG_LED_DR) + { + //AGC_LOG("CAL_FLG_LED_DR\r\n"); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X45, calReg_SPO2.G_LED); +// TYHX_LOG("R_LED:%d \r\n",hx3695_read_reg(0X45)); + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X45, calReg_SPO2.R_LED); +// TYHX_LOG("IR_LED:%d \r\n",hx3695_read_reg(0X45)); + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X45, calReg_SPO2.IR_LED1); + } + + if (calReg_SPO2.flag & CAL_FLG_LED_DAC) + { + //AGC_LOG("CAL_FLG_LED_DAC\r\n"); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X48, calReg_SPO2.G_LEDDAC); + + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X48, calReg_SPO2.R_LEDDAC); + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X48, calReg_SPO2.IR_LEDDAC1); + // AGC_LOG("IR_LEDDAC:%d \r\n",hx3695_read_reg(0X47)); + + } + + if (calReg_SPO2.flag & CAL_FLG_AMB_DAC) + { + //AGC_LOG("CAL_FLG_AMB_DAC\r\n"); + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X48, calReg_SPO2.GREEN_AMBDAC); + + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X48, calReg_SPO2.RED_AMBDAC); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X48, calReg_SPO2.IR_AMBDAC1); + +// hx3695_write_reg(0X43, phase6_mux_sel); +// hx3695_write_reg(0X48, calReg_SPO2.IR_AMBDAC1); + + } + + if (calReg_SPO2.flag & CAL_FLG_RF) + { + //AGC_LOG("CAL_FLG_RF\r\n"); + hx3695_write_reg(0X43, phase1_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_SPO2.G_RF)); + //AGC_LOG("RF:%x \r\n",hx3695_read_reg(0X44)); +// hx3695_write_reg(0X44, (hx3695_read_reg(0X44)| 0x07)&(calReg_SPO2.R_RF|0xff)); + hx3695_write_reg(0X43, phase2_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_SPO2.G_RF)); + //AGC_LOG("RF:%x \r\n",hx3695_read_reg(0X44)); +// hx3695_write_reg(0X44, (hx3695_read_reg(0X44)| 0x07)&(calReg_SPO2.G_RF|0xff)); + hx3695_write_reg(0X43, phase3_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_SPO2.R_RF)); + //AGC_LOG("RF:%x \r\n",hx3695_read_reg(0X44)); +// hx3695_write_reg(0X44, (hx3695_read_reg(0X44)| 0x07)&(calReg_SPO2.R_RF|0xff)); + hx3695_write_reg(0X43, phase4_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_SPO2.R_RF)); + //AGC_LOG("RF:%x \r\n",hx3695_read_reg(0X44)); +// hx3695_write_reg(0X44, (hx3695_read_reg(0X44)| 0x07)&(calReg_SPO2.IR_RF|0xff)); + +// hx3695_write_reg(0X43, phase3_mux_sel); +// hx3695_write_reg(0X44, (0x40 | calReg_SPO2.R_RF)); +// hx3695_write_reg(0X43, phase4_mux_sel); +// hx3695_write_reg(0X44, (0x40 | calReg_SPO2.R_RF)); + + hx3695_write_reg(0X43, phase5_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_SPO2.IR_RF1)); + + hx3695_write_reg(0X43, phase6_mux_sel); + hx3695_write_reg(0X44, (0x40 | calReg_SPO2.IR_RF1)); + + } + +} +void hx3695_spo2_set_mode(uint8_t mode_cmd) +{ + switch (mode_cmd) + { + case PPG_INIT: + hx3695_spo2_ppg_init(); +#if defined(TIMMER_MODE) + hx3695_320ms_timer_cfg(true); +#if defined(GSEN_40MS_TIMMER) + hx3695_40ms_timer_cfg(true); +#endif +#else + hx3695_gpioint_cfg(true); +#endif + s_ppg_state = 1; + AGC_LOG("ppg init mode\r\n"); + break; + + case PPG_OFF: + hx3695_ppg_off(); + s_ppg_state = 0; + AGC_LOG("ppg off mode\r\n"); + break; + + case PPG_LED_OFF: + hx3695_spo2_low_power(); + + s_ppg_state = 0; + AGC_LOG("ppg led off mode\r\n"); + break; + + case CAL_INIT: + Init_Spo2_PPG_Calibration_Routine(&calReg_SPO2,64); + hx3695_spo2_cal_init(); + hx3695_spo2_updata_reg(); +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(true); +#endif +#endif + s_cal_state = 1; + AGC_LOG("cal init mode\r\n"); + break; + + case RECAL_INIT: + Restart_Spo2_PPG_Calibration_Routine(&calReg_SPO2); + hx3695_spo2_cal_init(); + hx3695_spo2_updata_reg(); +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(true); +#endif +#endif + s_cal_state = 1; + AGC_LOG("recal init mode\r\n"); + break; + + case CAL_OFF: +#if defined(TIMMER_MODE) +#if defined(GSEN_40MS_TIMMER) +#else + hx3695_40ms_timer_cfg(false); +#endif +#endif + hx3695_spo2_cal_off(); + s_cal_state = 0; + AGC_LOG("cal off mode\r\n"); + break; + + default: + break; + } +} + +SENSOR_ERROR_T hx3695_spo2_enable(void) +{ + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return SENSOR_OP_FAILED; + } + + AGC_LOG("hx3695 check id success!\r\n"); + + if (s_ppg_state) + { + AGC_LOG("ppg already on!\r\n"); + return SENSOR_OP_FAILED; + } + + if(!tyhx_spo2_alg_open()) + { + AGC_LOG("spo2 alg open fail,or dynamic ram not enough!\r\n"); + return SENSOR_OP_FAILED; + } + spo2_wear_status = MSG_SPO2_NO_WEAR; + spo2_wear_status_pre = MSG_SPO2_NO_WEAR; + hx3695_spo2_set_mode(PPG_INIT); + + AGC_LOG("hx3695 enable!\r\n"); + + return SENSOR_OK; +} + +SENSOR_ERROR_T hx3695_hrspo2_enable(void) +{ + if (!hx3695_chip_check()) + { + AGC_LOG("hx3695 check id failed!\r\n"); + return SENSOR_OP_FAILED; + } + + AGC_LOG("hx3695 check id success!\r\n"); + + if (s_ppg_state) + { + AGC_LOG("ppg already on!\r\n"); + return SENSOR_OP_FAILED; + } + + if(!tyhx_spo2_alg_open()) + { + AGC_LOG("spo2 alg open fail,or dynamic ram not enough!\r\n"); + return SENSOR_OP_FAILED; + } + if(!tyhx_hrs_alg_open()) + { + AGC_LOG("spo2 alg open fail,or dynamic ram not enough!\r\n"); + return SENSOR_OP_FAILED; + } + spo2_wear_status = MSG_SPO2_NO_WEAR; + spo2_wear_status_pre = MSG_SPO2_NO_WEAR; + hx3695_spo2_set_mode(PPG_INIT); + + AGC_LOG("hx3695 enable!\r\n"); + + return SENSOR_OK; +} + +void hx3695_spo2_disable(void) +{ +#if defined(TIMMER_MODE) + hx3695_320ms_timer_cfg(false); + hx3695_40ms_timer_cfg(false); +#elif defined(INT_MODE) + hx3695_gpioint_cfg(false); +#endif + hx3695_spo2_set_mode(PPG_OFF); + s_ppg_state = 0; + s_cal_state = 0; + tyhx_spo2_alg_close(); + + AGC_LOG("hx3695 disable!\r\n"); +} + +void hx3695_spo2_data_reset(void) +{ + s_ppg_state = 0; + s_cal_state = 0; + tyhx_spo2_alg_close(); +} + +spo2_wear_msg_code_t hx3695_spo2_get_wear_status(void) +{ + return spo2_wear_status; +} + +SPO2_CAL_SET_T get_spo2_agc_status(void) +{ + SPO2_CAL_SET_T cal; + +// cal.flag = calReg_SPO2.flag; +// cal.int_cnt = calReg_SPO2.int_cnt; +// cal.G_LED = calReg_SPO2.G_LED; +// cal.R_LED = calReg_SPO2.R_LED; +// cal.IR_LED1 = calReg_SPO2.IR_LED1; +// cal.R_LEDDAC = calReg_SPO2.R_LEDDAC; +// cal.IR_LEDDAC1 = calReg_SPO2.IR_LEDDAC1; +// cal.G_LEDDAC = calReg_SPO2.G_LEDDAC; +// cal.AMBDAC = calReg_SPO2.AMBDAC; +// cal.G_RF = calReg_SPO2.G_RF; +// cal.R_RF = calReg_SPO2.R_RF; +// cal.IR_RF1 = calReg_SPO2.IR_RF1; +// cal.G_led_step = calReg_SPO2.G_led_step; +// cal.R_led_step = calReg_SPO2.R_led_step; +// cal.IR_led_step1 = calReg_SPO2.IR_led_step1; +// cal.state = calReg_SPO2.state; +// cal.green_idac = calReg_SPO2.green_idac; +// cal.red_idac = calReg_SPO2.red_idac; +// cal.ir_idac1 = calReg_SPO2.ir_idac1; + + cal = calReg_SPO2; + + return cal; +} + +//void hx3695_spo2_read_fifo_data(uint8_t read_fifo_size,int32_t *buf) +//{ +// uint8_t data_flg = 127; +// int32_t data; +// uint8_t databuf[3]; +// uint8_t ii=0; +// uint8_t data_size_all = 0; +// data_size_all = hx3695_read_fifo_size(); +// for(ii=0; ii>5; +// data = (int32_t)(databuf[0]|(databuf[1]<<8)|((databuf[2]&0x1f)<<16)); + +// if(ii==0) +// { +// if(data_flg ==3) +// { +// ii=3; +// buf[0] = 0; +// buf[1] = 0; +// buf[2] = 0; +// } +// if(data_flg ==2) +// { +// ii=2; +// buf[0] = 0; +// buf[1] = 0; +// } +// if(data_flg ==1) +// { +// ii=1; +// buf[0] = 0; +// } +// } + +// if(data_flg == 0) +// { +// buf[ii]= data; +// } +// else if(data_flg == 1) +// { +// buf[ii]= data; +// } +// else if(data_flg == 2) +// { +// buf[ii]= data; +// } +// else if(data_flg == 3) +// { +// buf[ii]= data; +// } +// } + +// if(data_size_all==64) +// { +// hx3695_write_reg(0X13, 0x30); +// hx3695_delay_ms(5); +// hx3695_write_reg(0X13, 0x31); +// hx3695_delay_ms(5); +// } +//} + +uint8_t hx3695_spo2_read(spo2_sensor_data_t * s_dat) +{ + int32_t Red_src_data; + int32_t Ir_src_data1, Ir_src_data2; + int32_t Green_src_data; + int32_t Ir_wear_value; + bool recal = false; + uint8_t size = 0; + uint8_t size_byte = 0; + uint8_t i; + int32_t *red_buf = &(s_dat->red_data[0]); + int32_t *green_buf = &(s_dat->green_data[0]); + int32_t *ir_buf1 = &(s_dat->ir_data1[0]); + int32_t *ir_buf2 = &(s_dat->ir_data2[0]); + int32_t *s_buf = &(s_dat->s_buf[0]); + s_dat->agc_green = calReg_SPO2.G_LED; + s_dat->agc_red = calReg_SPO2.R_LED; + s_dat->agc_ir1 = calReg_SPO2.IR_LED1; + s_dat->agc_ir2 = calReg_SPO2.IR_LED2; + uint8_t data_count = 0; + //AGC_LOG("s_ppg_state: %d,s_cal_state: %d\r\n",s_ppg_state,s_cal_state); + if (!s_ppg_state || s_cal_state) + { + return 0; + } + + data_count = hx3695_read_fifo_data(s_buf,spo2_phase_num,1); + s_dat->count = data_count; + + hx3695_spo2_read_data( agc_buf ); + Ir_wear_value = agc_buf[7]- agc_buf[6]; + TYHX_LOG("Ir_wear_value: %d \r\n",Ir_wear_value); + for (i=0; i 750000)||( Red_src_data < 400000 || Red_src_data > 750000) +// ||(Ir_src_data1 < 400000 ||Ir_src_data1 > 750000)) + if((agc_buf[1] < 300000 ||agc_buf[1] > 750000)||( agc_buf[3] < 300000 || agc_buf[3] > 750000) + ||(agc_buf[5] < 300000 ||agc_buf[5] > 750000)) + + { + recal = true; + if(spo2_wear_status==MSG_SPO2_NO_WEAR) + { + recal = false; + } + } + green_buf[i] = Green_src_data; + red_buf[i] = Red_src_data; + ir_buf1[i] = Ir_src_data1; + ir_buf2[i] = Ir_src_data2; + + //AGC_LOG("G_LEDDAC: %d,R_LEDDAC: %d\r\n", calReg_SPO2.R_LEDDAC,cal.R_LEDDAC); + //DEBUG_PRINTF(0,"%d/%d %d %d %d %d %d %d %d %d\r\n" ,1+i,data_count, + // green_buf[i],red_buf[i],ir_buf[i],s_buf[i*4],s_buf[i*4+1],s_buf[i*4+2],s_buf[i*4+3],spo2_wear_status); + +// AGC_LOG("fifo_data: %d/%d %d %d %d %d\r\n", i+1,data_count,s_buf[i*4], + // s_buf[i*4+1],s_buf[i*4+2],s_buf[i*4+3]); + + + if(spo2_wear_status==MSG_SPO2_WEAR) + { + if(hx3695_spo2_check_unwear(Ir_wear_value)) //Ir_src_data2 + { + return 0; + } + } + else + { + if(hx3695_spo2_check_wear(Ir_wear_value)) + { + return 0; + } + } + } + + if (recal) + //if (0) + { + cal_delay--; + if (cal_delay <= 0) + { + cal_delay = SPO2_CAL_DELAY_COUNT; + hx3695_spo2_set_mode(RECAL_INIT); + } + } + else + { + cal_delay = SPO2_CAL_DELAY_COUNT; + } + + return 1; +} + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_spo2_agc.h b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_spo2_agc.h new file mode 100644 index 000000000..db07398de --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_spo2_agc.h @@ -0,0 +1,122 @@ +#ifndef _HX3695_SPO2_AGC_H_ +#define _HX3695_SPO2_AGC_H_ +#include +#include +#include "hx3695.h" + +#define CAL_FLG_LED_DR 0x01 +#define CAL_FLG_LED_DAC 0x02 +#define CAL_FLG_AMB_DAC 0x04 +#define CAL_FLG_RF 0x08 + +#define SPO2_CAL_INIT_LED_RED 32 +#define SPO2_CAL_INIT_LED_IR 32 +#define SPO2_CAL_INIT_LED_GREEN 64 + +#define SPO2_CAL_DELAY_COUNT 8 +#define SPO2_NO_TOUCH_CHECK_NUM 2 + + +//typedef enum { +// sCalStart, +// sCalLedCur, +// sCalLed, +// sCalLed2, +// sCalLed3, +// sCalFinish, +//} SPO2_STATE_T; + +typedef enum { + + sCalStart, + sCalStart1, + sCalLed, + sCalLed2, + sCalLed3, + sCalRf, + sCalRfEnd, + sCalFinish, +} SPO2_STATE_T; + +typedef struct { + uint8_t count; + int32_t red_data[16]; + int32_t green_data[16]; + int32_t ir_data1[16]; + int32_t ir_data2[16]; + int32_t s_buf[64]; +// int32_t red_amb_buf[64]; + + uint8_t agc_green; + uint8_t agc_red; + uint8_t agc_ir1; + uint8_t agc_ir2; + +}spo2_sensor_data_t; + +typedef enum { + MSG_SPO2_NO_WEAR, + MSG_SPO2_WEAR +} spo2_wear_msg_code_t; + +typedef struct { + uint8_t flag; + bool work; + uint8_t int_cnt; + uint8_t cur255_cnt; + uint8_t green_idac; + uint8_t red_idac; + uint8_t ir_idac1; + uint8_t ir_idac2; + uint16_t G_LED; + uint16_t R_LED; + uint16_t IR_LED1; + uint16_t IR_LED2; + uint8_t G_LEDDAC; + uint8_t R_LEDDAC; + uint8_t IR_LEDDAC1; + uint8_t IR_LEDDAC2; + uint8_t AMBDAC; + uint8_t GREEN_AMBDAC; + uint8_t RED_AMBDAC; + uint8_t IR_AMBDAC1; + uint8_t IR_AMBDAC2; + uint8_t G_RF; + uint8_t R_RF; + uint8_t IR_RF1; + uint8_t IR_RF2; + uint32_t G_led_step; + uint32_t R_led_step; + uint32_t IR_led_step1; + uint32_t IR_led_step2; + uint8_t state; + uint8_t green_max_cur; + uint8_t red_max_cur; + uint8_t ir_max_cur; +} SPO2_CAL_SET_T; + +void Init_Spo2_PPG_Calibration_Routine(SPO2_CAL_SET_T *calR,uint8_t led); +void Restart_spo2_PPG_Calibration_Routine(SPO2_CAL_SET_T *calR); +//void PPG_Spo2_Calibration_Routine(SPO2_CAL_SET_T *calR, int32_t g_led, int32_t r_led, int32_t amb, int32_t ir_led); +//void PPG_Spo2_Calibration_Routine(SPO2_CAL_SET_T *calRS, int32_t r_led, int32_t ir_led1, int32_t red_amb, int32_t ir_amb1); +void PPG_Spo2_Calibration_Routine(SPO2_CAL_SET_T *calRS, int32_t g_led, int32_t r_led, int32_t ir_led1, int32_t g_amb, int32_t red_amb, int32_t ir_amb1); + +void hx3695_spo2_cal_init(void); +void hx3695_spo2_cal_off(void); +void hx3695_spo2_read_data(int32_t *s_buf); +void hx3695_spo2_low_power(void); +void hx3695_spo2_normal_power(void); +void hx3695_spo2_updata_reg(void); +void hx3695_spo2_set_mode(uint8_t mode_cmd); +SENSOR_ERROR_T hx3695_spo2_enable(void); +void hx3695_spo2_disable(void); +spo2_wear_msg_code_t hx3695_spo2_get_wear_status(void); +uint8_t hx3695_spo2_read(spo2_sensor_data_t * s_dat); +bool hx3695_spo2_check_unwear(int32_t infrared_data); +bool hx3695_spo2_check_wear(int32_t infrared_data); +SPO2_CAL_SET_T get_spo2_agc_status(void); +SPO2_CAL_SET_T PPG_spo2_agc(void); +void hx3695_spo2_data_reset(void); +void hx3695_spo2_read_data(int32_t *s_buf); + +#endif diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/libhx3695.a b/code/sdk/drivers/peripheral/ppg/hx3695/libhx3695.a new file mode 100644 index 000000000..4ef4b515d Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/hx3695/libhx3695.a differ diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrs_alg.h b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrs_alg.h new file mode 100644 index 000000000..b693581dd --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrs_alg.h @@ -0,0 +1,112 @@ +//vesion3.1.35 +#ifndef _TYHX_HRS_ALG_H_ +#define _TYHX_HRS_ALG_H_ + +#include +#if 0 +/* portable 8-bit unsigned integer */ +typedef unsigned char uint8_t; +/* portable 8-bit signed integer */ +typedef signed char int8_t; +/* portable 16-bit unsigned integer */ +typedef unsigned short int uint16_t; +/* portable 16-bit signed integer */ +typedef signed short int int16_t; +/* portable 32-bit unsigned integer */ +typedef unsigned int uint32_t; +/* portable 32-bit signed integer */ +typedef signed int int32_t; +#endif +#ifndef bool +#define bool unsigned char +#endif + +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif + +#ifdef HRS_ALG_LIB + +typedef enum { + NORMAL_MODE, + RIDE_MODE, + WALK_MODE, + JUMP_MODE, + ALLDAY_HR_MODE, + HIGH_POW_MODE +} hrs_sports_mode_t; + +typedef enum { + MSG_HRS_ALG_NOT_OPEN, + MSG_HRS_ALG_OPEN, + MSG_HRS_READY, + MSG_HRS_ALG_TIMEOUT +} hrs_alg_msg_code_t; + +typedef enum { + MSG_LIVING_INITIAL, + MSG_LIVING_TRUE, + MSG_LIVING_FAIL +} living_msg_code_t; + +typedef struct { + hrs_alg_msg_code_t hrs_alg_status; + living_msg_code_t living_status; + uint32_t data_cnt; + uint8_t hr_result; + uint16_t cal_result; + uint8_t hr_result_qual; + uint32_t hr_result_std; +} hrs_results_t; + +#ifdef BP_CUSTDOWN_ALG_LIB +typedef enum { + MSG_BP_ALG_NOT_OPEN = 0x01, + MSG_BP_NO_TOUCH = 0x02, + MSG_BP_PPG_LEN_TOO_SHORT = 0x03, + MSG_BP_READY = 0x04, + MSG_BP_ALG_TIMEOUT = 0x05, + MSG_BP_SETTLE = 0x06 +} bp_msg_code_t; + +typedef struct { + uint8_t age; + uint8_t height; + uint8_t weight; + uint8_t gender; + uint8_t ref_sbp; + uint8_t ref_dbp; +} bp_exinf_t; + +typedef struct { + bp_msg_code_t bp_alg_status; + uint8_t sbp; + uint8_t dbp; + uint32_t data_cnt; + uint8_t hr_result; + bool object_flg; +} bp_results_t; + +void tyhx_bp_set_exinf(uint8_t age, uint8_t height, uint8_t weight, uint8_t gender, uint8_t ref_sbp, uint8_t ref_dbp); +void tyhx_bp_age_fn(uint8_t hr_result, bp_exinf_t body_s); +void tyhx_restart_bp_cal(void); +bp_results_t tyhx_alg_get_bp_results(void); +#endif //BP_CUSTDOWN_ALG_LIB + +bool tyhx_hrs_alg_open(void); +bool tyhx_hrs_alg_open_deep(void); +void tyhx_hrs_alg_close(void); +bool tyhx_hrs_alg_send_data(int32_t *new_raw_data,uint8_t dat_len, int16_t *gsen_data_x, int16_t *gsen_data_y, int16_t *gsen_data_z, uint8_t green_offset); +bool tyhx_hrs_alg(int32_t new_raw_data, int16_t gsen_data_x, int16_t gsen_data_y, int16_t gsen_data_z, uint8_t offset); +bool tyhx_motion_pedometer(int16_t gsen_data_x, int16_t gsen_data_y, int16_t gsen_data_z); +hrs_results_t tyhx_hrs_alg_get_results(void); +void tyhx_hrs_set_alg_para(hrs_sports_mode_t sports_mode, uint16_t static_thre_val, uint8_t gsen_fun_lv_val); +void tyhx_hrs_set_living(uint8_t mode, uint8_t qu_thre, uint8_t st_thre); +#endif //HRS_ALG_LIB + +#endif + + diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrs_custom.h b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrs_custom.h new file mode 100644 index 000000000..de67fcb7c --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrs_custom.h @@ -0,0 +1,82 @@ +#ifndef __TYHX_HRS_CUSTOM_H__ +#define __TYHX_HRS_CUSTOM_H__ + +#include "debug_print.h" +#include "platform_core.h" +typedef struct { + int32_t leak_green; + int32_t leak_red; + int32_t leak_ir; + int32_t card_green; + int32_t card_red; + int32_t card_ir; + int32_t hr_living; + int32_t hr_living_qu; + int32_t hr_living_std; + int32_t lastesthrs; + int32_t lastestspo2; + int32_t lastesthrv; + int32_t wearstatus; +} FT_CUSTOM_RESULTS_t; + +extern FT_CUSTOM_RESULTS_t hrsresult; +#define TYHX_DEBUG + +#ifdef TYHX_DEBUG +#define TYHX_LOG(fmt, ...) \ + do { \ + PRINT(fmt"\r\n", ##__VA_ARGS__); \ + } while (0) +#else +#define TYHX_LOG(ftm, ...) +#endif + +#define TYHX_ERROR(x, ...) \ + do { \ + PRINT("[ERROR]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + +#define TYHX_WARNING(x, ...) \ + do { \ + PRINT("[WARNING]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } while (0) + + +#define CHIP_HX3695 + + +#define HX3695_I2C_BUS I2C_BUS_2 +#define HX3695_I2C_DEV_8ADDR 0X44 +#define HX3695_I2C_TIME_MAX 3 + +// us 延时函数, 客户需填写 +void tyhx_delay_us(uint32_t us); +void tyhx_delay_ms(uint32_t ms); + +// i2c 写函数, 客户需填写, 地址0x44(7bit) +uint32_t tyhx_write_reg( uint8_t reg_addr, uint8_t data); + +// i2c 读函数, 客户需填写 +uint32_t tyhx_read_regs( uint8_t reg_addr,uint8_t *readbuf,uint8_t readlen); + +#define TYHX_TIMER_40MS 40 +#define TYHX_TIMER_320MS 320 + +bool tyhx_timer_start(uint32_t ms); +bool tyhx_timer_stop(uint32_t ms); + +uint32_t tyhx_suspend(void); +uint32_t tyhx_resume(void); + + +uint32_t tyhx_poweron(void); +uint32_t tyhx_poweroff(void); + + +extern void hx3695_hrs_disable(void); +extern void hx3695_hrv_disable(void); +extern void hx3695_spo2_disable(void); + + +void readFifoByHrsModule(void); +#endif //__TYHX_HRS_CUSTOM_H__ \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrv_alg.h b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrv_alg.h new file mode 100644 index 000000000..116e27889 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_hrv_alg.h @@ -0,0 +1,64 @@ +#ifndef _TYHX_HRV_ALG_H_ +#define _TYHX_HRV_ALG_H_ +#endif + +#include +#if 0 +/* portable 8-bit unsigned integer */ +typedef unsigned char uint8_t; +/* portable 8-bit signed integer */ +typedef signed char int8_t; +/* portable 16-bit unsigned integer */ +typedef unsigned short int uint16_t; +/* portable 16-bit signed integer */ +typedef signed short int int16_t; +/* portable 32-bit unsigned integer */ +typedef unsigned int uint32_t; +/* portable 32-bit signed integer */ +typedef signed int int32_t; +#endif +#ifndef bool +#define bool unsigned char +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif + +#define HRV_GLITCH_THRES 20000 +#define HRV_GSEN_POW_THRE 150 + +#ifdef HRV_ALG_LIB + +typedef enum { + MSG_HRV_ALG_NOT_OPEN, + MSG_HRV_ALG_OPEN, + MSG_HRV_READY, + MSG_HRV_ALG_TIMEOUT, +} hrv_alg_msg_code_t; + +typedef struct { + hrv_alg_msg_code_t hrv_alg_status; + uint32_t data_cnt; + uint8_t hrv_result; + uint32_t hrv_peak; + uint8_t spirit_pressure; + uint8_t p_m; + uint8_t screen_up; + uint8_t motion; + uint8_t signal_quality; +} hrv_results_t; + + +void tyhx_hrv_alg(int32_t new_raw_data); +bool tyhx_hrv_alg_open(void); +bool tyhx_hrv_alg_open_deep(void); +void tyhx_hrv_alg_close(void); +void kfft(double *pr,double *pi,int n,int k,double *fr,double *fi); + +hrv_results_t tyhx_hrv_alg_send_data(int32_t new_raw_data, int32_t green_data_als, int32_t infrared_data); +hrv_results_t tyhx_hrv_alg_send_bufdata(int32_t *new_raw_data, uint8_t count, int16_t *gsen_data_x, int16_t *gsen_data_y, int16_t *gsen_data_z); +#endif //HRV_ALG_LIB + diff --git a/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_spo2_alg.h b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_spo2_alg.h new file mode 100644 index 000000000..e330cc6f0 --- /dev/null +++ b/code/sdk/drivers/peripheral/ppg/hx3695/tyhx_spo2_alg.h @@ -0,0 +1,165 @@ +#ifndef _SPO2_ALG_H_ +#define _SPO2_ALG_H_ +#endif +#include + +//version:3.3.17 + +//#include "tyhx_spo2_alg_para.h" + +#if 0 +/* portable 8-bit unsigned integer */ +typedef unsigned char uint8_t; +/* portable 8-bit signed integer */ +typedef signed char int8_t; +/* portable 16-bit unsigned integer */ +typedef unsigned short int uint16_t; +/* portable 16-bit signed integer */ +typedef signed short int int16_t; +/* portable 32-bit unsigned integer */ +typedef unsigned int uint32_t; +/* portable 32-bit signed integer */ +typedef signed int int32_t; +#endif + +#ifndef bool +#define bool unsigned char +#endif + +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif + + +#ifdef SPO2_ALG_LIB + +typedef enum { + MSG_SPO2_ALG_NOT_OPEN, + MSG_SPO2_ALG_OPEN, + MSG_SPO2_READY, + MSG_SPO2_ALG_TIMEOUT, + MSG_SPO2_END +} spo2_alg_msg_code_t; + +typedef enum { + MSG_SPO2_LIVING_INITIAL, + MSG_SPO2_LIVING_TRUE, + MSG_SPO2_LIVING_FAIL +} spo2_living_code_t; + +typedef enum { + SPO2_NORMAL_MODE, + SPO2_ALLDAY_MODE +} spo2_mode_t; + +typedef struct { + spo2_alg_msg_code_t spo2_alg_status; + spo2_living_code_t spo2_living_status; + uint32_t data_cnt; + uint8_t spo2_result; + uint8_t hr_result; + uint8_t block_cnt; + uint8_t ir_quality; + uint16_t reliable_score_result; + + uint8_t screen_up; + uint8_t motion; + uint8_t poor_signal; + + uint8_t signal_snr; + uint32_t signal_std; + +} spo2_results_t; + +typedef struct { + uint8_t screen_up; + uint8_t motion; + uint8_t poor_signal; +} spo2_gesture_recognize_t; + +typedef struct { + uint32_t data_cnt; + int32_t red_new_raw_data; + int32_t ir_new_raw_data; + int32_t green_new_raw_data; + int32_t ir_iir_data_filter_out; + int32_t ir_data_smooth; + int32_t red_iir_data_filter_out; + int32_t red_data_smooth; + uint8_t ir_offset_50; + uint8_t red_offset_50; + uint8_t green_offset_50; + int32_t ir_dc; + int32_t red_dc; + int32_t green_dc; + int32_t ir_data_o2_128; + int32_t red_data_o2_128; + int32_t green_data_o2_128; + int16_t red_ir_dc; + int16_t red_green_dc; + int16_t ir_green_dc; + int16_t ir_fft_snr; + int8_t motion_status; + uint8_t xcorr_max; + int16_t COUNT_IN_judge; + uint8_t spo2_result; + uint8_t count_block; + int32_t SaO2_data_temp; +} spo2_debug_t; + +typedef struct { + uint8_t red_offset_idac; + uint8_t ir_offset_idac; + uint8_t green_offset_idac; + uint16_t spo2_start_cnt; +} spo2_agcpara_t; + +typedef struct { + uint8_t XCORR_MODE; + uint8_t QUICK_RESULT; +} spo2_switch_t; + +typedef struct { + uint8_t SPO2_LOW_XCORR_THRE; + uint8_t SPO2_LOW_SNR_THRE; + uint8_t COUNT_BLOCK_NUM; + uint32_t SPO2_BASE_LINE_INIT; + uint32_t SPO2_SLOPE; + uint16_t SPO2_GSEN_POW_THRE; +} spo2_usuallyadjust_t; + +typedef struct { + uint16_t MEAN_NUM; + int32_t SOP2_DEGLITCH_THRE; + int32_t SPO2_REMOVE_JUMP_THRE; + uint16_t SPO2_LOW_CLIP_END_TIME; + uint16_t SPO2_LOW_CLIP_DN; + uint16_t SPO2_NORMAL_CLIP_DN; + uint16_t IR_AC_TOUCH_THRE; + uint16_t IR_FFT_POW_THRE; + uint8_t SPO2_CALI; + uint8_t SLOPE_PARA_MAX; + uint8_t SLOPE_PARA_MIN; +} spo2_barelychange_t; + +void tyhx_spo2_set_switch(uint8_t XCORR_MODE,uint8_t QUICK_RESULT); +void tyhx_spo2_para_usuallyadjust(uint8_t SPO2_LOW_XCORR_THRE,uint8_t SPO2_LOW_SNR_THRE,uint8_t COUNT_BLOCK_NUM,uint32_t SPO2_BASE_LINE_INIT,uint32_t SPO2_SLOPE,uint16_t SPO2_GSEN_POW_THRE); +void tyhx_spo2_para_barelychange(uint16_t MEAN_NUM,int32_t SOP2_DEGLITCH_THRE,int32_t SPO2_REMOVE_JUMP_THRE, \ + uint16_t SPO2_LOW_CLIP_END_TIME,uint16_t SPO2_LOW_CLIP_DN,uint16_t SPO2_NORMAL_CLIP_DN, \ + uint16_t IR_AC_TOUCH_THRE,uint16_t IR_FFT_POW_THRE,uint8_t SPO2_CALI,uint8_t SLOPE_PARA_MAX,uint8_t SLOPE_PARA_MIN); + +void tyhx_spo2_set_living(uint8_t living_mode, uint8_t qu_thre, uint8_t st_thre); +void tyhx_spo2_set_mode(spo2_mode_t mode); +bool tyhx_spo2_alg_send_data(int32_t *red_new_raw_data,int32_t *ir_new_raw_data,int32_t *green_new_raw_data,uint8_t R_LEDDAC,uint8_t IR_LEDDAC,uint8_t G_LEDDAC, int16_t *gsen_data_x, int16_t *gsen_data_y, int16_t *gsen_data_z, uint8_t dat_len); +void tyhx_spo2_alg(int32_t red_new_raw_data , int32_t ir_new_raw_data, int32_t green_new_raw_data,uint8_t R_LEDDAC,uint8_t IR_LEDDAC,uint8_t G_LEDDAC); +void tyhx_spo2_alg_close(void); +bool tyhx_spo2_alg_open(void); +bool tyhx_spo2_alg_open_deep(void); +spo2_results_t tyhx_spo2_alg_get_results(void); +spo2_debug_t tyhx_spo2_alg_debug_results(void); + +#endif + diff --git a/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt b/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt new file mode 100644 index 000000000..8a107beff --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt @@ -0,0 +1,52 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "rotary_encoder") + +if("ROTARYENCODER_HX3507" IN_LIST DEFINES) +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hx3507.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3507_at_cmd.c +) +set(PUBLIC_DEFINES +SUPPORT_AT_HX3507 +) +else() +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/hx3507.c + ${CMAKE_CURRENT_SOURCE_DIR}/hx3507_at_cmd.c +) +set(PUBLIC_DEFINES +SUPPORT_AT_HX3507 +) +endif() + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_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() diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507.c b/code/sdk/drivers/peripheral/rotary_encoder/hx3507.c new file mode 100644 index 000000000..92a06fc72 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507.c @@ -0,0 +1,542 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n + * + * Description: Button driver source file \n + * Author: @CompanyNameTag \n + * History: \n + * 2023-02-24, Create file. \n + */ + +#include "pinctrl.h" +#include "button_porting.h" +#include "platform_core.h" +#include "gpio.h" +#include "gpio_porting.h" +#include "debug_print.h" +#include "rtc.h" +#include "timer.h" +#include "systick.h" +#include "chip_core_irq.h" +#include "tcxo.h" +#include "errcode.h" +#include "pm_veto.h" + +/** + * Copyright (c) 2014 - 2023, 南京天易合芯电子有限公司 + * + * All rights reserved. + * +*/ +/***************************************************************************** + * @file tyhx_crown_custom.c + * @author Jiandang.Dong + * @date 2022-08-09 created + * @Emial Jiandang.Dong@tianyihexin.com + * @brief HX3507 驱动程序 +******************************************************************************/ +/* +整体应用流程, 请见应用文档. +先初始化IO, 执行crown_init 保证通信正确; +在需要HX3507工作的时候, 调用crown_start(), 定时器启动, +定时器周期处理调用crown_data_handler()来读取HX3507的数据; +在HX3507 不需要工作的时候, 调用crown_stop() 让HX3507 进入power down状态 +*/ + + +#include +#include +#include +#include +#include +#include "hx3507.h" + +// #ifdef CHIP_HX3507 + + +#include "cmsis_os2.h" + +osTimerId_t g_hx3507_timer = NULL;//定义一个定时器ID +static uint8_t g_hx3695_timer_installed = 0; + +static int16_t crown_result = 0; + +/*----------------------以下为定时函数相关定义 建立/启动/停止定时器//定时中断处理-------------------------------*/ + + + +/** + * 定时器超时处理函数 + * @param p_context 是对应的定时器; + */ +void crown_timer_handler(void * p_context) +{ + UNUSED(p_context); + crown_data_handler(NULL,0); +} +/** + * 表冠定时器创建函数 + * @param NULL + */ +void crown_timer_creat(void) +{ + if (g_hx3695_timer_installed == 1) + return ; + g_hx3507_timer = osTimerNew((osTimerFunc_t)crown_timer_handler, osTimerPeriodic, NULL, NULL); + g_hx3695_timer_installed = true; + return ; + // app_timer_create(&crown_timer_id, APP_TIMER_MODE_REPEATED, crown_timer_handler); +} + +/** + * 定时器start函数 , 目前定义的定时器是50ms, 用户可以根据需要改为100ms + * @param NULL + */ +void crown_timer_start(void) +{ + if(osTimerIsRunning(g_hx3507_timer)==0) + osTimerStart(g_hx3507_timer, 50); +} + +/** + * 定时器stop函数 + * @param timerid 是对应的定时器; + */ +void crown_timer_stop(void) +{ + if(osTimerIsRunning(g_hx3507_timer)) + osTimerStop(g_hx3507_timer); +} + + + +/*----------------------以上为定时函数相关定义 建立/启动/停止定时器//定时中断处理-------------------------------*/ + + +/*---------------------------以下为表冠的寄存器读写,初始化/开始/结束------------------------*/ + +/** + * 通信重新同步函数, 作用是防止因为其他干扰而引起的错乱 + * @param NULL; + */ +void crown_com_resync(void) +{ + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH); + uapi_tcxo_delay_us(5); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + uapi_tcxo_delay_us(5); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH); + uapi_tcxo_delay_ms(5); +} + +/** + * 通信读寄存器值函数 + * @param regaddr, hx3507的寄存器地址 + * uapi_tcxo_delay_us(COM_DELAY), 读写函数的delay 按照实际平台调整, HX3507 通信sclk 最高支持1MHZ频率. + * 在最高频率的范围内, 尽量减小delay, 减少定时器周期读取的时间. + */ +uint8_t crown_read_reg(uint8_t regaddr) +{ + uint8_t readvalue = 0; + + regaddr &= 0x7f; + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + uapi_tcxo_delay_us(COM_DELAY); + + for(int i=0; i<8; i++) + { + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + + if(regaddr & 0x80) + { + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_HIGH); + } + else + { + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + + } + //uapi_tcxo_delay_us(COM_DELAY); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH); + + regaddr<<=1; + //uapi_tcxo_delay_us(COM_DELAY); + } + + //开始读操作,HOST要把SDIO从输出端口改为输入端口. + uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_INPUT); + uapi_pin_set_pull(PIN_TYHX_SDIO, (pin_pull_t)HAL_PIO_PULL_UP); + uapi_pin_set_ie(PIN_TYHX_SDIO,HAL_PIO_IE_ENBALE); + uapi_tcxo_delay_us(COM_DELAY); + //nrf_gpio_pin_clear(PIN_TYHX_SCLK); + //uapi_tcxo_delay_us(COM_DELAY); + + for(int i=0; i<8; i++) + { + readvalue<<=1; + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + + //uapi_tcxo_delay_us(COM_DELAY); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH); + //uapi_tcxo_delay_us(COM_DELAY); + if(uapi_gpio_get_val(PIN_TYHX_SDIO)) + { + readvalue |= 0x1; + } + //uapi_tcxo_delay_us(COM_DELAY); + } + uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + + return readvalue; +} + +/** + * 通信读寄存器值函数 + * @param regaddr, hx3507的寄存器地址 + * @param regvalue, 要写的值 + */ +void crown_write_reg(uint8_t regaddr, uint8_t regvalue) +{ + + uint16_t writevalue; + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + uapi_tcxo_delay_us(COM_DELAY); + + //写通信协议, 最高位置1, 循环16次依次送出寄存器和值,在SCLK的上升沿前准备好数据 + writevalue= (uint16_t)((regaddr|0x80)<<8) + regvalue; + + for(int i=0; i<16; i++) + { + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + + if(writevalue & 0x8000) + { + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_HIGH); + } + else + { + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + + } + //uapi_tcxo_delay_us(COM_DELAY); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH); + + writevalue<<=1; + } + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + + return; +} + + +/** + * 某些OTS冠轴质量非常差, 这个是防呆处理 + * @param xdata, 当前读到的OTS的有效轴的数据 + * @result = true, 值有效, = false 这个值无效 + */ +static bool crown_data_verify(int16_t xdata) +{ + static int16_t xstore[3] = {0}; + uint16_t diff1, diff2, diff3= 0; + + if(abs(xdata)>=600)//间隔50ms的一次读数 + { + crown_timer_stop(); + crown_start(); + return false; + } + diff1 = abs(xstore[2]-xstore[1]); + diff2 = abs(xstore[1]-xstore[0]); + diff3 = abs(xstore[0]-xdata); + + if((diff1<5) &&(diff2<=5) &&(diff3<=5) &&(abs(xdata)>=100))//连续四次读到接近的值 + { + crown_timer_stop(); + crown_start(); + return false; + } + xstore[2] = xstore[1]; + xstore[1] = xstore[0]; + xstore[0] = xdata; + return true; +} + +/** + * 周期定时器数据读取 + * @param p_event_data, 参数暂时无用 + * @param event_size, 参数暂时无用 + */ +void crown_data_handler(void *p_event_data, uint16_t event_size) +{ + int16_t delatx = 0; + uint8_t sleepstatus = 0; + for(int i=0; i<5; i++)//先读一下芯片ID保证通信正常 + { + if(crown_read_reg(HX3507_DID) == 0x30) + { + break; + } + else + { + crown_com_resync(); + } + } + if(crown_read_reg(Motion_St)&0x80) + { +#if defined(MOT_LOW_LEVEL_MODE) + //如果有使用中断, 需要读取Y的值, 值读完, 中断电平才能恢复 + int16_t delaty = 0; + delaty = crown_read_reg(DeltaY) |(crown_read_reg(DeltaY_Hi)<<8); +#endif + //HX3507 一个方向转动出正值, 另外一个方向就是负值, 正负值跟芯片的摆放方向有关 + delatx = crown_read_reg(DeltaX) |(crown_read_reg(DeltaX_Hi)<<8); + if(crown_data_verify(delatx)) //先判断数据是否合理, + // 主要针对OTS冠轴质量,或者装配摆动幅度大引起的错误, 做的保护程序 + { + //打印读取结果 + TYHX_LOG("DeltaX = %d\r\n",delatx); + //把结果转换为大概的估算角度 + put_crown_result(delatx); + } + } + else //下面这两个参数在产测程序里面需要加上 + { + //冠轴静止的时候, 打印图像的质量和PD的饱和度, 这两个参数读取要放在出货测试的程序里面, + // 图像质量应该>=80, 否则可能代表芯片表面有脏污等或者装配问题或者有漏光 + // PD的饱和度应该>=100 且 <=180, 如果有漏光等问题, 结果>=240以上, 相关漏光等要处理 + TYHX_LOG("pic qulity =%d, pd saturation=%d\r\n",crown_read_reg(Img_Qa),crown_read_reg(PD_SAT)); + } + +#if (defined(MOT_LOW_LEVEL_MODE))//如果低电平中断模式,要读到芯片MOT变高 + if(uapi_gpio_get_val(PIN_TYHX_MOT)) + { + TYHX_LOG("PIN_TYHX_MOT is high \r\n"); + crown_timer_stop(); + } +#endif + +#if (defined(MOT_FALLINGTRI_MODE))//如果是脉冲中断模式,要读到芯片进入sleep + sleepstatus = crown_read_reg(Op_St); + if((sleepstatus & 0x7) == 6) + { + TYHX_LOG("crown is sleep \r\n"); + crown_timer_stop(); + } +#endif +#if (defined(MOT_NO_USE_MODE)) + //如果是MOT_NO_USE_MODE , 一般在屏幕熄掉,不需要HX3507工作的时候, 关闭定时器 +#endif + +} + +//MOT 中断处理程序, 这个是根据平台程序处理, 用户可以自行修改 +//这里加中断发生标志位或者把中断处理推送到其他任务队列, 因为中断函数里面不能加太多程序 +//下面的例子用的是NORDIC标准的程序,中断发生后GPIO的一个处理,并且把中断处理推送到任务队列 +#if (defined(MOT_LOW_LEVEL_MODE) || defined(MOT_FALLINGTRI_MODE)) +static void crown_int_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +{ + uint32_t err_code; + bool mothitolow = false; + + nrf_drv_gpiote_in_uninit(PIN_TYHX_MOT); + if (action == NRF_GPIOTE_POLARITY_HITOLO) + { + mothitolow = true; + nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false); + err_code = nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler); + APP_ERROR_CHECK(err_code); + config_crown.pull = NRF_GPIO_PIN_PULLUP; + nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true); + } + else + { + mothitolow = false; + nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); + err_code = nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler); + APP_ERROR_CHECK(err_code); + config_crown.pull = NRF_GPIO_PIN_PULLUP; + nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true); + } + nrf_gpio_pin_latch_clear(PIN_TYHX_MOT); + if(mothitolow) + { + TYHX_LOG("mot interrupt! \r\n"); + mothitolow = false; + crown_timer_start(); + } + +} + +#endif + + +/** + * HX3507 初始化 + * @param NULL + */ +void crown_init(void) +{ + int i; + uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_INPUT); + uapi_gpio_set_dir(PIN_TYHX_SCLK,GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW); + uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW); + + uapi_tcxo_delay_us(COM_DELAY); + crown_com_resync(); + for(i=0; i<10; i++) + { + if(crown_read_reg(HX3507_DID) == 0x30) + { + TYHX_LOG("read chip id is 0x30\r\n",i); + break; + } + if(i<7)//读到ID不对, 复位通信 + { + crown_com_resync(); + } + } + if(i==10) + { + TYHX_LOG("HX3507 communication err, please check\r\n"); + return; + } + +#if (defined(MOT_LOW_LEVEL_MODE) || defined(MOT_FALLINGTRI_MODE)) + //中断定义 + nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); + config_crown.pull = NRF_GPIO_PIN_PULLUP; + nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler); + nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true); + +#endif + //定时器创建 + crown_timer_creat(); +} + + +/** + * HX3507 启动 + * @param NULL + */ +void crown_start(void) +{ + int i = 0; + for(int i=0; i<5; i++) + { + crown_write_reg(Config_St,0x89); //RESET + uapi_tcxo_delay_ms(10); + TYHX_LOG("Reset ic, now init ---\r\n"); + +#if defined(MOT_LOW_LEVEL_MODE) + crown_write_reg(Config_St,0x01); //正常工作, MOT低电平中断 + crown_write_reg(Op_Mode,0xb8); //打开Sleep1 和 sleep2 功能 + crown_write_reg(Sleep1_Setting,0xc0); + crown_write_reg(Enter_Time,0xc1); + crown_write_reg(Sleep2_Setting,0xc0); +#elif defined(MOT_FALLINGTRI_MODE) + crown_write_reg(Config_St,0x41); //正常工作, MOT下降沿中断 + crown_write_reg(Op_Mode,0xb8); //打开Sleep1 和 sleep2 功能 + crown_write_reg(Sleep1_Setting,0xc0); + crown_write_reg(Enter_Time,0xc1); + crown_write_reg(Sleep2_Setting,0xc0); + +#elif defined(MOT_NO_USE_MODE) + crown_write_reg(Op_Mode,0xa0); //关闭sleep功能 +#endif + crown_write_reg(Write_Protect,0xc3); //enable all registers + crown_write_reg(Sleep1_Setting,0xc0); //0x70,32ms.loop = 40ms. return 0 slowly + crown_write_reg(Enter_Time,0x0); //sleep1=128*(Enter_Time[7:4]+1) sleep2=20480*(Enter_Time[3:0]+1) + crown_write_reg(DxDy_16bit,0x01); //0:8bit,1:16bit + crown_write_reg(CPI2_Setting,0x88); //800 cpi + crown_write_reg(HX3507_REV,0x00); + if(1 == crown_read_reg(DxDy_16bit) ) + { + break; + } + else + { + crown_com_resync(); + } + } + if(i==5) + { + TYHX_LOG("HX3507 init err, please check\r\n"); + return; + } + + +#if 0 //这里非常关键, 在调试初期, 需要用#if 1 来验证寄存器写入的值和读出来的值是一样的, 通信正确 + TYHX_LOG("Op_Mode = 0x%x\r\n",crown_read_reg(Op_Mode)); + TYHX_LOG("Sleep1_Setting = 0x%x\r\n",crown_read_reg(Sleep1_Setting)); + TYHX_LOG("DxDy_16bit = 0x%x\r\n",crown_read_reg(DxDy_16bit)); + TYHX_LOG("CPI2_Setting = 0x%x\r\n",crown_read_reg(CPI2_Setting)); +#endif + +#ifdef MOT_NO_USE_MODE // 如果是非中断模式, 初始后, 开启定时器; + crown_timer_start(); +#endif + + + +} + + +/** + * HX3507 停止 + * @param NULL + */ +void crown_stop(void) +{ +#ifdef MOT_NO_USE_MODE + crown_timer_stop(); + crown_write_reg(Config_St,0x89); // power down, power down 后芯片功耗9uA + uapi_tcxo_delay_ms(20); + TYHX_LOG("[tyhx_crown_stop]\r\n"); +#endif +} + + +/** + * HX3507 结果转换为角度, 供UI处理 + * @param NULL + */ +void put_crown_result(int16_t x) +{ + if(abs(x)<=FILTER_MIN ) + return; + if(abs(x)>=4 ) + { + crown_result += x/4; //大于4的值除以4, 代表角度, 单位0.5° + } + else + { + if(x>0) + { + crown_result+=1; //2~4 默认一个单位, 0.5° + } + else + { + crown_result-=1; //2~4 默认一个单位, 0.5° + } + } +} + +/** + * 获取表冠的数据结果接口函数 + * @param NULL +*/ +int16_t get_crown_result(void) +{ + int16_t resulttemp; + resulttemp=crown_result; + crown_result = 0; + return resulttemp; +} + +// #endif + diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507.h b/code/sdk/drivers/peripheral/rotary_encoder/hx3507.h new file mode 100644 index 000000000..647601e28 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507.h @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2014 - 2023, 南京天易合芯电子有限公司 + * + * All rights reserved. + * +*/ + +/*************************************************************************** + * @file TYHX_CROWN_CUSTOM.h + * @author TYHX team + * @product CROWN + * @version V0.1 + * @date 2022-08-09 + * @modify date 2023-02-17 + +****************************************************************************/ +#ifndef _TYHX_CROWN_CUSTOM_H_ +#define _TYHX_CROWN_CUSTOM_H_ + +#include "debug_print.h" +#define CHIP_HX3507 + + +//三种中断模式的应用具体见“天易合芯表冠产品应用文档.docx"的流程说明,用户也可以定义自己的流程模式 +//#define MOT_LOW_LEVEL_MODE //MOT使用低电平中断 +//#define MOT_FALLINGTRI_MODE //MOT 使用低脉冲中断 +#define MOT_NO_USE_MODE //用户不使用MOT 中断, 这个为常用的推荐模式 + + +//register define , addr, rw, default value, detail +#define HX3507_DID 0x00 //R 0x30 芯片ID +#define Motion_St 0x02 //R 是否有冠轴转动数据产生 +#define DeltaX 0x03 //R 0x30 DeltaX 的低8位数据 +#define DeltaY 0x04 //R 0x30 DeltaY 的低8位数据 +#define Op_Mode 0x05 //W/R 操作模式 +#define Config_St 0x06 //W/R 0x02 閰嶇疆 +#define Img_Qa 0x07 //R 图像质量 +#define Op_St 0x08 //R Sleep 和帧率设置 +#define Write_Protect 0x09 //W扩展寄存器的写使能 +#define Sleep1_Setting 0x0A //W/R Sleep1 的工作频率设置 +#define Enter_Time 0x0B //W/R 进入SLEEP的等待时间设置 +#define Sleep2_Setting 0x0C // W/R Sleep2的工作频率设置 +#define DeltaX_Hi 0x20 //R DeltaX 的高8位数据 +#define DeltaY_Hi 0x21 //R DeltaY的高8位数据 +#define DxDy_16bit 0x22 //数据输出寄存器选择16bit还是8bit格式 +#define CPI2_Setting 0x23 //W/R 扩展CPI 设置 +#define PD_SAT 0x3D //PD 感光的饱和度 +#define HX3507_REV 0x5F //W 保留寄存器 + +#define COM_DELAY 5 // 通信的delay 单位, 用户根据平台实际调整, 最高支持1MHZ CLK +#define FILTER_MIN 1 // 偶尔冠轴被震动等各种意外产生的小的数据, 可根据产品情况把小的出值滤掉 + +//log 打印定义 +#define TYHX_LOG_ENABLE +#ifdef TYHX_LOG_ENABLE +#define TYHX_LOG(fmt, ...) \ + do { \ + PRINT(fmt" ", ##__VA_ARGS__); \ + } while (0) +#else +#define TYHX_LOG(...) +#endif //TYHX_LOG_ENABLE + + +/*----------------------使用的IO定义-------------------------------*/ + +#define PIN_TYHX_SDIO S_AGPIO_L12 //custom to do here +#define PIN_TYHX_SCLK S_AGPIO_L13 //custom to do here +#define PIN_TYHX_MOT S_AGPIO_L17 //custom to do here + +//定时器的 创建/启动/停止/溢出处理函数 +void crown_timer_creat(void); +void crown_timer_start(void); +void crown_timer_stop(void); +void crown_timer_handler(void * p_context); + +//HX3507 初始化,启动,停止, 数据读取, 读寄存器, 写寄存器等, 通信同步 +void crown_init(void); +void crown_start(void); +void crown_stop(void); +void crown_data_handler(void *p_event_data, uint16_t event_size); +uint8_t crown_read_reg(uint8_t regaddr); +void crown_write_reg(uint8_t regaddr, uint8_t regvalue); +void crown_com_resync(void); + +//把读出的数据转换为大概角度函数 +void put_crown_result(int16_t x); + +//把角度结果上报的函数 +int16_t get_crown_result(void); +#endif //_TYHX_CROWN_CUSTOM_H_ diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507_at_cmd.c b/code/sdk/drivers/peripheral/rotary_encoder/hx3507_at_cmd.c new file mode 100644 index 000000000..064256ed5 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507_at_cmd.c @@ -0,0 +1,92 @@ + +// #include "hx3507.h" + + +#include "at_cmd_api.h" +#include "pm_control.h" +#include "hx3507.h" + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define HX3507_MAX_ARGC 8 +#define HX3507_MAX_ARGV_LEN 64 + +#define HX3507_SUCCESS 0 +#define HX3507_FAILED (-1) + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[HX3507_MAX_ARGC][HX3507_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 >= HX3507_MAX_ARGC) { + return HX3507_FAILED; + } + } else { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= HX3507_MAX_ARGV_LEN) { + return HX3507_FAILED; + } + } + } + if (pos != 0) { + *argc += 1; + } + + return HX3507_SUCCESS; +} + +static uint8_t g_hx3507_test_started = 0; +static uint32_t hx3507_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t argv[HX3507_MAX_ARGC][HX3507_MAX_ARGV_LEN] = { 0 }; + uint32_t argc = 0; + + int ret = ConvertCmdToParam(para, paraLen, argv, &argc); + if (ret != HX3507_SUCCESS) { + PRINT("HX3507TEST ATCMD Convert Command Failed\n"); + return ERRCODE_FAIL; + } + + if (argc != 1) { + PRINT("HX3507TEST 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_hx3507_test_started == 1) + { + PRINT("SKIP hx3507test start, already started\r\n"); + return 0; + } + crown_init(); + crown_start(); + g_hx3507_test_started = 1; + }else{ + if (g_hx3507_test_started == 0) + { + PRINT("SKIP hx3507test stop, already stopped\r\n"); + return 0; + } + crown_stop(); + g_hx3507_test_started = 0 ; + } + return ERRCODE_SUCC; +} +static const at_cmd_table_t g_hx3507_cmd[] = { + { (char *)"AT^HX3507TEST", hx3507_test, (char *)"1" }, +}; + +at_cmd_table_t *get_hx3507_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_hx3507_cmd); + return (at_cmd_table_t *)g_hx3507_cmd; +} diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507_at_cmd.h b/code/sdk/drivers/peripheral/rotary_encoder/hx3507_at_cmd.h new file mode 100644 index 000000000..cb7de8558 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 HX3507_AT_PROCESS_H +#define HX3507_AT_PROCESS_H + +#include +#include +#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_mmc5603_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/slip/CMakeLists.txt b/code/sdk/drivers/peripheral/slip/CMakeLists.txt new file mode 100644 index 000000000..f7d787807 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/CMakeLists.txt @@ -0,0 +1,49 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "SLIP") +set(LWIP_PORT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/port/vfs_lwip.c + ${CMAKE_CURRENT_SOURCE_DIR}/port/debug/lwip_debug.c + ${CMAKE_CURRENT_SOURCE_DIR}/port/netif/ethernetif.c +) +set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/asio.c + ${CMAKE_CURRENT_SOURCE_DIR}/slipif.c + ${CMAKE_CURRENT_SOURCE_DIR}/uart_slip.c + ${CMAKE_CURRENT_SOURCE_DIR}/uart_slip.c + # ${LWIP_PORT_SOURCES} +) +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} + # ${CMAKE_CURRENT_SOURCE_DIR}/port +) +set(PUBLIC_DEFINES + SUPPORT_AT_SLIP +) +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +# use this when you want to add ccflags like -include xxx +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wno-incompatible-function-pointer-types + -Wno-unused-function +) + +set(WHOLE_LINK + true +) + +set(MAIN_COMPONENT + false +) + +build_component() + diff --git a/code/sdk/drivers/peripheral/slip/asio.c b/code/sdk/drivers/peripheral/slip/asio.c new file mode 100644 index 000000000..34de6ab81 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/asio.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + */ + +/* + * This is the interface to the platform specific serial IO module + * It needs to be implemented by those platforms which need SLIP or PPP + */ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "driver/uart.h" +#include "lwip/sio.h" + +#ifdef QUECTEL_CONFIG_HIGH_SPEED_SUPPORT +#define SEND_BUFFER_MAX (6) +#else +#define SEND_BUFFER_MAX (1) +#endif + +struct slip_send_buffer_t { + uint8_t buffer[SEND_BUFFER_MAX+1]; + int len; +}; + +struct slip_send_buffer_t slip_send_buffer; + +/* The following functions can be defined to something else in your cc.h file + or be implemented in your custom sio.c file. */ + +/** + * Opens a serial device for communication. + * + * @param devnum device number + * @return handle to serial device if successful, NULL otherwise + */ +sio_fd_t sio_open(u8_t devnum) +{ + memset(&slip_send_buffer, 0x00, sizeof(struct slip_send_buffer_t)); + return 1; +} + +/** + * Sends a single character to the serial device. + * + * @param c character to send + * @param fd serial device handle + * + * @note This function will block until the character can be sent. + */ +void sio_send(u8_t c, sio_fd_t fd) +{ + //uart_write_bytes(UART_NUM_0, (const char *)&c, 1); + slip_send_buffer.buffer[slip_send_buffer.len] = c; + slip_send_buffer.len += 1; + if( slip_send_buffer.len >= (SEND_BUFFER_MAX) ) { + //printf("send2 data len = %d\n", slip_send_buffer.len); + uart_write_bytes(UART_NUM_0, (const char *)slip_send_buffer.buffer, slip_send_buffer.len); + slip_send_buffer.len = 0; + } +} + +void sio_send_all(u8_t c, sio_fd_t fd) +{ + //uart_write_bytes(UART_NUM_0, (const char *)&c, 1); + if( slip_send_buffer.len > 0 ) { + //printf("send data len = %d\n", slip_send_buffer.len); + uart_write_bytes(UART_NUM_0, (const char *)slip_send_buffer.buffer, slip_send_buffer.len); + slip_send_buffer.len = 0; + } +} + +/** + * Receives a single character from the serial device. + * + * @param fd serial device handle + * + * @note This function will block until a character is received. + */ +u8_t sio_recv(sio_fd_t fd) +{ + return 0; +} diff --git a/code/sdk/drivers/peripheral/slip/cat1slip.c b/code/sdk/drivers/peripheral/slip/cat1slip.c new file mode 100644 index 000000000..0b3356635 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/cat1slip.c @@ -0,0 +1,16 @@ +#define SLIP_UART_BUS UART_BUS_1 +#define CHIP_FIXED_TX_PIN S_MGPIO33 +#define CHIP_FIXED_RX_PIN S_MGPIO34 + +void slipinit(void) +{ + uart_set_baudrate(UART_NUM_1,921600); + + uint8_t ret = slip_uart_init((int)setting); + if( ret != 0 ) { + printf("custom_uart_init fail ret = %d\n", ret); + return; + } + + user_netif_set_default(); +} \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/slip/slipif.c b/code/sdk/drivers/peripheral/slip/slipif.c new file mode 100644 index 000000000..0e4fc5361 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/slipif.c @@ -0,0 +1,565 @@ +/** + * @file + * SLIP Interface + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is built upon the file: src/arch/rtxc/netif/sioslip.c + * + * Author: Magnus Ivarsson + * Simon Goldschmidt + */ + + +/** + * @defgroup slipif SLIP + * @ingroup netifs + * + * This is an arch independent SLIP netif. The specific serial hooks must be + * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send + * + * Usage: This netif can be used in three ways:\n + * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() + * until data is received.\n + * 2) In your main loop, call slipif_poll() to check for new RX bytes, + * completed packets are fed into netif->input().\n + * 3) Call slipif_received_byte[s]() from your serial RX ISR and + * slipif_process_rxqueue() from your main loop. ISR level decodes + * packets and puts completed packets on a queue which is fed into + * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for + * pbuf_alloc to work on ISR level!). + * + */ +#include +#include "netif/slipif.h" +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/sys.h" +#include "lwip/sio.h" + +#define SLIP_END 0xC0 /* 0300: start and end of every packet */ +#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ +#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ +#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ + +/** Maximum packet size that is received by this netif */ +#ifndef SLIP_MAX_SIZE +#define SLIP_MAX_SIZE 1500 +#endif + +/** Define this to the interface speed for SNMP + * (sio_fd is the sio_fd_t returned by sio_open). + * The default value of zero means 'unknown'. + */ +#ifndef SLIP_SIO_SPEED +#define SLIP_SIO_SPEED(sio_fd) 0 +#endif + +enum slipif_recv_state { + SLIP_RECV_NORMAL, + SLIP_RECV_ESCAPE +}; + +struct slipif_priv { + sio_fd_t sd; + /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ + struct pbuf *p, *q; + u8_t state; + u16_t i, recved; +#if SLIP_RX_FROM_ISR + struct pbuf *rxpackets; +#endif +}; +struct slipif_priv *priv = NULL; +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chain packet to send + * @return always returns ERR_OK since the serial layer does not provide return values + */ +static err_t +slipif_output(struct netif *netif, struct pbuf *p) +{ + struct slipif_priv *priv; + struct pbuf *q; + u16_t i; + u8_t c; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + LWIP_ASSERT("p != NULL", (p != NULL)); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output: sending %"U16_F" bytes\n", p->tot_len)); + //printf("slipif_output: sending %d bytes\n", p->tot_len); + priv = (struct slipif_priv *)netif->state; + + /* Send pbuf out on the serial I/O device. */ + /* Start with packet delimiter. */ + sio_send(SLIP_END, priv->sd); + + for (q = p; q != NULL; q = q->next) { + for (i = 0; i < q->len; i++) { + c = ((u8_t *)q->payload)[i]; + switch (c) { + case SLIP_END: + /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_END, priv->sd); + break; + case SLIP_ESC: + /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_ESC, priv->sd); + break; + default: + /* normal byte - no need for escaping */ + sio_send(c, priv->sd); + break; + } + } + } + /* End with packet delimiter. */ + sio_send(SLIP_END, priv->sd); + extern void sio_send_all(sio_fd_t fd); + sio_send_all(priv->sd); + return ERR_OK; +} + +#if LWIP_IPV4 +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chain packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values + */ +static err_t +slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr) +{ + LWIP_UNUSED_ARG(ipaddr); + return slipif_output(netif, p); +} +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chain packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values + */ +static err_t +slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr) +{ + LWIP_UNUSED_ARG(ipaddr); + return slipif_output(netif, p); +} +#endif /* LWIP_IPV6 */ + +/** + * Handle the incoming SLIP stream character by character + * + * @param netif the lwip network interface structure for this slipif + * @param c received character (multiple calls to this function will + * return a complete packet, NULL is returned before - used for polling) + * @return The IP packet when SLIP_END is received + */ +static struct pbuf * +slipif_rxbyte(struct netif *netif, u8_t c) +{ + struct slipif_priv *priv; + struct pbuf *t; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + switch (priv->state) { + case SLIP_RECV_NORMAL: + switch (c) { + case SLIP_END: + if (priv->recved > 0) { + /* Received whole packet. */ + /* Trim the pbuf to the size of the received packet. */ + pbuf_realloc(priv->q, priv->recved); + + LINK_STATS_INC(link.recv); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); + t = priv->q; + priv->p = priv->q = NULL; + priv->i = priv->recved = 0; + return t; + } + return NULL; + case SLIP_ESC: + priv->state = SLIP_RECV_ESCAPE; + return NULL; + default: + break; + } /* end switch (c) */ + break; + case SLIP_RECV_ESCAPE: + /* un-escape END or ESC bytes, leave other bytes + (although that would be a protocol error) */ + switch (c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + default: + break; + } + priv->state = SLIP_RECV_NORMAL; + break; + default: + break; + } /* end switch (priv->state) */ + + /* byte received, packet not yet completely received */ + if (priv->p == NULL) { + /* allocate a new pbuf */ + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); + priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - PBUF_LINK_ENCAPSULATION_HLEN), PBUF_POOL); + + if (priv->p == NULL) { + LINK_STATS_INC(link.drop); + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); + /* don't process any further since we got no pbuf to receive to */ + return NULL; + } + + if (priv->q != NULL) { + /* 'chain' the pbuf to the existing chain */ + pbuf_cat(priv->q, priv->p); + } else { + /* p is the first pbuf in the chain */ + priv->q = priv->p; + } + } + + /* this automatically drops bytes if > SLIP_MAX_SIZE */ + if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { + ((u8_t *)priv->p->payload)[priv->i] = c; + priv->recved++; + priv->i++; + if (priv->i >= priv->p->len) { + /* on to the next pbuf */ + priv->i = 0; + if (priv->p->next != NULL && priv->p->next->len > 0) { + /* p is a chain, on to the next in the chain */ + priv->p = priv->p->next; + } else { + /* p is a single pbuf, set it to NULL so next time a new + * pbuf is allocated */ + priv->p = NULL; + } + } + } + return NULL; +} + +/** Like slipif_rxbyte, but passes completed packets to netif->input + * + * @param netif The lwip network interface structure for this slipif + * @param c received character + */ +static void +slipif_rxbyte_input(struct netif *netif, u8_t c) +{ + struct pbuf *p; + p = slipif_rxbyte(netif, c); + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + } +} + +#if SLIP_USE_RX_THREAD +/** + * The SLIP input thread. + * + * Feed the IP layer with incoming packets + * + * @param nf the lwip network interface structure for this slipif + */ +static void +slipif_loop_thread(void *nf) +{ + u8_t c; + struct netif *netif = (struct netif *)nf; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + + while (1) { + if (sio_read(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); + } + } +} +#endif /* SLIP_USE_RX_THREAD */ + +/** + * @ingroup slipif + * SLIP netif initialization + * + * Call the arch specific sio_open and remember + * the opened device in the state field of the netif. + * + * @param netif the lwip network interface structure for this slipif + * @return ERR_OK if serial line could be opened, + * ERR_MEM if no memory could be allocated, + * ERR_IF is serial line couldn't be opened + * + * @note If netif->state is interpreted as an u8_t serial port number. + * + */ +err_t +slipif_init(struct netif *netif) +{ + u8_t sio_num; + + LWIP_ASSERT("slipif needs an input callback", netif->input != NULL); + + /* netif->state contains serial port number */ + sio_num = LWIP_PTR_NUMERIC_CAST(u8_t, netif->state); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)sio_num)); + + /* Allocate private data */ + if( priv == NULL ) { + priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); + if (!priv) { + return ERR_MEM; + } + } + memset(priv, 0x00, sizeof(struct slipif_priv)); + + netif->name[0] = 's'; + netif->name[1] = 'l'; +#if LWIP_IPV4 + netif->output = slipif_output_v4; +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 + netif->output_ip6 = slipif_output_v6; +#endif /* LWIP_IPV6 */ + netif->mtu = SLIP_MAX_SIZE; + + /* Try to open the serial port. */ + priv->sd = sio_open(sio_num); + if (!priv->sd) { + /* Opening the serial port failed. */ + mem_free(priv); + return ERR_IF; + } + + /* Initialize private data */ + priv->p = NULL; + priv->q = NULL; + priv->state = SLIP_RECV_NORMAL; + priv->i = 0; + priv->recved = 0; +#if SLIP_RX_FROM_ISR + priv->rxpackets = NULL; +#endif + + netif->state = priv; + + /* initialize the snmp variables and counters inside the struct netif */ + MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); + +#if SLIP_USE_RX_THREAD + /* Create a thread to poll the serial line. */ + sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, + SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); +#endif /* SLIP_USE_RX_THREAD */ + return ERR_OK; +} + +/** + * @ingroup slipif + * Polls the serial device and feeds the IP layer with incoming packets. + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_poll(struct netif *netif) +{ + u8_t c; + struct slipif_priv *priv; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + while (sio_tryread(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); + } +} + +#if SLIP_RX_FROM_ISR +/** + * @ingroup slipif + * Feeds the IP layer with incoming packets that were receive + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_process_rxqueue(struct netif *netif) +{ + struct slipif_priv *priv; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + SYS_ARCH_PROTECT(old_level); + while (priv->rxpackets != NULL) { + struct pbuf *p = priv->rxpackets; +#if SLIP_RX_QUEUE + /* dequeue packet */ + struct pbuf *q = p; + while ((q->len != q->tot_len) && (q->next != NULL)) { + q = q->next; + } + priv->rxpackets = q->next; + q->next = NULL; +#else /* SLIP_RX_QUEUE */ + priv->rxpackets = NULL; +#endif /* SLIP_RX_QUEUE */ + SYS_ARCH_UNPROTECT(old_level); + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + SYS_ARCH_PROTECT(old_level); + } + SYS_ARCH_UNPROTECT(old_level); +} + +/** Like slipif_rxbyte, but queues completed packets. + * + * @param netif The lwip network interface structure for this slipif + * @param data Received serial byte + */ +static void +slipif_rxbyte_enqueue(struct netif *netif, u8_t data) +{ + struct pbuf *p; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + SYS_ARCH_DECL_PROTECT(old_level); + + p = slipif_rxbyte(netif, data); + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + if (priv->rxpackets != NULL) { +#if SLIP_RX_QUEUE + /* queue multiple pbufs */ + struct pbuf *q = p; + while (q->next != NULL) { + q = q->next; + } + q->next = p; + } else { +#else /* SLIP_RX_QUEUE */ + pbuf_free(priv->rxpackets); + } + { +#endif /* SLIP_RX_QUEUE */ + priv->rxpackets = p; + } + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * @ingroup slipif + * Process a received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +void +slipif_received_byte(struct netif *netif, u8_t data) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + slipif_rxbyte_enqueue(netif, data); +} + +/** + * @ingroup slipif + * Process multiple received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + * @param len Number of received characters + */ +void +slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) +{ + u8_t i; + u8_t *rxdata = data; + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + + for (i = 0; i < len; i++, rxdata++) { + //slipif_rxbyte_enqueue(netif, *rxdata); + slipif_rxbyte_input(netif, *rxdata); + } +} +#endif /* SLIP_RX_FROM_ISR */ diff --git a/code/sdk/drivers/peripheral/slip/uart_slip.c b/code/sdk/drivers/peripheral/slip/uart_slip.c new file mode 100644 index 000000000..ac23514c0 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/uart_slip.c @@ -0,0 +1,200 @@ +// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "driver/uart.h" +#include "esp_log.h" + +#include "lwip/ip.h" +#include "lwip/netif.h" +#include "netif/slipif.h" +#include "lwip/init.h" +#include "lwip/lwip_napt.h" + +#include "lwip/inet_chksum.h" + +struct netif sl_netif; + +/** + * This example shows how to use the UART driver to handle special UART events. + * + * It also reads data from UART0 directly, and echoes it to console. + * + * - Port: UART0 + * - Receive (Rx) buffer: on + * - Transmit (Tx) buffer: on + * - Flow control: off + * - Event queue: on + * - Pin assignment: TxD (default), RxD (default) + */ + +#define EX_UART_NUM UART_NUM_0 + +#define BUF_SIZE (1024) +#define RD_BUF_SIZE (BUF_SIZE) + +static QueueHandle_t uart0_queue; +static void uart_event_task(void *pvParameters) +{ + uart_event_t event; + uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE); + int len = 0; + size_t remain_len = 0; + for (;;) { + // Waiting for UART event. + if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY)) { + // ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM); + + switch (event.type) { + // Event of UART receving data + // We'd better handler data event fast, there would be much more data events than + // other types of events. If we take too much time on data event, the queue might be full. + case UART_DATA: + len = uart_read_bytes(EX_UART_NUM, dtmp, event.size, 0); + //xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + // ESP_LOGI(TAG, "[DATA EVT]:"); + slipif_received_bytes(&sl_netif, dtmp, len); + // slipif_process_rxqueue(&sl_netif); + break; + // Event of HW FIFO overflow detected + case UART_FIFO_OVF: + //uart_get_buffered_data_len(EX_UART_NUM, &remain_len); + //printf("event.size = %d, remain_len=%d\n", event.size, remain_len); + //printf("hw fifo overflow\n"); + // If fifo overflow happened, you should consider adding flow control for your application. + // The ISR has already reset the rx FIFO, + // As an example, we directly flush the rx buffer here in order to read more data. + uart_flush_input(EX_UART_NUM); + xQueueReset(uart0_queue); + break; + + // Event of UART ring buffer full + case UART_BUFFER_FULL: + printf("ring buffer full\n"); + // If buffer full happened, you should consider encreasing your buffer size + // As an example, we directly flush the rx buffer here in order to read more data. + uart_flush_input(EX_UART_NUM); + xQueueReset(uart0_queue); + break; + + case UART_PARITY_ERR: + printf("uart parity errori\n"); + break; + + // Event of UART frame error + case UART_FRAME_ERR: + printf("uart frame errori\n"); + break; + // Others + default: + printf("uart event type: %d\n", event.type); + break; + } + } + } + + free(dtmp); + dtmp = NULL; + vTaskDelete(NULL); +} + +void user_netif_deinit() +{ + ip_addr_t ipaddr; + IP4_ADDR(&ipaddr, 172, 16, 1, 5); + if(sl_netif.napt == 1 ) { + ip_napt_enable(ipaddr.addr, 0); + } + netif_set_link_down(&sl_netif); + netif_set_down(&sl_netif); + netif_remove(&sl_netif); +} + +void user_netif_set_default() +{ + netif_set_default(&sl_netif); +} + +int user_netif_init(int mode) +{ + ip_addr_t ipaddr; + ip_addr_t netmask; + ip_addr_t gw; + char int_no = 2; + + struct netif *temp; + + IP4_ADDR(&ipaddr, 172, 16, 1, 5); + IP4_ADDR(&netmask, 255, 255, 255, 0); + IP4_ADDR(&gw, 172, 16, 1, 1); + temp = netif_add(&sl_netif, &ipaddr, &netmask, &gw, &int_no, slipif_init, ip_input); + if( temp == NULL ) { + printf("fail to netif init\n"); + return -1; + } + netif_set_up(&sl_netif); + sl_netif.mtu = 1500; + netif_set_link_up(&sl_netif); + + if( mode == 1 ) { + ip_napt_enable(ipaddr.addr, 1); + } else if(mode == 2) { + netif_set_default(&sl_netif); + } + + return 0; +} + +int slip_uart_init(int mode) +{ +#ifdef QUECTEL_CONFIG_UART0_SWAP_SUPPORT + uart_enable_swap(); +#endif + // Configure parameters of an UART driver, 921600 + // communication pins and install the driver + uart_config_t uart_config = { + .baud_rate = 921600, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE + }; + uart_param_config(EX_UART_NUM, &uart_config); + esp_err_t err; + int ret = 0; + + // Install UART driver, and get the queue. +#ifdef QUECTEL_CONFIG_HIGH_SPEED_SUPPORT + err = uart_driver_install(EX_UART_NUM, BUF_SIZE * 16, BUF_SIZE * 12, 512, &uart0_queue, 0); +#else + err = uart_driver_install(EX_UART_NUM, BUF_SIZE * 8, BUF_SIZE * 4, 512, &uart0_queue, 0); +#endif + if( err != ERR_OK ) { + printf("uart_driver_install fail err = %d\n", err); + return -1; + } + //uart_set_rx_timeout(EX_UART_NUM, 1); + ret = user_netif_init(mode); + if( ret != 0 ) return -1; + + // Create a task to handler UART event from ISR + xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 10, NULL); + + return 0; +} diff --git a/code/sdk/drivers/peripheral/slip/uart_slip.h b/code/sdk/drivers/peripheral/slip/uart_slip.h new file mode 100644 index 000000000..510159b90 --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/uart_slip.h @@ -0,0 +1,35 @@ +// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __CUSTOM_UART_H +#define __CUSTOM_UART_H + +/** + * @brief init uart config and config uart as slip netif bridge + */ +int slip_uart_init(int mode); + +/** + * @brief remove slip netif + */ +void user_netif_deinit(void); + +void user_netif_set_default(); + +/** + * @brief add slip netif + */ +int user_netif_init(int mode); + +#endif diff --git a/code/sdk/drivers/peripheral/slip/udp_server.c b/code/sdk/drivers/peripheral/slip/udp_server.c new file mode 100644 index 000000000..b8d48445a --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/udp_server.c @@ -0,0 +1,546 @@ +/* BSD Socket API Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "nvs.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include +#include "esp_wifi.h" + +#include "uart_slip.h" +#include "wifi_ap.h" +#include "wifi_station.h" +#include "web_server.h" +#include "udp_server.h" +#include "app_version.h" + +#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT +#include "smartconfig.h" +#endif + +extern int g_wifi_station_status; +extern int g_wifi_ap_status; +extern int g_wifi_ota_status; + +web_config_t tcp_web_config = {0}; + +#define PEER_IP "172.16.1.2" +#define PEER_PORT 5000 + +#define PORT 1000 +#define SSID_LENGTH 32 +#define PASSWORD_LENGTH 64 + +enum UDP_COMMAND_HEAD { + UDP_CHANGE_WEB_NETWORK = '0', // web config + UDP_WIFI_STATUS = '1', // status + UDP_CHANGE_AP = '2', // ap mode + UDP_CHANGE_STATION = '3', // station mode + UDP_OTA_UPDATE = '4', // ota upgrade + UDP_APP_VERSION = '5', // app version + UDP_SMART_CONFIG = '6', // smartconfig + UDP_CONFIG_QUERY = '7', // config query + UDP_EVENT_REPORT = 'F' // auto report +}; +// current work station +enum SSS_WORKING_STATUS { + SSS_WORKING_NONE = 0, // do nothing + SSS_WORKING_REINIT, // reinit uart slip + SSS_WORKING_RESTART, // restart device + SSS_WORKING_OTA // ota ing +}; + +static char *msg_wifi_resp[] = +{ + "OK", // op success + "ERROR", // op failure + "0", // no init + "1", // station mode, wifi connected + "2", // station mode, wifi connecting + "3", // web config mode + "4", // ap mode + "5", // ota ing + "6", // smart config mode +}; +#define RESP_STATUS_OFSET 2 + +#pragma pack(push) +#pragma pack(1) +struct tcp_msg_t { + char head[2]; + int length; + char buffer[512]; +}; +#pragma pack(pop) + +// status 0: init, 1: station 2: softap +typedef struct _quec_wifi_status_t { + int mode; + enum SSS_WORKING_STATUS s_status; +} quec_wifi_status_t; +quec_wifi_status_t quec_wifi_status ={0, 0}; + +static int g_listen_sock = 0; +struct sockaddr_in sourceAddr = {0}; + +extern int quec_config_query_entry(char *key, char *buffer); + +void set_current_wifi_stat(enum WIFI_CURRENT_SETTINNG stat) +{ + quec_wifi_status.mode = stat; +} + +static void tcp_device_restart() +{ + +} + +static void stop_current_wifi() +{ + +} + +static struct tcp_msg_t *unpack_tlv_format(char *rx_buffer, int length) +{ + char temp[8]; + struct tcp_msg_t *msg = (struct tcp_msg_t *)rx_buffer; + strncpy(temp, (char *)&msg->length, 4); + temp[4] = '\0'; + msg->length = atoi(temp); + + if( length != msg->length+6 ) return NULL; + return msg; +} + +static int pack_tlv_format(char *tx_buffer, char *head, char *content) +{ + int content_length = (int)strlen(content); + if( content == NULL || head == NULL || content_length > 9999 ) { + return -1; + } + + struct tcp_msg_t *msg = (struct tcp_msg_t *)tx_buffer; + strncpy(msg->head, head, 2); + //sprintf((char *)(&msg->length), "%04d", (unsigned char)content_length); + sprintf(&tx_buffer[2], "%04d", content_length); + + strcpy(msg->buffer, content); + return strlen(content)+6; +} + +static void udp_send_response(char *tx_buffer, char *head, char *content) +{ + // remain lock using + int len = pack_tlv_format(tx_buffer, head, content); + int err = 0; + if( len > 0 ) { + err = sendto(g_listen_sock, tx_buffer, len, 0, (struct sockaddr *)&sourceAddr, sizeof(sourceAddr)); + if (err < 0) { + printf("Error occured during sending: errno %d\n", errno); + } + } else { + printf("Error occured unkown send data\n"); + } +} + +void udp_ota_update(char *content) +{ + char ota_tx_buffer[128] = {0}; + char ota_head[2] = {0}; + ota_head[0] = 'F'; + ota_head[1] = UDP_EVENT_REPORT; + udp_send_response(ota_tx_buffer, ota_head, content); +} + +void udp_station_update(char *content) +{ + char station_tx_buffer[128] = {0}; + char station_head[2] = {0}; + if( sourceAddr.sin_port != 0 ) { + station_head[0] = 'F'; + station_head[1] = UDP_EVENT_REPORT; + udp_send_response(station_tx_buffer, station_head, content); + } +} + +static int resolve_msg_ap_connect(struct tcp_msg_t *msg) +{ + int ret = 0; + int index = 0; + char ssid[SSID_LENGTH]; + char password[PASSWORD_LENGTH]; + if( msg == NULL || msg->buffer == NULL ) return 1; + //ptr = strtok(data, ","); + char *ptr = strchr(msg->buffer, ','); + if( ptr == NULL ) { + return 1; + } + if( strlen(&ptr[1]) < 1 || strlen(&ptr[1]) >= PASSWORD_LENGTH ) { + return 1; + } + memset(password, 0, PASSWORD_LENGTH); + strncpy(password, &ptr[1], strlen(&ptr[1])); + + ptr[0] = '\0'; + if( strlen(msg->buffer) < 1 || strlen(msg->buffer) >= SSID_LENGTH ) { + return 1; + } + memset(ssid, 0, SSID_LENGTH); + strncpy(ssid, msg->buffer, strlen(msg->buffer)); + + printf("ssid: %s,password: %s\r\n", ssid, password); + return index; +} + +static int resolve_msg_wifi_status(struct tcp_msg_t *msg) +{ + int index = 0; + //printf("quec_wifi_status.mode = %d\n", quec_wifi_status.mode); + if( g_wifi_ota_status == 1 ) { + return 5; // ota ing + } + int web_server_status = 0; +#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT + int smartconfig_status = 0; +#endif + if( quec_wifi_status.mode == WIFI_CURRENT_SETTINNG_STATION) { // station + +#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT + smartconfig_status = get_smartconfig_status(); + if( smartconfig_status != -1 ) { + index = 6; + } + else +#endif + if( g_wifi_station_status == 1 ) { + index = 1; // connected success + } else { + index = 2; // connected fail + } + } else if( quec_wifi_status.mode == WIFI_CURRENT_SETTINNG_SOFTAP ){ + web_server_status = get_web_server_status(); + if( web_server_status == 1 ) { + index = 3; // web server start + } else if( g_wifi_ap_status == 1 ) { + index = 4; // ap construct + } + } + return index; +} + +static int resolve_msg_ap_construct(struct tcp_msg_t *msg) +{ + int ret = 0; + int index = 0; + char ssid[SSID_LENGTH]; + char password[PASSWORD_LENGTH]; + if( msg->buffer == NULL ) return 1; + //ptr = strtok(data, ","); + char *ptr = strchr(msg->buffer, ','); + if( ptr == NULL ) { + return 1; + } + if( strlen(&ptr[1]) < 1 || strlen(&ptr[1]) >= PASSWORD_LENGTH ) { + return 1; + } + memset(password, 0, PASSWORD_LENGTH); + strncpy(password, &ptr[1], strlen(&ptr[1])); + + ptr[0] = '\0'; + if( strlen(msg->buffer) < 1 || strlen(msg->buffer) >= SSID_LENGTH ) { + return 1; + } + memset(ssid, 0, SSID_LENGTH); + strncpy(ssid, msg->buffer, strlen(msg->buffer)); + stop_current_wifi(); + + //printf("ssid: %s,password: %s\r\n", ssid, password); + ret = softap_wifi_init(ssid, password, 0); + if( ret == 0 ) { + index = 0; + } else { + index = 1; + } + web_server_status_reset(); + quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_SOFTAP; + quec_wifi_status.s_status = SSS_WORKING_REINIT; + return index; +} + +static int resolve_msg_web_network(struct tcp_msg_t *msg) +{ + int index = 0; + char ssid[SSID_LENGTH]; + char password[PASSWORD_LENGTH]; + if( msg->buffer == NULL ) return 1; + + if( (msg->length == 1) && (msg->buffer[0] == '0') ) { + strcpy(tcp_web_config.user, ""); + strcpy(tcp_web_config.password, ""); + quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_SOFTAP; + quec_wifi_status.s_status = SSS_WORKING_RESTART; + return index; + } + //ptr = strtok(data, ","); + char *ptr = strchr(msg->buffer, ','); + if( ptr == NULL ) { + return 1; + } + if( strlen(&ptr[1]) < 1 || strlen(&ptr[1]) >= PASSWORD_LENGTH ) { + return 1; + } + memset(password, 0, PASSWORD_LENGTH); + strncpy(password, &ptr[1], strlen(&ptr[1])); + + ptr[0] = '\0'; + if( strlen(msg->buffer) < 1 || strlen(msg->buffer) >= SSID_LENGTH ) { + return 1; + } + memset(ssid, 0, SSID_LENGTH); + strncpy(ssid, msg->buffer, strlen(msg->buffer)); + //printf("ssid: %s,password: %s\r\n", ssid, password); + + memcpy(tcp_web_config.user, ssid, 32); + memcpy(tcp_web_config.password, password, 64); + quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_SOFTAP; + quec_wifi_status.s_status = SSS_WORKING_RESTART; + return index; +} + +static int resolve_msg_smartconfig_network(struct tcp_msg_t *msg) +{ + int index = 0; +#ifdef QUECTEL_CONFIG_SMARTCONFIG_SUPPORT + if( msg->buffer == NULL || msg->length != 1 ) return 1; + printf("msg->buffer[0] = %c\n", msg->buffer[0]); + if( msg->buffer[0] == '0' ) { + stop_smartconfig(); + quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_STATION; + quec_wifi_status.s_status = SSS_WORKING_RESTART; + return index; + } + stop_current_wifi(); + web_server_status_reset(); + + int ret = start_smartconfig(msg->buffer[0] - '1'); + if( ret != 0 ) { + printf("start_smartconfig ret = %d\n", ret); + return 1; + } + + quec_wifi_status.mode = WIFI_CURRENT_SETTINNG_STATION; + quec_wifi_status.s_status = SSS_WORKING_REINIT; +#else + index = 1; +#endif + return index; +} + +static int resolve_config_query(struct tcp_msg_t *msg) +{ + int index = -1; + char config_tx_buffer[256] = {0}; + char buffer[128]; + if( msg->buffer == NULL && msg->buffer[0] != '0') return 1; + + memset(buffer, 0x00, sizeof(buffer)); + index = quec_config_query_entry(msg->buffer, buffer); + if( index == 0 ) { + udp_send_response(config_tx_buffer, msg->head, buffer); + } else { + index = 1; + } + + return index; +} + +static int resolve_msg_ota(struct tcp_msg_t *msg) +{ + int index = 0; + if( msg->buffer == NULL ) return 1; +#ifdef QUECTEL_CONFIG_OTA_SUPPORT + extern int ota_app_main(char *ota_server); + //printf("ota url = %s\n", msg->buffer); + int ret = ota_app_main(msg->buffer); + if( ret != 0 ) { + index = 1; + } +#else + index = 1; +#endif + return index; +} + +static int resolve_msg_app_version(struct tcp_msg_t *msg) +{ + int index = -1; + char version_tx_buffer[256] = {0}; + if( msg->buffer == NULL && msg->buffer[0] != '0') return 1; + char version[128] = {0}; + snprintf(version, 128, "sdk: %s\nmodel: %s\nversion: %s\ntime: %s", + build_sdk, build_model, build_version, build_time); + + udp_send_response(version_tx_buffer, msg->head, version); + return index; +} + +static int udp_packet_parse(char *rx_buffer, int len) +{ + struct tcp_msg_t *msg = unpack_tlv_format(rx_buffer, len); + int index = 0; + if( g_wifi_ota_status == 1 && msg->head[1] != UDP_WIFI_STATUS ) { // ota only status check + return 1; + } + if( msg != NULL ) { + switch (msg->head[1]) { + case UDP_WIFI_STATUS: + index = resolve_msg_wifi_status(msg); + index += RESP_STATUS_OFSET; + break; + case UDP_CHANGE_WEB_NETWORK: + index = resolve_msg_web_network(msg); + break; + case UDP_CHANGE_AP: + index = resolve_msg_ap_construct(msg); + break; + case UDP_CHANGE_STATION: + index = resolve_msg_ap_connect(msg); + break; + case UDP_OTA_UPDATE: + index = resolve_msg_ota(msg); + break; + case UDP_APP_VERSION: + index = resolve_msg_app_version(msg); + break; + case UDP_SMART_CONFIG: + index = resolve_msg_smartconfig_network(msg); + break; + case UDP_CONFIG_QUERY: + index = resolve_config_query(msg); + break; + default: + printf("error message: %s\n", rx_buffer); + index = 1; + break; + } + } else { + printf("wrong format msg and exit\n"); + index = 1; + } + return index; +} + +static int udp_socket_init() +{ + int addr_family; + int ip_protocol; + int opt = 1; + struct sockaddr_in destAddr; + char addr_str[128]; + + // destAddr.sin_addr.s_addr = htonl(INADDR_ANY); + destAddr.sin_addr.s_addr = inet_addr("172.16.1.5"); + destAddr.sin_family = AF_INET; + destAddr.sin_port = htons(PORT); + addr_family = AF_INET; + ip_protocol = IPPROTO_IP; + inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); + + int listen_sock = socket(addr_family, SOCK_DGRAM, ip_protocol); + if (listen_sock < 0) { + printf("Unable to create socket: errno %d\n", errno); + return -1; + } + setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); + if (err != 0) { + printf("Socket unable to bind: errno %d\n", errno); + return -1; + } + + sourceAddr.sin_addr.s_addr = inet_addr(PEER_IP); + sourceAddr.sin_family = AF_INET; + sourceAddr.sin_port = htons(PEER_PORT); + + return listen_sock; +} + +void udp_server_task(void *pvParameters) +{ + char rx_buffer[512]; + char tx_buffer[256]; + int index; + uint addrLen = sizeof(sourceAddr); + while (1) { + if( g_listen_sock > 0 ) close(g_listen_sock); + g_listen_sock = udp_socket_init(); + if( g_listen_sock < 0 ) { + printf("socket init fail and retry\n"); + vTaskDelay(1000/portTICK_RATE_MS); + continue; + } + + while (1) { + memset(rx_buffer, 0, sizeof(rx_buffer)); + int len = recvfrom(g_listen_sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&sourceAddr, &addrLen); + // Error occured during receiving + if (len < 0) { + printf("recv failed: errno %d\n", errno); + break; + } else if (len == 0) { + printf("Connection closed\n"); + break; + } + // Data received + rx_buffer[len] = '\0'; // Null-terminate whatever we received and treat like a string + printf("Received %d bytes, rx_buffer: %s\n", len, rx_buffer); + index = udp_packet_parse(rx_buffer, len); + if( index >= 0 ) { + udp_send_response(tx_buffer, rx_buffer, msg_wifi_resp[index]); + } + + if( quec_wifi_status.s_status == SSS_WORKING_RESTART ) { + //station_wifi_set_info("",""); + + tcp_device_restart(); + } else if( quec_wifi_status.s_status == SSS_WORKING_REINIT ) { + user_netif_deinit(); + vTaskDelay(1000/portTICK_RATE_MS); + user_netif_init(quec_wifi_status.mode); + quec_wifi_status.s_status = SSS_WORKING_NONE; + break; + } + } + } + + vTaskDelete(NULL); +} +#if 0 +void wifi_status() +{ + char tx_buffer[128] = {0}; + int index = resolve_msg_wifi_status(NULL); + char *head = "FF"; + int len = pack_tlv_format(tx_buffer, head, msg_wifi_status[index]); + printf("wifi_status len = %d, msg = [%s]\n",len, tx_buffer); +} +#endif \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/slip/udp_server.h b/code/sdk/drivers/peripheral/slip/udp_server.h new file mode 100644 index 000000000..a2fac0f1a --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/udp_server.h @@ -0,0 +1,30 @@ +/* BSD Socket API Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#ifndef __UDP_SERVER_H +#define __UDP_SERVER_H + +// status 0: init, 1: station 2: softap +enum WIFI_CURRENT_SETTINNG { + WIFI_CURRENT_SETTINNG_NONE = 0, + WIFI_CURRENT_SETTINNG_STATION, + WIFI_CURRENT_SETTINNG_SOFTAP +}; + +typedef struct _web_config_t { + int used; + char user[36]; + char password[64]; +} web_config_t; + +void set_current_wifi_stat(enum WIFI_CURRENT_SETTINNG stat); + +void udp_server_task(void *pvParameters); + +void udp_ota_update(char *content); +#endif diff --git a/code/sdk/drivers/drivers/driver/touch/CMakeLists.txt b/code/sdk/drivers/peripheral/touch/CMakeLists.txt old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/CMakeLists.txt rename to code/sdk/drivers/peripheral/touch/CMakeLists.txt diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.c b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c old mode 100755 new mode 100644 similarity index 98% rename from code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.c rename to code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c index d52db5b26..8fc2aa673 --- a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.c +++ b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c @@ -39,7 +39,7 @@ ext_errno ztw523_register_handle(const ztw523_ctrl_ops *peri_data, touch_callbac ext_errno ret; - //tp_err("ztw523_register_handle*****************888888888"); + //tp_err("ft6x46_register_handle*****************888888888"); g_ztw523_callback = func; /* register int io interrupt handler */ uapi_gpio_init(); @@ -47,7 +47,7 @@ ext_errno ztw523_register_handle(const ztw523_ctrl_ops *peri_data, touch_callbac uapi_gpio_set_dir(ZTW523_INT_GPIO, GPIO_DIRECTION_INPUT); ret = uapi_gpio_register_isr_func(ZTW523_INT_GPIO, GPIO_INTERRUPT_FALLING_EDGE, ztw523_gpio_isr_handle); if (ret != 0) { - tp_err("ztw523 int callback register fail! ret=0x%x", ret); + tp_err("ft6x46 int callback register fail! ret=0x%x", ret); return ret; } @@ -474,7 +474,7 @@ ext_errno ztw523_host_peripheral_init(ztw523_ctrl_attr *attr) ext_errno ret; if (attr == NULL) { - tp_err("ztw523 communication interface cfg is empty!"); + tp_err("ft6x46 communication interface cfg is empty!"); return EXT_ERR_FAILURE; } ret = ztw523_ctrl_attr_check(attr); @@ -507,7 +507,7 @@ ext_errno ztw523_host_peripheral_init(ztw523_ctrl_attr *attr) ext_errno ztw523_host_init_sample(void) { ext_errno ret; - PRINT("**********ztw523_host_init_sample**********\r\n"); + PRINT("**********ft6x46_host_init_sample**********\r\n"); ret = ztw523_host_peripheral_init(&g_ctrl_attr); ret = ztw523_init(); if (ret != EXT_ERR_SUCCESS) { diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.h b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_ctrl.h rename to code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.h diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_drv1.c b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_drv1.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_drv1.c rename to code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_drv1.c diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_drv1.h b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_drv1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_drv1.h rename to code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_drv1.h diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_touch1.c b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_touch1.c old mode 100755 new mode 100644 similarity index 98% rename from code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_touch1.c rename to code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_touch1.c index e9074326f..455eb599e --- a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_touch1.c +++ b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_touch1.c @@ -420,7 +420,7 @@ ext_errno ztw523_irq_callback(uint8_t *data_buf, uint8_t data_len) #define FTS_CMD_START_DELAY 12 -static ext_errno ztw523_power_sequence(void) +static ext_errno ft6x46_power_sequence(void) { ext_errno ret; #if 0 @@ -500,13 +500,13 @@ static ext_errno ztw523_power_sequence(void) tp_err("3333333get ic information, error2"); return EXT_ERR_TP_ZTW523_POWERUP_READ_CHIPID; } - tp_err("11111111111111get ic information, chip id = 0x%02x%02x", chip_id[0], chip_id[1]); + tp_print("11111111111111get ic information, chip id = 0x%02x%02x", chip_id[0], chip_id[1]); if ((FTS_CHIP_IDH == chip_id[0]) && (FTS_CHIP_IDL == chip_id[1])) { tp_err("get ic information, chip id = 0x%02x%02x", chip_id[0], chip_id[1]); return EXT_ERR_SUCCESS; } - tp_err("fw is invalid, need read boot id"); + // tp_err("fw is invalid, need read boot id"); ret = tp_ft6x46_i2c_data_write_reg(0x55, 0xAA); if (ret != EXT_ERR_SUCCESS) { tp_err("start cmd write fail"); @@ -939,7 +939,7 @@ static ext_errno ztw523_set_standby_mode(void) ret = ztw523_standby(); if (ret != EXT_ERR_SUCCESS) { - tp_err("TOUCH:ztw523 set standby 0x%x", ret); + tp_err("TOUCH:ft6x46 set standby 0x%x", ret); return EXT_ERR_FAILURE; } #ifdef ZTW523_GESTURE_WAKEUP @@ -954,7 +954,7 @@ static ext_errno ztw523_set_sleep_mode(void) ret = ztw523_suspend(); if (ret != EXT_ERR_SUCCESS) { - tp_err("TOUCH:ztw523 set suspend fail 0x%x", ret); + tp_err("TOUCH:ft6x46 set suspend fail 0x%x", ret); } #ifdef ZTW523_GESTURE_WAKEUP g_ztw523_drv.gesture_wakeup = TD_FALSE; @@ -979,7 +979,7 @@ static ext_errno ztw523_set_normal_mode(void) } /* delay 50ms */ osDelay(ZTW523_GENERAL_DELAY_50); - ret = ztw523_power_sequence(); + ret = ft6x46_power_sequence(); if (ret != EXT_ERR_SUCCESS) { return EXT_ERR_FAILURE; } @@ -1028,7 +1028,7 @@ static ext_errno ztw523_config(void) } /* Step 2 power up */ - ret = ztw523_power_sequence(); + ret = ft6x46_power_sequence(); if (ret != EXT_ERR_SUCCESS) { tp_err("TOUCH:init powerup fail 0x%x", ret); return EXT_ERR_TP_ZTW523_INIT_POWERUP; diff --git a/code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_touch1.h b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_touch1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ft6x46_touch/ft6x46_touch1.h rename to code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_touch1.h diff --git a/code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_ctrl.c b/code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_ctrl.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_ctrl.c rename to code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_ctrl.c diff --git a/code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_ctrl.h b/code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_ctrl.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_ctrl.h rename to code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_ctrl.h diff --git a/code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_drv1.c b/code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_drv1.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_drv1.c rename to code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_drv1.c diff --git a/code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_drv1.h b/code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_drv1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_drv1.h rename to code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_drv1.h diff --git a/code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_touch1.c b/code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_touch1.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_touch1.c rename to code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_touch1.c diff --git a/code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_touch1.h b/code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_touch1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/tma525b_touch/tma525b_touch1.h rename to code/sdk/drivers/peripheral/touch/tma525b_touch/tma525b_touch1.h diff --git a/code/sdk/drivers/drivers/driver/touch/touch_screen_def.h b/code/sdk/drivers/peripheral/touch/touch_screen_def.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/touch_screen_def.h rename to code/sdk/drivers/peripheral/touch/touch_screen_def.h diff --git a/code/sdk/drivers/drivers/driver/touch/touch_screen_drv.c b/code/sdk/drivers/peripheral/touch/touch_screen_drv.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/touch_screen_drv.c rename to code/sdk/drivers/peripheral/touch/touch_screen_drv.c diff --git a/code/sdk/drivers/drivers/driver/touch/touch_screen_drv.h b/code/sdk/drivers/peripheral/touch/touch_screen_drv.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/touch_screen_drv.h rename to code/sdk/drivers/peripheral/touch/touch_screen_drv.h diff --git a/code/sdk/drivers/drivers/driver/touch/touch_screen_queue1.c b/code/sdk/drivers/peripheral/touch/touch_screen_queue1.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/touch_screen_queue1.c rename to code/sdk/drivers/peripheral/touch/touch_screen_queue1.c diff --git a/code/sdk/drivers/drivers/driver/touch/touch_screen_queue1.h b/code/sdk/drivers/peripheral/touch/touch_screen_queue1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/touch_screen_queue1.h rename to code/sdk/drivers/peripheral/touch/touch_screen_queue1.h diff --git a/code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_ctrl.c b/code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_ctrl.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_ctrl.c rename to code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_ctrl.c diff --git a/code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_ctrl.h b/code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_ctrl.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_ctrl.h rename to code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_ctrl.h diff --git a/code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_drv1.c b/code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_drv1.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_drv1.c rename to code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_drv1.c diff --git a/code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_drv1.h b/code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_drv1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_drv1.h rename to code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_drv1.h diff --git a/code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_touch1.c b/code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_touch1.c old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_touch1.c rename to code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_touch1.c diff --git a/code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_touch1.h b/code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_touch1.h old mode 100755 new mode 100644 similarity index 100% rename from code/sdk/drivers/drivers/driver/touch/ztw523_touch/ztw523_touch1.h rename to code/sdk/drivers/peripheral/touch/ztw523_touch/ztw523_touch1.h diff --git a/code/sdk/drivers/peripheral/utils/CMakeLists.txt b/code/sdk/drivers/peripheral/utils/CMakeLists.txt new file mode 100644 index 000000000..33ba8c3f5 --- /dev/null +++ b/code/sdk/drivers/peripheral/utils/CMakeLists.txt @@ -0,0 +1,41 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "custom_utils") + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/custom_utils.c + ${CMAKE_CURRENT_SOURCE_DIR}/custom_utils_at_cmd.c +) + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +SUPPORT_AT_CUSTOMUTILS +) + +# 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() diff --git a/code/sdk/drivers/peripheral/utils/custom_utils.c b/code/sdk/drivers/peripheral/utils/custom_utils.c new file mode 100644 index 000000000..a0410aae5 --- /dev/null +++ b/code/sdk/drivers/peripheral/utils/custom_utils.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n + * + * Description: Button driver source file \n + * Author: @CompanyNameTag \n + * History: \n + * 2023-02-24, Create file. \n + */ + +#include "pinctrl.h" +#include "button_porting.h" +#include "platform_core.h" +#include "gpio.h" +#include "gpio_porting.h" +#include "debug_print.h" +#include "rtc.h" +#include "timer.h" +#include "systick.h" +#include "chip_core_irq.h" +#include "pwm.h" +#include "pwm_porting.h" +#include "pinctrl.h" +#include "errcode.h" + + +#define SUPPORT_NV + +#ifdef SUPPORT_NV +#include "nv.h" +#include "key_id.h" +#include "common.h" +#endif + + + +uint32_t zh_get_sn(uint8_t *buf_sn, uint32_t *len_sn) +{ + +#ifdef SUPPORT_NV + if( buf_sn == NULL) + return ERRCODE_FAIL; + uint16_t len = 0; + custom_key_sn_t sn = {0}; + errcode_t nvRet = uapi_nv_read(NV_ID_CUSTOM_KEY_SERIAL_NUM, sizeof(custom_key_sn_t), &len, &sn); + if (nvRet != ERRCODE_SUCC) { + *len_sn = 0; + } + memcpy_s(buf_sn,sizeof(sn.sn),sn.sn,sn.size); + *len_sn = sn.size; + PRINT("get sn len %d, ret %d , %s\r\n",sn.size,nvRet,sn.sn); +#endif + return ERRCODE_SUCC; +} + + +uint32_t zh_set_sn(uint8_t *buf_sn, uint32_t len_sn) +{ + +#ifdef SUPPORT_NV + if( buf_sn == NULL || len_sn == 0) + return ERRCODE_FAIL; + + uint16_t len = 0; + custom_key_sn_t sn = {0}; + if (len_sn > sizeof(sn.sn)) + { + len = sizeof(sn.sn); + }else{ + len = len_sn; + } + sn.size = len; + memcpy_s(sn.sn,sizeof(sn.sn),buf_sn,len); + errcode_t nvRet = uapi_nv_write(NV_ID_CUSTOM_KEY_SERIAL_NUM, &sn, sizeof(custom_key_sn_t)); + PRINT("write sn len %d, ret %d , %s\r\n",len,nvRet,sn.sn); +#endif + return nvRet; +} + diff --git a/code/sdk/drivers/peripheral/utils/custom_utils.h b/code/sdk/drivers/peripheral/utils/custom_utils.h new file mode 100644 index 000000000..f7895bb07 --- /dev/null +++ b/code/sdk/drivers/peripheral/utils/custom_utils.h @@ -0,0 +1,36 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n + * + * Description: Button driver header file \n + * Author: @CompanyNameTag \n + * History: \n + * 2023-02-24, Create file. \n + */ +#ifndef BUTTON_H +#define BUTTON_H + +#include "hal_gpio.h" +#include "soc_osal.h" +#include "platform_core.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +uint32_t zh_get_sn(uint8_t *buf_sn, uint32_t *len_sn); +uint32_t zh_set_sn(uint8_t *buf_sn, uint32_t len_sn); + + +/** + * @} + */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.c b/code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.c new file mode 100644 index 000000000..5174b3682 --- /dev/null +++ b/code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.c @@ -0,0 +1,90 @@ + +// #include "custom_utils.h" + + +#include "at_cmd_api.h" +#include "pm_control.h" +#include "custom_utils.h" +#include "debug_print.h" + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define CUSTOM_UTILS_MAX_ARGC 8 +#define CUSTOM_UTILS_MAX_ARGV_LEN 64 + +#define CUSTOM_UTILS_SUCCESS 0 +#define CUSTOM_UTILS_FAILED (-1) + + +#include "common.h" + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_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 >= CUSTOM_UTILS_MAX_ARGC) { + return CUSTOM_UTILS_FAILED; + } + } else { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= CUSTOM_UTILS_MAX_ARGV_LEN) { + return CUSTOM_UTILS_FAILED; + } + } + } + if (pos != 0) { + *argc += 1; + } + + return CUSTOM_UTILS_SUCCESS; +} + + +static uint32_t custom_utils_setsn(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t argv[CUSTOM_UTILS_MAX_ARGC][CUSTOM_UTILS_MAX_ARGV_LEN] = { 0 }; + uint32_t argc = 0; + + int ret = ConvertCmdToParam(para, paraLen, argv, &argc); + if (ret != CUSTOM_UTILS_SUCCESS) { + PRINT("CUSTOM_UTILSTEST ATCMD Convert Command Failed\n"); + return ERRCODE_FAIL; + } + + if (argc != 1) { + PRINT("CUSTOM_UTILSTEST ATCMD Set Parameter Failed argc %d\n",argc); + return ERRCODE_FAIL; + } + uint8_t *sn_buf = (uint8_t*)argv[0]; + uint16_t len = strlen((const char*)sn_buf); + PRINT("set sn = %s \r\n",sn_buf); + uint32_t rret = zh_set_sn(sn_buf,len); + return rret; +} +static uint32_t custom_utils_getsn(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t sn_buf[32] = {0}; + uint32_t len = 0; + uint32_t ret = zh_get_sn(sn_buf,&len); + PRINT("get sn len %d , %s \r\n",len,sn_buf); + return ret; +} +static const at_cmd_table_t g_custom_utils_cmd[] = { + { (char *)"AT^CUSTOM_SN", custom_utils_setsn, (char *)"123456789ABCDEF2345678" }, + { (char *)"AT^CUSTOM_SN?", custom_utils_getsn, (char *)" " }, +}; + +at_cmd_table_t *get_custom_utils_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_custom_utils_cmd); + return (at_cmd_table_t *)g_custom_utils_cmd; +} diff --git a/code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.h b/code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.h new file mode 100644 index 000000000..8793e366c --- /dev/null +++ b/code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 CUSTOM_UTILS_AT_PROCESS_H +#define CUSTOM_UTILS_AT_PROCESS_H + +#include +#include +#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_custom_utils_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/drivers/peripheral/vibrator/CMakeLists.txt b/code/sdk/drivers/peripheral/vibrator/CMakeLists.txt new file mode 100644 index 000000000..93b247f87 --- /dev/null +++ b/code/sdk/drivers/peripheral/vibrator/CMakeLists.txt @@ -0,0 +1,41 @@ +#=============================================================================== +# @brief cmake file +# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. +#=============================================================================== +set(COMPONENT_NAME "vibrator") + +set(SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/vibrator.c + ${CMAKE_CURRENT_SOURCE_DIR}/vibrator_at_cmd.c +) + +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(PRIVATE_HEADER +) + +set(PRIVATE_DEFINES +) + +set(PUBLIC_DEFINES +SUPPORT_AT_VIBRATOR +) + +# 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() diff --git a/code/sdk/drivers/peripheral/vibrator/vibrator.c b/code/sdk/drivers/peripheral/vibrator/vibrator.c new file mode 100644 index 000000000..c8acb13e5 --- /dev/null +++ b/code/sdk/drivers/peripheral/vibrator/vibrator.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n + * + * Description: Button driver source file \n + * Author: @CompanyNameTag \n + * History: \n + * 2023-02-24, Create file. \n + */ + +#include "pinctrl.h" +#include "button_porting.h" +#include "platform_core.h" +#include "gpio.h" +#include "gpio_porting.h" +#include "debug_print.h" +#include "rtc.h" +#include "timer.h" +#include "systick.h" +#include "chip_core_irq.h" +#include "pwm.h" +#include "pwm_porting.h" +#include "pinctrl.h" +#define VIBRATOR_GPIOPPIN S_AGPIO_R2 +// #define VIBRATORPIN_MODE HAL_PIO_FUNC_PWMP1_M2 +#define VIBRATORPIN_MODE HAL_PIO_FUNC_PWMN1_M3 + +#define TEST_TCXO_DELAY_1000MS 1000 +#define TEST_PARAM_FOR_PWM_10 10 +#define TEST_PARAM_FOR_PWM_200 200 + +static pwm_channel_t channel = PWM_1; +static pin_t pin = VIBRATOR_GPIOPPIN; +static pin_mode_t mode = VIBRATORPIN_MODE; +static uint32_t delay_ms = 500; +static pwm_config_t cfg_repeat = { 100, 100, 0xFF, 0xFF, true }; +static uint32_t param_index = 0; +static uint16_t repeat_times = 0; +static errcode_t pwm_test_callback(uint8_t channel) +{ + PRINT("PWM number is %d, func of interrupt start. repeat_times %d\r\n", channel,repeat_times++); + uapi_pwm_isr(channel); + return ERRCODE_SUCC; +} +static uint8_t pwm_started = 0; +static int test_pwm_repeat(int vibratorType) +{ + + if (pwm_started == 1) + { + PRINT("PWM alredy started! skip start \r\n"); + return -1; + } + + if (channel >= PWM_MAX_NUMBER) + { + PRINT("Paremeter Error. PWM max number is 5. \r\n"); + return -1; + } + pwm_started = 1; + repeat_times = 0; + uapi_pwm_init(); + uapi_pin_set_mode(pin, mode); + PRINT("+++++++ pwm init success +++++++ \r\n"); + uint32_t pwm_frequency = uapi_pwm_get_frequency(channel); + /* test for repeat, interrupt only be call when stop or close */ + PRINT("+++++++ Start pwm repeat test +++++++ pwm_frequency %u\r\n",pwm_frequency); + // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + // cfg_repeat.high_time = pwm_frequency/2; + // cfg_repeat.low_time = pwm_frequency/2; + uapi_pwm_open(channel, &cfg_repeat); + uapi_pwm_unregister_interrupt(channel); + uapi_pwm_register_interrupt(channel, pwm_test_callback); +#if defined(CONFIG_PWM_USING_V151) + uapi_pwm_set_group(0, 1u << channel); + uapi_pwm_start(0); +#else + uapi_pwm_start(channel); +#endif + // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_tcxo_delay_ms(delay_ms); + + for (uint32_t test_times = 1; test_times <= vibratorType; test_times++) { + + // uapi_pwm_check(channel) + PRINT("+++++++ pwm repeat interrupt +++++++ \r\n"); + if (test_times == vibratorType) { + PRINT("+++++++ pwm repeat ready to trigger interrupt +++++++ \r\n"); + uapi_pwm_close(channel); + break; + PRINT("+++++++ pwm repeat exit interrupt +++++++ \r\n"); + } + uapi_tcxo_delay_ms(delay_ms); + } + + uapi_pwm_close(channel); + // uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS); + uapi_tcxo_delay_ms(delay_ms); + uapi_pwm_deinit(); + pwm_started = 0; + PRINT("+++++++ pwm stoped +++++++ \r\n"); + + return 0; +} +void g_VibratorFunc(uint8_t vibratorType , uint16_t delaytime) +{ + + if(vibratorType <1 || vibratorType > 3) + { + PRINT("g_VibratorFunc vib times should in 1~3 \r\n",vibratorType); + }else{ + PRINT("g_VibratorFunc vib %d times , delaytime %d\r\n",vibratorType , delaytime); + delay_ms = delaytime; + test_pwm_repeat(vibratorType); + } +} diff --git a/code/sdk/drivers/peripheral/vibrator/vibrator.h b/code/sdk/drivers/peripheral/vibrator/vibrator.h new file mode 100644 index 000000000..b0983db6e --- /dev/null +++ b/code/sdk/drivers/peripheral/vibrator/vibrator.h @@ -0,0 +1,36 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n + * + * Description: Button driver header file \n + * Author: @CompanyNameTag \n + * History: \n + * 2023-02-24, Create file. \n + */ +#ifndef BUTTON_H +#define BUTTON_H + +#include "hal_gpio.h" +#include "soc_osal.h" +#include "platform_core.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ +/** + * vibtype 1 vib1 , 2 vib2, 3 vib3 +*/ +void g_VibratorFunc(uint8_t vibratorType , uint16_t delaytime); + +/** + * @} + */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/vibrator/vibrator_at_cmd.c b/code/sdk/drivers/peripheral/vibrator/vibrator_at_cmd.c new file mode 100644 index 000000000..6f54417bd --- /dev/null +++ b/code/sdk/drivers/peripheral/vibrator/vibrator_at_cmd.c @@ -0,0 +1,77 @@ + +// #include "vibrator.h" + + +#include "at_cmd_api.h" +#include "pm_control.h" +#include "vibrator.h" +#include "debug_print.h" + +#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) +#define VIBRATOR_MAX_ARGC 8 +#define VIBRATOR_MAX_ARGV_LEN 64 + +#define VIBRATOR_SUCCESS 0 +#define VIBRATOR_FAILED (-1) + +static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen, + uint8_t argv[VIBRATOR_MAX_ARGC][VIBRATOR_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 >= VIBRATOR_MAX_ARGC) { + return VIBRATOR_FAILED; + } + } else { + argv[*argc][pos] = para[i]; + pos++; + if (pos >= VIBRATOR_MAX_ARGV_LEN) { + return VIBRATOR_FAILED; + } + } + } + if (pos != 0) { + *argc += 1; + } + + return VIBRATOR_SUCCESS; +} + + +static uint32_t vibrator_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t argv[VIBRATOR_MAX_ARGC][VIBRATOR_MAX_ARGV_LEN] = { 0 }; + uint32_t argc = 0; + + int ret = ConvertCmdToParam(para, paraLen, argv, &argc); + if (ret != VIBRATOR_SUCCESS) { + PRINT("VIBRATORTEST ATCMD Convert Command Failed\n"); + return ERRCODE_FAIL; + } + + if (argc != 2) { + PRINT("VIBRATORTEST ATCMD Set Parameter Failed argc %d\n",argc); + return ERRCODE_FAIL; + } + uint8_t channel = (uint8_t)atoi((char*)argv[0]); + uint16_t delaytime = (uint16_t)atoi((char*)argv[1]); + g_VibratorFunc(channel,delaytime); + return ERRCODE_SUCC; +} + +static const at_cmd_table_t g_vibrator_cmd[] = { + { (char *)"AT^VIBRATORTEST", vibrator_do_test, (char *)"1" }, +}; + +at_cmd_table_t *get_vibrator_cmd_table(uint32_t *cmd_count) +{ + *cmd_count = ARRAY_COUNT(g_vibrator_cmd); + return (at_cmd_table_t *)g_vibrator_cmd; +} diff --git a/code/sdk/drivers/peripheral/vibrator/vibrator_at_cmd.h b/code/sdk/drivers/peripheral/vibrator/vibrator_at_cmd.h new file mode 100644 index 000000000..57959aef0 --- /dev/null +++ b/code/sdk/drivers/peripheral/vibrator/vibrator_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 VIBRATOR_AT_PROCESS_H +#define VIBRATOR_AT_PROCESS_H + +#include +#include +#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_vibrator_cmd_table(uint32_t *cmd_count); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif diff --git a/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy.config b/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy.config index 3115c2ae0..e5fc7ec65 100755 --- a/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy.config +++ b/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy.config @@ -76,7 +76,7 @@ LOSCFG_TASK_JOINABLE=y LOSCFG_BASE_CORE_TSK_MONITOR=y LOSCFG_TASK_STACK_STATIC_ALLOCATION=y LOSCFG_TASK_STACK_DYNAMIC_ALLOCATION=y -LOSCFG_BASE_CORE_TSK_LIMIT=32 +LOSCFG_BASE_CORE_TSK_LIMIT=64 LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE=1024 LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE=2048 LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE=2048 diff --git a/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy_xts.config b/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy_xts.config index d66e1b699..47302b430 100755 --- a/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy_xts.config +++ b/code/sdk/kernel/liteos/liteos_v207.1.0/Huawei_LiteOS/tools/build/config/brandy_xts.config @@ -76,7 +76,7 @@ LOSCFG_TASK_JOINABLE=y LOSCFG_BASE_CORE_TSK_MONITOR=y LOSCFG_TASK_STACK_STATIC_ALLOCATION=y LOSCFG_TASK_STACK_DYNAMIC_ALLOCATION=y -LOSCFG_BASE_CORE_TSK_LIMIT=40 +LOSCFG_BASE_CORE_TSK_LIMIT=64 LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE=1024 LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE=2048 LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE=2048 diff --git a/code/sdk/middleware/chips/brandy/nv/nv_config/cfg/acore/app.json b/code/sdk/middleware/chips/brandy/nv/nv_config/cfg/acore/app.json index 38006070c..52dc09067 100755 --- a/code/sdk/middleware/chips/brandy/nv/nv_config/cfg/acore/app.json +++ b/code/sdk/middleware/chips/brandy/nv/nv_config/cfg/acore/app.json @@ -41,7 +41,7 @@ "key_status": "alive", "structure_type": "btsrv_local_device_info_t", "attributions": 1, - "value": [[40,17,6,133,105, 89],0,0,["W","a","t","c","h","D","e","m","o",0]] + "value": [[40,17,6,133,105, 89],0,0,["W","a","t","c","h","S","o","a","r",0]] }, "btsrv_paired_device_info":{ "key_id": "0x2102", @@ -87,6 +87,17 @@ 65576964, 1000, 679102459, 67108874, 327680, 655367, 2126009683, 654734439, 1, 0, 0, 0, 0, 0, 10551272, 655336, 4286447619, 64536, 500, 16384, 3277, 0, 66049, 0]] + }, + "custom_key_serial_num":{ + "key_id": "0x1010", + "key_status": "alive", + "structure_type": "custom_key_sn_t", + "attributions": 4, + "value": [32, + [0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0]] } } } diff --git a/code/sdk/middleware/chips/brandy/nv/nv_config/include/common.h b/code/sdk/middleware/chips/brandy/nv/nv_config/include/common.h index db3b33bf7..7259af9bd 100755 --- a/code/sdk/middleware/chips/brandy/nv/nv_config/include/common.h +++ b/code/sdk/middleware/chips/brandy/nv/nv_config/include/common.h @@ -102,4 +102,10 @@ typedef struct { uint32_t data[NV_AUDIO_VQE_PARAM_SIZE]; } audio_vqe_param_t; +#define CUSTOM_KEY_SERIAL_NUM_SIZE 32 +typedef struct { + uint8_t size; /* 序列号长度 */ + uint8_t sn[CUSTOM_KEY_SERIAL_NUM_SIZE]; /* 序列号数组 */ +} custom_key_sn_t; + #endif /* __COMMON_H__ */ diff --git a/code/sdk/middleware/chips/brandy/nv/nv_config/include/key_id.h b/code/sdk/middleware/chips/brandy/nv/nv_config/include/key_id.h index 295291945..c32e75bde 100755 --- a/code/sdk/middleware/chips/brandy/nv/nv_config/include/key_id.h +++ b/code/sdk/middleware/chips/brandy/nv/nv_config/include/key_id.h @@ -15,7 +15,7 @@ /* user factory key_id [0x1000,0x2000) */ - +#define NV_ID_CUSTOM_KEY_SERIAL_NUM 0x1010 /* 序列号 */ /* system normal key_id [0x2000,0x3000) */ #define NV_ID_SECURE_CONN 0x2001 /* secure connect */ diff --git a/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.c b/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.c index fe3400ab6..7a22bdc8a 100755 --- a/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.c +++ b/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.c @@ -67,6 +67,20 @@ static void pm_sdio_power_off(void) pmu1_dig_pg_sub_power_on(PMU1_DIG_PG_MCU_HS, TURN_OFF); osal_irq_restore(irq); } +static void pm_ppg_power_on(void) +{ + uint32_t irq = osal_irq_lock(); + pmu_sdio_glb_common_reset(TURN_OFF); + hal_pmu_mcpu_perip_config(HAL_PMU_MCPU_PERIP_EMMC, HAL_PMU_PERIP_REQUEST_RESET); + hal_pmu_mcpu_perip_config(HAL_PMU_MCPU_PERIP_SDIO_HOST, HAL_PMU_PERIP_REQUEST_RESET); + + pmu1_dig_pg_sub_power_on(PMU1_DIG_PG_MCU_HS, TURN_ON); + + pmu_sdio_glb_common_reset(TURN_ON); + hal_pmu_mcpu_perip_config(HAL_PMU_MCPU_PERIP_EMMC, HAL_PMU_PERIP_REQUEST_DERESET); + hal_pmu_mcpu_perip_config(HAL_PMU_MCPU_PERIP_SDIO_HOST, HAL_PMU_PERIP_REQUEST_DERESET); + osal_irq_restore(irq); +} static void pm_display_power_on(void) { @@ -215,6 +229,15 @@ static void pm_sdio_power_control(pm_control_t type) } } +static void pm_app_wake_power_control(pm_control_t type) +{ + if (type == PM_APP_WAKE_NEEDED) { + uapi_pm_add_sleep_veto(PM_ID_SCREEN); + } else if (type == PM_APP_WAKE_NONEED) { + uapi_pm_remove_sleep_veto(PM_ID_SCREEN); + } +} + static void pm_display_power_control(pm_control_t type) { if (type == PM_DISPLAY_POWER_UP_AND_RUN) { @@ -258,6 +281,8 @@ void uapi_pm_control(pm_control_t type) pm_display_power_control(type); } else if (type <= PM_SDIO_POWER_OFF) { pm_sdio_power_control(type); + }else if (type <= PM_APP_WAKE_NONEED) { + pm_app_wake_power_control(type); } } diff --git a/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.h b/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.h index aafaed039..3ed1febe8 100755 --- a/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.h +++ b/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_control.h @@ -22,6 +22,8 @@ typedef enum { PM_DISPLAY_POWER_OFF = 5, // !< Power off off. PM_SDIO_POWER_UP_AND_RUN = 6, // !< Power up and run sdio PM_SDIO_POWER_OFF = 7, // !< Power off off. + PM_APP_WAKE_NEEDED = 8, + PM_APP_WAKE_NONEED = 9, PM_CONTROL_MAX, } pm_control_t; diff --git a/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_lp_stub.c.bak b/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_lp_stub.c.bak deleted file mode 100755 index 7c5eacffe..000000000 --- a/code/sdk/middleware/chips/brandy/pm/pm_adapt/pm_lp_stub.c.bak +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved. - * Description: pm lp stub code - */ - -#include "chip_io.h" -#include "platform.h" -#include "flash.h" -#include "hal_xip.h" -#include "touch_screen_def.h" -#include "lcd_bus.h" -#include "pmu_ldo.h" -#include "hal_pmu_ldo.h" -#include "pm_control.h" -#include "i2c_porting.h" -#include "spi_porting.h" -#include "uart_porting.h" -#ifdef CFG_DRIVERS_MMC -#include "soc_mmc.h" -#endif -#include "chip_io.h" - -#define UART_SUSPEND_REGS_NUM 8 -#define QSPI0_FLASH_D0_PIN 0xA3005000 -#define QSPI0_FLASH_D1_PIN 0xA3005004 -#define QSPI0_FLASH_D2_PIN 0xA3005008 -#define QSPI0_FLASH_D3_PIN 0xA300500C -#define QSPI0_FLASH_CLK_PIN 0xA3005010 -#define QSPI0_FLASH_CS0_PIN 0xA3005014 -#define PIN_FUNC_QSPI0 0x1 -#define QSPI0_FLASH_D0_PAD 0x5700CE00 -#define QSPI0_FLASH_D1_PAD 0x5700CE04 -#define QSPI0_FLASH_D2_PAD 0x5700CE08 -#define QSPI0_FLASH_D3_PAD 0x5700CE0C -#define QSPI0_FLASH_CLK_PAD 0x5700CE10 -#define QSPI0_FLASH_CS0_PAD 0x5700CE14 -#define PAD_IE_BIT 0x1 -#define PAD_PE_BIT 0x0 -#define PAD_PS_BIT 0X2 -#define OPI_PSRAM_CE_PAD 0x5700CE5c -#define QSPI1_NANDFLASH_CS0_PAD 0x5700DA2C -#define QSPI1_NANDFLASH_CS1_PAD 0x5700DA30 -#define PM_EMMC_CCLK_DIV_REG 0x52000100 -#define PM_SD_HOST_CCLK_DIV_REG 0x52000110 -#define RC_CLK_VALUE 49152000 -#define XO_CLK_VALUE 32000000 -#define XO_DLL2_CLK_VALUE 64000000 -#define PLL_CLK_VALUE 884736000 -#define PM_SDIOM_CLK_REG 0x55000628 -#define PM_EMMC_DIV_REG 0x52000120 - -static uint32_t g_uart_h0_regs_tmp[UART_SUSPEND_REGS_NUM]; -static uint32_t g_uart_h1_regs_tmp[UART_SUSPEND_REGS_NUM]; -static bool g_display_pwr_on_for_pm = true; -static uint8_t g_resume_touch_flag = 1; - -void set_touch_resume_flag(uint8_t flag) -{ - g_resume_touch_flag = flag; -} - -static void mem_retention_config(switch_type_t on) -{ - if (on != 0) { - // l2m_gmmu - writel(0x57004040, 0); - - // l2m_dsp - writel(0x57004050, 0); - - // com_mem - reg16_clrbit(0x57004074, 0); - // xip mem - reg16_clrbit(0x57004900, 0); - reg16_clrbit(0x57004900, 4); - } else { - // l2m_gmmu - writel(0x57004040, 0xfff); - - // l2m_dsp - writel(0x57004050, 0x3ff); - - // com_mem - reg16_setbit(0x57004074, 0); - // xip mem - reg16_setbit(0x57004900, 0); - reg16_setbit(0x57004900, 4); - } -} - -void pin_of_poweroff_suspend(void) -{ - uint32_t base_addr = 0; - // egpio - for (base_addr = 0x5700ce00; base_addr <= 0x5700ce64; base_addr += 4) { - reg16_clrbit(base_addr, 1); - } - // hgpio - for (base_addr = 0x5700d200; base_addr <= 0x5700d23c; base_addr += 4) { - reg16_clrbit(base_addr, 1); - } - // mgpio - for (base_addr = 0x5700ca00; base_addr <= 0x5700ca98; base_addr += 4) { - if (base_addr == 0x5700ca50 || base_addr == 0x5700ca88) { - continue; - } - reg16_clrbit(base_addr, 1); - } -} - -void pin_of_poweroff_resume(void) -{ - size_t pin_num; - hal_pio_config_t *pio_func = NULL; - get_pio_func_config(&pin_num, &pio_func); - - for (pin_t i = S_EGPIO0; i < S_MGPIO38; i++) { - if (pio_func[i].ie != HAL_PIO_IE_MAX) { - uapi_pin_set_ie(i, (pin_input_enable_t)pio_func[i].ie); - } - } -} - -void pin_of_poweron_suspend(void) -{ - uint32_t base_addr = 0; - // agpio l - for (base_addr = 0x5700c600; base_addr <= 0x5700c680; base_addr += 4) { - if (base_addr == 0x5700c60c || base_addr == 0x5700c610 || base_addr == 0x5700c628) { - continue; - } - reg16_clrbit(base_addr, 1); - } - // agpio r - for (base_addr = 0x5700da00; base_addr <= 0x5700da28; base_addr += 4) { - if (base_addr == 0x5700da14) { // S_AGPIO_R5 touch int - continue; - } - reg16_clrbit(base_addr, 1); - } - - // ulp gpio - for (base_addr = 0x5702c200; base_addr <= 0x5702c210; base_addr += 4) { - reg16_clrbit(base_addr, 1); - } -} - -static void clk_pll_en_tmp(void) -{ - // pll_clk_en - writew(0x57008020, 0x1); - // select fbdiv_man - writew(0x57008620, 0x1); - // set pll fbdiv man - writew(0x57008610, 0x37); - // sel frac man - writew(0x57008624, 0x1); - // set PLL_FRAC_MAN_H - writew(0x57008614, 0x4b); - // set PLL_FRAC_MAN_L - writew(0x57008618, 0xc6ab); - // set POSTDIV - writew(0x570082c4, 0xa); - // pull pd - writew(0x570082C8, 0x0); - // readback lock stat: 0x1 is stable - while (regw_getbits(0x57008000, 0x2d8, 0, 0x1) != 1) { - }; -} - -void clk_switch_to_rc(void) -{ - // disable GLB_CLKEN - writew(0x55000608, 0x0); - - if (reg16_getbit(0x520003e0, 0x6) == 0x0) { - // mcu ch1 to xo - writew(0x55000610, 0x1); - // mcu core switch to ch1 - reg16_setbit(0x520003e0, 0x6); - // mcu ch0 to xo - writew(0x5500060c, 0x1); - } else { - // mcu ch0 to xo - writew(0x5500060c, 0x1); - // mcu core switch to ch0 - reg16_clrbit(0x520003e0, 0x6); - // mcu ch1 to xo - writew(0x55000610, 0x1); - } - - // set mcu_bus_div is no div - writew(0x55000604, 0x0); - writew(0x55000604, 0x3); - - // clk_mcu_perp_ls=clk_rc - writew(0x55000614, 0x3); - // clk_mcu_perp_uart=clk_rc - writew(0x55000618, 0x3); - // clk_mcu_perp_spi=clk_rc - writew(0x5500061c, 0x1); - - if (reg16_getbit(0x55000af0, 0x0) == 0x1) { - // set com bus ch0 to rc - writew(0x55000620, 0x1); - // com bus switch to ch0 - reg16_clrbit(0x55000af0, 0x0); - // set com bus ch1 to rc - writew(0x55000624, 0x1); - } else { - // set com bus ch1 to rc - writew(0x55000624, 0x1); - // com bus switch to ch1 - reg16_setbit(0x55000af0, 0x0); - // set com bus ch0 to rc - writew(0x55000620, 0x1); - } - - // set clk_sdiom=clk_rc - writew(0x55000628, 0x1); - // clk_mem_bus=clk_rc - writew(0x5500062C, 0x1); - // clk_xip_opi=clk_rc - writew(0x55000630, 0x1); - // clk_xip_qspi=clk_rc - writew(0x55000634, 0x1); - // clk_gpu=clk_rc - writew(0x55000638, 0x1); - - if (reg16_getbit(0x55000af0, 0x1) == 0x1) { - // set hifi ch0 to rc - writew(0x5500063c, 0x1); - // hifi switch to ch0 - reg16_clrbit(0x55000af0, 0x1); - // set com bus ch1 to rc - writew(0x55000640, 0x1); - } else { - // set hifi bus ch1 to rc - writew(0x55000640, 0x1); - // hifi switch to ch1 - reg16_setbit(0x55000af0, 0x1); - // set hifi bus ch0 to rc - writew(0x5500063c, 0x1); - } - - if (reg16_getbit(0x55000af0, 0x2) == 0x1) { - // set codec ch0 to rc - writew(0x55000644, 0x1); - // codec switch to ch0 - reg16_clrbit(0x55000af0, 0x2); - // set codec ch1 to rc - writew(0x55000648, 0x1); - } else { - // set codec ch1 to rc - writew(0x55000648, 0x1); - // codec switch to ch1 - reg16_setbit(0x55000af0, 0x2); - // set codec ch0 to rc - writew(0x55000644, 0x1); - } - - // enable GLB_CLKEN - writew(0x55000608, 0x3ffe); -} - -void clocks_switch_case_09v(void) -{ - writew(0x55000608, 0x0); // close C_CRG(except clk_mcu_core) - writew(0x55000604, 0x0); // mcu_bus div en = 0 - writew(0x55000604, 0x5); // mcu bus 2 分频 div_en=1 - if (reg16_getbit(0x520003e0, 0x6) == 0x0) { - // mcu ch1 to xo - writew(0x55000610, 0x97); - // mcu core switch to ch1 - reg16_setbit(0x520003e0, 0x6); - // mcu ch0 to xo - writew(0x5500060c, 0x3); - } else { - // mcu ch0 to xo - writew(0x5500060c, 0x97); - // mcu core switch to ch0 - reg16_clrbit(0x520003e0, 0x6); - // mcu ch1 to xo - writew(0x55000610, 0x3); - } - - writew(0x55000614, 0x3); // clk_mcu_perp_ls = clk_xo - writew(0x5500061C, 0x97); // clk_mcu_perp_spi=clk_pll/11 - if (reg16_getbit(0x55000af0, 0x0) == 0x0) { - // set combus ch1 to xo - writew(0x55000624, 0xf7); - // combus switch to ch1 - reg16_setbit(0x55000af0, 0x0); - // set combus ch0 to xo - writew(0x55000620, 0x3); - } else { - // set combus bus ch0 to xo - writew(0x55000620, 0xf7); - // combus switch to ch0 - reg16_clrbit(0x55000af0, 0x0); - // set combus bus ch0 to xo - writew(0x55000624, 0x3); - } - writew(0x55000628, 0x77); // clk_sdiom=clk_pll/3 - writew(0x5500062C, 0xB7); // clk_mem_bus=clk_pll/5 - writew(0x55000630, 0x77); // clk_xip_opi=clk_pll/3 - writew(0x55000634, 0x97); // clk_xip_qspi=clk_pll/4 - writew(0x55000638, 0xD7); // clk_gpu=clk_pll/6 - if (reg16_getbit(0x55000af0, 0x1) == 0x0) { - // set hifi ch1 to xo - writew(0x55000640, 0x77); - // hifi switch to ch1 - reg16_setbit(0x55000af0, 0x1); - // set hifi ch0 to xo - writew(0x5500063c, 0x3); - } else { - // set hifi bus ch0 to xo - writew(0x5500063c, 0x77); - // hifi switch to ch0 - reg16_clrbit(0x55000af0, 0x1); - // set hifi bus ch0 to xo - writew(0x55000640, 0x3); - } - if (reg16_getbit(0x55000af0, 0x2) == 0x0) { - // set codec ch1 to xo - writew(0x55000648, 0x497); - // codec switch to ch1 - reg16_setbit(0x55000af0, 0x2); - // set codec ch0 to xo - writew(0x55000644, 0x3); - } else { - // set codec bus ch0 to xo - writew(0x55000644, 0x497); - // codec switch to ch0 - reg16_clrbit(0x55000af0, 0x2); - // set codec bus ch0 to xo - writew(0x55000648, 0x3); - } - writew(0x55000608, 0x3FFE); // open C_CRG clock output -} - -static void clock_gpu_hifi_to_xo_dll2(void) -{ - // 动态调频,必须保证两路channel都必须有时钟,要不就出现挂死 - if (reg16_getbit(0x55000af0, 0x1) == 0x1) { - // set hifi ch0 to xo - writew(0x5500063c, 0x5); - // hifi switch to ch0 - reg16_clrbit(0x55000af0, 0x1); - // set hifi ch1 to xo - writew(0x55000640, 0x5); - } else { - // set hifi bus ch1 to xo - writew(0x55000640, 0x5); - // hifi switch to ch1 - reg16_setbit(0x55000af0, 0x1); - // set hifi bus ch0 to xo - writew(0x5500063c, 0x5); - } - - if (reg16_getbit(0x55000af0, 0x2) == 0x1) { - // set codec ch0 to xo - writew(0x55000644, 0x5); - // codec switch to ch0 - reg16_clrbit(0x55000af0, 0x2); - // set codec ch1 to xo - writew(0x55000648, 0x5); - } else { - // set codec ch1 to xo - writew(0x55000648, 0x5); - // codec switch to ch1 - reg16_setbit(0x55000af0, 0x2); - // set codec ch0 to xo - writew(0x55000644, 0x5); - } -} - -void clk_switch_to_xo_dll2(void) -{ - // disable GLB_CLKEN - writew(0x55000608, 0x0); - writew(0x520003f0, 0x1); // config to switch the channel of mcu - if (reg16_getbit(0x520003e0, 0x6) == 0x0) { - // mcu ch1 to xo - writew(0x55000610, 0x5); - // mcu core switch to ch1 - reg16_setbit(0x520003e0, 0x6); - // mcu ch0 to xo - writew(0x5500060c, 0x5); - } else { - // mcu ch0 to xo - writew(0x5500060c, 0x5); - // mcu core switch to ch0 - reg16_clrbit(0x520003e0, 0x6); - // mcu ch1 to xo - writew(0x55000610, 0x5); - } - - // set mcu_bus_div is no div - writew(0x55000604, 0x0); - writew(0x55000604, 0x3); - - // clk_mcu_perp_ls=clk_xo_dll2 - writew(0x55000614, 0x3); - // clk_mcu_perp_uart=clk_xo_dll2 - writew(0x55000618, 0x3); - // clk_mcu_perp_spi=clk_xo_dll2 - writew(0x5500061c, 0x5); - - if (reg16_getbit(0x55000af0, 0x0) == 0x0) { - // set com bus ch1 to xo(32M) - writew(0x55000624, 0x5); - // switch com bus ch1 - reg16_setbit(0x55000af0, 0x0); - // set com bus ch0 to xo - writew(0x55000620, 0x5); - } else { - // set com bus ch0 to xo(32M) - writew(0x55000620, 0x5); - // switch com bus ch1 - reg16_clrbit(0x55000af0, 0x0); - // set com bus ch0 to xo - writew(0x55000624, 0x5); - } - - // set clk_sdiom=clk_xo 默认就是0 - writew(0x55000628, 0x5); - // clk_mem_bus=clk_xo - writew(0x5500062C, 0x5); - // clk_xip_opi=clk_xo - writew(0x55000630, 0x5); - // clk_xip_qspi=clk_xo - writew(0x55000634, 0x5); - clock_gpu_hifi_to_xo_dll2(); - // enable GLB_CLKEN - writew(0x55000608, 0x3ffe); - // tcxo cnt enable, 是否睡眠自己掉电 - reg16_setbit(0x55000580, 2); // enable tcxo -} - -void uart_h0_suspend_tmp(void) -{ - uart_save_reg(UART_BUS_0); -} - -void uart_h0_resume_tmp(void) -{ - uart_recovery_reg(UART_BUS_0); -} - -void uart_h1_suspend_tmp(void) -{ - uart_save_reg(UART_BUS_1); -} - -void uart_h1_resume_tmp(void) -{ - uart_recovery_reg(UART_BUS_1); -} - -void qspi0_suspend_tmp(void) -{ - uapi_flash_exit_from_xip_mode(FLASH_1); - hal_xip_set_cur_mode((xip_id_t)FLASH_1, XIP_MODE_DISABLE); - spi_save_reg(SPI_BUS_3); // QSPI0 for norflash - uapi_flash_switch_to_deeppower(FLASH_1); - reg16_setbit(QSPI0_FLASH_CS0_PAD, PAD_PE_BIT); - reg16_setbit(QSPI0_FLASH_CS0_PAD, PAD_PS_BIT); // make CS to high in deepsleep. -} - -void qspi0_resume_tmp(void) -{ - // qspi0 pinmux restore - writew(QSPI0_FLASH_D0_PIN, PIN_FUNC_QSPI0); - writew(QSPI0_FLASH_D1_PIN, PIN_FUNC_QSPI0); - writew(QSPI0_FLASH_D2_PIN, PIN_FUNC_QSPI0); - writew(QSPI0_FLASH_D3_PIN, PIN_FUNC_QSPI0); - writew(QSPI0_FLASH_CLK_PIN, PIN_FUNC_QSPI0); - writew(QSPI0_FLASH_CS0_PIN, PIN_FUNC_QSPI0); - reg16_setbit(QSPI0_FLASH_D0_PAD, PAD_IE_BIT); - reg16_setbit(QSPI0_FLASH_D1_PAD, PAD_IE_BIT); - reg16_setbit(QSPI0_FLASH_D2_PAD, PAD_IE_BIT); - reg16_setbit(QSPI0_FLASH_D3_PAD, PAD_IE_BIT); - reg16_setbit(QSPI0_FLASH_CLK_PAD, PAD_IE_BIT); - reg16_setbit(QSPI0_FLASH_CS0_PAD, PAD_IE_BIT); - reg16_clrbit(QSPI0_FLASH_CS0_PAD, PAD_PS_BIT); - reg16_clrbit(QSPI0_FLASH_CS0_PAD, PAD_PE_BIT); // make CS to pull none in normal. - - spi_recovery_reg(SPI_BUS_3); // QSPI0 for norflash - uapi_flash_resume_from_deeppower(FLASH_1); - uapi_flash_switch_to_cache_mode(0); - if (readb(FLASH_START) != 0x6f) { - PRINT("Enter XIP with value: 0x%x failed\r\n", readw(FLASH_START) == 0x6f); - } -} - -void storage_device_suspend(void) -{ -#ifdef CFG_DRIVERS_NANDFLASH - reg16_setbit(QSPI1_NANDFLASH_CS0_PAD, PAD_PS_BIT); - reg16_setbit(QSPI1_NANDFLASH_CS0_PAD, PAD_PE_BIT); // make CS1 to high in deepsleep. -#elif defined (CFG_DRIVERS_MMC) - emmc_save_info(); -#endif -} - -void storage_device_resume(void) -{ -#ifdef CFG_DRIVERS_NANDFLASH - nandflash_qspi_resume(); - reg16_clrbit(QSPI1_NANDFLASH_CS0_PAD, PAD_PS_BIT); - reg16_clrbit(QSPI1_NANDFLASH_CS0_PAD, PAD_PE_BIT); // make CS1 to pull none in normal. -#endif -} - -void opi_psram_suspend_tmp(void) -{ -#ifdef CONFIG_PSRAM_SUPPORT - uapi_psram_exit_xip(); - uapi_psram_enter_sleep(); - spi_save_reg(SPI_BUS_6); // QSPI0 for norflash - reg16_setbit(OPI_PSRAM_CE_PAD, PAD_PE_BIT); - reg16_setbit(OPI_PSRAM_CE_PAD, PAD_PS_BIT); // make CS to high in deepsleep. -#endif -} - -void opi_psram_resume_tmp(void) -{ -#ifdef CONFIG_PSRAM_SUPPORT - spi_recovery_reg(SPI_BUS_6); // QSPI0 for norflash - uapi_psram_exit_sleep(); - uapi_psram_enter_xip(); - reg16_clrbit(OPI_PSRAM_CE_PAD, PAD_PS_BIT); - reg16_clrbit(OPI_PSRAM_CE_PAD, PAD_PE_BIT); // make CS to pull none in normal. -#endif -} - -void touch_suspend_tmp(void) -{ - touch_peripheral_api *touch_ptr = touch_screen_get_api(); - ext_errno ret = touch_ptr->touch_sleep(); - if (ret != EXT_ERR_SUCCESS) { PRINT("touch sleep ret=0x%x", ret); } - i2c_save_reg(I2C_BUS_1); - uapi_gpio_disable_interrupt(S_AGPIO_R5); // close tp_int gpio interrupt -} - -void touch_resume_tmp(void) -{ - uapi_gpio_disable_interrupt(S_AGPIO_R5); // close tp_int gpio interrupt - i2c_recovery_reg(I2C_BUS_1); - writew(0x5700da14, 0x2); // open touch int ie(s_agpio_r5) -#if defined(TPTYPE_TMA525B) - tma525b_init(); - touch_peripheral_api *touch_ptr = (touch_peripheral_api*)touch_screen_get_api(); - ext_errno ret = touch_ptr->touch_resume(); - if (ret != EXT_ERR_SUCCESS) { PRINT("touch resume ret=0x%x", ret); } -#elif defined(TPTYPE_ZTW523) - ztw523_resume(); -#elif defined(TPTYPE_FT6X46) - ztw523_init(); -#else - ztw523_resume(); -#endif - uapi_gpio_enable_interrupt(S_AGPIO_R5); // open tp_int gpio interrupt -} - -void touch_suspend_for_i2c(void) -{ - i2c_save_reg(I2C_BUS_1); -} - -static void touch_resume_for_i2c(void) -{ - i2c_recovery_reg(I2C_BUS_1); - writew(0x5700da14, 0x2); // open touch int ie(s_agpio_r5) -} - -void touch_restart(void) -{ - uapi_i2c_deinit(I2C_BUS_1); - uapi_i2c_master_init(I2C_BUS_1, 400000, 0); /* 400000: 400KHz */ - writew(0x5700da14, 0x2); // open touch int ie(s_agpio_r5) -#if defined(TPTYPE_TMA525B) - tma525b_resume(); -#elif defined(TPTYPE_ZTW523) - ztw523_resume(); -#else - ztw523_resume(); -#endif - uapi_gpio_enable_interrupt(S_AGPIO_R5); // open tp_int gpio interrupt -} - -void dsp_resume_tmp(void) -{ - reg16_setbit(0x5700c634, 0x1); - reg16_setbit(0x5700c638, 0x1); - reg16_setbit(0x5700c63c, 0x1); - reg16_setbit(0x5700c640, 0x1); - reg16_setbit(0x5700c604, 0x1); // pdm amic ie enable - reg16_setbit(0x5700c608, 0x1); // pdm dmic ie enable -#if (defined BRANDY_PRODUCT_EVB4) // i2c pinmux config - reg16_setbit(0x5700ca44, 0x1); - reg16_setbit(0x5700ca48, 0x1); -#else - reg16_setbit(0x5700ca2c, 0x1); - reg16_setbit(0x5700ca30, 0x1); -#endif - pmu1_dsp_l2ram_config(DSP_L2RAM_AREA_SIZE); // set l2ram for dsp - reg16_setbit(0x52000020, 0x3); // enable dsp to mcu ipc int0&int1 -} - -void display_resume_power_on(void) -{ - if (g_display_pwr_on_for_pm == false) { - uapi_pm_control(PM_DISPLAY_POWER_UP_AND_RUN); - g_display_pwr_on_for_pm = true; - } -} - -void display_suspend_power_off(void) -{ - g_display_pwr_on_for_pm = false; -} - -void display_suspend_tmp(void) -{ - if (g_resume_touch_flag != 0) { touch_suspend_for_i2c(); } - int ret = drv_vau_suspend(NULL); - if (ret != 0) { PRINT("drv vau suspend ret =%d\n", ret); } -#ifndef QSPI_DISPLAY - ret = drv_dpu_suspend(NULL); - if (ret != 0) { PRINT("drv dpu suspend ret =%d\n", ret); } -#endif -#ifdef SUPPORT_GPU_GMMU - ret = drv_gmmu_suspend(NULL); - if (ret != 0) { PRINT("drv_gmmu_suspend ret =%d\n", ret); } -#endif - lcd_bus_api *bus_api = lcd_get_bus_api(); - ret = bus_api->bus_suspend(); - if (ret != 0) { PRINT("bus suspend ret =%d\n", ret); } -#ifndef QSPI_DISPLAY - pmu_ldo_power_on(PMU_LDO_AUXLDO3, TURN_OFF); - hal_pmu_auxldo_enable_high_resistance(HAL_PMU_AUXLDO3, TURN_ON); -#endif - writew(0x570000c0, 0); // display logic crg reset - writew(0x57004034, 0x100); // display close power -} - -void display_resume_tmp(void) -{ -#ifndef QSPI_DISPLAY - pmu_ldo_power_on(PMU_LDO_AUXLDO3, TURN_ON); -#endif - display_resume_power_on(); - writew(0x5700c658, 0x2); // sagpio_l22 open ie - lcd_bus_api *bus_api = lcd_get_bus_api(); - int ret = bus_api->bus_resume(); - if (ret != 0) { PRINT("bus resume ret =%d\n", ret); } -#ifndef QSPI_DISPLAY - ret = drv_dpu_resume(NULL); - if (ret != 0) { PRINT("drv dpu resume ret =%d\n", ret); } -#endif - ret = drv_vau_resume(NULL); - if (ret != 0) { PRINT("drv vau resume ret =%d\n", ret); } -#ifdef SUPPORT_GPU_GMMU - ret = drv_gmmu_resume(NULL); - if (ret != 0) { PRINT("drv_gmmu_resume ret =%d\n", ret); } -#endif - if (g_resume_touch_flag != 0) { touch_resume_for_i2c(); } -} - -void pm_misc_regs_resume(void) -{ -#ifdef CFG_DRIVERS_NANDFLASH - reg16_clrbit(PM_SD_HOST_CCLK_DIV_REG, 0); // close sd host clock enable. - reg16_clrbit(PM_EMMC_CCLK_DIV_REG, 0); // close sd mmc clock enable. -#endif -#ifdef CFG_DRIVERS_MMC - reg16_clrbit(PM_SD_HOST_CCLK_DIV_REG, 0); // close sd host clock enable. -#endif -} \ No newline at end of file diff --git a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp index 51b065c94..af81334a2 100755 --- a/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp +++ b/code/sdk/middleware/services/media/foundation/sample/wrapper/voice_call_volte_sample_wrapper.cpp @@ -160,9 +160,9 @@ static int32_t RunVoiceCallVolte(VoiceCallVolteContext *context) // create downlink AudioStreamIn CapturerInputConfig captureConfig = {}; captureConfig.audioFormat = PCM; - captureConfig.channelCount = 2; + captureConfig.channelCount = 1; captureConfig.linkDir = AUDIO_DOWN_LINK; - captureConfig.sampleRate = 16000; + captureConfig.sampleRate = 8000; captureConfig.sessionID = context->sessionId; captureConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; @@ -176,7 +176,7 @@ static int32_t RunVoiceCallVolte(VoiceCallVolteContext *context) renderConfig.audioFormat = PCM; renderConfig.channelCount = 1; renderConfig.linkDir = AUDIO_UP_LINK; - renderConfig.sampleRate = 16000; + renderConfig.sampleRate = 8000; renderConfig.sessionID = context->sessionId; renderConfig.streamType = AUDIO_STREAM_VOICE_CALL_VOLTE; diff --git a/code/sdk/middleware/utils/at/wstp_at/src/at_cmd_task.c b/code/sdk/middleware/utils/at/wstp_at/src/at_cmd_task.c index 64fa60855..a2504fb4f 100755 --- a/code/sdk/middleware/utils/at/wstp_at/src/at_cmd_task.c +++ b/code/sdk/middleware/utils/at/wstp_at/src/at_cmd_task.c @@ -20,7 +20,7 @@ #define AT_CMD_BUFSIZE 256 #define AT_CMD_NAME_MAX_LEN 32 #define AT_CMD_END_MARK_LEN 2 -#define AT_CMD_MODULE_MAX_NUM 5 +#define AT_CMD_MODULE_MAX_NUM 50 #define AT_CMD_MSG_COUNT 16 #define OFF_TWO 2 @@ -277,6 +277,7 @@ void at_cmd_msg_receive_handler(uint8_t *data, uint32_t data_len) errcode_t at_cmd_add_moudle(at_cmd_table_t *module_cmd_list, uint32_t cmd_count) { if (g_at_cmd_module_index >= AT_CMD_MODULE_MAX_NUM) { + PRINT("[at cmd]at_cmd_add_moudle failed, cmd module number %d is larger than %d !\r\n",g_at_cmd_module_index,AT_CMD_MODULE_MAX_NUM); return ERRCODE_FAIL; } g_at_cmd_module_list[g_at_cmd_module_index].cmd_set = module_cmd_list;