Skip to content

Commit 9f7c6c6

Browse files
committed
adds dual, quad and octal data transmitting modes for the SPI LCD and also for SPI Device.
you are able to "mix and match" when using the different type on a bus. Say you have a quad display and a normal spi touch panel. They can both be placed on the same bus. When constructing the display bus you add `quad=True` when constructing the `lcd_bus.SPIBus` instance. The display would get connected to miso, mosi, data2 and data3 pins and the touch would only get connected to the miso and mosi pins.
1 parent 65a7f7b commit 9f7c6c6

File tree

3 files changed

+172
-67
lines changed

3 files changed

+172
-67
lines changed

ext_mod/lcd_bus/esp32_src/spi_bus.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,12 @@ static mp_obj_t mp_lcd_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args
7373
ARG_freq,
7474
ARG_cs,
7575
ARG_dc_low_on_data,
76-
ARG_sio_mode,
7776
ARG_lsb_first,
7877
ARG_cs_high_active,
79-
ARG_spi_mode
78+
ARG_spi_mode,
79+
ARG_dual,
80+
ARG_quad,
81+
ARG_octal
8082
};
8183

8284
const mp_arg_t make_new_args[] = {
@@ -85,11 +87,12 @@ static mp_obj_t mp_lcd_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args
8587
{ MP_QSTR_freq, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
8688
{ MP_QSTR_cs, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = -1 } },
8789
{ MP_QSTR_dc_low_on_data, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
88-
{ MP_QSTR_sio_mode, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
8990
{ MP_QSTR_lsb_first, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
9091
{ MP_QSTR_cs_high_active, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
9192
{ MP_QSTR_spi_mode, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } },
92-
93+
{ MP_QSTR_dual, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
94+
{ MP_QSTR_quad, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
95+
{ MP_QSTR_octal, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
9396
};
9497

9598
mp_arg_val_t args[MP_ARRAY_SIZE(make_new_args)];
@@ -121,14 +124,15 @@ static mp_obj_t mp_lcd_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args
121124
self->panel_io_config.on_color_trans_done = &bus_trans_done_cb;
122125
self->panel_io_config.user_ctx = self;
123126
self->panel_io_config.flags.dc_low_on_data = (unsigned int)args[ARG_dc_low_on_data].u_bool;
124-
self->panel_io_config.flags.sio_mode = (unsigned int)args[ARG_sio_mode].u_bool;
125127
self->panel_io_config.flags.lsb_first = (unsigned int)args[ARG_lsb_first].u_bool;
126128
self->panel_io_config.flags.cs_high_active = (unsigned int)args[ARG_cs_high_active].u_bool;
127-
self->panel_io_config.flags.octal_mode = 0;
129+
self->panel_io_config.flags.sio_mode = (unsigned int)args[ARG_dual].u_bool;
130+
self->panel_io_config.flags.quad_mode = (unsigned int)args[ARG_quad].u_bool;
131+
self->panel_io_config.flags.octal_mode = (unsigned int)args[ARG_octal].u_bool;
128132

129-
if (spi_bus->quad) {
130-
self->panel_io_config.flags.quad_mode = 1;
131-
}
133+
if (!spi_bus->dual) self->panel_io_config.flags.sio_mode = 0;
134+
if (!spi_bus->quad) self->panel_io_config.flags.quad_mode = 0;
135+
if (!spi_bus->octal) self->panel_io_config.flags.octal_mode = 0;
132136

133137
self->panel_io_handle.del = &spi_del;
134138
self->panel_io_handle.init = &spi_init;
@@ -147,10 +151,11 @@ static mp_obj_t mp_lcd_spi_bus_make_new(const mp_obj_type_t *type, size_t n_args
147151
printf("spi_mode=%d\n", self->panel_io_config.spi_mode);
148152
printf("pclk_hz=%i\n", self->panel_io_config.pclk_hz);
149153
printf("dc_low_on_data=%d\n", self->panel_io_config.flags.dc_low_on_data);
150-
printf("sio_mode=%d\n", self->panel_io_config.flags.sio_mode);
151154
printf("lsb_first=%d\n", self->panel_io_config.flags.lsb_first);
152155
printf("cs_high_active=%d\n", self->panel_io_config.flags.cs_high_active);
153-
printf("octal_mode=%d\n", self->panel_io_config.flags.octal_mode);
156+
printf("dual=%d\n", self->panel_io_config.flags.sio_mode);
157+
printf("quad=%d\n", self->panel_io_config.flags.quad_mode);
158+
printf("octal=%d\n", self->panel_io_config.flags.octal_mode);
154159
#endif
155160

156161
return MP_OBJ_FROM_PTR(self);
@@ -232,6 +237,10 @@ mp_lcd_err_t spi_get_lane_count(mp_obj_t obj, uint8_t *lane_count)
232237

233238
if (self->panel_io_config.flags.sio_mode) {
234239
*lane_count = 2;
240+
} else if (self->panel_io_config.flags.quad_mode) {
241+
*lane_count = 4;
242+
} else if (self->panel_io_config.flags.octal_mode) {
243+
*lane_count = 8;
235244
} else {
236245
*lane_count = 1;
237246
}

micropy_updates/common/mp_spi_common.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@
2323
mp_obj_t miso;
2424
mp_obj_t data2;
2525
mp_obj_t data3;
26+
mp_obj_t data4;
27+
mp_obj_t data5;
28+
mp_obj_t data6;
29+
mp_obj_t data7;
30+
bool dual;
2631
bool quad;
32+
bool octal;
2733
uint8_t device_count;
2834
machine_hw_spi_device_obj_t **devices;
2935
mp_spi_state_t state;
@@ -38,6 +44,9 @@
3844
uint8_t phase;
3945
uint8_t bits;
4046
uint8_t firstbit;
47+
bool dual;
48+
bool quad;
49+
bool octal;
4150
bool active;
4251
mp_obj_t cs;
4352
machine_hw_spi_bus_obj_t *spi_bus;

micropy_updates/esp32/machine_hw_spi.c

Lines changed: 143 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -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

241250
static 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

409406
mp_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

536608
mp_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

Comments
 (0)