diff --git a/hw/application_fpga/Makefile b/hw/application_fpga/Makefile index d45f26f..022dbc5 100644 --- a/hw/application_fpga/Makefile +++ b/hw/application_fpga/Makefile @@ -94,7 +94,8 @@ FIRMWARE_OBJS = \ $(P)/fw/tk1/lib.o \ $(P)/fw/tk1/assert.o \ $(P)/fw/tk1/led.o \ - $(P)/fw/tk1/blake2s/blake2s.o + $(P)/fw/tk1/blake2s/blake2s.o \ + $(P)/fw/tk1/spi.o FIRMWARE_SOURCES = \ $(P)/fw/tk1/main.c \ @@ -102,7 +103,8 @@ FIRMWARE_SOURCES = \ $(P)/fw/tk1/lib.c \ $(P)/fw/tk1/assert.c \ $(P)/fw/tk1/led.c \ - $(P)/fw/tk1/blake2s/blake2s.c + $(P)/fw/tk1/blake2s/blake2s.c \ + $(P)/fw/tk1/spi.c TESTFW_OBJS = \ $(P)/fw/testfw/main.o \ diff --git a/hw/application_fpga/fw/tk1/main.c b/hw/application_fpga/fw/tk1/main.c index b6f59ec..3cff710 100644 --- a/hw/application_fpga/fw/tk1/main.c +++ b/hw/application_fpga/fw/tk1/main.c @@ -8,6 +8,7 @@ #include "blake2s/blake2s.h" #include "lib.h" #include "proto.h" +#include "spi.h" #include "state.h" #include "types.h" @@ -30,6 +31,7 @@ static volatile uint32_t *timer_status = (volatile uint32_t *)TK1_MMIO_TIMER_ static volatile uint32_t *timer_ctrl = (volatile uint32_t *)TK1_MMIO_TIMER_CTRL; static volatile uint32_t *ram_addr_rand = (volatile uint32_t *)TK1_MMIO_TK1_RAM_ADDR_RAND; static volatile uint32_t *ram_data_rand = (volatile uint32_t *)TK1_MMIO_TK1_RAM_DATA_RAND; +static volatile uint32_t *spi_func_addr = (volatile uint32_t *)TK1_MMIO_TK1_ADDR_SPI_CMD; // clang-format on // Context for the loading of a TKey program @@ -403,6 +405,7 @@ int main(void) // Let the app know the function adddress for blake2s() *fw_blake2s_addr = (uint32_t)blake2s; + *spi_func_addr = (uint32_t)spi_ready; /*@-mustfreeonly@*/ /* Yes, splint, this points directly to RAM and we don't care diff --git a/hw/application_fpga/fw/tk1/spi.c b/hw/application_fpga/fw/tk1/spi.c new file mode 100644 index 0000000..3f795ad --- /dev/null +++ b/hw/application_fpga/fw/tk1/spi.c @@ -0,0 +1,102 @@ +// Copyright (C) 2022, 2023 - Tillitis AB +// SPDX-License-Identifier: GPL-2.0-only + +#include "spi.h" +#include "../tk1_mem.h" +#include "types.h" + +// clang-format off +static volatile uint32_t *spi_en = (volatile uint32_t *)(TK1_MMIO_TK1_BASE | 0x200); +static volatile uint32_t *spi_xfer = (volatile uint32_t *)(TK1_MMIO_TK1_BASE | 0x204); +static volatile uint32_t *spi_data = (volatile uint32_t *)(TK1_MMIO_TK1_BASE | 0x208); +// clang-format on + +// returns non-zero when the SPI-master is ready, and zero if not +// ready. This can be used to check if the SPI-master is available +// in the hardware. +int spi_ready(void) +{ + return *spi_xfer; +} + +static void spi_enable(void) +{ + *spi_en = 1; +} + +static void spi_disable(void) +{ + *spi_en = 0; +} + +static void _spi_write(uint8_t *cmd, size_t size) +{ + for (int i = 0; i < size; i++) { + while (!spi_ready()) { + } + + *spi_data = cmd[i]; + *spi_xfer = 1; + } + + while (!spi_ready()) { + } +} + +static void _spi_read(uint8_t *buf, size_t size) +{ + + while (!spi_ready()) { + } + + for (int i = 0; i < size; i++) { + + *spi_data = 0x00; + *spi_xfer = 1; + + // wait until spi master is done + while (!spi_ready()) { + } + + buf[i] = (*spi_data & 0xff); + } +} + +int spi_write(uint8_t *cmd, size_t cmd_size, uint8_t *data, size_t data_size) +{ + if (cmd == NULL || cmd_size == 0) { + return -1; + } + + spi_enable(); + + _spi_write(cmd, cmd_size); + + if (data != NULL && data_size != 0) { + _spi_write(data, data_size); + } + + spi_disable(); + + return 0; +} + +int spi_transfer(uint8_t *tx_buf, size_t tx_size, uint8_t *rx_buf, + size_t rx_size) +{ + if (tx_buf == NULL || tx_size == 0) { + return -1; + } + + spi_enable(); + + _spi_write(tx_buf, tx_size); + + if (rx_buf != NULL && rx_size != 0) { + _spi_read(rx_buf, rx_size); + } + + spi_disable(); + + return 0; +} diff --git a/hw/application_fpga/fw/tk1/spi.h b/hw/application_fpga/fw/tk1/spi.h new file mode 100644 index 0000000..e962ce4 --- /dev/null +++ b/hw/application_fpga/fw/tk1/spi.h @@ -0,0 +1,14 @@ +// Copyright (C) 2022, 2023 - Tillitis AB +// SPDX-License-Identifier: GPL-2.0-only + +#ifndef TKEY_SPI_H +#define TKEY_SPI_H + +#include "types.h" + +int spi_ready(void); +int spi_write(uint8_t *cmd, size_t size_cmd, uint8_t *data, size_t size_data); +int spi_transfer(uint8_t *tx_buf, size_t tx_size, uint8_t *rx_buf, + size_t rx_size); + +#endif diff --git a/hw/application_fpga/fw/tk1_mem.h b/hw/application_fpga/fw/tk1_mem.h index 8bd5c07..b096016 100644 --- a/hw/application_fpga/fw/tk1_mem.h +++ b/hw/application_fpga/fw/tk1_mem.h @@ -149,4 +149,9 @@ #define TK1_MMIO_TK1_SPI_EN 0xff000200 #define TK1_MMIO_TK1_SPI_XFER 0xff000204 #define TK1_MMIO_TK1_SPI_DATA 0xff000208 + +#define TK1_MMIO_TK1_ADDR_SPI_CMD 0xff00020c + + + #endif