Line data Source code
1 1 : /** @file
2 : * @brief Byte order helpers.
3 : */
4 :
5 : /*
6 : * Copyright (c) 2015-2016, Intel Corporation.
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : */
10 :
11 : #ifndef ZEPHYR_INCLUDE_SYS_BYTEORDER_H_
12 : #define ZEPHYR_INCLUDE_SYS_BYTEORDER_H_
13 :
14 : #include <zephyr/types.h>
15 : #include <stddef.h>
16 : #include <zephyr/sys/__assert.h>
17 : #include <zephyr/toolchain.h>
18 :
19 0 : #define BSWAP_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
20 0 : #define BSWAP_24(x) ((uint32_t) ((((x) >> 16) & 0xff) | \
21 : (((x)) & 0xff00) | \
22 : (((x) & 0xff) << 16)))
23 0 : #define BSWAP_32(x) ((uint32_t) ((((x) >> 24) & 0xff) | \
24 : (((x) >> 8) & 0xff00) | \
25 : (((x) & 0xff00) << 8) | \
26 : (((x) & 0xff) << 24)))
27 0 : #define BSWAP_40(x) ((uint64_t) ((((x) >> 32) & 0xff) | \
28 : (((x) >> 16) & 0xff00) | \
29 : (((x)) & 0xff0000) | \
30 : (((x) & 0xff00) << 16) | \
31 : (((x) & 0xff) << 32)))
32 0 : #define BSWAP_48(x) ((uint64_t) ((((x) >> 40) & 0xff) | \
33 : (((x) >> 24) & 0xff00) | \
34 : (((x) >> 8) & 0xff0000) | \
35 : (((x) & 0xff0000) << 8) | \
36 : (((x) & 0xff00) << 24) | \
37 : (((x) & 0xff) << 40)))
38 0 : #define BSWAP_64(x) ((uint64_t) ((((x) >> 56) & 0xff) | \
39 : (((x) >> 40) & 0xff00) | \
40 : (((x) >> 24) & 0xff0000) | \
41 : (((x) >> 8) & 0xff000000) | \
42 : (((x) & 0xff000000) << 8) | \
43 : (((x) & 0xff0000) << 24) | \
44 : (((x) & 0xff00) << 40) | \
45 : (((x) & 0xff) << 56)))
46 :
47 : /** @def sys_le16_to_cpu
48 : * @brief Convert 16-bit integer from little-endian to host endianness.
49 : *
50 : * @param val 16-bit integer in little-endian format.
51 : *
52 : * @return 16-bit integer in host endianness.
53 : */
54 :
55 : /** @def sys_cpu_to_le16
56 : * @brief Convert 16-bit integer from host endianness to little-endian.
57 : *
58 : * @param val 16-bit integer in host endianness.
59 : *
60 : * @return 16-bit integer in little-endian format.
61 : */
62 :
63 : /** @def sys_le24_to_cpu
64 : * @brief Convert 24-bit integer from little-endian to host endianness.
65 : *
66 : * @param val 24-bit integer in little-endian format.
67 : *
68 : * @return 24-bit integer in host endianness.
69 : */
70 :
71 : /** @def sys_cpu_to_le24
72 : * @brief Convert 24-bit integer from host endianness to little-endian.
73 : *
74 : * @param val 24-bit integer in host endianness.
75 : *
76 : * @return 24-bit integer in little-endian format.
77 : */
78 :
79 : /** @def sys_le32_to_cpu
80 : * @brief Convert 32-bit integer from little-endian to host endianness.
81 : *
82 : * @param val 32-bit integer in little-endian format.
83 : *
84 : * @return 32-bit integer in host endianness.
85 : */
86 :
87 : /** @def sys_cpu_to_le32
88 : * @brief Convert 32-bit integer from host endianness to little-endian.
89 : *
90 : * @param val 32-bit integer in host endianness.
91 : *
92 : * @return 32-bit integer in little-endian format.
93 : */
94 :
95 : /** @def sys_le48_to_cpu
96 : * @brief Convert 48-bit integer from little-endian to host endianness.
97 : *
98 : * @param val 48-bit integer in little-endian format.
99 : *
100 : * @return 48-bit integer in host endianness.
101 : */
102 :
103 : /** @def sys_cpu_to_le48
104 : * @brief Convert 48-bit integer from host endianness to little-endian.
105 : *
106 : * @param val 48-bit integer in host endianness.
107 : *
108 : * @return 48-bit integer in little-endian format.
109 : */
110 :
111 : /** @def sys_be16_to_cpu
112 : * @brief Convert 16-bit integer from big-endian to host endianness.
113 : *
114 : * @param val 16-bit integer in big-endian format.
115 : *
116 : * @return 16-bit integer in host endianness.
117 : */
118 :
119 : /** @def sys_cpu_to_be16
120 : * @brief Convert 16-bit integer from host endianness to big-endian.
121 : *
122 : * @param val 16-bit integer in host endianness.
123 : *
124 : * @return 16-bit integer in big-endian format.
125 : */
126 :
127 : /** @def sys_be24_to_cpu
128 : * @brief Convert 24-bit integer from big-endian to host endianness.
129 : *
130 : * @param val 24-bit integer in big-endian format.
131 : *
132 : * @return 24-bit integer in host endianness.
133 : */
134 :
135 : /** @def sys_cpu_to_be24
136 : * @brief Convert 24-bit integer from host endianness to big-endian.
137 : *
138 : * @param val 24-bit integer in host endianness.
139 : *
140 : * @return 24-bit integer in big-endian format.
141 : */
142 :
143 : /** @def sys_be32_to_cpu
144 : * @brief Convert 32-bit integer from big-endian to host endianness.
145 : *
146 : * @param val 32-bit integer in big-endian format.
147 : *
148 : * @return 32-bit integer in host endianness.
149 : */
150 :
151 : /** @def sys_cpu_to_be32
152 : * @brief Convert 32-bit integer from host endianness to big-endian.
153 : *
154 : * @param val 32-bit integer in host endianness.
155 : *
156 : * @return 32-bit integer in big-endian format.
157 : */
158 :
159 : /** @def sys_be48_to_cpu
160 : * @brief Convert 48-bit integer from big-endian to host endianness.
161 : *
162 : * @param val 48-bit integer in big-endian format.
163 : *
164 : * @return 48-bit integer in host endianness.
165 : */
166 :
167 : /** @def sys_cpu_to_be48
168 : * @brief Convert 48-bit integer from host endianness to big-endian.
169 : *
170 : * @param val 48-bit integer in host endianness.
171 : *
172 : * @return 48-bit integer in big-endian format.
173 : */
174 :
175 : /** @def sys_uint16_to_array
176 : * @brief Convert 16-bit unsigned integer to byte array.
177 : *
178 : * @details Byte order aware macro to treat an unsigned integer
179 : * as an array, rather than an integer literal. For example,
180 : * `0x0123` would be converted to `{0x01, 0x23}` for big endian
181 : * machines, and `{0x23, 0x01}` for little endian machines.
182 : *
183 : * @param val 16-bit unsigned integer.
184 : *
185 : * @return 16-bit unsigned integer as byte array.
186 : */
187 :
188 : /** @def sys_uint32_to_array
189 : * @brief Convert 32-bit unsigned integer to byte array.
190 : *
191 : * @details Byte order aware macro to treat an unsigned integer
192 : * as an array, rather than an integer literal. For example,
193 : * `0x01234567` would be converted to `{0x01, 0x23, 0x45, 0x67}`
194 : * for big endian machines, and `{0x67, 0x45, 0x23, 0x01}` for
195 : * little endian machines.
196 : *
197 : * @param val 32-bit unsigned integer.
198 : *
199 : * @return 32-bit unsigned integer as byte array.
200 : */
201 :
202 : /** @def sys_uint64_to_array
203 : * @brief Convert 64-bit unsigned integer to byte array.
204 : *
205 : * @details Byte order aware macro to treat an unsigned integer
206 : * as an array, rather than an integer literal. For example,
207 : * `0x0123456789abcdef` would be converted to
208 : * `{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}`
209 : * for big endian machines, and
210 : * `{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01}` for
211 : * little endian machines.
212 : *
213 : * @param val 64-bit unsigned integer.
214 : *
215 : * @return 64-bit unsigned integer as byte array.
216 : */
217 :
218 : #ifdef CONFIG_LITTLE_ENDIAN
219 : #define sys_le16_to_cpu(val) (val)
220 : #define sys_cpu_to_le16(val) (val)
221 : #define sys_le24_to_cpu(val) (val)
222 : #define sys_cpu_to_le24(val) (val)
223 : #define sys_le32_to_cpu(val) (val)
224 : #define sys_cpu_to_le32(val) (val)
225 : #define sys_le40_to_cpu(val) (val)
226 : #define sys_cpu_to_le40(val) (val)
227 : #define sys_le48_to_cpu(val) (val)
228 : #define sys_cpu_to_le48(val) (val)
229 : #define sys_le64_to_cpu(val) (val)
230 : #define sys_cpu_to_le64(val) (val)
231 : #define sys_be16_to_cpu(val) BSWAP_16(val)
232 : #define sys_cpu_to_be16(val) BSWAP_16(val)
233 : #define sys_be24_to_cpu(val) BSWAP_24(val)
234 : #define sys_cpu_to_be24(val) BSWAP_24(val)
235 : #define sys_be32_to_cpu(val) BSWAP_32(val)
236 : #define sys_cpu_to_be32(val) BSWAP_32(val)
237 : #define sys_be40_to_cpu(val) BSWAP_40(val)
238 : #define sys_cpu_to_be40(val) BSWAP_40(val)
239 : #define sys_be48_to_cpu(val) BSWAP_48(val)
240 : #define sys_cpu_to_be48(val) BSWAP_48(val)
241 : #define sys_be64_to_cpu(val) BSWAP_64(val)
242 : #define sys_cpu_to_be64(val) BSWAP_64(val)
243 :
244 : #define sys_uint16_to_array(val) { \
245 : ((val) & 0xff), \
246 : (((val) >> 8) & 0xff)}
247 :
248 : #define sys_uint32_to_array(val) { \
249 : ((val) & 0xff), \
250 : (((val) >> 8) & 0xff), \
251 : (((val) >> 16) & 0xff), \
252 : (((val) >> 24) & 0xff)}
253 :
254 : #define sys_uint64_to_array(val) { \
255 : ((val) & 0xff), \
256 : (((val) >> 8) & 0xff), \
257 : (((val) >> 16) & 0xff), \
258 : (((val) >> 24) & 0xff), \
259 : (((val) >> 32) & 0xff), \
260 : (((val) >> 40) & 0xff), \
261 : (((val) >> 48) & 0xff), \
262 : (((val) >> 56) & 0xff)}
263 :
264 : #else
265 1 : #define sys_le16_to_cpu(val) BSWAP_16(val)
266 1 : #define sys_cpu_to_le16(val) BSWAP_16(val)
267 1 : #define sys_le24_to_cpu(val) BSWAP_24(val)
268 1 : #define sys_cpu_to_le24(val) BSWAP_24(val)
269 1 : #define sys_le32_to_cpu(val) BSWAP_32(val)
270 1 : #define sys_cpu_to_le32(val) BSWAP_32(val)
271 0 : #define sys_le40_to_cpu(val) BSWAP_40(val)
272 0 : #define sys_cpu_to_le40(val) BSWAP_40(val)
273 1 : #define sys_le48_to_cpu(val) BSWAP_48(val)
274 1 : #define sys_cpu_to_le48(val) BSWAP_48(val)
275 0 : #define sys_le64_to_cpu(val) BSWAP_64(val)
276 0 : #define sys_cpu_to_le64(val) BSWAP_64(val)
277 1 : #define sys_be16_to_cpu(val) (val)
278 1 : #define sys_cpu_to_be16(val) (val)
279 1 : #define sys_be24_to_cpu(val) (val)
280 1 : #define sys_cpu_to_be24(val) (val)
281 1 : #define sys_be32_to_cpu(val) (val)
282 1 : #define sys_cpu_to_be32(val) (val)
283 0 : #define sys_be40_to_cpu(val) (val)
284 0 : #define sys_cpu_to_be40(val) (val)
285 1 : #define sys_be48_to_cpu(val) (val)
286 1 : #define sys_cpu_to_be48(val) (val)
287 0 : #define sys_be64_to_cpu(val) (val)
288 0 : #define sys_cpu_to_be64(val) (val)
289 :
290 1 : #define sys_uint16_to_array(val) { \
291 : (((val) >> 8) & 0xff), \
292 : ((val) & 0xff)}
293 :
294 1 : #define sys_uint32_to_array(val) { \
295 : (((val) >> 24) & 0xff), \
296 : (((val) >> 16) & 0xff), \
297 : (((val) >> 8) & 0xff), \
298 : ((val) & 0xff)}
299 :
300 1 : #define sys_uint64_to_array(val) { \
301 : (((val) >> 56) & 0xff), \
302 : (((val) >> 48) & 0xff), \
303 : (((val) >> 40) & 0xff), \
304 : (((val) >> 32) & 0xff), \
305 : (((val) >> 24) & 0xff), \
306 : (((val) >> 16) & 0xff), \
307 : (((val) >> 8) & 0xff), \
308 : ((val) & 0xff)}
309 :
310 : #endif
311 :
312 : /**
313 : * @brief Put a 16-bit integer as big-endian to arbitrary location.
314 : *
315 : * Put a 16-bit integer, originally in host endianness, to a
316 : * potentially unaligned memory location in big-endian format.
317 : *
318 : * @param val 16-bit integer in host endianness.
319 : * @param dst Destination memory address to store the result.
320 : */
321 1 : static inline void sys_put_be16(uint16_t val, uint8_t dst[2])
322 : {
323 : dst[0] = val >> 8;
324 : dst[1] = val;
325 : }
326 :
327 : /**
328 : * @brief Put a 24-bit integer as big-endian to arbitrary location.
329 : *
330 : * Put a 24-bit integer, originally in host endianness, to a
331 : * potentially unaligned memory location in big-endian format.
332 : *
333 : * @param val 24-bit integer in host endianness.
334 : * @param dst Destination memory address to store the result.
335 : */
336 1 : static inline void sys_put_be24(uint32_t val, uint8_t dst[3])
337 : {
338 : dst[0] = val >> 16;
339 : sys_put_be16(val, &dst[1]);
340 : }
341 :
342 : /**
343 : * @brief Put a 32-bit integer as big-endian to arbitrary location.
344 : *
345 : * Put a 32-bit integer, originally in host endianness, to a
346 : * potentially unaligned memory location in big-endian format.
347 : *
348 : * @param val 32-bit integer in host endianness.
349 : * @param dst Destination memory address to store the result.
350 : */
351 1 : static inline void sys_put_be32(uint32_t val, uint8_t dst[4])
352 : {
353 : sys_put_be16(val >> 16, dst);
354 : sys_put_be16(val, &dst[2]);
355 : }
356 : /**
357 : * @brief Put a 40-bit integer as big-endian to arbitrary location.
358 : *
359 : * Put a 40-bit integer, originally in host endianness, to a
360 : * potentially unaligned memory location in big-endian format.
361 : *
362 : * @param val 40-bit integer in host endianness.
363 : * @param dst Destination memory address to store the result.
364 : */
365 1 : static inline void sys_put_be40(uint64_t val, uint8_t dst[5])
366 : {
367 : dst[0] = val >> 32;
368 : sys_put_be32(val, &dst[1]);
369 : }
370 :
371 : /**
372 : * @brief Put a 48-bit integer as big-endian to arbitrary location.
373 : *
374 : * Put a 48-bit integer, originally in host endianness, to a
375 : * potentially unaligned memory location in big-endian format.
376 : *
377 : * @param val 48-bit integer in host endianness.
378 : * @param dst Destination memory address to store the result.
379 : */
380 1 : static inline void sys_put_be48(uint64_t val, uint8_t dst[6])
381 : {
382 : sys_put_be16(val >> 32, dst);
383 : sys_put_be32(val, &dst[2]);
384 : }
385 :
386 : /**
387 : * @brief Put a 64-bit integer as big-endian to arbitrary location.
388 : *
389 : * Put a 64-bit integer, originally in host endianness, to a
390 : * potentially unaligned memory location in big-endian format.
391 : *
392 : * @param val 64-bit integer in host endianness.
393 : * @param dst Destination memory address to store the result.
394 : */
395 1 : static inline void sys_put_be64(uint64_t val, uint8_t dst[8])
396 : {
397 : sys_put_be32(val >> 32, dst);
398 : sys_put_be32(val, &dst[4]);
399 : }
400 :
401 : /**
402 : * @brief Put a 16-bit integer as little-endian to arbitrary location.
403 : *
404 : * Put a 16-bit integer, originally in host endianness, to a
405 : * potentially unaligned memory location in little-endian format.
406 : *
407 : * @param val 16-bit integer in host endianness.
408 : * @param dst Destination memory address to store the result.
409 : */
410 1 : static inline void sys_put_le16(uint16_t val, uint8_t dst[2])
411 : {
412 : dst[0] = val;
413 : dst[1] = val >> 8;
414 : }
415 :
416 : /**
417 : * @brief Put a 24-bit integer as little-endian to arbitrary location.
418 : *
419 : * Put a 24-bit integer, originally in host endianness, to a
420 : * potentially unaligned memory location in little-endian format.
421 : *
422 : * @param val 24-bit integer in host endianness.
423 : * @param dst Destination memory address to store the result.
424 : */
425 1 : static inline void sys_put_le24(uint32_t val, uint8_t dst[3])
426 : {
427 : sys_put_le16(val, dst);
428 : dst[2] = val >> 16;
429 : }
430 :
431 : /**
432 : * @brief Put a 32-bit integer as little-endian to arbitrary location.
433 : *
434 : * Put a 32-bit integer, originally in host endianness, to a
435 : * potentially unaligned memory location in little-endian format.
436 : *
437 : * @param val 32-bit integer in host endianness.
438 : * @param dst Destination memory address to store the result.
439 : */
440 1 : static inline void sys_put_le32(uint32_t val, uint8_t dst[4])
441 : {
442 : sys_put_le16(val, dst);
443 : sys_put_le16(val >> 16, &dst[2]);
444 : }
445 :
446 : /**
447 : * @brief Put a 40-bit integer as little-endian to arbitrary location.
448 : *
449 : * Put a 40-bit integer, originally in host endianness, to a
450 : * potentially unaligned memory location in little-endian format.
451 : *
452 : * @param val 40-bit integer in host endianness.
453 : * @param dst Destination memory address to store the result.
454 : */
455 1 : static inline void sys_put_le40(uint64_t val, uint8_t dst[5])
456 : {
457 : sys_put_le32(val, dst);
458 : dst[4] = val >> 32;
459 : }
460 :
461 : /**
462 : * @brief Put a 48-bit integer as little-endian to arbitrary location.
463 : *
464 : * Put a 48-bit integer, originally in host endianness, to a
465 : * potentially unaligned memory location in little-endian format.
466 : *
467 : * @param val 48-bit integer in host endianness.
468 : * @param dst Destination memory address to store the result.
469 : */
470 1 : static inline void sys_put_le48(uint64_t val, uint8_t dst[6])
471 : {
472 : sys_put_le32(val, dst);
473 : sys_put_le16(val >> 32, &dst[4]);
474 : }
475 :
476 : /**
477 : * @brief Put a 64-bit integer as little-endian to arbitrary location.
478 : *
479 : * Put a 64-bit integer, originally in host endianness, to a
480 : * potentially unaligned memory location in little-endian format.
481 : *
482 : * @param val 64-bit integer in host endianness.
483 : * @param dst Destination memory address to store the result.
484 : */
485 1 : static inline void sys_put_le64(uint64_t val, uint8_t dst[8])
486 : {
487 : sys_put_le32(val, dst);
488 : sys_put_le32(val >> 32, &dst[4]);
489 : }
490 :
491 : /**
492 : * @brief Get a 16-bit integer stored in big-endian format.
493 : *
494 : * Get a 16-bit integer, stored in big-endian format in a potentially
495 : * unaligned memory location, and convert it to the host endianness.
496 : *
497 : * @param src Location of the big-endian 16-bit integer to get.
498 : *
499 : * @return 16-bit integer in host endianness.
500 : */
501 1 : static inline uint16_t sys_get_be16(const uint8_t src[2])
502 : {
503 : return ((uint16_t)src[0] << 8) | src[1];
504 : }
505 :
506 : /**
507 : * @brief Get a 24-bit integer stored in big-endian format.
508 : *
509 : * Get a 24-bit integer, stored in big-endian format in a potentially
510 : * unaligned memory location, and convert it to the host endianness.
511 : *
512 : * @param src Location of the big-endian 24-bit integer to get.
513 : *
514 : * @return 24-bit integer in host endianness.
515 : */
516 1 : static inline uint32_t sys_get_be24(const uint8_t src[3])
517 : {
518 : return ((uint32_t)src[0] << 16) | sys_get_be16(&src[1]);
519 : }
520 :
521 : /**
522 : * @brief Get a 32-bit integer stored in big-endian format.
523 : *
524 : * Get a 32-bit integer, stored in big-endian format in a potentially
525 : * unaligned memory location, and convert it to the host endianness.
526 : *
527 : * @param src Location of the big-endian 32-bit integer to get.
528 : *
529 : * @return 32-bit integer in host endianness.
530 : */
531 1 : static inline uint32_t sys_get_be32(const uint8_t src[4])
532 : {
533 : return ((uint32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]);
534 : }
535 :
536 : /**
537 : * @brief Get a 40-bit integer stored in big-endian format.
538 : *
539 : * Get a 40-bit integer, stored in big-endian format in a potentially
540 : * unaligned memory location, and convert it to the host endianness.
541 : *
542 : * @param src Location of the big-endian 40-bit integer to get.
543 : *
544 : * @return 40-bit integer in host endianness.
545 : */
546 1 : static inline uint64_t sys_get_be40(const uint8_t src[5])
547 : {
548 : return ((uint64_t)sys_get_be32(&src[0]) << 8) | src[4];
549 : }
550 :
551 : /**
552 : * @brief Get a 48-bit integer stored in big-endian format.
553 : *
554 : * Get a 48-bit integer, stored in big-endian format in a potentially
555 : * unaligned memory location, and convert it to the host endianness.
556 : *
557 : * @param src Location of the big-endian 48-bit integer to get.
558 : *
559 : * @return 48-bit integer in host endianness.
560 : */
561 1 : static inline uint64_t sys_get_be48(const uint8_t src[6])
562 : {
563 : return ((uint64_t)sys_get_be32(&src[0]) << 16) | sys_get_be16(&src[4]);
564 : }
565 :
566 : /**
567 : * @brief Get a 64-bit integer stored in big-endian format.
568 : *
569 : * Get a 64-bit integer, stored in big-endian format in a potentially
570 : * unaligned memory location, and convert it to the host endianness.
571 : *
572 : * @param src Location of the big-endian 64-bit integer to get.
573 : *
574 : * @return 64-bit integer in host endianness.
575 : */
576 1 : static inline uint64_t sys_get_be64(const uint8_t src[8])
577 : {
578 : return ((uint64_t)sys_get_be32(&src[0]) << 32) | sys_get_be32(&src[4]);
579 : }
580 :
581 : /**
582 : * @brief Get a 16-bit integer stored in little-endian format.
583 : *
584 : * Get a 16-bit integer, stored in little-endian format in a potentially
585 : * unaligned memory location, and convert it to the host endianness.
586 : *
587 : * @param src Location of the little-endian 16-bit integer to get.
588 : *
589 : * @return 16-bit integer in host endianness.
590 : */
591 1 : static inline uint16_t sys_get_le16(const uint8_t src[2])
592 : {
593 : return ((uint16_t)src[1] << 8) | src[0];
594 : }
595 :
596 : /**
597 : * @brief Get a 24-bit integer stored in little-endian format.
598 : *
599 : * Get a 24-bit integer, stored in little-endian format in a potentially
600 : * unaligned memory location, and convert it to the host endianness.
601 : *
602 : * @param src Location of the little-endian 24-bit integer to get.
603 : *
604 : * @return 24-bit integer in host endianness.
605 : */
606 1 : static inline uint32_t sys_get_le24(const uint8_t src[3])
607 : {
608 : return ((uint32_t)src[2] << 16) | sys_get_le16(&src[0]);
609 : }
610 :
611 : /**
612 : * @brief Get a 32-bit integer stored in little-endian format.
613 : *
614 : * Get a 32-bit integer, stored in little-endian format in a potentially
615 : * unaligned memory location, and convert it to the host endianness.
616 : *
617 : * @param src Location of the little-endian 32-bit integer to get.
618 : *
619 : * @return 32-bit integer in host endianness.
620 : */
621 1 : static inline uint32_t sys_get_le32(const uint8_t src[4])
622 : {
623 : return ((uint32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]);
624 : }
625 :
626 : /**
627 : * @brief Get a 40-bit integer stored in little-endian format.
628 : *
629 : * Get a 40-bit integer, stored in little-endian format in a potentially
630 : * unaligned memory location, and convert it to the host endianness.
631 : *
632 : * @param src Location of the little-endian 40-bit integer to get.
633 : *
634 : * @return 40-bit integer in host endianness.
635 : */
636 1 : static inline uint64_t sys_get_le40(const uint8_t src[5])
637 : {
638 : return ((uint64_t)sys_get_le32(&src[1]) << 8) | src[0];
639 : }
640 :
641 : /**
642 : * @brief Get a 48-bit integer stored in little-endian format.
643 : *
644 : * Get a 48-bit integer, stored in little-endian format in a potentially
645 : * unaligned memory location, and convert it to the host endianness.
646 : *
647 : * @param src Location of the little-endian 48-bit integer to get.
648 : *
649 : * @return 48-bit integer in host endianness.
650 : */
651 1 : static inline uint64_t sys_get_le48(const uint8_t src[6])
652 : {
653 : return ((uint64_t)sys_get_le32(&src[2]) << 16) | sys_get_le16(&src[0]);
654 : }
655 :
656 : /**
657 : * @brief Get a 64-bit integer stored in little-endian format.
658 : *
659 : * Get a 64-bit integer, stored in little-endian format in a potentially
660 : * unaligned memory location, and convert it to the host endianness.
661 : *
662 : * @param src Location of the little-endian 64-bit integer to get.
663 : *
664 : * @return 64-bit integer in host endianness.
665 : */
666 1 : static inline uint64_t sys_get_le64(const uint8_t src[8])
667 : {
668 : return ((uint64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]);
669 : }
670 :
671 : /**
672 : * @brief Swap one buffer content into another
673 : *
674 : * Copy the content of src buffer into dst buffer in reversed order,
675 : * i.e.: src[n] will be put in dst[end-n]
676 : * Where n is an index and 'end' the last index in both arrays.
677 : * The 2 memory pointers must be pointing to different areas, and have
678 : * a minimum size of given length.
679 : *
680 : * @param dst A valid pointer on a memory area where to copy the data in
681 : * @param src A valid pointer on a memory area where to copy the data from
682 : * @param length Size of both dst and src memory areas
683 : */
684 1 : static inline void sys_memcpy_swap(void *dst, const void *src, size_t length)
685 : {
686 : uint8_t *pdst = (uint8_t *)dst;
687 : const uint8_t *psrc = (const uint8_t *)src;
688 :
689 : __ASSERT(((psrc < pdst && (psrc + length) <= pdst) ||
690 : (psrc > pdst && (pdst + length) <= psrc)),
691 : "Source and destination buffers must not overlap");
692 :
693 : psrc += length - 1;
694 :
695 : for (; length > 0; length--) {
696 : *pdst++ = *psrc--;
697 : }
698 : }
699 :
700 : /**
701 : * @brief Swap buffer content
702 : *
703 : * In-place memory swap, where final content will be reversed.
704 : * I.e.: buf[n] will be put in buf[end-n]
705 : * Where n is an index and 'end' the last index of buf.
706 : *
707 : * @param buf A valid pointer on a memory area to swap
708 : * @param length Size of buf memory area
709 : */
710 1 : static inline void sys_mem_swap(void *buf, size_t length)
711 : {
712 : size_t i;
713 :
714 : for (i = 0; i < (length/2); i++) {
715 : uint8_t tmp = ((uint8_t *)buf)[i];
716 :
717 : ((uint8_t *)buf)[i] = ((uint8_t *)buf)[length - 1 - i];
718 : ((uint8_t *)buf)[length - 1 - i] = tmp;
719 : }
720 : }
721 :
722 : #endif /* ZEPHYR_INCLUDE_SYS_BYTEORDER_H_ */
|