/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... read the silicon serial number.
 */

#include <stdio.h>
#include "ow.h"

#define ReadROM		0x33			// 1-wire command

/*
 * Read ROM
 *
 * Return rom or 0 on error.
 */
static unsigned char *
get_rom(void)
{
	static unsigned char rom[8];		// byte0 =CRC
						//  1..6 =serial number
						//     7 =family code

	unsigned char crc = 0;			// CRC
	int i;

	if (OW_PROBE) return 0;			// no device!
	ow_tx(ReadROM);				// read ROM cmd

	/*
	 * Read ROM to rom.
	 */
	for (i = sizeof(rom); --i >= 0;) rom[i] = ow_rx();

	/*
	 * Compute CRC. (result must be zero!)
	 *
	 * Poly = x^8+x^5+x^4+1 -> 100110001 -> 00110001.
	 * Since the bytes are transferred LSB first, the
	 * CRC is computed with reversed bit order of the
	 * data and the poly: 00110001 -> 10001100 =0x8c.
	 */
	for (i = sizeof(rom); --i >= 0;) {
		int bits = 8;

		crc ^= rom[i];
		while (bits--) crc = crc>>1^(crc&1? 0x8c: 0);
	}

	return crc? 0: rom;
}

int
main(void)
{
	unsigned char *rom;

	puts("Hit RETURN to read serial number..."), getchar();

	if (!(rom = get_rom())) return puts("No device or CRC error.\7"), 1;

	printf(" 8-Bit CRC           : %02x\n"
	       "48-Bit Serial Number : %02x%02x%02x%02x%02x%02x\n"
	       " 8-Bit Family Code   : %02x\n",
		rom[0],
		rom[1], rom[2], rom[3], rom[4], rom[5], rom[6],
		rom[7]
	);
	return 0;
}
