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 
9 #pragma once
10 
21 #include <stdint.h>
22 #include "cpu.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /* Define BITBAND_FUNCTIONS_PROVIDED 1 if the CPU provides its own
29  * implementations for bit manipulation */
30 #if !BITBAND_FUNCTIONS_PROVIDED
31 
32 #if DOXYGEN
36 #define CPU_HAS_BITBAND 1 || 0 (1 if CPU implements bit-banding, 0 if not)
48 #define CPU_HAS_SRAM_BITBAND 1 || 0
49 #endif
50 
51 #if CPU_HAS_BITBAND || DOXYGEN
52 /* Most CPUs with bitband have all of SRAM mapped in the bit-banding region.
53  * The few oddballs have to define it to zero in cpu_conf.h */
54 #ifndef CPU_HAS_SRAM_BITBAND
55 #define CPU_HAS_SRAM_BITBAND 1
56 #endif
57 
58 /* Some MCUs provide a bitband address space for atomically accessing
59  * single bits of peripheral registers, and sometimes for RAM as well */
64 /* Generic bit band conversion routine */
73 static inline volatile void *bitband_addr(volatile void *ptr, uintptr_t bit)
74 {
75  return (volatile void *)((((uintptr_t)ptr) & 0xF0000000ul) + 0x2000000ul +
76  ((((uintptr_t)ptr) & 0xFFFFFul) << 5) + (bit << 2));
77 }
78 
94 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
95 {
96  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 1;
97 }
98 
114 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
115 {
116  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 1;
117 }
118 
134 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
135 {
136  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 1;
137 }
138 
154 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
155 {
156  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 0;
157 }
158 
174 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
175 {
176  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 0;
177 }
178 
194 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
195 {
196  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 0;
197 }
198 
211 static inline bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
212 {
213  return *((volatile uint32_t *)bitband_addr(ptr, bit));
214 }
215 
228 static inline bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
229 {
230  return *((volatile uint16_t *)bitband_addr(ptr, bit));
231 }
232 
245 static inline bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
246 {
247  return *((volatile uint8_t *)bitband_addr(ptr, bit));
248 }
249 
252 #else /* CPU_HAS_BITBAND */
253 /* CPU does not have bitbanding, fall back to plain C */
254 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
255 {
256  *ptr |= (1 << (bit));
257 }
258 
259 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
260 {
261  *ptr |= (1 << (bit));
262 }
263 
264 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
265 {
266  *ptr |= (1 << (bit));
267 }
268 
269 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
270 {
271  *ptr &= ~(1 << (bit));
272 }
273 
274 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
275 {
276  *ptr &= ~(1 << (bit));
277 }
278 
279 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
280 {
281  *ptr &= ~(1 << (bit));
282 }
283 
284 static inline bool bit_check32(volatile uint32_t *ptr, uint8_t bit)
285 {
286  return *ptr & (1 << bit);
287 }
288 
289 static inline bool bit_check16(volatile uint16_t *ptr, uint8_t bit)
290 {
291  return *ptr & (1 << bit);
292 }
293 
294 static inline bool bit_check8(volatile uint8_t *ptr, uint8_t bit)
295 {
296  return *ptr & (1 << bit);
297 }
298 
299 #endif /* CPU_HAS_BITBAND */
300 
301 #endif /* !BITBAND_FUNCTIONS_PROVIDED */
302 
303 #ifdef __cplusplus
304 }
305 #endif
306 
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:194
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:73
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:114
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:154
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:228
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:134
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:94
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:245
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:211
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:174