UART ISR doesn't run even when Interrupt is generated

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

UART ISR doesn't run even when Interrupt is generated

1,147 Views
ditishmaharjan
Contributor I

I wanted to try Embedded C++, so for starters I wanted to use UART. The code I wrote generates the Interrupt but the code never jumps to the ISR that i wrote. I rewrote the code removing all class declarations and all except that i saved and compiled my code as main.cpp. The code still doesn't work, but when i re-compiled it as main.c the code works. I don't know what to do to make it work in c++. Does anyone as any idea what to do >>>>


#include <lpc17xx.h>

static const uint8_t IER_RBR=0x01;
static const uint8_t IER_THRE=0x02;
static const uint8_t IER_RLS=0x04;

static const uint8_t IIR_PEND=0x01;
static const uint8_t IIR_RLS=0x03;
static const uint8_t IIR_RDA=0x02;
static const uint8_t IIR_CTI=0x06l;
static const uint8_t IIR_THRE=0x01;

static const uint8_t LSR_RDR=0x01;
static const uint8_t LSR_OE=0x02;
static const uint8_t LSR_PE=0x04;
static const uint8_t LSR_FE=0x08;
static const uint8_t LSR_BI=0x10;
static const uint8_t LSR_THRE=0x20;
static const uint8_t LSR_TEMT=0x40;
static const uint8_t LSR_RXFE=0x80;

char ch;
int UART0Status, UART1Status;


#ifdef __cplusplus
extern "C"{
#endif

void UART_IRQHandler(void)
{

uint8_t IIRValue, LSRValue;
uint8_t Dummy = Dummy;

IIRValue = LPC_UART1->IIR;

IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if ( IIRValue == IIR_RLS ) /* Receive Line Status */
{
LSRValue = LPC_UART1->LSR;
/* Receive Line Status */
if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
{
/* There are errors or break interrupt */
/* Read LSR will clear the interrupt */
UART1Status = LSRValue;
Dummy = LPC_UART1->RBR; /* Dummy read on RX to clear
interrupt, then bail out */
return;
}
if ( LSRValue & LSR_RDR ) /* Receive Data Ready */
{
/* If no error on RLS, normal ready, save into the data buffer. */
/* Note: read RBR will clear the interrupt */
while(!(LPC_UART1->LSR & (1<<0)));
ch=LPC_UART1->RBR;
while(!(LPC_UART1->LSR & (1<<5)));
LPC_UART1->THR=ch;
}
}
else if ( IIRValue == IIR_RDA ) /* Receive Data Available */
{
/* Receive Data Available */
while(!(LPC_UART1->LSR & (1<<0)));
ch=LPC_UART1->RBR;
while(!(LPC_UART1->LSR & (1<<5)));
LPC_UART1->THR=ch;
}
else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */
{
/* Character Time-out indicator */
UART1Status |= 0x100; /* Bit 9 as the CTI error */
}
else if ( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */
{
/* THRE interrupt */
LSRValue = LPC_UART1->LSR; /* Check status in the LSR to see if
valid data in U0THR or not */
if ( LSRValue & LSR_THRE )
{
//UART1TxEmpty = 1;
}
else
{
// UART1TxEmpty = 0;
}
}

}
#ifdef __cplusplus
}
#endif


int main()
{
int pclk,Fdiv;
int baudrate=9600;
char ch;

//POWERING UP UART1
LPC_SC->PCONP |=(1<<4);

//PHERIPHERAL CLOCK SELECTION
LPC_SC->PCLKSEL0 &= ~(3<<8); //MASKING
LPC_SC->PCLKSEL0 |= (0<<8); //PCLK = CCLK/4
pclk = SystemCoreClock / 4;

//Set P2.0 as TXD1 and set P2.1 as RXD1
LPC_PINCON->PINSEL4 &= ~(0x3); //MASKING
LPC_PINCON->PINSEL4 |= (2<<0); //TXD1

LPC_PINCON->PINSEL4 &= ~(0xC); //MASKING
LPC_PINCON->PINSEL4 |= (2<<2); //RXD1

//INITIALIZATION
LPC_UART1->LCR = 0x83; //8N1, DLAB=1
Fdiv = (pclk/16) / baudrate;
LPC_UART1->DLM = Fdiv / 256;
LPC_UART1->DLL = Fdiv % 256;
LPC_UART1->LCR = 0x03; //8N1, DLAB=0
LPC_UART1->FCR |= 0x07;//(1 << 0) | (1 << 1) | (1 << 2); //FIFO EN, RX/TX FIFO RESET

//ENABLE INTERRUPT


LPC_UART1->IER = IER_RBR | IER_THRE | IER_RLS; //Enable UART1 Interrupt RBR,THRE,RLS
NVIC_SetPriority(UART1_IRQn, 6);
NVIC_EnableIRQ(UART1_IRQn);

while(1)
{

}
}

0 Kudos
Reply
1 Reply

584 Views
avt
Contributor III

I would suggest you look at your 'extern "C"'. given that it works when compiled with C, implies that your IRQ handler is being name-mangled. You can confirm by looking in the linker map.

0 Kudos
Reply