Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
USBDevice.h
00001 /* 00002 * Copyright (c) 2018-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #ifndef USBDEVICE_H 00019 #define USBDEVICE_H 00020 00021 #include <stddef.h> 00022 #include "USBDevice_Types.h" 00023 #include "USBPhy.h" 00024 #include "mbed_critical.h" 00025 #include "Callback.h" 00026 00027 /** 00028 * \defgroup drivers_USBDevice USBDevice class 00029 * \ingroup drivers-internal-api-usb 00030 * @{ 00031 */ 00032 00033 /** 00034 * Core USB Device driver 00035 * 00036 * USB driver which wraps and provides synchronization for a USBPhy object. 00037 */ 00038 class USBDevice: public USBPhyEvents { 00039 public: 00040 typedef void (USBDevice::*ep_cb_t)(); 00041 00042 enum RequestResult { 00043 Receive = 0, 00044 Send = 1, 00045 Success = 2, 00046 Failure = 3, 00047 PassThrough = 4, 00048 }; 00049 00050 enum DeviceState { 00051 Attached, 00052 Powered, 00053 Default, 00054 Address, 00055 Configured 00056 }; 00057 00058 struct setup_packet_t { 00059 struct { 00060 uint8_t dataTransferDirection; 00061 uint8_t Type; 00062 uint8_t Recipient; 00063 } bmRequestType; 00064 uint8_t bRequest; 00065 uint16_t wValue; 00066 uint16_t wIndex; 00067 uint16_t wLength; 00068 }; 00069 00070 /** 00071 * Instantiate a new USBDevice with the given parameters 00072 * 00073 * @param phy The USBPhy providing physical USB access 00074 * @param vendor_id The USB vendor ID 00075 * @param product_id The USB product ID 00076 * @param product_release The device release number 00077 */ 00078 USBDevice(USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release); 00079 00080 /** 00081 * Cleanup this USBDevice 00082 * 00083 * This USBDevice must be uninitialized when the destructor is 00084 * called or the behavior is undefined. 00085 */ 00086 virtual ~USBDevice(); 00087 00088 /** 00089 * Initialize this instance 00090 * 00091 * This function must be called before calling 00092 * any other functions of this class, unless specifically 00093 */ 00094 void init(); 00095 00096 /** 00097 * Power down this instance 00098 * 00099 * Disable interrupts and stop sending events. 00100 * This method can be used for temporary power-saving; This call can allow 00101 * USB to be temporarily disabled to permit power saving. 00102 * However, it is up to the user to make sure all the 00103 * transfers have concluded (for example when USB power is lost). 00104 * USBDevice::connect can be used to resume USB operation. 00105 */ 00106 void deinit(); 00107 00108 /** 00109 * Check if the device is configured 00110 * 00111 * @returns true if configured, false otherwise 00112 */ 00113 bool configured(); 00114 00115 /** 00116 * Connect a device 00117 * This method can also be used to resume USB operation when USB power is 00118 * detected after it was suspended via USBDevice::deinit. 00119 */ 00120 void connect(); 00121 00122 /** 00123 * Disconnect a device 00124 */ 00125 void disconnect(); 00126 00127 /** 00128 * Enable the start of frame interrupt 00129 * 00130 * Call USBDevice::callback_sof on every frame. 00131 */ 00132 void sof_enable(); 00133 00134 /** 00135 * Disable the start of frame interrupt 00136 * 00137 * Stop calling USBDevice::callback_sof. 00138 */ 00139 void sof_disable(); 00140 00141 /** 00142 * Add an endpoint 00143 * 00144 * @param endpoint Endpoint to enable 00145 * @param max_packet Maximum size of a packet which can be sent or received on this endpoint 00146 * @param type Endpoint type - USB_EP_TYPE_BULK, USB_EP_TYPE_INT or USB_EP_TYPE_ISO 00147 * @param callback Method pointer to be called when a packet is transferred 00148 * @returns true if successful, false otherwise 00149 */ 00150 bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type, mbed::Callback<void()> callback = NULL); 00151 00152 /** 00153 * Add an endpoint 00154 * 00155 * @param endpoint Endpoint to enable 00156 * @param max_packet Maximum size of a packet which can be sent or received on this endpoint 00157 * @param type Endpoint type - USB_EP_TYPE_BULK, USB_EP_TYPE_INT or USB_EP_TYPE_ISO 00158 * @param callback Method pointer to be called when a packet is transferred 00159 * @returns true if successful, false otherwise 00160 */ 00161 template<typename T> 00162 bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type, void (T::*callback)()) 00163 { 00164 return endpoint_add(endpoint, max_packet, type, mbed::callback(this, static_cast<ep_cb_t>(callback))); 00165 } 00166 00167 /** 00168 * Remove an endpoint 00169 * 00170 * @param endpoint Endpoint to disable 00171 * @note This endpoint must already have been setup with endpoint_add 00172 */ 00173 void endpoint_remove(usb_ep_t endpoint); 00174 00175 /** 00176 * Remove all non-zero endpoints 00177 */ 00178 void endpoint_remove_all(); 00179 00180 /** 00181 * Stall an endpoint 00182 * 00183 * If there is an ongoing transfer on this endpoint then it will 00184 * be aborted. 00185 * 00186 * @param endpoint Endpoint to stall 00187 * @note You cannot stall endpoint 0 with this function 00188 * @note This endpoint must already have been setup with endpoint_add 00189 */ 00190 void endpoint_stall(usb_ep_t endpoint); 00191 00192 /** 00193 * Un-stall an endpoint 00194 * 00195 * Un-stalling an endpoint resets data toggle back to DATA0. 00196 * Additionally, if there is an ongoing transfer on this endpoint 00197 * it will be aborted. 00198 * 00199 * @param endpoint Endpoint to un-stall 00200 * @note This endpoint must already have been setup with endpoint_add 00201 */ 00202 void endpoint_unstall(usb_ep_t endpoint); 00203 00204 /** 00205 * Get the current maximum size for this endpoint 00206 * 00207 * Return the currently configured maximum packet size, wMaxPacketSize, 00208 * for this endpoint. 00209 * @note This endpoint must already have been setup with endpoint_add 00210 */ 00211 uint32_t endpoint_max_packet_size(usb_ep_t endpoint); 00212 00213 /** 00214 * Abort the current transfer on this endpoint 00215 * 00216 * @param endpoint endpoint with transfer to abort 00217 * @note This endpoint must already have been setup with endpoint_add 00218 */ 00219 void endpoint_abort(usb_ep_t endpoint); 00220 00221 /** 00222 * start a read on the given endpoint 00223 * 00224 * Start a read on the given endpoint. The data buffer must remain 00225 * unchanged until the transfer either completes or is aborted. 00226 * 00227 * @param endpoint endpoint to read data from 00228 * @param buffer buffer to fill with read data 00229 * @param size The size of data to read. This must be greater than or equal 00230 * to the max packet size for this endpoint 00231 * @return true if the read was completed, otherwise false 00232 * @note This endpoint must already have been setup with endpoint_add 00233 */ 00234 bool read_start(usb_ep_t endpoint, uint8_t *buffer, uint32_t size); 00235 00236 /** 00237 * Get the status of a read 00238 * 00239 * @param endpoint endpoint to get the status of 00240 * @return number of bytes read by this endpoint 00241 */ 00242 uint32_t read_finish(usb_ep_t endpoint); 00243 00244 /** 00245 * Write a data to the given endpoint 00246 * 00247 * Write data to an endpoint. The data sent must remain unchanged until 00248 * the transfer either completes or is aborted. 00249 * 00250 * @param endpoint endpoint to write data to 00251 * @param buffer data to write 00252 * @param size the size of data to send. This must be less than or equal to the 00253 * max packet size of this endpoint 00254 * @note This endpoint must already have been setup with endpoint_add 00255 */ 00256 bool write_start(usb_ep_t endpoint, uint8_t *buffer, uint32_t size); 00257 00258 /** 00259 * Get the status of a write 00260 * 00261 * @param endpoint endpoint to get the status of 00262 * @return number of bytes sent by this endpoint 00263 */ 00264 uint32_t write_finish(usb_ep_t endpoint); 00265 00266 /* 00267 * Get device descriptor. 00268 * 00269 * @returns pointer to the device descriptor 00270 */ 00271 virtual const uint8_t *device_desc(); 00272 00273 /* 00274 * Get configuration descriptor 00275 * 00276 * @param index descriptor index 00277 * @returns pointer to the configuration descriptor 00278 */ 00279 virtual const uint8_t *configuration_desc(uint8_t index) = 0; 00280 00281 /* 00282 * Get string lang id descriptor 00283 * 00284 * @return pointer to the string lang id descriptor 00285 */ 00286 virtual const uint8_t *string_langid_desc(); 00287 00288 /* 00289 * Get string manufacturer descriptor 00290 * 00291 * @returns pointer to the string manufacturer descriptor 00292 */ 00293 virtual const uint8_t *string_imanufacturer_desc(); 00294 00295 /* 00296 * Get string product descriptor 00297 * 00298 * @returns pointer to the string product descriptor 00299 */ 00300 virtual const uint8_t *string_iproduct_desc(); 00301 00302 /* 00303 * Get string serial descriptor 00304 * 00305 * @returns pointer to the string serial descriptor 00306 */ 00307 virtual const uint8_t *string_iserial_desc(); 00308 00309 /* 00310 * Get string configuration descriptor 00311 * 00312 * @returns pointer to the string configuration descriptor 00313 */ 00314 virtual const uint8_t *string_iconfiguration_desc(); 00315 00316 /* 00317 * Get string interface descriptor 00318 * 00319 * @returns pointer to the string interface descriptor 00320 */ 00321 virtual const uint8_t *string_iinterface_desc(); 00322 00323 /* 00324 * Get the length of the report descriptor 00325 * 00326 * @returns length of the report descriptor 00327 */ 00328 virtual uint16_t report_desc_dength() 00329 { 00330 return 0; 00331 }; 00332 00333 protected: 00334 00335 /** 00336 * Called by USBDevice layer on power state change. 00337 * 00338 * @param powered true if device is powered, false otherwise 00339 * 00340 * Warning: Called in ISR context 00341 */ 00342 virtual void callback_power(bool powered) 00343 { 00344 00345 } 00346 00347 /** 00348 * Called by USBDevice layer on each new USB frame. 00349 * 00350 * Callbacks are enabled and disabled by calling sof_enable 00351 * and sof_disable. 00352 * 00353 * @param frame_number The current frame number 00354 * 00355 * Warning: Called in ISR context 00356 */ 00357 virtual void callback_sof(int frame_number) 00358 { 00359 00360 } 00361 00362 /** 00363 * Called by USBDevice layer on bus reset. 00364 * 00365 * complete_reset must be called after 00366 * the device is fully reset. 00367 * 00368 * Warning: Called in ISR context 00369 */ 00370 virtual void callback_reset() 00371 { 00372 00373 } 00374 00375 /** 00376 * Called when USB changes state 00377 * 00378 * @param new_state The new state of the USBDevice 00379 * 00380 * Warning: Called in ISR context 00381 */ 00382 virtual void callback_state_change(DeviceState new_state) = 0; 00383 00384 /** 00385 * Called by USBDevice on Endpoint0 request. 00386 * 00387 * This is used to handle extensions to standard requests 00388 * and class specific requests. The function complete_request 00389 * must be always be called in response to this callback. 00390 * 00391 * Warning: Called in ISR context 00392 */ 00393 virtual void callback_request(const setup_packet_t *setup) = 0; 00394 00395 /** 00396 * Called to complete the setup stage of a callback request 00397 * 00398 * Possible options that can be passed as a result are: 00399 * - Receive - Start the data OUT phase of this control transfer 00400 * - Send - Start the data IN phase of this control transfer 00401 * - Success - Operation was a success so start the status phase 00402 * - Failure - Operation failed or is unsupported so send a stall 00403 * - PassThrough - Pass on the request for standard processing 00404 * 00405 * @param result The result of the setup phase. 00406 * @param data Buffer to send or receive if the result is Send or Receive 00407 * @param size Size to transfer if the result is Send or Receive 00408 */ 00409 void complete_request(RequestResult result, uint8_t *data = NULL, uint32_t size = 0); 00410 00411 /** 00412 * Called by USBDevice on data stage completion 00413 * 00414 * The function complete_request_xfer_done must be always be called 00415 * in response to this callback. 00416 * 00417 * @param setup Setup packet of the current request 00418 * @param aborted false if the operation was aborted, true otherwise 00419 * 00420 * Warning: Called in ISR context 00421 */ 00422 virtual void callback_request_xfer_done(const setup_packet_t *setup, bool aborted) = 0; 00423 00424 /** 00425 * Called to complete the data stage of a callback request 00426 * 00427 * @param success true if the operation was successful, false otherwise 00428 */ 00429 void complete_request_xfer_done(bool success); 00430 00431 /* 00432 * Called by USBDevice layer in response to set_configuration. 00433 * 00434 * Upon reception of this command endpoints of the previous configuration 00435 * if any must be removed with endpoint_remove and new endpoint added with 00436 * endpoint_add. 00437 * 00438 * @param configuration Number of the configuration 00439 * 00440 * Warning: Called in ISR context 00441 */ 00442 virtual void callback_set_configuration(uint8_t configuration) = 0; 00443 00444 /** 00445 * Called to complete a set configuration command 00446 * 00447 * @param success true if the configuration was set, false otherwise 00448 */ 00449 void complete_set_configuration(bool success); 00450 00451 /* 00452 * Called by USBDevice layer in response to set_interface. 00453 * 00454 * Upon reception of this command endpoints of any previous interface 00455 * if any must be removed with endpoint_remove and new endpoint added with 00456 * endpoint_add. 00457 * 00458 * @param configuration Number of the configuration 00459 * 00460 * Warning: Called in ISR context 00461 */ 00462 virtual void callback_set_interface(uint16_t interface, uint8_t alternate) = 0; 00463 00464 /** 00465 * Called to complete a set interface command 00466 * 00467 * @param success true if the interface was set, false otherwise 00468 */ 00469 void complete_set_interface(bool success); 00470 00471 /** 00472 * Find a descriptor type inside the configuration descriptor 00473 * 00474 * @param descriptor_type Type of descriptor to find 00475 * @param index Configuration descriptor index ( 0 if only one configuration present ) 00476 * @return A descriptor of the given type or NULL if none were found 00477 */ 00478 uint8_t *find_descriptor(uint8_t descriptor_type, uint8_t index = 0); 00479 00480 /** 00481 * Get the endpoint table of this device 00482 * 00483 * @return Endpoint table of the USBPhy attached to this USBDevice 00484 */ 00485 const usb_ep_table_t *endpoint_table(); 00486 00487 /** 00488 * Callback called to indicate the USB processing needs to be done 00489 */ 00490 virtual void start_process(); 00491 00492 /** 00493 * Acquire exclusive access to this instance USBDevice 00494 */ 00495 virtual void lock(); 00496 00497 /** 00498 * Release exclusive access to this instance USBDevice 00499 */ 00500 virtual void unlock(); 00501 00502 /** 00503 * Assert that the current thread of execution holds the lock 00504 * 00505 */ 00506 virtual void assert_locked(); 00507 00508 uint16_t vendor_id; 00509 uint16_t product_id; 00510 uint16_t product_release; 00511 uint8_t device_descriptor[18]; 00512 00513 private: 00514 // USBPhyEvents 00515 virtual void power(bool powered); 00516 virtual void suspend(bool suspended); 00517 virtual void sof(int frame_number); 00518 virtual void reset(); 00519 virtual void ep0_setup(); 00520 virtual void ep0_out(); 00521 virtual void ep0_in(); 00522 virtual void out(usb_ep_t endpoint); 00523 virtual void in(usb_ep_t endpoint); 00524 00525 bool _request_get_descriptor(); 00526 bool _control_out(); 00527 bool _control_in(); 00528 bool _request_set_address(); 00529 bool _request_set_configuration(); 00530 bool _request_set_feature(); 00531 bool _request_clear_feature(); 00532 bool _request_get_status(); 00533 bool _request_setup(); 00534 void _control_setup(); 00535 void _control_abort(); 00536 void _control_abort_start(); 00537 void _control_setup_continue(); 00538 void _decode_setup_packet(uint8_t *data, setup_packet_t *packet); 00539 bool _request_get_configuration(); 00540 bool _request_get_interface(); 00541 bool _request_set_interface(); 00542 void _change_state(DeviceState state); 00543 void _run_later(void (USBDevice::*function)()); 00544 00545 void _complete_request(); 00546 void _complete_request_xfer_done(); 00547 void _complete_set_configuration(); 00548 void _complete_set_interface(); 00549 00550 struct endpoint_info_t { 00551 mbed::Callback<void()> callback; 00552 uint16_t max_packet_size; 00553 uint16_t transfer_size; 00554 uint8_t flags; 00555 uint8_t pending; 00556 }; 00557 00558 struct usb_device_t { 00559 volatile DeviceState state; 00560 uint8_t configuration; 00561 bool suspended; 00562 }; 00563 00564 enum ControlState { 00565 Setup, 00566 DataOut, 00567 DataIn, 00568 Status 00569 }; 00570 00571 enum UserCallback { 00572 None, 00573 Request, 00574 RequestXferDone, 00575 SetConfiguration, 00576 SetInterface 00577 }; 00578 00579 struct complete_request_t { 00580 RequestResult result; 00581 uint8_t *data; 00582 uint32_t size; 00583 }; 00584 00585 union complete_args_t { 00586 complete_request_t request; 00587 bool status; 00588 }; 00589 00590 struct control_transfer_t { 00591 setup_packet_t setup; 00592 uint8_t *ptr; 00593 uint32_t remaining; 00594 uint8_t direction; 00595 bool zlp; 00596 bool notify; 00597 ControlState stage; 00598 UserCallback user_callback; 00599 complete_args_t args; 00600 }; 00601 00602 endpoint_info_t _endpoint_info[32 - 2]; 00603 00604 USBPhy *_phy; 00605 bool _initialized; 00606 bool _connected; 00607 bool _endpoint_add_remove_allowed; 00608 control_transfer_t _transfer; 00609 usb_device_t _device; 00610 uint32_t _max_packet_size_ep0; 00611 void (USBDevice::*_post_process)(); 00612 00613 bool _setup_ready; 00614 bool _abort_control; 00615 00616 uint16_t _current_interface; 00617 uint8_t _current_alternate; 00618 uint32_t _locked; 00619 }; 00620 00621 /** @}*/ 00622 00623 #endif
Generated on Tue Jul 12 2022 13:55:02 by
