Jason Engelman
/
BlueUSB
BlueUSB with USB-> SERIAL (CP210x) GPIO pins working.
AutoEvents.cpp
- Committer:
- tecnosys
- Date:
- 2010-04-23
- Revision:
- 0:a14eaa2e1445
File content as of revision 0:a14eaa2e1445:
/* Copyright (c) 2010 Peter Barrett Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* CP210 HubStatusChange Hub:0 Port:1 00010101 ResetPort Hub:0 Port:1 HubStatusChange Hub:0 Port:1 00100103 Connect Hub:0 Port:1 full Class 00 found 10C4:EA60 AddEndpoint D:01 A:01 T:02 P:0040 I:00 LoadDevice 1 FF:00:00 1: Silicon Labs 2: CP2103 USB to UART Bridge Controller //// CP210 HubStatusChange Hub:0 Port:1 00010101 ResetPort Hub:0 Port:1 HubStatusChange Hub:0 Port:1 00100103 Connect Hub:0 Port:1 full Class 00 found 10C4:EA60 AddEndpoint D:01 A:00 T:00 P:0040 I:00 AddEndpoint D:01 A:81 T:02 P:0040 I:00 AddEndpoint D:01 A:01 T:02 P:0040 I:00 LoadDevice 1 FF:00:00 1: Silicon Labs 2: CP2103 USB to UART Bridge Controller /// FTDI HubStatusChange Hub:0 Port:1 00010101 ResetPort Hub:0 Port:1 HubStatusChange Hub:0 Port:1 00100103 Connect Hub:0 Port:1 full Class 00 found 0403:6001 AddEndpoint D:01 A:00 T:00 P:0008 I:00 AddEndpoint D:01 A:81 T:02 P:0040 I:00 AddEndpoint D:01 A:02 T:02 P:0040 I:00 LoadDevice 1 FF:FF:FF 1: FTDI 2: FT232R USB UART // mouse HubStatusChange Hub:0 Port:1 00010301 ResetPort Hub:0 Port:1 HubStatusChange Hub:0 Port:1 00100303 Connect Hub:0 Port:1 slow Class 00 found 046D:C019 AddEndpoint D:01 A:00 T:00 P:0008 I:00 Skipping descriptor 21 (9 bytes) AddEndpoint D:01 A:81 T:03 P:0005 I:0A LoadDevice 1 03:01:02 1: Logitech 2: Logitech USB Optical Mouse Auto Event for 81 00030102 usbhd HubStatusChange Hub:0 Port:1 00010101 ResetPort Hub:0 Port:1 HubStatusChange Hub:0 Port:1 00100103 Connect Hub:0 Port:1 full Class 00 found 1E3D:2088 AddEndpoint D:01 A:00 T:00 P:0040 I:00 AddEndpoint D:01 A:01 T:02 P:0040 I:00 AddEndpoint D:01 A:81 T:02 P:0040 I:00 LoadDevice 1 08:06:50 1: V88 2: V88 Dumping root dir _START~1.HTM 256 AUTORUN.INF 256 desktop.ini 256 STARTH~1.HTM 256 html 256 some tplink shit usb 54mbit wireless sChange Hub:0 Port:1 00010101 ResetPort Hub:0 Port:1 HubStatusChange Hub:0 Port:1 00100103 Connect Hub:0 Port:1 full Class 00 found 148F:2573 AddEndpoint D:01 A:00 T:00 P:0040 I:00 AddEndpoint D:01 A:81 T:02 P:0040 I:00 AddEndpoint D:01 A:01 T:02 P:0040 I:00 LoadDevice 1 FF:FF:FF 1: Ralink 2: 54M.USB....... */ #include "mbed.h" #include "USBHost.h" #include "Utils.h" //#include "CP2103.h" /* Config request types */ #define REQTYPE_HOST_TO_DEVICE 0x40 #define REQTYPE_DEVICE_TO_HOST 0xc0 /* Config request codes */ #define CP210X_SPECIFIC 0xFF /* CP210X_SPECIFIC */ #define GPIO_WRITE 0x37E1 #define GPIO_READ 0x00C2 #define PORT_CONFIG 0x370C #define WRITE_VID 0x3701 #define WRITE_PID 0x3702 #define WRITE_PRODUCT 0x3703 #define WRITE_SERIAL 0x3704 #define WRITE_POWER 0x3706 #define WRITE_RELEASE 0x3707 /* CP210X_IFC_ENABLE */ #define UART_ENABLE 0x0001 #define UART_DISABLE 0x0000 #define CP210X_IFC_ENABLE 0x00 #define CP210X_GPIO0 (1<<0) #define CP210X_GPIO1 (1<<1) #define CP210X_GPIO2 (1<<2) #define CP210X_GPIO3 (1<<3) struct cp210x_port_state_t { uint16_t mode; uint16_t low_power; uint16_t latch; } ;//cp210x_get_config struct cp210x_port_config_t { struct cp210x_port_state_t reset; /**< Port state applied on after reset. */ struct cp210x_port_state_t suspend; /**< Port state applied on suspend. */ unsigned char enhanced_fxn; /**< Enable/disable enhanced port functions. */ } ;//__attribute__ ((packed)); typedef struct { char *device_name; uint8_t input; /**< Mask of GPIOs to be configured as inputs. */ uint8_t output; /**< Mask of GPIOs to be configured as outputs. */ uint8_t hi; /**< Mask of GPIOs to be set. */ uint8_t lo; /**< Mask of GPIOs to be cleared. */ uint8_t toggle; /**< Mask of GPIOs to be toggled. */ int dump; /**< Dump structures. */ } config_t; static const char *pin_names[] = { "RI", "DCD", "DTR", "DSR", "TXD", "RXD", "RTS", "CTS", "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3", "reserved", "reserved", "SUSPEND", "/SUSPEND" }; static const char *fxn_names[] = { "GPIO_0_TXLED", "GPIO_1_RXLED", "GPIO_2_RS485", "reserved", "WEAKPULLUP_RESET", "WEAKPULLUP_SUSPEND", "SERIAL_DYNAMIC_SUSPEND", "GPIO_DYNAMIC_SUSPEND" }; #define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol) #define AUTO_KEYBOARD AUTOEVT(CLASS_HID,1,1) #define AUTO_MOUSE AUTOEVT(CLASS_HID,1,2) u8 auto_mouse[4]; // buttons,dx,dy,scroll u8 auto_keyboard[8]; // modifiers,reserved,keycode1..keycode6 u8 auto_joystick[4]; // x,y,buttons,throttle void AutoEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData) { int evt = (int)userData; switch (evt) { case AUTO_KEYBOARD: printf("AUTO_KEYBOARD "); break; case AUTO_MOUSE: printf("AUTO_MOUSE "); break; default: printf("HUH "); } printfBytes("data",data,len); USBInterruptTransfer(device,endpoint,data,len,AutoEventCallback,userData); } // Establish transfers for interrupt events void AddAutoEvent(int device, InterfaceDescriptor* id, EndpointDescriptor* ed) { if ((ed->bmAttributes & 3) != ENDPOINT_INTERRUPT || !(ed->bEndpointAddress & 0x80)) return; // Make automatic interrupt enpoints for known devices u32 evt = AUTOEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol); u8* dst = 0; int len; switch (evt) { case AUTO_MOUSE: dst = auto_mouse; len = sizeof(auto_mouse); break; case AUTO_KEYBOARD: dst = auto_keyboard; len = sizeof(auto_keyboard); break; default: printf("Interrupt endpoint %02X %08X\n",ed->bEndpointAddress,evt); break; } if (dst) { printf("Auto Event for %02X %08X\n",ed->bEndpointAddress,evt); USBInterruptTransfer(device,ed->bEndpointAddress,dst,len,AutoEventCallback,(void*)evt); } } void PrintString(int device, int i) { u8 buffer[256]; int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,i,buffer,255); if (le < 0) return; char* dst = (char*)buffer; for (int j = 2; j < le; j += 2) *dst++ = buffer[j]; *dst = 0; printf("%d:%s\n",i,(const char*)buffer); } // Walk descriptors and create endpoints for a given device int StartAutoEvent(int device, int configuration, int interfaceNumber) { u8 buffer[255]; int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255); if (err < 0) return err; int len = buffer[2] | (buffer[3] << 8); u8* d = buffer; u8* end = d + len; while (d < end) { if (d[1] == DESCRIPTOR_TYPE_INTERFACE) { InterfaceDescriptor* id = (InterfaceDescriptor*)d; if (id->bInterfaceNumber == interfaceNumber) { d += d[0]; while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE) { if (d[1] == DESCRIPTOR_TYPE_ENDPOINT) AddAutoEvent(device,id,(EndpointDescriptor*)d); d += d[0]; } } } d += d[0]; } return 0; } // Implemented in main.cpp int OnDiskInsert(int device); // Implemented in TestShell.cpp int OnBluetoothInsert(int device); static int cp210x_set_config(int device, u8 request, unsigned int *data, int size) { /* result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, 0, buf, size, 300); */ return USBControlTransfer(device, REQTYPE_HOST_TO_DEVICE, request, 0x0000, 0, (u8*)data, sizeof(*data),0); } void print_bits8( const uint8_t value ) { int i = 7; printf("b"); do { printf("%c", value & (1<<i) ? '1' : '0'); } while( i-- ); } void print_bits16( const uint16_t value ) { int i = 15; printf("b"); do { printf("%c", value & (1<<i) ? '1' : '0'); } while( i-- ); } int cp210x_get_port_config(int device,struct cp210x_port_config_t *data) { int result; /* Issue the request, attempting to read 'size' bytes */ //result = cp2103_usb_control_msg( // CP210X_SPECIFIC, REQTYPE_DEVICE_TO_HOST, PORT_CONFIG, 0, // data, sizeof(*data)); result = USBControlTransfer(device, REQTYPE_DEVICE_TO_HOST, CP210X_SPECIFIC, PORT_CONFIG, 0, (u8*)data, sizeof(*data),0); if (result != sizeof(*data)) { printf("Unable to get port_config, result = %d", result); return -1; } printf("reset: mode = 0x%04X, low_power = 0x%04X, latch = 0x%04X" " - supend: mode = 0x%04X, low_power = 0x%04X, latch = 0x%04X" " - enhanced_fxn: 0x%02X", data->reset.mode, data->reset.low_power, data->reset.latch, data->suspend.mode, data->suspend.low_power, data->suspend.latch, data->enhanced_fxn ); return 0; } int cp210x_set_port_config(int device,struct cp210x_port_config_t *data) { int result; printf("reset: mode = 0x%04X, low_power = 0x%04X, latch = 0x%04X" " - supend: mode = 0x%04X, low_power = 0x%04X, latch = 0x%04X" " - enhanced_fxn: 0x%02X", data->reset.mode, data->reset.low_power, data->reset.latch, data->suspend.mode, data->suspend.low_power, data->suspend.latch, data->enhanced_fxn ); /* Issue the request, attempting to read 'size' bytes */ // result = cp2103_usb_control_msg( // CP210X_SPECIFIC, REQTYPE_HOST_TO_DEVICE, PORT_CONFIG, 0, // data, sizeof(*data)); result = USBControlTransfer(device, REQTYPE_HOST_TO_DEVICE, CP210X_SPECIFIC, PORT_CONFIG, 0, (u8*)data, sizeof(*data),0); if (result != sizeof(*data)) { printf("Unable to set port_config, result = %d", result); return -1; } return 0; } static int cp210x_set_config_single(int device, u8 request, unsigned int data) { return cp210x_set_config(device, request, &data, 2); } static int cp210x_read_gpio(int device, int offset) { int result; u8 *data; /* Issue the request, attempting to read 'size' bytes */ //result = cp210x_control_msg(serial, // CP210X_SPECIFIC, REQTYPE_DEVICE_TO_HOST, GPIO_READ, // 0, data, sizeof(*data)); result = USBControlTransfer(device, REQTYPE_DEVICE_TO_HOST, CP210X_SPECIFIC, GPIO_READ, 0, (u8*)data, sizeof(*data),0); if (result != sizeof(*data)) { printf("%s: Unable to read gpio latch, "); return -1; } printf("\n\rread latch value = 0x%02X", *data); print_bits8(*data); return 0;// data & (1<<(offset & 0x0F)); } static int cp210x_write_gpio(int device, const u8 mask, const u8 value) { int result; printf("writing to latch mask = 0x%02X, value = 0x%02X", mask, value); //result = cp210x_control_msg(serial, // CP210X_SPECIFIC, REQTYPE_HOST_TO_DEVICE, GPIO_WRITE, // (value << 8) | mask, NULL, 0); u8 val = (value << 8)| mask ; result = USBControlTransfer(device, REQTYPE_HOST_TO_DEVICE, CP210X_SPECIFIC, GPIO_WRITE, (value << 8)| mask, 0, NULL,0); if (result < 0) { printf( "%s: Unable to write into gpio latch, "); return -1; } return 0; } static void cp210x_gpio_set(int device, unsigned offset, int value) { (void)cp210x_write_gpio(device, (1<<(offset & 0x0F)), value ? 0xFF : 0x00); } static int cp210x_gpio_input_mask(int device, u8 mask) { struct cp210x_port_config_t config = {}; int result; mask &= 0x0F; /* configure masked gpio as open-drain and set masked latch bits */ result = cp210x_get_port_config(device, &config); if (result == 0) { config.reset.mode &= ~(((u16)mask)<<8); config.reset.latch |= ((u16)mask)<<8; config.suspend.mode &= ~(((u16)mask)<<8); config.suspend.latch |= ((u16)mask)<<8; result = cp210x_set_port_config(device, &config); } return result; } static int cp210x_gpio_output_mask(int device, u8 mask) { struct cp210x_port_config_t config = {}; int result; mask &= 0x0F; /* configure masked gpio as push-pull */ result = cp210x_get_port_config(device, &config); if (result == 0) { config.reset.mode |= ((u16)mask)<<8; config.suspend.mode |= ((u16)mask)<<8; result = cp210x_set_port_config(device, &config); } return result; } void dump_port_config( const struct cp210x_port_config_t config ) { int i; printf("--- Dump of port configuration --- \n\r"); printf("Raw data:\n\r"); printf("reset.mode = 0x%04X ", config.reset.mode); print_bits16(config.reset.mode); printf("\n\r"); printf("reset.low_power = 0x%04X ", config.reset.low_power); print_bits16(config.reset.low_power); printf("\n\r"); printf("reset.latch = 0x%04X ", config.reset.latch); print_bits16(config.reset.latch); printf("\n\r"); printf("suspend.mode = 0x%04X ", config.suspend.mode); print_bits16(config.suspend.mode); printf("\n\r"); printf("suspend.low_power = 0x%04X ", config.suspend.low_power); print_bits16(config.suspend.low_power); printf("\n\r"); printf("suspend.latch = 0x%04X ", config.suspend.latch); print_bits16(config.suspend.latch); printf("\n\r"); printf("enhanced_fxn = 0x%02X ", config.enhanced_fxn); print_bits8(config.enhanced_fxn); printf("\n\r"); printf("\n\r"); printf("Configuration applied on after reset / suspend (mode, low_power, latch):\n\r"); for ( i=0; i<16; i++ ) { printf("%-20s %s %s/%s %c/%c %c/%c\n\r", pin_names[i], ((config.reset.mode & (1<<i)) == 0 && (config.reset.latch & (1<<i))) ? "IN " : "OUT", (config.reset.mode & (1<<i)) ? " Push-Pull" : "Open-Drain", (config.suspend.mode & (1<<i)) ? "Push-Pull " : "Open-Drain", (config.reset.low_power & (1<<i)) ? '1' : '0', (config.suspend.low_power & (1<<i)) ? '1' : '0', (config.reset.latch & (1<<i)) ? '1' : '0', (config.suspend.latch & (1<<i)) ? '1' : '0'); } printf("\n\r"); printf("Enhanced functions:\n\r"); for ( i=0; i<8; i++ ) { printf("%-24s %s\n\r", fxn_names[i], (config.enhanced_fxn & (1<<i)) ? "ENABLED" : "DISABLED"); } printf("--- End of Dump --- \n\r"); printf("\n\r"); } int OnCP210xInsert(int device) { printf("CP210x inserted of %d\n",device); struct cp210x_port_config_t *data; int result; u16 *tes; result = cp210x_get_port_config( device,data); // for (i = 0; i < sizeof(*data); i++) // data[i] = le32_to_cpu(data[i]); printf("reset: mode = 0x%04X, low_power = 0x%04X, latch = 0x%04X" " - supend: mode = 0x%04X, low_power = 0x%04X, latch = 0x%04X" " - enhanced_fxn: 0x%02X --------------------------------------------------", data->reset.mode, data->reset.low_power, data->reset.latch, data->suspend.mode, data->suspend.low_power, data->suspend.latch, data->enhanced_fxn ); printf(" HERE \n\r"); dump_port_config(*data); // if (cp210x_set_config_single(device, CP210X_IFC_ENABLE, UART_ENABLE)) { // printf(" Unable to enable UART\n"); // } cp210x_gpio_output_mask(device,0xf); cp210x_read_gpio(device,0);cp210x_read_gpio(device,1);cp210x_read_gpio(device,2);cp210x_read_gpio(device,3); cp210x_gpio_set(device,0,0xff); cp210x_gpio_set(device,1,0x0); cp210x_gpio_set(device,2,0xff); cp210x_gpio_set(device,3,0x0); // cp210x_gpio_set(device,2,0xff); // cp210x_gpio_set(device,3,0xf); cp210x_read_gpio(device,0);cp210x_read_gpio(device,1);cp210x_read_gpio(device,2);cp210x_read_gpio(device,3); printf(" HERE2 \n\r"); result = cp210x_get_port_config( device,data); dump_port_config(*data); return 0; } int OnFTDIInsert(int device); void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) { printf("LoadDevice %d %02X:%02X:%02X\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol); char s[128]; for (int i = 1; i < 3; i++) { if (GetString(device,i,s,sizeof(s)) < 0) break; printf("%d: %s\n",i,s); } switch (interfaceDesc->bInterfaceClass) { case CLASS_MASS_STORAGE: if (interfaceDesc->bInterfaceSubClass == 0x06 && interfaceDesc->bInterfaceProtocol == 0x50) OnDiskInsert(device); // it's SCSI! break; case CLASS_WIRELESS_CONTROLLER: if (interfaceDesc->bInterfaceSubClass == 0x01 && interfaceDesc->bInterfaceProtocol == 0x01) OnBluetoothInsert(device); // it's bluetooth! break; case CLASS_VENDOR_SPECIFIC: //Silicon Labs CP210x if (interfaceDesc->bInterfaceSubClass == 0x00 && interfaceDesc->bInterfaceProtocol == 0x00) { OnCP210xInsert(device); } //FTDI Serial if (interfaceDesc->bInterfaceSubClass == 0xFF && interfaceDesc->bInterfaceProtocol == 0xFF) OnFTDIInsert(device); break; default: StartAutoEvent(device,1,0); break; } }