Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.h Source File

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