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

📄 iso7816_4.c

📁 AT91SAM7S256-USB-CDC for IAR5
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
void ISO7816_Escape( void )
{
    trace_LOG(trace_DEBUG, "For user, if needed\n\r");
}

//------------------------------------------------------------------------------
/// Restart clock ISO7816
//------------------------------------------------------------------------------
void ISO7816_RestartClock( void )
{
    trace_LOG(trace_DEBUG, "ISO7816_RestartClock\n\r");
    AT91C_BASE_US0->US_BRGR = 13;
}

//------------------------------------------------------------------------------
/// Stop clock ISO7816
//------------------------------------------------------------------------------
void ISO7816_StopClock( void )
{
    trace_LOG(trace_DEBUG, "ISO7816_StopClock\n\r");
    AT91C_BASE_US0->US_BRGR = 0;
}

//------------------------------------------------------------------------------
/// T0 APDU
//------------------------------------------------------------------------------
void ISO7816_toAPDU( void )
{
    trace_LOG(trace_DEBUG, "ISO7816_toAPDU\n\r");
    trace_LOG(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_LOG(trace_DEBUG, "Length = %d", i);
    trace_LOG(trace_DEBUG, "ATR = ");
#ifdef trace_DEBUG
    for (j=0; j < i; j++) {
        trace_LOG(trace_DEBUG, "%02x ", pAtr[j]);
    }
#endif

    trace_LOG(trace_DEBUG, "\n\r");

    *pLength = i;

}

//----------------------------------------------------------------------
/// Set data rate and clock frequency
//----------------------------------------------------------------------
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
//------------------------------------------------------------------------------
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            ATR buffer
//----------------------------------------------------------------------
void ISO7816_Decode_ATR( unsigned char* pAtr )
{
    unsigned int i;
    unsigned int j;
    unsigned int y;
    unsigned char offset;

    trace_LOG(trace_INFO, "ATR: Answer To Reset:\n\r");
    trace_LOG(trace_INFO, "TS = 0x%X Initial caracter ",pAtr[0]);
    if( pAtr[0] == 0x3B ) {

        trace_LOG(trace_INFO, "Direct Convention\n\r");
    }
    else {
        if( pAtr[0] == 0x3F ) {

            trace_LOG(trace_INFO, "Inverse Convention\n\r");
        }
        else {
            trace_LOG(trace_INFO, "BAD Convention\n\r");
        }
    }

    trace_LOG(trace_INFO, "T0 = 0x%X Format caracter\n\r",pAtr[1]);
    trace_LOG(trace_INFO, "    Number of historical bytes: K = %d\n\r", pAtr[1]&0x0F);
    trace_LOG(trace_INFO, "    Presence further interface byte:\n\r");
    if( pAtr[1]&0x80 ) {
        trace_LOG(trace_INFO, "TA ");
    }
    if( pAtr[1]&0x40 ) {
        trace_LOG(trace_INFO, "TB ");
    }
    if( pAtr[1]&0x20 ) {
        trace_LOG(trace_INFO, "TC ");
    }
    if( pAtr[1]&0x10 ) {
        trace_LOG(trace_INFO, "TD ");
    }
    if( pAtr[1] != 0 ) {
        trace_LOG(trace_INFO, " present\n\r");
    }

    i = 2;
    y = pAtr[1] & 0xF0;

    // Read ATR Ti
    offset = 1;
    while (y) {

        if (y & 0x10) {  // TA[i]
            trace_LOG(trace_INFO, "TA[%d] = 0x%X ", offset, pAtr[i]);
            if( offset == 1 ) {
                trace_LOG(trace_INFO, "FI = %d ", (pAtr[i]>>8));
                trace_LOG(trace_INFO, "DI = %d", (pAtr[i]&0x0F));
            }
            trace_LOG(trace_INFO, "\n\r");
            i++;
        }
        if (y & 0x20) {  // TB[i]
            trace_LOG(trace_INFO, "TB[%d] = 0x%X\n\r", offset, pAtr[i]);
            i++;
        }
        if (y & 0x40) {  // TC[i]
            trace_LOG(trace_INFO, "TC[%d] = 0x%X ", offset, pAtr[i]);
            if( offset == 1 ) {
                trace_LOG(trace_INFO, "Extra Guard Time: N = %d", pAtr[i]);
            }
            trace_LOG(trace_INFO, "\n\r");
            i++;
        }
        if (y & 0x80) {  // TD[i]
            trace_LOG(trace_INFO, "TD[%d] = 0x%X\n\r", offset, pAtr[i]);
            y =  pAtr[i++] & 0xF0;
        }
        else {
            y = 0;
        }
        offset++;
    }

    // Historical Bytes
    trace_LOG(trace_INFO, "Historical bytes:\n\r");
    y = pAtr[1] & 0x0F;
    for( j=0; j < y; j++ ) {

        trace_LOG(trace_INFO, " 0x%X", pAtr[i]);
        if( (pAtr[i] > 0x21) && (pAtr[i] < 0x7D) ) {  // ASCII
            trace_LOG(trace_INFO, "(%c) ", pAtr[i]);
        }
        i++;
    }
    trace_LOG(trace_INFO, "\n\r");

}

//------------------------------------------------------------------------------
//  Initializes a ISO driver
/// \param pPinIso7816Usart0           Pin ISO 7816 Usart
/// \param pPinIso7816RstMC            Pin ISO 7816 Rst MC
/// \param pPinIso7816McClk            Pin ISO 7816 Mc Clock
//------------------------------------------------------------------------------
void ISO7816_Init( const Pin pPinIso7816RstMC )
{
    trace_LOG(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 + -