Skip to content

Instantly share code, notes, and snippets.

@Jartza
Last active March 8, 2017 12:51
Show Gist options
  • Save Jartza/29f70ad559a0f1e7b6ae to your computer and use it in GitHub Desktop.
Save Jartza/29f70ad559a0f1e7b6ae to your computer and use it in GitHub Desktop.
/*
* 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