pikapython/package/Arm2D/arm_2d_utils.h

474 lines
20 KiB
C
Raw Normal View History

2021-11-09 22:19:51 +08:00
/*
* Copyright (C) 2010-2021 Arm Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ----------------------------------------------------------------------
* Project: Arm-2D Library
* Title: arm_2d_utils.h
* Description: Public header file for Arm-2D Library
*
* $Date: 20. sep 2021
* $Revision: V.0.6.0
*
* -------------------------------------------------------------------- */
#ifndef __ARM_2D_UTILS_H__
#define __ARM_2D_UTILS_H__
/*============================ INCLUDES ======================================*/
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-warning-option"
# pragma clang diagnostic ignored "-Wreserved-identifier"
# pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
# pragma clang diagnostic ignored "-Wpadded"
# pragma clang diagnostic ignored "-Wsign-conversion"
# pragma clang diagnostic ignored "-Wimplicit-int-conversion"
# pragma clang diagnostic ignored "-Wundef"
2021-11-09 22:19:51 +08:00
#elif defined(__IS_COMPILER_GCC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpedantic"
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
2021-11-09 22:19:51 +08:00
#endif
#ifdef __ARM_2D_HAS_USER_HEADER__
# include __ARM_2D_HAS_USER_HEADER__
2021-11-09 22:19:51 +08:00
#endif
/*! \note arm-2d relies on CMSIS 5.4.0 and above.
*/
2021-11-20 20:23:11 +08:00
#include "cmsis_compiler.h"
#include <arm_math.h>
2021-11-09 22:19:51 +08:00
#ifdef __cplusplus
2021-11-09 22:19:51 +08:00
extern "C" {
#endif
2021-11-09 22:19:51 +08:00
/*============================ MACROS ========================================*/
2021-11-09 22:19:51 +08:00
/*----------------------------------------------------------------------------*
* Environment Detection *
*----------------------------------------------------------------------------*/
//! \name The macros to identify the compiler
//! @{
//! \note for IAR
#ifdef __IS_COMPILER_IAR__
# undef __IS_COMPILER_IAR__
2021-11-09 22:19:51 +08:00
#endif
#if defined(__IAR_SYSTEMS_ICC__)
# define __IS_COMPILER_IAR__ 1
2021-11-09 22:19:51 +08:00
#endif
//! \note for arm compiler 5
#ifdef __IS_COMPILER_ARM_COMPILER_5__
# undef __IS_COMPILER_ARM_COMPILER_5__
2021-11-09 22:19:51 +08:00
#endif
#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))
# define __IS_COMPILER_ARM_COMPILER_5__ 1
2021-11-09 22:19:51 +08:00
#endif
//! @}
//! \note for arm compiler 6
#ifdef __IS_COMPILER_ARM_COMPILER_6__
# undef __IS_COMPILER_ARM_COMPILER_6__
2021-11-09 22:19:51 +08:00
#endif
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
# define __IS_COMPILER_ARM_COMPILER_6__ 1
2021-11-09 22:19:51 +08:00
#endif
#ifdef __IS_COMPILER_LLVM__
# undef __IS_COMPILER_LLVM__
2021-11-09 22:19:51 +08:00
#endif
#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__
# define __IS_COMPILER_LLVM__ 1
2021-11-09 22:19:51 +08:00
#else
//! \note for gcc
# ifdef __IS_COMPILER_GCC__
# undef __IS_COMPILER_GCC__
# endif
# if defined(__GNUC__) && !( defined(__IS_COMPILER_ARM_COMPILER_5__) \
|| defined(__IS_COMPILER_ARM_COMPILER_6__) \
|| defined(__IS_COMPILER_LLVM__))
# define __IS_COMPILER_GCC__ 1
# endif
2021-11-09 22:19:51 +08:00
//! @}
#endif
//! @}
2021-11-09 22:19:51 +08:00
/*----------------------------------------------------------------------------*
* OOC and Private Protection *
*----------------------------------------------------------------------------*/
/*! \brief minimal support for OOPC
*/
#undef __implement_ex
#undef __implement
#undef implement
#undef implement_ex
#undef inherit
#undef inherit_ex
#define __implement_ex(__type, __name) \
union { \
__type __name; \
__type; \
}
2021-11-09 22:19:51 +08:00
#define __inherit_ex(__type, __name) \
__type __name \
2021-11-09 22:19:51 +08:00
#define __implement(__type) __implement_ex( __type, \
use_as__##__type)
2021-11-09 22:19:51 +08:00
#define __inherit(__type) __inherit_ex(__type,use_as__##__type)
2021-11-09 22:19:51 +08:00
#define implement(__type) __implement(__type)
#define implement_ex(__type, __name) __implement_ex(__type, __name)
#define inherit(__type) __inherit(__type)
#define inherit_ex(__type, __name) __inherit_ex(__type, __name)
2021-11-09 22:19:51 +08:00
/*----------------------------------------------------------------------------*
* Misc *
*----------------------------------------------------------------------------*/
#ifndef ARM_2D_UNUSED
# define ARM_2D_UNUSED(__VAR) (__VAR) = (__VAR)
2021-11-09 22:19:51 +08:00
#endif
#ifndef ARM_TEST_BITS
# define ARM_TEST_BITS(__VALUE, __BITS) ((__BITS) == ((__VALUE) & (__BITS)))
2021-11-09 22:19:51 +08:00
#endif
#ifndef dimof
# define dimof(__array) (sizeof(__array)/sizeof(__array[0]))
2021-11-09 22:19:51 +08:00
#endif
#define __ARM_TO_STRING(A) #A
#define TO_STRING(A) __ARM_TO_STRING(A)
#define __ARM_VA_NUM_ARGS_IMPL( _0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12, \
_13,_14,_15,_16,__N,...) __N
#define __ARM_VA_NUM_ARGS(...) \
__ARM_VA_NUM_ARGS_IMPL( 0,##__VA_ARGS__,16,15,14,13,12,11,10,9, \
8,7,6,5,4,3,2,1,0)
#define __ARM_CONNECT2(__A, __B) __A##__B
#define __ARM_CONNECT3(__A, __B, __C) __A##__B##__C
#define __ARM_CONNECT4(__A, __B, __C, __D) __A##__B##__C##__D
#define __ARM_CONNECT5(__A, __B, __C, __D, __E) __A##__B##__C##__D##__E
#define __ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
__A##__B##__C##__D##__E##__F
#define __ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
__A##__B##__C##__D##__E##__F##__G
#define __ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
__A##__B##__C##__D##__E##__F##__G##__H
#define __ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
__A##__B##__C##__D##__E##__F##__G##__H##__I
#define ARM_CONNECT2(__A, __B) __ARM_CONNECT2(__A, __B)
#define ARM_CONNECT3(__A, __B, __C) __ARM_CONNECT3(__A, __B, __C)
#define ARM_CONNECT4(__A, __B, __C, __D) __ARM_CONNECT4(__A, __B, __C, __D)
#define ARM_CONNECT5(__A, __B, __C, __D, __E) \
__ARM_CONNECT5(__A, __B, __C, __D, __E)
#define ARM_CONNECT6(__A, __B, __C, __D, __E, __F) \
__ARM_CONNECT6(__A, __B, __C, __D, __E, __F)
#define ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G) \
__ARM_CONNECT7(__A, __B, __C, __D, __E, __F, __G)
#define ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H) \
__ARM_CONNECT8(__A, __B, __C, __D, __E, __F, __G, __H)
#define ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I) \
__ARM_CONNECT9(__A, __B, __C, __D, __E, __F, __G, __H, __I)
#define arm_connect(...) \
ARM_CONNECT2(ARM_CONNECT, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define ARM_CONNECT(...) arm_connect(__VA_ARGS__)
#define __ARM_USING1(__declare) \
for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
)
#define __ARM_USING2(__declare, __on_leave_expr) \
for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL; \
__on_leave_expr \
)
#define __ARM_USING3(__declare, __on_enter_expr, __on_leave_expr) \
for (__declare, *ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr) = NULL; \
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
((__on_enter_expr),1) : 0; \
__on_leave_expr \
)
#define __ARM_USING4(__dcl1, __dcl2, __on_enter_expr, __on_leave_expr) \
for (__dcl1,__dcl2,*ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)= NULL;\
ARM_CONNECT3(__ARM_USING_, __LINE__,_ptr)++ == NULL ? \
((__on_enter_expr),1) : 0; \
__on_leave_expr \
)
#define arm_using(...) \
ARM_CONNECT2(__ARM_USING, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define __ARM_WITH2(__type, __addr) \
ARM_USING(__type *_p=(__addr))
#define __ARM_WITH3(__type, __addr, __item) \
ARM_USING(__type *_p=(__addr), *__item = _p, _p=_p, )
#define arm_with(...) \
ARM_CONNECT2(__ARM_WITH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define ARM_FOREACH2(__type, __array) \
arm_using(__type *_ = __array) \
for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
ARM_CONNECT2(count,__LINE__) > 0; \
_++, ARM_CONNECT2(count,__LINE__)-- \
)
#define ARM_FOREACH3(__type, __array, __item) \
arm_using(__type *_ = __array, *__item = _, _ = _, ) \
for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = dimof(__array);\
ARM_CONNECT2(count,__LINE__) > 0; \
_++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
)
#define ARM_FOREACH4(__type, __array, __count, __item) \
arm_using(__type *_ = __array, *__item = _, _ = _, ) \
for ( uint_fast32_t ARM_CONNECT2(count,__LINE__) = (__count); \
ARM_CONNECT2(count,__LINE__) > 0; \
_++, __item = _, ARM_CONNECT2(count,__LINE__)-- \
)
#define arm_foreach(...) \
ARM_CONNECT2(ARM_FOREACH, __ARM_VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)
2021-11-09 22:19:51 +08:00
#ifndef ARM_NONNULL
# if defined(__IS_COMPILER_ARM_COMPILER_5__) ||\
defined(__IS_COMPILER_ARM_COMPILER_6__) ||\
defined(__IS_COMPILER_GCC__) ||\
defined(__IS_COMPILER_LLVM__)
# define ARM_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
# else
# define ARM_NONNULL(...)
# endif
2021-11-09 22:19:51 +08:00
#endif
#ifndef ARM_NOINIT
# if defined(__IS_COMPILER_ARM_COMPILER_5__)
# define ARM_NOINIT __attribute__(( section( ".bss.noinit"),zero_init))
# elif defined(__IS_COMPILER_ARM_COMPILER_6__)
# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
# elif defined(__IS_COMPILER_IAR__)
# define ARM_NOINIT __no_init
# elif defined(__IS_COMPILER_GCC__) || defined(__IS_COMPILER_LLVM__)
# define ARM_NOINIT __attribute__(( section( ".bss.noinit")))
# else
# define ARM_NOINIT
# endif
2021-11-09 22:19:51 +08:00
#endif
2021-11-09 22:19:51 +08:00
#ifndef ARM_ALIGN
# define __ARM_ALIGN(__N) __attribute__((aligned(__N)))
# define ARM_ALIGN(__N) __ARM_ALIGN(__N)
2021-11-09 22:19:51 +08:00
#endif
2021-11-09 22:19:51 +08:00
#ifndef __RESTRICT
# define __RESTRICT __restrict
2021-11-09 22:19:51 +08:00
#endif
#ifndef __OVERRIDE_WEAK
# define __OVERRIDE_WEAK __USED
2021-11-09 22:19:51 +08:00
#endif
#define ARM_2D_SAFE_NAME(...) ARM_CONNECT(__,__LINE__,##__VA_ARGS__)
#define arm_2d_safe_name(...) ARM_2D_SAFE_NAME(__VA_ARGS__)
2021-11-09 22:19:51 +08:00
#undef arm_irq_safe
#define arm_irq_safe \
arm_using( uint32_t ARM_2D_SAFE_NAME(temp) = \
({uint32_t temp=__get_PRIMASK();__disable_irq();temp;}),\
__set_PRIMASK(ARM_2D_SAFE_NAME(temp)))
2021-11-09 22:19:51 +08:00
/*----------------------------------------------------------------------------*
* List Operations *
*----------------------------------------------------------------------------*/
/*! \note ALL the parameters passed to following macros must be pointer
*! variables.
*/
#define __ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
do { \
((__arm_slist_node_t *)(__P_NODE))->ptNext = \
(__arm_slist_node_t *)(__P_TOP); \
(*(__arm_slist_node_t **)&(__P_TOP)) = \
(__arm_slist_node_t *)(__P_NODE); \
} while(0)
#define ARM_LIST_STACK_PUSH(__P_TOP, __P_NODE) \
__ARM_LIST_STACK_PUSH((__P_TOP), (__P_NODE))
#define ARM_LIST_INSERT_AFTER(__P_TARGET, __P_NODE) \
__ARM_LIST_STACK_PUSH((__P_TARGET), (__P_NODE))
#define __ARM_LIST_STACK_POP(__P_TOP, __P_NODE) \
do { \
(*(__arm_slist_node_t **)&(__P_NODE)) = \
(__arm_slist_node_t *)(__P_TOP); \
if (NULL != (__P_TOP)) { \
(*(__arm_slist_node_t **)&(__P_TOP)) = \
((__arm_slist_node_t *)(__P_NODE))->ptNext; \
((__arm_slist_node_t *)(__P_NODE))->ptNext = NULL; \
} \
} while(0)
#define ARM_LIST_STACK_POP(__P_TOP, __P_NODE) __ARM_LIST_STACK_POP((__P_TOP), (__P_NODE))
#define ARM_LIST_REMOVE_AFTER(__P_TARGET, __P_NODE) \
ARM_LIST_STACK_POP((__P_TARGET), (__P_NODE))
#define __ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
do { \
if (NULL == (__TAIL)) { \
(*((__arm_slist_node_t **)&(__TAIL))) = \
(__arm_slist_node_t *)(__ITEM); \
((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
(*((__arm_slist_node_t **)&(__HEAD))) = \
(__arm_slist_node_t *)(__ITEM); \
} else { \
((__arm_slist_node_t *)(__TAIL))->ptNext = \
(__arm_slist_node_t *)(__ITEM); \
((__arm_slist_node_t *)(__ITEM))->ptNext = NULL; \
(*(__arm_slist_node_t **)&(__TAIL)) = \
(__arm_slist_node_t *)(__ITEM); \
} \
} while(0)
#define ARM_LIST_QUEUE_ENQUEUE(__HEAD, __TAIL, __ITEM) \
__ARM_LIST_QUEUE_ENQUEUE((__HEAD), (__TAIL), (__ITEM))
#define __ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
do { \
(*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
if (NULL != (__HEAD)) { \
(*(__arm_slist_node_t **)&(__HEAD)) = \
((__arm_slist_node_t *)(__HEAD))->ptNext; \
if (NULL == (__HEAD)) { \
(__TAIL) = NULL; \
} \
} \
} while(0)
#define ARM_LIST_QUEUE_DEQUEUE(__HEAD, __TAIL, __ITEM) \
__ARM_LIST_QUEUE_DEQUEUE((__HEAD), (__TAIL), (__ITEM))
#define __ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
do { \
(*(__arm_slist_node_t **)&(__ITEM)) = (__arm_slist_node_t *)(__HEAD); \
} while(0)
#define ARM_LIST_QUEUE_PEEK(__HEAD, __TAIL, __ITEM) \
__ARM_LIST_QUEUE_PEEK((__HEAD), (__TAIL), (__ITEM)) \
2021-11-09 22:19:51 +08:00
/*----------------------------------------------------------------------------*
* Definition Template *
*----------------------------------------------------------------------------*/
#define __def_low_lv_io(__NAME, __SW, ...) \
const __arm_2d_low_level_io_t LOW_LEVEL_IO##__NAME = { \
.SW = (__arm_2d_io_func_t *)&(__SW), \
.HW = (NULL, ##__VA_ARGS__) \
}
#define def_low_lv_io(__NAME, __SW, ...) \
__def_low_lv_io(__NAME, __SW, ##__VA_ARGS__)
2021-11-09 22:19:51 +08:00
#define __ref_low_lv_io(__NAME) &LOW_LEVEL_IO##__NAME
#define ref_low_lv_io(__NAME) __ref_low_lv_io(__NAME)
2021-11-09 22:19:51 +08:00
/*============================ TYPES =========================================*/
typedef struct __arm_slist_node_t __arm_slist_node_t;
struct __arm_slist_node_t {
__arm_slist_node_t *ptNext;
2021-11-09 22:19:51 +08:00
};
2021-11-09 22:19:51 +08:00
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ PROTOTYPES ====================================*/
#if defined(__clang__)
# pragma clang diagnostic pop
2021-11-09 22:19:51 +08:00
#elif __IS_COMPILER_ARM_COMPILER_5__
#elif __IS_COMPILER_GCC__
# pragma GCC diagnostic pop
2021-11-09 22:19:51 +08:00
#endif
#ifdef __cplusplus
2021-11-09 22:19:51 +08:00
}
#endif
#endif /* end of __ARM_2D_UTILS_H__ */
2021-11-09 22:19:51 +08:00
/*============================ MACROS ========================================*/
/*----------------------------------------------------------------------------*
* Reentrant Macros *
*----------------------------------------------------------------------------*/
/* un-define macros */
#undef ARM_PRIVATE
2021-11-09 22:19:51 +08:00
/* redefine macros */
#if defined(__ARM_2D_IMPL__) || defined(__IS_COMPILER_IAR__)
# define ARM_PRIVATE(...) \
struct { \
__VA_ARGS__ \
} __ALIGNED(__alignof__(struct {__VA_ARGS__}));
2021-11-09 22:19:51 +08:00
#else
# define ARM_PRIVATE(...) \
uint8_t ARM_CONNECT3(chMask,__LINE__,__COUNTER__) \
[sizeof(struct {__VA_ARGS__})] \
__ALIGNED(__alignof__(struct {__VA_ARGS__}));
2021-11-09 22:19:51 +08:00
#endif
2021-11-09 22:19:51 +08:00
/* post un-define macros */
#undef __ARM_2D_IMPL__