// Copyright (C) 2022, 2023 - Tillitis AB // SPDX-License-Identifier: GPL-2.0-only #include "spi.h" // #include // #include #include "../tk1/types.h" #include "../tk1_mem.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() { return *spi_xfer; } static void spi_enable() { *spi_en = 1; } static void spi_disable() { *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; }