PIT0 triggers DMA0 interrupt instead of PIT0 interrupt (Kinetis K10)

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

PIT0 triggers DMA0 interrupt instead of PIT0 interrupt (Kinetis K10)

跳至解决方案
1,459 次查看
stefanglatz
Contributor I

Hello,

I want to generate cyclic interrupts via PIT0 on a MK10DX128VLH7 device. But instead of an PIT0 interrupt, the NVIC always triggers a DMA0 interrupt.

As soon as the PIT0 interrupt is enabled, I see that instead of the PIT0-interrupt (= vector 84 or IRQ 68) the ISR of DMA-channel 0 is triggered (= vector 16 or IRQ0).
When I set a breakpoint inside the called ISR, I can see that the register IABR[3] contains 0x0000.0010 and the register ICSR.VECTACTIVE is set to 84. ICSR.VECTPENDING and ICSR.ISRPENDING are 0. So it seems, that, even though the ISR of channel 0 was called, the interrupt of PIT0 is active. My settings for PIT.MCR is 0x02 (FRZ=1; MDIS=0), PIT.TCTRL0 is 0x03 (TEN=1; TIE=1).

I know that PIT can trigger a DMA, but I have found no setting where I can select an normal interrupt instead of a DMA.

Can anyone give me a hint, what I do wrong?

Thanks in advance,

Stefan

标签 (1)
0 项奖励
回复
1 解答
1,425 次查看
mjbcswitzerland
Specialist V

Hello Stefan

If you set the VTOR to 0x00002200 I believe it will solve the issue.

However, I would in fact expect PIT0 interrupt to call DMA channel 4 and not channel 0 with it is set to 0x00002100.

In any case the issue is that you must align the interrupt vector table suitably since the VTOR operation doesn't implement all lower bits and so wraps around after the 64th vector if set to 0x100 alignment - the first 64 vectors work normally but then the following 64 cause the first 64 to be re-used (vector 64 is handled by vector 0, vector 65 by vector 1, vector 66 by vector 2, etc.)

For the K10 you must use 0x200 alignment if you want to use all possible interrupts. For parts with more that 128 interrupts 0x400 alignment needs to be used.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1064.html

在原帖中查看解决方案

0 项奖励
回复
7 回复数
1,452 次查看
mjbcswitzerland
Specialist V

Hi

Such effects are possible if the vector table is not correctly aligned.
Are there other interrupt working normally?

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/kinetis/TWR-K60D100M.html

0 项奖励
回复
1,442 次查看
stefanglatz
Contributor I

Hi Mark,

the other interrupts are working correctly. I use the ISRs of SPI and UART.

I have changed the the base address of the vector table via the VTOR-register to 0x00002100. Maybe this has someting to do with this behavoir.

As far as I have read in the docu, the DMA0 ISR would be the correct ISR for triggering a DMA by PIT0. So I think I have some kind of misconfiguration. I think I have not found the setting where I can configure PIT0 to trigger it's PIT0-ISR instead of triggering a DMA.

Yours,

  Stefan

0 项奖励
回复
1,426 次查看
mjbcswitzerland
Specialist V

Hello Stefan

If you set the VTOR to 0x00002200 I believe it will solve the issue.

However, I would in fact expect PIT0 interrupt to call DMA channel 4 and not channel 0 with it is set to 0x00002100.

In any case the issue is that you must align the interrupt vector table suitably since the VTOR operation doesn't implement all lower bits and so wraps around after the 64th vector if set to 0x100 alignment - the first 64 vectors work normally but then the following 64 cause the first 64 to be re-used (vector 64 is handled by vector 0, vector 65 by vector 1, vector 66 by vector 2, etc.)

For the K10 you must use 0x200 alignment if you want to use all possible interrupts. For parts with more that 128 interrupts 0x400 alignment needs to be used.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1064.html

0 项奖励
回复
1,406 次查看
stefanglatz
Contributor I

Hello Mark,

you are rigth!

I have changed the alignment in my linker script so that the interrupt vector table. It starts now at 0x00002200. After doing this, the PIT0 interrupt was triggered like expected.
I have derived the base address from the description of the VTOR-register in the ARMv7-M Architecture Reference Manual (Issue E.b). It says that VTOR contains the bits [31:7] of the vector table address. So I havent't thougth that there are also other limitations.

Due to Myke's post, I have rechecked the entries of the vector table. By doing this, I found out that also not "DMA channel 0 transfer complete" (IRQ0) was triggered but "DMA channel 4 transfer complete" (IRQ4).

Thanks to both of you for your help!

Stefan

0 项奖励
回复
1,387 次查看
mjbcswitzerland
Specialist V

Stefan

Case 1: - OK

VTOR = 0x0000
Interrupt vector 20 fires
Vector = VTOR + (4 x 20) = 0x0000 | 0x50 = Address 0x0050

VTOR = 0x0000
Interrupt vector 84 fires
Vector = VTOR + (4 x 84) = 0x0000 | 0x150 = Address 0x0150

 

Case 2: - fails

VTOR = 0x2100
Interrupt vector 20 fires
Vector = VTOR + (4 x 20) = 0x2100 | 0x50 = Address 0x2150

VTOR = 0x2100
Interrupt vector 84 fires
Vector = VTOR + (4 x 84) = 0x2100 | 0x150 = Address 0x2150  <-- same address as vector 20

 

Case 3: - OK

VTOR = 0x2200
Interrupt vector 20 fires
Vector = VTOR + (4 x 20) = 0x2200 | 0x50 = Address 0x2250

VTOR = 0x2200
Interrupt vector 84 fires
Vector = VTOR + (4 x 84) = 0x2200 | 0x150 = Address 0x2350

There are two things to bear in mind:
A. VTOR supports bits 31..7 so VTOR 0x003f == 0x0000 but this is not an issue in your case
B. The vector is calculated by ORing VTOR with the vector offset and not ADDing the offset to it. Therefore the VTOR value for the highest vector offset bit must be 0 otherwise the OR doesn't work for the bit involved and there is a wrap around.

I am pleased that you could also confirm that it was DMA 4 that was incorrectly firing since that confirms that the behavior is matching the theory and so leaves no more question marks.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements

For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/iMX/RT1064.html

1,399 次查看
myke_predko
Senior Contributor III

Hey @stefanglatz 

That's great news - I'm happy you have your solution.

myke

标记 (1)
0 项奖励
回复
1,433 次查看
myke_predko
Senior Contributor III

@stefanglatz 

What tool are you using for software development?  

If you're using MCUXpresso, then setting the interrupt handler is a bit non-intuitive because you have to understand C99's "weak" methods.  

By default the interrupt handler vector table is defined with "weak" default handler methods.  To define your own application in the vector table, you don't explicitly write to the vector table, you simply create your handler specified as the handler.  

To do, this, you create a define specifying that your handler's label is the specific interrupt handler and then put in the handler code.  The address of your code is automagically written to the interrupt handler vector table.  

For my PIT0 Interrupt handler, I use the define and code:

#define PIT_RUN_TASK_HANDLER PIT0_IRQHandler
  :
void PIT_RUN_TASK_HANDLER(void) {
/* Clear interrupt flag.*/
PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag);
++RTOS_RunTimeCounter;
/* Added for, and affects, all PIT handlers. For CPU clock which is much larger than the IP bus clock,
* CPU can run out of the interrupt handler before the interrupt flag being cleared, resulting in the
* CPU's entering the handler again and again. Adding DSB can prevent the issue from happening.
*/
__DSB();
}

Again, not very intuitive but once you understand how the "weak" attribute to methods work, it's quite simple.  

Hope this helps!

myke

0 项奖励
回复