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

Native USB host-side CDC-ECM (Ethernet over USB) class layer implementation. More...

#include "ra8_usb_hcdc_ecm.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
#include "ra8_usb.h"
Include dependency graph for ra8_usb_hcdc_ecm.c:

Go to the source code of this file.

Data Structures

struct  ra8_usb_hcdc_ecm_state_t
 Singleton shadow state for the host-CDC-ECM driver. More...

Enumerations

enum  ra8_usb_hcdc_ecm_step_t : uint8_t {
  k_ra8_hcdc_ecm_step_idle = 0U ,
  k_ra8_hcdc_ecm_step_bus_reset = 1U ,
  k_ra8_hcdc_ecm_step_set_address = 2U ,
  k_ra8_hcdc_ecm_step_get_dev_desc = 3U ,
  k_ra8_hcdc_ecm_step_get_cfg_desc = 4U ,
  k_ra8_hcdc_ecm_step_set_config = 5U ,
  k_ra8_hcdc_ecm_step_walk_desc = 6U ,
  k_ra8_hcdc_ecm_step_get_string_mac = 7U ,
  k_ra8_hcdc_ecm_step_set_filter = 8U ,
  k_ra8_hcdc_ecm_step_set_interface = 9U ,
  k_ra8_hcdc_ecm_step_done = 10U
}
 Enumeration step machine states. More...
enum  ra8_usb_hcdc_ecm_setup_field_t : uint8_t {
  k_ra8_hcdc_ecm_bm_std_dev_in = 0x80U ,
  k_ra8_hcdc_ecm_bm_std_dev_out = 0x00U ,
  k_ra8_hcdc_ecm_bm_std_iface_out = 0x01U ,
  k_ra8_hcdc_ecm_breq_get_descriptor = 0x06U ,
  k_ra8_hcdc_ecm_breq_set_address = 0x05U ,
  k_ra8_hcdc_ecm_breq_set_config = 0x09U ,
  k_ra8_hcdc_ecm_breq_set_interface = 0x0BU ,
  k_ra8_hcdc_ecm_bm_class_iface_out = 0x21U ,
  k_ra8_hcdc_ecm_bm_class_iface_in = 0xA1U ,
  k_ra8_hcdc_ecm_desc_device = 0x01U ,
  k_ra8_hcdc_ecm_desc_configuration = 0x02U ,
  k_ra8_hcdc_ecm_desc_string = 0x03U ,
  k_ra8_hcdc_ecm_desc_interface = 0x04U ,
  k_ra8_hcdc_ecm_desc_endpoint = 0x05U ,
  k_ra8_hcdc_ecm_desc_cs_interface = 0x24U ,
  k_ra8_hcdc_ecm_func_subtype_ecm = 0x0FU
}
 Standard chapter-9 + CDC-ECM class request bmRequestType / bRequest encodings. More...
enum  ra8_usb_hcdc_ecm_size_t : uint16_t {
  k_ra8_hcdc_ecm_dev_desc_len = 18U ,
  k_ra8_hcdc_ecm_cfg_desc_len = 9U ,
  k_ra8_hcdc_ecm_iface_desc_len = 9U ,
  k_ra8_hcdc_ecm_ep_desc_len = 7U ,
  k_ra8_hcdc_ecm_string_desc_len = 0x00FFU ,
  k_ra8_hcdc_ecm_assigned_address = 1U ,
  k_ra8_hcdc_ecm_default_config = 1U ,
  k_ra8_hcdc_ecm_data_alt = 1U ,
  k_ra8_hcdc_ecm_lang_id_us = 0x0409U
}
 Standard descriptor sizes and request payload sizes. More...
enum  ra8_usb_hcdc_ecm_byte_shift_t : uint8_t {
  k_ra8_hcdc_ecm_shift_byte0 = 0U ,
  k_ra8_hcdc_ecm_shift_byte1 = 8U ,
  k_ra8_hcdc_ecm_shift_nibble = 4U ,
  k_ra8_hcdc_ecm_hex_alpha = 0x0AU
}
 Per-byte shift constants for descriptor / wValue serialisation. More...
enum  ra8_usb_hcdc_ecm_byte_mask_t : uint32_t { k_ra8_hcdc_ecm_byte_mask = 0xFFU }
 Single-byte mask used during serialisation. More...

Functions

static uint16_t internal_bulk_max_packet (ra8_usb_speed_t speed)
 Pick the bulk-max-packet ceiling matching the negotiated speed.
static ra8_err_t internal_configure_pipes (void)
 Configure the three host-CDC-ECM pipes against the attached adapter's endpoints.
static ra8_err_t internal_setup_get_descriptor (uint8_t desc_type, uint8_t desc_index, uint16_t lang_id, uint16_t length)
 Stage a chapter-9 GET_DESCRIPTOR SETUP request.
static ra8_err_t internal_setup_set_address (uint8_t address)
 Stage a SET_ADDRESS SETUP request.
static ra8_err_t internal_setup_set_config (uint8_t config_value)
 Stage a SET_CONFIGURATION SETUP request.
static ra8_err_t internal_setup_set_interface_data (void)
 Stage a SET_INTERFACE (alt 1, iface 1) SETUP request.
static ra8_err_t internal_setup_set_packet_filter (uint16_t filter_mask)
 Stage SET_ETHERNET_PACKET_FILTER (bRequest=0x43).
static ra8_err_t internal_hex_nibble (char c, uint8_t *out_nibble)
 Convert one ASCII hex digit to a 0..15 nibble.
static void internal_walk_config_descriptor (void)
 Populate s_state.device with stub descriptor data.
static ra8_err_t internal_do_idle (void)
 Step handler – bus-reset assert.
static ra8_err_t internal_do_bus_reset (void)
 Step handler – bus-reset release + SETUP for SET_ADDRESS.
static ra8_err_t internal_do_set_address (void)
 Step handler – store assigned address + SETUP for GET_DEVICE_DESCRIPTOR.
static ra8_err_t internal_do_get_dev_desc (void)
 Step handler – SETUP for GET_CONFIGURATION_DESCRIPTOR.
static ra8_err_t internal_do_get_cfg_desc (void)
 Step handler – SETUP for SET_CONFIGURATION.
static ra8_err_t internal_do_set_config (void)
 Step handler – pure software descriptor walk.
static ra8_err_t internal_do_walk_desc (void)
 Step handler – SETUP for GET_STRING_DESCRIPTOR(iMACAddress).
static ra8_err_t internal_do_get_string_mac (void)
 Step handler – SETUP for SET_ETHERNET_PACKET_FILTER.
static ra8_err_t internal_do_set_filter (void)
 Step handler – SETUP for SET_INTERFACE (data IF, alt 1).
static ra8_err_t internal_do_set_interface (void)
 Step handler – finalise pipes + fire attach callback.
static ra8_err_t internal_step_advance (void)
 Drive the enumeration step machine forward by one step.
ra8_err_t ra8_usb_hcdc_ecm_init (ra8_usb_speed_t speed)
 Bring up the host-CDC-ECM driver on a chosen USB controller.
ra8_err_t ra8_usb_hcdc_ecm_close (void)
 Tear down the host-CDC-ECM driver and release the controller.
ra8_err_t ra8_usb_hcdc_ecm_attach_callback (ra8_usb_hcdc_ecm_attach_fn_t on_attach, void *ctx)
 Register (or detach) the attach callback.
ra8_err_t ra8_usb_hcdc_ecm_send_frame (const uint8_t *buf, uint16_t len)
 Send an Ethernet frame OUT to the attached CDC-ECM adapter.
ra8_err_t ra8_usb_hcdc_ecm_recv_frame (uint8_t *buf, uint16_t max_len, uint16_t *got_len)
 Drain an Ethernet frame IN from the attached CDC-ECM adapter.
ra8_err_t ra8_usb_hcdc_ecm_set_packet_filter (uint16_t filter_mask)
 Issue SET_ETHERNET_PACKET_FILTER (bRequest=0x43) to the attached CDC-ECM adapter.
ra8_err_t ra8_usb_hcdc_ecm_get_link_status (ra8_usb_hcdc_ecm_link_t *out_link)
 Issue GET_ETHERNET_STATISTIC (bRequest=0x44) to read the adapter's link state and store the result in *out_link.
ra8_err_t ra8_usb_hcdc_ecm_parse_mac (const char *chars, uint8_t *out_mac)
 Parse 12 ASCII hex characters from an iMACAddress string descriptor payload into a 6-byte MAC.
ra8_err_t ra8_usb_hcdc_ecm_step (void)
 Drive the enumeration step machine forward by one step.

Variables

static const char * s_tag = "USBHCDCECM"
static ra8_usb_hcdc_ecm_state_t s_state = {}

Detailed Description

Native USB host-side CDC-ECM (Ethernet over USB) class layer implementation.

Tag
[Ring 3 / HAL] {World: NS}

Glues the host-mode bring-up paths in ra8_usb to a CDC-ECM USB Ethernet adapter attached on the EK-RA8D2's USB-HS host port. This file is the native host-CDC-ECM class layer; FSP's r_usb_hcdc_ecm.c is reference material only – nothing is pulled in verbatim.

Mapping vs FSP (FSP function -> our entry point):

The starter does CPU-FIFO, single-adapter, no-hub. Enumeration is driven step-by-step from the controller's CTRT interrupt path (production) or directly via ra8_usb_hcdc_ecm_step (tests). Each step issues exactly one chapter-9 SETUP request via ra8_usb_host_setup_request; the next CTRT advances the step.

Definition in file ra8_usb_hcdc_ecm.c.

Enumeration Type Documentation

◆ ra8_usb_hcdc_ecm_byte_mask_t

Single-byte mask used during serialisation.

Enumerator
k_ra8_hcdc_ecm_byte_mask 

RA8 hcdc ecm byte mask.

Definition at line 139 of file ra8_usb_hcdc_ecm.c.

◆ ra8_usb_hcdc_ecm_byte_shift_t

Per-byte shift constants for descriptor / wValue serialisation.

Enumerator
k_ra8_hcdc_ecm_shift_byte0 

RA8 hcdc ecm shift byte0.

k_ra8_hcdc_ecm_shift_byte1 

RA8 hcdc ecm shift byte1.

k_ra8_hcdc_ecm_shift_nibble 

RA8 hcdc ecm shift nibble.

k_ra8_hcdc_ecm_hex_alpha 

Offset for 'A'/'a' in hex digit.

Definition at line 128 of file ra8_usb_hcdc_ecm.c.

◆ ra8_usb_hcdc_ecm_setup_field_t

Standard chapter-9 + CDC-ECM class request bmRequestType / bRequest encodings.

Enumerator
k_ra8_hcdc_ecm_bm_std_dev_in 

Std | Device | In.

k_ra8_hcdc_ecm_bm_std_dev_out 

Std | Device | Out.

k_ra8_hcdc_ecm_bm_std_iface_out 

Std | Interface | Out.

k_ra8_hcdc_ecm_breq_get_descriptor 

GET_DESCRIPTOR.

k_ra8_hcdc_ecm_breq_set_address 

SET_ADDRESS.

k_ra8_hcdc_ecm_breq_set_config 

SET_CONFIGURATION.

k_ra8_hcdc_ecm_breq_set_interface 

SET_INTERFACE.

k_ra8_hcdc_ecm_bm_class_iface_out 

Class | Interface | Out.

k_ra8_hcdc_ecm_bm_class_iface_in 

Class | Interface | In.

k_ra8_hcdc_ecm_desc_device 

DEVICE descriptor.

k_ra8_hcdc_ecm_desc_configuration 

CONFIGURATION descriptor.

k_ra8_hcdc_ecm_desc_string 

STRING descriptor.

k_ra8_hcdc_ecm_desc_interface 

INTERFACE descriptor.

k_ra8_hcdc_ecm_desc_endpoint 

ENDPOINT descriptor.

k_ra8_hcdc_ecm_desc_cs_interface 

CS_INTERFACE functional.

k_ra8_hcdc_ecm_func_subtype_ecm 

Ethernet Networking subtype.

Definition at line 85 of file ra8_usb_hcdc_ecm.c.

◆ ra8_usb_hcdc_ecm_size_t

enum ra8_usb_hcdc_ecm_size_t : uint16_t

Standard descriptor sizes and request payload sizes.

Enumerator
k_ra8_hcdc_ecm_dev_desc_len 

USB DEVICE descriptor.

k_ra8_hcdc_ecm_cfg_desc_len 

CONFIGURATION descriptor hdr.

k_ra8_hcdc_ecm_iface_desc_len 

INTERFACE descriptor.

k_ra8_hcdc_ecm_ep_desc_len 

ENDPOINT descriptor.

k_ra8_hcdc_ecm_string_desc_len 

wLength for string fetch.

k_ra8_hcdc_ecm_assigned_address 

First assigned device addr.

k_ra8_hcdc_ecm_default_config 

bConfigurationValue = 1.

k_ra8_hcdc_ecm_data_alt 

Data IF alt setting = 1.

k_ra8_hcdc_ecm_lang_id_us 

wIndex for English (US).

Definition at line 112 of file ra8_usb_hcdc_ecm.c.

◆ ra8_usb_hcdc_ecm_step_t

enum ra8_usb_hcdc_ecm_step_t : uint8_t

Enumeration step machine states.

Mirrors FSP's usb_hcdc_ecm_device_activation sequence (r_usb_hcdc_ecm.c). Each step issues exactly one SETUP via ra8_usb_host_setup_request; the next CTRT interrupt advances to the next step.

Enumerator
k_ra8_hcdc_ecm_step_idle 

Pre-attach.

k_ra8_hcdc_ecm_step_bus_reset 

Drive USBRST then release.

k_ra8_hcdc_ecm_step_set_address 

SET_ADDRESS to assigned 1.

k_ra8_hcdc_ecm_step_get_dev_desc 

GET_DEVICE_DESCRIPTOR (18 B).

k_ra8_hcdc_ecm_step_get_cfg_desc 

GET_CONFIGURATION_DESCRIPTOR.

k_ra8_hcdc_ecm_step_set_config 

SET_CONFIGURATION (1).

k_ra8_hcdc_ecm_step_walk_desc 

Find ECM IFs; populate pipes.

k_ra8_hcdc_ecm_step_get_string_mac 

GET_STRING_DESCRIPTOR(iMAC).

k_ra8_hcdc_ecm_step_set_filter 

SET_ETHERNET_PACKET_FILTER.

k_ra8_hcdc_ecm_step_set_interface 

SET_INTERFACE (alt 1).

k_ra8_hcdc_ecm_step_done 

Attach callback fires.

Definition at line 66 of file ra8_usb_hcdc_ecm.c.

Function Documentation

◆ internal_bulk_max_packet()

uint16_t internal_bulk_max_packet ( ra8_usb_speed_t speed)
static

Pick the bulk-max-packet ceiling matching the negotiated speed.

See implementation.

Parameters
[in]speedSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 185 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_bulk_max_packet_fs, k_ra8_hcdc_ecm_bulk_max_packet_hs, and k_ra8_usb_speed_hs.

Referenced by internal_configure_pipes(), and internal_walk_config_descriptor().

◆ internal_configure_pipes()

ra8_err_t internal_configure_pipes ( void )
static

Configure the three host-CDC-ECM pipes against the attached adapter's endpoints.

Mirrors FSP's usb_hcdc_pipe_info invocation site in r_usb_hcdc_ecm.c. Bulk pipes are PIPE1 / PIPE2; the notification pipe is PIPE6.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 209 of file ra8_usb_hcdc_ecm.c.

References internal_bulk_max_packet(), k_ra8_hcdc_ecm_intr_max_packet, k_ra8_hcdc_ecm_pipe_bulk_in, k_ra8_hcdc_ecm_pipe_bulk_out, k_ra8_hcdc_ecm_pipe_intr_in, k_ra8_usb_ep_dir_in, k_ra8_usb_ep_dir_out, k_ra8_usb_ep_type_bulk, k_ra8_usb_ep_type_intr, RA8_RETURN_ON_ERROR, ra8_usb_configure_endpoint(), s_state, and s_tag.

Referenced by internal_do_set_interface().

◆ internal_do_bus_reset()

ra8_err_t internal_do_bus_reset ( void )
static

Step handler – bus-reset release + SETUP for SET_ADDRESS.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 488 of file ra8_usb_hcdc_ecm.c.

References internal_setup_set_address(), k_ra8_hcdc_ecm_assigned_address, k_ra8_hcdc_ecm_step_set_address, RA8_RETURN_ON_ERROR, ra8_usb_host_bus_reset(), s_state, and s_tag.

Referenced by internal_step_advance().

◆ internal_do_get_cfg_desc()

ra8_err_t internal_do_get_cfg_desc ( void )
static

Step handler – SETUP for SET_CONFIGURATION.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 563 of file ra8_usb_hcdc_ecm.c.

References internal_setup_set_config(), k_ra8_hcdc_ecm_default_config, k_ra8_hcdc_ecm_step_set_config, and s_state.

Referenced by internal_step_advance().

◆ internal_do_get_dev_desc()

ra8_err_t internal_do_get_dev_desc ( void )
static

Step handler – SETUP for GET_CONFIGURATION_DESCRIPTOR.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 540 of file ra8_usb_hcdc_ecm.c.

References internal_setup_get_descriptor(), k_ra8_hcdc_ecm_cfg_desc_len, k_ra8_hcdc_ecm_desc_configuration, k_ra8_hcdc_ecm_step_get_cfg_desc, and s_state.

Referenced by internal_step_advance().

◆ internal_do_get_string_mac()

ra8_err_t internal_do_get_string_mac ( void )
static

Step handler – SETUP for SET_ETHERNET_PACKET_FILTER.

The starter installs a "directed | broadcast | multicast" default mask, mirroring the no-filter behaviour FSP installs in usb_hcdc_ecm_set_ethernet_packet_filter. Stub MAC parsing fills the device snapshot with a zero MAC since the fake string payload is not staged through the DCP data buffer; the production CTRT path consumes the real GET_STRING_DESCRIPTOR data stage and calls ra8_usb_hcdc_ecm_parse_mac directly. See USB CDC ECM 1.20 sec 5.4 "iMACAddress".

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 635 of file ra8_usb_hcdc_ecm.c.

References internal_setup_set_packet_filter(), k_ra8_hcdc_ecm_filter_all, k_ra8_hcdc_ecm_step_set_filter, and s_state.

Referenced by internal_step_advance().

◆ internal_do_idle()

ra8_err_t internal_do_idle ( void )
static

Step handler – bus-reset assert.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 468 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_step_bus_reset, ra8_usb_host_bus_reset(), and s_state.

Referenced by internal_step_advance().

◆ internal_do_set_address()

ra8_err_t internal_do_set_address ( void )
static

Step handler – store assigned address + SETUP for GET_DEVICE_DESCRIPTOR.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 513 of file ra8_usb_hcdc_ecm.c.

References internal_setup_get_descriptor(), k_ra8_hcdc_ecm_assigned_address, k_ra8_hcdc_ecm_desc_device, k_ra8_hcdc_ecm_dev_desc_len, k_ra8_hcdc_ecm_step_get_dev_desc, RA8_RETURN_ON_ERROR, ra8_usb_set_address(), s_state, and s_tag.

Referenced by internal_step_advance().

◆ internal_do_set_config()

ra8_err_t internal_do_set_config ( void )
static

Step handler – pure software descriptor walk.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 583 of file ra8_usb_hcdc_ecm.c.

References internal_walk_config_descriptor(), k_ra8_hcdc_ecm_step_walk_desc, k_ra8_ok, and s_state.

Referenced by internal_step_advance().

◆ internal_do_set_filter()

ra8_err_t internal_do_set_filter ( void )
static

Step handler – SETUP for SET_INTERFACE (data IF, alt 1).

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 655 of file ra8_usb_hcdc_ecm.c.

References internal_setup_set_interface_data(), k_ra8_hcdc_ecm_step_set_interface, and s_state.

Referenced by internal_step_advance().

◆ internal_do_set_interface()

ra8_err_t internal_do_set_interface ( void )
static

Step handler – finalise pipes + fire attach callback.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 675 of file ra8_usb_hcdc_ecm.c.

References internal_configure_pipes(), k_ra8_hcdc_ecm_step_done, k_ra8_ok, RA8_RETURN_ON_ERROR, s_state, and s_tag.

Referenced by internal_step_advance().

◆ internal_do_walk_desc()

ra8_err_t internal_do_walk_desc ( void )
static

Step handler – SETUP for GET_STRING_DESCRIPTOR(iMACAddress).

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 604 of file ra8_usb_hcdc_ecm.c.

References internal_setup_get_descriptor(), k_ra8_hcdc_ecm_desc_string, k_ra8_hcdc_ecm_lang_id_us, k_ra8_hcdc_ecm_step_get_string_mac, k_ra8_hcdc_ecm_string_desc_len, and s_state.

Referenced by internal_step_advance().

◆ internal_hex_nibble()

ra8_err_t internal_hex_nibble ( char c,
uint8_t * out_nibble )
static

Convert one ASCII hex digit to a 0..15 nibble.

See implementation.

Parameters
[in]cSee implementation.
[in]out_nibbleSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 399 of file ra8_usb_hcdc_ecm.c.

References k_ra8_err_invalid_arg, k_ra8_hcdc_ecm_hex_alpha, and k_ra8_ok.

Referenced by ra8_usb_hcdc_ecm_parse_mac().

◆ internal_setup_get_descriptor()

ra8_err_t internal_setup_get_descriptor ( uint8_t desc_type,
uint8_t desc_index,
uint16_t lang_id,
uint16_t length )
static

Stage a chapter-9 GET_DESCRIPTOR SETUP request.

See implementation.

Parameters
[in]desc_typeSee implementation.
[in]desc_indexSee implementation.
[in]lang_idSee implementation.
[in]lengthSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 256 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_bm_std_dev_in, k_ra8_hcdc_ecm_breq_get_descriptor, k_ra8_hcdc_ecm_shift_byte1, ra8_usb_host_setup_request(), and s_state.

Referenced by internal_do_get_dev_desc(), internal_do_set_address(), and internal_do_walk_desc().

◆ internal_setup_set_address()

ra8_err_t internal_setup_set_address ( uint8_t address)
static

Stage a SET_ADDRESS SETUP request.

See implementation.

Parameters
[in]addressSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 287 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_bm_std_dev_out, k_ra8_hcdc_ecm_breq_set_address, ra8_usb_host_setup_request(), and s_state.

Referenced by internal_do_bus_reset().

◆ internal_setup_set_config()

ra8_err_t internal_setup_set_config ( uint8_t config_value)
static

Stage a SET_CONFIGURATION SETUP request.

See implementation.

Parameters
[in]config_valueSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 314 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_bm_std_dev_out, k_ra8_hcdc_ecm_breq_set_config, ra8_usb_host_setup_request(), and s_state.

Referenced by internal_do_get_cfg_desc().

◆ internal_setup_set_interface_data()

ra8_err_t internal_setup_set_interface_data ( void )
static

Stage a SET_INTERFACE (alt 1, iface 1) SETUP request.

USB CDC ECM 1.20 sec 3.4 "Switching Between Configurations and Alternate Settings" mandates SET_INTERFACE(IF=1, alt=1) to bring the data-class interface online.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 343 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_bm_std_iface_out, k_ra8_hcdc_ecm_breq_set_interface, k_ra8_hcdc_ecm_data_alt, ra8_usb_host_setup_request(), and s_state.

Referenced by internal_do_set_filter().

◆ internal_setup_set_packet_filter()

ra8_err_t internal_setup_set_packet_filter ( uint16_t filter_mask)
static

Stage SET_ETHERNET_PACKET_FILTER (bRequest=0x43).

See USB CDC ECM 1.20 sec 6.2.4 "SetEthernetPacketFilter".

Parameters
[in]filter_maskSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 371 of file ra8_usb_hcdc_ecm.c.

References k_ra8_hcdc_ecm_bm_class_iface_out, k_ra8_hcdc_ecm_data_alt, k_ra8_hcdc_ecm_req_set_packet_filter, ra8_usb_host_setup_request(), and s_state.

Referenced by internal_do_get_string_mac(), and ra8_usb_hcdc_ecm_set_packet_filter().

◆ internal_step_advance()

ra8_err_t internal_step_advance ( void )
static

Drive the enumeration step machine forward by one step.

See implementation.

Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 701 of file ra8_usb_hcdc_ecm.c.

References internal_do_bus_reset(), internal_do_get_cfg_desc(), internal_do_get_dev_desc(), internal_do_get_string_mac(), internal_do_idle(), internal_do_set_address(), internal_do_set_config(), internal_do_set_filter(), internal_do_set_interface(), internal_do_walk_desc(), k_ra8_hcdc_ecm_step_bus_reset, k_ra8_hcdc_ecm_step_get_cfg_desc, k_ra8_hcdc_ecm_step_get_dev_desc, k_ra8_hcdc_ecm_step_get_string_mac, k_ra8_hcdc_ecm_step_idle, k_ra8_hcdc_ecm_step_set_address, k_ra8_hcdc_ecm_step_set_config, k_ra8_hcdc_ecm_step_set_filter, k_ra8_hcdc_ecm_step_set_interface, k_ra8_hcdc_ecm_step_walk_desc, k_ra8_ok, and s_state.

Referenced by ra8_usb_hcdc_ecm_step().

◆ internal_walk_config_descriptor()

void internal_walk_config_descriptor ( void )
static

Populate s_state.device with stub descriptor data.

In production this routine walks the configuration descriptor returned in the GET_CONFIG_DESCRIPTOR data stage and picks out the CDC Communication-Interface (class=0x02 / subclass= 0x06 ECM / protocol=0x00) plus the CDC Data-Interface (class=0x0A) and the Ethernet Networking Functional descriptor (CS_INTERFACE 0x24, subtype 0x0F) which holds the iMACAddress string-descriptor index. The starter relies on the fact that nearly every CDC-ECM adapter follows a near-universal layout: bulk-IN at EP address 1, bulk-OUT at EP address 2, notification IN at EP address 3.

See USB CDC ECM 1.20 sec 3.5 "Functional Descriptors" and sec 5.4 "Device Class Interface Definitions".

Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 440 of file ra8_usb_hcdc_ecm.c.

References internal_bulk_max_packet(), k_ra8_hcdc_ecm_assigned_address, and s_state.

Referenced by internal_do_set_config().

◆ ra8_usb_hcdc_ecm_attach_callback()

ra8_err_t ra8_usb_hcdc_ecm_attach_callback ( ra8_usb_hcdc_ecm_attach_fn_t on_attach,
void * ctx )
nodiscard

Register (or detach) the attach callback.

The supplied callback fires exactly once per attach event, after the descriptor walk identifies a CDC-ECM Communication + Data interface pair on the attached device and the iMACAddress string descriptor has been parsed into device->mac_address. Pass NULL to detach.

Parameters
[in]on_attachCallback. NULL detaches.
[in]ctxContext pointer threaded back into on_attach.
Returns
ra8_err_t error code.
Return values
k_ra8_okCallback installed.
k_ra8_err_invalid_stateDriver was never initialized.
Precondition
ra8_usb_hcdc_ecm_init has run.
Postcondition
On a subsequent attach, on_attach(ctx, &device) fires once.
Note
Not thread-safe.
Since
0.1.0

Definition at line 780 of file ra8_usb_hcdc_ecm.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

◆ ra8_usb_hcdc_ecm_close()

ra8_err_t ra8_usb_hcdc_ecm_close ( void )
nodiscard

Tear down the host-CDC-ECM driver 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_host_deinit ran; SOF generation halted; bus power dropped.
Subsequent host-CDC-ECM API calls return k_ra8_err_invalid_state.
Note
Not thread-safe.
Since
0.1.0

Definition at line 759 of file ra8_usb_hcdc_ecm.c.

References k_ra8_err_invalid_state, k_ra8_hcdc_ecm_step_idle, ra8_usb_host_deinit(), ra8_usb_host_set_uact(), and s_state.

◆ ra8_usb_hcdc_ecm_get_link_status()

ra8_err_t ra8_usb_hcdc_ecm_get_link_status ( ra8_usb_hcdc_ecm_link_t * out_link)
nodiscard

Issue GET_ETHERNET_STATISTIC (bRequest=0x44) to read the adapter's link state and store the result in *out_link.

Builds a class-interface-in SETUP packet (bmRequestType=0xA1, bRequest=0x44) with a 1-byte data stage that carries the latest NetworkConnection notification value (0 = down, 1 = up). See USB CDC ECM 1.20 sec 6.2.5 "GetEthernetStatistic".

Parameters
[out]out_linkReceives the current link state.
Returns
ra8_err_t error code.
Return values
k_ra8_okControl transfer queued; *out_link populated.
k_ra8_err_invalid_stateDriver not initialized, or no adapter attached.
k_ra8_err_null_ptrout_link was NULL.
k_ra8_err_busyA control transfer is already in flight.
Precondition
ra8_usb_hcdc_ecm_init succeeded.
Attach callback already fired.
out_link != NULL.
Postcondition
*out_link reflects the cached NetworkConnection state.
Note
Not thread-safe.
Since
0.1.0

Definition at line 855 of file ra8_usb_hcdc_ecm.c.

References k_ra8_err_invalid_state, k_ra8_hcdc_ecm_bm_class_iface_in, k_ra8_hcdc_ecm_data_alt, k_ra8_hcdc_ecm_req_get_statistic, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_usb_host_setup_request(), s_state, and s_tag.

◆ ra8_usb_hcdc_ecm_init()

ra8_err_t ra8_usb_hcdc_ecm_init ( ra8_usb_speed_t speed)
nodiscard

Bring up the host-CDC-ECM driver on a chosen USB controller.

Initialises the underlying ra8_usb driver in HOST mode for speed by delegating to ra8_usb_host_init, programs the DCP for 64-byte EP0 control transfers, leaves the bus in the "wait for attach" state (UACT cleared), and arms the internal enumeration step machine.

Parameters
[in]speedWhich USB controller (FS or HS).
Returns
ra8_err_t error code.
Return values
k_ra8_okHost-CDC-ECM ready, awaiting attach.
k_ra8_err_invalid_argspeed out of range.
k_ra8_err_hw_init_failedUnderlying ra8_usb_host_init failed.
Precondition
Single-threaded init context.
ra8_mstp_init and ra8_pwr_init already ran.
Postcondition
ra8_usb_host_init succeeded for speed.
Internal step machine armed; attach callback has not fired yet.
Note
Not thread-safe.
See also
ra8_usb_hcdc_ecm_attach_callback
ra8_usb_hcdc_ecm_close
Since
0.1.0

Definition at line 735 of file ra8_usb_hcdc_ecm.c.

References k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_hcdc_ecm_link_down, k_ra8_hcdc_ecm_step_idle, k_ra8_ok, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, ra8_log_error_val, ra8_log_info_val, ra8_usb_host_init(), s_state, and s_tag.

◆ ra8_usb_hcdc_ecm_parse_mac()

ra8_err_t ra8_usb_hcdc_ecm_parse_mac ( const char * chars,
uint8_t * out_mac )
nodiscard

Parse 12 ASCII hex characters from an iMACAddress string descriptor payload into a 6-byte MAC.

USB string descriptors are UTF-16LE; the iMACAddress payload is a 12-character ASCII-hex MAC encoded as 12 UTF-16LE code units (24 bytes). This helper walks chars two ASCII hex digits at a time and writes each parsed nibble pair to out_mac[0..5].

See USB CDC ECM 1.20 sec 5.4 "iMACAddress".

Parameters
[in]charsPointer to 12 ASCII hex characters (post-UTF-16 decoding).
[out]out_macReceives the 6-byte MAC.
Returns
ra8_err_t error code.
Return values
k_ra8_okParsed successfully.
k_ra8_err_null_ptrchars or out_mac was NULL.
k_ra8_err_invalid_argOne of the characters was not a valid ASCII hex digit.
Precondition
chars points to >= 12 readable bytes.
out_mac points to >= 6 writable bytes.
Postcondition
On success, out_mac[0..5] carries the parsed MAC.
On failure, out_mac contents are unspecified.
Note
Pure function; safe to call before init.
Since
0.1.0

Definition at line 888 of file ra8_usb_hcdc_ecm.c.

References internal_hex_nibble(), k_ra8_hcdc_ecm_mac_bytes, k_ra8_hcdc_ecm_shift_nibble, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_usb_hcdc_ecm_recv_frame()

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

Drain an Ethernet frame IN from the attached CDC-ECM adapter.

Polling / non-blocking. Pulls bytes from PIPE1 (bulk IN) into buf and stores the actual byte count in *got_len. Per USB CDC ECM 1.20 sec 5.4 "Data Class Interface Definitions" one bulk IN transfer yields one Ethernet frame.

Parameters
[out]bufDestination 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_okFrame drained; *got_len reflects the count.
k_ra8_err_no_dataPipe was empty.
k_ra8_err_invalid_stateDriver not initialized, or no adapter attached.
k_ra8_err_null_ptrbuf or got_len was NULL.
k_ra8_err_invalid_argmax_len == 0.
Precondition
ra8_usb_hcdc_ecm_init succeeded.
Attach callback already fired.
buf, got_len non-NULL, max_len > 0.
Postcondition
On success *got_len reflects the actual byte count.
Note
Not thread-safe.
Since
0.1.0

Definition at line 812 of file ra8_usb_hcdc_ecm.c.

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

◆ ra8_usb_hcdc_ecm_send_frame()

ra8_err_t ra8_usb_hcdc_ecm_send_frame ( const uint8_t * buf,
uint16_t len )
nodiscard

Send an Ethernet frame OUT to the attached CDC-ECM adapter.

Pushes buf bytes on PIPE2 (bulk OUT) so the controller delivers them at the next OUT token. Per USB CDC ECM 1.20 sec 5.4 "Data Class Interface Definitions" each USB transfer carries exactly one Ethernet frame (no length prefix). A frame whose length is an integer multiple of wMaxPacketSize is followed by a zero-length packet to terminate the transfer.

Parameters
[in]bufFrame buffer. NULL allowed iff len == 0.
[in]lenByte count, 0..k_ra8_hcdc_ecm_max_ethernet_frame.
Returns
ra8_err_t error code.
Return values
k_ra8_okTransfer queued.
k_ra8_err_invalid_stateDriver not initialized, or no adapter attached.
k_ra8_err_invalid_argBad buf / len.
Precondition
ra8_usb_hcdc_ecm_init succeeded.
Attach callback already fired.
Postcondition
Frame will be delivered on the next bulk OUT token.
Note
Not thread-safe.
Since
0.1.0

Definition at line 795 of file ra8_usb_hcdc_ecm.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_hcdc_ecm_max_ethernet_frame, k_ra8_hcdc_ecm_pipe_bulk_out, ra8_usb_queue_in(), and s_state.

◆ ra8_usb_hcdc_ecm_set_packet_filter()

ra8_err_t ra8_usb_hcdc_ecm_set_packet_filter ( uint16_t filter_mask)
nodiscard

Issue SET_ETHERNET_PACKET_FILTER (bRequest=0x43) to the attached CDC-ECM adapter.

Builds a class-interface-out SETUP packet (bmRequestType=0x21, bRequest=0x43) with the requested filter mask in wValue and wLength=0, and hands it to ra8_usb_host_setup_request. See USB CDC ECM 1.20 sec 6.2.4 "SetEthernetPacketFilter".

Parameters
[in]filter_maskOR of k_ra8_hcdc_ecm_filter_* bits.
Returns
ra8_err_t error code.
Return values
k_ra8_okControl transfer queued.
k_ra8_err_invalid_stateDriver not initialized, or no adapter attached.
k_ra8_err_invalid_argfilter_mask has bits outside the documented set.
k_ra8_err_busyA control transfer is already in flight.
Precondition
ra8_usb_hcdc_ecm_init succeeded.
Attach callback already fired.
Postcondition
DCP control transfer queued at the controller.
Note
Not thread-safe.
Since
0.1.0

Definition at line 841 of file ra8_usb_hcdc_ecm.c.

References internal_setup_set_packet_filter(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_hcdc_ecm_filter_all, and s_state.

◆ ra8_usb_hcdc_ecm_step()

ra8_err_t ra8_usb_hcdc_ecm_step ( void )
nodiscard

Drive the enumeration step machine forward by one step.

Test / debug entry point. The production path drives this from the ra8_usb_dispatch callback when the controller fires a CTRT or BRDY interrupt; tests call it directly to walk the state machine deterministically.

Returns
ra8_err_t error code.
Return values
k_ra8_okStep advanced.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_hcdc_ecm_init succeeded.
Postcondition
Internal enumeration step counter advances by one. When the step machine reaches the terminal state, the registered attach callback fires.
Note
Not thread-safe.
Since
0.1.0

Definition at line 917 of file ra8_usb_hcdc_ecm.c.

References internal_step_advance(), k_ra8_err_invalid_state, and s_state.

Variable Documentation

◆ s_state

ra8_usb_hcdc_ecm_state_t s_state = {}
static

Definition at line 163 of file ra8_usb_hcdc_ecm.c.

◆ s_tag

const char* s_tag = "USBHCDCECM"
static

Definition at line 50 of file ra8_usb_hcdc_ecm.c.