1 /*
2  * Copyright (c) 2022 Chipsea Technologies (Shenzhen) Corp., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include <securec.h>
10 #include "osal_file.h"
11 #include "hdf_log.h"
12 #include "ppg_cs1262.h"
13 
14 #define PPG_CONFIG_START_MAGIC 0x1262
15 #define HDF_LOG_TAG hdf_sensor_cs1262_fw
16 #define REG_TAB_INDEX_HALF 2
17 
18 static Cs1262RegConfigTab g_heartRegTab = {
19     0x1262,
20     0x0020,
21     {
22         0x0029, 0x473D, 0x003D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
23         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
24         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
25         0x0000, 0x0000, 0x0000, 0x0000
26     },
27     {
28         0x02C2, 0x0040, 0x0080, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
29         0x0000, 0x00FF, 0xFFFF
30     },
31     {
32         0x4224, 0x2224, 0x2222, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
33         0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
34         0x7000, 0x0050, 0x70A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
35         0x7028, 0x0050, 0x70C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
36         0x7028, 0x0028, 0x00A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
37         0x7000, 0x00F0, 0x70A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
38         0x0010, 0x0000, 0x0000, 0x0000, 0x0000
39     },
40     {
41         0x0300, 0x0000, 0x0000, 0x0500, 0x000A, 0x0001, 0x0000, 0x0000, 0x0000, 0x1E0F, 0x0002, 0x0028,
42         0x579E, 0x579E, 0x579E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
43         0x0840, 0x0800, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
44         0x0000, 0x0000
45     },
46     {
47         0x6160, 0x0020, 0x0202, 0x0000, 0x2200, 0x7FFF, 0x00C0, 0x01F4, 0x0000, 0x0000, 0x0000, 0x0000,
48         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
49         0x0000
50     },
51     {
52         0x0429, 0x0000, 0x0064, 0x000A, 0x0002, 0x0882, 0x00DF, 0x0223, 0x0002, 0x0000,
53     },
54     0x00F9
55 };
56 
57 static struct PpgModeTab g_ppgModeTab[] = {
58     { .mode = HEART_RATE_MODE, .regTab = &g_heartRegTab },
59 };
60 
validateTab(uint8_t * regTab,uint16_t valiSize)61 static int32_t validateTab(uint8_t *regTab, uint16_t valiSize)
62 {
63     uint8_t checksum = 0;
64     uint16_t index = 0;
65 
66     if (((uint16_t *)regTab)[0] != PPG_CONFIG_START_MAGIC) {
67         HDF_LOGE("%s: validateTab invalid", __func__);
68         return HDF_FAILURE;
69     }
70 
71     /* real checksum stored in the last 2 bytes, needs to be removed during calculation */
72     for (index = 0; index < valiSize - 2; index++) {
73         checksum += regTab[index];
74     }
75 
76     /* real checksum stored in the last 2 bytes, and one item of regTab has 2 bytes,
77      * needs to be divided by 2 when calculating the real checksum's index.
78      */
79     index = (valiSize / REG_TAB_INDEX_HALF) - 1;
80     return (checksum == ((uint16_t *)regTab)[index]) ? HDF_SUCCESS : HDF_FAILURE;
81 }
82 
Cs1262Loadfw(enum PpgMode mode,Cs1262RegConfigTab ** configTab)83 int32_t Cs1262Loadfw(enum PpgMode mode, Cs1262RegConfigTab **configTab)
84 {
85     int32_t ret;
86 
87     for (uint8_t index = 0; index < HDF_ARRAY_SIZE(g_ppgModeTab); index++) {
88         if (g_ppgModeTab[index].mode == mode) {
89             ret = validateTab((uint8_t *)(g_ppgModeTab[index].regTab), sizeof(*g_ppgModeTab[index].regTab));
90             if (ret != HDF_SUCCESS) {
91                 HDF_LOGE("%s: validateTab fail mode = %d", __func__, mode);
92                 return HDF_FAILURE;
93             }
94             *configTab = g_ppgModeTab[index].regTab;
95             HDF_LOGI("%s: load success", __func__);
96             return HDF_SUCCESS;
97         }
98     }
99     HDF_LOGE("%s: Cs1262Loadfw not match, mode = %d", __func__, mode);
100     return HDF_FAILURE;
101 }
102