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