加密芯片ATSHA204读序列号(Serial Number)

        近段时间一个项目使用了atsha204,硬件电路设计好后,需要设计一个程序来测试芯片是否正常工作,于是写了一个读Serial Number的程序。

        本文参考了博文 《atsha204a加密芯片使用攻略——配置篇》,该博文比较详细地说明了芯片该如何使用,更详细的芯片使用可以参考该文,这里不赘述了。

        但是我也发现文章中的一些问题,以下内容都是我测试过可行的。

 

一、目标

        我设定的测试目标是读取芯片的Serial Number。Serial Number在Config区域中。
加密芯片ATSHA204读序列号(Serial Number)_第1张图片


二、数据包的格式
1、芯片通讯包基本格式

Word Address

Count

Data

CRC

1 byte

1 byte

N byte

2 byte

 

2、查找datasheet中Read Command的具体样式

加密芯片ATSHA204读序列号(Serial Number)_第2张图片加密芯片ATSHA204读序列号(Serial Number)_第3张图片

可以具体看到Read Command的数据包具体样式如下所示。其中Count的长度不包括Word Address,但包括Count本身

Word Address
 Count
 Opcode
 Param1
 Param2
CRC
1 byte
1 byte
1 byte
1 byte
1 byte
2 byte


3、填充其它内容

      接下来分别填充Qpcode、Param1和Param2的内容

3.1 Qpcode值

        Read指令,所以Qpcode = 0x02

加密芯片ATSHA204读序列号(Serial Number)_第4张图片

3.2  Param1值

        Param1表示的是访问的区域,有三个区域Config、OTP和Data,分别对应的值为:0、1、2、

 加密芯片ATSHA204读序列号(Serial Number)_第5张图片

3.3  Param2值

        Param2中的Block指明操作哪个block和要offset多少个地址。这里是要读取 word 0 的值,所以Block和offset都是0

加密芯片ATSHA204读序列号(Serial Number)_第6张图片

所以Read Command数据包的样式如下:

Word Address

Count

Opcode
Param1
Param2(byte0)

Param2(byte1)

   CRC
0x03
0x07
0x02
0x00
0x00
0x00
2 byte

 

4、计算CRC的值
使用Atmel官方提供的库中的sha204c_calculate_crc()函数算出后面的CRC的值,
库下载地址:http://www.atmel.com/tools/CRYPTOAUTHENTICATIONATSHA204DEVELOPMENTLIBRARY.aspx
sha204c_calculate_crc函数在sha204_comm.c中


void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc) ;
第一个参数:Count ~ Param2(byte1)的个数,总共5个
第二个参数:需要计算的数据起始地址,即Count的地址
第三个参数:写入crc数据的起始地址(算出来的值为:0x1e, 0x2d)

最终Read Command数据包格式如下:

Word Address

Count

Opcode
Param1
Param2(byte0)

Param2(byte1)

CRC1

CRC2

0x03
0x07
0x02
0x00
0x00
0x00
0x1e
0x2d

三、程序设计
        芯片在读写之前,需要进行唤醒。Datasheet中的描述如下:


我写的程序思路如下:
1、设备需要Wake up才能读写数据。
2、查看slave是否有响应,此时读出4个字节,值分别为:0x04 0x11 0x33 0x43
3、发送Read Command
4、读出数据

四、实验结果



五、程序

#include 
#include 
#include 
#include 
#include 
#include 
 
#define SHA204_WRITE   0x01
#define SHA204_READ    0x03
 
struct my_i2c_msg {
    unsigned short addr;  /* slave address          */
    unsigned short flags;
    unsigned short len;       /* msg length             */
    unsigned char buf[64];        /* pointer to msg data          */
};
 
static void sha204c_calculate_crc( unsigned char  length, unsigned char  *data, unsigned char  *crc)
{
    unsigned char counter;
    unsigned short crc_register = 0;
    unsigned short polynom = 0x8005;
    unsigned char  shift_register;
    unsigned char  data_bit, crc_bit;
 
    for (counter = 0; counter < length; counter++) {
        for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
            data_bit = (data[counter] & shift_register) ? 1 : 0;
            crc_bit = crc_register >> 15;
            crc_register <<= 1;
            if (data_bit != crc_bit)
                crc_register ^= polynom;
        }
    }
    crc[0] = (unsigned char)(crc_register & 0x00FF);
    crc[1] = (unsigned char)(crc_register >> 8);
}
 
struct my_i2c_msg packet;
int main()
{
    int fd;

    fd = open("/dev/sha204", O_RDWR);
    if(fd < 0){
        printf("sha204 open failed!");
    }
 
    //1.wake up
    packet.addr = 0x00;
    packet.len = 1;
    packet.buf[0] = 0;
    ioctl(fd, SHA204_WRITE, &packet);
    usleep(2600);
     
    //2.read feedback bytes (4 bytes)
    packet.addr = 0xc8;
    packet.len = 4;
    ioctl(fd, SHA204_READ, &packet);
    printf("Feedback bytes: %x %x %x %x\n", packet.buf[0],packet.buf[1],packet.buf[2],packet.buf[3]);
     
    //3.send read command
    packet.addr = 0xc8;
    packet.len = 8;
    packet.buf[0] = 0x03; //0x03, 0x07, 0x02, 0x00, 0x00, 0x00
    packet.buf[1] = 0x07;
    packet.buf[2] = 0x02;
    packet.buf[3] = 0x00;
    packet.buf[4] = 0x00;
    packet.buf[5] = 0x00;
    sha204c_calculate_crc(5 ,&packet.buf[1],&packet.buf[6]);
    printf("Read command: %x %x %x %x %x %x %x %x\n", packet.buf[0],packet.buf[1],packet.buf[2],packet.buf[3],\
                                                    packet.buf[4],packet.buf[5],packet.buf[6],packet.buf[7]);\                               
    ioctl(fd, SHA204_WRITE, &packet);
    usleep(3000);
     
    //4.read data
    packet.addr = 0xc8;
    packet.len = 7;
    memset(packet.buf, 0, 7);
    ioctl(fd, SHA204_READ, &packet);
    printf("Reading Data: %x %x %x %x %x %x %x\n", packet.buf[0],packet.buf[1],packet.buf[2],packet.buf[3],\
                                                    packet.buf[4],packet.buf[5],packet.buf[6]);
     
    close(fd);
    return 0;
}


你可能感兴趣的:(硬件,i2c)