Other Parts Discussed in Thread: TPS63810, USB2ANY, TPS63810EVM, TPS63811
I am using an Arduino MEGA2560_R3 with TPS63811EVM module, communication via I2C (Wire library). I am able to write to device registers but seem to be experiencing an error reading register values. Even without being able to read back the register values, I can confirm the register writes work because of outputs changing as expected after reg write. My simplified my Arduino sketch which demonstrates the problem:
// board jumpers: VSEL pin jumper selects VOUT1 register, EN jumper sets EN_PIN to ON
// external 10k pull-up resistors pigtailed on SDA, SCL I2C lines
// I put some description in the code comments. Hopefully someone can help me fix the problem.
#include <Wire.h> #define ADDR 0x75 // TPS63811 I2C address #define CONTROL 0x01 // TPS63811 control register address #define VOUT1 0x04 // VOUT1 register address #define VOUT1_RESET 0b0111100 // VOUT1 default bits /***** using ***** * * Arduino MEGA2560_R3 * Wire library (I2C) * TI TPS63811EVM * */ void setup() { int val; uint8_t result = 0x4A; /* I am using external 10k resistors */ pinMode(7, OUTPUT); // SDA pull-up resistor pinMode(8, OUTPUT); // SCL pull-up resistor pinMode(10, OUTPUT); // TPS63811 VIN /* all 5V */ digitalWrite(10, HIGH); // power on TPS63811 digitalWrite(7, HIGH); digitalWrite(8, HIGH); /***** board jumper settings ***** * VSEL jumper is set to select VOUT1 * EN jumper is in the ON position */ Serial.begin(115200); delay(1000); Wire.begin(); Wire.setClock(100000); delay(1000); /* set CONTROL register bits, set RANGE bit prior to setting ENABLE bit (required) */ Wire.beginTransmission(ADDR); Wire.write(CONTROL); // select control register Wire.write(0x4A); // 0b1001010, 0x4A - sets range bit, fpwm, slew == 5V/ms val = Wire.endTransmission(); if (val != 0) { Serial.println("error writing initial control register value"); } /* set VOUT to desired voltage */ Wire.beginTransmission(ADDR); Wire.write(VOUT1); Wire.write(0x64); // should yield ~ 4.5V with the RANGE bit set // Wire.write(0x77); // 0b1110111, 0x77 - will yield 5.0V when RANGE bit set val = Wire.endTransmission(); if (val != 0) { Serial.println("error writing to vout1 register"); } /* set ENABLE bit in CONTROL register - enables the converter */ Wire.beginTransmission(ADDR); Wire.write(CONTROL); Wire.write(0x6A); // 0b1101010, 0x6A - sets range, enable, fpwm and slew bits (converter gets enabled) val = Wire.endTransmission(); if (val != 0) { Serial.println("error setting enable bit in control register"); } else { Serial.println("output converter enabled for 10 seconds"); delay(10000); // load (LED+resistor) connected to VOUT/GND - LED illuminates properly for 10 seconds Wire.beginTransmission(ADDR); Wire.write(CONTROL); Wire.write(0x4A); // clears the enable bit, disabling the converter val = Wire.endTransmission(); // LED goes dark as it should Serial.println("converter disabled"); } /* Everything above works. I have confirmed 4.5V output if I write 0x64 to VOUT1 register. * I have confirmed 5.0V if I write 0x77 to VOUT1 register. Converter is enabled/disabled as expected * when setting/clearing the ENABLE bit in the CONTROL register... * but when I try reading any register value I always get '0' - doesn't matter which register I select, * they all return 0. I have tried all sorts of things but I can't get it to work. * * I read this in the TPS6381x datasheet (section 8.5.2) - * "Attempting to read data from register addresses not listed in this section results in 00h being read out." * * that would explain my problem excecpt that I have checked all my addresses repeatedly (to the point of absurdity) * and they are all correct. */ /***** this read fails - I don't know why *****/ Wire.beginTransmission(ADDR); Wire.write(VOUT1); // select VOUT1 register Wire.endTransmission(); Wire.requestFrom(ADDR, 1); if (Wire.available() == 1) // I get one byte of data as I should { result = Wire.read(); } Serial.print("result: "); Serial.println(result); // but that byte is always is 0 Wire.end(); } void loop() { Serial.print("."); delay(1000); }