initial commit, reads dev id

MAX8614X.h

Committer:
phonemacro
Date:
20 months ago
Revision:
7:ffa35f46725e
Parent:
5:1f7b8cb07e26

File content as of revision 7:ffa35f46725e:

/*******************************************************************************
* Author: Ihsan Mert Ozcelik, Ihsan.Ozcelik@maximintegrated.com
* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/

#ifndef _MAX8614X_H_
#define _MAX8614X_H_

#include "mbed.h"
#include "queue.h"
#include "MaximSensor.h"

/**
@brief The MAX8614X
 */

/**
@brief MAX8614X - supports MAX8614X object with SPI interface
 */
class MAX8614X: public MaximSensor
{
public:
    /* PUBLIC CONST VARIABLES */

    /* Return codes */
    static const int8_t RTN_NO_ERROR = 0;
    static const int8_t RTN_ERR_UNSOPPORTED_PART = -1;
    static const int8_t RTN_ERR_WRONG_DATA_TYPE = -2;
    static const int8_t RTN_ERR_NOT_8614x = -3;
    static const int8_t RTN_ERR_MEM_ALLOC_FAIL = -4;
    static const int8_t RTN_ERR_QUEUE_INIT = -5;
    static const int8_t RTN_ERR_QUEUE_EMPTY = -6;

    /* MAX8614X Registers */
    enum Registers
    {
        MAX8614X_INT_STATUS1_REG = 0x00,
        MAX8614X_INT_STATUS2_REG,
        MAX8614X_INT_ENABLE1_REG,
        MAX8614X_INT_ENABLE2_REG,
        MAX8614X_FIFO_WR_PTR_REG,
        MAX8614X_FIFO_RD_PTR_REG,
        MAX8614X_OVF_CNT_REG,
        MAX8614X_FIFO_DATA_CNT_REG,
        MAX8614X_FIFO_DATA_REG,
        MAX8614X_FIFO_CFG1_REG,
        MAX8614X_FIFO_CFG2_REG, //0x0A
        MAX8614X_SYSTEM_CTRL_REG = 0x0D,
        MAX8614X_PPG_SYNC_CTRL_REG = 0x10,
        MAX8614X_PPG_CFG1_REG,
        MAX8614X_PPG_CFG2_REG,
        MAX8614X_PPG_CFG3_REG,
        MAX8614X_PROX_INT_THRES_REG,
        MAX8614X_PHOTO_DIODE_BIAS_REG,
        MAX8614X_FICKET_FENCE_REG, //0x16
        MAX8614X_LED_SEQ1_REG = 0x20,
        MAX8614X_LED_SEQ2_REG,
        MAX8614X_LED_SEQ3_REG,
        MAX8614X_LED1_PA_REG,
        MAX8614X_LED2_PA_REG,
        MAX8614X_LED3_PA_REG,
        MAX8614X_LED4_PA_REG,
        MAX8614X_LED5_PA_REG,
        MAX8614X_LED6_PA_REG,
        MAX8614X_LED_PILOT_PA_REG,
        MAX8614X_LED_RANGE1_REG,
        MAX8614X_LED_RANGE2_REG, //0x2B
        MAX8614X_DIE_TEMP_CFG_REG = 0x40,
        MAX8614X_DIE_TEMP_INT_REG,
        MAX8614X_DIE_TEMP_FRAC_REG,
        MAX8614X_SHA_CMD_REG = 0xF0,
        MAX8614X_SHA_CFG_REG,
        MAX8614X_MEMORY_CONTROL_REG,
        MAX8614X_MEMORY_INDEX_REG,
        MAX8614X_MEMORY_DATA_REG,
        MAX8614X_REV_ID_REG = 0xFE,
        MAX8614X_PART_ID_REG,

    };

    /*System Control*/
    static const uint8_t MAX8614X_SYSTEM_RESET_MASK     = (0x01 << 0);
    static const uint8_t MAX8614X_SYSTEM_SHDN_MASK      = (0x01 << 1);
    static const uint8_t MAX8614X_SYSTEM_LP_BOOST       = (0x01 << 2);

    /* Die Temperature */
    static const uint8_t MAX8614X_DIE_TEMP_EN           = (0x1 << 0);
    static const uint8_t MAX8614X_DIE_TEMP_FRAC_MASK    = (0xF << 0);

    /* Sample rates */
    static const uint8_t MAX8614X_PPG_SR_25_SPS         = (0x00 << 3);
    static const uint8_t MAX8614X_PPG_SR_50_SPS         = (0x01 << 3);
    static const uint8_t MAX8614X_PPG_SR_84_SPS         = (0x02 << 3);
    static const uint8_t MAX8614X_PPG_SR_100_SPS        = (0x03 << 3);
    static const uint8_t MAX8614X_PPG_SR_200_SPS        = (0x04 << 3);
    static const uint8_t MAX8614X_PPG_SR_400_SPS        = (0x05 << 3);

    /* LED Pulse Amplitude */
    static const uint8_t MAX8614X_LED1_RGE_MASK         = (0x3 << 0);
    static const uint8_t MAX8614X_LED2_RGE_MASK         = (0x3 << 2);
    static const uint8_t MAX8614X_LED3_RGE_MASK         = (0x3 << 4);

    static const uint8_t MAX8614X_LED4_RGE_MASK         = (0x3 << 0);
    static const uint8_t MAX8614X_LED5_RGE_MASK         = (0x3 << 2);
    static const uint8_t MAX8614X_LED6_RGE_MASK         = (0x3 << 4);

    static const uint8_t MAX8614X_LED1_RGE_25mA_MASK    = (0x0 << 0);
    static const uint8_t MAX8614X_LED1_RGE_50mA_MASK    = (0x1 << 0);
    static const uint8_t MAX8614X_LED1_RGE_75mA_MASK    = (0x2 << 0);
    static const uint8_t MAX8614X_LED1_RGE_100mA_MASK   = (0x3 << 0);

    static const uint8_t MAX8614X_LED2_RGE_25mA_MASK    = (0x0 << 2);
    static const uint8_t MAX8614X_LED2_RGE_50mA_MASK    = (0x1 << 2);
    static const uint8_t MAX8614X_LED2_RGE_75mA_MASK    = (0x2 << 2);
    static const uint8_t MAX8614X_LED2_RGE_100mA_MASK   = (0x3 << 2);

    static const uint8_t MAX8614X_LED3_RGE_25mA_MASK    = (0x0 << 4);
    static const uint8_t MAX8614X_LED3_RGE_50mA_MASK    = (0x1 << 4);
    static const uint8_t MAX8614X_LED3_RGE_75mA_MASK    = (0x2 << 4);
    static const uint8_t MAX8614X_LED3_RGE_100mA_MASK   = (0x3 << 4);

    /* PPG PW */
    static const uint8_t MAX8614X_PPG_LED_PW_14_4_US_MASK   = (0 << 0);
    static const uint8_t MAX8614X_PPG_LED_PW_28_8_US_MASK   = (1 << 0);
    static const uint8_t MAX8614X_PPG_LED_PW_57_6_US_MASK   = (2 << 0);
    static const uint8_t MAX8614X_PPG_LED_PW_115_2_US_MASK  = (3 << 0);

    /* PPG Range */
    static const uint8_t MAX8614X_PPG1_ADC_RGE_4096_MASK    = (0 << 2);
    static const uint8_t MAX8614X_PPG1_ADC_RGE_8192_MASK    = (1 << 2);
    static const uint8_t MAX8614X_PPG1_ADC_RGE_16384_MASK   = (2 << 2);
    static const uint8_t MAX8614X_PPG1_ADC_RGE_32768_MASK   = (3 << 2);

    static const uint8_t MAX8614X_PPG2_ADC_RGE_4096_MASK    = (0 << 4);
    static const uint8_t MAX8614X_PPG2_ADC_RGE_8192_MASK    = (1 << 4);
    static const uint8_t MAX8614X_PPG2_ADC_RGE_16384_MASK   = (2 << 4);
    static const uint8_t MAX8614X_PPG2_ADC_RGE_32768_MASK   = (3 << 4);

    /* FIFO */
    static const uint8_t MAX8614X_FIFO_WR_PTR_MASK      = (0x7F << 0);
    static const uint8_t MAX8614X_FIFO_RD_PTR_MASK      = (0x7F << 0);
    static const uint8_t MAX8614X_OVF_CNT_MASK          = (0x7F << 0);
    static const uint8_t MAX8614X_FIFO_A_FULL_MASK      = (0x7F << 0);
    static const uint8_t MAX8614X_FIFO_EN_MASK          = (0x01 << 0);
    static const uint8_t MAX8614X_FIFO_RO_MASK          = (0x01 << 1);
    static const uint8_t MAX8614X_A_FULL_TYPE_MASK      = (0x01 << 2);
    static const uint8_t MAX8614X_A_FULL_RPT            = (0x00 << 2);
    static const uint8_t MAX8614X_A_FULL_ONCE           = (0x01 << 2);
    static const uint8_t MAX8614X_FIFO_STAT_CLR_MASK    = (0x01 << 3);
    static const uint8_t MAX8614X_FLUSH_FIFO_MASK       = (0x01 << 4);

    /* Status */
    static const uint8_t MAX8614X_INT1_EN_A_FULL_MASK   = (0x1 << 7);
    static const uint8_t MAX8614X_INT1_EN_DATA_RDY_MASK = (0x1 << 6);
    static const uint8_t MAX8614X_INT1_EN_DIE_TEMP_MASK = (0x1 << 2);
    static const uint8_t MAX8614X_INT1_EN_VDD_OOR_MASK  = (0x1 << 1);

    /*SHA256 Control*/
    static const uint8_t MAX8614X_IE_SHA_DONE_EN          = (0x01 << 0);
    static const uint8_t MAX8614X_SHACFG_SHA_START        = (0x01 << 0);
    static const uint8_t MAX8614X_SHACFG_SHA_EN           = (0x01 << 1);
    static const uint8_t MAX8614X_MEMCNTRL_BANK0_MASK     = (0);
    static const uint8_t MAX8614X_MEMCNTRL_BANK1_MASK     = (1);
    static const uint8_t MAX8614X_MEMCNTRL_WR_DIS_MASK    = (0x01 << 0);
    static const uint8_t MAX8614X_MEMCNTRL_WR_EN_MASK     = (0x01 << 1);
    static const uint8_t MAX8614X_SHACMD_MAC_ROM_ID       = (0x35);
    static const uint8_t MAX8614X_SHACMD_MAC_NO_ROM_ID    = (0x36);

    /* PUBLIC TYPE DEFINITIONS */
    typedef struct RegisterMap {
        uint8_t addr;
        uint8_t val;
    } RegisterMap_t;

    /* PUBLIC FUNCTION DECLARATIONS */

    MAX8614X(SPI &spiBus, DigitalOut &cs, PinName intPin);

    int readRegister(uint8_t reg, uint8_t *data, int len);

    int writeRegister(uint8_t reg, const uint8_t data);

    int writeBlock(const RegisterMap reg_block[], unsigned int size);

    int dequeue_from_fifo_queue(uint32_t *ir, uint32_t *red, uint32_t *green);

    int get_part_info(uint8_t *part_id, uint8_t *rev_id);

    int init();

    const char *get_sensor_part_name();

    const char *get_sensor_name();

    int sensor_enable(int enable);

    int agc_enable(int agc_enable);

    int dump_registers();
    bool isShaComplete(void);
    void clearShaComplete(void);

    /* PUBLIC VARIABLES */
    InterruptIn m_ir;

private:
    /* PRIVATE CONST VARIABLES */
    static const uint32_t MAX8614X_DATA_WORD_SIZE = 3;
    static const uint32_t MAX8614X_MAX_FIFO_DEPTH = 128;
    static const uint32_t MAX8614X_DATA_TYPE_MASK = (0x1F << 19);
    static const uint32_t MAX8614X_DRIVER_FIFO_SZ = (MAX8614X_MAX_FIFO_DEPTH * 4);

    /* PRIVATE TYPE DEFINITIONS  */
    enum LedSequence
    {
        DATA_SEQ_NONE,
        DATA_SEQ_LED1,
        DATA_SEQ_LED2,
        DATA_SEQ_LED3,
        DATA_SEQ_LED1_LED2,
        DATA_SEQ_LED1_LED3,
        DATA_SEQ_LED2_LED3,
        DATA_SEQ_LED1_LED2_LED3,
        DATA_SEQ_PILOT_LED1,
        DATA_SEQ_AMBIENT,
        DATA_SEQ_LED4_EXT_MUX,
        DATA_SEQ_LED5_EXT_MUX,
        DATA_SEQ_LED6_EXT_MUX,
    };

    enum DataTypes
    {
        DATA_TYPE_PPG1_LEDC1 = 0x01,
        DATA_TYPE_PPG1_LEDC2,
        DATA_TYPE_PPG1_LEDC3,
        DATA_TYPE_PPG1_LEDC4,
        DATA_TYPE_PPG1_LEDC5,
        DATA_TYPE_PPG1_LEDC6,
        DATA_TYPE_PPG2_LEDC1,
        DATA_TYPE_PPG2_LEDC2,
        DATA_TYPE_PPG2_LEDC3,
        DATA_TYPE_PPG2_LEDC4,
        DATA_TYPE_PPG2_LEDC5,
        DATA_TYPE_PPG2_LEDC6,
        DATA_TYPE_PPF1_LEDC1,
        DATA_TYPE_PPF1_LEDC2,
        DATA_TYPE_PPF1_LEDC3,
        DATA_TYPE_PPF2_LEDC1 = 0x13,
        DATA_TYPE_PPF3_LEDC2,
        DATA_TYPE_PPF3_LEDC3,
        DATA_TYPE_PROX1 = 0x19,
        DATA_TYPE_PROX2,
        DATA_TYPE_INVALID_DATA = 0x1E,
        DATA_TYPE_TIME_STAMP,
    };

    enum PartIDs
    {
        MAX86140_PART_ID_VAL = 0x24,
        MAX86141_PART_ID_VAL,
        MAX86142_PART_ID_VAL,
        MAX86143_PART_ID_VAL,
    };

    enum LedRanges
    {
        LED_RANGE_0_50,
        LED_RANGE_50_100,
        LED_RANGE_100_150,
        LED_RANGE_150_200,
    };

    enum LedRangeSteps
    {
        LED_RANGE_STEP_25uA = 120,
        LED_RANGE_STEP_50uA = 240,
        LED_RANGE_STEP_75uA = 360,
        LED_RANGE_STEP_100uA = 480,
    };

    typedef enum {
        LED_1 = 0,
        LED_2,
        LED_3,
        LED_4,
        LED_5,
        LED_6,
        NUM_OF_LED,
    } max8614x_led_t;

    enum LED_CTRL_SM {
        LED_PROX = 1,
        LED_DATA_ACQ,
    };

    typedef union {
        struct {
            uint32_t val:19;
            uint32_t type:5;
            uint32_t:8;
        };
        uint32_t raw;
    } fifo_data_t;

    typedef union {
        uint16_t val;
        struct {
            uint8_t tint;
            uint8_t frac:4;
            uint8_t:4;
        };
    } die_temp_t;

    typedef union {
        struct {
            struct {
                unsigned char pwr_rdy:1;
                unsigned char vdd_oor:1;
                unsigned char die_temp_rdy:1;
                unsigned char led_compb:1;
                unsigned char prox_int:1;
                unsigned char alc_ovf:1;
                unsigned char data_rdy:1;
                unsigned char a_full:1;
            };
            struct {
                unsigned char:7;
                unsigned char sha_done:1;
            };
        };
        uint8_t val[2];
    } int_status_t;

    union led_range {
        struct {
            uint8_t led1:2;
            uint8_t led2:2;
            uint8_t led3:2;
            uint8_t:2;
            uint8_t led4:2;
            uint8_t led5:2;
            uint8_t led6:2;
            uint8_t:2;
        };
        uint8_t val[2];
    };

    typedef struct {
        uint32_t green;
        uint32_t ir;
        uint32_t red;
    } ppg_data_t;

    struct led_control {
        uint32_t diode_sum[NUM_OF_LED];
        uint32_t state;
        uint32_t prox_sum;
        uint32_t prox_sample_cnt;
        int32_t led_current[NUM_OF_LED];
        uint32_t default_current[NUM_OF_LED];
        int32_t agc_led_out_percent;
        int32_t agc_corr_coeff;
        int32_t agc_min_num_samples;
        int32_t agc_sensitivity_percent;
        int32_t change_by_percent_of_range[NUM_OF_LED];
        int32_t change_by_percent_of_current_setting[NUM_OF_LED];
        int32_t change_led_by_absolute_count[NUM_OF_LED];
        uint32_t sample_cnt;
        union led_range led_range_settings;
        uint8_t led_ranges;
        uint8_t agc_is_enabled;
        uint8_t lpm_is_enabled;
    };

    /* PRIVATE VARIABLES */
    SPI m_spiBus;
    DigitalOut m_cs;
    struct queue_t queue;
    struct led_control led_ctrl;
    int vdd_oor_cnt;
    die_temp_t die_temp;
    bool shaComplete;

    /* PRIVATE FUNCTION DECLARATIONS */
    int reset();

    int poweroff();

    void irq_handler();

    int enable_die_temp();

    int read_die_temp();

    int get_num_samples_in_fifo();

    void fifo_irq_handler();

    int read_fifo_data(uint8_t *fifo_data, int num_samples);

    /* AGC functions */
    int max8614x_update_led_range(int new_range, uint8_t led_num,
            union led_range *led_range_settings);

    int max8614x_update_led_current(union led_range *led_range_settings,
            int led_new_val, max8614x_led_t led_num);

    void ppg_auto_gain_ctrl(struct led_control *led_ctrl,
            uint32_t sample_cnt, int diode_data, max8614x_led_t led_num);

    void max8614x_agc_handler(struct led_control *led_ctrl,
            int *samples);

    int led_control_sm(struct led_control *led_ctrl,
            int diode_data, char lpm);

    void led_control_reset(struct led_control *led_ctrl);

    int led_prox_init(struct led_control *led_ctrl, char lpm);

    int led_daq_init(struct led_control *led_ctrl, char lpm);

    void led_control_init(struct led_control *led_ctrl);
};

#endif /* _MAX8614X_H_ */