bit.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2017 Eistec AB
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include "cpu.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /* Define BITBAND_FUNCTIONS_PROVIDED 1 if the CPU provides its own
27  * implementations for bit manipulation */
28 #if !BITBAND_FUNCTIONS_PROVIDED
29 
30 #if DOXYGEN
34 #define CPU_HAS_BITBAND 1 || 0 (1 if CPU implements bit-banding, 0 if not)
46 #define CPU_HAS_SRAM_BITBAND 1 || 0
47 #endif
48 
49 #if CPU_HAS_BITBAND || DOXYGEN
50 /* Most CPUs with bitband have all of SRAM mapped in the bit-banding region.
51  * The few oddballs have to define it to zero in cpu_conf.h */
52 #ifndef CPU_HAS_SRAM_BITBAND
53 #define CPU_HAS_SRAM_BITBAND 1
54 #endif
55 
56 /* Some MCUs provide a bitband address space for atomically accessing
57  * single bits of peripheral registers, and sometimes for RAM as well */
62 /* Generic bit band conversion routine */
71 static inline volatile void *bitband_addr(volatile void *ptr, uintptr_t bit)
72 {
73  return (volatile void *)((((uintptr_t)ptr) & 0xF0000000ul) + 0x2000000ul +
74  ((((uintptr_t)ptr) & 0xFFFFFul) << 5) + (bit << 2));
75 }
76 
92 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
93 {
94  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 1;
95 }
96 
112 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
113 {
114  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 1;
115 }
116 
132 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
133 {
134  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 1;
135 }
136 
152 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
153 {
154  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 0;
155 }
156 
172 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
173 {
174  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 0;
175 }
176 
192 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
193 {
194  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 0;
195 }
196 
209 static inline bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
210 {
211  return *((volatile uint32_t *)bitband_addr(ptr, bit));
212 }
213 
226 static inline bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
227 {
228  return *((volatile uint16_t *)bitband_addr(ptr, bit));
229 }
230 
243 static inline bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
244 {
245  return *((volatile uint8_t *)bitband_addr(ptr, bit));
246 }
247 
250 #else /* CPU_HAS_BITBAND */
251 /* CPU does not have bitbanding, fall back to plain C */
252 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
253 {
254  *ptr |= (1 << (bit));
255 }
256 
257 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
258 {
259  *ptr |= (1 << (bit));
260 }
261 
262 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
263 {
264  *ptr |= (1 << (bit));
265 }
266 
267 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
268 {
269  *ptr &= ~(1 << (bit));
270 }
271 
272 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
273 {
274  *ptr &= ~(1 << (bit));
275 }
276 
277 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
278 {
279  *ptr &= ~(1 << (bit));
280 }
281 
282 static inline bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
283 {
284  return *ptr & (1 << bit);
285 }
286 
287 static inline bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
288 {
289  return *ptr & (1 << bit);
290 }
291 
292 static inline bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
293 {
294  return *ptr & (1 << bit);
295 }
296 
297 #endif /* CPU_HAS_BITBAND */
298 
299 #endif /* !BITBAND_FUNCTIONS_PROVIDED */
300 
301 #ifdef __cplusplus
302 }
303 #endif
304 
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:192
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:71
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:112
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:152
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:226
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:132
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:92
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:243
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:209
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:172