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

USBX DFU device class wired to real MRAM, bound to either controller. More...

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

Go to the source code of this file.

Functions

void ra8_dfu_device_set_target (ra8_dfu_slot_t target_slot)
 Select the slot DFU_DNLOAD programs into / DFU_UPLOAD reads from.
ra8_err_t ra8_dfu_device_start (ra8_usb_speed_t speed, void *usbx_pool, uint32_t pool_bytes, unsigned char *framework, uint32_t framework_len, unsigned char *strings, uint32_t strings_len, unsigned char *langids, uint32_t langids_len)
 Bring up USBX + the DFU class on one controller and raise D+.
ra8_err_t ra8_dfu_device_worker_step (void)
 Program any pending DNLOAD block into MRAM; commit on end-of-download.
uint32_t ra8_dfu_device_image_len (void)
 Total image bytes accepted so far (diagnostic).
uint32_t ra8_dfu_device_block_writes (void)
 Count of DNLOAD blocks programmed into MRAM (diagnostic).
bool ra8_dfu_device_manifested (void)
 Whether the host has signalled end-of-download / manifest.
ra8_err_t ra8_dfu_device_last_error (void)
 Latched last program error (diagnostic).
bool ra8_dfu_device_committed (void)
 Whether the image header has been committed (slot now bootable).

Detailed Description

USBX DFU device class wired to real MRAM, bound to either controller.

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

Front-half of the controller-agnostic DFU device. Registers the vendored USBX DFU class and points its write/read/get_status/notify callbacks at the ra8_dfu_program MRAM path so a DFU_DNLOAD actually programs the inactive application slot and a DFU_UPLOAD reads it back. Which USB controller it runs on is purely the ra8_usb_speed_t passed to ra8_dfu_device_start (threaded through the ux_dcd_ra8_usb bridge) – the same core drives the FS device in Config A and the HS device in Config B.

The slow MRAM erase/program runs in the caller's device-worker thread via ra8_dfu_device_worker_step (the code-MRAM program loop must not run in an ISR or from MRAM); dfu_write only stages a block and the host's DFU_GETSTATUS sees dfuDNBUSY until the worker catches up.

Definition in file ra8_dfu_device.h.

Function Documentation

◆ ra8_dfu_device_block_writes()

uint32_t ra8_dfu_device_block_writes ( void )

Count of DNLOAD blocks programmed into MRAM (diagnostic).

Returns the value of the internal writes field, which is incremented once per successfully programmed DNLOAD block inside ::internal_dfu_write. A block is only counted if the MRAM program call returned k_ra8_ok; blocks that fault increment prog_err instead. Intended for J-Link live-watch or host diagnostics.

Returns
Number of DNLOAD blocks successfully written to MRAM since ra8_dfu_device_start was called.
Return values
0No blocks have been successfully programmed yet.
Precondition
ra8_dfu_device_start has been called and returned k_ra8_ok.
The caller reads this value only for diagnostic purposes; the underlying field is updated by ::internal_dfu_write (USBX context).
Postcondition
The returned value is a snapshot; it may increase as further blocks are received from the host.
The internal counter is not reset or modified by this call.
Note
Safe to read from any context; the underlying field is volatile.
Since
0.1.0

◆ ra8_dfu_device_committed()

bool ra8_dfu_device_committed ( void )

Whether the image header has been committed (slot now bootable).

Returns the internal committed flag, which is set to true by ra8_dfu_device_worker_step immediately after ra8_dfu_program_commit succeeds (or even on failure, to prevent repeated commit attempts). Goes true after ra8_dfu_device_worker_step writes the header on end-of-download. A bootloader polls this to know when it is safe to reset into the freshly programmed slot.

Returns
true once the target slot's header has been written; false while the download is still in progress or the commit has not yet run.
Return values
trueThe slot header has been committed; the slot is now bootable (assuming no program error was latched).
falseThe commit has not yet run; download may still be in flight.
Precondition
ra8_dfu_device_start has been called and returned k_ra8_ok.
ra8_dfu_device_manifested returns true before this flag becomes true; commit follows manifest in the worker step.
Postcondition
The returned value reflects the committed field at the time of the call; it will never revert to false once it becomes true.
The committed field itself is not modified by this call.
Note
Safe to read from any context; the underlying field is volatile.
Since
0.1.0

Referenced by blc_device_worker(), and dfu_host_pass().

◆ ra8_dfu_device_image_len()

uint32_t ra8_dfu_device_image_len ( void )

Total image bytes accepted so far (diagnostic).

Returns the value of the internal img_len field, which tracks the highest byte offset written: (block_number * wTransferSize) + padded block length. Updated by ra8_dfu_device_worker_step on each successful DNLOAD block. Intended for J-Link live-watch or host diagnostics; not needed for correct DFU operation.

Returns
Highest end-offset reached across all programmed DNLOAD blocks, in bytes. Zero if no block has been successfully programmed yet.
Return values
0No blocks have been successfully programmed yet.
Precondition
ra8_dfu_device_start has been called and returned k_ra8_ok.
The caller reads this value only for diagnostic purposes; no lock is required if single-reader, single-writer (worker thread updates it).
Postcondition
The returned value is a snapshot; it may increase on the next worker step if a new block is being programmed concurrently.
The internal counter is not reset by this call.
Note
Safe to read from any context; the underlying field is volatile.
Since
0.1.0

◆ ra8_dfu_device_last_error()

ra8_err_t ra8_dfu_device_last_error ( void )

Latched last program error (diagnostic).

Returns the value of s_dev.prog_err, which is latched to the first non-k_ra8_ok result from any ra8_dfu_program_image or ra8_dfu_program_commit call. Once set to a non-OK code it is never cleared within the session. ::internal_dfu_get_status and ::internal_dfu_write both read this field to decide which USBX media-status code to report to the host.

Returns
The latched program error code.
Return values
k_ra8_okNo program fault has occurred in this session.
k_ra8_err_*The error from the first failing ::ra8_dfu_program_* call; subsequent errors do not overwrite this value.
Precondition
ra8_dfu_device_start has been called and returned k_ra8_ok.
The field is initialised to k_ra8_ok by static zero-initialisation of the file-scope context; no explicit reset call is needed.
Postcondition
The returned value is a snapshot of the latch at the time of the call.
The latch is not reset or modified by this call.
Note
Safe to read from any context; the underlying field is volatile.
Since
0.1.0

Referenced by blc_device_worker(), and dfu_host_pass().

◆ ra8_dfu_device_manifested()

bool ra8_dfu_device_manifested ( void )

Whether the host has signalled end-of-download / manifest.

Returns the internal manifest flag, which is set to true by ::internal_dfu_write when a zero-length DNLOAD block (end-of-download) is received, or by ::internal_dfu_notify on a UX_SLAVE_CLASS_DFU_NOTIFICATION_END_DOWNLOAD event. Once set it is never cleared within a session. ra8_dfu_device_worker_step polls this flag to decide when to commit the image header.

Returns
true once a manifest or end-of-download signal has been received from the host; false while the download is still in progress.
Return values
trueEnd-of-download has been signalled; header commit is pending or already done.
falseNo end-of-download has arrived yet; download still in flight.
Precondition
ra8_dfu_device_start has been called and returned k_ra8_ok.
At least one DFU_DNLOAD transaction has been processed by the USBX stack (otherwise the flag remains false by initialisation).
Postcondition
The returned value reflects the manifest field at the time of the call; it will never revert to false once it becomes true.
The manifest field itself is not modified by this call.
Note
Safe to read from any context; the underlying field is volatile.
Since
0.1.0

◆ ra8_dfu_device_set_target()

void ra8_dfu_device_set_target ( ra8_dfu_slot_t target_slot)

Select the slot DFU_DNLOAD programs into / DFU_UPLOAD reads from.

Records the INACTIVE slot all subsequent DFU transfers act on; an out-of-range value is ignored so the default (Slot B) stands. Set once during init, before ra8_dfu_device_start.

Parameters
[in]target_slotSlot A or B (must NOT be the slot the caller runs from).
Precondition
Called before ra8_dfu_device_start.
target_slot is A or B.
Postcondition
Subsequent downloads target that slot.
Defaults to Slot B if unset.
Note
Not thread-safe; configure during init.
Since
0.1.0

Referenced by dfu_device_worker(), and main().

◆ ra8_dfu_device_start()

ra8_err_t ra8_dfu_device_start ( ra8_usb_speed_t speed,
void * usbx_pool,
uint32_t pool_bytes,
unsigned char * framework,
uint32_t framework_len,
unsigned char * strings,
uint32_t strings_len,
unsigned char * langids,
uint32_t langids_len )
nodiscard

Bring up USBX + the DFU class on one controller and raise D+.

Initialises the USBX system + device stack with the caller's descriptor framework, registers the DFU class with the MRAM-backed callbacks, runs ux_dcd_ra8_usb_initialize for speed, and attaches the D+ pull-up. The device enumerates directly into dfuIDLE (DFU-mode interface).

Parameters
[in]speedWhich USB controller (FS or HS).
[in]usbx_poolStatic byte pool for USBX (non-NULL).
[in]pool_bytesSize of usbx_pool.
[in]frameworkUSB descriptor framework (device + config + DFU).
[in]framework_lenLength of framework.
[in]stringsString-descriptor framework.
[in]strings_lenLength of strings.
[in]langidsLANGID framework.
[in]langids_lenLength of langids.
Returns
ra8_err_t outcome.
Return values
k_ra8_okDevice stack up, class registered, D+ raised.
k_ra8_err_null_ptrA required pointer was NULL.
k_ra8_err_invalid_stateUSBX init / class register failed.
k_ra8_err_hw_errorDCD init or attach failed.
Precondition
usbx_pool/framework/strings/langids non-NULL; thread context.
ra8_dfu_device_set_target chose a slot not in use by the caller.
Postcondition
On success the device is enumerable in dfuIDLE on speed.
Note
Not thread-safe; single init.
Since
0.1.0

Referenced by blc_device_worker(), and dfu_device_worker().

◆ ra8_dfu_device_worker_step()

ra8_err_t ra8_dfu_device_worker_step ( void )

Program any pending DNLOAD block into MRAM; commit on end-of-download.

Call repeatedly from the device-worker thread. On the first block it prepares the target slot (ra8_dfu_program_prepare). Each staged block is programmed via ra8_dfu_program_image. When the host signals end-of-download (zero-length DNLOAD / manifest) the slot header is committed (ra8_dfu_program_commit) so the slot becomes bootable. Slow + SRAM-resident, which is why it lives in thread context and not the DFU callback.

Returns
The most recent program error.
Return values
k_ra8_okIdle, or the pending block programmed cleanly.
k_ra8_err_*The failing ::ra8_dfu_program_* code (latched).
Precondition
ra8_dfu_device_start has run.
Caller is the device-worker thread.
Postcondition
A pending block is programmed and the BUSY status is cleared.
On end-of-download the target slot's header is committed.
Note
Not thread-safe vs a second worker.
Since
0.1.0

Referenced by blc_device_worker(), and dfu_device_worker().