Maxim Integrated 7-bit Sink/Source Current DAC. Driver/library for DS4424, DS4422

DS4424.cpp

Committer:
phonemacro
Date:
2018-09-06
Revision:
3:c40703da0faf
Parent:
1:cdaea8ff359c

File content as of revision 3:c40703da0faf:

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