|
| fsp_err_t | R_DMAC_W_Open (transfer_ctrl_t *const p_api_ctrl, transfer_cfg_t const *const p_cfg) |
| |
| fsp_err_t | R_DMAC_W_Reconfigure (transfer_ctrl_t *const p_api_ctrl, transfer_info_t *p_info) |
| |
| fsp_err_t | R_DMAC_W_Reset (transfer_ctrl_t *const p_api_ctrl, void const *volatile p_src, void *volatile p_dest, uint16_t const num_transfers) |
| |
| fsp_err_t | R_DMAC_W_SoftwareStart (transfer_ctrl_t *const p_api_ctrl, transfer_start_mode_t mode) |
| |
| fsp_err_t | R_DMAC_W_SoftwareStop (transfer_ctrl_t *const p_api_ctrl) |
| |
| fsp_err_t | R_DMAC_W_Enable (transfer_ctrl_t *const p_api_ctrl) |
| |
| fsp_err_t | R_DMAC_W_Disable (transfer_ctrl_t *const p_api_ctrl) |
| |
| fsp_err_t | R_DMAC_W_InfoGet (transfer_ctrl_t *const p_api_ctrl, transfer_properties_t *const p_info) |
| |
| fsp_err_t | R_DMAC_W_Reload (transfer_ctrl_t *const p_api_ctrl, void const *p_src, void *p_dest, uint32_t const num_transfers) |
| |
| fsp_err_t | R_DMAC_W_CallbackSet (transfer_ctrl_t *const p_api_ctrl, void(*p_callback)(dmac_callback_args_t *), void *const p_context, dmac_callback_args_t *const p_callback_memory) |
| |
| fsp_err_t | R_DMAC_W_Close (transfer_ctrl_t *const p_api_ctrl) |
| |
| fsp_err_t | R_DMAC_W_Freeze (bool freeze) |
| |
Driver for the DMAC peripheral on RA6W1/RA6W2 MCUs. This module implements the Transfer Interface.
Overview
The Direct Memory Access Controller (DMAC) transfers data from peripheral to memory location, from memory location to peripheral or from one memory location to another without using the CPU.
Features
- Supports multiple transfer modes
- Normal transfer
- Repeat transfer
- Address increment or fixed modes
- Triggered by predefined DMA triggers
- Supports 1, 2, and 4 byte data units
Configuration
Build Time Configurations for r_dmac_w
The following build time configurations are defined in fsp_cfg/r_dmac_w_cfg.h:
| Configuration | Options | Default | Description |
| Parameter Checking |
-
Default (BSP)
-
Enabled
-
Disabled
| Default (BSP) | If selected code for parameter checking is included in the build. |
Configurations for Transfer > Transfer (r_dmac_w)
This module can be added to the Stacks tab via New Stack > Transfer > Transfer (r_dmac_w).
| Configuration | Options | Default | Description |
| Name | Name must be a valid C symbol | g_transfer0 | Module name. |
| Channel | Value must be a non-negative integer | 0 | Specify the hardware channel. |
| Mode | MCU Specific Options | | Select the transfer mode. Normal: One transfer per activation, transfer ends after Number of Transfers; Repeat: One transfer per activation, Repeat Area address reset after Number of Transfers. |
| Transfer Size |
| 2 Bytes | Select the transfer size. |
| Destination Address Mode |
| Fixed | Select the address mode for the destination. |
| Source Address Mode |
| Fixed | Select the address mode for the source. |
| Number of Transfers | 'Number of Transfers' must be a valid non negative integer between 1 and 65535. | 1 | Specify the number of transfers for repeat and normal mode. |
| Number of Transfers to interrupt | Value must be a non-negative integer | 0 | Specify the number of transfers before DMA interrupt generation (0 to fire IRQ after transfer ends). |
| Activation Source | MCU Specific Options | | Select the DMAC transfer start event. |
| Callback | Name must be a valid C symbol | NULL | A user callback that is called at the end of the transfer. |
| Transfer End Interrupt Priority | MCU Specific Options | | Select the transfer end interrupt priority. |
| Start mode |
-
Start immediately
-
On peripheral request
| Start immediately | Select whether DMA starts immediately, or waits for a trigger from HW. |
| DMA idle mode |
-
Blocking mode
-
Interrupting mode
| Blocking mode | Select whether DMA blocks the bus during the transfer or allow CPU/cache activities on the bus during the transfer (relevant only for 'Request mode'='Start immediately'). |
| DMA init mode |
-
A1 to B1, A2 to B2
-
A1 to B1, B2
| A1 to B1, A2 to B2 | Select how DMA performs memory initialization (relevant only for 'Request mode'='Start immediately'). |
| DMA read/write bursts |
| Disabled | Set the DMA read/write bursts value for DMAC. The bursts are not used if 'Number of Transfers' are not multiple of 4 or 8 respectively. |
| DMA channel priority | 'DMA channel priority' must be integer from '0' (Lowest) up to '7' (Highest). | 0 | Select the priority of DMA channel to determine which DMA channel will be activated in case more than one DMA channel requests DMA (0 - Lowest, 7 - Highest). |
Clock Configuration
The DMAC peripheral module uses SYS_CLK as the clock source. The SYS_CLK frequency is set by using the Clocks tab of the RA6W1/RA6W2 Configuration editor prior to a build, or by using the CGC module at run-time.
Pin Configuration
This module does not use I/O pins.
Usage Notes
Transfer Modes
The DMAC Module supports two modes of operation.
- Normal Mode - In normal mode, a single data unit is transferred every time the configured trigger event is received by the DMAC channel. A data unit can be 1-byte, 2-bytes, or 4-bytes. The source and destination addresses can be fixed or incremented to the next data unit after each transfer operation. A 16-bit counter increments after each transfer operation. The channel can be configured in a way the CPU can be interrupted to signalize the desired amount of data was transferred (by default when all the data was transferred). When the counter reaches the desired length, transfers will no longer be triggered by the trigger event.
- Repeat Mode - Repeat mode works the same way as normal mode. But, when the transfer operation counter reaches the desired length, the counter is reset back to 0, the repeat area (source or/and destination address) resets to its starting address and the transfer continues. The channel can be configured in a way the CPU can be interrupted to signalize the desired amount of data was transferred (by default, the CPU is interrupted when one repeat cycle was performed).
DMAC Features
Init Mode
DMAC can perform efficient memory initialization in the case of transfer triggered by the software. It can populate destination buffer with the content of the source buffer using one of the two modes:
- A1 to B1, A2 to B2 - transfers the content of source buffer to destination buffer;
- A1 to B1, B2 - populates the destination buffer with the content of the first data unit (reading from A1 is performed only one time).
DMAC Idle Operation
DMAC can work in a two different operation modes:
- Blocking mode - DMAC blocks the bus for any lower priority DMAC operations / CPU interruptions to performs a fast back-to-back copy (for transfer triggered by a software);
- Interrupting mode - DMAC inserts a wait cycle after each store allowing the CPU to steal cycles or cache to perform a burst read.
DMAC Channel Prioritization
DMAC channel access to the bus can be prioritized. The priority level determines which DMA channel will be granted access for transferring data, in case more than one channels are active and request the bus at the same time. The greater the value, the higher the priority.
Bursts Transfers
DMAC can perform transfer operations with bursts of 4 or 8 data units simultaneously (the buffer length in those cases should be multiple of 4 or 8 data units respectively).
Freezing of DMAC operations
The DMA controller can be frozen. The API call to freeze suspends the activity on every DMA channel until DMAC is unfrozen by the corresponding API call to unfreeze it.
Selecting the DTC or DMAC
The Transfer API is implemented by both DTC (on some MCUs) and the DMAC, so that applications can switch between the DTC and the DMAC. When selecting between them, consider these factors:
| DTC | DMAC |
| Repeat Mode |
-
Repeats forever
-
Max repeat size is 256 x 4 bytes
|
-
Repeats forever (applicable only for transactions involving peripherals)
-
Max repeat size is 65535 x 4 bytes
|
| Block Mode |
-
Max transfer size is 256 x 4 bytes
|
|
| Normal Mode |
-
Max transfer size is 65535 x 4 bytes
|
-
Max transfer size is 65535 x 4 bytes
|
| Channels |
-
One instance per interrupt
|
-
MCU specific (16 channels or less)
|
| Chained Transfers |
|
|
| Software Trigger |
-
Must use the software ELC event
|
-
Has support of software trigger without peripheral HW involvement
-
Supports only TRANSFER_START_MODE_SINGLE
|
Interrupts
The DTC and DMAC interrupts behave differently. The DTC uses the configured IELSR event IRQ as the interrupt source whereas each DMAC channel has its own IRQ (one IRQn is shared between channels on some MCUs).
The transfer_info_t::irq is not used on DMAC, as DMAC provides more flexible way of interrupt generation depending on the transfer operation counter.
Additional Considerations
- The DTC requires a moderate amount of RAM (one transfer_info_t struct per open instance + DTC_VECTOR_TABLE_SIZE).
- The DTC stores transfer information in RAM and writes back to RAM after each transfer whereas the DMAC stores all transfer information in registers.
- When transfers are configured for more than one activation source, the DTC must fetch the transfer info from RAM on each interrupt. This can cause a higher latency between transfers.
Normal Mode
| DTC | DMAC |
| TRANSFER_IRQ_EACH | Interrupt after each transfer | N/A (has IRQ generation based on transfer counter) |
| TRANSFER_IRQ_END | Interrupt after last transfer | N/A (has IRQ generation based on transfer counter) |
Repeat Mode
| DTC | DMAC |
| TRANSFER_IRQ_EACH | Interrupt after each transfer | N/A (has IRQ generation based on transfer counter) |
| TRANSFER_IRQ_END | Interrupt after each repeat | N/A (has IRQ generation based on transfer counter) |
Block Mode
| DTC | DMAC |
| TRANSFER_IRQ_EACH | Interrupt after each block | N/A (has IRQ generation based on transfer counter) |
| TRANSFER_IRQ_END | Interrupt after last block | N/A (has IRQ generation based on transfer counter) |
- Note
- DTC_VECTOR_TABLE_SIZE = (ICU_NVIC_IRQ_SOURCES x 4) Bytes
Examples
Basic Example
This is a basic example of minimal use of the DMAC in an application. In this case, one or more events have been routed to the DMAC for handling so it only needs to be enabled to start accepting transfers.
#include "r_dmac_w.h"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#define TRANSFER_LENGTH (16U)
#define BSP_VECTOR_DMAC_0 ((IRQn_Type) 0)
int dmac_main(void);
void dmac_minimal_example(void);
void dmac_freeze_example(void);
dmac_instance_ctrl_t g_transfer_ctrl;
volatile bool g_transfer_complete = false;
{
.length = TRANSFER_LENGTH / 4,
.p_dest = NULL,
.p_src = NULL,
};
{
.irq = BSP_VECTOR_DMAC_0,
.ipl = 0,
.p_callback = dmac_callback,
};
{
.p_extend = &dmac_cfg,
};
void dmac_minimal_example (void)
{
assert(FSP_SUCCESS == err);
assert(FSP_SUCCESS == err);
while (!g_transfer_complete)
{
}
}
void dmac_freeze_example (void)
{
assert(FSP_SUCCESS == err);
assert(FSP_SUCCESS == err);
assert(FSP_SUCCESS == err);
assert(FSP_SUCCESS == err);
}
{
g_transfer_complete = true;
}
int dmac_main (void)
{
dmac_minimal_example();
assert(FSP_SUCCESS == err);
dmac_freeze_example();
return 0;
}
◆ dmac_extended_cfg_t
| struct dmac_extended_cfg_t |
DMAC transfer configuration extension. This extension is required.
◆ irq_num_of_trans
| uint16_t dmac_extended_cfg_t::irq_num_of_trans |
Number of transfers before IRQ generation. Set to 0 to fire IRQ after transfer ends.
◆ p_callback
Callback for transfer end interrupt.
◆ p_context
| void* dmac_extended_cfg_t::p_context |
◆ DMAC_MAX_NORMAL_TRANSFER_LENGTH
| #define DMAC_MAX_NORMAL_TRANSFER_LENGTH |
Max configurable number of transfers in TRANSFER_MODE_NORMAL.
◆ dmac_callback_args_t
Callback function parameter data.
◆ dmac_start_mode_t
DMAC channel start mode
| Enumerator |
|---|
| DMAC_START_IMMEDIATELY | DMAC channel starts immediately.
|
| DMAC_START_ON_PERIPHERAL_REQUEST | DMAC channel must be triggered by a peripheral DMA request.
|
◆ dmac_burst_mode_t
DMAC channel burst mode
| Enumerator |
|---|
| DMAC_BURST_MODE_DISABLED | DMAC burst mode is disabled
|
| DMAC_BURST_MODE_4x | DMAC burst mode enabled, burst size of 4 data units is used
|
| DMAC_BURST_MODE_8x | DMAC burst mode enabled, burst size of 8 data units is used
|
◆ dmac_idle_mode_t
DMA idle mode
In blocking mode the DMA performs a fast back-to-back copy, disabling bus access for any bus master with lower priority. In interrupting mode the DMAC inserts a wait cycle after each store allowing other bus masters to perform a burst read.
| Enumerator |
|---|
| DMAC_IDLE_BLOCKING_MODE | Blocking mode.
|
| DMAC_IDLE_INTERRUPTING_MODE | Interrupting mode.
|
◆ dmac_init_mode_t
| Enumerator |
|---|
| DMAC_INIT_AX_BX_AY_BY | DMA performs copy A1 to B1, A2 to B2
|
| DMAC_INIT_AX_BX_BY | DMA performs copy A1 to B1, B2
|
◆ R_DMAC_W_Open()
Configure a DMAC channel.
Example:
- Return values
-
| FSP_SUCCESS | Successful open. |
| FSP_ERR_ASSERTION | An input parameter is invalid. |
| FSP_ERR_IP_CHANNEL_NOT_PRESENT | The configured channel is invalid. |
| FSP_ERR_IRQ_BSP_DISABLED | The IRQ associated with the activation source is not enabled in the BSP. |
| FSP_ERR_ALREADY_OPEN | The control structure is already opened. |
| FSP_ERR_UNSUPPORTED | A Selected setting is not supported by this API. |
◆ R_DMAC_W_Reconfigure()
Reconfigure the transfer with new transfer info.
- Return values
-
| FSP_SUCCESS | Transfer is configured and will start when R_DMAC_W_Enable() is called. |
| FSP_ERR_ASSERTION | An input parameter is invalid. |
| FSP_ERR_UNSUPPORTED | A Selected setting is not supported by this API. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. |
◆ R_DMAC_W_Reset()
| fsp_err_t R_DMAC_W_Reset |
( |
transfer_ctrl_t *const |
p_api_ctrl, |
|
|
void const *volatile |
p_src, |
|
|
void *volatile |
p_dest, |
|
|
uint16_t const |
num_transfers |
|
) |
| |
Reset transfer source and destination.
- Return values
-
| FSP_ERR_UNSUPPORTED | This feature is not supported. |
◆ R_DMAC_W_SoftwareStart()
If the mode is TRANSFER_START_MODE_SINGLE initiate a single transfer with software. If the mode is TRANSFER_START_MODE_REPEAT continue triggering transfers until all of the transfers are completed.
- Return values
-
| FSP_ERR_UNSUPPORTED | This feature is not supported. |
◆ R_DMAC_W_SoftwareStop()
Stop software transfers if they were started with TRANSFER_START_MODE_REPEAT.
- Return values
-
| FSP_ERR_UNSUPPORTED | This feature is not supported. |
◆ R_DMAC_W_Enable()
Enable a DMAC channel.
Example:
- Return values
-
| FSP_SUCCESS | DMAC channel activated successfully. |
| FSP_ERR_ASSERTION | An input parameter is invalid. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. |
◆ R_DMAC_W_Disable()
Disable a Dmac channel.
- Return values
-
| FSP_SUCCESS | DMAC channel disabled successfully. |
| FSP_ERR_ASSERTION | An input parameter is invalid. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. |
◆ R_DMAC_W_InfoGet()
Set driver specific information in provided pointer.
- Return values
-
| FSP_SUCCESS | Information has been written to p_info. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. |
| FSP_ERR_ASSERTION | An input parameter is invalid. |
◆ R_DMAC_W_Reload()
| fsp_err_t R_DMAC_W_Reload |
( |
transfer_ctrl_t *const |
p_api_ctrl, |
|
|
void const * |
p_src, |
|
|
void * |
p_dest, |
|
|
uint32_t const |
num_transfers |
|
) |
| |
To update next transfer information without interruption during transfer.
- Return values
-
| FSP_ERR_UNSUPPORTED | This feature is not supported. |
◆ R_DMAC_W_CallbackSet()
Updates the user callback with the option to provide memory for the callback argument structure.
- Return values
-
| FSP_SUCCESS | Callback updated successfully. |
| FSP_ERR_ASSERTION | A required pointer is NULL. |
| FSP_ERR_NOT_OPEN | The control block has not been opened. |
| FSP_ERR_IRQ_BSP_DISABLED | The IRQ associated with the activation source is not enabled in the BSP. |
◆ R_DMAC_W_Close()
Disable transfer and clean up internal data. Implements transfer_api_t::close.
- Return values
-
| FSP_SUCCESS | Successful close. |
| FSP_ERR_ASSERTION | An input parameter is invalid. |
| FSP_ERR_NOT_OPEN | Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. |
◆ R_DMAC_W_Freeze()
Temporarily freeze/unfreeze all channels of the DMAC controller.
Example:
assert(FSP_SUCCESS == err);
- Return values
-
| FSP_SUCCESS | Successful freeze. |