From 17096a54d223d1d047a72149bac6d136f7727b88 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Sat, 19 Jan 2019 12:38:44 +0100 Subject: [PATCH 1/4] cpu/fe310: Add call to periph_init() Until now fe310's cpu_init() was missing a call to periph_init(). This commit adds this call. --- cpu/fe310/Makefile.include | 1 + cpu/fe310/cpu.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/cpu/fe310/Makefile.include b/cpu/fe310/Makefile.include index 564abaa5b322..9f8e7ad1506c 100644 --- a/cpu/fe310/Makefile.include +++ b/cpu/fe310/Makefile.include @@ -5,6 +5,7 @@ USEMODULE += newlib_syscalls_fe310 USEMODULE += sifive_drivers_fe310 USEMODULE += periph +USEMODULE += periph_common USEMODULE += periph_pm CFLAGS += -Wno-pedantic diff --git a/cpu/fe310/cpu.c b/cpu/fe310/cpu.c index d145738c5bbd..b8e12ec446fc 100644 --- a/cpu/fe310/cpu.c +++ b/cpu/fe310/cpu.c @@ -28,6 +28,7 @@ #include "cpu.h" #include "context_frame.h" #include "periph_cpu.h" +#include "periph/init.h" #include "panic.h" #include "vendor/encoding.h" #include "vendor/platform.h" @@ -88,6 +89,9 @@ void cpu_init(void) /* Set default state of mstatus */ set_csr(mstatus, MSTATUS_DEFAULT); + + /* trigger static peripheral initialization */ + periph_init(); } /** From a5cc0ce6dcf405c3558b38e2afac92f83541f9f4 Mon Sep 17 00:00:00 2001 From: Tristan Bruns Date: Thu, 17 Jan 2019 17:21:09 +0100 Subject: [PATCH 2/4] boards/hifive1: fix CLOCK_CORECLOCK --- boards/hifive1/include/periph_conf.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/boards/hifive1/include/periph_conf.h b/boards/hifive1/include/periph_conf.h index e0dd67612199..a636be5179c1 100644 --- a/boards/hifive1/include/periph_conf.h +++ b/boards/hifive1/include/periph_conf.h @@ -27,12 +27,8 @@ extern "C" { * @name Core Clock configuration * @{ */ -#define CLOCK_CORECLOCK (1600000ul) -/* - * #define CLOCK_CORECLOCK (20000000ul) - * #define CLOCK_CORECLOCK (27000000ul) - * #define CLOCK_CORECLOCK (38400000ul) - */ +/* As defined in boards/hifive1/board.c CPU_DESIRED_FREQ **/ +#define CLOCK_CORECLOCK (200000000ul) /** @} */ /** From 7c4e810636836421c5bdd182f3326e524036d64b Mon Sep 17 00:00:00 2001 From: Tristan Bruns Date: Sun, 20 Jan 2019 17:52:50 +0100 Subject: [PATCH 3/4] cpu/fe310: implement SPI --- boards/hifive1/Makefile.features | 2 +- boards/hifive1/include/periph_conf.h | 20 ++++ cpu/fe310/Makefile.include | 3 + cpu/fe310/include/periph_cpu.h | 9 ++ cpu/fe310/periph/spi.c | 136 +++++++++++++++++++++++++++ 5 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 cpu/fe310/periph/spi.c diff --git a/boards/hifive1/Makefile.features b/boards/hifive1/Makefile.features index c74c6deeaaf4..5a6d856ab9be 100644 --- a/boards/hifive1/Makefile.features +++ b/boards/hifive1/Makefile.features @@ -3,7 +3,7 @@ FEATURES_PROVIDED += periph_gpio periph_gpio_irq #FEATURES_PROVIDED += periph_pwm FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_rtt -#FEATURES_PROVIDED += periph_spi +FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_uart diff --git a/boards/hifive1/include/periph_conf.h b/boards/hifive1/include/periph_conf.h index a636be5179c1..78e1a48d188b 100644 --- a/boards/hifive1/include/periph_conf.h +++ b/boards/hifive1/include/periph_conf.h @@ -19,6 +19,8 @@ #ifndef PERIPH_CONF_H #define PERIPH_CONF_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -78,6 +80,24 @@ extern "C" { #define PWM_NUMOF (3) /** @} */ +/** + * @name SPI device configuration + * + * @{ + */ +/* DIV_UP is division which rounds up instead of down */ +#define DIV_UP(a,b) (((a) + ((b) - 1)) / (b)) +static const uint32_t spi_clk_config[] = { + DIV_UP(CLOCK_CORECLOCK, 2 * 100000) - 1, + DIV_UP(CLOCK_CORECLOCK, 2 * 400000) - 1, + DIV_UP(CLOCK_CORECLOCK, 2 * 1000000) - 1, + DIV_UP(CLOCK_CORECLOCK, 2 * 5000000) - 1, + DIV_UP(CLOCK_CORECLOCK, 2 * 10000000) - 1, +}; +#undef DIV_UP +#define SPI_NUMOF (1) +/** @} */ + /** * @name UART configuration * diff --git a/cpu/fe310/Makefile.include b/cpu/fe310/Makefile.include index 9f8e7ad1506c..33659ff22359 100644 --- a/cpu/fe310/Makefile.include +++ b/cpu/fe310/Makefile.include @@ -8,6 +8,9 @@ USEMODULE += periph USEMODULE += periph_common USEMODULE += periph_pm +# include common periph drivers +USEMODULE += periph_common + CFLAGS += -Wno-pedantic include $(RIOTMAKE)/arch/riscv.inc.mk diff --git a/cpu/fe310/include/periph_cpu.h b/cpu/fe310/include/periph_cpu.h index 70b817ed53b4..a010ecc4759e 100644 --- a/cpu/fe310/include/periph_cpu.h +++ b/cpu/fe310/include/periph_cpu.h @@ -28,6 +28,15 @@ extern "C" { */ #define CPUID_LEN (12U) +/** + * @name This CPU makes use of the following shared SPI functions + * @{ + */ +#define PERIPH_SPI_NEEDS_TRANSFER_BYTE 1 +#define PERIPH_SPI_NEEDS_TRANSFER_REG 1 +#define PERIPH_SPI_NEEDS_TRANSFER_REGS 1 +/** @} */ + /** * @brief Prevent shared timer functions from being used */ diff --git a/cpu/fe310/periph/spi.c b/cpu/fe310/periph/spi.c new file mode 100644 index 000000000000..ca4009053ac5 --- /dev/null +++ b/cpu/fe310/periph/spi.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2019 Tristan Bruns + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_fe310 + * @ingroup drivers_periph_spi + * + * @{ + * + * @file spi.c + * @brief Low-level SPI driver implementation + * + * @author Tristan Bruns + * + * @} + */ + +#include "cpu.h" +#include "mutex.h" +#include "assert.h" +#include "periph/spi.h" +#include "vendor/platform.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/** + * @brief Allocation device locks + */ +static mutex_t lock; + +void spi_init(spi_t bus) +{ + /* make sure given bus device is valid */ + assert(bus == 0); + + /* initialize the buses lock */ + mutex_init(&lock); + + /* trigger pin initialization */ + spi_init_pins(bus); + + /* disable hardware chip select + (hardware chip select only supports one-byte transfers...) */ + SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_OFF; +} + +void spi_init_pins(spi_t bus) +{ + assert(bus == 0); + + const gpio_t spi1_pins = + (1 << IOF_SPI1_MOSI) | + (1 << IOF_SPI1_MISO) | + (1 << IOF_SPI1_SCK); + + /* Enable I/O Function 0 */ + GPIO_REG(GPIO_IOF_EN) |= spi1_pins; + GPIO_REG(GPIO_IOF_SEL) &= ~spi1_pins; +} + +int spi_init_cs(spi_t bus, spi_cs_t cs) +{ + if (bus != 0) { + return SPI_NODEV; + } + + /* setting the CS high before configuring it as an + output should be fine on FE310. */ + gpio_set(cs); + + if (gpio_init(cs, GPIO_OUT)) { + return SPI_NOCS; + } + + return SPI_OK; +} + +int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk) +{ + (void) bus; + (void) cs; + + mutex_lock(&lock); + + SPI1_REG(SPI_REG_SCKDIV) = spi_clk_config[clk]; + SPI1_REG(SPI_REG_SCKMODE) = mode; + + return SPI_OK; +} + +void spi_release(spi_t bus) +{ + (void) bus; + + mutex_unlock(&lock); +} + +void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont, + const void *out_, void *in_, size_t len) +{ + (void) bus; + + assert((out_ || in_) && len > 0); + assert(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY); + assert(!(SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL)); + + const uint8_t *out = out_; + uint8_t *in = in_; + + if (cs != SPI_CS_UNDEF) { + gpio_clear(cs); + } + + for (size_t i = 0; i < len; i++) { + SPI1_REG(SPI_REG_TXFIFO) = out ? out[i] : 0; + + uint32_t rxdata = SPI_RXFIFO_EMPTY; + while (rxdata & SPI_RXFIFO_EMPTY) { + rxdata = SPI1_REG(SPI_REG_RXFIFO); + } + + if (in) { + in[i] = (uint8_t)rxdata; + } + } + + if (cs != SPI_CS_UNDEF && !cont) { + gpio_set(cs); + } +} From aa541f2058b173d7667c088e74d7b85017789efc Mon Sep 17 00:00:00 2001 From: Tristan Bruns Date: Mon, 21 Jan 2019 15:37:15 +0100 Subject: [PATCH 4/4] fixup! cpu/fe310: implement SPI --- cpu/fe310/periph/spi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/fe310/periph/spi.c b/cpu/fe310/periph/spi.c index ca4009053ac5..645901eca1f1 100644 --- a/cpu/fe310/periph/spi.c +++ b/cpu/fe310/periph/spi.c @@ -52,6 +52,7 @@ void spi_init(spi_t bus) void spi_init_pins(spi_t bus) { + (void) bus; assert(bus == 0); const gpio_t spi1_pins =