Commit b6492661 authored by Adam Wujek's avatar Adam Wujek

main/i2c: use var block mode for TEMP_CURVE_POINTS and TEMP_MATRIX_ROW

Changes cover:
- fix broken handling of setting row/points (size of temp_matrix_row was too
  small, fan_n in set_tc_curve was read from a wrong type (uint16 not uint8))
- use structures for handling row/points
- add get functionality for row/points (before it was possible to read only
  the transfered data not the actual used)
- iterate over fan entries when getting row/points
- update pytests
  -- update query flags for TEMP_CURVE_POINTS and TEMP_MATRIX_ROW registers
  -- improve write testing of TEMP_CURVE_POINTS and TEMP_MATRIX_ROW
     registers
- update documentation
Signed-off-by: 's avatarAdam Wujek <dev_public@wujek.eu>
parent 5fd1cff2
......@@ -182,9 +182,9 @@ Commands marked with \+ or \* are:
+----------+---------------------+------------------------+----------+-------------------------------------------------------------------------+
| D9 + | USE_PEC_ | Byte write / read | 1 | turn PEC on / off |
+----------+---------------------+------------------------+----------+-------------------------------------------------------------------------+
| E0 + | TEMP_CURVE_POINTS_ | MultiByte write / read | 13 | set / get temp. curve points |
| E0 + | TEMP_CURVE_POINTS_ | Block write / read | var(1+13)| set / get temp. curve points |
+----------+---------------------+------------------------+----------+-------------------------------------------------------------------------+
| E1 + | TEMP_MATRIX_ROW_ | MultiByte write / read | 7 | set / get temp. matrix points |
| E1 + | TEMP_MATRIX_ROW_ | Block write / read | var(1+7) | set / get temp. matrix points |
+----------+---------------------+------------------------+----------+-------------------------------------------------------------------------+
| E2 + | TC_ONOFF_ | Byte write / read | 1 | turn temp. control on / off |
+----------+---------------------+------------------------+----------+-------------------------------------------------------------------------+
......@@ -676,7 +676,7 @@ TEMP_CURVE_POINTS
| Command code: **E0**
| Transaction type: **Block write / read**
| Data length: **13**
| Data length: **var(1+13)**
As described in the :ref:`temp_control_sec` section, the temperature
curve can be set separately for each fan. To do this, the format in
......@@ -690,6 +690,17 @@ curve can be set separately for each fan. To do this, the format in
Temperature curve data frame
The first byte specifies the fan number (0-2), following bytes
contains data specific for temperature curve.
The first read after the write to this register allows to get just stored data
for the particular fan.
The following reads of this register iterates over all fans and allow to get
their data.
The fist byte of the register contains the number of bytes of data.
For this register, its value is fixed to 13.
.. _TEMP_MATRIX_ROW:
TEMP_MATRIX_ROW
......@@ -697,7 +708,7 @@ TEMP_MATRIX_ROW
| Command code: **E1**
| Transaction type: **Block write / read**
| Data length: **7**
| Data length: **var(1+7)**
As described in the :ref:`temp_control_sec` section, the temperature
matrix can be set separately for each fan. The data format for the
......@@ -711,6 +722,17 @@ operation is illustrated in :numref:`temp_matrix_fmt`.
Temperature matrix data frame
The first byte specifies the fan number (0-2), following bytes
contains data specific for temperature control.
The first read after the write to this register allows to get just stored data
for the particular fan.
The following reads of this register iterates over all fans and allow to get
their data.
The fist byte of the register contains the number of bytes of data.
For this register, its value is fixed to 7.
.. _TC_ONOFF:
TC_ONOFF
......
......@@ -8,6 +8,7 @@
#include <usb_debug.h>
#define STATUS_BYTE_CML_SHIFT 1
#define FAN_N 3
const char MFR_ID[] = "CERN (BE/CEM)";
const char MFR_MDL[] = "DI/OT MoniMod";
......@@ -81,20 +82,40 @@ static uint8_t reset_byte;
static uint8_t fw_type;
static uint8_t capablity;
static uint8_t tc_curve_curr_fan;
static uint8_t tc_matrix_curr_fan;
struct __attribute__((__packed__)) temp_curve_point {
uint16_t t;
uint16_t s;
};
struct __attribute__((__packed__)) {
uint8_t fan_n;
struct temp_curve_point points[3];
} temp_curve_points_data;
struct __attribute__((__packed__)) {
uint8_t fan_n;
uint16_t m[3];
} temp_matrix_row;
void get_capablity(void);
void get_frpms(void);
void set_frpms();
uint16_t setfrpms_lin[3];
extern uint16_t setfrpms[3] __xMR;
void get_tc_curve();
void set_tc_curve();
uint16_t temp_curve_points_data[7];
extern float temp_curve_points_x[3][3] __xMR;
extern float temp_curve_points_y[3][3] __xMR;
void get_tc_matrix();
void set_tc_matrix();
void set_tc_onoff();
uint16_t temp_matrix_row[3]; // these rows mix the 3 temps separately for each fan
uint8_t tc_on;
extern float temp_matrix[3][3] __xMR;
extern uint16_t temp_control_on __xMR;
......@@ -185,8 +206,8 @@ static const int8_t cmd_data_lengths[] = {
[cmd_0xD7] = 4,
[cmd_0xD8] = 4,
[cmd_0xD9] = 1,
[cmd_0xE0] = 13,
[cmd_0xE1] = 7,
[cmd_0xE0] = -((int8_t)sizeof(temp_curve_points_data)), /* no null char, no -1 */
[cmd_0xE1] = -((int8_t)sizeof(temp_matrix_row)), /* no null char, no -1 */
[cmd_0xE2] = 1
};
......@@ -194,6 +215,7 @@ static const int8_t cmd_data_lengths[] = {
static int8_t cmd_data_length_query = -1;
static const cmd_t cmds_cmds[] = (cmd_t[]){
/* addr, int8_t *const data_len, uint8_t *const data_pnt, access callback, write callback, read callback, query byte PEC */
{0x00, (int8_t *)&cmd_data_lengths[cmd_0x00], (uint8_t *)&page_tmp, (fp_t)NULL, &page_chk, (fp_t)NULL, QUERY_WR | QUERY_RD | QUERY_FMT_8B, 0},
{0x19, (int8_t *)&cmd_data_lengths[cmd_0x19], (uint8_t *)&capablity, &get_capablity, (fp_t)NULL, (fp_t)NULL, QUERY_RD, 0},
{0x1A, (int8_t *)&cmd_data_length_query, (uint8_t *)&query_r, (fp_t)NULL, &query_prp, (fp_t)NULL, QUERY_WR, 1},
......@@ -226,8 +248,8 @@ static const cmd_t cmds_cmds[] = (cmd_t[]){
{0xD7, (int8_t *)&cmd_data_lengths[cmd_0xD7], (uint8_t *)&seconds_up, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD, 0},
{0xD8, (int8_t *)&cmd_data_lengths[cmd_0xD8], (uint8_t *)&TMR_ERROR_CNT, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xD9, (int8_t *)&cmd_data_lengths[cmd_0xD9], (uint8_t *)&use_pec_tmp, &get_pec, &set_pec, (fp_t)NULL, QUERY_WR | QUERY_RD, 1},
{0xE0, (int8_t *)&cmd_data_lengths[cmd_0xE0], (uint8_t *)&temp_curve_points_data, (fp_t)NULL, &set_tc_curve, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xE1, (int8_t *)&cmd_data_lengths[cmd_0xE1], (uint8_t *)&temp_matrix_row, (fp_t)NULL, &set_tc_matrix, (fp_t)NULL, QUERY_WR | QUERY_RD, 0},
{0xE0, (int8_t *)&cmd_data_lengths[cmd_0xE0], (uint8_t *)&temp_curve_points_data, &get_tc_curve, &set_tc_curve, (fp_t)NULL, QUERY_WR | QUERY_RD | QUERY_FMT_NAN,0},
{0xE1, (int8_t *)&cmd_data_lengths[cmd_0xE1], (uint8_t *)&temp_matrix_row, &get_tc_matrix, &set_tc_matrix, (fp_t)NULL, QUERY_WR | QUERY_RD | QUERY_FMT_NAN,0},
{0xE2, (int8_t *)&cmd_data_lengths[cmd_0xE2], (uint8_t *)&tc_on, (fp_t)NULL, &set_tc_onoff, (fp_t)NULL, QUERY_WR | QUERY_RD, 0}
};
......@@ -430,23 +452,64 @@ void __xMR set_frpms()
flash_write_row((uint32_t *)&user_flash, (uint32_t *)fw_write_buf);
}
void __xMR get_tc_curve()
{
uint8_t fan_n = tc_curve_curr_fan;
for (uint8_t i = 0; i < FAN_N; ++i) {
temp_curve_points_data.points[i].t = float_to_linear(temp_curve_points_x[fan_n][i]);
temp_curve_points_data.points[i].s = float_to_linear(temp_curve_points_y[fan_n][i]);
}
temp_curve_points_data.fan_n = fan_n;
/* Increase fan counter, at the next read return data for the next fan */
tc_curve_curr_fan = (tc_curve_curr_fan + 1) % FAN_N;
}
void __xMR set_tc_curve()
{
uint8_t fan_n = temp_curve_points_data[0];
for (uint8_t i = 0; i < 3; ++i) {
temp_curve_points_x[fan_n][i] = linear_to_float(temp_curve_points_data[1 + 2*i]);
temp_curve_points_y[fan_n][i] = linear_to_float(temp_curve_points_data[1 + 2*i + 1]);
uint8_t fan_n = temp_curve_points_data.fan_n;
if (fan_n >= FAN_N) {
/* Fan number out of range */
return;
}
for (uint8_t i = 0; i < FAN_N; ++i) {
temp_curve_points_x[fan_n][i] = linear_to_float(temp_curve_points_data.points[i].t);
temp_curve_points_y[fan_n][i] = linear_to_float(temp_curve_points_data.points[i].s);
}
tc_curve_curr_fan = fan_n;
}
void __xMR get_tc_matrix()
{
uint8_t fan_n = tc_matrix_curr_fan;
for (uint8_t i = 0; i < FAN_N; ++i) {
temp_matrix_row.m[i] = float_to_linear(temp_matrix[fan_n][i]);
}
temp_matrix_row.fan_n = fan_n;
/* Increase fan counter, at the next read return data for the next fan */
tc_matrix_curr_fan = (tc_matrix_curr_fan + 1) % FAN_N;
}
void __xMR set_tc_matrix()
{
uint8_t fan_n = temp_matrix_row[0];
for (uint8_t i = 0; i < 3; ++i) {
temp_matrix[fan_n][i] = linear_to_float(temp_matrix_row[1 + i]);
uint8_t fan_n = temp_matrix_row.fan_n;
if (fan_n >= FAN_N) {
/* Fan number out of range */
return;
}
for (uint8_t i = 0; i < FAN_N; ++i) {
temp_matrix[fan_n][i] = linear_to_float(temp_matrix_row.m[i]);
}
tc_matrix_curr_fan = fan_n;
}
......@@ -473,10 +536,18 @@ void set_frpms()
{
}
void get_tc_curve()
{
}
void set_tc_curve()
{
}
void get_tc_matrix()
{
}
void set_tc_matrix()
{
}
......
......@@ -59,8 +59,8 @@ cmd_query = {
"UPTIME_SECS" : QUERY_SUP | QUERY_RD,
"TMR_ERROR_CNT" : QUERY_SUP | QUERY_WR | QUERY_RD,
"USE_PEC" : QUERY_SUP | QUERY_WR | QUERY_RD,
"TEMP_CURVE_POINTS" : QUERY_SUP | QUERY_WR | QUERY_RD,
"TEMP_MATRIX_ROW" : QUERY_SUP | QUERY_WR | QUERY_RD,
"TEMP_CURVE_POINTS" : QUERY_SUP | QUERY_WR | QUERY_RD | QUERY_FMT_NAN,
"TEMP_MATRIX_ROW" : QUERY_SUP | QUERY_WR | QUERY_RD | QUERY_FMT_NAN,
"TC_ONOFF" : QUERY_SUP | QUERY_WR | QUERY_RD,
}
......@@ -245,20 +245,24 @@ class TestFwMainRegValues(object):
TMR_val = monimod_bus.get_tmr()
assert TMR_val == 0
@pytest.mark.parametrize("cmds, data_len", [# cmd, size
("TEMP_CURVE_POINTS", 13),
("TEMP_MATRIX_ROW", 7)]
@pytest.mark.parametrize("cmds, test_data", [# cmd, size
("TEMP_CURVE_POINTS", [0x02, 0x80, 0xda, 0x20, 0xeb, 0x20, 0xdb, 0x20, 0xf3, 0xc0, 0xdb, 0xe8, 0x03]),
("TEMP_CURVE_POINTS", [0x02, 0x11, 0x22, 0x33, 0x44, 0xaa, 0x5c, 0xee, 0x80, 0x99, 0xaa, 0xbb, 0xcc]),
("TEMP_MATRIX_ROW", [0x00, 0x02, 0xfa, 0x04, 0x05, 0x0c, 0x92]),
("TEMP_MATRIX_ROW", [0x00, 0x05, 0x33, 0x44, 0x05, 0x12, 0x92])
]
)
def test_write_multibyte(self, monimod_bus, cmds, data_len):
data_old = monimod_bus.read_i2c_block_data(monimod_bus.cmd_ids[cmds], data_len)
data_new = [x + 1 for x in data_old]
assert data_old != data_new
monimod_bus.write_i2c_block_data(monimod_bus.cmd_ids[cmds], data_new)
data_new_read = monimod_bus.read_i2c_block_data(monimod_bus.cmd_ids[cmds], data_len)
def test_write_multibyte(self, monimod_bus, cmds, test_data):
data_old = monimod_bus.pmbus_read_block_cmd(monimod_bus.cmd_ids[cmds])
# Use the same fan ID
data_new = [data_old[0]] + test_data[1:]
monimod_bus.pmbus_write_block_cmd(monimod_bus.cmd_ids[cmds], data_new)
data_new_read = monimod_bus.pmbus_read_block_cmd(monimod_bus.cmd_ids[cmds])
# restore and verify the old value
monimod_bus.write_i2c_block_data(monimod_bus.cmd_ids[cmds], data_old)
data_old_read = monimod_bus.read_i2c_block_data(monimod_bus.cmd_ids[cmds], data_len)
monimod_bus.pmbus_write_block_cmd(monimod_bus.cmd_ids[cmds], data_old)
data_old_read = monimod_bus.pmbus_read_block_cmd(monimod_bus.cmd_ids[cmds])
assert data_new_read == data_new
assert data_new_read != data_old
assert data_old_read == data_old
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment