Skip to content
Snippets Groups Projects
Commit dfd58318 authored by Christos Gentsos's avatar Christos Gentsos
Browse files

I2C: Clear error bit on bus error, add STATUS_BYTE and STATUS_CML

When a bus error happened, the I2C peripheral's error bit remained
set. This caused it to respond erroneously in future transactions.

Now, when a bus error occurs, we're clearing the error bit and setting
the error flags in the STATUS_BYTE and STATUS_CML PMBus registers.
After the user reads those registers (using commands 0x78 and 0x7E),
their error flags are cleared.
parent a9cb79cb
Branches
No related merge requests found
......@@ -12,6 +12,8 @@ extern cmd_space_t cmds;
//! Our custom commmands structure
extern cmd_space_t ext_cmds;
uint8_t status_b;
int main(void)
{
system_init();
......
......@@ -36,6 +36,9 @@ static uint16_t added_tx_pec __xMR = 0;
static uint16_t sent_checksum __xMR = 0;
static uint8_t tx_tmp;
extern uint8_t status_b;
uint8_t status_cml;
int16_t in_addr_space(cmd_space_t *addr_space, uint8_t addr)
{
for (uint8_t i = 0; i < addr_space->n_cmds; ++i)
......@@ -179,8 +182,11 @@ static void __xMR I2C_rx_complete(const struct i2c_s_async_descriptor *const des
send_ack(descr);
if (cmds->cmds[cmd_index].w_callback)
cmds->cmds[cmd_index].w_callback();
} else
} else {
status_b |= 0x01;
status_cml = 0x20; // PEC error
send_nack(descr);
}
set_cmd(descr, 2);
rx_state = CMD;
break;
......@@ -190,8 +196,11 @@ static void __xMR I2C_rx_complete(const struct i2c_s_async_descriptor *const des
send_ack(descr);
if (ext_cmds->cmds[cmd_index].w_callback)
ext_cmds->cmds[cmd_index].w_callback();
} else
} else {
status_b |= 0x01;
status_cml = 0x20; // PEC error
send_nack(descr);
}
set_cmd(descr, 2);
rx_state = CMD;
break;
......@@ -280,6 +289,9 @@ static void __xMR I2C_tx_complete(const struct i2c_s_async_descriptor *const des
/*! we get here when something bad has happened */
static void __xMR I2C_error(const struct i2c_s_async_descriptor *const descr)
{
status_b |= 0x01;
status_cml = 0x02; // Other comm fault
hri_sercomi2cs_clear_INTFLAG_ERROR_bit(descr->device.hw);
set_cmd(descr, 2);
}
......
......@@ -32,6 +32,11 @@ extern uint16_t use_pec __xMR;
uint8_t use_pec_tmp;
void set_pec();
void read_status_b();
void read_status_cml();
extern uint8_t status_b;
extern uint8_t status_cml;
void accvolt();
void acccurr();
void accpowr();
......@@ -85,6 +90,8 @@ extern uint16_t fan_ppr[3] __xMR;
static const int8_t cmd_data_lengths[] = {
1, // 0x00
-1, // 0x1A
1, // 0x78
1, // 0x7E
2, // 0x8B
2, // 0x8C
2, // 0x8D
......@@ -112,26 +119,28 @@ static int8_t cmd_data_length_query = -1;
static cmd_t cmds_cmds[] = (cmd_t[]){
{0x00, (int8_t *)&cmd_data_lengths[0], (uint8_t *)&page_tmp, (fp_t)NULL, &page_chk, (fp_t)NULL, QUERY_WR | QUERY_RD | QUERY_FMT_8B, 0},
{0x1A, (int8_t *)&cmd_data_length_query, (uint8_t *)&query_r, (fp_t)NULL, &query_prp, (fp_t)NULL, QUERY_SUP, 1},
{0x8B, (int8_t *)&cmd_data_lengths[2], (uint8_t *)&curpage_volt, &accvolt, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8C, (int8_t *)&cmd_data_lengths[3], (uint8_t *)&curpage_curr, &acccurr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8D, (int8_t *)&cmd_data_lengths[4], (uint8_t *)&temps_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8E, (int8_t *)&cmd_data_lengths[5], (uint8_t *)&temps_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8F, (int8_t *)&cmd_data_lengths[6], (uint8_t *)&temps_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x90, (int8_t *)&cmd_data_lengths[7], (uint8_t *)&frpms_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x91, (int8_t *)&cmd_data_lengths[8], (uint8_t *)&frpms_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x92, (int8_t *)&cmd_data_lengths[9], (uint8_t *)&frpms_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x96, (int8_t *)&cmd_data_lengths[10], (uint8_t *)&curpage_powr, &accpowr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x99, (int8_t *)&cmd_data_lengths[11], (uint8_t *)&MFR_ID, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9A, (int8_t *)&cmd_data_lengths[12], (uint8_t *)&MFR_MDL, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9B, (int8_t *)&cmd_data_lengths[13], (uint8_t *)&MFR_REV, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9C, (int8_t *)&cmd_data_lengths[14], (uint8_t *)&MFR_LOC, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9D, (int8_t *)&cmd_data_lengths[15], (uint8_t *)&MFR_DAT, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9E, (int8_t *)&cmd_data_lengths[16], (uint8_t *)&MFR_SER, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x3A, (int8_t *)&cmd_data_lengths[17], (uint8_t *)&fan_config_1_2, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
{0x3B, (int8_t *)&cmd_data_lengths[18], (uint8_t *)&setfrpms_lin[0], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
{0x3C, (int8_t *)&cmd_data_lengths[19], (uint8_t *)&setfrpms_lin[1], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
{0x3D, (int8_t *)&cmd_data_lengths[20], (uint8_t *)&fan_config_3_4, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
{0x3E, (int8_t *)&cmd_data_lengths[21], (uint8_t *)&setfrpms_lin[2], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0}};
{0x78, (int8_t *)&cmd_data_lengths[2], (uint8_t *)&status_b, (fp_t)NULL, (fp_t)NULL, &read_status_b, QUERY_RD, 0},
{0x7E, (int8_t *)&cmd_data_lengths[3], (uint8_t *)&status_cml, (fp_t)NULL, (fp_t)NULL, &read_status_cml, QUERY_RD, 0},
{0x8B, (int8_t *)&cmd_data_lengths[4], (uint8_t *)&curpage_volt, &accvolt, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8C, (int8_t *)&cmd_data_lengths[5], (uint8_t *)&curpage_curr, &acccurr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8D, (int8_t *)&cmd_data_lengths[6], (uint8_t *)&temps_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8E, (int8_t *)&cmd_data_lengths[7], (uint8_t *)&temps_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x8F, (int8_t *)&cmd_data_lengths[8], (uint8_t *)&temps_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x90, (int8_t *)&cmd_data_lengths[9], (uint8_t *)&frpms_lin[0], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x91, (int8_t *)&cmd_data_lengths[10], (uint8_t *)&frpms_lin[1], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x92, (int8_t *)&cmd_data_lengths[11], (uint8_t *)&frpms_lin[2], (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x96, (int8_t *)&cmd_data_lengths[12], (uint8_t *)&curpage_powr, &accpowr, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_LIN, 0},
{0x99, (int8_t *)&cmd_data_lengths[13], (uint8_t *)&MFR_ID, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9A, (int8_t *)&cmd_data_lengths[14], (uint8_t *)&MFR_MDL, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9B, (int8_t *)&cmd_data_lengths[15], (uint8_t *)&MFR_REV, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9C, (int8_t *)&cmd_data_lengths[16], (uint8_t *)&MFR_LOC, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9D, (int8_t *)&cmd_data_lengths[17], (uint8_t *)&MFR_DAT, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x9E, (int8_t *)&cmd_data_lengths[18], (uint8_t *)&MFR_SER, (fp_t)NULL, (fp_t)NULL, (fp_t)NULL, QUERY_RD | QUERY_FMT_NAN, 0},
{0x3A, (int8_t *)&cmd_data_lengths[19], (uint8_t *)&fan_config_1_2, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
{0x3B, (int8_t *)&cmd_data_lengths[20], (uint8_t *)&setfrpms_lin[0], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
{0x3C, (int8_t *)&cmd_data_lengths[21], (uint8_t *)&setfrpms_lin[1], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0},
{0x3D, (int8_t *)&cmd_data_lengths[22], (uint8_t *)&fan_config_3_4, (fp_t)NULL, &fan_config, (fp_t)NULL, QUERY_WR | QUERY_FMT_NAN, 0},
{0x3E, (int8_t *)&cmd_data_lengths[23], (uint8_t *)&setfrpms_lin[2], (fp_t)NULL, &set_frpms, (fp_t)NULL, QUERY_WR | QUERY_FMT_LIN, 0}};
cmd_space_t cmds = {
sizeof(cmds_cmds)/sizeof(cmd_t),
......@@ -239,6 +248,16 @@ void __xMR set_pec()
use_pec = use_pec_tmp;
}
void read_status_b()
{
status_b &= 0xFE;
}
void read_status_cml()
{
status_cml = 0;
}
#if defined(MMFANT) || defined(MMPROT)
void __xMR fan_config()
......
......@@ -127,6 +127,8 @@ float temps[3];
float volts[4];
float currs[3];
uint8_t status_b;
uint16_t trig_adc_next_second __xMR = 0;
#if defined(MMFANT) || defined(MMPROT)
......
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