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

Dependencies:   mbed

Committer:
AjK
Date:
Mon Oct 11 10:34:55 2010 +0000
Revision:
0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:0a841b89d614 1 /****************************************************************************
AjK 0:0a841b89d614 2 * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
AjK 0:0a841b89d614 3 *
AjK 0:0a841b89d614 4 * This file is part of the Satellite Observers Workbench (SOWB).
AjK 0:0a841b89d614 5 *
AjK 0:0a841b89d614 6 * SOWB is free software: you can redistribute it and/or modify
AjK 0:0a841b89d614 7 * it under the terms of the GNU General Public License as published by
AjK 0:0a841b89d614 8 * the Free Software Foundation, either version 3 of the License, or
AjK 0:0a841b89d614 9 * (at your option) any later version.
AjK 0:0a841b89d614 10 *
AjK 0:0a841b89d614 11 * SOWB is distributed in the hope that it will be useful,
AjK 0:0a841b89d614 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
AjK 0:0a841b89d614 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
AjK 0:0a841b89d614 14 * GNU General Public License for more details.
AjK 0:0a841b89d614 15 *
AjK 0:0a841b89d614 16 * You should have received a copy of the GNU General Public License
AjK 0:0a841b89d614 17 * along with SOWB. If not, see <http://www.gnu.org/licenses/>.
AjK 0:0a841b89d614 18 *
AjK 0:0a841b89d614 19 * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
AjK 0:0a841b89d614 20 *
AjK 0:0a841b89d614 21 ***************************************************************************/
AjK 0:0a841b89d614 22
AjK 0:0a841b89d614 23 #include "sowb.h"
AjK 0:0a841b89d614 24 #include "usbeh_api.h"
AjK 0:0a841b89d614 25 #include "usbeh_endpoint.h"
AjK 0:0a841b89d614 26 #include "usbeh_device.h"
AjK 0:0a841b89d614 27 #include "usbeh_controller.h"
AjK 0:0a841b89d614 28
AjK 0:0a841b89d614 29 #include "main.h"
AjK 0:0a841b89d614 30 #include "debug.h"
AjK 0:0a841b89d614 31
AjK 0:0a841b89d614 32 /* Device driver headers. */
AjK 0:0a841b89d614 33 #include "xbox360gamepad.h"
AjK 0:0a841b89d614 34
AjK 0:0a841b89d614 35 #define DEBUG_USB_API 1
AjK 0:0a841b89d614 36
AjK 0:0a841b89d614 37 USBEH_device_info_callback usb_devices_callback_map[] = {
AjK 0:0a841b89d614 38 (xbox360gamepad_onload_callback),
AjK 0:0a841b89d614 39 NULL
AjK 0:0a841b89d614 40 };
AjK 0:0a841b89d614 41
AjK 0:0a841b89d614 42 int usbeh_no_device_found(int device, USBEH_deviceDescriptor *deviceDesc, USBEH_interfaceDescriptor **interfaceDesc) {
AjK 0:0a841b89d614 43 USBEH_interfaceDescriptor *iface;
AjK 0:0a841b89d614 44 int interfaceCounter = 0;
AjK 0:0a841b89d614 45 debug_printf("%s CALLBACK ACTIVATED for device %d\r\n", __FUNCTION__, device);
AjK 0:0a841b89d614 46 debug_printf(" VendorId = %04X ProductId = %04X \r\n", deviceDesc->idVendor, deviceDesc->idProduct);
AjK 0:0a841b89d614 47 while ((iface = interfaceDesc[interfaceCounter]) != (USBEH_interfaceDescriptor *)NULL) {
AjK 0:0a841b89d614 48 debug_printf(" interface%d:- \r\n", interfaceCounter);
AjK 0:0a841b89d614 49 debug_printf(" InterfaceClass = %02X \r\n", iface->bInterfaceClass);
AjK 0:0a841b89d614 50 debug_printf(" InterfaceSubClass = %02X \r\n", iface->bInterfaceSubClass);
AjK 0:0a841b89d614 51 debug_printf(" InterfaceProtocol = %02X \r\n", iface->bInterfaceProtocol);
AjK 0:0a841b89d614 52 interfaceCounter++;
AjK 0:0a841b89d614 53 }
AjK 0:0a841b89d614 54 debug_printf(" No device driver loaded.\r\n");
AjK 0:0a841b89d614 55 return 0;
AjK 0:0a841b89d614 56 }
AjK 0:0a841b89d614 57
AjK 0:0a841b89d614 58 /* Create an instance of the USBEH controller and place
AjK 0:0a841b89d614 59 it within the AHB static ram area. */
AjK 0:0a841b89d614 60 USBEH_Controller sys_usb_controller __attribute__((at(0x2007C000)));
AjK 0:0a841b89d614 61
AjK 0:0a841b89d614 62
AjK 0:0a841b89d614 63 void usbeh_api_on_load_device(int device, USBEH_deviceDescriptor* deviceDesc, USBEH_interfaceDescriptor **interfaceDesc) {
AjK 0:0a841b89d614 64 int i, slen, driver_loaded = 0;
AjK 0:0a841b89d614 65 char s[3][128];
AjK 0:0a841b89d614 66
AjK 0:0a841b89d614 67 memset((char *)s, 0, 3 * 128);
AjK 0:0a841b89d614 68
AjK 0:0a841b89d614 69 /* Get device strings. */
AjK 0:0a841b89d614 70 for (i = 1; i < 3; i++) {
AjK 0:0a841b89d614 71 slen = usbeh_api_get_string(device, i, s[i - 1], 128);
AjK 0:0a841b89d614 72 if (slen < 0) {
AjK 0:0a841b89d614 73 break;
AjK 0:0a841b89d614 74 }
AjK 0:0a841b89d614 75 }
AjK 0:0a841b89d614 76
AjK 0:0a841b89d614 77 /* Scan through the device driver onLoad callbacks to see who wants to claim it. */
AjK 0:0a841b89d614 78 for (i = 0; usb_devices_callback_map[i] != NULL && driver_loaded == 0; i++) {
AjK 0:0a841b89d614 79 driver_loaded = (usb_devices_callback_map[i])(device,deviceDesc,interfaceDesc);
AjK 0:0a841b89d614 80 }
AjK 0:0a841b89d614 81
AjK 0:0a841b89d614 82 if (driver_loaded == 0) {
AjK 0:0a841b89d614 83 usbeh_no_device_found(device, deviceDesc, interfaceDesc);
AjK 0:0a841b89d614 84 }
AjK 0:0a841b89d614 85 }
AjK 0:0a841b89d614 86
AjK 0:0a841b89d614 87 int usbeh_api_init(void) {
AjK 0:0a841b89d614 88 DEBUG_INIT_START;
AjK 0:0a841b89d614 89 sys_usb_controller.init();
AjK 0:0a841b89d614 90 DEBUG_INIT_END;
AjK 0:0a841b89d614 91 return 0;
AjK 0:0a841b89d614 92 }
AjK 0:0a841b89d614 93
AjK 0:0a841b89d614 94 void usbeh_api_process(void) {
AjK 0:0a841b89d614 95 sys_usb_controller.process();
AjK 0:0a841b89d614 96 }
AjK 0:0a841b89d614 97
AjK 0:0a841b89d614 98 int usbeh_api_set_address(int device, int new_addr) {
AjK 0:0a841b89d614 99 return usbeh_api_control_transfer(device, USBEH_HOST_TO_DEVICE | USBEH_RECIPIENT_DEVICE, USBEH_SET_ADDRESS, new_addr, 0, 0, 0, 0, 0);
AjK 0:0a841b89d614 100 }
AjK 0:0a841b89d614 101
AjK 0:0a841b89d614 102 int usbeh_api_get_descriptor(int device, int descType,int descIndex, USBEH_U08* data, int length) {
AjK 0:0a841b89d614 103 return usbeh_api_control_transfer(device, USBEH_DEVICE_TO_HOST | USBEH_RECIPIENT_DEVICE, USBEH_GET_DESCRIPTOR, (descType << 8)|(descIndex), 0, data, length, 0, 0);
AjK 0:0a841b89d614 104 }
AjK 0:0a841b89d614 105
AjK 0:0a841b89d614 106 static USBEH_Setup* usbeh_api_get_setup(int device) {
AjK 0:0a841b89d614 107 if (device == 0) {
AjK 0:0a841b89d614 108 return &sys_usb_controller.setupZero;
AjK 0:0a841b89d614 109 }
AjK 0:0a841b89d614 110
AjK 0:0a841b89d614 111 if (device < 1 || device > USBEH_MAX_DEVICES) {
AjK 0:0a841b89d614 112 return 0;
AjK 0:0a841b89d614 113 }
AjK 0:0a841b89d614 114
AjK 0:0a841b89d614 115 return &sys_usb_controller.devices[device-1].setupBuffer;
AjK 0:0a841b89d614 116 }
AjK 0:0a841b89d614 117
AjK 0:0a841b89d614 118 static int usbeh_api_wait_IO_done(USBEH_Endpoint* endpoint) {
AjK 0:0a841b89d614 119
AjK 0:0a841b89d614 120 if (endpoint->currentState == USBEH_Endpoint::notQueued) {
AjK 0:0a841b89d614 121 return 0;
AjK 0:0a841b89d614 122 }
AjK 0:0a841b89d614 123
AjK 0:0a841b89d614 124 while (endpoint->currentState != USBEH_Endpoint::idle) {
AjK 0:0a841b89d614 125 usbeh_api_process();
AjK 0:0a841b89d614 126 }
AjK 0:0a841b89d614 127
AjK 0:0a841b89d614 128 int status = endpoint->status();
AjK 0:0a841b89d614 129 if (status == 0) {
AjK 0:0a841b89d614 130 return endpoint->length;
AjK 0:0a841b89d614 131 }
AjK 0:0a841b89d614 132
AjK 0:0a841b89d614 133 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 134 debug_printf("usbeh_api_wait_IO_done() error with 0x%x at line %d\r\n", status, __LINE__);
AjK 0:0a841b89d614 135 #endif
AjK 0:0a841b89d614 136
AjK 0:0a841b89d614 137 return -status;
AjK 0:0a841b89d614 138 }
AjK 0:0a841b89d614 139
AjK 0:0a841b89d614 140
AjK 0:0a841b89d614 141 int usbeh_api_get_port_status(int device, int port, USBEH_U32 *status) {
AjK 0:0a841b89d614 142 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);
AjK 0:0a841b89d614 143 }
AjK 0:0a841b89d614 144
AjK 0:0a841b89d614 145 int usbeh_api_clear_port_feature(int device, int feature, int index) {
AjK 0:0a841b89d614 146 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);
AjK 0:0a841b89d614 147 }
AjK 0:0a841b89d614 148
AjK 0:0a841b89d614 149 int usbeh_api_set_port_power(int device, int port) {
AjK 0:0a841b89d614 150 int result = usbeh_api_set_port_feature(device, USBEH_PORT_POWER, port);
AjK 0:0a841b89d614 151 USBEH_OS_DELAY_MS(20);
AjK 0:0a841b89d614 152 return result;
AjK 0:0a841b89d614 153 }
AjK 0:0a841b89d614 154
AjK 0:0a841b89d614 155 int usbeh_api_set_port_feature(int device, int feature, int index) {
AjK 0:0a841b89d614 156 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);
AjK 0:0a841b89d614 157 }
AjK 0:0a841b89d614 158
AjK 0:0a841b89d614 159 int usbeh_api_set_configuration(int device, int configNum) {
AjK 0:0a841b89d614 160 return usbeh_api_control_transfer(device, USBEH_HOST_TO_DEVICE | USBEH_RECIPIENT_DEVICE, USBEH_SET_CONFIGURATION, configNum, 0, 0, 0, 0, 0);
AjK 0:0a841b89d614 161 }
AjK 0:0a841b89d614 162
AjK 0:0a841b89d614 163 int usbeh_api_set_port_reset(int device, int port) {
AjK 0:0a841b89d614 164 return usbeh_api_set_port_feature(device, USBEH_PORT_RESET, port);
AjK 0:0a841b89d614 165 }
AjK 0:0a841b89d614 166
AjK 0:0a841b89d614 167 int usbeh_api_get_string(int device, int index, char *dst, int length) {
AjK 0:0a841b89d614 168
AjK 0:0a841b89d614 169 USBEH_U08 buffer[255];
AjK 0:0a841b89d614 170
AjK 0:0a841b89d614 171 int le = usbeh_api_get_descriptor(device, USBEH_DESCRIPTOR_TYPE_STRING, index, buffer, sizeof(buffer));
AjK 0:0a841b89d614 172
AjK 0:0a841b89d614 173 if (le < 0) {
AjK 0:0a841b89d614 174 return le;
AjK 0:0a841b89d614 175 }
AjK 0:0a841b89d614 176
AjK 0:0a841b89d614 177 if (length < 1) {
AjK 0:0a841b89d614 178 return -1;
AjK 0:0a841b89d614 179 }
AjK 0:0a841b89d614 180
AjK 0:0a841b89d614 181 length <<= 1;
AjK 0:0a841b89d614 182
AjK 0:0a841b89d614 183 if (le > length) {
AjK 0:0a841b89d614 184 le = length;
AjK 0:0a841b89d614 185 }
AjK 0:0a841b89d614 186
AjK 0:0a841b89d614 187 for (int j = 2; j < le; j += 2) {
AjK 0:0a841b89d614 188 *dst++ = buffer[j];
AjK 0:0a841b89d614 189 }
AjK 0:0a841b89d614 190
AjK 0:0a841b89d614 191 *dst = 0;
AjK 0:0a841b89d614 192
AjK 0:0a841b89d614 193 return (le >> 1) - 1;
AjK 0:0a841b89d614 194 }
AjK 0:0a841b89d614 195
AjK 0:0a841b89d614 196 int usbeh_api_transfer(int device, int ep, USBEH_U08 flags, USBEH_U08 *data, int length, USBEH_callback callback, void *userData) {
AjK 0:0a841b89d614 197 USBEH_Endpoint *endpoint = sys_usb_controller.getEndpoint(device, ep);
AjK 0:0a841b89d614 198 if (!endpoint) {
AjK 0:0a841b89d614 199 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 200 debug_printf("sys_usb_controller.getEndpoint() failed at line %d\r\n", __LINE__);
AjK 0:0a841b89d614 201 #endif
AjK 0:0a841b89d614 202 return USBEH_ERR_ENDPOINT_NOT_FOUND;
AjK 0:0a841b89d614 203 }
AjK 0:0a841b89d614 204
AjK 0:0a841b89d614 205 usbeh_api_wait_IO_done(endpoint);
AjK 0:0a841b89d614 206
AjK 0:0a841b89d614 207 endpoint->flags = flags;
AjK 0:0a841b89d614 208 endpoint->data = data;
AjK 0:0a841b89d614 209 endpoint->length = length;
AjK 0:0a841b89d614 210 endpoint->callback = callback;
AjK 0:0a841b89d614 211 endpoint->userData = userData;
AjK 0:0a841b89d614 212
AjK 0:0a841b89d614 213 if (ep == 0) {
AjK 0:0a841b89d614 214 sys_usb_controller.transfer(endpoint, USBEH_TOKEN_SETUP, (USBEH_U08 *)usbeh_api_get_setup(device), 8, USBEH_Endpoint::setupQueued);
AjK 0:0a841b89d614 215 }
AjK 0:0a841b89d614 216 else {
AjK 0:0a841b89d614 217 sys_usb_controller.transfer(endpoint, flags & 0x80 ? USBEH_TOKEN_IN : USBEH_TOKEN_OUT, data, length, USBEH_Endpoint::dataQueued);
AjK 0:0a841b89d614 218 }
AjK 0:0a841b89d614 219
AjK 0:0a841b89d614 220 if (callback) {
AjK 0:0a841b89d614 221 return USBEH_IO_PENDING;
AjK 0:0a841b89d614 222 }
AjK 0:0a841b89d614 223
AjK 0:0a841b89d614 224 return usbeh_api_wait_IO_done(endpoint);
AjK 0:0a841b89d614 225 }
AjK 0:0a841b89d614 226
AjK 0:0a841b89d614 227 int usbeh_api_interrupt_transfer(int device, int ep, USBEH_U08 *data, int length, USBEH_callback callback, void *userData) {
AjK 0:0a841b89d614 228 return usbeh_api_transfer(device, ep, (ep & 0x80) | USBEH_ENDPOINT_INTERRUPT, data, length, callback, userData);
AjK 0:0a841b89d614 229 }
AjK 0:0a841b89d614 230
AjK 0:0a841b89d614 231 int usbeh_api_control_transfer_short(int device, int request_type, int request, int value, int index, USBEH_U08 *data, int length) {
AjK 0:0a841b89d614 232 return usbeh_api_control_transfer(device, request_type, request, value, index, data, length, 0, 0);
AjK 0:0a841b89d614 233 }
AjK 0:0a841b89d614 234
AjK 0:0a841b89d614 235 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) {
AjK 0:0a841b89d614 236 USBEH_Setup* setup = usbeh_api_get_setup(device);
AjK 0:0a841b89d614 237 if (!setup) {
AjK 0:0a841b89d614 238 #ifdef DEBUG_USB_DRIVER
AjK 0:0a841b89d614 239 debug_printf("usbeh_api_get_setup() failed at line %d\r\n", __LINE__);
AjK 0:0a841b89d614 240 #endif
AjK 0:0a841b89d614 241 return USBEH_ERR_DEVICE_NOT_FOUND;
AjK 0:0a841b89d614 242 }
AjK 0:0a841b89d614 243
AjK 0:0a841b89d614 244 usbeh_api_wait_IO_done(sys_usb_controller.getEndpoint(device,0));
AjK 0:0a841b89d614 245
AjK 0:0a841b89d614 246 setup->bm_request_type = request_type;
AjK 0:0a841b89d614 247 setup->b_request = request;
AjK 0:0a841b89d614 248 setup->w_value = value;
AjK 0:0a841b89d614 249 setup->w_index = index;
AjK 0:0a841b89d614 250 setup->w_length = length;
AjK 0:0a841b89d614 251
AjK 0:0a841b89d614 252 return usbeh_api_transfer(device, 0, request_type & USBEH_DEVICE_TO_HOST, data, length, callback, userData);
AjK 0:0a841b89d614 253 }
AjK 0:0a841b89d614 254
AjK 0:0a841b89d614 255 void usbeh_sof_counter_init(USBEH_SOF_COUNTER *q, USBEH_U08 mode, USBEH_U32 count) {
AjK 0:0a841b89d614 256 q->mode = mode;
AjK 0:0a841b89d614 257 q->flag = 0;
AjK 0:0a841b89d614 258 q->counter = count;
AjK 0:0a841b89d614 259 q->reload = count;
AjK 0:0a841b89d614 260 q->callback = NULL;
AjK 0:0a841b89d614 261 q->next = NULL;
AjK 0:0a841b89d614 262 }
AjK 0:0a841b89d614 263
AjK 0:0a841b89d614 264 extern USBEH_SOF_COUNTER *sof_counter_head;
AjK 0:0a841b89d614 265 void usbeh_sof_counter_register(USBEH_SOF_COUNTER *q) {
AjK 0:0a841b89d614 266 q->next = sof_counter_head;
AjK 0:0a841b89d614 267 sof_counter_head = q;
AjK 0:0a841b89d614 268 }
AjK 0:0a841b89d614 269
AjK 0:0a841b89d614 270 void usbeh_sof_counter_unregister(USBEH_SOF_COUNTER *q) {
AjK 0:0a841b89d614 271 USBEH_SOF_COUNTER *list;
AjK 0:0a841b89d614 272 for (list = sof_counter_head; list != NULL; list = list->next) {
AjK 0:0a841b89d614 273 if (list->next == q) {
AjK 0:0a841b89d614 274 list->next = q->next;
AjK 0:0a841b89d614 275 return;
AjK 0:0a841b89d614 276 }
AjK 0:0a841b89d614 277 }
AjK 0:0a841b89d614 278 }
AjK 0:0a841b89d614 279
AjK 0:0a841b89d614 280
AjK 0:0a841b89d614 281 void usbeh_api_list_endpoints(void) {
AjK 0:0a841b89d614 282 debug_printf("List system endpoints\r\n");
AjK 0:0a841b89d614 283 for (int i = 0; i < USBEH_MAX_ENDPOINTS_TOTAL; i++) {
AjK 0:0a841b89d614 284 printf("Index %d: 0x%02X Status:%02X State:%d\r\n", i,
AjK 0:0a841b89d614 285 sys_usb_controller.endpoints[i].address(),
AjK 0:0a841b89d614 286 sys_usb_controller.endpoints[i].status(),
AjK 0:0a841b89d614 287 sys_usb_controller.endpoints[i].currentState
AjK 0:0a841b89d614 288 );
AjK 0:0a841b89d614 289 }
AjK 0:0a841b89d614 290 }