1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-12 01:53:07 +03:00

Change UART register access methods

This commit is contained in:
ficeto
2015-05-03 16:44:19 +03:00
parent c3b559b6e0
commit fcbd7dbed0
2 changed files with 78 additions and 85 deletions

View File

@ -20,6 +20,7 @@
Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266) Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266)
Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266) Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266)
Modified 3 May 2015 by Hristo Gochkov (change register access methods)
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -33,7 +34,6 @@ extern "C" {
#include "osapi.h" #include "osapi.h"
#include "ets_sys.h" #include "ets_sys.h"
#include "mem.h" #include "mem.h"
#include "uart_register.h"
#include "user_interface.h" #include "user_interface.h"
} }
@ -104,51 +104,51 @@ UARTnr_t uart_get_debug();
void ICACHE_RAM_ATTR uart_interrupt_handler(uart_t* uart) { void ICACHE_RAM_ATTR uart_interrupt_handler(uart_t* uart) {
// -------------- UART 0 -------------- // -------------- UART 0 --------------
uint32_t status = READ_PERI_REG(UART_INT_ST(0)); uint32_t status = U0IS;
if(Serial.isRxEnabled()) { if(Serial.isRxEnabled()) {
if(status & UART_RXFIFO_FULL_INT_ST) { if(status & (1 << UIFF)) {
while(true) { while(true) {
int rx_count = (READ_PERI_REG(UART_STATUS(0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT; int rx_count = (U0S >> USTXC) & 0xFF;
if(!rx_count) if(!rx_count)
break; break;
while(rx_count--) { while(rx_count--) {
char c = READ_PERI_REG(UART_FIFO(0)) & 0xFF; char c = U0F & 0xFF;
Serial._rx_complete_irq(c); Serial._rx_complete_irq(c);
} }
} }
WRITE_PERI_REG(UART_INT_CLR(0), UART_RXFIFO_FULL_INT_CLR); U0IC = (1 << UIFF);
} }
} }
if(Serial.isTxEnabled()) { if(Serial.isTxEnabled()) {
if(status & UART_TXFIFO_EMPTY_INT_ST) { if(status & (1 << UIFE)) {
WRITE_PERI_REG(UART_INT_CLR(0), UART_TXFIFO_EMPTY_INT_CLR); U0IC = (1 << UIFE);
Serial._tx_empty_irq(); Serial._tx_empty_irq();
} }
} }
// -------------- UART 1 -------------- // -------------- UART 1 --------------
status = READ_PERI_REG(UART_INT_ST(1)); status = U1IS;
if(Serial1.isRxEnabled()) { if(Serial1.isRxEnabled()) {
if(status & UART_RXFIFO_FULL_INT_ST) { if(status & (1 << UIFF)) {
while(true) { while(true) {
int rx_count = (READ_PERI_REG(UART_STATUS(1)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT; int rx_count = (U1S >> USTXC) & 0xFF;
if(!rx_count) if(!rx_count)
break; break;
while(rx_count--) { while(rx_count--) {
char c = READ_PERI_REG(UART_FIFO(1)) & 0xFF; char c = U1F & 0xFF;
Serial1._rx_complete_irq(c); Serial1._rx_complete_irq(c);
} }
} }
WRITE_PERI_REG(UART_INT_CLR(1), UART_RXFIFO_FULL_INT_CLR); U1IC = (1 << UIFF);
} }
} }
if(Serial1.isTxEnabled()) { if(Serial1.isTxEnabled()) {
status = READ_PERI_REG(UART_INT_ST(1)); status = U1IS;
if(status & UART_TXFIFO_EMPTY_INT_ST) { if(status & (1 << UIFE)) {
WRITE_PERI_REG(UART_INT_CLR(1), UART_TXFIFO_EMPTY_INT_CLR); U1IC = (1 << UIFE);
Serial1._tx_empty_irq(); Serial1._tx_empty_irq();
} }
} }
@ -161,7 +161,7 @@ void ICACHE_FLASH_ATTR uart_wait_for_tx_fifo(uart_t* uart, size_t size_needed) {
return; return;
if(uart->txEnabled) { if(uart->txEnabled) {
while(true) { while(true) {
size_t tx_count = (READ_PERI_REG(UART_STATUS(uart->uart_nr)) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT; size_t tx_count = (USS(uart->uart_nr) >> USTXC) & 0xFF;
if(tx_count <= (UART_TX_FIFO_SIZE - size_needed)) if(tx_count <= (UART_TX_FIFO_SIZE - size_needed))
break; break;
} }
@ -172,7 +172,7 @@ size_t ICACHE_FLASH_ATTR uart_get_tx_fifo_room(uart_t* uart) {
if(uart == 0) if(uart == 0)
return 0; return 0;
if(uart->txEnabled) { if(uart->txEnabled) {
return UART_TX_FIFO_SIZE - ((READ_PERI_REG(UART_STATUS(uart->uart_nr)) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT); return UART_TX_FIFO_SIZE - ((USS(uart->uart_nr) >> USTXC) & 0xFF);
} }
return 0; return 0;
} }
@ -189,7 +189,7 @@ void ICACHE_FLASH_ATTR uart_transmit_char(uart_t* uart, char c) {
if(uart == 0) if(uart == 0)
return; return;
if(uart->txEnabled) { if(uart->txEnabled) {
WRITE_PERI_REG(UART_FIFO(uart->uart_nr), c); USF(uart->uart_nr) = c;
} }
} }
@ -203,7 +203,7 @@ void ICACHE_FLASH_ATTR uart_transmit(uart_t* uart, const char* buf, size_t size)
uart_wait_for_tx_fifo(uart, part_size); uart_wait_for_tx_fifo(uart, part_size);
for(; part_size; --part_size, ++buf) for(; part_size; --part_size, ++buf)
WRITE_PERI_REG(UART_FIFO(uart->uart_nr), *buf); USF(uart->uart_nr) = *buf;
} }
} }
} }
@ -215,24 +215,24 @@ void ICACHE_FLASH_ATTR uart_flush(uart_t* uart) {
return; return;
if(uart->rxEnabled) { if(uart->rxEnabled) {
tmp |= UART_RXFIFO_RST; tmp |= (1 << UCRXRST);
} }
if(uart->txEnabled) { if(uart->txEnabled) {
tmp |= UART_TXFIFO_RST; tmp |= (1 << UCTXRST);
} }
SET_PERI_REG_MASK(UART_CONF0(uart->uart_nr), tmp); USC0(uart->uart_nr) |= (tmp);
CLEAR_PERI_REG_MASK(UART_CONF0(uart->uart_nr), tmp); USC0(uart->uart_nr) &= ~(tmp);
} }
void ICACHE_FLASH_ATTR uart_interrupt_enable(uart_t* uart) { void ICACHE_FLASH_ATTR uart_interrupt_enable(uart_t* uart) {
if(uart == 0) if(uart == 0)
return; return;
WRITE_PERI_REG(UART_INT_CLR(uart->uart_nr), 0x1ff); USIC(uart->uart_nr) = 0x1ff;
ETS_UART_INTR_ATTACH(&uart_interrupt_handler, uart); // uart parameter is not osed in irq function! ETS_UART_INTR_ATTACH(&uart_interrupt_handler, uart); // uart parameter is not osed in irq function!
if(uart->rxEnabled) { if(uart->rxEnabled) {
SET_PERI_REG_MASK(UART_INT_ENA(uart->uart_nr), UART_RXFIFO_FULL_INT_ENA); USIE(uart->uart_nr) |= (1 << UIFF);
} }
ETS_UART_INTR_ENABLE(); ETS_UART_INTR_ENABLE();
} }
@ -241,10 +241,10 @@ void ICACHE_FLASH_ATTR uart_interrupt_disable(uart_t* uart) {
if(uart == 0) if(uart == 0)
return; return;
if(uart->rxEnabled) { if(uart->rxEnabled) {
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart->uart_nr), UART_RXFIFO_FULL_INT_ENA); USIE(uart->uart_nr) &= ~(1 << UIFF);
} }
if(uart->txEnabled) { if(uart->txEnabled) {
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart->uart_nr), UART_TXFIFO_EMPTY_INT_ENA); USIE(uart->uart_nr) &= ~(1 << UIFE);
} }
//ETS_UART_INTR_DISABLE(); // never disable irq complete may its needed by the other Serial Interface! //ETS_UART_INTR_DISABLE(); // never disable irq complete may its needed by the other Serial Interface!
} }
@ -253,7 +253,7 @@ void ICACHE_FLASH_ATTR uart_arm_tx_interrupt(uart_t* uart) {
if(uart == 0) if(uart == 0)
return; return;
if(uart->txEnabled) { if(uart->txEnabled) {
SET_PERI_REG_MASK(UART_INT_ENA(uart->uart_nr), UART_TXFIFO_EMPTY_INT_ENA); USIE(uart->uart_nr) |= (1 << UIFE);
} }
} }
@ -261,7 +261,7 @@ void ICACHE_FLASH_ATTR uart_disarm_tx_interrupt(uart_t* uart) {
if(uart == 0) if(uart == 0)
return; return;
if(uart->txEnabled) { if(uart->txEnabled) {
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart->uart_nr), UART_TXFIFO_EMPTY_INT_ENA); USIE(uart->uart_nr) &= ~(1 << UIFE);
} }
} }
@ -269,7 +269,7 @@ void ICACHE_FLASH_ATTR uart_set_baudrate(uart_t* uart, int baud_rate) {
if(uart == 0) if(uart == 0)
return; return;
uart->baud_rate = baud_rate; uart->baud_rate = baud_rate;
uart_div_modify(uart->uart_nr, UART_CLK_FREQ / (uart->baud_rate)); USD(uart->uart_nr) = (F_CPU / uart->baud_rate);
} }
int ICACHE_FLASH_ATTR uart_get_baudrate(uart_t* uart) { int ICACHE_FLASH_ATTR uart_get_baudrate(uart_t* uart) {
@ -291,18 +291,15 @@ uart_t* ICACHE_FLASH_ATTR uart_init(UARTnr_t uart_nr, int baudrate, byte config)
switch(uart->uart_nr) { switch(uart->uart_nr) {
case UART0: case UART0:
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); pinMode(1, SPECIAL);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); pinMode(3, SPECIAL);
PIN_PULLUP_EN(PERIPHS_IO_MUX_U0RXD_U);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD);
uart->rxEnabled = true; uart->rxEnabled = true;
uart->txEnabled = true; uart->txEnabled = true;
uart->rxPin = 3; uart->rxPin = 3;
uart->txPin = 1; uart->txPin = 1;
break; break;
case UART1: case UART1:
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); pinMode(2, SPECIAL);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
uart->rxEnabled = false; uart->rxEnabled = false;
uart->txEnabled = true; uart->txEnabled = true;
uart->rxPin = 255; uart->rxPin = 255;
@ -314,20 +311,20 @@ uart_t* ICACHE_FLASH_ATTR uart_init(UARTnr_t uart_nr, int baudrate, byte config)
break; break;
} }
uart_set_baudrate(uart, baudrate); uart_set_baudrate(uart, baudrate);
WRITE_PERI_REG(UART_CONF0(uart->uart_nr), config); USC0(uart->uart_nr) = config;
uart_flush(uart); uart_flush(uart);
uart_interrupt_enable(uart); uart_interrupt_enable(uart);
if(uart->rxEnabled) { if(uart->rxEnabled) {
conf1 |= ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S); conf1 |= (0x01 << UCFFT);
} }
if(uart->txEnabled) { if(uart->txEnabled) {
conf1 |= ((0x20 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S); conf1 |= (0x20 << UCFET);
} }
WRITE_PERI_REG(UART_CONF1(uart->uart_nr), conf1); USC1(uart->uart_nr) = conf1;
return uart; return uart;
} }
@ -339,30 +336,25 @@ void ICACHE_FLASH_ATTR uart_uninit(uart_t* uart) {
switch(uart->rxPin) { switch(uart->rxPin) {
case 3: case 3:
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0RXD_U); pinMode(3, INPUT);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3);
break; break;
case 13: case 13:
PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); pinMode(13, INPUT);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
break; break;
} }
switch(uart->txPin) { switch(uart->txPin) {
case 1: case 1:
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1); pinMode(1, INPUT);
break; break;
case 2: case 2:
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); pinMode(2, INPUT);
break; break;
case 15: case 15:
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); pinMode(15, INPUT);
break; break;
} }
pinMode(uart->rxPin, INPUT);
pinMode(uart->txPin, INPUT);
os_free(uart); os_free(uart);
} }
@ -372,39 +364,19 @@ void ICACHE_FLASH_ATTR uart_swap(uart_t* uart) {
switch(uart->uart_nr) { switch(uart->uart_nr) {
case UART0: case UART0:
if(uart->txPin == 1 && uart->rxPin == 3) { if(uart->txPin == 1 && uart->rxPin == 3) {
pinMode(15, FUNCTION_4);//TX
PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); pinMode(13, FUNCTION_4);//RX
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); USWAP |= (1 << USWAP0);
pinMode(1, INPUT);//TX
PIN_PULLUP_EN(PERIPHS_IO_MUX_MTDO_U); pinMode(3, INPUT);//RX
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_UART0_RTS);
//SWAP PIN : U0TXD<==>U0RTS(MTDO, GPIO15) , U0RXD<==>U0CTS(MTCK, GPIO13)
SET_PERI_REG_MASK(0x3ff00028, BIT2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_GPIO3);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_GPIO1);
pinMode(uart->rxPin, INPUT);
pinMode(uart->txPin, INPUT);
uart->rxPin = 13; uart->rxPin = 13;
uart->txPin = 15; uart->txPin = 15;
} else { } else {
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); pinMode(1, SPECIAL);//TX
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); pinMode(3, SPECIAL);//RX
USWAP &= ~(1 << USWAP0);
PIN_PULLUP_EN(PERIPHS_IO_MUX_U0RXD_U); pinMode(15, INPUT);//TX
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); pinMode(13, INPUT);//RX
CLEAR_PERI_REG_MASK(0x3ff00028, BIT2);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15);
pinMode(uart->rxPin, INPUT);
pinMode(uart->txPin, INPUT);
uart->rxPin = 3; uart->rxPin = 3;
uart->txPin = 1; uart->txPin = 1;
} }
@ -433,9 +405,9 @@ void ICACHE_FLASH_ATTR uart0_write_char(char c) {
Serial.write(c); Serial.write(c);
} else { } else {
if(c == '\n') { if(c == '\n') {
WRITE_PERI_REG(UART_FIFO(0), '\r'); USF(0) = '\r';
} }
WRITE_PERI_REG(UART_FIFO(0), c); USF(0) = c;
} }
} }
@ -447,9 +419,9 @@ void ICACHE_FLASH_ATTR uart1_write_char(char c) {
Serial1.write(c); Serial1.write(c);
} else { } else {
if(c == '\n') { if(c == '\n') {
WRITE_PERI_REG(UART_FIFO(1), '\r'); USF(1) = '\r';
} }
WRITE_PERI_REG(UART_FIFO(1), c); USF(1) = c;
} }
} }

View File

@ -149,6 +149,10 @@ static uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C,
#define TCIT 0 //Interrupt Type 0:edge, 1:level #define TCIT 0 //Interrupt Type 0:edge, 1:level
//UART SWAP Register
#define USWAP ESP8266_DREG(0x28)
#define USWAP0 2 //BIT 2 swaps UART 0
//UART 0 Registers //UART 0 Registers
#define U0F ESP8266_REG(0x000) //UART FIFO #define U0F ESP8266_REG(0x000) //UART FIFO
#define U0IR ESP8266_REG(0x004) //INT_RAW #define U0IR ESP8266_REG(0x004) //INT_RAW
@ -183,6 +187,23 @@ static uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C,
#define U1DT ESP8266_REG(0xF78) //DATE #define U1DT ESP8266_REG(0xF78) //DATE
#define U1ID ESP8266_REG(0xF7C) //ID #define U1ID ESP8266_REG(0xF7C) //ID
//UART(uart) Registers
#define USF(u) ESP8266_REG(0x000+(0xF00*(u&1))) //UART FIFO
#define USIR(u) ESP8266_REG(0x004+(0xF00*(u&1))) //INT_RAW
#define USIS(u) ESP8266_REG(0x008+(0xF00*(u&1))) //INT_STATUS
#define USIE(u) ESP8266_REG(0x00c+(0xF00*(u&1))) //INT_ENABLE
#define USIC(u) ESP8266_REG(0x010+(0xF00*(u&1))) //INT_CLEAR
#define USD(u) ESP8266_REG(0x014+(0xF00*(u&1))) //CLKDIV
#define USA(u) ESP8266_REG(0x018+(0xF00*(u&1))) //AUTOBAUD
#define USS(u) ESP8266_REG(0x01C+(0xF00*(u&1))) //STATUS
#define USC0(u) ESP8266_REG(0x020+(0xF00*(u&1))) //CONF0
#define USC1(u) ESP8266_REG(0x024+(0xF00*(u&1))) //CONF1
#define USLP(u) ESP8266_REG(0x028+(0xF00*(u&1))) //LOW_PULSE
#define USHP(u) ESP8266_REG(0x02C+(0xF00*(u&1))) //HIGH_PULSE
#define USPN(u) ESP8266_REG(0x030+(0xF00*(u&1))) //PULSE_NUM
#define USDT(u) ESP8266_REG(0x078+(0xF00*(u&1))) //DATE
#define USID(u) ESP8266_REG(0x07C+(0xF00*(u&1))) //ID
//UART INT Registers Bits //UART INT Registers Bits
#define UITO 8 //RX FIFO TimeOut #define UITO 8 //RX FIFO TimeOut
#define UIBD 7 //Break Detected #define UIBD 7 //Break Detected