Mercurial > ~darius > hgwebdir.cgi > stm32test
comparison lcd.c @ 9:be0a1ac64d97
- Add ellipse drawing.
- Factor out stripe drawing to a function.
- Rename LCD functions to match other code.
- Add filled circles.
- Rotate coords for landsacpe.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sun, 05 Feb 2012 16:41:42 +1030 |
parents | 58d76cf522ff |
children |
comparison
equal
deleted
inserted
replaced
8:58d76cf522ff | 9:be0a1ac64d97 |
---|---|
55 40 D15 PD10/FSMC_D15 | 55 40 D15 PD10/FSMC_D15 |
56 */ | 56 */ |
57 | 57 |
58 #include <stdio.h> | 58 #include <stdio.h> |
59 #include <stdint.h> | 59 #include <stdint.h> |
60 #include <stdlib.h> | |
61 #include <ctype.h> | |
60 #include "stm32f10x.h" | 62 #include "stm32f10x.h" |
61 #include "lcd.h" | 63 #include "lcd.h" |
62 #include "delay.h" | 64 #include "delay.h" |
63 | 65 |
64 #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ | 66 #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ |
65 #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ | 67 #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ |
66 | 68 |
67 void | 69 #define COLINCVAL 7968 /* 255.0 / 320.0 * 10000 */ |
68 lcd_wr_reg(uint16_t index, uint16_t val) { | 70 |
71 void colinc(uint16_t *mag, uint16_t *err, uint16_t amt, uint16_t max) { | |
72 *err += amt; | |
73 if (*err > max) { | |
74 (*mag) = (*mag) + 1; | |
75 (*err) = (*err) - max; | |
76 } | |
77 } | |
78 | |
79 void | |
80 lcd_writereg(uint16_t index, uint16_t val) { | |
69 *(__IO uint16_t *)(Bank1_LCD_C) = index; | 81 *(__IO uint16_t *)(Bank1_LCD_C) = index; |
70 *(__IO uint16_t *)(Bank1_LCD_D) = val; | 82 *(__IO uint16_t *)(Bank1_LCD_D) = val; |
71 } | 83 } |
72 | 84 |
73 uint16_t | 85 uint16_t |
74 lcd_rd_reg(uint16_t index) { | 86 lcd_readreg(uint16_t index) { |
75 *(__IO uint16_t *)(Bank1_LCD_C) = index; | 87 *(__IO uint16_t *)(Bank1_LCD_C) = index; |
76 return(*(__IO uint16_t *)(Bank1_LCD_D)); | 88 return(*(__IO uint16_t *)(Bank1_LCD_D)); |
77 } | 89 } |
78 | 90 |
79 uint16_t | 91 uint16_t |
80 lcd_rd_data(int first) { | 92 lcd_readdata(int first) { |
81 uint16_t a = 0; | 93 uint16_t a = 0; |
82 if (first) | 94 if (first) |
83 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Dummy */ | 95 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Dummy */ |
84 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Read */ | 96 a = *(__IO uint16_t *) (Bank1_LCD_D); /* Read */ |
85 | 97 |
86 return (a); | 98 return (a); |
87 } | 99 } |
88 | 100 |
89 void | 101 void |
90 lcd_wr_startdata(uint16_t x, uint16_t y) { | 102 lcd_startgram(uint16_t x, uint16_t y) { |
91 lcd_wr_reg(0x20, x); | 103 lcd_writereg(0x20, x); |
92 lcd_wr_reg(0x21, y); | 104 lcd_writereg(0x21, y); |
93 *(__IO uint16_t *)(Bank1_LCD_C) = 0x22; /* Start GRAM write */ | 105 *(__IO uint16_t *)(Bank1_LCD_C) = 0x22; /* Start GRAM write */ |
94 } | 106 } |
95 | 107 |
96 void | 108 void |
97 lcd_wr_data(uint16_t val) { | 109 lcd_writedata(uint16_t val) { |
98 *(__IO uint16_t *)(Bank1_LCD_D) = val; | 110 *(__IO uint16_t *)(Bank1_LCD_D) = val; |
99 } | 111 } |
100 | 112 |
101 void | 113 void |
102 lcd_setpwm(uint16_t val) { | 114 lcd_setpwm(uint16_t val) { |
112 | 124 |
113 } | 125 } |
114 | 126 |
115 void | 127 void |
116 lcd_init(void) { | 128 lcd_init(void) { |
117 uint16_t id; | 129 uint16_t id, x, y; |
118 | 130 |
119 /* Initialise LCD panel */ | 131 /* Initialise LCD panel */ |
120 | 132 |
121 /* Pull reset pin low */ | 133 /* Pull reset pin low */ |
122 delay(1); | 134 delay(1); |
123 GPIO_ResetBits(GPIOE, GPIO_Pin_1); | 135 GPIO_ResetBits(GPIOE, GPIO_Pin_1); |
124 delay(10); | 136 delay(10); |
125 GPIO_SetBits(GPIOE, GPIO_Pin_1); | 137 GPIO_SetBits(GPIOE, GPIO_Pin_1); |
126 delay(50); | 138 delay(50); |
127 | 139 |
128 id = lcd_rd_reg(0x00); | 140 id = lcd_readreg(0x00); |
129 if (id != 0x9325) { | 141 if (id != 0x9325) { |
130 printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); | 142 printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); |
131 return; | 143 return; |
132 } | 144 } |
133 printf("LCD ID matches\r\n"); | 145 printf("LCD ID matches\r\n"); |
134 | 146 |
135 lcd_wr_reg(0x00e3, 0x3008); /* Set internal timing (not documented) */ | 147 lcd_writereg(0x00e3, 0x3008); /* Set internal timing (not documented) */ |
136 lcd_wr_reg(0x00e7, 0x0012); /* Set internal timing (not documented) */ | 148 lcd_writereg(0x00e7, 0x0012); /* Set internal timing (not documented) */ |
137 lcd_wr_reg(0x00ef, 0x1231); /* Set internal timing (not documented) */ | 149 lcd_writereg(0x00ef, 0x1231); /* Set internal timing (not documented) */ |
138 lcd_wr_reg(0x0000, 0x0001); /* Start Oscillation */ | 150 lcd_writereg(0x0000, 0x0001); /* Start Oscillation */ |
139 delay(50); | 151 delay(50); |
140 lcd_wr_reg(0x0001, 0x0100); /* set SS (S720 -> S1) */ | 152 lcd_writereg(0x0001, 0x0100); /* set SS (S720 -> S1) */ |
141 lcd_wr_reg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ | 153 lcd_writereg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ |
142 lcd_wr_reg(0x0004, 0x0000); /* no resizing */ | 154 lcd_writereg(0x0004, 0x0000); /* no resizing */ |
143 lcd_wr_reg(0x0008, 0x0202); /* set the back porch and front porch (2 lines each) */ | 155 lcd_writereg(0x0008, 0x0202); /* set the back porch and front porch (2 lines each) */ |
144 lcd_wr_reg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ | 156 lcd_writereg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ |
145 lcd_wr_reg(0x000a, 0x0000); /* FMARK function */ | 157 lcd_writereg(0x000a, 0x0000); /* FMARK function */ |
146 | 158 |
147 lcd_wr_reg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ | 159 lcd_writereg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ |
148 lcd_wr_reg(0x000d, 0x0000); /* Frame marker Position */ | 160 lcd_writereg(0x000d, 0x0000); /* Frame marker Position */ |
149 lcd_wr_reg(0x000f, 0x0000); /* RGB interface polarity */ | 161 lcd_writereg(0x000f, 0x0000); /* RGB interface polarity */ |
150 | 162 |
151 /* Power On sequence */ | 163 /* Power On sequence */ |
152 lcd_wr_reg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | 164 lcd_writereg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ |
153 lcd_wr_reg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ | 165 lcd_writereg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ |
154 lcd_wr_reg(0x0012, 0x0000); /* VREG1OUT voltage */ | 166 lcd_writereg(0x0012, 0x0000); /* VREG1OUT voltage */ |
155 lcd_wr_reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ | 167 lcd_writereg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ |
156 delay(200); /* Dis-charge capacitor power voltage */ | 168 delay(200); /* Dis-charge capacitor power voltage */ |
157 lcd_wr_reg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ | 169 lcd_writereg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ |
158 lcd_wr_reg(0x0011, 0x0227); /* R11h = 0x0221 at VCI = 3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ | 170 lcd_writereg(0x0011, 0x0227); /* R11h = 0x0221 at VCI = 3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ |
159 delay(50); /* delay 50ms */ | 171 delay(50); /* delay 50ms */ |
160 lcd_wr_reg(0x0012, 0x001c); /* External reference voltage= Vci; */ | 172 lcd_writereg(0x0012, 0x001c); /* External reference voltage= Vci; */ |
161 delay(50); /* delay 50ms */ | 173 delay(50); /* delay 50ms */ |
162 lcd_wr_reg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ | 174 lcd_writereg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ |
163 lcd_wr_reg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ | 175 lcd_writereg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ |
164 lcd_wr_reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ | 176 lcd_writereg(0x002b, 0x000d); /* Frame Rate = 91Hz */ |
165 delay(50); /* delay 50ms */ | 177 delay(50); /* delay 50ms */ |
166 | 178 |
167 /* Set GRAM area */ | 179 /* Set GRAM area */ |
168 lcd_wr_reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ | 180 lcd_writereg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ |
169 lcd_wr_reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ | 181 lcd_writereg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ |
170 lcd_wr_reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ | 182 lcd_writereg(0x0052, 0x0000); /* Vertical GRAM Start Address */ |
171 lcd_wr_reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ | 183 lcd_writereg(0x0053, 0x013f); /* Vertical GRAM Start Address */ |
172 | 184 |
173 lcd_wr_reg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ | 185 lcd_writereg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ |
174 lcd_wr_reg(0x0061, 0x0003); /* VLE & REV */ | 186 lcd_writereg(0x0061, 0x0003); /* VLE & REV */ |
175 lcd_wr_reg(0x006a, 0x0000); /* set scrolling line */ | 187 lcd_writereg(0x006a, 0x0000); /* set scrolling line */ |
176 | 188 |
177 /* Partial Display Control */ | 189 /* Partial Display Control */ |
178 lcd_wr_reg(0x0080, 0x0000); /* Image 1 */ | 190 lcd_writereg(0x0080, 0x0000); /* Image 1 */ |
179 lcd_wr_reg(0x0081, 0x0000); | 191 lcd_writereg(0x0081, 0x0000); |
180 lcd_wr_reg(0x0082, 0x0000); | 192 lcd_writereg(0x0082, 0x0000); |
181 lcd_wr_reg(0x0083, 0x0000); /* Image 2 */ | 193 lcd_writereg(0x0083, 0x0000); /* Image 2 */ |
182 lcd_wr_reg(0x0084, 0x0000); | 194 lcd_writereg(0x0084, 0x0000); |
183 lcd_wr_reg(0x0085, 0x0000); | 195 lcd_writereg(0x0085, 0x0000); |
184 | 196 |
185 /* Panel Control */ | 197 /* Panel Control */ |
186 lcd_wr_reg(0x0090, 0x0010); | 198 lcd_writereg(0x0090, 0x0010); |
187 lcd_wr_reg(0x0092, 0x0000); | 199 lcd_writereg(0x0092, 0x0000); |
188 lcd_wr_reg(0x0093, 0x0003); | 200 lcd_writereg(0x0093, 0x0003); |
189 lcd_wr_reg(0x0095, 0x0110); | 201 lcd_writereg(0x0095, 0x0110); |
190 lcd_wr_reg(0x0097, 0x0000); /* Undocumented */ | 202 lcd_writereg(0x0097, 0x0000); /* Undocumented */ |
191 lcd_wr_reg(0x0098, 0x0000); /* Undocumented */ | 203 lcd_writereg(0x0098, 0x0000); /* Undocumented */ |
192 | 204 |
193 lcd_wr_reg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ | 205 lcd_writereg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ |
194 | 206 |
195 lcd_wr_reg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ | 207 lcd_writereg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ |
196 | 208 |
197 /* Adjust the Gamma Curve */ | 209 /* Adjust the Gamma Curve */ |
198 lcd_wr_reg(0x0030, 0x0006); | 210 lcd_writereg(0x0030, 0x0006); |
199 lcd_wr_reg(0x0031, 0x0101); | 211 lcd_writereg(0x0031, 0x0101); |
200 lcd_wr_reg(0x0032, 0x0003); | 212 lcd_writereg(0x0032, 0x0003); |
201 lcd_wr_reg(0x0035, 0x0106); | 213 lcd_writereg(0x0035, 0x0106); |
202 lcd_wr_reg(0x0036, 0x0b02); | 214 lcd_writereg(0x0036, 0x0b02); |
203 lcd_wr_reg(0x0037, 0x0302); | 215 lcd_writereg(0x0037, 0x0302); |
204 lcd_wr_reg(0x0038, 0x0707); | 216 lcd_writereg(0x0038, 0x0707); |
205 lcd_wr_reg(0x0039, 0x0007); | 217 lcd_writereg(0x0039, 0x0007); |
206 lcd_wr_reg(0x003c, 0x0600); | 218 lcd_writereg(0x003c, 0x0600); |
207 lcd_wr_reg(0x003d, 0x020b); | 219 lcd_writereg(0x003d, 0x020b); |
208 | 220 |
209 fputs("Testing\r\n", stdout); | 221 fputs("Testing\r\n", stdout); |
210 lcd_wr_startdata(0, 0); | 222 lcd_startgram(0, 0); |
211 lcd_wr_data(0xa5a5); | 223 lcd_writedata(0xa5a5); |
212 lcd_wr_data(0x5a5a); | 224 lcd_writedata(0x5a5a); |
213 lcd_wr_startdata(0, 0); | 225 lcd_startgram(0, 0); |
214 if ((id = lcd_rd_data(1)) != 0xa5a5) | 226 if ((id = lcd_readdata(1)) != 0xa5a5) |
215 printf("Expected 0xa5a5 got 0x%04x\r\n", id); | 227 printf("Expected 0xa5a5 got 0x%04x\r\n", id); |
216 | 228 |
217 if ((id = lcd_rd_data(0)) != 0x5a5a) | 229 if ((id = lcd_readdata(0)) != 0x5a5a) |
218 printf("Expected 0x5a5a got 0x%04x\r\n", id); | 230 printf("Expected 0x5a5a got 0x%04x\r\n", id); |
219 | 231 |
220 fputs("Filling\r\n", stdout); | 232 fputs("Filling\r\n", stdout); |
221 /* Fill panel */ | 233 /* Fill panel */ |
222 lcd_wr_startdata(0, 0); | 234 lcd_startgram(0, 0); |
223 | 235 |
224 for (int x = 0; x < 320; x++) { | 236 for (y = 0; y < 320; y++) |
225 for (int y = 0; y < 240; y++) { | 237 for (x = 0; x < 240; x++) |
226 if (((x / 5) % 3) == 0) | 238 lcd_writedata(LCD_BLACK); |
227 lcd_wr_data(LCD_RED); | |
228 else if (((x / 5) % 3) == 1) | |
229 lcd_wr_data(LCD_GREEN); | |
230 else | |
231 lcd_wr_data(LCD_BLUE); | |
232 } | |
233 } | |
234 | |
235 lcd_circle(50, 50, 20, LCD_BLACK); | |
236 | |
237 } | 239 } |
238 | 240 |
239 void | 241 void |
240 lcd_pixel(uint16_t x, uint16_t y, uint16_t colour) { | 242 lcd_pixel(uint16_t x, uint16_t y, uint16_t colour) { |
241 if (x > LCD_HEIGHT || y > LCD_WIDTH) | 243 if (x > LCD_WIDTH || y > LCD_HEIGHT) |
242 return; | 244 return; |
243 | 245 |
244 lcd_wr_startdata(x, y); | 246 /* Rotate for landscape */ |
245 lcd_wr_data(colour); | 247 lcd_startgram(y, x); |
248 lcd_writedata(colour); | |
246 } | 249 } |
247 | 250 |
248 /* | 251 /* |
249 * Draw a circle | 252 * Draw a circle |
250 * From http://en.wikipedia.org/wiki/Midpoint_circle_algorithm | 253 * From http://en.wikipedia.org/wiki/Midpoint_circle_algorithm |
251 */ | 254 */ |
252 void | 255 void |
253 lcd_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t colour) { | 256 lcd_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint8_t fill, uint16_t colour) { |
254 int16_t f; | 257 int16_t f; |
255 uint16_t ddF_x, ddF_y, x, y; | 258 uint16_t ddF_x, ddF_y, x, y; |
256 | 259 |
257 f = 1 - radius; | 260 f = 1 - radius; |
258 ddF_x = 1; | 261 ddF_x = 1; |
259 ddF_y = -2 * radius; | 262 ddF_y = -2 * radius; |
260 x = 0; | 263 x = 0; |
261 y = radius; | 264 y = radius; |
262 | 265 |
263 lcd_pixel(x0, y0 + radius, colour); | 266 |
264 lcd_pixel(x0, y0 - radius, colour); | 267 if (fill) { |
265 lcd_pixel(x0 + radius, y0, colour); | 268 lcd_line(x0, y0 + radius, x0, y0 - radius, colour); |
266 lcd_pixel(x0 - radius, y0, colour); | 269 lcd_line(x0 + radius, y0, x0 - radius, y0, colour); |
267 | 270 } else { |
271 lcd_pixel(x0, y0 + radius, colour); | |
272 lcd_pixel(x0, y0 - radius, colour); | |
273 lcd_pixel(x0 + radius, y0, colour); | |
274 lcd_pixel(x0 - radius, y0, colour); | |
275 } | |
276 | |
268 while(x < y) { | 277 while(x < y) { |
269 // ddF_x == 2 * x + 1; | |
270 // ddF_y == -2 * y; | |
271 // f == x*x + y*y - radius*radius + 2*x - y + 1; | |
272 if(f >= 0) { | 278 if(f >= 0) { |
273 y--; | 279 y--; |
274 ddF_y += 2; | 280 ddF_y += 2; |
275 f += ddF_y; | 281 f += ddF_y; |
276 } | 282 } |
277 x++; | 283 x++; |
278 ddF_x += 2; | 284 ddF_x += 2; |
279 f += ddF_x; | 285 f += ddF_x; |
280 lcd_pixel(x0 + x, y0 + y, colour); | 286 if (fill) { |
281 lcd_pixel(x0 - x, y0 + y, colour); | 287 lcd_line(x0 + x, y0 + y, x0 - x, y0 + y, colour); |
282 lcd_pixel(x0 + x, y0 - y, colour); | 288 lcd_line(x0 + x, y0 - y, x0 - x, y0 - y, colour); |
283 lcd_pixel(x0 - x, y0 - y, colour); | 289 lcd_line(x0 + y, y0 + x, x0 - y, y0 + x, colour); |
284 lcd_pixel(x0 + y, y0 + x, colour); | 290 lcd_line(x0 + y, y0 - x, x0 - y, y0 - x, colour); |
285 lcd_pixel(x0 - y, y0 + x, colour); | 291 } else { |
286 lcd_pixel(x0 + y, y0 - x, colour); | 292 lcd_pixel(x0 + x, y0 + y, colour); |
287 lcd_pixel(x0 - y, y0 - x, colour); | 293 lcd_pixel(x0 - x, y0 + y, colour); |
294 lcd_pixel(x0 + x, y0 - y, colour); | |
295 lcd_pixel(x0 - x, y0 - y, colour); | |
296 lcd_pixel(x0 + y, y0 + x, colour); | |
297 lcd_pixel(x0 - y, y0 + x, colour); | |
298 lcd_pixel(x0 + y, y0 - x, colour); | |
299 lcd_pixel(x0 - y, y0 - x, colour); | |
300 } | |
288 } | 301 } |
289 } | 302 } |
290 | 303 |
291 | 304 |
292 /* | 305 /* |
293 * Draw a line | 306 * Draw a line |
294 * From http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm | 307 * From http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm |
295 */ | 308 */ |
296 void | 309 void |
297 lcd_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t colour) { | 310 lcd_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t colour) { |
298 uint16_t dx, dy, d, x, y; | 311 uint16_t dx, dy; |
299 | 312 int16_t sx, sy, err, e2; |
300 dx = x1 - x0; | 313 |
301 dy = y1 - y0; | 314 dx = abs(x1 - x0); |
302 | 315 dy = abs(y1 - y0); |
303 d = 2 * dy - dx; | 316 |
304 lcd_pixel(x0, y0, colour); | 317 if (x0 < x1) |
305 y = y0; | 318 sx = 1; |
306 | 319 else |
307 for (x = x0 + 1; x <= x1; x++) { | 320 sx = -1; |
308 if (d > 0) { | 321 |
309 y++; | 322 if (y0 < y1) |
310 lcd_pixel(x, y, colour); | 323 sy = 1; |
311 d += 2 * dy - 2 * dx; | 324 else |
312 } else { | 325 sy = -1; |
313 lcd_pixel(x, y, colour); | 326 |
314 d += 2 * dy; | 327 err = dx - dy; |
315 } | 328 |
316 } | 329 while (1) { |
317 } | 330 |
331 lcd_pixel(x0, y0, colour); | |
332 | |
333 if (x0 == x1 && y0 == y1) | |
334 break; | |
335 | |
336 e2 = 2 * err; | |
337 | |
338 if (e2 > -dy) { | |
339 err = err - dy; | |
340 x0 = x0 + sx; | |
341 } | |
342 | |
343 if (e2 < dx) { | |
344 err = err + dx; | |
345 y0 = y0 + sy; | |
346 } | |
347 } | |
348 } | |
349 | |
350 static void | |
351 _lcd_ellipsedraw(uint16_t xc, uint16_t yc, uint16_t x, uint16_t y, uint8_t fill, uint16_t colour) { | |
352 if (fill) { | |
353 lcd_line(xc + x, yc + y, xc - x, yc + y, colour); | |
354 lcd_line(xc - x, yc - y, xc + x, yc - y, colour); | |
355 } else { | |
356 lcd_pixel(xc + x, yc + y, colour); /* 1st quadrant */ | |
357 lcd_pixel(xc - x, yc + y, colour); /* 2nd quadrant */ | |
358 lcd_pixel(xc - x, yc - y, colour); /* 3rd quadrant */ | |
359 lcd_pixel(xc + x, yc - y, colour); /* 4th quadrant */ | |
360 } | |
361 } | |
362 | |
363 /* Draw an ellipse, from | |
364 * http://rooparam.blogspot.com.au/2009/09/midpoint-ellipse-algorithm.html | |
365 */ | |
366 void lcd_ellipse(int xc, int yc, int rx, int ry, uint8_t fill, uint16_t colour) { | |
367 long long int rx_2 = rx * rx, ry_2 = ry * ry; | |
368 long long int p = ry_2 - rx_2 * ry + (ry_2 >> 2); | |
369 int x = 0, y = ry; | |
370 long long int two_ry_2_x = 0, two_rx_2_y = (rx_2 << 1) * y; | |
371 | |
372 _lcd_ellipsedraw(xc, yc, x, y, fill, colour); | |
373 | |
374 while (two_rx_2_y >= two_ry_2_x) { | |
375 x++; | |
376 two_ry_2_x += ry_2 << 1; | |
377 | |
378 p += two_ry_2_x + ry_2; | |
379 | |
380 if (p >= 0){ | |
381 y--; | |
382 two_rx_2_y -= rx_2 << 1; | |
383 | |
384 p -= two_rx_2_y; | |
385 } | |
386 _lcd_ellipsedraw(xc, yc, x, y, fill, colour); | |
387 } | |
388 | |
389 p = (long long int)(ry_2 * (x + 1 / 2.0) * (x + 1 / 2.0) + rx_2 * (y - 1) * (y - 1) - rx_2 * ry_2); | |
390 while (y >= 0) { | |
391 p += rx_2; | |
392 y--; | |
393 two_rx_2_y -= rx_2 << 1; | |
394 p -= two_rx_2_y; | |
395 | |
396 if (p <= 0) { | |
397 x++; | |
398 two_ry_2_x += ry_2 << 1; | |
399 p += two_ry_2_x; | |
400 } | |
401 _lcd_ellipsedraw(xc, yc, x, y, fill, colour); | |
402 } | |
403 } | |
404 | |
405 void lcd_stripes(void) { | |
406 uint16_t x, y, mag, err; | |
407 | |
408 lcd_startgram(0, 0); | |
409 | |
410 mag = err = 0; | |
411 for (y = 0; y < 320; y++) { | |
412 for (x = 0; x < 240; x++) { | |
413 if (((x / 80) % 3) == 0) { | |
414 lcd_writedata(RGB24_565(mag, 0, 0)); | |
415 } else if (((x / 80) % 3) == 1) { | |
416 lcd_writedata(RGB24_565(0, mag, 0)); | |
417 } else { | |
418 lcd_writedata(RGB24_565(0, 0, mag)); | |
419 } | |
420 } | |
421 colinc(&mag, &err, COLINCVAL, 10000); | |
422 } | |
423 } | |
424 uint16_t | |
425 lcd_parsecol(char c) { | |
426 c = toupper(c); | |
427 if (c == 'R') | |
428 return(LCD_RED); | |
429 else if (c == 'G') | |
430 return(LCD_GREEN); | |
431 else if (c == 'B') | |
432 return(LCD_BLUE); | |
433 else if (c == 'L') | |
434 return(LCD_BLACK); | |
435 else | |
436 return(LCD_WHITE); | |
437 | |
438 } | |
439 |