ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
usb_printer_vendor_ch9.h File Reference

Chapter-9 SETUP router + descriptor tables for the printer/vendor demo. More...

#include <stdint.h>
#include "ra8_usb.h"
Include dependency graph for usb_printer_vendor_ch9.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  pv_req_field_t : uint8_t {
  k_pv_bm_dir_mask = 0x80U ,
  k_pv_bm_dir_in = 0x80U ,
  k_pv_bm_type_mask = 0x60U ,
  k_pv_bm_type_standard = 0x00U ,
  k_pv_bm_type_class = 0x20U ,
  k_pv_bm_type_vendor = 0x40U ,
  k_pv_bm_recip_mask = 0x1FU ,
  k_pv_bm_recip_iface = 0x01U
}
 Masks + values used to decode a SETUP bmRequestType byte. More...
enum  pv_std_request_t : uint8_t {
  k_pv_std_get_descriptor = 0x06U ,
  k_pv_std_set_address = 0x05U ,
  k_pv_std_set_configuration = 0x09U
}
 Standard bRequest codes this device answers (USB 2.0 Table 9-4). More...
enum  pv_desc_type_t : uint8_t {
  k_pv_dt_device = 0x01U ,
  k_pv_dt_config = 0x02U ,
  k_pv_dt_string = 0x03U
}
 bDescriptorType values carried in the GET_DESCRIPTOR wValue high byte (USB 2.0 Table 9-5). More...
enum  pv_printer_request_t : uint8_t {
  k_pv_pprn_get_device_id = 0x00U ,
  k_pv_pprn_get_port_status = 0x01U ,
  k_pv_pprn_soft_reset = 0x02U
}
 Printer class bRequest codes (USB Printer Class 1.1 sec 4.2). More...
enum  pv_action_t : uint8_t {
  k_pv_action_stall = 0U ,
  k_pv_action_get_device_desc = 1U ,
  k_pv_action_get_config_desc = 2U ,
  k_pv_action_get_string_desc = 3U ,
  k_pv_action_set_address = 4U ,
  k_pv_action_set_configuration = 5U ,
  k_pv_action_printer_class = 6U ,
  k_pv_action_vendor_class = 7U
}
 The decision pv_route_setup produces for a SETUP envelope. More...

Functions

static pv_action_t pv_route_get_descriptor (const ra8_usb_setup_t *setup)
 Route a standard GET_DESCRIPTOR by its wValue high byte.
static pv_action_t pv_route_standard (const ra8_usb_setup_t *setup)
 Route a standard request by its bRequest code.
static pv_action_t pv_route_setup (const ra8_usb_setup_t *setup)
 Classify an 8-byte SETUP envelope into a pv_action_t.
static bool pv_is_printer_class_request (const ra8_usb_setup_t *setup)
 Recognise an interface-directed Printer class-specific request.
static bool pv_descriptor (pv_action_t action, const uint8_t **out_desc, uint16_t *out_len)
 Fetch the descriptor byte table + length for a descriptor action.
static uint16_t pv_clamp_len (uint16_t available, uint16_t requested)
 Clamp a descriptor length to the host's advertised wLength.

Variables

static const uint8_t g_pv_device_desc []
 18-byte DEVICE descriptor for the composite printer + vendor gadget.
static const uint8_t g_pv_config_desc []
 55-byte CONFIGURATION descriptor: IF0 Printer + IF1 Vendor.
static const uint8_t g_pv_string0_desc []
 STRING descriptor index 0 – the supported-language ID array.

Detailed Description

Chapter-9 SETUP router + descriptor tables for the printer/vendor demo.

Tag
[Ring 6 / APP] {World: NS}

The pure, hardware-free heart of the usb_printer_vendor example. The native ra8_usb device driver plus the ra8_usb_pprn (Printer) and ra8_usb_pvnd (vendor-specific) class layers do not carry a USB chapter-9 responder of their own – they expect the application to answer the standard GET_DESCRIPTOR / SET_ADDRESS / SET_CONFIGURATION requests and to route the class / vendor SETUPs into the class layers. This module factors that decision logic out of main.c into static inline pure functions plus the descriptor byte tables, so both the firmware and the host test compile the SAME code and it can be exercised with full MC/DC coverage (the header-only pattern, mirroring er_pageturn.h):

  • pv_route_setup classifies an incoming 8-byte SETUP envelope into a pv_action_t (which descriptor to stage, whether to ACK a no-data request, or which class layer owns the request).
  • pv_descriptor hands back the byte table + length for a descriptor action.
  • pv_clamp_len applies the wLength ceiling the host advertises.
  • pv_is_printer_class_request is the compound recognition predicate the Printer interface uses (USB Printer Class 1.1 sec 4.2).

The composite configuration advertises two interfaces so a single enumeration exercises both class layers:

  • IF0: Printer, class 0x07 / subclass 0x01 / protocol 0x02 (bi-directional). Bulk OUT EP 0x01 (print data) + bulk IN EP 0x82 (printer status).
  • IF1: Vendor specific, class 0xFF. Bulk IN EP 0x81 + bulk OUT EP 0x02.

The wire-format descriptor byte tables follow USB 2.0 sec 9.6; the byte values are protocol constants documented inline (the same convention the other USB device examples use for their descriptor blobs).

Reference: USB 2.0 sec 9.4 "Standard Device Requests", sec 9.6 "Standard USB Descriptor Definitions"; USB Printer Class 1.1 sec 4.2 "Class Specific Requests".

Author
Brighton Sikarskie
Date
2026-07-16
Since
0.1.0

Definition in file usb_printer_vendor_ch9.h.

Enumeration Type Documentation

◆ pv_action_t

enum pv_action_t : uint8_t

The decision pv_route_setup produces for a SETUP envelope.

Each value tells main.c exactly which side effect to run on the default control pipe (DCP / EP0): stage a specific descriptor, ACK a no-data request, hand off to a class layer, or STALL an unsupported request.

See also
pv_route_setup
pv_descriptor
Enumerator
k_pv_action_stall 

Unsupported: STALL EP0.

k_pv_action_get_device_desc 

Stage the DEVICE descriptor.

k_pv_action_get_config_desc 

Stage the CONFIGURATION descriptor.

k_pv_action_get_string_desc 

Stage the STRING (LANGID) descriptor.

k_pv_action_set_address 

SET_ADDRESS: SIE-owned, ACK.

k_pv_action_set_configuration 

SET_CONFIGURATION: ACK + go live.

k_pv_action_printer_class 

Route to the Printer class layer.

k_pv_action_vendor_class 

Route to the Vendor class layer.

Definition at line 141 of file usb_printer_vendor_ch9.h.

◆ pv_desc_type_t

enum pv_desc_type_t : uint8_t

bDescriptorType values carried in the GET_DESCRIPTOR wValue high byte (USB 2.0 Table 9-5).

Enumerator
k_pv_dt_device 

DEVICE descriptor.

k_pv_dt_config 

CONFIGURATION descriptor.

k_pv_dt_string 

STRING descriptor.

Definition at line 108 of file usb_printer_vendor_ch9.h.

◆ pv_printer_request_t

enum pv_printer_request_t : uint8_t

Printer class bRequest codes (USB Printer Class 1.1 sec 4.2).

Enumerator
k_pv_pprn_get_device_id 

GET_DEVICE_ID.

k_pv_pprn_get_port_status 

GET_PORT_STATUS.

k_pv_pprn_soft_reset 

SOFT_RESET.

Definition at line 118 of file usb_printer_vendor_ch9.h.

◆ pv_req_field_t

enum pv_req_field_t : uint8_t

Masks + values used to decode a SETUP bmRequestType byte.

Per USB 2.0 sec 9.3 Table 9-2: bit 7 is direction, bits 6:5 are the request type, bits 4:0 are the recipient. The class layer needs the type field (standard / class / vendor) to route the request and the recipient field to recognise the interface-directed Printer requests.

See also
pv_route_setup
Enumerator
k_pv_bm_dir_mask 

Direction bit 7 (1 = device->host).

k_pv_bm_dir_in 

Device-to-host control read.

k_pv_bm_type_mask 

Request-type field, bits 6:5.

k_pv_bm_type_standard 

Standard request.

k_pv_bm_type_class 

Class request.

k_pv_bm_type_vendor 

Vendor request.

k_pv_bm_recip_mask 

Recipient field, bits 4:0.

k_pv_bm_recip_iface 

Interface recipient.

Definition at line 77 of file usb_printer_vendor_ch9.h.

◆ pv_std_request_t

enum pv_std_request_t : uint8_t

Standard bRequest codes this device answers (USB 2.0 Table 9-4).

The chapter-9 responder only needs the three requests the host issues during enumeration of a bulk-only device: GET_DESCRIPTOR (the bulk of the traffic), SET_ADDRESS, and SET_CONFIGURATION. All other standard requests are stalled.

Enumerator
k_pv_std_get_descriptor 

GET_DESCRIPTOR.

k_pv_std_set_address 

SET_ADDRESS.

k_pv_std_set_configuration 

SET_CONFIGURATION.

Definition at line 97 of file usb_printer_vendor_ch9.h.

Function Documentation

◆ pv_clamp_len()

uint16_t pv_clamp_len ( uint16_t available,
uint16_t requested )
inlinestatic

Clamp a descriptor length to the host's advertised wLength.

Parameters
[in]availableFull descriptor length the device can offer.
[in]requestedThe host's wLength ceiling.
Returns
min(available, requested).
Precondition
None.
Postcondition
Return value is <= both arguments.
Note
Reentrant and thread-safe.
Since
0.1.0

Definition at line 485 of file usb_printer_vendor_ch9.h.

Referenced by demo_printer_setup(), and demo_stage_descriptor().

◆ pv_descriptor()

bool pv_descriptor ( pv_action_t action,
const uint8_t ** out_desc,
uint16_t * out_len )
inlinestatic

Fetch the descriptor byte table + length for a descriptor action.

Parameters
[in]actionA pv_action_t. Only the three GET_DESCRIPTOR actions resolve to a table.
[out]out_descReceives a pointer to the static descriptor bytes.
[out]out_lenReceives the descriptor's full byte length.
Returns
true when action names a descriptor and the pointers were populated; false for a non-descriptor action or a NULL output pointer.
Precondition
out_desc and out_len are non-NULL.
Postcondition
On true, *out_desc / *out_len describe a static buffer.
On false, the outputs are left untouched.
Note
Reentrant and thread-safe: returns pointers to static const data.
See also
pv_route_setup
Since
0.1.0

Definition at line 448 of file usb_printer_vendor_ch9.h.

References g_pv_config_desc, g_pv_device_desc, g_pv_string0_desc, k_pv_action_get_config_desc, k_pv_action_get_device_desc, and k_pv_action_get_string_desc.

Referenced by demo_stage_descriptor(), and demo_usb_bringup().

◆ pv_is_printer_class_request()

bool pv_is_printer_class_request ( const ra8_usb_setup_t * setup)
inlinestatic

Recognise an interface-directed Printer class-specific request.

The compound predicate the Printer interface applies before it answers a class SETUP: the recipient field must be "interface" AND the bRequest must be one of the three Printer 1.1 requests (GET_DEVICE_ID, GET_PORT_STATUS, SOFT_RESET). USB Printer Class 1.1 sec 4.2.

Parameters
[in]setupDecoded SETUP packet (may be NULL).
Returns
true when the envelope is an interface-recipient Printer request, false otherwise (including NULL).
Precondition
None (NULL tolerated).
Postcondition
No state mutated (pure function).
Note
Reentrant and thread-safe.
See also
pv_route_setup
Since
0.1.0

Definition at line 415 of file usb_printer_vendor_ch9.h.

References ra8_usb_setup_t::b_request, ra8_usb_setup_t::bm_request_type, k_pv_bm_recip_iface, k_pv_bm_recip_mask, k_pv_pprn_get_device_id, k_pv_pprn_get_port_status, and k_pv_pprn_soft_reset.

◆ pv_route_get_descriptor()

pv_action_t pv_route_get_descriptor ( const ra8_usb_setup_t * setup)
inlinestatic

Route a standard GET_DESCRIPTOR by its wValue high byte.

Parameters
[in]setupDecoded SETUP (non-NULL, standard GET_DESCRIPTOR).
Returns
pv_action_t The resolved descriptor action, or k_pv_action_stall for an unknown descriptor type.
Precondition
setup is non-NULL (caller-guaranteed).
The request is a standard GET_DESCRIPTOR.
Postcondition
No state mutated (pure function).
Note
Reentrant and thread-safe.
Since
0.1.0

Definition at line 297 of file usb_printer_vendor_ch9.h.

References k_pv_action_get_config_desc, k_pv_action_get_device_desc, k_pv_action_get_string_desc, k_pv_action_stall, k_pv_dt_config, k_pv_dt_device, k_pv_dt_string, and ra8_usb_setup_t::w_value.

Referenced by pv_route_standard().

◆ pv_route_setup()

pv_action_t pv_route_setup ( const ra8_usb_setup_t * setup)
inlinestatic

Classify an 8-byte SETUP envelope into a pv_action_t.

Decodes bmRequestType bits 6:5 (request type). Standard requests are further switched on bRequest: GET_DESCRIPTOR maps to a per-descriptor action keyed on the wValue high byte, SET_ADDRESS and SET_CONFIGURATION map to their own actions, and everything else STALLs. Class requests route to k_pv_action_printer_class and vendor requests to k_pv_action_vendor_class; the class layers then validate the specific request. A NULL envelope STALLs.

Parameters
[in]setupDecoded SETUP packet (may be NULL).
Returns
pv_action_t The decoded action.
Return values
k_pv_action_stallsetup is NULL or unsupported.
k_pv_action_get_device_descStandard GET_DESCRIPTOR(DEVICE).
k_pv_action_get_config_descStandard GET_DESCRIPTOR(CONFIGURATION).
k_pv_action_get_string_descStandard GET_DESCRIPTOR(STRING).
k_pv_action_set_addressStandard SET_ADDRESS.
k_pv_action_set_configurationStandard SET_CONFIGURATION.
k_pv_action_printer_classAny class-type request.
k_pv_action_vendor_classAny vendor-type request.
Precondition
None (NULL tolerated).
Postcondition
No state mutated (pure function).
Note
Reentrant and thread-safe: reads only the argument.
See also
pv_descriptor
Since
0.1.0

Definition at line 376 of file usb_printer_vendor_ch9.h.

References ra8_usb_setup_t::bm_request_type, k_pv_action_printer_class, k_pv_action_stall, k_pv_action_vendor_class, k_pv_bm_type_class, k_pv_bm_type_mask, k_pv_bm_type_standard, k_pv_bm_type_vendor, and pv_route_standard().

Referenced by demo_dispatch_setup().

◆ pv_route_standard()

pv_action_t pv_route_standard ( const ra8_usb_setup_t * setup)
inlinestatic

Route a standard request by its bRequest code.

Parameters
[in]setupDecoded SETUP (non-NULL, standard request type).
Returns
pv_action_t The resolved standard action, or k_pv_action_stall.
Precondition
setup is non-NULL (caller-guaranteed).
The request type is standard.
Postcondition
No state mutated (pure function).
Note
Reentrant and thread-safe.
Since
0.1.0

Definition at line 326 of file usb_printer_vendor_ch9.h.

References ra8_usb_setup_t::b_request, k_pv_action_set_address, k_pv_action_set_configuration, k_pv_action_stall, k_pv_std_get_descriptor, k_pv_std_set_address, k_pv_std_set_configuration, and pv_route_get_descriptor().

Referenced by pv_route_setup().

Variable Documentation

◆ g_pv_config_desc

const uint8_t g_pv_config_desc[]
static

55-byte CONFIGURATION descriptor: IF0 Printer + IF1 Vendor.

wTotalLength = 0x0037. IF0 is Printer 0x07/0x01/0x02 with bulk OUT EP 0x01 + bulk IN EP 0x82; IF1 is Vendor 0xFF with bulk IN EP 0x81

  • bulk OUT EP 0x02. Endpoint addresses match the pipe assignments ra8_usb_pprn (PIPE3/PIPE4) and ra8_usb_pvnd (PIPE5/PIPE1) program.
    Note
    Read-only wire-format constant.
    Since
    0.1.0

Definition at line 196 of file usb_printer_vendor_ch9.h.

Referenced by pv_descriptor().

◆ g_pv_device_desc

const uint8_t g_pv_device_desc[]
static
Initial value:
= {
0x12U,
0x01U,
0x00U,
0x02U,
0x00U,
0x00U,
0x00U,
0x40U,
0x09U,
0x12U,
0x01U,
0x00U,
0x00U,
0x01U,
0x00U,
0x00U,
0x00U,
0x01U,
}

18-byte DEVICE descriptor for the composite printer + vendor gadget.

bDeviceClass = 0x00 (class declared per interface), 64-byte EP0, VID/PID from the pid.codes test range, one configuration.

Note
Read-only wire-format constant.
Since
0.1.0

Definition at line 165 of file usb_printer_vendor_ch9.h.

Referenced by pv_descriptor().

◆ g_pv_string0_desc

const uint8_t g_pv_string0_desc[]
static
Initial value:
= {
0x04U,
0x03U,
0x09U,
0x04U,
}

STRING descriptor index 0 – the supported-language ID array.

Single LANGID 0x0409 (English, US), little-endian, per USB 2.0 sec 9.6.7. The device advertises no string indices, so this is the only string the host requests.

Note
Read-only wire-format constant.
Since
0.1.0

Definition at line 270 of file usb_printer_vendor_ch9.h.

Referenced by pv_descriptor().