All pastes #1717114 Raw Edit

AVR register bit operator

public c v1 · immutable
#1717114 ·published 2009-12-16 16:14 UTC
rendered paste body
/*	SYNOPSIS:		SETR(register_name, bit, bit, ...)	DESCRIPTION:		register_name			Any readable/writable AVR register		bit			Bit number (0..7) which you want to set or unset.			If you want to set a bit, just put a bit number.			Otherwise, if you want to UNSET the bit, put BITNOTed			(ie. use ~ operator) bit number. See EXAMPLES below.			You can specify bits numbers up to eight.			EXAMPLES:		To set bit:			SETR(MCUCR, PUD); // set MCUCR one			SETR(GIMSK, INT1, INT0); // set both INT1 INT0 one		To unset bit:			SETR(MCUCR, ~PUD); // set MCUCR zero			SETR(GIMSK, ~INT1, ~INT0); // unset both INT1 INT0 		You can mix these set/unset specifier at once:			SETR(TCCR0B, CS02, ~CS01, CS00); // set CSO2:CS01:CS00 = 1:0:1	NOTE:		This macro heavily expects gcc's optimization. Gcc 4.3 is known to		work well with this. Other versions will or will not.*/#define SETR_BIT_(n) \	if(bits[n] != 100) { \		if(bits[n] < 0) \			and_bits += 1<<(~bits[n]); \		else \		or_bits += 1<<(bits[n]); \	}#define SETR(REG, ...) \	do { \		static const int bits[]= \			{ __VA_ARGS__, \			100, 100, 100, 100, \			100, 100, 100, 100 }; \		int and_bits = 0, or_bits = 0; \		uchar p; \		SETR_BIT_(0) \		SETR_BIT_(1) \		SETR_BIT_(2) \		SETR_BIT_(3) \		SETR_BIT_(4) \		SETR_BIT_(5) \		SETR_BIT_(6) \		SETR_BIT_(7) \		and_bits = ~and_bits; \		if(or_bits == 0xff) { \			(REG) = 0xff; \		} else if(and_bits == 0x00) { \			(REG) = 0x00; \		} else { \			p = (REG); \			if(and_bits != 0x00) p &= and_bits; \			if(or_bits  != 0x00) p |= or_bits;   \			(REG) = p; \		} \	} while(0)