FlexBook / Mbed 2 deprecated FlexBook171204a

Dependencies:   SDFileSystem app epson mbed msp430 pl tests

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pmic-tps65185.cpp Source File

pmic-tps65185.cpp

00001 /*
00002   Plastic Logic EPD project on MSP430
00003 
00004   Copyright (C) 2013, 2014 Plastic Logic Limited
00005 
00006   This program is free software: you can redistribute it and/or modify
00007   it under the terms of the GNU General Public License as published by
00008   the Free Software Foundation, either version 3 of the License, or
00009   (at your option) any later version.
00010 
00011   This program is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014   GNU General Public License for more details.
00015 
00016   You should have received a copy of the GNU General Public License
00017   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 /*
00020  * pmic-tps65185.c -- Driver for TI TPS65185 PMIC
00021  *
00022  * Authors:
00023  *  Nick Terry <nick.terry@plasticlogic.com>
00024  *  Guillaume Tucker <guillaume.tucker@plasticlogic.com>
00025  *
00026  */
00027 
00028 #include <stdlib.h>
00029 #include "assert.h"
00030 #include "pmic-tps65185.h"
00031 #include "vcom.h"
00032 
00033 #define lOG printf
00034 
00035 #define LOG_TAG "tps65185"
00036 #include "utils.h"
00037 
00038 /* Set to 1 to dump registers */
00039 #define DO_REG_DUMP 0
00040 
00041 #define HVPMIC_DAC_MAX          ((1 << 9)-1)
00042 #define HVPMIC_DAC_MIN          0
00043 #define HVPMIC_TEMP_DEFAULT     20
00044 #define HVPMIC_VERSION          0x65
00045 
00046 #if 0
00047 #define MV_DIV  33      // Each DAC step is 33mV
00048 #endif
00049 
00050 enum tps65185_register {
00051     HVPMIC_REG_TMST_VALUE = 0x00,
00052     HVPMIC_REG_ENABLE     = 0x01,
00053     HVPMIC_REG_VADJ       = 0x02,
00054     HVPMIC_REG_VCOM1      = 0x03,
00055     HVPMIC_REG_VCOM2      = 0x04,
00056     HVPMIC_REG_INT_EN1    = 0x05,
00057     HVPMIC_REG_INT_EN2    = 0x06,
00058     HVPMIC_REG_INT1       = 0x07,
00059     HVPMIC_REG_INT2       = 0x08,
00060     HVPMIC_REG_UPSEQ0     = 0x09,
00061     HVPMIC_REG_UPSEQ1     = 0x0A,
00062     HVPMIC_REG_DWNSEQ0    = 0x0B,
00063     HVPMIC_REG_DWNSEQ1    = 0x0C,
00064     HVPMIC_REG_TMST1      = 0x0D,
00065     HVPMIC_REG_TMST2      = 0x0E,
00066     HVPMIC_REG_PG_STAT    = 0x0F,
00067     HVPMIC_REG_REV_ID     = 0x10,
00068     HVPMIC_REG_MAX
00069 };
00070 
00071 union tps65185_version {
00072     struct {
00073         char version:4;
00074         char minor:2;
00075         char major:2;
00076     } v;
00077     uint8_t byte;
00078 };
00079 
00080 struct pmic_data {
00081     uint8_t reg;
00082     uint8_t data;
00083 };
00084 
00085 static const struct pmic_data init_data[] = {
00086     { HVPMIC_REG_ENABLE,     0x00 },
00087     { HVPMIC_REG_VADJ,       0x03 },
00088     { HVPMIC_REG_VCOM1,      0x00 },
00089     { HVPMIC_REG_VCOM2,      0x00 },
00090     { HVPMIC_REG_INT_EN1,    0x00 },
00091     { HVPMIC_REG_INT_EN2,    0x00 },
00092     { HVPMIC_REG_UPSEQ0,     0x78 },
00093     { HVPMIC_REG_UPSEQ1,     0x00 },
00094     { HVPMIC_REG_DWNSEQ0,    0x00 },
00095     { HVPMIC_REG_DWNSEQ1,    0x00 },
00096     { HVPMIC_REG_TMST1,      0x00 },
00097     { HVPMIC_REG_TMST2,      0x78 }
00098 };
00099 
00100 int pl_i2c_reg_read_8(I2C &i2c, uint8_t i2c_addr, uint8_t reg, uint8_t *data)
00101 {
00102     if (i2c.write(i2c_addr << 1, (char *) &reg, 1, true))
00103     {
00104         unsigned int log_addr = i2c_addr;
00105         unsigned int log_reg = reg;
00106 
00107         LOG("error writing I2C address %x register %x in pl_i2c_reg_read_8", log_addr, log_reg);
00108         i2c.stop();
00109         return -1;
00110     }
00111 
00112     return i2c.read(i2c_addr << 1, (char *) data, 1);
00113 }
00114 
00115 /* Note: reading some registers will modify the status of the device */
00116 void reg_dump(struct tps65185_info *p)
00117 {
00118     uint8_t data;
00119     uint8_t reg;
00120 
00121     for (reg = HVPMIC_REG_TMST_VALUE; reg < HVPMIC_REG_MAX; reg++) {
00122         if (!pl_i2c_reg_read_8(*p->i2c, p->i2c_addr, reg, &data))
00123             LOG("reg[0x%02X] = 0x%02X", reg, data);
00124     }
00125 }
00126 
00127 int pl_i2c_reg_write_8(I2C &i2c, uint8_t i2c_addr, uint8_t reg,
00128                uint8_t data)
00129 {
00130     const uint8_t w_data[2] = { reg, data };
00131 
00132     int status = i2c.write(i2c_addr << 1, (char *) w_data, sizeof(w_data));
00133     if(status)
00134     {
00135         unsigned int log_addr = i2c_addr;
00136         unsigned int log_reg = reg;
00137 
00138         LOG("error writing I2C address %x register %x in pl_i2c_reg_write_8", log_addr, log_reg);
00139         return -1;
00140     }
00141     return status;
00142 }
00143 
00144 int tps65185_init(struct tps65185_info *p, I2C &i2c,
00145           uint8_t i2c_addr, const struct vcom_cal *cal)
00146 {
00147     union tps65185_version ver;
00148     int i;
00149 
00150     p->i2c = &i2c;
00151     p->i2c_addr = i2c_addr;
00152     p->cal = cal; /* Cal may be NULL if not being used */
00153 
00154     if (pl_i2c_reg_read_8(i2c, i2c_addr, HVPMIC_REG_REV_ID, &ver.byte))
00155         return -1;
00156 
00157     LOG("Version: %d.%d.%d", ver.v.major, ver.v.minor, ver.v.version);
00158 
00159     if (ver.byte != HVPMIC_VERSION) {
00160         LOG("Wrong version: 0x%02X instead of 0x%02X",
00161             ver.byte, HVPMIC_VERSION);
00162         return -1;
00163     }
00164 
00165     for (i = 0; i < ARRAY_SIZE(init_data); i++) {
00166         if (pl_i2c_reg_write_8(i2c, i2c_addr, init_data[i].reg, init_data[i].data))
00167             return -1;
00168     }
00169 
00170     return 0;
00171 }
00172 
00173 /* program the internal VCOM Dac to give us the required voltage */
00174 int tps65185_set_vcom_voltage(struct tps65185_info *p, int mv)
00175 {
00176     int dac_value;
00177     uint8_t v1;
00178     uint8_t v2;
00179 
00180     assert(p != NULL);
00181 
00182     dac_value = vcom_calculate(p->cal, mv);
00183 
00184     if (dac_value < HVPMIC_DAC_MIN)
00185         dac_value = HVPMIC_DAC_MIN;
00186     else if (dac_value > HVPMIC_DAC_MAX)
00187         dac_value = HVPMIC_DAC_MAX;
00188 
00189     v1 = dac_value & 0x00FF;
00190     v2 = ((dac_value >> 8) & 0x0001);
00191 
00192     if (pl_i2c_reg_write_8(*p->i2c, p->i2c_addr, HVPMIC_REG_VCOM1, v1))
00193         return -1;
00194 
00195     return pl_i2c_reg_write_8(*p->i2c, p->i2c_addr, HVPMIC_REG_VCOM2, v2);
00196 }