USB HID String descriptor issue

04 Sep 2011

Good evening, I am working with program USB HID Joystick http://mbed.org/users/bricklife/programs/USBJoystick/ll8vnv based on USB HID Mouse. My target was to add String descriptor which is as TODO list in both programs and is located in USBhid.cpp.

Original code part is :

bool usbhid::requestGetDescriptor(void)
{
    bool success = false;
        
    switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
    {
        case DEVICE_DESCRIPTOR:
            transfer.remaining = sizeof(deviceDescriptor);
            transfer.ptr = deviceDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;
            break;
        case CONFIGURATION_DESCRIPTOR:
            transfer.remaining =  sizeof(configurationDescriptor);
            transfer.ptr = configurationDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;
            break;

        case STRING_DESCRIPTOR: /*-------------------------I am trying to add functionality here----------------*/


        case INTERFACE_DESCRIPTOR:
        case ENDPOINT_DESCRIPTOR:
            /* TODO: Support is optional, not implemented here */
            break;
        case HID_DESCRIPTOR:
            transfer.remaining = 0x09; /* TODO: Fix hard coded size/offset */
            transfer.ptr = &configurationDescriptor[18];
            transfer.direction = DEVICE_TO_HOST;
            success = true;            
            break;
        case REPORT_DESCRIPTOR:
            transfer.remaining = sizeof(reportDescriptor);
            transfer.ptr = reportDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;            
            break;
        default:
            break;    
    }
    
    return success;
}

So I created my own string descriptor based on example I found on keil.com

unsigned char stringDescriptor[] = {
/* Index 0x00: LANGID Codes */
  0x04,                              /* bLength */
  bDESC_TYPE_STRING,        /* bDescriptorType */
  AWBVAL(0x0409), /* US English */    /* wLANGID */
/* Index 0x04: Manufacturer */
  0x1C,                              /* bLength */
  bDESC_TYPE_STRING,        /* bDescriptorType */
  'N',0,
  'X',0,
  'P',0,
  ' ',0,
  'S',0,
  'E',0,
  'M',0,
  'I',0,
  'C',0,
  'O',0,
  'N',0,
  'D',0,
  ' ',0,
/* Index 0x20: Product */
  0x22,                              /* bLength */
  bDESC_TYPE_STRING,        /* bDescriptorType */
  'L',0,
  'P',0,
  'C',0,
  '1',0,
  '7',0,
  'x',0,
  'x',0,
  ' ',0,
  'H',0,
  'I',0,
  'D',0,
  ' ',0,
  ' ',0,
  ' ',0,
  ' ',0,
  ' ',0,
/* Index 0x42: Serial Number */
  0x1A,                              /* bLength */
  bDESC_TYPE_STRING,        /* bDescriptorType */
  'D',0,
  'E',0,
  'M',0,
  'O',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
/* Index 0x5C: Interface 0, Alternate Setting 0 */
  0x08,                              /* bLength */
  bDESC_TYPE_STRING,        /* bDescriptorType */
  'H',0,
  'I',0,
  'D',0,
};

And modified part of code mentoied above to this:

bool usbhid::requestGetDescriptor(void)
{
    bool success = false;
        
    switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
    {
        case DEVICE_DESCRIPTOR:
            transfer.remaining = sizeof(deviceDescriptor);
            transfer.ptr = deviceDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;
            break;
        case CONFIGURATION_DESCRIPTOR:
            transfer.remaining =  sizeof(configurationDescriptor);
            transfer.ptr = configurationDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;
            break;


        case STRING_DESCRIPTOR:                  /*------------------modified this part to look like other cases---------*/
        transfer.remaining =  sizeof(stringDescriptor);
            transfer.ptr = stringDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;
            break;

        
        case INTERFACE_DESCRIPTOR:
        case ENDPOINT_DESCRIPTOR:
            /* TODO: Support is optional, not implemented here */
            break;
        case HID_DESCRIPTOR:
            transfer.remaining = 0x09; /* TODO: Fix hard coded size/offset */
            transfer.ptr = &configurationDescriptor[18];
            transfer.direction = DEVICE_TO_HOST;
            success = true;            
            break;
        case REPORT_DESCRIPTOR:
            transfer.remaining = sizeof(reportDescriptor);
            transfer.ptr = reportDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;            
            break;
        default:
            break;    
    }
    
    return success;
}

Program compiles without any warnings or errors but if I use SimpleHIDwrite utility I see this:

/media/uploads/llumpu/badstringdescriptor.png

As You can see LangID is correctly recognised as english (string with offset 0x00) but iMANUFACTURER and iPRODUCT strings are not recognised and in the name of device appears "?" instead of iPRODUCT.

I also found that if I use this tool on my mouse it lists only strings that have to appear (iMANUFACTURER string1, iPRODUCT string2, etc) but in my test appears String1 "?", String2 "?" up to string255. But I only define 4 strings.

Good list of strings from my mouse looks like this:

/media/uploads/llumpu/goodstringdescriptor.png

I also defined offset for strings in device descriptor:

 0x00,                    /* bcdDevice (LSB) */
    0x00,                    /* bcdDevice (MSB) */
    0x04,                   /* iManufacturer */
    0x20,                   /* iProduct */
    0x42,                  /* iSerialNumber */
    0x01,                    /* bNumConfigurations */

I would like to ask You for any ideas what is wrong and why. Without changing code in SWITCH for STRING_DESCRIPTOR there was no langID recognised in SimpleHIDwrite tool so code +- works but there is something wrong.

Here are some used defines from start of page. All seems to be OK.

#define bDESC_TYPE_STRING (3)
#define HID_CLASS         (3)
#define HID_SUBCLASS_NONE (0)
#define HID_PROTOCOL_NONE (0)
#define HID_DESCRIPTOR    (33)
#define REPORT_DESCRIPTOR (34)
#define STRING_DESCRIPTOR (3)
#define AWBVAL(x) (x & 0xFF),((x >> 8) & 0xFF)

Thank everybody for any help. I am trying to get it work whole day but without success. I am sorry of my english.

06 Sep 2011

Hello, does have anybody an idea about how to get HID STRING descriptor working with mbed as USB hid device? I am still not able to get it working. Tried many changes in desriptor itself, tried changes in offset which is set in device descriptor in iMANUFACTURER, iPRODUCT and iSERIALNUMBER but still with no success. Can anybody help, please?

06 Sep 2011

Hi

Did you know the strings have to be unicode?

The length is the number of bytes and not the number of characters.

In your case it might be the bytes in the unicode characters are swapped. \0 tends to show up as a ? mark.

wvd_vegt

06 Sep 2011

Have you got HID Device to work, as a simple HID Interface, not mouse/Keyboard/joystick etc.

I have been looking for a long time to upgrade my PIC18f4550 HW/SW

If so can you publish some code, or let me know how to do it :)

Cheers

Ceri

06 Sep 2011

Hi

Sorry last usb code i did was 5-6 years agoo and based on cypress cpu for usb 1.1 low speed.

Curently i have a more urgent project i need to finish but if i find some time, i will sure try to code something.

Wvd_vegt

08 Sep 2011

Hey little llumpu,

It's funny, without reading your forum post, we basically have gone through the same steps as you, and haven't got it working either... :(

Maybe somebody with more USB experience can chime in?

Cheers!

08 Sep 2011

Hello, as mentoied @Wvd_vegt, Text string must be unicode 16 coding so maybe writing 'L',0, 'P',0,'C',0, etc... isn't recognised as unicode encoding by windows. @Wvd_vegt also mentoied that there should be swapped bytes in string so maybe 0,'L',0,'P',.... should be right. Also maybe offset which is set in device descriptor in iMANUFACTURER, iPRODUCT and iSERIALNUMBER is missplaced and have to be changed. Maybe host ask for string with other offset (0,1,2,3...) as mentoied at USB.org. But all looks good and is adopted from keil.com for LPC1768 HID device program. Also maybe the problem should be in code where descriptor is delivered to host.

case STRING_DESCRIPTOR:                  /*------------------modified this part to look like other cases---------*/
        transfer.remaining =  sizeof(stringDescriptor);
            transfer.ptr = stringDescriptor;
            transfer.direction = DEVICE_TO_HOST;
            success = true;
            break;

I think I tried all possible combinations but still no success.

So maybe anybody with more USB HID experience should be able to point us to right way. Maybe somebody of mbed staff. I think it is very fine if here will be fully working USB HID stack with all things working like string descriptor, alternate configuration descriptors, alternate settings, IN OUT(joystick feedback) endpoints, set feature, get feature... There is example of working keyboard, mouse and joystick but what about other classes. For example mbed with RN 42 bluetooth as USB bluetooth 'dongle'. I will try but I am newbie...

08 Sep 2011

Hi

I can see the byte order it at home where I keep the asm list files of my old usb project. Hopefully I'll think of looking at it tonight.

wvd_vegt

08 Sep 2011

Thank You, Wim van der Vegt, I am very pleased that You want to help us.

08 Sep 2011

Hi,

Can you share your code?

wvd_vegt

08 Sep 2011

Hi,

Just had a look at the cypress sources on http://www.lvr.com/files/usbhidio.zip

The asm listing listing looks like:

0452            USBStringDescription1:     ; IManufacturerName
0452 1A    [00]     db 1Ah          ; Length
0453 03    [00]     db 03h          ; Type (3=string)
0454 55 00 ...      dsu "USB Complete" ;
     53 00 42 00 20 00 43 00 6F 00 6D 00 70 00 6C 00 65 00 74 00 65 00

So your unicode byte order seems to be ok.

But Looking at your code it seems like the lines:

transfer.remaining =  sizeof(stringDescriptor);
transfer.ptr = stringDescriptor;

are suspected. You return a pointer to your stringDescriptor array and not the individual strings (ie the bLength byte). The string at index 0 is a special one describing the languages supported.

The pointer should be the start of a string descriptor (and not all), Although from the assembly listing it seems to be an offset somehow (altough I cannot remember). It is certainly not unicode. The length to be returned is the length if the single descriptor and not all strings.

So you should:

1) cut your stringDescriptor into several desciptors, one for each string 2) use pointer to the appropriate string 3) use the length of that string. 4) for testing not use string 0 as it's not unicode at all but binary.

Hope this solves your problem.

Some asm code:

; Get Descriptor (string)               wValueHi = 3
     cmp A, string
     jz GetStringDescriptor

GetStringDescriptor:
;Use the string index to find out which string it is.
     mov A, [wValue]
     cmp A, 0h
     jz LanguageString      // String #0 is a special one and NOT unicode but binary.
     cmp A, 01h
     jz ManufacturerString  // String #1 is the IManufacturerName
     cmp A, 02h
     jz ProductString       // String #2 is the IProduct

ManufacturerString:     
     mov A, ( USBStringDescription2 - USBStringDescription1) //Length
      mov [data_count], A
     mov A, (USBStringDescription1 - control_read_table)     //Offset, maybe a cypress feature?
      jmp SendDescriptor

wvd_vegt

08 Sep 2011

Hi,

Forgot to clearify: you always return only the requested string and not the whole string table.

wvd_vegt

08 Sep 2011

Hello, thank @wvd_vegt, I am very near resolving this. There only left minor problem i think I will resolve too. When done, I will publish my code here.

08 Sep 2011

Hello, I have a good news. I got STRING DESCRIPTOR working. Based on posts from Wim van der Vegt and info found at USB.org I was able to get mbed introduce to USB host not only with VID & PID but also with name of Manufacturer, Product name, Serial Number, Configuration number and interface name.

So I cut STRING DESCRIPTOR array to multiple STRING DESCRIPTORS arrays each for one string in USBhid.cpp:

unsigned char stringLangidDescriptor[] = {
    0x04,                                                   /*bLength - must match size of stringLangidDescriptor array (always 4 bytes - hex 0x04) */
    STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
    0x09,0x00,                                              /*bString Lang ID - 0x009 - English*/
    };
    
    unsigned char stringImanufacturerDescriptor[] = {
    0x12,                                                   /*bLength must match size of stringImanufacturerDescriptor array (here 18 bytes - hex 0x12) */
    STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
    'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0,        /*bString iManufacturer - mbed.org*/
    };
    
    unsigned char stringIproductDescriptor[] = {
    0x12,                                                   /*bLength must match size of stringIproductDescriptor array (here 18 bytes - hex 0x12) */
    STRING_DESCRIPTOR,                                      /*bDescriptorType 0x03*/
    'm',0,'b',0,'e',0,'d',0,' ',0,'H',0,'I',0,'D',0,        /*bString iProduct - mbed HID*/
    };
    
    unsigned char stringIserialDescriptor[] = {
    0x16,                                                           /*bLength must match size of stringIserialDescriptor array (here 22 bytes - hex 0x16) */
    STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
    '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0,    /*bString iSerial - 0123456789*/
    };
   
    unsigned char stringIconfigurationDescriptor[] = {
    0x06,                                                           /*bLength must match size of stringIconfigurationDescriptor array (here 6 bytes - hex 0x06) */
    STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
    '0',0,'1',0,                                                    /*bString iConfiguration - 01*/
    };

    unsigned char stringIinterfaceDescriptor[] = {
    0x08,                                                           /*bLength must match size of stringIinterfaceDescriptor array (here 8 bytes - hex 0x08) */
    STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
    'H',0,'I',0,'D',0,                                              /*bString iInterface - HID*/
    };

Then i defined string offset (which string will be send for each ask from host in USBdevice.h:

/*string offset*/
#define STRING_OFFSET_LANGID            (0) 
#define STRING_OFFSET_IMANUFACTURER     (1)
#define STRING_OFFSET_IPRODUCT          (2)
#define STRING_OFFSET_ISERIAL           (3)
#define STRING_OFFSET_ICONFIGURATION    (4)
#define STRING_OFFSET_IINTERFACE        (5)

And used this offset in definition of DEVICE DESCRIPTOR and CONFIGURATION DESCRIPTOR in USBhid.cpp:

/* Descriptors */
unsigned char deviceDescriptor[] = {
    0x12,                           /* bLength */
    DEVICE_DESCRIPTOR,              /* bDescriptorType */
    0x00,                           /* bcdUSB (LSB) */
    0x02,                           /* bcdUSB (MSB) */
    0x00,                           /* bDeviceClass */
    0x00,                           /* bDeviceSubClass */
    0x00,                           /* bDeviceprotocol */
    MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
    0x28,                           /* idVendor (LSB) */
    0x0d,                           /* idVendor (MSB) */
    0x05,                           /* idProduct (LSB) */
    0x02,                           /* idProduct (MSB) */
    0x00,                           /* bcdDevice (LSB) */
    0x00,                           /* bcdDevice (MSB) */
    STRING_OFFSET_IMANUFACTURER,    /* iManufacturer */
    STRING_OFFSET_IPRODUCT,         /* iProduct */
    STRING_OFFSET_ISERIAL,          /* iSerialNumber */
    0x01                            /* bNumConfigurations */
    };
    
unsigned char configurationDescriptor[] = {
    0x09,                        /* bLength */
    CONFIGURATION_DESCRIPTOR,    /* bDescriptorType */
    0x09+0x09+0x09+0x07,         /* wTotalLength (LSB) */
    0x00,                        /* wTotalLength (MSB) */
    0x01,                        /* bNumInterfaces */
    0x01,                        /* bConfigurationValue */
    STRING_OFFSET_ICONFIGURATION,/* iConfiguration */
    0xc0,                        /* bmAttributes */
    0x00,                        /* bMaxPower */
    
    0x09,                        /* bLength */
    INTERFACE_DESCRIPTOR,        /* bDescriptorType */    
    0x00,                        /* bInterfaceNumber */
    0x00,                        /* bAlternateSetting */
    0x01,                        /* bNumEndpoints */
    HID_CLASS,                   /* bInterfaceClass */
    HID_SUBCLASS_NONE,           /* bInterfaceSubClass */
    HID_PROTOCOL_NONE,           /* bInterfaceProtocol */
    STRING_OFFSET_IINTERFACE,    /* iInterface */
    
    0x09,                        /* bLength */
    HID_DESCRIPTOR,              /* bDescriptorType */
    0x11,                        /* bcdHID (LSB) */
    0x01,                        /* bcdHID (MSB) */
    0x00,                        /* bCountryCode */
    0x01,                        /* bNumDescriptors */
    REPORT_DESCRIPTOR,           /* bDescriptorType */
    0x79,                        /* wDescriptorLength (LSB) */
    0x00,                        /* wDescriptorLength (MSB) */
        
    0x07,                        /* bLength */
    ENDPOINT_DESCRIPTOR,         /* bDescriptorType */
    0x81,                        /* bEndpointAddress */
    0x03,                        /* bmAttributes */
    MAX_PACKET_SIZE_EP1,         /* wMaxPacketSize (LSB) */
    0x00,                        /* wMaxPacketSize (MSB) */
    0x0a,                        /* bInterval */
    };

I found that USB host asks for each string with offset specified in DEVICE & CONFIGURATION DESCRIPTOR mentoied above. This offset is send from host in wINDEX of STRING DESCRIPTOR request. So I found that i have to send each string based on wIndex request and modified case STRING_DESCRIPTOR in switch in USBhid.cpp to this:

 case STRING_DESCRIPTOR:
            switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
                    {
                    case STRING_OFFSET_LANGID:
                        transfer.remaining = sizeof(stringLangidDescriptor);
                        transfer.ptr = stringLangidDescriptor;
                        transfer.direction = DEVICE_TO_HOST;
                        success = true;
                        break;
                    case STRING_OFFSET_IMANUFACTURER:
                        transfer.remaining =  sizeof(stringImanufacturerDescriptor);
                        transfer.ptr = stringImanufacturerDescriptor;
                        transfer.direction = DEVICE_TO_HOST;
                        success = true;
                        break;       
                    case STRING_OFFSET_IPRODUCT:
                        transfer.remaining =  sizeof(stringIproductDescriptor);
                        transfer.ptr = stringIproductDescriptor;
                        transfer.direction = DEVICE_TO_HOST;
                        success = true;
                        break;            
                    case STRING_OFFSET_ISERIAL:
                        transfer.remaining =  sizeof(stringIserialDescriptor);
                        transfer.ptr = stringIserialDescriptor;
                        transfer.direction = DEVICE_TO_HOST;
                        success = true;
                        break;        
                    case STRING_OFFSET_ICONFIGURATION:
                        transfer.remaining =  sizeof(stringIconfigurationDescriptor);
                        transfer.ptr = stringIconfigurationDescriptor;
                        transfer.direction = DEVICE_TO_HOST;
                        success = true;
                        break; 
                    case STRING_OFFSET_IINTERFACE:
                        transfer.remaining =  sizeof(stringIinterfaceDescriptor);
                        transfer.ptr = stringIinterfaceDescriptor;
                        transfer.direction = DEVICE_TO_HOST;
                        success = true;
                        break; 
            }

So I added another switch into case STRING_DESCRIPTOR which selects proper string based on wIndex - (DESCRIPTOR_INDEX(transfer.setup.wValue)) - value recieved from host in GetDescriptor.

Then it worked but there was also problem because these strings was sent multiple times - Strings was 1 iManufacturer, 2 iProduct, 3 iSerial then 17 iManufacturer, 18 iProduct, 19 iSerial etc each 16 up to string 255.

After time I found how to get send only once. There was definition of DESCRIPTOR_INDEX in USBdevice.h (on which I based selection of sent strings in switch) which was:

#define DESCRIPTOR_INDEX(wValue) (wValue & 0xf)

I changed it to:

#define DESCRIPTOR_INDEX(wValue) (wValue & 0xff)

And then everything works like a charm.

I am newbie in electronics and programing (learn from May) so I would like if somebody experienced can look at code an say if it is OK.

Once again I would like to thank Wim van der Vegt who pointed me to right way.

I will add published example bellow.

EDIT: You can use SimpleHIDwrite utility http://www.lvr.com/files/SimpleHIDWrite3.zip to view this strings.

08 Sep 2011

This is example program with USB String Descriptor working

Import programUSBKeyboardMouse_with_String_Descriptor

Based on USBKeyboardMouse example. I added USB String Descriptor so mbed reports itself to host not only with VID & PID but also with name of manufacturer, product name, serial number, configuration number and interface name. These can be changed to matching Yours in USBhid.cpp file on lines 88 - 122.

08 Sep 2011

Hi,

Congrats on getting it to work (and thanks for sharing). Glad to be of help btw.

It took me much more time to figure it out when USB v1.0 was still new and I had only the specs to work with. Once i got the hang of the manual and found the correct chapter to read it all fell into place.

Nice part of the strings is that some show up in the windows device manager (so you device is not longer a gray 'Hid Device').

I've already imported the project!

Btw be carefull supplying serial numbers at all. It's a real pain when you install device drivers from what I remember.

wvd_vegt

08 Sep 2011

Wow, great job!

I'll let you know how it works out with my particular setup after testing this evening...

It would be awesome for the mbed folks to integrate @little llumpu's work into their official USB example :)

Very handy to be able to distinguish connected devices this way.

08 Sep 2011

Is this still a Keyboard/Mouse/Joystick,

or is it a Basic HID Device ?

I am desperate to start using MBED's in at least 4 new projects, to replace PIC18f4550

Equipment.

Ceri

08 Sep 2011

ceri clatworthy wrote:

Is this still a Keyboard/Mouse/Joystick,

or is it a Basic HID Device ?

I am desperate to start using MBED's in at least 4 new projects, to replace PIC18f4550

Equipment.

Ceri

It is still Keyboard/Mouse. Maybe by editing descriptors You can change it to Your match. I am not sure what do You mean by Basic HID. This program describes itself as usb hid device with two reports. So changing the reports should help You to get device You want. The report descriptor makes this device mouse and keyboard. Other descriptors like device, configuration and hid must be set properly too. So if You use descriptors from Your PIC You should reach Your goal. All data which is sent to host is sent from report buffer. Buffer is filled with data with function so You can change it and fill with Your data. I am newbie but I will try... You can try to start forum post BASIC HID where others can help.

08 Sep 2011

I have asked before, in the forum, but with no responses,

I have tried myself, comparing the MBED Keyboard/Mouse, with the equivalent PIC version(s), then with PIC Basic HID, but too confusing.

Cheers Ceri

08 Sep 2011

ceri clatworthy wrote:

I have asked before, in the forum, but with no responses,

I have tried myself, comparing the MBED Keyboard/Mouse, with the equivalent PIC version(s), then with PIC Basic HID, but too confusing.

Cheers Ceri

Please try to post some code with descriptors or links where to find and somebody maybe should be able to give answer.

08 Sep 2011

Hi,

What usb hardware / pins does this program use? Pins 37 & 38?

wvd_vegt

08 Sep 2011

Wim van der Vegt wrote:

Hi,

What usb hardware / pins does this program use? Pins 37 & 38?

wvd_vegt

I connect mbed to USB host via D+, D-, GND and VIN pins on mbed. I think selection of chip pins for usb socket is in USBdc.cpp via:

 /* Configure pins P0.29 and P0.30 to be USB D+ and USB D- */
    LPC_PINCON->PINSEL1 &= 0xc3ffffff;
    LPC_PINCON->PINSEL1 |= 0x14000000;

#ifdef ENABLE_VBUS    
    /* Configure pin P1.30 to be VBUS */
    LPC_PINCON->PINSEL3 &= 0xcfffffff;
    LPC_PINCON->PINSEL3 |= 0x20000000;
    
    /* Configure pin P1.30 to have pull-down */
    LPC_PINCON->PINMODE3 |= 0x30000000;
#endif
        
    /* Configure pin P2.9 to be Connect */
    LPC_PINCON->PINSEL4 &= 0xfffcffff;
    LPC_PINCON->PINSEL4 |= 0x00040000;
    

But I am not sure if it is that what do You mean.

08 Sep 2011

I have used these pins for mouse/keyboard/joystick before. Hope to have MBED development board on Monday, So I can start experimentation again.

Ceri