The MAX77734 is a tiny PMIC for applications where size and simplicity are critical. The IC integrates a linear-mode Li+ battery charger, low-dropout linear regulator (LDO), analog multiplexer, and dual-channel current sink driver. Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX77734.pdf Applications ● Hearables: Headsets, Headphones, Earbuds ● Fitness Bands and other Bluetooth Wearables ● Action Cameras, Wearable/Body Cameras ● Low-Power Internet of Things (IoT) Gadgets

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers max77734.cpp Source File

max77734.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************
00032  */
00033 #include "max77734.h"
00034  
00035 /***** Definitions *****/
00036 #define I2C_ADDR            (0x48<<1)
00037 
00038 //******************************************************************************
00039 MAX77734::MAX77734(PinName sda, PinName scl)
00040 {
00041     i2c_ = new I2C(sda, scl);
00042     i2c_owner = true;
00043  
00044     i2c_->frequency(400000);
00045 }
00046  
00047 //******************************************************************************
00048 MAX77734::MAX77734(I2C *i2c) :
00049     i2c_(i2c)
00050 {
00051     i2c_owner = false;
00052 }
00053  
00054 //******************************************************************************
00055 MAX77734::~MAX77734()
00056 {
00057     if(i2c_owner) {
00058         delete i2c_;
00059     }
00060 }
00061  
00062 //******************************************************************************
00063 int32_t MAX77734::init()
00064 {     
00065     // Clear Mask
00066     interrupt_isr();
00067     
00068     // set INTM_GLBL: masked all interrupt(Chip Reset Value)
00069     i2c_update_byte(REG_INTM_GLBL, 0x7c, 0x7c);
00070     
00071     // set INTM_CHG: masked all interrupt(Chip Reset Value)
00072     i2c_update_byte(REG_INTM_CHG, 0x7f, 0x7f);
00073     
00074     return 0;
00075 }
00076 
00077 //******************************************************************************
00078 int32_t MAX77734::i2c_write_byte(MAX77734::REG_TYPE reg_addr, char reg_data)
00079 {
00080     char data[2];
00081  
00082     data[0] = reg_addr;
00083     data[1] = reg_data;
00084     if (i2c_->write(I2C_ADDR, data, 2) != 0) {
00085         return -1;
00086     }
00087  
00088     return 0;
00089 }
00090 
00091 //*****************************************************************************
00092 int32_t MAX77734::i2c_write_bytes(MAX77734::REG_TYPE startReg, 
00093                                 MAX77734::REG_TYPE stopReg,
00094                                 const uint8_t *data)
00095 {
00096     int32_t numBytes = ((stopReg - startReg) + 1);
00097     char packet[numBytes + 1];
00098     
00099     packet[0] = static_cast<char>(startReg);    
00100     memcpy(packet + 1, data, numBytes);
00101     
00102     return i2c_->write(I2C_ADDR, packet, sizeof(packet));
00103 }
00104  
00105 //******************************************************************************
00106 int32_t MAX77734::i2c_read_byte(MAX77734::REG_TYPE reg_addr)
00107 {
00108     char data;
00109  
00110     data = reg_addr;
00111     if (i2c_->write(I2C_ADDR, &data, 1, true) != 0) {
00112         return -1;
00113     }
00114  
00115     if (i2c_->read(I2C_ADDR | 0x01, &data, 1) != 0) {
00116         return -1;
00117     }
00118  
00119     return (0x0 + data);
00120 }
00121 
00122 //*****************************************************************************
00123 int32_t MAX77734::i2c_read_bytes(MAX77734::REG_TYPE startReg,
00124                                 MAX77734::REG_TYPE stopReg,
00125                                 uint8_t *data)
00126 {
00127     int32_t rtnVal = -1;
00128     int32_t numBytes = ((stopReg - startReg) + 1);
00129     char packet[] = {static_cast<char>(startReg)};
00130     
00131     if(i2c_->write(I2C_ADDR, packet, 1) == 0)
00132     {
00133         rtnVal = i2c_->read(I2C_ADDR | 0x01, 
00134                             reinterpret_cast<char *>(data), numBytes);
00135     }
00136     
00137     return rtnVal;
00138 }
00139 
00140 //******************************************************************************
00141 int32_t MAX77734::i2c_update_byte(MAX77734::REG_TYPE reg_addr, 
00142                                     char set_data, char mask)
00143 {
00144     int32_t rData;
00145     
00146     rData = i2c_read_byte(reg_addr);
00147     if(rData < 0)
00148         return rData;
00149     
00150     rData &= ~mask;
00151     rData = (set_data & mask);
00152  
00153     rData = i2c_write_byte(reg_addr, rData);    
00154     if(rData < 0)
00155         return rData;
00156         
00157     return 0;
00158 }
00159 
00160 //*****************************************************************************
00161 int32_t MAX77734::read_register(MAX77734::REG_TYPE reg_addr)
00162 {
00163     int32_t rData, mask;
00164     
00165     rData = i2c_read_byte(reg_addr);
00166     if(rData < 0)
00167         return rData;
00168         
00169     switch(reg_addr) {
00170         case REG_INT_GLBL:     mask = 0x7F; break;
00171         case REG_INT_CHG:      mask = 0x7F; break;
00172         case REG_STAT_CHG_A:   mask = 0x7F; break;
00173         case REG_INTM_GLBL:    mask = 0x7C; break;
00174         case REG_INTM_CHG:     mask = 0x7F; break;
00175         case REG_CID:          mask = 0x0F; break;
00176         case REG_CNFG_WDT:     mask = 0x3F; break;
00177         case REG_CNFG_CHG_F:   mask = 0xFE; break;
00178         case REG_CNFG_CHG_G:   mask = 0xFE; break;
00179         case REG_CNFG_CHG_H:   mask = 0xFC; break;
00180         case REG_CNFG_LDO_B:   mask = 0x0F; break;
00181         case REG_CNFG_SNK_TOP: mask = 0x03; break;
00182         default: mask = 0xFF; break;
00183     }
00184         
00185     return (rData & mask);
00186 }
00187 
00188 //*****************************************************************************
00189 int32_t MAX77734::interrupt_isr()
00190 {
00191     int32_t rData[2];
00192     
00193     rData[0] = i2c_read_byte(REG_INT_GLBL) & 0xff;
00194     if(rData[0] < 0)
00195         return rData[0];
00196 
00197     rData[1] = i2c_read_byte(REG_INT_CHG) & 0xff;
00198     if(rData[1] < 1)
00199         return rData[1]; 
00200 
00201     return ((rData[1] &0xff) << 8 ) | (rData[0] &0xff);
00202 }
00203 
00204 //*****************************************************************************
00205 int32_t MAX77734::set_i_fastchg_uA(int32_t current)
00206 {
00207     int32_t rData;
00208     int32_t code = (current - 7500) / 7500;
00209     
00210     if( current > 300000)
00211         code = 0x3f;
00212     
00213     rData = i2c_update_byte(REG_CNFG_CHG_E, code <<2, 0xFC);    
00214     if(rData < 0)
00215         return rData;
00216     
00217     return 0;
00218 }
00219 
00220 //*****************************************************************************
00221 int32_t MAX77734::set_time_fastchg_hour(int32_t hour)
00222 {
00223     int32_t rData, code;
00224         
00225     switch(hour) {
00226       case 0:         code = 0x0; break; //Timer Disabled
00227       case 1 ... 3:   code = 0x1; break; // 3hours
00228       case 4 ... 5:   code = 0x2; break; //5 hours
00229       default:        code = 0x3; break; //7 hours
00230     };  
00231     
00232     rData = i2c_update_byte(REG_CNFG_CHG_E, code, 0x03);    
00233     if(rData < 0)
00234         return rData;
00235     
00236     return 0;
00237 }
00238 
00239 //*****************************************************************************
00240 int32_t MAX77734::set_v_fastchg_mA(int32_t voltage)
00241 {
00242     int32_t rData;
00243     int32_t code = (voltage - 3600) / 25;
00244     
00245     if( voltage > 4600)
00246         code = 0x3f;
00247     
00248     rData = i2c_update_byte(REG_CNFG_CHG_G, code <<2, 0xFC);    
00249     if(rData < 0)
00250         return rData;
00251     
00252     return 0;
00253 }
00254 
00255 //*****************************************************************************
00256 int32_t MAX77734::set_i_term_percent(MAX77734::I_TERM_TYPE percent)
00257 {
00258     int32_t rData;
00259             
00260     rData = i2c_update_byte(REG_CNFG_CHG_C, percent <<3, 0x18);
00261     if(rData < 0)
00262         return rData;
00263     
00264     return 0;
00265 }
00266 
00267 //*****************************************************************************
00268 int32_t MAX77734::set_time_topoff_min(int32_t minute)
00269 {
00270     int32_t rData, code;
00271     
00272     switch(minute) {
00273       case 0:         code = 0x0; break;
00274       case 1 ... 5:   code = 0x1; break;
00275       case 6 ... 10:  code = 0x2; break;
00276       case 11 ... 15: code = 0x3; break;
00277       case 16 ... 20: code = 0x4; break;
00278       case 21 ... 25: code = 0x5; break;
00279       case 26 ... 30: code = 0x6; break;
00280       default:        code = 0x7; break;
00281     };  
00282             
00283     rData = i2c_update_byte(REG_CNFG_CHG_C, code, 0x07);
00284     if(rData < 0)
00285         return rData;
00286     
00287     return 0;
00288 }
00289 
00290 //*****************************************************************************
00291 int32_t MAX77734::set_charger_enable(MAX77734::ENABLE_TYPE control)
00292 {
00293     int32_t rData, code = 0;
00294     
00295     if(control == VAL_ENABLE)
00296         code = 0x01;
00297             
00298     rData = i2c_update_byte(REG_CNFG_CHG_B, code, 0x01);
00299     if(rData < 0)
00300         return rData;
00301     
00302     return 0;
00303 }
00304 
00305 //*****************************************************************************
00306 int32_t MAX77734::set_ldo_enable(MAX77734::ENABLE_TYPE control)
00307 {
00308     int32_t rData, code;
00309     
00310     switch(control) {
00311         case VAL_ENABLE: code = 0x01; break;
00312         case VAL_ENABLE_OPTION1: code = 0x02; break;
00313         default: code = 0x00; break;        
00314     };
00315             
00316     rData = i2c_update_byte(REG_CNFG_LDO_B, code, 0x03);
00317     if(rData < 0)
00318         return rData;
00319     
00320     return 0;
00321 }
00322 
00323 //*****************************************************************************
00324 int32_t MAX77734::set_ldo_pwr_mode(MAX77734::POWER_MODE_TYPE mode)
00325 {
00326     int32_t rData, code;
00327     
00328     switch(mode) {
00329         case LDO_LOW_PWR_MODE:    code = 0x00; break;
00330         case LDO_NORMAL_PWR_MODE: code = 0x01; break;
00331         case LDO_PIN_ACT_HIGH:    code = 0x02; break;
00332         case LDO_PIN_ACT_LOW:     code = 0x03; break;
00333         default: return -1;
00334     };
00335             
00336     rData = i2c_update_byte(REG_CNFG_LDO_B, code << 2, 0x0C);
00337     if(rData < 0)
00338         return rData;
00339     
00340     return 0;
00341 }
00342 
00343 //*****************************************************************************
00344 int32_t MAX77734::set_ldo_voltage_mV(int32_t voltage)
00345 {
00346     int32_t rData;
00347     int32_t code = (voltage - 800) / 25;
00348                 
00349     rData = i2c_update_byte(REG_CNFG_LDO_A, code, 0x7F);
00350     if(rData < 0)
00351         return rData;
00352     
00353     return 0;
00354 }