Arm-2D
2D Image Processing Library for Cortex-M Processors
arm_2d_utils.h
1
/*
2
* Copyright (C) 2010-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: arm_2d_utils.h
22
* Description: Public header file for Arm-2D Library
23
*
24
* $Date: 12. April 2022
25
* $Revision: V.1.0.1
26
*
27
* -------------------------------------------------------------------- */
28
29
#ifndef __ARM_2D_UTILS_H__
30
#define __ARM_2D_UTILS_H__
31
32
/*============================ INCLUDES ======================================*/
33
34
#if defined(__clang__)
35
# pragma clang diagnostic push
36
# pragma clang diagnostic ignored "-Wunknown-warning-option"
37
# pragma clang diagnostic ignored "-Wreserved-identifier"
38
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
39
# pragma clang diagnostic ignored "-Wpadded"
40
# pragma clang diagnostic ignored "-Wsign-conversion"
41
# pragma clang diagnostic ignored "-Wimplicit-int-conversion"
42
# pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
43
# pragma clang diagnostic ignored "-Wundef"
44
#elif defined(__IS_COMPILER_GCC__)
45
# pragma GCC diagnostic push
46
# pragma GCC diagnostic ignored "-Wpedantic"
47
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
48
#endif
49
50
#ifdef __ARM_2D_HAS_USER_HEADER__
51
# include __ARM_2D_HAS_USER_HEADER__
52
#endif
53
54
/*! \note arm-2d relies on CMSIS 5.4.0 and above.
55
*/
56
#include "cmsis_compiler.h"
57
58
#ifdef __cplusplus
59
extern
"C"
{
60
#endif
61
62
63
64
/*============================ MACROS ========================================*/
65
66
67
/*----------------------------------------------------------------------------*
68
* Environment Detection *
69
*----------------------------------------------------------------------------*/
70
71
//! \name The macros to identify the compiler
72
//! @{
73
74
//! \note for IAR
75
#ifdef __IS_COMPILER_IAR__
76
# undef __IS_COMPILER_IAR__
77
#endif
78
#if defined(__IAR_SYSTEMS_ICC__)
79
# define __IS_COMPILER_IAR__ 1
80
#endif
81
82
//! \note for arm compiler 5
83
#ifdef __IS_COMPILER_ARM_COMPILER_5__
84
# undef __IS_COMPILER_ARM_COMPILER_5__
85
#endif
86
#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
87
# define __IS_COMPILER_ARM_COMPILER_5__ 1
88
#endif
89
//! @}
90
91
//! \note for arm compiler 6
92
#ifdef __IS_COMPILER_ARM_COMPILER_6__
93
# undef __IS_COMPILER_ARM_COMPILER_6__
94
#endif
95
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
96
# define __IS_COMPILER_ARM_COMPILER_6__ 1
97
#endif
98
99
#ifdef __IS_COMPILER_LLVM__
100
# undef __IS_COMPILER_LLVM__
101
#endif
102
#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
103
# define __IS_COMPILER_LLVM__ 1
104
#else
105
//! \note for gcc
106
# ifdef __IS_COMPILER_GCC__
107
# undef __IS_COMPILER_GCC__
108
# endif
109
# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER_5__) \
110
|| defined(__IS_COMPILER_ARM_COMPILER_6__) \
111
|| defined(__IS_COMPILER_LLVM__))
112
# define __IS_COMPILER_GCC__ 1
113
# endif
114
//! @}
115
#endif
116
//! @}
117
118
119
/*----------------------------------------------------------------------------*
120
* OOC and Private Protection *
121
*----------------------------------------------------------------------------*/
122
/*! \brief minimal support for OOPC
123
*/
124
#undef __implement_ex
125
#undef __implement
126
#undef implement
127
#undef implement_ex
128
#undef inherit
129
#undef inherit_ex
130
131
#define __implement_ex(__type, __name) \
132
union { \
133
__type __name; \
134
__type; \
135
}
136
137
#define __inherit_ex(__type, __name) \
138
__type __name \
139
140
#define __implement(__type) __implement_ex( __type, \
141
use_as__##__type)
142
143
#define __inherit(__type) __inherit_ex(__type,use_as__##__type)
144
145
#define implement(__type) __implement(__type)
146
#define implement_ex(__type, __name) __implement_ex(__type, __name)
147
148
#define inherit(__type) __inherit(__type)
149
#define inherit_ex(__type, __name) __inherit_ex(__type, __name)
150
151
152
/*----------------------------------------------------------------------------*
153
* Misc *
154
*----------------------------------------------------------------------------*/
155
156
#ifndef ARM_2D_UNUSED
157
# define ARM_2D_UNUSED(__VAR) (void)(__VAR)
158
#endif
159
160
#ifndef ARM_TEST_BITS
161
# define ARM_TEST_BITS(__VALUE, __BITS) ((__BITS) == ((__VALUE) & (__BITS)))
162
#endif
163
164
#ifndef dimof
165
# define dimof(__array) (sizeof(__array)/sizeof(__array[0]))
166
#endif
167
168
#ifndef offsetof
169
# define offsetof(__type, __member) \
170
((uintptr_t)&(((__type *)NULL)->__member))
171
#endif
172
173
#define __ARM_TO_STRING(__STR) #__STR
174
#define ARM_TO_STRING(__STR) __ARM_TO_STRING(__STR)
175
176
#define __ARM_VA_NUM_ARGS_IMPL( _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, \
177
_13,_14,_15,_16,__N,...) __N
178
#define __ARM_VA_NUM_ARGS(...) \
179
__ARM_VA_NUM_ARGS_IMPL( 0,##__VA_ARGS__,16,15,14,13,12,11,10,9, \
180
8,7,6,5,4,3,2,1,0)
181
182
/*! \brief detect whether GNU extension is enabled in compilation or not
183
*/
184
#if __ARM_VA_NUM_ARGS() != 0
185
# warning Please enable GNC extensions, it is required by the Arm-2D.
186
#endif
187
188
#ifndef ARM_2D_INVOKE
189
# define ARM_2D_INVOKE(__FUNC_PTR, ...) \
190
do { \
191
if (NULL != (__FUNC_PTR)) { \
192
(*(__FUNC_PTR))(__VA_ARGS__); \
193
} \
194
} while(0)
195
#endif
196
197
#define __ARM_CONNECT2(__A, __B) __A##__B
198
#define __ARM_CONNECT2_ALT(__A, __B) __A##__B
199
#define __ARM_CONNECT3(__A, __B, __C) __A##__B##__C
200
#define __ARM_CONNECT4(__A, __B, __C, __D) __A##__B##__C##__D
201
#define __ARM_CONNECT5(__A, __B, __C, __D, __E) __A##__B##__C##__D##__E
202
#define __ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
203
__A##__B##__C##__D##__E##__F
204
#define __ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
205
__A##__B##__C##__D##__E##__F##__G
206
#define __ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
207
__A##__B##__C##__D##__E##__F##__G##__H
208
#define __ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
209
__A##__B##__C##__D##__E##__F##__G##__H##__I
210
211
#define ARM_CONNECT2(__A, __B) __ARM_CONNECT2(__A, __B)
212
#define ARM_CONNECT2_ALT(__A, __B) __ARM_CONNECT2_ALT(__A, __B)
213
#define ARM_CONNECT3(__A, __B, __C) __ARM_CONNECT3(__A, __B, __C)
214
#define ARM_CONNECT4(__A, __B, __C, __D) __ARM_CONNECT4(__A, __B, __C, __D)
215
#define ARM_CONNECT5(__A, __B, __C, __D, __E) \
216
__ARM_CONNECT5(__A, __B, __C, __D, __E)
217
#define ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
218
__ARM_CONNECT6(__A, __B, __C, __D, __E, __F)
219
#define ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
220
__ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G)
221
#define ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
222
__ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H)
223
#define ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
224
__ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I)
225
226
#define arm_connect(...) \
227
ARM_CONNECT2_ALT(ARM_CONNECT, __ARM_VA_NUM_ARGS(__VA_ARGS__)) \
228
(__VA_ARGS__)
229
230
#define ARM_CONNECT(...) arm_connect(__VA_ARGS__)
231
232
#define __ARM_USING1(__declare) \
233
for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
234
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
235
)
236
237
#define __ARM_USING2(__declare, __on_leave_expr) \
238
for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
239
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
240
__on_leave_expr \
241
)
242
243
#define __ARM_USING3(__declare, __on_enter_expr, __on_leave_expr) \
244
for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
245
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
246
((__on_enter_expr),1) : 0; \
247
__on_leave_expr \
248
)
249
250
#define __ARM_USING4(__dcl1, __dcl2, __on_enter_expr, __on_leave_expr) \
251
for (__dcl1,__dcl2,*ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)= NULL;\
252
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
253
((__on_enter_expr),1) : 0; \
254
__on_leave_expr \
255
)
256
257
#define arm_using(...) \
258
ARM_CONNECT2(__ARM_USING, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
259
260
261
#define __ARM_WITH2(__type, __addr) \
262
ARM_USING(__type *_p=(__addr))
263
#define __ARM_WITH3(__type, __addr, __item) \
264
ARM_USING(__type *_p=(__addr), *__item = _p, _p=_p, )
265
266
#define arm_with(...) \
267
ARM_CONNECT2(__ARM_WITH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
268
269
#define ARM_FOREACH2(__type, __array) \
270
arm_using(__type *_ = __array) \
271
for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
272
ARM_CONNECT2(count,__LINE__) > 0; \
273
_++, ARM_CONNECT2(count,__LINE__)-- \
274
)
275
276
#define ARM_FOREACH3(__type, __array, __item) \
277
arm_using(__type *_ = __array, *__item = _, _ = _, ) \
278
for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
279
ARM_CONNECT2(count,__LINE__) > 0; \
280
_++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
281
)
282
283
#define ARM_FOREACH4(__type, __array, __count, __item) \
284
arm_using(__type *_ = __array, *__item = _, _ = _, ) \
285
for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = (__count); \
286
ARM_CONNECT2(count,__LINE__) > 0; \
287
_++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
288
)
289
290
#define arm_foreach(...) \
291
ARM_CONNECT2(ARM_FOREACH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
292
293
294
#ifndef ARM_NONNULL
295
# if defined(__IS_COMPILER_ARM_COMPILER_5__) ||\
296
defined(__IS_COMPILER_ARM_COMPILER_6__) ||\
297
defined(__IS_COMPILER_GCC__) ||\
298
defined(__IS_COMPILER_LLVM__)
299
# define ARM_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
300
# else
301
# define ARM_NONNULL(...)
302
# endif
303
#endif
304
305
#ifndef ARM_NOINIT
306
# if defined(__IS_COMPILER_ARM_COMPILER_5__)
307
# define ARM_NOINIT __attribute__(( section( ".bss.noinit"
),zero_init))
308
# elif defined(__IS_COMPILER_ARM_COMPILER_6__)
309
# define ARM_NOINIT __attribute__(( section( ".bss.noinit"
)))
310
# elif defined(__IS_COMPILER_IAR__)
311
# define ARM_NOINIT __no_init
312
# elif defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)
313
# define ARM_NOINIT __attribute__(( section( ".bss.noinit"
)))
314
# else
315
# define ARM_NOINIT
316
# endif
317
#endif
318
319
320
#ifndef ARM_ALIGN
321
# define __ARM_ALIGN(__N) __attribute__((aligned(__N)))
322
# define ARM_ALIGN(__N) __ARM_ALIGN(__N)
323
#endif
324
325
326
#ifndef __RESTRICT
327
# define __RESTRICT __restrict
328
#endif
329
330
#ifndef __OVERRIDE_WEAK
331
# define __OVERRIDE_WEAK
332
#endif
333
334
#define ARM_2D_SAFE_NAME(...) ARM_CONNECT(__,__LINE__,##__VA_ARGS__)
335
#define arm_2d_safe_name(...) ARM_2D_SAFE_NAME(__VA_ARGS__)
336
337
#undef arm_irq_safe
338
339
#define arm_irq_safe \
340
arm_using( uint32_t ARM_2D_SAFE_NAME(temp) = \
341
({uint32_t temp=__get_PRIMASK();__disable_irq();temp;}),\
342
__set_PRIMASK(ARM_2D_SAFE_NAME(temp)))
343
344
345
#undef ARM_2D_WRAP_FUNC
346
#undef __ARM_2D_WRAP_FUNC
347
#undef ARM_2D_ORIG_FUNC
348
#undef __ARM_2D_ORIG_FUNC
349
350
#if defined(__IS_COMPILER_ARM_COMPILER_6__)
351
# define __ARM_2D_WRAP_FUNC(__FUNC) $Sub$$##__FUNC
352
# define __ARM_2D_ORIG_FUNC(__FUNC) $Super$$## __FUNC
353
#else
354
# define __ARM_2D_WRAP_FUNC(x) __wrap_ ## x
355
# define __ARM_2D_ORIG_FUNC(x) __real_ ## x
356
#endif
357
358
#define ARM_2D_WRAP_FUNC(__FUNC) __ARM_2D_WRAP_FUNC(__FUNC)
359
#define ARM_2D_ORIG_FUNC(__FUNC) __ARM_2D_ORIG_FUNC(__FUNC)
360
361
/*----------------------------------------------------------------------------*
362
* List Operations *
363
*----------------------------------------------------------------------------*/
364
365
/*! \note ALL the parameters passed to following macros must be pointer
366
*! variables.
367
*/
368
369
#define __ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
370
do { \
371
((__arm_slist_node_t *)(__P_NODE))->ptNext = \
372
(__arm_slist_node_t *)(__P_TOP); \
373
(*(__arm_slist_node_t **)&(__P_TOP)) = \
374
(__arm_slist_node_t *)(__P_NODE); \
375
} while(0)
376
#define ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
377
__ARM_LIST_STACK_PUSH((__P_TOP), (__P_NODE))
378
#define ARM_LIST_INSERT_AFTER(__P_TARGET, __P_NODE) \
379
__ARM_LIST_STACK_PUSH((__P_TARGET), (__P_NODE))
380
381
#define __ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
382
do { \
383
(*(__arm_slist_node_t **)&(__P_NODE)) = \
384
(__arm_slist_node_t *)(__P_TOP); \
385
if (NULL != (__P_TOP)) { \
386
(*(__arm_slist_node_t **)&(__P_TOP)) = \
387
((__arm_slist_node_t *)(__P_NODE))->ptNext; \
388
((__arm_slist_node_t *)(__P_NODE))->ptNext = NULL; \
389
} \
390
} while(0)
391
#define ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
392
__ARM_LIST_STACK_POP((__P_TOP), (__P_NODE))
393
#define ARM_LIST_REMOVE_AFTER(__P_TARGET, __P_NODE) \
394
ARM_LIST_STACK_POP((__P_TARGET), (__P_NODE))
395
396
397
#define __ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
398
do { \
399
if (NULL == (__TAIL)) { \
400
(*((__arm_slist_node_t **)&(__TAIL))) = \
401
(__arm_slist_node_t *)(__ITEM); \
402
((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
403
(*((__arm_slist_node_t **)&(__HEAD))) = \
404
(__arm_slist_node_t *)(__ITEM); \
405
} else { \
406
((__arm_slist_node_t *)(__TAIL))->ptNext = \
407
(__arm_slist_node_t *)(__ITEM); \
408
((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
409
(*(__arm_slist_node_t **)&(__TAIL)) = \
410
(__arm_slist_node_t *)(__ITEM); \
411
} \
412
} while(0)
413
#define ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
414
__ARM_LIST_QUEUE_ENQUEUE((__HEAD), (__TAIL), (__ITEM))
415
416
#define __ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
417
do { \
418
(*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
419
if (NULL != (__HEAD)) { \
420
(*(__arm_slist_node_t **)&(__HEAD)) = \
421
((__arm_slist_node_t *)(__HEAD))->ptNext; \
422
if (NULL == (__HEAD)) { \
423
(__TAIL) = NULL; \
424
} \
425
} \
426
} while(0)
427
428
#define ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
429
__ARM_LIST_QUEUE_DEQUEUE((__HEAD), (__TAIL), (__ITEM))
430
431
#define __ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
432
do { \
433
(*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
434
} while(0)
435
#define ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
436
__ARM_LIST_QUEUE_PEEK((__HEAD), (__TAIL), (__ITEM)) \
437
438
/*----------------------------------------------------------------------------*
439
* Definition Template *
440
*----------------------------------------------------------------------------*/
441
442
#define __def_low_lv_io(__NAME, __SW, ...) \
443
const __arm_2d_low_level_io_t LOW_LEVEL_IO##__NAME = { \
444
.SW = (__arm_2d_io_func_t *)&(__SW), \
445
.HW = (NULL, ##__VA_ARGS__) \
446
}
447
#define def_low_lv_io(__NAME, __SW, ...) \
448
__def_low_lv_io(__NAME, __SW, ##__VA_ARGS__)
449
450
451
#define __ref_low_lv_io(__NAME) &LOW_LEVEL_IO##__NAME
452
#define ref_low_lv_io(__NAME) __ref_low_lv_io(__NAME)
453
454
/*============================ TYPES =========================================*/
455
456
typedef
struct
__arm_slist_node_t
__arm_slist_node_t
;
457
struct
__arm_slist_node_t
{
458
__arm_slist_node_t
*ptNext;
459
};
460
461
462
/*============================ GLOBAL VARIABLES ==============================*/
463
/*============================ PROTOTYPES ====================================*/
464
465
#if defined(__clang__)
466
# pragma clang diagnostic pop
467
#elif __IS_COMPILER_ARM_COMPILER_5__
468
#elif __IS_COMPILER_GCC__
469
# pragma GCC diagnostic pop
470
#endif
471
472
#ifdef __cplusplus
473
}
474
#endif
475
476
#endif
/* end of __ARM_2D_UTILS_H__ */
477
478
479
/*============================ MACROS ========================================*/
480
/*----------------------------------------------------------------------------*
481
* Reentrant Macros *
482
*----------------------------------------------------------------------------*/
483
484
/* un-define macros */
485
#undef ARM_PRIVATE
486
487
488
/* redefine macros */
489
490
#if defined(__ARM_2D_IMPL__) || defined(__IS_COMPILER_IAR__)
491
492
# define ARM_PRIVATE(...) \
493
struct { \
494
__VA_ARGS__ \
495
} __ALIGNED(__alignof__(struct {__VA_ARGS__}));
496
497
#else
498
# define ARM_PRIVATE(...) \
499
uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
500
[sizeof(struct {__VA_ARGS__})] \
501
__ALIGNED(__alignof__(struct {__VA_ARGS__}));
502
#endif
503
504
505
506
507
/* post un-define macros */
508
509
#undef __ARM_2D_IMPL__
510
Library
Include
arm_2d_utils.h