|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Generic DMA transfer substrate implementation. More...
#include "ra8_dma.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_dmac.h"#include "ra8_err.h"#include "ra8_log.h"#include "ra8_mstp.h"#include "ra8_mstp_regs.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_dma_channel_state_t |
| Per-channel dispatch-table entry. More... | |
Functions | |
| static uint8_t | internal_find_free (void) |
| Find the first free channel. | |
| static void | internal_pack_dmac_cfg (const ra8_dma_request_t *req, ra8_dmac_config_t *out_cfg) |
| Copy a high-level ra8_dma_request_t into the lower-level ra8_dmac_config_t the DMAC driver expects. | |
| static ra8_err_t | internal_validate_request (const ra8_dma_request_t *req) |
| Validate a request descriptor before touching hardware. | |
| ra8_err_t | ra8_dma_init (void) |
| Bring up the generic DMA substrate. | |
| ra8_err_t | ra8_dma_deinit (void) |
| Tear down the generic DMA substrate. | |
| ra8_err_t | ra8_dma_request (const ra8_dma_request_t *req, uint8_t *out_channel) |
| Allocate a channel and arm a DMAC transfer. | |
| ra8_err_t | ra8_dma_release (uint8_t channel) |
| Release a previously allocated channel. | |
| ra8_err_t | ra8_dma_channel_is_busy (uint8_t channel, bool *out_busy) |
| Query the allocation state of a channel. | |
| void | ra8_dma_dispatch_complete (uint8_t channel) |
| Fire the per-channel completion callback. | |
Variables | |
| static const char * | s_tag = "DMA" |
| static ra8_dma_channel_state_t | s_channels [k_ra8_dma_channel_count] |
| Channel allocation + dispatch table. | |
| static bool | s_initialized = false |
| true while the substrate is live (between ra8_dma_init and ra8_dma_deinit). | |
Generic DMA transfer substrate implementation.
See ra8_dma.h for the API contract. This file owns the channel-allocation table and the completion dispatch table. Per-channel register writes go through ra8_dmac_start / ra8_dmac_stop. Callers that need the DTC's vector-table transfer model use ra8_dtc_* directly.
Definition in file ra8_dma.c.
|
static |
Find the first free channel.
Linear scan over the static s_channels[] table looking for the first slot whose in_use flag is false. Used by ra8_dma_request() to allocate a channel; tests may also call it to assert table consistency. Loop is bounded by k_ra8_dma_channel_count.
| 0..k_ra8_dma_channel_count-1 | First free channel index. |
| k_ra8_dma_channel_none | Every channel slot is currently in use. |
Definition at line 113 of file ra8_dma.c.
References k_ra8_dma_channel_count, k_ra8_dma_channel_none, RA8_INTERNAL, and s_channels.
Referenced by ra8_dma_request().
|
static |
Copy a high-level ra8_dma_request_t into the lower-level ra8_dmac_config_t the DMAC driver expects.
Translates the user-facing request descriptor (typed addresses, width enum, increment direction) into the register-level config struct consumed by ra8_dmac_start(). No validation – caller has already invoked internal_validate_request().
| [in] | req | Source request descriptor (non-NULL). |
| [out] | out_cfg | Destination DMAC config struct (non-NULL). |
Definition at line 144 of file ra8_dma.c.
References ra8_dma_request_t::count, ra8_dmac_config_t::count, ra8_dmac_config_t::dst, ra8_dma_request_t::dst_addr, ra8_dma_request_t::dst_inc, ra8_dmac_config_t::dst_inc, RA8_INTERNAL, ra8_dmac_config_t::src, ra8_dma_request_t::src_addr, ra8_dma_request_t::src_inc, ra8_dmac_config_t::src_inc, ra8_dma_request_t::width, and ra8_dmac_config_t::width.
Referenced by ra8_dma_request().
|
static |
Validate a request descriptor before touching hardware.
Bounds-checks the byte count and width enum so a malformed request is rejected before a single DMAC register write. Width must be within the k_ra8_dmac_width_* range (HUM Ch 16.2.4 "DMTMD : DMA Transfer Mode Register", p 608).
| [in] | req | Request descriptor (non-NULL). |
| k_ra8_ok | Request is well-formed. |
| k_ra8_err_invalid_arg | count == 0 or width out of range. |
Definition at line 178 of file ra8_dma.c.
References ra8_dma_request_t::count, k_ra8_dmac_width_word, k_ra8_err_invalid_arg, k_ra8_ok, RA8_INTERNAL, and ra8_dma_request_t::width.
Referenced by ra8_dma_request().
|
nodiscard |
Query the allocation state of a channel.
Diagnostic accessor used by unit tests to verify the allocator state. Returns true if the channel is currently in use.
| [in] | channel | Channel number 0..k_ra8_dma_channel_count - 1. |
| [out] | out_busy | On success, true if allocated. |
| k_ra8_ok | Query successful. |
| k_ra8_err_null_ptr | out_busy NULL. |
| k_ra8_err_invalid_arg | channel out of range. |
Definition at line 428 of file ra8_dma.c.
References k_ra8_dma_channel_count, k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, s_channels, and s_tag.
|
nodiscard |
Tear down the generic DMA substrate.
Release the DMA substrate.
Stops every in-use channel via ra8_dmac_stop(), clears the dispatch table, and releases the MSTPA22 reference (HUM Ch 11.2.6, p 443). After this returns ra8_dma_request() rejects with k_ra8_err_not_initialized.
| k_ra8_ok | All channels stopped and MSTP released. |
| k_ra8_err_hw_error | Underlying ra8_mstp_disable() failed. |
Definition at line 257 of file ra8_dma.c.
References k_ra8_dma_channel_count, k_ra8_err_hw_error, k_ra8_mstp_dmac0_dtc0, k_ra8_ok, ra8_dmac_stop(), ra8_log_error_val, ra8_mstp_disable(), s_channels, s_initialized, and s_tag.
| void ra8_dma_dispatch_complete | ( | uint8_t | channel | ) |
Fire the per-channel completion callback.
Dispatch a transfer-end completion callback for one channel.
Looks up the stashed callback / context for channel and invokes the callback if non-NULL. Called from the DMAC IRQ trampoline (or from a unit-test driver in off-target mode). Out-of-range channels are silently ignored.
| [in] | channel | Channel whose completion just fired. |
Definition at line 458 of file ra8_dma.c.
References k_ra8_dma_channel_count, and s_channels.
|
nodiscard |
Bring up the generic DMA substrate.
Initialise the DMA substrate.
Enables MSTPA22 (shared with DTC0, HUM Ch 11.2.6 "MSTPCRA : Module Stop Control Register A", p 443) and clears every entry in the channel-allocation / dispatch table. After this returns ra8_dma_request() may allocate channels.
| k_ra8_ok | Channel table reset and MSTP gate opened. |
| k_ra8_err_hw_init_failed | Underlying ra8_mstp_enable() failed. |
Definition at line 215 of file ra8_dma.c.
References k_ra8_dma_channel_count, k_ra8_err_hw_init_failed, k_ra8_mstp_dmac0_dtc0, k_ra8_ok, ra8_log_error_val, ra8_log_info, ra8_mstp_enable(), s_channels, s_initialized, and s_tag.
Referenced by internal_setup_or_halt(), and ra8_nsc_periph_init().
|
nodiscard |
Release a previously allocated channel.
Stop a channel and return it to the free pool.
Calls ra8_dmac_stop() to disable the channel at the hardware level, then clears the dispatch entry. The MSTP reference held by the substrate root is preserved – only ra8_dma_deinit() releases it.
| [in] | channel | Channel previously returned by ra8_dma_request(). |
| k_ra8_ok | Channel released. |
| k_ra8_err_invalid_arg | channel >= k_ra8_dma_channel_count. |
| k_ra8_err_invalid_state | Channel was not in use. |
| k_ra8_err_hw_error | ra8_dmac_stop() failed. |
Definition at line 370 of file ra8_dma.c.
References k_ra8_dma_channel_count, k_ra8_err_hw_error, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, ra8_dmac_stop(), ra8_log_error_val, s_channels, and s_tag.
Referenced by internal_run_one().
|
nodiscard |
Allocate a channel and arm a DMAC transfer.
Allocate a DMAC channel, programme it, and start the trigger wiring.
Validates *req, finds a free channel via internal_find_free(), packs a ra8_dmac_config_t and calls ra8_dmac_start(). On success the channel index is written through out_channel and the caller-supplied completion callback is stashed for later dispatch.
| [in] | req | Transfer descriptor (non-NULL). |
| [out] | out_channel | Allocated channel index (non-NULL). |
| k_ra8_ok | Channel allocated and DMAC armed. |
| k_ra8_err_invalid_arg | req malformed. |
| k_ra8_err_not_initialized | ra8_dma_init() was not called. |
| k_ra8_err_no_mem | No free channel. |
| k_ra8_err_hw_error | ra8_dmac_start() failed. |
Definition at line 308 of file ra8_dma.c.
References ra8_dma_request_t::ctx, internal_find_free(), internal_pack_dmac_cfg(), internal_validate_request(), k_ra8_dma_channel_none, k_ra8_err_hw_error, k_ra8_err_no_mem, k_ra8_err_not_initialized, k_ra8_ok, ra8_dma_request_t::on_complete, RA8_CHECK_NULL_PTR, ra8_dmac_start(), ra8_log_error, ra8_log_error_val, s_channels, s_initialized, and s_tag.
Referenced by ra8_gpt_read_dma(), ra8_gpt_write_dma(), ra8_sci_read_dma(), ra8_sci_write_dma(), ra8_spi_read_dma(), and ra8_spi_write_dma().
|
static |
Channel allocation + dispatch table.
Indexed by DMAC channel number. Updated by ra8_dma_request / release and read by ra8_dma_dispatch_complete.
Definition at line 59 of file ra8_dma.c.
Referenced by internal_find_free(), ra8_dma_channel_is_busy(), ra8_dma_deinit(), ra8_dma_dispatch_complete(), ra8_dma_init(), ra8_dma_release(), and ra8_dma_request().
|
static |
true while the substrate is live (between ra8_dma_init and ra8_dma_deinit).