ST AN1527 Application note

AN1527

APPLICATION NOTE

DEVELOPING A USB

SMARTCARD READER WITH ST7SCR

by Microcontroller Division Applications

INTRODUCTION

This document describes a firmware implementation developed by STMicroelectronics for a USB Smart Card Reader. This firmware is for the ST7SCR microcontroller and can be used with the associated Smart Card Reader board available from STMicroelectronics.

It is divided into 4 parts:

Universal Serial Bus (USB) management: This is the USB library which manages the USB hardware.

Chip Card Interface Device (CCID) implementation: This contains high level functions for using the USB in compliance with CCID specifications (messages for Bulk-in, Bulk-out, interrupt and class requests)

Interface Device (IFD) implementation: This contains high level functions for ISO 7816 specification implementation and the smartcard-specific command interpreter.

7816 UART Smartcard Interface (CRD) management: This contains low level functions for the hardware management of the 7816 UART Smartcard Interface (CRD).

The main loop polls USB transactions (functions in Ccid_usb.c) using a state machine process:

USB_Polling() function from library for USB low level and endpoint 0 management.

Receive USB Bulk-out message (CCID part).

Execute the function corresponding to the Bulk-out message (IFD part).

Send USB interrupt in message (CCID part) if necessary.

Send USB Bulk-in response (CCID part).

The Bulk-out/in messages are managed by a state machine. When the Bulk-out message reception is completed, the message function is executed and returns only after the completion of the action to be done in the IFD part. As this may take several 10 ms (e.g. ATR reading), the response is sent to the host by Bulk-in message. The Bulk-in/out messages are received in several transactions with a single transaction at every main loop if the USB endpoint is available.

If there are any interrupt messages, they are sent just before the Bulk-in message is sent.

Specific CCID class requests are managed by the setup management function in the USB library (USER_USB_setup() function).

AN1527/0702

1/14

DEVELOPING A USB SMARTCARD READER WITH ST7SCR

1 CCID IMPLEMENTATION

1.1 GENERALITIES

The Chip Card Interface Device (CCID) firmware implementation conforms to the “Universal Serial Bus Device Class Specification for USB Chip/Smart Card Interface Devices” revision 1.0. It contains two files:

Ccid_usb.c: This file contains the USB - CCID interface functions used to manage the state machine that generates Bulk-in/Bulk-out messages.

Ifd_ccid.c: This file contains the PC_to_RDR_xxx() and RDR_to_PC_xxx() message functions for the CCID.

The following commands are not supported but can be added easily:

PC_To_RDR_Secure,

PC_To_RDR_SetDataRateAndClockFrequency,

PC_To_RDR_ToAPDU,

PC_To_RDR_Mechanical.

This CCID part uses a 271-byte buffer for all messages. Messages are composed of two parts:

header (10 bytes: fixed size)

data (up to 261 bytes).

The size is based on the largest message managed at the short APDU transaction level. Due to this large size, the ST7SCR can have only 1 buffer and cannot store more than one message at a given time.

The CCID_BulkOutMessage() function uses several Bulk-out USB transactions to verify the message header and store the entire message in the buffer.

When the message reception is completed, the CCID_DispatchMessage() function identifies the message type and calls the corresponding function (PC_to_RDR_xxx()) for processing. Then, the IFD part of the firmware executes a command on the ICC if necessary. This command is included in the data field of the buffer. The PC_to_RDR_xxx() function receives from the IFD the answer to the message in the buffer data field and returns an error code to be included in the Bulk-in response.

The RDR_to_PC_xxx() function, which corresponds to the PC_to_RDR_xxx() previously executed, is launched and enters the correct values for error and status codes in the header.

At this time, the Bulk-in message is ready to be sent. But before the sending, the CCID_IntMessage() function is executed to detect any hardware problems or if a slot change has occurred. In this case, the corresponding interrupt message is sent to the host.

2/14

ST AN1527 Application note

DEVELOPING A USB SMARTCARD READER WITH ST7SCR

To finish the main loop, the CCID_BulkInMessage() function sends the Bulk-in message as an answer to the previous Bulk-out message. The message is sent in a process that requires several Bulk-in transactions (same concept as for the Bulk-out process).

In addition, the Abort request is implemented through the CCIDClassRequestAbort() function called in the USB_Polling() function. For this purpose, the USB_Polling() function is called in the PC_to_RDR_xxx() function. When this request is received from endpoint 0, a flag is set and the command sequence number is memorized.

All commands are aborted until the next PC_to_RDR_Abort command with the correct sequence number is received.

1.2 FUNCTION DESCRIPTION

void CCID_Init(void)

This function initializes the flags and status variables for the state machine process.

void CCID_Init_IT(void)

This function initializes the state machine and switches off the VccCard after a USB reset done by the PC Host. It can only be called by an interrupt routine.

void CCID_Suspend_IT(void)

This function initializes the state machine and the card interface hardware after a resume from USB suspend mode.

void CCID_BulkOutMessage(void)

This function manages the state machine during USB Bulk Out message reception. It fills the message buffer with a maximum of 271 bytes.

void CCID_BulkInMessage(void)

This function manages the state machine during the USB Bulk In message transmission. It sends the buffer content as a message with a maximum of 271 bytes.

void CCID_DispatchMessage(void)

This function identifies the USB Bulk Out received message and calls the corresponding functions to process it : PC_to_RDR_xxx() and RDR_to_PC_xxx().

void CCID_IntMessage(void)

This function verifies the slot status and sends an interrupt In message if needed.

3/14

DEVELOPING A USB SMARTCARD READER WITH ST7SCR

void CcidClassRequestAbort(void)

This function is called from the USER_USB_Setup() function to process an Abort request.

unsigned char PC_to_RDR_IccPowerOn(void)

This function verifies the PC_TO_RDR_ICCPOWERON command format and calls the IFD_IccPowerOn() function (from Interface Device level). If IFD_IccPowerOn() returns no error, the message header is filled with the ATR length. This PC_to_RDR function returns an error code.

unsigned char PC_to_RDR_IccPowerOff(void)

This function verifies the PC_TO_RDR_ICCPOWEROFF command format, switches off the smartcard power supply and returns the NOERROR code.

unsigned char PC_to_RDR_GetSlotStatus(void)

This function verifies the PC_TO_RDR_GETSLOTSTATUS command format, verifies the slot hardware state and returns the corresponding error code.

unsigned char PC_to_RDR_XfrBlock(void)

This function verifies the PC_TO_RDR_XFRBLOCK command format, checks the slot status and returns an error if needed. If there is no error, it calls the IFD_XfrBlock() function (from the Interface Device level). The message buffer contains the data to be transferred and is updated by this IFD function. This PC_to_RDR function returns an error code.

unsigned char PC_to_RDR_GetParameters(void)

This function verifies the PC_TO_RDR_GETPARAMETERS command format, checks the slot hardware state and returns the corresponding error code.

unsigned char PC_to_RDR_ResetParameters(void)

This function verifies the PC_TO_RDR_RESETPARAMETERS command format, fills the message buffer with the default values of the reader parameters and calls the IFD_SetParameters() function (from the Interface Device level). This PC_to_RDR function returns an error code.

unsigned char PC_to_RDR_SetParameters(void)

This function verifies the PC_TO_RDR_SETPARAMETERS command format and calls the IFD_SetParameters() function (from the Interface Device level). This PC_to_RDR function returns an error code.

4/14

DEVELOPING A USB SMARTCARD READER WITH ST7SCR

unsigned char PC_to_RDR_Escape(void)

This function verifies the PC_TO_RDR_ESCAPE command format and calls the IFD_Escape() function (from the Interface Device level). This PC_to_RDR function returns an error code (from IFD_Escape(), for example).

unsigned char PC_to_RDR_IccClock(void)

This function verifies the PC_TO_RDR_ICCCLOCK command format and calls the IFD_SetClock() function (from the Interface Device level). This PC_to_RDR function returns an error code (from IFD_SetClock(), for example).

unsigned char PC_to_RDR_Abort(void)

This function verifies the PC_TO_RDR_ABORT command format, checks the abort conditions and sets the corresponding flag. It returns the corresponding error code.

void RDR_to_PC_DataBlock(unsigned char ErrorCode)

This function fills the whole command buffer header including the error code given as input to prepare the RDR_TO_PC_DATABLOCK message.

void RDR_to_PC_SlotStatus(unsigned char ErrorCode)

This function fills the whole command buffer header including the error code given as input to prepare the RDR_TO_PC_SLOTSTATUS message.

void RDR_to_PC_Parameters(unsigned char ErrorCode)

This function fills the whole command buffer header including the error code given as input to prepare the RDR_TO_PC_PARAMETERS message and call the IFD_GetParameters() function to fill the message data field.

void RDR_to_PC_Escape(unsigned char ErrorCode)

This function fills the whole command buffer header including the error code given as input to prepare the RDR_TO_PC_ESCAPE message.

5/14

Loading...
+ 9 hidden pages