cancel
Showing results for 
Search instead for 
Did you mean: 

ST10 Interrupt Misbehaving

ashley2
Associate II
Posted on April 19, 2007 at 19:50

ST10 Interrupt Misbehaving

5 REPLIES 5
ashley2
Associate II
Posted on April 17, 2007 at 02:10

Am using ST10F269. Having trouble using he ASC0 module! I have a circular transmit buffer and transmit interrupt (S0TBIC) that sends buffer contents. I disable the transmit interrupt locally while working on the buffer then re-enable it when done... unfortunately I get some unexpected behavior. All works well on the simulator, but on the chip things go a bit wrong and I get a few messed up bytes. It is like the local disable does not actually work.. I have checked that the correct bits are being set and cleared, but all seems OK. Here is the catch, my program works perfectly when I use global interrupt disable instead of local interrupt disable!!! Any ideas or help greatly appreciated.

Thanks

Ashley

ashley2
Associate II
Posted on April 18, 2007 at 05:36

Yes, the interrupts I am using are as above. I am only using the one transmit complete interrupt. The interrpt has a priority of 3 and group of 1. Here are some observations I have made whle debugging:

- The problem goes away when setting and clearing the tx complete interupt enable is replaced with setting and clearing global interrupt enable.

- The problem changes away when a single ''NOP'' is inserted anywhere in the code!

- The problem goes away when a tiny memory model is selected instead of small.

- The problem does not exist when the tx buffer is operated on, then the tx ISR is allowed to run through without changing the buffer contents.

- Changing a single statement from P2 &= 0xFF to P2 |= 0x01 causes the problem to appear as it changes the assembly listing from a literal assignment to port 2 to a DPP referenced assignment of the ones register to port 2.

- The memory used for the buffer is getting corrupted.

- I am certain that the interrupt flag is being cleared somewhere in software probably about the same time as writing to the interrupt enable flag as the tranmit interrupts just unexplainably stop happening! It is like when I enable the interrupt with the tx complete flag set it clears the tx complete flag!!!

I believe there is no problem with my code (famous last words) and that the problem is in the processor specific implementation. A very seasoned ST10 programmer at work believes that the problem may be due to misuse of DPP registers. I am a pretty confident C programmer, but very new to ST10 assembly and memory management.

I will put together a single source file and post it to see if anybody can spot the fault... But it changes based on cpu cycles!!!

Thanks for your help..

ashley2
Associate II
Posted on April 18, 2007 at 21:19

ashley2
Associate II
Posted on April 18, 2007 at 21:22

OK, I think I have it sorted... It seems that the following code segment causes a fault:

uint8 SendBytes(uint8 * ptrString, uint8 uiOffset, uint8 uiBytesToSend)

{

uint16 uiLocation;

uint8 uiCounter = 0;

// Disable tx interrupt as we will be operating on the tx buffer

DisableLocalInterrupt(S0TBIC);

// Calculate the start position for writing to the buffer

(uint16)g_UARTtxBuffer.uiNoOfCharsInBuf) % (uint8)CIRC_BUF_SIZE);

uiLocation = (uint16)g_UARTtxBuffer.uiBufPointer + (uint16)g_UARTtxBuffer.uiNoOfCharsInBuf;

if(uiLocation >= CIRC_BUF_SIZE)

{

uiLocation -= CIRC_BUF_SIZE;

}

But this is OK:

uint8 SendBytes(uint8 * ptrString, uint8 uiOffset, uint8 uiBytesToSend)

{

uint16 uiLocation;

uint8 uiCounter = 0;

// Disable tx interrupt as we will be operating on the tx buffer

DisableLocalInterrupt(S0TBIC);

_nop_();

// Calculate the start position for writing to the buffer

(uint16)g_UARTtxBuffer.uiNoOfCharsInBuf) % (uint8)CIRC_BUF_SIZE);

uiLocation = (uint16)g_UARTtxBuffer.uiBufPointer + (uint16)g_UARTtxBuffer.uiNoOfCharsInBuf;

if(uiLocation >= CIRC_BUF_SIZE)

{

uiLocation -= CIRC_BUF_SIZE;

}

Note the _nop_() under the DisableLocalInterrupt() macro function. Is it possible that local interrupts are subject to the same pipelining effects as the global interrupts? The line following the interrupt disable uses a variable that is modified by the ISR. If the variable was part way through being modified when the ISR occurred, I would get the exact problem I am seeing??? Here is the disassembly for those of you who care:

93: uint8 SendBytes(uint8 * ptrString, uint8 uiOffset, uint8 uiBytesToSend)

94: {

95: uint16 uiLocation;

96: uint8 uiCounter = 0;

97:

98: // Disable tx interrupt as we will be operating on the tx buffer

0002006C E10E MOVB RL7,#0x00

99: DisableLocalInterrupt(S0TBIC);

100:

101: // Calculate the start position for writing to the buffer

102: // uiLocation = (uint8)(((uint16)g_UARTtxBuffer.uiBufPointer + (uint16)g_UARTtxBuffer.uiNoOfCharsInBuf) % (uint8)CIRC_BUF_SIZE);

0002006E D180 EXTR #1

00020070 0ACE4000 BFLDL S0TBIC,#0x40,#0x00

103: _nop_();

104:

00020074 CC00 NOP

105: uiLocation = (uint16)g_UARTtxBuffer.uiBufPointer + (uint16)g_UARTtxBuffer.uiNoOfCharsInBuf;

00020076 C2F5BF82 MOVBZ R5,DPP2:0x02BF

0002007A C2F6BE82 MOVBZ R6,DPP2:0x02BE

0002007E 0065 ADD R6,R5

106: if(uiLocation >= CIRC_BUF_SIZE)

107: {

00020080 46F61900 CMP R6,#0x0019

00020084 8D02 JMPR CC_C,0x02008A

108: uiLocation -= CIRC_BUF_SIZE;

00020086 26F61900 SUB R6,#0x0019

109: }

110:

ps how come using the CODE button makes my entire email disappear?

[ This message was edited by: ashes on 19-04-2007 00:53 ]

ashley2
Associate II
Posted on April 19, 2007 at 19:50

So should I put one NOP or two in after the interrupt disable instruction do you think?