From ee2dd7322f3befccd005318a57c6c67fdf44c99b Mon Sep 17 00:00:00 2001 From: Karsten Koenig Date: Wed, 7 Aug 2019 17:13:35 +0200 Subject: [PATCH] drivers: spi: rv32m1: Add driver for RV32M1 LPSPI Add SPI driver and bindings for LPSPI peripheral for the RV32M1 SOC. Based heavily on the existing mcux LPSPI driver. Signed-off-by: Karsten Koenig --- CODEOWNERS | 1 + drivers/spi/CMakeLists.txt | 1 + drivers/spi/Kconfig | 2 + drivers/spi/Kconfig.rv32m1_lpspi | 12 + drivers/spi/spi_rv32m1_lpspi.c | 409 +++++++++++++++++++++ dts/bindings/spi/openisa,rv32m1-lpspi.yaml | 21 ++ dts/riscv/rv32m1.dtsi | 44 +++ dts/riscv/rv32m1_ri5cy.dtsi | 20 + dts/riscv/rv32m1_zero_riscy.dtsi | 20 + modules/Kconfig.vega | 5 + soc/riscv/openisa_rv32m1/Kconfig.defconfig | 8 + soc/riscv/openisa_rv32m1/Kconfig.soc | 1 + west.yml | 2 +- 13 files changed, 545 insertions(+), 1 deletion(-) create mode 100644 drivers/spi/Kconfig.rv32m1_lpspi create mode 100644 drivers/spi/spi_rv32m1_lpspi.c create mode 100644 dts/bindings/spi/openisa,rv32m1-lpspi.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 1604609407..9cd497d946 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -162,6 +162,7 @@ /drivers/ptp_clock/ @jukkar /drivers/spi/ @tbursztyka /drivers/spi/spi_ll_stm32.* @superna9999 +/drivers/spi/spi_rv32m1_lpspi* @karstenkoenig /drivers/timer/apic_timer.c @andrewboie /drivers/timer/cortex_m_systick.c @ioannisg /drivers/timer/altera_avalon_timer_hal.c @wentongwu diff --git a/drivers/spi/CMakeLists.txt b/drivers/spi/CMakeLists.txt index 88ea5fa76e..49e3cd9c95 100644 --- a/drivers/spi/CMakeLists.txt +++ b/drivers/spi/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_MCUX_LPSPI spi_mcux_lpspi.c) zephyr_library_sources_ifdef(CONFIG_SPI_SAM spi_sam.c) zephyr_library_sources_ifdef(CONFIG_SPI_SAM0 spi_sam0.c) zephyr_library_sources_ifdef(CONFIG_SPI_SIFIVE spi_sifive.c) +zephyr_library_sources_ifdef(CONFIG_SPI_RV32M1_LPSPI spi_rv32m1_lpspi.c) zephyr_library_sources_ifdef(CONFIG_NRFX_SPI spi_nrfx_spi.c) zephyr_library_sources_ifdef(CONFIG_NRFX_SPIM spi_nrfx_spim.c) zephyr_library_sources_ifdef(CONFIG_NRFX_SPIS spi_nrfx_spis.c) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index e3cf8d6cc3..e513c08d90 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -187,6 +187,8 @@ source "drivers/spi/Kconfig.mcux_dspi" source "drivers/spi/Kconfig.mcux_lpspi" +source "drivers/spi/Kconfig.rv32m1_lpspi" + source "drivers/spi/Kconfig.sam" source "drivers/spi/Kconfig.sam0" diff --git a/drivers/spi/Kconfig.rv32m1_lpspi b/drivers/spi/Kconfig.rv32m1_lpspi new file mode 100644 index 0000000000..4f5b2df27d --- /dev/null +++ b/drivers/spi/Kconfig.rv32m1_lpspi @@ -0,0 +1,12 @@ +# Kconfig - RV32M1 SPI +# +# Copyright (c) 2019, Karsten Koenig +# +# SPDX-License-Identifier: Apache-2.0 +# + +config SPI_RV32M1_LPSPI + bool "RV32M1 LPSPI driver" + depends on HAS_RV32M1_LPSPI && CLOCK_CONTROL + help + Enable the RV32M1 LPSPI driver. diff --git a/drivers/spi/spi_rv32m1_lpspi.c b/drivers/spi/spi_rv32m1_lpspi.c new file mode 100644 index 0000000000..28317ac07d --- /dev/null +++ b/drivers/spi/spi_rv32m1_lpspi.c @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2018, NXP + * + * Forked off the spi_mcux_lpi2c driver. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL +#include +LOG_MODULE_REGISTER(spi_rv32m1_lpspi); + +#include "spi_context.h" + +#define CHIP_SELECT_COUNT 4 +#define MAX_DATA_WIDTH 4096 + +struct spi_mcux_config { + LPSPI_Type *base; + char *clock_name; + clock_control_subsys_t clock_subsys; + clock_ip_name_t clock_ip_name; + u32_t clock_ip_src; + void (*irq_config_func)(struct device *dev); +}; + +struct spi_mcux_data { + lpspi_master_handle_t handle; + struct spi_context ctx; + size_t transfer_len; +}; + +static void spi_mcux_transfer_next_packet(struct device *dev) +{ + const struct spi_mcux_config *config = dev->config->config_info; + struct spi_mcux_data *data = dev->driver_data; + LPSPI_Type *base = config->base; + struct spi_context *ctx = &data->ctx; + lpspi_transfer_t transfer; + status_t status; + + if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { + /* nothing left to rx or tx, we're done! */ + spi_context_cs_control(&data->ctx, false); + spi_context_complete(&data->ctx, 0); + return; + } + + transfer.configFlags = kLPSPI_MasterPcsContinuous | + (ctx->config->slave << LPSPI_MASTER_PCS_SHIFT); + + if (ctx->tx_len == 0) { + /* rx only, nothing to tx */ + transfer.txData = NULL; + transfer.rxData = ctx->rx_buf; + transfer.dataSize = ctx->rx_len; + } else if (ctx->rx_len == 0) { + /* tx only, nothing to rx */ + transfer.txData = (u8_t *) ctx->tx_buf; + transfer.rxData = NULL; + transfer.dataSize = ctx->tx_len; + } else if (ctx->tx_len == ctx->rx_len) { + /* rx and tx are the same length */ + transfer.txData = (u8_t *) ctx->tx_buf; + transfer.rxData = ctx->rx_buf; + transfer.dataSize = ctx->tx_len; + } else if (ctx->tx_len > ctx->rx_len) { + /* Break up the tx into multiple transfers so we don't have to + * rx into a longer intermediate buffer. Leave chip select + * active between transfers. + */ + transfer.txData = (u8_t *) ctx->tx_buf; + transfer.rxData = ctx->rx_buf; + transfer.dataSize = ctx->rx_len; + transfer.configFlags |= kLPSPI_MasterPcsContinuous; + } else { + /* Break up the rx into multiple transfers so we don't have to + * tx from a longer intermediate buffer. Leave chip select + * active between transfers. + */ + transfer.txData = (u8_t *) ctx->tx_buf; + transfer.rxData = ctx->rx_buf; + transfer.dataSize = ctx->tx_len; + transfer.configFlags |= kLPSPI_MasterPcsContinuous; + } + + if (!(ctx->tx_count <= 1 && ctx->rx_count <= 1)) { + transfer.configFlags |= kLPSPI_MasterPcsContinuous; + } + + data->transfer_len = transfer.dataSize; + status = LPSPI_MasterTransferNonBlocking(base, &data->handle, + &transfer); + if (status != kStatus_Success) { + LOG_ERR("Transfer could not start"); + } +} + +static void spi_mcux_isr(void *arg) +{ + struct device *dev = (struct device *)arg; + const struct spi_mcux_config *config = dev->config->config_info; + struct spi_mcux_data *data = dev->driver_data; + LPSPI_Type *base = config->base; + + LPSPI_MasterTransferHandleIRQ(base, &data->handle); +} + +static void spi_mcux_master_transfer_callback(LPSPI_Type *base, + lpspi_master_handle_t *handle, status_t status, void *userData) +{ + struct device *dev = userData; + struct spi_mcux_data *data = dev->driver_data; + + spi_context_update_tx(&data->ctx, 1, data->transfer_len); + spi_context_update_rx(&data->ctx, 1, data->transfer_len); + + spi_mcux_transfer_next_packet(dev); +} + +static int spi_mcux_configure(struct device *dev, + const struct spi_config *spi_cfg) +{ + const struct spi_mcux_config *config = dev->config->config_info; + struct spi_mcux_data *data = dev->driver_data; + LPSPI_Type *base = config->base; + lpspi_master_config_t master_config; + struct device *clock_dev; + u32_t clock_freq; + u32_t word_size; + + if (spi_context_configured(&data->ctx, spi_cfg)) { + /* This configuration is already in use */ + return 0; + } + + LPSPI_MasterGetDefaultConfig(&master_config); + + if (spi_cfg->slave > CHIP_SELECT_COUNT) { + LOG_ERR("Slave %d is greater than %d", + spi_cfg->slave, + CHIP_SELECT_COUNT); + return -EINVAL; + } + + word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); + if (word_size > MAX_DATA_WIDTH) { + LOG_ERR("Word size %d is greater than %d", + word_size, MAX_DATA_WIDTH); + return -EINVAL; + } + + master_config.bitsPerFrame = word_size; + + master_config.cpol = + (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) + ? kLPSPI_ClockPolarityActiveLow + : kLPSPI_ClockPolarityActiveHigh; + + master_config.cpha = + (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) + ? kLPSPI_ClockPhaseSecondEdge + : kLPSPI_ClockPhaseFirstEdge; + + master_config.direction = + (spi_cfg->operation & SPI_TRANSFER_LSB) + ? kLPSPI_LsbFirst + : kLPSPI_MsbFirst; + + master_config.baudRate = spi_cfg->frequency; + + clock_dev = device_get_binding(config->clock_name); + if (clock_dev == NULL) { + return -EINVAL; + } + + if (clock_control_get_rate(clock_dev, config->clock_subsys, + &clock_freq)) { + return -EINVAL; + } + + LPSPI_MasterInit(base, &master_config, clock_freq); + + LPSPI_MasterTransferCreateHandle(base, &data->handle, + spi_mcux_master_transfer_callback, dev); + + data->ctx.config = spi_cfg; + spi_context_cs_configure(&data->ctx); + + return 0; +} + +static int transceive(struct device *dev, + const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + bool asynchronous, + struct k_poll_signal *signal) +{ + struct spi_mcux_data *data = dev->driver_data; + int ret; + + spi_context_lock(&data->ctx, asynchronous, signal); + + ret = spi_mcux_configure(dev, spi_cfg); + if (ret) { + goto out; + } + + spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); + + spi_context_cs_control(&data->ctx, true); + + spi_mcux_transfer_next_packet(dev); + + ret = spi_context_wait_for_completion(&data->ctx); +out: + spi_context_release(&data->ctx, ret); + + return ret; +} + +static int spi_mcux_transceive(struct device *dev, + const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL); +} + +#ifdef CONFIG_SPI_ASYNC +static int spi_mcux_transceive_async(struct device *dev, + const struct spi_config *spi_cfg, + const struct spi_buf_set *tx_bufs, + const struct spi_buf_set *rx_bufs, + struct k_poll_signal *async) +{ + return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, async); +} +#endif /* CONFIG_SPI_ASYNC */ + +static int spi_mcux_release(struct device *dev, + const struct spi_config *spi_cfg) +{ + struct spi_mcux_data *data = dev->driver_data; + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static int spi_mcux_init(struct device *dev) +{ + const struct spi_mcux_config *config = dev->config->config_info; + struct spi_mcux_data *data = dev->driver_data; + + CLOCK_SetIpSrc(config->clock_ip_name, config->clock_ip_src); + + config->irq_config_func(dev); + + spi_context_unlock_unconditionally(&data->ctx); + + return 0; +} + +static const struct spi_driver_api spi_mcux_driver_api = { + .transceive = spi_mcux_transceive, +#ifdef CONFIG_SPI_ASYNC + .transceive_async = spi_mcux_transceive_async, +#endif + .release = spi_mcux_release, +}; + +#ifdef CONFIG_SPI_0 +static void spi_mcux_config_func_0(struct device *dev); + +static const struct spi_mcux_config spi_mcux_config_0 = { + .base = (LPSPI_Type *) DT_OPENISA_RV32M1_LPSPI_SPI_0_BASE_ADDRESS, + .clock_name = DT_OPENISA_RV32M1_LPSPI_SPI_0_CLOCK_CONTROLLER, + .clock_subsys = (clock_control_subsys_t) + DT_OPENISA_RV32M1_LPSPI_SPI_0_CLOCK_NAME, + .irq_config_func = spi_mcux_config_func_0, + .clock_ip_name = kCLOCK_Lpspi0, + .clock_ip_src = kCLOCK_IpSrcFircAsync, +}; + +static struct spi_mcux_data spi_mcux_data_0 = { + SPI_CONTEXT_INIT_LOCK(spi_mcux_data_0, ctx), + SPI_CONTEXT_INIT_SYNC(spi_mcux_data_0, ctx), +}; + +DEVICE_AND_API_INIT(spi_mcux_0, DT_OPENISA_RV32M1_LPSPI_SPI_0_LABEL, + &spi_mcux_init, &spi_mcux_data_0, &spi_mcux_config_0, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &spi_mcux_driver_api); + +static void spi_mcux_config_func_0(struct device *dev) +{ + IRQ_CONNECT(DT_OPENISA_RV32M1_LPSPI_SPI_0_IRQ_0, + DT_OPENISA_RV32M1_LPSPI_SPI_0_IRQ_0_PRIORITY, + spi_mcux_isr, DEVICE_GET(spi_mcux_0), 0); + + irq_enable(DT_OPENISA_RV32M1_LPSPI_SPI_0_IRQ_0); +} +#endif /* SPI_0 */ + +#ifdef CONFIG_SPI_1 +static void spi_mcux_config_func_1(struct device *dev); + +static const struct spi_mcux_config spi_mcux_config_1 = { + .base = (LPSPI_Type *) DT_OPENISA_RV32M1_LPSPI_SPI_1_BASE_ADDRESS, + .clock_name = DT_OPENISA_RV32M1_LPSPI_SPI_1_CLOCK_CONTROLLER, + .clock_subsys = (clock_control_subsys_t) + DT_OPENISA_RV32M1_LPSPI_SPI_1_CLOCK_NAME, + .irq_config_func = spi_mcux_config_func_1, + .clock_ip_name = kCLOCK_Lpspi1, + .clock_ip_src = kCLOCK_IpSrcFircAsync, +}; + +static struct spi_mcux_data spi_mcux_data_1 = { + SPI_CONTEXT_INIT_LOCK(spi_mcux_data_1, ctx), + SPI_CONTEXT_INIT_SYNC(spi_mcux_data_1, ctx), +}; + +DEVICE_AND_API_INIT(spi_mcux_1, DT_OPENISA_RV32M1_LPSPI_SPI_1_LABEL, + &spi_mcux_init, &spi_mcux_data_1, &spi_mcux_config_1, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &spi_mcux_driver_api); + +static void spi_mcux_config_func_1(struct device *dev) +{ + IRQ_CONNECT(DT_OPENISA_RV32M1_LPSPI_SPI_1_IRQ_0, + DT_OPENISA_RV32M1_LPSPI_SPI_1_IRQ_0_PRIORITY, + spi_mcux_isr, DEVICE_GET(spi_mcux_1), 0); + + irq_enable(DT_OPENISA_RV32M1_LPSPI_SPI_1_IRQ_0); +} +#endif /* SPI_1 */ + +#ifdef CONFIG_SPI_2 +static void spi_mcux_config_func_2(struct device *dev); + +static const struct spi_mcux_config spi_mcux_config_2 = { + .base = (LPSPI_Type *) DT_OPENISA_RV32M1_LPSPI_SPI_2_BASE_ADDRESS, + .clock_name = DT_OPENISA_RV32M1_LPSPI_SPI_2_CLOCK_CONTROLLER, + .clock_subsys = (clock_control_subsys_t) + DT_OPENISA_RV32M1_LPSPI_SPI_2_CLOCK_NAME, + .irq_config_func = spi_mcux_config_func_2, + .clock_ip_name = kCLOCK_Lpspi2, + .clock_ip_src = kCLOCK_IpSrcFircAsync, +}; + +static struct spi_mcux_data spi_mcux_data_2 = { + SPI_CONTEXT_INIT_LOCK(spi_mcux_data_2, ctx), + SPI_CONTEXT_INIT_SYNC(spi_mcux_data_2, ctx), +}; + +DEVICE_AND_API_INIT(spi_mcux_2, DT_OPENISA_RV32M1_LPSPI_SPI_2_LABEL, + &spi_mcux_init, &spi_mcux_data_2, &spi_mcux_config_2, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &spi_mcux_driver_api); + +static void spi_mcux_config_func_2(struct device *dev) +{ + IRQ_CONNECT(DT_OPENISA_RV32M1_LPSPI_SPI_2_IRQ_0, + DT_OPENISA_RV32M1_LPSPI_SPI_2_IRQ_0_PRIORITY, + spi_mcux_isr, DEVICE_GET(spi_mcux_2), 0); + + irq_enable(DT_OPENISA_RV32M1_LPSPI_SPI_2_IRQ_0); +} +#endif /* SPI_2 */ + +#ifdef CONFIG_SPI_3 +static void spi_mcux_config_func_3(struct device *dev); + +static const struct spi_mcux_config spi_mcux_config_3 = { + .base = (LPSPI_Type *) DT_OPENISA_RV32M1_LPSPI_SPI_3_BASE_ADDRESS, + .clock_name = DT_OPENISA_RV32M1_LPSPI_SPI_3_CLOCK_CONTROLLER, + .clock_subsys = (clock_control_subsys_t) + DT_OPENISA_RV32M1_LPSPI_SPI_3_CLOCK_NAME, + .irq_config_func = spi_mcux_config_func_3, + .clock_ip_name = kCLOCK_Lpspi3, + .clock_ip_src = kCLOCK_IpSrcFircAsync, +}; + +static struct spi_mcux_data spi_mcux_data_3 = { + SPI_CONTEXT_INIT_LOCK(spi_mcux_data_3, ctx), + SPI_CONTEXT_INIT_SYNC(spi_mcux_data_3, ctx), +}; + +DEVICE_AND_API_INIT(spi_mcux_3, DT_OPENISA_RV32M1_LPSPI_SPI_3_LABEL, + &spi_mcux_init, &spi_mcux_data_3, &spi_mcux_config_3, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &spi_mcux_driver_api); + +static void spi_mcux_config_func_3(struct device *dev) +{ + IRQ_CONNECT(DT_OPENISA_RV32M1_LPSPI_SPI_3_IRQ_0, + DT_OPENISA_RV32M1_LPSPI_SPI_3_IRQ_0_PRIORITY, + spi_mcux_isr, DEVICE_GET(spi_mcux_3), 0); + + irq_enable(DT_OPENISA_RV32M1_LPSPI_SPI_3_IRQ_0); +} +#endif /* CONFIG_SPI_3 */ diff --git a/dts/bindings/spi/openisa,rv32m1-lpspi.yaml b/dts/bindings/spi/openisa,rv32m1-lpspi.yaml new file mode 100644 index 0000000000..b84676b92a --- /dev/null +++ b/dts/bindings/spi/openisa,rv32m1-lpspi.yaml @@ -0,0 +1,21 @@ +# +# Copyright (c) 2019, Karsten Koenig +# +# SPDX-License-Identifier: Apache-2.0 +# + +title: OpenISA LPSPI + +description: > + This binding gives a base representation of the OpenISA LPSPI controller + +compatible: "openisa,rv32m1-lpspi" + +include: spi-controller.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/dts/riscv/rv32m1.dtsi b/dts/riscv/rv32m1.dtsi index 6cd23df807..121ba46f32 100644 --- a/dts/riscv/rv32m1.dtsi +++ b/dts/riscv/rv32m1.dtsi @@ -32,6 +32,10 @@ i2c-1 = &i2c1; i2c-2 = &i2c2; i2c-3 = &i2c3; + spi-0 = &spi0; + spi-1 = &spi1; + spi-2 = &spi2; + spi-3 = &spi3; }; cpus { @@ -443,6 +447,46 @@ status = "disabled"; }; + spi0: spi@4003f000 { + compatible = "openisa,rv32m1-lpspi"; + reg = <0x4003f000 0x78>; + label = "SPI_0"; + status = "disabled"; + clocks = <&pcc0 0xfc>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@40040000 { + compatible = "openisa,rv32m1-lpspi"; + reg = <0x40040000 0x78>; + label = "SPI_1"; + status = "disabled"; + clocks = <&pcc0 0x100>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi2: spi@40041000 { + compatible = "openisa,rv32m1-lpspi"; + reg = <0x40041000 0x78>; + label = "SPI_2"; + status = "disabled"; + clocks = <&pcc0 0x104>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi3: spi@41035000 { + compatible = "openisa,rv32m1-lpspi"; + reg = <0x41035000 0x78>; + label = "SPI_3"; + status = "disabled"; + clocks = <&pcc1 0xd4>; + #address-cells = <1>; + #size-cells = <0>; + }; + flash-controller@40023000 { compatible = "openisa,rv32m1-ftfe"; label = "FLASH_CTRL"; diff --git a/dts/riscv/rv32m1_ri5cy.dtsi b/dts/riscv/rv32m1_ri5cy.dtsi index ac7b9d6bc8..25e6400749 100644 --- a/dts/riscv/rv32m1_ri5cy.dtsi +++ b/dts/riscv/rv32m1_ri5cy.dtsi @@ -170,3 +170,23 @@ interrupt-parent = <&intmux0_ch1>; interrupts = <24>; }; + +&spi0 { + interrupt-parent = <&event0>; + interrupts = <13>; +}; + +&spi1 { + interrupt-parent = <&event0>; + interrupts = <14>; +}; + +&spi2 { + interrupt-parent = <&intmux0_ch1>; + interrupts = <12>; +}; + +&spi3 { + interrupt-parent = <&intmux0_ch1>; + interrupts = <25>; +}; diff --git a/dts/riscv/rv32m1_zero_riscy.dtsi b/dts/riscv/rv32m1_zero_riscy.dtsi index 7af2929336..46ea9a9e25 100644 --- a/dts/riscv/rv32m1_zero_riscy.dtsi +++ b/dts/riscv/rv32m1_zero_riscy.dtsi @@ -169,3 +169,23 @@ interrupt-parent = <&event1>; interrupts = <16>; }; + +&spi0 { + interrupt-parent = <&intmux1_ch0>; + interrupts = <18>; +}; + +&spi1 { + interrupt-parent = <&intmux1_ch0>; + interrupts = <19>; +}; + +&spi2 { + interrupt-parent = <&intmux1_ch0>; + interrupts = <20>; +}; + +&spi3 { + interrupt-parent = <&event1>; + interrupts = <19>; +}; diff --git a/modules/Kconfig.vega b/modules/Kconfig.vega index 4b891a6cad..663d03b7e2 100644 --- a/modules/Kconfig.vega +++ b/modules/Kconfig.vega @@ -15,6 +15,11 @@ config HAS_RV32M1_LPI2C help Set if the low power i2c (LPI2C) module is present in the SoC. +config HAS_RV32M1_LPSPI + bool + help + Set if the low power spi (LPSPI) module is present in the SoC. + config HAS_RV32M1_FTFX bool help diff --git a/soc/riscv/openisa_rv32m1/Kconfig.defconfig b/soc/riscv/openisa_rv32m1/Kconfig.defconfig index 46b25c2f79..bcd6e30c89 100644 --- a/soc/riscv/openisa_rv32m1/Kconfig.defconfig +++ b/soc/riscv/openisa_rv32m1/Kconfig.defconfig @@ -161,6 +161,14 @@ config I2C_RV32M1_LPI2C endif # I2C +if SPI + +config SPI_RV32M1_LPSPI + default y + +endif # SPI + + if FLASH config SOC_FLASH_RV32M1 diff --git a/soc/riscv/openisa_rv32m1/Kconfig.soc b/soc/riscv/openisa_rv32m1/Kconfig.soc index 15019754c0..3141eb4c6d 100644 --- a/soc/riscv/openisa_rv32m1/Kconfig.soc +++ b/soc/riscv/openisa_rv32m1/Kconfig.soc @@ -10,6 +10,7 @@ config SOC_OPENISA_RV32M1_RISCV32 select XIP select HAS_RV32M1_LPUART select HAS_RV32M1_LPI2C + select HAS_RV32M1_LPSPI select ATOMIC_OPERATIONS_C select VEGA_SDK_HAL select RISCV_SOC_INTERRUPT_INIT diff --git a/west.yml b/west.yml index da86f0a811..534f5e98c2 100644 --- a/west.yml +++ b/west.yml @@ -47,7 +47,7 @@ manifest: revision: e0bfd6f253ca6a5e87b6f53a8bb317bd6f483511 path: modules/hal/nordic - name: hal_openisa - revision: be5c01f86c96500def5079bcc58d2baefdffb6c8 + revision: 0cbbf29f1523fe2970e57622bd79d9b115ca84e5 path: modules/hal/openisa - name: hal_microchip revision: 85302959c0c659311cf90ac51d133e5ce19c9288