Arm-2D  
2D Image Processing Library for Cortex-M Processors
arm_2d_helper.h
1/*
2 * Copyright (C) 2022 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: Arm-2D Library
21 * Title: #include "arm_2d_helper.h"
22 * Description: Public header file for the all helper services
23 *
24 * $Date: 25. Nov 2024
25 * $Revision: V.2.2.1
26 *
27 * Target Processor: Cortex-M cores
28 * -------------------------------------------------------------------- */
29
30#ifndef __ARM_2D_HELPER_H__
31#define __ARM_2D_HELPER_H__
32
33/*============================ INCLUDES ======================================*/
34#include "arm_2d.h"
35#include "./__arm_2d_helper_common.h"
36#include "./arm_2d_helper_pfb.h"
37#include "./arm_2d_helper_scene.h"
38#include "./arm_2d_disp_adapters.h"
39#include "./arm_2d_helper_list.h"
40#include "./arm_2d_helper_shape.h"
41#include "./arm_2d_helper_font.h"
42#include "./arm_2d_helper_control.h"
43
44//#include "./arm_2d_helper_map.h"
45
46
47#include <stdlib.h>
48#include <assert.h>
49
50#ifdef __cplusplus
51extern "C" {
52#endif
53
54#if defined(__clang__)
55# pragma clang diagnostic push
56# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
57# pragma clang diagnostic ignored "-Wunused-function"
58# pragma clang diagnostic ignored "-Wmissing-declarations"
59# pragma clang diagnostic ignored "-Wpadded"
60#elif defined(__IS_COMPILER_ARM_COMPILER_5__)
61# pragma diag_suppress 64
62#endif
63
64
65/* OOC header, please DO NOT modify */
66#ifdef __ARM_2D_HELPER_IMPLEMENT__
67# define __ARM_2D_IMPL__
68#elif defined(__ARM_2D_HELPER_INHERIT__)
69# define __ARM_2D_INHERIT__
70#endif
71#include "arm_2d_utils.h"
72
73/*!
74 * \addtogroup Deprecated
75 * @{
76 */
77#define arm_2d_draw_box arm_2d_helper_draw_box
78/*! @} */
79
80/*!
81 * \addtogroup gHelper 8 Helper Services
82 * @{
83 */
84/*============================ MACROS ========================================*/
85/*============================ MACROFIED FUNCTIONS ===========================*/
86
87/*!
88 * \brief set an alarm with given period and check the status
89 *
90 * \param[in] __ms a time period in millisecond
91 * \param[in] ... an optional timestamp holder
92 *
93 * \return bool whether it is timeout
94 */
95#define arm_2d_helper_is_time_out(__ms, ...) \
96 ({ static int64_t arm_2d_safe_name(s_lTimestamp); \
97 __arm_2d_helper_is_time_out(arm_2d_helper_convert_ms_to_ticks(__ms), \
98 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
99
100
101#define arm_2d_helper_time_elapsed(__timestamp_ptr) \
102 arm_2d_helper_convert_ticks_to_ms( \
103 __arm_2d_helper_time_elapsed(__timestamp_ptr))
104
105/*!
106 * \brief calculate the stroke of a liner slider based on time
107 *
108 * \param[in] __from the start of the slider
109 * \param[in] __to the end of the slider
110 * \param[in] __ms a given period (ms) in which the slider should finish the
111 * whole stroke
112 * \param[out] __stroke_ptr the address of an int32_t stroke variable
113 * \param[in] ... an optional address of a timestamp variable, if you omit it,
114 * NULL will be passed, and the code that call this funtion will not
115 * be reentrant.
116 * \retval true the slider has finished the whole stroke
117 * \retval false the slider hasn't reach the target end
118 */
119#define arm_2d_helper_time_liner_slider( __from, \
120 __to, \
121 __ms, \
122 __stroke_ptr, \
123 ...) \
124 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
125 __arm_2d_helper_time_liner_slider((__from), \
126 (__to), \
127 arm_2d_helper_convert_ms_to_ticks(__ms), \
128 (__stroke_ptr), \
129 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
130
131/*!
132 * \brief calculate the stroke of a cosine slider based on time
133 *
134 * \param[in] __from the start of the slider
135 * \param[in] __to the end of the slider
136 * \param[in] __ms a given period (ms) in which the slider should finish the
137 * whole stroke
138 * \param[in] __phase the phase offset
139 * \param[out] __stroke_ptr the address of an int32_t stroke variable
140 * \param[in] ... an optional address of a timestamp variable, if you omit it,
141 * NULL will be passed, and the code that call this funtion will not
142 * be reentrant.
143 * \retval true the slider has finished the whole stroke
144 * \retval false the slider hasn't reach the target end
145 */
146#define arm_2d_helper_time_cos_slider( __from, \
147 __to, \
148 __ms, \
149 __phase, \
150 __stroke_ptr, \
151 ...) \
152 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
153 __arm_2d_helper_time_cos_slider((__from), \
154 (__to), \
155 arm_2d_helper_convert_ms_to_ticks(__ms), \
156 (__phase), \
157 (__stroke_ptr), \
158 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
159
160/*!
161 * \brief calculate the stroke of a cosine slider(0~pi) based on time
162 *
163 * \param[in] __from the start of the slider
164 * \param[in] __to the end of the slider
165 * \param[in] __ms a given period (ms) in which the slider should finish the
166 * whole stroke
167 * \param[out] __stroke_ptr the address of an int32_t stroke variable
168 * \param[in] ... an optional address of a timestamp variable, if you omit it,
169 * NULL will be passed, and the code that call this funtion will not
170 * be reentrant.
171 * \retval true the slider has finished the whole stroke
172 * \retval false the slider hasn't reach the target end
173 */
174#define arm_2d_helper_time_half_cos_slider( __from, \
175 __to, \
176 __ms, \
177 __stroke_ptr, \
178 ...) \
179 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
180 __arm_2d_helper_time_half_cos_slider((__from), \
181 (__to), \
182 arm_2d_helper_convert_ms_to_ticks(__ms), \
183 (__stroke_ptr), \
184 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
185
186
187/*!
188 * \brief initialize/implement a given film (arm_2d_helper_file_t) object
189 * at compile-time.
190 * \param[in] __sprites_tile the sprites tile
191 * \param[in] __width the width of each frame
192 * \param[in] __height the height of each frame
193 * \param[in] __column the number of frames per row in the sprite tile
194 * \param[in] __frame_count the total number of frames in the sprite tile
195 * \param[in] __period the period per-frame
196 * \note __period is used as a reference for applications. The helper service
197 * doesn't use it at all.
198 */
199#define impl_film( __sprites_tile, \
200 __width, \
201 __height, \
202 __column, \
203 __frame_count, \
204 __period) \
205 { \
206 .use_as__arm_2d_tile_t = \
207 impl_child_tile((__sprites_tile), 0, 0, (__width), (__height)), \
208 .hwColumn = (__column), \
209 .hwFrameNum = (__frame_count), \
210 .hwPeriodPerFrame = (__period), \
211 }
212
213/*============================ TYPES =========================================*/
214
215/*!
216 * \brief a helper class to represent a GIF-like resource
217 */
218typedef struct arm_2d_helper_film_t {
219 implement(arm_2d_tile_t); /*!< derived from arm_2d_tile_t */
220 uint16_t hwColumn; /*!< number of frames per row in a sprite tile */
221 uint16_t hwFrameNum; /*!< the total number of frames */
222 uint16_t hwPeriodPerFrame; /*!< the period per frame (optional, used as a reference) */
223 uint16_t hwFrameIndex; /*!< the frame index used at runtime */
225
227 uint16_t hwPointer;
228 uint16_t hwDataAvailable;
229};
230
231typedef struct arm_2d_byte_fifo_t {
232ARM_PROTECTED (
233 uint8_t *pchBuffer;
234 uint16_t hwSize;
235 uint16_t hwTail;
236
237 struct __arm_2d_fifo_reader_pointer tHead;
238 struct __arm_2d_fifo_reader_pointer tPeek;
239)
241
242/*============================ GLOBAL VARIABLES ==============================*/
243/*============================ LOCAL VARIABLES ===============================*/
244/*============================ PROTOTYPES ====================================*/
245
246/*!
247 * \brief initialize helper services
248 */
249extern
251
252/*!
253 * \brief backend task for asynchronose mode
254 */
255extern
257
258/*!
259 * \brief convert ticks of a reference timer to millisecond
260 *
261 * \param[in] lTick the tick count
262 * \return int64_t the millisecond
263 */
264extern
266
267/*!
268 * \brief convert millisecond into ticks of the reference timer
269 *
270 * \param[in] wMS the target time in millisecond
271 * \return int64_t the ticks
272 */
273extern
275
276/*!
277 * \brief get the reference clock frequency
278 * \return uint32_t the frequency
279 */
280extern
282
283/*!
284 * \brief get the current system stamp from the reference clock
285 *
286 * \return int64_t the timestamp in ticks
287 * \note you have to call arm_2d_helper_convert_ticks_to_ms() to convert the
288 * the timestamp into milliseconds when required.
289 */
290extern
292
293/*!
294 * \brief get the elapsed time since a reference timestamp
295 * \param[in] plTimestamp the reference timestamp
296 * \return int64_t the timestamp in ticks
297 */
298extern
299ARM_NONNULL(1)
300int64_t __arm_2d_helper_time_elapsed(int64_t *plTimestamp);
301
302/*!
303 * \brief set an alarm with given period and check the status
304 *
305 * \param[in] lPeriod a time period in ticks
306 * \param[in] plTimestamp a pointer points to an int64_t integer, if NULL is
307 * passed, an static local variable inside the function will be used
308 * \return bool whether it is timeout or not
309 */
310ARM_NONNULL(2)
311extern
312bool __arm_2d_helper_is_time_out(int64_t lPeriod, int64_t *plTimestamp);
313
314/*!
315 * \brief get a new semaphore from host RTOS
316 * \return uintptr_t a handler for the semaphore
317 */
318extern
320
321/*!
322 * \brief free a semaphore
323 * \param[in] pSemaphore the target semaphore
324 */
325extern
326void arm_2d_port_free_semaphore(uintptr_t pSemaphore);
327
328/*!
329 * \brief wait for a semaphore
330 * \param[in] pSemaphore the target semaphore
331 * \retval true we get the semaphore
332 * \retval false we haven't get the sempahore
333 */
334extern
335bool arm_2d_port_wait_for_semaphore(uintptr_t pSemaphore);
336
337/*!
338 * \brief set a semaphore
339 * \param[in] pSemaphore the target semaphore
340 */
341extern
342void arm_2d_port_set_semaphore(uintptr_t pSemaphore);
343
344/*!
345 * \brief calculate the stroke of a liner slider based on time
346 *
347 * \param[in] nFrom the start of the slider
348 * \param[in] nTo the end of the slider
349 * \param[in] lPeriod a given period in which the slider should finish the whole
350 * stroke
351 * \param[out] pnStroke the address of an int32_t stroke variable
352 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
353 * the code that call this funtion will not be reentrant.
354 * \retval true the slider has finished the whole stroke
355 * \retval false the slider hasn't reach the target end
356 */
357ARM_NONNULL(4,5)
358extern
360 int32_t nTo,
361 int64_t lPeriod,
362 int32_t *pnStroke,
363 int64_t *plTimestamp);
364
365/*!
366 * \brief calculate the stroke of a cosine slider (0~pi) based on time
367 *
368 * \param[in] nFrom the start of the slider
369 * \param[in] nTo the end of the slider
370 * \param[in] lPeriod a given period in which the slider should finish the whole
371 * stroke
372 * \param[out] pnStroke the address of an int32_t stroke variable
373 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
374 * the code that call this funtion will not be reentrant.
375 * \retval true the slider has finished the whole stroke
376 * \retval false the slider hasn't reach the target end
377 */
378ARM_NONNULL(4,5)
379extern
381 int32_t nTo,
382 int64_t lPeriod,
383 int32_t *pnStroke,
384 int64_t *plTimestamp);
385
386/*!
387 * \brief calculate the stroke of a consine slider (0~2pi) based on time
388 *
389 * \param[in] nFrom the start of the slider
390 * \param[in] nTo the end of the slider
391 * \param[in] lPeriod a given period in which the slider should finish the whole
392 * stroke
393 * \param[in] lPhase the phase offset
394 * \param[out] pnStroke the address of an int32_t stroke variable
395 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
396 * the code that call this funtion will not be reentrant.
397 * \retval true the slider has finished the whole stroke
398 * \retval false the slider hasn't reach the target end
399 */
400ARM_NONNULL(5,6)
401extern
403 int32_t nTo,
404 int64_t lPeriod,
405 float fPhase,
406 int32_t *pnStroke,
407 int64_t *plTimestamp);
408
409/*!
410 * \brier colour intrapolation
411 * \param[in] wFrom a 32bit colour (4 8bit colour channels) on the start
412 * \param[in] wTo a 32bit colour (4 8bit colour channels) on the end
413 * \param[in] nDistance the reference full distance between two end points
414 * \param[in] nOffset the offset from the start
415 * \return uint32_t 32bit colour
416 */
417extern
418uint32_t __arm_2d_helper_colour_slider( uint32_t wFrom,
419 uint32_t wTo,
420 int32_t nDistance,
421 int32_t nOffset);
422
423/*!
424 * \brier draw a box with specified colour, border width and opacity
425 * \param[in] ptTarget the target tile
426 * \param[in] ptRegion the target region
427 * \param[in] iBorderWidth the border width
428 * \param[in] tColour the target colour
429 * \param[in] chOpacity the opacity
430 */
431extern
433 const arm_2d_region_t *ptRegion,
434 int16_t iBorderWidth,
435 COLOUR_INT tColour,
436 uint8_t chOpacity);
437
438/*!
439 * \brier move to the next frame of a given film
440 * \param[in] ptThis the target film
441 */
442extern
443ARM_NONNULL(1)
445
446/*!
447 * \brier reset the frame index to zero
448 * \param[in] ptThis the target film
449 */
450extern
451ARM_NONNULL(1)
453
454/*!
455 * \brier reset the frame index to a specified value and wrap around if the
456 * index number is out of range.
457 * \param[in] ptThis the target film
458 * \param[in] nIndex the given index
459 */
460extern
461ARM_NONNULL(1)
463
464/*----------------------------------------------------------------------------*
465 * FIFO Helper Service *
466 *----------------------------------------------------------------------------*/
467
468/*!
469 * \brief initialize a given byte fifo
470 * \param[in] ptThis the target FIFO control block
471 * \param[in] pBuffer a buffer for storing the data
472 * \param[in] hwSize the buffer size
473 * \retval false Illegal parameters
474 * \retval true the target FIFO is initialized
475 */
476extern
477ARM_NONNULL(1,2)
479 void *pBuffer,
480 uint16_t hwSize);
481
482/*!
483 * \brief Empty a given byte fifo
484 * \param[in] ptThis the target byte fifo
485 */
486extern
487ARM_NONNULL(1)
489
490/*!
491 * \brief write a byte to a given fifo
492 * \param[in] ptThis the target FIFO control block
493 * \param[in] chChar the target byte
494 * \retval false the FIFO is FULL
495 * \retval true operation is successful
496 */
497extern
498ARM_NONNULL(1)
499bool arm_2d_byte_fifo_enqueue(arm_2d_byte_fifo_t *ptThis, uint8_t chChar);
500
501/*!
502 * \brief read a byte from a given fifo
503 * \param[in] ptThis the target FIFO control block
504 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
505 * \retval false the FIFO is EMPTY
506 * \retval true operation is successful
507 */
508extern
509ARM_NONNULL(1)
510bool arm_2d_byte_fifo_dequeue(arm_2d_byte_fifo_t *ptThis, uint8_t *pchChar);
511
512/*!
513 * \brief peek a byte continuously from a given fifo
514 * \param[in] ptThis the target FIFO control block
515 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
516 * \retval false the FIFO is EMPTY
517 * \retval true operation is successful
518 */
519extern
520ARM_NONNULL(1)
522 uint8_t *pchChar,
523 bool bMovePointer);
524
525/*!
526 * \brief drop all peeked byte from a given fifo
527 * \param[in] ptThis the target FIFO control block
528 * \return none
529 */
530extern
531ARM_NONNULL(1)
533
534/*!
535 * \brief reset the peek pointer, so you can restart from the beginning to peek.
536 * \param[in] ptThis the target FIFO control block
537 * \return none
538 */
539ARM_NONNULL(1)
541
542/*----------------------------------------------------------------------------*
543 * Misc *
544 *----------------------------------------------------------------------------*/
545
546/*!
547 * \brief swap the high and low bytes for each rgb16 pixel
548 *
549 * \param[in] phwBuffer the pixel buffer
550 * \note the phwBuffer MUST aligned to half-word addresses
551 *
552 * \param[in] wSize the number of pixels
553 */
554extern
555void arm_2d_helper_swap_rgb16(uint16_t *phwBuffer, uint32_t wCount);
556
557extern
558ARM_NONNULL(1)
559/*!
560 * \brief fill the target tile with a specified colour
561 *
562 * \param[in] ptTile the target tile
563 * \param[in] tColourFormat the colour format of the target tile
564 * \param[in] tColour the target colour
565 */
567 arm_2d_color_info_t tColourFormat,
568 arm_2d_colour_t tColour);
569
570#if __ARM_2D_HELPER_CFG_LAYOUT_DEBUG_MODE__
571extern
572ARM_NONNULL(1)
573void __arm_2d_helper_layout_debug_print_label(const arm_2d_tile_t *ptTile,
574 arm_2d_region_t *ptRegion,
575 const char *pchString);
576#endif
577
578/*! @} */
579
580/*============================ INCLUDES ======================================*/
581#include "arm_2d_helper_built_in.h"
582
583#if defined(__clang__)
584# pragma clang diagnostic pop
585#elif __IS_COMPILER_ARM_COMPILER_5__
586#pragma diag_warning 64
587#endif
588
589#undef __ARM_2D_HELPER_IMPLEMENT__
590#undef __ARM_2D_HELPER_INHERIT__
591
592
593#ifdef __cplusplus
594}
595#endif
596
597#endif