00001
00048 #include <stdarg.h>
00049 #include "board.h"
00050 #include "et024006dhu.h"
00051 #include "conf_demo.h"
00052 #include "delay.h"
00053 #include "gpio.h"
00054 #include "gui.h"
00055 #include "background_image.h"
00056 #include "cycle_counter.h"
00057
00058 #include "dsp.h"
00059 #include "dsp_sprintf.h"
00060
00061 #include "compiler.h"
00062
00063 struct gui_box
00064 {
00065 uint16_t x, y;
00066 uint16_t width, height;
00067 et024006_color_t fg_color, bg_color;
00068 };
00069
00070 static void gui_draw_background(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
00071 static void gui_buffer_print_dsp16_signal(void *buffer, uint16_t width, uint16_t height, dsp16_t *signal, uint16_t signal_size);
00072 static void gui_buffer_print_dsp16_bars(void *buffer, uint16_t width, uint16_t height, dsp16_t *signal, uint16_t signal_size);
00073 static inline void gui_buffer_set_pixel(void *buffer, uint16_t width, uint16_t height, uint16_t x, uint16_t y);
00074
00075 static void gui_print_signal_box(int box_id, dsp16_t *signal, uint16_t signal_size);
00076 static void gui_print_fft_box(int box_id, dsp16_t *signal, uint16_t signal_size);
00077
00078 static const struct gui_box box[] = {
00079 GUI_BOXES
00080 };
00081
00082 #define MAX_BUFFER_WIDTH Max(Max(Max(Max(GUI_SOURCE1_WIDTH, GUI_SOURCE2_WIDTH), GUI_INPUT_WIDTH), GUI_OUTPUT_WIDTH), GUI_ZOOM_BOX_WIDTH)
00083 #define MAX_BUFFER_HEIGHT Max(Max(Max(Max(GUI_SOURCE1_HEIGHT, GUI_SOURCE2_HEIGHT), GUI_INPUT_HEIGHT), GUI_OUTPUT_HEIGHT), GUI_ZOOM_BOX_HEIGHT)
00084
00085 static uint8_t buffer[ET024006_BITMAP_WIDTH(MAX_BUFFER_WIDTH)*MAX_BUFFER_HEIGHT];
00086 static dsp16_t signal_buffer[BUFFER_LENGTH];
00087
00088 static struct
00089 {
00090 t_cpu_time cpu_time;
00091 uint32_t time_ms;
00092 } gui_fs;
00093 static int gui_cpu_hz;
00094
00095 char gui_text_buffer[GUI_TEXT_BUFFER_SIZE];
00096
00097 extern dsp16_t signal1_buf[BUFFER_LENGTH];
00098 extern dsp16_t signal2_buf[BUFFER_LENGTH];
00099 extern dsp16_t *signal_in_buf;
00100 extern dsp16_t signal_in_fft[BUFFER_LENGTH];
00101 extern dsp16_t signal_out_buf[BUFFER_LENGTH];
00102 extern dsp16_t signal_out_fft[BUFFER_LENGTH];
00103
00104 extern bool signals_are_updated;
00105 void gui_change_update_fs(uint32_t time_ms)
00106 {
00107 gui_fs.time_ms = time_ms;
00108 cpu_set_timeout(cpu_ms_2_cy(gui_fs.time_ms, gui_cpu_hz), &gui_fs.cpu_time);
00109 }
00110
00111 uint32_t gui_get_update_fs(void)
00112 {
00113 return gui_fs.time_ms;
00114 }
00115
00116 void gui_init(int cpu_hz, int hsb_hz, int pba_hz, int pbb_hz)
00117 {
00118 gui_cpu_hz = cpu_hz;
00119
00120 delay_init(cpu_hz);
00121
00122 et024006_Init(cpu_hz, hsb_hz);
00123 gpio_set_gpio_pin(ET024006DHU_BL_PIN);
00124
00125 gui_clear_view();
00126
00127 gui_change_update_fs(DEFAULT_SCREEN_UPDATE_FS_MS);
00128 }
00129
00130 void gui_clear_view(void)
00131 {
00132 gui_draw_background(0, 0, ET024006_WIDTH, ET024006_HEIGHT);
00133 }
00134
00135 void gui_task(void)
00136 {
00137 extern volatile Bool input_fft_view;
00138 extern volatile Bool output_fft_view;
00139
00140
00141 if (cpu_is_timeout(&gui_fs.cpu_time))
00142 {
00143 gui_print_signal_box(GUI_SOURCE1_ID, signal1_buf, sizeof(signal1_buf)/sizeof(signal1_buf[0]));
00144 gui_print_signal_box(GUI_SOURCE2_ID, signal2_buf, sizeof(signal2_buf)/sizeof(signal2_buf[0]));
00145 if (input_fft_view)
00146 gui_print_fft_box(GUI_INPUT_ID, signal_in_fft, FFT_LENGTH);
00147 else
00148 gui_print_signal_box(GUI_INPUT_ID, signal_in_buf, BUFFER_LENGTH);
00149 if (output_fft_view)
00150 gui_print_fft_box(GUI_OUTPUT_ID, signal_out_fft, FFT_LENGTH);
00151 else
00152 gui_print_signal_box(GUI_OUTPUT_ID, signal_out_buf, sizeof(signal2_buf)/sizeof(signal2_buf[0]));
00153 cpu_set_timeout(cpu_ms_2_cy(gui_fs.time_ms, gui_cpu_hz), &gui_fs.cpu_time);
00154 }
00155 }
00156
00157 void gui_set_selection(int box_id)
00158 {
00159 static int prev_selection = GUI_NO_SEL;
00160 struct gui_box *sb;
00161 int i;
00162
00163
00164 if (prev_selection != GUI_NO_SEL && prev_selection != box_id)
00165 {
00166 i = prev_selection;
00167 sb = (struct gui_box *) &box[i];
00168
00169 if (sb->bg_color == GUI_NO_COLOR)
00170 {
00171 gui_draw_background(sb->x - 2, sb->y - 2, sb->width + 4, 2);
00172 gui_draw_background(sb->x - 2, sb->y + sb->height, sb->width + 4, 2);
00173 gui_draw_background(sb->x - 2, sb->y - 2, 2, sb->height + 4);
00174 gui_draw_background(sb->x + sb->width, sb->y - 2, 2, sb->height + 4);
00175 }
00176 else
00177 {
00178 et024006_DrawFilledRect(sb->x - 2, sb->y - 2, sb->width + 4, 2, sb->bg_color);
00179 et024006_DrawFilledRect(sb->x - 2, sb->y + sb->height, sb->width + 4, 2, sb->bg_color);
00180 et024006_DrawFilledRect(sb->x - 2, sb->y - 2, 2, sb->height + 4, sb->bg_color);
00181 et024006_DrawFilledRect(sb->x + sb->width, sb->y - 2, 2, sb->height + 4, sb->bg_color);
00182 }
00183 }
00184
00185 prev_selection = box_id;
00186
00187 if (box_id == GUI_NO_SEL)
00188 return;
00189
00190 sb = (struct gui_box *) &box[box_id];
00191 et024006_DrawFilledRect(sb->x - 2, sb->y - 2, sb->width + 4, 2, GUI_SELECTION_COLOR);
00192 et024006_DrawFilledRect(sb->x - 2, sb->y + sb->height, sb->width + 4, 2, GUI_SELECTION_COLOR);
00193 et024006_DrawFilledRect(sb->x - 2, sb->y - 2, 2, sb->height + 4, GUI_SELECTION_COLOR);
00194 et024006_DrawFilledRect(sb->x + sb->width, sb->y - 2, 2, sb->height + 4, GUI_SELECTION_COLOR);
00195 }
00196
00197
00198 static void gui_print_signal_box(int box_id, dsp16_t *signal, uint16_t signal_size)
00199 {
00200 const struct gui_box *sb = &box[box_id];
00201 extern volatile Bool zoom_view;
00202 extern volatile int zoom_view_id;
00203
00204 if (zoom_view && zoom_view_id != box_id)
00205 return;
00206
00207 signal_size = Min(signal_size, BUFFER_LENGTH);
00208 do
00209 {
00210 signals_are_updated = 0;
00211 memcpy(signal_buffer, signal, sizeof(dsp16_t)*signal_size);
00212 } while (signals_are_updated);
00213
00214 if (zoom_view && zoom_view_id == box_id)
00215 gui_buffer_print_dsp16_signal(buffer, GUI_ZOOM_BOX_WIDTH, GUI_ZOOM_BOX_HEIGHT, signal_buffer, signal_size);
00216 else
00217 gui_buffer_print_dsp16_signal(buffer, sb->width, sb->height, signal_buffer, signal_size);
00218
00219 if (zoom_view && zoom_view_id == box_id)
00220 et024006_PutBitmap(buffer, GUI_ZOOM_BOX_WIDTH, GUI_ZOOM_BOX_X, GUI_ZOOM_BOX_Y, GUI_ZOOM_BOX_WIDTH, GUI_ZOOM_BOX_HEIGHT, sb->fg_color, sb->bg_color);
00221 else
00222 et024006_PutBitmap(buffer, sb->width, sb->x, sb->y, sb->width, sb->height, sb->fg_color, sb->bg_color);
00223 }
00224
00225 static void gui_print_fft_box(int box_id, dsp16_t *signal, uint16_t signal_size)
00226 {
00227 const struct gui_box *sb = &box[box_id];
00228 extern volatile Bool zoom_view;
00229 extern volatile int zoom_view_id;
00230
00231 if (zoom_view && zoom_view_id != box_id)
00232 return;
00233
00234 if (zoom_view && zoom_view_id == box_id)
00235 {
00236 gui_buffer_print_dsp16_bars(buffer, GUI_ZOOM_BOX_WIDTH, GUI_ZOOM_BOX_HEIGHT, signal, signal_size);
00237 et024006_PutBitmap(buffer, GUI_ZOOM_BOX_WIDTH, GUI_ZOOM_BOX_X, GUI_ZOOM_BOX_Y, GUI_ZOOM_BOX_WIDTH, GUI_ZOOM_BOX_HEIGHT, sb->fg_color, sb->bg_color);
00238 }
00239 else
00240 {
00241 gui_buffer_print_dsp16_bars(buffer, sb->width, sb->height, signal, signal_size);
00242 et024006_PutBitmap(buffer, sb->width, sb->x, sb->y, sb->width, sb->height, sb->fg_color, sb->bg_color);
00243 }
00244 }
00245
00246 void gui_text_print(int box_id, const char *text)
00247 {
00248 extern volatile Bool zoom_view;
00249 const struct gui_box *sb = (struct gui_box *) &box[box_id];
00250 int i, len;
00251 int y = sb->y;
00252
00253 if (zoom_view)
00254 return;
00255
00256
00257 if (sb->bg_color == GUI_NO_COLOR)
00258 gui_draw_background(sb->x, sb->y, sb->width, sb->height);
00259 else
00260 et024006_DrawFilledRect(sb->x, sb->y, sb->width, sb->height, sb->bg_color);
00261
00262
00263 len = 0;
00264 i = 0;
00265 do
00266 {
00267 if (text[i] == '\n' || text[i] == '\0')
00268 len++;
00269 } while (text[i++]);
00270
00271 y += (sb->height - len*GUI_FONT_HEIGHT)/2;
00272
00273
00274 len = 0;
00275 i = 0;
00276 do
00277 {
00278 if (text[i] == '\n' || text[i] == '\0')
00279 {
00280 if (i - len >= 0)
00281 {
00282 memmove(gui_text_buffer, &text[i - len], len);
00283 gui_text_buffer[len] = '\0';
00284 if (sb->bg_color == GUI_NO_COLOR)
00285 et024006_PrintString(gui_text_buffer, (const unsigned char *) &GUI_FONT, sb->x, y, sb->fg_color, -1);
00286 else
00287 et024006_PrintString(gui_text_buffer, (const unsigned char *) &GUI_FONT, sb->x, y, sb->fg_color, sb->bg_color);
00288 gui_text_buffer[len] = ' ';
00289 }
00290 y += GUI_FONT_HEIGHT;
00291 len = 0;
00292 }
00293 else
00294 len++;
00295 } while (text[i++]);
00296 }
00297
00298 static void gui_draw_background(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
00299 {
00300 et024006_PutPixmap(background_image, ET024006_WIDTH, x, y, x, y, width, height);
00301 }
00302
00303 static inline void gui_buffer_set_pixel(void *buffer, uint16_t width, uint16_t height, uint16_t x, uint16_t y)
00304 {
00305 uint8_t *u8_buffer = (uint8_t *) buffer;
00306 if (x >= width || y >= height)
00307 return;
00308 u8_buffer += y * ET024006_BITMAP_WIDTH(width) + x / 8;
00309 *u8_buffer = *u8_buffer | (1 << (x & 7));
00310 }
00311
00312 static void gui_buffer_print_dsp16_signal(void *buffer, uint16_t width, uint16_t height, dsp16_t *signal, uint16_t signal_size)
00313 {
00314 uint16_t t, cur_y;
00315 uint32_t scale_x, scale_y;
00316 uint32_t i_signal;
00317 uint16_t i, last_y = 0;
00318
00319
00320 memset(buffer, 0, ET024006_BITMAP_WIDTH(width)*height);
00321
00322 scale_y = (uint32_t) ((height/2) * 0x10000) / ((uint32_t) -DSP_FP_MIN(DSP16_QA, DSP16_QB));
00323
00324 if (signal_size >= width)
00325 {
00326
00327 scale_x = (uint32_t) (signal_size * 0x10000) / width;
00328 for (t=0; t<width; t++)
00329 {
00330 i_signal = ((uint64_t) t * scale_x) / 0x10000;
00331
00332 cur_y = ((((uint64_t) signal[i_signal] * scale_y) / 0x10000) >> DSP16_QB);
00333 cur_y = height/2 - cur_y - 1;
00334 if (last_y <= cur_y && t)
00335 {
00336 for (i=last_y; i<=cur_y; i++)
00337 gui_buffer_set_pixel(buffer, width, height, t, i);
00338 }
00339 else if (t)
00340 {
00341 for (i=cur_y; i<=last_y; i++)
00342 gui_buffer_set_pixel(buffer, width, height, t, i);
00343 }
00344 last_y = cur_y;
00345 }
00346 }
00347 else
00348 {
00349 uint16_t prev_t = 0, prev_y = 0;
00350 int32_t delta_y;
00351
00352
00353 scale_x = (((uint32_t) (width * (signal_size + 1)) / signal_size) * 0x10000) / signal_size;
00354 for (i_signal=0; i_signal<signal_size; i_signal++)
00355 {
00356 t = ((uint64_t) i_signal * scale_x) / 0x10000;
00357 cur_y = ((((uint64_t) signal[i_signal] * scale_y) / 0x10000) >> DSP16_QB);
00358 cur_y = height/2 - cur_y - 1;
00359
00360 if (i_signal)
00361 {
00362
00363 if (Abs(prev_y - cur_y) < t - prev_t)
00364 {
00365 int16_t b;
00366
00367 delta_y = (int32_t) ((prev_y - cur_y) * 0x10000) / (prev_t - t);
00368 b = cur_y - (delta_y * t) / 0x10000;
00369 for (i=prev_t; i<t; i++)
00370 {
00371 uint16_t temp_y;
00372 temp_y = (uint16_t) ((delta_y * i) / 0x10000 + b);
00373 gui_buffer_set_pixel(buffer, width, height, i, temp_y);
00374 }
00375 }
00376
00377 else
00378 {
00379 int16_t b;
00380
00381 delta_y = (int32_t) ((prev_t - t) * 0x10000) / (prev_y - cur_y);
00382 b = cur_y - ((int32_t) 0x10000 * t) / delta_y;
00383 if (prev_y < cur_y)
00384 {
00385 for (i=prev_y; i<cur_y; i++)
00386 {
00387 uint16_t temp_x;
00388 temp_x = ((uint32_t) ((i - b) * delta_y)) / 0x10000;
00389 gui_buffer_set_pixel(buffer, width, height, temp_x, i);
00390 }
00391 }
00392 else
00393 {
00394 for (i=cur_y; i<prev_y; i++)
00395 {
00396 uint16_t temp_x;
00397 temp_x = ((uint32_t) ((i - b) * delta_y)) / 0x10000;
00398 gui_buffer_set_pixel(buffer, width, height, temp_x, i);
00399 }
00400 }
00401 }
00402 }
00403 prev_t = t;
00404 prev_y = cur_y;
00405 }
00406 }
00407 }
00408
00409 static void gui_buffer_print_dsp16_bars(void *buffer, uint16_t width, uint16_t height, dsp16_t *signal, uint16_t signal_size)
00410 {
00411 uint16_t t, cur_y;
00412 uint32_t scale_x, scale_y;
00413 uint32_t i_signal;
00414 uint16_t i;
00415
00416
00417 memset(buffer, 0, ET024006_BITMAP_WIDTH(width)*height);
00418
00419 scale_y = (uint32_t) ((height) * 0x10000) / ((uint32_t) -DSP_FP_MIN(DSP16_QA, DSP16_QB));
00420
00421 if (signal_size >= width)
00422 {
00423 scale_x = (uint32_t) (signal_size * 0x10000) / width;
00424 for (t=0; t<width; t++)
00425 {
00426 i_signal = ((uint64_t) t * scale_x) / 0x10000;
00427
00428 cur_y = ((((uint64_t) signal[i_signal] * scale_y) / 0x10000) >> DSP16_QB);
00429 if (cur_y <= 0)
00430 cur_y = 1;
00431
00432 cur_y = height - cur_y;
00433 if (cur_y <= 0)
00434 cur_y = 1;
00435
00436
00437 uint16_t temp_y;
00438 for (temp_y = cur_y; temp_y < height; temp_y++)
00439 gui_buffer_set_pixel(buffer, width, height, t, temp_y);
00440 }
00441 }
00442 else
00443 {
00444 uint16_t prev_t = 0;
00445
00446 scale_x = (((uint32_t) (width * (signal_size + 1)) / signal_size) * 0x10000) / signal_size;
00447 for (i_signal=0; i_signal<signal_size; i_signal++)
00448 {
00449 t = ((uint64_t) i_signal * scale_x) / 0x10000;
00450 cur_y = ((((uint64_t) signal[i_signal] * scale_y) / 0x10000) >> DSP16_QB);
00451 if (cur_y <= 0)
00452 cur_y = 1;
00453
00454 cur_y = height - cur_y;
00455 if (cur_y <= 0)
00456 cur_y = 1;
00457
00458
00459 for (i = prev_t; i < t; i++)
00460 {
00461 uint16_t temp_y;
00462 for (temp_y = cur_y; temp_y < height; temp_y++)
00463 gui_buffer_set_pixel(buffer, width, height, i, temp_y);
00464 }
00465 prev_t = t;
00466 }
00467 }
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529