1
+ /*
2
+ This file is part of IngenicHAL.
3
+ Copyright (C) 2022 Reimu NotMoe <[email protected] >
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as
7
+ published by the Free Software Foundation, either version 3 of the
8
+ License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ #include <ingenic-hal.h>
20
+
21
+ volatile XHAL_GPIO_TypeDef * xgpioa , * xgpiob , * xgpioc , * xgpiod ;
22
+
23
+ // Use this if you have a 16-bit RGB LCD is connected to PB<15:0>
24
+ // ffmpeg -vcodec png -i logo.png -vcodec rawvideo -f rawvideo -pix_fmt bgr565le logo.raw
25
+ #define LOGO_BGR565LE
26
+
27
+ // Use this if you have a 24-bit RGB LCD is connected to PB<24:0>, or a 16-bit RGB LCD with each color aligned to MSB
28
+ // ffmpeg -vcodec png -i logo.png -vcodec rawvideo -f rawvideo -pix_fmt bgra logo.raw
29
+ //#define LOGO_BGRA8888
30
+
31
+ // Snatch GPIO back from Linux
32
+ //#define ENABLE_GPIO_SNATCH
33
+
34
+ #if defined(LOGO_BGR565LE )
35
+ #define logo_pixel_t uint16_t
36
+ #define lcd_DATA lcd_DATA16
37
+ #elif defined(LOGO_BGRA8888 )
38
+ #define logo_pixel_t uint32_t
39
+ #define lcd_DATA lcd_DATA24
40
+ #endif
41
+
42
+ // The logo file should be placed at 127MiB of DRAM
43
+ // The mini core has no MMU, so all addresses are in physical
44
+ volatile logo_pixel_t * logo = (void * )0x07F00000 ;
45
+ uint32_t logo_pos = 0 ;
46
+
47
+ logo_pixel_t lcd_Color () {
48
+ logo_pixel_t ret = logo [logo_pos ];
49
+ logo_pos ++ ;
50
+
51
+ return ret ;
52
+ }
53
+
54
+ int lcd_gpio_changed () {
55
+ if (xgpiob -> PAT1 & (1 << 27 )) {
56
+ return 1 ;
57
+ }
58
+
59
+ return 0 ;
60
+ }
61
+
62
+ void lcd_gpio_init (void ) {
63
+ int i ;
64
+ for (i = 0 ; i <=27 ; i ++ ) {
65
+ XHAL_GPIO_SetAsGPIO (xgpiob , i , 0 );
66
+ }
67
+ }
68
+
69
+ void lcd_DATA16 (uint16_t v ) {
70
+ xgpiob -> PAT0C = 0xffff ;
71
+ xgpiob -> PAT0S = v ;
72
+ }
73
+
74
+ void lcd_DATA24 (uint32_t v ) {
75
+ xgpiob -> PAT0C = 0xffffff ;
76
+ xgpiob -> PAT0S = v & 0xffffff ;
77
+ }
78
+
79
+ void lcd_DE (int v ) {
80
+ XHAL_GPIO_WritePin (xgpiob , 27 , v );
81
+ }
82
+
83
+ void lcd_PCLK (int v ) {
84
+ XHAL_GPIO_WritePin (xgpiob , 24 , v );
85
+ }
86
+
87
+ void lcd_VSYNC (int v ) {
88
+ XHAL_GPIO_WritePin (xgpiob , 25 , v );
89
+ }
90
+
91
+ void lcd_HSYNC (int v ) {
92
+ XHAL_GPIO_WritePin (xgpiob , 26 , v );
93
+ }
94
+
95
+ void lcd_init () {
96
+ lcd_gpio_init ();
97
+
98
+ lcd_VSYNC (1 );
99
+ lcd_HSYNC (1 );
100
+ lcd_DE (0 );
101
+ lcd_PCLK (0 );
102
+ }
103
+
104
+ uint32_t resX = 480 , resY = 272 ;
105
+
106
+ uint32_t Tvpw = 1 ; /* VSYNC Width */
107
+ uint32_t Tvbp = 11 ; /* VSYNC Back Porch */
108
+ uint32_t Tvfp = 13 ; /* VSYNC Front Porch */
109
+
110
+ uint32_t Thpw = 8 ; /* HSYNC Width */
111
+ uint32_t Thbp = 35 ; /* HSYNC Back Porch */
112
+ uint32_t Thfp = 40 ; /* HSYNC Front Porch */
113
+
114
+ //uint32_t resX = 800, resY = 480;
115
+ //
116
+ //uint32_t Tvpw = 3; /* VSYNC Width */
117
+ //uint32_t Tvbp = 32; /* VSYNC Back Porch */
118
+ //uint32_t Tvfp = 13; /* VSYNC Front Porch */
119
+ //
120
+ //uint32_t Thpw = 48; /* HSYNC Width */
121
+ //uint32_t Thbp = 88; /* HSYNC Back Porch */
122
+ //uint32_t Thfp = 40; /* HSYNC Front Porch */
123
+
124
+ void lcd_flip_PCLK () {
125
+ lcd_PCLK (1 );
126
+ lcd_PCLK (0 );
127
+ }
128
+
129
+ void lcd_BlastLine (int DE_needs_change ) {
130
+ uint32_t i ;
131
+
132
+ lcd_HSYNC (0 );
133
+ for (i = 0 ; i < Thpw ; i ++ ) {
134
+ lcd_flip_PCLK ();
135
+ }
136
+
137
+ lcd_HSYNC (1 );
138
+ for (i = 0 ; i < Thbp ; i ++ ) {
139
+ lcd_flip_PCLK ();
140
+ }
141
+
142
+ if (DE_needs_change )
143
+ lcd_DE (1 );
144
+
145
+ for (i = 0 ; i < resX ; i ++ ) {
146
+ if (DE_needs_change ) {
147
+ lcd_DATA (lcd_Color ());
148
+ }
149
+ lcd_flip_PCLK ();
150
+ }
151
+
152
+ if (DE_needs_change )
153
+ lcd_DE (0 );
154
+
155
+ for (i = 0 ; i < Thfp ; i ++ ) {
156
+ lcd_flip_PCLK ();
157
+ }
158
+
159
+ };
160
+
161
+ void lcd_BlastScreen () {
162
+ uint32_t i ;
163
+
164
+
165
+ lcd_VSYNC (0 );
166
+ for (i = 0 ; i < Tvpw ; i ++ ) {
167
+ lcd_BlastLine (0 );
168
+ }
169
+
170
+ lcd_VSYNC (1 );
171
+ for (i = 0 ; i < Tvbp ; i ++ ) {
172
+ lcd_BlastLine (0 );
173
+ }
174
+
175
+ for (i = 0 ; i < resY ; i ++ ) {
176
+ lcd_BlastLine (1 );
177
+ }
178
+
179
+ for (i = 0 ; i < Tvfp ; i ++ ) {
180
+ lcd_BlastLine (0 );
181
+ }
182
+
183
+ }
184
+
185
+ int main () {
186
+ xgpioa = (volatile void * )(XHAL_PHYSADDR_GPIO + XHAL_REGWIDTH_GPIO_PORT * 0 );
187
+ xgpiob = (volatile void * )(XHAL_PHYSADDR_GPIO + XHAL_REGWIDTH_GPIO_PORT * 1 );
188
+ xgpioc = (volatile void * )(XHAL_PHYSADDR_GPIO + XHAL_REGWIDTH_GPIO_PORT * 2 );
189
+ xgpiod = (volatile void * )(XHAL_PHYSADDR_GPIO + XHAL_REGWIDTH_GPIO_PORT * 3 );
190
+
191
+ lcd_init ();
192
+
193
+ while (1 ) {
194
+ lcd_BlastScreen ();
195
+
196
+ #ifdef ENABLE_GPIO_SNATCH
197
+ if (lcd_gpio_changed ()) {
198
+ lcd_gpio_init ();
199
+ }
200
+ #endif
201
+
202
+ logo_pos = 0 ;
203
+ }
204
+ }
0 commit comments