⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tda8007.c

📁 单片机读写TDA8007
💻 C
📖 第 1 页 / 共 3 页
字号:
	          // Start timer
	          dssc_writeregister(TOC,0x65);
	        }
	      }
	    }
	
	    // Read Timer status
	    if (USRval & USR_TOL3_MASK)
	    {
#if DEBUG > 0
	      printf("Character waiting timeout\n");
#endif
	      dssc_powerdown();
	      return ERR_POWERUP_ATR_TIMEOUT;
	    }
	    if ((mode == POWERUP_EMV) && (USRval & USR_TOL1_MASK))
	    {
	      // If 192 ETU rollover, increment total count
	      etucount++;
	      // If we exceed 192 * 100 or 19200 etu, we fail as the whole ATR has not come
	      if (etucount > 100)
	      {
#if DEBUG > 0
	        printf("ATR waiting timeout\n");
#endif
	        dssc_powerdown();
	        return ERR_POWERUP_ATR_TIMEOUT;
	      }
	    }
	  }
	
	  // If we are in T=1 protocol, we get a LRC (xor checksum) at the end
	  if (T==1)
	  {
	    if (check != 0)
	    {
#if DEBUG > 0
	      printf("LRC failed: %02bx\n",check);
#endif
	      dssc_powerdown();
	      return ERR_POWERUP_ATR_CRC_FAILURE;
	    }
	  }
	
	  // Set ATR length for the ATR received
	  ATRLength[currentSlot] = index;
	  // Set T protocol mode
	  TMode[currentSlot] = T;
	
	  // Set the 8007 UCR1.PROT mode according to T value
	  val = dssc_readregister(UCR1);
	  if (T == 0)
	    dssc_writeregister(UCR1,val & ~UCR1_PROT_MASK);
	  else
	    dssc_writeregister(UCR1,val | UCR1_PROT_MASK);
	
	  // Set extra guard time if present in TC1, else use guard time of 0
	  if (lastATR[currentSlot].TC[1] != -1)
	    dssc_writeregister(GTR,lastATR[currentSlot].TC[1]);
	  else
	    dssc_writeregister(GTR,0x00);
	
	  // Set the EDC type (either LRC or CRC)
	  // FIXME: In EMV mode, if TC3 comes by and is not zero, we should bail out!!!!
	  EDCtype[currentSlot] = EDC_TYPE_LRC;  // Default to LRC if not told otherwise.
	  for (i = 3;i < 8;i++)
	  {
	    if (lastATR[currentSlot].TC[3] != -1)
	    { 
	      EDCtype[currentSlot] = (lastATR[currentSlot].TC[3] & 0x01)?EDC_TYPE_CRC:EDC_TYPE_LRC;
	    }
	  }
	
	  // Set IFSC (max segment size of card) if TA3 present (only used for T=1 protocol)
	  // FIXME: Using TA3 this way may only be correct for EMV, not ISO7816
	  if (lastATR[currentSlot].TA[3] != -1)
	  {
	    val = lastATR[currentSlot].TA[3];
	    if ((val < 0x10) || (val == 0xFF))
	    {
	      // FIXME: Should we power down here?  It is an EMV violation
	      dssc_powerdown();
	      return ERR_POWERUP_ATR_INVALID;
	    }
	    IFSC[currentSlot] = val;
	  }
	  else
	    IFSC[currentSlot] = 0x20;  // Default for IFSC is 0x20 according to EMV 4.1 8.3.3.9 and ISO7816 9.5.2.1
	
	  // Set WWT if present in TC2 (only used for T=0), ISO7816 8.2
	  if (lastATR[currentSlot].TC[2] != -1)
	    WWT[currentSlot] = lastATR[currentSlot].TC[2] * 960;
	  else
	    WWT[currentSlot] = 960 * 10;
	
#if DEBUG > 1
	  printf("WWT: %ld\n",WWT[currentSlot]);
#endif
	
	  if (mode == POWERUP_EMV)
	  {
	    if (lastATR[currentSlot].TB[3] == -1)
	    {
	      // FIXME: Should we power down here?  It is an EMV violation
	      dssc_powerdown();
	      return ERR_POWERUP_ATR_INVALID;
	    }
	    else
	    {
	      val = lastATR[currentSlot].TB[i] & 0x0F;
	      // Fail if CWI is out of range
	      if (val > 5)
	      {
	        // FIXME: Should we power down here?  It is an EMV violation
	        dssc_powerdown();
	        return ERR_POWERUP_ATR_INVALID;
	      }
	      val = (lastATR[currentSlot].TB[i] & 0x0F) >> 4;
	      // Fail if BWI is out of range
	      if (val > 4)
	      {
	        // FIXME: Should we power down here?  It is an EMV violation
	        dssc_powerdown();
	        return ERR_POWERUP_ATR_INVALID;
	      }
	    }
	  }
	
	  // Set default values for CWT and BWT, ISO7816 9.5.3.1 and 9.5.3.2
	  CWT[currentSlot] = 11 + (1 << 13);
	  BWT[currentSlot] = 11 + (1 << 4) * 960;
	  for (i = 3;i < 8;i++)
	  {
	    // Set CWT and BWT if present in TBi
	    // FIXME: Check this algorithm again!
	    if (lastATR[currentSlot].TB[i] != -1)
	    {
	      val = lastATR[currentSlot].TB[i] & 0x0F;
	      CWT[currentSlot] = 11 + (1 << val);
	      val = (lastATR[currentSlot].TB[i] & 0x0F) >> 4;
	      if (val > 9)
	      {
	        // FIXME: Should we power down here?  It is an ISO7816 violation.
	        dssc_powerdown();
	        return ERR_POWERUP_ATR_INVALID;
	      }
	      BWT[currentSlot] = 11 + (1 << val) * 960;
	      break;
	    }
	  }
#if DEBUG > 1
	  printf("CWT: %ld\n",CWT[currentSlot]);
	  printf("BWT: %ld\n",BWT[currentSlot]);
#endif
	
	  return 0;
}

int16_t dssc_powerdown()
{
  uint8_t val;

  // Power down the card
  val = dssc_readregister(PCR);
  dssc_writeregister(PCR,val & ~PCR_START_MASK);

  return 0;
}

int16_t dssc_selectcard(uint8_t slot)
{
	  uint8_t val;
	
	  val = dssc_readregister(CSR);
	  switch (slot) 
	  {
	    case 1:
	      // Select appropriate smartcard and clear other card selects
	      dssc_writeregister(CSR,val & ~(CSR_SC3_MASK|CSR_SC2_MASK) | CSR_SC1_MASK);
	      break;
	    case 2:
	      // Select appropriate smartcard and clear other card selects
	      dssc_writeregister(CSR,val & ~(CSR_SC3_MASK|CSR_SC1_MASK) | CSR_SC2_MASK);
	      break;
	    case 3:
	      // Select appropriate smartcard and clear other card selects
	      dssc_writeregister(CSR,val & ~(CSR_SC2_MASK|CSR_SC1_MASK) | CSR_SC3_MASK);
	      break;
	    default:
	      return ERR_INVALID_SLOT;
	  }
	
	  // Set global slot identifier value
	  currentSlot = slot-1;
	
	if ( DEBUG > 2)
	  	printf("card selected: %d\n", currentSlot);
	
	  return 0;
}

int16_t dssc_checkpresence(uint8_t slot)
{
  uint8_t val;

  val = dssc_readregister(MSR);

  switch(slot)
  {
    case 1:
      if (val & MSR_PR1_MASK) return 1;
      break;
    case 2:
      if (val & MSR_PR2_MASK) return 1;
      break;
    default:
      return ERR_INVALID_SLOT;
      break;
  }
  return 0;
}

/*
Library initialization
*/
int16_t dssc_init()
{
	  uint8_t val;
	
	  // Reset the UART
	  dssc_writeregister(CSR,0x00);
	
	  // Select smart card slot 1
	  dssc_writeregister(CSR,CSR_SC1_MASK);
	
	  // Make sure card is powered down
	  val = dssc_readregister(PCR);
	  dssc_writeregister(PCR,val & ~PCR_START_MASK);
	
	  // Select smart card slot 2
	  dssc_writeregister(CSR,CSR_SC2_MASK);
	
	  // Make sure card is powered down
	  val = dssc_readregister(PCR);
	  dssc_writeregister(PCR,val & ~PCR_START_MASK);
	
	  // Select smart card slot 3
	  dssc_writeregister(CSR,CSR_SC3_MASK);
	
	  // Deselect all cards
	  dssc_writeregister(CSR,0x00);
	
	  return 0;
}

int16_t dssc_getATRbuffer(uint8_t *buff, int16_t length)
{
	  memcpy(buff,workingBuffer,(length<ATRLength[currentSlot])?length:ATRLength[currentSlot]);
	  return ATRLength[currentSlot];
}

void dssc_getATR(struct ATR *userATR)
{
  	memcpy(userATR,&lastATR[currentSlot],sizeof(struct ATR));
}

#pragma REGPARMS
uint8_t dssc_readregister(uint8_t address)
{
	idata uint8_t rAddress, toReturn;
#ifdef DEBUG_CRED
  idata uint8_t count = 0;
#endif
	rAddress = address;

//ds5250 DMOS |= 0x01;
  	RPCTL |= 0x20;    //the MOVX route access the expend port(P0,P2);
//	P3 &= 0xEF;		// Happy CS for 8007 on Ramit Board
	P1 &= 0xEF;        // Happy CS for 8007 on Eval Refrence Design
  	switch (rAddress)
  	{
    	case URR:
      // If reading URR, check the CRED bit in MSR so that
      // we don't overrun the 8007.  See MSR.CRED bit description on page
      // 18 of 8007 spec.
#ifdef DEBUG_CRED
      	while (!(BASE_ADDRESS[MSR] & MSR_CRED_MASK))
      	{
        // If card de-powers exit with zero return value.
        	if ((BASE_ADDRESS[PCR] & 0x01) == 0)//if the card is deactivation,then out.
        	{
			//ds5250 DMOS &= 0xFE;
			//	P3 |= 0x10;		// Happy CS for 8007 on Ramit Board
				P1 |= 0x10;        // Happy CS for 8007 on Eval Refrence Design

  				RPCTL &= 0xDF;
        		return 0;
        	}

       	 	count++;
        	if (count == 30000)
        	{
		          printf("CRED read locked up on: %02bx\n",rAddress);
		          printf("PCR: %02bx\n",BASE_ADDRESS[PCR]);
		          printf("HSR: %02bx\n",BASE_ADDRESS[HSR]);
		          count = 0;
        	}
      	}
#else
      	while (!(BASE_ADDRESS[MSR] & MSR_CRED_MASK))
      	{
        // If card de-powers exit with zero return value.
	        if ((BASE_ADDRESS[PCR] & 0x01) == 0)// there is possible to become permanent cycle run
	        {
	//ds5250 DMOS &= 0xFE;
	//	P3 |= 0x10;		// Happy CS for 8007 on Ramit Board
				P1 |= 0x10;        // Happy CS for 8007 on Eval Refrence Design
	
	          	RPCTL &= 0xDF;
	          	return 0;
	        }
	    }
#endif
	      break;
	      default:
	      break;
  }

 	toReturn = BASE_ADDRESS[rAddress];
//ds5250 DMOS &= 0xFE;
//	P3 |= 0x10;		// Happy CS for 8007 on Ramit Board
	P1 |= 0x10;        // Happy CS for 8007 on Eval Refrence Design

  	RPCTL &= 0xDF;
  	return toReturn;

}

void dssc_writeregister(uint8_t address,uint8_t value)
{
	idata uint8_t rAddress, rValue;
#ifdef DEBUG_CRED
	idata int count = 0;
#endif
	rAddress = address;
	rValue = value;
	
	//ds5250 DMOS |= 0x01;
	  RPCTL |= 0x20;
	//	P3 &= 0xEF;		// Happy CS for 8007 on Ramit Board
	P1 &= 0xEF;        // Happy CS for 8007 on Eval Refrence Design	p1.5
	  switch (rAddress)
	  {
	    case TOC:
	    case UTR:
	      // If writing TOC or UTR, check the CRED bit in MSR so that
	      // we don't overrun the 8007.  See MSR.CRED bit description on page
	      // 18 of 8007 spec.
#ifdef DEBUG_CRED
	      while (!(BASE_ADDRESS[MSR] & MSR_CRED_MASK))
	      {
	        // If card de-powers exit with zero return value.
	        if ((BASE_ADDRESS[PCR] & 0x01) == 0)
	        {
	//ds5250 DMOS &= 0xFE;
	//	P3 |= 0x10;		// Happy CS for 8007 on Ramit Board
				P1 |= 0x10;        // Happy CS for 8007 on Eval Refrence Design
	
				RPCTL &= 0xDF;
	          	return;
	        }
	        count++;
	        if (count == 30000)
	        {
	          printf("CRED write locked up on: %02bx\n",rAddress);
	          printf("PCR: %02bx\n",BASE_ADDRESS[PCR]);
	          printf("HSR: %02bx\n",BASE_ADDRESS[HSR]);
	          count = 0;
	        }
	      }
#else
	     while (!(BASE_ADDRESS[MSR] & MSR_CRED_MASK));
#endif
	      break;
	      default:
	      break;
	  }
	  BASE_ADDRESS[rAddress] = rValue;
	
	//ds5250 DMOS &= 0xFE;
	//	P3 |= 0x10;		// Happy CS for 8007 on Ramit Board
		P1 |= 0x10;        // Happy CS for 8007 on Eval Refrence Design
	
	  RPCTL &= 0xDF;
}
/*
uint8_t Card_iso_out()
{
	uint8_t	Ret[2];
//	DWORD dRet;
//	WORD wRet;
	uint8_t	ins,count,Chr,Len;

	CurTC1=TC1[ChannelNo];
	CurCardTS=(CardTS>>ChannelNo)&0x1;
//	if(CurCardTS)
//		for(i=0;i<5;i++)
//			data_buf[2+i]=ChangeTo3F(data_buf[2+i]);
	ins=data_buf[3];
	*(WORD*)Ret=SendStr(5,&data_buf[2]);
	if(Ret[0])
		return 2;

	Len=data_buf[6]+3;
	count=3;
	for(;;)
	{
		if(ChannelNo)
			*(WORD*)Ret=ReceByteB();
		else
			*(WORD*)Ret=ReceByteA();
//		*(WORD*)Ret=ReceByte();
		if(Ret[0])
			return 2;
		Chr=Ret[1];
//		if(CurCardTS)
//			Chr=ChangeTo3F(Chr);
		if(Chr==ins)
		{
			while(count<Len)
			{
				if(ChannelNo)
					*(WORD*)Ret=ReceByteB();
				else
					*(WORD*)Ret=ReceByteA();
//				*(WORD*)Ret=ReceByte();
				if(Ret[0])
					return 2;
				data_buf[count++]=Ret[1];
			}
			continue;
		}
		if(Chr==~ins)
		{
			if(ChannelNo)
				*(WORD*)Ret=ReceByteB();
			else
				*(WORD*)Ret=ReceByteA();
//			*(WORD*)Ret=ReceByte();
			if(Ret[0])
				return 2;
			data_buf[count++]=Ret[1];
			continue;
		}
		if(Chr==0x60)
			continue;
		if(((Chr&0xf0)==0x60)||((Chr&0xf0)==0x90))
		{
			if(ChannelNo)
				*(WORD*)Ret=ReceByteB();
			else
				*(WORD*)Ret=ReceByteA();
//			*(WORD*)Ret=ReceByte();
			data_buf[Len]=Chr;
			if(Ret[0])
				return 2;
//			if(CurCardTS)
//				data_buf[Len+1]=ChangeTo3F(Ret[1]);
//			else
				data_buf[Len+1]=Ret[1];
			data_buf[2]=Len-1;
			break;
		}
	}

//	if(CurCardTS)
//		for(i=0;i<count-3;i++)
//			data_buf[3+i]=ChangeTo3F(data_buf[3+i]);

	return 0;

}

uint8_t	Card_iso_in()
{
	uint8_t	Ret[2];
	//WORD	wRet;
	//DWORD	dRet;
	uint8_t	ins,count,Chr;

	CurTC1=TC1[ChannelNo];
	CurCardTS=(CardTS>>ChannelNo)&0x1;
//	if(CurCardTS)
//		for(i=0;i<5+data_buf[6];i++)
//			data_buf[2+i]=ChangeTo3F(data_buf[2+i]);
	ins=data_buf[3];
	*(WORD*)Ret=SendStr(5,&data_buf[2]);
	if(Ret[0])
		return 2;
	count=0;
	for(;;)
	{
		if(ChannelNo)
			*(WORD*)Ret=ReceByteB();
		else
			*(WORD*)Ret=ReceByteA();
//		*(WORD*)Ret=ReceByte();
		if(Ret[0])
			return 2;
		Chr=Ret[1];
// 		if(CurCardTS)
//			Chr=ChangeTo3F(Chr);
		if(Chr==ins)
		{
			DelayETU(16);
			*(WORD*)Ret=SendStr(data_buf[6]-count,&data_buf[7+count]);
			if(Ret[0])
				return 2;
			continue;
		}
		if(Chr==~ins)
		{
			DelayETU(16);
			if(ChannelNo)
			{
				if(SendByteB(data_buf[7+count++]))
					return 2;
			}
			else
			{
				if(SendByteA(data_buf[7+count++]))
					return 2;
			}
//			if(SendByte(data_buf[7+count++]))
//				return 2;
			continue;
		}
		if(Chr==0x60)
			continue;
		if(((Chr&0xf0)==0x60)||((Chr&0xf0)==0x90))
		{
			if(ChannelNo)
				*(WORD*)Ret=ReceByteB();
			else
				*(WORD*)Ret=ReceByteA();
//			*(WORD*)Ret=ReceByte();
			data_buf[3]=Chr;
			if(Ret[0])
				return 2;
//			if(CurCardTS)
//				data_buf[4]=ChangeTo3F(Ret[1]);
//			else
				data_buf[4]=Ret[1];
			data_buf[2]=2;
			break;
		}
	}
	return 0;
}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -