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: 28. Aug 2023
25 * $Revision: V.1.6.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_map.h"
41
42#include <stdlib.h>
43#include <assert.h>
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49#if defined(__clang__)
50# pragma clang diagnostic push
51# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
52# pragma clang diagnostic ignored "-Wunused-function"
53# pragma clang diagnostic ignored "-Wmissing-declarations"
54# pragma clang diagnostic ignored "-Wpadded"
55#elif defined(__IS_COMPILER_ARM_COMPILER_5__)
56# pragma diag_suppress 64
57#endif
58
59
60/* OOC header, please DO NOT modify */
61#ifdef __ARM_2D_HELPER_IMPLEMENT__
62# undef __ARM_2D_HELPER_IMPLEMENT__
63# define __ARM_2D_IMPL__
64#endif
65#include "arm_2d_utils.h"
66
67/*!
68 * \addtogroup Deprecated
69 * @{
70 */
71#define arm_2d_draw_box arm_2d_helper_draw_box
72/*! @} */
73
74/*!
75 * \addtogroup gHelper 7 Helper Services
76 * @{
77 */
78/*============================ MACROS ========================================*/
79/*============================ MACROFIED FUNCTIONS ===========================*/
80
81/*!
82 * \brief set an alarm with given period and check the status
83 *
84 * \param[in] __ms a time period in millisecond
85 * \param[in] ... an optional timestamp holder
86 *
87 * \return bool whether it is timeout
88 */
89#define arm_2d_helper_is_time_out(__ms, ...) \
90 ({ static int64_t arm_2d_safe_name(s_lTimestamp); \
91 __arm_2d_helper_is_time_out(arm_2d_helper_convert_ms_to_ticks(__ms), \
92 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
93
94
95/*!
96 * \brief calculate the stroke of a liner slider based on time
97 *
98 * \param[in] __from the start of the slider
99 * \param[in] __to the end of the slider
100 * \param[in] __ms a given period (ms) in which the slider should finish the
101 * whole stroke
102 * \param[out] __stroke_ptr the address of an int32_t stroke variable
103 * \param[in] ... an optional address of a timestamp variable, if you omit it,
104 * NULL will be passed, and the code that call this funtion will not
105 * be reentrant.
106 * \retval true the slider has finished the whole stroke
107 * \retval false the slider hasn't reach the target end
108 */
109#define arm_2d_helper_time_liner_slider( __from, \
110 __to, \
111 __ms, \
112 __stroke_ptr, \
113 ...) \
114 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
115 __arm_2d_helper_time_liner_slider((__from), \
116 (__to), \
117 arm_2d_helper_convert_ms_to_ticks(__ms), \
118 (__stroke_ptr), \
119 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
120
121/*!
122 * \brief calculate the stroke of a cosine slider based on time
123 *
124 * \param[in] __from the start of the slider
125 * \param[in] __to the end of the slider
126 * \param[in] __ms a given period (ms) in which the slider should finish the
127 * whole stroke
128 * \param[in] __phase the phase offset
129 * \param[out] __stroke_ptr the address of an int32_t stroke variable
130 * \param[in] ... an optional address of a timestamp variable, if you omit it,
131 * NULL will be passed, and the code that call this funtion will not
132 * be reentrant.
133 * \retval true the slider has finished the whole stroke
134 * \retval false the slider hasn't reach the target end
135 */
136#define arm_2d_helper_time_cos_slider( __from, \
137 __to, \
138 __ms, \
139 __phase, \
140 __stroke_ptr, \
141 ...) \
142 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
143 __arm_2d_helper_time_cos_slider((__from), \
144 (__to), \
145 arm_2d_helper_convert_ms_to_ticks(__ms), \
146 (__phase), \
147 (__stroke_ptr), \
148 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
149
150/*!
151 * \brief calculate the stroke of a cosine slider(0~pi) based on time
152 *
153 * \param[in] __from the start of the slider
154 * \param[in] __to the end of the slider
155 * \param[in] __ms a given period (ms) in which the slider should finish the
156 * whole stroke
157 * \param[out] __stroke_ptr the address of an int32_t stroke variable
158 * \param[in] ... an optional address of a timestamp variable, if you omit it,
159 * NULL will be passed, and the code that call this funtion will not
160 * be reentrant.
161 * \retval true the slider has finished the whole stroke
162 * \retval false the slider hasn't reach the target end
163 */
164#define arm_2d_helper_time_half_cos_slider( __from, \
165 __to, \
166 __ms, \
167 __stroke_ptr, \
168 ...) \
169 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
170 __arm_2d_helper_time_half_cos_slider((__from), \
171 (__to), \
172 arm_2d_helper_convert_ms_to_ticks(__ms), \
173 (__stroke_ptr), \
174 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
175
176
177/*!
178 * \brief initialize/implement a given film (arm_2d_helper_file_t) object
179 * at compile-time.
180 * \param[in] __sprites_tile the sprites tile
181 * \param[in] __width the width of each frame
182 * \param[in] __height the height of each frame
183 * \param[in] __column the number of frames per row in the sprite tile
184 * \param[in] __frame_count the total number of frames in the sprite tile
185 * \param[in] __period the period per-frame
186 * \note __period is used as a reference for applications. The helper service
187 * doesn't use it at all.
188 */
189#define impl_film( __sprites_tile, \
190 __width, \
191 __height, \
192 __column, \
193 __frame_count, \
194 __period) \
195 { \
196 .use_as__arm_2d_tile_t = \
197 impl_child_tile((__sprites_tile), 0, 0, (__width), (__height)), \
198 .hwColumn = (__column), \
199 .hwFrameNum = (__frame_count), \
200 .hwPeriodPerFrame = (__period), \
201 }
202
203/*============================ TYPES =========================================*/
204
205/*!
206 * \brief a helper class to represent a GIF-like resource
207 */
208typedef struct arm_2d_helper_film_t {
209 implement(arm_2d_tile_t); /*!< derived from arm_2d_tile_t */
210 uint16_t hwColumn; /*!< number of frames per row in a sprite tile */
211 uint16_t hwFrameNum; /*!< the total number of frames */
212 uint16_t hwPeriodPerFrame; /*!< the period per frame (optional, used as a reference) */
213 uint16_t hwFrameIndex; /*!< the frame index used at runtime */
215
216/*!
217 * \brief the configuration structure for the Proportional-Integral Control
218 *
219 */
221 int32_t nInterval;
222 float fProportion;
223 float fIntegration;
225
226/*!
227 * \brief a helper class for Proportional-Integral Control
228 */
230
231ARM_PRIVATE (
233 int64_t lTimestamp;
234 int32_t nTimeResidual;
235 int32_t iCurrent;
236 float fOP;
239
240/*============================ GLOBAL VARIABLES ==============================*/
241/*============================ LOCAL VARIABLES ===============================*/
242/*============================ PROTOTYPES ====================================*/
243
244/*!
245 * \brief initialize helper services
246 */
247extern
249
250/*!
251 * \brief backend task for asynchronose mode
252 */
253extern
255
256/*!
257 * \brief convert ticks of a reference timer to millisecond
258 *
259 * \param[in] lTick the tick count
260 * \return int64_t the millisecond
261 */
262extern
264
265/*!
266 * \brief convert millisecond into ticks of the reference timer
267 *
268 * \param[in] wMS the target time in millisecond
269 * \return int64_t the ticks
270 */
271extern
273
274/*!
275 * \brief get the reference clock frequency
276 * \return uint32_t the frequency
277 */
278extern
280
281/*!
282 * \brief get the current system stamp from the reference clock
283 *
284 * \return int64_t the timestamp in ticks (no overflow issue)
285 * \note you have to call arm_2d_helper_convert_ticks_to_ms() to convert the
286 * the timestamp into milliseconds when required.
287 */
288extern
290
291
292/*!
293 * \brief set an alarm with given period and check the status
294 *
295 * \param[in] lPeriod a time period in ticks
296 * \param[in] plTimestamp a pointer points to an int64_t integer, if NULL is
297 * passed, an static local variable inside the function will be used
298 * \return bool whether it is timeout or not
299 */
300ARM_NONNULL(2)
301extern
302bool __arm_2d_helper_is_time_out(int64_t lPeriod, int64_t *plTimestamp);
303
304/*!
305 * \brief get a new semaphore from host RTOS
306 * \return uintptr_t a handler for the semaphore
307 */
308extern
310
311/*!
312 * \brief free a semaphore
313 * \param[in] pSemaphore the target semaphore
314 */
315extern
316void arm_2d_port_free_semaphore(uintptr_t pSemaphore);
317
318/*!
319 * \brief wait for a semaphore
320 * \param[in] pSemaphore the target semaphore
321 * \retval true we get the semaphore
322 * \retval false we haven't get the sempahore
323 */
324extern
325bool arm_2d_port_wait_for_semaphore(uintptr_t pSemaphore);
326
327/*!
328 * \brief set a semaphore
329 * \param[in] pSemaphore the target semaphore
330 */
331extern
332void arm_2d_port_set_semaphore(uintptr_t pSemaphore);
333
334/*!
335 * \brief calculate the stroke of a liner slider based on time
336 *
337 * \param[in] nFrom the start of the slider
338 * \param[in] nTo the end of the slider
339 * \param[in] lPeriod a given period in which the slider should finish the whole
340 * stroke
341 * \param[out] pnStroke the address of an int32_t stroke variable
342 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
343 * the code that call this funtion will not be reentrant.
344 * \retval true the slider has finished the whole stroke
345 * \retval false the slider hasn't reach the target end
346 */
347ARM_NONNULL(4,5)
348extern
350 int32_t nTo,
351 int64_t lPeriod,
352 int32_t *pnStroke,
353 int64_t *plTimestamp);
354
355/*!
356 * \brief calculate the stroke of a cosine slider (0~pi) based on time
357 *
358 * \param[in] nFrom the start of the slider
359 * \param[in] nTo the end of the slider
360 * \param[in] lPeriod a given period in which the slider should finish the whole
361 * stroke
362 * \param[out] pnStroke the address of an int32_t stroke variable
363 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
364 * the code that call this funtion will not be reentrant.
365 * \retval true the slider has finished the whole stroke
366 * \retval false the slider hasn't reach the target end
367 */
368ARM_NONNULL(4,5)
369extern
371 int32_t nTo,
372 int64_t lPeriod,
373 int32_t *pnStroke,
374 int64_t *plTimestamp);
375
376/*!
377 * \brief calculate the stroke of a consine slider (0~2pi) based on time
378 *
379 * \param[in] nFrom the start of the slider
380 * \param[in] nTo the end of the slider
381 * \param[in] lPeriod a given period in which the slider should finish the whole
382 * stroke
383 * \param[in] lPhase the phase offset
384 * \param[out] pnStroke the address of an int32_t stroke variable
385 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
386 * the code that call this funtion will not be reentrant.
387 * \retval true the slider has finished the whole stroke
388 * \retval false the slider hasn't reach the target end
389 */
390ARM_NONNULL(5,6)
391extern
393 int32_t nTo,
394 int64_t lPeriod,
395 float fPhase,
396 int32_t *pnStroke,
397 int64_t *plTimestamp);
398
399/*!
400 * \brier colour intrapolation
401 * \param[in] wFrom a 32bit colour (4 8bit colour channels) on the start
402 * \param[in] wTo a 32bit colour (4 8bit colour channels) on the end
403 * \param[in] nDistance the reference full distance between two end points
404 * \param[in] nOffset the offset from the start
405 * \return uint32_t 32bit colour
406 */
407extern
408uint32_t __arm_2d_helper_colour_slider( uint32_t wFrom,
409 uint32_t wTo,
410 int32_t nDistance,
411 int32_t nOffset);
412
413/*!
414 * \brief initialize the Proportional-Integral Control helper
415 * \param[in] the target helper control block
416 * \param[in] the configuration structure, NULL means using the default
417 * parameters, i.e P = 5.0f, I = 3.0f and Interval = 20ms
418 * \param[in] nStartPosition the start postion
419 * \return arm_2d_helper_pi_slider_t* the control block
420 */
421extern
422ARM_NONNULL(1)
426 int32_t nStartPosition);
427
428/*!
429 * \brief A helper function for Proportional-Integral Control
430 * \param[in] ptThis the control block (arm_2d_helper_pi_slider_t)
431 * \param[in] nTargetPosition the new target position
432 * \param[in] pnResult a int32_t buffer for reading the current postion
433 * \retval true the slider has reached the target postion
434 * \retval false the slider is still moving
435 */
436extern
437ARM_NONNULL( 1, 3 )
439 int32_t nTargetPosition,
440 int32_t *pnResult);
441
442/*!
443 * \brier draw a box with specified colour, border width and opacity
444 * \param[in] ptTarget the target tile
445 * \param[in] ptRegion the target region
446 * \param[in] iBorderWidth the border width
447 * \param[in] tColour the target colour
448 * \param[in] chOpacity the opacity
449 */
450extern
452 const arm_2d_region_t *ptRegion,
453 int16_t iBorderWidth,
454 COLOUR_INT tColour,
455 uint8_t chOpacity);
456
457/*!
458 * \brier move to the next frame of a given film
459 * \param[in] ptThis the target film
460 */
461extern
462ARM_NONNULL(1)
464
465/*!
466 * \brier reset the frame index to zero
467 * \param[in] ptThis the target film
468 */
469extern
470ARM_NONNULL(1)
472
473/*!
474 * \brier reset the frame index to a specified value and wrap around if the
475 * index number is out of range.
476 * \param[in] ptThis the target film
477 * \param[in] nIndex the given index
478 */
479extern
480ARM_NONNULL(1)
482
483/*! @} */
484
485#if defined(__clang__)
486# pragma clang diagnostic pop
487#elif __IS_COMPILER_ARM_COMPILER_5__
488#pragma diag_warning 64
489#endif
490
491#ifdef __cplusplus
492}
493#endif
494
495#endif