Page 1 of 1

using console uart for 'pass-through'

Posted: Tue Jun 18, 2019 7:23 pm
by genedyne
I have a PC serial port connected to an ESP32 GPIO_1&3, mapped to UART0, which is used for console, bootloading, etc.
My ESP32 UART2 is mapped to GPIO16&17, and is connected to a serial device.
Under certain conditions, I need to be able to 'switch' the console uart into 'pass-through' mode, for direct communication between the PC & the serial device. For instanced GPIO_3->GPIO_17 & GPIO_16->GPIO_1.
Since UART0 is already configured for console use, & I'd like to preserve this, I thought I might be able to make use of the IO_MUX to simply re-direct the pads for GPIO1&3 to UART1, and configure it for RX & TX when in 'pass-through' mode. When I wanted to restore normal 'console' operation, I should just be able to reconfigure the IO_MUX to select the UART0 functions. This didn't work.
The most stable configuration I've found so far to be able to 'switch' between UART0 & UART1 on GPIO_1&3 is to fully deleted the current UART driver, then enable the UART required for the new mode:

Code: Select all

#define U0_IO_TX	1
#define U0_IO_RX	3

/* Toggle UART passthrough
---------------------------------------------------------------------------*/
static void togglePassThrough( void )
{

    if (passThroughEnabled) {
	// currently in Pass-Through mode - reset to normal handling
    	uart_driver_delete( UART_NUM_1 );		// This DISABLES the peripheral
	passThroughEnabled = false;
	vTaskDelay( pdMS_TO_TICKS( 5 ) );

	// setup IO to map UART0 to GPIO1&3
	uart_param_config(UART_NUM_0, &u0_config);		// This ENABLES the peripheral
	uart_set_pin(UART_NUM_0, U0_IO_TX, U0_IO_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	//Install UART driver, and get the queue.
	uart_driver_install(UART_NUM_0, BUF_SIZE_RX*2, 0, 20, &qU0, 0);
	ESP_LOGI(TAG, "Toggle Pass-Through: ON->OFF" );
   } else {
	ESP_LOGI(TAG, "Toggle Pass-Through: OFF->ON" );
	vTaskDelay( pdMS_TO_TICKS( 5 ) );
    	uart_driver_delete( UART_NUM_0 );		// This DISABLES the peripheral

	// setup IO to map UART1 to GPIO1&3
	uart_param_config(UART_NUM_1, &u1_config);		// This ENABLES the peripheral
	uart_set_pin(UART_NUM_1, U0_IO_TX, U0_IO_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	uart_driver_install(UART_NUM_1, BUF_SIZE_RX*2, 0, 20, &qU1, 0);
	passThroughEnabled = true;
   }
}
My ISR looks like:

Code: Select all

    if(xQueueReceive(qUart, (void * )&event, (portTickType)portMAX_DELAY)) {
        switch(event.type) {
            //Event of UART receiving data
            /*We'd better handle data event fast, there would be much more data events than
            other types of events. If we take too much time on data event, the queue might
            be full.*/
            case UART_DATA:
                uart_read_bytes(uart, dtmp, event.size, portMAX_DELAY);
                if (passThroughEnabled) {
                    if (uart == UART_NUM_1)
                    	uart_write_bytes(UART_NUM_2, (const char*) dtmp, event.size);
                    if (uart == UART_NUM_2)
                    	uart_write_bytes(UART_NUM_1, (const char*) dtmp, event.size);
                } else {
                    buildMsg( &(msgBuff[uart]), dtmp, event.size );
                }
...
The above code allows me to toggle between 'pass-through' mode & normal console mode, but for some reason, I never see any data received by UART0 when in 'console' mode. When in 'pass-through' mode, data from the PC is sent through to the serial device on UART2.

Does anyone have suggestions for why I don't see any data received by UART0 when in console mode?