blob: f4f76605b24bfbec50c9353fb1b63e84b5f48606 [file] [log] [blame]
Christina Quast32906bb2015-02-24 11:35:19 +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
30/*------------------------------------------------------------------------------
31 * Headers
32 *------------------------------------------------------------------------------*/
33
34#include "board.h"
35
36#include <string.h>
37
38/*------------------------------------------------------------------------------
39 * Internal definitions
40 *------------------------------------------------------------------------------*/
41
42/** Maximum ucSize in bytes of the smartcard answer to a command.*/
43#define MAX_ANSWER_SIZE 10
44
45/** Maximum ATR ucSize in bytes.*/
46#define MAX_ATR_SIZE 55
47
48/** USB states */
49/// Use for power management
50#define STATE_IDLE 0
51/// The USB device is in suspend state
52#define STATE_SUSPEND 4
53/// The USB device is in resume state
54#define STATE_RESUME 5
55
Christina Quast578daaa2015-03-13 23:46:01 +010056/* WTX (Wait time extension):
57* R-block PCB begins with (msb) 10 , ends with 000011 for WTX req, 100011 for WTX resp
58*
59* The standard says:
60* Rule 3 β€” If the card requires more than BWT to process the previously received I-block, it transmits S(WTX
61* request) where INF conveys one byte encoding an integer multiplier of the BWT value. The interface device
62* shall acknowledge by S(WTX response) with the same INF.
63* The time allocated starts at the leading edge of the last character of S(WTX response).
64*/
Christina Quasta4d1d162015-04-06 20:41:50 +020065// FIXME: Two times the same name for the define, which one is right?
66//#define WTX_req 0b10000011
67//#define WTX_req 0b10100011
Christina Quast578daaa2015-03-13 23:46:01 +010068// Alternatively:
69/* For T = 0 Protocol: The firmware on receiving the NULL (0x60) Procedure byte from the card, notifies
70it to the driver using the RDR_to_PC_DataBlock response. During this period, the reception of bytes
71from the smart card is still in progress and hence the device cannot indefinitely wait for IN tokens on
72the USB bulk-in endpoint. Hence, it is required of the driver to readily supply β€˜IN’ tokens on the USB
73bulk-in endpoint. On failure to do so, some of the wait time extension responses, will not be queued to
74the driver.
75*/
Christina Quast4db82e02015-04-11 18:14:41 +020076extern volatile uint8_t timeout_occured;
Christina Quast578daaa2015-03-13 23:46:01 +010077
Christina Quast32906bb2015-02-24 11:35:19 +010078/*------------------------------------------------------------------------------
79 * Internal variables
80 *------------------------------------------------------------------------------*/
81/** USB state: suspend, resume, idle */
82unsigned char USBState = STATE_IDLE;
83
84/** ISO7816 pins */
85static const Pin pinsISO7816_PHONE[] = {PINS_ISO7816_PHONE};
Christina Quast8043fdd2015-03-04 18:45:30 +010086/** Bus switch pins */
Christina Quast5c6a2992015-04-11 20:03:14 +020087
88#if DEBUG_PHONE_SNIFF
89# warning "Debug phone sniff via logic analyzer is enabled"
90// Logic analyzer probes are easier to attach to the SIM card slot
91static const Pin pins_bus[] = {PINS_BUS_SNIFF};
92#else
Christina Quast30418542015-04-05 10:08:06 +020093static const Pin pins_bus[] = {PINS_BUS_DEFAULT};
Christina Quast5c6a2992015-04-11 20:03:14 +020094#endif
Christina Quast4bcc0232015-03-24 21:59:32 +010095
Christina Quast32906bb2015-02-24 11:35:19 +010096/** ISO7816 RST pin */
97static const Pin pinIso7816RstMC = PIN_ISO7816_RST_PHONE;
98static uint8_t sim_inserted = 0;
99
100static const Pin pPwr[] = {
101 /* Enable power converter 4.5-6V to 3.3V; low: off */
102 {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT},
103
104 /* Enable second power converter: VCC_PHONE to VCC_SIM; high: off */
105 {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
106};
107
108
Christina Quast8e5381c2015-04-03 11:37:17 +0200109static const Pin pinPhoneRST = PIN_ISO7816_RST_PHONE;
110
Christina Quaste24b9ac2015-04-10 17:44:49 +0200111static struct Usart_info usart_info = {.base = USART_PHONE, .id = ID_USART_PHONE};
112
Christina Quast8e5381c2015-04-03 11:37:17 +0200113#define PR TRACE_INFO
Christina Quast32906bb2015-02-24 11:35:19 +0100114
115/* ===================================================*/
116/* Taken from iso7816_4.c */
117/* ===================================================*/
118/** Flip flop for send and receive char */
119#define USART_SEND 0
120#define USART_RCV 1
Christina Quastce296b92015-03-18 18:41:19 +0100121
Christina Quast4db82e02015-04-11 18:14:41 +0200122// FIXME: Comments
Christina Quast32906bb2015-02-24 11:35:19 +0100123/*-----------------------------------------------------------------------------
124 * Internal variables
125 *-----------------------------------------------------------------------------*/
126/** Variable for state of send and receive froom USART */
127static uint8_t StateUsartGlobal = USART_RCV;
Christina Quast32906bb2015-02-24 11:35:19 +0100128
Christina Quast4db82e02015-04-11 18:14:41 +0200129static uint8_t host_to_sim_buf[BUFLEN];
Christina Quast0ca83902015-03-22 19:05:23 +0100130
Christina Quast32906bb2015-02-24 11:35:19 +0100131/*-----------------------------------------------------------------------------
132 * Interrupt routines
133 *-----------------------------------------------------------------------------*/
Christina Quastdcce4c32015-04-13 22:20:12 +0200134void Callback_PhoneRST_ISR( uint8_t *pArg, uint8_t status, uint32_t transferred, uint32_t remaining)
135{
136 printf("rstCB\n\r");
137 PIO_EnableIt( &pinPhoneRST ) ;
138}
Christina Quast32906bb2015-02-24 11:35:19 +0100139static void ISR_PhoneRST( const Pin *pPin)
140{
Christina Quast4db82e02015-04-11 18:14:41 +0200141 int ret;
142 // FIXME: no printfs in ISRs?
Christina Quastd3630cc2015-04-03 11:38:24 +0200143 printf("+++ Int!! %x\n\r", pinPhoneRST.pio->PIO_ISR);
144 if ( ((pinPhoneRST.pio->PIO_ISR & pinPhoneRST.mask) != 0) )
145 {
146 if(PIO_Get( &pinPhoneRST ) == 0) {
147 printf(" 0 ");
148 } else {
149 printf(" 1 ");
150 }
151 }
Christina Quast4db82e02015-04-11 18:14:41 +0200152
Christina Quastdcce4c32015-04-13 22:20:12 +0200153 if ((ret = USBD_Write( PHONE_INT, "R", 1, (TransferCallback)&Callback_PhoneRST_ISR, 0 )) != USBD_STATUS_SUCCESS) {
Christina Quast4db82e02015-04-11 18:14:41 +0200154 TRACE_ERROR("USB err status: %d (%s)\n", ret, __FUNCTION__);
155 return;
156 }
Christina Quast32906bb2015-02-24 11:35:19 +0100157
Christina Quast95d66162015-04-09 22:38:47 +0200158 /* Interrupt enabled after ATR is sent to phone */
Christina Quastdcce4c32015-04-13 22:20:12 +0200159 PIO_DisableIt( &pinPhoneRST ) ;
Christina Quast32906bb2015-02-24 11:35:19 +0100160}
161
Christina Quast4db82e02015-04-11 18:14:41 +0200162void receive_from_host( void );
163void sendResponse_to_phone( uint8_t *pArg, uint8_t status, uint32_t transferred, uint32_t remaining)
164{
165 if (status != USBD_STATUS_SUCCESS) {
166 TRACE_ERROR("USB err status: %d (%s)\n", __FUNCTION__, status);
167 return;
168 }
169 PR("sendResp, stat: %X, trnsf: %x, rem: %x\n\r", status, transferred, remaining);
Christina Quast5c6a2992015-04-11 20:03:14 +0200170 PR("Resp: %x %x %x .. %x\n", host_to_sim_buf[0], host_to_sim_buf[1], host_to_sim_buf[2], host_to_sim_buf[transferred-1]);
Christina Quast4db82e02015-04-11 18:14:41 +0200171
Christina Quastd52201f2015-04-13 22:38:05 +0200172 USART_SetReceiverEnabled(USART_PHONE, 0);
173 USART_SetTransmitterEnabled(USART_PHONE, 1);
Christina Quast4db82e02015-04-11 18:14:41 +0200174 for (uint32_t i = 0; i < transferred; i++ ) {
Christina Quastb595e7c2015-04-12 13:31:01 +0200175 ISO7816_SendChar(host_to_sim_buf[i], &usart_info);
Christina Quast4db82e02015-04-11 18:14:41 +0200176 }
Christina Quastd52201f2015-04-13 22:38:05 +0200177 USART_SetTransmitterEnabled(USART_PHONE, 0);
178 USART_SetReceiverEnabled(USART_PHONE, 1);
Christina Quast4db82e02015-04-11 18:14:41 +0200179
180 receive_from_host();
181}
182
183void receive_from_host()
184{
185 int ret;
186 if ((ret = USBD_Read(PHONE_DATAOUT, &host_to_sim_buf, sizeof(host_to_sim_buf),
187 (TransferCallback)&sendResponse_to_phone, 0)) == USBD_STATUS_SUCCESS) {
188 } else {
Christina Quast5c6a2992015-04-11 20:03:14 +0200189 TRACE_ERROR("USB Err: %X\n", ret);
Christina Quast4db82e02015-04-11 18:14:41 +0200190 }
191}
Christina Quast32906bb2015-02-24 11:35:19 +0100192
Christina Quast95d66162015-04-09 22:38:47 +0200193void Phone_configure( void ) {
194 PIO_ConfigureIt( &pinPhoneRST, ISR_PhoneRST ) ;
195 NVIC_EnableIRQ( PIOA_IRQn );
196}
197
198void Phone_exit( void ) {
199 PIO_DisableIt( &pinPhoneRST ) ;
Christina Quastd52201f2015-04-13 22:38:05 +0200200 NVIC_DisableIRQ(USART1_IRQn);
Christina Quast95d66162015-04-09 22:38:47 +0200201 USART_DisableIt( USART_PHONE, US_IER_RXRDY) ;
202 USART_SetTransmitterEnabled(USART_PHONE, 0);
203 USART_SetReceiverEnabled(USART_PHONE, 0);
204}
205
206void Phone_init( void ) {
Christina Quast32906bb2015-02-24 11:35:19 +0100207 PIO_Configure( pinsISO7816_PHONE, PIO_LISTSIZE( pinsISO7816_PHONE ) ) ;
Christina Quast8043fdd2015-03-04 18:45:30 +0100208 PIO_Configure( pins_bus, PIO_LISTSIZE( pins_bus) ) ;
209
Christina Quast95d66162015-04-09 22:38:47 +0200210 PIO_Configure( &pinPhoneRST, 1);
Christina Quast32906bb2015-02-24 11:35:19 +0100211
Christina Quast95d66162015-04-09 22:38:47 +0200212 PIO_EnableIt( &pinPhoneRST ) ;
Christina Quaste24b9ac2015-04-10 17:44:49 +0200213 ISO7816_Init(&usart_info, CLK_SLAVE);
Christina Quastc0aa7692015-02-25 14:02:01 +0100214
Christina Quastd52201f2015-04-13 22:38:05 +0200215 USART_SetTransmitterEnabled(USART_PHONE, 0);
Christina Quastc0aa7692015-02-25 14:02:01 +0100216 USART_SetReceiverEnabled(USART_PHONE, 1);
Christina Quastfb524b92015-02-27 13:39:45 +0100217
Christina Quastd52201f2015-04-13 22:38:05 +0200218 USART_EnableIt(USART_PHONE, US_IER_RXRDY); // TODO: interrupt enable/disable is shared with sniffer
219 NVIC_EnableIRQ(USART1_IRQn);
220
Christina Quastfb524b92015-02-27 13:39:45 +0100221 /* Configure ISO7816 driver */
222 // FIXME: PIO_Configure(pPwr, PIO_LISTSIZE( pPwr ));
223
Christina Quast32906bb2015-02-24 11:35:19 +0100224// FIXME: Or do I need to call VBUS_CONFIGURE() here instead, which will call USBD_Connect() later?
225// USBD_Connect();
Christina Quast32906bb2015-02-24 11:35:19 +0100226
Christina Quast4db82e02015-04-11 18:14:41 +0200227 //Timer_Init();
228
229 receive_from_host();
Christina Quast32906bb2015-02-24 11:35:19 +0100230}
Christina Quastfb524b92015-02-27 13:39:45 +0100231
Christina Quastaab3d7c2015-04-09 17:02:17 +0200232
Christina Quastce296b92015-03-18 18:41:19 +0100233// Sniffed Phone to SIM card communication:
234// phone > sim : RST
235// phone < sim : ATR
236// phone > sim : A0 A4 00 00 02 (Select File)
237// phone < sim : A4 (INS repeated)
238// phone > sim : 7F 02 (= ??)
239// phone < sim : 9F 16 (9F: success, can deliver 0x16 (=22) byte)
240// phone > sim : ?? (A0 C0 00 00 16)
241// phone < sim : C0 (INS repeated)
242// phone < sim : 00 00 00 00 7F 20 02 00 00 00 00 00 09 91 00 17 04 00 83 8A (data of length 22 -2)
243// phone <? sim : 90 00 (OK, everything went fine)
244// phone ? sim : 00 (??)
Christina Quast578daaa2015-03-13 23:46:01 +0100245
Christina Quastfb524b92015-02-27 13:39:45 +0100246void Phone_run( void )
247{
Christina Quast4db82e02015-04-11 18:14:41 +0200248 check_data_from_phone();
Christina Quastfb524b92015-02-27 13:39:45 +0100249}