initial commit, reads dev id

Committer:
phonemacro
Date:
Fri Aug 17 05:35:58 2018 +0000
Revision:
5:1f7b8cb07e26
Parent:
4:6ec3bc44f055
Child:
6:ec1c447e825c
Updated driver for MAX86140/MAX86141 driver functions

Who changed what in which revision?

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