MCF5235 spurious interrupt on UART 0

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

MCF5235 spurious interrupt on UART 0

3,353 次查看
Haiiro
Contributor I
My code is set up to get an interrupt after a byte is transmitted from the serial port. I am getting a spurious interrupt on UART 0 just after the following code is executed:

Code:
// Enable interrupt for when transmission of single byte is completeMCF_UART_UIMR0 |= MCF_UART_UIMR_TXRDY;

On page 13-8 of the Rev. 1.1 and Rev. 2.0 manuals  (MCF5235RM/D) is the following note:
Code:
NOTEIf an interrupt source is being masked in the interrupt controller maskregister (IMR) or a module’s interrupt mask register while theinterrupt mask in the status register (SR[I]) is set to a value lower thanthe interrupt’s level, a spurious interrupt may occur. This is because bythe time the status register acknowledges this interrupt, the interrupthas been masked. A spurious interrupt is generated because the CPUcannot determine the interrupt source. To avoid this situation forinterrupts sources with levels 1-6, first write a higher level interruptmask to the status register, before setting the mask in the IMR or themodule’s interrupt mask register. After the mask is set, return theinterrupt mask in the status register to its previous value. Since level 7interrupts cannot be disabled in the status register prior to masking,use of the IMR or module interrupt mask registers to disable level 7interrupts is not recommended.

What I don't understand is the statement about "first write a higher level interrupt mask to the status register". Which register is this referring to? I cannot find any registers that implement an interrupt level except for the ICR[nx] registers, but this does not seem to be what is talked about here.

Is there some clarification about how to do this?

标签 (1)
0 项奖励
回复
2 回复数

748 次查看
SimonMarsden_de
Contributor II
Hi

Yes, there's another register which you need to set up. It's the processor's main Status Register (SR) which is part of the ColdFire core. The SR contains a 3-bit field which acts as the final interrupt mask:

0 = No interrupts masked
1 = Level 1 masked
2 = Levels 1 and 2 masked
...etc

The SR is so fundamental to the ColdFire architecture that you program it using special instructions, rather than normal memory-mapped writes. You need to use the instruction:

          MOVE   <value>,SR

This makes it a little harder to program from C, because you need to use a little bit of assembler code.

You also need to set the interrupt mask bits without changing the other important bits in the register, particularly the Supervisor bit.

To get you started, assuming that you're currently running in Supervisor Mode (the mode in which the processor boots), you could set the mask to 7 using the following code:

asm {
    move.w   #0x2700,sr
}

Some environments offer a subroutine to do this for you. For example in a CodeWarrior project there is often a routine called asm_set_ipl, which you can call from C as follows:

    old_mask = asm_set_ipl (new_mask);


Hope this helps



Simon














0 项奖励
回复

748 次查看
Haiiro
Contributor I
Of course, I should have seen that. I was looking through the Interrupt Controller section for the register in that section. Then, as I look through other parts of the code, there are numerous DISABLE and ENABLE macros that do exactly that: move.w #0x2700, sr and move.w #0x2000, sr.

It's been too long since I did much 68K assembly.

Now, even with that it still crashes, but that's something I can deal with.

0 项奖励
回复