Skip to content

Commit 04e0df1

Browse files
committed
prepare to split file
1 parent 6d58633 commit 04e0df1

File tree

1 file changed

+352
-0
lines changed

1 file changed

+352
-0
lines changed

src/usb/uf2/macros.h

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
/**
2+
3+
Microsoft UF2
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) Microsoft Corporation
8+
9+
All rights reserved.
10+
11+
Permission is hereby granted, free of charge, to any person obtaining a copy
12+
of this software and associated documentation files (the "Software"), to deal
13+
in the Software without restriction, including without limitation the rights
14+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
copies of the Software, and to permit persons to whom the Software is
16+
furnished to do so, subject to the following conditions:
17+
18+
The above copyright notice and this permission notice shall be included in all
19+
copies or substantial portions of the Software.
20+
21+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+
SOFTWARE.
28+
29+
*/
30+
#ifndef UF2FORMAT_H
31+
#define UF2FORMAT_H 1
32+
33+
#include "uf2cfg.h"
34+
35+
#include <stdint.h>
36+
#include <stdbool.h>
37+
38+
#include "app_util.h"
39+
40+
#include "dfu_types.h"
41+
42+
#define SD_MAGIC_NUMBER 0x51b1e5db
43+
#define SD_MAGIC_OK() (*((uint32_t*)(SOFTDEVICE_INFO_STRUCT_ADDRESS+4)) == 0x51b1e5db)
44+
extern bool sdRunning;
45+
46+
// All entries are little endian.
47+
48+
#define UF2_MAGIC_START0 0x0A324655UL // "UF2\n"
49+
#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected
50+
#define UF2_MAGIC_END 0x0AB16F30UL // Ditto
51+
52+
// If set, the block is "comment" and should not be flashed to the device
53+
#define UF2_FLAG_NOFLASH 0x00000001
54+
#define UF2_FLAG_FAMILYID 0x00002000
55+
56+
#define MAX_BLOCKS (FLASH_SIZE / 256 + 100)
57+
typedef struct {
58+
uint32_t numBlocks;
59+
uint32_t numWritten;
60+
uint8_t writtenMask[MAX_BLOCKS / 8 + 1];
61+
} WriteState;
62+
63+
typedef struct {
64+
// 32 byte header
65+
uint32_t magicStart0;
66+
uint32_t magicStart1;
67+
uint32_t flags;
68+
uint32_t targetAddr;
69+
uint32_t payloadSize;
70+
uint32_t blockNo;
71+
uint32_t numBlocks;
72+
uint32_t familyID;
73+
74+
// raw data;
75+
uint8_t data[476];
76+
77+
// store magic also at the end to limit damage from partial block reads
78+
uint32_t magicEnd;
79+
} UF2_Block;
80+
81+
typedef struct {
82+
uint8_t version;
83+
uint8_t ep_in;
84+
uint8_t ep_out;
85+
uint8_t reserved0;
86+
uint32_t cbw_tag;
87+
uint32_t blocks_remaining;
88+
uint8_t *buffer;
89+
} UF2_HandoverArgs;
90+
91+
typedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);
92+
typedef void (*UF2_HID_Handover_Handler)(int ep);
93+
94+
// this is required to be exactly 16 bytes long by the linker script
95+
typedef struct {
96+
void *reserved0;
97+
UF2_HID_Handover_Handler handoverHID;
98+
UF2_MSC_Handover_Handler handoverMSC;
99+
const char *info_uf2;
100+
} UF2_BInfo;
101+
102+
#define UF2_BINFO ((UF2_BInfo *)(APP_START_ADDRESS - sizeof(UF2_BInfo)))
103+
104+
static inline bool is_uf2_block(void *data) {
105+
UF2_Block *bl = (UF2_Block *)data;
106+
return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&
107+
bl->magicEnd == UF2_MAGIC_END;
108+
}
109+
110+
static inline bool in_uf2_bootloader_space(const void *addr) {
111+
return USER_FLASH_END <= (uint32_t)addr && (uint32_t)addr < FLASH_SIZE;
112+
}
113+
114+
115+
#ifdef UF2_DEFINE_HANDOVER
116+
static inline const char *uf2_info(void) {
117+
if (in_uf2_bootloader_space(UF2_BINFO->info_uf2))
118+
return UF2_BINFO->info_uf2;
119+
return "N/A";
120+
}
121+
122+
static inline void hf2_handover(uint8_t ep) {
123+
const char *board_info = UF2_BINFO->info_uf2;
124+
UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;
125+
126+
if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&
127+
((uint32_t)fn & 1)) {
128+
// Pass control to bootloader; never returns
129+
fn(ep & 0xf);
130+
}
131+
}
132+
133+
// the ep_in/ep_out are without the 0x80 mask
134+
// cbw_tag is in the same bit format as it came
135+
static inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,
136+
uint8_t ep_out, uint32_t cbw_tag) {
137+
if (!is_uf2_block(buffer))
138+
return;
139+
140+
const char *board_info = UF2_BINFO->info_uf2;
141+
UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;
142+
143+
if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&
144+
((uint32_t)fn & 1)) {
145+
UF2_HandoverArgs hand = {
146+
1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,
147+
};
148+
// Pass control to bootloader; never returns
149+
fn(&hand);
150+
}
151+
}
152+
#endif
153+
154+
#endif
155+
156+
#ifndef ARRAYSIZE2_H
157+
#define ARRAYSIZE2_H
158+
159+
#ifndef __has_feature
160+
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
161+
#endif
162+
163+
#if __cplusplus >= 199711L
164+
#pragma message "using Ivan J. Johnson's ARRAY_SIZE2"
165+
166+
// Works on older compilers, even Visual C++ 6....
167+
// Created by Ivan J. Johnson, March 06, 2007
168+
// See http://drdobbs.com/cpp/197800525?pgno=1
169+
//
170+
// Pseudocode:
171+
// if x is not an array
172+
// issue a compile-time error
173+
// else
174+
// use the traditional (non-typesafe) C99 COUNTOF expression
175+
//
176+
// If the argument is any of:
177+
// object of class type, such as an std::vector
178+
// floating-point type
179+
// function pointer
180+
// pointer-to-member
181+
// then the first reinterpret_cast<> is not legal (compiler error)
182+
//
183+
// The type for check1 is chosen and named to help understand
184+
// the cause of the error, because the class name is likely to
185+
// appear in the compiler error message.
186+
//
187+
// If check1 succeeds, then the argument must be one of:
188+
// an integral type
189+
// an enumerated type
190+
// a pointer to an object
191+
// an array
192+
//
193+
// Check2 expands approximately to sizeof(check_type(x, &x)),
194+
// where check_type is an overloaded function.
195+
// Because this is purely a compile-time computation,
196+
// the function is never really called or even implemented,
197+
// but it lets the compiler apply overload resolution,
198+
// which allows further type discrimination.
199+
// There are three possibilities to consider:
200+
// x is an integral type or enumerated type.
201+
// In this case, neither of the two function overloads
202+
// is a match, resulting in a compiler error.
203+
// x is a pointer to an object.
204+
// In this case, the first argument to check_type()
205+
// is a pointer and the second one is a pointer-to-pointer.
206+
// The best function match is the first overload of check_type,
207+
// the one that returns an incomplete type (Is_pointer).
208+
// However, because Is_pointer is an incomplete type,
209+
// sizeof(Is_pointer) is not a valid expression,
210+
// resulting in a compiler error.
211+
// x is an array.
212+
// In this case, the first argument to check_type()
213+
// is an array and the second is a pointer-to-array.
214+
// A pointer-to-array is *NOT* convertible to a
215+
// pointer-to-pointer, so the first overload of
216+
// check_type() is not a match.
217+
// However, an array IS convertible to a pointer,
218+
// and a pointer-to-array already is a pointer.
219+
// Any pointer is convertible to a void*,
220+
// so the second function overload is a match.
221+
// That overload returns a complete type (Is_array).
222+
// Because it's a complete type,
223+
// sizeof(Is_array) is a valid expression.
224+
// Thus, the compiler has EXCLUDED every possible type
225+
// except arrays via compilation errors before reaching
226+
// the third line.
227+
// Moreover, check1 and check2 are reduced to the value zero,
228+
// while the third line is the old type-unsafe C-style macro,
229+
// now made entirely type-safe.
230+
//
231+
// Additional benefits:
232+
// The result is itself constexpr
233+
//
234+
//
235+
#define ARRAY_SIZE2(arr) ( \
236+
0 * sizeof(reinterpret_cast<const ::Bad_arg_to_COUNTOF*>(arr)) + /*check1*/ \
237+
0 * sizeof(::Bad_arg_to_COUNTOF::check_type((arr), &(arr))) + /*check2*/ \
238+
sizeof(arr) / sizeof((arr)[0]) /* eval */ \
239+
)
240+
241+
struct Bad_arg_to_COUNTOF {
242+
class Is_pointer; // incomplete
243+
class Is_array {};
244+
template <typename T>
245+
static Is_pointer check_type(const T*, const T* const*);
246+
static Is_array check_type(const void*, const void*);
247+
};
248+
249+
#elif __cplusplus >= 201103L || /* any compiler claiming C++11 support */ \
250+
_MSC_VER >= 1900 || /* Visual C++ 2015 or higher */ \
251+
__has_feature(cxx_constexpr) /* CLang versions supporting constexp */
252+
253+
#pragma message "C++11 version ARRAY_SIZE2"
254+
255+
namespace detail
256+
{
257+
template <typename T, std::size_t N>
258+
constexpr std::size_t countof(T const (&)[N]) noexcept
259+
{
260+
return N;
261+
}
262+
} // namespace detail
263+
#define ARRAY_SIZE2(arr) detail::countof(arr)
264+
265+
#elif _MSC_VER // Visual C++ fallback
266+
267+
#pragma message "using Microsoft Visual C++ intrinsic ARRAY_SIZE2"
268+
#define ARRAY_SIZE2(arr) _countof(arr)
269+
270+
#elif __cplusplus >= 199711L && ( /* C++ 98 trick */ \
271+
defined(__INTEL_COMPILER) || \
272+
defined(__clang__) || \
273+
(defined(__GNUC__) && ( \
274+
(__GNUC__ > 4) || \
275+
(__GNUC__ == 4 && __GNUC_MINOR__ >= 4) \
276+
)))
277+
278+
#pragma message "C++98 version ARRAY_SIZE2"
279+
280+
template <typename T, std::size_t N>
281+
char(&_ArraySizeHelperRequiresArray(T(&)[N]))[N];
282+
#define ARRAY_SIZE2(x) sizeof(_ArraySizeHelperRequiresArray(x))
283+
284+
#else
285+
286+
#pragma message "Using type-unsafe version of ARRAY_SIZE2"
287+
// This is the worst-case scenario macro.
288+
// While it is valid C, it is NOT typesafe.
289+
// For example, if the parameter arr is a pointer instead of array,
290+
// the compiler will SILENTLY give a (likely) incorrect result.
291+
#define ARRAY_SIZE2(arr) sizeof(arr) / sizeof(arr[0])
292+
293+
#endif
294+
295+
296+
#endif // ARRAYSIZE2_H
297+
298+
299+
#ifndef COMPILE_DATE_H
300+
#define COMPILE_DATE_H
301+
302+
#define __YEAR_INT__ ((( \
303+
(__DATE__ [ 7u] - '0') * 10u + \
304+
(__DATE__ [ 8u] - '0')) * 10u + \
305+
(__DATE__ [ 9u] - '0')) * 10u + \
306+
(__DATE__ [10u] - '0'))
307+
308+
#define __MONTH_INT__ ( \
309+
(__DATE__ [2u] == 'n' && __DATE__ [1u] == 'a') ? 1u /*Jan*/ \
310+
: (__DATE__ [2u] == 'b' ) ? 2u /*Feb*/ \
311+
: (__DATE__ [2u] == 'r' && __DATE__ [1u] == 'a') ? 3u /*Mar*/ \
312+
: (__DATE__ [2u] == 'r' ) ? 4u /*Apr*/ \
313+
: (__DATE__ [2u] == 'y' ) ? 5u /*May*/ \
314+
: (__DATE__ [2u] == 'n' ) ? 6u /*Jun*/ \
315+
: (__DATE__ [2u] == 'l' ) ? 7u /*Jul*/ \
316+
: (__DATE__ [2u] == 'g' ) ? 8u /*Jul*/ \
317+
: (__DATE__ [2u] == 'p' ) ? 9u /*Jul*/ \
318+
: (__DATE__ [2u] == 't' ) ? 10u /*Jul*/ \
319+
: (__DATE__ [2u] == 'v' ) ? 11u /*Jul*/ \
320+
: 12u /*Dec*/ )
321+
322+
#define __DAY_INT__ ( \
323+
(__DATE__ [4u] == ' ' ? 0u : __DATE__ [4u] - '0') * 10u \
324+
+ (__DATE__ [5u] - '0') )
325+
326+
// __TIME__ expands to an eight-character string constant
327+
// "23:59:01", or (if cannot determine time) "??:??:??"
328+
#define __HOUR_INT__ ( \
329+
(__TIME__ [0u] == '?' ? 0u : __TIME__ [0u] - '0') * 10u \
330+
+ (__TIME__ [1u] == '?' ? 0u : __TIME__ [1u] - '0') )
331+
332+
#define __MINUTE_INT__ ( \
333+
(__TIME__ [3u] == '?' ? 0u : __TIME__ [3u] - '0') * 10u \
334+
+ (__TIME__ [4u] == '?' ? 0u : __TIME__ [4u] - '0') )
335+
336+
#define __SECONDS_INT__ ( \
337+
(__TIME__ [6u] == '?' ? 0u : __TIME__ [6u] - '0') * 10u \
338+
+ (__TIME__ [7u] == '?' ? 0u : __TIME__ [7u] - '0') )
339+
340+
341+
#define __DOSDATE__ ( \
342+
((__YEAR_INT__ - 1980u) << 9u) | \
343+
( __MONTH_INT__ << 5u) | \
344+
( __DAY_INT__ << 0u) )
345+
346+
#define __DOSTIME__ ( \
347+
( __HOUR_INT__ << 11u) | \
348+
( __MONTH_INT__ << 5u) | \
349+
( __DAY_INT__ << 0u) )
350+
351+
#endif // COMPILE_DATE_H
352+

0 commit comments

Comments
 (0)