Page 1 of 1

hw fifo overflow max set / reset

Posted: Sun Nov 20, 2016 11:38 pm
by rudi ;-)
hi guys

Code: Select all


#define UART_FIFO_LEN           (128)        /*!< Length of the hardware FIFO buffers */

how much we can set fifo for uart in extrem example and how much you suggest for max?
can we read, reset overflow bit by user?
reset Fifo after read by user ?

Code: Select all

uart_reg->int_clr.txfifo_empty = 1;
uart_reg->int_ena.txfifo_empty = 1;
best wishes
rudi ;-)

Code: Select all


//Event of HW FIFO overflow detected
                  case UART_FIFO_OVF:
                      ESP_LOGI(TAG, "hw fifo overflow\n");
                      break;
                      
btw, we have rxfifo and txfifo,
hw fifo respekt UART_FIFO_OVF means allways rxfifo ?

btw: CAN Register works just in time pefekt ( 1000 msg )
only uart hw fifo ovf - have not insert fifo reset after INTR.
hw fifo overflow.png
hw fifo overflow.png (10.46 KiB) Viewed 16082 times

Re: hw fifo overflow max set / reset

Posted: Mon Nov 21, 2016 4:04 am
by WiFive
Max is 128. The idea is to set threshold on number of bytes before the interrupt is triggered.

Re: hw fifo overflow max set / reset

Posted: Wed Nov 23, 2016 10:06 am
by rudi ;-)
WiFive wrote:Max is 128. The idea is to set threshold on number of bytes before the interrupt is triggered.
txs, WiFive,
do you or folks know from head how can hw Fifo check fast and clear the bit?
( src ? / info ? )

( i search just in time this and for controll the ring buffer )
i play with this
and see not the clear doing for hw Fifo. perhabs to much fog for my 8-) :mrgreen:
the event "hw Fifo" can be processed - how/where i can find this info ?

best wishes
rudi ;-)

Code: Select all


} else if(uart_intr_status & UART_RXFIFO_OVF_INT_ST_M) {
            UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
            uart_reg->conf0.rxfifo_rst = 1;
            uart_reg->conf0.rxfifo_rst = 0;
            uart_reg->int_clr.rxfifo_ovf = 1;
            UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
            uart_event.type = UART_FIFO_OVF;

clear..all other..

Code: Select all


else {
            uart_reg->int_clr.val = uart_intr_status; /*simply clear all other intr status*/
            uart_event.type = UART_EVENT_MAX;
            

?

Code: Select all


uart_reg->int_clr.val = UART_RXFIFO_FULL_INT_CLR_M | UART_RXFIFO_TOUT_INT_CLR_M;

Re: hw fifo overflow max set / reset

Posted: Wed Nov 23, 2016 11:34 am
by rudi ;-)
hi

where is UART defined?

Code: Select all

uart_dev_t* uart_reg = UART[uart_num];
txs
best wishes
rudi ;-)

Re: hw fifo overflow max set / reset

Posted: Wed Nov 23, 2016 11:45 am
by rudi ;-)
rudi ;-) wrote:hi

where is UART defined?

Code: Select all

uart_dev_t* uart_reg = UART[uart_num];
txs
best wishes
rudi ;-)

Code: Select all


// static const char* UART_TAG = "UART";
static uart_dev_t* UART[UART_NUM_MAX] = {&UART0, &UART1, &UART2};
..
...

int ValReg = 0;
      int uart_num = (int)pvParameters;
      uart_event_t event;
	  uart_dev_t* uart_reg = UART[uart_num];  // yeap..


Re: hw fifo overflow max set / reset

Posted: Wed Nov 23, 2016 2:15 pm
by rudi ;-)
hi,
when/where we must do this?
in the ISR after clear the bits?

Code: Select all

uart_flush(uart_num);



Code: Select all


esp_err_t uart_flush(uart_port_t uart_num)
{
    UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
    UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL);
    uart_obj_t* p_uart = p_uart_obj[uart_num];
    uint8_t* data;
    size_t size;

    //rx sem protect the ring buffer read related functions
    xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY);
    ESP_INTR_DISABLE(p_uart->intr_num);
    while(true) {
        if(p_uart->rx_head_ptr) {
            vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr);
            p_uart->rx_ptr = NULL;
            p_uart->rx_cur_remain = 0;
            p_uart->rx_head_ptr = NULL;
        }
        data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0);
        if(data == NULL) {
            break;
        }
        vRingbufferReturnItem(p_uart->rx_ring_buf, data);
    }
    p_uart->rx_ptr = NULL;
    p_uart->rx_cur_remain = 0;
    p_uart->rx_head_ptr = NULL;
    ESP_INTR_ENABLE(p_uart->intr_num);
    xSemaphoreGive(p_uart->rx_mux);

    if(p_uart->tx_buf_size > 0) {
        xSemaphoreTake(p_uart->tx_mux, (portTickType)portMAX_DELAY);
        ESP_INTR_DISABLE(p_uart->intr_num);
        UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
        UART[uart_num]->int_ena.txfifo_empty = 0;
        UART[uart_num]->int_clr.txfifo_empty = 1;
        UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
        do {
            data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0);
            if(data == NULL) {
                break;
            }
            vRingbufferReturnItem(p_uart->rx_ring_buf, data);
        } while(1);
        p_uart->tx_brk_flg = 0;
        p_uart->tx_brk_len = 0;
        p_uart->tx_head = NULL;
        p_uart->tx_len_cur = 0;
        p_uart->tx_len_tot = 0;
        p_uart->tx_ptr = NULL;
        p_uart->tx_waiting_brk = 0;
        p_uart->tx_waiting_fifo = false;
        ESP_INTR_ENABLE(p_uart->intr_num);
        xSemaphoreGive(p_uart->tx_mux);
    }
    uart_reset_fifo(uart_num);
    return ESP_OK;
}

Re: hw fifo overflow max set / reset

Posted: Wed Nov 23, 2016 8:24 pm
by rudi ;-)

Code: Select all


..
static esp_err_t uart_reset_fifo(uart_port_t uart_num);
..
..

//Event of HW FIFO overflow detected
                  case UART_FIFO_OVF:
                      ESP_LOGI(TAG, "hw fifo overflow\n");
					  // uart_reg->int_clr.val = UART_RXFIFO_FULL_INT_CLR_M | UART_RXFIFO_TOUT_INT_CLR_M;
					  
					  // UART_RXFIFO_OVF_INT_ST_M
					  uart_reg->int_clr.val = UART_RXFIFO_OVF_INT_ST_M;
					  
					  reg_delay();
					  ESP_LOGI(TAG, "cleared..\n");
					  
					   uart_flush(uart_num);
					   ESP_LOGI(TAG, "uart_flush cleared..\n");
					  
					  // reset
					   uart_reset_fifo(uart_num);
					   ESP_LOGI(TAG, "fifo reset\r\n");
					  
					  break;
                  //Event of UART ring buffer full
                  case UART_BUFFER_FULL:
                      ESP_LOGI(TAG, "ring buffer full\n");
                      
					  
					  uart_reg->int_clr.val = UART_RXFIFO_OVF_INT_ST_M;
					  reg_delay();
					  ESP_LOGI(TAG, "ringbuffer int cleared..\n");
					  break;

...

Code: Select all



..../build/main\libmain.a(uart_main.o):(.literal.uart_task+0x64): undefined reference to `uart_reset_fifo'

:(

Re: hw fifo overflow max set / reset

Posted: Wed Nov 23, 2016 9:00 pm
by WiFive
It is not exported in UART.h

But really you are supposed to design UART code to avoid overflow for expected data stream. You may need to interrupt more frequently to empty the fifo into the ring buffer or make a bigger ring buffer or use hw/sw flow control or wait for DMA support.

Re: hw fifo overflow max set / reset

Posted: Thu Nov 24, 2016 1:13 am
by rudi ;-)
WiFive wrote:It is not exported in UART.h

But really you are supposed to design UART code to avoid overflow for expected data stream. You may need to interrupt more frequently to empty the fifo into the ring buffer or make a bigger ring buffer or use hw/sw flow control or wait for DMA support.
thank you WiFive,
i do now a delay between the send data - and for first - it works - the fifo ovf do not fire now
but the (ring) buffer i think is too small, there are missings thing ( last picture )

i have test the example uart code with task.
now i try to build/design the UART code to avoid overflow for expected data stream, also the ring buffer.

i saw the UHCI (=uart dma )in the 1.0 plan - this would be a goal for this too :P

i will try to handle the things now ( ring buffer, fifo ) - must deeper read .

the good things are, that the register write/clear now ok without mistake.
i do this after each write/clear and it helps:

Code: Select all

void reg_delay (void) {
	__asm__ __volatile__("nop;nop;nop;nop;nop;nop;nop;nop;");
}


best wishes
rudi ;-)