@@ -237,6 +237,15 @@ static mp_uint_t gcd(mp_uint_t x, mp_uint_t y)
237237    return  x ;
238238}
239239
240+ static  void  disable_gpio (int  gpio_num ) {
241+     if  (gpio_num  !=  -1 ) {
242+         esp_rom_gpio_pad_select_gpio (gpio_num );
243+         esp_rom_gpio_connect_out_signal (gpio_num , SIG_GPIO_OUT_IDX , false, false);
244+         gpio_set_direction (gpio_num , GPIO_MODE_INPUT );
245+         gpio_reset_pin (gpio_num );
246+     }
247+ }
248+ 
240249
241250static  void  machine_hw_spi_bus_deinit_internal (machine_hw_spi_bus_obj_t  * self )
242251{
@@ -260,37 +269,15 @@ static void machine_hw_spi_bus_deinit_internal(machine_hw_spi_bus_obj_t *self)
260269            return ;
261270    }
262271
263-     int  miso  =  (int )mp_obj_get_int (self -> miso );
264-     int  mosi  =  (int )mp_obj_get_int (self -> mosi );
265-     int  sck  =  (int )mp_obj_get_int (self -> sck );
266-     int  data2  =  (int )mp_obj_get_int (self -> data2 );
267-     int  data3  =  (int )mp_obj_get_int (self -> data3 );
268- 
269-     if  (miso  !=  -1 ) {
270-         esp_rom_gpio_pad_select_gpio (miso );
271-         esp_rom_gpio_connect_out_signal (miso , SIG_GPIO_OUT_IDX , false, false);
272-         gpio_set_direction (miso , GPIO_MODE_INPUT );
273-     }
274-     if  (mosi  !=  -1 ) {
275-         esp_rom_gpio_pad_select_gpio (mosi );
276-         esp_rom_gpio_connect_out_signal (mosi , SIG_GPIO_OUT_IDX , false, false);
277-         gpio_set_direction (mosi , GPIO_MODE_INPUT );
278-     }
279-     if  (sck  !=  -1 ) {
280-         esp_rom_gpio_pad_select_gpio (sck );
281-         esp_rom_gpio_connect_out_signal (sck , SIG_GPIO_OUT_IDX , false, false);
282-         gpio_set_direction (sck , GPIO_MODE_INPUT );
283-     }
284-     if  (data2  !=  -1 ) {
285-         esp_rom_gpio_pad_select_gpio (data2 );
286-         esp_rom_gpio_connect_out_signal (data2 , SIG_GPIO_OUT_IDX , false, false);
287-         gpio_set_direction (data2 , GPIO_MODE_INPUT );
288-     }
289-     if  (data3  !=  -1 ) {
290-         esp_rom_gpio_pad_select_gpio (data3 );
291-         esp_rom_gpio_connect_out_signal (data3 , SIG_GPIO_OUT_IDX , false, false);
292-         gpio_set_direction (data3 , GPIO_MODE_INPUT );
293-     }
272+     disable_gpio ((int )mp_obj_get_int (self -> miso ));
273+     disable_gpio ((int )mp_obj_get_int (self -> mosi ));
274+     disable_gpio ((int )mp_obj_get_int (self -> sck ));
275+     disable_gpio ((int )mp_obj_get_int (self -> data2 ));
276+     disable_gpio ((int )mp_obj_get_int (self -> data3 ));
277+     disable_gpio ((int )mp_obj_get_int (self -> data4 ));
278+     disable_gpio ((int )mp_obj_get_int (self -> data5 ));
279+     disable_gpio ((int )mp_obj_get_int (self -> data6 ));
280+     disable_gpio ((int )mp_obj_get_int (self -> data7 ));
294281
295282    self -> state  =  MP_SPI_STATE_STOPPED ;
296283}
@@ -339,9 +326,15 @@ static void machine_hw_spi_device_transfer(mp_obj_base_t *self_in, size_t len, c
339326
340327        transaction .flags  =  SPI_TRANS_USE_TXDATA  | SPI_TRANS_USE_RXDATA ;
341328        transaction .length  =  bits_to_send ;
342-         if  (self -> spi_bus -> quad ) {
329+ 
330+         if  (self -> dual ) {
331+             transaction .flags  |= SPI_TRANS_MODE_DIO ;
332+         } else  if  (self -> quad ) {
343333            transaction .flags  |= SPI_TRANS_MODE_QIO ;
334+         } else  if  (self -> octal ) {
335+             transaction .flags  |= SPI_TRANS_MODE_OCT ;
344336        }
337+ 
345338        spi_device_transmit (spi_device , & transaction );
346339
347340        if  (dest  !=  NULL ) {
@@ -376,8 +369,12 @@ static void machine_hw_spi_device_transfer(mp_obj_base_t *self_in, size_t len, c
376369                transaction -> flags  |= SPI_TRANS_USE_RXDATA ;
377370            }
378371
379-             if  (self -> spi_bus -> quad ) {
372+             if  (self -> dual ) {
373+                 transaction .flags  |= SPI_TRANS_MODE_DIO ;
374+             } else  if  (self -> quad ) {
380375                transaction .flags  |= SPI_TRANS_MODE_QIO ;
376+             } else  if  (self -> octal ) {
377+                 transaction .flags  |= SPI_TRANS_MODE_OCT ;
381378            }
382379
383380            spi_device_queue_trans (spi_device , transaction , portMAX_DELAY );
@@ -408,14 +405,14 @@ static void machine_hw_spi_device_transfer(mp_obj_base_t *self_in, size_t len, c
408405
409406mp_obj_t  machine_hw_spi_bus_make_new (const  mp_obj_type_t  * type , size_t  n_args , size_t  n_kw , const  mp_obj_t  * all_args ) {
410407
411-     enum  { ARG_host , ARG_mosi , ARG_miso , ARG_sck , ARG_data2 ,  ARG_data3  };
408+     enum  { ARG_host , ARG_mosi , ARG_miso , ARG_sck , ARG_quad_pins ,  ARG_octal_pins  };
412409    static  const  mp_arg_t  allowed_args [] =  {
413-         { MP_QSTR_host ,     MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
414-         { MP_QSTR_mosi ,     MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
415-         { MP_QSTR_miso ,     MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
416-         { MP_QSTR_sck ,      MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
417-         { MP_QSTR_data2 ,     MP_ARG_KW_ONLY  | MP_ARG_INT ,  { .u_int  =  -1  } },
418-         { MP_QSTR_data3 ,     MP_ARG_KW_ONLY  | MP_ARG_INT ,  { .u_int  =  -1  } },
410+         { MP_QSTR_host ,        MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
411+         { MP_QSTR_mosi ,        MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
412+         { MP_QSTR_miso ,        MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
413+         { MP_QSTR_sck ,         MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
414+         { MP_QSTR_quad_pins ,  MP_ARG_KW_ONLY  | MP_ARG_OBJ ,  { .u_obj  =  mp_const_none  } },
415+         { MP_QSTR_octal_pins ,  MP_ARG_KW_ONLY  | MP_ARG_OBJ ,  { .u_obj  =  mp_const_none  } },
419416    };
420417
421418    mp_arg_val_t  args [MP_ARRAY_SIZE (allowed_args )];
@@ -425,11 +422,77 @@ mp_obj_t machine_hw_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args, s
425422    int  mosi  =  (int )args [ARG_mosi ].u_int ;
426423    int  miso  =  (int )args [ARG_miso ].u_int ;
427424    int  sck  =  (int )args [ARG_sck ].u_int ;
428-     int  data2  =  (int )args [ARG_data2 ].u_int ;
429-     int  data3  =  (int )args [ARG_data3 ].u_int ;
425+     int  data2  =  -1 ;
426+     int  data3  =  -1 ;
427+     int  data4  =  -1 ;
428+     int  data5  =  -1 ;
429+     int  data6  =  -1 ;
430+     int  data7  =  -1 ;
431+ 
432+     bool  dual  =  false;
433+     bool  quad  =  false;
434+     bool  octal  =  false;
430435
431436    machine_hw_spi_bus_obj_t  * self ;
432437
438+     if  (mosi  !=  -1  &&  mosi  !=  -1 ) dual  =  true;
439+ 
440+     if  (args [ARG_quad_pins ].u_obj  !=  mp_const_none ) {
441+         p_obj_tuple_t  * quad_data_pins  =  MP_OBJ_TO_PTR (args [ARG_quad_pins ].u_obj );
442+ 
443+         if  (!dual ) {
444+             mp_raise_msg (
445+                 & mp_type_ValueError ,
446+                 MP_ERROR_TEXT ("You MUST supply both the MISO and MOSI pins to use quad mode" ),
447+             );
448+             return  mp_const_none ;
449+         }
450+         if  (quad_data_pins -> len  !=  2 ) {
451+             mp_raise_msg_varg (
452+                 & mp_type_ValueError ,
453+                 MP_ERROR_TEXT ("2 additional pins are mneeded for quad SPI not %d" ),
454+                 quad_data_pins -> len 
455+             );
456+             return  mp_const_none ;
457+         }
458+ 
459+         data2  =  (int )mp_obj_get_int (quad_data_pins -> items [0 ])
460+         data3  =  (int )mp_obj_get_int (quad_data_pins -> items [1 ])
461+ 
462+         quad  =  true;
463+         octal  =  false;
464+ 
465+     } else  if  (args [ARG_data_pins ].u_obj  !=  mp_const_none ) {
466+         p_obj_tuple_t  * octal_data_pins  =  MP_OBJ_TO_PTR (args [ARG_octal_pins ].u_obj );
467+ 
468+         if  (!dual ) {
469+             mp_raise_msg (
470+                 & mp_type_ValueError ,
471+                 MP_ERROR_TEXT ("You MUST supply both the MISO and MOSI pins to use octal mode" ),
472+             );
473+             return  mp_const_none ;
474+         }
475+ 
476+         if  (octal_data_pins -> len  !=  6 ) {
477+             mp_raise_msg_varg (
478+                 & mp_type_ValueError ,
479+                 MP_ERROR_TEXT ("6 additional pins are needed for octal SPI not %d" ),
480+                 octal_data_pins -> len 
481+             );
482+             return  mp_const_none ;
483+         }
484+ 
485+         data2  =  (int )mp_obj_get_int (octal_data_pins -> items [0 ])
486+         data3  =  (int )mp_obj_get_int (octal_data_pins -> items [1 ])
487+         data4  =  (int )mp_obj_get_int (octal_data_pins -> items [2 ])
488+         data5  =  (int )mp_obj_get_int (octal_data_pins -> items [3 ])
489+         data6  =  (int )mp_obj_get_int (octal_data_pins -> items [4 ])
490+         data7  =  (int )mp_obj_get_int (octal_data_pins -> items [5 ])
491+ 
492+         quad  =  true;
493+         octal  =  true;
494+     }
495+ 
433496    if  (1  <= host  &&  host  <= MICROPY_HW_SPI_MAX ) {
434497        self  =  machine_hw_spi_bus_objs [host  -  1 ];
435498    } else  {
@@ -452,6 +515,10 @@ mp_obj_t machine_hw_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args, s
452515        if  ((int )mp_obj_get_int (self -> sck ) !=  sck ) reconfigure  =  true;
453516        if  ((int )mp_obj_get_int (self -> data2 ) !=  data2 ) reconfigure  =  true;
454517        if  ((int )mp_obj_get_int (self -> data3 ) !=  data3 ) reconfigure  =  true;
518+         if  ((int )mp_obj_get_int (self -> data4 ) !=  data4 ) reconfigure  =  true;
519+         if  ((int )mp_obj_get_int (self -> data5 ) !=  data5 ) reconfigure  =  true;
520+         if  ((int )mp_obj_get_int (self -> data6 ) !=  data6 ) reconfigure  =  true;
521+         if  ((int )mp_obj_get_int (self -> data7 ) !=  data7 ) reconfigure  =  true;
455522    }
456523
457524    if  (reconfigure ) {
@@ -465,12 +532,13 @@ mp_obj_t machine_hw_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args, s
465532        self -> sck  =  mp_obj_new_int ((mp_int_t )sck );
466533        self -> data2  =  mp_obj_new_int ((mp_int_t )data2 );
467534        self -> data3  =  mp_obj_new_int ((mp_int_t )data3 );
468- 
469-         if  (data2  !=  -1  &&  data3  !=  -1 ) {
470-             self -> quad  =  true;
471-         } else  {
472-             self -> quad  =  false;
473-         }
535+         self -> data4  =  mp_obj_new_int ((mp_int_t )data4 );
536+         self -> data5  =  mp_obj_new_int ((mp_int_t )data5 );
537+         self -> data6  =  mp_obj_new_int ((mp_int_t )data6 );
538+         self -> data7  =  mp_obj_new_int ((mp_int_t )data7 );
539+         self -> dual  =  dual ;
540+         self -> quad  =  quad ;
541+         self -> octal  =  octal ;
474542    }
475543
476544    return  MP_OBJ_FROM_PTR (self );
@@ -483,16 +551,20 @@ void machine_hw_spi_bus_initilize(machine_hw_spi_bus_obj_t *bus)
483551
484552    uint32_t  flags  =  0 ;
485553
486-     if  (self -> quad ) { 
487-          flags  |= SPICOMMON_BUSFLAG_QUAD ;
488-     } 
554+     if  (self -> dual )  flags  |=  SPICOMMON_BUSFLAG_DUAL ; 
555+     if  ( self -> quad )  flags  |= SPICOMMON_BUSFLAG_QUAD ;
556+     if  ( self -> octal )  flags  |=  SPICOMMON_BUSFLAG_OCTAL ; 
489557
490558    spi_bus_config_t  buscfg  =  {
491559        .miso_io_num  =  (int )mp_obj_get_int (bus -> miso ),
492560        .mosi_io_num  =  (int )mp_obj_get_int (bus -> mosi ),
493561        .sclk_io_num  =  (int )mp_obj_get_int (bus -> sck ),
494562        .data2_io_num  =  (int )mp_obj_get_int (bus -> data2 ),
495563        .data3_io_num  =  (int )mp_obj_get_int (bus -> data3 ),
564+         .data4_io_num  =  (int )mp_obj_get_int (bus -> data4 ),
565+         .data5_io_num  =  (int )mp_obj_get_int (bus -> data5 ),
566+         .data6_io_num  =  (int )mp_obj_get_int (bus -> data6 ),
567+         .data7_io_num  =  (int )mp_obj_get_int (bus -> data7 ),
496568        .flags  =  flags ,
497569        .max_transfer_sz  =  SPI_LL_DMA_MAX_BIT_LEN  / 8 
498570    };
@@ -535,15 +607,18 @@ spi_host_device_t machine_hw_spi_get_host(mp_obj_t in) {
535607
536608mp_obj_t  machine_hw_spi_device_make_new (const  mp_obj_type_t  * type , size_t  n_args , size_t  n_kw , const  mp_obj_t  * all_args ) {
537609
538-     enum  { ARG_spi_bus , ARG_freq , ARG_cs , ARG_polarity , ARG_phase , ARG_bits , ARG_firstbit , ARG_quad };
610+     enum  { ARG_spi_bus , ARG_freq , ARG_cs , ARG_polarity , ARG_phase , ARG_bits , ARG_firstbit , ARG_dual ,  ARG_quad ,  ARG_octal   };
539611    static  const  mp_arg_t  allowed_args [] =  {
540612        { MP_QSTR_spi_bus ,  MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_OBJ  },
541613        { MP_QSTR_freq ,     MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
542614        { MP_QSTR_cs ,       MP_ARG_KW_ONLY  | MP_ARG_REQUIRED  | MP_ARG_INT  },
543-         { MP_QSTR_polarity , MP_ARG_KW_ONLY  | MP_ARG_INT ,  {.u_int  =  0 } },
544-         { MP_QSTR_phase ,    MP_ARG_KW_ONLY  | MP_ARG_INT ,  {.u_int  =  0 } },
545-         { MP_QSTR_bits ,     MP_ARG_KW_ONLY  | MP_ARG_INT ,  {.u_int  =  8 } },
546-         { MP_QSTR_firstbit , MP_ARG_KW_ONLY  | MP_ARG_INT ,  {.u_int  =  MICROPY_PY_MACHINE_SPI_MSB } }
615+         { MP_QSTR_polarity , MP_ARG_KW_ONLY  | MP_ARG_INT ,  { .u_int  =  0  } },
616+         { MP_QSTR_phase ,    MP_ARG_KW_ONLY  | MP_ARG_INT ,  { .u_int  =  0  } },
617+         { MP_QSTR_bits ,     MP_ARG_KW_ONLY  | MP_ARG_INT ,  { .u_int  =  8  } },
618+         { MP_QSTR_firstbit , MP_ARG_KW_ONLY  | MP_ARG_INT ,  { .u_int  =  MICROPY_PY_MACHINE_SPI_MSB } },
619+         { MP_QSTR_dual ,     MP_ARG_KW_ONLY  | MP_ARG_BOOL , { .u_bool  =  false } },
620+         { MP_QSTR_quad ,     MP_ARG_KW_ONLY  | MP_ARG_BOOL , { .u_bool  =  false } },
621+         { MP_QSTR_octal ,    MP_ARG_KW_ONLY  | MP_ARG_BOOL , { .u_bool  =  false } }
547622    };
548623
549624    mp_arg_val_t  args [MP_ARRAY_SIZE (allowed_args )];
@@ -558,6 +633,18 @@ mp_obj_t machine_hw_spi_device_make_new(const mp_obj_type_t *type, size_t n_args
558633    self -> cs  =  mp_obj_new_int ((mp_int_t )cs );
559634    self -> bits  =   (uint8_t )args [ARG_bits ].u_int ;
560635    self -> deinit  =  & machine_hw_spi_device_deinit_callback ;
636+     bool  dual  =  (bool )args [ARG_dual ].u_bool ;
637+     bool  quad  =  (bool )args [ARG_quad ].u_bool ;
638+     bool  octal  =  (bool )args [ARG_octal ].u_bool ;
639+ 
640+ 
641+     if  (!self -> spi_bus -> dual ) dual  =  false;
642+     if  (!self -> spi_bus -> quad ) quad  =  false;
643+     if  (!self -> spi_bus -> octal ) octal  =  false;
644+ 
645+     self -> dual  =  dual ;
646+     self -> quad  =  quad ;
647+     self -> octal  =  octal ;
561648
562649    spi_device_interface_config_t  devcfg  =  {
563650        .clock_speed_hz  =  (uint32_t )spi_get_actual_clock (APB_CLK_FREQ , args [ARG_freq ].u_int , 0 ),
0 commit comments