initial commit, reads dev id

Committer:
phonemacro
Date:
Fri Sep 02 22:15:27 2022 +0000
Revision:
6:ec1c447e825c
Parent:
5:1f7b8cb07e26
Child:
7:ffa35f46725e
updated MAX8614X::read_fifo_data to not enable, disable clock when reading the FIFO (this is only needed for Rev A of the chip)

Who changed what in which revision?

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