Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBPhy.h Source File

USBPhy.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 USBPHY_H
00019 #define USBPHY_H
00020 
00021 #include "USBPhyTypes.h"
00022 #include "USBPhyEvents.h"
00023 
00024 /** Abstract interface to physical USB hardware
00025  *
00026  * # Defined behavior
00027  * * You can use any endpoint configurations that fit in the parameters
00028  *      of the table returned by USBPhy::endpoint_table.
00029  * * You can use all endpoints in any valid endpoint configuration concurrently.
00030  * * The device supports use of at least one control, bulk, interrupt and
00031  *      isochronous in each direction at the same time - at least 8 endpoints.
00032  * * USBPhy supports all standard endpoint sizes (wMaxPacketSize).
00033  * * USBPhy can handle an interrupt latency of at least 100ms if the host PC
00034  *      is not performing a reset or setting the device's address.
00035  * * USBPhy only sends USBPhyEvents when it is in the initialized state.
00036  * * When unpowered, USBPhy only sends the USBPhyEvents::power event.
00037  * * On USB reset, all endpoints are removed except for endpoint 0.
00038  * * A call to USBPhy::ep0_write results in the call of USBPhyEvents::in when
00039  *      the PC reads the data unless a power loss, reset, or a call to
00040  *      USBPhy::disconnect occurs first.
00041  * * A call to USBPhy::endpoint_write results in the call of USBPhyEvents::in
00042  *      when the pc reads the data unless a power loss, reset, or a call to
00043  *      USBPhy::endpoint_abort occurs first.
00044  * * A call to USBPhy::endpoint_read results in the call of USBPhyEvents::out
00045  *      when the pc sends data unless a power loss, reset, or a call to
00046  *      USBPhy::endpoint_abort occurs first.
00047  * * Endpoint 0 naks all transactions aside from setup packets until
00048  *      higher-level code calls one of USBPhy::ep0_read, USBPhy::ep0_write or
00049  *      USBPhy::ep0_stall.
00050  * * Endpoint 0 stall automatically clears on reception of a setup packet.
00051  *
00052  * # Undefined behavior
00053  * * Calling USBPhy::endpoint_add or USBPhy::endpoint_remove outside of the
00054  *      control requests SetInterface or SetConfiguration.
00055  * * Calling USBPhy::endpoint_remove on an endpoint that has an ongoing read
00056  *      or write operation. To avoid undefined behavior, you must abort ongoing
00057  *      operations with USBPhy::endpoint_abort.
00058  * * Devices behavior is undefined if latency is greater than 2ms when address
00059  *      is being set - see USB spec 9.2.6.3.
00060  * * Devices behavior is undefined if latency is greater than 10ms when a
00061  *      reset occurs - see USB spec 7.1.7.5.
00062  * * Calling any of the USBPhy::endpoint_* functions on endpoint 0.
00063  *
00064  * # Notes
00065  * * Make sure USBPhy sends USBPhyEvents in the correct order when multiple
00066  *      packets are present. USBPhy must send IN endpoint events before OUT
00067  *      endpoint events if both are pending.
00068  * * A host PC may resend setup packets to a USB device if there is noise on
00069  *      the USB line. The USBPhy should be able to handle this scenario and
00070  *      respond to the setup packet with an ACK.
00071  * * Bidirectional protocols making use of alternating IN and OUT phases
00072  *      should not rely on the last ACK an IN transfer to indicate that the
00073  *      OUT phase should start. Instead, the OUT phase should be started at
00074  *      the same time the last IN transfer is started. This is because the ACK
00075  *      to the last in transfer may be dropped if there is noise on the USB
00076  *      line. If dropped, it will only be resent on the next IN phase. You can
00077  *      find more information on this in section 8.5.3.3 of the USB
00078  *      specification.
00079  *
00080  * @ingroup usb_device_core
00081  */
00082 class USBPhy {
00083 public:
00084     USBPhy() {};
00085     virtual ~USBPhy() {};
00086 
00087     /**
00088      * Initialize this USBPhy instance
00089      *
00090      * This function must be called before calling
00091      * any other functions of this class, unless specifically
00092      * noted.
00093      *
00094      * @param events Callback class to handle USB events
00095      */
00096     virtual void init(USBPhyEvents *events) = 0;
00097 
00098     /**
00099      * Power down this USBPhy instance
00100      *
00101      * Disable interrupts and stop sending events.
00102      */
00103     virtual void deinit() = 0;
00104 
00105     /**
00106      * Check if USB power is present
00107      *
00108      * Devices which don't support checking the USB power state
00109      * must always return true.
00110      *
00111      * @return true if USB power is present, false otherwise
00112      */
00113     virtual bool powered() = 0;
00114 
00115     /**
00116      * Make the USB phy visible to the USB host
00117      *
00118      * Enable either the D+ or D-  pullup so the host can detect
00119      * the presence of this device.
00120      */
00121     virtual void connect() = 0;
00122 
00123     /**
00124      * Detach the USB phy
00125      *
00126      * Disable the D+ and D- pullup and stop responding to
00127      * USB traffic.
00128      */
00129     virtual void disconnect() = 0;
00130 
00131     /**
00132      * Set this device to the configured state
00133      *
00134      * Enable added endpoints if they are not enabled
00135      * already.
00136      */
00137     virtual void configure() = 0;
00138 
00139     /**
00140      * Leave the configured state
00141      *
00142      * This is a notification to the USBPhy indicating that the device
00143      * is leaving the configured state. The USBPhy can disable all
00144      * endpoints other than endpoint 0.
00145      *
00146      */
00147     virtual void unconfigure() = 0;
00148 
00149     /**
00150      * Enable the start of frame interrupt
00151      *
00152      * Call USBPhyEvents::sof on every frame.
00153      */
00154     virtual void sof_enable() = 0;
00155 
00156     /**
00157      * Disable the start of frame interrupt
00158      *
00159      * Stop calling USBPhyEvents::sof.
00160      */
00161     virtual void sof_disable() = 0;
00162 
00163     /**
00164      * Set the USBPhy's address
00165      *
00166      * @param address This device's USB address
00167      */
00168     virtual void set_address(uint8_t address) = 0;
00169 
00170     /**
00171      * Wake upstream devices
00172      */
00173     virtual void remote_wakeup() = 0;
00174 
00175     /**
00176      * Get the endpoint table
00177      *
00178      * This function returns a table which describes the endpoints
00179      * can be used, the functionality of those endpoints and the
00180      * resource cost.
00181      */
00182     virtual const usb_ep_table_t *endpoint_table() = 0;
00183 
00184     /**
00185      * Set wMaxPacketSize of endpoint 0
00186      *
00187      * @param max_packet The wMaxPacketSize value for endpoint 0
00188      * @return The actual size of endpoint 0
00189      */
00190     virtual uint32_t ep0_set_max_packet(uint32_t max_packet) = 0;
00191 
00192     /**
00193      * Read the contents of the SETUP packet
00194      *
00195      * @param buffer Buffer to fill with data
00196      * @param size Size of buffer passed in
00197      */
00198     virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size) = 0;
00199 
00200     /**
00201      * Start receiving a packet of up to wMaxPacketSize on endpoint 0
00202      *
00203      * @param data Buffer to fill with the data read
00204      * @param size Size of buffer
00205      */
00206     virtual void ep0_read(uint8_t *data, uint32_t size) = 0;
00207 
00208     /**
00209      * Read the contents of a received packet
00210      *
00211      * @return Size of data read
00212      */
00213     virtual uint32_t ep0_read_result() = 0;
00214 
00215     /**
00216      * Write a packet on endpoint 0
00217      *
00218      * @param buffer Buffer fill with data to send
00219      * @param size Size of data to send
00220      */
00221     virtual void ep0_write(uint8_t *buffer, uint32_t size) = 0;
00222 
00223     /**
00224      * Protocol stall on endpoint 0
00225      *
00226      * Stall all IN and OUT packets on endpoint 0 until a setup packet
00227      * is received.
00228      * @note The stall is cleared automatically when a setup packet is received
00229      */
00230     virtual void ep0_stall() = 0;
00231 
00232     /**
00233      * Configure and enable an endpoint
00234      *
00235      * @param endpoint Endpoint to configure and enable
00236      * @param max_packet The maximum packet size that can be sent or received
00237      * @param type The type of endpoint this should be configured as -
00238      *  USB_EP_TYPE_BULK, USB_EP_TYPE_INT or USB_EP_TYPE_ISO
00239      * @note This function cannot be used to configure endpoint 0. That must be done
00240      * with ep0_set_max_packet
00241      */
00242     virtual bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type) = 0;
00243 
00244     /**
00245      * Disable an endpoint
00246      *
00247      * @param endpoint Endpoint to disable
00248      */
00249     virtual void endpoint_remove(usb_ep_t endpoint) = 0;
00250 
00251     /**
00252      * Perform a functional stall on the given endpoint
00253      *
00254      * Set the HALT feature for this endpoint so that all further
00255      * communication is aborted.
00256      *
00257      * @param endpoint Endpoint to stall
00258      */
00259     virtual void endpoint_stall(usb_ep_t endpoint) = 0;
00260 
00261     /**
00262      * Un-stall the endpoint
00263      *
00264      * Clear the HALT feature on this endpoint so communication can
00265      * resume.
00266      *
00267      * @param endpoint Endpoint to stall
00268      */
00269     virtual void endpoint_unstall(usb_ep_t endpoint) = 0;
00270 
00271     /**
00272      * Start a read on the given endpoint
00273      *
00274      * @param endpoint Endpoint to start the read on
00275      * @param data Buffer to fill with data
00276      * @param size Size of the read buffer. This must be at least
00277      *     the max packet size for this endpoint.
00278      * @return true if the read was successfully started, false otherwise
00279      */
00280     virtual bool endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size) = 0;
00281 
00282     /**
00283      * Finish a read on the given endpoint
00284      *
00285      * @param endpoint Endpoint to check
00286      * @return The number of bytes received
00287      */
00288     virtual uint32_t endpoint_read_result(usb_ep_t endpoint) = 0;
00289 
00290     /**
00291      * Start a write on the given endpoint
00292      *
00293      * @param endpoint Endpoint to write to
00294      * @param data Buffer to write
00295      * @param size Size of data to write
00296      * @return true if the data was prepared for transmit, false otherwise
00297      */
00298     virtual bool endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size) = 0;
00299 
00300     /**
00301      * Abort the current transfer if it has not yet been sent
00302      *
00303      * @param endpoint Endpoint to abort the transfer on. It is implementation defined
00304      * if this function has an effect on receive endpoints.
00305      */
00306     virtual void endpoint_abort(usb_ep_t endpoint) = 0;
00307 
00308     /**
00309      * Callback used for performing USB processing
00310      *
00311      * USBPhy processing should be triggered by calling USBPhyEvents::start_process
00312      * and done inside process. All USBPhyEvents callbacks aside from
00313      * USBPhyEvents::start_process must be called in the context of process
00314      */
00315     virtual void process() = 0;
00316 };
00317 
00318 #endif