This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM9 Serial Interrupt

Gentlemen(Ladies):

I'm working on serial port routines for the ST Microelectronics STR912FW44 ARM9 part. I've taken and written some crude, but useful, serial port code for transmitting chars from UART0 (COM1). Now I'm trying to handle reception of characters in a serial ISR.

I've modelled my code after working routines for the ADC and Timer1 (both of which worked) and I figured that would be a good starting point. The relevant (I think) code appears in three places in the code below.

First is the general UART0 setup:

UART0->IMSC= 0x010;

Second is the installation of the IRQ handler:

VIC1->VAiR[0]=(unsigned int)UART0_IRQ_Handler;    /* Specify handerl in IRQ.C */
  VIC1->VCiR[0]|=0x20;              /* Enable the vector interrupt      */
  VIC1->VCiR[0]|=0;                 /* Specify the interrupt number     */
  VIC1->INTER |=(1<<0);             /* Enable UART0 interrupt on VIC1          */

And Finally, the interrupt handler itself:

__irq void UART0_IRQ_Handler (void) {    /* UART0 interrupt routine       */

c=UART0->DR;  // Read the Character from the UART0->DR
  if(UART0->RSECR==0)      // Read the Status from the UART0->UART_RSECR
  {
     char_recvd_flag=1;    //we received a char...Toggle global rcvd_char variable
     UART0->ICR|=0x10;     //clear the Rx interrupt
  }

  VIC0->VAR = 0;                        /* Acknowledge Interrupt              */
  VIC1->VAR = 0;
}

What should happen (er what I WANT to happen) is for the received character to be echoed back after being received. What happens is nothing! But for the life of me, I can't figure out why. It's got to be the way I'm setting up the IRQ handler. Any thoughts would be greatly appreciated. The complete code follows. Best Regards, -=Rich=-

//***********************************************************************

#include <91x_lib.h>
#include "LCD.h"
int sendchar(int ch);
int retval;
char c='\0';                /* character received in UART0 ISR */
extern int char_recvd_flag;
extern __irq void UART0_IRQ_Handler (void);

void wait (void){   /* Wait function                    */
  long d=950000L;   /* 950,000 gives a delay of about 1 sec. */
  while (d--);      /* Only to delay for LED flashes    */
}
int main (void) {
  unsigned int i;

  /* General Purpose I/O Port 7 Setup ..............................*/
  SCU->GPIOOUT[7]  = 0x5555;    /* P7.0..7 output - mode 1          */
  GPIO7->DDR       = 0xFF;      /* P7.0..7 Outputs (LED Data)       */

  /* LCD Setup......................................................*/
  GPIO8->DDR       = 0xFF;      /* P8.0..7 Outputs (LCD Data)       */
  GPIO9->DDR       = 0x07;      /* P9.0..2 Outputs (LCD Control)    */

 /* UART0 Setup.....................................................*/

   SCU->GPIOOUT[3] &= 0xFFF3;   /* Enable UART0_TX (COM1) connected to P3.1  */
                                /* by setting bits 3 & 2 to 0 first */
   SCU->GPIOOUT[3] |= 0x0008;   /* then by setting bit 3 to 1  */
                                                                /* this sets GPIOOUT[3] to "Alternate Output 2" */
                                /* see page 78 of ST Microelectronics Document */
                                /* UM0216 (12126.pdf) for info on this register */
                                /* see page 39 of ST Microelectronics 12274.pdf- */
                                /* STR91xF Data Sheet for information on alternate */
                                /* pin functions */

   SCU->GPIOIN[3]  |= 0x01;          /* Enable UART0_RX (COM1) connected to P3.0             */
                                                                /* by setting bit 0 to 1                                */
                                                                /* this sets GPIOIN[3] to "Alternate Input 1" */

                                /* Baud rate integer and fractional divisors were */
                                /* calculated based on the Baud Rate Clock being */
                                /* set to fMSTR (as opposed to fMSTR/2).         */

   UART0->IBRD = 0x1A;          /* Integer divider for 115kBaud */
   UART0->FBRD = 0x03;          /* Fractional divider           */
   UART0->LCR  = 0x0060;        /* 8 bits, no Parity, 1 Stop bit, FIFO disabled */
   UART0->CR   = 0x0301;        /* Enable UART, Receive Enable, Transmit Enable */
   UART0->IMSC= 0x010;      /* Enable Rx Interrupt Mask Set/Clear Register */

  lcd_init();
  lcd_clear();
  lcd_print (" Serial_IRQ.C  ");      /* this line of code works as expected */
  set_cursor (0, 1);
  lcd_print (" October 15, 2006  "); /* this line of code works as expected*/

  /* Configure and enable IRQ for UART0....................................*/
  VIC1->VAiR[0]=(unsigned int)UART0_IRQ_Handler;    /* Specify handerl in IRQ.C */
  VIC1->VCiR[0]|=0x20;              /* Enable the vector interrupt      */
  VIC1->VCiR[0]|=0;                 /* Specify the interrupt number     */
  VIC1->INTER |=(1<<0);             /* Enable UART0 interrupt on VIC1          */


  retval=sendchar('A');             /* This function returns */
  if(char_recvd_flag)
  retval=sendchar(c);               /* echo back the received character */

  for (i = 0; i < 5; i++) wait();    /* Wait for initial display         */
  while (1) {                        /* Loop forever                     */
      int n=0;
      for(n=0x01;n<=0xFF;n<<=1)             /* scroll thru all eight LEDS                */
          {
          GPIO7->DR[0x3FC] = n;          /* Turn on LED ...this code works   */
      wait();                        /* Delay                            */
          retval=sendchar('A');              /* This function returns */
      }
  }

}

int sendchar (int ch)  {
   /* This code works as expected */

   if (ch == '\n')  {
      while (!(UART0->FR & 0x0080));
      UART0->DR = '\r';
   }
   while (!(UART0->FR & 0x0080));
   return(UART0->DR = ch);

}


0