@@ -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,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)
637634static 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);
732733static 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
736743static 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 )
12161222static 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
12901286static 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, \
0 commit comments