bit.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Eistec AB
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
19 #ifndef BIT_H
20 #define BIT_H
21 
22 #include <stdint.h>
23 #include "cpu.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /* Define BITBAND_FUNCTIONS_PROVIDED 1 if the CPU provides its own
30  * implementations for bit manipulation */
31 #if !BITBAND_FUNCTIONS_PROVIDED
32 
33 #if DOXYGEN
37 #define CPU_HAS_BITBAND 1 || 0 (1 if CPU implements bit-banding, 0 if not)
49 #define CPU_HAS_SRAM_BITBAND 1 || 0
50 #endif
51 
52 #if CPU_HAS_BITBAND || DOXYGEN
53 /* Most CPUs with bitband have all of SRAM mapped in the bit-banding region.
54  * The few oddballs have to define it to zero in cpu_conf.h */
55 #ifndef CPU_HAS_SRAM_BITBAND
56 #define CPU_HAS_SRAM_BITBAND 1
57 #endif
58 
59 /* Some MCUs provide a bitband address space for atomically accessing
60  * single bits of peripheral registers, and sometimes for RAM as well */
65 /* Generic bit band conversion routine */
74 static inline volatile void *bitband_addr(volatile void *ptr, uintptr_t bit)
75 {
76  return (volatile void *)((((uintptr_t)ptr) & 0xF0000000ul) + 0x2000000ul +
77  ((((uintptr_t)ptr) & 0xFFFFFul) << 5) + (bit << 2));
78 }
79 
95 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
96 {
97  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 1;
98 }
99 
115 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
116 {
117  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 1;
118 }
119 
135 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
136 {
137  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 1;
138 }
139 
155 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
156 {
157  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 0;
158 }
159 
175 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
176 {
177  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 0;
178 }
179 
195 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
196 {
197  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 0;
198 }
199 
212 static inline bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
213 {
214  return *((volatile uint32_t *)bitband_addr(ptr, bit));
215 }
216 
229 static inline bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
230 {
231  return *((volatile uint16_t *)bitband_addr(ptr, bit));
232 }
233 
246 static inline bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
247 {
248  return *((volatile uint8_t *)bitband_addr(ptr, bit));
249 }
250 
253 #else /* CPU_HAS_BITBAND */
254 /* CPU does not have bitbanding, fall back to plain C */
255 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
256 {
257  *ptr |= (1 << (bit));
258 }
259 
260 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
261 {
262  *ptr |= (1 << (bit));
263 }
264 
265 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
266 {
267  *ptr |= (1 << (bit));
268 }
269 
270 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
271 {
272  *ptr &= ~(1 << (bit));
273 }
274 
275 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
276 {
277  *ptr &= ~(1 << (bit));
278 }
279 
280 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
281 {
282  *ptr &= ~(1 << (bit));
283 }
284 
285 static inline bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
286 {
287  return *ptr & (1 << bit);
288 }
289 
290 static inline bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
291 {
292  return *ptr & (1 << bit);
293 }
294 
295 static inline bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
296 {
297  return *ptr & (1 << bit);
298 }
299 
300 #endif /* CPU_HAS_BITBAND */
301 
302 #endif /* !BITBAND_FUNCTIONS_PROVIDED */
303 
304 #ifdef __cplusplus
305 }
306 #endif
307 
308 #endif /* BIT_H */
static void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
Clear a single bit in the 8 bit byte pointed to by ptr.
Definition: bit.h:195
static volatile void * bitband_addr(volatile void *ptr, uintptr_t bit)
Convert bit band region address and bit number to bit band alias address.
Definition: bit.h:74
static void bit_set16(volatile uint16_t *ptr, uint8_t bit)
Set a single bit in the 16 bit word pointed to by ptr.
Definition: bit.h:115
static void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
Clear a single bit in the 32 bit word pointed to by ptr.
Definition: bit.h:155
static bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
Checks if a single bit in the 16 bit word pointed to by ptr is set.
Definition: bit.h:229
static void bit_set8(volatile uint8_t *ptr, uint8_t bit)
Set a single bit in the 8 bit byte pointed to by ptr.
Definition: bit.h:135
static void bit_set32(volatile uint32_t *ptr, uint8_t bit)
Set a single bit in the 32 bit word pointed to by ptr.
Definition: bit.h:95
static bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
Checks if a single bit in the 8 bit byte pointed to by ptr is set.
Definition: bit.h:246
static bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
Checks if a single bit in the 32 bit word pointed to by ptr is set.
Definition: bit.h:212
static void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
Clear a single bit in the 16 bit word pointed to by ptr.
Definition: bit.h:175