diff --git a/cpu/lpc11u34/Makefile b/cpu/lpc11u34/Makefile new file mode 100644 index 0000000000..21f0d18719 --- /dev/null +++ b/cpu/lpc11u34/Makefile @@ -0,0 +1,7 @@ +# define the module that is build +MODULE = cpu + +# add a list of subdirectories, that should also be build +DIRS = periph $(RIOTCPU)/cortexm_common + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/lpc11u34/Makefile.include b/cpu/lpc11u34/Makefile.include new file mode 100644 index 0000000000..04c2fd5dd4 --- /dev/null +++ b/cpu/lpc11u34/Makefile.include @@ -0,0 +1,3 @@ +export CPU_ARCH = cortex-m0 + +include $(RIOTCPU)/Makefile.include.cortexm_common diff --git a/cpu/lpc11u34/cpu.c b/cpu/lpc11u34/cpu.c new file mode 100644 index 0000000000..a41832e254 --- /dev/null +++ b/cpu/lpc11u34/cpu.c @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Implementation of the CPU initialization + * + * @author Paul RATHGEB + * @} + */ + +#include "cpu.h" + + +#define SYSOSCCTRL_Val 0x00000000 /* Reset: 0x000 */ +#define SYSPLLCTRL_Val 0x00000023 /* Reset: 0x000 */ +#define SYSPLLCLKSEL_Val 0x00000001 /* Reset: 0x000 */ +#define MAINCLKSEL_Val 0x00000003 /* Reset: 0x000 */ +#define SYSAHBCLKDIV_Val 0x00000001 /* Reset: 0x001 */ +#define USBPLLCTRL_Val 0x00000023 /* Reset: 0x000 */ +#define USBPLLCLKSEL_Val 0x00000001 /* Reset: 0x000 */ +#define USBCLKSEL_Val 0x00000000 /* Reset: 0x000 */ +#define USBCLKDIV_Val 0x00000001 /* Reset: 0x001 */ + +/** + * @brief Initialize the CPU clock + * + * This configuration use an external XTAL + */ +void clk_init(void) +{ + volatile uint32_t i; + + /* Power-up System Osc */ + LPC_SYSCON->PDRUNCFG &= ~(1 << 5); + LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val; + for (i = 0; i < 200; i++) __NOP(); + + /* Select PLL Input*/ + LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; + /* Update clock source */ + LPC_SYSCON->SYSPLLCLKUEN = 0x01; + /* Toggle update register */ + LPC_SYSCON->SYSPLLCLKUEN = 0x00; + LPC_SYSCON->SYSPLLCLKUEN = 0x01; + /* Wait until updated */ + while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); + /* Main Clock is PLL Out */ + LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val; + /* Power-up SYSPLL */ + LPC_SYSCON->PDRUNCFG &= ~(1 << 7); + /* Wait Until PLL Locked */ + while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); + + /* Select PLL Clock Output */ + LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; + /* Update MCLK Clock Source */ + LPC_SYSCON->MAINCLKUEN = 0x01; + /* Toggle Update Register */ + LPC_SYSCON->MAINCLKUEN = 0x00; + LPC_SYSCON->MAINCLKUEN = 0x01; + /* Wait Until Updated */ + while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); + + LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val; + + /* Power-up USB PHY */ + LPC_SYSCON->PDRUNCFG &= ~(1 << 10); + /* Power-up USB PLL */ + LPC_SYSCON->PDRUNCFG &= ~(1 << 8); + /* Select PLL Input */ + LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val; + /* Update Clock Source */ + LPC_SYSCON->USBPLLCLKUEN = 0x01; + /* Toggle Update Register */ + LPC_SYSCON->USBPLLCLKUEN = 0x00; + LPC_SYSCON->USBPLLCLKUEN = 0x01; + /* Wait Until Updated */ + while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01)); + LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val; + /* Wait Until PLL Locked */ + while (!(LPC_SYSCON->USBPLLSTAT & 0x01)); + + /* Select USB Clock */ + LPC_SYSCON->USBCLKSEL = USBCLKSEL_Val; + /* Toggle Update Register */ + LPC_SYSCON->USBCLKUEN = 0x00; + LPC_SYSCON->USBCLKUEN = 0x01; + /* Set USB clock divider */ + LPC_SYSCON->USBCLKDIV = USBCLKDIV_Val; + + /* System clock to the IOCON needs to be enabled or + most of the I/O related peripherals won't work. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16); +} + +/** + * @brief Initialize the CPU, set IRQ priorities + */ +void cpu_init(void) +{ + /* initialize the Cortex-M core */ + cortexm_init(); + /* initialize the clock */ + clk_init(); +} diff --git a/cpu/lpc11u34/include/LPC11Uxx.h b/cpu/lpc11u34/include/LPC11Uxx.h new file mode 100644 index 0000000000..35afda3511 --- /dev/null +++ b/cpu/lpc11u34/include/LPC11Uxx.h @@ -0,0 +1,666 @@ +/** + * @defgroup cpu_lpc11u34 NXP LPC11U34 + * @ingroup cpu + * @brief CMSIS Core Peripheral Assess Layer + * @{ + * @file + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * for NXP LPC11uxx Device Series + * @version: V0.1 + * @date: 21. March 2011 + * + * @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. + * + * 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 __LPC11UXX_H__ +#define __LPC11UXX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined ( __CC_ARM ) + #pragma anon_unions +#endif + + /* Interrupt Number Definition */ + +typedef enum { +// ------------------------- Cortex-M0 Processor Exceptions Numbers ----------------------------- + Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */ + PendSV_IRQn = -2, /*!< 14 Pendable request for system service */ + SysTick_IRQn = -1, /*!< 15 System Tick Timer */ +// --------------------------- LPC11Uxx Specific Interrupt Numbers ------------------------------ + FLEX_INT0_IRQn = 0, /*!< All I/O pins can be routed to below 8 interrupts.*/ + FLEX_INT1_IRQn = 1, /*!< Flex interrupt 1 */ + FLEX_INT2_IRQn = 2, /*!< Flex interrupt 2 */ + FLEX_INT3_IRQn = 3, /*!< Flex interrupt 3 */ + FLEX_INT4_IRQn = 4, /*!< Flex interrupt 4 */ + FLEX_INT5_IRQn = 5, /*!< Flex interrupt 5 */ + FLEX_INT6_IRQn = 6, /*!< Flex interrupt 6 */ + FLEX_INT7_IRQn = 7, /*!< Flex interrupt 7 */ + GINT0_IRQn = 8, /*!< Grouped Interrupt 0 */ + GINT1_IRQn = 9, /*!< Grouped Interrupt 1 */ + Reserved0_IRQn = 10, /*!< Reserved Interrupt */ + Reserved1_IRQn = 11, /*!< Reserved Interrupt */ + Reserved2_IRQn = 12, /*!< Reserved Interrupt */ + Reserved3_IRQn = 13, /*!< Reserved Interrupt */ + SSP1_IRQn = 14, /*!< SSP1 Interrupt */ + I2C_IRQn = 15, /*!< I2C Interrupt */ + TIMER_16_0_IRQn = 16, /*!< 16-bit Timer0 Interrupt */ + TIMER_16_1_IRQn = 17, /*!< 16-bit Timer1 Interrupt */ + TIMER_32_0_IRQn = 18, /*!< 32-bit Timer0 Interrupt */ + TIMER_32_1_IRQn = 19, /*!< 32-bit Timer1 Interrupt */ + SSP0_IRQn = 20, /*!< SSP0 Interrupt */ + UART_IRQn = 21, /*!< UART Interrupt */ + USB_IRQn = 22, /*!< USB IRQ Interrupt */ + USB_FIQn = 23, /*!< USB FIQ Interrupt */ + ADC_IRQn = 24, /*!< A/D Converter Interrupt */ + WDT_IRQn = 25, /*!< Watchdog timer Interrupt */ + BOD_IRQn = 26, /*!< Brown Out Detect(BOD) Interrupt */ + FMC_IRQn = 27, /*!< Flash Memory Controller Interrupt */ + Reserved4_IRQn = 28, /*!< Reserved Interrupt */ + Reserved5_IRQn = 29, /*!< Reserved Interrupt */ + USBWakeup_IRQn = 30, /*!< USB wakeup Interrupt */ + Reserved6_IRQn = 31, /*!< Reserved Interrupt */ +} IRQn_Type; + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + +/* Processor and Core Peripheral Section */ /* Configuration of the Cortex-M0 Processor and Core Peripherals */ + +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "core_cm0.h" /*!< Cortex-M0 processor and core peripherals */ + +/** @addtogroup Device_Peripheral_Registers + * @{ + */ + + +// ------------------------------------------------------------------------------------------------ +// ----- I2C ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x I2C-bus controller Modification date=3/16/2011 Major revision=0 Minor revision=3 (I2C) + */ + +typedef struct { /*!< (@ 0x40000000) I2C Structure */ + __IO uint32_t CONSET; /*!< (@ 0x40000000) I2C Control Set Register */ + __I uint32_t STAT; /*!< (@ 0x40000004) I2C Status Register */ + __IO uint32_t DAT; /*!< (@ 0x40000008) I2C Data Register. */ + __IO uint32_t ADR0; /*!< (@ 0x4000000C) I2C Slave Address Register 0 */ + __IO uint32_t SCLH; /*!< (@ 0x40000010) SCH Duty Cycle Register High Half Word */ + __IO uint32_t SCLL; /*!< (@ 0x40000014) SCL Duty Cycle Register Low Half Word */ + __IO uint32_t CONCLR; /*!< (@ 0x40000018) I2C Control Clear Register*/ + __IO uint32_t MMCTRL; /*!< (@ 0x4000001C) Monitor mode control register*/ + __IO uint32_t ADR1; /*!< (@ 0x40000020) I2C Slave Address Register 1*/ + __IO uint32_t ADR2; /*!< (@ 0x40000024) I2C Slave Address Register 2*/ + __IO uint32_t ADR3; /*!< (@ 0x40000028) I2C Slave Address Register 3*/ + __I uint32_t DATA_BUFFER; /*!< (@ 0x4000002C) Data buffer register */ +union{ + __IO uint32_t MASK[4]; /*!< (@ 0x40000030) I2C Slave address mask register */ + struct{ + __IO uint32_t MASK0; /*!< (@ 0x40000030) I2C Slave address mask register 0 */ + __IO uint32_t MASK1; /*!< (@ 0x40000034) I2C Slave address mask register 1 */ + __IO uint32_t MASK2; /*!< (@ 0x40000038) I2C Slave address mask register 2 */ + __IO uint32_t MASK3; /*!< (@ 0x4000003C) I2C Slave address mask register 3 */ + }; + }; +} LPC_I2C_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- WWDT ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x Windowed Watchdog Timer (WWDT) Modification date=3/16/2011 Major revision=0 Minor revision=3 (WWDT) + */ + +typedef struct { /*!< (@ 0x40004000) WWDT Structure */ + __IO uint32_t MOD; /*!< (@ 0x40004000) Watchdog mode register*/ + __IO uint32_t TC; /*!< (@ 0x40004004) Watchdog timer constant register */ + __IO uint32_t FEED; /*!< (@ 0x40004008) Watchdog feed sequence register */ + __I uint32_t TV; /*!< (@ 0x4000400C) Watchdog timer value register */ + __IO uint32_t CLKSEL; /*!< (@ 0x40004010) Watchdog clock select register. */ + __IO uint32_t WARNINT; /*!< (@ 0x40004014) Watchdog Warning Interrupt compare value. */ + __IO uint32_t WINDOW; /*!< (@ 0x40004018) Watchdog Window compare value. */ +} LPC_WWDT_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- USART ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x USART Modification date=3/16/2011 Major revision=0 Minor revision=3 (USART) + */ + +typedef struct { /*!< (@ 0x40008000) USART Structure */ + + union { + __IO uint32_t DLL; /*!< (@ 0x40008000) Divisor Latch LSB. Least significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */ + __O uint32_t THR; /*!< (@ 0x40008000) Transmit Holding Register. The next character to be transmitted is written here. (DLAB=0) */ + __I uint32_t RBR; /*!< (@ 0x40008000) Receiver Buffer Register. Contains the next received character to be read. (DLAB=0) */ + }; + + union { + __IO uint32_t IER; /*!< (@ 0x40008004) Interrupt Enable Register. Contains individual interrupt enable bits for the 7 potential USART interrupts. (DLAB=0) */ + __IO uint32_t DLM; /*!< (@ 0x40008004) Divisor Latch MSB. Most significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */ + }; + + union { + __O uint32_t FCR; /*!< (@ 0x40008008) FIFO Control Register. Controls USART FIFO usage and modes. */ + __I uint32_t IIR; /*!< (@ 0x40008008) Interrupt ID Register. Identifies which interrupt(s) are pending. */ + }; + __IO uint32_t LCR; /*!< (@ 0x4000800C) Line Control Register. Contains controls for frame formatting and break generation. */ + __IO uint32_t MCR; /*!< (@ 0x40008010) Modem Control Register. */ + __I uint32_t LSR; /*!< (@ 0x40008014) Line Status Register. Contains flags for transmit and receive status, including line errors. */ + __I uint32_t MSR; /*!< (@ 0x40008018) Modem Status Register. */ + __IO uint32_t SCR; /*!< (@ 0x4000801C) Scratch Pad Register. Eight-bit temporary storage for software. */ + __IO uint32_t ACR; /*!< (@ 0x40008020) Auto-baud Control Register. Contains controls for the auto-baud feature. */ + __IO uint32_t ICR; /*!< (@ 0x40008024) IrDA Control Register. Enables and configures the IrDA (remote control) mode. */ + __IO uint32_t FDR; /*!< (@ 0x40008028) Fractional Divider Register. Generates a clock input for the baud rate divider. */ + __IO uint32_t OSR; /*!< (@ 0x4000802C) Oversampling Register. Controls the degree of oversampling during each bit time. */ + __IO uint32_t TER; /*!< (@ 0x40008030) Transmit Enable Register. Turns off USART transmitter for use with software flow control. */ + __I uint32_t RESERVED0[3]; /*!< (@ 0x40008034) Reserved */ + __IO uint32_t HDEN; /*!< (@ 0x40008040) Half duplex enable register. */ + __I uint32_t RESERVED1; /*!< (@ 0x40008044) Reserved */ + __IO uint32_t SCICTRL; /*!< (@ 0x40008048) Smart Card Interface Control register. Enables and configures the Smart Card Interface feature. */ + __IO uint32_t RS485CTRL; /*!< (@ 0x4000804C) RS-485/EIA-485 Control. Contains controls to configure various aspects of RS-485/EIA-485 modes. */ + __IO uint32_t RS485ADRMATCH; /*!< (@ 0x40008050) RS-485/EIA-485 address match. Contains the address match value for RS-485/EIA-485 mode. */ + __IO uint32_t RS485DLY; /*!< (@ 0x40008054) RS-485/EIA-485 direction control delay. */ + __IO uint32_t SYNCCTRL; /*!< (@ 0x40008058) Synchronous mode control */ +} LPC_USART_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- Timer ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x 32-bitcounter/timers CT32B0/1 Modification date=3/16/2011 Major revision=0 Minor revision=3 + */ + +typedef struct { /*!< (@ 0x40014000) CT32B0 Structure */ + __IO uint32_t IR; /*!< (@ 0x40014000) Interrupt Register */ + __IO uint32_t TCR; /*!< (@ 0x40014004) Timer Control Register */ + __IO uint32_t TC; /*!< (@ 0x40014008) Timer Counter */ + __IO uint32_t PR; /*!< (@ 0x4001400C) Prescale Register */ + __IO uint32_t PC; /*!< (@ 0x40014010) Prescale Counter */ + __IO uint32_t MCR; /*!< (@ 0x40014014) Match Control Register */ + union { + __IO uint32_t MR[4]; /*!< (@ 0x40014018) Match Register */ + struct{ + __IO uint32_t MR0; /*!< (@ 0x40018018) Match Register. MR0 */ + __IO uint32_t MR1; /*!< (@ 0x4001801C) Match Register. MR1 */ + __IO uint32_t MR2; /*!< (@ 0x40018020) Match Register. MR2 */ + __IO uint32_t MR3; /*!< (@ 0x40018024) Match Register. MR3 */ + }; + }; + __IO uint32_t CCR; /*!< (@ 0x40014028) Capture Control Register */ + union{ + __I uint32_t CR[4]; /*!< (@ 0x4001402C) Capture Register */ + struct{ + __I uint32_t CR0; /*!< (@ 0x4001802C) Capture Register. CR 0 */ + __I uint32_t CR1; /*!< (@ 0x40018030) Capture Register. CR 1 */ + __I uint32_t CR2; /*!< (@ 0x40018034) Capture Register. CR 2 */ + __I uint32_t CR3; /*!< (@ 0x40018038) Capture Register. CR 3 */ + }; + }; +__IO uint32_t EMR; /*!< (@ 0x4001403C) External Match Register */ + __I uint32_t RESERVED0[12]; /*!< (@ 0x4001403C) Reserved */ + __IO uint32_t CTCR; /*!< (@ 0x40014070) Count Control Register */ + __IO uint32_t PWMC; /*!< (@ 0x40014074) PWM Control Register */ +} LPC_CTxxBx_Type; + + + +// ------------------------------------------------------------------------------------------------ +// ----- ADC ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x ADC Modification date=3/16/2011 Major revision=0 Minor revision=3 (ADC) + */ + +typedef struct { /*!< (@ 0x4001C000) ADC Structure */ + __IO uint32_t CR; /*!< (@ 0x4001C000) A/D Control Register */ + __IO uint32_t GDR; /*!< (@ 0x4001C004) A/D Global Data Register */ + __I uint32_t RESERVED0[1]; /*!< (@ 0x4001C008) Reserved */ + __IO uint32_t INTEN; /*!< (@ 0x4001C00C) A/D Interrupt Enable Register */ + union{ + __I uint32_t DR[8]; /*!< (@ 0x4001C010) A/D Channel Data Register*/ + struct{ + __IO uint32_t DR0; /*!< (@ 0x40020010) A/D Channel Data Register 0*/ + __IO uint32_t DR1; /*!< (@ 0x40020014) A/D Channel Data Register 1*/ + __IO uint32_t DR2; /*!< (@ 0x40020018) A/D Channel Data Register 2*/ + __IO uint32_t DR3; /*!< (@ 0x4002001C) A/D Channel Data Register 3*/ + __IO uint32_t DR4; /*!< (@ 0x40020020) A/D Channel Data Register 4*/ + __IO uint32_t DR5; /*!< (@ 0x40020024) A/D Channel Data Register 5*/ + __IO uint32_t DR6; /*!< (@ 0x40020028) A/D Channel Data Register 6*/ + __IO uint32_t DR7; /*!< (@ 0x4002002C) A/D Channel Data Register 7*/ + }; + }; + __I uint32_t STAT; /*!< (@ 0x4001C030) A/D Status Register. */ +} LPC_ADC_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- PMU ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x Power Management Unit (PMU) Modification date=3/16/2011 Major revision=0 Minor revision=3 (PMU) + */ + +typedef struct { /*!< (@ 0x40038000) PMU Structure */ + __IO uint32_t PCON; /*!< (@ 0x40038000) Power control register */ + union{ + __IO uint32_t GPREG[4]; /*!< (@ 0x40038004) General purpose register 0 */ + struct{ + __IO uint32_t GPREG0; /*!< (@ 0x40038004) General purpose register 0 */ + __IO uint32_t GPREG1; /*!< (@ 0x40038008) General purpose register 1 */ + __IO uint32_t GPREG2; /*!< (@ 0x4003800C) General purpose register 2 */ + __IO uint32_t GPREG3; /*!< (@ 0x40038010) General purpose register 3 */ + }; + }; +} LPC_PMU_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- FLASHCTRL ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x Flash programming firmware Modification date=3/17/2011 Major revision=0 Minor revision=3 (FLASHCTRL) + */ + +typedef struct { /*!< (@ 0x4003C000) FLASHCTRL Structure */ + __I uint32_t RESERVED0[4]; /*!< (@ 0x4003C000) Reserved */ + __IO uint32_t FLASHCFG; /*!< (@ 0x4003C010) Flash memory access time configuration register */ + __I uint32_t RESERVED1[3]; /*!< (@ 0x4003C014) Reserved */ + __IO uint32_t FMSSTART; /*!< (@ 0x4003C020) Signature start address register */ + __IO uint32_t FMSSTOP; /*!< (@ 0x4003C024) Signature stop-address register */ + __I uint32_t RESERVED2[1]; /*!< (@ 0x4003C028) Reserved */ + __I uint32_t FMSW0; /*!< (@ 0x4003C02C) Word 0 [31:0] */ + __I uint32_t FMSW1; /*!< (@ 0x4003C030) Word 1 [63:32] */ + __I uint32_t FMSW2; /*!< (@ 0x4003C034) Word 2 [95:64] */ + __I uint32_t FMSW3; /*!< (@ 0x4003C038) Word 3 [127:96] */ + __I uint32_t RESERVED3[1001]; /*!< (@ 0x4003C03C) Reserved */ + __I uint32_t FMSTAT; /*!< (@ 0x4003CFE0) Signature generation status register */ + __I uint32_t RESERVED4[1]; /*!< (@ 0x4003CFE4) Reserved */ + __IO uint32_t FMSTATCLR; /*!< (@ 0x4003CFE8) Signature generation status clear register */ +} LPC_FLASHCTRL_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- SSP0/1 ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x SSP/SPI Modification date=3/16/2011 Major revision=0 Minor revision=3 (SSP0) + */ + +typedef struct { /*!< (@ 0x40040000) SSP0 Structure */ + __IO uint32_t CR0; /*!< (@ 0x40040000) Control Register 0. Selects the serial clock rate, bus type, and data size. */ + __IO uint32_t CR1; /*!< (@ 0x40040004) Control Register 1. Selects master/slave and other modes. */ + __IO uint32_t DR; /*!< (@ 0x40040008) Data Register. Writes fill the transmit FIFO, and reads empty the receive FIFO. */ + __I uint32_t SR; /*!< (@ 0x4004000C) Status Register */ + __IO uint32_t CPSR; /*!< (@ 0x40040010) Clock Prescale Register */ + __IO uint32_t IMSC; /*!< (@ 0x40040014) Interrupt Mask Set and Clear Register */ + __I uint32_t RIS; /*!< (@ 0x40040018) Raw Interrupt Status Register */ + __I uint32_t MIS; /*!< (@ 0x4004001C) Masked Interrupt Status Register */ + __IO uint32_t ICR; /*!< (@ 0x40040020) SSPICR Interrupt Clear Register */ +} LPC_SSPx_Type; + + + +// ------------------------------------------------------------------------------------------------ +// ----- IOCONFIG ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x I/O configuration Modification date=3/16/2011 Major revision=0 Minor revision=3 (IOCONFIG) + */ + +typedef struct { /*!< (@ 0x40044000) IOCONFIG Structure */ + __IO uint32_t RESET_PIO0_0; /*!< (@ 0x40044000) I/O configuration for pin RESET/PIO0_0 */ + __IO uint32_t PIO0_1; /*!< (@ 0x40044004) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2/USB_FTOGGLE */ + __IO uint32_t PIO0_2; /*!< (@ 0x40044008) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */ + __IO uint32_t PIO0_3; /*!< (@ 0x4004400C) I/O configuration for pin PIO0_3/USB_VBUS */ + __IO uint32_t PIO0_4; /*!< (@ 0x40044010) I/O configuration for pin PIO0_4/SCL */ + __IO uint32_t PIO0_5; /*!< (@ 0x40044014) I/O configuration for pin PIO0_5/SDA */ + __IO uint32_t PIO0_6; /*!< (@ 0x40044018) I/O configuration for pin PIO0_6/USB_CONNECT/SCK0 */ + __IO uint32_t PIO0_7; /*!< (@ 0x4004401C) I/O configuration for pin PIO0_7/CTS */ + __IO uint32_t PIO0_8; /*!< (@ 0x40044020) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */ + __IO uint32_t PIO0_9; /*!< (@ 0x40044024) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */ + __IO uint32_t SWCLK_PIO0_10; /*!< (@ 0x40044028) I/O configuration for pin SWCLK/PIO0_10/ SCK0/CT16B0_MAT2 */ + __IO uint32_t TDI_PIO0_11; /*!< (@ 0x4004402C) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */ + __IO uint32_t TMS_PIO0_12; /*!< (@ 0x40044030) I/O configuration for pin TMS/PIO0_12/AD1/CT32B1_CAP0 */ + __IO uint32_t TDO_PIO0_13; /*!< (@ 0x40044034) I/O configuration for pin TDO/PIO0_13/AD2/CT32B1_MAT0 */ + __IO uint32_t TRST_PIO0_14; /*!< (@ 0x40044038) I/O configuration for pin TRST/PIO0_14/AD3/CT32B1_MAT1 */ + __IO uint32_t SWDIO_PIO0_15; /*!< (@ 0x4004403C) I/O configuration for pin SWDIO/PIO0_15/AD4/CT32B1_MAT2 */ + __IO uint32_t PIO0_16; /*!< (@ 0x40044040) I/O configuration for pin PIO0_16/AD5/CT32B1_MAT3/ WAKEUP */ + __IO uint32_t PIO0_17; /*!< (@ 0x40044044) I/O configuration for pin PIO0_17/RTS/CT32B0_CAP0/SCLK */ + __IO uint32_t PIO0_18; /*!< (@ 0x40044048) I/O configuration for pin PIO0_18/RXD/CT32B0_MAT0 */ + __IO uint32_t PIO0_19; /*!< (@ 0x4004404C) I/O configuration for pin PIO0_19/TXD/CT32B0_MAT1 */ + __IO uint32_t PIO0_20; /*!< (@ 0x40044050) I/O configuration for pin PIO0_20/CT16B1_CAP0 */ + __IO uint32_t PIO0_21; /*!< (@ 0x40044054) I/O configuration for pin PIO0_21/CT16B1_MAT0/MOSI1 */ + __IO uint32_t PIO0_22; /*!< (@ 0x40044058) I/O configuration for pin PIO0_22/AD6/CT16B1_MAT1/MISO1 */ + __IO uint32_t PIO0_23; /*!< (@ 0x4004405C) I/O configuration for pin PIO0_23/AD7 */ + __IO uint32_t PIO1_0; /*!< (@ 0x40044060) I/O configuration for pin PIO1_0 */ + __IO uint32_t PIO1_1; /*!< (@ 0x40044064) I/O configuration for pin PIO1_1 */ + __IO uint32_t PIO1_2; /*!< (@ 0x40044068) I/O configuration for pin PIO1_2 */ + __IO uint32_t PIO1_3; /*!< (@ 0x4004406C) I/O configuration for pin PIO1_3 */ + __IO uint32_t PIO1_4; /*!< (@ 0x40044070) I/O configuration for pin PIO1_4 */ + __IO uint32_t PIO1_5; /*!< (@ 0x40044074) I/O configuration for pin PIO1_5 */ + __IO uint32_t PIO1_6; /*!< (@ 0x40044078) I/O configuration for pin PIO1_6 */ + __IO uint32_t PIO1_7; /*!< (@ 0x4004407C) I/O configuration for pin PIO1_7 */ + __IO uint32_t PIO1_8; /*!< (@ 0x40044080) I/O configuration for pin PIO1_8 */ + __IO uint32_t PIO1_9; /*!< (@ 0x40044084) I/O configuration for pin PIO1_9 */ + __IO uint32_t PIO1_10; /*!< (@ 0x40044088) I/O configuration for pin PIO1_10 */ + __IO uint32_t PIO1_11; /*!< (@ 0x4004408C) I/O configuration for pin PIO1_11 */ + __IO uint32_t PIO1_12; /*!< (@ 0x40044090) I/O configuration for pin PIO1_12 */ + __IO uint32_t PIO1_13; /*!< (@ 0x40044094) I/O configuration for pin PIO1_13/DTR/CT16B0_MAT0/TXD */ + __IO uint32_t PIO1_14; /*!< (@ 0x40044098) I/O configuration for pin PIO1_14/DSR/CT16B0_MAT1/RXD */ + __IO uint32_t PIO1_15; /*!< (@ 0x4004409C) I/O configuration for pin PIO1_15/DCD/ CT16B0_MAT2/SCK1 */ + __IO uint32_t PIO1_16; /*!< (@ 0x400440A0) I/O configuration for pin PIO1_16/RI/CT16B0_CAP0 */ + __IO uint32_t PIO1_17; /*!< (@ 0x4004405C) I/O configuration for pin PIO0_23/AD7 */ + __IO uint32_t PIO1_18; /*!< (@ 0x4004405C) I/O configuration for pin PIO0_23/AD7 */ + __IO uint32_t PIO1_19; /*!< (@ 0x400440AC) I/O configuration for pin PIO1_19/DTR/SSEL1 */ + __IO uint32_t PIO1_20; /*!< (@ 0x400440B0) I/O configuration for pin PIO1_20/DSR/SCK1 */ + __IO uint32_t PIO1_21; /*!< (@ 0x400440B4) I/O configuration for pin PIO1_21/DCD/MISO1 */ + __IO uint32_t PIO1_22; /*!< (@ 0x400440B8) I/O configuration for pin PIO1_22/RI/MOSI1 */ + __IO uint32_t PIO1_23; /*!< (@ 0x400440BC) I/O configuration for pin PIO1_23/CT16B1_MAT1/SSEL1 */ + __IO uint32_t PIO1_24; /*!< (@ 0x400440C0) I/O configuration for pin PIO1_24/ CT32B0_MAT0 */ + __IO uint32_t PIO1_25; /*!< (@ 0x400440C4) I/O configuration for pin PIO1_25/CT32B0_MAT1 */ + __IO uint32_t PIO1_26; /*!< (@ 0x400440C8) I/O configuration for pin PIO1_26/CT32B0_MAT2/ RXD */ + __IO uint32_t PIO1_27; /*!< (@ 0x400440CC) I/O configuration for pin PIO1_27/CT32B0_MAT3/ TXD */ + __IO uint32_t PIO1_28; /*!< (@ 0x400440D0) I/O configuration for pin PIO1_28/CT32B0_CAP0/ SCLK */ + __IO uint32_t PIO1_29; /*!< (@ 0x400440D4) I/O configuration for pin PIO1_29/SCK0/ CT32B0_CAP1 */ + __IO uint32_t PIO1_30; /*!< (@ 0x400440D8) I/O configuration for pin PIO1_30 */ + __IO uint32_t PIO1_31; /*!< (@ 0x400440DC) I/O configuration for pin PIO1_31 */ +} LPC_IOCON_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- SYSCON ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x System control block Modification date=3/16/2011 Major revision=0 Minor revision=3 (SYSCON) + */ + +typedef struct { /*!< (@ 0x40048000) SYSCON Structure */ + __IO uint32_t SYSMEMREMAP; /*!< (@ 0x40048000) System memory remap */ + __IO uint32_t PRESETCTRL; /*!< (@ 0x40048004) Peripheral reset control */ + __IO uint32_t SYSPLLCTRL; /*!< (@ 0x40048008) System PLL control */ + __I uint32_t SYSPLLSTAT; /*!< (@ 0x4004800C) System PLL status */ + __IO uint32_t USBPLLCTRL; /*!< (@ 0x40048010) USB PLL control */ + __I uint32_t USBPLLSTAT; /*!< (@ 0x40048014) USB PLL status */ + __I uint32_t RESERVED0[2]; /*!< (@ 0x40048018) Reserved */ + __IO uint32_t SYSOSCCTRL; /*!< (@ 0x40048020) System oscillator control */ + __IO uint32_t WDTOSCCTRL; /*!< (@ 0x40048024) Watchdog oscillator control */ + __I uint32_t RESERVED1[2]; /*!< (@ 0x40048028) Reserved */ + __IO uint32_t SYSRSTSTAT; /*!< (@ 0x40048030) System reset status register */ + __I uint32_t RESERVED2[3]; /*!< (@ 0x40048034) Reserved */ + __IO uint32_t SYSPLLCLKSEL; /*!< (@ 0x40048040) System PLL clock source select */ + __IO uint32_t SYSPLLCLKUEN; /*!< (@ 0x40048044) System PLL clock source update enable */ + __IO uint32_t USBPLLCLKSEL; /*!< (@ 0x40048048) USB PLL clock source select */ + __IO uint32_t USBPLLCLKUEN; /*!< (@ 0x4004804C) USB PLL clock source update enable */ + __I uint32_t RESERVED3[8]; /*!< (@ 0x40048050) Reserved */ + __IO uint32_t MAINCLKSEL; /*!< (@ 0x40048070) Main clock source select */ + __IO uint32_t MAINCLKUEN; /*!< (@ 0x40048074) Main clock source update enable */ + __IO uint32_t SYSAHBCLKDIV; /*!< (@ 0x40048078) System clock divider */ + __I uint32_t RESERVED4[1]; /*!< (@ 0x4004807C) Reserved */ + __IO uint32_t SYSAHBCLKCTRL; /*!< (@ 0x40048080) System clock control */ + __I uint32_t RESERVED5[4]; /*!< (@ 0x40048084) Reserved */ + __IO uint32_t SSP0CLKDIV; /*!< (@ 0x40048094) SSP0 clock divider */ + __IO uint32_t UARTCLKDIV; /*!< (@ 0x40048098) UART clock divider */ + __IO uint32_t SSP1CLKDIV; /*!< (@ 0x4004809C) SSP1 clock divider */ + __I uint32_t RESERVED6[8]; /*!< (@ 0x400480A0) Reserved */ + __IO uint32_t USBCLKSEL; /*!< (@ 0x400480C0) USB clock source select */ + __IO uint32_t USBCLKUEN; /*!< (@ 0x400480C4) USB clock source update enable */ + __IO uint32_t USBCLKDIV; /*!< (@ 0x400480C8) USB clock source divider */ + __I uint32_t RESERVED7[5]; /*!< (@ 0x400480CC) Reserved */ + __IO uint32_t CLKOUTSEL; /*!< (@ 0x400480E0) CLKOUT clock source select */ + __IO uint32_t CLKOUTUEN; /*!< (@ 0x400480E4) CLKOUT clock source update enable */ + __IO uint32_t CLKOUTDIV; /*!< (@ 0x400480E8) CLKOUT clock divider */ + __I uint32_t RESERVED8[5]; /*!< (@ 0x400480EC) Reserved */ + __I uint32_t PIOPORCAP0; /*!< (@ 0x40048100) POR captured PIO status 0 */ + __I uint32_t PIOPORCAP1; /*!< (@ 0x40048104) POR captured PIO status 1 */ + __I uint32_t RESERVED9[18]; /*!< (@ 0x40048108) Reserved */ + __IO uint32_t BODCTRL; /*!< (@ 0x40048150) Brown-Out Detect */ + __IO uint32_t SYSTCKCAL; /*!< (@ 0x40048154) System tick counter calibration */ + __I uint32_t RESERVED10[6]; /*!< (@ 0x40048158) Reserved */ + __IO uint32_t IRQLATENCY; /*!< (@ 0x40048170) IQR delay */ + __IO uint32_t NMISRC; /*!< (@ 0x40048174) NMI Source Control */ + __IO uint32_t PINTSEL[8]; /*!< (@ 0x40048178) GPIO Pin Interrupt Select register 0 */ + __IO uint32_t USBCLKCTRL; /*!< (@ 0x40048198) USB clock control */ + __I uint32_t USBCLKST; /*!< (@ 0x4004819C) USB clock status */ + __I uint32_t RESERVED11[25]; /*!< (@ 0x400481A0) Reserved */ + __IO uint32_t STARTERP0; /*!< (@ 0x40048204) Start logic 0 interrupt wake-up enable register 0 */ + __I uint32_t RESERVED12[3]; /*!< (@ 0x40048208) Reserved */ + __IO uint32_t STARTERP1; /*!< (@ 0x40048214) Start logic 1 interrupt wake-up enable register 1 */ + __I uint32_t RESERVED13[6]; /*!< (@ 0x40048218) Reserved */ + __IO uint32_t PDSLEEPCFG; /*!< (@ 0x40048230) Power-down states in deep-sleep mode */ + __IO uint32_t PDAWAKECFG; /*!< (@ 0x40048234) Power-down states for wake-up from deep-sleep */ + __IO uint32_t PDRUNCFG; /*!< (@ 0x40048238) Power configuration register */ + __I uint32_t RESERVED14[110]; /*!< (@ 0x4004823C) Reserved */ + __I uint32_t DEVICE_ID; /*!< (@ 0x400483F4) Device ID */ +} LPC_SYSCON_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- GPIO_PIN_INT ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_PIN_INT) + */ + +typedef struct { /*!< (@ 0x4004C000) GPIO_PIN_INT Structure */ + __IO uint32_t ISEL; /*!< (@ 0x4004C000) Pin Interrupt Mode register */ + __IO uint32_t IENR; /*!< (@ 0x4004C004) Pin Interrupt Enable (Rising) register */ + __IO uint32_t SIENR; /*!< (@ 0x4004C008) Set Pin Interrupt Enable (Rising) register */ + __IO uint32_t CIENR; /*!< (@ 0x4004C00C) Clear Pin Interrupt Enable (Rising) register */ + __IO uint32_t IENF; /*!< (@ 0x4004C010) Pin Interrupt Enable Falling Edge / Active Level register */ + __IO uint32_t SIENF; /*!< (@ 0x4004C014) Set Pin Interrupt Enable Falling Edge / Active Level register */ + __IO uint32_t CIENF; /*!< (@ 0x4004C018) Clear Pin Interrupt Enable Falling Edge / Active Level address */ + __IO uint32_t RISE; /*!< (@ 0x4004C01C) Pin Interrupt Rising Edge register */ + __IO uint32_t FALL; /*!< (@ 0x4004C020) Pin Interrupt Falling Edge register */ + __IO uint32_t IST; /*!< (@ 0x4004C024) Pin Interrupt Status register */ +} LPC_GPIO_PIN_INT_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- GPIO_GROUP_INT0/1 ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_GROUP_INT0) + */ + +typedef struct { /*!< (@ 0x4005C000) GPIO_GROUP_INT0 Structure */ + __IO uint32_t CTRL; /*!< (@ 0x4005C000) GPIO grouped interrupt control register */ + __I uint32_t RESERVED0[7]; /*!< (@ 0x4005C004) Reserved */ + __IO uint32_t PORT_POL[2]; /*!< (@ 0x4005C020) GPIO grouped interrupt port 0 polarity register */ + __I uint32_t RESERVED1[6]; /*!< (@ 0x4005C02C) Reserved */ + __IO uint32_t PORT_ENA[2]; /*!< (@ 0x4005C040) GPIO grouped interrupt port 0/1 enable register */ +} LPC_GPIO_GROUP_INTx_Type; + + + +// ------------------------------------------------------------------------------------------------ +// ----- USB ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x USB2.0device controller Modification date=3/16/2011 Major revision=0 Minor revision=3 (USB) + */ + +typedef struct { /*!< (@ 0x40080000) USB Structure */ + __IO uint32_t DEVCMDSTAT; /*!< (@ 0x40080000) USB Device Command/Status register */ + __IO uint32_t INFO; /*!< (@ 0x40080004) USB Info register */ + __IO uint32_t EPLISTSTART; /*!< (@ 0x40080008) USB EP Command/Status List start address */ + __IO uint32_t DATABUFSTART; /*!< (@ 0x4008000C) USB Data buffer start address */ + __IO uint32_t LPM; /*!< (@ 0x40080010) Link Power Management register */ + __IO uint32_t EPSKIP; /*!< (@ 0x40080014) USB Endpoint skip */ + __IO uint32_t EPINUSE; /*!< (@ 0x40080018) USB Endpoint Buffer in use */ + __IO uint32_t EPBUFCFG; /*!< (@ 0x4008001C) USB Endpoint Buffer Configuration register */ + __IO uint32_t INTSTAT; /*!< (@ 0x40080020) USB interrupt status register */ + __IO uint32_t INTEN; /*!< (@ 0x40080024) USB interrupt enable register */ + __IO uint32_t INTSETSTAT; /*!< (@ 0x40080028) USB set interrupt status register */ + __IO uint32_t INTROUTING; /*!< (@ 0x4008002C) USB interrupt routing register */ + __I uint32_t RESERVED0[1]; /*!< (@ 0x40080030) Reserved */ + __I uint32_t EPTOGGLE; /*!< (@ 0x40080034) USB Endpoint toggle register */ +} LPC_USB_Type; + + +// ------------------------------------------------------------------------------------------------ +// ----- GPIO_PORT ----- +// ------------------------------------------------------------------------------------------------ + + +/** + * @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_PORT) + */ + +typedef struct { + union { + struct { + __IO uint8_t B0[32]; /*!< (@ 0x50000000) Byte pin registers port 0; pins PIO0_0 to PIO0_31 */ + __IO uint8_t B1[32]; /*!< (@ 0x50000020) Byte pin registers port 1 */ + }; + __IO uint8_t B[64]; /*!< (@ 0x50000000) Byte pin registers port 0/1 */ + }; + __I uint32_t RESERVED0[1008]; /*!< (@ 0x50000040) Reserved */ + union { + struct { + __IO uint32_t W0[32]; /*!< (@ 0x50001000) Word pin registers port 0 */ + __IO uint32_t W1[32]; /*!< (@ 0x50001080) Word pin registers port 1 */ + }; + __IO uint32_t W[64]; /*!< (@ 0x50001000) Word pin registers port 0/1 */ + }; + uint32_t RESERVED1[960]; /*!< (@ 0x50001100) Reserved */ + __IO uint32_t DIR[2]; /*!< 0x2000 */ + uint32_t RESERVED2[30]; /*!< Reserved */ + __IO uint32_t MASK[2]; /*!< 0x2080 */ + uint32_t RESERVED3[30]; /*!< Reserved */ + __IO uint32_t PIN[2]; /*!< 0x2100 */ + uint32_t RESERVED4[30]; /*!< Reserved */ + __IO uint32_t MPIN[2]; /*!< 0x2180 */ + uint32_t RESERVED5[30]; /*!< Reserved */ + __IO uint32_t SET[2]; /*!< 0x2200 */ + uint32_t RESERVED6[30]; /*!< Reserved */ + __O uint32_t CLR[2]; /*!< 0x2280 */ + uint32_t RESERVED7[30]; /*!< Reserved */ + __O uint32_t NOT[2]; /*!< 0x2300 */ +} LPC_GPIO_Type; + + +#if defined ( __CC_ARM ) + #pragma no_anon_unions +#endif + +/** + * @brief Memory map definition for the peripherals + * @{ + */ +#define LPC_I2C_BASE (0x40000000) +#define LPC_WWDT_BASE (0x40004000) +#define LPC_USART_BASE (0x40008000) +#define LPC_CT16B0_BASE (0x4000C000) +#define LPC_CT16B1_BASE (0x40010000) +#define LPC_CT32B0_BASE (0x40014000) +#define LPC_CT32B1_BASE (0x40018000) +#define LPC_ADC_BASE (0x4001C000) +#define LPC_PMU_BASE (0x40038000) +#define LPC_FLASHCTRL_BASE (0x4003C000) +#define LPC_SSP0_BASE (0x40040000) +#define LPC_SSP1_BASE (0x40058000) +#define LPC_IOCON_BASE (0x40044000) +#define LPC_SYSCON_BASE (0x40048000) +#define LPC_GPIO_PIN_INT_BASE (0x4004C000) +#define LPC_GPIO_GROUP_INT0_BASE (0x4005C000) +#define LPC_GPIO_GROUP_INT1_BASE (0x40060000) +#define LPC_USB_BASE (0x40080000) +#define LPC_GPIO_BASE (0x50000000) +/* @} */ + +/** + * @brief Peripheral declaration + * @{ + */ +#define LPC_I2C ((LPC_I2C_Type *) LPC_I2C_BASE) +#define LPC_WWDT ((LPC_WWDT_Type *) LPC_WWDT_BASE) +#define LPC_USART ((LPC_USART_Type *) LPC_USART_BASE) +#define LPC_CT16B0 ((LPC_CTxxBx_Type *) LPC_CT16B0_BASE) +#define LPC_CT16B1 ((LPC_CTxxBx_Type *) LPC_CT16B1_BASE) +#define LPC_CT32B0 ((LPC_CTxxBx_Type *) LPC_CT32B0_BASE) +#define LPC_CT32B1 ((LPC_CTxxBx_Type *) LPC_CT32B1_BASE) +#define LPC_ADC ((LPC_ADC_Type *) LPC_ADC_BASE) +#define LPC_PMU ((LPC_PMU_Type *) LPC_PMU_BASE) +#define LPC_FLASHCTRL ((LPC_FLASHCTRL_Type *) LPC_FLASHCTRL_BASE) +#define LPC_SSP0 ((LPC_SSPx_Type *) LPC_SSP0_BASE) +#define LPC_SSP1 ((LPC_SSPx_Type *) LPC_SSP1_BASE) +#define LPC_IOCON ((LPC_IOCON_Type *) LPC_IOCON_BASE) +#define LPC_SYSCON ((LPC_SYSCON_Type *) LPC_SYSCON_BASE) +#define LPC_GPIO_PIN_INT ((LPC_GPIO_PIN_INT_Type *) LPC_GPIO_PIN_INT_BASE) +#define LPC_GPIO_GROUP_INT0 ((LPC_GPIO_GROUP_INTx_Type*) LPC_GPIO_GROUP_INT0_BASE) +#define LPC_GPIO_GROUP_INT1 ((LPC_GPIO_GROUP_INTx_Type*) LPC_GPIO_GROUP_INT1_BASE) +#define LPC_USB ((LPC_USB_Type *) LPC_USB_BASE) +#define LPC_GPIO ((LPC_GPIO_Type *) LPC_GPIO_BASE) +/* @} */ + +/** @} */ /* End of group Device_Peripheral_Registers */ +/** @} */ /* End of group (null) */ +/** @} */ /* End of group LPC11Uxx */ + +#ifdef __cplusplus +} +#endif + + +#endif // __LPC11UXX_H__ +/** @} */ diff --git a/cpu/lpc11u34/include/cpu_conf.h b/cpu/lpc11u34/include/cpu_conf.h new file mode 100644 index 0000000000..e5a276b0c0 --- /dev/null +++ b/cpu/lpc11u34/include/cpu_conf.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @defgroup cpu_lpc11u34 NXP LPC11U34 + * @ingroup cpu + * @brief CPU specific implementations for the NXP LPC11U34 cpu + * @{ + * + * @file + * @brief CPU specific configuration options + * + * @author Paul RATHGEB + */ + +#ifndef __CPU_CONF_H +#define __CPU_CONF_H + +#include "LPC11Uxx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ARM Cortex-M specific CPU configuration + * @{ + */ +#define CPU_DEFAULT_IRQ_PRIO (1U) +#define CPU_IRQ_NUMOF (35U) +#define CPU_FLASH_BASE LPC_FLASH_BASE +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CPU_CONF_H */ +/** @} */ diff --git a/cpu/lpc11u34/include/periph_cpu.h b/cpu/lpc11u34/include/periph_cpu.h new file mode 100644 index 0000000000..b7ceae00ed --- /dev/null +++ b/cpu/lpc11u34/include/periph_cpu.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author Paul RATHGEB + */ + +#ifndef PERIPH_CPU_H_ +#define PERIPH_CPU_H_ + +#include "periph/dev_enums.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* nothing to do here, yet */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CPU_H_ */ +/** @} */ diff --git a/cpu/lpc11u34/ldscripts/lpc11u34.ld b/cpu/lpc11u34/ldscripts/lpc11u34.ld new file mode 100644 index 0000000000..9d46224a20 --- /dev/null +++ b/cpu/lpc11u34/ldscripts/lpc11u34.ld @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Memory definitions for the LPC11U34 + * + * @author Paul RATHGEB + * + * @} + */ + +MEMORY +{ + rom (rx) : ORIGIN = 0x0, LENGTH = 0xc000 /* 48K bytes */ + ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x2000 /* 8K bytes */ + usb_ram (rwx) : ORIGIN = 0x20004000, LENGTH = 0x800 /* 2K bytes */ +} + +INCLUDE cortexm_base.ld diff --git a/cpu/lpc11u34/lpm_arch.c b/cpu/lpc11u34/lpm_arch.c new file mode 100644 index 0000000000..85a6c0546b --- /dev/null +++ b/cpu/lpc11u34/lpm_arch.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Implementation of the kernels power management interface + * + * @author Paul RATHGEB + * + * @} + */ + +#include "cpu.h" +#include "arch/lpm_arch.h" + +void lpm_arch_init(void) +{ + /* TODO */ +} + +enum lpm_mode lpm_arch_set(enum lpm_mode target) +{ + /* TODO */ + return 0; +} + +enum lpm_mode lpm_arch_get(void) +{ + /* TODO */ + return 0; +} + +void lpm_arch_awake(void) +{ + /* TODO*/ +} + +void lpm_arch_begin_awake(void) +{ + /* TODO */ +} + +void lpm_arch_end_awake(void) +{ + /* TODO */ +} diff --git a/cpu/lpc11u34/periph/Makefile b/cpu/lpc11u34/periph/Makefile new file mode 100644 index 0000000000..6d1887b640 --- /dev/null +++ b/cpu/lpc11u34/periph/Makefile @@ -0,0 +1,3 @@ +MODULE = periph + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/lpc11u34/periph/gpio.c b/cpu/lpc11u34/periph/gpio.c new file mode 100644 index 0000000000..779720fab1 --- /dev/null +++ b/cpu/lpc11u34/periph/gpio.c @@ -0,0 +1,501 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Low-level GPIO driver implementation + * + * @author Paul RATHGEB + * + * @} + */ + +#include "cpu.h" +#include "thread.h" +#include "periph/gpio.h" + +typedef struct { + gpio_cb_t cb; + void *arg; +} gpio_state_t; + +/* Static IOCON registers definition */ +volatile uint32_t * const lpc_pin_registersS[] = { + /* PORT 0 (PIO0_0 -> PIO0_23) */ + &LPC_IOCON->RESET_PIO0_0, &LPC_IOCON->PIO0_1, + &LPC_IOCON->PIO0_2, &LPC_IOCON->PIO0_3, + &LPC_IOCON->PIO0_4, &LPC_IOCON->PIO0_5, + &LPC_IOCON->PIO0_6, &LPC_IOCON->PIO0_7, + &LPC_IOCON->PIO0_8, &LPC_IOCON->PIO0_9, + &LPC_IOCON->SWCLK_PIO0_10, &LPC_IOCON->TDI_PIO0_11, + &LPC_IOCON->TMS_PIO0_12, &LPC_IOCON->TDO_PIO0_13, + &LPC_IOCON->TRST_PIO0_14, &LPC_IOCON->SWDIO_PIO0_15, + &LPC_IOCON->PIO0_16, &LPC_IOCON->PIO0_17, + &LPC_IOCON->PIO0_18, &LPC_IOCON->PIO0_19, + &LPC_IOCON->PIO0_20, &LPC_IOCON->PIO0_21, + &LPC_IOCON->PIO0_22, &LPC_IOCON->PIO0_23, + /* PORT 1 (PIO1_0 -> PIO0_31) */ + &LPC_IOCON->PIO1_0, &LPC_IOCON->PIO1_1, + &LPC_IOCON->PIO1_2, &LPC_IOCON->PIO1_3, + &LPC_IOCON->PIO1_4, &LPC_IOCON->PIO1_5, + &LPC_IOCON->PIO1_6, &LPC_IOCON->PIO1_7, + &LPC_IOCON->PIO1_8, &LPC_IOCON->PIO1_9, + &LPC_IOCON->PIO1_10, &LPC_IOCON->PIO1_11, + &LPC_IOCON->PIO1_12, &LPC_IOCON->PIO1_13, + &LPC_IOCON->PIO1_14, &LPC_IOCON->PIO1_15, + &LPC_IOCON->PIO1_16, &LPC_IOCON->PIO1_17, + &LPC_IOCON->PIO1_18, &LPC_IOCON->PIO1_19, + &LPC_IOCON->PIO1_20, &LPC_IOCON->PIO1_21, + &LPC_IOCON->PIO1_22, &LPC_IOCON->PIO1_23, + &LPC_IOCON->PIO1_24, &LPC_IOCON->PIO1_25, + &LPC_IOCON->PIO1_26, &LPC_IOCON->PIO1_27, + &LPC_IOCON->PIO1_28, &LPC_IOCON->PIO1_29, + &LPC_IOCON->PIO1_30, &LPC_IOCON->PIO1_31, +}; + +static int8_t flex_int_mapping[GPIO_NUMOF]; + +static gpio_state_t gpio_config[GPIO_NUMOF]; +static uint8_t gpio_int_id = 0; + +/* static port mappings */ +static const uint8_t gpio_port_map[GPIO_NUMOF] = { +#if GPIO_0_EN + [GPIO_0] = GPIO_0_PORT, +#endif +#if GPIO_1_EN + [GPIO_1] = GPIO_1_PORT, +#endif +#if GPIO_2_EN + [GPIO_2] = GPIO_2_PORT, +#endif +#if GPIO_3_EN + [GPIO_3] = GPIO_3_PORT, +#endif +#if GPIO_4_EN + [GPIO_4] = GPIO_4_PORT, +#endif +#if GPIO_5_EN + [GPIO_5] = GPIO_5_PORT, +#endif +#if GPIO_6_EN + [GPIO_6] = GPIO_6_PORT, +#endif +#if GPIO_7_EN + [GPIO_7] = GPIO_7_PORT, +#endif +#if GPIO_8_EN + [GPIO_8] = GPIO_8_PORT, +#endif +#if GPIO_9_EN + [GPIO_9] = GPIO_9_PORT, +#endif +#if GPIO_10_EN + [GPIO_10] = GPIO_10_PORT, +#endif +#if GPIO_11_EN + [GPIO_11] = GPIO_11_PORT, +#endif +#if GPIO_12_EN + [GPIO_12] = GPIO_12_PORT, +#endif +#if GPIO_13_EN + [GPIO_13] = GPIO_13_PORT, +#endif +#if GPIO_14_EN + [GPIO_14] = GPIO_14_PORT, +#endif +#if GPIO_15_EN + [GPIO_15] = GPIO_15_PORT, +#endif +#if GPIO_16_EN + [GPIO_16] = GPIO_16_PORT, +#endif +#if GPIO_17_EN + [GPIO_17] = GPIO_17_PORT, +#endif +#if GPIO_18_EN + [GPIO_18] = GPIO_18_PORT, +#endif +#if GPIO_19_EN + [GPIO_19] = GPIO_19_PORT, +#endif +#if GPIO_20_EN + [GPIO_20] = GPIO_20_PORT, +#endif +#if GPIO_21_EN + [GPIO_21] = GPIO_21_PORT, +#endif +#if GPIO_22_EN + [GPIO_22] = GPIO_22_PORT, +#endif +#if GPIO_23_EN + [GPIO_23] = GPIO_23_PORT, +#endif +#if GPIO_24_EN + [GPIO_24] = GPIO_24_PORT, +#endif +#if GPIO_25_EN + [GPIO_25] = GPIO_25_PORT, +#endif +#if GPIO_26_EN + [GPIO_26] = GPIO_26_PORT, +#endif +#if GPIO_27_EN + [GPIO_27] = GPIO_27_PORT, +#endif +#if GPIO_28_EN + [GPIO_28] = GPIO_28_PORT, +#endif +#if GPIO_29_EN + [GPIO_29] = GPIO_29_PORT, +#endif +#if GPIO_30_EN + [GPIO_30] = GPIO_30_PORT, +#endif +#if GPIO_31_EN + [GPIO_31] = GPIO_31_PORT, +#endif +}; + +/* static pin mappings */ +static const uint8_t gpio_pin_map[GPIO_NUMOF] = { +#if GPIO_0_EN + [GPIO_0] = GPIO_0_PIN, +#endif +#if GPIO_1_EN + [GPIO_1] = GPIO_1_PIN, +#endif +#if GPIO_2_EN + [GPIO_2] = GPIO_2_PIN, +#endif +#if GPIO_3_EN + [GPIO_3] = GPIO_3_PIN, +#endif +#if GPIO_4_EN + [GPIO_4] = GPIO_4_PIN, +#endif +#if GPIO_5_EN + [GPIO_5] = GPIO_5_PIN, +#endif +#if GPIO_6_EN + [GPIO_6] = GPIO_6_PIN, +#endif +#if GPIO_7_EN + [GPIO_7] = GPIO_7_PIN, +#endif +#if GPIO_8_EN + [GPIO_8] = GPIO_8_PIN, +#endif +#if GPIO_9_EN + [GPIO_9] = GPIO_9_PIN, +#endif +#if GPIO_10_EN + [GPIO_10] = GPIO_10_PIN, +#endif +#if GPIO_11_EN + [GPIO_11] = GPIO_11_PIN, +#endif +#if GPIO_12_EN + [GPIO_12] = GPIO_12_PIN, +#endif +#if GPIO_13_EN + [GPIO_13] = GPIO_13_PIN, +#endif +#if GPIO_14_EN + [GPIO_14] = GPIO_14_PIN, +#endif +#if GPIO_15_EN + [GPIO_15] = GPIO_15_PIN, +#endif +#if GPIO_16_EN + [GPIO_16] = GPIO_16_PIN, +#endif +#if GPIO_17_EN + [GPIO_17] = GPIO_17_PIN, +#endif +#if GPIO_18_EN + [GPIO_18] = GPIO_18_PIN, +#endif +#if GPIO_19_EN + [GPIO_19] = GPIO_19_PIN, +#endif +#if GPIO_20_EN + [GPIO_20] = GPIO_20_PIN, +#endif +#if GPIO_21_EN + [GPIO_21] = GPIO_21_PIN, +#endif +#if GPIO_22_EN + [GPIO_22] = GPIO_22_PIN, +#endif +#if GPIO_23_EN + [GPIO_23] = GPIO_23_PIN, +#endif +#if GPIO_24_EN + [GPIO_24] = GPIO_24_PIN, +#endif +#if GPIO_25_EN + [GPIO_25] = GPIO_25_PIN, +#endif +#if GPIO_26_EN + [GPIO_26] = GPIO_26_PIN, +#endif +#if GPIO_27_EN + [GPIO_27] = GPIO_27_PIN, +#endif +#if GPIO_28_EN + [GPIO_28] = GPIO_28_PIN, +#endif +#if GPIO_29_EN + [GPIO_29] = GPIO_29_PIN, +#endif +#if GPIO_30_EN + [GPIO_30] = GPIO_30_PIN, +#endif +#if GPIO_31_EN + [GPIO_31] = GPIO_31_PIN, +#endif +}; + +int gpio_init(gpio_t dev, gpio_dir_t dir, gpio_pp_t pullup) +{ + uint8_t port; + uint8_t pin; + + if (dev >= GPIO_NUMOF) { + return -1; + } + + /* Get the port and pin values */ + port = gpio_port_map[dev]; + pin = gpio_pin_map[dev]; + + /* Put pin in the primary function */ + *lpc_pin_registersS[pin + (port * 24)] = *lpc_pin_registersS[pin + (port * 24)] & ~(0x07); + + /* Disable resistors */ + *lpc_pin_registersS[pin + (port * 24)] &= ~(3 << 3); + /* Set resistors */ + if (pullup == GPIO_PULLUP) { + *lpc_pin_registersS[pin + (port * 24)] |= (2 << 3); + } + else if (pullup == GPIO_PULLDOWN) { + *lpc_pin_registersS[pin + (port * 24)] |= (1 << 3); + } + + /* Set direction */ + if (dir == GPIO_DIR_OUT) { + LPC_GPIO->DIR[port] |= (1 << pin); /* set pin to output mode */ + } + else { + LPC_GPIO->DIR[port] &= ~(1 << pin); /* set pin to output mode */ + } + + return 0; /* all OK */ +} + +int gpio_init_int(gpio_t dev, gpio_pp_t pullup, gpio_flank_t flank, gpio_cb_t cb, void *arg) +{ + int res; + uint8_t pin; + uint8_t port; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 19); + + if (dev >= GPIO_NUMOF) { + return -1; + } + + if (gpio_int_id > 7) { + return -1; + } + + port = gpio_port_map[dev]; + pin = gpio_pin_map[dev]; + + /* configure pin as input */ + res = gpio_init(dev, GPIO_DIR_IN, pullup); + if (res < 0) { + return res; + } + + /* Disable interrupts */ + NVIC_DisableIRQ(gpio_int_id); + /* Register pin as flex interrupt */ + LPC_SYSCON->PINTSEL[gpio_int_id] = (port * 24) + pin; + + /* set callback */ + gpio_config[gpio_int_id].cb = cb; + gpio_config[gpio_int_id].arg = arg; + + /* configure the event that triggers an interrupt */ + switch (flank) { + case GPIO_RISING: + LPC_GPIO_PIN_INT->ISEL &= ~(1 << gpio_int_id); /* Set PMODE=edge sensitive */ + LPC_GPIO_PIN_INT->IENR |= (1 << gpio_int_id); /* Enable rising edge. */ + LPC_GPIO_PIN_INT->IENF &= ~(1 << gpio_int_id); /* Disable falling edge. */ + break; + case GPIO_FALLING: + LPC_GPIO_PIN_INT->ISEL &= ~(1 << gpio_int_id); /* Set PMODE=edge sensitive */ + LPC_GPIO_PIN_INT->IENR &= ~(1 << gpio_int_id); /* Disable rising edge. */ + LPC_GPIO_PIN_INT->IENF |= (1 << gpio_int_id); /* Enable falling edge. */ + break; + case GPIO_BOTH: + LPC_GPIO_PIN_INT->ISEL &= ~(1 << gpio_int_id); /* Set PMODE=edge sensitive */ + LPC_GPIO_PIN_INT->IENR |= (1 << gpio_int_id); /* Enable rising edge. */ + LPC_GPIO_PIN_INT->IENF |= (1 << gpio_int_id); /* Enable falling edge. */ + break; + } + + /* clear any pending requests */ + LPC_GPIO_PIN_INT->RISE = (1 << gpio_int_id); /* Clear rising edge (sort of) flag */ + LPC_GPIO_PIN_INT->FALL = (1 << gpio_int_id); /* Clear falling edge (sort of) flag */ + + NVIC_SetPriority(gpio_int_id, 3); + + flex_int_mapping[dev] = gpio_int_id+1; + + gpio_int_id++; + + return 0; +} + +void gpio_irq_enable(gpio_t dev) +{ + if (dev >= GPIO_NUMOF) { + return; + } + + NVIC_EnableIRQ(flex_int_mapping[dev]-1); +} + +void gpio_irq_disable(gpio_t dev) +{ + uint8_t int_id; + + if (dev >= GPIO_NUMOF) { + return; + } + + int_id = flex_int_mapping[dev] - 1; + + NVIC_DisableIRQ(int_id); +} + +int gpio_read(gpio_t dev) +{ + uint8_t port; + uint8_t pin; + + if (dev >= GPIO_NUMOF) { + return -1; + } + + port = gpio_port_map[dev]; + pin = gpio_pin_map[dev]; + + if(LPC_GPIO->PIN[port] & (1 << pin)) /* read output data register */ + return 1; + else + return 0; +} + +void gpio_set(gpio_t dev) +{ + uint8_t port; + uint8_t pin; + + if (dev >= GPIO_NUMOF) { + return; + } + + port = gpio_port_map[dev]; + pin = gpio_pin_map[dev]; + + LPC_GPIO->SET[port] = (1 << pin); +} + +void gpio_clear(gpio_t dev) +{ + uint8_t port; + uint8_t pin; + + if (dev >= GPIO_NUMOF) { + return; + } + + port = gpio_port_map[dev]; + pin = gpio_pin_map[dev]; + + LPC_GPIO->CLR[port] = (1 << pin); +} + +void gpio_toggle(gpio_t dev) +{ + if (dev >= GPIO_NUMOF) { + return; + } + + LPC_GPIO->NOT[gpio_port_map[dev]] = (1 << gpio_pin_map[dev]); +} + +void gpio_write(gpio_t dev, int value) +{ + if (value) { + gpio_set(dev); + } else { + gpio_clear(dev); + } +} + +static inline void isr_common(uint8_t int_id) { + + LPC_GPIO_PIN_INT->IST |= (1 << int_id); /* Clear pending interrupt */ + gpio_config[int_id].cb(gpio_config[int_id].arg); + + if (sched_context_switch_request) { + thread_yield(); + } +} + +void isr_pinint0(void) +{ + isr_common(0); +} +void isr_pinint1(void) +{ + isr_common(1); +} +void isr_pinint2(void) +{ + isr_common(2); +} +void isr_pinint3(void) +{ + isr_common(3); +} +void isr_pinint4(void) +{ + isr_common(4); +} +void isr_pinint5(void) +{ + isr_common(5); +} +void isr_pinint6(void) +{ + isr_common(6); +} +void isr_pinint7(void) +{ + isr_common(7); +} diff --git a/cpu/lpc11u34/periph/timer.c b/cpu/lpc11u34/periph/timer.c new file mode 100644 index 0000000000..a216587c28 --- /dev/null +++ b/cpu/lpc11u34/periph/timer.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Implementation of the low-level timer driver for the LPC11U34 + * + * @author Paul RATHGEB + * @} + */ + +#include + +#include "cpu.h" +#include "sched.h" +#include "thread.h" +#include "periph_conf.h" +#include "periph/timer.h" + +/* guard file in case no timers are defined */ +#if TIMER_0_EN + +/** + * @name Timer channel interrupt flags + * @{ + */ +#define MR0_FLAG (0x01) /**< match for channel 0 */ +#define MR1_FLAG (0x02) /**< match for channel 1 */ +#define MR2_FLAG (0x04) /**< match for channel 2 */ +#define MR3_FLAG (0x08) /**< match for channel 3 */ +/** @} */ + +/** + * @brief Struct holding the configuration data for a UART device + */ +typedef struct { + void (*cb)(int); /**< timeout callback */ +} timer_conf_t; + +/** + * @brief UART device configurations + */ +static timer_conf_t config[TIMER_NUMOF]; + +int timer_init(tim_t dev, unsigned int us_per_tick, void (*callback)(int)) +{ + if (dev == TIMER_0) { + /* save callback */ + config[TIMER_0].cb = callback; + /* enable power for timer */ + TIMER_0_CLKEN(); + /* set to timer mode */ + TIMER_0_DEV->CTCR = 0; + /* configure prescaler */ + TIMER_0_DEV->PR = (us_per_tick * TIMER_0_PRESCALER); + /* configure and enable timer interrupts */ + NVIC_SetPriority(TIMER_0_IRQ, TIMER_IRQ_PRIO); + NVIC_EnableIRQ(TIMER_0_IRQ); + /* enable timer */ + TIMER_0_DEV->TCR |= 1; + return 0; + } + return -1; +} + +int timer_set(tim_t dev, int channel, unsigned int timeout) +{ + if (dev == TIMER_0) { + unsigned int now = timer_read(dev); + return timer_set_absolute(dev, channel, now + timeout); + } + return -1; +} + +int timer_set_absolute(tim_t dev, int channel, unsigned int value) +{ + if (dev == TIMER_0) { + switch (channel) { + case 0: + TIMER_0_DEV->MR0 = value; + break; + case 1: + TIMER_0_DEV->MR1 = value; + break; + case 2: + TIMER_0_DEV->MR2 = value; + break; + case 3: + TIMER_0_DEV->MR3 = value; + break; + default: + return -1; + } + TIMER_0_DEV->MCR |= (1 << (channel * 3)); + return 1; + } + return -1; +} + +int timer_clear(tim_t dev, int channel) +{ + if (dev == TIMER_0 && channel >= 0 && channel < TIMER_0_CHANNELS) { + TIMER_0_DEV->MCR &= ~(1 << (channel * 3)); + return 1; + } + return -1; +} + +unsigned int timer_read(tim_t dev) +{ + if (dev == TIMER_0) { + return (unsigned int)TIMER_0_DEV->TC; + } + return 0; +} + +void timer_start(tim_t dev) +{ + if (dev == TIMER_0) { + TIMER_0_DEV->TCR |= 1; + } +} + +void timer_stop(tim_t dev) +{ + if (dev == TIMER_0) { + TIMER_0_DEV->TCR &= ~(1); + } +} + +void timer_irq_enable(tim_t dev) +{ + if (dev == TIMER_0) { + NVIC_EnableIRQ(TIMER_0_IRQ); + } +} + +void timer_irq_disable(tim_t dev) +{ + if (dev == TIMER_0) { + NVIC_DisableIRQ(TIMER_0_IRQ); + } +} + +void timer_reset(tim_t dev) +{ + if (dev == TIMER_0) { + TIMER_0_DEV->TCR |= (1 << 1); + asm("nop"); /* just wait a cycle */ + TIMER_0_DEV->TCR &= ~(1 << 1); + } +} + +void TIMER_0_ISR(void) +{ + if (TIMER_0_DEV->IR & MR0_FLAG) { + TIMER_0_DEV->IR |= (MR0_FLAG); + TIMER_0_DEV->MCR &= ~(1 << 0); + config[TIMER_0].cb(0); + } + if (TIMER_0_DEV->IR & MR1_FLAG) { + TIMER_0_DEV->IR |= (MR1_FLAG); + TIMER_0_DEV->MCR &= ~(1 << 3); + config[TIMER_0].cb(1); + } + if (TIMER_0_DEV->IR & MR2_FLAG) { + TIMER_0_DEV->IR |= (MR2_FLAG); + TIMER_0_DEV->MCR &= ~(1 << 6); + config[TIMER_0].cb(2); + } + if (TIMER_0_DEV->IR & MR3_FLAG) { + TIMER_0_DEV->IR |= (MR3_FLAG); + TIMER_0_DEV->MCR &= ~(1 << 9); + config[TIMER_0].cb(3); + } + if (sched_context_switch_request) { + thread_yield(); + } +} + +#endif /* TIMER_0_EN */ diff --git a/cpu/lpc11u34/periph/uart.c b/cpu/lpc11u34/periph/uart.c new file mode 100644 index 0000000000..db6a75f6e6 --- /dev/null +++ b/cpu/lpc11u34/periph/uart.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Implementation of the low-level UART driver for the LPC11U34 + * + * @author Paul RATHGEB + * @} + */ + +#include + +#include "cpu.h" +#include "sched.h" +#include "thread.h" +#include "periph/uart.h" +#include "periph_conf.h" + +/* guard the file in case no UART is defined */ +#if (UART_0_EN) + +/** + * @brief Struct holding the configuration data for a UART device + */ +typedef struct { + uart_rx_cb_t rx_cb; /**< receive callback */ + uart_tx_cb_t tx_cb; /**< transmit callback */ + void *arg; /**< callback argument */ +} uart_conf_t; + +/** + * @brief UART device configurations + */ +static uart_conf_t config[UART_NUMOF]; + +int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg) +{ + int res = uart_init_blocking(uart, baudrate); + if (res < 0) { + return res; + } + + /* save callbacks */ + config[uart].rx_cb = rx_cb; + config[uart].tx_cb = tx_cb; + config[uart].arg = arg; + + switch (uart) { +#if UART_0_EN + case UART_0: + /* configure and enable global device interrupts */ + NVIC_SetPriority(UART_0_IRQ, UART_IRQ_PRIO); + NVIC_EnableIRQ(UART_0_IRQ); + /* enable RX interrupt */ + UART_0_DEV->IER |= (1 << 0); + break; +#endif + } + + return 0; +} + +int uart_init_blocking(uart_t uart, uint32_t baudrate) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + /* this implementation only supports 115200 baud */ + if (baudrate != 115200) { + return -2; + } + + /* select and configure the pin for RX */ + UART_0_RX_PINSEL &= ~0x07; + UART_0_RX_PINSEL |= (UART_0_AF); + /* select and configure the pin for TX */ + UART_0_TX_PINSEL &= ~0x07; + UART_0_TX_PINSEL |= (UART_0_AF); + + /* power on UART device and select peripheral clock */ + UART_0_CLKEN(); + UART_0_CLKSEL(); + /* set mode to 8N1 and enable access to divisor latch */ + UART_0_DEV->LCR = ((0x3 << 0) | (1 << 7)) | (3 << 4); + /* set baud rate registers (fixed for now) */ + UART_0_DEV->DLM = 0; + UART_0_DEV->DLL = 17; + UART_0_DEV->FDR |= (8) | (15 << 4); + /* disable access to divisor latch */ + UART_0_DEV->LCR &= ~0x80; + /* enable FIFOs */ + UART_0_DEV->FCR = (1 << 0) | (1 << 1) | (1 << 2) | (2 << 6); + break; +#endif + default: + return -1; + } + + return 0; +} + +void uart_tx_begin(uart_t uart) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + /* enable TX interrupt */ + UART_0_DEV->IER |= (1 << 1); + break; +#endif + } +} + +int uart_write(uart_t uart, char data) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + UART_0_DEV->THR = (uint8_t)data;; + break; +#endif + default: + return -1; + } + + return 1; +} + +int uart_read_blocking(uart_t uart, char *data) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + while (!(UART_0_DEV->LSR & (1 << 0))); /* wait for RDR bit to be set */ + + *data = (char)UART_0_DEV->RBR; + break; +#endif + default: + return -1; + } + + return 1; +} + +int uart_write_blocking(uart_t uart, char data) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + while (!(UART_0_DEV->LSR & (1 << 5))); /* wait for THRE bit to be set */ + + UART_0_DEV->THR = (uint8_t)data; + break; +#endif + default: + return -1; + } + + return 1; +} + +void uart_poweron(uart_t uart) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + UART_0_CLKEN(); + break; +#endif + } +} + +void uart_poweroff(uart_t uart) +{ + switch (uart) { +#if UART_0_EN + case UART_0: + UART_0_CLKDIS(); + break; +#endif + } +} + +#if UART_0_EN +void UART_0_ISR(void) +{ + if (UART_0_DEV->LSR & (1 << 0)) { /* is RDR flag set? */ + char data = (char)UART_0_DEV->RBR; + config[UART_0].rx_cb(config[UART_0].arg, data); + } + + if (UART_0_DEV->LSR & (1 << 5)) { /* THRE flag set? */ + if (UART_0_DEV->IER & (1 << 1)) { + if (config[UART_0].tx_cb(config[UART_0].arg) == 0) { + /* disable TX interrupt */ + UART_0_DEV->IER &= ~(1 << 1); + } + } + } + + if (sched_context_switch_request) { + thread_yield(); + } +} +#endif + + +#endif /* (UART_0_EN) */ diff --git a/cpu/lpc11u34/reboot_arch.c b/cpu/lpc11u34/reboot_arch.c new file mode 100644 index 0000000000..643c2a3ee6 --- /dev/null +++ b/cpu/lpc11u34/reboot_arch.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Implementation of the kernels reboot interface + * + * @author Paul RATHGEB + * + * @} + */ + +#include + +#include "arch/reboot_arch.h" +#include "cpu.h" + +int reboot_arch(int mode) +{ + printf("Going into reboot, mode %i\n", mode); + + NVIC_SystemReset(); + + return 0; +} diff --git a/cpu/lpc11u34/vectors.c b/cpu/lpc11u34/vectors.c new file mode 100644 index 0000000000..7036cd1403 --- /dev/null +++ b/cpu/lpc11u34/vectors.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_lpc11u34 + * @{ + * + * @file + * @brief Startup code and interrupt vector definition + * + * @author Paul RATHGEB + * + * @} + */ + +#include +#include "vectors_cortexm.h" + +/* get the start of the ISR stack as defined in the linkerscript */ +extern uint32_t _estack; + +/* define a local dummy handler as it needs to be in the same compilation unit + * as the alias definition */ +void dummy_handler(void) { + dummy_handler_default(); +} + +/* Cortex-M common interrupt vectors */ +WEAK_DEFAULT void isr_svc(void); +WEAK_DEFAULT void isr_pendsv(void); +WEAK_DEFAULT void isr_systick(void); +/* LPC11U34 specific interrupt vector */ +WEAK_DEFAULT void isr_pinint0(void); +WEAK_DEFAULT void isr_pinint1(void); +WEAK_DEFAULT void isr_pinint2(void); +WEAK_DEFAULT void isr_pinint3(void); +WEAK_DEFAULT void isr_pinint4(void); +WEAK_DEFAULT void isr_pinint5(void); +WEAK_DEFAULT void isr_pinint6(void); +WEAK_DEFAULT void isr_pinint7(void); +WEAK_DEFAULT void isr_gint0(void); +WEAK_DEFAULT void isr_gint1(void); +WEAK_DEFAULT void isr_ssp1(void); +WEAK_DEFAULT void isr_i2c0(void); +WEAK_DEFAULT void isr_ct16b0(void); +WEAK_DEFAULT void isr_ct16b1(void); +WEAK_DEFAULT void isr_ct32b0(void); +WEAK_DEFAULT void isr_ct32b1(void); +WEAK_DEFAULT void isr_ssp0(void); +WEAK_DEFAULT void isr_usart0(void); +WEAK_DEFAULT void isr_usb_irq(void); +WEAK_DEFAULT void isr_usb_fiq(void); +WEAK_DEFAULT void isr_adc(void); +WEAK_DEFAULT void isr_wwdt(void); +WEAK_DEFAULT void isr_bod(void); +WEAK_DEFAULT void isr_flash(void); +WEAK_DEFAULT void isr_usb_wakeup(void); + +/* interrupt vector table */ +__attribute__ ((section(".vectors"))) +const void *interrupt_vector[] = { + /* Exception stack pointer */ + (void*) (&_estack), /* pointer to the top of the stack */ + /* Cortex-M0 handlers */ + (void*) reset_handler_default, /* entry point of the program */ + (void*) nmi_default, /* non maskable interrupt handler */ + (void*) hard_fault_default, /* hard fault exception */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) isr_svc, /* system call interrupt, in RIOT used for + * switching into thread context on boot */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) isr_pendsv, /* pendSV interrupt, in RIOT the actual + * context switching is happening here */ + (void*) isr_systick, /* SysTick interrupt, not used in RIOT */ + /* LPC specific peripheral handlers */ + (void*) isr_pinint0, /* Pin ISR0 */ + (void*) isr_pinint1, /* Pin ISR1 */ + (void*) isr_pinint2, /* Pin ISR2 */ + (void*) isr_pinint3, /* Pin ISR3 */ + (void*) isr_pinint4, /* Pin ISR4 */ + (void*) isr_pinint5, /* Pin ISR5 */ + (void*) isr_pinint6, /* Pin ISR6 */ + (void*) isr_pinint7, /* Pin ISR7 */ + (void*) isr_gint0, /* GPIO Group ISR 0 */ + (void*) isr_gint1, /* GPIO Group ISR 1 */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) isr_ssp1, /* ssp1 */ + (void*) isr_i2c0, /* i2c0 */ + (void*) isr_ct16b0, /* ct16b0 */ + (void*) isr_ct16b1, /* ct16b1 */ + (void*) isr_ct32b0, /* ct32b0 */ + (void*) isr_ct32b1, /* ct32b1 */ + (void*) isr_ssp0, /* ssp0 */ + (void*) isr_usart0, /* usart0 */ + (void*) isr_usb_irq, /* USB */ + (void*) isr_usb_fiq, /* USB */ + (void*) isr_adc, /* ADC */ + (void*) isr_wwdt, /* windowed watchdog */ + (void*) isr_bod, /* brown out */ + (void*) isr_flash, /* brown out detect */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) isr_usb_wakeup, /* flash */ + (void*) (0UL), /* Reserved */ +};