1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-05-19 23:38:46 +00:00

feat(nordic): turn of uart by default, enable turning it on/off on command

[no changelog]
This commit is contained in:
tychovrahe 2025-04-24 10:58:43 +02:00 committed by TychoVrahe
parent 700f432df7
commit 83b5c16766
6 changed files with 82 additions and 20 deletions

View File

@ -39,6 +39,8 @@ static K_SEM_DEFINE(management_ok, 0, 1);
typedef enum { typedef enum {
MGMT_CMD_SYSTEM_OFF = 0x00, MGMT_CMD_SYSTEM_OFF = 0x00,
MGMT_CMD_INFO = 0x01, MGMT_CMD_INFO = 0x01,
MGMT_CMD_START_UART = 0x02,
MGMT_CMD_STOP_UART = 0x03,
} management_cmd_t; } management_cmd_t;
typedef enum { typedef enum {
@ -74,6 +76,14 @@ static void process_command(uint8_t *data, uint16_t len) {
LOG_INF("Info command"); LOG_INF("Info command");
send_info(); send_info();
break; 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: default:
break; break;
} }

View File

@ -59,7 +59,7 @@ static void process_command(uint8_t *data, uint16_t len) {
trz_comm_send_msg(NRF_SERVICE_PRODTEST, resp_data, 64); trz_comm_send_msg(NRF_SERVICE_PRODTEST, resp_data, 64);
break; break;
case PRODTEST_CMD_SET_OUTPUT: case PRODTEST_CMD_SET_OUTPUT:
signals_reserved(data[1]); signals_wakeup(data[1]);
break; break;
default: default:
break; break;

View File

@ -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 // Polls for incoming data from the specified service
trz_packet_t *trz_comm_poll_data(nrf_service_id_t 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);

View File

@ -39,7 +39,7 @@ static K_FIFO_DEFINE(fifo_uart_rx_prodtest);
void trz_comm_init(void) { void trz_comm_init(void) {
spi_init(); spi_init();
uart_init(); uart_power_down();
} }
bool trz_comm_send_msg(nrf_service_id_t service, const uint8_t *data, 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; return NULL;
} }
} }
void trz_comm_start_uart(void) { uart_init(); }
void trz_comm_stop_uart(void) { uart_deinit(); }

View File

@ -30,6 +30,10 @@ void spi_init(void);
int uart_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 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); bool uart_send(uint8_t service_id, const uint8_t *tx_data, uint8_t len);

View File

@ -22,6 +22,7 @@
#include <zephyr/drivers/uart.h> #include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <zephyr/pm/device.h>
#include <zephyr/settings/settings.h> #include <zephyr/settings/settings.h>
#include <zephyr/sys/crc.h> #include <zephyr/sys/crc.h>
#include <zephyr/types.h> #include <zephyr/types.h>
@ -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 = CONTAINER_OF(evt->data.rx.buf, trz_packet_t, data[0]);
buf->len += evt->data.rx.len; buf->len += evt->data.rx.len;
rx_data = buf->data[0]; 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; break;
case UART_RX_DISABLED: 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"); LOG_DBG("UART_RX_MALLOC");
buf = k_malloc(sizeof(*buf)); buf = k_malloc(sizeof(*buf));
if (buf) { if (g_uart_rx_running) {
uart_rx_enable(uart, buf->data, 1, SYS_FOREVER_US); 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 { } else {
LOG_WRN("Not able to allocate UART receive buffer"); uart_power_down();
k_work_reschedule(&uart_work, UART_WAIT_FOR_BUF_DELAY);
g_uart_rx_running = false;
} }
break; break;
case UART_RX_BUF_RELEASED: 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]); buf = CONTAINER_OF(evt->data.rx_buf.buf, trz_packet_t, data[0]);
k_free(buf); 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; break;
case UART_RX_STOPPED: case UART_RX_STOPPED:
LOG_DBG("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) { static void uart_work_handler(struct k_work *item) {
trz_packet_t *buf; trz_packet_t *buf;
if (!g_uart_rx_running) {
uart_power_down();
return;
}
buf = k_malloc(sizeof(*buf)); buf = k_malloc(sizeof(*buf));
if (buf) { if (buf) {
buf->len = 0; buf->len = 0;
@ -204,6 +211,8 @@ static void uart_work_handler(struct k_work *item) {
int uart_init(void) { int uart_init(void) {
int err; int err;
pm_device_action_run(uart, PM_DEVICE_ACTION_RESUME);
if (!device_is_ready(uart)) { if (!device_is_ready(uart)) {
return -ENODEV; return -ENODEV;
} }
@ -230,6 +239,26 @@ int uart_init(void) {
return uart_start_rx(); 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) { bool uart_send(uint8_t service_id, const uint8_t *tx_data, uint8_t len) {
trz_packet_t *tx = k_malloc(sizeof(*tx)); 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; 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);
}
}