aboutsummaryrefslogtreecommitdiff
#include <tft.h>
#include <hardware.h>
#include <zeta.h>

void
_delay_ms(uint8_t ms);

/*
 * Driver for the ILI9341 TFT Chip
 */

static inline void
tft_soft_reset(void)
{
    tft_ctrl = SWRESET;
}

static inline void
tft_enable_ext_cmd(void)
{
    tft_ctrl = SETEXTC;
    tft_data = 0xFF;
    tft_data = 0x83;
    tft_data = 0x57;
}

static inline void
tft_memory_access_ctrl(uint8_t bits)
{
    tft_ctrl = MADCTL;
    tft_data = bits;
}

static inline void
tft_sleep_out(void) {
    tft_ctrl = SLPOUT;
}

static inline void
tft_display_on(void)
{
    tft_ctrl = DISPON;
}

static inline void
tft_pixel_format(uint8_t dbi, uint8_t dpi)
{
    tft_ctrl = COLMOD;
    tft_data = (dpi << 4) | dbi;
}

static inline void
tft_set_rgb_interface(void)
{
    tft_ctrl = SETRGB;
    tft_data = 0x00;
    tft_data = 0x00;
    tft_data = 0x06;
    tft_data = 0x06;
}

static inline void
tft_set_col_addr(uint16_t start, uint16_t end)
{
	tft_ctrl = CASET;
	tft_data = start >> 8;
	tft_data = start & 0xFF;
	tft_data = end >> 8;
	tft_data = end & 0xFF;
}

static inline void
tft_set_page_addr(uint16_t start, uint16_t end)
{
	tft_ctrl = PASET;
	tft_data = start >> 8;
	tft_data = start & 0xFF;
	tft_data = end >> 8;
	tft_data = end & 0xFF;
}

void
tft_set_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
	tft_set_col_addr(x, x + w - 1);
	tft_set_page_addr(y, y + h - 1);
}

enum memory_access {
	// MY MX MV ML |  BGR SS X X
	MV = 0x20, // 1: landscape 0 <= x < 480; 0 <= y < 320
	MX = 0x40, // MV = 0: Invert X; MV = 1: Invert Y
	MY = 0x80, // MV = 0: Invert Y; MV = 1: Invert X
	ML = 0x10
};

void
clear_screen(void)
{
	DI;
	tft_set_col_addr(0, TFT_WIDTH - 1);
	tft_set_page_addr(0, TFT_HEIGHT - 1);

	tft_ctrl = RAMWR;
	for (u16 i = 0; i < TFT_HEIGHT; ++i) {
		for (u16 j = 0; j < TFT_WIDTH; ++j) {
			tft_data = 0x00;
			tft_data = 0x00;
			tft_data = 0x00;
		}
	}
	EI;
}

void
tft_init(void)
{
    _delay_ms(200);

    tft_soft_reset();
    tft_enable_ext_cmd();

    _delay_ms(250);

    tft_set_rgb_interface();

    tft_pixel_format(BIT18, BIT18);

	tft_memory_access_ctrl(MV | 0x0C);
    tft_sleep_out();

    _delay_ms(150);

    tft_display_on();

    _delay_ms(50);
	clear_screen();
}