1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 #pragma once
19 #include "types.h"
20 
21 #define abs(a)   (((a)>0)?((a)):(-(a)))
22 
23 #define cat2(i,j)       i##j
24 #define cat3(i,j,k)     i##j##k
25 
26 #ifndef min
27 #define min(a,b)	((a) < (b) ? (a) : (b))
28 #endif
29 
30 #ifndef max
31 #define max(a,b)	((a) > (b) ? (a): (b))
32 #endif
33 
34 #ifndef min2
35 #define min2(a,b)	((a) < (b) ? (a) : (b))
36 #endif
37 
38 #ifndef min3
39 #define min3(a,b,c)	min2(min2(a, b), c)
40 #endif
41 
42 #ifndef max2
43 #define max2(a,b)	((a) > (b) ? (a): (b))
44 #endif
45 
46 #ifndef max3
47 #define max3(a,b,c)	max2(max2(a, b), c)
48 #endif
49 
50 #define OFFSETOF(s, m) 			((unsigned int) &((s *)0)->m)
51 #define ROUND_INT(x, r)			(((x) + (r) - 1) / (r) * (r))
52 #define ROUND_TO_POW2(x, r)		(((x) + (r) - 1) & ~((r) - 1))
53 
54 //  direct memory access
55 #define U8_GET(addr)			(*(volatile unsigned char  *)(addr))
56 #define U16_GET(addr)			(*(volatile unsigned short *)(addr))
57 #define U32_GET(addr)			(*(volatile unsigned int  *)(addr))
58 
59 #define U8_SET(addr, v)			(*(volatile unsigned char  *)(addr) = (unsigned char)(v))
60 #define U16_SET(addr, v)		(*(volatile unsigned short *)(addr) = (unsigned short)(v))
61 #define U32_SET(addr, v)		(*(volatile unsigned int  *)(addr) = (v))
62 
63 #define U8_INC(addr)			U8_GET(addr) += 1
64 #define U16_INC(addr)			U16_GET(addr) += 1
65 #define U32_INC(addr)			U32_GET(addr) += 1
66 
67 #define U8_DEC(addr)			U8_GET(addr) -= 1
68 #define U16_DEC(addr)			U16_GET(addr) -= 1
69 #define U32_DEC(addr)			U32_GET(addr) -= 1
70 
71 #define U8_CPY(addr1,addr2)		U8_SET(addr1, U8_GET(addr2))
72 #define U16_CPY(addr1,addr2)	U16_SET(addr1, U16_GET(addr2))
73 #define U32_CPY(addr1,addr2)	U32_SET(addr1, U32_GET(addr2))
74 
75 #define MAKE_U16(h,l) 			((unsigned short)(((h) << 8) | (l)))
76 #define MAKE_U24(a,b,c)			((unsigned int)(((a) << 16) | ((b) << 8) | (c)))
77 #define MAKE_U32(a,b,c,d)		((unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d)))
78 
79 #define BOUND(x, l, m)			((x) < (l) ? (l) : ((x) > (m) ? (m) : (x)))
80 #define SET_BOUND(x, l, m)		((x) = BOUND(x, l, m))
81 #define BOUND_INC(x, m)			do{++(x); (x) = (x) < (m) ? (x) :0;} while(0)
82 #define BOUND_INC_POW2(x, m)	do{								\
83 									(x) = ((x)+1) & (m-1);		\
84 								}while(0)
85 
86 #define IS_POWER_OF_2(x)		(!(x & (x-1)))
87 #define IS_LITTLE_ENDIAN 		(*(unsigned short*)"\0\xff" > 0x100)
88 #define IS_4BYTE_ALIGN(x) 		(!(x & 3))
89 
90 #define IMPLIES(x, y) 			(!(x) || (y))
91 
92 // x > y ? 1 : (x ==y : 0 ? -1)
93 #define COMPARE(x, y) 			(((x) > (y)) - ((x) < (y)))
94 #define SIGN(x) 				COMPARE(x, 0)
95 
96 // better than xor swap:  http://stackoverflow.com/questions/3912699/why-swap-with-xor-works-fine-in-c-but-in-java-doesnt-some-puzzle
97 #define SWAP(x, y, T) 			do { T tmp = (x); (x) = (y); (y) = tmp; } while(0)
98 #define SORT2(a, b, T) 			do { if ((a) > (b)) SWAP((a), (b), T); } while (0)
99 
100 #define foreach(i, n) 			for(int i = 0; i < (n); ++i)
101 #define foreach_range(i, s, e) 	for(int i = (s); i < (e); ++i)
102 #define foreach_arr(i, arr) 	for(int i = 0; i < ARRAY_SIZE(arr); ++i)
103 
104 #define ARRAY_SIZE(a) 			(sizeof(a) / sizeof(*a))
105 
106 #define everyN(i, n) 			++(i); (i)=((i) < N ? (i) : 0); if(0 == (i))
107 
108 #define U16_HI(a)    (((a) >> 8) & 0xFF)
109 #define U16_LO(a)    ((a) & 0xFF)
110 
111 #define U32_BYTE0(a) ((a) & 0xFF)
112 #define U32_BYTE1(a) (((a) >> 8) & 0xFF)
113 #define U32_BYTE2(a) (((a) >> 16) & 0xFF)
114 #define U32_BYTE3(a) (((a) >> 24) & 0xFF)
115 
116 
117 
118 void swapN (unsigned char *p, int n);
119 void swapX(const u8 *src, u8 *dst, int len);
120 
121 void swap24(u8 dst[3], const u8 src[3]);
122 void swap32(u8 dst[4], const u8 src[4]);
123 void swap48(u8 dst[6], const u8 src[6]);
124 void swap56(u8 dst[7], const u8 src[7]);
125 
126 void swap64(u8 dst[8], const u8 src[8]);
127 
128 void swap128(u8 dst[16], const u8 src[16]);
129 
130 void flip_addr(u8 *dest, u8 *src);
131 
mul64_32x32(u32 u,u32 v)132 static inline u64 mul64_32x32(u32 u, u32 v)
133 {
134 #if 0 //Eagle HW support this process
135     u32  u0,   v0,   w0;
136     u32  u1,   v1,   w1,   w2,   t;
137     u32  x, y;
138 
139     u0   =   u & 0xFFFF;
140     u1   =   u >> 16;
141     v0   =   v & 0xFFFF;
142     v1   =   v >> 16;
143     w0   =   u0 * v0;
144     t    =   u1 * v0 + (w0 >> 16);
145     w1   =   t & 0xFFFF;
146     w2   =   t >> 16;
147     w1   =   u0 * v1 + w1;
148 
149     //x is high 32 bits, y is low 32 bits
150 
151     x = u1 * v1 + w2 + (w1 >> 16);
152     y = u * v;
153 
154 
155     return(((u64)x << 32) | y);
156 #else
157     return (u64)u*v;
158 #endif
159 }
160 
161 typedef	struct {
162 	u32		size;
163 	u16		num;
164 	u8		wptr;
165 	u8		rptr;
166 	u8*		p;
167 }	my_fifo_t;
168 
169 void my_fifo_init (my_fifo_t *f, int s, u8 n, u8 *p);
170 u8*  my_fifo_wptr (my_fifo_t *f);
171 u8*  my_fifo_wptr_v2 (my_fifo_t *f);
172 void my_fifo_next (my_fifo_t *f);
173 int  my_fifo_push (my_fifo_t *f, u8 *p, int n);
174 void my_fifo_pop (my_fifo_t *f);
175 u8 * my_fifo_get (my_fifo_t *f);
176 
177 #define		MYFIFO_INIT(name,size,n)			u8 name##_b[size * n]={0};my_fifo_t name = {size,n,0,0, name##_b}
178 
179 #define		MYFIFO_INIT_IRAM(name,size,n)		u8 name##_b[size * n]__attribute__((aligned(4)))/*={0}*/;my_fifo_t name = {size,n,0,0, name##_b}
180 
181 
182 #define		DATA_LENGTH_ALLIGN4(n)				((n + 3) / 4 * 4)
183 #define		DATA_LENGTH_ALLIGN16(n)				((n + 15) / 16 * 16)
184