Maxim Integrated 7-bit Sink/Source Current DAC. DS4424, DS4422 input/output current Digital-to-Analog Converter Driver/library code.

Dependents:   DS4424_Hello_Current_DAC_on_MAX32630FTHR

DS4424.cpp

Committer:
phonemacro
Date:
2018-10-07
Revision:
4:3824afaf0d61
Parent:
2:b7a81b724561
Child:
5:fc75fced724f

File content as of revision 4:3824afaf0d61:

/*******************************************************************************
 * Copyright (C) 2018 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 "DS4424.h"

/*
 * DS4424 DAC control register 8 bits
 * [7]      0: to sink; 1: to source
 * [6:0]    steps to sink/source
 * bit[7] looks like a sign bit, but the value of the register is
 * not a two's complement code considering the bit[6:0] is a absolute
 * distance from the zero point.
 */
union ds4424_raw_data {
    struct {
        uint8_t dx:7;
        uint8_t source_bit:1;
    };
    uint8_t bits;
};
 
/******************************************************************************/
DS4424::DS4424(I2C &i2c_bus, DS4424_i2c_adrs_t slaveAddress, DS4424_ic_t ic_variant):
m_i2c(i2c_bus), 
m_writeAddress(slaveAddress <<1),
m_readAddress ((slaveAddress << 1) | 1)
{
    switch(ic_variant) {
       case DS4424_IC:
            m_max_ch_reg_addr = REG_OUT3;
            break;
        case DS4422_IC:
            m_max_ch_reg_addr = REG_OUT1;
            break;
        default:
            m_max_ch_reg_addr = REG_OUT3;
            break;
    }
}
 
 
/******************************************************************************/
DS4424::~DS4424(void) 
{
  /** empty block */
}
 
 
/******************************************************************************/
int DS4424::read_raw(int32_t &result, ChannelRegAddr_e chan_addr) 
{
    uint8_t value;
    int ret = DS4424_ERROR;
    union ds4424_raw_data raw;
    
    if (chan_addr >= REG_OUT0 && chan_addr <=  m_max_ch_reg_addr)
        ret = read_register(chan_addr, value);
    if (ret != 0)
        return DS4424_ERROR;
    

    raw.bits = value;
    result = raw.dx;
    if (raw.source_bit == DS4424_SINK_I)  /** Sinking will be negative values */
        result = -result;
    return DS4424_NO_ERROR;

}


/******************************************************************************/
int DS4424::write_raw(int32_t value, ChannelRegAddr_e chan_addr) 
{
    #define U8_MAX     ((uint8_t)~0U)
    #define S8_MAX     ((int8_t)(U8_MAX>>1))
    #define S8_MIN     ((int8_t)(-S8_MAX - 1))
    int ret = DS4424_ERROR;
    union ds4424_raw_data raw;
    
    if ((chan_addr >= REG_OUT0 && chan_addr <=  m_max_ch_reg_addr) &&
        (value >= S8_MIN && value <= S8_MAX)) {
        if (value > 0) {
            raw.source_bit = DS4424_SOURCE_I;
            raw.dx = value;
        } else {
            raw.source_bit = DS4424_SINK_I;
            raw.dx = -value;
        }
        ret = write_register(chan_addr, raw.bits);
 
        if (ret != 0)
            return DS4424_ERROR;
        return DS4424_NO_ERROR;
    } else {
        return DS4424_ERROR;
    }
}

 
/******************************************************************************/
int DS4424::read_register(ChannelRegAddr_e reg, uint8_t &value) 
{
    int32_t ret;
 
    char data = reg;
 
    ret = m_i2c.write(m_writeAddress, &data, sizeof(data));
    if (ret != 0) {
        printf("%s - failed - ret: %d reg: %d data: %d sizeof(data): %d\r\n", __func__, ret, (int)reg, data, sizeof(data));
        return DS4424_ERROR;
    }
 
    ret = m_i2c.read(m_readAddress, &data, sizeof(data));
    if (ret != 0) {
        printf("%s - failed - ret: %d\r\n", __func__, ret);
        return DS4424_ERROR;
    }
 
    value = data;
    return DS4424_NO_ERROR;

}


/******************************************************************************/
int DS4424::write_register(ChannelRegAddr_e reg, uint8_t value)
{
    
    int32_t ret;
 
    char cmdData[] = {static_cast<char>(reg), static_cast<char>(value)};
 
    ret = m_i2c.write(m_writeAddress, cmdData, sizeof(cmdData));

    if (ret != 0)
        return DS4424_ERROR;
 
    return DS4424_NO_ERROR;
}