driver: spi: Add initial support for spi driver on ra8
Add initial SPI driver support for RA8 MCUs Signed-off-by: Duy Phuong Hoang. Nguyen <duy.nguyen.xa@renesas.com>
This commit is contained in:
parent
4d5bf29315
commit
bec9952ce8
24 changed files with 1084 additions and 0 deletions
|
@ -100,6 +100,8 @@ The below features are currently supported on Zephyr OS for EK-RA8D1 board:
|
|||
+--------------+------------+------------------+
|
||||
| ENTROPY | on-chip | entropy |
|
||||
+--------------+------------+------------------+
|
||||
| SPI | on-chip | spi |
|
||||
+--------------+------------+------------------+
|
||||
|
||||
Other hardware features are currently not supported by the port.
|
||||
|
||||
|
|
|
@ -15,4 +15,14 @@
|
|||
psels = <RA_PSEL(RA_PSEL_SCI_9, 10, 15)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_default: spi0_default {
|
||||
group1 {
|
||||
/* MISO MOSI RSPCK SSL */
|
||||
psels = <RA_PSEL(RA_PSEL_SPI, 7, 0)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 7, 1)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 7, 2)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 7, 3)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -104,3 +104,9 @@
|
|||
&trng {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-0 = <&spi0_default>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -102,6 +102,8 @@ The below features are currently supported on Zephyr OS for EK-RA8M1 board:
|
|||
+-----------+------------+----------------------+
|
||||
| ENTROPY | on-chip | entropy |
|
||||
+-----------+------------+----------------------+
|
||||
| SPI | on-chip | spi |
|
||||
+-----------+------------+----------------------+
|
||||
|
||||
Other hardware features are currently not supported by the port.
|
||||
|
||||
|
|
|
@ -43,4 +43,14 @@
|
|||
renesas,analog-enable;
|
||||
};
|
||||
};
|
||||
|
||||
spi1_default: spi1_default {
|
||||
group1 {
|
||||
/* MISO MOSI RSPCK SSL*/
|
||||
psels = <RA_PSEL(RA_PSEL_SPI, 4, 10)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 4, 11)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 4, 12)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 4, 13)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -163,3 +163,9 @@ mikrobus_serial: &uart3 {};
|
|||
&trng {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
pinctrl-0 = <&spi1_default>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -98,6 +98,8 @@ The below features are currently supported on Zephyr OS for MCB-RA8T1 board:
|
|||
+--------------+------------+----------------------+
|
||||
| ENTROPY | on-chip | entropy |
|
||||
+--------------+------------+----------------------+
|
||||
| SPI | on-chip | spi |
|
||||
+--------------+------------+----------------------+
|
||||
|
||||
Other hardware features are currently not supported by the port.
|
||||
|
||||
|
|
|
@ -15,4 +15,14 @@
|
|||
psels = <RA_PSEL(RA_PSEL_SCI_3, 3, 9)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi0_default: spi0_default {
|
||||
group1 {
|
||||
/* MISO MOSI RSPCK SSL*/
|
||||
psels = <RA_PSEL(RA_PSEL_SPI, 3, 13)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 2, 2)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 2, 3)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 2, 4)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -98,3 +98,9 @@
|
|||
&trng {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-0 = <&spi0_default>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -49,6 +49,7 @@ zephyr_library_sources_ifdef(CONFIG_SPI_AMBIQ spi_ambiq.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_SPI_AMBIQ_BLEIF spi_ambiq_bleif.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SPI_RPI_PICO_PIO spi_rpi_pico_pio.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SPI_MCHP_MSS spi_mchp_mss.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SPI_RENESAS_RA8 spi_b_renesas_ra8.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SPI_RTIO spi_rtio.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_SPI_ASYNC spi_signal.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c)
|
||||
|
|
|
@ -158,4 +158,6 @@ source "drivers/spi/Kconfig.grlib_spimctrl"
|
|||
|
||||
source "drivers/spi/Kconfig.max32"
|
||||
|
||||
source "drivers/spi/Kconfig.renesas_ra8"
|
||||
|
||||
endif # SPI
|
||||
|
|
34
drivers/spi/Kconfig.renesas_ra8
Normal file
34
drivers/spi/Kconfig.renesas_ra8
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Renesas RA Family
|
||||
|
||||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SPI_RENESAS_RA8
|
||||
bool "Renesas RA SPI B"
|
||||
default y
|
||||
depends on DT_HAS_RENESAS_RA8_SPI_B_ENABLED
|
||||
select USE_RA_FSP_SPI_B
|
||||
help
|
||||
Enable Renesas RA RA SPI B Driver.
|
||||
|
||||
if SPI_RENESAS_RA8
|
||||
|
||||
config SPI_B_INTERRUPT
|
||||
bool "RA MCU SPI B Interrupt Support"
|
||||
help
|
||||
Enable Interrupt support for the SPI B Driver of RA family.
|
||||
|
||||
config SPI_B_RA_DTC
|
||||
bool "RA MCU SPI DTC Support"
|
||||
default y
|
||||
select USE_RA_FSP_DTC
|
||||
help
|
||||
Enable the SPI DTC mode for SPI instances
|
||||
|
||||
config SPI_B_USE_HW_SS
|
||||
bool "RA MCU SPI B Hardware Slave Select support"
|
||||
default y
|
||||
help
|
||||
Use Slave Select pin instead of software Slave Select.
|
||||
|
||||
endif # RA_SPI_B
|
771
drivers/spi/spi_b_renesas_ra8.c
Normal file
771
drivers/spi/spi_b_renesas_ra8.c
Normal file
|
@ -0,0 +1,771 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Renesas Electronics Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT renesas_ra8_spi_b
|
||||
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/drivers/clock_control/renesas_ra_cgc.h>
|
||||
#include <zephyr/irq.h>
|
||||
#include <soc.h>
|
||||
#include <instances/r_dtc.h>
|
||||
#include <instances/r_spi_b.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(ra8_spi_b);
|
||||
|
||||
#include "spi_context.h"
|
||||
|
||||
#if defined(CONFIG_SPI_B_INTERRUPT)
|
||||
void spi_b_rxi_isr(void);
|
||||
void spi_b_txi_isr(void);
|
||||
void spi_b_tei_isr(void);
|
||||
void spi_b_eri_isr(void);
|
||||
#endif
|
||||
|
||||
struct ra_spi_config {
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
const struct device *clock_dev;
|
||||
const struct clock_control_ra_subsys_cfg clock_subsys;
|
||||
};
|
||||
|
||||
struct ra_spi_data {
|
||||
struct spi_context ctx;
|
||||
uint8_t dfs;
|
||||
struct st_spi_b_instance_ctrl spi;
|
||||
struct st_spi_cfg fsp_config;
|
||||
struct st_spi_b_extended_cfg fsp_config_extend;
|
||||
#if CONFIG_SPI_B_INTERRUPT
|
||||
uint32_t data_len;
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_B_RA_DTC)
|
||||
/* RX */
|
||||
struct st_transfer_instance rx_transfer;
|
||||
struct st_dtc_instance_ctrl rx_transfer_ctrl;
|
||||
struct st_transfer_info rx_transfer_info;
|
||||
struct st_transfer_cfg rx_transfer_cfg;
|
||||
struct st_dtc_extended_cfg rx_transfer_cfg_extend;
|
||||
|
||||
/* TX */
|
||||
struct st_transfer_instance tx_transfer;
|
||||
struct st_dtc_instance_ctrl tx_transfer_ctrl;
|
||||
struct st_transfer_info tx_transfer_info;
|
||||
struct st_transfer_cfg tx_transfer_cfg;
|
||||
struct st_dtc_extended_cfg tx_transfer_cfg_extend;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void spi_cb(spi_callback_args_t *p_args)
|
||||
{
|
||||
struct device *dev = (struct device *)p_args->p_context;
|
||||
struct ra_spi_data *data = dev->data;
|
||||
|
||||
switch (p_args->event) {
|
||||
case SPI_EVENT_TRANSFER_COMPLETE:
|
||||
spi_context_cs_control(&data->ctx, false);
|
||||
spi_context_complete(&data->ctx, dev, 0);
|
||||
break;
|
||||
case SPI_EVENT_ERR_MODE_FAULT: /* Mode fault error */
|
||||
case SPI_EVENT_ERR_READ_OVERFLOW: /* Read overflow error */
|
||||
case SPI_EVENT_ERR_PARITY: /* Parity error */
|
||||
case SPI_EVENT_ERR_OVERRUN: /* Overrun error */
|
||||
case SPI_EVENT_ERR_FRAMING: /* Framing error */
|
||||
case SPI_EVENT_ERR_MODE_UNDERRUN: /* Underrun error */
|
||||
spi_context_cs_control(&data->ctx, false);
|
||||
spi_context_complete(&data->ctx, dev, -EIO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int ra_spi_b_configure(const struct device *dev, const struct spi_config *config)
|
||||
{
|
||||
struct ra_spi_data *data = dev->data;
|
||||
fsp_err_t fsp_err;
|
||||
|
||||
if (spi_context_configured(&data->ctx, config)) {
|
||||
/* Nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
fsp_err = R_SPI_B_Close(&data->spi);
|
||||
|
||||
if ((config->operation & SPI_FRAME_FORMAT_TI) == SPI_FRAME_FORMAT_TI) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (config->operation & SPI_OP_MODE_SLAVE) {
|
||||
data->fsp_config.operating_mode = SPI_MODE_SLAVE;
|
||||
} else {
|
||||
data->fsp_config.operating_mode = SPI_MODE_MASTER;
|
||||
}
|
||||
|
||||
if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) {
|
||||
data->fsp_config.clk_polarity = SPI_CLK_POLARITY_HIGH;
|
||||
} else {
|
||||
data->fsp_config.clk_polarity = SPI_CLK_POLARITY_LOW;
|
||||
}
|
||||
|
||||
if (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) {
|
||||
data->fsp_config.clk_phase = SPI_CLK_PHASE_EDGE_EVEN;
|
||||
} else {
|
||||
data->fsp_config.clk_phase = SPI_CLK_PHASE_EDGE_ODD;
|
||||
}
|
||||
|
||||
if (config->operation & SPI_TRANSFER_LSB) {
|
||||
data->fsp_config.bit_order = SPI_BIT_ORDER_LSB_FIRST;
|
||||
} else {
|
||||
data->fsp_config.bit_order = SPI_BIT_ORDER_MSB_FIRST;
|
||||
}
|
||||
|
||||
if (config->frequency > 0) {
|
||||
fsp_err = R_SPI_B_CalculateBitrate(config->frequency,
|
||||
data->fsp_config_extend.clock_source,
|
||||
&data->fsp_config_extend.spck_div);
|
||||
__ASSERT(fsp_err == 0, "spi_b: spi frequency calculate error: %d", fsp_err);
|
||||
}
|
||||
|
||||
data->fsp_config_extend.spi_comm = SPI_B_COMMUNICATION_FULL_DUPLEX;
|
||||
if (spi_cs_is_gpio(config) || !IS_ENABLED(CONFIG_SPI_B_USE_HW_SS)) {
|
||||
data->fsp_config_extend.spi_clksyn = SPI_B_SSL_MODE_CLK_SYN;
|
||||
} else {
|
||||
data->fsp_config_extend.spi_clksyn = SPI_B_SSL_MODE_SPI;
|
||||
data->fsp_config_extend.ssl_select = SPI_B_SSL_SELECT_SSL0;
|
||||
}
|
||||
|
||||
data->fsp_config.p_extend = &data->fsp_config_extend;
|
||||
|
||||
data->fsp_config.p_callback = spi_cb;
|
||||
data->fsp_config.p_context = dev;
|
||||
fsp_err = R_SPI_B_Open(&data->spi, &data->fsp_config);
|
||||
if (fsp_err != FSP_SUCCESS) {
|
||||
LOG_ERR("R_SPI_B_Open error: %d", fsp_err);
|
||||
return -EINVAL;
|
||||
}
|
||||
data->ctx.config = config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ra_spi_b_transfer_ongoing(struct ra_spi_data *data)
|
||||
{
|
||||
#if defined(CONFIG_SPI_B_INTERRUPT)
|
||||
return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx));
|
||||
#else
|
||||
if (spi_context_total_tx_len(&data->ctx) < spi_context_total_rx_len(&data->ctx)) {
|
||||
return (spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx));
|
||||
} else {
|
||||
return (spi_context_tx_on(&data->ctx) && spi_context_rx_on(&data->ctx));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPI_B_INTERRUPT
|
||||
static int ra_spi_b_transceive_slave(struct ra_spi_data *data)
|
||||
{
|
||||
R_SPI_B0_Type *p_spi_reg = data->spi.p_regs;
|
||||
|
||||
if (p_spi_reg->SPSR_b.SPTEF && spi_context_tx_on(&data->ctx)) {
|
||||
uint32_t tx;
|
||||
|
||||
if (data->ctx.tx_buf != NULL) {
|
||||
if (data->dfs > 2) {
|
||||
tx = *(uint32_t *)(data->ctx.tx_buf);
|
||||
} else if (data->dfs > 1) {
|
||||
tx = *(uint16_t *)(data->ctx.tx_buf);
|
||||
} else {
|
||||
tx = *(uint8_t *)(data->ctx.tx_buf);
|
||||
}
|
||||
} else {
|
||||
tx = 0;
|
||||
}
|
||||
/* Clear Transmit Empty flag */
|
||||
p_spi_reg->SPSRC = R_SPI_B0_SPSRC_SPTEFC_Msk;
|
||||
|
||||
p_spi_reg->SPDR = tx;
|
||||
|
||||
spi_context_update_tx(&data->ctx, data->dfs, 1);
|
||||
} else {
|
||||
p_spi_reg->SPCR_b.SPTIE = 0;
|
||||
}
|
||||
|
||||
if (p_spi_reg->SPSR_b.SPRF && spi_context_rx_buf_on(&data->ctx)) {
|
||||
uint32_t rx;
|
||||
|
||||
rx = p_spi_reg->SPDR;
|
||||
/* Clear Receive Full flag */
|
||||
p_spi_reg->SPSRC = R_SPI_B0_SPSRC_SPRFC_Msk;
|
||||
if (data->dfs > 2) {
|
||||
UNALIGNED_PUT(rx, (uint32_t *)data->ctx.rx_buf);
|
||||
} else if (data->dfs > 1) {
|
||||
UNALIGNED_PUT(rx, (uint16_t *)data->ctx.rx_buf);
|
||||
} else {
|
||||
UNALIGNED_PUT(rx, (uint8_t *)data->ctx.rx_buf);
|
||||
}
|
||||
spi_context_update_rx(&data->ctx, data->dfs, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ra_spi_b_transceive_master(struct ra_spi_data *data)
|
||||
{
|
||||
R_SPI_B0_Type *p_spi_reg = data->spi.p_regs;
|
||||
uint32_t tx;
|
||||
uint32_t rx;
|
||||
|
||||
/* Tx transfer*/
|
||||
if (spi_context_tx_buf_on(&data->ctx)) {
|
||||
if (data->dfs > 2) {
|
||||
tx = *(uint32_t *)(data->ctx.tx_buf);
|
||||
} else if (data->dfs > 1) {
|
||||
tx = *(uint16_t *)(data->ctx.tx_buf);
|
||||
} else {
|
||||
tx = *(uint8_t *)(data->ctx.tx_buf);
|
||||
}
|
||||
} else {
|
||||
tx = 0U;
|
||||
}
|
||||
|
||||
while (!p_spi_reg->SPSR_b.SPTEF) {
|
||||
}
|
||||
|
||||
p_spi_reg->SPDR = tx;
|
||||
|
||||
/* Clear Transmit Empty flag */
|
||||
p_spi_reg->SPSRC = R_SPI_B0_SPSRC_SPTEFC_Msk;
|
||||
spi_context_update_tx(&data->ctx, data->dfs, 1);
|
||||
|
||||
/* Rx receive */
|
||||
if (spi_context_rx_on(&data->ctx)) {
|
||||
while (!p_spi_reg->SPSR_b.SPRF) {
|
||||
}
|
||||
rx = p_spi_reg->SPDR;
|
||||
/* Clear Receive Full flag */
|
||||
p_spi_reg->SPSRC = R_SPI_B0_SPSRC_SPRFC_Msk;
|
||||
if (data->dfs > 2) {
|
||||
UNALIGNED_PUT(rx, (uint32_t *)data->ctx.rx_buf);
|
||||
} else if (data->dfs > 1) {
|
||||
UNALIGNED_PUT(rx, (uint16_t *)data->ctx.rx_buf);
|
||||
} else {
|
||||
UNALIGNED_PUT(rx, (uint8_t *)data->ctx.rx_buf);
|
||||
}
|
||||
spi_context_update_rx(&data->ctx, data->dfs, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ra_spi_b_transceive_data(struct ra_spi_data *data)
|
||||
{
|
||||
uint16_t operation = data->ctx.config->operation;
|
||||
|
||||
if (SPI_OP_MODE_GET(operation) == SPI_OP_MODE_MASTER) {
|
||||
ra_spi_b_transceive_master(data);
|
||||
} else {
|
||||
ra_spi_b_transceive_slave(data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int transceive(const struct device *dev, const struct spi_config *config,
|
||||
const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs,
|
||||
bool asynchronous, spi_callback_t cb, void *userdata)
|
||||
{
|
||||
struct ra_spi_data *data = dev->data;
|
||||
R_SPI_B0_Type *p_spi_reg;
|
||||
int ret = 0;
|
||||
|
||||
if (!tx_bufs && !rx_bufs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPI_B_INTERRUPT
|
||||
if (asynchronous) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
spi_context_lock(&data->ctx, asynchronous, cb, userdata, config);
|
||||
|
||||
ret = ra_spi_b_configure(dev, config);
|
||||
if (ret) {
|
||||
goto end;
|
||||
}
|
||||
data->dfs = ((SPI_WORD_SIZE_GET(config->operation) - 1) / 8) + 1;
|
||||
p_spi_reg = data->spi.p_regs;
|
||||
/* Set buffers info */
|
||||
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, data->dfs);
|
||||
|
||||
spi_context_cs_control(&data->ctx, true);
|
||||
|
||||
#ifdef CONFIG_SPI_B_INTERRUPT
|
||||
spi_bit_width_t spi_width =
|
||||
(spi_bit_width_t)(SPI_WORD_SIZE_GET(data->ctx.config->operation) - 1);
|
||||
|
||||
if (data->ctx.rx_len == 0) {
|
||||
data->data_len = spi_context_is_slave(&data->ctx)
|
||||
? spi_context_total_tx_len(&data->ctx)
|
||||
: data->ctx.tx_len;
|
||||
} else if (data->ctx.tx_len == 0) {
|
||||
data->data_len = spi_context_is_slave(&data->ctx)
|
||||
? spi_context_total_rx_len(&data->ctx)
|
||||
: data->ctx.rx_len;
|
||||
} else {
|
||||
data->data_len = spi_context_is_slave(&data->ctx)
|
||||
? MAX(spi_context_total_tx_len(&data->ctx),
|
||||
spi_context_total_rx_len(&data->ctx))
|
||||
: MIN(data->ctx.tx_len, data->ctx.rx_len);
|
||||
}
|
||||
|
||||
if (data->ctx.rx_buf == NULL) {
|
||||
R_SPI_B_Write(&data->spi, data->ctx.tx_buf, data->data_len, spi_width);
|
||||
} else if (data->ctx.tx_buf == NULL) {
|
||||
R_SPI_B_Read(&data->spi, data->ctx.rx_buf, data->data_len, spi_width);
|
||||
} else {
|
||||
R_SPI_B_WriteRead(&data->spi, data->ctx.tx_buf, data->ctx.rx_buf, data->data_len,
|
||||
spi_width);
|
||||
}
|
||||
ret = spi_context_wait_for_completion(&data->ctx);
|
||||
|
||||
#else
|
||||
p_spi_reg->SPCR_b.TXMD = 0x0; /* tx - rx*/
|
||||
if (!spi_context_tx_on(&data->ctx)) {
|
||||
p_spi_reg->SPCR_b.TXMD = 0x2; /* rx only */
|
||||
}
|
||||
if (!spi_context_rx_on(&data->ctx)) {
|
||||
p_spi_reg->SPCR_b.TXMD = 0x1; /* tx only */
|
||||
}
|
||||
|
||||
/* Clear FIFOs */
|
||||
p_spi_reg->SPFCR = 1;
|
||||
|
||||
/* Enable the SPI Transfer. */
|
||||
p_spi_reg->SPCR_b.SPE = 1;
|
||||
p_spi_reg->SPCMD0 |= (uint32_t)(SPI_WORD_SIZE_GET(data->ctx.config->operation) - 1)
|
||||
<< R_SPI_B0_SPCMD0_SPB_Pos;
|
||||
do {
|
||||
ra_spi_b_transceive_data(data);
|
||||
} while (ra_spi_b_transfer_ongoing(data));
|
||||
|
||||
/* Wait for transmision complete */
|
||||
while (p_spi_reg->SPSR_b.IDLNF) {
|
||||
}
|
||||
|
||||
/* Disable the SPI Transfer. */
|
||||
p_spi_reg->SPCR_b.SPE = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_SLAVE
|
||||
if (spi_context_is_slave(&data->ctx) && !ret) {
|
||||
ret = data->ctx.recv_frames;
|
||||
}
|
||||
#endif /* CONFIG_SPI_SLAVE */
|
||||
|
||||
end:
|
||||
spi_context_release(&data->ctx, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ra_spi_b_transceive(const struct device *dev, const struct spi_config *config,
|
||||
const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs)
|
||||
{
|
||||
return transceive(dev, config, tx_bufs, rx_bufs, false, NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPI_ASYNC
|
||||
static int ra_spi_b_transceive_async(const struct device *dev, const struct spi_config *config,
|
||||
const struct spi_buf_set *tx_bufs,
|
||||
const struct spi_buf_set *rx_bufs, spi_callback_t cb,
|
||||
void *userdata)
|
||||
{
|
||||
return transceive(dev, config, tx_bufs, rx_bufs, true, cb, userdata);
|
||||
}
|
||||
#endif /* CONFIG_SPI_ASYNC */
|
||||
|
||||
static int ra_spi_b_release(const struct device *dev, const struct spi_config *config)
|
||||
{
|
||||
struct ra_spi_data *data = dev->data;
|
||||
|
||||
spi_context_unlock_unconditionally(&data->ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spi_driver_api ra_spi_driver_api = {.transceive = ra_spi_b_transceive,
|
||||
#ifdef CONFIG_SPI_ASYNC
|
||||
.transceive_async =
|
||||
ra_spi_b_transceive_async,
|
||||
#endif /* CONFIG_SPI_ASYNC */
|
||||
.release = ra_spi_b_release};
|
||||
|
||||
static spi_b_clock_source_t ra_spi_b_clock_name(const struct device *clock_dev)
|
||||
{
|
||||
const char *clock_dev_name = clock_dev->name;
|
||||
|
||||
if (strcmp(clock_dev_name, "spiclk") == 0 || strcmp(clock_dev_name, "scispiclk") == 0) {
|
||||
return SPI_B_CLOCK_SOURCE_SCISPICLK;
|
||||
}
|
||||
|
||||
return SPI_B_CLOCK_SOURCE_PCLK;
|
||||
}
|
||||
|
||||
static int spi_b_ra_init(const struct device *dev)
|
||||
{
|
||||
const struct ra_spi_config *config = dev->config;
|
||||
struct ra_spi_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
if (!device_is_ready(config->clock_dev)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
data->fsp_config_extend.clock_source = ra_spi_b_clock_name(config->clock_dev);
|
||||
|
||||
/* Configure dt provided device signals when available */
|
||||
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = spi_context_cs_configure_all(&data->ctx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
spi_context_unlock_unconditionally(&data->ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SPI_B_INTERRUPT)
|
||||
|
||||
static void ra_spi_retransmit(struct ra_spi_data *data)
|
||||
{
|
||||
spi_bit_width_t spi_width =
|
||||
(spi_bit_width_t)(SPI_WORD_SIZE_GET(data->ctx.config->operation) - 1);
|
||||
|
||||
if (data->ctx.rx_len == 0) {
|
||||
data->data_len = data->ctx.tx_len;
|
||||
data->spi.p_tx_data = data->ctx.tx_buf;
|
||||
data->spi.p_rx_data = NULL;
|
||||
} else if (data->ctx.tx_len == 0) {
|
||||
data->data_len = data->ctx.rx_len;
|
||||
data->spi.p_tx_data = NULL;
|
||||
data->spi.p_rx_data = data->ctx.rx_buf;
|
||||
} else {
|
||||
data->data_len = MIN(data->ctx.tx_len, data->ctx.rx_len);
|
||||
data->spi.p_tx_data = data->ctx.tx_buf;
|
||||
data->spi.p_rx_data = data->ctx.rx_buf;
|
||||
}
|
||||
|
||||
data->spi.bit_width = spi_width;
|
||||
data->spi.rx_count = 0;
|
||||
data->spi.tx_count = 0;
|
||||
data->spi.count = data->data_len;
|
||||
#ifdef CONFIG_SPI_B_RA_DTC
|
||||
/* Determine DTC transfer size */
|
||||
transfer_size_t size;
|
||||
|
||||
if (spi_width > SPI_BIT_WIDTH_16_BITS) { /* Bit Widths of 17-32 bits */
|
||||
size = TRANSFER_SIZE_4_BYTE;
|
||||
} else if (spi_width > SPI_BIT_WIDTH_8_BITS) { /* Bit Widths of 9-16 bits*/
|
||||
size = TRANSFER_SIZE_2_BYTE;
|
||||
} else { /* Bit Widths of 4-8 bits */
|
||||
size = TRANSFER_SIZE_1_BYTE;
|
||||
}
|
||||
|
||||
if (data->spi.p_cfg->p_transfer_rx) {
|
||||
/* When the rxi interrupt is called, all transfers will be finished. */
|
||||
data->spi.rx_count = data->data_len;
|
||||
|
||||
transfer_instance_t *p_transfer_rx =
|
||||
(transfer_instance_t *)data->spi.p_cfg->p_transfer_rx;
|
||||
transfer_info_t *p_info = p_transfer_rx->p_cfg->p_info;
|
||||
|
||||
/* Configure the receive DMA instance. */
|
||||
p_info->transfer_settings_word_b.size = size;
|
||||
p_info->length = (uint16_t)data->data_len;
|
||||
p_info->transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED;
|
||||
p_info->p_dest = data->ctx.rx_buf;
|
||||
|
||||
if (NULL == data->ctx.rx_buf) {
|
||||
static uint32_t dummy_rx;
|
||||
|
||||
p_info->transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED;
|
||||
p_info->p_dest = &dummy_rx;
|
||||
}
|
||||
|
||||
p_transfer_rx->p_api->reconfigure(p_transfer_rx->p_ctrl, p_info);
|
||||
}
|
||||
|
||||
if (data->spi.p_cfg->p_transfer_tx) {
|
||||
/* When the txi interrupt is called, all transfers will be finished. */
|
||||
data->spi.tx_count = data->data_len;
|
||||
|
||||
transfer_instance_t *p_transfer_tx =
|
||||
(transfer_instance_t *)data->spi.p_cfg->p_transfer_tx;
|
||||
transfer_info_t *p_info = p_transfer_tx->p_cfg->p_info;
|
||||
|
||||
/* Configure the transmit DMA instance. */
|
||||
p_info->transfer_settings_word_b.size = size;
|
||||
p_info->length = (uint16_t)data->data_len;
|
||||
p_info->transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED;
|
||||
p_info->p_src = data->ctx.tx_buf;
|
||||
|
||||
if (NULL == data->ctx.tx_buf) {
|
||||
static uint32_t dummy_tx;
|
||||
|
||||
p_info->transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_FIXED;
|
||||
p_info->p_src = &dummy_tx;
|
||||
}
|
||||
|
||||
p_transfer_tx->p_api->reconfigure(p_transfer_tx->p_ctrl, p_info);
|
||||
}
|
||||
#endif
|
||||
data->spi.p_regs->SPSRC = R_SPI_B0_SPSRC_SPTEFC_Msk;
|
||||
}
|
||||
|
||||
static void ra_spi_rxi_isr(const struct device *dev)
|
||||
{
|
||||
#ifndef CONFIG_SPI_SLAVE
|
||||
ARG_UNUSED(dev);
|
||||
spi_b_rxi_isr();
|
||||
#else
|
||||
struct ra_spi_data *data = dev->data;
|
||||
|
||||
spi_b_rxi_isr();
|
||||
if (spi_context_is_slave(&data->ctx) && data->spi.rx_count == data->spi.count) {
|
||||
|
||||
if (data->ctx.rx_buf != NULL && data->ctx.tx_buf != NULL) {
|
||||
data->ctx.recv_frames = MIN(spi_context_total_tx_len(&data->ctx),
|
||||
spi_context_total_rx_len(&data->ctx));
|
||||
} else if (data->ctx.tx_buf == NULL) {
|
||||
data->ctx.recv_frames = data->data_len;
|
||||
} else {
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
R_BSP_IrqDisable(data->fsp_config.tei_irq);
|
||||
|
||||
/* Writing 0 to SPE generatates a TXI IRQ. Disable the TXI IRQ.
|
||||
* (See Section 38.2.1 SPI Control Register in the RA6T2 manual R01UH0886EJ0100).
|
||||
*/
|
||||
R_BSP_IrqDisable(data->fsp_config.txi_irq);
|
||||
|
||||
/* Disable the SPI Transfer. */
|
||||
data->spi.p_regs->SPCR_b.SPE = 0;
|
||||
|
||||
/* Re-enable the TXI IRQ and clear the pending IRQ. */
|
||||
R_BSP_IrqEnable(data->fsp_config.txi_irq);
|
||||
|
||||
spi_context_cs_control(&data->ctx, false);
|
||||
spi_context_complete(&data->ctx, dev, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ra_spi_txi_isr(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
spi_b_txi_isr();
|
||||
}
|
||||
|
||||
static void ra_spi_tei_isr(const struct device *dev)
|
||||
{
|
||||
struct ra_spi_data *data = dev->data;
|
||||
|
||||
if (data->spi.rx_count == data->spi.count) {
|
||||
spi_context_update_rx(&data->ctx, 1, data->data_len);
|
||||
}
|
||||
if (data->spi.tx_count == data->spi.count) {
|
||||
spi_context_update_tx(&data->ctx, 1, data->data_len);
|
||||
}
|
||||
if (ra_spi_b_transfer_ongoing(data)) {
|
||||
R_ICU->IELSR_b[data->fsp_config.tei_irq].IR = 0U;
|
||||
ra_spi_retransmit(data);
|
||||
} else {
|
||||
spi_b_tei_isr();
|
||||
}
|
||||
}
|
||||
|
||||
static void ra_spi_eri_isr(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
spi_b_eri_isr();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define _ELC_EVENT_SPI_RXI(channel) ELC_EVENT_SPI##channel##_RXI
|
||||
#define _ELC_EVENT_SPI_TXI(channel) ELC_EVENT_SPI##channel##_TXI
|
||||
#define _ELC_EVENT_SPI_TEI(channel) ELC_EVENT_SPI##channel##_TEI
|
||||
#define _ELC_EVENT_SPI_ERI(channel) ELC_EVENT_SPI##channel##_ERI
|
||||
|
||||
#define ELC_EVENT_SPI_RXI(channel) _ELC_EVENT_SPI_RXI(channel)
|
||||
#define ELC_EVENT_SPI_TXI(channel) _ELC_EVENT_SPI_TXI(channel)
|
||||
#define ELC_EVENT_SPI_TEI(channel) _ELC_EVENT_SPI_TEI(channel)
|
||||
#define ELC_EVENT_SPI_ERI(channel) _ELC_EVENT_SPI_ERI(channel)
|
||||
|
||||
#if defined(CONFIG_SPI_B_INTERRUPT)
|
||||
|
||||
#define RA_SPI_B_IRQ_CONFIG_INIT(index) \
|
||||
do { \
|
||||
ARG_UNUSED(dev); \
|
||||
\
|
||||
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, rxi, irq)] = \
|
||||
ELC_EVENT_SPI_RXI(DT_INST_PROP(index, channel)); \
|
||||
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, txi, irq)] = \
|
||||
ELC_EVENT_SPI_TXI(DT_INST_PROP(index, channel)); \
|
||||
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, tei, irq)] = \
|
||||
ELC_EVENT_SPI_TEI(DT_INST_PROP(index, channel)); \
|
||||
R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, eri, irq)] = \
|
||||
ELC_EVENT_SPI_ERI(DT_INST_PROP(index, channel)); \
|
||||
\
|
||||
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rxi, irq), \
|
||||
DT_INST_IRQ_BY_NAME(index, rxi, priority), ra_spi_rxi_isr, \
|
||||
DEVICE_DT_INST_GET(index), 0); \
|
||||
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, txi, irq), \
|
||||
DT_INST_IRQ_BY_NAME(index, txi, priority), ra_spi_txi_isr, \
|
||||
DEVICE_DT_INST_GET(index), 0); \
|
||||
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, tei, irq), \
|
||||
DT_INST_IRQ_BY_NAME(index, tei, priority), ra_spi_tei_isr, \
|
||||
DEVICE_DT_INST_GET(index), 0); \
|
||||
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, eri, irq), \
|
||||
DT_INST_IRQ_BY_NAME(index, eri, priority), ra_spi_eri_isr, \
|
||||
DEVICE_DT_INST_GET(index), 0); \
|
||||
\
|
||||
irq_enable(DT_INST_IRQ_BY_NAME(index, rxi, irq)); \
|
||||
irq_enable(DT_INST_IRQ_BY_NAME(index, txi, irq)); \
|
||||
irq_enable(DT_INST_IRQ_BY_NAME(index, eri, irq)); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define RA_SPI_B_IRQ_CONFIG_INIT(index)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SPI_B_RA_DTC
|
||||
#define RA_SPI_B_DTC_STRUCT_INIT(index)
|
||||
#define RA_SPI_B_DTC_INIT(index)
|
||||
#else
|
||||
#define RA_SPI_B_DTC_INIT(index) \
|
||||
do { \
|
||||
if (DT_INST_PROP_OR(index, rx_dtc, false)) { \
|
||||
ra_spi_data_##index.fsp_config.p_transfer_rx = \
|
||||
&ra_spi_data_##index.rx_transfer; \
|
||||
} \
|
||||
if (DT_INST_PROP_OR(index, tx_dtc, false)) { \
|
||||
ra_spi_data_##index.fsp_config.p_transfer_tx = \
|
||||
&ra_spi_data_##index.tx_transfer; \
|
||||
} \
|
||||
} while (0)
|
||||
#define RA_SPI_B_DTC_STRUCT_INIT(index) \
|
||||
.rx_transfer_info = \
|
||||
{ \
|
||||
.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \
|
||||
.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_DESTINATION, \
|
||||
.transfer_settings_word_b.irq = TRANSFER_IRQ_END, \
|
||||
.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \
|
||||
.transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_FIXED, \
|
||||
.transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \
|
||||
.transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \
|
||||
.p_dest = (void *)NULL, \
|
||||
.p_src = (void const *)NULL, \
|
||||
.num_blocks = 0, \
|
||||
.length = 0, \
|
||||
}, \
|
||||
.rx_transfer_cfg_extend = {.activation_source = DT_INST_IRQ_BY_NAME(index, rxi, irq)}, \
|
||||
.rx_transfer_cfg = \
|
||||
{ \
|
||||
.p_info = &ra_spi_data_##index.rx_transfer_info, \
|
||||
.p_extend = &ra_spi_data_##index.rx_transfer_cfg_extend, \
|
||||
}, \
|
||||
.rx_transfer = \
|
||||
{ \
|
||||
.p_ctrl = &ra_spi_data_##index.rx_transfer_ctrl, \
|
||||
.p_cfg = &ra_spi_data_##index.rx_transfer_cfg, \
|
||||
.p_api = &g_transfer_on_dtc, \
|
||||
}, \
|
||||
.tx_transfer_info = \
|
||||
{ \
|
||||
.transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED, \
|
||||
.transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE, \
|
||||
.transfer_settings_word_b.irq = TRANSFER_IRQ_END, \
|
||||
.transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \
|
||||
.transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \
|
||||
.transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \
|
||||
.transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \
|
||||
.p_dest = (void *)NULL, \
|
||||
.p_src = (void const *)NULL, \
|
||||
.num_blocks = 0, \
|
||||
.length = 0, \
|
||||
}, \
|
||||
.tx_transfer_cfg_extend = {.activation_source = DT_INST_IRQ_BY_NAME(index, txi, irq)}, \
|
||||
.tx_transfer_cfg = \
|
||||
{ \
|
||||
.p_info = &ra_spi_data_##index.tx_transfer_info, \
|
||||
.p_extend = &ra_spi_data_##index.tx_transfer_cfg_extend, \
|
||||
}, \
|
||||
.tx_transfer = { \
|
||||
.p_ctrl = &ra_spi_data_##index.tx_transfer_ctrl, \
|
||||
.p_cfg = &ra_spi_data_##index.tx_transfer_cfg, \
|
||||
.p_api = &g_transfer_on_dtc, \
|
||||
},
|
||||
#endif
|
||||
|
||||
#define RA_SPI_INIT(index) \
|
||||
\
|
||||
PINCTRL_DT_INST_DEFINE(index); \
|
||||
\
|
||||
static const struct ra_spi_config ra_spi_config_##index = { \
|
||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
|
||||
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(index)), \
|
||||
.clock_subsys = \
|
||||
{ \
|
||||
.mstp = (uint32_t *)DT_INST_CLOCKS_CELL_BY_NAME(index, spiclk, \
|
||||
mstp), \
|
||||
.stop_bit = DT_INST_CLOCKS_CELL_BY_NAME(index, spiclk, stop_bit), \
|
||||
}, \
|
||||
}; \
|
||||
\
|
||||
static struct ra_spi_data ra_spi_data_##index = { \
|
||||
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(index), ctx) \
|
||||
SPI_CONTEXT_INIT_LOCK(ra_spi_data_##index, ctx), \
|
||||
SPI_CONTEXT_INIT_SYNC(ra_spi_data_##index, ctx), \
|
||||
.fsp_config = \
|
||||
{ \
|
||||
.channel = DT_INST_PROP(index, channel), \
|
||||
.rxi_ipl = DT_INST_IRQ_BY_NAME(index, rxi, priority), \
|
||||
.rxi_irq = DT_INST_IRQ_BY_NAME(index, rxi, irq), \
|
||||
.txi_ipl = DT_INST_IRQ_BY_NAME(index, txi, priority), \
|
||||
.txi_irq = DT_INST_IRQ_BY_NAME(index, txi, irq), \
|
||||
.tei_ipl = DT_INST_IRQ_BY_NAME(index, tei, priority), \
|
||||
.tei_irq = DT_INST_IRQ_BY_NAME(index, tei, irq), \
|
||||
.eri_ipl = DT_INST_IRQ_BY_NAME(index, eri, priority), \
|
||||
.eri_irq = DT_INST_IRQ_BY_NAME(index, eri, irq), \
|
||||
}, \
|
||||
RA_SPI_B_DTC_STRUCT_INIT(index)}; \
|
||||
\
|
||||
static int spi_b_ra_init##index(const struct device *dev) \
|
||||
{ \
|
||||
RA_SPI_B_DTC_INIT(index); \
|
||||
int err = spi_b_ra_init(dev); \
|
||||
if (err != 0) { \
|
||||
return err; \
|
||||
} \
|
||||
RA_SPI_B_IRQ_CONFIG_INIT(index); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(index, spi_b_ra_init##index, PM_DEVICE_DT_INST_GET(index), \
|
||||
&ra_spi_data_##index, &ra_spi_config_##index, POST_KERNEL, \
|
||||
CONFIG_SPI_INIT_PRIORITY, &ra_spi_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(RA_SPI_INIT)
|
|
@ -303,6 +303,32 @@
|
|||
compatible = "renesas,ra-rsip-e51a-trng";
|
||||
};
|
||||
|
||||
spi0: spi@4035c000 {
|
||||
compatible = "renesas,ra8-spi-b";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
channel = <0>;
|
||||
clocks = <&pclka MSTPB 19>;
|
||||
clock-names = "spiclk";
|
||||
interrupts = <28 1>, <29 1>, <30 1>, <31 1>;
|
||||
interrupt-names = "rxi", "txi", "tei", "eri";
|
||||
reg = <0x4035c000 0x100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi1: spi@4035c100 {
|
||||
compatible = "renesas,ra8-spi-b";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
channel = <1>;
|
||||
clocks = <&pclka MSTPB 18>;
|
||||
clock-names = "spiclk";
|
||||
interrupts = <32 1>, <33 1>, <34 1>, <35 1>;
|
||||
interrupt-names = "rxi", "txi", "tei", "eri";
|
||||
reg = <0x4035c100 0x100>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
option_setting_ofs: option_setting_ofs@300a100 {
|
||||
compatible = "zephyr,memory-region";
|
||||
reg = <0x0300a100 0x18>;
|
||||
|
|
37
dts/bindings/spi/renesas,ra8-spi-b.yaml
Normal file
37
dts/bindings/spi/renesas,ra8-spi-b.yaml
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Renesas RA8 SPI_B controller
|
||||
|
||||
compatible: "renesas,ra8-spi-b"
|
||||
|
||||
include: [spi-controller.yaml, pinctrl-device.yaml]
|
||||
|
||||
properties:
|
||||
channel:
|
||||
type: int
|
||||
required: true
|
||||
|
||||
reg:
|
||||
required: true
|
||||
|
||||
clocks:
|
||||
required: true
|
||||
|
||||
tx-dtc:
|
||||
type: boolean
|
||||
|
||||
rx-dtc:
|
||||
type: boolean
|
||||
|
||||
pinctrl-0:
|
||||
required: true
|
||||
|
||||
pinctrl-names:
|
||||
required: true
|
||||
|
||||
interrupts:
|
||||
required: true
|
||||
|
||||
interrupt-names:
|
||||
required: true
|
|
@ -48,3 +48,8 @@ config HAS_RENESAS_RA_RSIP_E51A
|
|||
Includes RSIP-E51A implementation for SCE driver
|
||||
|
||||
endif
|
||||
|
||||
config USE_RA_FSP_SPI_B
|
||||
bool
|
||||
help
|
||||
Enable RA FSP SPI-B driver
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_SPI_B_INTERRUPT=y
|
||||
CONFIG_SPI_B_RA_DTC=y
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Renesas Electronics Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&pinctrl {
|
||||
spi0_default_alt: spi0_default_alt {
|
||||
group1 {
|
||||
/* MISO MOSI RSPCK SSL */
|
||||
psels = <RA_PSEL(RA_PSEL_SPI, 7, 0)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 7, 1)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 7, 2)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi1_default_alt: spi1_default_alt {
|
||||
group1 {
|
||||
/* MISO MOSI RSPCK SSL */
|
||||
psels = <RA_PSEL(RA_PSEL_SPI, 4, 10)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 4, 11)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 4, 12)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 4, 13)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&ioport7 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ioport4 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
rx-dtc;
|
||||
tx-dtc;
|
||||
status = "okay";
|
||||
pinctrl-0 = <&spi0_default_alt>;
|
||||
pinctrl-names = "default";
|
||||
cs-gpios = <&ioport7 3 GPIO_ACTIVE_LOW>;
|
||||
dut_spi_dt: test-spi-dev@0 {
|
||||
compatible = "vnd,spi-device";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
|
||||
dut_spis: &spi1 {
|
||||
rx-dtc;
|
||||
tx-dtc;
|
||||
status = "okay";
|
||||
pinctrl-0 = <&spi1_default_alt>;
|
||||
pinctrl-names = "default";
|
||||
};
|
6
tests/drivers/spi/spi_loopback/boards/ek_ra8d1.conf
Normal file
6
tests/drivers/spi/spi_loopback/boards/ek_ra8d1.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_SPI_LOOPBACK_MODE_LOOP=y
|
||||
CONFIG_SPI_B_INTERRUPT=y
|
||||
CONFIG_SPI_B_RA_DTC=y
|
20
tests/drivers/spi/spi_loopback/boards/ek_ra8d1.overlay
Normal file
20
tests/drivers/spi/spi_loopback/boards/ek_ra8d1.overlay
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Renesas Electronics Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&spi0 {
|
||||
rx-dtc;
|
||||
tx-dtc;
|
||||
slow@0 {
|
||||
compatible = "test-spi-loopback-slow";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <2000000>;
|
||||
};
|
||||
|
||||
fast@0 {
|
||||
compatible = "test-spi-loopback-fast";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <3000000>;
|
||||
};
|
||||
};
|
6
tests/drivers/spi/spi_loopback/boards/ek_ra8m1.conf
Normal file
6
tests/drivers/spi/spi_loopback/boards/ek_ra8m1.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_SPI_LOOPBACK_MODE_LOOP=y
|
||||
CONFIG_SPI_B_INTERRUPT=y
|
||||
CONFIG_SPI_B_RA_DTC=y
|
36
tests/drivers/spi/spi_loopback/boards/ek_ra8m1.overlay
Normal file
36
tests/drivers/spi/spi_loopback/boards/ek_ra8m1.overlay
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Renesas Electronics Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/dt-bindings/clock/ra_clock.h>
|
||||
|
||||
&pinctrl {
|
||||
spi0_default: spi0_default {
|
||||
group1 {
|
||||
/* MISO MOSI RSPCK SSL*/
|
||||
psels = <RA_PSEL(RA_PSEL_SPI, 6, 9)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 6, 11)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 6, 10)>,
|
||||
<RA_PSEL(RA_PSEL_SPI, 6, 12)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
rx-dtc;
|
||||
tx-dtc;
|
||||
pinctrl-0 = <&spi0_default>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
slow@0 {
|
||||
compatible = "test-spi-loopback-slow";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <2000000>;
|
||||
};
|
||||
fast@0 {
|
||||
compatible = "test-spi-loopback-fast";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <3000000>;
|
||||
};
|
||||
};
|
6
tests/drivers/spi/spi_loopback/boards/mck_ra8t1.conf
Normal file
6
tests/drivers/spi/spi_loopback/boards/mck_ra8t1.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_SPI_LOOPBACK_MODE_LOOP=y
|
||||
CONFIG_SPI_B_INTERRUPT=y
|
||||
CONFIG_SPI_B_RA_DTC=y
|
20
tests/drivers/spi/spi_loopback/boards/mck_ra8t1.overlay
Normal file
20
tests/drivers/spi/spi_loopback/boards/mck_ra8t1.overlay
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Renesas Electronics Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&spi0 {
|
||||
rx-dtc;
|
||||
tx-dtc;
|
||||
slow@0 {
|
||||
compatible = "test-spi-loopback-slow";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <2000000>;
|
||||
};
|
||||
|
||||
fast@0 {
|
||||
compatible = "test-spi-loopback-fast";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <3000000>;
|
||||
};
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue