📄 iso7816_4.c
字号:
return( indexMessage );
}
//------------------------------------------------------------------------------
/// Escape ISO7816
//------------------------------------------------------------------------------
void ISO7816_Escape( void )
{
TRACE_DEBUG("For user, if needed\n\r");
}
//------------------------------------------------------------------------------
/// Restart clock ISO7816
//------------------------------------------------------------------------------
void ISO7816_RestartClock( void )
{
TRACE_DEBUG("ISO7816_RestartClock\n\r");
AT91C_BASE_US0->US_BRGR = 13;
}
//------------------------------------------------------------------------------
/// Stop clock ISO7816
//------------------------------------------------------------------------------
void ISO7816_StopClock( void )
{
TRACE_DEBUG("ISO7816_StopClock\n\r");
AT91C_BASE_US0->US_BRGR = 0;
}
//------------------------------------------------------------------------------
/// T0 APDU
//------------------------------------------------------------------------------
void ISO7816_toAPDU( void )
{
TRACE_DEBUG("ISO7816_toAPDU\n\r");
TRACE_DEBUG("Not supported at this time\n\r");
}
//----------------------------------------------------------------------
/// Answer To Reset (ATR)
/// \param pAtr ATR buffer
/// \param pLength Pointer for store the ATR length
//----------------------------------------------------------------------
void ISO7816_Datablock_ATR( unsigned char* pAtr, unsigned char* pLength )
{
unsigned int i;
unsigned int j;
unsigned int y;
*pLength = 0;
// Read ATR TS
ISO7816_GetChar(&pAtr[0]);
// Read ATR T0
ISO7816_GetChar(&pAtr[1]);
y = pAtr[1] & 0xF0;
i = 2;
// Read ATR Ti
while (y) {
if (y & 0x10) { // TA[i]
ISO7816_GetChar(&pAtr[i++]);
}
if (y & 0x20) { // TB[i]
ISO7816_GetChar(&pAtr[i++]);
}
if (y & 0x40) { // TC[i]
ISO7816_GetChar(&pAtr[i++]);
}
if (y & 0x80) { // TD[i]
ISO7816_GetChar(&pAtr[i]);
y = pAtr[i++] & 0xF0;
}
else {
y = 0;
}
}
// Historical Bytes
y = pAtr[1] & 0x0F;
for( j=0; j < y; j++ ) {
ISO7816_GetChar(&pAtr[i++]);
}
TRACE_DEBUG_WP("Length = %d", i);
TRACE_DEBUG_WP("ATR = ");
for (j=0; j < i; j++) {
TRACE_DEBUG_WP("%02x ", pAtr[j]);
}
TRACE_DEBUG_WP("\n\r");
*pLength = i;
}
//----------------------------------------------------------------------
/// Set data rate and clock frequency
/// \param dwClockFrequency ICC clock frequency in KHz.
/// \param dwDataRate ICC data rate in bpd
//----------------------------------------------------------------------
void ISO7816_SetDataRateandClockFrequency( unsigned int dwClockFrequency, unsigned int dwDataRate )
{
unsigned char ClockFrequency;
// Define the baud rate divisor register
// CD = MCK / SCK
// SCK = FIDI x BAUD = 372 x 9600
// BOARD_MCK
// CD = MCK/(FIDI x BAUD) = 48000000 / (372x9600) = 13
AT91C_BASE_US0->US_BRGR = BOARD_MCK / (dwClockFrequency*1000);
ClockFrequency = BOARD_MCK / AT91C_BASE_US0->US_BRGR;
AT91C_BASE_US0->US_FIDI = (ClockFrequency)/dwDataRate;
}
//------------------------------------------------------------------------------
/// Pin status for ISO7816 RESET
/// \return 1 if the Pin RstMC is high; otherwise 0.
//------------------------------------------------------------------------------
unsigned char ISO7816_StatusReset( void )
{
return PIO_Get(&st_pinIso7816RstMC);
}
//------------------------------------------------------------------------------
/// cold reset
//------------------------------------------------------------------------------
void ISO7816_cold_reset( void )
{
volatile unsigned int i;
// tb: wait 400 cycles, 3.58MHz => 80祍 48000000Hz (3840)
for( i=0; i<(120*(BOARD_MCK/1000000)); i++ ) {
}
AT91C_BASE_US0->US_RHR;
AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA | AT91C_US_RSTIT | AT91C_US_RSTNACK;
ISO7816_IccPowerOn();
}
//------------------------------------------------------------------------------
/// Warm reset
//------------------------------------------------------------------------------
void ISO7816_warm_reset( void )
{
volatile unsigned int i;
ISO7816_IccPowerOff();
// tb: wait 400 cycles, 3.58MHz => 80祍 48000000Hz (3840)
for( i=0; i<(120*(BOARD_MCK/1000000)); i++ ) {
}
AT91C_BASE_US0->US_RHR;
AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA | AT91C_US_RSTIT | AT91C_US_RSTNACK;
ISO7816_IccPowerOn();
}
//----------------------------------------------------------------------
/// Decode ATR trace
/// \param pAtr pointer on ATR buffer
//----------------------------------------------------------------------
void ISO7816_Decode_ATR( unsigned char* pAtr )
{
unsigned int i;
unsigned int j;
unsigned int y;
unsigned char offset;
TRACE_INFO_WP("ATR: Answer To Reset:\n\r");
TRACE_INFO_WP("TS = 0x%X Initial caracter ",pAtr[0]);
if( pAtr[0] == 0x3B ) {
TRACE_INFO_WP("Direct Convention\n\r");
}
else {
if( pAtr[0] == 0x3F ) {
TRACE_INFO_WP("Inverse Convention\n\r");
}
else {
TRACE_INFO_WP("BAD Convention\n\r");
}
}
TRACE_INFO_WP("T0 = 0x%X Format caracter\n\r",pAtr[1]);
TRACE_INFO_WP(" Number of historical bytes: K = %d\n\r", pAtr[1]&0x0F);
TRACE_INFO_WP(" Presence further interface byte:\n\r");
if( pAtr[1]&0x80 ) {
TRACE_INFO_WP("TA ");
}
if( pAtr[1]&0x40 ) {
TRACE_INFO_WP("TB ");
}
if( pAtr[1]&0x20 ) {
TRACE_INFO_WP("TC ");
}
if( pAtr[1]&0x10 ) {
TRACE_INFO_WP("TD ");
}
if( pAtr[1] != 0 ) {
TRACE_INFO_WP(" present\n\r");
}
i = 2;
y = pAtr[1] & 0xF0;
// Read ATR Ti
offset = 1;
while (y) {
if (y & 0x10) { // TA[i]
TRACE_INFO_WP("TA[%d] = 0x%X ", offset, pAtr[i]);
if( offset == 1 ) {
TRACE_INFO_WP("FI = %d ", (pAtr[i]>>8));
TRACE_INFO_WP("DI = %d", (pAtr[i]&0x0F));
}
TRACE_INFO_WP("\n\r");
i++;
}
if (y & 0x20) { // TB[i]
TRACE_INFO_WP("TB[%d] = 0x%X\n\r", offset, pAtr[i]);
i++;
}
if (y & 0x40) { // TC[i]
TRACE_INFO_WP("TC[%d] = 0x%X ", offset, pAtr[i]);
if( offset == 1 ) {
TRACE_INFO_WP("Extra Guard Time: N = %d", pAtr[i]);
}
TRACE_INFO_WP("\n\r");
i++;
}
if (y & 0x80) { // TD[i]
TRACE_INFO_WP("TD[%d] = 0x%X\n\r", offset, pAtr[i]);
y = pAtr[i++] & 0xF0;
}
else {
y = 0;
}
offset++;
}
// Historical Bytes
TRACE_INFO_WP("Historical bytes:\n\r");
y = pAtr[1] & 0x0F;
for( j=0; j < y; j++ ) {
TRACE_INFO_WP(" 0x%X", pAtr[i]);
if( (pAtr[i] > 0x21) && (pAtr[i] < 0x7D) ) { // ASCII
TRACE_INFO_WP("(%c) ", pAtr[i]);
}
i++;
}
TRACE_INFO_WP("\n\r");
}
//------------------------------------------------------------------------------
// Initializes a ISO driver
/// \param pPinIso7816RstMC Pin ISO 7816 Rst MC
//------------------------------------------------------------------------------
void ISO7816_Init( const Pin pPinIso7816RstMC )
{
TRACE_DEBUG("ISO_Init\n\r");
// Pin ISO7816 initialize
st_pinIso7816RstMC = pPinIso7816RstMC;
USART_Configure( AT91C_BASE_US0,
AT91C_US_USMODE_ISO7816_0
| AT91C_US_CLKS_CLOCK
| AT91C_US_NBSTOP_1_BIT
| AT91C_US_PAR_EVEN
| AT91C_US_CHRL_8_BITS
| AT91C_US_CKLO
| (3<<24), // MAX_ITERATION
1,
0);
// Configure USART0
AT91C_BASE_PMC->PMC_PCER = ((unsigned int) 1 << AT91C_ID_US0);
// Disable interrupts
AT91C_BASE_US0->US_IDR = (unsigned int) -1;
AT91C_BASE_US0->US_FIDI = 372; // by default
// Define the baud rate divisor register
// CD = MCK / SCK
// SCK = FIDI x BAUD = 372 x 9600
// BOARD_MCK
// CD = MCK/(FIDI x BAUD) = 48000000 / (372x9600) = 13
AT91C_BASE_US0->US_BRGR = BOARD_MCK / (372*9600);
// Write the Timeguard Register
AT91C_BASE_US0->US_TTGR = 5;
USART_SetTransmitterEnabled(AT91C_BASE_US0, 1);
USART_SetReceiverEnabled(AT91C_BASE_US0, 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -