[SOLVED] Kinetis K12 Periodic DMA Triggering

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

[SOLVED] Kinetis K12 Periodic DMA Triggering

704 Views
danielberhe
Contributor IV

Hi,

I am trying to use DMA in periodic trigger mode to transfer data from memory to the PDOR register of a port. I've set the source to one of the always-on slots. My expectation is that a minor loop (a byte in my case) transaction would be carried out every time the PIT timer interrupt happens. However, when PIT interrupt fires, all my data (until major loop is completed) is being written to the PDOR without any throttling. What I'm trying to do should be possible according to section 20.4.3 of the reference manual. Could you please point me in the right direction, maybe provide me with an example project that I can use as a reference?

I'm using MK12DX128VLF5 on a custom board. I'm using PIT channel 0 with DMA channel 0. 

Best wishes,

Daniel

0 Kudos
5 Replies

509 Views
danielberhe
Contributor IV

It looks like it is an issue with the Kinetis MCU. I found this errata e4588 http://cache.freescale.com/files/microcontrollers/doc/errata/KINETIS_4N30D.pdf

Daniel

0 Kudos

509 Views
mjbcswitzerland
Specialist V

Daniel

I don't know that I have used the PIT DMA trigger on a device with this errata but if this is the reason you can switch to using a FlexTimer channel as trigger instead. The FlexTimer can be used to generate a fixed number of pulses at a certain frequency and, using DMA, change the frequency and next step counter at the end of the period to automatically generate stepper motor acceleration/deceleration ramps, etc. and so is potentially more flexible too.

Regards

Mark

0 Kudos

509 Views
danielberhe
Contributor IV

Hi Mark,

Yeah that's what I just did and it is working fine with using one FlexTimer channel. 

Thanks for all your help.

Daniel

0 Kudos

509 Views
danielberhe
Contributor IV

Hello Mark,

Thank you for your message.

However, this doesn't fix the issue I'm having. DREQ in DMA_TCDx_CSR is already set. According to the reference manual, setting that bit will make eDMA clear the ERQ bit after a major loop completion. What I'm trying to do is to clear ERQ after a minor loop completion. So basically, I've set the major loop count to 38 bytes and minor to 1 byte. I'm attempting to send the one byte every time PIT interrupt happens until all the 38 bytes are transferred. 

Best wishes,

Daniel

0 Kudos

509 Views
mjbcswitzerland
Specialist V

Hi Daniel

Set DREQ in DMA_TCDx_CSR to get a single transfer for each trigger.

In case of continued difficulties just use the open source uTasker solution on GitHub which support this in its PIT driver as follows (DMA channel is always DMAMUX0 for PIT0 and DMAMUX1 for PIT1):

PIT_SETUP pit_setup;                                                 // PIT interrupt configuration parameters
pit_setup.int_type = PIT_INTERRUPT;
pit_setup.mode = (PIT_PERIODIC | PIT_OUTPUT_DMA_TRIG);               // periodic with DMA trigger to control a port toggle
pit_setup.int_handler = 0;                                           // no interrupt due to DM
pit_setup.count_delay = PIT_US_DELAY(1);                             // 1us period (for 500kHz square wave)
pit_setup.ucPIT = 0;                                                 // use PIT0
pit_setup.ulPortBits = PORTA_BIT1;                                   // toggle PTA1 on each PIT trigger
pit_setup.ucPortRef = PORTA;
fnConfigureInterrupt((void *)&pit_setup);                            // configure PIT
‍‍‍‍‍‍‍‍‍


Regards

Mark


Complete Kinetis solutions, training and support: http://www.utasker.com/kinetis.html

0 Kudos