Last active
March 8, 2017 12:51
-
-
Save Jartza/29f70ad559a0f1e7b6ae to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Struct to handle bits in registers | |
*/ | |
typedef struct { | |
uint8_t b0:1; | |
uint8_t b1:1; | |
uint8_t b2:1; | |
uint8_t b3:1; | |
uint8_t b4:1; | |
uint8_t b5:1; | |
uint8_t b6:1; | |
uint8_t b7:1; | |
} bitmask_s; | |
/* | |
* Helper macros for bit pointer macro | |
*/ | |
#define BNAME(x) BSTR(x) | |
#define BSTR(x) b##x | |
/* | |
* Common defines | |
*/ | |
#define OUT 1 | |
#define IN 0 | |
#define ON 1 | |
#define OFF 0 | |
/* | |
* Concatenate helper | |
*/ | |
#define CONCAT(a, ...) CONCAT_IMPL(a, __VA_ARGS__) | |
#define CONCAT_IMPL(x, ...) x ## __VA_ARGS__ | |
/* | |
* Count number of arguments in __VA_ARGS__ | |
*/ | |
#define VA_NUM_ARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, x, ...) x | |
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) | |
/* | |
* Bit-Shift-Or macros for 1-8 parameters | |
*/ | |
#define BSO_1(a) (1 << a) | |
#define BSO_2(a, b) (1 << a) | (1 << b) | |
#define BSO_3(a, b, c) (1 << a) | (1 << b) | (1 << c) | |
#define BSO_4(a, b, c, d) (1 << a) | (1 << b) | (1 << c) | (1 << d) | |
#define BSO_5(a, b, c, d, e) (1 << a) | (1 << b) | (1 << c) | (1 << d) | (1 << e) | |
#define BSO_6(a, b, c, d, e, f) (1 << a) | (1 << b) | (1 << c) | (1 << d) | (1 << e) | (1 << f) | |
#define BSO_7(a, b, c, d, e, f, g) (1 << a) | (1 << b) | (1 << c) | (1 << d) | (1 << e) | (1 << f) | (1 << g) | |
#define BSO_8(a, b, c, d, e, f, g, h) (1 << a) | (1 << b) | (1 << c) | (1 << d) | (1 << e) | (1 << f) | (1 << g) | (1 << h) | |
/* | |
* Examples: | |
* | |
* #define LED_DIR BITP(DDRB, PB4); // LED_DIR is "variable" pointing to single bit (PB4) in DDRB | |
* #define LED_STATE BITP(PORTB, PB4); // LED_STATE points to single bit (PB4) in PORTB | |
* LED_DIR = OUT; // Set pin as output | |
* LED_STATE = ON; // Switch LED on | |
* | |
* BITS_SET(DDRB, PB3, PB5, PB7); // Set bits PB3, PB5 and PB7 in DDRB, leave other bits untouched. | |
* BITS_SET_EX(DDRB, PB7); // Sets only PB7 in DDRB, other bits are zeroed (set exclusive). | |
* BITS_CLEAR(PORTB, PB4); // Clear bit PB4 in PORTB, leave other bits untouched. | |
*/ | |
/* | |
* Bit pointer macro which can be used to make individual | |
* bit variables | |
*/ | |
#define BITP(var, bit) ((volatile bitmask_s*)&var)->BNAME(bit) | |
/* | |
* Macros to set and clear multiple bits in registers | |
*/ | |
#define BITS_SET(x, ...) x |= (CONCAT(BSO_, VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)) | |
#define BITS_CLEAR(x, ...) x &= ~(CONCAT(BSO_, VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)) | |
#define BITS_SET_EX(x, ...) x = (CONCAT(BSO_, VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment