diff --git a/examples/driver_lib/driver/uart.c b/examples/driver_lib/driver/uart.c new file mode 100644 index 00000000..4c4872ca --- /dev/null +++ b/examples/driver_lib/driver/uart.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2014 -2016 Espressif System + * + */ + +#include "esp_common.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +#include "uart.h" + +enum { + UART_EVENT_RX_CHAR, + UART_EVENT_MAX +}; + +typedef struct _os_event_ { + uint32 event; + uint32 param; +} os_event_t; + + +xTaskHandle xUartTaskHandle; +xQueueHandle xQueueUart; + +LOCAL STATUS +uart_tx_one_char(uint8 uart, uint8 TxChar) +{ + while (true) { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); + + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { + break; + } + } + + WRITE_PERI_REG(UART_FIFO(uart) , TxChar); + return OK; +} + +LOCAL void +uart1_write_char(char c) +{ + if (c == '\n') { + uart_tx_one_char(UART1, '\r'); + uart_tx_one_char(UART1, '\n'); + } else if (c == '\r') { + } else { + uart_tx_one_char(UART1, c); + } +} + +LOCAL void uart_rx_intr_handler_ssc(void) +{ + /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents + * uart1 and uart0 respectively + */ + os_event_t e; + portBASE_TYPE xHigherPriorityTaskWoken; + + uint8 RcvChar; + uint8 uart_no = 0; + + if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) { + return; + } + + RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; + + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); + + e.event = UART_EVENT_RX_CHAR; + e.param = RcvChar; + + xQueueSendFromISR(xQueueUart, (void *)&e, &xHigherPriorityTaskWoken); + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +} + +LOCAL void ICACHE_FLASH_ATTR +uart_config(uint8 uart_no, UartDevice *uart) +{ + if (uart_no == UART1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + } else { + /* rcv_buff size if 0x100 */ + _xt_isr_attach(ETS_UART_INUM, uart_rx_intr_handler_ssc); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + } + + uart_div_modify(uart_no, UART_CLK_FREQ / (uart->baut_rate)); + + WRITE_PERI_REG(UART_CONF0(uart_no), uart->exist_parity + | uart->parity + | (uart->stop_bits << UART_STOP_BIT_NUM_S) + | (uart->data_bits << UART_BIT_NUM_S)); + + //clear rx and tx fifo,not ready + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + + if (uart_no == UART0) { + //set rx fifo trigger + WRITE_PERI_REG(UART_CONF1(uart_no), + ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); + } else { + WRITE_PERI_REG(UART_CONF1(uart_no), + ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); + } + + //clear all interrupt + WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); + //enable rx_interrupt + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); +} + +LOCAL void ICACHE_FLASH_ATTR +uart_task(void *pvParameters) +{ + os_event_t e; + + for (;;) { + if (xQueueReceive(xQueueUart, (void *)&e, (portTickType)portMAX_DELAY)) { + switch (e.event) { + case UART_EVENT_RX_CHAR: + printf("%c", e.param); + break; + + default: + break; + } + } + } + + vTaskDelete(NULL); +} + +void ICACHE_FLASH_ATTR +uart_init(void) +{ + while (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); + while (READ_PERI_REG(UART_STATUS(1)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); + + UartDevice uart; + + uart.baut_rate = BIT_RATE_74880; + uart.data_bits = EIGHT_BITS; + uart.flow_ctrl = NONE_CTRL; + uart.exist_parity = STICK_PARITY_DIS; + uart.parity = NONE_BITS; + uart.stop_bits = ONE_STOP_BIT; + + uart_config(UART0, &uart); + uart_config(UART1, &uart); + + os_install_putc1(uart1_write_char); + + _xt_isr_unmask(1 << ETS_UART_INUM); + + xQueueUart = xQueueCreate(32, sizeof(os_event_t)); + + xTaskCreate(uart_task, (uint8 const *)"uTask", 512, NULL, tskIDLE_PRIORITY + 2, &xUartTaskHandle); +} + diff --git a/examples/driver_lib/include/uart.h b/examples/driver_lib/include/uart.h index 62a7d74d..ca792189 100644 --- a/examples/driver_lib/include/uart.h +++ b/examples/driver_lib/include/uart.h @@ -60,4 +60,6 @@ typedef struct { UartFlowCtrl flow_ctrl; } UartDevice; +void uart_init(); + #endif