diff --git a/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cli b/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cli index aa952c4..a5357f2 100755 Binary files a/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cli and b/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cli differ diff --git a/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cliOld b/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cliOld new file mode 100755 index 0000000..aa952c4 Binary files /dev/null and b/Jumperless Wokwi Bridge App/JumperlessWokwiBridge.app/Contents/MacOS/jumperlesswokwibridge_cliOld differ diff --git a/JumperlessNano/.vscode/extensions 2.json b/JumperlessNano/.vscode/extensions 2.json deleted file mode 100644 index 080e70d..0000000 --- a/JumperlessNano/.vscode/extensions 2.json +++ /dev/null @@ -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" - ] -} diff --git a/JumperlessNano/lib/mcp4725/mcp4725.cpp b/JumperlessNano/lib/mcp4725/mcp4725.cpp new file mode 100644 index 0000000..d5455c0 --- /dev/null +++ b/JumperlessNano/lib/mcp4725/mcp4725.cpp @@ -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 ------------------------ \ No newline at end of file diff --git a/JumperlessNano/lib/mcp4725/mcp4725.hpp b/JumperlessNano/lib/mcp4725/mcp4725.hpp new file mode 100644 index 0000000..12a6435 --- /dev/null +++ b/JumperlessNano/lib/mcp4725/mcp4725.hpp @@ -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 // optional for printf debug error messages +#include "pico/stdlib.h" +#include "hardware/i2c.h" +#include // 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 diff --git a/JumperlessNano/platformio.ini b/JumperlessNano/platformio.ini index 4a841fb..0ed37d0 100644 --- a/JumperlessNano/platformio.ini +++ b/JumperlessNano/platformio.ini @@ -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 diff --git a/JumperlessNano/src/LEDs.cpp b/JumperlessNano/src/LEDs.cpp index 3b6df9a..68d47a6 100644 --- a/JumperlessNano/src/LEDs.cpp +++ b/JumperlessNano/src/LEDs.cpp @@ -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 diff --git a/JumperlessNano/src/Peripherals.cpp b/JumperlessNano/src/Peripherals.cpp index f266e18..9931958 100644 --- a/JumperlessNano/src/Peripherals.cpp +++ b/JumperlessNano/src/Peripherals.cpp @@ -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; } diff --git a/JumperlessNano/src/Peripherals.h b/JumperlessNano/src/Peripherals.h index f909444..336cba2 100644 --- a/JumperlessNano/src/Peripherals.h +++ b/JumperlessNano/src/Peripherals.h @@ -1,10 +1,11 @@ #ifndef PERIPHERALS_H #define PERIPHERALS_H //#include "Adafruit_MCP4725.h" -#include "MCP4725.h" +//#include "MCP4725.h" #include #include "INA219.h" -#include "Wire.h" +#include + void initINA219(void); diff --git a/JumperlessNano/src/main.cpp b/JumperlessNano/src/main.cpp index ebe8e7d..11cd58d 100644 --- a/JumperlessNano/src/main.cpp +++ b/JumperlessNano/src/main.cpp @@ -10,16 +10,11 @@ // #include "CH446Q.h" #include "Peripherals.h" #include -#include + // #include // #include "ArduinoStuff.h" - - - - - #ifdef EEPROMSTUFF #include #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();