@@ -205,6 +205,37 @@ static void spi_max32_setup(mxc_spi_regs_t *spi, mxc_spi_req_t *req, uint8_t dfs
205205 MXC_SPI_ClearFlags (spi );
206206}
207207
208+ static void spi_cs_assert (const struct device * dev )
209+ {
210+ const struct max32_spi_config * cfg = dev -> config ;
211+ struct max32_spi_data * data = dev -> data ;
212+ struct spi_context * ctx = & data -> ctx ;
213+
214+ if (spi_cs_is_gpio (ctx -> config )) {
215+ MXC_SPI_HWSSControl (cfg -> regs , false);
216+ spi_context_cs_control (ctx , true);
217+ } else {
218+ MXC_SPI_HWSSControl (cfg -> regs , true);
219+ cfg -> regs -> ctrl0 = (cfg -> regs -> ctrl0 & ~MXC_F_SPI_CTRL0_START ) |
220+ ADI_MAX32_SPI_CTRL0_SS_CTRL ;
221+ }
222+ }
223+
224+ static void spi_cs_deassert (const struct device * dev )
225+ {
226+ const struct max32_spi_config * cfg = dev -> config ;
227+ struct max32_spi_data * data = dev -> data ;
228+ struct spi_context * ctx = & data -> ctx ;
229+
230+ if (spi_cs_is_gpio (ctx -> config )) {
231+ spi_context_cs_control (ctx , false);
232+ } else {
233+ cfg -> regs -> ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL |
234+ ADI_MAX32_SPI_CTRL_EN );
235+ cfg -> regs -> ctrl0 |= ADI_MAX32_SPI_CTRL_EN ;
236+ }
237+ }
238+
208239#ifndef CONFIG_SPI_MAX32_INTERRUPT
209240static int spi_max32_transceive_sync (mxc_spi_regs_t * spi , struct max32_spi_data * data ,
210241 uint8_t dfs_shift )
@@ -228,15 +259,23 @@ static int spi_max32_transceive_sync(mxc_spi_regs_t *spi, struct max32_spi_data
228259 req -> txCnt +=
229260 MXC_SPI_WriteTXFIFO (spi , & req -> txData [req -> txCnt ], remain );
230261 }
231- if (!(spi -> ctrl0 & MXC_F_SPI_CTRL0_START )) {
232- spi -> ctrl0 |= MXC_F_SPI_CTRL0_START ;
233- }
234262 }
235263
236264 if (req -> rxCnt < rx_len ) {
237265 req -> rxCnt += MXC_SPI_ReadRXFIFO (spi , & req -> rxData [req -> rxCnt ],
238266 rx_len - req -> rxCnt );
239267 }
268+
269+ if (!(spi -> ctrl0 & MXC_F_SPI_CTRL0_START )) {
270+ /* Transfer not started */
271+ if ((MXC_SPI_GetTXFIFOAvailable (spi ) - MXC_SPI_FIFO_DEPTH ) > 0 ) {
272+ /* Data remaining in the TX FIFO, ensure TX started */
273+ spi -> ctrl0 |= MXC_F_SPI_CTRL0_START ;
274+ } else if (MXC_SPI_GetRXFIFOAvailable (spi ) < (rx_len - req -> rxCnt )) {
275+ /* Not enough data into the RX FIFO */
276+ spi -> ctrl0 |= MXC_F_SPI_CTRL0_START ;
277+ }
278+ }
240279 } while ((req -> txCnt < tx_len ) || (req -> rxCnt < rx_len ));
241280
242281 do {
@@ -307,7 +346,19 @@ static int spi_max32_transceive(const struct device *dev)
307346 break ;
308347 }
309348#else
310- data -> req .txLen = len ;
349+ if ((ctx -> config -> operation & SPI_HALF_DUPLEX )
350+ #if defined(CONFIG_SPI_EXTENDED_MODES )
351+ || (ctx -> config -> operation & SPI_LINES_DUAL )
352+ || (ctx -> config -> operation & SPI_LINES_QUAD )
353+ || (ctx -> config -> operation & SPI_LINES_OCTAL )
354+ #endif
355+ ) {
356+ /* Half duplex mode, tx should be set only if no rx */
357+ data -> req .txLen = ctx -> tx_buf ? len : 0 ;
358+ } else {
359+ /* Full duplex mode, tx and rx can be set independently */
360+ data -> req .txLen = len ;
361+ }
311362 data -> req .txData = (uint8_t * )ctx -> tx_buf ;
312363 data -> req .rxLen = len ;
313364 data -> req .rxData = ctx -> rx_buf ;
@@ -375,10 +426,6 @@ static int transceive(const struct device *dev, const struct spi_config *config,
375426 int ret = 0 ;
376427 struct max32_spi_data * data = dev -> data ;
377428 struct spi_context * ctx = & data -> ctx ;
378- #ifndef CONFIG_SPI_RTIO
379- const struct max32_spi_config * cfg = dev -> config ;
380- bool hw_cs_ctrl = true;
381- #endif
382429
383430#ifndef CONFIG_SPI_MAX32_INTERRUPT
384431 if (async ) {
@@ -397,19 +444,8 @@ static int transceive(const struct device *dev, const struct spi_config *config,
397444
398445 spi_context_buffers_setup (ctx , tx_bufs , rx_bufs , 1 );
399446
400- /* Check if CS GPIO exists */
401- if (spi_cs_is_gpio (config )) {
402- hw_cs_ctrl = false;
403- }
404- MXC_SPI_HWSSControl (cfg -> regs , hw_cs_ctrl );
405-
406- /* Assert the CS line if HW control disabled */
407- if (!hw_cs_ctrl ) {
408- spi_context_cs_control (ctx , true);
409- } else {
410- cfg -> regs -> ctrl0 =
411- (cfg -> regs -> ctrl0 & ~MXC_F_SPI_CTRL0_START ) | ADI_MAX32_SPI_CTRL0_SS_CTRL ;
412- }
447+ /* Assert the CS line */
448+ spi_cs_assert (dev );
413449
414450#ifdef CONFIG_SPI_MAX32_INTERRUPT
415451 do {
@@ -433,15 +469,9 @@ static int transceive(const struct device *dev, const struct spi_config *config,
433469
434470#endif /* CONFIG_SPI_MAX32_INTERRUPT */
435471
436- /* Deassert the CS line if hw control disabled */
437- if (!async ) {
438- if (!hw_cs_ctrl ) {
439- spi_context_cs_control (ctx , false);
440- } else {
441- cfg -> regs -> ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL |
442- ADI_MAX32_SPI_CTRL_EN );
443- cfg -> regs -> ctrl0 |= ADI_MAX32_SPI_CTRL_EN ;
444- }
472+ /* Deassert the CS line if hold mode is not enabled */
473+ if (!async && !(ctx -> config -> operation & SPI_HOLD_ON_CS )) {
474+ spi_cs_deassert (dev );
445475 }
446476#else
447477 /* Guard against unsupported word lengths here, as spi_configure is
@@ -573,8 +603,6 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
573603 uint32_t len , word_count ;
574604 uint8_t dfs_shift ;
575605
576- bool hw_cs_ctrl = true;
577-
578606 spi_context_lock (ctx , async , cb , userdata , config );
579607
580608 MXC_SPI_ClearTXFIFO (spi );
@@ -605,18 +633,8 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
605633
606634 spi_context_buffers_setup (ctx , tx_bufs , rx_bufs , 1 );
607635
608- /* Check if CS GPIO exists */
609- if (spi_cs_is_gpio (config )) {
610- hw_cs_ctrl = false;
611- }
612- MXC_SPI_HWSSControl (cfg -> regs , hw_cs_ctrl );
613-
614- /* Assert the CS line if HW control disabled */
615- if (!hw_cs_ctrl ) {
616- spi_context_cs_control (ctx , true);
617- } else {
618- spi -> ctrl0 = (spi -> ctrl0 & ~MXC_F_SPI_CTRL0_START ) | ADI_MAX32_SPI_CTRL0_SS_CTRL ;
619- }
636+ /* Assert the CS line */
637+ spi_cs_assert (dev );
620638
621639 MXC_SPI_SetSlave (cfg -> regs , ctx -> config -> slave );
622640
@@ -665,14 +683,8 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
665683 }
666684
667685unlock :
668- /* Deassert the CS line if hw control disabled */
669- if (!hw_cs_ctrl ) {
670- spi_context_cs_control (ctx , false);
671- } else {
672- spi -> ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL |
673- ADI_MAX32_SPI_CTRL_EN );
674- spi -> ctrl0 |= ADI_MAX32_SPI_CTRL_EN ;
675- }
686+ /* Deassert the CS line */
687+ spi_cs_deassert (dev );
676688
677689 spi_context_release (ctx , ret );
678690
@@ -712,26 +724,12 @@ static inline void spi_max32_iodev_prepare_start(const struct device *dev)
712724 struct spi_rtio * rtio_ctx = data -> rtio_ctx ;
713725 struct spi_dt_spec * spi_dt_spec = rtio_ctx -> txn_curr -> sqe .iodev -> data ;
714726 struct spi_config * spi_config = & spi_dt_spec -> config ;
715- struct max32_spi_config * cfg = (struct max32_spi_config * )dev -> config ;
716727 int ret ;
717- bool hw_cs_ctrl = true;
718728
719729 ret = spi_configure (dev , spi_config );
720730 __ASSERT (!ret , "%d" , ret );
721731
722- /* Check if CS GPIO exists */
723- if (spi_cs_is_gpio (spi_config )) {
724- hw_cs_ctrl = false;
725- }
726- MXC_SPI_HWSSControl (cfg -> regs , hw_cs_ctrl );
727-
728- /* Assert the CS line if HW control disabled */
729- if (!hw_cs_ctrl ) {
730- spi_context_cs_control (& data -> ctx , true);
731- } else {
732- cfg -> regs -> ctrl0 =
733- (cfg -> regs -> ctrl0 & ~MXC_F_SPI_CTRL0_START ) | MXC_F_SPI_CTRL0_SS_CTRL ;
734- };
732+ spi_cs_assert (dev );
735733}
736734
737735static void spi_max32_iodev_complete (const struct device * dev , int status )
@@ -743,16 +741,7 @@ static void spi_max32_iodev_complete(const struct device *dev, int status)
743741 rtio_ctx -> txn_curr = rtio_txn_next (rtio_ctx -> txn_curr );
744742 spi_max32_iodev_start (dev );
745743 } else {
746- struct max32_spi_config * cfg = (struct max32_spi_config * )dev -> config ;
747- bool hw_cs_ctrl = true;
748-
749- if (!hw_cs_ctrl ) {
750- spi_context_cs_control (& data -> ctx , false);
751- } else {
752- cfg -> regs -> ctrl0 &= ~(MXC_F_SPI_CTRL0_START | MXC_F_SPI_CTRL0_SS_CTRL |
753- ADI_MAX32_SPI_CTRL_EN );
754- cfg -> regs -> ctrl0 |= ADI_MAX32_SPI_CTRL_EN ;
755- }
744+ spi_cs_deassert (dev );
756745
757746 if (spi_rtio_complete (rtio_ctx , status )) {
758747 spi_max32_iodev_prepare_start (dev );
@@ -820,13 +809,7 @@ static void spi_max32_callback(mxc_spi_req_t *req, int error)
820809 if (ctx -> asynchronous && ((spi_context_tx_on (ctx ) || spi_context_rx_on (ctx )))) {
821810 k_work_submit (& data -> async_work );
822811 } else {
823- if (spi_cs_is_gpio (ctx -> config )) {
824- spi_context_cs_control (ctx , false);
825- } else {
826- req -> spi -> ctrl0 &= ~(MXC_F_SPI_CTRL0_START | ADI_MAX32_SPI_CTRL0_SS_CTRL |
827- ADI_MAX32_SPI_CTRL_EN );
828- req -> spi -> ctrl0 |= ADI_MAX32_SPI_CTRL_EN ;
829- }
812+ spi_cs_deassert (dev );
830813 spi_context_complete (ctx , dev , error == E_NO_ERROR ? 0 : - EIO );
831814 }
832815#else
@@ -900,12 +883,17 @@ static void spi_max32_isr(const struct device *dev)
900883static int api_release (const struct device * dev , const struct spi_config * config )
901884{
902885 struct max32_spi_data * data = dev -> data ;
886+ struct spi_context * ctx = & data -> ctx ;
903887
904888#ifndef CONFIG_SPI_RTIO
905889 if (!spi_context_configured (& data -> ctx , config )) {
906890 return - EINVAL ;
907891 }
908892#endif
893+
894+ if (ctx -> config -> operation & SPI_HOLD_ON_CS ) {
895+ spi_cs_deassert (dev );
896+ }
909897 spi_context_unlock_unconditionally (& data -> ctx );
910898 return 0 ;
911899}
0 commit comments