USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
BaseUsbHostCtlEp.cpp
00001 // BaseUsbHostCtlEp.cpp 2013/2/11 00002 #include "mbed.h" 00003 #include "rtos.h" 00004 #include "BaseUsbHost.h" 00005 //#define DEBUG 00006 #include "BaseUsbHostDebug.h" 00007 #define TEST 00008 #include "BaseUsbHostTest.h" 00009 00010 #pragma pack(push,1) 00011 struct SETUP { 00012 uint8_t bmRequestType;// +0 00013 uint8_t bRequest; // +1 00014 uint16_t wValue; // +2 00015 uint16_t wIndex; // +4 00016 uint16_t wLength; // +6 00017 // +8 00018 SETUP(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length) { 00019 CTASSERT(sizeof(SETUP) == 8); 00020 TEST_ASSERT(sizeof(SETUP) == 8); 00021 bmRequestType = RequestType; 00022 bRequest = Request; 00023 wValue = Value; 00024 wIndex = Index; 00025 wLength = Length; 00026 }; 00027 }; 00028 #pragma pack(pop) 00029 00030 static uint8_t device_addr = 1; 00031 ControlEp::ControlEp(int lowSpeed):BaseEp(0, 0, 8, lowSpeed) 00032 { 00033 CTASSERT(HCTD_QUEUE_SIZE >= 3); 00034 TEST_ASSERT(HCTD_QUEUE_SIZE >= 3); 00035 HCTD* td = new HCTD(this); 00036 TEST_ASSERT(td); 00037 m_pED->TailTd = td; 00038 m_pED->HeadTd = td; 00039 00040 m_pED->Next = reinterpret_cast<HCED*>(LPC_USB->HcControlHeadED); 00041 LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(m_pED); 00042 00043 DBG_OHCI(LPC_USB->HcControlHeadED); 00044 DBG_ED(m_pED); 00045 00046 int r = open(device_addr); 00047 if (r == USB_OK) { 00048 device_addr++; 00049 } 00050 } 00051 00052 int ControlEp::SetAddress(int addr) 00053 { 00054 return controlSend(0x00, 5, addr); 00055 } 00056 00057 int ControlEp::GetDescriptor(int descType, int descIndex, uint8_t* data, int length) 00058 { 00059 return controlReceive(0x80, 6, (descType<<8)|descIndex, 0, data, length); 00060 } 00061 00062 int ControlEp::SetConfiguration(int config) 00063 { 00064 return controlSend(0x00, 9, config); 00065 } 00066 00067 int ControlEp::GetConfiguration(int *config) 00068 { 00069 uint8_t buf[1]; 00070 int rc = controlReceive(0x80, 8, 0, 0, buf, 1); 00071 *config = buf[0]; 00072 return rc; 00073 } 00074 00075 int ControlEp::SetInterfaceAlternate(int interface, int alternate) 00076 { 00077 int rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, 00078 SET_INTERFACE, alternate, interface, NULL, 0); 00079 return rc; 00080 } 00081 00082 int ControlEp::GetInterface(int interface, int *alternate) 00083 { 00084 uint8_t buf[1]; 00085 int rc = controlReceive(0x81, 10, 0, interface, buf, 1); 00086 *alternate = buf[0]; 00087 return rc; 00088 } 00089 00090 string ControlEp::GetStringDescriptor(int index) 00091 { 00092 string s = ""; 00093 uint8_t buf[128]; 00094 int r = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, buf, sizeof(buf)); 00095 if (r != USB_OK) { 00096 return s; 00097 } 00098 DBG_HEX(buf, sizeof(buf)); 00099 StandardStringDescriptor* desc = reinterpret_cast<StandardStringDescriptor*>(buf); 00100 if (desc->bLength <= 2 || desc->bDescriptorType != 3) { 00101 return s; 00102 } 00103 for(int i = 0; i < desc->bLength-2; i += 2) { 00104 s += desc->bString[i]; 00105 } 00106 return s; 00107 } 00108 00109 int ControlEp::open(int addr) 00110 { 00111 TEST_ASSERT(addr >= 1 && addr <= 127); 00112 uint8_t buf[8]; 00113 int r = GetDescriptor(1, 0, buf, 8); 00114 if (r != USB_OK) { 00115 return r; 00116 } 00117 TEST_ASSERT(buf[0] == 0x12); 00118 TEST_ASSERT(buf[1] == 0x01); 00119 TEST_ASSERT(buf[7] >= 8); 00120 update_MaxPacketSize(buf[7]); 00121 r = SetAddress(addr); 00122 TEST_ASSERT(r == USB_OK); 00123 if (r != USB_OK) { 00124 return r; 00125 } 00126 wait_ms(2); 00127 update_FunctionAddress(addr); 00128 return USB_OK; 00129 } 00130 00131 int ControlEp::controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, 00132 uint8_t* data, int length) { 00133 DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length); 00134 HCTD* setup_td = m_pED->TailTd; 00135 SETUP setup(bmRequestType, bRequest, wValue, wIndex, length); 00136 setup_td->transfer(reinterpret_cast<uint8_t*>(&setup), sizeof(SETUP)); 00137 setup_td->Control |= TD_TOGGLE_0|TD_SETUP|TD_DI; 00138 00139 HCTD* data_td = new HCTD(this); 00140 TEST_ASSERT(data_td); 00141 data_td->transfer(data, length); 00142 data_td->Control |= TD_TOGGLE_1|TD_IN|TD_DI; 00143 setup_td->Next = data_td; 00144 00145 HCTD* status_td = new HCTD(this); 00146 TEST_ASSERT(status_td); 00147 status_td->Control |= TD_TOGGLE_1|TD_OUT; // OUT(DATA1) 00148 data_td->Next = status_td; 00149 00150 HCTD* blank_td = new HCTD(this); 00151 TEST_ASSERT(blank_td); 00152 status_td->Next = blank_td; 00153 m_pED->TailTd = blank_td; 00154 00155 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; 00156 LPC_USB->HcControl |= OR_CONTROL_CLE; 00157 00158 int r = wait_queue_HCTD(setup_td, 100); // wait setup stage 00159 if (r != USB_OK) { 00160 return r; 00161 } 00162 HCTD* td = get_queue_HCTD(100); 00163 if (td == data_td) { 00164 delete td; 00165 } else { 00166 DBG_TD(td); 00167 TEST_ASSERT(td == data_td); 00168 return USB_ERROR; 00169 } 00170 r = wait_queue_HCTD(status_td, 100); // wait status stage 00171 return r; 00172 } 00173 00174 int ControlEp::controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, 00175 const uint8_t* data, int length) { 00176 DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length); 00177 HCTD* setup_td = m_pED->TailTd; 00178 00179 HCTD* status_td = new HCTD(this); 00180 TEST_ASSERT(status_td); 00181 HCTD* blank_td = new HCTD(this); 00182 TEST_ASSERT(blank_td); 00183 00184 SETUP setup(bmRequestType, bRequest, wValue, wIndex, length); 00185 setup_td->transfer(reinterpret_cast<uint8_t*>(&setup), sizeof(SETUP)); 00186 setup_td->Control |= TD_TOGGLE_0|TD_SETUP|TD_DI; 00187 status_td->Control |= TD_TOGGLE_1|TD_IN; // IN(DATA1) 00188 setup_td->Next = status_td; 00189 status_td->Next = blank_td; 00190 00191 if (length != 0) { 00192 HCTD* data_td = new HCTD(this); 00193 TEST_ASSERT(data_td); 00194 data_td->Control |= TD_TOGGLE_1|TD_OUT|TD_DI; 00195 data_td->transfer(const_cast<uint8_t*>(data), length); 00196 setup_td->Next = data_td; 00197 data_td->Next = status_td; 00198 } 00199 m_pED->TailTd = blank_td; 00200 DBG_ED(m_pED); 00201 00202 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; 00203 LPC_USB->HcControl |= OR_CONTROL_CLE; 00204 00205 int r = wait_queue_HCTD(status_td, 200); // wait status stage 00206 return r; 00207 } 00208 00209 HCTD::HCTD(BaseEp* obj) { 00210 CTASSERT(sizeof(HCTD) == 36); 00211 TEST_ASSERT(sizeof(HCTD) == 36); 00212 TEST_ASSERT(obj); 00213 Control = TD_CC|TD_ROUNDING; 00214 CurrBufPtr = NULL; 00215 Next = NULL; 00216 BufEnd = NULL; 00217 buf_top = NULL; 00218 buf_size = 0; 00219 ep = obj; 00220 }
Generated on Fri Jul 15 2022 19:56:09 by 1.7.2