Skip to content

Commit c0e3ec7

Browse files
decsnynashif
authored andcommitted
spi_nxp_lpspi: Add maximum wait time of fifo empty
Instead of waiting forever and potentially allowing infinite loop on ISR, wait some arbitrary amount of cycles to error out if it isn't happening. Still make this configurable for debugging purposes. Signed-off-by: Declan Snyder <declan.snyder@nxp.com>
1 parent 691e759 commit c0e3ec7

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

drivers/spi/spi_nxp_lpspi/Kconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,17 @@ config SPI_MCUX_LPSPI_CPU
3636
This has lower latency than DMA-based driver but over the
3737
longer transfers will likely have less bandwidth and use more CPU time.
3838

39+
config SPI_NXP_LPSPI_TXFIFO_WAIT_CYCLES
40+
int "Number of CPU cycles to wait on TX fifo empty"
41+
default 0 if DEBUG
42+
default 10000
43+
help
44+
This option most likely does not need changed.
45+
The drivers tend to need to wait on confirming the transmit command
46+
is consumed by the hardware by checking of the TX fifo is emptied.
47+
This option gives a maximum number of CPU cycles to wait on that check.
48+
The special value of 0 means infinite, which can be useful for debugging
49+
for if there is some programming error that causes TX fifo not to empty.
50+
The default of 10000 is arbitrary.
51+
3952
endif # SPI_MCUX_LPSPI

drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,10 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg
337337
base->TCR |= LPSPI_TCR_CONT_MASK;
338338
}
339339
/* tcr is written to tx fifo */
340-
lpspi_wait_tx_fifo_empty(dev);
340+
ret = lpspi_wait_tx_fifo_empty(dev);
341+
if (ret) {
342+
return ret;
343+
}
341344

342345
/* start the transfer sequence which are handled by irqs */
343346
lpspi_next_tx_fill(dev);

drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,24 @@ static inline clock_ip_name_t lpspi_get_clock(LPSPI_Type *const base)
6060
}
6161
#endif
6262

63-
void lpspi_wait_tx_fifo_empty(const struct device *dev)
63+
int lpspi_wait_tx_fifo_empty(const struct device *dev)
6464
{
6565
LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base);
66+
int arbitrary_cycle_limit = CONFIG_SPI_NXP_LPSPI_TXFIFO_WAIT_CYCLES;
67+
bool limit_wait = arbitrary_cycle_limit > 0;
6668

67-
while (LPSPI_GetTxFifoCount(base) != 0) {
69+
while (FIELD_GET(LPSPI_FSR_TXCOUNT_MASK, base->FSR) != 0) {
70+
if (!limit_wait) {
71+
continue;
72+
}
73+
74+
if (arbitrary_cycle_limit-- < 0) {
75+
LOG_WRN("Failed waiting for TX fifo empty");
76+
return -EIO;
77+
}
6878
}
79+
80+
return 0;
6981
}
7082

7183
int spi_lpspi_release(const struct device *dev, const struct spi_config *spi_cfg)
@@ -185,7 +197,7 @@ int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cf
185197
base->CR |= LPSPI_CR_DBGEN_MASK;
186198
}
187199

188-
return 0;
200+
return lpspi_wait_tx_fifo_empty(dev);
189201
}
190202

191203
static void lpspi_module_system_init(LPSPI_Type *base)

drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ int spi_nxp_init_common(const struct device *dev);
6868
/* common api function for now */
6969
int spi_lpspi_release(const struct device *dev, const struct spi_config *spi_cfg);
7070

71-
void lpspi_wait_tx_fifo_empty(const struct device *dev);
71+
int lpspi_wait_tx_fifo_empty(const struct device *dev);
7272

7373
#define SPI_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n) \
7474
nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), DEVICE_DT_INST_GET(n), \

0 commit comments

Comments
 (0)