Other Parts Discussed in Thread: TMS320F28335,
Hi.
I'm using TPS65381A-Q1 along with TMS320F28335. I have found a SW driver which is provided for Hercules (including some examples). I took the driver and adopted it to F28335, which was not a big task (I wonder why the driver is not generalized so it could be used with any MCU).
Anyway, I was stuck with the driver usage, I did a lot of debugging and finally I found a mistake in the code:
In Tps_Driver.c, there is a function configuring the Watchdog windows:
boolean TPS_ConfigureWatchdogWindows(TPS_WatchdogWindows watchdog_windows,
uint8 u8windowtime_scaler)
{
boolean blRetVal = TRUE;
uint8 u8tps_device_state = 0U;
blRetVal = TPS_GetCurrentTPSDeviceState(&u8tps_device_state);
if ((TRUE == blRetVal) && (TPS_DEVICE_DIAGNOSTIC == u8tps_device_state))
{
switch (watchdog_windows)
{
case OPEN_WINDOW:
if (u8windowtime_scaler <= OPEN_WINDOW_SCALER_MAX)
{
blRetVal = TpsIf_SetRegisterBitFieldVerify(TPS_WDT_WIN1_CFG,
BF_WD_OPEN_WINDOW_SCALER_START,
BF_WD_OPEN_WINDOW_SCALER_LENGTH, u8windowtime_scaler);
/*update the init_configuration structure to support register readback*/
/*SAFETYMCUSW 9 S MR: 12.2 <APPROVED> "Comment_2"*/
BFU8_SET(init_configuration.u8wdt_win1_cfg,
u8windowtime_scaler, BF_WD_OPEN_WINDOW_SCALER_START,
BF_WD_OPEN_WINDOW_SCALER_LENGTH);
}
else
{
blRetVal = FALSE;
}
break;
case CLOSE_WINDOW:
if (u8windowtime_scaler <= CLOSE_WINDOW_SCALER_MAX)
{
blRetVal = TpsIf_SetRegisterBitFieldVerify(TPS_WDT_WIN2_CFG,
BF_WD_CLOSE_WINDOW_SCALER_START,
BF_WD_CLOSE_WINDOW_SCALER_LEN, u8windowtime_scaler);
/*update the init_configuration structure to support register readback*/
/*SAFETYMCUSW 9 S MR: 12.2 <APPROVED> "Comment_2"*/
BFU8_SET(init_configuration.u8wdt_win2_cfg,
u8windowtime_scaler,
BF_WD_CLOSE_WINDOW_SCALER_START,
BF_WD_CLOSE_WINDOW_SCALER_LEN);
}
else
{
blRetVal = FALSE;
}
break;
default:
blRetVal = FALSE;
break;
}
}
else
{
blRetVal = FALSE;
}
return blRetVal;
}
It seems alright until you find out that the OPEN_WINDOW and CLOSE_WINDOW are swapped (probably accidentally): in case of OPEN_WINDOW, the value is written into TPS_WDT_WIN1_CFG and in case of CLOSE_WINDOW, the value is written into TPS_WDT_WIN2_CFG.
Based on the TPS65381A-Q1 datasheet (available here: https://www.ti.com/lit/ds/symlink/tps65381a-q1.pdf?ts=1635950961406&ref_url=https%253A%252F%252Fwww.google.com%252F - e.g. Fig. 5-6), window 1 (WIN1) is also displayed as CLOSE, while window 2 (WIN2) is displayed as OPEN, the other way around from the code is handling the data.
The faulty behavior comes up when I try to use WIN1 longer than 31 x 0.55 ms = 17.05 ms. The value is sent to the device register WIN2, and it is dropped due to the invalid value, since the WIN2 accepts numbers 31 and lower. Default value is then used, which is 0x1f = 31d = 17.05ms. The same way, WIN2 value is stored to the WIN1 register, but the intended WIN2 may be much shorter than the intended WIN1, thus the entire timing is broken and the system goes to safe state upon leaving the DIAGNOSTIC state.
I believe the issue is described well. I would suggest a bugfix:
boolean TPS_ConfigureWatchdogWindows(TPS_WatchdogWindows watchdog_windows,
uint8 u8windowtime_scaler)
{
boolean blRetVal = TRUE;
uint8 u8tps_device_state = 0U;
blRetVal = TPS_GetCurrentTPSDeviceState(&u8tps_device_state);
if ((TRUE == blRetVal) && (TPS_DEVICE_DIAGNOSTIC == u8tps_device_state))
{
switch (watchdog_windows)
{
case OPEN_WINDOW:
if (u8windowtime_scaler <= OPEN_WINDOW_SCALER_MAX)
{
blRetVal = TpsIf_SetRegisterBitFieldVerify(TPS_WDT_WIN2_CFG,
BF_WD_OPEN_WINDOW_SCALER_START,
BF_WD_OPEN_WINDOW_SCALER_LENGTH, u8windowtime_scaler);
/*update the init_configuration structure to support register readback*/
/*SAFETYMCUSW 9 S MR: 12.2 <APPROVED> "Comment_2"*/
BFU8_SET(init_configuration.u8wdt_win2_cfg,
u8windowtime_scaler, BF_WD_OPEN_WINDOW_SCALER_START,
BF_WD_OPEN_WINDOW_SCALER_LENGTH);
}
else
{
blRetVal = FALSE;
}
break;
case CLOSE_WINDOW:
if (u8windowtime_scaler <= CLOSE_WINDOW_SCALER_MAX)
{
blRetVal = TpsIf_SetRegisterBitFieldVerify(TPS_WDT_WIN1_CFG,
BF_WD_CLOSE_WINDOW_SCALER_START,
BF_WD_CLOSE_WINDOW_SCALER_LEN, u8windowtime_scaler);
/*update the init_configuration structure to support register readback*/
/*SAFETYMCUSW 9 S MR: 12.2 <APPROVED> "Comment_2"*/
BFU8_SET(init_configuration.u8wdt_win1_cfg,
u8windowtime_scaler,
BF_WD_CLOSE_WINDOW_SCALER_START,
BF_WD_CLOSE_WINDOW_SCALER_LEN);
}
else
{
blRetVal = FALSE;
}
break;
default:
blRetVal = FALSE;
break;
}
}
else
{
blRetVal = FALSE;
}
return blRetVal;
}
I hope it helps and I hope it saves some debugging time to others.
Best regards,
Matej