From 18c291b7ce070af9a617fbfdfa63b2da4516954d Mon Sep 17 00:00:00 2001 From: Matthew Else Date: Fri, 19 Jul 2013 11:24:51 +0100 Subject: [PATCH] Added ytsuboi's modifications for using the 1114 --- .../TARGET_NXP/TARGET_LPC11XX/ARM/LPC1114.sct | 14 + .../TARGET_LPC11XX/ARM/startup_LPC11xx.s | 286 ++++++++ .../TARGET_NXP/TARGET_LPC11XX/ARM/sys.cpp | 31 + .../TARGET_LPC11XX/GCC_ARM/startup_LPC11xx.s | 213 ++++++ .../TARGET_LPC11XX/GCC_CR/startup_LPC11xx.cpp | 161 +++++ .../TARGET_LPC11XX/GCC_CS/startup_LPC11xx.s | 112 +++ .../TARGET_NXP/TARGET_LPC11XX/GCC_CS/sys.cpp | 79 +++ .../cmsis/TARGET_NXP/TARGET_LPC11XX/LPC11xx.h | 602 ++++++++++++++++ .../cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis.h | 13 + .../TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.c | 58 ++ .../TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.h | 23 + .../TARGET_NXP/TARGET_LPC11XX/core_cm0.c | 279 ++++++++ .../TARGET_NXP/TARGET_LPC11XX/core_cm0.h | 667 ++++++++++++++++++ .../TARGET_NXP/TARGET_LPC11XX/core_cmFunc.h | 616 ++++++++++++++++ .../TARGET_NXP/TARGET_LPC11XX/core_cmInstr.h | 643 +++++++++++++++++ .../TARGET_LPC11XX/system_LPC11xx.c | 367 ++++++++++ .../TARGET_LPC11XX/system_LPC11xx.h | 64 ++ .../TARGET_LPC11XX/uARM/LPC1114.sct | 14 + .../TARGET_LPC11XX/uARM/startup_LPC11xx.s | 234 ++++++ .../TARGET_NXP/TARGET_LPC11XX/uARM/sys.cpp | 31 + .../TARGET_LPC11XX/PeripheralNames.h | 71 ++ .../hal/TARGET_NXP/TARGET_LPC11XX/PinNames.h | 191 +++++ .../hal/TARGET_NXP/TARGET_LPC11XX/PortNames.h | 33 + .../TARGET_NXP/TARGET_LPC11XX/analogin_api.c | 123 ++++ .../hal/TARGET_NXP/TARGET_LPC11XX/device.h | 59 ++ .../hal/TARGET_NXP/TARGET_LPC11XX/gpio_api.c | 83 +++ .../TARGET_NXP/TARGET_LPC11XX/gpio_irq_api.c | 132 ++++ .../TARGET_NXP/TARGET_LPC11XX/gpio_object.h | 47 ++ .../hal/TARGET_NXP/TARGET_LPC11XX/i2c_api.c | 377 ++++++++++ .../hal/TARGET_NXP/TARGET_LPC11XX/objects.h | 66 ++ .../hal/TARGET_NXP/TARGET_LPC11XX/pinmap.c | 47 ++ .../hal/TARGET_NXP/TARGET_LPC11XX/port_api.c | 75 ++ .../TARGET_NXP/TARGET_LPC11XX/pwmout_api.c | 183 +++++ .../TARGET_NXP/TARGET_LPC11XX/serial_api.c | 276 ++++++++ .../hal/TARGET_NXP/TARGET_LPC11XX/sleep.c | 75 ++ .../hal/TARGET_NXP/TARGET_LPC11XX/spi_api.c | 214 ++++++ .../hal/TARGET_NXP/TARGET_LPC11XX/us_ticker.c | 62 ++ workspace_tools/settings.py | 6 +- workspace_tools/targets.py | 12 +- 39 files changed, 6637 insertions(+), 2 deletions(-) create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/LPC1114.sct create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/startup_LPC11xx.s create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/sys.cpp create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_ARM/startup_LPC11xx.s create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CR/startup_LPC11xx.cpp create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/startup_LPC11xx.s create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/sys.cpp create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/LPC11xx.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.c create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.c create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmFunc.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmInstr.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.c create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.h create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/LPC1114.sct create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/startup_LPC11xx.s create mode 100644 libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/sys.cpp create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PeripheralNames.h create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PinNames.h create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PortNames.h create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/analogin_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/device.h create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_irq_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_object.h create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/i2c_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/objects.h create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pinmap.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/port_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pwmout_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/serial_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/sleep.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/spi_api.c create mode 100644 libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/us_ticker.c diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/LPC1114.sct b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/LPC1114.sct new file mode 100644 index 0000000000..0a7772d0c3 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/LPC1114.sct @@ -0,0 +1,14 @@ + +LR_IROM1 0x00000000 0x8000 { ; load region size_region (32k) + ER_IROM1 0x00000000 0x8000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + ; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0 + ; 8KB - 0xC0 = 0xF40 + RW_IRAM1 0x100000C0 0xF40 { + .ANY (+RW +ZI) + } +} + diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/startup_LPC11xx.s b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/startup_LPC11xx.s new file mode 100644 index 0000000000..310568eb27 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/startup_LPC11xx.s @@ -0,0 +1,286 @@ +;/***************************************************************************** +; * @file: startup_LPC11xx.s +; * @purpose: CMSIS Cortex-M0 Core Device Startup File +; * for the NXP LPC11xx Device Series +; * @version: V1.0 +; * @date: 25. Nov. 2008 +; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +; * +; * Copyright (C) 2008 ARM Limited. All rights reserved. +; * ARM Limited (ARM) is supplying this software for use with Cortex-M0 +; * 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. +; * +; *****************************************************************************/ + +__initial_sp EQU 0x10001000 ; Top of RAM from LPC1114 + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + DCD FLEX_INT0_IRQHandler ; All GPIO pin can be routed to FLEX_INTx + DCD FLEX_INT1_IRQHandler ; + DCD FLEX_INT2_IRQHandler ; + DCD FLEX_INT3_IRQHandler ; + DCD FLEX_INT4_IRQHandler ; + DCD FLEX_INT5_IRQHandler ; + DCD FLEX_INT6_IRQHandler ; + DCD FLEX_INT7_IRQHandler ; + DCD GINT0_IRQHandler ; + DCD GINT1_IRQHandler ; PIO0 (0:7) + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; + DCD Reserved_IRQHandler ; + DCD Reserved_IRQHandler ; + DCD SSP1_IRQHandler ; SSP1 + DCD I2C_IRQHandler ; I2C + DCD TIMER16_0_IRQHandler ; 16-bit Timer0 + DCD TIMER16_1_IRQHandler ; 16-bit Timer1 + DCD TIMER32_0_IRQHandler ; 32-bit Timer0 + DCD TIMER32_1_IRQHandler ; 32-bit Timer1 + DCD SSP0_IRQHandler ; SSP0 + DCD UART_IRQHandler ; UART + DCD USB_IRQHandler ; USB IRQ + DCD USB_FIQHandler ; USB FIQ + DCD ADC_IRQHandler ; A/D Converter + DCD WDT_IRQHandler ; Watchdog timer + DCD BOD_IRQHandler ; Brown Out Detect + DCD FMC_IRQHandler ; IP2111 Flash Memory Controller + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + DCD Reserved_IRQHandler ; Reserved + + ;; 48 vector entries. We pad to 128 to fill the 0x0 - 0x1FF REMAP address space + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + DCD 0xFFFFFFFF ; Datafill + + IF :LNOT::DEF:NO_CRP + AREA |.ARM.__at_0x02FC|, CODE, READONLY +CRP_Key DCD 0xFFFFFFFF + ENDIF + + + AREA |.text|, CODE, READONLY + + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +; now, under COMMON NMI.c and NMI.h, a real NMI handler is created if NMI is enabled +; for particular peripheral. +;NMI_Handler PROC +; EXPORT NMI_Handler [WEAK] +; B . +; ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP +Reserved_IRQHandler PROC + EXPORT Reserved_IRQHandler [WEAK] + B . + ENDP + +Default_Handler PROC +; for LPC11Uxx (With USB) + EXPORT NMI_Handler [WEAK] + EXPORT FLEX_INT0_IRQHandler [WEAK] + EXPORT FLEX_INT1_IRQHandler [WEAK] + EXPORT FLEX_INT2_IRQHandler [WEAK] + EXPORT FLEX_INT3_IRQHandler [WEAK] + EXPORT FLEX_INT4_IRQHandler [WEAK] + EXPORT FLEX_INT5_IRQHandler [WEAK] + EXPORT FLEX_INT6_IRQHandler [WEAK] + EXPORT FLEX_INT7_IRQHandler [WEAK] + EXPORT GINT0_IRQHandler [WEAK] + EXPORT GINT1_IRQHandler [WEAK] + EXPORT SSP1_IRQHandler [WEAK] + EXPORT I2C_IRQHandler [WEAK] + EXPORT TIMER16_0_IRQHandler [WEAK] + EXPORT TIMER16_1_IRQHandler [WEAK] + EXPORT TIMER32_0_IRQHandler [WEAK] + EXPORT TIMER32_1_IRQHandler [WEAK] + EXPORT SSP0_IRQHandler [WEAK] + EXPORT UART_IRQHandler [WEAK] + + EXPORT USB_IRQHandler [WEAK] + EXPORT USB_FIQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT BOD_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT USBWakeup_IRQHandler [WEAK] + +NMI_Handler +FLEX_INT0_IRQHandler +FLEX_INT1_IRQHandler +FLEX_INT2_IRQHandler +FLEX_INT3_IRQHandler +FLEX_INT4_IRQHandler +FLEX_INT5_IRQHandler +FLEX_INT6_IRQHandler +FLEX_INT7_IRQHandler +GINT0_IRQHandler +GINT1_IRQHandler +SSP1_IRQHandler +I2C_IRQHandler +TIMER16_0_IRQHandler +TIMER16_1_IRQHandler +TIMER32_0_IRQHandler +TIMER32_1_IRQHandler +SSP0_IRQHandler +UART_IRQHandler +USB_IRQHandler +USB_FIQHandler +ADC_IRQHandler +WDT_IRQHandler +BOD_IRQHandler +FMC_IRQHandler +USBWakeup_IRQHandler + + B . + + ENDP + + ALIGN + END diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/sys.cpp b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/sys.cpp new file mode 100644 index 0000000000..2f1024ace8 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/ARM/sys.cpp @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_ARM/startup_LPC11xx.s b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_ARM/startup_LPC11xx.s new file mode 100644 index 0000000000..3ffdd07e58 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_ARM/startup_LPC11xx.s @@ -0,0 +1,213 @@ +/* File: startup_ARMCM0.S + * Purpose: startup file for Cortex-M0 devices. Should use with + * GCC for ARM Embedded Processors + * Version: V1.2 + * Date: 15 Nov 2011 + * + * Copyright (c) 2011, ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the ARM Limited nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + .syntax unified + .arch armv6-m + +/* Memory Model + The HEAP starts at the end of the DATA section and grows upward. + + The STACK starts at the end of the RAM and grows downward. + + The HEAP and stack STACK are only checked at compile time: + (DATA_SIZE + HEAP_SIZE + STACK_SIZE) < RAM_SIZE + + This is just a check for the bare minimum for the Heap+Stack area before + aborting compilation, it is not the run time limit: + Heap_Size + Stack_Size = 0x80 + 0x80 = 0x100 + */ + .section .stack + .align 3 +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 0x80 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0x80 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .space Heap_Size + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + +/* LPC11xx interrupts */ + .long WAKEUP_IRQHandler /* 16 0 Wake-up on pin PIO0_0 */ + .long WAKEUP_IRQHandler /* 17 1 Wake-up on pin PIO0_1 */ + .long WAKEUP_IRQHandler /* 18 2 Wake-up on pin PIO0_2 */ + .long WAKEUP_IRQHandler /* 19 3 Wake-up on pin PIO0_3 */ + .long WAKEUP_IRQHandler /* 20 4 Wake-up on pin PIO0_4 */ + .long WAKEUP_IRQHandler /* 21 5 Wake-up on pin PIO0_5 */ + .long WAKEUP_IRQHandler /* 22 6 Wake-up on pin PIO0_6 */ + .long WAKEUP_IRQHandler /* 23 7 Wake-up on pin PIO0_7 */ + .long WAKEUP_IRQHandler /* 24 8 Wake-up on pin PIO0_8 */ + .long WAKEUP_IRQHandler /* 25 9 Wake-up on pin PIO0_9 */ + .long WAKEUP_IRQHandler /* 26 10 Wake-up on pin PIO0_10 */ + .long WAKEUP_IRQHandler /* 27 11 Wake-up on pin PIO0_11 */ + .long WAKEUP_IRQHandler /* 28 12 Wake-up on pin PIO1_0 */ + .long Default_Handler /* 29 13 */ + .long SSP1_IRQHandler /* 30 14 SSP1 */ + .long I2C_IRQHandler /* 31 15 I2C0 SI (state change) */ + .long TIMER16_0_IRQHandler /* 32 16 CT16B0 16 bit timer 0 */ + .long TIMER16_1_IRQHandler /* 33 17 CT16B1 16 bit timer 1 */ + .long TIMER32_0_IRQHandler /* 34 18 CT32B0 32 bit timer 0 */ + .long TIMER32_1_IRQHandler /* 35 19 CT32B1 32 bit timer 1 */ + .long SSP0_IRQHandler /* 36 20 SSP */ + .long UART_IRQHandler /* 37 21 UART */ + .long Default_Handler /* 38 22 */ + .long Default_Handler /* 39 23 */ + .long ADC_IRQHandler /* 40 24 ADC end of conversion */ + .long WDT_IRQHandler /* 41 25 Watchdog interrupt (WDINT) */ + .long BOD_IRQHandler /* 42 26 BOD Brown-out detect */ + .long Default_Handler /* 43 27 */ + .long PIOINT3_IRQHandler /* 44 28 PIO_3 GPIO interrupt status of port 3 */ + .long PIOINT2_IRQHandler /* 45 29 PIO_2 GPIO interrupt status of port 2 */ + .long PIOINT1_IRQHandler /* 46 30 PIO_1 GPIO interrupt status of port 1 */ + .long PIOINT0_IRQHandler /* 47 31 PIO_0 GPIO interrupt status of port 0 */ + + .size __isr_vector, . - __isr_vector + + .section .text.Reset_Handler + .thumb + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + + subs r3, r2 + ble .flash_to_ram_loop_end + + movs r4, 0 +.flash_to_ram_loop: + ldr r0, [r1,r4] + str r0, [r2,r4] + adds r4, 4 + cmp r4, r3 + blt .flash_to_ram_loop +.flash_to_ram_loop_end: + + ldr r0, =SystemInit + blx r0 + ldr r0, =_start + bx r0 + .pool + .size Reset_Handler, . - Reset_Handler + + .text +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_default_handler handler_name + .align 1 + .thumb_func + .weak \handler_name + .type \handler_name, %function +\handler_name : + b . + .size \handler_name, . - \handler_name + .endm + + def_default_handler NMI_Handler + def_default_handler HardFault_Handler + def_default_handler SVC_Handler + def_default_handler PendSV_Handler + def_default_handler SysTick_Handler + def_default_handler Default_Handler + + def_default_handler WAKEUP_IRQHandler + def_default_handler SSP1_IRQHandler + def_default_handler I2C_IRQHandler + def_default_handler TIMER16_0_IRQHandler + def_default_handler TIMER16_1_IRQHandler + def_default_handler TIMER32_0_IRQHandler + def_default_handler TIMER32_1_IRQHandler + def_default_handler SSP0_IRQHandler + def_default_handler UART_IRQHandler + def_default_handler ADC_IRQHandler + def_default_handler WDT_IRQHandler + def_default_handler BOD_IRQHandler + def_default_handler PIOINT3_IRQHandler + def_default_handler PIOINT2_IRQHandler + def_default_handler PIOINT1_IRQHandler + def_default_handler PIOINT0_IRQHandler + + .weak DEF_IRQHandler + .set DEF_IRQHandler, Default_Handler + + .end + diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CR/startup_LPC11xx.cpp b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CR/startup_LPC11xx.cpp new file mode 100644 index 0000000000..ffcb738df4 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CR/startup_LPC11xx.cpp @@ -0,0 +1,161 @@ +extern "C" { + +#include "LPC11Uxx.h" + +#define WEAK __attribute__ ((weak)) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) +#define AFTER_VECTORS __attribute__ ((section(".after_vectors"))) + + void ResetISR (void); +WEAK void NMI_Handler (void); +WEAK void HardFault_Handler (void); +WEAK void SVCall_Handler (void); +WEAK void PendSV_Handler (void); +WEAK void SysTick_Handler (void); +WEAK void IntDefaultHandler (void); + void FLEX_INT0_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT1_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT2_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT3_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT4_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT5_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT6_IRQHandler(void) ALIAS(IntDefaultHandler); + void FLEX_INT7_IRQHandler(void) ALIAS(IntDefaultHandler); + void GINT0_IRQHandler (void) ALIAS(IntDefaultHandler); + void GINT1_IRQHandler (void) ALIAS(IntDefaultHandler); + void SSP1_IRQHandler (void) ALIAS(IntDefaultHandler); + void I2C_IRQHandler (void) ALIAS(IntDefaultHandler); + void TIMER16_0_IRQHandler(void) ALIAS(IntDefaultHandler); + void TIMER16_1_IRQHandler(void) ALIAS(IntDefaultHandler); + void TIMER32_0_IRQHandler(void) ALIAS(IntDefaultHandler); + void TIMER32_1_IRQHandler(void) ALIAS(IntDefaultHandler); + void SSP0_IRQHandler (void) ALIAS(IntDefaultHandler); + void UART_IRQHandler (void) ALIAS(IntDefaultHandler); + void USB_IRQHandler (void) ALIAS(IntDefaultHandler); + void USB_FIQHandler (void) ALIAS(IntDefaultHandler); + void ADC_IRQHandler (void) ALIAS(IntDefaultHandler); + void WDT_IRQHandler (void) ALIAS(IntDefaultHandler); + void BOD_IRQHandler (void) ALIAS(IntDefaultHandler); + void FMC_IRQHandler (void) ALIAS(IntDefaultHandler); + void USBWakeup_IRQHandler(void) ALIAS(IntDefaultHandler); + +extern void __libc_init_array(void); +extern int main(void); +extern void _vStackTop(void); + +extern void (* const g_pfnVectors[])(void); +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + &_vStackTop, + ResetISR, + NMI_Handler, + HardFault_Handler, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + SVCall_Handler, + 0, + 0, + PendSV_Handler, + SysTick_Handler, + FLEX_INT0_IRQHandler, + FLEX_INT1_IRQHandler, + FLEX_INT2_IRQHandler, + FLEX_INT3_IRQHandler, + FLEX_INT4_IRQHandler, + FLEX_INT5_IRQHandler, + FLEX_INT6_IRQHandler, + FLEX_INT7_IRQHandler, + GINT0_IRQHandler, + GINT1_IRQHandler, + 0, + 0, + 0, + 0, + SSP1_IRQHandler, + I2C_IRQHandler, + TIMER16_0_IRQHandler, + TIMER16_1_IRQHandler, + TIMER32_0_IRQHandler, + TIMER32_1_IRQHandler, + SSP0_IRQHandler, + UART_IRQHandler, + USB_IRQHandler, + USB_FIQHandler, + ADC_IRQHandler, + WDT_IRQHandler, + BOD_IRQHandler, + FMC_IRQHandler, + 0, + 0, + USBWakeup_IRQHandler, + 0, +}; + +AFTER_VECTORS void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = *pulSrc++; +} + +AFTER_VECTORS void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) *pulDest++ = 0; +} + +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table_end; + +AFTER_VECTORS void ResetISR(void) { + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Data Init + SectionTableAddr = &__data_section_table; + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + + // BSS Init + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + + SystemInit(); + __libc_init_array(); + main(); + while (1) {;} +} + +AFTER_VECTORS void NMI_Handler (void) {while(1){}} +AFTER_VECTORS void HardFault_Handler(void) {while(1){}} +AFTER_VECTORS void SVCall_Handler (void) {while(1){}} +AFTER_VECTORS void PendSV_Handler (void) {while(1){}} +AFTER_VECTORS void SysTick_Handler (void) {while(1){}} +AFTER_VECTORS void IntDefaultHandler(void) {while(1){}} + +#include + +void *operator new (size_t size) {return malloc(size);} +void *operator new[](size_t size) {return malloc(size);} + +void operator delete (void *p) {free(p);} +void operator delete[](void *p) {free(p);} + +int __aeabi_atexit(void *object, void (*destructor)(void *), void *dso_handle) { + return 0; +} + +} diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/startup_LPC11xx.s b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/startup_LPC11xx.s new file mode 100644 index 0000000000..cc8ab7bc24 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/startup_LPC11xx.s @@ -0,0 +1,112 @@ + .equ Stack_Size, 0x80 + .section ".stack", "w" + .align 3 + .globl __cs3_stack_mem + .globl __cs3_stack_size +__cs3_stack_mem: + .if Stack_Size + .space Stack_Size + .endif + .size __cs3_stack_mem, . - __cs3_stack_mem + .set __cs3_stack_size, . - __cs3_stack_mem + + .equ Heap_Size, 0x80 + .section ".heap", "w" + .align 3 + .globl __cs3_heap_start + .globl __cs3_heap_end +__cs3_heap_start: + .if Heap_Size + .space Heap_Size + .endif +__cs3_heap_end: + + .section ".cs3.interrupt_vector" + .globl __cs3_interrupt_vector_cortex_m + .type __cs3_interrupt_vector_cortex_m, %object + +__cs3_interrupt_vector_cortex_m: + .long __cs3_stack + .long __cs3_reset + .long NMI_Handler + .long HardFault_Handler + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + .long SVC_Handler + .long 0 + .long 0 + .long PendSV_Handler + .long SysTick_Handler + + .long DEF_IRQHandler + + .size __cs3_interrupt_vector_cortex_m, . - __cs3_interrupt_vector_cortex_m + + .thumb + + .section .cs3.reset,"x",%progbits + .thumb_func + .globl __cs3_reset_cortex_m + .type __cs3_reset_cortex_m, %function +__cs3_reset_cortex_m: + .fnstart + LDR R0, =SystemInit + BLX R0 + LDR R0,=__cs3_start_c + BX R0 + .pool + .cantunwind + .fnend + .size __cs3_reset_cortex_m,.-__cs3_reset_cortex_m + + .section ".text" + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + B . + .size NMI_Handler, . - NMI_Handler + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + B . + .size HardFault_Handler, . - HardFault_Handler + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + B . + .size SVC_Handler, . - SVC_Handler + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + B . + .size PendSV_Handler, . - PendSV_Handler + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + B . + .size SysTick_Handler, . - SysTick_Handler + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + B . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ DEF_IRQHandler + + .end diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/sys.cpp b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/sys.cpp new file mode 100644 index 0000000000..6fc5736daf --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/GCC_CS/sys.cpp @@ -0,0 +1,79 @@ +#include "cmsis.h" +#include +#include + +extern "C" { + +struct SCS3Regions { + unsigned long Dummy; + unsigned long* InitRam; + unsigned long* StartRam; + unsigned long InitSizeRam; + unsigned long ZeroSizeRam; +}; + +extern unsigned long __cs3_regions; +extern unsigned long __cs3_heap_start; + +int main(void); +void __libc_init_array(void); +void exit(int ErrorCode); + +static void *heap_pointer = NULL; + +void __cs3_start_c(void) { + static SCS3Regions* pCS3Regions = (SCS3Regions*)&__cs3_regions; + unsigned long* pulDest; + unsigned long* pulSrc; + unsigned long ByteCount; + unsigned long i; + + pulSrc = pCS3Regions->InitRam; + pulDest = pCS3Regions->StartRam; + ByteCount = pCS3Regions->InitSizeRam; + if (pulSrc != pulDest) { + for(i = 0 ; i < ByteCount ; i += sizeof(unsigned long)) { + *(pulDest++) = *(pulSrc++); + } + } else { + pulDest = (unsigned long*)(void*)((char*)pulDest + ByteCount); + } + + ByteCount = pCS3Regions->ZeroSizeRam; + for(i = 0 ; i < ByteCount ; i += sizeof(unsigned long)) { + *(pulDest++) = 0; + } + + heap_pointer = &__cs3_heap_start; + __libc_init_array(); + exit(main()); +} + +int _kill(int pid, int sig) { + errno = EINVAL; + return -1; +} + +void _exit(int status) { + exit(status); +} + +int _getpid(void) { + return 1; +} + +void *_sbrk(unsigned int incr) { + void *mem; + + unsigned int next = ((((unsigned int)heap_pointer + incr) + 7) & ~7); + if (next > __get_MSP()) { + mem = NULL; + } else { + mem = (void *)heap_pointer; + } + heap_pointer = (void *)next; + + return mem; +} + +} diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/LPC11xx.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/LPC11xx.h new file mode 100644 index 0000000000..b8a932607d --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/LPC11xx.h @@ -0,0 +1,602 @@ +/**************************************************************************** + * $Id:: LPC11xx.h 9198 2012-05-29 usb00175 $ + * Project: NXP LPC11xx software example + * + * Description: + * CMSIS Cortex-M0 Core Peripheral Access Layer Header File for + * NXP LPC11xx Device Series + + **************************************************************************** + * Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* products. This software is supplied "AS IS" without any warranties. +* NXP Semiconductors assumes no responsibility or liability for the +* use of the software, conveys no license or title under any patent, +* copyright, or mask work right to the product. NXP Semiconductors +* reserves the right to make changes in the software without +* notification. NXP Semiconductors also make no representation or +* warranty that such application will be suitable for the specified +* use without further testing or modification. + +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' +* relevant copyright in the software, without fee, provided that it +* is used in conjunction with NXP Semiconductors microcontrollers. This +* copyright, permission, and disclaimer notice must appear in all copies of +* this code. + +****************************************************************************/ +#ifndef __LPC11xx_H__ +#define __LPC11xx_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup LPC11xx_Definitions LPC11xx Definitions + This file defines all structures and symbols for LPC11xx: + - Registers and bitfields + - peripheral base address + - peripheral ID + - PIO definitions + @{ +*/ + + +/******************************************************************************/ +/* Processor and Core Peripherals */ +/******************************************************************************/ +/** @addtogroup LPC11xx_CMSIS LPC11xx CMSIS Definitions + Configuration of the Cortex-M0 Processor and Core Peripherals + @{ +*/ + +/* + * ========================================================================== + * ---------- Interrupt Number Definition ----------------------------------- + * ========================================================================== + */ +typedef enum IRQn +{ +/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */ + +/****** LPC11Cxx or LPC11xx Specific Interrupt Numbers *******************************************************/ + WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */ + WAKEUP1_IRQn = 1, /*!< There are 13 pins in total for LPC11xx */ + WAKEUP2_IRQn = 2, + WAKEUP3_IRQn = 3, + WAKEUP4_IRQn = 4, + WAKEUP5_IRQn = 5, + WAKEUP6_IRQn = 6, + WAKEUP7_IRQn = 7, + WAKEUP8_IRQn = 8, + WAKEUP9_IRQn = 9, + WAKEUP10_IRQn = 10, + WAKEUP11_IRQn = 11, + WAKEUP12_IRQn = 12, + CAN_IRQn = 13, /*!< CAN 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 */ + Reserved0_IRQn = 22, /*!< Reserved Interrupt */ + Reserved1_IRQn = 23, + 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 */ + EINT3_IRQn = 28, /*!< External Interrupt 3 Interrupt */ + EINT2_IRQn = 29, /*!< External Interrupt 2 Interrupt */ + EINT1_IRQn = 30, /*!< External Interrupt 1 Interrupt */ + EINT0_IRQn = 31, /*!< External Interrupt 0 Interrupt */ +} IRQn_Type; + +/* + * ========================================================================== + * ----------- 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 2 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/*@}*/ /* end of group LPC11xx_CMSIS */ + + +#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */ +#include "system_LPC11xx.h" /* System Header */ + + +/******************************************************************************/ +/* Device Specific Peripheral Registers structures */ +/******************************************************************************/ + +#if defined ( __CC_ARM ) +#pragma anon_unions +#endif + +/*------------- System Control (SYSCON) --------------------------------------*/ +/** @addtogroup LPC11xx_SYSCON LPC11xx System Control Block + @{ +*/ +typedef struct +{ + __IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 System memory remap (R/W) */ + __IO uint32_t PRESETCTRL; /*!< Offset: 0x004 Peripheral reset control (R/W) */ + __IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 System PLL control (R/W) */ + __I uint32_t SYSPLLSTAT; /*!< Offset: 0x00C System PLL status (R/ ) */ + uint32_t RESERVED0[4]; + + __IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 System oscillator control (R/W) */ + __IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 Watchdog oscillator control (R/W) */ + __IO uint32_t IRCCTRL; /*!< Offset: 0x028 IRC control (R/W) */ + uint32_t RESERVED1[1]; + __IO uint32_t SYSRSTSTAT; /*!< Offset: 0x030 System reset status Register (R/ ) */ + uint32_t RESERVED2[3]; + __IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 System PLL clock source select (R/W) */ + __IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 System PLL clock source update enable (R/W) */ + uint32_t RESERVED3[10]; + + __IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 Main clock source select (R/W) */ + __IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 Main clock source update enable (R/W) */ + __IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 System AHB clock divider (R/W) */ + uint32_t RESERVED4[1]; + + __IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 System AHB clock control (R/W) */ + uint32_t RESERVED5[4]; + __IO uint32_t SSP0CLKDIV; /*!< Offset: 0x094 SSP0 clock divider (R/W) */ + __IO uint32_t UARTCLKDIV; /*!< Offset: 0x098 UART clock divider (R/W) */ + __IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C SSP1 clock divider (R/W) */ + uint32_t RESERVED6[12]; + + __IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 WDT clock source select (R/W) */ + __IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 WDT clock source update enable (R/W) */ + __IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 WDT clock divider (R/W) */ + uint32_t RESERVED8[1]; + __IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 CLKOUT clock source select (R/W) */ + __IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 CLKOUT clock source update enable (R/W) */ + __IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 CLKOUT clock divider (R/W) */ + uint32_t RESERVED9[5]; + + __IO uint32_t PIOPORCAP0; /*!< Offset: 0x100 POR captured PIO status 0 (R/ ) */ + __IO uint32_t PIOPORCAP1; /*!< Offset: 0x104 POR captured PIO status 1 (R/ ) */ + uint32_t RESERVED10[18]; + __IO uint32_t BODCTRL; /*!< Offset: 0x150 BOD control (R/W) */ + __IO uint32_t SYSTCKCAL; /*!< Offset: 0x154 System tick counter calibration (R/W) */ + + uint32_t RESERVED13[7]; + __IO uint32_t NMISRC; /*!< Offset: 0x174 NMI source selection register (R/W) */ + uint32_t RESERVED14[34]; + + __IO uint32_t STARTAPRP0; /*!< Offset: 0x200 Start logic edge control Register 0 (R/W) */ + __IO uint32_t STARTERP0; /*!< Offset: 0x204 Start logic signal enable Register 0 (R/W) */ + __O uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 Start logic reset Register 0 ( /W) */ + __I uint32_t STARTSRP0; /*!< Offset: 0x20C Start logic status Register 0 (R/) */ + __IO uint32_t STARTAPRP1; /*!< Offset: 0x210 Start logic edge control Register 0 (R/W). (LPC11UXX only) */ + __IO uint32_t STARTERP1; /*!< Offset: 0x214 Start logic signal enable Register 0 (R/W). (LPC11UXX only) */ + __O uint32_t STARTRSRP1CLR; /*!< Offset: 0x218 Start logic reset Register 0 ( /W). (LPC11UXX only) */ + __IO uint32_t STARTSRP1; /*!< Offset: 0x21C Start logic status Register 0 (R/W). (LPC11UXX only) */ + uint32_t RESERVED17[4]; + + __IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 Power-down states in Deep-sleep mode (R/W) */ + __IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 Power-down states after wake-up (R/W) */ + __IO uint32_t PDRUNCFG; /*!< Offset: 0x238 Power-down configuration Register (R/W) */ + uint32_t RESERVED15[110]; + __I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 Device ID (R/ ) */ +} LPC_SYSCON_TypeDef; +/*@}*/ /* end of group LPC11xx_SYSCON */ + + +/*------------- Pin Connect Block (IOCON) --------------------------------*/ +/** @addtogroup LPC11xx_IOCON LPC11xx I/O Configuration Block + @{ +*/ +typedef struct +{ + __IO uint32_t PIO2_6; /*!< Offset: 0x000 I/O configuration for pin PIO2_6 (R/W) */ + uint32_t RESERVED0[1]; + __IO uint32_t PIO2_0; /*!< Offset: 0x008 I/O configuration for pin PIO2_0/DTR/SSEL1 (R/W) */ + __IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C I/O configuration for pin RESET/PIO0_0 (R/W) */ + __IO uint32_t PIO0_1; /*!< Offset: 0x010 I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 (R/W) */ + __IO uint32_t PIO1_8; /*!< Offset: 0x014 I/O configuration for pin PIO1_8/CT16B1_CAP0 (R/W) */ + __IO uint32_t SSEL1_LOC; /*!< Offset: 0x018 IOCON SSEL1 location register (IOCON_SSEL1_LOC, address 0x4004 4018) */ + __IO uint32_t PIO0_2; /*!< Offset: 0x01C I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 (R/W) */ + + __IO uint32_t PIO2_7; /*!< Offset: 0x020 I/O configuration for pin PIO2_7 (R/W) */ + __IO uint32_t PIO2_8; /*!< Offset: 0x024 I/O configuration for pin PIO2_8 (R/W) */ + __IO uint32_t PIO2_1; /*!< Offset: 0x028 I/O configuration for pin PIO2_1/nDSR/SCK1 (R/W) */ + __IO uint32_t PIO0_3; /*!< Offset: 0x02C I/O configuration for pin PIO0_3 (R/W) */ + __IO uint32_t PIO0_4; /*!< Offset: 0x030 I/O configuration for pin PIO0_4/SCL (R/W) */ + __IO uint32_t PIO0_5; /*!< Offset: 0x034 I/O configuration for pin PIO0_5/SDA (R/W) */ + __IO uint32_t PIO1_9; /*!< Offset: 0x038 I/O configuration for pin PIO1_9/CT16B1_MAT0 (R/W) */ + __IO uint32_t PIO3_4; /*!< Offset: 0x03C I/O configuration for pin PIO3_4 (R/W) */ + + __IO uint32_t PIO2_4; /*!< Offset: 0x040 I/O configuration for pin PIO2_4 (R/W) */ + __IO uint32_t PIO2_5; /*!< Offset: 0x044 I/O configuration for pin PIO2_5 (R/W) */ + __IO uint32_t PIO3_5; /*!< Offset: 0x048 I/O configuration for pin PIO3_5 (R/W) */ + __IO uint32_t PIO0_6; /*!< Offset: 0x04C I/O configuration for pin PIO0_6/SCK0 (R/W) */ + __IO uint32_t PIO0_7; /*!< Offset: 0x050 I/O configuration for pin PIO0_7/nCTS (R/W) */ + __IO uint32_t PIO2_9; /*!< Offset: 0x054 I/O configuration for pin PIO2_9 (R/W) */ + __IO uint32_t PIO2_10; /*!< Offset: 0x058 I/O configuration for pin PIO2_10 (R/W) */ + __IO uint32_t PIO2_2; /*!< Offset: 0x05C I/O configuration for pin PIO2_2/DCD/MISO1 (R/W) */ + + __IO uint32_t PIO0_8; /*!< Offset: 0x060 I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 (R/W) */ + __IO uint32_t PIO0_9; /*!< Offset: 0x064 I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 (R/W) */ + __IO uint32_t SWCLK_PIO0_10; /*!< Offset: 0x068 I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 (R/W) */ + __IO uint32_t PIO1_10; /*!< Offset: 0x06C I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 (R/W) */ + __IO uint32_t PIO2_11; /*!< Offset: 0x070 I/O configuration for pin PIO2_11/SCK0 (R/W) */ + __IO uint32_t R_PIO0_11; /*!< Offset: 0x074 I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 (R/W) */ + __IO uint32_t R_PIO1_0; /*!< Offset: 0x078 I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 (R/W) */ + __IO uint32_t R_PIO1_1; /*!< Offset: 0x07C I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 (R/W) */ + + __IO uint32_t R_PIO1_2; /*!< Offset: 0x080 I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 (R/W) */ + __IO uint32_t PIO3_0; /*!< Offset: 0x084 I/O configuration for pin PIO3_0/nDTR (R/W) */ + __IO uint32_t PIO3_1; /*!< Offset: 0x088 I/O configuration for pin PIO3_1/nDSR (R/W) */ + __IO uint32_t PIO2_3; /*!< Offset: 0x08C I/O configuration for pin PIO2_3/RI/MOSI1 (R/W) */ + __IO uint32_t SWDIO_PIO1_3; /*!< Offset: 0x090 I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 (R/W) */ + __IO uint32_t PIO1_4; /*!< Offset: 0x094 I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 (R/W) */ + __IO uint32_t PIO1_11; /*!< Offset: 0x098 I/O configuration for pin PIO1_11/AD7 (R/W) */ + __IO uint32_t PIO3_2; /*!< Offset: 0x09C I/O configuration for pin PIO3_2/nDCD (R/W) */ + + __IO uint32_t PIO1_5; /*!< Offset: 0x0A0 I/O configuration for pin PIO1_5/nRTS/CT32B0_CAP0 (R/W) */ + __IO uint32_t PIO1_6; /*!< Offset: 0x0A4 I/O configuration for pin PIO1_6/RXD/CT32B0_MAT0 (R/W) */ + __IO uint32_t PIO1_7; /*!< Offset: 0x0A8 I/O configuration for pin PIO1_7/TXD/CT32B0_MAT1 (R/W) */ + __IO uint32_t PIO3_3; /*!< Offset: 0x0AC I/O configuration for pin PIO3_3/nRI (R/W) */ + __IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 SCK pin location select Register (R/W) */ + __IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 DSR pin location select Register (R/W) */ + __IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 DCD pin location select Register (R/W) */ + __IO uint32_t RI_LOC; /*!< Offset: 0x0BC RI pin location Register (R/W) */ + + __IO uint32_t CT16B0_CAP0_LOC; /*!< Offset: 0x0C0 IOCON CT16B0_CAP0 location register (IOCON_CT16B0_CAP0_LOC, address 0x4004 40C0) */ + __IO uint32_t SCK1_LOC; /*!< Offset: 0x0C4 IOCON SCK1 location register (IOCON_SCK1_LOC, address 0x4004 40C4) */ + __IO uint32_t MISO1_LOC; /*!< Offset: 0x0C8 IOCON MISO1 location register (IOCON_MISO1_LOC, address 0x4004 40C8) */ + __IO uint32_t MOSI1_LOC; /*!< Offset: 0x0CC IOCON MOSI1 location register (IOCON_MOSI1_LOC, address 0x4004 40CC) */ + __IO uint32_t CT32B0_CAP0_LOC; /*!< Offset: 0x0D0 IOCON CT32B0_CAP0 location register (IOCON_CT32B0_CAP0_LOC, address 0x4004 40D0) */ + __IO uint32_t RXD_LOC; /*!< Offset: 0x0D4 IOCON RXD location register (IOCON_RXD_LOC, address 0x4004 40D4) */ +} LPC_IOCON_TypeDef; +/*@}*/ /* end of group LPC11xx_IOCON */ + + +/*------------- Power Management Unit (PMU) --------------------------*/ +/** @addtogroup LPC11xx_PMU LPC11xx Power Management Unit + @{ +*/ +typedef struct +{ + __IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */ + __IO uint32_t GPREG0; /*!< Offset: 0x004 General purpose Register 0 (R/W) */ + __IO uint32_t GPREG1; /*!< Offset: 0x008 General purpose Register 1 (R/W) */ + __IO uint32_t GPREG2; /*!< Offset: 0x00C General purpose Register 2 (R/W) */ + __IO uint32_t GPREG3; /*!< Offset: 0x010 General purpose Register 3 (R/W) */ + __IO uint32_t GPREG4; /*!< Offset: 0x014 General purpose Register 4 (R/W) */ +} LPC_PMU_TypeDef; +/*@}*/ /* end of group LPC11xx_PMU */ + + + +// ------------------------------------------------------------------------------------------------ +// ----- FLASHCTRL ----- +// ------------------------------------------------------------------------------------------------ + +typedef struct { /*!< (@ 0x4003C000) FLASHCTRL Structure */ + __I uint32_t RESERVED0[4]; + __IO uint32_t FLASHCFG; /*!< (@ 0x4003C010) Flash memory access time configuration register */ + __I uint32_t RESERVED1[3]; + __IO uint32_t FMSSTART; /*!< (@ 0x4003C020) Signature start address register */ + __IO uint32_t FMSSTOP; /*!< (@ 0x4003C024) Signature stop-address register */ + __I uint32_t RESERVED2[1]; + __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]; + __I uint32_t FMSTAT; /*!< (@ 0x4003CFE0) Signature generation status register */ + __I uint32_t RESERVED4[1]; + __IO uint32_t FMSTATCLR; /*!< (@ 0x4003CFE8) Signature generation status clear register */ +} LPC_FLASHCTRL_Type; + + +/*------------- General Purpose Input/Output (GPIO) --------------------------*/ +/** @addtogroup LPC11xx_GPIO LPC11xx General Purpose Input/Output + @{ +*/ +typedef struct +{ + union { + __IO uint32_t MASKED_ACCESS[4096]; /*!< Offset: 0x0000 to 0x3FFC Port data Register for pins PIOn_0 to PIOn_11 (R/W) */ + struct { + uint32_t RESERVED0[4095]; + __IO uint32_t DATA; /*!< Offset: 0x3FFC Port data Register (R/W) */ + }; + }; + uint32_t RESERVED1[4096]; + __IO uint32_t DIR; /*!< Offset: 0x8000 Data direction Register (R/W) */ + __IO uint32_t IS; /*!< Offset: 0x8004 Interrupt sense Register (R/W) */ + __IO uint32_t IBE; /*!< Offset: 0x8008 Interrupt both edges Register (R/W) */ + __IO uint32_t IEV; /*!< Offset: 0x800C Interrupt event Register (R/W) */ + __IO uint32_t IE; /*!< Offset: 0x8010 Interrupt mask Register (R/W) */ + __I uint32_t RIS; /*!< Offset: 0x8014 Raw interrupt status Register (R/ ) */ + __I uint32_t MIS; /*!< Offset: 0x8018 Masked interrupt status Register (R/ ) */ + __O uint32_t IC; /*!< Offset: 0x801C Interrupt clear Register (/W) */ +} LPC_GPIO_TypeDef; +/*@}*/ /* end of group LPC11xx_GPIO */ + +/*------------- Timer (TMR) --------------------------------------------------*/ +/** @addtogroup LPC11xx_TMR LPC11xx 16/32-bit Counter/Timer + @{ +*/ +typedef struct +{ + __IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */ + __IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */ + __IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */ + __IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */ + __IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */ + __IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */ + union { + __IO uint32_t MR[4]; /*!< (@ 0x40014018) Match Register */ + struct{ + __IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */ + __IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */ + __IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */ + __IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */ + }; + }; + __IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */ + __I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */ + __I uint32_t CR1; /*!< Offset: 0x030 Capture Register 1 (R/ ) */ + uint32_t RESERVED1[2]; + __IO uint32_t EMR; /*!< Offset: 0x03C External Match Register (R/W) */ + uint32_t RESERVED2[12]; + __IO uint32_t CTCR; /*!< Offset: 0x070 Count Control Register (R/W) */ + __IO uint32_t PWMC; /*!< Offset: 0x074 PWM Control Register (R/W) */ +} LPC_TMR_TypeDef; +/*@}*/ /* end of group LPC11xx_TMR */ + + +/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/ +/** @addtogroup LPC11xx_UART LPC11xx Universal Asynchronous Receiver/Transmitter + @{ +*/ +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) */ + __I uint32_t FIFOLVL; /*!< Offset: 0x058 FIFO Level Register (R) */ +} LPC_UART_TypeDef; +/*@}*/ /* end of group LPC11xx_UART */ + + +/*------------- Synchronous Serial Communication (SSP) -----------------------*/ +/** @addtogroup LPC11xx_SSP LPC11xx Synchronous Serial Port + @{ +*/ +typedef struct +{ + __IO uint32_t CR0; /*!< Offset: 0x000 Control Register 0 (R/W) */ + __IO uint32_t CR1; /*!< Offset: 0x004 Control Register 1 (R/W) */ + __IO uint32_t DR; /*!< Offset: 0x008 Data Register (R/W) */ + __I uint32_t SR; /*!< Offset: 0x00C Status Registe (R/ ) */ + __IO uint32_t CPSR; /*!< Offset: 0x010 Clock Prescale Register (R/W) */ + __IO uint32_t IMSC; /*!< Offset: 0x014 Interrupt Mask Set and Clear Register (R/W) */ + __I uint32_t RIS; /*!< Offset: 0x018 Raw Interrupt Status Register (R/) */ + __I uint32_t MIS; /*!< Offset: 0x01C Masked Interrupt Status Register (R/) */ + __O uint32_t ICR; /*!< Offset: 0x020 SSPICR Interrupt Clear Register (/W) */ +} LPC_SSP_TypeDef; +/*@}*/ /* end of group LPC11xx_SSP */ + + +/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/ +/** @addtogroup LPC11xx_I2C LPC11xx I2C-Bus Interface + @{ +*/ +typedef struct +{ + __IO uint32_t CONSET; /*!< Offset: 0x000 I2C Control Set Register (R/W) */ + __I uint32_t STAT; /*!< Offset: 0x004 I2C Status Register (R/ ) */ + __IO uint32_t DAT; /*!< Offset: 0x008 I2C Data Register (R/W) */ + __IO uint32_t ADR0; /*!< Offset: 0x00C I2C Slave Address Register 0 (R/W) */ + __IO uint32_t SCLH; /*!< Offset: 0x010 SCH Duty Cycle Register High Half Word (R/W) */ + __IO uint32_t SCLL; /*!< Offset: 0x014 SCL Duty Cycle Register Low Half Word (R/W) */ + __O uint32_t CONCLR; /*!< Offset: 0x018 I2C Control Clear Register ( /W) */ + __IO uint32_t MMCTRL; /*!< Offset: 0x01C Monitor mode control register (R/W) */ + __IO uint32_t ADR1; /*!< Offset: 0x020 I2C Slave Address Register 1 (R/W) */ + __IO uint32_t ADR2; /*!< Offset: 0x024 I2C Slave Address Register 2 (R/W) */ + __IO uint32_t ADR3; /*!< Offset: 0x028 I2C Slave Address Register 3 (R/W) */ + __I uint32_t DATA_BUFFER; /*!< Offset: 0x02C Data buffer register ( /W) */ + __IO uint32_t MASK0; /*!< Offset: 0x030 I2C Slave address mask register 0 (R/W) */ + __IO uint32_t MASK1; /*!< Offset: 0x034 I2C Slave address mask register 1 (R/W) */ + __IO uint32_t MASK2; /*!< Offset: 0x038 I2C Slave address mask register 2 (R/W) */ + __IO uint32_t MASK3; /*!< Offset: 0x03C I2C Slave address mask register 3 (R/W) */ +} LPC_I2C_TypeDef; +/*@}*/ /* end of group LPC11xx_I2C */ + + +/*------------- Watchdog Timer (WDT) -----------------------------------------*/ +/** @addtogroup LPC11xx_WDT LPC11xx WatchDog Timer + @{ +*/ +typedef struct +{ + __IO uint32_t MOD; /*!< Offset: 0x000 Watchdog mode register (R/W) */ + __IO uint32_t TC; /*!< Offset: 0x004 Watchdog timer constant register (R/W) */ + __O uint32_t FEED; /*!< Offset: 0x008 Watchdog feed sequence register (W) */ + __I uint32_t TV; /*!< Offset: 0x00C Watchdog timer value register (R) */ + uint32_t RESERVED0; + __IO uint32_t WARNINT; /*!< Offset: 0x014 Watchdog timer warning int. register (R/W) */ + __IO uint32_t WINDOW; /*!< Offset: 0x018 Watchdog timer window value register (R/W) */ +} LPC_WDT_TypeDef; +/*@}*/ /* end of group LPC11xx_WDT */ + + +/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/ +/** @addtogroup LPC11xx_ADC LPC11xx Analog-to-Digital Converter + @{ +*/ +typedef struct +{ + __IO uint32_t CR; /*!< Offset: 0x000 A/D Control Register (R/W) */ + __IO uint32_t GDR; /*!< Offset: 0x004 A/D Global Data Register (R/W) */ + uint32_t RESERVED0; + __IO uint32_t INTEN; /*!< Offset: 0x00C A/D Interrupt Enable Register (R/W) */ + __IO uint32_t DR[8]; /*!< Offset: 0x010-0x02C A/D Channel 0..7 Data Register (R/W) */ + __I uint32_t STAT; /*!< Offset: 0x030 A/D Status Register (R/ ) */ +} LPC_ADC_TypeDef; +/*@}*/ /* end of group LPC11xx_ADC */ + + +/*------------- CAN Controller (CAN) ----------------------------*/ +/** @addtogroup LPC11xx_CAN LPC11xx Controller Area Network(CAN) + @{ +*/ +typedef struct +{ + __IO uint32_t CNTL; /* 0x000 */ + __IO uint32_t STAT; + __IO uint32_t EC; + __IO uint32_t BT; + __IO uint32_t INT; + __IO uint32_t TEST; + __IO uint32_t BRPE; + uint32_t RESERVED0; + __IO uint32_t IF1_CMDREQ; /* 0x020 */ + __IO uint32_t IF1_CMDMSK; + __IO uint32_t IF1_MSK1; + __IO uint32_t IF1_MSK2; + __IO uint32_t IF1_ARB1; + __IO uint32_t IF1_ARB2; + __IO uint32_t IF1_MCTRL; + __IO uint32_t IF1_DA1; + __IO uint32_t IF1_DA2; + __IO uint32_t IF1_DB1; + __IO uint32_t IF1_DB2; + uint32_t RESERVED1[13]; + __IO uint32_t IF2_CMDREQ; /* 0x080 */ + __IO uint32_t IF2_CMDMSK; + __IO uint32_t IF2_MSK1; + __IO uint32_t IF2_MSK2; + __IO uint32_t IF2_ARB1; + __IO uint32_t IF2_ARB2; + __IO uint32_t IF2_MCTRL; + __IO uint32_t IF2_DA1; + __IO uint32_t IF2_DA2; + __IO uint32_t IF2_DB1; + __IO uint32_t IF2_DB2; + uint32_t RESERVED2[21]; + __I uint32_t TXREQ1; /* 0x100 */ + __I uint32_t TXREQ2; + uint32_t RESERVED3[6]; + __I uint32_t ND1; /* 0x120 */ + __I uint32_t ND2; + uint32_t RESERVED4[6]; + __I uint32_t IR1; /* 0x140 */ + __I uint32_t IR2; + uint32_t RESERVED5[6]; + __I uint32_t MSGV1; /* 0x160 */ + __I uint32_t MSGV2; + uint32_t RESERVED6[6]; + __IO uint32_t CLKDIV; /* 0x180 */ +} LPC_CAN_TypeDef; +/*@}*/ /* end of group LPC11xx_CAN */ + +#if defined ( __CC_ARM ) +#pragma no_anon_unions +#endif + +/******************************************************************************/ +/* Peripheral memory map */ +/******************************************************************************/ +/* Base addresses */ +#define LPC_FLASH_BASE (0x00000000UL) +#define LPC_RAM_BASE (0x10000000UL) +#define LPC_APB0_BASE (0x40000000UL) +#define LPC_AHB_BASE (0x50000000UL) + +/* APB0 peripherals */ +#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000) +#define LPC_WDT_BASE (LPC_APB0_BASE + 0x04000) +#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000) +#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000) +#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000) +#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000) +#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000) +#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000) +#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000) +#define LPC_FLASHCTRL_BASE (LPC_APB0_BASE + 0x3C000) +#define LPC_SSP0_BASE (LPC_APB0_BASE + 0x40000) +#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000) +#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000) +#define LPC_CAN_BASE (LPC_APB0_BASE + 0x50000) +#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x58000) + +/* AHB peripherals */ +#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000) +#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000) +#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000) +#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000) +#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000) + +/******************************************************************************/ +/* Peripheral declaration */ +/******************************************************************************/ +#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE ) +#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE ) +#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE ) +#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE) +#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE) +#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE) +#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE) +#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE ) +#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE ) +#define LPC_FLASHCTRL ((LPC_FLASHCTRL_Type *) LPC_FLASHCTRL_BASE) +#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE ) +#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE ) +#define LPC_CAN ((LPC_CAN_TypeDef *) LPC_CAN_BASE ) +#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE ) +#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_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 ) + +#ifdef __cplusplus +} +#endif + +#endif /* __LPC11xx_H__ */ diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis.h new file mode 100644 index 0000000000..6e00f1e26b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis.h @@ -0,0 +1,13 @@ +/* mbed Microcontroller Library - CMSIS + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * A generic CMSIS include header, pulling in LPC11U24 specifics + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "LPC11xx.h" +#include "cmsis_nvic.h" + +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.c b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.c new file mode 100644 index 0000000000..bdbe5263bd --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.c @@ -0,0 +1,58 @@ +/* mbed Microcontroller Library - cmsis_nvic for LPC11U24 + * Copyright (c) 2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#include "cmsis_nvic.h" + +/* In the M0, there is no VTOR. In the LPC range such as the LPC11U, + * whilst the vector table may only be something like 48 entries (192 bytes, 0xC0), + * the SYSMEMREMAP register actually remaps the memory from 0x10000000-0x100001FF + * to adress 0x0-0x1FF. In this case, RAM can be addressed at both 0x10000000 and 0x0 + * + * If we just copy the vectors to RAM and switch the SYSMEMMAP, any accesses to FLASH + * above the vector table before 0x200 will actually go to RAM. So we need to provide + * a solution where the compiler gets the right results based on the memory map + * + * Option 1 - We allocate and copy 0x200 of RAM rather than just the table + * - const data and instructions before 0x200 will be copied to and fetched/exec from RAM + * - RAM overhead: 0x200 - 0xC0 = 320 bytes, FLASH overhead: 0 + * + * Option 2 - We pad the flash to 0x200 to ensure the compiler doesn't allocate anything there + * - No flash accesses will go to ram, as there will be nothing there + * - RAM only needs to be allocated for the vectors, as all other ram addresses are normal + * - RAM overhead: 0, FLASH overhead: 320 bytes + * + * Option 2 is the one to go for, as RAM is the most valuable resource + */ + +#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals +#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + int i; + // Space for dynamic vectors, initialised to allocate in R/W + static volatile uint32_t* vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; + + // Copy and switch to dynamic vectors if first time called + if((LPC_SYSCON->SYSMEMREMAP & 0x3) != 0x1) { + uint32_t *old_vectors = (uint32_t *)0; // FLASH vectors are at 0x0 + for(i = 0; i < NVIC_NUM_VECTORS; i++) { + vectors[i] = old_vectors[i]; + } + LPC_SYSCON->SYSMEMREMAP = 0x1; // Remaps 0x0-0x1FF FLASH block to RAM block + } + + // Set the vector + vectors[IRQn + 16] = vector; +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) { + // We can always read vectors at 0x0, as the addresses are remapped + uint32_t *vectors = (uint32_t*)0; + + // Return the vector + return vectors[IRQn + 16]; +} + diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.h new file mode 100644 index 0000000000..299d3879be --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/cmsis_nvic.h @@ -0,0 +1,23 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.c b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.c new file mode 100644 index 0000000000..3e9f12bee9 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.c @@ -0,0 +1,279 @@ +/**************************************************************************//** + * @file core_cm0.c + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Source File + * @version V2.00 + * @date 10. September 2010 + * + * @note + * Copyright (C) 2009-2010 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#include + +/* define compiler specific symbols */ +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */ + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + +#endif + + +/* ########################## Core Instruction Access ######################### */ + +#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/ + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#if (__ARMCC_VERSION < 400677) +__ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#if (__ARMCC_VERSION < 400677) +__ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#if (__ARMCC_VERSION < 400000) +__ASM void __CLREX(void) +{ + clrex +} +#endif /* __ARMCC_VERSION */ + + +#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/ +/* obsolete */ +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ +/* obsolete */ +#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/ +/* obsolete */ +#endif + + +/* ########################### Core Function Access ########################### */ + +#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_CONTROL(void) +{ + mrs r0, control + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +#if (__ARMCC_VERSION < 400000) +__ASM void __set_CONTROL(uint32_t control) +{ + msr control, r0 + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Get ISPR Register + + This function returns the content of the ISPR Register. + + \return ISPR Register value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_IPSR(void) +{ + mrs r0, ipsr + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_APSR(void) +{ + mrs r0, apsr + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_xPSR(void) +{ + mrs r0, xpsr + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_PSP(void) +{ + mrs r0, psp + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +#if (__ARMCC_VERSION < 400000) +__ASM void __set_PSP(uint32_t topOfProcStack) +{ + msr psp, r0 + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_MSP(void) +{ + mrs r0, msp + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +#if (__ARMCC_VERSION < 400000) +__ASM void __set_MSP(uint32_t mainStackPointer) +{ + msr msp, r0 + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +#if (__ARMCC_VERSION < 400000) +__ASM uint32_t __get_PRIMASK(void) +{ + mrs r0, primask + bx lr +} +#endif /* __ARMCC_VERSION */ + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +#if (__ARMCC_VERSION < 400000) +__ASM void __set_PRIMASK(uint32_t priMask) +{ + msr primask, r0 + bx lr +} +#endif /* __ARMCC_VERSION */ + + +#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/ +/* obsolete */ +#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ +/* obsolete */ +#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/ +/* obsolete */ +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.h new file mode 100644 index 0000000000..530a786c42 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cm0.h @@ -0,0 +1,667 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V3.02 + * @date 05. November 2012 + * + * @note + * Copyright (C) 2009-2012 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. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000 + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) + are only accessible over DAP and not via processor. Therefore + they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ + else { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmFunc.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmFunc.h new file mode 100644 index 0000000000..3175adee1b --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmFunc.h @@ -0,0 +1,616 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.02 + * @date 24. May 2012 + * + * @note + * Copyright (C) 2009-2012 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 __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmInstr.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmInstr.h new file mode 100644 index 0000000000..eefce6f07f --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/core_cmInstr.h @@ -0,0 +1,643 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.03 + * @date 29. August 2012 + * + * @note + * Copyright (C) 2009-2012 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 __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + uint32_t result; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + + __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) ); + return(op1); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint8_t result; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint16_t result; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint8_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.c b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.c new file mode 100644 index 0000000000..dc58670ea7 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.c @@ -0,0 +1,367 @@ +/**************************************************************************//** + * @file system_LPC11xx.c + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Source File + * for the NXP LPC11xx/LPC11Cxx Devices + * @version V1.10 + * @date 24. November 2010 + * + * @note + * Copyright (C) 2009-2010 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + + +#include +#include "LPC11xx.h" + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +*/ + +/*--------------------- Clock Configuration ---------------------------------- +// +// Clock Configuration +// System Oscillator Control Register (SYSOSCCTRL) +// BYPASS: System Oscillator Bypass Enable +// If enabled then PLL input (sys_osc_clk) is fed +// directly from XTALIN and XTALOUT pins. +// FREQRANGE: System Oscillator Frequency Range +// Determines frequency range for Low-power oscillator. +// <0=> 1 - 20 MHz +// <1=> 15 - 25 MHz +// +// +// Watchdog Oscillator Control Register (WDTOSCCTRL) +// DIVSEL: Select Divider for Fclkana +// wdt_osc_clk = Fclkana/ (2 × (1 + DIVSEL)) +// <0-31> +// FREQSEL: Select Watchdog Oscillator Analog Output Frequency (Fclkana) +// <0=> Undefined +// <1=> 0.5 MHz +// <2=> 0.8 MHz +// <3=> 1.1 MHz +// <4=> 1.4 MHz +// <5=> 1.6 MHz +// <6=> 1.8 MHz +// <7=> 2.0 MHz +// <8=> 2.2 MHz +// <9=> 2.4 MHz +// <10=> 2.6 MHz +// <11=> 2.7 MHz +// <12=> 2.9 MHz +// <13=> 3.1 MHz +// <14=> 3.2 MHz +// <15=> 3.4 MHz +// +// +// System PLL Control Register (SYSPLLCTRL) +// F_clkout = M * F_clkin = F_CCO / (2 * P) +// F_clkin must be in the range of 10 MHz to 25 MHz +// F_CCO must be in the range of 156 MHz to 320 MHz +// MSEL: Feedback Divider Selection +// M = MSEL + 1 +// <0-31> +// PSEL: Post Divider Selection +// <0=> P = 1 +// <1=> P = 2 +// <2=> P = 4 +// <3=> P = 8 +// +// +// System PLL Clock Source Select Register (SYSPLLCLKSEL) +// SEL: System PLL Clock Source +// <0=> IRC Oscillator +// <1=> System Oscillator +// <2=> Reserved +// <3=> Reserved +// +// +// Main Clock Source Select Register (MAINCLKSEL) +// SEL: Clock Source for Main Clock +// <0=> IRC Oscillator +// <1=> Input Clock to System PLL +// <2=> WDT Oscillator +// <3=> System PLL Clock Out +// +// +// System AHB Clock Divider Register (SYSAHBCLKDIV) +// DIV: System AHB Clock Divider +// Divides main clock to provide system clock to core, memories, and peripherals. +// 0 = is disabled +// <0-255> +// +// +*/ +#define CLOCK_SETUP 1 +#define SYSOSCCTRL_Val 0x00000000 // Reset: 0x000 +#define WDTOSCCTRL_Val 0x00000000 // Reset: 0x000 +#define SYSPLLCTRL_Val 0x00000023 // Reset: 0x000 +#define SYSPLLCLKSEL_Val 0x00000001 // Reset: 0x000 +#define MAINCLKSEL_Val 0x00000000 // Reset: 0x000 +#define SYSAHBCLKDIV_Val 0x00000001 // Reset: 0x001 + +/* +//-------- <<< end of configuration section >>> ------------------------------ +*/ + +/*---------------------------------------------------------------------------- + Check the register settings + *----------------------------------------------------------------------------*/ +#define CHECK_RANGE(val, min, max) ((val < min) || (val > max)) +#define CHECK_RSVD(val, mask) (val & mask) + +/* Clock Configuration -------------------------------------------------------*/ +#if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003)) + #error "SYSOSCCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF)) + #error "WDTOSCCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2)) + #error "SYSPLLCLKSEL: Value out of range!" +#endif + +#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF)) + #error "SYSPLLCTRL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003)) + #error "MAINCLKSEL: Invalid values of reserved bits!" +#endif + +#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255)) + #error "SYSAHBCLKDIV: Value out of range!" +#endif + + +/*---------------------------------------------------------------------------- + DEFINES + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define __XTAL (12000000UL) /* Oscillator frequency */ +#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */ +#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */ + + +#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F) +#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2) + +#if (CLOCK_SETUP) /* Clock Setup */ + #if (__FREQSEL == 0) + #define __WDT_OSC_CLK ( 0) /* undefined */ + #elif (__FREQSEL == 1) + #define __WDT_OSC_CLK ( 500000 / __DIVSEL) + #elif (__FREQSEL == 2) + #define __WDT_OSC_CLK ( 800000 / __DIVSEL) + #elif (__FREQSEL == 3) + #define __WDT_OSC_CLK (1100000 / __DIVSEL) + #elif (__FREQSEL == 4) + #define __WDT_OSC_CLK (1400000 / __DIVSEL) + #elif (__FREQSEL == 5) + #define __WDT_OSC_CLK (1600000 / __DIVSEL) + #elif (__FREQSEL == 6) + #define __WDT_OSC_CLK (1800000 / __DIVSEL) + #elif (__FREQSEL == 7) + #define __WDT_OSC_CLK (2000000 / __DIVSEL) + #elif (__FREQSEL == 8) + #define __WDT_OSC_CLK (2200000 / __DIVSEL) + #elif (__FREQSEL == 9) + #define __WDT_OSC_CLK (2400000 / __DIVSEL) + #elif (__FREQSEL == 10) + #define __WDT_OSC_CLK (2600000 / __DIVSEL) + #elif (__FREQSEL == 11) + #define __WDT_OSC_CLK (2700000 / __DIVSEL) + #elif (__FREQSEL == 12) + #define __WDT_OSC_CLK (2900000 / __DIVSEL) + #elif (__FREQSEL == 13) + #define __WDT_OSC_CLK (3100000 / __DIVSEL) + #elif (__FREQSEL == 14) + #define __WDT_OSC_CLK (3200000 / __DIVSEL) + #else + #define __WDT_OSC_CLK (3400000 / __DIVSEL) + #endif + + /* sys_pllclkin calculation */ + #if ((SYSPLLCLKSEL_Val & 0x03) == 0) + #define __SYS_PLLCLKIN (__IRC_OSC_CLK) + #elif ((SYSPLLCLKSEL_Val & 0x03) == 1) + #define __SYS_PLLCLKIN (__SYS_OSC_CLK) + #else + #define __SYS_PLLCLKIN (0) + #endif + + #define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1)) + + /* main clock calculation */ + #if ((MAINCLKSEL_Val & 0x03) == 0) + #define __MAIN_CLOCK (__IRC_OSC_CLK) + #elif ((MAINCLKSEL_Val & 0x03) == 1) + #define __MAIN_CLOCK (__SYS_PLLCLKIN) + #elif ((MAINCLKSEL_Val & 0x03) == 2) + #if (__FREQSEL == 0) + #error "MAINCLKSEL: WDT Oscillator selected but FREQSEL is undefined!" + #else + #define __MAIN_CLOCK (__WDT_OSC_CLK) + #endif + #elif ((MAINCLKSEL_Val & 0x03) == 3) + #define __MAIN_CLOCK (__SYS_PLLCLKOUT) + #else + #define __MAIN_CLOCK (0) + #endif + + #define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val) + +#else + #define __SYSTEM_CLOCK (__IRC_OSC_CLK) +#endif // CLOCK_SETUP + + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/ + + +/*---------------------------------------------------------------------------- + Clock functions + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ +{ + uint32_t wdt_osc = 0; + + /* Determine clock frequency according to clock register values */ + switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) { + case 0: wdt_osc = 0; break; + case 1: wdt_osc = 500000; break; + case 2: wdt_osc = 800000; break; + case 3: wdt_osc = 1100000; break; + case 4: wdt_osc = 1400000; break; + case 5: wdt_osc = 1600000; break; + case 6: wdt_osc = 1800000; break; + case 7: wdt_osc = 2000000; break; + case 8: wdt_osc = 2200000; break; + case 9: wdt_osc = 2400000; break; + case 10: wdt_osc = 2600000; break; + case 11: wdt_osc = 2700000; break; + case 12: wdt_osc = 2900000; break; + case 13: wdt_osc = 3100000; break; + case 14: wdt_osc = 3200000; break; + case 15: wdt_osc = 3400000; break; + } + wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2; + + switch (LPC_SYSCON->MAINCLKSEL & 0x03) { + case 0: /* Internal RC oscillator */ + SystemCoreClock = __IRC_OSC_CLK; + break; + case 1: /* Input Clock to System PLL */ + switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) { + case 0: /* Internal RC oscillator */ + SystemCoreClock = __IRC_OSC_CLK; + break; + case 1: /* System oscillator */ + SystemCoreClock = __SYS_OSC_CLK; + break; + case 2: /* Reserved */ + case 3: /* Reserved */ + SystemCoreClock = 0; + break; + } + break; + case 2: /* WDT Oscillator */ + SystemCoreClock = wdt_osc; + break; + case 3: /* System PLL Clock Out */ + switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) { + case 0: /* Internal RC oscillator */ + if (LPC_SYSCON->SYSPLLCTRL & 0x180) { + SystemCoreClock = __IRC_OSC_CLK; + } else { + SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1); + } + break; + case 1: /* System oscillator */ + if (LPC_SYSCON->SYSPLLCTRL & 0x180) { + SystemCoreClock = __SYS_OSC_CLK; + } else { + SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1); + } + break; + case 2: /* Reserved */ + case 3: /* Reserved */ + SystemCoreClock = 0; + break; + } + break; + } + + SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV; + +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System. + */ +void SystemInit (void) { + volatile uint32_t i; + +#if (CLOCK_SETUP) /* Clock Setup */ + +#if ((SYSPLLCLKSEL_Val & 0x03) == 1) + LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up System Osc */ + LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val; + for (i = 0; i < 200; i++) __NOP(); +#endif + + LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */ + LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */ + LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */ + LPC_SYSCON->SYSPLLCLKUEN = 0x01; + while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */ +#if ((MAINCLKSEL_Val & 0x03) == 3) /* Main Clock is PLL Out */ + LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val; + LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */ + while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */ +#endif + +#if (((MAINCLKSEL_Val & 0x03) == 2) ) + LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val; + LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */ + for (i = 0; i < 200; i++) __NOP(); +#endif + + LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */ + LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */ + LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */ + LPC_SYSCON->MAINCLKUEN = 0x01; + while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */ + + LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val; +#endif + /* 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); +} diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.h b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.h new file mode 100644 index 0000000000..fa57304d48 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/system_LPC11xx.h @@ -0,0 +1,64 @@ +/**************************************************************************//** + * @file system_LPC11xx.h + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File + * for the NXP LPC11xx/LPC11Cxx Device Series + * @version V1.10 + * @date 24. November 2010 + * + * @note + * Copyright (C) 2009-2010 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_LPC11xx_H +#define __SYSTEM_LPC11xx_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +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_LPC11xx_H */ diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/LPC1114.sct b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/LPC1114.sct new file mode 100644 index 0000000000..0a7772d0c3 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/LPC1114.sct @@ -0,0 +1,14 @@ + +LR_IROM1 0x00000000 0x8000 { ; load region size_region (32k) + ER_IROM1 0x00000000 0x8000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + ; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0 + ; 8KB - 0xC0 = 0xF40 + RW_IRAM1 0x100000C0 0xF40 { + .ANY (+RW +ZI) + } +} + diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/startup_LPC11xx.s b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/startup_LPC11xx.s new file mode 100644 index 0000000000..aaf796aa27 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/startup_LPC11xx.s @@ -0,0 +1,234 @@ +;/**************************************************************************//** +; * @file startup_LPC11xx.s +; * @brief CMSIS Cortex-M0 Core Device Startup File +; * for the NXP LPC11xx/LPC11Cxx Device Series +; * @version V1.10 +; * @date 24. November 2010 +; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +; * +; * @note +; * Copyright (C) 2009-2010 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. +; * +; ******************************************************************************/ + + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000200 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000000 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WAKEUP_IRQHandler ; 16+ 0: Wakeup PIO0.0 + DCD WAKEUP_IRQHandler ; 16+ 1: Wakeup PIO0.1 + DCD WAKEUP_IRQHandler ; 16+ 2: Wakeup PIO0.2 + DCD WAKEUP_IRQHandler ; 16+ 3: Wakeup PIO0.3 + DCD WAKEUP_IRQHandler ; 16+ 4: Wakeup PIO0.4 + DCD WAKEUP_IRQHandler ; 16+ 5: Wakeup PIO0.5 + DCD WAKEUP_IRQHandler ; 16+ 6: Wakeup PIO0.6 + DCD WAKEUP_IRQHandler ; 16+ 7: Wakeup PIO0.7 + DCD WAKEUP_IRQHandler ; 16+ 8: Wakeup PIO0.8 + DCD WAKEUP_IRQHandler ; 16+ 9: Wakeup PIO0.9 + DCD WAKEUP_IRQHandler ; 16+10: Wakeup PIO0.10 + DCD WAKEUP_IRQHandler ; 16+11: Wakeup PIO0.11 + DCD WAKEUP_IRQHandler ; 16+12: Wakeup PIO1.0 + DCD CAN_IRQHandler ; 16+13: CAN + DCD SSP1_IRQHandler ; 16+14: SSP1 + DCD I2C_IRQHandler ; 16+15: I2C + DCD TIMER16_0_IRQHandler ; 16+16: 16-bit Counter-Timer 0 + DCD TIMER16_1_IRQHandler ; 16+17: 16-bit Counter-Timer 1 + DCD TIMER32_0_IRQHandler ; 16+18: 32-bit Counter-Timer 0 + DCD TIMER32_1_IRQHandler ; 16+19: 32-bit Counter-Timer 1 + DCD SSP0_IRQHandler ; 16+20: SSP0 + DCD UART_IRQHandler ; 16+21: UART + DCD USB_IRQHandler ; 16+22: USB IRQ + DCD USB_FIQHandler ; 16+24: USB FIQ + DCD ADC_IRQHandler ; 16+24: A/D Converter + DCD WDT_IRQHandler ; 16+25: Watchdog Timer + DCD BOD_IRQHandler ; 16+26: Brown Out Detect + DCD FMC_IRQHandler ; 16+27: IP2111 Flash Memory Controller + DCD PIOINT3_IRQHandler ; 16+28: PIO INT3 + DCD PIOINT2_IRQHandler ; 16+29: PIO INT2 + DCD PIOINT1_IRQHandler ; 16+30: PIO INT1 + DCD PIOINT0_IRQHandler ; 16+31: PIO INT0 + + + IF :LNOT::DEF:NO_CRP + AREA |.ARM.__at_0x02FC|, CODE, READONLY +CRP_Key DCD 0xFFFFFFFF + ENDIF + + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WAKEUP_IRQHandler [WEAK] + EXPORT CAN_IRQHandler [WEAK] + EXPORT SSP1_IRQHandler [WEAK] + EXPORT I2C_IRQHandler [WEAK] + EXPORT TIMER16_0_IRQHandler [WEAK] + EXPORT TIMER16_1_IRQHandler [WEAK] + EXPORT TIMER32_0_IRQHandler [WEAK] + EXPORT TIMER32_1_IRQHandler [WEAK] + EXPORT SSP0_IRQHandler [WEAK] + EXPORT UART_IRQHandler [WEAK] + EXPORT USB_IRQHandler [WEAK] + EXPORT USB_FIQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT BOD_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT PIOINT3_IRQHandler [WEAK] + EXPORT PIOINT2_IRQHandler [WEAK] + EXPORT PIOINT1_IRQHandler [WEAK] + EXPORT PIOINT0_IRQHandler [WEAK] + +WAKEUP_IRQHandler +CAN_IRQHandler +SSP1_IRQHandler +I2C_IRQHandler +TIMER16_0_IRQHandler +TIMER16_1_IRQHandler +TIMER32_0_IRQHandler +TIMER32_1_IRQHandler +SSP0_IRQHandler +UART_IRQHandler +USB_IRQHandler +USB_FIQHandler +ADC_IRQHandler +WDT_IRQHandler +BOD_IRQHandler +FMC_IRQHandler +PIOINT3_IRQHandler +PIOINT2_IRQHandler +PIOINT1_IRQHandler +PIOINT0_IRQHandler + + B . + + ENDP + + + ALIGN + + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + + END diff --git a/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/sys.cpp b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/sys.cpp new file mode 100644 index 0000000000..2f1024ace8 --- /dev/null +++ b/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX/uARM/sys.cpp @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library - stackheap + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern char Image$$RW_IRAM1$$ZI$$Limit[]; + +extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit; + uint32_t sp_limit = __current_sp(); + + zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned + + struct __initial_stackheap r; + r.heap_base = zi_limit; + r.heap_limit = sp_limit; + return r; +} + +#ifdef __cplusplus +} +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PeripheralNames.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PeripheralNames.h new file mode 100644 index 0000000000..e7eba416e5 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PeripheralNames.h @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UART_0 = (int)LPC_UART_BASE +} UARTName; + +typedef enum { + I2C_0 = (int)LPC_I2C_BASE +} I2CName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7 +} ADCName; + +typedef enum { + SPI_0 = (int)LPC_SSP0_BASE, + SPI_1 = (int)LPC_SSP1_BASE +} SPIName; + +typedef enum { + PWM_1 = 0, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6, + PWM_7, + PWM_8, + PWM_9, + PWM_10, + PWM_11 +} PWMName; + +#define STDIO_UART_TX USBTX +#define STDIO_UART_RX USBRX +#define STDIO_UART UART_0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PinNames.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PinNames.h new file mode 100644 index 0000000000..eda7930b1d --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PinNames.h @@ -0,0 +1,191 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#ifndef MBED_PINNAMES_H +#define MBED_PINNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PIN_INPUT, + PIN_OUTPUT +} PinDirection; + +#define PORT_SHIFT 5 + +typedef enum { + // LPC1114 Pin Names (PORT[15:12] + PIN[11:8] + IOCON offset[7:0]) + P0_0 = 0x000c, + P0_1 = 0x0110, + P0_2 = 0x021c, + P0_3 = 0x032c, + P0_4 = 0x0430, + P0_5 = 0x0534, + P0_6 = 0x064c, + P0_7 = 0x0750, + P0_8 = 0x0860, + P0_9 = 0x0964, + P0_10 = 0x0a68, + P0_11 = 0x0b74, + + P1_0 = 0x1078, + P1_1 = 0x117c, + P1_2 = 0x1280, + P1_3 = 0x1390, + P1_4 = 0x1494, + P1_5 = 0x15a0, + P1_6 = 0x16a4, + P1_7 = 0x17a8, + P1_8 = 0x1814, + P1_9 = 0x1938, + P1_10 = 0x1a6c, + P1_11 = 0x1b98, + + P2_0 = 0x2008, + P2_1 = 0x2128, + P2_2 = 0x225c, + P2_3 = 0x238c, + P2_4 = 0x2440, + P2_5 = 0x2544, + P2_6 = 0x2600, + P2_7 = 0x2720, + P2_8 = 0x2824, + P2_9 = 0x2954, + P2_10 = 0x2a58, + P2_11 = 0x2b70, + + P3_0 = 0x3084, + P3_1 = 0x3188, + P3_2 = 0x329c, + P3_3 = 0x33ac, + P3_4 = 0x343c, + P3_5 = 0x3548, + + // mbed DIP Pin Names (CQ board) + p4 = P0_0, + p5 = P0_9, + p6 = P0_8, + p7 = P0_6, + p8 = P1_5, + p9 = P1_7, + p10 = P1_6, + p11 = P0_7, + p12 = P1_0, + p13 = P1_1, + p14 = P1_2, + p15 = P0_11, + p16 = P1_0, + p17 = P1_1, + p18 = P1_2, + p19 = P1_3, + p20 = P1_4, + p21 = P0_10, + p22 = P0_2, + p23 = P0_11, + p24 = P0_2, + p25 = P1_8, + p26 = P1_9, + p27 = P0_4, + p28 = P0_5, + p29 = P0_3, + p30 = P0_1, + + // Other mbed Pin Names + LED1 = P1_5, + LED2 = P0_7, + LED3 = P1_5, + LED4 = P0_7, + + USBTX = P1_7, + USBRX = P1_6, + + // mbed DIP Pin Names (LPCXpresso LPC1114) + xp4 = P0_0, + xp5 = P0_9, + xp6 = P0_8, + xp7 = P2_11, + xp8 = P0_2, + xp9 = P1_7, + xp10 = P1_6, + xp11 = P0_7, + xp12 = P2_0, + xp13 = P2_1, + xp14 = P2_2, + xp15 = P0_11, + xp16 = P1_0, + xp17 = P1_1, + xp18 = P1_2, + xp19 = P1_3, + xp20 = P1_4, + xp21 = P1_5, + xp22 = P1_8, + xp23 = P0_6, + xp24 = P0_10, + xp25 = P3_0, + xp26 = P3_1, + xp27 = P3_2, + + xp29 = P3_3, + xp30 = P2_10, + xp31 = P2_9, + xp32 = P2_8, + xp33 = P2_7, + xp34 = P2_6, + xp35 = P2_5, + xp36 = P2_4, + xp37 = P2_3, + xp38 = P1_11, + xp39 = P1_10, + xp40 = P1_9, + xp41 = P0_4, + xp42 = P0_5, + xp43 = P0_3, + xp44 = P0_1, + + // Other mbed Pin Names + xLED1 = P0_7, + + // Not connected + NC = (int)0xFFFFFFFF, +} PinName; + +typedef enum { + CHANNEL0 = WAKEUP0_IRQn, + CHANNEL1 = WAKEUP1_IRQn, + CHANNEL2 = WAKEUP2_IRQn, + CHANNEL3 = WAKEUP3_IRQn, + CHANNEL4 = WAKEUP4_IRQn, + CHANNEL5 = WAKEUP5_IRQn, + CHANNEL6 = WAKEUP6_IRQn, + CHANNEL7 = WAKEUP7_IRQn +} Channel; + +typedef enum { + PullUp = 2, + PullDown = 1, + PullNone = 0, + Repeater = 3, + OpenDrain = 4 +} PinMode; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PortNames.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PortNames.h new file mode 100644 index 0000000000..4887fecb33 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/PortNames.h @@ -0,0 +1,33 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + Port0 = 0, + Port1 = 1, + Port2 = 2, + Port3 = 3 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/analogin_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/analogin_api.c new file mode 100644 index 0000000000..2309224f68 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/analogin_api.c @@ -0,0 +1,123 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include "analogin_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +#define ANALOGIN_MEDIAN_FILTER 1 + +#define ADC_10BIT_RANGE 0x3FF +#define ADC_12BIT_RANGE 0xFFF + +static inline int div_round_up(int x, int y) { + return (x + (y - 1)) / y; +} + +static const PinMap PinMap_ADC[] = { + {P0_11, ADC0_0, 2}, + {P1_0 , ADC0_1, 2}, + {P1_1 , ADC0_2, 2}, + {P1_2 , ADC0_3, 2}, + {P1_3 , ADC0_4, 2}, + {P1_4 , ADC0_5, 1}, + {P1_10, ADC0_6, 1}, + {P1_11, ADC0_7, 1}, + {NC , NC , 0} +}; + +#define ADC_RANGE ADC_10BIT_RANGE + +void analogin_init(analogin_t *obj, PinName pin) { + obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); + if (obj->adc == (uint32_t)NC) { + error("ADC pin mapping failed"); + } + + // Power up ADC + LPC_SYSCON->PDRUNCFG &= ~ (1 << 4); + LPC_SYSCON->SYSAHBCLKCTRL |= ((uint32_t)1 << 13); + + uint32_t offset = (uint32_t)pin & 0xff; + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + offset); + + // set pin to ADC mode + *reg &= ~(1 << 7); // set ADMODE = 0 (analog mode) + + uint32_t PCLK = SystemCoreClock; + uint32_t MAX_ADC_CLK = 4500000; + uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; + + LPC_ADC->CR = (0 << 0) // no channels selected + | (clkdiv << 8) // max of 4.5MHz + | (0 << 16) // BURST = 0, software controlled + | ( 0 << 17 ); // CLKS = 0, not applicable + + pinmap_pinout(pin, PinMap_ADC); +} + +static inline uint32_t adc_read(analogin_t *obj) { + // Select the appropriate channel and start conversion + LPC_ADC->CR &= ~0xFF; + LPC_ADC->CR |= 1 << (int)obj->adc; + LPC_ADC->CR |= 1 << 24; + + // Repeatedly get the sample data until DONE bit + unsigned int data; + do { + data = LPC_ADC->GDR; + } while ((data & ((unsigned int)1 << 31)) == 0); + + // Stop conversion + LPC_ADC->CR &= ~(1 << 24); + + return (data >> 6) & ADC_RANGE; // 10 bit +} + +static inline void order(uint32_t *a, uint32_t *b) { + if (*a > *b) { + uint32_t t = *a; + *a = *b; + *b = t; + } +} + +static inline uint32_t adc_read_u32(analogin_t *obj) { + uint32_t value; +#if ANALOGIN_MEDIAN_FILTER + uint32_t v1 = adc_read(obj); + uint32_t v2 = adc_read(obj); + uint32_t v3 = adc_read(obj); + order(&v1, &v2); + order(&v2, &v3); + order(&v1, &v2); + value = v2; +#else + value = adc_read(obj); +#endif + return value; +} + +uint16_t analogin_read_u16(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + + return (value << 6) | ((value >> 4) & 0x003F); // 10 bit +} + +float analogin_read(analogin_t *obj) { + uint32_t value = adc_read_u32(obj); + return (float)value * (1.0f / (float)ADC_RANGE); +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/device.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/device.h new file mode 100644 index 0000000000..7a93c9bbec --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/device.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 0 +#define DEVICE_PORTOUT 0 +#define DEVICE_PORTINOUT 0 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 0 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 0 + +#define DEVICE_ETHERNET 0 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SEMIHOST 1 +#define DEVICE_LOCALFILESYSTEM 1 +#define DEVICE_ID_LENGTH 32 +#define DEVICE_MAC_OFFSET 20 + +#define DEVICE_SLEEP 1 + +#define DEVICE_DEBUG_AWARENESS 0 + +#define DEVICE_STDIO_MESSAGES 1 + +#define DEVICE_ERROR_PATTERN 1 + +#include "objects.h" + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_api.c new file mode 100644 index 0000000000..5bf56d66ef --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_api.c @@ -0,0 +1,83 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include "gpio_api.h" +#include "pinmap.h" + +uint32_t gpio_set(PinName pin) { + // PIO default value of following ports are not same as others + int f = ((pin == P0_0 ) || // RESET + (pin == P0_10) || // SWCLK + (pin == P0_11) || // R + (pin == P1_0 ) || // R + (pin == P1_1 ) || // R + (pin == P1_2 ) || // R + (pin == P1_3 )) ? // + (1) : (0); + + pin_function(pin, f); + + int pin_number = ((pin & 0x0F00) >> 8); + return (pin_number + 1); // port n data address offset +} + +void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) { + if(pin == NC) return; + + obj->pin = pin; + + LPC_GPIO_TypeDef *port_reg; + + switch (pin & 0xF000) { + case 0x0000: + port_reg = LPC_GPIO0; + break; + case 0x1000: + port_reg = LPC_GPIO1; + break; + case 0x2000: + port_reg = LPC_GPIO2; + break; + case 0x3000: + port_reg = LPC_GPIO3; + break; + default: + return; + } + +#warning TODO (@toyowata): Need to check array offset + obj->mask = &port_reg->MASKED_ACCESS[gpio_set(pin)]; + obj->reg_dir = &port_reg->DIR; + obj->reg_in = &port_reg->DATA; + obj->reg_data= &port_reg->DATA; + + gpio_dir(obj, direction); + switch (direction) { + case PIN_OUTPUT: pin_mode(pin, PullNone); break; + case PIN_INPUT : pin_mode(pin, PullDown); break; + } +} + +void gpio_mode(gpio_t *obj, PinMode mode) { + pin_mode(obj->pin, mode); +} + +void gpio_dir(gpio_t *obj, PinDirection direction) { + int pin_number = ((obj->pin & 0x0F00) >> 8); + switch (direction) { + case PIN_INPUT : *obj->reg_dir &= ~(1 << pin_number); break; + case PIN_OUTPUT: *obj->reg_dir |= (1 << pin_number); break; + } +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_irq_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_irq_api.c new file mode 100644 index 0000000000..5d5b81afa9 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_irq_api.c @@ -0,0 +1,132 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include +#include "cmsis.h" +#include "gpio_irq_api.h" +#include "error.h" + +#define CHANNEL_NUM 4 +#define PININT_IRQ 28+3 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; +static gpio_irq_handler irq_handler; +#warning TODO(@toyowata): need implimentation +#if 0 +static inline void handle_interrupt_in(uint32_t channel) { + uint32_t ch_bit = (1 << channel); + + LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE + (channel * 0x10000)); + + // Return immediately if: + // * The interrupt was already served + // * There is no user handler + // * It is a level interrupt, not an edge interrupt + if ( ((&port_reg->IST & ch_bit) == 0) || + (channel_ids[channel] == 0 ) || + (&port_reg->ISEL & ch_bit ) ) return; + + if ((&port_reg->IENR & ch_bit) && (&port_reg->RISE & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_RISE); + &port_reg->RISE = ch_bit; + } + if ((&port_reg->IENF & ch_bit) && (&port_reg->FALL & ch_bit)) { + irq_handler(channel_ids[channel], IRQ_FALL); + } + &port_reg->IST = ch_bit; +} + +void gpio_irq0(void) {handle_interrupt_in(0);} +void gpio_irq1(void) {handle_interrupt_in(1);} +void gpio_irq2(void) {handle_interrupt_in(2);} +void gpio_irq3(void) {handle_interrupt_in(3);} + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) return -1; + + irq_handler = handler; + + int found_free_channel = 0; + int i = 0; + for (i=0; ich = i; + found_free_channel = 1; + break; + } + } + if (!found_free_channel) return -1; + + /* Enable AHB clock to the GPIO domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); + + /* Enable AHB clock to the FlexInt, GroupedInt domain. */ + LPC_SYSCON->SYSAHBCLKCTRL |= ((1<<19) | (1<<23) | (1<<24)); + + /* To select a pin for any of the eight pin interrupts, write the pin number + * as 0 to 23 for pins PIO0_0 to PIO0_23 and 24 to 55. + * @see: mbed_capi/PinNames.h + */ + LPC_SYSCON->PINTSEL[obj->ch] = (pin >> 5) ? (pin - 8) : (pin); + + // Interrupt Wake-Up Enable + LPC_SYSCON->STARTERP0 |= 1 << obj->ch; + + void (*channels_irq)(void) = NULL; + switch (obj->ch) { + case 0: channels_irq = &gpio_irq0; break; + case 1: channels_irq = &gpio_irq1; break; + case 2: channels_irq = &gpio_irq2; break; + case 3: channels_irq = &gpio_irq3; break; + } + NVIC_SetVector((IRQn_Type)(PININT_IRQ - obj->ch)), (uint32_t)channels_irq); + NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ - obj->ch)); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; + LPC_SYSCON->STARTERP0 &= ~(1 << obj->ch); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + unsigned int ch_bit = (1 << obj->ch); + + LPC_GPIO_TypeDef *port_reg = ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE + (obj->ch * 0x10000)); + + // Clear interrupt + if (!(&port_reg->ISEL & ch_bit)) + &port_reg->IST = ch_bit; + + // Edge trigger + &port_reg->ISEL &= ~ch_bit; + if (event == IRQ_RISE) { + if (enable) { + &port_reg->IENR |= ch_bit; + } else { + &port_reg->IENR &= ~ch_bit; + } + } else { + if (enable) { + &port_reg->IENF |= ch_bit; + } else { + &port_reg->IENF &= ~ch_bit; + } + } +} + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_object.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_object.h new file mode 100644 index 0000000000..2d37743032 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/gpio_object.h @@ -0,0 +1,47 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + __IO uint32_t *mask; + __IO uint32_t *reg_dir; + __IO uint32_t *reg_data; + __I uint32_t *reg_in; +} gpio_t; + +static inline void gpio_write(gpio_t *obj, int value) { + uint32_t pin_number = ((obj->pin & 0x0F00) >> 8); + if (value) + *obj->reg_data |= (1 << pin_number); + else + *obj->reg_data &= ~(1 << pin_number); +} + +static inline int gpio_read(gpio_t *obj) { + return ((*obj->mask) ? 1 : 0); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/i2c_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/i2c_api.c new file mode 100644 index 0000000000..faad235724 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/i2c_api.c @@ -0,0 +1,377 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include "i2c_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +static const PinMap PinMap_I2C_SDA[] = { + {P0_5, I2C_0, 1}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {P0_4, I2C_0, 1}, + {NC , NC, 0} +}; + +#define I2C_CONSET(x) (x->i2c->CONSET) +#define I2C_CONCLR(x) (x->i2c->CONCLR) +#define I2C_STAT(x) (x->i2c->STAT) +#define I2C_DAT(x) (x->i2c->DAT) +#define I2C_SCLL(x, val) (x->i2c->SCLL = val) +#define I2C_SCLH(x, val) (x->i2c->SCLH = val) + +static const uint32_t I2C_addr_offset[4] = { + 0x0C, 0x20, 0x24, 0x28 +}; + +static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONCLR(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +static inline void i2c_conset(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) { + I2C_CONSET(obj) = (start << 5) + | (stop << 4) + | (interrupt << 3) + | (acknowledge << 2); +} + +// Clear the Serial Interrupt (SI) +static inline void i2c_clear_SI(i2c_t *obj) { + i2c_conclr(obj, 0, 0, 1, 0); +} + +static inline int i2c_status(i2c_t *obj) { + return I2C_STAT(obj); +} + +// Wait until the Serial Interrupt (SI) is set +static int i2c_wait_SI(i2c_t *obj) { + int timeout = 0; + while (!(I2C_CONSET(obj) & (1 << 3))) { + timeout++; + if (timeout > 100000) return -1; + } + return 0; +} + +static inline void i2c_interface_enable(i2c_t *obj) { + I2C_CONSET(obj) = 0x40; +} + +static inline void i2c_power_enable(i2c_t *obj) { + LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 5); + LPC_SYSCON->PRESETCTRL |= 1 << 1; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + // determine the SPI to use + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (LPC_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + + if ((int)obj->i2c == NC) { + error("I2C pin mapping failed"); + } + + // enable power + i2c_power_enable(obj); + + // set default frequency at 100k + i2c_frequency(obj, 100000); + i2c_conclr(obj, 1, 1, 1, 1); + i2c_interface_enable(obj); + + pinmap_pinout(sda, PinMap_I2C_SDA); + pinmap_pinout(scl, PinMap_I2C_SCL); +} + +inline int i2c_start(i2c_t *obj) { + int status = 0; + // 8.1 Before master mode can be entered, I2CON must be initialised to: + // - I2EN STA STO SI AA - - + // - 1 0 0 0 x - - + // if AA = 0, it can't enter slave mode + i2c_conclr(obj, 1, 1, 1, 1); + + // The master mode may now be entered by setting the STA bit + // this will generate a start condition when the bus becomes free + i2c_conset(obj, 1, 0, 0, 1); + + i2c_wait_SI(obj); + status = i2c_status(obj); + + // Clear start bit now transmitted, and interrupt bit + i2c_conclr(obj, 1, 0, 0, 0); + return status; +} + +inline void i2c_stop(i2c_t *obj) { + // write the stop bit + i2c_conset(obj, 0, 1, 0, 0); + i2c_clear_SI(obj); + + // wait for STO bit to reset + while(I2C_CONSET(obj) & (1 << 4)); +} + + +static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) { + // write the data + I2C_DAT(obj) = value; + + // clear SI to init a send + i2c_clear_SI(obj); + + // wait and return status + i2c_wait_SI(obj); + return i2c_status(obj); +} + +static inline int i2c_do_read(i2c_t *obj, int last) { + // we are in state 0x40 (SLA+R tx'd) or 0x50 (data rx'd and ack) + if (last) { + i2c_conclr(obj, 0, 0, 0, 1); // send a NOT ACK + } else { + i2c_conset(obj, 0, 0, 0, 1); // send a ACK + } + + // accept byte + i2c_clear_SI(obj); + + // wait for it to arrive + i2c_wait_SI(obj); + + // return the data + return (I2C_DAT(obj) & 0xFF); +} + +void i2c_frequency(i2c_t *obj, int hz) { + // No peripheral clock divider on the M0 + uint32_t PCLK = SystemCoreClock; + + uint32_t pulse = PCLK / (hz * 2); + + // I2C Rate + I2C_SCLL(obj, pulse); + I2C_SCLH(obj, pulse); +} + +// The I2C does a read or a write as a whole operation +// There are two types of error conditions it can encounter +// 1) it can not obtain the bus +// 2) it gets error responses at part of the transmission +// +// We tackle them as follows: +// 1) we retry until we get the bus. we could have a "timeout" if we can not get it +// which basically turns it in to a 2) +// 2) on error, we use the standard error mechanisms to report/debug +// +// Therefore an I2C transaction should always complete. If it doesn't it is usually +// because something is setup wrong (e.g. wiring), and we don't need to programatically +// check for that + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + int count, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return status; + } + + status = i2c_do_write(obj, (address | 0x01), 1); + if (status != 0x40) { + i2c_stop(obj); + return status; + } + + // Read in all except last byte + for (count = 0; count < (length - 1); count++) { + int value = i2c_do_read(obj, 0); + status = i2c_status(obj); + if (status != 0x50) { + i2c_stop(obj); + return status; + } + data[count] = (char) value; + } + + // read in last byte + int value = i2c_do_read(obj, 1); + status = i2c_status(obj); + if (status != 0x58) { + i2c_stop(obj); + return status; + } + + data[count] = (char) value; + + // If not repeated start, send stop. + if (stop) { + i2c_stop(obj); + } + + return 0; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + int i, status; + + status = i2c_start(obj); + + if ((status != 0x10) && (status != 0x08)) { + i2c_stop(obj); + return status; + } + + status = i2c_do_write(obj, (address & 0xFE), 1); + if (status != 0x18) { + i2c_stop(obj); + return status; + } + + for (i=0; i= 0) && (idx <= 3)) { + addr = ((uint32_t)obj->i2c) + I2C_addr_offset[idx]; + *((uint32_t *) addr) = address & 0xFF; + } +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/objects.h b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/objects.h new file mode 100644 index 0000000000..0718498e8d --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/objects.h @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gpio_irq_s { + uint32_t ch; +}; + +struct port_s { + __IO uint32_t *reg_dir; + __IO uint32_t *reg_mpin; + PortName port; + uint32_t mask; +}; + +struct pwmout_s { + PWMName pwm; +}; + +struct serial_s { + LPC_UART_TypeDef *uart; + int index; +}; + +struct analogin_s { + ADCName adc; +}; + +struct i2c_s { + LPC_I2C_TypeDef *i2c; +}; + +struct spi_s { + LPC_SSP_TypeDef *spi; +}; + +#include "gpio_object.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pinmap.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pinmap.c new file mode 100644 index 0000000000..8006ca18f1 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pinmap.c @@ -0,0 +1,47 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include "pinmap.h" +#include "error.h" + +void pin_function(PinName pin, int function) { + if (pin == (uint32_t)NC) return; + + uint32_t offset = (uint32_t)pin & 0xff; + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + offset); + + // pin function bits: [2:0] -> 111 = (0x7) + *reg = (*reg & ~0x7) | (function & 0x7); +} + +void pin_mode(PinName pin, PinMode mode) { + if (pin == (uint32_t)NC) { return; } + + uint32_t offset = (uint32_t)pin & 0xff; + uint32_t drain = ((uint32_t) mode & (uint32_t) OpenDrain) >> 2; + + __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + offset); + uint32_t tmp = *reg; + + // pin mode bits: [4:3] -> 11000 = (0x3 << 3) + tmp &= ~(0x3 << 3); + tmp |= (mode & 0x3) << 3; + + // drain + tmp &= ~(0x1 << 10); + tmp |= drain << 10; + + *reg = tmp; +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/port_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/port_api.c new file mode 100644 index 0000000000..f39a420a33 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/port_api.c @@ -0,0 +1,75 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ + +#warning TODO(@toyowata) This platform doesn't support PortIn, PortOut and PortInOut +#if 0 + +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" + +PinName port_pin(PortName port, int pin_n) { + return (PinName)((port << PORT_SHIFT) | pin_n); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { + obj->port = port; + obj->mask = mask; + + LPC_GPIO_TypeDef *port_reg = (LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + ((int)port * 0x20)); + + port_reg->MASK = ~mask; + + obj->reg_out = &port_reg->PIN; + obj->reg_in = &port_reg->PIN; + obj->reg_dir = &port_reg->DIR; + + uint32_t i; + // The function is set per pin: reuse gpio logic + for (i=0; i<32; i++) { + if (obj->mask & (1<port, i)); + } + } + + port_dir(obj, dir); +} + +void port_mode(port_t *obj, PinMode mode) { + uint32_t i; + // The mode is set per pin: reuse pinmap logic + for (i=0; i<32; i++) { + if (obj->mask & (1<port, i), mode); + } + } +} + +void port_dir(port_t *obj, PinDirection dir) { + switch (dir) { + case PIN_INPUT : *obj->reg_dir &= ~obj->mask; break; + case PIN_OUTPUT: *obj->reg_dir |= obj->mask; break; + } +} + +void port_write(port_t *obj, int value) { + *obj->reg_mpin = value; +} + +int port_read(port_t *obj) { + return (*obj->reg_mpin); +} +#endif diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pwmout_api.c new file mode 100644 index 0000000000..1872302219 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/pwmout_api.c @@ -0,0 +1,183 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include "pwmout_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +#define TCR_CNT_EN 0x00000001 +#define TCR_RESET 0x00000002 + +/* To have a PWM where we can change both the period and the duty cycle, + * we need an entire timer. With the following conventions: + * * MR3 is used for the PWM period + * * MR0, MR1, MR2 are used for the duty cycle + */ +static const PinMap PinMap_PWM[] = { + /* CT16B0 */ + {P0_8 , PWM_1, 0x02}, /* MR0 */ + {P0_9 , PWM_2, 0x02}, /* MR1 */ + {P0_10, PWM_3, 0x03}, /* MR2 */ + + /* CT16B1 */ + {P1_9 , PWM_4, 0x01}, /* MR0 */ + {P1_10, PWM_5, 0x02}, /* MR1 */ + + /* CT32B0 */ + {P1_6 , PWM_6, 0x02}, /* MR0 */ + {P1_7 , PWM_7, 0x02}, /* MR1 */ + {P0_1 , PWM_8, 0x02}, /* MR2 */ + + /* CT32B1 */ + {P1_1 , PWM_9 ,0x03}, /* MR0 */ + {P1_2 , PWM_10,0x03}, /* MR1 */ + {P1_3 , PWM_11,0x03}, /* MR2 */ + + {NC , NC ,0x00} +}; + +typedef struct { + uint8_t timer; + uint8_t mr; +} timer_mr; + +static timer_mr pwm_timer_map[4] = { + {0, 0}, + {1, 0}, + {2, 0}, + {3, 0}, +}; + +static LPC_TMR_TypeDef *Timers[4] = { + LPC_TMR16B0, LPC_TMR16B1, + LPC_TMR32B0, LPC_TMR32B1 +}; + +static unsigned int pwm_clock_mhz; + +void pwmout_init(pwmout_t* obj, PinName pin) { + // determine the channel + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + if (pwm == (uint32_t)NC) + error("PwmOut pin mapping failed"); + + obj->pwm = pwm; + + // Timer registers + timer_mr tid = pwm_timer_map[pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + + // Disable timer + timer->TCR = 0; + + // Power the correspondent timer + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7); + + /* Enable PWM function */ + timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0); + + /* Reset Functionality on MR3 controlling the PWM period */ + timer->MCR = 1 << 10; + + pwm_clock_mhz = SystemCoreClock / 1000000; + + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + pwmout_write (obj, 0); + + // Wire pinout + pinmap_pinout(pin, PinMap_PWM); +} + +void pwmout_free(pwmout_t* obj) { + // [TODO] +} + +void pwmout_write(pwmout_t* obj, float value) { + if (value < 0.0f) { + value = 0.0; + } else if (value > 1.0f) { + value = 1.0; + } + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + uint32_t t_off = timer->MR3 - (uint32_t)((float)(timer->MR3) * value); + + timer->TCR = TCR_RESET; + timer->MR[tid.mr] = t_off; + timer->TCR = TCR_CNT_EN; +} + +float pwmout_read(pwmout_t* obj) { + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + + float v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3); + return (v > 1.0f) ? (1.0f) : (v); +} + +void pwmout_period(pwmout_t* obj, float seconds) { + pwmout_period_us(obj, seconds * 1000000.0f); +} + +void pwmout_period_ms(pwmout_t* obj, int ms) { + pwmout_period_us(obj, ms * 1000); +} + +// Set the PWM period, keeping the duty cycle the same. +void pwmout_period_us(pwmout_t* obj, int us) { + int i = 0; + uint32_t period_ticks = pwm_clock_mhz * us; + + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + uint32_t old_period_ticks = timer->MR3; + + timer->TCR = TCR_RESET; + timer->MR3 = period_ticks; + + // Scale the pulse width to preserve the duty ratio + if (old_period_ticks > 0) { + for (i=0; i<3; i++) { + uint32_t t_off = period_ticks - (uint32_t)(((uint64_t)timer->MR[i] * (uint64_t)period_ticks) / (uint64_t)old_period_ticks); + timer->MR[i] = t_off; + } + } + timer->TCR = TCR_CNT_EN; +} + +void pwmout_pulsewidth(pwmout_t* obj, float seconds) { + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); +} + +void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, int us) { + uint32_t t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000); + timer_mr tid = pwm_timer_map[obj->pwm]; + LPC_TMR_TypeDef *timer = Timers[tid.timer]; + + timer->TCR = TCR_RESET; + if (t_on > timer->MR3) { + pwmout_period_us(obj, us); + } + uint32_t t_off = timer->MR3 - t_on; + timer->MR[tid.mr] = t_off; + timer->TCR = TCR_CNT_EN; +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/serial_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/serial_api.c new file mode 100644 index 0000000000..df8b15338c --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/serial_api.c @@ -0,0 +1,276 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +// math.h required for floating point operations for baud rate calculation +#include +#include + +#include "serial_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +/****************************************************************************** + * INITIALIZATION + ******************************************************************************/ +#define UART_NUM 1 + +static const PinMap PinMap_UART_TX[] = { + {P2_8 , UART_0, 0x02}, + {P3_5 , UART_0, 0x02}, + {P3_0 , UART_0, 0x03}, + {P1_7 , UART_0, 0x01}, + {NC , NC , 0x00} +}; + +static const PinMap PinMap_UART_RX[] = { + {P2_7 , UART_0, 0x02}, + {P3_4 , UART_0, 0x02}, + {P3_1 , UART_0, 0x03}, + {P1_6 , UART_0, 0x01}, + {NC , NC , 0x00} +}; + +static uint32_t serial_irq_ids[UART_NUM] = {0}; +static uart_irq_handler irq_handler; + +int stdio_uart_inited = 0; +serial_t stdio_uart; + +void serial_init(serial_t *obj, PinName tx, PinName rx) { + int is_stdio_uart = 0; + + // determine the UART to use + UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); + UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); + UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx); + if ((int)uart == NC) { + error("Serial pinout mapping failed"); + } + + obj->uart = (LPC_UART_TypeDef *)uart; + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12); + + // enable fifos and default rx trigger level + obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled + | 0 << 1 // Rx Fifo Reset + | 0 << 2 // Tx Fifo Reset + | 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars + + // disable irqs + obj->uart->IER = 0 << 0 // Rx Data available irq enable + | 0 << 1 // Tx Fifo empty irq enable + | 0 << 2; // Rx Line Status irq enable + + // set default baud rate and format + serial_baud (obj, 9600); + serial_format(obj, 8, ParityNone, 1); + + // pinout the chosen uart + pinmap_pinout(tx, PinMap_UART_TX); + pinmap_pinout(rx, PinMap_UART_RX); + + // set rx/tx pins in PullUp mode + pin_mode(tx, PullUp); + pin_mode(rx, PullUp); + + switch (uart) { + case UART_0: obj->index = 0; break; + } + + is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); + + if (is_stdio_uart) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +} + +void serial_free(serial_t *obj) { + serial_irq_ids[obj->index] = 0; +} + +// serial_baud +// set the baud rate, taking in to account the current SystemFrequency +void serial_baud(serial_t *obj, int baudrate) { + LPC_SYSCON->UARTCLKDIV = 0x1; + uint32_t PCLK = SystemCoreClock; + // First we check to see if the basic divide with no DivAddVal/MulVal + // ratio gives us an integer result. If it does, we set DivAddVal = 0, + // MulVal = 1. Otherwise, we search the valid ratio value range to find + // the closest match. This could be more elegant, using search methods + // and/or lookup tables, but the brute force method is not that much + // slower, and is more maintainable. + uint16_t DL = PCLK / (16 * baudrate); + + uint8_t DivAddVal = 0; + uint8_t MulVal = 1; + int hit = 0; + uint16_t dlv; + uint8_t mv, dav; + if ((PCLK % (16 * baudrate)) != 0) { // Checking for zero remainder + float err_best = (float) baudrate; + uint16_t dlmax = DL; + for ( dlv = (dlmax/2); (dlv <= dlmax) && !hit; dlv++) { + for ( mv = 1; mv <= 15; mv++) { + for ( dav = 1; dav < mv; dav++) { + float ratio = 1.0f + ((float) dav / (float) mv); + float calcbaud = (float)PCLK / (16.0f * (float) dlv * ratio); + float err = fabs(((float) baudrate - calcbaud) / (float) baudrate); + if (err < err_best) { + DL = dlv; + DivAddVal = dav; + MulVal = mv; + err_best = err; + if (err < 0.001f) { + hit = 1; + } + } + } + } + } + } + + // set LCR[DLAB] to enable writing to divider registers + obj->uart->LCR |= (1 << 7); + + // set divider values + obj->uart->DLM = (DL >> 8) & 0xFF; + obj->uart->DLL = (DL >> 0) & 0xFF; + obj->uart->FDR = (uint32_t) DivAddVal << 0 + | (uint32_t) MulVal << 4; + + // clear LCR[DLAB] + obj->uart->LCR &= ~(1 << 7); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { + // 0: 1 stop bits, 1: 2 stop bits + if (stop_bits != 1 && stop_bits != 2) { + error("Invalid stop bits specified"); + } + stop_bits -= 1; + + // 0: 5 data bits ... 3: 8 data bits + if (data_bits < 5 || data_bits > 8) { + error("Invalid number of bits (%d) in serial format, should be 5..8", data_bits); + } + data_bits -= 5; + + int parity_enable, parity_select; + switch (parity) { + case ParityNone: parity_enable = 0; parity_select = 0; break; + case ParityOdd : parity_enable = 1; parity_select = 0; break; + case ParityEven: parity_enable = 1; parity_select = 1; break; + case ParityForced1: parity_enable = 1; parity_select = 2; break; + case ParityForced0: parity_enable = 1; parity_select = 3; break; + default: + error("Invalid serial parity setting"); + return; + } + + obj->uart->LCR = data_bits << 0 + | stop_bits << 2 + | parity_enable << 3 + | parity_select << 4; +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +static inline void uart_irq(uint32_t iir, uint32_t index) { + // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling + SerialIrq irq_type; + switch (iir) { + case 1: irq_type = TxIrq; break; + case 2: irq_type = RxIrq; break; + default: return; + } + + if (serial_irq_ids[index] != 0) + irq_handler(serial_irq_ids[index], irq_type); +} + +void uart0_irq() {uart_irq((LPC_UART->IIR >> 1) & 0x7, 0);} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { + irq_handler = handler; + serial_irq_ids[obj->index] = id; +} + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + switch ((int)obj->uart) { + case UART_0: + irq_n=UART_IRQn; + vector = (uint32_t)&uart0_irq; + break; + default: + return; + } + + if (enable) { + obj->uart->IER |= 1 << irq; + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + } else { // disable + int all_disabled = 0; + SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); + + obj->uart->IER &= ~(1 << irq); + all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; + + if (all_disabled) + NVIC_DisableIRQ(irq_n); + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ +int serial_getc(serial_t *obj) { + while (!serial_readable(obj)); + return obj->uart->RBR; +} + +void serial_putc(serial_t *obj, int c) { + while (!serial_writable(obj)); + obj->uart->THR = c; + +#warning TODO(@toyowata): need to fix a full-duplex bug? https://mbed.org/forum/bugs-suggestions/topic/4473/ + uint32_t lsr = obj->uart->LSR; + lsr = lsr; + uint32_t thr = obj->uart->THR; + thr = thr; +} + +int serial_readable(serial_t *obj) { + return obj->uart->LSR & 0x01; +} + +int serial_writable(serial_t *obj) { + return obj->uart->LSR & 0x20; +} + +void serial_clear(serial_t *obj) { + obj->uart->FCR = 1 << 1 // rx FIFO reset + | 1 << 2 // tx FIFO reset + | 0 << 6; // interrupt depth +} + +void serial_pinout_tx(PinName tx) { + pinmap_pinout(tx, PinMap_UART_TX); +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/sleep.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/sleep.c new file mode 100644 index 0000000000..051db5217b --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/sleep.c @@ -0,0 +1,75 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include "sleep_api.h" +#include "cmsis.h" +#include "mbed_interface.h" + +void sleep(void) { + // ensure debug is disconnected + mbed_interface_disconnect(); + + // PCON[DPDEN] set to sleep + LPC_PMU->PCON = 0x0; + + // SRC[SLEEPDEEP] set to 0 = sleep + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt + __WFI(); +} + +/* +* The mbed lpc1768 does not support the deepsleep mode +* as a debugger is connected to it (the mbed interface). +* +* As mentionned in an application note from NXP: +* +* http://www.po-star.com/public/uploads/20120319123122_141.pdf +* +* {{{ +* The user should be aware of certain limitations during debugging. +* The most important is that, due to limitations of the Cortex-M3 +* integration, the LPC17xx cannot wake up in the usual manner from +* Deep Sleep and Power-down modes. It is recommended not to use these +* modes during debug. Once an application is downloaded via JTAG/SWD +* interface, the USB to SWD/JTAG debug adapter (Keil ULINK2 for example) +* should be removed from the target board, and thereafter, power cycle +* the LPC17xx to allow wake-up from deep sleep and power-down modes +* }}} +* +* As the interface firmware does not reset the target when a +* mbed_interface_disconnect() semihosting call is made, the +* core cannot wake-up from deepsleep. +* +* We treat a deepsleep() as a normal sleep(). +*/ + +void deepsleep(void) { + // ensure debug is disconnected + mbed_interface_disconnect(); + + // PCON[DPDEN] set to deepsleep + LPC_PMU->PCON = 0x2; + + // SRC[SLEEPDEEP] set to 1 = deep sleep + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // Power up everything after powerdown + LPC_SYSCON->PDAWAKECFG &= 0xFFFFF800; + + // wait for interrupt + __WFI(); +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/spi_api.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/spi_api.c new file mode 100644 index 0000000000..a35895682c --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/spi_api.c @@ -0,0 +1,214 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include +#include "spi_api.h" +#include "cmsis.h" +#include "pinmap.h" +#include "error.h" + +static const PinMap PinMap_SPI_SCLK[] = { + {P0_6 , SPI_0, 0x02}, + {P0_10, SPI_0, 0x02}, + {P2_11, SPI_0, 0x01}, + {P2_1 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MOSI[] = { + {P0_9 , SPI_0, 0x01}, + {P2_3 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_MISO[] = { + {P0_8 , SPI_0, 0x01}, + {P2_2 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static const PinMap PinMap_SPI_SSEL[] = { + {P0_2 , SPI_0, 0x01}, + {P2_0 , SPI_1, 0x02}, + {NC , NC , 0} +}; + +static inline int ssp_disable(spi_t *obj); +static inline int ssp_enable(spi_t *obj); + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { + // determine the SPI to use + SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI); + SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); + SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); + SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); + SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); + SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); + + obj->spi = (LPC_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); + + if ((int)obj->spi == NC) { + error("SPI pinout mapping failed"); + } + + // enable power and clocking + switch ((int)obj->spi) { + case SPI_0: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 11; + LPC_SYSCON->SSP0CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 0; + break; + case SPI_1: + LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 18; + LPC_SYSCON->SSP1CLKDIV = 0x01; + LPC_SYSCON->PRESETCTRL |= 1 << 2; + break; + } + + // set default format and frequency + if (ssel == NC) { + spi_format(obj, 8, 0, 0); // 8 bits, mode 0, master + } else { + spi_format(obj, 8, 0, 1); // 8 bits, mode 0, slave + } + spi_frequency(obj, 1000000); + + // enable the ssp channel + ssp_enable(obj); + + // pin out the spi pins + pinmap_pinout(mosi, PinMap_SPI_MOSI); + pinmap_pinout(miso, PinMap_SPI_MISO); + pinmap_pinout(sclk, PinMap_SPI_SCLK); + if (ssel != NC) { + pinmap_pinout(ssel, PinMap_SPI_SSEL); + } +} + +void spi_free(spi_t *obj) {} + +void spi_format(spi_t *obj, int bits, int mode, int slave) { + ssp_disable(obj); + + if (!(bits >= 4 && bits <= 16) || !(mode >= 0 && mode <= 3)) { + error("SPI format error"); + } + + int polarity = (mode & 0x2) ? 1 : 0; + int phase = (mode & 0x1) ? 1 : 0; + + // set it up + int DSS = bits - 1; // DSS (data select size) + int SPO = (polarity) ? 1 : 0; // SPO - clock out polarity + int SPH = (phase) ? 1 : 0; // SPH - clock out phase + + int FRF = 0; // FRF (frame format) = SPI + uint32_t tmp = obj->spi->CR0; + tmp &= ~(0xFFFF); + tmp |= DSS << 0 + | FRF << 4 + | SPO << 6 + | SPH << 7; + obj->spi->CR0 = tmp; + + tmp = obj->spi->CR1; + tmp &= ~(0xD); + tmp |= 0 << 0 // LBM - loop back mode - off + | ((slave) ? 1 : 0) << 2 // MS - master slave mode, 1 = slave + | 0 << 3; // SOD - slave output disable - na + obj->spi->CR1 = tmp; + + ssp_enable(obj); +} + +void spi_frequency(spi_t *obj, int hz) { + ssp_disable(obj); + + uint32_t PCLK = SystemCoreClock; + + int prescaler; + + for (prescaler = 2; prescaler <= 254; prescaler += 2) { + int prescale_hz = PCLK / prescaler; + + // calculate the divider + int divider = floor(((float)prescale_hz / (float)hz) + 0.5f); + + // check we can support the divider + if (divider < 256) { + // prescaler + obj->spi->CPSR = prescaler; + + // divider + obj->spi->CR0 &= ~(0xFFFF << 8); + obj->spi->CR0 |= (divider - 1) << 8; + ssp_enable(obj); + return; + } + } + error("Couldn't setup requested SPI frequency"); +} + +static inline int ssp_disable(spi_t *obj) { + return obj->spi->CR1 &= ~(1 << 1); +} + +static inline int ssp_enable(spi_t *obj) { + return obj->spi->CR1 |= (1 << 1); +} + +static inline int ssp_readable(spi_t *obj) { + return obj->spi->SR & (1 << 2); +} + +static inline int ssp_writeable(spi_t *obj) { + return obj->spi->SR & (1 << 1); +} + +static inline void ssp_write(spi_t *obj, int value) { + while (!ssp_writeable(obj)); + obj->spi->DR = value; +} + +static inline int ssp_read(spi_t *obj) { + while (!ssp_readable(obj)); + return obj->spi->DR; +} + +static inline int ssp_busy(spi_t *obj) { + return (obj->spi->SR & (1 << 4)) ? (1) : (0); +} + +int spi_master_write(spi_t *obj, int value) { + ssp_write(obj, value); + return ssp_read(obj); +} + +int spi_slave_receive(spi_t *obj) { + return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); +}; + +int spi_slave_read(spi_t *obj) { + return obj->spi->DR; +} + +void spi_slave_write(spi_t *obj, int value) { + while (ssp_writeable(obj) == 0) ; + obj->spi->DR = value; +} + +int spi_busy(spi_t *obj) { + return ssp_busy(obj); +} diff --git a/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/us_ticker.c b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/us_ticker.c new file mode 100644 index 0000000000..b137293c22 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11XX/us_ticker.c @@ -0,0 +1,62 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * 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. + */ +#include +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define US_TICKER_TIMER ((LPC_TMR_TypeDef *)LPC_CT32B1_BASE) +#define US_TICKER_TIMER_IRQn TIMER_32_1_IRQn + +int us_ticker_inited = 0; + +void us_ticker_init(void) { + if (us_ticker_inited) return; + us_ticker_inited = 1; + + LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock TIMER_1 + uint32_t PCLK = SystemCoreClock; + + US_TICKER_TIMER->TCR = 0x2; // reset + + uint32_t prescale = PCLK / 1000000; // default to 1MHz (1 us ticks) + US_TICKER_TIMER->PR = prescale - 1; + US_TICKER_TIMER->TCR = 1; // enable = 1, reset = 0 + + NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); +} + +uint32_t us_ticker_read() { + if (!us_ticker_inited) + us_ticker_init(); + + return US_TICKER_TIMER->TC; +} + +void us_ticker_set_interrupt(unsigned int timestamp) { + // set match value + US_TICKER_TIMER->MR0 = timestamp; + // enable match interrupt + US_TICKER_TIMER->MCR |= 1; +} + +void us_ticker_disable_interrupt(void) { + US_TICKER_TIMER->MCR &= ~1; +} + +void us_ticker_clear_interrupt(void) { + US_TICKER_TIMER->IR = 1; +} diff --git a/workspace_tools/settings.py b/workspace_tools/settings.py index e60a10c16e..189e3d0fb1 100644 --- a/workspace_tools/settings.py +++ b/workspace_tools/settings.py @@ -29,6 +29,10 @@ MUTs = { "port":"COM44", "disk":'H:\\', "peripherals": ["TMP102", "digital_loop", "port_loop", "analog_loop", "SD"] }, + "5" : {"mcu": "LPC1114", + "port":"COM45", "disk":"I:\\", + "peripherals": ["TMP102", "digital_loop", "port_loop", "analog_loop", "SD"] + } } # ARM @@ -56,7 +60,7 @@ ARM_CPPLIB = join(ARM_LIB, "cpplib") MY_ARM_CLIB = join(ARM_PATH, "lib", "microlib") # GCC ARM -GCC_ARM_PATH = "C:/arm-none-eabi-gcc-4_7/bin" +GCC_ARM_PATH = "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\4.7 2013q2\\bin" # GCC CodeSourcery GCC_CS_PATH = "C:/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin" diff --git a/workspace_tools/targets.py b/workspace_tools/targets.py index ef1c88029e..7dbacb9b32 100644 --- a/workspace_tools/targets.py +++ b/workspace_tools/targets.py @@ -173,6 +173,15 @@ class LPC1347(Target): self.supported_toolchains = ["ARM", "GCC_ARM"] +class LPC1114(Target): + def __init__(self): + Target.__init__(self) + + self.core = "Cortex-M0" + self.extra_labels = ['NXP', 'LPC11XX'] + + self.supported_toolchains = ["ARM", "uARM", "GCC_CR", "GCC_ARM"] + # Get a single instance for each target TARGETS = [ LPC2368(), @@ -185,7 +194,8 @@ TARGETS = [ LPC4330_M4(), STM32F407(), MBED_MCU(), - LPC1347() + LPC1347(), + LPC1114() ] # Map each target name to its unique instance