尊敬的技术工作者:
附件是我的驱动文件及驱动log。我目前只使用了A通道的三相,我阅读芯片手册,需要先选择page,然后设置VOUT_COMMAND, 使能OPERATION,之后还有别的操作吗,并没有电压输出, 其他的寄存器在芯片手册中都有默认值,如 VOUT_MODE 只读 且设置为5mv,ON_OFF_CONFIG 默认设备1B,PHASE默认为FF,我不知道还需要设置那些寄存器,
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "bsp_tps53681.h"
#include "gd32f10x_gpio.h"
extern uint8_t read_reg_data(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf);
extern uint8_t write_reg_data(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf);
typedef struct
{
uint8_t addr;
const char *name;
} reg_desc_t;
static const reg_desc_t status_regs[] = {
{0x78, "REG_STATUS_BYTE"},
{0x79, "REG_STATUS_WORD"},
{0x7A, "REG_STATUS_VOUT"},
{0x7B, "REG_STATUS_IOUT"},
{0x7C, "REG_STATUS_INPUT"},
{0x7D, "REG_STATUS_TEMP"},
{0x7E, "REG_STATUS_CML"},
{0x80, "REG_STATUS_MFR_SPECIFIC"}};
static const size_t status_regs_count = sizeof(status_regs) / sizeof(*status_regs);
int read_from_reg(uint8_t reg, uint8_t *buff, uint8_t len)
{
return read_reg_data(96, reg, len, buff);
}
int write_to_reg(uint8_t reg, uint8_t *buff, uint8_t len)
{
return write_reg_data(96, reg, len, buff);
}
// void dump_all_regs(uint8_t slave_addr)
// {
// for (size_t i = 0; i < status_regs_count; ++i)
// {
// uint8_t addr = status_regs[i].addr;
// uint8_t val = i2c_read(slave_addr, addr);
// printf("%s (0x%02X) = 0x%02X\n",
// status_regs[i].name, addr, val);
// }
// }
int parse_status_byte(uint8_t addr)
{
uint8_t status = 0;
read_from_reg(addr, &status, 1);
// Bit6: OFF (Power supply status)
if (status & (1 << 6))
{
printf("status_byte: not providing power to VOUT: %02x\n", status);
}
// Bit5: VOUT_OV (Output over-voltage fault)
if (status & (1 << 5))
{
printf("status_byte: Output over-voltage %02x\n", status);
}
// Bit4: IOUT_OC (Output over-current fault)
if (status & (1 << 4))
{
printf("status_byte: Output over-current %02x\n", status);
}
// Bit3: VIN_UV (Input under-voltage fault)
if (status & (1 << 3))
{
printf("status_byte: Input voltage below UVLO threshold (check input power supply)\n");
}
// Bit2: TEMP (Over-temperature fault/warning)
if (status & (1 << 2))
{
printf("status_byte: Over-temperature fault or warning (check thermal management)\n");
}
// Bit1: CML (Communication/memory/logic fault)
if (status & (1 << 1))
{
printf("status_byte:Communication/memory/logic anomaly (check PMBus connection or NVM)\n");
}
// Bit0: OTHER (Unclassified fault)
if (status & (1 << 0))
{
printf("status_byte: Unclassified fault (e.g., UVF, OCW; check other status registers)\n");
}
return 0xFF;
}
int parse_status_word(uint8_t addr)
{
uint8_t buffer[2] = {0}; // 用于存储原始字节
uint16_t status_word = 0;
int result;
// 读取两个字节数据
result = read_from_reg(addr, buffer, 2);
if (result != 0)
{
printf("ERROR: Failed to read STATUS_WORD (read %d bytes, expected 2)\n", result);
return -1;
}
// 正确处理Little Endian字节序:低字节在前,高字节在后
status_word = (uint16_t)buffer[1] << 8 | buffer[0];
printf("status_word: value: 0x%04X (Bytes: 0x%02X 0x%02X)\n", status_word, buffer[0], buffer[1]);
// Bit15: VOUT (Output voltage fault/warning)
if (status_word & (1 << 15))
{
printf("status_word: Output voltage bit warning\n");
}
// Bit14: IOUT (Output current fault/warning)
if (status_word & (1 << 14))
{
printf("status_word: Output current bit warning\n");
}
// Bit13: INPUT (Input voltage/current fault/warning)
if (status_word & (1 << 13))
{
printf("status_word: Input voltage bit warning\n");
}
// Bit12: MFR (Manufacturer-specific fault)
if (status_word & (1 << 12))
{
printf("status_word: MFR bit warning\n");
}
// Bit11: PGOOD (Power good status)
if (status_word & (1 << 11))
{
printf("status_word: Power NOT good (AVR_RDY/BVR_RDY pin is LOW)\n");
}
else
{
printf("status_word: Power good (AVR_RDY/BVR_RDY pin is HIGH)");
}
// Bit6: OFF (Power supply status)
if (status_word & (1 << 6))
{
printf("status_word: Not providing power to VOUT\n");
}
// Bit5: VOUT_OV (Output over-voltage fault)
if (status_word & (1 << 5))
{
printf("status_word: Output over-voltage fault detected\n");
}
// Bit4: IOUT_OC (Output over-current fault)
if (status_word & (1 << 4))
{
printf("status_word: Output over-current fault detected\n");
}
// Bit3: VIN_UV (Input under-voltage fault)
if (status_word & (1 << 3))
{
printf("status_word: Output Input-voltage fault detected\n");
}
// Bit2: TEMP (Over-temperature fault/warning)
if (status_word & (1 << 2))
{
printf("status_word: Over-temperature warning detected\n");
}
// Bit1: CML (Communication/memory/logic fault)
if (status_word & (1 << 1))
{
printf("status_word: Communication, memory, or logic fault detected\n");
}
// Bit0: OTHER (Unclassified fault)
if (status_word & (1 << 0))
{
printf("status_word: Unclassified fault detected\n");
}
return 0;
}
int parse_status_vout(uint8_t addr)
{
uint8_t status = 0; // Store 8-bit status value
read_from_reg(addr, &status, 1);
printf("\nRaw value: 0x%02X\n", status);
// Bit7: VOUT_OVF (Output Over-Voltage Fault)
if (status & (1 << 7))
{
printf("- Bit7 (VOUT_OVF): Output Over-Voltage Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit7 (VOUT_OVF): No output over-voltage fault detected.\n");
}
// Bit6: VOUT_OVW (Unsupported, always 0)
if ((status & (1 << 6)) != 0)
{
printf("- Bit6 (VOUT_OVW): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit5: VOUT_UVW (Unsupported, always 0)
if ((status & (1 << 5)) != 0)
{
printf("- Bit5 (VOUT_UVW): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit4: VOUT_UVF (Output Under-Voltage Fault)
if (status & (1 << 4))
{
printf("- Bit4 (VOUT_UVF): Output Under-Voltage Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit4 (VOUT_UVF): No output under-voltage fault detected.\n");
}
// Bit3: VOUT_MIN_MAX (Output Voltage Max/Min Exceeded Warning)
if (status & (1 << 3))
{
printf("- Bit3 (VOUT_MIN_MAX): Output voltage exceeded VOUT_MAX/VOUT_MIN limits. "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit3 (VOUT_MIN_MAX): Output voltage within VOUT_MAX/VOUT_MIN limits.\n");
}
// Bit2: TON_MAX (Unsupported, always 0)
if ((status & (1 << 2)) != 0)
{
printf("- Bit2 (TON_MAX): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit1: TOFF_MAX (Unsupported, always 0)
if ((status & (1 << 1)) != 0)
{
printf("- Bit1 (TOFF_MAX): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit0: VOUT_TRACK (Unsupported, always 0)
if ((status & (1 << 0)) != 0)
{
printf("- Bit0 (VOUT_TRACK): Anomaly (this bit is unsupported and should be 0).\n");
}
return 0;
}
int parse_status_iout(uint8_t addr)
{
uint8_t status = 0; // Store 8-bit status value
read_from_reg(addr, &status, 1);
printf("\nRaw value: 0x%02X\n", status);
// Bit7: IOUT_OCF (Output Over-Current Fault)
if (status & (1 << 7))
{
printf("- Bit7 (IOUT_OCF): Output Over-Current Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit7 (IOUT_OCF): No output over-current fault detected.\n");
}
// Bit6: IOUT_OCUVF (Unsupported, always 0)
if ((status & (1 << 6)) != 0)
{
printf("- Bit6 (IOUT_OCUVF): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit5: IOUT_OCW (Output Over-Current Warning)
if (status & (1 << 5))
{
printf("- Bit5 (IOUT_OCW): Output Over-Current Warning detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit5 (IOUT_OCW): No output over-current warning detected.\n");
}
// Bit4: IOUT_UCF (Unsupported, always 0)
if ((status & (1 << 4)) != 0)
{
printf("- Bit4 (IOUT_UCF): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit3: CUR_SHAREF (Current Sharing Fault)
if (status & (1 << 3))
{
printf("- Bit3 (CUR_SHAREF): Current Sharing Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit3 (CUR_SHAREF): No current sharing fault detected.\n");
}
// Bit2: POW_LIMIT (Unsupported, always 0)
if ((status & (1 << 2)) != 0)
{
printf("- Bit2 (POW_LIMIT): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit1: POUT_OPF (Unsupported, always 0)
if ((status & (1 << 1)) != 0)
{
printf("- Bit1 (POUT_OPF): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit0: POUT_OPW (Unsupported, always 0)
if ((status & (1 << 0)) != 0)
{
printf("- Bit0 (POUT_OPW): Anomaly (this bit is unsupported and should be 0).\n");
}
return 0;
}
int parse_status_input(uint8_t addr)
{
uint8_t status = 0;
read_from_reg(addr, &status, 1);
// Step 2: Parse status bits and log results
printf("\n===== STATUS_INPUT (0x7C) Parsing Results =====");
printf("\nRaw value: 0x%02X\n", status);
// Bit7: VIN_OVF (Input Over-Voltage Fault)
if (status & (1 << 7))
{
printf("- Bit7 (VIN_OVF): Input Over-Voltage Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit7 (VIN_OVF): No input over-voltage fault detected.\n");
}
// Bit6: VIN_OVW (Unsupported, always 0)
if ((status & (1 << 6)) != 0)
{
printf("- Bit6 (VIN_OVW): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit5: VIN_UVW (Unsupported, always 0)
if ((status & (1 << 5)) != 0)
{
printf("- Bit5 (VIN_UVW): Anomaly (this bit is unsupported and should be 0).\n");
}
// Bit4: VIN_UVF (Input Under-Voltage Fault)
if (status & (1 << 4))
{
printf("- Bit4 (VIN_UVF): Input Under-Voltage Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit4 (VIN_UVF): No input under-voltage fault detected.\n");
}
// Bit3: LOW_VIN (Input Voltage Insufficient)
if (status & (1 << 3))
{
printf("- Bit3 (LOW_VIN): Converter turned off due to insufficient input voltage (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit3 (LOW_VIN): Input voltage sufficient (no shutdown due to LOW_VIN).\n");
}
// Bit2: IIN_OCF (Input Over-Current Fault)
if (status & (1 << 2))
{
printf("- Bit2 (IIN_OCF): Input Over-Current Fault detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit2 (IIN_OCF): No input over-current fault detected.\n");
}
// Bit1: IIN_OCW (Input Over-Current Warning)
if (status & (1 << 1))
{
printf("- Bit1 (IIN_OCW): Input Over-Current Warning detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit1 (IIN_OCW): No input over-current warning detected.\n");
}
// Bit0: PIN_OPW (Input Over-Power Warning)
if (status & (1 << 0))
{
printf("- Bit0 (PIN_OPW): Input Over-Power Warning detected (latched). "
"Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit0 (PIN_OPW): No input over-power warning detected.\n");
}
return 0;
}
int parse_status_temperature(uint8_t addr)
{
uint8_t status = 0;
read_from_reg(addr, &status, 1);
printf("\nRaw Value: 0x%02X\n", status);
// Bit7: OTF(过热故障)
if (status & (1 << 7))
{
printf("- Bit7 (OTF): Over-Temperature Fault (latched). "
"Temperature exceeds fault threshold. Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit7 (OTF): No over-temperature fault detected.\n");
}
// Bit6: OTW(过热警告)
if (status & (1 << 6))
{
printf("- Bit6 (OTW): Over-Temperature Warning (latched). "
"Temperature approaching threshold. Clear by writing 1 to this bit.\n");
}
else
{
printf("- Bit6 (OTW): No over-temperature warning detected.\n");
}
// 保留位检查(Bit5~Bit0)
if (status & 0x1F)
{ // Bit5~0 应为0
printf("- WARNING: Reserved bits (Bit5~0) are non-zero (0x%02X). "
"This may indicate hardware异常.\n",
status & 0x1F);
}
return 0;
}
int parse_status_cml(uint8_t addr)
{
uint8_t status = 0; // 存储寄存器原始值
read_from_reg(addr, &status, 1);
// ---------------------- 步骤 2:输出原始值 ----------------------
printf("\n===== TPS53681 STATUS_CML (0x7E) 解析结果 =====");
printf("\n原始值: 0x%02X(二进制: %08b)\n", status, status);
// ---------------------- 步骤 3:逐位解析状态 ----------------------
// Bit7: IV_CMD(无效/不支持命令标志)
if (status & CML_IV_CMD_MASK)
{
printf("- Bit7 (IV_CMD): 检测到无效或不支持的命令(锁存)。\n"
" 说明: 曾接收到 TPS53681 不支持的 PMBus 命令。\n"
" 清除方法: 向该位写 1 清除。\n");
}
else
{
printf("- Bit7 (IV_CMD): 未检测到无效命令。\n");
}
// Bit6: IV_DATA(无效/不支持数据标志)
if (status & CML_IV_DATA_MASK)
{
printf("- Bit6 (IV_DATA): 检测到无效或不支持的数据(锁存)。\n"
" 说明: 曾接收到命令中携带的无效参数(如超出范围的电压值)。\n"
" 清除方法: 向该位写 1 清除。\n");
}
else
{
printf("- Bit6 (IV_DATA): 未检测到无效数据。\n");
}
// Bit5: PEC_FAIL(PEC 校验失败标志)
if (status & CML_PEC_FAIL_MASK)
{
printf("- Bit5 (PEC_FAIL): 检测到 PEC 校验失败(锁存)。\n"
" 说明: 曾接收到的 PMBus 数据包 PEC 校验不通过。\n"
" 清除方法: 向该位写 1 清除。\n");
}
else
{
printf("- Bit5 (PEC_FAIL): 未检测到 PEC 校验失败。\n");
}
// Bit4: Reserved(保留位,必须为 0)
if (status & (1 << 4))
{
printf("- Bit4: 保留位异常(值非 0),可能硬件故障。\n");
}
else
{
printf("- Bit4: 保留位正常(值为 0)。\n");
}
// Bit3: MEM(内存/NVM 错误标志)
if (status & CML_MEM_MASK)
{
printf("- Bit3 (MEM): 检测到内存/NVM 错误(锁存)。\n"
" 说明: 内部非易失性存储器(如配置寄存器)读写失败。\n"
" 清除方法: 向该位写 1 清除。\n");
}
else
{
printf("- Bit3 (MEM): 未检测到内存错误。\n");
}
// Bit2: Reserved(保留位,必须为 0)
if (status & (1 << 2))
{
printf("- Bit2: 保留位异常(值非 0),可能硬件故障。\n");
}
else
{
printf("- Bit2: 保留位正常(值为 0)。\n");
}
// Bit1: COM_FAIL(其他通信故障标志)
if (status & CML_COM_FAIL_MASK)
{
printf("- Bit1 (COM_FAIL): 检测到其他通信故障(锁存)。\n"
" 说明: 非 PEC/命令/数据错误的通信问题(如总线超时)。\n"
" 清除方法: 向该位写 1 清除。\n");
}
else
{
printf("- Bit1 (COM_FAIL): 未检测到其他通信故障。\n");
}
// Bit0: CML_OTHER(不支持位,必须为 0)
if (status & (1 << 0))
{
printf("- Bit0: 不支持位异常(值非 0),可能硬件故障。\n");
}
else
{
printf("- Bit0: 不支持位正常(值为 0)。\n");
}
return 0;
}
int parse_status_mfr_specific(uint8_t addr)
{
uint8_t status = 0;
read_from_reg(addr, &status, 1);
printf("MFR_SPECIFIC_STATUS: 0x%02X\n", status);
// Bit7: MFR_FAULT_PS (Power stage fault - latched)
if (status & MFR_FAULT_PS_MASK)
{
printf("- Bit7 (MFR_FAULT_PS): Power stage fault detected (latched).\n");
}
// Bit6: VSNS_OPEN (VSNS pin open - latched)
if (status & VSNS_OPEN_MASK)
{
printf("- Bit6 (VSNS_OPEN): VSNS pin open detected (latched)\n");
}
// Bit5: MAX_PH_WARN (Max phase warning - latched)
if (status & MAX_PH_WARN_MASK)
{
printf("- Bit5 (MAX_PH_WARN): Max phase count exceeded (latched).\n");
}
// Bit4: TSNS_LOW (TSEN ≥ 150mV before soft start)
if (status & TSNS_LOW_MASK)
{
printf("- Bit4 (TSNS_LOW): TSEN voltage high before soft start.\n");
}
// Bit3: RST_VID (VID reset occurred)
if (status & RST_VID_MASK)
{
printf("- Bit3 (RST_VID): VID reset executed (Page 0 only).\n");
}
// Bit2~1: Reserved (should be 0)
if ((status & 0x06) != 0)
{
printf("- Bit2~1: Reserved bits set unexpectedly (0x%02X).\n", status & 0x06);
}
// Bit0: PHFLT (Phase current sharing fault - latched)
if (status & PHFLT_MASK)
{
printf("- Bit0 (PHFLT): Phase current sharing fault detected (latched).\n");
}
return 0;
}
int deal_status_reg(uint8_t addr)
{
int ret;
switch (addr)
{
case REG_STATUS_BYTE:
ret = parse_status_byte(addr);
break;
case REG_STATUS_WORD:
ret = parse_status_word(addr);
break;
case REG_STATUS_VOUT:
ret = parse_status_vout(addr);
break;
case REG_STATUS_IOUT:
ret = parse_status_iout(addr);
break;
case REG_STATUS_INPUT:
ret = parse_status_input(addr);
break;
case REG_STATUS_TEMP:
ret = parse_status_temperature(addr);
break;
case REG_STATUS_CML:
parse_status_cml(addr);
break;
case REG_STATUS_MFR_SPECIFIC:
ret = parse_status_mfr_specific(addr);
break;
default:
break;
}
}
int check_status_error_(void)
{
int i;
for (i = 0; i < status_regs_count; i++)
{
/* code */
}
}
// 5mV 步进模式的 VID 转电压
int vid_to_voltage_5mv(int val)
{
if (val < 1 || val > 0xFF)
{
return 0; // 返回 0 表示无效
}
return 250 + (val - 1) * 5;
}
int16_t voltage_to_vid_5mv(uint16_t value)
{
// 电压小于 250mV,无效,返回 VID = 0
if (value < 250)
{
return 0;
}
// 向上取整到最接近的 5mV
value = (value + 4) / 5 * 5;
// 计算 VID
uint8_t vid = (value - 250) / 5 + 1;
// 如果 VID 超出有效范围,返回最大 VID (0xFF)
return (vid > 0xFF) ? 0xFF : vid;
}
/**
* @description: 设置 VR_MODE 为 5mV 模式的函数
* @return {*}
*/
int set_5mv_dac_mode(void)
{
uint8_t current_value[2];
// 读取 MFR_SPECIFIC_13 寄存器的当前值
if (read_from_reg(MFR_SPECIFIC_13, current_value, sizeof(current_value)) != 0)
{
return -1;
}
// 清除 VR_MODE 位(位 7 - 5)
current_value[0] &= ~(0x07 << 5);
// 设置 VR_MODE 为 5mV 模式(0x07 << 5)
current_value[1] |= (0x07 << 5);
// 将修改后的值写回 MFR_SPECIFIC_13 寄存器
if (write_to_reg(MFR_SPECIFIC_13, current_value, sizeof(current_value)) != 0)
{
return -1;
}
return 0;
}
/** tps53681 该寄存器默认为21 5mv模式
* @description: 先获取确认是5mv, 不是重新设置输出电压的步长
* @return {*}
*/
VoutMode set_vout_mode(void)
{
uint8_t status = 0;
if (read_from_reg(VOUT_MODE_REG, &status, sizeof(status)) != 0)
{
// 处理I2C读取错误
return -1;
}
printf(" status %d\n", status);
if (status == VOUT_MODE_5MV)
{
return VOUT_MODE_5MV;
}
set_5mv_dac_mode();
return VOUT_MODE_5MV;
}
/**
* @description: 设置警报掩码的函数
* @param {uint8_t} status_reg_addr
* @param {uint8_t} offset
* @return {*}
*/
void set_alert_mask(uint8_t status_reg_addr, uint8_t offset)
{
uint8_t reg[3];
if (read_from_reg(SMBALERT_MASK_REGISTER, ®[2], 1) != 0)
{
// return -1;
}
reg[0] = SMBALERT_MASK_REGISTER;
reg[1] = status_reg_addr;
reg[2] |= 1 << offset;
write_to_reg(SMBALERT_MASK_REGISTER, reg, sizeof(reg));
}
/**
* @description: // 禁止 STATUS_VOUT 中的欠压故障
* @return {*}
*/
void disable_under_voltage(void)
{
set_alert_mask(STATUS_VOUT_REGISTER, 4);
}
void set_phase_num(uint8_t page, uint8_t num)
{
write_to_reg(PAGE_REGISTER, &page, 1);
write_to_reg(MFR_PHASE_CONFIG_REGISTER, &num, 1);
}
uint16_t current_to_register_value(uint16_t current)
{
uint8_t exp = 0;
uint16_t reg_value;
if (current >= 0x07FF)
{
// 如果超出范围,将电流值设置为尾数位能表示的最大值 单位A
current = 0x07FF;
}
// 组合指数和尾数,指数位全 0 时,直接用尾数表示电流值
reg_value = (exp << 11) | current;
return reg_value;
}
/**
* @description: 选择通道A、B
* @param {uint8_t} page 0:A, 1:B
* @return {*}
*/
void select_page(uint8_t page)
{
write_to_reg(PAGE_REGISTER, &page, 1);
}
/**
* @description: 输出电流的过流阈值
* @param {uint8_t} addr
* @param {uint16_t} current
* @return {*}
*/
int8_t set_register_bit10(uint8_t addr, uint16_t current)
{
uint16_t value = current_to_register_value(current);
return write_to_reg(addr, (uint8_t *)&value, sizeof(value));
}
int16_t set_vout_register(uint16_t value)
{
int16_t voltage;
voltage = voltage_to_vid_5mv(value);
printf("set voltage:%02x\n", voltage);
return write_to_reg(VOUT_COMMAND_REGISTER, &voltage, sizeof(voltage));
}
// 配置 MFR_SPECIFIC_13 寄存器的 VR_MODE 和 OTF_DFLT 位
int8_t configure_mfr_specific_13(uint8_t vr_mode, uint8_t otf_dflt)
{
uint16_t current_value;
uint16_t new_value;
if (vr_mode || otf_dflt)
{
return -1;
}
// 读取当前寄存器值
read_from_reg(MFR_SPECIFIC_13, (uint8_t *)¤t_value, sizeof(current_value)); // todo 有一样的
// 仅当参数非零时设置对应位
if (vr_mode)
{
// 清除目标位(VR_MODE和OTF_DFLT)
current_value &= ~(0x07 << 5); // 清除位7-5
new_value |= (vr_mode << 5); // 设置VR_MODE(位7-5)
}
if (otf_dflt)
{
current_value &= ~(0x01 << 11); // 清除位11
new_value |= (otf_dflt << 11); // 设置OTF_DFLT(位11)
}
// 初始化new_value为清除后的当前值
new_value = current_value;
// 写入新的值到寄存器
write_to_reg(MFR_SPECIFIC_13, (uint8_t *)&new_value, sizeof(new_value));
return 0;
}
// 配置 MFR_SPECIFIC_10
/**
* @description: 设置最大输出电流 单位1A
* @param {uint8_t} max_electr
* @return {*}
*/
void configure_mfr_specific_10(uint8_t max_electr)
{
uint8_t current_value[2] = {0};
// 读取当前寄存器值
read_from_reg(MFR_SPECIFIC_10, current_value, sizeof(current_value));
// 清除目标位
current_value[0] &= ~(0xFF); // 清除低8bit
// 设置新的值
current_value[0] = max_electr;
// 写入新的值到寄存器
write_to_reg(MFR_SPECIFIC_10, current_value, sizeof(current_value));
}
// 定期读取电压电流函数
// void Monitor_Parameters(void)
// {
// uint8_t vout_data[2];
// uint8_t iout_data[2];
// read_from_reg(CMD_READ_VOUT, vout_data, sizeof(vout_data));
// printf("Vout: Read data, need conversion\n");
// read_from_reg(CMD_READ_IOUT, iout_data, sizeof(iout_data));
// printf("Iout: Read data, need conversion\n");
// }
#if 0
void configure_chip(void)
{
select_page(0); // 选择通道 A
set_vout_mode(); // 先获取是什么数值,获取模式
set_vout_register(VOUT_COMMAND_REGISTER, 1000); // 设置1000mv,对应vid为0x9700
write_to_reg(VOUT_UV_FAULT_RESPONSE, &(0XBA), 1); // 欠压响应 默认0x80
configure_mfr_specific_10(10); // 设置过流阈值 10A
set_register_bit10(IOUT_OC_FAULT_LIMIT, 10); // 10:0 1A
set_register_bit10(IOUT_OC_WARN_LIMIT, 255); // 10:0 1A 根据FPGA的供电电流配置 // 设置过流阈值警告 最大255A 单位1A
write_to_reg(IOUT_OC_FAULT_RESPONSE,&(0xC0), 1); // 响应输出过流故障
configure_mfr_specific_13(NONE, NONE);
set_register_bit10(OT_FAULT_LIMIT, 0x80); // 设置最大温度 //10:0 默认135
set_register_bit10(OT_WARN_LIMIT, 0x69); // 默认105度 // 设置警告温度
write_to_reg(OT_FAULT_RESPONSE_REG, &(0x80), 1); // 设置过温处理
// 使能 OPERATION 命令控制
write_to_reg(ON_OFF_CONFIG_REGISTER, &(0x1B), 1);
// 开启输出
write_to_reg(OPERATION_REGISTER, &(0x80), 1);
// write_to_reg(OPERATION_REGISTER, 0x00,1);//关闭
}
#endif
void configure_chip(void)
{
uint8_t data;
select_page(0); // 选择通道 A
// set_vout_mode(); // 先获取是什么数值,获取模式
// set_vout_register(VOUT_COMMAND_REGISTER, 1000); // 设置输出电压为1000mv
data = 0XBA;
write_to_reg(VOUT_UV_FAULT_RESPONSE, &data, 1); // 欠压响应 默认0x80 关机不重启, 欠压芯片20ms后重启
configure_mfr_specific_10(10); // 设置最大输出电流 10A
set_register_bit10(IOUT_OC_FAULT_LIMIT, 10); // 过流阈值
set_register_bit10(IOUT_OC_WARN_LIMIT, 255); // 10:0 1A 根据FPGA的供电电流配置 // 设置过流阈值警告 最大255A 单位1A
data = 0xC0;
write_to_reg(IOUT_OC_FAULT_RESPONSE, &data, 1); // 响应输出过流故障
// configure_mfr_specific_13(NONE, NONE);
set_register_bit10(OT_FAULT_LIMIT, 0x80); // 设置最大温度 //10:0 默认135
set_register_bit10(OT_WARN_LIMIT, 0x69); // 默认105度 // 设置警告温度
data = 0x80;
write_to_reg(OT_FAULT_RESPONSE_REG, &data, 1); // 设置过温处理
// 使能 OPERATION 命令控制
data = 0x1B;
write_to_reg(ON_OFF_CONFIG_REGISTER, &data, 1);
// 开启输出
data = 0x80;
write_to_reg(OPERATION_REGISTER, &data, 1);
// write_to_reg(OPERATION_REGISTER, 0x00,1);//关闭
}
// 分隔线打印(固定格式)
static void print_separator(void)
{
printf("\n+++++++++++++++++++++++++++++++++++++\n");
}
// 操作头信息打印(通用标题)
static void print_operation_header(const char *op_type, uint8_t reg, uint8_t len)
{
printf("======= %s: reg=0x%02X, len=%d\n", op_type, reg, len);
}
// 缓冲区内容打印(通用数组打印)
static void print_buffer(const char *buf_type, uint8_t reg, uint8_t len, const uint8_t *buf)
{
uint8_t i;
for (i = 0; i < len; i++)
{
printf("%s[%d] = 0x%02X ", buf_type, i, buf[i]);
if (i == len - 1)
{
printf("\n");
}
}
}
void reg_test(uint8_t reg, uint8_t *buf, uint8_t len)
{
uint8_t value[2], i; // 注意:原逻辑限制最大长度为2字节(sizeof(value)=2)
uint8_t value2[2] = {0};
// 长度校验(保持原有逻辑)
if (len > sizeof(value))
{
printf("[ERROR] len (%d) exceeds buffer size\n", len);
return;
}
print_separator(); // 顶部分隔线
// 读取原始值
print_operation_header("before write", reg, len);
read_from_reg(reg, value, len);
print_buffer("read", reg, len, value);
// 写入新值
print_operation_header("to reg", reg, len);
print_buffer("write", reg, len, buf);
write_to_reg(reg, buf, len);
// 验证写入结果
print_operation_header("after write", reg, len);
read_from_reg(reg, value2, len);
print_buffer("read", reg, len, value2);
print_separator(); // 底部分隔线
}
void page_test(void)
{
uint8_t page = 0, data = 0;
uint8_t buf2[2] = {0};
uint16_t vid;
reg_test(PAGE_REGISTER, &page, 1);
}
void out_voltage(void)
{
uint8_t page = 0, data = 0;
uint8_t buf2[2] = {0};
uint16_t vid;
vid = voltage_to_vid_5mv(360);
buf2[0] = (uint8_t)(vid & 0xFF); // low byte
buf2[1] = (uint8_t)(vid >> 8); // high byte
printf("VID=0x%04X, buf: %02x, %02x\n", vid, buf2[0], buf2[1]);
reg_test(VOUT_COMMAND_REGISTER, buf2, 2);
}
void enable_test(void)
{
uint8_t page = 0, data = 0;
uint8_t buf2[2] = {0};
uint16_t vid;
data = 0x80;
reg_test(OPERATION_REGISTER, &data, 1);
}
void get_out_mode(void)
{
uint8_t mode = 0;
read_from_reg(VOUT_MODE_REG, &mode, 1);
printf("mode %02x\n", mode);
}
void get_on_off_config(void)
{
uint8_t mode = 0;
read_from_reg(ON_OFF_CONFIG_REGISTER, &mode, 1);
printf("ON_OFF_CONFIG %02x\n", mode);
}
void get_up_rate(void)
{
uint8_t buf2[2] = {0};
read_from_reg(VOUT_RATE_REG, buf2, 2);
printf("VOUT_RATE_REG=0x%04X, buf: %02x, %02x\n", VOUT_RATE_REG, buf2[0], buf2[1]);
}
void get_vout_fault_limit(void)
{
uint8_t buf2[2] = {0};
read_from_reg(VOUT_OV_FAULT_LIMIT, buf2, 2);
printf("VOUT_OV_FAULT_LIMIT=0x%04X, buf: %02x, %02x\n", VOUT_OV_FAULT_LIMIT, buf2[0], buf2[1]);
}
void MFR_SPECIFIC_13_test(void)
{
uint8_t page = 0, data = 0;
uint8_t buf2[2] = {0};
uint16_t vid;
// read_from_reg(MFR_SPECIFIC_13, buf2, 2);
// printf("MFR_SPECIFIC_13=0x%04X, buf: %02x, %02x\n", MFR_SPECIFIC_13, buf2[0], buf2[1]);
// buf2[0] = 0xE5; // low byte
// buf2[1] = 0x88; // high byte 89 1/16 88 1/4
// printf("MFR_SPECIFIC_13: %02x, buf: %02x, %02x\n", MFR_SPECIFIC_13, buf2[0], buf2[1]);
// reg_test(MFR_SPECIFIC_13, buf2, 2);
read_from_reg(MFR_SPECIFIC_13, buf2, 2);
printf("MFR_SPECIFIC_13: %02x, buf: %02x, %02x\n", MFR_SPECIFIC_13, buf2[0], buf2[1]);
}
// 读取输出电压(单位 mV,LSB = 0.625mV,适用于 Intel VR13 模式)
int tps53681_read_vout_voltage(void)
{
uint16_t raw = 0;
read_from_reg(READ_VOUT_REG, &raw, 2);
print_buffer(" vout", READ_VOUT_REG, 2, &raw);
return 0;
}
// 读取芯片温度(单位 °C,LSB = 0.125°C)
int tps53681_read_temperature()
{
uint16_t raw;
read_from_reg(READ_TEMPER_REG, &raw, 2);
print_buffer(" temper", READ_TEMPER_REG, 2, &raw);
return 0;
}
// 读取某个相位的输出电流(单位 A,LSB = 0.125A)
// int tps53681_read_iout_phase(uint8_t phase, float *current)
// {
// if (phase >= TPS53681_MAX_PHASES)
// return -1;
// if (tps_set_page(0) < 0)
// return -1;
// // 设置 PHASE = 0x80 | phase
// if (tps_i2c_write_byte(PMBUS_PHASE, 0x80 | (phase & 0x0F)) < 0)
// return -1;
// uint16_t raw;
// if (tps_i2c_read_word(PMBUS_READ_IOUT, &raw) < 0)
// return -1;
// *current = raw * 0.125f;
// return 0;
// }
// 读取总输出电流(phase 设置为 0x80 表示全部相位)
int tps53681_read_iout_total(void)
{
uint16_t raw = 0;
uint8_t cmd = 0x80;
write_to_reg(MFR_PHASE_CONFIG_REGISTER, &cmd, 1);
read_from_reg(READ_IOUT_REG, &raw, 2);
return 0;
}
// int tps53681_init1(void)
// {
// gpio_init(TPS53681_AVREN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, TPS53681_AVREN_PIN);
// gpio_bit_reset(TPS53681_AVREN_PORT, TPS53681_AVREN_PIN);
// return 0;
// }
void clear_error(void)
{
uint16_t num = 0x0000;
write_to_reg(CLERA_FAULT_REG, &num, 2);
}
void tps53681_init(void)
{
page_test();
// clear_error();
// parse_status_word(REG_STATUS_WORD);
// MFR_SPECIFIC_13_test();
get_on_off_config(); // ON_OFF_CONFIG 1B
get_out_mode(); // mode 21
// get_up_rate();
// get_vout_fault_limit();
// tps53681_read_temperature();
out_voltage();
enable_test();
parse_status_byte(REG_STATUS_BYTE);
parse_status_word(REG_STATUS_WORD);
parse_status_mfr_specific(REG_STATUS_MFR_SPECIFIC);
tps53681_read_vout_voltage();
}
// void tps53681_init(void)
// {
// uint8_t page = 0, value[2] = {0}, data = 0;
// uint16_t voltage = 0;
// reg_test(PAGE_REGISTER, &page, 1);
// printf("====== page 0 ======\n");
// reg_test(PAGE_REGISTER, &page, 1);
// voltage = voltage_to_vid_5mv(800);
// value[0] = voltage & 0xFF;
// value[1] = voltage >> 8;
// printf(" set voltage :%02x", voltage);
// reg_test(VOUT_COMMAND_REGISTER, &value, 2);
// // 开启输出 // 使能 OPERATION 命令控制
// data = 0x80;
// reg_test(OPERATION_REGISTER, &data, 1);
// printf("====== enable ======\n");
// // disable_under_voltage();
// // configure_chip();
// }
void reset_chip(void)
{
// MCU PA15
// 警报 PA1
}
======= before write: reg=0x00, len=1 read[0] = 0x00 ======= to reg: reg=0x00, len=1 write[0] = 0x00 ======= after write: reg=0x00, len=1 read[0] = 0x00 +++++++++++++++++++++++++++++++++++++ ON_OFF_CONFIG 1b mode 21 temper[0] = 0xAC temper[1] = 0xE2 VID=0x0017, buf: 17, 00 +++++++++++++++++++++++++++++++++++++ ======= before write: reg=0x21, len=2 read[0] = 0x17 read[1] = 0x00 ======= to reg: reg=0x21, len=2 write[0] = 0x17 write[1] = 0x00 ======= after write: reg=0x21, len=2 read[0] = 0x17 read[1] = 0x00 +++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++ ======= before write: reg=0x01, len=1 read[0] = 0x80 ======= to reg: reg=0x01, len=1 write[0] = 0x80 ======= after write: reg=0x01, len=1 read[0] = 0x80 +++++++++++++++++++++++++++++++++++++ status_byte: not providing power to VOUT: 41 status_byte: Unclassified fault (e.g., UVF, OCW; check other status registers) status_word: value: 0x1841 (Bytes: 0x41 0x18) status_word: MFR bit warning status_word: Power NOT good (AVR_RDY/BVR_RDY pin is LOW) status_word: Not providing power to VOUT status_word: Unclassified fault detected MFR_SPECIFIC_STATUS: 0x40 - Bit6 (VSNS_OPEN): VSNS pin open detected (latched) vout[0] = 0x00 vout[1] = 0x00




