Hello everyone,

I've got a bit of a problem getting my USART TX interrupt working correctly (using DT_INTS), something that I've done numerous times before. This is on a 18F25K20 (on the AMICUS 18 board) and here the piece of code I'm using as a base for testing:
Code:
DEFINE OSC 64
DEFINE LOADER_USED 1            ' We're using a bootloader.
DEFINE HSER_RCSTA 90h           ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h           ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1           ' Clear overflow automatically
DEFINE HSER_SPBRG 138           ' 115200 Baud @ 64MHz, -0,08%
 
SPBRGH = 0
BAUDCON.3 = 1                   ' Enable 16 bit baudrate generator
 
INCLUDE "DT_INTS-18.bas"        ' Include Darrels interrupt engine.
INCLUDE "ReEnterPBP-18.bas"     ' And the stub needed for interrupts in PBP 
 
ASM                             ; Set up the USART transmit interrupt.
INT_LIST  macro     ; IntSource,   Label,    Type, ResetFlag?
        INT_Handler    TX_INT,   _USART_TX,   PBP,    no
    endm
    INT_CREATE                  ; Creates the interrupt processor
ENDASM
 
String_1    VAR BYTE 50       ' Array to hold string.
TXPointer   VAR BYTE           ' Pointer into array
 
HSEROUT["Program start",13,13]
 
ArrayWrite String_1, ["This is the content of String_1",13,0]
 
'-------------------------------------------------------------------
HSEROUT["First test:  "]
HSEROUT[STR String_1]
Pause 200
'-------------------------------------------------------------------
 
'-------------------------------------------------------------------
HSEROUT["Second test: "]
TxPointer = 0
While String_1[TxPointer] <> 0
  HSEROUT[String_1[TXPointer]]
  TxPointer = TxPointer + 1
WEND
Pause 200
'-------------------------------------------------------------------
 
'-------------------------------------------------------------------
HSEROUT["Third test:  "]
TxPointer = 0
@  INT_ENABLE TX_INT
Pause 200
'-------------------------------------------------------------------
 
'-------------------------------------------------------------------
HSEROUT["Fourth test: "]
TxPointer = 0
While String_1[TxPointer] <> 0
  HSEROUT[String_1[TXPointer]]
  TxPointer = TxPointer + 1
WEND
Pause 200
'-------------------------------------------------------------------
 
END
 
'-- Interrupt service rotuine for USART TX Interrupt ---------------
USART_TX:
  TXReg = String_1[TxPointer]       ' Load character from array into USART TX register
  If String_1[TxPointer] = 0 then   ' If that character was a NULL we're done so we.....
@   INT_DISABLE  TX_INT             ; ...disable the any further USART TX interrupts.
  ELSE                              ' If the character was not a CR we.....
    TxPointer = TxPointer + 1       ' ...increase the pointer, prepare to send the next character.
  ENDIF                             ' As soon as the TX-reg is empty the interrupt will fire again. (~1ms at 9600baud)
@ INT_RETURN
As you can see I load an array with a short string and then I send it out using various methods. This works exactly as I want, on the serial terminal I get the following, each time I reset the device:
Program start

First test: This is the content of String_1
Second test: This is the content of String_1
Third test: This is the content of String_1
Fourth test: This is the content of String_1
However, if I now increase the size of the array to 100 it messes up and I get this instead:
Program start

First test: This is the content of String_1
Second test: This is the content of String_1
Third test: TFourth test: T
As you can see something is now messed up and I don't understand what and why. The interrupt routine seems to disable the interrupt after the first character and then, what previously worked fine in Test2, no longer works either. As if the array got corrupted.

As a debug aid I then added a fifth output as follows:
Code:
HSEROUT[13, "Fifth test",13]
For TXPointer = 0 to 35
  HSEROUT [DEC TXPointer,": ", DEC String_1[TXPointer],13]
NEXT
Pause 200
 
END
The output of this clearly shows why the interrupt routine (and the following WHILE-WEND routine) stops sending - there's now a NULL at location 1 in the array - the array has somehow gotten corrupted:
First test: This is the content of String_1
Second test: This is the content of String_1
Third test: TFourth test: T
Fifth test
0: 84
1: 0
2: 0
3: 115
4: 32
5: 133
6: 0
7: 32
8: 116
9: 104
10: 0
The 25K20 used here has 1536 bytes of RAM so I can't imagine it's running out of room - in which case I should've gotten a message about it not being able to fit the array, which I don't.

This was initially with 2.60A but I've tried with 3.01 and I get the same results.

I've tried declaring the array as various sizes. At 50 bytes everything works, so does 63 but at 64 bytes it "starts" to fall apart, the output then becomes:
First test: This is the content of String_1
Second test: This is the content of String_1
Third test: This is the content of String_1
`Fourth test: This is the content of String_1
`
What am I doing wrong here? Why is the ISR corrupting my array? I've got the ISR declared as type PBP so it's not that. What is that I'm not seeing here?

/Henrik.