drivers: spi: Add cypress PSoC-6 scb spi driver
Add Cypress PSoC-6 SCB[spi] driver. Signed-off-by: Gerson Fernando Budke <gerson.budke@atl-electronics.com>
This commit is contained in:
parent
3155b762a6
commit
d999531f7f
6 changed files with 529 additions and 0 deletions
|
@ -23,5 +23,6 @@ zephyr_library_sources_ifdef(CONFIG_SPI_GECKO spi_gecko.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_SPI_XLNX_AXI_QUADSPI spi_xlnx_axi_quadspi.c)
|
zephyr_library_sources_ifdef(CONFIG_SPI_XLNX_AXI_QUADSPI spi_xlnx_axi_quadspi.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_ESP32_SPIM spi_esp32_spim.c)
|
zephyr_library_sources_ifdef(CONFIG_ESP32_SPIM spi_esp32_spim.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_SPI_TEST spi_test.c)
|
zephyr_library_sources_ifdef(CONFIG_SPI_TEST spi_test.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_SPI_PSOC6 spi_psoc6.c)
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c)
|
zephyr_library_sources_ifdef(CONFIG_USERSPACE spi_handlers.c)
|
||||||
|
|
|
@ -73,4 +73,6 @@ source "drivers/spi/Kconfig.esp32"
|
||||||
|
|
||||||
source "drivers/spi/Kconfig.test"
|
source "drivers/spi/Kconfig.test"
|
||||||
|
|
||||||
|
source "drivers/spi/Kconfig.psoc6"
|
||||||
|
|
||||||
endif # SPI
|
endif # SPI
|
||||||
|
|
10
drivers/spi/Kconfig.psoc6
Normal file
10
drivers/spi/Kconfig.psoc6
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Cypress SCB[SPI] configuration
|
||||||
|
|
||||||
|
# Copyright (c) 2021 ATL Electronics
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config SPI_PSOC6
|
||||||
|
bool "PSoC-6 MCU SCB spi driver"
|
||||||
|
depends on SOC_FAMILY_PSOC6
|
||||||
|
help
|
||||||
|
This option enables the SCB[SPI] driver for PSoC-6 SoC family.
|
421
drivers/spi/spi_psoc6.c
Normal file
421
drivers/spi/spi_psoc6.c
Normal file
|
@ -0,0 +1,421 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||||
|
* Copyright (c) 2017, NXP
|
||||||
|
* Copyright (c) 2021, ATL Electronics.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT cypress_psoc6_spi
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(spi_psoc6);
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <drivers/spi.h>
|
||||||
|
#include <soc.h>
|
||||||
|
|
||||||
|
#include "spi_context.h"
|
||||||
|
|
||||||
|
#include "cy_syslib.h"
|
||||||
|
#include "cy_sysclk.h"
|
||||||
|
#include "cy_scb_spi.h"
|
||||||
|
#include "cy_sysint.h"
|
||||||
|
|
||||||
|
#define SPI_CHIP_SELECT_COUNT 4
|
||||||
|
#define SPI_MAX_DATA_WIDTH 16
|
||||||
|
#define SPI_PSOC6_CLK_DIV_NUMBER 1
|
||||||
|
|
||||||
|
struct spi_psoc6_config {
|
||||||
|
CySCB_Type *base;
|
||||||
|
uint32_t periph_id;
|
||||||
|
void (*irq_config_func)(const struct device *dev);
|
||||||
|
uint32_t num_pins;
|
||||||
|
struct soc_gpio_pin pins[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct spi_psoc6_transfer {
|
||||||
|
uint8_t *txData;
|
||||||
|
uint8_t *rxData;
|
||||||
|
size_t dataSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct spi_psoc6_data {
|
||||||
|
struct spi_context ctx;
|
||||||
|
struct cy_stc_scb_spi_config cfg;
|
||||||
|
struct spi_psoc6_transfer xfer;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void spi_psoc6_transfer_next_packet(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct spi_psoc6_config *config = dev->config;
|
||||||
|
struct spi_psoc6_data *data = dev->data;
|
||||||
|
struct spi_context *ctx = &data->ctx;
|
||||||
|
struct spi_psoc6_transfer *xfer = &data->xfer;
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
|
LOG_DBG("TX L: %d, RX L: %d", ctx->tx_len, ctx->rx_len);
|
||||||
|
|
||||||
|
if ((ctx->tx_len == 0U) && (ctx->rx_len == 0U)) {
|
||||||
|
/* nothing left to rx or tx, we're done! */
|
||||||
|
xfer->dataSize = 0U;
|
||||||
|
|
||||||
|
spi_context_cs_control(ctx, false);
|
||||||
|
spi_context_complete(ctx, 0U);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->tx_len == 0U) {
|
||||||
|
/* rx only, nothing to tx */
|
||||||
|
xfer->txData = NULL;
|
||||||
|
xfer->rxData = ctx->rx_buf;
|
||||||
|
xfer->dataSize = ctx->rx_len;
|
||||||
|
} else if (ctx->rx_len == 0U) {
|
||||||
|
/* tx only, nothing to rx */
|
||||||
|
xfer->txData = (uint8_t *) ctx->tx_buf;
|
||||||
|
xfer->rxData = NULL;
|
||||||
|
xfer->dataSize = ctx->tx_len;
|
||||||
|
} else if (ctx->tx_len == ctx->rx_len) {
|
||||||
|
/* rx and tx are the same length */
|
||||||
|
xfer->txData = (uint8_t *) ctx->tx_buf;
|
||||||
|
xfer->rxData = ctx->rx_buf;
|
||||||
|
xfer->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.
|
||||||
|
*/
|
||||||
|
xfer->txData = (uint8_t *) ctx->tx_buf;
|
||||||
|
xfer->rxData = ctx->rx_buf;
|
||||||
|
xfer->dataSize = ctx->rx_len;
|
||||||
|
} 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.
|
||||||
|
*/
|
||||||
|
xfer->txData = (uint8_t *) ctx->tx_buf;
|
||||||
|
xfer->rxData = ctx->rx_buf;
|
||||||
|
xfer->dataSize = ctx->tx_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xfer->txData != NULL) {
|
||||||
|
if (Cy_SCB_SPI_WriteArray(config->base, xfer->txData,
|
||||||
|
xfer->dataSize) != xfer->dataSize) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Need fill TX fifo with garbage to perform read.
|
||||||
|
* This keeps logic simple and saves stack.
|
||||||
|
* Use 0 as dummy data.
|
||||||
|
*/
|
||||||
|
for (count = 0U; count < xfer->dataSize; count++) {
|
||||||
|
if (Cy_SCB_SPI_Write(config->base, 0U) == 0U) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("TRX L: %d", xfer->dataSize);
|
||||||
|
|
||||||
|
return;
|
||||||
|
err:
|
||||||
|
/* no FIFO available to run the transfer */
|
||||||
|
xfer->dataSize = 0U;
|
||||||
|
|
||||||
|
spi_context_cs_control(ctx, false);
|
||||||
|
spi_context_complete(ctx, -ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spi_psoc6_isr(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct spi_psoc6_config *config = dev->config;
|
||||||
|
struct spi_psoc6_data *data = dev->data;
|
||||||
|
|
||||||
|
Cy_SCB_ClearMasterInterrupt(config->base,
|
||||||
|
CY_SCB_MASTER_INTR_SPI_DONE);
|
||||||
|
|
||||||
|
/* extract data from RX FIFO */
|
||||||
|
if (data->xfer.rxData != NULL) {
|
||||||
|
Cy_SCB_SPI_ReadArray(config->base,
|
||||||
|
data->xfer.rxData,
|
||||||
|
data->xfer.dataSize);
|
||||||
|
} else {
|
||||||
|
Cy_SCB_ClearRxFifo(config->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set next data block */
|
||||||
|
spi_context_update_tx(&data->ctx, 1, data->xfer.dataSize);
|
||||||
|
spi_context_update_rx(&data->ctx, 1, data->xfer.dataSize);
|
||||||
|
|
||||||
|
/* Start next block
|
||||||
|
* Since 1 byte at TX FIFO will start transfer data, let's try
|
||||||
|
* minimize ISR recursion disabling all interrupt sources when add
|
||||||
|
* data on TX FIFO
|
||||||
|
*/
|
||||||
|
Cy_SCB_SetMasterInterruptMask(config->base, 0U);
|
||||||
|
|
||||||
|
spi_psoc6_transfer_next_packet(dev);
|
||||||
|
|
||||||
|
if (data->xfer.dataSize > 0U) {
|
||||||
|
Cy_SCB_SetMasterInterruptMask(config->base,
|
||||||
|
CY_SCB_MASTER_INTR_SPI_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t spi_psoc6_get_freqdiv(uint32_t frequency)
|
||||||
|
{
|
||||||
|
uint32_t oversample;
|
||||||
|
uint32_t bus_freq = 100000000UL;
|
||||||
|
/*
|
||||||
|
* TODO: Get PerBusSpeed when clocks are available to PSoC-6.
|
||||||
|
* Currently the bus freq is fixed to 50Mhz and max SPI clk can be
|
||||||
|
* 12.5MHz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (oversample = 4; oversample < 16; oversample++) {
|
||||||
|
if ((bus_freq / oversample) <= frequency) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Oversample [4, 16] */
|
||||||
|
return oversample;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spi_psoc6_master_get_defaults(struct cy_stc_scb_spi_config *cfg)
|
||||||
|
{
|
||||||
|
cfg->spiMode = CY_SCB_SPI_MASTER;
|
||||||
|
cfg->subMode = CY_SCB_SPI_MOTOROLA;
|
||||||
|
cfg->sclkMode = 0U;
|
||||||
|
cfg->oversample = 0U;
|
||||||
|
cfg->rxDataWidth = 0U;
|
||||||
|
cfg->txDataWidth = 0U;
|
||||||
|
cfg->enableMsbFirst = false;
|
||||||
|
cfg->enableFreeRunSclk = false;
|
||||||
|
cfg->enableInputFilter = false;
|
||||||
|
cfg->enableMisoLateSample = false;
|
||||||
|
cfg->enableTransferSeperation = false;
|
||||||
|
cfg->ssPolarity = 0U;
|
||||||
|
cfg->enableWakeFromSleep = false;
|
||||||
|
cfg->rxFifoTriggerLevel = 0U;
|
||||||
|
cfg->rxFifoIntEnableMask = 0U;
|
||||||
|
cfg->txFifoTriggerLevel = 0U;
|
||||||
|
cfg->txFifoIntEnableMask = 0U;
|
||||||
|
cfg->masterSlaveIntEnableMask = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spi_psoc6_configure(const struct device *dev,
|
||||||
|
const struct spi_config *spi_cfg)
|
||||||
|
{
|
||||||
|
struct spi_psoc6_data *data = dev->data;
|
||||||
|
uint32_t word_size;
|
||||||
|
|
||||||
|
if (spi_context_configured(&data->ctx, spi_cfg)) {
|
||||||
|
/* This configuration is already in use */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_size = SPI_WORD_SIZE_GET(spi_cfg->operation);
|
||||||
|
if (word_size > SPI_MAX_DATA_WIDTH) {
|
||||||
|
LOG_ERR("Word size %d is greater than %d",
|
||||||
|
word_size, SPI_MAX_DATA_WIDTH);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SPI_OP_MODE_GET(spi_cfg->operation) == SPI_OP_MODE_MASTER) {
|
||||||
|
spi_psoc6_master_get_defaults(&data->cfg);
|
||||||
|
|
||||||
|
if (spi_cfg->slave > SPI_CHIP_SELECT_COUNT) {
|
||||||
|
LOG_ERR("Slave %d is greater than %d",
|
||||||
|
spi_cfg->slave, SPI_CHIP_SELECT_COUNT);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->cfg.rxDataWidth = data->cfg.txDataWidth = word_size;
|
||||||
|
|
||||||
|
if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) {
|
||||||
|
if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) {
|
||||||
|
data->cfg.sclkMode = CY_SCB_SPI_CPHA1_CPOL1;
|
||||||
|
} else {
|
||||||
|
data->cfg.sclkMode = CY_SCB_SPI_CPHA1_CPOL0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) {
|
||||||
|
data->cfg.sclkMode = CY_SCB_SPI_CPHA0_CPOL1;
|
||||||
|
} else {
|
||||||
|
data->cfg.sclkMode = CY_SCB_SPI_CPHA0_CPOL0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->cfg.enableMsbFirst = !!!(spi_cfg->operation &
|
||||||
|
SPI_TRANSFER_LSB);
|
||||||
|
data->cfg.oversample = spi_psoc6_get_freqdiv(spi_cfg->frequency);
|
||||||
|
|
||||||
|
data->ctx.config = spi_cfg;
|
||||||
|
spi_context_cs_configure(&data->ctx);
|
||||||
|
} else {
|
||||||
|
/* Slave mode is not implemented yet. */
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spi_psoc6_transceive_sync_loop(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct spi_psoc6_config *config = dev->config;
|
||||||
|
struct spi_psoc6_data *data = dev->data;
|
||||||
|
|
||||||
|
while (data->xfer.dataSize > 0U) {
|
||||||
|
while (!Cy_SCB_IsTxComplete(config->base)) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->xfer.rxData != NULL) {
|
||||||
|
Cy_SCB_SPI_ReadArray(config->base,
|
||||||
|
data->xfer.rxData,
|
||||||
|
data->xfer.dataSize);
|
||||||
|
} else {
|
||||||
|
Cy_SCB_ClearRxFifo(config->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_context_update_tx(&data->ctx, 1, data->xfer.dataSize);
|
||||||
|
spi_context_update_rx(&data->ctx, 1, data->xfer.dataSize);
|
||||||
|
|
||||||
|
spi_psoc6_transfer_next_packet(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spi_psoc6_transceive(const 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)
|
||||||
|
{
|
||||||
|
const struct spi_psoc6_config *config = dev->config;
|
||||||
|
struct spi_psoc6_data *data = dev->data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
spi_context_lock(&data->ctx, asynchronous, signal, spi_cfg);
|
||||||
|
|
||||||
|
LOG_DBG("\n\n");
|
||||||
|
|
||||||
|
ret = spi_psoc6_configure(dev, spi_cfg);
|
||||||
|
if (ret) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cy_SCB_SPI_Init(config->base, &data->cfg, NULL);
|
||||||
|
Cy_SCB_SPI_SetActiveSlaveSelect(config->base, spi_cfg->slave);
|
||||||
|
Cy_SCB_SPI_Enable(config->base);
|
||||||
|
|
||||||
|
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1);
|
||||||
|
|
||||||
|
spi_context_cs_control(&data->ctx, true);
|
||||||
|
|
||||||
|
spi_psoc6_transfer_next_packet(dev);
|
||||||
|
|
||||||
|
if (asynchronous) {
|
||||||
|
Cy_SCB_SetMasterInterruptMask(config->base,
|
||||||
|
CY_SCB_MASTER_INTR_SPI_DONE);
|
||||||
|
} else {
|
||||||
|
spi_psoc6_transceive_sync_loop(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = spi_context_wait_for_completion(&data->ctx);
|
||||||
|
|
||||||
|
Cy_SCB_SPI_Disable(config->base, NULL);
|
||||||
|
|
||||||
|
out:
|
||||||
|
spi_context_release(&data->ctx, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spi_psoc6_transceive_sync(const struct device *dev,
|
||||||
|
const struct spi_config *spi_cfg,
|
||||||
|
const struct spi_buf_set *tx_bufs,
|
||||||
|
const struct spi_buf_set *rx_bufs)
|
||||||
|
{
|
||||||
|
return spi_psoc6_transceive(dev, spi_cfg, tx_bufs,
|
||||||
|
rx_bufs, false, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPI_ASYNC
|
||||||
|
static int spi_psoc6_transceive_async(const 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 spi_psoc6_transceive(dev, spi_cfg, tx_bufs,
|
||||||
|
rx_bufs, true, async);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_SPI_ASYNC */
|
||||||
|
|
||||||
|
static int spi_psoc6_release(const struct device *dev,
|
||||||
|
const struct spi_config *config)
|
||||||
|
{
|
||||||
|
struct spi_psoc6_data *data = dev->data;
|
||||||
|
|
||||||
|
spi_context_unlock_unconditionally(&data->ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spi_psoc6_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct spi_psoc6_config *config = dev->config;
|
||||||
|
|
||||||
|
soc_gpio_list_configure(config->pins, config->num_pins);
|
||||||
|
|
||||||
|
Cy_SysClk_PeriphAssignDivider(config->periph_id,
|
||||||
|
CY_SYSCLK_DIV_8_BIT,
|
||||||
|
SPI_PSOC6_CLK_DIV_NUMBER);
|
||||||
|
Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT,
|
||||||
|
SPI_PSOC6_CLK_DIV_NUMBER, 0U);
|
||||||
|
Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT,
|
||||||
|
SPI_PSOC6_CLK_DIV_NUMBER);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPI_ASYNC
|
||||||
|
config->irq_config_func(dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return spi_psoc6_release(dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct spi_driver_api spi_psoc6_driver_api = {
|
||||||
|
.transceive = spi_psoc6_transceive_sync,
|
||||||
|
#ifdef CONFIG_SPI_ASYNC
|
||||||
|
.transceive_async = spi_psoc6_transceive_async,
|
||||||
|
#endif
|
||||||
|
.release = spi_psoc6_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SPI_PSOC6_DEVICE_INIT(n) \
|
||||||
|
static void spi_psoc6_spi##n##_irq_cfg(const struct device *port); \
|
||||||
|
static const struct spi_psoc6_config spi_psoc6_config_##n = { \
|
||||||
|
.base = (CySCB_Type *)DT_INST_REG_ADDR(n), \
|
||||||
|
.periph_id = DT_INST_PROP(n, peripheral_id), \
|
||||||
|
.num_pins = CY_PSOC6_DT_INST_NUM_PINS(n), \
|
||||||
|
.pins = CY_PSOC6_DT_INST_PINS(n), \
|
||||||
|
.irq_config_func = spi_psoc6_spi##n##_irq_cfg, \
|
||||||
|
}; \
|
||||||
|
static struct spi_psoc6_data spi_psoc6_dev_data_##n = { \
|
||||||
|
SPI_CONTEXT_INIT_LOCK(spi_psoc6_dev_data_##n, ctx), \
|
||||||
|
SPI_CONTEXT_INIT_SYNC(spi_psoc6_dev_data_##n, ctx), \
|
||||||
|
}; \
|
||||||
|
DEVICE_DT_INST_DEFINE(n, &spi_psoc6_init, NULL, \
|
||||||
|
&spi_psoc6_dev_data_##n, \
|
||||||
|
&spi_psoc6_config_##n, POST_KERNEL, \
|
||||||
|
CONFIG_SPI_INIT_PRIORITY, \
|
||||||
|
&spi_psoc6_driver_api); \
|
||||||
|
static void spi_psoc6_spi##n##_irq_cfg(const struct device *port) \
|
||||||
|
{ \
|
||||||
|
CY_PSOC6_DT_INST_NVIC_INSTALL(n, \
|
||||||
|
spi_psoc6_isr); \
|
||||||
|
};
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(SPI_PSOC6_DEVICE_INIT)
|
|
@ -248,6 +248,97 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
spi0: spi@40610000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40610000 0x10000>;
|
||||||
|
interrupts = <41 7>;
|
||||||
|
peripheral-id = <0>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_0";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi1: spi@40620000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40620000 0x10000>;
|
||||||
|
interrupts = <42 7>;
|
||||||
|
peripheral-id = <1>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_1";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi2: spi@40630000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40630000 0x10000>;
|
||||||
|
interrupts = <43 7>;
|
||||||
|
peripheral-id = <2>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_2";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi3: spi@40640000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40640000 0x10000>;
|
||||||
|
interrupts = <44 7>;
|
||||||
|
peripheral-id = <3>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_3";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi4: spi@40650000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40650000 0x10000>;
|
||||||
|
interrupts = <45 7>;
|
||||||
|
peripheral-id = <4>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_4";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi5: spi@40660000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40660000 0x10000>;
|
||||||
|
interrupts = <46 7>;
|
||||||
|
peripheral-id = <5>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_5";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi6: spi@40670000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40670000 0x10000>;
|
||||||
|
interrupts = <47 7>;
|
||||||
|
peripheral-id = <6>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_6";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi7: spi@40680000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40680000 0x10000>;
|
||||||
|
interrupts = <48 7>;
|
||||||
|
peripheral-id = <7>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_7";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
spi8: spi@40690000 {
|
||||||
|
compatible = "cypress,psoc6-spi";
|
||||||
|
reg = <0x40690000 0x10000>;
|
||||||
|
interrupts = <18 7>;
|
||||||
|
peripheral-id = <8>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "spi_8";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
uart0: uart@40610000 {
|
uart0: uart@40610000 {
|
||||||
compatible = "cypress,psoc6-uart";
|
compatible = "cypress,psoc6-uart";
|
||||||
reg = <0x40610000 0x10000>;
|
reg = <0x40610000 0x10000>;
|
||||||
|
|
|
@ -21,6 +21,10 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||||
|
|
||||||
source "soc/arm/cypress/psoc6/Kconfig.defconfig.psoc*"
|
source "soc/arm/cypress/psoc6/Kconfig.defconfig.psoc*"
|
||||||
|
|
||||||
|
config SPI_PSOC6
|
||||||
|
default y
|
||||||
|
depends on SPI
|
||||||
|
|
||||||
config UART_PSOC6
|
config UART_PSOC6
|
||||||
default y
|
default y
|
||||||
depends on SERIAL
|
depends on SERIAL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue