move mcu cmsis file to /mcu

This commit is contained in:
hathach
2014-03-12 17:20:24 +07:00
parent d98bc0a64b
commit 8db8294af2
190 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
/******************************************************************************/
/* SERIAL.C: Low Level Serial Routines */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/
#include "LPC13Uxx.h" /* LPC13Uxx definitions */
#include "uart.h"
#define CR 0x0D
/* implementation of putchar (also used by printf function to output data) */
int sendchar (int ch) { /* Write character to Serial Port */
if (ch == '\n') {
while (!(LPC_USART->LSR & 0x20));
LPC_USART->THR = CR; /* output CR */
}
while (!(LPC_USART->LSR & 0x20));
return (LPC_USART->THR = ch);
}
int getkey (void) { /* Read character from Serial Port */
while (!(LPC_USART->LSR & 0x01));
return (LPC_USART->RBR);
}

View File

@@ -0,0 +1,69 @@
/****************************************************************************
* $Id:: clkconfig.c 6874 2011-03-22 01:58:31Z usb00423 $
* Project: NXP LPC13Uxx Clock Configuration example
*
* Description:
* This file contains clock configuration code example which include
* watchdog setup and debug clock out setup.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC13Uxx.h"
#include "clkconfig.h"
/*****************************************************************************
** Function name: WDT_CLK_Setup
**
** Descriptions: Configure WDT clock.
** parameters: clock source: irc_osc(0), main_clk(1), wdt_osc(2).
**
** Returned value: None
**
*****************************************************************************/
void WDT_CLK_Setup ( uint32_t clksrc )
{
/* Freq = 0.5Mhz, div_sel is 0x1F, divided by 64. WDT_OSC should be 7.8125khz */
LPC_SYSCON->WDTOSCCTRL = (0x1<<5)|0x1F;
LPC_SYSCON->PDRUNCFG &= ~(0x1<<6); /* Let WDT clock run */
/* Enables clock for WDT */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15);
LPC_WWDT->CLKSEL = clksrc; /* Select clock source */
return;
}
/*****************************************************************************
** Function name: CLKOUT_Setup
**
** Descriptions: Configure CLKOUT for reference clock check.
** parameters: clock source: irc_osc(0), sys_osc(1), wdt_osc(2),
** main_clk(3).
**
** Returned value: None
**
*****************************************************************************/
void CLKOUT_Setup ( uint32_t clksrc )
{
/* debug PLL after configuration. */
LPC_SYSCON->CLKOUTSEL = clksrc; /* Select Main clock */
LPC_SYSCON->CLKOUTDIV = 1; /* Divided by 1 */
return;
}

View File

@@ -0,0 +1,838 @@
/****************************************************************************
* $Id:: gpio.c 6874 2011-03-22 01:58:31Z usb00423 $
* Project: NXP LPC13Uxx GPIO example
*
* Description:
* This file contains GPIO code example which include GPIO
* initialization, GPIO interrupt handler, and related APIs for
* GPIO access.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC13Uxx.h" /* LPC13Uxx Peripheral Registers */
#include "gpio.h"
volatile uint32_t pin_int0_counter = 0;
volatile uint32_t pin_int1_counter = 0;
volatile uint32_t pin_int2_counter = 0;
volatile uint32_t pin_int3_counter = 0;
volatile uint32_t pin_int4_counter = 0;
volatile uint32_t pin_int5_counter = 0;
volatile uint32_t pin_int6_counter = 0;
volatile uint32_t pin_int7_counter = 0;
volatile uint32_t gint0_counter = 0;
volatile uint32_t gint1_counter = 0;
volatile uint32_t pin_int0_level_counter = 0;
volatile uint32_t pin_int0_rising_edge_counter = 0;
volatile uint32_t pin_int0_falling_edge_counter = 0;
volatile uint32_t pin_int1_level_counter = 0;
volatile uint32_t pin_int1_rising_edge_counter = 0;
volatile uint32_t pin_int1_falling_edge_counter = 0;
volatile uint32_t pin_int2_level_counter = 0;
volatile uint32_t pin_int2_rising_edge_counter = 0;
volatile uint32_t pin_int2_falling_edge_counter = 0;
volatile uint32_t pin_int3_level_counter = 0;
volatile uint32_t pin_int3_rising_edge_counter = 0;
volatile uint32_t pin_int3_falling_edge_counter = 0;
volatile uint32_t pin_int4_level_counter = 0;
volatile uint32_t pin_int4_rising_edge_counter = 0;
volatile uint32_t pin_int4_falling_edge_counter = 0;
volatile uint32_t pin_int5_level_counter = 0;
volatile uint32_t pin_int5_rising_edge_counter = 0;
volatile uint32_t pin_int5_falling_edge_counter = 0;
volatile uint32_t pin_int6_level_counter = 0;
volatile uint32_t pin_int6_rising_edge_counter = 0;
volatile uint32_t pin_int6_falling_edge_counter = 0;
volatile uint32_t pin_int7_level_counter = 0;
volatile uint32_t pin_int7_rising_edge_counter = 0;
volatile uint32_t pin_int7_falling_edge_counter = 0;
volatile uint32_t gint0_level_counter = 0;
volatile uint32_t gint0_edge_counter = 0;
volatile uint32_t gint1_level_counter = 0;
volatile uint32_t gint1_edge_counter = 0;
/*****************************************************************************
** Function name: PIN_INT0_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT0_IRQHandler(void)
{
pin_int0_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<0) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<0) )
{
pin_int0_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<0) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<0) ) )
{
pin_int0_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<0;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<0) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<0) ) )
{
pin_int0_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<0;
}
LPC_GPIO_PIN_INT->IST = 0x1<<0;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT1_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT1_IRQHandler(void)
{
pin_int1_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<1) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<1) )
{
pin_int1_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<1) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<1) ) )
{
pin_int1_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<1;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<1) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<1) ) )
{
pin_int1_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<1;
}
LPC_GPIO_PIN_INT->IST = 0x1<<1;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT2_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT2_IRQHandler(void)
{
pin_int2_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<2) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<2) )
{
pin_int2_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<2) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<2) ) )
{
pin_int2_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<2;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<2) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<2) ) )
{
pin_int2_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<2;
}
LPC_GPIO_PIN_INT->IST = 0x1<<2;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT3_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT3_IRQHandler(void)
{
pin_int3_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<3) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<3) )
{
pin_int3_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<3) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<3) ) )
{
pin_int3_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<3;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<3) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<3) ) )
{
pin_int3_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<3;
}
LPC_GPIO_PIN_INT->IST = 0x1<<3;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT4_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT4_IRQHandler(void)
{
pin_int4_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<4) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<4) )
{
pin_int4_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<4) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<4) ) )
{
pin_int4_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<4;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<4) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<4) ) )
{
pin_int4_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<4;
}
LPC_GPIO_PIN_INT->IST = 0x1<<4;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT5_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT5_IRQHandler(void)
{
pin_int5_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<5) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<5) )
{
pin_int5_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<5) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<5) ) )
{
pin_int5_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<5;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<5) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<5) ) )
{
pin_int5_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<5;
}
LPC_GPIO_PIN_INT->IST = 0x1<<5;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT6_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT6_IRQHandler(void)
{
pin_int6_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<6) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<6) )
{
pin_int6_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<6) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<6) ) )
{
pin_int6_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<6;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<6) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<6) ) )
{
pin_int6_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<6;
}
LPC_GPIO_PIN_INT->IST = 0x1<<6;
}
}
return;
}
/*****************************************************************************
** Function name: PIN_INT7_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void PIN_INT7_IRQHandler(void)
{
pin_int7_counter++;
if ( LPC_GPIO_PIN_INT->IST & (0x1<<7) )
{
if ( LPC_GPIO_PIN_INT->ISEL & (0x1<<7) )
{
pin_int7_level_counter++;
}
else
{
if ( ( LPC_GPIO_PIN_INT->RISE & (0x1<<7) ) && ( LPC_GPIO_PIN_INT->IENR & (0x1<<7) ) )
{
pin_int7_rising_edge_counter++;
LPC_GPIO_PIN_INT->RISE = 0x1<<7;
}
if ( ( LPC_GPIO_PIN_INT->FALL & (0x1<<7) ) && ( LPC_GPIO_PIN_INT->IENF & (0x1<<7) ) )
{
pin_int7_falling_edge_counter++;
LPC_GPIO_PIN_INT->FALL = 0x1<<7;
}
LPC_GPIO_PIN_INT->IST = 0x1<<7;
}
}
return;
}
/*****************************************************************************
** Function name: GINT0_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void GINT0_IRQHandler(void)
{
gint0_counter++;
if ( LPC_GPIO_GROUP_INT0->CTRL & (0x1<<0) )
{
if ( LPC_GPIO_GROUP_INT0->CTRL & (0x1<<2) )
{
gint0_level_counter++;
}
else
{
gint0_edge_counter++;
}
LPC_GPIO_GROUP_INT0->CTRL |= (0x1<<0);
}
return;
}
/*****************************************************************************
** Function name: GINT1_IRQHandler
**
** Descriptions: Use one GPIO pin as interrupt source
**
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void GINT1_IRQHandler(void)
{
gint1_counter++;
if ( LPC_GPIO_GROUP_INT1->CTRL & (0x1<<0) )
{
if ( LPC_GPIO_GROUP_INT1->CTRL & (0x1<<2) )
{
gint1_level_counter++;
}
else
{
gint1_edge_counter++;
}
LPC_GPIO_GROUP_INT1->CTRL |= (0x1<<0);
}
return;
}
/*****************************************************************************
** Function name: GPIOInit
**
** Descriptions: Initialize GPIO, install the
** GPIO interrupt handler
**
** parameters: None
**
** Returned value: true or false, return false if the VIC table
** is full and GPIO interrupt handler can be
** installed.
**
*****************************************************************************/
void GPIOInit( void )
{
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
/* Enable AHB clock to the PinInt, GroupedInt domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= ((1<<19) | (1<<23) | (1<<24));
return;
}
/*****************************************************************************
** Function name: GPIOSetPinInterrupt
**
** Descriptions: Set interrupt sense, event, etc.
** sense: edge or level, 0 is edge, 1 is level
** event/polarity: 0 is active low/falling, 1 is high/rising.
**
** parameters: channel #, port #, bit position, sense, event(polarity)
**
** Returned value: None
**
*****************************************************************************/
void GPIOSetPinInterrupt( uint32_t channelNum, uint32_t portNum, uint32_t bitPosi,
uint32_t sense, uint32_t event )
{
switch ( channelNum )
{
case CHANNEL0:
if ( portNum )
{
LPC_SYSCON->PINSEL[0] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[0] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT0_IRQn);
break;
case CHANNEL1:
if ( portNum )
{
LPC_SYSCON->PINSEL[1] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[1] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT1_IRQn);
break;
case CHANNEL2:
if ( portNum )
{
LPC_SYSCON->PINSEL[2] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[2] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT2_IRQn);
break;
case CHANNEL3:
if ( portNum )
{
LPC_SYSCON->PINSEL[3] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[3] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT3_IRQn);
break;
case CHANNEL4:
if ( portNum )
{
LPC_SYSCON->PINSEL[4] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[4] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT4_IRQn);
break;
case CHANNEL5:
if ( portNum )
{
LPC_SYSCON->PINSEL[5] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[5] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT5_IRQn);
break;
case CHANNEL6:
if ( portNum )
{
LPC_SYSCON->PINSEL[6] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[6] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT6_IRQn);
break;
case CHANNEL7:
if ( portNum )
{
LPC_SYSCON->PINSEL[7] = bitPosi + 24;
}
else
{
LPC_SYSCON->PINSEL[7] = bitPosi;
}
NVIC_EnableIRQ(PIN_INT7_IRQn);
break;
default:
break;
}
if ( sense == 0 )
{
LPC_GPIO_PIN_INT->ISEL &= ~(0x1<<channelNum); /* Edge trigger */
if ( event == 0 )
{
LPC_GPIO_PIN_INT->IENF |= (0x1<<channelNum); /* faling edge */
}
else
{
LPC_GPIO_PIN_INT->IENR |= (0x1<<channelNum); /* Rising edge */
}
}
else
{
LPC_GPIO_PIN_INT->ISEL |= (0x1<<channelNum); /* Level trigger. */
LPC_GPIO_PIN_INT->IENR |= (0x1<<channelNum); /* Level enable */
if ( event == 0 )
{
LPC_GPIO_PIN_INT->IENF &= ~(0x1<<channelNum); /* active-low */
}
else
{
LPC_GPIO_PIN_INT->IENF |= (0x1<<channelNum); /* active-high */
}
}
return;
}
/*****************************************************************************
** Function name: GPIOPinIntEnable
**
** Descriptions: Enable Interrupt
**
** parameters: channel num, event(0 is falling edge, 1 is rising edge)
** Returned value: None
**
*****************************************************************************/
void GPIOPinIntEnable( uint32_t channelNum, uint32_t event )
{
if ( !( LPC_GPIO_PIN_INT->ISEL & (0x1<<channelNum) ) )
{
if ( event == 0 )
{
LPC_GPIO_PIN_INT->SIENF |= (0x1<<channelNum); /* faling edge */
}
else
{
LPC_GPIO_PIN_INT->SIENR |= (0x1<<channelNum); /* Rising edge */
}
}
else
{
LPC_GPIO_PIN_INT->SIENR |= (0x1<<channelNum); /* Level */
}
return;
}
/*****************************************************************************
** Function name: GPIOPinIntDisable
**
** Descriptions: Disable Interrupt
**
** parameters: channel num, event(0 is falling edge, 1 is rising edge)
**
** Returned value: None
**
*****************************************************************************/
void GPIOPinIntDisable( uint32_t channelNum, uint32_t event )
{
if ( !( LPC_GPIO_PIN_INT->ISEL & (0x1<<channelNum) ) )
{
if ( event == 0 )
{
LPC_GPIO_PIN_INT->CIENF |= (0x1<<channelNum); /* faling edge */
}
else
{
LPC_GPIO_PIN_INT->CIENR |= (0x1<<channelNum); /* Rising edge */
}
}
else
{
LPC_GPIO_PIN_INT->CIENR |= (0x1<<channelNum); /* Level */
}
return;
}
/*****************************************************************************
** Function name: GPIOPinIntStatus
**
** Descriptions: Get Interrupt status
**
** parameters: channel num
**
** Returned value: None
**
*****************************************************************************/
uint32_t GPIOPinIntStatus( uint32_t channelNum )
{
if ( LPC_GPIO_PIN_INT->IST & (0x1<<channelNum) )
{
return( 1 );
}
else
{
return( 0 );
}
}
/*****************************************************************************
** Function name: GPIOPinIntClear
**
** Descriptions: Clear Interrupt
**
** parameters: channel num
**
** Returned value: None
**
*****************************************************************************/
void GPIOPinIntClear( uint32_t channelNum )
{
if ( !( LPC_GPIO_PIN_INT->ISEL & (0x1<<channelNum) ) )
{
LPC_GPIO_PIN_INT->IST = (1<<channelNum);
}
return;
}
/*****************************************************************************
** Function name: GPIOSetGroupedInterrupt
**
** Descriptions: Set interrupt logic, sense, eventPattern, etc.
** logic: AND or OR, 0 is OR, 1 is AND
** sensePattern: edge or level, 0 is edge, 1 is level
** event/polarity: 0 is active low/falling, 1 is high/rising.
**
** parameters: group #, bit pattern, logic, sense, event(polarity) pattern
**
** Returned value: None
**
*****************************************************************************/
void GPIOSetGroupedInterrupt( uint32_t groupNum, uint32_t *bitPattern, uint32_t logic,
uint32_t sense, uint32_t *eventPattern )
{
switch ( groupNum )
{
case GROUP0:
if ( sense == 0 )
{
LPC_GPIO_GROUP_INT0->CTRL &= ~(0x1<<2); /* Edge trigger */
}
else
{
LPC_GPIO_GROUP_INT0->CTRL |= (0x1<<2); /* Level trigger. */
}
if ( logic == 0 )
{
LPC_GPIO_GROUP_INT0->CTRL &= ~(0x1<<1); /* OR */
}
else
{
LPC_GPIO_GROUP_INT0->CTRL |= (0x1<<1); /* AND */
}
LPC_GPIO_GROUP_INT0->PORT_POL[0] = *((uint32_t *)(eventPattern + 0));
LPC_GPIO_GROUP_INT0->PORT_POL[1] = *((uint32_t *)(eventPattern + 1));
LPC_GPIO_GROUP_INT0->PORT_ENA[0] = *((uint32_t *)(bitPattern + 0));
LPC_GPIO_GROUP_INT0->PORT_ENA[1] = *((uint32_t *)(bitPattern + 1));
/* as soon as enabled, an edge may be generated */
/* clear interrupt flag and NVIC pending interrupt to */
/* workaround the potential edge generated as enabled */
LPC_GPIO_GROUP_INT0->CTRL |= (1<<0);
NVIC_ClearPendingIRQ(GINT0_IRQn);
NVIC_EnableIRQ(GINT0_IRQn);
break;
case GROUP1:
if ( sense == 0 )
{
LPC_GPIO_GROUP_INT1->CTRL &= ~(0x1<<2); /* Edge trigger */
}
else
{
LPC_GPIO_GROUP_INT1->CTRL |= (0x1<<2); /* Level trigger. */
}
if ( logic == 0 )
{
LPC_GPIO_GROUP_INT1->CTRL &= ~(0x1<<1); /* OR */
}
else
{
LPC_GPIO_GROUP_INT1->CTRL |= (0x1<<1); /* AND */
}
LPC_GPIO_GROUP_INT1->PORT_POL[0] = *((uint32_t *)(eventPattern + 0));
LPC_GPIO_GROUP_INT1->PORT_POL[1] = *((uint32_t *)(eventPattern + 1));
LPC_GPIO_GROUP_INT1->PORT_ENA[0] = *((uint32_t *)(bitPattern + 0));
LPC_GPIO_GROUP_INT1->PORT_ENA[1] = *((uint32_t *)(bitPattern + 1));
/* as soon as enabled, an edge may be generated */
/* clear interrupt flag and NVIC pending interrupt to */
/* workaround the potential edge generated as enabled */
LPC_GPIO_GROUP_INT1->CTRL |= (1<<0);
NVIC_ClearPendingIRQ(GINT1_IRQn);
NVIC_EnableIRQ(GINT1_IRQn);
break;
default:
break;
}
return;
}
/*****************************************************************************
** Function name: GPIOGetPinValue
**
** Descriptions: Read Current state of port pin, PIN register value
**
** parameters: port num, bit position
** Returned value: None
**
*****************************************************************************/
uint32_t GPIOGetPinValue( uint32_t portNum, uint32_t bitPosi )
{
uint32_t regVal = 0;
if( bitPosi < 0x20 )
{
if ( LPC_GPIO->PIN[portNum] & (0x1<<bitPosi) )
{
regVal = 1;
}
}
else if( bitPosi == 0xFF )
{
regVal = LPC_GPIO->PIN[portNum];
}
return ( regVal );
}
/*****************************************************************************
** Function name: GPIOSetBitValue
**
** Descriptions: Set/clear a bit in a specific position
**
** parameters: port num, bit position, bit value
**
** Returned value: None
**
*****************************************************************************/
void GPIOSetBitValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal )
{
if ( bitVal )
{
LPC_GPIO->SET[portNum] = 1<<bitPosi;
}
else
{
LPC_GPIO->CLR[portNum] = 1<<bitPosi;
}
return;
}
/*****************************************************************************
** Function name: GPIOSetDir
**
** Descriptions: Set the direction in GPIO port
**
** parameters: portNum, bit position, direction (1 out, 0 input)
**
** Returned value: None
**
*****************************************************************************/
void GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir )
{
if( dir )
{
LPC_GPIO->DIR[portNum] |= (1<<bitPosi);
}
else
{
LPC_GPIO->DIR[portNum] &= ~(1<<bitPosi);
}
return;
}
/******************************************************************************
** End Of File
******************************************************************************/

View File

@@ -0,0 +1,95 @@
/****************************************************************************
* $Id:: nmi.c 7227 2011-04-27 20:20:38Z usb01267 $
* Project: NXP LPC13Uxx NMI interrupt example
*
* Description:
* This file contains NMI interrupt handler code example.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC13Uxx.h"
#include "nmi.h"
#if NMI_ENABLED
volatile uint32_t NMI_Counter[MAX_NMI_NUM];
/*****************************************************************************
** Function name: NMI_Handler
**
** Descriptions: NMI interrupt handler
** parameters: None
**
** Returned value: None
**
*****************************************************************************/
void NMI_Handler( void )
{
uint32_t regVal;
regVal = LPC_SYSCON->NMISRC;
regVal &= ~0x80000000;
if ( regVal < MAX_NMI_NUM )
{
if ( regVal == CT16B0_IRQn )
{
/* Use TIMER16_0_IRQHandler as example for real application. */
LPC_CT16B0->IR = 0xFF; /* Clear timer16_0 interrupt */
}
else if ( regVal == CT16B1_IRQn )
{
/* Use TIMER16_1_IRQHandler as example for real application. */
LPC_CT16B1->IR = 0xFF; /* Clear timer16_1 interrupt */
}
else if ( regVal == CT32B0_IRQn )
{
/* Use TIMER32_0_IRQHandler as example for real application. */
LPC_CT32B0->IR = 0xFF; /* Clear timer32_0 interrupt */
}
else if ( regVal == CT32B1_IRQn )
{
/* Use TIMER32_0_IRQHandler as example for real application. */
LPC_CT32B1->IR = 0xFF; /* Clear timer32_1 interrupt */
}
NMI_Counter[regVal]++;
}
return;
}
/*****************************************************************************
** Function name: NMI_Init
**
** Descriptions: NMI initialization
** parameters: NMI number
**
** Returned value: None
**
*****************************************************************************/
void NMI_Init( uint32_t NMI_num )
{
uint32_t i;
for ( i = 0; i < MAX_NMI_NUM; i++ )
{
NMI_Counter[i] = 0x0;
}
LPC_SYSCON->NMISRC = 0x80000000|NMI_num;
return;
}
#endif

View File

@@ -0,0 +1,628 @@
/****************************************************************************
* $Id:: timer16.c 6950 2011-03-23 22:09:44Z usb00423 $
* Project: NXP LPC13Uxx 16-bit timer example
*
* Description:
* This file contains 16-bit timer code example which include timer
* initialization, timer interrupt handler, and related APIs for
* timer setup.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC13Uxx.h"
#include "timer16.h"
#include "nmi.h"
volatile uint32_t timer16_0_counter[4] = {0,0,0,0};
volatile uint32_t timer16_1_counter[4] = {0,0,0,0};
volatile uint32_t timer16_0_capture[4] = {0,0,0,0};
volatile uint32_t timer16_1_capture[4] = {0,0,0,0};
volatile uint32_t timer16_0_period = 0;
volatile uint32_t timer16_1_period = 0;
/*****************************************************************************
** Function name: delayMs
**
** Descriptions: Start the timer delay in milo seconds
** until elapsed
**
** parameters: timer number, Delay value in milo second
**
** Returned value: None
**
*****************************************************************************/
void delayMs(uint8_t timer_num, uint32_t delayInMs)
{
if (timer_num == 0)
{
/*
* setup timer #0 for delay
*/
LPC_CT16B0->TCR = 0x02; /* reset timer */
LPC_CT16B0->PR = 0x00; /* set prescaler to zero */
LPC_CT16B0->MR0 = delayInMs * (SystemCoreClock / 1000);
LPC_CT16B0->IR = 0xff; /* reset all interrrupts */
LPC_CT16B0->MCR = 0x04; /* stop timer on match */
LPC_CT16B0->TCR = 0x01; /* start timer */
/* wait until delay time has elapsed */
while (LPC_CT16B0->TCR & 0x01);
}
else if (timer_num == 1)
{
/*
* setup timer #1 for delay
*/
LPC_CT16B1->TCR = 0x02; /* reset timer */
LPC_CT16B1->PR = 0x00; /* set prescaler to zero */
LPC_CT16B1->MR0 = delayInMs * (SystemCoreClock / 1000);
LPC_CT16B1->IR = 0xff; /* reset all interrrupts */
LPC_CT16B1->MCR = 0x04; /* stop timer on match */
LPC_CT16B1->TCR = 0x01; /* start timer */
/* wait until delay time has elapsed */
while (LPC_CT16B1->TCR & 0x01);
}
return;
}
/******************************************************************************
** Function name: CT16B0_IRQHandler
**
** Descriptions: Timer/CounterX and CaptureX interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void CT16B0_IRQHandler(void)
{
if ( LPC_CT16B0->IR & (0x1<<0) )
{
LPC_CT16B0->IR = 0x1<<0; /* clear interrupt flag */
timer16_0_counter[0]++;
}
if ( LPC_CT16B0->IR & (0x1<<1) )
{
LPC_CT16B0->IR = 0x1<<1; /* clear interrupt flag */
timer16_0_counter[1]++;
}
if ( LPC_CT16B0->IR & (0x1<<2) )
{
LPC_CT16B0->IR = 0x1<<2; /* clear interrupt flag */
timer16_0_counter[2]++;
}
if ( LPC_CT16B0->IR & (0x1<<3) )
{
LPC_CT16B0->IR = 0x1<<3; /* clear interrupt flag */
timer16_0_counter[3]++;
}
if ( LPC_CT16B0->IR & (0x1<<4) )
{
LPC_CT16B0->IR = 0x1<<4; /* clear interrupt flag */
timer16_0_capture[0]++;
}
if ( LPC_CT16B0->IR & (0x1<<5) )
{
LPC_CT16B0->IR = 0x1<<5; /* clear interrupt flag */
timer16_0_capture[1]++;
}
if ( LPC_CT16B0->IR & (0x1<<6) )
{
LPC_CT16B0->IR = 0x1<<6; /* clear interrupt flag */
timer16_0_capture[2]++;
}
if ( LPC_CT16B0->IR & (0x1<<7) )
{
LPC_CT16B0->IR = 0x1<<7; /* clear interrupt flag */
timer16_0_capture[3]++;
}
return;
}
/******************************************************************************
** Function name: CT16B1_IRQHandler
**
** Descriptions: Timer/CounterX and CaptureX interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void CT16B1_IRQHandler(void)
{
if ( LPC_CT16B1->IR & (0x1<<0) )
{
LPC_CT16B1->IR = 0x1<<0; /* clear interrupt flag */
timer16_1_counter[0]++;
}
if ( LPC_CT16B1->IR & (0x1<<1) )
{
LPC_CT16B1->IR = 0x1<<1; /* clear interrupt flag */
timer16_1_counter[1]++;
}
if ( LPC_CT16B1->IR & (0x1<<2) )
{
LPC_CT16B1->IR = 0x1<<2; /* clear interrupt flag */
timer16_1_counter[2]++;
}
if ( LPC_CT16B1->IR & (0x1<<3) )
{
LPC_CT16B1->IR = 0x1<<3; /* clear interrupt flag */
timer16_1_counter[3]++;
}
if ( LPC_CT16B1->IR & (0x1<<4) )
{
LPC_CT16B1->IR = 0x1<<4; /* clear interrupt flag */
timer16_1_capture[0]++;
}
if ( LPC_CT16B1->IR & (0x1<<5) )
{
LPC_CT16B1->IR = 0x1<<5; /* clear interrupt flag */
timer16_1_capture[1]++;
}
if ( LPC_CT16B1->IR & (0x1<<6) )
{
LPC_CT16B1->IR = 0x1<<6; /* clear interrupt flag */
timer16_1_capture[2]++;
}
if ( LPC_CT16B1->IR & (0x1<<7) )
{
LPC_CT16B1->IR = 0x1<<7; /* clear interrupt flag */
timer16_1_capture[3]++;
}
return;
}
/******************************************************************************
** Function name: enable_timer
**
** Descriptions: Enable timer
**
** parameters: timer number: 0 or 1
** Returned value: None
**
******************************************************************************/
void enable_timer16(uint8_t timer_num)
{
if ( timer_num == 0 )
{
LPC_CT16B0->TCR = 1;
}
else
{
LPC_CT16B1->TCR = 1;
}
return;
}
/******************************************************************************
** Function name: disable_timer
**
** Descriptions: Disable timer
**
** parameters: timer number: 0 or 1
** Returned value: None
**
******************************************************************************/
void disable_timer16(uint8_t timer_num)
{
if ( timer_num == 0 )
{
LPC_CT16B0->TCR = 0;
}
else
{
LPC_CT16B1->TCR = 0;
}
return;
}
/******************************************************************************
** Function name: reset_timer
**
** Descriptions: Reset timer
**
** parameters: timer number: 0 or 1
** Returned value: None
**
******************************************************************************/
void reset_timer16(uint8_t timer_num)
{
uint32_t regVal;
if ( timer_num == 0 )
{
regVal = LPC_CT16B0->TCR;
regVal |= 0x02;
LPC_CT16B0->TCR = regVal;
}
else
{
regVal = LPC_CT16B1->TCR;
regVal |= 0x02;
LPC_CT16B1->TCR = regVal;
}
return;
}
/******************************************************************************
** Function name: Set_timer_capture
**
** Descriptions: set timer capture based on LOC number.
**
** parameters: timer number and location number
** Returned value: None
**
******************************************************************************/
void set_timer16_capture(uint8_t timer_num, uint8_t location )
{
if ( timer_num == 0 )
{
/* Timer0_16 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO1_16 &= ~0x07;
LPC_IOCON->PIO1_16 |= 0x02; /* Timer0_16 CAP0 */
LPC_IOCON->PIO1_17 &= ~0x07;
LPC_IOCON->PIO1_17 |= 0x01; /* Timer0_16 CAP2 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO0_2 &= ~0x07;
LPC_IOCON->PIO0_2 |= 0x02; /* Timer0_16 CAP0 */
}
else
{
while ( 1 ); /* Fatal location number error */
}
}
else
{
/* Timer1_16 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO0_20 &= ~0x07; /* Timer1_16 I/O config */
LPC_IOCON->PIO0_20 |= 0x01; /* Timer1_16 CAP0 */
LPC_IOCON->PIO1_18 &= ~0x07;
LPC_IOCON->PIO1_18 |= 0x01; /* Timer1_16 CAP1 */
}
else
{
while ( 1 ); /* Fatal location number error */
}
}
return;
}
/******************************************************************************
** Function name: Set_timer_match
**
** Descriptions: set timer match based on LOC number.
**
** parameters: timer number, match enable, and location number
** Returned value: None
**
******************************************************************************/
void set_timer16_match(uint8_t timer_num, uint8_t match_enable, uint8_t location)
{
if ( timer_num == 0 )
{
if ( match_enable & 0x01 )
{
/* Timer0_16 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO0_8 &= ~0x07;
LPC_IOCON->PIO0_8 |= 0x02; /* Timer0_16 MAT0 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_13 &= ~0x07;
LPC_IOCON->PIO1_13 |= 0x02; /* Timer0_16 MAT0 */
}
}
if ( match_enable & 0x02 )
{
/* Timer0_16 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO0_9 &= ~0x07;
LPC_IOCON->PIO0_9 |= 0x02; /* Timer0_16 MAT1 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_14 &= ~0x07;
LPC_IOCON->PIO1_14 |= 0x02; /* Timer0_16 MAT1 */
}
}
if ( match_enable & 0x04 )
{
/* Timer0_16 I/O config */
if ( location == 0 )
{
#ifdef __SWD_DISABLED
LPC_IOCON->SWCLK_PIO0_10 &= ~0x07;
LPC_IOCON->SWCLK_PIO0_10 |= 0x03; /* Timer0_16 MAT2 */
#endif
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_15 &= ~0x07;
LPC_IOCON->PIO1_15 |= 0x02; /* Timer0_16 MAT2 */
}
}
}
else if ( timer_num == 1 )
{
if ( match_enable & 0x01 )
{
/* Timer1_16 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO0_21 &= ~0x07;
LPC_IOCON->PIO0_21 |= 0x01; /* Timer1_16 MAT0 */
}
}
if ( match_enable & 0x02 )
{
/* Timer1_16 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO0_22 &= ~0x07;
LPC_IOCON->PIO0_22 |= 0x02; /* Timer1_16 MAT1 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_23 &= ~0x07;
LPC_IOCON->PIO1_23 |= 0x01; /* Timer1_16 MAT1 */
}
}
}
return;
}
/******************************************************************************
** Function name: init_timer
**
** Descriptions: Initialize timer, set timer interval, reset timer,
** install timer interrupt handler
**
** parameters: timer number and timer interval
** Returned value: None
**
******************************************************************************/
void init_timer16(uint8_t timer_num, uint32_t TimerInterval)
{
uint32_t i;
if ( timer_num == 0 )
{
/* Some of the I/O pins need to be clearfully planned if
you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
LPC_CT16B0->MR0 = TimerInterval;
LPC_CT16B0->MR1 = TimerInterval;
#if TIMER_MATCH
for ( i = 0; i < 4; i++ )
{
timer16_0_counter[i] = 0;
}
set_timer16_match(timer_num, 0x07, 0);
LPC_CT16B0->EMR &= ~(0xFF<<4);
LPC_CT16B0->EMR |= ((0x3<<4)|(0x3<<6)|(0x3<<8));
#else
for ( i = 0; i < 4; i++ )
{
timer16_0_capture[i] = 0;
}
set_timer16_capture(timer_num, 0);
/* Capture 0 and 2 on rising edge, interrupt enable. */
LPC_CT16B0->CCR = (0x5<<0)|(0x5<<6);
#endif
LPC_CT16B0->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */
/* Enable the TIMER0 Interrupt */
#if NMI_ENABLED
NVIC_DisableIRQ(CT16B0_IRQn);
NMI_Init( CT16B0_IRQn );
#else
NVIC_EnableIRQ(CT16B0_IRQn);
#endif
}
else if ( timer_num == 1 )
{
/* Some of the I/O pins need to be clearfully planned if
you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<8);
LPC_CT16B1->MR0 = TimerInterval;
LPC_CT16B1->MR1 = TimerInterval;
#if TIMER_MATCH
for ( i = 0; i < 4; i++ )
{
timer16_1_counter[i] = 0;
}
set_timer16_match(timer_num, 0x07, 0);
LPC_CT16B1->EMR &= ~(0xFF<<4);
LPC_CT16B1->EMR |= ((0x3<<4)|(0x3<<6)|(0x3<<8));
#else
for ( i = 0; i < 4; i++ )
{
timer16_1_capture[i] = 0;
}
set_timer16_capture(timer_num, 0);
/* Capture 0 and 1 on rising edge, interrupt enable. */
LPC_CT16B1->CCR = (0x5<<0)|(0x5<<3);
#endif
LPC_CT16B1->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */
/* Enable the TIMER1 Interrupt */
#if NMI_ENABLED
NVIC_DisableIRQ(CT16B1_IRQn);
NMI_Init( CT16B1_IRQn );
#else
NVIC_EnableIRQ(CT16B1_IRQn);
#endif
}
return;
}
/******************************************************************************
** Function name: init_timer16PWM
**
** Descriptions: Initialize timer as PWM
**
** parameters: timer number, period and match enable:
** match_enable[0] = PWM for MAT0
** match_enable[1] = PWM for MAT1
** match_enable[2] = PWM for MAT2
**
** Returned value: None
**
******************************************************************************/
void init_timer16PWM(uint8_t timer_num, uint32_t period, uint8_t match_enable, uint8_t cap_enabled)
{
disable_timer16(timer_num);
if (timer_num == 1)
{
/* Some of the I/O pins need to be clearfully planned if
you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<8);
/* Setup the external match register */
LPC_CT16B1->EMR = (1<<EMC3)|(1<<EMC2)|(1<<EMC1)|(2<<EMC0)|(1<<3)|(match_enable);
/* Setup the outputs */
/* If match0 is enabled, set the output */
set_timer16_match(timer_num, match_enable, 0 );
/* Enable the selected PWMs and enable Match3 */
LPC_CT16B1->PWMC = (1<<3)|(match_enable);
/* Setup the match registers */
/* set the period value to a global variable */
timer16_1_period = period;
LPC_CT16B1->MR3 = timer16_1_period;
LPC_CT16B1->MR0 = timer16_1_period/2;
LPC_CT16B1->MR1 = timer16_1_period/2;
LPC_CT16B1->MR2 = timer16_1_period/2;
/* Set match control register */
LPC_CT16B1->MCR = 1<<10;// | 1<<9; /* Reset on MR3 */
if (cap_enabled)
{
/* Use location 0 for test. */
set_timer16_capture( timer_num, 0 );
LPC_CT16B1->IR = 0xF; /* clear interrupt flag */
/* Set the capture control register */
LPC_CT16B1->CCR = 7;
}
/* Enable the TIMER1 Interrupt */
NVIC_EnableIRQ(CT16B1_IRQn);
}
else
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7);
/* Setup the external match register */
LPC_CT16B0->EMR = (1<<EMC3)|(1<<EMC2)|(1<<EMC1)|(1<<EMC0)|(1<<3)|(match_enable);
/* Setup the outputs */
/* If match0 is enabled, set the output */
set_timer16_match(timer_num, match_enable, 0 );
/* Enable the selected PWMs and enable Match3 */
LPC_CT16B0->PWMC = (1<<3)|(match_enable);
/* Setup the match registers */
/* set the period value to a global variable */
timer16_0_period = period;
LPC_CT16B0->MR3 = timer16_0_period;
LPC_CT16B0->MR0 = timer16_0_period/2;
LPC_CT16B0->MR1 = timer16_0_period/2;
LPC_CT16B0->MR2 = timer16_0_period/2;
/* Set the match control register */
LPC_CT16B0->MCR = 1<<10; /* Reset on MR3 */
/* Enable the TIMER1 Interrupt */
NVIC_EnableIRQ(CT16B0_IRQn);
}
}
/******************************************************************************
** Function name: pwm16_setMatch
**
** Descriptions: Set the pwm16 match values
**
** parameters: timer number, match numner and the value
**
** Returned value: None
**
******************************************************************************/
void setMatch_timer16PWM (uint8_t timer_num, uint8_t match_nr, uint32_t value)
{
if (timer_num)
{
switch (match_nr)
{
case 0:
LPC_CT16B1->MR0 = value;
break;
case 1:
LPC_CT16B1->MR1 = value;
break;
case 2:
LPC_CT16B1->MR2 = value;
break;
case 3:
LPC_CT16B1->MR3 = value;
break;
default:
break;
}
}
else
{
switch (match_nr)
{
case 0:
LPC_CT16B0->MR0 = value;
break;
case 1:
LPC_CT16B0->MR1 = value;
break;
case 2:
LPC_CT16B0->MR2 = value;
break;
case 3:
LPC_CT16B0->MR3 = value;
break;
default:
break;
}
}
}
/******************************************************************************
** End Of File
******************************************************************************/

View File

@@ -0,0 +1,646 @@
/****************************************************************************
* $Id:: timer32.c 6951 2011-03-23 22:11:07Z usb00423 $
* Project: NXP LPC13Uxx 32-bit timer example
*
* Description:
* This file contains 32-bit timer code example which include timer
* initialization, timer interrupt handler, and related APIs for
* timer setup.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC13Uxx.h"
#include "timer32.h"
#include "nmi.h"
volatile uint32_t timer32_0_counter[4] = {0,0,0,0};
volatile uint32_t timer32_1_counter[4] = {0,0,0,0};
volatile uint32_t timer32_0_capture[4] = {0,0,0,0};
volatile uint32_t timer32_1_capture[4] = {0,0,0,0};
volatile uint32_t timer32_0_period = 0;
volatile uint32_t timer32_1_period = 0;
/*****************************************************************************
** Function name: delay32Ms
**
** Descriptions: Start the timer delay in milo seconds
** until elapsed
**
** parameters: timer number, Delay value in milo second
**
** Returned value: None
**
*****************************************************************************/
void delay32Ms(uint8_t timer_num, uint32_t delayInMs)
{
if (timer_num == 0)
{
/* setup timer #0 for delay */
LPC_CT32B0->TCR = 0x02; /* reset timer */
LPC_CT32B0->PR = 0x00; /* set prescaler to zero */
LPC_CT32B0->MR0 = delayInMs * (SystemCoreClock / 1000);
LPC_CT32B0->IR = 0xff; /* reset all interrrupts */
LPC_CT32B0->MCR = 0x04; /* stop timer on match */
LPC_CT32B0->TCR = 0x01; /* start timer */
/* wait until delay time has elapsed */
while (LPC_CT32B0->TCR & 0x01);
}
else if (timer_num == 1)
{
/* setup timer #1 for delay */
LPC_CT32B1->TCR = 0x02; /* reset timer */
LPC_CT32B1->PR = 0x00; /* set prescaler to zero */
LPC_CT32B1->MR0 = delayInMs * (SystemCoreClock / 1000);
LPC_CT32B1->IR = 0xff; /* reset all interrrupts */
LPC_CT32B1->MCR = 0x04; /* stop timer on match */
LPC_CT32B1->TCR = 0x01; /* start timer */
/* wait until delay time has elapsed */
while (LPC_CT32B1->TCR & 0x01);
}
return;
}
/******************************************************************************
** Function name: CT32B0_IRQHandler
**
** Descriptions: Timer/CounterX and captureX interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void CT32B0_IRQHandler(void)
{
if ( LPC_CT32B0->IR & (0x01<<0) )
{
LPC_CT32B0->IR = 0x1<<0; /* clear interrupt flag */
timer32_0_counter[0]++;
}
if ( LPC_CT32B0->IR & (0x01<<1) )
{
LPC_CT32B0->IR = 0x1<<1; /* clear interrupt flag */
timer32_0_counter[1]++;
}
if ( LPC_CT32B0->IR & (0x01<<2) )
{
LPC_CT32B0->IR = 0x1<<2; /* clear interrupt flag */
timer32_0_counter[2]++;
}
if ( LPC_CT32B0->IR & (0x01<<3) )
{
LPC_CT32B0->IR = 0x1<<3; /* clear interrupt flag */
timer32_0_counter[3]++;
}
if ( LPC_CT32B0->IR & (0x1<<4) )
{
LPC_CT32B0->IR = 0x1<<4; /* clear interrupt flag */
timer32_0_capture[0]++;
}
if ( LPC_CT32B0->IR & (0x1<<5) )
{
LPC_CT32B0->IR = 0x1<<5; /* clear interrupt flag */
timer32_0_capture[1]++;
}
if ( LPC_CT32B0->IR & (0x1<<6) )
{
LPC_CT32B0->IR = 0x1<<6; /* clear interrupt flag */
timer32_0_capture[2]++;
}
if ( LPC_CT32B0->IR & (0x1<<7) )
{
LPC_CT32B0->IR = 0x1<<7; /* clear interrupt flag */
timer32_0_capture[3]++;
}
return;
}
/******************************************************************************
** Function name: CT32B1_IRQHandler
**
** Descriptions: Timer/CounterX and captureX interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void CT32B1_IRQHandler(void)
{
if ( LPC_CT32B1->IR & (0x01<<0) )
{
LPC_CT32B1->IR = 0x1<<0; /* clear interrupt flag */
timer32_1_counter[0]++;
}
if ( LPC_CT32B1->IR & (0x01<<1) )
{
LPC_CT32B1->IR = 0x1<<1; /* clear interrupt flag */
timer32_1_counter[1]++;
}
if ( LPC_CT32B1->IR & (0x01<<2) )
{
LPC_CT32B1->IR = 0x1<<2; /* clear interrupt flag */
timer32_1_counter[2]++;
}
if ( LPC_CT32B1->IR & (0x01<<3) )
{
LPC_CT32B1->IR = 0x1<<3; /* clear interrupt flag */
timer32_1_counter[3]++;
}
if ( LPC_CT32B1->IR & (0x1<<4) )
{
LPC_CT32B1->IR = 0x1<<4; /* clear interrupt flag */
timer32_1_capture[0]++;
}
if ( LPC_CT32B1->IR & (0x1<<5) )
{
LPC_CT32B1->IR = 0x1<<5; /* clear interrupt flag */
timer32_1_capture[1]++;
}
if ( LPC_CT32B1->IR & (0x1<<6) )
{
LPC_CT32B1->IR = 0x1<<6; /* clear interrupt flag */
timer32_1_capture[2]++;
}
if ( LPC_CT32B1->IR & (0x1<<7) )
{
LPC_CT32B1->IR = 0x1<<7; /* clear interrupt flag */
timer32_1_capture[3]++;
}
return;
}
/******************************************************************************
** Function name: enable_timer
**
** Descriptions: Enable timer
**
** parameters: timer number: 0 or 1
** Returned value: None
**
******************************************************************************/
void enable_timer32(uint8_t timer_num)
{
if ( timer_num == 0 )
{
LPC_CT32B0->TCR = 1;
}
else
{
LPC_CT32B1->TCR = 1;
}
return;
}
/******************************************************************************
** Function name: disable_timer
**
** Descriptions: Disable timer
**
** parameters: timer number: 0 or 1
** Returned value: None
**
******************************************************************************/
void disable_timer32(uint8_t timer_num)
{
if ( timer_num == 0 )
{
LPC_CT32B0->TCR = 0;
}
else
{
LPC_CT32B1->TCR = 0;
}
return;
}
/******************************************************************************
** Function name: reset_timer
**
** Descriptions: Reset timer
**
** parameters: timer number: 0 or 1
** Returned value: None
**
******************************************************************************/
void reset_timer32(uint8_t timer_num)
{
uint32_t regVal;
if ( timer_num == 0 )
{
regVal = LPC_CT32B0->TCR;
regVal |= 0x02;
LPC_CT32B0->TCR = regVal;
}
else
{
regVal = LPC_CT32B1->TCR;
regVal |= 0x02;
LPC_CT32B1->TCR = regVal;
}
return;
}
/******************************************************************************
** Function name: set_timer_capture
**
** Descriptions: Set timer capture based on location
**
** parameters: timer number: 0~1, location 0~2
** Returned value: None
**
******************************************************************************/
void set_timer32_capture(uint8_t timer_num, uint8_t location )
{
if ( timer_num == 0 )
{
/* Timer0_32 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO1_28 &= ~0x07;
LPC_IOCON->PIO1_28 |= 0x01; /* Timer0_32 CAP0 */
LPC_IOCON->PIO1_29 &= ~0x07;
LPC_IOCON->PIO1_29 |= 0x02; /* Timer0_32 CAP2 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO0_17 &= ~0x07;
LPC_IOCON->PIO0_17 |= 0x02; /* Timer0_32 CAP0 */
}
else
{
while ( 1 ); /* Fatal location number error */
}
}
else
{
/* Timer1_32 I/O config */
if ( location == 0 )
{
LPC_IOCON->PIO1_4 &= ~0x07; /* Timer1_32 I/O config */
LPC_IOCON->PIO1_4 |= 0x01; /* Timer1_32 CAP0 */
LPC_IOCON->PIO1_5 &= ~0x07;
LPC_IOCON->PIO1_5 |= 0x01; /* Timer1_32 CAP1 */
}
else if ( location == 1 )
{
LPC_IOCON->TMS_PIO0_12 &= ~0x07;
LPC_IOCON->TMS_PIO0_12 |= 0x03; /* Timer1_32 CAP0 */
}
else
{
while ( 1 ); /* Fatal location number error */
}
}
return;
}
/******************************************************************************
** Function name: set_timer_match
**
** Descriptions: Set timer match based on location
**
** parameters: timer number: 0~1, location 0~2
** Returned value: None
**
******************************************************************************/
void set_timer32_match(uint8_t timer_num, uint8_t match_enable, uint8_t location)
{
if ( timer_num == 0 )
{
if ( match_enable & 0x01 )
{
if ( location == 0 )
{
LPC_IOCON->PIO0_18 &= ~0x07;
LPC_IOCON->PIO0_18 |= 0x02; /* Timer0_32 MAT0 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_24 &= ~0x07;
LPC_IOCON->PIO1_24 |= 0x01; /* Timer0_32 MAT0 */
}
}
if ( match_enable & 0x02 )
{
if ( location == 0 )
{
LPC_IOCON->PIO0_19 &= ~0x07;
LPC_IOCON->PIO0_19 |= 0x02; /* Timer0_32 MAT1 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_25 &= ~0x07;
LPC_IOCON->PIO1_25 |= 0x01; /* Timer0_32 MAT1 */
}
}
if ( match_enable & 0x04 )
{
if ( location == 0 )
{
LPC_IOCON->PIO0_1 &= ~0x07;
LPC_IOCON->PIO0_1 |= 0x02; /* Timer0_32 MAT2 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_26 &= ~0x07;
LPC_IOCON->PIO1_26 |= 0x01; /* Timer0_32 MAT2 */
}
}
if ( match_enable & 0x08 )
{
if ( location == 0 )
{
LPC_IOCON->TDI_PIO0_11 &= ~0x07;
LPC_IOCON->TDI_PIO0_11 |= 0x03; /* Timer0_32 MAT3 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO1_27 &= ~0x07;
LPC_IOCON->PIO1_27 |= 0x01; /* Timer0_32 MAT3 */
}
}
}
else if ( timer_num == 1 )
{
if ( match_enable & 0x01 )
{
if ( location == 0 )
{
LPC_IOCON->PIO1_0 &= ~0x07;
LPC_IOCON->PIO1_0 |= 0x01; /* Timer1_32 MAT0 */
}
else if ( location == 1 )
{
LPC_IOCON->TDO_PIO0_13 &= ~0x07;
LPC_IOCON->TDO_PIO0_13 |= 0x03; /* Timer1_32 MAT0 */
}
}
if ( match_enable & 0x02 )
{
if ( location == 0 )
{
LPC_IOCON->PIO1_1 &= ~0x07;
LPC_IOCON->PIO1_1 |= 0x01; /* Timer1_32 MAT1 */
}
else if ( location == 1 )
{
LPC_IOCON->TRST_PIO0_14 &= ~0x07;
LPC_IOCON->TRST_PIO0_14 |= 0x03; /* Timer1_32 MAT1 */
}
}
if ( match_enable & 0x04 )
{
if ( location == 0 )
{
LPC_IOCON->PIO1_2 &= ~0x07;
LPC_IOCON->PIO1_2 |= 0x01; /* Timer1_32 MAT2 */
}
else if ( location == 1 )
{
#if __SWD_DISABLED
LPC_IOCON->SWDIO_PIO0_15 &= ~0x07;
LPC_IOCON->SWDIO_PIO0_15 |= 0x03; /* Timer1_32 MAT2 */
#endif
}
}
if ( match_enable & 0x08 )
{
if ( location == 0 )
{
LPC_IOCON->PIO1_3 &= ~0x07;
LPC_IOCON->PIO1_3 |= 0x01; /* Timer1_32 MAT3 */
}
else if ( location == 1 )
{
LPC_IOCON->PIO0_16 &= ~0x07;
LPC_IOCON->PIO0_16 |= 0x02; /* Timer1_32 MAT3 */
}
}
}
return;
}
/******************************************************************************
** Function name: init_timer
**
** Descriptions: Initialize timer, set timer interval, reset timer,
** install timer interrupt handler
**
** parameters: timer number and timer interval
** Returned value: None
**
******************************************************************************/
void init_timer32(uint8_t timer_num, uint32_t TimerInterval)
{
uint32_t i;
if ( timer_num == 0 )
{
/* Some of the I/O pins need to be clearfully planned if
you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);
LPC_CT32B0->MR0 = TimerInterval;
#if TIMER_MATCH
for ( i = 0; i < 4; i++ )
{
timer32_0_counter[i] = 0;
}
set_timer32_match(timer_num, 0x0F, 0);
LPC_CT32B0->EMR &= ~(0xFF<<4);
LPC_CT32B0->EMR |= ((0x3<<4)|(0x3<<6)|(0x3<<8)|(0x3<<10)); /* MR0/1/2/3 Toggle */
#else
for ( i = 0; i < 4; i++ )
{
timer32_0_capture[i] = 0;
}
set_timer32_capture(timer_num, 0 );
/* Capture 0 on rising edge, interrupt enable. */
LPC_CT32B0->CCR = (0x5<<0)|(0x5<<6);
#endif
LPC_CT32B0->MCR = 3; /* Interrupt and Reset on MR0 */
/* Enable the TIMER0 Interrupt */
#if NMI_ENABLED
NVIC_DisableIRQ( CT32B0_IRQn );
NMI_Init( CT32B0_IRQn );
#else
NVIC_EnableIRQ(CT32B0_IRQn);
#endif
}
else if ( timer_num == 1 )
{
/* Some of the I/O pins need to be clearfully planned if
you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10);
LPC_CT32B1->MR0 = TimerInterval;
#if TIMER_MATCH
for ( i = 0; i < 4; i++ )
{
timer32_1_counter[i] = 0;
}
set_timer32_match(timer_num, 0x0F, 0);
LPC_CT32B1->EMR &= ~(0xFF<<4);
LPC_CT32B1->EMR |= ((0x3<<4)|(0x3<<6)|(0x3<<8)|(0x3<<10)); /* MR0/1/2 Toggle */
#else
for ( i = 0; i < 4; i++ )
{
timer32_1_capture[i] = 0;
}
set_timer32_capture(timer_num, 0 );
/* Capture 0 on rising edge, interrupt enable. */
LPC_CT32B1->CCR = (0x5<<0)|(0x5<<3);
#endif
LPC_CT32B1->MCR = 3; /* Interrupt and Reset on MR0 */
/* Enable the TIMER1 Interrupt */
#if NMI_ENABLED
NVIC_DisableIRQ( CT32B1_IRQn );
NMI_Init( CT32B1_IRQn );
#else
NVIC_EnableIRQ(CT32B1_IRQn);
#endif
}
return;
}
/******************************************************************************
** Function name: init_timer32PWM
**
** Descriptions: Initialize timer as PWM
**
** parameters: timer number, period and match enable:
** match_enable[0] = PWM for MAT0
** match_enable[1] = PWM for MAT1
** match_enable[2] = PWM for MAT2
** Returned value: None
**
******************************************************************************/
void init_timer32PWM(uint8_t timer_num, uint32_t period, uint8_t match_enable)
{
disable_timer32(timer_num);
if (timer_num == 1)
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10);
/* Setup the external match register */
LPC_CT32B1->EMR = (1<<EMC3)|(1<<EMC2)|(2<<EMC1)|(1<<EMC0)|MATCH3|(match_enable);
/* Setup the outputs */
/* If match0 is enabled, set the output, use location 0 for test. */
set_timer32_match( timer_num, match_enable, 0 );
/* Enable the selected PWMs and enable Match3 */
LPC_CT32B1->PWMC = MATCH3|(match_enable);
/* Setup the match registers */
/* set the period value to a global variable */
timer32_1_period = period;
LPC_CT32B1->MR3 = timer32_1_period;
LPC_CT32B1->MR0 = timer32_1_period/2;
LPC_CT32B1->MR1 = timer32_1_period/2;
LPC_CT32B1->MR2 = timer32_1_period/2;
LPC_CT32B1->MCR = 1<<10; /* Reset on MR3 */
}
else
{
/* Some of the I/O pins need to be clearfully planned if
you use below module because JTAG and TIMER CAP/MAT pins are muxed. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9);
/* Setup the external match register */
LPC_CT32B0->EMR = (1<<EMC3)|(2<<EMC2)|(1<<EMC1)|(1<<EMC0)|MATCH3|(match_enable);
/* Setup the outputs */
/* If match0 is enabled, set the output, use location 0 for test. */
set_timer32_match( timer_num, match_enable, 0 );
/* Enable the selected PWMs and enable Match3 */
LPC_CT32B0->PWMC = MATCH3|(match_enable);
/* Setup the match registers */
/* set the period value to a global variable */
timer32_0_period = period;
LPC_CT32B0->MR3 = timer32_0_period;
LPC_CT32B0->MR0 = timer32_0_period/2;
LPC_CT32B0->MR1 = timer32_0_period/2;
LPC_CT32B0->MR2 = timer32_0_period/2;
LPC_CT32B0->MCR = 1<<10; /* Reset on MR3 */
}
}
/******************************************************************************
** Function name: pwm32_setMatch
**
** Descriptions: Set the pwm32 match values
**
** parameters: timer number, match numner and the value
**
** Returned value: None
**
******************************************************************************/
void setMatch_timer32PWM (uint8_t timer_num, uint8_t match_nr, uint32_t value)
{
if (timer_num)
{
switch (match_nr)
{
case 0:
LPC_CT32B1->MR0 = value;
break;
case 1:
LPC_CT32B1->MR1 = value;
break;
case 2:
LPC_CT32B1->MR2 = value;
break;
case 3:
LPC_CT32B1->MR3 = value;
break;
default:
break;
}
}
else
{
switch (match_nr)
{
case 0:
LPC_CT32B0->MR0 = value;
break;
case 1:
LPC_CT32B0->MR1 = value;
break;
case 2:
LPC_CT32B0->MR2 = value;
break;
case 3:
LPC_CT32B0->MR3 = value;
break;
default:
break;
}
}
}
/******************************************************************************
** End Of File
******************************************************************************/

View File

@@ -0,0 +1,437 @@
/****************************************************************************
* $Id:: uart.c 7125 2011-04-15 00:22:12Z usb01267 $
* Project: NXP LPC13Uxx UART example
*
* Description:
* This file contains UART code example which include UART
* initialization, UART interrupt handler, and related APIs for
* UART access.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC13Uxx.h"
#include "type.h"
#include "uart.h"
volatile uint32_t UARTStatus;
volatile uint8_t UARTTxEmpty = 1;
volatile uint8_t UARTBuffer[BUFSIZE];
volatile uint32_t UARTCount = 0;
#if AUTOBAUD_ENABLE
volatile uint32_t UARTAutoBaud = 0, AutoBaudTimeout = 0;
#endif
/*****************************************************************************
** Function name: USART_IRQHandler
**
** Descriptions: USART interrupt handler
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void USART_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 */
{
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 Data Available */
UARTBuffer[UARTCount++] = LPC_USART->RBR;
if (UARTCount == BUFSIZE)
{
UARTCount = 0; /* buffer overflow */
}
}
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 */
{
/* 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;
}
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;
}
#if MODEM_TEST
/*****************************************************************************
** Function name: ModemInit
**
** Descriptions: Initialize UART0 port as modem, setup pin select.
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void ModemInit( void )
{
LPC_IOCON->PIO0_7 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO0_7 |= 0x01; /* UART CTS */
LPC_IOCON->PIO0_17 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO0_17 |= 0x01; /* UART RTS */
#if 1
LPC_IOCON->PIO1_13 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_13 |= 0x01; /* UART DTR */
LPC_IOCON->PIO1_14 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_14 |= 0x01; /* UART DSR */
LPC_IOCON->PIO1_15 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_15 |= 0x01; /* UART DCD */
LPC_IOCON->PIO1_16 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_16 |= 0x01; /* UART RI */
#else
LPC_IOCON->PIO1_19 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_19 |= 0x01; /* UART DTR */
LPC_IOCON->PIO1_20 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_20 |= 0x01; /* UART DSR */
LPC_IOCON->PIO1_21 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_21 |= 0x01; /* UART DCD */
LPC_IOCON->PIO1_22 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_22 |= 0x01; /* UART RI */
#endif
LPC_USART->MCR = 0xC0; /* Enable Auto RTS and Auto CTS. */
return;
}
#endif
/***********************************************************************
*
* Function: uart_set_divisors
*
* Purpose: Determines best dividers to get a target clock rate
*
* Processing:
* See function.
*
* Parameters:
* UARTClk : UART clock
* baudrate : Desired UART baud rate
*
* Outputs:
* baudrate : Sets the estimated buadrate value in DLL, DLM, and FDR.
*
* Returns: Error status.
*
* Notes: None
*
**********************************************************************/
uint32_t uart_set_divisors(uint32_t UARTClk, uint32_t baudrate)
{
uint32_t uClk;
uint32_t calcBaudrate = 0;
uint32_t temp = 0;
uint32_t mulFracDiv, dividerAddFracDiv;
uint32_t diviser = 0 ;
uint32_t mulFracDivOptimal = 1;
uint32_t dividerAddOptimal = 0;
uint32_t diviserOptimal = 0;
uint32_t relativeError = 0;
uint32_t relativeOptimalError = 100000;
/* get UART block clock */
uClk = UARTClk >> 4; /* div by 16 */
/* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers
* The formula is :
* BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)
* It involves floating point calculations. That's the reason the formulae are adjusted with
* Multiply and divide method.*/
/* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
* 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */
for (mulFracDiv = 1; mulFracDiv <= 15; mulFracDiv++)
{
for (dividerAddFracDiv = 0; dividerAddFracDiv <= 15; dividerAddFracDiv++)
{
temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv));
diviser = temp / baudrate;
if ((temp % baudrate) > (baudrate / 2))
diviser++;
if (diviser > 2 && diviser < 65536)
{
calcBaudrate = temp / diviser;
if (calcBaudrate <= baudrate)
relativeError = baudrate - calcBaudrate;
else
relativeError = calcBaudrate - baudrate;
if ((relativeError < relativeOptimalError))
{
mulFracDivOptimal = mulFracDiv ;
dividerAddOptimal = dividerAddFracDiv;
diviserOptimal = diviser;
relativeOptimalError = relativeError;
if (relativeError == 0)
break;
}
} /* End of if */
} /* end of inner for loop */
if (relativeError == 0)
break;
} /* end of outer for loop */
if (relativeOptimalError < (baudrate / 30))
{
/* Set the `Divisor Latch Access Bit` and enable so the DLL/DLM access*/
/* Initialise the `Divisor latch LSB` and `Divisor latch MSB` registers */
LPC_USART->DLM = (diviserOptimal >> 8) & 0xFF;
LPC_USART->DLL = diviserOptimal & 0xFF;
/* Initialise the Fractional Divider Register */
LPC_USART->FDR = ((mulFracDivOptimal & 0xF) << 4) | (dividerAddOptimal & 0xF);
return( TRUE );
}
return ( FALSE );
}
/*****************************************************************************
** 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(USART_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(USART_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;
}
/*****************************************************************************
** Function name: UARTSend
**
** Descriptions: Send a block of data to the UART 0 port based
** on the data length
**
** parameters: buffer pointer, and data length
** Returned value: None
**
*****************************************************************************/
void UARTSend(uint8_t *BufferPtr, uint32_t Length)
{
while ( Length != 0 )
{
/* THRE status, contain valid data */
#if !TX_INTERRUPT
while ( !(LPC_USART->LSR & LSR_THRE) );
LPC_USART->THR = *BufferPtr;
#else
/* Below flag is set inside the interrupt handler when THRE occurs. */
while ( !(UARTTxEmpty & 0x01) );
LPC_USART->THR = *BufferPtr;
UARTTxEmpty = 0; /* not empty in the THR until it shifts out */
#endif
BufferPtr++;
Length--;
}
return;
}
/*****************************************************************************
** Function name: print_string
**
** Descriptions: print out string on the terminal
**
** parameters: pointer to the string end with NULL char.
** Returned value: none.
**
*****************************************************************************/
void print_string( uint8_t *str_ptr )
{
while(*str_ptr != 0x00)
{
while((LPC_USART->LSR & 0x60) != 0x60);
LPC_USART->THR = *str_ptr;
str_ptr++;
}
return;
}
/*****************************************************************************
** Function name: get_key
**
** Descriptions: Get a character from the terminal
**
** parameters: None
** Returned value: character, zero is none.
**
*****************************************************************************/
uint8_t get_key( void )
{
uint8_t dummy;
while ( !(LPC_USART->LSR & 0x01) );
dummy = LPC_USART->RBR;
if ((dummy>=65) && (dummy<=90))
{
/* convert capital to non-capital character, A2a, B2b, C2c. */
dummy +=32;
}
/* echo */
LPC_USART->THR = dummy;
return(dummy);
}
/******************************************************************************
** End Of File
******************************************************************************/