ZHCU943A November 2020 – July 2022 TPS25750
命令
1.器件生成一个 I2C 中断 INT_EVENT.ReadyForPatch,表明其已准备好进行修补。主机只有在收到器件发出的此通知后才会启动补丁下载过程。
2.主机应通过向器件发送 PBMs 命令来启动补丁下载过程。
3.主机随后应发送整个补丁捆绑包数据。主机可以在单个 I2C 事务中发送整个补丁捆绑包,也可以将其拆分为多个事务。PD 控制器会递增其补丁存储器空间的指针,并在补丁从器件地址(在 'PBMs' 4CC 任务中进行配置)上接收每个字节。
4.主机随后应发送 PBMc 命令以指示 PD 控制器补丁加载序列已完成。成功完成引导序列后,PD 控制器开始执行应用程序。
若要执行 4CC 命令,主机应用程序应遵循以下顺序:
应用程序随后应将 4CC 命令字符写入相应的 CmdX(0x08 或 0x10)寄存器。
应用程序可以注册并等待 CmdXComplete 事件或重复读取 CmdX 寄存器的四字节内容,直至读取到:
0x00',表示命令执行成功。
或 '!CMD',表示命令执行失败。
1.
void AsyncEvtHandlerP11()
{
s_AppContext *const pCtx = &gAppCtx;
I2C_IF_TPS6598xIntDisable(pCtx->i2cPort);
ProcessEvent();
}
static int32_t ProcessEvent()
{
s_AppContext *const pCtx = &gAppCtx;
s_AppData *const pData = &gAppData[pCtx->i2cPort];
uint8_t outdata[MAX_BUF_BSIZE] = {0};
uint8_t indata[MAX_BUF_BSIZE] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
s_TPS_IntEvent *pSetEvent = NULL;
s_TPS_IntEvent *pClrEvent = NULL;
int32_t retVal = -1;
#ifdef WORKAROUND_WAIT_AFTER_GAID
if(0 == wait_after_gaid)
{
wait_after_gaid += 1;
/*
* The 100ms delay here is to allow the device to ACK the I2C transactions
* after a cold start
*/
Board_IF_Delay(100000);
}
#endif /* WORKAROUND_WAIT_AFTER_GAID */
retVal = ReadReg(pData->event_reg, REG_LEN_INTEVENT1, &outdata[0]);
RETURN_ON_ERROR(retVal);
/*
* output[0] = Register's size in bytes
* output[1..REG_LEN_INTEVENT1] = Register's content, and hence '&outdata[1]' below.!
*/
pSetEvent = (s_TPS_IntEvent *)&outdata[1];
pClrEvent = (s_TPS_IntEvent *)&indata[0];
if(0 != pSetEvent->cmd1complete)
{
pData->cmdExeInProgress = 0;
pClrEvent->cmd1complete = 1;
}
if(0 != pSetEvent->readyforpatch)
{
pClrEvent->readyforpatch = 1;
SignalEvent(APP_EVENT_READY_FOR_PATCH);
}
if(0 != pSetEvent->patchloaded)
{
pClrEvent->patchloaded = 1;
SignalEvent(APP_EVENT_PATCH_LOADED);
}
/* App events are triggred - The corresponding events of the device can now be cleared */ retVal = WriteReg(pData->clear_reg, REG_LEN_INTCLEAR1, &indata[0]); RETURN_ON_ERROR(retVal);
return 0;
}
static int32_t StartPatchDownloadBurstMode()
{
uint8_t outdata[MAX_BUF_BSIZE] = {0};
s_PBMs_InData pbmsInData = {0};
s_PBMs_OutData *p_pbmsOutData = NULL;
int32_t retVal = -1;
UART_PRINT("Starting Patch Download in Burst Mode\n\r");
retVal = ReadMode();
RETURN_ON_ERROR(retVal);
retVal = ReadVersion(); RETURN_ON_ERROR(retVal); /* If the device is in APP mode, don't allow burst-mode patch download */
if(isDeviceInAppMode())
{
UART_PRINT("Burst mode patching not allowed in APP mode\n\r");
retVal = -1;
goto error;
} /* Wait for CmdComplete event when executing the 4CC commands */
retVal = MaskCmdComplete(1);
RETURN_ON_ERROR(retVal); /* Fill the input, and execute 'PBMs' */
pbmsInData.lrBinSize = gSizeLowregionArray;
pbmsInData.slaveAddress = SLAVE_ADDR_FOR_PATCH_DATA;
pbmsInData.timeout = BURST_MODE_TIMEOUT;
retVal = ExecCmd(PBMs, sizeof(pbmsInData), (uint8_t *)&pbmsInData, \ PBMs_OUTPUT_SIZE, &outdata[0]);
RETURN_ON_ERROR(retVal); /* 'outdata' will contain the command's output after the successful execution of PBMs.*/
p_pbmsOutData = (s_PBMs_OutData *)&outdata[1];
if(PBMs_SUCCESS != p_pbmsOutData->patch_start_status)
{
ERR_PRINT(p_pbmsOutData->patch_start_status);
retVal = -1; goto error;
}
error: return retVal;
}
可使用应用程序自定义 GUI 生成低区二进制 'C' 数组格式。以下代码段中引用的 tps6598x_lowregion_array 和 gSizeLowregionArray 取自这个生成的文件。
static int32_t DownloadDataBurstMode()
{
int32_t retVal = 0;
#ifdef WORKAROUND_IGNORE_CMDxCMPLT_BURST_TX
/*
* Workaround: Device was erroneously sending an unexpected CmdXComplete
* event occationally while in the middle of the patch download process,
* causing the SM to go for a toss.!
*/
MaskCmdComplete(0);
#endif /* WORKAROUND_IGNORE_CMDxCMPLT_BURST_TX */
/*
* tps6598x_lowregion_array and gSizeLowregionArray are defined
* in the 'C' array file that can be created using the
* Application customization GUI
*/
UART_PRINT(".");
SendDataToSlave(SLAVE_ADDR_FOR_PATCH_DATA, gSizeLowregionArray, (uint8_t *)&tps6598x_lowregion_array[0]);
/* Proceed to the next step after the patch is successfully downloaded */
UART_PRINT("\n\r");
SignalEvent(APP_EVENT_PATCH_DOWNLOADED);
return retVal;
}
static int32_t PatchDownloadCompleteBurstMode()
{
s_AppContext *const pCtx = &gAppCtx;
/* PBMc return structure and statuses are exactly same as PTCc */
s_PTCc_OutData *p_pbmcOutData = NULL;
uint8_t outdata[MAX_BUF_BSIZE] = {0};
int32_t retVal = -1;
UART_PRINT("Patch Download Complete\n\r");
#ifdef WORKAROUND_IGNORE_CMDxCMPLT_BURST_TX
MaskCmdComplete(1);
#endif /* WORKAROUND_IGNORE_CMDxCMPLT_BURST_TX */
/* Execute PBMc to indicate to the device that the patch is successfully downloaded */
retVal = ExecCmd(PBMc, 0, NULL, PTCc_OUTPUT_SIZE, &outdata[0]);
RETURN_ON_ERROR(retVal);
/* 'outdata’ will contain the command's output after the successful execution of PBMc.*/
p_pbmcOutData = (s_PTCc_OutData *)&outdata[3];
if(p_pbmcOutData->patch_complete_status != PTCc_SUCCESS)
{
ERR_PRINT(p_pbmcOutData->patch_complete_status);
retVal = -1;
goto error;
}
/* Expecting 'PatchLoaded' event */
retVal = I2C_IF_TPS6598xIntEnable(pCtx->i2cPort);
RETURN_ON_ERROR(retVal);
error: return retVal;
}