master-thesis/netpfga/minip4/simple_sume_switch/sw/embedded/src/iic_pm.c

210 lines
5.2 KiB
C

/*
* Copyright (c) 2015 Digilent Inc.
* Copyright (c) 2015 Tinghui Wang (Steve)
* All rights reserved.
*
* File:
* sw/embedded/src/iic_pm.c
*
* Project:
* Reference project
*
* Author:
* Tinghui Wang (Steve)
*
* Description:
* Iic codes to read power information about NetFPGA-SUME boards through
* PMBus.
*
* @NETFPGA_LICENSE_HEADER_START@
*
* Licensed to NetFPGA C.I.C. (NetFPGA) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. NetFPGA licenses this
* file to you under the NetFPGA Hardware-Software License, Version 1.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.netfpga-cic.org
*
* Unless required by applicable law or agreed to in writing, Work distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @NETFPGA_LICENSE_HEADER_END@
*
*/
#include "iic_config.h"
#include "xstatus.h"
#include <stdio.h>
#define PM_CMD_LOAD_PAGE 0x00
#define PM_CMD_POUT 0x96
#define PM_CMD_VOUT 0x8B
#define PM_CMD_IOUT 0x8C
struct pm_info {
char* railName;
u8 i2cAddress;
u8 pageIndex;
u16 voltage;
u16 current;
u16 power;
};
struct pm_info pm[8] = {
{
.railName = "VCC1V0",
.i2cAddress = 0x5C,
.pageIndex = 0,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "VCC1V5",
.i2cAddress = 0x5D,
.pageIndex = 2,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "VCC1V8",
.i2cAddress = 0x5C,
.pageIndex = 1,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "VCC2V0",
.i2cAddress = 0x5C,
.pageIndex = 2,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "VCC3V3",
.i2cAddress = 0x5D,
.pageIndex = 1,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "MGTAVCC",
.i2cAddress = 0x5C,
.pageIndex = 3,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "MGTAVTT",
.i2cAddress = 0x5D,
.pageIndex = 0,
.voltage = 0,
.current = 0,
.power = 0
},{
.railName = "MGTVAUX",
.i2cAddress = 0x5D,
.pageIndex = 3,
.voltage = 0,
.current = 0,
.power = 0
}
};
/*
* This function reads the information of Power Management
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
*/
int pmReadInfo(void) {
int Status;
int i;
u8 WriteBuffer[10];
u8 ReadBuffer[30];
/*
* Write to the IIC Switch.
*/
WriteBuffer[0] = IIC_BUS_PCON; //Select Bus7 - DDR3
Status = IicWriteData(IIC_SWITCH_ADDRESS, WriteBuffer, 1);
if (Status != XST_SUCCESS) {
xil_printf("pmReadInfo: PCA9548 FAILED to select PM IIC Bus\r\n");
return XST_FAILURE;
}
for(i = 0; i < 8; i++) {
int decimal;
int small;
/*
* Load Corresponding Page Info
*/
WriteBuffer[0] = PM_CMD_LOAD_PAGE;
WriteBuffer[1] = pm[i].pageIndex; //Select Bus7 - Si5326
Status = IicWriteData(pm[i].i2cAddress, WriteBuffer, 2);
if (Status != XST_SUCCESS) {
xil_printf("PMBus[%x]: Load Page %d Failed\r\n", pm[i].i2cAddress, pm[i].pageIndex);
return XST_FAILURE;
}
xil_printf("Power Rail %s:\r\n", pm[i].railName);
Status = IicReadData(pm[i].i2cAddress, PM_CMD_LOAD_PAGE, ReadBuffer, 1);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
// xil_printf("Page: %d\r\n", ReadBuffer[0]);
/*
* Read Voltage
*/
Status = IicReadData(pm[i].i2cAddress, PM_CMD_VOUT, ReadBuffer, 2);
if (Status != XST_SUCCESS) {
xil_printf("PMBus[%x]: IIC Read Failed\r\n", pm[i].i2cAddress);
return XST_FAILURE;
}
pm[i].voltage = (ReadBuffer[1] << 8) + ReadBuffer[0];
// xil_printf("Voltage: 0x%x 0x%x V\r\n", ReadBuffer[0], ReadBuffer[1]);
// xil_printf("Voltage: 0x%x, %d V\r\n", pm[i].voltage, pm[i].voltage);
decimal = pm[i].voltage >> 13;
small = (pm[i].voltage - (decimal <<13)) * 1000 / (1<<13);
xil_printf("\tVoltage: %d.%d V\r\n", decimal, small);
/*
* Read Current
*/
Status = IicReadData(pm[i].i2cAddress, PM_CMD_IOUT, ReadBuffer, 2);
if (Status != XST_SUCCESS) {
xil_printf("PMBus[%x]: IIC Read Failed\r\n", pm[i].i2cAddress);
return XST_FAILURE;
}
pm[i].current = (ReadBuffer[1] << 8) + ReadBuffer[0];
// xil_printf("Current: 0x%x 0x%x V\r\n", ReadBuffer[0], ReadBuffer[1]);
// xil_printf("Current: 0x%x, %d V\r\n", pm[i].current, pm[i].current);
decimal = pm[i].current >> 13;
small = (pm[i].current - (decimal <<13)) * 1000 / (1<<13);
xil_printf("\tCurrent: %d.%d A\r\n", decimal, small);
/*
* Read Voltage
*/
Status = IicReadData(pm[i].i2cAddress, PM_CMD_POUT, ReadBuffer, 2);
if (Status != XST_SUCCESS) {
xil_printf("PMBus[%x]: IIC Read Failed\r\n", pm[i].i2cAddress);
return XST_FAILURE;
}
pm[i].power = (ReadBuffer[1] << 8) + ReadBuffer[0];
// xil_printf("Power: 0x%x 0x%x V\r\n", ReadBuffer[0], ReadBuffer[1]);
// xil_printf("Power: 0x%x, %d V\r\n", pm[i].power, pm[i].power);
decimal = pm[i].power >> 13;
small = (pm[i].power - (decimal <<13)) * 1000 / (1<<13);
xil_printf("\tPower: %d.%d W\r\n", decimal, small);
}
return XST_SUCCESS;
}