Arm-2D  
2D Image Processing Library for Cortex-M Processors
 
Loading...
Searching...
No Matches
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: 9. July 2025
25 * $Revision: V.2.4.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 liner 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[out] __stroke_ptr the address of an int32_t stroke variable
139 * \param[in] ... an optional address of a timestamp variable, if you omit it,
140 * NULL will be passed, and the code that call this funtion will not
141 * be reentrant.
142 * \retval true the slider has finished the whole stroke
143 * \retval false the slider hasn't reach the target end
144 */
145#define arm_2d_helper_time_liner_slider_i64( __from, \
146 __to, \
147 __ms, \
148 __stroke_ptr, \
149 ...) \
150 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
151 __arm_2d_helper_time_liner_slider_i64( (__from), \
152 (__to), \
153 arm_2d_helper_convert_ms_to_ticks(__ms), \
154 (__stroke_ptr), \
155 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
156
157/*!
158 * \brief calculate the stroke of a cosine slider based on time
159 *
160 * \param[in] __from the start of the slider
161 * \param[in] __to the end of the slider
162 * \param[in] __ms a given period (ms) in which the slider should finish the
163 * whole stroke
164 * \param[in] __phase the phase offset
165 * \param[out] __stroke_ptr the address of an int32_t stroke variable
166 * \param[in] ... an optional address of a timestamp variable, if you omit it,
167 * NULL will be passed, and the code that call this funtion will not
168 * be reentrant.
169 * \retval true the slider has finished the whole stroke
170 * \retval false the slider hasn't reach the target end
171 */
172#define arm_2d_helper_time_cos_slider( __from, \
173 __to, \
174 __ms, \
175 __phase, \
176 __stroke_ptr, \
177 ...) \
178 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
179 __arm_2d_helper_time_cos_slider((__from), \
180 (__to), \
181 arm_2d_helper_convert_ms_to_ticks(__ms), \
182 (__phase), \
183 (__stroke_ptr), \
184 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
185
186/*!
187 * \brief calculate the stroke of a cosine slider(0~pi) based on time
188 *
189 * \param[in] __from the start of the slider
190 * \param[in] __to the end of the slider
191 * \param[in] __ms a given period (ms) in which the slider should finish the
192 * whole stroke
193 * \param[out] __stroke_ptr the address of an int32_t stroke variable
194 * \param[in] ... an optional address of a timestamp variable, if you omit it,
195 * NULL will be passed, and the code that call this funtion will not
196 * be reentrant.
197 * \retval true the slider has finished the whole stroke
198 * \retval false the slider hasn't reach the target end
199 */
200#define arm_2d_helper_time_half_cos_slider( __from, \
201 __to, \
202 __ms, \
203 __stroke_ptr, \
204 ...) \
205 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
206 __arm_2d_helper_time_half_cos_slider((__from), \
207 (__to), \
208 arm_2d_helper_convert_ms_to_ticks(__ms), \
209 (__stroke_ptr), \
210 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
211
212
213/*!
214 * \brief initialize/implement a given film (arm_2d_helper_file_t) object
215 * at compile-time.
216 * \param[in] __sprites_tile the sprites tile
217 * \param[in] __width the width of each frame
218 * \param[in] __height the height of each frame
219 * \param[in] __column the number of frames per row in the sprite tile
220 * \param[in] __frame_count the total number of frames in the sprite tile
221 * \param[in] __period the period per-frame
222 * \note __period is used as a reference for applications. The helper service
223 * doesn't use it at all.
224 */
225#define impl_film( __sprites_tile, \
226 __width, \
227 __height, \
228 __column, \
229 __frame_count, \
230 __period) \
231 { \
232 .use_as__arm_2d_tile_t = \
233 impl_child_tile((__sprites_tile), 0, 0, (__width), (__height)), \
234 .hwColumn = (__column), \
235 .hwFrameNum = (__frame_count), \
236 .hwPeriodPerFrame = (__period), \
237 }
238
239/*============================ TYPES =========================================*/
240
241/*!
242 * \brief a helper class to represent a GIF-like resource
243 */
244typedef struct arm_2d_helper_film_t {
245 implement(arm_2d_tile_t); /*!< derived from arm_2d_tile_t */
246 uint16_t hwColumn; /*!< number of frames per row in a sprite tile */
247 uint16_t hwFrameNum; /*!< the total number of frames */
248 uint16_t hwPeriodPerFrame; /*!< the period per frame (optional, used as a reference) */
249 uint16_t hwFrameIndex; /*!< the frame index used at runtime */
251
253 uint16_t hwPointer;
254 uint16_t hwDataAvailable;
255};
256
257typedef struct arm_2d_byte_fifo_t {
258ARM_PROTECTED (
259 uint8_t *pchBuffer;
260 uint16_t hwSize;
261 uint16_t hwTail;
262
263 struct __arm_2d_fifo_reader_pointer tHead;
264 struct __arm_2d_fifo_reader_pointer tPeek;
265)
267
268/*============================ GLOBAL VARIABLES ==============================*/
269/*============================ LOCAL VARIABLES ===============================*/
270/*============================ PROTOTYPES ====================================*/
271
272/*!
273 * \brief initialize helper services
274 */
275extern
277
278/*!
279 * \brief backend task for asynchronose mode
280 */
281extern
283
284/*!
285 * \brief convert ticks of a reference timer to millisecond
286 *
287 * \param[in] lTick the tick count
288 * \return int64_t the millisecond
289 */
290extern
292
293/*!
294 * \brief convert millisecond into ticks of the reference timer
295 *
296 * \param[in] wMS the target time in millisecond
297 * \return int64_t the ticks
298 */
299extern
301
302/*!
303 * \brief get the reference clock frequency
304 * \return uint32_t the frequency
305 */
306extern
308
309/*!
310 * \brief get the current system stamp from the reference clock
311 *
312 * \return int64_t the timestamp in ticks
313 * \note you have to call arm_2d_helper_convert_ticks_to_ms() to convert the
314 * the timestamp into milliseconds when required.
315 */
316extern
318
319/*!
320 * \brief get the elapsed time since a reference timestamp
321 * \param[in] plTimestamp the reference timestamp
322 * \return int64_t the timestamp in ticks
323 */
324extern
325ARM_NONNULL(1)
326int64_t __arm_2d_helper_time_elapsed(int64_t *plTimestamp);
327
328/*!
329 * \brief set an alarm with given period and check the status
330 *
331 * \param[in] lPeriod a time period in ticks
332 * \param[in] plTimestamp a pointer points to an int64_t integer, if NULL is
333 * passed, an static local variable inside the function will be used
334 * \return bool whether it is timeout or not
335 */
336ARM_NONNULL(2)
337extern
338bool __arm_2d_helper_is_time_out(int64_t lPeriod, int64_t *plTimestamp);
339
340/*!
341 * \brief get a new semaphore from host RTOS
342 * \return uintptr_t a handler for the semaphore
343 */
344extern
346
347/*!
348 * \brief free a semaphore
349 * \param[in] pSemaphore the target semaphore
350 */
351extern
352void arm_2d_port_free_semaphore(uintptr_t pSemaphore);
353
354/*!
355 * \brief wait for a semaphore
356 * \param[in] pSemaphore the target semaphore
357 * \retval true we get the semaphore
358 * \retval false we haven't get the sempahore
359 */
360extern
361bool arm_2d_port_wait_for_semaphore(uintptr_t pSemaphore);
362
363/*!
364 * \brief set a semaphore
365 * \param[in] pSemaphore the target semaphore
366 */
367extern
368void arm_2d_port_set_semaphore(uintptr_t pSemaphore);
369
370/*!
371 * \brief calculate the stroke of a liner slider based on time
372 *
373 * \param[in] nFrom the start of the slider
374 * \param[in] nTo the end of the slider
375 * \param[in] lPeriod a given period in which the slider should finish the whole
376 * stroke
377 * \param[out] pnStroke the address of an int32_t stroke variable
378 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
379 * the code that call this funtion will not be reentrant.
380 * \retval true the slider has finished the whole stroke
381 * \retval false the slider hasn't reach the target end
382 */
383extern
384ARM_NONNULL(4,5)
386 int32_t nTo,
387 int64_t lPeriod,
388 int32_t *pnStroke,
389 int64_t *plTimestamp);
390
391/*!
392 * \brief calculate the stroke of a liner slider based on time
393 *
394 * \param[in] lFrom the start of the slider
395 * \param[in] lTo the end of the slider
396 * \param[in] lPeriod a given period in which the slider should finish the whole
397 * stroke
398 * \param[out] plStroke the address of an int32_t stroke variable
399 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
400 * the code that call this funtion will not be reentrant.
401 * \retval true the slider has finished the whole stroke
402 * \retval false the slider hasn't reach the target end
403 */
404extern
405ARM_NONNULL(4,5)
407 int64_t lTo,
408 int64_t lPeriod,
409 int64_t *plStroke,
410 int64_t *plTimestamp);
411
412/*!
413 * \brief calculate the stroke of a cosine slider (0~pi) based on time
414 *
415 * \param[in] nFrom the start of the slider
416 * \param[in] nTo the end of the slider
417 * \param[in] lPeriod a given period in which the slider should finish the whole
418 * stroke
419 * \param[out] pnStroke the address of an int32_t stroke variable
420 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
421 * the code that call this funtion will not be reentrant.
422 * \retval true the slider has finished the whole stroke
423 * \retval false the slider hasn't reach the target end
424 */
425ARM_NONNULL(4,5)
426extern
428 int32_t nTo,
429 int64_t lPeriod,
430 int32_t *pnStroke,
431 int64_t *plTimestamp);
432
433/*!
434 * \brief calculate the stroke of a consine slider (0~2pi) based on time
435 *
436 * \param[in] nFrom the start of the slider
437 * \param[in] nTo the end of the slider
438 * \param[in] lPeriod a given period in which the slider should finish the whole
439 * stroke
440 * \param[in] lPhase the phase offset
441 * \param[out] pnStroke the address of an int32_t stroke variable
442 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
443 * the code that call this funtion will not be reentrant.
444 * \retval true the slider has finished the whole stroke
445 * \retval false the slider hasn't reach the target end
446 */
447ARM_NONNULL(5,6)
448extern
450 int32_t nTo,
451 int64_t lPeriod,
452 float fPhase,
453 int32_t *pnStroke,
454 int64_t *plTimestamp);
455
456/*!
457 * \brier colour intrapolation
458 * \param[in] wFrom a 32bit colour (4 8bit colour channels) on the start
459 * \param[in] wTo a 32bit colour (4 8bit colour channels) on the end
460 * \param[in] nDistance the reference full distance between two end points
461 * \param[in] nOffset the offset from the start
462 * \return uint32_t 32bit colour
463 */
464extern
465uint32_t __arm_2d_helper_colour_slider( uint32_t wFrom,
466 uint32_t wTo,
467 int32_t nDistance,
468 int32_t nOffset);
469
470/*!
471 * \brier draw a box with specified colour, border width and opacity
472 * \param[in] ptTarget the target tile
473 * \param[in] ptRegion the target region
474 * \param[in] iBorderWidth the border width
475 * \param[in] tColour the target colour
476 * \param[in] chOpacity the opacity
477 */
478extern
480 const arm_2d_region_t *ptRegion,
481 int16_t iBorderWidth,
482 COLOUR_INT tColour,
483 uint8_t chOpacity);
484
485/*!
486 * \brier move to the next frame of a given film
487 * \param[in] ptThis the target film
488 * \return bool whether the film reaches the end or not
489 */
490extern
491ARM_NONNULL(1)
493
494/*!
495 * \brier reset the frame index to zero
496 * \param[in] ptThis the target film
497 */
498extern
499ARM_NONNULL(1)
501
502/*!
503 * \brier reset the frame index to a specified value and wrap around if the
504 * index number is out of range.
505 * \param[in] ptThis the target film
506 * \param[in] nIndex the given index
507 */
508extern
509ARM_NONNULL(1)
511
512/*----------------------------------------------------------------------------*
513 * FIFO Helper Service *
514 *----------------------------------------------------------------------------*/
515
516/*!
517 * \brief initialize a given byte fifo
518 * \param[in] ptThis the target FIFO control block
519 * \param[in] pBuffer a buffer for storing the data
520 * \param[in] hwSize the buffer size
521 * \retval false Illegal parameters
522 * \retval true the target FIFO is initialized
523 */
524extern
525ARM_NONNULL(1,2)
527 void *pBuffer,
528 uint16_t hwSize);
529
530/*!
531 * \brief Empty a given byte fifo
532 * \param[in] ptThis the target byte fifo
533 */
534extern
535ARM_NONNULL(1)
537
538/*!
539 * \brief write a byte to a given fifo
540 * \param[in] ptThis the target FIFO control block
541 * \param[in] chChar the target byte
542 * \retval false the FIFO is FULL
543 * \retval true operation is successful
544 */
545extern
546ARM_NONNULL(1)
547bool arm_2d_byte_fifo_enqueue(arm_2d_byte_fifo_t *ptThis, uint8_t chChar);
548
549/*!
550 * \brief read a byte from a given fifo
551 * \param[in] ptThis the target FIFO control block
552 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
553 * \retval false the FIFO is EMPTY
554 * \retval true operation is successful
555 */
556extern
557ARM_NONNULL(1)
558bool arm_2d_byte_fifo_dequeue(arm_2d_byte_fifo_t *ptThis, uint8_t *pchChar);
559
560/*!
561 * \brief peek a byte continuously from a given fifo
562 * \param[in] ptThis the target FIFO control block
563 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
564 * \retval false the FIFO is EMPTY
565 * \retval true operation is successful
566 */
567extern
568ARM_NONNULL(1)
570 uint8_t *pchChar,
571 bool bMovePointer);
572
573/*!
574 * \brief drop all peeked byte from a given fifo
575 * \param[in] ptThis the target FIFO control block
576 * \return none
577 */
578extern
579ARM_NONNULL(1)
581
582/*!
583 * \brief reset the peek pointer, so you can restart from the beginning to peek.
584 * \param[in] ptThis the target FIFO control block
585 * \return none
586 */
587ARM_NONNULL(1)
589
590/*----------------------------------------------------------------------------*
591 * Misc *
592 *----------------------------------------------------------------------------*/
593
594/*!
595 * \brief swap the high and low bytes for each rgb16 pixel
596 *
597 * \param[in] phwBuffer the pixel buffer
598 * \note the phwBuffer MUST aligned to half-word addresses
599 *
600 * \param[in] wSize the number of pixels
601 */
602extern
603void arm_2d_helper_swap_rgb16(uint16_t *phwBuffer, uint32_t wCount);
604
605extern
606ARM_NONNULL(1)
607/*!
608 * \brief fill the target tile with a specified colour
609 *
610 * \param[in] ptTile the target tile
611 * \param[in] tColourFormat the colour format of the target tile
612 * \param[in] tColour the target colour
613 */
615 arm_2d_color_info_t tColourFormat,
616 arm_2d_colour_t tColour);
617
618#if __ARM_2D_HELPER_CFG_LAYOUT_DEBUG_MODE__
619extern
620ARM_NONNULL(1)
621void __arm_2d_helper_layout_debug_print_label(const arm_2d_tile_t *ptTile,
622 arm_2d_region_t *ptRegion,
623 const char *pchString);
624#endif
625
626/*! @} */
627
628/*============================ INCLUDES ======================================*/
629#include "arm_2d_helper_built_in.h"
630
631#if defined(__clang__)
632# pragma clang diagnostic pop
633#elif __IS_COMPILER_ARM_COMPILER_5__
634#pragma diag_warning 64
635#endif
636
637#undef __ARM_2D_HELPER_IMPLEMENT__
638#undef __ARM_2D_HELPER_INHERIT__
639
640
641#ifdef __cplusplus
642}
643#endif
644
645#endif