Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768
Dependents: F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld
Fork of KL46Z-USBHost by
USBHALHost_LPC4088.h
00001 /* mbed USBHost Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #pragma once 00018 #include "mbed.h" 00019 #include "rtos.h" 00020 #include "USBHostTypes.h" 00021 #include "USBEndpoint.h" 00022 00023 #if defined(TARGET_LPC4088) 00024 #define HcRevision Revision 00025 #define HcControl Control 00026 #define HcCommandStatus CommandStatus 00027 #define HcInterruptStatus InterruptStatus 00028 #define HcInterruptEnable InterruptEnable 00029 #define HcHCCA HCCA 00030 #define HcControlHeadED ControlHeadED 00031 #define HcBulkHeadED BulkHeadED 00032 #define HcFmInterval FmInterval 00033 #define HcFmNumber FmNumber 00034 #define HcPeriodicStart PeriodicStart 00035 #define HcRhStatus RhStatus 00036 #define HcRhPortStatus1 RhPortStatus1 00037 #define OTGStCtrl StCtrl 00038 #endif 00039 // ------------------ HcControl Register --------------------- 00040 #define OR_CONTROL_PLE 0x00000004 00041 #define OR_CONTROL_IE 0x00000008 00042 #define OR_CONTROL_CLE 0x00000010 00043 #define OR_CONTROL_BLE 0x00000020 00044 #define OR_CONTROL_HCFS 0x000000C0 00045 #define OR_CONTROL_HC_OPER 0x00000080 00046 // ----------------- HcCommandStatus Register ----------------- 00047 #define OR_CMD_STATUS_HCR 0x00000001 00048 #define OR_CMD_STATUS_CLF 0x00000002 00049 #define OR_CMD_STATUS_BLF 0x00000004 00050 // --------------- HcInterruptStatus Register ----------------- 00051 #define OR_INTR_STATUS_WDH 0x00000002 00052 #define OR_INTR_STATUS_UE 0x00000010 00053 #define OR_INTR_STATUS_FNO 0x00000020 00054 #define OR_INTR_STATUS_RHSC 0x00000040 00055 // --------------- HcInterruptEnable Register ----------------- 00056 #define OR_INTR_ENABLE_WDH 0x00000002 00057 #define OR_INTR_ENABLE_FNO 0x00000020 00058 #define OR_INTR_ENABLE_RHSC 0x00000040 00059 #define OR_INTR_ENABLE_MIE 0x80000000 00060 // ---------------- HcRhDescriptorA Register ------------------ 00061 #define OR_RH_STATUS_LPSC 0x00010000 00062 #define OR_RH_STATUS_DRWE 0x00008000 00063 // -------------- HcRhPortStatus[1:NDP] Register -------------- 00064 #define OR_RH_PORT_CCS 0x00000001 00065 #define OR_RH_PORT_PRS 0x00000010 00066 #define OR_RH_PORT_LSDA 0x00000200 00067 #define OR_RH_PORT_CSC 0x00010000 00068 #define OR_RH_PORT_PRSC 0x00100000 00069 00070 // TRANSFER DESCRIPTOR CONTROL FIELDS 00071 #define TD_ROUNDING (uint32_t)(0x00040000) /* Buffer Rounding */ 00072 #define TD_SETUP (uint32_t)(0x00000000) /* Direction of Setup Packet */ 00073 #define TD_IN (uint32_t)(0x00100000) /* Direction In */ 00074 #define TD_OUT (uint32_t)(0x00080000) /* Direction Out */ 00075 #define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */ 00076 #define TD_DI (uint32_t)(7<<21) /* desable interrupt */ 00077 #define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */ 00078 #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ 00079 #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ 00080 00081 void* usb_ram_malloc(size_t size, int aligment); // USBHALHost2_LPC4088.cpp 00082 void usb_ram_free(void* p); 00083 00084 struct TBUF { 00085 uint8_t buf[0]; 00086 TBUF(const void* data = NULL, int size = 0); 00087 void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 4); } 00088 void operator delete(void* p) { usb_ram_free(p); } 00089 }; 00090 00091 class HCED; 00092 00093 struct HCTD { // HostController Transfer Descriptor 00094 __IO uint32_t Control; // +0 Transfer descriptor control 00095 __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer 00096 HCTD* Next; // +8 Physical pointer to next Transfer Descriptor 00097 uint8_t* BufEnd; // +12 Physical address of end of buffer 00098 uint8_t* buf_top; // +16 Buffer start address 00099 uint16_t buf_size; // +20 buffer size size 00100 uint8_t _dummy[10]; // +22 dummy 00101 HCED* parent; // +32 HCED object 00102 // +36 00103 HCTD(HCED* ed); 00104 void* operator new(size_t size) { return usb_ram_malloc(size, 16); } 00105 void operator delete(void* p) { usb_ram_free(p); } 00106 00107 void transfer(TBUF* tbuf, int len) { 00108 CurrBufPtr = tbuf->buf; 00109 buf_top = tbuf->buf; 00110 buf_size = len; 00111 BufEnd = const_cast<uint8_t*>(tbuf->buf)+len-1; 00112 } 00113 int getLengthTransferred() { 00114 if (CurrBufPtr) { 00115 return CurrBufPtr - buf_top; 00116 } 00117 return buf_size; 00118 } 00119 int status() { 00120 if (CurrBufPtr) { 00121 return CurrBufPtr - buf_top; 00122 } 00123 return buf_size; 00124 } 00125 00126 uint8_t ConditionCode() { 00127 return Control>>28; 00128 } 00129 }; 00130 00131 struct HCITD { // HostController Isochronous Transfer Descriptor 00132 __IO uint32_t Control; // +0 Transfer descriptor control 00133 uint8_t* BufferPage0; // +4 Buffer Page 0 00134 HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor 00135 uint8_t* BufferEnd; // +12 buffer End 00136 __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW 00137 HCED* parent; // +32 HCED object 00138 __IO uint8_t buf[0]; // +36 buffer 00139 // +36 00140 HCITD(HCED* ed, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); 00141 uint8_t* Buffer(int fc); 00142 void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 32); } 00143 void operator delete(void* p) { usb_ram_free(p); } 00144 00145 uint16_t StartingFrame() { 00146 return Control & 0xffff; 00147 } 00148 00149 uint8_t FrameCount() { 00150 return ((Control>>24)&7)+1; 00151 } 00152 00153 uint8_t ConditionCode() { 00154 return Control>>28; 00155 } 00156 00157 uint8_t ConditionCode(int fc) { 00158 uint16_t psw = OffsetPSW[fc]; 00159 return psw>>12; 00160 } 00161 00162 uint16_t Length(int fc) { 00163 uint16_t psw = OffsetPSW[fc]; 00164 return psw & 0x7ff; 00165 } 00166 }; 00167 00168 #define HCTD_QUEUE_SIZE 3 00169 00170 struct HCED { // HostController EndPoint Descriptor 00171 __IO uint32_t Control; // +0 Endpoint descriptor control 00172 HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list 00173 __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list 00174 HCED* Next; // +12 Physical address of next Endpoint descriptor 00175 // +16 00176 uint8_t m_ConditionCode; 00177 Queue<HCTD, HCTD_QUEUE_SIZE> _done_queue; // TD done queue 00178 struct { 00179 uint8_t queue_count; 00180 uint8_t queue_limit; 00181 uint16_t FrameNumber; 00182 uint8_t FrameCount; // 1-8 00183 HCITD* Current_itd; 00184 uint8_t Current_FrameCount; 00185 } iso; 00186 inline osEvent done_queue_get(uint32_t millisec) { return _done_queue.get(millisec); } 00187 inline void irqWdhHandler(HCTD* td) {_done_queue.put(td);} // WDH 00188 HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); 00189 HCITD* get_queue_HCITD(); 00190 HCITD* new_HCITD(); 00191 HCED(USBEndpoint* ep); 00192 void* operator new(size_t size) { return usb_ram_malloc(size, 16); } 00193 void operator delete(void* p) { usb_ram_free(p); } 00194 00195 uint8_t FunctionAddress() { 00196 return Control & 0x7f; 00197 } 00198 00199 uint8_t EndpointNumber() { 00200 return (Control>>7) & 0x7f; 00201 } 00202 00203 int Speed() { 00204 return (Control>>13)&1; 00205 } 00206 00207 void setFunctionAddress(int addr) { 00208 Control &= ~0x7f; 00209 Control |= addr; 00210 } 00211 00212 void setMaxPacketSize(uint16_t size) { 00213 Control &= ~0x07ff0000; 00214 Control |= size<<16; 00215 } 00216 00217 uint16_t getMaxPacketSize() { 00218 return (Control>>16)&0x7ff; 00219 } 00220 00221 void setToggle(uint8_t toggle); 00222 uint8_t getToggle(); 00223 00224 int Skip() { 00225 return (Control>>14) & 1; 00226 } 00227 00228 void setSkip() { 00229 Control |= (1<<14); 00230 } 00231 00232 void setFormat() { 00233 Control |= (1<<15); 00234 } 00235 00236 bool enqueue(HCTD* td); 00237 void init_queue(HCTD* td); 00238 }; 00239 00240 struct HCCA { // Host Controller Communication Area 00241 HCED* InterruptTable[32]; // +0 Interrupt Table 00242 __IO uint16_t FrameNumber;// +128 Frame Number 00243 __IO uint16_t Pad1; // +130 00244 __IO HCTD* DoneHead; // +132 Done Head 00245 uint8_t Reserved[116]; // +136 Reserved for future use 00246 uint8_t Unknown[4]; // +252 Unused 00247 // +256 00248 void* operator new(size_t size) { return usb_ram_malloc(size, 256); } 00249 void operator delete(void* p) { usb_ram_free(p); } 00250 void enqueue(HCED* ed); 00251 }; 00252 00253 class USBHALHost { 00254 protected: 00255 USBHALHost(); 00256 void init(); 00257 virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) = 0; 00258 int token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength = 0); 00259 int token_iso_in(USBEndpoint* ep, uint8_t* data, int size); 00260 int multi_token_in(USBEndpoint* ep, uint8_t* data = NULL, int size = 0); 00261 int multi_token_out(USBEndpoint* ep, const uint8_t* data = NULL, int size = 0); 00262 void multi_token_inNB(USBEndpoint* ep, uint8_t* data, int size); 00263 USB_TYPE multi_token_inNB_result(USBEndpoint* ep); 00264 void setToggle(USBEndpoint* ep, uint8_t toggle); 00265 00266 // report 00267 uint32_t m_report_irq; 00268 uint32_t m_report_RHSC; 00269 uint32_t m_report_FNO; 00270 uint32_t m_report_WDH; 00271 uint32_t m_report_sp; 00272 00273 private: 00274 void init_hw_ohci(HCCA* pHcca); 00275 void ResetRootHub(); 00276 void token_init(USBEndpoint* ep); 00277 static void _usbisr(void); 00278 void UsbIrqhandler(); 00279 HCCA* m_pHcca; 00280 bool wait_attach(); 00281 bool root_lowSpeed; 00282 static USBHALHost * instHost; 00283 }; 00284
Generated on Wed Jul 13 2022 05:41:27 by 1.7.2