1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-03-12 14:16:06 +00:00

T2W1: add model

This commit is contained in:
tychovrahe 2025-01-14 12:05:12 +01:00 committed by M1nd3r
parent 70e38acfe3
commit 91c3fde7bb
29 changed files with 3004 additions and 1 deletions

View File

@ -706,5 +706,123 @@
"nem:PAC:HRT": "not for T3W1 (#2793)",
"nem:XEM": "not for T3W1 (#2793)"
}
},
"T2W1": {
"supported": {
"bitcoin:ACM": "2.6.1",
"bitcoin:AXE": "2.6.1",
"bitcoin:BCH": "2.6.1",
"bitcoin:BTC": "2.6.1",
"bitcoin:BTCP": "2.6.1",
"bitcoin:BTX": "2.6.1",
"bitcoin:CPU": "2.6.1",
"bitcoin:CRW": "2.6.1",
"bitcoin:DOGE": "2.6.1",
"bitcoin:ELEMENTS": "2.6.1",
"bitcoin:FIRO": "2.6.1",
"bitcoin:FJC": "2.6.1",
"bitcoin:FLO": "2.6.1",
"bitcoin:FTC": "2.6.1",
"bitcoin:GRS": "2.6.1",
"bitcoin:KMD": "2.6.1",
"bitcoin:KOTO": "2.6.1",
"bitcoin:LTC": "2.6.1",
"bitcoin:MONA": "2.6.1",
"bitcoin:PPC": "2.6.1",
"bitcoin:QTUM": "2.6.1",
"bitcoin:REGTEST": "2.6.1",
"bitcoin:RITO": "2.6.1",
"bitcoin:RVN": "2.6.1",
"bitcoin:SMART": "2.6.1",
"bitcoin:SYS": "2.6.1",
"bitcoin:TAZ": "2.6.1",
"bitcoin:TBCH": "2.6.1",
"bitcoin:TEST": "2.6.1",
"bitcoin:UNO": "2.6.1",
"bitcoin:VIA": "2.6.1",
"bitcoin:VIPS": "2.6.1",
"bitcoin:XEC": "2.8.6",
"bitcoin:XPM": "2.6.1",
"bitcoin:XRC": "2.6.1",
"bitcoin:XSN": "2.6.1",
"bitcoin:XVG": "2.6.1",
"bitcoin:ZCR": "2.6.1",
"bitcoin:ZEC": "2.6.1",
"bitcoin:tFIRO": "2.6.1",
"bitcoin:tGRS": "2.6.1",
"bitcoin:tLTC": "2.6.1",
"bitcoin:tPPC": "2.6.1",
"bitcoin:tQTUM": "2.6.1",
"bitcoin:tRVN": "2.6.1",
"bitcoin:tSMART": "2.6.1",
"erc20:bnb:ATOM": "2.6.1",
"erc20:eth:AAVE": "2.6.1",
"erc20:eth:APE": "2.6.1",
"erc20:eth:AXS": "2.6.1",
"erc20:eth:BUSD": "2.6.1",
"erc20:eth:CHZ": "2.6.1",
"erc20:eth:CRO": "2.6.1",
"erc20:eth:DAI": "2.6.1",
"erc20:eth:FRAX": "2.6.1",
"erc20:eth:LEO": "2.6.1",
"erc20:eth:LINK": "2.6.1",
"erc20:eth:MANA": "2.6.1",
"erc20:eth:MATIC": "2.6.1",
"erc20:eth:OKB": "2.6.1",
"erc20:eth:QNT": "2.6.1",
"erc20:eth:SAND": "2.6.1",
"erc20:eth:SHIB": "2.6.1",
"erc20:eth:STETH": "2.6.1",
"erc20:eth:UNI": "2.6.1",
"erc20:eth:USDC": "2.6.1",
"erc20:eth:USDT": "2.6.1",
"erc20:eth:WBTC": "2.6.1",
"erc20:eth:XCN": "2.6.1",
"erc20:matic:WAVAX": "2.6.1",
"eth:ARB:42161": "2.6.1",
"eth:BASE:8453": "2.6.1",
"eth:BSC:56": "2.6.1",
"eth:ETC:61": "2.6.1",
"eth:ETH:1": "2.6.1",
"eth:OP:10": "2.6.1",
"eth:POL:137": "2.6.1",
"eth:tHOL:17000": "2.6.1",
"eth:tSEP:11155111": "2.6.1",
"misc:ADA": "2.6.1",
"misc:BNB": "2.6.1",
"misc:DSOL": "2.6.4",
"misc:MAID": "2.6.1",
"misc:OMNI": "2.6.1",
"misc:SOL": "2.6.4",
"misc:USDT": "2.6.1",
"misc:XLM": "2.6.1",
"misc:XMR": "2.6.1",
"misc:XRP": "2.6.1",
"misc:XTZ": "2.6.1",
"misc:tADA": "2.6.1",
"misc:tXRP": "2.6.1"
},
"unsupported": {
"bitcoin:BTG": "not for T3W1 (#2793)",
"bitcoin:DASH": "not for T3W1 (#2793)",
"bitcoin:DCR": "not for T3W1 (#2793)",
"bitcoin:DGB": "not for T3W1 (#2793)",
"bitcoin:NMC": "not for T3W1 (#2793)",
"bitcoin:PART": "incompatible fork",
"bitcoin:TBTG": "not for T3W1 (#2793)",
"bitcoin:TDCR": "not for T3W1 (#2793)",
"bitcoin:TRC": "address_type collides with Bitcoin",
"bitcoin:VTC": "not for T3W1 (#2793)",
"bitcoin:tDASH": "not for T3W1 (#2793)",
"bitcoin:tPART": "incompatible fork",
"misc:EOS": "not for T3W1 (#2793)",
"misc:LSK": "Incompatible mainnet hard-fork",
"nem:BREEZE": "not for T3W1 (#2793)",
"nem:DIM": "not for T3W1 (#2793)",
"nem:DIMTOK": "not for T3W1 (#2793)",
"nem:PAC:CHS": "not for T3W1 (#2793)",
"nem:PAC:HRT": "not for T3W1 (#2793)",
"nem:XEM": "not for T3W1 (#2793)"
}
}
}

View File

@ -0,0 +1,763 @@
/*
* 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 KERNEL_MODE
#include <trezor_bsp.h>
#include <trezor_rtl.h>
#include <io/nrf.h>
#include <sys/irq.h>
#include <sys/mpu.h>
#include <sys/systick.h>
#include <util/tsqueue.h>
#include "../crc8.h"
#include "../nrf_internal.h"
#define MAX_SPI_DATA_SIZE (244)
typedef struct {
uint8_t service_id;
uint8_t data[MAX_SPI_DATA_SIZE];
uint8_t crc;
} spi_packet_t;
typedef struct {
uint8_t service_id;
uint8_t msg_len;
uint8_t data[NRF_MAX_TX_DATA_SIZE + 1];
// uint8_t crc; part of data, as it has variable position
} uart_packet_t;
#define UART_OVERHEAD_SIZE (sizeof(uart_packet_t) - NRF_MAX_TX_DATA_SIZE)
#define UART_HEADER_SIZE (UART_OVERHEAD_SIZE - 1)
#define TX_QUEUE_SIZE (8)
#define START_BYTE (0xA0)
typedef struct {
uart_packet_t packet;
nrf_tx_callback_t callback;
void *context;
} nrf_tx_request_t;
typedef struct {
UART_HandleTypeDef urt;
DMA_HandleTypeDef urt_tx_dma;
uint8_t tx_buffers[TX_QUEUE_SIZE][sizeof(nrf_tx_request_t)];
tsqueue_entry_t tx_queue_entries[TX_QUEUE_SIZE];
tsqueue_t tx_queue;
nrf_tx_request_t tx_request;
int32_t tx_request_id;
uart_packet_t rx_buffer;
uint8_t rx_len;
uint8_t rx_byte;
uint16_t rx_idx;
SPI_HandleTypeDef spi;
DMA_HandleTypeDef spi_dma;
spi_packet_t long_rx_buffer;
bool comm_running;
bool initialized;
nrf_rx_callback_t service_listeners[NRF_SERVICE_CNT];
} nrf_driver_t;
__attribute__((section(".buf"))) static nrf_driver_t g_nrf_driver = {0};
static void nrf_start(void) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return;
}
HAL_SPI_Receive_DMA(&drv->spi, (uint8_t *)&drv->long_rx_buffer,
sizeof(spi_packet_t));
tsqueue_reset(&drv->tx_queue);
HAL_UART_Receive_IT(&drv->urt, &drv->rx_byte, 1);
drv->comm_running = true;
nrf_signal_running();
}
static void nrf_abort_urt_comm(nrf_driver_t *drv) {
HAL_UART_AbortReceive(&drv->urt);
HAL_UART_AbortTransmit(&drv->urt);
if (drv->tx_request.callback != NULL) {
drv->tx_request.callback(NRF_STATUS_ERROR, drv->tx_request.context);
}
drv->rx_idx = 0;
drv->rx_len = 0;
drv->tx_request_id = -1;
while (tsqueue_dequeue(&drv->tx_queue, (uint8_t *)&drv->tx_request,
sizeof(nrf_tx_request_t), NULL, NULL)) {
if (drv->tx_request.callback != NULL) {
drv->tx_request.callback(NRF_STATUS_ERROR, drv->tx_request.context);
}
}
memset(&drv->tx_request, 0, sizeof(nrf_tx_request_t));
tsqueue_reset(&drv->tx_queue);
}
static void nrf_stop(void) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return;
}
nrf_signal_off();
irq_key_t key = irq_lock();
drv->comm_running = false;
HAL_SPI_DMAStop(&drv->spi);
nrf_abort_urt_comm(drv);
irq_unlock(key);
}
void nrf_init(void) {
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized) {
return;
}
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
memset(drv, 0, sizeof(*drv));
tsqueue_init(&drv->tx_queue, drv->tx_queue_entries,
(uint8_t *)drv->tx_buffers, sizeof(nrf_tx_request_t),
TX_QUEUE_SIZE);
GPIO_InitTypeDef GPIO_InitStructure = {0};
// synchronization signals
NRF_OUT_RESET_CLK_ENA();
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_SET);
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = NRF_OUT_RESET_PIN;
HAL_GPIO_Init(NRF_OUT_RESET_PORT, &GPIO_InitStructure);
NRF_IN_GPIO0_CLK_ENA();
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = NRF_IN_GPIO0_PIN;
HAL_GPIO_Init(NRF_IN_GPIO0_PORT, &GPIO_InitStructure);
NRF_IN_FW_RUNNING_CLK_ENA();
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = NRF_IN_FW_RUNNING_PIN;
HAL_GPIO_Init(NRF_IN_FW_RUNNING_PORT, &GPIO_InitStructure);
NRF_OUT_STAY_IN_BLD_CLK_ENA();
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = NRF_OUT_STAY_IN_BLD_PIN;
HAL_GPIO_Init(NRF_OUT_STAY_IN_BLD_PORT, &GPIO_InitStructure);
NRF_OUT_FW_RUNNING_CLK_ENA();
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = NRF_OUT_FW_RUNNING_PIN;
HAL_GPIO_Init(NRF_OUT_FW_RUNNING_PORT, &GPIO_InitStructure);
// UART PINS
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF7_USART1;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_12;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
drv->urt.Init.Mode = UART_MODE_TX_RX;
drv->urt.Init.BaudRate = 1000000;
drv->urt.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
drv->urt.Init.OverSampling = UART_OVERSAMPLING_16;
drv->urt.Init.Parity = UART_PARITY_NONE;
drv->urt.Init.StopBits = UART_STOPBITS_1;
drv->urt.Init.WordLength = UART_WORDLENGTH_8B;
drv->urt.Instance = USART1;
drv->urt.hdmatx = &drv->urt_tx_dma;
drv->urt_tx_dma.Instance = DMA2_Stream7;
drv->urt_tx_dma.State = HAL_DMA_STATE_RESET;
drv->urt_tx_dma.Init.Channel = DMA_CHANNEL_4;
drv->urt_tx_dma.Init.Direction = DMA_MEMORY_TO_PERIPH;
drv->urt_tx_dma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
drv->urt_tx_dma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
drv->urt_tx_dma.Init.MemBurst = DMA_MBURST_SINGLE;
drv->urt_tx_dma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
drv->urt_tx_dma.Init.MemInc = DMA_MINC_ENABLE;
drv->urt_tx_dma.Init.Mode = DMA_NORMAL;
drv->urt_tx_dma.Init.PeriphBurst = DMA_PBURST_SINGLE;
drv->urt_tx_dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
drv->urt_tx_dma.Init.PeriphInc = DMA_PINC_DISABLE;
drv->urt_tx_dma.Init.Priority = DMA_PRIORITY_HIGH;
drv->urt_tx_dma.Parent = &drv->urt;
HAL_DMA_Init(&drv->urt_tx_dma);
HAL_UART_Init(&drv->urt);
NVIC_SetPriority(DMA2_Stream7_IRQn, IRQ_PRI_NORMAL);
NVIC_EnableIRQ(DMA2_Stream7_IRQn);
NVIC_SetPriority(USART1_IRQn, IRQ_PRI_NORMAL);
NVIC_EnableIRQ(USART1_IRQn);
// SPI pins
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF5_SPI2;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_3;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_9;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
drv->spi_dma.Instance = DMA1_Stream3;
drv->spi_dma.State = HAL_DMA_STATE_RESET;
drv->spi_dma.Init.Channel = DMA_CHANNEL_0;
drv->spi_dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
drv->spi_dma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
drv->spi_dma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
drv->spi_dma.Init.MemBurst = DMA_MBURST_SINGLE;
drv->spi_dma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
drv->spi_dma.Init.MemInc = DMA_MINC_ENABLE;
drv->spi_dma.Init.Mode = DMA_NORMAL;
drv->spi_dma.Init.PeriphBurst = DMA_PBURST_SINGLE;
drv->spi_dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
drv->spi_dma.Init.PeriphInc = DMA_PINC_DISABLE;
drv->spi_dma.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&drv->spi_dma);
drv->spi.Instance = SPI2;
drv->spi.Init.Mode = SPI_MODE_SLAVE;
drv->spi.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
drv->spi.Init.DataSize = SPI_DATASIZE_8BIT;
drv->spi.Init.CLKPolarity = SPI_POLARITY_LOW;
drv->spi.Init.CLKPhase = SPI_PHASE_1EDGE;
drv->spi.Init.NSS = SPI_NSS_HARD_INPUT;
drv->spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
drv->spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
drv->spi.Init.TIMode = SPI_TIMODE_DISABLE;
drv->spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
drv->spi.Init.CRCPolynomial = 0;
drv->spi.hdmarx = &drv->spi_dma;
drv->spi_dma.Parent = &drv->spi;
HAL_SPI_Init(&drv->spi);
NVIC_SetPriority(DMA1_Stream3_IRQn, IRQ_PRI_NORMAL);
NVIC_EnableIRQ(DMA1_Stream3_IRQn);
NVIC_SetPriority(SPI2_IRQn, IRQ_PRI_NORMAL);
NVIC_EnableIRQ(SPI2_IRQn);
drv->tx_request_id = -1;
drv->initialized = true;
nrf_start();
}
void nrf_deinit(void) {
nrf_driver_t *drv = &g_nrf_driver;
nrf_stop();
NVIC_DisableIRQ(DMA1_Stream3_IRQn);
NVIC_DisableIRQ(DMA2_Stream7_IRQn);
NVIC_DisableIRQ(SPI2_IRQn);
__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
__HAL_RCC_USART1_FORCE_RESET();
__HAL_RCC_USART1_RELEASE_RESET();
drv->initialized = false;
}
bool nrf_register_listener(nrf_service_id_t service,
nrf_rx_callback_t callback) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return false;
}
if (service >= NRF_SERVICE_CNT) {
return false;
}
if (drv->service_listeners[service] != NULL) {
return false;
}
irq_key_t key = irq_lock();
drv->service_listeners[service] = callback;
irq_unlock(key);
return true;
}
void nrf_unregister_listener(nrf_service_id_t service) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return;
}
if (service >= NRF_SERVICE_CNT) {
return;
}
irq_key_t key = irq_lock();
drv->service_listeners[service] = NULL;
irq_unlock(key);
}
static void nrf_process_msg(nrf_driver_t *drv, const uint8_t *data,
uint32_t len, nrf_service_id_t service) {
if (drv->service_listeners[service] != NULL) {
drv->service_listeners[service](data, len);
}
}
/// DFU communication
/// ----------------------------------------------------------
void nrf_dfu_comm_send(const uint8_t *data, uint32_t len) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return;
}
HAL_UART_Transmit(&drv->urt, (uint8_t *)data, len, 30);
}
uint32_t nrf_dfu_comm_receive(uint8_t *data, uint32_t len) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return 0;
}
if (__HAL_UART_GET_FLAG(&drv->urt, UART_FLAG_RXNE)) {
HAL_StatusTypeDef result = HAL_UART_Receive(&drv->urt, data, len, 30);
if (result == HAL_OK) {
return len;
}
if (drv->urt.RxXferCount == len) {
return 0;
}
return len - drv->urt.RxXferCount - 1;
}
return 0;
}
/// UART communication
/// ---------------------------------------------------------
int32_t nrf_send_msg(nrf_service_id_t service, const uint8_t *data,
uint32_t len, nrf_tx_callback_t callback, void *context) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return -1;
}
if (len > NRF_MAX_TX_DATA_SIZE) {
return -1;
}
if (service > NRF_SERVICE_CNT) {
return -1;
}
if (!nrf_is_running()) {
return -1;
}
int32_t id = 0;
nrf_tx_request_t tx_request = {0};
tx_request.callback = callback;
tx_request.context = context;
tx_request.packet.service_id = 0xA0 | (uint8_t)service;
tx_request.packet.msg_len = len + UART_OVERHEAD_SIZE;
memcpy(&tx_request.packet.data, data, len);
tx_request.packet.data[len] =
crc8((uint8_t *)&tx_request.packet, len + UART_OVERHEAD_SIZE - 1, 0x07,
0x00, false);
if (!tsqueue_enqueue(&drv->tx_queue, (uint8_t *)&tx_request,
sizeof(nrf_tx_request_t), &id)) {
return -1;
}
irq_key_t key = irq_lock();
if (drv->tx_request_id <= 0) {
int32_t tx_id = 0;
if (tsqueue_dequeue(&drv->tx_queue, (uint8_t *)&drv->tx_request,
sizeof(nrf_tx_request_t), NULL, &tx_id)) {
HAL_UART_Transmit_DMA(&drv->urt, (uint8_t *)&drv->tx_request.packet,
drv->tx_request.packet.msg_len);
drv->tx_request_id = tx_id;
}
}
irq_unlock(key);
return id;
}
bool nrf_abort_msg(int32_t id) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return false;
}
bool aborted = tsqueue_abort(&drv->tx_queue, id, NULL, 0, NULL);
if (aborted) {
return true;
}
irq_key_t key = irq_lock();
if (drv->tx_request_id == id) {
drv->tx_request_id = -1;
irq_unlock(key);
return true;
}
irq_unlock(key);
return false;
}
static bool nrf_is_valid_startbyte(uint8_t val) {
if ((val & 0xF0) != 0xA0) {
return false;
}
if ((val & 0x0F) >= NRF_SERVICE_CNT) {
return false;
}
return true;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *urt) {
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized && urt == &drv->urt) {
if (drv->rx_idx == 0) {
// received first byte: START BYTE
if (nrf_is_valid_startbyte(drv->rx_byte)) {
drv->rx_buffer.service_id = drv->rx_byte;
drv->rx_idx++;
} else {
// bad message, flush the line
drv->rx_idx = 0;
}
} else if (drv->rx_idx == 1) {
// received second byte: LEN
drv->rx_buffer.msg_len = drv->rx_byte;
drv->rx_len = drv->rx_byte;
if (drv->rx_len > sizeof(uart_packet_t)) {
drv->rx_len = 0;
drv->rx_idx = 0;
} else {
drv->rx_idx++;
}
} else if (drv->rx_idx >= UART_HEADER_SIZE &&
drv->rx_idx < (drv->rx_len - 1)) {
// receive the rest of the message
drv->rx_buffer.data[drv->rx_idx - UART_HEADER_SIZE] = drv->rx_byte;
drv->rx_idx++;
if (drv->rx_idx >= NRF_MAX_TX_DATA_SIZE) {
// message is too long, flush the line
drv->rx_idx = 0;
drv->rx_len = 0;
}
} else if (drv->rx_idx == (drv->rx_len - 1)) {
// received last byte: CRC
uint8_t crc =
crc8((uint8_t *)&drv->rx_buffer, drv->rx_len - 1, 0x07, 0x00, false);
if (drv->rx_byte == crc) {
uart_packet_t *packet = &drv->rx_buffer;
nrf_process_msg(drv, drv->rx_buffer.data,
drv->rx_len - UART_OVERHEAD_SIZE,
packet->service_id & 0x0F);
}
drv->rx_idx = 0;
drv->rx_len = 0;
} else {
// bad message, flush the line
drv->rx_idx = 0;
drv->rx_len = 0;
}
}
// receive the rest of the message, or new message in any case.
HAL_UART_Receive_IT(&drv->urt, &drv->rx_byte, 1);
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *urt) {
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized && urt == &drv->urt) {
nrf_abort_urt_comm(drv);
HAL_UART_Receive_IT(&drv->urt, &drv->rx_byte, 1);
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *urt) {
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized && urt == &drv->urt) {
if (drv->tx_request.callback != NULL) {
drv->tx_request.callback(NRF_STATUS_OK, drv->tx_request.context);
}
drv->tx_request_id = -1;
memset(&drv->tx_request, 0, sizeof(nrf_tx_request_t));
bool msg =
tsqueue_dequeue(&drv->tx_queue, (uint8_t *)&drv->tx_request,
sizeof(nrf_tx_request_t), NULL, &drv->tx_request_id);
if (msg) {
HAL_UART_Transmit_DMA(&drv->urt, (uint8_t *)&drv->tx_request.packet,
drv->tx_request.packet.msg_len);
}
}
}
void USART1_IRQHandler(void) {
IRQ_LOG_ENTER();
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized) {
HAL_UART_IRQHandler(&drv->urt);
}
mpu_restore(mpu_mode);
IRQ_LOG_EXIT();
}
void DMA2_Stream7_IRQHandler(void) {
IRQ_LOG_ENTER();
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized) {
HAL_DMA_IRQHandler(&drv->urt_tx_dma);
}
mpu_restore(mpu_mode);
IRQ_LOG_EXIT();
}
/// SPI communication
/// ----------------------------------------------------------
void DMA1_Stream3_IRQHandler(void) {
IRQ_LOG_ENTER();
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized) {
HAL_DMA_IRQHandler(&drv->spi_dma);
}
mpu_restore(mpu_mode);
IRQ_LOG_EXIT();
}
void SPI2_IRQHandler(void) {
IRQ_LOG_ENTER();
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized) {
HAL_SPI_IRQHandler(&drv->spi);
}
mpu_restore(mpu_mode);
IRQ_LOG_EXIT();
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return;
}
if (hspi != &drv->spi) {
return;
}
spi_packet_t *packet = &drv->long_rx_buffer;
uint8_t crc = crc8((uint8_t *)&drv->long_rx_buffer, sizeof(spi_packet_t) - 1,
0x07, 0x00, false);
if ((packet->service_id & 0xF0) != START_BYTE || packet->crc != crc) {
HAL_SPI_Abort(&drv->spi);
HAL_SPI_Receive_DMA(&drv->spi, (uint8_t *)&drv->long_rx_buffer,
sizeof(spi_packet_t));
return;
}
nrf_process_msg(drv, drv->long_rx_buffer.data, sizeof(packet->data),
packet->service_id & 0x0F);
HAL_SPI_Receive_DMA(&drv->spi, (uint8_t *)&drv->long_rx_buffer,
sizeof(spi_packet_t));
}
/// GPIO communication
/// ---------------------------------------------------------
bool nrf_reboot_to_bootloader(void) {
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,
GPIO_PIN_SET);
systick_delay_ms(50);
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_SET);
systick_delay_ms(1000);
return true;
}
bool nrf_reboot(void) {
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(NRF_OUT_STAY_IN_BLD_PORT, NRF_OUT_STAY_IN_BLD_PIN,
GPIO_PIN_RESET);
systick_delay_ms(50);
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_RESET);
return true;
}
void nrf_signal_running(void) {
HAL_GPIO_WritePin(NRF_OUT_FW_RUNNING_PORT, NRF_OUT_FW_RUNNING_PIN,
GPIO_PIN_SET);
}
void nrf_signal_off(void) {
HAL_GPIO_WritePin(NRF_OUT_FW_RUNNING_PORT, NRF_OUT_FW_RUNNING_PIN,
GPIO_PIN_RESET);
}
bool nrf_firmware_running(void) {
return HAL_GPIO_ReadPin(NRF_IN_FW_RUNNING_PORT, NRF_IN_FW_RUNNING_PIN) != 0;
}
bool nrf_is_running(void) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return false;
}
if (!nrf_firmware_running()) {
return false;
}
return drv->comm_running;
}
void nrf_set_dfu_mode(void) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return;
}
// TODO
// if (nrf_reboot_to_bootloader()) {
// drv->mode_current = BLE_MODE_DFU;
// } else {
// drv->status_valid = false;
// }
}
bool nrf_is_dfu_mode(void) {
nrf_driver_t *drv = &g_nrf_driver;
if (!drv->initialized) {
return false;
}
return true;
// TODO
}
#endif

View File

@ -0,0 +1,91 @@
#ifndef _TREZOR_T2W1_H
#define _TREZOR_T2W1_H
#define DISPLAY_COLOR_MODE DMA2D_OUTPUT_RGB565
#define DISPLAY_I8080_16BIT_DW 1
#define DISPLAY_PANEL_LHS200KB_IF21 1
#define TPS61043_FREQ 50000
#define TPS61043_TIM TIM1
#define TPS61043_TIM_CLK_EN __HAL_RCC_TIM1_CLK_ENABLE
#define TPS61043_TIM_CLK_DIS __HAL_RCC_TIM1_CLK_DISABLE
#define TPS61043_TIM_FORCE_RESET __HAL_RCC_TIM1_FORCE_RESET
#define TPS61043_TIM_RELEASE_RESET __HAL_RCC_TIM1_RELEASE_RESET
#define TPS61043_TIM_AF GPIO_AF1_TIM1
#define TPS61043_TIM_OCMODE TIM_OCMODE_PWM2
#define TPS61043_TIM_CHANNEL TIM_CHANNEL_1
#define TPS61043_TIM_CCR CCR1
#define TPS61043_PIN GPIO_PIN_7
#define TPS61043_PORT GPIOA
#define TPS61043_PORT_CLK_EN __HAL_RCC_GPIOA_CLK_ENABLE
#define I2C_COUNT 1
#define I2C_INSTANCE_0 I2C2
#define I2C_INSTANCE_0_CLK_EN __HAL_RCC_I2C2_CLK_ENABLE
#define I2C_INSTANCE_0_CLK_DIS __HAL_RCC_I2C2_CLK_DISABLE
#define I2C_INSTANCE_0_PIN_AF GPIO_AF4_I2C2
#define I2C_INSTANCE_0_SDA_PORT GPIOB
#define I2C_INSTANCE_0_SDA_PIN GPIO_PIN_11
#define I2C_INSTANCE_0_SDA_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define I2C_INSTANCE_0_SCL_PORT GPIOB
#define I2C_INSTANCE_0_SCL_PIN GPIO_PIN_10
#define I2C_INSTANCE_0_SCL_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE
#define I2C_INSTANCE_0_RESET_REG &RCC->APB1RSTR
#define I2C_INSTANCE_0_RESET_BIT RCC_APB1RSTR_I2C2RST
#define I2C_INSTANCE_0_EV_IRQHandler I2C2_EV_IRQHandler
#define I2C_INSTANCE_0_ER_IRQHandler I2C2_ER_IRQHandler
#define I2C_INSTANCE_0_EV_IRQn I2C2_EV_IRQn
#define I2C_INSTANCE_0_ER_IRQn I2C2_ER_IRQn
#define I2C_INSTANCE_0_GUARD_TIME 0
#define TOUCH_SENSITIVITY 0x06
#define TOUCH_I2C_INSTANCE 0
#define TOUCH_RST_PORT GPIOC
#define TOUCH_RST_PIN GPIO_PIN_5
#define TOUCH_INT_PORT GPIOC
#define TOUCH_INT_PIN GPIO_PIN_4
#define TOUCH_ON_PORT GPIOB
#define TOUCH_ON_PIN GPIO_PIN_8
#define TOUCH_PANEL_LHS200KB_IF21 1
#define SD_DETECT_PORT GPIOB
#define SD_DETECT_PIN GPIO_PIN_0
#define SD_ENABLE_PORT GPIOE
#define SD_ENABLE_PIN GPIO_PIN_1
#define SBU_1_PIN GPIO_PIN_2
#define SBU_1_PORT GPIOA
#define SBU_1_CLK_ENA __HAL_RCC_GPIOA_CLK_ENABLE
#define SBU_2_PIN GPIO_PIN_3
#define SBU_2_PORT GPIOA
#define SBU_2_CLK_ENA __HAL_RCC_GPIOA_CLK_ENABLE
#define GPIO_1_PORT GPIOC
#define GPIO_1_PIN GPIO_PIN_1
#define GPIO_2_PORT GPIOC
#define GPIO_2_PIN GPIO_PIN_6
#define GPIO_3_PORT GPIOC
#define GPIO_3_PIN GPIO_PIN_7
#define BTN_POWER_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
#define BTN_POWER_PORT GPIOE
#define BTN_POWER_PIN GPIO_PIN_0
#define NRF_IN_GPIO0_PIN GPIO_PIN_1
#define NRF_IN_GPIO0_PORT GPIOC
#define NRF_IN_GPIO0_CLK_ENA __HAL_RCC_GPIOC_CLK_ENABLE
#define NRF_IN_FW_RUNNING_PIN GPIO_PIN_6
#define NRF_IN_FW_RUNNING_PORT GPIOC
#define NRF_IN_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOC_CLK_ENABLE
#define NRF_OUT_RESET_PIN GPIO_PIN_1
#define NRF_OUT_RESET_PORT GPIOA
#define NRF_OUT_RESET_CLK_ENA __HAL_RCC_GPIOA_CLK_ENABLE
#define NRF_OUT_STAY_IN_BLD_PIN GPIO_PIN_12
#define NRF_OUT_STAY_IN_BLD_PORT GPIOB
#define NRF_OUT_STAY_IN_BLD_CLK_ENA __HAL_RCC_GPIOB_CLK_ENABLE
#define NRF_OUT_FW_RUNNING_PIN GPIO_PIN_7
#define NRF_OUT_FW_RUNNING_PORT GPIOC
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOC_CLK_ENABLE
#endif //_TREZOR_T3W1_H

Binary file not shown.

View File

@ -0,0 +1,3 @@
MCU = STM32F4
OPENOCD_TARGET = target/stm32f4x.cfg
LAYOUT_FEATURE = layout_bolt

View File

@ -0,0 +1,68 @@
/* Auto-generated file, do not edit.*/
NORCOW_SECTOR_SIZE = 0x10000;
FLASH_START = 0x8000000;
BOARDLOADER_START = 0x8000000;
BOARDLOADER_MAXSIZE = 0xc000;
BOARDLOADER_SECTOR_START = 0x0;
BOARDLOADER_SECTOR_END = 0x2;
BOARDCAPS_START = 0x800bf00;
BOARDCAPS_MAXSIZE = 0x100;
UNUSED_1_START = 0x800c000;
UNUSED_1_MAXSIZE = 0x4000;
UNUSED_1_SECTOR_START = 0x3;
UNUSED_1_SECTOR_END = 0x3;
STORAGE_1_START = 0x8010000;
STORAGE_1_MAXSIZE = 0x10000;
STORAGE_1_SECTOR_START = 0x4;
STORAGE_1_SECTOR_END = 0x4;
BOOTLOADER_START = 0x8020000;
BOOTLOADER_MAXSIZE = 0x20000;
BOOTLOADER_SECTOR_START = 0x5;
BOOTLOADER_SECTOR_END = 0x5;
FIRMWARE_START = 0x8040000;
FIRMWARE_MAXSIZE = 0x1a0000;
FIRMWARE_P1_START = 0x8040000;
FIRMWARE_P1_MAXSIZE = 0xc0000;
FIRMWARE_P1_SECTOR_START = 0x6;
FIRMWARE_P1_SECTOR_END = 0xb;
KERNEL_START = 0x8040000;
KERNEL_MAXSIZE = 0x80000;
ASSETS_START = 0x8100000;
ASSETS_MAXSIZE = 0xc000;
ASSETS_SECTOR_START = 0xc;
ASSETS_SECTOR_END = 0xe;
UNUSED_2_START = 0x810c000;
UNUSED_2_MAXSIZE = 0x4000;
UNUSED_2_SECTOR_START = 0xf;
UNUSED_2_SECTOR_END = 0xf;
STORAGE_2_START = 0x8110000;
STORAGE_2_MAXSIZE = 0x10000;
STORAGE_2_SECTOR_START = 0x10;
STORAGE_2_SECTOR_END = 0x10;
FIRMWARE_P2_START = 0x8120000;
FIRMWARE_P2_MAXSIZE = 0xe0000;
FIRMWARE_P2_SECTOR_START = 0x11;
FIRMWARE_P2_SECTOR_END = 0x17;
S_MAIN_STACK_START = 0x10000000;
S_MAIN_STACK_SIZE = 0x4000;
S_FB1_RAM_START = 0x10004000;
S_FB1_RAM_SIZE = 0x0;
S_MAIN_RAM_START = 0x10004000;
S_MAIN_RAM_SIZE = 0xbf00;
K_MAIN_STACK_START = 0x10000000;
K_MAIN_STACK_SIZE = 0x2000;
K_AUX2_RAM_START = 0x10002000;
K_AUX2_RAM_SIZE = 0xa000;
K_FB1_RAM_START = 0x1000c000;
K_FB1_RAM_SIZE = 0x0;
K_MAIN_RAM_START = 0x1000c000;
K_MAIN_RAM_SIZE = 0x3f00;
BOOTARGS_START = 0x1000ff00;
BOOTARGS_SIZE = 0x100;
DMABUF_RAM_START = 0x20000000;
DMABUF_RAM_SIZE = 0x800;
AUX1_RAM_START = 0x20000800;
AUX1_RAM_SIZE = 0x2f800;
CODE_ALIGNMENT = 0x200;
COREAPP_ALIGNMENT = 0x200;

View File

@ -0,0 +1,128 @@
#ifndef MODELS_MODEL_T2T1_H_
#define MODELS_MODEL_T2T1_H_
// #include "bootloaders/bootloader_hashes.h"
#define MODEL_NAME "T2W1"
#define MODEL_FULL_NAME "Trezor Model T2W1"
#define MODEL_INTERNAL_NAME "T2W1"
#define MODEL_INTERNAL_NAME_TOKEN T2W1
#define MODEL_INTERNAL_NAME_QSTR MP_QSTR_T2W1
#define MODEL_USB_MANUFACTURER "SatoshiLabs"
#define MODEL_USB_PRODUCT "TREZOR"
#define MODEL_HOMESCREEN_MAXSIZE 16384
/*** PRODUCTION KEYS ***/
#define MODEL_BOARDLOADER_KEYS \
(const uint8_t *)"\x0e\xb9\x85\x6b\xe9\xba\x7e\x97\x2c\x7f\x34\xea\xc1\xed\x9b\x6f\xd0\xef\xd1\x72\xec\x00\xfa\xf0\xc5\x89\x75\x9d\xa4\xdd\xfb\xa0", \
(const uint8_t *)"\xac\x8a\xb4\x0b\x32\xc9\x86\x55\x79\x8f\xd5\xda\x5e\x19\x2b\xe2\x7a\x22\x30\x6e\xa0\x5c\x6d\x27\x7c\xdf\xf4\xa3\xf4\x12\x5c\xd8", \
(const uint8_t *)"\xce\x0f\xcd\x12\x54\x3e\xf5\x93\x6c\xf2\x80\x49\x82\x13\x67\x07\x86\x3d\x17\x29\x5f\xac\xed\x72\xaf\x17\x1d\x6e\x65\x13\xff\x06",
#define MODEL_BOOTLOADER_KEYS \
(const uint8_t *)"\xc2\xc8\x7a\x49\xc5\xa3\x46\x09\x77\xfb\xb2\xec\x9d\xfe\x60\xf0\x6b\xd6\x94\xdb\x82\x44\xbd\x49\x81\xfe\x3b\x7a\x26\x30\x7f\x3f", \
(const uint8_t *)"\x80\xd0\x36\xb0\x87\x39\xb8\x46\xf4\xcb\x77\x59\x30\x78\xde\xb2\x5d\xc9\x48\x7a\xed\xcf\x52\xe3\x0b\x4f\xb7\xcd\x70\x24\x17\x8a", \
(const uint8_t *)"\xb8\x30\x7a\x71\xf5\x52\xc6\x0a\x4c\xbb\x31\x7f\xf4\x8b\x82\xcd\xbf\x6b\x6b\xb5\xf0\x4c\x92\x0f\xec\x7b\xad\xf0\x17\x88\x37\x51",
#define IMAGE_CHUNK_SIZE (128 * 1024)
#define IMAGE_HASH_BLAKE2S
#define DISPLAY_JUMP_BEHAVIOR DISPLAY_RETAIN_CONTENT
// SHARED WITH MAKEFILE
// common
#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB
#define FLASH_START 0x08000000
// FLASH layout
#define BOARDLOADER_START 0x08000000
#define BOARDLOADER_MAXSIZE (3 * 16 * 1024) // 48 kB
#define BOARDLOADER_SECTOR_START 0
#define BOARDLOADER_SECTOR_END 2
#define BOARDCAPS_START 0x0800BF00
#define BOARDCAPS_MAXSIZE 0x100
#define UNUSED_1_START 0x0800C000
#define UNUSED_1_MAXSIZE (1 * 16 * 1024) // 16 kB
#define UNUSED_1_SECTOR_START 3
#define UNUSED_1_SECTOR_END 3
#define STORAGE_1_START 0x08010000
#define STORAGE_1_MAXSIZE (1 * 64 * 1024) // 64 kB
#define STORAGE_1_SECTOR_START 4
#define STORAGE_1_SECTOR_END 4
#define BOOTLOADER_START 0x08020000
#define BOOTLOADER_MAXSIZE (1 * 128 * 1024) // 128 kB
#define BOOTLOADER_SECTOR_START 5
#define BOOTLOADER_SECTOR_END 5
#define FIRMWARE_START 0x08040000
#define FIRMWARE_MAXSIZE (13 * 128 * 1024) // 1664 kB
#define FIRMWARE_P1_START 0x08040000
#define FIRMWARE_P1_MAXSIZE (6 * 128 * 1024)
#define FIRMWARE_P1_SECTOR_START 6
#define FIRMWARE_P1_SECTOR_END 11
// part of firmware P1
#define KERNEL_START 0x08040000
#define KERNEL_MAXSIZE (4 * 128 * 1024)
#define ASSETS_START 0x08100000
#define ASSETS_MAXSIZE (3 * 16 * 1024) // 48 kB
#define ASSETS_SECTOR_START 12
#define ASSETS_SECTOR_END 14
#define UNUSED_2_START 0x0810C000
#define UNUSED_2_MAXSIZE (1 * 16 * 1024) // 16 kB
#define UNUSED_2_SECTOR_START 15
#define UNUSED_2_SECTOR_END 15
#define STORAGE_2_START 0x08110000
#define STORAGE_2_MAXSIZE (1 * 64 * 1024) // 64 kB
#define STORAGE_2_SECTOR_START 16
#define STORAGE_2_SECTOR_END 16
#define FIRMWARE_P2_START 0x08120000
#define FIRMWARE_P2_MAXSIZE (7 * 128 * 1024)
#define FIRMWARE_P2_SECTOR_START 17
#define FIRMWARE_P2_SECTOR_END 23
// Ram layout - shared boardloader, bootloader, prodtest
#define S_MAIN_STACK_START 0x10000000
#define S_MAIN_STACK_SIZE (16 * 1024)
#define S_FB1_RAM_START 0x10004000
#define S_FB1_RAM_SIZE (0)
#define S_MAIN_RAM_START 0x10004000
#define S_MAIN_RAM_SIZE (48 * 1024 - 0x100)
// RAM layout - kernel
#define K_MAIN_STACK_START 0x10000000
#define K_MAIN_STACK_SIZE (8 * 1024)
#define K_AUX2_RAM_START 0x10002000
#define K_AUX2_RAM_SIZE (40 * 1024)
#define K_FB1_RAM_START 0x1000C000
#define K_FB1_RAM_SIZE (0)
#define K_MAIN_RAM_START 0x1000C000
#define K_MAIN_RAM_SIZE (16 * 1024 - 0x100)
// RAM layout - common
#define BOOTARGS_START 0x1000FF00
#define BOOTARGS_SIZE 0x100
#define DMABUF_RAM_START 0x20000000
#define DMABUF_RAM_SIZE (2 * 1024)
#define AUX1_RAM_START (0x20000800)
#define AUX1_RAM_SIZE (190 * 1024)
// misc
#define CODE_ALIGNMENT 0x200
#define COREAPP_ALIGNMENT 0x200
#endif

View File

@ -0,0 +1,22 @@
{
"header_len": 4608,
"text": "DEV ONLY, DO NOT USE!",
"hw_model": "T2W1",
"expiry": 0,
"version": [0, 0],
"sig_m": 2,
"trust": {
"_reserved": 0,
"_dont_provide_secret": false,
"allow_run_with_secret": false,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,
"delay": 0
},
"pubkeys": [
"e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351",
"d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869",
"772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef"
]
}

View File

@ -0,0 +1 @@
./vendor_satoshilabs.toif

View File

@ -0,0 +1,21 @@
{
"header_len": 4608,
"text": "UNSAFE, FACTORY TEST ONLY",
"hw_model": "T2W1",
"expiry": 0,
"version": [0, 0],
"sig_m": 2,
"trust": {
"_reserved": 0,
"_dont_provide_secret": false,
"allow_run_with_secret": false,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,
"delay": 0
},
"pubkeys": [
"c17d221529b70da08aa42ccb1b2cef773736a7d48434209f6eb16b1b474716d2",
"6622ee8403464acfc2fe1e20311937b115e60771f3ee6e70f22bf2921977e534"
]
}

View File

@ -0,0 +1 @@
vendor_unsafe.toif

View File

@ -0,0 +1,22 @@
{
"header_len": 4608,
"text": "SatoshiLabs",
"hw_model": "T2W1",
"expiry": 0,
"version": [0, 1],
"sig_m": 2,
"trust": {
"_reserved": 0,
"_dont_provide_secret": false,
"allow_run_with_secret": false,
"show_vendor_string": false,
"require_user_click": false,
"red_background": false,
"delay": 0
},
"pubkeys": [
"47fbdc84d8abef44fe6abde8f87b6ead821b7082ec63b9f7cc33dc53bf6c708d",
"9af22a52ab47a93091403612b3d6731a2dfef8a33383048ed7556a20e8b03c81",
"2218c25f8ba70c82eba8ed6a321df209c0a7643d014f33bf9317846f62923830"
]
}

View File

@ -0,0 +1,22 @@
{
"header_len": 4608,
"text": "UNSAFE, DO NOT USE!",
"hw_model": "T2W1",
"expiry": 0,
"version": [0, 1],
"sig_m": 2,
"trust": {
"_reserved": 0,
"_dont_provide_secret": false,
"allow_run_with_secret": false,
"show_vendor_string": true,
"require_user_click": true,
"red_background": true,
"delay": 1
},
"pubkeys": [
"e28a8970753332bd72fef413e6b0b2ef1b4aadda7aa2c141f233712a6876b351",
"d4eec1869fb1b8a4e817516ad5a931557cb56805c3eb16e8f3a803d647df7869",
"772c8a442b7db06e166cfbc1ccbcbcde6f3eba76a4e98ef3ffc519502237d6ef"
]
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
#define BOOTLOADER_MONOTONIC_VERSION 2
#define FIRMWARE_MONOTONIC_VERSION 2

View File

@ -0,0 +1,27 @@
from __future__ import annotations
from typing import Optional
from .t2w1 import configure
def configure_board(
revision: Optional[int | str],
features_wanted: list[str],
env: dict, # type: ignore
defines: list[str | tuple[str, str]],
sources: list[str],
paths: list[str],
):
defines += (("MODEL_HEADER", '"T2W1/model_T2W1.h"'),)
defines += (("VERSIONS_HEADER", '"T2W1/versions.h"'),)
return configure(env, features_wanted, defines, sources, paths)
def get_model_ui() -> str:
return "bolt"
def get_model_ui_conf() -> list[str]:
return []

View File

@ -0,0 +1,129 @@
from __future__ import annotations
from .. import get_hw_model_as_number
from ..stm32f4_common import stm32f4_common_files
def configure(
env: dict,
features_wanted: list[str],
defines: list[str | tuple[str, str]],
sources: list[str],
paths: list[str],
) -> list[str]:
features_available: list[str] = []
board = "T2W1/boards/t2w1.h"
hw_model = get_hw_model_as_number("T2W1")
hw_revision = 0
features_available.append("display_rgb565")
defines += [
"DISPLAY_RGB565",
("USE_RGB_COLORS", "1"),
("DISPLAY_RESX", "240"),
("DISPLAY_RESY", "320"),
]
mcu = "STM32F427xx"
stm32f4_common_files(env, defines, sources, paths)
env.get("ENV")[
"CPU_ASFLAGS"
] = "-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16"
env.get("ENV")[
"CPU_CCFLAGS"
] = "-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 "
env.get("ENV")["RUST_TARGET"] = "thumbv7em-none-eabihf"
defines += [
mcu,
("TREZOR_BOARD", f'"{board}"'),
("HW_MODEL", str(hw_model)),
("HW_REVISION", str(hw_revision)),
("HSE_VALUE", "8000000"),
("USE_HSE", "1"),
]
sources += ["embed/io/display/st-7789/display_nofb.c"]
sources += ["embed/io/display/st-7789/display_driver.c"]
sources += ["embed/io/display/st-7789/display_io.c"]
sources += ["embed/io/display/st-7789/display_panel.c"]
sources += ["embed/io/display/st-7789/panels/lhs200kb-if21.c"]
paths += ["embed/io/display/inc"]
features_available.append("backlight")
defines += [("USE_BACKLIGHT", "1")]
sources += ["embed/io/backlight/stm32/tps61043.c"]
paths += ["embed/io/backlight/inc"]
if "input" in features_wanted:
sources += ["embed/io/i2c_bus/stm32f4/i2c_bus.c"]
sources += ["embed/io/touch/ft6x36/ft6x36.c"]
sources += ["embed/io/touch/ft6x36/panels/lhs200kb-if21.c"]
paths += ["embed/io/i2c_bus/inc"]
paths += ["embed/io/touch/inc"]
features_available.append("touch")
defines += [("USE_TOUCH", "1")]
defines += [("USE_BUTTON", "1")]
sources += ["embed/io/button/stm32/button.c"]
paths += ["embed/io/button/inc"]
features_available.append("button")
defines += [("USE_I2C", "1")]
if "sd_card" in features_wanted:
sources += ["embed/io/sdcard/stm32f4/sdcard.c"]
sources += ["embed/upymod/modtrezorio/ff.c"]
sources += ["embed/upymod/modtrezorio/ffunicode.c"]
sources += [
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c"
]
paths += ["embed/io/sdcard/inc"]
features_available.append("sd_card")
defines += [("USE_SD_CARD", "1")]
if "sbu" in features_wanted:
sources += ["embed/io/sbu/stm32/sbu.c"]
paths += ["embed/io/sbu/inc"]
features_available.append("sbu")
defines += [("USE_SBU", "1")]
if "ble" in features_wanted:
sources += ["embed/io/ble/stm32/ble.c"]
paths += ["embed/io/ble/inc"]
features_available.append("ble")
defines += [("USE_BLE", "1")]
sources += ["embed/io/nrf/stm32f4/nrf.c"]
sources += ["embed/io/nrf/crc8.c"]
paths += ["embed/io/nrf/inc"]
sources += [
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c",
]
if "usb" in features_wanted:
sources += [
"embed/io/usb/stm32/usb_class_hid.c",
"embed/io/usb/stm32/usb_class_vcp.c",
"embed/io/usb/stm32/usb_class_webusb.c",
"embed/io/usb/stm32/usb.c",
"embed/io/usb/stm32/usbd_conf.c",
"embed/io/usb/stm32/usbd_core.c",
"embed/io/usb/stm32/usbd_ctlreq.c",
"embed/io/usb/stm32/usbd_ioreq.c",
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c",
]
features_available.append("usb")
paths += ["embed/io/usb/inc"]
defines += [("USE_USB", "1")]
if "dma2d" in features_wanted:
defines += ["USE_DMA2D"]
sources += ["embed/gfx/bitblt/stm32/dma2d_bitblt.c"]
sources += [
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c"
]
features_available.append("dma2d")
defines += [("USE_PVD", "1")]
return features_available

File diff suppressed because it is too large Load Diff

View File

@ -334,3 +334,58 @@ def _networks_iterator() -> Iterator[NetworkInfoTuple]:
"tSEP", # symbol
"Sepolia", # name
)
if utils.INTERNAL_MODEL == "T2W1":
yield (
1, # chain_id
60, # slip44
"ETH", # symbol
"Ethereum", # name
)
yield (
10, # chain_id
614, # slip44
"ETH", # symbol
"Optimism", # name
)
yield (
56, # chain_id
714, # slip44
"BNB", # symbol
"BNB Smart Chain", # name
)
yield (
61, # chain_id
61, # slip44
"ETC", # symbol
"Ethereum Classic", # name
)
yield (
137, # chain_id
966, # slip44
"POL", # symbol
"Polygon", # name
)
yield (
8453, # chain_id
8453, # slip44
"ETH", # symbol
"Base", # name
)
yield (
17000, # chain_id
1, # slip44
"tHOL", # symbol
"Holesky", # name
)
yield (
42161, # chain_id
9001, # slip44
"ETH", # symbol
"Arbitrum One", # name
)
yield (
11155111, # chain_id
1, # slip44
"tSEP", # symbol
"Sepolia", # name
)

View File

@ -782,3 +782,151 @@ def _token_iterator(chain_id: int) -> Iterator[tuple[bytes, str, int, str]]:
18,
"Wrapped AVAX",
)
if utils.INTERNAL_MODEL == "T2W1":
if chain_id == 1: # eth
yield ( # address, symbol, decimals, name
b"\x7f\xc6\x65\x00\xc8\x4a\x76\xad\x7e\x9c\x93\x43\x7b\xfc\x5a\xc3\x3e\x2d\xda\xe9",
"AAVE",
18,
"Aave",
)
yield ( # address, symbol, decimals, name
b"\x4d\x22\x44\x52\x80\x1a\xce\xd8\xb2\xf0\xae\xbe\x15\x53\x79\xbb\x5d\x59\x43\x81",
"APE",
18,
"ApeCoin",
)
yield ( # address, symbol, decimals, name
b"\xbb\x0e\x17\xef\x65\xf8\x2a\xb0\x18\xd8\xed\xd7\x76\xe8\xdd\x94\x03\x27\xb2\x8b",
"AXS",
18,
"Axie Infinity",
)
yield ( # address, symbol, decimals, name
b"\x4f\xab\xb1\x45\xd6\x46\x52\xa9\x48\xd7\x25\x33\x02\x3f\x6e\x7a\x62\x3c\x7c\x53",
"BUSD",
18,
"Binance USD",
)
yield ( # address, symbol, decimals, name
b"\x35\x06\x42\x4f\x91\xfd\x33\x08\x44\x66\xf4\x02\xd5\xd9\x7f\x05\xf8\xe3\xb4\xaf",
"CHZ",
18,
"Chiliz",
)
yield ( # address, symbol, decimals, name
b"\xa0\xb7\x3e\x1f\xf0\xb8\x09\x14\xab\x6f\xe0\x44\x4e\x65\x84\x8c\x4c\x34\x45\x0b",
"CRO",
8,
"Cronos",
)
yield ( # address, symbol, decimals, name
b"\x6b\x17\x54\x74\xe8\x90\x94\xc4\x4d\xa9\x8b\x95\x4e\xed\xea\xc4\x95\x27\x1d\x0f",
"DAI",
18,
"Dai",
)
yield ( # address, symbol, decimals, name
b"\x85\x3d\x95\x5a\xce\xf8\x22\xdb\x05\x8e\xb8\x50\x59\x11\xed\x77\xf1\x75\xb9\x9e",
"FRAX",
18,
"Frax",
)
yield ( # address, symbol, decimals, name
b"\x2a\xf5\xd2\xad\x76\x74\x11\x91\xd1\x5d\xfe\x7b\xf6\xac\x92\xd4\xbd\x91\x2c\xa3",
"LEO",
18,
"LEO Token",
)
yield ( # address, symbol, decimals, name
b"\x51\x49\x10\x77\x1a\xf9\xca\x65\x6a\xf8\x40\xdf\xf8\x3e\x82\x64\xec\xf9\x86\xca",
"LINK",
18,
"Chainlink",
)
yield ( # address, symbol, decimals, name
b"\x0f\x5d\x2f\xb2\x9f\xb7\xd3\xcf\xee\x44\x4a\x20\x02\x98\xf4\x68\x90\x8c\xc9\x42",
"MANA",
18,
"Decentraland",
)
yield ( # address, symbol, decimals, name
b"\x7d\x1a\xfa\x7b\x71\x8f\xb8\x93\xdb\x30\xa3\xab\xc0\xcf\xc6\x08\xaa\xcf\xeb\xb0",
"MATIC",
18,
"Polygon",
)
yield ( # address, symbol, decimals, name
b"\x75\x23\x1f\x58\xb4\x32\x40\xc9\x71\x8d\xd5\x8b\x49\x67\xc5\x11\x43\x42\xa8\x6c",
"OKB",
18,
"OKB",
)
yield ( # address, symbol, decimals, name
b"\x4a\x22\x0e\x60\x96\xb2\x5e\xad\xb8\x83\x58\xcb\x44\x06\x8a\x32\x48\x25\x46\x75",
"QNT",
18,
"Quant",
)
yield ( # address, symbol, decimals, name
b"\x38\x45\xba\xda\xde\x8e\x6d\xff\x04\x98\x20\x68\x0d\x1f\x14\xbd\x39\x03\xa5\xd0",
"SAND",
18,
"The Sandbox",
)
yield ( # address, symbol, decimals, name
b"\x95\xad\x61\xb0\xa1\x50\xd7\x92\x19\xdc\xf6\x4e\x1e\x6c\xc0\x1f\x0b\x64\xc4\xce",
"SHIB",
18,
"Shiba Inu",
)
yield ( # address, symbol, decimals, name
b"\xae\x7a\xb9\x65\x20\xde\x3a\x18\xe5\xe1\x11\xb5\xea\xab\x09\x53\x12\xd7\xfe\x84",
"STETH",
18,
"Lido Staked Ether",
)
yield ( # address, symbol, decimals, name
b"\x1f\x98\x40\xa8\x5d\x5a\xf5\xbf\x1d\x17\x62\xf9\x25\xbd\xad\xdc\x42\x01\xf9\x84",
"UNI",
18,
"Uniswap",
)
yield ( # address, symbol, decimals, name
b"\xa0\xb8\x69\x91\xc6\x21\x8b\x36\xc1\xd1\x9d\x4a\x2e\x9e\xb0\xce\x36\x06\xeb\x48",
"USDC",
6,
"USD Coin",
)
yield ( # address, symbol, decimals, name
b"\xda\xc1\x7f\x95\x8d\x2e\xe5\x23\xa2\x20\x62\x06\x99\x45\x97\xc1\x3d\x83\x1e\xc7",
"USDT",
6,
"Tether",
)
yield ( # address, symbol, decimals, name
b"\x22\x60\xfa\xc5\xe5\x54\x2a\x77\x3a\xa4\x4f\xbc\xfe\xdf\x7c\x19\x3b\xc2\xc5\x99",
"WBTC",
8,
"Wrapped Bitcoin",
)
yield ( # address, symbol, decimals, name
b"\xa2\xcd\x3d\x43\xc7\x75\x97\x8a\x96\xbd\xbf\x12\xd7\x33\xd5\xa1\xed\x94\xfb\x18",
"XCN",
18,
"Chain",
)
if chain_id == 56: # bnb
yield ( # address, symbol, decimals, name
b"\x0e\xb3\xa7\x05\xfc\x54\x72\x50\x37\xcc\x9e\x00\x8b\xde\xde\x69\x7f\x62\xf3\x35",
"ATOM",
18,
"Cosmos Hub",
)
if chain_id == 137: # matic
yield ( # address, symbol, decimals, name
b"\x2c\x89\xbb\xc9\x2b\xd8\x6f\x80\x75\xd1\xde\xcc\x58\xc7\xf4\xe0\x10\x7f\x28\x6b",
"WAVAX",
18,
"Wrapped AVAX",
)

View File

@ -33,6 +33,7 @@ class Model(Enum):
T1B1 = b"T1B1"
T2B1 = b"T2B1"
T2T1 = b"T2T1"
T2W1 = b"T2W1"
T3B1 = b"T3B1"
T3T1 = b"T3T1"
T3W1 = b"T3W1"
@ -178,6 +179,31 @@ T2T1 = ModelKeys(
firmware_sigs_needed=-1,
)
T2W1 = ModelKeys(
production=True,
boardloader_keys=[
bytes.fromhex(key)
for key in (
"0eb9856be9ba7e972c7f34eac1ed9b6fd0efd172ec00faf0c589759da4ddfba0",
"ac8ab40b32c98655798fd5da5e192be27a22306ea05c6d277cdff4a3f4125cd8",
"ce0fcd12543ef5936cf2804982136707863d17295faced72af171d6e6513ff06",
)
],
boardloader_sigs_needed=2,
bootloader_keys=[
bytes.fromhex(key)
for key in (
"c2c87a49c5a3460977fbb2ec9dfe60f06bd694db8244bd4981fe3b7a26307f3f",
"80d036b08739b846f4cb77593078deb25dc9487aedcf52e30b4fb7cd7024178a",
"b8307a71f552c60a4cbb317ff48b82cdbf6b6bb5f04c920fec7badf017883751",
)
],
bootloader_sigs_needed=2,
firmware_keys=(),
firmware_sigs_needed=-1,
)
TREZOR_CORE_DEV = ModelKeys(
production=False,
boardloader_keys=[
@ -310,6 +336,12 @@ T2T1_HASH_PARAMS = FirmwareHashParameters(
padding_byte=None,
)
T2W1_HASH_PARAMS = FirmwareHashParameters(
hash_function=hashlib.blake2s,
chunk_size=1024 * 128,
padding_byte=None,
)
T3T1_HASH_PARAMS = FirmwareHashParameters(
hash_function=hashlib.sha256,
chunk_size=1024 * 128,
@ -337,6 +369,7 @@ D002_HASH_PARAMS = FirmwareHashParameters(
MODEL_MAP = {
Model.T1B1: LEGACY_V3,
Model.T2T1: T2T1,
Model.T2W1: T2W1,
Model.T2B1: T2B1,
Model.T3T1: T3T1,
Model.T3B1: T3B1,
@ -348,6 +381,7 @@ MODEL_MAP = {
MODEL_MAP_DEV = {
Model.T1B1: LEGACY_V3_DEV,
Model.T2T1: TREZOR_CORE_DEV,
Model.T2W1: TREZOR_CORE_DEV,
Model.T2B1: TREZOR_CORE_DEV,
Model.T3T1: TREZOR_CORE_DEV,
Model.T3B1: TREZOR_CORE_DEV,
@ -359,6 +393,7 @@ MODEL_MAP_DEV = {
MODEL_HASH_PARAMS_MAP = {
Model.T1B1: LEGACY_HASH_PARAMS,
Model.T2T1: T2T1_HASH_PARAMS,
Model.T2W1: T2W1_HASH_PARAMS,
Model.T2B1: T2T1_HASH_PARAMS,
Model.T3T1: T3T1_HASH_PARAMS,
Model.T3B1: T3B1_HASH_PARAMS,

View File

@ -63,6 +63,15 @@ T2T1 = TrezorModel(
default_mapping=mapping.DEFAULT_MAPPING,
)
T2W1 = TrezorModel(
name="T2W1",
internal_name="T2W1",
minimum_version=(2, 1, 0),
vendors=VENDORS,
usb_ids=((0x1209, 0x53C1), (0x1209, 0x53C0)),
default_mapping=mapping.DEFAULT_MAPPING,
)
T2B1 = TrezorModel(
name="Safe 3",
internal_name="T2B1",
@ -127,7 +136,7 @@ TREZOR_SAFE5 = T3T1
TREZOR_DISC1 = DISC1
TREZOR_DISC2 = DISC2
TREZORS = frozenset({T1B1, T2T1, T2B1, T3T1, T3B1, T3W1, DISC1, DISC2})
TREZORS = frozenset({T1B1, T2T1, T2W1, T2B1, T3T1, T3B1, T3W1, DISC1, DISC2})
def by_name(name: str | None) -> TrezorModel | None: