Skip to content

Commit 4140012

Browse files
committed
Allow pins >= 32, allow write pin on different register than data pins
1 parent 10965e5 commit 4140012

File tree

3 files changed

+69
-53
lines changed

3 files changed

+69
-53
lines changed

locale/circuitpython.pot

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ msgid "Data 0 pin must be byte aligned"
798798
msgstr ""
799799

800800
#: ports/esp32s2/common-hal/displayio/ParallelBus.c
801-
msgid "Data 0 pin must be byte aligned and < 32"
801+
msgid "Data 0 pin must be byte aligned."
802802
msgstr ""
803803

804804
#: shared-module/audiocore/WaveFile.c
@@ -2140,10 +2140,6 @@ msgstr ""
21402140
msgid "Woken up by alarm.\n"
21412141
msgstr ""
21422142

2143-
#: ports/esp32s2/common-hal/displayio/ParallelBus.c
2144-
msgid "Write pin must be < 32"
2145-
msgstr ""
2146-
21472143
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
21482144
msgid "Writes not supported on Characteristic"
21492145
msgstr ""

ports/esp32s2/common-hal/displayio/ParallelBus.c

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@
3636
/*
3737
*
3838
* Current pin limitations for ESP32-S2 ParallelBus:
39-
* 1. data0 pin must be byte aligned (data0 pin options: 0, 8, 16 or 24)
40-
* 2. The 8 data lines must use pin numbers < 32
41-
* 3. The write pin must be pin number < 32.
39+
* - data0 pin must be byte aligned (data0 pin options: 0, 8, 16 or 24)
4240
*
4341
*/
4442

@@ -48,7 +46,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
4846

4947
uint8_t data_pin = data0->number;
5048
if ( (data_pin % 8 != 0) && (data_pin >= 32) ) {
51-
mp_raise_ValueError(translate("Data 0 pin must be byte aligned and < 32"));
49+
mp_raise_ValueError(translate("Data 0 pin must be byte aligned."));
5250
}
5351

5452
for (uint8_t i = 0; i < 8; i++) {
@@ -57,10 +55,6 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
5755
}
5856
}
5957

60-
if (write->number >= 32) {
61-
mp_raise_ValueError(translate("Write pin must be < 32"));
62-
}
63-
6458
gpio_dev_t *g = &GPIO; // this is the GPIO registers, see "extern gpio_dev_t GPIO" from file:gpio_struct.h
6559

6660
// Setup the pins as "Simple GPIO outputs" see section 19.3.3 of the ESP32-S2 Reference Manual
@@ -74,11 +68,14 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
7468

7569
/* From my understanding, there is a limitation of the ESP32-S2 that does not allow single-byte writes
7670
* into the GPIO registers. See section 10.3.3 regarding "non-aligned writes" into the registers.
77-
* If a method for writing single-byte writes is uncovered, this code can be modified to provide
78-
* single-byte access into the output register
7971
*/
8072

81-
self->bus = (uint32_t*) &g->out; //pointer to GPIO output register (for pins 0-31)
73+
74+
if (data_pin < 31) {
75+
self->bus = (uint32_t*) &g->out; //pointer to GPIO output register (for pins 0-31)
76+
} else {
77+
self->bus = (uint32_t*) &g->out1.val; //pointer to GPIO output register (for pins >= 32)
78+
}
8279

8380
/* SNIP - common setup of command, chip select, write and read pins, same as from SAMD and NRF ports */
8481
self->command.base.type = &digitalio_digitalinout_type;
@@ -98,17 +95,38 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
9895
common_hal_digitalio_digitalinout_switch_to_output(&self->read, true, DRIVE_MODE_PUSH_PULL);
9996

10097
self->data0_pin = data_pin;
101-
self->write_group = &GPIO;
102-
/* If we want to allow a write pin >= 32, should consider putting separate "clear_write" and
103-
* "set_write" pointers into the .h in place of "write_group"
104-
* to select between out_w1tc/out1_w1tc (clear) and out_w1ts/out1_w1ts (set) registers.
105-
*/
98+
99+
if (write->number < 32) {
100+
self->write_clear_register = (uint32_t*) &g->out_w1tc;
101+
self->write_set_register = (uint32_t*) &g->out_w1ts;
102+
} else {
103+
self->write_clear_register = (uint32_t*) &g->out1_w1tc.val;
104+
self->write_set_register = (uint32_t*) &g->out1_w1ts.val;
105+
}
106+
107+
// Check to see if the data and write pins are on the same register:
108+
if ( ( ((self->data0_pin < 32) && (write->number < 32)) ) ||
109+
( ((self->data0_pin > 31) && (write->number > 31)) ) ) {
110+
self->data_write_same_register = true; // data pins and write pin are on the same register
111+
} else {
112+
self->data_write_same_register = false; // data pins and write pins are on different registers
113+
}
114+
115+
116+
mp_printf(&mp_plat_print, "write_clear: %x, write_set: %x\n", self->write_clear_register, self->write_set_register);
106117

107118
self->write_mask = 1 << (write->number % 32); /* the write pin triggers the LCD to latch the data */
108-
/* Note: As currently written for the ESP32-S2 port, the write pin must be a pin number less than 32
109-
* This could be updated to accommodate 32 and higher by using the different construction of the
110-
* address for writing to output pins >= 32, see related note above for 'self->write_group'
111-
*/
119+
mp_printf(&mp_plat_print, "write_mask: %x\n", self->write_mask);
120+
121+
mp_printf(&mp_plat_print, "out1 register: %x\n", g->out1.val);
122+
mp_printf(&mp_plat_print, "clear a bit\n");
123+
*self->write_clear_register = self->write_mask;
124+
mp_printf(&mp_plat_print, "out1 register: %x\n", g->out1.val);
125+
mp_printf(&mp_plat_print, "write a bit\n");
126+
*self->write_set_register = self->write_mask;
127+
mp_printf(&mp_plat_print, "out1 register: %x\n", g->out1.val);
128+
129+
*self->write_clear_register = self->write_mask;
112130

113131
/* SNIP - common setup of the reset pin, same as from SAMD and NRF ports */
114132
self->reset.base.type = &mp_type_NoneType;
@@ -174,13 +192,8 @@ void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byt
174192
displayio_parallelbus_obj_t* self = MP_OBJ_TO_PTR(obj);
175193
common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA);
176194

177-
/* Currently the write pin number must be < 32.
178-
* Future: To accommodate write pin numbers >= 32, will need to update to choose the correct register
179-
* for the write pin set/clear (out_w1ts/out1_w1ts and out_w1tc/out1_w1tc)
180-
*/
181-
182-
uint32_t* clear_write = (uint32_t*) &self->write_group->out_w1tc;
183-
uint32_t* set_write = (uint32_t*) &self->write_group->out_w1ts;
195+
uint32_t* clear_write = self->write_clear_register;
196+
uint32_t* set_write = self->write_set_register;
184197

185198
const uint32_t mask = self->write_mask;
186199

@@ -197,24 +210,29 @@ void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byt
197210
* each data byte will be written to the data pin registers
198211
*/
199212

200-
for (uint32_t i = 0; i < data_length; i++) {
201213

202-
/* Question: Is there a faster way of stuffing the data byte into the data_buffer, is bit arithmetic
203-
* faster than writing to the byte address?
204-
*/
205-
206-
/* Note: If the write pin and data pins are controlled by the same GPIO register, we can eliminate
207-
* the "clear_write" step below, since the write pin is cleared when the data_buffer is written
208-
* to the bus.
209-
* Remember: This method requires the write pin to be controlled by the same GPIO register as the data pins.
210-
*/
211-
212-
// *clear_write = mask; // clear the write pin (See comment above, this may not be necessary).
213-
214-
*(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location
215-
*self->bus = data_buffer; // write the data to the output register
216-
*set_write = mask; // set the write pin
217-
}
214+
if ( self->data_write_same_register ) { // data and write pins are on the same register
215+
for (uint32_t i = 0; i < data_length; i++) {
216+
217+
/* Note: If the write pin and data pins are controlled by the same GPIO register, we can eliminate
218+
* the "clear_write" step below, since the write pin is cleared when the data_buffer is written
219+
* to the bus.
220+
*/
221+
222+
*(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location
223+
*self->bus = data_buffer; // write the data to the output register
224+
*set_write = mask; // set the write pin
225+
}
226+
}
227+
else { // data and write pins are on different registers
228+
for (uint32_t i = 0; i < data_length; i++) {
229+
*clear_write = mask; // clear the write pin (See comment above, this may not be necessary).
230+
*(data_address) = data[i]; // stuff the data byte into the data_buffer at the correct offset byte location
231+
*self->bus = data_buffer; // write the data to the output register
232+
*set_write = mask; // set the write pin
233+
234+
}
235+
}
218236

219237
}
220238

ports/esp32s2/common-hal/displayio/ParallelBus.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ typedef struct {
3535
digitalio_digitalinout_obj_t command;
3636
digitalio_digitalinout_obj_t chip_select;
3737
digitalio_digitalinout_obj_t reset;
38-
digitalio_digitalinout_obj_t write; // write pin, must be a pin number < 32 currently
38+
digitalio_digitalinout_obj_t write;
3939
digitalio_digitalinout_obj_t read;
40-
uint8_t data0_pin; // pin number for the lowest number pin. Must be 0, 8, 16 or 24 with current
41-
gpio_dev_t* write_group; // pointer to the write group for setting/clearing the write bit to latch the data on the LCD
42-
uint32_t write_mask; // bit mask for the single bit for the write pin, currently write pin must be a pin number < 32
40+
uint8_t data0_pin; // pin number for the lowest number data pin. Must be 8-bit aligned
41+
bool data_write_same_register; // if data and write pins are in the sare
42+
uint32_t* write_set_register; // pointer to the write group for setting the write bit to latch the data on the LCD
43+
uint32_t* write_clear_register; // pointer to the write group for clearing the write bit to latch the data on the LCD
44+
uint32_t write_mask; // bit mask for the single bit for the write pin register
4345
} displayio_parallelbus_obj_t;
4446

4547
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_DISPLAYIO_PARALLELBUS_H

0 commit comments

Comments
 (0)