added init function from NXP Rapid ioT SDK, read_proximity_sensors function now works well.

Dependents:   rIoTwear-touch rIoTwear-snake

sx9500.h

Committer:
batman52
Date:
2019-12-27
Revision:
3:b0a2ba594005
Parent:
2:f88a77463a32

File content as of revision 3:b0a2ba594005:

#include "mbed.h"

#define SX9500_REG_IRQSRC                           0x00
#define SX9500_REG_STAT                             0x01
#define SX9500_REG_IRQMSK                           0x03
#define SX9500_REG_PROXCTRL0                        0x06
#define SX9500_REG_PROXCTRL1                        0x07
#define SX9500_REG_PROXCTRL2                        0x08
#define SX9500_REG_PROXCTRL3                        0x09
#define SX9500_REG_PROXCTRL4                        0x0A
#define SX9500_REG_PROXCTRL5                        0x0B
#define SX9500_REG_PROXCTRL6                        0x0C
#define SX9500_REG_PROXCTRL7                        0x0D
#define SX9500_REG_PROXCTRL8                        0x0E
#define SX9500_REG_SENSORSEL                        0x20
#define SX9500_REG_USEMSB                           0x21
#define SX9500_REG_USELSB                           0x22
#define SX9500_REG_AVGMSB                           0x23
#define SX9500_REG_AVGLSB                           0x24
#define SX9500_REG_DIFFMSB                          0x25
#define SX9500_REG_DIFFLSB                          0x26
#define SX9500_REG_OFFSETMSB                        0x27
#define SX9500_REG_OFFSETLSB                        0x28
#define SX9500_REG_RESET                            0x7F

#define SX9500_RESET_CMD                            0xDE

/*
 * Copyright (c) 2018 NXP
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Define registers that need to be initialized to values different than
 * default
 */
typedef struct smtc_reg_data {
    unsigned char reg;
    unsigned char val;
}smtc_reg_data_t;
static smtc_reg_data_t sx9500_i2c_reg_setup[] = {
    {
        .reg = SX9500_REG_IRQMSK,
        .val = 0x60,  /* CLOSEIRQEN[6]=1 (close interrupt is on),            */
                      /* FARIRQEN[5]=1 (far interrupt is on),                */
                      /* COMPDONEIRQEN[4]=0 (compensation interrupt is off), */
                      /* CONVDONEIRQEN[3]=0 (conversion interrupt is off)    */
    },
    {
        .reg = SX9500_REG_PROXCTRL1,
        .val = 0x03,  /* SHIELDEN[7:6]=0 (no shield),              */
                      /* RANGE[1:0]=3 (small, +/-2.5pF Full Scale) */
    },
    {
        .reg = SX9500_REG_PROXCTRL2,
        .val = 0x27,  /* GAIN[6:5]=1 (digital gain x2),          */
                      /* FREQ[4:3]=0 (83kHz sampling frequency), */
                      /* RESOLUTION[2:0]=0 (finest resolution)   */
    },
    {
        .reg = SX9500_REG_PROXCTRL3,
        .val = 0x41,  /* DOZEEN[6]=1 (enables doze mode),   */
                      /* DOZEPERIOD[5:4]=0 (2*scan period), */
                      /* RAWFILT[1:0]=1 (Low)               */
    },
    {
        .reg = SX9500_REG_PROXCTRL4,
        .val = 0x80,  /* AVGTHRESH[7:0]=0x80 (threshold triggering compensation = +/-128*value (typ between 16384 and 24576) */
    },
    {
        .reg = SX9500_REG_PROXCTRL5,
        .val = 0x0F,  /* AVGDEB[7:6]=0 (debounce=off),               */
                      /* AVGNEGFILT[5:3]=1 (lowest negative filter), */
                      /* AVGPOSFILT[2:0]=7 (highest positive filter) */
    },
    {
        .reg = SX9500_REG_PROXCTRL6,
        .val = 0x06,  /* PROXTHRESH[4:0]=6 (sensitivity=120) */
    },
    {
        .reg = SX9500_REG_PROXCTRL7,
        .val = 0x00,  /* AVGCOMPDIS[7]=0 (compensation enabled),      */
                      /* COMPMETHOD[6]=0 (separate CSx compensation), */
                      /* HYST[5:4]=0 (hysteresis=32),                 */
                      /* CLOSEDEB[3:2]=0 (close debouncer=off),       */
                      /* FARDEB[1:0]=0 (far debouncer=off)            */
    },
    {
        .reg = SX9500_REG_PROXCTRL8,
        .val = 0x08,  /* STUCK[7:4]=0 (stuck timeout=off),                          */
                      /* COMPPRD[3:0]=8 (periodic compensation every 8*128 samples) */
    },
    {
        .reg = SX9500_REG_PROXCTRL0,
        .val = 0x0F,  /* SCANPERIOD[6:4]=0 (scan every 30ms),  */
                      /* SENSOREN[3:0]=15 (enable all sensors) */
    },
};

typedef enum
{
    SX9500_SUCCESS,
    SX9500_I2C_ERROR,
    SX9500_INTERNAL_ERROR,
    SX9500_NOINIT_ERROR
} SX9500_status;

typedef struct {
    bool downPressed;
    bool upPressed;
    bool leftPressed;
    bool rightPressed;
} SX9500_TouchState_t;

/*
 * END Copyright (c) 2018 NXP
 *
*/

typedef union {
    struct {    // sx9500 register 0x09
        uint8_t txen_stat   : 1;    // 0
        uint8_t reserved    : 2;    // 1,2
        uint8_t conv_done   : 1;    // 3
        uint8_t comp_done   : 1;    // 4
        uint8_t far         : 1;    // 5
        uint8_t close       : 1;    // 6
        uint8_t reset       : 1;    // 7
    } bits;
    uint8_t octet;
} RegIrqSrc_t;

typedef union {
    struct {    // sx9500 register 0x09
        uint8_t compstat         : 4;    // 0,1,2,3
        uint8_t proxstat0        : 1;    // 4
        uint8_t proxstat1        : 1;    // 5
        uint8_t proxstat2        : 1;    // 6
        uint8_t proxstat3        : 1;    // 7
    } bits;
    uint8_t octet;
} RegStat_t;

typedef union {
    struct {    // sx9500 register 0x06
        uint8_t sensor_en   : 4;    // 0,1,2,3
        uint8_t scan_period : 3;    // 4,5,6
        uint8_t reserved    : 1;    // 7
    } bits;
    uint8_t octet;
} RegProxCtrl0_t;

typedef union {
    struct {    // sx9500 register 0x09
        uint8_t raw_filt    : 2;    // 0,1
        uint8_t reserved    : 2;    // 2,3
        uint8_t doze_period : 2;    // 4,5
        uint8_t doze_en     : 1;    // 6
        uint8_t res7        : 1;    // 7
    } bits;
    uint8_t octet;
} RegProxCtrl3_t;

class SX9500 {
    public:
        SX9500(I2C& r, PinName en_pin, PinName nirq_pin);
        ~SX9500();
        //void try_read(void);
        uint8_t read_single(uint8_t addr);
        void read(uint8_t addr, uint8_t *dst_buf, int length);
        void write(uint8_t addr, uint8_t data);
        void reset(void);
        //uint16_t get_sensor(char CSn);
        void print_sensor(char CSn);
        SX9500_TouchState_t read_proximity_sensors();
        void set_active(bool);
        bool get_active(void);
        void service(void);
        uint8_t init(void);
        
        RegIrqSrc_t RegIrqSrc;
        RegProxCtrl0_t RegProxCtrl0;
        
    private:
        I2C& m_i2c;
        DigitalOut m_txen;
        DigitalIn m_nirq; // polled irq pin, because i2c is shared
};