drivers: spi: Add optional delays to mcux flexcomm spi driver
Adds optional device tree properties to insert delays between spi chip select assert/deassert and the clock edges, and also between spi frames and transfers to the mcux flexcomm spi driver. If the properties are not set, no additional delay is inserted. Verified expected behavior on mimxrt685_evk and check with a scope that the pre- and post-delay could be changed from the device tree properties. Signed-off-by: Bryce Wilkins <bryce.wilkins@gmail.com>
This commit is contained in:
parent
4b822395ed
commit
219bf88fe8
2 changed files with 62 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
|||
#ifdef CONFIG_SPI_MCUX_FLEXCOMM_DMA
|
||||
#include <drivers/dma.h>
|
||||
#endif
|
||||
#include <sys_clock.h>
|
||||
|
||||
LOG_MODULE_REGISTER(spi_mcux_flexcomm, CONFIG_SPI_LOG_LEVEL);
|
||||
|
||||
|
@ -28,6 +29,10 @@ struct spi_mcux_config {
|
|||
const struct device *clock_dev;
|
||||
clock_control_subsys_t clock_subsys;
|
||||
void (*irq_config_func)(const struct device *dev);
|
||||
uint32_t pre_delay;
|
||||
uint32_t post_delay;
|
||||
uint32_t frame_delay;
|
||||
uint32_t transfer_delay;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SPI_MCUX_FLEXCOMM_DMA
|
||||
|
@ -143,6 +148,18 @@ static void spi_mcux_transfer_callback(SPI_Type *base,
|
|||
spi_mcux_transfer_next_packet(data->dev);
|
||||
}
|
||||
|
||||
static uint8_t spi_clock_cycles(uint32_t delay_ns, uint32_t sck_frequency_hz)
|
||||
{
|
||||
/* Convert delay_ns to an integer number of clock cycles of frequency
|
||||
* sck_frequency_hz. The maximum delay is 15 clock cycles.
|
||||
*/
|
||||
uint8_t delay_cycles = (uint64_t)delay_ns * sck_frequency_hz / NSEC_PER_SEC;
|
||||
|
||||
delay_cycles = MIN(delay_cycles, 15);
|
||||
|
||||
return delay_cycles;
|
||||
}
|
||||
|
||||
static int spi_mcux_configure(const struct device *dev,
|
||||
const struct spi_config *spi_cfg)
|
||||
{
|
||||
|
@ -211,6 +228,17 @@ static int spi_mcux_configure(const struct device *dev,
|
|||
|
||||
master_config.baudRate_Bps = spi_cfg->frequency;
|
||||
|
||||
spi_delay_config_t *delayConfig = &master_config.delayConfig;
|
||||
|
||||
delayConfig->preDelay = spi_clock_cycles(config->pre_delay,
|
||||
spi_cfg->frequency);
|
||||
delayConfig->postDelay = spi_clock_cycles(config->post_delay,
|
||||
spi_cfg->frequency);
|
||||
delayConfig->frameDelay = spi_clock_cycles(config->frame_delay,
|
||||
spi_cfg->frequency);
|
||||
delayConfig->transferDelay = spi_clock_cycles(config->transfer_delay,
|
||||
spi_cfg->frequency);
|
||||
|
||||
SPI_MasterInit(base, &master_config, clock_freq);
|
||||
|
||||
SPI_MasterTransferCreateHandle(base, &data->handle,
|
||||
|
@ -769,6 +797,10 @@ static void spi_mcux_config_func_##id(const struct device *dev) \
|
|||
.clock_subsys = \
|
||||
(clock_control_subsys_t)DT_INST_CLOCKS_CELL(id, name),\
|
||||
SPI_MCUX_FLEXCOMM_IRQ_HANDLER_FUNC(id) \
|
||||
.pre_delay = DT_INST_PROP_OR(id, pre_delay, 0), \
|
||||
.post_delay = DT_INST_PROP_OR(id, post_delay, 0), \
|
||||
.frame_delay = DT_INST_PROP_OR(id, frame_delay, 0), \
|
||||
.transfer_delay = DT_INST_PROP_OR(id, transfer_delay, 0), \
|
||||
}; \
|
||||
static struct spi_mcux_data spi_mcux_data_##id = { \
|
||||
SPI_CONTEXT_INIT_LOCK(spi_mcux_data_##id, ctx), \
|
||||
|
|
|
@ -6,3 +6,33 @@ description: NXP LPC SPI controller
|
|||
compatible: "nxp,lpc-spi"
|
||||
|
||||
include: [spi-controller.yaml, "nxp,lpc-flexcomm.yaml"]
|
||||
|
||||
properties:
|
||||
pre-delay:
|
||||
type: int
|
||||
required: false
|
||||
description: |
|
||||
Delay in nanoseconds inserted between chip select assert to the first
|
||||
clock edge. If not set, no additional delay is inserted.
|
||||
|
||||
post-delay:
|
||||
type: int
|
||||
required: false
|
||||
description: |
|
||||
Delay in nanoseconds inserted between the last clock edge to the chip
|
||||
select deassert. If not set, no additional delay is inserted.
|
||||
|
||||
frame-delay:
|
||||
type: int
|
||||
required: false
|
||||
description: |
|
||||
Delay in nanoseconds inserted between data frames when chip select is
|
||||
asserted and the EOF flag is set. If not set, no additional delay is
|
||||
inserted.
|
||||
|
||||
transfer-delay:
|
||||
type: int
|
||||
required: false
|
||||
description: |
|
||||
Delay in nanoseconds inserted between transfers when chip select is
|
||||
deasserted. If not set, no additional delay is inserted.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue