bool peci_getPwr()

in common/util/hal_peci.c [131:224]


bool peci_getPwr(uint8_t sensor_num, int *reading)
{
	uint8_t rdpkgcfgCmd = PECI_RD_PKG_CFG0_CMD;
	uint8_t PECIaddr = 0x30;
	uint8_t readlen = 0x05;
	uint8_t *readbuf = (uint8_t*)malloc(2 * readlen * sizeof(uint8_t));
	uint8_t u8index[2] = { 0x03, 0x1F };
	uint16_t u16Param[2] = { 0x00FF, 0x0000 };
	uint8_t ret, complete_code;
	bool is_retry_success = false;
	uint32_t pkg_energy, run_time, diff_energy, diff_time;
	static uint32_t last_pkg_energy = 0, last_run_time = 0;

	peci_read(rdpkgcfgCmd, PECIaddr, u8index[0], u16Param[0], readlen, readbuf);
	complete_code = readbuf[0];
	if (complete_code == PECI_CC_RSP_TIMEOUT ||
	    complete_code == PECI_CC_OUT_OF_RESOURCES_TIMEOUT) {
		is_retry_success = peci_retry_read(rdpkgcfgCmd, PECIaddr, u8index[0], u16Param[0],
						   readlen, readbuf);
		if (!is_retry_success) {
			printf("PECI sensor [%x] response timeout. Reach Max retry.\n", sensor_num);
			free(readbuf);
			return false;
		}
	}
	ret = peci_read(rdpkgcfgCmd, PECIaddr, u8index[1], u16Param[1], readlen, &readbuf[5]);
	complete_code = readbuf[5];
	if (complete_code == PECI_CC_RSP_TIMEOUT ||
	    complete_code == PECI_CC_OUT_OF_RESOURCES_TIMEOUT) {
		is_retry_success = peci_retry_read(rdpkgcfgCmd, PECIaddr, u8index[1], u16Param[1],
						   readlen, &readbuf[5]);
		if (!is_retry_success) {
			printf("PECI sensor [%x] response timeout. Reach Max retry.\n", sensor_num);
			free(readbuf);
			return false;
		}
	}
	if (ret) {
		free(readbuf);
		return false;
	}
	if (readbuf[0] != PECI_CC_RSP_SUCCESS || readbuf[5] != PECI_CC_RSP_SUCCESS) {
		if (readbuf[0] == PECI_CC_ILLEGAL_REQUEST ||
		    readbuf[5] == PECI_CC_ILLEGAL_REQUEST) {
			printf("Unknown request\n");
		} else {
			printf("PECI control hardware, firmware or associated logic error\n");
		}
		free(readbuf);
		return false;
	}

	pkg_energy = readbuf[4];
	pkg_energy = (pkg_energy << 8) | readbuf[3];
	pkg_energy = (pkg_energy << 8) | readbuf[2];
	pkg_energy = (pkg_energy << 8) | readbuf[1];

	run_time = readbuf[9];
	run_time = (run_time << 8) | readbuf[8];
	run_time = (run_time << 8) | readbuf[7];
	run_time = (run_time << 8) | readbuf[6];

	if (last_pkg_energy == 0 &&
	    last_run_time == 0) { // first read, need second data to calculate
		last_pkg_energy = pkg_energy;
		last_run_time = run_time;
		free(readbuf);
		return false;
	}

	if (pkg_energy >= last_pkg_energy) {
		diff_energy = pkg_energy - last_pkg_energy;
	} else {
		diff_energy = pkg_energy + (0xffffffff - last_pkg_energy + 1);
	}
	last_pkg_energy = pkg_energy;

	if (run_time >= last_run_time) {
		diff_time = run_time - last_run_time;
	} else {
		diff_time = run_time + (0xffffffff - last_run_time + 1);
	}
	last_run_time = run_time;

	if (diff_time == 0) {
		free(readbuf);
		return false;
	} else {
		free(readbuf);
		*reading = ((float)diff_energy / (float)diff_time *
			    0.06103515625); // energy / unit time
		return true;
	}
}