This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TPS65987D: I2c Patching Controller, issue getting controller from app mode to patch mode

Part Number: TPS65987D


I am having issues getting the EVM to go into patch mode so that I could follow the flow chart in the SLVA972A manual.flow diagram found in manual

So I have tried sending the 4cc command to reset the patch with the proper key and I don’t seem to get the system to react to it. It accepts the command, and reports everything is fine but the mode(0x03) stays in APP and I never read the READY_FOR_PATCH in the 0x14 reg. I have attached the driver I wrote to talk to the pd controller. Also attached is the config array that I got from the app customization tool. In the main() I have a serial interface running that when I send a command to send the patch it will call

 

Reset_Patch();

Apply_Patch();

 

Let me know if this is something you can help me with or if I must submit it to the E2E forum.

 

I am using a saleae logic to monitor the i2c lines to make sure that the pd controller is ack and returning the proper bytes and that my code receive them. I know that some of the 4cc commands have return bytes that I currently don’t handle in code but I was just monitoring it in saleae for simplicity.

/*
 * TPS6598.c
 *
 * Created: 3/2/2021 1:49:16 PM
 *  Author: carlson.magina
 */ 


#include "TPS6598.h"
#include "string.h"

extern const char tps6598x_lowregion_i2c_array[];
extern int gSizeLowregionArray ;

#define TPS6598_I2C_Addr 0x38
#define MaxBufferSize 128

uint8_t temp_readbuf[MaxBufferSize];
uint8_t temp_writebuf[MaxBufferSize];

#define TIMEOUT_TIME 500 //ms
#define MAXPATCHSIZE 64 //bytes




//registers
#define MODE_reg	0x03
#define CMD1_reg	0x08
#define DATA1_reg	0x09
#define IntEvent1_reg 0x14
#define IntMask1_reg 0x16


void MASTER_i2C_restart_PD_controller_ic (void)
{
	i2c_m_sync_disable(&I2C);

	gpio_set_pin_direction(HUB_SDA, GPIO_DIRECTION_IN);
	gpio_set_pin_function(HUB_SDA, GPIO_PIN_FUNCTION_OFF);
	
	gpio_set_pin_direction(HUB_SCL, GPIO_DIRECTION_OUT);
	gpio_set_pin_level(HUB_SCL,1);
	gpio_set_pin_function(HUB_SCL, GPIO_PIN_FUNCTION_OFF);
	
	while (!gpio_get_pin_level(HUB_SDA))
	{
		for (uint8_t i=0; i<9; i++)
		{
			gpio_set_pin_level(HUB_SCL,0);
			gpio_set_pin_level(HUB_SCL,1);
		}
	}
	
	I2C_PORT_init();
	i2c_m_sync_enable(&I2C);
//	i2c_m_sync_send_stop(&I2C);
}


void readPDmem (uint8_t regaddr, uint8_t* readbuf,uint8_t numBytes)
{
	int32_t ret_stat;
	
	if (MaxBufferSize<(numBytes+1))
	{
		//error 
		return;
	}

	//stopless write
	struct _i2c_m_msg msg;
	msg.addr   = TPS6598_I2C_Addr;
	msg.len    = 1;
	msg.flags  = 0;
	msg.buffer = &regaddr;
	ret_stat=i2c_m_sync_transfer (&I2C,&msg);

	msg.addr   = TPS6598_I2C_Addr;
	msg.len    = numBytes+1;
	msg.flags  =  I2C_M_RD | I2C_M_STOP ;
	msg.buffer = (uint8_t *)temp_readbuf;
	ret_stat=i2c_m_sync_transfer (&I2C,&msg);
	
	if (ret_stat==0)
	{
		memcpy(readbuf,&temp_readbuf[1],numBytes);
	}
	else if (ret_stat==-4)
	{
		
		sys_info.I2C_faults++;
		ret_stat=0;//error
		MASTER_i2C_restart_PD_controller_ic();
	}
	else if (ret_stat==-5)
	{
		sys_info.I2C_faults++;
		ret_stat=0;//error
		MASTER_i2C_restart_PD_controller_ic();
	}
	else
	{
		sys_info.I2C_faults++;
		ret_stat=0;//error
	}
}
void writePDmem(uint16_t regaddr, uint8_t *wrbuf, uint8_t numBytes)
{
	int32_t ret_stat;
	i2c_m_sync_set_slaveaddr(&I2C, TPS6598_I2C_Addr, I2C_M_SEVEN);
	
	if (MaxBufferSize<(numBytes+2))
	{
		//error 
		return;
	}
	
	temp_writebuf[0]=regaddr;
	temp_writebuf[1]=numBytes;

	memcpy(&temp_writebuf[2],wrbuf,numBytes);//set host timeout to 5 seconds

	ret_stat=io_write(&I2C.io, temp_writebuf,numBytes+2);
	//excute comand
	
	if (ret_stat==numBytes+1)
	{
		//*readbuf=hub_readbuf[1];
	}
	else if (ret_stat==-4)
	{
		sys_info.I2C_faults++;
		ret_stat=0;//error
		MASTER_i2C_restart_PD_controller_ic();
	}
	else if (ret_stat==-5)
	{
		sys_info.I2C_faults++;
		ret_stat=0;//error
		MASTER_i2C_restart_PD_controller_ic();
	}
	else
	{
		sys_info.I2C_faults++;
		ret_stat=0;//error
	}
}

bool setupIntMask()
{
		uint8_t registerBytes[11];
	
	registerBytes[0]=0xff;
	registerBytes[1]=0xff;
	registerBytes[2]=0xff;
	registerBytes[3]=0xff;
	registerBytes[4]=0xff;
	registerBytes[5]=0xff;
	registerBytes[6]=0xff;
	registerBytes[7]=0xff;
	registerBytes[8]=0xff;
	registerBytes[9]=0xff;
	registerBytes[10]=0xff;

	
	writePDmem(IntMask1_reg,registerBytes,11);
	
	readPDmem(IntMask1_reg,registerBytes,11);
	
	//Patch Status stored in byte 11 bit 1
	if (registerBytes[10] & 0x02)
	{
		//continue
	}
	else
	{
		return false;
	}
	return true;
}

bool isReadyforPatch ()
{

	uint8_t registerBytes[11];
	
	readPDmem(IntEvent1_reg,registerBytes,11);
	
	readPDmem(MODE_reg,registerBytes,4);
	
	//Patch Status stored in byte 11 bit 1
	if (registerBytes[10] & 0x02)
	{
		return true;
	}
	else
	{
		return false;
	}
	
}

bool Send4ccCmd (char* CC4_cmd, uint8_t DataBytes, uint8_t *data, uint8_t receiveBytes, uint8_t* receiveData)
{
	if (DataBytes>0)
	{
		//send data if neccesary
		if (data==NULL)
		{
			//error null pointer to data
			return false;
		}
		writePDmem(DATA1_reg,data,DataBytes);
	}
	
	//send command
	writePDmem(CMD1_reg,(uint8_t*)CC4_cmd,4);
	
	//check for command execution success
	uint8_t commandsuccess[4];
	
	for (uint8_t i=0; i<10; i++) //try four times
	{
		readPDmem(CMD1_reg,commandsuccess,4);	
		if ((*((uint32_t *)commandsuccess))==0)
		{
			break;
			//command success
			//continue
			//return true;
		}
		else if (	commandsuccess[0] == CC4_cmd[0] && //
					commandsuccess[1] == CC4_cmd[1] && //
					commandsuccess[2] == CC4_cmd[2] && //
					commandsuccess[3] == CC4_cmd[3] )
		{
			//waiting for command to finish
			delay_ms(1);
		}
		else if (	commandsuccess[0] == '!' && //
					commandsuccess[1] == 'C' && //
					commandsuccess[2] == 'M' && //
					commandsuccess[3] == 'D' )
		{
			//command not recognized
			//error
			
			return false;
		}
		else
		{
			//unknown
			delay_ms(1);
			return false;
		}
		delay_ms(1);
	}
	
	if (receiveBytes>0)
	{
		//send data if neccesary
		if (data==NULL)
		{
			//error null pointer to data
			return false;
		}
		readPDmem(DATA1_reg,receiveData,receiveBytes);	 
	}
	
	
	return true;
}

bool Reset_Patch()
{
	
	isReadyforPatch(); 
	
	uint8_t data[4];
	
	data[0]= 0x01;
	data[1]= 0x00;
	data[2]= 0xBE;
	data[3]= 0xEF;
	
	
	return Send4ccCmd("PTCr",4,data,1,data);
}

bool Apply_Patch()
{
	uint16_t timeout = 0;
	uint8_t rtnData[10];
	
	setupIntMask();
	
	while(!isReadyforPatch())
	{
		delay_ms(1);
		timeout++;
		if (timeout>TIMEOUT_TIME)
		{
			//failed to get ready in reasonable amount of time
			return 0;
		}		
	}

	uint8_t data[4];
	
	data[0]=0x02;
	
	
	Send4ccCmd("PTCs",1,data,4,rtnData);
	
	uint32_t numBytesSnt =0,numBytesRem = 0;
	uint8_t bytes2Snd =0;
	uint8_t * dataAddr = NULL;
	numBytesRem=gSizeLowregionArray;
	
	while (numBytesRem)
	{
		if (numBytesRem>MAXPATCHSIZE)
		{
			bytes2Snd=MAXPATCHSIZE;
		}
		else
		{
			bytes2Snd=(uint8_t)numBytesRem;
		}
		
		dataAddr= (uint8_t *)&(tps6598x_lowregion_i2c_array[numBytesSnt]);
		

			
		if (!Send4ccCmd("PTCd",bytes2Snd,dataAddr,10,rtnData))
		{
			//failed sending data 
			return false;
		}
		
		numBytesSnt=numBytesSnt+bytes2Snd;
		numBytesRem=numBytesRem-bytes2Snd;
				
	}
	
	if (!Send4ccCmd("PTCc",0,NULL,4,rtnData))
	{
		//failed sending data
		return false;
	}
	
	return true;
}
TPS6598_config.c