Files
arduino/libraries/mcu-renderer/examples/gammacalibration-stm32-st7789/src/display.c
2025-10-12 09:13:56 +02:00

155 lines
3.8 KiB
C

/*
* MCU renderer
* ST7789 on STM32
*
* (C) 2023-2024 Gissio
*
* License: MIT
*/
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/spi.h>
#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)
{
}