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: 13. Feb 2026
25 * $Revision: V.2.5.5
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 .tTile = \
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 union {
246 arm_2d_tile_t tTile;
247 implement(arm_2d_tile_t); /*!< derived from arm_2d_tile_t */
248 };
249 uint16_t hwColumn; /*!< number of frames per row in a sprite tile */
250 uint16_t hwFrameNum; /*!< the total number of frames */
251 uint16_t hwPeriodPerFrame; /*!< the period per frame (optional, used as a reference) */
252 uint16_t hwFrameIndex; /*!< the frame index used at runtime */
254
256 uint16_t hwPointer;
257 uint16_t hwDataAvailable;
258};
259
260typedef struct arm_2d_byte_fifo_t {
261ARM_PROTECTED (
262 uint8_t *pchBuffer;
263 uint16_t hwSize;
264 uint16_t hwTail;
265
266 struct __arm_2d_fifo_reader_pointer tHead;
267 struct __arm_2d_fifo_reader_pointer tPeek;
270
271/*============================ GLOBAL VARIABLES ==============================*/
272/*============================ LOCAL VARIABLES ===============================*/
273/*============================ PROTOTYPES ====================================*/
274
275/*!
276 * \brief initialize helper services
277 */
278extern
280
281/*!
282 * \brief backend task for asynchronose mode
283 */
284extern
286
287/*!
288 * \brief convert ticks of a reference timer to millisecond
289 *
290 * \param[in] lTick the tick count
291 * \return int64_t the millisecond
292 */
293extern
295
296/*!
297 * \brief convert millisecond into ticks of the reference timer
298 *
299 * \param[in] lMS the target time in millisecond
300 * \return int64_t the ticks
301 */
302extern
304
305/*!
306 * \brief get the reference clock frequency
307 * \return uint32_t the frequency
308 */
309extern
311
312/*!
313 * \brief get the current system stamp from the reference clock
314 *
315 * \return int64_t the timestamp in ticks
316 * \note you have to call arm_2d_helper_convert_ticks_to_ms() to convert the
317 * the timestamp into milliseconds when required.
318 */
319extern
321
322/*!
323 * \brief get the elapsed time since a reference timestamp
324 * \param[in] plTimestamp the reference timestamp
325 * \return int64_t the timestamp in ticks
326 */
327extern
328ARM_NONNULL(1)
329int64_t __arm_2d_helper_time_elapsed(int64_t *plTimestamp);
330
331/*!
332 * \brief set an alarm with given period and check the status
333 *
334 * \param[in] lPeriod a time period in ticks
335 * \param[in] plTimestamp a pointer points to an int64_t integer, if NULL is
336 * passed, an static local variable inside the function will be used
337 * \return bool whether it is timeout or not
338 */
339ARM_NONNULL(2)
340extern
341bool __arm_2d_helper_is_time_out(int64_t lPeriod, int64_t *plTimestamp);
342
343/*!
344 * \brief get a new semaphore from host RTOS
345 * \return uintptr_t a handler for the semaphore
346 */
347extern
349
350/*!
351 * \brief free a semaphore
352 * \param[in] pSemaphore the target semaphore
353 */
354extern
355void arm_2d_port_free_semaphore(uintptr_t pSemaphore);
356
357/*!
358 * \brief wait for a semaphore
359 * \param[in] pSemaphore the target semaphore
360 * \retval true we get the semaphore
361 * \retval false we haven't get the sempahore
362 */
363extern
364bool arm_2d_port_wait_for_semaphore(uintptr_t pSemaphore);
365
366/*!
367 * \brief set a semaphore
368 * \param[in] pSemaphore the target semaphore
369 */
370extern
371void arm_2d_port_set_semaphore(uintptr_t pSemaphore);
372
373/*!
374 * \brief calculate the stroke of a liner slider based on time
375 *
376 * \param[in] nFrom the start of the slider
377 * \param[in] nTo the end of the slider
378 * \param[in] lPeriod a given period in which the slider should finish the whole
379 * stroke
380 * \param[out] pnStroke the address of an int32_t stroke variable
381 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
382 * the code that call this funtion will not be reentrant.
383 * \retval true the slider has finished the whole stroke
384 * \retval false the slider hasn't reach the target end
385 */
386extern
387ARM_NONNULL(4,5)
389 int32_t nTo,
390 int64_t lPeriod,
391 int32_t *pnStroke,
392 int64_t *plTimestamp);
393
394/*!
395 * \brief calculate the stroke of a liner slider based on time
396 *
397 * \param[in] lFrom the start of the slider
398 * \param[in] lTo the end of the slider
399 * \param[in] lPeriod a given period in which the slider should finish the whole
400 * stroke
401 * \param[out] plStroke the address of an int32_t stroke variable
402 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
403 * the code that call this funtion will not be reentrant.
404 * \retval true the slider has finished the whole stroke
405 * \retval false the slider hasn't reach the target end
406 */
407extern
408ARM_NONNULL(4,5)
410 int64_t lTo,
411 int64_t lPeriod,
412 int64_t *plStroke,
413 int64_t *plTimestamp);
414
415/*!
416 * \brief calculate the stroke of a cosine slider (0~pi) based on time
417 *
418 * \param[in] nFrom the start of the slider
419 * \param[in] nTo the end of the slider
420 * \param[in] lPeriod a given period in which the slider should finish the whole
421 * stroke
422 * \param[out] pnStroke the address of an int32_t stroke variable
423 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
424 * the code that call this funtion will not be reentrant.
425 * \retval true the slider has finished the whole stroke
426 * \retval false the slider hasn't reach the target end
427 */
428ARM_NONNULL(4,5)
429extern
431 int32_t nTo,
432 int64_t lPeriod,
433 int32_t *pnStroke,
434 int64_t *plTimestamp);
435
436/*!
437 * \brief calculate the stroke of a consine slider (0~2pi) based on time
438 *
439 * \param[in] nFrom the start of the slider
440 * \param[in] nTo the end of the slider
441 * \param[in] lPeriod a given period in which the slider should finish the whole
442 * stroke
443 * \param[in] lPhase the phase offset
444 * \param[out] pnStroke the address of an int32_t stroke variable
445 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
446 * the code that call this funtion will not be reentrant.
447 * \retval true the slider has finished the whole stroke
448 * \retval false the slider hasn't reach the target end
449 */
450ARM_NONNULL(5,6)
451extern
453 int32_t nTo,
454 int64_t lPeriod,
455 float fPhase,
456 int32_t *pnStroke,
457 int64_t *plTimestamp);
458
459/*!
460 * \brier colour intrapolation
461 * \param[in] wFrom a 32bit colour (4 8bit colour channels) on the start
462 * \param[in] wTo a 32bit colour (4 8bit colour channels) on the end
463 * \param[in] nDistance the reference full distance between two end points
464 * \param[in] nOffset the offset from the start
465 * \return uint32_t 32bit colour
466 */
467extern
468uint32_t __arm_2d_helper_colour_slider( uint32_t wFrom,
469 uint32_t wTo,
470 int32_t nDistance,
471 int32_t nOffset);
472
473/*!
474 * \brier draw a box with specified colour, border width and opacity
475 * \param[in] ptTarget the target tile
476 * \param[in] ptRegion the target region
477 * \param[in] iBorderWidth the border width
478 * \param[in] tColour the target colour
479 * \param[in] chOpacity the opacity
480 */
481extern
483 const arm_2d_region_t *ptRegion,
484 int16_t iBorderWidth,
485 COLOUR_INT tColour,
486 uint8_t chOpacity);
487
488/*!
489 * \brier move to the next frame of a given film
490 * \param[in] ptThis the target film
491 * \return bool whether the film reaches the end or not
492 */
493extern
494ARM_NONNULL(1)
496
497/*!
498 * \brier reset the frame index to zero
499 * \param[in] ptThis the target film
500 */
501extern
502ARM_NONNULL(1)
504
505/*!
506 * \brier reset the frame index to a specified value and wrap around if the
507 * index number is out of range.
508 * \param[in] ptThis the target film
509 * \param[in] nIndex the given index
510 */
511extern
512ARM_NONNULL(1)
514
515/*!
516 * \brief get the current frame index number
517 * \param[in] ptThis the target film
518 * \return uint_fast16_t the current index
519 */
520extern
521ARM_NONNULL(1)
523
524/*!
525 * \brief get the frame count
526 * \param[in] ptThis the target film
527 * \return uint_fast16_t the frame count
528 */
529extern
530ARM_NONNULL(1)
532/*----------------------------------------------------------------------------*
533 * FIFO Helper Service *
534 *----------------------------------------------------------------------------*/
535
536/*!
537 * \brief initialize a given byte fifo
538 * \param[in] ptThis the target FIFO control block
539 * \param[in] pBuffer a buffer for storing the data
540 * \param[in] hwSize the buffer size
541 * \retval false Illegal parameters
542 * \retval true the target FIFO is initialized
543 */
544extern
545ARM_NONNULL(1,2)
547 void *pBuffer,
548 uint16_t hwSize);
549
550/*!
551 * \brief Empty a given byte fifo
552 * \param[in] ptThis the target byte fifo
553 */
554extern
555ARM_NONNULL(1)
557
558/*!
559 * \brief write a byte to a given fifo
560 * \param[in] ptThis the target FIFO control block
561 * \param[in] chChar the target byte
562 * \retval false the FIFO is FULL
563 * \retval true operation is successful
564 */
565extern
566ARM_NONNULL(1)
567bool arm_2d_byte_fifo_enqueue(arm_2d_byte_fifo_t *ptThis, uint8_t chChar);
568
569/*!
570 * \brief remove a byte from the queue tail
571 * \param[in] ptThis the target FIFO control block
572 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
573 * \retval false the FIFO is EMPTY
574 * \retval true operation is successful
575 */
576extern
577ARM_NONNULL(1)
578bool arm_2d_byte_fifo_vomit(arm_2d_byte_fifo_t *ptThis, uint8_t *pchChar);
579
580/*!
581 * \brief enter a byte to the FIFO, if the FIFO is full, drop one from the FIFO
582 * \param[in] ptThis the target FIFO control block
583 * \param[in] chChar the target byte
584 */
585extern
586ARM_NONNULL(1)
587void arm_2d_byte_fifo_squeeze(arm_2d_byte_fifo_t *ptThis, uint8_t chChar);
588
589/*!
590 * \brief get the number of bytes available in the FIFO.
591 * \param[in] ptThis the target FIFO control block
592 * \return uint16_t the byte count
593 */
594ARM_NONNULL(1)
596
597/*!
598 * \brief get the depth of the FIFO
599 * \param[in] ptThis the target FIFO control block
600 * \return uint16_t the byte count
601 */
602extern
603ARM_NONNULL(1)
605
606/*
607 * \brief move the peek pointer with a given offset and mode
608 * \param[in] ptThis the target FIFO control block
609 * \param[in] iOffset the offset for a given mode
610 * \param[in] whence one of the seek mode: SEEK_SET, SEEK_END and SEEK_CUR
611 */
612ARM_NONNULL(1)
613int16_t arm_2d_byte_fifo_peek_seek( arm_2d_byte_fifo_t *ptThis,
614 int16_t iOffset,
615 int32_t whence);
616/*!
617 * \brief read a byte from a given fifo
618 * \param[in] ptThis the target FIFO control block
619 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
620 * \retval false the FIFO is EMPTY
621 * \retval true operation is successful
622 */
623extern
624ARM_NONNULL(1)
625bool arm_2d_byte_fifo_dequeue(arm_2d_byte_fifo_t *ptThis, uint8_t *pchChar);
626
627/*!
628 * \brief peek a byte continuously from a given fifo
629 * \param[in] ptThis the target FIFO control block
630 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
631 * \retval false the FIFO is EMPTY
632 * \retval true operation is successful
633 */
634extern
635ARM_NONNULL(1)
637 uint8_t *pchChar,
638 bool bMovePointer);
639
640/*!
641 * \brief peek a number of bytes from a given fifo
642 * \param[in] ptThis the target FIFO control block
643 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
644 * \return size_t the number of bytes actually read out
645 */
646extern
647ARM_NONNULL(1)
649 uint8_t *pchChar,
650 size_t tLength);
651
652/*!
653 * \brief drop all peeked byte from a given fifo
654 * \param[in] ptThis the target FIFO control block
655 * \return none
656 */
657extern
658ARM_NONNULL(1)
660
661/*!
662 * \brief reset the peek pointer, so you can restart from the beginning to peek.
663 * \param[in] ptThis the target FIFO control block
664 * \return none
665 */
666ARM_NONNULL(1)
668
669/*----------------------------------------------------------------------------*
670 * Misc *
671 *----------------------------------------------------------------------------*/
672
673/*!
674 * \brief swap the high and low bytes for each rgb16 pixel
675 *
676 * \param[in] phwBuffer the pixel buffer
677 * \note the phwBuffer MUST aligned to half-word addresses
678 *
679 * \param[in] wSize the number of pixels
680 */
681extern
682void arm_2d_helper_swap_rgb16(uint16_t *phwBuffer, uint32_t wCount);
683
684extern
685ARM_NONNULL(1)
686/*!
687 * \brief fill the target tile with a specified colour
688 *
689 * \param[in] ptTile the target tile
690 * \param[in] tColourFormat the colour format of the target tile
691 * \param[in] tColour the target colour
692 */
694 arm_2d_color_info_t tColourFormat,
695 arm_2d_colour_t tColour);
696
697#if __ARM_2D_HELPER_CFG_LAYOUT_DEBUG_MODE__
698extern
699ARM_NONNULL(1)
700void __arm_2d_helper_layout_debug_print_label(const arm_2d_tile_t *ptTile,
701 arm_2d_region_t *ptRegion,
702 const char *pchString);
703#endif
704
705/*! @} */
706
707/*============================ INCLUDES ======================================*/
708#include "arm_2d_helper_built_in.h"
709
710#if defined(__clang__)
711# pragma clang diagnostic pop
712#elif __IS_COMPILER_ARM_COMPILER_5__
713#pragma diag_warning 64
714#endif
715
716#undef __ARM_2D_HELPER_IMPLEMENT__
717#undef __ARM_2D_HELPER_INHERIT__
718
719
720#ifdef __cplusplus
721}
722#endif
723
724#endif