kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'bugfix/several_i2C_issues' into 'release/v4.4'
I2C: Fix I2C task wait too long on an event (backport 4.4) See merge request espressif/esp-idf!18768pull/9730/head
commit
b65ec8c7c9
|
@ -207,7 +207,7 @@ static i2c_clk_alloc_t i2c_clk_alloc[I2C_SCLK_MAX] = {
|
||||||
|
|
||||||
static i2c_obj_t *p_i2c_obj[I2C_NUM_MAX] = {0};
|
static i2c_obj_t *p_i2c_obj[I2C_NUM_MAX] = {0};
|
||||||
static void i2c_isr_handler_default(void *arg);
|
static void i2c_isr_handler_default(void *arg);
|
||||||
static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num);
|
static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num, portBASE_TYPE* HPTaskAwoken);
|
||||||
static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num);
|
static esp_err_t i2c_hw_fsm_reset(i2c_port_t i2c_num);
|
||||||
|
|
||||||
static void i2c_hw_disable(i2c_port_t i2c_num)
|
static void i2c_hw_disable(i2c_port_t i2c_num)
|
||||||
|
@ -486,6 +486,7 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg)
|
||||||
}
|
}
|
||||||
i2c_intr_event_t evt_type = I2C_INTR_EVENT_ERR;
|
i2c_intr_event_t evt_type = I2C_INTR_EVENT_ERR;
|
||||||
portBASE_TYPE HPTaskAwoken = pdFALSE;
|
portBASE_TYPE HPTaskAwoken = pdFALSE;
|
||||||
|
portBASE_TYPE HPTaskAwokenCallee = pdFALSE;
|
||||||
if (p_i2c->mode == I2C_MODE_MASTER) {
|
if (p_i2c->mode == I2C_MODE_MASTER) {
|
||||||
if (p_i2c->status == I2C_STATUS_WRITE) {
|
if (p_i2c->status == I2C_STATUS_WRITE) {
|
||||||
i2c_hal_master_handle_tx_event(&(i2c_context[i2c_num].hal), &evt_type);
|
i2c_hal_master_handle_tx_event(&(i2c_context[i2c_num].hal), &evt_type);
|
||||||
|
@ -494,18 +495,18 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg)
|
||||||
}
|
}
|
||||||
if (evt_type == I2C_INTR_EVENT_NACK) {
|
if (evt_type == I2C_INTR_EVENT_NACK) {
|
||||||
p_i2c_obj[i2c_num]->status = I2C_STATUS_ACK_ERROR;
|
p_i2c_obj[i2c_num]->status = I2C_STATUS_ACK_ERROR;
|
||||||
i2c_master_cmd_begin_static(i2c_num);
|
i2c_master_cmd_begin_static(i2c_num, &HPTaskAwokenCallee);
|
||||||
} else if (evt_type == I2C_INTR_EVENT_TOUT) {
|
} else if (evt_type == I2C_INTR_EVENT_TOUT) {
|
||||||
p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
|
p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
|
||||||
i2c_master_cmd_begin_static(i2c_num);
|
i2c_master_cmd_begin_static(i2c_num, &HPTaskAwokenCallee);
|
||||||
} else if (evt_type == I2C_INTR_EVENT_ARBIT_LOST) {
|
} else if (evt_type == I2C_INTR_EVENT_ARBIT_LOST) {
|
||||||
p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
|
p_i2c_obj[i2c_num]->status = I2C_STATUS_TIMEOUT;
|
||||||
i2c_master_cmd_begin_static(i2c_num);
|
i2c_master_cmd_begin_static(i2c_num, &HPTaskAwokenCallee);
|
||||||
} else if (evt_type == I2C_INTR_EVENT_END_DET) {
|
} else if (evt_type == I2C_INTR_EVENT_END_DET) {
|
||||||
i2c_master_cmd_begin_static(i2c_num);
|
i2c_master_cmd_begin_static(i2c_num, &HPTaskAwokenCallee);
|
||||||
} else if (evt_type == I2C_INTR_EVENT_TRANS_DONE) {
|
} else if (evt_type == I2C_INTR_EVENT_TRANS_DONE) {
|
||||||
if (p_i2c->status != I2C_STATUS_ACK_ERROR && p_i2c->status != I2C_STATUS_IDLE) {
|
if (p_i2c->status != I2C_STATUS_ACK_ERROR && p_i2c->status != I2C_STATUS_IDLE) {
|
||||||
i2c_master_cmd_begin_static(i2c_num);
|
i2c_master_cmd_begin_static(i2c_num, &HPTaskAwokenCallee);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Do nothing if there is no proper event.
|
// Do nothing if there is no proper event.
|
||||||
|
@ -538,7 +539,7 @@ static void IRAM_ATTR i2c_isr_handler_default(void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//We only need to check here if there is a high-priority task needs to be switched.
|
//We only need to check here if there is a high-priority task needs to be switched.
|
||||||
if (HPTaskAwoken == pdTRUE) {
|
if (HPTaskAwoken == pdTRUE || HPTaskAwokenCallee == pdTRUE) {
|
||||||
portYIELD_FROM_ISR();
|
portYIELD_FROM_ISR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1283,10 +1284,9 @@ static inline bool i2c_cmd_is_single_byte(const i2c_cmd_t *cmd) {
|
||||||
return cmd->total_bytes == 1;
|
return cmd->total_bytes == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)
|
static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num, portBASE_TYPE* HPTaskAwoken)
|
||||||
{
|
{
|
||||||
i2c_obj_t *p_i2c = p_i2c_obj[i2c_num];
|
i2c_obj_t *p_i2c = p_i2c_obj[i2c_num];
|
||||||
portBASE_TYPE HPTaskAwoken = pdFALSE;
|
|
||||||
i2c_cmd_evt_t evt = { 0 };
|
i2c_cmd_evt_t evt = { 0 };
|
||||||
if (p_i2c->cmd_link.head != NULL && p_i2c->status == I2C_STATUS_READ) {
|
if (p_i2c->cmd_link.head != NULL && p_i2c->status == I2C_STATUS_READ) {
|
||||||
i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
|
i2c_cmd_t *cmd = &p_i2c->cmd_link.head->cmd;
|
||||||
|
@ -1305,17 +1305,19 @@ static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)
|
||||||
}
|
}
|
||||||
} else if ((p_i2c->status == I2C_STATUS_ACK_ERROR)
|
} else if ((p_i2c->status == I2C_STATUS_ACK_ERROR)
|
||||||
|| (p_i2c->status == I2C_STATUS_TIMEOUT)) {
|
|| (p_i2c->status == I2C_STATUS_TIMEOUT)) {
|
||||||
|
assert(HPTaskAwoken != NULL);
|
||||||
evt.type = I2C_CMD_EVT_DONE;
|
evt.type = I2C_CMD_EVT_DONE;
|
||||||
xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken);
|
xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, HPTaskAwoken);
|
||||||
return;
|
return;
|
||||||
} else if (p_i2c->status == I2C_STATUS_DONE) {
|
} else if (p_i2c->status == I2C_STATUS_DONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_i2c->cmd_link.head == NULL) {
|
if (p_i2c->cmd_link.head == NULL) {
|
||||||
|
assert(HPTaskAwoken != NULL);
|
||||||
p_i2c->cmd_link.cur = NULL;
|
p_i2c->cmd_link.cur = NULL;
|
||||||
evt.type = I2C_CMD_EVT_DONE;
|
evt.type = I2C_CMD_EVT_DONE;
|
||||||
xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, &HPTaskAwoken);
|
xQueueOverwriteFromISR(p_i2c->cmd_evt_queue, &evt, HPTaskAwoken);
|
||||||
// Return to the IDLE status after cmd_eve_done signal were send out.
|
// Return to the IDLE status after cmd_eve_done signal were send out.
|
||||||
p_i2c->status = I2C_STATUS_IDLE;
|
p_i2c->status = I2C_STATUS_IDLE;
|
||||||
return;
|
return;
|
||||||
|
@ -1461,7 +1463,7 @@ esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num, i2c_cmd_handle_t cmd_handle,
|
||||||
i2c_hal_disable_intr_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK);
|
i2c_hal_disable_intr_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK);
|
||||||
i2c_hal_clr_intsts_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK);
|
i2c_hal_clr_intsts_mask(&(i2c_context[i2c_num].hal), I2C_LL_INTR_MASK);
|
||||||
//start send commands, at most 32 bytes one time, isr handler will process the remaining commands.
|
//start send commands, at most 32 bytes one time, isr handler will process the remaining commands.
|
||||||
i2c_master_cmd_begin_static(i2c_num);
|
i2c_master_cmd_begin_static(i2c_num, NULL);
|
||||||
|
|
||||||
// Wait event bits
|
// Wait event bits
|
||||||
i2c_cmd_evt_t evt;
|
i2c_cmd_evt_t evt;
|
||||||
|
|
Ładowanie…
Reference in New Issue