mirror of
https://github.com/Architeuthis-Flux/JumperlessV5.git
synced 2025-12-24 19:36:48 +00:00
183 lines
5.3 KiB
C++
183 lines
5.3 KiB
C++
|
|
/*!
|
|
* @file Adafruit_MCP4728.cpp
|
|
*
|
|
* @mainpage Adafruit MCP4728 4-Channel 12-Bit I2C DAC library
|
|
*
|
|
* @section intro_sec Introduction
|
|
*
|
|
* I2C Driver for the Adafruit MCP4728 4-Channel 12-Bit I2C DAC library
|
|
*
|
|
* This is a library for the Adafruit MCP4728 breakout:
|
|
* https://www.adafruit.com/product/4470
|
|
*
|
|
* Adafruit invests time and resources providing this open source code,
|
|
* please support Adafruit and open-source hardware by purchasing products from
|
|
* Adafruit!
|
|
*
|
|
* @section dependencies Dependencies
|
|
* This library depends on the Adafruit BusIO library
|
|
*
|
|
*
|
|
* @section author Author
|
|
*
|
|
* Bryan Siepert for Adafruit Industries
|
|
*
|
|
* @section license License
|
|
*
|
|
* BSD (see license.txt)
|
|
*
|
|
* @section HISTORY
|
|
*
|
|
* v1.0 - First release
|
|
*/
|
|
|
|
#include "Adafruit_MCP4728.h"
|
|
#include "Arduino.h"
|
|
#include <Wire.h>
|
|
|
|
/*!
|
|
* @brief Instantiates a new MCP4728 class
|
|
*/
|
|
Adafruit_MCP4728::Adafruit_MCP4728(void) {}
|
|
|
|
/*!
|
|
* @brief Sets up the hardware and initializes I2C
|
|
* @param i2c_address
|
|
* The I2C address to be used.
|
|
* @param wire
|
|
* The Wire object to be used for I2C connections.
|
|
* @return True if initialization was successful, otherwise false.
|
|
*/
|
|
boolean Adafruit_MCP4728::begin(uint8_t i2c_address, TwoWire *wire) {
|
|
i2c_dev = new Adafruit_I2CDevice(i2c_address, wire);
|
|
|
|
if (!i2c_dev->begin()) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the input register for a given channel to the specified settings
|
|
*
|
|
* @param channel The channel to update
|
|
* @param new_value The new value to assign
|
|
* @param new_vref Optional vref setting - Defaults to `MCP4728_VREF_VDD`
|
|
* @param new_gain Optional gain setting - Defaults to `MCP4728_GAIN_1X`
|
|
* @param new_pd_mode Optional power down mode setting - Defaults to
|
|
* `MCP4728_PD_MOOE_NORMAL`
|
|
* @param udac Optional UDAC setting - Defaults to `false`, latching
|
|
* immediately. Set to `true` to latch when the LDAC pin is pulled low
|
|
*
|
|
* @return true if the write was successful
|
|
* @return false if there was an error with I2C communication between the MCU
|
|
* and the DAC
|
|
*/
|
|
bool Adafruit_MCP4728::setChannelValue(
|
|
MCP4728_channel_t channel, uint16_t new_value, MCP4728_vref_t new_vref,
|
|
MCP4728_gain_t new_gain, MCP4728_pd_mode_t new_pd_mode, bool udac) {
|
|
|
|
uint8_t output_buffer[3];
|
|
|
|
// build the setter header/ "address"
|
|
// 0 1 0 0 0 DAC1 DAC0 UDAC[A]
|
|
uint8_t sequential_write_cmd = MCP4728_MULTI_IR_CMD;
|
|
sequential_write_cmd |= (channel << 1);
|
|
sequential_write_cmd |= udac;
|
|
|
|
output_buffer[0] = sequential_write_cmd;
|
|
// VREF PD1 PD0 Gx D11 D10 D9 D8 [A] D7 D6 D5 D4 D3 D2 D1 D0 [A]
|
|
new_value |= (new_vref << 15);
|
|
new_value |= (new_pd_mode << 13);
|
|
new_value |= (new_gain << 12);
|
|
|
|
output_buffer[1] = new_value >> 8;
|
|
output_buffer[2] = new_value & 0xFF;
|
|
|
|
if (!i2c_dev->write(output_buffer, 3)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
/**
|
|
* @brief Set the values of all four channels simultaneously with minimal delay
|
|
* or configuration
|
|
*
|
|
* @param channel_a_value The value to assign to channel A
|
|
* @param channel_b_value The value to assign to channel B
|
|
* @param channel_c_value The value to assign to channel C
|
|
* @param channel_d_value The value to assign to channel D
|
|
* @return true if the write was successful
|
|
* @return false if there was an error with I2C communication between the MCU
|
|
* and the DAC
|
|
*/
|
|
bool Adafruit_MCP4728::fastWrite(uint16_t channel_a_value,
|
|
uint16_t channel_b_value,
|
|
uint16_t channel_c_value,
|
|
uint16_t channel_d_value) {
|
|
|
|
uint8_t output_buffer[8];
|
|
|
|
output_buffer[0] = channel_a_value >> 8;
|
|
output_buffer[1] = channel_a_value & 0xFF;
|
|
|
|
output_buffer[2] = channel_b_value >> 8;
|
|
output_buffer[3] = channel_b_value & 0xFF;
|
|
|
|
output_buffer[4] = channel_c_value >> 8;
|
|
output_buffer[5] = channel_c_value & 0xFF;
|
|
|
|
output_buffer[6] = channel_d_value >> 8;
|
|
output_buffer[7] = channel_d_value & 0xFF;
|
|
|
|
if (!i2c_dev->write(output_buffer, 8)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @brief Saves the DAC's input register settings to the internal EEPROM,
|
|
* makeing them the default values when the ADC is powered on
|
|
*
|
|
* @return true if the write was successful
|
|
* @return false if there was an error with I2C communication between the MCU
|
|
* and the DAC */
|
|
|
|
bool Adafruit_MCP4728::saveToEEPROM(void) {
|
|
uint8_t input_buffer[24];
|
|
uint8_t output_buffer[9];
|
|
|
|
i2c_dev->read(input_buffer, 24);
|
|
|
|
// build header byte 0 1 0 1 0 DAC1 DAC0 UDAC [A]
|
|
uint8_t eeprom_write_cmd = MCP4728_MULTI_EEPROM_CMD; // 0 1 0 1 0 xxx
|
|
eeprom_write_cmd |=
|
|
(MCP4728_CHANNEL_A << 1); // DAC1 DAC0, start at channel A obvs
|
|
eeprom_write_cmd |= 0; // UDAC ; yes, latch please
|
|
// First byte is the write command+options
|
|
output_buffer[0] = eeprom_write_cmd;
|
|
|
|
// copy the incoming input register bytes to the outgoing buffer
|
|
// Channel A
|
|
output_buffer[1] = input_buffer[1];
|
|
output_buffer[2] = input_buffer[2];
|
|
// Channel B
|
|
output_buffer[3] = input_buffer[7];
|
|
output_buffer[4] = input_buffer[8];
|
|
// Channel C
|
|
output_buffer[5] = input_buffer[13];
|
|
output_buffer[6] = input_buffer[14];
|
|
// Channel D
|
|
output_buffer[7] = input_buffer[19];
|
|
output_buffer[8] = input_buffer[20];
|
|
|
|
if (!i2c_dev->write(output_buffer, 9)) {
|
|
return false;
|
|
}
|
|
delay(15);
|
|
return true;
|
|
}
|