void run_4bit_toggle(uint8_t *value, const uint16_t menu_item) { // Run a menu page where 4 bits can be independently toggled. // // . . * . <- menu item // . . . . // # # # # <- bits to be toggled. // . . . . int16_t leds = REVERSE_BYTE(*value) << 4; // Add in the dim background for the toggle bits leds |= 0b0000111100000000 & dim_mask; // Add the flashing exit lights leds |= menu_item & flash_mask; // Update LEDs. led_set_state(leds); // Process key presses. // Multiple key presses are sorted out by importance: Exit buttons // first, then increment/decrement, then toggle bits. if (g_key_down & menu_item) { // exit key is pressed g_menu_state = TOP_LEVEL; } else if (g_key_down & 0x0f00) { // toggle bits using an exclusive-or of the keydown bits. uint16_t bits = g_key_down & 0x0f00; uint8_t toggle = bits >> 4; // Then we reverse the LSB, moving the top 4 bits to the bottom 4. *value = *value ^ REVERSE_BYTE(toggle); }
static int proto_series_led_col_row_8(monome_t *monome, proto_series_message_t mode, uint_t address, const uint8_t *data) { uint8_t buf[2] = {0, 0}; uint_t xaddress = address; /* I guess this is a bit of a hack...but damn does it work well! treating the address as a coordinate pair with itself lets us calculate the row/col translation in one call using the existing rotation code then we just pick whether we want the x coord (row) or y coord (col) depending on what sort of message it is. */ ROTATE_COORDS(monome, xaddress, address); switch( mode ) { case PROTO_SERIES_LED_ROW_8: if( ROTSPEC(monome).flags & ROW_COL_SWAP ) address = xaddress; if( ROTSPEC(monome).flags & ROW_REVBITS ) buf[1] = REVERSE_BYTE(*data); else buf[1] = *data; break; case PROTO_SERIES_LED_COL_8: if( !(ROTSPEC(monome).flags & ROW_COL_SWAP) ) address = xaddress; if( ROTSPEC(monome).flags & COL_REVBITS ) buf[1] = REVERSE_BYTE(*data); else buf[1] = *data; break; default: return -1; } if( ROTSPEC(monome).flags & ROW_COL_SWAP ) mode = (!(mode - PROTO_SERIES_LED_ROW_8) << 4) + PROTO_SERIES_LED_ROW_8; buf[0] = mode | (address & 0x0F ); return monome_write(monome, buf, sizeof(buf)); }
static int proto_series_led_col_row_16(monome_t *monome, proto_series_message_t mode, uint_t address, const uint8_t *data) { uint8_t buf[3] = {0, 0, 0}; uint_t xaddress = address; ROTATE_COORDS(monome, xaddress, address); switch( mode ) { case PROTO_SERIES_LED_ROW_16: address = xaddress; if( ROTSPEC(monome).flags & ROW_REVBITS ) { buf[1] = REVERSE_BYTE(data[1]); buf[2] = REVERSE_BYTE(data[0]); } else { buf[1] = data[0]; buf[2] = data[1]; } break; case PROTO_SERIES_LED_COL_16: if( ROTSPEC(monome).flags & COL_REVBITS ) { buf[1] = REVERSE_BYTE(data[1]); buf[2] = REVERSE_BYTE(data[0]); } else { buf[1] = data[0]; buf[2] = data[1]; } break; default: return -1; } if( ROTSPEC(monome).flags & ROW_COL_SWAP ) mode = (!(mode - PROTO_SERIES_LED_ROW_16) << 4) + PROTO_SERIES_LED_ROW_16; buf[0] = mode | (address & 0x0F ); return monome_write(monome, buf, sizeof(buf)); }
static int proto_chronome_led_col_row(monome_t *monome, proto_chronome_message_t mode, uint_t address, const uint8_t *data) { uint8_t buf[2]; uint_t xaddress = address; ROTATE_COORDS(monome, xaddress, address); switch( mode ) { case PROTO_CHRONOME_LED_ROW: address = xaddress; if( ROTSPEC(monome).flags & ROW_REVBITS ) buf[1] = REVERSE_BYTE(*data); else buf[1] = *data; break; case PROTO_CHRONOME_LED_COL: if( ROTSPEC(monome).flags & COL_REVBITS ) buf[1] = REVERSE_BYTE(*data); else buf[1] = *data; break; default: return -1; } if( ROTSPEC(monome).flags & ROW_COL_SWAP ) mode = !(mode - PROTO_CHRONOME_LED_ROW) + PROTO_CHRONOME_LED_ROW; buf[0] = 0x80 | ((address & 0x7 ) << 4) | mode; return monome_write(monome, buf, sizeof(buf)); }