00001 /* ---------------------------------------------------------------------------- */ 00002 /* Atmel Microcontroller Software Support */ 00003 /* SAM Software Package License */ 00004 /* ---------------------------------------------------------------------------- */ 00005 /* Copyright (c) 2015, Atmel Corporation */ 00006 /* */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without */ 00010 /* modification, are permitted provided that the following condition is met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, */ 00013 /* this list of conditions and the disclaimer below. */ 00014 /* */ 00015 /* Atmel's name may not be used to endorse or promote products derived from */ 00016 /* this software without specific prior written permission. */ 00017 /* */ 00018 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ 00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ 00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ 00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ 00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ 00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ 00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00028 /* ---------------------------------------------------------------------------- */ 00029 00030 /** 00031 * \page usart_7816 USART ISO7816 Example 00032 * 00033 * \section Purpose 00034 * This example sends ISO 7816 commands to a smartcard connected to 00035 * SAMV7/E7 Microcontrollers. 00036 * 00037 * \section Requirements 00038 * This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board. 00039 * Please connect the smartcard contacts with following pins which could be 00040 * easily wired from the board. 00041 * - <b>SAMV71 Xplained -- SMARTCARD</b> 00042 * - PB02(PIN6 of EXT1) -- RST(C2) 00043 * - TXD0(PB01,PIN14 of EXT1 ) -- I/O(C7) 00044 * - SCK0(PB13,PIN5 of J504) -- CLK(C3) 00045 * - VCC -- VCC(C1) 00046 * - GND -- GND(C5) 00047 * \section Description 00048 * The iso7816 software provide in this examples is use to transform APDU 00049 * commands to TPDU commands for the smart card. 00050 * The iso7816 provide here is for the protocol T=0 only. 00051 * The send and the receive of a character is made under polling. 00052 * In the file ISO7816_Init is defined all pins of the card. User must have to 00053 * change this pins according to his environment. 00054 * The driver is compliant with CASE 1, 2, 3 of the ISO7816-4 specification. 00055 * 00056 * \section Usage 00057 * -# Build the program and download it inside the board. 00058 * Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf 00059 * -# On the computer, open and configure a terminal application 00060 * (e.g. HyperTerminal on Microsoft Windows) with these settings: 00061 * - 115200 baud rate 00062 * - 8 bits of data 00063 * - No parity 00064 * - 1 stop bit 00065 * - No flow control 00066 * -# Connect the card reader to SAM V71 Xplained Ultra board: 00067 * <table border="1" cellpadding="2" cellspacing="0"> 00068 * <tr><td>C1: Vcc - 7816_3V5V</td> <td> C5: Gnd</td> <td> C4: RFU</td></tr> 00069 * <tr><td>C2: Reset - 7816_RST</td> <td> C6: Vpp</td> <td> C8: RFU</td></tr> 00070 * <tr><td>C3: Clock - 7816_CLK</td> <td> C7: I/O - 7816_IO</td> </tr> 00071 * </table> 00072 * If necessary,another pin must be connected on the card reader for detecting the 00073 * insertion and removal: 7816_IRQ. 00074 * -# Start the application. The following traces shall appear on the terminal: 00075 * \code 00076 * -- USART ISO7816 Example xxx -- 00077 * -- SAMxxxxx-xx 00078 * -- Compiled: xxx xx xxxx xx:xx:xx -- 00079 * Display the ATR 00080 * \endcode 00081 * 00082 * \section References 00083 * - usart_iso7816/main.c 00084 * - iso7816_4.c 00085 * - usart.c 00086 * - pio.h 00087 * - usart.h 00088 * 00089 */ 00090 00091 /** \file 00092 * 00093 * This file contains all the specific code for the usart_iso7816 example. 00094 * 00095 */ 00096 00097 00098 /*------------------------------------------------------------------------------ 00099 * Headers 00100 *------------------------------------------------------------------------------*/ 00101 00102 #include "board.h" 00103 00104 #include <string.h> 00105 00106 /*------------------------------------------------------------------------------ 00107 * Internal definitions 00108 *------------------------------------------------------------------------------*/ 00109 00110 /** Maximum ucSize in bytes of the smart card answer to a command.*/ 00111 #define MAX_ANSWER_SIZE 10 00112 00113 /** Maximum ATR ucSize in bytes.*/ 00114 #define MAX_ATR_SIZE 55 00115 00116 /** Register base for USART */ 00117 #define USART USART0 00118 #define ID_USART ID_USART0 00119 00120 /*------------------------------------------------------------------------------ 00121 * Internal variables 00122 *------------------------------------------------------------------------------*/ 00123 00124 /** Test command #1.*/ 00125 static const uint8_t testCommand1[] = {0x00, 0x10, 0x00, 0x00}; 00126 /** Test command #2.*/ 00127 static const uint8_t testCommand2[] = {0x00, 0x20, 0x00, 0x00, 0x02}; 00128 /** Test command #3.*/ 00129 static const uint8_t testCommand3[] = {0x00, 0x30, 0x00, 0x00, 0x02, 0x0A, 0x0B}; 00130 /** ISO7816 pins */ 00131 static const Pin pinsISO7816[] = {PINS_ISO7816}; 00132 /** ISO7816 RST pin */ 00133 static const Pin pinIso7816RstMC = PIN_ISO7816_RSTMC; 00134 00135 /*------------------------------------------------------------------------------ 00136 * Internal functions 00137 *------------------------------------------------------------------------------*/ 00138 00139 /*------------------------------------------------------------------------------ 00140 * Optional smartcard detection 00141 *------------------------------------------------------------------------------*/ 00142 00143 #ifdef SMARTCARD_CONNECT_PIN 00144 00145 /** Smartcard detection pin.*/ 00146 static const Pin pinSmartCard = SMARTCARD_CONNECT_PIN; 00147 00148 /** 00149 * PIO interrupt service routine. Checks if the smartcard has been connected 00150 * or disconnected. 00151 */ 00152 static void ISR_PioSmartCard(const Pin *pPin) 00153 { 00154 /* Check all pending interrupts */ 00155 if ((pinSmartCard.pio->PIO_ISR & pinSmartCard.mask) != 0) { 00156 /* Check current level on pin */ 00157 if (PIO_Get(&pinSmartCard ) == 0) 00158 printf("-I- Smartcard inserted\n\r"); 00159 else 00160 printf("-I- Smartcard removed\n\r"); 00161 } 00162 } 00163 00164 /** 00165 * Configures the smartcard detection pin to trigger an interrupt. 00166 */ 00167 static void ConfigureCardDetection(void) 00168 { 00169 PIO_Configure(&pinSmartCard, 1); 00170 PIO_ConfigureIt(&pinSmartCard, ISR_PioSmartCard); 00171 PIO_EnableIt(&pinSmartCard); 00172 } 00173 00174 #else 00175 00176 /** 00177 * Dummy implementation. 00178 */ 00179 static void ConfigureCardDetection(void) 00180 { 00181 printf("-I- Smartcard detection not supported.\n\r"); 00182 } 00183 00184 #endif 00185 00186 /** 00187 * Displays a menu which enables the user to send several commands to the 00188 * smartcard and check its answers. 00189 */ 00190 static void SendReceiveCommands(void) 00191 { 00192 uint8_t pMessage[MAX_ANSWER_SIZE]; 00193 uint8_t ucSize; 00194 uint8_t ucKey; 00195 uint8_t command; 00196 uint8_t i; 00197 00198 /* Clear message buffer */ 00199 memset(pMessage, 0, sizeof(pMessage)); 00200 00201 /* Display menu */ 00202 printf("-I- The following three commands can be sent:\n\r"); 00203 printf(" 1. "); 00204 for (i = 0; i < sizeof(testCommand1); i++) 00205 printf( "0x%X ", testCommand1[i]); 00206 printf("\n\r 2. "); 00207 00208 for (i = 0; i < sizeof(testCommand2); i++) 00209 printf("0x%X ", testCommand2[i]); 00210 printf("\n\r 3. "); 00211 00212 for (i = 0; i < sizeof(testCommand3); i++) 00213 printf("0x%X ", testCommand3[i]); 00214 printf("\n\r" ); 00215 00216 /* Get user input */ 00217 ucKey = 0; 00218 while (ucKey != 'q') { 00219 printf("\r "); 00220 printf("\rChoice ? (q to quit): "); 00221 ucKey = DBG_GetChar(); 00222 printf("%c", ucKey); 00223 command = ucKey - '0'; 00224 00225 /* Check user input */ 00226 ucSize = 0; 00227 if (command == 1) { 00228 printf("\n\r-I- Sending command "); 00229 for (i = 0; i < sizeof( testCommand1 ); i++) 00230 printf( "0x%02X ", testCommand1[i]); 00231 printf("...\n\r"); 00232 ucSize = ISO7816_XfrBlockTPDU_T0(testCommand1, pMessage, 00233 sizeof( testCommand1)); 00234 } else { 00235 if (command == 2) { 00236 printf("\n\r-I- Sending command "); 00237 for (i = 0; i < sizeof(testCommand2); i++) 00238 printf("0x%02X ", testCommand2[i]); 00239 printf("...\n\r"); 00240 ucSize = ISO7816_XfrBlockTPDU_T0(testCommand2, pMessage, 00241 sizeof( testCommand2)); 00242 } else { 00243 if (command == 3) { 00244 printf("\n\r-I- Sending command "); 00245 for (i = 0; i < sizeof(testCommand3); i++) 00246 printf("0x%02X ", testCommand3[i]); 00247 printf("...\n\r"); 00248 ucSize = ISO7816_XfrBlockTPDU_T0(testCommand3, pMessage, 00249 sizeof(testCommand3)); 00250 } 00251 } 00252 } 00253 00254 /* Output smartcard answer */ 00255 if (ucSize > 0) { 00256 printf("\n\rAnswer: "); 00257 for (i = 0; i < ucSize; i++) 00258 printf("0x%02X ", pMessage[i]); 00259 printf("\n\r"); 00260 } 00261 } 00262 printf("Quitting ...\n\r"); 00263 } 00264 00265 /*------------------------------------------------------------------------------ 00266 * Exported functions 00267 *------------------------------------------------------------------------------*/ 00268 00269 /** 00270 * Initializes the DBGU and ISO7816 driver, and starts some tests. 00271 * \return Unused (ANSI-C compatibility) 00272 */ 00273 extern int main( void ) 00274 { 00275 uint8_t pAtr[MAX_ATR_SIZE]; 00276 uint8_t ucSize; 00277 00278 /* Disable watchdog*/ 00279 WDT_Disable(WDT); 00280 00281 SCB_EnableICache(); 00282 SCB_EnableDCache(); 00283 00284 /* Initialize Atr buffer */ 00285 memset(pAtr, 0, sizeof(pAtr)); 00286 00287 printf("-- USART ISO7816 Example %s --\n\r", SOFTPACK_VERSION); 00288 printf("-- %s\n\r", BOARD_NAME); 00289 printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); 00290 00291 /* Configure IT on Smart Card */ 00292 ConfigureCardDetection(); 00293 00294 /* Configure ISO7816 driver */ 00295 PIO_Configure(pinsISO7816, PIO_LISTSIZE(pinsISO7816)); 00296 00297 ISO7816_Init(USART, ID_USART, pinIso7816RstMC); 00298 00299 /* Read ATR */ 00300 ISO7816_warm_reset(); 00301 00302 ISO7816_Datablock_ATR(pAtr, &ucSize); 00303 00304 /* Decode ATR */ 00305 ISO7816_Decode_ATR(pAtr); 00306 00307 /* Allow user to send some commands */ 00308 SendReceiveCommands(); 00309 00310 return 0; 00311 } 00312