HSP Platform firmware evaluating ECG data and hearth rate over PPG data.
Dependencies: max32630fthr Adafruit_FeatherOLED USBDevice
Drivers/MAX8614X/MAX8614X.cpp@1:f60eafbf009a, 2019-04-10 (annotated)
- Committer:
- gmehmet
- Date:
- Wed Apr 10 14:56:25 2019 +0300
- Revision:
- 1:f60eafbf009a
upload from local
Who changed what in which revision?
| User | Revision | Line number | New 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 | } |