/*
 * AD5272.h - library for interface with AD5272 digital rheostat w/ I2C interface
 * AD5272 is 1024-position version (as opposed to 256 for AD5274)
 * Only covers reading and adjusting the wiper position - does not cover
 *    other features like setting memory, resetting, shutdown, toggling
 *    precision mode, reading memory, etc.
 * Based on previous code written for AD5274/Teensy (6/10/20)
 * Irene Hu
 * 
 * April 11, 2023
 * 
*/

#include "AD5272.h"
#include <Wire.h>
#include "Config.h"


//******************************************************************************
//* Constructors
//******************************************************************************

AD5272::AD5272(byte slaveaddr)
// input: AD5274 slave address as 7 bit number (as defined on p18)
{
	_addr = slaveaddr;
}


//******************************************************************************
//* Public Methods
//******************************************************************************

int AD5272::begin()
// setup function
// return 1 for success, 0 for fail
{	
	// set up as I2C master
	Wire.begin();
	// these next settings might get written if Wire is reinitialized byanother class
	//Wire.setWireTimeout(WIRETIMEOUT_US, true);
	// setWireTimeout doesn't work; may not exist for this platform
	//Wire.setClock(WIRESPEED_HZ);
	// somehow trying to set clock to 400k messes it up messes it up
	
	// Unlock the wiper write protect
	Wire.beginTransmission(_addr);
	
	// apparently Wire.write will NOT send 2 bytes if you put in a 2-byte value.  it sends 1 byte.
	// there must be a more elegant way to do this, but whatever.
	Wire.write(ENABLE_WRITE >> 8);
	Wire.write(ENABLE_WRITE & 0b11111111);
	
	int ret = Wire.endTransmission();

	if ( ret != 0) {
		DEBUGPORT.print("I2C error in writing to control register for AD5272. Error code: ");
		DEBUGPORT.println(ret);
		// Arduino class, unlike Teensy's i2c_t3, doesn't have Wire.getError
		return 0;
	}
	
	return 1;
}


int AD5272::setwiper( int position )
// set wiper to position indicated by position
// position is given in bit numbers, out of a max of 1024 for AD5274
// returns 1 if success, 0 for fail
{
	if (position < 0 || position >=  NUMPOS) {
		DEBUGPORT.print("Input wiper position must be a number between 0 and ");
		DEBUGPORT.print(NUMPOS-1);
		DEBUGPORT.println(".");
		return 0;
	}
		
	// convert to a command
	int cmd = WRITE_RDAC | position; // assemble the command
	
	// send command
	Wire.beginTransmission(_addr);
	
	Wire.write(cmd >> 8);
	Wire.write(cmd & 0b11111111);
	
	if ( Wire.endTransmission() != 0) {
		DEBUGPORT.println("I2C error in writing to control register for AD5272.");
		// Arduino class, unlike Teensy's i2c_t3, doesn't have Wire.getError
		// for now, to save overhead, we'll simply print the error but not the error code (returned by endTransmission)
		return 0;
	}
	
	return 1;
}


int AD5272::readwiper( int *position )
// reads wiper position - pass by pointer so the error values don't confuse
//   return values.  position variable will hold the position (0 to 1024)
// returns 1 if success, 0 if I2C error
{
	int returnval;

	// first send command to read
	Wire.beginTransmission(_addr);
		
	Wire.write(READ_RDAC >> 8);
	Wire.write(READ_RDAC & 0b11111111);
	
	if ( Wire.endTransmission() != 0) {
		DEBUGPORT.println("I2C error in writing to control register for AD5272.");
		return 0;
	}
	
	// now read the number
	if (Wire.requestFrom(_addr, 2, true) != 2) {
		DEBUGPORT.println("I2C error in reading 2 bytes from RDAC.");
		return 0;
	}
	
	// we gonna parse this return value now
	returnval = Wire.read();
	returnval = (returnval << 8) | Wire.read();
	*position = returnval;
	
	return 0;
}


int AD5272::readwiper()
// reads wiper position - return value directly, 0 for an I2C error
{
	int returnval;
	// first send command to read
	Wire.beginTransmission(_addr);
		
	Wire.write(READ_RDAC >> 8);
	Wire.write(READ_RDAC & 0b11111111);
	
	if ( Wire.endTransmission() != 0) {
		DEBUGPORT.println("I2C error in writing to control register for AD5272.");
		return 0;
	}
	
	// now read the number
	if (Wire.requestFrom(_addr, 2, true) != 2) {
		DEBUGPORT.println("I2C error in reading 2 bytes from RDAC for AD5272.");
		return 0;
	}
	
	// we gonna parse this return value now
	returnval = Wire.read();
	returnval = (returnval << 8) | Wire.read();
	
	return returnval;
}


//******************************************************************************
//* Private Methods
//******************************************************************************
  
