Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting alternate TX for UART 0, so GPIO1 is available as SPI_CS1 #1424

Merged
merged 3 commits into from
Jan 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 90 additions & 24 deletions cores/esp8266/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,12 @@ void uart_disarm_tx_interrupt(uart_t* uart);
void uart_set_baudrate(uart_t* uart, int baud_rate);
int uart_get_baudrate(uart_t* uart);

uart_t* uart_start_init(int uart_nr, int baudrate, byte config);
uart_t* uart_start_init(int uart_nr, int baudrate, byte config, uint8_t use_tx);
void uart_finish_init(uart_t* uart);
void uart_uninit(uart_t* uart);
void uart_swap(uart_t* uart);
void uart_swap(uart_t* uart, uint8_t use_tx);
void uart_set_tx(uart_t* uart, uint8_t use_tx);
void uart_set_pins(uart_t* uart, uint8_t tx, uint8_t rx);

void uart_ignore_char(char c);
void uart0_write_char(char c);
Expand Down Expand Up @@ -274,7 +276,7 @@ int uart_get_baudrate(uart_t* uart) {
return uart->baud_rate;
}

uart_t* uart_start_init(int uart_nr, int baudrate, byte config, byte mode) {
uart_t* uart_start_init(int uart_nr, int baudrate, byte config, byte mode, uint8_t use_tx) {

uart_t* uart = (uart_t*) os_malloc(sizeof(uart_t));

Expand All @@ -289,8 +291,15 @@ uart_t* uart_start_init(int uart_nr, int baudrate, byte config, byte mode) {
uart->rxEnabled = (mode != SERIAL_TX_ONLY);
uart->txEnabled = (mode != SERIAL_RX_ONLY);
uart->rxPin = (uart->rxEnabled)?3:255;
uart->txPin = (uart->txEnabled)?1:255;
if(uart->rxEnabled) pinMode(uart->rxPin, SPECIAL);
if(uart->rxEnabled) {
if (use_tx == 2) {
uart->txPin = 2;
pinMode(uart->rxPin, FUNCTION_4);
} else {
uart->txPin = 1;
pinMode(uart->rxPin, SPECIAL);
}
} else uart->txPin = 255;
if(uart->txEnabled) pinMode(uart->txPin, SPECIAL);
IOSWAP &= ~(1 << IOSWAPU0);
break;
Expand All @@ -299,7 +308,7 @@ uart_t* uart_start_init(int uart_nr, int baudrate, byte config, byte mode) {
uart->rxEnabled = false;
uart->txEnabled = (mode != SERIAL_RX_ONLY);
uart->rxPin = 255;
uart->txPin = (uart->txEnabled)?2:255;
uart->txPin = (uart->txEnabled)?2:255; // GPIO7 as TX not possible! See GPIO pins used by UART
if(uart->txEnabled) pinMode(uart->txPin, SPECIAL);
break;
case UART_NO:
Expand Down Expand Up @@ -360,46 +369,91 @@ void uart_uninit(uart_t* uart) {
os_free(uart);
}

void uart_swap(uart_t* uart) {
void uart_swap(uart_t* uart, uint8_t use_tx) {
if(uart == 0)
return;
switch(uart->uart_nr) {
case UART0:
if((uart->txPin == 1 && uart->txEnabled) || (uart->rxPin == 3 && uart->rxEnabled)) {
if(uart->txEnabled) pinMode(15, FUNCTION_4); //TX
if(uart->rxEnabled) pinMode(13, FUNCTION_4); //RX
IOSWAP |= (1 << IOSWAPU0);
if(((uart->txPin == 1 || uart->txPin == 2) && uart->txEnabled) || (uart->rxPin == 3 && uart->rxEnabled)) {
if(uart->txEnabled){ //TX
pinMode(1, INPUT);
pinMode(uart->txPin, INPUT);
uart->txPin = 15;
}
if(uart->rxEnabled){ //RX
pinMode(3, INPUT);
pinMode(uart->rxPin, INPUT);
uart->rxPin = 13;
}
if(uart->txEnabled) pinMode(uart->txPin, FUNCTION_4); //TX
if(uart->rxEnabled) pinMode(uart->rxPin, FUNCTION_4); //RX
IOSWAP |= (1 << IOSWAPU0);
} else {
if(uart->txEnabled) pinMode(1, SPECIAL); //TX
if(uart->rxEnabled) pinMode(3, SPECIAL); //RX
IOSWAP &= ~(1 << IOSWAPU0);
if(uart->txEnabled){ //TX
pinMode(15, INPUT);
uart->txPin = 1;
pinMode(uart->txPin, INPUT);
uart->txPin = (use_tx == 2)?2:1;
}
if(uart->rxEnabled){ //RX
pinMode(13, INPUT); //RX
pinMode(uart->rxPin, INPUT);
uart->rxPin = 3;
}
if(uart->txEnabled) pinMode(uart->txPin, (use_tx == 2)?FUNCTION_4:SPECIAL); //TX
if(uart->rxEnabled) pinMode(3, SPECIAL); //RX
IOSWAP &= ~(1 << IOSWAPU0);
}

break;
case UART1:
// Currently no swap possible! See GPIO pins used by UART
break;
default:
break;
}
}

void uart_set_tx(uart_t* uart, uint8_t use_tx) {
if(uart == 0)
return;
switch(uart->uart_nr) {
case UART0:
if(uart->txEnabled) {
if (uart->txPin == 1 && use_tx == 2) {
pinMode(uart->txPin, INPUT);
uart->txPin = 2;
pinMode(uart->txPin, FUNCTION_4);
} else if (uart->txPin == 2 && use_tx != 2) {
pinMode(uart->txPin, INPUT);
uart->txPin = 1;
pinMode(uart->txPin, SPECIAL);
}
}

break;
case UART1:
// current no swap possible! see GPIO pins used by UART
// GPIO7 as TX not possible! See GPIO pins used by UART
break;
default:
break;
}
}

void uart_set_pins(uart_t* uart, uint8_t tx, uint8_t rx) {
if(uart == 0)
return;

if(uart->uart_nr == UART0) { // Only UART0 allows pin changes
if(uart->txEnabled && uart->txPin != tx) {
if( rx == 13 && tx == 15) {
uart_swap(uart, 15);
} else if (rx == 3 && (tx == 1 || tx == 2)) {
if (uart->rxPin != rx) uart_swap(uart, tx);
else uart_set_tx(uart, tx);
}
}
if(uart->rxEnabled && uart->rxPin != rx && rx == 13 && tx == 15) {
uart_swap(uart, 15);
}
}
}

// ####################################################################################################
// ####################################################################################################
// ####################################################################################################
Expand Down Expand Up @@ -488,7 +542,7 @@ HardwareSerial::HardwareSerial(int uart_nr) :
_uart_nr(uart_nr), _uart(0), _tx_buffer(0), _rx_buffer(0) {
}

void HardwareSerial::begin(unsigned long baud, byte config, byte mode) {
void HardwareSerial::begin(unsigned long baud, byte config, byte mode, uint8_t use_tx) {
InterruptLock il;

// disable debug for this interface
Expand All @@ -499,7 +553,7 @@ void HardwareSerial::begin(unsigned long baud, byte config, byte mode) {
if (_uart) {
os_free(_uart);
}
_uart = uart_start_init(_uart_nr, baud, config, mode);
_uart = uart_start_init(_uart_nr, baud, config, mode, use_tx);

if(_uart == 0) {
return;
Expand Down Expand Up @@ -538,10 +592,22 @@ void HardwareSerial::end() {
_tx_buffer = 0;
}

void HardwareSerial::swap() {
void HardwareSerial::swap(uint8_t use_tx) {
if(_uart == 0)
return;
uart_swap(_uart, use_tx);
}

void HardwareSerial::set_tx(uint8_t use_tx) {
if(_uart == 0)
return;
uart_set_tx(_uart, use_tx);
}

void HardwareSerial::pins(uint8_t tx, uint8_t rx) {
if(_uart == 0)
return;
uart_swap(_uart);
uart_set_pins(_uart, tx, rx);
}

void HardwareSerial::setDebugOutput(bool en) {
Expand Down
27 changes: 23 additions & 4 deletions cores/esp8266/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,33 @@ class HardwareSerial: public Stream {
HardwareSerial(int uart_nr);

void begin(unsigned long baud) {
begin(baud, SERIAL_8N1, SERIAL_FULL);
begin(baud, SERIAL_8N1, SERIAL_FULL, 1);
}
void begin(unsigned long baud, uint8_t config) {
begin(baud, config, SERIAL_FULL);
begin(baud, config, SERIAL_FULL, 1);
}
void begin(unsigned long, uint8_t, uint8_t);
void begin(unsigned long baud, uint8_t config, uint8_t mode) {
begin(baud, config, mode, 1);
}
void begin(unsigned long, uint8_t, uint8_t, uint8_t);
void end();
void swap(); //toggle between use of GPIO13/GPIO15 or GPIO3/GPIO1 as RX and TX
void swap() {
swap(1);
}
void swap(uint8_t use_tx); //toggle between use of GPIO13/GPIO15 or GPIO3/GPIO(1/2) as RX and TX

/*
* Toggle between use of GPIO1 and GPIO2 as TX on UART 0.
* Note: UART 1 can't be used if GPIO2 is used with UART 0!
*/
void set_tx(uint8_t use_tx);

/*
* UART 0 possible options are (1, 3), (2, 3) or (15, 13)
* UART 1 allows only TX on 2 if UART 0 is not (2, 3)
*/
void pins(uint8_t tx, uint8_t rx);

int available(void) override;
int peek(void) override;
int read(void) override;
Expand Down