- /*
- * (c) 2021 by Tomasz bla Fortuna
- * License: GPLv2
- *
- * This file is shared with the Shine firmware. Keep it in sync (and in the
- * shine's clang formatting).
- */
-
- #pragma once
- #include <stdint.h>
-
- #define PROTOCOL_SD SD0
-
- enum {
- /*
- * Main -> LED
- */
- /* Basic config */
- CMD_LED_ON = 0x01,
- CMD_LED_OFF = 0x02,
-
- CMD_LED_SET_PROFILE = 0x03,
- CMD_LED_NEXT_PROFILE = 0x04,
- CMD_LED_PREV_PROFILE = 0x05,
-
- CMD_LED_NEXT_INTENSITY = 0x06,
- CMD_LED_NEXT_ANIMATION_SPEED = 0x07,
-
- /* Masks */
- /* Override a key color, eg. capslock */
- CMD_LED_MASK_SET_KEY = 0x10,
- /* Override all keys in a row with configurable colors */
- CMD_LED_MASK_SET_ROW = 0x11,
-
- /* Override all keys with single color (eg. foreground color) */
- CMD_LED_MASK_SET_MONO = 0x12,
-
- /* Reactive / status */
- CMD_LED_GET_STATUS = 0x20, /* unused */
- CMD_LED_KEY_BLINK = 0x21,
- CMD_LED_KEY_DOWN = 0x22,
- CMD_LED_KEY_UP = 0x23, /* TODO */
- CMD_LED_IAP = 0x24,
-
- /* Manual color control */
- CMD_LED_SET_MANUAL = 0x30,
- CMD_LED_COLOR_SET_KEY = 0x31,
- CMD_LED_COLOR_SET_ROW = 0x32,
- CMD_LED_COLOR_SET_MONO = 0x33,
-
- /* LED -> Main */
- /* Payload with data to send over HID */
- CMD_LED_DEBUG = 0x40,
-
- /* Number of profiles, current profile, on/off state,
- reactive flag, brightness, errors */
- CMD_LED_STATUS = 0x41,
-
- /* Set sticky key, meaning the key will light up even when LEDs are turned off */
- CMD_LED_STICKY_SET_KEY = 0x50,
- CMD_LED_STICKY_SET_ROW = 0x51,
- CMD_LED_STICKY_SET_MONO = 0x52,
- CMD_LED_STICKY_UNSET_KEY = 0x53,
- CMD_LED_STICKY_UNSET_ROW = 0x54,
- CMD_LED_STICKY_UNSET_ALL = 0x55,
- };
-
- /* 1 ROW * 14 COLS * 4B (RGBX) = 56 + header prefix. */
- #define MAX_PAYLOAD_SIZE 64
-
- /** Enum of the states used for the serial protocol finite-state automaton */
- enum proto_state {
- /* 2-byte initial start-of-message sync */
- STATE_SYNC_1,
- STATE_SYNC_2,
- /* Waiting for command byte */
- STATE_CMD,
- /* Waiting for ID byte */
- STATE_ID,
- /* Waiting for payload size */
- STATE_PAYLOAD_SIZE,
- /* Reading payload until payload_position == payload_size */
- STATE_PAYLOAD,
- };
-
- /* Buffer holding a single message */
- typedef struct {
- uint8_t command;
- uint8_t msg_id;
- uint8_t payload_size;
- uint8_t payload[MAX_PAYLOAD_SIZE];
- } message_t;
-
- /* Internal protocol state */
- typedef struct {
- /* Callback to call upon receiving a valid message */
- void (*callback)(const message_t *);
-
- /* Number of read payload bytes */
- uint8_t payload_position;
-
- /* Current finite-state-automata state */
- enum proto_state state;
-
- uint8_t previous_id;
- uint8_t errors;
-
- /* Currently received message */
- message_t buffer;
- } protocol_t;
-
- /* NOTE: This didn't work when defined on stack */
- extern protocol_t proto;
-
- /* Init state */
- extern void proto_init(protocol_t *proto, void (*callback)(const message_t *));
-
- /* Consume one byte and push state forward - might call the callback */
- extern void proto_consume(protocol_t *proto, uint8_t byte);
-
- /* Prolonged silence - reset state */
- extern void proto_silence(protocol_t *proto);
-
- /* Transmit message */
- extern void proto_tx(uint8_t cmd, const unsigned char *buf, int payload_size, int retries);
|