FTM Mode "Enable DMA" K60

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FTM Mode "Enable DMA" K60

2,410 Views
kenrenjen
Contributor III

Hi

I'm working on a K60 MCU and I have tried to use DMA along with a flextimer.

I can see in the manual that the mode for the flextimer can be set to enable DMA. Nothing else is mentioned about this using flextimers.

I've tried several guides and examples, but they are hard to understand.

I have no clue how to implement DMA, but I understand the principles. Is there a very basic example out there, where for instance when an rising edge occur the value of the counter can be transferred by DMA? Or can anyone take me through step-by-step how to implement it.

In my head, when the K60 offers the opportunity to enable DMA for flextimer by a single bit, it shouldn't be so hard to setup as the DMA-ADC example.

I'm using uTasker and I posted my code beneath. I hope someone can help me out, I've been stuck to this for weeks now.

Thanks in advance.

void ftm_init(void)

{

  POWER_UP(6, SIM_SCGC6_FTM0); // Enable clock

  PORTC_PCR1 = PC_1_FTM0_CH0; // Multiplexer (MUX) for flextimer (FTM) initialized to port FTM0 and channel 0  (route the desired signal to the pin)

  FTM0_MODE = (FTM_MODE_WPDIS | FTM_MODE_FTMEN); // Disable write protection

  FTM0_CONF = FTM_CONF_BDMMODE_3; // FTM_DEBUG_BEHAVIOUR: Allow timer to continue operating when debugging 

  FTM0_COMBINE = ( FTM_COMBINE_COMBINE0 | FTM_COMBINE_DECAPEN0 | FTM_COMBINE_DECAP0 ); // Channels combined, Dual edge capture enabled and activated.

  FTM0_CNTIN = 0x0000; // Counter initial value

  FTM0_MOD = 0xFFFF; // Modulo to max

  // Capture set to rising edge (ELSB:ELSA = 0:1) and Mode set to continious (MSA:MSB = 1:0) on both channels

  FTM0_C0SC = (FTM_CSC_ELSA | FTM_CSC_MSA | FTM_CSC_DMA);

  FTM0_C1SC = (FTM_CSC_ELSA | FTM_CSC_MSA | FTM_CSC_DMA | FTM_CSC_CHIE); 

  FTM0_SC = (FTM_SC_CLKS_SYS | FTM_SC_PS_1 | FTM_SC_TOIE); // Sets the source to system clock and define the prescalar. Timer overflow interrupt enabled (1)

  fnEnterInterrupt(irq_FTM0_ID, PRIORITY_HW_TIMER, ftm0_isr); //Configure and enter the ftm0 handling interrupt routine in the vector table

}

Labels (1)
0 Kudos
Reply
6 Replies

1,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Jensen Kenneth,

      We don't have the example about FTM with DMA based on K60, but I think, in you code,if you want to use FTM DMA transfer, you not only need to enable FTMx_CnSC[DMA], but also you need to configure the DMA MUX and DMA controller module.

      1, you should to configure the DMA MUX to choose the request source, eg, you configure DMAMUX_CHCFGn, enable DMA channel by bit [ENBL] ,choose DMA Channel Source by register[SOURECE], you can find the request source from according reference manual,souce number=24 is FTM0 channel0.

     2, you should to configure DMA controller, details you can find in reference manual.

     3,enable the FTM channel DMA by FTMX_CnSC[DMA].

     Actually, in the Kinetis Peripheral Module Quick Reference,there has a chapter to describe how to configure DMA and the steps.

the Kinetis Peripheral Module Quick Reference:

       http://cache.freescale.com/files/32bit/doc/quick_ref_guide/KQRUG.pdf?fpsp=1&WT_TYPE=Quick Reference Guides&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation

You can refer to the chapter 7:enhanced direct memory access controller.    7.1.4 Configuration steps.

Wish it helps you!

Best regards!

Jing

1,009 Views
kenrenjen
Contributor III

Hi Jing

Thank you for your reply. I was wondering if it is possible to trigger the DMA channel whenever a timer overflow has appeared to count the number of overflows.

The reason for this is that I will eleminate number of ISR request, becouse I have two interrupts in the same routine, channel and overflow.

I was thinking that it would be the most efficient solution instead of trigger DMA whenever a channel interrupt appears.

Thanks Again.

Kenneth

0 Kudos
Reply

1,009 Views
DavidS
NXP Employee
NXP Employee

Hi Kenneth,

The FTM can generate an interrupt on overflow per the Reference Manual for K60:

The generation of an interrupt when the counter overflows

The FTMx_SC[TOIE] bit does this.

Or you could set the MOD register to 0xFFFF.

The code attached can play with FTM in Polled or Interrupt mode and you can set the MOD to whatever you want.

Just place it in the following path to play with:

C:\Freescale\Freescale_MQX_4_0_2_GA\mqx\examples\timer

Regards,

David

0 Kudos
Reply

1,009 Views
kenrenjen
Contributor III

Hi David

Thanks for you reply. I think you misunderstood my problem. I know that the timer can generate an interrupt by setting the TOF..

What I want is to eleminate numbers of interrupts and do the "counting" without locking the CPU.

The reason for this is that I have a channel interrupt in the same vector and I have problem triggering all channel interrupts if they happen after or before the overflow, without overloading.

To be more specifig. I am recording time between rising edges, on up to 500kzh IR signals. The timer overflows every 546uS (system clock = 120mHz) and I get channel interrupt every 2uS.

The think the "easiest" way to eleminate number of interrupts is by counting the timer overflows in a register using DMA. The other solution could be to store all times when a channel interrupt appers in registers.

Kenneth

0 Kudos
Reply

1,009 Views
DavidS
NXP Employee
NXP Employee

Hi Kenneth,

You are right.  I didn't understand the question.

Thank you for elaborating.

How many timing input channels are you using?  Are all channels used to the same FTMx module or are multiple FTMx modules being used?

I think your idea of using DMA is good idea.

Once you record the time between rising edges, how soon do you have to do something based on that information?

Regards,

David

0 Kudos
Reply

1,009 Views
kenrenjen
Contributor III

Hi

I'm using one channel in input capture mode. I also tried dual edge capture mode by combining two channels. The timer module is the same for all channels. When I receive ir code, I have to count number of rising edges in a pulstrain, and if the time between the pulstrains.

I could store the count value raw in an array  when a input occour or I could store the difference from rising edge to rising edge in an array, it doesn't matter. I just need to store it without missing an input or missing an overflow.

Using DMA seems to be the only solution, but I really need some basic examples of how to set it up. How to read and write date to memory and how to trigger DMA on overflow, so that I don't have to count it in ISR.

Thanks again

Kennet

0 Kudos
Reply