mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-29 12:18:51 +00:00
feat(core): change internal communication with NRF to SPI only
[no changelog]
This commit is contained in:
parent
a9103763ec
commit
3fe0c90c1c
@ -22,13 +22,14 @@
|
||||
#include <trezor_types.h>
|
||||
|
||||
// maximum data size allowed to be sent
|
||||
#define NRF_MAX_TX_DATA_SIZE (64)
|
||||
#define NRF_MAX_TX_DATA_SIZE (244)
|
||||
|
||||
typedef enum {
|
||||
NRF_SERVICE_BLE = 0,
|
||||
NRF_SERVICE_BLE_MANAGER = 1,
|
||||
NRF_SERVICE_MANAGEMENT = 2,
|
||||
NRF_SERVICE_PRODTEST = 3,
|
||||
NRF_SERVICE_IDLE = 4,
|
||||
|
||||
NRF_SERVICE_CNT // Number of services
|
||||
} nrf_service_id_t;
|
||||
@ -91,6 +92,7 @@ bool nrf_abort_msg(int32_t id);
|
||||
// Blocking function.
|
||||
bool nrf_get_info(nrf_info_t *info);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TEST only functions
|
||||
|
||||
// Test SPI communication with NRF
|
||||
@ -99,11 +101,11 @@ bool nrf_test_spi_comm(void);
|
||||
// Test UART communication with NRF
|
||||
bool nrf_test_uart_comm(void);
|
||||
|
||||
// Test reboot to bootloader
|
||||
bool nrf_test_reboot_to_bootloader(void);
|
||||
|
||||
bool nrf_test_gpio_trz_ready(void);
|
||||
// Test reset pin
|
||||
bool nrf_test_reset(void);
|
||||
|
||||
// Test GPIO stay in bootloader
|
||||
bool nrf_test_gpio_stay_in_bld(void);
|
||||
|
||||
bool nrf_test_gpio_reserved(void);
|
||||
// Test GPIO wakeup
|
||||
bool nrf_test_gpio_wakeup(void);
|
||||
|
@ -30,19 +30,24 @@ typedef enum {
|
||||
MGMT_RESP_INFO = 0,
|
||||
} management_resp_t;
|
||||
|
||||
void nrf_start(void);
|
||||
void nrf_stop(void);
|
||||
|
||||
void nrf_dfu_comm_send(const uint8_t *data, uint32_t len);
|
||||
uint32_t nrf_dfu_comm_receive(uint8_t *data, uint32_t len);
|
||||
|
||||
void nrf_int_send(const uint8_t *data, uint32_t len);
|
||||
uint32_t nrf_int_receive(uint8_t *data, uint32_t len);
|
||||
|
||||
bool nrf_firmware_running(void);
|
||||
|
||||
bool nrf_reboot(void);
|
||||
bool nrf_reboot_to_bootloader(void);
|
||||
|
||||
void nrf_signal_running(void);
|
||||
void nrf_signal_off(void);
|
||||
void nrf_signal_data_ready(void);
|
||||
void nrf_signal_no_data(void);
|
||||
|
||||
bool nrf_force_reset(void);
|
||||
void nrf_stay_in_bootloader(bool set);
|
||||
bool nrf_in_reserved_gpio(void);
|
||||
bool nrf_in_wakeup(void);
|
||||
|
||||
void nrf_uart_send(uint8_t data);
|
||||
uint8_t nrf_uart_get_received(void);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <sys/irq.h>
|
||||
#include <sys/mpu.h>
|
||||
#include <sys/systick.h>
|
||||
#include <sys/systimer.h>
|
||||
#include <util/tsqueue.h>
|
||||
|
||||
#include "../crc8.h"
|
||||
@ -35,26 +36,22 @@
|
||||
|
||||
typedef struct {
|
||||
uint8_t service_id;
|
||||
uint8_t msg_len;
|
||||
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 SPI_OVERHEAD_SIZE (sizeof(spi_packet_t) - MAX_SPI_DATA_SIZE)
|
||||
#define SPI_HEADER_SIZE (SPI_OVERHEAD_SIZE - 1)
|
||||
|
||||
#define TX_QUEUE_SIZE (8)
|
||||
|
||||
#define START_BYTE (0xA0)
|
||||
|
||||
#define CTS_PULSE_RESEND_PERIOD_US 2000
|
||||
|
||||
typedef struct {
|
||||
uart_packet_t packet;
|
||||
spi_packet_t packet;
|
||||
nrf_tx_callback_t callback;
|
||||
void *context;
|
||||
} nrf_tx_request_t;
|
||||
@ -69,13 +66,14 @@ typedef struct {
|
||||
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;
|
||||
uint8_t urt_rx_byte;
|
||||
uint8_t urt_tx_byte;
|
||||
bool urt_tx_complete;
|
||||
bool urt_rx_complete;
|
||||
|
||||
SPI_HandleTypeDef spi;
|
||||
DMA_HandleTypeDef spi_dma;
|
||||
DMA_HandleTypeDef spi_rx_dma;
|
||||
DMA_HandleTypeDef spi_tx_dma;
|
||||
spi_packet_t long_rx_buffer;
|
||||
|
||||
bool comm_running;
|
||||
@ -85,38 +83,41 @@ typedef struct {
|
||||
|
||||
bool info_valid;
|
||||
nrf_info_t info;
|
||||
|
||||
systimer_t *timer;
|
||||
bool pending_spi_transaction;
|
||||
|
||||
} nrf_driver_t;
|
||||
|
||||
static nrf_driver_t g_nrf_driver = {0};
|
||||
|
||||
static void nrf_start(void) {
|
||||
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);
|
||||
|
||||
static void nrf_complete_current_request(nrf_driver_t *drv,
|
||||
nrf_status_t status) {
|
||||
if (drv->tx_request_id >= 0) {
|
||||
if (drv->tx_request.callback != NULL) {
|
||||
drv->tx_request.callback(NRF_STATUS_ERROR, drv->tx_request.context);
|
||||
drv->tx_request.callback(status, drv->tx_request.context);
|
||||
}
|
||||
|
||||
drv->rx_idx = 0;
|
||||
drv->rx_len = 0;
|
||||
drv->tx_request_id = -1;
|
||||
memset(&drv->tx_request, 0, sizeof(nrf_tx_request_t));
|
||||
}
|
||||
}
|
||||
|
||||
static void nrf_abort_comm(nrf_driver_t *drv) {
|
||||
HAL_SPI_Abort(&drv->spi);
|
||||
drv->pending_spi_transaction = false;
|
||||
|
||||
nrf_complete_current_request(drv, NRF_STATUS_ERROR);
|
||||
|
||||
while (tsqueue_dequeue(&drv->tx_queue, (uint8_t *)&drv->tx_request,
|
||||
sizeof(nrf_tx_request_t), NULL, NULL)) {
|
||||
@ -130,17 +131,16 @@ static void nrf_abort_urt_comm(nrf_driver_t *drv) {
|
||||
tsqueue_reset(&drv->tx_queue);
|
||||
}
|
||||
|
||||
static void nrf_stop(void) {
|
||||
void nrf_stop(void) {
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
nrf_signal_off();
|
||||
// nrf_signal_off();
|
||||
irq_key_t key = irq_lock();
|
||||
drv->comm_running = false;
|
||||
HAL_SPI_DMAStop(&drv->spi);
|
||||
nrf_abort_urt_comm(drv);
|
||||
nrf_abort_comm(drv);
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
@ -160,6 +160,16 @@ void nrf_management_rx_cb(const uint8_t *data, uint32_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
void nrf_timer_callback(void *context) {
|
||||
nrf_driver_t *drv = (nrf_driver_t *)context;
|
||||
if (drv->initialized && drv->pending_spi_transaction) {
|
||||
nrf_signal_data_ready();
|
||||
systick_delay_us(1);
|
||||
nrf_signal_no_data();
|
||||
systimer_set(drv->timer, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
void nrf_init(void) {
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
|
||||
@ -190,19 +200,19 @@ void nrf_init(void) {
|
||||
GPIO_InitStructure.Pin = NRF_OUT_RESET_PIN;
|
||||
HAL_GPIO_Init(NRF_OUT_RESET_PORT, &GPIO_InitStructure);
|
||||
|
||||
NRF_IN_GPIO0_CLK_ENA();
|
||||
NRF_IN_WAKEUP_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);
|
||||
GPIO_InitStructure.Pin = NRF_IN_WAKEUP_PIN;
|
||||
HAL_GPIO_Init(NRF_IN_WAKEUP_PORT, &GPIO_InitStructure);
|
||||
|
||||
NRF_IN_FW_RUNNING_CLK_ENA();
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
|
||||
NRF_OUT_SPI_READY_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_IN_FW_RUNNING_PIN;
|
||||
HAL_GPIO_Init(NRF_IN_FW_RUNNING_PORT, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.Pin = NRF_OUT_SPI_READY_PIN;
|
||||
HAL_GPIO_Init(NRF_OUT_SPI_READY_PORT, &GPIO_InitStructure);
|
||||
|
||||
NRF_OUT_STAY_IN_BLD_CLK_ENA();
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
@ -211,12 +221,22 @@ void nrf_init(void) {
|
||||
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;
|
||||
NRF_IN_SPI_REQUEST_CLK_ENA();
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
|
||||
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);
|
||||
GPIO_InitStructure.Pin = NRF_IN_SPI_REQUEST_PIN;
|
||||
HAL_GPIO_Init(NRF_IN_SPI_REQUEST_PORT, &GPIO_InitStructure);
|
||||
|
||||
EXTI_HandleTypeDef EXTI_Handle = {0};
|
||||
EXTI_ConfigTypeDef EXTI_Config = {0};
|
||||
EXTI_Config.GPIOSel = NRF_EXTI_INTERRUPT_GPIOSEL;
|
||||
EXTI_Config.Line = NRF_EXTI_INTERRUPT_LINE;
|
||||
EXTI_Config.Mode = EXTI_MODE_INTERRUPT;
|
||||
EXTI_Config.Trigger = EXTI_TRIGGER_RISING;
|
||||
HAL_EXTI_SetConfigLine(&EXTI_Handle, &EXTI_Config);
|
||||
NVIC_SetPriority(NRF_EXTI_INTERRUPT_NUM, IRQ_PRI_NORMAL);
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(NRF_EXTI_INTERRUPT_PIN);
|
||||
|
||||
// UART PINS
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
@ -224,12 +244,14 @@ void nrf_init(void) {
|
||||
GPIO_InitStructure.Alternate = GPIO_AF7_USART3;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
drv->urt.Init.Mode = UART_MODE_TX_RX;
|
||||
drv->urt.Init.BaudRate = 1000000;
|
||||
@ -239,37 +261,8 @@ void nrf_init(void) {
|
||||
drv->urt.Init.StopBits = UART_STOPBITS_1;
|
||||
drv->urt.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
drv->urt.Instance = USART3;
|
||||
drv->urt.hdmatx = &drv->urt_tx_dma;
|
||||
|
||||
drv->urt_tx_dma.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
drv->urt_tx_dma.Init.Mode = DMA_NORMAL;
|
||||
drv->urt_tx_dma.Instance = GPDMA1_Channel1;
|
||||
drv->urt_tx_dma.Init.Request = GPDMA1_REQUEST_USART3_TX;
|
||||
drv->urt_tx_dma.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
drv->urt_tx_dma.Init.SrcInc = DMA_SINC_INCREMENTED;
|
||||
drv->urt_tx_dma.Init.DestInc = DMA_DINC_FIXED;
|
||||
drv->urt_tx_dma.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
drv->urt_tx_dma.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
|
||||
drv->urt_tx_dma.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
|
||||
drv->urt_tx_dma.Init.SrcBurstLength = 1;
|
||||
drv->urt_tx_dma.Init.DestBurstLength = 1;
|
||||
drv->urt_tx_dma.Init.TransferAllocatedPort =
|
||||
DMA_SRC_ALLOCATED_PORT1 | DMA_DEST_ALLOCATED_PORT0;
|
||||
drv->urt_tx_dma.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
|
||||
drv->urt_tx_dma.Parent = &drv->urt;
|
||||
HAL_DMA_Init(&drv->urt_tx_dma);
|
||||
HAL_DMA_ConfigChannelAttributes(
|
||||
&drv->urt_tx_dma, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC |
|
||||
DMA_CHANNEL_SRC_SEC | DMA_CHANNEL_DEST_SEC);
|
||||
|
||||
HAL_UART_Init(&drv->urt);
|
||||
|
||||
NVIC_SetPriority(GPDMA1_Channel1_IRQn, IRQ_PRI_NORMAL);
|
||||
NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
|
||||
NVIC_SetPriority(USART3_IRQn, IRQ_PRI_NORMAL);
|
||||
NVIC_EnableIRQ(USART3_IRQn);
|
||||
|
||||
// SPI pins
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
@ -278,30 +271,52 @@ void nrf_init(void) {
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
drv->spi_dma.Instance = GPDMA1_Channel2;
|
||||
drv->spi_dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
drv->spi_dma.Init.Mode = DMA_NORMAL;
|
||||
drv->spi_dma.Init.Request = GPDMA1_REQUEST_SPI1_RX;
|
||||
drv->spi_dma.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
drv->spi_dma.Init.SrcInc = DMA_SINC_FIXED;
|
||||
drv->spi_dma.Init.DestInc = DMA_DINC_INCREMENTED;
|
||||
drv->spi_dma.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
drv->spi_dma.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
|
||||
drv->spi_dma.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
|
||||
drv->spi_dma.Init.SrcBurstLength = 1;
|
||||
drv->spi_dma.Init.DestBurstLength = 1;
|
||||
drv->spi_dma.Init.TransferAllocatedPort =
|
||||
drv->spi_rx_dma.Instance = GPDMA1_Channel2;
|
||||
drv->spi_rx_dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
drv->spi_rx_dma.Init.Mode = DMA_NORMAL;
|
||||
drv->spi_rx_dma.Init.Request = GPDMA1_REQUEST_SPI1_RX;
|
||||
drv->spi_rx_dma.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
drv->spi_rx_dma.Init.SrcInc = DMA_SINC_FIXED;
|
||||
drv->spi_rx_dma.Init.DestInc = DMA_DINC_INCREMENTED;
|
||||
drv->spi_rx_dma.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
drv->spi_rx_dma.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
|
||||
drv->spi_rx_dma.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
|
||||
drv->spi_rx_dma.Init.SrcBurstLength = 1;
|
||||
drv->spi_rx_dma.Init.DestBurstLength = 1;
|
||||
drv->spi_rx_dma.Init.TransferAllocatedPort =
|
||||
DMA_SRC_ALLOCATED_PORT1 | DMA_DEST_ALLOCATED_PORT0;
|
||||
drv->spi_dma.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
drv->spi_rx_dma.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
drv->spi_rx_dma.Parent = &drv->spi;
|
||||
|
||||
HAL_DMA_Init(&drv->spi_dma);
|
||||
HAL_DMA_Init(&drv->spi_rx_dma);
|
||||
HAL_DMA_ConfigChannelAttributes(
|
||||
&drv->spi_dma, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC | DMA_CHANNEL_SRC_SEC |
|
||||
DMA_CHANNEL_DEST_SEC);
|
||||
&drv->spi_rx_dma, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC |
|
||||
DMA_CHANNEL_SRC_SEC | DMA_CHANNEL_DEST_SEC);
|
||||
|
||||
drv->spi_tx_dma.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
drv->spi_tx_dma.Init.Mode = DMA_NORMAL;
|
||||
drv->spi_tx_dma.Instance = GPDMA1_Channel1;
|
||||
drv->spi_tx_dma.Init.Request = GPDMA1_REQUEST_SPI1_TX;
|
||||
drv->spi_tx_dma.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
drv->spi_tx_dma.Init.SrcInc = DMA_SINC_INCREMENTED;
|
||||
drv->spi_tx_dma.Init.DestInc = DMA_DINC_FIXED;
|
||||
drv->spi_tx_dma.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
drv->spi_tx_dma.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
|
||||
drv->spi_tx_dma.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
|
||||
drv->spi_tx_dma.Init.SrcBurstLength = 1;
|
||||
drv->spi_tx_dma.Init.DestBurstLength = 1;
|
||||
drv->spi_tx_dma.Init.TransferAllocatedPort =
|
||||
DMA_SRC_ALLOCATED_PORT1 | DMA_DEST_ALLOCATED_PORT0;
|
||||
drv->spi_tx_dma.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
drv->spi_tx_dma.Parent = &drv->spi;
|
||||
HAL_DMA_Init(&drv->spi_tx_dma);
|
||||
HAL_DMA_ConfigChannelAttributes(
|
||||
&drv->spi_tx_dma, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC |
|
||||
DMA_CHANNEL_SRC_SEC | DMA_CHANNEL_DEST_SEC);
|
||||
|
||||
drv->spi.Instance = SPI1;
|
||||
drv->spi.Init.Mode = SPI_MODE_SLAVE;
|
||||
drv->spi.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
|
||||
drv->spi.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
drv->spi.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
drv->spi.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
drv->spi.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
@ -311,16 +326,22 @@ void nrf_init(void) {
|
||||
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;
|
||||
drv->spi.hdmarx = &drv->spi_rx_dma;
|
||||
drv->spi.hdmatx = &drv->spi_tx_dma;
|
||||
|
||||
HAL_SPI_Init(&drv->spi);
|
||||
|
||||
drv->timer = systimer_create(nrf_timer_callback, drv);
|
||||
|
||||
NVIC_SetPriority(USART3_IRQn, IRQ_PRI_NORMAL);
|
||||
NVIC_EnableIRQ(USART3_IRQn);
|
||||
NVIC_SetPriority(GPDMA1_Channel1_IRQn, IRQ_PRI_NORMAL);
|
||||
NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
|
||||
NVIC_SetPriority(GPDMA1_Channel2_IRQn, IRQ_PRI_NORMAL);
|
||||
NVIC_EnableIRQ(GPDMA1_Channel2_IRQn);
|
||||
NVIC_SetPriority(SPI1_IRQn, IRQ_PRI_NORMAL);
|
||||
NVIC_EnableIRQ(SPI1_IRQn);
|
||||
NVIC_EnableIRQ(NRF_EXTI_INTERRUPT_NUM);
|
||||
|
||||
drv->tx_request_id = -1;
|
||||
drv->initialized = true;
|
||||
@ -335,15 +356,19 @@ void nrf_deinit(void) {
|
||||
|
||||
nrf_stop();
|
||||
|
||||
systimer_delete(drv->timer);
|
||||
|
||||
NVIC_DisableIRQ(GPDMA1_Channel1_IRQn);
|
||||
NVIC_DisableIRQ(GPDMA1_Channel2_IRQn);
|
||||
NVIC_DisableIRQ(SPI1_IRQn);
|
||||
NVIC_DisableIRQ(USART3_IRQn);
|
||||
NVIC_DisableIRQ(NRF_EXTI_INTERRUPT_NUM);
|
||||
|
||||
__HAL_RCC_SPI1_FORCE_RESET();
|
||||
__HAL_RCC_SPI1_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_USART1_FORCE_RESET();
|
||||
__HAL_RCC_USART1_RELEASE_RESET();
|
||||
__HAL_RCC_USART3_FORCE_RESET();
|
||||
__HAL_RCC_USART3_RELEASE_RESET();
|
||||
|
||||
drv->initialized = false;
|
||||
}
|
||||
@ -392,6 +417,30 @@ static void nrf_process_msg(nrf_driver_t *drv, const uint8_t *data,
|
||||
}
|
||||
}
|
||||
|
||||
static void nrf_prepare_spi_data(nrf_driver_t *drv) {
|
||||
if (drv->pending_spi_transaction) {
|
||||
return;
|
||||
}
|
||||
memset(&drv->long_rx_buffer, 0, sizeof(spi_packet_t));
|
||||
if (tsqueue_dequeue(&drv->tx_queue, (uint8_t *)&drv->tx_request,
|
||||
sizeof(nrf_tx_request_t), NULL, &drv->tx_request_id)) {
|
||||
HAL_SPI_TransmitReceive_DMA(&drv->spi, (uint8_t *)&drv->tx_request.packet,
|
||||
(uint8_t *)&drv->long_rx_buffer,
|
||||
sizeof(spi_packet_t));
|
||||
} else {
|
||||
memset(&drv->tx_request.packet, 0, sizeof(spi_packet_t));
|
||||
HAL_SPI_TransmitReceive_DMA(&drv->spi, (uint8_t *)&drv->tx_request.packet,
|
||||
(uint8_t *)&drv->long_rx_buffer,
|
||||
sizeof(spi_packet_t));
|
||||
}
|
||||
|
||||
drv->pending_spi_transaction = true;
|
||||
nrf_signal_data_ready();
|
||||
systick_delay_us(1);
|
||||
nrf_signal_no_data();
|
||||
systimer_set(drv->timer, 2000);
|
||||
}
|
||||
|
||||
/// DFU communication
|
||||
/// ----------------------------------------------------------
|
||||
|
||||
@ -427,9 +476,6 @@ uint32_t nrf_dfu_comm_receive(uint8_t *data, uint32_t len) {
|
||||
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;
|
||||
@ -449,6 +495,10 @@ int32_t nrf_send_msg(nrf_service_id_t service, const uint8_t *data,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!drv->comm_running) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t id = 0;
|
||||
|
||||
nrf_tx_request_t tx_request = {0};
|
||||
@ -456,26 +506,19 @@ int32_t nrf_send_msg(nrf_service_id_t service, const uint8_t *data,
|
||||
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;
|
||||
tx_request.packet.msg_len = len;
|
||||
memcpy(&tx_request.packet.data, data, len);
|
||||
tx_request.packet.data[len] =
|
||||
crc8((uint8_t *)&tx_request.packet, len + UART_OVERHEAD_SIZE - 1, 0x07,
|
||||
memset(&tx_request.packet.data[len], 0, sizeof(tx_request.packet.data) - len);
|
||||
tx_request.packet.crc =
|
||||
crc8((uint8_t *)&tx_request.packet, sizeof(tx_request.packet) - 1, 0x07,
|
||||
0x00, false);
|
||||
|
||||
if (!tsqueue_enqueue(&drv->tx_queue, (uint8_t *)&tx_request,
|
||||
sizeof(nrf_tx_request_t), &id)) {
|
||||
return -1;
|
||||
}
|
||||
tsqueue_enqueue(&drv->tx_queue, (uint8_t *)&tx_request,
|
||||
sizeof(nrf_tx_request_t), &id);
|
||||
|
||||
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;
|
||||
}
|
||||
if (drv->tx_request_id <= 0 && !tsqueue_empty(&drv->tx_queue)) {
|
||||
nrf_prepare_spi_data(drv);
|
||||
}
|
||||
irq_unlock(key);
|
||||
|
||||
@ -517,94 +560,58 @@ static bool nrf_is_valid_startbyte(uint8_t val) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// UART communication
|
||||
/// ---------------------------------------------------------
|
||||
|
||||
void nrf_uart_send(uint8_t data) {
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
drv->urt_rx_complete = false;
|
||||
drv->urt_tx_complete = false;
|
||||
drv->urt_rx_byte = false;
|
||||
drv->urt_tx_byte = data;
|
||||
|
||||
drv->urt_tx_byte = data;
|
||||
HAL_UART_Transmit(&drv->urt, (uint8_t *)&drv->urt_tx_byte, 1, 30);
|
||||
|
||||
// receive the rest of the message, or new message in any case.
|
||||
HAL_UART_Receive_IT(&drv->urt, &drv->urt_rx_byte, 1);
|
||||
}
|
||||
|
||||
uint8_t nrf_uart_get_received(void) {
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
if (!drv->initialized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!drv->urt_rx_complete) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return drv->urt_rx_byte;
|
||||
}
|
||||
|
||||
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;
|
||||
drv->urt_rx_complete = true;
|
||||
}
|
||||
} 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
|
||||
if (drv->rx_idx >= NRF_MAX_TX_DATA_SIZE + UART_HEADER_SIZE) {
|
||||
// message is too long, flush the line
|
||||
drv->rx_idx = 0;
|
||||
drv->rx_len = 0;
|
||||
} else {
|
||||
drv->rx_buffer.data[drv->rx_idx - UART_HEADER_SIZE] = drv->rx_byte;
|
||||
drv->rx_idx++;
|
||||
}
|
||||
|
||||
} 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);
|
||||
HAL_UART_Receive_IT(&drv->urt, &drv->urt_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);
|
||||
}
|
||||
drv->urt_tx_complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,6 +630,9 @@ void USART3_IRQHandler(void) {
|
||||
IRQ_LOG_EXIT();
|
||||
}
|
||||
|
||||
/// SPI communication
|
||||
/// ----------------------------------------------------------
|
||||
|
||||
void GPDMA1_Channel1_IRQHandler(void) {
|
||||
IRQ_LOG_ENTER();
|
||||
|
||||
@ -630,7 +640,7 @@ void GPDMA1_Channel1_IRQHandler(void) {
|
||||
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
if (drv->initialized) {
|
||||
HAL_DMA_IRQHandler(&drv->urt_tx_dma);
|
||||
HAL_DMA_IRQHandler(&drv->spi_tx_dma);
|
||||
}
|
||||
|
||||
mpu_restore(mpu_mode);
|
||||
@ -638,9 +648,6 @@ void GPDMA1_Channel1_IRQHandler(void) {
|
||||
IRQ_LOG_EXIT();
|
||||
}
|
||||
|
||||
/// SPI communication
|
||||
/// ----------------------------------------------------------
|
||||
|
||||
void GPDMA1_Channel2_IRQHandler(void) {
|
||||
IRQ_LOG_ENTER();
|
||||
|
||||
@ -648,7 +655,7 @@ void GPDMA1_Channel2_IRQHandler(void) {
|
||||
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
if (drv->initialized) {
|
||||
HAL_DMA_IRQHandler(&drv->spi_dma);
|
||||
HAL_DMA_IRQHandler(&drv->spi_rx_dma);
|
||||
}
|
||||
|
||||
mpu_restore(mpu_mode);
|
||||
@ -671,7 +678,7 @@ void SPI1_IRQHandler(void) {
|
||||
IRQ_LOG_EXIT();
|
||||
}
|
||||
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
|
||||
void nrf_spi_transfer_complete(SPI_HandleTypeDef *hspi) {
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
@ -682,27 +689,87 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
|
||||
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));
|
||||
if (!drv->comm_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
nrf_process_msg(drv, drv->long_rx_buffer.data, sizeof(packet->data),
|
||||
packet->service_id & 0x0F);
|
||||
spi_packet_t packet;
|
||||
memcpy(&packet, &drv->long_rx_buffer, sizeof(spi_packet_t));
|
||||
|
||||
HAL_SPI_Receive_DMA(&drv->spi, (uint8_t *)&drv->long_rx_buffer,
|
||||
sizeof(spi_packet_t));
|
||||
drv->pending_spi_transaction = false;
|
||||
|
||||
// tx was completed
|
||||
nrf_complete_current_request(drv, NRF_STATUS_OK);
|
||||
|
||||
// something to send?
|
||||
if (!tsqueue_empty(&drv->tx_queue)) {
|
||||
nrf_prepare_spi_data(drv);
|
||||
}
|
||||
|
||||
// process received data
|
||||
uint8_t crc = crc8((uint8_t *)&packet, MAX_SPI_DATA_SIZE + SPI_HEADER_SIZE,
|
||||
0x07, 0x00, false);
|
||||
|
||||
if (nrf_is_valid_startbyte(packet.service_id) && packet.crc == crc) {
|
||||
nrf_process_msg(drv, packet.data, packet.msg_len, packet.service_id & 0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
|
||||
nrf_spi_transfer_complete(hspi);
|
||||
}
|
||||
|
||||
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) {
|
||||
nrf_spi_transfer_complete(hspi);
|
||||
}
|
||||
|
||||
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) {
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hspi != &drv->spi) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!drv->comm_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
drv->pending_spi_transaction = false;
|
||||
nrf_complete_current_request(drv, NRF_STATUS_ERROR);
|
||||
|
||||
if (!tsqueue_empty(&drv->tx_queue)) {
|
||||
nrf_prepare_spi_data(drv);
|
||||
}
|
||||
}
|
||||
|
||||
void NRF_EXTI_INTERRUPT_HANDLER(void) {
|
||||
IRQ_LOG_ENTER();
|
||||
mpu_mode_t mpu_mode = mpu_reconfig(MPU_MODE_DEFAULT);
|
||||
|
||||
nrf_driver_t *drv = &g_nrf_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
if (HAL_GPIO_ReadPin(NRF_OUT_SPI_READY_PORT, NRF_OUT_SPI_READY_PIN) == 0) {
|
||||
nrf_prepare_spi_data(drv);
|
||||
}
|
||||
}
|
||||
// Clear the EXTI line pending bit
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(NRF_EXTI_INTERRUPT_PIN);
|
||||
|
||||
mpu_restore(mpu_mode);
|
||||
IRQ_LOG_EXIT();
|
||||
}
|
||||
|
||||
/// GPIO communication
|
||||
/// ---------------------------------------------------------
|
||||
bool nrf_force_reset(void) {
|
||||
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_RESET);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nrf_reboot_to_bootloader(void) {
|
||||
HAL_GPIO_WritePin(NRF_OUT_RESET_PORT, NRF_OUT_RESET_PIN, GPIO_PIN_RESET);
|
||||
@ -729,8 +796,8 @@ void nrf_stay_in_bootloader(bool set) {
|
||||
}
|
||||
}
|
||||
|
||||
bool nrf_in_reserved_gpio(void) {
|
||||
return HAL_GPIO_ReadPin(NRF_IN_GPIO0_PORT, NRF_IN_GPIO0_PIN) != 0;
|
||||
bool nrf_in_wakeup(void) {
|
||||
return HAL_GPIO_ReadPin(NRF_IN_WAKEUP_PORT, NRF_IN_WAKEUP_PIN) != 0;
|
||||
}
|
||||
|
||||
bool nrf_reboot(void) {
|
||||
@ -742,29 +809,23 @@ bool nrf_reboot(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void nrf_signal_running(void) {
|
||||
HAL_GPIO_WritePin(NRF_OUT_FW_RUNNING_PORT, NRF_OUT_FW_RUNNING_PIN,
|
||||
void nrf_signal_data_ready(void) {
|
||||
HAL_GPIO_WritePin(NRF_OUT_SPI_READY_PORT, NRF_OUT_SPI_READY_PIN,
|
||||
GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void nrf_signal_off(void) {
|
||||
HAL_GPIO_WritePin(NRF_OUT_FW_RUNNING_PORT, NRF_OUT_FW_RUNNING_PIN,
|
||||
void nrf_signal_no_data(void) {
|
||||
HAL_GPIO_WritePin(NRF_OUT_SPI_READY_PORT, NRF_OUT_SPI_READY_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;
|
||||
}
|
||||
// todo
|
||||
|
||||
return drv->comm_running;
|
||||
}
|
||||
|
@ -17,13 +17,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/systick.h>
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <io/nrf.h>
|
||||
#include <sys/systick.h>
|
||||
|
||||
#include "../nrf_internal.h"
|
||||
|
||||
@ -40,7 +41,6 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
bool answered_spi;
|
||||
bool answered_uart;
|
||||
|
||||
} nrf_test_t;
|
||||
|
||||
@ -51,9 +51,6 @@ void nrf_test_cb(const uint8_t *data, uint32_t len) {
|
||||
case PRODTEST_RESP_SPI:
|
||||
g_nrf_test.answered_spi = true;
|
||||
break;
|
||||
case PRODTEST_RESP_UART:
|
||||
g_nrf_test.answered_uart = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -84,40 +81,40 @@ bool nrf_test_spi_comm(void) {
|
||||
bool nrf_test_uart_comm(void) {
|
||||
nrf_register_listener(NRF_SERVICE_PRODTEST, nrf_test_cb);
|
||||
|
||||
g_nrf_test.answered_uart = false;
|
||||
nrf_uart_send(0xAB);
|
||||
|
||||
uint8_t data[1] = {PRODTEST_CMD_UART_DATA};
|
||||
systick_delay_ms(10);
|
||||
|
||||
if (!nrf_send_msg(NRF_SERVICE_PRODTEST, data, 1, NULL, NULL)) {
|
||||
uint8_t rx = nrf_uart_get_received();
|
||||
|
||||
if (rx != 0xAB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t timeout = ticks_timeout(100);
|
||||
|
||||
while (!ticks_expired(timeout)) {
|
||||
if (g_nrf_test.answered_uart) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nrf_test_reboot_to_bootloader(void) {
|
||||
bool nrf_test_reset(void) {
|
||||
bool result = false;
|
||||
|
||||
if (!nrf_firmware_running()) {
|
||||
return false;
|
||||
nrf_stop();
|
||||
|
||||
// looking at UART CTS PIN,
|
||||
// it has pull up and is only reset when NRF is not in reset
|
||||
if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == GPIO_PIN_SET) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!nrf_reboot_to_bootloader()) {
|
||||
return false;
|
||||
if (!nrf_force_reset()) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
uint32_t timeout = ticks_timeout(10);
|
||||
uint32_t timeout = ticks_timeout(1000);
|
||||
|
||||
while (!ticks_expired(timeout)) {
|
||||
if (!nrf_firmware_running()) {
|
||||
if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == GPIO_PIN_SET) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
@ -125,54 +122,20 @@ bool nrf_test_reboot_to_bootloader(void) {
|
||||
|
||||
systick_delay_ms(10);
|
||||
|
||||
// todo test UART communication with MCUboot
|
||||
|
||||
if (!nrf_reboot()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
timeout = ticks_timeout(1000);
|
||||
while (!ticks_expired(timeout)) {
|
||||
if (nrf_firmware_running()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nrf_test_gpio_trz_ready(void) {
|
||||
bool result = false;
|
||||
nrf_signal_running();
|
||||
systick_delay_ms(10);
|
||||
|
||||
nrf_info_t info = {0};
|
||||
if (!nrf_get_info(&info)) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!info.in_trz_ready) {
|
||||
systick_delay_ms(2000);
|
||||
|
||||
if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_11) == GPIO_PIN_SET) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
nrf_signal_off();
|
||||
systick_delay_ms(10);
|
||||
if (!nrf_get_info(&info)) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (info.in_trz_ready) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = true;
|
||||
|
||||
cleanup:
|
||||
nrf_signal_running();
|
||||
nrf_start();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -211,7 +174,7 @@ cleanup:
|
||||
return result;
|
||||
}
|
||||
|
||||
bool nrf_test_gpio_reserved(void) {
|
||||
bool nrf_test_gpio_wakeup(void) {
|
||||
bool result = false;
|
||||
uint8_t data[2] = {PRODTEST_CMD_SET_OUTPUT, 0};
|
||||
if (!nrf_send_msg(NRF_SERVICE_PRODTEST, data, sizeof(data), NULL, NULL)) {
|
||||
@ -220,7 +183,7 @@ bool nrf_test_gpio_reserved(void) {
|
||||
|
||||
systick_delay_ms(10);
|
||||
|
||||
if (nrf_in_reserved_gpio()) {
|
||||
if (nrf_in_wakeup()) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -233,7 +196,7 @@ bool nrf_test_gpio_reserved(void) {
|
||||
|
||||
systick_delay_ms(10);
|
||||
|
||||
if (!nrf_in_reserved_gpio()) {
|
||||
if (!nrf_in_wakeup()) {
|
||||
result = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -144,21 +144,26 @@
|
||||
#define SBU_2_PORT GPIOC
|
||||
#define SBU_2_CLK_ENA __HAL_RCC_GPIOC_CLK_ENABLE
|
||||
|
||||
#define NRF_IN_GPIO0_PIN GPIO_PIN_7
|
||||
#define NRF_IN_GPIO0_PORT GPIOE
|
||||
#define NRF_IN_GPIO0_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_FW_RUNNING_PIN GPIO_PIN_13
|
||||
#define NRF_IN_FW_RUNNING_PORT GPIOE
|
||||
#define NRF_IN_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_WAKEUP_PIN GPIO_PIN_7
|
||||
#define NRF_IN_WAKEUP_PORT GPIOE
|
||||
#define NRF_IN_WAKEUP_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_RESET_PIN GPIO_PIN_0
|
||||
#define NRF_OUT_RESET_PORT GPIOG
|
||||
#define NRF_OUT_RESET_CLK_ENA __HAL_RCC_GPIOG_CLK_ENABLE
|
||||
#define NRF_OUT_STAY_IN_BLD_PIN GPIO_PIN_15
|
||||
#define NRF_OUT_STAY_IN_BLD_PORT GPIOE
|
||||
#define NRF_OUT_STAY_IN_BLD_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_FW_RUNNING_PIN GPIO_PIN_11
|
||||
#define NRF_OUT_FW_RUNNING_PORT GPIOE
|
||||
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_SPI_READY_PIN GPIO_PIN_13
|
||||
#define NRF_OUT_SPI_READY_PORT GPIOE
|
||||
#define NRF_OUT_SPI_READY_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_SPI_REQUEST_PIN GPIO_PIN_11
|
||||
#define NRF_IN_SPI_REQUEST_PORT GPIOE
|
||||
#define NRF_IN_SPI_REQUEST_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_EXTI_INTERRUPT_GPIOSEL EXTI_GPIOE
|
||||
#define NRF_EXTI_INTERRUPT_LINE EXTI_LINE_11
|
||||
#define NRF_EXTI_INTERRUPT_PIN GPIO_PIN_11
|
||||
#define NRF_EXTI_INTERRUPT_NUM EXTI11_IRQn
|
||||
#define NRF_EXTI_INTERRUPT_HANDLER EXTI11_IRQHandler
|
||||
|
||||
#define NFC_SPI_INSTANCE SPI3
|
||||
#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
|
||||
|
@ -144,21 +144,26 @@
|
||||
#define SBU_2_PORT GPIOC
|
||||
#define SBU_2_CLK_ENA __HAL_RCC_GPIOC_CLK_ENABLE
|
||||
|
||||
#define NRF_IN_GPIO0_PIN GPIO_PIN_7
|
||||
#define NRF_IN_GPIO0_PORT GPIOE
|
||||
#define NRF_IN_GPIO0_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_FW_RUNNING_PIN GPIO_PIN_13
|
||||
#define NRF_IN_FW_RUNNING_PORT GPIOE
|
||||
#define NRF_IN_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_WAKEUP_PIN GPIO_PIN_7
|
||||
#define NRF_IN_WAKEUP_PORT GPIOE
|
||||
#define NRF_IN_WAKEUP_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_RESET_PIN GPIO_PIN_0
|
||||
#define NRF_OUT_RESET_PORT GPIOG
|
||||
#define NRF_OUT_RESET_CLK_ENA __HAL_RCC_GPIOG_CLK_ENABLE
|
||||
#define NRF_OUT_STAY_IN_BLD_PIN GPIO_PIN_15
|
||||
#define NRF_OUT_STAY_IN_BLD_PORT GPIOE
|
||||
#define NRF_OUT_STAY_IN_BLD_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_FW_RUNNING_PIN GPIO_PIN_11
|
||||
#define NRF_OUT_FW_RUNNING_PORT GPIOE
|
||||
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_SPI_READY_PIN GPIO_PIN_13
|
||||
#define NRF_OUT_SPI_READY_PORT GPIOE
|
||||
#define NRF_OUT_SPI_READY_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_SPI_REQUEST_PIN GPIO_PIN_11
|
||||
#define NRF_IN_SPI_REQUEST_PORT GPIOE
|
||||
#define NRF_IN_SPI_REQUEST_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_EXTI_INTERRUPT_GPIOSEL EXTI_GPIOE
|
||||
#define NRF_EXTI_INTERRUPT_LINE EXTI_LINE_11
|
||||
#define NRF_EXTI_INTERRUPT_PIN GPIO_PIN_11
|
||||
#define NRF_EXTI_INTERRUPT_NUM EXTI11_IRQn
|
||||
#define NRF_EXTI_INTERRUPT_HANDLER EXTI11_IRQHandler
|
||||
|
||||
#define NFC_SPI_INSTANCE SPI3
|
||||
#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
|
||||
|
@ -162,21 +162,26 @@
|
||||
#define SBU_2_PORT GPIOC
|
||||
#define SBU_2_CLK_ENA __HAL_RCC_GPIOC_CLK_ENABLE
|
||||
|
||||
#define NRF_IN_GPIO0_PIN GPIO_PIN_7
|
||||
#define NRF_IN_GPIO0_PORT GPIOE
|
||||
#define NRF_IN_GPIO0_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_FW_RUNNING_PIN GPIO_PIN_13
|
||||
#define NRF_IN_FW_RUNNING_PORT GPIOE
|
||||
#define NRF_IN_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_WAKEUP_PIN GPIO_PIN_7
|
||||
#define NRF_IN_WAKEUP_PORT GPIOE
|
||||
#define NRF_IN_WAKEUP_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_RESET_PIN GPIO_PIN_0
|
||||
#define NRF_OUT_RESET_PORT GPIOG
|
||||
#define NRF_OUT_RESET_CLK_ENA __HAL_RCC_GPIOG_CLK_ENABLE
|
||||
#define NRF_OUT_STAY_IN_BLD_PIN GPIO_PIN_15
|
||||
#define NRF_OUT_STAY_IN_BLD_PORT GPIOE
|
||||
#define NRF_OUT_STAY_IN_BLD_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_FW_RUNNING_PIN GPIO_PIN_11
|
||||
#define NRF_OUT_FW_RUNNING_PORT GPIOE
|
||||
#define NRF_OUT_FW_RUNNING_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_OUT_SPI_READY_PIN GPIO_PIN_13
|
||||
#define NRF_OUT_SPI_READY_PORT GPIOE
|
||||
#define NRF_OUT_SPI_READY_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_IN_SPI_REQUEST_PIN GPIO_PIN_11
|
||||
#define NRF_IN_SPI_REQUEST_PORT GPIOE
|
||||
#define NRF_IN_SPI_REQUEST_CLK_ENA __HAL_RCC_GPIOE_CLK_ENABLE
|
||||
#define NRF_EXTI_INTERRUPT_GPIOSEL EXTI_GPIOE
|
||||
#define NRF_EXTI_INTERRUPT_LINE EXTI_LINE_11
|
||||
#define NRF_EXTI_INTERRUPT_PIN GPIO_PIN_11
|
||||
#define NRF_EXTI_INTERRUPT_NUM EXTI11_IRQn
|
||||
#define NRF_EXTI_INTERRUPT_HANDLER EXTI11_IRQHandler
|
||||
|
||||
#define NFC_SPI_INSTANCE SPI3
|
||||
#define NFC_SPI_PIN_AF GPIO_AF6_SPI3
|
||||
|
@ -37,15 +37,9 @@ static void prodtest_nrf_communication(cli_t* cli) {
|
||||
return;
|
||||
}
|
||||
|
||||
cli_trace(cli, "Testing reboot to bootloader...");
|
||||
if (!nrf_test_reboot_to_bootloader()) {
|
||||
cli_error(cli, CLI_ERROR, "Reboot to bootloader failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
cli_trace(cli, "Testing GPIO TRZ ready...");
|
||||
if (!nrf_test_gpio_trz_ready()) {
|
||||
cli_error(cli, CLI_ERROR, "TRZ ready GPIO failed.");
|
||||
cli_trace(cli, "Testing reset..");
|
||||
if (!nrf_test_reset()) {
|
||||
cli_error(cli, CLI_ERROR, "Reset failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -55,9 +49,9 @@ static void prodtest_nrf_communication(cli_t* cli) {
|
||||
return;
|
||||
}
|
||||
|
||||
cli_trace(cli, "Testing GPIO reserved...");
|
||||
if (!nrf_test_gpio_reserved()) {
|
||||
cli_error(cli, CLI_ERROR, "Reserved GPIO failed.");
|
||||
cli_trace(cli, "Testing GPIO wakeup...");
|
||||
if (!nrf_test_gpio_wakeup()) {
|
||||
cli_error(cli, CLI_ERROR, "Wakeup GPIO failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import utime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -96,6 +97,8 @@ async def reboot_to_bootloader(msg: RebootToBootloader) -> NoReturn:
|
||||
await ctx.write(Success(message="Rebooting"))
|
||||
# make sure the outgoing USB buffer is flushed
|
||||
await loop.wait(ctx.iface.iface_num() | io.POLL_WRITE)
|
||||
|
||||
utime.sleep_ms(10)
|
||||
# reboot to the bootloader, pass the firmware header hash if any
|
||||
utils.reboot_to_bootloader(boot_command, boot_args)
|
||||
raise RuntimeError
|
||||
|
Loading…
Reference in New Issue
Block a user