1 /**************************************************************************//**
2 *
3 * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date Author Notes
9 * 2020-1-16 Wayne First version
10 *
11 ******************************************************************************/
12
13 #include <rtconfig.h>
14
15 #if defined(NU_PKG_USING_ILI9341_EBI)
16
17 #include <lcd_ili9341.h>
18 #include "drv_pdma.h"
19
20 #define ILI9341_ADDR_CMD 0x0
21 #define ILI9341_ADDR_DATA 0x0030000
22
23 #define ili9341_reg_write(u32RegAddr) (*((volatile unsigned short *)(g_uint32_ili9341_base+(ILI9341_ADDR_CMD))) = (u32RegAddr))
24 #define ili9341_read_data() (*((volatile unsigned short *)(g_uint32_ili9341_base+(ILI9341_ADDR_DATA))))
25 #define ili9341_write_data(u32Data) (*((volatile unsigned short *)(g_uint32_ili9341_base+(ILI9341_ADDR_DATA))) = (u32Data))
26
27 static rt_uint32_t g_uint32_ili9341_base = 0;
28
ili9341_send_cmd(rt_uint8_t cmd)29 void ili9341_send_cmd(rt_uint8_t cmd)
30 {
31 CLR_RS;
32 ili9341_reg_write(cmd);
33 SET_RS;
34 }
35
ili9341_send_cmd_parameter(rt_uint8_t data)36 void ili9341_send_cmd_parameter(rt_uint8_t data)
37 {
38 ili9341_write_data(data);
39 }
40
ili9341_send_pixel_data(rt_uint16_t color)41 void ili9341_send_pixel_data(rt_uint16_t color)
42 {
43 ili9341_write_data(color);
44 }
45
ili9341_send_pixels(rt_uint16_t * pixels,int len)46 void ili9341_send_pixels(rt_uint16_t *pixels, int len)
47 {
48 int count = len / sizeof(rt_uint16_t);
49 if (count < 1024)
50 {
51 // CPU feed
52 int i = 0;
53 while (i < count)
54 {
55 ili9341_write_data(pixels[i]);
56 i++;
57 }
58 }
59 else
60 {
61 // PDMA-M2M feed
62 nu_pdma_mempush((void *)(g_uint32_ili9341_base + (ILI9341_ADDR_DATA)), (void *)pixels, 16, count);
63 }
64 }
65
ili9341_set_column(uint16_t StartCol,uint16_t EndCol)66 void ili9341_set_column(uint16_t StartCol, uint16_t EndCol)
67 {
68 ili9341_send_cmd(0x2A);
69 ili9341_write_data((StartCol >> 8) & 0xFF);
70 ili9341_write_data(StartCol & 0xFF);
71 ili9341_write_data((EndCol >> 8) & 0xFF);
72 ili9341_write_data(EndCol & 0xFF);
73 }
74
ili9341_set_page(uint16_t StartPage,uint16_t EndPage)75 void ili9341_set_page(uint16_t StartPage, uint16_t EndPage)
76 {
77 ili9341_send_cmd(0x2B);
78 ili9341_write_data((StartPage >> 8) & 0xFF);
79 ili9341_write_data(StartPage & 0xFF);
80 ili9341_write_data((EndPage >> 8) & 0xFF);
81 ili9341_write_data(EndPage & 0xFF);
82 }
83
ili9341_lcd_get_pixel(char * color,int x,int y)84 void ili9341_lcd_get_pixel(char *color, int x, int y)
85 {
86 rt_uint16_t red = 0;
87 rt_uint16_t green = 0;
88 rt_uint16_t blue = 0;
89
90 if (x >= XSIZE_PHYS || y >= YSIZE_PHYS)
91 {
92 *(rt_uint16_t *)color = 0;
93 return;
94 }
95
96 ili9341_set_column(x, x);
97 ili9341_set_page(y, y);
98 ili9341_send_cmd(0x2E);
99
100 ili9341_read_data(); // Dummy
101 red = ili9341_read_data(); // Red[4:0]@D15~D11
102 blue = ili9341_read_data(); // Blue[4:0]@D15~D11
103 green = ili9341_read_data(); // Green[5:0]@D15~D10
104
105 //BGR565: B in High byte, R in low byte
106 //*(rt_uint16_t *)color = (((blue >> 11) << 11) | ((green >> 10) << 5) | (red >> 11));
107
108 //RGB565: R in High byte, B in low byte
109 *(rt_uint16_t *)color = (((red >> 11) << 11) | ((green >> 10) << 5) | (blue >> 11));
110 }
111
rt_hw_lcd_ili9341_ebi_init(rt_uint32_t ili9341_base)112 rt_err_t rt_hw_lcd_ili9341_ebi_init(rt_uint32_t ili9341_base)
113 {
114 g_uint32_ili9341_base = ili9341_base;
115 return RT_EOK;
116 }
117
118 #endif /* if defined(NU_PKG_USING_ILI9341_EBI) */
119