diff --git a/common/defs/support.json b/common/defs/support.json index 348122827c..f6f0aa5752 100644 --- a/common/defs/support.json +++ b/common/defs/support.json @@ -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)" + } } } diff --git a/core/embed/io/nrf/stm32f4/nrf.c b/core/embed/io/nrf/stm32f4/nrf.c new file mode 100644 index 0000000000..b642fcd956 --- /dev/null +++ b/core/embed/io/nrf/stm32f4/nrf.c @@ -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 . + */ + +#ifdef KERNEL_MODE + +#include +#include + +#include +#include +#include +#include +#include + +#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 diff --git a/core/embed/models/T2W1/boards/t2w1.h b/core/embed/models/T2W1/boards/t2w1.h new file mode 100644 index 0000000000..d178d61a42 --- /dev/null +++ b/core/embed/models/T2W1/boards/t2w1.h @@ -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 diff --git a/core/embed/models/T2W1/bootloaders/bootloader_T2W1.bin b/core/embed/models/T2W1/bootloaders/bootloader_T2W1.bin new file mode 100644 index 0000000000..4302d3451c Binary files /dev/null and b/core/embed/models/T2W1/bootloaders/bootloader_T2W1.bin differ diff --git a/core/embed/models/T2W1/config.mk b/core/embed/models/T2W1/config.mk new file mode 100644 index 0000000000..a93e37f112 --- /dev/null +++ b/core/embed/models/T2W1/config.mk @@ -0,0 +1,3 @@ +MCU = STM32F4 +OPENOCD_TARGET = target/stm32f4x.cfg +LAYOUT_FEATURE = layout_bolt diff --git a/core/embed/models/T2W1/memory.ld b/core/embed/models/T2W1/memory.ld new file mode 100644 index 0000000000..1614fb601e --- /dev/null +++ b/core/embed/models/T2W1/memory.ld @@ -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; diff --git a/core/embed/models/T2W1/model_T2W1.h b/core/embed/models/T2W1/model_T2W1.h new file mode 100644 index 0000000000..d8f2f295f0 --- /dev/null +++ b/core/embed/models/T2W1/model_T2W1.h @@ -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 diff --git a/core/embed/models/T2W1/vendorheader/vendor_dev_DO_NOT_SIGN.json b/core/embed/models/T2W1/vendorheader/vendor_dev_DO_NOT_SIGN.json new file mode 100644 index 0000000000..c791aab382 --- /dev/null +++ b/core/embed/models/T2W1/vendorheader/vendor_dev_DO_NOT_SIGN.json @@ -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" + ] +} diff --git a/core/embed/models/T2W1/vendorheader/vendor_dev_DO_NOT_SIGN.toif b/core/embed/models/T2W1/vendorheader/vendor_dev_DO_NOT_SIGN.toif new file mode 120000 index 0000000000..3dc5d9734f --- /dev/null +++ b/core/embed/models/T2W1/vendorheader/vendor_dev_DO_NOT_SIGN.toif @@ -0,0 +1 @@ +./vendor_satoshilabs.toif \ No newline at end of file diff --git a/core/embed/models/T2W1/vendorheader/vendor_prodtest.json b/core/embed/models/T2W1/vendorheader/vendor_prodtest.json new file mode 100644 index 0000000000..fe8a356749 --- /dev/null +++ b/core/embed/models/T2W1/vendorheader/vendor_prodtest.json @@ -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" + ] +} diff --git a/core/embed/models/T2W1/vendorheader/vendor_prodtest.toif b/core/embed/models/T2W1/vendorheader/vendor_prodtest.toif new file mode 120000 index 0000000000..22ac5e8400 --- /dev/null +++ b/core/embed/models/T2W1/vendorheader/vendor_prodtest.toif @@ -0,0 +1 @@ +vendor_unsafe.toif \ No newline at end of file diff --git a/core/embed/models/T2W1/vendorheader/vendor_satoshilabs.json b/core/embed/models/T2W1/vendorheader/vendor_satoshilabs.json new file mode 100644 index 0000000000..32d01bbebc --- /dev/null +++ b/core/embed/models/T2W1/vendorheader/vendor_satoshilabs.json @@ -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" + ] +} diff --git a/core/embed/models/T2W1/vendorheader/vendor_satoshilabs.toif b/core/embed/models/T2W1/vendorheader/vendor_satoshilabs.toif new file mode 100644 index 0000000000..231990e5a2 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendor_satoshilabs.toif differ diff --git a/core/embed/models/T2W1/vendorheader/vendor_unsafe.json b/core/embed/models/T2W1/vendorheader/vendor_unsafe.json new file mode 100644 index 0000000000..89d987f8a1 --- /dev/null +++ b/core/embed/models/T2W1/vendorheader/vendor_unsafe.json @@ -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" + ] +} diff --git a/core/embed/models/T2W1/vendorheader/vendor_unsafe.toif b/core/embed/models/T2W1/vendorheader/vendor_unsafe.toif new file mode 100644 index 0000000000..8c25f0ddd9 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendor_unsafe.toif differ diff --git a/core/embed/models/T2W1/vendorheader/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin b/core/embed/models/T2W1/vendorheader/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin new file mode 100644 index 0000000000..1a04ecaab3 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin differ diff --git a/core/embed/models/T2W1/vendorheader/vendorheader_dev_DO_NOT_SIGN_unsigned.bin b/core/embed/models/T2W1/vendorheader/vendorheader_dev_DO_NOT_SIGN_unsigned.bin new file mode 100644 index 0000000000..a819463ca7 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendorheader_dev_DO_NOT_SIGN_unsigned.bin differ diff --git a/core/embed/models/T2W1/vendorheader/vendorheader_prodtest_unsigned.bin b/core/embed/models/T2W1/vendorheader/vendorheader_prodtest_unsigned.bin new file mode 100644 index 0000000000..c45817eef1 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendorheader_prodtest_unsigned.bin differ diff --git a/core/embed/models/T2W1/vendorheader/vendorheader_satoshilabs_unsigned.bin b/core/embed/models/T2W1/vendorheader/vendorheader_satoshilabs_unsigned.bin new file mode 100644 index 0000000000..2212dcb3d0 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendorheader_satoshilabs_unsigned.bin differ diff --git a/core/embed/models/T2W1/vendorheader/vendorheader_unsafe_signed_dev.bin b/core/embed/models/T2W1/vendorheader/vendorheader_unsafe_signed_dev.bin new file mode 100644 index 0000000000..aa79ad8f70 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendorheader_unsafe_signed_dev.bin differ diff --git a/core/embed/models/T2W1/vendorheader/vendorheader_unsafe_unsigned.bin b/core/embed/models/T2W1/vendorheader/vendorheader_unsafe_unsigned.bin new file mode 100644 index 0000000000..30dba7fbc6 Binary files /dev/null and b/core/embed/models/T2W1/vendorheader/vendorheader_unsafe_unsigned.bin differ diff --git a/core/embed/models/T2W1/versions.h b/core/embed/models/T2W1/versions.h new file mode 100644 index 0000000000..546ca6a16b --- /dev/null +++ b/core/embed/models/T2W1/versions.h @@ -0,0 +1,3 @@ + +#define BOOTLOADER_MONOTONIC_VERSION 2 +#define FIRMWARE_MONOTONIC_VERSION 2 diff --git a/core/site_scons/models/T2W1/__init__.py b/core/site_scons/models/T2W1/__init__.py new file mode 100644 index 0000000000..c99f655eab --- /dev/null +++ b/core/site_scons/models/T2W1/__init__.py @@ -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 [] diff --git a/core/site_scons/models/T2W1/t2w1.py b/core/site_scons/models/T2W1/t2w1.py new file mode 100644 index 0000000000..af86980c55 --- /dev/null +++ b/core/site_scons/models/T2W1/t2w1.py @@ -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 diff --git a/core/src/apps/common/coininfo.py b/core/src/apps/common/coininfo.py index 602f2ada3f..f8ec8d9acc 100644 --- a/core/src/apps/common/coininfo.py +++ b/core/src/apps/common/coininfo.py @@ -7040,4 +7040,1341 @@ def by_name(name: str) -> CoinInfo: None, # confidential_assets ) raise ValueError # Unknown coin name + if utils.INTERNAL_MODEL == "T2W1": + if name == "Bitcoin": + return CoinInfo( + name, # coin_name + "BTC", # coin_shortcut + 8, # decimals + 0, # address_type + 5, # address_type_p2sh + 2000000, # maxfee_kb + "Bitcoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0295b43f, # xpub_magic_multisig_segwit_p2sh + 0x02aa7ed3, # xpub_magic_multisig_segwit_native + "bc", # bech32_prefix + None, # cashaddr_prefix + 0, # slip44 + True, # segwit + True, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Regtest": + return CoinInfo( + name, # coin_name + "REGTEST", # coin_shortcut + 8, # decimals + 111, # address_type + 196, # address_type_p2sh + 10000000, # maxfee_kb + "Bitcoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x024289ef, # xpub_magic_multisig_segwit_p2sh + 0x02575483, # xpub_magic_multisig_segwit_native + "bcrt", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + True, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Testnet": + return CoinInfo( + name, # coin_name + "TEST", # coin_shortcut + 8, # decimals + 111, # address_type + 196, # address_type_p2sh + 10000000, # maxfee_kb + "Bitcoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x024289ef, # xpub_magic_multisig_segwit_p2sh + 0x02575483, # xpub_magic_multisig_segwit_native + "tb", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + True, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if not utils.BITCOIN_ONLY: + if name == "Actinium": + return CoinInfo( + name, # coin_name + "ACM", # coin_shortcut + 8, # decimals + 53, # address_type + 55, # address_type_p2sh + 320000000000, # maxfee_kb + "Actinium Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "acm", # bech32_prefix + None, # cashaddr_prefix + 228, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Axe": + return CoinInfo( + name, # coin_name + "AXE", # coin_shortcut + 8, # decimals + 55, # address_type + 16, # address_type_p2sh + 21000000000, # maxfee_kb + "DarkCoin Signed Message:\n", # signed_message_header + 0x02fe52cc, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 4242, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Bcash": + return CoinInfo( + name, # coin_name + "BCH", # coin_shortcut + 8, # decimals + 0, # address_type + 5, # address_type_p2sh + 14000000, # maxfee_kb + "Bitcoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + "bitcoincash", # cashaddr_prefix + 145, # slip44 + False, # segwit + False, # taproot + 0, # fork_id + True, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Bcash Testnet": + return CoinInfo( + name, # coin_name + "TBCH", # coin_shortcut + 8, # decimals + 111, # address_type + 196, # address_type_p2sh + 10000000, # maxfee_kb + "Bitcoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + "bchtest", # cashaddr_prefix + 1, # slip44 + False, # segwit + False, # taproot + 0, # fork_id + True, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Bprivate": + return CoinInfo( + name, # coin_name + "BTCP", # coin_shortcut + 8, # decimals + 4901, # address_type + 5039, # address_type_p2sh + 32000000000, # maxfee_kb + "BitcoinPrivate Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 183, # slip44 + False, # segwit + False, # taproot + 42, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Bitcore": + return CoinInfo( + name, # coin_name + "BTX", # coin_shortcut + 8, # decimals + 3, # address_type + 125, # address_type_p2sh + 14000000000, # maxfee_kb + "BitCore Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "btx", # bech32_prefix + None, # cashaddr_prefix + 160, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "CPUchain": + return CoinInfo( + name, # coin_name + "CPU", # coin_shortcut + 8, # decimals + 28, # address_type + 30, # address_type_p2sh + 8700000000000, # maxfee_kb + "CPUchain Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "cpu", # bech32_prefix + None, # cashaddr_prefix + 363, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Crown": + return CoinInfo( + name, # coin_name + "CRW", # coin_shortcut + 8, # decimals + 95495, # address_type + 95473, # address_type_p2sh + 52000000000, # maxfee_kb + "Crown Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 72, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Dogecoin": + return CoinInfo( + name, # coin_name + "DOGE", # coin_shortcut + 8, # decimals + 30, # address_type + 22, # address_type_p2sh + 1200000000000, # maxfee_kb + "Dogecoin Signed Message:\n", # signed_message_header + 0x02facafd, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 3, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Elements": + return CoinInfo( + name, # coin_name + "ELEMENTS", # coin_shortcut + 8, # decimals + 235, # address_type + 75, # address_type_p2sh + 10000000, # maxfee_kb + "Bitcoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x043587cf, # xpub_magic_multisig_segwit_p2sh + 0x043587cf, # xpub_magic_multisig_segwit_native + "ert", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + {'address_prefix': 4, 'blech32_prefix': 'el'}, # confidential_assets + ) + if name == "Feathercoin": + return CoinInfo( + name, # coin_name + "FTC", # coin_shortcut + 8, # decimals + 14, # address_type + 5, # address_type_p2sh + 390000000000, # maxfee_kb + "Feathercoin Signed Message:\n", # signed_message_header + 0x0488bc26, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488bc26, # xpub_magic_multisig_segwit_p2sh + 0x0488bc26, # xpub_magic_multisig_segwit_native + "fc", # bech32_prefix + None, # cashaddr_prefix + 8, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Firo": + return CoinInfo( + name, # coin_name + "FIRO", # coin_shortcut + 8, # decimals + 82, # address_type + 7, # address_type_p2sh + 640000000, # maxfee_kb + "Zcoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 136, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Firo Testnet": + return CoinInfo( + name, # coin_name + "tFIRO", # coin_shortcut + 8, # decimals + 65, # address_type + 178, # address_type_p2sh + 1000000, # maxfee_kb + "Zcoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Florincoin": + return CoinInfo( + name, # coin_name + "FLO", # coin_shortcut + 8, # decimals + 35, # address_type + 94, # address_type_p2sh + 78000000000, # maxfee_kb + "Florincoin Signed Message:\n", # signed_message_header + 0x00174921, # xpub_magic + 0x01b26ef6, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x00174921, # xpub_magic_multisig_segwit_p2sh + 0x00174921, # xpub_magic_multisig_segwit_native + "flo", # bech32_prefix + None, # cashaddr_prefix + 216, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Fujicoin": + return CoinInfo( + name, # coin_name + "FJC", # coin_shortcut + 8, # decimals + 36, # address_type + 16, # address_type_p2sh + 35000000000000, # maxfee_kb + "FujiCoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0295b43f, # xpub_magic_multisig_segwit_p2sh + 0x02aa7ed3, # xpub_magic_multisig_segwit_native + "fc", # bech32_prefix + None, # cashaddr_prefix + 75, # slip44 + True, # segwit + True, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Groestlcoin": + return CoinInfo( + name, # coin_name + "GRS", # coin_shortcut + 8, # decimals + 36, # address_type + 5, # address_type_p2sh + 16000000000, # maxfee_kb + "GroestlCoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "grs", # bech32_prefix + None, # cashaddr_prefix + 17, # slip44 + True, # segwit + True, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1-groestl', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Groestlcoin Testnet": + return CoinInfo( + name, # coin_name + "tGRS", # coin_shortcut + 8, # decimals + 111, # address_type + 196, # address_type_p2sh + 100000, # maxfee_kb + "GroestlCoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x043587cf, # xpub_magic_multisig_segwit_p2sh + 0x043587cf, # xpub_magic_multisig_segwit_native + "tgrs", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + True, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1-groestl', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Komodo": + return CoinInfo( + name, # coin_name + "KMD", # coin_shortcut + 8, # decimals + 60, # address_type + 85, # address_type_p2sh + 4800000000, # maxfee_kb + "Komodo Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 141, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + True, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + True, # overwintered + None, # confidential_assets + ) + if name == "Koto": + return CoinInfo( + name, # coin_name + "KOTO", # coin_shortcut + 8, # decimals + 6198, # address_type + 6203, # address_type_p2sh + 1000000, # maxfee_kb + "Koto Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 510, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + True, # overwintered + None, # confidential_assets + ) + if name == "Litecoin": + return CoinInfo( + name, # coin_name + "LTC", # coin_shortcut + 8, # decimals + 48, # address_type + 50, # address_type_p2sh + 67000000, # maxfee_kb + "Litecoin Signed Message:\n", # signed_message_header + 0x019da462, # xpub_magic + 0x01b26ef6, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x019da462, # xpub_magic_multisig_segwit_p2sh + 0x019da462, # xpub_magic_multisig_segwit_native + "ltc", # bech32_prefix + None, # cashaddr_prefix + 2, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Litecoin Testnet": + return CoinInfo( + name, # coin_name + "tLTC", # coin_shortcut + 8, # decimals + 111, # address_type + 58, # address_type_p2sh + 40000000, # maxfee_kb + "Litecoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x043587cf, # xpub_magic_multisig_segwit_p2sh + 0x043587cf, # xpub_magic_multisig_segwit_native + "tltc", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Monacoin": + return CoinInfo( + name, # coin_name + "MONA", # coin_shortcut + 8, # decimals + 50, # address_type + 55, # address_type_p2sh + 2100000000, # maxfee_kb + "Monacoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "mona", # bech32_prefix + None, # cashaddr_prefix + 22, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Peercoin": + return CoinInfo( + name, # coin_name + "PPC", # coin_shortcut + 6, # decimals + 55, # address_type + 117, # address_type_p2sh + 13000000000, # maxfee_kb + "Peercoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "pc", # bech32_prefix + None, # cashaddr_prefix + 6, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + True, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Peercoin Testnet": + return CoinInfo( + name, # coin_name + "tPPC", # coin_shortcut + 6, # decimals + 111, # address_type + 196, # address_type_p2sh + 2000000, # maxfee_kb + "Peercoin Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x043587cf, # xpub_magic_multisig_segwit_p2sh + 0x043587cf, # xpub_magic_multisig_segwit_native + "tpc", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + True, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Primecoin": + return CoinInfo( + name, # coin_name + "XPM", # coin_shortcut + 8, # decimals + 23, # address_type + 83, # address_type_p2sh + 89000000000, # maxfee_kb + "Primecoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 24, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Qtum": + return CoinInfo( + name, # coin_name + "QTUM", # coin_shortcut + 8, # decimals + 58, # address_type + 50, # address_type_p2sh + 1000000000, # maxfee_kb + "Qtum Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "qc", # bech32_prefix + None, # cashaddr_prefix + 2301, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Qtum Testnet": + return CoinInfo( + name, # coin_name + "tQTUM", # coin_shortcut + 8, # decimals + 120, # address_type + 110, # address_type_p2sh + 40000000, # maxfee_kb + "Qtum Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + 0x044a5262, # xpub_magic_segwit_p2sh + 0x045f1cf6, # xpub_magic_segwit_native + 0x043587cf, # xpub_magic_multisig_segwit_p2sh + 0x043587cf, # xpub_magic_multisig_segwit_native + "tq", # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Ravencoin": + return CoinInfo( + name, # coin_name + "RVN", # coin_shortcut + 8, # decimals + 60, # address_type + 122, # address_type_p2sh + 170000000000, # maxfee_kb + "Raven Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 175, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Ravencoin Testnet": + return CoinInfo( + name, # coin_name + "tRVN", # coin_shortcut + 8, # decimals + 111, # address_type + 196, # address_type_p2sh + 170000000000, # maxfee_kb + "Raven Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Ritocoin": + return CoinInfo( + name, # coin_name + "RITO", # coin_shortcut + 8, # decimals + 25, # address_type + 105, # address_type_p2sh + 39000000000000, # maxfee_kb + "Rito Signed Message:\n", # signed_message_header + 0x0534e7ca, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 19169, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "SmartCash": + return CoinInfo( + name, # coin_name + "SMART", # coin_shortcut + 8, # decimals + 63, # address_type + 18, # address_type_p2sh + 780000000000, # maxfee_kb + "SmartCash Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 224, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1-smart', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "SmartCash Testnet": + return CoinInfo( + name, # coin_name + "tSMART", # coin_shortcut + 8, # decimals + 65, # address_type + 21, # address_type_p2sh + 1000000, # maxfee_kb + "SmartCash Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1-smart', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Stakenet": + return CoinInfo( + name, # coin_name + "XSN", # coin_shortcut + 8, # decimals + 76, # address_type + 16, # address_type_p2sh + 11000000000, # maxfee_kb + "DarkCoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "xc", # bech32_prefix + None, # cashaddr_prefix + 199, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Syscoin": + return CoinInfo( + name, # coin_name + "SYS", # coin_shortcut + 8, # decimals + 63, # address_type + 5, # address_type_p2sh + 42000000000, # maxfee_kb + "Syscoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "sys", # bech32_prefix + None, # cashaddr_prefix + 57, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Unobtanium": + return CoinInfo( + name, # coin_name + "UNO", # coin_shortcut + 8, # decimals + 130, # address_type + 30, # address_type_p2sh + 53000000, # maxfee_kb + "Unobtanium Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 92, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "VIPSTARCOIN": + return CoinInfo( + name, # coin_name + "VIPS", # coin_shortcut + 8, # decimals + 70, # address_type + 50, # address_type_p2sh + 140000000000000, # maxfee_kb + "VIPSTARCOIN Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "vips", # bech32_prefix + None, # cashaddr_prefix + 1919, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Verge": + return CoinInfo( + name, # coin_name + "XVG", # coin_shortcut + 6, # decimals + 30, # address_type + 33, # address_type_p2sh + 550000000000, # maxfee_kb + "Name: Dogecoin Dark\n", # signed_message_header + 0x022d2533, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 77, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + True, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Viacoin": + return CoinInfo( + name, # coin_name + "VIA", # coin_shortcut + 8, # decimals + 71, # address_type + 33, # address_type_p2sh + 14000000000, # maxfee_kb + "Viacoin Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + 0x049d7cb2, # xpub_magic_segwit_p2sh + 0x04b24746, # xpub_magic_segwit_native + 0x0488b21e, # xpub_magic_multisig_segwit_p2sh + 0x0488b21e, # xpub_magic_multisig_segwit_native + "via", # bech32_prefix + None, # cashaddr_prefix + 14, # slip44 + True, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "ZCore": + return CoinInfo( + name, # coin_name + "ZCR", # coin_shortcut + 8, # decimals + 142, # address_type + 145, # address_type_p2sh + 170000000000, # maxfee_kb + "DarkNet Signed Message:\n", # signed_message_header + 0x04b24746, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 428, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Zcash": + return CoinInfo( + name, # coin_name + "ZEC", # coin_shortcut + 8, # decimals + 7352, # address_type + 7357, # address_type_p2sh + 51000000, # maxfee_kb + "Zcash Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 133, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + True, # overwintered + None, # confidential_assets + ) + if name == "Zcash Testnet": + return CoinInfo( + name, # coin_name + "TAZ", # coin_shortcut + 8, # decimals + 7461, # address_type + 7354, # address_type_p2sh + 10000000, # maxfee_kb + "Zcash Signed Message:\n", # signed_message_header + 0x043587cf, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 1, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + True, # extra_data + False, # timestamp + True, # overwintered + None, # confidential_assets + ) + if name == "Ecash": + return CoinInfo( + name, # coin_name + "XEC", # coin_shortcut + 2, # decimals + 0, # address_type + 5, # address_type_p2sh + 14000000, # maxfee_kb + "eCash Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + "ecash", # cashaddr_prefix + 899, # slip44 + False, # segwit + False, # taproot + 0, # fork_id + True, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + if name == "Brhodium": + return CoinInfo( + name, # coin_name + "XRC", # coin_shortcut + 8, # decimals + 61, # address_type + 123, # address_type_p2sh + 1000000000, # maxfee_kb + "BitCoin Rhodium Signed Message:\n", # signed_message_header + 0x0488b21e, # xpub_magic + None, # xpub_magic_segwit_p2sh + None, # xpub_magic_segwit_native + None, # xpub_magic_multisig_segwit_p2sh + None, # xpub_magic_multisig_segwit_native + None, # bech32_prefix + None, # cashaddr_prefix + 10291, # slip44 + False, # segwit + False, # taproot + None, # fork_id + False, # force_bip143 + False, # decred + False, # negative_fee + 'secp256k1', # curve_name + False, # extra_data + False, # timestamp + False, # overwintered + None, # confidential_assets + ) + raise ValueError # Unknown coin name raise ValueError # Unknown model diff --git a/core/src/apps/ethereum/networks.py b/core/src/apps/ethereum/networks.py index 9c00d1a86f..57d6824e57 100644 --- a/core/src/apps/ethereum/networks.py +++ b/core/src/apps/ethereum/networks.py @@ -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 + ) diff --git a/core/src/apps/ethereum/tokens.py b/core/src/apps/ethereum/tokens.py index c83e548899..3174074219 100644 --- a/core/src/apps/ethereum/tokens.py +++ b/core/src/apps/ethereum/tokens.py @@ -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", + ) diff --git a/python/src/trezorlib/firmware/models.py b/python/src/trezorlib/firmware/models.py index a8fa08a988..080dd07203 100644 --- a/python/src/trezorlib/firmware/models.py +++ b/python/src/trezorlib/firmware/models.py @@ -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, diff --git a/python/src/trezorlib/models.py b/python/src/trezorlib/models.py index e7a4d9ea75..a5f3236c75 100644 --- a/python/src/trezorlib/models.py +++ b/python/src/trezorlib/models.py @@ -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: