Peripheral interfaces
Introduction - Peripheral interfaces
The block diagram shows connections between components in the architecture of the peripheral interface.
Components peripheral interface
USB/MSC Peripheral interface
In this diagram, the byte and packet interfaces are shown to inherit from the control interface.
All peripheral drivers implement an abstract interface built on top of the driver’s internal interface. The outermost abstract interface is a packet-level interface. It returns the payload of packets to the caller. Drivers that use framing packets have another abstract interface layer that operates at the byte level. The abstract interfaces allow the higher layers to use exactly the same code regardless which peripheral is being used.
The abstract packet interface feeds into the command and data packet processor. This component interprets the packets returned by the lower layer as command or data packets.
Parent topic:Peripheral interfaces
Abstract control interface
This control interface provides a common method to initialize and shutdown peripheral drivers. It also provides the means to perform the active peripheral detection. No data transfer functionality is provided by this interface. That is handled by the interfaces that inherit the control interface.
The main reason this interface is separate from the byte and packet interfaces is to show the commonality between the two. It also allows the driver to provide a single control interface structure definition that can be easily shared.
struct PeripheralDescriptor {
//! @brief Bit mask identifying the peripheral type.
//!
//! See #_peripheral_types for a list of valid bits.
uint32_t typeMask;
//! @brief The instance number of the peripheral.
uint32_t instance;
//! @brief Configure pinmux setting for the peripheral.
void (*pinmuxConfig)(uint32_t instance, pinmux_type_t pinmux);
//! @brief Control interface for the peripheral.
const peripheral_control_interface_t * controlInterface;
//! @brief Byte-level interface for the peripheral.
//!
//! May be NULL because not all periperhals support this interface.
const peripheral_byte_inteface_t * byteInterface;
//! @brief Packet level interface for the peripheral.
const peripheral_packet_interface_t * packetInterface;
};
struct PeripheralControlInterface
{
bool (*pollForActivity)(const PeripheralDescriptor * self);
status_t (*init)(const PeripheralDescriptor * self, BoatloaderInitInfo * info);
void (*shutdown)(const PeripheralDescriptor * self);
void (*pump)(const peripheral_descriptor_t *self);
}
Abstract control interface
Interface |
Description |
---|---|
pollForActivity() |
Check whether communications has started. |
init() |
Fully initialize the driver. |
shutdown() |
Shutdown the fully initialized driver. |
pump |
Provide execution time to driver. |
Parent topic:Peripheral interfaces
Abstract byte interface
This interface gives the framing packetizer a common interface for the peripherals that use framing packets (see framing packetizer ).
The abstract byte interface inherits the abstract control interface.
struct PeripheralByteInterface
{
status_t (*init)(const peripheral_descriptor_t * self);
status_t (*write)(const peripheral_descriptor_t * self, const uint8_t *buffer, uint32_t byteCount);
};
Abstract byte interface
Interface |
Description |
---|---|
init() |
Initialize the interface |
write() |
Write the requested number of bytes |
Note: The byte interface has no read() member. Interface reads are performed in an interrupt handler at the packet level.
Parent topic:Peripheral interfaces
Abstract packet interface
The abstract packet interface inherits the abstract control interface.
status_t (*init)(const peripheral_descriptor_t *self);
status_t (*readPacket)(const peripheral_descriptor_t *self,
uint8_t **packet,
uint32_t *packetLength,
packet_type_t packetType);
status_t (*writePacket)(const peripheral_descriptor_t *self,
const uint8_t *packet,
uint32_t byteCount,
packet_type_t packetType);
void (*abortDataPhase)(const peripheral_descriptor_t *self);
status_t (*finalize)(const peripheral_descriptor_t *self);
uint32_t (*getMaxPacketSize)(const peripheral_descriptor_t *self);
void (*byteReceivedCallback)(uint8_t byte);
Abstract packet interface
Interface |
Description |
---|---|
init() |
Initialize the peripheral. |
readPacket() |
Read a full packet from the peripheral. |
writePacket() |
Send a complete packet to the peripheral. |
abortDataPhase() |
Abort receiving of data packets. |
finalize() |
Shut down the peripheral when done with use. |
getMaxPacketSize |
Returns the current maximum packet size. |
byteReceivedCallback |
Notification of received byte. |
Parent topic:Peripheral interfaces
Framing packetizer
The framing packetizer processes framing packets received via the byte interface with which it communicates. The framing packetizer builds and validates a framing packet as it reads bytes. The framing packetizer also constructs outgoing framing packets as needed to add flow control information and command or data packets. The framing packetizer also supports data phase abort.
Parent topic:Peripheral interfaces
USB HID packetizer
The USB HID packetizer implements the abstract packet interface for USB HID, taking advantage of the USB’s inherent flow control and error detection capabilities. The USB HID packetizer provides a link layer that supports variable length packets and data phase abort.
Parent topic:Peripheral interfaces
USB HID packetizer
The USB HID packetizer implements the abstract packet interface for USB HID, taking advantage of the USB’s inherent flow control and error detection capabilities.
The image shows the USB MSC command/data/status flow chart.
USB MSC status flow chart
The CBW begins on a packet boundary, and ends as a short packet. Exactly 31 bytes are transferred.
The CSW begins on a packet boundary, and ends as a short packet. Exactly 13 bytes are transferred.
The data packet begins on a packet boundary, and ends as a short packet. Exactly 64 bytes are transferred.
Parent topic:Peripheral interfaces
Command/data processor
This component reads complete packets from the abstract packet interface, and interprets them as either command packets or data packets. The actual handling of each command is done by command handlers called by the command processor. The command handler tells the command processor whether a data phase is expected and how much data it is expected to receive.
The command/data processor ignores any unexpected commands or data packets if received. In this instance, the communications link resynchronizes upon reception of the next valid command.
Parent topic:Peripheral interfaces