@@ -103,7 +103,7 @@ static int spi_configure(const struct device *dev, const struct spi_config *conf
103
103
104
104
ret = Wrap_MXC_SPI_Init (regs , master_mode , quad_mode , num_slaves , ss_polarity , spi_speed );
105
105
if (ret ) {
106
- return ret ;
106
+ return - EINVAL ;
107
107
}
108
108
109
109
int cpol = (SPI_MODE_GET (config -> operation ) & SPI_MODE_CPOL ) ? 1 : 0 ;
@@ -119,12 +119,12 @@ static int spi_configure(const struct device *dev, const struct spi_config *conf
119
119
ret = MXC_SPI_SetMode (regs , SPI_MODE_0 );
120
120
}
121
121
if (ret ) {
122
- return ret ;
122
+ return - EINVAL ;
123
123
}
124
124
125
125
ret = MXC_SPI_SetDataSize (regs , SPI_WORD_SIZE_GET (config -> operation ));
126
126
if (ret ) {
127
- return ret ;
127
+ return - ENOTSUP ;
128
128
}
129
129
130
130
#if defined(CONFIG_SPI_EXTENDED_MODES )
@@ -145,7 +145,7 @@ static int spi_configure(const struct device *dev, const struct spi_config *conf
145
145
}
146
146
147
147
if (ret ) {
148
- return ret ;
148
+ return - EINVAL ;
149
149
}
150
150
#endif
151
151
@@ -163,18 +163,21 @@ static inline int spi_max32_get_dfs_shift(const struct spi_context *ctx)
163
163
return 1 ;
164
164
}
165
165
166
- static void spi_max32_setup (mxc_spi_regs_t * spi , mxc_spi_req_t * req )
166
+ static void spi_max32_setup (mxc_spi_regs_t * spi , mxc_spi_req_t * req , uint8_t dfs_shift )
167
167
{
168
168
req -> rxCnt = 0 ;
169
169
req -> txCnt = 0 ;
170
170
171
+ spi -> ctrl0 &= ~ADI_MAX32_SPI_CTRL_EN ;
172
+
171
173
if (spi -> ctrl0 & ADI_MAX32_SPI_CTRL_MASTER_MODE ) {
172
174
MXC_SPI_SetSlave (spi , req -> ssIdx );
173
175
}
174
176
177
+ /* SPI_CTRL1 holds the number of words so apply dfs_shift first */
175
178
if (req -> rxData && req -> rxLen ) {
176
179
MXC_SETFIELD (spi -> ctrl1 , MXC_F_SPI_CTRL1_RX_NUM_CHAR ,
177
- req -> rxLen << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS );
180
+ ( req -> rxLen >> dfs_shift ) << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS );
178
181
spi -> dma |= MXC_F_SPI_DMA_RX_FIFO_EN ;
179
182
} else {
180
183
spi -> ctrl1 &= ~MXC_F_SPI_CTRL1_RX_NUM_CHAR ;
@@ -183,7 +186,7 @@ static void spi_max32_setup(mxc_spi_regs_t *spi, mxc_spi_req_t *req)
183
186
184
187
if (req -> txLen ) {
185
188
MXC_SETFIELD (spi -> ctrl1 , MXC_F_SPI_CTRL1_TX_NUM_CHAR ,
186
- req -> txLen << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS );
189
+ ( req -> txLen >> dfs_shift ) << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS );
187
190
spi -> dma |= MXC_F_SPI_DMA_TX_FIFO_EN ;
188
191
} else {
189
192
spi -> ctrl1 &= ~MXC_F_SPI_CTRL1_TX_NUM_CHAR ;
@@ -206,8 +209,8 @@ static int spi_max32_transceive_sync(mxc_spi_regs_t *spi, struct max32_spi_data
206
209
MXC_SPI_ClearTXFIFO (spi );
207
210
MXC_SPI_ClearRXFIFO (spi );
208
211
209
- tx_len = req -> txLen << dfs_shift ;
210
- rx_len = req -> rxLen << dfs_shift ;
212
+ tx_len = req -> txLen ;
213
+ rx_len = req -> rxLen ;
211
214
do {
212
215
remain = tx_len - req -> txCnt ;
213
216
if (remain > 0 ) {
@@ -251,8 +254,6 @@ static int spi_max32_transceive(const struct device *dev)
251
254
uint32_t len ;
252
255
uint8_t dfs_shift ;
253
256
254
- MXC_SPI_ClearTXFIFO (cfg -> regs );
255
-
256
257
dfs_shift = spi_max32_get_dfs_shift (ctx );
257
258
258
259
len = spi_context_max_continuous_chunk (ctx );
@@ -291,36 +292,46 @@ static int spi_max32_transceive(const struct device *dev)
291
292
break ;
292
293
}
293
294
#else
294
- data -> req .txLen = len >> dfs_shift ;
295
+ data -> req .txLen = len ;
295
296
data -> req .txData = (uint8_t * )ctx -> tx_buf ;
296
- data -> req .rxLen = len >> dfs_shift ;
297
+ data -> req .rxLen = len ;
297
298
data -> req .rxData = ctx -> rx_buf ;
298
299
299
- data -> req .rxData = ctx -> rx_buf ;
300
-
301
- data -> req .rxLen = len >> dfs_shift ;
302
300
if (!data -> req .rxData ) {
303
301
/* Pass a dummy buffer to HAL if receive buffer is NULL, otherwise
304
302
* corrupt data is read during subsequent transactions.
305
303
*/
306
304
data -> req .rxData = data -> dummy ;
307
305
data -> req .rxLen = 0 ;
306
+
307
+ if (!data -> req .txData && !data -> req .txLen ) {
308
+ /* Both RX and TX are NULL, nothing to do */
309
+ spi_context_update_tx (& data -> ctx , dfs_shift ? 2 : 1 , len );
310
+ spi_context_update_rx (& data -> ctx , dfs_shift ? 2 : 1 , len );
311
+ if (!spi_context_tx_on (ctx ) && !spi_context_rx_on (ctx )) {
312
+ spi_context_complete (ctx , dev , 0 );
313
+ }
314
+
315
+ return 0 ;
316
+ }
308
317
}
309
318
#endif
310
319
data -> req .spi = cfg -> regs ;
311
320
data -> req .ssIdx = ctx -> config -> slave ;
312
321
data -> req .ssDeassert = 0 ;
313
322
data -> req .txCnt = 0 ;
314
323
data -> req .rxCnt = 0 ;
315
- spi_max32_setup (cfg -> regs , & data -> req );
324
+ spi_max32_setup (cfg -> regs , & data -> req , dfs_shift );
316
325
#ifdef CONFIG_SPI_MAX32_INTERRUPT
317
- MXC_SPI_SetTXThreshold (cfg -> regs , 1 );
326
+ MXC_SPI_SetTXThreshold (cfg -> regs , 1 << dfs_shift );
318
327
if (data -> req .rxLen ) {
319
- MXC_SPI_SetRXThreshold (cfg -> regs , 2 );
328
+ MXC_SPI_SetRXThreshold (cfg -> regs , 2 << dfs_shift );
320
329
MXC_SPI_EnableInt (cfg -> regs , ADI_MAX32_SPI_INT_EN_RX_THD );
321
330
}
322
331
MXC_SPI_EnableInt (cfg -> regs , ADI_MAX32_SPI_INT_EN_TX_THD | ADI_MAX32_SPI_INT_EN_MST_DONE );
323
332
333
+ MXC_SPI_ClearTXFIFO (cfg -> regs );
334
+ MXC_SPI_ClearRXFIFO (cfg -> regs );
324
335
if (!data -> req .txData ) {
325
336
data -> req .txCnt =
326
337
MXC_SPI_WriteTXFIFO (cfg -> regs , data -> dummy , MIN (len , sizeof (data -> dummy )));
@@ -334,8 +345,8 @@ static int spi_max32_transceive(const struct device *dev)
334
345
if (ret ) {
335
346
ret = - EIO ;
336
347
} else {
337
- spi_context_update_tx (ctx , 1 , len );
338
- spi_context_update_rx (ctx , 1 , len );
348
+ spi_context_update_tx (ctx , dfs_shift ? 2 : 1 , len );
349
+ spi_context_update_rx (ctx , dfs_shift ? 2 : 1 , len );
339
350
}
340
351
#endif
341
352
@@ -366,7 +377,7 @@ static int transceive(const struct device *dev, const struct spi_config *config,
366
377
ret = spi_configure (dev , config );
367
378
if (ret != 0 ) {
368
379
spi_context_release (ctx , ret );
369
- return - EIO ;
380
+ return ret ;
370
381
}
371
382
372
383
spi_context_buffers_setup (ctx , tx_bufs , rx_bufs , 1 );
@@ -434,9 +445,10 @@ static void spi_max32_dma_callback(const struct device *dev, void *arg, uint32_t
434
445
const struct device * spi_dev = data -> dev ;
435
446
const struct max32_spi_config * config = spi_dev -> config ;
436
447
uint32_t len ;
448
+ uint8_t dfs = spi_max32_get_dfs_shift (& data -> ctx ) ? 2 : 1 ;
437
449
438
450
if (status < 0 ) {
439
- LOG_ERR ("DMA callback error with channel %d. " , channel );
451
+ LOG_ERR ("DMA callback error for channel %u: %d " , channel , status );
440
452
} else {
441
453
/* identify the origin of this callback */
442
454
if (channel == config -> tx_dma .channel ) {
@@ -447,14 +459,14 @@ static void spi_max32_dma_callback(const struct device *dev, void *arg, uint32_t
447
459
}
448
460
if ((data -> dma_stat & SPI_MAX32_DMA_DONE_FLAG ) == SPI_MAX32_DMA_DONE_FLAG ) {
449
461
len = spi_context_max_continuous_chunk (& data -> ctx );
450
- spi_context_update_tx (& data -> ctx , 1 , len );
451
- spi_context_update_rx (& data -> ctx , 1 , len );
462
+ spi_context_update_tx (& data -> ctx , dfs , len );
463
+ spi_context_update_rx (& data -> ctx , dfs , len );
452
464
spi_context_complete (& data -> ctx , spi_dev , status == 0 ? 0 : - EIO );
453
465
}
454
466
}
455
467
456
468
static int spi_max32_tx_dma_load (const struct device * dev , const uint8_t * buf , uint32_t len ,
457
- uint8_t word_shift )
469
+ uint8_t dfs_shift )
458
470
{
459
471
int ret ;
460
472
const struct max32_spi_config * config = dev -> config ;
@@ -467,9 +479,9 @@ static int spi_max32_tx_dma_load(const struct device *dev, const uint8_t *buf, u
467
479
dma_cfg .user_data = (void * )data ;
468
480
dma_cfg .dma_slot = config -> tx_dma .slot ;
469
481
dma_cfg .block_count = 1 ;
470
- dma_cfg .source_data_size = 1U << word_shift ;
471
- dma_cfg .source_burst_length = 1U ;
472
- dma_cfg .dest_data_size = 1U << word_shift ;
482
+ dma_cfg .source_data_size = 1U << dfs_shift ;
483
+ dma_cfg .source_burst_length = 1U << dfs_shift ;
484
+ dma_cfg .dest_data_size = 1U << dfs_shift ;
473
485
dma_cfg .head_block = & dma_blk ;
474
486
dma_blk .block_size = len ;
475
487
if (buf ) {
@@ -489,7 +501,7 @@ static int spi_max32_tx_dma_load(const struct device *dev, const uint8_t *buf, u
489
501
}
490
502
491
503
static int spi_max32_rx_dma_load (const struct device * dev , const uint8_t * buf , uint32_t len ,
492
- uint8_t word_shift )
504
+ uint8_t dfs_shift )
493
505
{
494
506
int ret ;
495
507
const struct max32_spi_config * config = dev -> config ;
@@ -502,9 +514,9 @@ static int spi_max32_rx_dma_load(const struct device *dev, const uint8_t *buf, u
502
514
dma_cfg .user_data = (void * )data ;
503
515
dma_cfg .dma_slot = config -> rx_dma .slot ;
504
516
dma_cfg .block_count = 1 ;
505
- dma_cfg .source_data_size = 1U << word_shift ;
506
- dma_cfg .source_burst_length = 1U ;
507
- dma_cfg .dest_data_size = 1U << word_shift ;
517
+ dma_cfg .source_data_size = 1U << dfs_shift ;
518
+ dma_cfg .source_burst_length = 1U << dfs_shift ;
519
+ dma_cfg .dest_data_size = 1U << dfs_shift ;
508
520
dma_cfg .head_block = & dma_blk ;
509
521
dma_blk .block_size = len ;
510
522
if (buf ) {
@@ -540,6 +552,7 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
540
552
spi_context_lock (ctx , async , cb , userdata , config );
541
553
542
554
MXC_SPI_ClearTXFIFO (spi );
555
+ MXC_SPI_ClearRXFIFO (spi );
543
556
544
557
ret = dma_get_status (cfg -> tx_dma .dev , cfg -> tx_dma .channel , & status );
545
558
if (ret < 0 || status .busy ) {
@@ -553,9 +566,14 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
553
566
goto unlock ;
554
567
}
555
568
569
+ /* Word sizes less than 8-bits are not supported in DMA mode */
570
+ if (SPI_WORD_SIZE_GET (config -> operation ) < 8 ) {
571
+ ret = - ENOTSUP ;
572
+ goto unlock ;
573
+ }
574
+
556
575
ret = spi_configure (dev , config );
557
576
if (ret != 0 ) {
558
- ret = - EIO ;
559
577
goto unlock ;
560
578
}
561
579
@@ -581,12 +599,17 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
581
599
dfs_shift = spi_max32_get_dfs_shift (ctx );
582
600
word_count = len >> dfs_shift ;
583
601
602
+ if (word_count == 0 ) {
603
+ /* Nothing to do, continue */
604
+ continue ;
605
+ }
606
+
584
607
MXC_SETFIELD (spi -> ctrl1 , MXC_F_SPI_CTRL1_RX_NUM_CHAR ,
585
608
word_count << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS );
586
609
spi -> dma |= ADI_MAX32_SPI_DMA_RX_FIFO_CLEAR ;
587
610
spi -> dma |= MXC_F_SPI_DMA_RX_FIFO_EN ;
588
611
spi -> dma |= ADI_MAX32_SPI_DMA_RX_DMA_EN ;
589
- MXC_SPI_SetRXThreshold (spi , 0 );
612
+ MXC_SPI_SetRXThreshold (spi , dfs_shift ? 1 : 0 );
590
613
591
614
ret = spi_max32_rx_dma_load (dev , ctx -> rx_buf , len , dfs_shift );
592
615
if (ret < 0 ) {
@@ -598,7 +621,7 @@ static int transceive_dma(const struct device *dev, const struct spi_config *con
598
621
spi -> dma |= ADI_MAX32_SPI_DMA_TX_FIFO_CLEAR ;
599
622
spi -> dma |= MXC_F_SPI_DMA_TX_FIFO_EN ;
600
623
spi -> dma |= ADI_MAX32_SPI_DMA_TX_DMA_EN ;
601
- MXC_SPI_SetTXThreshold (spi , 1 );
624
+ MXC_SPI_SetTXThreshold (spi , 2 );
602
625
603
626
ret = spi_max32_tx_dma_load (dev , ctx -> tx_buf , len , dfs_shift );
604
627
if (ret < 0 ) {
@@ -754,6 +777,7 @@ static void spi_max32_callback(mxc_spi_req_t *req, int error)
754
777
struct spi_context * ctx = & data -> ctx ;
755
778
const struct device * dev = data -> dev ;
756
779
uint32_t len ;
780
+ uint8_t dfs ;
757
781
758
782
#ifdef CONFIG_SPI_RTIO
759
783
struct spi_rtio * rtio_ctx = data -> rtio_ctx ;
@@ -762,9 +786,10 @@ static void spi_max32_callback(mxc_spi_req_t *req, int error)
762
786
spi_max32_iodev_complete (data -> dev , 0 );
763
787
}
764
788
#endif
789
+ dfs = spi_max32_get_dfs_shift (ctx ) ? 2 : 1 ;
765
790
len = spi_context_max_continuous_chunk (ctx );
766
- spi_context_update_tx (ctx , 1 , len );
767
- spi_context_update_rx (ctx , 1 , len );
791
+ spi_context_update_tx (ctx , dfs , len );
792
+ spi_context_update_rx (ctx , dfs , len );
768
793
#ifdef CONFIG_SPI_ASYNC
769
794
if (ctx -> asynchronous && ((spi_context_tx_on (ctx ) || spi_context_rx_on (ctx )))) {
770
795
k_work_submit (& data -> async_work );
@@ -804,12 +829,11 @@ static void spi_max32_isr(const struct device *dev)
804
829
mxc_spi_req_t * req = & data -> req ;
805
830
mxc_spi_regs_t * spi = cfg -> regs ;
806
831
uint32_t flags , remain ;
807
- uint8_t dfs_shift = spi_max32_get_dfs_shift (& data -> ctx );
808
832
809
833
flags = MXC_SPI_GetFlags (spi );
810
834
MXC_SPI_ClearFlags (spi );
811
835
812
- remain = ( req -> txLen << dfs_shift ) - req -> txCnt ;
836
+ remain = req -> txLen - req -> txCnt ;
813
837
if (flags & ADI_MAX32_SPI_INT_FL_TX_THD ) {
814
838
if (remain ) {
815
839
if (!data -> req .txData ) {
@@ -824,10 +848,10 @@ static void spi_max32_isr(const struct device *dev)
824
848
}
825
849
}
826
850
827
- remain = ( req -> rxLen << dfs_shift ) - req -> rxCnt ;
851
+ remain = req -> rxLen - req -> rxCnt ;
828
852
if (remain ) {
829
853
req -> rxCnt += MXC_SPI_ReadRXFIFO (spi , & req -> rxData [req -> rxCnt ], remain );
830
- remain = ( req -> rxLen << dfs_shift ) - req -> rxCnt ;
854
+ remain = req -> rxLen - req -> rxCnt ;
831
855
if (remain >= MXC_SPI_FIFO_DEPTH ) {
832
856
MXC_SPI_SetRXThreshold (spi , 2 );
833
857
} else {
0 commit comments