InfiniTime/src/drivers/St7789.cpp

186 lines
4.4 KiB
C++
Raw Normal View History

2020-11-14 23:04:22 -05:00
#include "St7789.h"
2019-12-05 13:23:46 -05:00
#include <hal/nrf_gpio.h>
#include <libraries/delay/nrf_delay.h>
#include <nrfx_log.h>
2020-05-07 13:53:51 -04:00
#include "Spi.h"
2019-12-05 13:23:46 -05:00
using namespace Pinetime::Drivers;
St7789::St7789(Spi& spi, uint8_t pinDataCommand) : spi {spi}, pinDataCommand {pinDataCommand} {
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::Init() {
2020-05-07 13:53:51 -04:00
spi.Init();
2019-12-07 11:11:50 -05:00
nrf_gpio_cfg_output(pinDataCommand);
nrf_gpio_cfg_output(26);
nrf_gpio_pin_set(26);
HardwareReset();
2019-12-05 13:23:46 -05:00
SoftwareReset();
SleepOut();
ColMod();
MemoryDataAccessControl();
ColumnAddressSet();
RowAddressSet();
DisplayInversionOn();
NormalModeOn();
DisplayOn();
}
2019-12-07 11:11:50 -05:00
void St7789::WriteCommand(uint8_t cmd) {
nrf_gpio_pin_clear(pinDataCommand);
2019-12-05 13:23:46 -05:00
WriteSpi(&cmd, 1);
}
2019-12-07 11:11:50 -05:00
void St7789::WriteData(uint8_t data) {
nrf_gpio_pin_set(pinDataCommand);
2019-12-05 13:23:46 -05:00
WriteSpi(&data, 1);
}
void St7789::WriteSpi(const uint8_t* data, size_t size) {
spi.Write(data, size);
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::SoftwareReset() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::SoftwareReset));
nrf_delay_ms(150);
}
2019-12-07 11:11:50 -05:00
void St7789::SleepOut() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::SleepOut));
}
void St7789::SleepIn() {
WriteCommand(static_cast<uint8_t>(Commands::SleepIn));
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::ColMod() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::ColMod));
WriteData(0x55);
nrf_delay_ms(10);
}
2019-12-07 11:11:50 -05:00
void St7789::MemoryDataAccessControl() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::MemoryDataAccessControl));
WriteData(0x00);
}
2019-12-07 11:11:50 -05:00
void St7789::ColumnAddressSet() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::ColumnAddressSet));
WriteData(0x00);
WriteData(0x00);
WriteData(Width >> 8u);
WriteData(Width & 0xffu);
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::RowAddressSet() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::RowAddressSet));
WriteData(0x00);
WriteData(0x00);
WriteData(320u >> 8u);
WriteData(320u & 0xffu);
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::DisplayInversionOn() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::DisplayInversionOn));
nrf_delay_ms(10);
}
2019-12-07 11:11:50 -05:00
void St7789::NormalModeOn() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::NormalModeOn));
nrf_delay_ms(10);
}
2019-12-07 11:11:50 -05:00
void St7789::DisplayOn() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::DisplayOn));
}
2019-12-07 11:11:50 -05:00
void St7789::SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::ColumnAddressSet));
WriteData(x0 >> 8);
WriteData(x0 & 0xff);
WriteData(x1 >> 8);
WriteData(x1 & 0xff);
WriteCommand(static_cast<uint8_t>(Commands::RowAddressSet));
WriteData(y0 >> 8);
2019-12-05 13:23:46 -05:00
WriteData(y0 & 0xff);
WriteData(y1 >> 8);
WriteData(y1 & 0xff);
WriteToRam();
}
2019-12-07 11:11:50 -05:00
void St7789::WriteToRam() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::WriteToRam));
}
2019-12-07 11:11:50 -05:00
void St7789::DisplayOff() {
2019-12-05 13:23:46 -05:00
WriteCommand(static_cast<uint8_t>(Commands::DisplayOff));
nrf_delay_ms(500);
}
void St7789::VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines) {
WriteCommand(static_cast<uint8_t>(Commands::VerticalScrollDefinition));
WriteData(topFixedLines >> 8u);
WriteData(topFixedLines & 0x00ffu);
WriteData(scrollLines >> 8u);
WriteData(scrollLines & 0x00ffu);
WriteData(bottomFixedLines >> 8u);
WriteData(bottomFixedLines & 0x00ffu);
}
void St7789::VerticalScrollStartAddress(uint16_t line) {
verticalScrollingStartAddress = line;
WriteCommand(static_cast<uint8_t>(Commands::VerticalScrollStartAddress));
WriteData(line >> 8u);
WriteData(line & 0x00ffu);
}
2019-12-07 11:11:50 -05:00
void St7789::Uninit() {
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::DrawPixel(uint16_t x, uint16_t y, uint32_t color) {
if ((x < 0) || (x >= Width) || (y < 0) || (y >= Height))
return;
2019-12-05 13:23:46 -05:00
SetAddrWindow(x, y, x + 1, y + 1);
2019-12-05 13:23:46 -05:00
2019-12-07 11:11:50 -05:00
nrf_gpio_pin_set(pinDataCommand);
WriteSpi(reinterpret_cast<const uint8_t*>(&color), 2);
2019-12-05 13:23:46 -05:00
}
2019-12-07 11:11:50 -05:00
void St7789::DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, size_t size) {
2021-03-18 15:38:19 -04:00
SetAddrWindow(x, y, x + width - 1, y + height - 1);
nrf_gpio_pin_set(pinDataCommand);
WriteSpi(data, size);
}
void St7789::HardwareReset() {
nrf_gpio_pin_clear(26);
nrf_delay_ms(10);
nrf_gpio_pin_set(26);
}
void St7789::Sleep() {
SleepIn();
nrf_gpio_cfg_default(pinDataCommand);
NRF_LOG_INFO("[LCD] Sleep");
}
void St7789::Wakeup() {
nrf_gpio_cfg_output(pinDataCommand);
// TODO why do we need to reset the controller?
HardwareReset();
SoftwareReset();
SleepOut();
ColMod();
MemoryDataAccessControl();
ColumnAddressSet();
RowAddressSet();
DisplayInversionOn();
NormalModeOn();
VerticalScrollStartAddress(verticalScrollingStartAddress);
DisplayOn();
NRF_LOG_INFO("[LCD] Wakeup")
}