void keyscanner_main(void) { /* TODO: low power mode: * When all keys reported up: * DDR_PP = 0x11; PORT_PP = 0x00; * Guarantee wake on TWI / any PORT_OD pin FALLING * Sleep */ for (uint8_t pp = 0; pp < 8; ++pp) { uint8_t pp_bitmask = _BV(pp); _delay_ms(0.5); DDR_PP = 0x00 ^ pp_bitmask; PORT_PP = 0xFF ^ pp_bitmask; _delay_ms(0.5); uint8_t od_bits = PIN_OD; /* * Rollover conditions exist if: * * Multiple OD pins are pulled low AND * * Multiple PP pins are pulled low */ uint8_t nPp = popCount(~PIN_PP); uint8_t nOd = popCount(~od_bits); // Most of the time the keyboard will not be a rollover state if (__builtin_expect(nPp > 1 && nOd > 1, 0)) { continue; } // Debounce key state uint8_t changes = debounce(od_bits, db + pp); // Most of the time there will be no new key events if (__builtin_expect(changes == 0, 1)) { continue; } DISABLE_INTERRUPTS({ key_t key; key.dataNumber = 0; // Set by I²C code (ringbuf.count != 0) key.pp = pp; for (int8_t od = 0; od < 8; od++) { // Fewer than half the keys are expected to be down for each scanline if (__builtin_expect(bit_is_set(changes, od), 0)) { key.keyState = bit_is_clear(db[pp].state, od); key.od = od; ringbuf_append(key.val); } } SET_INT(0); }); }
int main() { std::cout << popcount(0b00000000) << '\n'; std::cout << popcount(0b00000001) << '\n'; std::cout << popcount(0b00100001) << '\n'; std::cout << popcount(0b11111111) << '\n'; std::cout << popcount(0b1111111111110000) << '\n'; std::cout << popCount(0b00000000) << '\n'; std::cout << popCount(0b00000001) << '\n'; std::cout << popCount(0b00100001) << '\n'; std::cout << popCount(0b11111111) << '\n'; std::cout << popCount(0b1111111111110000) << '\n'; return 0; }
uint16_t FID::rank(int pos, int digit) { // bitmask: #tailing zero is (pos % smallSize) // Ex. 11100000 #tailing zero is 5 const uint8_t mask = 0xff << (smallSize - (pos % smallSize)); const uint8_t lowerBit = originalBit[pos >> 3]; uint16_t result = blockLarge[pos / largeSize] + blockSmall[pos / smallSize] + popCount(lowerBit & mask); if (digit == 0) result = static_cast<uint16_t>(pos - result); return result; }