[Sysless] [PATCH] Added some NXP CMSIS libraries from 25_jan_2010 release

Jiri Kubias jiri.kubias at gmail.com
Wed Jul 21 10:38:25 CEST 2010


---
 arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile       |   14 +
 arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile.omk   |   11 +
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.c  |  335 ++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.h  |  299 +++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.c  | 1919 ++++++++++++++++++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.h  |  855 +++++++++
 .../mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.c    |  345 ++++
 .../mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.h    |  384 ++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.c |  989 ++++++++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.h |  582 ++++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.c |  657 +++++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.h |  166 ++
 .../libs/cmsis/lpc17xx_libcfg_default.c            |   64 +
 .../libs/cmsis/lpc17xx_libcfg_default.h            |  163 ++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.c |  135 ++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.h |   64 +
 .../mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.c    |  308 ++++
 .../mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.h    |  210 +++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.c  |  831 +++++++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.h  |  457 +++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.c | 1538 ++++++++++++++++
 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.h |  633 +++++++
 .../mach-lpc17cmsis/libs/cmsis/system_LPC17xx.c    |  574 ++++++
 .../mach-lpc17cmsis/libs/cmsis/system_LPC17xx.h    |   63 +
 24 files changed, 11596 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile.omk
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.h
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.c
 create mode 100644 arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.h

diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile b/arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile
new file mode 100644
index 0000000..76b56fd
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+	@echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile.omk b/arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile.omk
new file mode 100644
index 0000000..63d73b2
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/Makefile.omk
@@ -0,0 +1,11 @@
+# -*- makefile -*-
+
+lib_LIBRARIES = cmsis
+
+cmsis_SOURCES =  lpc17xx_adc.c lpc17xx_can.c lpc17xx_clkpwr.c lpc17xx_emac.c lpc17xx_gpio.c lpc17xx_libcfg_default.c lpc17xx_nvic.c lpc17xx_pinsel.c lpc17xx_ssp.c lpc17xx_uart.c system_LPC17xx.c
+
+
+include_HEADERS = lpc17xx_adc.h lpc17xx_can.h lpc17xx_clkpwr.h lpc17xx_emac.h lpc17xx_gpio.h lpc17xx_libcfg_default.h lpc17xx_nvic.h lpc17xx_pinsel.h lpc17xx_ssp.h lpc17xx_uart.h system_LPC17xx.h
+
+
+
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.c
new file mode 100644
index 0000000..b17f0d9
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.c
@@ -0,0 +1,335 @@
+/**
+ * @file	: lpc17xx_adc.c
+ * @brief	: Contains all functions support for ADC firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 3. April. 2009
+ * @author	: NgaDinh
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup ADC
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_adc.h"
+#include "lpc17xx_clkpwr.h"
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _ADC
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup ADC_Public_Functions
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief 		Initial for ADC
+ * 					- Set bit PCADC
+ * 					- Set clock for ADC
+ * 					- Set Clock Frequency
+ *
+ * @param[in]	ADCx pointer to LPC_ADC_TypeDef
+ * @param[in]	ConvFreq Clock frequency
+ * @return 		None
+ **********************************************************************/
+void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t ConvFreq)
+
+{
+	uint32_t temp, tmp;
+
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_FREQUENCY(ConvFreq));
+
+	// Turn on power and clock
+	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCAD, ENABLE);
+	// Set clock divider for ADC to 4 from CCLK as default
+	// CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_ADC,CLKPWR_PCLKSEL_CCLK_DIV_4);
+
+	ADCx->ADCR = 0;
+
+	//Enable PDN bit
+	tmp = ADC_CR_PDN;
+	// Set clock frequency
+	temp = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_ADC) ;
+	temp = (temp /ConvFreq) - 1;
+	tmp |=  ADC_CR_CLKDIV(temp);
+
+	ADCx->ADCR = tmp;
+}
+
+
+/*********************************************************************//**
+* @brief 		Close ADC
+* @param[in]	ADCx pointer to ADC
+* @return 		None
+**********************************************************************/
+void 		ADC_DeInit(LPC_ADC_TypeDef *ADCx)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+
+	// Clear PDN bit
+	ADCx->ADCR &= ~ADC_CR_PDN;
+	// Turn on power and clock
+	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCAD, DISABLE);
+}
+
+
+/*********************************************************************//**
+* @brief 		Get Result conversion from A/D data register
+* @param[in]	channel number which want to read back the result
+* @return 		Result of conversion
+*********************************************************************/
+uint32_t ADC_GetData(uint32_t channel)
+{
+	uint32_t adc_value;
+
+	CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
+
+	adc_value = *(uint32_t *)((&LPC_ADC->ADDR0) + channel);
+	return ADC_GDR_RESULT(adc_value);
+}
+
+/*********************************************************************//**
+* @brief 		Set start mode for ADC
+* @param[in]	ADCx pointer to LPC_ADC_TypeDef
+* @param[in]	start_mode Start mode choose one of modes in
+* 							'ADC_START_OPT' enumeration type definition
+* @return 		None
+*********************************************************************/
+void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_START_OPT(start_mode));
+
+	ADCx->ADCR &= ~ADC_CR_START_MASK;
+	ADCx->ADCR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode);
+}
+
+
+/*********************************************************************//**
+* @brief 		ADC Burst mode setting
+*
+* @param[in]	ADCx pointer to ADC
+* @param[in]	NewState
+* 				-	1: Set Burst mode
+* 				-	0: reset Burst mode
+* @return 		None
+**********************************************************************/
+void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+
+	ADCx->ADCR &= ~ADC_CR_BURST;
+	if (NewState){
+		ADCx->ADCR |= ADC_CR_BURST;
+	}
+
+}
+
+/*********************************************************************//**
+* @brief 		Set AD conversion in power mode
+*
+* @param[in]	ADCx pointer to ADC
+* @param[in]	NewState
+* 				-	1: AD converter is optional
+* 				-	0: AD Converter is in power down mode
+* @return 		None
+**********************************************************************/
+void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+
+	ADCx->ADCR &= ~ADC_CR_PDN;
+	if (NewState){
+		ADCx->ADCR |= ADC_CR_PDN;
+	}
+}
+
+/*********************************************************************//**
+* @brief 		Set Edge start configuration
+*
+* @param[in]	ADCx pointer to ADC
+* @param[in]	EdgeOption is ADC_START_ON_RISING and ADC_START_ON_FALLING
+* 					0:ADC_START_ON_RISING
+* 					1:ADC_START_ON_FALLING
+*
+* @return 		None
+**********************************************************************/
+void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_START_ON_EDGE_OPT(EdgeOption));
+
+	ADCx->ADCR &= ~ADC_CR_EDGE;
+	if (EdgeOption){
+		ADCx->ADCR |= ADC_CR_EDGE;
+	}
+}
+
+/*********************************************************************//**
+* @brief 		ADC interrupt configuration
+* @param[in]	ADCx pointer to ADC
+* @param[in]	IntType
+* @param[in]	NewState:
+* 					- SET : enable ADC interrupt
+* 					- RESET: disable ADC interrupt
+*
+* @return 		None
+**********************************************************************/
+void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_TYPE_INT_OPT(IntType));
+
+	ADCx->ADINTEN &= ~ADC_INTEN_CH(IntType);
+	if (NewState){
+		ADCx->ADINTEN |= ADC_INTEN_CH(IntType);
+	}
+}
+
+/*********************************************************************//**
+* @brief 		Enable/Disable ADC channel number
+* @param[in]	ADCx pointer to ADC
+* @param[in]	Channel channel number
+* @param[in]	NewState Enable or Disable
+*
+* @return 		None
+**********************************************************************/
+void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(Channel));
+
+	if (NewState == ENABLE) {
+		ADCx->ADCR |= ADC_CR_CH_SEL(Channel);
+	} else {
+		ADCx->ADCR &= ~ADC_CR_CH_SEL(Channel);
+	}
+}
+
+/*********************************************************************//**
+* @brief 		Get ADC result
+* @param[in]	ADCx pointer to ADC
+* @param[in]	channel channel number
+* @return 		Data conversion
+**********************************************************************/
+uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel)
+{
+	uint32_t adc_value;
+
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
+
+	adc_value = *(uint32_t *) ((&ADCx->ADDR0) + channel);
+	return ADC_DR_RESULT(adc_value);
+}
+
+/*********************************************************************//**
+* @brief 		Get ADC Chanel status from ADC data register
+* @param[in]	ADCx pointer to ADC
+* @param[in]	channel channel number
+* @param[in]  	StatusType
+*              		 	0:Burst status
+*               		1:Done 	status
+* @return 		SET / RESET
+**********************************************************************/
+FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType)
+{
+	uint32_t temp;
+
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
+	CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));
+
+	temp =  *(uint32_t *) ((&ADCx->ADDR0) + channel);
+	if (StatusType) {
+		temp &= ADC_DR_DONE_FLAG;
+	}else{
+		temp &= ADC_DR_OVERRUN_FLAG;
+	}
+	if (temp) {
+		return SET;
+	} else {
+		return RESET;
+	}
+
+}
+
+/*********************************************************************//**
+* @brief 		Get ADC Data from AD Global register
+* @param[in]	ADCx pointer to ADC
+* @param[in]	channel channel number
+* @return 		Result of conversion
+**********************************************************************/
+uint16_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel)
+{
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
+
+	//ADCx->ADGDR &= ~ADC_GDR_CH_MASK;
+	//ADCx->ADGDR |= ADC_GDR_CH(channel);
+	return (uint16_t)(ADC_GDR_RESULT(ADCx->ADGDR));
+}
+
+/*********************************************************************//**
+* @brief 		Get ADC Chanel status from AD global data register
+* @param[in]	ADCx pointer to ADC
+* @param[in]  	StatusType
+*              		 	0:Burst status
+*               		1:Done 	status
+* @return 		SET / RESET
+**********************************************************************/
+FlagStatus	ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType)
+{
+	uint32_t temp;
+
+	CHECK_PARAM(PARAM_ADCx(ADCx));
+	CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));
+
+	temp =  ADCx->ADGDR;
+	if (StatusType){
+		temp &= ADC_DR_DONE_FLAG;
+	}else{
+		temp &= ADC_DR_OVERRUN_FLAG;
+	}
+	if (temp){
+		return SET;
+	}else{
+		return RESET;
+	}
+}
+
+/**
+ * @}
+ */
+
+#endif /* _ADC */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
+
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.h
new file mode 100644
index 0000000..3f8e8bc
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_adc.h
@@ -0,0 +1,299 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_adc.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for ADC firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 3. April. 2009
+ * @author	: NgaDinh
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup ADC
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_ADC_H_
+#define LPC17XX_ADC_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup ADC_Private_Macros ADC_Private_Macros
+ * @{
+ */
+
+
+/** @defgroup group3 ADC_REGISTER_BIT_DEFINITIONS
+ * @{
+ */
+
+/*********************************************************************//**
+ * Macro defines for ADC  control register
+ **********************************************************************/
+/**  Selects which of the AD0.0:7 pins is (are) to be sampled and converted */
+#define ADC_CR_CH_SEL(n)	((1UL << n))
+/**  The APB clock (PCLK) is divided by (this value plus one)
+* to produce the clock for the A/D */
+#define ADC_CR_CLKDIV(n)	((n<<8))
+/**  Repeated conversions A/D enable bit */
+#define ADC_CR_BURST		((1UL<<16))
+/**  ADC convert in power down mode */
+#define ADC_CR_PDN			((1UL<<21))
+/**  Start mask bits */
+#define ADC_CR_START_MASK	((7UL<<24))
+/**  Select Start Mode */
+#define ADC_CR_START_MODE_SEL(SEL)	((SEL<<24))
+/**  Start conversion now */
+#define ADC_CR_START_NOW	((1UL<<24))
+/**  Start conversion when the edge selected by bit 27 occurs on P2.10/EINT0 */
+#define ADC_CR_START_EINT0	((2UL<<24))
+/** Start conversion when the edge selected by bit 27 occurs on P1.27/CAP0.1 */
+#define ADC_CR_START_CAP01	((3UL<<24))
+/**  Start conversion when the edge selected by bit 27 occurs on MAT0.1 */
+#define ADC_CR_START_MAT01	((4UL<<24))
+/**  Start conversion when the edge selected by bit 27 occurs on MAT0.3 */
+#define ADC_CR_START_MAT03	((5UL<<24))
+/**  Start conversion when the edge selected by bit 27 occurs on MAT1.0 */
+#define ADC_CR_START_MAT10	((6UL<<24))
+/**  Start conversion when the edge selected by bit 27 occurs on MAT1.1 */
+#define ADC_CR_START_MAT11	((7UL<<24))
+/**  Start conversion on a falling edge on the selected CAP/MAT signal */
+#define ADC_CR_EDGE			((1UL<<27))
+
+/*********************************************************************//**
+ * Macro defines for ADC Global Data register
+ **********************************************************************/
+/** When DONE is 1, this field contains result value of ADC conversion */
+#define ADC_GDR_RESULT(n)		(((n>>4)&0xFFF))
+/** These bits contain the channel from which the LS bits were converted */
+#define ADC_GDR_CH(n)			(((n>>24)&0x7))
+/** This bit is 1 in burst mode if the results of one or
+ * more conversions was (were) lost */
+#define ADC_GDR_OVERRUN_FLAG	((1UL<<30))
+/** This bit is set to 1 when an A/D conversion completes */
+#define ADC_GDR_DONE_FLAG		((1UL<<31))
+
+/** This bits is used to mask for Channel */
+#define ADC_GDR_CH_MASK		((7UL<<24))
+/*********************************************************************//**
+ * Macro defines for ADC Interrupt register
+ **********************************************************************/
+/** These bits allow control over which A/D channels generate
+ * interrupts for conversion completion */
+#define ADC_INTEN_CH(n)			((1UL<<n))
+/** When 1, enables the global DONE flag in ADDR to generate an interrupt */
+#define ADC_INTEN_GLOBAL		((1UL<<8))
+
+/*********************************************************************//**
+ * Macro defines for ADC Data register
+ **********************************************************************/
+/** When DONE is 1, this field contains result value of ADC conversion */
+#define ADC_DR_RESULT(n)		(((n>>4)&0xFFF))
+/** These bits mirror the OVERRRUN status flags that appear in the
+ * result register for each A/D channel */
+#define ADC_DR_OVERRUN_FLAG		((1UL<<30))
+/** This bit is set to 1 when an A/D conversion completes. It is cleared
+ * when this register is read */
+#define ADC_DR_DONE_FLAG		((1UL<<31))
+
+/*********************************************************************//**
+ * Macro defines for ADC Status register
+**********************************************************************/
+/** These bits mirror the DONE status flags that appear in the result
+ * register for each A/D channel */
+#define ADC_STAT_CH_DONE_FLAG(n)		((n&0xFF))
+/** These bits mirror the OVERRRUN status flags that appear in the
+ * result register for each A/D channel */
+#define ADC_STAT_CH_OVERRUN_FLAG(n)		(((n>>8)&0xFF))
+/** This bit is the A/D interrupt flag */
+#define ADC_STAT_INT_FLAG				((1UL<<16))
+
+/*********************************************************************//**
+ * Macro defines for ADC Trim register
+**********************************************************************/
+/** Offset trim bits for ADC operation */
+#define ADC_ADCOFFS(n)		(((n&0xF)<<4))
+/** Written to boot code*/
+#define ADC_TRIM(n)		    (((n&0xF)<<8))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup ADC_Public_Types
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief ADC enumeration
+ **********************************************************************/
+/** @brief Channel Selection */
+typedef enum
+{
+	ADC_CHANNEL_0  = 0, /*!<  Channel 0 */
+	ADC_CHANNEL_1,		/*!<  Channel 1 */
+	ADC_CHANNEL_2,		/*!<  Channel 2 */
+	ADC_CHANNEL_3,		/*!<  Channel 3 */
+	ADC_CHANNEL_4,		/*!<  Channel 4 */
+	ADC_CHANNEL_5,		/*!<  Channel 5 */
+	ADC_CHANNEL_6,		/*!<  Channel 6 */
+	ADC_CHANNEL_7		/*!<  Channel 7 */
+}ADC_CHANNEL_SELECTION;
+
+
+
+/** @brief Type of start option */
+
+/** @brief Type of start option */
+
+typedef enum
+{
+	ADC_START_CONTINUOUS =0,	/*!< Continuous mode */
+	ADC_START_NOW,				/*!< Start conversion now */
+	ADC_START_ON_EINT0,			/*!< Start conversion when the edge selected
+								 * by bit 27 occurs on P2.10/EINT0 */
+	ADC_START_ON_CAP01,			/*!< Start conversion when the edge selected
+								 * by bit 27 occurs on P1.27/CAP0.1 */
+	ADC_START_ON_MAT01,			/*!< Start conversion when the edge selected
+								 * by bit 27 occurs on MAT0.1 */
+	ADC_START_ON_MAT03,			/*!< Start conversion when the edge selected
+								 * by bit 27 occurs on MAT0.3 */
+	ADC_START_ON_MAT10,			/*!< Start conversion when the edge selected
+								  * by bit 27 occurs on MAT1.0 */
+	ADC_START_ON_MAT11			/*!< Start conversion when the edge selected
+								  * by bit 27 occurs on MAT1.1 */
+} ADC_START_OPT;
+
+
+/** @brief Type of edge when start conversion on the selected CAP/MAT signal */
+
+typedef enum
+{
+	ADC_START_ON_RISING = 0,	/*!< Start conversion on a rising edge
+								*on the selected CAP/MAT signal */
+	ADC_START_ON_FALLING		/*!< Start conversion on a falling edge
+								*on the selected CAP/MAT signal */
+} ADC_START_ON_EDGE_OPT;
+
+/** @brief* ADC type interrupt enum */
+typedef enum
+{
+	ADC_ADINTEN0 = 0,		/*!< Interrupt channel 0 */
+	ADC_ADINTEN1,			/*!< Interrupt channel 1 */
+	ADC_ADINTEN2,			/*!< Interrupt channel 2 */
+	ADC_ADINTEN3,			/*!< Interrupt channel 3 */
+	ADC_ADINTEN4,			/*!< Interrupt channel 4 */
+	ADC_ADINTEN5,			/*!< Interrupt channel 5 */
+	ADC_ADINTEN6,			/*!< Interrupt channel 6 */
+	ADC_ADINTEN7,			/*!< Interrupt channel 7 */
+	ADC_ADGINTEN			/*!< Individual channel/global flag done generate an interrupt */
+}ADC_TYPE_INT_OPT;
+
+/** Macro to determine if it is valid interrupt type */
+#define PARAM_ADC_TYPE_INT_OPT(OPT) ((OPT == ADC_ADINTEN0)||(OPT == ADC_ADINTEN1)\
+||(OPT == ADC_ADINTEN2)||(OPT == ADC_ADINTEN3)\
+||(OPT == ADC_ADINTEN4)||(OPT == ADC_ADINTEN5)\
+||(OPT == ADC_ADINTEN6)||(OPT == ADC_ADINTEN7)\
+||(OPT == ADC_ADGINTEN))
+
+
+/** @brief ADC Data  status */
+typedef enum
+{
+	ADC_DATA_BURST = 0,		/*Burst bit*/
+	ADC_DATA_DONE		 /*Done bit*/
+}ADC_DATA_STATUS;
+
+
+#define PARAM_ADC_START_ON_EDGE_OPT(OPT)	((OPT == ADC_START_ON_RISING)||(OPT == ADC_START_ON_FALLING))
+
+#define PARAM_ADC_DATA_STATUS(OPT)	((OPT== ADC_DATA_BURST)||(OPT== ADC_DATA_DONE))
+
+#define PARAM_ADC_FREQUENCY(FRE) (FRE <= 13000000 )
+
+#define PARAM_ADC_CHANNEL_SELECTION(SEL)     ((SEL == ADC_CHANNEL_0)||(ADC_CHANNEL_1)\
+||(SEL == ADC_CHANNEL_2)|(ADC_CHANNEL_3)\
+||(SEL == ADC_CHANNEL_4)||(ADC_CHANNEL_5)\
+||(SEL == ADC_CHANNEL_6)||(ADC_CHANNEL_7))
+
+#define PARAM_ADC_START_OPT(OPT)	((OPT == ADC_START_CONTINUOUS)||(OPT == ADC_START_NOW)\
+||(OPT == ADC_START_ON_EINT0)||(OPT == ADC_START_ON_CAP01)\
+||(OPT == ADC_START_ON_MAT01)||(OPT == ADC_START_ON_MAT03)\
+||(OPT == ADC_START_ON_MAT10)||(OPT == ADC_START_ON_MAT11))
+
+#define PARAM_ADC_TYPE_INT_OPT(OPT) ((OPT == ADC_ADINTEN0)||(OPT == ADC_ADINTEN1)\
+||(OPT == ADC_ADINTEN2)||(OPT == ADC_ADINTEN3)\
+||(OPT == ADC_ADINTEN4)||(OPT == ADC_ADINTEN5)\
+||(OPT == ADC_ADINTEN6)||(OPT == ADC_ADINTEN7)\
+||(OPT == ADC_ADGINTEN))
+
+#define PARAM_ADCx(n)	(((uint32_t *)n)==((uint32_t *)LPC_ADC))
+
+/**
+ * @}
+ */
+
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup ADC_Public_Functions
+ * @{
+ */
+
+void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t ConvFreq);
+void ADC_DeInit(LPC_ADC_TypeDef *ADCx);
+void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState);
+void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState);
+void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode);
+void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption);
+void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState);
+void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState);
+uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel);
+FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType);
+uint16_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel);
+FlagStatus	ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* LPC17XX_ADC_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.c
new file mode 100644
index 0000000..2373aaa
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.c
@@ -0,0 +1,1919 @@
+/**
+ * @file	: lpc17xx_can.c
+ * @brief	: Contains all functions support for CAN firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 1.June.2009
+ * @author	: NguyenCao
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup CAN
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_can.h"
+#include "lpc17xx_clkpwr.h"
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _CAN
+
+/* Private Variables ---------------------------------------------------------- */
+/** @defgroup CAN_Private_Variables
+ * @{
+ */
+
+FunctionalState FULLCAN_ENABLE;
+
+//use for debugging
+LPC_CAN_TypeDef *CAN1x = LPC_CAN1;
+LPC_CAN_TypeDef *CAN2x = LPC_CAN2;
+LPC_CANAF_RAM_TypeDef *CANAFRAMx = LPC_CANAF_RAM;
+LPC_CANAF_TypeDef *CANAFx = LPC_CANAF;
+
+/* Values of bit time register for different baudrates
+   NT = Nominal bit time = TSEG1 + TSEG2 + 3
+   SP = Sample point     = ((TSEG2 +1) / (TSEG1 + TSEG2 + 3)) * 100%
+                                            SAM,  SJW, TSEG1, TSEG2, NT,  SP */
+const uint32_t CAN_BIT_TIME[] ={0, /*             not used             */
+0, /*             not used             */
+0, /*             not used             */
+0, /*             not used             */
+0x0001C000, /* 0+1,  3+1,   1+1,   0+1,  4, 75% */
+0, /*             not used             */
+0x0012C000, /* 0+1,  3+1,   2+1,   1+1,  6, 67% */
+0, /*             not used             */
+0x0023C000, /* 0+1,  3+1,   3+1,   2+1,  8, 63% */
+0, /*             not used             */
+0x0025C000, /* 0+1,  3+1,   5+1,   2+1, 10, 70% */
+0, /*             not used             */
+0x0036C000, /* 0+1,  3+1,   6+1,   3+1, 12, 67% */
+0, /*             not used             */
+0, /*             not used             */
+0x0048C000, /* 0+1,  3+1,   8+1,   4+1, 15, 67% */
+0x0049C000, /* 0+1,  3+1,   9+1,   4+1, 16, 69% */
+};
+
+/* Counts number of filters (CAN message objects) used */
+uint16_t CANAF_FullCAN_cnt = 0;
+uint16_t CANAF_std_cnt = 0;
+uint16_t CANAF_gstd_cnt = 0;
+uint16_t CANAF_ext_cnt = 0;
+uint16_t CANAF_gext_cnt = 0;
+
+static fnCANCbs_Type* _apfnCANCbs[12]={
+		NULL, 	//CAN Recieve  Call-back funtion pointer
+		NULL,	//CAN Transmit1 Call-back funtion pointer
+		NULL,	//CAN Error Warning Call-back function pointer
+		NULL,	//CAN Data Overrun Call-back function pointer
+		NULL,	//CAN Wake-up Call-back funtion pointer
+		NULL,	//CAN Error Passive Call-back function pointer
+		NULL,	//CAN Arbitration Lost Call-back function pointer
+		NULL,	//CAN Bus Error Call-back function pointer
+		NULL,	//CAN ID Ready Call-back function pointer
+		NULL,	//CAN Transmit2 Call-back function pointer
+		NULL,	//CAN Transmit3 Call-back function pointer
+		NULL	//FullCAN Receive Call-back function pointer
+};
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup CAN_Public_Functions
+ * @{
+ */
+
+
+/*********************************************************************//**
+ * @brief 		Setting CAN baud rate (bps)
+ * @param[in] 	CANx point to LPC_CAN_TypeDef object, should be:
+ * 				- CAN1
+ * 				- CAN2
+ * @param[in]	baudrate is the baud rate value will be set
+ * @return 		None
+ ***********************************************************************/
+void CAN_SetBaudRate (LPC_CAN_TypeDef *CANx, uint32_t baudrate)
+{
+	uint32_t nominal_time;
+	uint32_t result = 0;
+	uint32_t CANPclk = 0;
+
+	CHECK_PARAM(PARAM_CANx(CANx));
+
+	if (CANx == LPC_CAN1)
+	{
+		CANPclk = CLKPWR_GetPCLK (CLKPWR_PCONP_PCAN1);
+	}
+	else
+	{
+		CANPclk = CLKPWR_GetPCLK (CLKPWR_PCONP_PCAN2);
+	}
+	/* Determine which nominal time to use for PCLK and baudrate */
+	if (baudrate <= 500000)
+	{
+		nominal_time = 12;
+	}
+	else if (((CANPclk / 1000000) % 15) == 0)
+	{
+		nominal_time = 15;
+	}
+	else if (((CANPclk / 1000000) % 16) == 0)
+	{
+		nominal_time = 16;
+	}
+	else
+	{
+		nominal_time = 10;
+	}
+
+	/* Prepare value appropriate for bit time register                         */
+	result  = (CANPclk / nominal_time) / baudrate - 1;
+	result &= 0x000003FF;
+	result |= CAN_BIT_TIME[nominal_time];
+
+	/* Enter reset mode */
+	CANx->MOD = 0x01;
+	/* Set bit timing */
+	CANx->BTR  = result;
+
+	/* Return to normal operating */
+	CANx->MOD = 0;
+}
+
+/********************************************************************//**
+ * @brief		Initialize CAN peripheral with given baudrate
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	baudrate: the value of CAN baudrate will be set (bps)
+ * @return 		void
+ *********************************************************************/
+void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate)
+{
+	uint32_t temp;
+	uint16_t i;
+	CHECK_PARAM(PARAM_CANx(CANx));
+
+	if(CANx == LPC_CAN1)
+	{
+		/* Turn on power and clock for CAN1 */
+		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE);
+		/* Set clock divide for CAN1 */
+		CLKPWR_SetPCLKDiv (CLKPWR_PCONP_PCAN1, CLKPWR_PCLKSEL_CCLK_DIV_4);
+	}
+	else
+	{
+		/* Turn on power and clock for CAN1 */
+		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE);
+		/* Set clock divide for CAN2 */
+		CLKPWR_SetPCLKDiv (CLKPWR_PCONP_PCAN2, CLKPWR_PCLKSEL_CCLK_DIV_4);
+	}
+
+	CANx->MOD = 1; // Enter Reset Mode
+	CANx->IER = 0; // Disable All CAN Interrupts
+	CANx->GSR = 0;
+	/* Request command to release Rx, Tx buffer and clear data overrun */
+	//CANx->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO;
+	CANx->CMR = (1<<1)|(1<<2)|(1<<3);
+	/* Read to clear interrupt pending in interrupt capture register */
+	temp = CANx->ICR;
+	CANx->MOD = 0;// Return Normal operating
+
+	//Reset CANAF value
+	LPC_CANAF->AFMR = 0x01;
+
+	//clear ALUT RAM
+	for (i = 0; i < 512; i++) {
+		LPC_CANAF_RAM->mask[i] = 0x00;
+	}
+
+	LPC_CANAF->SFF_sa = 0x00;
+	LPC_CANAF->SFF_GRP_sa = 0x00;
+	LPC_CANAF->EFF_sa = 0x00;
+	LPC_CANAF->EFF_GRP_sa = 0x00;
+	LPC_CANAF->ENDofTable = 0x00;
+
+	LPC_CANAF->AFMR = 0x00;
+	/* Set baudrate */
+	CAN_SetBaudRate (CANx, baudrate);
+}
+/********************************************************************//**
+ * @brief		CAN deInit
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @return 		void
+ *********************************************************************/
+void CAN_DeInit(LPC_CAN_TypeDef *CANx)
+{
+	CHECK_PARAM(PARAM_CANx(CANx));
+
+	if(CANx == LPC_CAN1)
+	{
+		/* Turn on power and clock for CAN1 */
+		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, DISABLE);
+	}
+	else
+	{
+		/* Turn on power and clock for CAN1 */
+		CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, DISABLE);
+	}
+}
+/********************************************************************//**
+ * @brief		Setup Acceptance Filter Look-Up Table
+ * @param[in]	CANAFx	pointer to LPC_CANAF_TypeDef, should be: CANAF
+ * @param[in]	AFSection	the pointer to AF_SectionDef struct
+ * 				It contain information about 5 sections will be install in AFLUT
+ * @return 		CAN Error	could be:
+ * 				- CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available
+ * 				- CAN_AF_ENTRY_ERROR: table error-violation of ascending numerical order
+ * 				- CAN_OK: ID is added into table successfully
+ *********************************************************************/
+CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection)
+{
+	uint8_t ctrl1,ctrl2;
+	uint8_t dis1, dis2;
+	uint16_t SID, SID_temp,i, count = 0;
+	uint32_t EID, EID_temp, entry, buf;
+	uint16_t lowerSID, upperSID;
+	uint32_t lowerEID, upperEID;
+
+	CHECK_PARAM(PARAM_CANAFx(CANAFx));
+	CANAFx->AFMR = 0x01;
+
+/***** setup FullCAN Table *****/
+	if(AFSection->FullCAN_Sec == NULL)
+	{
+		FULLCAN_ENABLE = DISABLE;
+	}
+	else
+	{
+		FULLCAN_ENABLE = ENABLE;
+		for(i=0;i<(AFSection->FC_NumEntry);i++)
+		{
+			if(count + 1 > 64)
+			{
+				return CAN_OBJECTS_FULL_ERROR;
+			}
+			ctrl1 = AFSection->FullCAN_Sec->controller;
+			SID = AFSection->FullCAN_Sec->id_11;
+			dis1 = AFSection->FullCAN_Sec->disable;
+
+			CHECK_PARAM(PARAM_CTRL(ctrl1));
+			CHECK_PARAM(PARAM_ID_11(SID));
+			CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
+			entry = 0x00; //reset entry value
+			if((CANAF_FullCAN_cnt & 0x00000001)==0)
+			{
+				if(count!=0x00)
+				{
+					buf = LPC_CANAF_RAM->mask[count-1];
+					SID_temp = (buf & 0x000003FF);
+					if(SID_temp > SID)
+					{
+						return CAN_AF_ENTRY_ERROR;
+					}
+				}
+				entry = (ctrl1<<29)|(dis1<<28)|(SID<<16)|(1<<27);
+				LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
+				LPC_CANAF_RAM->mask[count] |= entry;
+				CANAF_FullCAN_cnt++;
+			}
+			else
+			{
+				buf = LPC_CANAF_RAM->mask[count];
+				SID_temp = (buf & 0x03FF0000)>>16;
+				if(SID_temp > SID)
+				{
+					return CAN_AF_ENTRY_ERROR;
+				}
+				entry = (ctrl1<<13)|(dis1<<12)|(SID<<0)|(1<<11);
+				LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
+				LPC_CANAF_RAM->mask[count]|= entry;
+				count++;
+				CANAF_FullCAN_cnt++;
+			}
+			AFSection->FullCAN_Sec = (FullCAN_Entry *)((uint32_t)(AFSection->FullCAN_Sec)+ sizeof(FullCAN_Entry));
+		}
+	}
+
+/***** Setup Explicit Standard Frame Format Section *****/
+	if(AFSection->SFF_Sec != NULL)
+	{
+		for(i=0;i<(AFSection->SFF_NumEntry);i++)
+		{
+			if(count + 1 > 512)
+			{
+				return CAN_OBJECTS_FULL_ERROR;
+			}
+			ctrl1 = AFSection->SFF_Sec->controller;
+			SID = AFSection->SFF_Sec->id_11;
+			dis1 = AFSection->SFF_Sec->disable;
+
+			//check parameter
+			CHECK_PARAM(PARAM_CTRL(ctrl1));
+			CHECK_PARAM(PARAM_ID_11(SID));
+			CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
+
+			entry = 0x00; //reset entry value
+			if((CANAF_std_cnt & 0x00000001)==0)
+			{
+				if(CANAF_std_cnt !=0 )
+				{
+					buf = LPC_CANAF_RAM->mask[count-1];
+					SID_temp = (buf & 0x00000FFF);
+					if(SID_temp > SID)
+					{
+						return CAN_AF_ENTRY_ERROR;
+					}
+				}
+				entry = (ctrl1<<29)|(dis1<<28)|(SID<<16);
+				LPC_CANAF_RAM->mask[count] &= 0x0000FFFF;
+				LPC_CANAF_RAM->mask[count] |= entry;
+				CANAF_std_cnt++;
+			}
+			else
+			{
+				buf = LPC_CANAF_RAM->mask[count];
+				SID_temp = (buf & 0x0FFF0000)>>16;
+				if(SID_temp > SID)
+				{
+					return CAN_AF_ENTRY_ERROR;
+				}
+				entry = (ctrl1<<13)|(dis1<<12)|(SID<<0);
+				LPC_CANAF_RAM->mask[count] &= 0xFFFF0000;
+				LPC_CANAF_RAM->mask[count] |= entry;
+				count++;
+				CANAF_std_cnt++;
+			}
+			AFSection->SFF_Sec = (SFF_Entry *)((uint32_t)(AFSection->SFF_Sec)+ sizeof(SFF_Entry));
+		}
+	}
+
+/***** Setup Group of Standard Frame Format Identifier Section *****/
+	if(AFSection->SFF_GPR_Sec != NULL)
+	{
+		for(i=0;i<(AFSection->SFF_GPR_NumEntry);i++)
+		{
+			if(count + 1 > 512)
+			{
+				return CAN_OBJECTS_FULL_ERROR;
+			}
+			ctrl1 = AFSection->SFF_GPR_Sec->controller1;
+			ctrl2 = AFSection->SFF_GPR_Sec->controller2;
+			dis1 = AFSection->SFF_GPR_Sec->disable1;
+			dis2 = AFSection->SFF_GPR_Sec->disable2;
+			lowerSID = AFSection->SFF_GPR_Sec->lowerID;
+			upperSID = AFSection->SFF_GPR_Sec->upperID;
+
+			/* check parameter */
+			CHECK_PARAM(PARAM_CTRL(ctrl1));
+			CHECK_PARAM(PARAM_CTRL(ctrl2));
+			CHECK_PARAM(PARAM_MSG_DISABLE(dis1));
+			CHECK_PARAM(PARAM_MSG_DISABLE(dis2));
+			CHECK_PARAM(PARAM_ID_11(lowerSID));
+			CHECK_PARAM(PARAM_ID_11(upperSID));
+
+			entry = 0x00;
+			if(CANAF_gstd_cnt!=0)
+			{
+				buf = LPC_CANAF_RAM->mask[count-1];
+				SID_temp = buf & 0x00000FFF;
+				if(SID_temp > lowerSID)
+				{
+					return CAN_AF_ENTRY_ERROR;
+				}
+			}
+			entry = (ctrl1 << 29)|(dis1 << 28)|(lowerSID << 16)|  \
+					(ctrl2 << 13)|(dis2 << 12)|(upperSID << 0);
+			LPC_CANAF_RAM->mask[count] = entry;
+			CANAF_gstd_cnt++;
+			count++;
+			AFSection->SFF_GPR_Sec = (SFF_GPR_Entry *)((uint32_t)(AFSection->SFF_GPR_Sec)+ sizeof(SFF_GPR_Entry));
+		}
+	}
+
+/***** Setup Explicit Extend Frame Format Identifier Section *****/
+	if(AFSection->EFF_Sec != NULL)
+	{
+		for(i=0;i<(AFSection->EFF_NumEntry);i++)
+		{
+			if(count + 1 > 512)
+			{
+				return CAN_OBJECTS_FULL_ERROR;
+			}
+			EID = AFSection->EFF_Sec->ID_29;
+			ctrl1 = AFSection->EFF_Sec->controller;
+
+			// check parameter
+			CHECK_PARAM(PARAM_ID_29(EID));
+			CHECK_PARAM(PARAM_CTRL(ctrl1));
+
+			entry = 0x00; //reset entry value
+			if(CANAF_ext_cnt != 0)
+			{
+				buf = LPC_CANAF_RAM->mask[count-1];
+				EID_temp = buf & 0x0FFFFFFF;
+				if(EID_temp > EID)
+				{
+					return CAN_AF_ENTRY_ERROR;
+				}
+			}
+			entry = (ctrl1 << 29)|(EID << 0);
+			LPC_CANAF_RAM->mask[count] = entry;
+			CANAF_ext_cnt ++;
+			count++;
+			AFSection->EFF_Sec = (EFF_Entry *)((uint32_t)(AFSection->EFF_Sec)+ sizeof(EFF_Entry));
+		}
+	}
+
+/***** Setup Group of Extended Frame Format Identifier Section *****/
+	if(AFSection->EFF_GPR_Sec != NULL)
+	{
+		for(i=0;i<(AFSection->EFF_GPR_NumEntry);i++)
+		{
+			if(count + 2 > 512)
+			{
+				return CAN_OBJECTS_FULL_ERROR;
+			}
+			ctrl1 = AFSection->EFF_GPR_Sec->controller1;
+			ctrl2 = AFSection->EFF_GPR_Sec->controller2;
+			lowerEID = AFSection->EFF_GPR_Sec->lowerEID;
+			upperEID = AFSection->EFF_GPR_Sec->upperEID;
+
+			//check parameter
+			CHECK_PARAM(PARAM_CTRL(ctrl1));
+			CHECK_PARAM(PARAM_CTRL(ctrl2));
+			CHECK_PARAM(PARAM_ID_29(lowerEID));
+			CHECK_PARAM(PARAM_ID_29(upperEID));
+
+			entry = 0x00;
+			if(CANAF_gext_cnt != 0)
+			{
+				buf = LPC_CANAF_RAM->mask[count-1];
+				EID_temp = buf & 0x0FFFFFFF;
+				if(EID_temp > lowerEID)
+				{
+					return CAN_AF_ENTRY_ERROR;
+				}
+			}
+			entry = (ctrl1 << 29)|(lowerEID << 0);
+			LPC_CANAF_RAM->mask[count++] = entry;
+			entry = (ctrl2 << 29)|(upperEID << 0);
+			LPC_CANAF_RAM->mask[count++] = entry;
+			CANAF_gext_cnt++;
+			AFSection->EFF_GPR_Sec = (EFF_GPR_Entry *)((uint32_t)(AFSection->EFF_GPR_Sec)+ sizeof(EFF_GPR_Entry));
+		}
+	}
+	//update address values
+	LPC_CANAF->SFF_sa = ((CANAF_FullCAN_cnt + 1)>>1)<<2;
+	LPC_CANAF->SFF_GRP_sa = LPC_CANAF->SFF_sa + (((CANAF_std_cnt+1)>>1)<< 2);
+	LPC_CANAF->EFF_sa = LPC_CANAF->SFF_GRP_sa + (CANAF_gstd_cnt << 2);
+	LPC_CANAF->EFF_GRP_sa = LPC_CANAF->EFF_sa + (CANAF_ext_cnt << 2);
+	LPC_CANAF->ENDofTable = LPC_CANAF->EFF_GRP_sa + (CANAF_gext_cnt << 3);
+
+	if(FULLCAN_ENABLE == DISABLE)
+	{
+		LPC_CANAF->AFMR = 0x00; // Normal mode
+	}
+	else
+	{
+		LPC_CANAF->AFMR = 0x04;
+	}
+	return CAN_OK;
+}
+/********************************************************************//**
+ * @brief		Add Explicit ID into AF Look-Up Table dynamically.
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	id: The ID of entry will be added
+ * @param[in]	format: is the type of ID Frame Format, should be:
+ * 				- STD_ID_FORMAT: 11-bit ID value
+ * 				- EXT_ID_FORMAT: 29-bit ID value
+ * @return 		CAN Error, could be:
+ * 				- CAN_OBJECTS_FULL_ERROR: No more rx or tx objects available
+ * 				- CAN_ID_EXIT_ERROR: ID exited in table
+ * 				- CAN_OK: ID is added into table successfully
+ *********************************************************************/
+CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t id, CAN_ID_FORMAT_Type format)
+{
+	uint32_t tmp0 = 0;
+	uint32_t buf0=0, buf1=0;
+	int16_t cnt1=0, cnt2=0, bound1=0, total=0;
+
+
+	CHECK_PARAM(PARAM_CANx(CANx));
+	CHECK_PARAM(PARAM_ID_FORMAT(format));
+
+	if (CANx == LPC_CAN1)
+	{
+		tmp0 = 0;
+	}
+	else if (CANx == LPC_CAN2)
+	{
+		tmp0 = 1;
+	}
+
+	/* Acceptance Filter Memory full - return */
+	total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
+			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
+	if (total >= 512){ //don't have enough space
+		return CAN_OBJECTS_FULL_ERROR;
+	}
+
+	/* Setup Acceptance Filter Configuration
+    Acceptance Filter Mode Register = Off */
+	LPC_CANAF->AFMR = 0x00000001;
+
+/*********** Add Explicit Standard Identifier Frame Format entry *********/
+ 	if(format == STD_ID_FORMAT)
+ 	{
+ 		id &= 0x07FF;
+ 		id |= (tmp0 << 13); /* Add controller number */
+		/* Move all remaining sections one place up
+		if new entry will increase FullCAN list */
+		if ((CANAF_std_cnt & 0x0001) == 0)
+		{
+			cnt1   = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
+			bound1 = total - cnt1;
+			buf0   = LPC_CANAF_RAM->mask[cnt1];
+			while(bound1--)
+			{
+				cnt1++;
+				buf1 = LPC_CANAF_RAM->mask[cnt1];
+				LPC_CANAF_RAM->mask[cnt1] = buf0;
+				buf0 = buf1;
+			}
+		}
+		if (CANAF_std_cnt == 0)
+		{
+			cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
+			/* For entering first ID */
+			LPC_CANAF_RAM->mask[cnt2] = 0x0000FFFF | (id << 16);
+		}
+		else if (CANAF_std_cnt == 1)
+		{
+			cnt2 = (CANAF_FullCAN_cnt + 1)>>1;
+			/* For entering second ID */
+			if ((LPC_CANAF_RAM->mask[cnt2] >> 16) > id)
+			{
+				LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] >> 16) | (id << 16);
+			}
+			else
+			{
+				LPC_CANAF_RAM->mask[cnt2] = (LPC_CANAF_RAM->mask[cnt2] & 0xFFFF0000) | id;
+			}
+		}
+		else
+		{
+			/* Find where to insert new ID */
+			cnt1 = (CANAF_FullCAN_cnt+1)>>1;
+			cnt2 = CANAF_std_cnt;
+			bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1);
+			while (cnt1 < bound1)
+			{
+				/* Loop through standard existing IDs */
+				if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)
+				{
+					cnt2 = cnt1 * 2;
+					break;
+				}
+
+				if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)
+				{
+					cnt2 = cnt1 * 2 + 1;
+					break;
+				}
+
+				cnt1++;
+			}
+			/* cnt1 = U32 where to insert new ID */
+			/* cnt2 = U16 where to insert new ID */
+
+			if (cnt1 == bound1)
+			{
+				/* Adding ID as last entry */
+				/* Even number of IDs exists */
+				if ((CANAF_std_cnt & 0x0001) == 0)
+				{
+					LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
+				}
+				/* Odd  number of IDs exists */
+				else
+				{
+					LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
+				}
+			}
+			else
+			{
+				buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
+				if ((cnt2 & 0x0001) == 0)
+				{
+					/* Insert new mask to even address*/
+					buf1 = (id << 16) | (buf0 >> 16);
+				}
+				else
+				{
+					/* Insert new mask to odd  address */
+					buf1 = (buf0 & 0xFFFF0000) | id;
+				}
+				LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
+				bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1)-1;
+				/* Move all remaining standard mask entries one place up */
+				while (cnt1 < bound1)
+				{
+					cnt1++;
+					buf1  = LPC_CANAF_RAM->mask[cnt1];
+					LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
+					buf0  = buf1;
+				}
+
+				if ((CANAF_std_cnt & 0x0001) == 0)
+				{
+					/* Even number of IDs exists */
+					LPC_CANAF_RAM->mask[cnt1+1] = (buf0 <<16) |(0x0000FFFF);
+				}
+			}
+		}
+		CANAF_std_cnt++;
+		//update address values
+		LPC_CANAF->SFF_GRP_sa +=0x04 ;
+		LPC_CANAF->EFF_sa     +=0x04 ;
+		LPC_CANAF->EFF_GRP_sa +=0x04;
+		LPC_CANAF->ENDofTable +=0x04;
+ 	}
+
+/*********** Add Explicit Extended Identifier Frame Format entry *********/
+ 	else
+ 	{
+ 		/* Add controller number */
+ 		id |= (tmp0) << 29;
+
+ 		cnt1 = ((CANAF_FullCAN_cnt+1)>>1)+(((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt);
+ 		cnt2 = 0;
+ 		while (cnt2 < CANAF_ext_cnt)
+ 		{
+ 			/* Loop through extended existing masks*/
+ 			if (LPC_CANAF_RAM->mask[cnt1] > id)
+ 			{
+ 				break;
+ 			}
+ 			cnt1++;/* cnt1 = U32 where to insert new mask */
+			cnt2++;
+ 		}
+
+ 		buf0 = LPC_CANAF_RAM->mask[cnt1];  /* Remember current entry */
+ 		LPC_CANAF_RAM->mask[cnt1] = id;    /* Insert mask */
+
+ 		CANAF_ext_cnt++;
+
+ 		bound1 = total;
+ 		/* Move all remaining extended mask entries one place up*/
+ 		while (cnt2 < bound1)
+ 		{
+ 			cnt1++;
+ 			cnt2++;
+ 			buf1 = LPC_CANAF_RAM->mask[cnt1];
+ 			LPC_CANAF_RAM->mask[cnt1] = buf0;
+ 			buf0 = buf1;
+ 		}
+ 		/* update address values */
+ 		LPC_CANAF->EFF_GRP_sa += 4;
+ 		LPC_CANAF->ENDofTable += 4;
+ 	}
+ 	if(CANAF_FullCAN_cnt == 0) //not use FullCAN mode
+ 	{
+ 		LPC_CANAF->AFMR = 0x00;//not use FullCAN mode
+ 	}
+ 	else
+ 	{
+ 		LPC_CANAF->AFMR = 0x04;
+ 	}
+
+ 	return CAN_OK;
+}
+
+/********************************************************************//**
+ * @brief		Load FullCAN entry into AFLUT
+ * @param[in]	CANx: CAN peripheral selected, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	id: identifier of entry that will be added
+ * @return 		CAN_ERROR, could be:
+ * 				- CAN_OK: loading is successful
+ * 				- CAN_ID_EXIT_ERROR: ID exited in FullCAN Section
+ * 				- CAN_OBJECTS_FULL_ERROR: no more space available
+ *********************************************************************/
+CAN_ERROR CAN_LoadFullCANEntry (LPC_CAN_TypeDef* CANx, uint16_t id)
+{
+	uint32_t ctrl0 = 0;
+	uint32_t buf0=0, buf1=0, buf2=0;
+	uint32_t tmp0=0, tmp1=0, tmp2=0;
+	int16_t cnt1=0, cnt2=0, bound1=0, total=0;
+
+	CHECK_PARAM(PARAM_CANx(CANx));
+
+	if (CANx == LPC_CAN1)
+	{
+		ctrl0 = 0;
+	}
+	else if (CANx == LPC_CAN2)
+	{
+		ctrl0 = 1;
+	}
+
+	/* Acceptance Filter Memory full - return */
+	total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
+			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
+	//don't have enough space for this fullCAN Entry and its Object(3*32 bytes)
+	if ((total >=508)||(CANAF_FullCAN_cnt>=64)){
+		return CAN_OBJECTS_FULL_ERROR;
+	}
+	/* Setup Acceptance Filter Configuration
+    Acceptance Filter Mode Register = Off */
+	LPC_CANAF->AFMR = 0x00000001;
+
+	/* Add mask for standard identifiers   */
+	id &= 0x07FF;
+	id |= (ctrl0 << 13) | (1 << 11); /* Add controller number */
+//	total = ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
+	/* Move all remaining sections one place up
+	if new entry will increase FullCAN list */
+	if (((CANAF_FullCAN_cnt & 0x0001) == 0)&&(total!=0))
+	{
+		//then remove remaining section
+		cnt1   = (CANAF_FullCAN_cnt >> 1);
+		bound1 = total;
+		buf0   = LPC_CANAF_RAM->mask[cnt1];
+
+		while (bound1--)
+		{
+			cnt1++;
+			buf1 = LPC_CANAF_RAM->mask[cnt1];
+			LPC_CANAF_RAM->mask[cnt1] = buf0;
+			buf0 = buf1;
+		}
+	}
+	if (CANAF_FullCAN_cnt == 0)
+	{
+		/* For entering first ID */
+		LPC_CANAF_RAM->mask[0] = 0x0000FFFF | (id << 16);
+	}
+	else if (CANAF_FullCAN_cnt == 1)
+	{
+		/* For entering second ID */
+		if ((LPC_CANAF_RAM->mask[0] >> 16) > id)
+		{
+			LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] >> 16) | (id << 16);
+		}
+		else
+		{
+			LPC_CANAF_RAM->mask[0] = (LPC_CANAF_RAM->mask[0] & 0xFFFF0000) | id;
+		}
+	}
+	else
+	{
+		/* Find where to insert new ID */
+		cnt1 = 0;
+		cnt2 = CANAF_FullCAN_cnt;
+		bound1 = (CANAF_FullCAN_cnt - 1) >> 1;
+		while (cnt1 <= bound1)
+		{
+			/* Loop through standard existing IDs */
+			if ((LPC_CANAF_RAM->mask[cnt1] >> 16) > id)
+			{
+				cnt2 = cnt1 * 2;
+				break;
+			}
+
+			if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000FFFF) > id)
+			{
+				cnt2 = cnt1 * 2 + 1;
+				break;
+			}
+
+			cnt1++;
+		}
+		/* cnt1 = U32 where to insert new ID */
+		/* cnt2 = U16 where to insert new ID */
+
+		if (cnt1 > bound1)
+		{
+			/* Adding ID as last entry */
+			/* Even number of IDs exists */
+			if ((CANAF_FullCAN_cnt & 0x0001) == 0)
+			{
+				LPC_CANAF_RAM->mask[cnt1]  = 0x0000FFFF | (id << 16);
+			}
+			/* Odd  number of IDs exists */
+			else
+			{
+				LPC_CANAF_RAM->mask[cnt1]  = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000) | id;
+			}
+		}
+		else
+		{
+			buf0 = LPC_CANAF_RAM->mask[cnt1]; /* Remember current entry */
+			if ((cnt2 & 0x0001) == 0)
+			{
+				/* Insert new mask to even address*/
+				buf1 = (id << 16) | (buf0 >> 16);
+			}
+			else
+			{
+				/* Insert new mask to odd  address */
+				buf1 = (buf0 & 0xFFFF0000) | id;
+			}
+			LPC_CANAF_RAM->mask[cnt1] = buf1;/* Insert mask */
+			bound1 = CANAF_FullCAN_cnt >> 1;
+			/* Move all remaining standard mask entries one place up */
+			while (cnt1 < bound1)
+			{
+				cnt1++;
+				buf1  = LPC_CANAF_RAM->mask[cnt1];
+				LPC_CANAF_RAM->mask[cnt1] = (buf1 >> 16) | (buf0 << 16);
+				buf0  = buf1;
+			}
+
+			if ((CANAF_FullCAN_cnt & 0x0001) == 0)
+			{
+				/* Even number of IDs exists */
+				LPC_CANAF_RAM->mask[cnt1] = (LPC_CANAF_RAM->mask[cnt1] & 0xFFFF0000)
+											| (0x0000FFFF);
+			}
+		}
+	}
+	//restruct FulCAN Object Section
+	bound1 = CANAF_FullCAN_cnt - cnt2;
+	cnt1 = total - (CANAF_FullCAN_cnt)*3 + cnt2*3 + 1;
+	buf0 = LPC_CANAF_RAM->mask[cnt1];
+	buf1 = LPC_CANAF_RAM->mask[cnt1+1];
+	buf2 = LPC_CANAF_RAM->mask[cnt1+2];
+	LPC_CANAF_RAM->mask[cnt1]=LPC_CANAF_RAM->mask[cnt1+1]= LPC_CANAF_RAM->mask[cnt1+2]=0x00;
+	cnt1+=3;
+	while(bound1--)
+	{
+		tmp0 = LPC_CANAF_RAM->mask[cnt1];
+		tmp1 = LPC_CANAF_RAM->mask[cnt1+1];
+		tmp2 = LPC_CANAF_RAM->mask[cnt1+2];
+		LPC_CANAF_RAM->mask[cnt1]= buf0;
+		LPC_CANAF_RAM->mask[cnt1+1]= buf1;
+		LPC_CANAF_RAM->mask[cnt1+2]= buf2;
+		buf0 = tmp0;
+		buf1 = tmp1;
+		buf2 = tmp2;
+		cnt1+=3;
+	}
+	CANAF_FullCAN_cnt++;
+	//update address values
+	LPC_CANAF->SFF_sa 	  +=0x04;
+	LPC_CANAF->SFF_GRP_sa +=0x04 ;
+	LPC_CANAF->EFF_sa     +=0x04 ;
+	LPC_CANAF->EFF_GRP_sa +=0x04;
+	LPC_CANAF->ENDofTable +=0x04;
+
+	LPC_CANAF->AFMR = 0x04;
+ 	return CAN_OK;
+}
+
+/********************************************************************//**
+ * @brief		Load Group entry into AFLUT
+ * @param[in]	CANx: CAN peripheral selected, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	lowerID, upperID: lower and upper identifier of entry
+ * @param[in]	format: type of ID format, should be:
+ * 				- STD_ID_FORMAT: Standard ID format (11-bit value)
+ * 				- EXT_ID_FORMAT: Extended ID format (29-bit value)
+ * @return 		CAN_ERROR, could be:
+ * 				- CAN_OK: loading is successful
+ * 				- CAN_CONFLICT_ID_ERROR: Conflict ID occurs
+ * 				- CAN_OBJECTS_FULL_ERROR: no more space available
+ *********************************************************************/
+CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID, \
+		uint32_t upperID, CAN_ID_FORMAT_Type format)
+{
+	uint16_t tmp = 0;
+	uint32_t buf0, buf1, entry1, entry2, LID,UID;
+	int16_t cnt1, bound1, total;
+
+	CHECK_PARAM(PARAM_CANx(CANx));
+	CHECK_PARAM(PARAM_ID_FORMAT(format));
+
+	if(lowerID > upperID) return CAN_CONFLICT_ID_ERROR;
+	if(CANx == LPC_CAN1)
+	{
+		tmp = 0;
+	}
+	else
+	{
+		tmp = 1;
+	}
+
+	total =((CANAF_FullCAN_cnt+1)>>1)+ CANAF_FullCAN_cnt*3 +((CANAF_std_cnt + 1) >> 1)+  \
+			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
+
+	/* Setup Acceptance Filter Configuration
+	Acceptance Filter Mode Register = Off */
+	LPC_CANAF->AFMR = 0x00000001;
+
+/*********Add Group of Standard Identifier Frame Format************/
+	if(format == STD_ID_FORMAT)
+	{
+		if ((total >= 512)){//don't have enough space
+			return CAN_OBJECTS_FULL_ERROR;
+		}
+		lowerID &=0x7FF; //mask ID
+		upperID &=0x7FF;
+		entry1  = (tmp << 29)|(lowerID << 16)|(tmp << 13)|(upperID << 0);
+		cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1);
+
+		//if this is the first Group standard ID entry
+		if(CANAF_gstd_cnt == 0)
+		{
+			LPC_CANAF_RAM->mask[cnt1] = entry1;
+		}
+		else
+		{
+			//find the position to add new Group entry
+			bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt;
+			while(cnt1 < bound1)
+			{
+				buf0 = LPC_CANAF_RAM->mask[cnt1];
+				LID  = (buf0 >> 16)&0x7FF;
+				UID  = buf0 & 0x7FF;
+				if (upperID <= LID)
+				{
+					//add new entry before this entry
+					LPC_CANAF_RAM->mask[cnt1] = entry1;
+					break;
+				}
+				else if (lowerID >= UID)
+				{
+					//load next entry to compare
+					cnt1 ++;
+				}
+				else
+					return CAN_CONFLICT_ID_ERROR;
+			}
+			if(cnt1 >= bound1)
+			{
+				//add new entry at the last position in this list
+				buf0 = LPC_CANAF_RAM->mask[cnt1];
+				LPC_CANAF_RAM->mask[cnt1] = entry1;
+			}
+
+			//remove all remaining entry of this section one place up
+			bound1 = total - cnt1;
+			while(bound1--)
+			{
+				cnt1++;
+				buf1 = LPC_CANAF_RAM->mask[cnt1];
+				LPC_CANAF_RAM->mask[cnt1] = buf0;
+				buf0 = buf1;
+			}
+		}
+		CANAF_gstd_cnt++;
+		//update address values
+		LPC_CANAF->EFF_sa     +=0x04 ;
+		LPC_CANAF->EFF_GRP_sa +=0x04;
+		LPC_CANAF->ENDofTable +=0x04;
+	}
+
+
+/*********Add Group of Extended Identifier Frame Format************/
+	else
+	{
+		if ((total >= 511)){//don't have enough space
+			return CAN_OBJECTS_FULL_ERROR;
+		}
+		lowerID  &= 0x1FFFFFFF; //mask ID
+		upperID &= 0x1FFFFFFF;
+		entry1   = (tmp << 29)|(lowerID << 0);
+		entry2   = (tmp << 29)|(upperID << 0);
+
+		cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt;
+		//if this is the first Group standard ID entry
+		if(CANAF_gext_cnt == 0)
+		{
+			LPC_CANAF_RAM->mask[cnt1] = entry1;
+			LPC_CANAF_RAM->mask[cnt1+1] = entry2;
+		}
+		else
+		{
+			//find the position to add new Group entry
+			bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \
+						+ CANAF_ext_cnt + (CANAF_gext_cnt<<1);
+			while(cnt1 < bound1)
+			{
+				buf0 = LPC_CANAF_RAM->mask[cnt1];
+				buf1 = LPC_CANAF_RAM->mask[cnt1+1];
+				LID  = buf0 & 0x1FFFFFFF; //mask ID
+				UID  = buf1 & 0x1FFFFFFF;
+				if (upperID <= LID)
+				{
+					//add new entry before this entry
+					LPC_CANAF_RAM->mask[cnt1] = entry1;
+					LPC_CANAF_RAM->mask[++cnt1] = entry2;
+					break;
+				}
+				else if (lowerID >= UID)
+				{
+					//load next entry to compare
+					cnt1 +=2;
+				}
+				else
+					return CAN_CONFLICT_ID_ERROR;
+			}
+			if(cnt1 >= bound1)
+			{
+				//add new entry at the last position in this list
+				buf0 = LPC_CANAF_RAM->mask[cnt1];
+				buf1 = LPC_CANAF_RAM->mask[cnt1+1];
+				LPC_CANAF_RAM->mask[cnt1]   = entry1;
+				LPC_CANAF_RAM->mask[++cnt1] = entry2;
+			}
+			//remove all remaining entry of this section two place up
+			bound1 = total - cnt1 + 1;
+			cnt1++;
+			while(bound1>0)
+			{
+				entry1 = LPC_CANAF_RAM->mask[cnt1];
+				entry2 = LPC_CANAF_RAM->mask[cnt1+1];
+				LPC_CANAF_RAM->mask[cnt1]   = buf0;
+				LPC_CANAF_RAM->mask[cnt1+1] = buf1;
+				buf0 = entry1;
+				buf1 = entry2;
+				cnt1   +=2;
+				bound1 -=2;
+			}
+		}
+		CANAF_gext_cnt++;
+		//update address values
+		LPC_CANAF->ENDofTable +=0x08;
+	}
+	LPC_CANAF->AFMR = 0x04;
+ 	return CAN_OK;
+}
+
+/********************************************************************//**
+ * @brief		Remove AFLUT entry (FullCAN entry and Explicit Standard entry)
+ * @param[in]	EntryType: the type of entry that want to remove, should be:
+ * 				- FULLCAN_ENTRY
+ * 				- EXPLICIT_STANDARD_ENTRY
+ * 				- GROUP_STANDARD_ENTRY
+ * 				- EXPLICIT_EXTEND_ENTRY
+ * 				- GROUP_EXTEND_ENTRY
+ * @param[in]	position: the position of this entry in its section
+ * Note: the first position is 0
+ * @return 		CAN_ERROR, could be:
+ * 				- CAN_OK: removing is successful
+ * 				- CAN_ENTRY_NOT_EXIT_ERROR: entry want to remove is not exit
+ *********************************************************************/
+CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position)
+{
+	uint16_t cnt, bound, total;
+	uint32_t buf0, buf1;
+	CHECK_PARAM(PARAM_AFLUT_ENTRY_TYPE(EntryType));
+	CHECK_PARAM(PARAM_POSITION(position));
+
+	/* Setup Acceptance Filter Configuration
+	Acceptance Filter Mode Register = Off */
+	LPC_CANAF->AFMR = 0x00000001;
+	total = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt + 1) >> 1) + \
+			CANAF_gstd_cnt + CANAF_ext_cnt + (CANAF_gext_cnt<<1);
+
+
+/************** Remove FullCAN Entry *************/
+	if(EntryType == FULLCAN_ENTRY)
+	{
+		if((CANAF_FullCAN_cnt==0)||(position >= CANAF_FullCAN_cnt))
+		{
+			return CAN_ENTRY_NOT_EXIT_ERROR;
+		}
+		else
+		{
+			cnt = position >> 1;
+			buf0 = LPC_CANAF_RAM->mask[cnt];
+			bound = (CANAF_FullCAN_cnt - position -1)>>1;
+			if((position & 0x0001) == 0) //event position
+			{
+				while(bound--)
+				{
+					//remove all remaining FullCAN entry one place down
+					buf1  = LPC_CANAF_RAM->mask[cnt+1];
+					LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
+					buf0  = buf1;
+					cnt++;
+				}
+			}
+			else //odd position
+			{
+				while(bound--)
+				{
+					//remove all remaining FullCAN entry one place down
+					buf1  = LPC_CANAF_RAM->mask[cnt+1];
+					LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
+					LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
+					buf0  = buf1<<16;
+					cnt++;
+				}
+			}
+			if((CANAF_FullCAN_cnt & 0x0001) == 0)
+			{
+				if((position & 0x0001)==0)
+					LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
+				else
+					LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
+			}
+			else
+			{
+				//remove all remaining section one place down
+				cnt = (CANAF_FullCAN_cnt + 1)>>1;
+				bound = total + CANAF_FullCAN_cnt * 3;
+				while(bound>cnt)
+				{
+					LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
+					cnt++;
+				}
+				LPC_CANAF_RAM->mask[cnt-1]=0x00;
+				//update address values
+				LPC_CANAF->SFF_sa 	  -=0x04;
+				LPC_CANAF->SFF_GRP_sa -=0x04 ;
+				LPC_CANAF->EFF_sa     -=0x04 ;
+				LPC_CANAF->EFF_GRP_sa -=0x04;
+				LPC_CANAF->ENDofTable -=0x04;
+			}
+			CANAF_FullCAN_cnt--;
+
+			//delete its FullCAN Object in the FullCAN Object section
+			//remove all remaining FullCAN Object three place down
+			cnt = total + position * 3;
+			bound = (CANAF_FullCAN_cnt - position + 1) * 3;
+
+			while(bound)
+			{
+				LPC_CANAF_RAM->mask[cnt]=LPC_CANAF_RAM->mask[cnt+3];;
+				LPC_CANAF_RAM->mask[cnt+1]=LPC_CANAF_RAM->mask[cnt+4];
+				LPC_CANAF_RAM->mask[cnt+2]=LPC_CANAF_RAM->mask[cnt+5];
+				bound -=3;
+				cnt   +=3;
+			}
+		}
+	}
+
+/************** Remove Explicit Standard ID Entry *************/
+	else if(EntryType == EXPLICIT_STANDARD_ENTRY)
+	{
+		if((CANAF_std_cnt==0)||(position >= CANAF_std_cnt))
+		{
+			return CAN_ENTRY_NOT_EXIT_ERROR;
+		}
+		else
+		{
+			cnt = ((CANAF_FullCAN_cnt+1)>>1)+ (position >> 1);
+			buf0 = LPC_CANAF_RAM->mask[cnt];
+			bound = (CANAF_std_cnt - position - 1)>>1;
+			if((position & 0x0001) == 0) //event position
+			{
+				while(bound--)
+				{
+					//remove all remaining FullCAN entry one place down
+					buf1  = LPC_CANAF_RAM->mask[cnt+1];
+					LPC_CANAF_RAM->mask[cnt] = (buf1 >> 16) | (buf0 << 16);
+					buf0  = buf1;
+					cnt++;
+				}
+			}
+			else //odd position
+			{
+				while(bound--)
+				{
+					//remove all remaining FullCAN entry one place down
+					buf1  = LPC_CANAF_RAM->mask[cnt+1];
+					LPC_CANAF_RAM->mask[cnt] = (buf0 & 0xFFFF0000)|(buf1 >> 16);
+					LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+1] << 16;
+					buf0  = buf1<<16;
+					cnt++;
+				}
+			}
+			if((CANAF_std_cnt & 0x0001) == 0)
+			{
+				if((position & 0x0001)==0)
+					LPC_CANAF_RAM->mask[cnt] = (buf0 << 16) | (0x0000FFFF);
+				else
+					LPC_CANAF_RAM->mask[cnt] = buf0 | 0x0000FFFF;
+			}
+			else
+			{
+				//remove all remaining section one place down
+				cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1);
+				bound = total + CANAF_FullCAN_cnt * 3;
+				while(bound>cnt)
+				{
+					LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
+					cnt++;
+				}
+				LPC_CANAF_RAM->mask[cnt-1]=0x00;
+				//update address value
+				LPC_CANAF->SFF_GRP_sa -=0x04 ;
+				LPC_CANAF->EFF_sa     -=0x04 ;
+				LPC_CANAF->EFF_GRP_sa -=0x04;
+				LPC_CANAF->ENDofTable -=0x04;
+			}
+			CANAF_std_cnt--;
+		}
+	}
+
+/************** Remove Group of Standard ID Entry *************/
+	else if(EntryType == GROUP_STANDARD_ENTRY)
+	{
+		if((CANAF_gstd_cnt==0)||(position >= CANAF_gstd_cnt))
+		{
+			return CAN_ENTRY_NOT_EXIT_ERROR;
+		}
+		else
+		{
+			cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ position + 1;
+			bound = total + CANAF_FullCAN_cnt * 3;
+			while (cnt<bound)
+			{
+				LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
+				cnt++;
+			}
+			LPC_CANAF_RAM->mask[cnt-1]=0x00;
+		}
+		CANAF_gstd_cnt--;
+		//update address value
+		LPC_CANAF->EFF_sa     -=0x04;
+		LPC_CANAF->EFF_GRP_sa -=0x04;
+		LPC_CANAF->ENDofTable -=0x04;
+	}
+
+/************** Remove Explicit Extended ID Entry *************/
+	else if(EntryType == EXPLICIT_EXTEND_ENTRY)
+	{
+		if((CANAF_ext_cnt==0)||(position >= CANAF_ext_cnt))
+		{
+			return CAN_ENTRY_NOT_EXIT_ERROR;
+		}
+		else
+		{
+			cnt = ((CANAF_FullCAN_cnt + 1)>>1) + ((CANAF_std_cnt + 1) >> 1)+ CANAF_gstd_cnt + position + 1;
+			bound = total + CANAF_FullCAN_cnt * 3;
+			while (cnt<bound)
+			{
+				LPC_CANAF_RAM->mask[cnt-1] = LPC_CANAF_RAM->mask[cnt];
+				cnt++;
+			}
+			LPC_CANAF_RAM->mask[cnt-1]=0x00;
+		}
+		CANAF_ext_cnt--;
+		LPC_CANAF->EFF_GRP_sa -=0x04;
+		LPC_CANAF->ENDofTable -=0x04;
+	}
+
+/************** Remove Group of Extended ID Entry *************/
+	else
+	{
+		if((CANAF_gext_cnt==0)||(position >= CANAF_gext_cnt))
+		{
+			return CAN_ENTRY_NOT_EXIT_ERROR;
+		}
+		else
+		{
+			cnt = total - (CANAF_gext_cnt<<1) + (position<<1);
+			bound = total + CANAF_FullCAN_cnt * 3;
+			while (cnt<bound)
+			{
+				//remove all remaining entry two place up
+				LPC_CANAF_RAM->mask[cnt] = LPC_CANAF_RAM->mask[cnt+2];
+				LPC_CANAF_RAM->mask[cnt+1] = LPC_CANAF_RAM->mask[cnt+3];
+				cnt+=2;
+			}
+		}
+		CANAF_gext_cnt--;
+		LPC_CANAF->ENDofTable -=0x08;
+	}
+	LPC_CANAF->AFMR = 0x04;
+	return CAN_OK;
+}
+
+/********************************************************************//**
+ * @brief		Send message data
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	CAN_Msg point to the CAN_MSG_Type Structure, it contains message
+ * 				information such as: ID, DLC, RTR, ID Format
+ * @return 		Status:
+ * 				- SUCCESS: send message successfully
+ * 				- ERROR: send message unsuccessfully
+ *********************************************************************/
+Status CAN_SendMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
+{
+	uint32_t data;
+	CHECK_PARAM(PARAM_CANx(CANx));
+	CHECK_PARAM(PARAM_ID_FORMAT(CAN_Msg->format));
+	if(CAN_Msg->format==STD_ID_FORMAT)
+	{
+		CHECK_PARAM(PARAM_ID_11(CAN_Msg->id));
+	}
+	else
+	{
+		CHECK_PARAM(PARAM_ID_29(CAN_Msg->id));
+	}
+	CHECK_PARAM(PARAM_DLC(CAN_Msg->len));
+	CHECK_PARAM(PARAM_FRAME_TYPE(CAN_Msg->type));
+
+	//Check status of Transmit Buffer 1
+	if ((CANx->SR & 0x00000004)>>2)
+	{
+		/* Transmit Channel 1 is available */
+		/* Write frame informations and frame data into its CANxTFI1,
+		 * CANxTID1, CANxTDA1, CANxTDB1 register */
+		CANx->TFI1 &= ~0x000F000;
+		CANx->TFI1 |= (CAN_Msg->len)<<16;
+		if(CAN_Msg->type == REMOTE_FRAME)
+		{
+			CANx->TFI1 |= (1<<30); //set bit RTR
+		}
+		else
+		{
+			CANx->TFI1 &= ~(1<<30);
+		}
+		if(CAN_Msg->format == EXT_ID_FORMAT)
+		{
+			CANx->TFI1 |= (1<<31); //set bit FF
+		}
+		else
+		{
+			CANx->TFI1 &= ~(1<<31);
+		}
+
+		/* Write CAN ID*/
+		CANx->TID1 = CAN_Msg->id;
+
+		/*Write first 4 data bytes*/
+		data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
+//		CANx->TDA1 = *((uint32_t *) &(CAN_Msg->dataA));
+		CANx->TDA1 = data;
+
+		/*Write second 4 data bytes*/
+		data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
+//		CANx->TDB1 = *((uint32_t *) &(CAN_Msg->dataB));
+		CANx->TDB1 = data;
+
+		 /*Write transmission request*/
+		 CANx->CMR = 0x21;
+		 return SUCCESS;
+	}
+	//check status of Transmit Buffer 2
+	else if((CANx->SR & 0x00000004)>>10)
+	{
+		/* Transmit Channel 2 is available */
+		/* Write frame informations and frame data into its CANxTFI2,
+		 * CANxTID2, CANxTDA2, CANxTDB2 register */
+		CANx->TFI2 &= ~0x000F000;
+		CANx->TFI2 |= (CAN_Msg->len)<<16;
+		if(CAN_Msg->type == REMOTE_FRAME)
+		{
+			CANx->TFI2 |= (1<<30); //set bit RTR
+		}
+		else
+		{
+			CANx->TFI2 &= ~(1<<30);
+		}
+		if(CAN_Msg->format == EXT_ID_FORMAT)
+		{
+			CANx->TFI2 |= (1<<31); //set bit FF
+		}
+		else
+		{
+			CANx->TFI2 &= ~(1<<31);
+		}
+
+		/* Write CAN ID*/
+		CANx->TID2 = CAN_Msg->id;
+
+		/*Write first 4 data bytes*/
+		data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
+//		CANx->TDA2 = *((uint32_t *) &(CAN_Msg->dataA));
+		CANx->TDA2 = data;
+
+		/*Write second 4 data bytes*/
+		data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
+//		CANx->TDB2 = *((uint32_t *) &(CAN_Msg->dataB));
+		CANx->TDB2 = data;
+
+		/*Write transmission request*/
+		CANx->CMR = 0x41;
+		return SUCCESS;
+	}
+	//check status of Transmit Buffer 3
+	else if ((CANx->SR & 0x00000004)>>18)
+	{
+		/* Transmit Channel 3 is available */
+		/* Write frame informations and frame data into its CANxTFI3,
+		 * CANxTID3, CANxTDA3, CANxTDB3 register */
+		CANx->TFI3 &= ~0x000F000;
+		CANx->TFI3 |= (CAN_Msg->len)<<16;
+		if(CAN_Msg->type == REMOTE_FRAME)
+		{
+			CANx->TFI3 |= (1<<30); //set bit RTR
+		}
+		else
+		{
+			CANx->TFI3 &= ~(1<<30);
+		}
+		if(CAN_Msg->format == EXT_ID_FORMAT)
+		{
+			CANx->TFI3 |= (1<<31); //set bit FF
+		}
+		else
+		{
+			CANx->TFI3 &= ~(1<<31);
+		}
+
+		/* Write CAN ID*/
+		CANx->TID3 = CAN_Msg->id;
+
+		/*Write first 4 data bytes*/
+		data = (CAN_Msg->dataA[0])|(((CAN_Msg->dataA[1]))<<8)|((CAN_Msg->dataA[2])<<16)|((CAN_Msg->dataA[3])<<24);
+//		CANx->TDA3 = *((uint32_t *) &(CAN_Msg->dataA));
+		CANx->TDA3 = data;
+
+		/*Write second 4 data bytes*/
+		data = (CAN_Msg->dataB[0])|(((CAN_Msg->dataB[1]))<<8)|((CAN_Msg->dataB[2])<<16)|((CAN_Msg->dataB[3])<<24);
+//		CANx->TDB3 = *((uint32_t *) &(CAN_Msg->dataB));
+		CANx->TDB3 = data;
+
+		/*Write transmission request*/
+		CANx->CMR = 0x81;
+		return SUCCESS;
+	}
+	else
+	{
+		return ERROR;
+	}
+}
+
+/********************************************************************//**
+ * @brief		Receive message data
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
+ *  			message information such as: ID, DLC, RTR, ID Format
+ * @return 		Status:
+ * 				- SUCCESS: receive message successfully
+ * 				- ERROR: receive message unsuccessfully
+ *********************************************************************/
+Status CAN_ReceiveMsg (LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg)
+{
+	uint32_t data;
+
+	CHECK_PARAM(PARAM_CANx(CANx));
+
+	//check status of Receive Buffer
+	if((CANx->SR &0x00000001))
+	{
+		/* Receive message is available */
+		/* Read frame informations */
+		CAN_Msg->format   = (uint8_t)(((CANx->RFS) & 0x80000000)>>31);
+		CAN_Msg->type     = (uint8_t)(((CANx->RFS) & 0x40000000)>>30);
+		CAN_Msg->len      = (uint8_t)(((CANx->RFS) & 0x000F0000)>>16);
+
+
+		/* Read CAN message identifier */
+		CAN_Msg->id = CANx->RID;
+
+		/* Read the data if received message was DATA FRAME */
+		if (CAN_Msg->type == DATA_FRAME)
+		{
+			/* Read first 4 data bytes */
+//			*((uint32_t *) &CAN_Msg->dataA) = CANx->RDA;
+			data = CANx->RDA;
+			*((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
+			*((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;;
+			*((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
+			*((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
+
+			/* Read second 4 data bytes */
+//			*((uint32_t *) &CAN_Msg->dataB) = CANx->RDB;
+			data = CANx->RDB;
+			*((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
+			*((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
+			*((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
+			*((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
+
+		/*release receive buffer*/
+		CANx->CMR = 0x04;
+		}
+		else
+		{
+			/* Received Frame is a Remote Frame, not have data, we just receive
+			 * message information only */
+			return SUCCESS;
+		}
+	}
+	else
+	{
+		// no receive message available
+		return ERROR;
+	}
+	return SUCCESS;
+}
+
+/********************************************************************//**
+ * @brief		Receive FullCAN Object
+ * @param[in]	CANAFx: CAN Acceptance Filter register, should be LPC_CANAF
+ * @param[in]	CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
+ *  			message information such as: ID, DLC, RTR, ID Format
+ * @return 		CAN_ERROR, could be:
+ * 				- CAN_FULL_OBJ_NOT_RCV: FullCAN Object is not be received
+ * 				- CAN_OK: Received FullCAN Object successful
+ *
+ *********************************************************************/
+CAN_ERROR FCAN_ReadObj (LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg)
+{
+	uint32_t *pSrc, data;
+	uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx;
+
+	CHECK_PARAM(PARAM_CANAFx(CANAFx));
+
+	interrut_word = 0;
+
+	if (LPC_CANAF->FCANIC0 != 0)
+	{
+		interrut_word = LPC_CANAF->FCANIC0;
+		head_idx = 0;
+		tail_idx = 31;
+	}
+	else if (LPC_CANAF->FCANIC1 != 0)
+	{
+		interrut_word = LPC_CANAF->FCANIC1;
+		head_idx = 32;
+		tail_idx = 63;
+	}
+
+	if (interrut_word != 0)
+	{
+		/* Detect for interrupt pending */
+		msg_idx = 0;
+		for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++)
+		{
+			test_bit = interrut_word & 0x1;
+			interrut_word = interrut_word >> 1;
+
+			if (test_bit)
+			{
+				pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12);
+
+	    	 	/* Has been finished updating the content */
+	    	 	if ((*pSrc & 0x03000000L) == 0x03000000L)
+	    	 	{
+	    	 		/*clear semaphore*/
+	    	 		*pSrc &= 0xFCFFFFFF;
+
+	    	 		/*Set to DatA*/
+	    	 		pSrc++;
+	    	 		/* Copy to dest buf */
+//	    	 		*((uint32_t *) &CAN_Msg->dataA) = *pSrc;
+	    	 		data = *pSrc;
+	    			*((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
+	    			*((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00)>>8;
+	    			*((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000)>>16;
+	    			*((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000)>>24;
+
+	    	 		/*Set to DatB*/
+	    	 		pSrc++;
+	    	 		/* Copy to dest buf */
+//	    	 		*((uint32_t *) &CAN_Msg->dataB) = *pSrc;
+	    	 		data = *pSrc;
+	    			*((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
+	    			*((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00)>>8;
+	    			*((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000)>>16;
+	    			*((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000)>>24;
+	    	 		/*Back to Dat1*/
+	    	 		pSrc -= 2;
+
+	    	 		CAN_Msg->id = *pSrc & 0x7FF;
+	    	 		CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F;
+					CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value
+					CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01;
+	    	 		/*Re-read semaphore*/
+	    	 		if ((*pSrc & 0x03000000L) == 0)
+	    	 		{
+	    	 			return CAN_OK;
+	    	 		}
+	    	 	}
+			}
+		}
+	}
+	return CAN_FULL_OBJ_NOT_RCV;
+}
+/********************************************************************//**
+ * @brief		Get CAN Control Status
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	arg: type of CAN status to get from CAN status register
+ * 				Should be:
+ * 				- CANCTRL_GLOBAL_STS: CAN Global Status
+ * 				- CANCTRL_INT_CAP: CAN Interrupt and Capture
+ * 				- CANCTRL_ERR_WRN: CAN Error Warning Limit
+ * 				- CANCTRL_STS: CAN Control Status
+ * @return 		Current Control Status that you want to get value
+ *********************************************************************/
+uint32_t CAN_GetCTRLStatus (LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg)
+{
+	CHECK_PARAM(PARAM_CANx(CANx));
+	CHECK_PARAM(PARAM_CTRL_STS_TYPE(arg));
+
+	switch (arg)
+	{
+	case CANCTRL_GLOBAL_STS:
+		return CANx->GSR;
+
+	case CANCTRL_INT_CAP:
+		return CANx->ICR;
+
+	case CANCTRL_ERR_WRN:
+		return CANx->EWL;
+
+	default: // CANCTRL_STS
+		return CANx->SR;
+	}
+}
+/********************************************************************//**
+ * @brief		Get CAN Central Status
+ * @param[in]	CANCRx point to LPC_CANCR_TypeDef
+ * @param[in]	arg: type of CAN status to get from CAN Central status register
+ * 				Should be:
+ * 				- CANCR_TX_STS: Central CAN Tx Status
+ * 				- CANCR_RX_STS: Central CAN Rx Status
+ * 				- CANCR_MS: Central CAN Miscellaneous Status
+ * @return 		Current Central Status that you want to get value
+ *********************************************************************/
+uint32_t CAN_GetCRStatus (LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg)
+{
+	CHECK_PARAM(PARAM_CANCRx(CANCRx));
+	CHECK_PARAM(PARAM_CR_STS_TYPE(arg));
+
+	switch (arg)
+	{
+	case CANCR_TX_STS:
+		return CANCRx->CANTxSR;
+
+	case CANCR_RX_STS:
+		return CANCRx->CANRxSR;
+
+	default:	// CANCR_MS
+		return CANCRx->CANMSR;
+	}
+}
+/********************************************************************//**
+ * @brief		Enable/Disable CAN Interrupt
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	arg: type of CAN interrupt that you want to enable/disable
+ * 				Should be:
+ * 				- CANINT_RIE: CAN Receiver Interrupt Enable
+ * 				- CANINT_TIE1: CAN Transmit Interrupt Enable
+ * 				- CANINT_EIE: CAN Error Warning Interrupt Enable
+ * 				- CANINT_DOIE: CAN Data Overrun Interrupt Enable
+ * 				- CANINT_WUIE: CAN Wake-Up Interrupt Enable
+ * 				- CANINT_EPIE: CAN Error Passive Interrupt Enable
+ * 				- CANINT_ALIE: CAN Arbitration Lost Interrupt Enable
+ * 				- CANINT_BEIE: CAN Bus Error Interrupt Enable
+ * 				- CANINT_IDIE: CAN ID Ready Interrupt Enable
+ * 				- CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2
+ * 				- CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3
+ * 				- CANINT_FCE: FullCAN Interrupt Enable
+ * @param[in]	NewState: New state of this function, should be:
+ * 				- ENABLE
+ * 				- DISABLE
+ * @return 		none
+ *********************************************************************/
+void CAN_IRQCmd (LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_CANx(CANx));
+	CHECK_PARAM(PARAM_INT_EN_TYPE(arg));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if(NewState == ENABLE)
+	{
+		if(arg==CANINT_FCE)
+		{
+			LPC_CANAF->AFMR = 0x01;
+			LPC_CANAF->FCANIE = 0x01;
+			LPC_CANAF->AFMR = 0x04;
+		}
+		else
+			CANx->IER |= (1 << arg);
+	}
+	else
+	{
+		if(arg==CANINT_FCE){
+			LPC_CANAF->AFMR = 0x01;
+			LPC_CANAF->FCANIE = 0x01;
+			LPC_CANAF->AFMR = 0x00;
+		}
+		else
+			CANx->IER &= ~(1 << arg);
+	}
+}
+/*********************************************************************//**
+ * @brief		Install interrupt call-back function
+ * @param[in]	arg: CAN interrupt type, should be:
+ * 	  			- CANINT_RIE: CAN Receiver Interrupt Enable
+ * 				- CANINT_TIE1: CAN Transmit Interrupt Enable
+ * 				- CANINT_EIE: CAN Error Warning Interrupt Enable
+ * 				- CANINT_DOIE: CAN Data Overrun Interrupt Enable
+ * 				- CANINT_WUIE: CAN Wake-Up Interrupt Enable
+ * 				- CANINT_EPIE: CAN Error Passive Interrupt Enable
+ * 				- CANINT_ALIE: CAN Arbitration Lost Interrupt Enable
+ * 				- CANINT_BEIE: CAN Bus Error Interrupt Enable
+ * 				- CANINT_IDIE: CAN ID Ready Interrupt Enable
+ * 				- CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2
+ * 				- CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3
+ * 				- CANINT_FCE: FullCAN Interrupt Enable
+ * @param[in]	pnCANCbs: pointer point to call-back function
+ * @return		None
+ **********************************************************************/
+void CAN_SetupCBS(CAN_INT_EN_Type arg,fnCANCbs_Type* pnCANCbs)
+{
+	CHECK_PARAM(PARAM_INT_EN_TYPE(arg));
+	_apfnCANCbs[arg] = pnCANCbs;
+}
+/********************************************************************//**
+ * @brief		Setting Acceptance Filter mode
+ * @param[in]	CANAFx point to LPC_CANAF_TypeDef object, should be: CANAF
+ * @param[in]	AFMode: type of AF mode that you want to set, should be:
+ * 				- CAN_Normal: Normal mode
+ * 				- CAN_AccOff: Acceptance Filter Off Mode
+ * 				- CAN_AccBP: Acceptance Fileter Bypass Mode
+ * 				- CAN_eFCAN: FullCAN Mode Enhancement
+ * @return 		none
+ *********************************************************************/
+void CAN_SetAFMode (LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFMode)
+{
+	CHECK_PARAM(PARAM_CANAFx(CANAFx));
+	CHECK_PARAM(PARAM_AFMODE_TYPE(AFMode));
+
+	switch(AFMode)
+	{
+	case CAN_Normal:
+		CANAFx->AFMR = 0x00;
+		break;
+	case CAN_AccOff:
+		CANAFx->AFMR = 0x01;
+		break;
+	case CAN_AccBP:
+		CANAFx->AFMR = 0x02;
+		break;
+	case CAN_eFCAN:
+		CANAFx->AFMR = 0x04;
+		break;
+	}
+}
+
+/********************************************************************//**
+ * @brief		Enable/Disable CAN Mode
+ * @param[in]	CANx pointer to LPC_CAN_TypeDef, should be:
+ * 				- CAN1: CAN 1
+ * 				- CAN2: CAN 2
+ * @param[in]	mode: type of CAN mode that you want to enable/disable, should be:
+ * 				- CAN_OPERATING_MODE: Normal Operating Mode
+ * 				- CAN_RESET_MODE: Reset Mode
+ * 				- CAN_LISTENONLY_MODE: Listen Only Mode
+ * 				- CAN_SELFTEST_MODE: Self Test Mode
+ * 				- CAN_TXPRIORITY_MODE: Transmit Priority Mode
+ * 				- CAN_SLEEP_MODE: Sleep Mode
+ * 				- CAN_RXPOLARITY_MODE: Receive Polarity Mode
+ * 				- CAN_TEST_MODE: Test Mode
+ * @param[in]	NewState: New State of this function, should be:
+ * 				- ENABLE
+ * 				- DISABLE
+ * @return 		none
+ *********************************************************************/
+void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_CANx(CANx));
+	CHECK_PARAM(PARAM_MODE_TYPE(mode));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	switch(mode)
+	{
+	case CAN_OPERATING_MODE:
+		CANx->MOD = 0x00;
+		break;
+	case CAN_RESET_MODE:
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_RM;
+		else
+			CANx->MOD &= ~CAN_MOD_RM;
+		break;
+	case CAN_LISTENONLY_MODE:
+		CANx->MOD |=CAN_MOD_RM;
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_LOM;
+		else
+			CANx->MOD &=~CAN_MOD_LOM;
+		break;
+	case CAN_SELFTEST_MODE:
+		CANx->MOD |=CAN_MOD_RM;
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_STM;
+		else
+			CANx->MOD &=~CAN_MOD_STM;
+		break;
+	case CAN_TXPRIORITY_MODE:
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_TPM;
+		else
+			CANx->MOD &=~CAN_MOD_TPM;
+		break;
+	case CAN_SLEEP_MODE:
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_SM;
+		else
+			CANx->MOD &=~CAN_MOD_SM;
+		break;
+	case CAN_RXPOLARITY_MODE:
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_RPM;
+		else
+			CANx->MOD &=~CAN_MOD_RPM;
+		break;
+	case CAN_TEST_MODE:
+		if(NewState == ENABLE)
+			CANx->MOD |=CAN_MOD_TM;
+		else
+			CANx->MOD &=~CAN_MOD_TM;
+		break;
+	}
+}
+/*********************************************************************//**
+ * @brief		Standard CAN interrupt handler, this function will check
+ * 				all interrupt status of CAN channels, then execute the call
+ * 				back function if they're already installed
+ * @param[in]	CANx point to CAN peripheral selected, should be: CAN1 or CAN2
+ * @return		None
+ **********************************************************************/
+void CAN_IntHandler(LPC_CAN_TypeDef* CANx)
+{
+	uint8_t t;
+	//scan interrupt pending
+	if(LPC_CANAF->FCANIE)
+	{
+		_apfnCANCbs[11]();
+	}
+	//scan interrupt channels
+	for(t=0;t<11;t++)
+	{
+		if(((CANx->ICR)>>t)&0x01)
+		{
+			_apfnCANCbs[t]();
+		}
+	}
+}
+
+/**
+ * @}
+ */
+
+#endif /* _CAN */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.h
new file mode 100644
index 0000000..c9d5b4e
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_can.h
@@ -0,0 +1,855 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_can.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for CAN firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 1.June.2009
+ * @author	: NguyenCao
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup CAN
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_CAN_H_
+#define LPC17XX_CAN_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup CAN_Private_Macros
+ * @{
+ */
+
+#define ID_11	1
+#define MAX_HW_FULLCAN_OBJ 		64
+#define MAX_SW_FULLCAN_OBJ 		32
+
+
+/** @defgroup CAN_REGISTER_BIT_DEFINITION
+ * @{
+ */
+
+/** CAN Reset mode */
+#define CAN_MOD_RM			((uint32_t)(1))
+/** CAN Listen Only Mode */
+#define CAN_MOD_LOM			((uint32_t)(1<<1))
+/** CAN Self Test mode */
+#define CAN_MOD_STM			((uint32_t)(1<<2))
+/** CAN Transmit Priority mode */
+#define CAN_MOD_TPM			((uint32_t)(1<<3))
+/** CAN Sleep mode */
+#define CAN_MOD_SM			((uint32_t)(1<<4))
+/** CAN Receive Polarity mode */
+#define CAN_MOD_RPM			((uint32_t)(1<<5))
+/** CAN Test mode */
+#define CAN_MOD_TM			((uint32_t)(1<<7))
+/*********************************************************************//**
+ * Macro defines for CAN Command Register
+ **********************************************************************/
+/** CAN Transmission Request */
+#define CAN_CMR_TR			((uint32_t)(1))
+/** CAN Abort Transmission */
+#define CAN_CMR_AT			((uint32_t)(1<<1))
+/** CAN Release Receive Buffer */
+#define CAN_CMR_RRB			((uint32_t)(1<<2))
+/** CAN Clear Data Overrun */
+#define CAN_CMR_CDO			((uint32_t)(1<<3))
+/** CAN Self Reception Request */
+#define CAN_CMR_SRR			((uint32_t)(1<<4))
+/** CAN Select Tx Buffer 1 */
+#define CAN_CMR_STB1		((uint32_t)(1<<5))
+/** CAN Select Tx Buffer 2 */
+#define CAN_CMR_STB2		((uint32_t)(1<<6))
+/** CAN Select Tx Buffer 3 */
+#define CAN_CMR_STB3		((uint32_t)(1<<7))
+
+/*********************************************************************//**
+ * Macro defines for CAN Global Status Register
+ **********************************************************************/
+/** CAN Receive Buffer Status */
+#define CAN_GSR_RBS			((uint32_t)(1))
+/** CAN Data Overrun Status */
+#define CAN_GSR_DOS			((uint32_t)(1<<1))
+/** CAN Transmit Buffer Status */
+#define CAN_GSR_TBS			((uint32_t)(1<<2))
+/** CAN Transmit Complete Status */
+#define CAN_GSR_TCS			((uint32_t)(1<<3))
+/** CAN Receive Status */
+#define CAN_GSR_RS			((uint32_t)(1<<4))
+/** CAN Transmit Status */
+#define CAN_GSR_TS			((uint32_t)(1<<5))
+/** CAN Error Status */
+#define CAN_GSR_ES			((uint32_t)(1<<6))
+/** CAN Bus Status */
+#define CAN_GSR_BS			((uint32_t)(1<<7))
+/** CAN Current value of the Rx Error Counter */
+#define CAN_GSR_RXERR(n)	((uint32_t)((n&0xFF)<<16))
+/** CAN Current value of the Tx Error Counter */
+#define CAN_GSR_TXERR(n)	((uint32_t)(n&0xFF)<<24))
+
+/*********************************************************************//**
+ * Macro defines for CAN Interrupt and Capture Register
+ **********************************************************************/
+/** CAN Receive Interrupt */
+#define CAN_ICR_RI			((uint32_t)(1))
+/** CAN Transmit Interrupt 1 */
+#define CAN_ICR_TI1			((uint32_t)(1<<1))
+/** CAN Error Warning Interrupt */
+#define CAN_ICR_EI			((uint32_t)(1<<2))
+/** CAN Data Overrun Interrupt */
+#define CAN_ICR_DOI			((uint32_t)(1<<3))
+/** CAN Wake-Up Interrupt */
+#define CAN_ICR_WUI			((uint32_t)(1<<4))
+/** CAN Error Passive Interrupt */
+#define CAN_ICR_EPI			((uint32_t)(1<<5))
+/** CAN Arbitration Lost Interrupt */
+#define CAN_ICR_ALI			((uint32_t)(1<<6))
+/** CAN Bus Error Interrupt */
+#define CAN_ICR_BEI			((uint32_t)(1<<7))
+/** CAN ID Ready Interrupt */
+#define CAN_ICR_IDI			((uint32_t)(1<<8))
+/** CAN Transmit Interrupt 2 */
+#define CAN_ICR_TI2			((uint32_t)(1<<9))
+/** CAN Transmit Interrupt 3 */
+#define CAN_ICR_TI3			((uint32_t)(1<<10))
+/** CAN Error Code Capture */
+#define CAN_ICR_ERRBIT(n)	((uint32_t)((n&0x1F)<<16))
+/** CAN Error Direction */
+#define CAN_ICR_ERRDIR		((uint32_t)(1<<21))
+/** CAN Error Capture */
+#define CAN_ICR_ERRC(n)		((uint32_t)((n&0x3)<<22))
+/** CAN Arbitration Lost Capture */
+#define CAN_ICR_ALCBIT(n)		((uint32_t)((n&0xFF)<<24))
+
+/*********************************************************************//**
+ * Macro defines for CAN Interrupt Enable Register
+ **********************************************************************/
+/** CAN Receive Interrupt Enable */
+#define CAN_IER_RIE			((uint32_t)(1))
+/** CAN Transmit Interrupt Enable for buffer 1 */
+#define CAN_IER_TIE1		((uint32_t)(1<<1))
+/** CAN Error Warning Interrupt Enable */
+#define CAN_IER_EIE			((uint32_t)(1<<2))
+/** CAN Data Overrun Interrupt Enable */
+#define CAN_IER_DOIE		((uint32_t)(1<<3))
+/** CAN Wake-Up Interrupt Enable */
+#define CAN_IER_WUIE		((uint32_t)(1<<4))
+/** CAN Error Passive Interrupt Enable */
+#define CAN_IER_EPIE		((uint32_t)(1<<5))
+/** CAN Arbitration Lost Interrupt Enable */
+#define CAN_IER_ALIE		((uint32_t)(1<<6))
+/** CAN Bus Error Interrupt Enable */
+#define CAN_IER_BEIE		((uint32_t)(1<<7))
+/** CAN ID Ready Interrupt Enable */
+#define CAN_IER_IDIE		((uint32_t)(1<<8))
+/** CAN Transmit Enable Interrupt for Buffer 2 */
+#define CAN_IER_TIE2		((uint32_t)(1<<9))
+/** CAN Transmit Enable Interrupt for Buffer 3 */
+#define CAN_IER_TIE3		((uint32_t)(1<<10))
+
+/*********************************************************************//**
+ * Macro defines for CAN Bus Timing Register
+ **********************************************************************/
+/** CAN Baudrate Prescaler */
+#define CAN_BTR_BRP(n)		((uint32_t)(n&0x3FF))
+/** CAN Synchronization Jump Width */
+#define CAN_BTR_SJM(n)		((uint32_t)((n&0x3)<<14))
+/** CAN Time Segment 1 */
+#define CAN_BTR_TESG1(n)	((uint32_t)(n&0xF)<<16))
+/** CAN Time Segment 2 */
+#define CAN_BTR_TESG2(n)	((uint32_t)(n&0xF)<<20))
+/** CAN Sampling */
+#define CAN_BTR_SAM(n)		((uint32_t)(1<<23))
+
+/*********************************************************************//**
+ * Macro defines for CAN Error Warning Limit Register
+ **********************************************************************/
+/** CAN Error Warning Limit */
+#define CAN_EWL_EWL(n)		((uint32_t)(n&0xFF))
+
+/*********************************************************************//**
+ * Macro defines for CAN Status Register
+ **********************************************************************/
+/** CAN Receive Buffer Status */
+#define CAN_SR_RBS		((uint32_t)(1))
+/** CAN Data Overrun Status */
+#define CAN_SR_DOS		((uint32_t)(1<<1))
+/** CAN Transmit Buffer Status 1 */
+#define CAN_SR_TBS1		((uint32_t)(1<<2))
+/** CAN Transmission Complete Status of Buffer 1 */
+#define CAN_SR_TCS1		((uint32_t)(1<<3))
+/** CAN Receive Status */
+#define CAN_SR_RS		((uint32_t)(1<<4))
+/** CAN Transmit Status 1 */
+#define CAN_SR_TS1		((uint32_t)(1<<5))
+/** CAN Error Status */
+#define CAN_SR_ES		((uint32_t)(1<<6))
+/** CAN Bus Status */
+#define CAN_SR_BS		((uint32_t)(1<<7))
+/** CAN Transmit Buffer Status 2 */
+#define CAN_SR_TBS2		((uint32_t)(1<<10))
+/** CAN Transmission Complete Status of Buffer 2 */
+#define CAN_SR_TCS2		((uint32_t)(1<<11))
+/** CAN Transmit Status 2 */
+#define CAN_SR_TS2		((uint32_t)(1<<13))
+/** CAN Transmit Buffer Status 2 */
+#define CAN_SR_TBS3		((uint32_t)(1<<18))
+/** CAN Transmission Complete Status of Buffer 2 */
+#define CAN_SR_TCS3		((uint32_t)(1<<19))
+/** CAN Transmit Status 2 */
+#define CAN_SR_TS3		((uint32_t)(1<<21))
+
+/*********************************************************************//**
+ * Macro defines for CAN Receive Frame Status Register
+ **********************************************************************/
+/** CAN ID Index */
+#define CAN_RFS_ID_INDEX(n)	((uint32_t)(n&0x3FF))
+/** CAN Bypass */
+#define CAN_RFS_BP			((uint32_t)(1<<10))
+/** CAN Data Length Code */
+#define CAN_RFS_DLC(n)		((uint32_t)((n&0xF)<<16)
+/** CAN Remote Transmission Request */
+#define CAN_RFS_RTR			((uint32_t)(1<<30))
+/** CAN control 11 bit or 29 bit Identifier */
+#define CAN_RFS_FF			((uint32_t)(1<<31))
+
+/*********************************************************************//**
+ * Macro defines for CAN Receive Identifier Register
+ **********************************************************************/
+/** CAN 11 bit Identifier */
+#define CAN_RID_ID_11(n)		((uint32_t)(n&0x7FF))
+/** CAN 29 bit Identifier */
+#define CAN_RID_ID_29(n)		((uint32_t)(n&0x1FFFFFFF))
+
+/*********************************************************************//**
+ * Macro defines for CAN Receive Data A Register
+ **********************************************************************/
+/** CAN Receive Data 1 */
+#define CAN_RDA_DATA1(n)		((uint32_t)(n&0xFF))
+/** CAN Receive Data 2 */
+#define CAN_RDA_DATA2(n)		((uint32_t)((n&0xFF)<<8))
+/** CAN Receive Data 3 */
+#define CAN_RDA_DATA3(n)		((uint32_t)((n&0xFF)<<16))
+/** CAN Receive Data 4 */
+#define CAN_RDA_DATA4(n)		((uint32_t)((n&0xFF)<<24))
+
+/*********************************************************************//**
+ * Macro defines for CAN Receive Data B Register
+ **********************************************************************/
+/** CAN Receive Data 5 */
+#define CAN_RDB_DATA5(n)		((uint32_t)(n&0xFF))
+/** CAN Receive Data 6 */
+#define CAN_RDB_DATA6(n)		((uint32_t)((n&0xFF)<<8))
+/** CAN Receive Data 7 */
+#define CAN_RDB_DATA7(n)		((uint32_t)((n&0xFF)<<16))
+/** CAN Receive Data 8 */
+#define CAN_RDB_DATA8(n)		((uint32_t)((n&0xFF)<<24))
+
+/*********************************************************************//**
+ * Macro defines for CAN Transmit Frame Information Register
+ **********************************************************************/
+/** CAN Priority */
+#define CAN_TFI_PRIO(n)			((uint32_t)(n&0xFF))
+/** CAN Data Length Code */
+#define CAN_TFI_DLC(n)			((uint32_t)((n&0xF)<<16))
+/** CAN Remote Frame Transmission */
+#define CAN_TFI_RTR				((uint32_t)(1<<30))
+/** CAN control 11-bit or 29-bit Identifier */
+#define CAN_TFI_FF				((uint32_t)(1<<31))
+
+/*********************************************************************//**
+ * Macro defines for CAN Transmit Identifier Register
+ **********************************************************************/
+/** CAN 11-bit Identifier */
+#define CAN_TID_ID11(n)			((uint32_t)(n&0x7FF))
+/** CAN 11-bit Identifier */
+#define CAN_TID_ID29(n)			((uint32_t)(n&0x1FFFFFFF))
+
+/*********************************************************************//**
+ * Macro defines for CAN Transmit Data A Register
+ **********************************************************************/
+/** CAN Transmit Data 1 */
+#define CAN_TDA_DATA1(n)		((uint32_t)(n&0xFF))
+/** CAN Transmit Data 2 */
+#define CAN_TDA_DATA2(n)		((uint32_t)((n&0xFF)<<8))
+/** CAN Transmit Data 3 */
+#define CAN_TDA_DATA3(n)		((uint32_t)((n&0xFF)<<16))
+/** CAN Transmit Data 4 */
+#define CAN_TDA_DATA4(n)		((uint32_t)((n&0xFF)<<24))
+
+/*********************************************************************//**
+ * Macro defines for CAN Transmit Data B Register
+ **********************************************************************/
+/** CAN Transmit Data 5 */
+#define CAN_TDA_DATA5(n)		((uint32_t)(n&0xFF))
+/** CAN Transmit Data 6 */
+#define CAN_TDA_DATA6(n)		((uint32_t)((n&0xFF)<<8))
+/** CAN Transmit Data 7 */
+#define CAN_TDA_DATA7(n)		((uint32_t)((n&0xFF)<<16))
+/** CAN Transmit Data 8 */
+#define CAN_TDA_DATA8(n)		((uint32_t)((n&0xFF)<<24))
+
+/*********************************************************************//**
+ * Macro defines for CAN Sleep Clear Register
+ **********************************************************************/
+/** CAN1 Sleep mode */
+#define CAN1SLEEPCLR			((uint32_t)(1<<1))
+/** CAN2 Sleep Mode */
+#define CAN2SLEEPCLR			((uint32_t)(1<<2))
+
+/*********************************************************************//**
+ * Macro defines for CAN Wake up Flags Register
+ **********************************************************************/
+/** CAN1 Sleep mode */
+#define CAN_WAKEFLAGES_CAN1WAKE		((uint32_t)(1<<1))
+/** CAN2 Sleep Mode */
+#define CAN_WAKEFLAGES_CAN2WAKE		((uint32_t)(1<<2))
+
+/*********************************************************************//**
+ * Macro defines for Central transmit Status Register
+ **********************************************************************/
+/** CAN Transmit 1 */
+#define CAN_TSR_TS1			((uint32_t)(1))
+/** CAN Transmit 2 */
+#define CAN_TSR_TS2			((uint32_t)(1<<1))
+/** CAN Transmit Buffer Status 1 */
+#define CAN_TSR_TBS1			((uint32_t)(1<<8))
+/** CAN Transmit Buffer Status 2 */
+#define CAN_TSR_TBS2			((uint32_t)(1<<9))
+/** CAN Transmission Complete Status 1 */
+#define CAN_TSR_TCS1			((uint32_t)(1<<16))
+/** CAN Transmission Complete Status 2 */
+#define CAN_TSR_TCS2			((uint32_t)(1<<17))
+
+/*********************************************************************//**
+ * Macro defines for Central Receive Status Register
+ **********************************************************************/
+/** CAN Receive Status 1 */
+#define CAN_RSR_RS1				((uint32_t)(1))
+/** CAN Receive Status 1 */
+#define CAN_RSR_RS2				((uint32_t)(1<<1))
+/** CAN Receive Buffer Status 1*/
+#define CAN_RSR_RB1				((uint32_t)(1<<8))
+/** CAN Receive Buffer Status 2*/
+#define CAN_RSR_RB2				((uint32_t)(1<<9))
+/** CAN Data Overrun Status 1 */
+#define CAN_RSR_DOS1			((uint32_t)(1<<16))
+/** CAN Data Overrun Status 1 */
+#define CAN_RSR_DOS2			((uint32_t)(1<<17))
+
+/*********************************************************************//**
+ * Macro defines for Central Miscellaneous Status Register
+ **********************************************************************/
+/** Same CAN Error Status in CAN1GSR */
+#define CAN_MSR_E1		((uint32_t)(1))
+/** Same CAN Error Status in CAN2GSR */
+#define CAN_MSR_E2		((uint32_t)(1<<1))
+/** Same CAN Bus Status in CAN1GSR */
+#define CAN_MSR_BS1		((uint32_t)(1<<8))
+/** Same CAN Bus Status in CAN2GSR */
+#define CAN_MSR_BS2		((uint32_t)(1<<9))
+
+/*********************************************************************//**
+ * Macro defines for Acceptance Filter Mode Register
+ **********************************************************************/
+/** CAN Acceptance Filter Off mode */
+#define CAN_AFMR_AccOff		((uint32_t)(1))
+/** CAN Acceptance File Bypass mode */
+#define CAN_AFMR_AccBP		((uint32_t)(1<<1))
+/** FullCAN Mode Enhancements */
+#define CAN_AFMR_eFCAN		((uint32_t)(1<<2))
+
+/*********************************************************************//**
+ * Macro defines for Standard Frame Individual Start Address Register
+ **********************************************************************/
+/** The start address of the table of individual Standard Identifier */
+#define CAN_STT_sa(n)		((uint32_t)((n&1FF)<<2))
+
+/*********************************************************************//**
+ * Macro defines for Standard Frame Group Start Address Register
+ **********************************************************************/
+/** The start address of the table of grouped Standard Identifier */
+#define CAN_SFF_GRP_sa(n)		((uint32_t)((n&3FF)<<2))
+
+/*********************************************************************//**
+ * Macro defines for Extended Frame Start Address Register
+ **********************************************************************/
+/** The start address of the table of individual Extended Identifier */
+#define CAN_EFF_sa(n)		((uint32_t)((n&1FF)<<2))
+
+/*********************************************************************//**
+ * Macro defines for Extended Frame Group Start Address Register
+ **********************************************************************/
+/** The start address of the table of grouped Extended Identifier */
+#define CAN_Eff_GRP_sa(n)		((uint32_t)((n&3FF)<<2))
+
+/*********************************************************************//**
+ * Macro defines for End Of AF Table Register
+ **********************************************************************/
+/** The End of Table of AF LookUp Table */
+#define CAN_EndofTable(n)		((uint32_t)((n&3FF)<<2))
+
+/*********************************************************************//**
+ * Macro defines for LUT Error Address Register
+ **********************************************************************/
+/** CAN Look-Up Table Error Address */
+#define CAN_LUTerrAd(n)		((uint32_t)((n&1FF)<<2))
+
+/*********************************************************************//**
+ * Macro defines for LUT Error Register
+ **********************************************************************/
+/** CAN Look-Up Table Error */
+#define CAN_LUTerr		((uint32_t)(1))
+
+/*********************************************************************//**
+ * Macro defines for Global FullCANInterrupt Enable Register
+ **********************************************************************/
+/** Global FullCANInterrupt Enable */
+#define CAN_FCANIE		((uint32_t)(1))
+
+/*********************************************************************//**
+ * Macro defines for FullCAN Interrupt and Capture Register 0
+ **********************************************************************/
+/** FullCAN Interrupt and Capture (0-31)*/
+#define CAN_FCANIC0_IntPnd(n)	((uint32_t)(1<<n))
+
+/*********************************************************************//**
+ * Macro defines for FullCAN Interrupt and Capture Register 1
+ **********************************************************************/
+/** FullCAN Interrupt and Capture (0-31)*/
+#define CAN_FCANIC1_IntPnd(n)	((uint32_t)(1<<(n-32)))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup CAN_Public_Types
+ * @{
+ */
+
+/** CAN configuration structure */
+/***********************************************************************
+ * CAN device configuration commands (IOCTL commands and arguments)
+ **********************************************************************/
+/**
+ * @brief CAN ID format definition
+ */
+typedef enum {
+	STD_ID_FORMAT = 0, 	/**< Use standard ID format (11 bit ID) */
+	EXT_ID_FORMAT = 1	/**< Use extended ID format (29 bit ID) */
+} CAN_ID_FORMAT_Type;
+
+/**
+ * @brief AFLUT Entry type definition
+ */
+typedef enum {
+	FULLCAN_ENTRY = 0,
+	EXPLICIT_STANDARD_ENTRY,
+	GROUP_STANDARD_ENTRY,
+	EXPLICIT_EXTEND_ENTRY,
+	GROUP_EXTEND_ENTRY,
+} AFLUT_ENTRY_Type;
+
+/**
+ * @brief Symbolic names for type of CAN message
+ */
+typedef enum {
+	DATA_FRAME = 0, 	/**< Data frame */
+	REMOTE_FRAME = 1	/**< Remote frame */
+} CAN_FRAME_Type;
+
+/**
+ * @brief CAN Control status definition
+ */
+typedef enum {
+	CANCTRL_GLOBAL_STS = 0, /**< CAN Global Status */
+	CANCTRL_INT_CAP, 		/**< CAN Interrupt and Capture */
+	CANCTRL_ERR_WRN, 		/**< CAN Error Warning Limit */
+	CANCTRL_STS				/**< CAN Control Status */
+} CAN_CTRL_STS_Type;
+
+/**
+ * @brief Central CAN status type definition
+ */
+typedef enum {
+	CANCR_TX_STS = 0, 	/**< Central CAN Tx Status */
+	CANCR_RX_STS, 		/**< Central CAN Rx Status */
+	CANCR_MS			/**< Central CAN Miscellaneous Status */
+} CAN_CR_STS_Type;
+
+/**
+ * @brief CAN interrupt enable type definition
+ */
+typedef enum {
+	CANINT_RIE = 0, 	/**< CAN Receiver Interrupt Enable */
+	CANINT_TIE1, 		/**< CAN Transmit Interrupt Enable */
+	CANINT_EIE, 		/**< CAN Error Warning Interrupt Enable */
+	CANINT_DOIE, 		/**< CAN Data Overrun Interrupt Enable */
+	CANINT_WUIE, 		/**< CAN Wake-Up Interrupt Enable */
+	CANINT_EPIE, 		/**< CAN Error Passive Interrupt Enable */
+	CANINT_ALIE, 		/**< CAN Arbitration Lost Interrupt Enable */
+	CANINT_BEIE, 		/**< CAN Bus Error Inter rupt Enable */
+	CANINT_IDIE, 		/**< CAN ID Ready Interrupt Enable */
+	CANINT_TIE2, 		/**< CAN Transmit Interrupt Enable for Buffer2 */
+	CANINT_TIE3, 		/**< CAN Transmit Interrupt Enable for Buffer3 */
+	CANINT_FCE			/**< FullCAN Interrupt Enable */
+} CAN_INT_EN_Type;
+
+/**
+ * @brief Acceptance Filter Mode type definition
+ */
+typedef enum {
+	CAN_Normal = 0, 	/**< Normal Mode */
+	CAN_AccOff, 		/**< Acceptance Filter Off Mode */
+	CAN_AccBP, 			/**< Acceptance Fileter Bypass Mode */
+	CAN_eFCAN			/**< FullCAN Mode Enhancement */
+} CAN_AFMODE_Type;
+
+/**
+ * @brief CAN Mode Type definition
+ */
+typedef enum {
+	CAN_OPERATING_MODE = 0, 	/**< Operating Mode */
+	CAN_RESET_MODE, 			/**< Reset Mode */
+	CAN_LISTENONLY_MODE, 		/**< Listen Only Mode */
+	CAN_SELFTEST_MODE, 			/**< Seft Test Mode */
+	CAN_TXPRIORITY_MODE, 		/**< Transmit Priority Mode */
+	CAN_SLEEP_MODE, 			/**< Sleep Mode */
+	CAN_RXPOLARITY_MODE, 		/**< Receive Polarity Mode */
+	CAN_TEST_MODE				/**< Test Mode */
+} CAN_MODE_Type;
+
+/**
+ * @brief Error values that functions can return
+ */
+typedef enum {
+	CAN_OK = 1, 				/**< No error */
+	CAN_OBJECTS_FULL_ERROR, 	/**< No more rx or tx objects available */
+	CAN_FULL_OBJ_NOT_RCV, 		/**< Full CAN object not received */
+	CAN_NO_RECEIVE_DATA, 		/**< No have receive data available */
+	CAN_AF_ENTRY_ERROR, 		/**< Entry load in AFLUT is unvalid */
+	CAN_CONFLICT_ID_ERROR, 		/**< Conflict ID occur */
+	CAN_ENTRY_NOT_EXIT_ERROR	/**< Entry remove outo AFLUT is not exit */
+} CAN_ERROR;
+
+/**
+ * @brief Pin Configuration structure
+ */
+typedef struct {
+	uint8_t RD; 			/**< Serial Inputs, from CAN transceivers, should be:
+							 ** For CAN1:
+							 - CAN_RD1_P0_0: RD pin is on P0.0
+							 - CAN_RD1_P0_21 : RD pin is on P0.21
+							 ** For CAN2:
+							 - CAN_RD2_P0_4: RD pin is on P0.4
+							 - CAN_RD2_P2_7: RD pin is on P2.7
+							 */
+	uint8_t TD;				/**< Serial Outputs, To CAN transceivers, should be:
+							 ** For CAN1:
+							 - CAN_TD1_P0_1: TD pin is on P0.1
+							 - CAN_TD1_P0_22: TD pin is on P0.22
+							 ** For CAN2:
+							 - CAN_TD2_P0_5: TD pin is on P0.5
+							 - CAN_TD2_P2_8: TD pin is on P2.8
+							 */
+} CAN_PinCFG_Type;
+
+/**
+ * @brief CAN message object structure
+ */
+typedef struct {
+	uint32_t id; 			/**< 29 bit identifier, it depend on "format" value
+								 - if format = STD_ID_FORMAT, id should be 11 bit identifier
+								 - if format = EXT_ID_FORMAT, id should be 29 bit identifier
+							 */
+	uint8_t dataA[4]; 		/**< Data field A */
+	uint8_t dataB[4]; 		/**< Data field B */
+	uint8_t len; 			/**< Length of data field in bytes, should be:
+								 - 0000b-0111b: 0-7 bytes
+								 - 1xxxb: 8 bytes
+							*/
+	uint8_t format; 		/**< Identifier Format, should be:
+								 - STD_ID_FORMAT: Standard ID - 11 bit format
+								 - EXT_ID_FORMAT: Extended ID - 29 bit format
+							*/
+	uint8_t type; 			/**< Remote Frame transmission, should be:
+								 - DATA_FRAME: the number of data bytes called out by the DLC
+								 field are send from the CANxTDA and CANxTDB registers
+								 - REMOTE_FRAME: Remote Frame is sent
+							*/
+} CAN_MSG_Type;
+
+/**
+ * @brief FullCAN Entry structure
+ */
+typedef struct {
+	uint8_t controller;		/**< CAN Controller, should be:
+								 - CAN1_CTRL: CAN1 Controller
+								 - CAN2_CTRL: CAN2 Controller
+							*/
+	uint8_t disable;		/**< Disable bit, should be:
+								 - MSG_ENABLE: disable bit = 0
+								 - MSG_DISABLE: disable bit = 1
+							*/
+	uint16_t id_11;			/**< Standard ID, should be 11-bit value */
+} FullCAN_Entry;
+
+/**
+ * @brief Standard ID Frame Format Entry structure
+ */
+typedef struct {
+	uint8_t controller; 	/**< CAN Controller, should be:
+								 - CAN1_CTRL: CAN1 Controller
+								 - CAN2_CTRL: CAN2 Controller
+							*/
+	uint8_t disable; 		/**< Disable bit, should be:
+								 - MSG_ENABLE: disable bit = 0
+								 - MSG_DISABLE: disable bit = 1
+							*/
+	uint16_t id_11; 		/**< Standard ID, should be 11-bit value */
+} SFF_Entry;
+
+/**
+ * @brief Group of Standard ID Frame Format Entry structure
+ */
+typedef struct {
+	uint8_t controller1; 	/**< First CAN Controller, should be:
+								 - CAN1_CTRL: CAN1 Controller
+								 - CAN2_CTRL: CAN2 Controller
+							*/
+	uint8_t disable1; 		/**< First Disable bit, should be:
+								 - MSG_ENABLE: disable bit = 0)
+								 - MSG_DISABLE: disable bit = 1
+							*/
+	uint16_t lowerID; 		/**< ID lower bound, should be 11-bit value */
+	uint8_t controller2; 	/**< Second CAN Controller, should be:
+								 - CAN1_CTRL: CAN1 Controller
+								 - CAN2_CTRL: CAN2 Controller
+							*/
+	uint8_t disable2; 		/**< Second Disable bit, should be:
+								 - MSG_ENABLE: disable bit = 0
+								 - MSG_DISABLE: disable bit = 1
+							*/
+	uint16_t upperID; 		/**< ID upper bound, should be 11-bit value and
+								 equal or greater than lowerID
+							*/
+} SFF_GPR_Entry;
+
+/**
+ * @brief Extended ID Frame Format Entry structure
+ */
+typedef struct {
+	uint8_t controller; 	/**< CAN Controller, should be:
+								 - CAN1_CTRL: CAN1 Controller
+								 - CAN2_CTRL: CAN2 Controller
+							*/
+	uint32_t ID_29; 		/**< Extend ID, shoud be 29-bit value */
+} EFF_Entry;
+
+
+/**
+ * @brief Group of Extended ID Frame Format Entry structure
+ */
+typedef struct {
+	uint8_t controller1; 	/**< First CAN Controller, should be:
+								 - CAN1_CTRL: CAN1 Controller
+								 - CAN2_CTRL: CAN2 Controller
+							*/
+	uint8_t controller2; 	/**< Second Disable bit, should be:
+								 - MSG_ENABLE: disable bit = 0(default)
+								 - MSG_DISABLE: disable bit = 1
+							*/
+	uint32_t lowerEID; 		/**< Extended ID lower bound, should be 29-bit value */
+	uint32_t upperEID; 		/**< Extended ID upper bound, should be 29-bit value */
+} EFF_GPR_Entry;
+
+
+/**
+ * @brief Acceptance Filter Section Table structure
+ */
+typedef struct {
+	FullCAN_Entry* FullCAN_Sec; 	/**< The pointer point to FullCAN_Entry */
+	uint8_t FC_NumEntry;			/**< FullCAN Entry Number */
+	SFF_Entry* SFF_Sec; 			/**< The pointer point to SFF_Entry */
+	uint8_t SFF_NumEntry;			/**< Standard ID Entry Number */
+	SFF_GPR_Entry* SFF_GPR_Sec; 	/**< The pointer point to SFF_GPR_Entry */
+	uint8_t SFF_GPR_NumEntry;		/**< Group Standard ID Entry Number */
+	EFF_Entry* EFF_Sec; 			/**< The pointer point to EFF_Entry */
+	uint8_t EFF_NumEntry;			/**< Extended ID Entry Number */
+	EFF_GPR_Entry* EFF_GPR_Sec; 	/**< The pointer point to EFF_GPR_Entry */
+	uint8_t EFF_GPR_NumEntry;		/**< Group Extended ID Entry Number */
+} AF_SectionDef;
+
+/**
+ * @brief CAN call-back function type definitions
+ */
+typedef void ( fnCANCbs_Type)();
+
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup CAN_Public_Macros
+ * @{
+ */
+
+/** Macro to determine if it is valid CAN peripheral */
+#define PARAM_CANx(x)			((((uint32_t*)x)==((uint32_t *)LPC_CAN1)) \
+||(((uint32_t*)x)==((uint32_t *)LPC_CAN2)))
+
+#define PARAM_CANAFx(x)			(((uint32_t*)x)== ((uint32_t*)LPC_CANAF))
+#define PARAM_CANAFRAMx(x)		(((uint32_t*)x)== (uint32_t*)LPC_CANAF_RAM)
+#define PARAM_CANCRx(x)			(((uint32_t*)x)==((uint32_t*)LPC_CANCR))
+
+/** Macro to check Data to send valid */
+#define PARAM_I2S_DATA(data) 	((data>=0)&&(data <= 0xFFFFFFFF))
+#define PRAM_I2S_FREQ(freq)		((freq>=16000)&&(freq <= 96000))
+
+/** Macro to check Pin Selection value */
+#define PARAM_RD1_PIN(n)		((n==CAN_RD1_P0_0)||(n==CAN_RD1_P0_21))
+#define PARAM_TD1_PIN(n)		((n==CAN_TD1_P0_1)||(n==CAN_TD1_P0_22))
+#define PARAM_RD2_PIN(n)		((n==CAN_RD2_P0_4)||(n==CAN_RD2_P2_7))
+#define PARAM_TD2_PIN(n)		((n==CAN_TD2_P0_5)||(n==CAN_TD2_P2_8))
+
+/** Macro to check Frame Identifier */
+#define PARAM_ID_11(n)			((n>>11)==0) /*-- 11 bit --*/
+#define PARAM_ID_29(n)			((n>>29)==0) /*-- 29 bit --*/
+
+#define PARAM_DLC(n)			((n>>4)==0)  /*-- 4 bit --*/
+#define PARAM_ID_FORMAT(n)		((n==STD_ID_FORMAT)||(n==EXT_ID_FORMAT))
+#define PARAM_GRP_ID(x, y)		((x<=y))
+#define PARAM_FRAME_TYPE(n)		((n==DATA_FRAME)||(n==REMOTE_FRAME))
+
+/** Macro to check Control/Central Status type parameter */
+#define PARAM_CTRL_STS_TYPE(n)	((n==CANCTRL_GLOBAL_STS)||(n==CANCTRL_INT_CAP) \
+||(n==CANCTRL_ERR_WRN)||(n==CANCTRL_STS))
+#define PARAM_CR_STS_TYPE(n)	((n==CANCR_TX_STS)||(n==CANCR_RX_STS) \
+||(n==CANCR_MS))
+/** Macro to check AF Mode type parameter */
+#define PARAM_AFMODE_TYPE(n)	((n==CAN_Normal)||(n==CAN_AccOff) \
+||(n==CAN_AccBP)||(n==CAN_eFCAN))
+/** Macro to check Operation Mode */
+#define PARAM_MODE_TYPE(n)		((n==CAN_OPERATING_MODE)||(n==CAN_RESET_MODE) \
+||(n==CAN_LISTENONLY_MODE)||(n==CAN_SELFTEST_MODE) \
+||(n==CAN_TXPRIORITY_MODE)||(n==CAN_SLEEP_MODE) \
+||(n==CAN_RXPOLARITY_MODE)||(n==CAN_TEST_MODE))
+
+/** Macro define for struct AF_Section parameter */
+#define CAN1_CTRL	((uint8_t)(0))
+#define CAN2_CTRL	((uint8_t)(1))
+#define PARAM_CTRL(n)	((n==CAN1_CTRL)|(n==CAN2_CTRL))
+
+#define MSG_ENABLE				((uint8_t)(0))
+#define MSG_DISABLE				((uint8_t)(1))
+#define PARAM_MSG_DISABLE(n)	((n==MSG_ENABLE)|(n==MSG_DISABLE))
+
+/**Macro to check Interrupt Type parameter */
+#define PARAM_INT_EN_TYPE(n)	((n==CANINT_RIE)||(n==CANINT_TIE1) \
+||(n==CANINT_EIE)||(n==CANINT_DOIE) \
+||(n==CANINT_WUIE)||(n==CANINT_EPIE) \
+||(n==CANINT_ALIE)||(n==CANINT_BEIE) \
+||(n==CANINT_IDIE)||(n==CANINT_TIE2) \
+||(n==CANINT_TIE3)||(n==CANINT_FCE))
+
+/** Macro to check AFLUT Entry type */
+#define PARAM_AFLUT_ENTRY_TYPE(n)	((n==FULLCAN_ENTRY)||(n==EXPLICIT_STANDARD_ENTRY)\
+||(n==GROUP_STANDARD_ENTRY)||(n==EXPLICIT_EXTEND_ENTRY)	\
+||(n==GROUP_EXTEND_ENTRY))
+#define PARAM_POSITION(n)	((n>=0)&&(n<512))
+
+/** CAN function pin selection defines */
+#define CAN_RD1_P0_0		((uint8_t)(0))
+#define CAN_RD1_P0_21		((uint8_t)(1))
+#define CAN_TD1_P0_1		((uint8_t)(0))
+#define CAN_TD1_P0_22		((uint8_t)(1))
+
+#define CAN_RD2_P0_4		((uint8_t)(0))
+#define CAN_RD2_P2_7		((uint8_t)(1))
+#define CAN_TD2_P0_5		((uint8_t)(0))
+#define CAN_TD2_P2_8		((uint8_t)(1))
+
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup CAN_Public_Functions
+ * @{
+ */
+
+void CAN_Init(LPC_CAN_TypeDef *CANx, uint32_t baudrate);
+void CAN_DeInit(LPC_CAN_TypeDef *CANx);
+
+Status CAN_SendMsg(LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg);
+Status CAN_ReceiveMsg(LPC_CAN_TypeDef *CANx, CAN_MSG_Type *CAN_Msg);
+CAN_ERROR FCAN_ReadObj(LPC_CANAF_TypeDef* CANAFx, CAN_MSG_Type *CAN_Msg);
+
+uint32_t CAN_GetCTRLStatus(LPC_CAN_TypeDef* CANx, CAN_CTRL_STS_Type arg);
+uint32_t CAN_GetCRStatus(LPC_CANCR_TypeDef* CANCRx, CAN_CR_STS_Type arg);
+void CAN_ModeConfig(LPC_CAN_TypeDef* CANx, CAN_MODE_Type mode,
+		FunctionalState NewState);
+void CAN_SetBaudRate(LPC_CAN_TypeDef *CANx, uint32_t baudrate);
+
+void CAN_SetAFMode(LPC_CANAF_TypeDef* CANAFx, CAN_AFMODE_Type AFmode);
+CAN_ERROR CAN_SetupAFLUT(LPC_CANAF_TypeDef* CANAFx, AF_SectionDef* AFSection);
+CAN_ERROR CAN_LoadFullCANEntry(LPC_CAN_TypeDef* CANx, uint16_t ID);
+CAN_ERROR CAN_LoadExplicitEntry(LPC_CAN_TypeDef* CANx, uint32_t ID,
+		CAN_ID_FORMAT_Type format);
+CAN_ERROR CAN_LoadGroupEntry(LPC_CAN_TypeDef* CANx, uint32_t lowerID,
+		uint32_t upperID, CAN_ID_FORMAT_Type format);
+CAN_ERROR CAN_RemoveEntry(AFLUT_ENTRY_Type EntryType, uint16_t position);
+
+void CAN_SetupCBS(CAN_INT_EN_Type arg, fnCANCbs_Type* pnCANCbs);
+void CAN_IRQCmd(LPC_CAN_TypeDef* CANx, CAN_INT_EN_Type arg,
+		FunctionalState NewState);
+void CAN_IntHandler(LPC_CAN_TypeDef* CANx);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_CAN_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.c
new file mode 100644
index 0000000..64d7b09
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.c
@@ -0,0 +1,345 @@
+/**
+ * @file	: lpc17xx_clkpwr.c
+ * @brief	: Contains all functions support for Clock and Power Control
+ * 				firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 18. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup CLKPWR
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_clkpwr.h"
+#include "system_LPC17xx.h"
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup CLKPWR_Public_Functions
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief 		Set value of each Peripheral Clock Selection
+ * @param[in]	ClkType	Peripheral Clock Selection of each type,
+ * 				should be one of the following:
+ *				- CLKPWR_PCLKSEL_WDT   		: WDT
+				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
+				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
+				- CLKPWR_PCLKSEL_UART0   	: UART 0
+				- CLKPWR_PCLKSEL_UART1  	: UART 1
+				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
+				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
+				- CLKPWR_PCLKSEL_SPI   		: SPI
+				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
+				- CLKPWR_PCLKSEL_DAC   		: DAC
+				- CLKPWR_PCLKSEL_ADC   		: ADC
+				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
+				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
+				- CLKPWR_PCLKSEL_ACF   		: ACF
+				- CLKPWR_PCLKSEL_QEI 		: QEI
+				- CLKPWR_PCLKSEL_PCB   		: PCB
+				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
+				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
+				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
+				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
+				- CLKPWR_PCLKSEL_UART2   	: UART 2
+				- CLKPWR_PCLKSEL_UART3   	: UART 3
+				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
+				- CLKPWR_PCLKSEL_I2S   		: I2S
+				- CLKPWR_PCLKSEL_RIT   		: RIT
+				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
+				- CLKPWR_PCLKSEL_MC 		: MC
+
+ * @param[in]	DivVal	Value of divider, should be:
+ * 				- CLKPWR_PCLKSEL_CCLK_DIV_4 : PCLK_peripheral = CCLK/4
+ * 				- CLKPWR_PCLKSEL_CCLK_DIV_1 : PCLK_peripheral = CCLK/1
+ *				- CLKPWR_PCLKSEL_CCLK_DIV_2 : PCLK_peripheral = CCLK/2
+ *
+ * @return none
+ **********************************************************************/
+void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal)
+{
+	uint32_t bitpos;
+
+	bitpos = (ClkType < 32) ? (ClkType) : (ClkType - 32);
+
+	/* PCLKSEL0 selected */
+	if (ClkType < 32)
+	{
+		/* Clear two bit at bit position */
+		LPC_SC->PCLKSEL0 &= (~(CLKPWR_PCLKSEL_BITMASK(bitpos)));
+
+		/* Set two selected bit */
+		LPC_SC->PCLKSEL0 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
+	}
+	/* PCLKSEL1 selected */
+	else
+	{
+		/* Clear two bit at bit position */
+		LPC_SC->PCLKSEL1 &= ~(CLKPWR_PCLKSEL_BITMASK(bitpos));
+
+		/* Set two selected bit */
+		LPC_SC->PCLKSEL1 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Get current value of each Peripheral Clock Selection
+ * @param[in]	ClkType	Peripheral Clock Selection of each type,
+ * 				should be one of the following:
+ *				- CLKPWR_PCLKSEL_WDT   		: WDT
+				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
+				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
+				- CLKPWR_PCLKSEL_UART0   	: UART 0
+				- CLKPWR_PCLKSEL_UART1  	: UART 1
+				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
+				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
+				- CLKPWR_PCLKSEL_SPI   		: SPI
+				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
+				- CLKPWR_PCLKSEL_DAC   		: DAC
+				- CLKPWR_PCLKSEL_ADC   		: ADC
+				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
+				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
+				- CLKPWR_PCLKSEL_ACF   		: ACF
+				- CLKPWR_PCLKSEL_QEI 		: QEI
+				- CLKPWR_PCLKSEL_PCB   		: PCB
+				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
+				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
+				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
+				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
+				- CLKPWR_PCLKSEL_UART2   	: UART 2
+				- CLKPWR_PCLKSEL_UART3   	: UART 3
+				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
+				- CLKPWR_PCLKSEL_I2S   		: I2S
+				- CLKPWR_PCLKSEL_RIT   		: RIT
+				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
+				- CLKPWR_PCLKSEL_MC 		: MC
+
+ * @return		Value of Selected Peripheral Clock Selection
+ **********************************************************************/
+uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType)
+{
+	uint32_t bitpos, retval;
+
+	if (ClkType < 32)
+	{
+		bitpos = ClkType;
+		retval = LPC_SC->PCLKSEL0;
+	}
+	else
+	{
+		bitpos = ClkType - 32;
+		retval = LPC_SC->PCLKSEL1;
+	}
+
+	retval = CLKPWR_PCLKSEL_GET(bitpos, retval);
+	return retval;
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Get current value of each Peripheral Clock
+ * @param[in]	ClkType	Peripheral Clock Selection of each type,
+ * 				should be one of the following:
+ *				- CLKPWR_PCLKSEL_WDT   		: WDT
+				- CLKPWR_PCLKSEL_TIMER0   	: Timer 0
+				- CLKPWR_PCLKSEL_TIMER1   	: Timer 1
+				- CLKPWR_PCLKSEL_UART0   	: UART 0
+				- CLKPWR_PCLKSEL_UART1  	: UART 1
+				- CLKPWR_PCLKSEL_PWM1   	: PWM 1
+				- CLKPWR_PCLKSEL_I2C0   	: I2C 0
+				- CLKPWR_PCLKSEL_SPI   		: SPI
+				- CLKPWR_PCLKSEL_SSP1   	: SSP 1
+				- CLKPWR_PCLKSEL_DAC   		: DAC
+				- CLKPWR_PCLKSEL_ADC   		: ADC
+				- CLKPWR_PCLKSEL_CAN1  		: CAN 1
+				- CLKPWR_PCLKSEL_CAN2  		: CAN 2
+				- CLKPWR_PCLKSEL_ACF   		: ACF
+				- CLKPWR_PCLKSEL_QEI 		: QEI
+				- CLKPWR_PCLKSEL_PCB   		: PCB
+				- CLKPWR_PCLKSEL_I2C1   	: I2C 1
+				- CLKPWR_PCLKSEL_SSP0   	: SSP 0
+				- CLKPWR_PCLKSEL_TIMER2   	: Timer 2
+				- CLKPWR_PCLKSEL_TIMER3   	: Timer 3
+				- CLKPWR_PCLKSEL_UART2   	: UART 2
+				- CLKPWR_PCLKSEL_UART3   	: UART 3
+				- CLKPWR_PCLKSEL_I2C2   	: I2C 2
+				- CLKPWR_PCLKSEL_I2S   		: I2S
+				- CLKPWR_PCLKSEL_RIT   		: RIT
+				- CLKPWR_PCLKSEL_SYSCON   	: SYSCON
+				- CLKPWR_PCLKSEL_MC 		: MC
+
+ * @return		Value of Selected Peripheral Clock
+ **********************************************************************/
+uint32_t CLKPWR_GetPCLK (uint32_t ClkType)
+{
+	uint32_t retval, div;
+
+	retval = SystemCoreClock;
+	div = CLKPWR_GetPCLKSEL(ClkType);
+
+	switch (div)
+	{
+	case 0:
+		div = 4;
+		break;
+
+	case 1:
+		div = 1;
+		break;
+
+	case 2:
+		div = 2;
+		break;
+
+	case 3:
+		div = 8;
+		break;
+	}
+	retval /= div;
+
+	return retval;
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Configure power supply for each peripheral according to NewState
+ * @param[in]	PPType	Type of peripheral used to enable power,
+ *     					should be one of the following:
+ *     			-  CLKPWR_PCONP_PCTIM0 		: Timer 0
+				-  CLKPWR_PCONP_PCTIM1 		: Timer 1
+				-  CLKPWR_PCONP_PCUART0  	: UART 0
+				-  CLKPWR_PCONP_PCUART1   	: UART 1
+				-  CLKPWR_PCONP_PCPWM1 		: PWM 1
+				-  CLKPWR_PCONP_PCI2C0 		: I2C 0
+				-  CLKPWR_PCONP_PCSPI   	: SPI
+				-  CLKPWR_PCONP_PCRTC   	: RTC
+				-  CLKPWR_PCONP_PCSSP1 		: SSP 1
+				-  CLKPWR_PCONP_PCAD   		: ADC
+				-  CLKPWR_PCONP_PCAN1   	: CAN 1
+				-  CLKPWR_PCONP_PCAN2   	: CAN 2
+				-  CLKPWR_PCONP_PCGPIO 		: GPIO
+				-  CLKPWR_PCONP_PCRIT 		: RIT
+				-  CLKPWR_PCONP_PCMC 		: MC
+				-  CLKPWR_PCONP_PCQEI 		: QEI
+				-  CLKPWR_PCONP_PCI2C1   	: I2C 1
+				-  CLKPWR_PCONP_PCSSP0 		: SSP 0
+				-  CLKPWR_PCONP_PCTIM2 		: Timer 2
+				-  CLKPWR_PCONP_PCTIM3 		: Timer 3
+				-  CLKPWR_PCONP_PCUART2  	: UART 2
+				-  CLKPWR_PCONP_PCUART3   	: UART 3
+				-  CLKPWR_PCONP_PCI2C2 		: I2C 2
+				-  CLKPWR_PCONP_PCI2S   	: I2S
+				-  CLKPWR_PCONP_PCGPDMA   	: GPDMA
+				-  CLKPWR_PCONP_PCENET 		: Ethernet
+				-  CLKPWR_PCONP_PCUSB   	: USB
+ *
+ * @param[in]	NewState	New state of Peripheral Power, should be:
+ * 				- ENABLE	: Enable power for this peripheral
+ * 				- DISABLE	: Disable power for this peripheral
+ *
+ * @return none
+ **********************************************************************/
+void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState)
+{
+	if (NewState == ENABLE)
+	{
+		LPC_SC->PCONP |= PPType & CLKPWR_PCONP_BITMASK;
+	}
+	else if (NewState == DISABLE)
+	{
+		LPC_SC->PCONP &= (~PPType) & CLKPWR_PCONP_BITMASK;
+	}
+}
+
+
+/**
+ * @brief 		Enter Sleep mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ */
+void CLKPWR_Sleep(void)
+{
+	LPC_SC->PCON = 0x00;
+	/* Sleep Mode*/
+	__WFI();
+}
+
+
+/**
+ * @brief 		Enter Deep Sleep mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ */
+void CLKPWR_DeepSleep(void)
+{
+    /* Deep-Sleep Mode, set SLEEPDEEP bit */
+	SCB->SCR = 0x4;
+	LPC_SC->PCON = 0x00;
+	/* Sleep Mode*/
+	__WFI();
+}
+
+
+/**
+ * @brief 		Enter Power Down mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ */
+void CLKPWR_PowerDown(void)
+{
+    /* Deep-Sleep Mode, set SLEEPDEEP bit */
+	SCB->SCR = 0x4;
+	LPC_SC->PCON = 0x01;
+	/* Sleep Mode*/
+	__WFI();
+}
+
+
+/**
+ * @brief 		Enter Deep Power Down mode with co-operated instruction by the Cortex-M3.
+ * @param[in]	None
+ * @return		None
+ */
+void CLKPWR_DeepPowerDown(void)
+{
+    /* Deep-Sleep Mode, set SLEEPDEEP bit */
+	SCB->SCR = 0x4;
+	LPC_SC->PCON = 0x03;
+	/* Sleep Mode*/
+	__WFI();
+}
+
+
+/**
+ * @brief 		Configure Brown-Out function in
+ */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.h
new file mode 100644
index 0000000..cb47275
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_clkpwr.h
@@ -0,0 +1,384 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_clkpwr.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for Clock and Power Control firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 18. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup CLKPWR
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_CLKPWR_H_
+#define LPC17XX_CLKPWR_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx.h"
+#include "lpc_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup CLKPWR_Private_Macros
+ * @{
+ */
+
+/** @defgroup CLKPPWR_REGISTER_BIT_DEFINITIONS
+ * @{
+ */
+
+/* Clock source selection multiplexer definition */
+/** Internal RC oscillator */
+#define CLKPWR_CLKSRCSEL_CLKSRC_IRC			((uint32_t)(0x00))
+/** Main oscillator */
+#define CLKPWR_CLKSRCSEL_CLKSRC_MAINOSC		((uint32_t)(0x01))
+/** RTC oscillator */
+#define CLKPWR_CLKSRCSEL_CLKSRC_RTC			((uint32_t)(0x02))
+/** Clock source selection bit mask */
+#define CLKPWR_CLKSRCSEL_BITMASK			((uint32_t)(0x03))
+
+
+/* Clock Output Configuration register definition */
+/** Selects the CPU clock as the CLKOUT source */
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_CPU		((uint32_t)(0x00))
+/** Selects the main oscillator as the CLKOUT source */
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_MAINOSC	((uint32_t)(0x01))
+/** Selects the Internal RC oscillator as the CLKOUT source */
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_RC		((uint32_t)(0x02))
+/** Selects the USB clock as the CLKOUT source */
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_USB		((uint32_t)(0x03))
+/** Selects the RTC oscillator as the CLKOUT source */
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_RTC		((uint32_t)(0x04))
+/** Integer value to divide the output clock by, minus one */
+#define CLKPWR_CLKOUTCFG_CLKOUTDIV(n)		((uint32_t)((n&0x0F)<<4))
+/** CLKOUT enable control */
+#define CLKPWR_CLKOUTCFG_CLKOUT_EN			((uint32_t)(1<<8))
+/** CLKOUT activity indication */
+#define CLKPWR_CLKOUTCFG_CLKOUT_ACT			((uint32_t)(1<<9))
+/** Clock source selection bit mask */
+#define CLKPWR_CLKOUTCFG_BITMASK			((uint32_t)(0x3FF))
+
+
+/* PLL 0 control definition */
+/** PLL 0 control enable */
+#define CLKPWR_PLL0CON_ENABLE		((uint32_t)(0x01))
+/** PLL 0 control connect */
+#define CLKPWR_PLL0CON_CONNECT		((uint32_t)(0x02))
+/** PLL 0 control bit mask */
+#define CLKPWR_PLL0CON_BITMASK		((uint32_t)(0x03))
+
+
+/* PLL 0 Configuration register definition */
+/** PLL 0 Configuration MSEL field */
+#define CLKPWR_PLL0CFG_MSEL(n)		((uint32_t)(n&0x7FFF))
+/** PLL 0 Configuration NSEL field */
+#define CLKPWR_PLL0CFG_NSEL(n)		((uint32_t)((n<<16)&0xFF0000))
+/** PLL 0 Configuration bit mask */
+#define CLKPWR_PLL0CFG_BITMASK		((uint32_t)(0xFF7FFF))
+
+
+/* PLL 0 status definition */
+/** PLL 0 MSEL value */
+#define CLKPWR_PLL0STAT_MSEL(n)		((uint32_t)(n&0x7FFF))
+/** PLL NSEL get value  */
+#define CLKPWR_PLL0STAT_NSEL(n)		((uint32_t)((n>>16)&0xFF))
+/** PLL status enable bit */
+#define CLKPWR_PLL0STAT_PLLE		((uint32_t)(1<<24))
+/** PLL status Connect bit */
+#define CLKPWR_PLL0STAT_PLLC		((uint32_t)(1<<25))
+/** PLL status lock */
+#define CLKPWR_PLL0STAT_PLOCK		((uint32_t)(1<<26))
+
+
+/* PLL0 Feed register definition */
+/** PLL0 Feed bit mask */
+#define CLKPWR_PLL0FEED_BITMASK			((uint32_t)0xFF)
+
+
+/* USB PLL control definition */
+/** USB PLL control enable */
+#define CLKPWR_PLL1CON_ENABLE		((uint32_t)(0x01))
+/** USB PLL control connect */
+#define CLKPWR_PLL1CON_CONNECT		((uint32_t)(0x02))
+/** USB PLL control bit mask */
+#define CLKPWR_PLL1CON_BITMASK		((uint32_t)(0x03))
+
+
+/* USB PLL configuration definition */
+/** USB PLL MSEL set value */
+#define CLKPWR_PLL1CFG_MSEL(n)		((uint32_t)(n&0x1F))
+/** USB PLL PSEL set value */
+#define CLKPWR_PLL1CFG_PSEL(n)		((uint32_t)((n&0x03)<<5))
+/** USB PLL configuration bit mask */
+#define CLKPWR_PLL1CFG_BITMASK		((uint32_t)(0x7F))
+
+
+/* USB PLL status definition */
+/** USB PLL MSEL get value  */
+#define CLKPWR_PLL1STAT_MSEL(n)		((uint32_t)(n&0x1F))
+/** USB PLL PSEL get value  */
+#define CLKPWR_PLL1STAT_PSEL(n)		((uint32_t)((n>>5)&0x03))
+/** USB PLL status enable bit */
+#define CLKPWR_PLL1STAT_PLLE		((uint32_t)(1<<8))
+/** USB PLL status Connect bit */
+#define CLKPWR_PLL1STAT_PLLC		((uint32_t)(1<<9))
+/** USB PLL status lock */
+#define CLKPWR_PLL1STAT_PLOCK		((uint32_t)(1<<10))
+
+
+/* PLL1 Feed register definition */
+/** PLL1 Feed bit mask */
+#define CLKPWR_PLL1FEED_BITMASK		((uint32_t)0xFF)
+
+
+/* CPU Clock Configuration register definition */
+/** CPU Clock configuration bit mask */
+#define CLKPWR_CCLKCFG_BITMASK		((uint32_t)(0xFF))
+
+/* USB Clock Configuration register definition */
+/** USB Clock Configuration bit mask */
+#define CLKPWR_USBCLKCFG_BITMASK	((uint32_t)(0x0F))
+
+/* IRC Trim register definition */
+/** IRC Trim bit mask */
+#define CLKPWR_IRCTRIM_BITMASK		((uint32_t)(0x0F))
+
+
+/* Peripheral clock divider bit position definition */
+/** Peripheral Clock Selection 0 mask bit */
+#define CLKPWR_PCLKSEL0_BITMASK		((uint32_t)(0xFFF3F3FF))
+/** Peripheral Clock Selection 1 mask bit */
+#define CLKPWR_PCLKSEL1_BITMASK		((uint32_t)(0xFCF3F0F3))
+
+
+/** Macro to set peripheral clock of each type
+ * p: position of two bits that hold divider of peripheral clock
+ * n: value of divider of peripheral clock  to be set */
+#define CLKPWR_PCLKSEL_SET(p,n)		_SBF(p,n)
+/** Macro to mask peripheral clock of each type */
+#define CLKPWR_PCLKSEL_BITMASK(p)	_SBF(p,0x03)
+/** Macro to get peripheral clock of each type */
+#define CLKPWR_PCLKSEL_GET(p, n)	((uint32_t)((n>>p)&0x03))
+
+
+/* Power Mode Control register definition */
+/** Power mode control bit 0 */
+#define CLKPWR_PCON_PM0			((uint32_t)(1<<0))
+/** Power mode control bit 1 */
+#define CLKPWR_PCON_PM1			((uint32_t)(1<<1))
+/** Brown-Out Reduced Power Mode */
+#define CLKPWR_PCON_BODPDM		((uint32_t)(1<<2))
+/** Brown-Out Global Disable */
+#define CLKPWR_PCON_BOGD		((uint32_t)(1<<3))
+/** Brown Out Reset Disable */
+#define CLKPWR_PCON_BORD		((uint32_t)(1<<4))
+/** Sleep Mode entry flag */
+#define CLKPWR_PCON_SMFLAG		((uint32_t)(1<<8))
+/** Deep Sleep entry flag */
+#define CLKPWR_PCON_DSFLAG		((uint32_t)(1<<9))
+/** Power-down entry flag */
+#define CLKPWR_PCON_PDFLAG		((uint32_t)(1<<10))
+/** Deep Power-down entry flag */
+#define CLKPWR_PCON_DPDFLAG		((uint32_t)(1<<11))
+
+
+/** Power Control for Peripherals bit mask */
+#define CLKPWR_PCONP_BITMASK	0xEFEFF7DE
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup CLKPWR_Public_Macros
+ * @{
+ */
+
+/**********************************************************************
+ * Peripheral Clock Selection Definitions
+ **********************************************************************/
+/** Peripheral clock divider bit position for WDT */
+#define	CLKPWR_PCLKSEL_WDT  		((uint32_t)(0))
+/** Peripheral clock divider bit position for TIMER0 */
+#define	CLKPWR_PCLKSEL_TIMER0  		((uint32_t)(2))
+/** Peripheral clock divider bit position for TIMER1 */
+#define	CLKPWR_PCLKSEL_TIMER1  		((uint32_t)(4))
+/** Peripheral clock divider bit position for UART0 */
+#define	CLKPWR_PCLKSEL_UART0  		((uint32_t)(6))
+/** Peripheral clock divider bit position for UART1 */
+#define	CLKPWR_PCLKSEL_UART1  		((uint32_t)(8))
+/** Peripheral clock divider bit position for PWM1 */
+#define	CLKPWR_PCLKSEL_PWM1  		((uint32_t)(12))
+/** Peripheral clock divider bit position for I2C0 */
+#define	CLKPWR_PCLKSEL_I2C0  		((uint32_t)(14))
+/** Peripheral clock divider bit position for SPI */
+#define	CLKPWR_PCLKSEL_SPI  		((uint32_t)(16))
+/** Peripheral clock divider bit position for SSP1 */
+#define	CLKPWR_PCLKSEL_SSP1  		((uint32_t)(20))
+/** Peripheral clock divider bit position for DAC */
+#define	CLKPWR_PCLKSEL_DAC  		((uint32_t)(22))
+/** Peripheral clock divider bit position for ADC */
+#define	CLKPWR_PCLKSEL_ADC  		((uint32_t)(24))
+/** Peripheral clock divider bit position for CAN1 */
+#define	CLKPWR_PCLKSEL_CAN1 		((uint32_t)(26))
+/** Peripheral clock divider bit position for CAN2 */
+#define	CLKPWR_PCLKSEL_CAN2 		((uint32_t)(28))
+/** Peripheral clock divider bit position for ACF */
+#define	CLKPWR_PCLKSEL_ACF  		((uint32_t)(30))
+/** Peripheral clock divider bit position for QEI */
+#define	CLKPWR_PCLKSEL_QEI	  		((uint32_t)(32))
+/** Peripheral clock divider bit position for PCB */
+#define	CLKPWR_PCLKSEL_PCB  		((uint32_t)(36))
+/** Peripheral clock divider bit position for  I2C1 */
+#define	CLKPWR_PCLKSEL_I2C1  		((uint32_t)(38))
+/** Peripheral clock divider bit position for SSP0 */
+#define	CLKPWR_PCLKSEL_SSP0  		((uint32_t)(42))
+/** Peripheral clock divider bit position for TIMER2 */
+#define	CLKPWR_PCLKSEL_TIMER2  		((uint32_t)(44))
+/** Peripheral clock divider bit position for  TIMER3 */
+#define	CLKPWR_PCLKSEL_TIMER3  		((uint32_t)(46))
+/** Peripheral clock divider bit position for UART2 */
+#define	CLKPWR_PCLKSEL_UART2  		((uint32_t)(48))
+/** Peripheral clock divider bit position for UART3 */
+#define	CLKPWR_PCLKSEL_UART3  		((uint32_t)(50))
+/** Peripheral clock divider bit position for I2C2 */
+#define	CLKPWR_PCLKSEL_I2C2  		((uint32_t)(52))
+/** Peripheral clock divider bit position for I2S */
+#define	CLKPWR_PCLKSEL_I2S  		((uint32_t)(54))
+/** Peripheral clock divider bit position for RIT */
+#define	CLKPWR_PCLKSEL_RIT  		((uint32_t)(58))
+/** Peripheral clock divider bit position for SYSCON */
+#define	CLKPWR_PCLKSEL_SYSCON  		((uint32_t)(60))
+/** Peripheral clock divider bit position for MC */
+#define	CLKPWR_PCLKSEL_MC		  	((uint32_t)(62))
+
+/** Macro for Peripheral Clock Selection register bit values
+ * Note: When CCLK_DIV_8, Peripheral’s clock is selected to
+ * PCLK_xyz = CCLK/8 except for CAN1, CAN2, and CAN filtering
+ * when ’11’selects PCLK_xyz = CCLK/6 */
+/* Peripheral clock divider is set to 4 from CCLK */
+#define	CLKPWR_PCLKSEL_CCLK_DIV_4  ((uint32_t)(0))
+/** Peripheral clock divider is the same with CCLK */
+#define	CLKPWR_PCLKSEL_CCLK_DIV_1  ((uint32_t)(1))
+/** Peripheral clock divider is set to 2 from CCLK */
+#define	CLKPWR_PCLKSEL_CCLK_DIV_2  ((uint32_t)(2))
+
+
+/********************************************************************
+* Power Control for Peripherals Definitions
+**********************************************************************/
+/** Timer/Counter 0 power/clock control bit */
+#define	 CLKPWR_PCONP_PCTIM0	((uint32_t)(1<<1))
+/* Timer/Counter 1 power/clock control bit */
+#define	 CLKPWR_PCONP_PCTIM1	((uint32_t)(1<<2))
+/** UART0 power/clock control bit */
+#define	 CLKPWR_PCONP_PCUART0  	((uint32_t)(1<<3))
+/** UART1 power/clock control bit */
+#define	 CLKPWR_PCONP_PCUART1  	((uint32_t)(1<<4))
+/** PWM1 power/clock control bit */
+#define	 CLKPWR_PCONP_PCPWM1	((uint32_t)(1<<6))
+/** The I2C0 interface power/clock control bit */
+#define	 CLKPWR_PCONP_PCI2C0	((uint32_t)(1<<7))
+/** The SPI interface power/clock control bit */
+#define	 CLKPWR_PCONP_PCSPI  	((uint32_t)(1<<8))
+/** The RTC power/clock control bit */
+#define	 CLKPWR_PCONP_PCRTC  	((uint32_t)(1<<9))
+/** The SSP1 interface power/clock control bit */
+#define	 CLKPWR_PCONP_PCSSP1	((uint32_t)(1<<10))
+/** A/D converter 0 (ADC0) power/clock control bit */
+#define	 CLKPWR_PCONP_PCAD  	((uint32_t)(1<<12))
+/** CAN Controller 1 power/clock control bit */
+#define	 CLKPWR_PCONP_PCAN1  	((uint32_t)(1<<13))
+/** CAN Controller 2 power/clock control bit */
+#define	 CLKPWR_PCONP_PCAN2  	((uint32_t)(1<<14))
+/** GPIO power/clock control bit */
+#define	CLKPWR_PCONP_PCGPIO		((uint32_t)(1<<15))
+/** Repetitive Interrupt Timer power/clock control bit */
+#define	CLKPWR_PCONP_PCRIT		((uint32_t)(1<<16))
+/** Motor Control PWM */
+#define CLKPWR_PCONP_PCMC		((uint32_t)(1<<17))
+/** Quadrature Encoder Interface power/clock control bit */
+#define CLKPWR_PCONP_PCQEI		((uint32_t)(1<<18))
+/** The I2C1 interface power/clock control bit */
+#define	 CLKPWR_PCONP_PCI2C1  	((uint32_t)(1<<19))
+/** The SSP0 interface power/clock control bit */
+#define	 CLKPWR_PCONP_PCSSP0	((uint32_t)(1<<21))
+/** Timer 2 power/clock control bit */
+#define	 CLKPWR_PCONP_PCTIM2	((uint32_t)(1<<22))
+/** Timer 3 power/clock control bit */
+#define	 CLKPWR_PCONP_PCTIM3	((uint32_t)(1<<23))
+/** UART 2 power/clock control bit */
+#define	 CLKPWR_PCONP_PCUART2  	((uint32_t)(1<<24))
+/** UART 3 power/clock control bit */
+#define	 CLKPWR_PCONP_PCUART3  	((uint32_t)(1<<25))
+/** I2C interface 2 power/clock control bit */
+#define	 CLKPWR_PCONP_PCI2C2	((uint32_t)(1<<26))
+/** I2S interface power/clock control bit*/
+#define	 CLKPWR_PCONP_PCI2S  	((uint32_t)(1<<27))
+/** GP DMA function power/clock control bit*/
+#define	 CLKPWR_PCONP_PCGPDMA  	((uint32_t)(1<<29))
+/** Ethernet block power/clock control bit*/
+#define	 CLKPWR_PCONP_PCENET	((uint32_t)(1<<30))
+/** USB interface power/clock control bit*/
+#define	 CLKPWR_PCONP_PCUSB  	((uint32_t)(1<<31))
+
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup CLKPWR_Public_Functions
+ * @{
+ */
+
+void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal);
+uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType);
+uint32_t CLKPWR_GetPCLK (uint32_t ClkType);
+void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState);
+void CLKPWR_Sleep(void);
+void CLKPWR_DeepSleep(void);
+void CLKPWR_PowerDown(void);
+void CLKPWR_DeepPowerDown(void);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_CLKPWR_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.c
new file mode 100644
index 0000000..34a18d6
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.c
@@ -0,0 +1,989 @@
+/**
+ * @file	: lpc17xx_emac.c
+ * @brief	: Contains all functions support for Ethernet MAC firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 02. Jun. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup EMAC
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_emac.h"
+#include "lpc17xx_clkpwr.h"
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _EMAC
+
+/* Private Variables ---------------------------------------------------------- */
+/** @defgroup EMAC_Private_Variables
+ * @{
+ */
+
+/* MII Mgmt Configuration register - Clock divider setting */
+const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28 };
+
+/* EMAC local DMA Descriptors */
+
+/** Rx Descriptor data array */
+static RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];
+
+/** Rx Status data array - Must be 8-Byte aligned */
+#if defined ( __CC_ARM   )
+static __align(8) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
+#elif defined ( __ICCARM__ )
+#pragma data_alignment=8
+static RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
+#elif defined   (  __GNUC__  )
+static __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
+#endif
+
+/** Tx Descriptor data array */
+static TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
+/** Tx Status data array */
+static TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];
+
+/* EMAC local DMA buffers */
+/** Rx buffer data */
+static uint32_t rx_buf[EMAC_NUM_RX_FRAG][EMAC_ETH_MAX_FLEN>>2];
+/** Tx buffer data */
+static uint32_t tx_buf[EMAC_NUM_TX_FRAG][EMAC_ETH_MAX_FLEN>>2];
+
+/* EMAC call-back function pointer data */
+static EMAC_IntCBSType *_pfnIntCbDat[10];
+
+/**
+ * @}
+ */
+
+
+/* Private Functions ---------------------------------------------------------- */
+/** @defgroup EMAC_Private_Functions
+ * @{
+ */
+
+static void rx_descr_init (void);
+static void tx_descr_init (void);
+static int32_t write_PHY (uint32_t PhyReg, uint16_t Value);
+static int32_t  read_PHY (uint32_t PhyReg);
+
+
+/*--------------------------- rx_descr_init ---------------------------------*/
+
+/**
+ * @brief 		Initializes RX Descriptor
+ * @param[in]	None
+ * @return		None
+ */
+static void rx_descr_init (void)
+{
+	/* Initialize Receive Descriptor and Status array. */
+	uint32_t i;
+
+	for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
+		Rx_Desc[i].Packet  = (uint32_t)&rx_buf[i];
+		Rx_Desc[i].Ctrl    = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
+		Rx_Stat[i].Info    = 0;
+		Rx_Stat[i].HashCRC = 0;
+	}
+
+	/* Set EMAC Receive Descriptor Registers. */
+	LPC_EMAC->RxDescriptor       = (uint32_t)&Rx_Desc[0];
+	LPC_EMAC->RxStatus           = (uint32_t)&Rx_Stat[0];
+	LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;
+
+	/* Rx Descriptors Point to 0 */
+	LPC_EMAC->RxConsumeIndex  = 0;
+}
+
+
+/*--------------------------- tx_descr_init ---- ----------------------------*/
+/**
+ * @brief 		Initializes TX Descriptor
+ * @param[in]	None
+ * @return		None
+ */
+static void tx_descr_init (void) {
+	/* Initialize Transmit Descriptor and Status array. */
+	uint32_t i;
+
+	for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
+		Tx_Desc[i].Packet = (uint32_t)&tx_buf[i];
+		Tx_Desc[i].Ctrl   = 0;
+		Tx_Stat[i].Info   = 0;
+	}
+
+	/* Set EMAC Transmit Descriptor Registers. */
+	LPC_EMAC->TxDescriptor       = (uint32_t)&Tx_Desc[0];
+	LPC_EMAC->TxStatus           = (uint32_t)&Tx_Stat[0];
+	LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;
+
+	/* Tx Descriptors Point to 0 */
+	LPC_EMAC->TxProduceIndex  = 0;
+}
+
+
+/*--------------------------- write_PHY -------------------------------------*/
+/**
+ * @brief 		Write value to PHY device
+ * @param[in]	PhyReg PHY Register address
+ * @param[in]	Value Value to write
+ * @return		(0) if sucess, otherwise return (-1)
+ */
+static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)
+{
+	/* Write a data 'Value' to PHY register 'PhyReg'. */
+	uint32_t tout;
+
+	LPC_EMAC->MADR = EMAC_DP83848C_DEF_ADR | PhyReg;
+	LPC_EMAC->MWTD = Value;
+
+	/* Wait until operation completed */
+	tout = 0;
+	for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) {
+		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
+			return (0);
+		}
+	}
+	// Time out!
+	return (-1);
+}
+
+
+/*--------------------------- read_PHY --------------------------------------*/
+/**
+ * @brief 		Read value from PHY device
+ * @param[in]	PhyReg PHY Register address
+ * @return		Return value if success, otherwise return (-1)
+ */
+static int32_t read_PHY (uint32_t PhyReg)
+{
+	/* Read a PHY register 'PhyReg'. */
+	uint32_t tout;
+
+	LPC_EMAC->MADR = EMAC_DP83848C_DEF_ADR | PhyReg;
+	LPC_EMAC->MCMD = EMAC_MCMD_READ;
+
+	/* Wait until operation completed */
+	tout = 0;
+	for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++) {
+		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
+			LPC_EMAC->MCMD = 0;
+			return (LPC_EMAC->MRDD);
+		}
+	}
+	// Time out!
+	return (-1);
+}
+
+/*********************************************************************//**
+ * @brief		Set Station MAC address for EMAC module
+ * @param[in]	abStationAddr Pointer to Station address that contains 6-bytes
+ * 				of MAC address (should be in order from MAC Address 1 to MAC Address 6)
+ * @return		None
+ **********************************************************************/
+void setEmacAddr(uint8_t abStationAddr[])
+{
+	/* Set the Ethernet MAC Address registers */
+	LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4];
+	LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2];
+	LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0];
+}
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup EMAC_Public_Functions
+ * @{
+ */
+
+
+/*********************************************************************//**
+ * @brief		Initializes the EMAC peripheral according to the specified
+*               parameters in the EMAC_ConfigStruct.
+ * @param[in]	EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure
+*                    that contains the configuration information for the
+*                    specified EMAC peripheral.
+ * @return		None
+ *
+ * Note: This function will initialize EMAC module according to procedure below:
+ *  - Remove the soft reset condition from the MAC
+ *  - Configure the PHY via the MIIM interface of the MAC
+ *  - Select RMII mode
+ *  - Configure the transmit and receive DMA engines, including the descriptor arrays
+ *  - Configure the host registers (MAC1,MAC2 etc.) in the MAC
+ *  - Enable the receive and transmit data paths
+ *  In default state after initializing, only Rx Done and Tx Done interrupt are enabled,
+ *  all remain interrupts are disabled
+ *  (Ref. from LPC17xx UM)
+ **********************************************************************/
+Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
+{
+	/* Initialize the EMAC Ethernet controller. */
+	int32_t regv,tout, tmp;
+
+	/* Set up clock and power for Ethernet module */
+	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);
+
+	/* Reset all EMAC internal modules */
+	LPC_EMAC->MAC1    = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
+					EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;
+
+	LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM;
+
+	/* A short delay after reset. */
+	for (tout = 100; tout; tout--);
+
+	/* Initialize MAC control registers. */
+	LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
+	LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
+	LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
+	/*
+	 * Find the clock that close to desired target clock
+	 */
+	tmp = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
+	for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++){
+		if (EMAC_clkdiv[tout] >= tmp) break;
+	}
+	tout++;
+	// Write to MAC configuration register and reset
+	LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;
+	// release reset
+	LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
+	LPC_EMAC->CLRT = EMAC_CLRT_DEF;
+	LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;
+
+	/* Enable Reduced MII interface. */
+	LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;
+
+	/* Reset Reduced MII Logic. */
+	LPC_EMAC->SUPP = EMAC_SUPP_RES_RMII;
+
+	for (tout = 100; tout; tout--);
+	LPC_EMAC->SUPP = 0;
+
+	/* Put the DP83848C in reset mode */
+	write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);
+
+	/* Wait for hardware reset to end. */
+	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+		regv = read_PHY (EMAC_PHY_REG_BMCR);
+		if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN))) {
+			/* Reset complete, device not Power Down. */
+			break;
+		}
+		if (tout == 0){
+			// Time out, return ERROR
+			return (ERROR);
+		}
+	}
+
+	// Set PHY mode
+	if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0){
+		return (ERROR);
+	}
+
+	// Set EMAC address
+	setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);
+
+	/* Initialize Tx and Rx DMA Descriptors */
+	rx_descr_init ();
+	tx_descr_init ();
+
+	// Set Receive Filter register: enable broadcast and multicast
+	LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
+
+	/* Enable Rx Done and Tx Done interrupt for EMAC */
+	LPC_EMAC->IntEnable = EMAC_INT_RX_DONE | EMAC_INT_TX_DONE;
+
+	/* Reset all interrupts */
+	LPC_EMAC->IntClear  = 0xFFFF;
+
+	/* Enable receive and transmit mode of MAC Ethernet core */
+	LPC_EMAC->Command  |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
+	LPC_EMAC->MAC1     |= EMAC_MAC1_REC_EN;
+
+	return SUCCESS;
+}
+
+
+/*********************************************************************//**
+ * @brief		De-initializes the EMAC peripheral registers to their
+*                  default reset values.
+ * @param[in]	None
+ * @return 		None
+ **********************************************************************/
+void EMAC_DeInit(void)
+{
+	// Disable all interrupt
+	LPC_EMAC->IntEnable = 0x00;
+	// Clear all pending interrupt
+	LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP);
+
+	/* TurnOff clock and power for Ethernet module */
+	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
+}
+
+
+/*********************************************************************//**
+ * @brief		Check specified PHY status in EMAC peripheral
+ * @param[in]	ulPHYState	Specified PHY Status Type, should be:
+ * 							- EMAC_PHY_STAT_LINK: Link Status
+ * 							- EMAC_PHY_STAT_SPEED: Speed Status
+ * 							- EMAC_PHY_STAT_DUP: Duplex Status
+ * @return		Status of specified PHY status (0 or 1).
+ * 				(-1) if error.
+ *
+ * Note:
+ * For EMAC_PHY_STAT_LINK, return value:
+ * - 0: Link Down
+ * - 1: Link Up
+ * For EMAC_PHY_STAT_SPEED, return value:
+ * - 0: 10Mbps
+ * - 1: 100Mbps
+ * For EMAC_PHY_STAT_DUP, return value:
+ * - 0: Half-Duplex
+ * - 1: Full-Duplex
+ **********************************************************************/
+int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState)
+{
+	int32_t regv, tmp;
+
+	regv = read_PHY (EMAC_PHY_REG_STS);
+	switch(ulPHYState){
+	case EMAC_PHY_STAT_LINK:
+		tmp = (regv & EMAC_PHY_SR_LINK) ? 1 : 0;
+		break;
+	case EMAC_PHY_STAT_SPEED:
+		tmp = (regv & EMAC_PHY_SR_SPEED) ? 0 : 1;
+		break;
+	case EMAC_PHY_STAT_DUP:
+		tmp = (regv & EMAC_PHY_SR_DUP) ? 1 : 0;
+		break;
+	default:
+		tmp = -1;
+		break;
+	}
+	return (tmp);
+}
+
+
+/*********************************************************************//**
+ * @brief		Set specified PHY mode in EMAC peripheral
+ * @param[in]	ulPHYMode	Specified PHY mode, should be:
+ * 							- EMAC_MODE_AUTO
+ * 							- EMAC_MODE_10M_FULL
+ * 							- EMAC_MODE_10M_HALF
+ * 							- EMAC_MODE_100M_FULL
+ * 							- EMAC_MODE_100M_HALF
+ * @return		Return (0) if no error, otherwise return (-1)
+ **********************************************************************/
+int32_t EMAC_SetPHYMode(uint32_t ulPHYMode)
+{
+	int32_t id1, id2, tout, regv;
+
+	/* Check if this is a DP83848C PHY. */
+	id1 = read_PHY (EMAC_PHY_REG_IDR1);
+	id2 = read_PHY (EMAC_PHY_REG_IDR2);
+
+	if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_DP83848C_ID) {
+		/* Configure the PHY device */
+		switch(ulPHYMode){
+		case EMAC_MODE_AUTO:
+			/* Use auto-negotiation about the link speed. */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
+			/* Wait to complete Auto_Negotiation */
+			for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+				regv = read_PHY (EMAC_PHY_REG_BMSR);
+				if (regv & EMAC_PHY_BMSR_AUTO_DONE) {
+					/* Auto-negotiation Complete. */
+					break;
+				}
+				if (tout == 0){
+					// Time out, return error
+					return (-1);
+				}
+			}
+			break;
+		case EMAC_MODE_10M_FULL:
+			/* Connect at 10MBit full-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
+			break;
+		case EMAC_MODE_10M_HALF:
+			/* Connect at 10MBit half-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
+			break;
+		case EMAC_MODE_100M_FULL:
+			/* Connect at 100MBit full-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
+			break;
+		case EMAC_MODE_100M_HALF:
+			/* Connect at 100MBit half-duplex */
+			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
+			break;
+		default:
+			// un-supported
+			return (-1);
+		}
+	}
+	// It's not correct module ID
+	else {
+		return (-1);
+	}
+
+	// Update EMAC configuration with current PHY status
+	if (EMAC_UpdatePHYStatus() < 0){
+		return (-1);
+	}
+
+	// Complete
+	return (0);
+}
+
+
+/*********************************************************************//**
+ * @brief		Auto-Configures value for the EMAC configuration register to
+ * 				match with current PHY mode
+ * @param[in]	None
+ * @return		Return (0) if no error, otherwise return (-1)
+ *
+ * Note: The EMAC configuration will be auto-configured:
+ * 		- Speed mode.
+ * 		- Half/Full duplex mode
+ **********************************************************************/
+int32_t EMAC_UpdatePHYStatus(void)
+{
+	int32_t regv, tout;
+
+	/* Check the link status. */
+	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
+		regv = read_PHY (EMAC_PHY_REG_STS);
+		if (regv & EMAC_PHY_SR_LINK) {
+			/* Link is on. */
+			break;
+		}
+		if (tout == 0){
+			// time out
+			return (-1);
+		}
+	}
+
+	/* Configure Full/Half Duplex mode. */
+	if (regv & EMAC_PHY_SR_DUP) {
+		/* Full duplex is enabled. */
+		LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
+		LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
+		LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
+	} else {
+		/* Half duplex mode. */
+		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
+	}
+
+	/* Configure 100MBit/10MBit mode. */
+	if (regv & EMAC_PHY_SR_SPEED) {
+		/* 10MBit mode. */
+		LPC_EMAC->SUPP = 0;
+	} else {
+		/* 100MBit mode. */
+		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
+	}
+
+	// Complete
+	return (0);
+}
+
+
+/*********************************************************************//**
+ * @brief		Enable/Disable hash filter functionality for specified destination
+ * 				MAC address in EMAC module
+ * @param[in]	dstMAC_addr		Pointer to the first MAC destination address, should
+ * 								be 6-bytes length, in order LSB to the MSB
+ * @param[in]	NewState		New State of this command, should be:
+ *									- ENABLE.
+ *									- DISABLE.
+ * @return		None
+ *
+ * Note:
+ * The standard Ethernet cyclic redundancy check (CRC) function is calculated from
+ * the 6 byte destination address in the Ethernet frame (this CRC is calculated
+ * anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of
+ * the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access
+ * the hash table: it is used as an index in the 64 bit HashFilter register that has been
+ * programmed with accept values. If the selected accept value is 1, the frame is
+ * accepted.
+ **********************************************************************/
+void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
+{
+	uint32_t *pReg;
+	uint32_t tmp;
+	int32_t crc;
+
+	// Calculate the CRC from the destination MAC address
+	crc = EMAC_CRCCalc(dstMAC_addr, 6);
+	// Extract the value from CRC to get index value for hash filter table
+	crc = (crc >> 23) & 0x3F;
+
+	pReg = (crc > 31) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \
+								: ((uint32_t *)&LPC_EMAC->HashFilterL);
+	tmp = (crc > 31) ? (crc - 32) : crc;
+	if (NewState == ENABLE) {
+		(*pReg) |= (1UL << tmp);
+	} else {
+		(*pReg) &= ~(1UL << tmp);
+	}
+	// Enable Rx Filter
+	LPC_EMAC->Command &= ~EMAC_CR_PASS_RX_FILT;
+}
+
+
+/*********************************************************************//**
+ * @brief		Calculates CRC code for number of bytes in the frame
+ * @param[in]	frame_no_fcs	Pointer to the first byte of the frame
+ * @param[in]	frame_len		length of the frame without the FCS
+ * @return		the CRC as a 32 bit integer
+ **********************************************************************/
+int32_t EMAC_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len)
+{
+	int i; 		// iterator
+	int j; 		// another iterator
+	char byte; 	// current byte
+	int crc; 	// CRC result
+	int q0, q1, q2, q3; // temporary variables
+	crc = 0xFFFFFFFF;
+	for (i = 0; i < frame_len; i++) {
+		byte = *frame_no_fcs++;
+		for (j = 0; j < 2; j++) {
+			if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) {
+				q3 = 0x04C11DB7;
+			} else {
+				q3 = 0x00000000;
+			}
+			if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) {
+				q2 = 0x09823B6E;
+			} else {
+				q2 = 0x00000000;
+			}
+			if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) {
+				q1 = 0x130476DC;
+			} else {
+				q1 = 0x00000000;
+			}
+			if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) {
+				q0 = 0x2608EDB8;
+			} else {
+				q0 = 0x00000000;
+			}
+			crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
+			byte >>= 4;
+		}
+	}
+	return crc;
+}
+
+/*********************************************************************//**
+ * @brief		Enable/Disable Filter mode for each specified type EMAC peripheral
+ * @param[in]	ulFilterMode	Filter mode, should be:
+ * 								- EMAC_RFC_UCAST_EN: all frames of unicast types
+ * 								will be accepted
+ * 								- EMAC_RFC_BCAST_EN: broadcast frame will be
+ * 								accepted
+ * 								- EMAC_RFC_MCAST_EN: all frames of multicast
+ * 								types will be accepted
+ * 								- EMAC_RFC_UCAST_HASH_EN: The imperfect hash
+ * 								filter will be applied to unicast addresses
+ * 								- EMAC_RFC_MCAST_HASH_EN: The imperfect hash
+ * 								filter will be applied to multicast addresses
+ * 								- EMAC_RFC_PERFECT_EN: the destination address
+ * 								will be compared with the 6 byte station address
+ * 								programmed in the station address by the filter
+ * 								- EMAC_RFC_MAGP_WOL_EN: the result of the magic
+ * 								packet filter will generate a WoL interrupt when
+ * 								there is a match
+ * 								- EMAC_RFC_PFILT_WOL_EN: the result of the perfect address
+ * 								matching filter and the imperfect hash filter will
+ * 								generate a WoL interrupt when there is a match
+ * @param[in]	NewState	New State of this command, should be:
+ * 								- ENABLE
+ * 								- DISABLE
+ * @return		None
+ **********************************************************************/
+void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState)
+{
+	if (NewState == ENABLE){
+		LPC_EMAC->RxFilterCtrl |= ulFilterMode;
+	} else {
+		LPC_EMAC->RxFilterCtrl &= ~ulFilterMode;
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Get status of Wake On LAN Filter for each specified
+ * 				type in EMAC peripheral, clear this status if it is set
+ * @param[in]	ulWoLMode	WoL Filter mode, should be:
+ * 								- EMAC_WOL_UCAST: unicast frames caused WoL
+ * 								- EMAC_WOL_UCAST: broadcast frame caused WoL
+ * 								- EMAC_WOL_MCAST: multicast frame caused WoL
+ * 								- EMAC_WOL_UCAST_HASH: unicast frame that passes the
+ * 								imperfect hash filter caused WoL
+ * 								- EMAC_WOL_MCAST_HASH: multicast frame that passes the
+ * 								imperfect hash filter caused WoL
+ * 								- EMAC_WOL_PERFECT:perfect address matching filter
+ * 								caused WoL
+ * 								- EMAC_WOL_RX_FILTER: the receive filter caused WoL
+ * 								- EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL
+ * @return		SET/RESET
+ **********************************************************************/
+FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode)
+{
+	if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) {
+		LPC_EMAC->RxFilterWoLClear = ulWoLMode;
+		return SET;
+	} else {
+		return RESET;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Write data to Tx packet data buffer at current index due to
+ * 				TxProduceIndex
+ * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
+ * 							data that contain specified information about
+ * 							Packet data buffer.
+ * @return		None
+ **********************************************************************/
+void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
+{
+	uint32_t idx,len;
+	uint32_t *sp,*dp;
+
+	idx = LPC_EMAC->TxProduceIndex;
+	sp  = (uint32_t *)pDataStruct->pbDataBuf;
+	dp  = (uint32_t *)Tx_Desc[idx].Packet;
+	/* Copy frame data to EMAC packet buffers. */
+	for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
+		*dp++ = *sp++;
+	}
+	Tx_Desc[idx].Ctrl = (pDataStruct->ulDataLen - 1) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);
+}
+
+/*********************************************************************//**
+ * @brief		Read data from Rx packet data buffer at current index due
+ * 				to RxConsumeIndex
+ * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
+ * 							data that contain specified information about
+ * 							Packet data buffer.
+ * @return		None
+ **********************************************************************/
+void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
+{
+	uint32_t idx, len;
+	uint32_t *dp, *sp;
+
+	idx = LPC_EMAC->RxConsumeIndex;
+	dp = (uint32_t *)pDataStruct->pbDataBuf;
+	sp = (uint32_t *)Rx_Desc[idx].Packet;
+
+	if (pDataStruct->pbDataBuf != NULL) {
+		for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
+			*dp++ = *sp++;
+		}
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Standard EMAC IRQ Handler. This sub-routine will check
+ * 				these following interrupt and call the call-back function
+ * 				if they're already installed:
+ * 				- Overrun Error interrupt in RX Queue
+ * 				- Receive Error interrupt: AlignmentError, RangeError,
+ * 				LengthError, SymbolError, CRCError or NoDescriptor or Overrun
+ * 				- RX Finished Process Descriptors interrupt (ProduceIndex == ConsumeIndex)
+ * 				- Receive Done interrupt
+ * 				- Transmit Under-run interrupt
+ * 				- Transmit errors interrupt : LateCollision, ExcessiveCollision
+ * 				and ExcessiveDefer, NoDescriptor or Under-run
+ * 				- TX Finished Process Descriptors interrupt (ProduceIndex == ConsumeIndex)
+ * 				- Transmit Done interrupt
+ * 				- Interrupt triggered by software
+ *				- Interrupt triggered by a Wakeup event detected by the receive filter
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void EMAC_StandardIRQHandler(void)
+{
+	/* EMAC Ethernet Controller Interrupt function. */
+	uint32_t n, int_stat;
+
+	// Get EMAC interrupt status
+	while ((int_stat = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable)) != 0) {
+		// Clear interrupt status
+		LPC_EMAC->IntClear = int_stat;
+		// Execute call-back function
+		for (n = 0; n <= 7; n++) {
+			if ((int_stat & (1 << n)) && (_pfnIntCbDat[n] != NULL)) {
+				_pfnIntCbDat[n]();
+			}
+		}
+		// Soft interrupt
+		if ((int_stat & EMAC_INT_SOFT_INT) && (_pfnIntCbDat[8] != NULL)) {
+			_pfnIntCbDat[8]();
+		}
+		// WakeUp interrupt
+		if ((int_stat & EMAC_INT_WAKEUP) && (_pfnIntCbDat[9] != NULL)) {
+			// Clear WoL interrupt
+			LPC_EMAC->RxFilterWoLClear = EMAC_WOL_BITMASK;
+			_pfnIntCbDat[9]();
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Setup/register Call-back function for each interrupt type
+ * 				in EMAC module.
+ * @param[in]	ulIntType	Interrupt type, should be one of the following:
+ * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
+ * 							- EMAC_INT_RX_ERR: Receive Error
+ * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
+ * 							- EMAC_INT_RX_DONE: Receive Done
+ * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
+ * 							- EMAC_INT_TX_ERR: Transmit Error
+ * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
+ * 							- EMAC_INT_TX_DONE: Transmit Done
+ * 							- EMAC_INT_SOFT_INT: Software interrupt
+ * 							- EMAC_INT_WAKEUP: Wakeup interrupt
+ * @param[in]	pfnIntCb	Pointer to Call-back function used for this
+ * 							interrupt type
+ * @return		None
+ **********************************************************************/
+void EMAC_SetupIntCBS(uint32_t ulIntType, EMAC_IntCBSType *pfnIntCb)
+{
+	/* EMAC Ethernet Controller Interrupt function. */
+	uint32_t n;
+
+	if (ulIntType <= EMAC_INT_TX_DONE){
+		for (n = 0; n <= 7; n++) {
+			// Found it, install cbs now
+			if (ulIntType & (1 << n)) {
+				_pfnIntCbDat[n] = pfnIntCb;
+				// Don't install cbs any more
+				break;
+			}
+		}
+	} else if (ulIntType & EMAC_INT_SOFT_INT) {
+		_pfnIntCbDat[8] = pfnIntCb;
+	} else if (ulIntType & EMAC_INT_WAKEUP) {
+		_pfnIntCbDat[9] = pfnIntCb;
+	}
+}
+
+/*********************************************************************//**
+ * @brief 		Enable/Disable interrupt for each type in EMAC
+ * @param[in]	ulIntType	Interrupt Type, should be:
+ * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
+ * 							- EMAC_INT_RX_ERR: Receive Error
+ * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
+ * 							- EMAC_INT_RX_DONE: Receive Done
+ * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
+ * 							- EMAC_INT_TX_ERR: Transmit Error
+ * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
+ * 							- EMAC_INT_TX_DONE: Transmit Done
+ * 							- EMAC_INT_SOFT_INT: Software interrupt
+ * 							- EMAC_INT_WAKEUP: Wakeup interrupt
+ * @param[in]	NewState	New State of this function, should be:
+ * 							- ENABLE.
+ * 							- DISABLE.
+ * @return		None
+ **********************************************************************/
+void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState)
+{
+	if (NewState == ENABLE) {
+		LPC_EMAC->IntEnable |= ulIntType;
+	} else {
+		LPC_EMAC->IntEnable &= ~(ulIntType);
+	}
+}
+
+/*********************************************************************//**
+ * @brief 		Check whether if specified interrupt flag is set or not
+ * 				for each interrupt type in EMAC and clear interrupt pending
+ * 				if it is set.
+ * @param[in]	ulIntType	Interrupt Type, should be:
+ * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
+ * 							- EMAC_INT_RX_ERR: Receive Error
+ * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
+ * 							- EMAC_INT_RX_DONE: Receive Done
+ * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
+ * 							- EMAC_INT_TX_ERR: Transmit Error
+ * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
+ * 							- EMAC_INT_TX_DONE: Transmit Done
+ * 							- EMAC_INT_SOFT_INT: Software interrupt
+ * 							- EMAC_INT_WAKEUP: Wakeup interrupt
+ * @return		New state of specified interrupt (SET or RESET)
+ **********************************************************************/
+IntStatus EMAC_IntGetStatus(uint32_t ulIntType)
+{
+	if (LPC_EMAC->IntStatus & ulIntType) {
+		LPC_EMAC->IntClear = ulIntType;
+		return SET;
+	} else {
+		return RESET;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Check whether if the current RxConsumeIndex is not equal to the
+ * 				current RxProduceIndex.
+ * @param[in]	None
+ * @return		TRUE if they're not equal, otherwise return FALSE
+ *
+ * Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,
+ * it means there're available data has been received. They should be read
+ * out and released the Receive Data Buffer by updating the RxConsumeIndex value.
+ **********************************************************************/
+Bool EMAC_CheckReceiveIndex(void)
+{
+	if (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) {
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Check whether if the current TxProduceIndex is not equal to the
+ * 				current RxProduceIndex - 1.
+ * @param[in]	None
+ * @return		TRUE if they're not equal, otherwise return FALSE
+ *
+ * Note: In case the RxConsumeIndex is equal to the RxProduceIndex - 1,
+ * it means the transmit buffer is available and data can be written to transmit
+ * buffer to be sent.
+ **********************************************************************/
+Bool EMAC_CheckTransmitIndex(void)
+{
+	uint32_t tmp = LPC_EMAC->TxConsumeIndex -1;
+	if (LPC_EMAC->TxProduceIndex == tmp) {
+		return FALSE;
+	} else {
+		return TRUE;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Get current status value of receive data (due to RxConsumeIndex)
+ * @param[in]	ulRxStatType	Received Status type, should be one of following:
+ * 							- EMAC_RINFO_CTRL_FRAME: Control Frame
+ * 							- EMAC_RINFO_VLAN: VLAN Frame
+ * 							- EMAC_RINFO_FAIL_FILT: RX Filter Failed
+ * 							- EMAC_RINFO_MCAST: Multicast Frame
+ * 							- EMAC_RINFO_BCAST: Broadcast Frame
+ * 							- EMAC_RINFO_CRC_ERR: CRC Error in Frame
+ * 							- EMAC_RINFO_SYM_ERR: Symbol Error from PHY
+ * 							- EMAC_RINFO_LEN_ERR: Length Error
+ * 							- EMAC_RINFO_RANGE_ERR: Range error(exceeded max size)
+ * 							- EMAC_RINFO_ALIGN_ERR: Alignment error
+ * 							- EMAC_RINFO_OVERRUN: Receive overrun
+ * 							- EMAC_RINFO_NO_DESCR: No new Descriptor available
+ * 							- EMAC_RINFO_LAST_FLAG: last Fragment in Frame
+ * 							- EMAC_RINFO_ERR: Error Occurred (OR of all error)
+ * @return		Current value of receive data (due to RxConsumeIndex)
+ **********************************************************************/
+FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType)
+{
+	uint32_t idx;
+	idx = LPC_EMAC->RxConsumeIndex;
+	return (((Rx_Stat[idx].Info) & ulRxStatType) ? SET : RESET);
+}
+
+
+/*********************************************************************//**
+ * @brief		Get size of current Received data in received buffer (due to
+ * 				RxConsumeIndex)
+ * @param[in]	None
+ * @return		Size of received data
+ **********************************************************************/
+uint32_t EMAC_GetReceiveDataSize(void)
+{
+	uint32_t idx;
+	idx =LPC_EMAC->RxConsumeIndex;
+	return ((Rx_Stat[idx].Info) & EMAC_RINFO_SIZE);
+}
+
+/*********************************************************************//**
+ * @brief		Increase the RxConsumeIndex (after reading the Receive buffer
+ * 				to release the Receive buffer) and wrap-around the index if
+ * 				it reaches the maximum Receive Number
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void EMAC_UpdateRxConsumeIndex(void)
+{
+	// Get current Rx consume index
+	uint32_t idx = LPC_EMAC->RxConsumeIndex;
+
+	/* Release frame from EMAC buffer */
+	if (++idx == EMAC_NUM_RX_FRAG) idx = 0;
+	LPC_EMAC->RxConsumeIndex = idx;
+}
+
+/*********************************************************************//**
+ * @brief		Increase the TxProduceIndex (after writting to the Transmit buffer
+ * 				to enable the Transmit buffer) and wrap-around the index if
+ * 				it reaches the maximum Transmit Number
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void EMAC_UpdateTxProduceIndex(void)
+{
+	// Get current Tx produce index
+	uint32_t idx = LPC_EMAC->TxProduceIndex;
+
+	/* Start frame transmission */
+	if (++idx == EMAC_NUM_TX_FRAG) idx = 0;
+	LPC_EMAC->TxProduceIndex = idx;
+}
+
+
+/**
+ * @}
+ */
+
+#endif /* _EMAC */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.h
new file mode 100644
index 0000000..c31fa56
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_emac.h
@@ -0,0 +1,582 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_emac.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for Ethernet MAC firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 02. Jun. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup EMAC
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_EMAC_H_
+#define LPC17XX_EMAC_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup EMAC_Private_Macros
+ * @{
+ */
+
+
+/** @defgroup EMAC_REGISTER_BIT_DEFINITIONS
+ * @{
+ */
+
+
+/* EMAC Memory Buffer configuration for 16K Ethernet RAM */
+#define EMAC_NUM_RX_FRAG         4           /**< Num.of RX Fragments 4*1536= 6.0kB */
+#define EMAC_NUM_TX_FRAG         3           /**< Num.of TX Fragments 3*1536= 4.6kB */
+#define EMAC_ETH_MAX_FLEN        1536        /**< Max. Ethernet Frame Size          */
+#define EMAC_TX_FRAME_TOUT       0x00100000  /**< Frame Transmit timeout count      */
+
+/* Ethernet MAC register definitions --------------------------------------------------------------------- */
+/* MAC Configuration Register 1 */
+#define EMAC_MAC1_REC_EN         0x00000001  /**< Receive Enable                    */
+#define EMAC_MAC1_PASS_ALL       0x00000002  /**< Pass All Receive Frames           */
+#define EMAC_MAC1_RX_FLOWC       0x00000004  /**< RX Flow Control                   */
+#define EMAC_MAC1_TX_FLOWC       0x00000008  /**< TX Flow Control                   */
+#define EMAC_MAC1_LOOPB          0x00000010  /**< Loop Back Mode                    */
+#define EMAC_MAC1_RES_TX         0x00000100  /**< Reset TX Logic                    */
+#define EMAC_MAC1_RES_MCS_TX     0x00000200  /**< Reset MAC TX Control Sublayer     */
+#define EMAC_MAC1_RES_RX         0x00000400  /**< Reset RX Logic                    */
+#define EMAC_MAC1_RES_MCS_RX     0x00000800  /**< Reset MAC RX Control Sublayer     */
+#define EMAC_MAC1_SIM_RES        0x00004000  /**< Simulation Reset                  */
+#define EMAC_MAC1_SOFT_RES       0x00008000  /**< Soft Reset MAC                    */
+
+/* MAC Configuration Register 2 */
+#define EMAC_MAC2_FULL_DUP       0x00000001  /**< Full-Duplex Mode                  */
+#define EMAC_MAC2_FRM_LEN_CHK    0x00000002  /**< Frame Length Checking             */
+#define EMAC_MAC2_HUGE_FRM_EN    0x00000004  /**< Huge Frame Enable                 */
+#define EMAC_MAC2_DLY_CRC        0x00000008  /**< Delayed CRC Mode                  */
+#define EMAC_MAC2_CRC_EN         0x00000010  /**< Append CRC to every Frame         */
+#define EMAC_MAC2_PAD_EN         0x00000020  /**< Pad all Short Frames              */
+#define EMAC_MAC2_VLAN_PAD_EN    0x00000040  /**< VLAN Pad Enable                   */
+#define EMAC_MAC2_ADET_PAD_EN    0x00000080  /**< Auto Detect Pad Enable            */
+#define EMAC_MAC2_PPREAM_ENF     0x00000100  /**< Pure Preamble Enforcement         */
+#define EMAC_MAC2_LPREAM_ENF     0x00000200  /**< Long Preamble Enforcement         */
+#define EMAC_MAC2_NO_BACKOFF     0x00001000  /**< No Backoff Algorithm              */
+#define EMAC_MAC2_BACK_PRESSURE  0x00002000  /**< Backoff Presurre / No Backoff     */
+#define EMAC_MAC2_EXCESS_DEF     0x00004000  /**< Excess Defer                      */
+
+/* Back-to-Back Inter-Packet-Gap Register */
+/** Programmable field representing the nibble time offset of the minimum possible period
+ * between the end of any transmitted packet to the beginning of the next */
+#define EMAC_IPGT_BBIPG(n)		(n&0x7F)
+/** Recommended value for Full Duplex of Programmable field representing the nibble time
+ * offset of the minimum possible period between the end of any transmitted packet to the
+ * beginning of the next */
+#define EMAC_IPGT_FULL_DUP		(EMAC_IPGT_BBIPG(0x15))
+/** Recommended value for Half Duplex of Programmable field representing the nibble time
+ * offset of the minimum possible period between the end of any transmitted packet to the
+ * beginning of the next */
+#define EMAC_IPGT_HALF_DUP      (EMAC_IPGT_BBIPG(0x12))
+
+/* Non Back-to-Back Inter-Packet-Gap Register */
+/** Programmable field representing the Non-Back-to-Back Inter-Packet-Gap */
+#define EMAC_IPGR_NBBIPG_P2(n)	(n&0x7F)
+/** Recommended value for Programmable field representing the Non-Back-to-Back Inter-Packet-Gap Part 1 */
+#define EMAC_IPGR_P2_DEF		(EMAC_IPGR_NBBIPG_P2(0x12))
+/** Programmable field representing the optional carrierSense window referenced in
+ * IEEE 802.3/4.2.3.2.1 'Carrier Deference' */
+#define EMAC_IPGR_NBBIPG_P1(n)	((n&0x7F)<<8)
+/** Recommended value for Programmable field representing the Non-Back-to-Back Inter-Packet-Gap Part 2 */
+#define EMAC_IPGR_P1_DEF        EMAC_IPGR_NBBIPG_P1(0x0C)
+
+/* Collision Window/Retry Register */
+/** Programmable field specifying the number of retransmission attempts following a collision before
+ * aborting the packet due to excessive collisions */
+#define EMAC_CLRT_MAX_RETX(n)	(n&0x0F)
+/** Programmable field representing the slot time or collision window during which collisions occur
+ * in properly configured networks */
+#define EMAC_CLRT_COLL(n)		((n&0x3F)<<8)
+/** Default value for Collision Window / Retry register */
+#define EMAC_CLRT_DEF           ((EMAC_CLRT_MAX_RETX(0x0F))|(EMAC_CLRT_COLL(0x37)))
+
+/* Maximum Frame Register */
+/** Represents a maximum receive frame of 1536 octets */
+#define EMAC_MAXF_MAXFRMLEN(n)	(n&0xFFFF)
+
+/* PHY Support Register */
+#define EMAC_SUPP_SPEED			0x00000100  	/**< Reduced MII Logic Current Speed   */
+#define EMAC_SUPP_RES_RMII      0x00000800  	/**< Reset Reduced MII Logic           */
+
+/* Test Register */
+#define EMAC_TEST_SHCUT_PQUANTA  0x00000001  	/**< Shortcut Pause Quanta             */
+#define EMAC_TEST_TST_PAUSE      0x00000002  	/**< Test Pause                        */
+#define EMAC_TEST_TST_BACKP      0x00000004  	/**< Test Back Pressure                */
+
+/* MII Management Configuration Register */
+#define EMAC_MCFG_SCAN_INC       0x00000001  	/**< Scan Increment PHY Address        */
+#define EMAC_MCFG_SUPP_PREAM     0x00000002  	/**< Suppress Preamble                 */
+#define EMAC_MCFG_CLK_SEL(n)     ((n&0x0F)<<2)  /**< Clock Select Field                 */
+#define EMAC_MCFG_RES_MII        0x00008000  	/**< Reset MII Management Hardware     */
+#define EMAC_MCFG_MII_MAXCLK	 2500000UL		/**< MII Clock max */
+
+/* MII Management Command Register */
+#define EMAC_MCMD_READ           0x00000001  	/**< MII Read                          */
+#define EMAC_MCMD_SCAN           0x00000002  	/**< MII Scan continuously             */
+
+#define EMAC_MII_WR_TOUT         0x00050000  	/**< MII Write timeout count           */
+#define EMAC_MII_RD_TOUT         0x00050000  	/**< MII Read timeout count            */
+
+/* MII Management Address Register */
+#define EMAC_MADR_REG_ADR(n)     (n&0x1F)  		/**< MII Register Address field         */
+#define EMAC_MADR_PHY_ADR(n)     ((n&0x1F)<<8)  /**< PHY Address Field                  */
+
+/* MII Management Write Data Register */
+#define EMAC_MWTD_DATA(n)		(n&0xFFFF)		/**< Data field for MMI Management Write Data register */
+
+/* MII Management Read Data Register */
+#define EMAC_MRDD_DATA(n)		(n&0xFFFF)		/**< Data field for MMI Management Read Data register */
+
+/* MII Management Indicators Register */
+#define EMAC_MIND_BUSY           0x00000001  	/**< MII is Busy                       */
+#define EMAC_MIND_SCAN           0x00000002  	/**< MII Scanning in Progress          */
+#define EMAC_MIND_NOT_VAL        0x00000004  	/**< MII Read Data not valid           */
+#define EMAC_MIND_MII_LINK_FAIL  0x00000008  	/**< MII Link Failed                   */
+
+/* Station Address 0 Register */
+/* Station Address 1 Register */
+/* Station Address 2 Register */
+
+
+/* Control register definitions --------------------------------------------------------------------------- */
+/* Command Register */
+#define EMAC_CR_RX_EN            0x00000001  	/**< Enable Receive                    */
+#define EMAC_CR_TX_EN            0x00000002  	/**< Enable Transmit                   */
+#define EMAC_CR_REG_RES          0x00000008  	/**< Reset Host Registers              */
+#define EMAC_CR_TX_RES           0x00000010  	/**< Reset Transmit Datapath           */
+#define EMAC_CR_RX_RES           0x00000020  	/**< Reset Receive Datapath            */
+#define EMAC_CR_PASS_RUNT_FRM    0x00000040  	/**< Pass Runt Frames                  */
+#define EMAC_CR_PASS_RX_FILT     0x00000080  	/**< Pass RX Filter                    */
+#define EMAC_CR_TX_FLOW_CTRL     0x00000100  	/**< TX Flow Control                   */
+#define EMAC_CR_RMII             0x00000200  	/**< Reduced MII Interface             */
+#define EMAC_CR_FULL_DUP         0x00000400  	/**< Full Duplex                       */
+
+/* Status Register */
+#define EMAC_SR_RX_EN            0x00000001  	/**< Enable Receive                    */
+#define EMAC_SR_TX_EN            0x00000002  	/**< Enable Transmit                   */
+
+/* Receive Descriptor Base Address Register */
+//
+
+/* Receive Status Base Address Register */
+//
+
+/* Receive Number of Descriptors Register */
+//
+
+/* Receive Produce Index Register */
+//
+
+/* Receive Consume Index Register */
+//
+
+/* Transmit Descriptor Base Address Register */
+//
+
+/* Transmit Status Base Address Register */
+//
+
+/* Transmit Number of Descriptors Register */
+//
+
+/* Transmit Produce Index Register */
+//
+
+/* Transmit Consume Index Register */
+//
+
+/* Transmit Status Vector 0 Register */
+#define EMAC_TSV0_CRC_ERR        0x00000001  /**< CRC error                         */
+#define EMAC_TSV0_LEN_CHKERR     0x00000002  /**< Length Check Error                */
+#define EMAC_TSV0_LEN_OUTRNG     0x00000004  /**< Length Out of Range               */
+#define EMAC_TSV0_DONE           0x00000008  /**< Tramsmission Completed            */
+#define EMAC_TSV0_MCAST          0x00000010  /**< Multicast Destination             */
+#define EMAC_TSV0_BCAST          0x00000020  /**< Broadcast Destination             */
+#define EMAC_TSV0_PKT_DEFER      0x00000040  /**< Packet Deferred                   */
+#define EMAC_TSV0_EXC_DEFER      0x00000080  /**< Excessive Packet Deferral         */
+#define EMAC_TSV0_EXC_COLL       0x00000100  /**< Excessive Collision               */
+#define EMAC_TSV0_LATE_COLL      0x00000200  /**< Late Collision Occured            */
+#define EMAC_TSV0_GIANT          0x00000400  /**< Giant Frame                       */
+#define EMAC_TSV0_UNDERRUN       0x00000800  /**< Buffer Underrun                   */
+#define EMAC_TSV0_BYTES          0x0FFFF000  /**< Total Bytes Transferred           */
+#define EMAC_TSV0_CTRL_FRAME     0x10000000  /**< Control Frame                     */
+#define EMAC_TSV0_PAUSE          0x20000000  /**< Pause Frame                       */
+#define EMAC_TSV0_BACK_PRESS     0x40000000  /**< Backpressure Method Applied       */
+#define EMAC_TSV0_VLAN           0x80000000  /**< VLAN Frame                        */
+
+/* Transmit Status Vector 1 Register */
+#define EMAC_TSV1_BYTE_CNT       0x0000FFFF  /**< Transmit Byte Count               */
+#define EMAC_TSV1_COLL_CNT       0x000F0000  /**< Transmit Collision Count          */
+
+/* Receive Status Vector Register */
+#define EMAC_RSV_BYTE_CNT        0x0000FFFF  /**< Receive Byte Count                */
+#define EMAC_RSV_PKT_IGNORED     0x00010000  /**< Packet Previously Ignored         */
+#define EMAC_RSV_RXDV_SEEN       0x00020000  /**< RXDV Event Previously Seen        */
+#define EMAC_RSV_CARR_SEEN       0x00040000  /**< Carrier Event Previously Seen     */
+#define EMAC_RSV_REC_CODEV       0x00080000  /**< Receive Code Violation            */
+#define EMAC_RSV_CRC_ERR         0x00100000  /**< CRC Error                         */
+#define EMAC_RSV_LEN_CHKERR      0x00200000  /**< Length Check Error                */
+#define EMAC_RSV_LEN_OUTRNG      0x00400000  /**< Length Out of Range               */
+#define EMAC_RSV_REC_OK          0x00800000  /**< Frame Received OK                 */
+#define EMAC_RSV_MCAST           0x01000000  /**< Multicast Frame                   */
+#define EMAC_RSV_BCAST           0x02000000  /**< Broadcast Frame                   */
+#define EMAC_RSV_DRIB_NIBB       0x04000000  /**< Dribble Nibble                    */
+#define EMAC_RSV_CTRL_FRAME      0x08000000  /**< Control Frame                     */
+#define EMAC_RSV_PAUSE           0x10000000  /**< Pause Frame                       */
+#define EMAC_RSV_UNSUPP_OPC      0x20000000  /**< Unsupported Opcode                */
+#define EMAC_RSV_VLAN            0x40000000  /**< VLAN Frame                        */
+
+/* Flow Control Counter Register */
+#define EMAC_FCC_MIRR_CNT(n)        	(n&0xFFFF)  		/**< Mirror Counter                    */
+#define EMAC_FCC_PAUSE_TIM(n)       	((n&0xFFFF)<<16)  	/**< Pause Timer                       */
+
+/* Flow Control Status Register */
+#define EMAC_FCS_MIRR_CNT(n)        	(n&0xFFFF)  		/**< Mirror Counter Current            */
+
+
+/* Receive filter register definitions -------------------------------------------------------- */
+/* Receive Filter Control Register */
+#define EMAC_RFC_UCAST_EN        0x00000001  /**< Accept Unicast Frames Enable      */
+#define EMAC_RFC_BCAST_EN        0x00000002  /**< Accept Broadcast Frames Enable    */
+#define EMAC_RFC_MCAST_EN        0x00000004  /**< Accept Multicast Frames Enable    */
+#define EMAC_RFC_UCAST_HASH_EN   0x00000008  /**< Accept Unicast Hash Filter Frames */
+#define EMAC_RFC_MCAST_HASH_EN   0x00000010  /**< Accept Multicast Hash Filter Fram.*/
+#define EMAC_RFC_PERFECT_EN      0x00000020  /**< Accept Perfect Match Enable       */
+#define EMAC_RFC_MAGP_WOL_EN     0x00001000  /**< Magic Packet Filter WoL Enable    */
+#define EMAC_RFC_PFILT_WOL_EN    0x00002000  /**< Perfect Filter WoL Enable         */
+
+/* Receive Filter WoL Status/Clear Registers */
+#define EMAC_WOL_UCAST           0x00000001  /**< Unicast Frame caused WoL          */
+#define EMAC_WOL_BCAST           0x00000002  /**< Broadcast Frame caused WoL        */
+#define EMAC_WOL_MCAST           0x00000004  /**< Multicast Frame caused WoL        */
+#define EMAC_WOL_UCAST_HASH      0x00000008  /**< Unicast Hash Filter Frame WoL     */
+#define EMAC_WOL_MCAST_HASH      0x00000010  /**< Multicast Hash Filter Frame WoL   */
+#define EMAC_WOL_PERFECT         0x00000020  /**< Perfect Filter WoL                */
+#define EMAC_WOL_RX_FILTER       0x00000080  /**< RX Filter caused WoL              */
+#define EMAC_WOL_MAG_PACKET      0x00000100  /**< Magic Packet Filter caused WoL    */
+#define EMAC_WOL_BITMASK		 0x01BF		/**< Receive Filter WoL Status/Clear bitmasl value */
+
+/* Hash Filter Table LSBs Register */
+//
+
+/* Hash Filter Table MSBs Register */
+//
+
+
+/* Module control register definitions ---------------------------------------------------- */
+/* Interrupt Status/Enable/Clear/Set Registers */
+#define EMAC_INT_RX_OVERRUN      0x00000001  /**< Overrun Error in RX Queue         */
+#define EMAC_INT_RX_ERR          0x00000002  /**< Receive Error                     */
+#define EMAC_INT_RX_FIN          0x00000004  /**< RX Finished Process Descriptors   */
+#define EMAC_INT_RX_DONE         0x00000008  /**< Receive Done                      */
+#define EMAC_INT_TX_UNDERRUN     0x00000010  /**< Transmit Underrun                 */
+#define EMAC_INT_TX_ERR          0x00000020  /**< Transmit Error                    */
+#define EMAC_INT_TX_FIN          0x00000040  /**< TX Finished Process Descriptors   */
+#define EMAC_INT_TX_DONE         0x00000080  /**< Transmit Done                     */
+#define EMAC_INT_SOFT_INT        0x00001000  /**< Software Triggered Interrupt      */
+#define EMAC_INT_WAKEUP          0x00002000  /**< Wakeup Event Interrupt            */
+
+/* Power Down Register */
+#define EMAC_PD_POWER_DOWN       0x80000000  /**< Power Down MAC                    */
+
+/* RX Descriptor Control Word */
+#define EMAC_RCTRL_SIZE(n)       (n&0x7FF)  	/**< Buffer size field                  */
+#define EMAC_RCTRL_INT           0x80000000  	/**< Generate RxDone Interrupt         */
+
+/* RX Status Hash CRC Word */
+#define EMAC_RHASH_SA            0x000001FF  	/**< Hash CRC for Source Address       */
+#define EMAC_RHASH_DA            0x001FF000  	/**< Hash CRC for Destination Address  */
+
+/* RX Status Information Word */
+#define EMAC_RINFO_SIZE          0x000007FF  /**< Data size in bytes                */
+#define EMAC_RINFO_CTRL_FRAME    0x00040000  /**< Control Frame                     */
+#define EMAC_RINFO_VLAN          0x00080000  /**< VLAN Frame                        */
+#define EMAC_RINFO_FAIL_FILT     0x00100000  /**< RX Filter Failed                  */
+#define EMAC_RINFO_MCAST         0x00200000  /**< Multicast Frame                   */
+#define EMAC_RINFO_BCAST         0x00400000  /**< Broadcast Frame                   */
+#define EMAC_RINFO_CRC_ERR       0x00800000  /**< CRC Error in Frame                */
+#define EMAC_RINFO_SYM_ERR       0x01000000  /**< Symbol Error from PHY             */
+#define EMAC_RINFO_LEN_ERR       0x02000000  /**< Length Error                      */
+#define EMAC_RINFO_RANGE_ERR     0x04000000  /**< Range Error (exceeded max. size)  */
+#define EMAC_RINFO_ALIGN_ERR     0x08000000  /**< Alignment Error                   */
+#define EMAC_RINFO_OVERRUN       0x10000000  /**< Receive overrun                   */
+#define EMAC_RINFO_NO_DESCR      0x20000000  /**< No new Descriptor available       */
+#define EMAC_RINFO_LAST_FLAG     0x40000000  /**< Last Fragment in Frame            */
+#define EMAC_RINFO_ERR           0x80000000  /**< Error Occured (OR of all errors)  */
+
+/** RX Status Information word mask */
+#define EMAC_RINFO_ERR_MASK     (EMAC_RINFO_FAIL_FILT | EMAC_RINFO_CRC_ERR   | EMAC_RINFO_SYM_ERR | \
+EMAC_RINFO_LEN_ERR   | EMAC_RINFO_ALIGN_ERR | EMAC_RINFO_OVERRUN)
+
+/* TX Descriptor Control Word */
+#define EMAC_TCTRL_SIZE          0x000007FF  /**< Size of data buffer in bytes      */
+#define EMAC_TCTRL_OVERRIDE      0x04000000  /**< Override Default MAC Registers    */
+#define EMAC_TCTRL_HUGE          0x08000000  /**< Enable Huge Frame                 */
+#define EMAC_TCTRL_PAD           0x10000000  /**< Pad short Frames to 64 bytes      */
+#define EMAC_TCTRL_CRC           0x20000000  /**< Append a hardware CRC to Frame    */
+#define EMAC_TCTRL_LAST          0x40000000  /**< Last Descriptor for TX Frame      */
+#define EMAC_TCTRL_INT           0x80000000  /**< Generate TxDone Interrupt         */
+
+/* TX Status Information Word */
+#define EMAC_TINFO_COL_CNT       0x01E00000  /**< Collision Count                   */
+#define EMAC_TINFO_DEFER         0x02000000  /**< Packet Deferred (not an error)    */
+#define EMAC_TINFO_EXCESS_DEF    0x04000000  /**< Excessive Deferral                */
+#define EMAC_TINFO_EXCESS_COL    0x08000000  /**< Excessive Collision               */
+#define EMAC_TINFO_LATE_COL      0x10000000  /**< Late Collision Occured            */
+#define EMAC_TINFO_UNDERRUN      0x20000000  /**< Transmit Underrun                 */
+#define EMAC_TINFO_NO_DESCR      0x40000000  /**< No new Descriptor available       */
+#define EMAC_TINFO_ERR           0x80000000  /**< Error Occured (OR of all errors)  */
+
+
+/* DP83848C PHY definition ------------------------------------------------------------ */
+
+/** PHY device reset time out definition */
+#define EMAC_PHY_RESP_TOUT		0x100000UL
+
+/* ENET Device Revision ID */
+#define EMAC_OLD_EMAC_MODULE_ID  0x39022000  /**< Rev. ID for first rev '-'         */
+
+/* DP83848C PHY Registers */
+#define EMAC_PHY_REG_BMCR        0x00        /**< Basic Mode Control Register       */
+#define EMAC_PHY_REG_BMSR        0x01        /**< Basic Mode Status Register        */
+#define EMAC_PHY_REG_IDR1        0x02        /**< PHY Identifier 1                  */
+#define EMAC_PHY_REG_IDR2        0x03        /**< PHY Identifier 2                  */
+#define EMAC_PHY_REG_ANAR        0x04        /**< Auto-Negotiation Advertisement    */
+#define EMAC_PHY_REG_ANLPAR      0x05        /**< Auto-Neg. Link Partner Abitily    */
+#define EMAC_PHY_REG_ANER        0x06        /**< Auto-Neg. Expansion Register      */
+#define EMAC_PHY_REG_ANNPTR      0x07        /**< Auto-Neg. Next Page TX            */
+#define EMAC_PHY_REG_LPNPA		 0x08
+
+
+/* PHY Extended Registers */
+#define EMAC_PHY_REG_STS         0x10        /**< Status Register                   */
+#define EMAC_PHY_REG_MICR        0x11        /**< MII Interrupt Control Register    */
+#define EMAC_PHY_REG_MISR        0x12        /**< MII Interrupt Status Register     */
+#define EMAC_PHY_REG_FCSCR       0x14        /**< False Carrier Sense Counter       */
+#define EMAC_PHY_REG_RECR        0x15        /**< Receive Error Counter             */
+#define EMAC_PHY_REG_PCSR        0x16        /**< PCS Sublayer Config. and Status   */
+#define EMAC_PHY_REG_RBR         0x17        /**< RMII and Bypass Register          */
+#define EMAC_PHY_REG_LEDCR       0x18        /**< LED Direct Control Register       */
+#define EMAC_PHY_REG_PHYCR       0x19        /**< PHY Control Register              */
+#define EMAC_PHY_REG_10BTSCR     0x1A        /**< 10Base-T Status/Control Register  */
+#define EMAC_PHY_REG_CDCTRL1     0x1B        /**< CD Test Control and BIST Extens.  */
+#define EMAC_PHY_REG_EDCR        0x1D        /**< Energy Detect Control Register    */
+
+
+/* PHY Basic Mode Control Register (BMCR) bitmap definitions */
+#define EMAC_PHY_BMCR_RESET     			(1<<15)		/**< Reset bit */
+#define EMAC_PHY_BMCR_LOOPBACK      		(1<<14)		/**< Loop back */
+#define EMAC_PHY_BMCR_SPEED_SEL     		(1<<13)		/**< Speed selection */
+#define EMAC_PHY_BMCR_AN					(1<<12)		/**< Auto Negotiation */
+#define EMAC_PHY_BMCR_POWERDOWN				(1<<11)		/**< Power down mode */
+#define EMAC_PHY_BMCR_ISOLATE				(1<<10)		/**< Isolate */
+#define EMAC_PHY_BMCR_RE_AN					(1<<9)		/**< Restart auto negotiation */
+#define EMAC_PHY_BMCR_DUPLEX				(1<<8)		/**< Duplex mode */
+
+/* PHY Basic Mode Status Status Register (BMSR) bitmap definitions */
+#define EMAC_PHY_BMSR_100BE_T4        	   	(1<<15)		/**< 100 base T4 */
+#define EMAC_PHY_BMSR_100TX_FULL			(1<<14)		/**< 100 base full duplex */
+#define EMAC_PHY_BMSR_100TX_HALF			(1<<13)		/**< 100 base half duplex */
+#define EMAC_PHY_BMSR_10BE_FULL				(1<<12)		/**< 10 base T full duplex */
+#define EMAC_PHY_BMSR_10BE_HALF				(1<<11)		/**< 10 base T half duplex */
+#define EMAC_PHY_BMSR_NOPREAM				(1<<6)		/**< MF Preamable Supress */
+#define EMAC_PHY_BMSR_AUTO_DONE				(1<<5)		/**< Auto negotiation complete */
+#define EMAC_PHY_BMSR_REMOTE_FAULT			(1<<4)		/**< Remote fault */
+#define EMAC_PHY_BMSR_NO_AUTO				(1<<3)		/**< Auto Negotiation ability */
+#define EMAC_PHY_BMSR_LINK_ESTABLISHED		(1<<2)		/**< Link status */
+
+/* PHY Status Register bitmap definitions */
+#define EMAC_PHY_SR_REMOTE_FAULT   			(1<<6)		/**< Remote Fault */
+#define EMAC_PHY_SR_JABBER					(1<<5)		/**< Jabber detect */
+#define EMAC_PHY_SR_AUTO_DONE				(1<<4)		/**< Auto Negotiation complete */
+#define EMAC_PHY_SR_LOOPBACK				(1<<3)		/**< Loop back status */
+#define EMAC_PHY_SR_DUP						(1<<2)		/**< Duplex status */
+#define EMAC_PHY_SR_SPEED					(1<<1)		/**< Speed status */
+#define EMAC_PHY_SR_LINK					(1<<0)		/**< Link Status */
+
+
+#define EMAC_PHY_FULLD_100M      0x2100      /**< Full Duplex 100Mbit               */
+#define EMAC_PHY_HALFD_100M      0x2000      /**< Half Duplex 100Mbit               */
+#define EMAC_PHY_FULLD_10M       0x0100      /**< Full Duplex 10Mbit                */
+#define EMAC_PHY_HALFD_10M       0x0000      /**< Half Duplex 10MBit                */
+#define EMAC_PHY_AUTO_NEG        0x3000      /**< Select Auto Negotiation           */
+
+#define EMAC_DP83848C_DEF_ADR    0x0100      /**< Default PHY device address        */
+#define EMAC_DP83848C_ID         0x20005C90  /**< PHY Identifier                    */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup EMAC_Public_Types
+ * @{
+ */
+
+/* Descriptor and status formats ---------------------------------------------- */
+
+/**
+ * @brief RX Descriptor structure type definition
+ */
+typedef struct {
+	uint32_t Packet;	/**< Receive Packet Descriptor */
+	uint32_t Ctrl;		/**< Receive Control Descriptor */
+} RX_Desc;
+
+/**
+ * @brief RX Status structure type definition
+ */
+typedef struct {
+	uint32_t Info;		/**< Receive Information Status */
+	uint32_t HashCRC;	/**< Receive Hash CRC Status */
+} RX_Stat;
+
+/**
+ * @brief TX Descriptor structure type definition
+ */
+typedef struct {
+	uint32_t Packet;	/**< Transmit Packet Descriptor */
+	uint32_t Ctrl;		/**< Transmit Control Descriptor */
+} TX_Desc;
+
+/**
+ * @brief TX Status structure type definition
+ */
+typedef struct {
+   uint32_t Info;		/**< Transmit Information Status */
+} TX_Stat;
+
+
+/**
+ * @brief TX Data Buffer structure definition
+ */
+typedef struct {
+	uint32_t ulDataLen;			/**< Data length */
+	uint32_t *pbDataBuf;		/**< A word-align data pointer to data buffer */
+} EMAC_PACKETBUF_Type;
+
+/**
+ * @brief EMAC configuration structure definition
+ */
+typedef struct {
+	uint32_t	Mode;						/**< Supported EMAC PHY device speed, should be one of the following:
+											- EMAC_MODE_AUTO
+											- EMAC_MODE_10M_FULL
+											- EMAC_MODE_10M_HALF
+											- EMAC_MODE_100M_FULL
+											- EMAC_MODE_100M_HALF
+											*/
+	uint8_t 	*pbEMAC_Addr;				/**< Pointer to EMAC Station address that contains 6-bytes
+											of MAC address, it must be sorted in order (bEMAC_Addr[0]..[5])
+											*/
+} EMAC_CFG_Type;
+
+/** EMAC Call back function type definition */
+typedef void (EMAC_IntCBSType)(void);
+
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup EMAC_Public_Macros
+ * @{
+ */
+
+
+/* EMAC PHY status type definitions */
+#define EMAC_PHY_STAT_LINK			(0)		/**< Link Status */
+#define EMAC_PHY_STAT_SPEED			(1)		/**< Speed Status */
+#define EMAC_PHY_STAT_DUP			(2)		/**< Duplex Status */
+
+/* EMAC PHY device Speed definitions */
+#define EMAC_MODE_AUTO				(0)		/**< Auto-negotiation mode */
+#define EMAC_MODE_10M_FULL			(1)		/**< 10Mbps FullDuplex mode */
+#define EMAC_MODE_10M_HALF			(2)		/**< 10Mbps HalfDuplex mode */
+#define EMAC_MODE_100M_FULL			(3)		/**< 100Mbps FullDuplex mode */
+#define EMAC_MODE_100M_HALF			(4)		/**< 100Mbps HalfDuplex mode */
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup EMAC_Public_Functions
+ * @{
+ */
+
+Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct);
+void EMAC_DeInit(void);
+int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState);
+int32_t EMAC_SetPHYMode(uint32_t ulPHYMode);
+int32_t EMAC_UpdatePHYStatus(void);
+void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState);
+int32_t EMAC_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len);
+void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState);
+FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode);
+void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct);
+void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct);
+void EMAC_StandardIRQHandler(void);
+void EMAC_SetupIntCBS(uint32_t ulIntType, EMAC_IntCBSType *pfnIntCb);
+void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState);
+IntStatus EMAC_IntGetStatus(uint32_t ulIntType);
+Bool EMAC_CheckReceiveIndex(void);
+Bool EMAC_CheckTransmitIndex(void);
+FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType);
+uint32_t EMAC_GetReceiveDataSize(void);
+void EMAC_UpdateRxConsumeIndex(void);
+void EMAC_UpdateTxProduceIndex(void);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_EMAC_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.c
new file mode 100644
index 0000000..1004a7a
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.c
@@ -0,0 +1,657 @@
+/**
+ * @file	: lpc17xx_gpio.c
+ * @brief	: Contains all functions support for GPIO firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 11. Jun. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup GPIO
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_gpio.h"
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _GPIO
+
+/* Private Functions ---------------------------------------------------------- */
+/** @addtogroup GPIO_Private_Functions
+ * @{
+ */
+/*********************************************************************//**
+ * @brief		Get pointer to GPIO peripheral due to GPIO port
+ * @param[in]	portNum		Port Number value, should be in range from 0 to 4.
+ * @return		Pointer to GPIO peripheral
+ **********************************************************************/
+static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum)
+{
+	LPC_GPIO_TypeDef *pGPIO = NULL;
+
+	switch (portNum) {
+	case 0:
+		pGPIO = LPC_GPIO0;
+		break;
+	case 1:
+		pGPIO = LPC_GPIO1;
+		break;
+	case 2:
+		pGPIO = LPC_GPIO2;
+		break;
+	case 3:
+		pGPIO = LPC_GPIO3;
+		break;
+	case 4:
+		pGPIO = LPC_GPIO4;
+		break;
+	default:
+		break;
+	}
+
+	return pGPIO;
+}
+
+/*********************************************************************//**
+ * @brief		Get pointer to FIO peripheral in halfword accessible style
+ * 				due to FIO port
+ * @param[in]	portNum		Port Number value, should be in range from 0 to 4.
+ * @return		Pointer to FIO peripheral
+ **********************************************************************/
+static GPIO_HalfWord_TypeDef *FIO_HalfWordGetPointer(uint8_t portNum)
+{
+	GPIO_HalfWord_TypeDef *pFIO = NULL;
+
+	switch (portNum) {
+	case 0:
+		pFIO = GPIO0_HalfWord;
+		break;
+	case 1:
+		pFIO = GPIO1_HalfWord;
+		break;
+	case 2:
+		pFIO = GPIO2_HalfWord;
+		break;
+	case 3:
+		pFIO = GPIO3_HalfWord;
+		break;
+	case 4:
+		pFIO = GPIO4_HalfWord;
+		break;
+	default:
+		break;
+	}
+
+	return pFIO;
+}
+
+/*********************************************************************//**
+ * @brief		Get pointer to FIO peripheral in byte accessible style
+ * 				due to FIO port
+ * @param[in]	portNum		Port Number value, should be in range from 0 to 4.
+ * @return		Pointer to FIO peripheral
+ **********************************************************************/
+static GPIO_Byte_TypeDef *FIO_ByteGetPointer(uint8_t portNum)
+{
+	GPIO_Byte_TypeDef *pFIO = NULL;
+
+	switch (portNum) {
+	case 0:
+		pFIO = GPIO0_Byte;
+		break;
+	case 1:
+		pFIO = GPIO1_Byte;
+		break;
+	case 2:
+		pFIO = GPIO2_Byte;
+		break;
+	case 3:
+		pFIO = GPIO3_Byte;
+		break;
+	case 4:
+		pFIO = GPIO4_Byte;
+		break;
+	default:
+		break;
+	}
+
+	return pFIO;
+}
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup GPIO_Public_Functions
+ * @{
+ */
+
+
+/* GPIO ------------------------------------------------------------------------------ */
+
+/*********************************************************************//**
+ * @brief		Set Direction for GPIO port.
+ * @param[in]	portNum		Port Number value, should be in range from 0 to 4
+ * @param[in]	bitValue	Value that contains all bits to set direction,
+ * 							in range from 0 to 0xFFFFFFFF.
+ * 							example: value 0x5 to set direction for bit 0 and bit 1.
+ * @param[in]	dir			Direction value, should be:
+ * 							- 0: Input.
+ * 							- 1: Output.
+ * @return		None
+ *
+ * Note: All remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
+{
+	LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
+
+	if (pGPIO != NULL) {
+		// Enable Output
+		if (dir) {
+			pGPIO->FIODIR |= bitValue;
+		}
+		// Enable Input
+		else {
+			pGPIO->FIODIR &= ~bitValue;
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Set Value for bits that have output direction on GPIO port.
+ * @param[in]	portNum		Port number value, should be in range from 0 to 4
+ * @param[in]	bitValue	Value that contains all bits on GPIO to set,
+ * 							in range from 0 to 0xFFFFFFFF.
+ * 							example: value 0x5 to set bit 0 and bit 1.
+ * @return		None
+ *
+ * Note:
+ * - For all bits that has been set as input direction, this function will
+ * not effect.
+ * - For all remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)
+{
+	LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
+
+	if (pGPIO != NULL) {
+		pGPIO->FIOSET = bitValue;
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Clear Value for bits that have output direction on GPIO port.
+ * @param[in]	portNum		Port number value, should be in range from 0 to 4
+ * @param[in]	bitValue	Value that contains all bits on GPIO to clear,
+ * 							in range from 0 to 0xFFFFFFFF.
+ * 							example: value 0x5 to clear bit 0 and bit 1.
+ * @return		None
+ *
+ * Note:
+ * - For all bits that has been set as input direction, this function will
+ * not effect.
+ * - For all remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue)
+{
+	LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
+
+	if (pGPIO != NULL) {
+		pGPIO->FIOCLR = bitValue;
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Read Current state on port pin that have input direction of GPIO
+ * @param[in]	portNum		Port number to read value, in range from 0 to 4
+ * @return		Current value of GPIO port.
+ *
+ * Note: Return value contain state of each port pin (bit) on that GPIO regardless
+ * its direction is input or output.
+ **********************************************************************/
+uint32_t GPIO_ReadValue(uint8_t portNum)
+{
+	LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);
+
+	if (pGPIO != NULL) {
+		return pGPIO->FIOPIN;
+	}
+
+	return (0);
+}
+
+/* FIO word accessible ----------------------------------------------------------------- */
+/* Stub function for FIO (word-accessible) style */
+
+/**
+ * @brief The same with GPIO_SetDir()
+ */
+void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
+{
+	GPIO_SetDir(portNum, bitValue, dir);
+}
+
+/**
+ * @brief The same with GPIO_SetValue()
+ */
+void FIO_SetValue(uint8_t portNum, uint32_t bitValue)
+{
+	GPIO_SetValue(portNum, bitValue);
+}
+
+/**
+ * @brief The same with GPIO_ClearValue()
+ */
+void FIO_ClearValue(uint8_t portNum, uint32_t bitValue)
+{
+	GPIO_ClearValue(portNum, bitValue);
+}
+
+/**
+ * @brief The same with GPIO_ReadValue()
+ */
+uint32_t FIO_ReadValue(uint8_t portNum)
+{
+	return (GPIO_ReadValue(portNum));
+}
+
+
+/*********************************************************************//**
+ * @brief		Set mask value for bits in FIO port
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	bitValue	Value that contains all bits in to set,
+ * 							in range from 0 to 0xFFFFFFFF.
+ * @param[in]	maskValue	Mask value contains state value for each bit:
+ * 							- 0: not mask.
+ * 							- 1: mask.
+ * @return		None
+ *
+ * Note:
+ * - All remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ * - After executing this function, in mask register, value '0' on each bit
+ * enables an access to the corresponding physical pin via a read or write access,
+ * while value '1' on bit (masked) that corresponding pin will not be changed
+ * with write access and if read, will not be reflected in the updated pin.
+ **********************************************************************/
+void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue)
+{
+	LPC_GPIO_TypeDef *pFIO = GPIO_GetPointer(portNum);
+	if(pFIO != NULL) {
+		// Mask
+		if (maskValue){
+			pFIO->FIOMASK |= bitValue;
+		}
+		// Un-mask
+		else {
+			pFIO->FIOMASK &= ~bitValue;
+		}
+	}
+}
+
+
+/* FIO halfword accessible ------------------------------------------------------------- */
+
+/*********************************************************************//**
+ * @brief		Set direction for FIO port in halfword accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	halfwordNum	HalfWord part number, should be 0 (lower) or 1(upper)
+ * @param[in]	bitValue	Value that contains all bits in to set direction,
+ * 							in range from 0 to 0xFFFF.
+ * @param[in]	dir			Direction value, should be:
+ * 							- 0: Input.
+ * 							- 1: Output.
+ * @return		None
+ *
+ * Note: All remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir)
+{
+	GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Output direction
+		if (dir) {
+			// Upper
+			if(halfwordNum) {
+				pFIO->FIODIRU |= bitValue;
+			}
+			// lower
+			else {
+				pFIO->FIODIRL |= bitValue;
+			}
+		}
+		// Input direction
+		else {
+			// Upper
+			if(halfwordNum) {
+				pFIO->FIODIRU &= ~bitValue;
+			}
+			// lower
+			else {
+				pFIO->FIODIRL &= ~bitValue;
+			}
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Set mask value for bits in FIO port in halfword accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	halfwordNum	HalfWord part number, should be 0 (lower) or 1(upper)
+ * @param[in]	bitValue	Value that contains all bits in to set,
+ * 							in range from 0 to 0xFFFF.
+ * @param[in]	maskValue	Mask value contains state value for each bit:
+ * 					- 0: not mask.
+ * 					- 1: mask.
+ * @return		None
+ *
+ * Note:
+ * - All remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ * - After executing this function, in mask register, value '0' on each bit
+ * enables an access to the corresponding physical pin via a read or write access,
+ * while value '1' on bit (masked) that corresponding pin will not be changed
+ * with write access and if read, will not be reflected in the updated pin.
+ **********************************************************************/
+void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue)
+{
+	GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Mask
+		if (maskValue){
+			// Upper
+			if(halfwordNum) {
+				pFIO->FIOMASKU |= bitValue;
+			}
+			// lower
+			else {
+				pFIO->FIOMASKL |= bitValue;
+			}
+		}
+		// Un-mask
+		else {
+			// Upper
+			if(halfwordNum) {
+				pFIO->FIOMASKU &= ~bitValue;
+			}
+			// lower
+			else {
+				pFIO->FIOMASKL &= ~bitValue;
+			}
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Set bits for FIO port in halfword accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	halfwordNum	HalfWord part number, should be 0 (lower) or 1(upper)
+ * @param[in]	bitValue	Value that contains all bits in to set,
+ * 							in range from 0 to 0xFFFF.
+ * @return		None
+ *
+ * Note:
+ * - For all bits that has been set as input direction, this function will
+ * not effect.
+ * - For all remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue)
+{
+	GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Upper
+		if(halfwordNum) {
+			pFIO->FIOSETU = bitValue;
+		}
+		// lower
+		else {
+			pFIO->FIOSETL = bitValue;
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Clear bits for FIO port in halfword accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	halfwordNum	HalfWord part number, should be 0 (lower) or 1(upper)
+ * @param[in]	bitValue	Value that contains all bits in to clear,
+ * 							in range from 0 to 0xFFFF.
+ * @return		None
+ *
+ * Note:
+ * - For all bits that has been set as input direction, this function will
+ * not effect.
+ * - For all remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue)
+{
+	GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Upper
+		if(halfwordNum) {
+			pFIO->FIOCLRU = bitValue;
+		}
+		// lower
+		else {
+			pFIO->FIOCLRL = bitValue;
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Read Current state on port pin that have input direction of GPIO
+ * 				in halfword accessible style.
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	halfwordNum	HalfWord part number, should be 0 (lower) or 1(upper)
+ * @return		Current value of FIO port pin of specified halfword.
+ * Note: Return value contain state of each port pin (bit) on that FIO regardless
+ * its direction is input or output.
+ **********************************************************************/
+uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum)
+{
+	GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Upper
+		if(halfwordNum) {
+			return (pFIO->FIOPINU);
+		}
+		// lower
+		else {
+			return (pFIO->FIOPINL);
+		}
+	}
+	return (0);
+}
+
+
+/* FIO Byte accessible ------------------------------------------------------------ */
+
+/*********************************************************************//**
+ * @brief		Set direction for FIO port in byte accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	byteNum		Byte part number, should be in range from 0 to 3
+ * @param[in]	bitValue	Value that contains all bits in to set direction,
+ * 							in range from 0 to 0xFF.
+ * @param[in]	dir			Direction value, should be:
+ * 							- 0: Input.
+ * 							- 1: Output.
+ * @return		None
+ *
+ * Note: All remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir)
+{
+	GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Output direction
+		if (dir) {
+			if ((byteNum >= 0) && (byteNum <= 3)) {
+				pFIO->FIODIR[byteNum] |= bitValue;
+			}
+		}
+		// Input direction
+		else {
+			if ((byteNum >= 0) && (byteNum <= 3)) {
+				pFIO->FIODIR[byteNum] &= ~bitValue;
+			}
+		}
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Set mask value for bits in FIO port in byte accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	byteNum		Byte part number, should be in range from 0 to 3
+ * @param[in]	bitValue	Value that contains all bits in to set mask,
+ * 							in range from 0 to 0xFF.
+ * @param[in]	maskValue	Mask value contains state value for each bit:
+ * 							- 0: not mask.
+ * 							- 1: mask.
+ * @return		None
+ *
+ * Note:
+ * - All remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ * - After executing this function, in mask register, value '0' on each bit
+ * enables an access to the corresponding physical pin via a read or write access,
+ * while value '1' on bit (masked) that corresponding pin will not be changed
+ * with write access and if read, will not be reflected in the updated pin.
+ **********************************************************************/
+void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue)
+{
+	GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
+	if(pFIO != NULL) {
+		// Mask
+		if (maskValue) {
+			if ((byteNum >= 0) && (byteNum <= 3)) {
+				pFIO->FIOMASK[byteNum] |= bitValue;
+			}
+		}
+		// Un-mask
+		else {
+			if ((byteNum >= 0) && (byteNum <= 3)) {
+				pFIO->FIOMASK[byteNum] &= ~bitValue;
+			}
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Set bits for FIO port in byte accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	byteNum		Byte part number, should be in range from 0 to 3
+ * @param[in]	bitValue	Value that contains all bits in to set,
+ * 							in range from 0 to 0xFF.
+ * @return		None
+ *
+ * Note:
+ * - For all bits that has been set as input direction, this function will
+ * not effect.
+ * - For all remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue)
+{
+	GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
+	if (pFIO != NULL) {
+		if ((byteNum >= 0) && (byteNum <= 3)){
+			pFIO->FIOSET[byteNum] = bitValue;
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Clear bits for FIO port in byte accessible style
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	byteNum		Byte part number, should be in range from 0 to 3
+ * @param[in]	bitValue	Value that contains all bits in to clear,
+ * 							in range from 0 to 0xFF.
+ * @return		None
+ *
+ * Note:
+ * - For all bits that has been set as input direction, this function will
+ * not effect.
+ * - For all remaining bits that are not activated in bitValue (value '0')
+ * will not be effected by this function.
+ **********************************************************************/
+void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue)
+{
+	GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
+	if (pFIO != NULL) {
+		if ((byteNum >= 0) && (byteNum <= 3)){
+			pFIO->FIOCLR[byteNum] = bitValue;
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Read Current state on port pin that have input direction of GPIO
+ * 				in byte accessible style.
+ * @param[in]	portNum		Port number, in range from 0 to 4
+ * @param[in]	byteNum		Byte part number, should be in range from 0 to 3
+ * @return		Current value of FIO port pin of specified byte part.
+ * Note: Return value contain state of each port pin (bit) on that FIO regardless
+ * its direction is input or output.
+ **********************************************************************/
+uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum)
+{
+	GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);
+	if (pFIO != NULL) {
+		if ((byteNum >= 0) && (byteNum <= 3)){
+			return (pFIO->FIOPIN[byteNum]);
+		}
+	}
+	return (0);
+}
+
+/**
+ * @}
+ */
+
+#endif /* _GPIO */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.h
new file mode 100644
index 0000000..8c05153
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_gpio.h
@@ -0,0 +1,166 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_gpio.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for GPIO firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 23. Apr. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup GPIO
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_GPIO_H_
+#define LPC17XX_GPIO_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup GPIO_Public_Types
+ * @{
+ */
+
+/**
+ * @brief Fast GPIO port byte type definition
+ */
+typedef struct {
+	__IO uint8_t FIODIR[4];		/**< FIO direction register in byte-align */
+	   uint32_t RESERVED0[3];	/**< Reserved */
+	__IO uint8_t FIOMASK[4];	/**< FIO mask register in byte-align */
+	__IO uint8_t FIOPIN[4];		/**< FIO pin register in byte align */
+	__IO uint8_t FIOSET[4];		/**< FIO set register in byte-align */
+	__O  uint8_t FIOCLR[4];		/**< FIO clear register in byte-align */
+} GPIO_Byte_TypeDef;
+
+
+/**
+ * @brief Fast GPIO port half-word type definition
+ */
+typedef struct {
+	__IO uint16_t FIODIRL;		/**< FIO direction register lower halfword part */
+	__IO uint16_t FIODIRU;		/**< FIO direction register upper halfword part */
+	   uint32_t RESERVED0[3];	/**< Reserved */
+	__IO uint16_t FIOMASKL;		/**< FIO mask register lower halfword part */
+	__IO uint16_t FIOMASKU;		/**< FIO mask register upper halfword part */
+	__IO uint16_t FIOPINL;		/**< FIO pin register lower halfword part */
+	__IO uint16_t FIOPINU;		/**< FIO pin register upper halfword part */
+	__IO uint16_t FIOSETL;		/**< FIO set register lower halfword part */
+	__IO uint16_t FIOSETU;		/**< FIO set register upper halfword part */
+	__O  uint16_t FIOCLRL;		/**< FIO clear register lower halfword part */
+	__O  uint16_t FIOCLRU;		/**< FIO clear register upper halfword part */
+} GPIO_HalfWord_TypeDef;
+
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup GPIO_Public_Macros
+ * @{
+ */
+
+/** Fast GPIO port 0 byte accessible definition */
+#define GPIO0_Byte	((GPIO_Byte_TypeDef *)(LPC_GPIO0_BASE))
+/** Fast GPIO port 1 byte accessible definition */
+#define GPIO1_Byte	((GPIO_Byte_TypeDef *)(LPC_GPIO1_BASE))
+/** Fast GPIO port 2 byte accessible definition */
+#define GPIO2_Byte	((GPIO_Byte_TypeDef *)(LPC_GPIO2_BASE))
+/** Fast GPIO port 3 byte accessible definition */
+#define GPIO3_Byte	((GPIO_Byte_TypeDef *)(LPC_GPIO3_BASE))
+/** Fast GPIO port 4 byte accessible definition */
+#define GPIO4_Byte	((GPIO_Byte_TypeDef *)(LPC_GPIO4_BASE))
+
+
+
+/** Fast GPIO port 0 half-word accessible definition */
+#define GPIO0_HalfWord	((GPIO_HalfWord_TypeDef *)(LPC_GPIO0_BASE))
+/** Fast GPIO port 1 half-word accessible definition */
+#define GPIO1_HalfWord	((GPIO_HalfWord_TypeDef *)(LPC_GPIO1_BASE))
+/** Fast GPIO port 2 half-word accessible definition */
+#define GPIO2_HalfWord	((GPIO_HalfWord_TypeDef *)(LPC_GPIO2_BASE))
+/** Fast GPIO port 3 half-word accessible definition */
+#define GPIO3_HalfWord	((GPIO_HalfWord_TypeDef *)(LPC_GPIO3_BASE))
+/** Fast GPIO port 4 half-word accessible definition */
+#define GPIO4_HalfWord	((GPIO_HalfWord_TypeDef *)(LPC_GPIO4_BASE))
+
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup GPIO_Public_Functions
+ * @{
+ */
+
+/* GPIO style ------------------------------- */
+void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir);
+void GPIO_SetValue(uint8_t portNum, uint32_t bitValue);
+void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue);
+uint32_t GPIO_ReadValue(uint8_t portNum);
+
+/* FIO (word-accessible) style ------------------------------- */
+void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir);
+void FIO_SetValue(uint8_t portNum, uint32_t bitValue);
+void FIO_ClearValue(uint8_t portNum, uint32_t bitValue);
+uint32_t FIO_ReadValue(uint8_t portNum);
+void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue);
+
+/* FIO (halfword-accessible) style ------------------------------- */
+void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir);
+void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue);
+void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue);
+void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue);
+uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum);
+
+/* FIO (byte-accessible) style ------------------------------- */
+void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir);
+void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue);
+void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue);
+void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue);
+uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum);
+
+
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_GPIO_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.c
new file mode 100644
index 0000000..14914e8
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.c
@@ -0,0 +1,64 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_libcfg_default.c
+ * @brief	: Library configuration source file (default),
+ * 				used to build library without examples.
+ * @version	: 1.0
+ * @date	: 26. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Library group ----------------------------------------------------------- */
+/** @addtogroup LIBCFG_DEFAULT
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_libcfg_default.h"
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup LIBCFG_DEFAULT_Public_Functions
+ * @{
+ */
+
+#ifndef __BUILD_WITH_EXAMPLE__
+
+#ifdef  DEBUG
+/*******************************************************************************
+* @brief		Reports the name of the source file and the source line number
+* 				where the CHECK_PARAM error has occurred.
+* @param[in]	file Pointer to the source file name
+* @param[in]    line assert_param error line source number
+* @return		None
+*******************************************************************************/
+void check_failed(uint8_t *file, uint32_t line)
+{
+	/* User can add his own implementation to report the file name and line number,
+	 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+
+	/* Infinite loop */
+	while(1);
+}
+#endif /* DEBUG */
+
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.h
new file mode 100644
index 0000000..3430e0a
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_libcfg_default.h
@@ -0,0 +1,163 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_libcfg_default.h
+ * @brief	: Default Library configuration header file
+ * @version	: 1.0
+ * @date	: 26. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Library Configuration group ----------------------------------------------------------- */
+/** @defgroup LIBCFG_DEFAULT
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_LIBCFG_DEFAULT_H_
+#define LPC17XX_LIBCFG_DEFAULT_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc_types.h"
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup LIBCFG_DEFAULT_Public_Macros
+ * @{
+ */
+
+/************************** DEBUG MODE DEFINITIONS *********************************/
+/* Un-comment the line below to compile the library in DEBUG mode, this will expanse
+   the "CHECK_PARAM" macro in the FW library code */
+
+#define DEBUG    1
+
+
+/******************* PERIPHERAL FW LIBRARY CONFIGURATION DEFINITIONS ***********************/
+
+/* Comment the line below to disable the specific peripheral inclusion */
+
+/* GPIO ------------------------------- */
+#define _GPIO	1
+
+/* UART ------------------------------- */
+#define _UART 	1
+#define _UART0 	1
+#define _UART1 	1
+#define _UART2 	1
+#define _UART3 	1
+
+/* SPI ------------------------------- */
+#define _SPI 	1
+
+/* SSP ------------------------------- */
+#define _SSP 	1
+#define _SSP0 	1
+#define _SSP1 	1
+
+
+/* I2C ------------------------------- */
+#define _I2C 	1
+#define _I2C0 	1
+#define _I2C1 	1
+#define _I2C2 	1
+
+/* TIMER ------------------------------- */
+#define _TIM 	1
+
+/* WDT ------------------------------- */
+#define _WDT 	1
+
+
+/* GPDMA ------------------------------- */
+#define _GPDMA 	1
+
+
+/* DAC ------------------------------- */
+#define _DAC	1
+
+/* DAC ------------------------------- */
+#define _ADC	1
+
+
+/* PWM ------------------------------- */
+#define _PWM	1
+#define _PWM1	1
+
+/* RTC ------------------------------- */
+#define _RTC	1
+
+/* I2S ------------------------------- */
+#define _I2S 	1
+
+/* USB device ------------------------------- */
+#define _USBDEV		1
+#define _USB_DMA 	1
+
+/* QEI ------------------------------- */
+#define _QEI 	1
+
+/* MCPWM ------------------------------- */
+#define _MCPWM 	1
+
+/* CAN--------------------------------*/
+#define _CAN 	1
+
+/* RIT ------------------------------- */
+#define _RIT	1
+
+/* EMAC ------------------------------ */
+#define _EMAC	1
+
+
+/************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/
+
+#ifdef  DEBUG
+/*******************************************************************************
+* @brief		The CHECK_PARAM macro is used for function's parameters check.
+* 				It is used only if the library is compiled in DEBUG mode.
+* @param[in]	expr - If expr is false, it calls check_failed() function
+*                    	which reports the name of the source file and the source
+*                    	line number of the call that failed.
+*                    - If expr is true, it returns no value.
+* @return		None
+*******************************************************************************/
+#define CHECK_PARAM(expr) ((expr) ? (void)0 : check_failed((uint8_t *)__FILE__, __LINE__))
+#else
+#define CHECK_PARAM(expr)
+#endif /* DEBUG */
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup LIBCFG_DEFAULT_Public_Functions
+ * @{
+ */
+
+#ifdef  DEBUG
+void check_failed(uint8_t *file, uint32_t line);
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* LPC17XX_LIBCFG_DEFAULT_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.c
new file mode 100644
index 0000000..98a6878
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.c
@@ -0,0 +1,135 @@
+/**
+ * @file	: lpc17xx_nvic.c
+ * @brief	: Contains all expansion functions support for
+ * 				NVIC firmware library on LPC17xx. The main
+ * 				NVIC functions are defined in core_cm3.h
+ * @version	: 1.0
+ * @date	: 18. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup NVIC
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_nvic.h"
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @addtogroup NVIC_Private_Macros
+ * @{
+ */
+
+/* Vector table offset bit mask */
+#define NVIC_VTOR_MASK              0x3FFFFF80
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup NVIC_Public_Functions
+ * @{
+ */
+
+
+/*****************************************************************************//**
+ * @brief		De-initializes the NVIC peripheral registers to their default
+ * 				reset values.
+ * @param		None
+ * @return      None
+ *
+ * These following NVIC peripheral registers will be de-initialized:
+ * - Disable Interrupt (32 IRQ interrupt sources that matched with LPC17xx)
+ * - Clear all Pending Interrupts (32 IRQ interrupt source that matched with LPC17xx)
+ * - Clear all Interrupt Priorities (32 IRQ interrupt source that matched with LPC17xx)
+ *******************************************************************************/
+void NVIC_DeInit(void)
+{
+	uint8_t tmp;
+
+	/* Disable all interrupts */
+	NVIC->ICER[0] = 0xFFFFFFFF;
+	NVIC->ICER[1] = 0x00000001;
+	/* Clear all pending interrupts */
+	NVIC->ICPR[0] = 0xFFFFFFFF;
+	NVIC->ICPR[1] = 0x00000001;
+
+	/* Clear all interrupt priority */
+	for (tmp = 0; tmp < 32; tmp++) {
+		NVIC->IP[tmp] = 0x00;
+	}
+}
+
+/*****************************************************************************//**
+ * @brief			De-initializes the SCB peripheral registers to their default
+ *                  reset values.
+ * @param			none
+ * @return 			none
+ *
+ * These following SCB NVIC peripheral registers will be de-initialized:
+ * - Interrupt Control State register
+ * - Interrupt Vector Table Offset register
+ * - Application Interrupt/Reset Control register
+ * - System Control register
+ * - Configuration Control register
+ * - System Handlers Priority Registers
+ * - System Handler Control and State Register
+ * - Configurable Fault Status Register
+ * - Hard Fault Status Register
+ * - Debug Fault Status Register
+ *******************************************************************************/
+void NVIC_SCBDeInit(void)
+{
+	uint8_t tmp;
+
+	SCB->ICSR = 0x0A000000;
+	SCB->VTOR = 0x00000000;
+	SCB->AIRCR = 0x05FA0000;
+	SCB->SCR = 0x00000000;
+	SCB->CCR = 0x00000000;
+
+	for (tmp = 0; tmp < 32; tmp++) {
+		SCB->SHP[tmp] = 0x00;
+	}
+
+	SCB->SHCSR = 0x00000000;
+	SCB->CFSR = 0xFFFFFFFF;
+	SCB->HFSR = 0xFFFFFFFF;
+	SCB->DFSR = 0xFFFFFFFF;
+}
+
+
+/*****************************************************************************//**
+ * @brief		Set Vector Table Offset value
+ * @param		offset Offset value
+ * @return      None
+ *******************************************************************************/
+void NVIC_SetVTOR(uint32_t offset)
+{
+	SCB->VTOR  = (offset & NVIC_VTOR_MASK);
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.h
new file mode 100644
index 0000000..072a654
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_nvic.h
@@ -0,0 +1,64 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_nvic.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for Nesting Vectored Interrupt firmware library
+ * 				on LPC17xx
+ * @version	: 1.0
+ * @date	: 18. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup NVIC
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_NVIC_H_
+#define LPC17XX_NVIC_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup NVIC_Public_Functions
+ * @{
+ */
+
+void NVIC_DeInit(void);
+void NVIC_SCBDeInit(void);
+void NVIC_SetVTOR(uint32_t offset);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_NVIC_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.c
new file mode 100644
index 0000000..c459217
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.c
@@ -0,0 +1,308 @@
+/**
+ * @file	: lpc17xx_pinsel.c
+ * @brief	: Contains all functions support for Pin connect block firmware
+ * 				library on LPC17xx
+ * @version	: 1.0
+ * @date	: 25. Feb. 2009
+ * @author	: HoanTran
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup PINSEL
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_pinsel.h"
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup PINSEL_Public_Functions
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief 		Setup the pin selection function
+ * @param[in]	portnum PORT number,
+ * 				should be one of the following:
+ * 				- PINSEL_PORT_0	: Port 0
+ * 				- PINSEL_PORT_1	: Port 1
+ * 				- PINSEL_PORT_2	: Port 2
+ * 				- PINSEL_PORT_3	: Port 3
+ *
+ * @param[in]	pinnum	Pin number,
+ * 				should be one of the following:
+				- PINSEL_PIN_0 : Pin 0
+				- PINSEL_PIN_1 : Pin 1
+				- PINSEL_PIN_2 : Pin 2
+				- PINSEL_PIN_3 : Pin 3
+				- PINSEL_PIN_4 : Pin 4
+				- PINSEL_PIN_5 : Pin 5
+				- PINSEL_PIN_6 : Pin 6
+				- PINSEL_PIN_7 : Pin 7
+				- PINSEL_PIN_8 : Pin 8
+				- PINSEL_PIN_9 : Pin 9
+				- PINSEL_PIN_10 : Pin 10
+				- PINSEL_PIN_11 : Pin 11
+				- PINSEL_PIN_12 : Pin 12
+				- PINSEL_PIN_13 : Pin 13
+				- PINSEL_PIN_14 : Pin 14
+				- PINSEL_PIN_15 : Pin 15
+				- PINSEL_PIN_16 : Pin 16
+				- PINSEL_PIN_17 : Pin 17
+				- PINSEL_PIN_18 : Pin 18
+				- PINSEL_PIN_19 : Pin 19
+				- PINSEL_PIN_20 : Pin 20
+				- PINSEL_PIN_21 : Pin 21
+				- PINSEL_PIN_22 : Pin 22
+				- PINSEL_PIN_23 : Pin 23
+				- PINSEL_PIN_24 : Pin 24
+				- PINSEL_PIN_25 : Pin 25
+				- PINSEL_PIN_26 : Pin 26
+				- PINSEL_PIN_27 : Pin 27
+				- PINSEL_PIN_28 : Pin 28
+				- PINSEL_PIN_29 : Pin 29
+				- PINSEL_PIN_30 : Pin 30
+				- PINSEL_PIN_31 : Pin 31
+
+ * @param[in] 	funcnum Function number,
+ * 				should be one of the following:
+ *				- PINSEL_FUNC_0 : default function
+ *				- PINSEL_FUNC_1 : first alternate function
+ *				- PINSEL_FUNC_2 : second alternate function
+ *				- PINSEL_FUNC_3 : third alternate function
+ *
+ * @return 		None
+ **********************************************************************/
+void PINSEL_SetPinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum)
+{
+	uint32_t pinnum_t = pinnum;
+	uint32_t pinselreg_idx = 2 * portnum;
+	uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINSEL0;
+
+	if (pinnum_t >= 16) {
+		pinnum_t -= 16;
+		pinselreg_idx++;
+	}
+	*(uint32_t *)(pPinCon + pinselreg_idx) &= ~(0x03UL << (pinnum_t * 2));
+	*(uint32_t *)(pPinCon + pinselreg_idx) |= ((uint32_t)funcnum) << (pinnum_t * 2);
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Configure trace function
+ * @param[in] 	NewState State of the Trace function configuration,
+ * 				should be one of the following:
+ * 				- ENABLE : Enable Trace Function
+ * 				- DISABLE : Disable Trace Function
+ *
+ * @return 		None
+ **********************************************************************/
+void PINSEL_ConfigTraceFunc(FunctionalState NewState)
+{
+	if (NewState == ENABLE) {
+		LPC_PINCON->PINSEL10 |= (0x01UL << 3);
+	} else if (NewState == DISABLE) {
+		LPC_PINCON->PINSEL10 &= ~(0x01UL << 3);
+	}
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Setup resistor mode for each pin
+ * @param[in]	portnum PORT number,
+ * 				should be one of the following:
+ * 				- PINSEL_PORT_0	: Port 0
+ * 				- PINSEL_PORT_1	: Port 1
+ * 				- PINSEL_PORT_2	: Port 2
+ * 				- PINSEL_PORT_3	: Port 3
+ * @param[in]	pinnum	Pin number,
+ * 				should be one of the following:
+				- PINSEL_PIN_0 : Pin 0
+				- PINSEL_PIN_1 : Pin 1
+				- PINSEL_PIN_2 : Pin 2
+				- PINSEL_PIN_3 : Pin 3
+				- PINSEL_PIN_4 : Pin 4
+				- PINSEL_PIN_5 : Pin 5
+				- PINSEL_PIN_6 : Pin 6
+				- PINSEL_PIN_7 : Pin 7
+				- PINSEL_PIN_8 : Pin 8
+				- PINSEL_PIN_9 : Pin 9
+				- PINSEL_PIN_10 : Pin 10
+				- PINSEL_PIN_11 : Pin 11
+				- PINSEL_PIN_12 : Pin 12
+				- PINSEL_PIN_13 : Pin 13
+				- PINSEL_PIN_14 : Pin 14
+				- PINSEL_PIN_15 : Pin 15
+				- PINSEL_PIN_16 : Pin 16
+				- PINSEL_PIN_17 : Pin 17
+				- PINSEL_PIN_18 : Pin 18
+				- PINSEL_PIN_19 : Pin 19
+				- PINSEL_PIN_20 : Pin 20
+				- PINSEL_PIN_21 : Pin 21
+				- PINSEL_PIN_22 : Pin 22
+				- PINSEL_PIN_23 : Pin 23
+				- PINSEL_PIN_24 : Pin 24
+				- PINSEL_PIN_25 : Pin 25
+				- PINSEL_PIN_26 : Pin 26
+				- PINSEL_PIN_27 : Pin 27
+				- PINSEL_PIN_28 : Pin 28
+				- PINSEL_PIN_29 : Pin 29
+				- PINSEL_PIN_30 : Pin 30
+				- PINSEL_PIN_31 : Pin 31
+
+ * @param[in] 	modenum: Mode number,
+ * 				should be one of the following:
+				- PINSEL_PINMODE_PULLUP	: Internal pull-up resistor
+				- PINSEL_PINMODE_TRISTATE : Tri-state
+				- PINSEL_PINMODE_PULLDOWN : Internal pull-down resistor
+
+ * @return 		None
+ **********************************************************************/
+void PINSEL_SetResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
+{
+	uint32_t pinnum_t = pinnum;
+	uint32_t pinmodereg_idx = 2 * portnum;
+	uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE0;
+
+	if (pinnum_t >= 16) {
+		pinnum_t -= 16;
+		pinmodereg_idx++ ;
+	}
+
+	*(uint32_t *)(pPinCon + pinmodereg_idx) &= ~(0x03UL << (pinnum_t * 2));
+	*(uint32_t *)(pPinCon + pinmodereg_idx) |= ((uint32_t)modenum) << (pinnum_t * 2);
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Setup Open drain mode for each pin
+ * @param[in]	portnum PORT number,
+ * 				should be one of the following:
+ * 				- PINSEL_PORT_0	: Port 0
+ * 				- PINSEL_PORT_1	: Port 1
+ * 				- PINSEL_PORT_2	: Port 2
+ * 				- PINSEL_PORT_3	: Port 3
+ *
+ * @param[in]	pinnum	Pin number,
+ * 				should be one of the following:
+				- PINSEL_PIN_0 : Pin 0
+				- PINSEL_PIN_1 : Pin 1
+				- PINSEL_PIN_2 : Pin 2
+				- PINSEL_PIN_3 : Pin 3
+				- PINSEL_PIN_4 : Pin 4
+				- PINSEL_PIN_5 : Pin 5
+				- PINSEL_PIN_6 : Pin 6
+				- PINSEL_PIN_7 : Pin 7
+				- PINSEL_PIN_8 : Pin 8
+				- PINSEL_PIN_9 : Pin 9
+				- PINSEL_PIN_10 : Pin 10
+				- PINSEL_PIN_11 : Pin 11
+				- PINSEL_PIN_12 : Pin 12
+				- PINSEL_PIN_13 : Pin 13
+				- PINSEL_PIN_14 : Pin 14
+				- PINSEL_PIN_15 : Pin 15
+				- PINSEL_PIN_16 : Pin 16
+				- PINSEL_PIN_17 : Pin 17
+				- PINSEL_PIN_18 : Pin 18
+				- PINSEL_PIN_19 : Pin 19
+				- PINSEL_PIN_20 : Pin 20
+				- PINSEL_PIN_21 : Pin 21
+				- PINSEL_PIN_22 : Pin 22
+				- PINSEL_PIN_23 : Pin 23
+				- PINSEL_PIN_24 : Pin 24
+				- PINSEL_PIN_25 : Pin 25
+				- PINSEL_PIN_26 : Pin 26
+				- PINSEL_PIN_27 : Pin 27
+				- PINSEL_PIN_28 : Pin 28
+				- PINSEL_PIN_29 : Pin 29
+				- PINSEL_PIN_30 : Pin 30
+				- PINSEL_PIN_31 : Pin 31
+
+ * @param[in]	modenum  Open drain mode number,
+ * 				should be one of the following:
+ * 				- PINSEL_PINMODE_NORMAL : Pin is in the normal (not open drain) mode
+ * 				- PINSEL_PINMODE_OPENDRAIN : Pin is in the open drain mode
+ *
+ * @return 		None
+ **********************************************************************/
+void PINSEL_SetOpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum)
+{
+	uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE_OD0;
+
+	if (modenum == PINSEL_PINMODE_OPENDRAIN){
+		*(uint32_t *)(pPinCon + portnum) |= (0x01UL << pinnum);
+	} else {
+		*(uint32_t *)(pPinCon + portnum) &= ~(0x01UL << pinnum);
+	}
+}
+
+
+
+/*********************************************************************//**
+ * @brief 		Setup I2C0 pins
+ * @param[in]	i2cPinMode I2C pin mode,
+ * 				should be one of the following:
+ * 				- PINSEL_I2C_Normal_Mode : The standard drive mode
+ * 				- PINSEL_I2C_Fast_Mode : Fast Mode Plus drive mode
+ *
+ * @param[in]	filterSlewRateEnable  should be:
+ * 				- ENABLE: Enable filter and slew rate.
+ * 				- DISABLE: Disable filter and slew rate.
+ *
+ * @return 		None
+ **********************************************************************/
+void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable)
+{
+	uint32_t regVal;
+
+	if (i2cPinMode == PINSEL_I2C_Fast_Mode){
+		regVal = PINSEL_I2CPADCFG_SCLDRV0 | PINSEL_I2CPADCFG_SDADRV0;
+	}
+
+	if (filterSlewRateEnable == DISABLE){
+		regVal = PINSEL_I2CPADCFG_SCLI2C0 | PINSEL_I2CPADCFG_SDAI2C0;
+	}
+	LPC_PINCON->I2CPADCFG = regVal;
+}
+
+
+/*********************************************************************//**
+ * @brief 		Configure Pin corresponding to specified parameters passed
+ * 				in the PinCfg
+ * @param[in]	PinCfg	Pointer to a PINSEL_CFG_Type structure
+ *                    that contains the configuration information for the
+ *                    specified pin.
+ * @return 		None
+ **********************************************************************/
+void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg)
+{
+	PINSEL_SetPinFunc(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Funcnum);
+	PINSEL_SetResistorMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Pinmode);
+	PINSEL_SetOpenDrainMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->OpenDrain);
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.h
new file mode 100644
index 0000000..ac1ba8a
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_pinsel.h
@@ -0,0 +1,210 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_pinsel.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for Pin connect block firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 25. Feb. 2009
+ * @author	: HoanTran
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup PINSEL
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_PINSEL_H_
+#define LPC17XX_PINSEL_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx.h"
+#include "lpc_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup PINSEL_Private_Macros
+ * @{
+ */
+
+/** @defgroup PINSEL_REGISTER_BIT_DEFINITIONS
+ * @{
+ */
+
+/* Pin selection define */
+/* I2C Pin Configuration register bit description */
+#define PINSEL_I2CPADCFG_SDADRV0 	_BIT(0) /**< Drive mode control for the SDA0 pin, P0.27 */
+#define PINSEL_I2CPADCFG_SDAI2C0	_BIT(1) /**< I2C mode control for the SDA0 pin, P0.27 */
+#define PINSEL_I2CPADCFG_SCLDRV0	_BIT(2) /**< Drive mode control for the SCL0 pin, P0.28 */
+#define PINSEL_I2CPADCFG_SCLI2C0	_BIT(3) /**< I2C mode control for the SCL0 pin, P0.28 */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup PINSEL_Public_Macros
+ * @{
+ */
+
+/*********************************************************************//**
+ *!< Macros define for PORT Selection
+ ***********************************************************************/
+#define PINSEL_PORT_0 	((0))	/**< PORT 0*/
+#define PINSEL_PORT_1 	((1))	/**< PORT 1*/
+#define PINSEL_PORT_2 	((2))	/**< PORT 2*/
+#define PINSEL_PORT_3 	((3))	/**< PORT 3*/
+#define PINSEL_PORT_4 	((4))	/**< PORT 4*/
+
+
+/***********************************************************************
+ * Macros define for Pin Function selection
+ **********************************************************************/
+#define PINSEL_FUNC_0	((0))	/**< default function*/
+#define PINSEL_FUNC_1	((1))	/**< first alternate function*/
+#define PINSEL_FUNC_2	((2))	/**< second alternate function*/
+#define PINSEL_FUNC_3	((3))	/**< third or reserved alternate function*/
+
+
+
+/***********************************************************************
+ * Macros define for Pin Number of Port
+ **********************************************************************/
+#define PINSEL_PIN_0 	((0)) 	/**< Pin 0 */
+#define PINSEL_PIN_1 	((1)) 	/**< Pin 1 */
+#define PINSEL_PIN_2 	((2)) 	/**< Pin 2 */
+#define PINSEL_PIN_3 	((3)) 	/**< Pin 3 */
+#define PINSEL_PIN_4 	((4)) 	/**< Pin 4 */
+#define PINSEL_PIN_5 	((5)) 	/**< Pin 5 */
+#define PINSEL_PIN_6 	((6)) 	/**< Pin 6 */
+#define PINSEL_PIN_7 	((7)) 	/**< Pin 7 */
+#define PINSEL_PIN_8 	((8)) 	/**< Pin 8 */
+#define PINSEL_PIN_9 	((9)) 	/**< Pin 9 */
+#define PINSEL_PIN_10 	((10)) 	/**< Pin 10 */
+#define PINSEL_PIN_11 	((11)) 	/**< Pin 11 */
+#define PINSEL_PIN_12 	((12)) 	/**< Pin 12 */
+#define PINSEL_PIN_13 	((13)) 	/**< Pin 13 */
+#define PINSEL_PIN_14 	((14)) 	/**< Pin 14 */
+#define PINSEL_PIN_15 	((15)) 	/**< Pin 15 */
+#define PINSEL_PIN_16 	((16)) 	/**< Pin 16 */
+#define PINSEL_PIN_17 	((17)) 	/**< Pin 17 */
+#define PINSEL_PIN_18 	((18)) 	/**< Pin 18 */
+#define PINSEL_PIN_19 	((19)) 	/**< Pin 19 */
+#define PINSEL_PIN_20 	((20)) 	/**< Pin 20 */
+#define PINSEL_PIN_21 	((21)) 	/**< Pin 21 */
+#define PINSEL_PIN_22 	((22)) 	/**< Pin 22 */
+#define PINSEL_PIN_23 	((23)) 	/**< Pin 23 */
+#define PINSEL_PIN_24 	((24)) 	/**< Pin 24 */
+#define PINSEL_PIN_25 	((25)) 	/**< Pin 25 */
+#define PINSEL_PIN_26 	((26)) 	/**< Pin 26 */
+#define PINSEL_PIN_27 	((27)) 	/**< Pin 27 */
+#define PINSEL_PIN_28 	((28)) 	/**< Pin 28 */
+#define PINSEL_PIN_29 	((29)) 	/**< Pin 29 */
+#define PINSEL_PIN_30 	((30)) 	/**< Pin 30 */
+#define PINSEL_PIN_31 	((31)) 	/**< Pin 31 */
+
+
+/***********************************************************************
+ * Macros define for Pin mode
+ **********************************************************************/
+#define PINSEL_PINMODE_PULLUP		((0))	/**< Internal pull-up resistor*/
+#define PINSEL_PINMODE_TRISTATE 	((2))	/**< Tri-state */
+#define PINSEL_PINMODE_PULLDOWN 	((3)) 	/**< Internal pull-down resistor */
+
+
+/***********************************************************************
+ * Macros define for Pin mode (normal/open drain)
+ **********************************************************************/
+#define	PINSEL_PINMODE_NORMAL		((0))	/**< Pin is in the normal (not open drain) mode.*/
+#define	PINSEL_PINMODE_OPENDRAIN	((1)) 	/**< Pin is in the open drain mode */
+
+
+/***********************************************************************
+ * Macros define for I2C mode
+ ***********************************************************************/
+#define	PINSEL_I2C_Normal_Mode		((0))	/**< The standard drive mode */
+#define	PINSEL_I2C_Fast_Mode		((1)) 	/**<  Fast Mode Plus drive mode */
+
+
+/**
+ * @}
+ */
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup PINSEL_Public_Types
+ * @{
+ */
+
+/** @brief Pin configuration structure */
+typedef struct
+{
+	uint8_t Portnum;	/**< Port Number, should be PINSEL_PORT_x,
+						where x should be in range from 0 to 4 */
+	uint8_t Pinnum;		/**< Pin Number, should be PINSEL_PIN_x,
+						where x should be in range from 0 to 31 */
+	uint8_t Funcnum;	/**< Function Number, should be PINSEL_FUNC_x,
+						where x should be in range from 0 to 3 */
+	uint8_t Pinmode;	/**< Pin Mode, should be:
+						- PINSEL_PINMODE_PULLUP: Internal pull-up resistor
+						- PINSEL_PINMODE_TRISTATE: Tri-state
+						- PINSEL_PINMODE_PULLDOWN: Internal pull-down resistor */
+	uint8_t OpenDrain;	/**< OpenDrain mode, should be:
+						- PINSEL_PINMODE_NORMAL: Pin is in the normal (not open drain) mode
+						- PINSEL_PINMODE_OPENDRAIN: Pin is in the open drain mode */
+} PINSEL_CFG_Type;
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup PINSEL_Public_Functions
+ * @{
+ */
+
+void PINSEL_SetPinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum);
+void PINSEL_ConfigTraceFunc (FunctionalState NewState);
+void PINSEL_SetResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
+void PINSEL_SetOpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum);
+void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable);
+void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_PINSEL_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
+
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.c
new file mode 100644
index 0000000..967a2e2
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.c
@@ -0,0 +1,831 @@
+/**
+ * @file	: lpc17xx_ssp.c
+ * @brief	: Contains all functions support for SSP firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 9. April. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup SSP
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_ssp.h"
+#include "lpc17xx_clkpwr.h"
+
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _SSP
+
+/* Private Types -------------------------------------------------------------- */
+/** @defgroup SSP_Private_Types
+ * @{
+ */
+
+/** @brief SSP device configuration structure type */
+typedef struct
+{
+	int32_t 	dataword;				/* Current data word: 0 - 8 bit; 1 - 16 bit */
+	uint32_t    txrx_setup; 			/* Transmission setup */
+	void		(*inthandler)(LPC_SSP_TypeDef *SSPx);   	/* Transmission interrupt handler */
+} SSP_CFG_T;
+
+/**
+ * @}
+ */
+
+/* Private Variables ---------------------------------------------------------- */
+/* SSP configuration data */
+static SSP_CFG_T sspdat[2];
+
+
+/* Private Functions ---------------------------------------------------------- */
+/** @defgroup SSP_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Convert from SSP peripheral to number
+ */
+static int32_t SSP_getNum(LPC_SSP_TypeDef *SSPx){
+	if (SSPx == LPC_SSP0) {
+		return (0);
+	} else if (SSPx == LPC_SSP1) {
+		return (1);
+	}
+	return (-1);
+}
+
+
+/*********************************************************************//**
+ * @brief 		Standard Private SSP Interrupt handler
+ * @param		SSPx: SSP peripheral definition, should be
+ * 					  SSP0 or SSP1.
+ * @return 		None
+ ***********************************************************************/
+void SSP_IntHandler(LPC_SSP_TypeDef *SSPx)
+{
+	SSP_DATA_SETUP_Type *xf_setup;
+    uint16_t tmp;
+    int32_t sspnum;
+
+    // Disable interrupt
+    SSPx->IMSC = 0;
+
+    sspnum = SSP_getNum(SSPx);
+    xf_setup = (SSP_DATA_SETUP_Type *)sspdat[sspnum].txrx_setup;
+
+    // save status
+    tmp = SSPx->RIS;
+    xf_setup->status = tmp;
+
+    // Check overrun error
+    if (tmp & SSP_RIS_ROR){
+    	// Clear interrupt
+    	SSPx->ICR = SSP_RIS_ROR;
+    	// update status
+    	xf_setup->status |= SSP_STAT_ERROR;
+    	// Callback
+    	if (xf_setup->callback != NULL){
+    		xf_setup->callback();
+    	}
+    	return;
+    }
+
+    if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)){
+    	/* check if RX FIFO contains data */
+		while ((SSPx->SR & SSP_SR_RNE) && (xf_setup->rx_cnt != xf_setup->length)){
+			// Read data from SSP data
+			tmp = SSP_ReceiveData(SSPx);
+
+			// Store data to destination
+			if (xf_setup->rx_data != NULL)
+			{
+				if (sspdat[sspnum].dataword == 0){
+					*(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp;
+				} else {
+					*(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp;
+				}
+			}
+			// Increase counter
+			if (sspdat[sspnum].dataword == 0){
+				xf_setup->rx_cnt++;
+			} else {
+				xf_setup->rx_cnt += 2;
+			}
+		}
+
+		while ((SSPx->SR & SSP_SR_TNF) && (xf_setup->tx_cnt != xf_setup->length)){
+			// Write data to buffer
+			if(xf_setup->tx_data == NULL){
+				if (sspdat[sspnum].dataword == 0){
+					SSP_SendData(SSPx, 0xFF);
+					xf_setup->tx_cnt++;
+				} else {
+					SSP_SendData(SSPx, 0xFFFF);
+					xf_setup->tx_cnt += 2;
+				}
+			} else {
+				if (sspdat[sspnum].dataword == 0){
+					SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt)));
+					xf_setup->tx_cnt++;
+				} else {
+					SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt)));
+					xf_setup->tx_cnt += 2;
+				}
+			}
+
+		    // Check overrun error
+		    if ((tmp = SSPx->RIS) & SSP_RIS_ROR){
+		    	// update status
+		    	xf_setup->status |= SSP_STAT_ERROR;
+		    	// Callback
+		    	if (xf_setup->callback != NULL){
+		    		xf_setup->callback();
+		    	}
+		    	return;
+		    }
+
+			// Check for any data available in RX FIFO
+			while ((SSPx->SR & SSP_SR_RNE) && (xf_setup->rx_cnt != xf_setup->length)){
+				// Read data from SSP data
+				tmp = SSP_ReceiveData(SSPx);
+
+				// Store data to destination
+				if (xf_setup->rx_data != NULL)
+				{
+					if (sspdat[sspnum].dataword == 0){
+						*(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp;
+					} else {
+						*(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp;
+					}
+				}
+				// Increase counter
+				if (sspdat[sspnum].dataword == 0){
+					xf_setup->rx_cnt++;
+				} else {
+					xf_setup->rx_cnt += 2;
+				}
+			}
+		}
+    }
+
+	// If there more data to sent or receive
+	if ((xf_setup->rx_cnt != xf_setup->length) || (xf_setup->tx_cnt != xf_setup->length)){
+		// Enable all interrupt
+		SSPx->IMSC = SSP_IMSC_BITMASK;
+	} else {
+		// Save status
+		xf_setup->status = SSP_STAT_DONE;
+		// Callback
+		if (xf_setup->callback != NULL){
+			xf_setup->callback();
+		}
+	}
+}
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup SSP_Public_Functions
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief 		Setup clock rate for SSP device
+ * @param[in] 	SSPx	SSP peripheral definition, should be
+ * 						SSP0 or SSP1.
+ * @param[in]	target_clock : clock of SSP (Hz)
+ * @return 		None
+ ***********************************************************************/
+void SSP_SetClock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock)
+{
+    uint32_t prescale, cr0_div, cmp_clk, ssp_clk;
+
+    CHECK_PARAM(PARAM_SSPx(SSPx));
+
+    /* The SSP clock is derived from the (main system oscillator / 2),
+       so compute the best divider from that clock */
+    if (SSPx == LPC_SSP0){
+    	ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP0);
+    } else if (SSPx == LPC_SSP1) {
+    	ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP1);
+    } else {
+    	return;
+    }
+
+	/* Find closest divider to get at or under the target frequency.
+	   Use smallest prescale possible and rely on the divider to get
+	   the closest target frequency */
+	cr0_div = 0;
+	cmp_clk = 0xFFFFFFFF;
+	prescale = 2;
+	while (cmp_clk > target_clock)
+	{
+		cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
+		if (cmp_clk > target_clock)
+		{
+			cr0_div++;
+			if (cr0_div > 0xFF)
+			{
+				cr0_div = 0;
+				prescale += 2;
+			}
+		}
+	}
+
+    /* Write computed prescaler and divider back to register */
+    SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
+    SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
+    SSPx->CPSR = prescale & SSP_CPSR_BITMASK;
+}
+
+
+/*********************************************************************//**
+ * @brief		De-initializes the SSPx peripheral registers to their
+*                  default reset values.
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @return 		None
+ **********************************************************************/
+void SSP_DeInit(LPC_SSP_TypeDef* SSPx)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+
+	if (SSPx == LPC_SSP0){
+		/* Set up clock and power for SSP0 module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, DISABLE);
+	} else if (SSPx == LPC_SSP1) {
+		/* Set up clock and power for SSP1 module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, DISABLE);
+	}
+}
+
+
+
+/********************************************************************//**
+ * @brief		Initializes the SSPx peripheral according to the specified
+*               parameters in the SSP_ConfigStruct.
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	SSP_ConfigStruct Pointer to a SSP_CFG_Type structure
+*                    that contains the configuration information for the
+*                    specified SSP peripheral.
+ * @return 		None
+ *********************************************************************/
+void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct)
+{
+	uint32_t tmp;
+
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+
+	if(SSPx == LPC_SSP0) {
+		/* Set up clock and power for SSP0 module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, ENABLE);
+	} else if(SSPx == LPC_SSP1) {
+		/* Set up clock and power for SSP1 module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, ENABLE);
+	} else {
+		return;
+	}
+
+	/* Configure SSP, interrupt is disable, LoopBack mode is disable,
+	 * SSP is disable, Slave output is disable as default
+	 */
+	tmp = ((SSP_ConfigStruct->CPHA) | (SSP_ConfigStruct->CPOL) \
+		| (SSP_ConfigStruct->FrameFormat) | (SSP_ConfigStruct->Databit))
+		& SSP_CR0_BITMASK;
+	// write back to SSP control register
+	SSPx->CR0 = tmp;
+	tmp = SSP_getNum(SSPx);
+	if (SSP_ConfigStruct->Databit > SSP_DATABIT_8){
+		sspdat[tmp].dataword = 1;
+	} else {
+		sspdat[tmp].dataword = 0;
+	}
+
+	tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK;
+	// Write back to CR1
+	SSPx->CR1 = tmp;
+
+	// Set clock rate for SSP peripheral
+	SSP_SetClock(SSPx, SSP_ConfigStruct->ClockRate);
+}
+
+
+
+/*****************************************************************************//**
+* @brief		Fills each SSP_InitStruct member with its default value:
+* 				- CPHA = SSP_CPHA_FIRST
+* 				- CPOL = SSP_CPOL_HI
+* 				- ClockRate = 1000000
+* 				- Databit = SSP_DATABIT_8
+* 				- Mode = SSP_MASTER_MODE
+* 				- FrameFormat = SSP_FRAME_SSP
+* @param[in]	SSP_InitStruct Pointer to a SSP_CFG_Type structure
+*                    which will be initialized.
+* @return		None
+*******************************************************************************/
+void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct)
+{
+	SSP_InitStruct->CPHA = SSP_CPHA_FIRST;
+	SSP_InitStruct->CPOL = SSP_CPOL_HI;
+	SSP_InitStruct->ClockRate = 1000000;
+	SSP_InitStruct->Databit = SSP_DATABIT_8;
+	SSP_InitStruct->Mode = SSP_MASTER_MODE;
+	SSP_InitStruct->FrameFormat = SSP_FRAME_SPI;
+}
+
+
+/*********************************************************************//**
+ * @brief		Enable or disable SSP peripheral's operation
+ * @param[in]	SSPx	SSP peripheral, should be SSP0 or SSP1
+ * @param[in]	NewState New State of SSPx peripheral's operation
+ * @return 		none
+ **********************************************************************/
+void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		SSPx->CR1 |= SSP_CR1_SSP_EN;
+	}
+	else
+	{
+		SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK;
+	}
+}
+
+
+
+/*********************************************************************//**
+ * @brief		Enable or disable Loop Back mode function in SSP peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	NewState	New State of Loop Back mode, should be:
+ * 							- ENABLE: Enable this function
+ * 							- DISABLE: Disable this function
+ * @return 		None
+ **********************************************************************/
+void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		SSPx->CR1 |= SSP_CR1_LBM_EN;
+	}
+	else
+	{
+		SSPx->CR1 &= (~SSP_CR1_LBM_EN) & SSP_CR1_BITMASK;
+	}
+}
+
+
+
+/*********************************************************************//**
+ * @brief		Enable or disable Slave Output function in SSP peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	NewState	New State of Slave Output function, should be:
+ * 							- ENABLE: Slave Output in normal operation
+ * 							- DISABLE: Slave Output is disabled. This blocks
+ * 							SSP controller from driving the transmit data
+ * 							line (MISO)
+ * Note: 		This function is available when SSP peripheral in Slave mode
+ * @return 		None
+ **********************************************************************/
+void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		SSPx->CR1 &= (~SSP_CR1_SO_DISABLE) & SSP_CR1_BITMASK;
+	}
+	else
+	{
+		SSPx->CR1 |= SSP_CR1_SO_DISABLE;
+	}
+}
+
+
+
+/*********************************************************************//**
+ * @brief		Transmit a single data through SSPx peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP
+ * @param[in]	Data	Data to transmit (must be 16 or 8-bit long,
+ * 						this depend on SSP data bit number configured)
+ * @return 		none
+ **********************************************************************/
+void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+
+	SSPx->DR = SSP_DR_BITMASK(Data);
+}
+
+
+
+/*********************************************************************//**
+ * @brief		Receive a single data from SSPx peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP
+ * @return 		Data received (16-bit long)
+ **********************************************************************/
+uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+
+	return ((uint16_t) (SSP_DR_BITMASK(SSPx->DR)));
+}
+
+/*********************************************************************//**
+ * @brief 		SSP Read write data function
+ * @param[in]	SSPx 	Pointer to SSP peripheral, should be SSP0 or SSP1
+ * @param[in]	dataCfg	Pointer to a SSP_DATA_SETUP_Type structure that
+ * 						contains specified information about transmit
+ * 						data configuration.
+ * @param[in]	xfType	Transfer type, should be:
+ * 						- SSP_TRANSFER_POLLING: Polling mode
+ * 						- SSP_TRANSFER_INTERRUPT: Interrupt mode
+ * @return 		Actual Data length has been transferred in polling mode.
+ * 				In interrupt mode, always return (0)
+ * 				Return (-1) if error.
+ * Note: This function can be used in both master and slave mode.
+ ***********************************************************************/
+int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \
+						SSP_TRANSFER_Type xfType)
+{
+	uint8_t *rdata8;
+    uint8_t *wdata8;
+	uint16_t *rdata16;
+    uint16_t *wdata16;
+    uint32_t stat;
+    uint32_t tmp;
+    int32_t sspnum;
+    int32_t dataword;
+
+    dataCfg->rx_cnt = 0;
+    dataCfg->tx_cnt = 0;
+    dataCfg->status = 0;
+
+
+	/* Clear all remaining data in RX FIFO */
+	while (SSPx->SR & SSP_SR_RNE){
+		tmp = (uint32_t) SSP_ReceiveData(SSPx);
+	}
+
+	// Clear status
+	SSPx->ICR = SSP_ICR_BITMASK;
+
+	sspnum = SSP_getNum(SSPx);
+	dataword = sspdat[sspnum].dataword;
+
+	// Polling mode ----------------------------------------------------------------------
+	if (xfType == SSP_TRANSFER_POLLING){
+		if (dataword == 0){
+			rdata8 = (uint8_t *)dataCfg->rx_data;
+			wdata8 = (uint8_t *)dataCfg->tx_data;
+		} else {
+			rdata16 = (uint16_t *)dataCfg->rx_data;
+			wdata16 = (uint16_t *)dataCfg->tx_data;
+		}
+		while ((dataCfg->tx_cnt != dataCfg->length) || (dataCfg->rx_cnt != dataCfg->length)){
+			if ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){
+				// Write data to buffer
+				if(dataCfg->tx_data == NULL){
+					if (dataword == 0){
+						SSP_SendData(SSPx, 0xFF);
+						dataCfg->tx_cnt++;
+					} else {
+						SSP_SendData(SSPx, 0xFFFF);
+						dataCfg->tx_cnt += 2;
+					}
+				} else {
+					if (dataword == 0){
+						SSP_SendData(SSPx, *wdata8);
+						wdata8++;
+						dataCfg->tx_cnt++;
+					} else {
+						SSP_SendData(SSPx, *wdata16);
+						wdata16++;
+						dataCfg->tx_cnt += 2;
+					}
+				}
+			}
+
+			// Check overrun error
+			if ((stat = SSPx->RIS) & SSP_RIS_ROR){
+				// save status and return
+				dataCfg->status = stat | SSP_STAT_ERROR;
+				return (-1);
+			}
+
+			// Check for any data available in RX FIFO
+			while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){
+				// Read data from SSP data
+				tmp = SSP_ReceiveData(SSPx);
+
+				// Store data to destination
+				if (dataCfg->rx_data != NULL)
+				{
+					if (dataword == 0){
+						*(rdata8) = (uint8_t) tmp;
+						rdata8++;
+					} else {
+						*(rdata16) = (uint16_t) tmp;
+						rdata16++;
+					}
+				}
+				// Increase counter
+				if (dataword == 0){
+					dataCfg->rx_cnt++;
+				} else {
+					dataCfg->rx_cnt += 2;
+				}
+			}
+		}
+
+		// save status
+		dataCfg->status = SSP_STAT_DONE;
+
+		if (dataCfg->tx_data != NULL){
+			return dataCfg->tx_cnt;
+		} else if (dataCfg->rx_data != NULL){
+			return dataCfg->rx_cnt;
+		} else {
+			return (0);
+		}
+	}
+
+	// Interrupt mode ----------------------------------------------------------------------
+	else if (xfType == SSP_TRANSFER_INTERRUPT){
+		sspdat[sspnum].inthandler = SSP_IntHandler;
+		sspdat[sspnum].txrx_setup = (uint32_t)dataCfg;
+
+		while ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){
+			// Write data to buffer
+			if(dataCfg->tx_data == NULL){
+				if (sspdat[sspnum].dataword == 0){
+					SSP_SendData(SSPx, 0xFF);
+					dataCfg->tx_cnt++;
+				} else {
+					SSP_SendData(SSPx, 0xFFFF);
+					dataCfg->tx_cnt += 2;
+				}
+			} else {
+				if (sspdat[sspnum].dataword == 0){
+					SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));
+					dataCfg->tx_cnt++;
+				} else {
+					SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));
+					dataCfg->tx_cnt += 2;
+				}
+			}
+
+			// Check error
+			if ((stat = SSPx->RIS) & SSP_RIS_ROR){
+				// save status and return
+				dataCfg->status = stat | SSP_STAT_ERROR;
+				return (-1);
+			}
+
+			// Check for any data available in RX FIFO
+			while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){
+				// Read data from SSP data
+				tmp = SSP_ReceiveData(SSPx);
+
+				// Store data to destination
+				if (dataCfg->rx_data != NULL)
+				{
+					if (sspdat[sspnum].dataword == 0){
+						*(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp;
+					} else {
+						*(uint16_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint16_t) tmp;
+					}
+				}
+				// Increase counter
+				if (sspdat[sspnum].dataword == 0){
+					dataCfg->rx_cnt++;
+				} else {
+					dataCfg->rx_cnt += 2;
+				}
+			}
+		}
+
+		// If there more data to sent or receive
+		if ((dataCfg->rx_cnt != dataCfg->length) || (dataCfg->tx_cnt != dataCfg->length)){
+			// Enable all interrupt
+			SSPx->IMSC = SSP_IMSC_BITMASK;
+		} else {
+			// Save status
+			dataCfg->status = SSP_STAT_DONE;
+		}
+		return (0);
+	}
+
+	return (-1);
+}
+
+/*********************************************************************//**
+ * @brief		Checks whether the specified SSP status flag is set or not
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	FlagType	Type of flag to check status, should be one
+ * 							of following:
+ *							- SSP_STAT_TXFIFO_EMPTY: TX FIFO is empty
+ *							- SSP_STAT_TXFIFO_NOTFULL: TX FIFO is not full
+ *							- SSP_STAT_RXFIFO_NOTEMPTY: RX FIFO is not empty
+ *							- SSP_STAT_RXFIFO_FULL: RX FIFO is full
+ *							- SSP_STAT_BUSY: SSP peripheral is busy
+ * @return		New State of specified SSP status flag
+ **********************************************************************/
+FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_SSP_STAT(FlagType));
+
+	return ((SSPx->SR & FlagType) ? SET : RESET);
+}
+
+
+
+/*********************************************************************//**
+ * @brief		Enable or disable specified interrupt type in SSP peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	IntType	Interrupt type in SSP peripheral, should be:
+ * 				- SSP_INTCFG_ROR: Receive Overrun interrupt
+ * 				- SSP_INTCFG_RT: Receive Time out interrupt
+ * 				- SSP_INTCFG_RX: RX FIFO is at least half full interrupt
+ * 				- SSP_INTCFG_TX: TX FIFO is at least half empty interrupt
+ * @param[in]	NewState New State of specified interrupt type, should be:
+ * 				- ENABLE: Enable this interrupt type
+ * 				- DISABLE: Disable this interrupt type
+ * @return		None
+ **********************************************************************/
+void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_SSP_INTCFG(IntType));
+
+	if (NewState == ENABLE)
+	{
+		SSPx->IMSC |= IntType;
+	}
+	else
+	{
+		SSPx->IMSC &= (~IntType) & SSP_IMSC_BITMASK;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief	Check whether the specified Raw interrupt status flag is
+ * 			set or not
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	RawIntType	Raw Interrupt Type, should be:
+ * 				- SSP_INTSTAT_RAW_ROR: Receive Overrun interrupt
+ * 				- SSP_INTSTAT_RAW_RT: Receive Time out interrupt
+ * 				- SSP_INTSTAT_RAW_RX: RX FIFO is at least half full interrupt
+ * 				- SSP_INTSTAT_RAW_TX: TX FIFO is at least half empty interrupt
+ * @return	New State of specified Raw interrupt status flag in SSP peripheral
+ * Note: Enabling/Disabling specified interrupt in SSP peripheral does not
+ * 		effect to Raw Interrupt Status flag.
+ **********************************************************************/
+IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_SSP_INTSTAT_RAW(RawIntType));
+
+	return ((SSPx->RIS & RawIntType) ? SET : RESET);
+}
+
+
+/*********************************************************************//**
+ * @brief	Check whether the specified interrupt status flag is
+ * 			set or not
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	IntType	Raw Interrupt Type, should be:
+ * 				- SSP_INTSTAT_ROR: Receive Overrun interrupt
+ * 				- SSP_INTSTAT_RT: Receive Time out interrupt
+ * 				- SSP_INTSTAT_RX: RX FIFO is at least half full interrupt
+ * 				- SSP_INTSTAT_TX: TX FIFO is at least half empty interrupt
+ * @return	New State of specified interrupt status flag in SSP peripheral
+ * Note: Enabling/Disabling specified interrupt in SSP peripheral effects
+ * 			to Interrupt Status flag.
+ **********************************************************************/
+IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_SSP_INTSTAT(IntType));
+
+	return ((SSPx->MIS & IntType) ? SET :RESET);
+}
+
+
+
+/*********************************************************************//**
+ * @brief				Clear specified interrupt pending in SSP peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	IntType	Interrupt pending to clear, should be:
+ * 						- SSP_INTCLR_ROR: clears the "frame was received when
+ * 						RxFIFO was full" interrupt.
+ * 						- SSP_INTCLR_RT: clears the "Rx FIFO was not empty and
+ * 						has not been read for a timeout period" interrupt.
+ * @return		None
+ **********************************************************************/
+void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_SSP_INTCLR(IntType));
+
+	SSPx->ICR = IntType;
+}
+
+/*********************************************************************//**
+ * @brief				Enable/Disable DMA function for SSP peripheral
+ * @param[in]	SSPx	SSP peripheral selected, should be SSP0 or SSP1
+ * @param[in]	DMAMode	Type of DMA, should be:
+ * 						- SSP_DMA_TX: DMA for the transmit FIFO
+ * 						- SSP_DMA_RX: DMA for the Receive FIFO
+ * @param[in]	NewState	New State of DMA function on SSP peripheral,
+ * 						should be:
+ * 						- ENALBE: Enable this function
+ * 						- DISABLE: Disable this function
+ * @return		None
+ **********************************************************************/
+void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_SSPx(SSPx));
+	CHECK_PARAM(PARAM_SSP_DMA(DMAMode));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		SSPx->DMACR |= DMAMode;
+	}
+	else
+	{
+		SSPx->DMACR &= (~DMAMode) & SSP_DMA_BITMASK;
+	}
+}
+
+/**
+ * @brief		Standard SSP0 Interrupt handler
+ * @param[in] 	None
+ * @return		None
+ */
+void SSP0_StdIntHandler(void)
+{
+	// Call relevant handler
+	sspdat[0].inthandler(LPC_SSP0);
+}
+
+/**
+ * @brief		Standard SSP1 Interrupt handler
+ * @param[in] 	None
+ * @return		None
+ */
+void SSP1_StdIntHandler(void)
+{
+	// Call relevant handler
+	sspdat[1].inthandler(LPC_SSP1);
+}
+
+/**
+ * @}
+ */
+
+#endif /* _SSP */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
+
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.h
new file mode 100644
index 0000000..6ec5746
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_ssp.h
@@ -0,0 +1,457 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_ssp.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for SSP firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 9. April. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup SSP
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef LPC17XX_SSP_H_
+#define LPC17XX_SSP_H_
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup SSP_Private_Macros
+ * @{
+ */
+
+/*********************************************************************//**
+ * Macro defines for CR0 register
+ **********************************************************************/
+
+/** @defgroup SSP_REGISTER_BIT_DEFINITION
+ * @{
+ */
+
+/** SSP data size select, must be 4 bits to 16 bits */
+#define SSP_CR0_DSS(n)   		((uint32_t)((n-1)&0xF))
+/** SSP control 0 Motorola SPI mode */
+#define SSP_CR0_FRF_SPI  		((uint32_t)(0<<4))
+/** SSP control 0 TI synchronous serial mode */
+#define SSP_CR0_FRF_TI   		((uint32_t)(1<<4))
+/** SSP control 0 National Micro-wire mode */
+#define SSP_CR0_FRF_MICROWIRE  	((uint32_t)(2<<4))
+/** SPI clock polarity bit (used in SPI mode only), (1) = maintains the
+   bus clock high between frames, (0) = low */
+#define SSP_CR0_CPOL_HI		((uint32_t)(1<<6))
+/** SPI clock out phase bit (used in SPI mode only), (1) = captures data
+   on the second clock transition of the frame, (0) = first */
+#define SSP_CR0_CPHA_SECOND	((uint32_t)(1<<7))
+/** SSP serial clock rate value load macro, divider rate is
+   PERIPH_CLK / (cpsr * (SCR + 1)) */
+#define SSP_CR0_SCR(n)   	((uint32_t)((n&0xFF)<<8))
+/** SSP CR0 bit mask */
+#define SSP_CR0_BITMASK		((uint32_t)(0xFFFF))
+
+
+/*********************************************************************//**
+ * Macro defines for CR1 register
+ **********************************************************************/
+/** SSP control 1 loopback mode enable bit */
+#define SSP_CR1_LBM_EN		((uint32_t)(1<<0))
+/** SSP control 1 enable bit */
+#define SSP_CR1_SSP_EN		((uint32_t)(1<<1))
+/** SSP control 1 slave enable */
+#define SSP_CR1_SLAVE_EN	((uint32_t)(1<<2))
+/** SSP control 1 slave out disable bit, disables transmit line in slave
+   mode */
+#define SSP_CR1_SO_DISABLE	((uint32_t)(1<<3))
+/** SSP CR1 bit mask */
+#define SSP_CR1_BITMASK		((uint32_t)(0x0F))
+
+
+/*********************************************************************//**
+ * Macro defines for DR register
+ **********************************************************************/
+/** SSP data bit mask */
+#define SSP_DR_BITMASK(n)   ((n)&0xFFFF)
+
+/*********************************************************************//**
+ * Macro defines for SR register
+ **********************************************************************/
+/** SSP status TX FIFO Empty bit */
+#define SSP_SR_TFE      ((uint32_t)(1<<0))
+/** SSP status TX FIFO not full bit */
+#define SSP_SR_TNF      ((uint32_t)(1<<1))
+/** SSP status RX FIFO not empty bit */
+#define SSP_SR_RNE      ((uint32_t)(1<<2))
+/** SSP status RX FIFO full bit */
+#define SSP_SR_RFF      ((uint32_t)(1<<3))
+/** SSP status SSP Busy bit */
+#define SSP_SR_BSY      ((uint32_t)(1<<4))
+/** SSP SR bit mask */
+#define SSP_SR_BITMASK	((uint32_t)(0x1F))
+
+
+/*********************************************************************//**
+ * Macro defines for CPSR register
+ **********************************************************************/
+/** SSP clock prescaler */
+#define SSP_CPSR_CPDVSR(n) 	((uint32_t)(n&0xFF))
+/** SSP CPSR bit mask */
+#define SSP_CPSR_BITMASK	((uint32_t)(0xFF))
+
+
+/*********************************************************************//**
+ * Macro define for (IMSC) Interrupt Mask Set/Clear registers
+ **********************************************************************/
+/** Receive Overrun */
+#define SSP_IMSC_ROR	((uint32_t)(1<<0))
+/** Receive TimeOut */
+#define SSP_IMSC_RT		((uint32_t)(1<<1))
+/** Rx FIFO is at least half full */
+#define SSP_IMSC_RX		((uint32_t)(1<<2))
+/** Tx FIFO is at least half empty */
+#define SSP_IMSC_TX		((uint32_t)(1<<3))
+/** IMSC bit mask */
+#define SSP_IMSC_BITMASK	((uint32_t)(0x0F))
+
+/*********************************************************************//**
+ * Macro define for (RIS) Raw Interrupt Status registers
+ **********************************************************************/
+/** Receive Overrun */
+#define SSP_RIS_ROR		((uint32_t)(1<<0))
+/** Receive TimeOut */
+#define SSP_RIS_RT		((uint32_t)(1<<1))
+/** Rx FIFO is at least half full */
+#define SSP_RIS_RX		((uint32_t)(1<<2))
+/** Tx FIFO is at least half empty */
+#define SSP_RIS_TX		((uint32_t)(1<<3))
+/** RIS bit mask */
+#define SSP_RIS_BITMASK	((uint32_t)(0x0F))
+
+
+/*********************************************************************//**
+ * Macro define for (MIS) Masked Interrupt Status registers
+ **********************************************************************/
+/** Receive Overrun */
+#define SSP_MIS_ROR		((uint32_t)(1<<0))
+/** Receive TimeOut */
+#define SSP_MIS_RT		((uint32_t)(1<<1))
+/** Rx FIFO is at least half full */
+#define SSP_MIS_RX		((uint32_t)(1<<2))
+/** Tx FIFO is at least half empty */
+#define SSP_MIS_TX		((uint32_t)(1<<3))
+/** MIS bit mask */
+#define SSP_MIS_BITMASK	((uint32_t)(0x0F))
+
+
+/*********************************************************************//**
+ * Macro define for (ICR) Interrupt Clear registers
+ **********************************************************************/
+/** Writing a 1 to this bit clears the "frame was received when
+ * RxFIFO was full" interrupt */
+#define SSP_ICR_ROR		((uint32_t)(1<<0))
+/** Writing a 1 to this bit clears the "Rx FIFO was not empty and
+ * has not been read for a timeout period" interrupt */
+#define SSP_ICR_RT		((uint32_t)(1<<1))
+/** ICR bit mask */
+#define SSP_ICR_BITMASK	((uint32_t)(0x03))
+
+
+/*********************************************************************//**
+ * Macro defines for DMACR register
+ **********************************************************************/
+/** SSP bit for enabling RX DMA */
+#define SSP_DMA_RXDMA_EN  	((uint32_t)(1<<0))
+/** SSP bit for enabling TX DMA */
+#define SSP_DMA_TXDMA_EN  	((uint32_t)(1<<1))
+/** DMACR	bit mask */
+#define SSP_DMA_BITMASK		((uint32_t)(0x03))
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup SSP_Public_Types
+ * @{
+ */
+
+/** @brief SSP configuration structure */
+typedef struct {
+	uint32_t Databit; 		/** Databit number, should be SSP_DATABIT_x,
+							where x is in range from 4 - 16 */
+	uint32_t CPHA;			/** Clock phase, should be:
+							- SSP_CPHA_FIRST: first clock edge
+							- SSP_CPHA_SECOND: second clock edge */
+	uint32_t CPOL;			/** Clock polarity, should be:
+							- SSP_CPOL_HI: high level
+							- SSP_CPOL_LO: low level */
+	uint32_t Mode;			/** SSP mode, should be:
+							- SSP_MASTER_MODE: Master mode
+							- SSP_SLAVE_MODE: Slave mode */
+	uint32_t FrameFormat;	/** Frame Format:
+							- SSP_FRAME_SPI: Motorola SPI frame format
+							- SSP_FRAME_TI: TI frame format
+							- SSP_FRAME_MICROWIRE: National Microwire frame format */
+	uint32_t ClockRate;		/** Clock rate,in Hz */
+} SSP_CFG_Type;
+
+/**
+ * @brief SSP Transfer Type definitions
+ */
+typedef enum {
+	SSP_TRANSFER_POLLING = 0,	/**< Polling transfer */
+	SSP_TRANSFER_INTERRUPT		/**< Interrupt transfer */
+} SSP_TRANSFER_Type;
+
+/**
+ * @brief SPI Data configuration structure definitions
+ */
+typedef struct {
+	void *tx_data;				/**< Pointer to transmit data */
+	uint32_t tx_cnt;			/**< Transmit counter */
+	void *rx_data;				/**< Pointer to transmit data */
+	uint32_t rx_cnt;			/**< Receive counter */
+	uint32_t length;			/**< Length of transfer data */
+	uint32_t status;			/**< Current status of SSP activity */
+	void (*callback)(void);		/**< Pointer to Call back function when transmission complete
+								used in interrupt transfer mode */
+} SSP_DATA_SETUP_Type;
+
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup SSP_Public_Macros
+ * @{
+ */
+
+/** Macro to determine if it is valid SSP port number */
+#define PARAM_SSPx(n)	((((uint32_t *)n)==((uint32_t *)LPC_SSP0)) \
+|| (((uint32_t *)n)==((uint32_t *)LPC_SSP1)))
+
+/*********************************************************************//**
+ * SSP configuration parameter defines
+ **********************************************************************/
+/** Clock phase control bit */
+#define SSP_CPHA_FIRST			((uint32_t)(0))
+#define SSP_CPHA_SECOND			SSP_CR0_CPHA_SECOND
+#define PARAM_SSP_CPHA(n) 		((n==SSP_CPHA_FIRST) || (n==SSP_CPHA_SECOND))
+
+/** Clock polarity control bit */
+/* There's no bug here!!!
+ * - If bit[6] in SSPnCR0 is 0: SSP controller maintains the bus clock low between frames.
+ * That means the active clock is in HI state.
+ * - If bit[6] in SSPnCR0 is 1 (SSP_CR0_CPOL_HI): SSP controller maintains the bus clock
+ * high between frames. That means the active clock is in LO state.
+ */
+#define SSP_CPOL_HI				((uint32_t)(0))
+#define SSP_CPOL_LO				SSP_CR0_CPOL_HI
+#define PARAM_SSP_CPOL(n)		((n==SSP_CPOL_HI) || (n==SSP_CPOL_LO))
+
+/** SSP master mode enable */
+#define SSP_SLAVE_MODE			SSP_CR1_SLAVE_EN
+#define SSP_MASTER_MODE			((uint32_t)(0))
+#define PARAM_SSP_MODE(n)		((n==SSP_SLAVE_MODE) || (n==SSP_MASTER_MODE))
+
+/** SSP data bit number defines */
+#define SSP_DATABIT_4		SSP_CR0_DSS(4) 			/*!< Databit number = 4 */
+#define SSP_DATABIT_5		SSP_CR0_DSS(5) 			/*!< Databit number = 5 */
+#define SSP_DATABIT_6		SSP_CR0_DSS(6) 			/*!< Databit number = 6 */
+#define SSP_DATABIT_7		SSP_CR0_DSS(7) 			/*!< Databit number = 7 */
+#define SSP_DATABIT_8		SSP_CR0_DSS(8) 			/*!< Databit number = 8 */
+#define SSP_DATABIT_9		SSP_CR0_DSS(9) 			/*!< Databit number = 9 */
+#define SSP_DATABIT_10		SSP_CR0_DSS(10) 		/*!< Databit number = 10 */
+#define SSP_DATABIT_11		SSP_CR0_DSS(11) 		/*!< Databit number = 11 */
+#define SSP_DATABIT_12		SSP_CR0_DSS(12) 		/*!< Databit number = 12 */
+#define SSP_DATABIT_13		SSP_CR0_DSS(13) 		/*!< Databit number = 13 */
+#define SSP_DATABIT_14		SSP_CR0_DSS(14) 		/*!< Databit number = 14 */
+#define SSP_DATABIT_15		SSP_CR0_DSS(15) 		/*!< Databit number = 15 */
+#define SSP_DATABIT_16		SSP_CR0_DSS(16) 		/*!< Databit number = 16 */
+#define PARAM_SSP_DATABIT(n) 	((n==SSP_DATABIT_4) || (n==SSP_DATABIT_5) \
+|| (n==SSP_DATABIT_6) || (n==SSP_DATABIT_16) \
+|| (n==SSP_DATABIT_7) || (n==SSP_DATABIT_8) \
+|| (n==SSP_DATABIT_9) || (n==SSP_DATABIT_10) \
+|| (n==SSP_DATABIT_11) || (n==SSP_DATABIT_12) \
+|| (n==SSP_DATABIT_13) || (n==SSP_DATABIT_14) \
+|| (n==SSP_DATABIT_15))
+
+/** SSP Frame Format definition */
+/** Motorola SPI mode */
+#define SSP_FRAME_SPI		SSP_CR0_FRF_SPI
+/** TI synchronous serial mode */
+#define SSP_FRAME_TI		SSP_CR0_FRF_TI
+/** National Micro-wire mode */
+#define SSP_FRAME_MICROWIRE	SSP_CR0_FRF_MICROWIRE
+
+#define PARAM_SSP_FRAME(n) ((n==SSP_FRAME_SPI) || (n==SSP_FRAME_TI)\
+|| (n==SSP_FRAME_MICROWIRE))
+
+
+/*********************************************************************//**
+ * SSP Status defines
+ **********************************************************************/
+/** SSP status TX FIFO Empty bit */
+#define SSP_STAT_TXFIFO_EMPTY		SSP_SR_TFE
+/** SSP status TX FIFO not full bit */
+#define SSP_STAT_TXFIFO_NOTFULL		SSP_SR_TNF
+/** SSP status RX FIFO not empty bit */
+#define SSP_STAT_RXFIFO_NOTEMPTY	SSP_SR_RNE
+/** SSP status RX FIFO full bit */
+#define SSP_STAT_RXFIFO_FULL		SSP_SR_RFF
+/** SSP status SSP Busy bit */
+#define SSP_STAT_BUSY				SSP_SR_BSY
+
+#define PARAM_SSP_STAT(n) ((n==SSP_STAT_TXFIFO_EMPTY) || (n==SSP_STAT_TXFIFO_NOTFULL) \
+|| (n==SSP_STAT_RXFIFO_NOTEMPTY) || (n==SSP_STAT_RXFIFO_FULL) \
+|| (n==SSP_STAT_BUSY))
+
+
+/*********************************************************************//**
+ * SSP Interrupt Configuration defines
+ **********************************************************************/
+/** Receive Overrun */
+#define SSP_INTCFG_ROR		SSP_IMSC_ROR
+/** Receive TimeOut */
+#define SSP_INTCFG_RT		SSP_IMSC_RT
+/** Rx FIFO is at least half full */
+#define SSP_INTCFG_RX		SSP_IMSC_RX
+/** Tx FIFO is at least half empty */
+#define SSP_INTCFG_TX		SSP_IMSC_TX
+
+#define PARAM_SSP_INTCFG(n)	((n==SSP_INTCFG_ROR) || (n==SSP_INTCFG_RT) \
+|| (n==SSP_INTCFG_RX) || (n==SSP_INTCFG_TX))
+
+
+/*********************************************************************//**
+ * SSP Configured Interrupt Status defines
+ **********************************************************************/
+/** Receive Overrun */
+#define SSP_INTSTAT_ROR		SSP_MIS_ROR
+/** Receive TimeOut */
+#define SSP_INTSTAT_RT		SSP_MIS_RT
+/** Rx FIFO is at least half full */
+#define SSP_INTSTAT_RX		SSP_MIS_RX
+/** Tx FIFO is at least half empty */
+#define SSP_INTSTAT_TX		SSP_MIS_TX
+
+#define PARAM_SSP_INTSTAT(n) ((n==SSP_INTSTAT_ROR) || (n==SSP_INTSTAT_RT) \
+|| (n==SSP_INTSTAT_RX) || (n==SSP_INTSTAT_TX))
+
+
+/*********************************************************************//**
+ * SSP Raw Interrupt Status defines
+ **********************************************************************/
+/** Receive Overrun */
+#define SSP_INTSTAT_RAW_ROR		SSP_RIS_ROR
+/** Receive TimeOut */
+#define SSP_INTSTAT_RAW_RT		SSP_RIS_RT
+/** Rx FIFO is at least half full */
+#define SSP_INTSTAT_RAW_RX		SSP_RIS_RX
+/** Tx FIFO is at least half empty */
+#define SSP_INTSTAT_RAW_TX		SSP_RIS_TX
+
+#define PARAM_SSP_INTSTAT_RAW(n)	((n==SSP_INTSTAT_RAW_ROR) || (n==SSP_INTSTAT_RAW_RT) \
+|| (n==SSP_INTSTAT_RAW_RX) || (n==SSP_INTSTAT_RAW_TX))
+
+
+/*********************************************************************//**
+ * SSP Interrupt Clear defines
+ **********************************************************************/
+/** Writing a 1 to this bit clears the "frame was received when
+ * RxFIFO was full" interrupt */
+#define SSP_INTCLR_ROR		SSP_ICR_ROR
+/** Writing a 1 to this bit clears the "Rx FIFO was not empty and
+ * has not been read for a timeout period" interrupt */
+#define SSP_INTCLR_RT		SSP_ICR_RT
+
+#define PARAM_SSP_INTCLR(n)	((n==SSP_INTCLR_ROR) || (n==SSP_INTCLR_RT))
+
+
+/*********************************************************************//**
+ * SSP DMA defines
+ **********************************************************************/
+/** SSP bit for enabling RX DMA */
+#define SSP_DMA_TX		SSP_DMA_RXDMA_EN
+/** SSP bit for enabling TX DMA */
+#define SSP_DMA_RX		SSP_DMA_TXDMA_EN
+
+#define PARAM_SSP_DMA(n)	((n==SSP_DMA_TX) || (n==SSP_DMA_RX))
+
+/* SSP Status Implementation definitions */
+#define SSP_STAT_DONE		(1UL<<8)		/**< Done */
+#define SSP_STAT_ERROR		(1UL<<9)		/**< Error */
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup SSP_Public_Functions
+ * @{
+ */
+
+void SSP_SetClock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock);
+void SSP_DeInit(LPC_SSP_TypeDef* SSPx);
+void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct);
+void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct);
+void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState);
+void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState);
+void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState);
+void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data);
+uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx);
+int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \
+						SSP_TRANSFER_Type xfType);
+FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType);
+void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState);
+IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType);
+IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType);
+void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType);
+void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState);
+void SSP0_StdIntHandler(void);
+void SSP1_StdIntHandler(void);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LPC17XX_SSP_H_ */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.c
new file mode 100644
index 0000000..35f0e94
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.c
@@ -0,0 +1,1538 @@
+/**
+ * @file	: lpc17xx_uart.c
+ * @brief	: Contains all functions support for UART firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 18. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **********************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @addtogroup UART
+ * @{
+ */
+
+/* Includes ------------------------------------------------------------------- */
+#include "lpc17xx_uart.h"
+#include "lpc17xx_clkpwr.h"
+
+/* If this source file built with example, the LPC17xx FW library configuration
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,
+ * otherwise the default FW library configuration file must be included instead
+ */
+#ifdef __BUILD_WITH_EXAMPLE__
+#include "lpc17xx_libcfg.h"
+#else
+#include "lpc17xx_libcfg_default.h"
+#endif /* __BUILD_WITH_EXAMPLE__ */
+
+
+#ifdef _UART
+
+/* Private Types -------------------------------------------------------------- */
+/** @defgroup UART_Private_Types
+ * @{
+ */
+
+/**
+ * @brief UART call-back function type definitions
+ */
+typedef struct {
+	fnTxCbs_Type *pfnTxCbs; 	// Transmit callback
+	fnRxCbs_Type *pfnRxCbs;		// Receive callback
+	fnABCbs_Type *pfnABCbs;		// Auto-Baudrate callback
+	fnErrCbs_Type *pfnErrCbs;	// Error callback
+} UART_CBS_Type;
+
+/**
+ * @}
+ */
+
+
+/* Private Variables ---------------------------------------------------------- */
+/** @defgroup UART_Private_Variables
+ * @{
+ */
+
+
+/** Call-back function pointer data */
+UART_CBS_Type uartCbsDat[4] = {
+		{NULL, NULL, NULL, NULL},
+		{NULL, NULL, NULL, NULL},
+		{NULL, NULL, NULL, NULL},
+		{NULL, NULL, NULL, NULL},
+};
+
+/** UART1 modem status interrupt callback pointer data */
+fnModemCbs_Type *pfnModemCbs = NULL;
+
+/**
+ * @}
+ */
+
+
+/* Private Functions ---------------------------------------------------------- */
+/** @defgroup UART_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief		Get UART number due to UART peripheral pointer
+ * @param[in]	UARTx	UART pointer
+ * @return		UART number
+ */
+uint8_t getUartNum(LPC_UART_TypeDef *UARTx) {
+	if (UARTx == LPC_UART0) return (0);
+	else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1) return (1);
+	else if (UARTx == LPC_UART2) return (2);
+	else return (3);
+}
+
+/*********************************************************************//**
+ * @brief		Determines best dividers to get a target clock rate
+ * @param[in]	UARTx	Pointer to selected UART peripheral, should be
+ * 						UART0, UART1, UART2 or UART3.
+ * @param[in]	baudrate Desired UART baud rate.
+ * @return 		Error status.
+ **********************************************************************/
+
+Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate)
+{
+	Status errorStatus = ERROR;
+
+	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 */
+	if (UARTx == LPC_UART0)
+	{
+		uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0);
+	}
+	else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1)
+	{
+		uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1);
+	}
+	else if (UARTx == LPC_UART2)
+	{
+		uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2);
+	}
+	else if (UARTx == LPC_UART3)
+	{
+		uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3);
+	}
+
+
+	uClk = uClk >> 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 * UART_ACCEPTED_BAUDRATE_ERROR)/100))
+	{
+		if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+		{
+			((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
+			((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);
+			((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);
+			/* Then reset DLAB bit */
+			((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
+			((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \
+					| UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;
+		}
+		else
+		{
+			UARTx->LCR |= UART_LCR_DLAB_EN;
+			UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);
+			UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);
+			/* Then reset DLAB bit */
+			UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
+			UARTx->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \
+					| UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;
+		}
+		errorStatus = SUCCESS;
+	}
+
+	return errorStatus;
+}
+
+/*********************************************************************//**
+ * @brief		General UART interrupt handler and router
+ * @param[in]	UARTx	Selected UART peripheral, should be UART0..3
+ * @return		None
+ *
+ * Note:
+ * - Handles transmit, receive, and status interrupts for the UART.
+ * Based on the interrupt status, routes the interrupt to the
+ * respective call-back to be handled by the user application using
+ * this driver.
+ * - If callback is not installed, corresponding interrupt will be disabled
+ * - All these interrupt source below will be checked:
+ *   		- Transmit Holding Register Empty.
+ * 			- Received Data Available and Character Time Out.
+ * 			- Receive Line Status (not implemented)
+ * 			- End of auto-baud interrupt (not implemented)
+ * 			- Auto-Baudrate Time-Out interrupt (not implemented)
+ * 			- Modem Status interrupt (UART0 Modem functionality)
+ * 			- CTS signal transition interrupt (UART0 Modem functionality)
+ **********************************************************************/
+void UART_GenIntHandler(LPC_UART_TypeDef *UARTx)
+{
+	uint8_t pUart, modemsts;
+	uint32_t intsrc, tmp, tmp1;
+
+	pUart = getUartNum(UARTx);
+
+	/* Determine the interrupt source */
+	intsrc = UARTx->IIR;
+	tmp = intsrc & UART_IIR_INTID_MASK;
+
+	/*
+	 * In case of using UART1 with full modem,
+	 * interrupt ID = 0 that means modem status interrupt has been detected
+	 */
+	if (pUart == 1) {
+		if (tmp == 0){
+			// Check Modem status
+			modemsts = LPC_UART1->MSR & UART1_MSR_BITMASK;
+			// Call modem status call-back
+			if (pfnModemCbs != NULL){
+				pfnModemCbs(modemsts);
+			}
+			// disable modem status interrupt and CTS status change interrupt
+			// if its callback is not installed
+			else {
+				LPC_UART1->IER &= ~(UART1_IER_MSINT_EN | UART1_IER_CTSINT_EN);
+			}
+		}
+	}
+
+	// Receive Line Status
+	if (tmp == UART_IIR_INTID_RLS){
+		// Check line status
+		tmp1 = UARTx->LSR;
+		// Mask out the Receive Ready and Transmit Holding empty status
+		tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \
+				| UART_LSR_BI | UART_LSR_RXFE);
+		// If any error exist
+		if (tmp1) {
+			// Call Call-back function with error input value
+			if (uartCbsDat[pUart].pfnErrCbs != NULL) {
+				uartCbsDat[pUart].pfnErrCbs(tmp1);
+			}
+			// Disable interrupt if its call-back is not install
+			else {
+				UARTx->IER &= ~(UART_IER_RLSINT_EN);
+			}
+		}
+	}
+
+	// Receive Data Available or Character time-out
+	if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){
+		// Call Rx call back function
+		if (uartCbsDat[pUart].pfnRxCbs != NULL) {
+			uartCbsDat[pUart].pfnRxCbs();
+		}
+		// Disable interrupt if its call-back is not install
+		else {
+			UARTx->IER &= ~(UART_IER_RBRINT_EN);
+		}
+	}
+
+	// Transmit Holding Empty
+	if (tmp == UART_IIR_INTID_THRE){
+		// Call Tx call back function
+		if (uartCbsDat[pUart].pfnTxCbs != NULL) {
+			uartCbsDat[pUart].pfnTxCbs();
+		}
+		// Disable interrupt if its call-back is not install
+		else {
+			UARTx->IER &= ~(UART_IER_THREINT_EN);
+		}
+	}
+
+	intsrc &= (UART_IIR_ABEO_INT | UART_IIR_ABTO_INT);
+	// Check if End of auto-baudrate interrupt or Auto baudrate time out
+	if (intsrc){
+		// Clear interrupt pending
+		UARTx->ACR |= ((intsrc & UART_IIR_ABEO_INT) ? UART_ACR_ABEOINT_CLR : 0) \
+						| ((intsrc & UART_IIR_ABTO_INT) ? UART_ACR_ABTOINT_CLR : 0);
+		if (uartCbsDat[pUart].pfnABCbs != NULL) {
+			uartCbsDat[pUart].pfnABCbs(intsrc);
+		} else {
+			// Disable End of AB interrupt
+			UARTx->IER &= ~(UART_IER_ABEOINT_EN | UART_IER_ABTOINT_EN);
+		}
+	}
+}
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @addtogroup UART_Public_Functions
+ * @{
+ */
+
+/*********************************************************************//**
+ * @brief		De-initializes the UARTx peripheral registers to their
+*                  default reset values.
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @return 		None
+ **********************************************************************/
+void UART_DeInit(LPC_UART_TypeDef* UARTx)
+{
+	// For debug mode
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+
+	UART_TxCmd(UARTx, DISABLE);
+
+#ifdef _UART0
+	if (UARTx == LPC_UART0)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE);
+	}
+#endif
+
+#ifdef _UART1
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE);
+	}
+#endif
+
+#ifdef _UART2
+	if (UARTx == LPC_UART2)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE);
+	}
+#endif
+
+#ifdef _UART3
+	if (UARTx == LPC_UART3)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE);
+	}
+#endif
+}
+
+/********************************************************************//**
+ * @brief		Initializes the UARTx peripheral according to the specified
+*               parameters in the UART_ConfigStruct.
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @param[in]	UART_ConfigStruct Pointer to a UART_CFG_Type structure
+*                    that contains the configuration information for the
+*                    specified UART peripheral.
+ * @return 		None
+ *********************************************************************/
+void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct)
+{
+	uint32_t tmp;
+
+	// For debug mode
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+	CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits));
+	CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits));
+	CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity));
+
+#ifdef _UART0
+	if(UARTx == LPC_UART0)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE);
+	}
+#endif
+
+#ifdef _UART1
+	if(((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE);
+	}
+#endif
+
+#ifdef _UART2
+	if(UARTx == LPC_UART2)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE);
+	}
+#endif
+
+#ifdef _UART3
+	if(UARTx == LPC_UART3)
+	{
+		/* Set up clock and power for UART module */
+		CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE);
+	}
+#endif
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		/* FIFOs are empty */
+		((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \
+				| UART_FCR_RX_RS | UART_FCR_TX_RS);
+		// Disable FIFO
+		((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = 0;
+
+		// Dummy reading
+		while (((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_RDR)
+		{
+			tmp = ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR;
+		}
+
+		((LPC_UART1_TypeDef *)UARTx)->TER = UART_TER_TXEN;
+		// Wait for current transmit complete
+		while (!(((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_THRE));
+		// Disable Tx
+		((LPC_UART1_TypeDef *)UARTx)->TER = 0;
+
+		// Disable interrupt
+		((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER = 0;
+		// Set LCR to default state
+		((LPC_UART1_TypeDef *)UARTx)->LCR = 0;
+		// Set ACR to default state
+		((LPC_UART1_TypeDef *)UARTx)->ACR = 0;
+		// Set Modem Control to default state
+		((LPC_UART1_TypeDef *)UARTx)->MCR = 0;
+		// Set RS485 control to default state
+		((LPC_UART1_TypeDef *)UARTx)->RS485CTRL = 0;
+		// Set RS485 delay timer to default state
+		((LPC_UART1_TypeDef *)UARTx)->RS485DLY = 0;
+		// Set RS485 addr match to default state
+		((LPC_UART1_TypeDef *)UARTx)->ADRMATCH = 0;
+		//Dummy Reading to Clear Status
+		tmp = ((LPC_UART1_TypeDef *)UARTx)->MSR;
+		tmp = ((LPC_UART1_TypeDef *)UARTx)->LSR;
+	}
+	else
+	{
+		/* FIFOs are empty */
+		UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS);
+		// Disable FIFO
+		UARTx->/*IIFCR.*/FCR = 0;
+
+		// Dummy reading
+		while (UARTx->LSR & UART_LSR_RDR)
+		{
+			tmp = UARTx->/*RBTHDLR.*/RBR;
+		}
+
+		UARTx->TER = UART_TER_TXEN;
+		// Wait for current transmit complete
+		while (!(UARTx->LSR & UART_LSR_THRE));
+		// Disable Tx
+		UARTx->TER = 0;
+
+		// Disable interrupt
+		UARTx->/*DLIER.*/IER = 0;
+		// Set LCR to default state
+		UARTx->LCR = 0;
+		// Set ACR to default state
+		UARTx->ACR = 0;
+		// Dummy reading
+		tmp = UARTx->LSR;
+	}
+
+	if (UARTx == LPC_UART3)
+	{
+		// Set IrDA to default state
+		UARTx->ICR = 0;
+	}
+
+	// Set Line Control register ----------------------------
+
+	uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate));
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		tmp = (((LPC_UART1_TypeDef *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \
+				& UART_LCR_BITMASK;
+	}
+	else
+	{
+		tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK;
+	}
+
+	switch (UART_ConfigStruct->Databits){
+	case UART_DATABIT_5:
+		tmp |= UART_LCR_WLEN5;
+		break;
+	case UART_DATABIT_6:
+		tmp |= UART_LCR_WLEN6;
+		break;
+	case UART_DATABIT_7:
+		tmp |= UART_LCR_WLEN7;
+		break;
+	case UART_DATABIT_8:
+	default:
+		tmp |= UART_LCR_WLEN8;
+		break;
+	}
+
+	if (UART_ConfigStruct->Parity == UART_PARITY_NONE)
+	{
+		// Do nothing...
+	}
+	else
+	{
+		tmp |= UART_LCR_PARITY_EN;
+		switch (UART_ConfigStruct->Parity)
+		{
+		case UART_PARITY_ODD:
+			tmp |= UART_LCR_PARITY_ODD;
+			break;
+
+		case UART_PARITY_EVEN:
+			tmp |= UART_LCR_PARITY_EVEN;
+			break;
+
+		case UART_PARITY_SP_1:
+			tmp |= UART_LCR_PARITY_F_1;
+			break;
+
+		case UART_PARITY_SP_0:
+			tmp |= UART_LCR_PARITY_F_0;
+			break;
+		default:
+			break;
+		}
+	}
+
+	switch (UART_ConfigStruct->Stopbits){
+	case UART_STOPBIT_2:
+		tmp |= UART_LCR_STOPBIT_SEL;
+		break;
+	case UART_STOPBIT_1:
+	default:
+		// Do no thing
+		break;
+	}
+
+
+	// Write back to LCR, configure FIFO and Disable Tx
+	if (((LPC_UART1_TypeDef *)UARTx) ==  LPC_UART1)
+	{
+		((LPC_UART1_TypeDef *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
+	}
+	else
+	{
+		UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);
+	}
+}
+
+
+/*****************************************************************************//**
+* @brief		Fills each UART_InitStruct member with its default value:
+* 				9600 bps
+* 				8-bit data
+* 				1 Stopbit
+* 				None Parity
+* @param[in]	UART_InitStruct Pointer to a UART_CFG_Type structure
+*                    which will be initialized.
+* @return		None
+*******************************************************************************/
+void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct)
+{
+	UART_InitStruct->Baud_rate = 9600;
+	UART_InitStruct->Databits = UART_DATABIT_8;
+	UART_InitStruct->Parity = UART_PARITY_NONE;
+	UART_InitStruct->Stopbits = UART_STOPBIT_1;
+}
+
+
+/*********************************************************************//**
+ * @brief		Transmit a single data through UART peripheral
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @param[in]	Data	Data to transmit (must be 8-bit long)
+ * @return none
+ **********************************************************************/
+void UART_SendData(LPC_UART_TypeDef* UARTx, uint8_t Data)
+{
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
+	}
+	else
+	{
+		UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;
+	}
+
+}
+
+
+/*********************************************************************//**
+ * @brief		Receive a single data from UART peripheral
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @return 		Data received
+ **********************************************************************/
+uint8_t UART_ReceiveData(LPC_UART_TypeDef* UARTx)
+{
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		return (((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);
+	}
+	else
+	{
+		return (UARTx->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Force BREAK character on UART line, output pin UARTx TXD is
+				forced to logic 0.
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @return none
+ **********************************************************************/
+void UART_ForceBreak(LPC_UART_TypeDef* UARTx)
+{
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_BREAK_EN;
+	}
+	else
+	{
+		UARTx->LCR |= UART_LCR_BREAK_EN;
+	}
+}
+
+
+#ifdef _UART3
+
+/*********************************************************************//**
+ * @brief		Enable or disable inverting serial input function of IrDA
+ * 				on UART peripheral.
+ * @param[in]	UARTx UART peripheral selected, should be UART3 (only)
+ * @param[in]	NewState New state of inverting serial input, should be:
+ * 				- ENABLE: Enable this function.
+ * 				- DISABLE: Disable this function.
+ * @return none
+ **********************************************************************/
+void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_UART_IrDA(UARTx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		UARTx->ICR |= UART_ICR_IRDAINV;
+	}
+	else if (NewState == DISABLE)
+	{
+		UARTx->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Enable or disable IrDA function on UART peripheral.
+ * @param[in]	UARTx UART peripheral selected, should be UART3 (only)
+ * @param[in]	NewState New state of IrDA function, should be:
+ * 				- ENABLE: Enable this function.
+ * 				- DISABLE: Disable this function.
+ * @return none
+ **********************************************************************/
+void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_UART_IrDA(UARTx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		UARTx->ICR |= UART_ICR_IRDAEN;
+	}
+	else
+	{
+		UARTx->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Configure Pulse divider for IrDA function on UART peripheral.
+ * @param[in]	UARTx UART peripheral selected, should be UART3 (only)
+ * @param[in]	PulseDiv Pulse Divider value from Peripheral clock,
+ * 				should be one of the following:
+				- UART_IrDA_PULSEDIV2 	: Pulse width = 2 * Tpclk
+				- UART_IrDA_PULSEDIV4 	: Pulse width = 4 * Tpclk
+				- UART_IrDA_PULSEDIV8 	: Pulse width = 8 * Tpclk
+				- UART_IrDA_PULSEDIV16 	: Pulse width = 16 * Tpclk
+				- UART_IrDA_PULSEDIV32 	: Pulse width = 32 * Tpclk
+				- UART_IrDA_PULSEDIV64 	: Pulse width = 64 * Tpclk
+				- UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk
+				- UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk
+
+ * @return none
+ **********************************************************************/
+void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv)
+{
+	uint32_t tmp, tmp1;
+	CHECK_PARAM(PARAM_UART_IrDA(UARTx));
+	CHECK_PARAM(PARAM_UART_IrDA_PULSEDIV(PulseDiv));
+
+	tmp1 = UART_ICR_PULSEDIV(PulseDiv);
+	tmp = UARTx->ICR & (~UART_ICR_PULSEDIV(7));
+	tmp |= tmp1 | UART_ICR_FIXPULSE_EN;
+	UARTx->ICR = tmp & UART_ICR_BITMASK;
+}
+
+#endif
+
+
+/********************************************************************//**
+ * @brief 		Enable or disable specified UART interrupt.
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @param[in]	UARTIntCfg	Specifies the interrupt flag,
+ * 				should be one of the following:
+				- UART_INTCFG_RBR 	:  RBR Interrupt enable
+				- UART_INTCFG_THRE 	:  THR Interrupt enable
+				- UART_INTCFG_RLS 	:  RX line status interrupt enable
+				- UART1_INTCFG_MS	:  Modem status interrupt enable (UART1 only)
+				- UART1_INTCFG_CTS	:  CTS1 signal transition interrupt enable (UART1 only)
+				- UART_INTCFG_ABEO 	:  Enables the end of auto-baud interrupt
+				- UART_INTCFG_ABTO 	:  Enables the auto-baud time-out interrupt
+ * @param[in]	NewState New state of specified UART interrupt type,
+ * 				should be:
+ * 				- ENALBE: Enable this UART interrupt type.
+* 				- DISALBE: Disable this UART interrupt type.
+ * @return 		None
+ *********************************************************************/
+void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, FunctionalState NewState)
+{
+	uint32_t tmp;
+
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	switch(UARTIntCfg){
+		case UART_INTCFG_RBR:
+			tmp = UART_IER_RBRINT_EN;
+			break;
+		case UART_INTCFG_THRE:
+			tmp = UART_IER_THREINT_EN;
+			break;
+		case UART_INTCFG_RLS:
+			tmp = UART_IER_RLSINT_EN;
+			break;
+		case UART1_INTCFG_MS:
+			tmp = UART1_IER_MSINT_EN;
+			break;
+		case UART1_INTCFG_CTS:
+			tmp = UART1_IER_CTSINT_EN;
+			break;
+		case UART_INTCFG_ABEO:
+			tmp = UART_IER_ABEOINT_EN;
+			break;
+		case UART_INTCFG_ABTO:
+			tmp = UART_IER_ABTOINT_EN;
+			break;
+	}
+
+	if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
+	{
+		CHECK_PARAM((PARAM_UART_INTCFG(UARTIntCfg)) || (PARAM_UART1_INTCFG(UARTIntCfg)));
+	}
+	else
+	{
+		CHECK_PARAM(PARAM_UART_INTCFG(UARTIntCfg));
+	}
+
+	if (NewState == ENABLE)
+	{
+		if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
+		{
+			((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER |= tmp;
+		}
+		else
+		{
+			UARTx->/*DLIER.*/IER |= tmp;
+		}
+	}
+	else
+	{
+		if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)
+		{
+			((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER &= (~tmp) & UART1_IER_BITMASK;
+		}
+		else
+		{
+			UARTx->/*DLIER.*/IER &= (~tmp) & UART_IER_BITMASK;
+		}
+	}
+}
+
+
+/********************************************************************//**
+ * @brief 		Get current value of Line Status register in UART peripheral.
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @return		Current value of Line Status register in UART peripheral.
+ * Note:	The return value of this function must be ANDed with each member in
+ * 			UART_LS_Type enumeration to determine current flag status
+ * 			corresponding to each Line status type. Because some flags in
+ * 			Line Status register will be cleared after reading, the next reading
+ * 			Line Status register could not be correct. So this function used to
+ * 			read Line status register in one time only, then the return value
+ * 			used to check all flags.
+ *********************************************************************/
+uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx)
+{
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		return ((((LPC_UART1_TypeDef *)LPC_UART1)->LSR) & UART_LSR_BITMASK);
+	}
+	else
+	{
+		return ((UARTx->LSR) & UART_LSR_BITMASK);
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Check whether if UART is busy or not
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @return		RESET if UART is not busy, otherwise return SET.
+ **********************************************************************/
+FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx)
+{
+	if (UARTx->LSR & UART_LSR_TEMT){
+		return RESET;
+	} else {
+		return SET;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Configure FIFO function on selected UART peripheral
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @param[in]	FIFOCfg	Pointer to a UART_FIFO_CFG_Type Structure that
+ * 						contains specified information about FIFO configuration
+ * @return 		none
+ **********************************************************************/
+void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg)
+{
+	uint8_t tmp = 0;
+
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+	CHECK_PARAM(PARAM_UART_FIFO_LEVEL(FIFOCfg->FIFO_Level));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_DMAMode));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetRxBuf));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetTxBuf));
+
+	tmp |= UART_FCR_FIFO_EN;
+	switch (FIFOCfg->FIFO_Level){
+	case UART_FIFO_TRGLEV0:
+		tmp |= UART_FCR_TRG_LEV0;
+		break;
+	case UART_FIFO_TRGLEV1:
+		tmp |= UART_FCR_TRG_LEV1;
+		break;
+	case UART_FIFO_TRGLEV2:
+		tmp |= UART_FCR_TRG_LEV2;
+		break;
+	case UART_FIFO_TRGLEV3:
+	default:
+		tmp |= UART_FCR_TRG_LEV3;
+		break;
+	}
+
+	if (FIFOCfg->FIFO_ResetTxBuf == ENABLE)
+	{
+		tmp |= UART_FCR_TX_RS;
+	}
+	if (FIFOCfg->FIFO_ResetRxBuf == ENABLE)
+	{
+		tmp |= UART_FCR_RX_RS;
+	}
+	if (FIFOCfg->FIFO_DMAMode == ENABLE)
+	{
+		tmp |= UART_FCR_DMAMODE_SEL;
+	}
+
+
+	//write to FIFO control register
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;
+	}
+	else
+	{
+		UARTx->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;
+	}
+
+}
+
+
+/*****************************************************************************//**
+* @brief		Fills each UART_FIFOInitStruct member with its default value:
+* 				- FIFO_DMAMode = DISABLE
+* 				- FIFO_Level = UART_FIFO_TRGLEV0
+* 				- FIFO_ResetRxBuf = ENABLE
+* 				- FIFO_ResetTxBuf = ENABLE
+* 				- FIFO_State = ENABLE
+
+* @param[in]	UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure
+*                    which will be initialized.
+* @return		None
+*******************************************************************************/
+void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct)
+{
+	UART_FIFOInitStruct->FIFO_DMAMode = DISABLE;
+	UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0;
+	UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE;
+	UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE;
+}
+
+
+/*********************************************************************//**
+ * @brief		Start/Stop Auto Baudrate activity
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @param[in]	ABConfigStruct	A pointer to UART_AB_CFG_Type structure that
+ * 								contains specified information about UART
+ * 								auto baudrate configuration
+ * @param[in]	NewState New State of Auto baudrate activity, should be:
+ * 				- ENABLE: Start this activity
+ *				- DISABLE: Stop this activity
+ * Note:		Auto-baudrate mode enable bit will be cleared once this mode
+ * 				completed.
+ * @return 		none
+ **********************************************************************/
+void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \
+				FunctionalState NewState)
+{
+	uint32_t tmp;
+
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	tmp = 0;
+	if (NewState == ENABLE) {
+		if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1){
+			tmp |= UART_ACR_MODE;
+		}
+		if (ABConfigStruct->AutoRestart == ENABLE){
+			tmp |= UART_ACR_AUTO_RESTART;
+		}
+	}
+
+	if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+	{
+		if (NewState == ENABLE)
+		{
+			// Clear DLL and DLM value
+			((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
+			((LPC_UART1_TypeDef *)UARTx)->DLL = 0;
+			((LPC_UART1_TypeDef *)UARTx)->DLM = 0;
+			((LPC_UART1_TypeDef *)UARTx)->LCR &= ~UART_LCR_DLAB_EN;
+			// FDR value must be reset to default value
+			((LPC_UART1_TypeDef *)UARTx)->FDR = 0x10;
+			((LPC_UART1_TypeDef *)UARTx)->ACR = UART_ACR_START | tmp;
+		}
+		else
+		{
+			((LPC_UART1_TypeDef *)UARTx)->ACR = 0;
+		}
+	}
+	else
+	{
+		if (NewState == ENABLE)
+		{
+			// Clear DLL and DLM value
+			UARTx->LCR |= UART_LCR_DLAB_EN;
+			UARTx->DLL = 0;
+			UARTx->DLM = 0;
+			UARTx->LCR &= ~UART_LCR_DLAB_EN;
+			// FDR value must be reset to default value
+			UARTx->FDR = 0x10;
+			UARTx->ACR = UART_ACR_START | tmp;
+		}
+		else
+		{
+			UARTx->ACR = 0;
+		}
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Enable/Disable transmission on UART TxD pin
+ * @param[in]	UARTx	UART peripheral selected, should be UART0, UART1,
+ * 						UART2 or UART3.
+ * @param[in]	NewState New State of Tx transmission function, should be:
+ * 				- ENABLE: Enable this function
+				- DISABLE: Disable this function
+ * @return none
+ **********************************************************************/
+void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState)
+{
+	CHECK_PARAM(PARAM_UARTx(UARTx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	if (NewState == ENABLE)
+	{
+		if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+		{
+			((LPC_UART1_TypeDef *)UARTx)->TER |= UART_TER_TXEN;
+		}
+		else
+		{
+			UARTx->TER |= UART_TER_TXEN;
+		}
+	}
+	else
+	{
+		if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
+		{
+			((LPC_UART1_TypeDef *)UARTx)->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;
+		}
+		else
+		{
+			UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;
+		}
+	}
+}
+
+#ifdef _UART1
+
+/*********************************************************************//**
+ * @brief		Force pin DTR/RTS corresponding to given state (Full modem mode)
+ * @param[in]	UARTx	UART1 (only)
+ * @param[in]	Pin	Pin that NewState will be applied to, should be:
+ * 				- UART1_MODEM_PIN_DTR: DTR pin.
+ * 				- UART1_MODEM_PIN_RTS: RTS pin.
+ * @param[in]	NewState New State of DTR/RTS pin, should be:
+ * 				- INACTIVE: Force the pin to inactive signal.
+				- ACTIVE: Force the pin to active signal.
+ * @return none
+ **********************************************************************/
+void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \
+							UART1_SignalState NewState)
+{
+	uint8_t tmp = 0;
+
+	CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
+	CHECK_PARAM(PARAM_UART1_MODEM_PIN(Pin));
+	CHECK_PARAM(PARAM_UART1_SIGNALSTATE(NewState));
+
+	switch (Pin){
+	case UART1_MODEM_PIN_DTR:
+		tmp = UART1_MCR_DTR_CTRL;
+		break;
+	case UART1_MODEM_PIN_RTS:
+		tmp = UART1_MCR_RTS_CTRL;
+		break;
+	default:
+		break;
+	}
+
+	if (NewState == ACTIVE){
+		UARTx->MCR |= tmp;
+	} else {
+		UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Configure Full Modem mode for UART peripheral
+ * @param[in]	UARTx	UART1 (only)
+ * @param[in]	Mode Full Modem mode, should be:
+ * 				- UART1_MODEM_MODE_LOOPBACK: Loop back mode.
+ * 				- UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode.
+ * 				- UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode.
+ * @param[in]	NewState New State of this mode, should be:
+ * 				- ENABLE: Enable this mode.
+				- DISABLE: Disable this mode.
+ * @return none
+ **********************************************************************/
+void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \
+							FunctionalState NewState)
+{
+	uint8_t tmp;
+
+	CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
+	CHECK_PARAM(PARAM_UART1_MODEM_MODE(Mode));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
+
+	switch(Mode){
+	case UART1_MODEM_MODE_LOOPBACK:
+		tmp = UART1_MCR_LOOPB_EN;
+		break;
+	case UART1_MODEM_MODE_AUTO_RTS:
+		tmp = UART1_MCR_AUTO_RTS_EN;
+		break;
+	case UART1_MODEM_MODE_AUTO_CTS:
+		tmp = UART1_MCR_AUTO_CTS_EN;
+		break;
+	default:
+		break;
+	}
+
+	if (NewState == ENABLE)
+	{
+		UARTx->MCR |= tmp;
+	}
+	else
+	{
+		UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;
+	}
+}
+
+
+/*********************************************************************//**
+ * @brief		Get current status of modem status register
+ * @param[in]	UARTx	UART1 (only)
+ * @return 		Current value of modem status register
+ * Note:	The return value of this function must be ANDed with each member
+ * 			UART_MODEM_STAT_type enumeration to determine current flag status
+ * 			corresponding to each modem flag status. Because some flags in
+ * 			modem status register will be cleared after reading, the next reading
+ * 			modem register could not be correct. So this function used to
+ * 			read modem status register in one time only, then the return value
+ * 			used to check all flags.
+ **********************************************************************/
+uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx)
+{
+	CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
+	return ((UARTx->MSR) & UART1_MSR_BITMASK);
+}
+
+
+/*********************************************************************//**
+ * @brief		Configure UART peripheral in RS485 mode according to the specified
+*               parameters in the RS485ConfigStruct.
+ * @param[in]	UARTx	UART1 (only)
+ * @param[in]	RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure
+*                    that contains the configuration information for specified UART
+*                    in RS485 mode.
+ * @return		None
+ **********************************************************************/
+void UART_RS485Config(LPC_UART1_TypeDef *UARTx, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct)
+{
+	uint32_t tmp;
+
+	CHECK_PARAM(PARAM_UART1_MODEM(UARTx));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoAddrDetect_State));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoDirCtrl_State));
+	CHECK_PARAM(PARAM_UART1_RS485_CFG_DELAYVALUE(RS485ConfigStruct->DelayValue));
+	CHECK_PARAM(PARAM_SETSTATE(RS485ConfigStruct->DirCtrlPol_Level));
+	CHECK_PARAM(PARAM_UART_RS485_DIRCTRL_PIN(RS485ConfigStruct->DirCtrlPin));
+	CHECK_PARAM(PARAM_UART1_RS485_CFG_MATCHADDRVALUE(RS485ConfigStruct->MatchAddrValue));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->NormalMultiDropMode_State));
+	CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->Rx_State));
+
+	tmp = 0;
+	// If Auto Direction Control is enabled -  This function is used in Master mode
+	if (RS485ConfigStruct->AutoDirCtrl_State == ENABLE)
+	{
+		tmp |= UART1_RS485CTRL_DCTRL_EN;
+
+		// Set polar
+		if (RS485ConfigStruct->DirCtrlPol_Level == SET)
+		{
+			tmp |= UART1_RS485CTRL_OINV_1;
+		}
+
+		// Set pin according to
+		if (RS485ConfigStruct->DirCtrlPin == UART1_RS485_DIRCTRL_DTR)
+		{
+			tmp |= UART1_RS485CTRL_SEL_DTR;
+		}
+
+		// Fill delay time
+		UARTx->RS485DLY = RS485ConfigStruct->DelayValue & UART1_RS485DLY_BITMASK;
+	}
+
+	// MultiDrop mode is enable
+	if (RS485ConfigStruct->NormalMultiDropMode_State == ENABLE)
+	{
+		tmp |= UART1_RS485CTRL_NMM_EN;
+	}
+
+	// Auto Address Detect function
+	if (RS485ConfigStruct->AutoAddrDetect_State == ENABLE)
+	{
+		tmp |= UART1_RS485CTRL_AADEN;
+		// Fill Match Address
+		UARTx->ADRMATCH = RS485ConfigStruct->MatchAddrValue & UART1_RS485ADRMATCH_BITMASK;
+	}
+
+
+	// Receiver is disable
+	if (RS485ConfigStruct->Rx_State == DISABLE)
+	{
+		tmp |= UART1_RS485CTRL_RX_DIS;
+	}
+
+	// write back to RS485 control register
+	UARTx->RS485CTRL = tmp & UART1_RS485CTRL_BITMASK;
+
+	// Enable Parity function and leave parity in stick '0' parity as default
+	UARTx->LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN);
+}
+
+
+/**
+ * @brief 		Enable/Disable receiver in RS485 module in UART1
+ * @param[in]	UARTx 		UART1 only.
+ * @param[in]	NewState	New State of command, should be:
+ * 							- ENABLE: Enable this function.
+ * 							- DISABLE: Disable this function.
+ * @return		None
+ */
+void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState)
+{
+	if (NewState == ENABLE){
+		UARTx->RS485CTRL &= ~UART1_RS485CTRL_RX_DIS;
+	} else {
+		UARTx->RS485CTRL |= UART1_RS485CTRL_RX_DIS;
+	}
+}
+
+
+/**
+ * @brief 		Send data on RS485 bus with specified parity stick value (9-bit mode).
+ * @param[in]	UARTx 		UART1 (only).
+ * @param[in]	pDatFrm 	Pointer to data frame.
+ * @param[in]	size		Size of data.
+ * @param[in]	ParityStick	Parity Stick value, should be 0 or 1.
+ * @return		None.
+ */
+uint32_t UART_RS485Send(LPC_UART1_TypeDef *UARTx, uint8_t *pDatFrm, \
+					uint32_t size, uint8_t ParityStick)
+{
+	uint8_t tmp, save;
+	uint32_t cnt;
+
+	if (ParityStick){
+		save = tmp = UARTx->LCR & UART_LCR_BITMASK;
+		tmp &= ~(UART_LCR_PARITY_EVEN);
+		UARTx->LCR = tmp;
+		cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);
+		while (!(UARTx->LSR & UART_LSR_TEMT));
+		UARTx->LCR = save;
+	} else {
+		cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);
+		while (!(UARTx->LSR & UART_LSR_TEMT));
+	}
+	return cnt;
+}
+
+
+/**
+ * @brief 		Send Slave address frames on RS485 bus.
+ * @param[in]	UARTx UART1 (only).
+ * @param[in]	SlvAddr Slave Address.
+ * @return		None.
+ */
+void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr)
+{
+	UART_RS485Send(UARTx, &SlvAddr, 1, 1);
+}
+
+
+/**
+ * @brief 		Send Data frames on RS485 bus.
+ * @param[in]	UARTx UART1 (only).
+ * @param[in]	pData Pointer to data to be sent.
+ * @param[in]	size Size of data frame to be sent.
+ * @return		None.
+ */
+uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size)
+{
+	return (UART_RS485Send(UARTx, pData, size, 0));
+}
+
+#endif /* _UART1 */
+
+
+/* Additional driver APIs ----------------------------------------------------------------------- */
+
+/*********************************************************************//**
+ * @brief		Send a block of data via UART peripheral
+ * @param[in]	UARTx	Selected UART peripheral used to send data,
+ * 				should be UART0, UART1, UART2 or UART3.
+ * @param[in]	txbuf 	Pointer to Transmit buffer
+ * @param[in]	buflen 	Length of Transmit buffer
+ * @param[in] 	flag 	Flag used in  UART transfer, should be
+ * 						NONE_BLOCKING or BLOCKING
+ * @return 		Number of bytes sent.
+ *
+ * Note: when using UART in BLOCKING mode, a time-out condition is used
+ * via defined symbol UART_BLOCKING_TIMEOUT.
+ **********************************************************************/
+uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,
+		uint32_t buflen, TRANSFER_BLOCK_Type flag)
+{
+	uint32_t bToSend, bSent, timeOut, fifo_cnt;
+	uint8_t *pChar = txbuf;
+
+	bToSend = buflen;
+
+	// blocking mode
+	if (flag == BLOCKING) {
+		bSent = 0;
+		while (bToSend){
+			timeOut = UART_BLOCKING_TIMEOUT;
+			// Wait for THR empty with timeout
+			while (!(UARTx->LSR & UART_LSR_THRE)) {
+				if (timeOut == 0) break;
+				timeOut--;
+			}
+			// Time out!
+			if(timeOut == 0) break;
+			fifo_cnt = UART_TX_FIFO_SIZE;
+			while (fifo_cnt && bToSend){
+				UART_SendData(UARTx, (*pChar++));
+				fifo_cnt--;
+				bToSend--;
+				bSent++;
+			}
+		}
+	}
+	// None blocking mode
+	else {
+		bSent = 0;
+		while (bToSend) {
+			if (!(UARTx->LSR & UART_LSR_THRE)){
+				break;
+			}
+			fifo_cnt = UART_TX_FIFO_SIZE;
+			while (fifo_cnt && bToSend) {
+				UART_SendData(UARTx, (*pChar++));
+				bToSend--;
+				fifo_cnt--;
+				bSent++;
+			}
+		}
+	}
+	return bSent;
+}
+
+/*********************************************************************//**
+ * @brief		Receive a block of data via UART peripheral
+ * @param[in]	UARTx	Selected UART peripheral used to send data,
+ * 				should be UART0, UART1, UART2 or UART3.
+ * @param[out]	rxbuf 	Pointer to Received buffer
+ * @param[in]	buflen 	Length of Received buffer
+ * @param[in] 	flag 	Flag mode, should be NONE_BLOCKING or BLOCKING
+
+ * @return 		Number of bytes received
+ *
+ * Note: when using UART in BLOCKING mode, a time-out condition is used
+ * via defined symbol UART_BLOCKING_TIMEOUT.
+ **********************************************************************/
+uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \
+		uint32_t buflen, TRANSFER_BLOCK_Type flag)
+{
+	uint32_t bToRecv, bRecv, timeOut;
+	uint8_t *pChar = rxbuf;
+
+	bToRecv = buflen;
+
+	// Blocking mode
+	if (flag == BLOCKING) {
+		bRecv = 0;
+		while (bToRecv){
+			timeOut = UART_BLOCKING_TIMEOUT;
+			while (!(UARTx->LSR & UART_LSR_RDR)){
+				if (timeOut == 0) break;
+				timeOut--;
+			}
+			// Time out!
+			if(timeOut == 0) break;
+			// Get data from the buffer
+			(*pChar++) = UART_ReceiveData(UARTx);
+			bToRecv--;
+			bRecv++;
+		}
+	}
+	// None blocking mode
+	else {
+		bRecv = 0;
+		while (bToRecv) {
+			if (!(UARTx->LSR & UART_LSR_RDR)) {
+				break;
+			} else {
+				(*pChar++) = UART_ReceiveData(UARTx);
+				bRecv++;
+				bToRecv--;
+			}
+		}
+	}
+	return bRecv;
+}
+
+
+/*********************************************************************//**
+ * @brief		Setup call-back function for UART interrupt handler for each
+ * 				UART peripheral
+ * @param[in]	UARTx	Selected UART peripheral, should be UART0..3
+ * @param[in]	CbType	Call-back type, should be:
+ * 						0 - Receive Call-back
+ * 						1 - Transmit Call-back
+ * 						2 - Auto Baudrate Callback
+ * 						3 - Error Call-back
+ * 						4 - Modem Status Call-back (UART1 only)
+ * @param[in]	pfnCbs	Pointer to Call-back function
+ * @return		None
+ **********************************************************************/
+void UART_SetupCbs(LPC_UART_TypeDef *UARTx, uint8_t CbType, void *pfnCbs)
+{
+	uint8_t pUartNum;
+
+	pUartNum = getUartNum(UARTx);
+	switch(CbType){
+	case 0:
+		uartCbsDat[pUartNum].pfnRxCbs = (fnTxCbs_Type *)pfnCbs;
+		break;
+	case 1:
+		uartCbsDat[pUartNum].pfnTxCbs = (fnRxCbs_Type *)pfnCbs;
+		break;
+	case 2:
+		uartCbsDat[pUartNum].pfnABCbs = (fnABCbs_Type *)pfnCbs;
+		break;
+	case 3:
+		uartCbsDat[pUartNum].pfnErrCbs = (fnErrCbs_Type *)pfnCbs;
+		break;
+	case 4:
+		pfnModemCbs = (fnModemCbs_Type *)pfnCbs;
+		break;
+	default:
+		break;
+	}
+}
+
+/*********************************************************************//**
+ * @brief		Standard UART0 interrupt handler
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void UART0_StdIntHandler(void)
+{
+	UART_GenIntHandler(LPC_UART0);
+}
+
+/*********************************************************************//**
+ * @brief		Standard UART1 interrupt handler
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void UART1_StdIntHandler(void)
+{
+	UART_GenIntHandler((LPC_UART_TypeDef *)LPC_UART1);
+}
+
+/*********************************************************************//**
+ * @brief		Standard UART2 interrupt handler
+ * @param[in]	None
+ * @return		None
+ **********************************************************************/
+void UART2_StdIntHandler(void)
+{
+	UART_GenIntHandler(LPC_UART2);
+}
+
+/*********************************************************************//**
+ * @brief		Standard UART3 interrupt handler
+ * @param[in]	None
+ * @return
+ **********************************************************************/
+void UART3_StdIntHandler(void)
+{
+	UART_GenIntHandler(LPC_UART3);
+}
+
+/**
+ * @}
+ */
+
+
+#endif /* _UART */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
+
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.h
new file mode 100644
index 0000000..84128e2
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/lpc17xx_uart.h
@@ -0,0 +1,633 @@
+/***********************************************************************//**
+ * @file	: lpc17xx_uart.h
+ * @brief	: Contains all macro definitions and function prototypes
+ * 				support for UART firmware library on LPC17xx
+ * @version	: 1.0
+ * @date	: 18. Mar. 2009
+ * @author	: HieuNguyen
+ **************************************************************************
+ * 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.
+ **************************************************************************/
+
+/* Peripheral group ----------------------------------------------------------- */
+/** @defgroup UART
+ * @ingroup LPC1700CMSIS_FwLib_Drivers
+ * @{
+ */
+
+#ifndef __LPC17XX_UART_H
+#define __LPC17XX_UART_H
+
+/* Includes ------------------------------------------------------------------- */
+#include "LPC17xx.h"
+#include "lpc_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* Private Macros ------------------------------------------------------------- */
+/** @defgroup UART_Private_Macros
+ * @{
+ */
+
+
+/** @defgroup UART_REGISTER_BIT_DEFINITIONS
+ * @{
+ */
+
+/* Accepted Error baud rate value (in percent unit) */
+#define UART_ACCEPTED_BAUDRATE_ERROR	(3)			/*!< Acceptable UART baudrate error */
+
+/* Macro defines for UARTn Receiver Buffer Register */
+#define UART_RBR_MASKBIT   	((uint8_t)0xFF) 		/*!< UART Received Buffer mask bit (8 bits) */
+
+/* Macro defines for UARTn Transmit Holding Register */
+#define UART_THR_MASKBIT   	((uint8_t)0xFF) 		/*!< UART Transmit Holding mask bit (8 bits) */
+
+/* Macro defines for UARTn Divisor Latch LSB register */
+#define UART_LOAD_DLL(div)	((div) & 0xFF)	/**< Macro for loading least significant halfs of divisors */
+#define UART_DLL_MASKBIT	((uint8_t)0xFF)	/*!< Divisor latch LSB bit mask */
+
+/* Macro defines for UARTn Divisor Latch MSB register */
+#define UART_DLM_MASKBIT	((uint8_t)0xFF)			/*!< Divisor latch MSB bit mask */
+#define UART_LOAD_DLM(div)  (((div) >> 8) & 0xFF)	/**< Macro for loading most significant halfs of divisors */
+
+
+/* Macro defines for UART interrupt enable register */
+#define UART_IER_RBRINT_EN		((uint32_t)(1<<0)) 	/*!< RBR Interrupt enable*/
+#define UART_IER_THREINT_EN		((uint32_t)(1<<1)) 	/*!< THR Interrupt enable*/
+#define UART_IER_RLSINT_EN		((uint32_t)(1<<2)) 	/*!< RX line status interrupt enable*/
+#define UART1_IER_MSINT_EN		((uint32_t)(1<<3))	/*!< Modem status interrupt enable */
+#define UART1_IER_CTSINT_EN		((uint32_t)(1<<7))	/*!< CTS1 signal transition interrupt enable */
+#define UART_IER_ABEOINT_EN		((uint32_t)(1<<8)) 	/*!< Enables the end of auto-baud interrupt */
+#define UART_IER_ABTOINT_EN		((uint32_t)(1<<9)) 	/*!< Enables the auto-baud time-out interrupt */
+#define UART_IER_BITMASK		((uint32_t)(0x307)) /*!< UART interrupt enable register bit mask */
+#define UART1_IER_BITMASK		((uint32_t)(0x38F)) /*!< UART1 interrupt enable register bit mask */
+
+
+/* UART interrupt identification register defines */
+#define UART_IIR_INTSTAT_PEND	((uint32_t)(1<<0))	/*!<Interrupt Status - Active low */
+#define UART_IIR_INTID_RLS		((uint32_t)(3<<1)) 	/*!<Interrupt identification: Receive line status*/
+#define UART_IIR_INTID_RDA		((uint32_t)(2<<1)) 	/*!<Interrupt identification: Receive data available*/
+#define UART_IIR_INTID_CTI		((uint32_t)(6<<1)) 	/*!<Interrupt identification: Character time-out indicator*/
+#define UART_IIR_INTID_THRE		((uint32_t)(1<<1)) 	/*!<Interrupt identification: THRE interrupt*/
+#define UART1_IIR_INTID_MODEM	((uint32_t)(0<<1)) 	/*!<Interrupt identification: Modem interrupt*/
+#define UART_IIR_INTID_MASK		((uint32_t)(7<<1))	/*!<Interrupt identification: Interrupt ID mask */
+#define UART_IIR_FIFO_EN		((uint32_t)(3<<6)) 	/*!<These bits are equivalent to UnFCR[0] */
+#define UART_IIR_ABEO_INT		((uint32_t)(1<<8)) 	/*!< End of auto-baud interrupt */
+#define UART_IIR_ABTO_INT		((uint32_t)(1<<9)) 	/*!< Auto-baud time-out interrupt */
+#define UART_IIR_BITMASK		((uint32_t)(0x3CF))	/*!< UART interrupt identification register bit mask */
+
+
+/* Macro defines for UART FIFO control register */
+#define UART_FCR_FIFO_EN		((uint8_t)(1<<0)) 	/*!< UART FIFO enable */
+#define UART_FCR_RX_RS			((uint8_t)(1<<1)) 	/*!< UART FIFO RX reset */
+#define UART_FCR_TX_RS			((uint8_t)(1<<2)) 	/*!< UART FIFO TX reset */
+#define UART_FCR_DMAMODE_SEL 	((uint8_t)(1<<3)) 	/*!< UART DMA mode selection */
+#define UART_FCR_TRG_LEV0		((uint8_t)(0)) 		/*!< UART FIFO trigger level 0: 1 character */
+#define UART_FCR_TRG_LEV1		((uint8_t)(1<<6)) 	/*!< UART FIFO trigger level 1: 4 character */
+#define UART_FCR_TRG_LEV2		((uint8_t)(2<<6)) 	/*!< UART FIFO trigger level 2: 8 character */
+#define UART_FCR_TRG_LEV3		((uint8_t)(3<<6)) 	/*!< UART FIFO trigger level 3: 14 character */
+#define UART_FCR_BITMASK		((uint8_t)(0xCF))	/*!< UART FIFO control bit mask */
+#define UART_TX_FIFO_SIZE		(16)
+
+/* Macro defines for UART line control register */
+#define UART_LCR_WLEN5     		((uint8_t)(0))   		/*!< UART 5 bit data mode */
+#define UART_LCR_WLEN6     		((uint8_t)(1<<0))   	/*!< UART 6 bit data mode */
+#define UART_LCR_WLEN7     		((uint8_t)(2<<0))   	/*!< UART 7 bit data mode */
+#define UART_LCR_WLEN8     		((uint8_t)(3<<0))   	/*!< UART 8 bit data mode */
+#define UART_LCR_STOPBIT_SEL	((uint8_t)(1<<2))   	/*!< UART Two Stop Bits Select */
+#define UART_LCR_PARITY_EN		((uint8_t)(1<<3))		/*!< UART Parity Enable */
+#define UART_LCR_PARITY_ODD		((uint8_t)(0))         	/*!< UART Odd Parity Select */
+#define UART_LCR_PARITY_EVEN	((uint8_t)(1<<4))		/*!< UART Even Parity Select */
+#define UART_LCR_PARITY_F_1		((uint8_t)(2<<4))		/*!< UART force 1 stick parity */
+#define UART_LCR_PARITY_F_0		((uint8_t)(3<<4))		/*!< UART force 0 stick parity */
+#define UART_LCR_BREAK_EN		((uint8_t)(1<<6))		/*!< UART Transmission Break enable */
+#define UART_LCR_DLAB_EN		((uint8_t)(1<<7))    	/*!< UART Divisor Latches Access bit enable */
+#define UART_LCR_BITMASK		((uint8_t)(0xFF))		/*!< UART line control bit mask */
+
+
+/* Macro defines for UART1 Modem Control Register */
+#define UART1_MCR_DTR_CTRL		((uint8_t)(1<<0))		/*!< Source for modem output pin DTR */
+#define UART1_MCR_RTS_CTRL		((uint8_t)(1<<1))		/*!< Source for modem output pin RTS */
+#define UART1_MCR_LOOPB_EN		((uint8_t)(1<<4))		/*!< Loop back mode select */
+#define UART1_MCR_AUTO_RTS_EN	((uint8_t)(1<<6))		/*!< Enable Auto RTS flow-control */
+#define UART1_MCR_AUTO_CTS_EN	((uint8_t)(1<<7))		/*!< Enable Auto CTS flow-control */
+#define UART1_MCR_BITMASK		((uint8_t)(0x0F3))		/*!< UART1 bit mask value */
+
+
+/* Macro defines for UART line status register */
+#define UART_LSR_RDR		((uint8_t)(1<<0)) 	/*!<Line status register: Receive data ready*/
+#define UART_LSR_OE			((uint8_t)(1<<1)) 	/*!<Line status register: Overrun error*/
+#define UART_LSR_PE			((uint8_t)(1<<2)) 	/*!<Line status register: Parity error*/
+#define UART_LSR_FE			((uint8_t)(1<<3)) 	/*!<Line status register: Framing error*/
+#define UART_LSR_BI			((uint8_t)(1<<4)) 	/*!<Line status register: Break interrupt*/
+#define UART_LSR_THRE		((uint8_t)(1<<5)) 	/*!<Line status register: Transmit holding register empty*/
+#define UART_LSR_TEMT		((uint8_t)(1<<6)) 	/*!<Line status register: Transmitter empty*/
+#define UART_LSR_RXFE		((uint8_t)(1<<7)) 	/*!<Error in RX FIFO*/
+#define UART_LSR_BITMASK	((uint8_t)(0xFF)) 	/*!<UART Line status bit mask */
+
+
+/* Macro defines for UART Modem (UART1 only) status register */
+#define UART1_MSR_DELTA_CTS		((uint8_t)(1<<0))	/*!< Set upon state change of input CTS */
+#define UART1_MSR_DELTA_DSR		((uint8_t)(1<<1))	/*!< Set upon state change of input DSR */
+#define UART1_MSR_LO2HI_RI		((uint8_t)(1<<2))	/*!< Set upon low to high transition of input RI */
+#define UART1_MSR_DELTA_DCD		((uint8_t)(1<<3))	/*!< Set upon state change of input DCD */
+#define UART1_MSR_CTS			((uint8_t)(1<<4))	/*!< Clear To Send State */
+#define UART1_MSR_DSR			((uint8_t)(1<<5))	/*!< Data Set Ready State */
+#define UART1_MSR_RI			((uint8_t)(1<<6))	/*!< Ring Indicator State */
+#define UART1_MSR_DCD			((uint8_t)(1<<7))	/*!< Data Carrier Detect State */
+#define UART1_MSR_BITMASK		((uint8_t)(0xFF))	/*!< MSR register bit-mask value */
+
+
+/* Macro defines for UART Scratch Pad Register */
+#define UART_SCR_BIMASK		((uint8_t)(0xFF))	/*!< UART Scratch Pad bit mask */
+
+/* Macro defines for UART Auto baudrate control register */
+#define UART_ACR_START				((uint32_t)(1<<0))	/**< UART Auto-baud start */
+#define UART_ACR_MODE				((uint32_t)(1<<1))	/**< UART Auto baudrate Mode 1 */
+#define UART_ACR_AUTO_RESTART		((uint32_t)(1<<2))	/**< UART Auto baudrate restart */
+#define UART_ACR_ABEOINT_CLR		((uint32_t)(1<<8))	/**< UART End of auto-baud interrupt clear */
+#define UART_ACR_ABTOINT_CLR		((uint32_t)(1<<9))	/**< UART Auto-baud time-out interrupt clear */
+#define UART_ACR_BITMASK			((uint32_t)(0x307))	/**< UART Auto Baudrate register bit mask */
+
+/* UART IrDA control register defines */
+#define UART_ICR_IRDAEN			((uint32_t)(1<<0))			/**< IrDA mode enable */
+#define UART_ICR_IRDAINV		((uint32_t)(1<<1))			/**< IrDA serial input inverted */
+#define UART_ICR_FIXPULSE_EN	((uint32_t)(1<<2))			/**< IrDA fixed pulse width mode */
+#define UART_ICR_PULSEDIV(n)	((uint32_t)((n&0x07)<<3))	/**< PulseDiv - Configures the pulse when FixPulseEn = 1 */
+#define UART_ICR_BITMASK		((uint32_t)(0x3F))			/*!< UART IRDA bit mask */
+
+/* Macro defines for UART Fractional divider register */
+#define UART_FDR_DIVADDVAL(n)	((uint32_t)(n&0x0F))		/**< Baud-rate generation pre-scaler divisor */
+#define UART_FDR_MULVAL(n)		((uint32_t)((n<<4)&0xF0))	/**< Baud-rate pre-scaler multiplier value */
+#define UART_FDR_BITMASK		((uint32_t)(0xFF))			/**< UART Fractional Divider register bit mask */
+
+/* Macro defines for UART Tx Enable register */
+#define UART_TER_TXEN			((uint8_t)(1<<7)) 		/*!< Transmit enable bit */
+#define UART_TER_BITMASK		((uint8_t)(0x80))		/**< UART Transmit Enable Register bit mask */
+
+
+/* Macro defines for UART1 RS485 Control register */
+#define UART1_RS485CTRL_NMM_EN		((uint32_t)(1<<0))	/*!< RS-485/EIA-485 Normal Multi-drop Mode (NMM)
+														is disabled */
+#define UART1_RS485CTRL_RX_DIS		((uint32_t)(1<<1))	/*!< The receiver is disabled */
+#define UART1_RS485CTRL_AADEN		((uint32_t)(1<<2))	/*!< Auto Address Detect (AAD) is enabled */
+#define UART1_RS485CTRL_SEL_DTR		((uint32_t)(1<<3))	/*!< If direction control is enabled
+														(bit DCTRL = 1), pin DTR is used for direction control */
+#define UART1_RS485CTRL_DCTRL_EN	((uint32_t)(1<<4))	/*!< Enable Auto Direction Control */
+#define UART1_RS485CTRL_OINV_1		((uint32_t)(1<<5))	/*!< This bit reverses the polarity of the direction
+														control signal on the RTS (or DTR) pin. The direction control pin
+														will be driven to logic "1" when the transmitter has data to be sent */
+#define UART1_RS485CTRL_BITMASK		((uint32_t)(0x3F))	/**< RS485 control bit-mask value */
+
+
+/* Macro defines for UART1 RS-485 Address Match register */
+#define UART1_RS485ADRMATCH_BITMASK ((uint8_t)(0xFF)) 	/**< Bit mask value */
+
+/* Macro defines for UART1 RS-485 Delay value register */
+#define UART1_RS485DLY_BITMASK		((uint8_t)(0xFF)) 	/** Bit mask value */
+
+
+/* Macro defines for UART FIFO Level register */
+#define UART_FIFOLVL_RXFIFOLVL(n)	((uint32_t)(n&0x0F))		/**< Reflects the current level of the UART receiver FIFO */
+#define UART_FIFOLVL_TXFIFOLVL(n)	((uint32_t)((n>>8)&0x0F))	/**< Reflects the current level of the UART transmitter FIFO */
+#define UART_FIFOLVL_BITMASK		((uint32_t)(0x0F0F))		/**< UART FIFO Level Register bit mask */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Public Types --------------------------------------------------------------- */
+/** @defgroup UART_Public_Types
+ * @{
+ */
+
+
+/**
+ * @brief UART Databit type definitions
+ */
+typedef enum {
+	UART_DATABIT_5		= 0,     		/*!< UART 5 bit data mode */
+	UART_DATABIT_6,		     			/*!< UART 6 bit data mode */
+	UART_DATABIT_7,		     			/*!< UART 7 bit data mode */
+	UART_DATABIT_8		     			/*!< UART 8 bit data mode */
+} UART_DATABIT_Type;
+
+/** Macro to check the input UART_DATABIT parameters */
+#define PARAM_UART_DATABIT(databit)	((databit==UART_DATABIT_5) || (databit==UART_DATABIT_6)\
+|| (databit==UART_DATABIT_7) || (databit==UART_DATABIT_8))
+
+/**
+ * @brief UART Stop bit type definitions
+ */
+typedef enum {
+	UART_STOPBIT_1		= (0),   					/*!< UART 1 Stop Bits Select */
+	UART_STOPBIT_2,		 							/*!< UART Two Stop Bits Select */
+} UART_STOPBIT_Type;
+
+/** Macro to check the input UART_STOPBIT parameters */
+#define PARAM_UART_STOPBIT(stopbit)	((stopbit==UART_STOPBIT_1) || (stopbit==UART_STOPBIT_2))
+
+/**
+ * @brief UART Parity type definitions
+ */
+typedef enum {
+	UART_PARITY_NONE 	= 0,					/*!< No parity */
+	UART_PARITY_ODD,	 						/*!< Odd parity */
+	UART_PARITY_EVEN, 							/*!< Even parity */
+	UART_PARITY_SP_1, 							/*!< Forced "1" stick parity */
+	UART_PARITY_SP_0 							/*!< Forced "0" stick parity */
+} UART_PARITY_Type;
+
+/** Macro to check the input UART_PARITY parameters */
+#define PARAM_UART_PARITY(parity)	((parity==UART_PARITY_NONE) || (parity==UART_PARITY_ODD) \
+|| (parity==UART_PARITY_EVEN) || (parity==UART_PARITY_SP_1) \
+|| (parity==UART_PARITY_SP_0))
+
+/**
+ * @brief FIFO Level type definitions
+ */
+typedef enum {
+	UART_FIFO_TRGLEV0 = 0,	/*!< UART FIFO trigger level 0: 1 character */
+	UART_FIFO_TRGLEV1, 		/*!< UART FIFO trigger level 1: 4 character */
+	UART_FIFO_TRGLEV2,		/*!< UART FIFO trigger level 2: 8 character */
+	UART_FIFO_TRGLEV3		/*!< UART FIFO trigger level 3: 14 character */
+} UART_FITO_LEVEL_Type;
+
+/** Macro to check the input UART_FIFO parameters */
+#define PARAM_UART_FIFO_LEVEL(fifo)	((fifo==UART_FIFO_TRGLEV0) \
+|| (fifo==UART_FIFO_TRGLEV1) || (fifo==UART_FIFO_TRGLEV2) \
+|| (fifo==UART_FIFO_TRGLEV3))
+
+/********************************************************************//**
+* @brief UART Interrupt Type definitions
+**********************************************************************/
+typedef enum {
+	UART_INTCFG_RBR = 0,	/*!< RBR Interrupt enable*/
+	UART_INTCFG_THRE,		/*!< THR Interrupt enable*/
+	UART_INTCFG_RLS,		/*!< RX line status interrupt enable*/
+	UART1_INTCFG_MS,		/*!< Modem status interrupt enable (UART1 only) */
+	UART1_INTCFG_CTS,		/*!< CTS1 signal transition interrupt enable (UART1 only) */
+	UART_INTCFG_ABEO,		/*!< Enables the end of auto-baud interrupt */
+	UART_INTCFG_ABTO		/*!< Enables the auto-baud time-out interrupt */
+} UART_INT_Type;
+
+/** Macro to check the input UART_INTCFG parameters */
+#define PARAM_UART_INTCFG(IntCfg)	((IntCfg==UART_INTCFG_RBR) || (IntCfg==UART_INTCFG_THRE) \
+|| (IntCfg==UART_INTCFG_RLS) || (IntCfg==UART_INTCFG_ABEO) \
+|| (IntCfg==UART_INTCFG_ABTO))
+
+/** Macro to check the input UART1_INTCFG parameters - expansion input parameter for UART1 */
+#define PARAM_UART1_INTCFG(IntCfg)	((IntCfg==UART1_INTCFG_MS) || (IntCfg==UART1_INTCFG_CTS))
+
+
+/**
+ * @brief UART Line Status Type definition
+ */
+typedef enum {
+	UART_LINESTAT_RDR	= UART_LSR_RDR,			/*!<Line status register: Receive data ready*/
+	UART_LINESTAT_OE	= UART_LSR_OE,			/*!<Line status register: Overrun error*/
+	UART_LINESTAT_PE	= UART_LSR_PE,			/*!<Line status register: Parity error*/
+	UART_LINESTAT_FE	= UART_LSR_FE,			/*!<Line status register: Framing error*/
+	UART_LINESTAT_BI	= UART_LSR_BI,			/*!<Line status register: Break interrupt*/
+	UART_LINESTAT_THRE	= UART_LSR_THRE,		/*!<Line status register: Transmit holding register empty*/
+	UART_LINESTAT_TEMT	= UART_LSR_TEMT,		/*!<Line status register: Transmitter empty*/
+	UART_LINESTAT_RXFE	= UART_LSR_RXFE			/*!<Error in RX FIFO*/
+} UART_LS_Type;
+
+
+/**
+ * @brief UART Auto-baudrate mode type definition
+ */
+typedef enum {
+	UART_AUTOBAUD_MODE0				= 0,			/**< UART Auto baudrate Mode 0 */
+	UART_AUTOBAUD_MODE1,							/**< UART Auto baudrate Mode 1 */
+} UART_AB_MODE_Type;
+
+/** Macro to check the input UART_AUTOBAUD_MODE parameters */
+#define PARAM_UART_AUTOBAUD_MODE(ABmode)	((ABmode==UART_AUTOBAUD_MODE0) || (ABmode==UART_AUTOBAUD_MODE1))
+
+/**
+ * @brief Auto Baudrate mode configuration type definition
+ */
+typedef struct {
+	UART_AB_MODE_Type	ABMode;			/**< Autobaudrate mode */
+	FunctionalState		AutoRestart;	/**< Auto Restart state */
+} UART_AB_CFG_Type;
+
+
+/**
+ * @brief UART End of Auto-baudrate type definition
+ */
+typedef enum {
+	UART_AUTOBAUD_INTSTAT_ABEO		= UART_IIR_ABEO_INT,		/**< UART End of auto-baud interrupt  */
+	UART_AUTOBAUD_INTSTAT_ABTO		= UART_IIR_ABTO_INT			/**< UART Auto-baud time-out interrupt  */
+}UART_ABEO_Type;
+
+/** Macro to check the input UART_AUTOBAUD_INTSTAT parameters */
+#define PARAM_UART_AUTOBAUD_INTSTAT(ABIntStat)	((ABIntStat==UART_AUTOBAUD_INTSTAT_ABEO) || (ABIntStat==UART_AUTOBAUD_INTSTAT_ABTO))
+
+/**
+ * UART IrDA Control type Definition
+ */
+typedef enum {
+	UART_IrDA_PULSEDIV2		= 0,		/**< Pulse width = 2 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV4,				/**< Pulse width = 4 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV8,				/**< Pulse width = 8 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV16,				/**< Pulse width = 16 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV32,				/**< Pulse width = 32 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV64,				/**< Pulse width = 64 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV128,				/**< Pulse width = 128 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+	UART_IrDA_PULSEDIV256				/**< Pulse width = 256 * Tpclk
+										- Configures the pulse when FixPulseEn = 1 */
+} UART_IrDA_PULSE_Type;
+
+
+/** Macro to check the input UART_IrDA_PULSEDIV parameters */
+#define PARAM_UART_IrDA_PULSEDIV(PulseDiv)	((PulseDiv==UART_IrDA_PULSEDIV2) || (PulseDiv==UART_IrDA_PULSEDIV4) \
+|| (PulseDiv==UART_IrDA_PULSEDIV8) || (PulseDiv==UART_IrDA_PULSEDIV16) \
+|| (PulseDiv==UART_IrDA_PULSEDIV32) || (PulseDiv==UART_IrDA_PULSEDIV64) \
+|| (PulseDiv==UART_IrDA_PULSEDIV128) || (PulseDiv==UART_IrDA_PULSEDIV256))
+
+/********************************************************************//**
+* @brief UART1 Full modem -  Signal states definition
+**********************************************************************/
+typedef enum {
+	INACTIVE = 0,			/* In-active state */
+	ACTIVE = !INACTIVE 		/* Active state */
+}UART1_SignalState;
+
+/* Macro to check the input UART1_SignalState parameters */
+#define PARAM_UART1_SIGNALSTATE(x) ((x==INACTIVE) || (x==ACTIVE))
+
+/**
+ * @brief UART modem status type definition
+ */
+typedef enum {
+	UART1_MODEM_STAT_DELTA_CTS	= UART1_MSR_DELTA_CTS,		/*!< Set upon state change of input CTS */
+	UART1_MODEM_STAT_DELTA_DSR	= UART1_MSR_DELTA_DSR,		/*!< Set upon state change of input DSR */
+	UART1_MODEM_STAT_LO2HI_RI	= UART1_MSR_LO2HI_RI,		/*!< Set upon low to high transition of input RI */
+	UART1_MODEM_STAT_DELTA_DCD	= UART1_MSR_DELTA_DCD,		/*!< Set upon state change of input DCD */
+	UART1_MODEM_STAT_CTS		= UART1_MSR_CTS,			/*!< Clear To Send State */
+	UART1_MODEM_STAT_DSR		= UART1_MSR_DSR,			/*!< Data Set Ready State */
+	UART1_MODEM_STAT_RI			= UART1_MSR_RI,				/*!< Ring Indicator State */
+	UART1_MODEM_STAT_DCD		= UART1_MSR_DCD				/*!< Data Carrier Detect State */
+} UART_MODEM_STAT_type;
+
+/**
+ * @brief Modem output pin type definition
+ */
+typedef enum {
+	UART1_MODEM_PIN_DTR			= 0,		/*!< Source for modem output pin DTR */
+	UART1_MODEM_PIN_RTS						/*!< Source for modem output pin RTS */
+} UART_MODEM_PIN_Type;
+
+/** Macro to check the input PARAM_UART1_MODEM_PIN parameters */
+#define PARAM_UART1_MODEM_PIN(x) ((x==UART1_MODEM_PIN_DTR) || (x==UART1_MODEM_PIN_RTS))
+
+
+/**
+ * @brief UART Modem mode type definition
+ */
+typedef enum {
+	UART1_MODEM_MODE_LOOPBACK	= 0,		/*!< Loop back mode select */
+	UART1_MODEM_MODE_AUTO_RTS,				/*!< Enable Auto RTS flow-control */
+	UART1_MODEM_MODE_AUTO_CTS 				/*!< Enable Auto CTS flow-control */
+} UART_MODEM_MODE_Type;
+
+/** Macro to check the input PARAM_UART1_MODEM_MODE parameters */
+#define PARAM_UART1_MODEM_MODE(x) ((x==UART1_MODEM_MODE_LOOPBACK) || (x==UART1_MODEM_MODE_AUTO_RTS) \
+|| (x==UART1_MODEM_MODE_AUTO_CTS))
+
+
+/**
+ * @brief UART Direction Control Pin type definition
+ */
+typedef enum {
+	UART1_RS485_DIRCTRL_RTS = 0,	/**< Pin RTS is used for direction control */
+	UART1_RS485_DIRCTRL_DTR			/**< Pin DTR is used for direction control */
+} UART_RS485_DIRCTRL_PIN_Type;
+
+/** Macro to check the direction control pin type */
+#define PARAM_UART_RS485_DIRCTRL_PIN(x)	((x==UART1_RS485_DIRCTRL_RTS) || (x==UART1_RS485_DIRCTRL_DTR))
+
+
+/********************************************************************//**
+* @brief UART Configuration Structure definition
+**********************************************************************/
+typedef struct {
+  uint32_t Baud_rate;   		/**< UART baud rate */
+  UART_PARITY_Type Parity;    	/**< Parity selection, should be:
+							   - UART_PARITY_NONE: No parity
+							   - UART_PARITY_ODD: Odd parity
+							   - UART_PARITY_EVEN: Even parity
+							   - UART_PARITY_SP_1: Forced "1" stick parity
+							   - UART_PARITY_SP_0: Forced "0" stick parity
+							   */
+  UART_DATABIT_Type Databits;   /**< Number of data bits, should be:
+							   - UART_DATABIT_5: UART 5 bit data mode
+							   - UART_DATABIT_6: UART 6 bit data mode
+							   - UART_DATABIT_7: UART 7 bit data mode
+							   - UART_DATABIT_8: UART 8 bit data mode
+							   */
+  UART_STOPBIT_Type Stopbits;   /**< Number of stop bits, should be:
+							   - UART_STOPBIT_1: UART 1 Stop Bits Select
+							   - UART_STOPBIT_2: UART 2 Stop Bits Select
+							   */
+} UART_CFG_Type;
+
+/********************************************************************//**
+* @brief UART FIFO Configuration Structure definition
+**********************************************************************/
+
+typedef struct {
+	FunctionalState FIFO_ResetRxBuf;	/**< Reset Rx FIFO command state , should be:
+										 - ENABLE: Reset Rx FIFO in UART
+										 - DISABLE: Do not reset Rx FIFO  in UART
+										 */
+	FunctionalState FIFO_ResetTxBuf;	/**< Reset Tx FIFO command state , should be:
+										 - ENABLE: Reset Tx FIFO in UART
+										 - DISABLE: Do not reset Tx FIFO  in UART
+										 */
+	FunctionalState FIFO_DMAMode;		/**< DMA mode, should be:
+										 - ENABLE: Enable DMA mode in UART
+										 - DISABLE: Disable DMA mode in UART
+										 */
+	UART_FITO_LEVEL_Type FIFO_Level;	/**< Rx FIFO trigger level, should be:
+										- UART_FIFO_TRGLEV0: UART FIFO trigger level 0: 1 character
+										- UART_FIFO_TRGLEV1: UART FIFO trigger level 1: 4 character
+										- UART_FIFO_TRGLEV2: UART FIFO trigger level 2: 8 character
+										- UART_FIFO_TRGLEV3: UART FIFO trigger level 3: 14 character
+										*/
+} UART_FIFO_CFG_Type;
+
+
+/********************************************************************//**
+* @brief UART1 Full modem -  RS485 Control configuration type
+**********************************************************************/
+typedef struct {
+	FunctionalState NormalMultiDropMode_State; /*!< Normal MultiDrop mode State:
+													- ENABLE: Enable this function.
+													- DISABLE: Disable this function. */
+	FunctionalState Rx_State;					/*!< Receiver State:
+													- ENABLE: Enable Receiver.
+													- DISABLE: Disable Receiver. */
+	FunctionalState AutoAddrDetect_State;		/*!< Auto Address Detect mode state:
+												- ENABLE: ENABLE this function.
+												- DISABLE: Disable this function. */
+	FunctionalState AutoDirCtrl_State;			/*!< Auto Direction Control State:
+												- ENABLE: Enable this function.
+												- DISABLE: Disable this function. */
+	UART_RS485_DIRCTRL_PIN_Type DirCtrlPin;		/*!< If direction control is enabled, state:
+												- UART1_RS485_DIRCTRL_RTS:
+												pin RTS is used for direction control.
+												- UART1_RS485_DIRCTRL_DTR:
+												pin DTR is used for direction control. */
+	 SetState DirCtrlPol_Level;					/*!< Polarity of the direction control signal on
+												the RTS (or DTR) pin:
+												- RESET: The direction control pin will be driven
+												to logic "0" when the transmitter has data to be sent.
+												- SET: The direction control pin will be driven
+												to logic "1" when the transmitter has data to be sent. */
+	uint8_t MatchAddrValue;					/*!< address match value for RS-485/EIA-485 mode, 8-bit long */
+	uint8_t DelayValue;						/*!< delay time is in periods of the baud clock, 8-bit long */
+} UART1_RS485_CTRLCFG_Type;
+
+
+/* UART call-back function type definitions */
+/** UART Receive Call-back function type */
+typedef void (fnRxCbs_Type)(void);
+/** UART Transmit Call-back function type */
+typedef void (fnTxCbs_Type)(void);
+/** UART Auto-Baudrate Call-back function type */
+typedef void (fnABCbs_Type)(uint32_t bABIntType);
+/** UART Error Call-back function type */
+typedef void (fnErrCbs_Type)(uint8_t bError);
+/** UART1 modem status interrupt callback type */
+typedef void (fnModemCbs_Type)(uint8_t ModemStatus);
+
+
+/**
+ * @}
+ */
+
+
+/* Public Macros -------------------------------------------------------------- */
+/** @defgroup UART_Public_Macros
+ * @{
+ */
+
+
+/* Macro to determine if it is valid UART port number */
+#define PARAM_UARTx(x)	((((uint32_t *)x)==((uint32_t *)LPC_UART0)) \
+|| (((uint32_t *)x)==((uint32_t *)LPC_UART1)) \
+|| (((uint32_t *)x)==((uint32_t *)LPC_UART2)) \
+|| (((uint32_t *)x)==((uint32_t *)LPC_UART3)))
+#define PARAM_UART_IrDA(x) (((uint32_t *)x)==((uint32_t *)LPC_UART3))
+#define PARAM_UART1_MODEM(x) (((uint32_t *)x)==((uint32_t *)LPC_UART1))
+
+
+/** Macro to check the input value for UART1_RS485_CFG_MATCHADDRVALUE parameter */
+#define PARAM_UART1_RS485_CFG_MATCHADDRVALUE(x) ((x<0xFF))
+
+/** Macro to check the input value for UART1_RS485_CFG_DELAYVALUE parameter */
+#define PARAM_UART1_RS485_CFG_DELAYVALUE(x) ((x<0xFF))
+
+
+/** UART time-out definitions in case of using Read() and Write function
+ * with Blocking Flag mode
+ */
+
+#define UART_BLOCKING_TIMEOUT			(0xFFFFFFFFUL)
+
+/**
+ * @}
+ */
+
+
+/* Public Functions ----------------------------------------------------------- */
+/** @defgroup UART_Public_Functions
+ * @{
+ */
+
+void UART_DeInit(LPC_UART_TypeDef* UARTx);
+void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct);
+void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct);
+void UART_SendData(LPC_UART_TypeDef* UARTx, uint8_t Data);
+uint8_t UART_ReceiveData(LPC_UART_TypeDef* UARTx);
+void UART_ForceBreak(LPC_UART_TypeDef* UARTx);
+void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState);
+void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState);
+void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv);
+void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, \
+				FunctionalState NewState);
+uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx);
+FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx);
+void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg);
+void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct);
+void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \
+				FunctionalState NewState);
+void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState);
+void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \
+							UART1_SignalState NewState);
+void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \
+							FunctionalState NewState);
+uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx);
+void UART_RS485Config(LPC_UART1_TypeDef *UARTx, \
+		UART1_RS485_CTRLCFG_Type *RS485ConfigStruct);
+void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState);
+void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr);
+uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size);
+uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,
+		uint32_t buflen, TRANSFER_BLOCK_Type flag);
+uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \
+		uint32_t buflen, TRANSFER_BLOCK_Type flag);
+void UART_SetupCbs(LPC_UART_TypeDef *UARTx, uint8_t CbType, void *pfnCbs);
+void UART0_StdIntHandler(void);
+void UART1_StdIntHandler(void);
+void UART2_StdIntHandler(void);
+void UART3_StdIntHandler(void);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __LPC17XX_UART_H */
+
+/**
+ * @}
+ */
+
+/* --------------------------------- End Of File ------------------------------ */
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.c b/arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.c
new file mode 100644
index 0000000..8fe2b41
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.c
@@ -0,0 +1,574 @@
+/**************************************************************************//**
+ * @file     system_LPC17xx.c
+ * @brief    CMSIS Cortex-M3 Device Peripheral Access Layer Source File
+ *           for the NXP LPC17xx Device Series
+ * @version  V1.03
+ * @date     07. October 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers.  This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#include <stdint.h>
+#include "LPC17xx.h"
+
+/*
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
+*/
+
+/*--------------------- Clock Configuration ----------------------------------
+//
+// <e> Clock Configuration
+//   <h> System Controls and Status Register (SCS)
+//     <o1.4>    OSCRANGE: Main Oscillator Range Select
+//                     <0=>  1 MHz to 20 MHz
+//                     <1=> 15 MHz to 24 MHz
+//     <e1.5>       OSCEN: Main Oscillator Enable
+//     </e>
+//   </h>
+//
+//   <h> Clock Source Select Register (CLKSRCSEL)
+//     <o2.0..1>   CLKSRC: PLL Clock Source Selection
+//                     <0=> Internal RC oscillator
+//                     <1=> Main oscillator
+//                     <2=> RTC oscillator
+//   </h>
+//
+
+*/
+#define CLOCK_SETUP           	1
+#define SCS_Val               	0x00000030
+#define CLKSRCSEL_Val         	0x00000001
+
+
+/*
+
+
+
+//   <e3> PLL0 Configuration (Main PLL)
+//     <h> PLL0 Configuration Register (PLL0CFG)
+//                     <i> F_cco0 = (2 * M * F_in) / N
+//                     <i> F_in must be in the range of 32 kHz to 50 MHz
+//                     <i> F_cco0 must be in the range of 275 MHz to 550 MHz
+//       <o4.0..14>  MSEL: PLL Multiplier Selection
+//                     <6-32768><#-1>
+//                     <i> M Value
+//       <o4.16..23> NSEL: PLL Divider Selection
+//                     <1-256><#-1>
+//                     <i> N Value
+//     </h>
+//   </e>
+//
+
+
+*/
+#define PLL0_SETUP            1
+#define PLL0CFG_Val           0x0003001B
+
+/*
+//   <e5> PLL1 Configuration (USB PLL)
+//     <h> PLL1 Configuration Register (PLL1CFG)
+//                     <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)
+//                     <i> F_cco1 = F_osc * M * 2 * P
+//                     <i> F_cco1 must be in the range of 156 MHz to 320 MHz
+//       <o6.0..4>   MSEL: PLL Multiplier Selection
+//                     <1-32><#-1>
+//                     <i> M Value (for USB maximum value is 4)
+//       <o6.5..6>   PSEL: PLL Divider Selection
+//                     <0=> 1
+//                     <1=> 2
+//                     <2=> 4
+//                     <3=> 8
+//                     <i> P Value
+//     </h>
+//   </e>
+//
+//   <h> CPU Clock Configuration Register (CCLKCFG)
+//     <o7.0..7>  CCLKSEL: Divide Value for CPU Clock from PLL0
+//                     <3-256><#-1>
+//   </h>
+//
+//   <h> USB Clock Configuration Register (USBCLKCFG)
+//     <o8.0..3>   USBSEL: Divide Value for USB Clock from PLL0
+//                     <0-15>
+//                     <i> Divide is USBSEL + 1
+//   </h>
+//
+//   <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
+//     <o9.0..1>    PCLK_WDT: Peripheral Clock Selection for WDT
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.2..3>    PCLK_TIMER0: Peripheral Clock Selection for TIMER0
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.4..5>    PCLK_TIMER1: Peripheral Clock Selection for TIMER1
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.6..7>    PCLK_UART0: Peripheral Clock Selection for UART0
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.8..9>    PCLK_UART1: Peripheral Clock Selection for UART1
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.12..13>  PCLK_PWM1: Peripheral Clock Selection for PWM1
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.14..15>  PCLK_I2C0: Peripheral Clock Selection for I2C0
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.16..17>  PCLK_SPI: Peripheral Clock Selection for SPI
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.20..21>  PCLK_SSP1: Peripheral Clock Selection for SSP1
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.22..23>  PCLK_DAC: Peripheral Clock Selection for DAC
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.24..25>  PCLK_ADC: Peripheral Clock Selection for ADC
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o9.26..27>  PCLK_CAN1: Peripheral Clock Selection for CAN1
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 6
+//     <o9.28..29>  PCLK_CAN2: Peripheral Clock Selection for CAN2
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 6
+//     <o9.30..31>  PCLK_ACF: Peripheral Clock Selection for ACF
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 6
+//   </h>
+//
+//   <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
+//     <o10.0..1>   PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.2..3>   PCLK_GPIO: Peripheral Clock Selection for GPIOs
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.4..5>   PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.6..7>   PCLK_I2C1: Peripheral Clock Selection for I2C1
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//     <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM
+//                     <0=> Pclk = Cclk / 4
+//                     <1=> Pclk = Cclk
+//                     <2=> Pclk = Cclk / 2
+//                     <3=> Pclk = Hclk / 8
+//   </h>
+//
+//   <h> Power Control for Peripherals Register (PCONP)
+//     <o11.1>      PCTIM0: Timer/Counter 0 power/clock enable
+//     <o11.2>      PCTIM1: Timer/Counter 1 power/clock enable
+//     <o11.3>      PCUART0: UART 0 power/clock enable
+//     <o11.4>      PCUART1: UART 1 power/clock enable
+//     <o11.6>      PCPWM1: PWM 1 power/clock enable
+//     <o11.7>      PCI2C0: I2C interface 0 power/clock enable
+//     <o11.8>      PCSPI: SPI interface power/clock enable
+//     <o11.9>      PCRTC: RTC power/clock enable
+//     <o11.10>     PCSSP1: SSP interface 1 power/clock enable
+//     <o11.12>     PCAD: A/D converter power/clock enable
+//     <o11.13>     PCCAN1: CAN controller 1 power/clock enable
+//     <o11.14>     PCCAN2: CAN controller 2 power/clock enable
+//     <o11.15>     PCGPIO: GPIOs power/clock enable
+//     <o11.16>     PCRIT: Repetitive interrupt timer power/clock enable
+//     <o11.17>     PCMC: Motor control PWM power/clock enable
+//     <o11.18>     PCQEI: Quadrature encoder interface power/clock enable
+//     <o11.19>     PCI2C1: I2C interface 1 power/clock enable
+//     <o11.21>     PCSSP0: SSP interface 0 power/clock enable
+//     <o11.22>     PCTIM2: Timer 2 power/clock enable
+//     <o11.23>     PCTIM3: Timer 3 power/clock enable
+//     <o11.24>     PCUART2: UART 2 power/clock enable
+//     <o11.25>     PCUART3: UART 3 power/clock enable
+//     <o11.26>     PCI2C2: I2C interface 2 power/clock enable
+//     <o11.27>     PCI2S: I2S interface power/clock enable
+//     <o11.29>     PCGPDMA: GP DMA function power/clock enable
+//     <o11.30>     PCENET: Ethernet block power/clock enable
+//     <o11.31>     PCUSB: USB interface power/clock enable
+//   </h>
+//
+//   <h> Clock Output Configuration Register (CLKOUTCFG)
+//     <o12.0..3>   CLKOUTSEL: Selects clock source for CLKOUT
+//                     <0=> CPU clock
+//                     <1=> Main oscillator
+//                     <2=> Internal RC oscillator
+//                     <3=> USB clock
+//                     <4=> RTC oscillator
+//     <o12.4..7>   CLKOUTDIV: Selects clock divider for CLKOUT
+//                     <1-16><#-1>
+//     <o12.8>      CLKOUT_EN: CLKOUT enable control
+//   </h>
+//
+// </e>
+*/
+
+
+#define PLL1_SETUP            0
+#define PLL1CFG_Val           0x00000023
+#define CCLKCFG_Val           0x00000003
+#define USBCLKCFG_Val         0x00000000
+#define PCLKSEL0_Val          0x00000000
+#define PCLKSEL1_Val          0x00000000
+#define PCONP_Val             0x042887DE
+#define CLKOUTCFG_Val         0x00000000
+
+
+/*--------------------- Flash Accelerator Configuration ----------------------
+//
+// <e> Flash Accelerator Configuration
+//   <o1.0..11>  Reserved
+//   <o1.12..15> FLASHTIM: Flash Access Time
+//               <0=> 1 CPU clock (for CPU clock up to 20 MHz)
+//               <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
+//               <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
+//               <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
+//               <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
+//               <5=> 6 CPU clocks (for any CPU clock)
+// </e>
+*/
+#define FLASH_SETUP           1
+#define FLASHCFG_Val          0x0000403A
+
+/*
+//-------- <<< end of configuration section >>> ------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+  Check the register settings
+ *----------------------------------------------------------------------------*/
+#define CHECK_RANGE(val, min, max)                ((val < min) || (val > max))
+#define CHECK_RSVD(val, mask)                     (val & mask)
+
+/* Clock Configuration -------------------------------------------------------*/
+#if (CHECK_RSVD((SCS_Val),       ~0x00000030))
+   #error "SCS: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
+   #error "CLKSRCSEL: Value out of range!"
+#endif
+
+#if (CHECK_RSVD((PLL0CFG_Val),   ~0x00FF7FFF))
+   #error "PLL0CFG: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PLL1CFG_Val),   ~0x0000007F))
+   #error "PLL1CFG: Invalid values of reserved bits!"
+#endif
+
+#if ((CCLKCFG_Val != 0) && (((CCLKCFG_Val - 1) % 2)))
+   #error "CCLKCFG: CCLKSEL field does not contain only odd values or 0!"
+#endif
+
+#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
+   #error "USBCLKCFG: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PCLKSEL0_Val),   0x000C0C00))
+   #error "PCLKSEL0: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PCLKSEL1_Val),   0x03000300))
+   #error "PCLKSEL1: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((PCONP_Val),      0x10100821))
+   #error "PCONP: Invalid values of reserved bits!"
+#endif
+
+#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
+   #error "CLKOUTCFG: Invalid values of reserved bits!"
+#endif
+
+/* Flash Accelerator Configuration -------------------------------------------*/
+#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))
+   #error "FLASHCFG: Invalid values of reserved bits!"
+#endif
+
+
+/*----------------------------------------------------------------------------
+  DEFINES
+ *----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+  Define clocks
+ *----------------------------------------------------------------------------*/
+#define XTAL        (12000000UL)        /* Oscillator frequency               */
+#define OSC_CLK     (      XTAL)        /* Main oscillator frequency          */
+#define RTC_CLK     (   32000UL)        /* RTC oscillator frequency           */
+#define IRC_OSC     ( 4000000UL)        /* Internal RC oscillator frequency   */
+
+
+/* F_cco0 = (2 * M * F_in) / N  */
+#define __M               (((PLL0CFG_Val      ) & 0x7FFF) + 1)
+#define __N               (((PLL0CFG_Val >> 16) & 0x00FF) + 1)
+#define __FCCO(__F_IN)    ((2 * __M * __F_IN) / __N)
+#define __CCLK_DIV        (((CCLKCFG_Val      ) & 0x00FF) + 1)
+
+/* Determine core clock frequency according to settings */
+ #if (PLL0_SETUP)
+    #if   ((CLKSRCSEL_Val & 0x03) == 1)
+        #define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV)
+    #elif ((CLKSRCSEL_Val & 0x03) == 2)
+        #define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV)
+    #else
+        #define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV)
+    #endif
+ #else
+    #if   ((CLKSRCSEL_Val & 0x03) == 1)
+        #define __CORE_CLK (OSC_CLK         / __CCLK_DIV)
+    #elif ((CLKSRCSEL_Val & 0x03) == 2)
+        #define __CORE_CLK (RTC_CLK         / __CCLK_DIV)
+    #else
+        #define __CORE_CLK (IRC_OSC         / __CCLK_DIV)
+    #endif
+ #endif
+
+
+/*----------------------------------------------------------------------------
+  Clock Variable definitions
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
+
+
+/*----------------------------------------------------------------------------
+  Clock functions
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)            /* Get Core Clock Frequency      */
+{
+  /* Determine clock frequency according to clock register values             */
+  if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */
+    switch (LPC_SC->CLKSRCSEL & 0x03) {
+      case 0:                                /* Int. RC oscillator => PLL0    */
+      case 3:                                /* Reserved, default to Int. RC  */
+        SystemCoreClock = (IRC_OSC *
+                          ((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1)))  /
+                          (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1)    /
+                          ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+        break;
+      case 1:                                /* Main oscillator => PLL0       */
+        SystemCoreClock = (OSC_CLK *
+                          ((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1)))  /
+                          (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1)    /
+                          ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+        break;
+      case 2:                                /* RTC oscillator => PLL0        */
+        SystemCoreClock = (RTC_CLK *
+                          ((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1)))  /
+                          (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1)    /
+                          ((LPC_SC->CCLKCFG & 0xFF)+ 1));
+        break;
+    }
+  } else {
+    switch (LPC_SC->CLKSRCSEL & 0x03) {
+      case 0:                                /* Int. RC oscillator => PLL0    */
+      case 3:                                /* Reserved, default to Int. RC  */
+        SystemCoreClock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+        break;
+      case 1:                                /* Main oscillator => PLL0       */
+        SystemCoreClock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+        break;
+      case 2:                                /* RTC oscillator => PLL0        */
+        SystemCoreClock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
+        break;
+    }
+  }
+
+}
+/* Exported types --------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+//extern unsigned long _sidata;		/* start address for the initialization values of the .data section. defined in linker script */
+//extern unsigned long _sdata;		/* start address for the .data section. defined in linker script */
+//extern unsigned long _edata;		/* end address for the .data section. defined in linker script */
+//
+//extern unsigned long _sbss;			/* start address for the .bss section. defined in linker script */
+//extern unsigned long _ebss;			/* end address for the .bss section. defined in linker script */
+
+//void _init(void)
+//{
+//    unsigned long *pulSrc, *pulDest;
+//
+//    //
+//    // Copy the data segment initializers from flash to SRAM in ROM mode
+//    //
+//#if (__RAM_MODE__==0)
+//    pulSrc = &_sidata;
+//    for(pulDest = &_sdata; pulDest < &_edata; )
+//    {
+//        *(pulDest++) = *(pulSrc++);
+//    }
+//#endif
+//
+//
+//    //
+//    // Zero fill the bss segment.
+//    //
+//    for(pulDest = &_sbss; pulDest < &_ebss; )
+//    {
+//        *(pulDest++) = 0;
+//    }
+//}
+
+/**
+ * Initialize the system
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System.
+ */
+void SystemInit (void)
+{
+
+#if (CLOCK_SETUP)                       /* Clock Setup                        */
+  LPC_SC->SCS       = SCS_Val;
+  if (SCS_Val & (1 << 5)) {             /* If Main Oscillator is enabled      */
+    while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready    */
+  }
+
+  LPC_SC->CCLKCFG   = CCLKCFG_Val;      /* Setup Clock Divider                */
+  LPC_SC->PCLKSEL0  = PCLKSEL0_Val;     /* Peripheral Clock Selection         */
+  LPC_SC->PCLKSEL1  = PCLKSEL1_Val;
+
+#if (PLL0_SETUP)
+  LPC_SC->CLKSRCSEL = CLKSRCSEL_Val;    /* Select Clock Source for PLL0       */
+
+  LPC_SC->PLL0CFG   = PLL0CFG_Val;      /* configure PLL0                     */
+  LPC_SC->PLL0FEED  = 0xAA;
+  LPC_SC->PLL0FEED  = 0x55;
+
+  LPC_SC->PLL0CON   = 0x01;             /* PLL0 Enable                        */
+  LPC_SC->PLL0FEED  = 0xAA;
+  LPC_SC->PLL0FEED  = 0x55;
+  while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0                    */
+
+  LPC_SC->PLL0CON   = 0x03;             /* PLL0 Enable & Connect              */
+  LPC_SC->PLL0FEED  = 0xAA;
+  LPC_SC->PLL0FEED  = 0x55;
+  while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */
+#endif
+
+#if (PLL1_SETUP)
+  LPC_SC->PLL1CFG   = PLL1CFG_Val;
+  LPC_SC->PLL1FEED  = 0xAA;
+  LPC_SC->PLL1FEED  = 0x55;
+
+  LPC_SC->PLL1CON   = 0x01;             /* PLL1 Enable                        */
+  LPC_SC->PLL1FEED  = 0xAA;
+  LPC_SC->PLL1FEED  = 0x55;
+  while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1                    */
+
+  LPC_SC->PLL1CON   = 0x03;             /* PLL1 Enable & Connect              */
+  LPC_SC->PLL1FEED  = 0xAA;
+  LPC_SC->PLL1FEED  = 0x55;
+  while (!(LPC_SC->PLL1STAT & ((1<< 9) | (1<< 8))));/* Wait for PLLC1_STAT & PLLE1_STAT */
+#else
+  LPC_SC->USBCLKCFG = USBCLKCFG_Val;    /* Setup USB Clock Divider            */
+#endif
+  LPC_SC->PCONP     = PCONP_Val;        /* Power Control for Peripherals      */
+
+  LPC_SC->CLKOUTCFG = CLKOUTCFG_Val;    /* Clock Output Configuration         */
+#endif
+
+#if (FLASH_SETUP == 1)                  /* Flash Accelerator Setup            */
+  LPC_SC->FLASHCFG  = FLASHCFG_Val;
+#endif
+}
diff --git a/arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.h b/arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.h
new file mode 100644
index 0000000..5a78d33
--- /dev/null
+++ b/arch/arm/mach-lpc17cmsis/libs/cmsis/system_LPC17xx.h
@@ -0,0 +1,63 @@
+/**************************************************************************//**
+ * @file     system_LPC17xx.h
+ * @brief    CMSIS Cortex-M3 Device Peripheral Access Layer Header File
+ *           for the NXP LPC17xx Device Series
+ * @version  V1.02
+ * @date     08. September 2009
+ *
+ * @note
+ * Copyright (C) 2009 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M
+ * processor based microcontrollers.  This file can be freely distributed
+ * within development tools that are supporting such ARM based processors.
+ *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
+
+
+#ifndef __SYSTEM_LPC17xx_H
+#define __SYSTEM_LPC17xx_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+extern uint32_t SystemCoreClock;     /*!< System Clock Frequency (Core Clock)  */
+
+
+/**
+ * Initialize the system
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Setup the microcontroller system.
+ *         Initialize the System and update the SystemCoreClock variable.
+ */
+extern void SystemInit (void);
+
+/**
+ * Update SystemCoreClock variable
+ *
+ * @param  none
+ * @return none
+ *
+ * @brief  Updates the SystemCoreClock with current core Clock
+ *         retrieved from cpu registers.
+ */
+extern void SystemCoreClockUpdate (void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_LPC17xx_H */
-- 
1.7.1




More information about the Sysless mailing list