We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello, Writing a an USB smartcard driver, I choose to start a new thread instead of continue the last thread i ve initiated. I have written the configuration for the LPC2368. Here the configuration:
const BYTE USB_ConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGUARTION_DESC_SIZE, /* bDescriptorType */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL( /* wTotalLength */ USB_CONFIGUARTION_DESC_SIZE + USB_INTERFACE_DESC_SIZE + SMARTCARD_CLASS_DESC_SIZE + 3*USB_ENDPOINT_DESC_SIZE ), 0x01, /* bNumInterfaces */ 0x01, /* bConfigurationValue */ 0x03, /* iConfiguration */ /*USB_CONFIG_BUS_POWERED */ /* bmAttributes */ 0x80, USB_CONFIG_POWER_MA(100), /* bMaxPower */ /* Interface 0, Alternate Setting 0, HID Class */ USB_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x03, /* bNumEndpoints */ 0x0b, /* bInterfaceClass */ //USB_DEVICE_CLASS_HUMAN_INTERFACE, /* bInterfaceClass */ 0x00, /* bInterfaceSubClass */ 0x00, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* Smartcard Class Descriptor */ SMARTCARD_CLASS_DESC_SIZE, /* bLength */ SMARTCARD_SMARTCARD_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0100), /* 1.00 */ /* bcdCCID */ 0x00, /* bMaxSlotIndex */ 0x07, /* bVoltageSupport: 5v, 3v and 1.8v */ 0x03,0x00,0x00,0x00, // dwProtocols: supports T=0 and T=1 0xF8,0x34,0x00,0x00, // dwDefaultClock: 13,56 Mhz (0x00000FA0) 0xF8,0x34,0x00,0x00, // dwMaximumClock: 13,56 Mhz (0x00000FA0) 0x00, // bNumClockSupported => no manual setting 0x00,0x2A,0x00,0x00, // dwDataRate: 10752 bps (0x00002A00) 0x08,0xF8,0x01,0x00, // dwMaxDataRate: 129032 bps (0x0001F808) 0x00, // bNumDataRatesSupported => no manual setting 0xFE,0x00,0x00,0x00, /* IFSD */ 0x00,0x00,0x00,0x00, /* Synchron Protocol */ 0x00,0x00,0x00,0x00, /* Mechanical Features, DWORD */ (0x04 | 0x08 | 0x10 | 0x40 | 0x02),(0x01 | 0x02),0x02,0x00, /* Features - Automatic activation - clk, baud rate, voltage :automatic - short APDU level exchange*/ // CCID can set ICC in clock stop mode - Automatic IFSD exchange(for T=1) 0x0F,0x01,0x00,0x00, /* Max CCID Message Length : Maximun block size + header (261 + 10)*/ 0xFF, /* Class Get Response */ 0XFF, /* Class enveloppe */ 0x00,0x00, /* wLayout */ 0x00, /* Pin Support */ 0x01, /* Max CCID Busy Slots */ /* Endpoint, INTERRUPT In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x81, /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0008), /* wMaxPacketSize */ 0x18, /* 32ms */ /* bInterval */ /* Endpoint, SMART CARD Bulk In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x82, /* bEndpointAddress */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ 0x00, /* 32ms */ /* bInterval */ /* Endpoint, SMART CARD BULK Out (from the host to the device) */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x02, /* bEndpointAddress */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ 0x00, /* 32ms */ /* bInterval */ /* Terminator */ 0 /* bLength */ };
The endpoints seem to be well configured since I can write {50, 03, 00, 00} on the Interrupt EP IN :
BYTE smcSlotStatusChange (void) { BYTE msg[4]; msg[0] = RDR_to_PC_NotifySlotChange; //bMessageType : 50 msg[1] = 0x03; //bmSlotICCstate 00000011 - slot 0 status changed and slot 0 current state is ICC present (manual that I linked page 56) EP1DataSnd.pData = msg; EP1DataSnd.Count = 4; USB_DataInStage1(); //write to the EP IN 0x81 return 0; }
The host respond successfully with the telegram {63, 00, 00, 00, 00, 00, 01, 00, 00, 00} (PC_to_RDR_ICCPowerOff).
Then I successfully sended the RDR_to_PC_Slotstatus in the Bulk IN (0x82) {81, 00, 00, 00, 00, 00, 01, 01, 00, 01}
The host respond successfully with the telegram {62, 00, 00, 00, 00, 00, 02, 00, 00, 00} (PC_to_RDR_ICCPowerON).
THEN I TRIED TO SEND A RDR_to_PC_Datablock but the host doesn't catch it! I tried with the telegramms: BYTE FirstDataBlock[14] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xXX, 0x40, 0xFE, 0x00}; // BYTE FirstDataBlock[14] = {0x80, 0x04, 0x00, 0x00, 0x00, 0xXX, 0xFF, 0x40, 0xFE, 0x00, 0x03, 0x00, 0x00,0x00};
where 0xXX ist the last BULK-OUT received bSeq BYTE but the Host does'nt take it! I can't see it on the USBLYzer!
Has anybody an Idea about it?
Here the protocol functions:
void smcDispatchMessage() { BYTE ErrorCode; //Initialize the pointers UsbMessageBuffer = EP2DataRcv.pData; UsbInMessageBuffer = EP2DataRcv.pData; switch (*UsbMessageBuffer) { case PC_to_RDR_IccPowerOn: //0x62 ErrorCode = PC_to_RDR_IccPowerON(); smcDataBlock(ErrorCode, FirstDataBlock); break; case PC_to_RDR_IccPowerOff: //0x63 ErrorCode = PC_to_RDR_IccPowerOFF(); smcSlotStatus(ErrorCode, IccPowerON); break; } } Thanks in advance!
In the first place, is smcDispatchMessage() called from the main line (or timered) polling loop? Or USB_EndPoint2( USB_EVT_OUT ) (ie. EP2 ISR) calls the routine?
Either will do, But depending on the strategy you apply, the code flow differs significantly. This isn't directly concerned to current problem, but this code has another problem.
void USB_DataInStage2 (void) { ... if (EP2DataSnd.Count > USB_MAX_PACKET0) { while(temp>USB_MAX_PACKET0) { temp-=USB_MAX_PACKET0; cnt = USB_WriteEP(0x82, EP2DataSnd.pData,USB_MAX_PACKET0); EP2DataSnd.pData += cnt; } cnt = USB_WriteEP(0x82, EP2DataSnd.pData,temp); }
In above code, the large data is split into packets of endpoint wMaxPacketSize. So far, so good. But USB_WriteEP() is repeatedly called without checking buffer empty. It may cause overwrite to the EP buffer.
When USB_EndPoint2( USB_EVT_IN ) is called, it shows the timing in which the EP2 IN buffer goes empty. Raise a flag in USB_EndPoint2(), and poll this flag.
Tsuneo