DMA on kinetis k64

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

DMA on kinetis k64

2,344 Views
stefanobizzari
Contributor I

I'm using a kinetis k64 microcontroller. In particular a MK64FN1M0VLQ12 part.

I need to transfer a lot of datas from memory to a peripheral (a video controller).

The videocontroller just need a simple initialization in order to specify the video area and then just a write pin to confirm the data.

So what I'm trying to do is to use a pwm in order to toggle a pin and, this pwm, is an hw trigger for a DMA channel that fetch the data and put it on the desired port.

The data size is of 2 bytes so the transaction count for the minor loop is 1 (2 bytes per request).
It works correctly except the fact that the major loop (as far as I have seen) is limited to 32767 transitions. What can I do if I need to transfer more datas?

I can try to re-iterate 32k transfer controlling the video size accordingly. But, in this way, the speed is reduced (every time I need to set the video size to 32767 pixels, start a new transfer etc etc).

I've seen that I can link one or more channels each other. However I've not understand how the linked channel can start "automatically"... I mean, in processor expert I've seen that there an option to link another channel at the end of a complete transfer which is great except the fact that it seems that it doesn't start the second channel.

I've attached a picture of my dma linking configuration.. What I miss in your opinion?

And, a part of this, is there an easier way to do what I need? Maybe I'm trying to do all in a very complicated way and there is an easier solution. I'm a very newbie regarding DMA transfer so I'm afraid that I'm trying an overcomplicated solution for my problem.

Labels (1)
0 Kudos
Reply
4 Replies

1,536 Views
isaacavila
NXP Employee
NXP Employee

Helo Stefano,

As Dean Jia already said, you can implement the Scatter/Gather feature. Here is a document and example (in baremetal implementation) that describes this features: What is and how to configure the eDMA scatter/gather feature 

Also, if you still want to know how the linking process between two DMA channels is, you can refer to this post (it is related to linking channels on minor loop instead of major loop but this can help you to understand the concept): https://community.nxp.com/thread/435844 

Hope this helps!

Regards,
Isaac

0 Kudos
Reply

1,536 Views
dean_jia
NXP Employee
NXP Employee

Hi Stefano,

The limitation of the Major Loop Size could be settled by enabling the Scatter/Gather Processing feature of the eDMA module. To utilize the feature, we need to:

1. Define an object/variable with the TCD type, as shown below, which takes 32 bytes. 

typedef struct _edma_tcd
{
__IO uint32_t SADDR; /*!< SADDR register, used to save source address */
__IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
__IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
__IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
__IO uint32_t SLAST; /*!< SLAST register */
__IO uint32_t DADDR; /*!< DADDR register, used for destination address */
__IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
__IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
__IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next stcd address used in scatter-gather mode */
__IO uint16_t CSR; /*!< CSR register, for TCD control status */
__IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
} edma_tcd_t;

2. When configuring the TCDn: 1)initialize the DMA_TCDn_DLASTSGA register with the address of the TCD object; 2) set the DMA_TCDn_CSR[ESG] bit .

3. Initiate the first DMA transfer as usual.

4. Initialize the TCD object with new value based on the requirement before the current major loop is completed.

When the current major loop is completed, the eDMA engine will load the defined TCD object to the current channel TCD. Then new DMA transfer could be triggered by the following hardware trigger, the coming PWM in your case.

Note: The TCD object address must be 0-modulo-32-byte, else a configuration error is reported.

Regards,

Dean

Best Regards,
Dean
0 Kudos
Reply

1,536 Views
stefanobizzari
Contributor I

Hi Dean,

I've some question in order to understand better your answer.
1. OK

2. Imagine I've channel 0 that start and I want to link channel 1 at the end of the major loop of channel 0. So I will put the address of my edma_tcd struct in the scatter/gather option of the processor expert and it should be ok? However I think that the information in the edma_tcd struct refer to channel 1.. Is it ok?

3. OK

4. Do you mean that I have to initialize this struct maybe in the half of the transfer of channel 0? I've seen in the options of the processor expert that DMA can generate an interrupt at the half of a complete transfer instead of the end of a complete transfer. In this way I can initialize the struct in the interrupt.

Thanks in advance,
Stefano

0 Kudos
Reply

1,536 Views
dean_jia
NXP Employee
NXP Employee

Hi Stefano,

Here are the answers of your questions.

2. You do not have to use the channel linking function in case you use the Scatter/Gather feature to solve this problem. One channel is sufficient. The mechanism is that the eDMA engine updates the TCD automatically for the next major loop transfer after the previous transfer is end.

4. You can either use the interrupt method or the Scatter/Gather method to update the TCD for a new transfer. However, as far as I'm concerned, the Scatter/Gather method takes less time to complete the update between the transfer interval. It is done by the eDMA engine rather than CPU. Thus, I suggest to use the Scatter/Gather method.

Regards,

Dean

Best Regards,
Dean
0 Kudos
Reply