AnsweredAssumed Answered

STM32F103 SmartCard Question

Question asked by wormsley.jeff on Apr 3, 2015
Latest reply on Apr 3, 2015 by wormsley.jeff
I am trying to create a smartcard driver on the STM32F103.  I am using USART3, and the ST8024CTR interface chip.

My problem is that I can read the cards (with a hack of a workaround), but cannot write to them.  What is happening is that I am using an interrupt driven read/write state machine, but the receive interrupts are happening way too soon.  

When I need to send a command to the card, I build an APDU structure, set my state variable to send the CLA, and enable the TXE interrupt.  

This immediately fires, and the state machine sends the CLA and sets the state to send the INS.  

The TXE interrupt triggers again (almost immediately since CLA went straight to the shift register) and I send the INS and set the state variable to send the P1.  

The TXE interrupt triggers again and I send P1 then set the state variable to send P2.  

The TXE interrupt triggers again and I send P1.  If I need to write data, then I set the state variable to send the length expected byte.  Else I skip this and part in () below.

(The TXE interrupt triggers again and I send length expected.)

Then I disable the transmitter and enable the RXNE interrupt to wait for the procedure byte.

Here's where things go wrong.  The RXNE interrupt fires almost immediately, but when I read the data byte, it contains the value of P2.  If I sent the length expected byte, it will fire again and I'll get the length expected byte.  Either way the next thing I get is the procedure byte.  I can work around this by ignoring anything that isn't a valid procedure byte (INS or -INS, 0x60, 0x6* or 0x9*), and that allows me to read data from my cards (since none of the commands INS bytes look like a procedure byte).

When I need to write data to the card, after getting the procedure byte, I disable the receiver and re-enable the TXE interrupt with my state set to send my data.  

Then the TXE interrupt fires, and I send a byte of data.  If there is no more data to send, then I disable the TXE interrupt, enable the RXNE interrupt, and wait for the SW1 SW2 status word.  

Here again, the RXNE interrupt fires when I don't expect it.  I get the last byte or two of the data I wrote read back in. 

Why is the USART receiving the data it wrote?  Is the smartcard mode not smart enough to reject the data it just sent?  Is it possible I missed some setting that would prevent this behavior?  Or is this something that is known and has to be worked around some way, perhaps by leaving the RXNE enabled always, and keeping track of what I just sent and discarding the received data if it matches?

Any insights would be appreciated.

Outcomes