36
36
/*
37
37
*
38
38
* 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)
42
40
*
43
41
*/
44
42
@@ -48,7 +46,7 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
48
46
49
47
uint8_t data_pin = data0 -> number ;
50
48
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. " ));
52
50
}
53
51
54
52
for (uint8_t i = 0 ; i < 8 ; i ++ ) {
@@ -57,10 +55,6 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
57
55
}
58
56
}
59
57
60
- if (write -> number >= 32 ) {
61
- mp_raise_ValueError (translate ("Write pin must be < 32" ));
62
- }
63
-
64
58
gpio_dev_t * g = & GPIO ; // this is the GPIO registers, see "extern gpio_dev_t GPIO" from file:gpio_struct.h
65
59
66
60
// 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
74
68
75
69
/* From my understanding, there is a limitation of the ESP32-S2 that does not allow single-byte writes
76
70
* 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
79
71
*/
80
72
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
+ }
82
79
83
80
/* SNIP - common setup of command, chip select, write and read pins, same as from SAMD and NRF ports */
84
81
self -> command .base .type = & digitalio_digitalinout_type ;
@@ -98,17 +95,38 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel
98
95
common_hal_digitalio_digitalinout_switch_to_output (& self -> read , true, DRIVE_MODE_PUSH_PULL );
99
96
100
97
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 );
106
117
107
118
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 ;
112
130
113
131
/* SNIP - common setup of the reset pin, same as from SAMD and NRF ports */
114
132
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
174
192
displayio_parallelbus_obj_t * self = MP_OBJ_TO_PTR (obj );
175
193
common_hal_digitalio_digitalinout_set_value (& self -> command , byte_type == DISPLAY_DATA );
176
194
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 ;
184
197
185
198
const uint32_t mask = self -> write_mask ;
186
199
@@ -197,24 +210,29 @@ void common_hal_displayio_parallelbus_send(mp_obj_t obj, display_byte_type_t byt
197
210
* each data byte will be written to the data pin registers
198
211
*/
199
212
200
- for (uint32_t i = 0 ; i < data_length ; i ++ ) {
201
213
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
+ }
218
236
219
237
}
220
238
0 commit comments