Please find below the code where I have implemented both the external interrupt and a Timer Interrupt. When I set the compiler to use only one of the interrupts (enable/disable definitions at header ‘ONLY_TIMER’ and ‘ONLY_EXT_INT’), each interrupt works fine by itself. But when I enable both interrupts, the compiler throws me a different error every time, and I do not get anything on the rabbit board. By the way, I am using a BL2120 computer board with an RCM2300 core module.
Among the errors I get:
- Immediate Timeout after programming the board
- Program Terminated. Exit Code -6499
- Program Terminated. Exit Code 243
It is a concern to me the lack of consistency when compiling the code. Any thoughts or help on this matter would be appreciated.
//* DEFINITIONS */
#ifndef _FLASH_
#error "This program must be compiled to Flash."
#endif
/* Compiler Settings */
#class auto // Put local variables on the stack by default
/* Rabbit Config */
#define IOCONFIG 0xDFFF // '1111111111111111' All Ports as sourcing
/* Ports */
#define LED 13 // Valve Port
#define PORTA 0001 // EXTERNAL OUTPUT PORT A (OUT00-0UT07)
#define PORTAShadow &PortAShadow
#define FAST_TIMERB
#define FAST_EXT_INT
#define ONLY_TIMER
//#define ONLY_EXT_INT
/* Test Timer */
#define PWM_PORT PEDR // using port E, bit PE5 (PE5_INT)
#define PWM_SHADOW PEDRShadow
#define PWM_BIT_LOW ~0x20
#define PWM_BIT_HIGH 0x20
/* General Definitions */
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef OFF
#define OFF (0)
#endif
#ifndef ON
#define ON (1)
#endif
/* Aquamaster 250L */
#ifndef ONLY_EXT_INT
void timerb_isr( void );
#endif
#ifndef ONLY_TIMER
void my_isr();
#endif
/********************************************************************
* LOCAL VARIABLES */
#ifndef ONLY_EXT_INT
char flag;
unsigned char PortAShadow;
#endif
#ifndef ONLY_TIMER
unsigned int count;
int status, key;
#endif
static uint8 temp[4];
void main ()
{
uint16 k;
// Required for BL2100 series boards
brdInit();
digOutConfig(IOCONFIG);
#ifndef ONLY_TIMER
count = 0;
status = FALSE;
WrPortI(PEDDR, &PEDDRShadow, 0x00); // set port E as all inputs
SetVectExtern2000(1, my_isr);
WrPortI(I0CR, &I0CRShadow, 0x00); // disable external INT0 on PE4
WrPortI(I1CR, &I1CRShadow, 0x00); // disable external INT1 on PE5
#endif
for(k=0;k<4;k++) {
temp[k]=0;
}
#ifndef ONLY_EXT_INT
#if __SEPARATE_INST_DATA__ && (_RK_FIXED_VECTORS)
interrupt_vector timerb_intvec timerb_isr;
#else
SetVectIntern(0x0B, timerb_isr); // initialize Timer B interrupt vector
#endif
//Initialize External Port A (OUT00-OUT07) Shadow Register with zeros
PortAShadow = 0x00;
//Initialize External Port A (OUT00-OUT07) with zeros
WrPortE(PORTA, PORTAShadow, PortAShadow);
flag = 0;
// initialize Timer B
WrPortI(TBCR, &TBCRShadow, 0x09); // clock timer B with PCLK/16 and set interrupt level to 1
// each count corresponds to 1/11.0592MHz = 90.42ns
WrPortI(TBM1R, NULL, 0);
WrPortI(TBL1R, NULL, 0); // set initial match
WrPortI(TBCSR, &TBCSRShadow, 0x03); // enable timer B and B1 match interrupts
#endif
while (1){
#ifndef ONLY_TIMER
// output the interrupt count every second
costate {
if (status) {
printf("count = %5u
", count);
}
else {
count = 0;
}
waitfor(DelaySec(1));
}
costate
{
if(kbhit())
{
key = getchar();
if (key == 'D' || key == 'd')
{
while(kbhit()) getchar();
WrPortI(I0CR, &I0CRShadow, 0x29); // enable external INT0 on PE4, rising edge
WrPortI(I1CR, &I1CRShadow, 0x29); // enable external INT1 on PE5, rising edge
status = TRUE;
}
if (key == 'F' || key == 'f') //Stop
{
while(kbhit()) getchar();
WrPortI(I0CR, &I0CRShadow, 0x00); // disable external INT0 on PE4
WrPortI(I1CR, &I1CRShadow, 0x00); // disable external INT1 on PE5
status = FALSE;
}
}
}
#endif
}
}
/****** interrupt routine for external interrupt 0 ******/
#ifndef ONLY_EXT_INT
#ifdef FAST_TIMERB
#asm root nodebug
timerb_isr::
push af ;save registers
push hl
push iy
push de
ioi ld a, (TBCSR) ; clear the interrupt
ld a,(flag) ; get flag value
inc a ; increment
ld (flag), a ; save for next time
and 0x01 ; mask off all but bit 0
jr nz, .set_high ; jump to set the PWM output low
.set_low:
c BitWrPortE(PORTA, PORTAShadow, 0, 0);
c BitWrPortE(PORTA, PORTAShadow, 1, 1);
jr .done
.set_high:
c BitWrPortE(PORTA, PORTAShadow, 1, 0);
c BitWrPortE(PORTA, PORTAShadow, 0, 1);
.done:
xor a ; setup to load counter B with zero's
ioi ld (TBM1R), a
ioi ld (TBL1R), a ; writing to low byte enables next interrupt
pop de ; restore registers
pop iy
pop hl
pop af
ipres ; restore interrupts
ret ; return
#endasm
#else
nodebug root interrupt void timerb_isr()
{
if (TBCSR) { //Clear Flag
count ++;
flag = (count > 50)? 1:0;
WrPortI(TBM1R, NULL, 0);
WrPortI(TBL1R, NULL, 0); // Set initial interrupt compare value
#asm
ld a, (msb_cval) ; put high byte value into bits 6 & 7
ioi ld (TBM1R), a
ld a, (lsb_cval) ; get low byte value
ioi ld (TBL1R), a ; writing to low byte enables next interrupt
#endasm
}
}
#endif
#endif
/****** interrupt routine for external interrupt 0 ******/
#ifndef ONLY_TIMER
#ifdef FAST_EXT_INT
#asm root nodebug
my_isr::
push hl
ld hl,(count)
inc hl
ld (count),hl
.done:
pop hl
ipres ; restore interrupts
ret ; return
#endasm
#else
nodebug root interrupt void my_isr()
{
count++;
}
#endif
#endif