@@ -109,6 +109,7 @@ typedef struct _pyb_i2c_obj_t {
109109 I2C_HandleTypeDef * i2c ;
110110 const dma_descr_t * tx_dma_descr ;
111111 const dma_descr_t * rx_dma_descr ;
112+ bool * use_dma ;
112113} pyb_i2c_obj_t ;
113114
114115#if defined(MICROPY_HW_I2C1_SCL )
@@ -121,21 +122,23 @@ I2C_HandleTypeDef I2CHandle2 = {.Instance = NULL};
121122I2C_HandleTypeDef I2CHandle3 = {.Instance = NULL };
122123#endif
123124
125+ STATIC bool pyb_i2c_use_dma [3 ];
126+
124127STATIC const pyb_i2c_obj_t pyb_i2c_obj [] = {
125128 #if defined(MICROPY_HW_I2C1_SCL )
126- {{& pyb_i2c_type }, & I2CHandle1 , & dma_I2C_1_TX , & dma_I2C_1_RX },
129+ {{& pyb_i2c_type }, & I2CHandle1 , & dma_I2C_1_TX , & dma_I2C_1_RX , & pyb_i2c_use_dma [ 0 ] },
127130 #else
128- {{& pyb_i2c_type }, NULL , NULL , NULL },
131+ {{& pyb_i2c_type }, NULL , NULL , NULL , NULL },
129132 #endif
130133 #if defined(MICROPY_HW_I2C2_SCL )
131- {{& pyb_i2c_type }, & I2CHandle2 , & dma_I2C_2_TX , & dma_I2C_2_RX },
134+ {{& pyb_i2c_type }, & I2CHandle2 , & dma_I2C_2_TX , & dma_I2C_2_RX , & pyb_i2c_use_dma [ 1 ] },
132135 #else
133- {{& pyb_i2c_type }, NULL , NULL , NULL },
136+ {{& pyb_i2c_type }, NULL , NULL , NULL , NULL },
134137 #endif
135138 #if defined(MICROPY_HW_I2C3_SCL )
136- {{& pyb_i2c_type }, & I2CHandle3 , & dma_I2C_3_TX , & dma_I2C_3_RX },
139+ {{& pyb_i2c_type }, & I2CHandle3 , & dma_I2C_3_TX , & dma_I2C_3_RX , & pyb_i2c_use_dma [ 2 ] },
137140 #else
138- {{& pyb_i2c_type }, NULL , NULL , NULL },
141+ {{& pyb_i2c_type }, NULL , NULL , NULL , NULL },
139142 #endif
140143};
141144
@@ -338,6 +341,7 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, mp_uint_t n_args,
338341 { MP_QSTR_addr , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 0x12 } },
339342 { MP_QSTR_baudrate , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = MICROPY_HW_I2C_BAUDRATE_DEFAULT } },
340343 { MP_QSTR_gencall , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
344+ { MP_QSTR_dma , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = false} },
341345 };
342346
343347 // parse args
@@ -362,6 +366,8 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, mp_uint_t n_args,
362366 init -> OwnAddress2 = 0 ; // unused
363367 init -> NoStretchMode = I2C_NOSTRETCH_DISABLE ;
364368
369+ * self -> use_dma = args [4 ].u_bool ;
370+
365371 // init the I2C bus
366372 i2c_init (self -> i2c );
367373
@@ -514,9 +520,11 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
514520 uint8_t data [1 ];
515521 pyb_buf_get_for_send (args [0 ].u_obj , & bufinfo , data );
516522
517- // if IRQs are enabled then we can use DMA
523+ // if option is set and IRQs are enabled then we can use DMA
524+ bool use_dma = * self -> use_dma && query_irq () == IRQ_STATE_ENABLED ;
525+
518526 DMA_HandleTypeDef tx_dma ;
519- if (query_irq () == IRQ_STATE_ENABLED ) {
527+ if (use_dma ) {
520528 dma_init (& tx_dma , self -> tx_dma_descr , self -> i2c );
521529 self -> i2c -> hdmatx = & tx_dma ;
522530 self -> i2c -> hdmarx = NULL ;
@@ -526,27 +534,27 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
526534 HAL_StatusTypeDef status ;
527535 if (in_master_mode (self )) {
528536 if (args [1 ].u_int == PYB_I2C_MASTER_ADDRESS ) {
529- if (query_irq () == IRQ_STATE_ENABLED ) {
537+ if (use_dma ) {
530538 dma_deinit (self -> tx_dma_descr );
531539 }
532540 nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "addr argument required" ));
533541 }
534542 mp_uint_t i2c_addr = args [1 ].u_int << 1 ;
535- if (query_irq () == IRQ_STATE_DISABLED ) {
543+ if (! use_dma ) {
536544 status = HAL_I2C_Master_Transmit (self -> i2c , i2c_addr , bufinfo .buf , bufinfo .len , args [2 ].u_int );
537545 } else {
538546 status = HAL_I2C_Master_Transmit_DMA (self -> i2c , i2c_addr , bufinfo .buf , bufinfo .len );
539547 }
540548 } else {
541- if (query_irq () == IRQ_STATE_DISABLED ) {
549+ if (! use_dma ) {
542550 status = HAL_I2C_Slave_Transmit (self -> i2c , bufinfo .buf , bufinfo .len , args [2 ].u_int );
543551 } else {
544552 status = HAL_I2C_Slave_Transmit_DMA (self -> i2c , bufinfo .buf , bufinfo .len );
545553 }
546554 }
547555
548556 // if we used DMA, wait for it to finish
549- if (query_irq () == IRQ_STATE_ENABLED ) {
557+ if (use_dma ) {
550558 if (status == HAL_OK ) {
551559 status = i2c_wait_dma_finished (self -> i2c , args [2 ].u_int );
552560 }
@@ -588,9 +596,11 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
588596 vstr_t vstr ;
589597 mp_obj_t o_ret = pyb_buf_get_for_recv (args [0 ].u_obj , & vstr );
590598
591- // if IRQs are enabled then we can use DMA
599+ // if option is set and IRQs are enabled then we can use DMA
600+ bool use_dma = * self -> use_dma && query_irq () == IRQ_STATE_ENABLED ;
601+
592602 DMA_HandleTypeDef rx_dma ;
593- if (query_irq () == IRQ_STATE_ENABLED ) {
603+ if (use_dma ) {
594604 dma_init (& rx_dma , self -> rx_dma_descr , self -> i2c );
595605 self -> i2c -> hdmatx = NULL ;
596606 self -> i2c -> hdmarx = & rx_dma ;
@@ -603,21 +613,21 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
603613 nlr_raise (mp_obj_new_exception_msg (& mp_type_TypeError , "addr argument required" ));
604614 }
605615 mp_uint_t i2c_addr = args [1 ].u_int << 1 ;
606- if (query_irq () == IRQ_STATE_DISABLED ) {
616+ if (! use_dma ) {
607617 status = HAL_I2C_Master_Receive (self -> i2c , i2c_addr , (uint8_t * )vstr .buf , vstr .len , args [2 ].u_int );
608618 } else {
609619 status = HAL_I2C_Master_Receive_DMA (self -> i2c , i2c_addr , (uint8_t * )vstr .buf , vstr .len );
610620 }
611621 } else {
612- if (query_irq () == IRQ_STATE_DISABLED ) {
622+ if (! use_dma ) {
613623 status = HAL_I2C_Slave_Receive (self -> i2c , (uint8_t * )vstr .buf , vstr .len , args [2 ].u_int );
614624 } else {
615625 status = HAL_I2C_Slave_Receive_DMA (self -> i2c , (uint8_t * )vstr .buf , vstr .len );
616626 }
617627 }
618628
619629 // if we used DMA, wait for it to finish
620- if (query_irq () == IRQ_STATE_ENABLED ) {
630+ if (use_dma ) {
621631 if (status == HAL_OK ) {
622632 status = i2c_wait_dma_finished (self -> i2c , args [2 ].u_int );
623633 }
@@ -680,8 +690,11 @@ STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
680690 mem_addr_size = I2C_MEMADD_SIZE_16BIT ;
681691 }
682692
693+ // if option is set and IRQs are enabled then we can use DMA
694+ bool use_dma = * self -> use_dma && query_irq () == IRQ_STATE_ENABLED ;
695+
683696 HAL_StatusTypeDef status ;
684- if (query_irq () == IRQ_STATE_DISABLED ) {
697+ if (! use_dma ) {
685698 status = HAL_I2C_Mem_Read (self -> i2c , i2c_addr , mem_addr , mem_addr_size , (uint8_t * )vstr .buf , vstr .len , args [3 ].u_int );
686699 } else {
687700 DMA_HandleTypeDef rx_dma ;
@@ -744,8 +757,11 @@ STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp
744757 mem_addr_size = I2C_MEMADD_SIZE_16BIT ;
745758 }
746759
760+ // if option is set and IRQs are enabled then we can use DMA
761+ bool use_dma = * self -> use_dma && query_irq () == IRQ_STATE_ENABLED ;
762+
747763 HAL_StatusTypeDef status ;
748- if (query_irq () == IRQ_STATE_DISABLED ) {
764+ if (! use_dma ) {
749765 status = HAL_I2C_Mem_Write (self -> i2c , i2c_addr , mem_addr , mem_addr_size , bufinfo .buf , bufinfo .len , args [3 ].u_int );
750766 } else {
751767 DMA_HandleTypeDef tx_dma ;
0 commit comments