@@ -237,6 +237,15 @@ static mp_uint_t gcd(mp_uint_t x, mp_uint_t y)
237237return 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)
260269return ;
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
295282self -> 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
340327transaction .flags = SPI_TRANS_USE_TXDATA |SPI_TRANS_USE_RXDATA ;
341328transaction .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 ) {
343333transaction .flags |=SPI_TRANS_MODE_QIO ;
334+ }else if (self -> octal ) {
335+ transaction .flags |=SPI_TRANS_MODE_OCT ;
344336 }
337+
345338spi_device_transmit (spi_device ,& transaction );
346339
347340if (dest != NULL ) {
@@ -376,8 +369,12 @@ static void machine_hw_spi_device_transfer(mp_obj_base_t *self_in, size_t len, c
376369transaction -> 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 ) {
380375transaction .flags |=SPI_TRANS_MODE_QIO ;
376+ }else if (self -> octal ) {
377+ transaction .flags |=SPI_TRANS_MODE_OCT ;
381378 }
382379
383380spi_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 };
412409static 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
421418mp_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
425422int mosi = (int )args [ARG_mosi ].u_int ;
426423int miso = (int )args [ARG_miso ].u_int ;
427424int 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
431436machine_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+
433496if (1 <=host && host <=MICROPY_HW_SPI_MAX ) {
434497self = 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
452515if ((int )mp_obj_get_int (self -> sck )!= sck )reconfigure = true;
453516if ((int )mp_obj_get_int (self -> data2 )!= data2 )reconfigure = true;
454517if ((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
457524if (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
465532self -> sck = mp_obj_new_int ((mp_int_t )sck );
466533self -> data2 = mp_obj_new_int ((mp_int_t )data2 );
467534self -> 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
476544return MP_OBJ_FROM_PTR (self );
@@ -483,16 +551,20 @@ void machine_hw_spi_bus_initilize(machine_hw_spi_bus_obj_t *bus)
483551
484552uint32_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
490558spi_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 };
539611static 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
549624mp_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
558633self -> cs = mp_obj_new_int ((mp_int_t )cs );
559634self -> bits = (uint8_t )args [ARG_bits ].u_int ;
560635self -> 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
562649spi_device_interface_config_t devcfg = {
563650 .clock_speed_hz = (uint32_t )spi_get_actual_clock (APB_CLK_FREQ ,args [ARG_freq ].u_int ,0 ),