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: 30. April 2025
25 * $Revision: V.2.3.2
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 * \return bool whether the film reaches the end or not
442 */
443extern
444ARM_NONNULL(1)
446
447/*!
448 * \brier reset the frame index to zero
449 * \param[in] ptThis the target film
450 */
451extern
452ARM_NONNULL(1)
454
455/*!
456 * \brier reset the frame index to a specified value and wrap around if the
457 * index number is out of range.
458 * \param[in] ptThis the target film
459 * \param[in] nIndex the given index
460 */
461extern
462ARM_NONNULL(1)
464
465/*----------------------------------------------------------------------------*
466 * FIFO Helper Service *
467 *----------------------------------------------------------------------------*/
468
469/*!
470 * \brief initialize a given byte fifo
471 * \param[in] ptThis the target FIFO control block
472 * \param[in] pBuffer a buffer for storing the data
473 * \param[in] hwSize the buffer size
474 * \retval false Illegal parameters
475 * \retval true the target FIFO is initialized
476 */
477extern
478ARM_NONNULL(1,2)
480 void *pBuffer,
481 uint16_t hwSize);
482
483/*!
484 * \brief Empty a given byte fifo
485 * \param[in] ptThis the target byte fifo
486 */
487extern
488ARM_NONNULL(1)
490
491/*!
492 * \brief write a byte to a given fifo
493 * \param[in] ptThis the target FIFO control block
494 * \param[in] chChar the target byte
495 * \retval false the FIFO is FULL
496 * \retval true operation is successful
497 */
498extern
499ARM_NONNULL(1)
500bool arm_2d_byte_fifo_enqueue(arm_2d_byte_fifo_t *ptThis, uint8_t chChar);
501
502/*!
503 * \brief read a byte from a given fifo
504 * \param[in] ptThis the target FIFO control block
505 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
506 * \retval false the FIFO is EMPTY
507 * \retval true operation is successful
508 */
509extern
510ARM_NONNULL(1)
511bool arm_2d_byte_fifo_dequeue(arm_2d_byte_fifo_t *ptThis, uint8_t *pchChar);
512
513/*!
514 * \brief peek a byte continuously from a given fifo
515 * \param[in] ptThis the target FIFO control block
516 * \param[in] pchChar a buffer to store the byte, NULL means drop a byte
517 * \retval false the FIFO is EMPTY
518 * \retval true operation is successful
519 */
520extern
521ARM_NONNULL(1)
523 uint8_t *pchChar,
524 bool bMovePointer);
525
526/*!
527 * \brief drop all peeked byte from a given fifo
528 * \param[in] ptThis the target FIFO control block
529 * \return none
530 */
531extern
532ARM_NONNULL(1)
534
535/*!
536 * \brief reset the peek pointer, so you can restart from the beginning to peek.
537 * \param[in] ptThis the target FIFO control block
538 * \return none
539 */
540ARM_NONNULL(1)
542
543/*----------------------------------------------------------------------------*
544 * Misc *
545 *----------------------------------------------------------------------------*/
546
547/*!
548 * \brief swap the high and low bytes for each rgb16 pixel
549 *
550 * \param[in] phwBuffer the pixel buffer
551 * \note the phwBuffer MUST aligned to half-word addresses
552 *
553 * \param[in] wSize the number of pixels
554 */
555extern
556void arm_2d_helper_swap_rgb16(uint16_t *phwBuffer, uint32_t wCount);
557
558extern
559ARM_NONNULL(1)
560/*!
561 * \brief fill the target tile with a specified colour
562 *
563 * \param[in] ptTile the target tile
564 * \param[in] tColourFormat the colour format of the target tile
565 * \param[in] tColour the target colour
566 */
568 arm_2d_color_info_t tColourFormat,
569 arm_2d_colour_t tColour);
570
571#if __ARM_2D_HELPER_CFG_LAYOUT_DEBUG_MODE__
572extern
573ARM_NONNULL(1)
574void __arm_2d_helper_layout_debug_print_label(const arm_2d_tile_t *ptTile,
575 arm_2d_region_t *ptRegion,
576 const char *pchString);
577#endif
578
579/*! @} */
580
581/*============================ INCLUDES ======================================*/
582#include "arm_2d_helper_built_in.h"
583
584#if defined(__clang__)
585# pragma clang diagnostic pop
586#elif __IS_COMPILER_ARM_COMPILER_5__
587#pragma diag_warning 64
588#endif
589
590#undef __ARM_2D_HELPER_IMPLEMENT__
591#undef __ARM_2D_HELPER_INHERIT__
592
593
594#ifdef __cplusplus
595}
596#endif
597
598#endif