display.c 5.31 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"
11
12
13
14
15
#include "FreeRTOS.h"
#include "timers.h"

#define MAX_BRIGHTNESS 300
#define FREQ 100
Gerd's avatar
Gerd committed
16
17

static TaskHandle_t lock = NULL;
18
19
20
21
22
23
24
25
static TimerHandle_t poll_timer;
static StaticTimer_t poll_timer_buffer;

static bool display_on;
static bool wake_event;
static uint16_t timeout_cycles = 1000;
static uint8_t lpf_speed = 10; //ca. 1Hz f_g
static uint8_t brightness_table[MAX_BRIGHTNESS];
Gerd's avatar
Gerd committed
26
27
28
29
30
31
32
33
34
35
36

static int check_lock()
{
	TaskHandle_t task = xTaskGetCurrentTaskHandle();
	if (task != lock) {
		return -EBUSY;
	} else {
		return 0;
	}
}

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
void epic_disp_set_brightness_table(uint8_t table[MAX_BRIGHTNESS])
{
	for (int i = 0; i < MAX_BRIGHTNESS; i++){
		brightness_table[i]=table[i];
	}
}

static uint16_t limit(uint16_t input, uint16_t max, uint16_t min){
	uint16_t output = input > max ? max : input;
	return output < 0 ? 0 : output;
}

static uint16_t lpf(uint16_t input, uint8_t speed){
	static uint16_t output;
	output = speed*input+(~speed)*output;
	output = output >> 8;
	return output;
}

static void auto_backlight(){
	uint16_t light = 0;
	if(display_on){
		epic_light_sensor_get(&light);
		light = brightness_table[limit(light,MAX_BRIGHTNESS-1,0)];
	}

	uint16_t lpf_light = lpf(light, lpf_speed);
	lpf_light = limit(lpf_light,100,display_on);
	epic_disp_backlight(lpf_light);
}

void epic_disp_wake(){
	wake_event = true;
}

static void CALLBACK_power_mgmt(){ //u gotta loop dis
	uint16_t buttonTimeout = 0;
	if(!timeout_cycles){
		display_on = true;
	} else if(wake_event){
		buttonTimeout = timeout_cycles;
		display_on = true;
		wake_event = false;
	} else if(buttonTimeout){
		buttonTimeout--;
	} else {
		display_on = false;
	}
	auto_backlight();
}

void epic_disp_backlight_auto_stop()
{
	if (!poll_timer || xTimerIsTimerActive(poll_timer) == pdFALSE) { return; }
	xTimerStop(poll_timer, 0);
}

void epic_disp_backlight_auto(){
	if(!poll_timer) {
		poll_timer = xTimerCreateStatic(
				"auto_backlight",
				FREQ,
				pdTRUE,
				NULL,
				CALLBACK_power_mgmt,
				&poll_timer_buffer
		);
	}
}

Gerd's avatar
Gerd committed
107
108
109
110
111
112
int epic_disp_print(
	uint16_t posx,
	uint16_t posy,
	const char *pString,
	uint16_t fg,
	uint16_t bg
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
) {
	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,
	uint16_t posx,
	uint16_t posy,
	const char *pString,
	uint16_t fg,
	uint16_t bg
Gerd's avatar
Gerd committed
130
131
) {
	int cl = check_lock();
132
133
134
	if (font >= (sizeof(font_map) / sizeof(sFONT *))) {
		return -EINVAL;
	}
Gerd's avatar
Gerd committed
135
136
137
	if (cl < 0) {
		return cl;
	} else {
138
139
140
141
142
143
144
145
146
		gfx_puts(
			font_map[font],
			&display_screen,
			posx,
			posy,
			pString,
			fg,
			bg
		);
Gerd's avatar
Gerd committed
147
148
149
150
151
152
153
154
155
156
		return 0;
	}
}

int epic_disp_clear(uint16_t color)
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	} else {
157
		gfx_clear_to_color(&display_screen, color);
Gerd's avatar
Gerd committed
158
159
160
161
		return 0;
	}
}

162
163
164
165
166
167
int epic_disp_pixel(uint16_t x, uint16_t y, uint16_t color)
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	} else {
168
		gfx_setpixel(&display_screen, x, y, color);
169
170
171
172
		return 0;
	}
}

Gerd's avatar
Gerd committed
173
174
175
176
177
178
int epic_disp_line(
	uint16_t xstart,
	uint16_t ystart,
	uint16_t xend,
	uint16_t yend,
	uint16_t color,
Rahix's avatar
Rahix committed
179
	enum disp_linestyle linestyle,
Gerd's avatar
Gerd committed
180
181
182
183
184
185
	uint16_t pixelsize
) {
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	} else {
186
		/* TODO add linestyle support to gfx code */
187
		gfx_line(
188
189
190
191
192
193
194
			&display_screen,
			xstart,
			ystart,
			xend,
			yend,
			pixelsize,
			color
Gerd's avatar
Gerd committed
195
196
197
198
199
200
201
202
203
204
205
		);
		return 0;
	}
}

int epic_disp_rect(
	uint16_t xstart,
	uint16_t ystart,
	uint16_t xend,
	uint16_t yend,
	uint16_t color,
Rahix's avatar
Rahix committed
206
	enum disp_fillstyle fillstyle,
Gerd's avatar
Gerd committed
207
208
209
	uint16_t pixelsize
) {
	int cl = check_lock();
210
	if (cl < 0)
Gerd's avatar
Gerd committed
211
		return cl;
212
213
214
215
216
217
218
219
220
221
222

	switch (fillstyle) {
	case FILLSTYLE_EMPTY:
		gfx_rectangle(
			&display_screen,
			xstart,
			ystart,
			xend - xstart,
			yend - ystart,
			pixelsize,
			color
Gerd's avatar
Gerd committed
223
		);
224
225
226
227
228
229
230
231
232
233
234
		break;
	case FILLSTYLE_FILLED:
		gfx_rectangle_fill(
			&display_screen,
			xstart,
			ystart,
			xend - xstart,
			yend - ystart,
			color
		);
		break;
Gerd's avatar
Gerd committed
235
	}
236
	return 0;
Gerd's avatar
Gerd committed
237
238
239
240
241
242
243
}

int epic_disp_circ(
	uint16_t x,
	uint16_t y,
	uint16_t rad,
	uint16_t color,
Rahix's avatar
Rahix committed
244
	enum disp_fillstyle fillstyle,
Gerd's avatar
Gerd committed
245
246
247
	uint16_t pixelsize
) {
	int cl = check_lock();
248
	if (cl < 0)
Gerd's avatar
Gerd committed
249
		return cl;
250
251
252
253
254
255
256
257

	switch (fillstyle) {
	case FILLSTYLE_EMPTY:
		gfx_circle(&display_screen, x, y, rad, pixelsize, color);
		break;
	case FILLSTYLE_FILLED:
		gfx_circle_fill(&display_screen, x, y, rad, color);
		break;
Gerd's avatar
Gerd committed
258
	}
259
260

	return 0;
Gerd's avatar
Gerd committed
261
262
263
264
265
266
267
268
}

int epic_disp_update()
{
	int cl = check_lock();
	if (cl < 0) {
		return cl;
	}
269

270
	gfx_update(&display_screen);
271
272
273
274
275
276
277
278
279
280
281
282
	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
283
284
}

285
286
int epic_disp_backlight(uint16_t brightness)
{
287
	/* TODO: lock? */
288
289
290
291
	LCD_SetBacklight(brightness);
	return 0;
}

Gerd's avatar
Gerd committed
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
int epic_disp_open()
{
	TaskHandle_t task = xTaskGetCurrentTaskHandle();
	if (lock == task) {
		return 0;
	} else if (lock == NULL) {
		lock = task;
		return 0;
	} else {
		return -EBUSY;
	}
}

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;
}