|
|
@ -32,16 +32,18 @@ |
|
|
|
|
|
|
|
#include "../../inc/MarlinConfig.h" |
|
|
|
|
|
|
|
#if ENABLED(DAC_STEPPER_CURRENT) |
|
|
|
#if ENABLED(HAS_MOTOR_CURRENT_DAC) |
|
|
|
|
|
|
|
#include "dac_mcp4728.h" |
|
|
|
|
|
|
|
xyze_uint_t mcp4728_values; |
|
|
|
MCP4728 mcp4728; |
|
|
|
|
|
|
|
xyze_uint_t dac_values; |
|
|
|
|
|
|
|
/**
|
|
|
|
* Begin I2C, get current values (input register and eeprom) of mcp4728 |
|
|
|
*/ |
|
|
|
void mcp4728_init() { |
|
|
|
void MCP4728::init() { |
|
|
|
Wire.begin(); |
|
|
|
Wire.requestFrom(I2C_ADDRESS(DAC_DEV_ADDRESS), uint8_t(24)); |
|
|
|
while (Wire.available()) { |
|
|
@ -50,7 +52,7 @@ void mcp4728_init() { |
|
|
|
loByte = Wire.read(); |
|
|
|
|
|
|
|
if (!(deviceID & 0x08)) |
|
|
|
mcp4728_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte); |
|
|
|
dac_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -58,9 +60,9 @@ void mcp4728_init() { |
|
|
|
* Write input resister value to specified channel using fastwrite method. |
|
|
|
* Channel : 0-3, Values : 0-4095 |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) { |
|
|
|
mcp4728_values[channel] = value; |
|
|
|
return mcp4728_fastWrite(); |
|
|
|
uint8_t MCP4728::analogWrite(const uint8_t channel, const uint16_t value) { |
|
|
|
dac_values[channel] = value; |
|
|
|
return fastWrite(); |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
@ -68,12 +70,12 @@ uint8_t mcp4728_analogWrite(const uint8_t channel, const uint16_t value) { |
|
|
|
* This will update both input register and EEPROM value |
|
|
|
* This will also write current Vref, PowerDown, Gain settings to EEPROM |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_eepromWrite() { |
|
|
|
uint8_t MCP4728::eepromWrite() { |
|
|
|
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); |
|
|
|
Wire.write(SEQWRITE); |
|
|
|
LOOP_XYZE(i) { |
|
|
|
Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[i])); |
|
|
|
Wire.write(lowByte(mcp4728_values[i])); |
|
|
|
Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(dac_values[i])); |
|
|
|
Wire.write(lowByte(dac_values[i])); |
|
|
|
} |
|
|
|
return Wire.endTransmission(); |
|
|
|
} |
|
|
@ -81,7 +83,7 @@ uint8_t mcp4728_eepromWrite() { |
|
|
|
/**
|
|
|
|
* Write Voltage reference setting to all input regiters |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_setVref_all(const uint8_t value) { |
|
|
|
uint8_t MCP4728::setVref_all(const uint8_t value) { |
|
|
|
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); |
|
|
|
Wire.write(VREFWRITE | (value ? 0x0F : 0x00)); |
|
|
|
return Wire.endTransmission(); |
|
|
@ -89,7 +91,7 @@ uint8_t mcp4728_setVref_all(const uint8_t value) { |
|
|
|
/**
|
|
|
|
* Write Gain setting to all input regiters |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_setGain_all(const uint8_t value) { |
|
|
|
uint8_t MCP4728::setGain_all(const uint8_t value) { |
|
|
|
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); |
|
|
|
Wire.write(GAINWRITE | (value ? 0x0F : 0x00)); |
|
|
|
return Wire.endTransmission(); |
|
|
@ -98,16 +100,16 @@ uint8_t mcp4728_setGain_all(const uint8_t value) { |
|
|
|
/**
|
|
|
|
* Return Input Register value |
|
|
|
*/ |
|
|
|
uint16_t mcp4728_getValue(const uint8_t channel) { return mcp4728_values[channel]; } |
|
|
|
uint16_t MCP4728::getValue(const uint8_t channel) { return dac_values[channel]; } |
|
|
|
|
|
|
|
#if 0 |
|
|
|
/**
|
|
|
|
* Steph: Might be useful in the future |
|
|
|
* Return Vout |
|
|
|
*/ |
|
|
|
uint16_t mcp4728_getVout(const uint8_t channel) { |
|
|
|
uint16_t MCP4728::getVout(const uint8_t channel) { |
|
|
|
const uint32_t vref = 2048, |
|
|
|
vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; |
|
|
|
vOut = (vref * dac_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096; |
|
|
|
return _MIN(vOut, defaultVDD); |
|
|
|
} |
|
|
|
#endif |
|
|
@ -115,15 +117,15 @@ uint16_t mcp4728_getVout(const uint8_t channel) { |
|
|
|
/**
|
|
|
|
* Returns DAC values as a 0-100 percentage of drive strength |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_getDrvPct(const uint8_t channel) { return uint8_t(100.0 * mcp4728_values[channel] / (DAC_STEPPER_MAX) + 0.5); } |
|
|
|
uint8_t MCP4728::getDrvPct(const uint8_t channel) { return uint8_t(100.0 * dac_values[channel] / (DAC_STEPPER_MAX) + 0.5); } |
|
|
|
|
|
|
|
/**
|
|
|
|
* Receives all Drive strengths as 0-100 percent values, updates |
|
|
|
* DAC Values array and calls fastwrite to update the DAC. |
|
|
|
*/ |
|
|
|
void mcp4728_setDrvPct(xyze_uint8_t &pct) { |
|
|
|
mcp4728_values *= 0.01 * pct * (DAC_STEPPER_MAX); |
|
|
|
mcp4728_fastWrite(); |
|
|
|
void MCP4728::setDrvPct(xyze_uint8_t &pct) { |
|
|
|
dac_values *= 0.01 * pct * (DAC_STEPPER_MAX); |
|
|
|
fastWrite(); |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
@ -131,11 +133,11 @@ void mcp4728_setDrvPct(xyze_uint8_t &pct) { |
|
|
|
* DAC Input and PowerDown bits update. |
|
|
|
* No EEPROM update |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_fastWrite() { |
|
|
|
uint8_t MCP4728::fastWrite() { |
|
|
|
Wire.beginTransmission(I2C_ADDRESS(DAC_DEV_ADDRESS)); |
|
|
|
LOOP_XYZE(i) { |
|
|
|
Wire.write(highByte(mcp4728_values[i])); |
|
|
|
Wire.write(lowByte(mcp4728_values[i])); |
|
|
|
Wire.write(highByte(dac_values[i])); |
|
|
|
Wire.write(lowByte(dac_values[i])); |
|
|
|
} |
|
|
|
return Wire.endTransmission(); |
|
|
|
} |
|
|
@ -143,10 +145,10 @@ uint8_t mcp4728_fastWrite() { |
|
|
|
/**
|
|
|
|
* Common function for simple general commands |
|
|
|
*/ |
|
|
|
uint8_t mcp4728_simpleCommand(const byte simpleCommand) { |
|
|
|
uint8_t MCP4728::simpleCommand(const byte simpleCommand) { |
|
|
|
Wire.beginTransmission(I2C_ADDRESS(GENERALCALL)); |
|
|
|
Wire.write(simpleCommand); |
|
|
|
return Wire.endTransmission(); |
|
|
|
} |
|
|
|
|
|
|
|
#endif // DAC_STEPPER_CURRENT
|
|
|
|
#endif // HAS_MOTOR_CURRENT_DAC
|
|
|
|