|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
8-channel DMA controller (DMAC0) driver More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_dmac_config_t |
| DMAC channel configuration. More... | |
Typedefs | |
| typedef void(* | ra8_dmac_callback_fn_t) (void *ctx) |
| Per-channel DMAC completion / half-complete callback signature. | |
Enumerations | |
| enum | ra8_dmac_width_t : uint8_t { k_ra8_dmac_width_byte = 0U , k_ra8_dmac_width_half = 1U , k_ra8_dmac_width_word = 2U } |
| Transfer element width. More... | |
| enum | ra8_dmac_mode_t : uint8_t { k_ra8_dmac_mode_normal = 0U , k_ra8_dmac_mode_repeat = 1U , k_ra8_dmac_mode_block = 2U , k_ra8_dmac_mode_repeat_block = 3U } |
| Transfer mode select. More... | |
| enum | ra8_dmac_repeat_area_t : uint8_t { k_ra8_dmac_repeat_area_dest = 0U , k_ra8_dmac_repeat_area_src = 1U , k_ra8_dmac_repeat_area_none = 2U } |
| Selects which side is the repeat / block area (DMTMD.DTS). More... | |
| enum | ra8_dmac_addr_mode_t : uint8_t { k_ra8_dmac_addr_fixed = 0U , k_ra8_dmac_addr_offset = 1U , k_ra8_dmac_addr_increment = 2U , k_ra8_dmac_addr_decrement = 3U } |
| Per-side address-update mode (DMAMD.SM / DMAMD.DM). More... | |
Functions | |
| ra8_err_t | ra8_dmac_start (uint8_t channel, const ra8_dmac_config_t *cfg) |
| Programme and enable a DMAC0 channel. | |
| ra8_err_t | ra8_dmac_stop (uint8_t channel) |
| Disable a DMAC0 channel and drop its MSTP reference. | |
| ra8_err_t | ra8_dmac_start_repeat (uint8_t channel, const ra8_dmac_config_t *cfg) |
| Programme a DMAC channel in repeat-area transfer mode. | |
| ra8_err_t | ra8_dmac_start_block (uint8_t channel, const ra8_dmac_config_t *cfg) |
| Programme a DMAC channel in block-transfer mode. | |
| ra8_err_t | ra8_dmac_set_address_mode (uint8_t channel, ra8_dmac_addr_mode_t src_mode, ra8_dmac_addr_mode_t dest_mode) |
| Override the DMAMD.SM / DMAMD.DM address-update modes. | |
| ra8_err_t | ra8_dmac_attach_half_complete_handler (uint8_t channel, ra8_dmac_callback_fn_t fn, void *ctx) |
| Attach a half-block IRQ callback to a DMAC channel. | |
| ra8_err_t | ra8_dmac_attach_callback (uint8_t channel, ra8_dmac_callback_fn_t fn, void *ctx) |
| Attach a transfer-end IRQ callback to a DMAC channel. | |
| void | ra8_dmac_dispatch (uint8_t channel) |
| Fire the per-channel completion callback (DMINT.DTIE path). | |
| void | ra8_dmac_dispatch_half (uint8_t channel) |
| Fire the per-channel half-complete callback (DMINT.RPTIE path). | |
| ra8_err_t | ra8_dmac_software_trigger (uint8_t channel) |
| Software-trigger one transfer request on a DMAC0 channel. | |
| ra8_err_t | ra8_dmac_is_active (uint8_t channel, bool *out_active) |
| Query whether a DMAC0 channel is mid-transfer. | |
| ra8_err_t | ra8_dmac_wait_idle (uint8_t channel, uint32_t poll_limit) |
| Spin until a DMAC0 channel goes idle or a poll bound expires. | |
8-channel DMA controller (DMAC0) driver
Thin wrapper around the per-channel DMAC0 register window. Mirrors the FSP R_DMAC_* transfer-API entry points using project-native names:
Anything that needs the DTC's vector-table-driven semantics calls ra8_dtc_* directly; this driver only handles the channel-style DMAC.
Definition in file ra8_dmac.h.
| typedef void(* ra8_dmac_callback_fn_t) (void *ctx) |
Per-channel DMAC completion / half-complete callback signature.
Invoked from the matching DMAC ISR (or by the host test fake via ra8_dmac_dispatch()). ctx is the user-supplied opaque pointer registered alongside the function.
Definition at line 212 of file ra8_dmac.h.
| enum ra8_dmac_addr_mode_t : uint8_t |
Per-side address-update mode (DMAMD.SM / DMAMD.DM).
Mirrors HUM 17.2.12 p 741. fixed keeps the DMSAR / DMDAR pointer static across transfers; increment advances the pointer by the transfer width; decrement walks backwards; offset adds the value in DMOFR after each transfer.
| Enumerator | |
|---|---|
| k_ra8_dmac_addr_fixed | 00b: address fixed. |
| k_ra8_dmac_addr_offset | 01b: offset addition. |
| k_ra8_dmac_addr_increment | 10b: increment. |
| k_ra8_dmac_addr_decrement | 11b: decrement. |
Definition at line 196 of file ra8_dmac.h.
| enum ra8_dmac_mode_t : uint8_t |
Transfer mode select.
Mirrors FSP transfer_mode_t and HUM DMTMD.MD field (17.2.10 p 738).
Repeat / block / repeat-block require non-zero block_count in ra8_dmac_config_t (driven into DMCRB). Repeat-block also requires DMSRR / DMDRR / DMSBS / DMDBS – not yet exposed here; callers needing it must extend the config.
| Enumerator | |
|---|---|
| k_ra8_dmac_mode_normal | DMTMD.MD = 00b. |
| k_ra8_dmac_mode_repeat | DMTMD.MD = 01b. |
| k_ra8_dmac_mode_block | DMTMD.MD = 10b. |
| k_ra8_dmac_mode_repeat_block | DMTMD.MD = 11b. |
Definition at line 67 of file ra8_dmac.h.
| enum ra8_dmac_repeat_area_t : uint8_t |
Selects which side is the repeat / block area (DMTMD.DTS).
Only meaningful in repeat or block mode. In normal and repeat- block mode the field is forced to "none" (HUM 17.2.10 p 738).
| Enumerator | |
|---|---|
| k_ra8_dmac_repeat_area_dest | DTS = 00b. Dest is repeat area. |
| k_ra8_dmac_repeat_area_src | DTS = 01b. Src is repeat area. |
| k_ra8_dmac_repeat_area_none | DTS = 10b. No repeat area. |
Definition at line 82 of file ra8_dmac.h.
| enum ra8_dmac_width_t : uint8_t |
Transfer element width.
Encodes the same 2-bit value as DMTMD.SZ. 64-bit transfers (DMTMD.SZ = 11b) exist on the chip but are not yet plumbed through this driver – see HUM 17.2.10 p 738.
| Enumerator | |
|---|---|
| k_ra8_dmac_width_byte | 8-bit transfers (DMTMD.SZ = 00b). |
| k_ra8_dmac_width_half | 16-bit transfers (DMTMD.SZ = 01b). |
| k_ra8_dmac_width_word | 32-bit transfers (DMTMD.SZ = 10b). |
Definition at line 50 of file ra8_dmac.h.
|
nodiscard |
Attach a transfer-end IRQ callback to a DMAC channel.
Registers a per-channel completion callback. The driver fires it whenever ra8_dmac_dispatch(channel) is called by the matching DMAC ISR (or, in host-test mode, by the test harness). Replaces any earlier global callback that the substrate may have used.
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | fn | Callback function (NULL clears the slot). |
| [in] | ctx | Opaque pointer passed to fn. |
| k_ra8_ok | Slot updated. |
| k_ra8_err_out_of_range | channel >= 8. |
Definition at line 524 of file ra8_dmac.c.
References k_ra8_dmac_channel_count, k_ra8_err_out_of_range, k_ra8_ok, and s_dmac_cb_slots.
|
nodiscard |
Attach a half-block IRQ callback to a DMAC channel.
Registers fn as the user-side handler invoked when DMINT.RPTIE fires (repeat-size end – HUM 17.2.11 p 739). The driver enables RPTIE in the DMAC ISR plumbing so the half-complete callback fires once per cfg->count transfers, independent of DTIE.
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | fn | Callback function (NULL clears the slot). |
| [in] | ctx | Opaque pointer passed to fn. |
| k_ra8_ok | Slot updated. |
| k_ra8_err_out_of_range | channel >= 8. |
Definition at line 514 of file ra8_dmac.c.
References k_ra8_dmac_channel_count, k_ra8_err_out_of_range, k_ra8_ok, and s_dmac_cb_slots.
| void ra8_dmac_dispatch | ( | uint8_t | channel | ) |
Fire the per-channel completion callback (DMINT.DTIE path).
Test / ISR helper; consumes the slot installed by ra8_dmac_attach_callback(). Silently returns if no callback is registered or the channel is out of range. Reads DMINT.DTIE (HUM Ch 16.2.7 "DMINT : DMA Interrupt Setting Register", p 612) to decide whether the transfer-end IRQ is enabled before invoking the callback.
| [in] | channel | DMAC0 channel index 0..7. |
Definition at line 535 of file ra8_dmac.c.
References k_ra8_dmac_channel_count, and s_dmac_cb_slots.
| void ra8_dmac_dispatch_half | ( | uint8_t | channel | ) |
Fire the per-channel half-complete callback (DMINT.RPTIE path).
ISR / test helper for the repeat-block half-complete event. Consumes the slot installed by ra8_dmac_attach_half_complete_handler() and silently returns if no callback is registered or the channel is out of range. Tied to DMINT.RPTIE (HUM Ch 16.2.7, p 612).
| [in] | channel | DMAC0 channel index 0..7. |
Definition at line 548 of file ra8_dmac.c.
References k_ra8_dmac_channel_count, and s_dmac_cb_slots.
|
nodiscard |
Query whether a DMAC0 channel is mid-transfer.
Reads DMSTS.ACT on channel (HUM Ch 17.2.16 "DMSTS : DMAC Status Register" p 745 – the ACT bit reads 1 while the controller is executing a transfer and clears to 0 once the request in flight has been satisfied). The status is returned through out_active rather than the return value so that a bad channel or a NULL pointer is still reportable as an error code (NASA P10 Rule 7).
| [in] | channel | DMAC0 channel index 0..7. |
| [out] | out_active | Set true when DMSTS.ACT is 1, else false. Untouched on any error return. |
| k_ra8_ok | *out_active written. |
| k_ra8_err_null_ptr | out_active is NULL. |
| k_ra8_err_out_of_range | channel >= 8. |
Definition at line 576 of file ra8_dmac.c.
References r_dmac_channel_regs_t::DMSTS, k_ra8_dmsts_act_mask, k_ra8_err_out_of_range, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dmac(), and s_tag.
|
nodiscard |
Override the DMAMD.SM / DMAMD.DM address-update modes.
Lets callers pick from the full 4-mode menu (fixed / offset / increment / decrement) per HUM 17.2.12 p 741. The base ra8_dmac_config_t only models fixed vs increment, so this entry point is required when offset-addition or decrement is needed (e.g. byte-reversed copy, ring-walk with stride).
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | src_mode | New DMAMD.SM value. |
| [in] | dest_mode | New DMAMD.DM value. |
| k_ra8_ok | DMAMD updated. |
| k_ra8_err_out_of_range | channel >= 8. |
| k_ra8_err_invalid_arg | Either mode > k_ra8_dmac_addr_decrement. |
Definition at line 492 of file ra8_dmac.c.
References r_dmac_channel_regs_t::DMAMD, k_ra8_dmac_addr_decrement, k_ra8_dmamd_dm_mask, k_ra8_dmamd_dm_pos, k_ra8_dmamd_sm_mask, k_ra8_dmamd_sm_pos, k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_ok, and ra8_dmac().
|
nodiscard |
Software-trigger one transfer request on a DMAC0 channel.
Writes DMREQ.SWREQ = 1 on channel to raise a software DMA transfer request (HUM Ch 17.2.15 "DMREQ : DMAC Software Start Register" p 744 – "When 1 is written to the SWREQ bit, a DMA transfer request is generated. After the DMA transfer is started [...] this bit is automatically cleared to 0"). The channel must already have been programmed and armed by ra8_dmac_start (or a sibling) with a software request source (DMTMD.DCTG = 00b, the driver default).
In block or repeat-block mode a single trigger moves a whole DMCRAH-sized block; in normal mode it moves one unit. Pair with ra8_dmac_wait_idle / ra8_dmac_is_active to observe completion. This is the HAL primitive that replaces reaching for ra8_dmac(channel)->DMREQ directly in application code.
| [in] | channel | DMAC0 channel index 0..7. |
| k_ra8_ok | Software request raised. |
| k_ra8_err_out_of_range | channel >= 8. |
Definition at line 565 of file ra8_dmac.c.
References r_dmac_channel_regs_t::DMREQ, k_ra8_dmreq_swreq_mask, k_ra8_err_out_of_range, k_ra8_ok, and ra8_dmac().
Referenced by internal_run_copy().
|
nodiscard |
Programme and enable a DMAC0 channel.
Mirrors FSP's R_DMAC_Open for the steady-state programme path. Sequence (matches HUM 17.6 register-setting procedure):
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | cfg | Transfer descriptor. |
| k_ra8_ok | Channel armed. |
| k_ra8_err_null_ptr | cfg is NULL. |
| k_ra8_err_out_of_range | channel >= 8. |
| k_ra8_err_invalid_arg | cfg->mode or cfg->width invalid. |
Definition at line 398 of file ra8_dmac.c.
References r_dma_shared_regs_t::DMAST, r_dmac_channel_regs_t::DMCNT, internal_program_channel(), internal_validate_cfg(), k_ra8_dmast_dmst_mask, k_ra8_dmcnt_dte_mask, k_ra8_err_out_of_range, k_ra8_mstp_dmac0_dtc0, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_dma_shared(), ra8_dmac(), ra8_log_info_val, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, and s_tag.
Referenced by internal_start_rx_dma(), internal_start_tx_dma(), internal_start_with_mode(), ra8_ceu_dma_pump(), and ra8_dma_request().
|
nodiscard |
Programme a DMAC channel in block-transfer mode.
Convenience wrapper that forces cfg->mode = k_ra8_dmac_mode_block before delegating to ra8_dmac_start(). The controller transfers cfg->count elements per trigger and then rewinds the repeat side; cfg->block_count blocks are processed before the channel is automatically disabled. HUM 17.2.10 p 738 (DMTMD.MD = 10b) and HUM 17.2.9 (DMCRB block count).
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | cfg | Transfer descriptor; mode is ignored. |
| k_ra8_ok | Channel armed in block mode. |
| k_ra8_err_null_ptr | cfg is NULL. |
| k_ra8_err_out_of_range | channel >= 8. |
| k_ra8_err_invalid_arg | cfg->block_count is zero. |
Definition at line 483 of file ra8_dmac.c.
References ra8_dmac_config_t::block_count, internal_start_with_mode(), k_ra8_dmac_mode_block, k_ra8_err_invalid_arg, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_run_copy().
|
nodiscard |
Programme a DMAC channel in repeat-area transfer mode.
Convenience wrapper that forces cfg->mode = k_ra8_dmac_mode_repeat before delegating to ra8_dmac_start(). In repeat mode the controller automatically rewinds either DMSAR or DMDAR (per cfg->repeat_area) every cfg->count transfers, so ring buffers and double-buffered framebuffers can be expressed without software intervention. HUM 17.2.10 p 738 (DMTMD.MD = 01b).
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | cfg | Transfer descriptor; mode is ignored. |
| k_ra8_ok | Channel armed in repeat mode. |
| k_ra8_err_null_ptr | cfg is NULL. |
| k_ra8_err_out_of_range | channel >= 8. |
| k_ra8_err_invalid_arg | cfg->width invalid. |
Definition at line 478 of file ra8_dmac.c.
References internal_start_with_mode(), and k_ra8_dmac_mode_repeat.
|
nodiscard |
Disable a DMAC0 channel and drop its MSTP reference.
| [in] | channel | DMAC0 channel index 0..7. |
| k_ra8_ok | Channel disabled. |
| k_ra8_err_out_of_range | channel >= 8. |
Definition at line 432 of file ra8_dmac.c.
References r_dmac_channel_regs_t::DMCNT, k_ra8_err_out_of_range, k_ra8_mstp_dmac0_dtc0, ra8_dmac(), and ra8_mstp_disable().
Referenced by internal_run_copy(), internal_unwind_tx_dma(), ra8_dma_deinit(), ra8_dma_release(), and ra8_ssie_detach_dma().
|
nodiscard |
Spin until a DMAC0 channel goes idle or a poll bound expires.
Polls DMSTS.ACT (HUM Ch 17.2.16 "DMSTS : DMAC Status Register" p 745) up to poll_limit times, returning as soon as the bit reads 0 (transfer complete). This is the synchronous completion gate the fire-and-wait DMA demos use after ra8_dmac_software_trigger: a block-mode copy holds ACT asserted for the duration of the block and clears it at completion.
The poll loop is statically bounded by poll_limit (NASA P10 Rule 2); a poll_limit of 0 performs no read and reports a timeout. Choose the bound for the expected transfer length at the current bus clock.
| [in] | channel | DMAC0 channel index 0..7. |
| [in] | poll_limit | Maximum number of DMSTS.ACT reads before giving up. |
| k_ra8_ok | Channel reached idle (ACT = 0). |
| k_ra8_err_hw_timeout | poll_limit exhausted, ACT still 1. |
| k_ra8_err_out_of_range | channel >= 8. |
Definition at line 588 of file ra8_dmac.c.
References r_dmac_channel_regs_t::DMSTS, k_ra8_dmsts_act_mask, k_ra8_err_hw_timeout, k_ra8_err_out_of_range, k_ra8_ok, and ra8_dmac().
Referenced by internal_run_copy().