mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-27 06:42:02 +00:00
feat(core/prodtest): implement NRF test functions
[no changelog]
This commit is contained in:
parent
06223b78fe
commit
4221b8514b
@ -109,6 +109,7 @@ SOURCE_PRODTEST = [
|
|||||||
'embed/projects/prodtest/cmd/prodtest_haptic.c',
|
'embed/projects/prodtest/cmd/prodtest_haptic.c',
|
||||||
'embed/projects/prodtest/cmd/prodtest_help.c',
|
'embed/projects/prodtest/cmd/prodtest_help.c',
|
||||||
'embed/projects/prodtest/cmd/prodtest_nfc.c',
|
'embed/projects/prodtest/cmd/prodtest_nfc.c',
|
||||||
|
'embed/projects/prodtest/cmd/prodtest_nrf.c',
|
||||||
'embed/projects/prodtest/cmd/prodtest_optiga.c',
|
'embed/projects/prodtest/cmd/prodtest_optiga.c',
|
||||||
'embed/projects/prodtest/cmd/prodtest_otp_batch.c',
|
'embed/projects/prodtest/cmd/prodtest_otp_batch.c',
|
||||||
'embed/projects/prodtest/cmd/prodtest_otp_variant.c',
|
'embed/projects/prodtest/cmd/prodtest_otp_variant.c',
|
||||||
|
@ -17,12 +17,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TREZORHAL_NRF_CRC8_H
|
#pragma once
|
||||||
#define TREZORHAL_NRF_CRC8_H
|
|
||||||
|
|
||||||
#include <trezor_types.h>
|
#include <trezor_types.h>
|
||||||
|
|
||||||
uint8_t crc8(const uint8_t *src, size_t len, uint8_t polynomial,
|
uint8_t crc8(const uint8_t *src, size_t len, uint8_t polynomial,
|
||||||
uint8_t initial_value, bool reversed);
|
uint8_t initial_value, bool reversed);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TREZORHAL_NRF_H
|
#pragma once
|
||||||
#define TREZORHAL_NRF_H
|
|
||||||
|
|
||||||
#include <trezor_types.h>
|
#include <trezor_types.h>
|
||||||
|
|
||||||
@ -28,6 +27,8 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
NRF_SERVICE_BLE = 0,
|
NRF_SERVICE_BLE = 0,
|
||||||
NRF_SERVICE_BLE_MANAGER = 1,
|
NRF_SERVICE_BLE_MANAGER = 1,
|
||||||
|
NRF_SERVICE_MANAGEMENT = 2,
|
||||||
|
NRF_SERVICE_PRODTEST = 3,
|
||||||
|
|
||||||
NRF_SERVICE_CNT // Number of services
|
NRF_SERVICE_CNT // Number of services
|
||||||
} nrf_service_id_t;
|
} nrf_service_id_t;
|
||||||
@ -39,6 +40,18 @@ typedef enum {
|
|||||||
NRF_STATUS_ABORTED = 3, // Packet was aborted
|
NRF_STATUS_ABORTED = 3, // Packet was aborted
|
||||||
} nrf_status_t;
|
} nrf_status_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t version_major;
|
||||||
|
uint8_t version_minor;
|
||||||
|
uint8_t version_patch;
|
||||||
|
uint8_t version_tweak;
|
||||||
|
|
||||||
|
bool in_trz_ready;
|
||||||
|
bool in_stay_in_bootloader;
|
||||||
|
bool out_nrf_ready;
|
||||||
|
bool out_reserved;
|
||||||
|
} nrf_info_t;
|
||||||
|
|
||||||
typedef void (*nrf_rx_callback_t)(const uint8_t *data, uint32_t len);
|
typedef void (*nrf_rx_callback_t)(const uint8_t *data, uint32_t len);
|
||||||
typedef void (*nrf_tx_callback_t)(nrf_status_t status, void *context);
|
typedef void (*nrf_tx_callback_t)(nrf_status_t status, void *context);
|
||||||
|
|
||||||
@ -74,4 +87,23 @@ int32_t nrf_send_msg(nrf_service_id_t service, const uint8_t *data,
|
|||||||
// the message is being sent, it will be sent. The callback will not be called.
|
// the message is being sent, it will be sent. The callback will not be called.
|
||||||
bool nrf_abort_msg(int32_t id);
|
bool nrf_abort_msg(int32_t id);
|
||||||
|
|
||||||
#endif
|
// Reads version and other info from NRF application.
|
||||||
|
// Blocking function.
|
||||||
|
bool nrf_get_info(nrf_info_t *info);
|
||||||
|
|
||||||
|
// TEST only functions
|
||||||
|
|
||||||
|
// Test SPI communication with NRF
|
||||||
|
bool nrf_test_spi_comm(void);
|
||||||
|
|
||||||
|
// Test UART communication with NRF
|
||||||
|
bool nrf_test_uart_comm(void);
|
||||||
|
|
||||||
|
// Test reboot to bootloader
|
||||||
|
bool nrf_test_reboot_to_bootloader(void);
|
||||||
|
|
||||||
|
bool nrf_test_gpio_trz_ready(void);
|
||||||
|
|
||||||
|
bool nrf_test_gpio_stay_in_bld(void);
|
||||||
|
|
||||||
|
bool nrf_test_gpio_reserved(void);
|
||||||
|
@ -17,11 +17,19 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TREZORHAL_NRF_INTERNAL_H
|
#pragma once
|
||||||
#define TREZORHAL_NRF_INTERNAL_H
|
|
||||||
|
|
||||||
#include <trezor_types.h>
|
#include <trezor_types.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MGMT_CMD_SYSTEM_OFF = 0x00,
|
||||||
|
MGMT_CMD_INFO = 0x01,
|
||||||
|
} management_cmd_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MGMT_RESP_INFO = 0,
|
||||||
|
} management_resp_t;
|
||||||
|
|
||||||
void nrf_dfu_comm_send(const uint8_t *data, uint32_t len);
|
void nrf_dfu_comm_send(const uint8_t *data, uint32_t len);
|
||||||
uint32_t nrf_dfu_comm_receive(uint8_t *data, uint32_t len);
|
uint32_t nrf_dfu_comm_receive(uint8_t *data, uint32_t len);
|
||||||
|
|
||||||
@ -36,4 +44,5 @@ bool nrf_reboot_to_bootloader(void);
|
|||||||
void nrf_signal_running(void);
|
void nrf_signal_running(void);
|
||||||
void nrf_signal_off(void);
|
void nrf_signal_off(void);
|
||||||
|
|
||||||
#endif
|
void nrf_stay_in_bootloader(bool set);
|
||||||
|
bool nrf_in_reserved_gpio(void);
|
||||||
|
@ -83,6 +83,8 @@ typedef struct {
|
|||||||
|
|
||||||
nrf_rx_callback_t service_listeners[NRF_SERVICE_CNT];
|
nrf_rx_callback_t service_listeners[NRF_SERVICE_CNT];
|
||||||
|
|
||||||
|
bool info_valid;
|
||||||
|
nrf_info_t info;
|
||||||
} nrf_driver_t;
|
} nrf_driver_t;
|
||||||
|
|
||||||
static nrf_driver_t g_nrf_driver = {0};
|
static nrf_driver_t g_nrf_driver = {0};
|
||||||
@ -142,6 +144,22 @@ static void nrf_stop(void) {
|
|||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nrf_management_rx_cb(const uint8_t *data, uint32_t len) {
|
||||||
|
nrf_driver_t *drv = &g_nrf_driver;
|
||||||
|
if (!drv->initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (data[0]) {
|
||||||
|
case MGMT_RESP_INFO:
|
||||||
|
drv->info_valid = true;
|
||||||
|
memcpy(&drv->info, &data[1], sizeof(drv->info));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void nrf_init(void) {
|
void nrf_init(void) {
|
||||||
nrf_driver_t *drv = &g_nrf_driver;
|
nrf_driver_t *drv = &g_nrf_driver;
|
||||||
|
|
||||||
@ -307,6 +325,8 @@ void nrf_init(void) {
|
|||||||
drv->tx_request_id = -1;
|
drv->tx_request_id = -1;
|
||||||
drv->initialized = true;
|
drv->initialized = true;
|
||||||
|
|
||||||
|
nrf_register_listener(NRF_SERVICE_MANAGEMENT, nrf_management_rx_cb);
|
||||||
|
|
||||||
nrf_start();
|
nrf_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,11 +714,25 @@ bool nrf_reboot_to_bootloader(void) {
|
|||||||
|
|
||||||
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_SET);
|
||||||
|
|
||||||
systick_delay_ms(1000);
|
systick_delay_ms(100);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nrf_stay_in_bootloader(bool set) {
|
||||||
|
if (set) {
|
||||||
|
HAL_GPIO_WritePin(NRF_OUT_STAY_IN_BLD_PORT, NRF_OUT_STAY_IN_BLD_PIN,
|
||||||
|
GPIO_PIN_SET);
|
||||||
|
} else {
|
||||||
|
HAL_GPIO_WritePin(NRF_OUT_STAY_IN_BLD_PORT, NRF_OUT_STAY_IN_BLD_PIN,
|
||||||
|
GPIO_PIN_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_in_reserved_gpio(void) {
|
||||||
|
return HAL_GPIO_ReadPin(NRF_IN_GPIO0_PORT, NRF_IN_GPIO0_PIN) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool nrf_reboot(void) {
|
bool nrf_reboot(void) {
|
||||||
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_RESET);
|
||||||
HAL_GPIO_WritePin(NRF_OUT_STAY_IN_BLD_PORT, NRF_OUT_STAY_IN_BLD_PIN,
|
HAL_GPIO_WritePin(NRF_OUT_STAY_IN_BLD_PORT, NRF_OUT_STAY_IN_BLD_PIN,
|
||||||
@ -735,6 +769,31 @@ bool nrf_is_running(void) {
|
|||||||
return drv->comm_running;
|
return drv->comm_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nrf_get_info(nrf_info_t *info) {
|
||||||
|
nrf_driver_t *drv = &g_nrf_driver;
|
||||||
|
if (!drv->initialized) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
drv->info_valid = false;
|
||||||
|
|
||||||
|
uint8_t data[1] = {MGMT_CMD_INFO};
|
||||||
|
if (!nrf_send_msg(NRF_SERVICE_MANAGEMENT, data, 1, NULL, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout = ticks_timeout(100);
|
||||||
|
|
||||||
|
while (!ticks_expired(timeout)) {
|
||||||
|
if (drv->info_valid) {
|
||||||
|
memcpy(info, &drv->info, sizeof(nrf_info_t));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void nrf_set_dfu_mode(void) {
|
void nrf_set_dfu_mode(void) {
|
||||||
nrf_driver_t *drv = &g_nrf_driver;
|
nrf_driver_t *drv = &g_nrf_driver;
|
||||||
|
|
||||||
|
249
core/embed/io/nrf/stm32u5/nrf_test.c
Normal file
249
core/embed/io/nrf/stm32u5/nrf_test.c
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/systick.h>
|
||||||
|
#ifdef KERNEL_MODE
|
||||||
|
|
||||||
|
#include <trezor_model.h>
|
||||||
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
|
#include <io/nrf.h>
|
||||||
|
|
||||||
|
#include "../nrf_internal.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PRODTEST_CMD_SPI_DATA = 0x00,
|
||||||
|
PRODTEST_CMD_UART_DATA = 0x01,
|
||||||
|
PRODTEST_CMD_SET_OUTPUT = 0x02,
|
||||||
|
} prodtest_cmd_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PRODTEST_RESP_SPI = 0x00,
|
||||||
|
PRODTEST_RESP_UART = 0x01,
|
||||||
|
} prodtest_resp_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool answered_spi;
|
||||||
|
bool answered_uart;
|
||||||
|
|
||||||
|
} nrf_test_t;
|
||||||
|
|
||||||
|
static nrf_test_t g_nrf_test;
|
||||||
|
|
||||||
|
void nrf_test_cb(const uint8_t *data, uint32_t len) {
|
||||||
|
switch (data[0]) {
|
||||||
|
case PRODTEST_RESP_SPI:
|
||||||
|
g_nrf_test.answered_spi = true;
|
||||||
|
break;
|
||||||
|
case PRODTEST_RESP_UART:
|
||||||
|
g_nrf_test.answered_uart = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_test_spi_comm(void) {
|
||||||
|
nrf_register_listener(NRF_SERVICE_PRODTEST, nrf_test_cb);
|
||||||
|
|
||||||
|
g_nrf_test.answered_spi = false;
|
||||||
|
|
||||||
|
uint8_t data[1] = {PRODTEST_CMD_SPI_DATA};
|
||||||
|
|
||||||
|
if (!nrf_send_msg(NRF_SERVICE_PRODTEST, data, 1, NULL, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout = ticks_timeout(100);
|
||||||
|
|
||||||
|
while (!ticks_expired(timeout)) {
|
||||||
|
if (g_nrf_test.answered_spi) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_test_uart_comm(void) {
|
||||||
|
nrf_register_listener(NRF_SERVICE_PRODTEST, nrf_test_cb);
|
||||||
|
|
||||||
|
g_nrf_test.answered_uart = false;
|
||||||
|
|
||||||
|
uint8_t data[1] = {PRODTEST_CMD_UART_DATA};
|
||||||
|
|
||||||
|
if (!nrf_send_msg(NRF_SERVICE_PRODTEST, data, 1, NULL, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout = ticks_timeout(100);
|
||||||
|
|
||||||
|
while (!ticks_expired(timeout)) {
|
||||||
|
if (g_nrf_test.answered_uart) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_test_reboot_to_bootloader(void) {
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (!nrf_firmware_running()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nrf_reboot_to_bootloader()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t timeout = ticks_timeout(10);
|
||||||
|
|
||||||
|
while (!ticks_expired(timeout)) {
|
||||||
|
if (!nrf_firmware_running()) {
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
systick_delay_ms(10);
|
||||||
|
|
||||||
|
// todo test UART communication with MCUboot
|
||||||
|
|
||||||
|
if (!nrf_reboot()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = ticks_timeout(1000);
|
||||||
|
while (!ticks_expired(timeout)) {
|
||||||
|
if (nrf_firmware_running()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_test_gpio_trz_ready(void) {
|
||||||
|
bool result = false;
|
||||||
|
nrf_signal_running();
|
||||||
|
systick_delay_ms(10);
|
||||||
|
|
||||||
|
nrf_info_t info = {0};
|
||||||
|
if (!nrf_get_info(&info)) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.in_trz_ready) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf_signal_off();
|
||||||
|
systick_delay_ms(10);
|
||||||
|
if (!nrf_get_info(&info)) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.in_trz_ready) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
nrf_signal_running();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_test_gpio_stay_in_bld(void) {
|
||||||
|
bool result = false;
|
||||||
|
nrf_stay_in_bootloader(false);
|
||||||
|
systick_delay_ms(10);
|
||||||
|
|
||||||
|
nrf_info_t info = {0};
|
||||||
|
if (!nrf_get_info(&info)) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.in_stay_in_bootloader) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf_stay_in_bootloader(true);
|
||||||
|
systick_delay_ms(10);
|
||||||
|
if (!nrf_get_info(&info)) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.in_stay_in_bootloader) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
nrf_stay_in_bootloader(false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nrf_test_gpio_reserved(void) {
|
||||||
|
bool result = false;
|
||||||
|
uint8_t data[2] = {PRODTEST_CMD_SET_OUTPUT, 0};
|
||||||
|
if (!nrf_send_msg(NRF_SERVICE_PRODTEST, data, sizeof(data), NULL, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
systick_delay_ms(10);
|
||||||
|
|
||||||
|
if (nrf_in_reserved_gpio()) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
data[1] = 1;
|
||||||
|
if (!nrf_send_msg(NRF_SERVICE_PRODTEST, data, sizeof(data), NULL, NULL)) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
systick_delay_ms(10);
|
||||||
|
|
||||||
|
if (!nrf_in_reserved_gpio()) {
|
||||||
|
result = false;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
data[1] = 0;
|
||||||
|
nrf_send_msg(NRF_SERVICE_PRODTEST, data, sizeof(data), NULL, NULL);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -268,6 +268,30 @@ haptic-test 3000
|
|||||||
OK
|
OK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### nrf-communication
|
||||||
|
Tests the internal communication between the main MCU and NRF MCU. The command returns `OK` if the communication is successful.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
nrf-communication
|
||||||
|
# Testing SPI communication...
|
||||||
|
# Testing UART communication...
|
||||||
|
# Testing reboot to bootloader...
|
||||||
|
# Testing GPIO TRZ ready...
|
||||||
|
# Testing GPIO stay in bootloader...
|
||||||
|
# Testing GPIO reserved...
|
||||||
|
OK
|
||||||
|
```
|
||||||
|
|
||||||
|
### nrf-version
|
||||||
|
Retrieves the version of the NRF52 MCU. The command returns `OK` followed by the version in the format `<major>.<minor>.<patch>.<tweak>`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
nrf-version
|
||||||
|
OK 0.1.2.3
|
||||||
|
```
|
||||||
|
|
||||||
### touch-draw
|
### touch-draw
|
||||||
Starts a drawing canvas, where user can draw with finger on pen. Canvas is exited by sending CTRL+C command.
|
Starts a drawing canvas, where user can draw with finger on pen. Canvas is exited by sending CTRL+C command.
|
||||||
```
|
```
|
||||||
|
94
core/embed/projects/prodtest/cmd/prodtest_nrf.c
Normal file
94
core/embed/projects/prodtest/cmd/prodtest_nrf.c
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef USE_BLE
|
||||||
|
|
||||||
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
|
#include <io/nrf.h>
|
||||||
|
#include <rtl/cli.h>
|
||||||
|
|
||||||
|
static void prodtest_nrf_communication(cli_t* cli) {
|
||||||
|
cli_trace(cli, "Testing SPI communication...");
|
||||||
|
if (!nrf_test_spi_comm()) {
|
||||||
|
cli_error(cli, CLI_ERROR, "SPI communication failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_trace(cli, "Testing UART communication...");
|
||||||
|
if (!nrf_test_uart_comm()) {
|
||||||
|
cli_error(cli, CLI_ERROR, "UART communication failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_trace(cli, "Testing reboot to bootloader...");
|
||||||
|
if (!nrf_test_reboot_to_bootloader()) {
|
||||||
|
cli_error(cli, CLI_ERROR, "Reboot to bootloader failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_trace(cli, "Testing GPIO TRZ ready...");
|
||||||
|
if (!nrf_test_gpio_trz_ready()) {
|
||||||
|
cli_error(cli, CLI_ERROR, "TRZ ready GPIO failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_trace(cli, "Testing GPIO stay in bootloader...");
|
||||||
|
if (!nrf_test_gpio_stay_in_bld()) {
|
||||||
|
cli_error(cli, CLI_ERROR, "Stay in bootloader GPIO failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_trace(cli, "Testing GPIO reserved...");
|
||||||
|
if (!nrf_test_gpio_reserved()) {
|
||||||
|
cli_error(cli, CLI_ERROR, "Reserved GPIO failed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_ok(cli, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prodtest_nrf_version(cli_t* cli) {
|
||||||
|
nrf_info_t info = {0};
|
||||||
|
if (!nrf_get_info(&info)) {
|
||||||
|
cli_error(cli, CLI_ERROR, "Could not read version.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_ok(cli, "%d.%d.%d.%d", info.version_major, info.version_minor,
|
||||||
|
info.version_patch, info.version_tweak);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
PRODTEST_CLI_CMD(
|
||||||
|
.name = "nrf-communication",
|
||||||
|
.func = prodtest_nrf_communication,
|
||||||
|
.info = "Tests NRF communication and GPIOs",
|
||||||
|
.args = ""
|
||||||
|
);
|
||||||
|
|
||||||
|
PRODTEST_CLI_CMD(
|
||||||
|
.name = "nrf-version",
|
||||||
|
.func = prodtest_nrf_version,
|
||||||
|
.info = "Reads NRF firmware version",
|
||||||
|
.args = ""
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
@ -84,6 +84,7 @@ def configure(
|
|||||||
features_available.append("ble")
|
features_available.append("ble")
|
||||||
defines += [("USE_BLE", "1")]
|
defines += [("USE_BLE", "1")]
|
||||||
sources += ["embed/io/nrf/stm32u5/nrf.c"]
|
sources += ["embed/io/nrf/stm32u5/nrf.c"]
|
||||||
|
sources += ["embed/io/nrf/stm32u5/nrf_test.c"]
|
||||||
sources += ["embed/io/nrf/crc8.c"]
|
sources += ["embed/io/nrf/crc8.c"]
|
||||||
paths += ["embed/io/nrf/inc"]
|
paths += ["embed/io/nrf/inc"]
|
||||||
sources += [
|
sources += [
|
||||||
|
@ -28,11 +28,11 @@
|
|||||||
compatible = "gpio-leds";
|
compatible = "gpio-leds";
|
||||||
led0: led_0 {
|
led0: led_0 {
|
||||||
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
|
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
|
||||||
label = "Green LED 0";
|
label = "Reserved output";
|
||||||
};
|
};
|
||||||
led1: led_1 {
|
led1: led_1 {
|
||||||
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
|
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
|
||||||
label = "Green LED 1";
|
label = "NRF ready";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,7 +40,7 @@
|
|||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
button0: button_0 {
|
button0: button_0 {
|
||||||
gpios = <&gpio0 14 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
|
gpios = <&gpio0 14 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
|
||||||
label = "Push button switch 0";
|
label = "Stay in bootloader";
|
||||||
zephyr,code = <INPUT_KEY_0>;
|
zephyr,code = <INPUT_KEY_0>;
|
||||||
};
|
};
|
||||||
trezor_ready: trezor_ready {
|
trezor_ready: trezor_ready {
|
||||||
|
@ -18,7 +18,8 @@ target_sources(app PRIVATE
|
|||||||
src/ble/bonds.c
|
src/ble/bonds.c
|
||||||
src/ble/pairing.c
|
src/ble/pairing.c
|
||||||
src/ble/ble.c
|
src/ble/ble.c
|
||||||
src/power_management/power_management.c
|
src/management/management.c
|
||||||
|
src/prodtest/prodtest.c
|
||||||
src/trz_comm/uart.c
|
src/trz_comm/uart.c
|
||||||
src/trz_comm/spi.c
|
src/trz_comm/spi.c
|
||||||
src/trz_comm/trz_comm.c
|
src/trz_comm/trz_comm.c
|
||||||
@ -28,7 +29,8 @@ target_sources(app PRIVATE
|
|||||||
include_directories(src/signals/inc)
|
include_directories(src/signals/inc)
|
||||||
include_directories(src/trz_comm/inc)
|
include_directories(src/trz_comm/inc)
|
||||||
include_directories(src/ble/inc)
|
include_directories(src/ble/inc)
|
||||||
include_directories(src/power_management/inc)
|
include_directories(src/management/inc)
|
||||||
|
include_directories(src/prodtest/inc)
|
||||||
|
|
||||||
# NORDIC SDK APP END
|
# NORDIC SDK APP END
|
||||||
|
|
||||||
|
@ -54,9 +54,9 @@ void auth_passkey_confirm(struct bt_conn *conn, unsigned int passkey) {
|
|||||||
|
|
||||||
uint8_t passkey_str[6];
|
uint8_t passkey_str[6];
|
||||||
passkey_to_str(passkey_str, passkey);
|
passkey_to_str(passkey_str, passkey);
|
||||||
management_send_pairing_request_event(passkey_str, 6);
|
ble_management_send_pairing_request_event(passkey_str, 6);
|
||||||
|
|
||||||
management_send_status_event();
|
ble_management_send_status_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pairing_auth_cancel(struct bt_conn *conn) {
|
void pairing_auth_cancel(struct bt_conn *conn) {
|
||||||
@ -66,8 +66,8 @@ void pairing_auth_cancel(struct bt_conn *conn) {
|
|||||||
|
|
||||||
connection_disconnect();
|
connection_disconnect();
|
||||||
|
|
||||||
management_send_pairing_cancelled_event();
|
ble_management_send_pairing_cancelled_event();
|
||||||
management_send_status_event();
|
ble_management_send_status_event();
|
||||||
|
|
||||||
LOG_INF("Pairing cancelled: %s", addr);
|
LOG_INF("Pairing cancelled: %s", addr);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@
|
|||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
#include <ble/ble.h>
|
#include <ble/ble.h>
|
||||||
#include <power_management/power_management.h>
|
#include <management/management.h>
|
||||||
|
#include <prodtest/prodtest.h>
|
||||||
#include <signals/signals.h>
|
#include <signals/signals.h>
|
||||||
#include <trz_comm/trz_comm.h>
|
#include <trz_comm/trz_comm.h>
|
||||||
|
|
||||||
@ -55,9 +56,11 @@ int main(void) {
|
|||||||
|
|
||||||
ble_init();
|
ble_init();
|
||||||
|
|
||||||
power_management_init();
|
management_init();
|
||||||
|
|
||||||
signals_fw_running(true);
|
prodtest_init();
|
||||||
|
|
||||||
|
signals_nrf_ready(true);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
k_sleep(K_FOREVER);
|
k_sleep(K_FOREVER);
|
||||||
|
@ -19,5 +19,5 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Initialize the power management module
|
// Initialize the management module
|
||||||
void power_management_init(void);
|
void management_init(void);
|
@ -23,45 +23,72 @@
|
|||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
#include <app_version.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
#include <zephyr/sys/crc.h>
|
#include <zephyr/sys/crc.h>
|
||||||
#include <zephyr/sys/poweroff.h>
|
#include <zephyr/sys/poweroff.h>
|
||||||
|
|
||||||
|
#include <signals/signals.h>
|
||||||
#include <trz_comm/trz_comm.h>
|
#include <trz_comm/trz_comm.h>
|
||||||
|
|
||||||
#define LOG_MODULE_NAME power_manangement
|
#define LOG_MODULE_NAME manangement
|
||||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
static K_SEM_DEFINE(power_management_ok, 0, 1);
|
static K_SEM_DEFINE(management_ok, 0, 1);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PWR_CMD_SYSTEM_OFF = 0x00,
|
MGMT_CMD_SYSTEM_OFF = 0x00,
|
||||||
} power_management_cmd_t;
|
MGMT_CMD_INFO = 0x01,
|
||||||
|
} management_cmd_t;
|
||||||
|
|
||||||
void power_management_init(void) { k_sem_give(&power_management_ok); }
|
typedef enum {
|
||||||
|
MGMT_RESP_INFO = 0,
|
||||||
|
} management_resp_t;
|
||||||
|
|
||||||
|
void management_init(void) { k_sem_give(&management_ok); }
|
||||||
|
|
||||||
|
static void send_info(void) {
|
||||||
|
uint8_t data[9] = {0};
|
||||||
|
|
||||||
|
data[0] = MGMT_RESP_INFO;
|
||||||
|
data[1] = APP_VERSION_MAJOR;
|
||||||
|
data[2] = APP_VERSION_MINOR;
|
||||||
|
data[3] = APP_PATCHLEVEL;
|
||||||
|
data[4] = APP_TWEAK;
|
||||||
|
data[5] = signals_is_trz_ready();
|
||||||
|
data[6] = signals_is_stay_in_bootloader();
|
||||||
|
data[7] = signals_out_get_nrf_ready();
|
||||||
|
data[8] = signals_out_get_reserved();
|
||||||
|
|
||||||
|
trz_comm_send_msg(NRF_SERVICE_MANAGEMENT, data, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
static void process_command(uint8_t *data, uint16_t len) {
|
static void process_command(uint8_t *data, uint16_t len) {
|
||||||
uint8_t cmd = data[0];
|
uint8_t cmd = data[0];
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case PWR_CMD_SYSTEM_OFF:
|
case MGMT_CMD_SYSTEM_OFF:
|
||||||
LOG_INF("System off");
|
LOG_INF("System off");
|
||||||
sys_poweroff();
|
sys_poweroff();
|
||||||
break;
|
break;
|
||||||
|
case MGMT_CMD_INFO:
|
||||||
|
LOG_INF("Info command");
|
||||||
|
send_info();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_management_thread(void) {
|
void management_thread(void) {
|
||||||
/* Don't go any further until BLE is initialized */
|
/* Don't go any further until BLE is initialized */
|
||||||
k_sem_take(&power_management_ok, K_FOREVER);
|
k_sem_take(&management_ok, K_FOREVER);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
trz_packet_t *buf = trz_comm_poll_data(NRF_SERVICE_POWER_MANAGEMENT);
|
trz_packet_t *buf = trz_comm_poll_data(NRF_SERVICE_MANAGEMENT);
|
||||||
process_command(buf->data, buf->len);
|
process_command(buf->data, buf->len);
|
||||||
k_free(buf);
|
k_free(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
K_THREAD_DEFINE(power_management_thread_id, CONFIG_DEFAULT_THREAD_STACK_SIZE,
|
K_THREAD_DEFINE(management_thread_id, CONFIG_DEFAULT_THREAD_STACK_SIZE,
|
||||||
power_management_thread, NULL, NULL, NULL, 7, 0, 0);
|
management_thread, NULL, NULL, NULL, 7, 0, 0);
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
// Initialize the prodtest module
|
||||||
|
void prodtest_init(void);
|
81
nordic/trezor/trezor-ble/src/prodtest/prodtest.c
Normal file
81
nordic/trezor/trezor-ble/src/prodtest/prodtest.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
|
#include <signals/signals.h>
|
||||||
|
#include <trz_comm/trz_comm.h>
|
||||||
|
|
||||||
|
#define LOG_MODULE_NAME prodtest
|
||||||
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
|
static K_SEM_DEFINE(prodtest_ok, 0, 1);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PRODTEST_CMD_SPI_DATA = 0x00,
|
||||||
|
PRODTEST_CMD_UART_DATA = 0x01,
|
||||||
|
PRODTEST_CMD_SET_OUTPUT = 0x02,
|
||||||
|
} prodtest_cmd_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PRODTEST_RESP_SPI = 0x00,
|
||||||
|
PRODTEST_RESP_UART = 0x01,
|
||||||
|
} prodtest_resp_t;
|
||||||
|
|
||||||
|
void prodtest_init(void) { k_sem_give(&prodtest_ok); }
|
||||||
|
|
||||||
|
static void process_command(uint8_t *data, uint16_t len) {
|
||||||
|
uint8_t resp_data[244] = {0};
|
||||||
|
uint8_t cmd = data[0];
|
||||||
|
switch (cmd) {
|
||||||
|
case PRODTEST_CMD_SPI_DATA:
|
||||||
|
resp_data[0] = PRODTEST_RESP_SPI;
|
||||||
|
trz_comm_send_msg(NRF_SERVICE_PRODTEST, resp_data, 244);
|
||||||
|
break;
|
||||||
|
case PRODTEST_CMD_UART_DATA:
|
||||||
|
resp_data[0] = PRODTEST_RESP_UART;
|
||||||
|
trz_comm_send_msg(NRF_SERVICE_PRODTEST, resp_data, 64);
|
||||||
|
break;
|
||||||
|
case PRODTEST_CMD_SET_OUTPUT:
|
||||||
|
signals_reserved(data[1]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prodtest_thread(void) {
|
||||||
|
/* Don't go any further until module is initialized */
|
||||||
|
k_sem_take(&prodtest_ok, K_FOREVER);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
trz_packet_t *buf = trz_comm_poll_data(NRF_SERVICE_PRODTEST);
|
||||||
|
process_command(buf->data, buf->len);
|
||||||
|
k_free(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
K_THREAD_DEFINE(prodtest_thread_id, CONFIG_DEFAULT_THREAD_STACK_SIZE,
|
||||||
|
prodtest_thread, NULL, NULL, NULL, 7, 0, 0);
|
@ -24,8 +24,24 @@
|
|||||||
// Initializes the Signals module
|
// Initializes the Signals module
|
||||||
bool signals_init(void);
|
bool signals_init(void);
|
||||||
|
|
||||||
|
// INPUTS
|
||||||
|
|
||||||
// Checks if the TRZ is ready to communicate
|
// Checks if the TRZ is ready to communicate
|
||||||
bool signals_is_trz_ready(void);
|
bool signals_is_trz_ready(void);
|
||||||
|
|
||||||
|
// Checks if the device should stay in the bootloader
|
||||||
|
bool signals_is_stay_in_bootloader(void);
|
||||||
|
|
||||||
|
// OUTPUTS
|
||||||
|
|
||||||
// Signals that NRF firmware is running and initialized
|
// Signals that NRF firmware is running and initialized
|
||||||
void signals_fw_running(bool set);
|
void signals_nrf_ready(bool set);
|
||||||
|
|
||||||
|
// Sets the reserved output
|
||||||
|
void signals_reserved(bool set);
|
||||||
|
|
||||||
|
// Reads the current output setting
|
||||||
|
bool signals_out_get_nrf_ready(void);
|
||||||
|
|
||||||
|
// Reads the current output setting
|
||||||
|
bool signals_out_get_reserved(void);
|
||||||
|
@ -28,12 +28,16 @@
|
|||||||
#define LOG_MODULE_NAME signals
|
#define LOG_MODULE_NAME signals
|
||||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
#define RUN_STATUS_LED DK_LED1
|
#define OUT_RESERVED DK_LED1
|
||||||
#define RUN_LED_BLINK_INTERVAL 1000
|
#define OUT_NRF_READY DK_LED2
|
||||||
|
|
||||||
#define FW_RUNNING_SIG DK_LED2
|
#define IN_STAY_IN_BOOTLOADER DK_BTN1_MSK
|
||||||
|
#define IN_TRZ_READY DK_BTN2_MSK
|
||||||
|
|
||||||
static K_SEM_DEFINE(led_init_ok, 0, 1);
|
static K_SEM_DEFINE(signals_ok, 0, 1);
|
||||||
|
|
||||||
|
static bool out_nrf_ready = false;
|
||||||
|
static bool out_reserved = false;
|
||||||
|
|
||||||
void button_changed(uint32_t button_state, uint32_t has_changed) {}
|
void button_changed(uint32_t button_state, uint32_t has_changed) {}
|
||||||
|
|
||||||
@ -52,44 +56,31 @@ static void configure_gpio(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool signals_is_trz_ready(void) {
|
bool signals_is_trz_ready(void) {
|
||||||
return (dk_get_buttons() & DK_BTN2_MSK) != 0;
|
return (dk_get_buttons() & IN_TRZ_READY) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool signals_is_stay_in_bootloader(void) {
|
||||||
|
return (dk_get_buttons() & IN_STAY_IN_BOOTLOADER) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool signals_init(void) {
|
bool signals_init(void) {
|
||||||
configure_gpio();
|
configure_gpio();
|
||||||
|
|
||||||
k_sem_give(&led_init_ok);
|
k_sem_give(&signals_ok);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void signals_fw_running(bool set) { dk_set_led(FW_RUNNING_SIG, set); }
|
void signals_nrf_ready(bool set) {
|
||||||
|
out_nrf_ready = set;
|
||||||
void led_thread(void) {
|
dk_set_led(OUT_NRF_READY, set);
|
||||||
// bool connected = false;
|
|
||||||
int blink_status = 0;
|
|
||||||
/* Don't go any further until BLE is initialized */
|
|
||||||
k_sem_take(&led_init_ok, K_FOREVER);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
blink_status++;
|
|
||||||
dk_set_led(RUN_STATUS_LED, (blink_status) % 2);
|
|
||||||
|
|
||||||
// connected = is_connected();
|
|
||||||
//
|
|
||||||
// if (connected) {
|
|
||||||
// dk_set_led_on(CON_STATUS_LED);
|
|
||||||
// } else {
|
|
||||||
// if (is_advertising() && !is_advertising_whitelist()) {
|
|
||||||
// dk_set_led(CON_STATUS_LED, (blink_status) % 2);
|
|
||||||
// } else {
|
|
||||||
// dk_set_led_off(CON_STATUS_LED);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
K_THREAD_DEFINE(led_thread_id, CONFIG_DEFAULT_THREAD_STACK_SIZE, led_thread,
|
bool signals_out_get_nrf_ready(void) { return out_nrf_ready; }
|
||||||
NULL, NULL, NULL, 7, 0, 0);
|
|
||||||
|
void signals_reserved(bool set) {
|
||||||
|
out_reserved = set;
|
||||||
|
dk_set_led(OUT_RESERVED, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool signals_out_get_reserved(void) { return out_reserved; }
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
NRF_SERVICE_BLE = 0,
|
NRF_SERVICE_BLE = 0,
|
||||||
NRF_SERVICE_BLE_MANAGER = 1,
|
NRF_SERVICE_BLE_MANAGER = 1,
|
||||||
NRF_SERVICE_POWER_MANAGEMENT = 2,
|
NRF_SERVICE_MANAGEMENT = 2,
|
||||||
|
NRF_SERVICE_PRODTEST = 3,
|
||||||
|
|
||||||
NRF_SERVICE_CNT // Number of services
|
NRF_SERVICE_CNT // Number of services
|
||||||
} nrf_service_id_t;
|
} nrf_service_id_t;
|
||||||
|
@ -34,7 +34,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||||||
|
|
||||||
static K_FIFO_DEFINE(fifo_uart_rx_ble);
|
static K_FIFO_DEFINE(fifo_uart_rx_ble);
|
||||||
static K_FIFO_DEFINE(fifo_uart_rx_ble_manager);
|
static K_FIFO_DEFINE(fifo_uart_rx_ble_manager);
|
||||||
static K_FIFO_DEFINE(fifo_uart_rx_power_management);
|
static K_FIFO_DEFINE(fifo_uart_rx_management);
|
||||||
|
static K_FIFO_DEFINE(fifo_uart_rx_prodtest);
|
||||||
|
|
||||||
void trz_comm_init(void) {
|
void trz_comm_init(void) {
|
||||||
spi_init();
|
spi_init();
|
||||||
@ -62,15 +63,23 @@ void process_rx_msg(uint8_t service_id, uint8_t *data, uint32_t len) {
|
|||||||
buf->len = len;
|
buf->len = len;
|
||||||
memcpy(buf->data, data, len);
|
memcpy(buf->data, data, len);
|
||||||
|
|
||||||
if (service_id == NRF_SERVICE_BLE) {
|
switch (service_id) {
|
||||||
k_fifo_put(&fifo_uart_rx_ble, buf);
|
case NRF_SERVICE_BLE:
|
||||||
} else if (service_id == NRF_SERVICE_BLE_MANAGER) {
|
k_fifo_put(&fifo_uart_rx_ble, buf);
|
||||||
k_fifo_put(&fifo_uart_rx_ble_manager, buf);
|
break;
|
||||||
} else if (service_id == NRF_SERVICE_POWER_MANAGEMENT) {
|
case NRF_SERVICE_BLE_MANAGER:
|
||||||
k_fifo_put(&fifo_uart_rx_power_management, buf);
|
k_fifo_put(&fifo_uart_rx_ble_manager, buf);
|
||||||
} else {
|
break;
|
||||||
LOG_WRN("UART_RX unknown service");
|
case NRF_SERVICE_MANAGEMENT:
|
||||||
k_free(buf);
|
k_fifo_put(&fifo_uart_rx_management, buf);
|
||||||
|
break;
|
||||||
|
case NRF_SERVICE_PRODTEST:
|
||||||
|
k_fifo_put(&fifo_uart_rx_prodtest, buf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_WRN("UART_RX unknown service");
|
||||||
|
k_free(buf);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,8 +89,10 @@ trz_packet_t *trz_comm_poll_data(nrf_service_id_t service) {
|
|||||||
return k_fifo_get(&fifo_uart_rx_ble, K_FOREVER);
|
return k_fifo_get(&fifo_uart_rx_ble, K_FOREVER);
|
||||||
case NRF_SERVICE_BLE_MANAGER:
|
case NRF_SERVICE_BLE_MANAGER:
|
||||||
return k_fifo_get(&fifo_uart_rx_ble_manager, K_FOREVER);
|
return k_fifo_get(&fifo_uart_rx_ble_manager, K_FOREVER);
|
||||||
case NRF_SERVICE_POWER_MANAGEMENT:
|
case NRF_SERVICE_MANAGEMENT:
|
||||||
return k_fifo_get(&fifo_uart_rx_power_management, K_FOREVER);
|
return k_fifo_get(&fifo_uart_rx_management, K_FOREVER);
|
||||||
|
case NRF_SERVICE_PRODTEST:
|
||||||
|
return k_fifo_get(&fifo_uart_rx_prodtest, K_FOREVER);
|
||||||
default:
|
default:
|
||||||
LOG_WRN("UART_RX unknown service");
|
LOG_WRN("UART_RX unknown service");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user