STM32F4读写AT88SC0104加密存储芯片驱动库

AT88SC系列加密芯片应用广泛,用于接触式与非接触式IC的存储。它采用I2C接口,与标准I2C时序有差别,建议用模拟时序驱动。加解密算法由ATmel官方封装,at88sc_read_storage与at88sc_write_storage函数对应用层友好。

一、AT88SC系列加密芯片应用很广,接触式与非接触式IC都会使用这个芯片作为存储芯片,I2C接口,但与标准的I2C时序有点差别,最好是使用模拟时序驱动,加解密算法来自于ATmel官方对其进行了封装,at88sc_read_storage与at88sc_write_storage两个函数对于应用层来说很友好

/** 
* @file     at88sc.c 
* @brief    at88sc driver. 
* @details  Simulation time sequence, authentication read and write user zone and config zone. 
* @author   ken 
* @date     2018-11-15 
* @version  A001 
* @par Copyright (c):  
* @par History:          
*   version: ken, 2018-11-15, create\n 
*/  
#include "system.h"
#include "at88sc.h"
#include "dwt.h"
#include "string.h"
#include "main.h"
#include "smartcard.h"

#ifdef AT88SC_DEBUG
    #define	at88sc_log(...) do{if(DEBUG(DEBUG_ENABLE)){DBG_LOG("[AT88SC](%ld) ",__LINE__);DBG_LOG(__VA_ARGS__);}}while(0)
    #define at88sc_usr(...) do{if(DEBUG(DEBUG_ENABLE)){DBG_LOG("[AT88SC] ");DBG_USR(__VA_ARGS__);}}while(0)
    #define at88sc_err(...) do{if(DEBUG(DEBUG_ENABLE)){DBG_LOG("[AT88SC] ");DBG_ERR(__VA_ARGS__);}}while(0)
    #define at88sc_dump(...) if(DEBUG(DEBUG_ENABLE)){DBG_DUMP(__VA_ARGS__);}
#else
    #define at88sc_log(...)
    #define at88sc_usr(...)
    #define at88sc_err(...)
    #define at88sc_dump(...)
#endif

/**  at88sc gpio port  */  
GPIO_InitTypeDef AT88SC_GPIO;
/**  GPA units  */  
uint8_t GPA[20];
/**  config zone  */  
//AT88SC_CONFIG_ZONE_T at88sc_config_zone;

static const uint8_t block_admini[]={BLOCK0_ADMINI,BLOCK1_ADMINI,BLOCK2_ADMINI,BLOCK3_ADMINI,BLOCK4_ADMINI,BLOCK5_ADMINI,BLOCK6_ADMINI,
BLOCK7_ADMINI,BLOCK8_ADMINI,BLOCK9_ADMINI,BLOCK10_ADMINI,BLOCK11_ADMINI,BLOCK12_ADMINI,BLOCK13_ADMINI,BLOCK14_ADMINI,BLOCK15_ADMINI};

/**  at88sc status  */  
AT88SC_STA_T st88sc_sta;

/**  GC_TABLE  */  
unsigned char const GC0[]={0x63,0x6A,0x56,0x56,0xD8,0x60,0x2F,0x25};//GC0
unsigned char const GC1[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//GC1
unsigned char const GC2[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//GC2
unsigned char const GC3[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//GC3

/**  PASSWORD_TABLE  */  
unsigned char const PW_WRITE0[]={0x57,0x26,0xF1};//WRITE PASSWORD 0
unsigned char const PW_READ0[]= {0x57,0x26,0xF1};//READ  PASSWORD 0
unsigned char const PW_WRITE1[]={0xFF,0xFF,0xFF};//WRITE PASSWORD 1
unsigned char const PW_READ1[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 1
unsigned char const PW_WRITE2[]={0xFF,0xFF,0xFF};//WRITE PASSWORD 2
unsigned char const PW_READ2[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 2
unsigned char const PW_WRITE3[]={0xFF,0xFF,0xFF};//WRITE PASSWORD 3
unsigned char const PW_READ3[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 3
unsigned char const PW_WRITE4[]={0xFF,0xFF,0xFF};//WRITE PASSWORD 4
unsigned char const PW_READ4[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 4
unsigned char const PW_WRITE5[]={0xFF,0xFF,0xFF};//WRITE PASSWORD 5
unsigned char const PW_READ5[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 5
unsigned char const PW_WRITE6[]={0xFF,0xFF,0xFF};//WRITE PASSWORD 6
unsigned char const PW_READ6[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 6
unsigned char const PW_WRITE7[]={0x05,0x05,0xC7};//WRITE PASSWORD 7
unsigned char const PW_READ7[]= {0xFF,0xFF,0xFF};//READ  PASSWORD 7


static void SMSTART(void);
static void SMSTOP(void);
static void IIC_Initial(void);
static void at88sc_ack_polling(void);
static void at88sc_gpa_clock(uint8_t Datain,uint8_t times);
static void at88sc_read(uint8_t *rd_ptr);
static void at88sc_write(uint8_t *wd_ptr);
static void at88sc_encrypto_data(uint8_t encryptodatanumber,uint8_t *ptr);
static void at88sc_send_checksum(void);
static uint8_t at88sc_mtz_test(void);

/** 
* test i2c communication normal with at88sc. 
* write 2 register and read comparison,if the chip config zone lock well return 0xfx. 
* @param[in]   none.
* @param[out]  noen.
* @retval  1 success, 0 failed
* @par TAG 
*      reserved 
* @par other 
*      none 
* @par modify
*      ken 2018-11-15 create
*/
uint8_t at88sc_mtz_test(void){
	
	uint8_t send_buf[2];
	uint8_t recv_buf[2];
	send_buf[0]=0xa5;
	send_buf[1]=0x5a;
	at88sc_write_config_register(MTZ_R,send_buf);
	delay_ms(10);
	at88sc_read_config_register(MTZ_R,recv_buf);
	
	if (recv_buf[0]==0xa5 && recv_buf[1]==0x5a ){
		return 1;
	}
	else
		return 0;
}

/** 
* i2c communication initialize. 
* initialize the i2c gpio signal. 
* @param[in]   none.
* @param[out]  noen.
* @retval  none
* @par TAG 
*      reserved 
* @par other 
*      none 
* @par modify
*      ken 2018-11-15 create
*/
static void IIC_Initial(void){
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__disable_irq();
	#endif
	
	CM_CLK_OUT;
	CM_DATA_OUT;
	
	CM_DATA_HI;			
	delay_us(12);
 	CM_CLK_HI;
	delay_us(12);
	CM_CLK_LO;
	delay_us(12);
 	CM_CLK_HI;
	delay_us(12);
	CM_CLK_LO;
	delay_us(12);
 	CM_CLK_HI;
	delay_us(12);
	CM_CLK_LO;
	delay_us(12);
 	CM_CLK_HI;
	delay_us(12);
	CM_CLK_LO;
	delay_us(12);
 	CM_CLK_HI;
	delay_us(12);
	CM_CLK_LO;
	delay_us(12);// 5 CLK
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__enable_irq();
	#endif
}

/** 
* generate i2c start signal. 
* generate i2c start signal. 
* @param[in]   none.
* @param[out]  noen.
* @retval  none
* @par TAG 
*      reserved 
* @par other 
*      none 
* @par modify
*      ken 2018-11-15 create
*/
static void SMSTART(void){
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__disable_irq();
	#endif
	
	CM_DATA_OUT;
 	CM_CLK_LO;
	delay_us(8);
	 CM_DATA_HI;
	delay_us(8);
	CM_CLK_HI;
	delay_us(8);
 	CM_DATA_LO;
	delay_us(8);
 	CM_CLK_LO;
	delay_us(8);
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__enable_irq();
	#endif
}

/** 
* generate i2c stop signal. 
* generate i2c stop signal. 
* @param[in]   none.
* @param[out]  noen.
* @retval  none
* @par TAG 
*      reserved 
* @par other 
*      none 
* @par modify
*      ken 2018-11-15 create
*/
static void SMSTOP(void){
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__disable_irq();
	#endif
	
	CM_DATA_OUT;  	
	CM_DATA_LO;
	delay_us(8);
  	CM_CLK_HI;
	delay_us(8);
  	CM_DATA_HI;
	delay_us(8);
  	CM_CLK_LO;
	delay_us(8);
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__enable_irq();
	#endif
}

/** 
* poll i2c ack signal. 
* poll i2c ack signal. 
* @param[in]   none.
* @param[out]  noen.
* @retval  none
* @par TAG 
*      reserved 
* @par other 
*      none 
* @par modify
*      ken 2018-11-15 create
*/
void at88sc_ack_polling(void){
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__disable_irq();
	#endif
	
	uint8_t  AckPolling_return;
	uint8_t  temp, bitcounter;
	uint8_t  bytecounter;

	SMSTART();
	temp=0xb6;
	bytecounter=0xff;			//note:if CPU clk fast,inc bytecounter.
	AckPolling_return=0;

	do{	
		CM_DATA_OUT;
		delay_us(8);
		for(bitcounter=0;bitcounter<8;bitcounter++){
			
			if (temp&0x80){
				CM_DATA_HI;
			}
			else{
				CM_DATA_LO;
			}
			delay_us(8);
			CM_CLK_HI;
			delay_us(8);
			CM_CLK_LO;
			delay_us(8);
			temp=temp<<1;
		}
		
		bytecounter--;
				
		CM_DATA_IN;
		delay_us(8);
		
		CM_CLK_HI;
		delay_us(8);
		
		if(!(CM_DATA_RD)){
			CM_CLK_LO;
			delay_us(8);
			AckPolling_return=1;
		}
		else{
			CM_CLK_LO;
			AckPolling_return=0;
			SMSTART();
			temp=0xb6;
		}

		if(AckPolling_return==1){
			break;
		}

	}while(bytecounter>0);

	SMSTOP();
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__enable_irq();
	#endif
}
  
/** 
* read data from at88sc. 
* protocol:cmd addr1 addr2 len data*N. 
* @param[in]   rd_ptr:read pointer, define command protocol.
* @param[out]  noen.
* @retval  none
* @par TAG 
*      reserved 
* @par other 
*      none 
* @par modify
*      ken 2018-11-15 create
*/
static void at88sc_read(uint8_t  *rd_ptr){
	
	#ifdef AT88SC_DISABLE_INTERRUPT
	__disable_irq();
	#endif
	
	uint8_t bitcounter;
	uint8_t temp;
	uint8_t cmd_send_counter;
	uint8_t bytecounter;
	temp=rd_ptr[0];
	bytecounter=0;
	cmd_send_counter=0;
	uint8_t recv_len = rd_ptr[3];
	
	SMSTART();

	do{
		CM_DATA_OUT;
		delay_us(8);
		for(bitcounter=0;bitcounter<8;bitcounter++){
			
			if (temp&0x80){
				CM_DATA_HI;
			}
			else{
				CM_DATA_LO;
			}
			delay_us(8);
			CM_CLK_HI;
			delay_us(8);
			CM_CLK_LO;
			delay_us(8);
			temp=temp<<1;
		}
		
		CM_DATA_HI;
		delay_us(8);

		CM_DATA_IN;
		delay_us(8);
		
		CM_CLK_HI;
		delay_us(8);

		if(!(CM_DATA_RD)){
			CM_CLK_LO;
			delay_us(8);
			bytecounter++;
			temp=rd_ptr[bytecounter];
		}
		else{
			CM_CLK_LO;
			SMSTART();
			temp=rd_ptr[0];
			bytecounter=0;
			cmd_send_counter++;
		}

		if(cmd_send_counter>8){
			bytecounter=4;
			goto read_out;
		}

	}while(bytecounter<4);
	
	for(bytecounter=0;bytecounter<recv_len;bytecounter++){
		
		CM_DATA_IN;
		delay_us(8);
		for(bitcounter=0;bitcounter<8;bitcounter++){
			
			CM_CLK_HI;
			delay_us(8);

			if (CM_DATA_RD){
				temp=temp|0x01;
			}
			else{
				temp=(temp&0xfe);
			}

			if(bitcounter<7){
				temp=temp<<1;
			}
			else{
				delay_us(4);
			}

			CM_CLK_LO;
			delay_us(8);
		}

		CM_DATA_OUT;
		delay_us(8);
		CM_DATA_LO;
		delay_us(8);
		CM_CLK_H
防范硬件盗版,最有效的方法是对产品加把“锁”。ATMEL公司提供了几种可靠方案,即AT88SC系列和SHA-256系列安全存储加密芯片AT88SC系列加密芯片,包括AT88SC0104CA~AT88SC6416CAAT88SC0104C~~25616C,采用独有的8字节密钥加密解密算法,具有协议认证和数据随机密文传送等功能。使用时,通过协议认证并将部分重要数据或程序存放到加密芯片中,极大地提高了产品的安全性。 SHA-256系列加密芯片,包括AT88SA100S、AT88SA10HS、AT88SA102S和ATSHA204,由于采用了SHA-256算法,因而具有更高的安全性。 为了提升您的开发效率,我们开发了完整的开发工具和开发包,包括:编程器、认证读写C源程序和密码密钥设置示例。使用我司产品,您可以大大缩短您的开发时间,并方便存档所有文件;还可以脱开电脑独立编程。 1、SC-RWP3型AT88SCXXXX读写编程器和开发包:1拖8型(9个日本烧录座TOP)编程器,可兼顾量产和调试两种需求。适用于AT88SC0104CA/C~AT88SC1616CA/C~ AT88SC25616CA/C全系列器件,支持SOP、DIP和卡式封装,采用了USB接口和日本烧录座。 2、SC-RWP2A型AT88SCXXXX读写编程器和开发包:用于开发和小规模生产。适用于AT88SC0104CA/C~ AT88SC1616CA/C~ AT88SC25616CA/C 全系列器件,支持SOP、DIP和卡式封装,采用了USB接口和日本烧录座。3、SC-RWP-CRF型AT88SCXXXXCRF读写器和开发包:适用于AT88SC0104CRF~ AT88SC0204CRF~ AT88SC1616CRF~AT88SC6416CRF全系列射频卡。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵向深耕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值