1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _PICO_TYPES_H
8 #define _PICO_TYPES_H
9 
10 #ifndef __ASSEMBLER__
11 
12 #include "pico/assert.h"
13 
14 #include <stdint.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 
18 typedef unsigned int uint;
19 
20 /*! \typedef absolute_time_t
21     \brief An opaque 64 bit timestamp in microseconds
22 
23     The type is used instead of a raw uint64_t to prevent accidentally passing relative times or times in the wrong
24     time units where an absolute time is required. It is equivalent to uint64_t in release builds.
25 
26     \see to_us_since_boot()
27     \see update_us_since_boot()
28     \ingroup timestamp
29 */
30 #ifdef NDEBUG
31 typedef uint64_t absolute_time_t;
32 #else
33 typedef struct {
34     uint64_t _private_us_since_boot;
35 } absolute_time_t;
36 #endif
37 
38 /*! fn to_us_since_boot
39  * \brief convert an absolute_time_t into a number of microseconds since boot.
40  * \param t the absolute time to convert
41  * \return a number of microseconds since boot, equivalent to t
42  * \ingroup timestamp
43  */
to_us_since_boot(absolute_time_t t)44 static inline uint64_t to_us_since_boot(absolute_time_t t) {
45 #ifdef NDEBUG
46     return t;
47 #else
48     return t._private_us_since_boot;
49 #endif
50 }
51 
52 /*! fn update_us_since_boot
53  * \brief update an absolute_time_t value to represent a given number of microseconds since boot
54  * \param t the absolute time value to update
55  * \param us_since_boot the number of microseconds since boot to represent. Note this should be representable
56  *                      as a signed 64 bit integer
57  * \ingroup timestamp
58  */
update_us_since_boot(absolute_time_t * t,uint64_t us_since_boot)59 static inline void update_us_since_boot(absolute_time_t *t, uint64_t us_since_boot) {
60 #ifdef NDEBUG
61     *t = us_since_boot;
62 #else
63     assert(us_since_boot <= INT64_MAX);
64     t->_private_us_since_boot = us_since_boot;
65 #endif
66 }
67 
68 /*! fn from_us_since_boot
69  * \brief convert a number of microseconds since boot to an absolute_time_t
70  * \param us_since_boot number of microseconds since boot
71  * \return an absolute time equivalent to us_since_boot
72  * \ingroup timestamp
73  */
from_us_since_boot(uint64_t us_since_boot)74 static inline absolute_time_t from_us_since_boot(uint64_t us_since_boot) {
75     absolute_time_t t;
76     update_us_since_boot(&t, us_since_boot);
77     return t;
78 }
79 
80 #ifdef NDEBUG
81 #define ABSOLUTE_TIME_INITIALIZED_VAR(name, value) name = value
82 #else
83 #define ABSOLUTE_TIME_INITIALIZED_VAR(name, value) name = {value}
84 #endif
85 
86 /** \struct datetime_t
87  *  \ingroup util_datetime
88  *  \brief Structure containing date and time information
89  *
90  *    When setting an RTC alarm, set a field to -1 tells
91  *    the RTC to not match on this field
92  */
93 typedef struct {
94     int16_t year;    ///< 0..4095
95     int8_t month;    ///< 1..12, 1 is January
96     int8_t day;      ///< 1..28,29,30,31 depending on month
97     int8_t dotw;     ///< 0..6, 0 is Sunday
98     int8_t hour;     ///< 0..23
99     int8_t min;      ///< 0..59
100     int8_t sec;      ///< 0..59
101 } datetime_t;
102 
103 #define bool_to_bit(x) ((uint)!!(x))
104 
105 #endif
106 #endif
107