@@ -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 )
@@ -519,8 +508,9 @@ static void spi_stm32_read_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
519508 } while (nb_fifo < data -> fifo_threshold && data -> rx_len );
520509}
521510
522- static void spi_stm32_shift_fifo (SPI_TypeDef * spi , struct spi_stm32_data * data )
511+ static int spi_stm32_shift_fifo (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
523512{
513+ SPI_TypeDef * spi = cfg -> spi ;
524514 uint32_t transfer_dir = LL_SPI_GetTransferDirection (spi );
525515
526516 if (transfer_dir == LL_SPI_FULL_DUPLEX && LL_SPI_IsActiveFlag_DXP (spi ) &&
@@ -566,7 +556,12 @@ static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
566556 LL_SPI_ClearFlag_TXTF (spi );
567557 LL_SPI_ClearFlag_EOT (spi );
568558 ll_func_disable_spi (spi );
569- LL_SPI_SetTransferSize (spi , data -> tx_len );
559+ if (data -> tx_len <= cfg -> max_transfer_size ) {
560+ LL_SPI_SetTransferSize (spi , data -> tx_len );
561+ } else {
562+ LOG_ERR ("Buffer size exceeds maximal supported value" );
563+ return - EINVAL ;
564+ }
570565 LL_SPI_Enable (spi );
571566 LL_SPI_StartMasterTransfer (spi );
572567#ifdef CONFIG_SPI_STM32_INTERRUPT
@@ -577,15 +572,16 @@ static void spi_stm32_shift_fifo(SPI_TypeDef *spi, struct spi_stm32_data *data)
577572 spi_stm32_send_fifo (spi , data );
578573 }
579574 }
575+ return 0 ;
580576}
581577#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
582578
583579/* Shift a SPI frame as master. */
584- static void spi_stm32_shift_m (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
580+ static int spi_stm32_shift_m (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
585581{
586582 if (cfg -> fifo_enabled ) {
587583#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
588- spi_stm32_shift_fifo (cfg -> spi , data );
584+ return spi_stm32_shift_fifo (cfg , data );
589585#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
590586 } else {
591587 uint32_t transfer_dir = LL_SPI_GetTransferDirection (cfg -> spi );
@@ -606,6 +602,7 @@ static void spi_stm32_shift_m(const struct spi_stm32_config *cfg, struct spi_stm
606602 spi_stm32_read_next_frame (cfg -> spi , data );
607603 }
608604 }
605+ return 0 ;
609606}
610607
611608/* Shift a SPI frame as slave. */
@@ -629,9 +626,13 @@ static void spi_stm32_shift_s(SPI_TypeDef *spi, struct spi_stm32_data *data)
629626static int spi_stm32_shift_frames (const struct spi_stm32_config * cfg , struct spi_stm32_data * data )
630627{
631628 spi_operation_t operation = data -> ctx .config -> operation ;
629+ int ret ;
632630
633631 if (SPI_OP_MODE_GET (operation ) == SPI_OP_MODE_MASTER ) {
634- spi_stm32_shift_m (cfg , data );
632+ ret = spi_stm32_shift_m (cfg , data );
633+ if (ret != 0 ) {
634+ return ret ;
635+ }
635636 } else {
636637 spi_stm32_shift_s (cfg -> spi , data );
637638 }
@@ -724,6 +725,12 @@ static void spi_stm32_iodev_complete(const struct device *dev, int status);
724725static int spi_stm32_configure (const struct device * dev ,
725726 const struct spi_config * config ,
726727 bool write );
728+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
729+ static int32_t spi_stm32_set_transfer_size (const struct device * dev ,
730+ const struct spi_config * config ,
731+ const struct spi_buf_set * tx_bufs ,
732+ const struct spi_buf_set * rx_bufs );
733+ #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
727734
728735static void spi_stm32_iodev_msg_start (const struct device * dev , struct spi_config * config ,
729736 const uint8_t * tx_buf , uint8_t * rx_buf , uint32_t buf_len )
@@ -759,8 +766,10 @@ static void spi_stm32_iodev_msg_start(const struct device *dev, struct spi_confi
759766 /* SPI needs to be disabled to set the transfer size */
760767 ll_func_disable_spi (spi );
761768 }
762- data -> tx_len = data -> rx_len = size ;
763- LL_SPI_SetTransferSize (spi , size );
769+
770+ if (spi_stm32_set_transfer_size (dev , NULL , NULL , NULL ) != 0 ) {
771+ spi_stm32_iodev_complete (dev , - EINVAL );
772+ }
764773 }
765774#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
766775
@@ -1162,11 +1171,10 @@ static int spi_stm32_configure(const struct device *dev,
11621171
11631172#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
11641173 if (cfg -> fifo_enabled ) {
1165- uint8_t fifo_size = spi_stm32_get_fifo_size (dev );
11661174 /* Do not use bits2bytes here, we want to get 3 for 24-bit operation */
11671175 uint8_t dfs = (SPI_WORD_SIZE_GET (config -> operation ) + 7U ) / 8U ;
11681176 /* FIFO threshold should not exceed half the FIFO size */
1169- data -> fifo_threshold = fifo_size / (dfs * 2U );
1177+ data -> fifo_threshold = cfg -> fifo_size / (dfs * 2U );
11701178 } else {
11711179 data -> fifo_threshold = 1 ;
11721180 }
@@ -1202,8 +1210,6 @@ static int spi_stm32_release(const struct device *dev, const struct spi_config *
12021210 return 0 ;
12031211}
12041212
1205- #ifndef CONFIG_SPI_RTIO
1206-
12071213#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
12081214static int32_t spi_stm32_count_bufset_frames (const struct spi_config * config ,
12091215 const struct spi_buf_set * bufs )
@@ -1233,36 +1239,19 @@ static int32_t spi_stm32_count_bufset_frames(const struct spi_config *config,
12331239 return frames ;
12341240}
12351241
1236- static int32_t spi_stm32_count_total_frames (const struct spi_config * config ,
1237- const struct spi_buf_set * tx_bufs ,
1238- const struct spi_buf_set * rx_bufs )
1239- {
1240- int tx_frames = spi_stm32_count_bufset_frames (config , tx_bufs );
1241-
1242- if (tx_frames < 0 ) {
1243- return tx_frames ;
1244- }
1245-
1246- int rx_frames = spi_stm32_count_bufset_frames (config , rx_bufs );
1247-
1248- if (rx_frames < 0 ) {
1249- return rx_frames ;
1250- }
1251-
1252- return MAX (rx_frames , tx_frames );
1253- }
1254-
1255- __maybe_unused
1256- static int32_t spi_stm32_set_transfer_size (SPI_TypeDef * spi ,
1242+ static int32_t spi_stm32_set_transfer_size (const struct device * dev ,
12571243 const struct spi_config * config ,
12581244 const struct spi_buf_set * tx_bufs ,
12591245 const struct spi_buf_set * rx_bufs )
12601246{
1247+ struct spi_stm32_data * data = dev -> data ;
1248+ const struct spi_stm32_config * cfg = dev -> config ;
1249+ SPI_TypeDef * spi = cfg -> spi ;
12611250 uint32_t transfer_dir = LL_SPI_GetTransferDirection (spi );
12621251 int32_t frames ;
12631252
12641253 if (transfer_dir == LL_SPI_FULL_DUPLEX ) {
1265- frames = spi_stm32_count_total_frames ( config , tx_bufs , rx_bufs );
1254+ frames = spi_context_max_continuous_chunk ( & data -> ctx );
12661255 } else if (transfer_dir == LL_SPI_HALF_DUPLEX_TX ) {
12671256 frames = spi_stm32_count_bufset_frames (config , tx_bufs );
12681257 } else {
@@ -1273,12 +1262,19 @@ static int32_t spi_stm32_set_transfer_size(SPI_TypeDef *spi,
12731262 return frames ;
12741263 }
12751264
1276- LL_SPI_SetTransferSize (spi , (uint32_t )frames );
1265+ if (frames <= cfg -> max_transfer_size ) {
1266+ data -> tx_len = data -> rx_len = frames ;
1267+ LL_SPI_SetTransferSize (spi , (uint32_t )frames );
1268+ } else {
1269+ LOG_ERR ("Buffer size exceeds maximal supported value" );
1270+ return - EINVAL ;
1271+ }
12771272
12781273 return 0 ;
12791274}
12801275#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
12811276
1277+ #ifndef CONFIG_SPI_RTIO
12821278static int spi_stm32_half_duplex_switch_to_receive (const struct spi_stm32_config * cfg ,
12831279 struct spi_stm32_data * data )
12841280{
@@ -1397,8 +1393,10 @@ static int transceive(const struct device *dev,
13971393
13981394#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
13991395 if (cfg -> fifo_enabled && SPI_OP_MODE_GET (config -> operation ) == SPI_OP_MODE_MASTER ) {
1400- data -> tx_len = data -> rx_len = spi_context_max_continuous_chunk (& data -> ctx );
1401- LL_SPI_SetTransferSize (spi , data -> tx_len );
1396+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
1397+ if (ret != 0 ) {
1398+ goto end ;
1399+ }
14021400 }
14031401
14041402#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi) */
@@ -1544,7 +1542,7 @@ static int transceive_dma(const struct device *dev,
15441542
15451543#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
15461544 if (transfer_dir == LL_SPI_HALF_DUPLEX_RX ) {
1547- ret = spi_stm32_set_transfer_size (spi , config , tx_bufs , rx_bufs );
1545+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
15481546
15491547 if (ret < 0 ) {
15501548 goto end ;
@@ -1604,7 +1602,10 @@ static int transceive_dma(const struct device *dev,
16041602#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
16051603 if (cfg -> fifo_enabled && transfer_dir == LL_SPI_FULL_DUPLEX &&
16061604 SPI_OP_MODE_GET (config -> operation ) == SPI_OP_MODE_MASTER ) {
1607- LL_SPI_SetTransferSize (spi , dma_len );
1605+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
1606+ if (ret != 0 ) {
1607+ goto end ;
1608+ }
16081609 LL_SPI_Enable (spi );
16091610 LL_SPI_StartMasterTransfer (spi );
16101611 }
@@ -1685,7 +1686,7 @@ static int transceive_dma(const struct device *dev,
16851686 transfer_dir = LL_SPI_HALF_DUPLEX_RX ;
16861687
16871688#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_spi )
1688- ret = spi_stm32_set_transfer_size (spi , config , tx_bufs , rx_bufs );
1689+ ret = spi_stm32_set_transfer_size (dev , config , tx_bufs , rx_bufs );
16891690
16901691 if (ret < 0 ) {
16911692 break ;
@@ -1990,6 +1991,10 @@ static int spi_stm32_init(const struct device *dev)
19901991 (.midi_clocks = DT_INST_PROP(id, midi_clock),)) \
19911992 IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
19921993 (.mssi_clocks = DT_INST_PROP(id, mssi_clock),)) \
1994+ IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
1995+ (.fifo_size = DT_INST_PROP(id, fifo_size),)) \
1996+ IF_ENABLED(DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi), \
1997+ (.max_transfer_size = DT_INST_PROP(id, max_transfer_size),)) \
19931998 }; \
19941999 \
19952000 IF_ENABLED(CONFIG_SPI_RTIO, \
0 commit comments