Here are some fragments from my code (which does not do anything useful yet, but does communicate with the ESP-32 to send its first command). I hope it is helpful.
Header file lilygo_tpicoc3.h
// Link to the ESPC3-C3 processor on the same board
#define TPICOC3_ESP32C3_UART 1
#define TPICOC3_ESP32C3_TX_PIN 8
#define TPICOC3_ESP32C3_RX_PIN 9
#define TPICOC3_ESP32C3_CTS_PIN 10
#define TPICOC3_ESP32C3_RTS_PIN 11
Set up RP2040 UART to communicate
uart = uart_get_instance(TPICOC3_ESP32C3_UART);
// The ESP32-C3 hardware can run its UARTs at up to 5 Mbaud
uart_init(uart, 115200); // Default for ESP-AT's hardware reset (?)
gpio_set_function(TPICOC3_ESP32C3_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(TPICOC3_ESP32C3_RX_PIN, GPIO_FUNC_UART);
gpio_set_function(TPICOC3_ESP32C3_CTS_PIN, GPIO_FUNC_UART);
gpio_set_function(TPICOC3_ESP32C3_RTS_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(uart, true, true); // Use CTS and RTS
uart_set_format(uart,8,1,UART_PARITY_NONE);
From the communication code. Must wait a short time (120 ms for the screen to wake up is enough for the ESP-32 as well).
// Send command: starts with AT and must end with \r\n
uart_puts(uart, "AT\r\n"); // Most commands are AT+...\r\n
Multi-line reply, ends with a full line OK\r\n or ERROR\r\n