Skip to content

Commit 94b6dda

Browse files
committed
pbio/drv/display: Upgrade to new event loop system.
Drop contiki usage and use pbio_os instead. Remove the update timer, just update as needed. Refs pybricks/support#2251
1 parent 26ebe18 commit 94b6dda

File tree

1 file changed

+64
-71
lines changed

1 file changed

+64
-71
lines changed

lib/pbio/drv/display/display_ev3.c

Lines changed: 64 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313
#include <stdio.h>
1414
#include <string.h>
1515

16-
#include <contiki.h>
17-
1816
#include "../core.h"
1917

2018
#include <pbdrv/gpio.h>
2119
#include <pbdrv/display.h>
2220
#include <pbio/error.h>
2321
#include <pbio/util.h>
22+
#include <pbio/os.h>
2423

2524
#include <tiam1808/edma.h>
2625
#include <tiam1808/spi.h>
@@ -112,8 +111,6 @@ static const pbdrv_gpio_t pin_lcd_reset = PBDRV_GPIO_EV3_PIN(12, 31, 28, 5, 0);
112111

113112
static volatile spi_status_t spi_status = SPI_STATUS_ERROR;
114113

115-
PROCESS(pbdrv_display_ev3_init_process, "st7586s");
116-
117114
/**
118115
* Number of column triplets. Each triplet is 3 columns of pixels, as detailed
119116
* below in the description of the display buffer.
@@ -350,7 +347,7 @@ static const pbdrv_display_st7586s_action_t init_script[] = {
350347
void pbdrv_display_ev3_spi1_tx_complete(uint32_t status) {
351348
SPIIntDisable(SOC_SPI_1_REGS, SPI_DMA_REQUEST_ENA_INT);
352349
spi_status = SPI_STATUS_COMPLETE;
353-
process_poll(&pbdrv_display_ev3_init_process);
350+
pbio_os_request_poll();
354351
}
355352

356353
/**
@@ -407,70 +404,26 @@ void pbdrv_display_st7586s_write_data_begin(uint8_t *data, uint32_t size) {
407404
SPIIntEnable(SOC_SPI_1_REGS, SPI_DMA_REQUEST_ENA_INT);
408405
}
409406

410-
/**
411-
* Initialize the display SPI driver.
412-
*
413-
* Pinmux and common EDMA handlers are already set up in platform.c.
414-
*/
415-
void pbdrv_display_init(void) {
416-
417-
// GPIO Mux. CS is in GPIO mode (manual control).
418-
pbdrv_gpio_alt(&pin_spi1_mosi, SYSCFG_PINMUX5_PINMUX5_23_20_SPI1_SIMO0);
419-
pbdrv_gpio_alt(&pin_spi1_clk, SYSCFG_PINMUX5_PINMUX5_11_8_SPI1_CLK);
420-
pbdrv_gpio_input(&pin_lcd_a0);
421-
pbdrv_gpio_input(&pin_lcd_cs);
422-
pbdrv_gpio_out_high(&pin_lcd_reset);
423-
424-
// Waking up the SPI1 instance.
425-
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_SPI1, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
426-
427-
// Reset.
428-
SPIReset(SOC_SPI_1_REGS);
429-
SPIOutOfReset(SOC_SPI_1_REGS);
430-
431-
// Mode.
432-
uint32_t spipc0 = SPI_SPIPC0_SOMIFUN | SPI_SPIPC0_SIMOFUN | SPI_SPIPC0_CLKFUN | SPI_SPIPC0_ENAFUN;
433-
SPIModeConfigure(SOC_SPI_1_REGS, SPI_MASTER_MODE);
434-
SPIPinControl(SOC_SPI_1_REGS, 0, 0, (unsigned int *)&spipc0);
435-
436-
// Config.
437-
SPIClkConfigure(SOC_SPI_1_REGS, SOC_SYSCLK_2_FREQ, 10000000, SPI_DATA_FORMAT0);
438-
SPICharLengthSet(SOC_SPI_1_REGS, 8, SPI_DATA_FORMAT0);
439-
SPIConfigClkFormat(SOC_SPI_1_REGS, SPI_CLK_POL_HIGH, SPI_DATA_FORMAT0);
440-
SPIDelayConfigure(SOC_SPI_1_REGS, 0, 0, 10, 10);
441-
SPIIntLevelSet(SOC_SPI_1_REGS, SPI_RECV_INTLVL | SPI_TRANSMIT_INTLVL);
442-
443-
// Request DMA Channel and TCC for SPI Transmit with queue number 0.
444-
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_SPI1_TX, EDMA3_CHA_SPI1_TX, 0);
445-
446-
// Enable the SPI controller.
447-
SPIEnable(SOC_SPI_1_REGS);
448-
449-
// Start SPI process and ask pbdrv to wait until it is initialized.
450-
pbdrv_init_busy_up();
451-
process_start(&pbdrv_display_ev3_init_process);
452-
}
407+
static pbio_os_process_t pbdrv_display_ev3_process;
453408

454409
/**
455410
* Display driver process. Initializes the display and updates the display
456411
* with the user frame buffer at a regular interval if the user data was
457412
* updated.
458413
*/
459-
PROCESS_THREAD(pbdrv_display_ev3_init_process, ev, data) {
414+
pbio_error_t pbdrv_display_ev3_process_thread(pbio_os_state_t *state, void *context) {
460415

461-
static struct etimer etimer;
416+
static pbio_os_timer_t timer;
462417
static uint32_t script_index;
463418
static uint8_t payload;
464419

465-
PROCESS_BEGIN();
420+
PBIO_OS_ASYNC_BEGIN(state);
466421

467422
#if ST7586S_DO_RESET_AND_INIT
468423
pbdrv_gpio_out_low(&pin_lcd_reset);
469-
etimer_set(&etimer, 10);
470-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER && etimer_expired(&etimer));
424+
PBIO_OS_AWAIT_MS(state, &timer, 10);
471425
pbdrv_gpio_out_high(&pin_lcd_reset);
472-
etimer_set(&etimer, 120);
473-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER && etimer_expired(&etimer));
426+
PBIO_OS_AWAIT_MS(state, &timer, 120);
474427
#endif // ST7586S_DO_RESET_AND_INIT
475428

476429
// For every action in the init script, either send a command or data, or
@@ -480,8 +433,7 @@ PROCESS_THREAD(pbdrv_display_ev3_init_process, ev, data) {
480433

481434
if (action->type == ST7586S_ACTION_DELAY) {
482435
// Simple delay.
483-
etimer_set(&etimer, action->payload);
484-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER && etimer_expired(&etimer));
436+
PBIO_OS_AWAIT_MS(state, &timer, action->payload);
485437
} else {
486438
// Send command or data.
487439
payload = action->payload;
@@ -491,7 +443,7 @@ PROCESS_THREAD(pbdrv_display_ev3_init_process, ev, data) {
491443
pbdrv_gpio_out_low(&pin_lcd_a0);
492444
}
493445
pbdrv_display_st7586s_write_data_begin(&payload, sizeof(payload));
494-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_POLL && spi_status == SPI_STATUS_COMPLETE);
446+
PBIO_OS_AWAIT_UNTIL(state, spi_status == SPI_STATUS_COMPLETE);
495447
pbdrv_gpio_out_high(&pin_lcd_cs);
496448
}
497449
}
@@ -503,27 +455,67 @@ PROCESS_THREAD(pbdrv_display_ev3_init_process, ev, data) {
503455
pbdrv_display_load_indexed_bitmap(pbdrv_display_pybricks_logo);
504456
pbdrv_display_st7586s_encode_user_frame();
505457
pbdrv_display_st7586s_write_data_begin(st7586s_send_buf, sizeof(st7586s_send_buf));
506-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_POLL && spi_status == SPI_STATUS_COMPLETE);
458+
PBIO_OS_AWAIT_UNTIL(state, spi_status == SPI_STATUS_COMPLETE);
507459
pbdrv_gpio_out_high(&pin_lcd_cs);
508460

509461
// Done initializing.
510462
pbdrv_init_busy_down();
511463

512-
// Regularly update the display with the user frame buffer, if changed.
513-
etimer_set(&etimer, 40);
464+
// Update the display with the user frame buffer, if changed.
514465
for (;;) {
515-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER && etimer_expired(&etimer));
516-
if (pbdrv_display_user_frame_update_requested) {
517-
pbdrv_display_user_frame_update_requested = false;
518-
pbdrv_display_st7586s_encode_user_frame();
519-
pbdrv_display_st7586s_write_data_begin(st7586s_send_buf, sizeof(st7586s_send_buf));
520-
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_POLL && spi_status == SPI_STATUS_COMPLETE);
521-
pbdrv_gpio_out_high(&pin_lcd_cs);
522-
}
523-
etimer_reset(&etimer);
466+
PBIO_OS_AWAIT_UNTIL(state, pbdrv_display_user_frame_update_requested);
467+
pbdrv_display_user_frame_update_requested = false;
468+
pbdrv_display_st7586s_encode_user_frame();
469+
pbdrv_display_st7586s_write_data_begin(st7586s_send_buf, sizeof(st7586s_send_buf));
470+
PBIO_OS_AWAIT_UNTIL(state, spi_status == SPI_STATUS_COMPLETE);
471+
pbdrv_gpio_out_high(&pin_lcd_cs);
524472
}
525473

526-
PROCESS_END();
474+
PBIO_OS_ASYNC_END(PBIO_SUCCESS);
475+
}
476+
477+
/**
478+
* Initialize the display SPI driver.
479+
*
480+
* Pinmux and common EDMA handlers are already set up in platform.c.
481+
*/
482+
void pbdrv_display_init(void) {
483+
484+
// GPIO Mux. CS is in GPIO mode (manual control).
485+
pbdrv_gpio_alt(&pin_spi1_mosi, SYSCFG_PINMUX5_PINMUX5_23_20_SPI1_SIMO0);
486+
pbdrv_gpio_alt(&pin_spi1_clk, SYSCFG_PINMUX5_PINMUX5_11_8_SPI1_CLK);
487+
pbdrv_gpio_input(&pin_lcd_a0);
488+
pbdrv_gpio_input(&pin_lcd_cs);
489+
pbdrv_gpio_out_high(&pin_lcd_reset);
490+
491+
// Waking up the SPI1 instance.
492+
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_SPI1, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
493+
494+
// Reset.
495+
SPIReset(SOC_SPI_1_REGS);
496+
SPIOutOfReset(SOC_SPI_1_REGS);
497+
498+
// Mode.
499+
uint32_t spipc0 = SPI_SPIPC0_SOMIFUN | SPI_SPIPC0_SIMOFUN | SPI_SPIPC0_CLKFUN | SPI_SPIPC0_ENAFUN;
500+
SPIModeConfigure(SOC_SPI_1_REGS, SPI_MASTER_MODE);
501+
SPIPinControl(SOC_SPI_1_REGS, 0, 0, (unsigned int *)&spipc0);
502+
503+
// Config.
504+
SPIClkConfigure(SOC_SPI_1_REGS, SOC_SYSCLK_2_FREQ, 10000000, SPI_DATA_FORMAT0);
505+
SPICharLengthSet(SOC_SPI_1_REGS, 8, SPI_DATA_FORMAT0);
506+
SPIConfigClkFormat(SOC_SPI_1_REGS, SPI_CLK_POL_HIGH, SPI_DATA_FORMAT0);
507+
SPIDelayConfigure(SOC_SPI_1_REGS, 0, 0, 10, 10);
508+
SPIIntLevelSet(SOC_SPI_1_REGS, SPI_RECV_INTLVL | SPI_TRANSMIT_INTLVL);
509+
510+
// Request DMA Channel and TCC for SPI Transmit with queue number 0.
511+
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_SPI1_TX, EDMA3_CHA_SPI1_TX, 0);
512+
513+
// Enable the SPI controller.
514+
SPIEnable(SOC_SPI_1_REGS);
515+
516+
// Start SPI process and ask pbdrv to wait until it is initialized.
517+
pbdrv_init_busy_up();
518+
pbio_os_process_start(&pbdrv_display_ev3_process, pbdrv_display_ev3_process_thread, NULL);
527519
}
528520

529521
pbio_image_t *pbdrv_display_get_image(void) {
@@ -540,6 +532,7 @@ uint8_t pbdrv_display_get_max_value(void) {
540532

541533
void pbdrv_display_update(void) {
542534
pbdrv_display_user_frame_update_requested = true;
535+
pbio_os_request_poll();
543536
}
544537

545538
#endif // PBDRV_CONFIG_DISPLAY_EV3

0 commit comments

Comments
 (0)