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.

max77950.cpp

Committer:
daniel_gs_jeong
Date:
2019-10-02
Revision:
0:005ee97a1572

File content as of revision 0:005ee97a1572:

/*******************************************************************************
 * 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;
}