@@ -115,43 +115,52 @@ static bool pbdrv_display_user_frame_update_requested;
115115static uint8_t pbdrv_display_send_buffer [PBDRV_CONFIG_DISPLAY_NUM_COLS ];
116116
117117/*
118- * Set the data transmission mode.
118+ * Switch to command transmission mode and send a command byte to the LCD controller .
119119 */
120- static void spi_set_tx_mode (spi_mode_t mode ) {
121- if (spi_mode == mode ) {
122- // Mode hasn't changed, no-op.
123- return ;
124- } else {
120+ static pbio_error_t spi_write_command_byte (pbio_os_state_t * state , uint8_t command ) {
121+ PBIO_OS_ASYNC_BEGIN (state );
122+
123+ if (spi_mode != SPI_MODE_COMMAND ) {
125124 // If there is a mode switch, we need to let the SPI controller
126125 // drain all data first, to avoid spurious writes of the wrong
127126 // type.
128127 while (!(* AT91C_SPI_SR & AT91C_SPI_TXEMPTY )) {
129- ;
128+ pbio_os_request_poll ();
129+ PBIO_OS_AWAIT_ONCE (state );
130130 }
131+ spi_mode = SPI_MODE_COMMAND ;
132+ * AT91C_PIOA_CODR = AT91C_PA12_MISO ;
131133 }
132134
133- spi_mode = mode ;
134-
135- if (mode == SPI_MODE_COMMAND ) {
136- * AT91C_PIOA_CODR = AT91C_PA12_MISO ;
137- } else {
138- * AT91C_PIOA_SODR = AT91C_PA12_MISO ;
135+ // Wait for the transmit register to empty.
136+ while (!(* AT91C_SPI_SR & AT91C_SPI_TDRE )) {
137+ pbio_os_request_poll ();
138+ PBIO_OS_AWAIT_ONCE (state );
139139 }
140+
141+ // Send the command byte.
142+ * AT91C_SPI_TDR = command ;
143+
144+ PBIO_OS_ASYNC_END (PBIO_SUCCESS );
140145}
141146
142147/*
143- * Send a command byte to the LCD controller .
148+ * Switch to data transmission mode .
144149 */
145- static void spi_write_command_byte ( uint8_t command ) {
146- spi_set_tx_mode ( SPI_MODE_COMMAND );
150+ static pbio_error_t spi_set_data_mode ( pbio_os_state_t * state ) {
151+ PBIO_OS_ASYNC_BEGIN ( state );
147152
148- // Wait for the transmit register to empty.
149- while (!(* AT91C_SPI_SR & AT91C_SPI_TDRE )) {
150- ;
153+ // Let the SPI controller drain all data first, to avoid spurious
154+ // writes of the wrong type.
155+ while (!(* AT91C_SPI_SR & AT91C_SPI_TXEMPTY )) {
156+ pbio_os_request_poll ();
157+ PBIO_OS_AWAIT_ONCE (state );
151158 }
152159
153- // Send the command byte and wait for a reply.
154- * AT91C_SPI_TDR = command ;
160+ spi_mode = SPI_MODE_DATA ;
161+ * AT91C_PIOA_SODR = AT91C_PA12_MISO ;
162+
163+ PBIO_OS_ASYNC_END (PBIO_SUCCESS );
155164}
156165
157166/*
@@ -235,6 +244,7 @@ static pbio_os_process_t pbdrv_display_nxt_process;
235244 */
236245static pbio_error_t pbdrv_display_nxt_process_thread (pbio_os_state_t * state , void * context ) {
237246 static pbio_os_timer_t timer ;
247+ static pbio_os_state_t sub ;
238248 static size_t i ;
239249 static int page ;
240250
@@ -294,20 +304,20 @@ static pbio_error_t pbdrv_display_nxt_process_thread(pbio_os_state_t *state, voi
294304 // Issue a reset command, and wait. Normally here we'd check the
295305 // UC1601 status register, but as noted at the start of the file, we
296306 // can't read from the LCD controller due to the board setup.
297- spi_write_command_byte (RESET ());
307+ PBIO_OS_AWAIT ( state , & sub , spi_write_command_byte (& sub , RESET () ));
298308 PBIO_OS_AWAIT_MS (state , & timer , 20 );
299309
300310 // Send every command of the init sequence.
301311 for (i = 0 ; i < sizeof (lcd_init_sequence ); i ++ ) {
302- spi_write_command_byte (lcd_init_sequence [i ]);
312+ PBIO_OS_AWAIT ( state , & sub , spi_write_command_byte (& sub , lcd_init_sequence [i ]) );
303313 }
304314
305315 // Clear display to start with.
306316 memset (& pbdrv_display_user_frame , 0 , sizeof (pbdrv_display_user_frame ));
307317 pbdrv_display_user_frame_update_requested = true;
308318
309319 // Make sure that we are in data TX mode.
310- spi_set_tx_mode ( SPI_MODE_DATA );
320+ PBIO_OS_AWAIT ( state , & sub , spi_set_data_mode ( & sub ) );
311321
312322 // Done initializing.
313323 pbio_busy_count_down ();
@@ -348,7 +358,7 @@ static pbio_error_t pbdrv_display_nxt_process_thread(pbio_os_state_t *state, voi
348358 // capacitors gracefully.
349359 * AT91C_SPI_IDR = ~0 ;
350360 * AT91C_SPI_PTCR = AT91C_PDC_TXTDIS ;
351- spi_write_command_byte (RESET ());
361+ PBIO_OS_AWAIT ( state , & sub , spi_write_command_byte (& sub , RESET () ));
352362 PBIO_OS_AWAIT_MS (state , & timer , 20 );
353363
354364 pbio_busy_count_down ();
0 commit comments