@@ -51,11 +51,16 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t *self,
51
51
self -> polarity = polarity ;
52
52
self -> phase = phase ;
53
53
54
- common_hal_digitalio_digitalinout_construct (& self -> command , command );
55
- common_hal_digitalio_digitalinout_switch_to_output (& self -> command , true, DRIVE_MODE_PUSH_PULL );
56
54
common_hal_digitalio_digitalinout_construct (& self -> chip_select , chip_select );
57
55
common_hal_digitalio_digitalinout_switch_to_output (& self -> chip_select , true, DRIVE_MODE_PUSH_PULL );
58
56
57
+ self -> command .base .type = & mp_type_NoneType ;
58
+ if (command != NULL ) {
59
+ self -> command .base .type = & digitalio_digitalinout_type ;
60
+ common_hal_digitalio_digitalinout_construct (& self -> command , command );
61
+ common_hal_digitalio_digitalinout_switch_to_output (& self -> command , true, DRIVE_MODE_PUSH_PULL );
62
+ common_hal_never_reset_pin (command );
63
+ }
59
64
self -> reset .base .type = & mp_type_NoneType ;
60
65
if (reset != NULL ) {
61
66
self -> reset .base .type = & digitalio_digitalinout_type ;
@@ -65,7 +70,6 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t *self,
65
70
common_hal_displayio_fourwire_reset (self );
66
71
}
67
72
68
- common_hal_never_reset_pin (command );
69
73
common_hal_never_reset_pin (chip_select );
70
74
}
71
75
@@ -114,18 +118,57 @@ bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) {
114
118
void common_hal_displayio_fourwire_send (mp_obj_t obj , display_byte_type_t data_type ,
115
119
display_chip_select_behavior_t chip_select , const uint8_t * data , uint32_t data_length ) {
116
120
displayio_fourwire_obj_t * self = MP_OBJ_TO_PTR (obj );
117
- common_hal_digitalio_digitalinout_set_value (& self -> command , data_type == DISPLAY_DATA );
118
- if (chip_select == CHIP_SELECT_TOGGLE_EVERY_BYTE ) {
119
- // Toggle chip select after each command byte in case the display driver
120
- // IC latches commands based on it.
121
+ if (self -> command .base .type == & mp_type_NoneType ) {
122
+ // When the data/command pin is not specified, we simulate a 9-bit SPI mode, by
123
+ // adding a data/command bit to every byte, and then splitting the resulting data back
124
+ // into 8-bit chunks for transmission. If the length of the data being transmitted
125
+ // is not a multiple of 8, there will be additional bits at the end of the
126
+ // transmission. We toggle the CS pin to make the receiver discard them.
127
+ uint8_t buffer = 0 ;
128
+ uint8_t bits = 0 ;
129
+ uint8_t dc = (data_type == DISPLAY_DATA );
130
+
121
131
for (size_t i = 0 ; i < data_length ; i ++ ) {
122
- common_hal_busio_spi_write (self -> bus , & data [i ], 1 );
132
+ bits = (bits + 1 ) % 8 ;
133
+
134
+ if (bits == 0 ) {
135
+ // send the previous byte and the dc bit
136
+ // we will send the current byte later
137
+ buffer = (buffer << 1 ) | dc ;
138
+ common_hal_busio_spi_write (self -> bus , & buffer , 1 );
139
+ // send the current byte, because previous byte already filled all bits
140
+ common_hal_busio_spi_write (self -> bus , & data [i ], 1 );
141
+ } else {
142
+ // send remaining bits from previous byte, dc and beginning of current byte
143
+ buffer = (buffer << (9 - bits )) | (dc << (8 - bits )) | (data [i ] >> bits );
144
+ common_hal_busio_spi_write (self -> bus , & buffer , 1 );
145
+ }
146
+ // save the current byte
147
+ buffer = data [i ];
148
+ }
149
+ // send any remaining bits
150
+ if (bits > 0 ) {
151
+ buffer = buffer << (8 - bits );
152
+ common_hal_busio_spi_write (self -> bus , & buffer , 1 );
153
+ // toggle CS to discard superfluous bits
123
154
common_hal_digitalio_digitalinout_set_value (& self -> chip_select , true);
124
155
common_hal_mcu_delay_us (1 );
125
156
common_hal_digitalio_digitalinout_set_value (& self -> chip_select , false);
126
157
}
127
158
} else {
128
- common_hal_busio_spi_write (self -> bus , data , data_length );
159
+ common_hal_digitalio_digitalinout_set_value (& self -> command , data_type == DISPLAY_DATA );
160
+ if (chip_select == CHIP_SELECT_TOGGLE_EVERY_BYTE ) {
161
+ // Toggle chip select after each command byte in case the display driver
162
+ // IC latches commands based on it.
163
+ for (size_t i = 0 ; i < data_length ; i ++ ) {
164
+ common_hal_busio_spi_write (self -> bus , & data [i ], 1 );
165
+ common_hal_digitalio_digitalinout_set_value (& self -> chip_select , true);
166
+ common_hal_mcu_delay_us (1 );
167
+ common_hal_digitalio_digitalinout_set_value (& self -> chip_select , false);
168
+ }
169
+ } else {
170
+ common_hal_busio_spi_write (self -> bus , data , data_length );
171
+ }
129
172
}
130
173
}
131
174
0 commit comments