O-H-M2 / qmk_port_ch582

GNU General Public License v2.0
131 stars 66 forks source link

Unable to expose KB configuration to VIA UI #165

Open JavierRiosN opened 2 weeks ago

JavierRiosN commented 2 weeks ago

Hi! I'm doing my first firmware for a small macropad with 12 keys and 4 knobs. Everything is doing well thanks to this wonderfoul QMK fork! Thank you!

The problem is that I pretend to expose some configurations for caps/num lock indicators and layer indicator to VIA UI but I haven't been able to do it. I take examples from other keyboards (mk67lite for instance) and see this code in info.json:

    {
      "label": "Dongle",
      "content": [
        {
          "label": "Dongle",
          "content": [
            {
              "label": "DFU Mode",
              "type": "toggle",
              "options": [
                254,
                255
              ],
              "content": [
                "id_custom_get_value",
                0,
                202
              ]
            }
          ]
        }
      ]
    }

But I don't see any code where this value is handled. The VIA specification says that the channel 0 is for via custom values. I don't know where the 202 is handled in the code.

I also tried to follow the Linworks fave84h which has this code:

// Single Indicator memory layout
typedef struct _indicator_config_t {
    uint8_t h;
    uint8_t s;
    uint8_t v;
    bool    enabled;
} indicator_config;

// Board memory layout
typedef struct _fave_config_t {
    indicator_config caps;
} fave_config;

fave_config fave;

void eeconfig_init_user(void) {
    // Default values
    fave.caps.h       = 0;
    fave.caps.s       = 0;
    fave.caps.v       = RGB_MATRIX_MAXIMUM_BRIGHTNESS;
    fave.caps.enabled = true;

    // Write default value to EEPROM now
    eeconfig_update_kb_datablock(&fave);
}

enum via_fave {
    id_caps_indicator_enabled    = 1,
    id_caps_indicator_brightness = 2,
    id_caps_indicator_color      = 3
};

//On Keyboard startup
void keyboard_post_init_user(void) {
    //Read our custom menu variables from memory
    eeconfig_read_kb_datablock(&fave);
}

bool rgb_matrix_indicators_user(void) {
    if (fave.caps.enabled) {
        // The rgb_matrix_set_color function needs an RGB code to work, so first the indicator color is cast to an HSV value and then translated to RGB
        HSV hsv_caps_indicator_color = {fave.caps.h, fave.caps.s, fave.caps.v};
        RGB rgb_caps_indicator_color = hsv_to_rgb(hsv_caps_indicator_color);
        if (host_keyboard_led_state().caps_lock)
            rgb_matrix_set_color(CAPS_INDICATOR_INDEX, rgb_caps_indicator_color.r, rgb_caps_indicator_color.g, rgb_caps_indicator_color.b);
    }

    return true;
}

void fave_config_set_value(uint8_t *data) {
    // data = [ value_id, value_data ]
    uint8_t *value_id   = &(data[0]);
    uint8_t *value_data = &(data[1]);

    switch (*value_id) {
        case id_caps_indicator_enabled: {
            fave.caps.enabled = value_data[0];
            break;
        }
        case id_caps_indicator_brightness: {
            fave.caps.v = value_data[0];
            break;
        }
        case id_caps_indicator_color: {
            fave.caps.h = value_data[0];
            fave.caps.s = value_data[1];
            break;
        }
    }
}

void fave_config_get_value(uint8_t *data) {
    // data = [ value_id, value_data ]
    uint8_t *value_id   = &(data[0]);
    uint8_t *value_data = &(data[1]);

    switch (*value_id) {
        case id_caps_indicator_enabled: {
            value_data[0] = fave.caps.enabled;
            break;
        }
        case id_caps_indicator_brightness: {
            value_data[0] = fave.caps.v;
            break;
        }
        case id_caps_indicator_color: {
            value_data[0] = fave.caps.h;
            value_data[1] = fave.caps.s;
            break;
        }
    }
}

void fave_config_save(void) {
    eeconfig_update_kb_datablock(&fave);
}

void via_custom_value_command_kb(uint8_t *data, uint8_t length) {
    // data = [ command_id, channel_id, value_id, value_data ]
    uint8_t *command_id        = &(data[0]);
    uint8_t *channel_id        = &(data[1]);
    uint8_t *value_id_and_data = &(data[2]);

    if (*channel_id == id_custom_channel) {
        switch (*command_id) {
            case id_custom_set_value: {
                fave_config_set_value(value_id_and_data);
                break;
            }
            case id_custom_get_value: {
                fave_config_get_value(value_id_and_data);
                break;
            }
            case id_custom_save: {
                fave_config_save();
                break;
            }
            default: {
                // Unhandled message.
                *command_id = id_unhandled;
                break;
            }
        }
        return;
    }

    *command_id = id_unhandled;
}

But VIA give me this errors:

Command Name: BACKLIGHT_CONFIG_GET_VALUE
Command: 8 0 1
Response: 8 0 202 254 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Error: Receiving incorrect response for command
at KeyboardAPI._hidCommand (https://usevia.app/assets/index-f35a099a.js:3:9407)
at async KeyboardAPI.flushQueue (https://usevia.app/assets/index-f35a099a.js:3:8661)

If I change the json to use the 202 field (which is apparently what the firmware is answering) it doesn't give me errors, but it changes nothing on the keyboard... What I'm missing?

Huckies commented 2 weeks ago

Hi, @JavierRiosN

The custom handler is implemented in protocol.c https://github.com/O-H-M2/qmk_port_ch582/blob/ffa0e1b426666ec327fe3f44bb3b0de8517ecec7/qmk_porting/protocol/protocol.c#L112