mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-03-27 13:35:44 +00:00
button hibernation prodtest
This commit is contained in:
parent
4e840cdd46
commit
caacadc3d0
@ -23,6 +23,29 @@
|
|||||||
|
|
||||||
#include <io/rgb_led.h>
|
#include <io/rgb_led.h>
|
||||||
#include <rtl/cli.h>
|
#include <rtl/cli.h>
|
||||||
|
#include <sys/systimer.h>
|
||||||
|
|
||||||
|
static bool g_prodtest_rgbled_start = false;
|
||||||
|
|
||||||
|
static void prodtest_rgbled_timer_cb(void* context) {
|
||||||
|
if (g_prodtest_rgbled_start) {
|
||||||
|
rgb_led_set_color(0);
|
||||||
|
g_prodtest_rgbled_start = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prodtest_rgbled_init(void) {
|
||||||
|
static systimer_t* timer = NULL;
|
||||||
|
|
||||||
|
timer = systimer_create(prodtest_rgbled_timer_cb, NULL);
|
||||||
|
|
||||||
|
if (timer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
systimer_set(timer, 1000);
|
||||||
|
rgb_led_set_color(0xFF00);
|
||||||
|
g_prodtest_rgbled_start = true;
|
||||||
|
}
|
||||||
|
|
||||||
static void prodtest_rgbled_set(cli_t* cli) {
|
static void prodtest_rgbled_set(cli_t* cli) {
|
||||||
uint32_t r = 0;
|
uint32_t r = 0;
|
||||||
@ -53,6 +76,7 @@ static void prodtest_rgbled_set(cli_t* cli) {
|
|||||||
|
|
||||||
uint32_t rgb = (r << 16) | (g << 8) | b;
|
uint32_t rgb = (r << 16) | (g << 8) | b;
|
||||||
|
|
||||||
|
g_prodtest_rgbled_start = false;
|
||||||
rgb_led_set_color(rgb);
|
rgb_led_set_color(rgb);
|
||||||
|
|
||||||
cli_ok(cli, "");
|
cli_ok(cli, "");
|
||||||
|
24
core/embed/projects/prodtest/cmd/prodtest_rgbled.h
Normal file
24
core/embed/projects/prodtest/cmd/prodtest_rgbled.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Trezor project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (c) SatoshiLabs
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <trezor_types.h>
|
||||||
|
|
||||||
|
void prodtest_rgbled_init(void);
|
@ -24,6 +24,7 @@
|
|||||||
#include <io/usb.h>
|
#include <io/usb.h>
|
||||||
#include <rtl/cli.h>
|
#include <rtl/cli.h>
|
||||||
#include <sys/system.h>
|
#include <sys/system.h>
|
||||||
|
#include <sys/systick.h>
|
||||||
#include <util/flash_otp.h>
|
#include <util/flash_otp.h>
|
||||||
#include <util/rsod.h>
|
#include <util/rsod.h>
|
||||||
#include <util/unit_properties.h>
|
#include <util/unit_properties.h>
|
||||||
@ -66,6 +67,7 @@
|
|||||||
|
|
||||||
#ifdef USE_RGB_LED
|
#ifdef USE_RGB_LED
|
||||||
#include <io/rgb_led.h>
|
#include <io/rgb_led.h>
|
||||||
|
#include "cmd/prodtest_rgbled.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_HASH_PROCESSOR
|
#ifdef USE_HASH_PROCESSOR
|
||||||
@ -105,6 +107,10 @@ cli_t g_cli = {0};
|
|||||||
|
|
||||||
#define VCP_IFACE 0
|
#define VCP_IFACE 0
|
||||||
|
|
||||||
|
static bool console_can_read(void *context) {
|
||||||
|
return usb_vcp_can_read(VCP_IFACE);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t console_read(void *context, char *buf, size_t size) {
|
static size_t console_read(void *context, char *buf, size_t size) {
|
||||||
return usb_vcp_read_blocking(VCP_IFACE, (uint8_t *)buf, size, -1);
|
return usb_vcp_read_blocking(VCP_IFACE, (uint8_t *)buf, size, -1);
|
||||||
}
|
}
|
||||||
@ -208,6 +214,7 @@ static void drivers_init(void) {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_RGB_LED
|
#ifdef USE_RGB_LED
|
||||||
rgb_led_init();
|
rgb_led_init();
|
||||||
|
prodtest_rgbled_init();
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_BLE
|
#ifdef USE_BLE
|
||||||
unit_properties_init();
|
unit_properties_init();
|
||||||
@ -232,7 +239,7 @@ int main(void) {
|
|||||||
show_welcome_screen();
|
show_welcome_screen();
|
||||||
|
|
||||||
// Initialize command line interface
|
// Initialize command line interface
|
||||||
cli_init(&g_cli, console_read, console_write, NULL);
|
cli_init(&g_cli, console_can_read, console_read, console_write, NULL);
|
||||||
|
|
||||||
extern cli_command_t _prodtest_cli_cmd_section_start;
|
extern cli_command_t _prodtest_cli_cmd_section_start;
|
||||||
extern cli_command_t _prodtest_cli_cmd_section_end;
|
extern cli_command_t _prodtest_cli_cmd_section_end;
|
||||||
@ -247,7 +254,35 @@ int main(void) {
|
|||||||
pair_optiga(&g_cli);
|
pair_optiga(&g_cli);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cli_run_loop(&g_cli);
|
while (true) {
|
||||||
|
cli_run_loop(&g_cli);
|
||||||
|
|
||||||
|
button_event_t btn_event = {0};
|
||||||
|
|
||||||
|
bool btn = button_get_event(&btn_event);
|
||||||
|
|
||||||
|
if (btn) {
|
||||||
|
bool hibernate = true;
|
||||||
|
uint32_t deadline = ticks_timeout(1000);
|
||||||
|
while (!ticks_expired(deadline)) {
|
||||||
|
button_get_event(&btn_event);
|
||||||
|
if (!button_is_down(BTN_POWER)) {
|
||||||
|
hibernate = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hibernate) {
|
||||||
|
// todo only
|
||||||
|
rgb_led_set_color(0xff0000);
|
||||||
|
systick_delay_ms(1000);
|
||||||
|
powerctl_hibernate();
|
||||||
|
rgb_led_set_color(0xffff00);
|
||||||
|
systick_delay_ms(1000);
|
||||||
|
rgb_led_set_color(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
#define ESC_COLOR_GRAY "\e[37m"
|
#define ESC_COLOR_GRAY "\e[37m"
|
||||||
#define ESC_COLOR_RESET "\e[39m"
|
#define ESC_COLOR_RESET "\e[39m"
|
||||||
|
|
||||||
bool cli_init(cli_t* cli, cli_read_cb_t read, cli_write_cb_t write,
|
bool cli_init(cli_t* cli, cli_can_read_cb_t can_read, cli_read_cb_t read,
|
||||||
void* callback_context) {
|
cli_write_cb_t write, void* callback_context) {
|
||||||
memset(cli, 0, sizeof(cli_t));
|
memset(cli, 0, sizeof(cli_t));
|
||||||
|
cli->can_read = can_read;
|
||||||
cli->read = read;
|
cli->read = read;
|
||||||
cli->write = write;
|
cli->write = write;
|
||||||
cli->callback_context = callback_context;
|
cli->callback_context = callback_context;
|
||||||
@ -527,77 +528,79 @@ static bool cli_split_args(cli_t* cli) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cli_run_loop(cli_t* cli) {
|
void cli_run_loop(cli_t* cli) {
|
||||||
while (true) {
|
if (!cli->can_read(cli->callback_context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cli->interactive) {
|
||||||
|
if (cli->final_status) {
|
||||||
|
// Finalize the last command with an empty line
|
||||||
|
cli_printf(cli, "\r\n");
|
||||||
|
}
|
||||||
|
// Print the prompt
|
||||||
|
cli_printf(cli, "> ");
|
||||||
|
}
|
||||||
|
|
||||||
|
cli->final_status = false;
|
||||||
|
cli->aborted = false;
|
||||||
|
|
||||||
|
// Read the next line
|
||||||
|
if (!cli_readln(cli)) {
|
||||||
|
cli_error(cli, CLI_ERROR_FATAL, "Input line too long.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_history_add(cli, cli->line_buffer);
|
||||||
|
|
||||||
|
// Split command line into arguments
|
||||||
|
if (!cli_split_args(cli)) {
|
||||||
|
cli_error(cli, CLI_ERROR_FATAL, "Too many arguments.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty line?
|
||||||
|
if (*cli->cmd_name == '\0') {
|
||||||
|
// Switch to interactive mode if two empty lines are entered
|
||||||
|
if (++cli->empty_lines >= 2 && !cli->interactive) {
|
||||||
|
cli->interactive = true;
|
||||||
|
// Print the welcome message
|
||||||
|
const cli_command_t* cmd = cli_find_command(cli, "$intro");
|
||||||
|
if (cmd != NULL) {
|
||||||
|
cmd->func(cli);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cli->empty_lines = 0;
|
||||||
|
|
||||||
|
// Quit interactive mode on `.+ENTER`
|
||||||
|
if ((strcmp(cli->cmd_name, ".") == 0)) {
|
||||||
if (cli->interactive) {
|
if (cli->interactive) {
|
||||||
if (cli->final_status) {
|
cli->interactive = false;
|
||||||
// Finalize the last command with an empty line
|
cli_trace(cli, "Exiting interactive mode...");
|
||||||
cli_printf(cli, "\r\n");
|
|
||||||
}
|
|
||||||
// Print the prompt
|
|
||||||
cli_printf(cli, "> ");
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cli->final_status = false;
|
// Find the command handler
|
||||||
cli->aborted = false;
|
cli->current_cmd = cli_find_command(cli, cli->cmd_name);
|
||||||
|
|
||||||
// Read the next line
|
if (cli->current_cmd == NULL) {
|
||||||
if (!cli_readln(cli)) {
|
cli_error(cli, CLI_ERROR_INVALID_CMD, "Invalid command '%s', try 'help'.",
|
||||||
cli_error(cli, CLI_ERROR_FATAL, "Input line too long.");
|
cli->cmd_name);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cli_history_add(cli, cli->line_buffer);
|
// Call the command handler
|
||||||
|
cli->current_cmd->func(cli);
|
||||||
|
|
||||||
// Split command line into arguments
|
if (!cli->final_status) {
|
||||||
if (!cli_split_args(cli)) {
|
// Command handler hasn't send final status
|
||||||
cli_error(cli, CLI_ERROR_FATAL, "Too many arguments.");
|
if (cli->aborted) {
|
||||||
continue;
|
cli_error(cli, CLI_ERROR_ABORT, "");
|
||||||
}
|
} else {
|
||||||
|
cli_error(cli, CLI_ERROR_FATAL,
|
||||||
// Empty line?
|
"Command handler didn't finish properly.");
|
||||||
if (*cli->cmd_name == '\0') {
|
|
||||||
// Switch to interactive mode if two empty lines are entered
|
|
||||||
if (++cli->empty_lines >= 2 && !cli->interactive) {
|
|
||||||
cli->interactive = true;
|
|
||||||
// Print the welcome message
|
|
||||||
const cli_command_t* cmd = cli_find_command(cli, "$intro");
|
|
||||||
if (cmd != NULL) {
|
|
||||||
cmd->func(cli);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cli->empty_lines = 0;
|
|
||||||
|
|
||||||
// Quit interactive mode on `.+ENTER`
|
|
||||||
if ((strcmp(cli->cmd_name, ".") == 0)) {
|
|
||||||
if (cli->interactive) {
|
|
||||||
cli->interactive = false;
|
|
||||||
cli_trace(cli, "Exiting interactive mode...");
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the command handler
|
|
||||||
cli->current_cmd = cli_find_command(cli, cli->cmd_name);
|
|
||||||
|
|
||||||
if (cli->current_cmd == NULL) {
|
|
||||||
cli_error(cli, CLI_ERROR_INVALID_CMD, "Invalid command '%s', try 'help'.",
|
|
||||||
cli->cmd_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the command handler
|
|
||||||
cli->current_cmd->func(cli);
|
|
||||||
|
|
||||||
if (!cli->final_status) {
|
|
||||||
// Command handler hasn't send final status
|
|
||||||
if (cli->aborted) {
|
|
||||||
cli_error(cli, CLI_ERROR_ABORT, "");
|
|
||||||
} else {
|
|
||||||
cli_error(cli, CLI_ERROR_FATAL,
|
|
||||||
"Command handler didn't finish properly.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,9 +77,12 @@ typedef struct {
|
|||||||
typedef size_t (*cli_write_cb_t)(void* ctx, const char* buf, size_t len);
|
typedef size_t (*cli_write_cb_t)(void* ctx, const char* buf, size_t len);
|
||||||
// Callback for reading characters from console input
|
// Callback for reading characters from console input
|
||||||
typedef size_t (*cli_read_cb_t)(void* ctx, char* buf, size_t len);
|
typedef size_t (*cli_read_cb_t)(void* ctx, char* buf, size_t len);
|
||||||
|
// Callback for can read assessment
|
||||||
|
typedef bool (*cli_can_read_cb_t)(void* ctx);
|
||||||
|
|
||||||
struct cli {
|
struct cli {
|
||||||
// I/O callbacks
|
// I/O callbacks
|
||||||
|
cli_can_read_cb_t can_read;
|
||||||
cli_read_cb_t read;
|
cli_read_cb_t read;
|
||||||
cli_write_cb_t write;
|
cli_write_cb_t write;
|
||||||
void* callback_context;
|
void* callback_context;
|
||||||
@ -116,8 +119,8 @@ struct cli {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Initializes the command line structure
|
// Initializes the command line structure
|
||||||
bool cli_init(cli_t* cli, cli_read_cb_t read, cli_write_cb_t write,
|
bool cli_init(cli_t* cli, cli_can_read_cb_t can_read, cli_read_cb_t read,
|
||||||
void* callback_context);
|
cli_write_cb_t write, void* callback_context);
|
||||||
|
|
||||||
// Registers the command handlers
|
// Registers the command handlers
|
||||||
void cli_set_commands(cli_t* cli, const cli_command_t* cmd_array,
|
void cli_set_commands(cli_t* cli, const cli_command_t* cmd_array,
|
||||||
|
Loading…
Reference in New Issue
Block a user