LPC54102 DMA Software Trigger

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

LPC54102 DMA Software Trigger

803 Views
rhsalced
Contributor I

Hello,

My goal is start/stop DMA transfers via software control. From the main loop I would like to start/stop DMA transfers.

The version of the SDK that I am using is v.3.04.000 and the example project is spis_dma. The reason for using this version is that I am working with legacy code that expects this version of the SDK. I am not planning on using the latest SDK and do not plan to.

From my understanding, I need to configure the DMA to be software trigger driven. From the UM10850 14.7.1 doc:

1) “CFGVALID and SV allows a more direct DMA block timing control by software”

Are these set in the .xfercfg on lines 131, 138, 146, 153 or should they be set elsewhere?

 

2) ”Leaving a CFGVALID bit set to 0 allows the DMA sequence to pause at the description unit software triggers the continuation”

How and where do I set this up?

 

3) “If a channel is configured with SWTRIG = 0, the channel can be later triggered either by hardware or software. Software triggering is accomplished by writing a 1 to the appropriate bit in the SETTRIG register”

How and where do I set this register from the main loop?

 

4) “When a channel is initially set up, the SWTRIG bit in the XFERCFG register can be set, causing the transfer to begin immediately”

 

I am unsure if I am configuring the DMA to be software driven.

Also, I don’t know what function/register I should call to start/stop the transfer. I’m calling the Chip_DMA_SetTrigChannel() function from the main loop, I don’t think I’m using this function correctly.

All that I am trying to do is set a DMA transfer once a second from the main loop via a software trigger. I could really use some help on how to do this.

The changes that I made to spis_dma.c:

1) Set SPI as master. Original project SPI was configured as slave. Set spiSetup.master = 1 on line 80.

2) Removed DMA_XFERCFG_RELOAD from xfercfg (lines 131, 138, 146, 153). I think I needed to do this so the DMA wouldn’t continuously execute.

3) Commented out spis_dma_Start(); from lines 189 and line 201.

4) In main, calling software dma trigger once a second. Lines 257- 258.

 

Any help on how to set up a software DMA trigger would be appreciated.

Thanks!

0 Kudos
Reply
8 Replies

774 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @rhsalced 

According the UM10850.

To enable full software control of DMA transfers, you need to:

Disable peripheral requests (set PERIPHREQEN = 0)

Configure SWTRIG in XFERCFG for immediate start, or

Use the SETTRIG register from your main loop

Use CFGVALID = 0 and SETVALID to pause and resume descriptor chains

1. 

CFGVALID is set in the descriptor itself:

dmaDescriptor.xfercfg = DMA_CHANNEL_XFERCFG_CFGVALID_MASK | other_fields;

To pause execution at a descriptor:

Do not set CFGVALID in .xfercfg for that descriptor.

Then


DMA0->SETVALID0 = (1U << channelNum); // e.g., channelNum = 0

2. 

In your descriptor chain, zero out CFGVALID for the descriptor where you want to pause.


descriptor[i].xfercfg &= ~DMA_CHANNEL_XFERCFG_CFGVALID_MASK;

Then, from your main loop:


DMA0->SETVALID0 = (1U << DMA_CHANNEL_NUMBER);

3.

From your main loop, trigger a DMA transfer like this:

DMA0->SETTRIG = (1U << DMA_CHANNEL_NUMBER); // software trigger

BR

Harry

0 Kudos
Reply

754 Views
rhsalced
Contributor I

Hello Harry, 

 

Thanks for the response, I appreciate your help. 

I tried the changes you recommended, at least I think I applied the changes you recommended. 

 

Could you please take a look at spis_dma.c? This is the file where I've applied the changes. Maybe I'm missing something. 

I also attached the original spis_dma_orig.c file provided by NXP. If you compare the files you'll be able to see the changes that I've made.

Maybe other changes are needed for the .xfercfg? 

 

Thanks,

Ricardo

0 Kudos
Reply

672 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @rhsalced 

I will check the spis_dma.c and spis_dma_orig.c.

BR

Harry

0 Kudos
Reply

594 Views
rhsalced
Contributor I

Hello @Harry_Zhang ,

Have you had the chance to look at spis_dma.c and spis_dma_orig.c?

Thanks,

Ricardo

0 Kudos
Reply

520 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @rhsalced 

I’ve reviewed your code and identified a few critical issues.

In Hostif_Init():

Chip_DMA_SetupChannelConfig(LPC_DMA, APP_SPI_DMA_TXCH,
(~DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(0)));

This is incorrect. You're using bitwise NOT (~DMA_CFG_PERIPHREQEN) which results in all bits flipped and corrupts the config.

In spis_dma_Start():

dmaSPISTxDesc[0].xfercfg = ~DMA_XFERCFG_CFGVALID | ...

The ~DMA_XFERCFG_CFGVALID again corrupts the value.

BR

Harry

0 Kudos
Reply

495 Views
rhsalced
Contributor I

1) 

In Hostif_Init():

Chip_DMA_SetupChannelConfig(LPC_DMA, APP_SPI_DMA_TXCH,
(~DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(0)));

 

I changed this to: 

Chip_DMA_SetupChannelConfig(LPC_DMA, APP_SPI_DMA_TXCH,
(DMA_CFG_TRIGBURST_SNGL | DMA_CFG_CHPRIORITY(0)));

Did the same for RX. 

2) 

In spis_dma_Start():

dmaSPISTxDesc[0].xfercfg = ~DMA_XFERCFG_CFGVALID | ...

I removed the ~DMA_XFERCFG_CRGVALID from dmaSPISTxDesc[0].xfercfg. I want to pause/resume from this descriptor. The other descriptors have DMA_XFERCFG_CFGVALID. 

 

Attached is the updated spis_dma.c.

My goal is to resume the DMA from the main loop once per second. Pausing and resuming from dmaSPISTxDesc[0].xfercfg. On the Oscope, I'm only see the SPI bus active for one TX transfer. The DMA seems to be hung up, not sure what I am doing wrong here. 

Thanks, in advance for your help. 

0 Kudos
Reply

418 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @rhsalced 

Your DMA descriptors are configured as a ring (cyclic):

dmaSPISTxDesc[0].next = DMA_ADDR(&dmaSPISTxDesc[1]);
dmaSPISTxDesc[1].next = DMA_ADDR(&dmaSPISTxDesc[0]);

That implies continuous DMA transfer, not single-shot.

I think you can refer to the sdk demo.
Harry_Zhang_0-1749631431790.png

Or i think you can  Simplify to One-Shot DMA and Restart It

Disable the next field (no chaining):
 
dmaSPISTxDesc[0].next = 0;
dmaSPISRxDesc[0].next = 0;
 

Set CFGVALID on every start:

Move xfercfg setup into the main loop. For example:

void start_spi_dma_once(void)
{
//set up tx and rx
}

BR

Harry

0 Kudos
Reply

751 Views
rhsalced
Contributor I
Forgot to mention I'm trying to stop the pause/resume at dmaSPISTxDesc[0].

I set dmaSPISTxDesc[0] = ~DMA_XFERCFG_CFGVALID.

And in the main loop I try resuming by setting SETVALID and SETTRIG.
0 Kudos
Reply