BUILD_NAME=_FD230
fi
+if [ "$1" == "n9" ]
+then
+TARGET_PACK_NAME=pack_brandy_native_js_n9
+APPLICATION_NAME=brandy-native-js-n9
+RECOVERY_NAME=brandy-native-js-n9-r
+DEFAULT_SSB_NAME=brandy-native-js-n9-ssb
+BUILD_NAME=_N9
+fi
+
if [ "$1" == "leakcheck" ]
then
TARGET_PACK_NAME=pack_brandy_native_js_leakcheck
button_map_t g_brandy_button_pin_map[BUTTON_PIN_MAP_MAX] = {
{ PIN_NONE, BUTTON_PWR },
+#ifdef BOARD_N9
+ { S_AGPIO_R3, BUTTON_1 },
+#else
{ S_AGPIO_R10, BUTTON_1 },
+#endif
{ PIN_NONE, BUTTON_2 },
{ PIN_NONE, BUTTON_3 },
{ PIN_NONE, BUTTON_4 },
#include "mixo_service.h"\r
#endif\r
\r
+#ifdef ENABLE_BN02\r
+#include "bp_service.h"\r
+#include "bp_tcp_server.h"\r
+#endif\r
+\r
+#ifdef ENABLE_GYRO\r
+#include "gyro_service.h"\r
+#endif\r
+\r
#define EMMC_BASE_ADDR 0x52062000\r
#define TASK_PRIORITY_APP (osPriority_t)(17)\r
#define TICK_TEN_MS (10U)\r
\r
#ifdef ENABLE_CUSTOM_I2C\r
\r
- custom_iic_init();\r
+ custom_i2c_init(I2C_BUS_2);\r
+\r
+#ifdef ENABLE_BN02\r
+ // custom_i2c_init(I2C_BUS_0);\r
+ // uapi_bp_service_init();\r
+ // uapi_bp_tcp_server_init();\r
+#endif\r
+\r
+ #ifdef ROTARYENCODER_MIXO\r
+ uapi_mixo_service_init();\r
+ #endif\r
\r
#ifdef MAG_MMC5603\r
uapi_mag_service_init();\r
uapi_cywee_service_init();\r
#endif \r
\r
- #ifdef ROTARYENCODER_MIXO\r
- uapi_mixo_service_init();\r
- #endif\r
+#endif\r
+\r
+#ifdef ENABLE_GYRO\r
+ uapi_gyro_service_init();\r
#endif\r
\r
/*启动蓝牙ble服务,cywee有重置 mac地址的操作,会需要把 蓝牙服务开启放在cywee服务之后*/\r
uapi_pin_set_ie(S_MGPIO34, HAL_PIO_IE_ENBALE);\r
#endif\r
\r
-#ifdef SUPPORT_GNSS_SERVICE\r
+#ifdef SUPPORT_GNSS_SERVER\r
gnss_uart_init();\r
#endif\r
\r
#ifdef CUSTOM_Z1
static constexpr const char *DEFAULT_DIALBACK_PATH = APP_RES_PATH "/dial_soures/z1background.bin";
static constexpr const char *DEFAULT_DIALPER_PATH = APP_RES_PATH "/dial_soures/Z1VIEW.bin";
-#elif BOARD_W9
+#elif defined(BOARD_W9) || defined(BOARD_N9)
static constexpr const char *DEFAULT_DIALBACK_PATH = APP_RES_PATH "/dial_soures/main_bg.bin";
static constexpr const char *DEFAULT_DIALPER_PATH = APP_RES_PATH "/dial_soures/thumbnail.bin";
#else
}\r
\r
HandleDrinkReminder(&curTime); \r
+#ifdef BOARD_FD230\r
HandleHeartRateDetection(&curTime); \r
+#endif\r
}\r
\r
//判断是否绑定\r
*/
bool MainClockView::InitBatteryView(BatteryDisplayType type)
{
- #if !defined(BOARD_W9) // N9需要显示电池
+ #if !(defined(BOARD_W9) || defined(BOARD_N9))// N9和W9需要显示电池
// 不显示电池 icon
if (type == BATTERY_DISPLAY_NONE)
{
datelabel->SetText(dateStr.c_str());
// Update battery status
- #if !defined(BOARD_W9) // N9需要显示电池
+ #if !(defined(BOARD_W9) || defined(BOARD_N9))// N9和W9需要显示电池
if (batterySetting == BATTERY_DISPLAY_NONE)
return;
#endif
const DialInfo dialInfoMap[] = {\r
#ifdef CUSTOM_Z1\r
{DIAL_CLOCK, "Z1", DEFAULT_DIALPER_PATH, DEFAULT_TASK_PERIOD},\r
-#elif BOARD_W9\r
+#elif defined(BOARD_W9) || defined(BOARD_N9)\r
{DIAL_CLOCK, "N9", DEFAULT_DIALPER_PATH, DEFAULT_TASK_PERIOD}, \r
#else\r
{DIAL_CLOCK, "KUMI", DEFAULT_DIALPER_PATH, DEFAULT_TASK_PERIOD},\r
if (len < 0)\r
{\r
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Failed to retrieve dial settings. Initializing to default settings.\r\n");\r
- #ifdef BOARD_W9\r
+ #if defined(BOARD_W9) || defined(BOARD_N9)\r
InitDialSettingDefault(DIAL_CLOCK);//N9使用默认静态表盘\r
#else\r
//判断黑耀表盘是否存在\r
else\r
{\r
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: First value is empty. Initializing to default settings.\r\n");\r
- #ifdef BOARD_W9\r
+ #if defined(BOARD_W9) || defined(BOARD_N9)\r
InitDialSettingDefault(DIAL_CLOCK);//N9使用默认静态表盘\r
#else\r
//判断黑耀表盘是否存在\r
else\r
{\r
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Second value is empty. Initializing to default settings.\r\n");\r
- #ifdef BOARD_W9\r
+ #if defined(BOARD_W9) || defined(BOARD_N9)\r
InitDialSettingDefault(DIAL_CLOCK);//N9使用默认静态表盘\r
#else\r
//判断黑耀表盘是否存在\r
* @Author: penglei 1624952103@qq.com\r
* @Date: 2024-08-23 10:50:37\r
* @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-06-06 15:56:14\r
+ * @LastEditTime: 2025-06-11 17:46:10\r
* @FilePath: /FD230/code/sdk/application/wearable/fd230/nativeapp/nativeui/producttest/include/testPresenter.h\r
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
*/\r
MICROPHONE,\r
HRSENSON,\r
GSENSON,\r
- BTTEST,\r
- SEChipTest,\r
- PingTest,\r
#ifdef SUPPORT_GNSS\r
GPSTEST,\r
#endif\r
+ BTTEST,\r
+ SEChipTest,\r
+ PingTest,\r
+\r
#ifdef ENABLE_LQBP002TA\r
PRESSURETEST,\r
#endif\r
-#ifdef ENABLE_GYRO\r
- GYROTEST,\r
-#endif\r
+// #ifdef ENABLE_GYRO\r
+// GYROTEST,\r
+// #endif\r
OLDTEST,\r
DEEPSLEEP,\r
\r
#include "producttest/include/testbt.h"\r
#include "producttest/include/testSEChipTest.h"\r
#include "producttest/include/testPing.h"\r
+#ifdef SUPPORT_GNSS\r
#include "producttest/include/testGPS.h"\r
+#endif\r
+#ifdef ENABLE_GYRO\r
+#include "producttest/include/testgyro.h"\r
+#endif\r
#ifdef SUPPORT_A5133_SERVICE\r
#include "producttest/include/testA5133.h"\r
#endif\r
bool ChangeBTTESTView(int16_t thisView);\r
bool ChangeSEChipTESTView(int16_t thisView);\r
bool ChangePingTESTView(int16_t thisView);\r
+#ifdef SUPPORT_GNSS\r
bool ChangeGPSTESTView(int16_t thisView);\r
+#endif\r
+#ifdef ENABLE_GYRO\r
+ bool ChangegyroTestTESTView(int16_t thisView);\r
+#endif\r
#ifdef SUPPORT_A5133_SERVICE\r
bool ChangeA5133TESTView(int16_t thisView);\r
#endif\r
\r
testSEChipView *test_SEChip_view{nullptr};\r
testPingView *test_Ping_view{nullptr};\r
+#ifdef SUPPORT_GNSS\r
testGPSView *test_GPS_view{nullptr};\r
- \r
+#endif\r
+#ifdef ENABLE_GYRO\r
+ testgyroView *test_gyro_view{nullptr};\r
+#endif\r
#ifdef SUPPORT_A5133_SERVICE\r
testA5133View *test_A5133_view{nullptr};\r
#endif\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-05-12 15:44:33
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-06-09 15:04:11
+ * @FilePath: /sdk615/code/sdk/zhihui/UI/producttest/include/testgyro.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#ifndef TEST_GYRO_VIEW_H
+#define TEST_GYRO_VIEW_H
+
+#include "BaseView.h"
+#include "View.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_label.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_button.h"
+#include "components/ui_image_view.h"
+#include "components/ui_label_button_ext.h"
+
+//#include "cmsis_os.h"
+#include <iostream>
+namespace OHOS
+{
+
+ class testgyroView
+ {
+
+ public:
+ struct ButtonConfig_ext_t
+ {
+ int x;
+ int y;
+ int w;
+ int h;
+ const char *str;
+ const char *ViewId;
+ const char *ImageSrc;
+
+ //label
+ int label_x;
+ int label_y;
+ uint8_t ALIGN;
+ int Fontsize;
+
+ };
+
+
+
+ struct LabelConfig
+ {
+ int16_t left;
+ int16_t top;
+ int16_t width;
+ int16_t height;
+ int16_t fontSize; // 字体大小
+ int16_t lineHeigh; // 行高
+ char *text; // 文本
+ uint8_t lineBreakMode; // 断行模式。
+ };
+
+
+
+
+ testgyroView();
+ virtual ~testgyroView();
+ static testgyroView *GetInstance(void);
+
+ UIScrollView *testgyroInitIView(uint8_t);
+ void gyrodataTimerCallBack(void);
+
+ void ClearAll(void);
+ private:
+ UILabelButtonExt *SetTheButton_ext(ButtonConfig_ext_t &buttonconfig);//, UIView::OnTouchListener *clickListener);
+ UILabel *InitLabel(LabelConfig &labelConfig);
+ bool testgyroScrollViewcrollViewinit(uint8_t);
+ UIScrollView *testgyroScrollView{nullptr};
+ UILabel *label_1_MSG=NULL;
+ UILabel *label_2_MSG{nullptr};
+ UILabel *label_3_MSG{nullptr};
+
+ UILabelButtonExt* labelButton_next = nullptr;
+ bool initViewStatus{false};
+ UILabel *Title{nullptr}; // 标题
+
+ };
+}
+#endif
\ No newline at end of file
{MICROPHONE,"microphonebutton","microphone", "microphonebutton_next",&testView::ChangeMPTESTView,true},\r
{HRSENSON,"hrsensonbutton","hrsensor", "hrsensonbutton_next",&testView::ChangeHRTESTView,true},\r
{GSENSON,"gsensonbutton","gsensor","gsensonbutton_next" ,&testView::ChangeGTESTView,true},\r
- {BTTEST,"BTbutton","BT" ,"BTbutton_next",&testView::ChangeBTTESTView,true},\r
- {SEChipTest,"SEChipTestbutton","SEChipTest","SEChipTestbutton_next" ,&testView::ChangeSEChipTESTView,true},\r
- {PingTest,"PingTestbutton","PingTest","PingTestbutton_next" ,&testView::ChangePingTESTView,true},\r
-\r
#if defined(SUPPORT_GNSS)\r
{GPSTEST,"GPSTestbutton","GPSTest","GPSTestbutton_next" ,&testView::ChangeGPSTESTView,true},\r
#endif\r
+ {BTTEST,"BTbutton","BT" ,"BTbutton_next",&testView::ChangeBTTESTView,true},\r
+ {SEChipTest,"SEChipTestbutton","SEChipTest","SEChipTestbutton_next" ,&testView::ChangeSEChipTESTView,true},\r
+ {PingTest,"PingTestbutton","PingTest","PingTestbutton_next" ,&testView::ChangePingTESTView,true},\r
#if defined(ENABLE_LQBP002TA)\r
{PRESSURETEST,"pressureTestbutton","pressureTest","pressureTestbutton_next" ,&testView::ChangepressureTestTESTView,true},\r
#endif\r
-#if defined(ENABLE_GYRO)\r
- {GYROTEST,"gyroTestbutton","gyroTest","gyroTestbutton_next" ,&testView::ChangegyroTestTESTView,true},\r
-#endif\r
-#ifdef AGINGTEST\r
+// #if defined(ENABLE_GYRO)\r
+// {GYROTEST,"gyroTestbutton","gyroTest","gyroTestbutton_next" ,&testView::ChangegyroTestTESTView,true},\r
+// #endif\r
{OLDTEST,"oldtestbutton","aging" ,"oldtestexit",&testView::ChangeoldTESTView,true},\r
-#endif\r
{DEEPSLEEP,"deepsleep","DeepSleepCurrent","xxxxxxxxx" ,&testView::ChangeoldTESTView,true},\r
{shutdown,"shutdown","shutdown", "xxxxxxxxx",&testView::ChangeoldTESTView,true},\r
{RESET,"reset","reset", "xxxxxxxxx",&testView::ChangeoldTESTView,true},\r
\r
bool testView::ChangeoldTESTView(int16_t thisView)\r
{\r
- #ifdef AGINGTEST\r
if (SystemScrollView[thisView] == nullptr)\r
{\r
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemView::ChangeoldTESTView");\r
SystemScrollView[thisView] = test_old_view->testoldInitIView(thisView);\r
RootView::GetInstance()->Add(SystemScrollView[thisView]);\r
}\r
- #endif\r
return true;\r
\r
}\r
SystemScrollView[hideView]=nullptr;\r
break;\r
#endif\r
-#if defined(ENABLE_GYRO)\r
- case GYROTEST:\r
- RootView::GetInstance()->Remove(SystemScrollView[hideView]);\r
- delete test_gyro_view; \r
- test_gyro_view = nullptr;\r
- SystemScrollView[hideView]=nullptr;\r
- break;\r
-#endif\r
+// #if defined(ENABLE_GYRO)\r
+// case GYROTEST:\r
+// RootView::GetInstance()->Remove(SystemScrollView[hideView]);\r
+// delete test_gyro_view; \r
+// test_gyro_view = nullptr;\r
+// SystemScrollView[hideView]=nullptr;\r
+// break;\r
+// #endif\r
\r
default:\r
break;\r
--- /dev/null
+#include "wearable_log.h"
+#include "custom_utils.h"
+#include "producttest/include/testPresenter.h"
+
+#include "cmsis_os2.h"
+#include "producttest/include/testView.h"
+#include "producttest/include/testgyro.h"
+// #include "gnss_sample.h"
+#include "graphic_service.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C"
+{
+#endif
+#endif
+#ifdef ENABLE_GYRO
+#include "gyro_service.h"
+#include "gyro_hal.h"
+#endif
+
+#ifdef ROTARYENCODER_MIXO
+#include "mixo_service.h"
+#endif
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif
+
+
+
+namespace OHOS
+{
+
+ static testgyroView *g_pSystemAboutTheWatchView{nullptr};
+
+ testgyroView::testgyroView()
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemAboutTheWatchView::SystemAboutTheWatchView");
+ g_pSystemAboutTheWatchView = this;
+ }
+
+ testgyroView::~testgyroView()
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "testgyroView::~testgyroView");
+ ClearAll();
+ //g_pSystemAboutTheWatchView = nullptr;
+ }
+
+ testgyroView *testgyroView::GetInstance()
+ {
+
+ return g_pSystemAboutTheWatchView;
+ }
+ static osTimerId_t P_TEST_timer=NULL;
+
+ void testgyroView::ClearAll()
+ {
+#ifdef ENABLE_GYRO
+ gyro_stop();
+#ifdef ROTARYENCODER_MIXO
+ do_mixo_service_check_msg(MIXO_SERVICE_CMD_START_CHECK);
+#endif
+#endif
+ if(testgyroScrollView)
+ {
+ testgyroScrollView->RemoveAll();
+
+ if (P_TEST_timer != NULL) {
+ osTimerStop(P_TEST_timer);
+ osTimerDelete(P_TEST_timer);
+ P_TEST_timer = NULL;
+ }
+ if(labelButton_next)
+ {
+ delete labelButton_next;
+ labelButton_next=nullptr;
+ }
+ if(label_1_MSG)
+ {
+ delete label_1_MSG;
+ label_1_MSG=nullptr;
+ }
+
+ if(label_2_MSG)
+ {
+ delete label_2_MSG;
+ label_2_MSG=nullptr;
+ }
+
+ if(label_3_MSG)
+ {
+ delete label_3_MSG;
+ label_3_MSG=nullptr;
+ }
+
+ if(Title)
+ {
+ delete Title;
+ Title=nullptr;
+ }
+
+ delete testgyroScrollView;
+ testgyroScrollView=nullptr;
+ }
+ }
+
+ UILabelButtonExt *testgyroView::SetTheButton_ext(ButtonConfig_ext_t &buttonconfig)
+ {
+ UILabelButtonExt *button = new UILabelButtonExt();
+ if (button == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SystemView::SetTheButton: button new fail!");
+ return nullptr;
+ }
+ button->SetPosition(buttonconfig.x, buttonconfig.y, buttonconfig.w, buttonconfig.h);
+ button->SetViewId(buttonconfig.ViewId);
+ button->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full);
+ //button->SetStyle(STYLE_BORDER_RADIUS,0);
+ button->SetStyleForState(STYLE_BACKGROUND_COLOR, Color::Black().full, UIButton::PRESSED);
+ //button->SetStyleForState(STYLE_BORDER_RADIUS,0, UIButton::PRESSED);
+ button->SetTouchable(true);
+ button->SetStyle(STYLE_BACKGROUND_OPA, 0x80);
+ button->SetText(buttonconfig.str);
+ button->SetAlign(TEXT_ALIGNMENT_LEFT);
+ button->SetLabelPosition(buttonconfig.label_x,buttonconfig.label_y );
+ button->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, buttonconfig.Fontsize);
+ UIView:: OnClickListener *touchListener = static_cast<UIView::OnClickListener *>(testPresenter::GetInstance());
+ button->SetOnClickListener(touchListener);
+
+ return button;
+ }
+
+ UILabel *testgyroView::InitLabel(LabelConfig &labelConfig)
+ {
+ UILabel *label = new UILabel();
+ if (label == nullptr)
+ {
+ return nullptr;
+ }
+ label->SetPosition(labelConfig.left, labelConfig.top, labelConfig.width, labelConfig.height); // 位置大小
+ label->SetStyle(STYLE_TEXT_FONT, labelConfig.fontSize); // 字体大小
+ label->SetStyle(STYLE_LINE_HEIGHT, labelConfig.lineHeigh); // 字体行高
+ label->SetText(labelConfig.text); // 内容
+ label->SetLineBreakMode(labelConfig.lineBreakMode); // 断行模式。
+ label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_TOP);
+ label->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, labelConfig.fontSize);
+ label->SetAlign(TEXT_ALIGNMENT_LEFT);
+ return label;
+ }
+
+
+ void testgyroView:: gyrodataTimerCallBack(void)
+ {
+ //此处实现数据刷新
+ char buf1[32]={0};
+ char buf2[32]={0};
+ char buf3[32]={0};
+#ifdef ENABLE_GYRO
+ gyro_data_t data = gyro_get_data();
+
+ // printf("gyro.x:%.2f gyro.y:%.2f gyro.z:%.2f \n",data.x,data.y,data.z);
+
+ sprintf(buf1,"gyro.x:%.2f",data.x);
+ sprintf(buf2,"gyro.y:%.2f",data.y);
+ sprintf(buf3,"gyro.z:%.2f",data.z);
+#endif
+ label_1_MSG->SetText(buf1);
+ label_2_MSG->SetText(buf2);
+ label_3_MSG->SetText(buf3);
+ RootView::GetInstance()->Invalidate();
+ }
+
+ void gyrodataTimerCallBackproc()
+ {
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(&testgyroView::gyrodataTimerCallBack,testgyroView::GetInstance()));
+ }
+
+
+ bool testgyroView::testgyroScrollViewcrollViewinit(uint8_t id)
+ {
+
+ testgyroScrollView = new UIScrollView();
+ if (testgyroScrollView == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemAboutTheWatchView::testgyroScrollView new fail!");
+ return false;
+ }
+ testgyroScrollView->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+ testgyroScrollView->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+ testgyroScrollView->SetStyle(STYLE_BORDER_RADIUS, 0);
+ testgyroScrollView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
+ testgyroScrollView->SetStyle(STYLE_BORDER_COLOR, Color::Yellow().blue);
+
+
+ UIView::OnDragListener *draglistener = static_cast<UIView::OnDragListener *>(testPresenter::GetInstance());
+ if (draglistener == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemView::draglistener can not be nullptr!");
+ return false;
+ }
+ testgyroScrollView->SetOnDragListener(draglistener);
+
+ LabelConfig Config = {
+ .left = 100,
+ .top = 100,
+ .width = 300,
+ .height = 35,
+ .fontSize = 40,
+ .lineHeigh = 35,
+ .text = "",
+ .lineBreakMode = UILabel::LINE_BREAK_WRAP,
+ };
+ label_1_MSG= InitLabel(Config);
+ if (label_1_MSG == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemView::SystemAboutTheWatchTitle new fail!");
+ return false;
+ }
+ testgyroScrollView->Add(label_1_MSG);
+
+ Config = {
+ .left = 100,
+ .top = 180,
+ .width = 300,
+ .height = 35,
+ .fontSize = 40,
+ .lineHeigh = 35,
+ .text = "",
+ .lineBreakMode = UILabel::LINE_BREAK_WRAP,
+ };
+ label_2_MSG= InitLabel(Config);
+ if (label_2_MSG == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemView::SystemAboutTheWatchTitle new fail!");
+ return false;
+ }
+ testgyroScrollView->Add(label_2_MSG);
+
+ Config = {
+ .left = 100,
+ .top = 260,
+ .width = 300,
+ .height = 35,
+ .fontSize = 40,
+ .lineHeigh = 35,
+ .text = "",
+ .lineBreakMode = UILabel::LINE_BREAK_WRAP,
+ };
+ label_3_MSG= InitLabel(Config);
+ if (label_3_MSG == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SystemView::SystemAboutTheWatchTitle new fail!");
+ return false;
+ }
+ testgyroScrollView->Add(label_3_MSG);
+
+ labelButton_next= testAboutView::GetInstance()->init_button_next(267,320,Test_ViewMapper_t[id].viewid_str_next);
+ testgyroScrollView->Add(labelButton_next);
+
+ Title= testAboutView::GetInstance()->init_title(125,45,"GYRO_TEST");
+ testgyroScrollView->Add(Title);
+
+
+ testgyroScrollView->SetTouchable(true);
+ testgyroScrollView->SetDraggable(true);
+
+#ifdef ENABLE_GYRO
+#ifdef ROTARYENCODER_MIXO
+ do_mixo_service_check_msg(MIXO_SERVICE_CMD_STOP_CHECK);
+#endif
+ gyro_start();
+#endif
+
+ uint32_t tick;
+ osStatus_t retTimer;
+ P_TEST_timer = osTimerNew((osTimerFunc_t)gyrodataTimerCallBackproc, osTimerPeriodic, NULL, NULL);
+ tick =2000;// osMs2Tick(1000);
+ retTimer = osTimerStart(P_TEST_timer, tick);
+ if (retTimer != osOK && P_TEST_timer != NULL) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"StartCallTimer osTimerStart failed, ret = %lx!!", retTimer);
+ osTimerDelete(P_TEST_timer);
+ P_TEST_timer = NULL;
+ return false;
+ }
+ return true;
+ }
+
+ UIScrollView *testgyroView::testgyroInitIView(uint8_t id)
+ {
+ if (!testgyroScrollViewcrollViewinit(id))
+ {
+ return nullptr;
+ }
+ return testgyroScrollView;
+ }
+}
+
+// #endif
std::unordered_map<uint16_t, std::string> registeredDials{
#ifdef CUSTOM_Z1
{DEFAULT_DIAL_ID_0, "Z1"},
-#elif BOARD_W9
+#elif BOARD_N9
{DEFAULT_DIAL_ID_0, "N9"},
#else
{DEFAULT_DIAL_ID_0, "KUMI"},
.lineHeigh = LABEL_LINEHEIGHT,\r
#ifdef CUSTOM_Z1\r
.text = "Z1",\r
- #elif BOARD_W9\r
+ #elif defined(BOARD_W9) || defined(BOARD_N9)\r
.text = "Watch N9",\r
#else\r
.text = "Watch Soar",\r
.fontSize = LABEL_FONTSIZE,\r
.lineHeigh = LABEL_LINEHEIGHT,\r
#if defined(SUPPORT_CHINA_MOBILE_DMP) || defined(SUPPORT_TELECOM_DMP)\r
- #ifdef BOARD_W9\r
+ #if defined(BOARD_W9) || defined(BOARD_N9)\r
.text = "Watch N9 V1.0",\r
#else\r
.text = "Watch Soar V1.0",\r
SystemAboutTheWatchScrollView->Add(HWVERTitle);\r
/* -------------------------------------------------------------------------- */\r
char * versionstr;\r
-#ifdef BOARD_W9\r
+#if defined(BOARD_W9) || defined(BOARD_N9)\r
versionstr= "Watch V1.0";\r
#else\r
versionstr= "FD230 V1.0";\r
ProductModelName->SetStyle(STYLE_LINE_HEIGHT, 30); // 字体行高\r
#ifdef CUSTOM_Z1\r
ProductModelName->SetText("Z1"); // 内容\r
- #elif BOARD_W9\r
+ #elif defined(BOARD_W9) || defined(BOARD_N9)\r
ProductModelName->SetText("Watch N9"); // 内容\r
#else\r
ProductModelName->SetText("Watch Soar"); // 内容\r
ble_cywee_store_report_handle(result->value_handle);\r
// }\r
\r
- ble_cywee_store_recv_handle(69);\r
+ ble_cywee_store_recv_handle(73);\r
}\r
#endif\r
return;\r
uint16_t server_handle = mail.service_handle;\r
uint32_t msg_len = mail.msg_len;\r
\r
- // WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"mail.msg_data:%X,g_blesrv_queue:%d ble_recv:%d %d %02X %02X %02X mail.msg_data: %02X %02X %02X\r\n",\r
+ // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"mail.msg_data:%X,g_blesrv_queue:%d ble_recv:%d %d %02X %02X %02X mail.msg_data: %02X %02X %02X\r\n",\r
// mail.msg_data,\r
// g_blesrv_queue,\r
// msg_len,\r
#ifdef CUSTOM_Z1
#define BLE_DEFAULT_NAME "Z1"//"
-#elif BOARD_W9
+#elif defined(BOARD_W9) || defined(BOARD_N9)
#define BLE_DEFAULT_NAME "WATCH N9"//"N9
#else
#define BLE_DEFAULT_NAME "WATCH Soar"//"FD230
* @Author: penglei 1624952103@qq.com\r
* @Date: 2024-06-17 14:31:08\r
* @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-06-06 17:11:43\r
+ * @LastEditTime: 2025-06-13 16:15:04\r
* @FilePath: /FD230/code/sdk/application/wearable/service/factorytest_service/factorytest_protocol.c\r
* @Description: \r
* \r
&send_data,\r
1);\r
}\r
+ case BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS:\r
\r
+ if (testitem == 0x01)\r
+ {\r
+ //定位\r
+ uint8_t send_data = 0;\r
+ bool flag = 0;\r
+ char tmp[1024]={0};\r
+ char time[10]={0};\r
+#ifdef SUPPORT_GNSS\r
+ gnss_start();\r
+ LOS_Msleep(100);\r
+ do{\r
+ gps_data_t *gps_data = getGPSGlobaldata();\r
+ if(gps_data == NULL)\r
+ {\r
+ PRINT("gps_data == NULL \n");\r
+ return;\r
+ }\r
+ if (gps_data->last_gps_time_ms > 0)\r
+ {\r
+ memcpy_s(&send_gps_data,sizeof(gps_data_t),gps_data,sizeof(gps_data_t));\r
+ }\r
+ if(send_gps_data.status > 1)\r
+ {\r
+ flag = 1;\r
+ }\r
+ else\r
+ {\r
+ LOS_Msleep(1000);\r
+ send_data++;\r
+ }\r
+ memset_s(tmp,sizeof(tmp),0,sizeof(tmp)); \r
+ dump_location_data_to_factory(&send_gps_data,tmp,sizeof(tmp));\r
+ memset_s(time,sizeof(time),0,sizeof(time)); \r
+ sprintf_s(time,sizeof(time),"%d",send_data);\r
+ strcat_s(tmp,sizeof(tmp),time);\r
+ PRINT("send_gps_data.status : %d time : %d\n",send_gps_data.status,send_data);\r
+ PRINT("tmp : %s size : %d\n",tmp,strlen(tmp));\r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS,\r
+ 0x01,\r
+ (uint8_t*)tmp,\r
+ strlen(tmp));\r
+ }while(send_data <= 2 * 60 && !flag);\r
+ // PRINT("定位超时 关闭GPS\n");\r
+ gnss_stop();\r
+#endif\r
+\r
+ } else if(testitem == 0x02)\r
+ {\r
+ //获取可见星 有效星 信号增益 定位精度\r
+ uint8_t send_data[7] = {0};\r
+#ifdef SUPPORT_GNSS\r
+ // if(send_gps_data)\r
+ {\r
+ send_data[0] = send_gps_data.num_sats;\r
+ send_data[1] = send_gps_data.th001_valid_star_count;\r
+ send_data[2] = send_gps_data.th000_signal_vga;\r
+ send_data[3] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0xFF000000) >> 24);\r
+ send_data[4] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0x00FF0000) >> 16);\r
+ send_data[5] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0x0000FF00) >> 8);\r
+ send_data[6] = (uint8_t)(((uint32_t)send_gps_data.th001_quality & 0x000000FF) >> 0);\r
+\r
+ // PRINT("gps_data->num_sats : %d,gps_data->th001_valid_star_count : %d,gps_data->th000_signal_vga : %d,gps_data->th001_quality : %f\n",\r
+ // send_gps_data.num_sats,send_gps_data.th001_valid_star_count,\r
+ // send_gps_data.th000_signal_vga,send_gps_data.th001_quality\r
+ // );\r
+ // PRINT("%2X %2X %2X\r\n",send_data[0],send_data[1],send_data[2]);\r
+ // PRINT("%2X %2X %2X %2X \r\n",send_data[3],send_data[4],send_data[5],send_data[6]);\r
+ }\r
+#endif\r
+ factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
+ BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS,\r
+ 0x02,\r
+ send_data,\r
+ sizeof(send_data));\r
+ }\r
+\r
+ break;\r
break;\r
\r
default:\r
\r
printf("crc16 0x%04X vs 0x%04X\n",crc16,crc16_2);\r
\r
- if( crc16 == crc16_2) //校验通过,开始正式解析\r
+ // if( crc16 == crc16_2) //校验通过,开始正式解析\r
{\r
if(factorytest_mode_flag == 0 && header.submod != BLE_TEST_CMD_COMMON_SUB_MODE_SWITCH_MODE)\r
return ERRCODE_FAIL;\r
#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_CAT1 0x1A
//软件测试 子模式ID SPEAKER
#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_SPEAKER 0x1B
+//软件测试 子模式ID GPS
+#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_GPS 0x1D
//软件测试 子模式ID 通讯录
#define BLE_TEST_CMD_SOFT_TEST_SUB_MODE_CONTACTS 0x30
//软件测试 子模式ID 支付宝
\r
errcode_t ret=0;\r
\r
-#if defined (BOARD_L22) || defined (BOARD_W9)\r
+#if defined (BOARD_W9) || defined (BOARD_N9)\r
ret=uapi_gpio_set_dir(S_AGPIO_L23,GPIO_DIRECTION_OUTPUT);\r
if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L23,GPIO_DIRECTION_OUTPUT ret %d\n",ret);\r
// ret=uapi_gpio_set_dir(S_AGPIO_L28,GPIO_DIRECTION_OUTPUT);\r
'-:ROTARYENCODER_HX3507',
'-:BOARD_FD230',
'BOARD_W9',
- # 'SUPPORT_GNSS',
- # 'DISABLE_UART_LOG',
- # 'CONFIG_GNSS_UART_WITH_FLOWCTRL',
- # 'DOWNLOAD_GNSS_SWITCH',
+ 'SUPPORT_GNSS',
+ 'DISABLE_UART_LOG',
+ 'CONFIG_GNSS_UART_WITH_FLOWCTRL',
+ 'DOWNLOAD_GNSS_SWITCH',
'TPTYPE_CST86XX',
'NANDFLASH_F35UQA',
- #'PPG_GH3X2X',
+ 'PPG_GH3X2X',
'GYRO_SH5001',
'ROTARYENCODER_MIXO',
+ 'ENABLE_BN02',
+ 'ENABLE_GYRO',
],
'ram_component': [
"gnss",
"gnss_sample",
- #"ppg_sensor_gh3x2x",
- "ppg_sensor_pah8009",
- #"bp_sensor",
- #'gyro',
- 'ppg_hal',
+ "ppg_sensor_gh3x2x",
+ #"ppg_sensor_pah8009",
+ "bp_sensor",
+ 'gyro',
],
'image_analysis': False,
'fs_image_path':'w9',
'NANDFLASH_F35UQA'
]
},
+
+ ################# n9 ############################
+ 'brandy-native-js-n9': {
+ 'base_target_name': 'brandy-native-js',
+ 'defines': [
+ '-:TPTYPE_FT6X46',
+ '-:PPG_HX3695',
+ '-:ROTARYENCODER_HX3507',
+ '-:BOARD_FD230',
+ 'BOARD_N9',
+ 'SUPPORT_GNSS',
+ 'DISABLE_UART_LOG',
+ 'CONFIG_GNSS_UART_WITH_FLOWCTRL',
+ 'DOWNLOAD_GNSS_SWITCH',
+ 'TPTYPE_CST86XX',
+ 'NANDFLASH_F35UQA',
+ #'PPG_GH3X2X',
+ 'GYRO_SH5001',
+ 'ROTARYENCODER_MIXO',
+ 'ENABLE_GYRO',
+ ],
+ 'ram_component': [
+ "gnss",
+ "gnss_sample",
+ #"ppg_sensor_gh3x2x",
+ "ppg_sensor_pah8009",
+ #"bp_sensor",
+ 'gyro',
+ ],
+ 'image_analysis': False,
+ 'fs_image_path':'n9',
+ 'fs_image': True
+ },
+ 'brandy-native-js-n9-r': {
+ 'base_target_name': 'brandy-native-js-r',
+ #自定义配置项,选择硬件及功能参数
+ 'defines': [
+ '-:TPTYPE_FT6X46',
+ 'BOARD_N9',
+ 'TPTYPE_CST86XX',
+ 'NANDFLASH_F35UQA'
+ ],
+ },
+ 'brandy-native-js-n9-ssb': {
+ 'base_target_name': 'brandy-ssb',
+ #自定义配置项,选择硬件及功能参数
+ 'defines': [
+ 'BOARD_N9',
+ 'GPIO_POWERON_FLASH',
+ 'NANDFLASH_F35UQA'
+ ]
+ },
}
target_group = {
'pack_brandy_native_js_cm_ai': ['brandy-ssb', 'brandy-native-js-r', 'brandy-native-js-cm-ai'],
'pack_brandy_native_js_4part': ['brandy-ssb', 'brandy-native-js-r-4part', 'brandy-native-js-4part'],
'pack_brandy_native_js_w9': ['brandy-native-js-w9-ssb', 'brandy-native-js-w9-r', 'brandy-native-js-w9'],
+ 'pack_brandy_native_js_n9': ['brandy-native-js-n9-ssb', 'brandy-native-js-n9-r', 'brandy-native-js-n9'],
'pack_brandy_native_js_fd230': ['brandy-native-js-fd230-ssb', 'brandy-native-js-fd230-r', 'brandy-native-js-fd230'],
'pack_brandy_xts': ['brandy-ssb', 'brandy-xts-r', 'brandy-xts'],
'pack_brandy_native_js_oob128': ['brandy-ssb-oob128', 'brandy-native-js-r', 'brandy-native-js-oob128'],
version https://git-lfs.github.com/spec/v1
-oid sha256:ccaf8aeb2a73734a10631405e462da7529ef592dc1f81403d60c1c5ebc373f4f
-size 43967616
+oid sha256:f45854c84d2648a7f2b51f9bddb38f3963f88ef15af8dc921be0b8be760c2a64
+size 43963392
version https://git-lfs.github.com/spec/v1
-oid sha256:534b215d45d9485abe3a0307c18fb36e299383d8dedc8956d59587c02b8cdcac
-size 43967616
+oid sha256:ae52e6e007867f07fe7d782db762d39686fa952adbecdf7fc232aea2f1023191
+size 43963392
version https://git-lfs.github.com/spec/v1
-oid sha256:ccaf8aeb2a73734a10631405e462da7529ef592dc1f81403d60c1c5ebc373f4f
-size 43967616
+oid sha256:a317e355903aa113ed57ca69838e97c5e6edf1f9cbe9b22b0f7e91de60c9ad53
+size 43963392
version https://git-lfs.github.com/spec/v1
-oid sha256:534b215d45d9485abe3a0307c18fb36e299383d8dedc8956d59587c02b8cdcac
-size 43967616
+oid sha256:7e383c66b84c89fb165eba71148fec946526964e9469ed0c4b7d679d057480dc
+size 43963392
{ HAL_PIO_FUNC_EMMC, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_HGPIO15 emmc clk
#endif
{ HAL_PIO_FUNC_SPI0, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO0 NC
-#ifdef BOARD_W9
{ HAL_PIO_FUNC_I2C2_M3, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO1 I2C2 SCL Sensor 6轴 指南针 心率
{ HAL_PIO_FUNC_I2C2_M3, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO2 I2C2 SDA Sensor
-#else
- { HAL_PIO_FUNC_SPI0, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO1 NC
- { HAL_PIO_FUNC_SPI0, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO2 NC
-#endif
{ HAL_PIO_FUNC_SPI0, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO3 NC
// #if (defined BRANDY_PRODUCT_EVB4)
{ HAL_PIO_FUNC_I2C0_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO12 I2C0 SDA
{ HAL_PIO_FUNC_I2C1_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO13 I2C1 SCL touch i2c
{ HAL_PIO_FUNC_I2C1_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO14 I2C1 SDA
-#ifdef BOARD_W9
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO15 I2C2 SCL Sensor 6轴 指南针 心率
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_DOWN, HAL_PIO_IE_DISABLE }, // S_MGPIO16 I2C2 SDA Sensor
-#else
- { HAL_PIO_FUNC_I2C2_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO15 I2C2 SCL Sensor 6轴 指南针 心率
- { HAL_PIO_FUNC_I2C2_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_MGPIO16 I2C2 SDA Sensor
-#endif
{ HAL_PIO_FUNC_I2C3_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO17 i2c3 SCL smart pa\ 预留马达控制 \安全芯片
{ HAL_PIO_FUNC_I2C3_M1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_MGPIO18 I2C3 SDA
{ HAL_PIO_FUNC_UART1, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_DISABLE }, // S_MGPIO19 uart1 tx
// #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_UP, HAL_PIO_IE_DISABLE }, // S_AGPIO_R3 NC
+#ifdef BOARD_N9
+ { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_ENBALE }, // S_AGPIO_R3 NC
+#else
+ { HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_DISABLE },
+#endif
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_UP, HAL_PIO_IE_DISABLE }, // S_AGPIO_R4 tp reset
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_R5 touch int
{ HAL_PIO_FUNC_GPIO, HAL_PIO_DRIVE_MAX, HAL_PIO_PULL_MAX, HAL_PIO_IE_ENBALE }, // S_AGPIO_R6 PRG_INT 心率中断
{HAL_CLOCKS_APP_SPI2_MS_CLK, TURN_OFF}, // spi2 clock
{HAL_CLOCKS_APP_UART_H0_CLK, TURN_ON}, // uart h0 clock
{HAL_CLOCKS_APP_UART_H1_CLK, TURN_ON}, // uart h1 clock
+#ifdef BOARD_W9
+ {HAL_CLOCKS_APP_I2C0_CLK, TURN_ON}, // i2c0 clock
+#else
{HAL_CLOCKS_APP_I2C0_CLK, TURN_OFF}, // i2c0 clock
+#endif
{HAL_CLOCKS_APP_I2C1_CLK, TURN_ON}, // i2c1 clock
{HAL_CLOCKS_APP_I2C2_CLK, TURN_ON}, // i2c2 clock
{HAL_CLOCKS_APP_I2C3_CLK, TURN_ON}, // i2c3 clock
#include "board_fpga.h"
#elif PRE_ASIC
-#if defined(BOARD_W9)
+#if defined(BOARD_W9) || defined(BOARD_N9)
#include "board_w9.h"
#else
#include "board_evb.h"
add_subdirectory_if_exist(a5133)
add_subdirectory_if_exist(entest)
add_subdirectory_if_exist(gnss)
+add_subdirectory_if_exist(bp)
+add_subdirectory_if_exist(gyro)
\ No newline at end of file
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "bp_sensor")
+
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/bn02/bn02.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/bp_at_cmd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/bp_service.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/bp_ble_service.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/bp_tcp_server.c
+
+)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/bn02/
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+ TARGET_NAME="${TARGET_COMMAND}"
+ BUILD_TIME="${BUILD_TIME}"
+)
+
+set(PUBLIC_DEFINES
+SUPPORT_AT_BP
+ENABLE_BN02
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+find_library(LIB_PATH_BP lib/lib_hr_yll_v0.5.3.060325.a ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive ${LIB_PATH_BP} PRIVATE -Wl,--whole-archive)
+
+build_component()
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-16 12:35:15\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-06-12 16:37:28\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/bn02/bn02.c\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#include "stdint.h"\r
+#include "bn02.h"\r
+#include "custom_utils.h"\r
+#include "pinctrl_porting.h"\r
+#include "hal_gpio.h"\r
+#include "i2c.h"\r
+#include "pm_definition.h"\r
+#include "bp_ble_service.h"\r
+#include "bp_tcp_server.h"\r
+\r
+\r
+#define BN02_I2C_ADDR 0x05\r
+#define BN02_I2C_BUS I2C_BUS_0\r
+#define I2C_ADDR_BN02_W 0x0a\r
+#define I2C_ADDR_BN02_R 0x0b\r
+#define P_EN S_AGPIO_L24\r
+#define P_INT S_AGPIO_R3\r
+\r
+#define POWER_EN S_AGPIO_R0\r
+\r
+#define BN02_FILE "user/userdata/bn02.bin"\r
+\r
+static int DATA_HANDLE = 1 << 24;\r
+\r
+static FILE *fp = NULL;\r
+\r
+static int data_cnt = 0;\r
+// static int data[16 * 5 * 60] = {0};\r
+\r
+// int data = ((rxByte[i] & 0xff) << 16)\r
+// + ((rxByte[i + 1] & 0xff) << 8)\r
+// + (rxByte[i + 2] & 0xff);\r
+// if (data >= DATA_HANDLE / 2) {\r
+// data -= DATA_HANDLE;\r
+// }\r
+// 其中:DATA_HANDLE = 2^24\r
+\r
+\r
+bool Bn02_write_reg(uint8_t data)\r
+{\r
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_BP);\r
+ if (cnt == 0) \r
+ {\r
+ uapi_pm_add_sleep_veto(PM_ID_BP);\r
+ }\r
+\r
+ i2c_data_t i2c_data;\r
+ i2c_data.send_buf = &data;\r
+ i2c_data.send_len = sizeof(data);\r
+ i2c_data.receive_buf = NULL;\r
+ i2c_data.receive_len = 0;\r
+ // custom_i2c_write_reg(BN02_I2C_ADDR, 0x00, 1, &data, 1, BN02_I2C_BUS);\r
+ errcode_t ret = uapi_i2c_master_write(BN02_I2C_BUS, BN02_I2C_ADDR, &i2c_data);\r
+ if (ret != ERRCODE_SUCC)\r
+ printf("i2c Write data write fail! ret=0x%x\n", ret);\r
+\r
+ cnt = pm_veto_get_id_cnt(PM_ID_BP);\r
+ if (cnt == 1) \r
+ {\r
+ uapi_pm_remove_sleep_veto(PM_ID_BP);\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+bool Bn02_reads(uint8_t *data,int len)\r
+{\r
+\r
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_BP);\r
+ if (cnt == 0) \r
+ {\r
+ uapi_pm_add_sleep_veto(PM_ID_BP);\r
+ }\r
+\r
+ i2c_data_t i2c_data;\r
+ i2c_data.send_buf = NULL;\r
+ i2c_data.send_len = 0;\r
+ i2c_data.receive_buf = data;\r
+ i2c_data.receive_len = len;\r
+ // custom_i2c_write_reg(BN02_I2C_ADDR, 0x00, 1, &data, 1, BN02_I2C_BUS);\r
+ errcode_t ret = uapi_i2c_master_read(BN02_I2C_BUS, BN02_I2C_ADDR, &i2c_data);\r
+ if (ret != ERRCODE_SUCC) \r
+ printf("i2c read data fail! ret=0x%x\n", ret);\r
+\r
+ cnt = pm_veto_get_id_cnt(PM_ID_BP);\r
+ if (cnt == 1) \r
+ {\r
+ uapi_pm_remove_sleep_veto(PM_ID_BP);\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+static void delay_ms(int cnt)\r
+{\r
+ LOS_Mdelay(cnt);\r
+}\r
+\r
+void Bn02_Power_Ctrl(int onoff)\r
+{\r
+ if(onoff == 1)\r
+ {\r
+ uapi_pin_set_mode(POWER_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(POWER_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(POWER_EN, GPIO_LEVEL_HIGH);\r
+ LOS_Mdelay(1);\r
+ uapi_pin_set_mode(P_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(P_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(P_EN, GPIO_LEVEL_HIGH);\r
+ // delay_ms(20);\r
+ LOS_Mdelay(50);\r
+ }\r
+ else\r
+ {\r
+ uapi_pin_set_mode(P_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(P_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(P_EN, GPIO_LEVEL_LOW);\r
+\r
+ uapi_pin_set_mode(POWER_EN, (pin_mode_t)HAL_PIO_FUNC_GPIO);\r
+ uapi_gpio_set_dir(POWER_EN, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(POWER_EN, GPIO_LEVEL_LOW);\r
+ }\r
+}\r
+\r
+void bn02_int_init(void)\r
+{\r
+ uapi_pin_set_ie(P_INT,HAL_PIO_IE_ENBALE);\r
+}\r
+\r
+void bn02_int_deinit(void)\r
+{\r
+ uapi_pin_set_ie(P_INT,HAL_PIO_IE_DISABLE);\r
+}\r
+\r
+void bn02_int_handle(void)\r
+{\r
+ uint8_t bn02_buf[48] = {0};\r
+ int i;\r
+ memset(bn02_buf,0,sizeof(bn02_buf));\r
+ Bn02_reads(bn02_buf,48);\r
+ int reply_data[16] = {0}; \r
+ int cnt = 0;\r
+ for(i = 0;i<48;i+=3,cnt++)\r
+ {\r
+ reply_data[cnt] = ((bn02_buf[i] & 0xff) << 16)\r
+ + ((bn02_buf[i + 1] & 0xff) << 8)\r
+ + (bn02_buf[i + 2] & 0xff);\r
+\r
+ if (reply_data[cnt] >= DATA_HANDLE / 2)\r
+ reply_data[cnt] -= DATA_HANDLE;\r
+\r
+ printf("111data[%d]:%d\n",cnt,reply_data[cnt]);\r
+ // printf("0x%x 0x%x 0x%x 0x%x\n",i,bn02_buf[i],bn02_buf[i+1],bn02_buf[i+2],reply_data[cnt]);\r
+ }\r
+\r
+ // if(bn02_get_ble_status())\r
+ // {\r
+ // bn02_replymsg(reply_data,cnt,1);\r
+ // }\r
+\r
+ // if(fp)\r
+ // {\r
+ // data_cnt += cnt;\r
+ // if(fwrite(bn02_buf,sizeof(int),cnt,fp) != cnt)\r
+ // printf("bn02 fwrite failed\n");\r
+ // else\r
+ // printf("bn02 fwrite succed data_cnt:%d\n",cnt);\r
+ // }\r
+\r
+\r
+ // printf("data_cnt:%d\n",data_cnt);\r
+\r
+ \r
+ do_bp_tcp_server_send_data((void *)reply_data,cnt);\r
+\r
+ // if(data_cnt >= 16 * 5 * 60 && fp)\r
+ // {\r
+ // int *data_array = (int *)malloc(data_cnt * sizeof(int));\r
+\r
+ // if (!data_array) \r
+ // {\r
+ // printf("内存分配失败\n");\r
+ // }\r
+ // else \r
+ // {\r
+ // int read_count = 0;\r
+\r
+ // fseek(fp, 0, SEEK_SET);\r
+\r
+ // while (read_count < data_cnt && fread(&data_array[read_count], sizeof(int), 1, fp) == 1)\r
+ // {\r
+ // printf("%d ", data_array[read_count]);\r
+ // read_count++;\r
+ \r
+ // if (read_count % 10 == 0)\r
+ // printf("\n");\r
+ // }\r
+ \r
+ // printf("\n实际读取数据: %d 个\n", read_count);\r
+ \r
+ // if (feof(fp))\r
+ // printf("已读取所有数据\n");\r
+ // else if (ferror(fp)) \r
+ // {\r
+ // printf("读取数据时发生错误\n");\r
+ // free(data_array);\r
+ // data_array = NULL;\r
+ // }\r
+\r
+\r
+ // free(data_array);\r
+ // data_array = NULL;\r
+ \r
+ // // 清空文件内容(将文件指针移到文件开头并截断文件)\r
+ // fclose(fp); // 关闭文件\r
+ // if(remove(BN02_FILE) != 0)\r
+ // printf("remove %s failed\n",BN02_FILE);\r
+ // else\r
+ // printf("remove %s succed\n",BN02_FILE);\r
+\r
+ // bn02_stop();\r
+ // } \r
+ // } \r
+ \r
+}\r
+\r
+void bn02_start(void)\r
+{\r
+ Bn02_Power_Ctrl(1);\r
+ bn02_int_init();\r
+ Bn02_write_reg(BN02_START_CMD);\r
+ // data_cnt = 0;\r
+ // fp = fopen(BN02_FILE, "ab+");\r
+ // if(fp == NULL)\r
+ // printf("open %s failed\n",BN02_FILE);\r
+ // else\r
+ // printf("open %s succed\n",BN02_FILE);\r
+}\r
+\r
+void bn02_stop(void)\r
+{\r
+ bn02_int_deinit();\r
+ Bn02_write_reg(BN02_STOP_CMD);\r
+ Bn02_Power_Ctrl(0);\r
+\r
+ bp_tcp_data_clean();\r
+ // if(fp)\r
+ // {\r
+ // fclose(fp);\r
+ // fp = NULL;\r
+ // }\r
+}\r
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-16 12:35:15\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-01-16 14:55:48\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/bn02/bn02.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#ifndef _BN02_H_\r
+#define _BN02_H_\r
+\r
+enum\r
+{\r
+\r
+ BN02_INT_HANDLE,\r
+ BN02_INIT_ENABLE,\r
+ BN02_START,\r
+ BN02_POWER_DISABLE,\r
+ BN02_STOP,\r
+};\r
+\r
+#define BN02_START_CMD 0x04\r
+#define BN02_STOP_CMD 0x08\r
+\r
+void bn02_int_handle(void);\r
+\r
+void bn02_start(void);\r
+\r
+void bn02_stop(void);\r
+\r
+#endif // _HRS3300_H_\r
+\r
--- /dev/null
+#ifndef __LIB_EMOTION_H__\r
+#define __LIB_EMOTION_H__\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+\r
+#define SAMPLERATE 81 // sampling rate\r
+//#define SAMPLERATE 100\r
+#define SAMPLETIME 5 // sampling time (seconds) data of which will be processed every time\r
+#define EMOTIONTIME 60\r
+#define HRVTIME 300\r
+#define BPTIME 30\r
+#define DDTIME 20 // measure duration of drinking degree\r
+#define SINGLETIME 5\r
+#define MAX_SLEEP_STATE 50\r
+\r
+\r
+/* Integer data types */\r
+#if ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) && \\r
+ (!defined(__ICC8051__) || (__ICC8051__ == 0)))\r
+#include <stdint.h>\r
+#else\r
+ typedef signed char int8_t;\r
+ typedef unsigned char uint8_t;\r
+ typedef signed short int16_t;\r
+ typedef unsigned short uint16_t;\r
+ typedef signed long int32_t;\r
+ typedef unsigned long uint32_t;\r
+ typedef unsigned long long uint64_t;\r
+#endif\r
+\r
+typedef struct\r
+{\r
+ short int x;\r
+ short int y;\r
+ short int z;\r
+} gsensor_data_t;\r
+\r
+typedef enum\r
+{\r
+ LS_STATE = 11, // light sleep\r
+ DS_STATE = 12, // deep sleep\r
+ REM_STATE = 2, // rapid eye movement\r
+} SLEEP_STATE_E;\r
+\r
+typedef struct\r
+{\r
+ uint16_t year;\r
+ uint8_t month;\r
+ uint8_t day;\r
+ uint8_t hour;\r
+ uint8_t minute;\r
+} sleep_time_t;\r
+\r
+typedef struct\r
+{\r
+ uint32_t duration; // the duration of corresponding state\r
+ SLEEP_STATE_E state; // state\r
+} sleep_detail_data_t;\r
+\r
+typedef struct\r
+{\r
+ uint32_t total_sleep_time; // minutes\r
+ sleep_time_t begin_sleep_time; // sleep_time_t\r
+ sleep_time_t end_sleep_time;\r
+ uint16_t state_count; // number of some sleep state\r
+ sleep_detail_data_t data[MAX_SLEEP_STATE];\r
+} sleep_data_t;\r
+\r
+typedef struct\r
+{\r
+ uint16_t hr;\r
+ uint32_t timestamp; // timestamp in measuretime (s)\r
+} sleep_hr_t;\r
+\r
+\r
+typedef struct\r
+{\r
+ uint16_t sbp;\r
+ uint16_t dbp;\r
+ int32_t timestamp; // timestamp in measuretime\r
+} bps_t;\r
+\r
+\r
+\r
+// base api (include callback function)\r
+typedef void (*extern_printf_cb_t)(const char* format, ...);\r
+unsigned int extern_printf_cb_reg(extern_printf_cb_t fun);\r
+int init_algorithm(unsigned char* buf, unsigned int len);\r
+\r
+\r
+// heart rate variability algorithm api (include callback function)\r
+typedef void (*extern_get_hr_run_time_cb_t)(int* type, int* sec);\r
+unsigned int extern_get_hr_run_time_cb_reg(extern_get_hr_run_time_cb_t fun);\r
+int get_hr(int data[], int datalen, int fs, int* hr);\r
+\r
+\r
+// emotion algorithm api\r
+int ppg_midvalue(int data[], int datalen, int fs, float Fm[25][8], int* fmlen);\r
+int get_emotion_pi(int data[], int datalen, int fs, int* emo, int* pi);\r
+int get_dd_index(int data[], int datalen, int fs, int* dd, int* hr);\r
+\r
+\r
+// blood pressure algorithm api\r
+int load_bp_model(unsigned char str_model[], const unsigned int str_model_len);\r
+int get_bp(int data[], int datalen, int fs, int* sbp, int* dbp);\r
+int load_gen_info(int height, int weight, int age, int gender);\r
+int get_bp_general(int data[], int datalen, int fs, int* sbp, int* dbp);\r
+\r
+\r
+// temperature algorithm api\r
+int get_core_temperature(int gender, int age, int weight, int height, int hr, float t_skin_0, float t_air, float phi_air, float* t_core);\r
+\r
+\r
+// sleep algorithm api (include callback function)\r
+typedef void (*extern_get_wear_state_cb_t)(uint8_t* worn);\r
+unsigned int extern_get_wear_state_cb_reg(extern_get_wear_state_cb_t fun);\r
+typedef void (*extern_get_inst_hr_cb_t)(uint8_t* hr, sleep_time_t* hr_time);\r
+unsigned int extern_get_inst_hr_cb_reg(extern_get_inst_hr_cb_t fun);\r
+void init_sleep_algo_ex(sleep_data_t* sdata, int gfs, int pfs);\r
+int get_sleep_data_ex(gsensor_data_t gdata[], const int glen, int pdata[], const int plen, const sleep_time_t curtime, sleep_data_t* sdata);\r
+\r
+\r
+// authentication api\r
+void request_validation(\r
+ const unsigned char fact[], const unsigned int fact_len,\r
+ const unsigned char imei[], const unsigned int imei_len,\r
+ unsigned char req_code[], unsigned int* req_code_len);\r
+\r
+int activate_algorithm(\r
+ const unsigned char req_code[], const unsigned int req_code_len,\r
+ const unsigned char key_code[], const unsigned int key_code_len);\r
+\r
+\r
+// version api\r
+void version_get_string(char* string, unsigned int* str_len);\r
+\r
+\r
+\r
+#ifdef __cplusplus \r
+}\r
+#endif\r
+\r
+\r
+#endif\r
--- /dev/null
+//\r
+// Created on 2021/12/22.\r
+//\r
+\r
+#ifndef YYLPFEV01_H\r
+#define YYLPFEV01_H\r
+\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <math.h>\r
+\r
+//#include "algo.h"\r
+\r
+#define OUTPUTDATALEN 120U\r
+#define LIMITEDPPGLEN 3000U\r
+#define LIMITOFMOTIONCAL 3\r
+\r
+\r
+ typedef struct\r
+ {\r
+ int32_t x;\r
+ int32_t y;\r
+ int32_t z;\r
+ }yylPFE_AxesData_t;\r
+\r
+ typedef struct\r
+ {\r
+ yylPFE_AxesData_t axes;\r
+ int32_t ppgSample;\r
+ }yylPFE_InputData_t;\r
+\r
+\r
+#if 0\r
+typedef struct {\r
+ uint32_t timestamp;\r
+ uint16_t RRI;\r
+ uint32_t areaUP;\r
+ uint16_t areaUPBase;\r
+ uint16_t areaUPHeight;\r
+ uint32_t areaDOWN;\r
+ uint16_t areaDOWNBase;\r
+ uint16_t areaDOWNHeight;\r
+ uint16_t motion;\r
+}yylPFE_OutputData;\r
+\r
+#else\r
+\r
+typedef struct {\r
+ uint32_t timestamp; \r
+ uint32_t areaUP;\r
+ uint16_t areaUPBase;\r
+ uint16_t areaUPHeight;\r
+ uint32_t areaDOWN;\r
+ uint16_t areaDOWNBase;\r
+ uint16_t areaDOWNHeight;\r
+ uint16_t RRI;\r
+ uint16_t motion;\r
+}yylPFE_OutputData;\r
+\r
+#endif\r
+// len >= 6870\r
+void YYL_Init_PFE(unsigned char* buf, unsigned int len);\r
+\r
+void YYL_Input_PFE(yylPFE_InputData_t *pInputData, int32_t hr);\r
+\r
+yylPFE_OutputData * YYL_Output_PFE(int32_t *outputLen);\r
+\r
+void YYL_Output_PFE_Array_Clear(void);\r
+\r
+char * YYL_PFE_Get_Current_Version(void);\r
+\r
+#endif //YYLPFEV01_H\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-23 15:11:01
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-16 18:02:23
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/HP4570/service/bp_at_cmd.c
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "debug_print.h"
+#include "bp_service.h"
+#include "custom_utils.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define BP_MAX_ARGC 8
+#define BP_MAX_ARGV_LEN 64
+
+#define BP_SUCCESS 0
+#define BP_FAILED (-1)
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[BP_MAX_ARGC][BP_MAX_ARGV_LEN], uint32_t* argc)
+{
+ uint32_t pos = 0;
+ *argc = 0;
+
+ for (uint32_t i = 0; i < paraLen; i++) {
+ if ((para[i] == ' ' || para[i] == '\n') && pos != 0) {
+ argv[*argc][pos] = '\0';
+ *argc += 1;
+ pos = 0;
+ if (*argc >= BP_MAX_ARGC) {
+ return BP_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= BP_MAX_ARGV_LEN) {
+ return BP_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return BP_SUCCESS;
+}
+
+static uint8_t g_bp_test_started = 0;
+static uint32_t bn02_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t argv[BP_MAX_ARGC][BP_MAX_ARGV_LEN] = { 0 };
+ uint32_t argc = 0;
+
+ int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+ if (ret != BP_SUCCESS) {
+ PRINT("BPTEST ATCMD Convert Command Failed\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc != 1) {
+ PRINT("BPTEST ATCMD Set Parameter Failed argc %d\n",argc);
+ return ERRCODE_FAIL;
+ }
+ uint8_t start = (uint8_t)atoi((char*)argv[0]);
+ if (start == 1)
+ {
+ // if (g_bp_test_started == 1)
+ // {
+ // PRINT("SKIP bptest start, already start\r\n");
+ // return 0;
+ // }
+ do_bp_service_check_msg(BP_SERVICE_CMD_START_CHECK);
+ g_bp_test_started = 1;
+ }else if (start == 2){
+ // if (g_bp_test_started == 0)
+ // {
+ // PRINT("SKIP bptest stop, already stopped\r\n");
+ // return 0;
+ // }
+ do_bp_service_check_msg(BP_SERVICE_CMD_STOP_CHECK);
+ g_bp_test_started = 0 ;
+ }else if (start == 3){
+ // if (g_bp_test_started == 0)
+ // {
+ // PRINT("SKIP bptest stop, already stopped\r\n");
+ // return 0;
+ // }
+ do_bp_service_check_msg(BP_SERVICE_CMD_TIMER_CHECK);
+ g_bp_test_started = 0 ;
+ }else{
+ }
+ return ERRCODE_SUCC;
+}
+static const at_cmd_table_t g_bp_cmd[] = {
+ { (char *)"AT^BN02TEST", bn02_test, (char *)"1" },
+};
+
+at_cmd_table_t *get_bp_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_bp_cmd);
+ return (at_cmd_table_t *)g_bp_cmd;
+}
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-18 10:23:22
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-16 15:07:33
+ * @FilePath: /sdk615/code/sdk/drivers/peripheral/rotary_encoder/hx3509/hx3509_at_cmd.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef BP_AT_PROCESS_H
+#define BP_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_bp_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-02-14 10:30:21
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-26 15:39:37
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/service/bp_ble_service.c
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#include "stdint.h"
+#include "bn02.h"
+#include "custom_utils.h"
+#include "bp_service.h"
+#include "bp_ble_service.h"
+#include "factorytestService.h"
+
+#define START_CODE 0x55
+#define PPG_DATA_SIZE 3
+#define PACKET_DATA_LENGTH (PPG_DATA_SIZE * 16)
+
+static uint8_t ble_status = 0;
+
+typedef struct ble_bp_data_t
+{
+ uint8_t start_code; //0x55
+ uint8_t main_func_code; //主功能码
+ uint8_t sub_func_code; //从功能码;
+ uint16_t data_length; //标识和数据的长度之和
+ uint16_t flags; //标识
+ uint8_t* data;
+ uint8_t checksum; //验内容包括起始符、功能码、数据长度、标识、数据5个部分,取其和的最后8位作为校验和
+}ble_bp_data_t;
+
+
+static ble_bp_data_t ble_bp_data = {0};
+
+uint8_t bn02_get_ble_status(void)
+{
+ uint8_t status = ble_status;
+ return status;
+}
+
+uint8_t bn02_calculate_checksum(ble_bp_data_t frame)
+{
+ uint8_t checksum = 0;
+
+ checksum += frame.start_code;
+
+ checksum += frame.main_func_code;
+ checksum += frame.sub_func_code;
+
+ checksum += (frame.data_length >> 8) & 0xFF; // 高字节
+ checksum += frame.data_length & 0xFF; // 低字节
+
+ checksum += (frame.flags >> 8) & 0xFF; // 高字节
+ checksum += frame.flags & 0xFF; // 低字节
+
+
+ for (uint16_t i = 0; i < (frame.data_length - 2); i++) {
+ checksum += frame.data[i];
+ }
+
+ checksum &= 0xFF;
+
+ // printf("checksum : 0x%x\n", checksum);
+ return checksum;
+}
+
+errcode_t bn02_parse_frame(uint8_t *buf, uint16_t event_size)
+{
+ if(buf != NULL && event_size >= (1+2+2+2+1+1))
+ {
+ memset_s(ble_bp_data,0,sizeof(ble_bp_data),0);
+
+ ble_bp_data.start_code = buf[0];
+ ble_bp_data.main_func_code = buf[1];
+ ble_bp_data.sub_func_code = buf[2];
+ ble_bp_data.data_length = (buf[3] << 8) + buf[4];
+ ble_bp_data.flags = (buf[5] << 8) + buf[6];
+ ble_bp_data.data = &buf[7];
+
+ // printf("start_code : 0x%x, main_func_code : 0x%x, sub_func_code : 0x%x, data_length : 0x%x, flags : 0x%x, data : 0x%x\n",
+ // ble_bp_data.start_code,ble_bp_data.main_func_code,ble_bp_data.sub_func_code,ble_bp_data.data_length,ble_bp_data.flags,*ble_bp_data.data);
+
+ if(buf[8] != bn02_calculate_checksum(ble_bp_data))
+ return ERRCODE_FAIL;
+
+ ble_bp_data.sub_func_code += 0x80;
+
+ if(!(*ble_bp_data.data))
+ {
+ do_bp_service_check_msg(BP_SERVICE_CMD_START_CHECK);
+ ble_status = 1;
+ }
+
+ else
+ {
+ do_bp_service_check_msg(BP_SERVICE_CMD_STOP_CHECK);
+ ble_status = 0;
+ }
+
+
+ }
+ else
+ {
+ printf("buf is null or event_size < (1+2+2+2+1+1) \n");
+ return ERRCODE_FAIL;
+ }
+ return ERRCODE_SUCC;
+}
+
+errcode_t bn02_replymsg(uint8_t *input_data,uint16_t input_len,uint8_t flags)
+{
+ errcode_t ret;
+ ble_bp_data.data = input_data;
+ ble_bp_data.data_length = input_len + 2;
+
+ if((ble_bp_data.flags & 0x3FFF) < (1 << 14))
+ ble_bp_data.flags++;
+
+ if(flags)
+ {
+ ble_bp_data.flags |= (1 << 15);
+ }
+
+ ble_bp_data.checksum = bn02_calculate_checksum(ble_bp_data);
+
+ // printf("start_code : 0x%x, main_func_code : 0x%x, sub_func_code : 0x%x, data_length : 0x%x, flags : 0x%x check_sum : 0x%x\n",
+ // ble_bp_data.start_code,ble_bp_data.main_func_code,ble_bp_data.sub_func_code,ble_bp_data.data_length,ble_bp_data.flags,ble_bp_data.checksum);
+
+ // for(int i = 0;i<48;i++)
+ // {
+ // printf("reply:[%d]= 0x%x\n",i,ble_bp_data.data[i]);
+ // }
+
+ ret = ble_factorytest_server_send_input_report((uint8_t *)&ble_bp_data,sizeof(ble_bp_data));
+ // printf("ret : 0x%x \n",ret);
+ return ret;
+}
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-02-14 10:30:32
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-02-14 11:35:06
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/service/bp_ble_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+#ifndef _BP_BLE_SERVICE_H_
+#define _BP_BLE_SERVICE_H_
+
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+
+errcode_t bn02_replymsg(uint8_t *input_data,uint16_t input_len,uint8_t flags);
+errcode_t bn02_parse_frame(uint8_t *buf, uint16_t event_size);
+uint8_t bn02_get_ble_status(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+#include "pinctrl.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+
+#include "tcxo.h"
+
+#include "cmsis_os2.h"
+#include "input_app.h"
+#include "bp_service.h"
+#include "custom_utils.h"
+#include "bn02.h"
+
+// #include "custom_runtime.h"
+/***
+ * 其他cmd在Header里定义,对外开放
+*/
+
+#define BP_CHECK_MS 40
+
+osTimerId_t g_bp_service_timer = NULL;
+
+static bool g_bp_sensor_exist = false;
+
+static bool g_bat_timer_is_running = false;
+
+static unsigned long g_app_queue= 0xFFFFFFFF;
+
+static bool bp_service_running_stat = false;
+
+void do_bp_service_check_msg(int cmd);
+
+static void bp_service_check_timer_callback(void* data)
+{
+ do_bp_service_check_msg(BP_SERVICE_CMD_TIMER_CHECK);
+}
+
+void do_bp_service_check_msg(int cmd)
+{
+ int ret;
+ if (g_bp_sensor_exist == false)
+ return ;
+ common_notify_mail_t mail = {0};
+ mail.comm.app = cmd;
+ ret = osal_msg_queue_write_copy(g_app_queue, (void *)&mail,
+ sizeof(common_notify_mail_t), 0);
+ if (ret != OSAL_SUCCESS) {
+ PRINT("Error bp Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret);
+ }
+
+}
+
+static void bp_service_check_task(void const *arg)
+{
+ unused(arg);
+ int32_t ret;
+ common_notify_mail_t mail;
+ uint32_t msgsize = (uint32_t)sizeof(common_notify_mail_t);
+ while (1) {
+ ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize,
+ OSAL_MSGQ_WAIT_FOREVER);
+ if (ret != OSAL_SUCCESS) {
+ continue;
+ }
+ if (mail.comm.app == BP_SERVICE_CMD_TIMER_CHECK) {
+ // PRINT("bn02_int_handle \n");
+ bn02_int_handle();
+ }else if (mail.comm.app == BP_SERVICE_CMD_START_CHECK){
+ // PRINT("bn02_start \n");
+ bn02_start();
+ // if(g_bp_service_timer)
+ // osTimerStart(g_bp_service_timer,150);
+ }else if (mail.comm.app == BP_SERVICE_CMD_STOP_CHECK){
+ // PRINT("bn02_stop \n");
+ bn02_stop();
+ // if(g_bp_service_timer)
+ // osTimerStop(g_bp_service_timer);
+ }
+ }
+}
+void create_bp_queue(void)
+{
+
+ if (osal_msg_queue_create("bp_service_queue", APP_BOARD_MSG_COUNT, &g_app_queue,
+ 0, sizeof(common_notify_mail_t)) != ERRCODE_SUCC) {
+ PRINT("[bp][service] app create mail fail\n");
+ }
+}
+
+#define BP_BOARD_TASK_SIZE 0x1000
+errcode_t uapi_bp_service_init(void)
+{
+ PRINT("uapi_bp_service_init !\r\n");
+
+ g_bp_sensor_exist = true;
+
+ app_task_definition_t taskcfg={0};
+ taskcfg.create_queue_handle = create_bp_queue;
+ taskcfg.attr.name="bp_service";
+ taskcfg.attr.priority = osPriorityBelowNormal4;
+ taskcfg.attr.stack_size = BP_BOARD_TASK_SIZE;
+ taskcfg.func = bp_service_check_task;
+ taskcfg.use_mem = USE_EXTEND_MEM;
+
+ errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+ if(ret != ERRCODE_SUCC)
+ {
+ PRINT("create bp_service failed %d!\r\n",ret);
+ return ERRCODE_FAIL;
+ }
+
+ // g_bp_service_timer = osTimerNew((osTimerFunc_t)bp_service_check_timer_callback, osTimerPeriodic, NULL, NULL);
+
+ return ERRCODE_SUCC;
+}
+
+void bp_int_callback(pin_t pin, uintptr_t param)
+{
+ // PRINT("bp_int_callback %d 0x%X\n",pin,param);
+ uapi_gpio_clear_interrupt(pin);
+ do_bp_service_check_msg(BP_SERVICE_CMD_TIMER_CHECK);
+}
+
+// void bp_service_service_resume(void)
+// {
+// MMC_LOG("bp_service_service resume!\r\n");
+// bp_service_check_timer_callback(0);
+// }
+// void bp_service_service_suspend(void)
+// {
+// MMC_LOG("bp_service_service suspend!\r\n");
+// }
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-23 15:11:01
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-16 17:39:43
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/charge/HP4570/service/charge_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Test adc header \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-08-16, Create file. \n
+ */
+
+#ifndef BP_SERVICE_H__
+#define BP_SERVICE_H__
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+
+#define BP_SERVICE_CMD_START_CHECK 0x12
+#define BP_SERVICE_CMD_STOP_CHECK 0x13
+#define BP_SERVICE_CMD_TIMER_CHECK 0x11
+
+errcode_t uapi_bp_service_init(void);
+void bp_int_callback(pin_t pin, uintptr_t param);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+#include "pinctrl.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+
+#include "tcxo.h"
+
+#include "cmsis_os2.h"
+#include "input_app.h"
+#include "bp_service.h"
+#include "custom_utils.h"
+#include "bp_tcp_server.h"
+#include "custom_runtime.h"
+// #include "custom_runtime.h"
+/***
+ * 其他cmd在Header里定义,对外开放
+*/
+
+#define APP_KEY "d8d960b748738c2f29c676baa3f5be64"
+#define NAME "W9"
+#define URL_HEADER "https://test.aicaring.com/api/v0"
+
+#define MAX_CNT 16 * 5 * 60
+static unsigned long g_app_queue= 0xFFFFFFFF;
+
+static int *tcp_data = NULL;
+static int tcp_data_cnt = 0;
+
+const char base64_table[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+// {
+// "app_key": "1db74281ece314ba6bbc2b553222cd84",
+// "name": "RH303"
+// "firm": "魔方",
+// "device_code": "DA:19:72:F3:0A:89",
+// "model": "T11",
+// "sensor": {"model": "VC32", "fs": 100},
+// “sinklib_version": "v0.3.0.072522",
+// "request_code":
+// "6+m78fFJkFKu1mzhhL4jKRJTEhJMwvSJFlJhWIgRC8wfyB0HFw8JMURNQ6c3MP/U"
+// }
+
+int base64_encode(char *out, size_t out_len, size_t *out_size, const char *in, size_t in_len)
+{
+ if (out == NULL || out_len == 0 || out_size == NULL || in == NULL || in_len == 0) {
+ return -1;
+ }
+
+ // 计算Base64编码后的最大长度: (in_len + 2) / 3 * 4
+ size_t max_out_len = (in_len + 2) / 3 * 4;
+
+ // 检查输出缓冲区是否足够
+ if (max_out_len + 1 > out_len) { // +1 for null terminator
+ return -2;
+ }
+
+ uint32_t value = 0;
+ size_t i = 0, j = 0;
+ uint8_t bytes_remaining = 0;
+
+ *out_size = 0;
+
+ // 按3字节分组处理
+ while (i < in_len) {
+ // 读取3字节
+ value = 0;
+ bytes_remaining = 0;
+
+ for (int k = 0; k < 3 && i < in_len; k++) {
+ value = (value << 8) | (uint8_t)in[i++];
+ bytes_remaining++;
+ }
+
+ // 编码为4个Base64字符
+ switch (bytes_remaining) {
+ case 3:
+ out[j++] = base64_table[(value >> 18) & 0x3F];
+ out[j++] = base64_table[(value >> 12) & 0x3F];
+ out[j++] = base64_table[(value >> 6) & 0x3F];
+ out[j++] = base64_table[value & 0x3F];
+ break;
+
+ case 2:
+ out[j++] = base64_table[(value >> 10) & 0x3F];
+ out[j++] = base64_table[(value >> 4) & 0x3F];
+ out[j++] = base64_table[(value << 2) & 0x3F];
+ out[j++] = '='; // 填充等号
+ break;
+
+ case 1:
+ out[j++] = base64_table[(value >> 2) & 0x3F];
+ out[j++] = base64_table[(value << 4) & 0x3F];
+ out[j++] = '='; // 填充等号
+ out[j++] = '='; // 填充等号
+ break;
+ }
+ }
+
+ out[j] = '\0'; // 字符串终止符
+ *out_size = j;
+ return 0;
+}
+
+void get_request_code(char *req_code)
+{
+ uint32_t req_code_len = 0;
+ char* fact = "zhihuishixun"; // 获取厂商名字(不超过32个字节的字符串)
+ const unsigned int fact_len = strlen(fact);
+ char* imei = uapi_dev_runtime_get_cat1_imei(); // 获取设备号(12个字节字符串)
+ const unsigned int imei_len = strlen(imei);
+ request_validation((unsigned char*)fact, fact_len, (unsigned char*)imei, imei_len, (unsigned char*)req_code, &req_code_len);
+ printf("req_code:%s\n",req_code);
+}
+
+void get_active_code(void)
+{
+#if 0
+ char * data_ptr = NULL;
+ uint32_t data_len = 0;
+ char * encode_str = NULL;
+ uint32_t encode_len = 0;
+ uint32_t output_len = 0;
+ int temp_len = 0;
+ int json_data_len = 256;
+ char * json_data = NULL;
+
+ json_data = malloc(json_data_len);
+ if(json_data == NULL)
+ goto FAILED;
+ memset(json_data,0,json_data_len);
+
+ temp_len += sprintf(json_data + temp_len, "{\"app_key\":\"%s\",", APP_KEY);
+ temp_len += sprintf(json_data + temp_len, "{\"name\":\"%s\",", NAME);
+ temp_len += sprintf(json_data + temp_len, "\"firm\":\"%s\",", "HENGAI");
+
+ uint8_t btaddr[6] = {0};
+ uint32_t len = 6;
+ uapi_get_nv_btaddr(btaddr, &len);
+ uint8_t btaddr_str[64] = {0};
+ sprintf((char *)btaddr_str, "%02X:%02X:%02X:%02X:%02X:%02X", btaddr[0], btaddr[1], btaddr[2], btaddr[3], btaddr[4], btaddr[5]);
+
+ temp_len += sprintf(json_data + temp_len, "\"device_code\":\"%s\",", btaddr_str);
+ temp_len += sprintf(json_data + temp_len, "\"model\":\"%s\",", "T11");
+ temp_len += sprintf(json_data + temp_len, "\"sensor\":{\"model\":\"VC32\",\"fs\":%d},", 100);
+ temp_len += sprintf(json_data + temp_len, "\"sensor\":{\"model\":\"VC32\",\"fs\":%d},", 100);
+ temp_len += sprintf(json_data + temp_len, "\"sinklib_version\":\"%s\",", "v0.5.3.060325");
+
+
+ char req_code[64] = {0};
+ get_request_code(req_code);
+ temp_len += sprintf(json_data + temp_len, "\"request_code\":\"%s\"}", req_code);
+
+ printf("temp_len:%d\n",temp_len);
+
+ // base64 body
+ encode_len = temp_len * 3 / 2;
+ encode_str = malloc(encode_len);
+
+ if(encode_str == NULL)
+ goto FAILED;
+
+ memset(encode_str,0,encode_len);
+
+ if(0 != base64_encode(encode_str, encode_len, &output_len, json_data, temp_len))
+ goto FAILED;
+
+
+ // content
+ data_len = output_len + 128;
+ data_ptr = malloc(data_len);
+ if(data_ptr == NULL)
+ goto FAILED;
+
+ memset(data_ptr,0,data_len);
+
+ sprintf(data_ptr, "[XT*YYYYYYYYYYYYYYY*%s*TCP_HTTP,POST,%s%s,,%s", URL_HEADER, "/sinklib/activation/feedback", encode_str);
+ data_len = strlen(data_ptr);
+
+ char *send_str = NULL;
+ int send_len = data_len + 64;
+ send_str = malloc(send_len);
+ if(send_str == NULL)
+ goto FAILED;
+
+
+ char len_str[4] = {0};
+ sprintf(len_str, "%04x", data_len+8);
+ sprintf(send_str, "[XT*YYYYYYYYYYYYYYY*%s*TCP_HTTP%s]", len_str, data_ptr);
+ send_len = strlen(send_str);
+
+ mmi_protocol_fzd_action_tcp_http(data_ptr, data_len);
+
+FAILED:
+ if(NULL != send_str)
+ {
+ lv_mem_free(send_str);
+ send_str = NULL;
+ }
+ if(NULL != json_data)
+ {
+ lv_mem_free(json_data);
+ json_data = NULL;
+ }
+ if(NULL != encode_str)
+ {
+ lv_mem_free(encode_str);
+ encode_str = NULL;
+ }
+ if(NULL != data_ptr)
+ {
+ lv_mem_free(data_ptr);
+ data_ptr = NULL;
+ }
+#endif
+}
+
+void bp_tcp_data_clean(void)
+{
+ if(tcp_data != NULL)
+ {
+ free(tcp_data);
+ tcp_data = NULL;
+ tcp_data_cnt = 0;
+ }
+}
+
+void do_bp_tcp_server_send_data(int *data,uint32_t len)
+{
+ if(data == NULL || len == 0)
+ return;
+
+ errcode_t ret;
+ bp_tcp_data_mail_t send_data = {0};
+ send_data.len = len;
+ send_data.data = (int *)malloc(len * sizeof(int));
+ if(send_data.data == NULL)
+ {
+ PRINT("malloc failed\n");
+ return;
+ }
+ memcpy_s(send_data.data,len * sizeof(int),data,len * sizeof(int));
+ uint32_t send_len = sizeof(send_data);
+
+ ret = osal_msg_queue_write_copy(g_app_queue, (void *)&send_data,
+ send_len, 0);
+ if (ret != OSAL_SUCCESS) {
+ PRINT("Error bp Check MSG 0x send failed! err=0x%x! \r\n", ret);
+ }
+
+ free(send_data.data);
+}
+
+// 数据开头标识:[
+// bid(需要登录后台申请)
+// 设备号0
+// 协议模块分割符:*
+// 消息内容(开头是命令,后面有内容用消息分割符逗号分割,没有则不需要逗号)
+// 消息长度(十六进制,4个字节,最大支持FFFF)
+// 消息分割符:,
+// 数据结尾标识:]
+
+
+
+void tcp_data_parse(char *rx_buffer, int len)
+{
+ if (len == 0 || rx_buffer == NULL || strlen(rx_buffer) != len)
+ {
+ printf("len = 0 or rx_buffer == NULL, format error !\n");
+ return;
+ }
+
+ // printf("rx_buffer %s\n", rx_buffer);
+ // printf("rx_buffer %d\n", strlen(rx_buffer));
+ // printf("format error ! header:%c len:%d\n", rx_buffer[0], len);
+ // printf("format error ! tail:%c \n", rx_buffer[len-1]);
+
+ if (!(rx_buffer[0] == '[' && rx_buffer[len-1] == ']'))
+ {
+ printf("format error ! header:%c,tail:%c\n",
+ (unsigned char)rx_buffer[0],
+ (unsigned char)rx_buffer[len-1]);
+ return;
+ }
+
+ // 解析BID
+ char *bid_start = &rx_buffer[1];
+ char *bid_end = strchr(bid_start, '*');
+ if (bid_end == NULL)
+ {
+ printf("Missing module delimiter\n");
+ return;
+ }
+
+ int bid_len = bid_end - bid_start;
+ char bid[20] = {0};
+ strncpy(bid, bid_start, bid_len);
+ bid[bid_len] = '\0';
+
+ // 解析设备号
+ char *device_start = bid_end + 1;
+ char *device_end = strchr(device_start, '*');
+ if (device_end == NULL) {
+ printf("Missing module delimiter *\n");
+ return;
+ }
+ int device_len = device_end - device_start;
+ char device_id[64] = {0};
+ strncpy(device_id, device_start, device_len);
+ device_id[device_len] = '\0';
+
+ // 解析长度字段 (4个十六进制字符 = 2字节)
+ char *len_start = device_end + 1;
+ char *len_end = strchr(len_start, '*');
+ if (len_end == NULL) {
+ printf("Missing module delimiter *\n");
+ return;
+ }
+
+ // 验证长度格式
+ int len_len = len_end - len_start;
+ if (len_len != 4) { // 4个十六进制字符
+ printf("Invalid length format (expected 4 characters, got %d)\n", len_len);
+ return;
+ }
+
+ // 转换长度字符串为整数
+ uint16_t total_length; // 使用16位整数存储2字节长度
+ sscanf(len_start, "%4hx", &total_length); // 注意这里用%4hx,匹配4个十六进制字符
+
+ // 解析命令和内容
+ char *cmd_start = len_end + 1;
+ char *content_start = strchr(cmd_start, ',');
+
+ if (content_start != NULL)
+ {
+ // 有内容的情况: [BID*DEVICE*LEN*COMMAND,CONTENT]
+ int cmd_len = content_start - cmd_start;
+ char command[64] = {0};
+ strncpy(command, cmd_start, cmd_len);
+ command[cmd_len] = '\0';
+
+ // 解析内容 (不包括逗号)
+ int content_len = &rx_buffer[len-1] - content_start - 1; // 不包含逗号
+ char content[128] = {0};
+ strncpy(content, content_start + 1, content_len); // 从逗号后一位开始复制
+ content[content_len] = '\0';
+
+ // 验证总长度 (从命令开始到消息结束的长度)
+ int actual_total_length = cmd_len + content_len + 1; // +1 是因为内容的逗号也计入总长度
+ if (actual_total_length != total_length) {
+ printf("Length mismatch: declared %u, actual %d\n",
+ total_length, actual_total_length);
+ return;
+ }
+
+ // 移除内容中的所有逗号
+ char filtered_content[128] = {0};
+ int j = 0;
+ for (int i = 0; content[i] != '\0'; i++) {
+ if (content[i] != ',') {
+ filtered_content[j++] = content[i];
+ }
+ }
+
+ // 打印解析结果
+ printf("Parsed successfully:\n");
+ printf("BID: %s\n", bid);
+ printf("Device ID: %s\n", device_id);
+ printf("Command: %s\n", command);
+ printf("Content: %s\n", filtered_content); // 打印不包含逗号的内容
+
+ if (strcmp(command, "blood") == 0) {
+ printf("blood start\n");
+#ifdef ENABLE_BN02
+ do_bp_service_check_msg(BP_SERVICE_CMD_START_CHECK);
+#endif
+ }
+ }
+ else
+ {
+ // 无内容的情况: [BID*DEVICE*LEN*COMMAND]
+ int cmd_len = &rx_buffer[len-1] - cmd_start;
+ char command[64] = {0};
+ strncpy(command, cmd_start, cmd_len);
+ command[cmd_len] = '\0';
+
+ // 验证命令长度 (无内容时,长度字段表示命令长度)
+ if (cmd_len != total_length) {
+ printf("Command length mismatch: declared %u, actual %d\n",
+ total_length, cmd_len);
+ return;
+ }
+
+ // 打印解析结果
+ printf("Parsed successfully:\n");
+ printf("BID: %s\n", bid);
+ printf("Device ID: %s\n", device_id);
+ printf("Command: %s\n", command);
+ printf("No content\n");
+
+
+ if (strcmp(command, "blood") == 0) {
+ printf("blood start\n");
+#ifdef ENABLE_BN02
+ do_bp_service_check_msg(BP_SERVICE_CMD_START_CHECK);
+#endif
+ }
+ }
+}
+
+static void bp_tcp_server_recv_task(void const *arg)
+{
+ // char rx_buffer[512];
+ // char tx_buffer[256];
+
+ // socklen_t addrLen = sizeof(filesourceAddr);
+ while (1) {
+
+ // // printf("recv ENTER\r\n");
+
+ // memset(rx_buffer, 0, sizeof(rx_buffer));
+ // int len = recvfrom(g_listen_sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&filesourceAddr, &addrLen);
+ // // Error occured during receiving
+ // printf("file recv len:%d rx_buffer:%s\r\n",len,rx_buffer);
+ // if (len < 0) {
+ // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"len < 0 , recv failed: errno %d\n", errno);
+ // // break;
+ // continue;
+ // } else if (len == 0) {
+ // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"len == 0\n");
+ // // break;
+ // continue;
+ // }
+ // // Data received
+ // rx_buffer[len] = '\0'; // Null-terminate whatever we received and treat like a string
+ // // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Received %d bytes, rx_buffer: %s\n", len, rx_buffer);
+ // tcp_data_parse(rx_buffer, len);
+
+ }
+}
+
+static void tcp_data_handler(int *data,int len)
+{
+ if(tcp_data == NULL)
+ {
+ tcp_data = (int *)malloc(MAX_CNT * sizeof(int));
+ if(tcp_data == NULL)
+ {
+ PRINT("malloc failed\n");
+ return;
+ }
+ }
+ // printf("len:%d\n",len);
+ memcpy_s(tcp_data + tcp_data_cnt,len * sizeof(int),data,len * sizeof(int));
+
+ // for(int i = tcp_data_cnt; i < tcp_data_cnt+len; i ++)
+ // {
+ // printf("222data[%d]:%d\n",i,tcp_data[i]);
+ // }
+
+ tcp_data_cnt += len;
+
+
+
+ if(tcp_data_cnt >= MAX_CNT)
+ {
+ // for(int i = 0; i < tcp_data_cnt; i ++)
+ // {
+ // printf("data[%d]:%d\n",i,tcp_data[i]);
+ // }
+ tcp_data_cnt = 0;
+ memset((void*)tcp_data,0,MAX_CNT * sizeof(int));
+ }
+}
+
+static void bp_tcp_server_send_task(void const *arg)
+{
+ unused(arg);
+ errcode_t ret;
+
+ bp_tcp_data_mail_t mail = {0};
+ uint32_t msgsize = sizeof(bp_tcp_data_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;
+ }
+
+ tcp_data_handler((int *)mail.data,mail.len);
+ // for(int i = 0; i < mail.len; i ++)
+ // {
+ // printf("222data[%d]:%d\n",i,mail.data[i]);
+ // }
+
+ }
+}
+
+void create_bp_tcp_queue(void)
+{
+
+ if (osal_msg_queue_create("bp_tcp_service_queue", APP_BOARD_MSG_COUNT, &g_app_queue,
+ 0, sizeof(bp_tcp_data_mail_t)) != ERRCODE_SUCC) {
+ PRINT("[bp][service] app create mail fail\n");
+ }
+}
+
+#define BP_BOARD_TASK_SIZE 0x1000
+errcode_t uapi_bp_tcp_server_init(void)
+{
+ PRINT("uapi_bp_tcp_server_init !\r\n");
+
+ app_task_definition_t taskcfg={0};
+ taskcfg.create_queue_handle = create_bp_tcp_queue;
+ taskcfg.attr.name="bp_tcp_server_send_task";
+ taskcfg.attr.priority = osPriorityBelowNormal4;
+ taskcfg.attr.stack_size = BP_BOARD_TASK_SIZE;
+ taskcfg.func = bp_tcp_server_send_task;
+ taskcfg.use_mem = USE_EXTEND_MEM;
+
+ errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+ if(ret != ERRCODE_SUCC)
+ {
+ PRINT("create bp_service failed %d!\r\n",ret);
+ return ERRCODE_FAIL;
+ }
+
+ // g_bp_service_timer = osTimerNew((osTimerFunc_t)bp_service_check_timer_callback, osTimerPeriodic, NULL, NULL);
+
+ return ERRCODE_SUCC;
+}
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-02-14 10:30:32
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-06-12 17:17:47
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/bp/service/bp_ble_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+#ifndef _BP_TCP_SERVER_H_
+#define _BP_TCP_SERVER_H_
+
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+
+typedef struct {
+ int *data;
+ uint32_t len;
+} bp_tcp_data_mail_t;
+
+
+void do_bp_tcp_server_send_data(int *data,uint32_t len);
+void tcp_data_parse(char *rx_buffer, int len);
+void bp_tcp_data_clean(void);
+void test_algorithm(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
//协议接收client下发的数据接口
void cywee_recv_cmd_data(uint8_t *buf, uint16_t event_size,uint16_t handle)
{
- if(buf != NULL)
- printf("cywee_recv_cmd_data len %d , handle 0x%X ,*buf 0x%02X\r\n",event_size,handle,*buf);
+ if(buf == NULL)
+ return;
+ // printf("cywee_recv_cmd_data len %d , handle 0x%X ,*buf 0x%02X\r\n",event_size,handle,*buf);
/****此处为接收指令,处理后反馈结果的参考**/
- // cywee_log_switch(*buf);
+ cywee_log_switch(*buf);
/*****参考结束****/
}
#include "battery_hal.h"
#include "sleep/include/SleepModelC.h"
#include "custom_save_runtime.h"
+#ifdef SUPPORT_GNSS
+#include "gnss_ctl.h"
+#include "NMEA0183.h"
+#endif
#define AP_ENABLE_DML_SDO_LISTEN
uapi_create_folder(dir_path);
}
+void cywee_gnss_update(void)
+{
+#ifdef SUPPORT_GNSS
+ gps_data_t *gps_data = getGPSGlobaldata();
+ if(gps_data == NULL)
+ {
+ CWM_OS_dbgPrintf("gps_data == NULL \n");
+ return;
+ }
+
+ if(gps_data->status < 1)
+ {
+ CWM_OS_dbgPrintf("gps_data->status < 1 \n");
+ return;
+ }
+
+ memset(&csd, 0, sizeof(CUSTOM_GNSS));
+ csd.sensorType = CUSTOM_GNSS;
+ csd.dData[0] = gps_data->location.lat;//latitude (degrees) (range: -90~90); //纬度
+ csd.dData[1] = gps_data->location.lng;//longitude (degrees) (range: -180~180) //经度
+ csd.dData[2] = gps_data->location.alt;//altitude (meters) //海拔
+ csd.dData[3] = gps_data->ground_course;//bearing (heading in degrees) //方位角
+ csd.dData[4] = gps_data->ground_speed;//speed (m/s) //速度
+ csd.dData[5] = gps_data->hdop;//Horizontal_Accuracy (meters) //水平精度
+ csd.dData[6] = gps_data->vdop;//Vertical_Accuracy (meters) //垂直精度
+ csd.dData[7] = 0; //水平精度衰减因子
+ csd.dData[8] = 0; //垂直精度衰减因子
+ CWM_CustomSensorInput(&csd);
+
+ CWM_OS_dbgPrintf("gps_data->location.lat:%f\n",gps_data->location.lat);
+ CWM_OS_dbgPrintf("gps_data->location.lng:%f\n",gps_data->location.lng);
+ CWM_OS_dbgPrintf("gps_data->location.alt:%f\n",gps_data->location.alt);
+ CWM_OS_dbgPrintf("gps_data->ground_course:%f\n",gps_data->ground_course);
+ CWM_OS_dbgPrintf("gps_data->ground_speed:%f\n",gps_data->ground_speed);
+ CWM_OS_dbgPrintf("gps_data->hdop:%f\n",gps_data->hdop);
+ CWM_OS_dbgPrintf("gps_data->vdop:%f\n",gps_data->vdop);
+
+#endif
+}
+
void cywee_hrs_update(int hrs_data)
{
// hrs = hrs_data;
hrs_mode_state = 0;
uapi_save_runtime_log(RUNTIME_LOG_OXYGEN_SPORT_MEASURE_END);
}
+ }
+ if((int)sensorEVT->fData[1] == CUSTOM_GNSS)
+ {
+ CWM_OS_dbgPrintf("CUSTOM_GNSS !!! \r\n");
+#ifdef SUPPORT_GNSS
+ if((int)sensorEVT->fData[2] == 1)
+ {
+
+ gnss_start();
+ }
+ else
+ {
+ gnss_stop();
+ }
+#endif
}
break;
case IDX_ALGO_SHAKE:
*/\r
#define TIOT_PIN_NONE 0xFFFFFFFFU\r
\r
-#ifdef BOARD_U8\r
-#define TIOT_UART_PORT UART_BUS_0\r
-#define TIOT_PIN_WAKEUP_HOST_NUM S_AGPIO_L31 /* 用于唤醒HOST. */\r
-#define TIOT_PIN_WAKEUP_GNSS_NUM TIOT_PIN_NONE /* 用于 唤醒GNSS. */\r
-#define TIOT_PIN_POWER S_AGPIO_L30 /* 用于开启GNSS. */\r
-\r
-#define TIOT_PIN_UART_TX S_MGPIO19\r
-#define TIOT_PIN_UART_RX S_MGPIO20\r
-#define TIOT_PIN_UART_CTS S_MGPIO22\r
-#define TIOT_PIN_UART_RTS S_MGPIO21\r
-#define TIOT_PINMUX HAL_PIO_FUNC_UART1\r
-\r
-#elif defined(BOARD_L22) || defined(BOARD_W9)\r
+#if defined(BOARD_W9) || defined(BOARD_N9)\r
#define TIOT_UART_PORT UART_BUS_1\r
#define TIOT_PIN_WAKEUP_HOST_NUM S_AGPIO_L15 /* 用于唤醒HOST. */\r
#define TIOT_PIN_WAKEUP_GNSS_NUM S_HGPIO0 /* 用于 唤醒GNSS. */\r
#include "tiot_service_interface.h"\r
#include "pm_definition.h"\r
#include "gnss_ctl.h"\r
+#include "cywee_hal.h"\r
\r
#define COLDSTART_FIXMODEGPS_NMEAALL_SAMPLE 0\r
#define AUTOSTART_FIXMODEALL_NMEADEF_SAMPLE 1\r
// 配置启动模式:冷启动模式。\r
int32_t ret = tiot_service_write(handle, cfgColdStartCmd, sizeof(cfgColdStartCmd));\r
if (ret < 0) {\r
- printf("\nerror: cfgColdStartCmd error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: cfgColdStartCmd error: %d\n", ret);\r
return 0;\r
}\r
\r
// 配置使能的GNSS星座:GPS。\r
ret = tiot_service_write(handle, cfgFixModeAllCmd, sizeof(cfgFixModeAllCmd));\r
if (ret < 0) {\r
- printf("\nerror: cfgFixModeAllCmd error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: cfgFixModeAllCmd error: %d\n", ret);\r
return 0;\r
}\r
\r
// 配置上报NMEA类型:PNT/ZDA/VTG/RMC/GSV/GSA/GLL/GGA。\r
ret = tiot_service_write(handle, cfgNmeaAllCmd, sizeof(cfgNmeaAllCmd));\r
if (ret < 0) {\r
- printf("\nerror: cfgNmeaAllCmd error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: cfgNmeaAllCmd error: %d\n", ret);\r
return 0;\r
}\r
\r
ret = tiot_service_write(handle, CFG_TRK_LPW_DISABLE, sizeof(CFG_TRK_LPW_DISABLE));\r
if (ret < 0) {\r
- printf("\nerror: CFG_TRK_LPW_DISABLE error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: CFG_TRK_LPW_DISABLE error: %d\n", ret);\r
return 0;\r
}\r
\r
ret = tiot_service_write(handle, CFG_ACQ_LPW_DISABLE, sizeof(CFG_ACQ_LPW_DISABLE));\r
if (ret < 0) {\r
- printf("\nerror: CFG_ACQ_LPW_DISABLE error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: CFG_ACQ_LPW_DISABLE error: %d\n", ret);\r
return 0;\r
}\r
\r
ret = tiot_service_write(handle, CFG_ANTIJAM_ENABLE, sizeof(CFG_ANTIJAM_ENABLE));\r
if (ret < 0) {\r
- printf("\nerror: CFG_ANTIJAM_ENABLE error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: CFG_ANTIJAM_ENABLE error: %d\n", ret);\r
return 0;\r
}\r
return 1;\r
// 配置启动模式:自动模式。\r
int32_t ret = tiot_service_write(handle, cfgAutoStartCmd, sizeof(cfgAutoStartCmd));\r
if (ret < 0) {\r
- printf("\nerror: cfgAutoStartCmd error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: cfgAutoStartCmd error: %d\n", ret);\r
return 0;\r
}\r
\r
// 配置使能的GNSS星座:QZSS/GAL/BDS/GLO/GPS。\r
ret = tiot_service_write(handle, cfgFixModeAllCmd, sizeof(cfgFixModeAllCmd));\r
if (ret < 0) {\r
- printf("\nerror: cfgFixModeAllCmd error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: cfgFixModeAllCmd error: %d\n", ret);\r
return 0;\r
}\r
\r
// 配置上报NMEA类型:RMC/GGA。\r
ret = tiot_service_write(handle, cfgNmeaDefaultCmd, sizeof(cfgNmeaDefaultCmd));\r
if (ret < 0) {\r
- printf("\nerror: cfgNmeaDefaultCmd error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: cfgNmeaDefaultCmd error: %d\n", ret);\r
return 0;\r
}\r
\r
ret = tiot_service_write(handle, CFG_TRK_LPW_DISABLE, sizeof(CFG_TRK_LPW_DISABLE));\r
if (ret < 0) {\r
- printf("\nerror: CFG_TRK_LPW_DISABLE error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: CFG_TRK_LPW_DISABLE error: %d\n", ret);\r
return 0;\r
}\r
\r
ret = tiot_service_write(handle, CFG_ACQ_LPW_DISABLE, sizeof(CFG_ACQ_LPW_DISABLE));\r
if (ret < 0) {\r
- printf("\nerror: CFG_ACQ_LPW_DISABLE error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: CFG_ACQ_LPW_DISABLE error: %d\n", ret);\r
return 0;\r
}\r
return 1;\r
// 查询版本号\r
int32_t ret = tiot_service_write(handle, qryVersion, sizeof(qryVersion));\r
if (ret < 0) {\r
- printf("\nerror: QryVersion error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: QryVersion error: %d\n", ret);\r
return 0;\r
}\r
return 1;\r
// 启动GNSS\r
int32_t ret = tiot_service_write(handle, startCmd, sizeof(startCmd));\r
if (ret < 0) {\r
- printf("\nerror: start gnss error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: start gnss error: %d\n", ret);\r
return 0;\r
}\r
- printf("\nstart gnss\n");\r
+ CWM_OS_dbgPrintf("\nstart gnss\n");\r
return 1;\r
}\r
\r
// 停止GNSS\r
int32_t ret = tiot_service_write(handle, stopCmd, sizeof(stopCmd));\r
if (ret < 0) {\r
- printf("\nerror: stop gnss error: %d\n", ret);\r
+ CWM_OS_dbgPrintf("\nerror: stop gnss error: %d\n", ret);\r
return 0;\r
}\r
- printf("\nstop gnss\n");\r
+ CWM_OS_dbgPrintf("\nstop gnss\n");\r
return 1;\r
}\r
\r
for (;;) { // 写日志条件\r
\r
if (i >= LISTEN_DATA_MAX_LINES) {\r
- printf("\ncnt enough\n");\r
+ CWM_OS_dbgPrintf("\ncnt enough\n");\r
break;\r
}\r
if (g_gnss_stopflag == 1)\r
if (type[0] == MSG_TYPE_ASCII) {\r
g_gnssServiceBuff[ret] = '\0';\r
char* pbuf=(char *)&g_gnssServiceBuff[MSG_CONTENT_IDX];\r
- printf("%s\n", pbuf);\r
+ CWM_OS_dbgPrintf("%s\n", pbuf);\r
if (g_is_gnss_logon)\r
fprintf(g_gnssLogFp, "%s\n", pbuf);\r
for (int index=0;index < ret ;index++)\r
if (decode_nmea(pbuf[index])==1)\r
{\r
// dump_location_data(&g_global_gpsData);\r
- printf("decode_nmea done\r\n");\r
+ CWM_OS_dbgPrintf("decode_nmea done\r\n");\r
}\r
}\r
}\r
\r
void GnssServerStart(void)\r
{\r
- printf("\nenter gnss samples\n");\r
+ CWM_OS_dbgPrintf("\nenter gnss samples\n");\r
if(g_is_gnss_poweron == 1)\r
{\r
- printf("gnss already on\r\n");\r
+ CWM_OS_dbgPrintf("gnss already on\r\n");\r
return ;\r
}\r
uapi_pm_add_sleep_veto(PM_ID_SYS);\r
// Step1: init\r
int32_t ret = tiot_service_init();\r
if (ret != 0) {\r
- printf("\ntiot service init fail\n");\r
+ CWM_OS_dbgPrintf("\ntiot service init fail\n");\r
g_is_gnss_poweron = 0;\r
g_gnss_stopflag = 1;\r
}\r
{\r
g_gnssLogFp = fopen("/user/log/gnss.log", "w");\r
if (g_gnssLogFp == NULL) {\r
- printf("\nerror: open log file error\n");\r
+ CWM_OS_dbgPrintf("\nerror: open log file error\n");\r
return;\r
}\r
}\r
- printf("\nbefore open tiot service\n");\r
+ CWM_OS_dbgPrintf("\nbefore open tiot service\n");\r
\r
// Step2: power on gnss\r
tiot_handle handle = tiot_service_open("gn71", NULL);\r
if (handle == 0) {\r
- printf("\nopen tiot service fail\n");\r
+ CWM_OS_dbgPrintf("\nopen tiot service fail\n");\r
g_is_gnss_poweron = 0;\r
g_gnss_stopflag = 1;\r
return;\r
}\r
- printf("\nopen tiot service success\n");\r
+ CWM_OS_dbgPrintf("\nopen tiot service success\n");\r
\r
int32_t cfgRet;\r
// ---- loop ----------\r
if (cfgRet == 0) {\r
continue;\r
}\r
- printf("\ncfg sample id:%u\n", g_gnssSamplesCfg[i].sampleId);\r
+ CWM_OS_dbgPrintf("\ncfg sample id:%u\n", g_gnssSamplesCfg[i].sampleId);\r
QryVersion(handle);\r
\r
// Step4: start gnss\r
#endif\r
uapi_pm_remove_sleep_veto(PM_ID_SYS);\r
g_is_gnss_poweron=0;\r
- printf("\nfinish gnss samples\n");\r
+ CWM_OS_dbgPrintf("\nfinish gnss samples\n");\r
}
\ No newline at end of file
#include "gpio.h"
#include "uart_gnss.h"
#include "gnss_sample.h"
+#include "cywee_hal.h"
errcode_t gnss_power_on(void)
{
- errcode_t ret=0;
-#if defined(BOARD_U8)
-/*
-S_AGPIO_L23 GPS_BAT_ON
-S_AGPIO_L30 GPS_PWRON
-S_AGPIO_L28 GPS_1V8
-*/
- ret=uapi_gpio_set_dir(S_AGPIO_L23,GPIO_DIRECTION_OUTPUT);
- if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L23,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
- ret=uapi_gpio_set_dir(S_AGPIO_L30,GPIO_DIRECTION_OUTPUT);
- if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L30,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
- ret=uapi_gpio_set_dir(S_AGPIO_L28,GPIO_DIRECTION_OUTPUT);
- if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L28,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
-
- ret=uapi_gpio_set_val(S_AGPIO_L28 , GPIO_LEVEL_HIGH); // gps V3.3 sw en
- PRINT("GPS_1V8 set_value S_AGPIO_L28 GPIO_LEVEL_HIGH ret %d\n",ret);
-
- ret=uapi_gpio_set_val(S_AGPIO_L23, GPIO_LEVEL_HIGH); // crystal sw
- PRINT("GPS_BAT_ON set_value S_AGPIO_L23 GPIO_LEVEL_HIGH ret %d\n",ret);
-
- ret=uapi_gpio_set_val(S_AGPIO_L30, GPIO_LEVEL_LOW); //gps reset
- PRINT("GPS_PWREN set_value S_AGPIO_L30 GPIO_LEVEL_LOW ret %d\n",ret);
- osDelay(1000);
- ret=uapi_gpio_set_val(S_AGPIO_L30, GPIO_LEVEL_HIGH); //gps reset
- PRINT("GPS_PWREN set_value S_AGPIO_L30 GPIO_LEVEL_HIGH ret %d\n",ret);
-
-
-#elif defined (BOARD_L22) || defined (BOARD_W9)
+ errcode_t ret=0;
+#if defined (BOARD_W9) || defined(BOARD_N9)
ret=uapi_gpio_set_dir(S_AGPIO_L16,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L16,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L16,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_AGPIO_L32,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L32,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L32,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_AGPIO_L20,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L20,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L20,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_AGPIO_R9,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_R9,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_R9,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_HGPIO0,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_HGPIO0,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_HGPIO0,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_val(S_HGPIO0, GPIO_LEVEL_HIGH); // crystal sw
- PRINT("GPS_CRYSTAL set_value S_HGPIO0 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_CRYSTAL set_value S_HGPIO0 GPIO_LEVEL_HIGH ret %d\n",ret);
ret=uapi_gpio_set_val(S_AGPIO_L20, GPIO_LEVEL_HIGH); // gps V1.8 sw en
- PRINT("GPS_1V8 set_value S_AGPIO_L20 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_1V8 set_value S_AGPIO_L20 GPIO_LEVEL_HIGH ret %d\n",ret);
ret=uapi_gpio_set_val(S_AGPIO_R9, GPIO_LEVEL_HIGH); // gps V3.3 sw en
- PRINT("GPS_BAT_ON set_value S_AGPIO_R9 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_BAT_ON set_value S_AGPIO_R9 GPIO_LEVEL_HIGH ret %d\n",ret);
ret=uapi_gpio_set_val(S_AGPIO_L32, GPIO_LEVEL_LOW); //gps reset
- PRINT("GPS_PWREN set_value S_AGPIO_L32 GPIO_LEVEL_LOW ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_PWREN set_value S_AGPIO_L32 GPIO_LEVEL_LOW ret %d\n",ret);
osDelay(1000);
ret=uapi_gpio_set_val(S_AGPIO_L32, GPIO_LEVEL_HIGH); //gps reset
- PRINT("GPS_PWREN set_value S_AGPIO_L32 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_PWREN set_value S_AGPIO_L32 GPIO_LEVEL_HIGH ret %d\n",ret);
// ret=uapi_gpio_set_val(S_AGPIO_L16, GPIO_LEVEL_HIGH); // crystal sw
- // PRINT("SWITCH uart to GPS set_value S_AGPIO_L16 GPIO_LEVEL_HIGH ret %d\n",ret);
+ // CWM_OS_dbgPrintf("SWITCH uart to GPS set_value S_AGPIO_L16 GPIO_LEVEL_HIGH ret %d\n",ret);
#endif
errcode_t gnss_power_off(void)
{
- errcode_t ret=0;
-#if defined(BOARD_U8)
-/*
-S_AGPIO_L23 GPS_BAT_ON
-S_AGPIO_L30 GPS_PWRON
-S_AGPIO_L28 GPS_1V8
-*/
- ret=uapi_gpio_set_dir(S_AGPIO_L23,GPIO_DIRECTION_OUTPUT);
- if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L23,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
- ret=uapi_gpio_set_dir(S_AGPIO_L30,GPIO_DIRECTION_OUTPUT);
- if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L30,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
- ret=uapi_gpio_set_dir(S_AGPIO_L28,GPIO_DIRECTION_OUTPUT);
- if (ret != ERRCODE_SUCC) PRINT("set_dir S_AGPIO_L28,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
-
- ret=uapi_gpio_set_val(S_AGPIO_L23, GPIO_LEVEL_HIGH); // crystal sw
- PRINT("GPS_BAT_ON set_value S_AGPIO_L23 GPIO_LEVEL_HIGH ret %d\n",ret);
-
- ret=uapi_gpio_set_val(S_AGPIO_L28 , GPIO_LEVEL_HIGH); // gps V3.3 sw en
- PRINT("GPS_1V8 set_value S_AGPIO_L28 GPIO_LEVEL_HIGH ret %d\n",ret);
-
- ret=uapi_gpio_set_val(S_AGPIO_L30, GPIO_LEVEL_LOW); //gps reset
- PRINT("GPS_PWRON set_value S_AGPIO_L30 GPIO_LEVEL_LOW ret %d\n",ret);
+ errcode_t ret=0;
-
-#elif defined (BOARD_L22) || defined (BOARD_W9)
+#if defined (BOARD_W9) || defined(BOARD_N9)
ret=uapi_gpio_set_dir(S_AGPIO_L16,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L16,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L16,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_AGPIO_L32,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L32,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L32,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_AGPIO_L20,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L20,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L20,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_AGPIO_R9,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_R9,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_R9,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_dir(S_HGPIO0,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_HGPIO0,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_HGPIO0,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
ret=uapi_gpio_set_val(S_HGPIO0, GPIO_LEVEL_HIGH); // crystal sw
- PRINT("GPS_CRYSTAL set_value S_HGPIO0 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_CRYSTAL set_value S_HGPIO0 GPIO_LEVEL_HIGH ret %d\n",ret);
ret=uapi_gpio_set_val(S_AGPIO_L20, GPIO_LEVEL_HIGH); // gps V1.8 sw en
- PRINT("GPS_1V8 set_value S_AGPIO_L20 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_1V8 set_value S_AGPIO_L20 GPIO_LEVEL_HIGH ret %d\n",ret);
ret=uapi_gpio_set_val(S_AGPIO_R9, GPIO_LEVEL_HIGH); // gps V3.3 sw en
- PRINT("GPS_BAT_ON set_value S_AGPIO_R9 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_BAT_ON set_value S_AGPIO_R9 GPIO_LEVEL_HIGH ret %d\n",ret);
ret=uapi_gpio_set_val(S_AGPIO_L32, GPIO_LEVEL_LOW); //gps reset
- PRINT("GPS_PWRON set_value S_AGPIO_L32 GPIO_LEVEL_LOW ret %d\n",ret);
+ CWM_OS_dbgPrintf("GPS_PWRON set_value S_AGPIO_L32 GPIO_LEVEL_LOW ret %d\n",ret);
// ret=uapi_gpio_set_val(S_AGPIO_L16, GPIO_LEVEL_LOW); // crystal sw
- // PRINT("SWITCH uart to download set_value S_AGPIO_L16 GPIO_LEVEL_LOW ret %d\n",ret);
+ // CWM_OS_dbgPrintf("SWITCH uart to download set_value S_AGPIO_L16 GPIO_LEVEL_LOW ret %d\n",ret);
#endif
return ERRCODE_SUCC;
{
errcode_t ret=ERRCODE_SUCC;
ret=uapi_gpio_set_dir(S_AGPIO_L16,GPIO_DIRECTION_OUTPUT);
- PRINT("set_dir S_AGPIO_L16,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
+ CWM_OS_dbgPrintf("set_dir S_AGPIO_L16,GPIO_DIRECTION_OUTPUT ret %d\n",ret);
if (download_gps_switch == SWITCH_TO_GNSS)
{
ret=uapi_gpio_set_val(S_AGPIO_L16, GPIO_LEVEL_HIGH); // crystal sw
- PRINT("SWITCH uart to GNSS set_value S_AGPIO_L16 GPIO_LEVEL_HIGH ret %d\n",ret);
+ CWM_OS_dbgPrintf("SWITCH uart to GNSS set_value S_AGPIO_L16 GPIO_LEVEL_HIGH ret %d\n",ret);
}else{
ret=uapi_gpio_set_val(S_AGPIO_L16, GPIO_LEVEL_LOW); // crystal sw
- PRINT("SWITCH uart to download set_value S_AGPIO_L16 GPIO_LEVEL_LOW ret %d\n",ret);
+ CWM_OS_dbgPrintf("SWITCH uart to download set_value S_AGPIO_L16 GPIO_LEVEL_LOW ret %d\n",ret);
}
return ret;
}
\ No newline at end of file
}
#define GNSS_CMD_TASK_MSG_COUNT 128
-#define GNSS_CMD_TASK_SIZE (0x1000)
+#define GNSS_CMD_TASK_SIZE (0x800*2)
#define GNSS_CMD_TASK_PRIO 4
void create_gnss_uart_queue(void)
{
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "gyro")
+
+set(SOURCES ${SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/sh5001/sh5001.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/gyro_at_cmd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/gyro_service.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/service/gyro_hal.c
+)
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/sh5001
+ ${CMAKE_CURRENT_SOURCE_DIR}/service
+)
+set(PUBLIC_DEFINES
+ SUPPORT_AT_GYRO
+ ENABLE_GYRO
+)
+
+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()
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-16 20:49:09
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-12 17:47:30
+ * @FilePath: /sdk615/code/sdk/drivers/peripheral/GYRO/service/lqbp_at_cmd.c
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "gyro_service.h"
+#include "gyro_hal.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define GYRO_MAX_ARGC 8
+#define GYRO_MAX_ARGV_LEN 64
+
+#define GYRO_SUCCESS 0
+#define GYRO_FAILED (-1)
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[GYRO_MAX_ARGC][GYRO_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 >= GYRO_MAX_ARGC) {
+ return GYRO_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= GYRO_MAX_ARGV_LEN) {
+ return GYRO_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return GYRO_SUCCESS;
+}
+
+static uint32_t gyro_start_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ UNUSED(paraLen);
+ UNUSED(para);
+ gyro_start();
+ return ERRCODE_SUCC;
+}
+static uint32_t gyro_stop_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ UNUSED(paraLen);
+ UNUSED(para);
+ gyro_stop();
+ return ERRCODE_SUCC;
+}
+static const at_cmd_table_t g_gyro_cmd[] = {
+ { (char *)"AT^GYROTESTSTART", gyro_start_test, (char *)"1" },
+ { (char *)"AT^GYROTESTSTOP", gyro_stop_test, (char *)"1" },
+};
+
+at_cmd_table_t *get_gyro_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_gyro_cmd);
+ return (at_cmd_table_t *)g_gyro_cmd;
+}
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-16 20:49:19
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-01-04 16:47:46
+ * @FilePath: /sdk615/code/sdk/drivers/peripheral/GYRO002TA/service/gyro_at_cmd.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef GYRO_AT_PROCESS_H
+#define GYRO_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_gyro_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-05-12 09:59:09
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-12 17:45:29
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/gyro/service/gyro_hal.c
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AEin
+ */
+#include <stdio.h>
+#include <stdbool.h>
+#include "gyro_hal.h"
+
+#ifdef GYRO_SH5001
+#include "sh5001.h"
+#endif
+
+void gyro_power_on(void)
+{
+#ifdef GYRO_SH5001
+ if(SH5001_init() == SH5001_TRUE)
+ printf("sh5001 init successful \n");
+ else
+ printf("sh5001 init failed \n");
+
+ if(SH5001_SwitchPowerMode(SH5001_NORMAL_MODE) == SH5001_TRUE)
+ printf("sh5001 start successful \n");
+ else
+ printf("sh5001 start failed \n");
+#endif
+}
+
+void gyro_power_off(void)
+{
+#ifdef GYRO_SH5001
+ if(SH5001_SwitchPowerMode(SH5001_POWERDOWN_MODE) == SH5001_TRUE)
+ printf("sh5001 stop successful \n");
+ else
+ printf("sh5001 stop failed \n");
+#endif
+}
+
+void gyro_check(void)
+{
+#ifdef GYRO_SH5001
+ SH5001_ReadFIFO();
+#endif
+}
+
+bool gyro_check_exist(void)
+{
+#ifdef GYRO_SH5001
+ if(gyro_get_chip_id() != SH5001_ID)
+ return false;
+ else
+ return true;
+#endif
+ return false;
+}
+
+gyro_data_t gyro_get_data(void)
+{
+ gyro_data_t data = {0};
+#ifdef GYRO_SH5001
+ data = sh5001_get_gyro_data();
+ // printf("%.3f %.3f %.3f\r\n",data.x,data.y,data.z);
+#endif
+ return data;
+}
+
+uint8_t gyro_get_chip_id(void)
+{
+#ifdef GYRO_SH5001
+ return SH5001_get_chip_id();
+#endif
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-05-12 10:00:46
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-23 14:14:26
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/gyro/service/gyro_hal.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#ifndef GYRO_HAL_H__
+#define GYRO_HAL_H__
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+#include <stdbool.h>
+
+typedef struct {
+ float x;
+ float y;
+ float z;
+} gyro_data_t;
+
+
+void gyro_power_on(void);
+void gyro_power_off(void);
+void gyro_check(void);
+gyro_data_t gyro_get_data(void);
+uint8_t gyro_get_chip_id(void);
+bool gyro_check_exist(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+
+#include "debug_print.h"
+#include "soc_osal.h"
+#include "tcxo.h"
+#include "irmalloc.h"
+#include "errcode.h"
+#include "common_def.h"
+#include "tcxo.h"
+#include "input_app.h"
+#include "cmsis_os2.h"
+#include "custom_utils.h"
+#include "gyro_hal.h"
+#include "gyro_service.h"
+#ifdef ROTARYENCODER_MIXO
+#include "mixo_service.h"
+#endif
+// #include "custom_runtime.h"
+/***
+ * 其他cmd在Header里定义,对外开放
+*/
+#define GYRO_SERVICE_CMD_TIMER_CHECK 0x11
+
+static bool g_gyro_service_initialled = false;
+
+
+static bool g_gyro_sensor_exist = false;
+
+
+static unsigned long g_app_queue= 0xFFFFFFFF;
+
+
+void do_gyro_service_check_msg(int cmd);
+
+void do_gyro_service_check_msg(int cmd)
+{
+ int ret;
+ if (g_gyro_sensor_exist == false)
+ return ;
+ common_notify_mail_t mail = {0};
+ mail.comm.app = cmd;
+ ret = osal_msg_queue_write_copy(g_app_queue, (void *)&mail,
+ sizeof(common_notify_mail_t), 0);
+ if (ret != OSAL_SUCCESS) {
+ PRINT("Error gyro Check MSG 0x%02X send failed! err=0x%x! \r\n",cmd, ret);
+ }
+
+}
+
+static void gyro_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 == GYRO_SERVICE_CMD_TIMER_CHECK) {
+ gyro_check();
+ }else if (mail.comm.app == GYRO_SERVICE_CMD_START_CHECK){
+ gyro_power_on();
+ }else if (mail.comm.app == GYRO_SERVICE_CMD_STOP_CHECK){
+ gyro_power_off();
+ }
+
+
+ }
+}
+void create_gyro_queue(void)
+{
+
+ if (osal_msg_queue_create("gyro_service_queue", APP_BOARD_MSG_COUNT, &g_app_queue,
+ 0, sizeof(common_notify_mail_t)) != ERRCODE_SUCC) {
+ PRINT("[gyro][service] app create mail fail\n");
+ }
+}
+
+#define GYRO_BOARD_TASK_SIZE 0x500
+errcode_t uapi_gyro_service_init(void)
+{
+ PRINT("uapi_gyro_service_init !\r\n");
+
+ if(!gyro_check_exist())
+ {
+ //TODO 设置陀螺仪检测是否存在标识
+ PRINT("gyro not found!\r\n");
+ return ERRCODE_FAIL;
+ }
+ g_gyro_sensor_exist = true;
+
+ gyro_power_off();
+
+ app_task_definition_t taskcfg={0};
+ taskcfg.create_queue_handle = create_gyro_queue;
+ taskcfg.attr.name="gyro_service";
+ taskcfg.attr.priority = osPriorityBelowNormal4;
+ taskcfg.attr.stack_size = GYRO_BOARD_TASK_SIZE;
+ taskcfg.func = gyro_service_check_task;
+ taskcfg.use_mem = USE_EXTEND_MEM;
+
+ errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+ if(ret != ERRCODE_SUCC)
+ {
+ PRINT("create gyro_service failed %d!\r\n",ret);
+ return ERRCODE_FAIL;
+ }
+
+ return ERRCODE_SUCC;
+}
+
+void gyro_int_callback(pin_t pin, uintptr_t param)
+{
+ // PRINT("gyro_int_callback %d 0x%X\n",pin,param);
+ uapi_gpio_clear_interrupt(pin);
+ do_gyro_service_check_msg(GYRO_SERVICE_CMD_TIMER_CHECK);
+}
+
+void gyro_start(void)
+{
+ do_gyro_service_check_msg(GYRO_SERVICE_CMD_START_CHECK);
+#ifdef ROTARYENCODER_MIXO
+ mixo_stop();
+#endif
+}
+
+void gyro_stop(void)
+{
+ do_gyro_service_check_msg(GYRO_SERVICE_CMD_STOP_CHECK);
+#ifdef ROTARYENCODER_MIXO
+ mixo_start();
+#endif
+}
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-12-23 15:12:01
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-12 17:47:11
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/gyro/service/gyro_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Test adc header \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-08-16, Create file. \n
+ */
+
+#ifndef GYRO_SERVICE_H__
+#define GYRO_SERVICE_H__
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+#include "platform_core.h"
+
+#define GYRO_SERVICE_CMD_START_CHECK 0x12
+#define GYRO_SERVICE_CMD_STOP_CHECK 0x13
+
+errcode_t uapi_gyro_service_init(void);
+void uapi_gyro_service_deinit(void);
+void do_gyro_service_check_msg(int cmd);
+void gyro_int_callback(pin_t pin, uintptr_t param);
+void gyro_start(void);
+void gyro_stop(void);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/******************************************************************\r
+* Senodia 6D IMU(Gyroscope+Accelerometer) SH5001 driver, By Senodia AE@20220505;\r
+*\r
+*\r
+* 1. SH5001_init() : SH5001 initialize function\r
+* 2. SH5001_GetImuData( ... ): SH5001 read gyro and accel data function\r
+* 3. SH5001_GetTempData(): SH5001 read termperature function\r
+* 4. delay_ms(x): delay x millisecond.\r
+* 5. SH5001_initFIFO(): initialize FIFO function\r
+* 6. SH5001_ReadFIFO(): read FIFO data\r
+* \r
+******************************************************************/\r
+\r
+#include "sh5001.h"\r
+#include "custom_utils.h"\r
+#include "los_base.h"\r
+\r
+// 32-bit version number represented as major[31:16].minor[15:0]\r
+#define SH5001_MAJOR 1\r
+#define SH5001_MINOR 01\r
+#define SH5001_REV 31\r
+#define MCU_VERSION_SH5001 ((SH5001_MAJOR<<16) | (SH5001_MINOR<<8) | SH5001_REV)\r
+\r
+#define SH5001_I2C_BUS I2C_BUS_2\r
+\r
+static gyro_data_t gyro_data = {0};\r
+\r
+/******************************************************************\r
+* Description: I2C or SPI bus interface functions and delay time function\r
+*\r
+* Parameters: \r
+* devAddr: I2C device address, modify the macro(SH5001_ADDRESS @SH5001.h) based on your I2C function. \r
+* If SPI interface, please ingnore the parameter.\r
+* regAddr: register address\r
+* readLen: data length to read\r
+* *readBuf: data buffer to read; If using FIFO function, the max buffer size is 1024; \r
+* writeLen: data length to write\r
+* *writeBuf: data buffer to write\r
+* \r
+* Note: I2C interface, define USER_INTERFACE_I2C (1)\r
+* SPI interface, define USER_INTERFACE_I2C (0)\r
+* SPI 3 Wire interface, define SH5001_SPI_3WIRE_MODE (1)\r
+* SPI 4 Wire interface, define SH5001_SPI_3WIRE_MODE (0)\r
+* \r
+******************************************************************/\r
+#define USER_INTERFACE_I2C (1)\r
+\r
+#if USER_INTERFACE_I2C\r
+\r
+unsigned char I2C_ReadNBytes( unsigned char devAddr, \r
+ unsigned char regAddr, \r
+ unsigned short readLen, \r
+ unsigned char *readBuf)\r
+{\r
+ //your I2C interface code:\r
+ //......\r
+ custom_i2c_read_regs(devAddr, regAddr, 1, readBuf, readLen,SH5001_I2C_BUS);\r
+ return (SH5001_TRUE);\r
+}\r
+\r
+unsigned char I2C_WriteNBytes( unsigned char devAddr, \r
+ unsigned char regAddr, \r
+ unsigned short writeLen, \r
+ unsigned char *writeBuf)\r
+{\r
+ //your I2C interface code:\r
+ //......\r
+ custom_i2c_write_reg(devAddr, regAddr, 1, writeBuf, writeLen,SH5001_I2C_BUS);\r
+ return (SH5001_TRUE);\r
+} \r
+\r
+IMU_read SH5001_read = I2C_ReadNBytes;\r
+IMU_write SH5001_write = I2C_WriteNBytes;\r
+\r
+#else\r
+\r
+#define SH5001_SPI_3WIRE_MODE (0)\r
+\r
+unsigned char SPI_readNBytes ( unsigned char devAddr, \r
+ unsigned char regAddr, \r
+ unsigned short readLen, \r
+ unsigned char *readBuf)\r
+{\r
+ //your SPI interface code:\r
+\r
+ //For example: \r
+ //unsigned char u8Data; \r
+ //devAddr = devAddr; \r
+ //u8Data = (regAddr > 0x7F) ? 0x01 : 0x00;\r
+ //SPIWrite(SH5001_SPI_REG_ACCESS, &u8Data, 1);\r
+ \r
+ //SPIRead((regAddr | 0x80), readBuf, readLen); \r
+ return (SH5001_TRUE);\r
+}\r
+\r
+unsigned char SPI_writeNBytes( unsigned char devAddr, \r
+ unsigned char regAddr, \r
+ unsigned short writeLen, \r
+ unsigned char *writeBuf)\r
+{\r
+ //your SPI interface code:\r
+ \r
+ //For example: \r
+ //unsigned char u8Data; \r
+ //devAddr = devAddr; \r
+ //u8Data = (regAddr > 0x7F) ? 0x01 : 0x00;\r
+ //SPIWrite(SH5001_SPI_REG_ACCESS, &u8Data, 1);\r
+ \r
+ //SPIWrite((regAddr & 0x7F), writeBuf, writeLen);\r
+ return (SH5001_TRUE);\r
+} \r
+\r
+IMU_read SH5001_read = SPI_readNBytes;\r
+IMU_write SH5001_write = SPI_writeNBytes;\r
+\r
+#endif\r
+\r
+\r
+static void delay_ms(unsigned short mSecond)\r
+{ \r
+ //your delay code(mSecond: millisecond):\r
+ //......\r
+ LOS_Mdelay(mSecond);\r
+ // HAL_Delay(mSecond);\r
+} \r
+\r
+\r
+#if SH5001_OIS_ENABLE\r
+unsigned char SH5001_OIS_read( unsigned char devAddr,\r
+ unsigned char regAddr,\r
+ unsigned short readLen,\r
+ unsigned char *readBuf)\r
+{\r
+ //your SPI interface code:\r
+\r
+\r
+ //SPIRead((regAddr | 0x80), readBuf, readLen);\r
+ return (SH5001_TRUE);\r
+}\r
+\r
+#endif\r
+\r
+\r
+/******************************************************************\r
+* Description: Local Variable \r
+******************************************************************/\r
+\r
+\r
+/******************************************************************\r
+* Description: Local Function Prototypes \r
+******************************************************************/\r
+static void SH5001_ModuleReset(void);\r
+static void SH5001_Acc_Config(unsigned char accODR, \r
+ unsigned char accRange, \r
+ unsigned char accCutOffFreq,\r
+ unsigned char accFilter,\r
+ unsigned char accByPass);\r
+\r
+static void SH5001_Gyro_Config( unsigned char gyroODR, \r
+ unsigned char gyroRange, \r
+ unsigned char gyroCutOffFreq,\r
+ unsigned char gyroFilter,\r
+ unsigned char gyroByPass);\r
+\r
+static void SH5001_TimeStamp_Config(unsigned char timeStampODR, \r
+ unsigned char timeStampEnable);\r
+\r
+static void SH5001_Temp_Config( unsigned char tempODR, \r
+ unsigned char tempEnable); \r
+\r
+ \r
+\r
+static void SH5001_SoftReset(void)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ regData = 0x01;\r
+ SH5001_write(SH5001_ADDRESS, 0x2B, 1, ®Data);\r
+ regData = 0x73;\r
+ SH5001_write(SH5001_ADDRESS, 0x00, 1, ®Data);\r
+\r
+ delay_ms(50);\r
+}\r
+\r
+static void SH5001_DriveStart(void)\r
+{\r
+ unsigned char regData = 0;\r
+ //Driver start\r
+ regData = 0x01;\r
+ SH5001_write(SH5001_ADDRESS, 0x2B, 1, ®Data);\r
+\r
+ delay_ms(2);\r
+\r
+ regData = 0x00;\r
+ SH5001_write(SH5001_ADDRESS, 0x2B, 1, ®Data);\r
+\r
+ delay_ms(1);\r
+\r
+}\r
+\r
+static void SH5001_ADCReset(void)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ regData = 0x08;\r
+ SH5001_write(SH5001_ADDRESS, 0x30, 1, ®Data);\r
+\r
+ regData = 0x00;\r
+ SH5001_write(SH5001_ADDRESS, 0xD2, 1, ®Data);\r
+\r
+ regData = 0x6B;\r
+ SH5001_write(SH5001_ADDRESS, 0xD1, 1, ®Data);\r
+\r
+ regData = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xD5, 1, ®Data);\r
+ delay_ms(5);\r
+\r
+ regData = 0x68;\r
+ SH5001_write(SH5001_ADDRESS, 0xD1, 1, ®Data);\r
+ delay_ms(2);\r
+\r
+ regData = 0x00;\r
+ SH5001_write(SH5001_ADDRESS, 0xD5, 1, ®Data);\r
+\r
+ regData = 0x00;\r
+ SH5001_write(SH5001_ADDRESS, 0x30, 1, ®Data);\r
+\r
+ regData = 0x08;\r
+ SH5001_write(SH5001_ADDRESS, 0x30, 1, ®Data);\r
+\r
+ regData = 0xE0;\r
+ SH5001_write(SH5001_ADDRESS, 0xD8, 1, ®Data);\r
+\r
+ delay_ms(5);\r
+\r
+ regData = 0x00;\r
+ SH5001_write(SH5001_ADDRESS, 0xD8, 1, ®Data);\r
+\r
+ regData = 0x00;\r
+ SH5001_write(SH5001_ADDRESS, 0x30, 1, ®Data);\r
+}\r
+\r
+static void SH5001_CVAReset(void)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ regData = 0x12;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, ®Data);\r
+ regData = 0x12;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, ®Data);\r
+ regData = 0x12;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, ®Data);\r
+\r
+ delay_ms(1);\r
+\r
+ regData = 0x2;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, ®Data);\r
+ regData = 0x2;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, ®Data);\r
+ regData = 0x2;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, ®Data);\r
+\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: reset some internal modules;\r
+*\r
+* Parameters: void \r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+static void SH5001_ModuleReset(void)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ // soft reset\r
+ SH5001_SoftReset();\r
+\r
+#if SH5001_SPI_3WIRE_MODE\r
+ SH5001_SPI_Config(SH5001_SPI_3_WIRE);\r
+#endif \r
+\r
+ //Driver start\r
+ SH5001_DriveStart();\r
+\r
+ \r
+ // ADC reset\r
+ SH5001_ADCReset();\r
+\r
+ //CVA Reset\r
+ SH5001_CVAReset();\r
+\r
+ delay_ms(250);\r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: 1.set accelerometer parameters;\r
+* 2.accCutOffRreq = accODR * 0.40 or accODR * 0.25 or accODR * 0.11 or accODR * 0.04 or accODR * 0.02;\r
+*\r
+* Parameters: accODR accRange accCutOffFreq accFilter accByPass\r
+* SH5001_ACC_ODR_1000HZ SH5001_ACC_RANGE_16G SH5001_ACC_ODRX040 SH5001_ACC_FILTER_EN SH5001_ACC_BYPASS_EN\r
+* SH5001_ACC_ODR_500HZ SH5001_ACC_RANGE_8G SH5001_ACC_ODRX025 SH5001_ACC_FILTER_DIS SH5001_ACC_BYPASS_DIS\r
+* SH5001_ACC_ODR_250HZ SH5001_ACC_RANGE_4G SH5001_ACC_ODRX011\r
+* SH5001_ACC_ODR_125HZ SH5001_ACC_RANGE_2G SH5001_ACC_ODRX004\r
+* SH5001_ACC_ODR_63HZ SH5001_ACC_ODRX002\r
+* SH5001_ACC_ODR_31HZ\r
+* SH5001_ACC_ODR_16HZ\r
+* SH5001_ACC_ODR_2000HZ\r
+* SH5001_ACC_ODR_4000HZ\r
+* SH5001_ACC_ODR_8000HZ\r
+* \r
+* return: void\r
+*\r
+******************************************************************/\r
+unsigned char storeAccODR;\r
+static void SH5001_Acc_Config(unsigned char accODR, \r
+ unsigned char accRange, \r
+ unsigned char accCutOffFreq,\r
+ unsigned char accFilter,\r
+ unsigned char accByPass)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ // enable acc digital filter and bypass or not\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF0, 1, ®Data);\r
+ regData = (regData & 0xFCU) | accFilter | accByPass;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF0, 1, ®Data);\r
+ \r
+ // set acc ODR range\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF1, 1, ®Data);\r
+ regData = (regData & 0x80U) | accODR | accRange;\r
+ storeAccODR = regData;\r
+ //regData = (regData & 0x80U)| accRange | accODR;\r
+ //regData = (regData & 0x80U)| 0x38;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF1, 1, ®Data);\r
+ \r
+ // set acc low pass filter cut-off frequency\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+ regData = (regData & 0xF0U) | accCutOffFreq;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+\r
+}\r
+\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.set accelerometer parameters;\r
+* 2.accCutOffRreq = accODR * 0.40 or accODR * 0.25 or accODR * 0.11 or accODR * 0.04 or accODR * 0.02;\r
+*\r
+* Parameters: accODR accRange accCutOffFreq accOisEnable\r
+\r
+* return: void\r
+*\r
+******************************************************************/\r
+static void SH5001_Acc_OIS_Config(unsigned char accODR,\r
+ unsigned char accRange,\r
+ unsigned char accCutOffFreq,\r
+ unsigned char accOisEnable)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ regData = accODR | accRange | accCutOffFreq | accOisEnable;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_OIS_ACC_CONF, 1, ®Data);\r
+\r
+}\r
+\r
+/******************************************************************\r
+* Description: 1.set gyroscope parameters;\r
+* 2.gyroCutOffRreq is at Page 33 of SH5001 datasheet.\r
+*\r
+* Parameters: gyroODR gyroRangeX,Y,Z gyroCutOffFreq gyroFilter gyroByPass\r
+* SH5001_GYRO_ODR_800HZ SH5001_GYRO_RANGE_125 SH5001_GYRO_ODRX00 SH5001_GYRO_FILTER_EN SH5001_GYRO_BYPASS_EN\r
+* SH5001_GYRO_ODR_400HZ SH5001_GYRO_RANGE_250 SH5001_GYRO_ODRX01 SH5001_GYRO_FILTER_DIS SH5001_GYRO_BYPASS_DIS\r
+* SH5001_GYRO_ODR_200HZ SH5001_GYRO_RANGE_500 SH5001_GYRO_ODRX02\r
+* SH5001_GYRO_ODR_100HZ SH5001_GYRO_RANGE_1000 SH5001_GYRO_ODRX03\r
+* SH5001_GYRO_ODR_50HZ SH5001_GYRO_RANGE_2000\r
+* SH5001_GYRO_ODR_25HZ\r
+* SH5001_GYRO_ODR_1600HZ\r
+* SH5001_GYRO_ODR_3200HZ\r
+* SH5001_GYRO_ODR_6400HZ\r
+* SH5001_GYRO_ODR_12800HZ\r
+* SH5001_GYRO_ODR_25600HZ\r
+* \r
+* gyroOnOff\r
+* SH5001_GYRO_OFF_INACT\r
+* SH5001_GYRO_ON_INACT\r
+* return: void\r
+*\r
+******************************************************************/\r
+/*\r
+static void SH5001_Gyro_Config( unsigned char gyroODR, \r
+ unsigned char gyroRange, \r
+ unsigned char gyroCutOffFreq,\r
+ unsigned char gyroFilter,\r
+ unsigned char gyroByPass,\r
+ unsigned char gyroOnOff)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ // enable gyro digital filter\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+ regData = (regData & 0x7CU) | gyroFilter | gyroByPass | gyroOnOff;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+ \r
+ // set gyro ODR\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF1, 1, ®Data);\r
+ regData = (regData & 0xF0U) | gyroODR;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF1, 1, ®Data);\r
+ \r
+ // set gyro low pass filter cut-off frequency\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF2, 1, ®Data);\r
+ regData = (regData & 0xFCU) | gyroCutOffFreq;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF2, 1, ®Data);\r
+ \r
+\r
+ // set gyro range\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF3, 1, ®Data);\r
+ regData = (regData & 0xF8U) | gyroRange;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF3, 1, ®Data); \r
+\r
+}\r
+\r
+*/\r
+static void SH5001_Gyro_Config( unsigned char gyroODR,\r
+ unsigned char gyroRange,\r
+ unsigned char gyroCutOffFreq,\r
+ unsigned char gyroFilter,\r
+ unsigned char gyroByPass)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ // enable gyro digital filter\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+ regData = (regData & 0x7CU) | gyroFilter | gyroByPass;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+\r
+ // set gyro ODR Range\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF1, 1, ®Data);\r
+ regData = (regData & 0x80U) | gyroODR | gyroRange;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF1, 1, ®Data);\r
+\r
+ // set gyro low pass filter cut-off frequency\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF2, 1, ®Data);\r
+ regData = (regData & 0xF0U) | gyroCutOffFreq;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF2, 1, ®Data);\r
+\r
+}\r
+\r
+//Jin: Modify \r
+/* */\r
+\r
+\r
+static void SH5001_Gyro_OIS_Config( unsigned char gyroODR,\r
+ unsigned char gyroRange,\r
+ unsigned char gyroCutOffFreq,\r
+ unsigned char gyroOisEnable)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ regData = gyroODR | gyroRange | gyroCutOffFreq | gyroOisEnable;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_OIS_GYRO_CONF, 1, ®Data);\r
+\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: set time stamp parameters;\r
+*\r
+* Parameters: timeStampODR timeStampEnable\r
+* SH5001_TS_ODR_25KHZ SH5001_TS_EN\r
+* SH5001_TS_ODR_1KHZ SH5001_TS_DIS \r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+static void SH5001_TimeStamp_Config(unsigned char timeStampODR, \r
+ unsigned char timeStampEnable)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ // config time stamp\r
+ SH5001_read(SH5001_ADDRESS, SH5001_TIMESTAMP_CONF, 1, ®Data);\r
+ regData = (regData & 0x9FU) | timeStampODR | timeStampEnable;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_TIMESTAMP_CONF, 1, ®Data);\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: set temperature parameters;\r
+*\r
+* Parameters: tempODR tempEnable\r
+* SH5001_TEMP_ODR_500HZ SH5001_TEMP_EN\r
+* SH5001_TEMP_ODR_250HZ SH5001_TEMP_DIS\r
+* SH5001_TEMP_ODR_125HZ \r
+* SH5001_TEMP_ODR_63HZ \r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+static void SH5001_Temp_Config( unsigned char tempODR, \r
+ unsigned char tempEnable)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ // enable temperature, set ODR\r
+ SH5001_read(SH5001_ADDRESS, SH5001_TEMP_CONF0, 1, ®Data);\r
+ regData = (regData & 0xF8U) | tempODR | tempEnable;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_TEMP_CONF0, 1, ®Data);\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: read temperature parameters;\r
+*\r
+* Parameters: void \r
+* \r
+* return: temperature data(deg);\r
+* \r
+******************************************************************/\r
+float SH5001_GetTempData(void)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ unsigned short int tempref[2] = {0};\r
+ \r
+ // read temperature data, unsigned 12bits; SH5001_TEMP_CONF2..SH5001_TEMP_CONF1\r
+ SH5001_read(SH5001_ADDRESS, SH5001_TEMP_CONF1, 2, ®Data[0]);\r
+ tempref[0] = ((unsigned short int)(regData[1] & 0x0FU) << 8U) | regData[0];\r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_TEMP_ZL, 2, ®Data[0]);\r
+ tempref[1] = ((unsigned short int)(regData[1] & 0x0FU) << 8U) | regData[0]; \r
+ \r
+ return ( (((float)(tempref[1] - tempref[0]))/14.0f) + 25.0f );\r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: enable or disable INT, mapping interrupt to INT pin or INT1 pin\r
+*\r
+* Parameters: intType intEnable intPinSel\r
+* SH5001_INT_LOWG SH5001_INT_EN SH5001_INT_MAP_INT0\r
+* SH5001_INT_HIGHG SH5001_INT_DIS SH5001_INT_MAP_INT1\r
+* SH5001_INT_INACT \r
+* SH5001_INT_ACT\r
+* SH5001_INT_DOUBLE_TAP\r
+* SH5001_INT_SINGLE_TAP\r
+* SH5001_INT_FLAT\r
+* SH5001_INT_ORIENTATION\r
+* SH5001_INT_TAP (Only INT/INT1 Map)\r
+* SH5001_INT_SMD\r
+* SH5001_INT_FIFO_WATERMARK\r
+* SH5001_INT_GYRO_READY\r
+* SH5001_INT_ACC_READY\r
+* SH5001_INT_FREE_FALL\r
+* SH5001_INT_UP_DOWN_Z\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Enable( unsigned short intType, \r
+ unsigned char intEnable, \r
+ unsigned char intPinSel)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ unsigned short int u16IntVal = 0; \r
+ \r
+ // Z axis change between UP to DOWN\r
+ if((intType & 0x0040U) == SH5001_INT_UP_DOWN_Z)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ORIEN_INTCONF0, 1, ®Data[0]);\r
+ regData[0] = (intEnable == SH5001_INT_EN) \\r
+ ? (regData[0] & 0xBFU) : (regData[0] | 0x40U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INTCONF0, 1, ®Data[0]);\r
+ } \r
+ \r
+ if(intType & 0xFF3FU)\r
+ { \r
+ // enable or disable INT\r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_ENABLE0, 2, ®Data[0]); \r
+ \r
+ u16IntVal = ((unsigned short int)regData[0] << 8U) | regData[1]; \r
+ \r
+ u16IntVal = u16IntVal & 0xFF1FU;\r
+ u16IntVal = (intEnable == SH5001_INT_EN) \\r
+ ? (u16IntVal | intType) : (u16IntVal & ~intType); \r
+ \r
+ regData[0] = (unsigned char)(u16IntVal >> 8U);\r
+ regData[1] = (unsigned char)(u16IntVal); \r
+ //SH5001_write(SH5001_ADDRESS, SH5001_INT_ENABLE0, 2, ®Data[0]);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_ENABLE0, 1, ®Data[0]);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_ENABLE1, 1, ®Data[1]);\r
+ \r
+ // mapping interrupt to INT0 pin or INT1 pin\r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_PIN_MAP0, 2, ®Data[0]);\r
+ u16IntVal = ((unsigned short int)regData[0] << 8U) | regData[1];\r
+ \r
+ u16IntVal = u16IntVal & 0xFF3FU;\r
+ u16IntVal = (intPinSel == SH5001_INT_MAP_INT1) \\r
+ ? (u16IntVal | intType) : (u16IntVal & ~intType); \r
+ \r
+ regData[0] = (unsigned char)(u16IntVal >> 8U);\r
+ regData[1] = (unsigned char)(u16IntVal);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_PIN_MAP0, 1, ®Data[0]);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_PIN_MAP1, 1, ®Data[1]);\r
+ } \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.config INT function\r
+* 2.intCount is valid only when intLatch is equal to SH5001_INT_NO_LATCH;\r
+*\r
+* Parameters: intLevel intLatch intClear \r
+* SH5001_INT_LEVEL_HIGH SH5001_INT_NO_LATCH SH5001_INT_CLEAR_ANY\r
+* SH5001_INT_LEVEL_LOW SH5001_INT_LATCH SH5001_INT_CLEAR_STATUS\r
+*\r
+* intTime\r
+* Unit: 2mS\r
+*\r
+* int1Mode int0Mode\r
+* SH5001_INT1_NORMAL SH5001_INT0_NORMAL\r
+* SH5001_INT1_OD SH5001_INT0_OD\r
+*\r
+* int1OE int0OE\r
+* SH5001_INT1_OUTPUT SH5001_INT0_OUTPUT\r
+* SH5001_INT1_INPUT SH5001_INT1_INPUT\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+\r
+\r
+void SH5001_INT_Config( unsigned char intLevel,\r
+ unsigned char intLatch,\r
+ unsigned char intClear,\r
+ unsigned char intTime,\r
+ unsigned char int1Mode,\r
+ unsigned char int0Mode,\r
+ unsigned char int1OE,\r
+ unsigned char int0OE)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ //SH5001_read(SH5001_ADDRESS, SH5001_INT_CONF, 1, ®Data);\r
+\r
+ regData = (intLevel == SH5001_INT0_LEVEL_LOW) \\r
+ ? (regData | SH5001_INT0_LEVEL_LOW) : (regData & SH5001_INT0_LEVEL_HIGH);\r
+\r
+ regData = (intLatch == SH5001_INT_NO_LATCH) \\r
+ ? (regData | SH5001_INT_NO_LATCH) : (regData & SH5001_INT_LATCH);\r
+\r
+ regData = (intClear == SH5001_INT_CLEAR_ANY) \\r
+ ? (regData | SH5001_INT_CLEAR_ANY) : (regData & SH5001_INT_CLEAR_STATUS);\r
+\r
+ regData = (int1Mode == SH5001_INT1_OD) \\r
+ ? (regData | SH5001_INT1_OD) : (regData & SH5001_INT1_NORMAL);\r
+\r
+ regData = (int1OE == SH5001_INT1_OUTPUT) \\r
+ ? (regData | SH5001_INT1_OUTPUT) : (regData & SH5001_INT1_INPUT);\r
+\r
+ regData = (int0Mode == SH5001_INT0_OD) \\r
+ ? (regData | SH5001_INT0_OD) : (regData & SH5001_INT0_NORMAL);\r
+\r
+ regData = (int0OE == SH5001_INT0_OUTPUT) \\r
+ ? (regData | SH5001_INT0_OUTPUT) : (regData & SH5001_INT0_INPUT);\r
+\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_CONF, 1, ®Data);\r
+\r
+ if(intLatch == SH5001_INT_NO_LATCH)\r
+ {\r
+ regData = intTime;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_LIMIT, 1, ®Data);\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.config INT0 & INT1 function\r
+*\r
+* Parameters: int1Mode int0Mode\r
+* SH5001_INT1_NORMAL SH5001_INT0_NORMAL\r
+* SH5001_INT1_OD SH5001_INT0_OD\r
+*\r
+* int1OE int0OE \r
+* SH5001_INT1_OUTPUT SH5001_INT0_OUTPUT\r
+* SH5001_INT1_INPUT SH5001_INT1_INPUT\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Output_Config( unsigned char int1Mode,\r
+ unsigned char int0Mode,\r
+ unsigned char int1OE,\r
+ unsigned char int0OE)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_CONF, 1, ®Data);\r
+ \r
+ regData = (int1Mode == SH5001_INT1_OD) \\r
+ ? (regData | SH5001_INT1_OD) : (regData & SH5001_INT1_NORMAL);\r
+ \r
+ regData = (int1OE == SH5001_INT1_OUTPUT) \\r
+ ? (regData | SH5001_INT1_OUTPUT) : (regData & SH5001_INT1_INPUT);\r
+ \r
+ regData = (int0Mode == SH5001_INT0_OD) \\r
+ ? (regData | SH5001_INT0_OD) : (regData & SH5001_INT0_NORMAL);\r
+ \r
+ regData = (int0OE == SH5001_INT0_OUTPUT) \\r
+ ? (regData | SH5001_INT0_OUTPUT) : (regData & SH5001_INT1_INPUT); \r
+ \r
+ SH5001_write(SH5001_ADDRESS, SH5001_INT_CONF, 1, ®Data); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: orientation config;\r
+*\r
+* Parameters: orientBlockMode orientMode orientTheta\r
+* SH5001_ORIENT_BLOCK_MODE0 SH5001_ORIENT_SYMM (1 Byte)\r
+* SH5001_ORIENT_BLOCK_MODE1 SH5001_ORIENT_HIGH_ASYMM\r
+* SH5001_ORIENT_BLOCK_MODE2 SH5001_ORIENT_LOW_ASYMM\r
+* SH5001_ORIENT_BLOCK_MODE3\r
+*\r
+* orientG1point5 orientSlope orientHyst\r
+* (2 Bytes) (2 Bytes) (2 Bytes)\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Orient_Config( unsigned char orientBlockMode,\r
+ unsigned char orientMode,\r
+ unsigned char orientTheta,\r
+ unsigned short orientG1point5,\r
+ unsigned short orientSlope,\r
+ unsigned short orientHyst)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ORIEN_INTCONF0, 1, ®Data[0]);\r
+ regData[0] |= (regData[0] & 0xC0U) | (orientTheta & 0x3FU); \r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INTCONF0, 1, ®Data[0]);\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ORIEN_INTCONF1, 1, ®Data[0]);\r
+ regData[0] |= (regData[0] & 0xF0U) | (orientBlockMode & 0x0CU) | (orientMode & 0x03U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INTCONF1, 1, ®Data[0]);\r
+ \r
+ regData[0] = (unsigned char)orientG1point5;\r
+ regData[1] = (unsigned char)(orientG1point5 >> 8U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INT_1G5_LOW, 2, ®Data[0]);\r
+ \r
+ regData[0] = (unsigned char)orientSlope;\r
+ regData[1] = (unsigned char)(orientSlope >> 8U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INT_SLOPE_LOW, 2, ®Data[0]); \r
+ \r
+ regData[0] = (unsigned char)orientHyst;\r
+ regData[1] = (unsigned char)(orientHyst >> 8U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INT_HYST_LOW, 2, ®Data[0]); \r
+}\r
+\r
+\r
+\r
+// Jin: flatTimeTH 200,400,800,000, sure? \r
+\r
+/******************************************************************\r
+* Description: flat INT time threshold, unit: mS;\r
+*\r
+* Parameters: flatTimeTH flatTanHeta2\r
+* SH5001_FLAT_TIME_200MS 0 ~ 63\r
+* SH5001_FLAT_TIME_400MS\r
+* SH5001_FLAT_TIME_800MS\r
+* SH5001_FLAT_TIME_000MS\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Flat_Config(unsigned char flatTimeTH, \r
+ unsigned char flatTanHeta2)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ORIEN_INTCONF1, 1, ®Data); \r
+ regData = (regData & 0xF3U) | SH5001_ORIENT_BLOCK_MODE1;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ORIEN_INTCONF1, 1, ®Data); \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_FLAT_INT_CONF, 1, ®Data); \r
+ regData = (flatTimeTH & 0xC0U) | (flatTanHeta2 & 0x3FU);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FLAT_INT_CONF, 1, ®Data); \r
+} \r
+\r
+// Jin: Act and inAct function --- actIntClear ?\r
+\r
+/******************************************************************\r
+* Description: activity INT config;\r
+* actIntThres: 1 LSB is 0.24mg@+/-2G, 0.48mg@+/-4G, 0.97mg@+/-8G, 1.95mg@+/-16G\r
+*\r
+* Parameters: actEnDisIntX actEnDisIntY actEnDisIntZ\r
+* SH5001_ACT_X_INT_EN SH5001_ACT_Y_INT_EN SH5001_ACT_Z_INT_EN\r
+* SH5001_ACT_X_INT_DIS SH5001_ACT_Y_INT_DIS SH5001_ACT_Z_INT_DIS\r
+* \r
+* \r
+* actTimeNum actIntThres actLinkStatus actIntClear \r
+* (1 Byte) (2 Byte2) SH5001_LINK_PRE_STA SH5001_ACT_INACT_CLR_STATUS1\r
+* SH5001_LINK_PRE_STA_NO SH5001_ACT_INACT_CLR_STATUS3\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Act_Config( unsigned char actEnDisIntX,\r
+ unsigned char actEnDisIntY,\r
+ unsigned char actEnDisIntZ,\r
+ unsigned char actTimeNum,\r
+ unsigned short actIntThres,\r
+ unsigned char actLinkStatus,\r
+ unsigned char actIntClear)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACT_INACT_INT_CONF, 1, ®Data[0]); \r
+ regData[0] |= (regData[0] & 0x8FU) | actEnDisIntX | actEnDisIntY | actEnDisIntZ;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INACT_INT_CONF, 1, ®Data[0]); \r
+ \r
+ regData[0] = (unsigned char)actIntThres;\r
+ regData[1] = (unsigned char)(actIntThres >> 8U);\r
+ //SH5001_write(SH5001_ADDRESS, SH5001_ACT_INT_THRESHOLDL, 2, ®Data[0]);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INT_THRESHOLDL, 1, ®Data[0]);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INT_THRESHOLDH, 1, ®Data[1]);\r
+\r
+ regData[0] = actTimeNum;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INT_TIME, 1, ®Data[0]);\r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACT_INACT_INT_LINK, 1, ®Data[0]); \r
+ regData[0] |= (regData[0] & 0x7EU) | actLinkStatus | actIntClear;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INACT_INT_LINK, 1, ®Data[0]); \r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: inactivity INT config;\r
+*\r
+* Parameters: inactEnDisIntX inactEnDisIntY inactEnDisIntZ\r
+* SH5001_INACT_X_INT_EN SH5001_INACT_Y_INT_EN SH5001_INACT_Z_INT_EN\r
+* SH5001_INACT_X_INT_DIS SH5001_INACT_Y_INT_DIS SH5001_INACT_Z_INT_DIS\r
+* \r
+* inactLinkStatus inactTimeMs inactIntThres\r
+* SH5001_LINK_PRE_STA Unit: mS (2 Bytes) \r
+* SH5001_LINK_PRE_STA_NO\r
+*\r
+* inactG1 inactIntClear\r
+* (2 Bytes) SH5001_ACT_INACT_CLR_STATUS1\r
+* SH5001_ACT_INACT_CLR_STATUS3\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Inact_Config( unsigned char inactEnDisIntX,\r
+ unsigned char inactEnDisIntY,\r
+ unsigned char inactEnDisIntZ,\r
+ unsigned char inactLinkStatus,\r
+ unsigned char inactTimeMs,\r
+ unsigned short inactIntThres,\r
+ unsigned short inactG1,\r
+ unsigned char inactIntClear)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACT_INACT_INT_CONF, 1, ®Data); \r
+ regData |= (regData & 0xF8U) | inactEnDisIntX | inactEnDisIntY | inactEnDisIntZ;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INACT_INT_CONF, 1, ®Data); \r
+ \r
+ regData = (unsigned char)inactIntThres;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INACT_INT_THRESHOLDL, 1, ®Data);\r
+ regData = (unsigned char)(inactIntThres >> 8U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INACT_INT_THRESHOLDH, 1, ®Data); \r
+ \r
+ regData = inactTimeMs;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INACT_INT_TIME, 1, ®Data); \r
+ \r
+ /*\r
+ regData = (unsigned char)inactG1;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INACT_INT_1G_REFL, 1, ®Data);\r
+ regData = (unsigned char)(inactG1 >> 8U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_INACT_INT_1G_REFH, 1, ®Data); \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACT_INACT_INT_LINK, 1, ®Data); \r
+ regData |= (regData & 0x7EU) | inactLinkStatus | inactIntClear;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INACT_INT_LINK, 1, ®Data); \r
+ */\r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: 1.tap INT config;\r
+* 2.tapIntThres is between 0 and 8191;\r
+* 3.tapWaitTimeWindowMs is more than tapWaitTimeMs;\r
+*\r
+* Parameters: tapEnDisIntX tapEnDisIntY tapEnDisIntZ\r
+* SH5001_TAP_X_INT_EN SH5001_TAP_Y_INT_EN SH5001_TAP_Z_INT_EN\r
+* SH5001_TAP_X_INT_DIS SH5001_TAP_Y_INT_DIS SH5001_TAP_Z_INT_DIS\r
+* \r
+* tapIntThres tapTimeMs tapWaitTimeMs tapWaitTimeWindowMs\r
+* (13 bits) Unit: mS Unit: mS Unit: 2mS\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_Tap_Config( unsigned char tapEnDisIntX,\r
+ unsigned char tapEnDisIntY,\r
+ unsigned char tapEnDisIntZ,\r
+ unsigned char tapIntThres,\r
+ unsigned char tapTimeMs,\r
+ unsigned char tapWaitTimeMs,\r
+ unsigned char tapWaitTimeWindowMs)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACT_INACT_INT_LINK, 1, ®Data); \r
+ regData |= (regData & 0xF1U) | tapEnDisIntX | tapEnDisIntY | tapEnDisIntZ;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACT_INACT_INT_LINK, 1, ®Data); \r
+ \r
+ regData = (unsigned char)tapIntThres; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_TAP_INT_THRESHOLDL, 1, ®Data);\r
+ SH5001_read(SH5001_ADDRESS, SH5001_TAP_INT_THRESHOLDH, 1, ®Data);\r
+ regData = ((unsigned char)(tapIntThres >> 8U) & 0x1FU) | (regData & 0xE0U); \r
+ SH5001_write(SH5001_ADDRESS, SH5001_TAP_INT_THRESHOLDH, 1, ®Data);\r
+ \r
+ regData = tapTimeMs; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_TAP_INT_DURATION, 1, ®Data); \r
+ \r
+ regData = tapWaitTimeMs; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_TAP_INT_LATENCY, 1, ®Data); \r
+\r
+ regData = tapWaitTimeWindowMs; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_DTAP_INT_WINDOW, 1, ®Data); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.SMD INT config;\r
+* 2.smdBlockTimeS:0-0.5S; 1-1.0S; 2-1.5S; 3-2.0S;\r
+* 4-3.0S; 5-4.0S; 6-5.0S; 7-6.0S;\r
+* 8-7.0S; 9-8.0S; A-9.0S; B-10S;\r
+* C-12S; D-14S; E-15S; F-16S;\r
+*\r
+* 3.smdProofTimeS:0-0.2S; 1-0.25S; 2-0.3S; 3-0.4S;\r
+* 4-0.5S; 5-0.6S; 6-0.7S; 7-0.8S;\r
+* 8-0.9S; 9-1.0S; A-1.2S; B-1.5S;\r
+* C-1.8S; D-2.1S; E-2.4S; F-2.8S;\r
+*\r
+* Parameters: smdThres smdBlockTimeS smdProofTimeS\r
+* 2 Bytes Unit: S Unit: S\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_SMD_Config( unsigned short smdThres,\r
+ unsigned char smdBlockTimeS,\r
+ unsigned char smdProofTimeS)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ \r
+ regData[0] = (unsigned char)smdThres; \r
+ regData[1] = (unsigned char)(smdThres >> 8U); \r
+ SH5001_write(SH5001_ADDRESS, SH5001_SMD_INT_THRESHOLDL, 2, ®Data[0]); \r
+\r
+ regData[0] |= (unsigned char)((smdBlockTimeS & 0xF0U) << 4U) | (smdProofTimeS & 0xF0U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_HIGHG_INT_CONF, 1, ®Data[0]); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.highG INT config;\r
+* 2.highGThres is between 0 and 8191;\r
+* 3.highGThres: x=0.5mG@2G, x=1mG@4G, x=2mG@8G, x=4mG@16G\r
+*\r
+* Parameters: highGEnDisIntX highGEnDisIntY highGEnDisIntZ \r
+* SH5001_HIGHG_X_INT_EN SH5001_HIGHG_Y_INT_EN SH5001_HIGHG_Z_INT_EN \r
+* SH5001_HIGHG_X_INT_DIS SH5001_HIGHG_Y_INT_DIS SH5001_HIGHG_Z_INT_DIS\r
+* \r
+* highGEnDisIntAll highGThres highGTimeMs\r
+* SH5001_HIGHG_ALL_INT_EN Unit: x*8mG Unit: 2mS\r
+* SH5001_HIGHG_ALL_INT_DIS (13 bits)\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_HighG_Config( unsigned char highGEnDisIntX,\r
+ unsigned char highGEnDisIntY,\r
+ unsigned char highGEnDisIntZ,\r
+ unsigned char highGEnDisIntAll,\r
+ unsigned short highGThres,\r
+ unsigned char highGTimeMs)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_HIGHG_INT_CONF, 1, ®Data[0]); \r
+ regData[0] |= (regData[0] & 0x0FU) | highGEnDisIntX | highGEnDisIntY | highGEnDisIntZ | highGEnDisIntAll;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_HIGHG_INT_CONF, 1, ®Data[0]); \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_HIGHG_INT_THRESHOLDL, 2, ®Data[0]); \r
+ regData[0] = (unsigned char)highGThres; \r
+ regData[1] = (regData[1] & 0xE0U) | ((unsigned char)(highGThres >> 8U) & 0x1FU); \r
+ SH5001_write(SH5001_ADDRESS, SH5001_HIGHG_INT_THRESHOLDL, 2, ®Data[0]); \r
+ \r
+ regData[0] = highGTimeMs; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_HIGHG_INT_TIME, 1, ®Data[0]); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.lowG INT config;\r
+* 2.lowGThres is between 0 and 8191;\r
+* 3.lowGThres: x=0.5mG@2G or x=1mG@4G or x=2mG@8G or x=4mG@16G\r
+*\r
+* Parameters: lowGEnDisIntAll lowGThres lowGTimeMs\r
+* SH5001_LOWG_ALL_INT_EN Unit: x*8mG Unit: 2mS\r
+* SH5001_LOWG_ALL_INT_DIS (13 bits)\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_LowG_Config( unsigned char lowGEnDisIntAll,\r
+ unsigned short lowGThres,\r
+ unsigned char lowGTimeMs)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_HIGHG_INT_CONF, 1, ®Data[0]); \r
+ regData[0] |= (regData[0] & 0xFEU) | lowGEnDisIntAll;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_HIGHG_INT_CONF, 1, ®Data[0]); \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_LOWG_INT_THRESHOLDL, 2, ®Data[0]); \r
+ regData[0] = (unsigned char)lowGThres; \r
+ regData[1] = (regData[1] & 0xE0U) | ((unsigned char)(lowGThres >> 8U) & 0x1FU);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_LOWG_INT_THRESHOLDL, 2, ®Data[0]); \r
+ \r
+ regData[0] = lowGTimeMs; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_LOWG_INT_TIME, 1, ®Data[0]); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.freeFall INT config;\r
+* 2.freeFallThres: x=0.5mG@2G or x=1mG@4G or x=2mG@8G or x=4mG@16G\r
+*\r
+* Parameters: freeFallThres freeFallTimeMs\r
+* Unit: x*8mG Unit: 2mS\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_INT_FreeFall_Config( unsigned char freeFallThres,\r
+ unsigned char freeFallTimeMs)\r
+{\r
+ unsigned char regData = 0;\r
+ \r
+ regData = freeFallThres; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_FREEFALL_INT_THRES, 1, ®Data); \r
+ \r
+ regData = freeFallTimeMs; \r
+ SH5001_write(SH5001_ADDRESS, SH5001_FREEFALL_INT_TIME, 1, ®Data); \r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.read INT status0\r
+*\r
+* Parameters: void\r
+*\r
+* return: unsigned short\r
+* bit 13: Tap, Single or Double Tap Interrupt status \r
+* bit 12: SMD Interrupt status\r
+* bit 11: FIFO Watermark Interrupt status \r
+* bit 10: Gyro Data Ready Interrupt status\r
+* bit 9: Acc Data Ready Interrupt status\r
+* bit 8: Free-fall Interrupt status \r
+* bit 7: Low-G Interrupt status\r
+* bit 6: High-G Interrupt status\r
+* bit 5: Inactivity Interrupt status\r
+* bit 4: Activity Interrupt status\r
+* bit 3: Double Tap Interrupt status \r
+* bit 2: Single Tap Interrupt status\r
+* bit 1: Flat Interrupt status\r
+* bit 0: Orientation Interrupt status \r
+* 0: Not Active\r
+* 1: Active\r
+*\r
+******************************************************************/\r
+unsigned short SH5001_INT_Read_Status01(void)\r
+{\r
+ unsigned char regData[3] = {0};\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_STA0, 3, ®Data[0]);\r
+\r
+ return( ((unsigned short)(regData[1] & 0x3FU) << 8U) | regData[0] );\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.read INT status2\r
+*\r
+* Parameters: void\r
+*\r
+* return: unsigned char\r
+* bit 7: High-G Sign\r
+* 0: Positive\r
+* 1: Negative\r
+* bit 6: High-G X-axis Interrupt status\r
+* bit 5: High-G Y-axis Interrupt status\r
+* bit 4: High-G Z-axis Interrupt status\r
+* 0: No Active\r
+* 1: Active\r
+* bit 3: Reserved\r
+* bit 2: Reserved\r
+* bit 1: Reserved\r
+* bit 0: Low-G Interrupt status\r
+* 0: Not Active\r
+* 1: Active\r
+*\r
+******************************************************************/\r
+unsigned char SH5001_INT_Read_Status2(void)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_STA2, 1, ®Data); \r
+\r
+ return( (regData & 0xF1U));\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.read INT status3\r
+*\r
+* Parameters: void\r
+*\r
+* return: unsigned char\r
+* bit 7: Activity-Inactivity Sign\r
+* 0: Positive\r
+* 1: Negative\r
+* bit 6: Activity-Inactivity X-axis Interrupt Status\r
+* bit 5: Activity-Inactivity Y-axis Interrupt Status\r
+* bit 4: Activity-Inactivity Z-axis Interrupt Status\r
+* 0: No Active\r
+* 1: Active\r
+* bit 3: Sign of acceleration that trigger Single or Double Tap Interrup\r
+* 0: Positive\r
+* 1: Negative\r
+* bit 2: Whether Single or Double Tap Interrupt is triggered by X axis\r
+* bit 1: Whether Single or Double Tap Interrupt is triggered by Y axis\r
+* bit 0: Whether Single or Double Tap Interrupt is triggered by Z axis\r
+* 0: No\r
+* 1: Yes\r
+******************************************************************/\r
+unsigned char SH5001_INT_Read_Status3(void)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_STA3, 1, ®Data); \r
+\r
+ return(regData);\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.read INT status4\r
+*\r
+* Parameters: void\r
+*\r
+* return: unsigned char\r
+* bit 7: Reserved\r
+* bit 6: Reserved\r
+* bit 5: Reserved\r
+* bit 4: Reserved\r
+* bit 3: Reserved\r
+* bit 2: Orientation Interrupt Value of Z-axis\r
+* 0: Upward\r
+* 1: Downward\r
+* bit 1..0: Orientation Interrupt Value of X and Y-axis\r
+* 00: Landscape left\r
+* 01: Landscape right\r
+* 10: Portrait upside down\r
+* 11: Portrait upright\r
+*\r
+******************************************************************/\r
+unsigned char SH5001_INT_Read_Status4(void)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_INT_STA4, 1, ®Data); \r
+\r
+ return(regData & 0x07U);\r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: reset FIFO controller;\r
+*\r
+* Parameters: fifoMode\r
+* SH5001_FIFO_MODE_DIS\r
+* SH5001_FIFO_MODE_FIFO\r
+* SH5001_FIFO_MODE_STREAM\r
+* SH5001_FIFO_MODE_TRIGGER\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_FIFO_Mode_Set(unsigned char fifoMode)\r
+{\r
+ unsigned char regData = 0; \r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_FIFO_CONF0, 1, ®Data);\r
+ regData &= 0x7F;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF0, 1, ®Data);\r
+ \r
+ regData = fifoMode & 0x03;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF0, 1, ®Data);\r
+}\r
+\r
+void SH5001_FIFO_Reset(void)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_FIFO_CONF0, 1, ®Data);\r
+ regData |= 0x80;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF0, 1, ®Data);\r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.FIFO down sample frequency config;\r
+* 2.fifoAccFreq: accODR*1/2, *1/4, *1/8, *1/16, *1/32, *1/64, *1/128, *1/256\r
+* 3.fifoGyroFreq: gyroODR*1/2, *1/4, *1/8, *1/16, *1/32, *1/64, *1/128, *1/256\r
+*\r
+* Parameters: fifoAccDownSampleEnDis fifoAccFreq/fifoGyroFreq fifoGyroDownSampleEnDis\r
+* SH5001_FIFO_ACC_DOWNS_EN SH5001_FIFO_FREQ_X1_2 SH5001_FIFO_GYRO_DOWNS_EN\r
+* SH5001_FIFO_ACC_DOWNS_DIS SH5001_FIFO_FREQ_X1_4 SH5001_FIFO_GYRO_DOWNS_DIS\r
+* SH5001_FIFO_FREQ_X1_8\r
+* SH5001_FIFO_FREQ_X1_16\r
+* SH5001_FIFO_FREQ_X1_32\r
+* SH5001_FIFO_FREQ_X1_64\r
+* SH5001_FIFO_FREQ_X1_128\r
+* SH5001_FIFO_FREQ_X1_256\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_FIFO_Freq_Config( unsigned char fifoAccDownSampleEnDis,\r
+ unsigned char fifoAccFreq,\r
+ unsigned char fifoGyroDownSampleEnDis,\r
+ unsigned char fifoGyroFreq)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ regData |= fifoAccDownSampleEnDis | fifoGyroDownSampleEnDis;\r
+ regData |= (fifoAccFreq << 4) | fifoGyroFreq;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF4, 1, ®Data); \r
+}\r
+\r
+\r
+// Jin: fifoWaterMarkLevel???\r
+/******************************************************************\r
+* Description: 1.config data type in FIFO;\r
+* 2.fifoWaterMarkLevel <= channelNum*2*(INT(1024/(channelNum*2))-1)\r
+* eg. fifomode = SH5001_FIFO_ACC_X_EN | SH5001_FIFO_ACC_Y_EN | SH5001_FIFO_ACC_Z_EN\r
+* then fifoWaterMarkLevel maximum is 1014\r
+*\r
+* Parameters: fifoMode fifoWaterMarkLevel\r
+ SH5001_FIFO_TIMESTAMP_EN <=1024 \r
+* SH5001_FIFO_EXT_Z_EN\r
+* SH5001_FIFO_EXT_Y_EN\r
+* SH5001_FIFO_EXT_X_EN \r
+* SH5001_FIFO_TEMPERATURE_EN \r
+* SH5001_FIFO_GYRO_Z_EN \r
+* SH5001_FIFO_GYRO_Y_EN \r
+* SH5001_FIFO_GYRO_X_EN\r
+* SH5001_FIFO_ACC_Z_EN\r
+* SH5001_FIFO_ACC_Y_EN\r
+* SH5001_FIFO_ACC_X_EN\r
+* SH5001_FIFO_ALL_DIS\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_FIFO_Data_Config( unsigned short fifoMode,\r
+ unsigned short fifoWaterMarkLevel)\r
+{\r
+ unsigned char regData = 0;\r
+ \r
+ if(fifoWaterMarkLevel > 1024U)\r
+ {\r
+ fifoWaterMarkLevel = 1024U;\r
+ }\r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_FIFO_CONF2, 1, ®Data);\r
+ regData = (regData & 0x88U) \\r
+ | ((unsigned char)(fifoMode >> 8U) & 0x70U) \\r
+ | (((unsigned char)(fifoWaterMarkLevel >> 8U)) & 0x07U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF2, 1, ®Data);\r
+\r
+ regData = (unsigned char)fifoMode;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF3, 1, ®Data);\r
+ \r
+ regData = (unsigned char)fifoWaterMarkLevel;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_FIFO_CONF1, 1, ®Data); \r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: 1. read Fifo status and fifo entries count\r
+*\r
+* Parameters: *fifoEntriesCount, store fifo entries count, less than or equal to 1024;\r
+*\r
+* \r
+* return: unsigned char\r
+* bit 7: 0\r
+* bit 6: 0\r
+* bit 5: Whether FIFO Watermark has been reached\r
+* bit 4: Whether FIFO is full\r
+* bit 3: Whether FIFO is empty\r
+* 0: No\r
+* 1: Yes\r
+* bit 2: 0\r
+* bit 1: 0\r
+* bit 0: 0\r
+*\r
+*\r
+******************************************************************/\r
+unsigned char SH5001_FIFO_Read_Status(unsigned short int *fifoEntriesCount)\r
+{\r
+ unsigned char regData[2] = {0}; \r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_FIFO_STA0, 2, ®Data[0]);\r
+\r
+ *fifoEntriesCount = ((unsigned short int)(regData[1] & 0x0FU) << 8U) | regData[0];\r
+\r
+ \r
+ return (regData[1] & 0x70U);\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1. read Fifo data\r
+*\r
+* Parameters: *fifoReadData fifoDataLength\r
+* data data length\r
+* \r
+* return: void\r
+*\r
+*\r
+******************************************************************/\r
+void SH5001_FIFO_Read_Data(unsigned char *fifoReadData, unsigned short int fifoDataLength)\r
+{\r
+ if(fifoDataLength == 0)\r
+ {\r
+ return;\r
+ } \r
+ \r
+ if(fifoDataLength > 1024U)\r
+ {\r
+ fifoDataLength = 1024U;\r
+ } \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_FIFO_DATA, fifoDataLength, fifoReadData);\r
+ /*\r
+ while(fifoDataLength--)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_FIFO_DATA, 1, fifoReadData);\r
+ fifoReadData++;\r
+ } \r
+ */\r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: reset Mater I2C;\r
+*\r
+* Parameters: void\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_MI2C_Reset(void)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ regData |= 0x80U;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ regData &= 0x7FU;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data); \r
+ \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.master I2C config;\r
+* 2.master I2C clock frequency is (1MHz/(6+3*mi2cFreq));\r
+* 3.mi2cSlaveAddr: slave device address, 7 bits;\r
+*\r
+*\r
+* Parameters: mi2cReadMode mi2cODR mi2cFreq\r
+* SH5001_MI2C_READ_MODE_AUTO SH5001_MI2C_READ_ODR_200HZ <=15\r
+* SH5001_MI2C_READ_MODE_MANUAL SH5001_MI2C_READ_ODR_100HZ\r
+* SH5001_MI2C_READ_ODR_50HZ \r
+* SH5001_MI2C_READ_ODR_25HZ \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_MI2C_Bus_Config( unsigned char mi2cReadMode,\r
+ unsigned char mi2cODR,\r
+ unsigned char mi2cFreq)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ if(mi2cFreq > 15U)\r
+ {\r
+ mi2cFreq = 15U;\r
+ }\r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF1, 1, ®Data);\r
+ regData = (regData & 0xC0U) | (mi2cODR & 0x30U) | mi2cFreq;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF1, 1, ®Data); \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ regData = (regData & 0xBFU) | mi2cReadMode;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.master I2C address and command config;\r
+* 2.mi2cSlaveAddr: slave device address, 7 bits;\r
+*\r
+* Parameters: mi2cSlaveAddr mi2cSlaveCmd mi2cReadMode\r
+* (1 Byte) (1 Byte) SH5001_MI2C_READ_MODE_AUTO\r
+* SH5001_MI2C_READ_MODE_MANUAL\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_MI2C_Cmd_Config( unsigned char mi2cSlaveAddr,\r
+ unsigned char mi2cSlaveCmd,\r
+ unsigned char mi2cReadMode)\r
+{\r
+ unsigned char regData = 0; \r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ regData = (regData & 0xBFU) | mi2cReadMode;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CMD0, 1, ®Data);\r
+ regData |= (mi2cSlaveAddr << 1U);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CMD0, 1, ®Data);\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CMD1, 1, &mi2cSlaveCmd); \r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.master I2C write data fucntion;\r
+* 2.mi2cWriteData: write data;\r
+*\r
+* Parameters: mi2cWriteData\r
+* \r
+* return: SH5001_TRUE or SH5001_FALSE\r
+* \r
+******************************************************************/\r
+unsigned char SH5001_MI2C_Write(unsigned char mi2cWriteData)\r
+{\r
+ unsigned char regData = 0; \r
+ unsigned char i = 0;\r
+\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_WR, 1, &mi2cWriteData);\r
+ \r
+ //Master I2C enable, write-operation\r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ regData = (regData & 0xFCU) | 0x02U;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ \r
+ // wait write-operation to end\r
+ while(i++ < 20U)\r
+ { \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ if(regData & 0x30U)\r
+ break;\r
+ }\r
+ \r
+ if((regData & 0x30U) == SH5001_MI2C_SUCCESS)\r
+ {\r
+ return (SH5001_TRUE); \r
+ } \r
+ else\r
+ {\r
+ return (SH5001_FALSE); \r
+ } \r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: 1.master I2C read data fucntion;\r
+* 2.*mi2cReadData: read data;\r
+*\r
+* Parameters: *mi2cReadData\r
+* \r
+* return: SH5001_TRUE or SH5001_FALSE\r
+* \r
+******************************************************************/\r
+unsigned char SH5001_MI2C_Read(unsigned char *mi2cReadData)\r
+{\r
+ unsigned char regData = 0; \r
+ unsigned char i = 0;\r
+ \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ if((regData & 0x40U) == 0)\r
+ { \r
+ //Master I2C enable, read-operation\r
+ regData |= 0x03U;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ }\r
+ \r
+ // wait read-operation to end\r
+ while(i++ < 20U)\r
+ { \r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ if(regData & 0x30U)\r
+ break;\r
+ } \r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_CONF0, 1, ®Data);\r
+ if((regData & 0x30U) == SH5001_MI2C_SUCCESS)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_MI2C_RD, 1, ®Data);\r
+ *mi2cReadData = regData;\r
+ \r
+ return (SH5001_TRUE); \r
+ } \r
+ else\r
+ {\r
+ return (SH5001_FALSE); \r
+ } \r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: 1.SPI interface config; Default: SH5001_SPI_4_WIRE\r
+*\r
+* Parameters: spiInterfaceMode\r
+* SH5001_SPI_3_WIRE\r
+* SH5001_SPI_4_WIRE\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_SPI_Config( unsigned char spiInterfaceMode)\r
+{\r
+ #if 0\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_SPI_CONF, 1, ®Data); \r
+ regData = (regData & 0xDFU) | spiInterfaceMode;\r
+ #endif\r
+ unsigned char regData = spiInterfaceMode;\r
+\r
+ SH5001_write(SH5001_ADDRESS, SH5001_SPI_CONF, 1, ®Data);\r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: 1.I2C interface config; Default: SH5001_I2C_EN\r
+*\r
+* Parameters: i2cInterfaceEnDis\r
+* SH5001_I2C_EN\r
+* SH5001_I2C_DIS\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_I2C_Config(unsigned char i2cInterfaceEnDis)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_I2C_CONF, 1, ®Data); \r
+ regData = (regData & 0x7FU) | i2cInterfaceEnDis;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_I2C_CONF, 1, ®Data);\r
+} \r
+\r
+\r
+\r
+// Jin\r
+/******************************************************************\r
+* Description: 1.I2C loop mode config;\r
+* 2.SH5001_I2C_LP_06BYTE: ACC_X ACC_Y ACC_Z\r
+* 3.SH5001_I2C_LP_12BYTE: ACC_X ACC_Y ACC_Z GYRO_X GYRO_Y GYRO_Z\r
+* 4.SH5001_I2C_LP_14BYTE: ACC_X ACC_Y ACC_Z GYRO_X GYRO_Y GYRO_Z TEMPERATURE\r
+*\r
+* Parameters: i2cReadLoopMode\r
+* SH5001_I2C_LP_06BYTE\r
+* SH5001_I2C_LP_12BYTE\r
+* SH5001_I2C_LP_14BYTE\r
+* SH5001_I2C_LP_DISABLE\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_I2C_LP_Config(unsigned char i2cReadLoopMode)\r
+{\r
+ unsigned char regData = 0; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_I2C_CONF, 1, ®Data); \r
+ regData = (regData & 0xF8U) | i2cReadLoopMode;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_I2C_CONF, 1, ®Data);\r
+} \r
+\r
+\r
+/******************************************************************\r
+* Description: 1.OIS SPI interface config; Default: SH5001_OIS_SPI_DIS\r
+*\r
+* Parameters: oisSpiInterfaceMode oisSpiInterfaceEnDis\r
+* SH5001_OIS_SPI_3WIRE SH5001_OIS_SPI_EN\r
+* SH5001_OIS_SPI_4WIRE SH5001_OIS_SPI_DIS\r
+*\r
+* return: void\r
+* \r
+******************************************************************/\r
+\r
+void SH5001_OIS_SPI_Config(unsigned char oisSpiInterfaceEnDis)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_OIS_SPI_CONF, 1, ®Data);\r
+ regData = (regData & 0xEFU) | oisSpiInterfaceEnDis;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_OIS_SPI_CONF, 1, ®Data);\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: 1.Switch SH5001 power mode;\r
+* 2.SH5001_NORMAL_MODE\r
+* 3.SH5001_ACC_HP_MODE\r
+* 4.SH5001_ACC_LP_MODE\r
+* 5.SH5001_POWERDOWN_MODE\r
+*\r
+* Parameters: powerMode\r
+* SH5001_NORMAL_MODE\r
+* SH5001_ACC_HP_MODE\r
+* SH5001_ACC_LP_MODE\r
+* SH5001_POWERDOWN_MODE\r
+*\r
+* return: SH5001_FALSE or SH5001_TRUE\r
+*\r
+******************************************************************/\r
+unsigned char SH5001_SwitchPowerMode(unsigned char powerMode)\r
+{\r
+\r
+ int i = 0;\r
+ unsigned char reg_addr[SH5001_POWMODE_REG_NUM] = { 0x30, 0x20, 0x2B, 0xBD, 0xD9, 0xD1, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8};\r
+ unsigned char reg_data_normal[SH5001_POWMODE_REG_NUM] = { 0x08, 0x23, 0x00, 0x0C, 0x99, 0x68, 0x00, 0x00, 0x01, 0x50, 0x00};\r
+ unsigned char reg_data_acc_hp[SH5001_POWMODE_REG_NUM] = { 0x08, 0x23, 0x01, 0x0C, 0x98, 0x6B, 0x00, 0x7A, 0xFF, 0xFC, 0x00};\r
+ unsigned char reg_data_acc_lp[SH5001_POWMODE_REG_NUM] = { 0x08, 0xA1, 0x01, 0x0E, 0x98, 0x6B, 0x90, 0xFA, 0xFF, 0xFC, 0x00};\r
+ unsigned char reg_data_powerdown[SH5001_POWMODE_REG_NUM] = { 0x08, 0xA1, 0x01, 0x0E, 0x98, 0x6B, 0xF1, 0xFE, 0xFF, 0xFC, 0xE2};\r
+ unsigned char accODR = SH5001_ACC_ODR_2000HZ;\r
+ unsigned char regData = 0;\r
+\r
+ if(powerMode > 0x03)\r
+ {\r
+ return (SH5001_FALSE);\r
+ }\r
+\r
+ switch(powerMode)\r
+ {\r
+ case SH5001_NORMAL_MODE:\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+ regData = regData & 0x7F;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF1, 1, &storeAccODR);\r
+ for(i = 0; i < SH5001_POWMODE_REG_NUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, reg_addr[i], 1, ®_data_normal[i]);\r
+ }\r
+\r
+ SH5001_DriveStart();\r
+ SH5001_ADCReset();\r
+ SH5001_CVAReset();\r
+ delay_ms(100);// or discard 10\r
+\r
+ return (SH5001_TRUE);\r
+\r
+ case SH5001_ACC_HP_MODE:\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+ regData = regData | 0x80;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF1, 1, &storeAccODR);\r
+ for(i = 0; i < SH5001_POWMODE_REG_NUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, reg_addr[i], 1, ®_data_acc_hp[i]);\r
+ }\r
+\r
+ delay_ms(30); // or discard 2\r
+\r
+ return (SH5001_TRUE);\r
+\r
+ case SH5001_ACC_LP_MODE:\r
+\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+ regData = regData & 0x7F;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+\r
+ regData = (storeAccODR & 0xF0) | accODR;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF1, 1, ®Data);\r
+ for(i = 0; i < SH5001_POWMODE_REG_NUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, reg_addr[i], 1, ®_data_acc_lp[i]);\r
+ }\r
+\r
+ delay_ms(30); // or discard 2\r
+ return (SH5001_TRUE);\r
+\r
+ case SH5001_POWERDOWN_MODE:\r
+\r
+ for(i = 0; i < SH5001_POWMODE_REG_NUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, reg_addr[i], 1, ®_data_powerdown[i]);\r
+ }\r
+\r
+ return (SH5001_TRUE);\r
+\r
+ default:\r
+ return (SH5001_FALSE);\r
+ }\r
+}\r
+\r
+/******************************************************************\r
+* Description: 1. fast compensate offset\r
+*\r
+* Parameters: SH5001Positon\r
+* SH5001_X_UP\r
+* SH5001_X_DOWN\r
+* SH5001_Y_UP\r
+* SH5001_Y_DOWN\r
+* SH5001_Z_UP\r
+* SH5001_Z_DOWN\r
+*\r
+* return: SH5001_FALSE or SH5001_TRUE\r
+*\r
+******************************************************************/\r
+void SH5001_FastOffsetComp(unsigned char SH5001Positon)\r
+{\r
+ unsigned char regData = 0;\r
+ \r
+ switch(SH5001Positon)\r
+ {\r
+ case SH5001_X_UP:\r
+ regData = 0x90U;\r
+ break;\r
+ case SH5001_X_DOWN:\r
+ regData = 0x91U;\r
+ break; \r
+ case SH5001_Y_UP:\r
+ regData = 0x92U;\r
+ break;\r
+ case SH5001_Y_DOWN:\r
+ regData = 0x93U;\r
+ break; \r
+ case SH5001_Z_UP:\r
+ regData = 0x94U;\r
+ break;\r
+ case SH5001_Z_DOWN:\r
+ regData = 0x95U;\r
+ break; \r
+ default:\r
+ regData = 0x94U;\r
+ break;\r
+ }\r
+ \r
+// SH5001_write(SH5001_ADDRESS, SH5001_FAST_COMP, 1, ®Data);\r
+} \r
+\r
+\r
+#ifdef SH5001_ACTIVITY_INT\r
+\r
+void SH5001_Init_Activity_Int(void)\r
+{\r
+\r
+ unsigned char regData = 0;\r
+\r
+ SH5001_INT_Config(SH5001_INT0_LEVEL_HIGH,\r
+ SH5001_INT_LATCH, //SH5001_INT_NO_LATCH, SH5001_INT_LATCH\r
+ SH5001_INT_CLEAR_STATUS, //SH5001_INT_CLEAR_ANY, SH5001_INT_CLEAR_STATUS\r
+ 1,\r
+ SH5001_INT1_NORMAL,\r
+ SH5001_INT0_NORMAL,\r
+ SH5001_INT1_OUTPUT,\r
+ SH5001_INT0_OUTPUT);\r
+\r
+ SH5001_INT_Act_Config(SH5001_ACT_X_INT_EN,\r
+ SH5001_ACT_Y_INT_EN,\r
+ SH5001_ACT_Z_INT_EN,\r
+ 2,\r
+ 20,\r
+ SH5001_LINK_PRE_STA_NO,\r
+ SH5001_ACT_INACT_CLR_STATUS1);\r
+\r
+ SH5001_INT_Enable(SH5001_INT_ACT,\r
+ SH5001_INT_EN,\r
+ SH5001_INT_MAP_INT0);\r
+ //TODO\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+ regData = regData & 0x7F;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF2, 1, ®Data);\r
+\r
+ SH5001_read(SH5001_ADDRESS, 0xBD, 1, ®Data);\r
+ regData = (regData & 0x7F);\r
+ SH5001_write(SH5001_ADDRESS, 0xBD, 1, ®Data);\r
+}\r
+\r
+#endif\r
+\r
+#ifdef SH5001_DATA_READY_INT\r
+void SH5001_Init_Data_Ready_Int(void)\r
+{\r
+\r
+ unsigned char regData = 0;\r
+\r
+ SH5001_INT_Config(SH5001_INT0_LEVEL_HIGH,\r
+ SH5001_INT_LATCH, //SH5001_INT_NO_LATCH, SH5001_INT_LATCH\r
+ SH5001_INT_CLEAR_STATUS, //SH5001_INT_CLEAR_ANY, SH5001_INT_CLEAR_STATUS\r
+ 1,\r
+ SH5001_INT1_NORMAL,\r
+ SH5001_INT0_NORMAL,\r
+ SH5001_INT1_OUTPUT,\r
+ SH5001_INT0_OUTPUT);\r
+\r
+ SH5001_INT_Enable(SH5001_INT_ACC_READY, //SH5001_INT_GYRO_READY SH5001_INT_ACC_READY\r
+ SH5001_INT_EN,\r
+ SH5001_INT_MAP_INT0);\r
+\r
+}\r
+\r
+#endif\r
+\r
+/******************************************************************\r
+* Description: 1. SH5001 initialization FIFO\r
+* 2. INT mode\r
+* 3. Enable ACC_X, ACC_Y, ACC_Z, GYRO_X, GYRO_Y, GYRO_Z\r
+*\r
+* Parameters: void\r
+*\r
+* return: void\r
+*\r
+******************************************************************/\r
+void SH5001_InitFIFO(void)\r
+{ \r
+\r
+ SH5001_INT_Config(SH5001_INT0_LEVEL_HIGH,\r
+ SH5001_INT_LATCH, //SH5001_INT_NO_LATCH, SH5001_INT_LATCH\r
+ SH5001_INT_CLEAR_STATUS, //SH5001_INT_CLEAR_ANY, SH5001_INT_CLEAR_STATUS\r
+ 1,\r
+ SH5001_INT1_NORMAL,\r
+ SH5001_INT0_NORMAL,\r
+ SH5001_INT1_OUTPUT,\r
+ SH5001_INT0_OUTPUT);\r
+\r
+ SH5001_FIFO_Reset();\r
+\r
+ SH5001_FIFO_Freq_Config(SH5001_FIFO_ACC_DOWNS_DIS,\r
+ SH5001_FIFO_FREQ_X1_32,\r
+ SH5001_FIFO_GYRO_DOWNS_DIS,\r
+ SH5001_FIFO_FREQ_X1_32);\r
+\r
+ SH5001_FIFO_Data_Config(SH5001_FIFO_ACC_X_EN\r
+ | SH5001_FIFO_ACC_Y_EN\r
+ | SH5001_FIFO_ACC_Z_EN\r
+ | SH5001_FIFO_GYRO_X_EN\r
+ | SH5001_FIFO_GYRO_Y_EN\r
+ | SH5001_FIFO_GYRO_Z_EN,\r
+ 120);\r
+\r
+ SH5001_FIFO_Mode_Set(SH5001_FIFO_MODE_FIFO);\r
+\r
+ SH5001_INT_Enable(SH5001_INT_FIFO_WATERMARK,\r
+ SH5001_INT_EN, \r
+ SH5001_INT_MAP_INT0);\r
+\r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: 1. SH5001 read ACC_X, ACC_Y, ACC_Z, GYRO_X, GYRO_Y, GYRO_Z @FIFO\r
+* 2. clear FIFO Watermark INT\r
+*\r
+* Parameters: void\r
+*\r
+* return: void\r
+*\r
+******************************************************************/\r
+void SH5001_ReadFIFO(void)\r
+{\r
+ unsigned short fifoEntriesCount = 0;\r
+ unsigned char fifoData[SH5001_FIFO_BUFFER] = {0};\r
+ unsigned short i = 0, j = 0, dataGroup = 0;\r
+ short accData[3], gyroData[3];\r
+ unsigned char regData = 0;\r
+\r
+ // read FIFO entries count\r
+ SH5001_FIFO_Read_Status(&fifoEntriesCount);\r
+\r
+ dataGroup = (unsigned short)(fifoEntriesCount/SH5001_WATERMARK_DIV);\r
+ fifoEntriesCount = dataGroup * SH5001_WATERMARK_DIV;\r
+\r
+ SH5001_FIFO_Read_Data(fifoData, fifoEntriesCount);\r
+\r
+ // printf("fc %d\r\n", fifoEntriesCount);\r
+\r
+ for(i = 0; i < dataGroup; i++) \r
+ { \r
+ accData[0] = ((short)fifoData[j+1] << 8) | fifoData[j];\r
+ accData[1] = ((short)fifoData[j+3] << 8) | fifoData[j+2];\r
+ accData[2] = ((short)fifoData[j+5] << 8) | fifoData[j+4]; \r
+ gyroData[0] = ((short)fifoData[j+7] << 8) | fifoData[j+6];\r
+ gyroData[1] = ((short)fifoData[j+9] << 8) | fifoData[j+8];\r
+ gyroData[2] = ((short)fifoData[j+11] << 8) | fifoData[j+10]; \r
+\r
+ gyro_data.x = (float)gyroData[0];\r
+ gyro_data.y = (float)gyroData[1];\r
+ gyro_data.z = (float)gyroData[2];\r
+\r
+ // printf("%d %d %d %d %d %d\r\n", accData[0], accData[1], accData[2],gyroData[0], gyroData[1], gyroData[2]);\r
+ \r
+ j = j + SH5001_WATERMARK_DIV;\r
+ } \r
+ \r
+ \r
+ // clear INT \r
+ SH5001_INT_Read_Status01();\r
+\r
+\r
+} \r
+\r
+ #define SH5001_REGISTER_SETTING_TOTAL 18\r
+static int sh5001DumpReg(void)\r
+{\r
+ int i = 0;\r
+ int ret = 0;\r
+ uint8_t reg = 0;\r
+ uint8_t regData = 0;\r
+\r
+ //uint8_t SH5001Reg[SH5001_REGISTER_SETTING_TOTAL] = {0x20, 0x21,0x22, 0x23, 0x24, 0x25};\r
+\r
+ //uint8_t SH5001Reg[SH5001_REGISTER_SETTING_TOTAL] = {0x20, 0x21,0x22, 0x23, 0x24, 0x25, 0x40, 0x41, 0x42, 0x43, 0x66}; //FIFO wm int\r
+ uint8_t SH5001Reg[SH5001_REGISTER_SETTING_TOTAL] = {0x20, 0x21,0x22, 0x23, 0x24, 0x25,0x40, 0x41, 0x42, 0x43, 0x66, 0x4D, 0x4E, 0x54,0x55, 0x56, 0xBD}; //Activity int\r
+\r
+ //uint8_t SH3001Reg[SH3001_REGISTER_SETTING_TOTAL] = {0x28, 0x29, 0x2B, 0x23, 0x26, 0xdd}; //lpf setting\r
+ // uint8_t SH3001Reg[SH3001_REGISTER_SETTING_TOTAL] = {0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,0x2A, 0x2B};\r
+ //uint8_t SH3001Reg[SH3001_REGISTER_SETTING_TOTAL] = {0x22, 0x23, 0x24, 0x25, 0x26, 0x35,0x36,0x37, 0x38,0x39};\r
+ //uint8_t ST3001RegData[SH3001_REGISTER_SETTING_TOTAL] = {0x00,0x1F,0x00,0x2B,0x00};\r
+ //uint8_t SH3001INTFIFOReg[SH3001_REGISTER_SETTING_TOTAL] = {0x35, 0x36, 0x37, 0x38, 0x39, 0x40,0x41,0x44, 0x45,0x46, 0x47, 0x4d,0x79,0x7A,0x0F,0x8F,0x9F,0xAF};\r
+ //uint8_t SH3001Reg[SH3001_REGISTER_SETTING_TOTAL] = {0x35, 0x36, 0x37, 0x38, 0x39, 0x40,0x41,0x42, 0x43,0x44, 0x45,0x46, 0x47, 0xFE};\r
+ //uint8_t SH3001Reg[SH3001_REGISTER_SETTING_TOTAL] = {0x20, 0x21, 0x0c, 0x0d};\r
+\r
+ for( i = 0 ; i < SH5001_REGISTER_SETTING_TOTAL ; i++ )\r
+ {\r
+\r
+ //read\r
+ reg = SH5001Reg[i];\r
+\r
+ ret = SH5001_read(SH5001_ADDRESS, reg, 1, ®Data);\r
+ if(ret != 0)\r
+ {\r
+ printf("Senodia Dump Reg 0x%x read error\r\n", reg);\r
+ return -1;\r
+ }\r
+\r
+ printf("Senodia DR >>>>> 0x%x = 0x%x\r\n", reg, regData);\r
+\r
+ }\r
+\r
+\r
+ return ret;\r
+\r
+}\r
+\r
+static void SH5001_IMU_Data_Stablize(void)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ //TODO Three times maybe\r
+ //acc\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_CONF0, 1, ®Data);\r
+ regData &= 0xFE;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF0, 1, ®Data);\r
+ regData |= 0x1;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_ACC_CONF0, 1, ®Data);\r
+\r
+\r
+ //gyro\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+ regData &= 0xFE;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+ regData |= 0x1;\r
+ SH5001_write(SH5001_ADDRESS, SH5001_GYRO_CONF0, 1, ®Data);\r
+}\r
+\r
+static void SH5001_OSC_FREQ(void)\r
+{\r
+ unsigned char regData = 0;\r
+\r
+ SH5001_read(SH5001_ADDRESS, 0xDA, 1, ®Data);\r
+ if((regData & 0x07) != 0x07)\r
+ {\r
+ regData |= 0x07;\r
+ SH5001_write(SH5001_ADDRESS, 0xDA, 1, ®Data);\r
+ }\r
+\r
+}\r
+\r
+#if SENODIA_VDD_3V3\r
+short v3_acc[3] = {0};\r
+unsigned char use_otp_comp = 0;\r
+\r
+void SH5001_Get_Otpoffset(short vacc[3])\r
+{\r
+ unsigned char regData[3]={0};\r
+ unsigned char data = 0;\r
+\r
+ //entry otp read mode\r
+ data = 0x72;\r
+ SH5001_write(SH5001_ADDRESS, 0x02, 1, &data);\r
+\r
+ //read otp page\r
+ data = 0;\r
+ SH5001_read(SH5001_ADDRESS, 0x0, 1, &data);\r
+ printf("otp page data:0x%x\n", data);\r
+ if(data == 0x70){\r
+ //exit otp mode\r
+ data = 0x71;\r
+ SH5001_write(SH5001_ADDRESS, 0x03, 1, &data);\r
+\r
+ //entry otp page 2\r
+ data = 0x70;\r
+ SH5001_write(SH5001_ADDRESS, 0x05, 1, &data);\r
+\r
+ //entry otp read mode\r
+ data = 0x72;\r
+ SH5001_write(SH5001_ADDRESS, 0x02, 1, &data);\r
+\r
+ }\r
+ //otp read data\r
+ SH5001_read(SH5001_ADDRESS, 0x08, 3, regData);\r
+\r
+ //exit otp mode\r
+ data = 0x71;\r
+ SH5001_write(SH5001_ADDRESS, 0x03, 1, &data);\r
+\r
+ if(regData[0] == 0x5f && regData[1] == 0x0 && regData[2] == 0x48)\r
+ use_otp_comp = 0;\r
+ else\r
+ use_otp_comp = 1;\r
+ printf("use_otp_comp:%d\n", use_otp_comp);\r
+ vacc[0] = ((signed char)regData[0]) * 8;\r
+ vacc[1] = ((signed char)regData[1]) * 8;\r
+ vacc[2] = ((signed char)regData[2]) * 8;\r
+ printf("%d %d %d %d %d %d \r\n", regData[0], regData[1], regData[2], vacc[0], vacc[1], vacc[2]);\r
+}\r
+#endif\r
+/******************************************************************\r
+* Description: SH5001 initialization function\r
+*\r
+* Parameters: void\r
+* \r
+* return: SH5001_TRUE or SH5001_FALSE\r
+*\r
+******************************************************************/\r
+\r
+uint8_t SH5001_get_chip_id(void)\r
+{\r
+ unsigned char regData = 0;\r
+ unsigned char i = 0;\r
+\r
+ // SH5001 chipID = 0xA1; \r
+ while((regData != 0xA1U) && (i++ < 3U))\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_CHIP_ID, 1, ®Data); \r
+ if((i == 3) && (regData != 0xA1U))\r
+ {\r
+ printf("SH5001 init fail, Chip ID = 0x%x\r\n", regData);\r
+ return SH5001_FALSE;\r
+ } \r
+ }\r
+ printf("SH5001 Chip ID = 0x%x\r\n", regData);\r
+ return regData;\r
+}\r
+\r
+unsigned char SH5001_init(void) \r
+{\r
+ unsigned char regData = 0;\r
+ unsigned char i = 0;\r
+\r
+#if SH5001_SPI_3WIRE_MODE\r
+ SH5001_SPI_Config(SH5001_SPI_3_WIRE);\r
+#endif\r
+\r
+ // SH5001 chipID = 0xA1; \r
+ while((regData != 0xA1U) && (i++ < 3U))\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_CHIP_ID, 1, ®Data); \r
+ if((i == 3) && (regData != 0xA1U))\r
+ {\r
+ printf("SH5001 init fail, Chip ID = 0x%x\r\n", regData);\r
+ return SH5001_FALSE;\r
+ } \r
+ }\r
+ printf("SH5001 Chip ID = 0x%x\r\n", regData);\r
+ \r
+ // reset internal module, don't modify it\r
+ SH5001_ModuleReset(); \r
+\r
+ SH5001_OSC_FREQ();\r
+\r
+ #if SH5001_OIS_ENABLE\r
+ SH5001_OIS_SPI_Config(SH5001_OIS_SPI_EN);\r
+ #endif\r
+\r
+ // 500Hz, 16G, cut off Freq(BW)=500*0.25Hz=125Hz, enable filter;\r
+ SH5001_Acc_Config(SH5001_ACC_ODR_125HZ, \r
+ SH5001_ACC_RANGE_16G, //SH5001_ACC_RANGE_8G SH5001_ACC_RANGE_16G\r
+ SH5001_ACC_ODRX040,\r
+ SH5001_ACC_FILTER_EN,\r
+ SH5001_ACC_BYPASS_EN);\r
+\r
+ printf("SH5001 acc config ok\r\n");\r
+\r
+ // 800Hz, X\Y\Z 2000deg/s, cut off Freq(BW)=291Hz, enable filter;\r
+ SH5001_Gyro_Config( SH5001_GYRO_ODR_125HZ,\r
+ SH5001_GYRO_RANGE_2000,\r
+ SH5001_GYRO_ODRX040,\r
+ SH5001_GYRO_FILTER_EN,\r
+ SH5001_GYRO_BYPASS_EN);\r
+\r
+ SH5001_IMU_Data_Stablize();\r
+\r
+ #if SH5001_OIS_ENABLE\r
+ SH5001_Acc_OIS_Config(SH5001_ACC_OIS_ODR_1000HZ,\r
+ SH5001_ACC_OIS_RANGE_8G,\r
+ SH5001_ACC_OIS_ODRX004,\r
+ SH5001_ACC_OIS_ENABLE);\r
+\r
+ SH5001_Gyro_OIS_Config(SH5001_GYRO_OIS_ODR_8000HZ,\r
+ SH5001_GYRO_OIS_RANGE_2000,\r
+ SH5001_GYRO_OIS_ODRX004,\r
+ SH5001_GYRO_OIS_ENABLE);\r
+ #endif\r
+\r
+ #if SH5001_TS_ENABLE\r
+ SH5001_TimeStamp_Config(SH5001_TS_ODR_1KHZ, SH5001_TS_EN);\r
+ #endif\r
+\r
+ // temperature ODR is 63Hz, enable temperature measurement\r
+ SH5001_Temp_Config(SH5001_TEMP_ODR_63HZ, SH5001_TEMP_EN);\r
+\r
+ //sh5001DumpReg();\r
+ #ifdef SH5001_FIFO_WM_INT\r
+ SH5001_InitFIFO();\r
+ #endif\r
+\r
+ #ifdef SH5001_ACTIVITY_INT\r
+ SH5001_Init_Activity_Int();\r
+ #endif\r
+\r
+ #ifdef SH5001_DATA_READY_INT\r
+ SH5001_Init_Data_Ready_Int();\r
+ #endif\r
+\r
+#if SENODIA_VDD_3V3\r
+ SH5001_Get_Otpoffset(v3_acc);\r
+#endif\r
+ //sh5001DumpReg();\r
+ //sh5001DumpRegAll();\r
+\r
+ return SH5001_TRUE;\r
+}\r
+\r
+\r
+\r
+/******************************************************************\r
+* Description: Read SH5001 gyroscope and accelerometer data\r
+*\r
+* Parameters: accData[3]: acc X,Y,Z; gyroData[3]: gyro X,Y,Z;\r
+* \r
+* return: void\r
+* \r
+******************************************************************/\r
+void SH5001_GetImuData( short accData[3], short gyroData[3] )\r
+{\r
+ unsigned char regData[12]={0}; \r
+ \r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_XL, 12, regData); \r
+ \r
+ accData[0] = ((short)regData[1] << 8) | regData[0];\r
+ accData[1] = ((short)regData[3] << 8) | regData[2];\r
+ accData[2] = ((short)regData[5] << 8) | regData[4]; \r
+ \r
+ gyroData[0] = ((short)regData[7] << 8) | regData[6];\r
+ gyroData[1] = ((short)regData[9] << 8) | regData[8];\r
+ gyroData[2] = ((short)regData[11] << 8) | regData[10];\r
+\r
+#if SENODIA_VDD_3V3\r
+ if(use_otp_comp){\r
+ accData[0] -= v3_acc[0];\r
+ accData[1] -= v3_acc[1];\r
+ accData[2] -= v3_acc[2];\r
+ }\r
+#endif\r
+\r
+ printf("%d %d %d %d %d %d\r\n", accData[0], accData[1], accData[2], gyroData[0], gyroData[1], gyroData[2]);\r
+}\r
+\r
+void SH5001_OIS_GetTS(int timestamp[1])\r
+{\r
+ unsigned char regData[3]={0};\r
+\r
+ SH5001_read(SH5001_ADDRESS, 0xE, 3, regData);\r
+\r
+ timestamp[0] = ((int)regData[2] << 16) | ((int)regData[1] << 8) | regData[0];\r
+\r
+}\r
+\r
+#if SH5001_OIS_ENABLE\r
+void SH5001_OIS_GetImuData( short accData[3], short gyroData[3] )\r
+{\r
+ unsigned char regData[12]={0};\r
+ int i = 0;\r
+\r
+ SH5001_OIS_read(SH5001_ADDRESS, SH5001_ACC_XL, 12, regData);\r
+\r
+ accData[0] = ((short)regData[1] << 8) | regData[0];\r
+ accData[1] = ((short)regData[3] << 8) | regData[2];\r
+ accData[2] = ((short)regData[5] << 8) | regData[4];\r
+\r
+ gyroData[0] = ((short)regData[7] << 8) | regData[6];\r
+ gyroData[1] = ((short)regData[9] << 8) | regData[8];\r
+ gyroData[2] = ((short)regData[11] << 8) | regData[10];\r
+\r
+ //printf("%d %d %d %d %d %d\r\n", accData[0], accData[1], accData[2], gyroData[0], gyroData[1], gyroData[2]);\r
+}\r
+#endif\r
+\r
+#define SH5001_OFFSET_REG_NUM 13\r
+void offset_comp_save_reg(float offset[3])\r
+{\r
+ unsigned char offsetData[SH5001_OFFSET_REG_NUM] = {0};\r
+\r
+ short offset_otp[3] = {0};\r
+ short gain_otp[3] = {0};\r
+ unsigned int range = 1;\r
+\r
+ int offset_temp[3] = {0};\r
+ short offset_new[3] = {0};\r
+ unsigned short s_offset_new[3] = {0};\r
+\r
+ unsigned char i;\r
+\r
+\r
+ unsigned char offsetRegister[SH5001_OFFSET_REG_NUM] = { 0x8C, 0x8D, 0x8E, 0x8F, 0x98, 0x99, 0x9A, 0x9B, 0xA4, 0xA5 , 0xA6,\r
+ 0xA7, 0x24};\r
+\r
+ for(i=0; i<SH5001_OFFSET_REG_NUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, offsetRegister[i], 1, &offsetData[i]);\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("0x%x = 0x%x\r\n", offsetRegister[i], offsetData[i]);\r
+ #endif\r
+ }\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("n offset %f %f %f \r\n", offset[0], offset[1],offset[2]);\r
+ #endif\r
+\r
+ offset_otp[0] = ((short)offsetData[3] << 8) | offsetData[2];\r
+ offset_otp[1] = ((short)offsetData[7] << 8) | offsetData[6];\r
+ offset_otp[2] = ((short)offsetData[11] << 8) | offsetData[10];\r
+\r
+ gain_otp[0] = ((short)offsetData[1] << 8) | offsetData[0];\r
+ gain_otp[1] = ((short)offsetData[5] << 8) | offsetData[4];\r
+ gain_otp[2] = ((short)offsetData[9] << 8) | offsetData[8];\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("offset_otp %d %d %d \r\n", offset_otp[0], offset_otp[1],offset_otp[2]);\r
+ printf("gain_otp %d %d %d \r\n", gain_otp[0], gain_otp[1],gain_otp[2]);\r
+ #endif\r
+\r
+ offsetData[12] = (offsetData[12] & 0x70) >> 4;\r
+\r
+ if(offsetData[12] != 0)\r
+ {\r
+ for(i=0; i < offsetData[12] + 7; i++)\r
+ {\r
+ range = range * 2;\r
+ }\r
+ }\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("range %d \r\n", range);\r
+ #endif\r
+\r
+ for(i = 0; i < 3; i++)\r
+ {\r
+ offset_temp[i] = offset_otp[i] + (int)(offset[i] * ((float)range) / ((float)gain_otp[i])); //\r
+ //offset_new[i] = offset_otp[i] + (offset[i] * range / gain_otp[i]); //\r
+ }\r
+\r
+ if(offset_temp[0] > 32767)\r
+ offset_temp[0] = 32767;\r
+ else if(offset_temp[0] < -32768)\r
+ offset_temp[0] = -32768;\r
+ if(offset_temp[1] > 32767)\r
+ offset_temp[1] = 32767;\r
+ else if(offset_temp[1] < -32768)\r
+ offset_temp[1] = -32768;\r
+ if(offset_temp[2] > 32767)\r
+ offset_temp[2] = 32767;\r
+ else if(offset_temp[2] < -32768)\r
+ offset_temp[2] = -32768;\r
+\r
+ offset_new[0] = (short)offset_temp[0];\r
+ offset_new[1] = (short)offset_temp[1];\r
+ offset_new[2] = (short)offset_temp[2];\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("offset_new %d %d %d \r\n", offset_new[0], offset_new[1],offset_new[2]);\r
+ #endif\r
+\r
+ s_offset_new[0] = (unsigned short)offset_new[0];\r
+ s_offset_new[1] = (unsigned short)offset_new[1];\r
+ s_offset_new[2] = (unsigned short)offset_new[2];\r
+\r
+ offsetData[3] = (unsigned char)((s_offset_new[0] & 0xFF00)>>8);\r
+ offsetData[7] = (unsigned char)((s_offset_new[1] & 0xFF00)>>8);\r
+ offsetData[11] = (unsigned char)((offset_new[2] & 0xFF00)>>8);\r
+ offsetData[2] = (unsigned char)((s_offset_new[0] & 0x00FF));\r
+ offsetData[6] = (unsigned char)((s_offset_new[1] & 0x00FF));\r
+ offsetData[10] = (unsigned char)((s_offset_new[2] & 0x00FF));\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("offsetData %x %x %x %x %x %x\r\n", offsetData[2], offsetData[3],offsetData[6], offsetData[7], offsetData[10], offsetData[11]);\r
+ #endif\r
+\r
+ SH5001_write(SH5001_ADDRESS, 0x8E, 1, &offsetData[2]);\r
+ SH5001_write(SH5001_ADDRESS, 0x8F, 1, &offsetData[3]);\r
+ SH5001_write(SH5001_ADDRESS, 0x9A, 1, &offsetData[6]);\r
+ SH5001_write(SH5001_ADDRESS, 0x9B, 1, &offsetData[7]);\r
+ SH5001_write(SH5001_ADDRESS, 0xA6, 1, &offsetData[10]);\r
+ SH5001_write(SH5001_ADDRESS, 0xA7, 1, &offsetData[11]);\r
+\r
+ //for test\r
+ #if 0\r
+ for(i=0; i<SH5001_OFFSET_REG_NUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, offsetRegister[i], 1, &offsetData[i]);\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("read back 0x%x = 0x%x\r\n", offsetRegister[i], offsetData[i]);\r
+ #endif\r
+ }\r
+ #endif\r
+}\r
+\r
+#define SH5001_TEMPCOMP_REG_NUM 10\r
+void temp_comp_save_reg(float k[3])\r
+{\r
+ unsigned char tempCompData[SH5001_OFFSET_REG_NUM] = {0};\r
+\r
+ signed char beta_otp[3] = {0};\r
+ short gain_otp[3] = {0};\r
+ unsigned int range = 1;\r
+\r
+ unsigned char beta_new[3] = {0};\r
+ signed char s_beta_new[3] = {0};\r
+ int s_beta_temp[3] = {0};\r
+\r
+ unsigned char i;\r
+\r
+ unsigned char tempCompRegister[SH5001_OFFSET_REG_NUM] = { 0x8C, 0x8D, 0x98, 0x99, 0xA4, 0xA5 , 0x92,0x9e,0xAA, 0x24};\r
+\r
+ for(i=0; i<SH5001_TEMPCOMP_REG_NUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, tempCompRegister[i], 1, &tempCompData[i]);\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("0x%x = 0x%x\r\n", tempCompRegister[i], tempCompData[i]);\r
+ #endif\r
+ }\r
+\r
+ for(i=0; i<3; i++)\r
+ {\r
+ k[i] = k[i] * 16.4 / 14.0; // deg/c to lsb/lsb range2000dps\r
+ }\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("k %f %f %f \r\n", k[0], k[1],k[2]);\r
+ #endif\r
+\r
+ gain_otp[0] = ((short)tempCompData[1] << 8) | tempCompData[0];\r
+ gain_otp[1] = ((short)tempCompData[3] << 8) | tempCompData[2];\r
+ gain_otp[2] = ((short)tempCompData[5] << 8) | tempCompData[4];\r
+\r
+ //TODO unsigned to signed\r
+ beta_otp[0] = ((signed char)tempCompData[6]);\r
+ beta_otp[1] = ((signed char)tempCompData[7]);\r
+ beta_otp[2] = ((signed char)tempCompData[8]);\r
+\r
+ tempCompData[9] = (tempCompData[9] & 0x70) >> 4;\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("gain_otp %d %d %d \r\n", gain_otp[0], gain_otp[1],gain_otp[2]);\r
+ printf("temp_otp %d %d %d \r\n", beta_otp[0], beta_otp[1],beta_otp[2]);\r
+ printf("range 0x%x \r\n", tempCompData[9]);\r
+ #endif\r
+\r
+ if(tempCompData[9] != 0)\r
+ {\r
+ for(i=0; i < tempCompData[9] + 14; i++)\r
+ {\r
+ range = range * 2;\r
+ }\r
+ }\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("range222 %d \r\n", range);\r
+ #endif\r
+ //TODO\r
+ for(i = 0; i < 3; i++)\r
+ {\r
+ s_beta_temp[i] = beta_otp[i] - (int)(k[i] * ((float)range) / ((float)gain_otp[i]));\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("beta_ 111 %f %d\r\n", k[i] * range / gain_otp[i], (int)(k[i] * range / gain_otp[i]));\r
+ #endif\r
+ }\r
+\r
+ if(s_beta_temp[0] > 127)\r
+ s_beta_temp[0] = 127;\r
+ else if(s_beta_temp[0] < -128)\r
+ s_beta_temp[0] = -128;\r
+ if(s_beta_temp[1] > 127)\r
+ s_beta_temp[1] = 127;\r
+ else if(s_beta_temp[1] < -128)\r
+ s_beta_temp[1] = -128;\r
+ if(s_beta_temp[2] > 127)\r
+ s_beta_temp[2] = 127;\r
+ else if(s_beta_temp[2] < -128)\r
+ s_beta_temp[2] = -128;\r
+\r
+ s_beta_new[0] = (char)s_beta_temp[0];\r
+ s_beta_new[1] = (char)s_beta_temp[1];\r
+ s_beta_new[2] = (char)s_beta_temp[2];\r
+\r
+ beta_new[0] = (unsigned char)s_beta_new[0];\r
+ beta_new[1] = (unsigned char)s_beta_new[1];\r
+ beta_new[2] = (unsigned char)s_beta_new[2];\r
+\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("s_beta_new %d %d %d \r\n", s_beta_new[0], s_beta_new[1],s_beta_new[2]);\r
+ printf("beta_new %x %x %x \r\n", beta_new[0], beta_new[1],beta_new[2]);\r
+ #endif\r
+\r
+ SH5001_write(SH5001_ADDRESS, 0x92, 1, &beta_new[0]);\r
+ SH5001_write(SH5001_ADDRESS, 0x9e, 1, &beta_new[1]);\r
+ SH5001_write(SH5001_ADDRESS, 0xAA, 1, &beta_new[2]);\r
+}\r
+\r
+#define SH5001_ACC_REG_NUM 4\r
+void acc_temp_comp_save_reg(float k[3])\r
+{\r
+ unsigned char tempCompData[SH5001_ACC_REG_NUM] = {0};\r
+ signed char beta_otp[3] = {0};\r
+ short gain_otp[3] = {0};\r
+ unsigned int range = 1;\r
+ float rangek = 1;\r
+ unsigned char beta_new[3] = {0};\r
+ signed char s_beta_new[3] = {0};\r
+ int s_beta_temp[3] = {0};\r
+ unsigned char i;\r
+ unsigned char tempCompRegister[SH5001_ACC_REG_NUM] = {0x71, 0x7c, 0x88, 0x21};\r
+ for(i=0; i<SH5001_ACC_REG_NUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, tempCompRegister[i], 1, &tempCompData[i]);\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("0x%x = 0x%x\r\n", tempCompRegister[i], tempCompData[i]);\r
+ #endif\r
+ }\r
+ beta_otp[0] = ((signed char)tempCompData[0]);\r
+ beta_otp[1] = ((signed char)tempCompData[1]);\r
+ beta_otp[2] = ((signed char)tempCompData[2]);\r
+ tempCompData[3] = (tempCompData[3] & 0x70) >> 4;\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("temp_otp %d %d %d \r\n", beta_otp[0], beta_otp[1],beta_otp[2]);\r
+ printf("range 0x%x \r\n", tempCompData[3]);\r
+ #endif\r
+ if(tempCompData[3] != 0)\r
+ {\r
+ for(i=0; i < 6 - tempCompData[3]; i++)\r
+ {\r
+ range = range * 2;\r
+ }\r
+ }\r
+ for(i=0; i<3; i++)\r
+ {\r
+ k[i] = k[i] * range * 2.048 / 14;\r
+ }\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("k %f %f %f \r\n", k[0], k[1],k[2]);\r
+ #endif\r
+ if(tempCompData[3] != 0)\r
+ {\r
+ for(i=0; i < tempCompData[3] + 1; i++)\r
+ {\r
+ rangek = rangek * 2;\r
+ }\r
+ }\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("range222 %f \r\n", rangek);\r
+ #endif\r
+ for(i = 0; i < 3; i++)\r
+ {\r
+ s_beta_temp[i] = beta_otp[i] - (int)(k[i] * rangek);\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("beta_111 %f %d\r\n", k[i] * rangek , (int)(k[i] * rangek));\r
+ #endif\r
+ }\r
+ if(s_beta_temp[0] > 127)\r
+ s_beta_temp[0] = 127;\r
+ else if(s_beta_temp[0] < -128)\r
+ s_beta_temp[0] = -128;\r
+ if(s_beta_temp[1] > 127)\r
+ s_beta_temp[1] = 127;\r
+ else if(s_beta_temp[1] < -128)\r
+ s_beta_temp[1] = -128;\r
+ if(s_beta_temp[2] > 127)\r
+ s_beta_temp[2] = 127;\r
+ else if(s_beta_temp[2] < -128)\r
+ s_beta_temp[2] = -128;\r
+ s_beta_new[0] = (char)s_beta_temp[0];\r
+ s_beta_new[1] = (char)s_beta_temp[1];\r
+ s_beta_new[2] = (char)s_beta_temp[2];\r
+ beta_new[0] = (unsigned char)s_beta_new[0];\r
+ beta_new[1] = (unsigned char)s_beta_new[1];\r
+ beta_new[2] = (unsigned char)s_beta_new[2];\r
+ #ifdef SH5001_OT_DEBUG\r
+ printf("s_beta_new %d %d %d \r\n", s_beta_new[0], s_beta_new[1],s_beta_new[2]);\r
+ printf("beta_new %x %x %x \r\n", beta_new[0], beta_new[1],beta_new[2]);\r
+ #endif\r
+ SH5001_write(SH5001_ADDRESS, 0x71, 1, &beta_new[0]);\r
+ SH5001_write(SH5001_ADDRESS, 0x7c, 1, &beta_new[1]);\r
+ SH5001_write(SH5001_ADDRESS, 0x88, 1, &beta_new[2]);\r
+}\r
+\r
+#define SH5001_QUAD_REG_NUM 10\r
+#define SH5001_QUAD_DEBUG\r
+\r
+void sh5001_gyro_trim_quad(unsigned char quadval[6])\r
+{\r
+ short S_Gyro_Quad[3] = {0};\r
+ short C_Gyro_Quad[3] = {0};\r
+ unsigned char quadData[SH5001_QUAD_REG_NUM] = {0};\r
+ int sumGyroData[3] = {0};\r
+ short avgGyroData[3] = {0};\r
+ short GyroData[3] = {0};\r
+ unsigned char temp[6]= {0};\r
+ unsigned char i;\r
+ double Slope[3] = {560, 560, 560};\r
+\r
+ unsigned char quadRegister[SH5001_QUAD_REG_NUM] = {0x8B, 0x97, 0xA3, 0xD9, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC};\r
+ unsigned char RegWrt_1[SH5001_QUAD_REG_NUM] = {0xFF, 0xFF, 0xFF, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+\r
+ for(i=0; i<SH5001_QUAD_REG_NUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, quadRegister[i], 1, &quadData[i]);\r
+ #ifdef SH5001_QUAD_DEBUG\r
+ printf("quadRegister RegWrt_1 raw 0x%x:0x%x\r\n",quadRegister[i], quadData[i]);\r
+ #endif\r
+ }\r
+\r
+ for(i=0; i<4; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, quadRegister[i], 1, &RegWrt_1[i]);\r
+ }\r
+\r
+ delay_ms(80);\r
+\r
+ for(i=20; i>0; i--)\r
+ {\r
+ delay_ms(1);\r
+\r
+ SH5001_read(SH5001_ADDRESS, 0x06, 6, temp);\r
+ GyroData[0]=((short)(temp[1]<<8))|temp[0];\r
+ GyroData[1]=((short)(temp[3]<<8))|temp[2];\r
+ GyroData[2]=((short)(temp[5]<<8))|temp[4];\r
+\r
+ sumGyroData[0] += GyroData[0];\r
+ sumGyroData[1] += GyroData[1];\r
+ sumGyroData[2] += GyroData[2];\r
+\r
+ #ifdef SH5001_QUAD_DEBUG\r
+ printf("sumGyroData %d %d %d\r\n",GyroData[0], GyroData[1], GyroData[2]);\r
+ #endif\r
+ }\r
+\r
+ for(i = 0; i < 3; i++)\r
+ {\r
+ avgGyroData[i] = sumGyroData[i] / 20;\r
+ }\r
+\r
+ #ifdef SH5001_QUAD_DEBUG\r
+ printf("avgGyroData %d %d %d\r\n",avgGyroData[0], avgGyroData[1], avgGyroData[2]);\r
+ #endif\r
+\r
+ for (i = 0; i < 3; i++)\r
+ {\r
+ S_Gyro_Quad[i] = (quadData[i + 7] & 0x04) >> 2;\r
+ C_Gyro_Quad[i] = quadData[i + 4] + (quadData[i + 7] & 0x03) * 256;\r
+\r
+ #ifdef SH5001_QUAD_DEBUG\r
+ printf("raw S_Gyro_Quad[%d] : %d C_Gyro_Quad[%d]: %d \r\n",i, S_Gyro_Quad[i], i, C_Gyro_Quad[i]);\r
+ #endif\r
+\r
+ C_Gyro_Quad[i] = (S_Gyro_Quad[i] == 0) ? C_Gyro_Quad[i]: (C_Gyro_Quad[i] * (-1) - 1);\r
+ C_Gyro_Quad[i] = (int)(C_Gyro_Quad[i] - avgGyroData[i] / Slope[i]);\r
+\r
+ S_Gyro_Quad[i] = C_Gyro_Quad[i] >= 0 ? 0 : 1;\r
+ C_Gyro_Quad[i] = C_Gyro_Quad[i] >= 0 ? C_Gyro_Quad[i]: (C_Gyro_Quad[i] * (-1) - 1);\r
+\r
+ RegWrt_1[i + 4] = C_Gyro_Quad[i] & 0x00FF;\r
+ RegWrt_1[i + 7] = (quadData[i + 7] & 0xF8) + S_Gyro_Quad[i] * 4 + ((C_Gyro_Quad[i] & 0x0300) >> 8);\r
+\r
+ }\r
+ #ifdef SH5001_QUAD_DEBUG\r
+ printf("mod S_Gyro_Quad %d %d %d C_Gyro_Quad %d %d %d RegWrt_1 %d %d %d %d %d %d\r\n",S_Gyro_Quad[0],\r
+ S_Gyro_Quad[1],S_Gyro_Quad[2],C_Gyro_Quad[0],C_Gyro_Quad[1],C_Gyro_Quad[2], RegWrt_1[4], RegWrt_1[5], RegWrt_1[6], RegWrt_1[7], RegWrt_1[8], RegWrt_1[9]);\r
+ #endif\r
+\r
+\r
+ //TODO Save Reg\r
+ for(i=0; i<6; i++) {\r
+ SH5001_write(SH5001_ADDRESS, quadRegister[i + 4], 1, &RegWrt_1[i + 4]);\r
+ quadval[i] = RegWrt_1[i + 4];\r
+ }\r
+\r
+ for(i=0; i<4; i++)\r
+ SH5001_write(SH5001_ADDRESS, quadRegister[i], 1, &quadData[i]);\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: SH5001 Acc self-test function\r
+*\r
+* Parameters: void\r
+*\r
+* return: SH3001_TRUE or SH3001_FALSE\r
+*\r
+******************************************************************/\r
+\r
+#define SH5001_ACC_SELFTEST_REGNUM 7\r
+#define SH5001_ACC_SELFTEST_DEBUG\r
+\r
+unsigned char SH5001_AccSelfTest(void)\r
+{\r
+ unsigned char regAddr[SH5001_ACC_SELFTEST_REGNUM] = {0x21, 0x69, 0x74, 0x80, 0xB9, 0xBA, 0xBB};\r
+ unsigned char regInit[SH5001_ACC_SELFTEST_REGNUM] = {0x30, 0xFF, 0xFF, 0xFF, 0x40, 0x45, 0x45};\r
+ unsigned char regBack[SH5001_ACC_SELFTEST_REGNUM] = {0};\r
+ unsigned char accTemp[6] = {0};\r
+ signed int accSum[3] = {0};\r
+ signed short accAvg1[3] = {0}, accAvg2[3] = {0};\r
+ unsigned char i = 0;\r
+ signed short accRange[3] = {0};\r
+\r
+\r
+ for(i=0; i<SH5001_ACC_SELFTEST_REGNUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, regAddr[i], 1, ®Back[i]);\r
+ }\r
+\r
+ for(i=0; i<SH5001_ACC_SELFTEST_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddr[i], 1, ®Init[i]);\r
+ }\r
+\r
+ delay_ms(100);\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_XL, 6, accTemp);\r
+ accSum[0] += ((short)accTemp[1] << 8) | accTemp[0];\r
+ accSum[1] += ((short)accTemp[3] << 8) | accTemp[2];\r
+ accSum[2] += ((short)accTemp[5] << 8) | accTemp[4];\r
+\r
+ #ifdef SH5001_ACC_SELFTEST_DEBUG\r
+ printf("bf %d %d %d\r\n", ((short)accTemp[1] << 8) | accTemp[0], ((short)accTemp[3] << 8) | accTemp[2], ((short)accTemp[5] << 8) | accTemp[4]);\r
+ #endif\r
+ }\r
+ accAvg1[0] = accSum[0]/20;\r
+ accAvg1[1] = accSum[1]/20;\r
+ accAvg1[2] = accSum[2]/20;\r
+\r
+\r
+ accTemp[0] = 0x60;\r
+ SH5001_write(SH5001_ADDRESS, 0xB9, 1, &accTemp[0]);\r
+ accTemp[0] = 0x65;\r
+ SH5001_write(SH5001_ADDRESS, 0xBA, 1, &accTemp[0]);\r
+ accTemp[0] = 0x65;\r
+ SH5001_write(SH5001_ADDRESS, 0xBB, 1, &accTemp[0]);\r
+\r
+ delay_ms(100);\r
+\r
+ accSum[0] = 0;\r
+ accSum[1] = 0;\r
+ accSum[2] = 0;\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_ACC_XL, 6, accTemp);\r
+ accSum[0] += ((short)accTemp[1] << 8) | accTemp[0];\r
+ accSum[1] += ((short)accTemp[3] << 8) | accTemp[2];\r
+ accSum[2] += ((short)accTemp[5] << 8) | accTemp[4];\r
+ #ifdef SH5001_ACC_SELFTEST_DEBUG\r
+ printf("af %d %d %d\r\n", ((short)accTemp[1] << 8) | accTemp[0], ((short)accTemp[3] << 8) | accTemp[2], ((short)accTemp[5] << 8) | accTemp[4]);\r
+ #endif\r
+ }\r
+ accAvg2[0] = accSum[0]/20;\r
+ accAvg2[1] = accSum[1]/20;\r
+ accAvg2[2] = accSum[2]/20;\r
+\r
+\r
+ for(i=0; i<SH5001_ACC_SELFTEST_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddr[i], 1, ®Back[i]);\r
+ }\r
+\r
+ accRange[0] = accAvg2[0] - accAvg1[0];\r
+ accRange[1] = accAvg2[1] - accAvg1[1];\r
+ accRange[2] = accAvg2[2] - accAvg1[2];\r
+\r
+ #ifdef SH5001_ACC_SELFTEST_DEBUG\r
+ printf("accdiff %d %d %d\r\n", accRange[0],accRange[1] ,accRange[2]);\r
+ #endif\r
+\r
+ if(((accRange[0] > 3900) && (accRange[0] < 9200))\r
+ && ((accRange[1] > 4100) && (accRange[1] < 9600))\r
+ && ((accRange[2] > 4500) && (accRange[2] < 10900)))\r
+ {\r
+ return(SH5001_TRUE);\r
+ }\r
+ else\r
+ {\r
+ return(SH5001_FALSE);\r
+ }\r
+}\r
+\r
+\r
+/******************************************************************\r
+* Description: SH5001 Gyro self-test function\r
+*\r
+* Parameters: void\r
+*\r
+* return: SH3001_TRUE or SH3001_FALSE\r
+*\r
+******************************************************************/\r
+\r
+#define SH5001_GYRO_SELFTEST_REGNUM 11\r
+#define SH5001_GYRO_SELFTEST_DEBUG\r
+\r
+unsigned char SH5001_GyroSelfTest(void)\r
+{\r
+ unsigned char regAddr[SH5001_GYRO_SELFTEST_REGNUM] = {0x24, 0x8B, 0x97, 0xA3, 0xCA, 0xCB, 0xCC, 0xCD,\\r
+ 0xCE, 0xCF, 0xD9};\r
+ unsigned char regInit[SH5001_GYRO_SELFTEST_REGNUM] = {0x60, 0xFF, 0xFF, 0xFF, 0x60, 0x60, 0x60, 0x02,\\r
+ 0x02, 0x02, 0x91};\r
+ unsigned char regBack[SH5001_GYRO_SELFTEST_REGNUM] = {0};\r
+ unsigned char gyroTemp[6] = {0};\r
+ signed int gyroSum[3] = {0};\r
+ signed short gyroAvg1[3] = {0}, gyroAvg2[3] = {0};\r
+ unsigned char i = 0;\r
+ signed short gyroRange[3] = {0};\r
+\r
+ for(i=0; i<SH5001_GYRO_SELFTEST_REGNUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, regAddr[i], 1, ®Back[i]);\r
+ }\r
+\r
+ for(i=0; i<SH5001_GYRO_SELFTEST_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddr[i], 1, ®Init[i]);\r
+ }\r
+\r
+ //Gyro x\r
+ gyroTemp[0] = 0x15;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, &gyroTemp[0]);\r
+\r
+ delay_ms(50);\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_XL, 2, gyroTemp);\r
+ gyroSum[0] += ((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gx bf %d \r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]));\r
+ #endif\r
+ }\r
+ gyroAvg1[0] = gyroSum[0]/20;\r
+\r
+ gyroTemp[0] = 0x14;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, &gyroTemp[0]);\r
+\r
+ delay_ms(50);\r
+\r
+ gyroSum[0] = 0;\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_XL, 2, gyroTemp);\r
+ gyroSum[0] += ((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gx af %d \r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]));\r
+ #endif\r
+ }\r
+ gyroAvg2[0] = gyroSum[0]/20;\r
+\r
+ //gyro y\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x15;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, &gyroTemp[0]);\r
+\r
+ delay_ms(50);\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_YL, 2, gyroTemp);\r
+ gyroSum[1] += ((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gy bf %d \r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]));\r
+ #endif\r
+ }\r
+ gyroAvg1[1] = gyroSum[1]/20;\r
+\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x14;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, &gyroTemp[0]);\r
+\r
+ delay_ms(50);\r
+\r
+ gyroSum[1] = 0;\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_YL, 2, gyroTemp);\r
+ gyroSum[1] += ((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gy af %d \r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]));\r
+ #endif\r
+\r
+ }\r
+ gyroAvg2[1] = gyroSum[1]/20;\r
+\r
+ //gyro z\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x15;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, &gyroTemp[0]);\r
+\r
+ delay_ms(50);\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_ZL, 2, gyroTemp);\r
+ gyroSum[2] += ((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gz bf %d \r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]));\r
+ #endif\r
+ }\r
+ gyroAvg1[2] = gyroSum[2]/20;\r
+\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCD, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x02;\r
+ SH5001_write(SH5001_ADDRESS, 0xCE, 1, &gyroTemp[0]);\r
+ gyroTemp[0] = 0x14;\r
+ SH5001_write(SH5001_ADDRESS, 0xCF, 1, &gyroTemp[0]);\r
+\r
+ delay_ms(50);\r
+\r
+ gyroSum[2] = 0;\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_ZL, 2, gyroTemp);\r
+ gyroSum[2] += ((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gz af %d\r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]));\r
+ #endif\r
+ }\r
+ gyroAvg2[2] = gyroSum[2]/20;\r
+\r
+ for(i=0; i<SH5001_GYRO_SELFTEST_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddr[i], 1, ®Back[i]);\r
+ }\r
+\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("G b average %d %d %d\r\n", gyroAvg1[0],gyroAvg1[1] ,gyroAvg1[2]);\r
+ printf("G a average %d %d %d\r\n", gyroAvg2[0],gyroAvg2[1] ,gyroAvg2[2]);\r
+ #endif\r
+\r
+ gyroRange[0] = gyroAvg2[0] - gyroAvg1[0];\r
+ gyroRange[1] = gyroAvg2[1] - gyroAvg1[1];\r
+ gyroRange[2] = gyroAvg2[2] - gyroAvg1[2];\r
+\r
+ #ifdef SH5001_GYRO_SELFTEST_DEBUG\r
+ printf("Gyro diff %d %d %d\r\n", gyroRange[0],gyroRange[1] ,gyroRange[2]);\r
+ #endif\r
+\r
+ if(((gyroRange[0] > -4500) && (gyroRange[0] < 7100))\r
+ && ((gyroRange[1] > -6900) && (gyroRange[1] < 8200))\r
+ && ((gyroRange[2] > -9300) && (gyroRange[2] < 4600)))\r
+ {\r
+ return(SH5001_TRUE);\r
+ }\r
+ else\r
+ {\r
+ return(SH5001_FALSE);\r
+ }\r
+}\r
+\r
+void sh5001_adc_phase(void)\r
+{\r
+ unsigned char addr = 0xD0;\r
+ unsigned char regData;\r
+\r
+ SH5001_read(SH5001_ADDRESS, addr, 1, ®Data);\r
+ //printf("0xD0 = 0x%x\r\n", regData);\r
+\r
+ if((regData & 0x02) == 0x02)\r
+ regData &= 0xFD;\r
+ else\r
+ regData |= 0x02;\r
+ SH5001_write(SH5001_ADDRESS, addr, 1, ®Data);\r
+ //printf("0xD0 = 0x%x\r\n", regData);\r
+\r
+}\r
+\r
+#define SH5001_GYRO_ADC_S1_REGNUM 5\r
+#define SH5001_GYRO_ADC_S2_REGNUM 1\r
+//#define SH5001_GYRO_ADC__DEBUG\r
+int adc_count = 0;\r
+int err_count = 0;\r
+void SH5001_Get_Adc_Polarity(short gyroPolarity[3])\r
+{\r
+ unsigned char regAddrS1[SH5001_GYRO_ADC_S1_REGNUM] = {0xA3, 0xC6, 0xCC, 0xCF, 0xD0};\r
+ unsigned char regInitS1[SH5001_GYRO_ADC_S1_REGNUM] = {0xFF, 0x00, 0x69, 0x1A, 0x0A};\r
+ unsigned char regAddrS2[SH5001_GYRO_ADC_S2_REGNUM] = {0xD0};\r
+ unsigned char regInitS2[SH5001_GYRO_ADC_S2_REGNUM] = {0x08};\r
+ unsigned char regBackS1[SH5001_GYRO_ADC_S1_REGNUM] = {0};\r
+ unsigned char gyroTemp[6] = {0};\r
+ signed int gyroSum[3] = {0};\r
+ signed short gyroAvg1[3] = {0}, gyroAvg2[3] = {0};\r
+ unsigned char i = 0;\r
+ //signed short gyroPolarity[3] = {0};\r
+\r
+ for(i=0; i<SH5001_GYRO_ADC_S1_REGNUM; i++)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, regAddrS1[i], 1, ®BackS1[i]);\r
+ }\r
+\r
+ for(i=0; i<SH5001_GYRO_ADC_S1_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddrS1[i], 1, ®InitS1[i]);\r
+ }\r
+\r
+ delay_ms(50);\r
+\r
+ i = 0;\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_XL, 6, gyroTemp);\r
+ gyroSum[0] += (signed short)((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+ gyroSum[1] += (signed short)((short)gyroTemp[3] << 8) | gyroTemp[2];\r
+ gyroSum[2] += (signed short)((short)gyroTemp[5] << 8) | gyroTemp[4];\r
+ #ifdef SH5001_GYRO_ADC__DEBUG\r
+ printf("bf %d %d %d\r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]), (signed short)(((short)gyroTemp[3] << 8) | gyroTemp[2]), (signed short)(((short)gyroTemp[5] << 8) | gyroTemp[4]));\r
+ #endif\r
+ }\r
+ gyroAvg1[0] = gyroSum[0]/20;\r
+ gyroAvg1[1] = gyroSum[1]/20;\r
+ gyroAvg1[2] = gyroSum[2]/20;\r
+\r
+ for(i=0; i<SH5001_GYRO_ADC_S2_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddrS2[i], 1, ®InitS2[i]);\r
+ }\r
+\r
+ delay_ms(50);\r
+\r
+ gyroSum[0] = 0;\r
+ gyroSum[1] = 0;\r
+ gyroSum[2] = 0;\r
+ i = 0;\r
+\r
+ while(i++ < 20)\r
+ {\r
+ SH5001_read(SH5001_ADDRESS, SH5001_GYRO_XL, 6, gyroTemp);\r
+ gyroSum[0] += (signed short)((short)gyroTemp[1] << 8) | gyroTemp[0];\r
+ gyroSum[1] += (signed short)((short)gyroTemp[3] << 8) | gyroTemp[2];\r
+ gyroSum[2] += (signed short)((short)gyroTemp[5] << 8) | gyroTemp[4];\r
+\r
+ #ifdef SH5001_GYRO_ADC__DEBUG\r
+ printf("af %d %d %d\r\n", (signed short)(((short)gyroTemp[1] << 8) | gyroTemp[0]), (signed short)(((short)gyroTemp[3] << 8) | gyroTemp[2]), (signed short)(((short)gyroTemp[5] << 8) | gyroTemp[4]));\r
+ #endif\r
+ }\r
+\r
+ gyroAvg2[0] = gyroSum[0]/20;\r
+ gyroAvg2[1] = gyroSum[1]/20;\r
+ gyroAvg2[2] = gyroSum[2]/20;\r
+\r
+ for(i=0; i<SH5001_GYRO_ADC_S1_REGNUM; i++)\r
+ {\r
+ SH5001_write(SH5001_ADDRESS, regAddrS1[i], 1, ®BackS1[i]);\r
+ }\r
+\r
+ gyroPolarity[0] = gyroAvg2[0] - gyroAvg1[0];\r
+ gyroPolarity[1] = gyroAvg2[1] - gyroAvg1[1];\r
+ gyroPolarity[2] = gyroAvg2[2] - gyroAvg1[2];\r
+ adc_count++;\r
+ #ifdef SH5001_GYRO_ADC__DEBUG\r
+ printf("gyroPolarity %d %d %d %d %d\r\n", adc_count, err_count, gyroPolarity[0],gyroPolarity[1] ,gyroPolarity[2]);\r
+ #endif\r
+\r
+ if(gyroPolarity[2] < 0)\r
+ {\r
+ err_count++;\r
+ }\r
+\r
+}\r
+\r
+int sh5001_get_version(void)\r
+{\r
+ return MCU_VERSION_SH5001;\r
+}\r
+\r
+gyro_data_t sh5001_get_gyro_data(void)\r
+{\r
+ gyro_data_t data = gyro_data;\r
+ return data;\r
+}
\ No newline at end of file
--- /dev/null
+#ifndef __SH5001_H \r
+#define __SH5001_H\r
+\r
+#include "gyro_hal.h"\r
+\r
+#define SH5001_FIFO_WM_INT\r
+//#define SH5001_ACTIVITY_INT\r
+//#define SH5001_DATA_READY_INT\r
+\r
+/******************************************************************\r
+* SH5001 I2C address Macro Definition \r
+*\r
+* (7bit): (0x37)011 0111@SDO=1; (0x36)011 0110@SDO=0;\r
+******************************************************************/\r
+#define SH5001_ADDRESS (0x36U) \r
+#define SENODIA_VDD_3V3 1\r
+#define SH5001_ID 0xA1\r
+\r
+/******************************************************************\r
+* SH5001 Registers Macro Definitions \r
+******************************************************************/\r
+#define SH5001_ACC_XL (0x00U)\r
+#define SH5001_ACC_XH (0x01U)\r
+#define SH5001_ACC_YL (0x02U)\r
+#define SH5001_ACC_YH (0x03U)\r
+#define SH5001_ACC_ZL (0x04U)\r
+#define SH5001_ACC_ZH (0x05U)\r
+#define SH5001_GYRO_XL (0x06U)\r
+#define SH5001_GYRO_XH (0x07U)\r
+#define SH5001_GYRO_YL (0x08U)\r
+#define SH5001_GYRO_YH (0x09U)\r
+#define SH5001_GYRO_ZL (0x0AU)\r
+#define SH5001_GYRO_ZH (0x0BU)\r
+#define SH5001_TEMP_ZL (0x0CU)\r
+#define SH5001_TEMP_ZH (0x0DU)\r
+#define SH5001_TIMESTAMP_L (0x0EU)\r
+#define SH5001_TIMESTAMP_M (0x0FU)\r
+#define SH5001_TIMESTAMP_H (0x10U)\r
+#define SH5001_INT_STA0 (0x16U)\r
+#define SH5001_INT_STA1 (0x17U)\r
+#define SH5001_INT_STA2 (0x18U)\r
+#define SH5001_INT_STA3 (0x19U)\r
+#define SH5001_INT_STA4 (0x1AU)\r
+#define SH5001_FIFO_STA0 (0x1BU)\r
+#define SH5001_FIFO_STA1 (0x1CU)\r
+#define SH5001_FIFO_DATA (0x1DU)\r
+\r
+#define SH5001_CHIP_ID (0x1FU)\r
+\r
+#define SH5001_ACC_CONF0 (0x20U)\r
+#define SH5001_ACC_CONF1 (0x21U)\r
+#define SH5001_ACC_CONF2 (0x22U)\r
+\r
+#define SH5001_GYRO_CONF0 (0x23U)\r
+#define SH5001_GYRO_CONF1 (0x24U)\r
+#define SH5001_GYRO_CONF2 (0x25U)\r
+\r
+#define SH5001_OIS_ACC_CONF (0x26U)\r
+#define SH5001_OIS_GYRO_CONF (0x27U)\r
+\r
+#define SH5001_TEMP_CONF0 (0x28U)\r
+#define SH5001_ACC_DOWNSAMPLE (0x28U)\r
+#define SH5001_TEMP_CONF1 (0x29U)\r
+#define SH5001_TEMP_CONF2 (0x2AU)\r
+#define SH5001_TIMESTAMP_CONF (0x2AU)\r
+\r
+#define SH5001_POWER_MODE (0x30U)\r
+#define SH5001_POWER_MODE_PWM (0x31U)\r
+\r
+#define SH5001_I2C_CONF (0x34U)\r
+#define SH5001_SPI_CONF (0x34U)\r
+#define SH5001_I2C_READ_LOOP (0x34U)\r
+#define SH5001_OIS_SPI_CONF (0x34U)\r
+\r
+\r
+#define SH5001_FIFO_CONF0 (0x35U)\r
+#define SH5001_FIFO_CONF1 (0x36U)\r
+#define SH5001_FIFO_CONF2 (0x37U)\r
+#define SH5001_FIFO_CONF3 (0x38U)\r
+#define SH5001_FIFO_CONF4 (0x39U)\r
+\r
+#define SH5001_MI2C_CONF0 (0x3AU)\r
+#define SH5001_MI2C_CONF1 (0x3BU)\r
+#define SH5001_MI2C_CMD0 (0x3CU)\r
+#define SH5001_MI2C_CMD1 (0x3DU)\r
+#define SH5001_MI2C_WR (0x3EU)\r
+#define SH5001_MI2C_RD (0x3FU)\r
+\r
+#define SH5001_INT_ENABLE0 (0x40U)\r
+#define SH5001_INT_ENABLE1 (0x41U)\r
+#define SH5001_INT_CONF (0x42U)\r
+#define SH5001_INT_LIMIT (0x43U)\r
+#define SH5001_ORIEN_INTCONF0 (0x44U)\r
+#define SH5001_ORIEN_INTCONF1 (0x45U)\r
+#define SH5001_ORIEN_INT_1G5_LOW (0x46U)\r
+#define SH5001_ORIEN_INT_1G5_HIGH (0x47U)\r
+#define SH5001_ORIEN_INT_SLOPE_LOW (0x48U)\r
+#define SH5001_ORIEN_INT_SLOPE_HIGH (0x49U)\r
+#define SH5001_ORIEN_INT_HYST_LOW (0x4AU)\r
+#define SH5001_ORIEN_INT_HYST_HIGH (0x4BU)\r
+\r
+#define SH5001_FLAT_INT_CONF (0x4CU)\r
+\r
+#define SH5001_ACT_INACT_INT_CONF (0x4DU)\r
+#define SH5001_ACT_INACT_INT_LINK (0x4EU)\r
+#define SH5001_ACT_INT_THRESHOLDL (0x54U)\r
+#define SH5001_ACT_INT_THRESHOLDH (0x55U)\r
+#define SH5001_ACT_INT_TIME (0x56U)\r
+\r
+#define SH5001_INACT_INT_THRESHOLDL (0x57U)\r
+#define SH5001_INACT_INT_THRESHOLDH (0x58U)\r
+#define SH5001_INACT_INT_TIME (0x59U)\r
+\r
+#define SH5001_SMD_INT_THRESHOLDL (0x5AU)\r
+#define SH5001_SMD_INT_THRESHOLDH (0x5BU)\r
+#define SH5001_SMD_INT_TIME (0x5CU)\r
+\r
+#define SH5001_TAP_INT_CONF (0x4EU)\r
+#define SH5001_TAP_INT_THRESHOLDL (0x4FU)\r
+#define SH5001_TAP_INT_THRESHOLDH (0x50U)\r
+#define SH5001_TAP_INT_DURATION (0x51U)\r
+#define SH5001_TAP_INT_LATENCY (0x52U)\r
+#define SH5001_DTAP_INT_WINDOW (0x53U)\r
+\r
+#define SH5001_HIGHG_INT_CONF (0x5DU)\r
+#define SH5001_HIGHG_INT_THRESHOLDL (0x5EU)\r
+#define SH5001_HIGHG_INT_THRESHOLDH (0x5FU)\r
+#define SH5001_HIGHG_INT_TIME (0x60U)\r
+\r
+#define SH5001_LOWG_INT_CONF (0x5DU)\r
+#define SH5001_LOWG_INT_THRESHOLDL (0x61U)\r
+#define SH5001_LOWG_INT_THRESHOLDH (0x62U)\r
+#define SH5001_LOWG_INT_TIME (0x63U)\r
+\r
+#define SH5001_FREEFALL_INT_THRES (0x64U)\r
+#define SH5001_FREEFALL_INT_TIME (0x65U)\r
+\r
+#define SH5001_INT_PIN_MAP0 (0x66U)\r
+#define SH5001_INT_PIN_MAP1 (0x67U)\r
+\r
+#define SH5001_SPI_REG_ACCESS (0x7FU)\r
+#define SH5001_AUX_I2C_CONF (0xFDU)\r
+\r
+#define SH5001_PIN_PP_CONF0 (0xFDU)\r
+#define SH5001_PIN_PP_CONF1 (0xFEU)\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/******************************************************************\r
+* ACC Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_ACC_ODR_1000HZ (0x00U) //TODO need to set ref datasheet\r
+#define SH5001_ACC_ODR_500HZ (0x01U)\r
+#define SH5001_ACC_ODR_250HZ (0x02U)\r
+#define SH5001_ACC_ODR_125HZ (0x03U)\r
+\r
+#define SH5001_ACC_ODR_2000HZ (0x08U)\r
+#define SH5001_ACC_ODR_4000HZ (0x09U)\r
+#define SH5001_ACC_ODR_8000HZ (0x0AU)\r
+\r
+#define SH5001_ACC_RANGE_4G (0x10U)\r
+#define SH5001_ACC_RANGE_8G (0x20U)\r
+#define SH5001_ACC_RANGE_16G (0x30U)\r
+//#define SH5001_ACC_RANGE_32G (0x40U)\r
+\r
+#define SH5001_ACC_ODRX040 (0x00U)\r
+#define SH5001_ACC_ODRX036 (0x01U)\r
+#define SH5001_ACC_ODRX032 (0x02U)\r
+#define SH5001_ACC_ODRX028 (0x03U)\r
+#define SH5001_ACC_ODRX024 (0x04U)\r
+#define SH5001_ACC_ODRX020 (0x05U)\r
+#define SH5001_ACC_ODRX016 (0x06U)\r
+#define SH5001_ACC_ODRX014 (0x07U)\r
+#define SH5001_ACC_ODRX012 (0x08U)\r
+#define SH5001_ACC_ODRX010 (0x09U)\r
+#define SH5001_ACC_ODRX008 (0x0aU)\r
+#define SH5001_ACC_ODRX006 (0x0bU)\r
+#define SH5001_ACC_ODRX004 (0x0cU)\r
+#define SH5001_ACC_ODRX003 (0x0dU)\r
+#define SH5001_ACC_ODRX002 (0x0eU)\r
+#define SH5001_ACC_ODRX001 (0x0fU)\r
+\r
+#define SH5001_ACC_FILTER_EN (0x01U)\r
+#define SH5001_ACC_FILTER_DIS (0x00U)\r
+#define SH5001_ACC_BYPASS_EN (0x02U)\r
+#define SH5001_ACC_BYPASS_DIS (0x00U)\r
+\r
+\r
+/******************************************************************\r
+* GYRO Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_GYRO_ODR_1000HZ (0x00U)\r
+#define SH5001_GYRO_ODR_500HZ (0x01U)\r
+#define SH5001_GYRO_ODR_250HZ (0x02U)\r
+#define SH5001_GYRO_ODR_125HZ (0x03U)\r
+#define SH5001_GYRO_ODR_2000HZ (0x08U)\r
+#define SH5001_GYRO_ODR_4000HZ (0x09U)\r
+#define SH5001_GYRO_ODR_8000HZ (0x0AU)\r
+#define SH5001_GYRO_ODR_16000HZ (0x0BU)\r
+\r
+\r
+\r
+#define SH5001_GYRO_RANGE_31 (0x00U)\r
+#define SH5001_GYRO_RANGE_62 (0x10U)\r
+#define SH5001_GYRO_RANGE_125 (0x20U)\r
+#define SH5001_GYRO_RANGE_250 (0x30U)\r
+#define SH5001_GYRO_RANGE_500 (0x40U)\r
+#define SH5001_GYRO_RANGE_1000 (0x50U)\r
+#define SH5001_GYRO_RANGE_2000 (0x60U)\r
+#define SH5001_GYRO_RANGE_4000 (0x70U)\r
+\r
+#define SH5001_GYRO_ODRX040 (0x00U)\r
+#define SH5001_GYRO_ODRX036 (0x01U)\r
+#define SH5001_GYRO_ODRX032 (0x02U)\r
+#define SH5001_GYRO_ODRX028 (0x03U)\r
+#define SH5001_GYRO_ODRX024 (0x04U)\r
+#define SH5001_GYRO_ODRX020 (0x05U)\r
+#define SH5001_GYRO_ODRX016 (0x06U)\r
+#define SH5001_GYRO_ODRX014 (0x07U)\r
+#define SH5001_GYRO_ODRX012 (0x08U)\r
+#define SH5001_GYRO_ODRX010 (0x09U)\r
+#define SH5001_GYRO_ODRX008 (0x0aU)\r
+#define SH5001_GYRO_ODRX006 (0x0bU)\r
+#define SH5001_GYRO_ODRX004 (0x0cU)\r
+#define SH5001_GYRO_ODRX003 (0x0dU)\r
+#define SH5001_GYRO_ODRX002 (0x0eU)\r
+#define SH5001_GYRO_ODRX001 (0x0fU)\r
+\r
+#define SH5001_GYRO_FILTER_EN (0x01U)\r
+#define SH5001_GYRO_FILTER_DIS (0x00U)\r
+#define SH5001_GYRO_BYPASS_EN (0x02U)\r
+#define SH5001_GYRO_BYPASS_DIS (0x00U)\r
+\r
+#define SH5001_GYRO_OFF_INACT (0x80U)\r
+#define SH5001_GYRO_ON_INACT (0x00U)\r
+\r
+/******************************************************************\r
+* Time Stamp Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_TS_ODR_25KHZ (0x20U)\r
+#define SH5001_TS_ODR_1KHZ (0x00U)\r
+#define SH5001_TS_EN (0x40U)\r
+#define SH5001_TS_DIS (0x00U)\r
+\r
+/******************************************************************\r
+* Temperature Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_TEMP_ODR_500HZ (0x00U)\r
+#define SH5001_TEMP_ODR_250HZ (0x02U)\r
+#define SH5001_TEMP_ODR_125HZ (0x04U)\r
+#define SH5001_TEMP_ODR_63HZ (0x06U)\r
+\r
+#define SH5001_TEMP_EN (0x01U)\r
+#define SH5001_TEMP_DIS (0x00U)\r
+\r
+/******************************************************************\r
+* INT Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_INT_LOWG (0x8000U)\r
+#define SH5001_INT_HIGHG (0x4000U)\r
+#define SH5001_INT_INACT (0x2000U)\r
+#define SH5001_INT_ACT (0x1000U)\r
+#define SH5001_INT_DOUBLE_TAP (0x0800U)\r
+#define SH5001_INT_SINGLE_TAP (0x0400U)\r
+#define SH5001_INT_FLAT (0x0200U)\r
+#define SH5001_INT_ORIENTATION (0x0100U)\r
+#define SH5001_INT_TAP (0x0020U)\r
+#define SH5001_INT_SMD (0x0010U)\r
+#define SH5001_INT_FIFO_WATERMARK (0x0008U)\r
+#define SH5001_INT_GYRO_READY (0x0004U)\r
+#define SH5001_INT_ACC_READY (0x0002U)\r
+#define SH5001_INT_FREE_FALL (0x0001U)\r
+#define SH5001_INT_UP_DOWN_Z (0x0040U)\r
+\r
+#define SH5001_INT_EN (0x01U)\r
+#define SH5001_INT_DIS (0x00U)\r
+\r
+#define SH5001_INT_MAP_INT1 (0x01U)\r
+#define SH5001_INT_MAP_INT0 (0x00U)\r
+\r
+#define SH5001_INT0_LEVEL_LOW (0x80U)\r
+#define SH5001_INT0_LEVEL_HIGH (0x7FU)\r
+#define SH5001_INT_NO_LATCH (0x40U)\r
+#define SH5001_INT_LATCH (0xBFU)\r
+#define SH5001_INT_CLEAR_ANY (0x10U)\r
+#define SH5001_INT_CLEAR_STATUS (0xEFU)\r
+#define SH5001_INT1_OD (0x08U)\r
+#define SH5001_INT1_NORMAL (0xF7U)\r
+#define SH5001_INT1_OUTPUT (0x04U)\r
+#define SH5001_INT1_INPUT (0xFBU)\r
+#define SH5001_INT0_OD (0x02U)\r
+#define SH5001_INT0_NORMAL (0xFDU)\r
+#define SH5001_INT0_OUTPUT (0x01U)\r
+#define SH5001_INT0_INPUT (0xFEU)\r
+\r
+\r
+/******************************************************************\r
+* Orientation Blocking Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_ORIENT_BLOCK_MODE0 (0x00U)\r
+#define SH5001_ORIENT_BLOCK_MODE1 (0x04U)\r
+#define SH5001_ORIENT_BLOCK_MODE2 (0x08U)\r
+#define SH5001_ORIENT_BLOCK_MODE3 (0x0CU)\r
+\r
+#define SH5001_ORIENT_SYMM (0x00U)\r
+#define SH5001_ORIENT_HIGH_ASYMM (0x01U)\r
+#define SH5001_ORIENT_LOW_ASYMM (0x02U)\r
+\r
+\r
+/******************************************************************\r
+* Flat Time Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_FLAT_TIME_200MS (0x00U)\r
+#define SH5001_FLAT_TIME_400MS (0x40U)\r
+#define SH5001_FLAT_TIME_800MS (0x80U)\r
+#define SH5001_FLAT_TIME_000MS (0xC0U)\r
+\r
+/******************************************************************\r
+* ACT and INACT Int Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_ACT_X_INT_EN (0x40U)\r
+#define SH5001_ACT_X_INT_DIS (0x00U)\r
+#define SH5001_ACT_Y_INT_EN (0x20U)\r
+#define SH5001_ACT_Y_INT_DIS (0x00U)\r
+#define SH5001_ACT_Z_INT_EN (0x10U)\r
+#define SH5001_ACT_Z_INT_DIS (0x00U)\r
+\r
+#define SH5001_INACT_X_INT_EN (0x04U)\r
+#define SH5001_INACT_X_INT_DIS (0x00U)\r
+#define SH5001_INACT_Y_INT_EN (0x02U)\r
+#define SH5001_INACT_Y_INT_DIS (0x00U)\r
+#define SH5001_INACT_Z_INT_EN (0x01U)\r
+#define SH5001_INACT_Z_INT_DIS (0x00U)\r
+\r
+\r
+#define SH5001_LINK_PRE_STA (0x01U)\r
+#define SH5001_LINK_PRE_STA_NO (0x00U)\r
+\r
+#define SH5001_ACT_INACT_CLR_STATUS1 (0x00U)\r
+#define SH5001_ACT_INACT_CLR_STATUS3 (0x80U)\r
+\r
+/******************************************************************\r
+* TAP Int Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_TAP_X_INT_EN (0x08U)\r
+#define SH5001_TAP_X_INT_DIS (0x00U)\r
+#define SH5001_TAP_Y_INT_EN (0x04U)\r
+#define SH5001_TAP_Y_INT_DIS (0x00U)\r
+#define SH5001_TAP_Z_INT_EN (0x02U)\r
+#define SH5001_TAP_Z_INT_DIS (0x00U)\r
+\r
+\r
+/******************************************************************\r
+* HIGHG Int Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_HIGHG_ALL_INT_EN (0x80U)\r
+#define SH5001_HIGHG_ALL_INT_DIS (0x00U)\r
+#define SH5001_HIGHG_X_INT_EN (0x40U)\r
+#define SH5001_HIGHG_X_INT_DIS (0x00U)\r
+#define SH5001_HIGHG_Y_INT_EN (0x20U)\r
+#define SH5001_HIGHG_Y_INT_DIS (0x00U)\r
+#define SH5001_HIGHG_Z_INT_EN (0x10U)\r
+#define SH5001_HIGHG_Z_INT_DIS (0x00U)\r
+\r
+\r
+/******************************************************************\r
+* LOWG Int Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_LOWG_ALL_INT_EN (0x01U)\r
+#define SH5001_LOWG_ALL_INT_DIS (0x00U)\r
+\r
+\r
+/******************************************************************\r
+* SPI Interface Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_SPI_3_WIRE (0x20U)\r
+#define SH5001_SPI_4_WIRE (0x00U)\r
+\r
+\r
+/******************************************************************\r
+* I2C Interface Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_I2C_DIS (0x80U)\r
+#define SH5001_I2C_EN (0x00U)\r
+\r
+//Jin\r
+#define SH5001_I2C_LP_06BYTE (0x04U)\r
+#define SH5001_I2C_LP_12BYTE (0x02U)\r
+#define SH5001_I2C_LP_14BYTE (0x01U)\r
+#define SH5001_I2C_LP_DISABLE (0x00U)\r
+\r
+/******************************************************************\r
+* OIS SPI Interface Config Macro Definitions \r
+******************************************************************/\r
+//#define SH5001_OIS_SPI_3WIRE (0x00U)\r
+//#define SH5001_OIS_SPI_4WIRE (0x40U)\r
+#define SH5001_OIS_SPI_EN (0x10U)\r
+#define SH5001_OIS_SPI_DIS (0x00U)\r
+\r
+#define SH5001_ACC_OIS_ENABLE (0x80U)\r
+#define SH5001_ACC_OIS_DISABLE (0x00U)\r
+\r
+#define SH5001_ACC_OIS_RANGE_4G (0x10U)\r
+#define SH5001_ACC_OIS_RANGE_8G (0x20U)\r
+#define SH5001_ACC_OIS_RANGE_16G (0x30U)\r
+\r
+#define SH5001_ACC_OIS_ODRX008 (0x0CU)\r
+#define SH5001_ACC_OIS_ODRX004 (0x08U)\r
+#define SH5001_ACC_OIS_ODRX002 (0x04U)\r
+#define SH5001_ACC_OIS_ODRX000 (0x00U) //bypass\r
+\r
+\r
+#define SH5001_ACC_OIS_ODR_1000HZ (0x00U) //TODO need to set ref datasheet\r
+#define SH5001_ACC_OIS_ODR_2000HZ (0x01U)\r
+#define SH5001_ACC_OIS_ODR_4000HZ (0x02U)\r
+#define SH5001_ACC_OIS_ODR_8000HZ (0x03U)\r
+\r
+\r
+\r
+\r
+#define SH5001_GYRO_OIS_ENABLE (0x80U)\r
+#define SH5001_GYRO_OIS_DISABLE (0x00U)\r
+\r
+#define SH5001_GYRO_OIS_RANGE_31 (0x00U)\r
+#define SH5001_GYRO_OIS_RANGE_62 (0x10U)\r
+#define SH5001_GYRO_OIS_RANGE_125 (0x20U)\r
+#define SH5001_GYRO_OIS_RANGE_250 (0x30U)\r
+#define SH5001_GYRO_OIS_RANGE_500 (0x40U)\r
+#define SH5001_GYRO_OIS_RANGE_1000 (0x50U)\r
+#define SH5001_GYRO_OIS_RANGE_2000 (0x60U)\r
+#define SH5001_GYRO_OIS_RANGE_4000 (0x70U)\r
+\r
+#define SH5001_GYRO_OIS_ODRX008 (0x0CU)\r
+#define SH5001_GYRO_OIS_ODRX004 (0x08U)\r
+#define SH5001_GYRO_OIS_ODRX002 (0x04U)\r
+#define SH5001_GYRO_OIS_ODRX000 (0x00U) //bypass\r
+\r
+#define SH5001_GYRO_OIS_ODR_1000HZ (0x00U)\r
+#define SH5001_GYRO_OIS_ODR_2000HZ (0x01U)\r
+#define SH5001_GYRO_OIS_ODR_4000HZ (0x02U)\r
+#define SH5001_GYRO_OIS_ODR_8000HZ (0x03U)\r
+\r
+\r
+\r
+\r
+/******************************************************************\r
+* FIFO Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_FIFO_MODE_DIS (0x00U)\r
+#define SH5001_FIFO_MODE_FIFO (0x01U)\r
+#define SH5001_FIFO_MODE_STREAM (0x02U)\r
+#define SH5001_FIFO_MODE_TRIGGER (0x03U)\r
+\r
+#define SH5001_FIFO_ACC_DOWNS_EN (0x80U)\r
+#define SH5001_FIFO_ACC_DOWNS_DIS (0x00U)\r
+#define SH5001_FIFO_GYRO_DOWNS_EN (0x08U)\r
+#define SH5001_FIFO_GYRO_DOWNS_DIS (0x00U)\r
+\r
+#define SH5001_FIFO_FREQ_X1_2 (0x00U)\r
+#define SH5001_FIFO_FREQ_X1_4 (0x01U)\r
+#define SH5001_FIFO_FREQ_X1_8 (0x02U)\r
+#define SH5001_FIFO_FREQ_X1_16 (0x03U)\r
+#define SH5001_FIFO_FREQ_X1_32 (0x04U)\r
+#define SH5001_FIFO_FREQ_X1_64 (0x05U)\r
+#define SH5001_FIFO_FREQ_X1_128 (0x06U)\r
+#define SH5001_FIFO_FREQ_X1_256 (0x07U)\r
+\r
+#define SH5001_FIFO_TIMESTAMP_EN (0x4000U)\r
+#define SH5001_FIFO_EXT_Z_EN (0x2000U)\r
+#define SH5001_FIFO_EXT_Y_EN (0x1000U)\r
+#define SH5001_FIFO_EXT_X_EN (0x0080U)\r
+#define SH5001_FIFO_TEMPERATURE_EN (0x0040U)\r
+#define SH5001_FIFO_GYRO_Z_EN (0x0020U)\r
+#define SH5001_FIFO_GYRO_Y_EN (0x0010U)\r
+#define SH5001_FIFO_GYRO_X_EN (0x0008U)\r
+#define SH5001_FIFO_ACC_Z_EN (0x0004U)\r
+#define SH5001_FIFO_ACC_Y_EN (0x0002U)\r
+#define SH5001_FIFO_ACC_X_EN (0x0001U)\r
+#define SH5001_FIFO_ALL_DIS (0x0000U)\r
+\r
+/******************************************************************\r
+* AUX I2C Config Macro Definitions \r
+******************************************************************/\r
+#define SH5001_MI2C_NORMAL_MODE (0x00U)\r
+#define SH5001_MI2C_BYPASS_MODE (0x01U)\r
+\r
+#define SH5001_MI2C_READ_ODR_200HZ (0x00U)\r
+#define SH5001_MI2C_READ_ODR_100HZ (0x10U)\r
+#define SH5001_MI2C_READ_ODR_50HZ (0x20U)\r
+#define SH5001_MI2C_READ_ODR_25HZ (0x30U)\r
+\r
+#define SH5001_MI2C_FAIL (0x20U)\r
+#define SH5001_MI2C_SUCCESS (0x10U)\r
+\r
+#define SH5001_MI2C_READ_MODE_AUTO (0x40U)\r
+#define SH5001_MI2C_READ_MODE_MANUAL (0x00U)\r
+\r
+\r
+/******************************************************************\r
+* Fast offset compensation Macro Definitions \r
+******************************************************************/\r
+#define SH5001_X_UP (0x00U)\r
+#define SH5001_X_DOWN (0x01U)\r
+#define SH5001_Y_UP (0x02U)\r
+#define SH5001_Y_DOWN (0x03U)\r
+#define SH5001_Z_UP (0x04U)\r
+#define SH5001_Z_DOWN (0x05U)\r
+\r
+\r
+/******************************************************************\r
+* Other Macro Definitions \r
+******************************************************************/\r
+#define SH5001_TRUE (0U)\r
+#define SH5001_FALSE (1U)\r
+\r
+#define SH5001_CALI_REG_NUM 8\r
+#define SH5001_POWMODE_REG_NUM 11\r
+#define SH5001_NORMAL_MODE (0x00)\r
+#define SH5001_ACC_HP_MODE (0x01)\r
+#define SH5001_ACC_LP_MODE (0x02)\r
+#define SH5001_POWERDOWN_MODE (0x03)\r
+\r
+// FIFO Mode DIV = FIFO channel * 2;\r
+#define SH5001_WATERMARK_DIV (12U) \r
+//#define SH5001_FIFO_BUFFER (1024U)\r
+#define SH5001_FIFO_BUFFER (500U)\r
+\r
+\r
+/***************************************************************************\r
+* Type Definitions \r
+****************************************************************************/\r
+typedef unsigned char (*IMU_read)( unsigned char devAddr, \r
+ unsigned char regAddr, \r
+ unsigned short readLen, \r
+ unsigned char *readBuf);\r
+\r
+typedef unsigned char (*IMU_write)( unsigned char devAddr, \r
+ unsigned char regAddr, \r
+ unsigned short writeLen, \r
+ unsigned char *writeBuf);\r
+\r
+\r
+\r
+\r
+/***************************************************************************\r
+ Exported Functions \r
+****************************************************************************/ \r
+ \r
+extern unsigned char SH5001_init(void);\r
+extern void SH5001_GetImuData( short accData[3], short gyroData[3] );\r
+extern float SH5001_GetTempData(void); \r
+extern unsigned char SH5001_SwitchPowerMode(unsigned char powerMode); \r
+ \r
+ \r
+\r
+// interrupt related fucntions\r
+extern void SH5001_INT_Enable( unsigned short intType, \r
+ unsigned char intEnable, \r
+ unsigned char intPinSel);\r
+\r
+extern void SH5001_INT_Config( unsigned char intLevel,\r
+ unsigned char intLatch,\r
+ unsigned char intClear,\r
+ unsigned char intTime,\r
+ unsigned char int1Mode,\r
+ unsigned char int0Mode,\r
+ unsigned char int1OE,\r
+ unsigned char int0OE);\r
+\r
+extern void SH5001_INT_Output_Config( unsigned char int1Mode,\r
+ unsigned char int0Mode,\r
+ unsigned char int1OE,\r
+ unsigned char int0OE); \r
+ \r
+extern void SH5001_INT_Orient_Config( unsigned char orientBlockMode,\r
+ unsigned char orientMode,\r
+ unsigned char orientTheta,\r
+ unsigned short orientG1point5,\r
+ unsigned short orientSlope,\r
+ unsigned short orientHyst); \r
+ \r
+extern void SH5001_INT_Flat_Config( unsigned char flatTimeTH, \r
+ unsigned char flatTanHeta2); \r
+ \r
+extern void SH5001_INT_Act_Config( unsigned char actEnDisIntX,\r
+ unsigned char actEnDisIntY,\r
+ unsigned char actEnDisIntZ,\r
+ unsigned char actTimeNum,\r
+ unsigned short actIntThres,\r
+ unsigned char actLinkStatus,\r
+ unsigned char actIntClear); \r
+\r
+extern void SH5001_INT_Inact_Config( unsigned char inactEnDisIntX,\r
+ unsigned char inactEnDisIntY,\r
+ unsigned char inactEnDisIntZ,\r
+ unsigned char inactLinkStatus,\r
+ unsigned char inactTimeMs,\r
+ unsigned short inactIntThres,\r
+ unsigned short inactG1,\r
+ unsigned char inactIntClear);\r
+\r
+extern void SH5001_INT_Tap_Config( unsigned char tapEnDisIntX,\r
+ unsigned char tapEnDisIntY,\r
+ unsigned char tapEnDisIntZ,\r
+ unsigned char tapIntThres,\r
+ unsigned char tapTimeMs,\r
+ unsigned char tapWaitTimeMs,\r
+ unsigned char tapWaitTimeWindowMs);\r
+\r
+extern void SH5001_INT_SMD_Config( unsigned short smdThres,\r
+ unsigned char smdBlockTimeS,\r
+ unsigned char smdProofTimeS); \r
+\r
+extern void SH5001_INT_HighG_Config( unsigned char highGEnDisIntX,\r
+ unsigned char highGEnDisIntY,\r
+ unsigned char highGEnDisIntZ,\r
+ unsigned char highGEnDisIntAll,\r
+ unsigned short highGThres,\r
+ unsigned char highGTimeMs);\r
+\r
+extern void SH5001_INT_LowG_Config( unsigned char lowGEnDisIntAll,\r
+ unsigned short lowGThres,\r
+ unsigned char lowGTimeMs);\r
+\r
+extern void SH5001_INT_FreeFall_Config( unsigned char freeFallThres,\r
+ unsigned char freeFallTimeMs);\r
+\r
+extern unsigned short SH5001_INT_Read_Status01(void);\r
+\r
+extern unsigned char SH5001_INT_Read_Status2(void);\r
+\r
+extern unsigned char SH5001_INT_Read_Status3(void);\r
+\r
+extern unsigned char SH5001_INT_Read_Status4(void);\r
+ \r
+ \r
+// Fifo related fucntions\r
+extern void SH5001_FIFO_Reset(void);\r
+\r
+extern void SH5001_FIFO_Freq_Config( unsigned char fifoAccDownSampleEnDis,\r
+ unsigned char fifoAccFreq,\r
+ unsigned char fifoGyroDownSampleEnDis,\r
+ unsigned char fifoGyroFreq);\r
+ \r
+extern void SH5001_FIFO_Data_Config( unsigned short fifoMode,\r
+ unsigned short fifoWaterMarkLevel); \r
+ \r
+extern unsigned char SH5001_FIFO_Read_Status(unsigned short int *fifoEntriesCount); \r
+ \r
+extern void SH5001_FIFO_Read_Data( unsigned char *fifoReadData, \r
+ unsigned short int fifoDataLength); \r
+ \r
+\r
+// Master I2C related fucntions\r
+extern void SH5001_MI2C_Reset(void);\r
+\r
+extern void SH5001_MI2C_Bus_Config( unsigned char mi2cReadMode,\r
+ unsigned char mi2cODR,\r
+ unsigned char mi2cFreq); \r
+ \r
+extern void SH5001_MI2C_Cmd_Config( unsigned char mi2cSlaveAddr,\r
+ unsigned char mi2cSlaveCmd,\r
+ unsigned char mi2cReadMode); \r
+ \r
+extern unsigned char SH5001_MI2C_Write(unsigned char mi2cWriteData); \r
+ \r
+extern unsigned char SH5001_MI2C_Read(unsigned char *mi2cReadData);\r
+\r
+ \r
+// SPI interface related fucntions\r
+extern void SH5001_SPI_Config(unsigned char spiInterfaceMode);\r
+\r
+\r
+// I2C interface related fucntions\r
+extern void SH5001_I2C_Config( unsigned char i2cInterfaceEnDis);\r
+\r
+extern void SH5001_I2C_LP_Config(unsigned char i2cReadLoopMode);\r
+\r
+\r
+// OIS SPI interface related fucntions\r
+extern void SH5001_OIS_SPI_Config(unsigned char oisSpiInterfaceEnDis);\r
+\r
+\r
+// fast offset compensation function\r
+extern void SH5001_FastOffsetComp(unsigned char SH5001Positon); \r
+ \r
+ \r
+// Read FIFO data functions\r
+extern void SH5001_initFIFO(void); \r
+ \r
+extern void SH5001_ReadFIFO(void); \r
+\r
+unsigned char SH5001_get_chip_id(void);\r
+gyro_data_t sh5001_get_gyro_data(void);\r
+#endif\r
+\r
/* display off sequence for common lcd */
const lcd_cmd_sequ g_common_466x466_cmd_display_off[] = {
-#ifdef BOARD_W9
+#if defined(BOARD_W9) || defined(BOARD_N9)
{1, 2, {0xfe, 0x00}, 0}, /* select default cmd page */
{1, 1, {0x28}, 10}, /* display off */
{1, 1, {0x10}, 120}, /* sleep in */
* @Author: penglei 1624952103@qq.com
* @Date: 2024-12-07 15:32:08
* @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-06-06 10:36:23
+ * @LastEditTime: 2025-06-07 17:32:58
* @FilePath: /FD230/code/sdk/drivers/peripheral/lcd/lcd_private.c
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
uapi_gpio_set_dir(VCI_LCD_GPIO, GPIO_DIRECTION_OUTPUT);
uapi_gpio_set_val(VCI_LCD_GPIO, GPIO_LEVEL_LOW);
#endif
-#ifndef BOARD_W9
+#if !defined(BOARD_W9) || !defined(BOARD_N9)
uapi_tcxo_delay_ms(10); /* delay 10 ms */
#endif
int resetvalue = uapi_gpio_get_output_val(RESET_LCD_GPIO);
add_subdirectory_if_exist(hx3695)
add_subdirectory_if_exist(ppgBleService)
add_subdirectory_if_exist(hal)
-add_subdirectory_if_exist(pah8009)
\ No newline at end of file
+add_subdirectory_if_exist(pah8009)
+add_subdirectory_if_exist(gh3x2x)
\ No newline at end of file
--- /dev/null
+#===============================================================================
+# @brief cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "ppg_sensor_gh3x2x")
+
+if("PPG_GH3X2X" IN_LIST DEFINES)
+
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/inc
+)
+
+set(SOURCES ${SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_adt.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_agc.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_demo.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_drv.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_lead_off.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_user.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_hal.c
+)
+
+else()
+set(SOURCES ${SOURCES}
+)
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+endif()
+
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+build_component()
+
--- /dev/null
+#ifndef _GH3X2X_AFE_ADT_H_\r
+#define _GH3X2X_AFE_ADT_H_\r
+#include "gh3x2x_afe_drv.h"\r
+ \r
+\r
+#define __HARD_ADT_WAER_ON_THRD__ 8600000\r
+#define __HARD_ADT_WAER_OFF_THRD__ 8538608\r
+#define __HARD_ADT_WAER_ON_DIFF_THRD__ 100000\r
+\r
+\r
+\r
+typedef enum\r
+{\r
+ WEAR_DETECT_WEAR_ON = 0, /**< detect wear on */\r
+ WEAR_DETECT_WEAR_OFF, /**< detect wear off */\r
+} EMWearDetectType;\r
+\r
+typedef enum\r
+{\r
+ WEAR_STATUS_WEAR_ON = 0, /**< detect wear on */\r
+ WEAR_STATUS_WEAR_OFF, /**< detect wear off */\r
+} EMWearStatus;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+GS8 GH3x2xAdtAlgoInit(void);\r
+GS8 GH3x2xAdtAlgoDeinit(void);\r
+void GH3x2xAdtAlgoExe(GU32* punRawdata,EMWearStatus* pemWearStatus);\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef _GH3X2X_AFE_AGC_H_\r
+#define _GH3X2X_AFE_AGC_H_\r
+#include "gh3x2x_afe_drv.h"\r
+#include <string.h> \r
+\r
+\r
+#define __SUPPORT_SOFT_AGC_CONFIG__ 1\r
+#define GH3X2X_NEW_AGC_SLOT_NUM_LIMIT (8)\r
+#define GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT (32-8)\r
+\r
+#define GH3X2X_LED_AGC_DISABLE (0)\r
+#define GH3X2X_LED_AGC_ENABLE (1)\r
+\r
+\r
+/// led agc adc num max\r
+#define GH3X2X_AGC_ADC_NUM_MAX (4u)\r
+\r
+/// led agc gain limit number\r
+#define GH3X2X_AGC_LIMIT_NUM_MAX (4u)\r
+\r
+/// raw data base line value\r
+#define GH3X2X_DATA_BASE_LINE (8388608) //2^23 \r
+\r
+/// sys sample rate, 32kHz\r
+#define GH3X2X_SYS_SAMPLE_RATE (32000)\r
+ \r
+/* slot register ctrl index */\r
+#define GH3X2X_SLOT_REG_CTRL_0 (0) /**< slot x ctrl 0 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_1 (1) /**< slot x ctrl 1 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_2 (2) /**< slot x ctrl 2 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_3 (3) /**< slot x ctrl 3 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_4 (4) /**< slot x ctrl 4 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_5 (5) /**< slot x ctrl 5 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_6 (6) /**< slot x ctrl 6 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_7 (7) /**< slot x ctrl 7 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_8 (8) /**< slot x ctrl 8 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_9 (9) /**< slot x ctrl 9 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_10 (10) /**< slot x ctrl 10 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_11 (11) /**< slot x ctrl 11 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_12 (12) /**< slot x ctrl 12 reg */\r
+#define GH3X2X_SLOT_REG_CTRL_13 (13) /**< slot x ctrl 13 reg */\r
+\r
+#define GH3X2X_BG_LEVEL_BIT_MASK (0x0030)\r
+#define GH3X2X_ADC_BG_CANCEL_32_UA (0x0)\r
+#define GH3X2X_ADC_BG_CANCEL_64_UA (0x1)\r
+#define GH3X2X_ADC_BG_CANCEL_128_UA (0x2)\r
+#define GH3X2X_ADC_BG_CANCEL_256_UA (0x3)\r
+\r
+/// amb slot select\r
+#define GH3X2X_AGC_AMB_SLOT_DISABLE (0x0)\r
+#define GH3X2X_AGC_AMB_SLOT_USER_DEFINED (0x1)\r
+#define GH3X2X_AGC_AMB_SLOT_FOLLOW_CFG (0x2)\r
+\r
+/// get bits data\r
+#define GH3X2X_GET_REG_BITS_U16(reg_data, lsb, msb) (((reg_data) & ((0xFFFF << (lsb)) & \\r
+ (0xFFFF >> (15 - (msb))))) >> (lsb))\r
+\r
+/// set bits data\r
+#define GH3X2X_SET_REG_BITS_U16(reg, lsb, msb, value) ((reg) = (((reg) & ((0xFFFF << (lsb)) ^ \\r
+ (0xFFFF >> (15 - (msb))))) | ((value) << (lsb))))\r
+\r
+/// get adc gain\r
+#define GH3X2X_GET_ADC_GAIN(reg_data, adc_no) GH3X2X_GET_REG_BITS_U16((reg_data), ((adc_no) * 4), \\r
+ ((adc_no) * 4 + 3))\r
+\r
+/// set adc gain\r
+#define GH3X2X_SET_ADC_GAIN(reg_data, adc_no, gain) GH3X2X_SET_REG_BITS_U16((reg_data), ((adc_no) * 4), \\r
+ ((adc_no) * 4 + 3), (gain))\r
+\r
+/// get bg cancel i_dacfs\r
+#define GH3X2X_GET_BGC_I_DACFS(reg_data, adc_no) GH3X2X_GET_REG_BITS_U16((reg_data), ((adc_no) << 1), \\r
+ ((adc_no) * 2 + 1))\r
+\r
+/// set bg cancel i_dacfs\r
+#define GH3X2X_SET_BGC_I_DACFS(reg_data, adc_no, i_dacfs) GH3X2X_SET_REG_BITS_U16((reg_data), ((adc_no) * 2), \\r
+ ((adc_no) * 2 + 1), (i_dacfs))\r
+ \r
+#define ABS(x) ((x) > 0 ? (x) : -(x))\r
+\r
+/// transfer int to float\r
+#define GH3X2X_TRANS_INT_TO_FLOAT (1.0f)\r
+\r
+/// agc calc seconds (250ms)\r
+#define GH3X2X_AGC_CALC_SECONDS (0.25f)\r
+\r
+/// agc bgc donw cnt, 5s\r
+#define GH3X2X_AGC_BGC_DOWN_CNT (20)\r
+\r
+/// slot tia gain val min\r
+#define GH3X2X_AGC_GAIN_MIN_VAL (0)\r
+\r
+/// slot tia gain val max, 5s, equal (GH3X2X_SLOT_TIA_GAIN_VAL_MAX - 1)\r
+#define GH3X2X_AGC_GAIN_MAX_VAL (12)\r
+\r
+/// Less than thr, include rawdata < thr\r
+#define GH3X2X_AGC_EXCD_FLAG_LESS (0x01)\r
+\r
+/// greater than thr, include rawdatamix > thr | rawdata > thr\r
+#define GH3X2X_AGC_EXCD_FLAG_GREATER (0x06)\r
+\r
+/// AGC failure reason\r
+#define GH3X2X_AGC_FAILURE_REASON_1 (0x1) \r
+#define GH3X2X_AGC_FAILURE_REASON_2 (0x2)\r
+#define GH3X2X_AGC_FAILURE_REASON_4 (0x4)\r
+#define GH3X2X_AGC_FAILURE_REASON_5 (0x5)\r
+#define GH3X2X_AGC_FAILURE_REASON_6 (0x6)\r
+\r
+#define GH3X2X_AGC_CHECK_EN_BITS(x) (((x) & (0x03 << 8)) != 0) /**< check enable bits of ctrl3 */\r
+#define GH3X2X_AGC_GET_SRC_BITS(x) (((x) >> 6) & 0x03) /**< get agc src bits of ctrl3 */\r
+#define GH3X2X_AGC_CHECK_BG_2X2_BITS(x) (((x) & (0x03 << 4)) == 0x03) /**< check 2x2 bg lvl bits of ctrl3 */\r
+#define GH3X2X_AGC_SET_SRC_BITS(x, n) (((x) & 0xFF3Fu) | ((n) << 6u)) /**< set agc src bits of ctrl3 */\r
+\r
+#define GH3X2X_AGC_GET_DONE_FAIL_BIT(x, i) (((x) >> (i)) & 0x01) /**< get tune done/fail bit of flag */\r
+#define GH3X2X_AGC_REG_BIT(x, i) (((x) >> (i)) & 0x01) /**< get reg bit value */\r
+#define GH3X2X_AGC_GET_RESULT_BITS(x, i) (((x) >> (i)) & 0x07) /**< get result bits of flag */\r
+#define GH3X2X_AGC_RESULT_BITS_SIZE (3u) /**< one result 3 bits size of flag */\r
+\r
+#define GH3X2X_FRAME_FLAG_NUM 8\r
+#define GH3X2X_AGC_MAIN_SLOT_NUM 8\r
+\r
+/**\r
+ * @brief soft lead result\r
+ */\r
+typedef struct\r
+{\r
+ GU8 uchAmbSampleEn : 2; /**< AMB sampling enable */\r
+ GU8 uchAmbSlot : 3; /**< slot of amb sampling */\r
+ GU8 uchRes : 3; /**< reserved */\r
+} STAmbSlotCtrl;\r
+ \r
+ /**\r
+ * @brief gain limit\r
+ */\r
+typedef struct\r
+{\r
+ GU8 uchGainLimitBg32uA : 4; /**< gain limit bg current */\r
+ GU8 uchGainLimitBg64uA : 4; \r
+ GU8 uchGainLimitBg128uA : 4; \r
+ GU8 uchGainLimitBg256uA : 4;\r
+} STSoftAgcGainLimit;\r
+\r
+ /**\r
+ * @brief soft agc parameter\r
+ */\r
+typedef struct\r
+{\r
+ GU8 uchSlotxSoftAgcAdjEn; /**< soft agc enable */\r
+ GU8 uchSlotxSoftBgAdjEn; /**< soft bg cancel adjust enable */\r
+ STAmbSlotCtrl stAmbSlotCtrl; /**< amb slot ctrl */\r
+ GU8 uchRes0; /**< reserved */\r
+ GU8 uchSpo2RedSlotCfgEn;\r
+ GU8 uchSpo2IrSlotCfgEn;\r
+ STSoftAgcGainLimit stSoftAgcGainLimit; /**< soft gain limit */\r
+ GU32 unAgcTrigThd_H; /**< trig threshold(high) of soft agc */\r
+ GU32 unAgcTrigThd_L; /**< trig threshold(low) of soft agc */\r
+ GU32 unAgcRestrainThd_H; /**< restrain threshold(high) of soft agc */\r
+ GU32 unAgcRestrainThd_L; /**< restrain threshold(low) of soft agc */\r
+} STSoftAgcCfg;\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+ GU8 uchEnable;\r
+ GU8 uchSpo2ChnlIndex; //0: is not spo2 channel N(N > 0): is spo2 channl \r
+ GU8 uchSlotAdc;\r
+ GU8 uchCurrentTiaGain;\r
+ GU8 uchCurrentDrv;\r
+ GU8 uchTiaGainUpLimit;\r
+ GU8 uchHaveBakRegFlag;\r
+ GU8 uchBakRegAgcEn;\r
+ GU8 uchBakRegAgcSrc;\r
+ GU8 uchBakRegLedCurrentMin;\r
+ GU8 uchBakRegLedCurrentMax;\r
+ GU8 uchBakTiaGain;\r
+} STGh3x2xNewAgcMainChnlInfo;\r
+\r
+typedef struct \r
+{\r
+ GU16 Sat_CheckCnt[GH3X2X_AGC_MAIN_SLOT_NUM]; /* num of data checked*/\r
+ GU16 Sat_cnt[GH3X2X_AGC_MAIN_SLOT_NUM]; /* sat num of each channel*/\r
+ GU8 Sat_flag; /* sat flag one bit each channel*/\r
+} STGh3x2xNewAgcMainChnlSat;\r
+\r
+typedef struct\r
+{\r
+ GU32 unMaxRawdata;\r
+ GU32 unMinRawdata;\r
+ GU32 unSumAdjust; // cacluate drv current and gain\r
+ GU32 unSumTrige; // judge whether AGC\r
+ GU32 unRawdataMean;\r
+ GU32 unLastRawdataMean;\r
+ GU16 usSampleRate;\r
+ GU16 usAnalysisCnt; // numble of nalysis data\r
+ GU8 uchHaveAgcAtLastReadPrd; //0: no agc action at last fifo read period 1: have agc action at last fifo read preiod\r
+ GU8 uchDropFlag;\r
+} STGh3x2xNewAgcMainChnlMeanInfo;\r
+\r
+typedef struct\r
+{\r
+ GU8 uchIniteFirst; // inite first time 0:yes 1:not\r
+ GU8 uchSeconsCnt; // \r
+} STGh3x2xNewAgcMainChnlIdaelAdjInfo;\r
+\r
+typedef struct\r
+{\r
+ GU32 unLastRawdata;\r
+ GU32 unLastLastRawdata;\r
+ GU32 unRawdataSum;\r
+ GU16 usAnalysisCnt;\r
+ GU16 usMoreThanUpLimitPointCnt;\r
+ GU16 usMoreThanUpLimitPointCntForBiggerGain;\r
+ GU16 usTrigeUpLimitForBiggerGain; // rawdate/256\r
+ GU8 uchEn;\r
+ GU8 uchSlotAdcNo;\r
+ GU8 uchCurrentGain;\r
+}STGh3x2xNewAgcSubChnlRxInfo;\r
+\r
+\r
+void GH3X2X_LedAgcReset(void);\r
+void GH3X2X_LedAgcPramWrite(GU16 usRegAddr, GU16 usRegData);\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgc_Close(void);\r
+void GH3X2X_LedAgc_Open(void);\r
+void Gh3x2xNewAgcSubChnlModuleReset(void);\r
+GU8 GH3x2xNewAgcSetNewSubChnl(GU8 uchSlotNo, GU8 uchRxEn, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcPramConfig(STSoftAgcCfg* stSoftAgcCfg);\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef __GH3X2X_AFE_DEMO_H__\r
+#define __GH3X2X_AFE_DEMO_H__\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+/**\r
+ * @brief channel map for function id\r
+ */\r
+#define GH3X2X_FUNC_OFFSET_ADT (0) /**<0 ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HR (1) /**<1 HR FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HRV (2) /**<2 HRV FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HSM (3) /**<3 HSM FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_FPBP (4) /**<4 BPD FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_PWA (5) /**<5 PFA FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SPO2 (6) /**<6 SPO2 FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_ECG (7) /**<7 ECG FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_PWTT (8) /**<8 PWTT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN (9) /**<9 SOFT ADT GREEN FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_BT (10) /**<10 BT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_RESP (11) /**<11 RESP FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_AF (12) /**<12 AF ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_TEST1 (13) /**<13 TEST1 FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_TEST2 (14) /**<14 TEST2 ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SOFT_ADT_IR (15) /**<15 SOFT ADT IR FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_RS0 (16) /**<16 */\r
+#define GH3X2X_FUNC_OFFSET_RS1 (17) /**<17 */\r
+#define GH3X2X_FUNC_OFFSET_RS2 (18) /**<18 */\r
+#define GH3X2X_FUNC_OFFSET_LEAD_DET (19) /**<19 */\r
+#define GH3X2X_FUNC_OFFSET_MAX (20) \r
+\r
+/* Function mode. */\r
+#define GH3X2X_NO_FUNCTION (0) /**<0x00000000 NO function */\r
+#define GH3X2X_FUNCTION_ADT ((0x1) << (GH3X2X_FUNC_OFFSET_ADT)) /**<0x00000001 ADT function */\r
+#define GH3X2X_FUNCTION_HR ((0x1) << (GH3X2X_FUNC_OFFSET_HR)) /**<0x00000002 HR function */\r
+#define GH3X2X_FUNCTION_HRV ((0x1) << (GH3X2X_FUNC_OFFSET_HRV)) /**<0x00000004 HRV function */\r
+#define GH3X2X_FUNCTION_HSM ((0x1) << (GH3X2X_FUNC_OFFSET_HSM)) /**<0x00000008 HSM function */\r
+#define GH3X2X_FUNCTION_FPBP ((0x1) << (GH3X2X_FUNC_OFFSET_FPBP)) /**<0x00000010 FPBP function */\r
+#define GH3X2X_FUNCTION_PWA ((0x1) << (GH3X2X_FUNC_OFFSET_PWA)) /**<0x00000020 PWA function */\r
+#define GH3X2X_FUNCTION_SPO2 ((0x1) << (GH3X2X_FUNC_OFFSET_SPO2)) /**<0x00000040 SPO2 function */\r
+#define GH3X2X_FUNCTION_ECG ((0x1) << (GH3X2X_FUNC_OFFSET_ECG)) /**<0x00000080 ECG function */\r
+#define GH3X2X_FUNCTION_PWTT ((0x1) << (GH3X2X_FUNC_OFFSET_PWTT)) /**<0x00000100 PWTT function */\r
+#define GH3X2X_FUNCTION_SOFT_ADT_GREEN ((0x1) << (GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN)) /**<0x00000200 SOFT ADT GREEN function */\r
+#define GH3X2X_FUNCTION_BT ((0x1) << (GH3X2X_FUNC_OFFSET_BT)) /**<0x00000400 BT function */\r
+#define GH3X2X_FUNCTION_RESP ((0x1) << (GH3X2X_FUNC_OFFSET_RESP)) /**<0x00000800 RESP function */\r
+#define GH3X2X_FUNCTION_AF ((0x1) << (GH3X2X_FUNC_OFFSET_AF)) /**<0x00001000 AF function */\r
+#define GH3X2X_FUNCTION_TEST1 ((0x1) << (GH3X2X_FUNC_OFFSET_TEST1)) /**<0x00002000 TEST1 function */\r
+#define GH3X2X_FUNCTION_TEST2 ((0x1) << (GH3X2X_FUNC_OFFSET_TEST2)) /**<0x00004000 TEST2 function */\r
+#define GH3X2X_FUNCTION_SOFT_ADT_IR ((0x1) << (GH3X2X_FUNC_OFFSET_SOFT_ADT_IR)) /**<0x00008000 SOFT ADT IR function */\r
+#define GH3X2X_FUNCTION_RS0 ((0x1) << (GH3X2X_FUNC_OFFSET_RS0))\r
+#define GH3X2X_FUNCTION_RS1 ((0x1) << (GH3X2X_FUNC_OFFSET_RS1))\r
+#define GH3X2X_FUNCTION_RS2 ((0x1) << (GH3X2X_FUNC_OFFSET_RS2))\r
+#define GH3X2X_FUNCTION_LEAD_DET ((0x1) << (GH3X2X_FUNC_OFFSET_LEAD_DET))\r
+\r
+#define GH3X2X_ADT_FUNC_ENABLE (1)\r
+#define GH3X2X_ECG_FUNC_ENABLE (1)\r
+\r
+#define GH3X2X_ECG_SLOT_NUM (0)\r
+#define GH3X2X_ADT_SLOT_NUM (1)\r
+\r
+#define GH3X2X_ADT_ADC_NUM (0)\r
+\r
+#define GH3X2X_ECG_DOWN_FS (250) //ecg fs:800, 320, 256\r
+#define GH3X2X_ECG_FS (320) //down sample ecg fs: 500 OR 250\r
+#define GH3X2X_PPG_DOWN_FS (250) //down sample ppg fs:\r
+\r
+void GH3X2X_DemoLedAgcPramConfig(void);\r
+\r
+#endif\r
+\r
--- /dev/null
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_drv.h\r
+ *\r
+ * @brief gh3x2x afe driver functions\r
+ *\r
+ * @version v3.2.4.6\r
+ *\r
+ * @author Gooidx Iot Team\r
+ *\r
+ */\r
+#ifndef __GH3X2X_AFE_DRV_H__\r
+#define __GH3X2X_AFE_DRV_H__\r
+\r
+#include "gh3x2x_afe_user.h"\r
+#include "gh3x2x_afe_version.h"\r
+#include <stdint.h>\r
+\r
+#ifndef GH3X2X_AFE_UNUSED_VAR\r
+#define GH3X2X_AFE_UNUSED_VAR(X) ((void)(X))\r
+#endif // GH3X2X_AFE_UNUSED_VAR\r
+\r
+\r
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */\r
+ #ifndef __weak\r
+ #define __weak __attribute__((weak))\r
+ #endif /* __weak */\r
+ #ifndef __packed\r
+ #define __packed __attribute__((__packed__))\r
+ #endif /* __packed */\r
+#endif /* __GNUC__ */\r
+\r
+\r
+\r
+\r
+\r
+\r
+/* type redefine */\r
+typedef unsigned char GU8; /**< 8bit unsigned integer type */\r
+typedef signed char GS8; /**< 8bit signed integer type */\r
+typedef unsigned short GU16; /**< 16bit unsigned integer type */\r
+typedef signed short GS16; /**< 16bit signed integer type */\r
+typedef int GS32; /**< 32bit signed integer type */\r
+typedef unsigned int GU32; /**< 32bit unsigned integer type */\r
+typedef float GF32; /**< float type */\r
+typedef double GD64; /**< double type */\r
+typedef char GCHAR; /**< char type */\r
+typedef unsigned char GBOOL; \r
+typedef long long GS64; /**< 64bit signed integer type */\r
+\r
+\r
+\r
+\r
+#define GH3020_ID (0x00)\r
+#define GH3026_ID (0x01)\r
+\r
+#define GH3220_ID (0x03)\r
+\r
+#define GH3X2X_MP_DISABLE (0)\r
+#define GH3X2X_MP_ENABLE (1)\r
+\r
+/********************* communication interface type******************************/\r
+#define GH3X2X_AFE_COM_INTERFACE_SPI 0\r
+#define GH3X2X_AFE_COM_INTERFACE_I2C 1\r
+\r
+\r
+/********************* spi type ************************************************/\r
+#define GH3X2X_AFE_SPI_SOFTWARE_CS 0\r
+#define GH3X2X_AFE_SPI_HARDWEAR_CS 1\r
+\r
+\r
+/********************* chip process type ***************************************/\r
+#define GH3X2X_AFE_PRO_BY_INT 0\r
+#define GH3X2X_AFE_PRO_BY_POLLING 1\r
+\r
+/********************* chip reset type ***************************************/\r
+#define GH3X2X_AFE_RESET_HARDWARE 0\r
+#define GH3X2X_AFE_RESET_SOFTWARE 1 \r
+\r
+\r
+\r
+#define GH3X2X_AFE_SPI_CS_CTRL_LOW 0\r
+#define GH3X2X_AFE_SPI_CS_CTRL_HIGH 1\r
+\r
+\r
+\r
+\r
+#define GH3X2X_AFE_CMD_SLEEP 0xC4\r
+#define GH3X2X_AFE_CMD_WAKEUP 0xC3\r
+#define GH3X2X_AFE_CMD_RESET 0xC2\r
+#define GH3X2X_AFE_SPI_CMD_WRITE (0xF0)\r
+#define GH3X2X_AFE_SPI_CMD_READ (0xF1)\r
+\r
+\r
+\r
+#define GH3X2X_AFE_RET_OK (0) /**< there is no error */\r
+#define GH3X2X_AFE_RET_GENERIC_ERROR (-1) /**< a generic error happens */\r
+\r
+// special reg addr\r
+#define GH3X2X_AFE_FIFO_REG_ADDR (0xAAAA) /**< fifo reg addr */\r
+#define GH3X2X_AFE_I2C_CMD_ADDR (0xDDDD) /**< i2c cmd reg addr */\r
+\r
+\r
+#define GH3X2X_AFE_SPI_END_DELAY_X_US (3)\r
+#define GH3X2X_AFE_SPI_WAIT_DELAY_X_US (4)\r
+\r
+#define GH3X2X_AFE_WAKE_UP_CMD_DELAY_X_US (500)\r
+#define GH3X2X_AFE_HARD_RESET_DELAY_X_US (100)\r
+\r
+/// null val\r
+#define GH3X2X_PTR_NULL ((void *) 0)\r
+\r
+\r
+\r
+#define GH3X2X_AFE_CHANGE_BYTE_U16(x) ((((u16)(((u8*)(&x))[0]))<<8) + ((u16)(((u8 *)(&x))[1])))\r
+/// get high byte from word\r
+#define GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(sValue) ((GU8)(((sValue) >> 8) & 0xFFU))\r
+/// get low byte from word\r
+#define GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(sValue) ((GU8)((sValue) & 0xFFU))\r
+#define GH3X2X_AFE_MAKEUP_WORD(uchHighByte, uchLowByte) ((GU16)(((((GU16)(uchHighByte)) << 8)& 0xFF00) |\\r
+ (((GU16)(uchLowByte))& 0x00FF)))\r
+\r
+/// makeup dword from bytes\r
+#define GH3X2X_AFE_MAKEUP_DWORD(uchByte3, uchByte2, uchByte1, uchByte0) (((((GU32)(uchByte3)) << 24) & 0xFF000000U)|\\r
+ ((((GU32)(uchByte2)) << 16) & 0x00FF0000U) |\\r
+ ((((GU32)(uchByte1)) << 8) & 0x0000FF00U) |\\r
+ (((GU32)(uchByte0)) & 0x000000FFU))\r
+\r
+\r
+/// rawdata clear all flag\r
+#define GH3X2X_RAWDATA_CLEAR_ALL_FLAG(x) ((x) & 0x00FFFFFF)\r
+\r
+\r
+/// macro of val get bits\r
+#define GH3X2X_AFE_VAL_GET_BIT(x, b) ((x) &= (b))\r
+\r
+\r
+\r
+#define GH3X2X_AFE_EVENT_BIT(x) ((GU16)1 << x)\r
+\r
+\r
+\r
+#define GH3X2X_AFE_REG_IS_VALID(x) ((x) <= 0x0780)\r
+/// macro of val clear bits\r
+#define GH3X2X_VAL_CLEAR_BIT(x, b) ((x) &= (~(b)))\r
+/// macro of val set bits\r
+#define GH3X2X_VAL_SET_BIT(x, b) ((x) |= (b))\r
+\r
+\r
+#define GH3X2X_PIN_STATUS_CS_0_MISO_0 (0)\r
+#define GH3X2X_PIN_STATUS_CS_1_MISO_0 (1)\r
+#define GH3X2X_PIN_STATUS_CS_0_MISO_1 (2)\r
+#define GH3X2X_PIN_STATUS_CS_1_MISO_1 (3)\r
+\r
+\r
+/// get byte3 from dword\r
+#define GH3X2X_AFE_GET_BYTE3_FROM_DWORD(unValue) ((GU8)(((unValue) >> 24) & 0x000000FFU))\r
+/// get byte2 from dword\r
+#define GH3X2X_AFE_GET_BYTE2_FROM_DWORD(unValue) ((GU8)(((unValue) >> 16) & 0x000000FFU))\r
+/// get byte1 from dword\r
+#define GH3X2X_AFE_GET_BYTE1_FROM_DWORD(unValue) ((GU8)(((unValue) >> 8) & 0x000000FFU))\r
+/// get byte0 from dword\r
+#define GH3X2X_AFE_GET_BYTE0_FROM_DWORD(unValue) ((GU8)((unValue) & 0x000000FFU))\r
+\r
+/// macro of val set bits\r
+#define GH3X2X_VAL_SET_BIT(x, b) ((x) |= (b))\r
+\r
+/// macro of clear bits\r
+#define GH3X2X_CLEAR_BIT(x, b) ((x) & (~(b)))\r
+\r
+/// macro of val clear bits\r
+#define GH3X2X_VAL_CLEAR_BIT(x, b) ((x) &= (~(b)))\r
+\r
+/// macro of val get bits\r
+#define GH3X2X_VAL_GET_BIT(x, b) ((x) &= (b))\r
+\r
+\r
+#define GH3X2X_AFE_I2C_DEVICE_BASE (0x28)\r
+#define GH3X2X_AFE_I2C_DEVICE_ADDR (GH3X2X_AFE_I2C_DEVICE_BASE | (GH3X2X_AFE_I2C_DEVICE_CTRL_PIN_STATUS << 1))\r
+\r
+\r
+#define GH3X2X_AFE_FIFO_RAWDATA_SIZE (4)\r
+#define GH3X2X_AFE_SLOT_ADC_NUM_BITS (0xF8)\r
+#define GH3X2X_AFE_CHANNEL_MAP_GET(x) ((x) & GH3X2X_AFE_SLOT_ADC_NUM_BITS)\r
+\r
+/// number of channel map id\r
+#define CHANNEL_MAP_ID_NUM (32)\r
+/// number of channel map id\r
+#define CHANNEL_SLOT_NUM (8)\r
+\r
+\r
+/**\r
+ * @brief register struct\r
+ */\r
+typedef struct\r
+{\r
+ GU16 usRegAddr; /**< register address */\r
+ GU16 usRegData; /**< register val */\r
+} STGH3X2X_AFEReg;\r
+\r
+typedef struct\r
+{\r
+ GU8 uchAddrOffset;\r
+ GU8 uchMsb;\r
+ GU8 uchLsb;\r
+} STGh3x2xAgcReg;\r
+\r
+typedef struct\r
+{\r
+ /// save gain\r
+ GU8 uchTiaGainRecord[CHANNEL_MAP_ID_NUM];\r
+ GU8 uchTiaGainAfterSoftAgc[CHANNEL_MAP_ID_NUM];\r
+ /// save current of drv0 and drv1\r
+ GU16 uchDrvCurrentAfterSoftAgc[CHANNEL_SLOT_NUM];\r
+ GU16 uchDrvCurrentRecord[CHANNEL_SLOT_NUM];\r
+} STGh3x2xAgcInfo;\r
+\r
+extern void GH3X2X_AFE_SpiSendCmd(GU8 uchCmd);\r
+extern void GH3X2X_AFE_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue);\r
+extern GU16 GH3X2X_AFE_SpiReadReg(GU16 usRegAddr);\r
+extern void GH3X2X_AFE_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen);\r
+\r
+extern void GH3X2X_AFE_SpiWriteRegHardwareCs(GU16 usRegAddr, GU16 usRegValue);\r
+extern void GH3X2X_AFE_SpiReadRegsHardwareCs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen);\r
+extern GU16 GH3X2X_AFE_SpiReadRegHardwareCs(GU16 usRegAddr);\r
+extern void GH3X2X_AFE_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue);\r
+extern GU16 GH3X2X_AFE_I2cReadReg(GU16 usRegAddr);\r
+extern void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU8 uchLen);\r
+extern void GH3X2X_AFE_Reset(void);\r
+extern void GH3X2X_AFE_SpiSendCmdHardwareCs(GU8 uchCmd);\r
+extern void GH3X2X_AFE_I2cSendCmd(GU8 uchCmd);\r
+\r
+\r
+/**************** cmd/read/write funciton define **************************/\r
+#if(GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_SPI)\r
+#if(GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS)\r
+#define GH3X2X_AFE_SEND_CMD(cmd) GH3X2X_AFE_SpiSendCmd(cmd)\r
+#define GH3X2X_AFE_WRITE_REG(usRegAddr, usRegValue) GH3X2X_AFE_SpiWriteReg(usRegAddr, usRegValue)\r
+#define GH3X2X_AFE_READ_REG(usRegAddr) GH3X2X_AFE_SpiReadReg(usRegAddr)\r
+#define GH3X2X_AFE_READ_FIFO(buf, len) GH3X2X_AFE_SpiReadFifo(buf, len)\r
+#define GH3X2X_AFE_READ_REGS(usRegAddr,pusRegValueBuffer,uchLen) GH3X2X_AFE_SpiReadRegs(usRegAddr,pusRegValueBuffer,uchLen)\r
+#else\r
+#define GH3X2X_AFE_SEND_CMD(cmd) GH3X2X_AFE_SpiSendCmdHardwareCs(cmd)\r
+#define GH3X2X_AFE_WRITE_REG(usRegAddr, usRegValue) GH3X2X_AFE_SpiWriteRegHardwareCs(usRegAddr, usRegValue)\r
+#define GH3X2X_AFE_READ_REG(usRegAddr) GH3X2X_AFE_SpiReadRegHardwareCs(usRegAddr)\r
+#define GH3X2X_AFE_READ_FIFO(buf, len) GH3X2X_AFE_SpiReadFifoHardwareCs(buf, len)\r
+#define GH3X2X_AFE_READ_REGS(usRegAddr,pusRegValueBuffer,uchLen) GH3X2X_AFE_SpiReadRegsHardwareCs(usRegAddr,pusRegValueBuffer,uchLen)\r
+\r
+#endif\r
+#else\r
+#define GH3X2X_AFE_SEND_CMD(cmd) GH3X2X_AFE_I2cSendCmd(cmd)\r
+#define GH3X2X_AFE_WRITE_REG(usRegAddr, usRegValue) GH3X2X_AFE_I2cWriteReg(usRegAddr, usRegValue)\r
+#define GH3X2X_AFE_READ_REG(usRegAddr) GH3X2X_AFE_I2cReadReg(usRegAddr)\r
+#define GH3X2X_AFE_READ_FIFO(buf, len) GH3X2X_AFE_I2cReadFifo(buf, len)\r
+#define GH3X2X_AFE_READ_REGS(usRegAddr,pusRegValueBuffer,uchLen) GH3X2X_I2cReadRegs(usRegAddr,pusRegValueBuffer,uchLen)\r
+\r
+#endif\r
+\r
+\r
+/***************************** GH3X2X event *************************************************/\r
+\r
+#define GH3X2X_AFE_EVENT_COM_READY (0)\r
+#define GH3X2X_AFE_EVENT_LEAD_ON (1)\r
+#define GH3X2X_AFE_EVENT_LEAD_OFF (2)\r
+#define GH3X2X_AFE_EVENT_FAST_RECOVER_DONE (3)\r
+#define GH3X2X_AFE_EVENT_ADC_DONE (4)\r
+#define GH3X2X_AFE_EVENT_FIFO_FULL (5)\r
+#define GH3X2X_AFE_EVENT_FIFO_OV (6)\r
+#define GH3X2X_AFE_EVENT_FIFO_UN (7)\r
+#define GH3X2X_AFE_EVENT_LED_TUNE_FAIL (8)\r
+#define GH3X2X_AFE_EVENT_LED_TUNE_DONE (9)\r
+#define GH3X2X_AFE_EVENT_WEAR_ON (10)\r
+#define GH3X2X_AFE_EVENT_WEAR_OFF (11)\r
+#define GH3X2X_AFE_EVENT_SLOT_TIME_OUT (12)\r
+#define GH3X2X_AFE_EVENT_SAMPLE_RATE_ERROR (13)\r
+#define GH3X2X_AFE_EVENT_ERSET (14)\r
+\r
+\r
+\r
+\r
+\r
+\r
+/***************************** GH3X2X registers *********************************************/\r
+\r
+\r
+#define GH3X2X_AFE_REG_INT_EVENT_ADDR 0x0508\r
+#define GH3X2X_AFE_REG_FIFO_USE_ADDR 0x050A\r
+#define GH3X2X_AFE_REG_CHIP_READY_CODE_REG_ADDR 0x0036\r
+#define GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR 0x01EC\r
+#define GH3X2X_AFE_REG_INT_EVENT_EN_ADDR 0x0502\r
+\r
+#define GH3X2X_AFE_REG_SLOT_EN_ADDR 0x0108\r
+\r
+\r
+#define GH3X2X_AFE_REG_START_ADDR 0x0000\r
+#define GH3X2X_AFE_REG_START_MSB 0\r
+#define GH3X2X_AFE_REG_START_LSB 0\r
+\r
+\r
+/**************************** GH3X2X ppg control reg index ***********************************************/\r
+#define GH3X2X_AFE_PPG_CTRL_REG_AGC_EN 0\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_UP_LIMIT 1\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DOWN_LIMIT 2\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV0 3\r
+#define GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV1 4\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX0 5\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX1 6\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX2 7\r
+#define GH3X2X_AFE_PPG_CTRL_REG_TIA_GAIN_RX3 8\r
+#define GH3X2X_AFE_PPG_CTRL_REG_AGC_SRC 9\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX0 10\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX1 11\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX2 12\r
+#define GH3X2X_AFE_PPG_CTRL_REG_BG_CANCEL_RX3 13\r
+#define GH3X2X_AFE_PPG_CTRL_REG_SR_MULIPLIPER 14\r
+#define GH3X2X_AFE_PPG_CTRL_ECG_PPG_RX_EN 15\r
+\r
+#define GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB (4)\r
+#define GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB (5)\r
+\r
+#define GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB (0)\r
+#define GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB (1)\r
+\r
+#define GH3X2X_WHO_AM_I_LSB (5)\r
+#define GH3X2X_WHO_AM_I_MSB (7)\r
+\r
+#define GH3X2X_EFUSE_MODE_LSB (0)\r
+#define GH3X2X_EFUSE_MODE_MSB (1)\r
+\r
+#define GH3X2X_EFUSE_CHOOSE_LSB (2)\r
+#define GH3X2X_EFUSE_CHOOSE_MSB (3)\r
+\r
+#define GH3X2X_EFUSE_START_LSB (4)\r
+#define GH3X2X_EFUSE_START_MSB (4)\r
+\r
+#define GH3X2X_EFUSE_CLK_EN_LSB (5)\r
+#define GH3X2X_EFUSE_CLK_EN_MSB (5)\r
+\r
+\r
+\r
+\r
+#define GH3X2X_LED_DRV_AD_REG_REG_ADDR (0x0692)\r
+#define GH3X2X_WHO_AM_I_REG_ADDR (0x0724)\r
+\r
+\r
+// efuse_ctrl block, start addr: 0x0700\r
+#define GH3X2X_EFUSE_CTRL_CMD_REG_ADDR (0x0700)\r
+#define GH3X2X_EFUSE_CTRL_PASSWORD_REG_ADDR (0x0702)\r
+#define GH3X2X_EFUSE_CTRL_TIMING_CFG_0_REG_ADDR (0x0704)\r
+#define GH3X2X_EFUSE_CTRL_TIMING_CFG_1_REG_ADDR (0x0706)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_0_REG_ADDR (0x0708)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_1_REG_ADDR (0x070A)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_2_REG_ADDR (0x070C)\r
+#define GH3X2X_EFUSE_CTRL_WDATA_3_REG_ADDR (0x070E)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR (0x0710)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_1_REG_ADDR (0x0712)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_2_REG_ADDR (0x0714)\r
+#define GH3X2X_EFUSE_CTRL_RDATA_3_REG_ADDR (0x0716)\r
+#define GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR (0x0718)\r
+#define GH3X2X_EFUSE_CTRL_REG_MODE_REG_ADDR (0x071A)\r
+ \r
+\r
+extern GU8 g_uchGh3x2xAfeIntCallBackIsCalled;\r
+\r
+\r
+extern void GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(GU8 uchFlag);\r
+extern void hal_gh3x2x_afe_DelayUs(GU16 usUsec);\r
+extern void hal_gh3x2x_afe_DelayMs(GU16 usMsec);\r
+\r
+extern void hal_gh3x2x_afe_i2c_init(void);\r
+extern GU8 hal_gh3x2x_afe_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length);\r
+extern GU8 hal_gh3x2x_afe_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length);\r
+\r
+extern void hal_gh3x2x_afe_spi_init(void);\r
+extern GU8 hal_gh3x2x_afe_spi_write(GU8 write_buffer[], GU16 length);\r
+extern GU8 hal_gh3x2x_afe_spi_read(GU8 read_buffer[], GU16 length);\r
+extern GU8 hal_gh3x2x_afe_spi_write_F1_and_read(GU8 read_buffer[], GU16 length);\r
+extern void hal_gh3x2x_afe_spi_cs_ctrl(GU8 cs_pin_level);\r
+\r
+extern void hal_gh3x2x_afe_reset_pin_init(void);\r
+extern void hal_gh3x2x_afe_reset_pin_ctrl(GU8 pin_level);\r
+\r
+extern void hal_gh3x2x_afe_int_init(void);\r
+extern void hal_gh3x2x_afe_int_handler_call_back(void);\r
+\r
+extern void GH3X2X_AFE_Log(GCHAR *log_string);\r
+\r
+\r
+\r
+\r
+\r
+extern void GH3X2X_AFE_ChipPro(void);\r
+extern void GH3X2X_AFE_Init(void);\r
+extern void GH3X2X_AFE_StartSampling(GU8 SlotCfgEnable);\r
+extern void GH3X2X_AFE_StopSampling(void);\r
+extern void GH3X2X_AFE_SwitchSlot(GU8 SlotCfgEnable);\r
+\r
+extern void GH3x2xSetPpgCtrlReg(GU8 uchPpgCtrlReg, GU8 uchSlot, GU16 usValue);\r
+extern GU16 GH3x2xGetPpgCtrlReg(GU8 uchPpgCtrlReg, GU8 uchSlot);\r
+\r
+GU16 GH3X2X_AFE_SetLedDrvCurrent(GU8 uchCurrent_mA, GU8 uchDrvNum, GS8 chECODE);\r
+GF32 GH3X2X_AFE_GetLedDrvCurrent(GU16 usDrvCode, GU8 uchDrvNum, GS8 chECODE);\r
+void GH3X2X_AFE_GetEfuseCode(GS8* pchLedDrvEcode,GS8* pchTiaEcode,GS8* pchEcgEcode);\r
+GF32 GH3X2X_AFE_GetTiaCalCode(GS8 chECODE);\r
+GF32 GH3X2X_AFE_GetEcgCalCode(GS8 chECODE);\r
+GCHAR *GH3X2X_GetAfeLibVersion(void);\r
+GU8 GH3X2X_AFE_GetChipId(void);\r
+GS8 GH3X2X_AFE_CheckChipId(void);\r
+void GH3X2X_AFE_LoadEfuse(GU8* puchEfuseBuffer,GU16 EfuseByteLen);\r
+GS8 GH3X2X_AFE_CheckEfuseCrc(void);\r
+void GH3X2X_AFE_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue);\r
+GU16 GH3X2X_AFE_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb);\r
+GU8 GH3X2X_AFE_GetSoftEvent(void);\r
+void GH3X2X_AFE_SetSoftEvent(GU32 unEvent);\r
+void GH3X2X_AFE_ClearSoftEvent(GU32 unEvent);\r
+void GH3X2X_AFE_StartFunction(GU32 unFuncMode);\r
+\r
+void GH3x2x_AFESetAgcReg(GU8 uchAgcReg, GU8 uchSlot, GU16 usValue);\r
+GU16 GH3x2x_AFEGetAgcReg(GU8 uchAgcReg, GU8 uchSlot);\r
+void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize);\r
+void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize);\r
+void GH3X2X_RecordAgcInfo(void);\r
+void GH3X2X_UpdateAgcInfo(void);\r
+\r
+void gh3x2x_control(char* mode, uint8_t enable);\r
+\r
+/*********************************************** master-slaver interface lib function *********************************/\r
+#define GH3X2X_INFO_LOG(...) do {\\r
+ char GH3X2X_AFE_GH3X2X_INFO_LOG[128] = {0};\\r
+ snprintf(GH3X2X_AFE_GH3X2X_INFO_LOG, 128, __VA_ARGS__);\\r
+ GH3X2X_AFE_Log((char *)GH3X2X_AFE_GH3X2X_INFO_LOG);\\r
+ } while(0)\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+#ifndef __GH3X2X_AFE_ECG_H__\r
+#define __GH3X2X_AFE_ECG_H__\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+/**\r
+ * @brief Downsample Function\r
+*/\r
+typedef enum\r
+{\r
+ DOWNSAMPLE_ECG = 0,\r
+ DOWNSAMPLE_PPG,\r
+}EmDownSampleFunction;\r
+\r
+/**\r
+ * @brief Downsample type\r
+*/\r
+typedef enum\r
+{\r
+ DOWNSAMPLE_DEFAULT = 0,\r
+ DOWNSAMPLE_800HZ_TO_500HZ = 1,\r
+ DOWNSAMPLE_800HZ_TO_250HZ = 2,\r
+ DOWNSAMPLE_400HZ_TO_250HZ = 3,\r
+ DOWNSAMPLE_320HZ_TO_250HZ = 4,\r
+ DOWNSAMPLE_256HZ_TO_250HZ = 5,\r
+}EmDownSampleType;\r
+\r
+typedef struct\r
+{\r
+ GS32 snRsXbuf[100/1 + 1];\r
+ GS32 snBufHead;\r
+ GS32 snRsFirState;\r
+ GU32 nRsIcounter;\r
+ GU32 nRrsDcounter;\r
+ GU8 uchFlagFrPrev;\r
+ GU32 nRsLastRaw;\r
+ GU32 fDownStep;\r
+ GU8 uchLinearInterState;\r
+ GU8 uchLinearDataUpdate;\r
+} STGh3x2xRsInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+ GS32 snCounter;\r
+ GS32 sniqCounter;\r
+ long long snniVal;\r
+ long long snnqVal;\r
+ GU8 uchFlagFrPrev;\r
+ GU8 uchFastRecoryHistory;\r
+ long long snniqAmp[5];\r
+} STGh3x2xSoftLeadOffDetInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+ GU8 uchRsFirOrder;\r
+ GU8 uchRsI;\r
+ GU8 uchRsD;\r
+ GU8 uchRsFirCoefNum;\r
+ GU8 uchRsBufSize;\r
+ GU8 uchRsEnable;\r
+ GU32 ufStep;\r
+ GS32* rsFirCoef;\r
+ GU8 uchDownSampleType;\r
+} STGh3x2xDownSampleCalParamInfo;\r
+\r
+#define __SUPPORT_ECG_PPG_DOWNSAMP__ 0\r
+ \r
+/* ecg sample event type */\r
+#define ECG_SAMPLE_EVENT_TYPE_SAMPLE (0x01) /**< sample evt type sample config */\r
+#define ECG_SAMPLE_EVENT_TYPE_SLOT (0x02) /**< sample evt type slot config */\r
+#define ECG_SAMPLE_EVENT_TYPE_LEAD (0x04) /**< sample evt type lead irq */\r
+#define ECG_SAMPLE_EVENT_ALL (ECG_SAMPLE_EVENT_TYPE_SAMPLE | ECG_SAMPLE_EVENT_TYPE_SLOT | \\r
+ ECG_SAMPLE_EVENT_TYPE_LEAD) /**< sample evt all */\r
+\r
+#define GH3X2X_ECG_CTRL_REG_ADDR (0x01EA)\r
+#define GH3X2X_ECG_FAST_RECV_EN_LSB (10) /**< ecg fast recv en lsb @GH3X2X_ECG_CTRL_REG */\r
+#define GH3X2X_ECG_FAST_RECV_EN_MSB (10) /**< ecg fast recv en msb @GH3X2X_ECG_CTRL_REG */\r
+/// ecg fast recover enable config\r
+#define ECG_FAST_RECV_EN_CONFIG(en) do {\\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_ECG_CTRL_REG_ADDR, \\r
+ GH3X2X_ECG_FAST_RECV_EN_LSB, GH3X2X_ECG_FAST_RECV_EN_MSB, (en)); \\r
+ } while (0)\r
+\r
+#define GH3X2X_ADT_LEADON_CR_REG_ADDR (0x0400)\r
+#define GH3X2X_ECG_LEAD_DET_EN_LSB (0) /**< ecg lead det en lsb @GH3X2X_ADT_LEADON_CR_REG */\r
+#define GH3X2X_ECG_LEAD_DET_EN_MSB (0) /**< ecg lead det en msb @GH3X2X_ADT_LEADON_CR_REG */\r
+ \r
+ /// ecg lead detect enable config\r
+#define ECG_LEAD_DET_EN_CONFIG(en) do {\\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_ADT_LEADON_CR_REG_ADDR, \\r
+ GH3X2X_ECG_LEAD_DET_EN_LSB, GH3X2X_ECG_LEAD_DET_EN_MSB, (en)); \\r
+ } while (0) \r
+ \r
+ \r
+#define GET_ECG_LEAD_DET_EN_VAL() (GH3X2X_AFE_ReadRegBitField(GH3X2X_ADT_LEADON_CR_REG_ADDR, \\r
+ GH3X2X_ECG_LEAD_DET_EN_LSB, GH3X2X_ECG_LEAD_DET_EN_MSB))\r
+ \r
+ \r
+\r
+GU8 GH3X2X_AFE_EcgRsHandle(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum, GU16 usEcgSampleRate);\r
+GS32 GH3X2X_LeadOffDetectInit(void);\r
+void GH3X2X_ECGResampleConfig(GU16 usEcgSampleRate);\r
+void GH3X2X_PPGResampleConfig(GU16 usEcgSampleRate); \r
+GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum);\r
+void GH3X2X_AFE_Leadon_hook(void);\r
+void GH3X2X_AFE_Leadoff_hook(void);\r
+void GH3x2xSetEcgOutputFs(GU16 usEcgOutputFs);\r
+\r
+#endif\r
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-13 10:11:20\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-02-17 11:32:58\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/ppg/gh3x2x/inc/gh3x2x_afe_user.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#ifndef __GH3X2X_AFE_USER_H__\r
+#define __GH3X2X_AFE_USER_H__\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+\r
+#define GH3X2X_CHIP_ID GH3220_ID\r
+#define GH3X2X_AFE_MP_MODE GH3X2X_MP_ENABLE\r
+\r
+\r
+/****** communication type config **************************/\r
+#define GH3X2X_AFE_COM_INTERFACE_TYPE GH3X2X_AFE_COM_INTERFACE_I2C\r
+#define GH3X2X_AFE_SPI_TYPE GH3X2X_AFE_SPI_SOFTWARE_CS\r
+\r
+\r
+/****** I2C device id ***************************************/\r
+#define GH3X2X_AFE_I2C_DEVICE_CTRL_PIN_STATUS GH3X2X_PIN_STATUS_CS_0_MISO_0\r
+\r
+\r
+\r
+/****** chip process type config ***************************/\r
+#define GH3X2X_AFE_PRO_TYPE GH3X2X_AFE_PRO_BY_INT\r
+\r
+\r
+\r
+/****** chip reset type config ***************************/\r
+#define GH3X2X_AFE_RESET_TYPE GH3X2X_AFE_RESET_SOFTWARE\r
+\r
+void hal_gh3x2x_afe_int_init(void);\r
+void hal_gh3x2x_afe_int_deinit(void);\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_version.h\r
+ *\r
+ * @brief gh3x2x afe driver version and change log\r
+ *\r
+ * @par history:\r
+ * @verbatim\r
+ * Date Version Notes\r
+ * 2021-11-04 v3.2.4.2 1.add calibration code\r
+ * 2021-11-05 v3.2.4.4 1.fix Efuse calibration bug\r
+ * 2021-11-05 v3.2.4.5 1.add Ffuse Crc Process\r
+ * 2.add Check Chip Id process\r
+ *\r
+ * 2021-11-05 v3.2.4.6 1.update Head file\r
+ * 2021-11-05 v3.2.4.7 1.add ecg lead off det lib\r
+ * 2021-11-05 v3.2.4.8 1.add 5Hz adt\r
+ * 2023-12-06 v3.2.4.9 1.update ecg and agc\r
+ * @endverbatim */\r
+\r
+#ifndef _GH3X2X_AFE_VERSION_H_\r
+#define _GH3X2X_AFE_VERSION_H_\r
+\r
+\r
+#define GH3X2X_DRV_MAJOR_VERSION_NUMBER 3 /**< major version number */\r
+#define GH3X2X_DRV_MINOR_VERSION_NUMBER 2 /**< minor version number */\r
+#define GH3X2X_DRV_REVISION_VERSION_NUMBER 4 /**< revision version number */\r
+#define GH3X2X_DRV_FIXED_VERSION_NUMBER 9 /**< fixed version number */\r
+\r
+#define GH3X2X_TO_STRING(x) #x /**< number to char */\r
+#define GH3X2X_STR(x) GH3X2X_TO_STRING(x) /**< number to char */\r
+\r
+/// makeup version string\r
+#define GH3X2X_VERSION_STRING "v" GH3X2X_STR(GH3X2X_DRV_MAJOR_VERSION_NUMBER)\\r
+ "." GH3X2X_STR(GH3X2X_DRV_MINOR_VERSION_NUMBER)\\r
+ "." GH3X2X_STR(GH3X2X_DRV_REVISION_VERSION_NUMBER)\\r
+ "." GH3X2X_STR(GH3X2X_DRV_FIXED_VERSION_NUMBER)\\r
+ " (build:"__DATE__"_"__TIME__")"\r
+\r
+\r
+#endif /* _GH3X2X_AFE_VERSION_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-06-07 11:18:26
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-06-06 11:23:50
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.h
+ * @Description:
+ *
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
+ */
+#ifndef GH_3X2X_HAL_H__
+#define GH_3X2X_HAL_H__
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+
+// typedef uint32_t PPG_CMD_TYPE_T ;
+
+void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable);
+
+uint32_t tyhx_poweron(void);
+uint32_t tyhx_poweroff(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
--- /dev/null
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_adt.c\r
+ *\r
+ * @brief gh3x2x led agc process functions\r
+ *\r
+ * @version \r
+ *\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include "gh3x2x_afe_adt.h"\r
+\r
+#define GH3X2X_MOVINF_AVA_WINDOW_SIZE 6\r
+\r
+\r
+\r
+EMWearDetectType g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+\r
+GU32 g_punGh3x2xMovingAvaFilterBuf[GH3X2X_MOVINF_AVA_WINDOW_SIZE];\r
+GU8 g_uchGh3x2xMovingAvaFilterPointCnt;\r
+GU8 g_Gh3x2xFilterHaveOutputFlag;\r
+\r
+\r
+\r
+void Gh3x2xMovingAvaFilterInit(void)\r
+{\r
+ g_uchGh3x2xMovingAvaFilterPointCnt = 0;\r
+ g_Gh3x2xFilterHaveOutputFlag = 0;\r
+}\r
+GU8 Gh3x2xMovingAvaFilter(GU32 *Rawdata, GU8 uchBypass)\r
+{\r
+ GU32 unSum = 0;\r
+\r
+ if(uchBypass)\r
+ {\r
+ return 1;\r
+ }\r
+ else\r
+ {\r
+ if(g_uchGh3x2xMovingAvaFilterPointCnt >= GH3X2X_MOVINF_AVA_WINDOW_SIZE)\r
+ {\r
+ for(GU8 uchCnt = 1; uchCnt < GH3X2X_MOVINF_AVA_WINDOW_SIZE; uchCnt ++)\r
+ {\r
+ g_punGh3x2xMovingAvaFilterBuf[uchCnt - 1] = g_punGh3x2xMovingAvaFilterBuf[uchCnt];\r
+ }\r
+ g_uchGh3x2xMovingAvaFilterPointCnt = GH3X2X_MOVINF_AVA_WINDOW_SIZE - 1;\r
+ }\r
+ g_punGh3x2xMovingAvaFilterBuf[g_uchGh3x2xMovingAvaFilterPointCnt] = Rawdata[0];\r
+ g_uchGh3x2xMovingAvaFilterPointCnt ++;\r
+ \r
+ if(g_uchGh3x2xMovingAvaFilterPointCnt > 1)\r
+ {\r
+ for(GU8 uchCnt = 0; uchCnt < g_uchGh3x2xMovingAvaFilterPointCnt - 1; uchCnt ++)\r
+ {\r
+ unSum += g_punGh3x2xMovingAvaFilterBuf[uchCnt];\r
+ }\r
+ Rawdata[0] = unSum/(g_uchGh3x2xMovingAvaFilterPointCnt - 1);\r
+ }\r
+ return 1;\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+GS8 GH3x2xAdtAlgoInit(void)\r
+{\r
+ Gh3x2xMovingAvaFilterInit();\r
+ g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+ return GH3X2X_AFE_RET_OK;\r
+}\r
+GS8 GH3x2xAdtAlgoDeinit(void)\r
+{\r
+ return GH3X2X_AFE_RET_OK;\r
+}\r
+\r
+void GH3x2xAdtAlgoExe(GU32* punRawdata,EMWearStatus* pemWearStatus)\r
+{\r
+ \r
+ GU32 unCurrentFrameRawdata;\r
+\r
+ GU32 unRawDataBeforeFilter;\r
+ unCurrentFrameRawdata = *punRawdata;\r
+ unRawDataBeforeFilter = *punRawdata;\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] punFrameRawdata = %d\r\n", unCurrentFrameRawdata);\r
+\r
+ Gh3x2xMovingAvaFilter(&unCurrentFrameRawdata, 0);\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] punFrameRawdata after filter = %d\r\n", unCurrentFrameRawdata);\r
+\r
+\r
+\r
+ GS32 snDiffRawdata;\r
+\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] start check...\r\n");\r
+\r
+ snDiffRawdata = (GS32)unRawDataBeforeFilter - (GS32)unCurrentFrameRawdata;\r
+\r
+ if(WEAR_DETECT_WEAR_ON == g_uchWearDetectStatus)\r
+ {\r
+ \r
+ *pemWearStatus = WEAR_STATUS_WEAR_OFF;\r
+ if((unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)&&((snDiffRawdata > (GS32)__HARD_ADT_WAER_ON_DIFF_THRD__)))\r
+ {\r
+ *pemWearStatus = WEAR_STATUS_WEAR_ON;\r
+ g_uchWearDetectStatus = WEAR_DETECT_WEAR_OFF;\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] wear on !\r\n");\r
+ }\r
+ else\r
+ {\r
+ if(unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)\r
+ {\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] wear on condition is not match ! r = %d, r_diff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);\r
+ }\r
+ }\r
+ if(snDiffRawdata > 30000)\r
+ {\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe]ppg 5Hz diff big event, Rawdata = %d, unRawdataDiff = %d\r\n",*punRawdata,snDiffRawdata);\r
+ }\r
+ }\r
+ else if(WEAR_DETECT_WEAR_OFF == g_uchWearDetectStatus)\r
+ {\r
+ *pemWearStatus = WEAR_STATUS_WEAR_ON;\r
+ if(unRawDataBeforeFilter < __HARD_ADT_WAER_OFF_THRD__)\r
+ {\r
+ *pemWearStatus = WEAR_STATUS_WEAR_OFF;\r
+ g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe]ppg 5Hz wear off event, Rawdata = %d, unRawdataDiff = %d\r\n",*punRawdata,snDiffRawdata);\r
+ GH3X2X_INFO_LOG("[GH3x2xAdtAlgoExe] wear off !\r\n");\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file gh3x2x_afe_agc.c\r
+ *\r
+ * @brief gh3x2x led agc process functions\r
+ *\r
+ * @version \r
+ *\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include "gh3x2x_afe_agc.h"\r
+#include "gh3x2x_afe_drv.h"\r
+\r
+#define __GH3X2X_AGC_GENERAL_TRIG_H_THD__ ((8388608 + 8388608*0.85f))\r
+#define __GH3X2X_AGC_GENERAL_TRIG_L_THD__ ((8388608 + 8388608*0.15f))\r
+#define __GH3X2X_AGC_GENERAL_IDEAL_VALUE__ ((8388608 + 8388608*0.56f))\r
+#define __GH3X2X_AGC_SPO2_TRIG_H_THD__ ((8388608 + 8388608*0.9f))\r
+#define __GH3X2X_AGC_SPO2_TRIG_L_THD__ ((8388608 + 8388608*0.5f))\r
+#define __GH3X2X_AGC_SPO2_IDEAL_VALUE__ ((8388608 + 8388608*0.7f))\r
+#define __GH3X2X_AGC_CONVERGENCE_LEVEL__ (16) // The values that can be set are 8, 16 and 32, and the recommended value is 16. The larger the value, the smaller the convergence range of AGC. \r
+\r
+//sub channel\r
+\r
+#define GH3X2X_NEW_AGC_SUB_CHNNL_ANAYLSIS_TIME_SEC 1\r
+\r
+#define GH3X2X_AGC_REG_AGC_EN 0\r
+#define GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT 1\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT 2\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV0 3\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV1 4\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX0 5\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX1 6\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX2 7\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX3 8\r
+#define GH3X2X_AGC_REG_AGC_SRC 9\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX0 10\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX1 11\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX2 12\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX3 13\r
+#define GH3X2X_AGC_REG_SR_MULIPLIPER 14\r
+#define GH3X2X_AGC_ECG_PPG_RX_EN 15\r
+\r
+\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+//main chnl\r
+STGh3x2xNewAgcMainChnlInfo g_pstGh3x2xNewAgcMainChnlInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+STGh3x2xNewAgcMainChnlMeanInfo g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+STGh3x2xNewAgcMainChnlIdaelAdjInfo g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+//sub chnl\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+STGh3x2xNewAgcSubChnlRxInfo g_pstGh3x2xNewAgcSubChnlRxInfoEntity[GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT];\r
+#endif\r
+\r
+\r
+STGh3x2xNewAgcMainChnlSat g_pstGh3x2xNewAgcMainChnlSat;\r
+const GU32 g_unNewAgcSpo2Trig_H_Thd = __GH3X2X_AGC_SPO2_TRIG_H_THD__;\r
+const GU32 g_unNewAgcSpo2Trig_L_Thd = __GH3X2X_AGC_SPO2_TRIG_L_THD__;\r
+const GU32 g_unNewAgcSpo2Ideal_value = __GH3X2X_AGC_SPO2_IDEAL_VALUE__;\r
+const GU32 g_unNewAgcGeneTrig_H_Thd = __GH3X2X_AGC_GENERAL_TRIG_H_THD__;\r
+const GU32 g_unNewAgcGeneTrig_L_Thd = __GH3X2X_AGC_GENERAL_TRIG_L_THD__;\r
+const GU32 g_unNewAgcGeneIdeal_value = __GH3X2X_AGC_GENERAL_IDEAL_VALUE__;\r
+const GU8 g_uchAgcConvergence_level = __GH3X2X_AGC_CONVERGENCE_LEVEL__;\r
+\r
+\r
+// soft agc parameter\r
+static STSoftAgcCfg g_stSoftAgcCfg;\r
+extern const GU16 g_usGH3x2xTiaGainR[];\r
+\r
+GU8 g_Gh3x2xNewAgcInitFlag = 0;\r
+\r
+void GH3X2X_LedAgcPramConfig(STSoftAgcCfg* stSoftAgcCfg)\r
+{\r
+ g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn = stSoftAgcCfg->uchSlotxSoftAgcAdjEn; //bit0: slot0\r
+ g_stSoftAgcCfg.uchSlotxSoftBgAdjEn = stSoftAgcCfg->uchSlotxSoftBgAdjEn;\r
+ g_stSoftAgcCfg.stAmbSlotCtrl.uchAmbSampleEn = stSoftAgcCfg->stAmbSlotCtrl.uchAmbSampleEn;\r
+ g_stSoftAgcCfg.uchSpo2RedSlotCfgEn = stSoftAgcCfg->uchSpo2RedSlotCfgEn;\r
+ g_stSoftAgcCfg.uchSpo2IrSlotCfgEn = stSoftAgcCfg->uchSpo2IrSlotCfgEn;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg32uA;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg64uA;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg128uA;\r
+ g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA = stSoftAgcCfg->stSoftAgcGainLimit.uchGainLimitBg256uA;\r
+ g_stSoftAgcCfg.unAgcTrigThd_H = stSoftAgcCfg->unAgcTrigThd_H;\r
+ g_stSoftAgcCfg.unAgcTrigThd_L = stSoftAgcCfg->unAgcTrigThd_L;\r
+ g_stSoftAgcCfg.unAgcRestrainThd_H = stSoftAgcCfg->unAgcRestrainThd_H;\r
+ g_stSoftAgcCfg.unAgcRestrainThd_L = stSoftAgcCfg->unAgcRestrainThd_L;\r
+ \r
+ GH3X2X_INFO_LOG("uchSlotxSoftAgcAdjEn = 0x%X, uchSlotxSoftBgAdjEn = 0x%X\r\n",(int)g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn,(int)g_stSoftAgcCfg.uchSlotxSoftBgAdjEn);\r
+ GH3X2X_INFO_LOG("uchAmbSampleEn = 0x%X, uchAmbSlot = 0x%X\r\n",(int)g_stSoftAgcCfg.stAmbSlotCtrl.uchAmbSampleEn,(int)g_stSoftAgcCfg.stAmbSlotCtrl.uchAmbSlot);\r
+ GH3X2X_INFO_LOG("uchSpo2RedSlotCfgEn = 0x%X,uchSpo2IrSlotCfgEn = 0x%X\r\n",(int)g_stSoftAgcCfg.uchSpo2RedSlotCfgEn,(int)g_stSoftAgcCfg.uchSpo2IrSlotCfgEn);\r
+ GH3X2X_INFO_LOG("stSoftAgcGainLimit = 0x%X,0x%X,0x%X,0x%X\r\n",g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA,g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA,g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA,g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA);\r
+ GH3X2X_INFO_LOG("unAgcTrigThd_H = %d,unAgcTrigThd_L = %d\r\n",(int)g_stSoftAgcCfg.unAgcTrigThd_H,(int)g_stSoftAgcCfg.unAgcTrigThd_L);\r
+ GH3X2X_INFO_LOG("unAgcRestrainThd_H = %d,unAgcRestrainThd_L = %d\r\n",(int)g_stSoftAgcCfg.unAgcRestrainThd_H,(int)g_stSoftAgcCfg.unAgcRestrainThd_L);\r
+\r
+}\r
+\r
+void GH3X2X_StoreRxTiaGainAfterAgc(GU8 uchGain, GU8 uchSlotNo, GU8 uchAdcNo, GU8* puchGainRecord)\r
+{\r
+ puchGainRecord[uchSlotNo*4 + uchAdcNo] = uchGain;\r
+}\r
+\r
+void GH3X2X_StoreDrvCurrentAfterAgc(GU8 DrvCurrent, GU8 uchSlotNo, GU8 uchDrvIndex, GU16* puchDrvCurrentRecord)\r
+{\r
+ if(!uchDrvIndex)\r
+ {\r
+ puchDrvCurrentRecord[uchSlotNo] = (puchDrvCurrentRecord[uchSlotNo]&0xFF00)|DrvCurrent;\r
+ }\r
+ else\r
+ {\r
+ puchDrvCurrentRecord[uchSlotNo] = (puchDrvCurrentRecord[uchSlotNo]&0x00FF)|(DrvCurrent<<8);\r
+ } \r
+}\r
+\r
+\r
+void GH3x2xNewAgcModuleReset(void)\r
+{\r
+ g_Gh3x2xNewAgcInitFlag = 0;\r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlInfo));\r
+ GH3X2X_Memset( (GU8*)(&g_pstGh3x2xNewAgcMainChnlSat),0,sizeof(STGh3x2xNewAgcMainChnlSat)); // init variable\r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlMeanInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlMeanInfo)); \r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlIdaelAdjInfo)); \r
+ \r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ Gh3x2xNewAgcSubChnlModuleReset(); \r
+ #endif\r
+}\r
+ \r
+void GH3X2X_NewAgcRecoveryAgcRegToMainChnl(GU8 uchSlotIdx, STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo)\r
+{\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegLedCurrentMax);\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegLedCurrentMin);\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_AGC_SRC, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegAgcSrc);\r
+ GH3X2X_INFO_LOG("[NewAgc] recover agc src:agc_src = %d, SlotNo = %d\r\n",pstAgcMainChnlInfo ->uchBakRegAgcSrc,uchSlotIdx);\r
+}\r
+\r
+GU8 GH3X2X_NewAgcFindSubChnlSlotInfo(GU8 uchSlot)\r
+{\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ {\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ if(pstAgcMainChnlInfo ->uchEnable)\r
+ {\r
+ if(uchSlot == (pstAgcMainChnlInfo ->uchSlotAdc >> 2))\r
+ {\r
+ return uchSlotCnt;\r
+ }\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+GU16 GH3x2xCalTrigerUpLimitForBiggerGain(GU8 uchCurrentGain ,GU8 uchSlotNo)\r
+{\r
+ GU32 unTempRawdata;\r
+ GU32 unTempTrigThd_H;\r
+\r
+ GU8 uchSlotCnt = GH3X2X_NewAgcFindSubChnlSlotInfo(uchSlotNo);\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ if(pstAgcMainChnlInfo->uchSpo2ChnlIndex)\r
+ {\r
+ unTempTrigThd_H = g_unNewAgcSpo2Trig_H_Thd;\r
+ }else\r
+ {\r
+ unTempTrigThd_H = g_unNewAgcGeneTrig_H_Thd;\r
+ }\r
+ \r
+ if(12 <= uchCurrentGain)\r
+ {\r
+ return 0xFFFF;\r
+ }\r
+ else\r
+ {\r
+ unTempRawdata = unTempTrigThd_H - 8388608;\r
+ unTempRawdata = 8388608 + (GU32)(((float)unTempRawdata)/(float)1.3*(float)g_usGH3x2xTiaGainR[uchCurrentGain]/(float)g_usGH3x2xTiaGainR[uchCurrentGain + 1]);\r
+ return unTempRawdata>>8;\r
+ }\r
+}\r
+\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(GU8 uchSlotNo, GU8 uchRxEn ,GU8 uchNextGain)\r
+{\r
+ for(GU8 uchRxCnt = 0; uchRxCnt < 4; uchRxCnt ++)\r
+ {\r
+ if(uchRxEn&(1 << uchRxCnt))\r
+ {\r
+ for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+ {\r
+ STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn)\r
+ {\r
+ if(((uchSlotNo << 2) + uchRxCnt) == pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usAnalysisCnt = 0;\r
+ if(0xFF != uchNextGain)\r
+ {\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchRxCnt, uchSlotNo, 0);\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = uchNextGain;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(uchNextGain,pstSTGh3x2xNewAgcSubChnlRxInfo->uchSlotAdcNo >> 2);\r
+ }\r
+ } \r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+#endif\r
+ \r
+ \r
+void GH3x2xNewAgcMeanInfoReset(GU8 uchSlotEnChange)\r
+{\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt++)\r
+ {\r
+ if( uchSlotEnChange & (1<<uchSlotCnt)) // SlotEn Change \r
+ {\r
+ for(GU8 uchAgcSlotCnt = 0; uchAgcSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchAgcSlotCnt ++) //// uchAgcSlotCnt'??????slot????\r
+ {\r
+ GU8 uchSlotIdx = ((g_pstGh3x2xNewAgcMainChnlInfoEntity[uchAgcSlotCnt].uchSlotAdc >> 2) & 0x0f);\r
+ GU8 uchEnable = g_pstGh3x2xNewAgcMainChnlInfoEntity[uchAgcSlotCnt].uchEnable;\r
+ if( uchEnable ) \r
+ { \r
+ if( uchSlotIdx == uchSlotCnt) \r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchAgcSlotCnt].usAnalysisCnt = 0;\r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(uchSlotIdx, 0x0F, 0xFF); //clear all rx analysis cnt in this slot\r
+ #endif \r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+} \r
+\r
+GU8 GH3x2xGetDrvCurrent(GU8 uchSlotIdx ,GU8 uchAgcEn)\r
+{\r
+ GU8 uchTempDrv;\r
+ if(2 == uchAgcEn)\r
+ { \r
+ uchTempDrv = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV1, uchSlotIdx);\r
+ }\r
+ else\r
+ {\r
+ uchTempDrv = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV0, uchSlotIdx);\r
+ }\r
+ return uchTempDrv;\r
+}\r
+\r
+void GH3x2xNewAgcChnlInfoInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ if(0 == GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+ {\r
+ return;\r
+ }\r
+ if(0 == g_Gh3x2xNewAgcInitFlag)\r
+ {\r
+ GU8 uchNewAgcSlotCnt = 0;\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+ {\r
+ if((g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn & (1 << uchSlotCnt)))\r
+ {\r
+ if(uchNewAgcSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchEnable = 1;\r
+ g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchSlotAdc = (uchSlotCnt << 2); \r
+ \r
+ /******* slot function Distinguish START******************************************************/ \r
+ if((g_stSoftAgcCfg.uchSpo2RedSlotCfgEn & (1 << uchSlotCnt))||(g_stSoftAgcCfg.uchSpo2IrSlotCfgEn & (1 << uchSlotCnt)))\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchSpo2ChnlIndex = 1;\r
+ GH3X2X_INFO_LOG("[NewAgc] uchNewAgcSpo2SlotCnt = %d\r\n",uchNewAgcSlotCnt);\r
+ }\r
+ /******* slot function Distinguish END******************************************************/\r
+ GH3X2X_INFO_LOG("[NewAgc] uchNewAgcSlotCnt = %d\r\n",uchNewAgcSlotCnt);\r
+ uchNewAgcSlotCnt ++;\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("[NewAgc] error !!! main chnl info is no enough! \r\n");\r
+ while(1);\r
+ }\r
+ }\r
+ }\r
+ g_Gh3x2xNewAgcInitFlag = 1;\r
+ }\r
+\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ { \r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ //GH3X2X_INFO_LOG_PARAM("AGC_InitValue %d: Enable = %d, AgcAdjEn = %d\r\n",uchSlotCnt, pstAgcMainChnlInfo->uchEnable,g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn);\r
+ if(pstAgcMainChnlInfo->uchEnable)\r
+ {\r
+ GU8 uchSlotIdx;\r
+ uchSlotIdx = pstAgcMainChnlInfo ->uchSlotAdc >> 2;\r
+ //GH3X2X_INFO_LOG_PARAM("AGC_InitFlag%d: SlotCfgX=%d, Vaule = %d\r\n",uchSlotCnt, uchSlotIdx, pstAgcMainChnlInfo->uchHaveBakRegFlag);\r
+ if(0 == pstAgcMainChnlInfo ->uchHaveBakRegFlag)\r
+ {\r
+ GU8 uchBgCancel;\r
+ GU8 uchGainLimit;\r
+ GU16 usSampleRate;\r
+ GU16 usEcgPpgRxEn;\r
+\r
+ //bak reg\r
+ pstAgcMainChnlInfo ->uchBakRegAgcEn = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_AGC_EN, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchBakRegAgcSrc = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_AGC_SRC, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchSlotAdc = (uchSlotIdx << 2) + pstAgcMainChnlInfo ->uchBakRegAgcSrc;\r
+ pstAgcMainChnlInfo ->uchBakRegLedCurrentMax = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT, uchSlotIdx); \r
+ pstAgcMainChnlInfo ->uchBakRegLedCurrentMin = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT, uchSlotIdx); \r
+ pstAgcMainChnlInfo ->uchBakTiaGain = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchCurrentTiaGain = pstAgcMainChnlInfo ->uchBakTiaGain;\r
+ pstAgcMainChnlInfo ->uchCurrentDrv = GH3x2xGetDrvCurrent(uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcEn); \r
+ //GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+ uchBgCancel = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_BG_CANCEL_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+ GH3X2X_StoreRxTiaGainAfterAgc(pstAgcMainChnlInfo->uchBakTiaGain, uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcSrc, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ if(0 == uchBgCancel)\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA;\r
+ }\r
+ else if(1 == uchBgCancel)\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA;\r
+ }\r
+ else if(2 == uchBgCancel)\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA;\r
+ }\r
+ else\r
+ {\r
+ uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA;\r
+ }\r
+ GH3X2X_INFO_LOG("[NewAgc] uchGainLimit = %d, uchSlotIdx = %d\r\n",uchGainLimit, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchTiaGainUpLimit = uchGainLimit;\r
+ usSampleRate = 1000/(GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_SR_MULIPLIPER, uchSlotIdx) + 1);\r
+ usEcgPpgRxEn = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_ECG_PPG_RX_EN, uchSlotIdx);\r
+ GH3X2X_INFO_LOG("[NewAgc] usEcgPpgRxEn = 0x%X\r\n",usEcgPpgRxEn);\r
+ if(usEcgPpgRxEn&0x0001) // ecg is enable\r
+ {\r
+ usEcgPpgRxEn = ((usEcgPpgRxEn>>1) & (~0x0008)); //clear RX3 enable bit\r
+ }\r
+ else\r
+ {\r
+ usEcgPpgRxEn = (usEcgPpgRxEn>>1);\r
+ }\r
+ usEcgPpgRxEn &= (~(1 << pstAgcMainChnlInfo ->uchBakRegAgcSrc)); //clear main channel RX enable bit\r
+ \r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].usSampleRate = usSampleRate; //init\r
+ GH3X2X_INFO_LOG("[AgcInit] SlotCnt = %d, SampleRate = %d\r\n", uchSlotCnt, usSampleRate); \r
+ //sub channel slot\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3x2xNewAgcSetNewSubChnl(uchSlotIdx,usEcgPpgRxEn,STGh3x2xAgcInfo);\r
+#endif\r
+ pstAgcMainChnlInfo ->uchHaveBakRegFlag = 1; \r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_AGC_EN, uchSlotIdx, 0); // disable hardware agc \r
+ }\r
+ else\r
+ {\r
+ pstAgcMainChnlInfo ->uchCurrentTiaGain = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+ pstAgcMainChnlInfo ->uchCurrentDrv = GH3x2xGetDrvCurrent(uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcEn);\r
+ //GH3X2X_INFO_LOG_PARAM("Drv Gian inite read %d: IniteDrv = %d, IniteGain = %d\r\n",uchSlotIdx, pstAgcMainChnlInfo ->uchCurrentDrv, pstAgcMainChnlInfo ->uchCurrentTiaGain);\r
+ ////get initial DRV and current in case them change before StartSampling()\r
+// GH3X2X_NewAgcRecoveryAgcRegToMainChnl(uchSlotIdx,pstAgcMainChnlInfo);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+GU32 GH32x2xMedSel(GU32 unData0, GU32 unData1, GU32 unData2)\r
+{\r
+ if((unData0 >= unData1)&&(unData0 <= unData2))\r
+ {\r
+ return unData0;\r
+ }\r
+ if((unData0 >= unData2)&&(unData0 <= unData1))\r
+ {\r
+ return unData0;\r
+ }\r
+ if((unData1 >= unData0)&&(unData1 <= unData2))\r
+ {\r
+ return unData1;\r
+ }\r
+ if((unData1 >= unData2)&&(unData1 <= unData0))\r
+ {\r
+ return unData1;\r
+ }\r
+ return unData2;\r
+}\r
+\r
+float GH3X2X_CalcfRelativeVpp(GU32 unRawdata, GU8 uchDrv, GU8 uchGain)\r
+{\r
+ return ((float)unRawdata/(float)uchDrv/(float)g_usGH3x2xTiaGainR[uchGain]);\r
+}\r
+\r
+void GH3X2X_StoreTiaGainAfterAgc(GU16 usGainRegValue, GU8 uchSlotNo, GU8* puchGainRecord)\r
+{\r
+ for(GU8 uchAdcCnt = 0; uchAdcCnt < 4; uchAdcCnt ++)\r
+ {\r
+ puchGainRecord[uchSlotNo*4 + uchAdcCnt] = (usGainRegValue>>(uchAdcCnt*4))&0x000F;\r
+ GH3X2X_INFO_LOG("StoreTiaGainAfterAgc slot no = %d, adc no = %d, usGainRegValue = %d\r\n", uchSlotNo,uchAdcCnt,usGainRegValue);\r
+ }\r
+}\r
+\r
+void GH3X_AgcGetThreshold( GU8 uchSpo2ChnlIndex, GU32* punTemp_H_Thd, GU32* punTemp_L_Thd )\r
+{ \r
+ if(uchSpo2ChnlIndex) // is spo2 slot\r
+ {\r
+ *punTemp_H_Thd = g_unNewAgcSpo2Trig_H_Thd; \r
+ *punTemp_L_Thd = g_unNewAgcSpo2Trig_L_Thd; \r
+ }else\r
+ { \r
+ *punTemp_H_Thd = g_unNewAgcGeneTrig_H_Thd;\r
+ *punTemp_L_Thd = g_unNewAgcGeneTrig_L_Thd; \r
+ }\r
+}\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void Gh3x2xNewAgcSubChnlModuleReset(void)\r
+{\r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcSubChnlRxInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT*sizeof(STGh3x2xNewAgcSubChnlRxInfo));\r
+ #endif\r
+}\r
+\r
+GU8 GH3x2xNewAgcSetNewSubChnl(GU8 uchSlotNo, GU8 uchRxEn, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GU8 uchSetSuccess = 1;\r
+ for(GU8 uchRxCnt = 0; uchRxCnt < 4; uchRxCnt ++)\r
+ {\r
+ if(uchRxEn&(1 << uchRxCnt))\r
+ {\r
+ uchSetSuccess = 0;\r
+ for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+ {\r
+ STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+ if(0 == pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn = 1;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->uchSlotAdcNo = (uchSlotNo << 2) + uchRxCnt;\r
+ //read current gain\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = GH3x2x_AFEGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchRxCnt, uchSlotNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] Sub chnl current Gain = %d, Slot = %d, Rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain,uchSlotNo,uchRxCnt);\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain, uchSlotNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] usTrigeUpLimitForBiggerGain = %d, Slot = %d, Rx = %d\r\n",((GU32)pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain)<<8,uchSlotNo,uchRxCnt);\r
+ GH3X2X_StoreRxTiaGainAfterAgc(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain, uchSlotNo, uchRxCnt, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ uchSetSuccess = 1;\r
+ break;\r
+ }\r
+ }\r
+ if(0 == uchSetSuccess)\r
+ {\r
+ GH3X2X_INFO_LOG("[NewAgc] Set new sub chnl fail !!! Slot = %d, Rx = %d\r\n",uchSlotNo,uchRxCnt);\r
+ while(1);\r
+ }\r
+ }\r
+ }\r
+ return uchSetSuccess;\r
+}\r
+#endif\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void GH3X2X_NewAgcSubChnlGainAdj(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+ { \r
+ GU16 usAnalysisDiscardLen;\r
+ GU16 usAnalysisEndLen;\r
+ GU8 uchSlotCnt;\r
+ GU8 uchSlotIdx;\r
+ GU8 uchAdcNo;\r
+ GU32 unTempTrigThd_L;\r
+ GU32 unTempTrigThd_H;\r
+ STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+ uchSlotIdx = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo >> 2;\r
+ uchAdcNo = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo&0x03;\r
+ uchSlotCnt = GH3X2X_NewAgcFindSubChnlSlotInfo(uchSlotIdx);\r
+ GU16 usSampleRate = g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].usSampleRate;\r
+ GU8 uchTiaGainLimit = g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt].uchTiaGainUpLimit;\r
+ usAnalysisDiscardLen = (usSampleRate<<1)/5; // 2/5 Fs\r
+ usAnalysisEndLen = usAnalysisDiscardLen + usSampleRate * GH3X2X_NEW_AGC_SUB_CHNNL_ANAYLSIS_TIME_SEC;\r
+ \r
+ GH3X_AgcGetThreshold(g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt].uchSpo2ChnlIndex,&unTempTrigThd_H, &unTempTrigThd_L); \r
+ \r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchEn)\r
+ {\r
+ // prevent unRawdataSum(GU32) overflow\r
+ if( (usAnalysisEndLen - usAnalysisDiscardLen) > 200 ) \r
+ {\r
+ usAnalysisDiscardLen = usAnalysisEndLen - 200; // maximum number of accumulated rawdata is 200\r
+ }\r
+ \r
+ for (GU16 usIndex = 0; usIndex < usFifoLen; usIndex += GH3X2X_AFE_FIFO_RAWDATA_SIZE) \r
+ {\r
+ GU32 unFifoVal;\r
+ GU8 uchSlotAdcNo;\r
+ GU32 unDataRaw; \r
+ unFifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchReadFifoBuffer[usIndex], puchReadFifoBuffer[usIndex + 1], \r
+ puchReadFifoBuffer[usIndex + 2], puchReadFifoBuffer[usIndex + 3]);\r
+ uchSlotAdcNo = ((unFifoVal >> 27)&0x0000001F);\r
+ unDataRaw = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unFifoVal);\r
+ if(uchSlotAdcNo == pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo)\r
+ {\r
+ if(usAnalysisDiscardLen == pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt) //init\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum = 0;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata = unDataRaw;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata = unDataRaw;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt = 0;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain = 0;\r
+ }\r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt < usAnalysisEndLen) //analysising\r
+ { \r
+ GU32 unTempRawdata = GH32x2xMedSel(pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata, pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata, unDataRaw);\r
+ if(usAnalysisDiscardLen == pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt)\r
+ {\r
+ GH3X2X_INFO_LOG("[NewAgc] sub chnl unTempRawdata = %d, Slot = %d, rx = %d\r\n",unTempRawdata, uchSlotIdx, uchAdcNo);\r
+ }\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum += unTempRawdata;\r
+ if(unTempRawdata > unTempTrigThd_H)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usMoreThanUpLimitPointCnt ++;\r
+ }\r
+ if((unTempRawdata >> 8) > pstSTGh3x2xNewAgcSubChnlRxInfo->usTrigeUpLimitForBiggerGain)\r
+ {\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usMoreThanUpLimitPointCntForBiggerGain ++;\r
+ }\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata = pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata = unDataRaw;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt ++; \r
+ }\r
+ else //anlysis finished\r
+ {\r
+ GU32 unAvaRawdata;\r
+ GU16 unRealAnaylsisNum = usAnalysisEndLen - usAnalysisDiscardLen;\r
+ GU8 uchNextGain = 0xFF;\r
+ GU8 uchCurrentGain = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain;\r
+ unAvaRawdata = pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum/unRealAnaylsisNum;\r
+ GH3X2X_INFO_LOG("[NewAgc] sub chnl rawdata ava = %d,DownLimit = %d, Slot = %d, rx = %d\r\n",unAvaRawdata, unTempTrigThd_L,uchSlotIdx, uchAdcNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] usMoreThanUpLimitPointCnt = %d,UpLimit = %d, Slot = %d, rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt, unTempTrigThd_H,uchSlotIdx, uchAdcNo);\r
+ GH3X2X_INFO_LOG("[NewAgc] usMoreThanUpLimitPointCntForBiggerGain = %d,UpLimit = %d, Slot = %d, rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain, ((GU32)pstSTGh3x2xNewAgcSubChnlRxInfo->usTrigeUpLimitForBiggerGain)<<8, uchSlotIdx, uchAdcNo);\r
+ if(pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt > (unRealAnaylsisNum >> 3)) // 1/8 points is bigger than trige up limit\r
+ {\r
+ if(uchCurrentGain > 0)\r
+ {\r
+ uchNextGain = uchCurrentGain - 1;\r
+ }\r
+ }\r
+ if((pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain < (unRealAnaylsisNum >> 3))&&(unAvaRawdata < unTempTrigThd_L))\r
+ {\r
+ if(uchCurrentGain < uchTiaGainLimit)\r
+ {\r
+ uchNextGain = uchCurrentGain + 1;\r
+ }\r
+ }\r
+ if(0xFF != uchNextGain)\r
+ { \r
+ GH3X2X_INFO_LOG("[NewAgc] sub chnl gain change: NewGain = %d, OldGain = %d, Slot = %d, rx = %d\r\n",uchNextGain,uchCurrentGain, uchSlotIdx, uchAdcNo);\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchAdcNo, uchSlotIdx, uchNextGain);\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = uchNextGain;\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(uchNextGain, uchSlotIdx); \r
+ GH3X2X_StoreRxTiaGainAfterAgc(uchNextGain, uchSlotIdx, uchAdcNo, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ }\r
+ pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt = 0; \r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+#endif\r
+\r
+\r
+/*********************************************self-test function start*****************************************/\r
+#define GH3X2X_SPO2_SELF_TEST 0\r
+\r
+#if GH3X2X_SPO2_SELF_TEST\r
+const GU32 g_uchSpo2AgcSelftestSlotAdc = 0x01; //slot0, adc1\r
+const GU32 g_usSpo2AgcFifoLen = 25*4;\r
+const GU32 g_unSpo2AgcRawdata[] = \r
+{\r
+ 10111744,9818116,10074798,9832931,10038819,9812989,10067119,9791632,10220862,9843610,9888564,9974512,10041146,10117796,9858828,10260863,9900963,10159857,10259720,10054459,10247477,9957985,10078474,9916146,9821879\r
+};\r
+\r
+GU8 g_uchSpo2AgcFifoBuffer[4*100];\r
+\r
+void GH3X2X_Spo2AgcFifoDataGen(void)\r
+{\r
+ for (GU16 usIndex = 0; usIndex < g_usSpo2AgcFifoLen; usIndex += GH3X2X_AFE_FIFO_RAWDATA_SIZE) \r
+ {\r
+ if(usIndex >= sizeof(g_uchSpo2AgcFifoBuffer))\r
+ {\r
+ break;\r
+ }\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 0] = (g_uchSpo2AgcSelftestSlotAdc<<3);\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 1] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 16));\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 2] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 8));\r
+ g_uchSpo2AgcFifoBuffer[usIndex + 3] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 0));\r
+ }\r
+}\r
+#endif\r
+/*********************************************self-test function end*****************************************/\r
+\r
+\r
+/****************************************************************\r
+* Description: calculate mean value of main channel \r
+* Input: rawdata \r
+* Return: none\r
+******************************************************************/\r
+static void GH3X2X_NewAgcMainChnlMeanValueCal(GU8* puchReadFifoBuffer, GU16 usFifoLen, GU32 *punRawdataMean, GU8 *pAdjFlag)\r
+{\r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ {\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ GU8 uchMainChnlSlotAdcNo = pstAgcMainChnlInfo ->uchSlotAdc;\r
+ \r
+ if(pstAgcMainChnlInfo ->uchEnable) // is enabled slot\r
+ { \r
+ GU32 unTemp_Trig_H_Thd; \r
+ GU32 unTemp_Trig_L_Thd; \r
+ GU32 unTemp_Ideal_value;\r
+ GU16 usAnalysisEndLen; \r
+ GU16 usAnalysisDiscardLenAdjust = 0;\r
+ GU16 usAnalysisDiscardLenTrige;\r
+ GU32 TrigeMean = 0; \r
+\r
+ if(pstAgcMainChnlInfo->uchSpo2ChnlIndex) // is spo2 slot\r
+ {\r
+ unTemp_Ideal_value= g_unNewAgcSpo2Ideal_value;\r
+ }else\r
+ { \r
+ unTemp_Ideal_value= g_unNewAgcGeneIdeal_value;\r
+ }\r
+ GH3X_AgcGetThreshold( pstAgcMainChnlInfo->uchSpo2ChnlIndex, &unTemp_Trig_H_Thd, &unTemp_Trig_L_Thd); \r
+ \r
+ STGh3x2xNewAgcMainChnlMeanInfo *pstNewAgcMainChnlMeanInfo = &g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt];\r
+ STGh3x2xNewAgcMainChnlIdaelAdjInfo *pstNewAgcMainChnlIdaelAdjInfo = &g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity[uchSlotCnt];\r
+ GU16 usSampleRate = pstNewAgcMainChnlMeanInfo->usSampleRate;\r
+ usAnalysisEndLen = (usSampleRate<<2)/5; // 4/5 Fs \r
+ usAnalysisDiscardLenTrige = (usSampleRate<<1)/5; // drop the first 2/5 data \r
+ //have agc motion at last fifo read period or first init \r
+ if(pstNewAgcMainChnlMeanInfo->uchHaveAgcAtLastReadPrd) \r
+ {\r
+ usAnalysisDiscardLenAdjust = (usSampleRate<<1)/5; // drop the first 2/5 data\r
+ //// After AGC, the previous data is drop to calcluate precise mean\r
+ if(!pstNewAgcMainChnlMeanInfo->uchDropFlag)\r
+ { // The frame count is only cleared for the first time to prevent data num cannot to be SampleRate\r
+ pstNewAgcMainChnlMeanInfo->usAnalysisCnt = 0; \r
+ pstNewAgcMainChnlMeanInfo->uchDropFlag = 1;\r
+ } \r
+ }\r
+ //The data fluctuates when initializing the early stage \r
+ if(!pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst) \r
+ {\r
+ usAnalysisDiscardLenAdjust = (usSampleRate<<1)/5; // drop the first 2/5 data\r
+ }\r
+\r
+ // prevent unSumAdjust(GU32) overflow\r
+ if( (usAnalysisEndLen - usAnalysisDiscardLenAdjust) > 200 )\r
+ {\r
+ usAnalysisDiscardLenAdjust = usAnalysisEndLen - 200; // maximum number of accumulated rawdata is 200\r
+ }\r
+ \r
+ if( (usAnalysisEndLen - usAnalysisDiscardLenTrige) > 200 )\r
+ {\r
+ usAnalysisDiscardLenTrige = usAnalysisEndLen - 200;\r
+ }\r
+\r
+ for (GU16 usIndex = 0; usIndex < usFifoLen; usIndex += GH3X2X_AFE_FIFO_RAWDATA_SIZE) \r
+ {\r
+ GU32 unFifoVal;\r
+ GU8 uchSlotAdcNo;\r
+ GU32 unDataRaw; \r
+ unFifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchReadFifoBuffer[usIndex], puchReadFifoBuffer[usIndex + 1], \r
+ puchReadFifoBuffer[usIndex + 2], puchReadFifoBuffer[usIndex + 3]);\r
+ uchSlotAdcNo = ((unFifoVal >> 27)&0x0000001F);\r
+ unDataRaw = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unFifoVal); \r
+ //GH3X2X_INFO_LOG_SPO2("uchSlotAdcNo = %d\r\n",uchSlotAdcNo);\r
+ //GH3X2X_INFO_LOG_SPO2("uchMainChnlSlotAdcNo = %d\r\n",uchMainChnlSlotAdcNo);\r
+ if(uchSlotAdcNo == uchMainChnlSlotAdcNo)\r
+ {\r
+ // begin Saturation judge \r
+ { \r
+ GU16 usSat_Check_Num_Max = (usSampleRate<<2) + usSampleRate; //// 5 seconds window\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt]++;\r
+ if( unDataRaw > unTemp_Trig_H_Thd)\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt]++;\r
+ }\r
+ //// as soon as posible set the Saturation flag \r
+ if( g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] >= (usSat_Check_Num_Max>>4) ) // about 8% of all checked data\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_flag |= (1<<uchSlotCnt); \r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] = 0; \r
+ } \r
+\r
+ if(g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt] >= usSat_Check_Num_Max ) \r
+ { \r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] = 0;\r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt] = 0; \r
+ } \r
+ } \r
+ // end Saturation judge \r
+ \r
+ //// begin mean calculate \r
+ ////GH3X2X_INFO_LOG_PARAM("slot = %d, uchSlotAdcNo = %d\r\n",uchSlotCnt,uchSlotAdcNo);\r
+ \r
+ if(usAnalysisDiscardLenAdjust == pstNewAgcMainChnlMeanInfo->usAnalysisCnt) //init\r
+ {\r
+ pstNewAgcMainChnlMeanInfo->unSumAdjust = 0;\r
+ pstNewAgcMainChnlMeanInfo->unMaxRawdata = 0; \r
+ pstNewAgcMainChnlMeanInfo->unMinRawdata = 16777216;\r
+ }\r
+ \r
+ if(usAnalysisDiscardLenTrige == pstNewAgcMainChnlMeanInfo->usAnalysisCnt) //init\r
+ {\r
+ pstNewAgcMainChnlMeanInfo->unSumTrige = 0;\r
+ } \r
+ \r
+ if(pstNewAgcMainChnlMeanInfo->usAnalysisCnt < usAnalysisEndLen) //analysising\r
+ {\r
+ pstNewAgcMainChnlMeanInfo->unSumAdjust += unDataRaw;\r
+ pstNewAgcMainChnlMeanInfo->unSumTrige += unDataRaw;\r
+ pstNewAgcMainChnlMeanInfo->usAnalysisCnt++; \r
+ pstNewAgcMainChnlMeanInfo->unMaxRawdata = ((unDataRaw > pstNewAgcMainChnlMeanInfo->unMaxRawdata)? unDataRaw: pstNewAgcMainChnlMeanInfo->unMaxRawdata ); // Max of rawdata\r
+ pstNewAgcMainChnlMeanInfo->unMinRawdata = ((unDataRaw < pstNewAgcMainChnlMeanInfo->unMinRawdata)? unDataRaw: pstNewAgcMainChnlMeanInfo->unMinRawdata ); // Min of rawdata\r
+ }\r
+ else //anlysis finished calculate mean and judge whether AGC\r
+ { \r
+ // mean value to calculate gain and current\r
+ if(usAnalysisEndLen > usAnalysisDiscardLenAdjust)\r
+ {\r
+ punRawdataMean[uchSlotCnt] = pstNewAgcMainChnlMeanInfo->unSumAdjust/(usAnalysisEndLen - usAnalysisDiscardLenAdjust); \r
+ TrigeMean = pstNewAgcMainChnlMeanInfo->unSumTrige / (usAnalysisEndLen - usAnalysisDiscardLenTrige);\r
+ }else // The normal case will not be executed, in case the division by 0 in abnormal case\r
+ {\r
+ punRawdataMean[uchSlotCnt] = unDataRaw; \r
+ TrigeMean = unDataRaw; \r
+ }\r
+ pstNewAgcMainChnlMeanInfo ->unRawdataMean = punRawdataMean[uchSlotCnt];\r
+ pstNewAgcMainChnlMeanInfo->usAnalysisCnt=0;\r
+ // The mean calculation key variable is cleared (Prevent mean calculation from being too small:Accumulation lost some data, but numble of raw is all) \r
+ usAnalysisDiscardLenAdjust = 0; \r
+ pstNewAgcMainChnlMeanInfo->uchHaveAgcAtLastReadPrd = 0; // clear after caculate mean!!! \r
+ //// end mean calculate\r
+\r
+ ///////////////////// whether AGC and adjust the mean value to calculate gain and current\r
+ if( (TrigeMean < unTemp_Trig_L_Thd) || (TrigeMean > unTemp_Trig_H_Thd) )\r
+ {\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ }\r
+ \r
+ if( g_pstGh3x2xNewAgcMainChnlSat.Sat_flag & (1<<uchSlotCnt)) //if the channel is saturation\r
+ {\r
+ GU32 unTempMean = 0; //Pay attention to initialization of local variables\r
+ if( pstNewAgcMainChnlMeanInfo->unMaxRawdata > unTemp_Trig_H_Thd)\r
+ {\r
+ /////////// Pay attention to data truncation, use 64-bi\r
+ unTempMean = (GS64)unTemp_Ideal_value*(GS64)(pstNewAgcMainChnlMeanInfo->unMaxRawdata)/15099494; // to adjust the max data to (0.8*2^23 + 2^23)\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ }\r
+ \r
+ if( punRawdataMean[uchSlotCnt] > unTemp_Ideal_value)\r
+ {\r
+ // adjust the mean value to calculate gain and current (reduce the DC amount)\r
+ punRawdataMean[uchSlotCnt] = ( (punRawdataMean[uchSlotCnt]>unTempMean)? punRawdataMean[uchSlotCnt]:unTempMean );\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ } \r
+ else if( pstNewAgcMainChnlMeanInfo->unMaxRawdata > unTemp_Trig_H_Thd)\r
+ {\r
+ punRawdataMean[uchSlotCnt] = unTempMean; // Increasing the mean value to reduce the DC amount\r
+ } \r
+ }\r
+ ////////////////////////////////////////////////////\r
+ //////////////begin ideal value adjust \r
+ if( (!((*pAdjFlag) & (1<<uchSlotCnt))) && (!( g_pstGh3x2xNewAgcMainChnlSat.Sat_flag & (1<<uchSlotCnt))))//if the channel not adjust and satuartion\r
+ {\r
+ //// The deviation of the mean and the ideal target value is above 1/16 and Data fluctuation is less than a certain value\r
+ if(((pstNewAgcMainChnlMeanInfo->unRawdataMean< ((unTemp_Ideal_value*(g_uchAgcConvergence_level-1))/g_uchAgcConvergence_level) ) \\r
+ || (pstNewAgcMainChnlMeanInfo->unRawdataMean > ((unTemp_Ideal_value*(g_uchAgcConvergence_level+1))/g_uchAgcConvergence_level))) \\r
+ &&( 10*pstNewAgcMainChnlMeanInfo->unMaxRawdata< 12*pstNewAgcMainChnlMeanInfo->unMinRawdata) ) \r
+ {\r
+ if( !pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst ) //// Inite First time \r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst = 1;\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ }\r
+ else\r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt++;\r
+ if(pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt >= 19)\r
+ {\r
+ *pAdjFlag |= (1<<uchSlotCnt); //need adjust gain and current \r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt = 0; \r
+ } \r
+ } \r
+ }\r
+ else\r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt = 0;\r
+ } \r
+ }\r
+ else\r
+ {\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt = 0;\r
+ }\r
+ pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst = 1; //// Must be set to 1 after the first second!!! \r
+ ////end ideal value adjust \r
+ //GH3X2X_INFO_LOG_PARAM("Mean cal: Slot_num = %d, Rawmean = %d, Adjmean = %d, TrigeMean = %d, AdjFlag= %d\r\n", uchSlotCnt,pstNewAgcMainChnlMeanInfo->unRawdataMean, punRawdataMean[uchSlotCnt]);\r
+ //GH3X2X_INFO_LOG_PARAM("Sat flag: SatCnt = %d, SatCheck = %d, CheckMaxNum = %d, Satflag = %d\r\n", g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_Check_Num_Max[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_flag);\r
+ //GH3X2X_INFO_LOG_PARAM("Ideal adjust: SeconsCnt = %d\r\n", pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt);\r
+ //GH3X2X_INFO_LOG_PARAM("Adj flag: Slot_num = %d, Trigmean = %d, L_Thd = %d, H_Thd = %d, Adjflag = %d\r\n", uchSlotCnt,TrigeMean, unTemp_Trig_L_Thd, unTemp_Trig_H_Thd, *pAdjFlag); \r
+ g_pstGh3x2xNewAgcMainChnlSat.Sat_flag &= (~(1<<uchSlotCnt)) ; ////clear the Sat flag \r
+\r
+ }\r
+ } \r
+ }\r
+ }\r
+ \r
+ }\r
+}\r
+\r
+/**\r
+ * @fn GU8 GH3X2X_NewAgcCalDrvCurrentAndGain(GU32 CurRawdata, GU32 IdealRawdata, STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo, GU8* puchIdealDrvCurrent, GU8* puchIdealGain)\r
+ *\r
+ * @brief mark abnormal chnl\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] CurRawdata, IdealRawdata, uchMainChnlInfoIndex\r
+ * @param[out] puchIdealDrvCurrent, puchIdealGain\r
+ *\r
+ * @return 0:DrvCurrent or gain will NOT change 1: DrvCurrent or gain will change\r
+ */\r
+GU8 GH3X2X_NewAgcCalDrvCurrentAndGain(GU32 CurRawdata, GU8 uchMainChnlInfoIndex, GU8* puchIdealDrvCurrent, GU8* puchIdealGain)\r
+{\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchMainChnlInfoIndex];\r
+ STGh3x2xNewAgcMainChnlMeanInfo *pstMainChnlExtralInfo = &g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchMainChnlInfoIndex];\r
+\r
+ GU8 uchDefaultGain = pstAgcMainChnlInfo->uchBakTiaGain;\r
+ GU8 uchGainUpLimit = pstAgcMainChnlInfo->uchTiaGainUpLimit;\r
+ GU8 uchLedCurrentMin = pstAgcMainChnlInfo->uchBakRegLedCurrentMin;\r
+ GU8 uchLedCurrentMax = pstAgcMainChnlInfo->uchBakRegLedCurrentMax;\r
+ GU8 uchCurrentDrv = pstAgcMainChnlInfo->uchCurrentDrv;\r
+ GU8 uchCurrentTiaGain = pstAgcMainChnlInfo->uchCurrentTiaGain;\r
+ \r
+ GU8 uchNewGain = uchDefaultGain;\r
+ GU32 unIdealRawdata_no;\r
+ GU32 unTempDrvCurrent;\r
+ GU8 uchChangeFlag = 0; //bit0: drv current flag bit1: gain flag\r
+ GU8 uchCalFinish = 0;\r
+ GU32 unTrigUpLimit;\r
+ GU8 unCalNum = 12;\r
+ \r
+ if(0 != pstAgcMainChnlInfo->uchSpo2ChnlIndex) // is spo2 slot\r
+ {\r
+ unTrigUpLimit = g_unNewAgcSpo2Trig_H_Thd;\r
+ unIdealRawdata_no= g_unNewAgcSpo2Ideal_value - 8388608;\r
+ }else\r
+ {\r
+ unTrigUpLimit = g_unNewAgcGeneTrig_H_Thd;\r
+ unIdealRawdata_no = g_unNewAgcGeneIdeal_value - 8388608;\r
+ }\r
+ \r
+ //GH3X2X_INFO_LOG_PARAM("Drv cal: UpLimit = %d, Mean = %d, LastMean = %d\r\n",unTrigUpLimit, pstMainChnlExtralInfo->unRawdataMean, pstMainChnlExtralInfo->unLastRawdataMean);\r
+ // reduce rawdata as soon as posible\r
+ if((unTrigUpLimit < pstMainChnlExtralInfo->unRawdataMean)&&(unTrigUpLimit < pstMainChnlExtralInfo->unLastRawdataMean)&&(uchCurrentTiaGain > 0)) \r
+ { \r
+ uchNewGain = 0; \r
+ unTempDrvCurrent = uchLedCurrentMin;\r
+ uchCalFinish = 1;\r
+ }\r
+ pstMainChnlExtralInfo ->unLastRawdataMean = pstMainChnlExtralInfo ->unRawdataMean;\r
+ \r
+ if(0 == uchCalFinish)\r
+ {\r
+ //remove offset\r
+ if(CurRawdata > (8388608 + 2048)) //// Can't open DC Cance !!!\r
+ {\r
+ CurRawdata -= 8388608;\r
+ }\r
+ else\r
+ {\r
+ //The value may be less than 2^23, preventing division by 0\r
+ CurRawdata = 2048; // Take an appropriately large number to prevent calculated DRV current overflow 32bit\r
+ }\r
+ //Rawdata stretch (The principle of magnification: the mean divided by the ideal target value is the data reduction factor )\r
+ if(CurRawdata < 8000000)\r
+ {\r
+ }\r
+ else if(CurRawdata < 8100000)\r
+ {\r
+ CurRawdata = 8000000 + (CurRawdata - 8000000)*6;\r
+ }\r
+ else if(CurRawdata < 8200000)\r
+ {\r
+ CurRawdata = 8000000 + ((CurRawdata - 8000000)<<3);\r
+ }\r
+ else\r
+ {\r
+ // The more saturated the data, the bigger the stretch, the key is that the data is really saturated\r
+ CurRawdata = 8000000 + (CurRawdata - 8000000)*14; // Blood oxygen drops 1 times, heart rate drops 2.5 times \r
+ }\r
+\r
+ //find new drv current and gain\r
+ do\r
+ { \r
+ unTempDrvCurrent = (GS64)(((GU32)uchCurrentDrv*(GU32)g_usGH3x2xTiaGainR[uchCurrentTiaGain]))* \\r
+ (GS64)unIdealRawdata_no/g_usGH3x2xTiaGainR[uchNewGain]/CurRawdata;\r
+\r
+#if 0\r
+ //GH3X2X_INFO_LOG_PARAM("Drv cal %d: CurrentDrv = %d, CurrentGain = %d, IdealRawdata_no = %d\r\n",uchMainChnlInfoIndex, uchCurrentDrv, uchCurrentTiaGain, unIdealRawdata_no);\r
+ //GH3X2X_INFO_LOG_PARAM("Drv cal %d: unTempDrvCurrent = %d, uchNewGain = %d, Meanraw = %d, CurRawdata = %d\r\n",uchMainChnlInfoIndex,unTempDrvCurrent, uchNewGain, pstMainChnlExtralInfo->unRawdataMean, CurRawdata);\r
+#endif\r
+ \r
+ if(unTempDrvCurrent > uchLedCurrentMax) //drv is too big, need increase gain\r
+ {\r
+ if(uchNewGain < uchGainUpLimit)\r
+ {\r
+ uchNewGain ++ ;\r
+ }\r
+ else\r
+ {\r
+ unTempDrvCurrent = uchLedCurrentMax;\r
+ break;\r
+ }\r
+ }\r
+ else if(unTempDrvCurrent < uchLedCurrentMin) //drv is too small, need dncrease gain\r
+ {\r
+ if(uchNewGain > 0)\r
+ {\r
+ uchNewGain -- ;\r
+ }\r
+ else\r
+ {\r
+ unTempDrvCurrent = uchLedCurrentMin;\r
+ break;\r
+ }\r
+ }\r
+ else //got right drv\r
+ {\r
+ break;\r
+ }\r
+ unCalNum --;\r
+ }\r
+ while (unCalNum);\r
+ }\r
+\r
+ puchIdealDrvCurrent[0] = (GU8)unTempDrvCurrent;\r
+ puchIdealGain[0] = (GU8)uchNewGain;\r
+\r
+ if(puchIdealDrvCurrent[0] != uchCurrentDrv)\r
+ {\r
+ uchChangeFlag |= 0x01;\r
+ //GH3X2X_INFO_LOG_PARAM("Drv change %d: CurrentDrv = %d, IdealDrv = %d\r\n",uchMainChnlInfoIndex, uchCurrentDrv, puchIdealDrvCurrent[0]);\r
+ }\r
+ if(puchIdealGain[0] != uchCurrentTiaGain)\r
+ {\r
+ uchChangeFlag |= 0x02;\r
+ //GH3X2X_INFO_LOG_PARAM("Gain change %d: CurrentGain = %d, IdealGain = %d\r\n",uchMainChnlInfoIndex, uchCurrentTiaGain, puchIdealGain[0]);\r
+ }\r
+ \r
+ return uchChangeFlag;\r
+}\r
+\r
+GU8 NewAgcMainChelFlag = 0;\r
+\r
+void GH3X2X_NewAgcMainChnlPro(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GU32 unNewAgcRawdataMeanChnl[8] = {0};\r
+ GU8 uchAdjFlag = 0; // Local variables used as judgments must be initialized to 0\r
+ GU8 uchNewDrvCurrent;\r
+ GU8 uchNewGain; \r
+ GU8 uchChangeFlag = 0; //bit0: drv current flag bit1: gain flag\r
+ \r
+ if(0 == GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+ {\r
+ return;\r
+ }\r
+\r
+#if GH3X2X_SPO2_SELF_TEST\r
+\r
+ GH3X2X_Spo2AgcFifoDataGen();\r
+ puchReadFifoBuffer = g_uchSpo2AgcFifoBuffer;\r
+ usFifoLen = g_usSpo2AgcFifoLen;\r
+#endif\r
+ \r
+ \r
+ GH3X2X_NewAgcMainChnlMeanValueCal( puchReadFifoBuffer,usFifoLen,unNewAgcRawdataMeanChnl,&uchAdjFlag); // caculate mean and whther adjust gain current \r
+ \r
+ for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+ {\r
+ if( uchAdjFlag & (1<<uchSlotCnt)) // need to AGC\r
+ {\r
+ STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+ uchChangeFlag = GH3X2X_NewAgcCalDrvCurrentAndGain(unNewAgcRawdataMeanChnl[uchSlotCnt], uchSlotCnt, &uchNewDrvCurrent,&uchNewGain);\r
+ GU8 uchSlotIdx = ((pstAgcMainChnlInfo ->uchSlotAdc >> 2) & 0x0f);\r
+ if(uchChangeFlag&0x02) //write tia gain to chip\r
+ { \r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx, uchNewGain); \r
+ pstAgcMainChnlInfo->uchCurrentTiaGain = uchNewGain;\r
+ GH3X2X_StoreRxTiaGainAfterAgc(uchNewGain, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegAgcSrc, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+ }\r
+ if(uchChangeFlag&0x01) //write drv current to chip\r
+ {\r
+ //change drv0/1\r
+ pstAgcMainChnlInfo ->uchCurrentDrv = uchNewDrvCurrent;\r
+ \r
+ if((pstAgcMainChnlInfo ->uchBakRegAgcEn)&0x01)\r
+ {\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV0, uchSlotIdx, uchNewDrvCurrent); \r
+ GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,0,STGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+ }\r
+ if((pstAgcMainChnlInfo ->uchBakRegAgcEn)&0x02)\r
+ {\r
+ GH3x2x_AFESetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV1, uchSlotIdx, uchNewDrvCurrent); \r
+ GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,1,STGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+ }\r
+ #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(uchSlotIdx, 0x0F, 0xFF); //clear all rx analysis cnt in this slot\r
+ #endif\r
+ }\r
+ if(uchChangeFlag)\r
+ {\r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].uchHaveAgcAtLastReadPrd = 1; // current or gain change at last time\r
+ g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].uchDropFlag = 0;\r
+ NewAgcMainChelFlag |= (1<<uchSlotCnt); // ADjFlag write to CSV file\r
+ } \r
+ } \r
+ } \r
+}\r
+\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+/**\r
+ * @fn static void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+ * \r
+ * @brief init led agc\r
+ *\r
+ * @attention just use to show function support\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GH3X2X_RecordAgcInfo(); //record agc info\r
+ GH3x2xNewAgcChnlInfoInit(STGh3x2xAgcInfo);\r
+}\r
+/**\r
+ * @fn void GH3X2X_LedAgcPramWrite(GU16 usRegVal, GU16 usRegPosi)\r
+ *\r
+ * @brief write AGC parameter\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegVal reg value\r
+ * @param[in] uchRegPosi reg posi\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_LedAgcPramWrite(GU16 usRegVal, GU16 usRegPosi)\r
+{\r
+\r
+ GU16 usByteOffset;\r
+ GU8 uchByteVal;\r
+ GU8 uchByteCnt;\r
+ for(uchByteCnt = 0; uchByteCnt < 2; uchByteCnt ++)\r
+ {\r
+ uchByteVal = ((usRegVal >> (8*uchByteCnt))&0x00FF);\r
+ usByteOffset = (usRegPosi * 2) + uchByteCnt;\r
+ if(usByteOffset < sizeof(g_stSoftAgcCfg))\r
+ {\r
+ GH3X2X_Memcpy(((GU8 *)(&g_stSoftAgcCfg)) + usByteOffset, (GU8*)(&uchByteVal), 1);\r
+ } \r
+ }\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_LedAgcReset(void)\r
+ *\r
+ * @brief reset agc parameter\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_LedAgcReset(void)\r
+{\r
+ GH3X2X_Memset(&g_stSoftAgcCfg, 0, sizeof(STSoftAgcCfg));\r
+ GH3x2xNewAgcModuleReset();\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen)\r
+ * \r
+ * @brief led agc process function\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchReadFifoBuffer pointer to read fifo data buffer\r
+ * @param[in] usFifoLen read fifo data buffer length\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+ GH3X2X_UpdateAgcInfo();\r
+ if(usFifoLen==0)\r
+ {\r
+ return;\r
+ }\r
+ \r
+ GH3X2X_NewAgcMainChnlPro(puchReadFifoBuffer, usFifoLen,STGh3x2xAgcInfo);\r
+ \r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+ GH3X2X_NewAgcSubChnlGainAdj(puchReadFifoBuffer, usFifoLen,STGh3x2xAgcInfo);\r
+#endif\r
+ \r
+}\r
+#endif\r
+#endif\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
--- /dev/null
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-01-13 11:45:20\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-02-12 10:50:38\r
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/ppg/gh3x2x/src/gh3x2x_afe_demo.c\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#include "gh3x2x_afe_ecg.h"\r
+#include "gh3x2x_afe_adt.h"\r
+#include "gh3x2x_afe_agc.h"\r
+#include "gh3x2x_afe_demo.h"\r
+\r
+\r
+\r
+GU32 g_unFuncMode = GH3X2X_NO_FUNCTION;\r
+\r
+\r
+\r
+void GH3X2X_AFE_StartFunction(GU32 unFuncMode)\r
+{\r
+ //红外佩戴检测\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ADT))\r
+ {\r
+ GH3x2xAdtAlgoInit();\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ADT_SLOT_NUM,GH3X2X_ADT_SLOT_NUM,1);\r
+ }\r
+ \r
+ //心电图\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ECG))\r
+ {\r
+ GH3X2X_LeadOffDetectInit(); \r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ECG_SLOT_NUM,GH3X2X_ECG_SLOT_NUM,1);\r
+ ECG_FAST_RECV_EN_CONFIG(1);\r
+ }\r
+ \r
+ if(g_unFuncMode == GH3X2X_NO_FUNCTION)\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,1);\r
+ }\r
+ g_unFuncMode |= unFuncMode;\r
+\r
+}\r
+\r
+\r
+void GH3X2X_AFE_StopFunction(GU32 unFuncMode)\r
+{\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ADT))\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ADT_SLOT_NUM,GH3X2X_ADT_SLOT_NUM,0);\r
+ GH3x2xAdtAlgoDeinit();\r
+ }\r
+ if(unFuncMode & (GH3X2X_FUNCTION_ECG))\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_SLOT_EN_ADDR,GH3X2X_ECG_SLOT_NUM,GH3X2X_ECG_SLOT_NUM,0);\r
+ ECG_FAST_RECV_EN_CONFIG(0);\r
+\r
+ }\r
+ g_unFuncMode &= (~unFuncMode);\r
+ if(g_unFuncMode == GH3X2X_NO_FUNCTION)\r
+ {\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,0);\r
+ }\r
+ \r
+}\r
+\r
+\r
+void GH3X2X_AFE_Leadon_hook(void)\r
+{\r
+ GH3X2X_AFE_StartFunction(GH3X2X_FUNCTION_ECG);\r
+}\r
+\r
+void GH3X2X_AFE_Leadoff_hook(void)\r
+{\r
+ GH3X2X_AFE_StopFunction(GH3X2X_FUNCTION_ECG);\r
+ ECG_LEAD_DET_EN_CONFIG(0);// enable lead detect\r
+ ECG_LEAD_DET_EN_CONFIG(1);// enable lead detect\r
+ \r
+}\r
+\r
+\r
+void GH3X2X_DemoLedAgcPramConfig(void)\r
+{\r
+ static STSoftAgcCfg stSoftAgcCfg;\r
+\r
+ stSoftAgcCfg.uchSlotxSoftAgcAdjEn = 1; //bit0-bit7: slot0 -slot7 \r
+ stSoftAgcCfg.uchSlotxSoftBgAdjEn = 0;\r
+ stSoftAgcCfg.stAmbSlotCtrl.uchAmbSampleEn = 0;\r
+ stSoftAgcCfg.uchSpo2RedSlotCfgEn = 2; //bit0-bit7: slot0 -slot7 for spo2 red \r
+ stSoftAgcCfg.uchSpo2IrSlotCfgEn = 4; //bit0-bit7: slot0 -slot7 for spo2 ir\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA = 8;\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA = 6;\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA = 5;\r
+ stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA = 4;\r
+ stSoftAgcCfg.unAgcTrigThd_H = (GU32)(8388608 + 8388608*0.85f);\r
+ stSoftAgcCfg.unAgcTrigThd_L = (GU32)(8388608 + 8388608*0.15f);\r
+ stSoftAgcCfg.unAgcRestrainThd_H = 12868608;\r
+ stSoftAgcCfg.unAgcRestrainThd_L = 10692608;\r
+ \r
+ GH3X2X_LedAgcPramConfig(&stSoftAgcCfg);\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/**\r
+ * @copyright (c) 2019 - 2024, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file gh3x2x_afe_drv.c\r
+ * \r
+ * @brief gh3x2x driver example code\r
+ *\r
+ * @author Gooidx Iot Team\r
+ * \r
+ * @attention\r
+ * This file just show how to init and control gh3x2x sampling.\r
+ */\r
+#include "stdio.h"\r
+#include "gh3x2x_afe_drv.h"\r
+#include "gh3x2x_afe_user.h"\r
+#include "gh3x2x_afe_ecg.h"\r
+#include "gh3x2x_afe_agc.h"\r
+#include "gh3x2x_afe_adt.h"\r
+#include "gh3x2x_afe_demo.h"\r
+\r
+#include "custom_utils.h"\r
+\r
+ \r
+#define SWAP_SIZE_OF_GU16 (2)\r
+#define SWAP_INDEX_OF_NEXT_BYTE (1)\r
+\r
+#define GH3X2X_I2C_BUS I2C_BUS_2\r
+\r
+//extern void GH3X2X_SoftLedADJAutoADJInt(void);\r
+//extern void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen);\r
+//extern void GH3X2X_LedAgcReset(void);\r
+//extern void GH3X2X_LedAgcPramWrite(void);\r
+//extern void GH3X2X_LedAgcInit(void);\r
+\r
+STGh3x2xAgcInfo g_stGh3x2xAgcInfo = {0};\r
+STGh3x2xAgcInfo *g_pstGh3x2xAgcInfo = &g_stGh3x2xAgcInfo;\r
+\r
+GU8 g_uchNeedWakeUpGh3x2xAfe = 1; // 0: do not need wake up gh3x2x 1: need wake up gh3x2x\r
+GU8 g_uchGh3x2xAfeIntCallBackIsCalled = 0; //0: no new interrupt 1: have new interrupt\r
+\r
+/*********************************************** reg cfg package *******************************************/\r
+STGH3X2X_AFEReg GH3X2X_AFE_reg_list[] =\r
+{\r
+// {0x0000, 0x0610}, {0x0004, 0x001F}, {0x0006, 0x0001}, {0x000A, 0x0010}, {0x000E, 0x000D}, {0x0100, 0x0100},\r
+// {0x010A, 0x27FC}, {0x0110, 0x0F65}, {0x0114, 0x00AA}, {0x011E, 0x021F}, {0x0120, 0x041F}, {0x0122, 0x137F},\r
+// {0x0126, 0xC77C}, {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA}, {0x013A, 0x010C}, {0x013C, 0x0400},\r
+// {0x01EC, 0x027C}, {0x01EE, 0x00AC}, {0x0200, 0x0120}, {0x0208, 0x0551}, {0x0280, 0x0A00}, {0x0282, 0xF530},\r
+// {0x0284, 0x9388}, {0x0286, 0xC45C}, {0x0288, 0xA328}, {0x0408, 0x0001}, {0x0410, 0x49F0}, {0x0412, 0x0082},\r
+// {0x0414, 0x49F0}, {0x0416, 0x0082}, {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0108}, {0x0428, 0x0102},\r
+// {0x0502, 0x4360}, {0x0504, 0x000A}, {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0400}, {0x0698, 0x2310},\r
+// {0x0700, 0x0000}, \r
+ \r
+// {0x0000, 0x0602}, {0x0004, 0x0013}, {0x0006, 0x0201}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0048},\r
+// {0x0100, 0x0100}, {0x010A, 0x0462}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x0120, 0x0400},\r
+// {0x0126, 0xC73C}, {0x0128, 0x0404}, {0x012A, 0x0404}, {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA},\r
+// {0x0136, 0x00FF}, {0x013A, 0x000C}, {0x013C, 0x0400}, {0x01EA, 0x0033}, {0x01EC, 0x0030}, {0x01EE, 0x0098},\r
+// {0x0200, 0x1020}, {0x0402, 0x5555}, {0x0404, 0x4120}, {0x0406, 0x0041}, {0x0408, 0x0001}, {0x0410, 0x49F0},\r
+// {0x0412, 0x0082}, {0x0414, 0x49F0}, {0x0416, 0x0082}, {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0109},\r
+// {0x0428, 0x0108}, {0x0480, 0x6550}, {0x0502, 0x4C66}, {0x0506, 0x0020}, {0x0588, 0x0008}, {0x0692, 0x0233},\r
+// {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000}, {0x0400, 0x5557}, {0x1000, 0x0000},\r
+// {0x1002, 0x3197}, {0x1004, 0x0000}, {0x1006, 0x6C91}, {0x1008, 0x2CE1}, {0x100A, 0x0001}, {0x10E0, 0x0000},\r
+// {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202}, {0x10EC, 0x0202},\r
+// {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000}, {0x2000, 0x0004}, {0x2002, 0x2A22},\r
+// {0x2004, 0x3A32}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005}, {0x288E, 0x00FA}, {0x3000, 0x0101},\r
+// {0x3002, 0x0000}, {0x3004, 0x49F0}, {0x3006, 0x0082}, {0x4500, 0x46C9}, {0x4502, 0x0F0F}, {0x4504, 0x0002},\r
+// {0x4506, 0x0140}, {0xFFFF, 0x0001}\r
+\r
+ {0x0000, 0x0610}, {0x0004, 0x001F}, {0x0006, 0x0001}, {0x000A, 0x0050}, {0x000E, 0x000D}, {0x0100, 0x0100},\r
+ {0x010A, 0x277C}, {0x0110, 0x0D14}, {0x0112, 0x5555}, {0x0114, 0x00AA}, {0x011E, 0x0019}, {0x0120, 0x0400},\r
+ {0x0122, 0x0CFF}, {0x0126, 0xC704}, {0x0128, 0x0001}, {0x012A, 0x0000}, {0x012C, 0x0C10}, {0x012E, 0x4442},\r
+ {0x0130, 0x0002}, {0x0136, 0x0003}, {0x013A, 0x010C}, {0x013C, 0x0400}, {0x01EC, 0x0136}, {0x01EE, 0x00AC},\r
+ {0x0200, 0x0120}, {0x0208, 0x0551}, {0x0280, 0x0A00}, {0x0282, 0xF530}, {0x0284, 0x9388}, {0x0286, 0xC45C},\r
+ {0x0288, 0xA328}, {0x0408, 0x0001}, {0x0410, 0x49F0}, {0x0412, 0x0082}, {0x0414, 0x49F0}, {0x0416, 0x0082},\r
+ {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0108}, {0x0428, 0x0102}, {0x0502, 0x4F60}, {0x0504, 0x000A},\r
+ {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0400}, {0x0698, 0x2310}, {0x0700, 0x0000}, {0x1000, 0x0000},\r
+ {0x1002, 0x3197}, {0x1004, 0x0000}, {0x1006, 0x6904}, {0x1008, 0x2AF6}, {0x100A, 0x0001}, {0x10E0, 0x0000},\r
+ {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202}, {0x10EC, 0x0202},\r
+ {0x10EE, 0x0202}, {0x1100, 0x0004}, {0x1102, 0x0000}, {0x1120, 0x0050}, {0x1122, 0x0005}, {0x1124, 0x0000},\r
+ {0x1140, 0x0000}, {0x1142, 0x00C8}, {0x1144, 0x0001}, {0x1160, 0x0001}, {0x1162, 0x0000}, {0x1164, 0x0000},\r
+ {0x1166, 0x4568}, {0x1168, 0xCCCC}, {0x116A, 0x00EC}, {0x116C, 0x3333}, {0x116E, 0x0093}, {0x1170, 0x5C00},\r
+ {0x1172, 0x00C4}, {0x1174, 0x2800}, {0x1176, 0x00A3}, {0x2000, 0x0001}, {0x2002, 0x0022}, {0x2022, 0x0004},\r
+ {0x2024, 0x0901}, {0x2026, 0x1911}, {0x2880, 0x0005}, {0x2882, 0x0019}, {0x3000, 0x0001}, {0x3002, 0x0000},\r
+ {0x3004, 0x49F0}, {0x3006, 0x0082}, {0xFFFF, 0x0001}\r
+};\r
+\r
+GU16 GH3X2X_AFE_reg_list_len = sizeof(GH3X2X_AFE_reg_list) / sizeof(GH3X2X_AFE_reg_list[0]);\r
+\r
+\r
+void GH3X2X_SwapLittleBigEndianData(GU8 *puchDataBuffer, GU16 usDataLength)\r
+{\r
+ GU16 usIndex = 0;\r
+\r
+ for (usIndex = 0; usIndex < (usDataLength / SWAP_SIZE_OF_GU16); usIndex++)\r
+ {\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16] ^= \\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE];\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE] ^= \\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16];\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16] ^= \\r
+ puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE];\r
+ }\r
+}\r
+\r
+\r
+#if ( GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_SPI )\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_SpiSendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief Send cmd via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] uchCmd spi cmd\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+void GH3X2X_AFE_SpiSendCmd(GU8 uchCmd)\r
+{\r
+ GU8 uchBuffArr[1];\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = uchCmd;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+#endif\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+void GH3X2X_AFE_SpiSendCmdHardwareCs(GU8 uchCmd)\r
+{\r
+ GU8 uchBuffArr[1];\r
+ uchBuffArr[0] = uchCmd;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+}\r
+#endif\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief Write register via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] usRegValue register data\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+void GH3X2X_AFE_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+ GU8 uchBuffArr[7];\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[3] = 0;\r
+ uchBuffArr[4] = 2;\r
+ uchBuffArr[5] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegValue);\r
+ uchBuffArr[6] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegValue);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 7);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+#endif\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+void GH3X2X_AFE_SpiWriteRegHardwareCs(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+ GU8 puchWriteBuf[7];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = usRegAddr>>8;\r
+ puchWriteBuf[2] = usRegAddr&0x00FF;\r
+ puchWriteBuf[3] = 0;\r
+ puchWriteBuf[4] = 2;\r
+ puchWriteBuf[5] = usRegValue>>8;\r
+ puchWriteBuf[6] = usRegValue&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 7);\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn static GU16 GH3X2X_AFE_SpiReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief Read register via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[out] None\r
+ *\r
+ * @return register data\r
+ */\r
+ \r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+GU16 GH3X2X_AFE_SpiReadReg(GU16 usRegAddr)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 3);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_READ;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_read(uchBuffArr, 2);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ return GH3X2X_AFE_MAKEUP_WORD(uchBuffArr[0], uchBuffArr[1]);\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen)\r
+ *\r
+ * @brief Read multi register via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] pusRegValueBuffer pointer to register value buffer\r
+ * @param[in] uchLen registers len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 3);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_READ;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_read((GU8 *)pusRegValueBuffer, uchLen * 2);\r
+ GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueBuffer, (GU16)((GU16)uchLen * 2));\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+\r
+#endif\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+GU16 GH3X2X_AFE_SpiReadRegHardwareCs(GU16 usRegAddr)\r
+{\r
+ GU8 puchWriteBuf[7];\r
+ GU8 puchReadBuf[2];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = usRegAddr>>8;\r
+ puchWriteBuf[2] = usRegAddr&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 3);\r
+ hal_gh3x2x_afe_spi_write_F1_and_read(puchReadBuf, 2);\r
+ return ((((GU16)puchReadBuf[0])<<8) + puchReadBuf[1]);\r
+}\r
+\r
+\r
+\r
+void GH3X2X_AFE_SpiReadRegsHardwareCs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU8 uchLen)\r
+{\r
+ GU8 puchWriteBuf[3];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = usRegAddr>>8;\r
+ puchWriteBuf[2] = usRegAddr&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 3);\r
+ hal_gh3x2x_afe_spi_write_F1_and_read((GU8 *)pusRegValueBuffer, uchLen * 2);\r
+ GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueBuffer, (GU16)((GU16)uchLen * 2));\r
+}\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_SpiReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief Read fifo via spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchDataBuffer pointer to buffer for fifo rawdata\r
+ * @param[in] usLen fifo bytes len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+ \r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+static void GH3X2X_AFE_SpiReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_WRITE;\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 3);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_LOW);\r
+ uchBuffArr[0] = GH3X2X_AFE_SPI_CMD_READ;\r
+ hal_gh3x2x_afe_spi_write(uchBuffArr, 1);\r
+ hal_gh3x2x_afe_spi_read(puchDataBuffer, usLen);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_WAIT_DELAY_X_US);\r
+ hal_gh3x2x_afe_spi_cs_ctrl(GH3X2X_AFE_SPI_CS_CTRL_HIGH);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_SPI_END_DELAY_X_US);\r
+}\r
+\r
+#endif\r
+\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS) \r
+void GH3X2X_AFE_SpiReadFifoHardwareCs(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+ GU8 puchWriteBuf[3];\r
+ puchWriteBuf[0] = 0xF0;\r
+ puchWriteBuf[1] = 0xAAAA>>8;\r
+ puchWriteBuf[2] = 0xAAAA&0x00FF;\r
+ hal_gh3x2x_afe_spi_write(puchWriteBuf, 3);\r
+ hal_gh3x2x_afe_spi_write_F1_and_read(puchDataBuffer, usLen);\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+#if ( GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_I2C )\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_I2cSendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief Send cmd via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] uchCmd i2c cmd\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_I2cSendCmd(GU8 uchCmd)\r
+{\r
+ GU8 uchBuffArr[3] = {0};\r
+\r
+ uchBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(GH3X2X_AFE_I2C_CMD_ADDR);\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_I2C_CMD_ADDR);\r
+ uchBuffArr[2] = uchCmd;\r
+ hal_gh3x2x_afe_i2c_write(GH3X2X_AFE_I2C_DEVICE_BASE, uchBuffArr, 3);\r
+}\r
+\r
+/**\r
+ * @fn static void GH3X2X_AFE_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief Write register via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] usRegValue register data\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+ GU8 uchBuffArr[4] = {0};\r
+\r
+ uchBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[2] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegValue);\r
+ uchBuffArr[3] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegValue);\r
+ hal_gh3x2x_afe_i2c_write(GH3X2X_AFE_I2C_DEVICE_BASE, uchBuffArr, 4);\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn static GU16 GH3X2X_I2cReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief Read register via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[out] None\r
+ *\r
+ * @return register data\r
+ */\r
+GU16 GH3X2X_AFE_I2cReadReg(GU16 usRegAddr)\r
+{\r
+ GU8 uchCmdBuffArr[2] = {0};\r
+ GU8 uchReadBuffArr[2] = {0};\r
+\r
+ uchCmdBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchCmdBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+ hal_gh3x2x_afe_i2c_read(GH3X2X_AFE_I2C_DEVICE_BASE, uchCmdBuffArr, 2, uchReadBuffArr, 2);\r
+\r
+ return GH3X2X_AFE_MAKEUP_WORD(uchReadBuffArr[0], uchReadBuffArr[1]);\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU8 uchLen)\r
+ *\r
+ * @brief Read multi register via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] pusRegValueBuffer pointer to register value buffer\r
+ * @param[in] uchLen registers len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU8 uchLen)\r
+{\r
+ GU8 uchBuffArr[2] = {0};\r
+\r
+ uchBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+ uchBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+\r
+ hal_gh3x2x_afe_i2c_read(GH3X2X_AFE_I2C_DEVICE_BASE, uchBuffArr, 2, \\r
+ (GU8 *)pusRegValueArr, uchLen * 2);\r
+ GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueArr, (GU16)uchLen * 2);\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn static void GH3X2X_I2cReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief Read fifo via i2c\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchDataBuffer pointer to buffer for fifo rawdata\r
+ * @param[in] usLen fifo bytes len\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_I2cReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+ GU8 uchCmdBuffArr[2] = {0};\r
+\r
+ uchCmdBuffArr[0] = GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ uchCmdBuffArr[1] = GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_FIFO_REG_ADDR);\r
+ hal_gh3x2x_afe_i2c_read(GH3X2X_AFE_I2C_DEVICE_BASE, uchCmdBuffArr, 2, puchDataBuffer, usLen);\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn void GH3X2X_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+ *\r
+ * @brief write register bit field via i2c or spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] uchLsb lsb of bit field\r
+ * @param[in] uchMsb msb of bit field\r
+ * @param[in] usRegValue register data\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+{\r
+ GU16 usMakData = ((((GU16)0x0001) << (uchMsb - uchLsb + 1)) - 1) << uchLsb;\r
+ GU16 usRegData = 0;\r
+ usRegData = GH3X2X_AFE_READ_REG(usRegAddr);\r
+ GH3X2X_VAL_CLEAR_BIT(usRegData, usMakData);\r
+ GH3X2X_VAL_SET_BIT(usRegData, (usValue << uchLsb) & usMakData);\r
+ GH3X2X_AFE_WRITE_REG(usRegAddr, usRegData);\r
+}\r
+\r
+/**\r
+ * @fn GU16 GH3X2X_AFE_READ_REGBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+ *\r
+ * @brief Read register bit field via i2c or spi\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] usRegAddr register addr\r
+ * @param[in] uchLsb lsb of bit field\r
+ * @param[in] uchMsb msb of bit field\r
+ * @param[out] None\r
+ *\r
+ * @return register bit field data\r
+ */\r
+GU16 GH3X2X_AFE_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+{\r
+ GU16 usMakData = ((((GU16)0x0001) << (uchMsb - uchLsb + 1)) - 1) << uchLsb;\r
+ GU16 usRegData = 0;\r
+ usRegData = GH3X2X_AFE_READ_REG(usRegAddr);\r
+ GH3X2X_AFE_VAL_GET_BIT(usRegData, usMakData);\r
+ usRegData >>= uchLsb;\r
+ return usRegData;\r
+}\r
+\r
+\r
+void GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(GU8 uchFlag)\r
+{\r
+ g_uchNeedWakeUpGh3x2xAfe = uchFlag;\r
+}\r
+\r
+GU8 GH3X2X_AFE_GetNeedWakeUpGh3x2xFlag(void)\r
+{\r
+ return g_uchNeedWakeUpGh3x2xAfe;\r
+}\r
+\r
+\r
+\r
+void GH3X2X_AFE_ExitLowPowerMode(void)\r
+{\r
+ GH3X2X_AFE_SEND_CMD(GH3X2X_AFE_CMD_WAKEUP);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_WAKE_UP_CMD_DELAY_X_US);\r
+}\r
+\r
+void GH3X2X_AFE_EnterLowPowerMode(void)\r
+{\r
+ GH3X2X_AFE_SEND_CMD(GH3X2X_AFE_CMD_SLEEP);\r
+ GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(1);\r
+}\r
+\r
+\r
+void GH3X2X_AFE_ClearEvent(GU16 usEvent)\r
+{\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_INT_EVENT_ADDR,usEvent);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_SendRegPackage(STGH3X2X_AFEReg* GH3X2X_AFE_reg_list, GU16 reg_list_len)\r
+ *\r
+ * @brief send register package (for initialize GH3X2X_AFE chip)\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GH3X2X_AFE_reg_list reg list that will be written to GH3X2X_AFE\r
+ * @param[in] reg_list_len reg count that contained in reg list\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_SendRegPackage(STGH3X2X_AFEReg* GH3X2X_AFE_reg_list, GU16 reg_list_len)\r
+{\r
+ GU16 luwIndex = 0;\r
+\r
+ if ((GH3X2X_AFE_reg_list != NULL) && (reg_list_len > 0))\r
+ {\r
+ for (luwIndex = 0; luwIndex < reg_list_len; luwIndex++)\r
+ {\r
+ if (GH3X2X_AFE_REG_IS_VALID(GH3X2X_AFE_reg_list->usRegAddr))\r
+ {\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_reg_list->usRegAddr, GH3X2X_AFE_reg_list->usRegData); \r
+ } \r
+ GH3X2X_AFE_reg_list++;\r
+ }\r
+ }\r
+\r
+ if(GH3X2X_AFE_PRO_TYPE == GH3X2X_AFE_PRO_BY_POLLING)\r
+ {\r
+ //int pin should not action when poling mode\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_INT_EVENT_EN_ADDR, 0); \r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn GS8 GH3X2X_HardReset(void)\r
+ *\r
+ * @brief Gh3x2x softreset via i2c/spi, can read&write reg with gh3x2x after reset\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ * @retval #GH3X2X_RET_OK return successfully\r
+ * @retval #GH3X2X_RET_GENERIC_ERROR reset pin control function not register\r
+ */\r
+void GH3X2X_AFE_Reset(void)\r
+{\r
+ GH3X2X_AFE_ClearEvent(0xFFFF);\r
+ #if(GH3X2X_AFE_RESET_TYPE == GH3X2X_AFE_RESET_HARDWARE)\r
+ hal_gh3x2x_afe_reset_pin_ctrl(0);\r
+ hal_gh3x2x_afe_DelayUs(GH3X2X_AFE_HARD_RESET_DELAY_X_US); \r
+ hal_gh3x2x_afe_reset_pin_ctrl(1); \r
+ #else\r
+ GH3X2X_AFE_SEND_CMD(GH3X2X_AFE_CMD_RESET);\r
+ #endif\r
+ hal_gh3x2x_afe_DelayMs(10);\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn GS8 GH3X2X_CommunicateConfirm(void)\r
+ *\r
+ * @brief Communication operation interface confirm\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_CommunicateConfirm(void)\r
+{\r
+ GU16 uchReadData;\r
+ GU16 uchWriteData;\r
+ \r
+ if (GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_CHIP_READY_CODE_REG_ADDR) == 0xAA55)\r
+ {\r
+ uchReadData = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR);\r
+ GH3X2X_INFO_LOG("slot_time0 reg = %d\r\n", (int)uchReadData);\r
+ uchWriteData = ~uchReadData;\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR, uchWriteData);\r
+ uchReadData = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR);\r
+ GH3X2X_INFO_LOG("slot_time0 reg = %d\r\n", (int)uchReadData);\r
+ if (uchWriteData == uchReadData)\r
+ {\r
+ uchWriteData = ~uchReadData;\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_TMR0_REG_ADDR, uchWriteData);\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("[%s]read fail or write fail!!! \r\n", __FUNCTION__);\r
+ while(1);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("[%s]ready code reg is error !!! 0x%x\r\n", __FUNCTION__,GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_CHIP_READY_CODE_REG_ADDR));\r
+ while(1);\r
+ }\r
+\r
+ GH3X2X_INFO_LOG("[%s]Comunication confirm ok. \r\n", __FUNCTION__);\r
+ \r
+ \r
+ \r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*********************************************** init function*******************************************/\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_Init(void)\r
+ *\r
+ * @brief init GH3X2X_AFE chip\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_Init(void)\r
+{\r
+ /* Step 1: init communicate interface. */\r
+ #if(GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_SPI)\r
+ hal_gh3x2x_afe_spi_init();\r
+ #else\r
+ hal_gh3x2x_afe_i2c_init();\r
+ #endif\r
+\r
+ /* Step 2: init interupt pin */\r
+ #if(GH3X2X_AFE_PRO_TYPE == GH3X2X_AFE_PRO_BY_INT)\r
+ hal_gh3x2x_afe_int_init();\r
+ #endif\r
+ \r
+\r
+ /* Step 3: Reset GH3X2X_AFE chip */\r
+ #if(GH3X2X_AFE_RESET_TYPE == GH3X2X_AFE_RESET_HARDWARE)\r
+ hal_gh3x2x_afe_reset_pin_init();\r
+ #endif\r
+ GH3X2X_AFE_Reset();\r
+\r
+ /* Step 4: Check conmunication and chip id is ok or not */\r
+ GH3X2X_AFE_CommunicateConfirm();\r
+ GH3X2X_AFE_CheckChipId();\r
+ GH3X2X_AFE_CheckEfuseCrc();\r
+\r
+\r
+ /* Step 5: Init GH3X2X_AFE chip */\r
+ GH3X2X_AFE_SendRegPackage(GH3X2X_AFE_reg_list, GH3X2X_AFE_reg_list_len);\r
+\r
+ /* Step 6: agc module reset and set parm*/\r
+ GH3X2X_LedAgcReset();\r
+ GH3X2X_DemoLedAgcPramConfig();\r
+ //GH3X2X_LedAgcPramWrite();\r
+ \r
+ /* Step 7: enter low power mode */\r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+\r
+}\r
+\r
+/*********************************************** sample control handle function*******************************************/\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_StartSampling(GU8 SlotCfgEnable)\r
+ *\r
+ * @brief start sample\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] SlotCfgEnable slot enable bit bit0 control slot0, bit1 control slot1, bit2 control slot2...\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_StartSampling(GU8 SlotCfgEnable)\r
+{\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+\r
+ //agc init\r
+ GH3X2X_LedAgcInit(g_pstGh3x2xAgcInfo);\r
+ \r
+ //write slot enable\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_EN_ADDR, (GU16)SlotCfgEnable);\r
+ //start sample\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,1);\r
+ \r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_StopSampling(void)\r
+ *\r
+ * @brief stop sample\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_StopSampling(void)\r
+{\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+\r
+ //stop sample\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_AFE_REG_START_ADDR,GH3X2X_AFE_REG_START_LSB,GH3X2X_AFE_REG_START_MSB,0);\r
+\r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_SwitchSlot(GU8 SlotCfgEnable)\r
+ *\r
+ * @brief switch sample slot.\r
+ *\r
+ * @attention this function can only be used during sampling, after call GH3X2X_AFE_StartSampling\r
+ *\r
+ * @param[in] SlotCfgEnable slot enable bit bit0 control slot0, bit1 control slot1, bit2 control slot2...\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_SwitchSlot(GU8 SlotCfgEnable)\r
+{\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+ \r
+ //write slot enable\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_SLOT_EN_ADDR, (GU16)SlotCfgEnable);\r
+ \r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+}\r
+\r
+/********************************* interrupt handle:fifo read and analysis ***************************/\r
+#define GH3X2X_AFE_READ_FIFO_BUF_LEN (800)\r
+GU32 GH3X2X_AFE_ReadFifoBuffer[(GU16)GH3X2X_AFE_READ_FIFO_BUF_LEN];\r
+\r
+/*\r
+ FIFO rawdata decode\r
+*/\r
+typedef struct\r
+{\r
+ GU32 uiAdcCode; //sampling rawdata of ADC\r
+ GU8 ubSlotNo; //slot number\r
+ GU8 ubAdcNo; //adc number\r
+ GU8 ubFlagLedAdjIsAgc_EcgRecover; //adj flag of ppg data or fast recover flag of ecg data\r
+ GU8 ubFlagLedAdjAgcUp; //adj up flag of ppg data\r
+}StFifoDataInformation;\r
+\r
+/**\r
+ * @fn GU32 EndienRev32(GU32 luiTempData)\r
+ *\r
+ * @brief reverse data endien\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] luiTempData input data\r
+ * @param[out] None\r
+ *\r
+ * @return output data\r
+ */\r
+static GU32 EndienRev32(GU32 luiTempData)\r
+{\r
+ GU8 *lpubIn;\r
+ GU8 *lpubOut;\r
+ \r
+ GU32 luiOutData;\r
+ \r
+ lpubIn = (GU8 *)(&luiTempData);\r
+ lpubOut = (GU8 *)(&luiOutData);\r
+ \r
+ for(GU8 i = 0; i < 4; i ++)\r
+ {\r
+ lpubOut[i] = lpubIn[3 - i];\r
+ }\r
+ \r
+ return luiOutData;\r
+}\r
+\r
+void GH3X2X_UpdateAgcInfo(void)\r
+{\r
+ GH3X2X_Memcpy(g_pstGh3x2xAgcInfo->uchTiaGainRecord, g_pstGh3x2xAgcInfo->uchTiaGainAfterSoftAgc, sizeof(g_pstGh3x2xAgcInfo->uchTiaGainRecord));\r
+ GH3X2X_Memcpy(g_pstGh3x2xAgcInfo->uchDrvCurrentRecord, g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc, sizeof(g_pstGh3x2xAgcInfo->uchDrvCurrentRecord));\r
+ \r
+ \r
+}\r
+\r
+void GH3X2X_RecordAgcInfo(void)\r
+{\r
+ GU16 usDrv0CurRegData = 0;\r
+ GU16 usDrv0CurRegAddr = 0; \r
+ GU16 usDrv1CurRegData = 0;\r
+ GU16 usDrv1CurRegAddr = 0;\r
+ GU16 uchTIAData = 0;\r
+\r
+ // record TIA\r
+ for (GU8 uchSlotIndex = 0; uchSlotIndex < 8; uchSlotIndex++)\r
+ {\r
+ uchTIAData = GH3X2X_AFE_READ_REG(0x0112 + (uchSlotIndex * 0x001C));\r
+ \r
+ for (GU8 nAdcCnt = 0; nAdcCnt < 4; nAdcCnt++)\r
+ {\r
+ uchTIAData = (GU8)(((uchTIAData) >> (4 * nAdcCnt)) & 0x000F);\r
+ g_pstGh3x2xAgcInfo->uchTiaGainAfterSoftAgc[uchSlotIndex*4 + nAdcCnt] = uchTIAData;\r
+ } \r
+ }\r
+ \r
+ //Record Drv \r
+ usDrv0CurRegAddr = 0x011E;\r
+ usDrv1CurRegAddr = 0x0120;\r
+ for (GU8 uchSlotIndexCnt = 0; uchSlotIndexCnt < 8; uchSlotIndexCnt++)\r
+ {\r
+ usDrv0CurRegData = (GH3X2X_AFE_READ_REG(usDrv0CurRegAddr + (uchSlotIndexCnt * 0x001C)) & 0xFF);\r
+ usDrv1CurRegData = (GH3X2X_AFE_READ_REG(usDrv1CurRegAddr + (uchSlotIndexCnt * 0x001C)) & 0xFF);\r
+ g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc[uchSlotIndexCnt] = (GU16)(usDrv0CurRegData << 0x0);\r
+ g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc[uchSlotIndexCnt] |= (GU16)(usDrv1CurRegData << 0x0);\r
+ }\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_FifoDataAnalysis(GU16 luwFifoDataCnt)\r
+ *\r
+ * @brief analysis fifo data\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] luwFifoDataCnt the number of rawdata \r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_FifoDataAnalysis(GU16 luwFifoDataCnt)\r
+{\r
+ StFifoDataInformation stTempFifoInfo = {0};\r
+ GU16 luwFifoCnt = 0;\r
+ \r
+ GU32 luiTempFifoData = 0;\r
+\r
+ GH3X2X_INFO_LOG("Received rawdata sample num = %d \r\n", (int)luwFifoDataCnt);\r
+ \r
+ for(luwFifoCnt = 0; luwFifoCnt < luwFifoDataCnt; luwFifoCnt++)\r
+ {\r
+ luiTempFifoData = EndienRev32(GH3X2X_AFE_ReadFifoBuffer[luwFifoCnt]); //big endien -> little endien\r
+ \r
+ stTempFifoInfo.uiAdcCode = ((luiTempFifoData >> 0) & 0x00FFFFFF);\r
+ stTempFifoInfo.ubSlotNo = ((luiTempFifoData >> 29) & 0x00000007);\r
+ stTempFifoInfo.ubAdcNo = ((luiTempFifoData >> 27) & 0x00000003);\r
+ stTempFifoInfo.ubFlagLedAdjIsAgc_EcgRecover = ((luiTempFifoData >> 26) & 0x00000001);\r
+ stTempFifoInfo.ubFlagLedAdjAgcUp = ((luiTempFifoData >> 25) & 0x00000001);\r
+ #if GH3X2X_ADT_FUNC_ENABLE\r
+ if(stTempFifoInfo.ubSlotNo == GH3X2X_ADT_SLOT_NUM && stTempFifoInfo.ubAdcNo == GH3X2X_ADT_ADC_NUM)\r
+ {\r
+ EMWearStatus emWearStatus;\r
+ GH3x2xAdtAlgoExe(&stTempFifoInfo.uiAdcCode,&emWearStatus);\r
+ }\r
+ #endif\r
+ GH3X2X_INFO_LOG("Received rawdata:slot:%d,adc:%d,data:%d\r\n", stTempFifoInfo.ubSlotNo, stTempFifoInfo.ubAdcNo,stTempFifoInfo.uiAdcCode);\r
+ //GH3X2X_INFO_LOG("drv = %d, g0 = %d,g1 = %d,g2 = %d,g0 = %d\r\n",(int)g_pstGh3x2xAgcInfo->uchDrvCurrentRecord[0],(int)g_pstGh3x2xAgcInfo->uchTiaGainRecord[0],(int)g_pstGh3x2xAgcInfo->uchTiaGainRecord[1],g_pstGh3x2xAgcInfo->uchTiaGainRecord[2],g_pstGh3x2xAgcInfo->uchTiaGainRecord[3]);\r
+ \r
+\r
+ \r
+ /******************************** add your fifo date process code******************************/\r
+ //you can combine frame rawdata according to stTempFifoInfo\r
+ //and then excute algorithm calculate\r
+ \r
+ \r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_ChipPro(void)\r
+ *\r
+ * @brief interrupt handle function\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_ChipPro(void)\r
+{\r
+ GU16 luwGH3X2X_AFEFifoLen = 0;\r
+ GU16 luwGotEvent = 0;\r
+\r
+\r
+#if (GH3X2X_AFE_PRO_TYPE == GH3X2X_AFE_PRO_BY_INT)\r
+ if(0 == g_uchGh3x2xAfeIntCallBackIsCalled)\r
+ {\r
+ GH3X2X_INFO_LOG("InterruptProcess:invalid call, do not process.\r\n");\r
+ return;\r
+ }\r
+ g_uchGh3x2xAfeIntCallBackIsCalled = 0; \r
+ \r
+#endif\r
+\r
+ if (GH3X2X_AFE_GetNeedWakeUpGh3x2xFlag())\r
+ {\r
+ GH3X2X_AFE_ExitLowPowerMode();\r
+ }\r
+\r
+\r
+ luwGH3X2X_AFEFifoLen = 0;\r
+\r
+ //read event\r
+ luwGotEvent = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_INT_EVENT_ADDR); \r
+ GH3X2X_INFO_LOG("Received irq = %d \r\n", (int)luwGotEvent);\r
+ //clear event\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_AFE_REG_INT_EVENT_ADDR,luwGotEvent); //clear event\r
+\r
+ //read fifo use\r
+ luwGH3X2X_AFEFifoLen = GH3X2X_AFE_READ_REG(GH3X2X_AFE_REG_FIFO_USE_ADDR);\r
+ if(luwGH3X2X_AFEFifoLen > GH3X2X_AFE_READ_FIFO_BUF_LEN)\r
+ {\r
+ luwGH3X2X_AFEFifoLen = GH3X2X_AFE_READ_FIFO_BUF_LEN;\r
+ }\r
+\r
+ // read fifo data\r
+ if(0 != luwGH3X2X_AFEFifoLen)\r
+ {\r
+ GH3X2X_AFE_READ_FIFO((GU8 *)GH3X2X_AFE_ReadFifoBuffer,luwGH3X2X_AFEFifoLen * 4);\r
+ } \r
+ \r
+ \r
+ //ECG_LEAD OFF DET & resample\r
+ #if GH3X2X_ECG_FUNC_ENABLE\r
+\r
+ GU16 luwGH3X2X_AFEFifoByteLen = luwGH3X2X_AFEFifoLen * 4;\r
+ luwGotEvent &= (~GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_OFF));\r
+ \r
+ GU8 lubRet = GH3X2X_LeadOffDetect((GU8 *)GH3X2X_AFE_ReadFifoBuffer, &luwGH3X2X_AFEFifoByteLen, 0);\r
+ if(lubRet != 0)\r
+ {\r
+ luwGotEvent |= (GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_OFF));\r
+ }\r
+ \r
+ GH3X2X_INFO_LOG("before Rs luwGH3X2X_AFEFifoLen = %d\r\n",luwGH3X2X_AFEFifoLen);\r
+ GH3X2X_AFE_EcgRsHandle((GU8 *)GH3X2X_AFE_ReadFifoBuffer, &luwGH3X2X_AFEFifoByteLen,0,GH3X2X_ECG_DOWN_FS);\r
+ luwGH3X2X_AFEFifoLen = luwGH3X2X_AFEFifoByteLen/4;\r
+ GH3X2X_INFO_LOG("after Rs luwGH3X2X_AFEFifoLen = %d\r\n",luwGH3X2X_AFEFifoLen);\r
+ #endif\r
+ \r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_WEAR_ON)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received wear on event\r\n");\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_WEAR_OFF)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received wear off event\r\n");\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_ON)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received lead on event\r\n");\r
+ GH3X2X_AFE_Leadon_hook();\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LEAD_OFF)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received lead off event\r\n");\r
+ GH3X2X_AFE_Leadoff_hook();\r
+\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LED_TUNE_FAIL)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received tune fail event\r\n");\r
+ }\r
+\r
+ if(0 != (luwGotEvent & GH3X2X_AFE_EVENT_BIT(GH3X2X_AFE_EVENT_LED_TUNE_DONE)))\r
+ {\r
+ GH3X2X_INFO_LOG("Received tune done event\r\n");\r
+ }\r
+\r
+\r
+ //you can add some code to adjust ppg sample parameter, such as led drv current GU16 usTempDrvCurrent;\r
+ \r
+ //GH3x2xSetPpgCtrlReg(GH3X2X_AFE_PPG_CTRL_REG_AGC_EN,1,0);\r
+ //GH3x2xSetPpgCtrlReg(GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV0,1,60);\r
+ //GH3X2X_INFO_LOG("change slot0 drv0 current.\r\n");\r
+ //GH3X2X_INFO_LOG("Get slot0 drv0 current = %d.\r\n",(int)GH3x2xGetPpgCtrlReg(GH3X2X_AFE_PPG_CTRL_REG_LED_CURRENT_DRV0,0));\r
+\r
+ GH3X2X_LedAgcProcess((GU8 *)GH3X2X_AFE_ReadFifoBuffer, luwGH3X2X_AFEFifoLen * 4, g_pstGh3x2xAgcInfo);\r
+ \r
+ GH3X2X_AFE_EnterLowPowerMode();\r
+ \r
+\r
+ if(0 != luwGH3X2X_AFEFifoLen)\r
+ {\r
+ GH3X2X_AFE_FifoDataAnalysis(luwGH3X2X_AFEFifoLen);\r
+ } \r
+}\r
+\r
+const GU16 g_usGH3x2xTiaGainR[] = \r
+{\r
+ 10,\r
+ 25,\r
+ 50,\r
+ 75,\r
+ 100,\r
+ 250,\r
+ 500,\r
+ 750,\r
+ 1000,\r
+ 1250,\r
+ 1500,\r
+ 1750,\r
+ 2000,\r
+};\r
+\r
+const GU16 g_usGH3x2xSlotRegBase[8] = \r
+{\r
+ 0x0100,\r
+ 0x011C,\r
+ 0x0138,\r
+ 0x0154,\r
+ 0x0170,\r
+ 0x018C,\r
+ 0x01A8,\r
+ 0x01C4,\r
+};\r
+\r
+\r
+const STGh3x2xAgcReg g_pstGH3x2xAgcReg[] = \r
+{\r
+ {0x10, 9, 8}, //0: agc en\r
+ {0x22, 7, 0}, //1: led current up limit\r
+ {0x22, 15, 8}, //2: led current down limit\r
+ {0x1E, 7, 0}, //3: led current drv0\r
+ {0x20, 7, 0}, //4: led current drv1\r
+ {0x12, 3, 0}, //5: rx0 tia gain\r
+ {0x12, 7, 4}, //6: rx1 tia gain\r
+ {0x12, 11, 8}, //7: rx2 tia gain\r
+ {0x12, 15, 12}, //8: rx3 tia gain\r
+ {0x10, 7,6}, //9: agc src\r
+ {0x1A, 1,0}, //10: rx0 bg cancel\r
+ {0x1A, 3,2}, //11: rx1 bg cancel \r
+ {0x1A, 5,4}, //12: rx2 bg cancel\r
+ {0x1A, 7,6}, //13: rx2 bg cancel\r
+ {0x0A, 15,8}, //14: sr mulipliper\r
+ {0x0A, 5,1}, //15: ecg en& rx0~rx1 en\r
+};\r
+\r
+void GH3x2x_AFESetAgcReg(GU8 uchAgcReg, GU8 uchSlot, GU16 usValue)\r
+{\r
+ GH3X2X_AFE_WriteRegBitField(g_usGH3x2xSlotRegBase[uchSlot] + g_pstGH3x2xAgcReg[uchAgcReg].uchAddrOffset, g_pstGH3x2xAgcReg[uchAgcReg].uchLsb, g_pstGH3x2xAgcReg[uchAgcReg].uchMsb, usValue);\r
+}\r
+\r
+GU16 GH3x2x_AFEGetAgcReg(GU8 uchAgcReg, GU8 uchSlot)\r
+{\r
+ return GH3X2X_AFE_ReadRegBitField(g_usGH3x2xSlotRegBase[uchSlot] + g_pstGH3x2xAgcReg[uchAgcReg].uchAddrOffset, g_pstGH3x2xAgcReg[uchAgcReg].uchLsb, g_pstGH3x2xAgcReg[uchAgcReg].uchMsb);\r
+}\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_GetEfuseCode(GS8* pchLedDrvEcode,GS8* pchTiaEcode,GS8* pchEcgEcode)\r
+ *\r
+ * @brief: Get Efuse Code\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] \r
+ * @param[out] pchLedDrvEcode\r
+ * pchTiaEcode\r
+ * pchEcgEcode\r
+ * @return : none\r
+ */\r
+void GH3X2X_AFE_GetEfuseCode(GS8* pchLedDrvEcode,GS8* pchTiaEcode,GS8* pchEcgEcode)\r
+{\r
+ GU16 usRegVal;\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,0x0020);\r
+ GH3X2X_AFE_WRITE_REG(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,0x0030);\r
+\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_1_REG_ADDR);\r
+ *pchLedDrvEcode = (GS8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ *pchTiaEcode = (GS8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ *pchEcgEcode = (GS8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_2_REG_ADDR));\r
+}\r
+\r
+\r
+/**\r
+ * @fn GU16 GH3X2X_AFE_SetLedDrvCurrent(GU8 uchCurrent_mA,GU8 uchDrvNum, GS8 chECODE)\r
+ *\r
+ * @brief: led drv calibration\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GU8 uchCurrent_mA:led drv current, unit: mA\r
+ GU8 uchDrvNum :led Drv num,0 or 1\r
+ GS8 chECODE :Led Drv Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : Drv code\r
+ */\r
+GU16 GH3X2X_AFE_SetLedDrvCurrent(GU8 uchCurrent_mA, GU8 uchDrvNum, GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ GF32 fY;\r
+ GU8 uchN;\r
+ GU16 usDrvCode;\r
+ GU16 usDrvScale;\r
+ \r
+ if(uchDrvNum == 0)\r
+ {\r
+ fY = 0.1;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB);\r
+ }\r
+ else\r
+ {\r
+ fY = 0.01;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB);\r
+ \r
+ }\r
+ uchN = 1 << (3 - usDrvScale); \r
+ \r
+ fEr = (GF32)((GF32)chECODE/256) + 1.0f;\r
+ usDrvCode = (GU16)(0.5f+((GF32)fEr*255*(GF32)uchN)/(0.225f/((GF32)uchCurrent_mA/1000) - fY));\r
+ \r
+ return usDrvCode;\r
+}\r
+\r
+\r
+/**\r
+ * @fn GF32 GH3X2X_AFE_GetLedDrvCurrent(GU16 usDrvCode, GU8 uchDrvNum, GS8 chECODE)\r
+ *\r
+ * @brief: get led drv calibration current\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GU16 usDrvCode :led drv code\r
+ GU8 uchDrvNum :led Drv num,0 or 1\r
+ GS8 chECODE :Led Drv Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : calibration current\r
+ */\r
+\r
+GF32 GH3X2X_AFE_GetLedDrvCurrent(GU16 usDrvCode, GU8 uchDrvNum, GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ GF32 fY;\r
+ GU8 uchN;\r
+ GF32 fDrvCurrent;\r
+ GU16 usDrvScale;\r
+ \r
+ if(uchDrvNum == 0)\r
+ {\r
+ fY = 0.1;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB);\r
+ }\r
+ else\r
+ {\r
+ fY = 0.01;\r
+ usDrvScale = GH3X2X_AFE_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB);\r
+ }\r
+ uchN = 1 << (3 - usDrvScale); \r
+ fEr = (GF32)((GF32)chECODE/256) + 1;\r
+ fDrvCurrent = 0.225f/(fEr*255*(GF32)uchN/(GF32)usDrvCode + fY);\r
+ return fDrvCurrent*1000;\r
+\r
+}\r
+\r
+/**\r
+ * @fn GF32 GH3X2X_AFE_GetTiaCalCode(GS8 chECODE)\r
+ \r
+ *\r
+ * @brief: Get Tia Calibration Code\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GS8 chECODE :Tia Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : calibration Code\r
+ */\r
+GF32 GH3X2X_AFE_GetTiaCalCode(GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ fEr = (GF32)((GF32)chECODE/512) + 1;\r
+ return fEr;\r
+}\r
+\r
+/**\r
+ * @fn GF32 GH3X2X_AFE_GetEcgCalCode(GS8 chECODE)\r
+ \r
+ *\r
+ * @brief: Get ECG Calibration Code\r
+ *\r
+ * @attention \r
+ *\r
+ * @param[in] GS8 chECODE :ECG Ecode from efuse\r
+ * @param[out] None\r
+ *\r
+ * @return : calibration Code\r
+ */\r
+GF32 GH3X2X_AFE_GetEcgCalCode(GS8 chECODE)\r
+{\r
+ GF32 fEr;\r
+ fEr = (GF32)((GF32)chECODE/1024) + 1;\r
+ return fEr;\r
+}\r
+\r
+\r
+/**\r
+ * @fn GCHAR *GH3X2X_GetAfeLibVersion(void)\r
+ *\r
+ * @brief Get afe driver version\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return library version string\r
+ */\r
+GCHAR *GH3X2X_GetAfeLibVersion(void)\r
+{\r
+ return (GCHAR *)GH3X2X_VERSION_STRING;\r
+}\r
+\r
+\r
+GU8 GH3X2X_AFE_GetChipId(void)\r
+{\r
+ return (GU8)GH3X2X_AFE_ReadRegBitField(GH3X2X_WHO_AM_I_REG_ADDR,GH3X2X_WHO_AM_I_LSB,GH3X2X_WHO_AM_I_MSB);\r
+}\r
+\r
+GS8 GH3X2X_AFE_CheckChipId(void)\r
+{\r
+ GS8 chRet = GH3X2X_AFE_RET_OK;\r
+ GS8 chipd_id = GH3X2X_AFE_GetChipId();\r
+ if(GH3X2X_CHIP_ID != chipd_id)\r
+ {\r
+ GH3X2X_INFO_LOG("wrong chip id!! 0x%x\r\n",chipd_id);\r
+ chRet = GH3X2X_AFE_RET_GENERIC_ERROR;\r
+ }\r
+ else\r
+ {\r
+ GH3X2X_INFO_LOG("check chip id success!! 0x%x\r\n",chipd_id);\r
+ }\r
+ return chRet;\r
+}\r
+\r
+/**\r
+ * @fn void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+ *\r
+ * @brief memcpy() Re-implementation\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] pSrc pointer to source buffer\r
+ * @param[in] unByteSize source buffer byte size\r
+ * @param[out] pDest pointer to destination buffer\r
+ *\r
+ * @return pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+{\r
+ GU8 *puchSrc = (GU8 *)pSrc;\r
+ GU8 *puchDest = (GU8 *)pDest;\r
+ GU32 unAlign = ((GU32)puchDest | (GU32)puchSrc) << 30;\r
+\r
+ if ((pDest == GH3X2X_PTR_NULL) || (pSrc == GH3X2X_PTR_NULL) || (0 == unByteSize))\r
+ {\r
+ return GH3X2X_PTR_NULL;\r
+ }\r
+ if (unAlign == 0) // if align 4\r
+ {\r
+ while (unByteSize >= 4)\r
+ {\r
+ *(GU32 *)puchDest = *(GU32 *)puchSrc;\r
+ puchSrc += 4;\r
+ puchDest += 4;\r
+ unByteSize -= 4;\r
+ }\r
+ }\r
+ while (unByteSize) // bytes\r
+ {\r
+ *(GU8 *)puchDest = *(GU8 *)puchSrc;\r
+ puchSrc++;\r
+ puchDest++;\r
+ unByteSize--;\r
+ }\r
+ return pDest;\r
+}\r
+\r
+/**\r
+ * @fn void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+ *\r
+ * @brief memset() Re-implementation\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] chVal char val for set\r
+ * @param[in] unByteSize source buffer len\r
+ * @param[out] pDest pointer to destination buffer\r
+ *\r
+ * @return pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+{\r
+ GU8 *puchDest = (GU8 *)pDest;\r
+ GU32 unAlign = ((GU32)puchDest) << 30;\r
+ GU32 unWordVal = GH3X2X_AFE_MAKEUP_DWORD(chVal, chVal, chVal, chVal);\r
+\r
+ if (pDest == GH3X2X_PTR_NULL)\r
+ {\r
+ return GH3X2X_PTR_NULL;\r
+ }\r
+ if (unAlign == 0) // if align 4\r
+ {\r
+ while (unByteSize >= 4)\r
+ {\r
+ *(GU32 *)puchDest = unWordVal;\r
+ puchDest += 4;\r
+ unByteSize -= 4;\r
+ }\r
+ }\r
+ while (unByteSize) // bytes\r
+ {\r
+ *(GU8 *)puchDest = (GU8)chVal;\r
+ puchDest++;\r
+ unByteSize--;\r
+ }\r
+ return pDest;\r
+}\r
+\r
+GU8 _crc8(GU8 *ptr,GS32 len)\r
+{\r
+ GS32 i;\r
+ GU8 crc = 0x00;\r
+ while(len--)\r
+ {\r
+ crc ^= *ptr++;\r
+ for(i=8;i>0;--i)\r
+ {\r
+ if(crc&0x80)\r
+ {\r
+ crc = (crc<<1)^0x31;\r
+ }\r
+ else\r
+ {\r
+ crc = (crc<<1);\r
+ }\r
+ crc = crc & 0xff;\r
+ }\r
+ }\r
+ return (GU8)(crc);\r
+}\r
+\r
+void GH3X2X_AFE_LoadEfuse(GU8* puchEfuseBuffer,GU16 EfuseByteLen)\r
+{\r
+ if(EfuseByteLen < 24)\r
+ {\r
+ GH3X2X_INFO_LOG("EfuseByteLen is too short!!\r\n");\r
+ return;\r
+ }\r
+ \r
+ GU16 usRegVal;\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_MODE_LSB,GH3X2X_EFUSE_MODE_MSB,0);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CHOOSE_LSB,GH3X2X_EFUSE_CHOOSE_MSB,0);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CLK_EN_LSB,GH3X2X_EFUSE_CLK_EN_MSB,1);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_START_LSB,GH3X2X_EFUSE_START_MSB,1);\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ for(GU8 i = 0; i < 4; i++)\r
+ {\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR + 2 * i);\r
+ puchEfuseBuffer[2*i] = (GU8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ puchEfuseBuffer[2*i + 1] = (GU8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ }\r
+\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CHOOSE_LSB,GH3X2X_EFUSE_CHOOSE_MSB,1);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_START_LSB,GH3X2X_EFUSE_START_MSB,1);\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ for(GU8 i = 0; i < 4; i++)\r
+ {\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR + 2 * i);\r
+ puchEfuseBuffer[8 + 2*i] = (GU8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ puchEfuseBuffer[8 + 2*i + 1] = (GU8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ }\r
+\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_CHOOSE_LSB,GH3X2X_EFUSE_CHOOSE_MSB,2);\r
+ GH3X2X_AFE_WriteRegBitField(GH3X2X_EFUSE_CTRL_CMD_REG_ADDR,GH3X2X_EFUSE_START_LSB,GH3X2X_EFUSE_START_MSB,1);\r
+ while(0 == GH3X2X_AFE_ReadRegBitField(GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR,0,0));\r
+ for(GU8 i = 0; i < 4; i++)\r
+ {\r
+ usRegVal = GH3X2X_AFE_READ_REG(GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR + 2 * i);\r
+ puchEfuseBuffer[16 + 2*i] = (GU8)GH3X2X_AFE_GET_LOW_BYTE_FROM_WORD(usRegVal);\r
+ puchEfuseBuffer[16 + 2*i + 1] = (GU8)GH3X2X_AFE_GET_HIGH_BYTE_FROM_WORD(usRegVal);\r
+ }\r
+\r
+ \r
+}\r
+\r
+GS8 GH3X2X_AFE_CheckEfuseCrc(void)\r
+{\r
+ GS8 chRet = GH3X2X_AFE_RET_OK;\r
+ GU8 uchEfuseBuffArr[24];\r
+ GH3X2X_AFE_LoadEfuse(uchEfuseBuffArr,24);\r
+ GU8 uchCrcArr[3];\r
+ uchCrcArr[0] = _crc8(uchEfuseBuffArr,7);\r
+ uchCrcArr[1] = _crc8((uchEfuseBuffArr + 8),3);\r
+ uchCrcArr[2] = _crc8((uchEfuseBuffArr + 12),10);\r
+ if(uchCrcArr[0] != uchEfuseBuffArr[7] || uchCrcArr[1] != uchEfuseBuffArr[11] ||uchCrcArr[2] != uchEfuseBuffArr[22])\r
+ {\r
+ GH3X2X_INFO_LOG("Efuse crc error!!\r\n");\r
+ chRet = GH3X2X_AFE_RET_GENERIC_ERROR;\r
+ }\r
+ return chRet;\r
+}\r
+\r
+void gh3x2x_control(char* mode, uint8_t enable)\r
+{\r
+\r
+ uint32_t md = 1;\r
+ if (strcmp(mode, "hrs") == 0) {\r
+ md = 0;\r
+ } else if (strcmp(mode, "hrv") == 0) {\r
+ md = 1;\r
+ } else if (strcmp(mode, "spo2") == 0) {\r
+ md = 2;\r
+ } else if (strcmp(mode, "leaklight") == 0) {\r
+ md = 4;\r
+ } else if (strcmp(mode, "graycard") == 0) {\r
+ md = 8;\r
+ } else if (strcmp(mode, "ledoff") == 0) {\r
+ md = 16;\r
+ } else if (strcmp(mode, "wear") == 0) {\r
+ md = 32;\r
+ } else if (strcmp(mode, "single") == 0) {\r
+ md = 64;\r
+ }else if (strcmp(mode, "factory") == 0) {\r
+ md = 128;\r
+ }else if (strcmp(mode, "fpc") == 0) {\r
+ // md = WORK_MODE_UNDEFINED;\r
+ }else if (strcmp(mode, "int") == 0) {\r
+ } \r
+\r
+ if (enable == 1)\r
+ {\r
+ // ppg_service_running_stat = true;\r
+ // uapi_pm_control(PM_APP_WAKE_NEEDED);\r
+ // GH3X2X_AFE_StartFunction(mode);\r
+ GH3X2X_AFE_Init();\r
+ GH3X2X_AFE_StartSampling(1);\r
+\r
+ } else {\r
+ \r
+ // uapi_pm_control(PM_APP_WAKE_NONEED);\r
+ GH3X2X_AFE_StopSampling();\r
+ } \r
+}
\ No newline at end of file
--- /dev/null
+#include "gh3x2x_afe_ecg.h"\r
+#include "gh3x2x_afe_demo.h"\r
+\r
+#define RESAMPLE_800HZ_TO_500HZ 0\r
+#define RESAMPLE_800HZ_TO_250HZ 0\r
+#define RESAMPLE_320HZ_TO_250HZ 1 \r
+#define RESAMPLE_256HZ_TO_250HZ 0 \r
+\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+#define RESAMPLE_400HZ_TO_250HZ 1 \r
+#else\r
+#define RESAMPLE_400HZ_TO_250HZ 0 \r
+#endif\r
+\r
+#define GH3X2X_PPG_START_SLOT 1\r
+#define GH3X2X_ECG_START_SLOT 0\r
+\r
+#define GH3X2X_AFE_GET_ECG_CHANNEL_MAP(slotNum) (((slotNum << 5) | (3 <<3)) &0xF8)\r
+#define GH3X2X_AFE_GET_PPG_CHANNEL_MAP(slotNum) (((slotNum << 5) | (0 <<3)) &0xF8)\r
+\r
+STGh3x2xSoftLeadOffDetInfo g_pstGh3x2xSoftLeadOffDetInfoEntity[1];\r
+STGh3x2xRsInfo g_pstGh3x2xEcgRsInfoEntity[1];\r
+const GU8 g_uchGh3x2xEcgChnlNumLimit = 1;\r
+STGh3x2xSoftLeadOffDetInfo * const g_pstGh3x2xSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfoEntity;\r
+STGh3x2xRsInfo * const g_pstGh3x2xEcgRsInfo = g_pstGh3x2xEcgRsInfoEntity;\r
+\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+#define GH3X2X_PPG_DOWNSAMP_CHNL_NUM 1\r
+const GU32 g_uchPPGDownSampleChnlNumLimit = GH3X2X_PPG_DOWNSAMP_CHNL_NUM;\r
+STGh3x2xRsInfo g_pstGh3x2xPPGRsInfoEntity[GH3X2X_PPG_DOWNSAMP_CHNL_NUM];\r
+STGh3x2xRsInfo * const g_pstGh3x2xPPGRsInfo = g_pstGh3x2xPPGRsInfoEntity;\r
+#endif\r
+\r
+//Ecg sample rate from hardware\r
+static GU16 g_usEcgInputFs = GH3X2X_ECG_FS; // ecg sample rate 800/320/256\r
+static GU16 g_usEcgOutputFs = GH3X2X_ECG_DOWN_FS; // ecg down sample rate 500/250\r
+\r
+/// down sample lead module(ECG PPG)\r
+static GU8 g_uchDownSampleModule = DOWNSAMPLE_ECG;\r
+\r
+#define ADCREF 1800 \r
+#define ADC_OFFSET (1<<23)\r
+#define PI 3.14159265\r
+#define ABS(x) ( (x)>0?(x):(-(x)) ) \r
+#define AMP_NUM 5 \r
+#define IQ_NUM 48 \r
+\r
+const int winCoef[IQ_NUM / 2] = { 0, 9580474, 38150933, 85201535, 149892663, 231069901, 327284639, 436819923, 557721094, 687830666, 824826833, 966264894, 1109620882, 1252336609, 1391865307, 1525717084, 1651503351, 1766979451, 1870084709, 1958979209, 2032076627, 2088072537, 2125967693, 2145085852};\r
+#define winAmpCoef 4082 \r
+//unsigned char gscFlagFrPrev = 0; \r
+GU32 g_nLeadOffDetIqAmpThr = 1500;//unit: uv\r
+long long g_lLeadOffDetIqAmp;\r
+long long g_lLeadOffDetIqAmpThrRaw;\r
+long long g_lLeadOffDetIqAmpFrThrRaw;\r
+\r
+GU32 g_nLeadOffDetIqAmpDiffThr = 1000;//unit: uv\r
+long long g_lLeadOffDetIqAmpDiff;\r
+long long g_lLeadOffDetIqAmpDiffThrRaw;\r
+long long g_lLeadOffDetIqAmpDiffFrThrRaw;\r
+\r
+int COND_VAL_VALID_TIME = 1; \r
+GU32 g_nLeadOffDetValThr = 80;//unit: mv\r
+int g_LeadOffDetValThrRaw;\r
+\r
+#define SHIFTBITS 30\r
+\r
+#if RESAMPLE_800HZ_TO_500HZ\r
+ const int rsFirCoef_800_500hz[] = { 58200, 102435, 156130, 215460, 274735, 326585, 362380, 372790, 348645, 281870, 166550, 0, -216285, -475850, -766815, -1071825, -1368460, -1630170, -1827760, -1931325, -1912605,\r
+ -1747635, -1419445, -920670, -255820, 557070, 1485515, 2482735, 3488860, 4433375, 5238695, 5824850, 6114965, 6041350, 5551740, 4615280, 3227790, 1415785, -761100, -3209770, -5805610, -8396875, -10811545, -12866385,\r
+ -14377925, -15174745, -15110485, -14076620, -12014295, -8924190, -4873605, 0, 5489625, 11323885, 17176845, 22682405, 27452740, 31100030, 33260510, 33619540, 31936265, 28066360, 21981325, 13782945, 3711580, -7852615,\r
+ -20396185, -33286830, -45795550, -57125820, -66448630, -72941905, -75832375, -74437800, -68207360, -56757870, -39903755, -17678885, 9651270, 41588185, 77410100, 116192965, 156841955, 198132190, 238757000, 277381455, 312698655, 343486005, 368658785, 387318230, 398791740, 402663190 };\r
+#endif\r
+#if RESAMPLE_800HZ_TO_250HZ \r
+ const int rsFirCoef_800_250hz[] = { -74905, -95385, -116975, -138740, -159540, -178080, -192900, -202440, -205060, -199120, -183040, -155365, -114830, -60455, 8370, 91845, 189655, 300920, 424150, 557225, 697345, 841065, 984315, 1122440, 1250290, 1362325,\r
+ 1452720, 1515555, 1544935, 1535220, 1481220, 1378385, 1223050, 1012615, 745780, 422705, 45175, -383265, -857210, -1369370, -1910565, -2469770, -3034240, -3589685, -4120510, -4610090, -5041145, -5396125, -5657660, -5809045, -5834740, -5720895, -5455890,\r
+ -5030825, -4440010, -3681420, -2757070, -1673325, -441140, 923805, 2401100, 3965690, 5588100, 7234765, 8868540, 10449275, 11934545, 13280495, 14442770, 15377525, 16042520, 16398240, 16409055, 16044325, 15279560, 14097430, 12488725, 10453225, 8000385,\r
+ 5149865, 1931900, -1612575, -5431990, -9464450, -13638290, -17872830, -22079425, -26162660, -30021820, -33552510, -36648435, -39203325, -41112955, -42277200, -42602135, -42002095, -40401670, -37737600, -33960495, -29036370, -22947970, -15695790,\r
+ -7298825, 2204995, 12758710, 24286615, 36694830, 49872305, 63692080, 78012930, 92681285, 107533410, 122397830, 137097950, 151454790, 165289835, 178427925, 190700125, 201946505, 212018845, 220783110, 228121755, 233935695, 238146055, 240695490, 241549195 };\r
+#endif\r
+\r
+#if RESAMPLE_400HZ_TO_250HZ \r
+//const int rsFirCoef_250hz1[] = { 0,-24495,-56710,-95045,-136775,-178125,-214440,-240490,-250920,-240760,-205965,-144050,-54555,60475,196250,345190,497105,639650,759070,841160,872410,841285,739500,563245,314150,0,-365010,-760510,-1160685,-1535620,-1853070,-2080745,-2188790,-2152475,-1954770,-1588670,-1058960,-383360,407260,1269625,2149850,2986210,3712890,4264415,4580525,4611280,4321835,3696680,2742865,1491895,0,-1653335,-3368750,-5032125,-6521320,-7714135,-8497040,-8774130,-8475685,-7565610,-6047220,-3966715,-1413955,1479820,4547350,7593800,10407850,12774895,14491705,15381495,15308470,14190830,12011055,8822720,4752940,0,-5174080,-10455925,-15497715,-19937805,-23423930,-25637735,-26318950,-25287690,-22463185,-17877445,-11682610,-4150955,4332910,13287805,22159230,30349170,37251070,42288110,44952645,44844420,41705155,35447110,26173540,14189250,0,-15699840,-32051440,-48066690,-62673020,-74765800,-83265770,-87178475,-85652480,-78033065,-63908265,-43144325,-15908305,17323970,55775495,98391360,143876925,190749335,237400000,282164985,323399855,359555130,389248460,411329760,424935830,429531605};\r
+const int rsFirCoef_250hz2[] = {-20165,29190,117750,248970,420650,623445,839855,1044105,1203060,1278285,1229350,1018175,614220,0,-823490,-1832200,-2975865,-4177020,-5332555,-6318335,-6996880,-7227970,-6881615,-5852620,-4075600,-1539030,1703020,5523035,9717440,14010255,18063685,21495860,23905235,24900525,24134595,21339975,16363405,9196555,0,-10882185,-22919440,-35404830,-47478995,-58167535,-66430495,-71221570,-71553685,-66566985,-55594615,-38221750,-14333265,15853795,51776230,92531020,136902815,183411755,230379530,276010140,318480795,356037520,387089565,410296710,424643805,429497860,};\r
+#endif\r
+ \r
+#if RESAMPLE_320HZ_TO_250HZ \r
+ const int rsFirCoef_320_250hz[] = {79095,936340,341760,-2712470,-2547785,4817105,8099190,-5170865,-17933790,0,30974265,15517780,-42765395,-45670380,44706790,92106715,-24021395,-152053275,-36768905,217784250,166596045,-277901355,-451953470,320248390,1667310365,2147483647,};\r
+#endif\r
+#if RESAMPLE_256HZ_TO_250HZ \r
+ const int rsFirCoef_256_250hz[]={194000,77770,-331070,-632290,-254280,769680,1439880,622640,-1454740,-2779600,-1303600,2436730,4847325,2461115,-3753755,-7872475,-4310105,5424840,12120690,7126740,-7444180,-17902495,-11265025,9777230,25594875,17187555,-12359260,-35689230,-25526795,15096890,48893725,37213545,-17872685,-66356185,-53763065,20552645,90184745,77974330,-22995885,-124828195,-115908245,25065740,181561700,183974820,-26641130,-299102515,-347934030,27626950,749679370,1463910805,1761638120,};\r
+#endif\r
+\r
+GS32* rsFirCoef;\r
+GS32* rsFirCoef1;\r
+ \r
+STGh3x2xDownSampleCalParamInfo pstECGDownSampCalParamInfo[1];\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+STGh3x2xDownSampleCalParamInfo pstPPGDownSampCalParamInfo[1];\r
+#endif\r
+\r
+void GH3X2X_DownSampleMarcoIni(GU16 usEcgSampleRate)\r
+{\r
+ switch (g_usEcgInputFs)\r
+ {\r
+ case 800:\r
+ if( usEcgSampleRate == 500)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_800HZ_TO_500HZ;\r
+ }\r
+ else\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_800HZ_TO_250HZ;\r
+ }\r
+ break;\r
+ case 320:\r
+ if( usEcgSampleRate == 250)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_320HZ_TO_250HZ;\r
+ }\r
+ break;\r
+ case 256:\r
+ if( usEcgSampleRate == 250)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_256HZ_TO_250HZ;\r
+ }\r
+ break;\r
+ default: // do nothing\r
+ break;\r
+ }\r
+\r
+ // ppg downsample ini\r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ pstPPGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_400HZ_TO_250HZ;\r
+ #endif\r
+}\r
+\r
+void RsFirResetSingle(GU8 uchChipIndex, GU8 uchMode)\r
+{\r
+ STGh3x2xRsInfo * pstRsInfo;\r
+ GU8 uchChnNum = 0;\r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ if(DOWNSAMPLE_PPG == uchMode)\r
+ {\r
+ pstRsInfo = g_pstGh3x2xPPGRsInfo;\r
+ uchChnNum = g_uchPPGDownSampleChnlNumLimit;\r
+ }\r
+ #endif\r
+\r
+ if(DOWNSAMPLE_ECG == uchMode)\r
+ {\r
+ pstRsInfo = g_pstGh3x2xEcgRsInfo;\r
+ uchChnNum = uchChipIndex+1;\r
+ }\r
+\r
+ for( GU8 i=0; i<uchChnNum;i++)\r
+ {\r
+ pstRsInfo[i].snBufHead = -1;\r
+ pstRsInfo[i].snRsFirState = 0;\r
+ pstRsInfo[i].nRsIcounter = 0;\r
+ pstRsInfo[i].nRrsDcounter = 0;\r
+ pstRsInfo[i].uchFlagFrPrev = 1;\r
+ pstRsInfo[i].nRsLastRaw = 0;\r
+ pstRsInfo[i].fDownStep = 0;\r
+ pstRsInfo[i].uchLinearInterState = 0;\r
+ pstRsInfo[i].uchLinearDataUpdate = 0;\r
+ }\r
+}\r
+\r
+void RsFirReset(GU8 uchMode)\r
+{\r
+ RsFirResetSingle(0,uchMode);\r
+}\r
+\r
+void GH3X2X_ECGResampleConfig(GU16 usEcgSampleRate)\r
+{\r
+ RsFirReset(DOWNSAMPLE_ECG);\r
+ GH3X2X_DownSampleMarcoIni(usEcgSampleRate);\r
+ if(usEcgSampleRate == 500)\r
+ {\r
+ #if RESAMPLE_800HZ_TO_500HZ\r
+ if(DOWNSAMPLE_800HZ_TO_500HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_800_500hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 182;\r
+ pstECGDownSampCalParamInfo->uchRsI = 5;\r
+ pstECGDownSampCalParamInfo->uchRsD = 8;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ }\r
+ #endif\r
+ }\r
+ else if(usEcgSampleRate == 250)\r
+ {\r
+ #if RESAMPLE_800HZ_TO_250HZ\r
+ if(DOWNSAMPLE_800HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_800_250hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 250;\r
+ pstECGDownSampCalParamInfo->uchRsI = 5;\r
+ pstECGDownSampCalParamInfo->uchRsD = 16;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_320HZ_TO_250HZ\r
+ if(DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_320_250hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 50;\r
+ pstECGDownSampCalParamInfo->uchRsI = 1;\r
+ pstECGDownSampCalParamInfo->uchRsD = 1;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ pstECGDownSampCalParamInfo->ufStep = 128;\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_256HZ_TO_250HZ\r
+ if(DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_256_250hz;\r
+ pstECGDownSampCalParamInfo->uchRsFirOrder = 100;\r
+ pstECGDownSampCalParamInfo->uchRsI = 1;\r
+ pstECGDownSampCalParamInfo->uchRsD = 1;\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+ pstECGDownSampCalParamInfo->ufStep = 1024;\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ pstECGDownSampCalParamInfo->uchRsEnable = 0;\r
+ return;\r
+ }\r
+\r
+ if(pstECGDownSampCalParamInfo->uchRsFirOrder % 2)\r
+ {\r
+ pstECGDownSampCalParamInfo->uchRsFirCoefNum = ((pstECGDownSampCalParamInfo->uchRsFirOrder+1)/2) ;\r
+ }\r
+ else\r
+ {\r
+ pstECGDownSampCalParamInfo->uchRsFirCoefNum = ((pstECGDownSampCalParamInfo->uchRsFirOrder+2)/2);\r
+ }\r
+ pstECGDownSampCalParamInfo->uchRsBufSize = (pstECGDownSampCalParamInfo->uchRsFirOrder / pstECGDownSampCalParamInfo->uchRsI + 1);\r
+}\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+void GH3X2X_PPGResampleConfig(GU16 usPPGSampleRate)\r
+{\r
+ RsFirReset(DOWNSAMPLE_PPG);\r
+ GH3X2X_DownSampleMarcoIni(usPPGSampleRate);\r
+ if(usPPGSampleRate == 250)\r
+ {\r
+ #if RESAMPLE_400HZ_TO_250HZ\r
+ pstPPGDownSampCalParamInfo->rsFirCoef = (GS32*)rsFirCoef_250hz2;\r
+ pstPPGDownSampCalParamInfo->uchRsFirOrder = 126;\r
+ pstPPGDownSampCalParamInfo->uchRsI = 5;\r
+ pstPPGDownSampCalParamInfo->uchRsD = 8;\r
+ pstPPGDownSampCalParamInfo->uchRsEnable = 1;\r
+ #else\r
+ pstPPGDownSampCalParamInfo->uchRsEnable = 0;\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ pstPPGDownSampCalParamInfo->uchRsEnable = 0;\r
+ return;\r
+ }\r
+\r
+ if(pstPPGDownSampCalParamInfo->uchRsFirOrder % 2)\r
+ {\r
+ pstPPGDownSampCalParamInfo->uchRsFirCoefNum = ((pstPPGDownSampCalParamInfo->uchRsFirOrder+1)/2) ;\r
+ }\r
+ else\r
+ {\r
+ pstPPGDownSampCalParamInfo->uchRsFirCoefNum = ((pstPPGDownSampCalParamInfo->uchRsFirOrder+2)/2);\r
+ }\r
+ pstPPGDownSampCalParamInfo->uchRsBufSize = (pstPPGDownSampCalParamInfo->uchRsFirOrder / pstPPGDownSampCalParamInfo->uchRsI + 1);\r
+}\r
+#else\r
+void GH3X2X_PPGResampleConfig(GU16 usPPGSampleRate)\r
+{\r
+ return;\r
+}\r
+#endif\r
+\r
+void GH3X2X_LeadOffDetectResetSingleChip(GU8 uchChipIndex)\r
+{\r
+ int i;\r
+ STGh3x2xSoftLeadOffDetInfo * pstSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfo + uchChipIndex;\r
+ pstSoftLeadOffDetInfo -> snCounter = 0;\r
+ pstSoftLeadOffDetInfo -> sniqCounter = 0;\r
+ pstSoftLeadOffDetInfo -> snniVal = 0;\r
+ pstSoftLeadOffDetInfo -> snnqVal = 0;\r
+ pstSoftLeadOffDetInfo -> uchFastRecoryHistory = 0;\r
+ for (i = 0; i < AMP_NUM; i++)\r
+ pstSoftLeadOffDetInfo -> snniqAmp[i] = 0;\r
+}\r
+\r
+void GH3X2X_LeadOffDetectReset(void)\r
+{\r
+ GH3X2X_LeadOffDetectResetSingleChip(0);\r
+}\r
+\r
+void GH3X2X_ConfigLeadOffThr(GU32 uIQAmpThr, GU32 uIQAmpDiffThr,GU32 uValThr)\r
+{\r
+ g_nLeadOffDetIqAmpThr = uIQAmpThr;\r
+ g_lLeadOffDetIqAmp = ((long long)g_nLeadOffDetIqAmpThr * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef);\r
+ g_lLeadOffDetIqAmpThrRaw = (g_lLeadOffDetIqAmp*g_lLeadOffDetIqAmp);\r
+ g_lLeadOffDetIqAmpFrThrRaw = (g_lLeadOffDetIqAmp*g_lLeadOffDetIqAmp / 20 / 20); \r
+\r
+ g_nLeadOffDetIqAmpDiffThr = uIQAmpDiffThr;\r
+ g_lLeadOffDetIqAmpDiff = ((long long)g_nLeadOffDetIqAmpDiffThr * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef);\r
+ g_lLeadOffDetIqAmpDiffThrRaw = (g_lLeadOffDetIqAmpDiff*g_lLeadOffDetIqAmpDiff);\r
+ g_lLeadOffDetIqAmpDiffFrThrRaw = (g_lLeadOffDetIqAmpDiff*g_lLeadOffDetIqAmpDiff / 20 / 20); \r
+\r
+ g_nLeadOffDetValThr = uValThr;\r
+ g_LeadOffDetValThrRaw = (g_nLeadOffDetValThr * (20 * ADC_OFFSET / ADCREF)); \r
+}\r
+\r
+GS32 GH3X2X_LeadOffDetectInit(void)\r
+{\r
+ GH3X2X_ECGResampleConfig(g_usEcgOutputFs);\r
+ \r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ GH3X2X_PPGResampleConfig(GH3X2X_PPG_DOWN_FS); \r
+ #endif\r
+ \r
+ GH3X2X_ConfigLeadOffThr(g_nLeadOffDetIqAmpThr, g_nLeadOffDetIqAmpDiffThr, g_nLeadOffDetValThr);\r
+ GH3X2X_LeadOffDetectReset();\r
+ return 0;\r
+}\r
+\r
+/**\r
+ * @fn GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16 usFifoBufferLen)\r
+ *\r
+ * @brief Lead off Detection, suppose the increment of normal ECG value in LEADOFF_DET_POINT_NUM+1 samples point \r
+ * not exceed LEADOFF_DET_THR_mV\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] puchFifoBuffer pointer to read fifo data buffer\r
+ * @param[in] usFifoBufferLen read fifo buffer len\r
+ * @param[out] None\r
+ *\r
+ * @return lead off status output \r
+ * @retval #0 not detect lead off\r
+ * @retval bit0=1 AdcValue larger than thresh\r
+ * @retval bit1=1 IQ Value larger than thresh\r
+ */\r
+\r
+GU8 GH3X2X_LeadOffDetectSingleChip(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 unChipIndex, GU8 uchEcgSlotNum)\r
+{\r
+ GU16 usByteIndexTmp = 0;\r
+ GS32 j;\r
+ GU8 uchRet = 0;\r
+ GU32 fifoVal;\r
+ GS32 adcVal;\r
+ GU8 flagFastRecovery;\r
+ GS32 absAdcVal; //ABS of adcVal\r
+ GS64 temp;\r
+\r
+ STGh3x2xSoftLeadOffDetInfo * pstSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfo + unChipIndex;\r
+\r
+ for (usByteIndexTmp = 0; usByteIndexTmp < *pusFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+ {\r
+ if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == GH3X2X_AFE_GET_ECG_CHANNEL_MAP(uchEcgSlotNum))\r
+ {\r
+ fifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchFifoBuffer[usByteIndexTmp], puchFifoBuffer[usByteIndexTmp + 1],puchFifoBuffer[usByteIndexTmp + 2], puchFifoBuffer[usByteIndexTmp + 3]);\r
+ adcVal = (GS32)((fifoVal & 0x00FFFFFF)) - ADC_OFFSET; \r
+ flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+ if(flagFastRecovery)\r
+ {\r
+ pstSoftLeadOffDetInfo->uchFastRecoryHistory = 1;\r
+ //GH3X2X_INFO_LOG("has fast recovery!!!!\r\n");\r
+ }\r
+ if(0 == pstSoftLeadOffDetInfo->uchFastRecoryHistory)\r
+ {\r
+ //GH3X2X_INFO_LOG("Warning: No fast recovery!!!!\r\n");\r
+ continue;\r
+ }\r
+ if (pstSoftLeadOffDetInfo-> uchFlagFrPrev != flagFastRecovery)\r
+ {\r
+ GH3X2X_LeadOffDetectReset();\r
+ pstSoftLeadOffDetInfo->uchFastRecoryHistory = 1;\r
+ }\r
+ pstSoftLeadOffDetInfo-> uchFlagFrPrev = flagFastRecovery;\r
+\r
+ //sample counter\r
+ if (pstSoftLeadOffDetInfo -> snCounter < 20000)\r
+ pstSoftLeadOffDetInfo -> snCounter++;\r
+ \r
+ if (flagFastRecovery == 0 && pstSoftLeadOffDetInfo -> snCounter>COND_VAL_VALID_TIME)\r
+ {\r
+ absAdcVal = ABS(adcVal);\r
+ if (absAdcVal > g_LeadOffDetValThrRaw)\r
+ uchRet |= 0x01;\r
+ }\r
+ if (pstSoftLeadOffDetInfo -> sniqCounter < IQ_NUM / 2)\r
+ {\r
+ temp = (GS64)adcVal*winCoef[pstSoftLeadOffDetInfo -> sniqCounter];\r
+ }\r
+ else\r
+ {\r
+ temp = (GS64)adcVal*winCoef[IQ_NUM-1 - pstSoftLeadOffDetInfo -> sniqCounter];\r
+ }\r
+ switch (pstSoftLeadOffDetInfo -> sniqCounter%4)\r
+ {\r
+ case 0:\r
+ pstSoftLeadOffDetInfo -> snniVal += temp;\r
+ break;\r
+ case 1:\r
+ pstSoftLeadOffDetInfo -> snnqVal += temp;\r
+ break;\r
+ case 2:\r
+ pstSoftLeadOffDetInfo -> snniVal -= temp;\r
+ break;\r
+ case 3:\r
+ pstSoftLeadOffDetInfo -> snnqVal -= temp;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ if (pstSoftLeadOffDetInfo -> sniqCounter == (IQ_NUM - 1))\r
+ {\r
+ for (j = AMP_NUM-1; j >0; j--)\r
+ {\r
+ pstSoftLeadOffDetInfo -> snniqAmp[j] = pstSoftLeadOffDetInfo -> snniqAmp[j - 1];\r
+ }\r
+ pstSoftLeadOffDetInfo -> snniVal = pstSoftLeadOffDetInfo -> snniVal >> 31;\r
+ pstSoftLeadOffDetInfo -> snnqVal = pstSoftLeadOffDetInfo -> snnqVal >> 31;\r
+ pstSoftLeadOffDetInfo -> snniqAmp[0] = pstSoftLeadOffDetInfo -> snniVal*(int)pstSoftLeadOffDetInfo -> snniVal + pstSoftLeadOffDetInfo -> snnqVal*(int)pstSoftLeadOffDetInfo -> snnqVal;\r
+ pstSoftLeadOffDetInfo -> snniVal = 0;\r
+ pstSoftLeadOffDetInfo -> snnqVal = 0;\r
+ \r
+ if (flagFastRecovery == 0)\r
+ {\r
+ if (pstSoftLeadOffDetInfo -> snniqAmp[0] > g_lLeadOffDetIqAmpThrRaw && pstSoftLeadOffDetInfo -> snniqAmp[1] > g_lLeadOffDetIqAmpThrRaw)\r
+ uchRet |= 0x02;\r
+\r
+ if ((pstSoftLeadOffDetInfo -> snniqAmp[0] - pstSoftLeadOffDetInfo -> snniqAmp[2]) > g_lLeadOffDetIqAmpDiffThrRaw && (pstSoftLeadOffDetInfo -> snniqAmp[1] - pstSoftLeadOffDetInfo -> snniqAmp[2]) > g_lLeadOffDetIqAmpDiffThrRaw)\r
+ {\r
+ if(pstSoftLeadOffDetInfo ->snCounter > 2 * IQ_NUM)\r
+ {\r
+ uchRet |= 0x04;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (pstSoftLeadOffDetInfo -> snniqAmp[0] > g_lLeadOffDetIqAmpFrThrRaw && pstSoftLeadOffDetInfo -> snniqAmp[1] > g_lLeadOffDetIqAmpFrThrRaw)\r
+ uchRet |= 0x08;\r
+ }\r
+ }\r
+ pstSoftLeadOffDetInfo -> sniqCounter++;\r
+ pstSoftLeadOffDetInfo -> sniqCounter = pstSoftLeadOffDetInfo -> sniqCounter%(IQ_NUM);\r
+ } // end of if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == g_uchEcgLeadChannelMap)\r
+ } // end of for (usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+\r
+ return uchRet;\r
+}\r
+\r
+\r
+\r
+void GH3x2xSetEcgOutputFs(GU16 usEcgOutputFs)\r
+{\r
+ g_usEcgOutputFs = usEcgOutputFs;\r
+}\r
+\r
+GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum)\r
+{\r
+ GU8 uchRet = 0;\r
+ uchRet |= GH3X2X_LeadOffDetectSingleChip(puchFifoBuffer, pusFifoBufferLen, 0, uchEcgSlotNum);\r
+ if(g_uchGh3x2xEcgChnlNumLimit > 1)\r
+ {\r
+ uchRet |= GH3X2X_LeadOffDetectSingleChip(puchFifoBuffer, pusFifoBufferLen, 1, uchEcgSlotNum);\r
+ }\r
+ return uchRet;\r
+}\r
+\r
+void GH3X2X_DownSampleCal( GU8 *puchFifoBuffer, GU16 usByteIndexTmp, GU16 *usRawdataBufIdx, GU16 usSampleRate, STGh3x2xRsInfo * pstRsInfo ,STGh3x2xDownSampleCalParamInfo * pstDownSampCalParamInfo)\r
+{\r
+ GU32 fifoVal;\r
+ GS32 adcVal;\r
+ GU8 chNo;\r
+ GU8 flagFastRecovery;\r
+ GS32 j;\r
+\r
+ fifoVal = GH3X2X_AFE_MAKEUP_DWORD(puchFifoBuffer[usByteIndexTmp], puchFifoBuffer[usByteIndexTmp + 1], puchFifoBuffer[usByteIndexTmp + 2], puchFifoBuffer[usByteIndexTmp + 3]);\r
+ chNo = (fifoVal >> 27); \r
+ adcVal = (GS32)((fifoVal & 0x00FFFFFF)) - ADC_OFFSET; \r
+ \r
+ if(g_uchDownSampleModule == DOWNSAMPLE_ECG)\r
+ {\r
+ flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+ if (pstRsInfo ->uchFlagFrPrev != flagFastRecovery)\r
+ {\r
+ GH3X2X_ECGResampleConfig(usSampleRate);\r
+ }\r
+ pstRsInfo ->uchFlagFrPrev = flagFastRecovery;\r
+ }\r
+\r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ else if(g_uchDownSampleModule == DOWNSAMPLE_PPG)\r
+ {\r
+ flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+ if (pstRsInfo ->uchFlagFrPrev != 1)\r
+ {\r
+ if(usSampleRate)\r
+ {\r
+ GH3X2X_PPGResampleConfig(usSampleRate);\r
+ }\r
+ }\r
+ pstRsInfo ->uchFlagFrPrev = 1;\r
+ }\r
+ #endif\r
+ \r
+ // ECG downsample\r
+ #if RESAMPLE_320HZ_TO_250HZ || RESAMPLE_256HZ_TO_250HZ\r
+ if((DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType) || (DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType))\r
+ { \r
+ GS32 LinerAdcVal;\r
+ if(pstDownSampCalParamInfo->uchRsEnable)\r
+ {\r
+ GS32 k;\r
+ GS64 y;\r
+\r
+ //??\r
+ if (pstRsInfo ->snRsFirState > 0)\r
+ {\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead - 1;\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead < 0 ? (pstDownSampCalParamInfo->uchRsBufSize - 1) : pstRsInfo ->snBufHead;\r
+ pstRsInfo ->snRsXbuf[pstRsInfo ->snBufHead] = adcVal;\r
+ }\r
+ else\r
+ {\r
+ for (j = 0; j < pstDownSampCalParamInfo->uchRsFirOrder / pstDownSampCalParamInfo->uchRsI + 1; j++)\r
+ pstRsInfo ->snRsXbuf[j] = adcVal;\r
+ pstRsInfo ->snBufHead = pstDownSampCalParamInfo->uchRsBufSize - 1;\r
+ }\r
+ \r
+ k = pstRsInfo ->snBufHead;\r
+ y = 0;\r
+ for (j = 1; j < pstDownSampCalParamInfo->uchRsFirCoefNum; j = j + 1) //\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+ for (; j <(pstDownSampCalParamInfo->uchRsFirOrder+1); j = j + 1) //\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[pstDownSampCalParamInfo->uchRsFirOrder - j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+\r
+ y = y >> SHIFTBITS;\r
+ k = (GS32)y + ADC_OFFSET; //\r
+ if (k < 0)\r
+ k = 0;\r
+ else if (k>=(ADC_OFFSET * 2))\r
+ k = (ADC_OFFSET * 2-1);\r
+\r
+ // ???????\r
+ if(pstRsInfo->uchLinearInterState >0)\r
+ {\r
+ #if RESAMPLE_320HZ_TO_250HZ\r
+ if(DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ if(pstRsInfo->fDownStep <=100)\r
+ {\r
+ LinerAdcVal = ((GU32)k*pstRsInfo->fDownStep + (100-pstRsInfo->fDownStep)*pstRsInfo->nRsLastRaw)/100;\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep - 100;\r
+ pstRsInfo->uchLinearDataUpdate = 1;\r
+ }\r
+ else\r
+ {\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep - 100;\r
+ pstRsInfo->uchLinearDataUpdate = 0;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_256HZ_TO_250HZ\r
+ if(DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+ {\r
+ if(pstRsInfo->fDownStep <=1000)\r
+ {\r
+ LinerAdcVal = (GU32)(((GS64)(k)*(GS64)(pstRsInfo->fDownStep) + (GS64)((1000-pstRsInfo->fDownStep)*(GS64)(pstRsInfo->nRsLastRaw)))/1000);\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep - 1000;\r
+ pstRsInfo->uchLinearDataUpdate = 1;\r
+ }\r
+ else\r
+ {\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep - 1000;\r
+ pstRsInfo->uchLinearDataUpdate = 0;\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ LinerAdcVal = (GU32)k;\r
+ pstRsInfo->nRsLastRaw = (GU32)k;\r
+ pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep;\r
+ pstRsInfo->uchLinearInterState =1;\r
+ pstRsInfo->uchLinearDataUpdate = 1;\r
+ }\r
+\r
+ if(pstRsInfo->uchLinearDataUpdate == 1)\r
+ {\r
+ fifoVal = (((GU8)chNo)<<27) + (((GU8)flagFastRecovery)<<26) + ((GU32)LinerAdcVal/5);\r
+ puchFifoBuffer[*usRawdataBufIdx] = GH3X2X_AFE_GET_BYTE3_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 1] = GH3X2X_AFE_GET_BYTE2_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 2] = GH3X2X_AFE_GET_BYTE1_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 3] = GH3X2X_AFE_GET_BYTE0_FROM_DWORD(fifoVal);\r
+\r
+ *usRawdataBufIdx += GH3X2X_AFE_FIFO_RAWDATA_SIZE;\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if RESAMPLE_800HZ_TO_500HZ ||RESAMPLE_800HZ_TO_250HZ || (RESAMPLE_400HZ_TO_250HZ & (__SUPPORT_ECG_PPG_DOWNSAMP__))\r
+ if((DOWNSAMPLE_800HZ_TO_500HZ == pstECGDownSampCalParamInfo->uchDownSampleType)||(DOWNSAMPLE_800HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)||(DOWNSAMPLE_400HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType))\r
+ {\r
+ if(pstDownSampCalParamInfo->uchRsEnable)\r
+ {\r
+ GS32 k;\r
+ GS64 y;\r
+ GS32 delta;\r
+ if (pstRsInfo ->snRsFirState > 0)\r
+ {\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead - 1;\r
+ pstRsInfo ->snBufHead = pstRsInfo ->snBufHead < 0 ? (pstDownSampCalParamInfo->uchRsBufSize - 1) : pstRsInfo ->snBufHead;\r
+ pstRsInfo ->snRsXbuf[pstRsInfo ->snBufHead] = adcVal;\r
+ pstRsInfo ->nRsIcounter += pstDownSampCalParamInfo->uchRsI;\r
+ }\r
+ else\r
+ {\r
+ for (j = 0; j < pstDownSampCalParamInfo->uchRsFirOrder / pstDownSampCalParamInfo->uchRsI + 1; j++)\r
+ pstRsInfo ->snRsXbuf[j] = adcVal;\r
+ pstRsInfo ->nRsIcounter = 0;\r
+ pstRsInfo ->snRsFirState = 1;\r
+ pstRsInfo ->snBufHead = pstDownSampCalParamInfo->uchRsBufSize - 1;\r
+ }\r
+\r
+ if (pstRsInfo ->nRrsDcounter >= pstRsInfo ->nRsIcounter && pstRsInfo ->nRrsDcounter < (pstRsInfo ->nRsIcounter + pstDownSampCalParamInfo->uchRsI))\r
+ {\r
+ delta = pstRsInfo ->nRrsDcounter - pstRsInfo ->nRsIcounter;\r
+ k = pstRsInfo ->snBufHead;\r
+ y = 0;\r
+ for (j = delta; j < pstDownSampCalParamInfo->uchRsFirCoefNum; j = j + pstDownSampCalParamInfo->uchRsI)\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+ for (j = j; j <(pstDownSampCalParamInfo->uchRsFirOrder+1); j = j + pstDownSampCalParamInfo->uchRsI)\r
+ {\r
+ y += ((GS64)pstRsInfo ->snRsXbuf[k] * pstDownSampCalParamInfo->rsFirCoef[pstDownSampCalParamInfo->uchRsFirOrder - j]);\r
+ k = (k + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+ }\r
+ pstRsInfo ->nRrsDcounter += pstDownSampCalParamInfo->uchRsD;\r
+\r
+ y = y >> SHIFTBITS;\r
+ k = (GS32)y + ADC_OFFSET;\r
+ if (k < 0)\r
+ k = 0;\r
+ else if (k>=(ADC_OFFSET * 2))\r
+ k = (ADC_OFFSET * 2-1); \r
+ fifoVal = (((GU8)chNo)<<27) + (((GU8)flagFastRecovery)<<26) + ((GU32)k);\r
+ puchFifoBuffer[*usRawdataBufIdx] = GH3X2X_AFE_GET_BYTE3_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 1] = GH3X2X_AFE_GET_BYTE2_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 2] = GH3X2X_AFE_GET_BYTE1_FROM_DWORD(fifoVal);\r
+ puchFifoBuffer[*usRawdataBufIdx + 3] = GH3X2X_AFE_GET_BYTE0_FROM_DWORD(fifoVal);\r
+ *usRawdataBufIdx += GH3X2X_AFE_FIFO_RAWDATA_SIZE;\r
+ }\r
+ }\r
+ }\r
+#endif\r
+}\r
+\r
+void GH3X2X_EcgPPGRsHandleSingleChip(GU8 *puchFifoBuffer, GU16 *pusFifoBufferLen, GU8 uchChipIndex, GU8 uchEcgSlotNum ,GU16 usSampleRate)\r
+{\r
+ GU16 usByteIndexTmp = 0;\r
+ GU16 usRawdataBufIdx = 0;\r
+ GU8 usCheckDataType = 0; // 1:ECG 2:PPG 0:other\r
+\r
+ for (usByteIndexTmp = 0; usByteIndexTmp < *pusFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+ { \r
+ if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == GH3X2X_AFE_GET_ECG_CHANNEL_MAP((GU8)(GH3X2X_ECG_START_SLOT + uchEcgSlotNum)))\r
+ {\r
+ STGh3x2xRsInfo * pstRsInfo_ECG = g_pstGh3x2xEcgRsInfo + uchChipIndex;\r
+ g_uchDownSampleModule = DOWNSAMPLE_ECG;\r
+ GH3X2X_DownSampleCal( puchFifoBuffer, usByteIndexTmp, &usRawdataBufIdx, usSampleRate,pstRsInfo_ECG,pstECGDownSampCalParamInfo);\r
+ usCheckDataType =1;\r
+ }\r
+ \r
+ #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+ if(g_uchPPGDownSampleChnlNumLimit && pstPPGDownSampCalParamInfo->uchRsEnable==1)\r
+ {\r
+ for(GU8 uchPPGSlotNumTmp = 0; uchPPGSlotNumTmp < g_uchPPGDownSampleChnlNumLimit; uchPPGSlotNumTmp++)\r
+ {\r
+ if (GH3X2X_AFE_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == GH3X2X_AFE_GET_PPG_CHANNEL_MAP((GU8)(GH3X2X_PPG_START_SLOT + uchPPGSlotNumTmp)))\r
+ {\r
+ STGh3x2xRsInfo * pstRsInfo_PPG = g_pstGh3x2xPPGRsInfo + uchPPGSlotNumTmp;\r
+ g_uchDownSampleModule = DOWNSAMPLE_PPG;\r
+ GH3X2X_DownSampleCal(puchFifoBuffer, usByteIndexTmp, &usRawdataBufIdx, usSampleRate,pstRsInfo_PPG,pstPPGDownSampCalParamInfo);\r
+ usCheckDataType =2;\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+ if(!usCheckDataType)\r
+ {\r
+ if(pstECGDownSampCalParamInfo->uchRsEnable)\r
+ {\r
+ //this rawdata is not ECG data\r
+ puchFifoBuffer[usRawdataBufIdx] = puchFifoBuffer[usByteIndexTmp];\r
+ puchFifoBuffer[usRawdataBufIdx + 1] = puchFifoBuffer[usByteIndexTmp + 1];\r
+ puchFifoBuffer[usRawdataBufIdx + 2] = puchFifoBuffer[usByteIndexTmp + 2];\r
+ puchFifoBuffer[usRawdataBufIdx + 3] = puchFifoBuffer[usByteIndexTmp + 3];\r
+ usRawdataBufIdx += GH3X2X_AFE_FIFO_RAWDATA_SIZE;\r
+ }\r
+ }\r
+ usCheckDataType = 0;\r
+ } // end of for (usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_AFE_FIFO_RAWDATA_SIZE)\r
+ *pusFifoBufferLen = usRawdataBufIdx;\r
+}\r
+\r
+GU8 GH3X2X_AFE_EcgRsHandle(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 uchEcgSlotNum, GU16 usEcgSampleRate)\r
+{\r
+ if(pstECGDownSampCalParamInfo->uchRsEnable == 1)\r
+ {\r
+ GH3X2X_EcgPPGRsHandleSingleChip(puchFifoBuffer, pusFifoBufferLen, 0,uchEcgSlotNum,usEcgSampleRate);\r
+ return 1;\r
+ }\r
+ else\r
+ {\r
+ return 0;\r
+ }\r
+}\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
+\r
--- /dev/null
+#include "gh3x2x_afe_user.h"\r
+#include "gh3x2x_afe_drv.h"\r
+#include "pinctrl_porting.h"\r
+#include "hal_gpio.h"\r
+#include "i2c.h"\r
+#include "pm_definition.h"\r
+#if GH3X2X_AFE_MP_MODE\r
+// #include "gh3x2x_mp_common.h"\r
+#endif\r
+\r
+#include "los_tick.h"\r
+#include "debug_print.h"\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#include "gh3x2x_demo_goodix_PLATFORM.h"\r
+#else\r
+\r
+\r
+#include "spi.h"\r
+\r
+#include "custom_utils.h"\r
+\r
+#define GOODIX_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length)\r
+#define GOODIX_PLATFORM_SPI_READ_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_CS_CTRL_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_RESET_PIN_ENTITY()\r
+#define GOODIX_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY()\r
+#define GOODIX_PLATFORM_LOG_ENTITY() \r
+#define GOODIX_PLATFORM_DELAY_US_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_MS_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_MS_ENTITY()\r
+#define GOODIX_PLATFORM_INT_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_RESET_PIN_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer,length)\r
+#define GOODIX_PLATFORM_I2C_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length)\r
+#endif\r
+\r
+#define GH3X2X_CS S_MGPIO3\r
+#define GH3X2X_CLK S_MGPIO2\r
+#define GH3X2X_MOSI S_MGPIO1\r
+#define GH3X2X_MISO S_MGPIO0\r
+\r
+#define H_INT S_AGPIO_R6\r
+\r
+#define GH3X2X_SPI_BUS SPI_BUS_0\r
+#define GH3X2X_I2C_BUS I2C_BUS_2\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_DelayUs(GU16 usUsec)\r
+ * \r
+ * @brief Delay in us,user should register this function into driver lib\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void hal_gh3x2x_afe_DelayUs(GU16 usUsec)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(usUsec);\r
+ // GOODIX_PLATFORM_DELAY_US_ENTITY();\r
+ LOS_Udelay(usUsec);\r
+\r
+}\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_BspDelayMs(GU16 usMsec)\r
+ * \r
+ * @brief Delay in ms\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void hal_gh3x2x_afe_DelayMs(GU16 usMsec)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(usMsec);\r
+ // GOODIX_PLATFORM_DELAY_MS_ENTITY();\r
+ LOS_Mdelay(usMsec);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+#if ( GH3X2X_AFE_COM_INTERFACE_TYPE == GH3X2X_AFE_COM_INTERFACE_I2C )\r
+\r
+/* i2c interface */\r
+/**\r
+ * @fn void hal_gh3x2x_afe_i2c_init(void)\r
+ * \r
+ * @brief hal i2c init for gh3x2x_afe\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void hal_gh3x2x_afe_i2c_init(void)\r
+{\r
+\r
+ /* code implement by user */\r
+ GOODIX_PLATFORM_I2C_INIT_ENTITY();\r
+\r
+}\r
+\r
+/**\r
+ * @fn uint8_t hal_gh3x2x_afe_i2c_write(uint8_t device_id, const uint8_t write_buffer[], uint16_t length)\r
+ * \r
+ * @brief hal i2c write for gh3x2x_afe\r
+ *\r
+ * @attention device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in] device_id device addr\r
+ * @param[in] write_buffer write data buffer\r
+ * @param[in] length write data len\r
+ * @param[out] None\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length)\r
+{\r
+ // custom_i2c_transfer(0x14,write_buffer, length, NULL, 0, GH3X2X_I2C_BUS);\r
+ custom_i2c_write_reg(0x14, 0, 0, write_buffer, length, GH3X2X_I2C_BUS);\r
+ return 1;\r
+}\r
+\r
+/**\r
+ * @fn uint8_t hal_gh3x2x_afe_i2c_read(uint8_t device_id, const uint8_t write_buffer[], uint16_t write_length,\r
+ * uint8_t read_buffer[], uint16_t read_length)\r
+ * \r
+ * @brief hal i2c read for gh3x2x_afe\r
+ *\r
+ * @attention device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in] device_id device addr\r
+ * @param[in] write_buffer write data buffer\r
+ * @param[in] write_length write data len\r
+ * @param[in] read_length read data len\r
+ * @param[out] read_buffer pointer to read buffer\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length)\r
+{\r
+ // custom_i2c_transfer(0x14,write_buffer, write_length, read_buffer, read_length, GH3X2X_I2C_BUS);\r
+ // custom_i2c_write_reg(0x14, 0, 0, write_buffer, length, GH3X2X_I2C_BUS);\r
+ custom_i2c_read_regs(0x14, write_buffer, write_length, read_buffer,read_length, GH3X2X_I2C_BUS);\r
+ return 1;\r
+}\r
+\r
+#else \r
+\r
+/* spi interface */\r
+/**\r
+ * @fn void hal_gh3x2x_afe_spi_init(void)\r
+ * \r
+ * @brief hal spi init for gh3x2x_afe\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void hal_gh3x2x_afe_spi_init(void)\r
+{\r
+ /* init spi and cs pin */\r
+ GOODIX_PLATFORM_SPI_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn GU8 hal_gh3x2x_afe_spi_write(GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief hal spi write for gh3x2x_afe\r
+ *\r
+ * @attention if __gh3x2x_afe_SPI_TYPE__ == __gh3x2x_afe_SPI_TYPE_SOFTWARE_CS__ , user need generate timming: write_buf[0](W) + write_buf[1](W) + ...\r
+ * @attention if __gh3x2x_afe_SPI_TYPE__ == __gh3x2x_afe_SPI_TYPE_HARDWARE_CS__ , user need generate timming: CS LOW + write_buf[0](W) + write_buf[1](W) + ... + CS HIGH\r
+ *\r
+ * @param[in] write_buffer write data buffer\r
+ * @param[in] length write data len\r
+ * @param[out] None\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_spi_write(GU8 write_buffer[], GU16 length)\r
+{\r
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 0) \r
+ {\r
+ uapi_pm_add_sleep_veto(PM_ID_HEART);\r
+ }\r
+\r
+ errcode_t ret;\r
+\r
+ // GOODIX_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length);\r
+ spi_xfer_data_t sdata ={0} ;\r
+ sdata.tx_buff = write_buffer;\r
+ sdata.tx_bytes = length;\r
+ sdata.rx_buff = NULL;\r
+ sdata.rx_bytes = 0;\r
+\r
+ ret = uapi_spi_master_write(GH3X2X_SPI_BUS, &sdata, 0XFF);\r
+ if (ret != ERRCODE_SUCC) \r
+ printf("spi write data fail! ret=0x%x\n", ret);\r
+\r
+ cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 1) \r
+ {\r
+ uapi_pm_remove_sleep_veto(PM_ID_HEART);\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+/**\r
+ * @fn GU8 hal_gh3x2x_afe_spi_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief hal spi read for gh3x2x_afe\r
+ *\r
+ * @attention user need generate timming: read_buf[0](R) + write_buf[1](R) + ... \r
+ *\r
+ * @param[in] read_length read data len\r
+ * @param[out] read_buffer pointer to read buffer\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_spi_read(GU8 read_buffer[], GU16 length)\r
+{\r
+ uint8_t cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 0) \r
+ {\r
+ uapi_pm_add_sleep_veto(PM_ID_HEART);\r
+ }\r
+\r
+ errcode_t ret;\r
+ // GH3X2X_AFE_UNUSED_VAR(read_buffer);\r
+ // GH3X2X_AFE_UNUSED_VAR(length);\r
+ // GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+\r
+ spi_xfer_data_t sdata ={0} ;\r
+ sdata.tx_buff = NULL;\r
+ sdata.tx_bytes = 0;\r
+ sdata.rx_buff = read_buffer;\r
+ sdata.rx_bytes = length;\r
+\r
+ ret = uapi_spi_master_read(GH3X2X_SPI_BUS, &sdata, 0XFF);\r
+\r
+ cnt = pm_veto_get_id_cnt(PM_ID_HEART);\r
+ if (cnt == 1) \r
+ {\r
+ uapi_pm_remove_sleep_veto(PM_ID_HEART);\r
+ }\r
+\r
+ return 1;\r
+}\r
+#elif (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_HARDWEAR_CS)\r
+/**\r
+ * @fn GU8 hal_gh3x2x_afe_spi_write_F1_and_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief hal spi write F1 and read for gh3x2x_afe\r
+ *\r
+ * @attention user need generate timming: CS LOW + F1(W) + read_buf[0](R) + read_buf[1](R) + ... + CS HIGH\r
+ *\r
+ * @param[in] write_buf write data\r
+ * @param[in] length write data len\r
+ *\r
+ * @return status\r
+ * @retval #1 return successfully\r
+ * @retval #0 return error\r
+ */\r
+GU8 hal_gh3x2x_afe_spi_write_F1_and_read(GU8 read_buffer[], GU16 length)\r
+{\r
+ // GU8 ret = 1;\r
+ // GH3X2X_AFE_UNUSED_VAR(read_buffer);\r
+ // GH3X2X_AFE_UNUSED_VAR(length);\r
+ // GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+ \r
+ // return ret;\r
+\r
+ errcode_t ret = 1;\r
+ // GH3X2X_AFE_UNUSED_VAR(read_buffer);\r
+ // GH3X2X_AFE_UNUSED_VAR(length);\r
+ // GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+\r
+ spi_xfer_data_t sdata ={0} ;\r
+ sdata.tx_buff = NULL;\r
+ sdata.tx_bytes = 0;\r
+ sdata.rx_buff = read_buffer;\r
+ sdata.rx_bytes = length;\r
+\r
+ ret = uapi_spi_master_read(GH3X2X_SPI_BUS, &sdata, 0XFF);\r
+ if (ret != ERRCODE_SUCC) \r
+ printf("spi read data fail! ret=0x%x\n", ret);\r
+ return 1;\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_spi_cs_ctrl(GU8 cs_pin_level)\r
+ * \r
+ * @brief hal spi cs pin ctrl for gh3x2x_afe\r
+ *\r
+ * @attention pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in] cs_pin_level spi cs pin level\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+\r
+\r
+#if (GH3X2X_AFE_SPI_TYPE == GH3X2X_AFE_SPI_SOFTWARE_CS) \r
+void hal_gh3x2x_afe_spi_cs_ctrl(GU8 cs_pin_level)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(cs_pin_level);\r
+ // GOODIX_PLATFORM_SPI_CS_CTRL_ENTITY();\r
+\r
+ uapi_pin_set_mode(GH3X2X_CS, (pin_mode_t)HAL_PIO_FUNC_SPI0);\r
+ uapi_gpio_set_dir(GH3X2X_CS, GPIO_DIRECTION_OUTPUT);\r
+ uapi_gpio_set_val(GH3X2X_CS, cs_pin_level);\r
+\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+#if (GH3X2X_AFE_RESET_TYPE == GH3X2X_AFE_RESET_HARDWARE)\r
+/**\r
+ * @fn void hal_gh3x2x_afe_int_init(void)\r
+ * \r
+ * @brief gh3x2x_afe int init\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+\r
+\r
+void hal_gh3x2x_afe_reset_pin_init(void)\r
+{\r
+ GOODIX_PLATFORM_RESET_PIN_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_reset_pin_ctrl(GU8 pin_level)\r
+ * \r
+ * @brief hal reset pin ctrl for gh3x2x_afe\r
+ *\r
+ * @attention pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in] pin_level reset pin level\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+void hal_gh3x2x_afe_reset_pin_ctrl(GU8 pin_level)\r
+{\r
+ GH3X2X_AFE_UNUSED_VAR(pin_level);\r
+ GOODIX_PLATFORM_SPI_RESET_PIN_ENTITY();\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn void hal_gh3x2x_afe_int_init(void)\r
+ * \r
+ * @brief gh3x2x_afe int init\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+\r
+\r
+void hal_gh3x2x_afe_int_init(void)\r
+{\r
+ // GOODIX_PLATFORM_INT_INIT_ENTITY();\r
+ uapi_pin_set_ie(H_INT,HAL_PIO_IE_ENBALE);\r
+}\r
+\r
+void hal_gh3x2x_afe_int_deinit(void)\r
+{\r
+ // GOODIX_PLATFORM_INT_INIT_ENTITY();\r
+ uapi_pin_set_ie(H_INT,HAL_PIO_IE_DISABLE);\r
+}\r
+\r
+#if (GH3X2X_AFE_PRO_BY_INT == GH3X2X_AFE_PRO_TYPE)\r
+/**\r
+ * @fn void hal_gh3x2x_afe_int_handler_call_back(void)\r
+ * \r
+ * @brief call back of gh3x2x_afe int handler\r
+ *\r
+ * @attention None\r
+ *\r
+ * @param[in] None\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void hal_gh3x2x_afe_int_handler_call_back(void)\r
+{\r
+/****************** DO NOT MODITY ****************************************************************/\r
+ GH3X2X_AFE_SetNeedWakeUpGh3x2xFlag(0); //not need wake up gh3x2x_afe when process int event\r
+ g_uchGh3x2xAfeIntCallBackIsCalled = 1;\r
+#if GH3X2X_AFE_MP_MODE\r
+ // GH3X2X_MP_SET_INT_FLAG(); //gh3x2x mp test must call it\r
+#endif\r
+/****************** DO NOT MODITY ****************************************************************/\r
+ \r
+ \r
+ \r
+ GOODIX_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY();\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn void GH3X2X_AFE_Log(char *log_string)\r
+ * \r
+ * @brief for debug version, log\r
+ *\r
+ * @attention this function must define that use debug version lib\r
+ *\r
+ * @param[in] log_string pointer to log string\r
+ * @param[out] None\r
+ *\r
+ * @return None\r
+ */\r
+void GH3X2X_AFE_Log(GCHAR *log_string)\r
+{\r
+ // GH3X2X_AFE_UNUSED_VAR(log_string);\r
+ // GOODIX_PLATFORM_LOG_ENTITY();\r
+ PRINT("%s", log_string);\r
+}\r
+\r
--- /dev/null
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-03-13 15:08:38
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-05-28 14:13:17
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
+ * @Description:
+ *
+ * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include "pm_control.h"
+#include "pinctrl_porting.h"
+#include "hal_gpio.h"
+#include "gh3x2x_afe_user.h"
+#include "gh3x2x_afe_demo.h"
+
+// S_AGPIO_L26 心率复位 PPG reset
+#define GPIO_PIN_PRG_RESET S_AGPIO_L26
+// S_AGPIO_R0 PRG_LED_POWER ON 心率等电源控制脚
+#define GPIO_PIN_PRG_LED_ON S_AGPIO_R0
+
+uint32_t tyhx_poweron(void)
+{
+ uapi_pin_set_mode(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);
+
+ uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_HIGH);
+ LOS_Mdelay(10);
+ return 0;
+}
+uint32_t tyhx_poweroff(void)
+{
+ hal_gh3x2x_afe_int_deinit();
+
+ uapi_pin_set_mode(GPIO_PIN_PRG_RESET, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_RESET, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_RESET, GPIO_LEVEL_LOW);
+
+ uapi_pin_set_mode(GPIO_PIN_PRG_LED_ON, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+ uapi_gpio_set_dir(GPIO_PIN_PRG_LED_ON, GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(GPIO_PIN_PRG_LED_ON, GPIO_LEVEL_LOW);
+ LOS_Mdelay(10);
+ return 0;
+}
+
+void ppg_send_cmd_to_gh3x2x_driver(char* mode, uint8_t enable)
+{
+
+ uint32_t md = 1;
+ if (strcmp(mode, "hrs") == 0) {
+ md = 0;
+ } else if (strcmp(mode, "hrv") == 0) {
+ md = 1;
+ } else if (strcmp(mode, "spo2") == 0) {
+ md = 2;
+ } else if (strcmp(mode, "leaklight") == 0) {
+ md = 4;
+ } else if (strcmp(mode, "graycard") == 0) {
+ md = 8;
+ } else if (strcmp(mode, "ledoff") == 0) {
+ md = 16;
+ } else if (strcmp(mode, "wear") == 0) {
+ md = 32;
+ } else if (strcmp(mode, "single") == 0) {
+ md = 64;
+ }else if (strcmp(mode, "factory") == 0) {
+ md = 128;
+ }else if (strcmp(mode, "fpc") == 0) {
+ // md = WORK_MODE_UNDEFINED;
+ }else if (strcmp(mode, "int") == 0) {
+ }
+
+ if (enable == 1)
+ {
+ // ppg_service_running_stat = true;
+ // uapi_pm_control(PM_APP_WAKE_NEEDED);
+ tyhx_poweron();
+ // GH3X2X_AFE_StartFunction(mode);
+ GH3X2X_AFE_Init();
+ GH3X2X_AFE_StartSampling(1);
+
+ } else {
+
+ // uapi_pm_control(PM_APP_WAKE_NONEED);
+ GH3X2X_AFE_StopSampling();
+ tyhx_poweroff();
+ }
+}
\ No newline at end of file
* @Author: penglei 1624952103@qq.com
* @Date: 2024-03-13 15:08:38
* @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-06-05 15:25:30
+ * @LastEditTime: 2025-06-09 11:37:07
* @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
* @Description:
*
#include "pah800x_main.h"
#endif
+#ifdef PPG_GH3X2X
+#include "gh3x2x_afe_drv.h"
+#endif
+
+
#ifdef SUPPORT_CYWEE_SERVICE
#include "cywee_service.h"
#endif
chip_id = hx3695_chip_check();
#elif defined PPG_PAH8009
chip_id = pah8009_get_chip_id();
+#elif defined PPG_GH3X2X
+ chip_id = GH3X2X_AFE_GetChipId();
#endif
ppg_power_off();
return chip_id;
{
#ifdef PPG_PAH8009
pah8009_int_handler();
+#elif defined PPG_PAH8009
+ hal_gh3x2x_afe_int_handler_call_back();
+ GH3X2X_AFE_ChipPro();
#endif
}
hx3695_control(mode,enable);
#elif defined PPG_PAH8009
pah8009_control(mode,enable);
+#elif defined PPG_GH3X2X
+ gh3x2x_control(mode,enable);
#endif
if(!enable)
ppg_power_off();
* @Author: penglei 1624952103@qq.com
* @Date: 2024-06-07 11:18:26
* @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-06-05 14:46:32
+ * @LastEditTime: 2025-06-09 11:26:55
* @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/ppg/ppg_hal.h
* @Description:
*
#define PPG_CHIP_ID 0x65
#elif defined PPG_PAH8009
#define PPG_CHIP_ID 0x8008
+#elif defined PPG_GH3X2X
+#define PPG_CHIP_ID GH3X2X_CHIP_ID
#else
#define PPG_CHIP_ID 0
#endif
* @Author: penglei 1624952103@qq.com\r
* @Date: 2025-05-27 11:09:04\r
* @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-06-04 15:38:48\r
+ * @LastEditTime: 2025-06-09 14:27:54\r
* @FilePath: /sdk615/code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_bsp.c\r
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
*/\r
#include "custom_utils.h"\r
#include "systick.h"\r
\r
+#ifdef SUPPORT_CYWEE_SERVICE\r
+#include "cywee_hal.h"\r
+#endif\r
+\r
//============================================================================\r
// Definition\r
//============================================================================\r
\r
void ReadGSensor(float *x, float *y, float *z)\r
{\r
- \r
+#ifdef SUPPORT_CYWEE_SERVICE\r
+ gsenson_t data = {0};\r
+ gsensor_get_n_data(1,&data);\r
+ *x = data.x;\r
+ *y = data.y;\r
+ *z = data.z;\r
+#endif\r
}\r
// data = cywee_wear_status;\r
// func(PPG_MSG_TYPE_WEARSTAT_UPDATE, &data, 1);\r
time_cnt = 0;\r
+ hr = 0;\r
}\r
#endif\r
report_hr_data(&ppg_mems_data_alg, ret, hr, hr_grader);\r
//MEMS_SensorZ() absolute data must be largest when let hand horizontal on the table at static state.\r
/***********************G sensor explanation end***********************************/\r
\r
- ppg_mems_data.MEMS_Data[0] = mems_data[0];//ReadGSensorX();\r
- ppg_mems_data.MEMS_Data[1] = mems_data[1];//ReadGSensorY();\r
- ppg_mems_data.MEMS_Data[2] = mems_data[2];//ReadGSensorZ();\r
+ ReadGSensor(&mems_data[0],&mems_data[1],&mems_data[2]);\r
+\r
+ ppg_mems_data.MEMS_Data[0] = mems_data[0] * 2048 / 10;//ReadGSensorX();\r
+ ppg_mems_data.MEMS_Data[1] = mems_data[1] * 2048 / 10;//ReadGSensorY();\r
+ ppg_mems_data.MEMS_Data[2] = mems_data[2] * 2048 / 10;//ReadGSensorZ();\r
+ // printf("x:%f y:%f z:%f\n",ppg_mems_data.MEMS_Data[0],ppg_mems_data.MEMS_Data[1],ppg_mems_data.MEMS_Data[2]);\r
ppg_mems_data.duration = duration;\r
\r
ppg_mems_data.ppg_data = ppg_data ;\r
{ 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
{ 0x4E,0x00 },//R_TouchDetection_Count_Th[4:0]\r
{ 0x4F,0x00 },//R_NoTouchDetection_Count_Th[4:0]\r
+// #ifdef TOUCH_DETECT_TRH_1\r
+// { 0x4C,0x20 },//R_TouchDetection_Th_Low[7:0]\r
+// { 0x4D,0x03 },//R_TouchDetection_Th_Low[13:8] //1800 ir阈值\r
+// #else\r
+// { 0x4C,0x00 },//R_TouchDetection_Th_Low[7:0] //1280 ir阈值\r
+// { 0x4D,0x05 },//R_TouchDetection_Th_Low[13:8]\r
+// #endif\r
{ 0xEB,0x80 },//update_flag\r
};\r
\r
* Select LED Supplier\r
* If Use new Supplier LED , Need to define LED_SUPPLIER_NEW\r
*/\r
-//#define LED_SUPPLIER_NEW\r
+#define LED_SUPPLIER_NEW\r
\r
\r
/*\r
}
}
-#define MIXO_BOARD_TASK_SIZE 0x1000
+#define MIXO_BOARD_TASK_SIZE 0x500
errcode_t uapi_mixo_service_init(void)
{
PRINT("uapi_mixo_service_init !\r\n");
* @Author: penglei 1624952103@qq.com
* @Date: 2024-12-23 15:12:01
* @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-05-14 16:29:38
+ * @LastEditTime: 2025-06-11 17:33:01
* @FilePath: /sdk615/code/sdk/zhihui/drivers/mixo/service/mixo_service.h
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include "pm_veto.h"
uint32_t uapi_cat1_bat_on(uint32_t pwron)
{
-
-#if defined(BOARD_L22)
- pin_t bat_en_pin = S_AGPIO_L14;
-#elif defined(BOARD_W9)
+#if defined(BOARD_W9) || defined(BOARD_N9)
pin_t bat_en_pin = S_AGPIO_L17;
if( pwron == 0)
{
#if defined(BOARD_FD230)
return ( GPIO_LEVEL_HIGH == uapi_gpio_get_output_val(S_AGPIO_L23));
-#elif defined(BOARD_L22)
- return ( GPIO_LEVEL_HIGH == uapi_gpio_get_output_val(S_AGPIO_L14));
-#elif defined(BOARD_W9)
+#elif defined(BOARD_W9) || defined(BOARD_N9)
return ( GPIO_LEVEL_HIGH == uapi_gpio_get_output_val(S_AGPIO_L17));
#endif
#include "custom_save_runtime.h"
#include "ppg_hal.h"
+#ifdef ENABLE_BN02
+#include "bp_service.h"
+#endif
+
errcode_t uapi_create_osThread_custom(app_task_definition_t *task_cfg)
{
if (task_cfg==NULL)
void power_on_cat1(void)
{
- #if defined(FD230) && !defined(BOARD_W9)
+ #if defined(FD230) && !(defined(BOARD_W9) || defined(BOARD_N9))
uapi_cat1_power_on(1);
uapi_cat1_reset(0);
#else
void power_off_cat1(void)
{
- #if defined(FD230) && !defined(BOARD_W9)
+ #if defined(FD230) && !(defined(BOARD_W9) || defined(BOARD_N9))
uapi_cat1_reset(1);
uapi_cat1_power_on(0);
#else
PRINT(" custom_iic_reset done! i2cbus %d clock %d\n",i2cbus,i2c_clock);
}
-errcode_t custom_iic_init(void)
+errcode_t custom_i2c_init(uint8_t bus_index)
{
- errcode_t result;
+ // if(i2c_installed == 1)
+ // return ERRCODE_SUCC;
// #ifdef CONFIG_I2C_SUPPORT_DMA
// #if CONFIG_I2C_SUPPORT_DMA
// #warning CONFIG_I2C_SUPPORT_DMA = 0
// #endif
// #endif
- if(i2c_installed == 0)
- {
- result = uapi_i2c_master_init(I2C_BUS_2, 400000, I2C_SPEED_MODE_FS); /* 400000: 400KHz */
- if (result != ERRCODE_SUCC) {
- PRINT("cywee i2c init fail! ret=0x%x\n", result);
- return ERRCODE_FAIL;
- }
+ errcode_t result = uapi_i2c_master_init(bus_index, 400000, I2C_SPEED_MODE_FS); /* 400000: 400KHz */
- i2c_installed = 1;
- return ERRCODE_SUCC;
- }
- else
+ if (result != ERRCODE_SUCC) {
+ PRINT("cywee i2c init fail! ret=0x%x\n", result);
return ERRCODE_FAIL;
+ }
+
+ // i2c_installed = 1;
+ return ERRCODE_SUCC;
+
+ // else
+ // return ERRCODE_FAIL;
}
errcode_t custom_i2c_read_regs(uint16_t slaveAddr, uint16_t reg, int regLength, uint8_t *readData, int readDataSize, int busIndex)
uint8_t *write_data = NULL;
int16_t write_len = 0;
- //custom_iic_init();
+ //custom_i2c_init();
write_len = regLength + writeDataSize;
write_data = (uint8_t *)osal_kmalloc(write_len, OSAL_GFP_KERNEL);
if (write_data == NULL) {
PM_ID_P_TEST,//产测
PM_ID_BUTTON_GPIO,//gpio按键
PM_ID_4G_AI,//4g AI
+#ifdef ENABLE_BN02
+ PM_ID_BP,//血压
+#endif
PM_ID_MAX,
} pm_id_t;
"PM_ID_P_TEST",
"PM_ID_BUTTON_GPIO",//GPIO按键
"PM_ID_4G_AI",//AI投票
+#ifdef ENABLE_BN02
+ "PM_ID_BP",//血压
+#endif
"PM_ID_MAX"
};
#ifdef CUSTOM_Z1
static constexpr char *ReBootPaths = "/user/res/RebootAndShutDown/ReBoot/"; //开机图片路径
static constexpr int16_t REBOOT_IMAGE_ANIMATOR_VIEW_NUM_FRAMES = 30; // 图片帧数
-#elif BOARD_W9
+#elif defined(BOARD_W9) || defined(BOARD_N9)
static constexpr char *ReBootPaths = "/user/res/RebootAndShutDown/ReBoot/"; //开机图片路径
static constexpr int16_t REBOOT_IMAGE_ANIMATOR_VIEW_NUM_FRAMES = 30; // 图片帧数
#else
#endif
#endif
-#ifdef BOARD_W9
+#if defined(BOARD_W9) || defined(BOARD_N9)
#ifdef IMAGE_OPEN_LOGO_PATH
#undef IMAGE_OPEN_LOGO_PATH
#endif
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new ReBootImageAnimatorView fail");
return false;
}
-#ifdef BOARD_W9
+#if defined(BOARD_W9) || defined(BOARD_N9)
for (int j = 0, i = REBOOT_IMAGE_ANIMATOR_VIEW_NUM_FRAMES - 1;
i > 0 && j < REBOOT_IMAGE_ANIMATOR_VIEW_NUM_FRAMES;
i--, j++)