initial commit, reads dev id

Committer:
phonemacro
Date:
Fri Sep 02 22:34:45 2022 +0000
Revision:
7:ffa35f46725e
Parent:
6:ec1c447e825c
remove clock enable/disable in MAX8614X::read_fifo_data (that was only needed for Rev A)

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 fifo_data[0] = MAX8614X_FIFO_DATA_REG;
phonemacro 5:1f7b8cb07e26 153 ret = readRegister(MAX8614X_FIFO_DATA_REG, fifo_data, num_bytes);
phonemacro 5:1f7b8cb07e26 154 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 155 pr_err("readRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 156 return ret;
phonemacro 5:1f7b8cb07e26 157 }
phonemacro 5:1f7b8cb07e26 158
phonemacro 5:1f7b8cb07e26 159 return ret;
phonemacro 5:1f7b8cb07e26 160 }
phonemacro 5:1f7b8cb07e26 161
phonemacro 5:1f7b8cb07e26 162 void MAX8614X::fifo_irq_handler()
phonemacro 5:1f7b8cb07e26 163 {
phonemacro 5:1f7b8cb07e26 164 uint8_t fifo_buf[MAX8614X_MAX_FIFO_DEPTH * MAX8614X_DATA_WORD_SIZE] = {0};
phonemacro 5:1f7b8cb07e26 165 int ret;
phonemacro 5:1f7b8cb07e26 166 int num_samples = 0;
phonemacro 5:1f7b8cb07e26 167 static int last_samples[DATA_TYPE_PPG2_LEDC4];
phonemacro 5:1f7b8cb07e26 168 fifo_data_t fifo_data;
phonemacro 5:1f7b8cb07e26 169 uint16_t idx;
phonemacro 5:1f7b8cb07e26 170 int i;
phonemacro 5:1f7b8cb07e26 171 static ppg_data_t ppg_data;
phonemacro 5:1f7b8cb07e26 172 static uint32_t ppg_data_ack = 0;
phonemacro 5:1f7b8cb07e26 173 const uint32_t ir_green_red_ppg_type = ((1 << DATA_TYPE_PPG1_LEDC1) |
phonemacro 5:1f7b8cb07e26 174 (1 << DATA_TYPE_PPG1_LEDC2) |
phonemacro 5:1f7b8cb07e26 175 (1 << DATA_TYPE_PPG1_LEDC3));
phonemacro 5:1f7b8cb07e26 176
phonemacro 5:1f7b8cb07e26 177 num_samples = get_num_samples_in_fifo();
phonemacro 5:1f7b8cb07e26 178 if (num_samples <= 0) {
phonemacro 5:1f7b8cb07e26 179 pr_debug("get_num_samples_in_fifo failed. err: %d", num_samples);
phonemacro 5:1f7b8cb07e26 180 return;
phonemacro 5:1f7b8cb07e26 181 }
phonemacro 5:1f7b8cb07e26 182
phonemacro 5:1f7b8cb07e26 183 ret = read_fifo_data(fifo_buf, num_samples);
phonemacro 5:1f7b8cb07e26 184 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 185 pr_debug("read_fifo_data failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 186 return;
phonemacro 5:1f7b8cb07e26 187 }
phonemacro 5:1f7b8cb07e26 188
phonemacro 5:1f7b8cb07e26 189 for (i = 0; i < num_samples; i++) {
phonemacro 5:1f7b8cb07e26 190 idx = MAX8614X_DATA_WORD_SIZE * i;
phonemacro 5:1f7b8cb07e26 191 fifo_data.raw = fifo_buf[idx + 0] << 16
phonemacro 5:1f7b8cb07e26 192 | fifo_buf[idx + 1] << 8
phonemacro 5:1f7b8cb07e26 193 | fifo_buf[idx + 2];
phonemacro 5:1f7b8cb07e26 194 if (fifo_data.type == DATA_TYPE_INVALID_DATA || fifo_data.type == 0) {
phonemacro 5:1f7b8cb07e26 195 pr_err("Received invalid data. data: %X, i: %d",
phonemacro 5:1f7b8cb07e26 196 (unsigned int)fifo_data.raw, i);
phonemacro 5:1f7b8cb07e26 197
phonemacro 5:1f7b8cb07e26 198 continue;
phonemacro 5:1f7b8cb07e26 199 }
phonemacro 5:1f7b8cb07e26 200 pr_debug("\ttype: %lu, val: %lu (%lX)",
phonemacro 5:1f7b8cb07e26 201 fifo_data.type, fifo_data.val, fifo_data.val);
phonemacro 5:1f7b8cb07e26 202
phonemacro 5:1f7b8cb07e26 203 if (fifo_data.type > DATA_TYPE_PPG2_LEDC3) {
phonemacro 5:1f7b8cb07e26 204 pr_err("Wrong Data Type: -> Type: %lu, val:%lu, Raw:%lu",
phonemacro 5:1f7b8cb07e26 205 fifo_data.type, fifo_data.val, fifo_data.raw);
phonemacro 5:1f7b8cb07e26 206 continue;
phonemacro 5:1f7b8cb07e26 207 }
phonemacro 5:1f7b8cb07e26 208
phonemacro 5:1f7b8cb07e26 209 if (fifo_data.type > 0 && fifo_data.type < DATA_TYPE_PPG2_LEDC3) {
phonemacro 5:1f7b8cb07e26 210 last_samples[fifo_data.type] = fifo_data.val;
phonemacro 5:1f7b8cb07e26 211 }
phonemacro 5:1f7b8cb07e26 212
phonemacro 5:1f7b8cb07e26 213 if (fifo_data.type == DATA_TYPE_PPG1_LEDC1) {
phonemacro 5:1f7b8cb07e26 214 max8614x_agc_handler(&led_ctrl, last_samples);
phonemacro 5:1f7b8cb07e26 215 }
phonemacro 5:1f7b8cb07e26 216
phonemacro 5:1f7b8cb07e26 217 if (fifo_data.type == DATA_TYPE_PPG1_LEDC1) {
phonemacro 5:1f7b8cb07e26 218 ppg_data.ir = fifo_data.val;
phonemacro 5:1f7b8cb07e26 219 } else if (fifo_data.type == DATA_TYPE_PPG1_LEDC2) {
phonemacro 5:1f7b8cb07e26 220 ppg_data.red = fifo_data.val;
phonemacro 5:1f7b8cb07e26 221 } else if (fifo_data.type == DATA_TYPE_PPG1_LEDC3) {
phonemacro 5:1f7b8cb07e26 222 ppg_data.green = fifo_data.val;
phonemacro 5:1f7b8cb07e26 223 }
phonemacro 5:1f7b8cb07e26 224
phonemacro 5:1f7b8cb07e26 225 ppg_data_ack |= 1 << fifo_data.type;
phonemacro 5:1f7b8cb07e26 226
phonemacro 5:1f7b8cb07e26 227 if ((ppg_data_ack & ir_green_red_ppg_type) != ir_green_red_ppg_type ){
phonemacro 5:1f7b8cb07e26 228 continue;
phonemacro 5:1f7b8cb07e26 229 }
phonemacro 5:1f7b8cb07e26 230 ppg_data_ack = 0;
phonemacro 5:1f7b8cb07e26 231
phonemacro 5:1f7b8cb07e26 232 ret = enqueue(&queue, &ppg_data);
phonemacro 5:1f7b8cb07e26 233 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 234 pr_err("Enqueue data is failed. ret: %d, thrown: %d",
phonemacro 5:1f7b8cb07e26 235 ret, num_samples - i);
phonemacro 5:1f7b8cb07e26 236 return;
phonemacro 5:1f7b8cb07e26 237 }
phonemacro 5:1f7b8cb07e26 238 }
phonemacro 5:1f7b8cb07e26 239 }
phonemacro 5:1f7b8cb07e26 240
phonemacro 5:1f7b8cb07e26 241 int MAX8614X::enable_die_temp()
phonemacro 5:1f7b8cb07e26 242 {
phonemacro 5:1f7b8cb07e26 243 int ret = 0;
phonemacro 5:1f7b8cb07e26 244
phonemacro 5:1f7b8cb07e26 245 ret = writeRegister(MAX8614X_DIE_TEMP_CFG_REG, MAX8614X_DIE_TEMP_EN);
phonemacro 5:1f7b8cb07e26 246 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 247 pr_err("SPI Communication error");
phonemacro 5:1f7b8cb07e26 248 }
phonemacro 5:1f7b8cb07e26 249
phonemacro 5:1f7b8cb07e26 250 return ret;
phonemacro 5:1f7b8cb07e26 251 }
phonemacro 5:1f7b8cb07e26 252
phonemacro 5:1f7b8cb07e26 253 int MAX8614X::read_die_temp()
phonemacro 5:1f7b8cb07e26 254 {
phonemacro 5:1f7b8cb07e26 255 int ret = 0;
phonemacro 5:1f7b8cb07e26 256 uint8_t buf[2];
phonemacro 5:1f7b8cb07e26 257
phonemacro 5:1f7b8cb07e26 258 ret = readRegister(MAX8614X_DIE_TEMP_INT_REG, buf, 2);
phonemacro 5:1f7b8cb07e26 259 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 260 pr_err("Unable to read die_temp. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 261 return ret;
phonemacro 5:1f7b8cb07e26 262 }
phonemacro 5:1f7b8cb07e26 263
phonemacro 5:1f7b8cb07e26 264 die_temp.frac = (uint8_t)buf[1] & MAX8614X_DIE_TEMP_FRAC_MASK;
phonemacro 5:1f7b8cb07e26 265 die_temp.tint = (uint8_t)buf[0];
phonemacro 5:1f7b8cb07e26 266
phonemacro 5:1f7b8cb07e26 267 pr_debug("Die temp: %d - %d, %d", die_temp.val, buf[0], buf[1]);
phonemacro 5:1f7b8cb07e26 268 return enable_die_temp();
phonemacro 5:1f7b8cb07e26 269 }
phonemacro 5:1f7b8cb07e26 270
phonemacro 1:7ae9b934ee55 271 void MAX8614X::irq_handler(void)
phonemacro 1:7ae9b934ee55 272 {
phonemacro 1:7ae9b934ee55 273 int ret;
phonemacro 1:7ae9b934ee55 274 int_status_t status;
phonemacro 1:7ae9b934ee55 275
phonemacro 1:7ae9b934ee55 276 ret = readRegister(MAX8614X_INT_STATUS1_REG, status.val, 2);
phonemacro 1:7ae9b934ee55 277 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 278 pr_err("readRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 279 }
phonemacro 5:1f7b8cb07e26 280 pr_debug("Status reg: %X %X", status.val[0], status.val[1]);
phonemacro 5:1f7b8cb07e26 281
phonemacro 5:1f7b8cb07e26 282 if (status.a_full || status.data_rdy) {
phonemacro 5:1f7b8cb07e26 283 fifo_irq_handler();
phonemacro 5:1f7b8cb07e26 284 }
phonemacro 5:1f7b8cb07e26 285
phonemacro 5:1f7b8cb07e26 286 if (status.die_temp_rdy) {
phonemacro 5:1f7b8cb07e26 287 pr_debug("Pwr_rdy interrupt was triggered.");
phonemacro 1:7ae9b934ee55 288 }
phonemacro 5:1f7b8cb07e26 289
phonemacro 5:1f7b8cb07e26 290 if (status.pwr_rdy) {
phonemacro 5:1f7b8cb07e26 291 pr_info("Pwr_rdy interrupt was triggered.");
phonemacro 5:1f7b8cb07e26 292 }
phonemacro 1:7ae9b934ee55 293
phonemacro 5:1f7b8cb07e26 294 if (status.die_temp_rdy) {
phonemacro 5:1f7b8cb07e26 295 read_die_temp();
phonemacro 5:1f7b8cb07e26 296 }
phonemacro 5:1f7b8cb07e26 297
phonemacro 5:1f7b8cb07e26 298 if (status.vdd_oor) {
phonemacro 5:1f7b8cb07e26 299 vdd_oor_cnt++;
phonemacro 5:1f7b8cb07e26 300 pr_info("VDD Out of range cnt: %d", vdd_oor_cnt);
phonemacro 5:1f7b8cb07e26 301 }
phonemacro 1:7ae9b934ee55 302 if (status.sha_done) {
phonemacro 2:11e0b5b86e1e 303 shaComplete = true;
phonemacro 1:7ae9b934ee55 304 printf("sha interrupt\n\r");
phonemacro 1:7ae9b934ee55 305 }
phonemacro 1:7ae9b934ee55 306 }
phonemacro 2:11e0b5b86e1e 307 bool MAX8614X::isShaComplete(void)
phonemacro 2:11e0b5b86e1e 308 {
phonemacro 2:11e0b5b86e1e 309 return shaComplete;
phonemacro 2:11e0b5b86e1e 310 }
phonemacro 2:11e0b5b86e1e 311 void MAX8614X::clearShaComplete(void)
phonemacro 2:11e0b5b86e1e 312 {
phonemacro 2:11e0b5b86e1e 313 shaComplete = false;
phonemacro 2:11e0b5b86e1e 314 }
phonemacro 5:1f7b8cb07e26 315 int MAX8614X::reset()
phonemacro 5:1f7b8cb07e26 316 {
phonemacro 5:1f7b8cb07e26 317 int ret = 0;
phonemacro 5:1f7b8cb07e26 318
phonemacro 5:1f7b8cb07e26 319 ret = writeRegister(MAX8614X_SYSTEM_CTRL_REG,
phonemacro 5:1f7b8cb07e26 320 MAX8614X_SYSTEM_RESET_MASK);
phonemacro 5:1f7b8cb07e26 321 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 322 pr_err("writeRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 323 return ret;
phonemacro 5:1f7b8cb07e26 324 }
phonemacro 5:1f7b8cb07e26 325
phonemacro 5:1f7b8cb07e26 326 ret = queue_reset(&queue);
phonemacro 5:1f7b8cb07e26 327 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 328 pr_err("queue_reset failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 329 return ret;
phonemacro 5:1f7b8cb07e26 330 }
phonemacro 5:1f7b8cb07e26 331
phonemacro 5:1f7b8cb07e26 332 led_control_reset(&led_ctrl);
phonemacro 5:1f7b8cb07e26 333
phonemacro 5:1f7b8cb07e26 334 return ret;
phonemacro 5:1f7b8cb07e26 335 }
phonemacro 5:1f7b8cb07e26 336
phonemacro 5:1f7b8cb07e26 337 int MAX8614X::poweroff()
phonemacro 5:1f7b8cb07e26 338 {
phonemacro 5:1f7b8cb07e26 339 int ret = 0;
phonemacro 5:1f7b8cb07e26 340
phonemacro 5:1f7b8cb07e26 341 ret = writeRegister(MAX8614X_SYSTEM_CTRL_REG,
phonemacro 5:1f7b8cb07e26 342 MAX8614X_SYSTEM_SHDN_MASK);
phonemacro 5:1f7b8cb07e26 343 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 344 pr_err("writeRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 345 return ret;
phonemacro 5:1f7b8cb07e26 346 }
phonemacro 5:1f7b8cb07e26 347
phonemacro 5:1f7b8cb07e26 348 return ret;
phonemacro 5:1f7b8cb07e26 349 }
phonemacro 5:1f7b8cb07e26 350
phonemacro 5:1f7b8cb07e26 351 int MAX8614X::init()
phonemacro 5:1f7b8cb07e26 352 {
phonemacro 5:1f7b8cb07e26 353 int ret = RTN_NO_ERROR;
phonemacro 5:1f7b8cb07e26 354 uint8_t part_id, rev_id;
phonemacro 5:1f7b8cb07e26 355 void *queue_buf = NULL;
phonemacro 5:1f7b8cb07e26 356
phonemacro 5:1f7b8cb07e26 357 ret = get_part_info(&part_id, &rev_id);
phonemacro 5:1f7b8cb07e26 358 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 359 pr_err("MAX8614X is not detected. Part_id: 0x%X, Rev_Id: 0x%X",
phonemacro 5:1f7b8cb07e26 360 part_id, rev_id);
phonemacro 5:1f7b8cb07e26 361 ret = RTN_ERR_NOT_8614x;
phonemacro 5:1f7b8cb07e26 362 goto fail;
phonemacro 5:1f7b8cb07e26 363 }
phonemacro 5:1f7b8cb07e26 364 pr_info("MAX8614X detected. Part_id: 0x%X, Rev_Id: 0x%X", part_id, rev_id);
phonemacro 5:1f7b8cb07e26 365
phonemacro 5:1f7b8cb07e26 366 queue_buf = malloc(sizeof(ppg_data_t) * MAX8614X_DRIVER_FIFO_SZ);
phonemacro 5:1f7b8cb07e26 367 if (queue_buf == NULL) {
phonemacro 5:1f7b8cb07e26 368 pr_err("malloc failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 369 ret = RTN_ERR_MEM_ALLOC_FAIL;
phonemacro 5:1f7b8cb07e26 370 goto fail;
phonemacro 5:1f7b8cb07e26 371 }
phonemacro 5:1f7b8cb07e26 372
phonemacro 5:1f7b8cb07e26 373 ret = queue_init(&queue, queue_buf,
phonemacro 5:1f7b8cb07e26 374 sizeof(ppg_data_t), sizeof(ppg_data_t) * MAX8614X_DRIVER_FIFO_SZ);
phonemacro 5:1f7b8cb07e26 375 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 376 pr_err("queue_init failed");
phonemacro 5:1f7b8cb07e26 377 ret = RTN_ERR_QUEUE_INIT;
phonemacro 5:1f7b8cb07e26 378 free(queue_buf);
phonemacro 5:1f7b8cb07e26 379 goto fail;
phonemacro 5:1f7b8cb07e26 380 }
phonemacro 5:1f7b8cb07e26 381
phonemacro 5:1f7b8cb07e26 382 ret = writeRegister(MAX8614X_SYSTEM_CTRL_REG,
phonemacro 5:1f7b8cb07e26 383 MAX8614X_SYSTEM_RESET_MASK);
phonemacro 5:1f7b8cb07e26 384 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 385 pr_err("writeRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 386 goto fail;
phonemacro 5:1f7b8cb07e26 387 }
phonemacro 5:1f7b8cb07e26 388
phonemacro 5:1f7b8cb07e26 389 die_temp.frac = 0;
phonemacro 5:1f7b8cb07e26 390 die_temp.tint = 0;
phonemacro 5:1f7b8cb07e26 391
phonemacro 5:1f7b8cb07e26 392 led_control_init(&led_ctrl); /*TODO: after porting agc, test */
phonemacro 5:1f7b8cb07e26 393
phonemacro 5:1f7b8cb07e26 394 m_ir.fall(Callback<void()>(this, &MAX8614X::irq_handler));
phonemacro 5:1f7b8cb07e26 395
phonemacro 5:1f7b8cb07e26 396 return ret;
phonemacro 5:1f7b8cb07e26 397 fail:
phonemacro 5:1f7b8cb07e26 398 pr_err("Init failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 399 return ret;
phonemacro 5:1f7b8cb07e26 400 }
phonemacro 5:1f7b8cb07e26 401
phonemacro 5:1f7b8cb07e26 402 int MAX8614X::sensor_enable(int enable)
phonemacro 0:77ee0ceb503a 403 {
phonemacro 5:1f7b8cb07e26 404 int ret = RTN_NO_ERROR;
phonemacro 5:1f7b8cb07e26 405 uint8_t led_seq[3];
phonemacro 5:1f7b8cb07e26 406
phonemacro 5:1f7b8cb07e26 407 RegisterMap_t ppg_init_cfg[] = {
phonemacro 5:1f7b8cb07e26 408 { MAX8614X_SYSTEM_CTRL_REG, MAX8614X_SYSTEM_RESET_MASK},
phonemacro 5:1f7b8cb07e26 409 { MAX8614X_PPG_CFG1_REG, MAX8614X_PPG_LED_PW_115_2_US_MASK // PPG_LED_PW = 3 (115.2us)
phonemacro 5:1f7b8cb07e26 410 | MAX8614X_PPG1_ADC_RGE_32768_MASK // PPG1_ADC_RGE = 3(32768nA)
phonemacro 5:1f7b8cb07e26 411 | MAX8614X_PPG2_ADC_RGE_32768_MASK }, // PPG2_ADC_RGE = 3(32768nA)
phonemacro 5:1f7b8cb07e26 412 { MAX8614X_PPG_CFG2_REG, MAX8614X_PPG_SR_100_SPS}, // PPG_SR: 3 (100Hz), SMP_AVE=0
phonemacro 5:1f7b8cb07e26 413 { MAX8614X_LED_SEQ1_REG, 0x21},
phonemacro 5:1f7b8cb07e26 414 { MAX8614X_LED_SEQ2_REG, 0x03},
phonemacro 5:1f7b8cb07e26 415 { MAX8614X_LED1_PA_REG, 0x80},
phonemacro 5:1f7b8cb07e26 416 { MAX8614X_LED2_PA_REG, 0x80},
phonemacro 5:1f7b8cb07e26 417 { MAX8614X_LED3_PA_REG, 0x80},
phonemacro 5:1f7b8cb07e26 418 { MAX8614X_LED_RANGE1_REG, MAX8614X_LED1_RGE_25mA_MASK
phonemacro 5:1f7b8cb07e26 419 | MAX8614X_LED2_RGE_25mA_MASK
phonemacro 5:1f7b8cb07e26 420 | MAX8614X_LED3_RGE_25mA_MASK},
phonemacro 5:1f7b8cb07e26 421 { MAX8614X_FIFO_CFG1_REG, 0x0C},
phonemacro 5:1f7b8cb07e26 422 { MAX8614X_FIFO_CFG2_REG, MAX8614X_FLUSH_FIFO_MASK
phonemacro 5:1f7b8cb07e26 423 | MAX8614X_FIFO_STAT_CLR_MASK
phonemacro 5:1f7b8cb07e26 424 | MAX8614X_A_FULL_TYPE_MASK // Try 0
phonemacro 5:1f7b8cb07e26 425 | MAX8614X_FIFO_RO_MASK
phonemacro 5:1f7b8cb07e26 426 | MAX8614X_FIFO_EN_MASK},
phonemacro 5:1f7b8cb07e26 427 { MAX8614X_INT_ENABLE1_REG, MAX8614X_INT1_EN_A_FULL_MASK
phonemacro 5:1f7b8cb07e26 428 | MAX8614X_INT1_EN_DIE_TEMP_MASK
phonemacro 5:1f7b8cb07e26 429 | MAX8614X_INT1_EN_VDD_OOR_MASK},
phonemacro 5:1f7b8cb07e26 430 };
phonemacro 5:1f7b8cb07e26 431
phonemacro 5:1f7b8cb07e26 432 if (enable) {
phonemacro 5:1f7b8cb07e26 433 /* Read current sequence settings, and check what modes are open */
phonemacro 5:1f7b8cb07e26 434 led_seq[0] = MAX8614X_LED_SEQ1_REG;
phonemacro 5:1f7b8cb07e26 435 ret |= readRegister(MAX8614X_LED_SEQ1_REG, led_seq, 3);
phonemacro 5:1f7b8cb07e26 436 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 437 pr_err("readRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 438 return ret;
phonemacro 5:1f7b8cb07e26 439 }
phonemacro 5:1f7b8cb07e26 440
phonemacro 5:1f7b8cb07e26 441 pr_debug("0-Sequence registers: %X %X %X", led_seq[0], led_seq[1], led_seq[2]);
phonemacro 5:1f7b8cb07e26 442 ret |= writeBlock(ppg_init_cfg, ARRAY_SIZE(ppg_init_cfg));
phonemacro 5:1f7b8cb07e26 443 led_seq[0] = MAX8614X_INT_STATUS1_REG;
phonemacro 5:1f7b8cb07e26 444 ret |= readRegister(MAX8614X_INT_STATUS1_REG, led_seq, 3); // Mert: the len was 3 ?!
phonemacro 5:1f7b8cb07e26 445 pr_debug("1-Sequence registers: %X %X %X", led_seq[0], led_seq[1], led_seq[2]);
phonemacro 5:1f7b8cb07e26 446 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 447 pr_err("readRegister failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 448 return ret;
phonemacro 5:1f7b8cb07e26 449 }
phonemacro 5:1f7b8cb07e26 450 agc_enable(1);
phonemacro 5:1f7b8cb07e26 451 pr_debug("Wrote register settings. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 452 } else {
phonemacro 5:1f7b8cb07e26 453 ret = reset();
phonemacro 5:1f7b8cb07e26 454 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 455 pr_err("reset failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 456 return ret;
phonemacro 5:1f7b8cb07e26 457 }
phonemacro 5:1f7b8cb07e26 458
phonemacro 5:1f7b8cb07e26 459 ret = poweroff();
phonemacro 5:1f7b8cb07e26 460 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 461 pr_err("poweroff failed. ret: %d", ret);
phonemacro 5:1f7b8cb07e26 462 return ret;
phonemacro 5:1f7b8cb07e26 463 }
phonemacro 5:1f7b8cb07e26 464 }
phonemacro 5:1f7b8cb07e26 465
phonemacro 5:1f7b8cb07e26 466 return RTN_NO_ERROR;
phonemacro 5:1f7b8cb07e26 467 }
phonemacro 5:1f7b8cb07e26 468
phonemacro 5:1f7b8cb07e26 469 int MAX8614X::agc_enable(int agc_enable)
phonemacro 5:1f7b8cb07e26 470 {
phonemacro 5:1f7b8cb07e26 471 int ret = RTN_NO_ERROR;
phonemacro 5:1f7b8cb07e26 472 led_ctrl.agc_is_enabled = !!agc_enable;
phonemacro 5:1f7b8cb07e26 473 led_ctrl.lpm_is_enabled = !!agc_enable;
phonemacro 5:1f7b8cb07e26 474 ret = led_prox_init(&led_ctrl, led_ctrl.lpm_is_enabled);
phonemacro 5:1f7b8cb07e26 475 return ret;
phonemacro 5:1f7b8cb07e26 476 }
phonemacro 5:1f7b8cb07e26 477
phonemacro 5:1f7b8cb07e26 478 int MAX8614X::dequeue_from_fifo_queue(uint32_t *ir, uint32_t *red, uint32_t *green)
phonemacro 5:1f7b8cb07e26 479 {
phonemacro 5:1f7b8cb07e26 480 int ret;
phonemacro 5:1f7b8cb07e26 481 ppg_data_t ppg_data;
phonemacro 5:1f7b8cb07e26 482
phonemacro 5:1f7b8cb07e26 483 ret = dequeue(&queue, &ppg_data);
phonemacro 5:1f7b8cb07e26 484 if (ret < 0) {
phonemacro 5:1f7b8cb07e26 485 return RTN_ERR_QUEUE_EMPTY;
phonemacro 5:1f7b8cb07e26 486 }
phonemacro 5:1f7b8cb07e26 487
phonemacro 5:1f7b8cb07e26 488 pr_debug("%lu %lu %lu", ppg_data.ir, ppg_data.red, ppg_data.green);
phonemacro 5:1f7b8cb07e26 489
phonemacro 5:1f7b8cb07e26 490 *ir = ppg_data.ir;
phonemacro 5:1f7b8cb07e26 491 *red = ppg_data.red;
phonemacro 5:1f7b8cb07e26 492 *green = ppg_data.green;
phonemacro 5:1f7b8cb07e26 493
phonemacro 5:1f7b8cb07e26 494 return RTN_NO_ERROR;
phonemacro 5:1f7b8cb07e26 495 }
phonemacro 5:1f7b8cb07e26 496
phonemacro 5:1f7b8cb07e26 497 int MAX8614X::dump_registers()
phonemacro 5:1f7b8cb07e26 498 {
phonemacro 5:1f7b8cb07e26 499 int ret = 0;
phonemacro 5:1f7b8cb07e26 500 uint8_t reg_addr;
phonemacro 5:1f7b8cb07e26 501 uint8_t val;
phonemacro 5:1f7b8cb07e26 502
phonemacro 5:1f7b8cb07e26 503 for (reg_addr = 0x00; reg_addr <= 0x42; reg_addr++) {
phonemacro 5:1f7b8cb07e26 504 ret |= readRegister(reg_addr, &val, 1);
phonemacro 5:1f7b8cb07e26 505 printf("{%02X,%02X},", reg_addr, val);
phonemacro 5:1f7b8cb07e26 506 }
phonemacro 5:1f7b8cb07e26 507
phonemacro 5:1f7b8cb07e26 508 for (reg_addr = 0xF0; reg_addr != 0x00; reg_addr++) {
phonemacro 5:1f7b8cb07e26 509 ret |= readRegister(reg_addr, &val, 1);
phonemacro 5:1f7b8cb07e26 510 printf("{%02X,%02X},", reg_addr, val);
phonemacro 5:1f7b8cb07e26 511 }
phonemacro 5:1f7b8cb07e26 512
phonemacro 5:1f7b8cb07e26 513 return ret;
phonemacro 5:1f7b8cb07e26 514 }
phonemacro 5:1f7b8cb07e26 515
phonemacro 5:1f7b8cb07e26 516 const char * MAX8614X::get_sensor_part_name()
phonemacro 5:1f7b8cb07e26 517 {
phonemacro 5:1f7b8cb07e26 518 return "max86141";
phonemacro 5:1f7b8cb07e26 519 }
phonemacro 5:1f7b8cb07e26 520
phonemacro 5:1f7b8cb07e26 521 const char * MAX8614X::get_sensor_name()
phonemacro 5:1f7b8cb07e26 522 {
phonemacro 5:1f7b8cb07e26 523 return "ppg";
phonemacro 5:1f7b8cb07e26 524 }