lpcware

UART receive complete interrupt is not working with Watchdog oscillator in powerdown mode

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by mahendra_ms on Thu Dec 10 02:04:42 MST 2015
Hello freaks!
I'm using lpcxpresso board with LPC11u24 target
before facing this problem I've try with demo code provided for lpcxpresso board library which seem good as i'm able to transmit and receive the data string for my desired baudrate.

But right now for my low power application I'm using watchdog as main oscillator in power down mode but with WDT osc. i can transmit the data trough UART but receive complete interrupt is not working.

my wdt_osc=4.6 Mhz, Div=2
systemclock =2.3Mhz

Here is the code for wdt osc.



void Board_SystemInit(void)
{
/* Setup system clocking and muxing */
SystemSetupMuxing();
SystemSetupClocking();
}

//-------------------------------------------------------------------------------

STATIC void SystemSetupMuxing(void)
{
LPC_SYSCTL->SYSAHBCLKCTRL |= (1<<16);                                   //Enable clock FOR IO config. block
LPC_IOCON->PIO0[0] = IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN; // RESET pin
LPC_IOCON->PIO0[1] = IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_DIGMODE_EN;// ISP pin
LPC_IOCON->PIO0[3] = IOCON_FUNC0 | IOCON_MODE_PULLDOWN | IOCON_DIGMODE_EN; // GPIO ... will be VBUS when USB enabled
LPC_IOCON->PIO0[4] = IOCON_FUNC1 | IOCON_DIGMODE_EN;// I2C standard mode
LPC_IOCON->PIO0[5] = IOCON_FUNC1 | IOCON_DIGMODE_EN;    // I2C standard mode
LPC_IOCON->PIO0[6] = IOCON_FUNC0 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN;  // GPIO ... will be USB_CONNECT when USB enabled
LPC_IOCON->PIO0[7] = IOCON_FUNC0 | IOCON_OPENDRAIN_EN | IOCON_MODE_INACT | IOCON_DIGMODE_EN; // RED LED
LPC_IOCON->PIO0[8] = IOCON_FUNC0 | IOCON_OPENDRAIN_EN | IOCON_MODE_INACT | IOCON_DIGMODE_EN; // GREEN LED
LPC_IOCON->PIO0[9] = IOCON_FUNC0 | IOCON_OPENDRAIN_EN | IOCON_MODE_INACT | IOCON_DIGMODE_EN; // BLUE LED

LPC_IOCON->PIO0[12] = IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN;  // SW1
LPC_IOCON->PIO0[13] = IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN;  // SW2
LPC_IOCON->PIO0[14] = IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN;  // SW3
LPC_IOCON->PIO0[16] = IOCON_FUNC1 | IOCON_ADMODE_EN   | IOCON_MODE_INACT | IOCON_FILT_DIS;  // Reference voltage: AD5
LPC_IOCON->PIO0[23] = IOCON_FUNC0 | IOCON_DIGMODE_EN  | IOCON_MODE_INACT;  // VCC_SW
LPC_IOCON->PIO1[19] = IOCON_FUNC0 | IOCON_MODE_PULLUP | IOCON_DIGMODE_EN  | IOCON_MODE_INACT;  // FD input
}

//-----------------------------------------------------------------------------------------------------------------------

STATIC void SystemSetupClocking(void)
{

#ifdef WDO
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_WDTOSC_PD);       //(1<<6) WDTOSC_PD watchdog osc power down
LPC_SYSCTL->SYSAHBCLKCTRL |= (1<<15);        // enable clock to WDT block
Chip_Clock_SetWDTOSC(WDTLFO_OSC_4_60, 2); 
LPC_WWDT->CLKSEL |= (1<<0);          // select watchdog oscillator   0=1 WDOSC  0==0 IRC
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_WDTOSC);

//#else  /* the IRC is enabled by default */
//Chip_Clock_SetSysClockDiv(1);
#endif

Chip_FMC_SetFLASHAccess(FLASHTIM_20MHZ_CPU);
SystemCoreClockUpdate();
}






UART code which is being provided in lpcxpresso board examples



/*****************************************************************************
** Function name:UARTInit
**
** Descriptions:Initialize UART0 port, setup pin select,
**clock, parity, stop bits, FIFO, etc.
**
** parameters:UART baudrate
** Returned value:None
**
*****************************************************************************/
void UARTInit(uint32_t baudrate)
{
#if !AUTOBAUD_ENABLE
  uint32_t Fdiv;
#endif
  volatile uint32_t regVal;
  UARTTxEmpty = 1;
  UARTCount = 0;

  NVIC_DisableIRQ(UART_IRQn);
  /* Select only one location from below. */
#if 1
  LPC_IOCON->PIO0_18 &= ~0x07;    /*  UART I/O config */
  LPC_IOCON->PIO0_18 |= 0x01;     /* UART RXD */
  LPC_IOCON->PIO0_19 &= ~0x07;
  LPC_IOCON->PIO0_19 |= 0x01;     /* UART TXD */
#endif
#if 0
  LPC_IOCON->PIO1_14 &= ~0x07;    /*  UART I/O config */
  LPC_IOCON->PIO1_14 |= 0x03;     /* UART RXD */
  LPC_IOCON->PIO1_13 &= ~0x07;
  LPC_IOCON->PIO1_13 |= 0x03;     /* UART TXD */
#endif
#if 0
  LPC_IOCON->PIO1_17 &= ~0x07;    /*  UART I/O config */
  LPC_IOCON->PIO1_17 |= 0x02;     /* UART RXD */
  LPC_IOCON->PIO1_18 &= ~0x07;
  LPC_IOCON->PIO1_18 |= 0x02;     /* UART TXD */
#endif
#if 0
  LPC_IOCON->PIO1_26 &= ~0x07;    /*  UART I/O config */
  LPC_IOCON->PIO1_26 |= 0x02;     /* UART RXD */
  LPC_IOCON->PIO1_27 &= ~0x07;
  LPC_IOCON->PIO1_27 |= 0x02;     /* UART TXD */
#endif

  /* Enable UART clock */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
  LPC_SYSCON->UARTCLKDIV = 0x1;     /* divided by 1 */

  LPC_USART->LCR = 0x83;            /* 8 bits, no Parity, 1 Stop bit */
#if !AUTOBAUD_ENABLE
#if FDR_CALIBRATION
if ( uart_set_divisors(SystemCoreClock/LPC_SYSCON->UARTCLKDIV, baudrate) != TRUE )
{
      Fdiv = ((SystemCoreClock/LPC_SYSCON->UARTCLKDIV)/16)/baudrate ;/*baud rate */
      LPC_USART->DLM = Fdiv / 256;
      LPC_USART->DLL = Fdiv % 256;
  LPC_USART->FDR = 0x10;/* Default */
}
#else
    Fdiv = ((SystemCoreClock/LPC_SYSCON->UARTCLKDIV)/16)/baudrate ;/*baud rate */
    LPC_USART->DLM = Fdiv / 256;
    LPC_USART->DLL = Fdiv % 256;
LPC_USART->FDR = 0x10;/* Default */
#endif
#endif
  LPC_USART->LCR = 0x03;/* DLAB = 0 */
  LPC_USART->FCR = 0x07;/* Enable and reset TX and RX FIFO. */

  /* Read to clear the line status. */
  regVal = LPC_USART->LSR;

  /* Ensure a clean start, no data in either TX or RX FIFO. */
  while (( LPC_USART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
  while ( LPC_USART->LSR & LSR_RDR )
  {
regVal = LPC_USART->RBR;/* Dump data from RX FIFO */
  }

  /* Enable the UART Interrupt */
  NVIC_EnableIRQ(UART_IRQn);

#if TX_INTERRUPT
  LPC_USART->IER = IER_RBR | IER_THRE | IER_RLS;/* Enable UART interrupt */
#else
  LPC_USART->IER = IER_RBR | IER_RLS;/* Enable UART interrupt */
#endif
#if AUTOBAUD_ENABLE
    LPC_USART->IER |= IER_ABEO | IER_ABTO;
#endif
  return;
}



uart IRQ handler is..


*****************************************************************************/
void UART_IRQHandler(void)
{
  uint8_t IIRValue, LSRValue;
  uint8_t Dummy = Dummy;

  IIRValue = LPC_USART->IIR;
  IIRValue >>= 1;/* skip pending bit in IIR */
  IIRValue &= 0x07;/* check bit 1~3, interrupt identification */
  if (IIRValue == IIR_RLS)/* Receive Line Status */    //(if interrupt is Available for line status)
  {
    LSRValue = LPC_USART->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 */
      UARTStatus = LSRValue;
      Dummy = LPC_USART->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 */
      UARTBuffer[UARTCount++] = LPC_USART->RBR;
      if (UARTCount == BUFSIZE)
      {
        UARTCount = 0;/* buffer overflow */
      }
    }
  }

  else if (IIRValue == IIR_RDA)/* Receive Data Available *****************///(Receive complate interrupt)
  {
    /* Receive Data Available */
     data[count]=LPC_USART->RBR;
if( data[count]=='\n')
{
data[count]=NULL;
count=0;
print_string(data);
print_string("\r\n");
}
else
{
count++;
}
  }
  else if (IIRValue == IIR_CTI)/* Character timeout indicator */
  {
                                /* Character Time-out indicator */
    UARTStatus |= 0x100;/* Bit 9 as the CTI error */
  }
  else if (IIRValue == IIR_THRE)/* THRE, transmit holding register empty *************///(interrupt for transmit buff Empty)
  {
    /* THRE interrupt */
    LSRValue = LPC_USART->LSR;/* Check status in the LSR to see if
valid data in U0THR or not */
    if (LSRValue & LSR_THRE)
    {
      UARTTxEmpty = 1;              //if tx buffer is Empty then set the flag!
    }
    else
    {
      UARTTxEmpty = 0;
    }
  }
#if AUTOBAUD_ENABLE
  if (LPC_USART->IIR & IIR_ABEO) /* End of Auto baud */
  {
LPC_USART->IER &= ~IIR_ABEO;
/* clear bit ABEOInt in the IIR by set ABEOIntClr in the ACR register */
LPC_USART->ACR |= IIR_ABEO;
UARTAutoBaud = 1;
  }
  else if (LPC_USART->IIR & IIR_ABTO)/* Auto baud time out */
  {
LPC_USART->IER &= ~IIR_ABTO;
AutoBaudTimeout = 1;
/* clear bit ABTOInt in the IIR by set ABTOIntClr in the ACR register */
LPC_USART->ACR |= IIR_ABTO;
  }
#endif
  return;
}




I expect help from the forum
Thanks and Regards,
Mahendra Sondagar

Outcomes