@@ -327,6 +327,79 @@ STATIC HAL_StatusTypeDef spi_wait_dma_finished(SPI_HandleTypeDef *spi, uint32_t
327
327
return HAL_OK ;
328
328
}
329
329
330
+ STATIC void spi_transfer (mp_obj_base_t * self_in , size_t src_len , const uint8_t * src_buf , size_t dest_len , uint8_t * dest_buf , uint32_t timeout ) {
331
+ // Note: there seems to be a problem sending 1 byte using DMA the first
332
+ // time directly after the SPI/DMA is initialised. The cause of this is
333
+ // unknown but we sidestep the issue by using polling for 1 byte transfer.
334
+
335
+ pyb_spi_obj_t * self = (pyb_spi_obj_t * )self_in ;
336
+ HAL_StatusTypeDef status ;
337
+
338
+ if (dest_len == 0 ) {
339
+ // send only
340
+ if (src_len == 1 || query_irq () == IRQ_STATE_DISABLED ) {
341
+ status = HAL_SPI_Transmit (self -> spi , (uint8_t * )src_buf , src_len , timeout );
342
+ } else {
343
+ DMA_HandleTypeDef tx_dma ;
344
+ dma_init (& tx_dma , self -> tx_dma_descr , self -> spi );
345
+ self -> spi -> hdmatx = & tx_dma ;
346
+ self -> spi -> hdmarx = NULL ;
347
+ status = HAL_SPI_Transmit_DMA (self -> spi , (uint8_t * )src_buf , src_len );
348
+ if (status == HAL_OK ) {
349
+ status = spi_wait_dma_finished (self -> spi , timeout );
350
+ }
351
+ dma_deinit (self -> tx_dma_descr );
352
+ }
353
+ } else if (src_len == 0 ) {
354
+ // receive only
355
+ if (dest_len == 1 || query_irq () == IRQ_STATE_DISABLED ) {
356
+ status = HAL_SPI_Receive (self -> spi , dest_buf , dest_len , timeout );
357
+ } else {
358
+ DMA_HandleTypeDef tx_dma , rx_dma ;
359
+ if (self -> spi -> Init .Mode == SPI_MODE_MASTER ) {
360
+ // in master mode the HAL actually does a TransmitReceive call
361
+ dma_init (& tx_dma , self -> tx_dma_descr , self -> spi );
362
+ self -> spi -> hdmatx = & tx_dma ;
363
+ } else {
364
+ self -> spi -> hdmatx = NULL ;
365
+ }
366
+ dma_init (& rx_dma , self -> rx_dma_descr , self -> spi );
367
+ self -> spi -> hdmarx = & rx_dma ;
368
+
369
+ status = HAL_SPI_Receive_DMA (self -> spi , dest_buf , dest_len );
370
+ if (status == HAL_OK ) {
371
+ status = spi_wait_dma_finished (self -> spi , timeout );
372
+ }
373
+ if (self -> spi -> hdmatx != NULL ) {
374
+ dma_deinit (self -> tx_dma_descr );
375
+ }
376
+ dma_deinit (self -> rx_dma_descr );
377
+ }
378
+ } else {
379
+ // send and receive
380
+ // requires src_len==dest_len
381
+ if (src_len == 1 || query_irq () == IRQ_STATE_DISABLED ) {
382
+ status = HAL_SPI_TransmitReceive (self -> spi , (uint8_t * )src_buf , dest_buf , src_len , timeout );
383
+ } else {
384
+ DMA_HandleTypeDef tx_dma , rx_dma ;
385
+ dma_init (& tx_dma , self -> tx_dma_descr , self -> spi );
386
+ self -> spi -> hdmatx = & tx_dma ;
387
+ dma_init (& rx_dma , self -> rx_dma_descr , self -> spi );
388
+ self -> spi -> hdmarx = & rx_dma ;
389
+ status = HAL_SPI_TransmitReceive_DMA (self -> spi , (uint8_t * )src_buf , dest_buf , src_len );
390
+ if (status == HAL_OK ) {
391
+ status = spi_wait_dma_finished (self -> spi , timeout );
392
+ }
393
+ dma_deinit (self -> tx_dma_descr );
394
+ dma_deinit (self -> rx_dma_descr );
395
+ }
396
+ }
397
+
398
+ if (status != HAL_OK ) {
399
+ mp_hal_raise (status );
400
+ }
401
+ }
402
+
330
403
/******************************************************************************/
331
404
/* Micro Python bindings */
332
405
@@ -556,27 +629,7 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
556
629
pyb_buf_get_for_send (args [0 ].u_obj , & bufinfo , data );
557
630
558
631
// send the data
559
- // Note: there seems to be a problem sending 1 byte using DMA the first
560
- // time directly after the SPI/DMA is initialised. The cause of this is
561
- // unknown but we sidestep the issue by using polling for 1 byte transfer.
562
- HAL_StatusTypeDef status ;
563
- if (bufinfo .len == 1 || query_irq () == IRQ_STATE_DISABLED ) {
564
- status = HAL_SPI_Transmit (self -> spi , bufinfo .buf , bufinfo .len , args [1 ].u_int );
565
- } else {
566
- DMA_HandleTypeDef tx_dma ;
567
- dma_init (& tx_dma , self -> tx_dma_descr , self -> spi );
568
- self -> spi -> hdmatx = & tx_dma ;
569
- self -> spi -> hdmarx = NULL ;
570
- status = HAL_SPI_Transmit_DMA (self -> spi , bufinfo .buf , bufinfo .len );
571
- if (status == HAL_OK ) {
572
- status = spi_wait_dma_finished (self -> spi , args [1 ].u_int );
573
- }
574
- dma_deinit (self -> tx_dma_descr );
575
- }
576
-
577
- if (status != HAL_OK ) {
578
- mp_hal_raise (status );
579
- }
632
+ spi_transfer ((mp_obj_base_t * )self , bufinfo .len , bufinfo .buf , 0 , NULL , args [1 ].u_int );
580
633
581
634
return mp_const_none ;
582
635
}
@@ -610,34 +663,7 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
610
663
mp_obj_t o_ret = pyb_buf_get_for_recv (args [0 ].u_obj , & vstr );
611
664
612
665
// receive the data
613
- HAL_StatusTypeDef status ;
614
- if (vstr .len == 1 || query_irq () == IRQ_STATE_DISABLED ) {
615
- status = HAL_SPI_Receive (self -> spi , (uint8_t * )vstr .buf , vstr .len , args [1 ].u_int );
616
- } else {
617
- DMA_HandleTypeDef tx_dma , rx_dma ;
618
- if (self -> spi -> Init .Mode == SPI_MODE_MASTER ) {
619
- // in master mode the HAL actually does a TransmitReceive call
620
- dma_init (& tx_dma , self -> tx_dma_descr , self -> spi );
621
- self -> spi -> hdmatx = & tx_dma ;
622
- } else {
623
- self -> spi -> hdmatx = NULL ;
624
- }
625
- dma_init (& rx_dma , self -> rx_dma_descr , self -> spi );
626
- self -> spi -> hdmarx = & rx_dma ;
627
-
628
- status = HAL_SPI_Receive_DMA (self -> spi , (uint8_t * )vstr .buf , vstr .len );
629
- if (status == HAL_OK ) {
630
- status = spi_wait_dma_finished (self -> spi , args [1 ].u_int );
631
- }
632
- if (self -> spi -> hdmatx != NULL ) {
633
- dma_deinit (self -> tx_dma_descr );
634
- }
635
- dma_deinit (self -> rx_dma_descr );
636
- }
637
-
638
- if (status != HAL_OK ) {
639
- mp_hal_raise (status );
640
- }
666
+ spi_transfer ((mp_obj_base_t * )self , 0 , NULL , vstr .len , (uint8_t * )vstr .buf , args [1 ].u_int );
641
667
642
668
// return the received data
643
669
if (o_ret != MP_OBJ_NULL ) {
@@ -706,27 +732,8 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp
706
732
}
707
733
}
708
734
709
- // send and receive the data
710
- HAL_StatusTypeDef status ;
711
- if (bufinfo_send .len == 1 || query_irq () == IRQ_STATE_DISABLED ) {
712
- status = HAL_SPI_TransmitReceive (self -> spi , bufinfo_send .buf , bufinfo_recv .buf , bufinfo_send .len , args [2 ].u_int );
713
- } else {
714
- DMA_HandleTypeDef tx_dma , rx_dma ;
715
- dma_init (& tx_dma , self -> tx_dma_descr , self -> spi );
716
- self -> spi -> hdmatx = & tx_dma ;
717
- dma_init (& rx_dma , self -> rx_dma_descr , self -> spi );
718
- self -> spi -> hdmarx = & rx_dma ;
719
- status = HAL_SPI_TransmitReceive_DMA (self -> spi , bufinfo_send .buf , bufinfo_recv .buf , bufinfo_send .len );
720
- if (status == HAL_OK ) {
721
- status = spi_wait_dma_finished (self -> spi , args [2 ].u_int );
722
- }
723
- dma_deinit (self -> tx_dma_descr );
724
- dma_deinit (self -> rx_dma_descr );
725
- }
726
-
727
- if (status != HAL_OK ) {
728
- mp_hal_raise (status );
729
- }
735
+ // do the transfer
736
+ spi_transfer ((mp_obj_base_t * )self , bufinfo_send .len , bufinfo_send .buf , bufinfo_recv .len , bufinfo_recv .buf , args [2 ].u_int );
730
737
731
738
// return the received data
732
739
if (o_ret != MP_OBJ_NULL ) {
0 commit comments