#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include "atsha204a_comm.h"
#define ATSHA204_ADDR (0xc8)
static unsigned char (*atsha204a_i2c_read)(unsigned char, unsigned char, unsigned char *, int);
static unsigned char (*atsha204a_i2c_write)(unsigned char, unsigned char, unsigned char *, int);
int atsha204a_set_i2c_func(
unsigned char (*i2c_read)(unsigned char, unsigned char, unsigned char *, int),
unsigned char (*i2c_write)(unsigned char, unsigned char, unsigned char *, int)
)
{
if (i2c_read == NULL || i2c_write == NULL) {
return 1;
}
atsha204a_i2c_read = i2c_read;
atsha204a_i2c_write = i2c_write;
return 0;
}
static void msleep(int msec)
{
usleep(msec * 1000);
}
/*
* CRC计算,从atsha204代码库移植过来
*/
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;
// Shift CRC to the left by 1.
crc_register <<= 1;
if ((data_bit ^ crc_bit) != 0)
{
crc_register ^= polynom;
}
}
}
crc[0] = (unsigned char) (crc_register & 0x00FF);
crc[1] = (unsigned char) (crc_register >> 8);
}
/*
* CRC校验,从atsha204代码库移植过来
*/
static unsigned char sha204c_check_crc(unsigned char length, unsigned char *data)
{
unsigned char crc[2];
sha204c_calculate_crc(length-2, data, crc);
return (crc[0] == data[length - 2] && crc[1] == data[length - 1]) ? SHA204_SUCCESS : SHA204_BAD_CRC;
}
static int atsha204a_send_command(struct atsha204a_command_packet *command_packet)
{
unsigned char command_buffer_len = 7 + command_packet->data_len;
unsigned char command_buffer[48];
if (command_packet->data_len > 32)
return SHA204_INVALID_SIZE;
command_buffer[0] = command_buffer_len;
command_buffer[1] = command_packet->op_code;
command_buffer[2] = command_packet->param1;
command_buffer[3] = command_packet->param2[0];
command_buffer[4] = command_packet->param2[1];
if(command_packet->data_len > 0) {
memcpy(command_buffer+5, command_packet->data, command_packet->data_len);
}
sha204c_calculate_crc(command_buffer_len-2, command_buffer, command_buffer+command_buffer_len-2);
atsha204a_i2c_write(ATSHA204_ADDR, 0x03, command_buffer, command_buffer_len);
return 0;
}
/*
* 读取操作命令的response内容,读取的地址都为0x00
*/
static int atsha204a_recv_response(unsigned char length, unsigned char *response_data)
{
atsha204a_i2c_read(ATSHA204_ADDR, 0x00, response_data, length);
return sha204c_check_crc(length,response_data);
}
int atsha204a_read_sn(unsigned char *sn_data)
{
struct atsha204a_command_packet get_sn_command;
unsigned char recv_buffer[35] = {};
get_sn_command.op_code = SHA204_READ;
get_sn_command.param1 = SHA204_ZONE_COUNT_FLAG | SHA204_ZONE_CONFIG;
get_sn_command.param2[0] = 0;
get_sn_command.param2[1] = 0;
get_sn_command.data_len = 0;
get_sn_command.data = NULL;
atsha204a_send_command(&get_sn_command);
msleep(5);
if(atsha204a_recv_response(35, recv_buffer) == SHA204_SUCCESS){
memcpy(sn_data , recv_buffer + SHA204_BUFFER_POS_DATA, 4);
memcpy(sn_data + 4 , recv_buffer + SHA204_BUFFER_POS_DATA + 8, 5);
return SHA204_SUCCESS;
}
return SHA204_CMD_FAIL;
}