mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Add USBPhy, USB HAL and Utility class
Add the USBPhy and USBPhyEvents abstract classes, the HAL header using this class and the EndpointResolver utility class.pull/9768/head
							parent
							
								
									e03b3b68c1
								
							
						
					
					
						commit
						8ae123f2d4
					
				| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include "usb_phy_api.h"
 | 
				
			||||||
 | 
					#include "mbed_error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(DEVICE_USBDEVICE) || !DEVICE_USBDEVICE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					USBPhy *get_usb_phy()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    error("This board does not have a hardware USB driver");
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** \addtogroup hal */
 | 
				
			||||||
 | 
					/** @{*/
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef MBED_USB_PHY_API_H
 | 
				
			||||||
 | 
					#define MBED_USB_PHY_API_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "USBPhy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Return a the USBPhy instance for this hardware
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * For details on adding support for a USBPhy see the specification in USBPhy.h.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return A pointer to a USBPhy instance
 | 
				
			||||||
 | 
					 * @note Calling this function on platforms without a USBPhy will result in an
 | 
				
			||||||
 | 
					 * error
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					USBPhy *get_usb_phy();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** @}*/
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,302 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef USBPHY_H
 | 
				
			||||||
 | 
					#define USBPHY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "USBPhyTypes.h"
 | 
				
			||||||
 | 
					#include "USBPhyEvents.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Abstract interface to physical USB hardware
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * # Defined behavior
 | 
				
			||||||
 | 
					 * * Any endpoint configurations which fit in the parameters of the table returned
 | 
				
			||||||
 | 
					 *      by USBPhy::endpoint_table can be used.
 | 
				
			||||||
 | 
					 * * All endpoints in any valid endpoint configuration can be used concurrently
 | 
				
			||||||
 | 
					 * * Device supports use of at least one control, bulk, interrupt and
 | 
				
			||||||
 | 
					 *      isochronous in each direction at the same time - at least 8 endpoints.
 | 
				
			||||||
 | 
					 * * Device supports all standard endpoint sizes (wMaxPacketSize)
 | 
				
			||||||
 | 
					 * * Device can handle an interrupt latency of at least 100ms if reset is not being performed and address is not being set
 | 
				
			||||||
 | 
					 * * USBPhyEvents events are only sent when USBPhy is in the initialized state
 | 
				
			||||||
 | 
					 * * When unpowered only the USBPhyEvents::power event can be sent
 | 
				
			||||||
 | 
					 * * On USB reset all endpoints are removed except for endpoint 0
 | 
				
			||||||
 | 
					 * * USBPhyEvents::out and USBPhyEvents::in events only occur for endpoints which have been added
 | 
				
			||||||
 | 
					 * * A call to USBPhy::ep0_write results in USBPhyEvents::in getting called if not
 | 
				
			||||||
 | 
					 *      interrupted by a power loss or reset
 | 
				
			||||||
 | 
					 * * A call to endpoint_read followed by endpoint_read_result results in USBPhyEvents::out getting called if not
 | 
				
			||||||
 | 
					 *      interrupted by a power loss or reset
 | 
				
			||||||
 | 
					 * * Endpoint 0 naks all transactions aside from setup packets until one
 | 
				
			||||||
 | 
					 *      of ep0_read, ep0_write or ep0_stall has been called
 | 
				
			||||||
 | 
					 * * Endpoint 0 stall is automatically cleared on reception of a setup packet
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * # Undefined behavior
 | 
				
			||||||
 | 
					 * * Calling USBPhy::endpoint_add or USBPhy::endpoint_remove outside of the control requests SetInterface or SetConfiguration
 | 
				
			||||||
 | 
					 * * Devices behavior is undefined if latency is greater than 2ms when address is being set - see USB spec 9.2.6.3
 | 
				
			||||||
 | 
					 * * Devices behavior is undefined if latency is greater than 10ms when a reset occurs - see USB spec 7.1.7.5
 | 
				
			||||||
 | 
					 * * Calling any of the USBPhy::endpoint_* functions on endpoint 0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * # Notes
 | 
				
			||||||
 | 
					 * * Make sure USB packets are processed in the correct order when multiple packets are present.
 | 
				
			||||||
 | 
					 *      Typically IN endpoints should be handled before OUT endpoints if both are pending.
 | 
				
			||||||
 | 
					 * * Setup packets may be resent if there is noise on the USB line. The USBPhy should be able
 | 
				
			||||||
 | 
					 *      to gracefully handle this scenario and respond to the setup packet with an ACK.
 | 
				
			||||||
 | 
					 * * Bi-directional protocols making use of alternating IN and OUT phases should not rely
 | 
				
			||||||
 | 
					 *      on the last ACK an IN transfer to indicate that the OUT phase should start. Instead,
 | 
				
			||||||
 | 
					 *      the OUT phase should be started at the same time the last IN transfer is started. This
 | 
				
			||||||
 | 
					 *      is because the ACK to the last in transfer may be dropped if there is noise on the USB
 | 
				
			||||||
 | 
					 *      line. If dropped it will only get re-sent on the next IN phase. More info on this can be
 | 
				
			||||||
 | 
					 *      found in section 8.5.3.3 of the USB spec.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @ingroup usb_device_core
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class USBPhy {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    USBPhy() {};
 | 
				
			||||||
 | 
					    virtual ~USBPhy() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initialize this USBPhy instance
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This function must be called before calling
 | 
				
			||||||
 | 
					     * any other functions of this class, unless specifically
 | 
				
			||||||
 | 
					     * noted.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param events Callback class to handle USB events
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void init(USBPhyEvents *events) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Power down this USBPhy instance
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Disable interrupts and stop sending events.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void deinit() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if USB power is present
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Devices which don't support checking the USB power state
 | 
				
			||||||
 | 
					     * must always return true.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return true if USB power is present, false otherwise
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool powered() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Make the USB phy visible to the USB host
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Enable either the D+ or D-  pullup so the host can detect
 | 
				
			||||||
 | 
					     * the presence of this device.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void connect() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Detach the USB phy
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Disable the D+ and D- pullup and stop responding to
 | 
				
			||||||
 | 
					     * USB traffic.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void disconnect() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Set this device to the configured state
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Enable added endpoints if they are not enabled
 | 
				
			||||||
 | 
					     * already.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void configure() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Leave the configured state
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This is a notification to the USBPhy indicating that the device
 | 
				
			||||||
 | 
					     * is leaving the configured state. The USBPhy can disable all
 | 
				
			||||||
 | 
					     * endpoints other than endpoint 0.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void unconfigure() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Enable the start of frame interrupt
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Call USBPhyEvents::sof on every frame.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void sof_enable() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Disable the start of frame interrupt
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Stop calling USBPhyEvents::sof.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void sof_disable() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Set the USBPhy's address
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param address This device's USB address
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void set_address(uint8_t address) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Wake upstream devices
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void remote_wakeup() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the endpoint table
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This function returns a table which describes the endpoints
 | 
				
			||||||
 | 
					     * can be used, the functionality of those endpoints and the
 | 
				
			||||||
 | 
					     * resource cost.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual const usb_ep_table_t* endpoint_table() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Set wMaxPacketSize of endpoint 0
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param max_packet The wMaxPacketSize value for endpoint 0
 | 
				
			||||||
 | 
					     * @return The actual size of endpoint 0
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual uint32_t ep0_set_max_packet(uint32_t max_packet) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Read the contents of the SETUP packet
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param buffer Buffer to fill with data
 | 
				
			||||||
 | 
					     * @param size Size of buffer passed in
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_setup_read_result(uint8_t *buffer, uint32_t size) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Start receiving a packet of up to wMaxPacketSize on endpoint 0
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_read() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Read the contents of a received packet
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param buffer Buffer to fill with the data read
 | 
				
			||||||
 | 
					     * @param size Size of buffer
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual uint32_t ep0_read_result(uint8_t *buffer, uint32_t size) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Write a packet on endpoint 0
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param buffer Buffer fill with data to send
 | 
				
			||||||
 | 
					     * @param size Size of data to send
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_write(uint8_t *buffer, uint32_t size) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Protocol stall on endpoint 0
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Stall all IN and OUT packets on endpoint 0 until a setup packet
 | 
				
			||||||
 | 
					     * is received.
 | 
				
			||||||
 | 
					     * @note The stall is cleared automatically when a setup packet is received
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_stall() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Configure and enable an endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to configure and enable
 | 
				
			||||||
 | 
					     * @param max_packet The maximum packet size that can be sent or received
 | 
				
			||||||
 | 
					     * @param type The type of endpoint this should be configured as -
 | 
				
			||||||
 | 
					     *  USB_EP_TYPE_BULK, USB_EP_TYPE_INT or USB_EP_TYPE_ISO
 | 
				
			||||||
 | 
					     * @note This function cannot be used to configure endpoint 0. That must be done
 | 
				
			||||||
 | 
					     * with ep0_set_max_packet
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Disable an endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to disable
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void endpoint_remove(usb_ep_t endpoint) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Perform a functional stall on the given endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Set the HALT feature for this endpoint so that all further
 | 
				
			||||||
 | 
					     * communication is aborted.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to stall
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void endpoint_stall(usb_ep_t endpoint) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Unstall the endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Clear the HALT feature on this endpoint so communication can
 | 
				
			||||||
 | 
					     * resume.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to stall
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void endpoint_unstall(usb_ep_t endpoint) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Start a read on the given endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to start the read on
 | 
				
			||||||
 | 
					     * @param max_packet A hint as to the wMaxPacketSize of this endpoint.
 | 
				
			||||||
 | 
					     *  This must match the size in endpoint_add.
 | 
				
			||||||
 | 
					     * @return true if the read was successfully started, false otherwise
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool endpoint_read(usb_ep_t endpoint, uint32_t max_packet) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Finish a read on the given endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to read data from
 | 
				
			||||||
 | 
					     * @param data Buffer to fill with data
 | 
				
			||||||
 | 
					     * @param size Size of buffer
 | 
				
			||||||
 | 
					     * @param bytes_read The number of bytes in the current packet. This can be larger than
 | 
				
			||||||
 | 
					     *  the size parameter if the buffer passed in was too small.
 | 
				
			||||||
 | 
					     * @return true if data was read false otherwise
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool endpoint_read_result(usb_ep_t endpoint, uint8_t *data, uint32_t size, uint32_t *bytes_read) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Start a write on the given endpoint
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to write to
 | 
				
			||||||
 | 
					     * @param data Buffer to write
 | 
				
			||||||
 | 
					     * @param size Size of data to write
 | 
				
			||||||
 | 
					     * @return true if the data was prepared for transmit, false otherwise
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual bool endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Abort the current transfer if it has not yet been sent
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint to abort the transfer on. It is implementation defined
 | 
				
			||||||
 | 
					     * if this function has an effect on receive endpoints.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void endpoint_abort(usb_ep_t endpoint) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback used for performing USB processing
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * USBPhy processing should be triggered by calling USBPhyEvents::start_process
 | 
				
			||||||
 | 
					     * and done inside process. All USBPhyEvents callbacks aside from
 | 
				
			||||||
 | 
					     * USBPhyEvents::start_process must be called in the context of process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void process() = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef USBPHY_EVENTS_H
 | 
				
			||||||
 | 
					#define USBPHY_EVENTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "USBPhyTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Event handler for USBPhy
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This class is the event handler for the USBPhy class. Any events generated
 | 
				
			||||||
 | 
					 * by USBPhy are passed to this class via the virtual functions.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @ingroup usb_device_core
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class USBPhyEvents {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    USBPhyEvents() {};
 | 
				
			||||||
 | 
					    virtual ~USBPhyEvents() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called when a bus reset occurs
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void reset() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called when an endpoint 0 setup packet is received
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_setup() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called when an endpoint 0 out packet is received
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_out() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called when an endpoint 0 in packet is received
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void ep0_in() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called USB power is applied or removed
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param powered true if USB power is present, false otherwise
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void power(bool powered) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called when entering or leaving suspend mode
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param suspended true if entering suspend mode false otherwise
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void suspend(bool suspended) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called on start of frame
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param frame_number The current frame number
 | 
				
			||||||
 | 
					     * @note This callback is enabled/disabled by
 | 
				
			||||||
 | 
					     *  calling USBPhy::sof_enable / USBPhy::sof_disable
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void sof(int frame_number) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called on the reception of an OUT packet
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint which received the OUT packet
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void out(usb_ep_t endpoint) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called on the transmission of an IN packet
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param endpoint Endpoint which sent the IN packet
 | 
				
			||||||
 | 
					     * @note called in the contex of USBPhy::process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void in(usb_ep_t endpoint) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Callback called to indicate the USB processing needs to be done
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    virtual void start_process() = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef USBPHY_TYPES_H
 | 
				
			||||||
 | 
					#define USBPHY_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef uint8_t usb_ep_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    USB_EP_TYPE_CTRL = 0,
 | 
				
			||||||
 | 
					    USB_EP_TYPE_ISO = 1,
 | 
				
			||||||
 | 
					    USB_EP_TYPE_BULK = 2,
 | 
				
			||||||
 | 
					    USB_EP_TYPE_INT = 3
 | 
				
			||||||
 | 
					} usb_ep_type_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum  {
 | 
				
			||||||
 | 
					    USB_EP_ATTR_ALLOW_CTRL = 1 << USB_EP_TYPE_CTRL,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_ALLOW_BULK = 1 << USB_EP_TYPE_BULK,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_ALLOW_INT = 1 << USB_EP_TYPE_INT,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_ALLOW_ISO = 1 << USB_EP_TYPE_ISO,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_ALLOW_ALL = USB_EP_ATTR_ALLOW_CTRL | USB_EP_ATTR_ALLOW_BULK |
 | 
				
			||||||
 | 
					                             USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_ALLOW_ISO,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    USB_EP_ATTR_DIR_IN = 0 << 4,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_DIR_OUT = 1 << 4,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_DIR_IN_OR_OUT = 2 << 4,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_DIR_IN_AND_OUT = 3 << 4,
 | 
				
			||||||
 | 
					    USB_EP_ATTR_DIR_MASK = 3 << 4
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef uint8_t usb_ep_attr_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct usb_ep_entry_t {
 | 
				
			||||||
 | 
					    usb_ep_attr_t attributes;
 | 
				
			||||||
 | 
					    uint8_t byte_cost;
 | 
				
			||||||
 | 
					    uint16_t base_cost;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct usb_ep_table_t {
 | 
				
			||||||
 | 
					    uint32_t resources;
 | 
				
			||||||
 | 
					    usb_ep_entry_t table[16];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,136 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "mbed.h"
 | 
				
			||||||
 | 
					#include "EndpointResolver.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t logical_to_index(uint32_t logical, bool in_not_out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (logical << 1) | (in_not_out ? 1 : 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static uint32_t index_to_logical(uint32_t index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return index >> 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EndpointResolver::EndpointResolver(const usb_ep_table_t *table) : _table(table), _cost(0), _used(0), _valid(true)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Do nothing
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EndpointResolver::~EndpointResolver()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Do nothing
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EndpointResolver::endpoint_ctrl(uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    endpoint_in(USB_EP_TYPE_CTRL, size);
 | 
				
			||||||
 | 
					    endpoint_out(USB_EP_TYPE_CTRL, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usb_ep_t EndpointResolver::endpoint_in(usb_ep_type_t type, uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int index = next_index(type, true);
 | 
				
			||||||
 | 
					    if (index < 0) {
 | 
				
			||||||
 | 
					        _valid = false;
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const usb_ep_entry_t &entry = _table->table[index_to_logical(index)];
 | 
				
			||||||
 | 
					    _cost += entry.base_cost + entry.byte_cost * size;
 | 
				
			||||||
 | 
					    _used |= 1 << index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return index_to_endpoint(index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usb_ep_t EndpointResolver::endpoint_out(usb_ep_type_t type, uint32_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int index = next_index(type, false);
 | 
				
			||||||
 | 
					    if (index < 0) {
 | 
				
			||||||
 | 
					        _valid = false;
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const usb_ep_entry_t &entry = _table->table[index_to_logical(index)];
 | 
				
			||||||
 | 
					    _cost += entry.base_cost + entry.byte_cost * size;
 | 
				
			||||||
 | 
					    _used |= 1 << index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return index_to_endpoint(index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool EndpointResolver::valid()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _valid && (_cost <= _table->resources);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EndpointResolver::reset() {
 | 
				
			||||||
 | 
					    _cost = 0;
 | 
				
			||||||
 | 
					    _used = 0;
 | 
				
			||||||
 | 
					    _valid = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usb_ep_t EndpointResolver::index_to_endpoint(int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return index_to_logical(index) | ((index & 1) ? 0x80 : 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int EndpointResolver::next_index(usb_ep_type_t type, bool in_not_out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for (int logical = 0; logical < (int)(sizeof(_table->table) / sizeof(_table->table[0])); logical++) {
 | 
				
			||||||
 | 
					        uint32_t index = logical_to_index(logical, in_not_out);
 | 
				
			||||||
 | 
					        uint32_t other = logical_to_index(logical, !in_not_out);
 | 
				
			||||||
 | 
					        const usb_ep_entry_t &entry = _table->table[logical];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        usb_ep_attr_t dir = entry.attributes & USB_EP_ATTR_DIR_MASK;
 | 
				
			||||||
 | 
					        bool in_allowed = dir != USB_EP_ATTR_DIR_OUT;
 | 
				
			||||||
 | 
					        bool out_allowed = dir != USB_EP_ATTR_DIR_IN;
 | 
				
			||||||
 | 
					        bool shared = dir == USB_EP_ATTR_DIR_IN_OR_OUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!(entry.attributes & (1 << type))) {
 | 
				
			||||||
 | 
					            // This type is not supported
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (in_not_out && !in_allowed) {
 | 
				
			||||||
 | 
					            // In endpoint not supported
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!in_not_out && !out_allowed) {
 | 
				
			||||||
 | 
					            // Out endpoint not supported
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_used & (1 << index)) {
 | 
				
			||||||
 | 
					            // This endpoint is in use
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (shared && (1 << other)) {
 | 
				
			||||||
 | 
					            // This endpoint can only be one direction at a time and is in
 | 
				
			||||||
 | 
					            // use by the other direction
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return index;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Not found
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,89 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ENDPOINT_RESOLVER_H
 | 
				
			||||||
 | 
					#define ENDPOINT_RESOLVER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "mbed.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "USBPhy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Utility class for resolving endpoints
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This class is intended to make the process of
 | 
				
			||||||
 | 
					 * selecting the correct endpoint from a device endpoint
 | 
				
			||||||
 | 
					 * table easier. It also provides a verification function
 | 
				
			||||||
 | 
					 * to check if the device has enough resources for the
 | 
				
			||||||
 | 
					 * given configuration.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @ingroup usb_device_core
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class EndpointResolver {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    EndpointResolver(const usb_ep_table_t *table);
 | 
				
			||||||
 | 
					    ~EndpointResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Add control endpoint size
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param size Space reserved for control in and control out
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void endpoint_ctrl(uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return a free IN endpoint of the given size
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param type Desired endpoint type
 | 
				
			||||||
 | 
					     * @param size Space to reserve for this endpoint
 | 
				
			||||||
 | 
					     * @return Endpoint index or 0 if there are not enough resources
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    usb_ep_t endpoint_in(usb_ep_type_t type, uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return a free OUT endpoint of the given size
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param type Desired endpoint type
 | 
				
			||||||
 | 
					     * @param size Space to reserve for this endpoint
 | 
				
			||||||
 | 
					     * @return Endpoint index or 0 if there are not enough resources
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    usb_ep_t endpoint_out(usb_ep_type_t type, uint32_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if the endpoint configuration created so far is valid
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return true if all endpoint sizes are available and fit, false otherwise
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    bool valid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reset this class's state to when it was constructed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    usb_ep_t index_to_endpoint(int index);
 | 
				
			||||||
 | 
					    int next_index(usb_ep_type_t type, bool in_not_out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const usb_ep_table_t *_table;
 | 
				
			||||||
 | 
					    uint32_t _cost;
 | 
				
			||||||
 | 
					    uint32_t _used;
 | 
				
			||||||
 | 
					    bool _valid;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
		Reference in New Issue