mirror of
https://github.com/adrcs/ip400.git
synced 2025-04-18 18:13:44 +03:00
120 lines
2.3 KiB
C
120 lines
2.3 KiB
C
#include <stdint.h>
|
|
|
|
/* Atom types */
|
|
#define ATOM_INVALID_TYPE 0x0000
|
|
#define ATOM_VENDOR_TYPE 0x0001
|
|
#define ATOM_GPIO_TYPE 0x0002
|
|
#define ATOM_DT_TYPE 0x0003
|
|
#define ATOM_CUSTOM_TYPE 0x0004
|
|
#define ATOM_HINVALID_TYPE 0xffff
|
|
|
|
#define ATOM_VENDOR_NUM 0x0000
|
|
#define ATOM_GPIO_NUM 0x0001
|
|
#define ATOM_DT_NUM 0x0002
|
|
|
|
//minimal sizes of data structures
|
|
#define HEADER_SIZE 12
|
|
#define ATOM_SIZE 10
|
|
#define VENDOR_SIZE 22
|
|
#define GPIO_SIZE 30
|
|
#define CRC_SIZE 2
|
|
|
|
#define GPIO_MIN 2
|
|
#define GPIO_COUNT 28
|
|
|
|
#define FORMAT_VERSION 0x01
|
|
|
|
#define CRC16 0x8005
|
|
|
|
/* EEPROM header structure */
|
|
struct header_t {
|
|
uint32_t signature;
|
|
unsigned char ver;
|
|
unsigned char res;
|
|
uint16_t numatoms;
|
|
uint32_t eeplen;
|
|
};
|
|
|
|
/* Atom structure */
|
|
struct atom_t {
|
|
uint16_t type;
|
|
uint16_t count;
|
|
uint32_t dlen;
|
|
char* data;
|
|
uint16_t crc16;
|
|
};
|
|
|
|
/* Vendor info atom data */
|
|
struct vendor_info_d {
|
|
uint32_t serial_1; //least significant
|
|
uint32_t serial_2;
|
|
uint32_t serial_3;
|
|
uint32_t serial_4; //most significant
|
|
uint16_t pid;
|
|
uint16_t pver;
|
|
unsigned char vslen;
|
|
unsigned char pslen;
|
|
char* vstr;
|
|
char* pstr;
|
|
};
|
|
|
|
/* GPIO map atom data */
|
|
struct gpio_map_d {
|
|
unsigned char flags;
|
|
unsigned char power;
|
|
unsigned char pins[GPIO_COUNT];
|
|
};
|
|
|
|
|
|
uint16_t getcrc(char* data, unsigned int size) {
|
|
|
|
uint16_t out = 0;
|
|
int bits_read = 0, bit_flag;
|
|
|
|
/* Sanity check: */
|
|
if((data == NULL) || size==0)
|
|
return 0;
|
|
|
|
while(size > 0)
|
|
{
|
|
bit_flag = out >> 15;
|
|
|
|
/* Get next bit: */
|
|
out <<= 1;
|
|
out |= (*data >> bits_read) & 1; // item a) work from the least significant bits
|
|
|
|
/* Increment bit counter: */
|
|
bits_read++;
|
|
if(bits_read > 7)
|
|
{
|
|
bits_read = 0;
|
|
data++;
|
|
size--;
|
|
}
|
|
|
|
/* Cycle check: */
|
|
if(bit_flag)
|
|
out ^= CRC16;
|
|
|
|
}
|
|
|
|
// item b) "push out" the last 16 bits
|
|
int i;
|
|
for (i = 0; i < 16; ++i) {
|
|
bit_flag = out >> 15;
|
|
out <<= 1;
|
|
if(bit_flag)
|
|
out ^= CRC16;
|
|
}
|
|
|
|
// item c) reverse the bits
|
|
uint16_t crc = 0;
|
|
i = 0x8000;
|
|
int j = 0x0001;
|
|
for (; i != 0; i >>=1, j <<= 1) {
|
|
if (i & out) crc |= j;
|
|
}
|
|
|
|
return crc;
|
|
}
|