Uart interrupts

Hello,

I am trying to use UART interrupts to get a message from a SM5100 cell module. I am able to receive one character, but when the interrupt function runs it returns to the beginning of the program which resets my counter (message_index) and doesn’t let me get an array longer than 1 character long.

I am using winarm to compile and the logomatic which has a lpc2148 and the sparkfun bootloader.

My IRQ function is below:

void IRQ_Routine(void) {
   char val = (char)U0RBR;
        if(val=='\n') {    //Newline means the current message is complete
      message[message_index] = val;
      message_complete = 1;               //Set a flag for the main FW
      message_index=0;
   }
   else{      
      message[message_index] = val;
      message_index=message_index + 1;
      message_complete = 0;
   }
       T0IR = 0x01;                //clear interrupt
       VICVectAddr = 0; //end of interrupt      
   }

My initialize is:

void init(void) {
/* Initialize Uart0 Block for Tx and Rx */
   PINSEL0=0x00050005;//Enable Uart0
   U0LCR=0x83;//8 bits, no parity, 1 stop bit, DLAB=1
   U0DLM=0x00;
   U0DLL=0x20; //115200 Baud rate
   U0FCR = 0x07;         //enable & clear FIFOs
   U0LCR=0x3; //DLAB=0
   rprintf_devopen(putc_serial0); //Open Serial port 0
   
   /* Initialize Uart1 Block for Tx and Rx */
   PINSEL1=0x00050000;//Enable Uart0
   U1LCR=0x83;//8 bits, no parity, 1 stop bit, DLAB=1
   U1DLM=0x00;
   U1DLL=0x20; //115200 Baud rate
   U1FCR= 0x01;
   U1LCR=0x03; //DLAB=0
   /*Set output for GPIO pins*/
   IODIR0 |= RED_LED | GREEN_LED;   //Set the Red, Green and Blue LED pins as outputs
   IOSET0 = RED_LED | GREEN_LED;   //Initially turn all of the LED's off
   
   /* Interrupt*/
   U0IER = 0x01; // enable RDA interrupt
   VICProtection = 0; // disable protection
   VICIntSelect &= 0xFFFFFFBF; // IRQ
   VICVectAddr0 = (unsigned)IRQ_Routine;
   VICVectCntl0 = 0x20 | 6;
   VICIntEnable = 0x00000040; // enable
    enableIRQ();   
}

Any help as to how to return to the main function after the interrupt has run would be greatly appreciated.

Here is the code I use:

//------------------------ UART1 ISR ------------------------//
static void uart1ISR(void)
{
  /* Read IIR to clear interrupt and find out the cause */
  unsigned iir = U1IIR;

  /* Handle UART1 interrupt */
  switch ((iir >> 1) & 0x7)
    {
      case 1:
        /* THRE interrupt */
        break;
      case 2:
        /* RDA interrupt */
        do
          {
          uint16_t temp;

          // calc next insert index & store character
          temp = (uart1_rx_insert_idx + 1) % UART1_RX_BUFFER_SIZE;
          uart1_rx_buffer[uart1_rx_insert_idx] = U1RBR;

          // check for more room in queue
          if (temp != uart1_rx_extract_idx)
            uart1_rx_insert_idx = temp; // update insert index
          }
        while (U1LSR & 0x01);

        break;
      case 3:
        /* RLS interrupt */
        break;
      case 6:
        /* CTI interrupt */
        break;
   }
}

/* Description:  
 *    This function gets a character from the UART1 receive queue
 *
 * Calling Sequence: 
 *    void
 *
 * Returns:
 *    character on success, -1 if no character is available
 *
 *****************************************************************************/
int uart1Getch(void)
{
  uint8_t ch;

  if (uart1_rx_insert_idx == uart1_rx_extract_idx) // check if character is available
    return -1;

  ch = uart1_rx_buffer[uart1_rx_extract_idx++]; // get character, bump pointer
  uart1_rx_extract_idx %= UART1_RX_BUFFER_SIZE; // limit the pointer
  return ch;
}

Here is the initialisation code:

 // initialise UART1 (RxD1 P0.9, TxD1 P0.8

  U1LCR = 0x83; // 8 bit, 1 stop bit, no parity, enable DLAB
  U1DLL = 0xC3; // set for 9600 baud
  U1DLM = 0x00;
  U1LCR &= ~0x80; // disable DLAB
  U1FCR = 1;      // enable FIFO
  PINSEL0 = PINSEL0 & ~(0xFFFF << 16) | (0x5555 << 16);

// Setup UART1 RX interrupt
  ctl_set_isr(7, 1, CTL_ISR_TRIGGER_FIXED, uart1ISR, 0);
  ctl_unmask_isr(7);
  U1IER = 1;

I used CrossWorks CTL functions to set up the interrupts, you will have to do it the hard way.

A circular buffer is used to store the incoming data.

Most of the above came from the LPC2000 Yahoo group Files section.