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_GREEN 1
#define IO_SW PIO_PA19
#define PIN_PUSHBUTTON {IO_SW, PIOA, ID_PIOA, PIO_INPUT, PIO_DEGLITCH | PIO_PULLUP}
/** Phone */
// 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 */
#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) */
#define CONSOLE_PINS {PINS_UART}
/// Smartcard detection pin
// FIXME: add connect pin as iso pin...should it be periph b or interrupt oder input?
#define BOARD_ISO7816_BASE_USART USART0
#define BOARD_ISO7816_ID_USART ID_USART0
#define USART_SIM USART0
#define ID_USART_SIM ID_USART0
#define USART_PHONE USART1
#define ID_USART_PHONE ID_USART1
#define SIM_PWEN PIO_PA5
#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, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_EDGE}
/// PIN used for reset the smartcard
//#define RST_SIM (1 << 7)
/// PIN used for resetting the smartcard
#define RST_SIM (1 << 7)
// 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}
@ -101,6 +108,17 @@
//#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 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 MISO pin definition (PA12).
#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}
};
#ifdef BOARD_ISO7816_BASE_USART
#undef BOARD_ISO7816_BASE_USART
#define BOARD_ISO7816_BASE_USART USART1
#endif
// SuperSIM ATR: 3B 9A 94 00 92 02 75 93 11 00 01 02 02 19
static const ATR[] = {0x3B, 0x9A, 0x94, 0x00, 0x92, 0x02, 0x75, 0x93, 0x11, 0x00, 0x01, 0x02, 0x02, 0x19};
#define NONE 0
#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 }
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 }
static const Pin pinPhoneClk = ISO7816_PHONE_CLK;
//#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;
/* ===================================================*/
/* Taken from iso7816_4.c */
@ -112,7 +110,7 @@ void USART1_IrqHandler( void )
{
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);
// Rcv buf full
@ -126,7 +124,8 @@ void USART1_IrqHandler( void )
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()
@ -151,13 +150,13 @@ static uint32_t ISO7816_GetChar( uint8_t *pCharToReceive )
uint32_t timeout=0;
if( StateUsartGlobal == USART_SEND ) {
while((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_TXEMPTY) == 0) {}
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
while((USART_PHONE->US_CSR & US_CSR_TXEMPTY) == 0) {}
USART_PHONE->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
StateUsartGlobal = USART_RCV;
}
/* 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)) {
TRACE_DEBUG("TimeOut\n\r");
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. */
/* 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|
(1<<10)));
if (status != 0 ) {
TRACE_DEBUG("R:0x%X\n\r", status);
TRACE_DEBUG("R:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_CSR);
TRACE_DEBUG("Nb:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_NER );
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA;
TRACE_DEBUG("R:0x%X\n\r", USART_PHONE->US_CSR);
TRACE_DEBUG("Nb:0x%X\n\r", USART_PHONE->US_NER );
USART_PHONE->US_CR = US_CR_RSTSTA;
}
/* 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
* \param pPinIso7816RstMC Pin ISO 7816 Rst MC
*/
@ -194,15 +235,16 @@ void _ISO7816_Init( const Pin pPinIso7816RstMC )
/* Pin ISO7816 initialize */
st_pinIso7816RstMC = pPinIso7816RstMC;
USART_Configure( BOARD_ISO7816_BASE_USART,
USART_Configure( USART_PHONE,
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_NBSTOP_1_BIT
// | US_MR_PAR_EVEN
| US_MR_PAR_EVEN
| US_MR_CHRL_8_BIT
| US_MR_CLKO, /** TODO: This field was set in the original simtrace firmware..why? */
// | (3<<24), /* MAX_ITERATION */
| US_MR_CLKO /** TODO: This field was set in the original simtrace firmware..why? */
| (3<<24), /* MAX_ITERATION */
1,
0);
/*
@ -212,17 +254,23 @@ void _ISO7816_Init( const Pin pPinIso7816RstMC )
USCLKS = 3 (Select SCK as input clock) --> US_MR_USCLKS_SCK
CD = 1 ? --> US_BRGR_CD(1)
*/
BOARD_ISO7816_BASE_USART->US_FIDI = 372;
BOARD_ISO7816_BASE_USART->US_BRGR = US_BRGR_CD(1);
USART_PHONE->US_FIDI = 372;
// 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 */
PMC_EnablePeripheral(BOARD_ISO7816_ID_USART);
PMC_EnablePeripheral(ID_USART_PHONE);
/* enable USART1 interrupt */
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);
/* 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));
// FIXME: RST seems to be allways high
@ -288,7 +336,8 @@ extern int main( void )
Config_PhoneRST_IrqHandler();
// USART_EnableIt( USART1, US_IER_RXRDY) ;
// USART_EnableIt( USART_PHONE, US_IER_TXRDY) ;
//USART_EnableIt( USART1, 0xffff) ;
// FIXME: At some point USBD_IrqHandler() should get called and set USBD_STATE_CONFIGURED
/* while (USBD_GetState() < USBD_STATE_CONFIGURED) {
@ -299,8 +348,8 @@ extern int main( void )
i++;
}
*/
// Infinite loop
printf("***** START \n\r");
TRACE_DEBUG("%s", "Start while loop\n\r");
while (1) {
/* if( USBState == STATE_SUSPEND ) {
@ -317,25 +366,30 @@ extern int main( void )
CCID_SmartCardRequest();
*/
int j;
for( j=0; j < 100; j++ ) {
// ISO7816_GetChar(&buff[j++]);
for( j=0; j < 1000; j++ ) {
// ISO7816_GetChar(&buff[j++]);
}
// printf("1 ");
for( j=0; j < 100; j++ ) {
for( j=0; j < 1000; j++ ) {
/* printf("0x%x ", buff[j++]);
if ((j % 40)==0) {
printf("\n\r");
}
*/
}
// printf("2\n\r");
//ISO7816_GetChar(&buff[0]);
//printf("buf: 0x%x\n\r", buff[0]);
/*if (char_avail == 1) {
ISO7816_GetChar(&buff[0]);
char_avail = 0;
}*/
uint32_t ret=-1;
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 ;
}