Obsługa kart chipowych Smart Card
Listing 2. Definicja funkcji SC_DetectPinConfig() inicjalizującej wyprowadzenie wykrywające obecność karty w gnieździe
void SC_DetectPinConfig(void) { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Właczenie taktowania portu E oraz funkcji alternatywnych */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); /* Konfiguracja PE14 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); /* Konfiguracja przerwania zewnętrzenego */ GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource14); EXTI_ClearITPendingBit(EXTI_Line14); EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_Line = EXTI_Line14; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /* Konfiguracja NVIC */ NVIC_ClearPendingIRQ(EXTI15_10_IRQn); NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
Na początku mikrokontroler pozostaje w pętli while() dopóty, dopóki w gnieździe nie zostanie umieszczona karta identyfikacyjna. Jeśli to nastąpi to wygenerowane zostanie przerwanie zewnętrzne od wspomnianego wyżej wyprowadzenia PE14. W konsekwencji mikrokontroler wywoła funkcję obsługi przerwania zewnętrznego EXTI15_10_IRQHandler() z pliku stm32f10x_it.c. Zamieszczono ją na listingu 3. Jest to standardowy kod obsługi przerwania dla układów z rodziny STM32, a zatem na początku sprawdzane jest, od której linii przerwanie pochodzi, a następnie mikrokontroler zeruje flagę przerwania i przystępuje do wykonywania właściwego kodu aplikacji. Po zmianie flagi obecności karty w gnieździe (CardInserted) na 1, uruchamiana jest procedura aktywacji karty i jej zerowania.
Listing 3. Funkcja obsługi przerwania od wyprowadzenia detekującego obecność karty
void EXTI15_10_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line14) != RESET) { /* Wyczyść flagę przerwania */ EXTI_ClearITPendingBit(EXTI_Line14); /* Karta Smartcard wykryta */ CardInserted = 1; /* Włączenie zasilania karty */ SC_PowerCmd(ENABLE); /* Zerowanie karty */ SC_Reset(Bit_RESET); } }
Po powrocie z obsługi przerwania warunek wykonywania się pierwszej pętli while() nie jest już spełniony. Oznacza obecność karty w gnieździe, a więc aplikacja przystępuje do próby odebrania odpowiedzi na sygnał zerowania (ATR), ale najpierw za pomocą wywołania funkcji SC_PTSConfig() ustalana jest prędkość komunikacji.
Gdy ramka ATR jest już odebrana i zdekodowana, mikrokontroler rozpoczyna poruszanie się po systemie plików karty Smart Card. Najpierw sprawdzana jest obecność pliku głównego MF (Master File), a następnie wybierany jest plik ICCID. Jeśli te czynności zostaną zakończone powodzeniem, aplikacja przystępuje do odczytu zawartości pliku ICCID, jest to 10 bajtów, ponieważ taki jest właśnie jego rozmiar na użytej karcie identyfikacyjnej.
Jak widać, podstawowa obsługa kart Smart Card nie jest zbytnio skomplikowana. Taki stan rzeczy nie wynika oczywiście z banalności samego standardu, ponieważ z pewnością banalnym on nie jest. Dzięki sprzętowemu wsparciu ze strony układów STM32, oraz dzięki udostępnianiu przez firmę STMicroelectronics bibliotek, implementacja obsługi kart identyfikacyjnych we własnych aplikacjach nie powinna nastręczać większych problemów przy tworzeniu własnych aplikacji.