qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

protocol.h (3324B)


      1 /*
      2  * (c) 2021 by Tomasz bla Fortuna
      3  * License: GPLv2
      4  *
      5  * This file is shared with the Shine firmware. Keep it in sync (and in the
      6  * shine's clang formatting).
      7  */
      8 
      9 #pragma once
     10 #include <stdint.h>
     11 
     12 #define PROTOCOL_SD SD0
     13 
     14 enum {
     15     /*
     16      * Main -> LED
     17      */
     18     /* Basic config */
     19     CMD_LED_ON  = 0x01,
     20     CMD_LED_OFF = 0x02,
     21 
     22     CMD_LED_SET_PROFILE  = 0x03,
     23     CMD_LED_NEXT_PROFILE = 0x04,
     24     CMD_LED_PREV_PROFILE = 0x05,
     25 
     26     CMD_LED_NEXT_INTENSITY       = 0x06,
     27     CMD_LED_NEXT_ANIMATION_SPEED = 0x07,
     28 
     29     /* Masks */
     30     /* Override a key color, eg. capslock */
     31     CMD_LED_MASK_SET_KEY = 0x10,
     32     /* Override all keys in a row with configurable colors */
     33     CMD_LED_MASK_SET_ROW = 0x11,
     34 
     35     /* Override all keys with single color (eg. foreground color) */
     36     CMD_LED_MASK_SET_MONO = 0x12,
     37 
     38     /* Reactive / status */
     39     CMD_LED_GET_STATUS = 0x20, /* unused */
     40     CMD_LED_KEY_BLINK  = 0x21,
     41     CMD_LED_KEY_DOWN   = 0x22,
     42     CMD_LED_KEY_UP     = 0x23, /* TODO */
     43     CMD_LED_IAP        = 0x24,
     44 
     45     /* Manual color control */
     46     CMD_LED_SET_MANUAL = 0x30,
     47     CMD_LED_COLOR_SET_KEY = 0x31,
     48     CMD_LED_COLOR_SET_ROW = 0x32,
     49     CMD_LED_COLOR_SET_MONO = 0x33,
     50 
     51     /* LED -> Main */
     52     /* Payload with data to send over HID */
     53     CMD_LED_DEBUG = 0x40,
     54 
     55     /* Number of profiles, current profile, on/off state,
     56        reactive flag, brightness, errors */
     57     CMD_LED_STATUS = 0x41,
     58 
     59     /* Set sticky key, meaning the key will light up even when LEDs are turned off */
     60     CMD_LED_STICKY_SET_KEY = 0x50,
     61     CMD_LED_STICKY_SET_ROW = 0x51,
     62     CMD_LED_STICKY_SET_MONO = 0x52,
     63     CMD_LED_STICKY_UNSET_KEY = 0x53,
     64     CMD_LED_STICKY_UNSET_ROW = 0x54,
     65     CMD_LED_STICKY_UNSET_ALL = 0x55,
     66 };
     67 
     68 /* 1 ROW * 14 COLS * 4B (RGBX) = 56 + header prefix. */
     69 #define MAX_PAYLOAD_SIZE 64
     70 
     71 /** Enum of the states used for the serial protocol finite-state automaton */
     72 enum proto_state {
     73     /* 2-byte initial start-of-message sync */
     74     STATE_SYNC_1,
     75     STATE_SYNC_2,
     76     /* Waiting for command byte */
     77     STATE_CMD,
     78     /* Waiting for ID byte */
     79     STATE_ID,
     80     /* Waiting for payload size */
     81     STATE_PAYLOAD_SIZE,
     82     /* Reading payload until payload_position == payload_size */
     83     STATE_PAYLOAD,
     84 };
     85 
     86 /* Buffer holding a single message */
     87 typedef struct {
     88     uint8_t command;
     89     uint8_t msg_id;
     90     uint8_t payload_size;
     91     uint8_t payload[MAX_PAYLOAD_SIZE];
     92 } message_t;
     93 
     94 /* Internal protocol state */
     95 typedef struct {
     96     /* Callback to call upon receiving a valid message */
     97     void (*callback)(const message_t *);
     98 
     99     /* Number of read payload bytes */
    100     uint8_t payload_position;
    101 
    102     /* Current finite-state-automata state */
    103     enum proto_state state;
    104 
    105     uint8_t previous_id;
    106     uint8_t errors;
    107 
    108     /* Currently received message */
    109     message_t buffer;
    110 } protocol_t;
    111 
    112 /* NOTE: This didn't work when defined on stack */
    113 extern protocol_t proto;
    114 
    115 /* Init state */
    116 extern void proto_init(protocol_t *proto, void (*callback)(const message_t *));
    117 
    118 /* Consume one byte and push state forward - might call the callback */
    119 extern void proto_consume(protocol_t *proto, uint8_t byte);
    120 
    121 /* Prolonged silence - reset state */
    122 extern void proto_silence(protocol_t *proto);
    123 
    124 /* Transmit message */
    125 extern void proto_tx(uint8_t cmd, const unsigned char *buf, int payload_size, int retries);