2019-12-05 13:23:46 -05:00
|
|
|
#include <hal/nrf_gpio.h>
|
|
|
|
#include <libraries/delay/nrf_delay.h>
|
2019-12-07 11:11:50 -05:00
|
|
|
#include "St7789.h"
|
|
|
|
#include "SpiMaster.h"
|
2019-12-05 13:23:46 -05:00
|
|
|
|
|
|
|
using namespace Pinetime::Drivers;
|
|
|
|
|
2019-12-07 11:11:50 -05:00
|
|
|
St7789::St7789(SpiMaster &spiMaster, uint8_t pinDataCommand) : spi{spiMaster}, pinDataCommand{pinDataCommand} {
|
2019-12-05 13:23:46 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-12-07 11:11:50 -05:00
|
|
|
|
|
|
|
void St7789::Init() {
|
|
|
|
nrf_gpio_cfg_output(pinDataCommand);
|
2020-01-02 08:47:59 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-07 11:11:50 -05:00
|
|
|
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));
|
2020-01-17 16:16:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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(Height >> 8);
|
|
|
|
WriteData(Height & 0xff);
|
|
|
|
}
|
|
|
|
|
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(Width >> 8);
|
|
|
|
WriteData(Width & 0xff);
|
|
|
|
}
|
|
|
|
|
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::FillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) {
|
2019-12-07 13:15:33 -05:00
|
|
|
BeginDrawBuffer(x, y, width, height);
|
2019-12-05 13:23:46 -05:00
|
|
|
|
|
|
|
uint32_t c = color + (color << 16);
|
2019-12-07 13:15:33 -05:00
|
|
|
uint8_t w = width/2;
|
2019-12-05 13:23:46 -05:00
|
|
|
|
|
|
|
for(y=height+ST7789_ROW_OFFSET; y>ST7789_ROW_OFFSET; y--) {
|
2019-12-07 13:15:33 -05:00
|
|
|
for(x=w; x>0; x--) {
|
|
|
|
NextDrawBuffer(reinterpret_cast<const uint8_t *>(&c), 4);
|
2019-12-05 13:23:46 -05:00
|
|
|
}
|
|
|
|
}
|
2019-12-07 13:15:33 -05:00
|
|
|
EndDrawBuffer();
|
2019-12-05 13:23:46 -05:00
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
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) {
|
2019-12-05 13:23:46 -05:00
|
|
|
if((x < 0) ||(x >= Width) || (y < 0) || (y >= Height)) return;
|
|
|
|
|
|
|
|
SetAddrWindow(x, y, x+1, y+1);
|
|
|
|
|
2019-12-07 11:11:50 -05:00
|
|
|
nrf_gpio_pin_set(pinDataCommand);
|
2019-12-05 13:23:46 -05:00
|
|
|
WriteSpi(reinterpret_cast<const uint8_t *>(&color), 2);
|
|
|
|
}
|
2019-12-07 11:11:50 -05:00
|
|
|
|
2019-12-07 13:15:33 -05:00
|
|
|
void St7789::BeginDrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height) {
|
|
|
|
if((x >= Width) || (y >= Height)) return;
|
|
|
|
if((x + width - 1) >= Width) width = Width - x;
|
|
|
|
if((y + height - 1) >= Height) height = Height - y;
|
|
|
|
|
|
|
|
SetAddrWindow(0+x, ST7789_ROW_OFFSET+y, x+width-1, y+height-1);
|
|
|
|
nrf_gpio_pin_set(pinDataCommand);
|
|
|
|
}
|
|
|
|
|
|
|
|
void St7789::EndDrawBuffer() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void St7789::NextDrawBuffer(const uint8_t *data, size_t size) {
|
|
|
|
spi.Write(data, size);
|
|
|
|
}
|
|
|
|
|
2020-01-02 08:47:59 -05:00
|
|
|
void St7789::HardwareReset() {
|
|
|
|
nrf_gpio_pin_clear(26);
|
2020-01-17 16:16:45 -05:00
|
|
|
nrf_delay_ms(10);
|
2020-01-02 08:47:59 -05:00
|
|
|
nrf_gpio_pin_set(26);
|
2020-01-17 16:16:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void St7789::Sleep() {
|
|
|
|
SleepIn();
|
|
|
|
nrf_gpio_cfg_default(pinDataCommand);
|
|
|
|
spi.Sleep();
|
|
|
|
}
|
2020-01-02 08:47:59 -05:00
|
|
|
|
2020-01-17 16:16:45 -05:00
|
|
|
void St7789::Wakeup() {
|
|
|
|
spi.Wakeup();
|
|
|
|
|
|
|
|
nrf_gpio_cfg_output(pinDataCommand);
|
|
|
|
// TODO why do we need to reset the controller?
|
|
|
|
SoftwareReset();
|
|
|
|
SleepOut();
|
|
|
|
ColMod();
|
|
|
|
MemoryDataAccessControl();
|
|
|
|
ColumnAddressSet();
|
|
|
|
RowAddressSet();
|
|
|
|
DisplayInversionOn();
|
|
|
|
NormalModeOn();
|
|
|
|
DisplayOn();
|
2020-01-02 08:47:59 -05:00
|
|
|
}
|
|
|
|
|
2019-12-07 13:15:33 -05:00
|
|
|
|