nRF52840 dynamic pin configuration for same UART instance(UART1) but not work.

We are working with nRF52840 and NCS2.6.1. And we want to change pin configuration for UART1 instance during the runtime and we have also used following ASYNC UART configuration and code to implement above function. But we always get repeatable sequence of UART_RX_DISABLED and UART_RX_STOPPED event. Could you give us good suggestions for above problem? Thank you very much.

CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
 

void uart1_alt_pinout_update(void)
{
	int err = 0;

	// Power on UART module
	err = pm_device_action_run(test_uart, PM_DEVICE_ACTION_SUSPEND);
	if (err) {
		LOG_ERR("pm_device_action_run(alt: SUSPEND) error %d.\n", err);
		return; // return error???
	}

	// Update states with a new set
	err = pinctrl_update_states(uart1_config, uart1_alt, ARRAY_SIZE(uart1_alt));
	if (err) {
		LOG_ERR("pinctrl_update_states(alt) error %d.\n", err);
		return; // return error???
	}

	/* Re-enable the UART with the new pinout */
	err = pm_device_action_run(test_uart, PM_DEVICE_ACTION_RESUME);
	if (err) {
		LOG_ERR("pm_device_action_run(alt: RESUME) error %d.\n", err);
		return;
	}

	uart_rx_enable(test_uart, uart_test_rx_buf, UART1_RX_BUF_SIZE, 0);
}

static void uart1_callback_handle(const struct device *dev, struct uart_event *evt, void *user_data)
{
	int err;
	enum pm_device_state state;
	switch (evt->type) {

	case UART_TX_DONE:
		// do something
		// LOG_DBG("UART_TX_DONE");
		break;

	case UART_TX_ABORTED:
		// do something
		// LOG_DBG("UART_TX_ABORTED");
		break;

	case UART_RX_RDY:
		// do something
		// LOG_DBG("UART_RX_RDY");
		if (evt->data.rx.len) {
			// printf("uart1 rx length = %d, char = %c\r\n", evt->data.rx.len,
			// evt->data.rx.buf[0]);
			uart1_rx_done = 1;
			uart1_temp_rx_data = evt->data.rx.buf[0];
		}
		break;

	case UART_RX_BUF_REQUEST:
		// do something
		// LOG_DBG("UART_RX_BUF_REQUEST");
		int err = uart_rx_buf_rsp(test_uart, uart1_buf_next, UART1_RX_BUF_SIZE);
		if (err) {
			LOG_ERR("uart1 rx buf response error: %d.", err);
		}
		break;

	case UART_RX_BUF_RELEASED:
		// do something
		// LOG_DBG("UART_RX_BUF_RELEASED");
		uart1_buf_next = evt->data.rx_buf.buf;
		break;

	case UART_RX_DISABLED:
		// do something
		LOG_DBG("UART_RX_DISABLED");
		err = uart_rx_enable(nrf_uart, &uart_rx_buf[0], UART_RX_BUF_SIZE, 100);
		if (err) {
			LOG_ERR("Error(DISABLED): uart1 enable rx fail %d.", err);
			return 1;
		}
		break;

	case UART_RX_STOPPED:
		// do something
		LOG_INF("UART_RX_STOPPED");
		LOG_INF("UART RX stopped (reason: %d)", evt->data.rx_stop.reason);

		uart_callback_set(test_uart, uart1_callback_handle, NULL);
		err = uart_rx_enable(nrf_uart, &uart_rx_buf[0], UART_RX_BUF_SIZE, 100);
		if (err) {
			LOG_ERR("Error(STOPPED): uart1 enable rx fail %d.", err);
			return 1;
		}
		break;

	default:
		break;
	}
}

Related