Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update main with v1.0/staging #61

Merged
merged 9 commits into from
Nov 8, 2024
Prev Previous commit
Next Next commit
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.
  • Loading branch information
AlexJones0 authored and marnovandermaas committed Nov 7, 2024
commit 6ff51671d2d84086f2728d330d5df8926a3ef9e8
57 changes: 25 additions & 32 deletions libraries/lcd.cc
Original file line number Diff line number Diff line change
@@ -10,50 +10,51 @@ using Cap = CHERI::Capability<T>;
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<volatile SonataSpi> 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<volatile SonataGPIO> gpio()
[[nodiscard, gnu::always_inline]] static Cap<volatile SonataLcdPwm> 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

2 changes: 1 addition & 1 deletion libraries/lcd.hh
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

#include <algorithm>
#include <cheri.hh>
#include <platform-gpio.hh>
#include <platform-pwm.hh>
#include <platform-spi.hh>
#include <thread.h>
#include <utility>