diff --git a/src/main/common/bitarray.c b/src/main/common/bitarray.c index 298c5ea9ea..a88ab9a455 100755 --- a/src/main/common/bitarray.c +++ b/src/main/common/bitarray.c @@ -24,17 +24,17 @@ // to find set bits faster. #define BITARRAY_BIT_OP(array, bit, op) ((array)[(bit) / (sizeof((array)[0]) * 8)] op ((1u<<31) >> ((bit) % (sizeof((array)[0]) * 8)))) -bool bitArrayGet(const void *array, unsigned bit) +bool bitArrayGet(const bitarrayElement_t *array, unsigned bit) { return BITARRAY_BIT_OP((uint32_t*)array, bit, &); } -void bitArraySet(void *array, unsigned bit) +void bitArraySet(bitarrayElement_t *array, unsigned bit) { BITARRAY_BIT_OP((uint32_t*)array, bit, |=); } -void bitArrayClr(void *array, unsigned bit) +void bitArrayClr(bitarrayElement_t *array, unsigned bit) { BITARRAY_BIT_OP((uint32_t*)array, bit, &=~); } @@ -52,7 +52,7 @@ __attribute__((always_inline)) static inline uint8_t __CLZ(uint32_t val) #endif } -int bitArrayFindFirstSet(const void *array, unsigned start, size_t size) +int bitArrayFindFirstSet(const bitarrayElement_t *array, unsigned start, size_t size) { const uint32_t *ptr = (uint32_t*)array; const uint32_t *end = ptr + (size / 4); diff --git a/src/main/common/bitarray.h b/src/main/common/bitarray.h index 1877e7e0c6..4c906c117b 100755 --- a/src/main/common/bitarray.h +++ b/src/main/common/bitarray.h @@ -20,16 +20,22 @@ /* * These functions expect array to be 4-byte aligned since they alias array - * to an uint32_t pointer in order to work fast. + * to an uint32_t pointer in order to work fast. Use the BITARRAY_DECLARE() + * macro to declare a bit array that can be safely used by them. */ -bool bitArrayGet(const void *array, unsigned bit); -void bitArraySet(void *array, unsigned bit); -void bitArrayClr(void *array, unsigned bit); +typedef uint32_t bitarrayElement_t; + +#define BITARRAY_DECLARE(name, bits) bitarrayElement_t name[(bits + 31) / 32] + +bool bitArrayGet(const bitarrayElement_t *array, unsigned bit); +void bitArraySet(bitarrayElement_t *array, unsigned bit); +void bitArrayClr(bitarrayElement_t *array, unsigned bit); + // Returns the first set bit with pos >= start_bit, or -1 if all bits -// are zero. -// Note that size must indicate the size of array in bytes. -// -// WARNING: This function only works for arrays where size is a multiple -// of 4. -int bitArrayFindFirstSet(const void *array, unsigned start_bit, size_t size); +// are zero. Note that size must indicate the size of array in bytes. +// In most cases, you should use the BITARRAY_FIND_FIRST_SET() macro +// to call this function. +int bitArrayFindFirstSet(const bitarrayElement_t *array, unsigned start_bit, size_t size); + +#define BITARRAY_FIND_FIRST_SET(array, start_bit) bitArrayFindFirstSet(array, start_bit, sizeof(array)) diff --git a/src/main/drivers/max7456.c b/src/main/drivers/max7456.c index 52e535f78d..f31504824f 100644 --- a/src/main/drivers/max7456.c +++ b/src/main/drivers/max7456.c @@ -183,7 +183,7 @@ uint16_t maxScreenSize = VIDEO_BUFFER_CHARS_PAL; // in screenIsDirty to upgrade only changed chars this solution // is faster than redrawing the whole screen on each frame static uint8_t screenBuffer[VIDEO_BUFFER_CHARS_PAL] ALIGNED(4); -static uint8_t screenIsDirty[VIDEO_BUFFER_CHARS_PAL/8] ALIGNED(4) = {0,}; +static BITARRAY_DECLARE(screenIsDirty, VIDEO_BUFFER_CHARS_PAL); //max chars to update in one idle #define MAX_CHARS2UPDATE 5 diff --git a/src/main/fc/fc_msp.c b/src/main/fc/fc_msp.c index 0b960633bc..acca383057 100644 --- a/src/main/fc/fc_msp.c +++ b/src/main/fc/fc_msp.c @@ -417,7 +417,7 @@ static void packBoxModeFlags(boxBitmask_t * mspBoxModeFlags) memset(mspBoxModeFlags, 0, sizeof(boxBitmask_t)); for (uint32_t i = 0; i < activeBoxIdCount; i++) { if (activeBoxes[activeBoxIds[i]]) { - bitArraySet(mspBoxModeFlags, i); + bitArraySet(mspBoxModeFlags->bits, i); } } } diff --git a/src/main/fc/rc_modes.c b/src/main/fc/rc_modes.c index a22659cb15..c378e3a638 100755 --- a/src/main/fc/rc_modes.c +++ b/src/main/fc/rc_modes.c @@ -66,7 +66,7 @@ bool isUsingNavigationModes(void) bool IS_RC_MODE_ACTIVE(boxId_e boxId) { - return bitArrayGet(&rcModeActivationMask, boxId); + return bitArrayGet(rcModeActivationMask.bits, boxId); } void rcModeUpdate(boxBitmask_t *newState) @@ -124,13 +124,13 @@ void updateActivatedModes(void) if (modeActivationOperatorConfig()->modeActivationOperator == MODE_OPERATOR_AND) { // AND the conditions if (activeConditionCountPerMode[modeIndex] == specifiedConditionCountPerMode[modeIndex]) { - bitArraySet(&newMask, modeIndex); + bitArraySet(newMask.bits, modeIndex); } } else { // OR the conditions if (activeConditionCountPerMode[modeIndex] > 0) { - bitArraySet(&newMask, modeIndex); + bitArraySet(newMask.bits, modeIndex); } } } diff --git a/src/main/fc/rc_modes.h b/src/main/fc/rc_modes.h index 4a69c2e819..438db7e4f4 100755 --- a/src/main/fc/rc_modes.h +++ b/src/main/fc/rc_modes.h @@ -19,6 +19,8 @@ #include +#include "common/bitarray.h" + #include "config/parameter_group.h" typedef enum { @@ -58,7 +60,7 @@ typedef enum { } boxId_e; // type to hold enough bits for CHECKBOX_ITEM_COUNT. Struct used for value-like behavior -typedef struct boxBitmask_s { uint32_t bits[(CHECKBOX_ITEM_COUNT + 31) / 32]; } boxBitmask_t; +typedef struct boxBitmask_s { BITARRAY_DECLARE(bits, CHECKBOX_ITEM_COUNT); } boxBitmask_t; #define MAX_MODE_ACTIVATION_CONDITION_COUNT 20