Driver for the DTC peripheral on RA MCUs. This module implements the Transfer Interface.
Overview
The Data Transfer Controller (DTC) transfers data from one memory location to another without using the CPU.
The DTC uses a RAM based vector table. Each entry in the vector table corresponds to an entry in the ISR vector table. When the DTC is triggered by an interrupt, it reads the DTC vector table, fetches the transfer information, and then executes the transfer. After the transfer is executed, the DTC writes the updated transfer info back to the location pointed to by the DTC vector table.
Features
Supports multiple transfer modes
Normal transfer
Repeat transfer
Block transfer
Chain transfers
Address increment, decrement or fixed modes
Can be triggered by any event that has reserved a slot in the interrupt vector table.
Some exceptions apply, see the Event table in the Event Numbers section of the Interrupt Controller Unit chapter of the hardware manual
Supports 1, 2, and 4 byte data units
Configuration
Build Time Configurations for r_dtc
The following build time configurations are defined in fsp_cfg/r_dtc_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.
Linker section to keep DTC vector table
Manual Entry
.fsp_dtc_vector_table
Section to place the DTC vector table.
Configurations for Transfer > Transfer (r_dtc)
This module can be added to the Stacks tab via New Stack > Transfer > Transfer (r_dtc).
Configuration
Options
Default
Description
Name
Name must be a valid C symbol
g_transfer0
Module name.
Mode
Normal
Repeat
Block
Normal
Select the transfer mode. 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 repeats until stopped; Block: Number of Blocks per activation, Repeat Area address reset after Number of Transfers, transfer ends after Number of Blocks.
Transfer Size
1 Byte
2 Bytes
4 Bytes
2 Bytes
Select the transfer size.
Destination Address Mode
Fixed
Incremented
Decremented
Fixed
Select the address mode for the destination.
Source Address Mode
Fixed
Incremented
Decremented
Fixed
Select the address mode for the source.
Repeat Area (Unused in Normal Mode)
Destination
Source
Source
Select the repeat area. Either the source or destination address resets to its initial value after completing Number of Transfers in Repeat or Block mode.
Interrupt Frequency
After all transfers have completed
After each transfer
After all transfers have completed
Select to have interrupt after each transfer or after last transfer.
Number of Transfers
Value must be a non-negative integer
0
Specify the number of transfers.
Number of Blocks (Valid only in Block Mode)
Must be a valid non-negative integer with a maximum configurable value of 65536. Applicable only in Block Mode.
0
Specify the number of blocks to transfer in Block mode.
Number of Transfer Descriptors
Value must be a non-negative integer
1
Specify the number of transfer descriptors. Users have to initialize descriptors if its value is greater than 1.
Activation Source
MCU Specific Options
Select the DTC transfer start event.
Clock Configuration
The DTC peripheral module uses ICLK as the clock source. The ICLK frequency is set by using the Clocks tab of the RA Configuration editor prior to a build or by using the CGC module at runtime.
Pin Configuration
This module does not use I/O pins.
Usage Notes
Source and Destination Configuration
R_DTC_Reset() API function should be called to set the Source and Destination address before starting the transfer operation.
Transfer Modes
The DTC Module supports three modes of operation.
Normal Mode - In normal mode, a single data unit is transfered every time an interrupt is received by the DTC. A data unit can be 1-byte, 2-bytes, or 4-bytes. The source and destination addresses can be fixed, increment or decrement to the next data unit after each transfer. A 16-bit counter (length) decrements after each transfer. When the counter reaches 0, transfers will no longer be triggered by the interrupt source and the CPU can be interrupted to signal that all transfers have finished.
Repeat Mode - Repeat mode works the same way as normal mode, however the length is limited to an integer in the range[1,256]. When the tranfer counter reaches 0, the counter is reset to its configured value and the repeat area (source or destination address) resets to its starting address and transfers will still be triggered by the interrupt.
Block Mode - In block mode, the amount of data units transfered by each interrupt can be set to an integer in the range [1,256]. The number of blocks to transfer can also be configured to a 16-bit number. After each block transfer the repeat area (source or destination address) will reset to the original address and the other address will be incremented or decremented to the next block.
Note
1. The source and destination address of the transfer must be aligned to the configured data unit.
2. In normal mode the length can be set to [0,65535]. When the length is set to 0, than the transaction will execute 65536 transfers not 0.
3. In block mode, num_blocks can be set to [0,65535]. When the length is set to 0, than the transaction will execute 65536 transfers not 0.
Chaining Transfers
Multiple transfers can be configured for the same interrupt source by specifying an array of transfer_info_t structs instead of just passing a pointer to one. In this configuration, every transfer_info_t struct must be configured for a chain mode except for the last one. There are two types of chain mode; CHAIN_MODE_EACH and CHAIN_MODE_END. If a transfer is configured in CHAIN_MODE_EACH then it triggers the next transfer in the chain after it completes each transfer. If a transfer is configured in CHAIN_MODE_END then it triggers the next transfer in the chain after it completes its last transfer.
DTC Transfer Flowchart
Selecting the DTC or DMAC
The Transfer API is implemented by both DTC 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
Configurable number of repeats
Max repeat size is 1024 x 4 bytes
Block Mode
Max block size is 256 x 4 bytes
Max block size is 1024 x 4 bytes
Channels
One instance per interrupt
MCU specific (8 channels or less)
Chained Transfers
Supported
Not Supported
Software Trigger
Must use the software ELC event
Has support for software trigger without using software ELC event
Supports TRANSFER_START_MODE_SINGLE and TRANSFER_START_MODE_REPEAT
Offset Address Mode
Not supported
Supported
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.
The DTC interrupts the CPU using the activation source's IRQ. Each DMAC channel has its own IRQ.
The necessary alignment of the transfer_info_t structs depends on the underlying MCU. The DTC_TRANSFER_INFO_ALIGNMENT macro is supplied to align the structs as necessary.
Interrupts
The DTC and DMAC interrupts behave differently. The DTC uses the configured event IRQ as the interrupt source whereas each DMAC channel has its own IRQ.
The transfer_info_t::irq setting also behaves a little differently depending on which mode is selected.
Normal Mode
DTC
DMAC
TRANSFER_IRQ_EACH
Interrupt after each transfer
N/A
TRANSFER_IRQ_END
Interrupt after last transfer
Interrupt after last transfer
Repeat Mode
DTC
DMAC
TRANSFER_IRQ_EACH
Interrupt after each transfer
Interrupt after each repeat
TRANSFER_IRQ_END
Interrupt after each repeat
Interrupt after last transfer
Block Mode
DTC
DMAC
TRANSFER_IRQ_EACH
Interrupt after each block
Interrupt after each block
TRANSFER_IRQ_END
Interrupt after last block
Interrupt after last block
Note
DTC_VECTOR_TABLE_SIZE = (ICU_NVIC_IRQ_SOURCES x 4) Bytes
Peripheral Interrupts and DTC
When an interrupt is configured to trigger DTC transfers, the peripheral ISR will trigger on the following conditions:
Each transfer completed (transfer_info_t::irq = TRANSFER_IRQ_EACH)
Last transfer completed (transfer_info_t::irq = TRANSFER_IRQ_END)
For example, if SCI1_RXI is configured to trigger DTC transfers and a SCI1_RXI event occurs, the interrupt will not fire until the DTC transfer is completed. If the DTC transfer_info_t::irq is configured to only interrupt on the last transfer, then no RXI interrupts will occur until the last transfer is completed.
Note
1. The DTC activation source must be enabled in the NVIC in order to trigger DTC transfers (Modules that are designed to integrate the R_DTC module will automatically handle this).
2. The DTC prioritizes activation sources by granting the smaller interrupt vector numbers higher priority. The priority of interrupts to the CPU is determined by the NVIC priority.
Low Power Modes
DTCST must be set to 0 before transitioning to any of the following:
Module-stop state
Software Standby mode without Snooze mode transition
Deep Software Standby mode
Note
1. R_LPM Module stops the DTC before entering deep software standby mode and software standby without snooze mode transition.
2. For more information see 18.9 and 18.10 in the RA6M3 manual R01UH0886EJ0100.
Limitations
Developers should be aware of the following limitations when using the DTC:
If the DTC is configured to service many different activation sources, the system could run in to performance issues due to memory contention. To address this issue, it is reccomended that the DTC vector table and transfer information be moved to their own dedicated memory area (Ex: SRAM0, SRAM1, SRAMHS). This allows memory accesses from different BUS Masters (CPU, DTC, DMAC, EDMAC and Graphics IPs) to occur in parallel.
Examples
Basic Example
This is a basic example of minimal use of the DTC in an application.
void dtc_minimal_example (void)
{
/* Open the transfer instance with initial configuration. */
Configure the vector table if it hasn't been configured, enable the Module and copy the pointer to the transfer info into the DTC vector table. Implements transfer_api_t::open.
Example:
/* Open the transfer instance with initial configuration. */