Skip to content

Commit b955b07

Browse files
committed
pbio/drv/display_nxt: Deinit from the display thread.
Use asynchronous code to avoid blocking. Thanks: Laurens for the code to do it. Refs: pybricks/support#2425
1 parent 3899247 commit b955b07

1 file changed

Lines changed: 20 additions & 12 deletions

File tree

lib/pbio/drv/display/display_nxt.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ static pbio_error_t pbdrv_display_nxt_process_thread(pbio_os_state_t *state, voi
338338
pbio_busy_count_down();
339339

340340
// Update the display with the user frame buffer, if changed.
341-
for (;;) {
341+
while (pbdrv_display_nxt_process.request != PBIO_OS_PROCESS_REQUEST_TYPE_CANCEL) {
342342
PBIO_OS_AWAIT_UNTIL(state, pbdrv_display_user_frame_update_requested);
343343
pbdrv_display_user_frame_update_requested = false;
344344
for (page = 0; page < PBDRV_CONFIG_DISPLAY_NUM_ROWS / 8; page++) {
@@ -365,7 +365,20 @@ static pbio_error_t pbdrv_display_nxt_process_thread(pbio_os_state_t *state, voi
365365
}
366366
}
367367

368-
PBIO_OS_ASYNC_END(PBIO_SUCCESS);
368+
// When power to the controller goes out, there is the risk that
369+
// some capacitors mounted around the controller might damage it
370+
// when discharging in an uncontrolled fashion. To avoid this, the
371+
// spec recommends putting the controller into reset mode before
372+
// shutdown, which activates a drain circuit to empty the board
373+
// capacitors gracefully.
374+
*AT91C_SPI_IDR = ~0;
375+
*AT91C_SPI_PTCR = AT91C_PDC_TXTDIS;
376+
spi_write_command_byte(RESET());
377+
PBIO_OS_AWAIT_MS(state, &timer, 20);
378+
379+
pbio_busy_count_down();
380+
381+
PBIO_OS_ASYNC_END(PBIO_ERROR_CANCELED);
369382
}
370383

371384
// Image corresponding to the display.
@@ -407,16 +420,11 @@ void pbdrv_display_update(void) {
407420
}
408421

409422
void pbdrv_display_deinit(void) {
410-
// When power to the controller goes out, there is the risk that
411-
// some capacitors mounted around the controller might damage it
412-
// when discharging in an uncontrolled fashion. To avoid this, the
413-
// spec recommends putting the controller into reset mode before
414-
// shutdown, which activates a drain circuit to empty the board
415-
// capacitors gracefully.
416-
*AT91C_SPI_IDR = ~0;
417-
*AT91C_SPI_PTCR = AT91C_PDC_TXTDIS;
418-
spi_write_command_byte(RESET());
419-
nx_systick_wait_ms(20);
423+
// This doesn't do deinit right away, but it ask the display process to
424+
// gracefully exit at a useful spot, and then do deinit. The busy count is
425+
// used so all processes can await deinit before actual power off.
426+
pbio_busy_count_up();
427+
pbio_os_process_make_request(&pbdrv_display_nxt_process, PBIO_OS_PROCESS_REQUEST_TYPE_CANCEL);
420428
}
421429

422430
#endif // PBDRV_CONFIG_DISPLAY_NXT

0 commit comments

Comments
 (0)