#define UART_EMPTY_THRESH_DEFAULT (10)\r
#define UART_FULL_THRESH_DEFAULT (120)\r
#define UART_TOUT_THRESH_DEFAULT (10)\r
-#define UART_TX_TASK_DEPTH_DEFAULT (256*2+64)\r
-#define UART_TX_TASK_PRIO_DEFAULT (10)\r
#define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux)\r
#define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux)\r
#define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux)\r
RingbufHandle_t rx_ring_buf;\r
int tx_buf_size;\r
RingbufHandle_t tx_ring_buf;\r
- TaskHandle_t tx_task_handle;\r
bool buffer_full_flg;\r
bool tx_waiting;\r
int cur_remain;\r
uart_dev_t* uart_reg = UART[uart_num];\r
uint8_t buf_idx = 0;\r
uint32_t uart_intr_status = UART[uart_num]->int_st.val;\r
- static int rx_fifo_len = 0;\r
+ int rx_fifo_len = 0;\r
uart_event_t uart_event;\r
+\r
+ static uint8_t * tx_ptr;\r
+ static uart_event_t* tx_head;\r
+ static int tx_len_tot = 0;\r
+ static int brk_flg = 0;\r
+ static int tx_brk_len = 0;\r
+ static int wait_brk = 0;\r
+\r
+\r
portBASE_TYPE HPTaskAwoken = 0;\r
while(uart_intr_status != 0x0) {\r
buf_idx = 0;\r
uart_reg->int_ena.txfifo_empty = 0;\r
uart_reg->int_clr.txfifo_empty = 1;\r
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
+ if(wait_brk) {\r
+ return;\r
+ }\r
if(p_uart->tx_waiting == true) {\r
p_uart->tx_waiting = false;\r
xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, NULL);\r
}\r
+ else {\r
+ int tx_fifo_rem = UART_FIFO_LEN - UART[uart_num]->status.txfifo_cnt;\r
+ bool en_tx_flg = false;\r
+ if(tx_len_tot == 0) {\r
+ size_t size;\r
+// ets_printf("dbg1,tot=0,get 1st head\n");\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+ tx_head = (uart_event_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size);\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+ if(tx_head) { //enable empty intr\r
+// tx_ptr = (uint8_t*)tx_head + sizeof(uart_event_t);\r
+ tx_ptr = NULL;\r
+// en_tx_flg = true;\r
+ tx_len_tot = tx_head->data.size;\r
+ if(tx_head->type == UART_DATA_BREAK) {\r
+ tx_len_tot = tx_head->data.size;\r
+ brk_flg = 1;\r
+ tx_brk_len = tx_head->data.brk_len;\r
+ }\r
+// ets_printf("ret1,tot: %d\n", tx_len_tot);\r
+ vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, tx_head, &HPTaskAwoken);\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+ }\r
+ else {\r
+ return;\r
+ }\r
+ }\r
+ if(tx_ptr == NULL) {\r
+ size_t size;\r
+// ets_printf("dbg2, tx ptr null, get 2nd tx ptr\n");\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+ tx_ptr = (uint8_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size);\r
+\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+ if(tx_ptr) {\r
+ tx_head = (void*) tx_ptr;\r
+// ets_printf("get size: %d ; h size: %d\n", size, tx_len_tot);\r
+ en_tx_flg = true;\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+// else\r
+ if(tx_len_tot > 0 && tx_ptr) { //tx\r
+ int send_len = tx_len_tot > tx_fifo_rem ? tx_fifo_rem : tx_len_tot;\r
+ for(buf_idx = 0; buf_idx < send_len; buf_idx++) {\r
+ WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(tx_ptr++) & 0xff);\r
+ }\r
+ tx_len_tot -= send_len;\r
+// ets_printf("tot: %d\n", tx_len_tot);\r
+ if(tx_len_tot == 0) {\r
+ if(brk_flg == 1) {\r
+ UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
+ uart_reg->int_ena.tx_brk_done = 0;\r
+ uart_reg->idle_conf.tx_brk_num = tx_brk_len;\r
+ uart_reg->conf0.txd_brk = 1;\r
+ uart_reg->int_clr.tx_brk_done = 1;\r
+ uart_reg->int_ena.tx_brk_done = 1;\r
+ UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
+ wait_brk = 1;\r
+ } else {\r
+ en_tx_flg = true;\r
+ }\r
+// ets_printf("ret2\n");\r
+ vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, tx_head, &HPTaskAwoken);\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+// xRingbufferPrintInfo(p_uart->tx_ring_buf);\r
+ tx_head = NULL;\r
+ tx_ptr = NULL;\r
+ } else {\r
+ en_tx_flg = true;\r
+ }\r
+ }\r
+ if(en_tx_flg) {\r
+ UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
+ uart_reg->int_clr.txfifo_empty = 1;\r
+ uart_reg->int_ena.txfifo_empty = 1;\r
+ UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
+ }\r
+ }\r
}\r
else if((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)) {\r
if(p_uart->buffer_full_flg == false) {\r
//Get the buffer from the FIFO\r
+// ESP_LOGE(UART_TAG, "FULL\n");\r
rx_fifo_len = uart_reg->status.rxfifo_cnt;\r
p_uart->data_len = rx_fifo_len;\r
memset(p_uart->data_buf, 0, sizeof(p_uart->data_buf));\r
uart_reg->int_clr.frm_err = 1;\r
uart_event.type = UART_PARITY_ERR;\r
} else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) {\r
+// ESP_LOGE(UART_TAG, "UART TX BRK DONE\n");\r
+ ets_printf("tx brk done\n");\r
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
uart_reg->conf0.txd_brk = 0;\r
uart_reg->int_ena.tx_brk_done = 0;\r
uart_reg->int_clr.tx_brk_done = 1;\r
+ if(brk_flg == 1) {\r
+ uart_reg->int_ena.txfifo_empty = 1;\r
+ }\r
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
- xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken);\r
+ if(brk_flg == 1) {\r
+ brk_flg = 0;\r
+ wait_brk = 0;\r
+ } else {\r
+ xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken);\r
+ }\r
} else if(uart_intr_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) {\r
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);\r
uart_reg->int_ena.tx_brk_idle_done = 0;\r
return original_size;\r
}\r
\r
-static void uart_tx_task(void* arg)\r
-{\r
- uart_obj_t* p_uart = (uart_obj_t*) arg;\r
- size_t size;\r
- uart_event_t evt;\r
- for(;;) {\r
- char* data = (char*) xRingbufferReceive(p_uart->tx_ring_buf, &size, portMAX_DELAY);\r
- if(data == NULL) {\r
- continue;\r
- }\r
- memcpy(&evt, data, sizeof(evt));\r
- if(evt.type == UART_DATA) {\r
- uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 0, 0);\r
- } else if(evt.type == UART_DATA_BREAK) {\r
- uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 1, evt.data.brk_len);\r
- }\r
- vRingbufferReturnItem(p_uart->tx_ring_buf, data);\r
- }\r
- vTaskDelete(NULL);\r
-}\r
+//static void uart_tx_task(void* arg)\r
+//{\r
+// uart_obj_t* p_uart = (uart_obj_t*) arg;\r
+// size_t size;\r
+// uart_event_t evt;\r
+// for(;;) {\r
+// char* data = (char*) xRingbufferReceive(p_uart->tx_ring_buf, &size, portMAX_DELAY);\r
+// if(data == NULL) {\r
+// continue;\r
+// }\r
+// memcpy(&evt, data, sizeof(evt));\r
+// if(evt.type == UART_DATA) {\r
+// uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 0, 0);\r
+// } else if(evt.type == UART_DATA_BREAK) {\r
+// uart_tx_all(p_uart->uart_num, (const char*) data + sizeof(uart_event_t), evt.data.size, 1, evt.data.brk_len);\r
+// }\r
+// vRingbufferReturnItem(p_uart->tx_ring_buf, data);\r
+// }\r
+// vTaskDelete(NULL);\r
+//}\r
\r
int uart_tx_all_chars(uart_port_t uart_num, const char* src, size_t size)\r
{\r
UART_CHECK(src, "buffer null");\r
if(p_uart_obj[uart_num]->tx_buf_size > 0) {\r
if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size + sizeof(uart_event_t))) {\r
- uart_event_t *evt = (uart_event_t*) malloc(sizeof(uart_event_t) + size);\r
- if(evt == NULL) {\r
- ESP_LOGE(UART_TAG, "UART EVT MALLOC ERROR\n");\r
- return -1;\r
- }\r
+ uart_event_t evt;\r
xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY);\r
- evt->type = UART_DATA;\r
- evt->data.size = size;\r
- memcpy(evt->data.data, src, size);\r
- xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) evt, sizeof(uart_event_t) + size, portMAX_DELAY);\r
- free(evt);\r
- evt = NULL;\r
+ evt.type = UART_DATA;\r
+ evt.data.size = size;\r
+ ets_printf("-----1st send-----\n");\r
+ xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY);\r
+ xRingbufferPrintInfo(p_uart_obj[uart_num]->tx_ring_buf);\r
+ ets_printf("====2nd send====\n");\r
+ xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY);\r
+ xRingbufferPrintInfo(p_uart_obj[uart_num]->tx_ring_buf);\r
xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex);\r
+ uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT);\r
return size;\r
} else {\r
ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[0], SEND DIRECTLY\n");\r
UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error");\r
if(p_uart_obj[uart_num]->tx_buf_size > 0) {\r
if(xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf) > (size)) {\r
- uart_event_t *evt = (uart_event_t*) malloc(sizeof(uart_event_t) + size);\r
- if(evt == NULL) {\r
- return -1;\r
- }\r
+ uart_event_t evt;\r
xSemaphoreTake(p_uart_obj[uart_num]->tx_buffer_mutex, (portTickType)portMAX_DELAY);\r
- evt->type = UART_DATA_BREAK;\r
- evt->data.size = size;\r
- evt->data.brk_len = brk_len;\r
- memcpy(evt->data.data, src, size);\r
- xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) evt, sizeof(uart_event_t) + size, portMAX_DELAY);\r
- free(evt);\r
- evt = NULL;\r
+ evt.type = UART_DATA_BREAK;\r
+ evt.data.size = size;\r
+ evt.data.brk_len = brk_len;\r
+ xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_event_t), portMAX_DELAY);\r
+ xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) src, size, portMAX_DELAY);\r
xSemaphoreGive(p_uart_obj[uart_num]->tx_buffer_mutex);\r
+ uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT);\r
return size;\r
} else {\r
ESP_LOGW(UART_TAG, "UART TX BUFFER TOO SMALL[1], SEND DIRECTLY\n");\r
p_uart_obj[uart_num]->head_ptr = data;\r
p_uart_obj[uart_num]->rd_ptr = data;\r
p_uart_obj[uart_num]->cur_remain = size;\r
+// ets_printf("dbg0\n");\r
} else {\r
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);\r
+// ets_printf("dbg1\n");\r
return copy_len;\r
}\r
}\r
} else {\r
len_tmp = p_uart_obj[uart_num]->cur_remain;\r
}\r
+// ets_printf("dbga\n");\r
memcpy(buf + copy_len, p_uart_obj[uart_num]->rd_ptr, len_tmp);\r
p_uart_obj[uart_num]->rd_ptr += len_tmp;\r
p_uart_obj[uart_num]->cur_remain -= len_tmp;\r
copy_len += len_tmp;\r
length -= len_tmp;\r
+// ets_printf("dbgb\n");\r
if(p_uart_obj[uart_num]->cur_remain == 0) {\r
vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->head_ptr);\r
p_uart_obj[uart_num]->head_ptr = NULL;\r
p_uart_obj[uart_num]->rd_ptr = NULL;\r
if(p_uart_obj[uart_num]->buffer_full_flg) {\r
BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->data_buf, p_uart_obj[uart_num]->data_len, 1);\r
+// ets_printf("dbg2\n");\r
if(res == pdTRUE) {\r
p_uart_obj[uart_num]->buffer_full_flg = false;\r
uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);\r
}\r
}\r
}\r
+// ets_printf("dbg3\n");\r
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);\r
return copy_len;\r
}\r
p_uart_obj[uart_num]->rx_buf_type = rx_buf_type;\r
p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, rx_buf_type);\r
if(tx_buffer_size > 0) {\r
- p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);\r
+ p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);//RINGBUF_TYPE_BYTEBUF);//RINGBUF_TYPE_NOSPLIT);\r
p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size;\r
- xTaskCreate(uart_tx_task, "uart_tx_task", UART_TX_TASK_DEPTH_DEFAULT, (void*)p_uart_obj[uart_num], UART_TX_TASK_PRIO_DEFAULT, &p_uart_obj[uart_num]->tx_task_handle);\r
-\r
} else {\r
p_uart_obj[uart_num]->tx_ring_buf = NULL;\r
p_uart_obj[uart_num]->tx_buf_size = 0;\r
- p_uart_obj[uart_num]->tx_task_handle = NULL;\r
}\r
} else {\r
ESP_LOGE(UART_TAG, "UART driver already installed\n");\r
uart_disable_tx_intr(uart_num);\r
uart_isr_register(uart_num, p_uart_obj[uart_num]->intr_num, NULL, NULL);\r
\r
- if(p_uart_obj[uart_num]->tx_task_handle) {\r
- vTaskDelete(p_uart_obj[uart_num]->tx_task_handle);\r
- p_uart_obj[uart_num]->tx_task_handle = NULL;\r
- }\r
if(p_uart_obj[uart_num]->tx_fifo_sem) {\r
vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem);\r
p_uart_obj[uart_num]->tx_fifo_sem = NULL;\r
{
int free_size = rb->free_ptr-rb->write_ptr;
if (free_size <= 0) free_size += rb->size;
+ //If we free the last dummy item in the buffer, free_ptr will point to rb->data
+ //In this case, after we write the last some bytes, the buffer might wrap around if we don't have room for a header anymore.
+// if (free_size == 0 && rb->read_ptr == rb->write_ptr) free_size += rb->size;
//Reserve one byte. If we do not do this and the entire buffer is filled, we get a situation
- //where read_ptr == free_ptr, messing up the next calculation.
- return free_size-1;
+ //where write_ptr == free_ptr, messing up the next calculation.
+// return free_size == 0 ? 0 : free_size - 1;
+ return free_size - 1;
}
//can be increase.
//This function by itself is not threadsafe, always call from within a muxed section.
static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) {
+ ets_printf("in returnItemToRingbufDefault\n");
+ xRingbufferPrintInfo(rb);
+
+
uint8_t *data=(uint8_t*)item;
configASSERT(((int)rb->free_ptr&3)==0);
configASSERT(data >= rb->data);
hdr=(buf_entry_hdr_t *)rb->free_ptr;
//basically forward free_ptr until we run into either a block that is still in use or the write pointer.
while (((hdr->flags & iflag_free) || (hdr->flags & iflag_dummydata)) && rb->free_ptr != rb->write_ptr) {
+
if (hdr->flags & iflag_dummydata) {
+ ets_printf("hrd len: %d; flg: 0x%02x\n",hdr->len,hdr->flags);
//Rest is dummy data. Reset to start of ringbuffer.
rb->free_ptr=rb->data;
+ //If the read_ptr is pointing to this dummy item,
+ //we should also move the read pointer to data, in case we overwrite the read hdr.
+// if(rb->read_ptr == (uint8_t*)hdr) {
+// rb->read_ptr = rb->data;
+// }
} else {
//Skip past item
size_t len=(hdr->len+3)&~3;
if ((rb->data+rb->size)-rb->free_ptr < sizeof(buf_entry_hdr_t)) {
rb->free_ptr=rb->data;
}
+ if(rb->free_ptr == rb->read_ptr) break;
//Next header
hdr=(buf_entry_hdr_t *)rb->free_ptr;
+
}
}
configASSERT(rb);
ets_printf("Rb size %d free %d rptr %d freeptr %d wptr %d\n",
rb->size, ringbufferFreeMem(rb), rb->read_ptr-rb->data, rb->free_ptr-rb->data, rb->write_ptr-rb->data);
+ buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->read_ptr;
+ if(rb->write_ptr == rb->read_ptr) {
+ ets_printf("write que read\n");
+ } else {
+ ets_printf("hdr len: %d; flg: 0x%08x\n", hdr->len, hdr->flags);
+ }
}
ticks_to_wait = ticks_end - xTaskGetTickCount();
}
} while (ringbufferFreeMem(rb) < needed_size && ticks_to_wait>=0);
-
+
//Lock the mux in order to make sure no one else is messing with the ringbuffer and do the copy.
portENTER_CRITICAL(&rb->mux);
//Another thread may have been able to sneak its write first. Check again now we locked the ringbuff, and retry