Driver File to control MAX77950, The MAX77950 is an advanced wireless power receiver IC that meets the specification requirements for WPC low-power (v1.2) and PMA SR1 (v2.0) communication protocols. This device operates using near-field magnetic induction when coupled with a WPC or PMA transmitter and provides output power up to 12 watts.

Revision:
0:005ee97a1572
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max77950.cpp	Wed Oct 02 08:22:22 2019 +0000
@@ -0,0 +1,636 @@
+/*******************************************************************************
+ * Copyright (C) 2019 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.
+ *******************************************************************************
+ */
+ #include "max77950.h"
+ 
+/***** Definitions *****/
+#define I2C_ADDR            (0x61<<1)
+ 
+/**
+  * MAX77950 constructor.
+  *
+  * @param i2c I2C object to use.
+  */
+MAX77950::MAX77950(I2C *i2c) :
+    i2c_(i2c)
+{
+    i2c_owner = false;
+}
+ 
+/**
+  * MAX77950 destructor.
+  */
+MAX77950::~MAX77950()
+{
+    if(i2c_owner) {
+        delete i2c_;
+    }
+}
+
+
+/**
+  * @brief   Initialize MAX77950
+  */
+int32_t MAX77950::init()
+{ 
+    // initial code position.          
+    return 0;
+}
+ 
+/**
+  * @brief   Read Register
+  * @details Reads data from MAX77950 register
+  *
+  * @param   reg_addr Register to read
+  * @returns data if no errors, -1 if error.
+  */
+int32_t MAX77950::read_register(MAX77950::registers_t reg_no)
+{
+    char data;
+ 
+    data = reg_no;
+    if (i2c_->write(I2C_ADDR, &data, 1, true) != 0) {
+        return -1;
+    }
+ 
+    if (i2c_->read(I2C_ADDR | 0x01, &data, 1) != 0) {
+        return -1;
+    }
+ 
+    return (0x0 + data);
+}
+ 
+/**
+  * @brief   Write Register
+  * @details Writes data to MAX77950 register
+  *
+  * @param   reg_addr Register to write
+  * @param   reg_data Data to write
+  * @returns 0 if no errors, -1 if error.
+  */
+int32_t MAX77950::write_register(MAX77950::registers_t reg_no, char reg_data)
+{
+    char data[2];
+ 
+    data[0] = reg_no;
+    data[1] = reg_data;
+    if (i2c_->write(I2C_ADDR, data, 2) != 0) {
+        return -1;
+    }
+ 
+    return 0;
+}
+
+/**
+  * @brief   Update Register data
+  * @details Update bits data of a register 
+  *
+  * @param   reg_no Register Number to be updated
+  * @param   mask Mask Data
+  * @param   reg_data bit data
+  * @returns 0 if no errors, -1 if error.
+  */
+int32_t MAX77950::update_register
+(MAX77950::registers_t reg_no, char reg_mask,  char reg_data)
+{
+    int32_t data;
+ 
+    data = read_register(reg_no);
+    if(data < 0)
+        return -1;
+    
+    data &= ~reg_mask;
+    data |= reg_data;
+    
+    data = write_register(reg_no, (char)(data & 0xff));
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Get Status Low
+  * @details Get status register data
+  *          BIT7 : LDO is ON
+  *          BIT6 : V_rect is over UVLO
+  *          BIT5 : Watchdog timer
+  *          BIT4 : FSK Data
+  *          BIT3 : Reserved
+  *          BIT2 : Reserved
+  *          BIT1 : Over Voltage Status
+  *          BIT0 : Over Current Status
+  * @param   None
+  * @returns status register data.
+  */
+int32_t MAX77950::get_status_low()
+{    
+    int32_t data;
+    
+    data = read_register(REG_STATUS_L);
+    if(data < 0)
+        return -1;
+    return (data & 0xf3);
+}
+
+/**
+  * @brief   Get Status high
+  * @details Get status register data
+  *          BIT7 : Over Temp
+  *          BIT6 : Over Current in TX Mode
+  *          BIT5 : Over Temp in TX Mode
+  *          BIT4 : Reserved
+  *          BIT3 : Power Transfer Established in Tx Mode
+  *          BIT2 : Packet Received in Ping Phase
+  *          BIT1 : Packet Received in ID
+  *          BIT0 : Packet Received in Power Transfer Phase
+  * @param   None
+  * @returns status register data.
+  */
+int32_t MAX77950::get_status_high()
+{    
+    int32_t data;
+    
+    data = read_register(REG_STATUS_H);
+    if(data < 0)
+        return -1;
+    return (data & 0xef);
+}
+
+/**
+  * @brief   Get Interrupt low
+  * @details Get Interrupt register data
+  *          BIT7 : LDO state change Interrupt
+  *          BIT6 : V_rect is over UVLO Interrupt
+  *          BIT5 : Watchdog timer Interrupt
+  *          BIT4 : FSK Data Interrupt
+  *          BIT3 : Reserved
+  *          BIT2 : Reserved
+  *          BIT1 : Over Voltage Interrupt
+  *          BIT0 : Over Current Interrupt
+  * @param   None
+  * @returns status register data.
+  */
+int32_t MAX77950::get_interrupt_low()
+{    
+    int32_t data;
+    
+    data = read_register(REG_INT_L);
+    if(data < 0)
+        return -1;
+    return (data & 0xf3);
+}
+
+/**
+  * @brief   Get Interrupt high
+  * @details Get Interrupt register data
+  *          BIT7 : Over Temp Interrupt
+  *          BIT6 : Over Current in TX Mode Interrupt
+  *          BIT5 : Over Temp in TX Mode Interrupt
+  *          BIT4 : Reserved
+  *          BIT3 : Power Transfer Established in Tx Mode Interrupt
+  *          BIT2 : Packet Received in Ping Phase Interrupt
+  *          BIT1 : Packet Received in ID Interrupt 
+  *          BIT0 : Packet Received in Power Transfer Phase Interrupt
+  * @param   None
+  * @returns status register data.
+  */
+int32_t MAX77950::get_interrupt_high()
+{    
+    int32_t data;
+    
+    data = read_register(REG_INT_H);
+    if(data < 0)
+        return -1;
+    return (data & 0xef);
+}
+
+/**
+  * @brief   Interrupt enable low
+  * @details 
+  *          BIT7 : LDO state change Interrupt
+  *          BIT6 : V_rect is over UVLO Interrupt
+  *          BIT5 : Watchdog timer Interrupt
+  *          BIT4 : FSK Data Interrupt
+  *          BIT3 : Reserved
+  *          BIT2 : Reserved
+  *          BIT1 : Over Voltage Interrupt
+  *          BIT0 : Over Current Interrupt
+  * @param   interrupt_low_t
+  * @returns status register data.
+  */
+int32_t MAX77950::set_interrupt_low(MAX77950::interrupt_low_t _int)
+{    
+    int32_t data;
+    
+    data = update_register(REG_INT_ENABLE_L, (char)_int, (char)_int);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Interrupt enable high
+  * @details 
+  *          BIT7 : Over Temp Interrupt
+  *          BIT6 : Over Current in TX Mode Interrupt
+  *          BIT5 : Over Temp in TX Mode Interrupt
+  *          BIT4 : Reserved
+  *          BIT3 : Power Transfer Established in Tx Mode Interrupt
+  *          BIT2 : Packet Received in Ping Phase Interrupt
+  *          BIT1 : Packet Received in ID Interrupt 
+  *          BIT0 : Packet Received in Power Transfer Phase Interrupt
+  * @param   interrupt_high_t
+  * @returns status register data.
+  */
+int32_t MAX77950::set_interrupt_high(MAX77950::interrupt_high_t _int)
+{    
+    int32_t data;
+    
+    data = update_register(REG_INT_ENABLE_H, (char)_int, (char)_int);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Interrupt disable low
+  * @details 
+  *          BIT7 : LDO state change Interrupt
+  *          BIT6 : V_rect is over UVLO Interrupt
+  *          BIT5 : Watchdog timer Interrupt
+  *          BIT4 : FSK Data Interrupt
+  *          BIT3 : Reserved
+  *          BIT2 : Reserved
+  *          BIT1 : Over Voltage Interrupt
+  *          BIT0 : Over Current Interrupt
+  * @param   interrupt_low_t
+  * @returns status register data.
+  */
+int32_t MAX77950::disable_interrupt_low(MAX77950::interrupt_low_t _int)
+{    
+    int32_t data;
+    
+    data = update_register(REG_INT_ENABLE_L, (char)_int, 0);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Interrupt disable high
+  * @details 
+  *          BIT7 : Over Temp Interrupt
+  *          BIT6 : Over Current in TX Mode Interrupt
+  *          BIT5 : Over Temp in TX Mode Interrupt
+  *          BIT4 : Reserved
+  *          BIT3 : Power Transfer Established in Tx Mode Interrupt
+  *          BIT2 : Packet Received in Ping Phase Interrupt
+  *          BIT1 : Packet Received in ID Interrupt 
+  *          BIT0 : Packet Received in Power Transfer Phase Interrupt
+  * @param   interrupt_high_t
+  * @returns status register data.
+  */
+int32_t MAX77950::disable_interrupt_high(MAX77950::interrupt_high_t _int)
+{    
+    int32_t data;
+    
+    data = update_register(REG_INT_ENABLE_H, (char)_int, 0);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Interrupt Clear low
+  * @details 
+  *          BIT7 : LDO state change Interrupt
+  *          BIT6 : V_rect is over UVLO Interrupt
+  *          BIT5 : Watchdog timer Interrupt
+  *          BIT4 : FSK Data Interrupt
+  *          BIT3 : Reserved
+  *          BIT2 : Reserved
+  *          BIT1 : Over Voltage Interrupt
+  *          BIT0 : Over Current Interrupt
+  * @param   interrupt_low_t
+  * @returns status register data.
+  */
+int32_t MAX77950::clear_interrupt_low(MAX77950::interrupt_low_t _int)
+{    
+    int32_t data;
+    
+    data = update_register(REG_INT_CLEAR_L, (char)_int, (char)_int);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Interrupt Clear high
+  * @details 
+  *          BIT7 : Over Temp Interrupt
+  *          BIT6 : Over Current in TX Mode Interrupt
+  *          BIT5 : Over Temp in TX Mode Interrupt
+  *          BIT4 : Reserved
+  *          BIT3 : Power Transfer Established in Tx Mode Interrupt
+  *          BIT2 : Packet Received in Ping Phase Interrupt
+  *          BIT1 : Packet Received in ID Interrupt 
+  *          BIT0 : Packet Received in Power Transfer Phase Interrupt
+  * @param   interrupt_high_t
+  * @returns status register data.
+  */
+int32_t MAX77950::clear_interrupt_high(MAX77950::interrupt_high_t _int)
+{    
+    int32_t data;
+    
+    data = update_register(REG_INT_CLEAR_H, (char)_int, (char)_int);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Get SOC(Charge Status)
+  * @details 
+  *          0x00, 0x65~0xFE : Reserved
+  *          0x01 ~ 0x64 : 1 ~ 100%
+  *          0xFF : No battery
+  * @param   None
+  * @returns -1: Communication Error
+             0x00: out of range
+             0x01 ~ 0x64: SOC 1~ 100 
+             0xff:  there is no battery to charge.
+  */
+int32_t MAX77950::get_charge_status()
+{    
+    int32_t data;
+    
+    data = read_register(REG_CHARGE_STATUS);
+    if(data < 0)
+        return -1; // communication Error
+        
+    if( (data & 0xff) == 0xff )
+        return 0xff; // here is no battery to charge
+        
+    if( (data &0xff) < 0x01 || (data &0xff)>0x64 )
+        return 0;
+         
+    return ((data &0xff));
+}
+
+/**
+  * @brief   Get VOUT Value
+  * @details 
+  *          Vout Value 12bit data
+  * @param   None
+  * @returns -1: Communication Error
+             0x00~0xFFF
+  */
+int32_t MAX77950::get_vout_value()
+{    
+    int32_t data_h, data_l;
+    
+    data_h = read_register(REG_VOUTVAL_H);
+    if(data_h < 0)
+        return -1; // communication Error
+        
+    data_l = read_register(REG_VOUTVAL_L);
+    if(data_l < 0)
+        return -1; // communication Error
+
+    return (((data_h << 4) & 0xff0) |(data_l & 0xf));
+}
+
+/**
+  * @brief   Get VRECT Value
+  * @details 
+  *          V_rect Value 12bit data
+  * @param   None
+  * @returns -1: Communication Error
+             0x00~0xFFF
+  */
+int32_t MAX77950::get_vrect_value()
+{    
+    int32_t data_h, data_l;
+    
+    data_h = read_register(REG_VRECTVAL_H);
+    if(data_h < 0)
+        return -1; // communication Error
+        
+    data_l = read_register(REG_VRECTVAL_L);
+    if(data_l < 0)
+        return -1; // communication Error
+
+    return (((data_h << 4) & 0xff0) |(data_l & 0xf));
+}
+
+/**
+  * @brief   Get ISense Value
+  * @details 
+  *          ISense Value 12bit data
+  * @param   None
+  * @returns -1: Communication Error
+             0x00~0xFFF
+  */
+int32_t MAX77950::get_isense_value()
+{    
+    int32_t data_h, data_l;
+    
+    data_h = read_register(REG_ISENSEVAL_H);
+    if(data_h < 0)
+        return -1; // communication Error
+        
+    data_l = read_register(REG_ISENSEVAL_L);
+    if(data_l < 0)
+        return -1; // communication Error
+
+    return (((data_h << 4) & 0xff0) |(data_l & 0xf));
+}
+
+/**
+  * @brief   Get Die Temp Value
+  * @details 
+  *          Die Temp
+  * @param   None
+  * @returns -1: Communication Error
+             0x00~0xFF
+  */
+int32_t MAX77950::get_die_temp_value()
+{    
+    int32_t data_h, data_l;
+    
+    data_h = read_register(REG_ISENSEVAL_H);
+    if(data_h < 0)
+        return -1; // communication Error
+        
+    data_l = read_register(REG_ISENSEVAL_L);
+    if(data_l < 0)
+        return -1; // communication Error
+
+    return (((data_h << 4) & 0xff0) |(data_l & 0xf));
+}
+
+/**
+  * @brief   Get AC Operation Frequency 
+  * @details 
+  *          AC Operation Frequency
+  * @param   None
+  * @returns -1: Communication Error
+             0x00~0xFFFF
+  */
+int32_t MAX77950::get_op_freq_value()
+{    
+    int32_t data_h, data_l;
+    
+    data_h = read_register(REG_OP_FREQ_H);
+    if(data_h < 0)
+        return -1; // communication Error
+        
+    data_l = read_register(REG_OP_FREQ_L);
+    if(data_l < 0)
+        return -1; // communication Error
+
+    return (((data_h << 8) & 0xff00) |(data_l & 0xff));
+}
+
+/**
+  * @brief   Get System Operation Mode
+  * @details 
+  *          read System Operation Mode
+  * @param   None
+  * @returns -1: Communication Error
+             0x00: Initial State
+             0x01: WPC Rx Mode
+             0x02: PMA Rx Mode
+             0x03: Tx Mode(PeerPower)
+  */
+int32_t MAX77950::get_systme_opmode()
+{    
+    int32_t data;
+    
+    data = read_register(REG_SYS_OP_MODE);
+    if(data < 0)
+        return -1; // communication Error
+        
+    return (data & 0x07);
+}
+
+/**
+  * @brief   Global Interrtup Clear 
+  * @details 
+  *          Clears all interrupt bits. After the set, it resets automatically.
+  * @param   None
+  * @returns Communication status.
+  */
+int32_t MAX77950::set_gloabl_interrupt_clear()
+{    
+    int32_t data;
+    
+    data = update_register(REG_RX_COM, (char)0x20, (char)0x20);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Send Charger Status 
+  * @details 
+             Send charge status packet. After the set, it resets automatically.
+  * @param   None
+  * @returns Communication status.
+  */
+int32_t MAX77950::set_send_charger_status()
+{    
+    int32_t data;
+    
+    data = update_register(REG_RX_COM, (char)0x10, (char)0x10);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Send "End Power Transfer" Packet
+  * @details 
+             Send End Power Transfer Packet. 
+             After the set, it resets automatically.
+  * @param   None
+  * @returns Communication status.
+  */
+int32_t MAX77950::set_send_ept_packet()
+{    
+    int32_t data;
+    
+    data = update_register(REG_RX_COM, (char)0x08, (char)0x08);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Toggle LDO output
+  * @details 
+              Toggle LDO output once (on to off, off to on). 
+              After the set, it resets automatically.
+  * @param   None
+  * @returns Communication status.
+  */
+int32_t MAX77950::set_toggle_ldo()
+{    
+    int32_t data;
+    
+    data = update_register(REG_RX_COM, (char)0x02, (char)0x02);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+/**
+  * @brief   Sed Rx Data
+  * @details 
+             Send WPC proprietary packet that includes PPP_Header (0x21), 
+             data command (0x22), and data values (0x23 to 0x26). 
+             After the set, it resets automatically
+  * @param   None
+  * @returns Communication status.
+  */
+int32_t MAX77950::set_send_rx_data()
+{    
+    int32_t data;
+    
+    data = update_register(REG_RX_COM, (char)0x01, (char)0x01);
+    if(data < 0)
+        return -1;
+    return 0;
+}
+
+
+