Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbeh_api.c Source File

usbeh_api.c

00001 /****************************************************************************
00002  *    Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
00003  *    
00004  *    This file is part of the Satellite Observers Workbench (SOWB).
00005  *
00006  *    SOWB is free software: you can redistribute it and/or modify
00007  *    it under the terms of the GNU General Public License as published by
00008  *    the Free Software Foundation, either version 3 of the License, or
00009  *    (at your option) any later version.
00010  *
00011  *    SOWB is distributed in the hope that it will be useful,
00012  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *    GNU General Public License for more details.
00015  *
00016  *    You should have received a copy of the GNU General Public License
00017  *    along with SOWB.  If not, see <http://www.gnu.org/licenses/>.
00018  *
00019  *    $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
00020  *    
00021  ***************************************************************************/
00022  
00023 #include "sowb.h"
00024 #include "usbeh_api.h"
00025 #include "usbeh_endpoint.h"
00026 #include "usbeh_device.h"
00027 #include "usbeh_controller.h"
00028 
00029 #include "main.h"
00030 #include "debug.h"
00031 
00032 /* Device driver headers. */
00033 #include "xbox360gamepad.h"
00034 
00035 #define DEBUG_USB_API 1
00036 
00037 USBEH_device_info_callback usb_devices_callback_map[] = {
00038     (xbox360gamepad_onload_callback),
00039     NULL
00040 };
00041 
00042 int usbeh_no_device_found(int device, USBEH_deviceDescriptor *deviceDesc, USBEH_interfaceDescriptor **interfaceDesc) {
00043     USBEH_interfaceDescriptor *iface;
00044     int interfaceCounter = 0;
00045     debug_printf("%s CALLBACK ACTIVATED for device %d\r\n", __FUNCTION__, device);
00046     debug_printf("  VendorId = %04X ProductId = %04X \r\n", deviceDesc->idVendor, deviceDesc->idProduct);
00047     while ((iface = interfaceDesc[interfaceCounter]) != (USBEH_interfaceDescriptor *)NULL) { 
00048         debug_printf("  interface%d:- \r\n", interfaceCounter);
00049         debug_printf("    InterfaceClass    = %02X \r\n", iface->bInterfaceClass);
00050         debug_printf("    InterfaceSubClass = %02X \r\n", iface->bInterfaceSubClass);
00051         debug_printf("    InterfaceProtocol = %02X \r\n", iface->bInterfaceProtocol);
00052         interfaceCounter++;
00053     }
00054     debug_printf("  No device driver loaded.\r\n");
00055     return 0;
00056 }
00057 
00058 /* Create an instance of the USBEH controller and place
00059    it within the AHB static ram area. */
00060 USBEH_Controller sys_usb_controller __attribute__((at(0x2007C000)));
00061 
00062 
00063 void usbeh_api_on_load_device(int device, USBEH_deviceDescriptor* deviceDesc, USBEH_interfaceDescriptor **interfaceDesc) {
00064     int i, slen, driver_loaded = 0;
00065     char s[3][128];
00066     
00067     memset((char *)s, 0, 3 * 128);
00068     
00069     /* Get device strings. */    
00070     for (i = 1; i < 3; i++) {
00071         slen = usbeh_api_get_string(device, i, s[i - 1], 128);
00072         if (slen < 0) {
00073             break;
00074         }
00075     }
00076  
00077     /* Scan through the device driver onLoad callbacks to see who wants to claim it. */
00078     for (i = 0; usb_devices_callback_map[i] != NULL && driver_loaded == 0; i++) {
00079         driver_loaded = (usb_devices_callback_map[i])(device,deviceDesc,interfaceDesc);
00080     }
00081     
00082     if (driver_loaded == 0) {
00083         usbeh_no_device_found(device, deviceDesc, interfaceDesc);
00084     }
00085 }
00086 
00087 int usbeh_api_init(void) {
00088     DEBUG_INIT_START;
00089     sys_usb_controller.init();
00090     DEBUG_INIT_END;
00091     return 0;
00092 }
00093 
00094 void usbeh_api_process(void) {
00095     sys_usb_controller.process();
00096 }
00097 
00098 int usbeh_api_set_address(int device, int new_addr) {
00099     return usbeh_api_control_transfer(device, USBEH_HOST_TO_DEVICE | USBEH_RECIPIENT_DEVICE, USBEH_SET_ADDRESS, new_addr, 0, 0, 0, 0, 0);
00100 }
00101 
00102 int usbeh_api_get_descriptor(int device, int descType,int descIndex, USBEH_U08* data, int length) {
00103     return usbeh_api_control_transfer(device, USBEH_DEVICE_TO_HOST | USBEH_RECIPIENT_DEVICE, USBEH_GET_DESCRIPTOR, (descType << 8)|(descIndex), 0, data, length, 0, 0);
00104 }
00105 
00106 static USBEH_Setup* usbeh_api_get_setup(int device) {
00107     if (device == 0) {
00108         return &sys_usb_controller.setupZero;
00109     }
00110     
00111     if (device < 1 || device > USBEH_MAX_DEVICES) {
00112         return 0;
00113     }
00114     
00115     return &sys_usb_controller.devices[device-1].setupBuffer;
00116 }
00117 
00118 static int usbeh_api_wait_IO_done(USBEH_Endpoint* endpoint) {
00119 
00120     if (endpoint->currentState == USBEH_Endpoint::notQueued) {
00121         return 0;
00122     }
00123     
00124     while (endpoint->currentState != USBEH_Endpoint::idle) {
00125         usbeh_api_process();
00126     }
00127     
00128     int status = endpoint->status();
00129     if (status == 0) {
00130         return endpoint->length;
00131     }
00132 
00133     #ifdef DEBUG_USB_DRIVER
00134     debug_printf("usbeh_api_wait_IO_done() error with 0x%x at line %d\r\n", status, __LINE__);
00135     #endif
00136     
00137     return -status;
00138 }
00139 
00140 
00141 int usbeh_api_get_port_status(int device, int port, USBEH_U32 *status) {
00142     return usbeh_api_control_transfer_short(device, USBEH_DEVICE_TO_HOST | USBEH_REQUEST_TYPE_CLASS | USBEH_RECIPIENT_OTHER, USBEH_GET_STATUS, 0, port, (USBEH_U08 *)status, 4);    
00143 }
00144 
00145 int usbeh_api_clear_port_feature(int device, int feature, int index) {
00146     return usbeh_api_control_transfer(device, USBEH_HOST_TO_DEVICE | USBEH_REQUEST_TYPE_CLASS | USBEH_RECIPIENT_OTHER, USBEH_CLEAR_FEATURE, feature, index, 0, 0, 0, 0);
00147 }
00148 
00149 int usbeh_api_set_port_power(int device, int port) {
00150     int result = usbeh_api_set_port_feature(device, USBEH_PORT_POWER, port);
00151     USBEH_OS_DELAY_MS(20);
00152     return result;
00153 }
00154 
00155 int usbeh_api_set_port_feature(int device, int feature, int index) {
00156     return usbeh_api_control_transfer(device, USBEH_HOST_TO_DEVICE | USBEH_REQUEST_TYPE_CLASS | USBEH_RECIPIENT_OTHER, USBEH_SET_FEATURE, feature, index, 0, 0, 0, 0);
00157 }
00158 
00159 int usbeh_api_set_configuration(int device, int configNum) {
00160     return usbeh_api_control_transfer(device, USBEH_HOST_TO_DEVICE | USBEH_RECIPIENT_DEVICE, USBEH_SET_CONFIGURATION, configNum, 0, 0, 0, 0, 0);
00161 }
00162 
00163 int usbeh_api_set_port_reset(int device, int port) {
00164     return usbeh_api_set_port_feature(device, USBEH_PORT_RESET, port);
00165 }
00166 
00167 int usbeh_api_get_string(int device, int index, char *dst, int length) {
00168     
00169     USBEH_U08 buffer[255];
00170     
00171     int le = usbeh_api_get_descriptor(device, USBEH_DESCRIPTOR_TYPE_STRING, index, buffer, sizeof(buffer));
00172     
00173     if (le < 0) {
00174         return le;
00175     }
00176     
00177     if (length < 1) {
00178         return -1;
00179     }
00180     
00181     length <<= 1;
00182     
00183     if (le > length) {
00184         le = length;
00185     }
00186     
00187     for (int j = 2; j < le; j += 2) {
00188         *dst++ = buffer[j];
00189     }
00190     
00191     *dst = 0;
00192     
00193     return (le >> 1) - 1;
00194 }
00195 
00196 int usbeh_api_transfer(int device, int ep, USBEH_U08 flags, USBEH_U08 *data, int length, USBEH_callback callback, void *userData) {
00197     USBEH_Endpoint *endpoint = sys_usb_controller.getEndpoint(device, ep);
00198     if (!endpoint) {
00199         #ifdef DEBUG_USB_DRIVER
00200         debug_printf("sys_usb_controller.getEndpoint() failed at line %d\r\n", __LINE__);
00201         #endif
00202         return USBEH_ERR_ENDPOINT_NOT_FOUND;
00203     }
00204         
00205     usbeh_api_wait_IO_done(endpoint);
00206     
00207     endpoint->flags = flags;
00208     endpoint->data = data;
00209     endpoint->length = length;
00210     endpoint->callback = callback;
00211     endpoint->userData = userData;
00212     
00213     if (ep == 0) {
00214         sys_usb_controller.transfer(endpoint, USBEH_TOKEN_SETUP, (USBEH_U08 *)usbeh_api_get_setup(device), 8, USBEH_Endpoint::setupQueued);
00215     }
00216     else {
00217         sys_usb_controller.transfer(endpoint, flags & 0x80 ? USBEH_TOKEN_IN : USBEH_TOKEN_OUT, data, length, USBEH_Endpoint::dataQueued);
00218     }
00219     
00220     if (callback) {
00221         return USBEH_IO_PENDING;
00222     }
00223     
00224     return usbeh_api_wait_IO_done(endpoint);
00225 }
00226 
00227 int usbeh_api_interrupt_transfer(int device, int ep, USBEH_U08 *data, int length, USBEH_callback callback, void *userData) {
00228     return usbeh_api_transfer(device, ep, (ep & 0x80) | USBEH_ENDPOINT_INTERRUPT, data, length, callback, userData);
00229 }
00230 
00231 int usbeh_api_control_transfer_short(int device, int request_type, int request, int value, int index, USBEH_U08 *data, int length) {
00232     return usbeh_api_control_transfer(device, request_type, request, value, index, data, length, 0, 0);
00233 }
00234 
00235 int usbeh_api_control_transfer(int device, int request_type, int request, int value, int index, USBEH_U08 *data, int length, USBEH_callback callback, void *userData) {
00236     USBEH_Setup* setup = usbeh_api_get_setup(device);
00237     if (!setup) {
00238         #ifdef DEBUG_USB_DRIVER
00239         debug_printf("usbeh_api_get_setup() failed at line %d\r\n", __LINE__);
00240         #endif
00241         return USBEH_ERR_DEVICE_NOT_FOUND;
00242     }
00243         
00244     usbeh_api_wait_IO_done(sys_usb_controller.getEndpoint(device,0));
00245     
00246     setup->bm_request_type = request_type;
00247     setup->b_request = request;
00248     setup->w_value = value;
00249     setup->w_index = index;
00250     setup->w_length = length;
00251 
00252     return usbeh_api_transfer(device, 0, request_type & USBEH_DEVICE_TO_HOST, data, length, callback, userData);
00253 }
00254 
00255 void usbeh_sof_counter_init(USBEH_SOF_COUNTER *q, USBEH_U08 mode, USBEH_U32 count) {
00256     q->mode     = mode;
00257     q->flag     = 0;
00258     q->counter  = count;
00259     q->reload   = count;
00260     q->callback = NULL;
00261     q->next     = NULL;
00262 }
00263 
00264 extern USBEH_SOF_COUNTER   *sof_counter_head;
00265 void usbeh_sof_counter_register(USBEH_SOF_COUNTER *q) {
00266     q->next = sof_counter_head;
00267     sof_counter_head = q;
00268 }
00269 
00270 void usbeh_sof_counter_unregister(USBEH_SOF_COUNTER *q) {
00271     USBEH_SOF_COUNTER *list;
00272     for (list = sof_counter_head; list != NULL; list = list->next) {
00273         if (list->next == q) {
00274             list->next = q->next;
00275             return;
00276         }
00277     }
00278 }
00279 
00280 
00281 void usbeh_api_list_endpoints(void) {
00282     debug_printf("List system endpoints\r\n");
00283     for (int i = 0; i < USBEH_MAX_ENDPOINTS_TOTAL; i++) {
00284         printf("Index %d: 0x%02X Status:%02X State:%d\r\n", i, 
00285             sys_usb_controller.endpoints[i].address(), 
00286             sys_usb_controller.endpoints[i].status(), 
00287             sys_usb_controller.endpoints[i].currentState
00288         ); 
00289     }
00290 }