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

Committer:
phonemacro
Date:
Wed Jan 23 00:43:09 2019 +0000
Revision:
5:fc75fced724f
Parent:
4:3824afaf0d61
Add methods for processed data (picoAmps). Reverse the parameter order in the protected method read_register.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phonemacro 0:8002303900e6 1 /*******************************************************************************
phonemacro 5:fc75fced724f 2 * Copyright (C) 2018-2019 Maxim Integrated Products, Inc., All Rights Reserved.
phonemacro 4:3824afaf0d61 3 *
phonemacro 4:3824afaf0d61 4 * Permission is hereby granted, free of charge, to any person obtaining a
phonemacro 4:3824afaf0d61 5 * copy of this software and associated documentation files (the "Software"),
phonemacro 4:3824afaf0d61 6 * to deal in the Software without restriction, including without limitation
phonemacro 4:3824afaf0d61 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
phonemacro 4:3824afaf0d61 8 * and/or sell copies of the Software, and to permit persons to whom the
phonemacro 4:3824afaf0d61 9 * Software is furnished to do so, subject to the following conditions:
phonemacro 4:3824afaf0d61 10 *
phonemacro 4:3824afaf0d61 11 * The above copyright notice and this permission notice shall be included
phonemacro 4:3824afaf0d61 12 * in all copies or substantial portions of the Software.
phonemacro 4:3824afaf0d61 13 *
phonemacro 4:3824afaf0d61 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
phonemacro 4:3824afaf0d61 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
phonemacro 4:3824afaf0d61 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
phonemacro 4:3824afaf0d61 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
phonemacro 4:3824afaf0d61 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
phonemacro 4:3824afaf0d61 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
phonemacro 4:3824afaf0d61 20 * OTHER DEALINGS IN THE SOFTWARE.
phonemacro 4:3824afaf0d61 21 *
phonemacro 4:3824afaf0d61 22 * Except as contained in this notice, the name of Maxim Integrated
phonemacro 4:3824afaf0d61 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
phonemacro 4:3824afaf0d61 24 * Products, Inc. Branding Policy.
phonemacro 4:3824afaf0d61 25 *
phonemacro 4:3824afaf0d61 26 * The mere transfer of this software does not imply any licenses
phonemacro 4:3824afaf0d61 27 * of trade secrets, proprietary technology, copyrights, patents,
phonemacro 4:3824afaf0d61 28 * trademarks, maskwork rights, or any other form of intellectual
phonemacro 4:3824afaf0d61 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
phonemacro 4:3824afaf0d61 30 * ownership rights.
phonemacro 4:3824afaf0d61 31 *******************************************************************************
phonemacro 4:3824afaf0d61 32 */
phonemacro 0:8002303900e6 33
phonemacro 0:8002303900e6 34 #include "DS4424.h"
phonemacro 5:fc75fced724f 35 /* #include "USBSerial.h" */
phonemacro 5:fc75fced724f 36 #define DS4424_U8_MAX ((uint8_t)~0U)
phonemacro 5:fc75fced724f 37 #define DS4424_S8_MAX ((int8_t)(DS4424_U8_MAX>>1))
phonemacro 5:fc75fced724f 38 #define DS4424_S8_MIN ((int8_t)(-DS4424_S8_MAX - 1))
phonemacro 0:8002303900e6 39
phonemacro 0:8002303900e6 40 /*
phonemacro 0:8002303900e6 41 * DS4424 DAC control register 8 bits
phonemacro 0:8002303900e6 42 * [7] 0: to sink; 1: to source
phonemacro 0:8002303900e6 43 * [6:0] steps to sink/source
phonemacro 0:8002303900e6 44 * bit[7] looks like a sign bit, but the value of the register is
phonemacro 0:8002303900e6 45 * not a two's complement code considering the bit[6:0] is a absolute
phonemacro 0:8002303900e6 46 * distance from the zero point.
phonemacro 0:8002303900e6 47 */
phonemacro 0:8002303900e6 48 union ds4424_raw_data {
phonemacro 0:8002303900e6 49 struct {
phonemacro 0:8002303900e6 50 uint8_t dx:7;
phonemacro 0:8002303900e6 51 uint8_t source_bit:1;
phonemacro 0:8002303900e6 52 };
phonemacro 0:8002303900e6 53 uint8_t bits;
phonemacro 0:8002303900e6 54 };
phonemacro 0:8002303900e6 55
phonemacro 4:3824afaf0d61 56 /******************************************************************************/
phonemacro 0:8002303900e6 57 DS4424::DS4424(I2C &i2c_bus, DS4424_i2c_adrs_t slaveAddress, DS4424_ic_t ic_variant):
phonemacro 0:8002303900e6 58 m_i2c(i2c_bus),
phonemacro 0:8002303900e6 59 m_writeAddress(slaveAddress <<1),
phonemacro 0:8002303900e6 60 m_readAddress ((slaveAddress << 1) | 1)
phonemacro 0:8002303900e6 61 {
phonemacro 0:8002303900e6 62 switch(ic_variant) {
phonemacro 0:8002303900e6 63 case DS4424_IC:
phonemacro 0:8002303900e6 64 m_max_ch_reg_addr = REG_OUT3;
phonemacro 0:8002303900e6 65 break;
phonemacro 0:8002303900e6 66 case DS4422_IC:
phonemacro 0:8002303900e6 67 m_max_ch_reg_addr = REG_OUT1;
phonemacro 0:8002303900e6 68 break;
phonemacro 0:8002303900e6 69 default:
phonemacro 0:8002303900e6 70 m_max_ch_reg_addr = REG_OUT3;
phonemacro 0:8002303900e6 71 break;
phonemacro 0:8002303900e6 72 }
phonemacro 0:8002303900e6 73 }
phonemacro 0:8002303900e6 74
phonemacro 0:8002303900e6 75
phonemacro 4:3824afaf0d61 76 /******************************************************************************/
phonemacro 0:8002303900e6 77 DS4424::~DS4424(void)
phonemacro 0:8002303900e6 78 {
phonemacro 4:3824afaf0d61 79 /** empty block */
phonemacro 0:8002303900e6 80 }
phonemacro 0:8002303900e6 81
phonemacro 0:8002303900e6 82
phonemacro 4:3824afaf0d61 83 /******************************************************************************/
phonemacro 1:a5d963a3c298 84 int DS4424::read_raw(int32_t &result, ChannelRegAddr_e chan_addr)
phonemacro 0:8002303900e6 85 {
phonemacro 0:8002303900e6 86 uint8_t value;
phonemacro 0:8002303900e6 87 int ret = DS4424_ERROR;
phonemacro 0:8002303900e6 88 union ds4424_raw_data raw;
phonemacro 0:8002303900e6 89
phonemacro 0:8002303900e6 90 if (chan_addr >= REG_OUT0 && chan_addr <= m_max_ch_reg_addr)
phonemacro 5:fc75fced724f 91 ret = read_register(value, chan_addr);
phonemacro 0:8002303900e6 92 if (ret != 0)
phonemacro 0:8002303900e6 93 return DS4424_ERROR;
phonemacro 0:8002303900e6 94
phonemacro 0:8002303900e6 95
phonemacro 0:8002303900e6 96 raw.bits = value;
phonemacro 0:8002303900e6 97 result = raw.dx;
phonemacro 2:b7a81b724561 98 if (raw.source_bit == DS4424_SINK_I) /** Sinking will be negative values */
phonemacro 0:8002303900e6 99 result = -result;
phonemacro 0:8002303900e6 100 return DS4424_NO_ERROR;
phonemacro 0:8002303900e6 101
phonemacro 0:8002303900e6 102 }
phonemacro 0:8002303900e6 103
phonemacro 0:8002303900e6 104
phonemacro 5:fc75fced724f 105
phonemacro 5:fc75fced724f 106 /******************************************************************************/
phonemacro 5:fc75fced724f 107 int DS4424::read_hw_raw(uint8_t &result, ChannelRegAddr_e chan_addr)
phonemacro 5:fc75fced724f 108 {
phonemacro 5:fc75fced724f 109 uint8_t value;
phonemacro 5:fc75fced724f 110 int ret = DS4424_ERROR;
phonemacro 5:fc75fced724f 111
phonemacro 5:fc75fced724f 112 if (chan_addr >= REG_OUT0 && chan_addr <= m_max_ch_reg_addr)
phonemacro 5:fc75fced724f 113 ret = read_register(value, chan_addr);
phonemacro 5:fc75fced724f 114 if (ret != 0)
phonemacro 5:fc75fced724f 115 return DS4424_ERROR;
phonemacro 5:fc75fced724f 116
phonemacro 5:fc75fced724f 117 result = value;
phonemacro 5:fc75fced724f 118 return DS4424_NO_ERROR;
phonemacro 5:fc75fced724f 119 }
phonemacro 5:fc75fced724f 120
phonemacro 5:fc75fced724f 121
phonemacro 4:3824afaf0d61 122 /******************************************************************************/
phonemacro 1:a5d963a3c298 123 int DS4424::write_raw(int32_t value, ChannelRegAddr_e chan_addr)
phonemacro 0:8002303900e6 124 {
phonemacro 0:8002303900e6 125 #define U8_MAX ((uint8_t)~0U)
phonemacro 0:8002303900e6 126 #define S8_MAX ((int8_t)(U8_MAX>>1))
phonemacro 0:8002303900e6 127 #define S8_MIN ((int8_t)(-S8_MAX - 1))
phonemacro 0:8002303900e6 128 int ret = DS4424_ERROR;
phonemacro 0:8002303900e6 129 union ds4424_raw_data raw;
phonemacro 0:8002303900e6 130
phonemacro 0:8002303900e6 131 if ((chan_addr >= REG_OUT0 && chan_addr <= m_max_ch_reg_addr) &&
phonemacro 0:8002303900e6 132 (value >= S8_MIN && value <= S8_MAX)) {
phonemacro 0:8002303900e6 133 if (value > 0) {
phonemacro 0:8002303900e6 134 raw.source_bit = DS4424_SOURCE_I;
phonemacro 0:8002303900e6 135 raw.dx = value;
phonemacro 0:8002303900e6 136 } else {
phonemacro 0:8002303900e6 137 raw.source_bit = DS4424_SINK_I;
phonemacro 0:8002303900e6 138 raw.dx = -value;
phonemacro 0:8002303900e6 139 }
phonemacro 1:a5d963a3c298 140 ret = write_register(chan_addr, raw.bits);
phonemacro 0:8002303900e6 141
phonemacro 0:8002303900e6 142 if (ret != 0)
phonemacro 0:8002303900e6 143 return DS4424_ERROR;
phonemacro 0:8002303900e6 144 return DS4424_NO_ERROR;
phonemacro 0:8002303900e6 145 } else {
phonemacro 0:8002303900e6 146 return DS4424_ERROR;
phonemacro 0:8002303900e6 147 }
phonemacro 0:8002303900e6 148 }
phonemacro 0:8002303900e6 149
phonemacro 5:fc75fced724f 150
phonemacro 5:fc75fced724f 151
phonemacro 5:fc75fced724f 152 /******************************************************************************/
phonemacro 5:fc75fced724f 153 int DS4424::write_hw_raw(uint8_t value, ChannelRegAddr_e chan_addr)
phonemacro 5:fc75fced724f 154 {
phonemacro 5:fc75fced724f 155 int ret = DS4424_ERROR;
phonemacro 5:fc75fced724f 156 if (chan_addr >= REG_OUT0 && chan_addr <= m_max_ch_reg_addr) {
phonemacro 5:fc75fced724f 157 ret = write_register(chan_addr, value);
phonemacro 0:8002303900e6 158
phonemacro 5:fc75fced724f 159 if (ret != 0)
phonemacro 5:fc75fced724f 160 return DS4424_ERROR;
phonemacro 5:fc75fced724f 161 return DS4424_NO_ERROR;
phonemacro 5:fc75fced724f 162 } else {
phonemacro 5:fc75fced724f 163 return DS4424_ERROR;
phonemacro 5:fc75fced724f 164 }
phonemacro 5:fc75fced724f 165 }
phonemacro 5:fc75fced724f 166
phonemacro 5:fc75fced724f 167
phonemacro 4:3824afaf0d61 168 /******************************************************************************/
phonemacro 5:fc75fced724f 169 int DS4424::convert_picoAmps_to_hw_raw(uint8_t *val_out,
phonemacro 5:fc75fced724f 170 int32_t picoAmps, uint32_t rfs_resistor)
phonemacro 5:fc75fced724f 171 {
phonemacro 5:fc75fced724f 172 uint32_t val, tmp_scale, round_up;
phonemacro 5:fc75fced724f 173 union ds4424_raw_data raw;
phonemacro 5:fc75fced724f 174
phonemacro 5:fc75fced724f 175 /* val can be 0 to 200,000,000 (200 picoAmps) */
phonemacro 5:fc75fced724f 176 val = picoAmps;
phonemacro 5:fc75fced724f 177 raw.source_bit = DS4424_SOURCE_I;
phonemacro 5:fc75fced724f 178 if (picoAmps < 0) {
phonemacro 5:fc75fced724f 179 raw.source_bit = DS4424_SINK_I;
phonemacro 5:fc75fced724f 180 val = -picoAmps;
phonemacro 5:fc75fced724f 181 }
phonemacro 5:fc75fced724f 182 if (val > DS4424_MAX_PICOAMPS ||
phonemacro 5:fc75fced724f 183 rfs_resistor < DS4424_MIN_RFS ||
phonemacro 5:fc75fced724f 184 rfs_resistor > DS4424_MAX_RFS)
phonemacro 5:fc75fced724f 185 return DS4424_ERROR;
phonemacro 5:fc75fced724f 186 rfs_resistor /= 100;
phonemacro 5:fc75fced724f 187 val = val / 1000;
phonemacro 5:fc75fced724f 188
phonemacro 5:fc75fced724f 189 tmp_scale = DS4424_IFS_SCALE / 10;
phonemacro 5:fc75fced724f 190 round_up = tmp_scale / 2;
phonemacro 5:fc75fced724f 191 val = ((val * rfs_resistor) + round_up) /
phonemacro 5:fc75fced724f 192 tmp_scale;
phonemacro 5:fc75fced724f 193
phonemacro 5:fc75fced724f 194 val = val / 100;
phonemacro 5:fc75fced724f 195 if (val > DS4424_S8_MAX) {
phonemacro 5:fc75fced724f 196 printf("%s : Requested current %d\r\n",
phonemacro 5:fc75fced724f 197 __func__, val);
phonemacro 5:fc75fced724f 198 printf("exceeds maximum. DAC set to maximum %d\n\r\n",
phonemacro 5:fc75fced724f 199 DS4424_S8_MAX);
phonemacro 5:fc75fced724f 200 val = DS4424_S8_MAX;
phonemacro 5:fc75fced724f 201 }
phonemacro 5:fc75fced724f 202 raw.dx = val;
phonemacro 5:fc75fced724f 203 *val_out = raw.bits;
phonemacro 5:fc75fced724f 204 return DS4424_NO_ERROR;
phonemacro 5:fc75fced724f 205
phonemacro 5:fc75fced724f 206 }
phonemacro 5:fc75fced724f 207
phonemacro 5:fc75fced724f 208
phonemacro 5:fc75fced724f 209 /******************************************************************************/
phonemacro 5:fc75fced724f 210 int DS4424::convert_raw_to_picoAmps(int32_t *val_out,
phonemacro 5:fc75fced724f 211 int8_t raw_in, uint32_t rfs_resistor)
phonemacro 5:fc75fced724f 212 {
phonemacro 5:fc75fced724f 213 uint32_t round_up;
phonemacro 5:fc75fced724f 214 union ds4424_raw_data raw;
phonemacro 5:fc75fced724f 215 if (rfs_resistor < DS4424_MIN_RFS || rfs_resistor > DS4424_MAX_RFS) {
phonemacro 5:fc75fced724f 216 return DS4424_ERROR;
phonemacro 5:fc75fced724f 217 }
phonemacro 5:fc75fced724f 218 rfs_resistor /= 100;
phonemacro 5:fc75fced724f 219
phonemacro 5:fc75fced724f 220 raw.bits = raw_in;
phonemacro 5:fc75fced724f 221 *val_out = DS4424_IFS_SCALE * raw.dx * 10;
phonemacro 5:fc75fced724f 222 round_up = rfs_resistor / 2;
phonemacro 5:fc75fced724f 223 *val_out = (*val_out + round_up) / rfs_resistor;
phonemacro 5:fc75fced724f 224
phonemacro 5:fc75fced724f 225 if (raw.source_bit == DS4424_SINK_I)
phonemacro 5:fc75fced724f 226 *val_out = -*val_out; /* this routine use negatives if sinking */
phonemacro 5:fc75fced724f 227 *val_out = *val_out * 1000; /* picoAmps */
phonemacro 5:fc75fced724f 228 return DS4424_NO_ERROR;
phonemacro 5:fc75fced724f 229 }
phonemacro 5:fc75fced724f 230
phonemacro 5:fc75fced724f 231
phonemacro 5:fc75fced724f 232 /******************************************************************************/
phonemacro 5:fc75fced724f 233 int DS4424::read_register(uint8_t &value, ChannelRegAddr_e reg)
phonemacro 0:8002303900e6 234 {
phonemacro 0:8002303900e6 235 int32_t ret;
phonemacro 0:8002303900e6 236
phonemacro 0:8002303900e6 237 char data = reg;
phonemacro 0:8002303900e6 238
phonemacro 0:8002303900e6 239 ret = m_i2c.write(m_writeAddress, &data, sizeof(data));
phonemacro 0:8002303900e6 240 if (ret != 0) {
phonemacro 0:8002303900e6 241 printf("%s - failed - ret: %d reg: %d data: %d sizeof(data): %d\r\n", __func__, ret, (int)reg, data, sizeof(data));
phonemacro 0:8002303900e6 242 return DS4424_ERROR;
phonemacro 0:8002303900e6 243 }
phonemacro 0:8002303900e6 244
phonemacro 0:8002303900e6 245 ret = m_i2c.read(m_readAddress, &data, sizeof(data));
phonemacro 0:8002303900e6 246 if (ret != 0) {
phonemacro 0:8002303900e6 247 printf("%s - failed - ret: %d\r\n", __func__, ret);
phonemacro 0:8002303900e6 248 return DS4424_ERROR;
phonemacro 0:8002303900e6 249 }
phonemacro 1:a5d963a3c298 250
phonemacro 0:8002303900e6 251 value = data;
phonemacro 0:8002303900e6 252 return DS4424_NO_ERROR;
phonemacro 0:8002303900e6 253
phonemacro 0:8002303900e6 254 }
phonemacro 0:8002303900e6 255
phonemacro 0:8002303900e6 256
phonemacro 4:3824afaf0d61 257 /******************************************************************************/
phonemacro 1:a5d963a3c298 258 int DS4424::write_register(ChannelRegAddr_e reg, uint8_t value)
phonemacro 0:8002303900e6 259 {
phonemacro 0:8002303900e6 260
phonemacro 0:8002303900e6 261 int32_t ret;
phonemacro 0:8002303900e6 262
phonemacro 0:8002303900e6 263 char cmdData[] = {static_cast<char>(reg), static_cast<char>(value)};
phonemacro 0:8002303900e6 264
phonemacro 0:8002303900e6 265 ret = m_i2c.write(m_writeAddress, cmdData, sizeof(cmdData));
phonemacro 0:8002303900e6 266
phonemacro 0:8002303900e6 267 if (ret != 0)
phonemacro 0:8002303900e6 268 return DS4424_ERROR;
phonemacro 0:8002303900e6 269
phonemacro 0:8002303900e6 270 return DS4424_NO_ERROR;
phonemacro 0:8002303900e6 271 }