0

I am able to use interrupts generated by the timer and by the UART the way I expect to be able to use them when they are used individually (that is, the timer is able to activate the interrupt subroutine when it is used on its own, and the UART is able to activate the interrupt subroutine when used by itself), but it seems that after the UART generates an interrupt (indicating that the write buffer is clear), then the timer interrupt stops working; if I enable both the UART and the timer to generate interrupts, the timer will not send the program into the interrupt subroutine after one or two periods. I have code that is supposed to send a message using the UART periodically- sending a message from a circular buffer whenever the timer countdown reaches zero:

/*
 * Main.c
 *
 *
 *
 *      clock: 12 megahertz
 */

#include "io_lib.h"
#include "configuregpio.h"
#include "my_uart_library.h"

/* Debug mode definition -- changed 'NO interrupt' to 4 instead of 0 */
#define WITH_TIMER_INT      0x01
#define WITH_UART_INT       0x02
#define WITHOUT_INT         0x04

#define DEBUG_MODE      3   /* 0 Error - should not use */
                            /* 1 Debugging with Timer Interrupt */
                            /* 2 Debugging with UART Interrupt */
                            /* 3 Debugging with Timer & UART Interrupt */
                            /* 4 Debugging without all interrupt */

/* 2.1 Timer Operating Counter - utilized either by interrupt or polling */
volatile unsigned int timercounter = 0;
unsigned int previouscounter = 0;

/* 2.2 Timer Operating Counter - utilized only at polling */
unsigned int timervalue;

/* 3. Pending Interrupt Status - RxRDY, TxRDY, Timer interrupt */
/*  - similar reason, two variables are defined for polling and interrupt use */
unsigned int irqStatusP;  /* Polling or normal routine use */
unsigned int irqStatusI;  /* interrupt use only */



/*** 5.x Following variables are defined as temporary purpose.  Normally they are not utilized */
unsigned int firstDigit, secondDigit, thirdDigit;
unsigned int tempBCD;

static char frameNo = 0;//0-99
static char counter = 0;
static int i = 0;
static char frameNumber[2];
char frameNoString[50] = "Minor cycle ";

unsigned char x;
unsigned int    datax;
/**** end of 5.x ** *******************************/

/* 6. Interrupt Service Routine for 8051 CPU's IRQ0 */
void INT0_IRQHandler(void) __interrupt (0) __using (1) //Changing "using" parameter will produce offset in
//irq handler addresses because a "different register" bank will be used.
{
    //disable all interrupts while this is being handled
  irqStatusI = inport8 (IRQ_Status);

#if DEBUG_MODE & WITH_UART_INT




#endif

#if (DEBUG_MODE & WITH_TIMER_INT)
    if ( (irqStatusI & IRQ_SRC2) != 0 ) /* IRQ Source 2 (Timer) has interrupted */
    {

        //incriment timer counter.  This will make it not equal to previous timer counter in main.
        timercounter ++;
        outport16(GPIO_OUT, timercounter);
        ClearTimerInterrupt();


    }

#endif

}

// Main code
int main(void)
{
    /* for debugging, initialize the Tx/Rx Buffer */
    timercounter=0;




    // configure GPIO
    configuregpio();

    //Turn on every LED bit. to test the GPIO
    outport8(GPIO_OUT, 0x0);
    outport16(GPIO_OUT, 0x0);

    /* To make sure of no interrupt before initiating UART/TIMER, */
    /*  all of the possible interrupt sources are cleared */
    /* a. clear all possible pending interrupt at the interrupt controller */
    outport16(FIQ_CLEAR, 0xFFFF);
    outport16(IRQ_CLEAR, 0xFFFF);
    /* b. clear possible pending interrupt at the timer */
    ClearTimerInterrupt();
    /* c. clear possible pending interrupt at the UART */
    inport8(StatusRegister);    /* reading status register of UART */

    /* Configure UART */
    configure_uart();
    //we need to read status register at the end of configuration.
    //tx ready signal may automatically generate.  To remove it we need to read uart status register once.


    //timer configure
    Set100msTimer(); /* setup timer 100 milli-second *///when timer is off interrupt 2 when on 6
    ClearTimerInterrupt();    /* added to prevent 'false' interrupt by the Timer */
    EnableTimer();
    ClearTimerInterrupt();    /* added to prevent 'false' interrupt by the Timer */

    /* Before Initializing Interrupt Controller, clear them */
    outport16(FIQ_CLEAR, 0xFFFF);
    outport16(IRQ_CLEAR, 0xFFFF);

    //This is enabling IRQ sources of the interrupt controller.
    //  IRQ Source 0 : RxRDY
    //  IRQ Source 1 : TxRDY
    //  IRQ Source 2 : Timer
    /* Combine those three macros whenever want to intiate their own interrupt */



#if DEBUG_MODE  == (WITH_TIMER_INT | WITH_UART_INT)
    outport16(IRQ_Enable_Reg, ( /*IRQ_SRC0 | */IRQ_SRC1 |IRQ_SRC2 ));  // all interrupt
#endif

#if (DEBUG_MODE & WITH_TIMER_INT) | (DEBUG_MODE & WITH_UART_INT)
    /* enable 8051 interrupt */
    set8051_interrupt_type();
    enable8051_interrupts();
#endif


    while (1)
    {



        /* for debugging, following strings have added to the Tx Buffer to transmit */
        if (timercounter != previouscounter)
        {
            previouscounter = timercounter;


        }

    }   /* end of while (1) */

}
Michael Kossin
  • 342
  • 3
  • 14
  • That's a lot of code to sift through. Can you narrow it down to the smallest representation of the problem you're having? – Baratong Jul 29 '13 at 23:13
  • Alright, I've taken out all but the essentials. – Michael Kossin Jul 29 '13 at 23:59
  • Hmm, well nothing jumps out at me here. Since you are using the external interrupt (INT0), and not using the internal UART and Timer interrupts (which would trap in interrupt 4 (uart0), and T0 on interrupt 1, or T1 on interrupt 3, it's difficult to tell if there isn't a hardware issue here as well. A couple questions though.. 1.Which MCU variant (if any) are you using? 2. Can you switch to use the internal interrupt vectors instead? (thereby removing any external hardware as a potential source of the problem?) – Baratong Jul 30 '13 at 18:50
  • We are using Actel/Microsemi flash-type FPGA and Core8051s module implemented inside an FPGA. The original 8051 has an internal timer but we're using core 8051s, made by ACTEL/Microsemi, which does not have an internal interrupt controller, timers, or UART. We use an external interrupt controller, external UART, and external timer which we have interfaced with the 8051 through APB3 Core. Through this interface, we are able to use them like the original 8051 resource. Only one interrupt signal is connected to the IRQ0 but it can be triggered by both the timer and the UART. – Michael Kossin Jul 30 '13 at 19:30

0 Answers0