mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-06-16 11:22:53 +08:00
167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
/*
|
|
* 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);
|
|
}
|
|
|