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
34 
35 #define CPU_HAS_BITBAND 1 || 0 (1 for Cortex-M3 and up, 0 for Cortex-M0)
36 #endif
37 
38 #ifndef CPU_HAS_BITBAND
39 #if (__CORTEX_M >= 3)
40 #define CPU_HAS_BITBAND 1
41 #else
42 #define CPU_HAS_BITBAND 0
43 #endif
44 #endif
45 
46 #if CPU_HAS_BITBAND || DOXYGEN
47 /* Cortex-M3 and higher provide a bitband address space for atomically accessing
48  * single bits of peripheral registers, and sometimes for RAM as well */
53 /* Generic bit band conversion routine */
62 static inline volatile void *bitband_addr(volatile void *ptr, uintptr_t bit)
63 {
64  return (volatile void *)((((uintptr_t)ptr) & 0xF0000000ul) + 0x2000000ul +
65  ((((uintptr_t)ptr) & 0xFFFFFul) << 5) + (bit << 2));
66 }
67 
83 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
84 {
85  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 1;
86 }
87 
103 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
104 {
105  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 1;
106 }
107 
123 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
124 {
125  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 1;
126 }
127 
143 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
144 {
145  *((volatile uint32_t *)bitband_addr(ptr, bit)) = 0;
146 }
147 
163 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
164 {
165  *((volatile uint16_t *)bitband_addr(ptr, bit)) = 0;
166 }
167 
183 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
184 {
185  *((volatile uint8_t *)bitband_addr(ptr, bit)) = 0;
186 }
187 
190 #else /* CPU_HAS_BITBAND */
191 /* CPU does not have bitbanding, fall back to plain C */
192 static inline void bit_set32(volatile uint32_t *ptr, uint8_t bit)
193 {
194  *ptr |= (1 << (bit));
195 }
196 
197 static inline void bit_set16(volatile uint16_t *ptr, uint8_t bit)
198 {
199  *ptr |= (1 << (bit));
200 }
201 
202 static inline void bit_set8(volatile uint8_t *ptr, uint8_t bit)
203 {
204  *ptr |= (1 << (bit));
205 }
206 
207 static inline void bit_clear32(volatile uint32_t *ptr, uint8_t bit)
208 {
209  *ptr &= ~(1 << (bit));
210 }
211 
212 static inline void bit_clear16(volatile uint16_t *ptr, uint8_t bit)
213 {
214  *ptr &= ~(1 << (bit));
215 }
216 
217 static inline void bit_clear8(volatile uint8_t *ptr, uint8_t bit)
218 {
219  *ptr &= ~(1 << (bit));
220 }
221 
222 #endif /* CPU_HAS_BITBAND */
223 
224 #endif /* !BITBAND_FUNCTIONS_PROVIDED */
225 
226 #ifdef __cplusplus
227 }
228 #endif
229 
230 #endif /* BIT_H */
231 
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:143
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:183
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:163
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:62
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:123
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:83
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:103