Kinetis L DMA BCR error

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

Kinetis L DMA BCR error

Jump to solution
1,408 Views
wendersonolivei
Contributor IV

Hi all,

I'm using KDS to program the DMA of KL25Z.

I'm setting the DMA to transfer a few configurations to ADC registers. DMA is triggered by hardware request (TPM0_CH1).

When the transfer complete event is called, the BCR is reset to the initial value and the SAR to begining of the config vector. But just 1 transfer (cycle steel of 8 bytes) can be completed, after this the DMA just call the OnError event.

To see what's happening I've installed the EmbSysRegView (How to Add Register Details View in Eclipse | MCU on Eclipse). By setting a break point at the DMA_Error event, I saw the BCR register comes to this value:

value1.JPG.jpg

I don't know why, because the value that I put on this register is 0x8.

This is my code:

void DMA_CH1_OnComplete(LDD_TUserData *UserDataPtr)

{

  printf("\nch1 dma complete");

  DMA_DSR_BCR1 = (uint32_t)8;

  DMA_SAR1 = AB_CFG_SOURCE; //Macro definition of the source address

}

Anyone knows whats happening?

Thanks

Tags (3)
0 Kudos
Reply
1 Solution
1,055 Views
mjbcswitzerland
Specialist V

Hi

Try removing the printf() from DMA_CH1_OnComplete() or moving it "after" the code that configures the DMA for the next transfer. You may find that it then works (I think that completely removing the printf() does make it work because there looks to be no more DMA errors resulting then).

The problem seems to be more system design than DMA code itself. The code is not very easy to follow (I think that you are using PE generated code which uses a lot of deferred function calls that are not easy to follow without investing a certain amount of time understanding where they are and where they are being called from) but I believe that there is a timer being used to regularly trigger than next DMA transfer sequence. At the end of a successful transfer you then set the DMA source pointer back and configure another sequence of 8 transfers. The problem looks to be the fact that you are using a blocking version of printf() which is taking a long time to complete - the next timer event seems to take place faster than the output and so it fires when the DMA (still) has a value of 0 for its transfer count still and this is an illegal configuration when triggering it - thus the following failure.

As long as your code is "fast enough" to set up the next transfer before the next timer event triggers it it is then OK. If you use printf() in a code area that is critical in terms of timing you will either need to use a non-blocking version or else call it after the critical work has been done. If it's execution generally takes longer than the timer period that is triggering the DMA you will not be able to use it in the path since it will not allow the system to keep up with the trigger rate.

Since the code is not obvious without quite a lot of study (which I prefer not to do for an otherwise quite simple case) I am not even sure whether your DMA_CH1_OnComplete() is being called from an interrupt or not, but generally it may be best to avoid any prinf() use in interrupts.

Regards

Mark

P.S: I don't think that the KDS viewer is a problem for debugging.

If you set the breakpoint at the "start" of your OnComplete routine/interrupt you will see that there is no DMA error but if you then step over the printf() you will see that the error has then occurred. This show that the error occurs "while" the printf() routien is being executed... If you set it at the end you just always see the error with no obvious reason why.

View solution in original post

0 Kudos
Reply
7 Replies
1,055 Views
mjbcswitzerland
Specialist V

Hi

DSR_BCRn is signalling that a configuration error occurred (0x40000000). This means that maybe the first transfer was successful but futher not due to an error (invalid source or destination is typical).

For example an attempt to read a long word from a non-aligned address would cause this, or writing to an invalid address.

Regards

Mark

µTasker Kinetis support

1,055 Views
wendersonolivei
Contributor IV

     I set a breakpoint at the end of OnComplete event, after the new configuration. But, only one register have your value shown here.

     That's the problem. With this viewer is very hard to debug correctly.

reg view error.JPG.jpg

0 Kudos
Reply
1,055 Views
mjbcswitzerland
Specialist V

Hi

If you need to know what is going wrong you can post a binary file to load to a standard Freescale board (in this case FRDM-KL25Z for example) - add a map file to go with the binary so that the location of routines is known and tell me which function is being called to start the DMA transfer.

Although KDS may have some limitations it should still be possible to identify the cause of the problem with it (and some experience and possibly a little cunning).

Personally I simulate the DMA operation so that errors are fairly obvious but could compare your code's setup and tell you what needs to be corrected.

Regards

Mark

http://www.utasker.com/kinetis.html

0 Kudos
Reply
1,055 Views
wendersonolivei
Contributor IV

Hi Mark,

I've attached the full project (it's at beginning, so I just have DMA and a CSIO).

For you knowledge, the DMA can transfer one time, but just one time. After this, the DMA calls OnError event.

Thank you for your attention, regards

0 Kudos
Reply
1,056 Views
mjbcswitzerland
Specialist V

Hi

Try removing the printf() from DMA_CH1_OnComplete() or moving it "after" the code that configures the DMA for the next transfer. You may find that it then works (I think that completely removing the printf() does make it work because there looks to be no more DMA errors resulting then).

The problem seems to be more system design than DMA code itself. The code is not very easy to follow (I think that you are using PE generated code which uses a lot of deferred function calls that are not easy to follow without investing a certain amount of time understanding where they are and where they are being called from) but I believe that there is a timer being used to regularly trigger than next DMA transfer sequence. At the end of a successful transfer you then set the DMA source pointer back and configure another sequence of 8 transfers. The problem looks to be the fact that you are using a blocking version of printf() which is taking a long time to complete - the next timer event seems to take place faster than the output and so it fires when the DMA (still) has a value of 0 for its transfer count still and this is an illegal configuration when triggering it - thus the following failure.

As long as your code is "fast enough" to set up the next transfer before the next timer event triggers it it is then OK. If you use printf() in a code area that is critical in terms of timing you will either need to use a non-blocking version or else call it after the critical work has been done. If it's execution generally takes longer than the timer period that is triggering the DMA you will not be able to use it in the path since it will not allow the system to keep up with the trigger rate.

Since the code is not obvious without quite a lot of study (which I prefer not to do for an otherwise quite simple case) I am not even sure whether your DMA_CH1_OnComplete() is being called from an interrupt or not, but generally it may be best to avoid any prinf() use in interrupts.

Regards

Mark

P.S: I don't think that the KDS viewer is a problem for debugging.

If you set the breakpoint at the "start" of your OnComplete routine/interrupt you will see that there is no DMA error but if you then step over the printf() you will see that the error has then occurred. This show that the error occurs "while" the printf() routien is being executed... If you set it at the end you just always see the error with no obvious reason why.

0 Kudos
Reply
1,055 Views
wendersonolivei
Contributor IV

Hi, Mark

Remove the blocking printf makes it work fine. Thanks for all!

Regards

0 Kudos
Reply
1,055 Views
wendersonolivei
Contributor IV

Thank you, mjbcswitzerland !

I was thinking that was a alignment error, but no. It's a configuration error, but I unable to see the value of all registers.

Actually I'm using the EmbSysReg view, because the KDS doesn't have a full register viewer (what I think is a bad thing). But, when I set a breakpoint at somewhere in events (like DMA_On_Complete or DMA_On_error events) the value of registers isn't fully shown. What I'm trying to say is that doesn't work fine (because of errors), and I can't see all of registers.

Do you know another way to see the registers values? With this I can debug correctly, not with alot of doubts about the integrity of the shown values.

Regards,

0 Kudos
Reply