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

Polled on-board USB-DFU host driver (factored from usb_selftest_dfu). More...

#include "ra8_dfu_host.h"
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_time.h"
#include "ra8_usb.h"
Include dependency graph for ra8_dfu_host.c:

Go to the source code of this file.

Enumerations

enum  rdh_proto_t : uint16_t {
  k_rdh_bm_std_dev_in = 0x80U ,
  k_rdh_bm_std_dev_out = 0x00U ,
  k_rdh_bm_class_if_out = 0x21U ,
  k_rdh_bm_class_if_in = 0xA1U ,
  k_rdh_breq_get_desc = 0x06U ,
  k_rdh_breq_set_addr = 0x05U ,
  k_rdh_breq_set_config = 0x09U ,
  k_rdh_breq_dnload = 0x01U ,
  k_rdh_breq_upload = 0x02U ,
  k_rdh_breq_getstatus = 0x03U ,
  k_rdh_breq_abort = 0x06U ,
  k_rdh_desc_device = 0x01U ,
  k_rdh_dev_desc_len = 18U ,
  k_rdh_off_dev_pid = 10U ,
  k_rdh_byte_bits = 8U ,
  k_rdh_getstatus_len = 6U ,
  k_rdh_off_status_state = 4U ,
  k_rdh_state_dnload_idle = 5U ,
  k_rdh_state_idle = 2U ,
  k_rdh_dev_addr = 1U ,
  k_rdh_config_val = 1U ,
  k_rdh_intf = 0U ,
  k_rdh_xfer_size = 64U
}
 Chapter-9 + DFU class request / descriptor constants. More...
enum  rdh_tune_t : uint32_t {
  k_rdh_vbus_settle_ms = 200U ,
  k_rdh_attach_to_ms = 2000U ,
  k_rdh_debounce_ms = 500U ,
  k_rdh_reset_hold_ms = 50U ,
  k_rdh_recovery_ms = 20U ,
  k_rdh_addr_settle_ms = 5U ,
  k_rdh_status_poll_ms = 2U ,
  k_rdh_status_tries = 50U ,
  k_rdh_enum_tries = 8U ,
  k_rdh_attach_spin = 50000000U ,
  k_rdh_mismatch_none = 0xFFFFFFFFU
}
 Timing / retry tunables for the polled enumeration + status polling. More...

Functions

static ra8_err_t internal_get_dev_desc (ra8_usb_speed_t speed, uint8_t *desc)
 Issue GET_DESCRIPTOR(DEVICE) over the polled control engine.
static ra8_err_t internal_enum_hunt (ra8_usb_speed_t speed, uint8_t *desc)
 Wait for device attach, apply bus reset, and read the DEVICE descriptor.
static ra8_err_t internal_set_address (ra8_usb_speed_t speed)
 Issue SET_ADDRESS(1) and retarget the DCP to the new address.
static ra8_err_t internal_set_config (ra8_usb_speed_t speed)
 Issue SET_CONFIGURATION(1) on the addressed device.
static ra8_err_t internal_getstatus (ra8_usb_speed_t speed, uint8_t *out_state)
 Issue DFU_GETSTATUS and return the bState byte.
static ra8_err_t internal_wait_state (ra8_usb_speed_t speed, uint8_t want_state)
 Poll DFU_GETSTATUS until the device reaches want_state or the retry cap.
static ra8_err_t internal_dnload_block (ra8_usb_speed_t speed, uint16_t block, uint8_t *data, uint16_t len)
 Issue DFU_DNLOAD for one block, then poll to dfuDNLOAD-IDLE.
static ra8_err_t internal_download_all (ra8_usb_speed_t speed, const uint8_t *img, uint32_t img_len)
 Download the entire image in 64-byte blocks, then DFU_ABORT to dfuIDLE.
static ra8_err_t internal_download_manifest (ra8_usb_speed_t speed, const uint8_t *img, uint32_t img_len)
 Download the entire image in 64-byte blocks, then send a zero-length manifest.
static ra8_err_t internal_upload_verify (ra8_usb_speed_t speed, const uint8_t *img, uint32_t img_len, ra8_dfu_host_result_t *out)
 DFU_UPLOAD each block and byte-compare against img.
static ra8_err_t internal_run_seq (ra8_usb_speed_t speed, const uint8_t *img, uint32_t img_len, ra8_dfu_host_result_t *out)
 Run the full self-test sequence: enumerate, download, abort, upload-verify.
ra8_err_t ra8_dfu_host_run (ra8_usb_speed_t host_speed, const uint8_t *img, uint32_t img_len, ra8_dfu_host_result_t *out)
 Enumerate, DFU_DNLOAD img, DFU_ABORT, DFU_UPLOAD, and byte-verify.
static ra8_err_t internal_program_seq (ra8_usb_speed_t speed, const uint8_t *img, uint32_t img_len, ra8_dfu_host_result_t *out)
 Run the real-flash sequence: enumerate, download, then send manifest.
ra8_err_t ra8_dfu_host_program (ra8_usb_speed_t host_speed, const uint8_t *img, uint32_t img_len, ra8_dfu_host_result_t *out)
 Enumerate, DFU_DNLOAD img, then a zero-length DFU_DNLOAD (manifest).

Detailed Description

Polled on-board USB-DFU host driver (factored from usb_selftest_dfu).

Tag
[Ring 4 / Service] {World: S}

Enumerate -> DFU_DNLOAD -> DFU_ABORT -> DFU_UPLOAD -> byte-verify, on whichever controller the caller names via ra8_usb_speed_t. Built entirely on the first-party polled ra8_usb_host_* + ra8_usb_host_control_xfer primitives, with no USBX on the host side. Firmware-only (RA8_OFF_TARGET skips it).

Definition in file ra8_dfu_host.c.

Enumeration Type Documentation

◆ rdh_proto_t

enum rdh_proto_t : uint16_t

Chapter-9 + DFU class request / descriptor constants.

Enumerator
k_rdh_bm_std_dev_in 

Std | Device | In.

k_rdh_bm_std_dev_out 

Std | Device | Out.

k_rdh_bm_class_if_out 

Class | Interface | Out.

k_rdh_bm_class_if_in 

Class | Interface | In.

k_rdh_breq_get_desc 

GET_DESCRIPTOR.

k_rdh_breq_set_addr 

SET_ADDRESS.

k_rdh_breq_set_config 

SET_CONFIGURATION.

k_rdh_breq_dnload 

DFU_DNLOAD.

k_rdh_breq_upload 

DFU_UPLOAD.

k_rdh_breq_getstatus 

DFU_GETSTATUS.

k_rdh_breq_abort 

DFU_ABORT (-> dfuIDLE).

k_rdh_desc_device 

DEVICE descriptor type.

k_rdh_dev_desc_len 

DEVICE descriptor length.

k_rdh_off_dev_pid 

idProduct LSB offset.

k_rdh_byte_bits 

Bits per byte.

k_rdh_getstatus_len 

DFU_GETSTATUS payload.

k_rdh_off_status_state 

bState offset.

k_rdh_state_dnload_idle 

dfuDNLOAD-IDLE.

k_rdh_state_idle 

dfuIDLE.

k_rdh_dev_addr 

Operating device address.

k_rdh_config_val 

bConfigurationValue.

k_rdh_intf 

DFU interface number.

k_rdh_xfer_size 

wTransferSize per block.

Definition at line 29 of file ra8_dfu_host.c.

◆ rdh_tune_t

enum rdh_tune_t : uint32_t

Timing / retry tunables for the polled enumeration + status polling.

Enumerator
k_rdh_vbus_settle_ms 

VBUS settle before probing.

k_rdh_attach_to_ms 

Wait for the D+ pull-up.

k_rdh_debounce_ms 

Post-attach debounce.

k_rdh_reset_hold_ms 

USB bus-reset hold (>=10 ms).

k_rdh_recovery_ms 

Post-reset recovery (TRSTRCY).

k_rdh_addr_settle_ms 

Post-SET_ADDRESS recovery.

k_rdh_status_poll_ms 

Pause between GETSTATUS polls.

k_rdh_status_tries 

GETSTATUS polls before giving up.

k_rdh_enum_tries 

Reset+probe attempts.

k_rdh_attach_spin 

Attach spin cap.

k_rdh_mismatch_none 

"no mismatch" sentinel.

Definition at line 56 of file ra8_dfu_host.c.

Function Documentation

◆ internal_dnload_block()

ra8_err_t internal_dnload_block ( ra8_usb_speed_t speed,
uint16_t block,
uint8_t * data,
uint16_t len )
static

Issue DFU_DNLOAD for one block, then poll to dfuDNLOAD-IDLE.

Sends a DFU class-specific DNLOAD request (bmRequestType=0x21, bRequest=0x01) with wValue set to block and wLength set to len. The OUT data phase carries the bytes pointed to by data. On transfer success the function immediately calls internal_wait_state to poll DFU_GETSTATUS until the device reaches dfuDNLOAD-IDLE (bState=5), confirming it has processed and buffered the block before the next one is sent.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]blockDFU block sequence number (wValue in the setup packet).
[in]dataPointer to the block payload (exactly len bytes).
[in]lenNumber of bytes to download in this block.
Returns
ra8_err_t
Return values
k_ra8_okBlock delivered and device reached dfuDNLOAD-IDLE.
k_ra8_err_hw_timeoutDevice did not reach dfuDNLOAD-IDLE in time.
k_ra8_err_*ra8_usb_host_control_xfer or wait_state failure.
Precondition
The device is in dfuDNLOAD-IDLE (or dfuIDLE for block 0) state.
data points to a buffer of at least len valid bytes.
Postcondition
On k_ra8_ok, the device has accepted block block and is in dfuDNLOAD-IDLE.
On failure, DFU state is indeterminate; the sequence should be aborted.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 379 of file ra8_dfu_host.c.

References internal_wait_state(), k_ra8_ok, k_rdh_bm_class_if_out, k_rdh_breq_dnload, k_rdh_intf, k_rdh_state_dnload_idle, and ra8_usb_host_control_xfer().

Referenced by internal_download_all(), and internal_download_manifest().

◆ internal_download_all()

ra8_err_t internal_download_all ( ra8_usb_speed_t speed,
const uint8_t * img,
uint32_t img_len )
static

Download the entire image in 64-byte blocks, then DFU_ABORT to dfuIDLE.

Iterates over img in k_rdh_xfer_size (64)-byte blocks, calling internal_dnload_block for each. After all blocks have been sent, instead of issuing the standard zero-length manifest DFU_DNLOAD, this function sends DFU_ABORT (bRequest=0x06) to transition the device from dfuDNLOAD-IDLE back to dfuIDLE without triggering a manifest/reset cycle. This keeps the device enumerated and in a known idle state so the upload-verify phase can immediately follow on the same enumeration.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]imgPointer to the image buffer (non-NULL).
[in]img_lenTotal image length; must be a non-zero multiple of k_rdh_xfer_size (64).
Returns
ra8_err_t
Return values
k_ra8_okAll blocks downloaded; device is in dfuIDLE.
k_ra8_err_hw_timeoutA block poll timed out or abort wait timed out.
k_ra8_err_*internal_dnload_block or DFU_ABORT xfer failure.
Precondition
The device is in dfuIDLE state (SET_CONFIGURATION completed).
img_len is a non-zero multiple of k_rdh_xfer_size and img is valid.
Postcondition
On k_ra8_ok, all image blocks are buffered in the device and it is in dfuIDLE.
The device did NOT enter dfuMANIFEST; it aborted cleanly to dfuIDLE.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 426 of file ra8_dfu_host.c.

References internal_dnload_block(), internal_wait_state(), k_ra8_ok, k_rdh_bm_class_if_out, k_rdh_breq_abort, k_rdh_intf, k_rdh_state_idle, k_rdh_xfer_size, memcpy(), and ra8_usb_host_control_xfer().

Referenced by internal_run_seq().

◆ internal_download_manifest()

ra8_err_t internal_download_manifest ( ra8_usb_speed_t speed,
const uint8_t * img,
uint32_t img_len )
static

Download the entire image in 64-byte blocks, then send a zero-length manifest.

Iterates over img in k_rdh_xfer_size (64)-byte blocks, calling internal_dnload_block for each. After the last data block the function sends a zero-length DFU_DNLOAD (wValue = block count, wLength = 0), which signals end-of-download per the DFU 1.1 specification. The device commits the slot header and enters dfuMANIFEST. Unlike internal_download_all this function does NOT issue DFU_ABORT and does NOT poll for dfuIDLE; the caller is responsible for confirming the commit via ra8_dfu_device_committed because the device half runs on the same chip and would deadlock if polled here.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]imgPointer to the image buffer (non-NULL).
[in]img_lenTotal image length; must be a non-zero multiple of k_rdh_xfer_size (64).
Returns
ra8_err_t
Return values
k_ra8_okAll blocks and the zero-length manifest were accepted.
k_ra8_err_hw_timeoutA block poll timed out before the manifest was sent.
k_ra8_err_*internal_dnload_block or manifest xfer failure.
Precondition
The device is in dfuIDLE state (SET_CONFIGURATION completed).
img_len is a non-zero multiple of k_rdh_xfer_size and img is valid.
Postcondition
On k_ra8_ok, the device has received all data blocks and the manifest request.
The device is entering dfuMANIFEST; the caller must not re-enumerate it until the commit is confirmed via ra8_dfu_device_committed.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 486 of file ra8_dfu_host.c.

References internal_dnload_block(), k_ra8_ok, k_rdh_bm_class_if_out, k_rdh_breq_dnload, k_rdh_intf, k_rdh_xfer_size, memcpy(), and ra8_usb_host_control_xfer().

Referenced by internal_program_seq().

◆ internal_enum_hunt()

ra8_err_t internal_enum_hunt ( ra8_usb_speed_t speed,
uint8_t * desc )
static

Wait for device attach, apply bus reset, and read the DEVICE descriptor.

Sequence:

  1. Waits k_rdh_vbus_settle_ms for VBUS to stabilise.
  2. Spins (up to k_rdh_attach_spin iterations or k_rdh_attach_to_ms) until the D+ line goes high (FS pull-up detected).
  3. Applies k_rdh_debounce_ms debounce delay.
  4. Retries up to k_rdh_enum_tries times: assert bus reset for k_rdh_reset_hold_ms, release, enable UACT, wait k_rdh_recovery_ms, retarget the DCP to address 0, then call internal_get_dev_desc. Returns immediately on the first successful descriptor read.
Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[out]descCaller-allocated buffer of at least k_rdh_dev_desc_len bytes; receives the raw DEVICE descriptor on success.
Returns
ra8_err_t
Return values
k_ra8_okDevice attached and descriptor received.
k_ra8_err_hw_timeoutAll k_rdh_enum_tries attempts failed.
k_ra8_err_*Last internal_get_dev_desc failure code.
Precondition
The USB host controller named by speed has been initialized.
VBUS is powered on the host jack.
Postcondition
On k_ra8_ok, the device is enumerated at address 0 and desc is valid.
On failure, bus state is indeterminate; the controller should be restarted.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 147 of file ra8_dfu_host.c.

References internal_get_dev_desc(), k_ra8_err_hw_timeout, k_ra8_ok, k_rdh_attach_spin, k_rdh_attach_to_ms, k_rdh_debounce_ms, k_rdh_enum_tries, k_rdh_recovery_ms, k_rdh_reset_hold_ms, k_rdh_vbus_settle_ms, ra8_delay_ms(), RA8_INTERNAL, ra8_time_ms(), ra8_usb_host_bus_reset(), ra8_usb_host_line_state(), ra8_usb_host_set_target(), and ra8_usb_host_set_uact().

Referenced by internal_program_seq(), and internal_run_seq().

◆ internal_get_dev_desc()

ra8_err_t internal_get_dev_desc ( ra8_usb_speed_t speed,
uint8_t * desc )
static

Issue GET_DESCRIPTOR(DEVICE) over the polled control engine.

Builds a standard Chapter-9 GET_DESCRIPTOR setup packet requesting the DEVICE descriptor (type 0x01, length 18 bytes) and executes it via ra8_usb_host_control_xfer. On success the 18-byte descriptor is stored in desc. If the transfer succeeds but the controller returns fewer than k_rdh_dev_desc_len bytes the function treats this as a hardware error and returns k_ra8_err_hw_error so that the caller can retry.

Parameters
[in]speedController speed (FS or HS) that selects the USB port.
[out]descCaller-allocated buffer of at least k_rdh_dev_desc_len bytes; receives the raw DEVICE descriptor on success.
Returns
ra8_err_t
Return values
k_ra8_okDescriptor received and fully length-checked.
k_ra8_err_hw_errorTransfer succeeded but byte count was short.
k_ra8_err_*Underlying ra8_usb_host_control_xfer failure.
Precondition
The USB host controller named by speed has been initialized.
The device is held at address 0 (before SET_ADDRESS).
Postcondition
On k_ra8_ok, desc holds the complete 18-byte DEVICE descriptor.
On failure, desc content is undefined.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 98 of file ra8_dfu_host.c.

References k_ra8_err_hw_error, k_ra8_ok, k_rdh_bm_std_dev_in, k_rdh_breq_get_desc, k_rdh_byte_bits, k_rdh_desc_device, k_rdh_dev_desc_len, RA8_INTERNAL, and ra8_usb_host_control_xfer().

Referenced by internal_enum_hunt().

◆ internal_getstatus()

ra8_err_t internal_getstatus ( ra8_usb_speed_t speed,
uint8_t * out_state )
static

Issue DFU_GETSTATUS and return the bState byte.

Sends a DFU class-specific GET_STATUS (bmRequestType=0xA1, bRequest=0x03) to interface k_rdh_intf and reads the 6-byte status response. The function validates that the transfer returned exactly k_rdh_getstatus_len (6) bytes, then extracts the bState field from offset k_rdh_off_status_state (4) and stores it in out_state. The bStatus byte at offset 0 is intentionally ignored; the caller only needs the state machine position.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[out]out_stateReceives the bState byte from the GETSTATUS response.
Returns
ra8_err_t
Return values
k_ra8_okStatus received; out_state is valid.
k_ra8_err_hw_errorTransfer succeeded but byte count was not 6.
k_ra8_err_*ra8_usb_host_control_xfer failure.
Precondition
The device is in the Configured state and the DFU interface is active.
out_state is a non-NULL pointer to a writable uint8_t.
Postcondition
On k_ra8_ok, out_state holds the current DFU bState value.
On failure, out_state is unchanged.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 280 of file ra8_dfu_host.c.

References k_ra8_err_hw_error, k_ra8_ok, k_rdh_bm_class_if_in, k_rdh_breq_getstatus, k_rdh_getstatus_len, k_rdh_intf, k_rdh_off_status_state, RA8_INTERNAL, and ra8_usb_host_control_xfer().

Referenced by internal_wait_state().

◆ internal_program_seq()

ra8_err_t internal_program_seq ( ra8_usb_speed_t speed,
const uint8_t * img,
uint32_t img_len,
ra8_dfu_host_result_t * out )
static

Run the real-flash sequence: enumerate, download, then send manifest.

Orchestrates the real DFU programming flow in four ordered steps:

  1. internal_enum_hunt – wait for attach, bus reset, read DEVICE descriptor and populate out->pid from bytes k_rdh_off_dev_pid and +1.
  2. internal_set_address – assign operating address k_rdh_dev_addr.
  3. internal_set_config – activate the DFU interface (dfuIDLE).
  4. internal_download_manifest – stream img to the device and send the zero-length manifest DFU_DNLOAD to trigger commit. There is no ABORT or upload-verify step. The device half (running on the same chip) commits the slot and the caller confirms via ra8_dfu_device_committed. Any step failure propagates immediately; the caller (ra8_dfu_host_program) tears down the host controller on error.
Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]imgBootable slot image to flash into the device.
[in]img_lenTotal image length; non-zero multiple of 64.
[out]outDiagnostics structure; out->pid set after enumeration.
Returns
ra8_err_t
Return values
k_ra8_okAll four steps completed; device is in dfuMANIFEST.
k_ra8_err_hw_timeoutAttach or GETSTATUS wait exhausted.
k_ra8_err_*Error from any of the four sub-functions.
Precondition
The USB host controller named by speed has been initialized via ra8_usb_host_init.
img and out are non-NULL; img_len is a non-zero multiple of 64.
Postcondition
On k_ra8_ok, out->pid is set and the device has received the manifest request.
On failure, the host controller is NOT torn down here; the caller handles it.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 704 of file ra8_dfu_host.c.

References internal_download_manifest(), internal_enum_hunt(), internal_set_address(), internal_set_config(), k_ra8_ok, k_rdh_byte_bits, k_rdh_dev_desc_len, k_rdh_off_dev_pid, ra8_dfu_host_result_t::pid, and RA8_INTERNAL.

Referenced by ra8_dfu_host_program().

◆ internal_run_seq()

ra8_err_t internal_run_seq ( ra8_usb_speed_t speed,
const uint8_t * img,
uint32_t img_len,
ra8_dfu_host_result_t * out )
static

Run the full self-test sequence: enumerate, download, abort, upload-verify.

Orchestrates the round-trip DFU self-test in five ordered steps:

  1. internal_enum_hunt – wait for attach, bus reset, read DEVICE descriptor and populate out->pid from bytes k_rdh_off_dev_pid and +1.
  2. internal_set_address – assign operating address k_rdh_dev_addr.
  3. internal_set_config – activate the DFU interface (dfuIDLE).
  4. internal_download_all – stream img to the device and DFU_ABORT.
  5. internal_upload_verify – stream back all blocks and byte-compare. Any step failure propagates immediately; the caller (ra8_dfu_host_run) tears down the host controller on error.
Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]imgImage to download and then verify via upload.
[in]img_lenTotal image length; non-zero multiple of 64.
[out]outDiagnostics structure; out->pid set after enumeration.
Returns
ra8_err_t
Return values
k_ra8_okAll five steps completed successfully.
k_ra8_err_hw_timeoutAttach or GETSTATUS wait exhausted.
k_ra8_err_*Error from any of the five sub-functions.
Precondition
The USB host controller named by speed has been initialized via ra8_usb_host_init.
img and out are non-NULL; img_len is a non-zero multiple of 64.
Postcondition
On k_ra8_ok, out->pid is set and out->blocks_ok equals img_len / 64.
On failure, the host controller is NOT torn down here; the caller handles it.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 614 of file ra8_dfu_host.c.

References internal_download_all(), internal_enum_hunt(), internal_set_address(), internal_set_config(), internal_upload_verify(), k_ra8_ok, k_rdh_byte_bits, k_rdh_dev_desc_len, k_rdh_off_dev_pid, ra8_dfu_host_result_t::pid, and RA8_INTERNAL.

Referenced by ra8_dfu_host_run().

◆ internal_set_address()

ra8_err_t internal_set_address ( ra8_usb_speed_t speed)
static

Issue SET_ADDRESS(1) and retarget the DCP to the new address.

Sends a standard Chapter-9 SET_ADDRESS control request assigning the device address k_rdh_dev_addr (1). After the successful status phase the function waits k_rdh_addr_settle_ms for the device to latch the new address, then calls ra8_usb_host_set_target to point the host DCP at address 1 so subsequent control transfers reach the addressed device.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
Returns
ra8_err_t
Return values
k_ra8_okSET_ADDRESS completed; DCP retargeted to addr 1.
k_ra8_err_*ra8_usb_host_control_xfer or set_target failure.
Precondition
The device has been enumerated at address 0 (internal_enum_hunt passed).
The DCP is currently targeting device address 0.
Postcondition
On k_ra8_ok, all subsequent DCP transactions use device address 1.
k_rdh_addr_settle_ms has elapsed since the status phase.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 200 of file ra8_dfu_host.c.

References k_ra8_ok, k_rdh_addr_settle_ms, k_rdh_bm_std_dev_out, k_rdh_breq_set_addr, k_rdh_dev_addr, ra8_delay_ms(), RA8_INTERNAL, ra8_usb_host_control_xfer(), and ra8_usb_host_set_target().

Referenced by internal_program_seq(), and internal_run_seq().

◆ internal_set_config()

ra8_err_t internal_set_config ( ra8_usb_speed_t speed)
static

Issue SET_CONFIGURATION(1) on the addressed device.

Sends a standard Chapter-9 SET_CONFIGURATION control request selecting bConfigurationValue k_rdh_config_val (1), which activates the DFU interface and brings the device from the Addressed state into the Configured state. The request has no data phase; success is indicated by the device accepting the status phase.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
Returns
ra8_err_t
Return values
k_ra8_okDevice is now in the Configured state (dfuIDLE).
k_ra8_err_*ra8_usb_host_control_xfer failure.
Precondition
SET_ADDRESS has completed successfully (internal_set_address passed).
The DCP is targeting device address k_rdh_dev_addr.
Postcondition
On k_ra8_ok, the DFU interface is active and the device is in dfuIDLE.
The device is ready to accept DFU class requests.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 241 of file ra8_dfu_host.c.

References k_rdh_bm_std_dev_out, k_rdh_breq_set_config, k_rdh_config_val, RA8_INTERNAL, and ra8_usb_host_control_xfer().

Referenced by internal_program_seq(), and internal_run_seq().

◆ internal_upload_verify()

ra8_err_t internal_upload_verify ( ra8_usb_speed_t speed,
const uint8_t * img,
uint32_t img_len,
ra8_dfu_host_result_t * out )
static

DFU_UPLOAD each block and byte-compare against img.

Iterates over each k_rdh_xfer_size (64)-byte block in img_len. For each block it issues a DFU class-specific UPLOAD request (bmRequestType=0xA1, bRequest=0x02, wValue=block index, wLength=64) and validates that exactly k_rdh_xfer_size bytes were returned. It then calls memcmp to check the received buffer against the corresponding region of img. The function increments out->blocks_ok for each passing block and records the first failing block index in out->mismatch on a size or data error. Processing stops at the first error.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]imgExpected image bytes to compare against.
[in]img_lenTotal image length; must be a non-zero multiple of k_rdh_xfer_size (64).
[out]outDiagnostics structure; out->blocks_ok is updated on each passing block; out->mismatch is set on first error.
Returns
ra8_err_t
Return values
k_ra8_okAll blocks uploaded and byte-matched img.
k_ra8_err_invalid_sizeAn upload block returned the wrong byte count.
k_ra8_err_invalid_stateAn upload block's data differed from img.
k_ra8_err_*ra8_usb_host_control_xfer failure.
Precondition
The device is in dfuIDLE state (DFU_ABORT or prior state transition done).
img and out are non-NULL; img_len is a non-zero multiple of 64.
Postcondition
On k_ra8_ok, out->blocks_ok equals img_len / k_rdh_xfer_size.
On failure, out->mismatch holds the index of the first bad block.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 547 of file ra8_dfu_host.c.

References ra8_dfu_host_result_t::blocks_ok, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_ok, k_rdh_bm_class_if_in, k_rdh_breq_upload, k_rdh_intf, k_rdh_xfer_size, memcmp(), ra8_dfu_host_result_t::mismatch, RA8_INTERNAL, and ra8_usb_host_control_xfer().

Referenced by internal_run_seq().

◆ internal_wait_state()

ra8_err_t internal_wait_state ( ra8_usb_speed_t speed,
uint8_t want_state )
static

Poll DFU_GETSTATUS until the device reaches want_state or the retry cap.

Loops up to k_rdh_status_tries times, calling internal_getstatus on each iteration. When the returned bState equals want_state the function returns k_ra8_ok immediately. Between unsuccessful polls it inserts a k_rdh_status_poll_ms delay. If the retry cap is exhausted without seeing the target state the function returns k_ra8_err_hw_timeout. Any internal_getstatus failure terminates the loop early and propagates the error to the caller.

Parameters
[in]speedController speed (FS or HS) selecting the USB port.
[in]want_stateDFU bState value to wait for (e.g. dfuDNLOAD-IDLE=5, dfuIDLE=2).
Returns
ra8_err_t
Return values
k_ra8_okThe device entered want_state within the limit.
k_ra8_err_hw_timeoutk_rdh_status_tries polls elapsed without match.
k_ra8_err_*internal_getstatus failure propagated.
Precondition
The device is in the Configured state and the DFU interface is active.
want_state is a valid DFU bState value for the expected transition.
Postcondition
On k_ra8_ok, the device bState at the last GETSTATUS poll equals want_state.
On k_ra8_err_hw_timeout, at least k_rdh_status_tries GETSTATUS polls were issued without observing the target state.
Note
Not thread-safe; called only from the single-threaded polled sequence.
Since
0.1.0

Definition at line 333 of file ra8_dfu_host.c.

References internal_getstatus(), k_ra8_err_hw_timeout, k_ra8_ok, k_rdh_status_poll_ms, k_rdh_status_tries, ra8_delay_ms(), and RA8_INTERNAL.

Referenced by internal_dnload_block(), and internal_download_all().

◆ ra8_dfu_host_program()

ra8_err_t ra8_dfu_host_program ( ra8_usb_speed_t host_speed,
const uint8_t * img,
uint32_t img_len,
ra8_dfu_host_result_t * out )
nodiscard

Enumerate, DFU_DNLOAD img, then a zero-length DFU_DNLOAD (manifest).

The real DFU flash flow – what dfu-util does – rather than the self-test round-trip of ra8_dfu_host_run. Brings the host controller up, enumerates the DFU device, downloads img one 64-byte block at a time, then issues a zero-length DFU_DNLOAD that signals end-of-download so the DEVICE commits the slot header (via its worker) and enters dfuMANIFEST. There is no UPLOAD/ABORT: the caller drives the device half on the SAME chip (self-loop) and confirms the commit with ra8_dfu_device_committed + ra8_dfu_slot_valid.

Parameters
[in]host_speedWhich controller acts as host (FS or HS).
[in]imgBootable slot image to flash (non-NULL).
[in]img_lenImage length; non-zero multiple of 64.
[out]outResult/diagnostics (non-NULL; pid populated).
Returns
ra8_err_t outcome (also mirrored in out->last_err).
Return values
k_ra8_okImage downloaded and the manifest accepted.
k_ra8_err_null_ptrimg or out was NULL.
k_ra8_err_invalid_argimg_len is 0 or not a multiple of 64.
k_ra8_err_*The failing enumerate / transfer code.
Precondition
The two USB jacks are cabled together; host_speed is the host jack.
ra8_time_init has run; the device half targets the slot to commit.
Postcondition
On failure the host controller is deinitialized for a clean retry.
The device has been told to commit; the caller polls for completion.
Note
Blocking; runs on the host worker thread.
Since
0.1.0

Definition at line 727 of file ra8_dfu_host.c.

References ra8_dfu_host_result_t::blocks_ok, internal_program_seq(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, k_rdh_mismatch_none, k_rdh_xfer_size, ra8_dfu_host_result_t::last_err, ra8_dfu_host_result_t::mismatch, ra8_dfu_host_result_t::pid, ra8_usb_host_deinit(), and ra8_usb_host_init().

Referenced by dfu_host_pass().

◆ ra8_dfu_host_run()

ra8_err_t ra8_dfu_host_run ( ra8_usb_speed_t host_speed,
const uint8_t * img,
uint32_t img_len,
ra8_dfu_host_result_t * out )
nodiscard

Enumerate, DFU_DNLOAD img, DFU_ABORT, DFU_UPLOAD, and byte-verify.

Runs the full round-trip on host_speed: brings the host controller up, enumerates the DFU device (bus reset -> GET_DESCRIPTOR -> SET_ADDRESS -> SET_CONFIGURATION, into dfuIDLE), downloads img one 64-byte block at a time (polling DFU_GETSTATUS to dfuDNLOAD-IDLE between blocks), DFU_ABORTs back to dfuIDLE, then uploads each block and compares to img. The device half programs/serves the bytes from real MRAM, so a clean byte-match proves the inactive slot was actually written.

Parameters
[in]host_speedWhich controller acts as host (FS or HS).
[in]imgImage to download + expected upload bytes (non-NULL).
[in]img_lenImage length; non-zero multiple of 64.
[out]outResult/diagnostics (non-NULL).
Returns
ra8_err_t outcome (also mirrored in out->last_err).
Return values
k_ra8_okDownload + upload + byte-verify all passed.
k_ra8_err_null_ptrimg or out was NULL.
k_ra8_err_invalid_argimg_len is 0 or not a multiple of 64.
k_ra8_err_invalid_sizeAn upload block returned the wrong length.
k_ra8_err_invalid_stateAn upload block's bytes differed.
k_ra8_err_*The failing enumerate / transfer code.
Precondition
The two USB jacks are cabled together; host_speed is the host jack.
ra8_time_init has run (ms delays); img_len % 64 == 0.
Postcondition
On any failure the host controller is deinitialized for a clean retry.
out is fully populated.
Note
Blocking; runs on the host worker thread.
Since
0.1.0

Definition at line 641 of file ra8_dfu_host.c.

References ra8_dfu_host_result_t::blocks_ok, internal_run_seq(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, k_rdh_mismatch_none, k_rdh_xfer_size, ra8_dfu_host_result_t::last_err, ra8_dfu_host_result_t::mismatch, ra8_dfu_host_result_t::pid, ra8_usb_host_deinit(), and ra8_usb_host_init().

Referenced by dfu_host_pass().