display.c 4.41 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
15
static struct gfx_region *current_fb = &application_screen;

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

int epic_disp_print(
27
28
	int16_t posx,
	int16_t posy,
Gerd's avatar
Gerd committed
29
30
31
	const char *pString,
	uint16_t fg,
	uint16_t bg
32
33
34
35
36
37
38
39
40
41
42
43
) {
	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,
44
45
	int16_t posx,
	int16_t posy,
46
47
48
	const char *pString,
	uint16_t fg,
	uint16_t bg
Gerd's avatar
Gerd committed
49
50
) {
	int cl = check_lock();
51
52
53
	if (font >= (sizeof(font_map) / sizeof(sFONT *))) {
		return -EINVAL;
	}
Gerd's avatar
Gerd committed
54
55
56
	if (cl < 0) {
		return cl;
	} else {
57
58
59
60
61
62
63
64
65
		gfx_puts(
			font_map[font],
			&display_screen,
			posx,
			posy,
			pString,
			fg,
			bg
		);
Gerd's avatar
Gerd committed
66
67
68
69
70
71
72
73
74
75
		return 0;
	}
}

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

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

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

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

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

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

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

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

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
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
203
204
205
206
207
208
int epic_disp_update()
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	}
209

210
	compositor();
211
	gfx_update(&display_screen);
212
213
214
215
216
217
218
219
220
221
222
223
	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
224
225
}

226
227
int epic_disp_backlight(uint16_t brightness)
{
228
	/* TODO: lock? */
229
230
231
232
	LCD_SetBacklight(brightness);
	return 0;
}

Gerd's avatar
Gerd committed
233
234
235
236
int epic_disp_open()
{
	TaskHandle_t task = xTaskGetCurrentTaskHandle();
	if (lock == task) {
237
        current_fb = &application_screen;
Gerd's avatar
Gerd committed
238
239
		return 0;
	} else if (lock == NULL) {
240
241
242
        lock = task;
        current_fb = &application_screen;
        return 0;
Gerd's avatar
Gerd committed
243
244
245
246
247
	} else {
		return -EBUSY;
	}
}

248
249
250
251
252
253
254
255
256
257
258
259
int epic_disp_overlay()
{
    int cl = check_lock();
    if (cl < 0) {
        return cl;
    }

    current_fb = &overlay_screen;

    return 0;
}

Gerd's avatar
Gerd committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
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;
}