@@ -115,17 +115,6 @@ static const uint32_t table_datawidth[] = {
115115static 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
131120static 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,6 +564,10 @@ 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 );
567+ if (data -> tx_len > cfg -> fifo_max_transfer_size ) {
568+ LOG_ERR ("Buffer size exceeds maximal supported value" );
569+ return - EINVAL ;
570+ }
577571 LL_SPI_SetTransferSize (spi , data -> tx_len );
578572 LL_SPI_Enable (spi );
579573 LL_SPI_StartMasterTransfer (spi );
@@ -585,15 +579,16 @@ static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
585579 spi_stm32_send_fifo (spi , data );
586580 }
587581 }
582+ return 0 ;
588583}
589584#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
590585
591586/* Shift a SPI frame as master. */
592- static void spi_stm32_shift_m (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
587+ static int spi_stm32_shift_m (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
593588{
594589 if (cfg -> fifo_enabled ) {
595590#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
596- spi_stm32_shift_fifo (cfg -> spi , data );
591+ return spi_stm32_shift_fifo (cfg , data );
597592#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
598593 } else {
599594 uint32_t transfer_dir = LL_SPI_GetTransferDirection (cfg -> spi );
@@ -614,6 +609,7 @@ static void spi_stm32_shift_m(const struct spi_stm32_config *cfg, struct spi_stm
614609 spi_stm32_read_next_frame (cfg -> spi , data );
615610 }
616611 }
612+ return 0 ;
617613}
618614
619615/* Shift a SPI frame as slave. */
@@ -637,9 +633,13 @@ static void spi_stm32_shift_s(SPI_TypeDef *spi, struct spi_stm32_data *data)
637633static int spi_stm32_shift_frames (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
638634{
639635 spi_operation_t operation = data -> ctx .config -> operation ;
636+ int ret ;
640637
641638 if (SPI_OP_MODE_GET (operation ) == SPI_OP_MODE_MASTER ) {
642- spi_stm32_shift_m (cfg , data );
639+ ret = spi_stm32_shift_m (cfg , data );
640+ if (ret != 0 ) {
641+ return ret ;
642+ }
643643 } else {
644644 spi_stm32_shift_s (cfg -> spi , data );
645645 }
@@ -732,6 +732,12 @@ static void spi_stm32_iodev_complete(const struct device *dev, int status);
732732static int spi_stm32_configure (const struct device * dev ,
733733 const struct spi_config * config ,
734734 bool write );
735+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
736+ static int32_t spi_stm32_set_transfer_size (const struct device * dev ,
737+ const struct spi_config * config ,
738+ const struct spi_buf_set * tx_bufs ,
739+ const struct spi_buf_set * rx_bufs );
740+ #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
735741
736742static void spi_stm32_iodev_msg_start (const struct device * dev , struct spi_config * config ,
737743 const uint8_t * tx_buf , uint8_t * rx_buf , uint32_t buf_len )
@@ -767,8 +773,10 @@ static void spi_stm32_iodev_msg_start(const struct device *dev, struct spi_confi
767773 /* SPI needs to be disabled to set the transfer size */
768774 ll_func_disable_spi (spi );
769775 }
770- data -> tx_len = data -> rx_len = size ;
771- LL_SPI_SetTransferSize (spi , size );
776+
777+ if (spi_stm32_set_transfer_size (dev , NULL , NULL , NULL ) != 0 ) {
778+ spi_stm32_iodev_complete (dev , - EINVAL );
779+ }
772780 }
773781#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
774782
@@ -1170,11 +1178,10 @@ static int spi_stm32_configure(const struct device *dev,
11701178
11711179#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
11721180 if (cfg -> fifo_enabled ) {
1173- uint8_t fifo_size = spi_stm32_get_fifo_size (dev );
11741181 /* Do not use bits2bytes here, we want to get 3 for 24-bit operation */
11751182 uint8_t dfs = DIV_ROUND_UP (SPI_WORD_SIZE_GET (config -> operation ), 8U );
11761183 /* FIFO threshold should not exceed half the FIFO size */
1177- data -> fifo_threshold = fifo_size / (dfs * 2U );
1184+ data -> fifo_threshold = cfg -> fifo_size / (dfs * 2U );
11781185 } else {
11791186 data -> fifo_threshold = 1 ;
11801187 }
@@ -1210,8 +1217,6 @@ static int spi_stm32_release(const struct device *dev, const struct spi_config *
12101217 return 0 ;
12111218}
12121219
1213- #ifndef CONFIG_SPI_RTIO
1214-
12151220#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
12161221static int32_t spi_stm32_count_bufset_frames (const struct spi_config * config ,
12171222 const struct spi_buf_set * bufs )
@@ -1241,36 +1246,19 @@ static int32_t spi_stm32_count_bufset_frames(const struct spi_config *config,
12411246 return frames ;
12421247}
12431248
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 ,
1249+ static int32_t spi_stm32_set_transfer_size (const struct device * dev ,
12651250 const struct spi_config * config ,
12661251 const struct spi_buf_set * tx_bufs ,
12671252 const struct spi_buf_set * rx_bufs )
12681253{
1254+ struct spi_stm32_data * data = dev -> data ;
1255+ const struct spi_stm32_config * cfg = dev -> config ;
1256+ SPI_TypeDef * spi = cfg -> spi ;
12691257 uint32_t transfer_dir = LL_SPI_GetTransferDirection (spi );
12701258 int32_t frames ;
12711259
12721260 if (transfer_dir == LL_SPI_FULL_DUPLEX ) {
1273- frames = spi_stm32_count_total_frames ( config , tx_bufs , rx_bufs );
1261+ frames = spi_context_max_continuous_chunk ( & data -> ctx );
12741262 } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX ) {
12751263 frames = spi_stm32_count_bufset_frames (config , tx_bufs );
12761264 } else {
@@ -1281,12 +1269,19 @@ static int32_t spi_stm32_set_transfer_size(SPI_TypeDef *spi,
12811269 return frames ;
12821270 }
12831271
1284- LL_SPI_SetTransferSize (spi , (uint32_t )frames );
1272+ if (frames <= cfg -> fifo_max_transfer_size ) {
1273+ data -> tx_len = data -> rx_len = frames ;
1274+ LL_SPI_SetTransferSize (spi , (uint32_t )frames );
1275+ } else {
1276+ LOG_ERR ("Buffer size exceeds maximal supported value" );
1277+ return - EINVAL ;
1278+ }
12851279
12861280 return 0 ;
12871281}
12881282#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
12891283
1284+ #ifndef CONFIG_SPI_RTIO
12901285static int spi_stm32_half_duplex_switch_to_receive (const struct spi_stm32_config * cfg ,
12911286 struct spi_stm32_data * data )
12921287{
@@ -1405,8 +1400,10 @@ static int transceive(const struct device *dev,
14051400
14061401#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
14071402 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 );
1403+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
1404+ if (ret != 0 ) {
1405+ goto end ;
1406+ }
14101407 }
14111408
14121409#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
@@ -1552,7 +1549,7 @@ static int transceive_dma(const struct device *dev,
15521549
15531550#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
15541551 if (transfer_dir == LL_SPI_HALF_DUPLEX_RX ) {
1555- ret = spi_stm32_set_transfer_size (spi , config , tx_bufs , rx_bufs );
1552+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
15561553
15571554 if (ret < 0 ) {
15581555 goto end ;
@@ -1612,7 +1609,10 @@ static int transceive_dma(const struct device *dev,
16121609#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
16131610 if (cfg -> fifo_enabled && transfer_dir == LL_SPI_FULL_DUPLEX &&
16141611 SPI_OP_MODE_GET (config -> operation ) == SPI_OP_MODE_MASTER ) {
1615- LL_SPI_SetTransferSize (spi , dma_len );
1612+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
1613+ if (ret != 0 ) {
1614+ break ;
1615+ }
16161616 LL_SPI_Enable (spi );
16171617 LL_SPI_StartMasterTransfer (spi );
16181618 }
@@ -1693,7 +1693,7 @@ static int transceive_dma(const struct device *dev,
16931693 transfer_dir = LL_SPI_HALF_DUPLEX_RX ;
16941694
16951695#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
1696- ret = spi_stm32_set_transfer_size (spi , config , tx_bufs , rx_bufs );
1696+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
16971697
16981698 if (ret < 0 ) {
16991699 break ;
@@ -1998,6 +1998,10 @@ static int spi_stm32_init(const struct device *dev)
19981998 (.midi_clocks = DT_INST_PROP(id, midi_clock),)) \
19991999 IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
20002000 (.mssi_clocks = DT_INST_PROP(id, mssi_clock),)) \
2001+ IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
2002+ (.fifo_size = DT_INST_PROP(id, fifo_size),)) \
2003+ IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
2004+ (.fifo_max_transfer_size = DT_INST_PROP(id, fifo_max_transfer_size),))\
20012005 }; \
20022006 \
20032007 IF_ENABLED(CONFIG_SPI_RTIO, \
0 commit comments