#include <tft.h>
#include <hardware.h>
#include <zeta.h>
void
_delay_ms(u8 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(u8 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(u8 dbi, u8 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(u16 start, u16 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(u16 start, u16 end)
{
tft_ctrl = PASET;
tft_data = start >> 8;
tft_data = start & 0xFF;
tft_data = end >> 8;
tft_data = end & 0xFF;
}
void
tft_set_area(u16 x, u16 y, u16 w, u16 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
};
extern u8 blink;
void
clear_screen(void)
{
DI;
u8 tmp = blink;
blink = 0;
EI;
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;
}
}
DI;
blink = tmp;
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(BIT16, BIT16);
tft_memory_access_ctrl(MV | 0x0C);
tft_sleep_out();
_delay_ms(150);
tft_display_on();
_delay_ms(50);
clear_screen();
}