aboutsummaryrefslogtreecommitdiff
path: root/src/tft.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tft.c')
-rw-r--r--src/tft.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/tft.c b/src/tft.c
new file mode 100644
index 0000000..d0c7d8f
--- /dev/null
+++ b/src/tft.c
@@ -0,0 +1,138 @@
+#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();
+}