phone: on reset by smartcardreader send ATR

Every time the reset line is pulled low, simtrace sends an ATR
packet over USART1.
The USART1 is slave in this configuration.
This commit is contained in:
Christina Quast 2015-01-23 20:57:52 +01:00
parent ea103826fa
commit f7c28e0b0b
2 changed files with 123 additions and 51 deletions

View File

@ -46,8 +46,15 @@
#define LED_NUM_RED 0 #define LED_NUM_RED 0
#define LED_NUM_GREEN 1 #define LED_NUM_GREEN 1
#define IO_SW PIO_PA19 /** Phone */
#define PIN_PUSHBUTTON {IO_SW, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP} // Connect VPP, CLK and RST lines from smartcard to the phone
//#define PIN_SC_SW {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
// Temporary fix: do not connect
#define PIN_SC_SW {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
// Connect SIM card I/O lines to the phone
//#define PIN_IO_SW {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
// FIXME: Temporary fix: do not connect
#define PIN_IO_SW {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
/** USART0 pin RX */ /** USART0 pin RX */
#define PIN_USART0_RXD {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} #define PIN_USART0_RXD {PIO_PA9A_URXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
@ -72,11 +79,12 @@
/** Pins description corresponding to Rxd,Txd, (UART pins) */ /** Pins description corresponding to Rxd,Txd, (UART pins) */
#define CONSOLE_PINS {PINS_UART} #define CONSOLE_PINS {PINS_UART}
/// Smartcard detection pin /// Smartcard detection pin
// FIXME: add connect pin as iso pin...should it be periph b or interrupt oder input? // FIXME: add connect pin as iso pin...should it be periph b or interrupt oder input?
#define BOARD_ISO7816_BASE_USART USART0 #define USART_SIM USART0
#define BOARD_ISO7816_ID_USART ID_USART0 #define ID_USART_SIM ID_USART0
#define USART_PHONE USART1
#define ID_USART_PHONE ID_USART1
#define SIM_PWEN PIO_PA5 #define SIM_PWEN PIO_PA5
#define VCC_FWD PIO_PA26 #define VCC_FWD PIO_PA26
@ -87,8 +95,7 @@
#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE } #define SMARTCARD_CONNECT_PIN {SW_SIM, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
//#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE} //#define SMARTCARD_CONNECT_PIN {SW_SIM, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE}
/// PIN used for reset the smartcard /// PIN used for resetting the smartcard
//#define RST_SIM (1 << 7)
#define RST_SIM (1 << 7) #define RST_SIM (1 << 7)
// FIXME: Card is resetted with pin set to 0 --> PIO_OUTPUT_1 as default is right? // FIXME: Card is resetted with pin set to 0 --> PIO_OUTPUT_1 as default is right?
#define PIN_ISO7816_RSTMC {RST_SIM, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} #define PIN_ISO7816_RSTMC {RST_SIM, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
@ -101,6 +108,17 @@
//#define PINS_ISO7816 PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC //#define PINS_ISO7816 PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC
#define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2 #define PINS_ISO7816 PIN_SIM_IO, PIN_SIM_CLK, PIN_ISO7816_RSTMC // SIM_PWEN_PIN, PIN_SIM_IO2, PIN_SIM_CLK2
#define VCC_PHONE {PIO_PA25, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
#define PIN_ISO7816_RST_PHONE {PIO_PA24, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
#define PIN_PHONE_IO2 {PIO_PA21, PIOA, ID_PIOA, PIO_INPUT, PIO_OPENDRAIN}
#define PIN_PHONE_IO {PIO_PA22, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_PHONE_CLK {PIO_PA23A_SCK1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT} // External Clock Input on PA28
#define PIN_PHONE_CLK2 {PIO_PA29, ID_PIOA, PIO_INPUT, PIO_OPENDRAIN}
#define PINS_ISO7816_PHONE PIN_PHONE_IO, PIN_PHONE_CLK, PIN_ISO7816_RST_PHONE
//, VCC_PHONE
//** SPI interface **/ //** SPI interface **/
/// SPI MISO pin definition (PA12). /// SPI MISO pin definition (PA12).
#define PIN_SPI_MISO {1 << 12, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP} #define PIN_SPI_MISO {1 << 12, PIOA, PIOA, PIO_PERIPH_A, PIO_PULLUP}

View File

@ -73,20 +73,18 @@ static const Pin pPwr[] = {
{VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} {VCC_FWD, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
}; };
#ifdef BOARD_ISO7816_BASE_USART // SuperSIM ATR: 3B 9A 94 00 92 02 75 93 11 00 01 02 02 19
#undef BOARD_ISO7816_BASE_USART static const ATR[] = {0x3B, 0x9A, 0x94, 0x00, 0x92, 0x02, 0x75, 0x93, 0x11, 0x00, 0x01, 0x02, 0x02, 0x19};
#define BOARD_ISO7816_BASE_USART USART1 #define NONE 0
#endif #define SEND_ATR 1
#define AFTER_ATR 2
static uint8_t phone_state = NONE;
#ifdef BOARD_ISO7816_ID_USART
#undef BOARD_ISO7816_ID_USART
#define BOARD_ISO7816_ID_USART ID_USART1
#endif
#define ISO7816_PHONE_RST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE } #define ISO7816_PHONE_RST {PIO_PA24, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
static const Pin pinPhoneRST = ISO7816_PHONE_RST; static const Pin pinPhoneRST = ISO7816_PHONE_RST;
#define ISO7816_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE } //#define ISO7816_PHONE_CLK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_DEGLITCH | PIO_IT_EDGE }
static const Pin pinPhoneClk = ISO7816_PHONE_CLK; //static const Pin pinPhoneClk = ISO7816_PHONE_CLK;
/* ===================================================*/ /* ===================================================*/
/* Taken from iso7816_4.c */ /* Taken from iso7816_4.c */
@ -112,7 +110,7 @@ void USART1_IrqHandler( void )
{ {
uint32_t stat; uint32_t stat;
stat = BOARD_USART_BASE->US_CSR; stat = USART1->US_CSR;
TRACE_DEBUG("stat: 0x%x, imask: 0x%x", stat, USART1->US_IMR); TRACE_DEBUG("stat: 0x%x, imask: 0x%x", stat, USART1->US_IMR);
// Rcv buf full // Rcv buf full
@ -126,7 +124,8 @@ void USART1_IrqHandler( void )
static void ISR_PhoneRST( const Pin *pPin) static void ISR_PhoneRST( const Pin *pPin)
{ {
printf("+++++++++ Interrupt!! %x\n\r", pinPhoneRST.pio->PIO_ISR); TRACE_DEBUG("+++++++++ Interrupt!! ISR:0x%x, CSR:0x%x\n\r", pinPhoneRST.pio->PIO_ISR, USART1->US_CSR);
phone_state = SEND_ATR;
} }
static void Config_PhoneRST_IrqHandler() static void Config_PhoneRST_IrqHandler()
@ -151,13 +150,13 @@ static uint32_t ISO7816_GetChar( uint8_t *pCharToReceive )
uint32_t timeout=0; uint32_t timeout=0;
if( StateUsartGlobal == USART_SEND ) { if( StateUsartGlobal == USART_SEND ) {
while((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_TXEMPTY) == 0) {} while((USART_PHONE->US_CSR & US_CSR_TXEMPTY) == 0) {}
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK; USART_PHONE->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
StateUsartGlobal = USART_RCV; StateUsartGlobal = USART_RCV;
} }
/* Wait USART ready for reception */ /* Wait USART ready for reception */
while( ((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_RXRDY) == 0) ) { while( ((USART_PHONE->US_CSR & US_CSR_RXRDY) == 0) ) {
if(timeout++ > 12000 * (BOARD_MCK/1000000)) { if(timeout++ > 12000 * (BOARD_MCK/1000000)) {
TRACE_DEBUG("TimeOut\n\r"); TRACE_DEBUG("TimeOut\n\r");
return( 0 ); return( 0 );
@ -167,23 +166,65 @@ static uint32_t ISO7816_GetChar( uint8_t *pCharToReceive )
/* At least one complete character has been received and US_RHR has not yet been read. */ /* At least one complete character has been received and US_RHR has not yet been read. */
/* Get a char */ /* Get a char */
*pCharToReceive = ((BOARD_ISO7816_BASE_USART->US_RHR) & 0xFF); *pCharToReceive = ((USART_PHONE->US_RHR) & 0xFF);
status = (BOARD_ISO7816_BASE_USART->US_CSR&(US_CSR_OVRE|US_CSR_FRAME| status = (USART_PHONE->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK| US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
(1<<10))); (1<<10)));
if (status != 0 ) { if (status != 0 ) {
TRACE_DEBUG("R:0x%X\n\r", status); TRACE_DEBUG("R:0x%X\n\r", status);
TRACE_DEBUG("R:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_CSR); TRACE_DEBUG("R:0x%X\n\r", USART_PHONE->US_CSR);
TRACE_DEBUG("Nb:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_NER ); TRACE_DEBUG("Nb:0x%X\n\r", USART_PHONE->US_NER );
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA; USART_PHONE->US_CR = US_CR_RSTSTA;
} }
/* Return status */ /* Return status */
return( status ); return( status );
} }
/**
* Send a char to ISO7816
* \param CharToSend char to be send
* \return status of US_CSR
*/
static uint32_t ISO7816_SendChar( uint8_t CharToSend )
{
uint32_t status;
TRACE_DEBUG("********** Send char: %c (0x%X)\n\r", CharToSend, CharToSend);
if( StateUsartGlobal == USART_RCV ) {
USART_PHONE->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
StateUsartGlobal = USART_SEND;
}
/* Wait USART ready for transmit */
while((USART_PHONE->US_CSR & US_CSR_TXRDY) == 0) {}
/* There is no character in the US_THR */
/* Transmit a char */
USART_PHONE->US_THR = CharToSend;
status = (USART_PHONE->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
(1<<10)));
if (status != 0 ) {
TRACE_DEBUG("******* status: 0x%X (Overrun: %d, NACK: %d, Timeout: %d, underrun: %d)\n\r",
status, ((status & US_CSR_OVRE)>> 5), ((status & US_CSR_NACK) >> 13),
((status & US_CSR_TIMEOUT) >> 8), ((status & (1 << 10)) >> 10));
TRACE_DEBUG("E (USART CSR reg):0x%X\n\r", USART_PHONE->US_CSR);
TRACE_DEBUG("Nb (Number of errors):0x%X\n\r", USART_PHONE->US_NER );
USART_PHONE->US_CR = US_CR_RSTSTA;
}
/* Return status */
return( status );
}
/** Initializes a ISO driver /** Initializes a ISO driver
* \param pPinIso7816RstMC Pin ISO 7816 Rst MC * \param pPinIso7816RstMC Pin ISO 7816 Rst MC
*/ */
@ -194,15 +235,16 @@ void _ISO7816_Init( const Pin pPinIso7816RstMC )
/* Pin ISO7816 initialize */ /* Pin ISO7816 initialize */
st_pinIso7816RstMC = pPinIso7816RstMC; st_pinIso7816RstMC = pPinIso7816RstMC;
USART_Configure( BOARD_ISO7816_BASE_USART, USART_Configure( USART_PHONE,
US_MR_USART_MODE_IS07816_T_0 US_MR_USART_MODE_IS07816_T_0
// Nope, we aren't master: | US_MR_USCLKS_MCK // Nope, we aren't master:
// | US_MR_USCLKS_MCK
| US_MR_USCLKS_SCK | US_MR_USCLKS_SCK
| US_MR_NBSTOP_1_BIT | US_MR_NBSTOP_1_BIT
// | US_MR_PAR_EVEN | US_MR_PAR_EVEN
| US_MR_CHRL_8_BIT | US_MR_CHRL_8_BIT
| US_MR_CLKO, /** TODO: This field was set in the original simtrace firmware..why? */ | US_MR_CLKO /** TODO: This field was set in the original simtrace firmware..why? */
// | (3<<24), /* MAX_ITERATION */ | (3<<24), /* MAX_ITERATION */
1, 1,
0); 0);
/* /*
@ -212,17 +254,23 @@ void _ISO7816_Init( const Pin pPinIso7816RstMC )
USCLKS = 3 (Select SCK as input clock) --> US_MR_USCLKS_SCK USCLKS = 3 (Select SCK as input clock) --> US_MR_USCLKS_SCK
CD = 1 ? --> US_BRGR_CD(1) CD = 1 ? --> US_BRGR_CD(1)
*/ */
BOARD_ISO7816_BASE_USART->US_FIDI = 372; USART_PHONE->US_FIDI = 372;
BOARD_ISO7816_BASE_USART->US_BRGR = US_BRGR_CD(1); // USART_PHONE->US_IDR = (uint32_t) -1;
USART_PHONE->US_BRGR = US_BRGR_CD(1);
// USART_PHONE->US_BRGR = BOARD_MCK / (372*9600);
USART_PHONE->US_TTGR = 5;
/* Configure USART */ /* Configure USART */
PMC_EnablePeripheral(BOARD_ISO7816_ID_USART); PMC_EnablePeripheral(ID_USART_PHONE);
/* enable USART1 interrupt */ /* enable USART1 interrupt */
NVIC_EnableIRQ( USART1_IRQn ) ; NVIC_EnableIRQ( USART1_IRQn ) ;
// USART_PHONE->US_IER = US_IER_RXRDY | US_IER_OVRE | US_IER_FRAME | US_IER_PARE | US_IER_NACK | US_IER_ITER;
USART_SetTransmitterEnabled(BOARD_ISO7816_BASE_USART, 1);
USART_SetReceiverEnabled(BOARD_ISO7816_BASE_USART, 1); USART_SetTransmitterEnabled(USART_PHONE, 1);
// USART_SetReceiverEnabled(USART_PHONE, 1);
} }
@ -272,7 +320,7 @@ extern int main( void )
PIO_InitializeInterrupts(0); PIO_InitializeInterrupts(0);
/* Configure ISO7816 driver */ /* Configure ISO7816 driver */
PIO_Configure( pinsISO7816_PHONE, PIO_LISTSIZE( &pinsISO7816_PHONE ) ) ; PIO_Configure( pinsISO7816_PHONE, PIO_LISTSIZE( pinsISO7816_PHONE ) ) ;
PIO_Configure(pPwr, PIO_LISTSIZE(pPwr)); PIO_Configure(pPwr, PIO_LISTSIZE(pPwr));
// FIXME: RST seems to be allways high // FIXME: RST seems to be allways high
@ -288,7 +336,8 @@ extern int main( void )
Config_PhoneRST_IrqHandler(); Config_PhoneRST_IrqHandler();
// USART_EnableIt( USART1, US_IER_RXRDY) ; // USART_EnableIt( USART_PHONE, US_IER_TXRDY) ;
//USART_EnableIt( USART1, 0xffff) ; //USART_EnableIt( USART1, 0xffff) ;
// FIXME: At some point USBD_IrqHandler() should get called and set USBD_STATE_CONFIGURED // FIXME: At some point USBD_IrqHandler() should get called and set USBD_STATE_CONFIGURED
/* while (USBD_GetState() < USBD_STATE_CONFIGURED) { /* while (USBD_GetState() < USBD_STATE_CONFIGURED) {
@ -299,8 +348,8 @@ extern int main( void )
i++; i++;
} }
*/ */
printf("***** START \n\r");
// Infinite loop TRACE_DEBUG("%s", "Start while loop\n\r");
while (1) { while (1) {
/* if( USBState == STATE_SUSPEND ) { /* if( USBState == STATE_SUSPEND ) {
@ -317,25 +366,30 @@ extern int main( void )
CCID_SmartCardRequest(); CCID_SmartCardRequest();
*/ */
int j; int j;
for( j=0; j < 100; j++ ) { for( j=0; j < 1000; j++ ) {
// ISO7816_GetChar(&buff[j++]); // ISO7816_GetChar(&buff[j++]);
} }
// printf("1 "); for( j=0; j < 1000; j++ ) {
for( j=0; j < 100; j++ ) {
/* printf("0x%x ", buff[j++]); /* printf("0x%x ", buff[j++]);
if ((j % 40)==0) { if ((j % 40)==0) {
printf("\n\r"); printf("\n\r");
} }
*/ */
} }
// printf("2\n\r");
//ISO7816_GetChar(&buff[0]); //ISO7816_GetChar(&buff[0]);
//printf("buf: 0x%x\n\r", buff[0]); //printf("buf: 0x%x\n\r", buff[0]);
/*if (char_avail == 1) { uint32_t ret=-1;
ISO7816_GetChar(&buff[0]);
char_avail = 0; if (phone_state == SEND_ATR) {
}*/ printf("*");
TRACE_DEBUG("Send char %x %x %x ..", ATR[0], ATR[1], ATR[2]);
for (j=0; j < sizeof(ATR)/sizeof(ATR[0]); j++) {
ret = ISO7816_SendChar(ATR[j]);
TRACE_DEBUG("ret: 0x%x\n\r", ret);
}
phone_state = AFTER_ATR;
}
} }
return 0 ; return 0 ;
} }