|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
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"Go to the source code of this file.
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). | |
Polled on-board USB-DFU host driver (factored from usb_selftest_dfu).
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.
| enum rdh_proto_t : uint16_t |
Chapter-9 + DFU class request / descriptor constants.
Definition at line 29 of file ra8_dfu_host.c.
| enum rdh_tune_t : uint32_t |
Timing / retry tunables for the polled enumeration + status polling.
Definition at line 56 of file ra8_dfu_host.c.
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | block | DFU block sequence number (wValue in the setup packet). |
| [in] | data | Pointer to the block payload (exactly len bytes). |
| [in] | len | Number of bytes to download in this block. |
| k_ra8_ok | Block delivered and device reached dfuDNLOAD-IDLE. |
| k_ra8_err_hw_timeout | Device did not reach dfuDNLOAD-IDLE in time. |
| k_ra8_err_* | ra8_usb_host_control_xfer or wait_state failure. |
data points to a buffer of at least len valid bytes. block and is in dfuDNLOAD-IDLE. 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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | img | Pointer to the image buffer (non-NULL). |
| [in] | img_len | Total image length; must be a non-zero multiple of k_rdh_xfer_size (64). |
| k_ra8_ok | All blocks downloaded; device is in dfuIDLE. |
| k_ra8_err_hw_timeout | A block poll timed out or abort wait timed out. |
| k_ra8_err_* | internal_dnload_block or DFU_ABORT xfer failure. |
img_len is a non-zero multiple of k_rdh_xfer_size and img is valid. 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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | img | Pointer to the image buffer (non-NULL). |
| [in] | img_len | Total image length; must be a non-zero multiple of k_rdh_xfer_size (64). |
| k_ra8_ok | All blocks and the zero-length manifest were accepted. |
| k_ra8_err_hw_timeout | A block poll timed out before the manifest was sent. |
| k_ra8_err_* | internal_dnload_block or manifest xfer failure. |
img_len is a non-zero multiple of k_rdh_xfer_size and img is valid. 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().
|
static |
Wait for device attach, apply bus reset, and read the DEVICE descriptor.
Sequence:
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [out] | desc | Caller-allocated buffer of at least k_rdh_dev_desc_len bytes; receives the raw DEVICE descriptor on success. |
| k_ra8_ok | Device attached and descriptor received. |
| k_ra8_err_hw_timeout | All k_rdh_enum_tries attempts failed. |
| k_ra8_err_* | Last internal_get_dev_desc failure code. |
speed has been initialized. desc is valid. 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().
|
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.
| [in] | speed | Controller speed (FS or HS) that selects the USB port. |
| [out] | desc | Caller-allocated buffer of at least k_rdh_dev_desc_len bytes; receives the raw DEVICE descriptor on success. |
| k_ra8_ok | Descriptor received and fully length-checked. |
| k_ra8_err_hw_error | Transfer succeeded but byte count was short. |
| k_ra8_err_* | Underlying ra8_usb_host_control_xfer failure. |
speed has been initialized. desc holds the complete 18-byte DEVICE descriptor. desc content is undefined.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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [out] | out_state | Receives the bState byte from the GETSTATUS response. |
| k_ra8_ok | Status received; out_state is valid. |
| k_ra8_err_hw_error | Transfer succeeded but byte count was not 6. |
| k_ra8_err_* | ra8_usb_host_control_xfer failure. |
out_state is a non-NULL pointer to a writable uint8_t. out_state holds the current DFU bState value. out_state is unchanged.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().
|
static |
Run the real-flash sequence: enumerate, download, then send manifest.
Orchestrates the real DFU programming flow in four ordered steps:
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.| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | img | Bootable slot image to flash into the device. |
| [in] | img_len | Total image length; non-zero multiple of 64. |
| [out] | out | Diagnostics structure; out->pid set after enumeration. |
| k_ra8_ok | All four steps completed; device is in dfuMANIFEST. |
| k_ra8_err_hw_timeout | Attach or GETSTATUS wait exhausted. |
| k_ra8_err_* | Error from any of the four sub-functions. |
speed has been initialized via ra8_usb_host_init. img and out are non-NULL; img_len is a non-zero multiple of 64. 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().
|
static |
Run the full self-test sequence: enumerate, download, abort, upload-verify.
Orchestrates the round-trip DFU self-test in five ordered steps:
img to the device and DFU_ABORT.| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | img | Image to download and then verify via upload. |
| [in] | img_len | Total image length; non-zero multiple of 64. |
| [out] | out | Diagnostics structure; out->pid set after enumeration. |
| k_ra8_ok | All five steps completed successfully. |
| k_ra8_err_hw_timeout | Attach or GETSTATUS wait exhausted. |
| k_ra8_err_* | Error from any of the five sub-functions. |
speed has been initialized via ra8_usb_host_init. img and out are non-NULL; img_len is a non-zero multiple of 64. 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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| k_ra8_ok | SET_ADDRESS completed; DCP retargeted to addr 1. |
| k_ra8_err_* | ra8_usb_host_control_xfer or set_target failure. |
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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| k_ra8_ok | Device is now in the Configured state (dfuIDLE). |
| k_ra8_err_* | ra8_usb_host_control_xfer failure. |
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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | img | Expected image bytes to compare against. |
| [in] | img_len | Total image length; must be a non-zero multiple of k_rdh_xfer_size (64). |
| [out] | out | Diagnostics structure; out->blocks_ok is updated on each passing block; out->mismatch is set on first error. |
| k_ra8_ok | All blocks uploaded and byte-matched img. |
| k_ra8_err_invalid_size | An upload block returned the wrong byte count. |
| k_ra8_err_invalid_state | An upload block's data differed from img. |
| k_ra8_err_* | ra8_usb_host_control_xfer failure. |
img and out are non-NULL; img_len is a non-zero multiple of 64. 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().
|
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.
| [in] | speed | Controller speed (FS or HS) selecting the USB port. |
| [in] | want_state | DFU bState value to wait for (e.g. dfuDNLOAD-IDLE=5, dfuIDLE=2). |
| k_ra8_ok | The device entered want_state within the limit. |
| k_ra8_err_hw_timeout | k_rdh_status_tries polls elapsed without match. |
| k_ra8_err_* | internal_getstatus failure propagated. |
want_state is a valid DFU bState value for the expected transition. want_state. 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().
|
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.
| [in] | host_speed | Which controller acts as host (FS or HS). |
| [in] | img | Bootable slot image to flash (non-NULL). |
| [in] | img_len | Image length; non-zero multiple of 64. |
| [out] | out | Result/diagnostics (non-NULL; pid populated). |
| k_ra8_ok | Image downloaded and the manifest accepted. |
| k_ra8_err_null_ptr | img or out was NULL. |
| k_ra8_err_invalid_arg | img_len is 0 or not a multiple of 64. |
| k_ra8_err_* | The failing enumerate / transfer code. |
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().
|
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.
| [in] | host_speed | Which controller acts as host (FS or HS). |
| [in] | img | Image to download + expected upload bytes (non-NULL). |
| [in] | img_len | Image length; non-zero multiple of 64. |
| [out] | out | Result/diagnostics (non-NULL). |
| k_ra8_ok | Download + upload + byte-verify all passed. |
| k_ra8_err_null_ptr | img or out was NULL. |
| k_ra8_err_invalid_arg | img_len is 0 or not a multiple of 64. |
| k_ra8_err_invalid_size | An upload block returned the wrong length. |
| k_ra8_err_invalid_state | An upload block's bytes differed. |
| k_ra8_err_* | The failing enumerate / transfer code. |
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().