|
|
@@ -555,116 +555,112 @@ static int IRAM_ATTR rmt_get_mem_len(rmt_channel_t channel)
|
|
|
|
|
|
static void IRAM_ATTR rmt_driver_isr_default(void* arg)
|
|
|
{
|
|
|
- uint32_t intr_st = RMT.int_st.val;
|
|
|
- uint32_t i = 0;
|
|
|
+ const uint32_t intr_st = RMT.int_st.val;
|
|
|
+ uint32_t status = intr_st;
|
|
|
uint8_t channel;
|
|
|
portBASE_TYPE HPTaskAwoken = 0;
|
|
|
- for(i = 0; i < 32; i++) {
|
|
|
+ while (status) {
|
|
|
+ int i = __builtin_ffs(status) - 1;
|
|
|
+ status &= ~(1 << i);
|
|
|
if(i < 24) {
|
|
|
- if(intr_st & BIT(i)) {
|
|
|
- channel = i / 3;
|
|
|
- rmt_obj_t* p_rmt = p_rmt_obj[channel];
|
|
|
- if(NULL == p_rmt) {
|
|
|
- RMT.int_clr.val = BIT(i);
|
|
|
- continue;
|
|
|
- }
|
|
|
- switch(i % 3) {
|
|
|
- //TX END
|
|
|
- case 0:
|
|
|
- xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken);
|
|
|
- RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
|
|
|
- RMT.conf_ch[channel].conf1.mem_rd_rst = 0;
|
|
|
- p_rmt->tx_data = NULL;
|
|
|
- p_rmt->tx_len_rem = 0;
|
|
|
- p_rmt->tx_offset = 0;
|
|
|
- p_rmt->tx_sub_len = 0;
|
|
|
- p_rmt->sample_cur = NULL;
|
|
|
- p_rmt->translator = false;
|
|
|
- if(rmt_tx_end_callback.function != NULL) {
|
|
|
- rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg);
|
|
|
- }
|
|
|
- break;
|
|
|
- //RX_END
|
|
|
- case 1:
|
|
|
- RMT.conf_ch[channel].conf1.rx_en = 0;
|
|
|
- int item_len = rmt_get_mem_len(channel);
|
|
|
- //change memory owner to protect data.
|
|
|
- RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
|
|
|
- if(p_rmt->rx_buf) {
|
|
|
- BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void*) RMTMEM.chan[channel].data32, item_len * 4, &HPTaskAwoken);
|
|
|
- if(res == pdFALSE) {
|
|
|
- ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL");
|
|
|
- } else {
|
|
|
-
|
|
|
- }
|
|
|
- } else {
|
|
|
- ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n");
|
|
|
- }
|
|
|
- RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
|
|
|
- RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX;
|
|
|
- RMT.conf_ch[channel].conf1.rx_en = 1;
|
|
|
- break;
|
|
|
- //ERR
|
|
|
- case 2:
|
|
|
- ESP_EARLY_LOGE(RMT_TAG, "RMT[%d] ERR", channel);
|
|
|
- ESP_EARLY_LOGE(RMT_TAG, "status: 0x%08x", RMT.status_ch[channel]);
|
|
|
- RMT.int_ena.val &= (~(BIT(i)));
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- RMT.int_clr.val = BIT(i);
|
|
|
+ channel = i / 3;
|
|
|
+ rmt_obj_t* p_rmt = p_rmt_obj[channel];
|
|
|
+ if(NULL == p_rmt) {
|
|
|
+ continue;
|
|
|
}
|
|
|
- } else {
|
|
|
- if(intr_st & (BIT(i))) {
|
|
|
- channel = i - 24;
|
|
|
- rmt_obj_t* p_rmt = p_rmt_obj[channel];
|
|
|
- RMT.int_clr.val = BIT(i);
|
|
|
-
|
|
|
- if(p_rmt->tx_data == NULL) {
|
|
|
- //skip
|
|
|
- } else {
|
|
|
- if(p_rmt->translator) {
|
|
|
- if(p_rmt->sample_size_remain > 0) {
|
|
|
- size_t translated_size = 0;
|
|
|
- p_rmt->sample_to_rmt((void *) p_rmt->sample_cur,
|
|
|
- p_rmt->tx_buf,
|
|
|
- p_rmt->sample_size_remain,
|
|
|
- p_rmt->tx_sub_len,
|
|
|
- &translated_size,
|
|
|
- &p_rmt->tx_len_rem
|
|
|
- );
|
|
|
- p_rmt->sample_size_remain -= translated_size;
|
|
|
- p_rmt->sample_cur += translated_size;
|
|
|
- p_rmt->tx_data = p_rmt->tx_buf;
|
|
|
+ switch(i % 3) {
|
|
|
+ //TX END
|
|
|
+ case 0:
|
|
|
+ xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken);
|
|
|
+ RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
|
|
|
+ RMT.conf_ch[channel].conf1.mem_rd_rst = 0;
|
|
|
+ p_rmt->tx_data = NULL;
|
|
|
+ p_rmt->tx_len_rem = 0;
|
|
|
+ p_rmt->tx_offset = 0;
|
|
|
+ p_rmt->tx_sub_len = 0;
|
|
|
+ p_rmt->sample_cur = NULL;
|
|
|
+ p_rmt->translator = false;
|
|
|
+ if(rmt_tx_end_callback.function != NULL) {
|
|
|
+ rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ //RX_END
|
|
|
+ case 1:
|
|
|
+ RMT.conf_ch[channel].conf1.rx_en = 0;
|
|
|
+ int item_len = rmt_get_mem_len(channel);
|
|
|
+ //change memory owner to protect data.
|
|
|
+ RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
|
|
|
+ if(p_rmt->rx_buf) {
|
|
|
+ BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void*) RMTMEM.chan[channel].data32, item_len * 4, &HPTaskAwoken);
|
|
|
+ if(res == pdFALSE) {
|
|
|
+ ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL");
|
|
|
} else {
|
|
|
- p_rmt->sample_cur = NULL;
|
|
|
- p_rmt->translator = false;
|
|
|
+
|
|
|
}
|
|
|
- }
|
|
|
- const rmt_item32_t* pdata = p_rmt->tx_data;
|
|
|
- int len_rem = p_rmt->tx_len_rem;
|
|
|
- if(len_rem >= p_rmt->tx_sub_len) {
|
|
|
- rmt_fill_memory(channel, pdata, p_rmt->tx_sub_len, p_rmt->tx_offset);
|
|
|
- p_rmt->tx_data += p_rmt->tx_sub_len;
|
|
|
- p_rmt->tx_len_rem -= p_rmt->tx_sub_len;
|
|
|
- } else if(len_rem == 0) {
|
|
|
- RMTMEM.chan[channel].data32[p_rmt->tx_offset].val = 0;
|
|
|
} else {
|
|
|
- rmt_fill_memory(channel, pdata, len_rem, p_rmt->tx_offset);
|
|
|
- RMTMEM.chan[channel].data32[p_rmt->tx_offset + len_rem].val = 0;
|
|
|
- p_rmt->tx_data += len_rem;
|
|
|
- p_rmt->tx_len_rem -= len_rem;
|
|
|
+ ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR\n");
|
|
|
}
|
|
|
- if(p_rmt->tx_offset == 0) {
|
|
|
- p_rmt->tx_offset = p_rmt->tx_sub_len;
|
|
|
+ RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
|
|
|
+ RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX;
|
|
|
+ RMT.conf_ch[channel].conf1.rx_en = 1;
|
|
|
+ break;
|
|
|
+ //ERR
|
|
|
+ case 2:
|
|
|
+ ESP_EARLY_LOGE(RMT_TAG, "RMT[%d] ERR", channel);
|
|
|
+ ESP_EARLY_LOGE(RMT_TAG, "status: 0x%08x", RMT.status_ch[channel]);
|
|
|
+ RMT.int_ena.val &= (~(BIT(i)));
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ channel = i - 24;
|
|
|
+ rmt_obj_t* p_rmt = p_rmt_obj[channel];
|
|
|
+
|
|
|
+ if(p_rmt->tx_data == NULL) {
|
|
|
+ //skip
|
|
|
+ } else {
|
|
|
+ if(p_rmt->translator) {
|
|
|
+ if(p_rmt->sample_size_remain > 0) {
|
|
|
+ size_t translated_size = 0;
|
|
|
+ p_rmt->sample_to_rmt((void *) p_rmt->sample_cur,
|
|
|
+ p_rmt->tx_buf,
|
|
|
+ p_rmt->sample_size_remain,
|
|
|
+ p_rmt->tx_sub_len,
|
|
|
+ &translated_size,
|
|
|
+ &p_rmt->tx_len_rem
|
|
|
+ );
|
|
|
+ p_rmt->sample_size_remain -= translated_size;
|
|
|
+ p_rmt->sample_cur += translated_size;
|
|
|
+ p_rmt->tx_data = p_rmt->tx_buf;
|
|
|
} else {
|
|
|
- p_rmt->tx_offset = 0;
|
|
|
+ p_rmt->sample_cur = NULL;
|
|
|
+ p_rmt->translator = false;
|
|
|
}
|
|
|
}
|
|
|
+ const rmt_item32_t* pdata = p_rmt->tx_data;
|
|
|
+ int len_rem = p_rmt->tx_len_rem;
|
|
|
+ if(len_rem >= p_rmt->tx_sub_len) {
|
|
|
+ rmt_fill_memory(channel, pdata, p_rmt->tx_sub_len, p_rmt->tx_offset);
|
|
|
+ p_rmt->tx_data += p_rmt->tx_sub_len;
|
|
|
+ p_rmt->tx_len_rem -= p_rmt->tx_sub_len;
|
|
|
+ } else if(len_rem == 0) {
|
|
|
+ RMTMEM.chan[channel].data32[p_rmt->tx_offset].val = 0;
|
|
|
+ } else {
|
|
|
+ rmt_fill_memory(channel, pdata, len_rem, p_rmt->tx_offset);
|
|
|
+ RMTMEM.chan[channel].data32[p_rmt->tx_offset + len_rem].val = 0;
|
|
|
+ p_rmt->tx_data += len_rem;
|
|
|
+ p_rmt->tx_len_rem -= len_rem;
|
|
|
+ }
|
|
|
+ if(p_rmt->tx_offset == 0) {
|
|
|
+ p_rmt->tx_offset = p_rmt->tx_sub_len;
|
|
|
+ } else {
|
|
|
+ p_rmt->tx_offset = 0;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ RMT.int_clr.val = intr_st;
|
|
|
if(HPTaskAwoken == pdTRUE) {
|
|
|
portYIELD_FROM_ISR();
|
|
|
}
|
|
|
@@ -959,4 +955,4 @@ esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status)
|
|
|
}
|
|
|
}
|
|
|
return ESP_OK;
|
|
|
-}
|
|
|
+}
|