Using DTC??

I'd like to see if the DTC can speed up the DAC timing.  The manual says that the DTCVBR has to point to an address which is modulo 4k (i.e. xxxxx000H) for the set up data.  I can't quite figure out how to do that with #pragma section.  There are no DTC RPDL commands.  If I create an assembler file with a .org directive, how do I ensure the linker will honor the absolute value?

Any example on the use of the DTC would be appreciated too.


Mike Rosing

  • Mike,

    RPDL has a number of functions that support the Data Transfer Controller (DTC):






    RPDL sets the DTCVBR register for you.

    There is a DTC example included in the YRDK Project Generator; it transfers data from the ADC to a memory buffer.

    For details on using the Project Generator, see the manual here:


  • Thanks John!

    I will definitely go check that out.  I found something interesting looking at the tutorial code - the #pragma address command.  I figured out how to set up a fixed address, and by using the map file I figured out how to move it to a place that would not get cobbered by everything else.

    The API manual has no entry for the DTC section other than a place holder.  I think I've figured out how to set the registers, but if the rpdl works I won't have to debug my mistakes.  With luck I'll have this up and running with DTC before the day is over.


  • Mike,

    Latest version of the RPDL manual is here:

    Look in Chapter 4 for the actual calls (earlier chapters just have brief descriptions).


  • Thanks!

    I guess I missed it the first time because of that.  A full search found all the info.  I got my code to compile at least - I'll see how well I understand the registers in a few minutes!

    If not, I can cut it all out and replace it with the RPDL.  Sometimes the order of setting registers can be a major pain, so having the RPDL take care of that for me is a major savings in headaches.


  • I finally got the DTC to send data to the dac at the rate I wanted.  Along the way I got the processor so screwed up the debugger couldn't talk to it any more!  The order of calls does matter and having the periferal demo code to look at helped a lot.  All I have to do now is give the DTC the correct data so my wave forms look right.

    Thanks the help John!

    Mike Rosing

  • In reply to Mike Rosing:

    Mike,  I am attempting to do exactly what you have done, without RPDL.  Can you give me some specific advice on how to set up?  Especially in creating the section for the interrupt vector.



    To give some specifics.  I am developing an RX631 on e2studio with the KPIT RX compiler.

  • In reply to Lane Mitcham:

    Here's a gist of how you'd do it using CCRX. Hope it helps. I believe there's a video on the e-learning website on the DTC. Cheers.

    /** Definition of DTC Transfer Control Block. */ #pragma bit_order left #pragma unpack typedef union dtc_mra { uint8_t BYTE; struct { uint8_t MD:2; /* b7,b6: DTC Transfer Mode Select */ uint8_t SZ:2; /* DTC Data Transfer Size */ uint8_t SM:2; /* Transfer Source Address Addressing Mode */ uint8_t rs:2; /* reserved */ } BIT; } dtc_mra_t; /* The DTC Mode Register B (MRB) structure */ typedef union dtc_mrb { uint8_t BYTE; struct { uint8_t CHNE :1; /* b7: DTC Chain Transfer Enable */ uint8_t CHNS :1; /* DTC Chain Transfer Select */ uint8_t DISEL:1; /* DTC Interrupt Select */ uint8_t DTS :1; /* DTC Transfer Mode Select */ uint8_t DM :2; /* Transfer Destination Address Addressing Mode */ uint8_t rs :2; /* reserved */ } BIT; } dtc_mrb_t; /* The DTC Transfer Count Register A (CRA) structure */ typedef union dtc_cra { uint16_t WORD; struct { #if (__BIG) ||(__RX_BIG_ENDIAN__) /* Big-Endian */ uint8_t CRA_H; uint8_t CRA_L; #else /* little endian */ uint8_t CRA_L; uint8_t CRA_H; #endif } BYTE; } dtc_cra_t; /* The DTC Transfer Count Register B (CRB) structure */ typedef union dtc_crb { uint16_t WORD; } dtc_crb_t; typedef struct st_dtc_full_transfer_data { union { uint32_t LWORD; struct { #if (__BIG) ||(__RX_BIG_ENDIAN__) /* Big-Endian */ dtc_mra_t MRA; dtc_mrb_t MRB; uint16_t reserver; /* reserve area */ #else /* Little-Endian */ uint16_t reserver; /* reserve area */ dtc_mrb_t MRB; dtc_mra_t MRA; #endif /* (DTC_BIG_ENDIAN) */ } REG; } FIRST_LWORD; union { uint32_t SAR; } SECOND_LWORD; union { uint32_t DAR; } THIRD_LWORD; union { uint32_t LWORD; struct { #if (__BIG) ||(__RX_BIG_ENDIAN__) /* Big-Endian */ dtc_cra_t CRA; dtc_crb_t CRB; #else /* Little-Endian */ dtc_crb_t CRB; dtc_cra_t CRA; #endif /* (DTC_BIG_ENDIAN) */ } REG; } FOURTH_LWORD; } dtc_tcb_registers_t; #pragma bit_order #pragma packoption

    	/** Enable CTSU interrupt operation. */

    	/* Use the DTC to move data when Peripheral interrupt occurs */
    dtc_tcb_registers_t peripheral_irq_tcb;    //Keep as a global variable 

    /* Initialize DTC Transfer Control Block as per your needs. */

    /* Put the TCB in the DTC vector table */
    		uint32_t* dtc_base_address = (uint32_t*)DTC.DTCVBR; //Must be on a 1k boundary since there are 256 x 4 bytes of DTC vectors.
    		/* Set the DTC vectors to point to the right locations */
    dtc_base_address[IR_PERIPHERAL_IRQ] = (uint32_t) &peripheral_irq_tcb;
    /* Enable DTC operation (Don't forget the MSTP bit) */

    DTC.DTCST.BIT.DTCST = false;

    (uint32_t)DTC.DTCVBR = 0x00003C00;

    memset((void*)DTC.DTCVBR, 0, 1024);

    DTC.DTCCR.BIT.RRS = true;

  • This thread will be archived due to inactivity.

    Mike Clements
    RenesasRulz Moderator