]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/include/binary.h
cccaa88bb3cde74ca46ce6648218a7fb62d0bbc3
[pes-rpp/rpp-lib.git] / rpp / include / binary.h
1 /**
2  * RPP binary handling header file.
3  * This file contains helpful macros for binary and bit manipulation.
4  *
5  * @file binary.h
6  *
7  * @copyright Copyright (C) 2013 Czech Technical University in Prague
8  *
9  * @author Carlos Jenkins <carlos@jenkins.co.cr>
10  */
11
12 #ifndef __RPP_BINARY_H
13 #define __RPP_BINARY_H
14
15 // Discussion about binary macros here:
16 // http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=60729
17
18 /**
19  * Create a bit mask for given bit number.
20  * For example:
21  *  - _BV(7) -> B[1000 0000]
22  *  - _BV(1) -> B[0000 0010]
23  *  - _BV(0) -> B[0000 0001]
24  *
25  * The function name stands for Bit Value, in reference that the mask is created
26  * only with the given bit number set.
27  *
28  * @param[in] bit       Bit number to create the mask, starting at 0 for the
29  *                      least-significant (rightmost) bit.
30  *
31  * @return A mask with all bits clear except the given bit number.
32  */
33 #define _BV(bit) (1UL << (bit))
34
35 /**
36  * Reads a bit of a number.
37  *
38  * @param[out] value    The number from which to read.
39  * @param[in] bit       Which bit number to read, starting at 0 for the
40  *                      least-significant (rightmost) bit.
41  *
42  * @return The value of the bit (0 or 1).
43  */
44 #define bit_read(value, bit) (((value) >> (bit)) & 0x01)
45
46
47 /**
48  * Sets (writes a 1 to) a bit of a numeric variable.
49  *
50  * @param[out] value    The numeric variable whose bit to set.
51  * @param[in] bit       Which bit number to set, starting at 0 for the
52  *                      least-significant (rightmost) bit
53  *
54  * @return None.
55  */
56 #define bit_set(value, bit) ((value) |= (1UL << (bit)))
57
58
59 /**
60  * Clears (writes a 0 to) a bit of a numeric variable.
61  *
62  * @param[out] value    The numeric variable whose bit to clear.
63  * @param[in] bit       Which bit number to clear, starting at 0 for the
64  *                      least-significant (rightmost) bit.
65  *
66  * @return None.
67  */
68 #define bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
69
70
71 /**
72  * Writes a bit of a numeric variable.
73  *
74  * @param[out] value    The numeric variable to which to write.
75  * @param[in] bit       Which bit number to write, starting at 0 for the
76  *                      least-significant (rightmost) bit.
77  * @param[in] bit_value The value to write to the bit (0 or 1).
78  *
79  * @return None.
80  */
81 #define bit_write(value, bit, bit_value) (bit_value ? bit_set(value, bit) : bit_clear(value, bit))
82
83
84 /**
85  * Check if given numeric value has it's given bit number set.
86  *
87  * @param[in] value     The numeric variable to which bit check.
88  * @param[in] bit       Which bit number to check, starting at 0 for the
89  *                      least-significant (rightmost) bit.
90  *
91  * @return TRUE if bit is set, FALSE if not.
92  */
93 #define is_bit_set(value, bit) (bit_read(value, bit) == 1)
94
95
96 /**
97  * Check if given numeric value has it's given bit number clear.
98  *
99  * @param[in] value     The numeric variable to which bit check.
100  * @param[in] bit       Which bit number to check, starting at 0 for the
101  *                      least-significant (rightmost) bit.
102  *
103  * @return TRUE if bit is clear, FALSE if not.
104  */
105 #define is_bit_clear(value, bit) (bit_read(value, bit) == 0)
106
107
108 /**
109  * @brief Set value at position specified by mask.
110  *
111  * Macro for value setting into mask position.
112  * For example we want to get value 0x0040. We can use
113  * this macro with parameters: __val2mfld(0x00F0, 4)
114  */
115 #define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
116
117
118 /**
119  * @brief Get value from position specified by mask.
120  *
121  * Macro for getting value from mask position.
122  * For example we have a value 0x1234 and we want get
123  * the second number value from the right. This macro
124  * can be used for this with parameters: __mfld2val(0x00F0, 0x1234)
125  * which will return 0x0030.
126  */
127 #define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
128
129 /**
130  * @brief Clear bits in mask position
131  *
132  * This macro clears all bits specified by the mask.
133  * For example the call __clrvalmsk(0x00F0, 0x1234) will
134  * return 0x1204.
135  */
136 #define __clrvalmsk(mask, val) ((val) & ~(mask))
137
138 /**
139  * @brief Insert value into mask position
140  *
141  * This macro inserts value into position specified by mask.
142  * All others bits are preserved, only masked bits are changed.
143  * For example:
144  *      int value = 0X1234;
145  *      int mask = 0x00F0;
146  *      value = __insval2mfld(mask, value, 4);
147  *  will change value into 0x1244;
148  */
149 #define __insval2mfld(mask, value, val) (__clrvalmsk(mask, value) |     \
150                                                                                  __val2mfld(mask,val))
151
152 #endif /* __RPP_BINARY_H */