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.
Diff: max77950.cpp
- 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; +} + + +