#ifndef SIGNATURE_H_ #define SIGNATURE_H_ // User signature is a 512 byte long reprogrammable region // We use it to store serial number and configuration data #include #define USER_SIG_SIZE_BYTES (512u) #define USER_SIG_SIZE_WORDS (USER_SIG_SIZE_BYTES/sizeof(uint32_t)) #define SIG_MAGIC (0x5AADE15Fu) // No special significance, just a randomly generated number from 0 to 0xFFFF.FFFF #define CRC8POLY (0x07) // Polynomial generator for CRC typedef enum en_user_sig_state{ SIG_UNINITIALIZED, // Ram buffer in unknown state, doesn't match Flash SIG_VALID, // Ram and Flash match SIG_OVERWRITTEN // Ram has been written with new values } User_Signature_State; // Signature tags. // Signature fields are stored in Tag-Length-Value-CRC format. // Tag is one byte, length is one byte, value is a variable number of bytes, // and CRC is one byte calculated over all the previous byte (including the initial tag). // // // Examples: // // |Tag--|Length--|Value (8 bytes)--------------------------------|CRC8| // 0x01, 0x08, 0x48, 0x69, 0x54, 0x68, 0x65, 0x72, 0x65, 0x21, 0x9D // This is a 8-byte serial number: "HiThere!" enum signature_tags{ SigTag_Serial = 0x01, // Variable length, ASCII characters. Assigned to PCBA during factory test. SigTag_RGB_Color = 0x02, // 3 bytes, Red, Green, and Blue color SigTag_Fan_Speed = 0x03, // one byte, fan speed in percent SigTag_Prox_Disable = 0x04, // one byte, boolean SigTag_Linkbox_v1 = 0x05, // one byte, boolean SigTag_Prox_Cal = 0x06, // two bytes, u16 value of proximity sensor signal with nothing present SigTag_FATP_Mode = 0x07, // one byte, boolean SigTag_HMD_Serial = 0x08, // Variable length, ASCII characters. Serial number of whole headset assembly SigTag_Tracking_Serial = 0x09, // Variable length, ASCII characters. Serial number of the tracking flex in the HMD SigTag_Display_Brightness = 0x0A, // two bytes, u16 value of default display brightness. 0 to 0x03FF SigTag_Prox_Threshold = 0x0B, // two bytes, u16 value of prox sensor threshold SigTag_Prox_Hysteresis = 0x0C, // two bytes, u16 value of prox sensor threshold hysteresis (eg turns on at thresh+hyst, turns off at thresh-hyst) SigTag_EDID_Switch = 0x0D, // one byte: 0 = both 75Hz and 90Hz modes, 1 = 90Hz only, 2 = 75Hz only SigTag_Prox_User_Trim = 0x0E, // two bytes, i16 proximity threshold adjustment (NOTE THIS IS A SIGNED VALUE!) SigTag_VXR_Sleep_Enable = 0x0F, // one byte: 0 = no sleep, anything else = sleep. Default (not loaded) is no sleep. SigTag_Invalid = 0xFF // Any unprogrammed byte will be 0xFF. Can use this to denote the end of the valid tags }; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" typedef struct __attribute__((packed)) st_user_sig_region{ uint32_t magic_num; char serial_number[16]; // 16 alpha-numeric serial number int16_t user_name[64]; // UTF-16 user name, up to 64 characters (will have to be truncated after 64, sorry long name folks) RGB_Color_t default_color; // initial boot up color, and "off" (all zeros) can count as a color uint8_t default_fan_speed; // fan speed in percent bool prox_disabled; // false: proximity sensor turns displays on and off // true: displays always on when there is video data, proximity sensor is ignored bool linkbox_is_v1; // false: CC wire pulldown should be 1k (extra pulldowns ON) to assert HPD. // true: CC wire pulldown should be 5.1k to assert HPD. This was the case on Linkbox v1. uint8_t crc8; } User_Signature_T; #pragma GCC diagnostic pop #define USER_SIG_STRUCT_SIZE sizeof(User_Signature_T) ct_assert(USER_SIG_STRUCT_SIZE <= USER_SIG_SIZE_BYTES, user_sig_too_big); uint8_t crc8(uint8_t initcrc, const uint8_t* input_data, uint32_t len); const User_Signature_T* get_signature(void); uint8_t update_signature_raw(uint8_t* buf, uint32_t offset, uint32_t len); const uint32_t* get_signature_raw(void); uint8_t save_signature(void); uint8_t save_signature_raw(void); bool check_signature(const User_Signature_T* sig); bool sigv2_find_tag(uint8_t tag, uint8_t* retval); bool sigv2_tag_exists(uint8_t tag); uint8_t sigv2_tag_length(uint8_t tag); uint16_t sigv2_build_signature(uint16_t sig_ptr, uint8_t tag, uint8_t length, uint8_t* data); uint16_t sigv2_find_first_blank(void); bool sigv2_add_new_tag(uint8_t tag, uint8_t length, uint8_t* data); void sigv2_upgrade_from_sigv1(void); #endif // SIGNATURE_H_