view duart28/eeprom_rd.c @ 67:742c41f44658

doc/FTDI-chip-ID: new article
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 13 Sep 2023 00:43:14 +0000
parents 8de3891460db
children
line wrap: on
line source

/*
 * This module implements the steps of reading and validating the starting
 * EEPROM content.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <usb.h>
#include "../libftmini/eeprom_func.h"

u_short eeprom[64];

void
read_eeprom(usbh)
	usb_dev_handle *usbh;
{
	unsigned n;

	for (n = 0; n < 64; n++)
		eeprom[n] = ftmini_read_eeprom_loc(usbh, n);
}

static void
verify_nonblank()
{
	unsigned n;

	for (n = 0; n < 64; n++) {
		if (eeprom[n] != 0xFFFF)
			return;
	}
	fprintf(stderr, "error: EEPROM is blank (erased?)\n");
	exit(1);
}

static void
verify_eeprom_chksum()
{
	u_short chksum = 0xAAAA;
	unsigned n;

	for (n = 0; n < 64; n++) {
		chksum ^= eeprom[n];
		chksum = (chksum << 1) | (chksum >> 15);
	}
	if (chksum == 0)
		return;
	fprintf(stderr, "error: EEPROM checksum is wrong\n");
	exit(1);
}

static int
check_req_match()
{
	if (eeprom[0] != 0x0808)
		return 0;
	if (eeprom[1] != 0x0403)
		return 0;
	if (eeprom[2] != 0x6010 && eeprom[2] != 0x7152)
		return 0;
	if (eeprom[3] != 0x0500)
		return 0;
	if (eeprom[4] != 0x3280)
		return 0;
	if (eeprom[5] != 0x0000 && eeprom[5] != 0x0008)
		return 0;
	if (eeprom[6] != 0x0200)
		return 0;
	if (eeprom[7] != 0x1896)
		return 0;
	if (eeprom[8] != 0x12AE)
		return 0;
	if (eeprom[10] != 0x0046)
		return 0;
	if (eeprom[11] != 0x0318)
		return 0;
	if (eeprom[12] != 'F')
		return 0;
	if (eeprom[13] != 'r')
		return 0;
	if (eeprom[14] != 'e')
		return 0;
	if (eeprom[15] != 'e')
		return 0;
	if (eeprom[16] != 'C')
		return 0;
	if (eeprom[17] != 'a')
		return 0;
	if (eeprom[18] != 'l')
		return 0;
	if (eeprom[19] != 'y')
		return 0;
	if (eeprom[20] != 'p')
		return 0;
	if (eeprom[21] != 's')
		return 0;
	if (eeprom[22] != 'o')
		return 0;
	if (eeprom[23] != 0x0312)
		return 0;
	if (eeprom[24] != 'D')
		return 0;
	if (eeprom[25] != 'U')
		return 0;
	if (eeprom[26] != 'A')
		return 0;
	if (eeprom[27] != 'R')
		return 0;
	if (eeprom[28] != 'T')
		return 0;
	if (eeprom[29] != '2')
		return 0;
	if (eeprom[30] != '8')
		return 0;
	if (eeprom[31] != 'C' && eeprom[31] != 'S')
		return 0;
	return 1;
}

analyze_eeprom()
{
	verify_nonblank();
	verify_eeprom_chksum();
	if (!check_req_match()) {
		fprintf(stderr,
			"error: EEPROM content does not match FC DUART28\n");
		exit(1);
	}
	if (eeprom[2] == 0x7152 && eeprom[31] == 'C') {
		printf("EEPROM is programmed for DUART28C\n");
		return 'C';
	}
	if (eeprom[2] == 0x6010 && eeprom[31] == 'S') {
		printf("EEPROM is programmed for DUART28S\n");
		return 'S';
	}
	printf("EEPROM is inconsistent between C and S configs!\n");
	return '?';
}