#include "display.h" #include "lib.h" #include "pixelstream.h" #include #include 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(left >> 8), static_cast(left & 0xFF), static_cast(right >> 8), static_cast(right & 0xFF) }; send_command(0x2A, params, 4); } { uint8_t params[4] = { static_cast(top >> 8), static_cast(top & 0xFF), static_cast(bottom >> 8), static_cast(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); }