STM32F10x_StdPeriph_Examples/USART/Smartcard/main.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    USART/Smartcard/main.c 
00004   * @author  MCD Application Team
00005   * @version V3.4.0
00006   * @date    10/15/2010
00007   * @brief   Main program body
00008   ******************************************************************************
00009   * @copy
00010   *
00011   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00012   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00013   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00014   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00015   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00016   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00017   *
00018   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
00019   */ 
00020 
00021 /* Includes ------------------------------------------------------------------*/
00022 #include "stm32f10x.h"
00023 #include "platform_config.h"
00024 
00025 /* Private define ------------------------------------------------------------*/
00026 #define T0_PROTOCOL           0x00 /* T0 PROTOCOL */
00027 #define SETUP_LENGHT          20 
00028 #define HIST_LENGHT           20
00029 #define SC_Receive_Timeout    0x4000 /* direction to reader */
00030 
00031 /** @addtogroup STM32F10x_StdPeriph_Examples
00032   * @{
00033   */
00034 
00035 /** @addtogroup USART_Smartcard
00036   * @{
00037   */ 
00038 
00039 /* Private typedef -----------------------------------------------------------*/
00040 /* ATR STRUCTURE - ANSWER TO RESET */
00041 typedef  struct 
00042 {
00043   uint8_t TS; /* Bit Convention */
00044   uint8_t T0; /* High Nibble = N. of setup byte; low nibble = N. of historical byte */
00045   uint8_t T[SETUP_LENGHT]; /* Setup array */
00046   uint8_t H[HIST_LENGHT]; /* Historical array */
00047   uint8_t Tlenght; /* Setup array dimension */
00048   uint8_t Hlenght; /* Historical array dimension */
00049 } SC_ATR;
00050 
00051 typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
00052 
00053 /* Private macro -------------------------------------------------------------*/
00054 /* Private variables ---------------------------------------------------------*/
00055 USART_InitTypeDef USART_InitStructure;
00056 USART_ClockInitTypeDef USART_ClockInitStructure; 
00057 SC_ATR  SC_A2R;
00058 __IO uint32_t index = 0, Counter = 0;
00059 volatile TestStatus ATRDecodeStatus = FAILED;
00060 __IO uint32_t CardInserted = 0, CardProtocol = 1;
00061 
00062 __IO uint8_t DST_Buffer[50]= {
00063                      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00064                      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00065                      0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
00066 
00067 /* Private function prototypes -----------------------------------------------*/
00068 /* Private functions ---------------------------------------------------------*/
00069 void RCC_Configuration(void);
00070 void GPIO_Configuration(void);
00071 void EXTI_Configuration(void);
00072 void NVIC_Configuration(void);
00073 uint8_t SC_decode_Answer2reset(__IO uint8_t *card);
00074 
00075 /**
00076   * @brief   Main program
00077   * @param  None
00078   * @retval None
00079   */
00080 int main(void)
00081 {
00082   /*!< At this stage the microcontroller clock setting is already configured, 
00083        this is done through SystemInit() function which is called from startup
00084        file (startup_stm32f10x_xx.s) before to branch to application main.
00085        To reconfigure the default setting of SystemInit() function, refer to
00086        system_stm32f10x.c file
00087      */     
00088        
00089   /* System Clocks Configuration */
00090   RCC_Configuration();
00091        
00092   /* NVIC configuration */
00093   NVIC_Configuration();
00094 
00095   /* Configure the GPIO ports */
00096   GPIO_Configuration();
00097 
00098   /* Configure the EXTI Controller */
00099   EXTI_Configuration();
00100 
00101 
00102 /* SC_USART configuration ----------------------------------------------------*/
00103   /* SC_USART configured as follow:
00104         - Word Length = 9 Bits
00105         - 0.5 Stop Bit
00106         - Even parity
00107         - BaudRate = 12096 baud
00108         - Hardware flow control disabled (RTS and CTS signals)
00109         - Tx and Rx enabled
00110         - USART Clock enabled
00111         - USART CPOL Low
00112         - USART CPHA on first edge
00113         - USART Last Bit Clock Enabled
00114   */
00115 
00116   /* SC_USART Clock set to 4.5MHz (PCLK1 = 36 MHZ / 8) */
00117   USART_SetPrescaler(SC_USART, 0x04);
00118   /* SC_USART Guard Time set to 2 Bit */
00119   USART_SetGuardTime(SC_USART, 0x2);
00120   
00121   USART_ClockInitStructure.USART_Clock = USART_Clock_Enable;
00122   USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
00123   USART_ClockInitStructure.USART_CPHA = USART_CPHA_1Edge;
00124   USART_ClockInitStructure.USART_LastBit = USART_LastBit_Enable;
00125   USART_ClockInit(SC_USART, &USART_ClockInitStructure);
00126 
00127   USART_InitStructure.USART_BaudRate = 12096;
00128   USART_InitStructure.USART_WordLength = USART_WordLength_9b;
00129   USART_InitStructure.USART_StopBits = USART_StopBits_1_5;
00130   USART_InitStructure.USART_Parity = USART_Parity_Even;
00131   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
00132   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
00133   USART_Init(SC_USART, &USART_InitStructure);  
00134 
00135   /* Enable the SC_USART Parity Error Interrupt */
00136   USART_ITConfig(SC_USART, USART_IT_PE, ENABLE);
00137 
00138   /* Enable SC_USART */
00139   USART_Cmd(SC_USART, ENABLE);
00140 
00141   /* Enable the NACK Transmission */
00142   USART_SmartCardNACKCmd(SC_USART, ENABLE);
00143 
00144   /* Enable the Smartcard Interface */
00145   USART_SmartCardCmd(SC_USART, ENABLE);
00146 
00147   /* Loop while no Smartcard is detected */  
00148   while(CardInserted == 0)
00149   {
00150   }
00151 
00152   /* Read Smartcard ATR response */ 
00153   for(index = 0; index < 40; index++, Counter = 0)
00154   {
00155     while((USART_GetFlagStatus(SC_USART, USART_FLAG_RXNE) == RESET) && (Counter != SC_Receive_Timeout))
00156     {
00157       Counter++;
00158     }
00159 
00160     if(Counter != SC_Receive_Timeout)
00161     {
00162       DST_Buffer[index] = USART_ReceiveData(SC_USART);
00163     }
00164   }
00165 
00166   /* Decode ATR */
00167   CardProtocol = SC_decode_Answer2reset(DST_Buffer);
00168 
00169   /* Test if the inserted card is ISO7816-3 T=0 compatible */
00170   if(CardProtocol == 0)
00171   {
00172     /* Inserted card is ISO7816-3 T=0 compatible */
00173     ATRDecodeStatus = PASSED;
00174   }
00175   else 
00176   { 
00177     /* Inserted Smartcard is not ISO7816-3 T=0 compatible */
00178     ATRDecodeStatus = FAILED;
00179   } 
00180 
00181   while (1)
00182   {   
00183   }
00184 }
00185 
00186 /**
00187   * @brief  Configures the different system clocks.
00188   * @param  None
00189   * @retval None
00190   */
00191 void RCC_Configuration(void)
00192 {  
00193   /* Enable GPIO_3_5V, SC_USART_GPIO_CLK, GPIO_CMDVCC, GPIO_RESET, GPIO_OFF and 
00194      AFIO clocks */
00195   RCC_APB2PeriphClockCmd(RCC_APB2Periph_3_5V | SC_USART_GPIO_CLK | RCC_APB2Periph_RESET | 
00196                          RCC_APB2Periph_CMDVCC | RCC_APB2Periph_OFF | RCC_APB2Periph_AFIO, ENABLE);
00197 
00198   /* Enable SC_USART clocks */
00199   RCC_APB1PeriphClockCmd(SC_USART_CLK, ENABLE);
00200 }
00201 
00202 /**
00203   * @brief  Configures the different GPIO ports.
00204   * @param  None
00205   * @retval None
00206   */
00207 void GPIO_Configuration(void)
00208 {
00209   GPIO_InitTypeDef GPIO_InitStructure;
00210 
00211 #ifdef USE_STM3210C_EVAL
00212   /* Enable the USART3 Pins Software Full Remapping */
00213   GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);
00214 #endif
00215   /* Configure SC_USART CK as alternate function push-pull */
00216   GPIO_InitStructure.GPIO_Pin = SC_USART_ClkPin;
00217   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
00218   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
00219   GPIO_Init(SC_USART_GPIO, &GPIO_InitStructure);
00220 
00221   /* Configure SC_USART Tx as alternate function open-drain */
00222   GPIO_InitStructure.GPIO_Pin = SC_USART_TxPin;
00223   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
00224   GPIO_Init(SC_USART_GPIO, &GPIO_InitStructure);
00225 
00226   /* Configure Smartcard Reset  */
00227   GPIO_InitStructure.GPIO_Pin = SC_RESET;
00228   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
00229   GPIO_Init(GPIO_RESET, &GPIO_InitStructure);
00230 
00231   /* Set RSTIN HIGH */  
00232   GPIO_SetBits(GPIO_RESET, SC_RESET);
00233 
00234   /* Configure Smartcard 3/5V  */
00235   GPIO_InitStructure.GPIO_Pin = SC_3_5V;
00236   GPIO_Init(GPIO_3_5V, &GPIO_InitStructure);
00237 
00238   /* Select 5 V */  
00239   GPIO_SetBits(GPIO_3_5V, SC_3_5V);
00240 
00241   /* Configure Smartcard CMDVCC  */
00242   GPIO_InitStructure.GPIO_Pin = SC_CMDVCC;
00243   GPIO_Init(GPIO_CMDVCC, &GPIO_InitStructure);
00244 
00245   /* Select Smartcard CMDVCC */ 
00246   GPIO_SetBits(GPIO_CMDVCC, SC_CMDVCC);
00247 
00248   /* Select Smartcard OFF */
00249   GPIO_InitStructure.GPIO_Pin = SC_OFF;
00250   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
00251   GPIO_Init(GPIO_OFF, &GPIO_InitStructure);
00252 }
00253 
00254 /**
00255   * @brief  Configures the External Interrupts controller.
00256   * @param  None
00257   * @retval None
00258   */
00259 void EXTI_Configuration(void)
00260 {
00261   EXTI_InitTypeDef EXTI_InitStructure;
00262 
00263   /* Smartcard OFF */
00264   GPIO_EXTILineConfig(SC_PortSource, SC_PinSource);
00265 
00266   EXTI_StructInit(&EXTI_InitStructure);
00267   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
00268   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
00269   EXTI_InitStructure.EXTI_Line = SC_EXTI;
00270   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
00271   EXTI_Init(&EXTI_InitStructure);
00272 
00273   /* Clear SC EXTI Line Pending Bit */
00274   EXTI_ClearITPendingBit(SC_EXTI);
00275 }
00276 
00277 /**
00278   * @brief  Configures the nested vectored interrupt controller.
00279   * @param  None
00280   * @retval None
00281   */
00282 void NVIC_Configuration(void)
00283 {
00284   NVIC_InitTypeDef NVIC_InitStructure;
00285 
00286   /* Configure the NVIC Preemption Priority Bits */
00287   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
00288   /* Clear the SC_EXTI IRQ Pending Bit */
00289   NVIC_ClearPendingIRQ(SC_EXTI_IRQ);
00290 
00291   NVIC_InitStructure.NVIC_IRQChannel = SC_EXTI_IRQ;
00292   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
00293   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
00294   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
00295   NVIC_Init(&NVIC_InitStructure);
00296 
00297   NVIC_InitStructure.NVIC_IRQChannel = SC_USART_IRQn;
00298   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
00299   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
00300   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
00301   NVIC_Init(&NVIC_InitStructure);
00302 }
00303 
00304 /**
00305   * @brief  Decode the Card ATR Response.
00306   * @param  card: pointer to the buffer containing the Card ATR.
00307   * @retval Card protocol
00308   */
00309 uint8_t SC_decode_Answer2reset(__IO uint8_t *card)
00310 {
00311   uint32_t i = 0, flag = 0, buf = 0, protocol = 0;
00312 
00313   SC_A2R.TS = 0;
00314   SC_A2R.T0 = 0;
00315   for (i = 0; i < SETUP_LENGHT; i++)
00316   {
00317     SC_A2R.T[i] = 0;
00318   }
00319   for (i = 0;i < HIST_LENGHT; i++)
00320   {
00321     SC_A2R.H[i] = 0;
00322   }
00323   SC_A2R.Tlenght = 0;
00324   SC_A2R.Hlenght = 0;
00325 
00326   SC_A2R.TS = card[0]; /* INITIAL CHARACTER */
00327   SC_A2R.T0 = card[1]; /* FORMAT CHARACTER */
00328 
00329   SC_A2R.Hlenght = SC_A2R.T0 & 0x0F;
00330 
00331   if((SC_A2R.T0 & 0x80) == 0x80) flag = 1;
00332 
00333   for(i = 0; i < 4; i++)
00334   {
00335     SC_A2R.Tlenght = SC_A2R.Tlenght + (((SC_A2R.T0 & 0xF0) >> (4 + i)) & 0x1);
00336   }
00337 
00338   for(i = 0; i < SC_A2R.Tlenght; i++)
00339   {
00340     SC_A2R.T[i] = card[i + 2];
00341   }
00342 
00343   protocol = SC_A2R.T[SC_A2R.Tlenght - 1] & 0x0F; 
00344 
00345   while(flag) 
00346   {
00347     if ((SC_A2R.T[SC_A2R.Tlenght-1] & 0x80)== 0x80)
00348     {
00349       flag = 1;
00350     }
00351     else
00352     {
00353       flag = 0;
00354     }
00355     buf = SC_A2R.Tlenght;
00356     SC_A2R.Tlenght = 0;
00357 
00358     for(i = 0; i < 4; i++)
00359     {
00360       SC_A2R.Tlenght = SC_A2R.Tlenght + (((SC_A2R.T[buf - 1] & 0xF0) >> (4 + i)) & 0x1);
00361     }
00362     for(i = 0; i < SC_A2R.Tlenght; i++)
00363     {
00364       SC_A2R.T[buf + i] = card[i + 2 + buf];
00365     }
00366     SC_A2R.Tlenght += buf;
00367   }
00368 
00369   for(i = 0;i < SC_A2R.Hlenght; i++)
00370   {
00371     SC_A2R.H[i] = card[i + 2 + SC_A2R.Tlenght];
00372   }
00373   
00374   return ((uint8_t)protocol);
00375 }
00376 
00377 #ifdef  USE_FULL_ASSERT
00378 /**
00379   * @brief  Reports the name of the source file and the source line number
00380   *         where the assert_param error has occurred.
00381   * @param  file: pointer to the source file name
00382   * @param  line: assert_param error line source number
00383   * @retval None
00384   */
00385 void assert_failed(uint8_t* file, uint32_t line)
00386 { 
00387   /* User can add his own implementation to report the file name and line number,
00388      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
00389 
00390   /* Infinite loop */
00391   while (1)
00392   {
00393   }
00394 }
00395 #endif
00396 
00397 /**
00398   * @}
00399   */ 
00400 
00401 /**
00402   * @}
00403   */ 
00404 
00405 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
STM32F10x Standard Peripherals Library: Footer

 

 

 

      For complete documentation on STM32(CORTEX M3) 32-bit Microcontrollers platform visit  www.st.com/STM32