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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy