~ruther/qmk_firmware

e5aa28455ec6c377cc9117b07dfa7d3951e6d610 — Andrew Kannan 6 years ago 6f5f943
[Keyboard] 201909 s75 custom encoder (#6745)

* Handle custom encoder configuration

* Whitespace changes

* Undo broken stuff

* more

* Remove printfs

* fix the dumb bug
M keyboards/cannonkeys/satisfaction75/config.h => keyboards/cannonkeys/satisfaction75/config.h +9 -9
@@ 71,15 71,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.

// TODO: refactor with new user EEPROM code (coming soon)
#define EEPROM_MAGIC 0x451F
#define EEPROM_MAGIC_ADDR 32
#define EEPROM_MAGIC_ADDR 40
// Bump this every time we change what we store
// This will automatically reset the EEPROM with defaults
// and avoid loading invalid data from the EEPROM
#define EEPROM_VERSION 0x01
#define EEPROM_VERSION_ADDR 34
#define EEPROM_VERSION_ADDR 42

// Dynamic keymap starts after EEPROM version
#define DYNAMIC_KEYMAP_EEPROM_ADDR 35
#define DYNAMIC_KEYMAP_EEPROM_ADDR 43

// Dynamic macro starts after dynamic keymaps (35+(4*6*16*2)) = (35+768) = 803



@@ 89,13 89,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 1 for OLED default mode
// 6 for 3x custom encoder settings, left, right, and press (18 total)

#define DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES 803
#define DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT 804
#define DYNAMIC_KEYMAP_DEFAULT_OLED 805
#define DYNAMIC_KEYMAP_CUSTOM_ENCODER 806
#define DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES 811
#define DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT 812
#define DYNAMIC_KEYMAP_DEFAULT_OLED 813
#define DYNAMIC_KEYMAP_CUSTOM_ENCODER 814

#define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 824
#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 200
#define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 832
#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 192
#define DYNAMIC_KEYMAP_MACRO_COUNT 16



M keyboards/cannonkeys/satisfaction75/satisfaction75.c => keyboards/cannonkeys/satisfaction75/satisfaction75.c +55 -57
@@ 94,51 94,53 @@ void raw_hid_receive( uint8_t *data, uint8_t length )
		}
		case id_get_keyboard_value:
		{
      switch( command_data[0])
      {
        case id_uptime:
        {
          uint32_t value = timer_read32();
          command_data[1] = (value >> 24 ) & 0xFF;
          command_data[2] = (value >> 16 ) & 0xFF;
          command_data[3] = (value >> 8 ) & 0xFF;
          command_data[4] = value & 0xFF;
          break;
        }
        case id_oled_default_mode:
        {
          uint8_t default_oled = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED);
          command_data[1] = default_oled;
          break;
        }
        case id_oled_mode:
        {
          command_data[1] = oled_mode;
          break;

        }
        case id_encoder_modes:
        {
          command_data[1] = enabled_encoder_modes;
          break;
        }
        case id_encoder_custom:
        {
          // uint8_t custom_encoder_idx = command_data[1];
          // command_data[2] = 0x00;
          // command_data[3] = 0x00;
          // command_data[4] = 0x00;
          // command_data[5] = 0x00;
          // command_data[6] = 0x00;
          // command_data[7] = 0x00;
          break;
        }
        default:
        {
          *command_id = id_unhandled;
          break;
        }
      }
            switch( command_data[0])
            {
                case id_uptime:
                {
                uint32_t value = timer_read32();
                command_data[1] = (value >> 24 ) & 0xFF;
                command_data[2] = (value >> 16 ) & 0xFF;
                command_data[3] = (value >> 8 ) & 0xFF;
                command_data[4] = value & 0xFF;
                break;
                }
                case id_oled_default_mode:
                {
                    uint8_t default_oled = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED);
                    command_data[1] = default_oled;
                    break;
                }
                case id_oled_mode:
                {
                    command_data[1] = oled_mode;
                    break;
                }
                case id_encoder_modes:
                {
                    command_data[1] = enabled_encoder_modes;
                    break;
                }
                case id_encoder_custom:
                {
                    uint8_t custom_encoder_idx = command_data[1];
                    uint16_t keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_CW);
                    command_data[2] =  keycode >> 8;
                    command_data[3] = keycode & 0xFF;
                    keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_CCW);
                    command_data[4] =  keycode >> 8;
                    command_data[5] = keycode & 0xFF;
                    keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_PRESS);
                    command_data[6] =  keycode >> 8;
                    command_data[7] = keycode & 0xFF;
                    break;
                }
                default:
                {
                    *command_id = id_unhandled;
                    break;
                }
            }
			break;
    }
#ifdef DYNAMIC_KEYMAP_ENABLE


@@ 164,7 166,10 @@ void raw_hid_receive( uint8_t *data, uint8_t length )
        }
        case id_encoder_custom:
        {
          // uint8_t custom_encoder_idx = command_data[1];
          uint8_t custom_encoder_idx = command_data[1];
          uint8_t encoder_behavior = command_data[2];
          uint16_t keycode = (command_data[3] << 8) | command_data[4];
          set_custom_encoder_config(custom_encoder_idx, encoder_behavior, keycode);
          break;
        }
        default:


@@ 208,13 213,6 @@ void raw_hid_receive( uint8_t *data, uint8_t length )
		{
			uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
			uint16_t size = command_data[2]; // size <= 28
			dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
			break;
		}
		case id_dynamic_keymap_macro_set_buffer:
		{
			uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
			uint16_t size = command_data[2]; // size <= 28
			dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
			break;
		}


@@ 339,9 337,9 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
        uint16_t mapped_code = handle_encoder_press();
        uint16_t held_keycode_timer = timer_read();
        if(mapped_code != 0){
          register_code(mapped_code);
          register_code16(mapped_code);
          while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
          unregister_code(mapped_code);
          unregister_code16(mapped_code);
        }
      } else {
        // Do something else when release


@@ 380,9 378,9 @@ void encoder_update_kb(uint8_t index, bool clockwise) {
      }
      uint16_t held_keycode_timer = timer_read();
      if(mapped_code != 0){
        register_code(mapped_code);
        register_code16(mapped_code);
        while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
        unregister_code(mapped_code);
        unregister_code16(mapped_code);
      }
    } else {
      if(clockwise){

M keyboards/cannonkeys/satisfaction75/satisfaction75.h => keyboards/cannonkeys/satisfaction75/satisfaction75.h +8 -0
@@ 47,6 47,12 @@ enum encoder_modes {
  ENC_MODE_CLOCK_SET // This shouldn't be included in the default modes, so we put it after NUM_ENCODER_MODES
};

enum custom_encoder_behavior {
    ENC_CUSTOM_CW = 0,
    ENC_CUSTOM_CCW,
    ENC_CUSTOM_PRESS
};

enum oled_modes {
  OLED_DEFAULT,
  OLED_TIME,


@@ 96,6 102,8 @@ void change_encoder_mode(bool negative);
uint16_t handle_encoder_clockwise(void);
uint16_t handle_encoder_ccw(void);
uint16_t handle_encoder_press(void);
uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior);
void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code);

void update_time_config(int8_t increment);


M keyboards/cannonkeys/satisfaction75/satisfaction_encoder.c => keyboards/cannonkeys/satisfaction75/satisfaction_encoder.c +57 -1
@@ 1,4 1,5 @@
#include "satisfaction75.h"
#include "tmk_core/common/eeprom.h"

void pre_encoder_mode_change(){
  if(encoder_mode == ENC_MODE_CLOCK_SET){


@@ 111,6 112,17 @@ uint16_t handle_encoder_clockwise(){
    case ENC_MODE_BRIGHTNESS:
      mapped_code = KC_BRIGHTNESS_UP;
      break;
#ifdef DYNAMIC_KEYMAP_ENABLE
    case ENC_MODE_CUSTOM0:
      mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_CW);
      break;
    case ENC_MODE_CUSTOM1:
      mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_CW);
      break;
    case ENC_MODE_CUSTOM2:
      mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_CW);
      break;
#endif
    case ENC_MODE_CLOCK_SET:
      update_time_config(1);
      queue_for_send = true;


@@ 145,6 157,18 @@ uint16_t handle_encoder_ccw(){
    case ENC_MODE_BRIGHTNESS:
      mapped_code = KC_BRIGHTNESS_DOWN;
      break;
#ifdef DYNAMIC_KEYMAP_ENABLE
    case ENC_MODE_CUSTOM0:
      mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_CCW);
      break;
    case ENC_MODE_CUSTOM1:
      mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_CCW);
      break;
    case ENC_MODE_CUSTOM2:
      mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_CCW);
      break;
#endif

    case ENC_MODE_CLOCK_SET:
      update_time_config(-1);
      queue_for_send = true;


@@ 159,6 183,7 @@ uint16_t handle_encoder_press(){
    case ENC_MODE_VOLUME:
      mapped_code = KC_MUTE;
      break;
    default:
    case ENC_MODE_MEDIA:
      mapped_code = KC_MEDIA_PLAY_PAUSE;
      break;


@@ 174,11 199,42 @@ uint16_t handle_encoder_press(){
        breathing_enable();
      }
      break;
#ifdef DYNAMIC_KEYMAP_ENABLE
    case ENC_MODE_CUSTOM0:
      mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_PRESS);
      break;
    case ENC_MODE_CUSTOM1:
      mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_PRESS);
      break;
    case ENC_MODE_CUSTOM2:
      mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_PRESS);
      break;
#endif
    case ENC_MODE_CLOCK_SET:
      time_config_idx = (time_config_idx + 1) % 5;
    default:
    case ENC_MODE_BRIGHTNESS:
      break;
  }
  return mapped_code;
}


uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior){
#ifdef DYNAMIC_KEYMAP_ENABLE
    void* addr = (void*)(DYNAMIC_KEYMAP_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2));
    //big endian
    uint16_t keycode = eeprom_read_byte(addr) << 8;
    keycode |= eeprom_read_byte(addr + 1);
    return keycode;
#else
    return 0;
#endif
}

void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code){
#ifdef DYNAMIC_KEYMAP_ENABLE
    void* addr = (void*)(DYNAMIC_KEYMAP_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2));
    eeprom_update_byte(addr, (uint8_t)(new_code >> 8));
    eeprom_update_byte(addr + 1, (uint8_t)(new_code & 0xFF));
#endif
}