144 lines
3.1 KiB
C++
144 lines
3.1 KiB
C++
#include "display.h"
|
|
|
|
#include "lib.h"
|
|
#include "pixelstream.h"
|
|
|
|
#include <hardware/spi.h>
|
|
#include <pico/stdlib.h>
|
|
|
|
using namespace lib;
|
|
|
|
Display::Display(uint8_t sck, uint8_t tx, uint8_t cs, uint8_t dc,
|
|
int baudrate) :
|
|
sck(sck),
|
|
tx(tx),
|
|
cs(cs),
|
|
dc(dc)
|
|
{
|
|
spi_inst_t* sck_spi = detail::get_spi_instance(sck);
|
|
spi_inst_t* tx_spi = detail::get_spi_instance(tx);
|
|
|
|
hard_assert(sck_spi == tx_spi, "Invalid configuration");
|
|
spi = sck_spi;
|
|
|
|
gpio_set_function(sck, GPIO_FUNC_SPI);
|
|
gpio_set_function(tx, GPIO_FUNC_SPI);
|
|
|
|
// chip select and data/command controlled manually
|
|
gpio_set_function(cs, GPIO_FUNC_SIO);
|
|
gpio_set_dir(cs, GPIO_OUT);
|
|
gpio_set_function(dc, GPIO_FUNC_SIO);
|
|
gpio_set_dir(dc, GPIO_OUT);
|
|
|
|
spi_init(spi, baudrate);
|
|
|
|
// initialize display command sequence
|
|
// -----------------------------------
|
|
// reset device
|
|
send_command(0x01);
|
|
sleep_ms(150);
|
|
|
|
// take device out of sleep mode
|
|
send_command(0x11);
|
|
sleep_ms(10);
|
|
|
|
// set display format to 18-bit color
|
|
send_command(0x3A, 0x66);
|
|
sleep_ms(10);
|
|
|
|
set_update_area(0, 0, 240, 320);
|
|
|
|
// set memory addressing mode
|
|
send_command(0x36, 0b11000000);
|
|
|
|
// turn on display inversion
|
|
send_command(0x21);
|
|
|
|
// set display to normal mode
|
|
send_command(0x13);
|
|
sleep_ms(10);
|
|
|
|
// set display brightness
|
|
send_command(0x51, 0x00);
|
|
|
|
// clear display to black
|
|
{
|
|
auto p = pixels();
|
|
for (int i = 0; i < 320 * 240; i++)
|
|
{
|
|
p.write(0, 0, 0);
|
|
}
|
|
}
|
|
|
|
// turn on display
|
|
send_command(0x29);
|
|
sleep_ms(10);
|
|
}
|
|
|
|
void Display::set_update_area(uint16_t left, uint16_t top, uint16_t width,
|
|
uint16_t height)
|
|
{
|
|
const uint16_t right = left + width;
|
|
const uint16_t bottom = top + height;
|
|
{
|
|
uint8_t params[4]
|
|
= { static_cast<uint8_t>(left >> 8), static_cast<uint8_t>(left & 0xFF),
|
|
static_cast<uint8_t>(right >> 8),
|
|
static_cast<uint8_t>(right & 0xFF) };
|
|
|
|
send_command(0x2A, params, 4);
|
|
}
|
|
{
|
|
uint8_t params[4]
|
|
= { static_cast<uint8_t>(top >> 8), static_cast<uint8_t>(top & 0xFF),
|
|
static_cast<uint8_t>(bottom >> 8),
|
|
static_cast<uint8_t>(bottom & 0xFF) };
|
|
|
|
send_command(0x2B, params, 4);
|
|
}
|
|
}
|
|
|
|
PixelStream Display::pixels() { return PixelStream(*this); }
|
|
|
|
void Display::send_command(uint8_t command)
|
|
{
|
|
send_command(command, nullptr, 0);
|
|
}
|
|
|
|
void Display::send_command(uint8_t command, uint8_t param)
|
|
{
|
|
send_command(command, ¶m, 1);
|
|
}
|
|
|
|
void Display::send_command(uint8_t command, const uint8_t* params,
|
|
size_t param_count)
|
|
{
|
|
gpio_put(cs, false);
|
|
|
|
gpio_put(dc, false);
|
|
spi_write_blocking(spi, &command, 1);
|
|
|
|
if (param_count > 0)
|
|
{
|
|
// parameters are sent via data mode
|
|
gpio_put(dc, true);
|
|
spi_write_blocking(spi, params, param_count);
|
|
}
|
|
|
|
gpio_put(cs, true);
|
|
}
|
|
|
|
void Display::send_command_and_begin_data_stream(uint8_t command)
|
|
{
|
|
gpio_put(cs, false);
|
|
|
|
gpio_put(dc, false);
|
|
spi_write_blocking(spi, &command, 1);
|
|
|
|
gpio_put(dc, true);
|
|
}
|
|
|
|
void Display::send_data(uint8_t data) { spi_write_blocking(spi, &data, 1); }
|
|
|
|
void Display::end_data_stream() { gpio_put(cs, true); }
|