Skip to content

Commit

Permalink
[#66346] pw_usb: Add headers
Browse files Browse the repository at this point in the history
  • Loading branch information
lkedziora committed Sep 30, 2024
1 parent ba8b722 commit fb81e92
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
97 changes: 97 additions & 0 deletions pw_usb/device/controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#pragma once

#include "endpoint.h"
#include "event.h"
#include "pw_function/function.h"
#include "pw_result/result.h"
#include "pw_span/span.h"
#include "pw_status/status.h"

namespace pw::usb_device {

// clang-format off
using EndpointDataFunction = Function<void(pw::usb_device::EndpointAddress, span<const std::byte>)>;
using EventFunction = Function<void(pw::usb_device::Event)>;
using StatusUpdateFunction = Function<void(pw::Status)>;
// clang-format on

// Controller class allows platform-agnostic access to the bottom
// layer of an USB device as defined in USB 2.0 Specification, Ch.9
// (USB Device Framework).
// See also:
// - USB 2.0 Specification, Ch.5.2.2 (USB Devices).
// - USB 2.0 Specification, Figure 5.9
class Controller {
public:
/// Initialize the controller.
/// This must be called before calling any other method of the `Controller`.
// `complete_callback` will be called with the result of initialization.
// `error_callback` will be called for fatal errors that occur after
// initialization. After a fatal error, this object is invalid. `Close` should
// be called to ensure a safe clean up.
virtual void Initialize(StatusUpdateFunction complete_callback,
StatusUpdateFunction error_callback) = 0;
/// Deinitialize the controller.
/// The given function is called when deinitialization of the controller was
/// completed.
virtual void Close(StatusUpdateFunction) = 0;

/// Fully enable the USB controller and start sending out events.
/// Called after `Initialize` and configuration of all required
/// endpoints/event functions.
///
/// This is separate from initialization, as it may involve enabling
/// USB clocks.
///
/// The given function is called when enabling the controller was
/// completed.
virtual void Run(StatusUpdateFunction) = 0;
/// Disable the USB controller and stop sending out events
/// This may disable the USB clock to lower power consumption.
/// The controller may be reenabled by calling `Run` again.
///
/// The given function is called when enabling the controller was
/// completed.
virtual void Stop(StatusUpdateFunction) = 0;

/// Set an event handler function to be called when certain
/// low-level USB events occur. This should be called before
/// calling `Initialize` to ensure no events are missed.
virtual void SetEventFunction(EventFunction) = 0;

/// Initialize a given endpoint
/// This must be called before any data can be received or sent to
/// the endpoint.
/// `callback` will be called with the result of the operation.
virtual void InitEndpoint(pw::usb_device::EndpointAddress endpoint,
StatusUpdateFunction callback) = 0;
/// Deinitialize a given endpoint
/// This must be called when an endpoint is not used anymore (for example,
/// as a result of interface or configuration change).
/// `callback` will be called with the result of the operation.
virtual void DeinitEndpoint(pw::usb_device::EndpointAddress endpoint,
StatusUpdateFunction callback) = 0;
/// Stall a given endpoint
/// `callback` will be called with the result of the operation.
virtual void StallEndpoint(pw::usb_device::EndpointAddress endpoint,
StatusUpdateFunction callback) = 0;
/// Unstall a given endpoint
/// `callback` will be called with the result of the operation.
virtual void UnstallEndpoint(pw::usb_device::EndpointAddress endpoint,
StatusUpdateFunction callback) = 0;

/// Send data over an endpoint asynchronously
/// The given endpoint must have been initialized beforehand using
/// `InitEndpoint`. The endpoint must be an IN endpoint (direction
/// bit set).
virtual void Send(pw::usb_device::EndpointAddress endpoint,
span<const std::byte> data) = 0;
/// Set a function to be called when data is received
/// The given function is called when data is received on any endpoint.
/// Data passed to the function is only valid for the duration of the
/// call.
virtual void SetReceiveFunction(EndpointDataFunction) = 0;

private:
};
} // namespace pw::usb_device
20 changes: 20 additions & 0 deletions pw_usb/device/endpoint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <cstdint>
namespace pw::usb_device {
/// Represents an endpoint number
/// The USB specification allows for 16 unique endpoints.
using EndpointNumber = uint8_t;

/// Represents the address of an USB endpoint
/// The bit format of the address is as follows:
/// Bit | 7 6 5 4 3 2 1 0
/// Value | D 0 0 0 N N N N
/// Where D represents the direction of the endpoint (0 - OUT, 1 - IN)
/// and N the endpoint number. As such, 32 endpoints can be addressed,
/// or 16 pipes - each one consisting of an IN and OUT endpoint.
/// The direction is host-centric, so OUT means data outgoing from
/// a host to the device, while IN signifies data inbound from device
/// to the host.
using EndpointAddress = uint8_t;
} // namespace pw::usb_device
9 changes: 9 additions & 0 deletions pw_usb/device/event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

namespace pw::usb_device {
enum class Event {
BusReset,
Detach,
Attach,
};
}

0 comments on commit fb81e92

Please sign in to comment.