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

Native USB device-side Printer class layer. More...

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

Go to the source code of this file.

Typedefs

typedef ra8_err_t(* ra8_usb_pprn_setup_fn_t) (void *ctx, const ra8_usb_setup_t *setup)
 Caller-supplied printer class-setup handler signature.

Enumerations

enum  ra8_usb_pprn_pipe_t : uint8_t {
  k_ra8_pprn_pipe_bulk_out = 3U ,
  k_ra8_pprn_pipe_bulk_in = 4U
}
 PIPE numbers used by the device-Printer function for the local bulk endpoints. More...
enum  ra8_usb_pprn_ep_t : uint8_t {
  k_ra8_pprn_ep_bulk_out_addr = 1U ,
  k_ra8_pprn_ep_bulk_in_addr = 2U
}
 USB endpoint addresses used by the device-Printer function. More...
enum  ra8_usb_pprn_packet_t : uint16_t {
  k_ra8_pprn_bulk_max_packet_fs = 64U ,
  k_ra8_pprn_bulk_max_packet_hs = 512U
}
 Packet sizing for the bulk endpoints. More...
enum  ra8_usb_pprn_class_t : uint8_t {
  k_ra8_pprn_class_printer = 0x07U ,
  k_ra8_pprn_subclass_default = 0x01U ,
  k_ra8_pprn_protocol_unidir = 0x01U ,
  k_ra8_pprn_protocol_bidir = 0x02U ,
  k_ra8_pprn_protocol_1284_4 = 0x03U
}
 Class / subclass / protocol triplet that identifies the local Printer function in the configuration descriptor. More...
enum  ra8_usb_pprn_request_t : uint8_t {
  k_ra8_pprn_req_get_device_id = 0x00U ,
  k_ra8_pprn_req_get_port_status = 0x01U ,
  k_ra8_pprn_req_soft_reset = 0x02U
}
 Printer class-specific request codes the host issues to the device. More...
enum  ra8_usb_pprn_port_status_bit_t : uint8_t {
  k_ra8_pprn_status_bit_paper_empty = 5U ,
  k_ra8_pprn_status_bit_select = 4U ,
  k_ra8_pprn_status_bit_not_error = 3U
}
 Bit positions in the 1-byte GET_PORT_STATUS response. More...

Functions

ra8_err_t ra8_usb_pprn_init (ra8_usb_speed_t speed)
 Bring up the device-Printer function on a chosen USB controller.
ra8_err_t ra8_usb_pprn_close (void)
 Tear down the device-Printer function and release the controller.
ra8_err_t ra8_usb_pprn_set_descriptors (const uint8_t *desc, uint16_t desc_len, const uint8_t *device_id, uint16_t device_id_len)
 Install the caller-supplied descriptor blob and IEEE 1284 device-ID string.
ra8_err_t ra8_usb_pprn_recv (uint8_t *buf, uint16_t max_len, uint16_t *got_len)
 Drain inbound print-job data from the bulk-OUT endpoint.
ra8_err_t ra8_usb_pprn_send (const uint8_t *data, uint16_t len)
 Push outbound printer-status bytes on the bulk-IN endpoint.
ra8_err_t ra8_usb_pprn_set_port_status (uint8_t status_byte)
 Update the local port-status byte returned by GET_PORT_STATUS.
ra8_err_t ra8_usb_pprn_get_port_status (uint8_t *out_status)
 Read the current port-status byte.
ra8_err_t ra8_usb_pprn_attach_setup_handler (ra8_usb_pprn_setup_fn_t setup_fn, void *ctx)
 Register the application's printer class-setup handler.
ra8_err_t ra8_usb_pprn_handle_setup (const ra8_usb_setup_t *setup)
 Process a class-specific SETUP packet on EP0.

Detailed Description

Native USB device-side Printer class layer.

Glues the device-mode ra8_usb controller driver to a USB Printer class function so the EK-RA8D2 enumerates as a uni-directional or bi-directional printer gadget. The implementation is from-scratch; FSP r_usb_pprn_driver.c is reference material only – nothing is pulled in verbatim. Mirrors the surface that FSP's peripheral-Printer class exposes:

  • Caller-supplied descriptor blob (configuration + interface + bulk EP descriptors).
  • Bulk-OUT pipe (PIPE3) for inbound print-job data.
  • Bulk-IN pipe (PIPE4) for outbound printer status (bi-directional interfaces only; protocol 0x02 / 0x03).
  • Caller-supplied class-setup callback so the application answers GET_DEVICE_ID, GET_PORT_STATUS, and SOFT_RESET (USB Printer Class 1.1 sec 4.2 "Class Specific Requests").
  • Local port_status shadow (paper-out / select / not-error bits) that the application updates and the class layer can hand back on GET_PORT_STATUS without re-entering the application.

Reference: USB Device Class Definition for Printing Devices revision 1.1 (USB-IF, 2000-01-25).

Definition in file ra8_usb_pprn.h.

Typedef Documentation

◆ ra8_usb_pprn_setup_fn_t

typedef ra8_err_t(* ra8_usb_pprn_setup_fn_t) (void *ctx, const ra8_usb_setup_t *setup)

Caller-supplied printer class-setup handler signature.

The class layer pre-decodes the SETUP envelope (validates it really is a printer class request on the printer interface) and hands the SETUP packet to the application. The application either lets the default handler answer GET_PORT_STATUS / SOFT_RESET from the local shadow, or installs custom logic (e.g. queueing a device-ID string for GET_DEVICE_ID).

Parameters
[in]ctxCaller-supplied context registered alongside the handler.
[in]setupThe 8-byte SETUP envelope (class request).
Returns
ra8_err_t error code; k_ra8_ok lets the class layer ACK the status stage, anything else stalls EP0.
Note
Invoked from the dispatch site (typically ISR context) when a printer class SETUP lands.

Definition at line 150 of file ra8_usb_pprn.h.

Enumeration Type Documentation

◆ ra8_usb_pprn_class_t

enum ra8_usb_pprn_class_t : uint8_t

Class / subclass / protocol triplet that identifies the local Printer function in the configuration descriptor.

Per USB Printer 1.1 sec 4.1 "Standard Descriptor Definition". Subclass 1 is the only defined value. Protocol 1 = uni-directional (OUT only), 2 = bi-directional, 3 = IEEE 1284.4 bi-directional.

Enumerator
k_ra8_pprn_class_printer 

Printer interface class.

k_ra8_pprn_subclass_default 

Printers subclass.

k_ra8_pprn_protocol_unidir 

Uni-directional.

k_ra8_pprn_protocol_bidir 

Bi-directional.

k_ra8_pprn_protocol_1284_4 

IEEE 1284.4 bi-dir.

Definition at line 94 of file ra8_usb_pprn.h.

◆ ra8_usb_pprn_ep_t

enum ra8_usb_pprn_ep_t : uint8_t

USB endpoint addresses used by the device-Printer function.

Enumerator
k_ra8_pprn_ep_bulk_out_addr 

EP1 OUT address.

k_ra8_pprn_ep_bulk_in_addr 

EP2 IN address.

Definition at line 68 of file ra8_usb_pprn.h.

◆ ra8_usb_pprn_packet_t

enum ra8_usb_pprn_packet_t : uint16_t

Packet sizing for the bulk endpoints.

Per USB 2.0 sec 5.8.3, FS bulk = 8/16/32/64 bytes and HS bulk = 512 bytes.

Enumerator
k_ra8_pprn_bulk_max_packet_fs 

Bulk size at FS.

k_ra8_pprn_bulk_max_packet_hs 

Bulk size at HS.

Definition at line 80 of file ra8_usb_pprn.h.

◆ ra8_usb_pprn_pipe_t

enum ra8_usb_pprn_pipe_t : uint8_t

PIPE numbers used by the device-Printer function for the local bulk endpoints.

FSP / RA8D2 PIPE assignment rules constrain bulk pipes to PIPE1..PIPE5. PIPE3 carries bulk OUT (host -> printer print data), PIPE4 carries bulk IN (printer -> host status, bi-directional only). USB Printer 1.1 sec 4.1.1 "Endpoint Descriptors".

Enumerator
k_ra8_pprn_pipe_bulk_out 

PIPE3 -> EP1 OUT (print data).

k_ra8_pprn_pipe_bulk_in 

PIPE4 -> EP2 IN (status).

Definition at line 59 of file ra8_usb_pprn.h.

◆ ra8_usb_pprn_port_status_bit_t

Bit positions in the 1-byte GET_PORT_STATUS response.

Per USB Printer 1.1 sec 4.2.2 "GET_PORT_STATUS". Bits 0..2 are reserved-as-0, bits 3 / 4 / 5 carry the printer-state flags.

Enumerator
k_ra8_pprn_status_bit_paper_empty 

1 = paper empty.

k_ra8_pprn_status_bit_select 

1 = printer online.

k_ra8_pprn_status_bit_not_error 

1 = no error.

Definition at line 123 of file ra8_usb_pprn.h.

◆ ra8_usb_pprn_request_t

enum ra8_usb_pprn_request_t : uint8_t

Printer class-specific request codes the host issues to the device.

Per USB Printer 1.1 sec 4.2 "Class Specific Requests". The three values are the entirety of the printer class request set.

Enumerator
k_ra8_pprn_req_get_device_id 

GET_DEVICE_ID.

k_ra8_pprn_req_get_port_status 

GET_PORT_STATUS.

k_ra8_pprn_req_soft_reset 

SOFT_RESET.

Definition at line 110 of file ra8_usb_pprn.h.

Function Documentation

◆ ra8_usb_pprn_attach_setup_handler()

ra8_err_t ra8_usb_pprn_attach_setup_handler ( ra8_usb_pprn_setup_fn_t setup_fn,
void * ctx )
nodiscard

Register the application's printer class-setup handler.

Pass NULL for setup_fn to detach. The class layer pre-decodes the SETUP envelope and forwards it if its bmRequestType indicates a class-recipient-interface request and its bRequest is one of GET_DEVICE_ID / GET_PORT_STATUS / SOFT_RESET.

Parameters
[in]setup_fnApplication's handler. NULL detaches.
[in]ctxContext pointer threaded back into setup_fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okHandler installed.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_pprn_init succeeded.
Postcondition
On the next class SETUP, setup_fn(ctx, &setup) fires.
Note
Not thread-safe.
Since
0.1.0

Definition at line 333 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

Referenced by demo_usb_bringup().

◆ ra8_usb_pprn_close()

ra8_err_t ra8_usb_pprn_close ( void )
nodiscard

Tear down the device-Printer function and release the controller.

Returns
ra8_err_t error code.
Return values
k_ra8_okReleased.
k_ra8_err_invalid_stateDriver was never initialized.
Precondition
Single-threaded shutdown context.
Postcondition
ra8_usb_device_deinit ran; D+ pull-up dropped; subsequent device-Printer API calls return k_ra8_err_invalid_state.
Note
Not thread-safe.
Since
0.1.0

Definition at line 219 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_state, ra8_usb_device_attach(), ra8_usb_device_deinit(), and s_state.

◆ ra8_usb_pprn_get_port_status()

ra8_err_t ra8_usb_pprn_get_port_status ( uint8_t * out_status)
nodiscard

Read the current port-status byte.

Parameters
[out]out_statusReceives the current status byte.
Returns
ra8_err_t error code.
Return values
k_ra8_okValue copied.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrout_status was NULL.
Precondition
out_status non-NULL.
Postcondition
No internal state mutated.
Note
Not thread-safe.
Since
0.1.0

Definition at line 318 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

Referenced by demo_printer_setup().

◆ ra8_usb_pprn_handle_setup()

ra8_err_t ra8_usb_pprn_handle_setup ( const ra8_usb_setup_t * setup)
nodiscard

Process a class-specific SETUP packet on EP0.

Switches on b_request: SOFT_RESET re-arms the bulk pipes internally; GET_DEVICE_ID / GET_PORT_STATUS forward to the registered application handler if any (the application normally queues the device-ID payload or the port-status byte itself). Standard (non-class) SETUPs are rejected with k_ra8_err_not_supported.

Parameters
[in]setupThe SETUP packet returned by ra8_usb_read_setup_if_valid.
Returns
ra8_err_t error code.
Return values
k_ra8_okSETUP handled (status stage queued internally).
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrsetup was NULL.
k_ra8_err_not_supportedbRequest is not a printer class request.
Precondition
ra8_usb_pprn_init succeeded.
Postcondition
Internal port-status shadow may have been refreshed by the application callback.
Note
Call from the CTRT ISR path of ra8_usb.
Since
0.1.0

Definition at line 348 of file ra8_usb_pprn.c.

References ra8_usb_setup_t::b_request, ra8_usb_setup_t::bm_request_type, internal_is_known_class_request(), k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_ok, k_ra8_pprn_bm_class_iface_in, k_ra8_pprn_bm_class_iface_out, RA8_CHECK_NULL_PTR, ra8_usb_control_response(), s_state, and s_tag.

Referenced by demo_dispatch_setup().

◆ ra8_usb_pprn_init()

ra8_err_t ra8_usb_pprn_init ( ra8_usb_speed_t speed)
nodiscard

Bring up the device-Printer function on a chosen USB controller.

Initialises the underlying ra8_usb driver in DEVICE mode for speed, configures PIPE3 (bulk OUT) and PIPE4 (bulk IN), seeds the port-status shadow to "select | not-error" (online, no error, no paper-out), and leaves the D+ pull-up dropped. The caller raises it via ra8_usb_device_attach once descriptors are set.

Parameters
[in]speedWhich USB controller (FS or HS).
Returns
ra8_err_t error code.
Return values
k_ra8_okDevice-Printer ready.
k_ra8_err_invalid_argspeed out of range.
k_ra8_err_hw_init_failedUnderlying ra8_usb_device_init failed.
Precondition
Single-threaded init context.
ra8_mstp_init and ra8_pwr_init already ran.
Postcondition
Internal state machine armed; descriptor pointer cleared.
Pipe3 / pipe4 configured at the speed's default packet size.
Note
Not thread-safe.
See also
ra8_usb_pprn_set_descriptors
ra8_usb_pprn_close
Since
0.1.0

Definition at line 201 of file ra8_usb_pprn.c.

References internal_configure_pipes(), internal_reset_shadow(), k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, ra8_log_error_val, ra8_log_info_val, ra8_usb_device_init(), s_state, and s_tag.

Referenced by demo_usb_bringup().

◆ ra8_usb_pprn_recv()

ra8_err_t ra8_usb_pprn_recv ( uint8_t * buf,
uint16_t max_len,
uint16_t * got_len )
nodiscard

Drain inbound print-job data from the bulk-OUT endpoint.

Parameters
[out]bufReceive buffer.
[in]max_lenCapacity of buf, > 0.
[out]got_lenReceives the number of bytes actually placed.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes drained.
k_ra8_err_no_dataPipe was empty.
k_ra8_err_null_ptrbuf or got_len was NULL.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_invalid_argmax_len == 0.
Precondition
ra8_usb_pprn_init succeeded.
Postcondition
On success *got_len reflects the actual byte count.
Note
Not thread-safe.
Since
0.1.0

Definition at line 269 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_pprn_pipe_bulk_out, RA8_CHECK_NULL_PTR, ra8_usb_queue_out(), s_state, and s_tag.

Referenced by demo_drain_print_job().

◆ ra8_usb_pprn_send()

ra8_err_t ra8_usb_pprn_send ( const uint8_t * data,
uint16_t len )
nodiscard

Push outbound printer-status bytes on the bulk-IN endpoint.

Only meaningful on a bi-directional printer interface (protocol 0x02 / 0x03). Uni-directional printers should ignore this function.

Parameters
[in]dataStatus payload.
[in]lenPayload length.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes queued onto bulk-IN.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrdata was NULL with len > 0.
k_ra8_err_invalid_arglen == 0 or larger than the pipe max.
Precondition
ra8_usb_pprn_init succeeded.
Postcondition
len bytes sit on PIPE4.
Note
Not thread-safe.
Since
0.1.0

Definition at line 290 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_pprn_pipe_bulk_in, ra8_usb_queue_in(), and s_state.

◆ ra8_usb_pprn_set_descriptors()

ra8_err_t ra8_usb_pprn_set_descriptors ( const uint8_t * desc,
uint16_t desc_len,
const uint8_t * device_id,
uint16_t device_id_len )
nodiscard

Install the caller-supplied descriptor blob and IEEE 1284 device-ID string.

The descriptor blob is the configuration / interface / EP descriptor triplet (or quadruplet for bi-directional). The device-ID string is the IEEE 1284-style device-ID payload returned by GET_DEVICE_ID; USB Printer 1.1 sec 4.2.1 "GET_DEVICE_ID" specifies a 2-byte big-endian length followed by the device-ID string. Pass device_id == NULL / device_id_len == 0 if the caller will instead handle GET_DEVICE_ID via its setup callback.

Parameters
[in]descPointer to the caller-owned descriptor blob.
[in]desc_lenByte length of desc.
[in]device_idPointer to the IEEE 1284 device-ID payload (caller-owned, may be NULL).
[in]device_id_lenByte length of device_id.
Returns
ra8_err_t error code.
Return values
k_ra8_okPointers + lengths stored.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrdesc was NULL.
k_ra8_err_invalid_argdesc_len == 0, or (device_id != NULL) ^ (device_id_len > 0).
Precondition
ra8_usb_pprn_init succeeded.
Postcondition
GET_DESCRIPTOR(Configuration) and GET_DEVICE_ID requests are served from these buffers.
Note
Not thread-safe.
Since
0.1.0

Definition at line 239 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

Referenced by demo_usb_bringup().

◆ ra8_usb_pprn_set_port_status()

ra8_err_t ra8_usb_pprn_set_port_status ( uint8_t status_byte)
nodiscard

Update the local port-status byte returned by GET_PORT_STATUS.

The shape of the byte is documented in ra8_usb_pprn_port_status_bit_t. The application typically calls this from its job-scheduler (e.g. when the paper sensor flips state).

Parameters
[in]status_byteThe new port-status byte.
Returns
ra8_err_t error code.
Return values
k_ra8_okShadow updated.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_pprn_init succeeded.
Postcondition
ra8_usb_pprn_get_port_status reflects the new value.
Note
Not thread-safe.
Since
0.1.0

Definition at line 309 of file ra8_usb_pprn.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.