From 755ccacb03a071f2da5c7c2eac4bfbb6b241121c Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Wed, 30 Oct 2024 12:10:01 +0000 Subject: [PATCH] Update LCD library to use LCD CS and PWM instead of GPIO In the latest 1.0 hardware, the LCD has been changed to use a chip select (for its CS, DC and RST pins) and to use a PWM for its backlight. This commit updates the LCD library/driver to appropriately make use of the SPI driver intsead of the GPIO as it was using before, and to use the PWM for the LCD's backlight. The PWM is always set to 100, and for now the driver simply replaces existing functionality - there is no way to modify the PWM from the driver. --- libraries/lcd.cc | 57 +++++++++++++++++++++--------------------------- libraries/lcd.hh | 2 +- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/libraries/lcd.cc b/libraries/lcd.cc index 8582c3b..fce0b74 100644 --- a/libraries/lcd.cc +++ b/libraries/lcd.cc @@ -10,50 +10,51 @@ using Cap = CHERI::Capability; using namespace sonata::lcd; /** - * Helper. Returns a pointer to the SPI device. + * Helper. Returns a pointer to the SPI device. */ [[nodiscard, gnu::always_inline]] static Cap spi() { - return MMIO_CAPABILITY(SonataSpi, spi1); + return MMIO_CAPABILITY(SonataSpi, spi_lcd); } /** - * Helper. Returns a pointer to the GPIO device. + * Helper. Returns a pointer to the LCD's backlight PWM device. */ -[[nodiscard, gnu::always_inline]] static Cap gpio() +[[nodiscard, gnu::always_inline]] static Cap pwm_bl() { - return MMIO_CAPABILITY(SonataGPIO, gpio); + return MMIO_CAPABILITY(SonataLcdPwm, pwm_lcd); } -static constexpr uint32_t LcdCsPin = 0; -static constexpr uint32_t LcdRstPin = 1; -static constexpr uint32_t LcdDcPin = 2; -static constexpr uint32_t LcdBlPin = 3; +static constexpr uint8_t LcdCsPin = 0; +static constexpr uint8_t LcdDcPin = 1; +static constexpr uint8_t LcdRstPin = 2; -static inline void set_gpio_output_bit(uint32_t bit, bool value) +/** + * Sets the value of a specific Chip Select of SPI1. These Chip Select + * lines are used to control the LCD's Chip Select, Reset, DC, and + * Backlight, in place of e.g. GPIO pins. + */ +void set_chip_select(uint8_t chipSelect, bool value) { - uint32_t output = gpio()->output; - output &= ~(1 << bit); - output |= value << bit; - gpio()->output = output; + const uint32_t CsBit = (1u << chipSelect); + spi()->cs = value ? (spi()->cs | CsBit) : (spi()->cs & ~CsBit); } - namespace sonata::lcd::internal { void __cheri_libcall lcd_init(LCD_Interface *lcdIntf, St7735Context *ctx) { // Set the initial state of the LCD control pins. - set_gpio_output_bit(LcdDcPin, false); - set_gpio_output_bit(LcdBlPin, true); - set_gpio_output_bit(LcdCsPin, false); + set_chip_select(LcdDcPin, false); + pwm_bl()->output_set(/*index =*/0, /*period=*/1, /*duty_cycle=*/255); + set_chip_select(LcdCsPin, false); // Initialise SPI driver. spi()->init(false, false, true, false); // Reset LCD. - set_gpio_output_bit(LcdRstPin, false); + set_chip_select(LcdRstPin, false); thread_millisecond_wait(150); - set_gpio_output_bit(LcdRstPin, true); + set_chip_select(LcdRstPin, true); // Initialise LCD driverr. lcdIntf->handle = nullptr; @@ -64,16 +65,8 @@ namespace sonata::lcd::internal }; lcdIntf->gpio_write = [](void *handle, bool csHigh, bool dcHigh) -> uint32_t { - if (csHigh) - { - spi()->cs = 1; - } - else - { - spi()->cs = 0; - } - - set_gpio_output_bit(LcdDcPin, dcHigh); + set_chip_select(LcdCsPin, csHigh); + set_chip_select(LcdDcPin, dcHigh); return 0; }; lcdIntf->timer_delay = [](uint32_t ms) { thread_millisecond_wait(ms); }; @@ -88,9 +81,9 @@ namespace sonata::lcd::internal { lcd_st7735_clean(ctx); // Hold LCD in reset. - set_gpio_output_bit(LcdRstPin, false); + set_chip_select(LcdRstPin, false); // Turn off backlight. - set_gpio_output_bit(LcdBlPin, false); + pwm_bl()->output_set(/*index =*/0, /*period=*/0, /*duty_cycle=*/0); } } // namespace sonata::lcd::internal diff --git a/libraries/lcd.hh b/libraries/lcd.hh index e185ca0..6256006 100644 --- a/libraries/lcd.hh +++ b/libraries/lcd.hh @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include #include