aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/hal/platforms/LPC17xx/LPC17xx.h999
-rw-r--r--os/hal/platforms/LPC17xx/adc_lld.c284
-rw-r--r--os/hal/platforms/LPC17xx/adc_lld.h346
-rw-r--r--os/hal/platforms/LPC17xx/gpt_lld.c338
-rw-r--r--os/hal/platforms/LPC17xx/gpt_lld.h208
-rw-r--r--os/hal/platforms/LPC17xx/hal_lld.c158
-rw-r--r--os/hal/platforms/LPC17xx/hal_lld.h433
-rw-r--r--os/hal/platforms/LPC17xx/i2c_lld.c533
-rw-r--r--os/hal/platforms/LPC17xx/i2c_lld.h271
-rw-r--r--os/hal/platforms/LPC17xx/lpc17xx_dma.c205
-rw-r--r--os/hal/platforms/LPC17xx/lpc17xx_dma.h415
-rw-r--r--os/hal/platforms/LPC17xx/pal_lld.c158
-rw-r--r--os/hal/platforms/LPC17xx/pal_lld.h332
-rw-r--r--os/hal/platforms/LPC17xx/platform.mk14
-rw-r--r--os/hal/platforms/LPC17xx/rtc_lld.c290
-rw-r--r--os/hal/platforms/LPC17xx/rtc_lld.h279
-rw-r--r--os/hal/platforms/LPC17xx/serial_lld.c476
-rw-r--r--os/hal/platforms/LPC17xx/serial_lld.h268
-rw-r--r--os/hal/platforms/LPC17xx/spi_lld.c387
-rw-r--r--os/hal/platforms/LPC17xx/spi_lld.h337
-rw-r--r--os/hal/platforms/LPC17xx/system_LPC17xx.h64
-rw-r--r--os/ports/GCC/ARMCMx/LPC17xx/cmparams.h62
-rw-r--r--os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1766.ld153
-rw-r--r--os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1769.ld153
-rw-r--r--os/ports/GCC/ARMCMx/LPC17xx/port.mk15
-rw-r--r--os/ports/GCC/ARMCMx/LPC17xx/vectors.c205
-rw-r--r--os/various/chrtclib.c87
27 files changed, 7468 insertions, 2 deletions
diff --git a/os/hal/platforms/LPC17xx/LPC17xx.h b/os/hal/platforms/LPC17xx/LPC17xx.h
new file mode 100644
index 000000000..904d917cc
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/LPC17xx.h
@@ -0,0 +1,999 @@
+/******************************************************************************
+ * @file: LPC17xx.h
+ * @purpose: CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
+ * NXP LPC17xx Device Series
+ * @version: V1.10
+ * @date: 24. September 2010
+ *----------------------------------------------------------------------------
+ *
+ * @note
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * @par
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M3
+ * 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 __LPC17xx_H__
+#define __LPC17xx_H__
+
+/*
+ * ==========================================================================
+ * ---------- Interrupt Number Definition -----------------------------------
+ * ==========================================================================
+ */
+
+/** @addtogroup LPC17xx_System
+ * @{
+ */
+
+/** @brief IRQ interrupt source definition */
+typedef enum IRQn
+{
+/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
+
+/****** LPC17xx Specific Interrupt Numbers *******************************************************/
+ WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */
+ TIMER0_IRQn = 1, /*!< Timer0 Interrupt */
+ TIMER1_IRQn = 2, /*!< Timer1 Interrupt */
+ TIMER2_IRQn = 3, /*!< Timer2 Interrupt */
+ TIMER3_IRQn = 4, /*!< Timer3 Interrupt */
+ UART0_IRQn = 5, /*!< UART0 Interrupt */
+ UART1_IRQn = 6, /*!< UART1 Interrupt */
+ UART2_IRQn = 7, /*!< UART2 Interrupt */
+ UART3_IRQn = 8, /*!< UART3 Interrupt */
+ PWM1_IRQn = 9, /*!< PWM1 Interrupt */
+ I2C0_IRQn = 10, /*!< I2C0 Interrupt */
+ I2C1_IRQn = 11, /*!< I2C1 Interrupt */
+ I2C2_IRQn = 12, /*!< I2C2 Interrupt */
+ SPI_IRQn = 13, /*!< SPI Interrupt */
+ SSP0_IRQn = 14, /*!< SSP0 Interrupt */
+ SSP1_IRQn = 15, /*!< SSP1 Interrupt */
+ PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */
+ RTC_IRQn = 17, /*!< Real Time Clock Interrupt */
+ EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */
+ EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */
+ EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */
+ EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */
+ ADC_IRQn = 22, /*!< A/D Converter Interrupt */
+ BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */
+ USB_IRQn = 24, /*!< USB Interrupt */
+ CAN_IRQn = 25, /*!< CAN Interrupt */
+ DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */
+ I2S_IRQn = 27, /*!< I2S Interrupt */
+ ENET_IRQn = 28, /*!< Ethernet Interrupt */
+ RIT_IRQn = 29, /*!< Repetitive Interrupt Timer Interrupt */
+ MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */
+ QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */
+ PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */
+ USBActivity_IRQn = 33, /*!< USB Activity Interrupt(For wakeup only) */
+ CANActivity_IRQn = 34 /*!< CAN Activity Interrupt(For wakeup only) */
+} IRQn_Type;
+
+
+/*
+ * ==========================================================================
+ * ----------- Processor and Core Peripheral Section ------------------------
+ * ==========================================================================
+ */
+
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */
+#define __MPU_PRESENT 1 /*!< MPU present or not */
+#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
+
+
+#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
+#include "system_LPC17xx.h" /* System Header */
+
+
+/******************************************************************************/
+/* Device Specific Peripheral registers structures */
+/******************************************************************************/
+
+#if defined ( __CC_ARM )
+#pragma anon_unions
+#endif
+
+/*------------- System Control (SC) ------------------------------------------*/
+/** @brief System Control (SC) register structure definition */
+typedef struct
+{
+ __IO uint32_t FLASHCFG; /*!< Offset: 0x000 (R/W) Flash Accelerator Configuration Register */
+ uint32_t RESERVED0[31];
+ __IO uint32_t PLL0CON; /*!< Offset: 0x080 (R/W) PLL0 Control Register */
+ __IO uint32_t PLL0CFG; /*!< Offset: 0x084 (R/W) PLL0 Configuration Register */
+ __I uint32_t PLL0STAT; /*!< Offset: 0x088 (R/ ) PLL0 Status Register */
+ __O uint32_t PLL0FEED; /*!< Offset: 0x08C ( /W) PLL0 Feed Register */
+ uint32_t RESERVED1[4];
+ __IO uint32_t PLL1CON; /*!< Offset: 0x0A0 (R/W) PLL1 Control Register */
+ __IO uint32_t PLL1CFG; /*!< Offset: 0x0A4 (R/W) PLL1 Configuration Register */
+ __I uint32_t PLL1STAT; /*!< Offset: 0x0A8 (R/ ) PLL1 Status Register */
+ __O uint32_t PLL1FEED; /*!< Offset: 0x0AC ( /W) PLL1 Feed Register */
+ uint32_t RESERVED2[4];
+ __IO uint32_t PCON; /*!< Offset: 0x0C0 (R/W) Power Control Register */
+ __IO uint32_t PCONP; /*!< Offset: 0x0C4 (R/W) Power Control for Peripherals Register */
+ uint32_t RESERVED3[15];
+ __IO uint32_t CCLKCFG; /*!< Offset: 0x104 (R/W) CPU Clock Configure Register */
+ __IO uint32_t USBCLKCFG; /*!< Offset: 0x108 (R/W) USB Clock Configure Register */
+ __IO uint32_t CLKSRCSEL; /*!< Offset: 0x10C (R/W) Clock Source Select Register */
+ __IO uint32_t CANSLEEPCLR; /*!< Offset: 0x110 (R/W) CAN Sleep Clear Register */
+ __IO uint32_t CANWAKEFLAGS; /*!< Offset: 0x114 (R/W) CAN Wake-up Flags Register */
+ uint32_t RESERVED4[10];
+ __IO uint32_t EXTINT; /*!< Offset: 0x140 (R/W) External Interrupt Flag Register */
+ uint32_t RESERVED5[1];
+ __IO uint32_t EXTMODE; /*!< Offset: 0x148 (R/W) External Interrupt Mode Register */
+ __IO uint32_t EXTPOLAR; /*!< Offset: 0x14C (R/W) External Interrupt Polarity Register */
+ uint32_t RESERVED6[12];
+ __IO uint32_t RSID; /*!< Offset: 0x180 (R/W) Reset Source Identification Register */
+ uint32_t RESERVED7[7];
+ __IO uint32_t SCS; /*!< Offset: 0x1A0 (R/W) System Controls and Status Register */
+ __IO uint32_t IRCTRIM; /* Clock Dividers */
+ __IO uint32_t PCLKSEL0; /*!< Offset: 0x1A8 (R/W) Peripheral Clock Select 0 Register */
+ __IO uint32_t PCLKSEL1; /*!< Offset: 0x1AC (R/W) Peripheral Clock Select 1 Register */
+ uint32_t RESERVED8[4];
+ __IO uint32_t USBIntSt; /*!< Offset: 0x1C0 (R/W) USB Interrupt Status Register */
+ __IO uint32_t DMAREQSEL; /*!< Offset: 0x1C4 (R/W) DMA Request Select Register */
+ __IO uint32_t CLKOUTCFG; /*!< Offset: 0x1C8 (R/W) Clock Output Configuration Register */
+
+ } LPC_SC_TypeDef;
+
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/
+/** @brief Pin Connect Block (PINCON) register structure definition */
+typedef struct
+{
+ __IO uint32_t PINSEL0; /* !< Offset: 0x000 PIN Select0 (R/W) */
+ __IO uint32_t PINSEL1; /* !< Offset: 0x004 PIN Select1 (R/W) */
+ __IO uint32_t PINSEL2; /* !< Offset: 0x008 PIN Select2 (R/W) */
+ __IO uint32_t PINSEL3; /* !< Offset: 0x00C PIN Select3 (R/W) */
+ __IO uint32_t PINSEL4; /* !< Offset: 0x010 PIN Select4 (R/W) */
+ __IO uint32_t PINSEL5; /* !< Offset: 0x014 PIN Select5 (R/W) */
+ __IO uint32_t PINSEL6; /* !< Offset: 0x018 PIN Select6 (R/W) */
+ __IO uint32_t PINSEL7; /* !< Offset: 0x01C PIN Select7 (R/W) */
+ __IO uint32_t PINSEL8; /* !< Offset: 0x020 PIN Select8 (R/W) */
+ __IO uint32_t PINSEL9; /* !< Offset: 0x024 PIN Select9 (R/W) */
+ __IO uint32_t PINSEL10; /* !< Offset: 0x028 PIN Select20 (R/W) */
+ uint32_t RESERVED0[5];
+ __IO uint32_t PINMODE0; /* !< Offset: 0x040 PIN Mode0 (R/W) */
+ __IO uint32_t PINMODE1; /* !< Offset: 0x044 PIN Mode1 (R/W) */
+ __IO uint32_t PINMODE2; /* !< Offset: 0x048 PIN Mode2 (R/W) */
+ __IO uint32_t PINMODE3; /* !< Offset: 0x04C PIN Mode3 (R/W) */
+ __IO uint32_t PINMODE4; /* !< Offset: 0x050 PIN Mode4 (R/W) */
+ __IO uint32_t PINMODE5; /* !< Offset: 0x054 PIN Mode5 (R/W) */
+ __IO uint32_t PINMODE6; /* !< Offset: 0x058 PIN Mode6 (R/W) */
+ __IO uint32_t PINMODE7; /* !< Offset: 0x05C PIN Mode7 (R/W) */
+ __IO uint32_t PINMODE8; /* !< Offset: 0x060 PIN Mode8 (R/W) */
+ __IO uint32_t PINMODE9; /* !< Offset: 0x064 PIN Mode9 (R/W) */
+ __IO uint32_t PINMODE_OD0; /* !< Offset: 0x068 Open Drain PIN Mode0 (R/W) */
+ __IO uint32_t PINMODE_OD1; /* !< Offset: 0x06C Open Drain PIN Mode1 (R/W) */
+ __IO uint32_t PINMODE_OD2; /* !< Offset: 0x070 Open Drain PIN Mode2 (R/W) */
+ __IO uint32_t PINMODE_OD3; /* !< Offset: 0x074 Open Drain PIN Mode3 (R/W) */
+ __IO uint32_t PINMODE_OD4; /* !< Offset: 0x078 Open Drain PIN Mode4 (R/W) */
+ __IO uint32_t I2CPADCFG; /* !< Offset: 0x07C I2C Pad Configure (R/W) */
+} LPC_PINCON_TypeDef;
+
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/
+/** @brief General Purpose Input/Output (GPIO) register structure definition */
+typedef struct
+{
+ union {
+ __IO uint32_t FIODIR; /* !< Offset: 0x00 Port direction (R/W) */
+ struct {
+ __IO uint16_t FIODIRL;
+ __IO uint16_t FIODIRH;
+ };
+ struct {
+ __IO uint8_t FIODIR0;
+ __IO uint8_t FIODIR1;
+ __IO uint8_t FIODIR2;
+ __IO uint8_t FIODIR3;
+ };
+ };
+ uint32_t RESERVED0[3];
+ union {
+ __IO uint32_t FIOMASK; /* !< Offset: 0x10 Port mask (R/W) */
+ struct {
+ __IO uint16_t FIOMASKL;
+ __IO uint16_t FIOMASKH;
+ };
+ struct {
+ __IO uint8_t FIOMASK0;
+ __IO uint8_t FIOMASK1;
+ __IO uint8_t FIOMASK2;
+ __IO uint8_t FIOMASK3;
+ };
+ };
+ union {
+ __IO uint32_t FIOPIN; /* !< Offset: 0x14 Port value (R/W) */
+ struct {
+ __IO uint16_t FIOPINL;
+ __IO uint16_t FIOPINH;
+ };
+ struct {
+ __IO uint8_t FIOPIN0;
+ __IO uint8_t FIOPIN1;
+ __IO uint8_t FIOPIN2;
+ __IO uint8_t FIOPIN3;
+ };
+ };
+ union {
+ __IO uint32_t FIOSET; /* !< Offset: 0x18 Port output set (R/W) */
+ struct {
+ __IO uint16_t FIOSETL;
+ __IO uint16_t FIOSETH;
+ };
+ struct {
+ __IO uint8_t FIOSET0;
+ __IO uint8_t FIOSET1;
+ __IO uint8_t FIOSET2;
+ __IO uint8_t FIOSET3;
+ };
+ };
+ union {
+ __O uint32_t FIOCLR; /* !< Offset: 0x1C Port output clear (R/W) */
+ struct {
+ __O uint16_t FIOCLRL;
+ __O uint16_t FIOCLRH;
+ };
+ struct {
+ __O uint8_t FIOCLR0;
+ __O uint8_t FIOCLR1;
+ __O uint8_t FIOCLR2;
+ __O uint8_t FIOCLR3;
+ };
+ };
+} LPC_GPIO_TypeDef;
+
+/** @brief General Purpose Input/Output interrupt (GPIOINT) register structure definition */
+typedef struct
+{
+ __I uint32_t IntStatus; /*!< Offset: 0x000 (R/ ) GPIO overall Interrupt Status Register */
+ __I uint32_t IO0IntStatR; /*!< Offset: 0x004 (R/ ) GPIO Interrupt Status Register 0 for Rising edge */
+ __I uint32_t IO0IntStatF; /*!< Offset: 0x008 (R/ ) GPIO Interrupt Status Register 0 for Falling edge */
+ __O uint32_t IO0IntClr; /*!< Offset: 0x00C (R/W) GPIO Interrupt Clear Register 0 */
+ __IO uint32_t IO0IntEnR; /*!< Offset: 0x010 ( /W) GPIO Interrupt Enable Register 0 for Rising edge */
+ __IO uint32_t IO0IntEnF; /*!< Offset: 0x014 (R/W) GPIO Interrupt Enable Register 0 for Falling edge */
+ uint32_t RESERVED0[3];
+ __I uint32_t IO2IntStatR; /*!< Offset: 0x000 (R/ ) GPIO Interrupt Status Register 2 for Rising edge */
+ __I uint32_t IO2IntStatF; /*!< Offset: 0x000 (R/ ) GPIO Interrupt Status Register 2 for Falling edge */
+ __O uint32_t IO2IntClr; /*!< Offset: 0x000 ( /W) GPIO Interrupt Clear Register 2 */
+ __IO uint32_t IO2IntEnR; /*!< Offset: 0x000 (R/W) GPIO Interrupt Enable Register 2 for Rising edge */
+ __IO uint32_t IO2IntEnF; /*!< Offset: 0x000 (R/W) GPIO Interrupt Enable Register 2 for Falling edge */
+} LPC_GPIOINT_TypeDef;
+
+/*------------- Timer (TIM) --------------------------------------------------*/
+/** @brief Timer (TIM) register structure definition */
+typedef struct
+{
+ __IO uint32_t IR; /*!< Offset: 0x000 (R/W) Interrupt Register */
+ __IO uint32_t TCR; /*!< Offset: 0x004 (R/W) Timer Control Register */
+ __IO uint32_t TC; /*!< Offset: 0x008 (R/W) Timer Counter Register */
+ __IO uint32_t PR; /*!< Offset: 0x00C (R/W) Prescale Register */
+ __IO uint32_t PC; /*!< Offset: 0x010 (R/W) Prescale Counter Register */
+ __IO uint32_t MCR; /*!< Offset: 0x014 (R/W) Match Control Register */
+ __IO uint32_t MR0; /*!< Offset: 0x018 (R/W) Match Register 0 */
+ __IO uint32_t MR1; /*!< Offset: 0x01C (R/W) Match Register 1 */
+ __IO uint32_t MR2; /*!< Offset: 0x020 (R/W) Match Register 2 */
+ __IO uint32_t MR3; /*!< Offset: 0x024 (R/W) Match Register 3 */
+ __IO uint32_t CCR; /*!< Offset: 0x028 (R/W) Capture Control Register */
+ __I uint32_t CR0; /*!< Offset: 0x02C (R/ ) Capture Register 0 */
+ __I uint32_t CR1; /*!< Offset: 0x030 (R/ ) Capture Register */
+ uint32_t RESERVED0[2];
+ __IO uint32_t EMR; /*!< Offset: 0x03C (R/W) External Match Register */
+ uint32_t RESERVED1[12];
+ __IO uint32_t CTCR; /*!< Offset: 0x070 (R/W) Count Control Register */
+} LPC_TIM_TypeDef;
+
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/
+/** @brief Pulse-Width Modulation (PWM) register structure definition */
+typedef struct
+{
+ __IO uint32_t IR; /*!< Offset: 0x000 (R/W) Interrupt Register */
+ __IO uint32_t TCR; /*!< Offset: 0x004 (R/W) Timer Control Register. Register */
+ __IO uint32_t TC; /*!< Offset: 0x008 (R/W) Timer Counter Register */
+ __IO uint32_t PR; /*!< Offset: 0x00C (R/W) Prescale Register */
+ __IO uint32_t PC; /*!< Offset: 0x010 (R/W) Prescale Counter Register */
+ __IO uint32_t MCR; /*!< Offset: 0x014 (R/W) Match Control Register */
+ __IO uint32_t MR0; /*!< Offset: 0x018 (R/W) Match Register 0 */
+ __IO uint32_t MR1; /*!< Offset: 0x01C (R/W) Match Register 1 */
+ __IO uint32_t MR2; /*!< Offset: 0x020 (R/W) Match Register 2 */
+ __IO uint32_t MR3; /*!< Offset: 0x024 (R/W) Match Register 3 */
+ __IO uint32_t CCR; /*!< Offset: 0x028 (R/W) Capture Control Register */
+ __I uint32_t CR0; /*!< Offset: 0x02C (R/ ) Capture Register 0 */
+ __I uint32_t CR1; /*!< Offset: 0x030 (R/ ) Capture Register 1 */
+ __I uint32_t CR2; /*!< Offset: 0x034 (R/ ) Capture Register 2 */
+ __I uint32_t CR3; /*!< Offset: 0x038 (R/ ) Capture Register 3 */
+ uint32_t RESERVED0;
+ __IO uint32_t MR4; /*!< Offset: 0x040 (R/W) Match Register 4 */
+ __IO uint32_t MR5; /*!< Offset: 0x044 (R/W) Match Register 5 */
+ __IO uint32_t MR6; /*!< Offset: 0x048 (R/W) Match Register 6 */
+ __IO uint32_t PCR; /*!< Offset: 0x04C (R/W) PWM Control Register */
+ __IO uint32_t LER; /*!< Offset: 0x050 (R/W) Load Enable Register */
+ uint32_t RESERVED1[7];
+ __IO uint32_t CTCR; /*!< Offset: 0x070 (R/W) Count Control Register */
+} LPC_PWM_TypeDef;
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+/** @brief Universal Asynchronous Receiver Transmitter (UART) register structure definition */
+typedef struct
+{
+ union {
+ __I uint32_t RBR; /*!< Offset: 0x000 Receiver Buffer Register (R/ ) */
+ __O uint32_t THR; /*!< Offset: 0x000 Transmit Holding Register ( /W) */
+ __IO uint32_t DLL; /*!< Offset: 0x000 Divisor Latch LSB (R/W) */
+ };
+ union {
+ __IO uint32_t DLM; /*!< Offset: 0x004 Divisor Latch MSB (R/W) */
+ __IO uint32_t IER; /*!< Offset: 0x004 Interrupt Enable Register (R/W) */
+ };
+ union {
+ __I uint32_t IIR; /*!< Offset: 0x008 Interrupt ID Register (R/ ) */
+ __O uint32_t FCR; /*!< Offset: 0x008 FIFO Control Register ( /W) */
+ };
+ __IO uint32_t LCR; /*!< Offset: 0x00C Line Control Register (R/W) */
+ uint32_t RESERVED0;
+ __I uint32_t LSR; /*!< Offset: 0x014 Line Status Register (R/ ) */
+ uint32_t RESERVED1;
+ __IO uint32_t SCR; /*!< Offset: 0x01C Scratch Pad Register (R/W) */
+ __IO uint32_t ACR; /*!< Offset: 0x020 Auto-baud Control Register (R/W) */
+ __IO uint32_t ICR; /*!< Offset: 0x024 IrDA Control Register (R/W) */
+ __IO uint32_t FDR; /*!< Offset: 0x028 Fractional Divider Register (R/W) */
+ uint32_t RESERVED2;
+ __IO uint32_t TER; /*!< Offset: 0x030 Transmit Enable Register (R/W) */
+} LPC_UART_TypeDef;
+
+/** @brief Universal Asynchronous Receiver Transmitter 0 (UART0) register structure definition */
+typedef struct
+{
+ union {
+ __I uint32_t RBR; /*!< Offset: 0x000 Receiver Buffer Register (R/ ) */
+ __O uint32_t THR; /*!< Offset: 0x000 Transmit Holding Register ( /W) */
+ __IO uint32_t DLL; /*!< Offset: 0x000 Divisor Latch LSB (R/W) */
+ };
+ union {
+ __IO uint32_t DLM; /*!< Offset: 0x004 Divisor Latch MSB (R/W) */
+ __IO uint32_t IER; /*!< Offset: 0x000 Interrupt Enable Register (R/W) */
+ };
+ union {
+ __I uint32_t IIR; /*!< Offset: 0x008 Interrupt ID Register (R/ ) */
+ __O uint32_t FCR; /*!< Offset: 0x008 FIFO Control Register ( /W) */
+ };
+ __IO uint32_t LCR; /*!< Offset: 0x00C Line Control Register (R/W) */
+ __IO uint32_t MCR; /*!< Offset: 0x010 Modem control Register (R/W) */
+ __I uint32_t LSR; /*!< Offset: 0x014 Line Status Register (R/ ) */
+ __I uint32_t MSR; /*!< Offset: 0x018 Modem status Register (R/ ) */
+ __IO uint32_t SCR; /*!< Offset: 0x01C Scratch Pad Register (R/W) */
+ __IO uint32_t ACR; /*!< Offset: 0x020 Auto-baud Control Register (R/W) */
+ uint32_t RESERVED0;
+ __IO uint32_t FDR; /*!< Offset: 0x028 Fractional Divider Register (R/W) */
+ uint32_t RESERVED1;
+ __IO uint32_t TER; /*!< Offset: 0x030 Transmit Enable Register (R/W) */
+ uint32_t RESERVED2[6];
+ __IO uint32_t RS485CTRL; /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */
+ __IO uint32_t ADRMATCH; /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */
+ __IO uint32_t RS485DLY; /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */
+} LPC_UART1_TypeDef;
+
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/
+/** @brief Serial Peripheral Interface (SPI) register structure definition */
+typedef struct
+{
+ __IO uint32_t SPCR; /*!< Offset: 0x000 SPI Control Register (R/W) */
+ __I uint32_t SPSR; /*!< Offset: 0x004 SPI Status Register (R/) */
+ __IO uint32_t SPDR; /*!< Offset: 0x008 SPI Data Register (R/W) */
+ __IO uint32_t SPCCR; /*!< Offset: 0x00C SPI Clock Counter Register (R/W) */
+ uint32_t RESERVED0[3];
+ __IO uint32_t SPINT; /*!< Offset: 0x01C SPI Interrupt Flag Register (R/W) */
+} LPC_SPI_TypeDef;
+
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/
+/** @brief Synchronous Serial Communication (SSP) register structure definition */
+typedef struct
+{
+ __IO uint32_t CR0; /*!< Offset: 0x000 (R/W) Control Register 0 */
+ __IO uint32_t CR1; /*!< Offset: 0x004 (R/W) Control Register 1 */
+ __IO uint32_t DR; /*!< Offset: 0x008 (R/W) Data Register */
+ __I uint32_t SR; /*!< Offset: 0x00C (R/ ) Status Register */
+ __IO uint32_t CPSR; /*!< Offset: 0x010 (R/W) Clock Prescale Register */
+ __IO uint32_t IMSC; /*!< Offset: 0x014 (R/W) Interrupt Mask Set and Clear Register */
+ __IO uint32_t RIS; /*!< Offset: 0x018 (R/W) Raw Interrupt Status Register */
+ __IO uint32_t MIS; /*!< Offset: 0x01C (R/W) Masked Interrupt Status Register */
+ __IO uint32_t ICR; /*!< Offset: 0x020 (R/W) SSPICR Interrupt Clear Register */
+ __IO uint32_t DMACR; /*!< Offset: 0x024 (R/W) DMA Control Register */
+} LPC_SSP_TypeDef;
+
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
+/** @brief Inter-Integrated Circuit (I2C) register structure definition */
+typedef struct
+{
+ __IO uint32_t CONSET; /*!< Offset: 0x000 (R/W) I2C Control Set Register */
+ __I uint32_t STAT; /*!< Offset: 0x004 (R/ ) I2C Status Register */
+ __IO uint32_t DAT; /*!< Offset: 0x008 (R/W) I2C Data Register */
+ __IO uint32_t ADR0; /*!< Offset: 0x00C (R/W) I2C Slave Address Register 0 */
+ __IO uint32_t SCLH; /*!< Offset: 0x010 (R/W) SCH Duty Cycle Register High Half Word */
+ __IO uint32_t SCLL; /*!< Offset: 0x014 (R/W) SCL Duty Cycle Register Low Half Word */
+ __O uint32_t CONCLR; /*!< Offset: 0x018 (R/W) I2C Control Clear Register */
+ __IO uint32_t MMCTRL; /*!< Offset: 0x01C (R/W) Monitor mode control register */
+ __IO uint32_t ADR1; /*!< Offset: 0x020 (R/W) I2C Slave Address Register 1 */
+ __IO uint32_t ADR2; /*!< Offset: 0x024 (R/W) I2C Slave Address Register 2 */
+ __IO uint32_t ADR3; /*!< Offset: 0x028 (R/W) I2C Slave Address Register 3 */
+ __I uint32_t DATA_BUFFER; /*!< Offset: 0x02C (R/ ) Data buffer Register */
+ __IO uint32_t MASK0; /*!< Offset: 0x030 (R/W) I2C Slave address mask register 0 */
+ __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) I2C Slave address mask register 1 */
+ __IO uint32_t MASK2; /*!< Offset: 0x038 (R/W) I2C Slave address mask register 2 */
+ __IO uint32_t MASK3; /*!< Offset: 0x03C (R/W) I2C Slave address mask register 3 */
+} LPC_I2C_TypeDef;
+
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/
+/** @brief Inter IC Sound (I2S) register structure definition */
+typedef struct
+{
+ __IO uint32_t DAO; /*!< Offset: 0x000 (R/W) Digital Audio Output Register */
+ __IO uint32_t DAI; /*!< Offset: 0x004 (R/W) Digital Audio Input Register */
+ __O uint32_t TXFIFO; /*!< Offset: 0x008 ( /W) Transmit FIFO */
+ __I uint32_t RXFIFO; /*!< Offset: 0x00C (R/ ) Receive FIFO */
+ __I uint32_t STATE; /*!< Offset: 0x010 (R/W) Status Feedback Register */
+ __IO uint32_t DMA1; /*!< Offset: 0x014 (R/W) DMA Configuration Register 1 */
+ __IO uint32_t DMA2; /*!< Offset: 0x018 (R/W) DMA Configuration Register 2 */
+ __IO uint32_t IRQ; /*!< Offset: 0x01C (R/W) Interrupt Request Control Register */
+ __IO uint32_t TXRATE; /*!< Offset: 0x020 (R/W) Transmit reference clock divider Register */
+ __IO uint32_t RXRATE; /*!< Offset: 0x024 (R/W) Receive reference clock divider Register */
+ __IO uint32_t TXBITRATE; /*!< Offset: 0x028 (R/W) Transmit bit rate divider Register */
+ __IO uint32_t RXBITRATE; /*!< Offset: 0x02C (R/W) Receive bit rate divider Register */
+ __IO uint32_t TXMODE; /*!< Offset: 0x030 (R/W) Transmit mode control Register */
+ __IO uint32_t RXMODE; /*!< Offset: 0x034 (R/W) Receive mode control Register */
+} LPC_I2S_TypeDef;
+
+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/
+/** @brief Repetitive Interrupt Timer (RIT) register structure definition */
+typedef struct
+{
+ __IO uint32_t RICOMPVAL;
+ __IO uint32_t RIMASK;
+ __IO uint32_t RICTRL;
+ __IO uint32_t RICOUNTER;
+} LPC_RIT_TypeDef;
+
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/
+/** @brief Real-Time Clock (RTC) register structure definition */
+typedef struct
+{
+ __IO uint32_t ILR; /*!< Offset: 0x000 (R/W) Interrupt Location Register */
+ uint32_t RESERVED0;
+ __IO uint32_t CCR; /*!< Offset: 0x008 (R/W) Clock Control Register */
+ __IO uint32_t CIIR; /*!< Offset: 0x00C (R/W) Counter Increment Interrupt Register */
+ __IO uint32_t AMR; /*!< Offset: 0x010 (R/W) Alarm Mask Register */
+ __I uint32_t CTIME0; /*!< Offset: 0x014 (R/ ) Consolidated Time Register 0 */
+ __I uint32_t CTIME1; /*!< Offset: 0x018 (R/ ) Consolidated Time Register 1 */
+ __I uint32_t CTIME2; /*!< Offset: 0x01C (R/ ) Consolidated Time Register 2 */
+ __IO uint32_t SEC; /*!< Offset: 0x020 (R/W) Seconds Counter Register */
+ __IO uint32_t MIN; /*!< Offset: 0x024 (R/W) Minutes Register */
+ __IO uint32_t HOUR; /*!< Offset: 0x028 (R/W) Hours Register */
+ __IO uint32_t DOM; /*!< Offset: 0x02C (R/W) Day of Month Register */
+ __IO uint32_t DOW; /*!< Offset: 0x030 (R/W) Day of Week Register */
+ __IO uint32_t DOY; /*!< Offset: 0x034 (R/W) Day of Year Register */
+ __IO uint32_t MONTH; /*!< Offset: 0x038 (R/W) Months Register */
+ __IO uint32_t YEAR; /*!< Offset: 0x03C (R/W) Years Register */
+ __IO uint32_t CALIBRATION; /*!< Offset: 0x040 (R/W) Calibration Value Register */
+ __IO uint32_t GPREG0; /*!< Offset: 0x044 (R/W) General Purpose Register 0 */
+ __IO uint32_t GPREG1; /*!< Offset: 0x048 (R/W) General Purpose Register 1 */
+ __IO uint32_t GPREG2; /*!< Offset: 0x04C (R/W) General Purpose Register 2 */
+ __IO uint32_t GPREG3; /*!< Offset: 0x050 (R/W) General Purpose Register 3 */
+ __IO uint32_t GPREG4; /*!< Offset: 0x054 (R/W) General Purpose Register 4 */
+ __IO uint32_t RTC_AUXEN; /*!< Offset: 0x058 (R/W) RTC Auxiliary Enable Register */
+ __IO uint32_t RTC_AUX; /*!< Offset: 0x05C (R/W) RTC Auxiliary Control Register */
+ __IO uint32_t ALSEC; /*!< Offset: 0x060 (R/W) Alarm value for Seconds */
+ __IO uint32_t ALMIN; /*!< Offset: 0x064 (R/W) Alarm value for Minutes */
+ __IO uint32_t ALHOUR; /*!< Offset: 0x068 (R/W) Alarm value for Hours */
+ __IO uint32_t ALDOM; /*!< Offset: 0x06C (R/W) Alarm value for Day of Month */
+ __IO uint32_t ALDOW; /*!< Offset: 0x070 (R/W) Alarm value for Day of Week */
+ __IO uint32_t ALDOY; /*!< Offset: 0x074 (R/W) Alarm value for Day of Year */
+ __IO uint32_t ALMON; /*!< Offset: 0x078 (R/W) Alarm value for Months */
+ __IO uint32_t ALYEAR; /*!< Offset: 0x07C (R/W) Alarm value for Year */
+} LPC_RTC_TypeDef;
+
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/
+/** @brief Watchdog Timer (WDT) register structure definition */
+typedef struct
+{
+ __IO uint32_t MOD; /*!< Offset: 0x000 (R/W) Watchdog mode Register */
+ __IO uint32_t TC; /*!< Offset: 0x004 (R/W) Watchdog timer constant Register */
+ __O uint32_t FEED; /*!< Offset: 0x008 ( /W) Watchdog feed sequence Register */
+ __I uint32_t TV; /*!< Offset: 0x00C (R/ ) Watchdog timer value Register */
+ __IO uint32_t WDCLKSEL;
+} LPC_WDT_TypeDef;
+
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
+/** @brief Analog-to-Digital Converter (ADC) register structure definition */
+typedef struct
+{
+ __IO uint32_t CR; /*!< Offset: 0x000 (R/W) A/D Control Register */
+ __IO uint32_t GDR; /*!< Offset: 0x004 (R/W) A/D Global Data Register */
+ uint32_t RESERVED0;
+ __IO uint32_t INTEN; /*!< Offset: 0x00C (R/W) A/D Interrupt Enable Register */
+ __I uint32_t DR[8]; /*!< Offset: 0x010 (R/ ) A/D Channel # Data Register */
+ __I uint32_t STAT; /*!< Offset: 0x030 (R/ ) A/D Status Register */
+ __IO uint32_t ADTRM; /*!< Offset: 0x034 (R/W) ADC trim Register */
+} LPC_ADC_TypeDef;
+
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/
+/** @brief Digital-to-Analog Converter (DAC) register structure definition */
+typedef struct
+{
+ __IO uint32_t CR; /*!< Offset: 0x000 (R/W) D/A Converter Register */
+ __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) DAC Control register */
+ __IO uint32_t CNTVAL; /*!< Offset: 0x008 (R/W) DAC Counter Value Register */
+} LPC_DAC_TypeDef;
+
+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/
+/** @brief Motor Control Pulse-Width Modulation (MCPWM) register structure definition */
+typedef struct
+{
+ __I uint32_t CON; /*!< Offset: 0x000 (R/ ) PWM Control read address Register */
+ __O uint32_t CON_SET; /*!< Offset: 0x004 ( /W) PWM Control set address Register */
+ __O uint32_t CON_CLR; /*!< Offset: 0x008 ( /W) PWM Control clear address Register */
+ __I uint32_t CAPCON; /*!< Offset: 0x00C (R/ ) Capture Control read address Register */
+ __O uint32_t CAPCON_SET; /*!< Offset: 0x010 ( /W) Capture Control set address Register */
+ __O uint32_t CAPCON_CLR; /*!< Offset: 0x014 ( /W) Event Control clear address Register */
+ __IO uint32_t TC0; /*!< Offset: 0x018 (R/W) Timer Counter Register, channel 0 */
+ __IO uint32_t TC1; /*!< Offset: 0x01C (R/W) Timer Counter Register, channel 1 */
+ __IO uint32_t TC2; /*!< Offset: 0x020 (R/W) Timer Counter Register, channel 2 */
+ __IO uint32_t LIM0; /*!< Offset: 0x024 (R/W) Limit Register, channel 0 */
+ __IO uint32_t LIM1; /*!< Offset: 0x028 (R/W) Limit Register, channel 1 */
+ __IO uint32_t LIM2; /*!< Offset: 0x02C (R/W) Limit Register, channel 2 */
+ __IO uint32_t MAT0; /*!< Offset: 0x030 (R/W) Match Register, channel 0 */
+ __IO uint32_t MAT1; /*!< Offset: 0x034 (R/W) Match Register, channel 1 */
+ __IO uint32_t MAT2; /*!< Offset: 0x038 (R/W) Match Register, channel 2 */
+ __IO uint32_t DT; /*!< Offset: 0x03C (R/W) Dead time Register */
+ __IO uint32_t CP; /*!< Offset: 0x040 (R/W) Commutation Pattern Register */
+ __IO uint32_t CAP0; /*!< Offset: 0x044 (R/W) Capture Register, channel 0 */
+ __IO uint32_t CAP1; /*!< Offset: 0x048 (R/W) Capture Register, channel 1 */
+ __IO uint32_t CAP2; /*!< Offset: 0x04C (R/W) Capture Register, channel 2 */
+ __I uint32_t INTEN; /*!< Offset: 0x050 (R/ ) Interrupt Enable read Register */
+ __O uint32_t INTEN_SET; /*!< Offset: 0x054 ( /W) Interrupt Enable set address Register */
+ __O uint32_t INTEN_CLR; /*!< Offset: 0x058 ( /W) Interrupt Enable clear address Register */
+ __I uint32_t CNTCON; /*!< Offset: 0x05C (R/ ) Count Control read address Register */
+ __O uint32_t CNTCON_SET; /*!< Offset: 0x060 ( /W) Count Control set address Register */
+ __O uint32_t CNTCON_CLR; /*!< Offset: 0x064 ( /W) Count Control clear address Register */
+ __I uint32_t INTF; /*!< Offset: 0x068 (R/ ) Interrupt flags read address Register */
+ __O uint32_t INTF_SET; /*!< Offset: 0x06C ( /W) Interrupt flags set address Register */
+ __O uint32_t INTF_CLR; /*!< Offset: 0x070 ( /W) Interrupt flags clear address Register */
+ __O uint32_t CAP_CLR; /*!< Offset: 0x074 ( /W) Capture clear address Register */
+} LPC_MCPWM_TypeDef;
+
+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/
+/** @brief Quadrature Encoder Interface (QEI) register structure definition */
+typedef struct
+{
+ __O uint32_t CON; /*!< Offset: 0x000 ( /W) Control Register */
+ __I uint32_t STAT; /*!< Offset: 0x004 (R/ ) Encoder Status Register */
+ __IO uint32_t CONF; /*!< Offset: 0x008 (R/W) Configuration Register */
+ __I uint32_t POS; /*!< Offset: 0x00C (R/ ) Position Register */
+ __IO uint32_t MAXPOS; /*!< Offset: 0x010 (R/W) Maximum position Register */
+ __IO uint32_t CMPOS0; /*!< Offset: 0x014 (R/W) Position compare Register 0 */
+ __IO uint32_t CMPOS1; /*!< Offset: 0x018 (R/W) Position compare Register 1 */
+ __IO uint32_t CMPOS2; /*!< Offset: 0x01C (R/W) Position compare Register 2 */
+ __I uint32_t INXCNT; /*!< Offset: 0x020 (R/ ) Index count Register */
+ __IO uint32_t INXCMP0; /*!< Offset: 0x024 (R/W) Index compare Register 0 */
+ __IO uint32_t LOAD; /*!< Offset: 0x028 (R/W) Velocity timer reload Register */
+ __I uint32_t TIME; /*!< Offset: 0x02C (R/ ) Velocity timer Register */
+ __I uint32_t VEL; /*!< Offset: 0x030 (R/ ) Velocity counter Register */
+ __I uint32_t CAP; /*!< Offset: 0x034 (R/ ) Velocity capture Register */
+ __IO uint32_t VELCOMP; /*!< Offset: 0x038 (R/W) Velocity compare Register */
+ __IO uint32_t FILTER;
+ uint32_t RESERVED0[998];
+ __O uint32_t IEC; /*!< Offset: 0xFD8 ( /W) Interrupt enable clear Register */
+ __O uint32_t IES; /*!< Offset: 0xFDC ( /W) Interrupt enable set Register */
+ __I uint32_t INTSTAT; /*!< Offset: 0xFE0 (R/ ) Interrupt status Register */
+ __I uint32_t IE; /*!< Offset: 0xFE4 (R/ ) Interrupt enable Register */
+ __O uint32_t CLR; /*!< Offset: 0xFE8 ( /W) Interrupt status clear Register */
+ __O uint32_t SET; /*!< Offset: 0xFEC ( /W) Interrupt status set Register */
+} LPC_QEI_TypeDef;
+
+/*------------- Controller Area Network (CAN) --------------------------------*/
+/** @brief Controller Area Network Acceptance Filter RAM (CANAF_RAM)structure definition */
+typedef struct
+{
+ __IO uint32_t mask[512]; /*!< Offset: 0x000 (R/W) Acceptance Filter RAM */
+} LPC_CANAF_RAM_TypeDef;
+
+/** @brief Controller Area Network Acceptance Filter(CANAF) register structure definition */
+typedef struct /* Acceptance Filter Registers */
+{
+ __IO uint32_t AFMR; /*!< Offset: 0x000 (R/W) Acceptance Filter Register */
+ __IO uint32_t SFF_sa; /*!< Offset: 0x004 (R/W) Standard Frame Individual Start Address Register */
+ __IO uint32_t SFF_GRP_sa; /*!< Offset: 0x008 (R/W) Standard Frame Group Start Address Register */
+ __IO uint32_t EFF_sa; /*!< Offset: 0x00C (R/W) Extended Frame Start Address Register */
+ __IO uint32_t EFF_GRP_sa; /*!< Offset: 0x010 (R/W) Extended Frame Group Start Address Register */
+ __IO uint32_t ENDofTable; /*!< Offset: 0x014 (R/W) End of AF Tables Register */
+ __I uint32_t LUTerrAd; /*!< Offset: 0x018 (R/ ) LUT Error Address Register */
+ __I uint32_t LUTerr; /*!< Offset: 0x01C (R/ ) LUT Error Register */
+ __IO uint32_t FCANIE; /*!< Offset: 0x020 (R/W) Global FullCANInterrupt Enable Register */
+ __IO uint32_t FCANIC0; /*!< Offset: 0x024 (R/W) FullCAN Interrupt and Capture Register 0 */
+ __IO uint32_t FCANIC1; /*!< Offset: 0x028 (R/W) FullCAN Interrupt and Capture Register 1 */
+} LPC_CANAF_TypeDef;
+
+/** @brief Controller Area Network Central (CANCR) register structure definition */
+typedef struct /* Central Registers */
+{
+ __I uint32_t TxSR; /*!< Offset: 0x000 (R/ ) CAN Central Transmit Status Register */
+ __I uint32_t RxSR; /*!< Offset: 0x004 (R/ ) CAN Central Receive Status Register */
+ __I uint32_t MSR; /*!< Offset: 0x008 (R/ ) CAN Central Miscellaneous Register */
+} LPC_CANCR_TypeDef;
+
+/** @brief Controller Area Network Controller (CAN) register structure definition */
+typedef struct /* Controller Registers */
+{
+ __IO uint32_t MOD; /*!< Offset: 0x000 (R/W) CAN Mode Register */
+ __O uint32_t CMR; /*!< Offset: 0x004 ( /W) CAN Command Register */
+ __IO uint32_t GSR; /*!< Offset: 0x008 (R/W) CAN Global Status Register */
+ __I uint32_t ICR; /*!< Offset: 0x00C (R/ ) CAN Interrupt and Capture Register */
+ __IO uint32_t IER; /*!< Offset: 0x010 (R/W) CAN Interrupt Enable Register */
+ __IO uint32_t BTR; /*!< Offset: 0x014 (R/W) CAN Bus Timing Register */
+ __IO uint32_t EWL; /*!< Offset: 0x018 (R/W) CAN Error Warning Limit Register */
+ __I uint32_t SR; /*!< Offset: 0x01C (R/ ) CAN Status Register */
+ __IO uint32_t RFS; /*!< Offset: 0x020 (R/W) CAN Receive Frame Status Register */
+ __IO uint32_t RID; /*!< Offset: 0x024 (R/W) CAN Receive Identifier Register */
+ __IO uint32_t RDA; /*!< Offset: 0x028 (R/W) CAN Receive Data Register A */
+ __IO uint32_t RDB; /*!< Offset: 0x02C (R/W) CAN Receive Data Register B */
+ __IO uint32_t TFI1; /*!< Offset: 0x030 (R/W) CAN Transmit Frame Information Register 1 */
+ __IO uint32_t TID1; /*!< Offset: 0x034 (R/W) CAN Transmit Identifier Register 1 */
+ __IO uint32_t TDA1; /*!< Offset: 0x038 (R/W) CAN Transmit Data Register A 1 */
+ __IO uint32_t TDB1; /*!< Offset: 0x03C (R/W) CAN Transmit Data Register B 1 */
+ __IO uint32_t TFI2; /*!< Offset: 0x040 (R/W) CAN Transmit Frame Information Register 2 */
+ __IO uint32_t TID2; /*!< Offset: 0x044 (R/W) CAN Transmit Identifier Register 2 */
+ __IO uint32_t TDA2; /*!< Offset: 0x048 (R/W) CAN Transmit Data Register A 2 */
+ __IO uint32_t TDB2; /*!< Offset: 0x04C (R/W) CAN Transmit Data Register B 2 */
+ __IO uint32_t TFI3; /*!< Offset: 0x050 (R/W) CAN Transmit Frame Information Register 3 */
+ __IO uint32_t TID3; /*!< Offset: 0x054 (R/W) CAN Transmit Identifier Register 3 */
+ __IO uint32_t TDA3; /*!< Offset: 0x058 (R/W) CAN Transmit Data Register A 3 */
+ __IO uint32_t TDB3; /*!< Offset: 0x05C (R/W) CAN Transmit Data Register B 3 */
+} LPC_CAN_TypeDef;
+
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/
+/** @brief General Purpose Direct Memory Access (GPDMA) register structure definition */
+typedef struct /* Common Registers */
+{
+ __I uint32_t IntStat; /*!< Offset: 0x000 (R/ ) DMA Interrupt Status Register */
+ __I uint32_t IntTCStat; /*!< Offset: 0x004 (R/ ) DMA Interrupt Terminal Count Request Status Register */
+ __O uint32_t IntTCClear; /*!< Offset: 0x008 ( /W) DMA Interrupt Terminal Count Request Clear Register */
+ __I uint32_t IntErrStat; /*!< Offset: 0x00C (R/ ) DMA Interrupt Error Status Register */
+ __O uint32_t IntErrClr; /*!< Offset: 0x010 ( /W) DMA Interrupt Error Clear Register */
+ __I uint32_t RawIntTCStat; /*!< Offset: 0x014 (R/ ) DMA Raw Interrupt Terminal Count Status Register */
+ __I uint32_t RawIntErrStat; /*!< Offset: 0x018 (R/ ) DMA Raw Error Interrupt Status Register */
+ __I uint32_t EnbldChns; /*!< Offset: 0x01C (R/ ) DMA Enabled Channel Register */
+ __IO uint32_t SoftBReq; /*!< Offset: 0x020 (R/W) DMA Software Burst Request Register */
+ __IO uint32_t SoftSReq; /*!< Offset: 0x024 (R/W) DMA Software Single Request Register */
+ __IO uint32_t SoftLBReq; /*!< Offset: 0x028 (R/W) DMA Software Last Burst Request Register */
+ __IO uint32_t SoftLSReq; /*!< Offset: 0x02C (R/W) DMA Software Last Single Request Register */
+ __IO uint32_t Config; /*!< Offset: 0x030 (R/W) DMA Configuration Register */
+ __IO uint32_t Sync; /*!< Offset: 0x034 (R/W) DMA Synchronization Register */
+} LPC_GPDMA_TypeDef;
+
+/** @brief General Purpose Direct Memory Access Channel (GPDMACH) register structure definition */
+typedef struct /* Channel Registers */
+{
+ __IO uint32_t CSrcAddr; /*!< Offset: 0x000 (R/W) DMA Channel # Source Address Register */
+ __IO uint32_t CDestAddr; /*!< Offset: 0x004 (R/W) DMA Channel # Destination Address Register */
+ __IO uint32_t CLLI; /*!< Offset: 0x008 (R/W) DMA Channel # Linked List Item Register */
+ __IO uint32_t CControl; /*!< Offset: 0x00C (R/W) DMA Channel # Control Register */
+ __IO uint32_t CConfig; /*!< Offset: 0x010 (R/W) DMA Channel # Configuration Register */
+} LPC_GPDMACH_TypeDef;
+
+/*------------- Universal Serial Bus (USB) -----------------------------------*/
+/** @brief Universal Serial Bus (USB) register structure definition */
+typedef struct
+{
+ __I uint32_t Revision; /*!< Offset: 0x000 (R/ ) Revision Register */
+ __IO uint32_t Control; /*!< Offset: 0x004 (R/W) Control Register */
+ __IO uint32_t CommandStatus; /*!< Offset: 0x008 (R/W) Command / Status Register */
+ __IO uint32_t InterruptStatus; /*!< Offset: 0x00C (R/W) Interrupt Status Register */
+ __IO uint32_t InterruptEnable; /*!< Offset: 0x010 (R/W) Interrupt Enable Register */
+ __IO uint32_t InterruptDisable; /*!< Offset: 0x014 (R/W) Interrupt Disable Register */
+ __IO uint32_t HCCA; /*!< Offset: 0x018 (R/W) Host Controller communication Area Register */
+ __I uint32_t PeriodCurrentED; /*!< Offset: 0x01C (R/ ) Register */
+ __IO uint32_t ControlHeadED; /*!< Offset: 0x020 (R/W) Register */
+ __IO uint32_t ControlCurrentED; /*!< Offset: 0x024 (R/W) Register */
+ __IO uint32_t BulkHeadED; /*!< Offset: 0x028 (R/W) Register */
+ __IO uint32_t BulkCurrentED; /*!< Offset: 0x02C (R/W) Register */
+ __I uint32_t DoneHead; /*!< Offset: 0x030 (R/ ) Register */
+ __IO uint32_t FmInterval; /*!< Offset: 0x034 (R/W) Register */
+ __I uint32_t FmRemaining; /*!< Offset: 0x038 (R/ ) Register */
+ __I uint32_t FmNumber; /*!< Offset: 0x03C (R/ ) Register */
+ __IO uint32_t PeriodicStart; /*!< Offset: 0x040 (R/W) Register */
+ __IO uint32_t LSTreshold; /*!< Offset: 0x044 (R/W) Register */
+ __IO uint32_t RhDescriptorA; /*!< Offset: 0x048 (R/W) Register */
+ __IO uint32_t RhDescriptorB; /*!< Offset: 0x04C (R/W) Register */
+ __IO uint32_t RhStatus; /*!< Offset: 0x050 (R/W) Register */
+ __IO uint32_t RhPortStatus1; /*!< Offset: 0x054 (R/W) Register */
+ __IO uint32_t RhPortStatus2; /*!< Offset: 0x05C (R/W) Register */
+ uint32_t RESERVED0[40];
+ __I uint32_t Module_ID; /*!< Offset: 0x0FC (R/ ) Module ID / Version Reverence ID Register */
+ /* USB On-The-Go Registers */
+ __I uint32_t IntSt; /*!< Offset: 0x100 (R/ ) OTG Interrupt Status Register */
+ __IO uint32_t IntEn; /*!< Offset: 0x104 (R/W) OTG Interrupt Enable Register */
+ __O uint32_t IntSet; /*!< Offset: 0x108 ( /W) OTG Interrupt Set Register */
+ __O uint32_t IntClr; /*!< Offset: 0x10C ( /W) OTG Interrupt Clear Register */
+ __IO uint32_t StCtrl; /*!< Offset: 0x110 (R/W) OTG Status and Control Register */
+ __IO uint32_t Tmr; /*!< Offset: 0x114 (R/W) OTG Timer Register */
+ uint32_t RESERVED1[58];
+ /* USB Device Interrupt Registers */
+ __I uint32_t DevIntSt; /*!< Offset: 0x200 (R/ ) USB Device Interrupt Status Register */
+ __IO uint32_t DevIntEn; /*!< Offset: 0x204 (R/W) USB Device Interrupt Enable Register */
+ __O uint32_t DevIntClr; /*!< Offset: 0x208 ( /W) USB Device Interrupt Clear Register */
+ __O uint32_t DevIntSet; /*!< Offset: 0x20C ( /W) USB Device Interrupt Set Register */
+ /* USB Device SIE Command Registers */
+ __O uint32_t CmdCode; /*!< Offset: 0x210 (R/W) USB Command Code Register */
+ __I uint32_t CmdData; /*!< Offset: 0x214 (R/W) USB Command Data Register */
+ /* USB Device Transfer Registers */
+ __I uint32_t RxData; /*!< Offset: 0x218 (R/ ) USB Receive Data Register */
+ __O uint32_t TxData; /*!< Offset: 0x21C ( /W) USB Transmit Data Register */
+ __I uint32_t RxPLen; /*!< Offset: 0x220 (R/ ) USB Receive Packet Length Register */
+ __O uint32_t TxPLen; /*!< Offset: 0x224 ( /W) USB Transmit Packet Length Register */
+ __IO uint32_t Ctrl; /*!< Offset: 0x228 (R/W) USB Control Register */
+ __O uint32_t DevIntPri; /*!< Offset: 0x22C (R/W) USB Device Interrupt Priority Register */
+ /* USB Device Endpoint Interrupt Regs */
+ __I uint32_t EpIntSt; /*!< Offset: 0x230 (R/ ) USB Endpoint Interrupt Status Register */
+ __IO uint32_t EpIntEn; /*!< Offset: 0x234 (R/W) USB Endpoint Interrupt Enable Register */
+ __O uint32_t EpIntClr; /*!< Offset: 0x238 ( /W) USB Endpoint Interrupt Clear Register */
+ __O uint32_t EpIntSet; /*!< Offset: 0x23C ( /W) USB Endpoint Interrupt Set Register */
+ __O uint32_t EpIntPri; /*!< Offset: 0x240 ( /W) USB Endpoint Interrupt Priority Register */
+ /* USB Device Endpoint Realization Reg*/
+ __IO uint32_t ReEp; /*!< Offset: 0x244 (R/W) USB Realize Endpoint Register */
+ __O uint32_t EpInd; /*!< Offset: 0x248 ( /W) USB Endpoint Index Register */
+ __IO uint32_t MaxPSize; /*!< Offset: 0x24C (R/W) USB MaxPacketSize Register */
+ /* USB Device DMA Registers */
+ __I uint32_t DMARSt; /*!< Offset: 0x250 (R/ ) USB DMA Request Status Register */
+ __O uint32_t DMARClr; /*!< Offset: 0x254 ( /W) USB DMA Request Clear Register */
+ __O uint32_t DMARSet; /*!< Offset: 0x258 ( /W) USB DMA Request Set Register */
+ uint32_t RESERVED2[9];
+ __IO uint32_t UDCAH; /*!< Offset: 0x280 (R/W) USB UDCA Head Register */
+ __I uint32_t EpDMASt; /*!< Offset: 0x284 (R/ ) USB EP DMA Status Register */
+ __O uint32_t EpDMAEn; /*!< Offset: 0x288 ( /W) USB EP DMA Enable Register */
+ __O uint32_t EpDMADis; /*!< Offset: 0x28C ( /W) USB EP DMA Disable Register */
+ __I uint32_t DMAIntSt; /*!< Offset: 0x290 (R/ ) USB DMA Interrupt Status Register */
+ __IO uint32_t DMAIntEn; /*!< Offset: 0x294 (R/W) USB DMA Interrupt Enable Register */
+ uint32_t RESERVED3[2];
+ __I uint32_t EoTIntSt; /*!< Offset: 0x2A0 (R/ ) USB End of Transfer Interrupt Status Register */
+ __O uint32_t EoTIntClr; /*!< Offset: 0x2A4 ( /W) USB End of Transfer Interrupt Clear Register */
+ __O uint32_t EoTIntSet; /*!< Offset: 0x2A8 ( /W) USB End of Transfer Interrupt Set Register */
+ __I uint32_t NDDRIntSt; /*!< Offset: 0x2AC (R/ ) USB New DD Request Interrupt Status Register */
+ __O uint32_t NDDRIntClr; /*!< Offset: 0x2B0 ( /W) USB New DD Request Interrupt Clear Register */
+ __O uint32_t NDDRIntSet; /*!< Offset: 0x2B4 ( /W) USB New DD Request Interrupt Set Register */
+ __I uint32_t SysErrIntSt; /*!< Offset: 0x2B8 (R/ ) USB System Error Interrupt Status Register */
+ __O uint32_t SysErrIntClr; /*!< Offset: 0x2BC ( /W) USB System Error Interrupt Clear Register */
+ __O uint32_t SysErrIntSet; /*!< Offset: 0x2C0 ( /W) USB System Error Interrupt Set Register */
+ uint32_t RESERVED4[15];
+ /* USB OTG I2C Registers */
+ union {
+ __I uint32_t I2C_RX; /*!< Offset: 0x300 (R/ ) OTG I2C Receive Register */
+ __O uint32_t I2C_TX; /*!< Offset: 0x300 ( /W) OTG I2C Transmit Register */
+ };
+ __I uint32_t I2C_STS; /*!< Offset: 0x304 (R/ ) OTG I2C Status Register */
+ __IO uint32_t I2C_CTL; /*!< Offset: 0x308 (R/W) OTG I2C Control Register */
+ __IO uint32_t I2C_CLKHI; /*!< Offset: 0x30C (R/W) OTG I2C Clock High Register */
+ __O uint32_t I2C_CLKLO; /*!< Offset: 0x310 ( /W) OTG I2C Clock Low Register */
+ uint32_t RESERVED5[824];
+ /* USB Clock Control Registers */
+ union {
+ __IO uint32_t USBClkCtrl; /*!< Offset: 0xFF4 (R/W) OTG clock controller Register */
+ __IO uint32_t OTGClkCtrl; /*!< Offset: 0xFF4 (R/W) USB clock controller Register */
+ };
+ union {
+ __I uint32_t USBClkSt; /*!< Offset: 0xFF8 (R/ ) OTG clock status Register */
+ __I uint32_t OTGClkSt; /*!< Offset: 0xFF8 (R/ ) USB clock status Register */
+ };
+} LPC_USB_TypeDef;
+
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/
+/** @brief Ethernet Media Access Controller (EMAC) register structure definition */
+typedef struct
+{
+ __IO uint32_t MAC1; /*!< Offset: 0x000 (R/W) MAC Configuration Register 1 */
+ __IO uint32_t MAC2; /*!< Offset: 0x004 (R/W) MAC Configuration Register 2 */
+ __IO uint32_t IPGT; /*!< Offset: 0x008 (R/W) Back-to-Back Inter-Packet-Gap Register */
+ __IO uint32_t IPGR; /*!< Offset: 0x00C (R/W) Non Back-to-Back Inter-Packet-Gap Register */
+ __IO uint32_t CLRT; /*!< Offset: 0x010 (R/W) Collision Window / Retry Register */
+ __IO uint32_t MAXF; /*!< Offset: 0x014 (R/W) Maximum Frame Register */
+ __IO uint32_t SUPP; /*!< Offset: 0x018 (R/W) PHY Support Register */
+ __IO uint32_t TEST; /*!< Offset: 0x01C (R/W) Test Register */
+ __IO uint32_t MCFG; /*!< Offset: 0x020 (R/W) MII Mgmt Configuration Register */
+ __IO uint32_t MCMD; /*!< Offset: 0x024 (R/W) MII Mgmt Command Register */
+ __IO uint32_t MADR; /*!< Offset: 0x028 (R/W) MII Mgmt Address Register */
+ __O uint32_t MWTD; /*!< Offset: 0x02C ( /W) MII Mgmt Write Data Register */
+ __I uint32_t MRDD; /*!< Offset: 0x030 (R/ ) MII Mgmt Read Data Register */
+ __I uint32_t MIND; /*!< Offset: 0x034 (R/ ) MII Mgmt Indicators Register */
+ uint32_t RESERVED0[2];
+ __IO uint32_t SA0; /*!< Offset: 0x040 (R/W) Station Address 0 Register */
+ __IO uint32_t SA1; /*!< Offset: 0x044 (R/W) Station Address 1 Register */
+ __IO uint32_t SA2; /*!< Offset: 0x048 (R/W) Station Address 2 Register */
+ uint32_t RESERVED1[45];
+ __IO uint32_t Command; /*!< Offset: 0x100 (R/W) Command Register */
+ __I uint32_t Status; /*!< Offset: 0x104 (R/ ) Status Register */
+ __IO uint32_t RxDescriptor; /*!< Offset: 0x108 (R/W) Receive Descriptor Base Address Register */
+ __IO uint32_t RxStatus; /*!< Offset: 0x10C (R/W) Receive Status Base Address Register */
+ __IO uint32_t RxDescriptorNumber; /*!< Offset: 0x110 (R/W) Receive Number of Descriptors Register */
+ __I uint32_t RxProduceIndex; /*!< Offset: 0x114 (R/ ) Receive Produce Index Register */
+ __IO uint32_t RxConsumeIndex; /*!< Offset: 0x118 (R/W) Receive Consume Index Register */
+ __IO uint32_t TxDescriptor; /*!< Offset: 0x11C (R/W) Transmit Descriptor Base Address Register */
+ __IO uint32_t TxStatus; /*!< Offset: 0x120 (R/W) Transmit Status Base Address Register */
+ __IO uint32_t TxDescriptorNumber; /*!< Offset: 0x124 (R/W) Transmit Number of Descriptors Register */
+ __IO uint32_t TxProduceIndex; /*!< Offset: 0x128 (R/W) Transmit Produce Index Register */
+ __I uint32_t TxConsumeIndex; /*!< Offset: 0x12C (R/ ) Transmit Consume Index Register */
+ uint32_t RESERVED2[10];
+ __I uint32_t TSV0; /*!< Offset: 0x158 (R/ ) Transmit Status Vector 0 Register */
+ __I uint32_t TSV1; /*!< Offset: 0x15C (R/ ) Transmit Status Vector 1 Register */
+ __I uint32_t RSV; /*!< Offset: 0x160 (R/ ) Receive Status Vector Register */
+ uint32_t RESERVED3[3];
+ __IO uint32_t FlowControlCounter; /*!< Offset: 0x170 (R/W) Flow Control Counter Register */
+ __I uint32_t FlowControlStatus; /*!< Offset: 0x174 (R/ ) Flow Control Status egister */
+ uint32_t RESERVED4[34];
+ __IO uint32_t RxFilterCtrl; /*!< Offset: 0x200 (R/W) Receive Filter Control Register */
+ __I uint32_t RxFilterWoLStatus; /*!< Offset: 0x204 (R/ ) Receive Filter WoL Status Register */
+ __O uint32_t RxFilterWoLClear; /*!< Offset: 0x208 ( /W) Receive Filter WoL Clear Register */
+ uint32_t RESERVED5;
+ __IO uint32_t HashFilterL; /*!< Offset: 0x210 (R/W) Hash Filter Table LSBs Register */
+ __IO uint32_t HashFilterH; /*!< Offset: 0x214 (R/W) Hash Filter Table MSBs Register */
+ uint32_t RESERVED6[882];
+ __I uint32_t IntStatus; /*!< Offset: 0xFE0 (R/ ) Interrupt Status Register */
+ __IO uint32_t IntEnable; /*!< Offset: 0xFE4 (R/W) Interrupt Enable Register */
+ __O uint32_t IntClear; /*!< Offset: 0xFE8 ( /W) Interrupt Clear Register */
+ __O uint32_t IntSet; /*!< Offset: 0xFEC ( /W) Interrupt Set Register */
+ uint32_t RESERVED7;
+ __IO uint32_t PowerDown; /*!< Offset: 0xFF4 (R/W) Power-Down Register */
+} LPC_EMAC_TypeDef;
+
+#if defined ( __CC_ARM )
+#pragma no_anon_unions
+#endif
+
+
+/******************************************************************************/
+/* Peripheral memory map */
+/******************************************************************************/
+/* Base addresses */
+#define LPC_FLASH_BASE (0x00000000UL)
+#define LPC_RAM_BASE (0x10000000UL)
+#ifdef __LPC17XX_REV00
+#define LPC_AHBRAM0_BASE (0x20000000UL)
+#define LPC_AHBRAM1_BASE (0x20004000UL)
+#else
+#define LPC_AHBRAM0_BASE (0x2007C000UL)
+#define LPC_AHBRAM1_BASE (0x20080000UL)
+#endif
+#define LPC_GPIO_BASE (0x2009C000UL)
+#define LPC_APB0_BASE (0x40000000UL)
+#define LPC_APB1_BASE (0x40080000UL)
+#define LPC_AHB_BASE (0x50000000UL)
+#define LPC_CM3_BASE (0xE0000000UL)
+
+/* APB0 peripherals */
+#define LPC_WDT_BASE (LPC_APB0_BASE + 0x00000)
+#define LPC_TIM0_BASE (LPC_APB0_BASE + 0x04000)
+#define LPC_TIM1_BASE (LPC_APB0_BASE + 0x08000)
+#define LPC_UART0_BASE (LPC_APB0_BASE + 0x0C000)
+#define LPC_UART1_BASE (LPC_APB0_BASE + 0x10000)
+#define LPC_PWM1_BASE (LPC_APB0_BASE + 0x18000)
+#define LPC_I2C0_BASE (LPC_APB0_BASE + 0x1C000)
+#define LPC_SPI_BASE (LPC_APB0_BASE + 0x20000)
+#define LPC_RTC_BASE (LPC_APB0_BASE + 0x24000)
+#define LPC_GPIOINT_BASE (LPC_APB0_BASE + 0x28080)
+#define LPC_PINCON_BASE (LPC_APB0_BASE + 0x2C000)
+#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x30000)
+#define LPC_ADC_BASE (LPC_APB0_BASE + 0x34000)
+#define LPC_CANAF_RAM_BASE (LPC_APB0_BASE + 0x38000)
+#define LPC_CANAF_BASE (LPC_APB0_BASE + 0x3C000)
+#define LPC_CANCR_BASE (LPC_APB0_BASE + 0x40000)
+#define LPC_CAN1_BASE (LPC_APB0_BASE + 0x44000)
+#define LPC_CAN2_BASE (LPC_APB0_BASE + 0x48000)
+#define LPC_I2C1_BASE (LPC_APB0_BASE + 0x5C000)
+
+/* APB1 peripherals */
+#define LPC_SSP0_BASE (LPC_APB1_BASE + 0x08000)
+#define LPC_DAC_BASE (LPC_APB1_BASE + 0x0C000)
+#define LPC_TIM2_BASE (LPC_APB1_BASE + 0x10000)
+#define LPC_TIM3_BASE (LPC_APB1_BASE + 0x14000)
+#define LPC_UART2_BASE (LPC_APB1_BASE + 0x18000)
+#define LPC_UART3_BASE (LPC_APB1_BASE + 0x1C000)
+#define LPC_I2C2_BASE (LPC_APB1_BASE + 0x20000)
+#define LPC_I2S_BASE (LPC_APB1_BASE + 0x28000)
+#define LPC_RIT_BASE (LPC_APB1_BASE + 0x30000)
+#define LPC_MCPWM_BASE (LPC_APB1_BASE + 0x38000)
+#define LPC_QEI_BASE (LPC_APB1_BASE + 0x3C000)
+#define LPC_SC_BASE (LPC_APB1_BASE + 0x7C000)
+
+/* AHB peripherals */
+#define LPC_EMAC_BASE (LPC_AHB_BASE + 0x00000)
+#define LPC_GPDMA_BASE (LPC_AHB_BASE + 0x04000)
+#define LPC_GPDMACH0_BASE (LPC_AHB_BASE + 0x04100)
+#define LPC_GPDMACH1_BASE (LPC_AHB_BASE + 0x04120)
+#define LPC_GPDMACH2_BASE (LPC_AHB_BASE + 0x04140)
+#define LPC_GPDMACH3_BASE (LPC_AHB_BASE + 0x04160)
+#define LPC_GPDMACH4_BASE (LPC_AHB_BASE + 0x04180)
+#define LPC_GPDMACH5_BASE (LPC_AHB_BASE + 0x041A0)
+#define LPC_GPDMACH6_BASE (LPC_AHB_BASE + 0x041C0)
+#define LPC_GPDMACH7_BASE (LPC_AHB_BASE + 0x041E0)
+#define LPC_USB_BASE (LPC_AHB_BASE + 0x0C000)
+
+/* GPIOs */
+#define LPC_GPIO0_BASE (LPC_GPIO_BASE + 0x00000)
+#define LPC_GPIO1_BASE (LPC_GPIO_BASE + 0x00020)
+#define LPC_GPIO2_BASE (LPC_GPIO_BASE + 0x00040)
+#define LPC_GPIO3_BASE (LPC_GPIO_BASE + 0x00060)
+#define LPC_GPIO4_BASE (LPC_GPIO_BASE + 0x00080)
+
+
+/******************************************************************************/
+/* Peripheral declaration */
+/******************************************************************************/
+#define LPC_SC ((LPC_SC_TypeDef *) LPC_SC_BASE )
+#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
+#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
+#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
+#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
+#define LPC_GPIO4 ((LPC_GPIO_TypeDef *) LPC_GPIO4_BASE )
+#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE )
+#define LPC_TIM0 ((LPC_TIM_TypeDef *) LPC_TIM0_BASE )
+#define LPC_TIM1 ((LPC_TIM_TypeDef *) LPC_TIM1_BASE )
+#define LPC_TIM2 ((LPC_TIM_TypeDef *) LPC_TIM2_BASE )
+#define LPC_TIM3 ((LPC_TIM_TypeDef *) LPC_TIM3_BASE )
+#define LPC_RIT ((LPC_RIT_TypeDef *) LPC_RIT_BASE )
+#define LPC_UART0 ((LPC_UART_TypeDef *) LPC_UART0_BASE )
+#define LPC_UART1 ((LPC_UART1_TypeDef *) LPC_UART1_BASE )
+#define LPC_UART2 ((LPC_UART_TypeDef *) LPC_UART2_BASE )
+#define LPC_UART3 ((LPC_UART_TypeDef *) LPC_UART3_BASE )
+#define LPC_PWM1 ((LPC_PWM_TypeDef *) LPC_PWM1_BASE )
+#define LPC_I2C0 ((LPC_I2C_TypeDef *) LPC_I2C0_BASE )
+#define LPC_I2C1 ((LPC_I2C_TypeDef *) LPC_I2C1_BASE )
+#define LPC_I2C2 ((LPC_I2C_TypeDef *) LPC_I2C2_BASE )
+#define LPC_I2S ((LPC_I2S_TypeDef *) LPC_I2S_BASE )
+#define LPC_SPI ((LPC_SPI_TypeDef *) LPC_SPI_BASE )
+#define LPC_RTC ((LPC_RTC_TypeDef *) LPC_RTC_BASE )
+#define LPC_GPIOINT ((LPC_GPIOINT_TypeDef *) LPC_GPIOINT_BASE )
+#define LPC_PINCON ((LPC_PINCON_TypeDef *) LPC_PINCON_BASE )
+#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE )
+#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE )
+#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
+#define LPC_DAC ((LPC_DAC_TypeDef *) LPC_DAC_BASE )
+#define LPC_CANAF_RAM ((LPC_CANAF_RAM_TypeDef *) LPC_CANAF_RAM_BASE)
+#define LPC_CANAF ((LPC_CANAF_TypeDef *) LPC_CANAF_BASE )
+#define LPC_CANCR ((LPC_CANCR_TypeDef *) LPC_CANCR_BASE )
+#define LPC_CAN1 ((LPC_CAN_TypeDef *) LPC_CAN1_BASE )
+#define LPC_CAN2 ((LPC_CAN_TypeDef *) LPC_CAN2_BASE )
+#define LPC_MCPWM ((LPC_MCPWM_TypeDef *) LPC_MCPWM_BASE )
+#define LPC_QEI ((LPC_QEI_TypeDef *) LPC_QEI_BASE )
+#define LPC_EMAC ((LPC_EMAC_TypeDef *) LPC_EMAC_BASE )
+#define LPC_GPDMA ((LPC_GPDMA_TypeDef *) LPC_GPDMA_BASE )
+#define LPC_GPDMACH0 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH0_BASE )
+#define LPC_GPDMACH1 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH1_BASE )
+#define LPC_GPDMACH2 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH2_BASE )
+#define LPC_GPDMACH3 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH3_BASE )
+#define LPC_GPDMACH4 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH4_BASE )
+#define LPC_GPDMACH5 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH5_BASE )
+#define LPC_GPDMACH6 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH6_BASE )
+#define LPC_GPDMACH7 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH7_BASE )
+#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE )
+
+/**
+ * @}
+ */
+
+#endif // __LPC17xx_H__
diff --git a/os/hal/platforms/LPC17xx/adc_lld.c b/os/hal/platforms/LPC17xx/adc_lld.c
new file mode 100644
index 000000000..2363dd12f
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/adc_lld.c
@@ -0,0 +1,284 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx ADC driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/adc_lld.c
+ * @brief LPC17xx ADC subsystem low level driver source.
+ * @note Values in samples buffer are from DR register.
+ * To get ADC values make conversion (DR >> 6) & 0x03FF.
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+ADCDriver ADCD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#if LPC17xx_ADC_USE_DMA
+/**
+ * @brief Common IRQ handler.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
+ (void) flags;
+
+ adcp->num++;
+ if (adcp->num == 1) {
+ dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.srcaddr);
+ dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, \
+ &adcp->samples[adcp->nsamples/2]);
+ dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.control);
+ dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.config);
+ _adc_isr_half_code(adcp);
+
+ }
+ else {
+ adcp->num = 0;
+ if (adcp->grpp->circular == TRUE) {
+ dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.srcaddr);
+ dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.dstaddr);
+ dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.control);
+ dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.config);
+ }
+ _adc_isr_full_code(adcp);
+ }
+}
+#endif
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector98) {
+ uint32_t status;
+ uint32_t n;
+ uint8_t i;
+
+ CH_IRQ_PROLOGUE();
+ status = LPC_ADC->STAT;
+
+ n = ADCD1.num;
+
+ /* Note, an overrun may occur only in burst mode, if one or more
+ conversions was (were) lost. */
+ if ((status & ADC0STAT_OVERRUN_MASK)) {
+ if (ADCD1.grpp != NULL)
+ _adc_isr_error_code(&ADCD1, ADC_ERR_OVERRUN);
+ }
+ else {
+
+ status = status & ADC0STAT_DONE_MASK;
+ for (i = 0; i < ADC_MAX_CHANNELS; i++) {
+ if (status & (0x01 << i)) {
+ ADCD1.samples[n] = LPC_ADC->DR[i];
+ n++;
+ }
+ }
+
+ if (n == (ADCD1.nsamples / 2)) {
+ _adc_isr_half_code(&ADCD1);
+ }
+
+ if (n == ADCD1.nsamples) {
+ n = 0;
+ _adc_isr_full_code(&ADCD1);
+ }
+ }
+ ADCD1.num = n;
+ CH_IRQ_EPILOGUE();
+}
+
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = LPC_ADC;
+
+#if LPC17xx_ADC_USE_DMA
+ nvicDisableVector(ADC_IRQn);
+#else
+ nvicEnableVector(ADC_IRQn, CORTEX_PRIORITY_MASK(LPC17xx_ADC_IRQ_PRIORITY));
+#endif
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* If in stopped state then enables the ADC. */
+ if (adcp->state == ADC_STOP) {
+ LPC_SC->PCONP |= (1UL << 12); /* Enable ADC power */
+
+#if LPC17xx_ADC_USE_DMA
+ dmaChannelAllocate(LPC17xx_ADC_DMA_CHANNEL, \
+ (lpc17xx_dmaisr_t)adc_serve_dma_interrupt, \
+ (void *)adcp);
+#endif
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock.*/
+ if (adcp->state == ADC_READY) {
+ adcp->adc->CR = 0; /* Clear PDN bit */
+ LPC_SC->PCONP &= ~(1UL << 12); /* Disable ADC power */
+
+#if LPC17xx_ADC_USE_DMA
+ dmaChannelRelease(LPC17xx_ADC_DMA_CHANNEL);
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+
+ uint32_t dummy;
+ uint32_t cr;
+ uint8_t i;
+#if LPC17xx_ADC_USE_DMA
+ uint8_t ch;
+#endif
+
+ cr = adcp->grpp->cr0;
+ adcp->num = 0;
+ adcp->nsamples = adcp->depth * adcp->grpp->num_channels;
+
+ for (i = 0; i < ADC_MAX_CHANNELS; i++) {
+ dummy = adcp->adc->DR[i]; /* Clear all DONE and OVERRUN flags. */
+ }
+
+#if LPC17xx_ADC_USE_DMA
+ ch = 0;
+ for (i = 0; i < 8; i++) {
+ if (cr & (1UL << i)) {
+ ch = i; /* Get enabled channel number */
+ break;
+ }
+ }
+
+ /* DMA configuration */
+ adcp->adc_dma_cfg.srcaddr = (uint32_t)&adcp->adc->DR[ch];
+ adcp->adc_dma_cfg.dstaddr = (uint32_t)&adcp->samples[0];
+ adcp->adc_dma_cfg.lli = 0;
+ adcp->adc_dma_cfg.control =
+ DMA_CTRL_TRANSFER_SIZE(adcp->nsamples/2) |
+ DMA_CTRL_SRC_BSIZE_1 |
+ DMA_CTRL_DST_BSIZE_1 |
+ DMA_CTRL_SRC_WIDTH_WORD |
+ DMA_CTRL_DST_WIDTH_WORD |
+ DMA_CTRL_SRC_NOINC |
+ DMA_CTRL_DST_INC |
+ DMA_CTRL_PROT1_USER |
+ DMA_CTRL_PROT2_NONBUFF |
+ DMA_CTRL_PROT3_NONCACHE |
+ DMA_CTRL_INT;
+
+ adcp->adc_dma_cfg.config =
+ DMA_CFG_CH_ENABLE |
+ DMA_CFG_SRC_PERIPH(DMA_ADC) |
+ DMA_CFG_TTYPE_P2M |
+ DMA_CFG_IE |
+ DMA_CFG_ITC;
+
+ dmaChannelSrcAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.srcaddr);
+ dmaChannelDstAddr(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.dstaddr);
+ dmaChannelControl(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.control);
+ dmaChannelConfig(LPC17xx_ADC_DMA_CHANNEL, adcp->adc_dma_cfg.config);
+#endif
+
+ /* ADC configuration and conversion start. */
+ adcp->adc->INTEN = adcp->grpp->inten; /* Set ADC interrupt on selected channels */
+ adcp->adc->CR = (cr & 0x0000FFFF) | ((LPC17xx_ADC_CLKDIV - 1) << 8) | AD0CR_PDN;
+ adcp->adc->CR |= cr & 0xFFFF0000;
+
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+#if LPC17xx_ADC_USE_DMA
+ dmaChannelDisable(LPC17xx_ADC_DMA_CHANNEL);
+#endif
+ adcp->adc->CR &= ~(AD0CR_MODE_BURST | AD0CR_START_MASK); /* Disable ADC conversion. */
+ adcp->adc->INTEN = 0; /* Mask ADC interrupts. */
+}
+
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/adc_lld.h b/os/hal/platforms/LPC17xx/adc_lld.h
new file mode 100644
index 000000000..0f13cd731
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/adc_lld.h
@@ -0,0 +1,346 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx ADC driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/adc_lld.h
+ * @brief LPC17xx ADC subsystem low level driver header.
+ * @note Values in samples buffer are from DR register.
+ * To get ADC values make conversion (DR >> 6) & 0x03FF.
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef _ADC_LLD_H_
+#define _ADC_LLD_H_
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define ADC0STAT_DONE_MASK 0x000000FF
+#define ADC0STAT_OVERRUN_MASK 0x0000FF00
+
+#define AD0CR_PDN (1UL << 21)
+/**
+ * @name Absolute Maximum Ratings
+ * @{
+ */
+
+/**
+ * @brief Maximum ADC clock frequency.
+ */
+#define LPC17xx_ADCCLK_MAX 13000000
+
+/**
+ * @brief Available number of ADC channels.
+ */
+#define ADC_MAX_CHANNELS 8
+/** @} */
+
+/**
+ * @name ADC settings
+ * @{
+ */
+
+/**
+ * @name Available analog channels
+ * @note In software-controlled mode only
+ * one channel can be selected.
+ * @{
+ */
+#define AD0CR_CHANNEL0 (1UL << 0)
+#define AD0CR_CHANNEL1 (1UL << 1)
+#define AD0CR_CHANNEL2 (1UL << 2)
+#define AD0CR_CHANNEL3 (1UL << 3)
+#define AD0CR_CHANNEL4 (1UL << 4)
+#define AD0CR_CHANNEL5 (1UL << 5)
+#define AD0CR_CHANNEL6 (1UL << 6)
+#define AD0CR_CHANNEL7 (1UL << 7)
+/** @} */
+
+/**
+ * @name ADC mode types
+ * @note In software-controlled mode only one conversion
+ * is make
+ * @{
+ */
+#define AD0CR_MODE_SOFT (0UL << 16)
+#define AD0CR_MODE_BURST (1UL << 16)
+/** @} */
+
+/**
+ * @name Triggers selection
+ * @note Only use in software-controlled mode
+ * @{
+ */
+#define AD0CR_START_NO (0UL << 24)
+#define AD0CR_START_NOW (1UL << 24)
+#define AD0CR_START_CT16B0_CAP0 (2UL << 24)
+#define AD0CR_START_CT32B0_CAP0 (3UL << 24)
+#define AD0CR_START_CT32B0_MAT0 (4UL << 24)
+#define AD0CR_START_CT32B0_MAT1 (5UL << 24)
+#define AD0CR_START_CT16B0_MAT0 (6UL << 24)
+#define AD0CR_START_CT16B0_MAT1 (7UL << 24)
+#define AD0CR_START_MASK (7UL << 24)
+/** @} */
+
+/**
+ * @name Trigger edge type selection
+ * @note Only use in software-controlled mode.
+ * @{
+ */
+#define AD0CR_EDGE_RISSING (0UL << 27)
+#define AD0CR_EDGE_FALLING (1UL << 27)
+/** @} */
+/** @} */
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC common clock divider.
+ */
+#if !defined(LPC17xx_ADC_CLKDIV) || defined(__DOXYGEN__)
+#define LPC17xx_ADC_CLKDIV 12
+#endif
+
+#if LPC17xx_PCLK/LPC17xx_ADC_CLKDIV > LPC17xx_ADCCLK_MAX
+#error "ADC clock frequency out of the acceptable range (13MHz max)"
+#endif
+
+/**
+ * @brief ADC interrupt priority level setting.
+ */
+#if !defined(LPC17xx_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_ADC_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief ADC DMA enable switch.
+ * @details If set to @p TRUE the support for ADC DMA is included.
+ * @note ADC DMA only support one selected channel. The default is @p FALSE.
+ */
+#if !defined(LPC17xx_ADC_USE_DMA) || defined(__DOXYGEN__)
+#define LPC17xx_ADC_USE_DMA FALSE
+#endif
+
+#if LPC17xx_ADC_USE_DMA || defined(__DOXYGEN__)
+#if !defined(LPC17xx_DMA_REQUIRED)
+#define LPC17xx_DMA_REQUIRED
+#endif
+#endif
+
+/**
+ * @brief ADC DMA channel.
+ */
+#if !defined(LPC17xx_ADC_DMA_CHANNEL) || defined(__DOXYGEN__)
+#define LPC17xx_ADC_DMA_CHANNEL DMA_CHANNEL6
+#endif
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint32_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_OVERRUN = 1 /**< ADC overrun condition. */
+} adcerror_t;
+
+/**
+ * @brief Type of a structure representing an ADC driver.
+ */
+typedef struct ADCDriver ADCDriver;
+
+/**
+ * @brief ADC notification callback type.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object triggering the
+ * callback
+ * @param[in] buffer pointer to the most recent samples data
+ * @param[in] n number of buffer rows available starting from @p buffer
+ */
+typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
+
+/**
+ * @brief ADC error callback type.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object triggering the
+ * callback
+ * @param[in] err ADC error code
+ */
+typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
+
+/**
+ * @brief Conversion group configuration structure.
+ * @details This implementation-dependent structure describes a conversion
+ * operation.
+ * @note The use of this configuration structure requires knowledge of
+ * LPC17xx ADC cell registers interface, please refer to the LPC17xx
+ * reference manual for details.
+ */
+typedef struct {
+ /**
+ * @brief Enables the circular buffer mode for the group.
+ */
+ bool_t circular;
+ /**
+ * @brief Number of the analog channels belonging to the conversion group.
+ */
+ adc_channels_num_t num_channels;
+ /**
+ * @brief Callback function associated to the group or @p NULL.
+ */
+ adccallback_t end_cb;
+ /**
+ * @brief Error callback or @p NULL.
+ */
+ adcerrorcallback_t error_cb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief ADC CR0 register initialization data.
+ * @note All the required bits must be defined into this field.
+ */
+ uint32_t cr0;
+ /**
+ * @brief ADC INTENT register initialization data.
+ * @note In interrupt burst mode only define interrupt for
+ * last enabled channel.
+ */
+ uint32_t inten;
+} ADCConversionGroup;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ uint32_t dummy;
+} ADCConfig;
+
+/**
+ * @brief Structure representing an ADC driver.
+ */
+struct ADCDriver {
+ /**
+ * @brief Driver state.
+ */
+ adcstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ADCConfig *config;
+ /**
+ * @brief Current samples buffer pointer or @p NULL.
+ */
+ adcsample_t *samples;
+ /**
+ * @brief Current samples buffer depth or @p 0.
+ */
+ size_t depth;
+ /**
+ * @brief Current conversion group pointer or @p NULL.
+ */
+ const ADCConversionGroup *grpp;
+#if ADC_USE_WAIT || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ Thread *thread;
+#endif
+#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+#if CH_USE_MUTEXES || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the peripheral.
+ */
+ Mutex mutex;
+#elif CH_USE_SEMAPHORES
+ Semaphore semaphore;
+#endif
+#endif /* ADC_USE_MUTUAL_EXCLUSION */
+#if defined(ADC_DRIVER_EXT_FIELDS)
+ ADC_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the ADCx registers block.
+ */
+ LPC_ADC_TypeDef *adc;
+ /**
+ * @brief Number of all samples in buffer.
+ */
+ uint32_t nsamples;
+ /**
+ * @brief Samples buffer counter.
+ */
+ uint32_t num;
+#if LPC17xx_ADC_USE_DMA
+ /**
+ * @brief ADC DMA configuration structure.
+ */
+ lpc17xx_dma_channel_config_t adc_dma_cfg;
+#endif
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* _ADC_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/gpt_lld.c b/os/hal/platforms/LPC17xx/gpt_lld.c
new file mode 100644
index 000000000..fada91b20
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/gpt_lld.c
@@ -0,0 +1,338 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/gpt_lld.c
+ * @brief LPC17xx GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver identifier.
+ * @note The driver GPT1 allocates the complex timer TIM0 when enabled.
+ */
+#if LPC17xx_GPT_USE_TIM0 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPT2 driver identifier.
+ * @note The driver GPT2 allocates the timer TIM1 when enabled.
+ */
+#if LPC17xx_GPT_USE_TIM1 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPT3 driver identifier.
+ * @note The driver GPT3 allocates the timer TIM2 when enabled.
+ */
+#if LPC17xx_GPT_USE_TIM2 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPT4 driver identifier.
+ * @note The driver GPT4 allocates the timer TIM3 when enabled.
+ */
+#if LPC17xx_GPT_USE_TIM3 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ */
+static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
+ if (gptp->state == GPT_ONESHOT) {
+ gptp->state = GPT_READY; /* Back in GPT_READY state. */
+ gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
+ }
+ gptp->config->callback(gptp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if LPC17xx_GPT_USE_TIM0
+/**
+ * @brief TIM0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector44) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC17xx_GPT_USE_TIM0 */
+
+#if LPC17xx_GPT_USE_TIM1
+/**
+ * @brief TIM1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector48) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC17xx_GPT_USE_TIM0 */
+
+#if LPC17xx_GPT_USE_TIM2
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector4C) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC17xx_GPT_USE_TIM2 */
+
+#if LPC17xx_GPT_USE_TIM3
+/**
+ * @brief TIM3 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector50) {
+
+ CH_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* LPC17xx_GPT_USE_TIM3 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if LPC17xx_GPT_USE_TIM0
+ /* Driver initialization.*/
+ GPTD1.tmr = LPC_TIM0;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if LPC17xx_GPT_USE_TIM1
+ /* Driver initialization.*/
+ GPTD2.tmr = LPC_TIM1;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if LPC17xx_GPT_USE_TIM2
+ /* Driver initialization.*/
+ GPTD3.tmr = LPC_TIM2;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if LPC17xx_GPT_USE_TIM3
+ /* Driver initialization.*/
+ GPTD4.tmr = LPC_TIM3;
+ gptObjectInit(&GPTD4);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint32_t pr;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if LPC17xx_GPT_USE_TIM0
+ if (&GPTD1 == gptp) {
+ LPC_SC->PCONP |= (1UL << 1);
+ nvicEnableVector(TIMER0_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC17xx_GPT_USE_TIM1
+ if (&GPTD2 == gptp) {
+ LPC_SC->PCONP |= (1UL << 2);
+ nvicEnableVector(TIMER1_IRQn, CORTEX_PRIORITY_MASK(3));
+ }
+#endif
+#if LPC17xx_GPT_USE_TIM2
+ if (&GPTD3 == gptp) {
+ LPC_SC->PCONP |= (1UL << 22);
+ nvicEnableVector(TIMER2_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+#if LPC17xx_GPT_USE_TIM3
+ if (&GPTD4 == gptp) {
+ LPC_SC->PCONP |= (1UL << 23);
+ nvicEnableVector(TIMER3_IRQn, CORTEX_PRIORITY_MASK(2));
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ pr = (uint16_t)((LPC17xx_PCLK/ gptp->config->frequency) - 1);
+ chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC17xx_PCLK,
+ "gpt_lld_start(), #1", "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tmr->PR = pr;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+
+#if LPC17xx_GPT_USE_TIM0
+ if (&GPTD1 == gptp) {
+ nvicDisableVector(TIMER0_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 1);
+ }
+#endif
+#if LPC17xx_GPT_USE_TIM1
+ if (&GPTD2 == gptp) {
+ nvicDisableVector(TIMER1_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 2);
+ }
+#endif
+#if LPC17xx_GPT_USE_TIM2
+ if (&GPTD3 == gptp) {
+ nvicDisableVector(TIMER2_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 22);
+ }
+#endif
+#if LPC17xx_GPT_USE_TIM3
+ if (&GPTD4 == gptp) {
+ nvicDisableVector(TIMER3_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 23);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 0;
+ gptp->tmr->TCR = 0;
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tmr->MR0 = interval - 1;
+ gptp->tmr->IR = 1;
+ gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
+ gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
+ gptp->tmr->TCR = 1; /* Timer enabled. */
+ while (gptp->tmr->TCR & 1)
+ ;
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/gpt_lld.h b/os/hal/platforms/LPC17xx/gpt_lld.h
new file mode 100644
index 000000000..09304536e
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/gpt_lld.h
@@ -0,0 +1,208 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/gpt_lld.h
+ * @brief LPC17xx GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef _GPT_LLD_H_
+#define _GPT_LLD_H_
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT1 driver enable switch.
+ * @details If set to @p TRUE the support for GPT1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC17xx_GPT_USE_TIM0) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_USE_TIM0 TRUE
+#endif
+
+/**
+ * @brief GPT2 driver enable switch.
+ * @details If set to @p TRUE the support for GPT2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC17xx_GPT_USE_TIM1) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_USE_TIM1 TRUE
+#endif
+
+/**
+ * @brief GPT3 driver enable switch.
+ * @details If set to @p TRUE the support for GPT3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC17xx_GPT_USE_TIM2) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_USE_TIM2 TRUE
+#endif
+
+/**
+ * @brief GPT4 driver enable switch.
+ * @details If set to @p TRUE the support for GPT4 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC17xx_GPT_USE_TIM3) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_USE_TIM3 TRUE
+#endif
+
+/**
+ * @brief GPT1 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_GPT_TIM0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_TIM0_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT2 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_GPT_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_TIM1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT3 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_GPT_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_TIM2_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief GPT4 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_GPT_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_GPT_TIM3_IRQ_PRIORITY 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !LPC17xx_GPT_USE_TIM0 && !LPC17xx_GPT_USE_TIM1 && \
+ !LPC17xx_GPT_USE_TIM2 && !LPC17xx_GPT_USE_TIM3
+#error "GPT driver activated but no CT peripheral assigned"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint32_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the CTxxBy registers block.
+ */
+ LPC_TIM_TypeDef *tmr;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC17xx_GPT_USE_TIM0 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if LPC17xx_GPT_USE_TIM1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if LPC17xx_GPT_USE_TIM2 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if LPC17xx_GPT_USE_TIM3 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* _GPT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/hal_lld.c b/os/hal/platforms/LPC17xx/hal_lld.c
new file mode 100644
index 000000000..b5190d81c
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/hal_lld.c
@@ -0,0 +1,158 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx HAL driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/hal_lld.c
+ * @brief LPC17xx HAL subsystem low level driver source.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+/**
+ * @brief Register missing in NXP header file.
+ */
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level HAL driver initialization.
+ *
+ * @notapi
+ */
+void hal_lld_init(void) {
+
+ /* SysTick initialization using the system clock.*/
+ nvicSetSystemHandlerPriority(HANDLER_SYSTICK, CORTEX_PRIORITY_SYSTICK);
+ SysTick->LOAD = LPC17xx_CCLK / CH_FREQUENCY - 1;
+ SysTick->VAL = 0;
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_ENABLE_Msk |
+ SysTick_CTRL_TICKINT_Msk;
+
+ /* DWT cycle counter enable.*/
+ SCS_DEMCR |= SCS_DEMCR_TRCENA;
+ DWT_CTRL |= DWT_CTRL_CYCCNTENA;
+
+#if defined(LPC17xx_DMA_REQUIRED)
+ dmaInit();
+#endif
+}
+
+/**
+ * @brief LPC17xx clocks and PLL initialization.
+ * @note All the involved constants come from the file @p board.h.
+ * @note This function must be invoked only after the system reset.
+ *
+ * @special
+ */
+void LPC17xx_clock_init(void) {
+
+ /* Flash wait states setting, the code takes care to not touch TBD bits.*/
+ LPC_SC->FLASHCFG = (LPC_SC->FLASHCFG & ~(0x0000000F << 12)) | (LPC17xx_FLASHCFG_FLASHTIM << 12);
+
+ /* System oscillator initialization if required.*/
+
+#if LPC17xx_MAINOSC_ENABLE
+ LPC_SC->SCS = (1 << 5) | (LPC17xx_OSCRANGE << 4); /* Enable Main oscillator */
+ while (!(LPC_SC->SCS & (1 << 6)))
+ ; /* Wait for main oscillator to be ready */
+#endif
+
+ /* Peripheral clock divider initialization, must be set before enabling Main PLL (PLL0).
+ Read errata sheet ES_LPC176x. */
+ LPC_SC->PCLKSEL0 = LPC17xx_PCLKSEL0;
+ LPC_SC->PCLKSEL1 = LPC17xx_PCLKSEL1;
+
+ LPC_SC->CCLKCFG = LPC17xx_CCLK_DIV - 1; /* Set CPU clock divider */
+
+ LPC_SC->CLKSRCSEL = LPC17xx_SYSCLK_SELECT; /* Select clock source for PLL0 if enabled or CPU */
+
+#if LPC17xx_MAINPLL_ENABLE
+
+ /* PLL0 configuration and start */
+ LPC_SC->PLL0CFG = (LPC17xx_PLL0CFG_NSEL0 << 16) | LPC17xx_PLL0CFG_MSEL0;
+ LPC_SC->PLL0FEED = 0xAA;
+ LPC_SC->PLL0FEED = 0x55;
+
+ LPC_SC->PLL0CON = 0x01; /* Enable PLL0. */
+ LPC_SC->PLL0FEED = 0xAA;
+ LPC_SC->PLL0FEED = 0x55;
+ while (!(LPC_SC->PLL0STAT & (1UL << 26)))
+ ; /* Wait for PLL0 locked */
+
+ LPC_SC->PLL0CON = 0x03; /* Enable and Connect PLL0. */
+ LPC_SC->PLL0FEED = 0xAA;
+ LPC_SC->PLL0FEED = 0x55;
+ while (!(LPC_SC->PLL0STAT & ((1UL << 25) | (1UL << 24))))
+ ; /* Wait for PLL0 connected */
+
+#endif /* LPC17xx_MAINPLL_ENABLE == TRUE */
+
+#if LPC17xx_USBPLL_ENABLE
+ /* PLL1 configuration and start */
+ LPC_SC->PLL1CFG = (LPC17xx_PLL1CFG_PSEL1 << 5) | LPC17xx_PLL1CFG_MSEL1;
+ LPC_SC->PLL1FEED = 0xAA;
+ LPC_SC->PLL1FEED = 0x55;
+
+ LPC_SC->PLL1CON = 0x01; /* Enable PLL1. */
+ LPC_SC->PLL1FEED = 0xAA;
+ LPC_SC->PLL1FEED = 0x55;
+ while (!(LPC_SC->PLL1STAT & (1UL << 10)))
+ ; /* Wait for PLL1 locked */
+
+ LPC_SC->PLL1CON = 0x03; /* Enable and Connect PLL1. */
+ LPC_SC->PLL1FEED = 0xAA;
+ LPC_SC->PLL1FEED = 0x55;
+ while (!(LPC_SC->PLL1STAT & ((1UL << 9) | (1UL << 8))))
+ ; /* Wait for PLL1 connected */
+#endif /* LPC17xx_USBPLL_ENABLE == TRUE */
+
+#if !LPC17xx_USBPLL_ENABLE && HAL_USE_USB
+ LPC_SC->USBCLKCFG = LPC17xx_USBCLKPLL0_SELECT;
+#endif
+
+ /* Power control configuration */
+ LPC_SC->PCONP = (1 << 15) | (1 << 9); /* Enable power for GPIO and RTC */
+
+#if LPC17xx_CLKOUT_ENABLE
+ LPC_SC->CLKOUTCFG = (1UL << 8) | ((LPC17xx_CLKOUT_DIV - 1) << 4) | LPC17xx_CLKOUT_SELECT;
+#endif
+}
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/hal_lld.h b/os/hal/platforms/LPC17xx/hal_lld.h
new file mode 100644
index 000000000..23a0e3574
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/hal_lld.h
@@ -0,0 +1,433 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx HAL driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/hal_lld.h
+ * @brief HAL subsystem low level driver header template.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef _HAL_LLD_H_
+#define _HAL_LLD_H_
+
+#include "LPC17xx.h"
+#include "nvic.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Defines the support for realtime counters in the HAL.
+ */
+#define HAL_IMPLEMENTS_COUNTERS TRUE
+
+/**
+ * @brief Platform name.
+ */
+#define PLATFORM_NAME "LPC17xx"
+
+#define IRCOSCCLK 4000000UL /**< High speed internal clock. */
+
+#define CLKSRCSEL_IRCOSC 0UL /**< Clock source is IRC. */
+#define CLKSRCSEL_MAINOSC 1UL /**< Clock source is Main oscillator. */
+#define CLKSRCSEL_RTCOSC 2UL /**< Clock source is RTC oscillator. */
+
+#define PCLKSEL_CCLK_DIV_4 0UL /**< Peripheral clock source is CCLK/4 */
+#define PCLKSEL_CCLK 1UL /**< Peripheral clock source is CCLK */
+#define PCLKSEL_CCLK_DIV_2 2UL /**< Peripheral clock source is CCLK/2 */
+#define PCLKSEL_CCLK_DIV_8 3UL /**< Peripheral clock source is CCLK/8 */
+#define PCLKSEL_MASK 3UL
+
+#define CLKOUTSEL_CCLK 0UL /**< Clock output is CPU clock. */
+#define CLKOUTSEL_MAINOSC 1UL /**< Clock output is Main oscillator. */
+#define CLKOUTSEL_IRCOSC 2UL /**< Clock output is IRC oscillator. */
+#define CLKOUTSEL_USBCLK 3UL /**< Clock output is USB clock. */
+#define CLKOUTSEL_RTCOSC 4UL /**< Clock output is RTC oscillator. */
+
+#define PCLKSEL_CCLK_DIV_4 0UL /**< Peripheral clock output is CCLK/4 */
+#define PCLKSEL_CCLK 1UL /**< Peripheral clock output is CCLK */
+#define PCLKSEL_CCLK_DIV_2 2UL /**< Peripheral clock output is CCLK/2 */
+#define PCLKSEL_CCLK_DIV_8 3UL /**< Peripheral clock output is CCLK/8 */
+
+#define USBSEL_PLL0_DIV_6 5UL /**< USB clock source is PLL0/6. */
+#define USBSEL_PLL0_DIV_7 7UL /**< USB clock source is PLL0/7. */
+#define USBSEL_PLL0_DIV_9 9UL /**< USB clock source is PLL0/9. */
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Main oscillator enable.
+ */
+#if !defined(LPC17xx_MAINOSC_ENABLE) || defined(__DOXYGEN__)
+#define LPC17xx_MAINOSC_ENABLE TRUE
+#endif
+
+/**
+ * @brief System PLL clock source select.
+ */
+#if !defined(LPC17xx_SYSCLK_SELECT) || defined(__DOXYGEN__)
+#define LPC17xx_SYSCLK_SELECT CLKSRCSEL_MAINOSC
+#endif
+
+/**
+ * @brief Main PLL enable.
+ */
+#if !defined(LPC17xx_MAINPLL_ENABLE) || defined(__DOXYGEN__)
+#define LPC17xx_MAINPLL_ENABLE TRUE
+#endif
+
+/**
+ * @brief Main PLL multiplier.
+ * @note Final frequency must not exceed the CCO ratings.
+ */
+#if !defined(LPC17xx_MAINPLL_MUL) || defined(__DOXYGEN__)
+#define LPC17xx_MAINPLL_MUL 200
+#endif
+
+/**
+ * @brief Main PLL pre-divider.
+ * @note The value must be in the 1..32 range and the final frequency
+ * must not exceed the CCO ratings.
+ */
+#if !defined(LPC17xx_MAINPLL_PREDIV) || defined(__DOXYGEN__)
+#define LPC17xx_MAINPLL_PREDIV 6
+#endif
+
+/**
+ * @brief USB PLL enable.
+ */
+#if !defined(LPC17xx_USBPLL_ENABLE) || defined(__DOXYGEN__)
+#define LPC17xx_USBPLL_ENABLE FALSE
+#endif
+
+/**
+ * @brief USB PLL multiplier.
+ * @note The value must be in the 1..32 range and the final frequency
+ * must not exceed the CCO ratings and USB clock must be equal 48MHz.
+ */
+#if !defined(LPC17xx_USBPLL_MUL) || defined(__DOXYGEN__)
+#define LPC17xx_USBPLL_MUL 4
+#endif
+
+/**
+ * @brief USB PLL divider.
+ * @note The value must be 2, 4, 8 or 16 and the final frequency
+ * must not exceed the CCO ratings and USB clock must be equal 48MHz.
+ */
+#if !defined(LPC17xx_USBPLL_DIV) || defined(__DOXYGEN__)
+#define LPC17xx_USBPLL_DIV 4
+#endif
+
+/**
+ * @brief CPU clock divider.
+ * @note The value must be chosen between (1...255).
+ */
+#if !defined(LPC17xx_CCLK_DIV) || defined(__DOXYGEN__)
+#define LPC17xx_CCLK_DIV 4
+#endif
+
+/**
+ * @brief PCLK clock select.
+ */
+#if !defined(LPC17xx_PCLK_SELECT) || defined(__DOXYGEN__)
+#define LPC17xx_PCLK_SELECT PCLKSEL_CCLK
+#endif
+
+/**
+ * @brief Clock output enable.
+ * @note
+ */
+#if !defined(LPC17xx_CLKOUT_ENABLE) || defined(__DOXYGEN__)
+#define LPC17xx_CLKOUT_ENABLE FALSE
+#endif
+
+/**
+ * @brief Clock output divider.
+ * @note The value must be chosen between (1...16).
+ */
+#if !defined(LPC17xx_CLKOUT_DIV) || defined(__DOXYGEN__)
+#define LPC17xx_CLKOUT_DIV 4
+#endif
+
+/**
+ * @brief Clock output clock source select.
+ */
+#if !defined(LPC17xx_CLKOUT_SELECT) || defined(__DOXYGEN__)
+#define LPC17xx_CLKOUT_SELECT CLKOUTSEL_MAINOSC
+#endif
+
+/**
+ * @brief USB clock PPL0 clock source select.
+ * @note PLL0 output must be 288MHz (USBSEL_PLL0_DIV_6), 384MHz (USBSEL_PLL0_DIV_8) or
+ * 480MHz(USBSEL_PLL0_DIV_10). Only is used when USB PLL (PLL1) disable.
+ */
+#if !defined(LPC17xx_USBCLKPLL0_SELECT) || defined(__DOXYGEN__)
+#define LPC17xx_USBCLKPLL0_SELECT USBSEL_PLL0_DIV_6
+#endif
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/**
+ * @brief Calculated OSCRANGE setting.
+ */
+#if (MAINOSCCLK < 18000000) || defined(__DOXYGEN__)
+#define LPC17xx_OSCRANGE 0
+#else
+#define LPC17xx_OSCRANGE 1
+#endif
+
+/**
+ * @brief PLL input clock frequency.
+ */
+#if (LPC17xx_SYSCLK_SELECT == CLKSRCSEL_IRCOSC) || defined(__DOXYGEN__)
+#define LPC17xx_SYSCLK IRCOSCCLK
+#elif LPC17xx_SYSCLK_SELECT == CLKSRCSEL_MAINOSC
+#define LPC17xx_SYSCLK MAINOSCCLK
+#elif LPC17xx_SYSCLK_SELECT == CLKSRCSEL_RTCOSC
+#define LPC17xx_SYSCLK RTCOSCCLK
+#else
+#error "Invalid LPC17xx_SYSCLK_SELECT clock source specified."
+#endif
+
+/**
+ * @brief MSEL mask in SYSPLLCTRL register.
+ */
+#if ((LPC17xx_MAINPLL_MUL % 2) == 0) || defined(__DOXYGEN__)
+#define LPC17xx_PLL0CFG_MSEL0 ((LPC17xx_MAINPLL_MUL/2) - 1)
+#else
+#error "Invalid LPC17xx_PLL0CFG_MUL value."
+#endif
+
+/**
+ * @brief PSEL mask in SYSPLLCTRL register.
+ */
+#if ((LPC17xx_MAINPLL_PREDIV >= 1) && (LPC17xx_MAINPLL_PREDIV <= 32)) || defined(__DOXYGEN__)
+#define LPC17xx_PLL0CFG_NSEL0 (LPC17xx_MAINPLL_PREDIV - 1)
+#else
+#error "Invalid LPC17xx_MAINPLL_PREDIV value (1 to 32 accepted)."
+#endif
+
+/**
+ * @brief CCO frequency.
+ */
+#define LPC17xx_MAINPLLCCO ((LPC17xx_MAINPLL_MUL * \
+ LPC17xx_SYSCLK)/LPC17xx_MAINPLL_PREDIV)
+
+#if (LPC17xx_MAINPLLCCO < 275000000) || (LPC17xx_SYSPLLCCO > 550000000)
+#error "CCO frequency out of the acceptable range (275...550)."
+#endif
+
+/**
+ * @brief PLL output clock frequency.
+ */
+#if LPC17xx_MAINPLL_ENABLE
+#define LPC17xx_MAINPLLCLK LPC17xx_MAINPLLCCO
+#else
+#define LPC17xx_MAINPLLCLK LPC17xx_SYSCLK
+#endif
+
+/**
+ * @brief CPU clock frequency.
+ * @note Most of LPC17xx have max 120 MHz clock.
+ */
+#define LPC17xx_CCLK (LPC17xx_MAINPLLCLK/LPC17xx_CCLK_DIV)
+#if (LPC17xx_CCLK > 120000000) || defined(__DOXYGEN__)
+#error "CPU Clock out of range."
+#endif
+
+#if LPC17xx_USBPLL_ENABLE
+/**
+ * @brief Main oscillator out of range.
+ */
+#if ((MAINOSCCLK < 10000000) && (MAINOSCCLK > 25000000)) || defined(__DOXYGEN__)
+#error "Main oscillator clock out of range."
+#endif
+
+/**
+ * @brief MSEL1 mask in PLL1CFG register.
+ */
+#if (LPC17xx_USBPLL_MUL >= 1) && (LPC17xx_USBPLL_MUL <= 32) || defined(__DOXYGEN__)
+#define LPC17xx_PLL1CFG_MSEL1 (LPC17xx_USBPLL_MUL - 1)
+#else
+#error "Invalid LPC17xx_USBPLL_MUL value (1 to 32 accepted)."
+#endif
+
+/**
+ * @brief PSEL1 mask in PLL1CFG register.
+ */
+#if (LPC17xx_USBPLL_DIV == 2) || defined(__DOXYGEN__)
+#define LPC17xx_PLL1CFG_PSEL1 0UL
+#elif (LPC17xx_USBPLL_DIV == 4)
+#define LPC17xx_PLL1CFG_PSEL1 1UL
+#elif (LPC17xx_USBPLL_DIV == 8)
+#define LPC17xx_PLL1CFG_PSEL1 2UL
+#elif (LPC17xx_USBPLL_DIV == 16)
+#define LPC17xx_PLL1CFG_PSEL1 3UL
+#else
+#error "Invalid LPC17xx_USBPLL_DIV value (2, 4, 8, 16 accepted)."
+#endif
+
+/**
+ * @brief USB PLL CCO frequency.
+ */
+#define LPC17xx_USBPLLCCO (MAINOSCCLK * LPC17xx_USBPLL_MUL * \
+ LPC17xx_USBPLL_DIV)
+
+#if (LPC17xx_USBPLLCCO < 156000000) || (LPC17xx_SYSPLLCCO > 320000000)
+#error "CCO frequency out of the acceptable range (156...320)"
+#endif
+
+/**
+ * @brief USB clock frequency.
+ * @note Must be 48 MHz.
+ */
+#define LPC17xx_USBCLK (LPC17xx_USBPLLCCO/LPC17xx_USBPLL_DIV)
+#if (LPC17xx_USBCLK != 48000000) || defined(__DOXYGEN__)
+#error "USB clock out of range."
+#endif
+#endif
+
+/**
+ * @brief Peripheral clock frequency.
+ */
+#if (LPC17xx_PCLK_SELECT == PCLKSEL_CCLK_DIV_4) || defined(__DOXYGEN__)
+#define LPC17xx_PCLK (LPC17xx_CCLK/4)
+#define LPC17xx_PCLKSEL0 0x00
+#define LPC17xx_PCLKSEL1 0x00
+#elif (LPC17xx_PCLK_SELECT == PCLKSEL_CCLK)
+#define LPC17xx_PCLK (LPC17xx_CCLK)
+#define LPC17xx_PCLKSEL0 0x55515155
+#define LPC17xx_PCLKSEL1 0x54555455
+#elif (LPC17xx_PCLK_SELECT == PCLKSEL_CCLK_DIV_2)
+#define LPC17xx_PCLK (LPC17xx_CCLK/2)
+#define LPC17xx_PCLKSEL0 0xAAA2A2AA
+#define LPC17xx_PCLKSEL1 0xA8AAA8AA
+#elif (LPC17xx_PCLK_SELECT == PCLKSEL_CCLK_DIV_8)
+#define LPC17xx_PCLK (LPC17xx_CCLK/8)
+#define LPC17xx_PCLKSEL0 0xFFF3F3FF
+#define LPC17xx_PCLKSEL1 0xFCFFFCFF
+#else
+#error "Invalid LPC17xx_PCLK_SELECT value"
+#endif
+
+/**
+ * @brief LPC17xx_CLKOUT_DIV out of range.
+ */
+#if ((LPC17xx_CLKOUT_DIV < 1) && (LPC17xx_CLKOUT_DIV > 16)) || defined(__DOXYGEN__)
+#error "Invalid LPC17xx_CLKOUT_DIV value (1 to 16 accepted)."
+#endif
+
+/**
+ * @brief CLKOUT frequency.
+ */
+#if (LPC17xx_CLKOUT_SELECT == CLKOUTSEL_CCLK) || defined(__DOXYGEN__)
+#define LPC17xx_CLKOUTCLK (LPC17xx_CCLK/LPC17xx_CLKOUT_DIV)
+#elif (LPC17xx_CLKOUT_SELECT == CLKOUTSEL_MAINOSC)
+#define LPC17xx_CLKOUTCLK (MAINOSCCLK/LPC17xx_CLKOUT_DIV)
+#elif (LPC17xx_CLKOUT_SELECT == CLKOUTSEL_IRCOSC)
+#define LPC17xx_CLKOUTCLK (IRCOSCCLK/LPC17xx_CLKOUT_DIV)
+#elif (LPC17xx_CLKOUT_SELECT == CLKOUTSEL_USBCLK)
+#define LPC17xx_CLKOUTCLK (LPC17xx_USBCLK/LPC17xx_CLKOUT_DIV)
+#elif (LPC17xx_CLKOUT_SELECT == CLKOUTSEL_RTCOSC)
+#define LPC17xx_CLKOUTCLK (RTCOSCCLK/LPC17xx_CLKOUT_DIV)
+#else
+#error "Invalid LPC17xx_CLKOUT_SELECT value."
+#endif
+
+/**
+ * @brief CLKOUT frequency out of range.
+ */
+#if (LPC17xx_CLKOUTCLK > 50000000) || defined(__DOXYGEN__)
+#error "CLKOUT frequency out of the acceptable range (less than 50 MHz)"
+#endif
+
+/**
+ * @brief Flash wait states.
+ */
+#if (LPC17xx_CCLK <= 20000000) || defined(__DOXYGEN__)
+#define LPC17xx_FLASHCFG_FLASHTIM 0UL
+#elif LPC17xx_CCLK <= 40000000
+#define LPC17xx_FLASHCFG_FLASHTIM 1UL
+#elif LPC17xx_CCLK <= 60000000
+#define LPC17xx_FLASHCFG_FLASHTIM 2UL
+#elif LPC17xx_CCLK <= 80000000
+#define LPC17xx_FLASHCFG_FLASHTIM 3UL
+#elif LPC17xx_CCLK <= 120000000
+#define LPC17xx_FLASHCFG_FLASHTIM 4UL
+#else
+#define LPC17xx_FLASHCFG_FLASHTIM 5UL
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of the realtime free counter value.
+ */
+typedef uint32_t halrtcnt_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the current value of the system free running counter.
+ * @note This service is implemented by returning the content of the
+ * DWT_CYCCNT register.
+ *
+ * @return The value of the system free running counter of
+ * type halrtcnt_t.
+ *
+ * @notapi
+ */
+#define hal_lld_get_counter_value() DWT_CYCCNT
+
+/**
+ * @brief Realtime counter frequency.
+ * @note The DWT_CYCCNT register is incremented directly by the cpu
+ * clock so this function returns LPC17xx_CCLK.
+ *
+ * @return The realtime counter frequency of type halclock_t.
+ *
+ * @notapi
+ */
+#define hal_lld_get_counter_frequency() LPC17xx_CCLK
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#include "lpc17xx_dma.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void hal_lld_init(void);
+ void LPC17xx_clock_init(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HAL_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/i2c_lld.c b/os/hal/platforms/LPC17xx/i2c_lld.c
new file mode 100644
index 000000000..0fc0bda40
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/i2c_lld.c
@@ -0,0 +1,533 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx I2C driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/*
+ Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+ aka barthess.
+ */
+
+
+/**
+ * @file LPC17xx/i2c_lld.h
+ * @brief LPC17xx I2C subsystem low level driver header.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if LPC17xx_I2C_USE_I2C0 || defined(__DOXYGEN__)
+/** @brief I2C1 driver identifier.*/
+I2CDriver I2CD1;
+#endif
+
+#if LPC17xx_I2C_USE_I2C1 || defined(__DOXYGEN__)
+/** @brief I2C2 driver identifier.*/
+I2CDriver I2CD2;
+#endif
+
+#if LPC17xx_I2C_USE_I2C2 || defined(__DOXYGEN__)
+/** @brief I2C3 driver identifier.*/
+I2CDriver I2CD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Wakes up the waiting thread.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] msg wakeup message
+ *
+ * @notapi
+ */
+#define wakeup_isr(i2cp, msg) { \
+ chSysLockFromIsr(); \
+ if ((i2cp)->thread != NULL) { \
+ Thread *tp = (i2cp)->thread; \
+ (i2cp)->thread = NULL; \
+ tp->p_u.rdymsg = (msg); \
+ chSchReadyI(tp); \
+ } \
+ chSysUnlockFromIsr(); \
+}
+
+/**
+ * @brief Handling of stalled I2C transactions.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_safety_timeout(void *p) {
+ I2CDriver *i2cp = (I2CDriver *)p;
+
+ chSysLockFromIsr();
+ if (i2cp->thread) {
+ Thread *tp = i2cp->thread;
+ i2cp->thread = NULL;
+ tp->p_u.rdymsg = RDY_TIMEOUT;
+ chSchReadyI(tp);
+ }
+ chSysUnlockFromIsr();
+}
+
+/**
+ * @brief I2C error handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t status) {
+ i2cflags_t error = 0;
+
+ switch (status) {
+ case I2C_STATE_ARB_LOST:
+ error = I2CD_ARBITRATION_LOST;
+ break;
+ case I2C_STATE_BUS_ERROR:
+ error = I2CD_BUS_ERROR;
+ break;
+ case I2C_STATE_MS_SLAR_NACK:
+ case I2C_STATE_MS_TDAT_NACK:
+ case I2C_STATE_MS_SLAW_NACK:
+ error = I2CD_ACK_FAILURE ;
+ break;
+ }
+
+ /* If some error has been identified then sends wakes the waiting thread.*/
+ i2cp->errors = error;
+ wakeup_isr(i2cp, RDY_RESET);
+}
+
+/**
+ * @brief I2C serve interrupt handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_interrupt(I2CDriver *i2cp) {
+ uint32_t status;
+ LPC_I2C_TypeDef *dp = i2cp->i2c;
+
+ status = dp->STAT;
+ switch(status) {
+ case I2C_STATE_MS_START: /* A START condition has been transmitted. */
+ if (i2cp->txbytes > 0) {
+ dp->DAT = i2cp->addr; /* Write slave address with WR bit. */
+ }
+ else {
+ dp->DAT = i2cp->addr | I2C_RD_BIT; /* Write slave address with RD bit. */
+ }
+
+ dp->CONCLR = I2C_CONCLR_STAC | I2C_CONCLR_SIC; /* Clear START and SI bit. */
+ break;
+
+ case I2C_STATE_MS_SLAR_NACK: /* NOT ACK has been received, Master will be transmitted STOP. */
+ case I2C_STATE_MS_TDAT_NACK: /* NOT ACK has been received, Master will be transmitted STOP. */
+ case I2C_STATE_MS_SLAW_NACK: /* NOT ACK has been received, Master will be transmitted STOP. */
+ dp->CONSET = I2C_CONSET_STO; /* Set STOP bit. */
+ dp->CONCLR = I2C_CONCLR_SIC; /* Clear SI bit. */
+ i2c_lld_serve_error_interrupt(i2cp, status);
+ break;
+
+ case I2C_STATE_MS_SLAW_ACK: /* SLA + W has been transmitted, ACK has been received. */
+ case I2C_STATE_MS_TDAT_ACK: /* Data byte has been transmitted, ACK has been received. */
+ if (i2cp->txbytes > 0) {
+ dp->DAT = *i2cp->txbuf++; /* Write data. */
+ i2cp->txbytes--;
+ }
+ else {
+ if (i2cp->rxbytes > 0) {
+ dp->CONSET = I2C_CONSET_STO | I2C_CONSET_STA; /* Set START and STOP bit. */
+ } /* STOP bit will be transmit, then START bit. */
+ else {
+ dp->CONSET = I2C_CONSET_STO; /* Set STOP bit. */
+ wakeup_isr(i2cp, RDY_OK);
+ }
+ }
+ dp->CONCLR = I2C_CONCLR_SIC; /* Clear SI bit. */
+ break;
+
+ case I2C_STATE_MS_SLAR_ACK: /* SLA + R has been transmitted, ACK has been received. */
+ case I2C_STATE_MS_RDAT_ACK: /* Data byte has been received, ACK has been returned. */
+ if (status == I2C_STATE_MS_RDAT_ACK) {
+ *i2cp->rxbuf++ = dp->DAT; /* Read data */
+ i2cp->rxbytes--;
+ }
+ if (i2cp->rxbytes == 1) {
+ dp->CONCLR = I2C_CONCLR_SIC | I2C_CONCLR_AAC; /* Clear SI and ACK bit. */
+ }
+ else {
+ dp->CONSET = I2C_CONSET_AA; /* Set ACK bit. */
+ dp->CONCLR = I2C_CONCLR_SIC; /* Clear SI bit. */
+ }
+ break;
+
+ case I2C_STATE_MS_RDAT_NACK: /* Data byte has been received, NOT ACK has been returned. */
+ *i2cp->rxbuf++ = dp->DAT; /* Read data. */
+ i2cp->rxbytes--;
+ dp->CONSET = I2C_CONSET_STO; /* Set STOP bit. */
+ dp->CONCLR = I2C_CONCLR_SIC; /* Clear SI bit. */
+ wakeup_isr(i2cp, RDY_OK);
+ break;
+
+ case I2C_STATE_BUS_ERROR: /* Bus error. */
+ case I2C_STATE_ARB_LOST: /* Arbitration lost. */
+ dp->CONCLR = I2C_CONCLR_SIC; /* Clear SI bit. */
+ i2c_lld_serve_error_interrupt(i2cp, status);
+ break;
+ }
+
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+#if LPC17xx_I2C_USE_I2C0 || defined(__DOXYGEN__)
+/**
+ * @brief I2C0 event interrupt handler.
+ *
+ * @notapi
+ */
+CH_IRQ_HANDLER(Vector68) {
+
+ CH_IRQ_PROLOGUE();
+ i2c_lld_serve_interrupt(&I2CD1);
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if LPC17xx_I2C_USE_I2C1 || defined(__DOXYGEN__)
+/**
+ * @brief I2C1 event interrupt handler.
+ *
+ * @notapi
+ */
+CH_IRQ_HANDLER(Vector6C) {
+
+ CH_IRQ_PROLOGUE();
+ i2c_lld_serve_interrupt(&I2CD2);
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if LPC17xx_I2C_USE_I2C2 || defined(__DOXYGEN__)
+/**
+ * @brief I2C2 event interrupt handler.
+ *
+ * @notapi
+ */
+CH_IRQ_HANDLER(Vector70) {
+
+ CH_IRQ_PROLOGUE();
+ i2c_lld_serve_interrupt(&I2CD3);
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2C driver initialization.
+ *
+ * @notapi
+ */
+void i2c_lld_init(void) {
+
+#if LPC17xx_I2C_USE_I2C0
+ i2cObjectInit(&I2CD1);
+ I2CD1.thread = NULL;
+ I2CD1.i2c = LPC_I2C0;
+#endif
+
+#if LPC17xx_I2C_USE_I2C1
+ i2cObjectInit(&I2CD2);
+ I2CD2.thread = NULL;
+ I2CD2.i2c = LPC_I2C1;
+#endif
+
+#if LPC17xx_I2C_USE_I2C2
+ i2cObjectInit(&I2CD3);
+ I2CD3.thread = NULL;
+ I2CD3.i2c = LPC_I2C2;
+#endif
+}
+
+/**
+ * @brief Configures and activates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_start(I2CDriver *i2cp) {
+
+ uint32_t i2cscl;
+ uint32_t mulh, mull, div;
+ LPC_I2C_TypeDef *dp = i2cp->i2c;
+
+ /* If in stopped state then enables the I2C clock. */
+ if (i2cp->state == I2C_STOP) {
+#if LPC17xx_I2C_USE_I2C0
+ if (&I2CD1 == i2cp) {
+ LPC_SC->PCONP |= (1UL << 7);
+ nvicEnableVector(I2C0_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_I2C_I2C0_IRQ_PRIORITY));
+ }
+#endif
+
+#if LPC17xx_I2C_USE_I2C1
+ if (&I2CD2 == i2cp) {
+ LPC_SC->PCONP |= (1UL << 19);
+ nvicEnableVector(I2C1_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_I2C_I2C1_IRQ_PRIORITY));
+ }
+#endif
+
+#if LPC17xx_I2C_USE_I2C2
+ if (&I2CD3 == i2cp) {
+ LPC_SC->PCONP |= (1UL << 26);
+ nvicEnableVector(I2C2_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_I2C_I2C2_IRQ_PRIORITY));
+ }
+#endif
+ }
+
+ /* Make sure I2C peripheral is disabled */
+ dp->CONCLR = I2C_CONCLR_ENC;
+
+ /* Setup I2C clock parameters.*/
+ i2cscl = (LPC17xx_PCLK/(i2cp->config->clock_timing));
+ if (i2cp->config->mode == I2C_FAST_MODE) {
+ div = 19;
+ mull = 13;
+ mulh = 6;
+ } else if (i2cp->config->mode == I2C_FAST_MODE_PLUS) {
+ div = 3;
+ mull = 2;
+ mulh = 1;
+ } else { /* i2cp->config->mode == I2C_STANDARD_MODE */
+ div = 2;
+ mull = 1;
+ mulh = 1;
+ }
+
+ dp->SCLH = (mulh * i2cscl) / div;
+ dp->SCLL = (mull * i2cscl) / div;
+
+ /* Enable I2C.*/
+ dp->CONSET |= I2C_CONSET_EN;
+
+}
+
+/**
+ * @brief Deactivates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_stop(I2CDriver *i2cp) {
+
+ /* If not in stopped state then disables the I2C clock.*/
+ if (i2cp->state != I2C_STOP) {
+
+ /* I2C disable.*/
+ i2cp->i2c->CONCLR = I2C_CONCLR_ENC;
+#if LPC17xx_I2C_USE_I2C0
+ if (&I2CD1 == i2cp) {
+ nvicDisableVector(I2C0_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 7);
+ }
+#endif
+
+#if LPC17xx_I2C_USE_I2C1
+ if (&I2CD2 == i2cp) {
+ nvicDisableVector(I2C1_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 19);
+ }
+#endif
+
+#if LPC17xx_I2C_USE_I2C2
+ if (&I2CD3 == i2cp) {
+ nvicDisableVector(I2C2_IRQn);
+ LPC_SC->PCONP &= ~(1UL << 26);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Receives data via the I2C bus as master.
+ * @details Number of receiving bytes must be more than 1 on STM32F1x. This is
+ * hardware restriction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if the function succeeded.
+ * @retval RDY_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state</b>.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ systime_t timeout) {
+ LPC_I2C_TypeDef *dp = i2cp->i2c;
+ VirtualTimer vt;
+
+ i2cp->addr = addr << 1;
+ /* Global timeout for the whole operation.*/
+ if (timeout != TIME_INFINITE)
+ chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
+
+ /* Releases the lock from high level driver.*/
+ chSysUnlock();
+
+ /* Initializes driver fields */
+ i2cp->errors = 0;
+ i2cp->rxbuf = rxbuf;
+ i2cp->rxbytes = rxbytes;
+
+ /* This lock will be released in high level driver.*/
+ chSysLock();
+
+ /* Atomic check on the timer in order to make sure that a timeout didn't
+ happen outside the critical zone.*/
+ if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt))
+ return RDY_TIMEOUT;
+
+ /* Starts the operation.*/
+ dp->CONSET = I2C_CONSET_STA;
+
+ /* Waits for the operation completion or a timeout.*/
+ i2cp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+ if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt))
+ chVTResetI(&vt);
+
+ return chThdSelf()->p_u.rdymsg;
+}
+
+/**
+ * @brief Transmits data via the I2C bus as master.
+ * @details Number of receiving bytes must be 0 or more than 1 on STM32F1x.
+ * This is hardware restriction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[in] txbuf pointer to the transmit buffer
+ * @param[in] txbytes number of bytes to be transmitted
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval RDY_OK if the function succeeded.
+ * @retval RDY_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state</b>.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ systime_t timeout) {
+ LPC_I2C_TypeDef *dp = i2cp->i2c;
+ VirtualTimer vt;
+
+ i2cp->addr = addr << 1;
+ /* Global timeout for the whole operation.*/
+ if (timeout != TIME_INFINITE)
+ chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
+
+ /* Releases the lock from high level driver.*/
+ chSysUnlock();
+
+ /* Initializes driver fields */
+ i2cp->errors = 0;
+ i2cp->txbuf = txbuf;
+ i2cp->txbytes = txbytes;
+ i2cp->rxbuf = rxbuf;
+ i2cp->rxbytes = rxbytes;
+
+ /* This lock will be released in high level driver.*/
+ chSysLock();
+
+ /* Atomic check on the timer in order to make sure that a timeout didn't
+ happen outside the critical zone.*/
+ if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt))
+ return RDY_TIMEOUT;
+
+ /* Starts the operation.*/
+ dp->CONSET = I2C_CONSET_STA;
+
+ /* Waits for the operation completion or a timeout.*/
+ i2cp->thread = chThdSelf();
+ chSchGoSleepS(THD_STATE_SUSPENDED);
+
+ if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt))
+ chVTResetI(&vt);
+
+ return chThdSelf()->p_u.rdymsg;
+}
+
+#endif /* HAL_USE_I2C */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/i2c_lld.h b/os/hal/platforms/LPC17xx/i2c_lld.h
new file mode 100644
index 000000000..2cf15b50e
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/i2c_lld.h
@@ -0,0 +1,271 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx I2C driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/*
+ Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+ aka barthess.
+ */
+
+/**
+ * @file LPC17xx/i2c_lld.h
+ * @brief LPC17xx I2C subsystem low level driver header.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#ifndef _I2C_LLD_H_
+#define _I2C_LLD_H_
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define I2C_CONSET_AA 0x04 /* Assert acknowledge flag. */
+#define I2C_CONSET_SI 0x08 /* I2C interrupt flag. */
+#define I2C_CONSET_STO 0x10 /* STOP flag. */
+#define I2C_CONSET_STA 0x20 /* START flag. */
+#define I2C_CONSET_EN 0x40 /* I2C interface enable. */
+
+#define I2C_CONCLR_AAC 0x04 /* Assert acknowledge Clear bit. */
+#define I2C_CONCLR_SIC 0x08 /* I2C interrupt Clear bit. */
+#define I2C_CONCLR_STAC 0x20 /* START flag Clear bit. */
+#define I2C_CONCLR_ENC 0x40 /* I2C interface Disable bit. */
+
+#define I2C_WR_BIT 0x00
+#define I2C_RD_BIT 0x01
+
+#define I2C_STATE_MS_START 0x08
+#define I2C_STATE_MS_RSTART 0x10
+#define I2C_STATE_MS_SLAW_ACK 0x18
+#define I2C_STATE_MS_SLAW_NACK 0x20
+#define I2C_STATE_MS_TDAT_ACK 0x28
+#define I2C_STATE_MS_TDAT_NACK 0x30
+#define I2C_STATE_ARB_LOST 0x38
+
+#define I2C_STATE_MS_SLAR_ACK 0x40
+#define I2C_STATE_MS_SLAR_NACK 0x48
+#define I2C_STATE_MS_RDAT_ACK 0x50
+#define I2C_STATE_MS_RDAT_NACK 0x58
+
+#define I2C_STATE_BUS_ERROR 0x00
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2C0 driver enable switch.
+ * @details If set to @p TRUE the support for device I2C0 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(LPC17xx_I2C_USE_I2C0) || defined(__DOXYGEN__)
+#define LPC17xx_I2C_USE_I2C0 FALSE
+#endif
+
+/**
+ * @brief I2C0 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_I2C_I2C0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_I2C_I2C0_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief I2C1 driver enable switch.
+ * @details If set to @p TRUE the support for device I2C0 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(LPC17xx_I2C_USE_I2C1) || defined(__DOXYGEN__)
+#define LPC17xx_I2C_USE_I2C1 FALSE
+#endif
+
+/**
+ * @brief I2C1 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_I2C_I2C1_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief I2C2 driver enable switch.
+ * @details If set to @p TRUE the support for device I2C0 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(LPC17xx_I2C_USE_I2C2) || defined(__DOXYGEN__)
+#define LPC17xx_I2C_USE_I2C2 FALSE
+#endif
+
+/**
+ * @brief I2C0 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_I2C_I2C2_IRQ_PRIORITY 3
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type representing I2C address.
+ */
+typedef uint16_t i2caddr_t;
+
+/**
+ * @brief I2C Driver condition flags type.
+ */
+typedef uint32_t i2cflags_t;
+/**
+ * @brief Supported modes for the I2C bus.
+ */
+typedef enum {
+ I2C_STANDARD_MODE = 1,
+ I2C_FAST_MODE = 2,
+ I2C_FAST_MODE_PLUS = 3,
+} i2cmode_t;
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ i2cmode_t mode; /**< @brief Specifies the I2C mode. */
+ uint32_t clock_timing; /**< @brief Specifies the clock timing */
+} I2CConfig;
+
+/**
+ * @brief Type of a structure representing an I2C driver.
+ */
+typedef struct I2CDriver I2CDriver;
+
+/**
+ * @brief Structure representing an I2C driver.
+ */
+struct I2CDriver {
+ /**
+ * @brief Driver state.
+ */
+ i2cstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const I2CConfig *config;
+ /**
+ * @brief Error flags.
+ */
+ i2cflags_t errors;
+#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+#if CH_USE_MUTEXES || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the bus.
+ */
+ Mutex mutex;
+#elif CH_USE_SEMAPHORES
+ Semaphore semaphore;
+#endif
+#endif /* I2C_USE_MUTUAL_EXCLUSION */
+#if defined(I2C_DRIVER_EXT_FIELDS)
+ I2C_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion.
+ */
+ Thread *thread;
+ /**
+ * @brief Current slave address without R/W bit.
+ */
+ i2caddr_t addr;
+ /**
+ * @brief Pointer to the transmit buffer.
+ */
+ const uint8_t *txbuf;
+ /**
+ * @brief Number of bytes to transmit.
+ */
+ size_t txbytes;
+ /**
+ * @brief Pointer to the receive buffer.
+ */
+ uint8_t *rxbuf;
+ /**
+ * @brief Number of bytes to receive.
+ */
+ size_t rxbytes;
+ /**
+ * @brief Pointer to the I2C registers block.
+ */
+ LPC_I2C_TypeDef *i2c;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Get errors from I2C driver.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC17xx_I2C_USE_I2C0 && !defined(__DOXYGEN__)
+extern I2CDriver I2CD1;
+#endif
+
+#if LPC17xx_I2C_USE_I2C1 && !defined(__DOXYGEN__)
+extern I2CDriver I2CD2;
+#endif
+
+#if LPC17xx_I2C_USE_I2C2 && !defined(__DOXYGEN__)
+extern I2CDriver I2CD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2c_lld_init(void);
+ void i2c_lld_start(I2CDriver *i2cp);
+ void i2c_lld_stop(I2CDriver *i2cp);
+ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ systime_t timeout);
+ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ systime_t timeout);
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif /* _I2C_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/lpc17xx_dma.c b/os/hal/platforms/LPC17xx/lpc17xx_dma.c
new file mode 100644
index 000000000..b4ae57d31
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/lpc17xx_dma.c
@@ -0,0 +1,205 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx DMA driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/LPC17xx_dma.c
+ * @brief DMA driver code.
+ *
+ * @addtogroup LPC17xx_DMA
+ * @details DMA sharing helper driver. In the LPC17xx the DMA streams are a
+ * shared resource, this driver allows to allocate and free DMA
+ * streams at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The DMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * ISRs when allocating streams.
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring DMA services
+ has been enabled.*/
+#if defined(LPC17xx_DMA_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+ LPC_GPDMACH_TypeDef * \
+ _lpc17xx_dma_channel_config_t[LPC17xx_DMA_CHANNELS] = {
+ LPC_GPDMACH0, LPC_GPDMACH1, LPC_GPDMACH2, LPC_GPDMACH3, LPC_GPDMACH4,
+ LPC_GPDMACH5, LPC_GPDMACH6, LPC_GPDMACH7 };
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA ISR redirector type.
+ */
+typedef struct {
+ lpc17xx_dmaisr_t dma_func; /**< @brief DMA callback function. */
+ void *dma_param; /**< @brief DMA callback parameter. */
+} dma_isr_redir_t;
+
+/**
+ * @brief Mask of the allocated streams.
+ */
+static uint32_t dma_streams_mask;
+
+/**
+ * @brief DMA IRQ redirectors.
+ */
+static dma_isr_redir_t dma_isr_redir[LPC17xx_DMA_CHANNELS];
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(VectorA8) {
+ uint32_t irq_status;
+ uint32_t err_status;
+ uint8_t i;
+
+ CH_IRQ_PROLOGUE();
+
+ irq_status = LPC_GPDMA->IntTCStat;
+ LPC_GPDMA->IntTCClear = irq_status; /* Clear DMA interrupt flag */
+ err_status = LPC_GPDMA->IntErrStat;
+ LPC_GPDMA->IntErrClr = err_status; /* Clear DMA error flag if any*/
+
+ for (i = 0; i < LPC17xx_DMA_CHANNELS; i++) {
+ if (irq_status & (1UL << i)) {
+ if (dma_isr_redir[i].dma_func)
+ dma_isr_redir[i].dma_func(dma_isr_redir[i].dma_param, err_status);
+ }
+ }
+
+
+ CH_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief LPC17xx DMA initialization.
+ *
+ * @init
+ */
+void dmaInit(void) {
+ uint8_t i;
+
+ LPC_SC->PCONP |= (1UL << 29); /* Enable DMA power */
+
+ /* Disable all channels */
+ for (i = 0; i < LPC17xx_DMA_CHANNELS; i++)
+ _lpc17xx_dma_channel_config_t[i]->CConfig = 0;
+
+ LPC_GPDMA->IntTCClear = 0xFF;
+ LPC_GPDMA->IntErrClr = 0xFF;
+
+ LPC_GPDMA->Config = DMACCONFIG_E; /* Enable DMA Controller */
+ while((LPC_GPDMA->Config & DMACCONFIG_E) != 0x01)
+ ;
+
+ nvicEnableVector(DMA_IRQn, CORTEX_PRIORITY_MASK(LPC17xx_DMA_IRQ_PRIORITY));
+}
+
+/**
+ * @brief Allocates a DMA channel.
+ * @details The channel is allocated.
+ * @pre The channel must not be already in use or an error is returned.
+ * @post The channel is allocated and the default ISR handler redirected
+ * to the specified function.
+ * @post The channel must be freed using @p dmaChannelRelease() before it can
+ * be reused with another peripheral.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmach DMA channel number
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return The operation status.
+ * @retval FALSE no error, stream taken.
+ * @retval TRUE error, stream already taken.
+ *
+ * @special
+ */
+bool_t dmaChannelAllocate(lpc17xx_dma_channel_t dmach,
+ lpc17xx_dmaisr_t func,
+ void *param) {
+ uint32_t channel;
+ channel = (1UL << dmach);
+
+ /* Checks if the channel is already taken.*/
+ if ((dma_streams_mask & channel) != 0)
+ return TRUE;
+
+ /* Marks the stream as allocated.*/
+ dma_isr_redir[dmach].dma_func = func;
+ dma_isr_redir[dmach].dma_param = param;
+ dma_streams_mask |= channel;
+
+ return FALSE;
+}
+
+/**
+ * @brief Releases a DMA channel.
+ * @details The channel is freed.
+ * Trying to release a unallocated channel is an illegal operation
+ * and is trapped if assertions are enabled.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post The channel is again available.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmach DMA channel number
+ *
+ * @special
+ */
+void dmaChannelRelease(lpc17xx_dma_channel_t dmach) {
+
+ uint32_t channel;
+ channel = (1UL << dmach);
+
+ /* Check if the streams is not taken.*/
+ chDbgAssert((dma_streams_mask & channel) != 0,
+ "dmaStreamRelease(), #1", "not allocated");
+
+ dma_streams_mask &= ~channel; /* Marks the stream as not allocated.*/
+}
+
+#endif /* LPC17xx_DMA_REQUIRED */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/lpc17xx_dma.h b/os/hal/platforms/LPC17xx/lpc17xx_dma.h
new file mode 100644
index 000000000..e581265a5
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/lpc17xx_dma.h
@@ -0,0 +1,415 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx DMA driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/LPC17xx_dma.h
+ * @brief DMA driver header.
+ *
+ * @addtogroup LPC17xx_DMA
+ * @{
+ */
+
+#ifndef _LPC17xx_DMA_H_
+#define _LPC17xx_DMA_H_
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define DMACCONFIG_E (1UL << 0)
+#define DMACCONFIG_M (1UL << 1)
+
+/**
+ * @brief Total number of DMA streams.
+ * @note This is the total number of streams among all the DMA units.
+ */
+#define LPC17xx_DMA_CHANNELS 8
+
+/**
+ * @name DMA control data configuration
+ * @{
+ */
+
+/**
+ * @brief DMA transfer size.
+ *
+ * @param[in] n DMA transfer size
+ */
+#define DMA_CTRL_TRANSFER_SIZE(n) (n)
+
+/**
+ * @brief DMA source burst size.
+ */
+#define DMA_CTRL_SRC_BSIZE_1 (0 << 12)
+#define DMA_CTRL_SRC_BSIZE_4 (1UL << 12)
+#define DMA_CTRL_SRC_BSIZE_8 (2UL << 12)
+#define DMA_CTRL_SRC_BSIZE_16 (3UL << 12)
+#define DMA_CTRL_SRC_BSIZE_32 (4UL << 12)
+#define DMA_CTRL_SRC_BSIZE_64 (5UL << 12)
+#define DMA_CTRL_SRC_BSIZE_128 (6UL << 12)
+#define DMA_CTRL_SRC_BSIZE_256 (7UL << 12)
+
+/**
+ * @brief DMA destination burst size.
+ * @{
+ */
+#define DMA_CTRL_DST_BSIZE_1 (0 << 15)
+#define DMA_CTRL_DST_BSIZE_4 (1UL << 15)
+#define DMA_CTRL_DST_BSIZE_8 (2UL << 15)
+#define DMA_CTRL_DST_BSIZE_16 (3UL << 15)
+#define DMA_CTRL_DST_BSIZE_32 (4UL << 15)
+#define DMA_CTRL_DST_BSIZE_64 (5UL << 15)
+#define DMA_CTRL_DST_BSIZE_128 (6UL << 15)
+#define DMA_CTRL_DST_BSIZE_256 (7UL << 15)
+/** @} */
+
+/**
+ * @name DMA source transfer width.
+ * @{
+ */
+#define DMA_CTRL_SRC_WIDTH_BYTE (0 << 18)
+#define DMA_CTRL_SRC_WIDTH_HWORD (1UL << 18)
+#define DMA_CTRL_SRC_WIDTH_WORD (2UL << 18)
+/** @} */
+
+/**
+ * @name DMA destination transfer width.
+ * @{
+ */
+#define DMA_CTRL_DST_WIDTH_BYTE (0 << 21)
+#define DMA_CTRL_DST_WIDTH_HWORD (1UL << 21)
+#define DMA_CTRL_DST_WIDTH_WORD (2UL << 21)
+
+/**
+ * @name DMA source increment after each transfer.
+ * @{
+ */
+#define DMA_CTRL_SRC_NOINC (0UL << 26)
+#define DMA_CTRL_SRC_INC (1UL << 26)
+
+/**
+ * @name DMA destination increment after each transfer.
+ * @{
+ */
+#define DMA_CTRL_DST_NOINC (0UL << 27)
+#define DMA_CTRL_DST_INC (1UL << 27)
+
+/**
+ * @name DMA bus access bits.
+ * @{
+ */
+#define DMA_CTRL_PROT1_USER (0 << 28)
+#define DMA_CTRL_PROT1_PRIV (1UL << 28)
+
+#define DMA_CTRL_PROT2_NONBUFF (0 << 29)
+#define DMA_CTRL_PROT2_BUFF (1UL << 29)
+
+#define DMA_CTRL_PROT3_NONCACHE (0 << 30)
+#define DMA_CTRL_PROT3_CACHE (1UL << 30)
+/** @} */
+
+/**
+ * @name DMA terminal count interrupt enable.
+ * @{
+ */
+#define DMA_CTRL_INT (1UL << 31)
+/** @} */
+
+/**
+ * @name DMA channel enable.
+ * @{
+ */
+#define DMA_CFG_CH_ENABLE (1UL << 0)
+
+/**
+ * @brief Source peripheral.
+ *
+ * @param[in] source source peripheral
+ */
+#define DMA_CFG_SRC_PERIPH(src) ((src) << 1)
+
+/**
+ * @brief Destination peripheral.
+ *
+ * @param[in] destination destination peripheral
+ */
+#define DMA_CFG_DST_PERIPH(dst) ((dst) << 6)
+
+/**
+ * @name Transfer type.
+ * @{
+ */
+#define DMA_CFG_TTYPE_M2M (0 << 11)
+#define DMA_CFG_TTYPE_M2P (1UL << 11)
+#define DMA_CFG_TTYPE_P2M (2UL << 11)
+#define DMA_CFG_TTYPE_P2P (3UL << 11)
+/** @} */
+
+/**
+ * @name Interrupt error mask.
+ * @{
+ */
+#define DMA_CFG_IE (1UL << 14)
+/** @} */
+
+/**
+ * @name Terminal count interrupt mask.
+ * @{
+ */
+#define DMA_CFG_ITC (1UL << 15)
+/** @} */
+
+/**
+ * @name Active.
+ * @note Read only
+ * @{
+ */
+#define DMA_CFG_ACTIVE (1UL << 17)
+/** @} */
+
+/**
+ * @name Halt.
+ * @{
+ */
+#define DMA_CFG_HALT (1UL << 18)
+/** @} */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA interrupt priority level setting.
+ */
+#if !defined(LPC17xx_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_DMA_IRQ_PRIORITY 3
+#endif
+
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+typedef struct {
+ volatile uint32_t srcaddr; /**< @brief Source address. */
+ volatile uint32_t dstaddr; /**< @brief Destination address. */
+ volatile uint32_t lli; /**< @brief Linked List Item. */
+ volatile uint32_t control; /**< @brief Control. */
+ volatile uint32_t config; /**< @brief Configuration. */
+} lpc17xx_dma_channel_config_t;
+
+/**
+ * @brief DMA channel number.
+ */
+typedef enum {
+ DMA_CHANNEL0 = 0,
+ DMA_CHANNEL1 = 1,
+ DMA_CHANNEL2 = 2,
+ DMA_CHANNEL3 = 3,
+ DMA_CHANNEL4 = 4,
+ DMA_CHANNEL5 = 5,
+ DMA_CHANNEL6 = 6,
+ DMA_CHANNEL7 = 7
+
+} lpc17xx_dma_channel_t;
+
+ /**
+ * @brief DMA source or destination type.
+ */
+ typedef enum {
+ DMA_SSP0_TX = 0,
+ DMA_SSP0_RX = 1,
+ DMA_SSP1_TX = 2,
+ DMA_SSP1_RX = 3,
+ DMA_ADC = 4,
+ DMA_I2S_CH0 = 5,
+ DMA_I2S_CH1 = 6,
+ DMA_DAC = 7,
+ DMA_UART0_TX_MAT0_0 = 8,
+ DMA_UART0_RX_MAT0_1 = 9,
+ DMA_UART1_TX_MAT1_0 = 10,
+ DMA_UART1_RX_MAT1_1 = 11,
+ DMA_UART2_TX_MAT2_0 = 12,
+ DMA_UART2_RX_MAT2_1 = 13,
+ DMA_UART3_TX_MAT3_0 = 14,
+ DMA_UART3_RX_MAT3_1 = 15
+ } lpc17xx_dma_src_dst_t;
+
+/**
+ * @brief LPC17xx DMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the xISR register, the bits
+ * are aligned to bit zero
+ */
+typedef void (*lpc17xx_dmaisr_t)(void *p, uint32_t flags);
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+
+/**
+ * @brief Associates a memory source to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmach DMA channel number
+ * @param[in] addr pointer to a source address
+ *
+ * @special
+ */
+#define dmaChannelSrcAddr(dmach, addr) \
+ _lpc17xx_dma_channel_config_t[dmach]->CSrcAddr = (uint32_t)(addr)
+
+/**
+ * @brief Associates a memory destination to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmach DMA channel number
+ * @param[in] addr pointer to a destination address
+ *
+ * @special
+ */
+#define dmaChannelDstAddr(dmach, addr) \
+ _lpc17xx_dma_channel_config_t[dmach]->CDestAddr = (uint32_t)(addr)
+
+/**
+ * @brief Associates a linked list item address to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmach DMA channel number
+ * @param[in] addr pointer to a linked list item
+ *
+ * @special
+ */
+#define dmaChannelLinkedList(dmach, addr) \
+ _lpc17xx_dma_channel_config_t[dmach]->CLLI = (((uint32_t)(addr)) << 2)
+
+/**
+ * @brief Set control configuration to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmach DMA channel number
+ * @param[in] ctrl control configuration value
+ *
+ * @special
+ */
+#define dmaChannelControl(dmach, ctrl) \
+ _lpc17xx_dma_channel_config_t[dmach]->CControl = (ctrl)
+
+/**
+ * @brief Set configuration to a DMA channel.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaStreamAllocate().
+ * @post After use the channel can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmach DMA channel number
+ * @param[in] config dma channel configuration value
+ *
+ * @special
+ */
+#define dmaChannelConfig(dmach, config) \
+ _lpc17xx_dma_channel_config_t[dmach]->CConfig = (config)
+
+/**
+ * @brief Trigger DMA software burst transfer request.
+ *
+ * @param[in] src peripheral source request
+ *
+ * @special
+ */
+#define dmaSoftBurstRequest(src) \
+ LPC_GPDMA->SoftBReq = (src)
+
+/**
+ * @brief Trigger DMA software single transfer request.
+ *
+ * @param[in] src peripheral source request
+ *
+ * @special
+ */
+#define dmaSoftSingleRequest(src) \
+ LPC_GPDMA->SoftSReq = (src)
+
+/**
+ * @brief DMA channel enable.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmach DMA channel number
+ *
+ * @special
+ */
+#define dmaChannelEnable(dmach) \
+ _lpc17xx_dma_channel_config_t[dmach]->CConfig |= (DMA_CFG_CH_ENABLE)
+
+/**
+ * @brief DMA channel disable.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmach DMA channel number
+ *
+ * @special
+ */
+#define dmaChannelDisable(dmach) \
+ _lpc17xx_dma_channel_config_t[dmach]->CConfig &= ~(DMA_CFG_CH_ENABLE)
+
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern LPC_GPDMACH_TypeDef * _lpc17xx_dma_channel_config_t[];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void dmaInit(void);
+ bool_t dmaChannelAllocate(lpc17xx_dma_channel_t dmach,
+ lpc17xx_dmaisr_t func,
+ void *param);
+ void dmaChannelRelease(lpc17xx_dma_channel_t dmach);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LPC17xx_DMA_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/pal_lld.c b/os/hal/platforms/LPC17xx/pal_lld.c
new file mode 100644
index 000000000..19aa390f8
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/pal_lld.c
@@ -0,0 +1,158 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/pal_lld.c
+ * @brief LPC17xx GPIO low level driver code.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+/**
+ * @brief LPC17xx I/O ports configuration.
+ * @details GPIO unit registers initialization.
+ *
+ * @param[in] config the LPC17xx ports configuration
+ *
+ * @notapi
+ */
+void _pal_lld_init(const PALConfig *config) {
+
+ LPC_GPIO0->FIODIR = config->P0.dir;
+ LPC_GPIO1->FIODIR = config->P1.dir;
+ LPC_GPIO2->FIODIR = config->P2.dir;
+ LPC_GPIO3->FIODIR = config->P3.dir;
+ LPC_GPIO4->FIODIR = config->P4.dir;
+ LPC_GPIO0->FIOMASK = 0;
+ LPC_GPIO1->FIOMASK = 0;
+ LPC_GPIO2->FIOMASK = 0;
+ LPC_GPIO3->FIOMASK = 0;
+ LPC_GPIO4->FIOMASK = 0;
+ LPC_GPIO0->FIOPIN = config->P0.data;
+ LPC_GPIO1->FIOPIN = config->P1.data;
+ LPC_GPIO2->FIOPIN = config->P2.data;
+ LPC_GPIO3->FIOPIN = config->P3.data;
+ LPC_GPIO4->FIOPIN = config->P4.data;
+}
+
+/**
+ * @brief Reads a group of bits.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @return The group logical states.
+ *
+ * @notapi
+ */
+uint32_t _pal_lld_readgroup(ioportid_t port,
+ ioportmask_t mask,
+ uint32_t offset) {
+
+ uint32_t p;
+
+ port->FIOMASK = ~((mask) << offset);
+ p = port->FIOPIN;
+ port->FIOMASK = 0;
+ return p;
+}
+
+/**
+ * @brief Writes a group of bits.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] bits bits to be written. Values exceeding the group width
+ * are masked.
+ *
+ * @notapi
+ */
+void _pal_lld_writegroup(ioportid_t port,
+ ioportmask_t mask,
+ uint32_t offset,
+ uint32_t bits) {
+
+ port->FIOMASK = ~((mask) << offset);
+ port->FIOPIN = bits;
+ port->FIOMASK = 0;
+}
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with
+ * high state.
+ * @note This function does not alter the @p PINSELx registers. Alternate
+ * functions setup must be handled by device-specific code.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @notapi
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode) {
+
+ switch (mode) {
+ case PAL_MODE_RESET:
+ case PAL_MODE_INPUT:
+ port->FIODIR &= ~mask;
+ break;
+ case PAL_MODE_UNCONNECTED:
+ palSetPort(port, PAL_WHOLE_PORT);
+ case PAL_MODE_OUTPUT_PUSHPULL:
+ port->FIODIR |= mask;
+ break;
+ }
+}
+
+#endif /* HAL_USE_PAL */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/pal_lld.h b/os/hal/platforms/LPC17xx/pal_lld.h
new file mode 100644
index 000000000..45812b3f5
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/pal_lld.h
@@ -0,0 +1,332 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/pal_lld.h
+ * @brief LPC17xx GPIO low level driver header.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#ifndef _PAL_LLD_H_
+#define _PAL_LLD_H_
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+#undef PAL_MODE_INPUT_PULLUP
+#undef PAL_MODE_INPUT_PULLDOWN
+#undef PAL_MODE_INPUT_ANALOG
+#undef PAL_MODE_OUTPUT_OPENDRAIN
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO port setup info.
+ */
+typedef struct {
+ /** Initial value for FIO_PIN register.*/
+ uint32_t data;
+ /** Initial value for FIO_DIR register.*/
+ uint32_t dir;
+} lpc17xx_gpio_setup_t;
+
+/**
+ * @brief GPIO static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialized the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ * @note The @p IOCON block is not configured, initially all pins have
+ * enabled pullups and are programmed as GPIO. It is responsibility
+ * of the various drivers to reprogram the pins in the proper mode.
+ * Pins that are not handled by any driver may be programmed in
+ * @p board.c.
+ */
+typedef struct {
+ /** @brief GPIO 0 setup data.*/
+ lpc17xx_gpio_setup_t P0;
+ /** @brief GPIO 1 setup data.*/
+ lpc17xx_gpio_setup_t P1;
+ /** @brief GPIO 2 setup data.*/
+ lpc17xx_gpio_setup_t P2;
+ /** @brief GPIO 3 setup data.*/
+ lpc17xx_gpio_setup_t P3;
+ /** @brief GPIO 4 setup data.*/
+ lpc17xx_gpio_setup_t P4;
+} PALConfig;
+
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 32
+
+/**
+ * @brief Whole port mask.
+ * @brief This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF)
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Digital I/O modes.
+ */
+typedef uint32_t iomode_t;
+
+/**
+ * @brief Port Identifier.
+ */
+typedef LPC_GPIO_TypeDef *ioportid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO0 port identifier.
+ */
+#define IOPORT1 LPC_GPIO0
+#define GPIO0 LPC_GPIO0
+
+/**
+ * @brief GPIO1 port identifier.
+ */
+#define IOPORT2 LPC_GPIO1
+#define GPIO1 LPC_GPIO1
+
+/**
+ * @brief GPIO2 port identifier.
+ */
+#define IOPORT3 LPC_GPIO2
+#define GPIO2 LPC_GPIO2
+
+/**
+ * @brief GPIO3 port identifier.
+ */
+#define IOPORT4 LPC_GPIO3
+#define GPIO3 LPC_GPIO3
+
+/**
+ * @brief GPIO3 port identifier.
+ */
+#define IOPORT5 LPC_GPIO4
+#define GPIO4 LPC_GPIO4
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level PAL subsystem initialization.
+ *
+ * @param[in] config architecture-dependent ports configuration
+ *
+ * @notapi
+ */
+#define pal_lld_init(config) _pal_lld_init(config)
+
+/**
+ * @brief Reads the physical I/O port states.
+ *
+ * @param[in] port port identifier
+ * @return The port bits.
+ *
+ * @notapi
+ */
+#define pal_lld_readport(port) ((port)->FIOPIN)
+
+/**
+ * @brief Reads the output latch.
+ * @details The purpose of this function is to read back the latched output
+ * value.
+ *
+ * @param[in] port port identifier
+ * @return The latched logical states.
+ *
+ * @notapi
+ */
+#define pal_lld_readlatch(port) ((port)->FIOPIN)
+
+/**
+ * @brief Writes a bits mask on a I/O port.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be written on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_writeport(port, bits) ((port)->FIOPIN = (bits))
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be ORed on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_setport(port, bits) ((port)->FIOSET = bits)
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be cleared on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_clearport(port, bits) ((port)->FIOCLR = bits)
+
+/**
+ * @brief Reads a group of bits.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @return The group logical states.
+ *
+ * @notapi
+ */
+#define pal_lld_readgroup(port, mask, offset) \
+ _pal_lld_readgroup(port, mask, offset)
+
+/**
+ * @brief Writes a group of bits.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] bits bits to be written. Values exceeding the group width
+ * are masked.
+ *
+ * @notapi
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) \
+ _pal_lld_writegroup(port, mask, offset, bits)
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] mode group mode
+ *
+ * @notapi
+ */
+#define pal_lld_setgroupmode(port, mask, offset, mode) \
+ _pal_lld_setgroupmode(port, mask << offset, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ * @note This function is not meant to be invoked directly by the
+ * application code.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] bit logical value, the value must be @p PAL_LOW or
+ * @p PAL_HIGH
+ *
+ * @notapi
+ */
+#define pal_lld_writepad(port, pad, bit) \
+ ((bit) == PAL_LOW) ? pal_lld_clearpad(port, pad) : \
+ pal_lld_setpad(port, pad)
+
+/**
+ * @brief Sets a pad logical state to @p PAL_HIGH.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_setpad(port, pad) \
+ ((port)->FIOSET = 1UL << (pad))
+
+/**
+ * @brief Clears a pad logical state to @p PAL_LOW.
+ * @note The @ref PAL provides a default software implementation of this
+ * functionality, implement this function if can optimize it by using
+ * special hardware functionalities or special coding.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_clearpad(port, pad) \
+ ((port)->FIOCLR = 1UL << (pad))
+
+#if !defined(__DOXYGEN__)
+extern const PALConfig pal_default_config;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(const PALConfig *config);
+ uint32_t _pal_lld_readgroup(ioportid_t port,
+ ioportmask_t mask,
+ uint32_t offset);
+ void _pal_lld_writegroup(ioportid_t port,
+ ioportmask_t mask,
+ uint32_t offset,
+ uint32_t bits);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_PAL */
+
+#endif /* _PAL_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/platform.mk b/os/hal/platforms/LPC17xx/platform.mk
new file mode 100644
index 000000000..b3e3f8eed
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/platform.mk
@@ -0,0 +1,14 @@
+# List of all the LPC17xx platform files.
+PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC17xx/hal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/lpc17xx_dma.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/adc_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/gpt_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/pal_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/serial_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/rtc_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/i2c_lld.c \
+ ${CHIBIOS}/os/hal/platforms/LPC17xx/spi_lld.c
+
+
+# Required include directories
+PLATFORMINC = ${CHIBIOS}/os/hal/platforms/LPC17xx
diff --git a/os/hal/platforms/LPC17xx/rtc_lld.c b/os/hal/platforms/LPC17xx/rtc_lld.c
new file mode 100644
index 000000000..62acfffc8
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/rtc_lld.c
@@ -0,0 +1,290 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx RTC driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/*
+ Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+ aka barthess.
+ */
+
+/**
+ * @file LPC17xx/rtc_lld.c
+ * @brief LPC17xx RTC low level driver.
+ *
+ * @addtogroup RTC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_RTC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief RTC driver identifier.
+ */
+RTCDriver RTCD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enable RTC clock.
+ */
+#define _rtc_clk_enable() \
+ LPC_RTC->CCR |= CCR_CLKEN
+
+/**
+ * @brief Disable RTC clock.
+ */
+#define _rtc_clk_disable() \
+ LPC_RTC->CCR &= ~CCR_CLKEN
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief RTC interrupt handler.
+ *
+ * @isr
+ */
+
+#if LPC17xx_RTC_USE_ALARM || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(Vector84) {
+ uint32_t status;
+
+ CH_IRQ_PROLOGUE();
+
+ status = LPC_RTC->ILR;
+ LPC_RTC->ILR = status; /* Clear interrupt flag */
+
+ if ((status & ILR_RTCALF) && (RTCD1.callback != NULL))
+ RTCD1.callback(&RTCD1, RTC_EVENT_ALARM);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enable access to registers.
+ *
+ * @api
+ */
+void rtc_lld_init(void) {
+
+ if(LPC_RTC->RTC_AUX & RTC_AUX_RTC_OSCF) { /* Set after RTC power was first turn. */
+
+ LPC_RTC->CCR = CCR_CCALEN; /* Disable calibration and RTC clock. */
+ LPC_RTC->CALIBRATION = 0;
+ LPC_RTC->RTC_AUX = RTC_AUX_RTC_OSCF; /* Clear RTC Oscillator Fail detect flag. */
+
+ LPC_RTC->CIIR = 0; /* Disable Counter Increment Interrupt. */
+ LPC_RTC->AMR = AMR_MASK_ALL; /* Mask alarm interrupt. */
+ LPC_RTC->ILR = ILR_RTCALF | ILR_RTCCIF; /* Clear interrupt flags. */
+
+ /* Set date to Saturday 01.01.2000 00:00:00 */
+ LPC_RTC->SEC = 0;
+ LPC_RTC->MIN = 0;
+ LPC_RTC->HOUR = 0;
+ LPC_RTC->DOM = 1;
+ LPC_RTC->MONTH = 1;
+ LPC_RTC->YEAR = 2000;
+ LPC_RTC->DOW = 6;
+ LPC_RTC->DOY = 1;
+
+ _rtc_clk_enable(); /* Enable RTC clock. */
+ }
+
+#if LPC17xx_RTC_USE_ALARM
+ nvicEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(LPC17xx_RTC_IRQ_PRIORITY));
+#endif
+ return;
+}
+
+/**
+ * @brief Set current time.
+ * @note Fractional part will be silently ignored. There is no possibility
+ * to set it on STM32 platform.
+ *
+ * @param[in] rtcp pointer to RTC driver structure
+ * @param[in] timespec pointer to a @p RTCTime structure
+ *
+ * @api
+ */
+void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec) {
+ (void)rtcp;
+
+ _rtc_clk_disable(); /* Disable RTC clock. */
+ LPC_RTC->SEC = timespec->sec;
+ LPC_RTC->MIN = timespec->min;
+ LPC_RTC->HOUR = timespec->hour;
+ LPC_RTC->DOM = timespec->dom;
+ LPC_RTC->MONTH = timespec->month;
+ LPC_RTC->YEAR = timespec->year;
+ LPC_RTC->DOW = timespec->dow;
+ LPC_RTC->DOY = timespec->doy;
+ _rtc_clk_enable(); /* Enable RTC clock. */
+
+}
+
+/**
+ * @brief Get current time.
+ *
+ * @param[in] rtcp pointer to RTC driver structure
+ * @param[out] timespec pointer to a @p RTCTime structure
+ *
+ * @api
+ */
+void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) {
+ (void)rtcp;
+
+ timespec->sec = LPC_RTC->SEC;
+ timespec->min = LPC_RTC->MIN;
+ timespec->hour = LPC_RTC->HOUR;
+ timespec->dom = LPC_RTC->DOM;
+ timespec->month = LPC_RTC->MONTH;
+ timespec->year = LPC_RTC->YEAR;
+ timespec->dow = LPC_RTC->DOW;
+ timespec->doy = LPC_RTC->DOY;
+}
+
+/**
+ * @brief Set alarm time.
+ *
+ * @note Default value after BKP domain reset for both comparators is 0.
+ * @note Function does not performs any checks of alarm time validity.
+ *
+ * @param[in] rtcp Pointer to RTC driver structure.
+ * @param[in] alarm Alarm identifier. Can be 1 or 2.
+ * @param[in] alarmspec Pointer to a @p RTCAlarm structure.
+ *
+ * @api
+ */
+void rtc_lld_set_alarm(RTCDriver *rtcp,
+ rtcalarm_t alarm,
+ const RTCAlarm *alarmspec) {
+ (void)rtcp;
+ (void)alarm;
+ LPC_RTC->ALSEC = alarmspec->alsec;
+ LPC_RTC->ALMIN = alarmspec->almin;
+ LPC_RTC->ALHOUR = alarmspec->alhour;
+ LPC_RTC->ALDOM = alarmspec->aldom;
+ LPC_RTC->ALMON = alarmspec->almonth;
+ LPC_RTC->ALYEAR = alarmspec->alyear;
+ LPC_RTC->ALDOW = alarmspec->aldow;
+ LPC_RTC->ALDOY = alarmspec->aldoy;
+
+}
+
+/**
+ * @brief Get alarm time.
+ *
+ * @param[in] rtcp pointer to RTC driver structure
+ * @param[in] alarm alarm identifier
+ * @param[out] alarmspec pointer to a @p RTCAlarm structure
+ *
+ * @api
+ */
+void rtc_lld_get_alarm(RTCDriver *rtcp,
+ rtcalarm_t alarm,
+ RTCAlarm *alarmspec) {
+ (void)rtcp;
+ (void)alarm;
+ alarmspec->alsec = LPC_RTC->ALSEC;
+ alarmspec->almin = LPC_RTC->ALMIN;
+ alarmspec->alhour = LPC_RTC->ALHOUR;
+ alarmspec->aldom = LPC_RTC->ALDOM;
+ alarmspec->almonth = LPC_RTC->ALMON;
+ alarmspec->alyear = LPC_RTC->ALYEAR;
+ alarmspec->aldow = LPC_RTC->ALDOW;
+ alarmspec->aldoy = LPC_RTC->ALDOY;
+
+}
+
+/**
+ * @brief Enables or disables RTC callbacks.
+ * @details This function enables or disables callbacks, use a @p NULL pointer
+ * in order to disable a callback.
+ *
+ * @param[in] rtcp pointer to RTC driver structure
+ * @param[in] callback callback function pointer or @p NULL
+ *
+ * @notapi
+ */
+void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) {
+
+ LPC_RTC->AMR = AMR_MASK_ALL; /* Mask alarm interrupt. */
+ LPC_RTC->ILR = ILR_RTCALF; /* Clear interrupt flag. */
+
+ if (callback != NULL) {
+
+ /* IRQ sources enabled only after setting up the callback.*/
+ rtcp->callback = callback;
+ LPC_RTC->AMR = 0; /* Enable alarm interrupt. */
+ }
+ else {
+
+ /* Callback set to NULL only after disabling the IRQ sources.*/
+ rtcp->callback = NULL;
+ }
+}
+
+#include "chrtclib.h"
+
+/**
+ * @brief Get current time in format suitable for usage in FatFS.
+ *
+ * @param[in] rtcp pointer to RTC driver structure
+ * @return FAT time value.
+ *
+ * @api
+ */
+uint32_t rtc_lld_get_time_fat(RTCDriver *rtcp) {
+ uint32_t fattime;
+ struct tm timp;
+
+ rtcGetTimeTm(rtcp, &timp);
+
+ fattime = (timp.tm_sec) >> 1;
+ fattime |= (timp.tm_min) << 5;
+ fattime |= (timp.tm_hour) << 11;
+ fattime |= (timp.tm_mday) << 16;
+ fattime |= (timp.tm_mon + 1) << 21;
+ fattime |= (timp.tm_year - 80) << 25;
+
+ return fattime;
+}
+
+#endif /* HAL_USE_RTC */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/rtc_lld.h b/os/hal/platforms/LPC17xx/rtc_lld.h
new file mode 100644
index 000000000..1b6a727cf
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/rtc_lld.h
@@ -0,0 +1,279 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+ LPC17xx RTC driver - Copyright (C) 2013 Marcin Jokel
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+/*
+ Concepts and parts of this file have been contributed by Uladzimir Pylinsky
+ aka barthess.
+ */
+
+/**
+ * @file LPC17xx/rtc_lld.h
+ * @brief LPC17xx RTC low level driver header.
+ *
+ * @addtogroup RTC
+ * @{
+ */
+
+#ifndef _RTC_LLD_H_
+#define _RTC_LLD_H_
+
+#if HAL_USE_RTC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define ILR_RTCCIF 0x01
+#define ILR_RTCALF 0x02
+
+#define CCR_CLKEN 0x01
+#define CCR_CTCRST 0x02
+#define CCR_CCALEN 0x10
+
+#define CIIR_IMSEC 0x01
+#define CIIR_IMMIN 0x02
+#define CIIR_IMHOUR 0x04
+#define CIIR_IMDOM 0x08
+#define CIIR_IMDOW 0x10
+#define CIIR_IMDOY 0x20
+#define CIIR_IMMON 0x40
+#define CIIR_IMYEAR 0x80
+
+#define AMR_AMRSEC 0x01
+#define AMR_AMRMIN 0x02
+#define AMR_AMRHOUR 0x04
+#define AMR_AMRDOM 0x08
+#define AMR_AMRDOW 0x10
+#define AMR_AMRDOY 0x20
+#define AMR_AMRMON 0x40
+#define AMR_AMRYEAR 0x80
+#define AMR_MASK_ALL 0xFF
+
+#define RTC_AUX_RTC_OSCF 0x10
+
+#define RTC_AUXEN_RTC_OSCFEN 0x10
+
+/**
+ * @brief This RTC implementation supports callbacks.
+ */
+#define RTC_SUPPORTS_CALLBACKS TRUE
+
+/**
+ * @brief One alarm comparator available.
+ */
+#define RTC_ALARMS 1
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/*
+ * RTC driver system settings.
+ */
+
+/**
+ * @brief RTC Alarm enable.
+ */
+#if !defined(LPC17xx_RTC_USE_ALARM) || defined(__DOXYGEN__)
+#define LPC17xx_RTC_USE_ALARM FALSE
+#endif
+
+/**
+ * @brief RTC IRQ Priority.
+ */
+#if !defined(LPC17xx_RTC_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_RTC_IRQ_PRIORITY 3
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a structure representing an RTC alarm time stamp.
+ */
+typedef struct RTCAlarm RTCAlarm;
+
+/**
+ * @brief Type of a structure representing an RTC wakeup period.
+ */
+typedef struct RTCWakeup RTCWakeup;
+
+/**
+ * @brief Type of a structure representing an RTC callbacks config.
+ */
+typedef struct RTCCallbackConfig RTCCallbackConfig;
+
+/**
+ * @brief Type of an RTC alarm.
+ * @details Meaningful on platforms with more than 1 alarm comparator.
+ */
+typedef uint32_t rtcalarm_t;
+
+/**
+ * @brief Type of an RTC event.
+ */
+typedef enum {
+ RTC_EVENT_ALARM = 0 /** Triggered on alarm. */
+} rtcevent_t;
+
+/**
+ * @brief Type of a generic RTC callback.
+ */
+typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event);
+
+/**
+ * @brief Structure representing an RTC callbacks config.
+ */
+struct RTCCallbackConfig{
+ /**
+ * @brief Generic RTC callback pointer.
+ */
+ rtccb_t callback;
+};
+
+/**
+ * @brief Structure representing an RTC time stamp.
+ */
+struct RTCTime {
+ /**
+ * @brief RTC seconds register.
+ */
+ uint8_t sec;
+ /**
+ * @brief RTC minutes register.
+ */
+ uint8_t min;
+ /**
+ * @brief RTC hours register.
+ */
+ uint8_t hour;
+ /**
+ * @brief RTC day of month register.
+ */
+ uint8_t dom;
+ /**
+ * @brief RTC month register.
+ */
+ uint8_t month;
+ /**
+ * @brief RTC day of week register.
+ */
+ uint8_t dow;
+ /**
+ * @brief RTC year register.
+ */
+ uint16_t year;
+ /**
+ * @brief RTC day of year register.
+ */
+ uint16_t doy;
+
+};
+
+/**
+ * @brief Structure representing an RTC alarm time stamp.
+ */
+struct RTCAlarm {
+ /**
+ * @brief RTC alarm seconds register.
+ */
+ uint8_t alsec;
+ /**
+ * @brief RTC alarm minutes register.
+ */
+ uint8_t almin;
+ /**
+ * @brief RTC alarm hours register.
+ */
+ uint8_t alhour;
+ /**
+ * @brief RTC alarm day of month register.
+ */
+ uint8_t aldom;
+ /**
+ * @brief RTC alarm month register.
+ */
+ uint8_t almonth;
+ /**
+ * @brief RTC alarm day of week register.
+ */
+ uint8_t aldow;
+ /**
+ * @brief RTC alarm year register.
+ */
+ uint16_t alyear;
+ /**
+ * @brief RTC alarm day of year register.
+ */
+ uint16_t aldoy;
+
+};
+
+/**
+ * @brief Structure representing an RTC driver.
+ */
+struct RTCDriver{
+ /**
+ * @brief Callback pointer.
+ */
+ rtccb_t callback;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern RTCDriver RTCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void rtc_lld_init(void);
+ void rtc_lld_set_time(RTCDriver *rtcp, const RTCTime *timespec);
+ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec);
+ void rtc_lld_set_alarm(RTCDriver *rtcp,
+ rtcalarm_t alarm,
+ const RTCAlarm *alarmspec);
+ void rtc_lld_get_alarm(RTCDriver *rtcp,
+ rtcalarm_t alarm,
+ RTCAlarm *alarmspec);
+ void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback);
+ uint32_t rtc_lld_get_time_fat(RTCDriver *rtcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_RTC */
+
+#endif /* _RTC_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/serial_lld.c b/os/hal/platforms/LPC17xx/serial_lld.c
new file mode 100644
index 000000000..03aed7961
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/serial_lld.c
@@ -0,0 +1,476 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/serial_lld.c
+ * @brief LPC17xx low level serial driver code.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if LPC17xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
+/** @brief UART0 serial driver identifier.*/
+SerialDriver SD1;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART1 || defined(__DOXYGEN__)
+/** @brief UART1 serial driver identifier.*/
+SerialDriver SD2;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART2 || defined(__DOXYGEN__)
+/** @brief UART2 serial driver identifier.*/
+SerialDriver SD3;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART3 || defined(__DOXYGEN__)
+/** @brief UART3 serial driver identifier.*/
+SerialDriver SD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/** @brief Driver default configuration.*/
+static const SerialConfig default_config = {
+ SERIAL_DEFAULT_BITRATE,
+ LCR_WL8 | LCR_STOP1 | LCR_NOPARITY,
+ FCR_TRIGGER0
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief UART initialization.
+ *
+ * @param[in] sdp communication channel associated to the UART
+ * @param[in] config the architecture-dependent serial driver configuration
+ */
+static void uart_init(SerialDriver *sdp, const SerialConfig *config) {
+ LPC_UART_TypeDef *u = sdp->uart;
+ uint32_t div = 0;
+
+#if LPC17xx_SERIAL_USE_UART0
+ if (&SD1 == sdp) {
+ div = LPC17xx_SERIAL_UART0_PCLK / (config->sc_speed << 4);
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART1
+ if (&SD2 == sdp) {
+ div = LPC17xx_SERIAL_UART1_PCLK / (config->sc_speed << 4);
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART2
+ if (&SD3 == sdp) {
+ div = LPC17xx_SERIAL_UART2_PCLK / (config->sc_speed << 4);
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART3
+ if (&SD4 == sdp) {
+ div = LPC17xx_SERIAL_UART3_PCLK / (config->sc_speed << 4);
+ }
+#endif
+
+ u->LCR = config->sc_lcr | LCR_DLAB;
+ u->DLL = div;
+ u->DLM = div >> 8;
+ u->LCR = config->sc_lcr;
+ u->FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | config->sc_fcr;
+ u->ACR = 0;
+ u->FDR = 0x10;
+ u->TER = TER_ENABLE;
+ u->IER = IER_RBR | IER_STATUS;
+}
+
+/**
+ * @brief UART de-initialization.
+ *
+ * @param[in] u pointer to an UART I/O block
+ */
+static void uart_deinit(LPC_UART_TypeDef *u) {
+
+ u->LCR = LCR_DLAB;
+ u->DLL = 1;
+ u->DLM = 0;
+ u->LCR = 0;
+ u->FDR = 0x10;
+ u->IER = 0;
+ u->FCR = FCR_RXRESET | FCR_TXRESET;
+ u->ACR = 0;
+ u->TER = TER_ENABLE;
+}
+
+/**
+ * @brief Error handling routine.
+ *
+ * @param[in] sdp communication channel associated to the UART
+ * @param[in] err UART LSR register value
+ */
+static void set_error(SerialDriver *sdp, IOREG32 err) {
+ flagsmask_t sts = 0;
+
+ if (err & LSR_OVERRUN)
+ sts |= SD_OVERRUN_ERROR;
+ if (err & LSR_PARITY)
+ sts |= SD_PARITY_ERROR;
+ if (err & LSR_FRAMING)
+ sts |= SD_FRAMING_ERROR;
+ if (err & LSR_BREAK)
+ sts |= SD_BREAK_DETECTED;
+ chSysLockFromIsr();
+ chnAddFlagsI(sdp, sts);
+ chSysUnlockFromIsr();
+}
+
+/**
+ * @brief Common IRQ handler.
+ * @note Tries hard to clear all the pending interrupt sources, we don't
+ * want to go through the whole ISR and have another interrupt soon
+ * after.
+ *
+ * @param[in] u pointer to an UART I/O block
+ * @param[in] sdp communication channel associated to the UART
+ */
+static void serve_interrupt(SerialDriver *sdp) {
+ LPC_UART_TypeDef *u = sdp->uart;
+
+ while (TRUE) {
+ switch (u->IIR & IIR_SRC_MASK) {
+ case IIR_SRC_NONE:
+ return;
+ case IIR_SRC_ERROR:
+ set_error(sdp, u->LSR);
+ break;
+ case IIR_SRC_TIMEOUT:
+ case IIR_SRC_RX:
+ chSysLockFromIsr();
+ if (chIQIsEmptyI(&sdp->iqueue))
+ chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
+ chSysUnlockFromIsr();
+ while (u->LSR & LSR_RBR_FULL) {
+ chSysLockFromIsr();
+ if (chIQPutI(&sdp->iqueue, u->RBR) < Q_OK)
+ chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
+ chSysUnlockFromIsr();
+ }
+ break;
+ case IIR_SRC_TX:
+ {
+ int i = LPC17xx_SERIAL_FIFO_PRELOAD;
+ do {
+ msg_t b;
+
+ chSysLockFromIsr();
+ b = chOQGetI(&sdp->oqueue);
+ chSysUnlockFromIsr();
+ if (b < Q_OK) {
+ u->IER &= ~IER_THRE;
+ chSysLockFromIsr();
+ chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
+ chSysUnlockFromIsr();
+ break;
+ }
+ u->THR = b;
+ } while (--i);
+ }
+ break;
+ default:
+ (void) u->THR;
+ (void) u->RBR;
+ }
+ }
+}
+
+/**
+ * @brief Attempts a TX FIFO preload.
+ */
+static void preload(SerialDriver *sdp) {
+ LPC_UART_TypeDef *u = sdp->uart;
+
+ if (u->LSR & LSR_THRE) {
+ int i = LPC17xx_SERIAL_FIFO_PRELOAD;
+ do {
+ msg_t b = chOQGetI(&sdp->oqueue);
+ if (b < Q_OK) {
+ chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
+ return;
+ }
+ u->THR = b;
+ } while (--i);
+ }
+ u->IER |= IER_THRE;
+}
+
+/**
+ * @brief Driver SD1 output notification.
+ */
+#if LPC17xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
+static void notify1(GenericQueue *qp) {
+
+ (void)qp;
+ preload(&SD1);
+}
+#endif
+
+/**
+ * @brief Driver SD2 output notification.
+ */
+#if LPC17xx_SERIAL_USE_UART1 || defined(__DOXYGEN__)
+static void notify2(GenericQueue *qp) {
+
+ (void)qp;
+ preload(&SD2);
+}
+#endif
+
+/**
+ * @brief Driver SD3 output notification.
+ */
+#if LPC17xx_SERIAL_USE_UART2 || defined(__DOXYGEN__)
+static void notify3(GenericQueue *qp) {
+
+ (void)qp;
+ preload(&SD3);
+}
+#endif
+
+/**
+ * @brief Driver SD4 output notification.
+ */
+#if LPC17xx_SERIAL_USE_UART3 || defined(__DOXYGEN__)
+static void notify4(GenericQueue *qp) {
+
+ (void)qp;
+ preload(&SD4);
+}
+#endif
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief UART0 IRQ handler.
+ *
+ * @isr
+ */
+#if LPC17xx_SERIAL_USE_UART0 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(Vector54) {
+
+ CH_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/**
+ * @brief UART1 IRQ handler.
+ *
+ * @isr
+ */
+#if LPC17xx_SERIAL_USE_UART1 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(Vector58) {
+
+ CH_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/**
+ * @brief UART2 IRQ handler.
+ *
+ * @isr
+ */
+#if LPC17xx_SERIAL_USE_UART2 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(Vector5C) {
+
+ CH_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD3);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/**
+ * @brief UART3 IRQ handler.
+ *
+ * @isr
+ */
+#if LPC17xx_SERIAL_USE_UART3 || defined(__DOXYGEN__)
+CH_IRQ_HANDLER(Vector60) {
+
+ CH_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD4);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level serial driver initialization.
+ *
+ * @notapi
+ */
+void sd_lld_init(void) {
+
+#if LPC17xx_SERIAL_USE_UART0
+ sdObjectInit(&SD1, NULL, notify1);
+ SD1.uart = (LPC_UART_TypeDef*) LPC_UART0;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART1
+ sdObjectInit(&SD2, NULL, notify2);
+ SD2.uart = (LPC_UART_TypeDef*) LPC_UART1;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART2
+ sdObjectInit(&SD3, NULL, notify3);
+ SD3.uart = (LPC_UART_TypeDef*) LPC_UART2;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART3
+ sdObjectInit(&SD4, NULL, notify4);
+ SD4.uart = (LPC_UART_TypeDef*) LPC_UART3;
+#endif
+}
+
+/**
+ * @brief Low level serial driver configuration and (re)start.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] config the architecture-dependent serial driver configuration.
+ * If this parameter is set to @p NULL then a default
+ * configuration is used.
+ *
+ * @notapi
+ */
+void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
+
+ if (config == NULL)
+ config = &default_config;
+
+ if (sdp->state == SD_STOP) {
+#if LPC17xx_SERIAL_USE_UART0
+ if (&SD1 == sdp) {
+ LPC_SC->PCONP |= (1 << 3);
+ nvicEnableVector(UART0_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_SERIAL_UART0_IRQ_PRIORITY));
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART1
+ if (&SD2 == sdp) {
+ LPC_SC->PCONP |= (1 << 4);
+ nvicEnableVector(UART1_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_SERIAL_UART1_IRQ_PRIORITY));
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART2
+ if (&SD3 == sdp) {
+ LPC_SC->PCONP |= (1 << 24);
+ nvicEnableVector(UART2_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_SERIAL_UART2_IRQ_PRIORITY));
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART3
+ if (&SD4 == sdp) {
+ LPC_SC->PCONP |= (1 << 25);
+ nvicEnableVector(UART3_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_SERIAL_UART3_IRQ_PRIORITY));
+ }
+#endif
+ }
+ uart_init(sdp, config);
+}
+
+/**
+ * @brief Low level serial driver stop.
+ * @details De-initializes the UART, stops the associated clock, resets the
+ * interrupt vector.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ *
+ * @notapi
+ */
+void sd_lld_stop(SerialDriver *sdp) {
+
+ if (sdp->state == SD_READY) {
+ uart_deinit(sdp->uart);
+#if LPC17xx_SERIAL_USE_UART0
+ if (&SD1 == sdp) {
+ LPC_SC->PCONP &= ~(1 << 3);
+ nvicDisableVector(UART0_IRQn);
+ return;
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART1
+ if (&SD2 == sdp) {
+ LPC_SC->PCONP &= ~(1 << 4);
+ nvicDisableVector(UART1_IRQn);
+ return;
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART2
+ if (&SD3 == sdp) {
+ LPC_SC->PCONP &= ~(1 << 24);
+ nvicDisableVector(UART2_IRQn);
+ return;
+ }
+#endif
+
+#if LPC17xx_SERIAL_USE_UART3
+ if (&SD4 == sdp) {
+ LPC_SC->PCONP &= ~(1 << 25);
+ nvicDisableVector(UART3_IRQn);
+ return;
+ }
+#endif
+ }
+}
+
+#endif /* HAL_USE_SERIAL */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/serial_lld.h b/os/hal/platforms/LPC17xx/serial_lld.h
new file mode 100644
index 000000000..75d68795d
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/serial_lld.h
@@ -0,0 +1,268 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/serial_lld.h
+ * @brief LPC17xx low level serial driver header.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#ifndef _SERIAL_LLD_H_
+#define _SERIAL_LLD_H_
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define IIR_SRC_MASK 0x0F
+#define IIR_SRC_NONE 0x01
+#define IIR_SRC_MODEM 0x00
+#define IIR_SRC_TX 0x02
+#define IIR_SRC_RX 0x04
+#define IIR_SRC_ERROR 0x06
+#define IIR_SRC_TIMEOUT 0x0C
+
+#define IER_RBR 1
+#define IER_THRE 2
+#define IER_STATUS 4
+
+#define LCR_WL5 0
+#define LCR_WL6 1
+#define LCR_WL7 2
+#define LCR_WL8 3
+#define LCR_STOP1 0
+#define LCR_STOP2 4
+#define LCR_NOPARITY 0
+#define LCR_PARITYODD 0x08
+#define LCR_PARITYEVEN 0x18
+#define LCR_PARITYONE 0x28
+#define LCR_PARITYZERO 0x38
+#define LCR_BREAK_ON 0x40
+#define LCR_DLAB 0x80
+
+#define FCR_ENABLE 1
+#define FCR_RXRESET 2
+#define FCR_TXRESET 4
+#define FCR_TRIGGER0 0
+#define FCR_TRIGGER1 0x40
+#define FCR_TRIGGER2 0x80
+#define FCR_TRIGGER3 0xC0
+
+#define LSR_RBR_FULL 1
+#define LSR_OVERRUN 2
+#define LSR_PARITY 4
+#define LSR_FRAMING 8
+#define LSR_BREAK 0x10
+#define LSR_THRE 0x20
+#define LSR_TEMT 0x40
+#define LSR_RXFE 0x80
+
+#define TER_ENABLE 0x80
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief UART0 driver enable switch.
+ * @details If set to @p TRUE the support for UART0 is included.
+ * @note The default is @p TRUE .
+ */
+#if !defined(LPC17xx_SERIAL_USE_UART0) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_USE_UART0 TRUE
+#endif
+
+/**
+ * @brief UART1 driver enable switch.
+ * @details If set to @p TRUE the support for UART1 is included.
+ * @note The default is @p TRUE .
+ */
+#if !defined(LPC17xx_SERIAL_USE_UART1) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_USE_UART1 TRUE
+#endif
+
+/**
+ * @brief UART2 driver enable switch.
+ * @details If set to @p TRUE the support for UART2 is included.
+ * @note The default is @p TRUE .
+ */
+#if !defined(LPC17xx_SERIAL_USE_UART2) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_USE_UART2 TRUE
+#endif
+
+/**
+ * @brief UART3 driver enable switch.
+ * @details If set to @p TRUE the support for UART3 is included.
+ * @note The default is @p TRUE .
+ */
+#if !defined(LPC17xx_SERIAL_USE_UART3) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_USE_UART3 TRUE
+#endif
+
+/**
+ * @brief FIFO preload parameter.
+ * @details Configuration parameter, this values defines how many bytes are
+ * preloaded in the HW transmit FIFO for each interrupt, the maximum
+ * value is 16 the minimum is 1.
+ * @note An high value reduces the number of interrupts generated but can
+ * also increase the worst case interrupt response time because the
+ * preload loops.
+ */
+#if !defined(LPC17xx_SERIAL_FIFO_PRELOAD) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_FIFO_PRELOAD 16
+#endif
+
+/**
+ * @brief UART0 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_SERIAL_UART0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_UART0_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief UART1 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_SERIAL_UART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_UART1_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief UART2 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_SERIAL_UART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_UART2_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief UART3 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_SERIAL_UART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_SERIAL_UART0_IRQ_PRIORITY 3
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+#if (LPC17xx_SERIAL_FIFO_PRELOAD < 1) || (LPC17xx_SERIAL_FIFO_PRELOAD > 16)
+#error "invalid LPC17xx_SERIAL_FIFO_PRELOAD setting"
+#endif
+
+/**
+ * @brief UART0 clock.
+ */
+#define LPC17xx_SERIAL_UART0_PCLK LPC17xx_PCLK
+
+/**
+ * @brief UART1 clock.
+ */
+#define LPC17xx_SERIAL_UART1_PCLK LPC17xx_PCLK
+
+/**
+ * @brief UART2 clock.
+ */
+#define LPC17xx_SERIAL_UART2_PCLK LPC17xx_PCLK
+
+/**
+ * @brief UART3 clock.
+ */
+#define LPC17xx_SERIAL_UART3_PCLK LPC17xx_PCLK
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief LPC17xx Serial Driver configuration structure.
+ * @details An instance of this structure must be passed to @p sdStart()
+ * in order to configure and start a serial driver operations.
+ */
+typedef struct {
+ /**
+ * @brief Bit rate.
+ */
+ uint32_t sc_speed;
+ /**
+ * @brief Initialization value for the LCR register.
+ */
+ uint32_t sc_lcr;
+ /**
+ * @brief Initialization value for the FCR register.
+ */
+ uint32_t sc_fcr;
+} SerialConfig;
+
+/**
+ * @brief @p SerialDriver specific data.
+ */
+#define _serial_driver_data \
+ _base_asynchronous_channel_data \
+ /* Driver state.*/ \
+ sdstate_t state; \
+ /* Input queue.*/ \
+ InputQueue iqueue; \
+ /* Output queue.*/ \
+ OutputQueue oqueue; \
+ /* Input circular buffer.*/ \
+ uint8_t ib[SERIAL_BUFFERS_SIZE]; \
+ /* Output circular buffer.*/ \
+ uint8_t ob[SERIAL_BUFFERS_SIZE]; \
+ /* End of the mandatory fields.*/ \
+ /* Pointer to the USART registers block.*/ \
+ LPC_UART_TypeDef *uart;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC17xx_SERIAL_USE_UART0 && !defined(__DOXYGEN__)
+extern SerialDriver SD1;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART1 && !defined(__DOXYGEN__)
+extern SerialDriver SD2;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART2 && !defined(__DOXYGEN__)
+extern SerialDriver SD3;
+#endif
+
+#if LPC17xx_SERIAL_USE_UART3 && !defined(__DOXYGEN__)
+extern SerialDriver SD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sd_lld_init(void);
+ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
+ void sd_lld_stop(SerialDriver *sdp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SERIAL */
+
+#endif /* _SERIAL_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/spi_lld.c b/os/hal/platforms/LPC17xx/spi_lld.c
new file mode 100644
index 000000000..483739aba
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/spi_lld.c
@@ -0,0 +1,387 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/spi_lld.c
+ * @brief LPC17xx low level SPI driver code.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if LPC17xx_SPI_USE_SSP0 || defined(__DOXYGEN__)
+/** @brief SPI1 driver identifier.*/
+SPIDriver SPID1;
+#endif
+
+#if LPC17xx_SPI_USE_SSP1 || defined(__DOXYGEN__)
+/** @brief SPI2 driver identifier.*/
+SPIDriver SPID2;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Preloads the transmit FIFO.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ */
+static void ssp_fifo_preload(SPIDriver *spip) {
+ LPC_SSP_TypeDef *ssp = spip->ssp;
+ uint32_t n = spip->txcnt > LPC17xx_SSP_FIFO_DEPTH ?
+ LPC17xx_SSP_FIFO_DEPTH : spip->txcnt;
+
+ while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
+ if (spip->txptr != NULL) {
+ if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
+ const uint16_t *p = spip->txptr;
+ ssp->DR = *p++;
+ spip->txptr = p;
+ }
+ else {
+ const uint8_t *p = spip->txptr;
+ ssp->DR = *p++;
+ spip->txptr = p;
+ }
+ }
+ else
+ ssp->DR = 0xFFFFFFFF;
+ n--;
+ spip->txcnt--;
+ }
+}
+
+/**
+ * @brief Common IRQ handler.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ */
+static void spi_serve_interrupt(SPIDriver *spip) {
+ LPC_SSP_TypeDef *ssp = spip->ssp;
+
+ if ((ssp->MIS & MIS_ROR) != 0) {
+ /* The overflow condition should never happen because priority is given
+ to receive but a hook macro is provided anyway...*/
+ LPC17xx_SPI_SSP_ERROR_HOOK(spip);
+ }
+ ssp->ICR = ICR_RT | ICR_ROR;
+ while ((ssp->SR & SR_RNE) != 0) {
+ if (spip->rxptr != NULL) {
+ if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
+ uint16_t *p = spip->rxptr;
+ *p++ = ssp->DR;
+ spip->rxptr = p;
+ }
+ else {
+ uint8_t *p = spip->rxptr;
+ *p++ = ssp->DR;
+ spip->rxptr = p;
+ }
+ }
+ else
+ (void)ssp->DR;
+ if (--spip->rxcnt == 0) {
+ chDbgAssert(spip->txcnt == 0,
+ "spi_serve_interrupt(), #1", "counter out of synch");
+ /* Stops the IRQ sources.*/
+ ssp->IMSC = 0;
+ /* Portable SPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _spi_isr_code(spip);
+ return;
+ }
+ }
+ ssp_fifo_preload(spip);
+ if (spip->txcnt == 0)
+ ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if LPC17xx_SPI_USE_SSP0 || defined(__DOXYGEN__)
+/**
+ * @brief SSP0 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector78) {
+
+ CH_IRQ_PROLOGUE();
+
+ spi_serve_interrupt(&SPID1);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+#if LPC17xx_SPI_USE_SSP1 || defined(__DOXYGEN__)
+/**
+ * @brief SSP1 interrupt handler.
+ *
+ * @isr
+ */
+CH_IRQ_HANDLER(Vector7C) {
+
+ CH_IRQ_PROLOGUE();
+
+ spi_serve_interrupt(&SPID2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SPI driver initialization.
+ *
+ * @notapi
+ */
+void spi_lld_init(void) {
+
+#if LPC17xx_SPI_USE_SSP0
+ spiObjectInit(&SPID1);
+ SPID1.ssp = LPC_SSP0;
+#endif /* LPC17xx_SPI_USE_SSP0 */
+
+#if LPC17xx_SPI_USE_SSP1
+ spiObjectInit(&SPID2);
+ SPID2.ssp = LPC_SSP1;
+#endif /* LPC17xx_SPI_USE_SSP0 */
+}
+
+/**
+ * @brief Configures and activates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_start(SPIDriver *spip) {
+
+ if (spip->state == SPI_STOP) {
+ /* Clock activation.*/
+#if LPC17xx_SPI_USE_SSP0
+ if (&SPID1 == spip) {
+ LPC_SC->PCONP |= (1UL << 21);
+ LPC_SC->PCLKSEL0 &= (PCLKSEL_MASK << 20);
+ LPC_SC->PCLKSEL0 |= (LPC17xx_SPI_SSP0_PCLKSEL << 20);
+ nvicEnableVector(SSP0_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_SPI_SSP0_IRQ_PRIORITY));
+ }
+#endif
+#if LPC17xx_SPI_USE_SSP1
+ if (&SPID2 == spip) {
+ LPC_SC->PCONP |= (1UL << 10);
+ LPC_SC->PCLKSEL1 &= (PCLKSEL_MASK << 10);
+ LPC_SC->PCLKSEL1 |= (LPC17xx_SPI_SSP0_PCLKSEL << 10);
+ nvicEnableVector(SSP1_IRQn,
+ CORTEX_PRIORITY_MASK(LPC17xx_SPI_SSP1_IRQ_PRIORITY));
+ }
+#endif
+ }
+ /* Configuration.*/
+ spip->ssp->CR1 = 0;
+ spip->ssp->ICR = ICR_RT | ICR_ROR;
+ spip->ssp->CR0 = spip->config->cr0;
+ spip->ssp->CPSR = spip->config->cpsr;
+ spip->ssp->CR1 = CR1_SSE;
+}
+
+/**
+ * @brief Deactivates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_stop(SPIDriver *spip) {
+
+ if (spip->state != SPI_STOP) {
+ spip->ssp->CR1 = 0;
+ spip->ssp->CR0 = 0;
+ spip->ssp->CPSR = 0;
+#if LPC17xx_SPI_USE_SSP0
+ if (&SPID1 == spip) {
+ LPC_SC->PCONP &= ~(1UL << 21);
+ nvicDisableVector(SSP0_IRQn);
+ }
+#endif
+#if LPC17xx_SPI_USE_SSP1
+ if (&SPID2 == spip) {
+ LPC_SC->PCONP &= ~(1UL << 10);
+ nvicDisableVector(SSP1_IRQn);
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Asserts the slave select signal and prepares for transfers.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_select(SPIDriver *spip) {
+
+ palClearPad(spip->config->ssport, spip->config->sspad);
+}
+
+/**
+ * @brief Deasserts the slave select signal.
+ * @details The previously selected peripheral is unselected.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_unselect(SPIDriver *spip) {
+
+ palSetPad(spip->config->ssport, spip->config->sspad);
+}
+
+/**
+ * @brief Ignores data on the SPI bus.
+ * @details This function transmits a series of idle words on the SPI bus and
+ * ignores the received data. This function can be invoked even
+ * when a slave select signal has not been yet asserted.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be ignored
+ *
+ * @notapi
+ */
+void spi_lld_ignore(SPIDriver *spip, size_t n) {
+
+ spip->rxptr = NULL;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
+ ssp_fifo_preload(spip);
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+}
+
+/**
+ * @brief Exchanges data on the SPI bus.
+ * @details This asynchronous function starts a simultaneous transmit/receive
+ * operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be exchanged
+ * @param[in] txbuf the pointer to the transmit buffer
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf) {
+
+ spip->rxptr = rxbuf;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
+ ssp_fifo_preload(spip);
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+}
+
+/**
+ * @brief Sends data over the SPI bus.
+ * @details This asynchronous function starts a transmit operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
+
+ spip->rxptr = NULL;
+ spip->txptr = txbuf;
+ spip->rxcnt = spip->txcnt = n;
+ ssp_fifo_preload(spip);
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+}
+
+/**
+ * @brief Receives data from the SPI bus.
+ * @details This asynchronous function starts a receive operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to receive
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
+
+ spip->rxptr = rxbuf;
+ spip->txptr = NULL;
+ spip->rxcnt = spip->txcnt = n;
+ ssp_fifo_preload(spip);
+ spip->ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
+}
+
+/**
+ * @brief Exchanges one frame using a polled wait.
+ * @details This synchronous function exchanges one frame using a polled
+ * synchronization method. This function is useful when exchanging
+ * small amount of data on high speed channels, usually in this
+ * situation is much more efficient just wait for completion using
+ * polling than suspending the thread waiting for an interrupt.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] frame the data frame to send over the SPI bus
+ * @return The received data frame from the SPI bus.
+ */
+uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
+
+ spip->ssp->DR = (uint32_t)frame;
+ while ((spip->ssp->SR & SR_RNE) == 0)
+ ;
+ return (uint16_t)spip->ssp->DR;
+}
+
+#endif /* HAL_USE_SPI */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/spi_lld.h b/os/hal/platforms/LPC17xx/spi_lld.h
new file mode 100644
index 000000000..cc1674519
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/spi_lld.h
@@ -0,0 +1,337 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file LPC17xx/spi_lld.h
+ * @brief LPC17xx low level SPI driver header.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#ifndef _SPI_LLD_H_
+#define _SPI_LLD_H_
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Hardware FIFO depth.
+ */
+#define LPC17xx_SSP_FIFO_DEPTH 8
+
+#define CR0_DSSMASK 0x0F
+#define CR0_DSS4BIT 3
+#define CR0_DSS5BIT 4
+#define CR0_DSS6BIT 5
+#define CR0_DSS7BIT 6
+#define CR0_DSS8BIT 7
+#define CR0_DSS9BIT 8
+#define CR0_DSS10BIT 9
+#define CR0_DSS11BIT 0xA
+#define CR0_DSS12BIT 0xB
+#define CR0_DSS13BIT 0xC
+#define CR0_DSS14BIT 0xD
+#define CR0_DSS15BIT 0xE
+#define CR0_DSS16BIT 0xF
+#define CR0_FRFSPI 0
+#define CR0_FRFSSI 0x10
+#define CR0_FRFMW 0x20
+#define CR0_CPOL 0x40
+#define CR0_CPHA 0x80
+#define CR0_CLOCKRATE(n) ((n) << 8)
+
+#define CR1_LBM 1
+#define CR1_SSE 2
+#define CR1_MS 4
+#define CR1_SOD 8
+
+#define SR_TFE 1
+#define SR_TNF 2
+#define SR_RNE 4
+#define SR_RFF 8
+#define SR_BSY 16
+
+#define IMSC_ROR 1
+#define IMSC_RT 2
+#define IMSC_RX 4
+#define IMSC_TX 8
+
+#define RIS_ROR 1
+#define RIS_RT 2
+#define RIS_RX 4
+#define RIS_TX 8
+
+#define MIS_ROR 1
+#define MIS_RT 2
+#define MIS_RX 4
+#define MIS_TX 8
+
+#define ICR_ROR 1
+#define ICR_RT 2
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief SPI1 driver enable switch.
+ * @details If set to @p TRUE the support for device SSP0 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC17xx_SPI_USE_SSP0) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_USE_SSP0 TRUE
+#endif
+
+/**
+ * @brief SPI2 driver enable switch.
+ * @details If set to @p TRUE the support for device SSP1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(LPC17xx_SPI_USE_SSP1) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_USE_SSP1 FALSE
+#endif
+
+/**
+ * @brief SSP0 PCLK divider.
+ */
+#if !defined(LPC17xx_SPI_SSP0CLKDIV) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_SSP0CLKDIV 1
+#endif
+
+/**
+ * @brief SSP1 PCLK divider.
+ */
+#if !defined(LPC17xx_SPI_SSP1CLKDIV) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_SSP1CLKDIV 1
+#endif
+
+/**
+ * @brief SPI0 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_SPI_SSP0_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_SSP0_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SPI1 interrupt priority level setting.
+ */
+#if !defined(LPC17xx_SPI_SSP1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_SSP1_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief Overflow error hook.
+ * @details The default action is to stop the system.
+ */
+#if !defined(LPC17xx_SPI_SSP_ERROR_HOOK) || defined(__DOXYGEN__)
+#define LPC17xx_SPI_SSP_ERROR_HOOK(spip) chSysHalt()
+#endif
+
+#if LPC17xx_SPI_SSP0CLKDIV == 1
+#define LPC17xx_SPI_SSP0_PCLKSEL PCLKSEL_CCLK
+#elif LPC17xx_SPI_SSP0CLKDIV == 2
+#define LPC17xx_SPI_SSP0_PCLKSEL PCLKSEL_CCLK_DIV_2
+#elif LPC17xx_SPI_SSP0CLKDIV == 4
+#define LPC17xx_SPI_SSP0_PCLKSEL PCLKSEL_CCLK_DIV_4
+#elif LPC17xx_SPI_SSP0CLKDIV == 8
+#define LPC17xx_SPI_SSP0_PCLKSEL PCLKSEL_CCLK_DIV_8
+#else
+#error "Invalid LPC17xx_SPI_SSP0CLKDIV setting (1, 2, 4 or 8 accepted)"
+#endif
+
+#if LPC17xx_SPI_SSP1CLKDIV == 1
+#define LPC17xx_SPI_SSP1_PCLKSEL PCLKSEL_CCLK
+#elif LPC17xx_SPI_SSP1CLKDIV == 2
+#define LPC17xx_SPI_SSP1_PCLKSEL PCLKSEL_CCLK_DIV_2
+#elif LPC17xx_SPI_SSP1CLKDIV == 4
+#define LPC17xx_SPI_SSP1_PCLKSEL PCLKSEL_CCLK_DIV_4
+#elif LPC17xx_SPI_SSP1CLKDIV == 8
+#define LPC17xx_SPI_SSP1_PCLKSEL PCLKSEL_CCLK_DIV_8
+#else
+#error "Invalid LPC17xx_SPI_SSP1CLKDIV setting (1, 2, 4 or 8 accepted)"
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if (LPC17xx_SPI_SSP0CLKDIV != 1) && (LPC17xx_SPI_SSP0CLKDIV != 2) && \
+ (LPC17xx_SPI_SSP0CLKDIV != 4) && (LPC17xx_SPI_SSP0CLKDIV != 8)
+#error "Invalid LPC17xx_SPI_SSP0CLKDIV setting (1, 2, 4 or 8 accepted)"
+#endif
+
+#if (LPC17xx_SPI_SSP1CLKDIV != 1) && (LPC17xx_SPI_SSP1CLKDIV != 2) && \
+ (LPC17xx_SPI_SSP1CLKDIV != 4) && (LPC17xx_SPI_SSP1CLKDIV != 8)
+#error "invalid LPC17xx_SPI_SSP1CLKDIV setting (1, 2, 4 or 8 accepted)"
+#endif
+
+#if !LPC17xx_SPI_USE_SSP0 && !LPC17xx_SPI_USE_SSP1
+#error "SPI driver activated but no SPI peripheral assigned"
+#endif
+
+/**
+ * @brief SSP0 clock.
+ */
+#define LPC17xx_SPI_SSP0_PCLK \
+ (LPC17xx_CCLK / LPC17xx_SPI_SSP0CLKDIV)
+
+/**
+ * @brief SSP1 clock.
+ */
+#define LPC17xx_SPI_SSP1_PCLK \
+ (LPC17xx_CCLK / LPC17xx_SPI_SSP1CLKDIV)
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a structure representing an SPI driver.
+ */
+typedef struct SPIDriver SPIDriver;
+
+/**
+ * @brief SPI notification callback type.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object triggering the
+ * callback
+ */
+typedef void (*spicallback_t)(SPIDriver *spip);
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Operation complete callback or @p NULL.
+ */
+ spicallback_t end_cb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief The chip select line port.
+ */
+ ioportid_t ssport;
+ /**
+ * @brief The chip select line pad number.
+ */
+ uint16_t sspad;
+ /**
+ * @brief SSP CR0 initialization data.
+ */
+ uint16_t cr0;
+ /**
+ * @brief SSP CPSR initialization data.
+ */
+ uint32_t cpsr;
+} SPIConfig;
+
+/**
+ * @brief Structure representing a SPI driver.
+ */
+struct SPIDriver {
+ /**
+ * @brief Driver state.
+ */
+ spistate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const SPIConfig *config;
+#if SPI_USE_WAIT || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ Thread *thread;
+#endif /* SPI_USE_WAIT */
+#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+#if CH_USE_MUTEXES || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the bus.
+ */
+ Mutex mutex;
+#elif CH_USE_SEMAPHORES
+ Semaphore semaphore;
+#endif
+#endif /* SPI_USE_MUTUAL_EXCLUSION */
+#if defined(SPI_DRIVER_EXT_FIELDS)
+ SPI_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the SSP registers block.
+ */
+ LPC_SSP_TypeDef *ssp;
+ /**
+ * @brief Number of bytes yet to be received.
+ */
+ uint32_t rxcnt;
+ /**
+ * @brief Receive pointer or @p NULL.
+ */
+ void *rxptr;
+ /**
+ * @brief Number of bytes yet to be transmitted.
+ */
+ uint32_t txcnt;
+ /**
+ * @brief Transmit pointer or @p NULL.
+ */
+ const void *txptr;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if LPC17xx_SPI_USE_SSP0 && !defined(__DOXYGEN__)
+extern SPIDriver SPID1;
+#endif
+
+#if LPC17xx_SPI_USE_SSP1 && !defined(__DOXYGEN__)
+extern SPIDriver SPID2;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void spi_lld_init(void);
+ void spi_lld_start(SPIDriver *spip);
+ void spi_lld_stop(SPIDriver *spip);
+ void spi_lld_select(SPIDriver *spip);
+ void spi_lld_unselect(SPIDriver *spip);
+ void spi_lld_ignore(SPIDriver *spip, size_t n);
+ void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf);
+ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
+ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
+ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SPI */
+
+#endif /* _SPI_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/platforms/LPC17xx/system_LPC17xx.h b/os/hal/platforms/LPC17xx/system_LPC17xx.h
new file mode 100644
index 000000000..d72cb509e
--- /dev/null
+++ b/os/hal/platforms/LPC17xx/system_LPC17xx.h
@@ -0,0 +1,64 @@
+/**************************************************************************//**
+ * @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 */
diff --git a/os/ports/GCC/ARMCMx/LPC17xx/cmparams.h b/os/ports/GCC/ARMCMx/LPC17xx/cmparams.h
new file mode 100644
index 000000000..9483509dc
--- /dev/null
+++ b/os/ports/GCC/ARMCMx/LPC17xx/cmparams.h
@@ -0,0 +1,62 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file GCC/ARMCMx/LPC17xx/cmparams.h
+ * @brief ARM Cortex-M3 LPC17xx Specific Parameters.
+ *
+ * @defgroup ARMCMx_LPC13xx LPC17xx Specific Parameters
+ * @ingroup ARMCMx_SPECIFIC
+ * @details This file contains the Cortex-M3 specific parameters for the
+ * LPC17xx platform.
+ * @{
+ */
+
+#ifndef _CMPARAMS_H_
+#define _CMPARAMS_H_
+
+/**
+ * @brief Cortex core model.
+ */
+#define CORTEX_MODEL CORTEX_M3
+
+/**
+ * @brief Systick unit presence.
+ */
+#define CORTEX_HAS_ST TRUE
+
+/**
+ * @brief Memory Protection unit presence.
+ */
+#define CORTEX_HAS_MPU TRUE
+
+/**
+ * @brief Floating Point unit presence.
+ */
+#define CORTEX_HAS_FPU FALSE
+
+/**
+ * @brief Number of bits in priority masks.
+ */
+#define CORTEX_PRIORITY_BITS 3
+
+#endif /* _CMPARAMS_H_ */
+
+/** @} */
diff --git a/os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1766.ld b/os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1766.ld
new file mode 100644
index 000000000..2a12d97e3
--- /dev/null
+++ b/os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1766.ld
@@ -0,0 +1,153 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * LPC1766 memory setup.
+ */
+__main_stack_size__ = 0x0200;
+__process_stack_size__ = 0x0200;
+
+MEMORY
+{
+ flash : org = 0x00000000, len = 256k
+ ram : org = 0x10000000, len = 32k
+ ramahb : org = 0x2007c000, len = 32k
+}
+
+__ram_start__ = ORIGIN(ram);
+__ram_size__ = LENGTH(ram);
+__ram_end__ = __ram_start__ + __ram_size__;
+
+ENTRY(ResetHandler)
+
+SECTIONS
+{
+ . = 0;
+ _text = .;
+
+ startup : ALIGN(16) SUBALIGN(16)
+ {
+ KEEP(*(vectors))
+ } > flash
+
+ constructors : ALIGN(4) SUBALIGN(4)
+ {
+ PROVIDE(__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE(__init_array_end = .);
+ } > flash
+
+ destructors : ALIGN(4) SUBALIGN(4)
+ {
+ PROVIDE(__fini_array_start = .);
+ KEEP(*(.fini_array))
+ KEEP(*(SORT(.fini_array.*)))
+ PROVIDE(__fini_array_end = .);
+ } > flash
+
+ .text : ALIGN(16) SUBALIGN(16)
+ {
+ *(.text.startup.*)
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.gcc*)
+ } > flash
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > flash
+
+ .ARM.exidx : {
+ PROVIDE(__exidx_start = .);
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ PROVIDE(__exidx_end = .);
+ } > flash
+
+ .eh_frame_hdr :
+ {
+ *(.eh_frame_hdr)
+ } > flash
+
+ .eh_frame : ONLY_IF_RO
+ {
+ *(.eh_frame)
+ } > flash
+
+ .textalign : ONLY_IF_RO
+ {
+ . = ALIGN(8);
+ } > flash
+
+ _etext = .;
+ _textdata = _etext;
+
+ .stacks :
+ {
+ . = ALIGN(8);
+ __main_stack_base__ = .;
+ . += __main_stack_size__;
+ . = ALIGN(8);
+ __main_stack_end__ = .;
+ __process_stack_base__ = .;
+ __main_thread_stack_base__ = .;
+ . += __process_stack_size__;
+ . = ALIGN(8);
+ __process_stack_end__ = .;
+ __main_thread_stack_end__ = .;
+ } > ram
+
+ .data :
+ {
+ . = ALIGN(4);
+ PROVIDE(_data = .);
+ *(.data)
+ . = ALIGN(4);
+ *(.data.*)
+ . = ALIGN(4);
+ *(.ramtext)
+ . = ALIGN(4);
+ PROVIDE(_edata = .);
+ } > ram AT > flash
+
+ .bss :
+ {
+ . = ALIGN(4);
+ PROVIDE(_bss_start = .);
+ *(.bss)
+ . = ALIGN(4);
+ *(.bss.*)
+ . = ALIGN(4);
+ *(COMMON)
+ . = ALIGN(4);
+ PROVIDE(_bss_end = .);
+ } > ram
+}
+
+PROVIDE(end = .);
+_end = .;
+
+__heap_base__ = _end;
+__heap_end__ = __ram_end__;
diff --git a/os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1769.ld b/os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1769.ld
new file mode 100644
index 000000000..dc5c1feb8
--- /dev/null
+++ b/os/ports/GCC/ARMCMx/LPC17xx/ld/LPC1769.ld
@@ -0,0 +1,153 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * LPC1766 memory setup.
+ */
+__main_stack_size__ = 0x0200;
+__process_stack_size__ = 0x0200;
+
+MEMORY
+{
+ flash : org = 0x00000000, len = 512k
+ ram : org = 0x10000000, len = 32k
+ ramahb : org = 0x2007c000, len = 32k
+}
+
+__ram_start__ = ORIGIN(ram);
+__ram_size__ = LENGTH(ram);
+__ram_end__ = __ram_start__ + __ram_size__;
+
+ENTRY(ResetHandler)
+
+SECTIONS
+{
+ . = 0;
+ _text = .;
+
+ startup : ALIGN(16) SUBALIGN(16)
+ {
+ KEEP(*(vectors))
+ } > flash
+
+ constructors : ALIGN(4) SUBALIGN(4)
+ {
+ PROVIDE(__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE(__init_array_end = .);
+ } > flash
+
+ destructors : ALIGN(4) SUBALIGN(4)
+ {
+ PROVIDE(__fini_array_start = .);
+ KEEP(*(.fini_array))
+ KEEP(*(SORT(.fini_array.*)))
+ PROVIDE(__fini_array_end = .);
+ } > flash
+
+ .text : ALIGN(16) SUBALIGN(16)
+ {
+ *(.text.startup.*)
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.gcc*)
+ } > flash
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > flash
+
+ .ARM.exidx : {
+ PROVIDE(__exidx_start = .);
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ PROVIDE(__exidx_end = .);
+ } > flash
+
+ .eh_frame_hdr :
+ {
+ *(.eh_frame_hdr)
+ } > flash
+
+ .eh_frame : ONLY_IF_RO
+ {
+ *(.eh_frame)
+ } > flash
+
+ .textalign : ONLY_IF_RO
+ {
+ . = ALIGN(8);
+ } > flash
+
+ _etext = .;
+ _textdata = _etext;
+
+ .stacks :
+ {
+ . = ALIGN(8);
+ __main_stack_base__ = .;
+ . += __main_stack_size__;
+ . = ALIGN(8);
+ __main_stack_end__ = .;
+ __process_stack_base__ = .;
+ __main_thread_stack_base__ = .;
+ . += __process_stack_size__;
+ . = ALIGN(8);
+ __process_stack_end__ = .;
+ __main_thread_stack_end__ = .;
+ } > ram
+
+ .data :
+ {
+ . = ALIGN(4);
+ PROVIDE(_data = .);
+ *(.data)
+ . = ALIGN(4);
+ *(.data.*)
+ . = ALIGN(4);
+ *(.ramtext)
+ . = ALIGN(4);
+ PROVIDE(_edata = .);
+ } > ram AT > flash
+
+ .bss :
+ {
+ . = ALIGN(4);
+ PROVIDE(_bss_start = .);
+ *(.bss)
+ . = ALIGN(4);
+ *(.bss.*)
+ . = ALIGN(4);
+ *(COMMON)
+ . = ALIGN(4);
+ PROVIDE(_bss_end = .);
+ } > ram
+}
+
+PROVIDE(end = .);
+_end = .;
+
+__heap_base__ = _end;
+__heap_end__ = __ram_end__;
diff --git a/os/ports/GCC/ARMCMx/LPC17xx/port.mk b/os/ports/GCC/ARMCMx/LPC17xx/port.mk
new file mode 100644
index 000000000..e98993ce2
--- /dev/null
+++ b/os/ports/GCC/ARMCMx/LPC17xx/port.mk
@@ -0,0 +1,15 @@
+# List of the ChibiOS/RT Cortex-M3 LPC17xx port files.
+PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/crt0.c \
+ $(CHIBIOS)/os/ports/GCC/ARMCMx/LPC17xx/vectors.c \
+ ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \
+ ${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v7m.c \
+ ${CHIBIOS}/os/ports/common/ARMCMx/nvic.c
+
+PORTASM =
+
+PORTINC = ${CHIBIOS}/os/ports/common/ARMCMx/CMSIS/include \
+ ${CHIBIOS}/os/ports/common/ARMCMx \
+ ${CHIBIOS}/os/ports/GCC/ARMCMx \
+ ${CHIBIOS}/os/ports/GCC/ARMCMx/LPC17xx
+
+PORTLD = ${CHIBIOS}/os/ports/GCC/ARMCMx/LPC17xx/ld
diff --git a/os/ports/GCC/ARMCMx/LPC17xx/vectors.c b/os/ports/GCC/ARMCMx/LPC17xx/vectors.c
new file mode 100644
index 000000000..cc2d72133
--- /dev/null
+++ b/os/ports/GCC/ARMCMx/LPC17xx/vectors.c
@@ -0,0 +1,205 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012,2013 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file GCC/ARMCMx/LPC13xx/vectors.c
+ * @brief Interrupt vectors for the LPC17xx family.
+ *
+ * @defgroup ARMCMx_LPC17xx_VECTORS LPC17xx Interrupt Vectors
+ * @ingroup ARMCMx_SPECIFIC
+ * @details Interrupt vectors for the LPC17xx family.
+ * @{
+ */
+
+#include "ch.h"
+
+/**
+ * @brief Type of an IRQ vector.
+ */
+typedef void (*irq_vector_t)(void);
+
+/**
+ * @brief Type of a structure representing the whole vectors table.
+ */
+typedef struct {
+ uint32_t *init_stack;
+ irq_vector_t reset_vector;
+ irq_vector_t nmi_vector;
+ irq_vector_t hardfault_vector;
+ irq_vector_t memmanage_vector;
+ irq_vector_t busfault_vector;
+ irq_vector_t usagefault_vector;
+ irq_vector_t vector1c;
+ irq_vector_t vector20;
+ irq_vector_t vector24;
+ irq_vector_t vector28;
+ irq_vector_t svcall_vector;
+ irq_vector_t debugmonitor_vector;
+ irq_vector_t vector34;
+ irq_vector_t pendsv_vector;
+ irq_vector_t systick_vector;
+ irq_vector_t vectors[35];
+} vectors_t;
+
+#if !defined(__DOXYGEN__)
+extern uint32_t __main_stack_end__;
+extern void ResetHandler(void);
+extern void NMIVector(void);
+extern void HardFaultVector(void);
+extern void MemManageVector(void);
+extern void BusFaultVector(void);
+extern void UsageFaultVector(void);
+extern void Vector1C(void);
+extern void Vector20(void);
+extern void Vector24(void);
+extern void Vector28(void);
+extern void SVCallVector(void);
+extern void DebugMonitorVector(void);
+extern void Vector34(void);
+extern void PendSVVector(void);
+extern void SysTickVector(void);
+extern void Vector40(void);
+extern void Vector44(void);
+extern void Vector48(void);
+extern void Vector4C(void);
+extern void Vector50(void);
+extern void Vector54(void);
+extern void Vector58(void);
+extern void Vector5C(void);
+extern void Vector60(void);
+extern void Vector64(void);
+extern void Vector68(void);
+extern void Vector6C(void);
+extern void Vector70(void);
+extern void Vector74(void);
+extern void Vector78(void);
+extern void Vector7C(void);
+extern void Vector80(void);
+extern void Vector84(void);
+extern void Vector88(void);
+extern void Vector8C(void);
+extern void Vector90(void);
+extern void Vector94(void);
+extern void Vector98(void);
+extern void Vector9C(void);
+extern void VectorA0(void);
+extern void VectorA4(void);
+extern void VectorA8(void);
+extern void VectorAC(void);
+extern void VectorB0(void);
+extern void VectorB4(void);
+extern void VectorB8(void);
+extern void VectorBC(void);
+extern void VectorC0(void);
+extern void VectorC4(void);
+extern void VectorC8(void);
+#endif
+
+/**
+ * @brief LPC17xx vectors table.
+ */
+#if !defined(__DOXYGEN__)
+__attribute__ ((section("vectors")))
+#endif
+vectors_t _vectors = {
+ &__main_stack_end__,ResetHandler, NMIVector, HardFaultVector,
+ MemManageVector, BusFaultVector, UsageFaultVector, Vector1C,
+ Vector20, Vector24, Vector28, SVCallVector,
+ DebugMonitorVector, Vector34, PendSVVector, SysTickVector,
+ {
+ Vector40, Vector44, Vector48, Vector4C,
+ Vector50, Vector54, Vector58, Vector5C,
+ Vector60, Vector64, Vector68, Vector6C,
+ Vector70, Vector74, Vector78, Vector7C,
+ Vector80, Vector84, Vector88, Vector8C,
+ Vector90, Vector94, Vector98, Vector9C,
+ VectorA0, VectorA4, VectorA8, VectorAC,
+ VectorB0, VectorB4, VectorB8, VectorBC,
+ VectorC0, VectorC4, VectorC8
+ }
+};
+
+/**
+ * @brief Unhandled exceptions handler.
+ * @details Any undefined exception vector points to this function by default.
+ * This function simply stops the system into an infinite loop.
+ *
+ * @notapi
+ */
+#if !defined(__DOXYGEN__)
+__attribute__ ((naked))
+#endif
+void _unhandled_exception(void) {
+
+ while (TRUE)
+ ;
+}
+
+void NMIVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void HardFaultVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void MemManageVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void BusFaultVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void UsageFaultVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector1C(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector20(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector24(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector28(void) __attribute__((weak, alias("_unhandled_exception")));
+void SVCallVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void DebugMonitorVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector34(void) __attribute__((weak, alias("_unhandled_exception")));
+void PendSVVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void SysTickVector(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector40(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector44(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector48(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector4C(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector50(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector54(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector58(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector5C(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector60(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector64(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector68(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector6C(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector70(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector74(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector78(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector7C(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector80(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector84(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector88(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector8C(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector90(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector94(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector98(void) __attribute__((weak, alias("_unhandled_exception")));
+void Vector9C(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorA0(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorA4(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorA8(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorAC(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorB0(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorB4(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorB8(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorBC(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorC0(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorC4(void) __attribute__((weak, alias("_unhandled_exception")));
+void VectorC8(void) __attribute__((weak, alias("_unhandled_exception")));
+
+/** @} */
diff --git a/os/various/chrtclib.c b/os/various/chrtclib.c
index f2616d460..6fcb3de41 100644
--- a/os/various/chrtclib.c
+++ b/os/various/chrtclib.c
@@ -37,7 +37,9 @@
defined(STM32F30X) || defined(STM32F37X) || \
defined(STM32F1XX) || defined(STM32F10X_MD) || defined(STM32F10X_LD) || \
defined(STM32F10X_HD) || defined(STM32F10X_CL) || defined(STM32F0XX) || \
- defined(LPC122X) || defined(__DOXYGEN__))
+ defined(LPC122X) || defined(LPC17XX) || defined(__DOXYGEN__))
+#if STM32_RTC_IS_CALENDAR || LPC17xx_RTC_IS_CALENDAR
+
#if STM32_RTC_IS_CALENDAR
/**
* @brief Converts from STM32 BCD to canonicalized time format.
@@ -135,6 +137,47 @@ static void stm32_rtc_tm2bcd(struct tm *timp, RTCTime *timespec) {
timespec->tv_time |= ((v / 10) << RTC_TR_ST_OFFSET) & RTC_TR_ST;
timespec->tv_time |= (v % 10) << RTC_TR_SU_OFFSET;
}
+#endif
+
+#if LPC17xx_RTC_IS_CALENDAR
+/**
+ * @brief Converts from LPC17xx RTC format to canonicalized time format.
+ *
+ * @param[out] timp pointer to a @p tm structure as defined in time.h
+ * @param[in] timespec pointer to a @p RTCTime structure
+ *
+ * @notapi
+ */
+static void lpc17xx_rtc_format2tm(struct tm *timp, RTCTime *timespec) {
+ timp->tm_sec = timespec->sec;
+ timp->tm_min = timespec->min;
+ timp->tm_hour = timespec->hour;
+ timp->tm_mday = timespec->dom;
+ timp->tm_mon = timespec->month - 1;
+ timp->tm_year = timespec->year - 1900;
+ timp->tm_wday = timespec->dow;
+ timp->tm_yday = timespec->doy - 1;
+}
+
+/**
+ * @brief Converts from LPC17xx RTC format to canonicalized time format.
+ *
+ * @param[out] timp pointer to a @p tm structure as defined in time.h
+ * @param[in] timespec pointer to a @p RTCTime structure
+ *
+ * @notapi
+ */
+static void lpc17xx_rtc_tm2format(struct tm *timp, RTCTime *timespec) {
+ timespec->sec = timp->tm_sec;
+ timespec->min = timp->tm_min;
+ timespec->hour = timp->tm_hour;
+ timespec->dom = timp->tm_mday;
+ timespec->month = timp->tm_mon + 1;
+ timespec->year = timp->tm_year + 1900;
+ timespec->dow = timp->tm_wday;
+ timespec->doy = timp->tm_yday + 1;
+}
+#endif
/**
* @brief Gets raw time from RTC and converts it to canonicalized format.
@@ -145,6 +188,7 @@ static void stm32_rtc_tm2bcd(struct tm *timp, RTCTime *timespec) {
* @api
*/
void rtcGetTimeTm(RTCDriver *rtcp, struct tm *timp) {
+#if STM32_RTC_IS_CALENDAR
#if STM32_RTC_HAS_SUBSECONDS
RTCTime timespec = {0,0,FALSE,0};
#else
@@ -153,6 +197,14 @@ void rtcGetTimeTm(RTCDriver *rtcp, struct tm *timp) {
rtcGetTime(rtcp, &timespec);
stm32_rtc_bcd2tm(timp, &timespec);
+#endif
+
+#if LPC17xx_RTC_IS_CALENDAR
+ RTCTime timespec;
+
+ rtcGetTime(rtcp, &timespec);
+ lpc17xx_rtc_format2tm(timp, &timespec);
+#endif
}
/**
@@ -164,6 +216,7 @@ void rtcGetTimeTm(RTCDriver *rtcp, struct tm *timp) {
* @api
*/
void rtcSetTimeTm(RTCDriver *rtcp, struct tm *timp) {
+#if STM32_RTC_IS_CALENDAR
#if STM32_RTC_HAS_SUBSECONDS
RTCTime timespec = {0,0,FALSE,0};
#else
@@ -172,6 +225,14 @@ void rtcSetTimeTm(RTCDriver *rtcp, struct tm *timp) {
stm32_rtc_tm2bcd(timp, &timespec);
rtcSetTime(rtcp, &timespec);
+#endif
+
+#if LPC17xx_RTC_IS_CALENDAR
+ RTCTime timespec;
+
+ lpc17xx_rtc_tm2format(timp, &timespec);
+ rtcSetTime(rtcp, &timespec);
+#endif
}
/**
@@ -183,6 +244,7 @@ void rtcSetTimeTm(RTCDriver *rtcp, struct tm *timp) {
* @api
*/
time_t rtcGetTimeUnixSec(RTCDriver *rtcp) {
+#if STM32_RTC_IS_CALENDAR
#if STM32_RTC_HAS_SUBSECONDS
RTCTime timespec = {0,0,FALSE,0};
#else
@@ -194,6 +256,16 @@ time_t rtcGetTimeUnixSec(RTCDriver *rtcp) {
stm32_rtc_bcd2tm(&timp, &timespec);
return mktime(&timp);
+#endif
+
+#if LPC17xx_RTC_IS_CALENDAR
+ RTCTime timespec;
+ struct tm timp;
+
+ rtcGetTime(rtcp, &timespec);
+ lpc17xx_rtc_format2tm(&timp, &timespec);
+ return mktime(&timp);
+#endif
}
/**
@@ -206,6 +278,7 @@ time_t rtcGetTimeUnixSec(RTCDriver *rtcp) {
* @api
*/
void rtcSetTimeUnixSec(RTCDriver *rtcp, time_t tv_sec) {
+#if STM32_RTC_IS_CALENDAR
#if STM32_RTC_HAS_SUBSECONDS
RTCTime timespec = {0,0,FALSE,0};
#else
@@ -216,6 +289,16 @@ void rtcSetTimeUnixSec(RTCDriver *rtcp, time_t tv_sec) {
localtime_r(&tv_sec, &timp);
stm32_rtc_tm2bcd(&timp, &timespec);
rtcSetTime(rtcp, &timespec);
+#endif
+
+#if LPC17xx_RTC_IS_CALENDAR
+ RTCTime timespec;
+ struct tm timp;
+
+ localtime_r(&tv_sec, &timp);
+ lpc17xx_rtc_tm2format(&timp, &timespec);
+ rtcSetTime(rtcp, &timespec);
+#endif
}
/**
@@ -354,7 +437,7 @@ uint32_t rtcGetTimeFatFromCounter(RTCDriver *rtcp) {
return fattime;
}
-#endif /* STM32_RTC_IS_CALENDAR */
+#endif /* STM32_RTC_IS_CALENDAR || LPC17xx_RTC_IS_CALENDAR */
#endif /* (defined(STM32F4XX) || defined(STM32F2XX) || defined(STM32L1XX) || defined(STM32F1XX)) */
/** @} */