/* * MCU renderer * ST7789 on STM32 * * (C) 2023-2024 Gissio * * License: MIT */ #include #include #include #include "display.h" #include "system.h" // Connections #define DISPLAY_RESX_PORT GPIOB #define DISPLAY_RESX_PIN GPIO0 #define DISPLAY_CSX_PORT GPIOB #define DISPLAY_CSX_PIN GPIO1 #define DISPLAY_DCX_PORT GPIOB #define DISPLAY_DCX_PIN GPIO10 #define DISPLAY_SCL_PORT GPIOA #define DISPLAY_SCL_PIN GPIO5 #define DISPLAY_SDA_PORT GPIOA #define DISPLAY_SDA_PIN GPIO7 // Display static uint8_t display_text_buffer[80 * 80]; static const uint8_t display_init_sequence[] = { MR_SEND_COMMAND(MR_ST7789_INVON), // Inverse for IPS displays MR_END(), }; void on_display_sleep(uint32_t value); void on_display_set_reset(bool value); void on_display_set_command(bool value); void on_display_send(uint16_t value); void on_display_send16(uint16_t value); void on_display_sleep(uint32_t value) { sleep(value); } void on_display_set_reset(bool value) { if (value) gpio_clear(DISPLAY_RESX_PORT, DISPLAY_RESX_PIN); else gpio_set(DISPLAY_RESX_PORT, DISPLAY_RESX_PIN); } void on_display_set_command(bool value) { if (value) { // Trigger CS before command gpio_set(DISPLAY_CSX_PORT, DISPLAY_CSX_PIN); gpio_clear(DISPLAY_CSX_PORT, DISPLAY_CSX_PIN); gpio_clear(DISPLAY_DCX_PORT, DISPLAY_DCX_PIN); } else gpio_set(DISPLAY_DCX_PORT, DISPLAY_DCX_PIN); } void on_display_send(uint16_t value) { spi_send(SPI1, value); } void on_display_send16(uint16_t value) { spi_send(SPI1, (value >> 8) & 0xff); spi_send(SPI1, (value >> 0) & 0xff); } void init_display(mr_t *mr) { // Setup GPIO gpio_set(DISPLAY_RESX_PORT, DISPLAY_RESX_PIN); gpio_set(DISPLAY_CSX_PORT, DISPLAY_CSX_PIN); gpio_set_mode(DISPLAY_RESX_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, DISPLAY_RESX_PIN); gpio_set_mode(DISPLAY_CSX_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, DISPLAY_CSX_PIN); gpio_set_mode(DISPLAY_DCX_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, DISPLAY_DCX_PIN); gpio_set_mode(DISPLAY_SCL_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, DISPLAY_SCL_PIN); gpio_set_mode(DISPLAY_SDA_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, DISPLAY_SDA_PIN); // Setup SPI rcc_periph_clock_enable(RCC_SPI1); spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_2, SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_2, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); spi_enable_software_slave_management(SPI1); spi_set_nss_high(SPI1); spi_enable(SPI1); // Setup display mr_st7789_init(mr, DISPLAY_HEIGHT, DISPLAY_WIDTH, MR_DISPLAY_ROTATION_270, display_text_buffer, sizeof(display_text_buffer), on_display_sleep, on_display_set_reset, on_display_set_command, on_display_send, on_display_send16); mr_send_sequence(mr, display_init_sequence); } void set_display(mr_t *mr, bool value) { mr_st7789_set_display(mr, value); mr_st7789_set_sleep(mr, !value); } void update_display(mr_t *mr) { }