HSP Platform firmware evaluating ECG data and hearth rate over PPG data.

Dependencies:   max32630fthr Adafruit_FeatherOLED USBDevice

Committer:
gmehmet
Date:
Wed Apr 10 14:56:25 2019 +0300
Revision:
1:f60eafbf009a
upload from local

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gmehmet 1:f60eafbf009a 1 /*******************************************************************************
gmehmet 1:f60eafbf009a 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
gmehmet 1:f60eafbf009a 3 *
gmehmet 1:f60eafbf009a 4 * Permission is hereby granted, free of charge, to any person obtaining a
gmehmet 1:f60eafbf009a 5 * copy of this software and associated documentation files (the "Software"),
gmehmet 1:f60eafbf009a 6 * to deal in the Software without restriction, including without limitation
gmehmet 1:f60eafbf009a 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
gmehmet 1:f60eafbf009a 8 * and/or sell copies of the Software, and to permit persons to whom the
gmehmet 1:f60eafbf009a 9 * Software is furnished to do so, subject to the following conditions:
gmehmet 1:f60eafbf009a 10 *
gmehmet 1:f60eafbf009a 11 * The above copyright notice and this permission notice shall be included
gmehmet 1:f60eafbf009a 12 * in all copies or substantial portions of the Software.
gmehmet 1:f60eafbf009a 13 *
gmehmet 1:f60eafbf009a 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
gmehmet 1:f60eafbf009a 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
gmehmet 1:f60eafbf009a 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
gmehmet 1:f60eafbf009a 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
gmehmet 1:f60eafbf009a 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
gmehmet 1:f60eafbf009a 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
gmehmet 1:f60eafbf009a 20 * OTHER DEALINGS IN THE SOFTWARE.
gmehmet 1:f60eafbf009a 21 *
gmehmet 1:f60eafbf009a 22 * Except as contained in this notice, the name of Maxim Integrated
gmehmet 1:f60eafbf009a 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
gmehmet 1:f60eafbf009a 24 * Products, Inc. Branding Policy.
gmehmet 1:f60eafbf009a 25 *
gmehmet 1:f60eafbf009a 26 * The mere transfer of this software does not imply any licenses
gmehmet 1:f60eafbf009a 27 * of trade secrets, proprietary technology, copyrights, patents,
gmehmet 1:f60eafbf009a 28 * trademarks, maskwork rights, or any other form of intellectual
gmehmet 1:f60eafbf009a 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
gmehmet 1:f60eafbf009a 30 * ownership rights.
gmehmet 1:f60eafbf009a 31 *******************************************************************************
gmehmet 1:f60eafbf009a 32 */
gmehmet 1:f60eafbf009a 33
gmehmet 1:f60eafbf009a 34 #include "MAX8614X.h"
gmehmet 1:f60eafbf009a 35 #include "PpgComm.h"
gmehmet 1:f60eafbf009a 36 #include "Peripherals.h"
gmehmet 1:f60eafbf009a 37
gmehmet 1:f60eafbf009a 38 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
gmehmet 1:f60eafbf009a 39
gmehmet 1:f60eafbf009a 40 #define MAX8614X_AGC_DEFAULT_LED_OUT_RANGE 50 //AGC Range parameter
gmehmet 1:f60eafbf009a 41 #define MAX8614X_AGC_INCREMENT_MID 15 //AGC Range parameter MID
gmehmet 1:f60eafbf009a 42 #define MAX8614X_AGC_INCREMENT_TOP 15 //AGC Range parameter TOP
gmehmet 1:f60eafbf009a 43
gmehmet 1:f60eafbf009a 44 MAX8614X::MAX8614X(SPI &spiBus, DigitalOut &cs, PinName pin)
gmehmet 1:f60eafbf009a 45 :m_ir(pin), m_spiBus(spiBus), m_cs(cs)
gmehmet 1:f60eafbf009a 46 {
gmehmet 1:f60eafbf009a 47 m_cs = 1;
gmehmet 1:f60eafbf009a 48 kMax8614xDefaultLedOutRange = MAX8614X_AGC_DEFAULT_LED_OUT_RANGE;
gmehmet 1:f60eafbf009a 49
gmehmet 1:f60eafbf009a 50 }
gmehmet 1:f60eafbf009a 51
gmehmet 1:f60eafbf009a 52 int MAX8614X::readRegister(uint8_t reg, uint8_t *data, int len)
gmehmet 1:f60eafbf009a 53 {
gmehmet 1:f60eafbf009a 54 int i = 0;
gmehmet 1:f60eafbf009a 55
gmehmet 1:f60eafbf009a 56 m_cs = 0;
gmehmet 1:f60eafbf009a 57
gmehmet 1:f60eafbf009a 58 m_spiBus.write(reg);
gmehmet 1:f60eafbf009a 59 m_spiBus.write(0x80);
gmehmet 1:f60eafbf009a 60 for(; i < len; i++) { /*TODO: make len unsigned*/
gmehmet 1:f60eafbf009a 61 data[i] = m_spiBus.write(0x00);
gmehmet 1:f60eafbf009a 62 }
gmehmet 1:f60eafbf009a 63
gmehmet 1:f60eafbf009a 64 m_cs = 1;
gmehmet 1:f60eafbf009a 65
gmehmet 1:f60eafbf009a 66 return 0; /*TODO: handle error cases*/
gmehmet 1:f60eafbf009a 67 }
gmehmet 1:f60eafbf009a 68
gmehmet 1:f60eafbf009a 69 int MAX8614X::writeRegister(uint8_t reg, const uint8_t data)
gmehmet 1:f60eafbf009a 70 {
gmehmet 1:f60eafbf009a 71 m_cs = 0;
gmehmet 1:f60eafbf009a 72
gmehmet 1:f60eafbf009a 73 m_spiBus.write(reg);
gmehmet 1:f60eafbf009a 74 m_spiBus.write(0x00);
gmehmet 1:f60eafbf009a 75 m_spiBus.write(data);
gmehmet 1:f60eafbf009a 76
gmehmet 1:f60eafbf009a 77 m_cs = 1;
gmehmet 1:f60eafbf009a 78
gmehmet 1:f60eafbf009a 79 return 0; /*TODO: handle error cases*/
gmehmet 1:f60eafbf009a 80 }
gmehmet 1:f60eafbf009a 81
gmehmet 1:f60eafbf009a 82 int MAX8614X::writeBlock(const RegisterMap reg_block[], unsigned int size)
gmehmet 1:f60eafbf009a 83 {
gmehmet 1:f60eafbf009a 84 unsigned int i;
gmehmet 1:f60eafbf009a 85 int ret = 0;
gmehmet 1:f60eafbf009a 86
gmehmet 1:f60eafbf009a 87 for (i = 0; i < size; i++) {
gmehmet 1:f60eafbf009a 88 ret = writeRegister((Registers) reg_block[i].addr,
gmehmet 1:f60eafbf009a 89 reg_block[i].val);
gmehmet 1:f60eafbf009a 90 if (ret < 0) {
gmehmet 1:f60eafbf009a 91 pr_err("writeRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 92 return ret;
gmehmet 1:f60eafbf009a 93 }
gmehmet 1:f60eafbf009a 94 }
gmehmet 1:f60eafbf009a 95
gmehmet 1:f60eafbf009a 96 return ret;
gmehmet 1:f60eafbf009a 97 }
gmehmet 1:f60eafbf009a 98
gmehmet 1:f60eafbf009a 99 int MAX8614X::get_part_info(uint8_t *part_id, uint8_t *rev_id)
gmehmet 1:f60eafbf009a 100 {
gmehmet 1:f60eafbf009a 101 uint32_t i;
gmehmet 1:f60eafbf009a 102 int ret;
gmehmet 1:f60eafbf009a 103 uint8_t buf[2];
gmehmet 1:f60eafbf009a 104 const uint8_t max8614x_part_ids[] = {
gmehmet 1:f60eafbf009a 105 MAX86140_PART_ID_VAL,
gmehmet 1:f60eafbf009a 106 MAX86141_PART_ID_VAL,
gmehmet 1:f60eafbf009a 107 MAX86142_PART_ID_VAL,
gmehmet 1:f60eafbf009a 108 MAX86143_PART_ID_VAL,
gmehmet 1:f60eafbf009a 109 };
gmehmet 1:f60eafbf009a 110
gmehmet 1:f60eafbf009a 111 ret = readRegister(MAX8614X_REV_ID_REG, buf, 2);
gmehmet 1:f60eafbf009a 112 if (ret < 0) {
gmehmet 1:f60eafbf009a 113 pr_err("readRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 114 return ret;
gmehmet 1:f60eafbf009a 115 }
gmehmet 1:f60eafbf009a 116
gmehmet 1:f60eafbf009a 117 for (i = 0; i < ARRAY_SIZE(max8614x_part_ids); i++) {
gmehmet 1:f60eafbf009a 118 if (buf[1] == max8614x_part_ids[i]) {
gmehmet 1:f60eafbf009a 119 *rev_id = buf[0];
gmehmet 1:f60eafbf009a 120 *part_id = buf[1];
gmehmet 1:f60eafbf009a 121 return 0;
gmehmet 1:f60eafbf009a 122 }
gmehmet 1:f60eafbf009a 123 }
gmehmet 1:f60eafbf009a 124
gmehmet 1:f60eafbf009a 125 // Unsupported part
gmehmet 1:f60eafbf009a 126 return -1;
gmehmet 1:f60eafbf009a 127 }
gmehmet 1:f60eafbf009a 128
gmehmet 1:f60eafbf009a 129 int MAX8614X::get_num_samples_in_fifo()
gmehmet 1:f60eafbf009a 130 {
gmehmet 1:f60eafbf009a 131 int fifo_ovf_cnt;
gmehmet 1:f60eafbf009a 132 uint8_t fifo_data[4];
gmehmet 1:f60eafbf009a 133 uint32_t num_samples;
gmehmet 1:f60eafbf009a 134 int ret;
gmehmet 1:f60eafbf009a 135
gmehmet 1:f60eafbf009a 136 ret = readRegister(MAX8614X_OVF_CNT_REG, fifo_data, 2);
gmehmet 1:f60eafbf009a 137 if (ret < 0) {
gmehmet 1:f60eafbf009a 138 pr_err("readRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 139 return ret;
gmehmet 1:f60eafbf009a 140 }
gmehmet 1:f60eafbf009a 141
gmehmet 1:f60eafbf009a 142 fifo_ovf_cnt = fifo_data[0] & MAX8614X_OVF_CNT_MASK;
gmehmet 1:f60eafbf009a 143 num_samples = fifo_data[1];
gmehmet 1:f60eafbf009a 144
gmehmet 1:f60eafbf009a 145 if (num_samples >= MAX8614X_MAX_FIFO_DEPTH) {
gmehmet 1:f60eafbf009a 146 pr_err("# FIFO is Full. OVF: %d num_samples: %lu",
gmehmet 1:f60eafbf009a 147 fifo_ovf_cnt, num_samples);
gmehmet 1:f60eafbf009a 148 }
gmehmet 1:f60eafbf009a 149
gmehmet 1:f60eafbf009a 150 return num_samples;
gmehmet 1:f60eafbf009a 151 }
gmehmet 1:f60eafbf009a 152
gmehmet 1:f60eafbf009a 153 int MAX8614X::read_fifo_data(uint8_t *fifo_data, int num_samples)
gmehmet 1:f60eafbf009a 154 {
gmehmet 1:f60eafbf009a 155 uint16_t num_bytes = num_samples * MAX8614X_DATA_WORD_SIZE;
gmehmet 1:f60eafbf009a 156 int ret = 0;
gmehmet 1:f60eafbf009a 157
gmehmet 1:f60eafbf009a 158 // const struct RegisterMap test_clk_enable[] = {
gmehmet 1:f60eafbf009a 159 // {0xFF, 0x54},
gmehmet 1:f60eafbf009a 160 // {0xFF, 0x4D},
gmehmet 1:f60eafbf009a 161 // {0x81, 0x20},
gmehmet 1:f60eafbf009a 162 // {0xFF, 0x00}
gmehmet 1:f60eafbf009a 163 // };
gmehmet 1:f60eafbf009a 164 //
gmehmet 1:f60eafbf009a 165 // const struct RegisterMap test_clk_disable[] = {
gmehmet 1:f60eafbf009a 166 // {0xFF, 0x54},
gmehmet 1:f60eafbf009a 167 // {0xFF, 0x4D},
gmehmet 1:f60eafbf009a 168 // {0x81, 0x00},
gmehmet 1:f60eafbf009a 169 // {0xFF, 0x00}
gmehmet 1:f60eafbf009a 170 // };
gmehmet 1:f60eafbf009a 171
gmehmet 1:f60eafbf009a 172 // ret = writeBlock(test_clk_enable, ARRAY_SIZE(test_clk_enable));
gmehmet 1:f60eafbf009a 173 // if (ret < 0) {
gmehmet 1:f60eafbf009a 174 // pr_err("writeBlock failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 175 // return ret;
gmehmet 1:f60eafbf009a 176 // }
gmehmet 1:f60eafbf009a 177
gmehmet 1:f60eafbf009a 178 fifo_data[0] = MAX8614X_FIFO_DATA_REG;
gmehmet 1:f60eafbf009a 179 ret = readRegister(MAX8614X_FIFO_DATA_REG, fifo_data, num_bytes);
gmehmet 1:f60eafbf009a 180 if (ret < 0) {
gmehmet 1:f60eafbf009a 181 pr_err("readRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 182 return ret;
gmehmet 1:f60eafbf009a 183 }
gmehmet 1:f60eafbf009a 184
gmehmet 1:f60eafbf009a 185 // ret = writeBlock(test_clk_disable, ARRAY_SIZE(test_clk_disable));
gmehmet 1:f60eafbf009a 186 // if (ret < 0) {
gmehmet 1:f60eafbf009a 187 // pr_err("writeBlock failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 188 // return ret;
gmehmet 1:f60eafbf009a 189 // }
gmehmet 1:f60eafbf009a 190
gmehmet 1:f60eafbf009a 191 return ret;
gmehmet 1:f60eafbf009a 192 }
gmehmet 1:f60eafbf009a 193
gmehmet 1:f60eafbf009a 194 void MAX8614X::irq()
gmehmet 1:f60eafbf009a 195 {
gmehmet 1:f60eafbf009a 196 irq_triggered = true;
gmehmet 1:f60eafbf009a 197 }
gmehmet 1:f60eafbf009a 198
gmehmet 1:f60eafbf009a 199 int MAX8614X::irq_handler()
gmehmet 1:f60eafbf009a 200 {
gmehmet 1:f60eafbf009a 201 int ret;
gmehmet 1:f60eafbf009a 202 int_status_t status;
gmehmet 1:f60eafbf009a 203 irq_triggered = false;
gmehmet 1:f60eafbf009a 204
gmehmet 1:f60eafbf009a 205 ret = readRegister(MAX8614X_INT_STATUS1_REG, status.val, 2);
gmehmet 1:f60eafbf009a 206 if (ret < 0) {
gmehmet 1:f60eafbf009a 207 pr_err("readRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 208 return -1;
gmehmet 1:f60eafbf009a 209 }
gmehmet 1:f60eafbf009a 210 pr_debug("Status reg: %X %X", status.val[0], status.val[1]);
gmehmet 1:f60eafbf009a 211
gmehmet 1:f60eafbf009a 212 if (status.a_full || status.data_rdy) {
gmehmet 1:f60eafbf009a 213 fifo_irq_handler();
gmehmet 1:f60eafbf009a 214 }
gmehmet 1:f60eafbf009a 215
gmehmet 1:f60eafbf009a 216 if (status.die_temp_rdy) {
gmehmet 1:f60eafbf009a 217 pr_debug("Pwr_rdy interrupt was triggered.");
gmehmet 1:f60eafbf009a 218 }
gmehmet 1:f60eafbf009a 219
gmehmet 1:f60eafbf009a 220 if (status.pwr_rdy) {
gmehmet 1:f60eafbf009a 221 pr_info("Pwr_rdy interrupt was triggered.");
gmehmet 1:f60eafbf009a 222 }
gmehmet 1:f60eafbf009a 223
gmehmet 1:f60eafbf009a 224 if (status.die_temp_rdy) {
gmehmet 1:f60eafbf009a 225 read_die_temp();
gmehmet 1:f60eafbf009a 226 }
gmehmet 1:f60eafbf009a 227
gmehmet 1:f60eafbf009a 228 if (status.vdd_oor) {
gmehmet 1:f60eafbf009a 229 vdd_oor_cnt++;
gmehmet 1:f60eafbf009a 230 pr_info("VDD Out of range cnt: %d", vdd_oor_cnt);
gmehmet 1:f60eafbf009a 231 }
gmehmet 1:f60eafbf009a 232 return 0;
gmehmet 1:f60eafbf009a 233 }
gmehmet 1:f60eafbf009a 234
gmehmet 1:f60eafbf009a 235 int MAX8614X::fifo_irq_handler()
gmehmet 1:f60eafbf009a 236 {
gmehmet 1:f60eafbf009a 237 uint8_t fifo_buf[MAX8614X_MAX_FIFO_DEPTH * MAX8614X_DATA_WORD_SIZE] = {0};
gmehmet 1:f60eafbf009a 238 int ret;
gmehmet 1:f60eafbf009a 239 int num_samples = 0;
gmehmet 1:f60eafbf009a 240 static int last_samples[DATA_TYPE_PPG2_LEDC4];
gmehmet 1:f60eafbf009a 241 fifo_data_t fifo_data;
gmehmet 1:f60eafbf009a 242 uint16_t idx;
gmehmet 1:f60eafbf009a 243 int i;
gmehmet 1:f60eafbf009a 244 static ppg_data_t ppg_data;
gmehmet 1:f60eafbf009a 245 static uint32_t ppg_data_ack = 0;
gmehmet 1:f60eafbf009a 246 const uint32_t ir_green_red_ppg_type = ((1 << DATA_TYPE_PPG1_LEDC1) |
gmehmet 1:f60eafbf009a 247 (1 << DATA_TYPE_PPG1_LEDC2) |
gmehmet 1:f60eafbf009a 248 (1 << DATA_TYPE_PPG1_LEDC3));
gmehmet 1:f60eafbf009a 249
gmehmet 1:f60eafbf009a 250 num_samples = get_num_samples_in_fifo();
gmehmet 1:f60eafbf009a 251 if (num_samples <= 0) {
gmehmet 1:f60eafbf009a 252 pr_err("get_num_samples_in_fifo failed. err: %d", num_samples);
gmehmet 1:f60eafbf009a 253 return -1;
gmehmet 1:f60eafbf009a 254 }
gmehmet 1:f60eafbf009a 255
gmehmet 1:f60eafbf009a 256 pr_debug("num_samples: %d", num_samples);
gmehmet 1:f60eafbf009a 257
gmehmet 1:f60eafbf009a 258 ret = read_fifo_data(fifo_buf, num_samples);
gmehmet 1:f60eafbf009a 259 if (ret < 0) {
gmehmet 1:f60eafbf009a 260 pr_err("read_fifo_data failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 261 return -1;
gmehmet 1:f60eafbf009a 262 }
gmehmet 1:f60eafbf009a 263
gmehmet 1:f60eafbf009a 264 for (i = 0; i < num_samples; i++) {
gmehmet 1:f60eafbf009a 265 idx = MAX8614X_DATA_WORD_SIZE * i;
gmehmet 1:f60eafbf009a 266 fifo_data.raw = fifo_buf[idx + 0] << 16
gmehmet 1:f60eafbf009a 267 | fifo_buf[idx + 1] << 8
gmehmet 1:f60eafbf009a 268 | fifo_buf[idx + 2];
gmehmet 1:f60eafbf009a 269 if (fifo_data.type == DATA_TYPE_INVALID_DATA || fifo_data.type == 0) {
gmehmet 1:f60eafbf009a 270 pr_err("Received invalid data. data: %X, i: %d",
gmehmet 1:f60eafbf009a 271 (unsigned int)fifo_data.raw, i);
gmehmet 1:f60eafbf009a 272
gmehmet 1:f60eafbf009a 273 continue;
gmehmet 1:f60eafbf009a 274 }
gmehmet 1:f60eafbf009a 275 pr_debug("\ttype: %lu, val: %lu (%lX)",
gmehmet 1:f60eafbf009a 276 fifo_data.type, fifo_data.val, fifo_data.val);
gmehmet 1:f60eafbf009a 277
gmehmet 1:f60eafbf009a 278 if (fifo_data.type > DATA_TYPE_PPG2_LEDC3) {
gmehmet 1:f60eafbf009a 279 pr_err("Wrong Data Type: -> Type: %lu, val:%lu, Raw:%lu",
gmehmet 1:f60eafbf009a 280 fifo_data.type, fifo_data.val, fifo_data.raw);
gmehmet 1:f60eafbf009a 281 continue;
gmehmet 1:f60eafbf009a 282 }
gmehmet 1:f60eafbf009a 283
gmehmet 1:f60eafbf009a 284 if (fifo_data.type > 0 && fifo_data.type < DATA_TYPE_PPG2_LEDC3) {
gmehmet 1:f60eafbf009a 285 last_samples[fifo_data.type] = fifo_data.val;
gmehmet 1:f60eafbf009a 286 }
gmehmet 1:f60eafbf009a 287
gmehmet 1:f60eafbf009a 288 if (fifo_data.type == DATA_TYPE_PPG1_LEDC1) {
gmehmet 1:f60eafbf009a 289 max8614x_agc_handler(&led_ctrl, last_samples);
gmehmet 1:f60eafbf009a 290 }
gmehmet 1:f60eafbf009a 291
gmehmet 1:f60eafbf009a 292 if (fifo_data.type == DATA_TYPE_PPG1_LEDC1) {
gmehmet 1:f60eafbf009a 293 ppg_data.ir = fifo_data.val;
gmehmet 1:f60eafbf009a 294 } else if (fifo_data.type == DATA_TYPE_PPG1_LEDC2) {
gmehmet 1:f60eafbf009a 295 ppg_data.red = fifo_data.val;
gmehmet 1:f60eafbf009a 296 } else if (fifo_data.type == DATA_TYPE_PPG1_LEDC3) {
gmehmet 1:f60eafbf009a 297 ppg_data.green = fifo_data.val;
gmehmet 1:f60eafbf009a 298 }
gmehmet 1:f60eafbf009a 299
gmehmet 1:f60eafbf009a 300 ppg_data_ack |= 1 << fifo_data.type;
gmehmet 1:f60eafbf009a 301
gmehmet 1:f60eafbf009a 302 if ((ppg_data_ack & ir_green_red_ppg_type) != ir_green_red_ppg_type ){
gmehmet 1:f60eafbf009a 303 continue;
gmehmet 1:f60eafbf009a 304 }
gmehmet 1:f60eafbf009a 305 ppg_data_ack = 0;
gmehmet 1:f60eafbf009a 306
gmehmet 1:f60eafbf009a 307 if (ppg_queue.size() >= MAX8614X_COMMON_QUEUE_SIZE) {
gmehmet 1:f60eafbf009a 308 pr_err("ppg_queue is full.");
gmehmet 1:f60eafbf009a 309 } else {
gmehmet 1:f60eafbf009a 310 ppg_queue.push(ppg_data);
gmehmet 1:f60eafbf009a 311 }
gmehmet 1:f60eafbf009a 312 }
gmehmet 1:f60eafbf009a 313 return 0;
gmehmet 1:f60eafbf009a 314 }
gmehmet 1:f60eafbf009a 315
gmehmet 1:f60eafbf009a 316 int MAX8614X::get_sensor_report(ppg_sensor_report &sensor_report)
gmehmet 1:f60eafbf009a 317 {
gmehmet 1:f60eafbf009a 318 int32_t ret;
gmehmet 1:f60eafbf009a 319 uint32_t irleddata, redleddata, greenleddata;
gmehmet 1:f60eafbf009a 320 //TODO: Implement
gmehmet 1:f60eafbf009a 321 ret = dequeue_from_fifo_queue(&irleddata, &redleddata, &greenleddata);
gmehmet 1:f60eafbf009a 322 if(ret == RTN_NO_ERROR){
gmehmet 1:f60eafbf009a 323 sensor_report.grn = irleddata;
gmehmet 1:f60eafbf009a 324 sensor_report.grn2 = redleddata;
gmehmet 1:f60eafbf009a 325 }else{
gmehmet 1:f60eafbf009a 326 return -1;
gmehmet 1:f60eafbf009a 327 }
gmehmet 1:f60eafbf009a 328 return 0;
gmehmet 1:f60eafbf009a 329 }
gmehmet 1:f60eafbf009a 330
gmehmet 1:f60eafbf009a 331 int MAX8614X::enable_die_temp()
gmehmet 1:f60eafbf009a 332 {
gmehmet 1:f60eafbf009a 333 int ret = 0;
gmehmet 1:f60eafbf009a 334
gmehmet 1:f60eafbf009a 335 ret = writeRegister(MAX8614X_DIE_TEMP_CFG_REG, MAX8614X_DIE_TEMP_EN);
gmehmet 1:f60eafbf009a 336 if (ret < 0) {
gmehmet 1:f60eafbf009a 337 pr_err("SPI Communication error");
gmehmet 1:f60eafbf009a 338 }
gmehmet 1:f60eafbf009a 339
gmehmet 1:f60eafbf009a 340 return ret;
gmehmet 1:f60eafbf009a 341 }
gmehmet 1:f60eafbf009a 342
gmehmet 1:f60eafbf009a 343 int MAX8614X::read_die_temp()
gmehmet 1:f60eafbf009a 344 {
gmehmet 1:f60eafbf009a 345 int ret = 0;
gmehmet 1:f60eafbf009a 346 uint8_t buf[2];
gmehmet 1:f60eafbf009a 347
gmehmet 1:f60eafbf009a 348 ret = readRegister(MAX8614X_DIE_TEMP_INT_REG, buf, 2);
gmehmet 1:f60eafbf009a 349 if (ret < 0) {
gmehmet 1:f60eafbf009a 350 pr_err("Unable to read die_temp. ret: %d", ret);
gmehmet 1:f60eafbf009a 351 return ret;
gmehmet 1:f60eafbf009a 352 }
gmehmet 1:f60eafbf009a 353
gmehmet 1:f60eafbf009a 354 die_temp.frac = (uint8_t)buf[1] & MAX8614X_DIE_TEMP_FRAC_MASK;
gmehmet 1:f60eafbf009a 355 die_temp.tint = (uint8_t)buf[0];
gmehmet 1:f60eafbf009a 356
gmehmet 1:f60eafbf009a 357 pr_debug("Die temp: %d - %d, %d", die_temp.val, buf[0], buf[1]);
gmehmet 1:f60eafbf009a 358 return enable_die_temp();
gmehmet 1:f60eafbf009a 359 }
gmehmet 1:f60eafbf009a 360
gmehmet 1:f60eafbf009a 361 int MAX8614X::reset()
gmehmet 1:f60eafbf009a 362 {
gmehmet 1:f60eafbf009a 363 int ret = 0;
gmehmet 1:f60eafbf009a 364
gmehmet 1:f60eafbf009a 365 ret = writeRegister(MAX8614X_SYSTEM_CTRL_REG,
gmehmet 1:f60eafbf009a 366 MAX8614X_SYSTEM_RESET_MASK);
gmehmet 1:f60eafbf009a 367 if (ret < 0) {
gmehmet 1:f60eafbf009a 368 pr_err("writeRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 369 return ret;
gmehmet 1:f60eafbf009a 370 }
gmehmet 1:f60eafbf009a 371
gmehmet 1:f60eafbf009a 372 /* Reset ppg_queue */
gmehmet 1:f60eafbf009a 373 std::queue<ppg_data_t> empty_queue;
gmehmet 1:f60eafbf009a 374 std::swap(ppg_queue, empty_queue);
gmehmet 1:f60eafbf009a 375
gmehmet 1:f60eafbf009a 376 led_control_reset(&led_ctrl);
gmehmet 1:f60eafbf009a 377
gmehmet 1:f60eafbf009a 378 return ret;
gmehmet 1:f60eafbf009a 379 }
gmehmet 1:f60eafbf009a 380
gmehmet 1:f60eafbf009a 381 int MAX8614X::poweroff()
gmehmet 1:f60eafbf009a 382 {
gmehmet 1:f60eafbf009a 383 int ret = 0;
gmehmet 1:f60eafbf009a 384
gmehmet 1:f60eafbf009a 385 ret = writeRegister(MAX8614X_SYSTEM_CTRL_REG,
gmehmet 1:f60eafbf009a 386 MAX8614X_SYSTEM_SHDN_MASK);
gmehmet 1:f60eafbf009a 387 if (ret < 0) {
gmehmet 1:f60eafbf009a 388 pr_err("writeRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 389 return ret;
gmehmet 1:f60eafbf009a 390 }
gmehmet 1:f60eafbf009a 391
gmehmet 1:f60eafbf009a 392 return ret;
gmehmet 1:f60eafbf009a 393 }
gmehmet 1:f60eafbf009a 394
gmehmet 1:f60eafbf009a 395 int MAX8614X::init()
gmehmet 1:f60eafbf009a 396 {
gmehmet 1:f60eafbf009a 397 int ret = RTN_NO_ERROR;
gmehmet 1:f60eafbf009a 398 uint8_t part_id, rev_id;
gmehmet 1:f60eafbf009a 399
gmehmet 1:f60eafbf009a 400 ret = get_part_info(&part_id, &rev_id);
gmehmet 1:f60eafbf009a 401 if (ret < 0) {
gmehmet 1:f60eafbf009a 402 pr_err("MAX8614X is not detected. Part_id: 0x%X, Rev_Id: 0x%X",
gmehmet 1:f60eafbf009a 403 part_id, rev_id);
gmehmet 1:f60eafbf009a 404 ret = RTN_ERR_NOT_8614x;
gmehmet 1:f60eafbf009a 405 goto fail;
gmehmet 1:f60eafbf009a 406 }
gmehmet 1:f60eafbf009a 407 pr_info("MAX8614X detected. Part_id: 0x%X, Rev_Id: 0x%X", part_id, rev_id);
gmehmet 1:f60eafbf009a 408
gmehmet 1:f60eafbf009a 409 ret = writeRegister(MAX8614X_SYSTEM_CTRL_REG,
gmehmet 1:f60eafbf009a 410 MAX8614X_SYSTEM_RESET_MASK);
gmehmet 1:f60eafbf009a 411 if (ret < 0) {
gmehmet 1:f60eafbf009a 412 pr_err("writeRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 413 goto fail;
gmehmet 1:f60eafbf009a 414 }
gmehmet 1:f60eafbf009a 415
gmehmet 1:f60eafbf009a 416 die_temp.frac = 0;
gmehmet 1:f60eafbf009a 417 die_temp.tint = 0;
gmehmet 1:f60eafbf009a 418
gmehmet 1:f60eafbf009a 419 led_control_init(&led_ctrl); /*TODO: after porting agc, test */
gmehmet 1:f60eafbf009a 420
gmehmet 1:f60eafbf009a 421 irq_triggered = false;
gmehmet 1:f60eafbf009a 422 m_ir.fall(Callback<void()>(this, &MAX8614X::irq));
gmehmet 1:f60eafbf009a 423
gmehmet 1:f60eafbf009a 424 return ret;
gmehmet 1:f60eafbf009a 425 fail:
gmehmet 1:f60eafbf009a 426 pr_err("Init failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 427 return ret;
gmehmet 1:f60eafbf009a 428 }
gmehmet 1:f60eafbf009a 429
gmehmet 1:f60eafbf009a 430 int MAX8614X::sensor_enable(int enable)
gmehmet 1:f60eafbf009a 431 {
gmehmet 1:f60eafbf009a 432 int ret = RTN_NO_ERROR;
gmehmet 1:f60eafbf009a 433 uint8_t led_seq[3];
gmehmet 1:f60eafbf009a 434
gmehmet 1:f60eafbf009a 435 RegisterMap_t ppg_init_cfg[] = {
gmehmet 1:f60eafbf009a 436 { MAX8614X_SYSTEM_CTRL_REG, MAX8614X_SYSTEM_RESET_MASK},
gmehmet 1:f60eafbf009a 437 { MAX8614X_PPG_CFG1_REG, MAX8614X_PPG_LED_PW_115_2_US_MASK // PPG_LED_PW = 3 (115.2us)
gmehmet 1:f60eafbf009a 438 | MAX8614X_PPG1_ADC_RGE_32768_MASK // PPG1_ADC_RGE = 3(32768nA)
gmehmet 1:f60eafbf009a 439 | MAX8614X_PPG2_ADC_RGE_32768_MASK }, // PPG2_ADC_RGE = 3(32768nA)
gmehmet 1:f60eafbf009a 440 { MAX8614X_PPG_CFG2_REG, MAX8614X_PPG_SR_25_SPS},
gmehmet 1:f60eafbf009a 441 { MAX8614X_LED_SEQ1_REG, 0x24},
gmehmet 1:f60eafbf009a 442 { MAX8614X_LED_SEQ2_REG, 0x03},
gmehmet 1:f60eafbf009a 443 { MAX8614X_LED1_PA_REG, 0x80},
gmehmet 1:f60eafbf009a 444 { MAX8614X_LED2_PA_REG, 0x80},
gmehmet 1:f60eafbf009a 445 { MAX8614X_LED3_PA_REG, 0x00},
gmehmet 1:f60eafbf009a 446 { MAX8614X_LED_RANGE1_REG, MAX8614X_LED1_RGE_25mA_MASK
gmehmet 1:f60eafbf009a 447 | MAX8614X_LED2_RGE_25mA_MASK
gmehmet 1:f60eafbf009a 448 | MAX8614X_LED3_RGE_25mA_MASK},
gmehmet 1:f60eafbf009a 449 { MAX8614X_FIFO_CFG1_REG, MAX8614X_INT1_EN_DATA_RDY_MASK},
gmehmet 1:f60eafbf009a 450 // 24 (ir+r+g) samples in fifo, size is 128/3=42
gmehmet 1:f60eafbf009a 451 { MAX8614X_FIFO_CFG2_REG, MAX8614X_FLUSH_FIFO_MASK
gmehmet 1:f60eafbf009a 452 | MAX8614X_FIFO_STAT_CLR_MASK
gmehmet 1:f60eafbf009a 453 | MAX8614X_A_FULL_TYPE_MASK // Try 0
gmehmet 1:f60eafbf009a 454 | MAX8614X_FIFO_RO_MASK
gmehmet 1:f60eafbf009a 455 | MAX8614X_FIFO_EN_MASK},
gmehmet 1:f60eafbf009a 456 { MAX8614X_INT_ENABLE1_REG, MAX8614X_INT1_EN_A_FULL_MASK
gmehmet 1:f60eafbf009a 457 | MAX8614X_INT1_EN_DIE_TEMP_MASK
gmehmet 1:f60eafbf009a 458 | MAX8614X_INT1_EN_VDD_OOR_MASK},
gmehmet 1:f60eafbf009a 459 };
gmehmet 1:f60eafbf009a 460
gmehmet 1:f60eafbf009a 461 if (enable) {
gmehmet 1:f60eafbf009a 462 /* Read current sequence settings, and check what modes are open */
gmehmet 1:f60eafbf009a 463 led_seq[0] = MAX8614X_LED_SEQ1_REG;
gmehmet 1:f60eafbf009a 464 ret |= readRegister(MAX8614X_LED_SEQ1_REG, led_seq, 3);
gmehmet 1:f60eafbf009a 465 if (ret < 0) {
gmehmet 1:f60eafbf009a 466 pr_err("readRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 467 return ret;
gmehmet 1:f60eafbf009a 468 }
gmehmet 1:f60eafbf009a 469
gmehmet 1:f60eafbf009a 470 pr_debug("0-Sequence registers: %X %X %X", led_seq[0], led_seq[1], led_seq[2]);
gmehmet 1:f60eafbf009a 471 ret |= writeBlock(ppg_init_cfg, ARRAY_SIZE(ppg_init_cfg));
gmehmet 1:f60eafbf009a 472 led_seq[0] = MAX8614X_INT_STATUS1_REG;
gmehmet 1:f60eafbf009a 473 ret |= readRegister(MAX8614X_INT_STATUS1_REG, led_seq, 3); // Mert: the len was 3 ?!
gmehmet 1:f60eafbf009a 474 pr_debug("1-Sequence registers: %X %X %X", led_seq[0], led_seq[1], led_seq[2]);
gmehmet 1:f60eafbf009a 475 if (ret < 0) {
gmehmet 1:f60eafbf009a 476 pr_err("readRegister failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 477 return ret;
gmehmet 1:f60eafbf009a 478 }
gmehmet 1:f60eafbf009a 479 agc_enable(1);
gmehmet 1:f60eafbf009a 480 pr_debug("Wrote register settings. ret: %d", ret);
gmehmet 1:f60eafbf009a 481 } else {
gmehmet 1:f60eafbf009a 482 ret = reset();
gmehmet 1:f60eafbf009a 483 if (ret < 0) {
gmehmet 1:f60eafbf009a 484 pr_err("reset failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 485 return ret;
gmehmet 1:f60eafbf009a 486 }
gmehmet 1:f60eafbf009a 487
gmehmet 1:f60eafbf009a 488 ret = poweroff();
gmehmet 1:f60eafbf009a 489 if (ret < 0) {
gmehmet 1:f60eafbf009a 490 pr_err("poweroff failed. ret: %d", ret);
gmehmet 1:f60eafbf009a 491 return ret;
gmehmet 1:f60eafbf009a 492 }
gmehmet 1:f60eafbf009a 493 }
gmehmet 1:f60eafbf009a 494
gmehmet 1:f60eafbf009a 495 return RTN_NO_ERROR;
gmehmet 1:f60eafbf009a 496 }
gmehmet 1:f60eafbf009a 497
gmehmet 1:f60eafbf009a 498 int MAX8614X::agc_enable(int agc_enable)
gmehmet 1:f60eafbf009a 499 {
gmehmet 1:f60eafbf009a 500 int ret = RTN_NO_ERROR;
gmehmet 1:f60eafbf009a 501 led_ctrl.agc_is_enabled = !!agc_enable;
gmehmet 1:f60eafbf009a 502 led_ctrl.lpm_is_enabled = !!agc_enable;
gmehmet 1:f60eafbf009a 503 ret = led_prox_init(&led_ctrl, led_ctrl.lpm_is_enabled);
gmehmet 1:f60eafbf009a 504 return ret;
gmehmet 1:f60eafbf009a 505 }
gmehmet 1:f60eafbf009a 506
gmehmet 1:f60eafbf009a 507 int MAX8614X::dequeue_from_fifo_queue(uint32_t *ir, uint32_t *red, uint32_t *green)
gmehmet 1:f60eafbf009a 508 {
gmehmet 1:f60eafbf009a 509 ppg_data_t ppg_data;
gmehmet 1:f60eafbf009a 510
gmehmet 1:f60eafbf009a 511 if (irq_triggered) {
gmehmet 1:f60eafbf009a 512 irq_handler();
gmehmet 1:f60eafbf009a 513 }
gmehmet 1:f60eafbf009a 514
gmehmet 1:f60eafbf009a 515 if (ppg_queue.size() <= 0) {
gmehmet 1:f60eafbf009a 516 return RTN_ERR_QUEUE_EMPTY;
gmehmet 1:f60eafbf009a 517 }
gmehmet 1:f60eafbf009a 518 ppg_data = ppg_queue.front();
gmehmet 1:f60eafbf009a 519 ppg_queue.pop();
gmehmet 1:f60eafbf009a 520
gmehmet 1:f60eafbf009a 521 pr_debug("%lu %lu %lu", ppg_data.ir, ppg_data.red, ppg_data.green);
gmehmet 1:f60eafbf009a 522
gmehmet 1:f60eafbf009a 523 *ir = ppg_data.ir;
gmehmet 1:f60eafbf009a 524 *red = ppg_data.red;
gmehmet 1:f60eafbf009a 525 *green = ppg_data.green;
gmehmet 1:f60eafbf009a 526
gmehmet 1:f60eafbf009a 527 return RTN_NO_ERROR;
gmehmet 1:f60eafbf009a 528 }
gmehmet 1:f60eafbf009a 529 // total number of registers to print are 57
gmehmet 1:f60eafbf009a 530 int MAX8614X::dump_registers(addr_val_pair *reg_vals)
gmehmet 1:f60eafbf009a 531 {
gmehmet 1:f60eafbf009a 532 int i, j = 0;
gmehmet 1:f60eafbf009a 533 int ret = 0;
gmehmet 1:f60eafbf009a 534 uint8_t val;
gmehmet 1:f60eafbf009a 535 // read 23 registers
gmehmet 1:f60eafbf009a 536 for (i = 0x00; i <= 0x16; i++, j++) {
gmehmet 1:f60eafbf009a 537 reg_vals[j].addr = i;
gmehmet 1:f60eafbf009a 538 ret |= readRegister(i, &val, 1);
gmehmet 1:f60eafbf009a 539 reg_vals[j].val = val;
gmehmet 1:f60eafbf009a 540 }
gmehmet 1:f60eafbf009a 541 // read 24 registers
gmehmet 1:f60eafbf009a 542 for (i = 0x20; i <= 0x37; i++, j++) {
gmehmet 1:f60eafbf009a 543 reg_vals[j].addr = i;
gmehmet 1:f60eafbf009a 544 ret |= readRegister(i, &val, 1);
gmehmet 1:f60eafbf009a 545 reg_vals[j].val = val;
gmehmet 1:f60eafbf009a 546 }
gmehmet 1:f60eafbf009a 547 // read 3 registers
gmehmet 1:f60eafbf009a 548 for (i = 0x40; i <= 0x42; i++, j++) {
gmehmet 1:f60eafbf009a 549 reg_vals[j].addr = i;
gmehmet 1:f60eafbf009a 550 ret |= readRegister(i, &val, 1);
gmehmet 1:f60eafbf009a 551 reg_vals[j].val = val;
gmehmet 1:f60eafbf009a 552 }
gmehmet 1:f60eafbf009a 553 // read 5 registers
gmehmet 1:f60eafbf009a 554 for (i = 0xF0; i <= 0xF4; i++, j++) {
gmehmet 1:f60eafbf009a 555 reg_vals[j].addr = i;
gmehmet 1:f60eafbf009a 556 ret |= readRegister(i, &val, 1);
gmehmet 1:f60eafbf009a 557 reg_vals[j].val = val;
gmehmet 1:f60eafbf009a 558 }
gmehmet 1:f60eafbf009a 559 // read 2 registers
gmehmet 1:f60eafbf009a 560 for (i = 0xFE; i <= 0xFF; i++, j++) {
gmehmet 1:f60eafbf009a 561 reg_vals[j].addr = i;
gmehmet 1:f60eafbf009a 562 ret |= readRegister(i, &val, 1);
gmehmet 1:f60eafbf009a 563 reg_vals[j].val = val;
gmehmet 1:f60eafbf009a 564 }
gmehmet 1:f60eafbf009a 565 return ret;
gmehmet 1:f60eafbf009a 566 }
gmehmet 1:f60eafbf009a 567
gmehmet 1:f60eafbf009a 568 const char * MAX8614X::get_sensor_part_name()
gmehmet 1:f60eafbf009a 569 {
gmehmet 1:f60eafbf009a 570 #if 1
gmehmet 1:f60eafbf009a 571 /* For sensor studio */
gmehmet 1:f60eafbf009a 572 return "max86141";
gmehmet 1:f60eafbf009a 573 #else
gmehmet 1:f60eafbf009a 574 uint8_t part_id, rev_id;
gmehmet 1:f60eafbf009a 575
gmehmet 1:f60eafbf009a 576 get_part_info(&part_id, &rev_id);
gmehmet 1:f60eafbf009a 577
gmehmet 1:f60eafbf009a 578 switch (part_id) {
gmehmet 1:f60eafbf009a 579 case MAX86140_PART_ID_VAL:
gmehmet 1:f60eafbf009a 580 return "max86140";
gmehmet 1:f60eafbf009a 581 case MAX86141_PART_ID_VAL:
gmehmet 1:f60eafbf009a 582 return "max86141";
gmehmet 1:f60eafbf009a 583 case MAX86142_PART_ID_VAL:
gmehmet 1:f60eafbf009a 584 return "max86142";
gmehmet 1:f60eafbf009a 585 case MAX86143_PART_ID_VAL:
gmehmet 1:f60eafbf009a 586 return "max86143";
gmehmet 1:f60eafbf009a 587 }
gmehmet 1:f60eafbf009a 588 return "unknown";
gmehmet 1:f60eafbf009a 589 #endif
gmehmet 1:f60eafbf009a 590 }
gmehmet 1:f60eafbf009a 591
gmehmet 1:f60eafbf009a 592 const char * MAX8614X::get_sensor_name()
gmehmet 1:f60eafbf009a 593 {
gmehmet 1:f60eafbf009a 594 return "ppg";
gmehmet 1:f60eafbf009a 595 }
gmehmet 1:f60eafbf009a 596
gmehmet 1:f60eafbf009a 597 const char * MAX8614X::get_sensor_algo_ver()
gmehmet 1:f60eafbf009a 598 {
gmehmet 1:f60eafbf009a 599 return "dummy_algo_ver";
gmehmet 1:f60eafbf009a 600 }
gmehmet 1:f60eafbf009a 601
gmehmet 1:f60eafbf009a 602
gmehmet 1:f60eafbf009a 603 //@brief Get status of the sensor: if PROX mode return true
gmehmet 1:f60eafbf009a 604 unsigned char MAX8614X::is_sensor_in_daq_mode(){
gmehmet 1:f60eafbf009a 605 return (led_ctrl.state == LED_DATA_ACQ);
gmehmet 1:f60eafbf009a 606 }
gmehmet 1:f60eafbf009a 607
gmehmet 1:f60eafbf009a 608 //@brief set agc range
gmehmet 1:f60eafbf009a 609 void MAX8614X::set_agc_range(enum Max8614x_Agc_Range RangeLevel){
gmehmet 1:f60eafbf009a 610
gmehmet 1:f60eafbf009a 611 if(RangeLevel == kRangeHigh)
gmehmet 1:f60eafbf009a 612 kMax8614xDefaultLedOutRange = MAX8614X_AGC_DEFAULT_LED_OUT_RANGE + MAX8614X_AGC_INCREMENT_TOP;
gmehmet 1:f60eafbf009a 613 else if(RangeLevel == kRangeMid)
gmehmet 1:f60eafbf009a 614 kMax8614xDefaultLedOutRange = MAX8614X_AGC_DEFAULT_LED_OUT_RANGE + MAX8614X_AGC_INCREMENT_MID;
gmehmet 1:f60eafbf009a 615 else
gmehmet 1:f60eafbf009a 616 kMax8614xDefaultLedOutRange= MAX8614X_AGC_DEFAULT_LED_OUT_RANGE;
gmehmet 1:f60eafbf009a 617
gmehmet 1:f60eafbf009a 618 // printf("Set agc range as: %d\r\n", kMax8614xDefaultLedOutRange);
gmehmet 1:f60eafbf009a 619 }
gmehmet 1:f60eafbf009a 620
gmehmet 1:f60eafbf009a 621
gmehmet 1:f60eafbf009a 622 /**
gmehmet 1:f60eafbf009a 623 * @brief Get sensor ID.
gmehmet 1:f60eafbf009a 624 *
gmehmet 1:f60eafbf009a 625 * @returns Sensor ID number.
gmehmet 1:f60eafbf009a 626 */
gmehmet 1:f60eafbf009a 627 unsigned char MAX8614X::get_sensor_id() {
gmehmet 1:f60eafbf009a 628
gmehmet 1:f60eafbf009a 629 return( SENSOR_ID_MAX30205 );
gmehmet 1:f60eafbf009a 630
gmehmet 1:f60eafbf009a 631 }