blob: 770e296cacacfb72fa136b1344ff73a9f0e0cec9 [file] [log] [blame]
Christina Quastdb7b1ab2015-03-03 12:34:36 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2009, Atmel Corporation
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the disclaimer below.
13 *
14 * Atmel's name may not be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * ----------------------------------------------------------------------------
28 */
29
Harald Welte2fb59962016-02-28 12:34:26 +010030#ifdef HAVE_CCID
31
Christina Quastdb7b1ab2015-03-03 12:34:36 +010032/*------------------------------------------------------------------------------
33 * Headers
34 *------------------------------------------------------------------------------*/
35
36#include "board.h"
37
38#include <string.h>
39
40/*------------------------------------------------------------------------------
41 * Internal definitions
42 *------------------------------------------------------------------------------*/
43/** Maximum ucSize in bytes of the smartcard answer to a command.*/
44#define MAX_ANSWER_SIZE 10
45
46/** Maximum ATR ucSize in bytes.*/
47#define MAX_ATR_SIZE 55
48
Christina Quastdb7b1ab2015-03-03 12:34:36 +010049/*------------------------------------------------------------------------------
50 * Internal variables
51 *------------------------------------------------------------------------------*/
52
53/** ISO7816 pins */
Harald Welte7dd3dfd2016-03-03 12:32:04 +010054static const Pin pinsISO7816[] = { PINS_ISO7816 };
55
Christina Quast53a76082015-03-04 19:01:34 +010056/** Bus switch pins */
Harald Welte7dd3dfd2016-03-03 12:32:04 +010057static const Pin pinsBus[] = { PINS_BUS_DEFAULT };
58
Christina Quast53a76082015-03-04 19:01:34 +010059/* SIMcard power pin */
Harald Welte7dd3dfd2016-03-03 12:32:04 +010060static const Pin pinsPower[] = { PWR_PINS };
61
Christina Quastdb7b1ab2015-03-03 12:34:36 +010062/** ISO7816 RST pin */
Harald Welte7dd3dfd2016-03-03 12:32:04 +010063static const Pin pinIso7816RstMC = PIN_ISO7816_RSTMC;
Christina Quastdb7b1ab2015-03-03 12:34:36 +010064static uint8_t sim_inserted = 0;
65
Harald Welte7dd3dfd2016-03-03 12:32:04 +010066static struct Usart_info usart_info = {
67 .base = USART_SIM,
68 .id = ID_USART_SIM,
69 .state = USART_RCV
70};
Christina Quaste24b9ac2015-04-10 17:44:49 +020071
Christina Quastdb7b1ab2015-03-03 12:34:36 +010072/*------------------------------------------------------------------------------
73 * Optional smartcard detection
74 *------------------------------------------------------------------------------*/
75
Christina Quastdb7b1ab2015-03-03 12:34:36 +010076/** Smartcard detection pin.*/
77static const Pin pinSmartCard = SMARTCARD_CONNECT_PIN;
78
79/**
80 * PIO interrupt service routine. Checks if the smartcard has been connected
81 * or disconnected.
82 */
Harald Welte7dd3dfd2016-03-03 12:32:04 +010083static void ISR_PioSmartCard(const Pin * pPin)
Christina Quastdb7b1ab2015-03-03 12:34:36 +010084{
85/* FIXME: why is pinSmartCard.pio->PIO_ISR the wrong number?
86 printf("+++++ Trying to check for pending interrupts (PIO ISR: 0x%X)\n\r", pinSmartCard.pio->PIO_ISR);
87 printf("+++++ Mask: 0x%X\n\r", pinSmartCard.mask);
88Output:
89 +++++ Trying to check for pending interrupts (PIO ISR: 0x400)) = 1<<10
90 +++++ Mask: 0x100 = 1<<8
91*/
Harald Welte7dd3dfd2016-03-03 12:32:04 +010092 // PA10 is DTXD, which is the debug uart transmit pin
Christina Quastdb7b1ab2015-03-03 12:34:36 +010093
Harald Welte7dd3dfd2016-03-03 12:32:04 +010094 printf("Interrupt!!\n\r");
95 /* Check all pending interrupts */
96 // FIXME: this if condition is not always true...
Christina Quastdb7b1ab2015-03-03 12:34:36 +010097// if ( (pinSmartCard.pio->PIO_ISR & pinSmartCard.mask) != 0 )
Harald Welte7dd3dfd2016-03-03 12:32:04 +010098 {
99 /* Check current level on pin */
100 if (PIO_Get(&pinSmartCard) == 0) {
101 sim_inserted = 1;
102 printf("-I- Smartcard inserted\n\r");
103 CCID_Insertion();
104 } else {
105 sim_inserted = 0;
106 printf("-I- Smartcard removed\n\r");
107 CCID_Removal();
108 }
109 }
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100110}
111
112/**
113 * Configures the smartcard detection pin to trigger an interrupt.
114 */
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100115static void ConfigureCardDetection(void)
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100116{
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100117 printf("+++++ Configure PIOs\n\r");
118 PIO_Configure(&pinSmartCard, 1);
119 NVIC_EnableIRQ(PIOA_IRQn);
120 PIO_EnableIt(&pinSmartCard);
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100121}
122
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100123/*-----------------------------------------------------------------------------
124 * Initialization and run
125 *-----------------------------------------------------------------------------*/
Christina Quast53a76082015-03-04 19:01:34 +0100126extern CCIDDriverConfigurationDescriptors configurationDescriptorCCID;
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100127
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100128void CCID_configure(void)
129{
130 CCIDDriver_Initialize();
Christina Quast95d66162015-04-09 22:38:47 +0200131// FIXME: Do we need to set priority?: NVIC_SetPriority( PIOA_IRQn, 10);
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100132 PIO_ConfigureIt(&pinSmartCard, ISR_PioSmartCard);
Christina Quast95d66162015-04-09 22:38:47 +0200133}
134
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100135void CCID_exit(void)
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100136{
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100137 PIO_DisableIt(&pinSmartCard);
138 USART_SetTransmitterEnabled(usart_info.base, 0);
139 USART_SetReceiverEnabled(usart_info.base, 0);
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100140}
141
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100142void CCID_init(void)
143{
144 uint8_t pAtr[MAX_ATR_SIZE];
145 uint8_t ucSize;
146
147 // FIXME: do we want to print ATR?
148 /* Initialize Atr buffer */
149 memset(pAtr, 0, sizeof(pAtr));
150
151 ConfigureCardDetection();
152
153 // Configure ISO7816 driver
154 PIO_Configure(pinsISO7816, PIO_LISTSIZE(pinsISO7816));
155 PIO_Configure(pinsBus, PIO_LISTSIZE(pinsBus));
156 PIO_Configure(pinsPower, PIO_LISTSIZE(pinsPower));
157
158 /* power up the card */
159// PIO_Set(&pinsPower[0]);
160
161 ISO7816_Init(&usart_info, CLK_MASTER);
162 USART_SetTransmitterEnabled(usart_info.base, 1);
163 USART_SetReceiverEnabled(usart_info.base, 1);
164
165 ISO7816_Set_Reset_Pin(&pinIso7816RstMC);
166 /* Read ATR */
167 ISO7816_warm_reset();
168
169 ISO7816_Datablock_ATR(pAtr, &ucSize);
170
171 /* Decode ATR and print it */
172 ISO7816_Decode_ATR(pAtr);
173
174 // FIXME. what if smcard is not inserted?
175 if (PIO_Get(&pinSmartCard) == 0) {
176 printf("SIM card inserted\n\r");
177 CCID_Insertion();
178 }
179}
180
181void CCID_run(void)
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100182{
Christina Quast53a76082015-03-04 19:01:34 +0100183
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100184 //if (USBD_Read(INT, pBuffer, dLength, fCallback, pArgument);
Christina Quast53a76082015-03-04 19:01:34 +0100185
Harald Welte7dd3dfd2016-03-03 12:32:04 +0100186 CCID_SmartCardRequest();
Christina Quastdb7b1ab2015-03-03 12:34:36 +0100187}
Harald Welte2fb59962016-02-28 12:34:26 +0100188#endif