1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
112
113
114
122
123
124
125
128
129
132
133
134
135
136
137
138
139
140
141
142
143
144
149
154
159
160
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
185
186
187
188
189
190
191
195
196
197
198
199
200
201
202
203
208
209
214
215
220
221
226
227
228
229
230
231
232
233
238
239
240
241
242
243
244
245
246
247
248
253
254
260
261
262
263
264
265
268
269
272
273
276
277
280
281
282
283
284
285
286
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
310
311
312
313
314
315
316
/* ... */
#ifndef _TUSB_COMMON_H_
#define _TUSB_COMMON_H_
#ifdef __cplusplus
extern "C" {
#endif
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
#define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) )
#define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) )
#define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d))
#define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low)))
#define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff))
#define TU_U16_LOW(_u16) ((uint8_t) ((_u16) & 0x00ff))
#define U16_TO_U8S_BE(_u16) TU_U16_HIGH(_u16), TU_U16_LOW(_u16)
#define U16_TO_U8S_LE(_u16) TU_U16_LOW(_u16), TU_U16_HIGH(_u16)
#define TU_U32_BYTE3(_u32) ((uint8_t) ((((uint32_t) _u32) >> 24) & 0x000000ff))
#define TU_U32_BYTE2(_u32) ((uint8_t) ((((uint32_t) _u32) >> 16) & 0x000000ff))
#define TU_U32_BYTE1(_u32) ((uint8_t) ((((uint32_t) _u32) >> 8) & 0x000000ff))
#define TU_U32_BYTE0(_u32) ((uint8_t) (((uint32_t) _u32) & 0x000000ff))
#define U32_TO_U8S_BE(_u32) TU_U32_BYTE3(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE0(_u32)
#define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32)
#define TU_BIT(n) (1UL << (n))
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
17 defines
#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "tusb_option.h"
#include "tusb_compiler.h"
#include "tusb_verify.h"
#include "tusb_types.h"
#include "tusb_debug.h"
11 includes
TU_ATTR_WEAK extern void tusb_app_dcache_flush(uintptr_t addr, uint32_t data_size);
TU_ATTR_WEAK extern void tusb_app_dcache_invalidate(uintptr_t addr, uint32_t data_size);
TU_ATTR_WEAK extern void* tusb_app_virt_to_phys(void *virt_addr);
TU_ATTR_WEAK extern void* tusb_app_phys_to_virt(void *phys_addr);
#define tu_memclr(buffer, size) memset((buffer), 0, (size))
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) {
if ( count > destsz ) {
return -1;
}if (count > destsz) { ... }
memset(dest, ch, count);
return 0;
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) {
if ( count > destsz ) {
return -1;
}if (count > destsz) { ... }
memcpy(dest, src, count);
return 0;
}{ ... }
Mem
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) {
return ( ((uint32_t) b3) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b1) << 8) | b0;
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) {
return (uint16_t) ((((uint16_t) high) << 8) | low);
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte3(uint32_t ui32) { return TU_U32_BYTE3(ui32); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return TU_U32_BYTE2(ui32); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t ui32) { return (uint16_t) (ui32 >> 16); }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t ui32) { return (uint16_t) (ui32 & 0x0000ffffu); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); }
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); }
Bytes
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); }
TU_ATTR_ALWAYS_INLINE static inline bool tu_bit_test (uint32_t value, uint8_t pos) { return (value & TU_BIT(pos)) ? true : false; }
Bits
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_min8 (uint8_t x, uint8_t y ) { return (x < y) ? x : y; }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_min16 (uint16_t x, uint16_t y) { return (x < y) ? x : y; }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_min32 (uint32_t x, uint32_t y) { return (x < y) ? x : y; }
Min
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_max8 (uint8_t x, uint8_t y ) { return (x > y) ? x : y; }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { return (x > y) ? x : y; }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; }
Max
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) {
return value & ((uint32_t) ~(alignment-1));
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4 (uint32_t value) { return (value & 0xFFFFFFFCUL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align8 (uint32_t value) { return (value & 0xFFFFFFF8UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); }
TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { return (value & 0x1FUL) == 0; }
TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; }
Align
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; }
static inline uint8_t tu_log2(uint32_t value)
{
uint8_t result = 0;
while (value >>= 1) { result++; }
return result;
}{ ... }
static inline bool tu_is_power_of_two(uint32_t value)
{
return (value != 0) && ((value & (value - 1)) == 0);
}{ ... }
Mathematics
#if TUP_ARCH_STRICT_ALIGN
typedef struct { uint16_t val; } TU_ATTR_PACKED tu_unaligned_uint16_t;
typedef struct { uint32_t val; } TU_ATTR_PACKED tu_unaligned_uint32_t;
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void* mem)
{
tu_unaligned_uint32_t const* ua32 = (tu_unaligned_uint32_t const*) mem;
return ua32->val;
}tu_unaligned_read32 (const void* mem) { ... }
TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void* mem, uint32_t value)
{
tu_unaligned_uint32_t* ua32 = (tu_unaligned_uint32_t*) mem;
ua32->val = value;
}tu_unaligned_write32 (void* mem, uint32_t value) { ... }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void* mem)
{
tu_unaligned_uint16_t const* ua16 = (tu_unaligned_uint16_t const*) mem;
return ua16->val;
}tu_unaligned_read16 (const void* mem) { ... }
TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_t value)
{
tu_unaligned_uint16_t* ua16 = (tu_unaligned_uint16_t*) mem;
ua16->val = value;
}tu_unaligned_write16 (void* mem, uint16_t value) { ... }
/* ... */
#elif TUP_MCU_STRICT_ALIGN
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void* mem)
{
volatile uint8_t const* buf8 = (uint8_t const*) mem;
return tu_u32(buf8[3], buf8[2], buf8[1], buf8[0]);
}tu_unaligned_read32 (const void* mem) { ... }
TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void* mem, uint32_t value)
{
volatile uint8_t* buf8 = (uint8_t*) mem;
buf8[0] = tu_u32_byte0(value);
buf8[1] = tu_u32_byte1(value);
buf8[2] = tu_u32_byte2(value);
buf8[3] = tu_u32_byte3(value);
}tu_unaligned_write32 (void* mem, uint32_t value) { ... }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void* mem)
{
volatile uint8_t const* buf8 = (uint8_t const*) mem;
return tu_u16(buf8[1], buf8[0]);
}tu_unaligned_read16 (const void* mem) { ... }
TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_t value)
{
volatile uint8_t* buf8 = (uint8_t*) mem;
buf8[0] = tu_u16_low(value);
buf8[1] = tu_u16_high(value);
}tu_unaligned_write16 (void* mem, uint16_t value) { ... }
/* ... */
#else
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) {
return *((uint32_t const *) mem);
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) {
return *((uint16_t const *) mem);
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) {
*((uint32_t *) mem) = value;
}{ ... }
TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) {
*((uint16_t *) mem) = value;
}{ ... }
/* ... */#endif
Unaligned Access
#if defined(__GNUC__) && !defined(__CC_ARM)
#define TU_BIN8(x) ((uint8_t) (0b##x))
#define TU_BIN16(b1, b2) ((uint16_t) (0b##b1##b2))
#define TU_BIN32(b1, b2, b3, b4) ((uint32_t) (0b##b1##b2##b3##b4))
/* ... */
#else
#define _B8__(x) (((x&0x0000000FUL)?1:0) \
+((x&0x000000F0UL)?2:0) \
+((x&0x00000F00UL)?4:0) \
+((x&0x0000F000UL)?8:0) \
+((x&0x000F0000UL)?16:0) \
+((x&0x00F00000UL)?32:0) \
+((x&0x0F000000UL)?64:0) \
+((x&0xF0000000UL)?128:0))...
#define TU_BIN8(d) ((uint8_t) _B8__(0x##d##UL))
#define TU_BIN16(dmsb,dlsb) (((uint16_t)TU_BIN8(dmsb)<<8) + TU_BIN8(dlsb))
#define TU_BIN32(dmsb,db2,db3,dlsb) \
(((uint32_t)TU_BIN8(dmsb)<<24) \
+ ((uint32_t)TU_BIN8(db2)<<16) \
+ ((uint32_t)TU_BIN8(db3)<<8) \
+ TU_BIN8(dlsb))...
/* ... */#endif
#ifdef __cplusplus
}extern "C" { ... }
#endif
/* ... */
#endif