Code:
#pragma interrupt_handler SCI1void SCI1_Handler(void){
int dummy;
dummy = SCI1SR1;
SCI1DRL = 0x55;
SCI1CR2 &= ~SCI_TIE;
printf("SCICR2 = %x\n\r",SCI1CR2);}void main(){
// Clockspeed = 24Mhz
CLKSEL &= ~BM_PLLSEL; // make sure PLL is *not* in use
PLLCTL |= BM_PLLON+BM_AUTO; // enable PLL module, Auto Mode
REFDV = S12_REFDV; // set up Reference Divider
SYNR = S12_SYNR; // set up Synthesizer Multiplier
while((CRGFLG & BM_LOCK) == 0) ;// wait until PLL is locked
CLKSEL |= BM_PLLSEL; // switch over to PLL clock
// SCI0 = Twinpeeks Monitor
SCI0BD = 78; // 19200Bd at 24MHz ECLK
SCI0CR1 = 0; // mode = 8N1
SCI0CR2 = 0x0c; // Transmitter + Receiver enable
// SCI1 = Port we're testing on
SCI1BD = 52; // 9600Bd at 24Mhz ECLK
SCI1CR1 = 0x80; // mode = 8N1, LOOP OFF
SCI1CR2 = 0x0c; // Tx enable, Rx enable, no interrupts yet
// SCI1 Interrupt for Twinpeeks (redirected vectors)
*((unsigned char *)0x3FC1) = 0x06; // JMP opcode
*((void (**)(void))0x3FC2) = SCI1_Handler; Enable_Interrupts; while(1) { printf("Test\n\r"); SCI1CR2 |= SCI_TIE; }}
So, that's very basic I'd say. The only thing I am trying to test is if the program will jump into the interrupt routine, and back out of it. What I expect the code to do:
- print "Test" to my monitor. --> This works
- Enable the TX Interrupt, and immediately trigger on TDRE --> This works
- Jump to the ISR, and print "SCICR2 = <CR2status>" to my monitor. --> This works, CR2 = 0x0C (TIE was turned off)
- Jump back to my main program, and start over again. --> This fails!
The MCU hangs, never prints anything to my monitor again. In my original program (including the whole SCI driver), the MCU would also hang on each TIE, and dump a load of garbage on my monitor (real garbage, just weird characters, nothing distinguishable). It doesn't reset, so I don't get back to my monitor unless I do a hard reset.
So... where am I going wrong? Is my thought that simply disabling the Tx Interrupt should be enough to return from the routine? Reading SR1 and then writing to DRL should be enough to clear the TDRE flag, and after that, the TIE gets disabled, so when the ISR is done, it should jump back to my normal routine, right?
Where am I going wrong?