mirror of
https://github.com/Architeuthis-Flux/Jumperless.git
synced 2025-01-31 04:03:46 +01:00
DACs and bridge App
This commit is contained in:
parent
ec010a16f6
commit
4f4d285e37
Binary file not shown.
Binary file not shown.
10
JumperlessNano/.vscode/extensions 2.json
vendored
10
JumperlessNano/.vscode/extensions 2.json
vendored
@ -1,10 +0,0 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
455
JumperlessNano/lib/mcp4725/mcp4725.cpp
Normal file
455
JumperlessNano/lib/mcp4725/mcp4725.cpp
Normal file
@ -0,0 +1,455 @@
|
||||
/*!
|
||||
@file mcp4725.cpp
|
||||
@author Gavin Lyons
|
||||
@brief MCP4725 DAC library cpp file.
|
||||
*/
|
||||
|
||||
#include "mcp4725.hpp"
|
||||
|
||||
|
||||
/*!
|
||||
@brief Constructor for class MCP4725_PIC0
|
||||
@param refV The the reference voltage to be set in Volts.
|
||||
*/
|
||||
MCP4725_PICO::MCP4725_PICO(float refV)
|
||||
{
|
||||
setReferenceVoltage(refV);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Init & config i2c
|
||||
@param addr I2C address 8 bit address 0x6?.
|
||||
@param i2c_type I2C instance of port, IC20 or I2C1.
|
||||
@param CLKspeed I2C Bus Clock speed in Kbit/s. see 7.1 datasheet
|
||||
@param SDApin I2C Data GPIO
|
||||
@param SCLKpin I2C Clock GPIO
|
||||
@return true if success , false for failure
|
||||
*/
|
||||
bool MCP4725_PICO::begin(MCP4725_I2C_Addr_e addr, i2c_inst_t* i2c_type, uint16_t CLKspeed, uint8_t SDApin, uint8_t SCLKpin)
|
||||
{
|
||||
uint8_t rxData = 0;
|
||||
|
||||
// init I2c pins and interface
|
||||
_i2cAddress = addr;
|
||||
_i2c = i2c_type;
|
||||
_SClkPin = SCLKpin;
|
||||
_SDataPin = SDApin;
|
||||
_CLKSpeed = CLKspeed;
|
||||
gpio_set_function(_SDataPin, GPIO_FUNC_I2C);
|
||||
gpio_set_function(_SClkPin, GPIO_FUNC_I2C);
|
||||
gpio_pull_up(_SDataPin);
|
||||
gpio_pull_up(_SClkPin);
|
||||
i2c_init(_i2c, _CLKSpeed * 1000);
|
||||
busy_wait_ms(50);
|
||||
// check connection?
|
||||
return isConnected();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Switch off the I2C interface and return I2C GPIO to default state
|
||||
*/
|
||||
void MCP4725_PICO::deinitI2C()
|
||||
{
|
||||
gpio_set_function(_SDataPin, GPIO_FUNC_NULL);
|
||||
gpio_set_function(_SClkPin, GPIO_FUNC_NULL);
|
||||
i2c_deinit(_i2c);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Checks if DAC is connected.
|
||||
@return true if DAC is connected , false if not
|
||||
*/
|
||||
bool MCP4725_PICO::isConnected()
|
||||
{
|
||||
int ReturnCode = 0;
|
||||
uint8_t rxData = 0;
|
||||
// check connection?
|
||||
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress , &rxData, 1, false, MCP4725_I2C_DELAY);
|
||||
if (ReturnCode < 1){ // no bytes read back from device or error issued
|
||||
if (_serialDebug == true)
|
||||
{
|
||||
printf("1202 PICO_MCP4725::is connected: \r\n");
|
||||
printf("Check Connection, Return code :: %d ,RX data :: %u \r\n", ReturnCode , rxData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Sets the reference voltage.
|
||||
@param voltage the reference voltage to be set, called from constructor.
|
||||
*/
|
||||
void MCP4725_PICO::setReferenceVoltage(float voltage)
|
||||
{
|
||||
if (voltage == 0)
|
||||
_refVoltage = MCP4725_REFERENCE_VOLTAGE;
|
||||
else
|
||||
_refVoltage = voltage;
|
||||
|
||||
_bitsPerVolt = (float)MCP4725_STEPS / _refVoltage;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Gets the reference voltage.
|
||||
@return The reference voltage in volts.
|
||||
*/
|
||||
float MCP4725_PICO::getReferenceVoltage(){return _refVoltage;}
|
||||
|
||||
/*!
|
||||
@brief Set voltage out based on DAC input code.
|
||||
@param InputCode 0 to MCP4725_MAX_VALUE.
|
||||
@param mode MCP4725DAC mode, see enum MCP4725_CmdType_e.
|
||||
@param powerType MCP4725DAC power type, see enum MCP4725_PowerType_e
|
||||
@return output of writeCommand method, true for success, false for failure.
|
||||
*/
|
||||
bool MCP4725_PICO::setInputCode(uint16_t InputCode, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType)
|
||||
{
|
||||
if (_safetyCheck == true)
|
||||
{
|
||||
if (InputCode > MCP4725_MAX_VALUE)
|
||||
InputCode = MCP4725_MAX_VALUE;
|
||||
}
|
||||
|
||||
return writeCommand(InputCode, mode, powerType);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Set voltage out based on voltage input in volts.
|
||||
@param voltage 0 to_MCP4725_REFERENCE_VOLTAGE, voltage out
|
||||
@param mode MCP4725DAC mode, see enum MCP4725_CmdType_e.
|
||||
@param powerType MCP4725DAC power type, see enum MCP4725_PowerType_e
|
||||
@return output of writeCommand method, true for success, false for failure.
|
||||
*/
|
||||
bool MCP4725_PICO::setVoltage(float voltage, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType)
|
||||
{
|
||||
uint16_t voltageValue = 0;
|
||||
|
||||
// Convert voltage to DAC bits
|
||||
//xx,xx,xx,xx,D11,D10,D9,D8 ,D7,D6,D4,D3,D2,D9,D1,D0
|
||||
if (_safetyCheck == true)
|
||||
{
|
||||
if (voltage >= _refVoltage)
|
||||
voltageValue = MCP4725_MAX_VALUE;
|
||||
else if (voltage <= 0)
|
||||
voltageValue = 0; //make sure value never below zero
|
||||
else
|
||||
voltageValue = voltage * _bitsPerVolt;
|
||||
}
|
||||
else if (_safetyCheck == false)
|
||||
{
|
||||
voltageValue = voltage * _bitsPerVolt;
|
||||
}
|
||||
|
||||
return writeCommand(voltageValue, mode, powerType);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief get current DAC InputCode from DAC register
|
||||
@return DAC InputCode :or 0xFFFF if I2C error
|
||||
*/
|
||||
uint16_t MCP4725_PICO::getInputCode()
|
||||
{
|
||||
uint16_t inputCode = readRegister(MCP4725_ReadDACReg);
|
||||
// InputCode = D11,D10,D9,D8,D7,D6,D5,D4, D3,D2,D1,D0,x,x,x,x
|
||||
|
||||
if (inputCode != MCP4725_ERROR)
|
||||
return inputCode >> 4; //0,0,0,0,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
|
||||
else
|
||||
return inputCode; // i2c Error return 0xFFFF
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief get DAC inputCode from DAC register & convert to volts
|
||||
@return DAC voltage or 0xFFFF if I2C error
|
||||
*/
|
||||
float MCP4725_PICO::getVoltage()
|
||||
{
|
||||
float InputCode = getInputCode();
|
||||
if (InputCode != MCP4725_ERROR)
|
||||
return InputCode / _bitsPerVolt;
|
||||
else
|
||||
return InputCode; // i2c Error return 0xFFFF
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Read DAC inputCode from EEPROM
|
||||
@return stored EEPROM inputcode value or 0xFFFF if I2C error
|
||||
*/
|
||||
uint16_t MCP4725_PICO::getStoredInputCode()
|
||||
{
|
||||
uint16_t inputCode = readRegister(MCP4725_ReadEEPROM);
|
||||
//InputCode = x,PD1,PD0,x,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
|
||||
|
||||
if (inputCode != MCP4725_ERROR)
|
||||
return inputCode & 0x0FFF; //0,0,0,0,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
|
||||
else
|
||||
return inputCode; // i2c Error return 0xFFFF
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief Read stored DAC InputCode from EEPROM & convert to voltage
|
||||
@return stored EEPROM voltage or 0xFFFF if I2C error
|
||||
*/
|
||||
float MCP4725_PICO::getStoredVoltage()
|
||||
{
|
||||
float InputCode = getStoredInputCode();
|
||||
|
||||
if (InputCode != MCP4725_ERROR)
|
||||
return InputCode / _bitsPerVolt;
|
||||
else
|
||||
return InputCode;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Get current power type from DAC register
|
||||
@return power type or 0xFFFF if I2C error
|
||||
@note Power type corresponds to enum MCP4725_PowerDownType_e
|
||||
*/
|
||||
uint16_t MCP4725_PICO::getPowerType()
|
||||
{
|
||||
uint16_t powerTypeValue = readRegister(MCP4725_ReadSettings);
|
||||
//powerTypeValue = BSY,POR,xx,xx,xx,PD1,PD0,xx
|
||||
|
||||
if (powerTypeValue != MCP4725_ERROR){
|
||||
powerTypeValue &= 0x0006; //00,00,00,00,00,PD1,PD0,00
|
||||
return powerTypeValue >> 1; //00,00,00,00,00,00,PD1,PD0
|
||||
}else{
|
||||
return powerTypeValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief Get stored power type from EEPROM
|
||||
@return EEPROM power type or 0xFFFF if I2C error
|
||||
@note Power type corresponds to enum MCP4725_PowerDownType_e
|
||||
*/
|
||||
uint16_t MCP4725_PICO::getStoredPowerType()
|
||||
{
|
||||
uint16_t powerTypeValue = readRegister(MCP4725_ReadEEPROM);
|
||||
//powerTypeValue = x,PD1,PD0,xx,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0
|
||||
|
||||
if (powerTypeValue != MCP4725_ERROR)
|
||||
{
|
||||
powerTypeValue = powerTypeValue << 1; //PD1,PD0,xx,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,00
|
||||
return powerTypeValue >> 14; //00,00,00,00,00,00,00,00,00,00,00,00,00,00,PD1,PD0
|
||||
}else
|
||||
{
|
||||
return powerTypeValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief get EEPROM writing status from DAC register
|
||||
@return 1 for completed or 0( busy or I2C error)
|
||||
@note The BSY bit is low (during the EEPROM writing)
|
||||
*/
|
||||
bool MCP4725_PICO::getEEPROMBusyFlag()
|
||||
{
|
||||
uint16_t registerValue = readRegister(MCP4725_ReadSettings);
|
||||
//register value = BSY,POR,xx,xx,xx,PD1,PD0,xx
|
||||
bool ReturnValue = false;
|
||||
if (registerValue != MCP4725_ERROR)
|
||||
{
|
||||
ReturnValue = ((registerValue >> 7) & 0x01);
|
||||
return ReturnValue; //1 - Not Busy, 0 - Busy
|
||||
}else
|
||||
{
|
||||
return ReturnValue; // I2C error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief Writes data to DAC register or EEPROM
|
||||
@param inputCode 0 to MCP4725_MAX_VALUE input code
|
||||
@param mode MCP4725DAC mode, see enum MCP4725_CmdType_e.
|
||||
@param PowerType MCP4725 power type, see enum MCP4725_PowerType_e
|
||||
@return true for success, false for failure.
|
||||
*/
|
||||
bool MCP4725_PICO::writeCommand(uint16_t inputCode, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType)
|
||||
{
|
||||
uint8_t dataBuffer[3];
|
||||
uint8_t lowByte = 0;
|
||||
uint8_t highByte = 0;
|
||||
int ReturnCode = 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case MCP4725_FastMode:
|
||||
//C2=0,C1=0,PD1,PD0,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0
|
||||
lowByte = (uint8_t)(inputCode & 0x00FF);
|
||||
highByte = (uint8_t)((inputCode >> 8) & 0x00FF);
|
||||
dataBuffer[0] = mode | (powerType << 4) | highByte; //C2,C1,PD1,PD0,D11,D10,D9,D8
|
||||
dataBuffer[1] = lowByte; //D7,D6,D5,D4,D3,D2,D1,D0
|
||||
ReturnCode = i2c_write_timeout_us(_i2c, _i2cAddress, dataBuffer, 2 , false, MCP4725_I2C_DELAY);
|
||||
if (ReturnCode < 1)
|
||||
{
|
||||
if (_serialDebug == true)
|
||||
{
|
||||
printf("1203 : I2C error :: WriteCommand 1 \r\n");
|
||||
printf("Tranmission code : %d \r\n", ReturnCode );
|
||||
busy_wait_ms(100);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MCP4725_RegisterMode:
|
||||
//C2=0,C1=1,C0=0,x,x,PD1,PD0,x,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,x,x,x,x
|
||||
case MCP4725_EEPROM_Mode:
|
||||
//C2=0,C1=1,C0=1,x,x,PD1,PD0,x,D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,x,x,x,x
|
||||
inputCode = inputCode << 4; //D11,D10,D9,D8,D7,D6,D5,D4,D3,D2,D1,D0,x,x,x,x
|
||||
lowByte = (uint8_t)(inputCode & 0x00FF);
|
||||
highByte = (uint8_t)((inputCode >> 8) & 0x00FF);
|
||||
dataBuffer[0] = mode | (powerType << 1); // C2,C1,C0,x,x,PD1,PD0,x
|
||||
dataBuffer[1] = highByte; // D11,D10,D9,D8,D7,D6,D5,D4
|
||||
dataBuffer[2] = lowByte; // D3,D2,D1,D0,x,x,x,x
|
||||
ReturnCode = i2c_write_timeout_us(_i2c, _i2cAddress, dataBuffer, 3 , false, MCP4725_I2C_DELAY);
|
||||
if (ReturnCode < 1)
|
||||
{
|
||||
if (_serialDebug == true)
|
||||
{
|
||||
printf("1204 : I2C error :: writeCommand 2 \r\n");
|
||||
printf("Tranmission code : %d \r\n", ReturnCode );
|
||||
busy_wait_ms(100);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode == MCP4725_EEPROM_Mode)
|
||||
{
|
||||
if (getEEPROMBusyFlag() == true)
|
||||
return true;
|
||||
busy_wait_ms(MCP4725_EEPROM_WRITE_TIME); //typical EEPROM write time 25 mSec
|
||||
if (getEEPROMBusyFlag() == true)
|
||||
return true;
|
||||
busy_wait_ms(MCP4725_EEPROM_WRITE_TIME); //maximum EEPROM write time 25*2 mSec
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Read DAC register
|
||||
@param mode MCP4725DAC datatype 1 3 or 5, see enum MCP4725_ReadType_e.
|
||||
@return Requested value of read or type 0XFFFF if I2c error
|
||||
*/
|
||||
uint16_t MCP4725_PICO::readRegister(MCP4725_ReadType_e readType)
|
||||
{
|
||||
uint16_t dataWord = readType;
|
||||
uint8_t dataBuffer[6];
|
||||
int ReturnCode = 0;
|
||||
|
||||
/*Format of read data :
|
||||
== Settings data one byte
|
||||
BSY,POR,xx,xx,xx,PD1,PD0,xx,
|
||||
== DAC register data 3 byte(1st 1 don't care)
|
||||
D11,D10,D9,D8,D7,D6,D5,D4, D3,D2,D1,D0,xx,xx,xx,xx,
|
||||
== EEPROM data 5 byte (1st 3 don't care)
|
||||
xx,PD1,PD0,xx,D11,D10,D9,D8, D7,D6,D5,D4,D3,D2,D1,D0
|
||||
*/
|
||||
switch (readType)
|
||||
{
|
||||
case MCP4725_ReadSettings: // Read one byte settings
|
||||
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress, dataBuffer, 1, false, MCP4725_I2C_DELAY);
|
||||
dataWord = dataBuffer[0];
|
||||
break;
|
||||
|
||||
case MCP4725_ReadDACReg: // Read 3 bytes DAC register data, skip first 1 don't care
|
||||
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress, dataBuffer, 3, false, MCP4725_I2C_DELAY);
|
||||
dataWord = dataBuffer[1];
|
||||
dataWord = (dataWord << 8) | dataBuffer[2];
|
||||
break;
|
||||
|
||||
case MCP4725_ReadEEPROM: // Read 5 bytes EEPROM data , first 3 don't care
|
||||
ReturnCode = i2c_read_timeout_us(_i2c, _i2cAddress, dataBuffer, 5, false, MCP4725_I2C_DELAY);
|
||||
dataWord = dataBuffer[3];
|
||||
dataWord = (dataWord << 8) | dataBuffer[4];
|
||||
break;
|
||||
}
|
||||
|
||||
if (ReturnCode < 1)
|
||||
{ // no bytes read back from device or error issued
|
||||
if (_serialDebug == true)
|
||||
{
|
||||
printf("1205 I2C Error readRegister : \r\n");
|
||||
printf("Tranmission Code :: %d\r\n", ReturnCode);
|
||||
busy_wait_ms(100);
|
||||
}
|
||||
return MCP4725_ERROR;
|
||||
}else{
|
||||
return dataWord;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief Setter for serial debug flag
|
||||
@param onOff Turns or or off the serial debug flag
|
||||
*/
|
||||
void MCP4725_PICO::setSerialDebugFlag(bool onOff){_serialDebug = onOff;}
|
||||
|
||||
/*!
|
||||
@brief Gets the serial Debug flag value
|
||||
@return The serial Debug flag value
|
||||
*/
|
||||
bool MCP4725_PICO::getSerialDebugFlag(void){return _serialDebug;}
|
||||
|
||||
/*!
|
||||
@brief Setter for safety Check flag
|
||||
@param onOff Turns or or off the safety check flag
|
||||
*/
|
||||
void MCP4725_PICO::setSafetyCheckFlag(bool onOff){_safetyCheck = onOff;}
|
||||
|
||||
/*!
|
||||
@brief Gets the safety Check flag value
|
||||
@return The safety Check flag value
|
||||
*/
|
||||
bool MCP4725_PICO::getSafetyCheckFlag(){return _safetyCheck;}
|
||||
|
||||
|
||||
/*!
|
||||
@brief General Call, name from datasheet section 7.3
|
||||
@param typeCall Reset or wakeup see MCP4725_GeneralCallType_e.
|
||||
@return True on success, false on I2c error OR wrong input(GeneralCallAddress)
|
||||
@note
|
||||
1. Reset MCP4725 & upload data from EEPROM to DAC register.
|
||||
Immediately after reset event, uploads contents of EEPROM into the DAC reg.
|
||||
2. Wake up & upload value from DAC register,
|
||||
Current power-down bits are set to normal, EEPROM power-down bit are not affected
|
||||
*/
|
||||
bool MCP4725_PICO::GeneralCall(MCP4725_GeneralCallType_e typeCall){
|
||||
|
||||
if (typeCall == MCP4725_GeneralCallAddress) {return false;}
|
||||
|
||||
int ReturnCode = 0;
|
||||
uint8_t dataBuffer[1];
|
||||
|
||||
dataBuffer[0] = (uint8_t)typeCall;
|
||||
// Note I2c address is MCP4725_GENERAL_CALL_ADDRESS
|
||||
ReturnCode = i2c_write_timeout_us(_i2c, (uint8_t)MCP4725_GeneralCallAddress, dataBuffer, 1 , false, MCP4725_I2C_DELAY);
|
||||
|
||||
if (ReturnCode < 1)
|
||||
{ // no bytes read back from device or error issued
|
||||
if (_serialDebug == true)
|
||||
{
|
||||
printf("1206 I2C Error General Call : \r\n");
|
||||
printf("Tranmission Code :: %d\r\n", ReturnCode);
|
||||
busy_wait_ms(100);
|
||||
}
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------ EOF ------------------------
|
131
JumperlessNano/lib/mcp4725/mcp4725.hpp
Normal file
131
JumperlessNano/lib/mcp4725/mcp4725.hpp
Normal file
@ -0,0 +1,131 @@
|
||||
/*!
|
||||
@file mcp4725.hpp
|
||||
@author Gavin Lyons
|
||||
@brief Library header file for MCP4725 PICO DAC library.
|
||||
|
||||
@note See URL for full details. https://github.com/gavinlyonsrepo/MCP4725_PICO
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __MCP4725_DAC_H
|
||||
#define __MCP4725_DAC_H
|
||||
|
||||
// Libraries
|
||||
#include <stdio.h> // optional for printf debug error messages
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include <cmath> // for pow() function
|
||||
|
||||
// Section Enums
|
||||
|
||||
/*! 8-bit i2c address. */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
MCP4725A0_Addr_A00 = 0x60, /**< MCP4725A0 with A0 = GND */
|
||||
MCP4725A0_Addr_A01 = 0x61, /**< MCP4725A0 with A0 = VCC */
|
||||
MCP4725A1_Addr_A00 = 0x62, /**< MCP4725A1 with A0 = GND */
|
||||
MCP4725A1_Addr_A01 = 0x63, /**< MCP4725A1 with A0 = VCC */
|
||||
MCP4725A2_Addr_A00 = 0x64, /**< MCP4725A2 with A0 = GND */
|
||||
MCP4725A2_Addr_A01 = 0x65 /**< MCP4725A2 with A0 = VCC */
|
||||
}MCP4725_I2C_Addr_e; // 8-bit i2c address
|
||||
|
||||
/*! DAC register, command bits C2C1C0 */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
MCP4725_FastMode = 0x00, /**< Writes data to DAC register */
|
||||
MCP4725_RegisterMode = 0x40, /**< Writes data & config bits to DAC register */
|
||||
MCP4725_EEPROM_Mode = 0x60 /**< Writes data & config bits to DAC register & EEPROM */
|
||||
}MCP4725_CmdType_e; // DAC register, command bits C2C1C0 */
|
||||
|
||||
/*! DAC register, power down bits PD1 PD0 , BSY,POR,xx,xx,xx,PD1,PD0,xx */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
MCP4725_PowerDown_Off = 0x00, /**< Power down off draws 0.40mA no load & 0.29mA max load */
|
||||
MCP4725_PowerDown_1kOhm = 0x01, /**< Power down on, with 1.0 kOhm to GND, draws ~60nA */
|
||||
MCP4725_PowerDown_100kOhm = 0x02, /**< Power down on, with 100 kOhm to GND */
|
||||
MCP4725_PowerDown_500kOhm = 0x03 /**< Power down on, with 500 kOhm to GND */
|
||||
}MCP4725_PowerDownType_e; // DAC register, power down bits PD1 PD0 , BSY,POR,xx,xx,xx,PD1,PD0,xx */
|
||||
|
||||
/*! DAC library read register type */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
MCP4725_ReadSettings = 1, /**< Read 1 byte, Settings data */
|
||||
MCP4725_ReadDACReg = 3, /**< Read 3 bytes, DAC register data */
|
||||
MCP4725_ReadEEPROM = 5 /**< Read 5 bytes, EEPROM data */
|
||||
}MCP4725_ReadType_e; // DAC library read register type
|
||||
|
||||
/*! DAC general call command datasheet 7.3 */
|
||||
typedef enum : uint8_t
|
||||
{
|
||||
MCP4725_GeneralCallAddress = 0x00, /**< General call address */
|
||||
MCP4725_GeneralCallReset = 0x06, /**< General call reset command */
|
||||
MCP4725_GeneralCallWakeUp = 0x09 /**< General call wake-up command */
|
||||
}MCP4725_GeneralCallType_e; // DAC general call command datasheet 7.3
|
||||
|
||||
// Section Definition's
|
||||
|
||||
// I2C interface Comms related
|
||||
#define MCP4725_I2C_DELAY 50000 /**< uS delay , I2C timeout */
|
||||
#define MCP4725_ERROR 0xFFFF /**< returns this value if I2C bus error from some methods */
|
||||
#define MCP4725_EEPROM_WRITE_TIME 25 /**< mSec Memory write time, maximum 50 mSec */
|
||||
|
||||
// DAC voltage levels
|
||||
#define MCP4725_REFERENCE_VOLTAGE 3.3 /**< supply-reference Voltage in volts */
|
||||
#define MCP4725_RESOLUTION 12 /**< resolution in bits , 12-bit */
|
||||
#define MCP4725_STEPS pow(2, (MCP4725_RESOLUTION)) /**< quantity of DAC steps 2^12-bits = 4096 */
|
||||
#define MCP4725_MAX_VALUE ((MCP4725_STEPS) - 1) /**< Max value = 4096 -1 , 0 to 4095 */
|
||||
|
||||
|
||||
/*!
|
||||
@brief Class for MCP4725_PIC0 DAC
|
||||
*/
|
||||
class MCP4725_PICO
|
||||
{
|
||||
public:
|
||||
MCP4725_PICO(float refV = MCP4725_REFERENCE_VOLTAGE);
|
||||
|
||||
bool begin(MCP4725_I2C_Addr_e addr, i2c_inst_t* type, uint16_t speed, uint8_t SDA, uint8_t SCLK);
|
||||
bool isConnected();
|
||||
bool GeneralCall(MCP4725_GeneralCallType_e);
|
||||
void deinitI2C();
|
||||
|
||||
void setReferenceVoltage(float value);
|
||||
float getReferenceVoltage(void);
|
||||
|
||||
bool setInputCode(uint16_t inputCode, MCP4725_CmdType_e = MCP4725_FastMode, MCP4725_PowerDownType_e = MCP4725_PowerDown_Off);
|
||||
uint16_t getInputCode(void);
|
||||
|
||||
bool setVoltage(float voltage, MCP4725_CmdType_e = MCP4725_FastMode, MCP4725_PowerDownType_e = MCP4725_PowerDown_Off);
|
||||
float getVoltage(void);
|
||||
|
||||
uint16_t getStoredInputCode(void);
|
||||
float getStoredVoltage(void);
|
||||
|
||||
uint16_t getPowerType(void);
|
||||
uint16_t getStoredPowerType(void);
|
||||
|
||||
void setSerialDebugFlag(bool onOff);
|
||||
bool getSerialDebugFlag(void);
|
||||
|
||||
void setSafetyCheckFlag(bool onOff);
|
||||
bool getSafetyCheckFlag(void);
|
||||
|
||||
private:
|
||||
//I2c related
|
||||
MCP4725_I2C_Addr_e _i2cAddress;
|
||||
i2c_inst_t *_i2c; // i2C port number, i2c0 or i2c1
|
||||
uint8_t _SDataPin;
|
||||
uint8_t _SClkPin;
|
||||
uint16_t _CLKSpeed = 100; // I2C bus speed in khz
|
||||
bool _serialDebug = false; // Outputs Messages for debugging to serial port true = on
|
||||
|
||||
float _refVoltage;
|
||||
uint16_t _bitsPerVolt;
|
||||
bool _safetyCheck = true; // Safety check for voltage level's , true = on
|
||||
|
||||
bool getEEPROMBusyFlag(void);
|
||||
bool writeCommand(uint16_t value, MCP4725_CmdType_e mode, MCP4725_PowerDownType_e powerType);
|
||||
uint16_t readRegister(MCP4725_ReadType_e dataType);
|
||||
};
|
||||
|
||||
#endif // library file header guard endif
|
@ -10,12 +10,11 @@
|
||||
|
||||
[env]
|
||||
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||
;platform = https://github.com/platformio/platform-raspberrypi.git
|
||||
framework = arduino
|
||||
board_build.core = earlephilhower
|
||||
board_build.filesystem_size = 0.5m
|
||||
upload_port = /dev/cu.usbmodem11301
|
||||
monitor_port = /dev/cu.usbmodem11301
|
||||
upload_port = /dev/cu.usbmodem11101
|
||||
monitor_port = /dev/cu.usbmodem11101
|
||||
extra_scripts = post:scripts/extra_script.py
|
||||
monitor_speed = 256000
|
||||
|
||||
@ -24,9 +23,7 @@ board = pico
|
||||
lib_deps =
|
||||
powerbroker2/SafeString@^4.1.27
|
||||
adafruit/Adafruit NeoPixel@^1.11.0
|
||||
adafruit/Adafruit MCP4725@^2.0.0
|
||||
adafruit/Adafruit INA219@^1.2.1
|
||||
robtillaart/MCP4725@^0.3.5
|
||||
robtillaart/INA219@^0.1.3
|
||||
bblanchon/ArduinoJson@^6.21.2
|
||||
arduino-libraries/Arduino_JSON@^0.2.0
|
||||
|
@ -73,7 +73,7 @@ void rainbowy(int saturation, int brightness, int wait)
|
||||
// saturation and value (brightness) (both 0-255, similar to the
|
||||
// ColorHSV() function, default 255), and a true/false flag for whether
|
||||
// to apply gamma correction to provide 'truer' colors (default true).
|
||||
leds.rainbow(firstPixelHue, 1, saturation, 255, true);
|
||||
leds.rainbow(firstPixelHue, 1, saturation, brightness, true);
|
||||
// Above line is equivalent to:
|
||||
// strip.rainbow(firstPixelHue, 1, 255, 255, true);
|
||||
leds.show(); // Update strip with new contents
|
||||
|
@ -16,8 +16,12 @@
|
||||
#include "ADCInput.h"
|
||||
#include "pico/cyw43_arch.h"
|
||||
|
||||
#include "mcp4725.hpp"
|
||||
|
||||
#define DAC_RESOLUTION 9
|
||||
|
||||
|
||||
|
||||
float freq[3] = {1, 1, 0};
|
||||
uint32_t period[3] = {0, 0, 0};
|
||||
uint32_t halvePeriod[3] = {0, 0, 0};
|
||||
@ -29,8 +33,12 @@ uint32_t halvePeriod[3] = {0, 0, 0};
|
||||
// r = random
|
||||
char mode[3] = {'z', 'z', 'z'};
|
||||
|
||||
MCP4725 dac0_5V(0x60, &Wire);
|
||||
MCP4725 dac1_8V(0x63, &Wire);
|
||||
MCP4725_PICO dac0_5V(5.0);
|
||||
MCP4725_PICO dac1_8V(8.0);
|
||||
|
||||
|
||||
|
||||
|
||||
INA219 INA0(0x40);
|
||||
INA219 INA1(0x41);
|
||||
|
||||
@ -85,14 +93,14 @@ adc_gpio_init(ADC2_PIN);
|
||||
|
||||
void initDAC(void)
|
||||
{
|
||||
//Wire.begin();
|
||||
dac1_8V.begin(MCP4725A1_Addr_A01, i2c0, 3000, 4,5);
|
||||
dac0_5V.begin(MCP4725A0_Addr_A00, i2c0, 3000, 4,5);
|
||||
|
||||
dac1_8V.begin(4, 5);
|
||||
dac0_5V.begin(4, 5);
|
||||
//
|
||||
|
||||
Wire.begin();
|
||||
|
||||
dac0_5V.setValue(0);
|
||||
dac1_8V.setValue(2047);
|
||||
dac0_5V.setVoltage(4.0);
|
||||
dac1_8V.setVoltage(1.0);
|
||||
|
||||
|
||||
}
|
||||
@ -139,82 +147,84 @@ void dacSine(int resolution)
|
||||
case 0 ... 5:
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
dac1_8V.setValue(DACLookup_FullSine_5Bit[i]);
|
||||
dac1_8V.setInputCode(DACLookup_FullSine_5Bit[i]);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
dac1_8V.setValue(DACLookup_FullSine_6Bit[i]);
|
||||
dac1_8V.setInputCode(DACLookup_FullSine_6Bit[i]);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
dac1_8V.setValue(DACLookup_FullSine_7Bit[i]);
|
||||
dac1_8V.setInputCode(DACLookup_FullSine_7Bit[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
dac1_8V.setValue(DACLookup_FullSine_8Bit[i]);
|
||||
dac1_8V.setInputCode(DACLookup_FullSine_8Bit[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 9 ... 12:
|
||||
for (i = 0; i < 512; i++)
|
||||
{
|
||||
dac1_8V.setValue(DACLookup_FullSine_9Bit[i]);
|
||||
dac1_8V.setInputCode(DACLookup_FullSine_9Bit[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setDac0_5V(float voltage)
|
||||
{
|
||||
uint16_t value = voltage * 819;
|
||||
//uint16_t value = voltage * 819;
|
||||
// float vPerBit = 5 / 4096;
|
||||
|
||||
// uint32_t voltage = value * vPerBit;
|
||||
|
||||
Serial.print("dac0_5V voltage: ");
|
||||
Serial.print(voltage);
|
||||
Serial.print("\tvalue: ");
|
||||
//Serial.print("dac0_5V voltage: ");
|
||||
//Serial.print(voltage);
|
||||
//Serial.print("\tvalue: ");
|
||||
|
||||
Serial.println(value);
|
||||
//Serial.println(value);
|
||||
|
||||
dac0_5V.setValue(value);
|
||||
dac0_5V.setVoltage(voltage);
|
||||
|
||||
// if (dac1_8V.setValue(value, 100000) == false)
|
||||
// if (dac1_8V.setVoltage(value, 100000) == false)
|
||||
//{
|
||||
// Serial.println("dac1_8V.setValue() failed");
|
||||
// Serial.println("dac1_8V.setVoltage() failed");
|
||||
// }
|
||||
}
|
||||
|
||||
void setDac1_8V(float voltage)
|
||||
{
|
||||
|
||||
uint16_t value = voltage * 276;
|
||||
//uint16_t value = voltage * 276;
|
||||
// float vPerBit = 5 / 4096;
|
||||
if (value >= 4095)
|
||||
{
|
||||
value = 4095;
|
||||
}
|
||||
//if (value >= 4095)
|
||||
//{
|
||||
//value = 4095;
|
||||
// }
|
||||
|
||||
// uint32_t voltage = value * vPerBit;
|
||||
|
||||
Serial.print("dac1 +-8V voltage: ");
|
||||
Serial.print(voltage / 2);
|
||||
Serial.print("\tvalue: ");
|
||||
//Serial.print("dac1 +-8V voltage: ");
|
||||
//Serial.print(voltage / 2);
|
||||
//Serial.print("\tvalue: ");
|
||||
|
||||
Serial.println(value);
|
||||
//Serial.println(value);
|
||||
|
||||
dac1_8V.setValue(value);
|
||||
dac1_8V.setVoltage(voltage);
|
||||
|
||||
// if (dac1_8V.setValue(value, 100000) == false)
|
||||
// if (dac1_8V.setVoltage(value, 100000) == false)
|
||||
//{
|
||||
// Serial.println("dac1_8V.setValue() failed");
|
||||
// Serial.println("dac1_8V.setVoltage() failed");
|
||||
// }
|
||||
}
|
||||
|
||||
@ -314,8 +324,11 @@ void waveGen(void)
|
||||
refillTable(amplitude[0], offset[0] + calib[0], 0);
|
||||
refillTable(amplitude[1], offset[1] + calib[1], 1);
|
||||
|
||||
dac0_5V.setValue(1);
|
||||
dac1_8V.setValue(offset[1] + calib[1]);
|
||||
if (dac0_5V.setVoltage(0.0) == false)
|
||||
{
|
||||
Serial.println("dac0_5V.setVoltage() failed");
|
||||
}
|
||||
dac1_8V.setInputCode(offset[1] + calib[1]);
|
||||
|
||||
Serial.println("\n\r\t\t\t\t waveGen\t\n\n\r\toptions\t\t\twaves\t\t\tadjust frequency\n\r");
|
||||
Serial.println("\t5/0 = dac 0 0-5V (togg)\tq = square\t\t+ = frequency++\n\r");
|
||||
@ -405,7 +418,7 @@ chars += Serial.print(adc0Reading);
|
||||
case '8':
|
||||
if (activeDac == 0)
|
||||
{
|
||||
dac0_5V.setValue(0);
|
||||
dac0_5V.setVoltage(0);
|
||||
}
|
||||
|
||||
if (activeDac != 3)
|
||||
@ -415,14 +428,14 @@ chars += Serial.print(adc0Reading);
|
||||
|
||||
if (dacOn[activeDac] == 0)
|
||||
{
|
||||
dac1_8V.setValue(amplitude[activeDac]);
|
||||
dac1_8V.setInputCode(amplitude[activeDac]);
|
||||
}
|
||||
|
||||
break;
|
||||
case '5':
|
||||
if (activeDac == 1)
|
||||
{
|
||||
dac1_8V.setValue(amplitude[activeDac]);
|
||||
dac1_8V.setInputCode(amplitude[activeDac]);
|
||||
}
|
||||
|
||||
if (activeDac != 3)
|
||||
@ -431,7 +444,7 @@ chars += Serial.print(adc0Reading);
|
||||
activeDac = 0;
|
||||
if (dacOn[activeDac] == 0)
|
||||
{
|
||||
dac0_5V.setValue(0);
|
||||
dac0_5V.setVoltage(0);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
@ -533,54 +546,54 @@ chars += Serial.print(adc0Reading);
|
||||
if (t < halvePeriod[activeDac])
|
||||
{
|
||||
if (activeDac == 0 && dacOn[activeDac] == 1)
|
||||
dac0_5V.setValue(amplitude[activeDac]);
|
||||
dac0_5V.setInputCode(amplitude[activeDac]);
|
||||
else if (activeDac == 1 && dacOn[activeDac] == 1)
|
||||
dac1_8V.setValue(amplitude[activeDac]);
|
||||
dac1_8V.setInputCode(amplitude[activeDac]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (activeDac == 0 && dacOn[activeDac] == 1)
|
||||
dac0_5V.setValue(offset[activeDac]);
|
||||
dac0_5V.setInputCode(offset[activeDac]);
|
||||
else if (activeDac == 1 && dacOn[activeDac] == 1)
|
||||
dac1_8V.setValue(offset[activeDac]);
|
||||
dac1_8V.setInputCode(offset[activeDac]);
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
if (activeDac == 0 && dacOn[activeDac] == 1)
|
||||
dac0_5V.setValue(t * amplitude[activeDac] / period[activeDac]);
|
||||
dac0_5V.setInputCode(t * amplitude[activeDac] / period[activeDac]);
|
||||
else if (activeDac == 1 && dacOn[activeDac] == 1)
|
||||
dac1_8V.setValue(t * amplitude[activeDac] / period[activeDac]);
|
||||
dac1_8V.setInputCode(t * amplitude[activeDac] / period[activeDac]);
|
||||
break;
|
||||
case 't':
|
||||
if (activeDac == 0 && dacOn[activeDac] == 1)
|
||||
{
|
||||
|
||||
if (t < halvePeriod[activeDac])
|
||||
dac0_5V.setValue(((t * amplitude[activeDac]) / halvePeriod[activeDac] )+ offset[activeDac]);
|
||||
dac0_5V.setInputCode(((t * amplitude[activeDac]) / halvePeriod[activeDac] )+ offset[activeDac]);
|
||||
else
|
||||
dac0_5V.setValue((((period[activeDac] - t) * (amplitude[activeDac]) / halvePeriod[activeDac])+offset[activeDac]));
|
||||
dac0_5V.setInputCode((((period[activeDac] - t) * (amplitude[activeDac]) / halvePeriod[activeDac])+offset[activeDac]));
|
||||
}
|
||||
else if (activeDac == 1 && dacOn[activeDac] == 1)
|
||||
{
|
||||
if (t < halvePeriod[activeDac])
|
||||
dac1_8V.setValue(t * amplitude[activeDac] / halvePeriod[activeDac]);
|
||||
dac1_8V.setInputCode(t * amplitude[activeDac] / halvePeriod[activeDac]);
|
||||
else
|
||||
dac1_8V.setValue((period[activeDac] - t) * amplitude[activeDac] / halvePeriod[activeDac]);
|
||||
dac1_8V.setInputCode((period[activeDac] - t) * amplitude[activeDac] / halvePeriod[activeDac]);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (activeDac == 0 && dacOn[activeDac] == 1)
|
||||
dac0_5V.setValue(random(amplitude[activeDac]) + offset[activeDac]);
|
||||
dac0_5V.setInputCode(random(amplitude[activeDac]) + offset[activeDac]);
|
||||
else if (activeDac == 1 && dacOn[activeDac] == 1)
|
||||
{
|
||||
dac1_8V.setValue(random(amplitude[activeDac]) + offset[activeDac]);
|
||||
dac1_8V.setInputCode(random(amplitude[activeDac]) + offset[activeDac]);
|
||||
}
|
||||
break;
|
||||
case 'z': // zero
|
||||
if (activeDac == 0)
|
||||
dac0_5V.setValue(0);
|
||||
dac0_5V.setVoltage(0);
|
||||
else if (activeDac == 1)
|
||||
dac1_8V.setValue(offset[activeDac]);
|
||||
dac1_8V.setInputCode(offset[activeDac]);
|
||||
break;
|
||||
case 'h': // high
|
||||
Serial.println("\n\r\t\t\t\t waveGen\t\n\n\r\toptions\t\t\twaves\t\t\tadjust frequency\n\r");
|
||||
@ -593,7 +606,7 @@ chars += Serial.print(adc0Reading);
|
||||
mode[activeDac] = mode[2];
|
||||
break;
|
||||
case 'm': // mid
|
||||
// dac1_8V.setValue(2047);
|
||||
// dac1_8V.setInputCode(2047);
|
||||
break;
|
||||
case 'a':
|
||||
{
|
||||
@ -868,15 +881,15 @@ chars += Serial.print(adc0Reading);
|
||||
case 's':
|
||||
// reference
|
||||
// float f = ((PI * 2) * t)/period;
|
||||
// dac1_8V.setValue(2047 + 2047 * sin(f));
|
||||
// dac1_8V.setInputCode(2047 + 2047 * sin(f));
|
||||
//
|
||||
if (mode[activeDac] != 'v')
|
||||
{
|
||||
int idx = (360 * t) / period[activeDac];
|
||||
if (activeDac == 0 && dacOn[activeDac] == 1)
|
||||
dac0_5V.setValue(sine0[idx]); // lookuptable
|
||||
dac0_5V.setInputCode(sine0[idx]); // lookuptable
|
||||
else if (activeDac == 1 && dacOn[activeDac] == 1)
|
||||
dac1_8V.setValue(sine1[idx]); // lookuptable
|
||||
dac1_8V.setInputCode(sine1[idx]); // lookuptable
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef PERIPHERALS_H
|
||||
#define PERIPHERALS_H
|
||||
//#include "Adafruit_MCP4725.h"
|
||||
#include "MCP4725.h"
|
||||
//#include "MCP4725.h"
|
||||
#include <Arduino.h>
|
||||
#include "INA219.h"
|
||||
#include "Wire.h"
|
||||
#include <Wire.h>
|
||||
|
||||
|
||||
|
||||
void initINA219(void);
|
||||
|
@ -10,16 +10,11 @@
|
||||
// #include "CH446Q.h"
|
||||
#include "Peripherals.h"
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_MCP4725.h>
|
||||
|
||||
// #include <EEPROM.h>
|
||||
// #include "ArduinoStuff.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef EEPROMSTUFF
|
||||
#include <EEPROM.h>
|
||||
#endif
|
||||
@ -114,7 +109,7 @@ debugFlagInit();
|
||||
// delay(20);
|
||||
//}
|
||||
|
||||
// rainbowy(255,253,100);
|
||||
|
||||
// parseWokwiFileToNodeFile();
|
||||
// openNodeFile();
|
||||
// while(1);
|
||||
@ -140,7 +135,7 @@ void loop()
|
||||
|
||||
// initArduino();
|
||||
//
|
||||
|
||||
//rainbowy(255,145,100);
|
||||
menu:
|
||||
|
||||
// arduinoPrint();
|
||||
|
Loading…
x
Reference in New Issue
Block a user