spi: fix a possible concurrency issue

This commit is contained in:
Michael (XIAO Xufeng) 2019-05-31 15:23:10 +08:00
parent 0dcbe15614
commit e238cf85a2
2 changed files with 12 additions and 6 deletions

View File

@ -419,6 +419,9 @@ static void IRAM_ATTR spi_intr(void *arg)
/*------------ new transaction starts here ------------------*/ /*------------ new transaction starts here ------------------*/
//ToDo: This is a stupidly simple low-cs-first priority scheme. Make this configurable somehow. - JD //ToDo: This is a stupidly simple low-cs-first priority scheme. Make this configurable somehow. - JD
//Disable interrupt before checking to avoid concurrency issue.
esp_intr_disable(host->intr);
for (i=0; i<NO_CS; i++) { for (i=0; i<NO_CS; i++) {
if (host->device[i]) { if (host->device[i]) {
r=xQueueReceiveFromISR(host->device[i]->trans_queue, &host->cur_trans_buf, &do_yield); r=xQueueReceiveFromISR(host->device[i]->trans_queue, &host->cur_trans_buf, &do_yield);
@ -428,13 +431,14 @@ static void IRAM_ATTR spi_intr(void *arg)
} }
} }
if (i==NO_CS) { if (i==NO_CS) {
//No packet waiting. Disable interrupt.
esp_intr_disable(host->intr);
#ifdef CONFIG_PM_ENABLE #ifdef CONFIG_PM_ENABLE
//Release APB frequency lock //Release APB frequency lock
esp_pm_lock_release(host->pm_lock); esp_pm_lock_release(host->pm_lock);
#endif #endif
} else { } else {
//enable the interrupt again if there is packet to send
esp_intr_enable(host->intr);
host->hw->slave.trans_done=0; //clear int bit host->hw->slave.trans_done=0; //clear int bit
//We have a transaction. Send it. //We have a transaction. Send it.
spi_device_t *dev=host->device[i]; spi_device_t *dev=host->device[i];

View File

@ -375,12 +375,14 @@ static void IRAM_ATTR spi_intr(void *arg)
} }
} }
//Disable interrupt before checking to avoid concurrency issue.
esp_intr_disable(host->intr);
//Grab next transaction //Grab next transaction
r = xQueueReceiveFromISR(host->trans_queue, &trans, &do_yield); r = xQueueReceiveFromISR(host->trans_queue, &trans, &do_yield);
if (!r) { if (r) {
//No packet waiting. Disable interrupt. //enable the interrupt again if there is packet to send
esp_intr_disable(host->intr); esp_intr_enable(host->intr);
} else {
//We have a transaction. Send it. //We have a transaction. Send it.
host->hw->slave.trans_done = 0; //clear int bit host->hw->slave.trans_done = 0; //clear int bit
host->cur_trans = trans; host->cur_trans = trans;