blob: 2a88dbef2c12407ba98d27c5fc9540af6825c56e [file] [log] [blame]
Christina Quaste8119112015-01-20 20:15:04 +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
56/*------------------------------------------------------------------------------
57 * Internal variables
58 *------------------------------------------------------------------------------*/
59/** USB state: suspend, resume, idle */
60unsigned char USBState = STATE_IDLE;
61
62/** ISO7816 pins */
63static const Pin pinsISO7816_PHONE[] = {PINS_ISO7816_PHONE};
64/** ISO7816 RST pin */
65static const Pin pinIso7816RstMC = PIN_ISO7816_RST_PHONE;
66static uint8_t sim_inserted = 0;
67
68static const Pin pPwr[] = {
69 /* Enable power converter 4.5-6V to 3.3V; low: off */
70 {SIM_PWEN, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT},
71
72 /* Enable second power converter: VCC_PHONE to VCC_SIM; high: off */
73 {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
74};
75
Christina Quastf7c28e02015-01-23 20:57:52 +010076// SuperSIM ATR: 3B 9A 94 00 92 02 75 93 11 00 01 02 02 19
Christina Quast0ff91d02015-01-28 18:04:58 +010077static const uint8_t ATR[] = {0x3B, 0x9A, 0x94, 0x00, 0x92, 0x02, 0x75, 0x93, 0x11, 0x00, 0x01, 0x02, 0x02, 0x19};
Christina Quastf7c28e02015-01-23 20:57:52 +010078#define NONE 0
79#define SEND_ATR 1
80#define AFTER_ATR 2
81static uint8_t phone_state = NONE;
Christina Quaste8119112015-01-20 20:15:04 +010082
Christina Quaste8119112015-01-20 20:15:04 +010083
84#define ISO7816_PHONE_RST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
85static const Pin pinPhoneRST = ISO7816_PHONE_RST;
Christina Quastf7c28e02015-01-23 20:57:52 +010086//#define ISO7816_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
87//static const Pin pinPhoneClk = ISO7816_PHONE_CLK;
Christina Quaste8119112015-01-20 20:15:04 +010088
89/* ===================================================*/
90/* Taken from iso7816_4.c */
91/* ===================================================*/
92/** Flip flop for send and receive char */
93#define USART_SEND 0
94#define USART_RCV 1
95/*-----------------------------------------------------------------------------
96 * Internal variables
97 *-----------------------------------------------------------------------------*/
98/** Variable for state of send and receive froom USART */
99static uint8_t StateUsartGlobal = USART_RCV;
100/** Pin reset master card */
101static Pin st_pinIso7816RstMC;
102
Christina Quastc8bf9f12015-01-29 17:34:46 +0100103static uint32_t char_stat = 0;
104static char rcvdChar = 0;
Christina Quaste8119112015-01-20 20:15:04 +0100105
106/*-----------------------------------------------------------------------------
107 * Interrupt routines
108 *-----------------------------------------------------------------------------*/
Christina Quastc8bf9f12015-01-29 17:34:46 +0100109/*
110 * char_stat is zero if no error occured.
111 * Otherwise it is filled with the content of the status register.
112 */
Christina Quaste8119112015-01-20 20:15:04 +0100113void USART1_IrqHandler( void )
114{
115 uint32_t stat;
Christina Quastc8bf9f12015-01-29 17:34:46 +0100116 char_stat = 0;
Christina Quaste8119112015-01-20 20:15:04 +0100117 // Rcv buf full
118/* if((stat & US_CSR_RXBUFF) == US_CSR_RXBUFF) {
119 TRACE_DEBUG("Rcv buf full");
120 USART_DisableIt(USART1, US_IDR_RXBUFF);
121 }
122*/
Christina Quastc8bf9f12015-01-29 17:34:46 +0100123 uint32_t csr = USART_PHONE->US_CSR;
124
Christina Quastb70efc02015-01-29 18:05:32 +0100125// printf(".\n\r");
126
Christina Quastc8bf9f12015-01-29 17:34:46 +0100127 if (csr & US_CSR_TXRDY) {
128 /* transmit buffer empty, nothing to transmit */
129 }
Christina Quastb70efc02015-01-29 18:05:32 +0100130 if (csr & US_CSR_RXRDY) {
131 stat = (csr&(US_CSR_OVRE|US_CSR_FRAME|
132 US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
133 (1<<10)));
Christina Quastc8bf9f12015-01-29 17:34:46 +0100134
Christina Quastb70efc02015-01-29 18:05:32 +0100135 if (stat == 0 ) {
136 /* Get a char */
137 rcvdChar = ((USART_PHONE->US_RHR) & 0xFF);
138 } /* else: error occured */
139 char_stat = stat;
140 }
Christina Quaste8119112015-01-20 20:15:04 +0100141}
142
143static void ISR_PhoneRST( const Pin *pPin)
144{
Christina Quastf7c28e02015-01-23 20:57:52 +0100145 TRACE_DEBUG("+++++++++ Interrupt!! ISR:0x%x, CSR:0x%x\n\r", pinPhoneRST.pio->PIO_ISR, USART1->US_CSR);
146 phone_state = SEND_ATR;
Christina Quastc8bf9f12015-01-29 17:34:46 +0100147 PIO_DisableIt( &pinPhoneRST ) ;
Christina Quaste8119112015-01-20 20:15:04 +0100148}
149
150static void Config_PhoneRST_IrqHandler()
151{
152 PIO_Configure( &pinPhoneRST, 1);
153// PIO_Configure( &pinPhoneClk, 1);
Christina Quaste8119112015-01-20 20:15:04 +0100154 PIO_ConfigureIt( &pinPhoneRST, ISR_PhoneRST ) ;
155// PIO_ConfigureIt( &pinPhoneClk, ISR_PhoneRST ) ;
156 PIO_EnableIt( &pinPhoneRST ) ;
157// PIO_EnableIt( &pinPhoneClk ) ;
Christina Quastc8bf9f12015-01-29 17:34:46 +0100158 NVIC_EnableIRQ( PIOA_IRQn );
Christina Quaste8119112015-01-20 20:15:04 +0100159}
160
161/**
162 * Get a character from ISO7816
163 * \param pCharToReceive Pointer for store the received char
164 * \return 0: if timeout else status of US_CSR
165 */
166static uint32_t ISO7816_GetChar( uint8_t *pCharToReceive )
167{
168 uint32_t status;
169 uint32_t timeout=0;
170
Christina Quastc8bf9f12015-01-29 17:34:46 +0100171 TRACE_DEBUG("--");
172
Christina Quaste8119112015-01-20 20:15:04 +0100173 if( StateUsartGlobal == USART_SEND ) {
Christina Quastf7c28e02015-01-23 20:57:52 +0100174 while((USART_PHONE->US_CSR & US_CSR_TXEMPTY) == 0) {}
175 USART_PHONE->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
Christina Quaste8119112015-01-20 20:15:04 +0100176 StateUsartGlobal = USART_RCV;
177 }
178
179 /* Wait USART ready for reception */
Christina Quastf7c28e02015-01-23 20:57:52 +0100180 while( ((USART_PHONE->US_CSR & US_CSR_RXRDY) == 0) ) {
Christina Quaste8119112015-01-20 20:15:04 +0100181 if(timeout++ > 12000 * (BOARD_MCK/1000000)) {
182 TRACE_DEBUG("TimeOut\n\r");
183 return( 0 );
184 }
185 }
186
187 /* At least one complete character has been received and US_RHR has not yet been read. */
188
189 /* Get a char */
Christina Quastf7c28e02015-01-23 20:57:52 +0100190 *pCharToReceive = ((USART_PHONE->US_RHR) & 0xFF);
Christina Quaste8119112015-01-20 20:15:04 +0100191
Christina Quastf7c28e02015-01-23 20:57:52 +0100192 status = (USART_PHONE->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
Christina Quaste8119112015-01-20 20:15:04 +0100193 US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
194 (1<<10)));
195
196 if (status != 0 ) {
197 TRACE_DEBUG("R:0x%X\n\r", status);
Christina Quastf7c28e02015-01-23 20:57:52 +0100198 TRACE_DEBUG("R:0x%X\n\r", USART_PHONE->US_CSR);
199 TRACE_DEBUG("Nb:0x%X\n\r", USART_PHONE->US_NER );
200 USART_PHONE->US_CR = US_CR_RSTSTA;
Christina Quaste8119112015-01-20 20:15:04 +0100201 }
202
203 /* Return status */
204 return( status );
205}
206
Christina Quastf7c28e02015-01-23 20:57:52 +0100207/**
208 * Send a char to ISO7816
209 * \param CharToSend char to be send
210 * \return status of US_CSR
211 */
212static uint32_t ISO7816_SendChar( uint8_t CharToSend )
213{
214 uint32_t status;
215
216 TRACE_DEBUG("********** Send char: %c (0x%X)\n\r", CharToSend, CharToSend);
217
218 if( StateUsartGlobal == USART_RCV ) {
219 USART_PHONE->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
220 StateUsartGlobal = USART_SEND;
221 }
222
223 /* Wait USART ready for transmit */
224 while((USART_PHONE->US_CSR & US_CSR_TXRDY) == 0) {}
225 /* There is no character in the US_THR */
226
227 /* Transmit a char */
228 USART_PHONE->US_THR = CharToSend;
229
230 status = (USART_PHONE->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
231 US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
232 (1<<10)));
233
234 if (status != 0 ) {
235 TRACE_DEBUG("******* status: 0x%X (Overrun: %d, NACK: %d, Timeout: %d, underrun: %d)\n\r",
236 status, ((status & US_CSR_OVRE)>> 5), ((status & US_CSR_NACK) >> 13),
237 ((status & US_CSR_TIMEOUT) >> 8), ((status & (1 << 10)) >> 10));
238
239 TRACE_DEBUG("E (USART CSR reg):0x%X\n\r", USART_PHONE->US_CSR);
240 TRACE_DEBUG("Nb (Number of errors):0x%X\n\r", USART_PHONE->US_NER );
241 USART_PHONE->US_CR = US_CR_RSTSTA;
242 }
243
244 /* Return status */
245 return( status );
246}
247
248
Christina Quaste8119112015-01-20 20:15:04 +0100249/** Initializes a ISO driver
250 * \param pPinIso7816RstMC Pin ISO 7816 Rst MC
251 */
252void _ISO7816_Init( const Pin pPinIso7816RstMC )
253{
254 TRACE_DEBUG("ISO_Init\n\r");
255
256 /* Pin ISO7816 initialize */
257 st_pinIso7816RstMC = pPinIso7816RstMC;
258
Christina Quastf7c28e02015-01-23 20:57:52 +0100259 USART_Configure( USART_PHONE,
Christina Quaste8119112015-01-20 20:15:04 +0100260 US_MR_USART_MODE_IS07816_T_0
Christina Quastf7c28e02015-01-23 20:57:52 +0100261// Nope, we aren't master:
262 // | US_MR_USCLKS_MCK
Christina Quaste8119112015-01-20 20:15:04 +0100263 | US_MR_USCLKS_SCK
264 | US_MR_NBSTOP_1_BIT
Christina Quastf7c28e02015-01-23 20:57:52 +0100265 | US_MR_PAR_EVEN
Christina Quaste8119112015-01-20 20:15:04 +0100266 | US_MR_CHRL_8_BIT
Christina Quastf7c28e02015-01-23 20:57:52 +0100267 | US_MR_CLKO /** TODO: This field was set in the original simtrace firmware..why? */
268 | (3<<24), /* MAX_ITERATION */
Christina Quaste8119112015-01-20 20:15:04 +0100269 1,
270 0);
271 /*
272 SYNC = 0 (async mode)
273 OVER = 0 (oversampling by 8?)
274 FIDI = 372 (default val on startup before other value is negotiated)
275 USCLKS = 3 (Select SCK as input clock) --> US_MR_USCLKS_SCK
276 CD = 1 ? --> US_BRGR_CD(1)
277 */
Christina Quastf7c28e02015-01-23 20:57:52 +0100278 USART_PHONE->US_FIDI = 372;
279// USART_PHONE->US_IDR = (uint32_t) -1;
280 USART_PHONE->US_BRGR = US_BRGR_CD(1);
281// USART_PHONE->US_BRGR = BOARD_MCK / (372*9600);
282 USART_PHONE->US_TTGR = 5;
Christina Quaste8119112015-01-20 20:15:04 +0100283
284 /* Configure USART */
Christina Quastf7c28e02015-01-23 20:57:52 +0100285 PMC_EnablePeripheral(ID_USART_PHONE);
Christina Quaste8119112015-01-20 20:15:04 +0100286
Christina Quastb70efc02015-01-29 18:05:32 +0100287 USART1->US_IDR = 0xffffffff;
288 USART_EnableIt( USART1, US_IER_RXRDY) ;
Christina Quaste8119112015-01-20 20:15:04 +0100289 /* enable USART1 interrupt */
Christina Quastb70efc02015-01-29 18:05:32 +0100290 NVIC_EnableIRQ( USART1_IRQn ) ;
Christina Quastf7c28e02015-01-23 20:57:52 +0100291
292// USART_PHONE->US_IER = US_IER_RXRDY | US_IER_OVRE | US_IER_FRAME | US_IER_PARE | US_IER_NACK | US_IER_ITER;
Christina Quaste8119112015-01-20 20:15:04 +0100293
Christina Quastf7c28e02015-01-23 20:57:52 +0100294 USART_SetTransmitterEnabled(USART_PHONE, 1);
Christina Quastb70efc02015-01-29 18:05:32 +0100295 USART_SetReceiverEnabled(USART_PHONE, 1);
Christina Quaste8119112015-01-20 20:15:04 +0100296
297}
298
299/*------------------------------------------------------------------------------
Christina Quaste8119112015-01-20 20:15:04 +0100300 * Main
301 *------------------------------------------------------------------------------*/
302
303/**
304 * Initializes the DBGU and ISO7816 driver, and starts some tests.
305 * \return Unused (ANSI-C compatibility)
306 */
307extern int main( void )
308{
309 uint8_t pAtr[MAX_ATR_SIZE] ;
310 uint8_t ucSize ;
311 static uint8_t buff[100];
312
313 LED_Configure(LED_NUM_GREEN);
314 LED_Set(LED_NUM_GREEN);
315
316 /* Disable watchdog*/
317 WDT_Disable( WDT ) ;
318
319 PIO_InitializeInterrupts(0);
320
321 /* Configure ISO7816 driver */
Christina Quastf7c28e02015-01-23 20:57:52 +0100322 PIO_Configure( pinsISO7816_PHONE, PIO_LISTSIZE( pinsISO7816_PHONE ) ) ;
Christina Quastc8bf9f12015-01-29 17:34:46 +0100323 PIO_Configure(pPwr, PIO_LISTSIZE( pPwr ));
Christina Quaste8119112015-01-20 20:15:04 +0100324
Christina Quastc8bf9f12015-01-29 17:34:46 +0100325 Config_PhoneRST_IrqHandler();
326
Christina Quaste8119112015-01-20 20:15:04 +0100327 _ISO7816_Init(pinIso7816RstMC);
328
329// FIXME: Or do I need to call VBUS_CONFIGURE() here instead, which will call USBD_Connect() later?
330// USBD_Connect();
331// FIXME: USB clock? USB PMC?
Christina Quastc8bf9f12015-01-29 17:34:46 +0100332// NVIC_EnableIRQ( UDP_IRQn );
Christina Quaste8119112015-01-20 20:15:04 +0100333
334
Christina Quastf7c28e02015-01-23 20:57:52 +0100335
Christina Quastc8bf9f12015-01-29 17:34:46 +0100336 // USART_EnableIt( USART_PHONE, US_IER_RXRDY) ;
337
Christina Quaste8119112015-01-20 20:15:04 +0100338 // FIXME: At some point USBD_IrqHandler() should get called and set USBD_STATE_CONFIGURED
339 /* while (USBD_GetState() < USBD_STATE_CONFIGURED) {
340 int i = 1;
341 if ((i%10000) == 0) {
342 TRACE_DEBUG("%d: USB State: %x\n\r", i, USBD_GetState());
343 }
344 i++;
345 }
346*/
Christina Quastf7c28e02015-01-23 20:57:52 +0100347 printf("***** START \n\r");
348 TRACE_DEBUG("%s", "Start while loop\n\r");
Christina Quaste8119112015-01-20 20:15:04 +0100349 while (1) {
Christina Quastc8bf9f12015-01-29 17:34:46 +0100350// printf(".\n\r");
Christina Quaste8119112015-01-20 20:15:04 +0100351
Christina Quastc8bf9f12015-01-29 17:34:46 +0100352 uint8_t j;
353/* for( j=0; j < 100; j++ ) {
Christina Quastf7c28e02015-01-23 20:57:52 +0100354 // ISO7816_GetChar(&buff[j++]);
Christina Quaste8119112015-01-20 20:15:04 +0100355 }
Christina Quastc8bf9f12015-01-29 17:34:46 +0100356*/
357 // for( j=0; j < 1000; j++ ) {
Christina Quaste8119112015-01-20 20:15:04 +0100358 /* printf("0x%x ", buff[j++]);
359 if ((j % 40)==0) {
360 printf("\n\r");
361 }
362 */
Christina Quastc8bf9f12015-01-29 17:34:46 +0100363// }
Christina Quaste8119112015-01-20 20:15:04 +0100364 //ISO7816_GetChar(&buff[0]);
365 //printf("buf: 0x%x\n\r", buff[0]);
Christina Quastf7c28e02015-01-23 20:57:52 +0100366
367 uint32_t ret=-1;
368
369 if (phone_state == SEND_ATR) {
370 printf("*");
371 TRACE_DEBUG("Send char %x %x %x ..", ATR[0], ATR[1], ATR[2]);
372 for (j=0; j < sizeof(ATR)/sizeof(ATR[0]); j++) {
373 ret = ISO7816_SendChar(ATR[j]);
374 TRACE_DEBUG("ret: 0x%x\n\r", ret);
375 }
376 phone_state = AFTER_ATR;
Christina Quastc8bf9f12015-01-29 17:34:46 +0100377 PIO_EnableIt( &pinPhoneRST ) ;
378 } else {
379// printf("Nothing to do\n\r");
380 }
381 if (rcvdChar != 0) {
Christina Quastb70efc02015-01-29 18:05:32 +0100382 printf("Received _%x_ \n\r", rcvdChar);
383 rcvdChar = 0;
Christina Quastf7c28e02015-01-23 20:57:52 +0100384 }
Christina Quaste8119112015-01-20 20:15:04 +0100385 }
386 return 0 ;
387}