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);