From 83b5c1676648f67ffe50f15a0f08b4e6c37ffc17 Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 24 Apr 2025 10:58:43 +0200 Subject: [PATCH] feat(nordic): turn of uart by default, enable turning it on/off on command [no changelog] --- .../trezor-ble/src/management/management.c | 10 +++ .../trezor/trezor-ble/src/prodtest/prodtest.c | 2 +- .../src/trz_comm/inc/trz_comm/trz_comm.h | 3 + .../trezor/trezor-ble/src/trz_comm/trz_comm.c | 6 +- .../src/trz_comm/trz_comm_internal.h | 4 + nordic/trezor/trezor-ble/src/trz_comm/uart.c | 77 ++++++++++++++----- 6 files changed, 82 insertions(+), 20 deletions(-) diff --git a/nordic/trezor/trezor-ble/src/management/management.c b/nordic/trezor/trezor-ble/src/management/management.c index 7656a5a747..d53c369a6e 100644 --- a/nordic/trezor/trezor-ble/src/management/management.c +++ b/nordic/trezor/trezor-ble/src/management/management.c @@ -39,6 +39,8 @@ static K_SEM_DEFINE(management_ok, 0, 1); typedef enum { MGMT_CMD_SYSTEM_OFF = 0x00, MGMT_CMD_INFO = 0x01, + MGMT_CMD_START_UART = 0x02, + MGMT_CMD_STOP_UART = 0x03, } management_cmd_t; typedef enum { @@ -74,6 +76,14 @@ static void process_command(uint8_t *data, uint16_t len) { LOG_INF("Info command"); send_info(); break; + case MGMT_CMD_START_UART: + LOG_INF("Start UART"); + trz_comm_start_uart(); + break; + case MGMT_CMD_STOP_UART: + LOG_INF("Stop UART"); + trz_comm_stop_uart(); + break; default: break; } diff --git a/nordic/trezor/trezor-ble/src/prodtest/prodtest.c b/nordic/trezor/trezor-ble/src/prodtest/prodtest.c index 26f8666da8..77fd2d56bd 100644 --- a/nordic/trezor/trezor-ble/src/prodtest/prodtest.c +++ b/nordic/trezor/trezor-ble/src/prodtest/prodtest.c @@ -59,7 +59,7 @@ static void process_command(uint8_t *data, uint16_t len) { trz_comm_send_msg(NRF_SERVICE_PRODTEST, resp_data, 64); break; case PRODTEST_CMD_SET_OUTPUT: - signals_reserved(data[1]); + signals_wakeup(data[1]); break; default: break; diff --git a/nordic/trezor/trezor-ble/src/trz_comm/inc/trz_comm/trz_comm.h b/nordic/trezor/trezor-ble/src/trz_comm/inc/trz_comm/trz_comm.h index 6a6a54a204..a00168356f 100644 --- a/nordic/trezor/trezor-ble/src/trz_comm/inc/trz_comm/trz_comm.h +++ b/nordic/trezor/trezor-ble/src/trz_comm/inc/trz_comm/trz_comm.h @@ -49,3 +49,6 @@ bool trz_comm_send_msg(nrf_service_id_t service, const uint8_t *data, // Polls for incoming data from the specified service trz_packet_t *trz_comm_poll_data(nrf_service_id_t service); + +void trz_comm_start_uart(void); +void trz_comm_stop_uart(void); diff --git a/nordic/trezor/trezor-ble/src/trz_comm/trz_comm.c b/nordic/trezor/trezor-ble/src/trz_comm/trz_comm.c index 4db804f80d..ac972f095c 100644 --- a/nordic/trezor/trezor-ble/src/trz_comm/trz_comm.c +++ b/nordic/trezor/trezor-ble/src/trz_comm/trz_comm.c @@ -39,7 +39,7 @@ static K_FIFO_DEFINE(fifo_uart_rx_prodtest); void trz_comm_init(void) { spi_init(); - uart_init(); + uart_power_down(); } bool trz_comm_send_msg(nrf_service_id_t service, const uint8_t *data, @@ -96,3 +96,7 @@ trz_packet_t *trz_comm_poll_data(nrf_service_id_t service) { return NULL; } } + +void trz_comm_start_uart(void) { uart_init(); } + +void trz_comm_stop_uart(void) { uart_deinit(); } diff --git a/nordic/trezor/trezor-ble/src/trz_comm/trz_comm_internal.h b/nordic/trezor/trezor-ble/src/trz_comm/trz_comm_internal.h index d5af4856c9..04b1593ed2 100644 --- a/nordic/trezor/trezor-ble/src/trz_comm/trz_comm_internal.h +++ b/nordic/trezor/trezor-ble/src/trz_comm/trz_comm_internal.h @@ -30,6 +30,10 @@ void spi_init(void); int uart_init(void); +void uart_deinit(void); + +void uart_power_down(void); + bool spi_send(uint8_t service_id, const uint8_t *data, uint32_t len); bool uart_send(uint8_t service_id, const uint8_t *tx_data, uint8_t len); diff --git a/nordic/trezor/trezor-ble/src/trz_comm/uart.c b/nordic/trezor/trezor-ble/src/trz_comm/uart.c index 1408a04af2..bc572d02c7 100644 --- a/nordic/trezor/trezor-ble/src/trz_comm/uart.c +++ b/nordic/trezor/trezor-ble/src/trz_comm/uart.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -101,6 +102,17 @@ static void uart_cb(const struct device *dev, struct uart_event *evt, buf = CONTAINER_OF(evt->data.rx.buf, trz_packet_t, data[0]); buf->len += evt->data.rx.len; rx_data = buf->data[0]; + + trz_packet_t *tx = k_malloc(sizeof(*tx)); + + if (tx == NULL) { + LOG_WRN("Not able to allocate UART send data buffer"); + return; + } + tx->len = 1; + tx->data[0] = rx_data; + + uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS); break; case UART_RX_DISABLED: @@ -110,14 +122,17 @@ static void uart_cb(const struct device *dev, struct uart_event *evt, LOG_DBG("UART_RX_MALLOC"); buf = k_malloc(sizeof(*buf)); - if (buf) { - uart_rx_enable(uart, buf->data, 1, SYS_FOREVER_US); + if (g_uart_rx_running) { + if (buf) { + uart_rx_enable(uart, buf->data, 1, SYS_FOREVER_US); + } else { + LOG_WRN("Not able to allocate UART receive buffer"); + k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY); + g_uart_rx_running = false; + } } else { - LOG_WRN("Not able to allocate UART receive buffer"); - k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY); - g_uart_rx_running = false; + uart_power_down(); } - break; case UART_RX_BUF_RELEASED: @@ -125,18 +140,6 @@ static void uart_cb(const struct device *dev, struct uart_event *evt, buf = CONTAINER_OF(evt->data.rx_buf.buf, trz_packet_t, data[0]); k_free(buf); - trz_packet_t *tx = k_malloc(sizeof(*tx)); - - if (tx == NULL) { - LOG_WRN("Not able to allocate UART send data buffer"); - return; - } - - tx->len = 1; - tx->data[0] = rx_data; - - uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS); - break; case UART_RX_STOPPED: LOG_DBG("UART_RX_STOPPED"); @@ -189,6 +192,10 @@ int uart_start_rx(void) { static void uart_work_handler(struct k_work *item) { trz_packet_t *buf; + if (!g_uart_rx_running) { + uart_power_down(); + return; + } buf = k_malloc(sizeof(*buf)); if (buf) { buf->len = 0; @@ -204,6 +211,8 @@ static void uart_work_handler(struct k_work *item) { int uart_init(void) { int err; + pm_device_action_run(uart, PM_DEVICE_ACTION_RESUME); + if (!device_is_ready(uart)) { return -ENODEV; } @@ -230,6 +239,26 @@ int uart_init(void) { return uart_start_rx(); } +void uart_deinit(void) { + int err; + + if (!g_uart_rx_running) { + return; + } + + g_uart_rx_running = false; + + err = uart_rx_disable(uart); + if (err) { + LOG_ERR("Cannot disable UART RX (err: %d)", err); + } + + err = uart_tx_abort(uart); + if (err) { + LOG_ERR("Cannot abort UART TX (err: %d)", err); + } +} + bool uart_send(uint8_t service_id, const uint8_t *tx_data, uint8_t len) { trz_packet_t *tx = k_malloc(sizeof(*tx)); @@ -256,3 +285,15 @@ bool uart_send(uint8_t service_id, const uint8_t *tx_data, uint8_t len) { } return true; } + +void uart_power_down(void) { + int err; + + uart_callback_set(uart, NULL, NULL); + + /* Power down the UART device */ + err = pm_device_action_run(uart, PM_DEVICE_ACTION_SUSPEND); + if (err) { + printk("pm_device_action_run() failed (%d)\n", err); + } +}