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: 04. May 2023
25 * $Revision: V.1.6.3
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
41#include <stdlib.h>
42#include <assert.h>
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48#if defined(__clang__)
49# pragma clang diagnostic push
50# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
51# pragma clang diagnostic ignored "-Wunused-function"
52# pragma clang diagnostic ignored "-Wmissing-declarations"
53#endif
54
55/*!
56 * \addtogroup Deprecated
57 * @{
58 */
59#define arm_2d_draw_box arm_2d_helper_draw_box
60/*! @} */
61
62/*!
63 * \addtogroup gHelper 7 Helper Services
64 * @{
65 */
66/*============================ MACROS ========================================*/
67/*============================ MACROFIED FUNCTIONS ===========================*/
68
69/*!
70 * \brief set an alarm with given period and check the status
71 *
72 * \param[in] __ms a time period in millisecond
73 * \param[in] ... an optional timestamp holder
74 *
75 * \return bool whether it is timeout
76 */
77#define arm_2d_helper_is_time_out(__ms, ...) \
78 ({ static int64_t arm_2d_safe_name(s_lTimestamp); \
79 __arm_2d_helper_is_time_out(arm_2d_helper_convert_ms_to_ticks(__ms), \
80 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
81
82
83/*!
84 * \brief calculate the stroke of a liner slider based on time
85 *
86 * \param[in] __from the start of the slider
87 * \param[in] __to the end of the slider
88 * \param[in] __ms a given period (ms) in which the slider should finish the
89 * whole stroke
90 * \param[out] __stroke_ptr the address of an int32_t stroke variable
91 * \param[in] ... an optional address of a timestamp variable, if you omit it,
92 * NULL will be passed, and the code that call this funtion will not
93 * be reentrant.
94 * \retval true the slider has finished the whole stroke
95 * \retval false the slider hasn't reach the target end
96 */
97#define arm_2d_helper_time_liner_slider( __from, \
98 __to, \
99 __ms, \
100 __stroke_ptr, \
101 ...) \
102 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
103 __arm_2d_helper_time_liner_slider((__from), \
104 (__to), \
105 arm_2d_helper_convert_ms_to_ticks(__ms), \
106 (__stroke_ptr), \
107 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
108
109/*!
110 * \brief calculate the stroke of a cosine slider based on time
111 *
112 * \param[in] __from the start of the slider
113 * \param[in] __to the end of the slider
114 * \param[in] __ms a given period (ms) in which the slider should finish the
115 * whole stroke
116 * \param[in] __phase the phase offset
117 * \param[out] __stroke_ptr the address of an int32_t stroke variable
118 * \param[in] ... an optional address of a timestamp variable, if you omit it,
119 * NULL will be passed, and the code that call this funtion will not
120 * be reentrant.
121 * \retval true the slider has finished the whole stroke
122 * \retval false the slider hasn't reach the target end
123 */
124#define arm_2d_helper_time_cos_slider( __from, \
125 __to, \
126 __ms, \
127 __phase, \
128 __stroke_ptr, \
129 ...) \
130 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
131 __arm_2d_helper_time_cos_slider((__from), \
132 (__to), \
133 arm_2d_helper_convert_ms_to_ticks(__ms), \
134 (__phase), \
135 (__stroke_ptr), \
136 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
137
138/*!
139 * \brief calculate the stroke of a cosine slider(0~pi) based on time
140 *
141 * \param[in] __from the start of the slider
142 * \param[in] __to the end of the slider
143 * \param[in] __ms a given period (ms) in which the slider should finish the
144 * whole stroke
145 * \param[out] __stroke_ptr the address of an int32_t stroke variable
146 * \param[in] ... an optional address of a timestamp variable, if you omit it,
147 * NULL will be passed, and the code that call this funtion will not
148 * be reentrant.
149 * \retval true the slider has finished the whole stroke
150 * \retval false the slider hasn't reach the target end
151 */
152#define arm_2d_helper_time_half_cos_slider( __from, \
153 __to, \
154 __ms, \
155 __stroke_ptr, \
156 ...) \
157 ({static int64_t arm_2d_safe_name(s_lTimestamp); \
158 __arm_2d_helper_time_half_cos_slider((__from), \
159 (__to), \
160 arm_2d_helper_convert_ms_to_ticks(__ms), \
161 (__stroke_ptr), \
162 (&arm_2d_safe_name(s_lTimestamp),##__VA_ARGS__));})
163
164
165/*!
166 * \brief initialize/implement a given film (arm_2d_helper_file_t) object
167 * at compile-time.
168 * \param[in] __sprites_tile the sprites tile
169 * \param[in] __width the width of each frame
170 * \param[in] __height the height of each frame
171 * \param[in] __column the number of frames per row in the sprite tile
172 * \param[in] __frame_count the total number of frames in the sprite tile
173 * \param[in] __period the period per-frame
174 * \note __period is used as a reference for applications. The helper service
175 * doesn't use it at all.
176 */
177#define impl_film( __sprites_tile, \
178 __width, \
179 __height, \
180 __column, \
181 __frame_count, \
182 __period) \
183 { \
184 .use_as__arm_2d_tile_t = \
185 impl_child_tile((__sprites_tile), 0, 0, (__width), (__height)), \
186 .hwColumn = (__column), \
187 .hwFrameNum = (__frame_count), \
188 .hwPeriodPerFrame = (__period), \
189 }
190
191/*============================ TYPES =========================================*/
192
193/*!
194 * \brief a helper class to represent a GIF-like resource
195 */
196typedef struct arm_2d_helper_film_t {
197 implement(arm_2d_tile_t); /*!< derived from arm_2d_tile_t */
198 uint16_t hwColumn; /*!< number of frames per row in a sprite tile */
199 uint16_t hwFrameNum; /*!< the total number of frames */
200 uint16_t hwPeriodPerFrame; /*!< the period per frame (optional, used as a reference) */
201 uint16_t hwFrameIndex; /*!< the frame index used at runtime */
203
204/*============================ GLOBAL VARIABLES ==============================*/
205/*============================ LOCAL VARIABLES ===============================*/
206/*============================ PROTOTYPES ====================================*/
207
208/*!
209 * \brief initialize helper services
210 */
211extern
213
214/*!
215 * \brief backend task for asynchronose mode
216 */
217extern
219
220/*!
221 * \brief convert ticks of a reference timer to millisecond
222 *
223 * \param[in] lTick the tick count
224 * \return int64_t the millisecond
225 */
226extern
228
229/*!
230 * \brief convert millisecond into ticks of the reference timer
231 *
232 * \param[in] wMS the target time in millisecond
233 * \return int64_t the ticks
234 */
235extern
237
238/*!
239 * \brief get the reference clock frequency
240 * \return uint32_t the frequency
241 */
242extern
244
245/*!
246 * \brief get the current system stamp from the reference clock
247 *
248 * \return int64_t the timestamp in ticks (no overflow issue)
249 * \note you have to call arm_2d_helper_convert_ticks_to_ms() to convert the
250 * the timestamp into milliseconds when required.
251 */
252extern
254
255
256/*!
257 * \brief set an alarm with given period and check the status
258 *
259 * \param[in] lPeriod a time period in ticks
260 * \param[in] plTimestamp a pointer points to an int64_t integer, if NULL is
261 * passed, an static local variable inside the function will be used
262 * \return bool whether it is timeout or not
263 */
264ARM_NONNULL(2)
265extern
266bool __arm_2d_helper_is_time_out(int64_t lPeriod, int64_t *plTimestamp);
267
268/*!
269 * \brief calculate the stroke of a liner slider based on time
270 *
271 * \param[in] nFrom the start of the slider
272 * \param[in] nTo the end of the slider
273 * \param[in] lPeriod a given period in which the slider should finish the whole
274 * stroke
275 * \param[out] pnStroke the address of an int32_t stroke variable
276 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
277 * the code that call this funtion will not be reentrant.
278 * \retval true the slider has finished the whole stroke
279 * \retval false the slider hasn't reach the target end
280 */
281ARM_NONNULL(4,5)
282extern
284 int32_t nTo,
285 int64_t lPeriod,
286 int32_t *pnStroke,
287 int64_t *plTimestamp);
288
289/*!
290 * \brief calculate the stroke of a cosine slider (0~pi) based on time
291 *
292 * \param[in] nFrom the start of the slider
293 * \param[in] nTo the end of the slider
294 * \param[in] lPeriod a given period in which the slider should finish the whole
295 * stroke
296 * \param[out] pnStroke the address of an int32_t stroke variable
297 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
298 * the code that call this funtion will not be reentrant.
299 * \retval true the slider has finished the whole stroke
300 * \retval false the slider hasn't reach the target end
301 */
302ARM_NONNULL(4,5)
303extern
305 int32_t nTo,
306 int64_t lPeriod,
307 int32_t *pnStroke,
308 int64_t *plTimestamp);
309
310/*!
311 * \brief calculate the stroke of a consine slider (0~2pi) based on time
312 *
313 * \param[in] nFrom the start of the slider
314 * \param[in] nTo the end of the slider
315 * \param[in] lPeriod a given period in which the slider should finish the whole
316 * stroke
317 * \param[in] lPhase the phase offset
318 * \param[out] pnStroke the address of an int32_t stroke variable
319 * \param[in] plTimestamp the address of a timestamp variable, if you pass NULL
320 * the code that call this funtion will not be reentrant.
321 * \retval true the slider has finished the whole stroke
322 * \retval false the slider hasn't reach the target end
323 */
324ARM_NONNULL(5,6)
325extern
327 int32_t nTo,
328 int64_t lPeriod,
329 float fPhase,
330 int32_t *pnStroke,
331 int64_t *plTimestamp);
332
333/*!
334 * \brier colour intrapolation
335 * \param[in] wFrom a 32bit colour (4 8bit colour channels) on the start
336 * \param[in] wTo a 32bit colour (4 8bit colour channels) on the end
337 * \param[in] nDistance the reference full distance between two end points
338 * \param[in] nOffset the offset from the start
339 * \return uint32_t 32bit colour
340 */
341extern
342uint32_t __arm_2d_helper_colour_slider( uint32_t wFrom,
343 uint32_t wTo,
344 int32_t nDistance,
345 int32_t nOffset);
346
347/*!
348 * \brier draw a box with specified colour, border width and opacity
349 * \param[in] ptTarget the target tile
350 * \param[in] ptRegion the target region
351 * \param[in] iBorderWidth the border width
352 * \param[in] tColour the target colour
353 * \param[in] chOpacity the opacity
354 */
355extern
357 const arm_2d_region_t *ptRegion,
358 int16_t iBorderWidth,
359 COLOUR_INT tColour,
360 uint8_t chOpacity);
361
362/*!
363 * \brier move to the next frame of a given film
364 * \param[in] ptThis the target film
365 */
366extern
367ARM_NONNULL(1)
369
370/*!
371 * \brier reset the frame index to zero
372 * \param[in] ptThis the target film
373 */
374extern
375ARM_NONNULL(1)
377
378/*!
379 * \brier reset the frame index to a specified value and wrap around if the
380 * index number is out of range.
381 * \param[in] ptThis the target film
382 * \param[in] nIndex the given index
383 */
384extern
385ARM_NONNULL(1)
387
388/*! @} */
389
390#if defined(__clang__)
391# pragma clang diagnostic pop
392#endif
393
394#ifdef __cplusplus
395}
396#endif
397
398#endif