Components I Usually Use (I): DS28CM00 – I2C Serial Number

I want to start a serie of brief articles describing the components that I usually used in my electronic designs.

The first one is the DS28CM00 I2C serial number. This device is an electronic registration number that gives you an unique 64-bit serial number over I2C or SMBUS interface. This 64-bit serial number is  factory lasered, so there aren’t  two devices with the same number.

I use this component in a railway application, to identify the PCB’s mounted in the system. The pinout and the typical connection of this device is shown here:

Imagen

The serial number has the following structure:

–          1 byte that identifies the family code (0x70)

–          6 bytes with the unique serial number

–          1 byte corresponiding the 8 bit CRC of the above bytes.

Also, the device has a contro register, where you can select the type of communication: I2C or SMBus. In the next figure, you can see the address of these registers:

Imagen

As an I2C device, the DS20CM00 must have a bus address to access it. The address for read is 0xA1, and the address for write is 0xA0. Unfortunately, this address cannot be configurated, so you must be carefully if you use in the bus with other devices, to avoid conflicts on it.

  • Software example

Here you can see an example of how to access and communicate with this device. I use an AT89C51RE2 microcontroller from Atmel, and with two pins I do a bit-banging I2C software bus. The code I use is here:

//
// FUNCTION : void Read_ID (void)                                      
// AUTHOR   : jechavarria
// DESCRIPTION: Reads registration number from DS28CM00
// First, configure the device for I2C operation mode
// After, reads the 8 bytes of data and checks the
// calculate CRC-8 with the one read from the device.
// If it’s the same, the data read from DS28CM00
// stores in the global variable  ID_Hardware [8]. If not,
// the global variable initialize to 0x00.
//
void Read_ID (void)
{
//————————————————————————
// Local variables
//————————————————————————
unsigned char i;
unsigned char num_serie [8];
for (i=0; i<8; i++)
  num_serie [i] = 0x00;
 //————————————————————————
// Config I2C mode
//————————————————————————
I2C3_Start ();                         // Start
I2C3_Write (ID_WR);             // Write
I2C3_Write (0x08);                // Write positon 08: Control register
I2C3_Write (0x00);                // Write 0x00: I2C mode
I2C3_Stop ();                        // Stops communication
I2C3_Delay (100);
//————————————————————————
// Reads 8 bytes of data of DS28CM00:
//————————————————————————
I2C3_Start ();                         // Start
I2C3_Write (ID_WR);             // Write Command
I2C3_Write (0x00);                // Pointer at position 0
I2C3_Start ();                         // Repeat Start conditon
I2C3_Write (ID_RD);              // Read command
// Reads 8 bytes of data. Stores in the temporal variable ‘num_serie [i]’
for (i=0;i<7;i++)
  {
    num_serie [i] = I2C3_Read ();
    I2C3_txACK ();
  }
num_serie [7] = I2C3_Read ();          // Reads CRC
I2C3_txNACK ();                                // Send NACK
I2C3_Stop ();                                    // Stops communication
I2C3_Delay (100);
//————————————————————————
// Calculating the CRC-8
//————————————————————————
CRC8 = 0;       // Global variable to store CRC8 calc
for (i=0; i<7; i++)
  Calculo_CRC8 (num_serie [i]);     // Calc CRC8 of the data read from DS28CM00
//————————————————————————
// Comparing the CRC-8 calc with the one read.
// If it’s the same, the data read from DS28CM00 stores in the
// global variable ID_Hardware [8]. If not, this variable initialize at 0x00
//————————————————————————
if (CRC8 == num_serie [7])
  {
    for (i=0; i<8; i++)
      {
        ID_Hardware [i] = num_serie [i];
      }
  }
else
  {
    for (i=0; i<8; i++)
      {
        ID_Hardware [i] = 0x00;
      }
  }
}
  • Calculating CRC-8

In the datasheet, you can find a reference to an application note (AN27) that describes how to calculate the CRC-8. I use it to make my own routine in C code:

//
// FUNCTION : void Calculo_CRC8 (unsigned char dato)                                      
// AUTHOR   : jechavarria
// DESCRIPTION: Calculating the CRC-8 of the data that passed by argument.
// The used polinomy is: x^8 + x^5 + x^4 + 1.
// The result is stored in the global variable 

CRC8

//

void Calculo_CRC8 (unsigned char dato)
{
//————————————————————————
// Local variables
//————————————————————————

unsigned char i;

unsigned char fb;

//————————————————————————
// Calculate the CRC-8
//————————————————————————

for (i=0; i<8; i++)

{

fb =  (CRC8 ^ dato) & 0x01;

dato >>= 1;

CRC8 >>= 1;

if (fb)

{

CRC8 ^=0x8C;

}

}

}

Finally, two tips to use this function:

– The variable CRC-8 must be a global variable.

– Before call the function for the first time, you must initialize this variable to 0x00.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s