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