Simple USBHost WebCam for EA LPC4088 QSB/LPC1768 test program

Dependencies:   LPC4088-USBHost mbed

EA LPC4088 QSB/LPC1768をUSBホストにしてWebカメラからJPEG画像を読み取るテストプログラムです。

The usage is the same as KL46Z-USBHostC270_example.
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認: Logitech C270,Logitech Q200R(Qcam Orbit AF)
/media/uploads/va009039/lpc4088-c270-480x360.jpg

Committer:
va009039
Date:
Thu Apr 24 05:38:45 2014 +0000
Revision:
0:c972ee42b455
first commit,sync rev.29.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:c972ee42b455 1 /* mbed USBHost Library
va009039 0:c972ee42b455 2 * Copyright (c) 2006-2013 ARM Limited
va009039 0:c972ee42b455 3 *
va009039 0:c972ee42b455 4 * Licensed under the Apache License, Version 2.0 (the "License");
va009039 0:c972ee42b455 5 * you may not use this file except in compliance with the License.
va009039 0:c972ee42b455 6 * You may obtain a copy of the License at
va009039 0:c972ee42b455 7 *
va009039 0:c972ee42b455 8 * http://www.apache.org/licenses/LICENSE-2.0
va009039 0:c972ee42b455 9 *
va009039 0:c972ee42b455 10 * Unless required by applicable law or agreed to in writing, software
va009039 0:c972ee42b455 11 * distributed under the License is distributed on an "AS IS" BASIS,
va009039 0:c972ee42b455 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
va009039 0:c972ee42b455 13 * See the License for the specific language governing permissions and
va009039 0:c972ee42b455 14 * limitations under the License.
va009039 0:c972ee42b455 15 */
va009039 0:c972ee42b455 16
va009039 0:c972ee42b455 17 #pragma once
va009039 0:c972ee42b455 18 #include "mbed.h"
va009039 0:c972ee42b455 19 #include "USBHostTypes.h"
va009039 0:c972ee42b455 20 #include "USBEndpoint.h"
va009039 0:c972ee42b455 21
va009039 0:c972ee42b455 22 #if defined(TARGET_LPC4088)
va009039 0:c972ee42b455 23 #define HcRevision Revision
va009039 0:c972ee42b455 24 #define HcControl Control
va009039 0:c972ee42b455 25 #define HcCommandStatus CommandStatus
va009039 0:c972ee42b455 26 #define HcInterruptStatus InterruptStatus
va009039 0:c972ee42b455 27 #define HcInterruptEnable InterruptEnable
va009039 0:c972ee42b455 28 #define HcHCCA HCCA
va009039 0:c972ee42b455 29 #define HcControlHeadED ControlHeadED
va009039 0:c972ee42b455 30 #define HcBulkHeadED BulkHeadED
va009039 0:c972ee42b455 31 #define HcFmInterval FmInterval
va009039 0:c972ee42b455 32 #define HcFmNumber FmNumber
va009039 0:c972ee42b455 33 #define HcPeriodicStart PeriodicStart
va009039 0:c972ee42b455 34 #define HcRhStatus RhStatus
va009039 0:c972ee42b455 35 #define HcRhPortStatus1 RhPortStatus1
va009039 0:c972ee42b455 36 #define OTGStCtrl StCtrl
va009039 0:c972ee42b455 37 #endif
va009039 0:c972ee42b455 38 // ------------------ HcControl Register ---------------------
va009039 0:c972ee42b455 39 #define OR_CONTROL_PLE 0x00000004
va009039 0:c972ee42b455 40 #define OR_CONTROL_IE 0x00000008
va009039 0:c972ee42b455 41 #define OR_CONTROL_CLE 0x00000010
va009039 0:c972ee42b455 42 #define OR_CONTROL_BLE 0x00000020
va009039 0:c972ee42b455 43 #define OR_CONTROL_HCFS 0x000000C0
va009039 0:c972ee42b455 44 #define OR_CONTROL_HC_OPER 0x00000080
va009039 0:c972ee42b455 45 // ----------------- HcCommandStatus Register -----------------
va009039 0:c972ee42b455 46 #define OR_CMD_STATUS_HCR 0x00000001
va009039 0:c972ee42b455 47 #define OR_CMD_STATUS_CLF 0x00000002
va009039 0:c972ee42b455 48 #define OR_CMD_STATUS_BLF 0x00000004
va009039 0:c972ee42b455 49 // --------------- HcInterruptStatus Register -----------------
va009039 0:c972ee42b455 50 #define OR_INTR_STATUS_WDH 0x00000002
va009039 0:c972ee42b455 51 #define OR_INTR_STATUS_UE 0x00000010
va009039 0:c972ee42b455 52 #define OR_INTR_STATUS_FNO 0x00000020
va009039 0:c972ee42b455 53 #define OR_INTR_STATUS_RHSC 0x00000040
va009039 0:c972ee42b455 54 // --------------- HcInterruptEnable Register -----------------
va009039 0:c972ee42b455 55 #define OR_INTR_ENABLE_WDH 0x00000002
va009039 0:c972ee42b455 56 #define OR_INTR_ENABLE_FNO 0x00000020
va009039 0:c972ee42b455 57 #define OR_INTR_ENABLE_RHSC 0x00000040
va009039 0:c972ee42b455 58 #define OR_INTR_ENABLE_MIE 0x80000000
va009039 0:c972ee42b455 59 // ---------------- HcRhDescriptorA Register ------------------
va009039 0:c972ee42b455 60 #define OR_RH_STATUS_LPSC 0x00010000
va009039 0:c972ee42b455 61 #define OR_RH_STATUS_DRWE 0x00008000
va009039 0:c972ee42b455 62 // -------------- HcRhPortStatus[1:NDP] Register --------------
va009039 0:c972ee42b455 63 #define OR_RH_PORT_CCS 0x00000001
va009039 0:c972ee42b455 64 #define OR_RH_PORT_PRS 0x00000010
va009039 0:c972ee42b455 65 #define OR_RH_PORT_CSC 0x00010000
va009039 0:c972ee42b455 66 #define OR_RH_PORT_PRSC 0x00100000
va009039 0:c972ee42b455 67
va009039 0:c972ee42b455 68 // TRANSFER DESCRIPTOR CONTROL FIELDS
va009039 0:c972ee42b455 69 #define TD_ROUNDING (uint32_t)(0x00040000) /* Buffer Rounding */
va009039 0:c972ee42b455 70 #define TD_SETUP (uint32_t)(0x00000000) /* Direction of Setup Packet */
va009039 0:c972ee42b455 71 #define TD_IN (uint32_t)(0x00100000) /* Direction In */
va009039 0:c972ee42b455 72 #define TD_OUT (uint32_t)(0x00080000) /* Direction Out */
va009039 0:c972ee42b455 73 #define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */
va009039 0:c972ee42b455 74 #define TD_DI (uint32_t)(7<<21) /* desable interrupt */
va009039 0:c972ee42b455 75 #define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */
va009039 0:c972ee42b455 76 #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */
va009039 0:c972ee42b455 77 #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */
va009039 0:c972ee42b455 78
va009039 0:c972ee42b455 79 struct SETUP_PACKET {
va009039 0:c972ee42b455 80 uint8_t bmRequestType;
va009039 0:c972ee42b455 81 uint8_t bRequest;
va009039 0:c972ee42b455 82 uint16_t wValue;
va009039 0:c972ee42b455 83 uint16_t wIndex;
va009039 0:c972ee42b455 84 uint16_t wLength;
va009039 0:c972ee42b455 85 SETUP_PACKET(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length) {
va009039 0:c972ee42b455 86 bmRequestType = RequestType;
va009039 0:c972ee42b455 87 bRequest = Request;
va009039 0:c972ee42b455 88 wValue = Value;
va009039 0:c972ee42b455 89 wIndex = Index;
va009039 0:c972ee42b455 90 wLength = Length;
va009039 0:c972ee42b455 91 }
va009039 0:c972ee42b455 92 };
va009039 0:c972ee42b455 93
va009039 0:c972ee42b455 94 void* usb_ram_malloc(size_t size, int aligment); // BaseUsbHostLib.cpp
va009039 0:c972ee42b455 95 void usb_ram_free(void* p);
va009039 0:c972ee42b455 96
va009039 0:c972ee42b455 97 struct TBUF {
va009039 0:c972ee42b455 98 uint8_t buf[0];
va009039 0:c972ee42b455 99 TBUF(const void* data = NULL, int size = 0);
va009039 0:c972ee42b455 100 void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 4); }
va009039 0:c972ee42b455 101 void operator delete(void* p) { usb_ram_free(p); }
va009039 0:c972ee42b455 102 };
va009039 0:c972ee42b455 103
va009039 0:c972ee42b455 104 struct HCTD { // HostController Transfer Descriptor
va009039 0:c972ee42b455 105 __IO uint32_t Control; // +0 Transfer descriptor control
va009039 0:c972ee42b455 106 __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer
va009039 0:c972ee42b455 107 HCTD* Next; // +8 Physical pointer to next Transfer Descriptor
va009039 0:c972ee42b455 108 uint8_t* BufEnd; // +12 Physical address of end of buffer
va009039 0:c972ee42b455 109 uint8_t* buf_top; // +16 Buffer start address
va009039 0:c972ee42b455 110 uint16_t buf_size; // +20 buffer size size
va009039 0:c972ee42b455 111 uint8_t _dummy[10]; // +22 dummy
va009039 0:c972ee42b455 112 USBEndpoint* ep; // +32 endpoint object
va009039 0:c972ee42b455 113 // +36
va009039 0:c972ee42b455 114 HCTD(USBEndpoint* obj);
va009039 0:c972ee42b455 115 void* operator new(size_t size) { return usb_ram_malloc(size, 16); }
va009039 0:c972ee42b455 116 void operator delete(void* p) { usb_ram_free(p); }
va009039 0:c972ee42b455 117
va009039 0:c972ee42b455 118 void transfer(TBUF* tbuf, int len) {
va009039 0:c972ee42b455 119 CurrBufPtr = tbuf->buf;
va009039 0:c972ee42b455 120 buf_top = tbuf->buf;
va009039 0:c972ee42b455 121 buf_size = len;
va009039 0:c972ee42b455 122 BufEnd = const_cast<uint8_t*>(tbuf->buf)+len-1;
va009039 0:c972ee42b455 123 }
va009039 0:c972ee42b455 124 int getLengthTransferred() {
va009039 0:c972ee42b455 125 if (CurrBufPtr) {
va009039 0:c972ee42b455 126 return CurrBufPtr - buf_top;
va009039 0:c972ee42b455 127 }
va009039 0:c972ee42b455 128 return buf_size;
va009039 0:c972ee42b455 129 }
va009039 0:c972ee42b455 130 int status() {
va009039 0:c972ee42b455 131 if (CurrBufPtr) {
va009039 0:c972ee42b455 132 return CurrBufPtr - buf_top;
va009039 0:c972ee42b455 133 }
va009039 0:c972ee42b455 134 return buf_size;
va009039 0:c972ee42b455 135 }
va009039 0:c972ee42b455 136
va009039 0:c972ee42b455 137 uint8_t ConditionCode() {
va009039 0:c972ee42b455 138 return Control>>28;
va009039 0:c972ee42b455 139 }
va009039 0:c972ee42b455 140 };
va009039 0:c972ee42b455 141
va009039 0:c972ee42b455 142 struct HCITD { // HostController Isochronous Transfer Descriptor
va009039 0:c972ee42b455 143 __IO uint32_t Control; // +0 Transfer descriptor control
va009039 0:c972ee42b455 144 uint8_t* BufferPage0; // +4 Buffer Page 0
va009039 0:c972ee42b455 145 HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor
va009039 0:c972ee42b455 146 uint8_t* BufferEnd; // +12 buffer End
va009039 0:c972ee42b455 147 __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW
va009039 0:c972ee42b455 148 USBEndpoint* ep; // +32 endpoint object
va009039 0:c972ee42b455 149 __IO uint8_t buf[0]; // +36 buffer
va009039 0:c972ee42b455 150 // +36
va009039 0:c972ee42b455 151 HCITD(USBEndpoint* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize);
va009039 0:c972ee42b455 152 void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 32); }
va009039 0:c972ee42b455 153 void operator delete(void* p) { usb_ram_free(p); }
va009039 0:c972ee42b455 154
va009039 0:c972ee42b455 155 uint16_t StartingFrame() {
va009039 0:c972ee42b455 156 return Control & 0xffff;
va009039 0:c972ee42b455 157 }
va009039 0:c972ee42b455 158
va009039 0:c972ee42b455 159 uint8_t FrameCount() {
va009039 0:c972ee42b455 160 return ((Control>>24)&7)+1;
va009039 0:c972ee42b455 161 }
va009039 0:c972ee42b455 162
va009039 0:c972ee42b455 163 uint8_t ConditionCode() {
va009039 0:c972ee42b455 164 return Control>>28;
va009039 0:c972ee42b455 165 }
va009039 0:c972ee42b455 166 };
va009039 0:c972ee42b455 167
va009039 0:c972ee42b455 168 struct HCED { // HostController EndPoint Descriptor
va009039 0:c972ee42b455 169 __IO uint32_t Control; // +0 Endpoint descriptor control
va009039 0:c972ee42b455 170 HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list
va009039 0:c972ee42b455 171 __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list
va009039 0:c972ee42b455 172 HCED* Next; // +12 Physical address of next Endpoint descriptor
va009039 0:c972ee42b455 173 // +16
va009039 0:c972ee42b455 174 HCED(USBEndpoint* ep);
va009039 0:c972ee42b455 175 void* operator new(size_t size) { return usb_ram_malloc(size, 16); }
va009039 0:c972ee42b455 176 void operator delete(void* p) { usb_ram_free(p); }
va009039 0:c972ee42b455 177
va009039 0:c972ee42b455 178 uint8_t FunctionAddress() {
va009039 0:c972ee42b455 179 return Control & 0x7f;
va009039 0:c972ee42b455 180 }
va009039 0:c972ee42b455 181
va009039 0:c972ee42b455 182 uint8_t EndpointNumber() {
va009039 0:c972ee42b455 183 return (Control>>7) & 0x7f;
va009039 0:c972ee42b455 184 }
va009039 0:c972ee42b455 185
va009039 0:c972ee42b455 186 int Speed() {
va009039 0:c972ee42b455 187 return (Control>>13)&1;
va009039 0:c972ee42b455 188 }
va009039 0:c972ee42b455 189
va009039 0:c972ee42b455 190 void setFunctionAddress(int addr) {
va009039 0:c972ee42b455 191 Control &= ~0x7f;
va009039 0:c972ee42b455 192 Control |= addr;
va009039 0:c972ee42b455 193 }
va009039 0:c972ee42b455 194
va009039 0:c972ee42b455 195 void setMaxPacketSize(uint16_t size) {
va009039 0:c972ee42b455 196 Control &= ~0xffff0000;
va009039 0:c972ee42b455 197 Control |= size<<16;
va009039 0:c972ee42b455 198 }
va009039 0:c972ee42b455 199
va009039 0:c972ee42b455 200 void setToggleDATA1() {
va009039 0:c972ee42b455 201 uint32_t c = reinterpret_cast<uint32_t>(HeadTd);
va009039 0:c972ee42b455 202 c |= 0x02;
va009039 0:c972ee42b455 203 HeadTd = reinterpret_cast<HCTD*>(c);
va009039 0:c972ee42b455 204 }
va009039 0:c972ee42b455 205
va009039 0:c972ee42b455 206 int Skip() {
va009039 0:c972ee42b455 207 return (Control>>14) & 1;
va009039 0:c972ee42b455 208 }
va009039 0:c972ee42b455 209
va009039 0:c972ee42b455 210 void setSkip() {
va009039 0:c972ee42b455 211 Control |= (1<<14);
va009039 0:c972ee42b455 212 }
va009039 0:c972ee42b455 213
va009039 0:c972ee42b455 214 void setFormat() {
va009039 0:c972ee42b455 215 Control |= (1<<15);
va009039 0:c972ee42b455 216 }
va009039 0:c972ee42b455 217
va009039 0:c972ee42b455 218 bool enqueue(HCTD* td);
va009039 0:c972ee42b455 219 void init_queue(HCTD* td);
va009039 0:c972ee42b455 220 };
va009039 0:c972ee42b455 221
va009039 0:c972ee42b455 222 struct HCCA { // Host Controller Communication Area
va009039 0:c972ee42b455 223 HCED* InterruptTable[32]; // +0 Interrupt Table
va009039 0:c972ee42b455 224 __IO uint16_t FrameNumber;// +128 Frame Number
va009039 0:c972ee42b455 225 __IO uint16_t Pad1; // +130
va009039 0:c972ee42b455 226 __IO HCTD* DoneHead; // +132 Done Head
va009039 0:c972ee42b455 227 uint8_t Reserved[116]; // +136 Reserved for future use
va009039 0:c972ee42b455 228 uint8_t Unknown[4]; // +252 Unused
va009039 0:c972ee42b455 229 // +256
va009039 0:c972ee42b455 230 void* operator new(size_t size) { return usb_ram_malloc(size, 256); }
va009039 0:c972ee42b455 231 void operator delete(void* p) { usb_ram_free(p); }
va009039 0:c972ee42b455 232 void enqueue(HCED* ed);
va009039 0:c972ee42b455 233 };
va009039 0:c972ee42b455 234
va009039 0:c972ee42b455 235 class USBHALHost {
va009039 0:c972ee42b455 236 public:
va009039 0:c972ee42b455 237 uint8_t LastStatus;
va009039 0:c972ee42b455 238 uint8_t prev_LastStatus;
va009039 0:c972ee42b455 239 static void enable(ENDPOINT_TYPE type);
va009039 0:c972ee42b455 240
va009039 0:c972ee42b455 241 protected:
va009039 0:c972ee42b455 242 USBHALHost();
va009039 0:c972ee42b455 243 void init();
va009039 0:c972ee42b455 244 void init_hw_ohci(HCCA* pHcca);
va009039 0:c972ee42b455 245 void ResetRootHub();
va009039 0:c972ee42b455 246 virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) = 0;
va009039 0:c972ee42b455 247 //void setAddr(int addr, bool lowSpeed = false);
va009039 0:c972ee42b455 248 //void setEndpoint();
va009039 0:c972ee42b455 249 //void token_transfer_init();
va009039 0:c972ee42b455 250 void token_init(USBEndpoint* ep);
va009039 0:c972ee42b455 251 int token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength = 0);
va009039 0:c972ee42b455 252 int token_in(USBEndpoint* ep, uint8_t* data = NULL, int size = 0, int retryLimit = 0);
va009039 0:c972ee42b455 253 int token_out(USBEndpoint* ep, const uint8_t* data = NULL, int size = 0, int retryLimit = 0);
va009039 0:c972ee42b455 254 void token_inNB(USBEndpoint* ep, uint8_t* data, int size);
va009039 0:c972ee42b455 255 USB_TYPE token_inNB_result(USBEndpoint* ep);
va009039 0:c972ee42b455 256 //void token_ready();
va009039 0:c972ee42b455 257 // report
va009039 0:c972ee42b455 258 uint32_t m_report_irq;
va009039 0:c972ee42b455 259 uint32_t m_report_RHSC;
va009039 0:c972ee42b455 260 uint32_t m_report_FNO;
va009039 0:c972ee42b455 261 uint32_t m_report_WDH;
va009039 0:c972ee42b455 262 uint32_t m_report_sp;
va009039 0:c972ee42b455 263
va009039 0:c972ee42b455 264 private:
va009039 0:c972ee42b455 265 static void _usbisr(void);
va009039 0:c972ee42b455 266 void UsbIrqhandler();
va009039 0:c972ee42b455 267 HCCA* m_pHcca;
va009039 0:c972ee42b455 268 //__IO bool attach_done;
va009039 0:c972ee42b455 269 //__IO bool token_done;
va009039 0:c972ee42b455 270 bool wait_attach();
va009039 0:c972ee42b455 271 bool root_lowSpeed;
va009039 0:c972ee42b455 272 static USBHALHost * instHost;
va009039 0:c972ee42b455 273 };
va009039 0:c972ee42b455 274