1 /* This is a small demo of the high-performance GUIX graphics framework. */
2 
3 #include <stdio.h>
4 #include "gx_api.h"
5 
6 #include "demo_guix_binres_resources.h"
7 #include "demo_guix_binres_specifications.h"
8 
9 /* This demo can be built and run on evaluation boards such as the STM32F439, in which
10    case the binary resource data is programmed to FLASH prior to running this demo.
11 */
12 
13 #ifdef STM32F439xx
14 #include "stm32f4xx_hal.h"
15 #endif
16 
17 #define GUIX_POOL_SIZE        (MAIN_DISPLAY_X_RESOLUTION * MAIN_DISPLAY_Y_RESOLUTION)
18 #define DEFAULT_CANVAS_PIXELS (MAIN_DISPLAY_X_RESOLUTION * MAIN_DISPLAY_Y_RESOLUTION)
19 
20 GX_WINDOW_ROOT               *root;
21 TX_BYTE_POOL                  memory_pool;
22 TX_THREAD                     demo_thread;
23 ULONG                         demo_thread_stack[1024];
24 
25 GX_VALUE language_count;
26 
27 
28 GX_LANGUAGE_HEADER language_info[8];
29 
30 /* reference the display table, theme table, and language table
31    produced by GUIX Studio
32 */
33 extern GX_STUDIO_DISPLAY_INFO demo_guix_binres_display_table[];
34 extern GX_CONST GX_THEME     *main_display_theme_table[];
35 extern GX_CONST GX_UBYTE    **main_display_language_table[];
36 
37 /* pointers which will be initialized when the binary resources
38    are installed
39 */
40 GX_THEME   *theme = GX_NULL;
41 GX_STRING **language_table = GX_NULL;
42 GX_UBYTE   *binres_root_address = GX_NULL;
43 GX_CHAR     binres_pathname[] = "..//..//demo_guix_binres_resources.bin";
44 
45 /* Define prototypes.   */
46 VOID demo_thread_entry(ULONG thread_input);
47 
48 #ifdef GX_TARGET_WIN32
49 extern UINT win32_graphics_driver_setup_565rgb(GX_DISPLAY *display);
50 GX_COLOR       default_canvas_memory[DEFAULT_CANVAS_PIXELS];
51 UCHAR          guix_pool_memory[GUIX_POOL_SIZE];
52 #endif
53 
54 #ifdef STM32F439xx
55 extern UINT  stm32f429_graphics_driver_setup_565rgb(GX_DISPLAY *graphic);
56 extern VOID  touch_thread_entry(ULONG thread_input);
57 
58 #define SDRAM _Pragma("location=\"SD_RAM\"")
59 SDRAM GX_COLOR default_canvas_memory[DEFAULT_CANVAS_PIXELS];
60 SDRAM UCHAR    guix_pool_memory[GUIX_POOL_SIZE];
61 TX_THREAD      touch_thread;
62 ULONG          touch_thread_stack[1024];
63 #endif
64 
65 /* local application function prototypes */
66 
67 VOID *load_binary_resource_data_to_ram();
68 UINT load_theme(GX_UBYTE *root_address, INT theme_id);
69 UINT load_language_table(GX_UBYTE *root_address);
70 
71 UINT load_language_info(GX_UBYTE *root_address, GX_LANGUAGE_HEADER *put_info);
72 UINT load_language_count(GX_UBYTE *root_address, GX_VALUE *put_count);
73 
74 
75 #ifdef STM32F439xx
76 /**
77   * @brief  System Clock Configuration
78   *         The system Clock is configured as follow :
79   *            System Clock source            = PLL (HSE)
80   *            SYSCLK(Hz)                     = 180000000
81   *            HCLK(Hz)                       = 180000000
82   *            AHB Prescaler                  = 1
83   *            APB1 Prescaler                 = 4
84   *            APB2 Prescaler                 = 2
85   *            HSE Frequency(Hz)              = 25000000
86   *            PLL_M                          = 25
87   *            PLL_N                          = 360
88   *            PLL_P                          = 2
89   *            PLL_Q                          = 7
90   *            VDD(V)                         = 3.3
91   *            Main regulator output voltage  = Scale1 mode
92   *            Flash Latency(WS)              = 5
93   * @param  None
94   * @retval None
95   */
SystemClock_Config(void)96 static void SystemClock_Config(void)
97 {
98     RCC_ClkInitTypeDef RCC_ClkInitStruct;
99     RCC_OscInitTypeDef RCC_OscInitStruct;
100 
101     /* Enable Power Control clock */
102     __HAL_RCC_PWR_CLK_ENABLE();
103 
104     /* The voltage scaling allows optimizing the power consumption when the device is
105     clocked below the maximum system frequency, to update the voltage scaling value
106     regarding system frequency refer to product datasheet.  */
107     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
108 
109     /* Enable HSE Oscillator and activate PLL with HSE as source */
110     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
111     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
112     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
113     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
114     RCC_OscInitStruct.PLL.PLLM = 25;
115     RCC_OscInitStruct.PLL.PLLN = 360;
116     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
117     RCC_OscInitStruct.PLL.PLLQ = 7;
118     HAL_RCC_OscConfig(&RCC_OscInitStruct);
119 
120     /* Activate the Over-Drive mode */
121     HAL_PWREx_EnableOverDrive();
122 
123     /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
124     clocks dividers */
125     RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
126     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
127     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
128     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
129     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
130     HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
131 }
132 #endif
133 
134 /************************************************************************************/
135 /*  User defined memory allocate function.                                          */
136 /************************************************************************************/
memory_allocate(ULONG size)137 VOID *memory_allocate(ULONG size)
138 {
139     VOID *memptr;
140 
141     if (tx_byte_allocate(&memory_pool, &memptr, size, TX_NO_WAIT) == TX_SUCCESS)
142     {
143         return memptr;
144     }
145 
146     return NULL;
147 }
148 
149 /************************************************************************************/
150 /*  User defined memory free function.                                              */
151 /************************************************************************************/
memory_free(VOID * mem)152 VOID memory_free(VOID *mem)
153 {
154     tx_byte_release(mem);
155 }
156 
157 /************************************************************************************/
158 /*  Program entry.                                                                  */
159 /************************************************************************************/
main(int argc,char ** argv)160 int main(int argc, char ** argv)
161 {
162 #ifdef STM32F439xx
163     /* STM32F4xx HAL library initialization */
164     HAL_Init();
165 
166     /* Configure the system clock to 180 MHz */
167     SystemClock_Config();
168 
169     BSP_NOR_Init();
170 #endif
171 
172     /* Enter the ThreadX kernel. */
173     tx_kernel_enter();
174     return(0);
175 }
176 
177 /************************************************************************************/
178 /*  Define system initialization.                                                   */
179 /************************************************************************************/
tx_application_define(void * first_unused_memory)180 VOID tx_application_define(void *first_unused_memory)
181 {
182       tx_thread_create(&demo_thread, "Demo Thread", demo_thread_entry, 0,
183                        demo_thread_stack, sizeof(demo_thread_stack),
184                        GX_SYSTEM_THREAD_PRIORITY + 1,
185                        GX_SYSTEM_THREAD_PRIORITY + 1, TX_NO_TIME_SLICE, TX_AUTO_START);
186 
187 #ifdef STM32F439xx
188       tx_thread_create(&touch_thread, "Touch Thread", touch_thread_entry, 0,
189                        touch_thread_stack, sizeof(touch_thread_stack),
190                        GX_SYSTEM_THREAD_PRIORITY + 1,
191                        GX_SYSTEM_THREAD_PRIORITY + 1, TX_NO_TIME_SLICE, TX_AUTO_START);
192 #endif
193 }
194 
demo_thread_entry(ULONG thread_input)195 VOID demo_thread_entry(ULONG thread_input)
196 {
197       /* Initialize GUIX.  */
198     gx_system_initialize();
199 
200     /* Set memory alloc/free functions. */
201     gx_system_memory_allocator_set(memory_allocate, memory_free);
202 
203     /* Create a display driver based on the target platform */
204 #if defined(GX_TARGET_WIN32)
205     /* Configure display. */
206     gx_studio_display_configure(MAIN_DISPLAY, win32_graphics_driver_setup_565rgb,
207         LANGUAGE_ENGLISH, MAIN_DISPLAY_THEME_1, &root);
208 #elif defined(STM32F439xx)
209     gx_studio_display_configure(MAIN_DISPLAY, stm32f429_graphics_driver_setup_565rgb,
210         LANGUAGE_ENGLISH, MAIN_DISPLAY_THEME_1, &root);
211 #endif
212 
213     /* initialize the canvas memory pointer (not allocated by Studio) */
214 
215 #if defined(GX_TARGET_WIN32) || defined(STM_32F439xx)
216     root -> gx_window_root_canvas->gx_canvas_memory = default_canvas_memory;
217 
218     /* Create byte pool. */
219     tx_byte_pool_create(&memory_pool, "guix_pool_memory", guix_pool_memory, GUIX_POOL_SIZE);
220 #endif
221 
222 #ifdef GX_TARGET_WIN32
223     /* Load binary resource file into ram. */
224     /* This suit the case that we generated a .bin format resource file. */
225     binres_root_address = load_binary_resource_data_to_ram();
226 #endif
227 
228 #ifdef STM32F439xx
229     /* Specify address that binary resource data is loated. */
230     /* This suit the case that we generate a .srec format resource file. */
231     /* .srec file should be programed to the target device memory first. */
232     binres_root_address = (GX_UBYTE *)0x60000000;
233 #endif
234 
235     /* Load language table. */
236     load_language_table(binres_root_address);
237 
238     /* Load theme table. */
239     load_theme(binres_root_address, 0);
240 
241     /* Create the "simple_window" screen. */
242     gx_studio_named_widget_create("simple_window", (GX_WIDGET *)root, GX_NULL);
243 
244     gx_binres_language_count_get(binres_root_address, &language_count);
245     gx_binres_language_info_load(binres_root_address, language_info);
246 
247     /* Show the root window to make "simple_window" screen visible.  */
248     gx_widget_show(root);
249 
250     /* Start GUIX thread */
251     gx_system_start();
252 }
253 
254 /************************************************************************************/
255 /*  Override default event processing of "simple_window" to handle signals from     */
256 /*  child widgets.                                                                  */
257 /************************************************************************************/
simple_window_event_handler(GX_WINDOW * widget,GX_EVENT * event_ptr)258 UINT simple_window_event_handler(GX_WINDOW *widget, GX_EVENT *event_ptr)
259 {
260     switch (event_ptr->gx_event_type)
261     {
262     case GX_SIGNAL(ID_THEME_1, GX_EVENT_RADIO_SELECT):
263         /* Load first theme from generated binary resource data. */
264         load_theme(binres_root_address, 0);
265         break;
266 
267     case GX_SIGNAL(ID_THEME_2, GX_EVENT_RADIO_SELECT):
268         /* Load second theme from generated binary resource data. */
269         load_theme(binres_root_address, 1);
270         break;
271 
272     case GX_SIGNAL(ID_ENGLISH, GX_EVENT_RADIO_SELECT):
273         /* Set action language to English. */
274         gx_system_active_language_set(LANGUAGE_ENGLISH);
275         break;
276 
277     case GX_SIGNAL(ID_SPANISH, GX_EVENT_RADIO_SELECT):
278         /* Set active language to Spanish. */
279         gx_system_active_language_set(LANGUAGE_SPANISH);
280         break;
281 
282     default:
283         /* for all other events, allow the default event
284            processor to run
285         */
286         return gx_window_event_process(widget, event_ptr);
287     }
288 
289     return 0;
290 }
291 
292 /************************************************************************************/
293 /*  Load binary resource data into ram.                                             */
294 /*  This is an example of how an application might load a binary resource data
295     file to RAM (or FLASH) from a local filesystem. In this case we are using generic ANSI
296     file I/O to read the resource data file.
297 
298     Note that for a typical embedded target, this step is not required. For most
299     targets, the binary resource data has been directly programmed to FLASH rather
300     than saved in a filesytem.
301 */
302 /************************************************************************************/
load_binary_resource_data_to_ram()303 VOID *load_binary_resource_data_to_ram()
304 {
305 UCHAR *address = GX_NULL;
306 
307     /* If generated resource is stored in a FAT filesystem, it must be
308        loaded into memory before it can be used. This memory could be
309        RAM or FLASH, but for the purpose of this example will simply
310        read the file to RAM. */
311     FILE *p_file;
312     size_t total_length;
313 
314     p_file = fopen(binres_pathname, "rb");
315 
316     if (p_file)
317     {
318         fseek(p_file, 0, SEEK_END);
319         total_length = ftell(p_file);
320         fseek(p_file, SEEK_SET, SEEK_SET);
321 
322         address = memory_allocate(total_length);
323         fread(address, 1, total_length, p_file);
324 
325         fclose(p_file);
326     }
327 
328     return address;
329 }
330 
331 /************************************************************************************/
332 /*  Load a theme.                                                                   */
333 /************************************************************************************/
load_theme(GX_UBYTE * root_address,INT theme_id)334 UINT load_theme(GX_UBYTE *root_address, INT theme_id)
335 {
336 UINT  status = GX_SUCCESS;
337 
338     if (theme)
339     {
340         memory_free(theme);
341         theme = GX_NULL;
342     }
343 
344     /* Load a theme from binary data memory. */
345     status = gx_binres_theme_load(root_address,/* Address of binary resource data. */
346                                   theme_id,    /* Theme identification, 0, 1, 2: 1th, 2nd, 3rd theme in the binary resource data. */
347                                   &theme);     /* Loaded theme. */
348 
349     if (status == GX_SUCCESS)
350     {
351         /* Install themes to specified display. */
352         gx_display_theme_install(demo_guix_binres_display_table[MAIN_DISPLAY].display, theme);
353     }
354 
355     return status;
356 }
357 
358 /************************************************************************************/
359 /*  Load language table.                                                            */
360 /************************************************************************************/
load_language_table(GX_UBYTE * root_address)361 UINT load_language_table(GX_UBYTE *root_address)
362 {
363 UINT  status = GX_SUCCESS;
364 
365     if (language_table)
366     {
367         memory_free(language_table);
368         language_table = GX_NULL;
369     }
370 
371     /* Load language table from binary data memory. */
372     status = gx_binres_language_table_load_ext(root_address,     /* Address of binary resource data. */
373                                               &language_table); /* Loaded language table that contains all languages in the specified binary resource data. */
374 
375     if (language_table)
376     {
377         /* Set language table. */
378         gx_display_language_table_set_ext(root->gx_window_root_canvas->gx_canvas_display, (GX_CONST GX_STRING **)language_table, MAIN_DISPLAY_LANGUAGE_TABLE_SIZE, MAIN_DISPLAY_STRING_TABLE_SIZE);
379 
380         /* Set active language. */
381         gx_system_active_language_set(LANGUAGE_ENGLISH);
382     }
383     return status;
384 }
385