#include "hx3918_prox.h"
#include "hx3918.h"
-
+#include "helios_securedata.h"
#ifdef TYHX_DEMO
#include "nordic_common.h"
#include "nrf.h"
#include "app_timer.h"
#endif
-/* ²úÆ·ÐèÒª¸Ä¶¯µÄµØ·½
-#define HX3918_IR_AIR 7000 //HX3918 ¶Ô¿Õ²âÊÔÅå´÷IRµÄÖµ·¶Î§,СÓÚÕâ¸öÖµ´ú±í¶Ô¿Õ
-#define NORMALWEARDIFF 6000 //HX3918 ¿¿½ü¸ÐÓ¦Åå´÷ʱ¸ÐÓ¦µÄ½á¹û, Ò»°ãÊÇ¿íËÉÅå´÷½á¹û
-hx_set_wear_detect_mode(NORMAL_WEAR_MODE) // ÔÚÊÖ±íÆ½³£²âÊÔÅå´÷ÓÃ
-hx_set_wear_detect_mode(SLEEP_WEAR_MODE) //ÔÚÊÖ±í¼ì²âµ½½øÈë˯ÃߺóÐèÒªµ÷ÓÃ
+/* 产品需要改动的地方
+#define HX3918_IR_AIR 7000 //HX3918 对空测试佩戴IR的值范围,小于这个值代表对空
+#define NORMALWEARDIFF 6000 //HX3918 靠近感应佩戴时感应的结果, 一般是宽松佩戴结果
+hx_set_wear_detect_mode(NORMAL_WEAR_MODE) // 在手表平常测试佩戴用
+hx_set_wear_detect_mode(SLEEP_WEAR_MODE) //在手表检测到进入睡眠后需要调用
*/
-/* --------------------------------³ÌÐò˵Ã÷------------------------------------------------------------
-1. ±¾³ÌÐòHX3918×÷ΪÅå´÷¸ÐÓ¦²¿·ÖµÄ¿ØÖƳÌÐò
-2. HX3918 ÄÚÖÃ3ͨµÀCAP´«¸ÐÆ÷;
-3. ¶ÁÈ¡µÄRAW DATAÊÇ×îÔʼµÄÄ£ÄâÁ¿×ª»»¹ýÀ´µÄÊý×ÖÁ¿,
- LPÊǾ¹ýÒ»´ÎÂ˲¨À´µÄ(Â˳ý¸ßƵ»·¾³ÔëÉù),
- BLÊÇRAW¾¹ýÁ½´ÎÂ˲¨À´µÄ£¨Â˳ýµÍƵÔëÉù°üº¬Î¶ȡ¢Êª¶È¡¢Ñ¹Á¦´øÀ´µÄÆ¯ÒÆ£©£¬
-4. ÓÐÁ½ÖÖ¹¤×÷ģʽ¹©Êµ¼ÊʹÓÃÑ¡Ôñ,
- Ïà¶Ôֵģʽ, ¿ª»úºó,оƬ×ÔУ׼¸ÐÓ¦Öµµ½0¸½½ü, ¿¿½üºÍÔ¶Àë,LP-BL»á²úÉúÒ»¸ö´óµÄ²îÖµ, Ïà¶Ôֵģʽ;
- ¾ø¶Ôֵģʽ,ÐèÒªÓû§ÔÚ¹¤³§µÄʱºò, ²ú²â³ÌÐòÒª¼Ç¼ÊÖ±í¶Ô¿ÕµÄÒ»¸öBASEÖµ(LPÖµ), ºóÃæÓÃLP-BASEÖµÀ´×öÅжÏ;
- Ïà¶ÔֵģʽÁ÷³ÌÉÔ΢¼òµ¥, µ«ÊÇÒòΪÉϵç»á×ÔÎÒУ׼, ËùÒÔÅå´÷×Å¿ª»úÎÞ·¨¼ì²âÅå´÷Çé¿ö. ¾ø¶ÔֵģʽÎÞ´ËÎÊÌâ.
-5. hx3918_chip_id ÊÇоƬIDµÄ±äÁ¿, ÕýÈ·µÄIDÖµÊÇ0x27, ÒòΪHX3918 ÊÇPPGºÍCAP, ÓÃÕâ¸ö±äÁ¿ÅжÏÊDz»ÊÇоƬÒѾÉϵç,
- ÇÒPPG²¿·ÖÒѾ³õʼ»¯, Èç¹ûµÈÓÚ0X27, Õâ±ß¿ØÖƲ»ÐèÒªÉϵçϵç, Èç¹ûÅöµ½²ú²âģʽ,CAP´«¸ÐÆ÷ÐèÒªµ¥¶À¹¤×÷,
- PPG²¿·ÖûÓÐͬʱ±»³õʼ»¯, ËùÒÔ¶Áµ½µÄhx3918_chip_id = 0, ÄÇÕâÀï¾ÍÊÇ»á¼ÓÉÏоƬµÄÉÏÏÂµç¿ØÖÆ
-6. ×¢ÒâCSxºÍCHx, CSxÊÇÖ¸ÍⲿPAD½Óµ½Ð¾Æ¬µÄ¶ÔÓ¦CS¹Ü½Å. CHÊÇÖ¸ÄÚ²¿²É¼¯Êý¾ÝµÄ3¸öͨµÀ, CSx¿ÉÅäÖÃÔÚ²»Í¬µÄCHÉÏ;
+/* --------------------------------程序说明------------------------------------------------------------
+1. 本程序HX3918作为佩戴感应部分的控制程序
+2. HX3918 内置3通道CAP传感器;
+3. 读取的RAW DATA是最原始的模拟量转换过来的数字量,
+ LP是经过一次滤波来的(滤除高频环境噪声),
+ BL是RAW经过两次滤波来的(滤除低频噪声包含温度、湿度、压力带来的漂移),
+4. 有两种工作模式供实际使用选择,
+ 相对值模式, 开机后,芯片自校准感应值到0附近, 靠近和远离,LP-BL会产生一个大的差值, 相对值模式;
+ 绝对值模式,需要用户在工厂的时候, 产测程序要记录手表对空的一个BASE值(LP值), 后面用LP-BASE值来做判断;
+ 相对值模式流程稍微简单, 但是因为上电会自我校准, 所以佩戴着开机无法检测佩戴情况. 绝对值模式无此问题.
+5. hx3918_chip_id 是芯片ID的变量, 正确的ID值是0x27, 因为HX3918 是PPG和CAP, 用这个变量判断是不是芯片已经上电,
+ 且PPG部分已经初始化, 如果等于0X27, 这边控制不需要上电下电, 如果碰到产测模式,CAP传感器需要单独工作,
+ PPG部分没有同时被初始化, 所以读到的hx3918_chip_id = 0, 那这里就是会加上芯片的上下电控制
+6. 注意CSx和CHx, CSx是指外部PAD接到芯片的对应CS管脚. CH是指内部采集数据的3个通道, CSx可配置在不同的CH上;
-------------------------------- -------------------------------- -----------------------------------*/
-#define ANALOG_DIFF //Ä£Äâ²î·Ö, Ò»°ãÓÃÕâÖÖģʽ
-//#define DIGITAL_DIFF //Êý×Ö²î·Ö
+#define ANALOG_DIFF //模拟差分, 一般用这种模式
+//#define DIGITAL_DIFF //数字差分
#ifdef ANALOG_DIFF
-#define INDEPENDDENT_CH // ¶ÀÁ¢Í¨µÀºê¶¨Òå, ¾ÍÊÇÒ»¸öPAD¶ÔÓ¦Ò»¸öCH
-//#define DIFFERENCE_CH //²î·ÖͨµÀ¶¨Òå, Á½¸öPAD×÷Ϊһ¸öCHµÄ²î·ÖÕý¶ËºÍ¸º¶Ë, °¤×Ÿ첲µÄÅå´÷ΪÕý¶Ë
+//#define INDEPENDDENT_CH // 独立通道宏定义, 就是一个PAD对应一个CH
+#define DIFFERENCE_CH //差分通道定义, 两个PAD作为一个CH的差分正端和负端, 挨着胳膊的佩戴为正端
#endif
-//#define HRS_VDD_ALWAYS_ON //HRS Ä£¿é³¤¹©µç
+//#define HRS_VDD_ALWAYS_ON //HRS 模块长供电
-extern uint8_t hx3918_chip_id; // оƬID, Ó¦¸ÃµÈÓÚ0x27
-int16_t nv_wear_offset[2] = {0}; // оƬ²ú²âУ׼µÄÁ½¸öͨµÀµÄOFFSETÖµ, Öµ¼Ç¼ÔÚfashÀïÃæ
-int16_t nv_base_data[2] = {0}; // оƬ²ú²âУ׼µÄÁ½¸öͨµÀµÄ¶Ô¿ÕLPÖµ, Öµ¼Ç¼ÔÚflashÀïÃæ
-//extern uint16_t sendcnt; // À¶ÑÀÊý¾Ý²É¼¯¼ÆÊý, Õâ¸öÊDzÉÊýÓõÄ, ¿ÉÒÔ²»ÓÃ
-int16_t gdiff[2] = {0}; // gdiff[0], gdiff[1] ·Ö±ð±£´æCH0, CH1µÄ½á¹û
+extern uint8_t hx3918_chip_id; // 芯片ID, 应该等于0x27
+int16_t nv_wear_offset[2] = {0}; // 芯片产测校准的两个通道的OFFSET值, 值记录在fash里面
+int16_t nv_base_data[2] = {0}; // 芯片产测校准的两个通道的对空LP值, 值记录在flash里面
+//extern uint16_t sendcnt; // 蓝牙数据采集计数, 这个是采数用的, 可以不用
+int16_t gdiff[2] = {0}; // gdiff[0], gdiff[1] 分别保存CH0, CH1的结果
int16_t lp[2] = {0};
int16_t bl[2] = {0};
-//flash ¶Áд±äÁ¿, ÒÀ´Î¼Ç¼nv_wear_offset[0],nv_wear_offset[1],nv_base_data[0],nv_base_data[1]
-uint32_t fds_read[4] = {0}; //¶Á³öflash ´æ´¢Êý¾ÝµÄ±äÁ¿;
-uint32_t fds_write[4] = {0}; //дflashµÄ±äÁ¿, flashÀïÃæ·Ö±ð¼Ç¼
+//flash 读写变量, 依次记录nv_wear_offset[0],nv_wear_offset[1],nv_base_data[0],nv_base_data[1]
+int16_t fds_read[4] = {0}; //读出flash 存储数据的变量;
+int16_t fds_write[4] = {0}; //写flash的变量, flash里面分别记录
-uint8_t is_factory_mode = 0; // ²ú²âģʽ, ÓÃÀ´¶ÁÈ¡Õû»ú¶Ô¿ÕʱOFFSETºÍ¶Ô¿ÕµÄnv_baseÖµ;
+uint8_t is_factory_mode = 0; // 产测模式, 用来读取整机对空时OFFSET和对空的nv_base值;
uint8_t wear_detect_mode = NORMAL_WEAR_MODE;
/**
* set touch detect mode
- * @param current_mode ÉèÖõŤ×÷ģʽ
+ * @param current_mode 设置的工作模式
*/
void hx_set_wear_detect_mode(uint8_t current_mode)
{
/**
- * ¶ÁÒ»×é16bit Êý¾ÝÖµ
- * @param addh ¼Ä´æÆ÷µØÖ·
- * @param addl ¼Ä´æÆ÷µØÖ·
+ * 读一组16bit 数据值
+ * @param addh 寄存器地址
+ * @param addl 寄存器地址
*/
int16_t hx3918_read_two_reg_low_triple(uint8_t addh, uint8_t addl)
{
}
/**
- * оƬÉϵç, ¶ÔÓ¦µÄµçÔ´¿ØÖƹܽŸúʵ¼Êµç·Ïà¹Ø,¸ù¾Ýʵ¼Êµç·×öºÃ¿ØÖÆ
+ * 芯片上电, 对应的电源控制管脚跟实际电路相关,根据实际电路做好控制
* @param NULL
*/
void hx3918_power_up(void)
}
/**
- * оƬϵç, ¶ÔÓ¦µÄµçÔ´¿ØÖƹܽŸúʵ¼Êµç·Ïà¹Ø,¸ù¾Ýʵ¼Êµç·×öºÃ¿ØÖÆ
+ * 芯片下电, 对应的电源控制管脚跟实际电路相关,根据实际电路做好控制
* @param NULL
*/
void hx3918_power_down(void)
nrf_delay_ms(100);
#endif
}
-
+extern void HX3918_restart(void);
/**
- * Ð¾Æ¬ÖØÐÂÉϵç
+ * 芯片重新上电
* @param NULL
*/
void hx3918_power_restart(void)
{
- hx3918_power_down();
- hx3918_power_up();
+ HX3918_restart();
}
/**
- * HX3918 ¶ÁоƬID
+ * HX3918 读芯片ID
* @param NULL
*/
uint8_t hx3918_check_device_id(void)
/**
- * HX3918 дOFFSETµÄÖµ
-* @param offset_value дOFFSETµÄÖµ
-* @param chx_offset ͨµÀ0/1/2 Ñ¡Ôñ
+ * HX3918 写OFFSET的值
+* @param offset_value 写OFFSET的值
+* @param chx_offset 通道0/1/2 选择
*/
void hx3918_write_offset(uint16_t offset_value, uint8_t chx_offset)
{
}
/**
- * HX3918дOFFSETµÄÖµ, ÓÃÔÚ²ú²â³ÌÐòÀïÃæµÄOFFSET¶ÁÈ¡
-* @param offset_value дOFFSETµÄÖµ
-* @param chx_offset ͨµÀ0/1/2 Ñ¡Ôñ
+ * HX3918写OFFSET的值, 用在产测程序里面的OFFSET读取
+* @param offset_value 写OFFSET的值
+* @param chx_offset 通道0/1/2 选择
*/
static int16_t readlp_after_writeoffset(int16_t offset,uint8_t chx_offset)
{
}
/**
- * HX3918 ¶ÁOFFSETµÄÖµ
-* @param chx_offset ͨµÀ0/1/2 Ñ¡Ôñ
+ * HX3918 读OFFSET的值
+* @param chx_offset 通道0/1/2 选择
*/
uint16_t hx3918_read_offset(uint8_t chx_offset)
{
/**
- * HX3918¶ÁÈ¡raw data »òÕßbaseline data //¶ÁÈ¡µÄÊÇraw»¹ÊÇbl ͨ¹ý0x38 ¼Ä´æÆ÷ÉèÖÃ
-* @param chx_raw ͨµÀ0/1/2 Ñ¡Ôñ
+ * HX3918读取raw data 或者baseline data //读取的是raw还是bl 通过0x38 寄存器设置
+* @param chx_raw 通道0/1/2 选择
*/
int16_t hx3918_read_raw_bl(uint8_t chx_raw)
{
/**
- * HX3918 ¶ÁÈ¡LP data »òÕßdiff data //¶ÁÈ¡µÄÊÇlp»¹ÊÇdiffͨ¹ý0x38 ¼Ä´æÆ÷ÉèÖÃ
-* @param chx_raw ͨµÀ0/1/2 Ñ¡Ôñ
+ * HX3918 读取LP data 或者diff data //读取的是lp还是diff通过0x38 寄存器设置
+* @param chx_raw 通道0/1/2 选择
*/
int16_t hx3918_read_diff_lp(uint8_t chx_diff)
{
}
/**
- * HX3918 ÉèÖýӽüãÐÖµºÍÔ¶ÀëãÐÖµ
-* @param chx ͨµÀ0/1/2 Ñ¡Ôñ
-* @param high_thres ½Ó½üãÐÖµ
-* @param low_thres Ô¶ÀëãÐÖµ
+ * HX3918 设置接近阈值和远离阈值
+* @param chx 通道0/1/2 选择
+* @param high_thres 接近阈值
+* @param low_thres 远离阈值
* @param base_data
*/
void hx3918_config_thres(uint8_t chx,int16_t high_thres, int16_t low_thres, int16_t base_data)
// write_ok &= hx3918_write_reg(0x57,0x03); //CS0->CH1
write_ok &= hx3918_write_reg(0x57,0x0c); //CS1->CH1
-#elif defined(DIFFERENCE_CH) //?????????????¡§, ???????¡¤??
+#elif defined(DIFFERENCE_CH) //?????????????¨, ???????·??
// write_ok &= hx3918_write_reg(0x55,0x2c); //CS1->CH0[P],CS2->CH0[N]
// write_ok &= hx3918_write_reg(0x55,0x0e); //CS1->CH0[P],CS0->CH0[N]
write_ok &= hx3918_write_reg(0x55,0x0B); //CS0->CH0[P],CS1->CH0[N]
write_ok &= hx3918_write_reg(0x5E,0x11); //OSR AVG
write_ok &= hx3918_write_reg(0x5F,0x01); //OSR AVG
- write_ok &= hx3918_write_reg(0x66,0x08); //²ÉÑùʱ¼ä
+ write_ok &= hx3918_write_reg(0x66,0x08); //采样时间
write_ok &= hx3918_write_reg(0x67,0x00); //
- write_ok &= hx3918_write_reg(0x68,0x08); //»ý·Öʱ¼ä
+ write_ok &= hx3918_write_reg(0x68,0x08); //积分时间
write_ok &= hx3918_write_reg(0x69,0x00); //
write_ok &= hx3918_write_reg(0x6E,0x11); //LP alpha
- write_ok &= hx3918_write_reg(0x77,0x70); //output Ñ¡ÔñLPºÍBL
+ write_ok &= hx3918_write_reg(0x77,0x70); //output 选择LP和BL
- write_ok &= hx3918_write_reg(0x7A,0x07); //²¹³¥µçÈÝУ׼´¥·¢ÉèÖÃ=16384
+ write_ok &= hx3918_write_reg(0x7A,0x07); //补偿电容校准触发设置=16384
if(is_factory_mode)
hx3918_config_thres(CH0,CH0_HIGH_DIFF, CH0_LOW_DIFF,nv_base_data[0]); // wear0
hx3918_config_thres(CH1,CH1_HIGH_DIFF, CH1_LOW_DIFF,nv_base_data[1]); // wear0
hx3918_write_reg(0x7A,0x17);
+ HX3918_LOG("hx3918_prox_reg_init:nv_base_data:%d %d!!!!!!!!!!!!!!!!!!!!!!!!\n",nv_base_data[0],nv_base_data[1]);
}
write_ok &= hx3918_write_reg(0x6a,0x03); //CH0, CH1 enable
}
-//À¶ÑÀ·¢ËÍÊý¾Ý¸øAPP
+//蓝牙发送数据给APP
//extern uint32_t sendDataToClient(int16_t sendnum1,int16_t sendnum2,int16_t sendnum3,int16_t sendnum4);
/**
- * hx3918 »ñÈ¡¿¿½ü¸ÐÓ¦µÄ½á¹û,½á¹û=0, prox¸ÐÓ¦µÄ½á¹ûΪ·ÇÅå´÷, =1 Åå´÷
+ * hx3918 获取靠近感应的结果,结果=0, prox感应的结果为非佩戴, =1 佩戴
* @param NULL
*/
uint8_t hx3918_report_prox_status(void)
HX3918_LOG("result = %d %d %d %d %d %d\r\n",lp[0],bl[0],lp[1],bl[1],gdiff[0],gdiff[1]);
- if(gdiff[0]>100)
- ret = 1;
- else
- {
- if((lp_old[0] - lp[0]) > 40)
- ret = 0;
- else
- {
- if(lp[0]>3300)
- ret = 1;
- else
- ret = 0;
- }
-
- }
- lp_old[0] = lp[0];
- lp_old[1] = lp[1];
- bl_old[0] = bl[0];
- bl_old[1] = bl[1];
- return ret;
-// #ifdef TEMP_COMPENSATION //ζȲ¹³¥
-// //Õâ¸öÊÇÓ¦¶Ô¸ßλ·¾³ÒªÇó, ²»Óôò¿ª, Òª¿´¿´¾ßÌåÇé¿ö,
-// if(gdiff[1]>20000)
-// {
-// gdiff[0] = gdiff[0]*0.9; // Èç¹ûËæ×ŸßÎÂ,¸ÐÓ¦ÖµÉÏÉý,Ϊ0.9, ¸ÐӦֵϽµ¸ÄΪ1.1
-// }
-// #endif
- // if(gdiff[0]<WEARTHRES)// WEARTHRES=9000/2
+ // if(gdiff[0]>100)
+ // ret = 1;
+ // else
// {
- // if((gdiff[0]>=SLEEPWEARTHRES)&&(wear_detect_mode == SLEEP_WEAR_MODE ))//SLEEPWEARTHRES=9000*0.3
+ // if((lp_old[0] - lp[0]) > 40)
+ // ret = 0;
+ // else
// {
- // return prox_detect;
+ // if(lp[0]>3300)
+ // ret = 1;
+ // else
+ // ret = 0;
// }
- // return prox_no_detect;
- // }
- // else
- // {
- // return prox_detect;
+
// }
+ // lp_old[0] = lp[0];
+ // lp_old[1] = lp[1];
+ // bl_old[0] = bl[0];
+ // bl_old[1] = bl[1];
+ // return ret;
+#ifdef TEMP_COMPENSATION //温度补偿
+ //这个是应对高温环境要求, 不用打开, 要看看具体情况,
+ if(gdiff[1]>20000)
+ {
+ gdiff[0] = gdiff[0]*0.9; // 如果随着高温,感应值上升,为0.9, 感应值下降改为1.1
+ }
+#endif
+ if(gdiff[0]<WEARTHRES)// WEARTHRES=3500/2
+ {
+ if((gdiff[0]>=SLEEPWEARTHRES)&&(wear_detect_mode == SLEEP_WEAR_MODE ))//SLEEPWEARTHRES=9000*0.3
+ {
+ return prox_detect;
+ }
+ return prox_no_detect;
+ }
+ else
+ {
+ return prox_detect;
+ }
}
/**
- * hx3918 ´Óflash¶ÁÈ¡¶Ô¿ÕУ׼ºóµÄOFFSETºÍNV_BASE
+ * hx3918 从flash读取对空校准后的OFFSET和NV_BASE
* @param NULL
*/
void hx3918_read_nv(void)
{
- //´Óflash¶ÁÈ¡4¸öÖµ, ·Ö±ðÊÇÒÔǰ±£´æµÄÖµ; Õâ¸öº¯ÊýÓû§ÐèÒª×Ô¼ºÍê³É, flash´æ´¢µÄλÖò»Äܱ»Óû§²Ù×÷ɾµô
+ //从flash读取4个值, 分别是以前保存的值; 这个函数用户需要自己完成, flash存储的位置不能被用户操作删掉
//flash_fds_data_get(4);
- nv_wear_offset[0] = 468;
- nv_wear_offset[1] = 82;
- nv_base_data[0] = -382;
- nv_base_data[1] = -389;
-
- //Èç¹ûflash¼Ç¼µÄÖµ´óÓÚÉÏÏÞ, ÔòÈÿ¿½ü¸ÐÓ¦½øÈëÏà¶Ôֵģʽ
+ Helios_SecureData_t r_data={0};
+ r_data.index = 1;
+ r_data.pBuffer = (uint8_t *)fds_read;
+ r_data.len = sizeof(fds_read);
+ Helios_Securedata_Read(&r_data);
+ nv_wear_offset[0] = fds_read[0];
+ nv_wear_offset[1] = fds_read[1];
+ nv_base_data[0] = fds_read[2];
+ nv_base_data[1] = fds_read[3];
+
+ //如果flash记录的值大于上限, 则让靠近感应进入相对值模式
if(nv_wear_offset[0] > 1020)
{
nv_wear_offset[0] = 0;
}
/**
- * hx3918 ¿¿½ü¸ÐÓ¦³õʼ»¯, ͨ¹ý¶Ôhx3918_chip_id ÅжÏ,À´ÅжϿ¿½ü¸ÐÓ¦ÊǶÀÁ¢¹¤×÷»¹ÊǸúPPGÒ»Æð¹¤×÷
+ * hx3918 靠近感应初始化, 通过对hx3918_chip_id 判断,来判断靠近感应是独立工作还是跟PPG一起工作
* @param NULL
*/
bool hx3918_prox_init(void)
/**
- * hx3918 ¿¿½ü¸ÐÓ¦³õʼ»¯, ͨ¹ý¶Ôhx3918_chip_id ÅжÏ,À´ÅжϿ¿½ü¸ÐÓ¦ÊǶÀÁ¢¹¤×÷»¹ÊǸúPPGÒ»Æð¹¤×÷
+ * hx3918 靠近感应初始化, 通过对hx3918_chip_id 判断,来判断靠近感应是独立工作还是跟PPG一起工作
* @param NULL
*/
bool hx3918_prox_factory_init(void)
/**
- * hx3918 ¿¿½ü¸ÐÓ¦²¿·Ö ¹¤³§²ú²â³ÌÐò, Ð轫ÊÖ±íÐü¿Õ»òÕßÔ¶ÀëÆäËû¿ÉÄÜÓ°ÏìµçÈÝÖµµÄÎïÌå.
+ * hx3918 靠近感应部分 工厂产测程序, 需将手表悬空或者远离其他可能影响电容值的物体.
* @param NULL
*/
+uint16_t prox_factory_offset0 = 0;
+uint16_t prox_factory_offset1 = 0;
+int16_t prox_factory_lp[2] = {0};
void hx3918_prox_factory_hanging_cali(void)
{
- uint16_t offset0 = 0;
- uint16_t offset1 = 0;
- int16_t lp[2] = {0};
+ // uint16_t offset0 = 0;
+ // uint16_t offset1 = 0;
+ // int16_t lp[2] = {0};
//uint8_t device_id = 0x00;
is_factory_mode = 1;
hx3918_prox_factory_init();
hx3918_delay(50);//delay 100ms
- offset0 = hx3918_read_offset(CH0_OFFSET);
- offset1 = hx3918_read_offset(CH1_OFFSET);
+ prox_factory_offset0 = hx3918_read_offset(CH0_OFFSET);
+ prox_factory_offset1 = hx3918_read_offset(CH1_OFFSET);
- lp[0] = hx3918_read_diff_lp(LP0);
- lp[1] = hx3918_read_diff_lp(LP1);
+ prox_factory_lp[0] = hx3918_read_diff_lp(LP0);
+ prox_factory_lp[1] = hx3918_read_diff_lp(LP1);
- HX3918_LOG("offset0,offset1= %d %d\r\n", offset0,offset1);
+ HX3918_LOG("offset0,offset1= %d %d\r\n", prox_factory_offset0,prox_factory_offset1);
#ifdef INDEPENDDENT_CH
- if((offset0-offset1)<100)
+ if((prox_factory_offset0-prox_factory_offset1)<100)
{
HX3918_LOG("ERR, resize cap of ch0\r\n");
}
#endif
- nv_wear_offset[0] = offset0;
- nv_wear_offset[1] = offset1;
+ nv_wear_offset[0] = prox_factory_offset0;
+ nv_wear_offset[1] = prox_factory_offset1;
nv_base_data[0] = lp[0];
nv_base_data[1] = lp[1];
HX3918_LOG("base0,base1= %d %d\r\n", lp[0],lp[1]);
#ifdef DIFFERENCE_CH
- //½«²î·ÖÊý¾Ý¶Áµ½µÄOFFSET, NV_BASE¼Ç¼µ½FLASHÀïÃæ, У׼´æ´¢°Ñ×ÔѧϰµÄ¼Ç¼ҲÐèÒªÇåµôÖØÐ¼ÆËã
+ //将差分数据读到的OFFSET, NV_BASE记录到FLASH里面, 校准存储把自学习的记录也需要清掉重新计算
- if((offset0 == 510) &&(offset1 == 510))
+ if((prox_factory_offset0 == 510) &&(prox_factory_offset1 == 510))
{
TYHX_LOG("ERR, read offset err, please redo it !!!\r\n");
}
}
/**
- * hx3918 ¿¿½ü¸ÐÓ¦²¿·Ö ¹¤³§²ú²â³ÌÐò, Ð轫ÊÖ±íÐü¿Õ»òÕßÔ¶ÀëÆäËû¿ÉÄÜÓ°ÏìµçÈÝÖµµÄÎïÌå.
+ * hx3918 靠近感应部分 工厂产测程序, 需将手表悬空或者远离其他可能影响电容值的物体.
* @param NULL
*/
void hx3918_factory_cali_save_nv(void)
fds_write[2] = nv_base_data[0];
fds_write[3] = nv_base_data[1];
-
+ Helios_SecureData_t w_data={0};
+ w_data.index = 1;
+ w_data.pBuffer = (uint8_t *)fds_write;
+ w_data.len = sizeof(fds_write);
+ Helios_Securedata_Store(&w_data);
TYHX_LOG("[hx3918_factory_cali_save_nv]");
for(int i=0; i<4; i++)
{
TYHX_LOG("%d ",fds_write[i]);
}
- //Óû§ÐèÒªflash±£´æ
+ //用户需要flash保存
//flash_fds_data_write(4);
}
/**
- * ×îÖÕÓÃIRºÍPROX×ÛºÏÀ´ÅжÏÅå´÷½á¹û
-* @param ppg_wear, PPG²¿·ÖÓÃIR¼ì²âµÄ½á¹û
+ * 最终用IR和PROX综合来判断佩戴结果
+* @param ppg_wear, PPG部分用IR检测的结果
*/
bool hx3918_get_wear_result(uint8_t ppg_wear)
{
// hx3918_ppg_timerout_flag = 0;
// }
wear_time++;
- if(wear_time > 1)
+ if(wear_time > 3)
{
wear_time = 0;
//hx3918_prox_factory_hanging_cali();
s_HX3918_HRV = 0;
//s_HX3918_wear_status = 0;
s_HX3918_blood_oxygen = 0x0;
-
- if(hx3918_init(mode) == true)
+ if(mode <= close_MODE)
{
- is_open_HX3918 = 1;
- if(sensor_timer== 0)
+ if(hx3918_init(mode) == true)
{
- sensor_timer = Helios_Timer_init( (void* )sensor_timerout_cb, NULL);
+ is_open_HX3918 = 1;
+ if(sensor_timer== 0)
+ {
+ sensor_timer = Helios_Timer_init( (void* )sensor_timerout_cb, NULL);
+ }
+
+ Helios_Timer_Start(sensor_timer, TIMER_TIME_MS, IS_CYCLICAL);
}
-
- Helios_Timer_Start(sensor_timer, TIMER_TIME_MS, IS_CYCLICAL);
+ }else if(mode == 255)//活体校准功能
+ {
+ // Helios_GPIO_SetLevel(g_HX3918->power, HELIOS_LVL_LOW);
+ // Helios_msleep(150);
+ // Helios_GPIO_SetLevel(g_HX3918->power, HELIOS_LVL_HIGH);
+ // Helios_msleep(20);
+ // hx3918_init(WEAR_MODE);//打开佩戴检测
+ hx3918_prox_factory_hanging_cali();
}
+
+
}
}
is_open_HX3918 = 0;
Helios_GPIO_SetLevel(g_HX3918->power, HELIOS_LVL_LOW);
- Helios_msleep(5);
+ Helios_msleep(15);
Helios_GPIO_SetLevel(g_HX3918->power, HELIOS_LVL_HIGH);
Helios_msleep(20);
hx3918_init(WEAR_MODE);//打开佩戴检测
}
-
+void HX3918_restart(void)
+{
+ Helios_GPIO_SetLevel(g_HX3918->power, HELIOS_LVL_LOW);
+ Helios_msleep(150);
+ Helios_GPIO_SetLevel(g_HX3918->power, HELIOS_LVL_HIGH);
+ Helios_msleep(50);
+}
//关闭hsensor
STATIC mp_obj_t mp_HX3918_close(mp_obj_t self_in)
{
}
// ir_wear = hx3918_get_wear_ppg_Int_handle();
// cap_wear = hx3918_report_prox_status();
+//lp[0],bl[0],lp[1],bl[1],gdiff[0]
+extern int16_t lp[2] ;
+extern int16_t bl[2];
+extern int16_t gdiff[2];
//获取佩戴状态
STATIC mp_obj_t mp_HX3918_get_wear(mp_obj_t self_in)
{
- mp_obj_t coordinate_list[3] = {mp_obj_new_int((int)ir_wear), mp_obj_new_int((int)cap_wear),mp_obj_new_int((int)s_HX3918_wear_status),};
- return mp_obj_new_list(3, coordinate_list);
+ mp_obj_t coordinate_list[1] = {mp_obj_new_int((int)s_HX3918_wear_status)};
+ return mp_obj_new_list(1, coordinate_list);
//return mp_obj_new_int(s_HX3918_wear_status);
}
//获取所有数据 心律、血氧、高压、低压、HRV、佩戴状态
//FT_LEAK_LIGHT_MODE 产测漏光测试模式;
//FT_GRAY_CARD_MODE 产测灰卡测试模式;
//LAB_TEST_MODE 实验室模式。
+// extern uint16_t prox_factory_offset0 ;
+// extern uint16_t prox_factory_offset1 ;
+// extern int16_t prox_factory_lp[2] ;
+extern int16_t nv_wear_offset[2] ; // 芯片产测校准的两个通道的OFFSET值, 值记录在fash里面
+extern int16_t nv_base_data[2]; // 芯片产测校准的两个通道的对空LP值, 值记录在flash里面
STATIC mp_obj_t mp_HX3918_get_test_data(mp_obj_t self_in)
{
- mp_obj_t coordinate_list[3] = {mp_obj_new_int((int)factory_reslts.green_data_final),mp_obj_new_int((int)factory_reslts.red_data_final),\
- mp_obj_new_int((int)factory_reslts.ir_data_final)};
- return mp_obj_new_list(3, coordinate_list);
+ mp_obj_t coordinate_list[15] = {mp_obj_new_int((int)factory_reslts.green_data_final),mp_obj_new_int((int)factory_reslts.red_data_final),mp_obj_new_int((int)factory_reslts.ir_data_final),
+ mp_obj_new_int((int)ir_wear),mp_obj_new_int((int)cap_wear),mp_obj_new_int((int)lp[0]),mp_obj_new_int((int)bl[0]),mp_obj_new_int((int)lp[1]),mp_obj_new_int((int)bl[1]),
+ mp_obj_new_int((int)(gdiff[0])),mp_obj_new_int((int)(gdiff[1])),mp_obj_new_int((int)nv_wear_offset[0]),mp_obj_new_int((int)nv_wear_offset[1]),mp_obj_new_int((int)nv_base_data[0]),
+ mp_obj_new_int((int)nv_base_data[1]),
+ };
+ return mp_obj_new_list(15, coordinate_list);
}
//设置sleep
STATIC mp_obj_t mp_HX3918_set_sleep(mp_obj_t self_in)
factorymode_screen.set_size(240, 320)
factorymode_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
+style_btn_1 = lv.style_t()
+style_btn_1.init()
+style_btn_1.set_bg_opa(0)
+style_btn_1.set_shadow_opa(0)
+style_btn_1.set_border_width(0)
+style_btn_1.set_bg_color(lv.color_make(0x00, 0xff, 0x2a))
+
factorymode_title = lv.label(factorymode_screen)
factorymode_title.set_pos(0, 10)
factorymode_title.set_size(240, 40)
factorymode_bat_test_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
factorymode_bat_test.add_style(style_btn, lv.PART.MAIN | lv.STATE.DEFAULT)
+factorymode_cont_y+=60
+factorymode_hsensor_test = lv.btn(factorymode_cont)
+factorymode_hsensor_test.set_pos(0, factorymode_cont_y)
+factorymode_hsensor_test.set_size(240, 60)
+factorymode_hsensor_test_label = lv.label(factorymode_hsensor_test)
+factorymode_hsensor_test_label.set_text("心率血氧测试")
+factorymode_hsensor_test.set_style_pad_all(0, lv.STATE.DEFAULT)
+factorymode_hsensor_test_label.align(lv.ALIGN.LEFT_MID, 70, 0)
+factorymode_hsensor_test_label.set_style_text_color(lv.color_make(0xff, 0xff, 0xff), lv.STATE.DEFAULT)
+factorymode_hsensor_test_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+factorymode_hsensor_test.add_style(style_btn, lv.PART.MAIN | lv.STATE.DEFAULT)
+
factorymode_cont_y+=200
factorymode_alipay_init = lv.btn(factorymode_cont)
factorymode_alipay_init.set_pos(0, factorymode_cont_y)
factorymode_location.add_event_cb(lambda e: EventMesh.callback_wrapper(self.load_screen(e, {"screen": "FactoryModeLocation"})), lv.EVENT.CLICKED, None)
factorymode_alipay_init.add_event_cb(lambda e: EventMesh.callback_wrapper(self.load_screen(e, {"screen": "FactoryModeAlipayInit"})), lv.EVENT.CLICKED, None)
factorymode_bat_test.add_event_cb(lambda e: EventMesh.callback_wrapper(self.load_screen(e, {"screen": "FactoryModeBatTest"})), lv.EVENT.CLICKED, None)
+ factorymode_hsensor_test.add_event_cb(lambda e: EventMesh.callback_wrapper(self.load_screen(e, {"screen": "FactoryModeHsensorTest"})), lv.EVENT.CLICKED, None)
def done_return(self):
EventMesh.publish("load_screen", {"screen": "main_menu"})
def btn8_press(self):
EventMesh.publish("load_screen", {"screen": "main_menu"})
+#hsensor测试
+FactoryModeHsensorTest_screen = lv.obj()
+FactoryModeHsensorTest_screen.center()
+FactoryModeHsensorTest_screen.set_size(240, 320)
+FactoryModeHsensorTest_screen.add_style(style_screen, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+FactoryModeHsensorTest_label = lv.label(FactoryModeHsensorTest_screen)
+FactoryModeHsensorTest_label.set_text(" 佩戴状态")
+FactoryModeHsensorTest_label.set_size(240, 260)
+FactoryModeHsensorTest_label.set_pos(0, 0)
+FactoryModeHsensorTest_label.set_style_text_color(lv.color_make(0xff, 0xff, 0xff), lv.STATE.DEFAULT)
+FactoryModeHsensorTest_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+
+FactoryModeHsensorCali_btn = lv.btn(FactoryModeHsensorTest_screen)
+FactoryModeHsensorCali_btn.set_pos(5, 260)
+FactoryModeHsensorCali_btn.set_size(110, 35)
+FactoryModeHsensorCali_btn.add_style(style_btn_1, lv.PART.MAIN | lv.STATE.DEFAULT)
+FactoryModeHsensorCali_btn.set_style_pad_all(0, lv.STATE.DEFAULT)
+FactoryModeHsensorCali_label = lv.label(FactoryModeHsensorCali_btn)
+FactoryModeHsensorCali_label.set_text("活体校准")
+FactoryModeHsensorCali_label.align(lv.ALIGN.CENTER, 0, 0)
+FactoryModeHsensorCali_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+FactoryModeHsensorCali_label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
+FactoryModeHsensorCali_label.set_style_text_color(lv.color_make(0x16, 0x2c, 0xd4), lv.STATE.DEFAULT)
+#FactoryModeHsensorCali_label.set_style_bg_color(lv.color_make(0x00, 0xff, 0x2a), lv.PART.MAIN | lv.STATE.DEFAULT)
+
+FactoryModeHsensorLeakLight_btn = lv.btn(FactoryModeHsensorTest_screen)
+FactoryModeHsensorLeakLight_btn.set_pos(120, 260)
+FactoryModeHsensorLeakLight_btn.set_size(110, 35)
+FactoryModeHsensorLeakLight_btn.add_style(style_btn_1, lv.PART.MAIN | lv.STATE.DEFAULT)
+FactoryModeHsensorLeakLight_btn.set_style_pad_all(0, lv.STATE.DEFAULT)
+FactoryModeHsensorLeakLight_label = lv.label(FactoryModeHsensorLeakLight_btn)
+FactoryModeHsensorLeakLight_label.set_text("漏光检测")
+FactoryModeHsensorLeakLight_label.align(lv.ALIGN.CENTER, 0, 0)
+FactoryModeHsensorLeakLight_label.add_style(style_font_youyuan_20, lv.PART.MAIN | lv.STATE.DEFAULT)
+FactoryModeHsensorLeakLight_label.set_style_text_align(lv.TEXT_ALIGN.CENTER, 0)
+FactoryModeHsensorLeakLight_label.set_style_text_color(lv.color_make(0x16, 0x2c, 0xd4), lv.STATE.DEFAULT)
+#FactoryModeHsensorLeakLight_label.set_style_bg_color(lv.color_make(0x00, 0xff, 0x2a), lv.PART.MAIN | lv.STATE.DEFAULT)
+
+
+
+class FactoryModeHsensorTestScreen(Screen):
+ NAME = "FactoryModeHsensorTest"
+ def __init__(self):
+ super().__init__()
+ self.meta = FactoryModeHsensorTest_screen
+ self.hsensorTest_timer_count = 0
+ self.hsensorTest_timer = osTimer()
+ self.Hsensor = None
+ FactoryModeHsensorCali_btn.add_event_cb(lambda e: EventMesh.callback_wrapper(self.HsensorCali_cb(e)), lv.EVENT.CLICKED, None)
+ FactoryModeHsensorLeakLight_btn.add_event_cb(lambda e: EventMesh.callback_wrapper(self.HsensorLeakLight_cb(e)), lv.EVENT.CLICKED, None)
+ def initialization(self):
+ print("FactoryModeHsensorTestScreen")
+ self.hsensorTest_timer.start(1000,1,self.hsensorTest_timer_cb)
+ if self.Hsensor == None:
+ self.Hsensor = EventMesh.publish("get_Hsensor")
+ def post_processor_after_initialization(self):
+ pass
+
+ def HsensorCali_cb(self,e):
+ self.Hsensor.open_test(255) #打开校准模式
+ utime.sleep_ms(500)
+ self.Hsensor.open_heart()
+ self.hsensorTest_timer_count = 5
+
+ def HsensorLeakLight_cb(self,e):
+ self.Hsensor.open_test(6) #打开漏光检测
+ # utime.sleep_ms(500)
+ # self.Hsensor.open_heart()
+ self.hsensorTest_timer_count = 5
+
+ def hsensorTest_timer_cb(self,e):
+ EventMesh.publish("system_sleep_rest")#防止黑屏
+ w_data = EventMesh.publish(constants.EVENT.GET_WEAR)#佩戴数据
+
+ #print("FactoryModeHsensorTest{}".format(data))
+ try:
+ c_data = self.Hsensor.get_test_data()#校准数据和工厂数据
+ FactoryModeHsensorTest_label.set_text(" 佩戴状态\n红外:{}活体:{}佩戴:{}\n{},{} \n{},{} \n{},{}\n校准数据:{},{},{},{}\n漏光数据:{},{},{}"
+ .format(c_data[3],c_data[4],w_data[0],c_data[5],c_data[6],c_data[7],c_data[8],c_data[9],c_data[10],
+ c_data[11],c_data[12],c_data[13],c_data[14],c_data[0],c_data[1],c_data[2],))
+ except Exception as e:
+ FactoryModeHsensorTest_label.set_text("佩戴状态:\n{}".format(w_data))
+ if(self.hsensorTest_timer_count != 0):
+ self.hsensorTest_timer_count -= 1
+ if self.hsensorTest_timer_count == 0:
+ self.Hsensor.close()
+
+ def Close(self):
+ self.hsensorTest_timer.stop()
+ pass
+
+ def done_return(self):
+ EventMesh.publish("load_screen", {"screen": "factorymode"})
+
+ def btn1_release(self):
+ EventMesh.publish("load_screen", {"screen": "factorymode"})
+
+ def btn8_press(self):
+ EventMesh.publish("load_screen", {"screen": "main_menu"})
+
+
+#电池测试
FactoryModeBatTest_screen = lv.obj()
FactoryModeBatTest_screen.center()
FactoryModeBatTest_screen.set_size(240, 320)