Skip to content

Commit 6b2330f

Browse files
committed
drivers: spi: stm32: use the new fifo related property
Use the new SPI FIFO related property to retrieve FIFO size (instead of guessing it from the supported data width), and to check that the TSIZE register is not written with a value that exceeds the maximal supported transfer size. Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
1 parent 0eaded2 commit 6b2330f

File tree

2 files changed

+57
-50
lines changed

2 files changed

+57
-50
lines changed

‎drivers/spi/spi_stm32.c‎

Lines changed: 55 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,6 @@ static const uint32_t table_datawidth[] = {
115115
static const uint32_t table_fifo_threshold[] = {
116116
LISTIFY(8, STM32_SPI_FIFO_THRESHOLD, (,))
117117
};
118-
119-
static uint8_t spi_stm32_get_fifo_size(const struct device *dev)
120-
{
121-
const struct spi_stm32_config *cfg = dev->config;
122-
123-
if(cfg->datawidth == STM32_SPI_DATA_WIDTH_FULL_4_TO_32_BIT) {
124-
return 16U;
125-
} else {
126-
return 8U;
127-
}
128-
}
129118
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
130119

131120
static bool spi_stm32_is_data_width_supported(const struct device *dev, uint32_t width)
@@ -527,8 +516,9 @@ static void spi_stm32_read_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
527516
} while (nb_fifo < data->fifo_threshold && data->rx_len);
528517
}
529518

530-
static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
519+
static int spi_stm32_shift_fifo(const struct spi_stm32_config *cfg, struct spi_stm32_data *data)
531520
{
521+
SPI_TypeDef *spi = cfg->spi;
532522
uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi);
533523

534524
if (transfer_dir == LL_SPI_FULL_DUPLEX && LL_SPI_IsActiveFlag_DXP(spi) &&
@@ -574,7 +564,12 @@ static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
574564
LL_SPI_ClearFlag_TXTF(spi);
575565
LL_SPI_ClearFlag_EOT(spi);
576566
ll_func_disable_spi(spi);
577-
LL_SPI_SetTransferSize(spi, data->tx_len);
567+
if (data->tx_len <= cfg->max_transfer_size) {
568+
LL_SPI_SetTransferSize(spi, data->tx_len);
569+
} else {
570+
LOG_ERR("Buffer size exceeds maximal supported value");
571+
return -EINVAL;
572+
}
578573
LL_SPI_Enable(spi);
579574
LL_SPI_StartMasterTransfer(spi);
580575
#ifdef CONFIG_SPI_STM32_INTERRUPT
@@ -585,15 +580,16 @@ static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
585580
spi_stm32_send_fifo(spi, data);
586581
}
587582
}
583+
return 0;
588584
}
589585
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
590586

591587
/* Shift a SPI frame as master. */
592-
static void spi_stm32_shift_m(const struct spi_stm32_config *cfg, struct spi_stm32_data *data)
588+
static int spi_stm32_shift_m(const struct spi_stm32_config *cfg, struct spi_stm32_data *data)
593589
{
594590
if (cfg->fifo_enabled) {
595591
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
596-
spi_stm32_shift_fifo(cfg->spi, data);
592+
return spi_stm32_shift_fifo(cfg, data);
597593
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
598594
} else {
599595
uint32_t transfer_dir = LL_SPI_GetTransferDirection(cfg->spi);
@@ -614,6 +610,7 @@ static void spi_stm32_shift_m(const struct spi_stm32_config *cfg, struct spi_stm
614610
spi_stm32_read_next_frame(cfg->spi, data);
615611
}
616612
}
613+
return 0;
617614
}
618615

619616
/* Shift a SPI frame as slave. */
@@ -637,9 +634,13 @@ static void spi_stm32_shift_s(SPI_TypeDef *spi, struct spi_stm32_data *data)
637634
static int spi_stm32_shift_frames(const struct spi_stm32_config *cfg, struct spi_stm32_data *data)
638635
{
639636
spi_operation_t operation = data->ctx.config->operation;
637+
int ret;
640638

641639
if (SPI_OP_MODE_GET(operation) == SPI_OP_MODE_MASTER) {
642-
spi_stm32_shift_m(cfg, data);
640+
ret = spi_stm32_shift_m(cfg, data);
641+
if (ret != 0) {
642+
return ret;
643+
}
643644
} else {
644645
spi_stm32_shift_s(cfg->spi, data);
645646
}
@@ -732,6 +733,12 @@ static void spi_stm32_iodev_complete(const struct device *dev, int status);
732733
static int spi_stm32_configure(const struct device *dev,
733734
const struct spi_config *config,
734735
bool write);
736+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
737+
static int32_t spi_stm32_set_transfer_size(const struct device *dev,
738+
const struct spi_config *config,
739+
const struct spi_buf_set *tx_bufs,
740+
const struct spi_buf_set *rx_bufs);
741+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
735742

736743
static void spi_stm32_iodev_msg_start(const struct device *dev, struct spi_config *config,
737744
const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t buf_len)
@@ -767,8 +774,10 @@ static void spi_stm32_iodev_msg_start(const struct device *dev, struct spi_confi
767774
/* SPI needs to be disabled to set the transfer size */
768775
ll_func_disable_spi(spi);
769776
}
770-
data->tx_len = data->rx_len = size;
771-
LL_SPI_SetTransferSize(spi, size);
777+
778+
if (spi_stm32_set_transfer_size(dev, NULL, NULL, NULL) != 0) {
779+
spi_stm32_iodev_complete(dev, -EINVAL);
780+
}
772781
}
773782
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
774783

@@ -1170,11 +1179,10 @@ static int spi_stm32_configure(const struct device *dev,
11701179

11711180
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
11721181
if (cfg->fifo_enabled) {
1173-
uint8_t fifo_size = spi_stm32_get_fifo_size(dev);
11741182
/* Do not use bits2bytes here, we want to get 3 for 24-bit operation */
11751183
uint8_t dfs = (SPI_WORD_SIZE_GET(config->operation) + 7U) / 8U;
11761184
/* FIFO threshold should not exceed half the FIFO size */
1177-
data->fifo_threshold = fifo_size / (dfs * 2U);
1185+
data->fifo_threshold = cfg->fifo_size / (dfs * 2U);
11781186
} else {
11791187
data->fifo_threshold = 1;
11801188
}
@@ -1210,8 +1218,6 @@ static int spi_stm32_release(const struct device *dev, const struct spi_config *
12101218
return 0;
12111219
}
12121220

1213-
#ifndef CONFIG_SPI_RTIO
1214-
12151221
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
12161222
static int32_t spi_stm32_count_bufset_frames(const struct spi_config *config,
12171223
const struct spi_buf_set *bufs)
@@ -1241,36 +1247,19 @@ static int32_t spi_stm32_count_bufset_frames(const struct spi_config *config,
12411247
return frames;
12421248
}
12431249

1244-
static int32_t spi_stm32_count_total_frames(const struct spi_config *config,
1245-
const struct spi_buf_set *tx_bufs,
1246-
const struct spi_buf_set *rx_bufs)
1247-
{
1248-
int tx_frames = spi_stm32_count_bufset_frames(config, tx_bufs);
1249-
1250-
if (tx_frames < 0) {
1251-
return tx_frames;
1252-
}
1253-
1254-
int rx_frames = spi_stm32_count_bufset_frames(config, rx_bufs);
1255-
1256-
if (rx_frames < 0) {
1257-
return rx_frames;
1258-
}
1259-
1260-
return MAX(rx_frames, tx_frames);
1261-
}
1262-
1263-
__maybe_unused
1264-
static int32_t spi_stm32_set_transfer_size(SPI_TypeDef *spi,
1250+
static int32_t spi_stm32_set_transfer_size(const struct device *dev,
12651251
const struct spi_config *config,
12661252
const struct spi_buf_set *tx_bufs,
12671253
const struct spi_buf_set *rx_bufs)
12681254
{
1255+
struct spi_stm32_data *data = dev->data;
1256+
const struct spi_stm32_config *cfg = dev->config;
1257+
SPI_TypeDef *spi = cfg->spi;
12691258
uint32_t transfer_dir = LL_SPI_GetTransferDirection(spi);
12701259
int32_t frames;
12711260

12721261
if (transfer_dir == LL_SPI_FULL_DUPLEX) {
1273-
frames = spi_stm32_count_total_frames(config, tx_bufs, rx_bufs);
1262+
frames = spi_context_max_continuous_chunk(&data->ctx);
12741263
} else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX) {
12751264
frames = spi_stm32_count_bufset_frames(config, tx_bufs);
12761265
} else {
@@ -1281,12 +1270,19 @@ static int32_t spi_stm32_set_transfer_size(SPI_TypeDef *spi,
12811270
return frames;
12821271
}
12831272

1284-
LL_SPI_SetTransferSize(spi, (uint32_t)frames);
1273+
if (frames <= cfg->max_transfer_size) {
1274+
data->tx_len = data->rx_len = frames;
1275+
LL_SPI_SetTransferSize(spi, (uint32_t)frames);
1276+
} else {
1277+
LOG_ERR("Buffer size exceeds maximal supported value");
1278+
return -EINVAL;
1279+
}
12851280

12861281
return 0;
12871282
}
12881283
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
12891284

1285+
#ifndef CONFIG_SPI_RTIO
12901286
static int spi_stm32_half_duplex_switch_to_receive(const struct spi_stm32_config *cfg,
12911287
struct spi_stm32_data *data)
12921288
{
@@ -1405,8 +1401,10 @@ static int transceive(const struct device *dev,
14051401

14061402
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
14071403
if (cfg->fifo_enabled && SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) {
1408-
data->tx_len = data->rx_len = spi_context_max_continuous_chunk(&data->ctx);
1409-
LL_SPI_SetTransferSize(spi, data->tx_len);
1404+
ret = spi_stm32_set_transfer_size(dev, config, tx_bufs, rx_bufs);
1405+
if (ret != 0) {
1406+
goto end;
1407+
}
14101408
}
14111409

14121410
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
@@ -1552,7 +1550,7 @@ static int transceive_dma(const struct device *dev,
15521550

15531551
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
15541552
if (transfer_dir == LL_SPI_HALF_DUPLEX_RX) {
1555-
ret = spi_stm32_set_transfer_size(spi, config, tx_bufs, rx_bufs);
1553+
ret = spi_stm32_set_transfer_size(dev, config, tx_bufs, rx_bufs);
15561554

15571555
if (ret < 0) {
15581556
goto end;
@@ -1612,7 +1610,10 @@ static int transceive_dma(const struct device *dev,
16121610
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
16131611
if (cfg->fifo_enabled && transfer_dir == LL_SPI_FULL_DUPLEX &&
16141612
SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) {
1615-
LL_SPI_SetTransferSize(spi, dma_len);
1613+
ret = spi_stm32_set_transfer_size(dev, config, tx_bufs, rx_bufs);
1614+
if (ret != 0) {
1615+
goto end;
1616+
}
16161617
LL_SPI_Enable(spi);
16171618
LL_SPI_StartMasterTransfer(spi);
16181619
}
@@ -1693,7 +1694,7 @@ static int transceive_dma(const struct device *dev,
16931694
transfer_dir = LL_SPI_HALF_DUPLEX_RX;
16941695

16951696
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
1696-
ret = spi_stm32_set_transfer_size(spi, config, tx_bufs, rx_bufs);
1697+
ret = spi_stm32_set_transfer_size(dev, config, tx_bufs, rx_bufs);
16971698

16981699
if (ret < 0) {
16991700
break;
@@ -1998,6 +1999,10 @@ static int spi_stm32_init(const struct device *dev)
19981999
(.midi_clocks = DT_INST_PROP(id, midi_clock),)) \
19992000
IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
20002001
(.mssi_clocks = DT_INST_PROP(id, mssi_clock),)) \
2002+
IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
2003+
(.fifo_size = DT_INST_PROP(id, fifo_size),)) \
2004+
IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
2005+
(.max_transfer_size = DT_INST_PROP(id, max_transfer_size),)) \
20012006
}; \
20022007
\
20032008
IF_ENABLED(CONFIG_SPI_RTIO, \

‎drivers/spi/spi_stm32.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ struct spi_stm32_config {
3434
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
3535
int midi_clocks;
3636
int mssi_clocks;
37+
uint8_t fifo_size;
38+
uint32_t max_transfer_size;
3739
#endif
3840
size_t pclk_len;
3941
const struct stm32_pclken *pclken;

0 commit comments

Comments
 (0)