display.c 4.81 KB
Newer Older
1
#include "display.h"
Gerd's avatar
Gerd committed
2
3
#include "Fonts/fonts.h"
#include "FreeRTOS.h"
4
#include "LCD_Driver.h"
5
6
7
8
9
10
#include "epicardium.h"
#include "gfx.h"
#include "gpio.h"
#include "task.h"
#include "tmr.h"
#include "tmr_utils.h"
Gerd's avatar
Gerd committed
11
12
13

static TaskHandle_t lock = NULL;

14
static struct gfx_region *current_fb = &application_screen;
Stefan Haun's avatar
Stefan Haun committed
15
static bool fullscreen = false;
16

Gerd's avatar
Gerd committed
17
18
19
20
21
22
23
24
25
26
27
static int check_lock()
{
	TaskHandle_t task = xTaskGetCurrentTaskHandle();
	if (task != lock) {
		return -EBUSY;
	} else {
		return 0;
	}
}

int epic_disp_print(
28
29
	int16_t posx,
	int16_t posy,
Gerd's avatar
Gerd committed
30
31
32
	const char *pString,
	uint16_t fg,
	uint16_t bg
33
34
35
36
37
38
39
40
41
42
43
44
) {
	return epic_disp_print_adv(DISP_FONT20, posx, posy, pString, fg, bg);
}

static const sFONT *font_map[] = {
	[DISP_FONT8] = &Font8,   [DISP_FONT12] = &Font12,
	[DISP_FONT16] = &Font16, [DISP_FONT20] = &Font20,
	[DISP_FONT24] = &Font24,
};

int epic_disp_print_adv(
	uint8_t font,
45
46
	int16_t posx,
	int16_t posy,
47
48
49
	const char *pString,
	uint16_t fg,
	uint16_t bg
Gerd's avatar
Gerd committed
50
51
) {
	int cl = check_lock();
52
53
54
	if (font >= (sizeof(font_map) / sizeof(sFONT *))) {
		return -EINVAL;
	}
Gerd's avatar
Gerd committed
55
56
57
	if (cl < 0) {
		return cl;
	} else {
58
59
60
61
62
63
64
65
66
		gfx_puts(
			font_map[font],
			&display_screen,
			posx,
			posy,
			pString,
			fg,
			bg
		);
Gerd's avatar
Gerd committed
67
68
69
70
71
72
73
74
75
76
		return 0;
	}
}

int epic_disp_clear(uint16_t color)
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	} else {
77
        gfx_clear_to_color(current_fb, color);
Gerd's avatar
Gerd committed
78
79
80
81
		return 0;
	}
}

82
int epic_disp_pixel(int16_t x, int16_t y, uint16_t color)
83
84
85
86
87
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	} else {
88
        gfx_setpixel(current_fb, x, y, color);
89
90
91
92
		return 0;
	}
}

Gerd's avatar
Gerd committed
93
int epic_disp_line(
94
95
96
97
	int16_t xstart,
	int16_t ystart,
	int16_t xend,
	int16_t yend,
Gerd's avatar
Gerd committed
98
	uint16_t color,
Rahix's avatar
Rahix committed
99
	enum disp_linestyle linestyle,
Gerd's avatar
Gerd committed
100
101
102
103
104
105
	uint16_t pixelsize
) {
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	} else {
106
		/* TODO add linestyle support to gfx code */
107
		gfx_line(
108
            current_fb,
109
110
111
112
113
114
			xstart,
			ystart,
			xend,
			yend,
			pixelsize,
			color
Gerd's avatar
Gerd committed
115
116
117
118
119
120
		);
		return 0;
	}
}

int epic_disp_rect(
121
122
123
124
	int16_t xstart,
	int16_t ystart,
	int16_t xend,
	int16_t yend,
Gerd's avatar
Gerd committed
125
	uint16_t color,
Rahix's avatar
Rahix committed
126
	enum disp_fillstyle fillstyle,
Gerd's avatar
Gerd committed
127
128
129
	uint16_t pixelsize
) {
	int cl = check_lock();
130
	if (cl < 0)
Gerd's avatar
Gerd committed
131
		return cl;
132
133
134
135

	switch (fillstyle) {
	case FILLSTYLE_EMPTY:
		gfx_rectangle(
136
            current_fb,
137
138
139
140
141
142
			xstart,
			ystart,
			xend - xstart,
			yend - ystart,
			pixelsize,
			color
Gerd's avatar
Gerd committed
143
		);
144
145
146
		break;
	case FILLSTYLE_FILLED:
		gfx_rectangle_fill(
147
            current_fb,
148
149
150
151
152
153
154
			xstart,
			ystart,
			xend - xstart,
			yend - ystart,
			color
		);
		break;
Gerd's avatar
Gerd committed
155
	}
156
	return 0;
Gerd's avatar
Gerd committed
157
158
159
}

int epic_disp_circ(
160
161
	int16_t x,
	int16_t y,
Gerd's avatar
Gerd committed
162
163
	uint16_t rad,
	uint16_t color,
Rahix's avatar
Rahix committed
164
	enum disp_fillstyle fillstyle,
Gerd's avatar
Gerd committed
165
166
167
	uint16_t pixelsize
) {
	int cl = check_lock();
168
	if (cl < 0)
Gerd's avatar
Gerd committed
169
		return cl;
170
171
172

	switch (fillstyle) {
	case FILLSTYLE_EMPTY:
173
        gfx_circle(current_fb, x, y, rad, pixelsize, color);
174
175
		break;
	case FILLSTYLE_FILLED:
176
        gfx_circle_fill(current_fb, x, y, rad, color);
177
		break;
Gerd's avatar
Gerd committed
178
	}
179
180

	return 0;
Gerd's avatar
Gerd committed
181
182
}

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
void compositor()
{
	for (int y = 0; y < display_screen.height; y++) {
		for (int x = 0; x < display_screen.width; x++) {
			uint8_t *overlay_pixel =
				fb_pixel(overlay_screen.fb, x, y);
			uint8_t *target = fb_pixel(display_screen.fb, x, y);

			if ((overlay_pixel[0] ==  0) && (overlay_pixel[1] == 0)) {
				uint8_t *app_pixel =
					fb_pixel(application_screen.fb, x, y);
                target[0] = app_pixel[0];
                target[1] = app_pixel[1];
            } else {
				target[0] = overlay_pixel[0];
				target[1] = overlay_pixel[1];
			}
		}
	}
}

Gerd's avatar
Gerd committed
204
205
206
207
208
209
int epic_disp_update()
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	}
210

Stefan Haun's avatar
Stefan Haun committed
211
212
213
214
	if (!fullscreen) {
        compositor();
    }

215
	gfx_update(&display_screen);
216
217
218
219
220
221
222
223
224
225
226
227
	return 0;
}

int epic_disp_framebuffer(union disp_framebuffer *fb)
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	}

	LCD_Set(fb->raw, sizeof(fb->raw));
	return 0;
Gerd's avatar
Gerd committed
228
229
}

230
231
int epic_disp_backlight(uint16_t brightness)
{
232
	/* TODO: lock? */
233
234
235
236
	LCD_SetBacklight(brightness);
	return 0;
}

Gerd's avatar
Gerd committed
237
238
239
240
int epic_disp_open()
{
	TaskHandle_t task = xTaskGetCurrentTaskHandle();
	if (lock == task) {
Stefan Haun's avatar
Stefan Haun committed
241
        current_fb = fullscreen ? &display_screen : &application_screen;
Gerd's avatar
Gerd committed
242
243
		return 0;
	} else if (lock == NULL) {
244
        lock = task;
Stefan Haun's avatar
Stefan Haun committed
245
        current_fb = fullscreen ? &display_screen : &application_screen;
246
        return 0;
Gerd's avatar
Gerd committed
247
248
249
250
251
	} else {
		return -EBUSY;
	}
}

Stefan Haun's avatar
Stefan Haun committed
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
int epic_disp_set_fullscreen(bool enable)
{
    int cl = check_lock();
    if (cl < 0) {
        return cl;
    }

    fullscreen = enable;

    current_fb = fullscreen ? &display_screen : &application_screen;

    return 0;
}

bool epic_disp_is_fullscreen()
{
    return fullscreen;
}

271
272
273
274
275
276
277
278
279
280
281
282
int epic_disp_overlay()
{
    int cl = check_lock();
    if (cl < 0) {
        return cl;
    }

    current_fb = &overlay_screen;

    return 0;
}

Gerd's avatar
Gerd committed
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
int epic_disp_close()
{
	if (check_lock() < 0 && lock != NULL) {
		return -EBUSY;
	} else {
		lock = NULL;
		return 0;
	}
}

void disp_forcelock()
{
	TaskHandle_t task = xTaskGetCurrentTaskHandle();
	lock              = task;
}