first commit

This commit is contained in:
valeh
2020-12-22 14:30:09 +02:00
commit 26b0ba5954
1832 changed files with 17777948 additions and 0 deletions

View File

@@ -0,0 +1,145 @@
#
# Generic and Simple GNU ARM Makefile
#
# Desinged for the gnu-arm-none-eabi tool chain
#
# Features
# - create hex file
# - create assembler listing (.dis)
#
# Limitations
# - only C-files supported
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
#
# Targets:
# make
# create hex file, no upload
# make upload
# create and upload hex file
# make clean
# delete all generated files
#
# Note:
# Display list make database: make -p -f/dev/null | less
#
#================================================
# External tools
# The base directory of gcc-arm-none-eabi
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
# If set, GCCBINPATH must contain a "/" at the end.
GCCBINPATH:=/usr/bin/
#================================================
# Project Information
# The name for the project
TARGETNAME:=blink
# The source files of the project
SRC:=$(wildcard *.c)
# The CPU architecture (will be used for -mcpu)
# for the LPC804, can we use "cortex-m0plus" instead of "cortex-m0"?
MCPU:=cortex-m0plus
# Include directory for the system include files
SYSINC:=../lpc_chip_804/inc
SYSSRC:=$(wildcard ../lpc_chip_804/src/*.c)
# Include directory for the u8g2 include files
#U8G2INC:=../../../../csrc/
#U8G2SRC:=$(wildcard ../../../../csrc/*.c)
# directory for FatFS
#FFINC:=../fatfs
#FFSRC:=$(wildcard ../fatfs/*.c)
# Directory for the linker script
LDSCRIPTDIR:=.
# Name of the linker script (must be the "keep" script, because the other script is not always working)
LDSCRIPT:=lpc804.ld
#================================================
# Main part of the Makefile starts here. Usually no changes are needed.
# Internal Variable Names
LIBNAME:=$(TARGETNAME).a
ELFNAME:=$(TARGETNAME).elf
HEXNAME:=$(TARGETNAME).hex
DISNAME:=$(TARGETNAME).dis
MAPNAME:=$(TARGETNAME).map
OBJ:=$(SRC:.c=.o) $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o) $(FFSRC:.c=.o)
# Replace standard build tools by arm tools
CC:=$(GCCBINPATH)arm-none-eabi-gcc
AR:=$(GCCBINPATH)arm-none-eabi-ar
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
SIZE:=$(GCCBINPATH)arm-none-eabi-size
# Common flags
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
# define stack size (defaults to 0x0100)
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
# COMMON_FLAGS += -Os -flto
COMMON_FLAGS += -Os
# COMMON_FLAGS += -fstack-protector
# COMMON_FLAGS += -finstrument-functions
# Do not use stand libs startup code. Uncomment this for gcclib procedures
# memcpy still works, but might be required for __aeabi_uidiv
# COMMON_FLAGS += -nostdlib
# remove unused data and function
COMMON_FLAGS += -ffunction-sections -fdata-sections
# COMMON_FLAGS += -ffunction-sections -fdata-sections -fshort-wchar
# C flags
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
# LD flags
# remove unreferenced procedures and variables, but keep "arm_stack_area" and __isr_vector
GC:=-Wl,--gc-sections -Wl,--undefined=arm_stack_area -Wl,--undefined=__isr_vector
MAP:=-Wl,-Map=$(MAPNAME)
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
#LDLIBS:=--specs=nano.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
LDLIBS:=--specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
# Additional Suffixes
.SUFFIXES: .elf .hex .bin .dis
# Targets
.PHONY: all
all: $(DISNAME) $(HEXNAME)
$(SIZE) $(ELFNAME)
.PHONY: upload
upload: $(DISNAME) $(HEXNAME) $(ELFNAME)
$(SIZE) $(ELFNAME)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) libssp.a libssp_nonshared.a
# implicit rules
.elf.hex:
$(OBJCOPY) -O ihex $< $@
# explicit rules
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
$(DISNAME): $(ELFNAME)
$(OBJDUMP) -D -S $< > $@
# create empty ssp libs for -fstack-protector-all -fstack-protector
libssp.a:
$(AR) rcs $@
libssp_nonshared.a:
$(AR) rcs $@

View File

@@ -0,0 +1,129 @@
/*
delay.c
The delay function delay_micro_seconds() will use the global variable
SystemCoreClock. A call to SystemCoreClockUpdate() is required before
using delay_micro_seconds().
LPC804 Project
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <LPC8xx.h>
/* Generic ARM delay procedure, based on the system timer (SysTick) */
/*
Delay by the provided number of system ticks.
The delay must be smaller than the RELOAD value.
This delay has an imprecision of about +/- 20 system ticks.
*/
static void _delay_system_ticks_sub(uint32_t sys_ticks)
{
uint32_t start_val, end_val, curr_val;
uint32_t load;
start_val = SysTick->VAL;
start_val &= 0x0ffffffUL;
end_val = start_val;
if ( end_val < sys_ticks )
{
/* check, if the operation after this if clause would lead to a negative result */
/* if this would be the case, then add the reload value first */
load = SysTick->LOAD;
load &= 0x0ffffffUL;
end_val += load;
}
/* counter goes towards zero, so end_val is below start value */
end_val -= sys_ticks;
/* wait until interval is left */
if ( start_val >= end_val )
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val )
break;
if ( curr_val > start_val )
break;
}
}
else
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val && curr_val > start_val )
break;
}
}
}
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks)
{
uint32_t load4;
load4 = SysTick->LOAD;
load4 &= 0x0ffffffUL;
load4 >>= 2;
while ( sys_ticks > load4 )
{
sys_ticks -= load4;
_delay_system_ticks_sub(load4);
}
_delay_system_ticks_sub(sys_ticks);
}
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us)
{
uint32_t sys_ticks;
sys_ticks = main_clk;
sys_ticks /=1000000UL;
sys_ticks *= us;
delay_system_ticks(sys_ticks);
}

View File

@@ -0,0 +1,55 @@
/*
delay.h
LPC11U3x GPS Logger (https://github.com/olikraus/lpc11u3x-gps-logger)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#ifndef _DELAY_H
#define _DELAY_H
#include <stdint.h>
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks);
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us);
#endif /* _DELAY_H */

View File

@@ -0,0 +1,177 @@
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld */
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
/* LPC804 */
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x8000 /* 32K for LPC804 */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x1000 /* 4K for LPC804 */
}
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/sections.ld */
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
/* entry point */
ENTRY(Reset_Handler)
/* extern declaration so that the value appears correctly for the LPC checksum calculation */
EXTERN(NMI_Handler)
EXTERN(HardFault_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/*
http://www.lpcware.com/content/forum/lpc1788-flash-signature-generation
Section 3.5.2/page 12 of the LPC82x User Manual
Linker works with even addresses, however to indicate thumb address mode,
the lowest bit of the address is set to one. For the checksum calculation we
only have the even addresses, however later in the isr table the compiler will
store the odd addresses for the three handler subprocedures if compiled in
thumb mode. Because of this, 3 is added to consider the three odd handler calls.
*/
LPC_checksum = 0- (__StackTop + Reset_Handler + NMI_Handler + HardFault_Handler + 3 /* three entries */);
}

View File

@@ -0,0 +1,61 @@
#include <LPC8xx.h>
#include <syscon.h>
#include <gpio.h>
#include <delay.h>
/*=======================================================================*/
/* Configuration */
#define SYS_TICK_PERIOD_IN_MS 100
/*=======================================================================*/
/* system procedures and sys tick master task */
volatile uint32_t sys_tick_irq_cnt=0;
void __attribute__ ((interrupt)) SysTick_Handler(void)
{
sys_tick_irq_cnt++;
}
/*=======================================================================*/
/*
setup the hardware and start interrupts.
called by "Reset_Handler"
*/
int __attribute__ ((noinline)) main(void)
{
/* call to the lpc lib setup procedure. This will set the IRC as clk src and main clk to 24 MHz */
SystemInit();
/* if the clock or PLL has been changed, also update the global variable SystemCoreClock */
SystemCoreClockUpdate();
/* set systick and start systick interrupt */
SysTick_Config(main_clk/1000UL*(unsigned long)SYS_TICK_PERIOD_IN_MS);
/* */
GPIOInit();
/* enable clock for several subsystems */
Enable_Periph_Clock(CLK_IOCON);
Enable_Periph_Clock(CLK_SWM);
GPIOSetDir( PORT0, 15, OUTPUT);
for(;;)
{
GPIOSetBitValue(PORT0, 15, 1);
delay_micro_seconds(1000000);
GPIOSetBitValue(PORT0, 15, 0);
delay_micro_seconds(1000000);
}
}

View File

@@ -0,0 +1,201 @@
/*
startup.c
LPC804
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
Requires code from the LPC804 example zip files
*/
#include <LPC8xx.h>
/*=======================================================================*/
/* external functions */
void __attribute__ ((interrupt)) SysTick_Handler(void);
//void __attribute__ ((interrupt, used)) UART_IRQ(void);
int __attribute__ ((noinline)) main(void);
/*=======================================================================*/
/*
Reserve some space for the stack. This is used to check if global variables + stack exceed RAM size.
If -Wl,--gc-sections is used, then also define -Wl,--undefined=arm_stack_area to keep the variable in RAM.
The name of the variable (here: arm_stack_area) does not matter.
Heap (=dynamic memory allocation) is not supported
*/
#ifndef __STACK_SIZE
#define __STACK_SIZE 0x100
#endif
unsigned char arm_stack_area[__STACK_SIZE] __attribute__ ((section(".stack"))) __attribute__ ((aligned(8)));
/*=======================================================================*/
/* isr system procedures */
/* make the top of the stack known to the c compiler, value will be calculated by the linker script */
void __StackTop(void);
void __attribute__ ((interrupt)) __attribute__ ((noreturn)) Reset_Handler(void)
{
register unsigned long *ptr;
register unsigned long *start;
register unsigned long *end;
/*
The following two operations are not required in normal mode reset mode,
however it is usefull if the reset handler is started via ISP "Go" command
*/
__set_MSP((uint32_t)__StackTop);
//Chip_SYSCTL_Map(2);
LPC_SYSCON->SYSMEMREMAP = (uint32_t) 2; // user flash mode: use user isr vector table
/*
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.
*/
extern unsigned long __data_start__[];
extern unsigned long __data_end__[];
extern unsigned long __etext[];
ptr = __etext;
start = __data_start__;
end = __data_end__;
while( start < end )
{
*start = *ptr;
start++;
ptr++;
}
/*
Loop to zero out BSS section, which uses following symbols
in linker script:
__bss_start__: start of BSS section. Must align to 4
__bss_end__: end of BSS section. Must align to 4
*/
extern unsigned long __bss_start__[];
extern unsigned long __bss_end__[];
ptr = __bss_start__;
end = __bss_end__;
while( ptr < end )
{
*ptr = 0;
ptr++;
}
/* Call main procedure */
main();
/* finished, do nothing. */
for(;;)
;
}
/* "NMI_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) NMI_Handler(void)
{
}
/* "HardFault_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) HardFault_Handler(void)
{
}
/* make the checksum known to the c compiler, value will be calculated by the linker script */
void LPC_checksum(void);
/*=======================================================================*/
/* isr vector */
/* based on LPC8xx.h */
/* see table 38 of the LPC804 user manual (page 39) */
typedef void (*isr_handler_t)(void);
isr_handler_t __isr_vector[48] __attribute__ ((section(".isr_vector"))) __attribute__ ((aligned(4)))=
{
__StackTop, /* 0x00: Top of Stack, calculated by the linker script */
Reset_Handler, /* -15, 0x04: Reset Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
NMI_Handler, /* .14, 0x08: NMI Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
HardFault_Handler, /* -13, 0x0c: Hard Fault Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
0, /* 0x10: Reserved, must be 0 */
0, /* 0x14: Reserved, must be 0 */
0, /* 0x18: Reserved, must be 0 */
LPC_checksum, /* 0x1c: Checksum, calculated by the linker script or the flash utility */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* -5, SVCall Handler */
0, /* -4, Reserved */
0, /* -3, Reserved */
0, /* -2, PendSV Handler */
SysTick_Handler, /* -1, SysTick Handler */
0, /* 0 SPI0_IRQn, SPI0 controller */
0, /* 1 Not used/Reserved */
0, /* 2 DAC0_IRQn, DAC0 Interrupt */
0, /* 3 UART0_IRQn, USART0 */
0, /* 4 UART1_IRQn, USART1 */
0, /* 5 Not used */
0, /* 6 Not used */
0, /* 7 I2C1 controller */
0, /* 8 I2C0 controller */
0, /* 9 Not used/Reserved */
0, /* 10 MRT_IRQnMulti-Rate Timer */
0, /* 11 CMP_IRQn, Analog Comparator /CapTouch*/
0, /* 12 WDT_IRQn WDT */
0, /* 13 BOD_IRQn BOD Brown Out Detect */
0, /* 14 FLASH_IRQn (/Reserved according to the user manual) */
0, /* 15 WKT_IRQn Self wake-up timer */
0, /* 16 ADC_SEQA_IRQn */
0, /* 17 ADC_SEQB_IRQn */
0, /* 18 ADC_THCMP_IRQn ADC threshold compare */
0, /* 19 ADC_OVR_IRQn ADC overrun */
0, /* 20 Not used/Reserved */
0, /* 21 Not used/Reserved */
0, /* 22 Not used/Reserved */
0, /* 23 CTIMER0_IRQn, CT32B0_IRQ */
0, /* 24 PIO INT0 */
0, /* 25 PIO INT1 */
0, /* 26 PIO INT2 */
0, /* 27 PIO INT3 */
0, /* 28 PIO INT4 */
0, /* 29 PIO INT5 */
0, /* 30 PIO INT6 */
0 /* 31 PIO INT7 */
};

View File

@@ -0,0 +1,145 @@
#
# Generic and Simple GNU ARM Makefile
#
# Desinged for the gnu-arm-none-eabi tool chain
#
# Features
# - create hex file
# - create assembler listing (.dis)
#
# Limitations
# - only C-files supported
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
#
# Targets:
# make
# create hex file, no upload
# make upload
# create and upload hex file
# make clean
# delete all generated files
#
# Note:
# Display list make database: make -p -f/dev/null | less
#
#================================================
# External tools
# The base directory of gcc-arm-none-eabi
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
# If set, GCCBINPATH must contain a "/" at the end.
GCCBINPATH:=/usr/bin/
#================================================
# Project Information
# The name for the project
TARGETNAME:=ctimer
# The source files of the project
SRC:=$(wildcard *.c)
# The CPU architecture (will be used for -mcpu)
# for the LPC804, can we use "cortex-m0plus" instead of "cortex-m0"?
MCPU:=cortex-m0plus
# Include directory for the system include files
SYSINC:=../lpc_chip_804/inc
SYSSRC:=$(wildcard ../lpc_chip_804/src/*.c)
# Include directory for the u8g2 include files
#U8G2INC:=../../../../csrc/
#U8G2SRC:=$(wildcard ../../../../csrc/*.c)
# directory for FatFS
#FFINC:=../fatfs
#FFSRC:=$(wildcard ../fatfs/*.c)
# Directory for the linker script
LDSCRIPTDIR:=.
# Name of the linker script (must be the "keep" script, because the other script is not always working)
LDSCRIPT:=lpc804.ld
#================================================
# Main part of the Makefile starts here. Usually no changes are needed.
# Internal Variable Names
LIBNAME:=$(TARGETNAME).a
ELFNAME:=$(TARGETNAME).elf
HEXNAME:=$(TARGETNAME).hex
DISNAME:=$(TARGETNAME).dis
MAPNAME:=$(TARGETNAME).map
OBJ:=$(SRC:.c=.o) $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o) $(FFSRC:.c=.o)
# Replace standard build tools by arm tools
CC:=$(GCCBINPATH)arm-none-eabi-gcc
AR:=$(GCCBINPATH)arm-none-eabi-ar
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
SIZE:=$(GCCBINPATH)arm-none-eabi-size
# Common flags
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
# define stack size (defaults to 0x0100)
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
# COMMON_FLAGS += -Os -flto
COMMON_FLAGS += -Os
# COMMON_FLAGS += -fstack-protector
# COMMON_FLAGS += -finstrument-functions
# Do not use stand libs startup code. Uncomment this for gcclib procedures
# memcpy still works, but might be required for __aeabi_uidiv
# COMMON_FLAGS += -nostdlib
# remove unused data and function
COMMON_FLAGS += -ffunction-sections -fdata-sections
# COMMON_FLAGS += -ffunction-sections -fdata-sections -fshort-wchar
# C flags
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
# LD flags
# remove unreferenced procedures and variables, but keep "arm_stack_area" and __isr_vector
GC:=-Wl,--gc-sections -Wl,--undefined=arm_stack_area -Wl,--undefined=__isr_vector
MAP:=-Wl,-Map=$(MAPNAME)
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
#LDLIBS:=--specs=nano.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
LDLIBS:=--specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
# Additional Suffixes
.SUFFIXES: .elf .hex .bin .dis
# Targets
.PHONY: all
all: $(DISNAME) $(HEXNAME)
$(SIZE) $(ELFNAME)
.PHONY: upload
upload: $(DISNAME) $(HEXNAME) $(ELFNAME)
$(SIZE) $(ELFNAME)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) libssp.a libssp_nonshared.a
# implicit rules
.elf.hex:
$(OBJCOPY) -O ihex $< $@
# explicit rules
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
$(DISNAME): $(ELFNAME)
$(OBJDUMP) -D -S $< > $@
# create empty ssp libs for -fstack-protector-all -fstack-protector
libssp.a:
$(AR) rcs $@
libssp_nonshared.a:
$(AR) rcs $@

View File

@@ -0,0 +1,129 @@
/*
delay.c
The delay function delay_micro_seconds() will use the global variable
SystemCoreClock. A call to SystemCoreClockUpdate() is required before
using delay_micro_seconds().
LPC804 Project
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <LPC8xx.h>
/* Generic ARM delay procedure, based on the system timer (SysTick) */
/*
Delay by the provided number of system ticks.
The delay must be smaller than the RELOAD value.
This delay has an imprecision of about +/- 20 system ticks.
*/
static void _delay_system_ticks_sub(uint32_t sys_ticks)
{
uint32_t start_val, end_val, curr_val;
uint32_t load;
start_val = SysTick->VAL;
start_val &= 0x0ffffffUL;
end_val = start_val;
if ( end_val < sys_ticks )
{
/* check, if the operation after this if clause would lead to a negative result */
/* if this would be the case, then add the reload value first */
load = SysTick->LOAD;
load &= 0x0ffffffUL;
end_val += load;
}
/* counter goes towards zero, so end_val is below start value */
end_val -= sys_ticks;
/* wait until interval is left */
if ( start_val >= end_val )
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val )
break;
if ( curr_val > start_val )
break;
}
}
else
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val && curr_val > start_val )
break;
}
}
}
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks)
{
uint32_t load4;
load4 = SysTick->LOAD;
load4 &= 0x0ffffffUL;
load4 >>= 2;
while ( sys_ticks > load4 )
{
sys_ticks -= load4;
_delay_system_ticks_sub(load4);
}
_delay_system_ticks_sub(sys_ticks);
}
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us)
{
uint32_t sys_ticks;
sys_ticks = main_clk;
sys_ticks /=1000000UL;
sys_ticks *= us;
delay_system_ticks(sys_ticks);
}

View File

@@ -0,0 +1,55 @@
/*
delay.h
LPC11U3x GPS Logger (https://github.com/olikraus/lpc11u3x-gps-logger)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#ifndef _DELAY_H
#define _DELAY_H
#include <stdint.h>
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks);
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us);
#endif /* _DELAY_H */

View File

@@ -0,0 +1,177 @@
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld */
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
/* LPC804 */
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x8000 /* 32K for LPC804 */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x1000 /* 4K for LPC804 */
}
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/sections.ld */
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
/* entry point */
ENTRY(Reset_Handler)
/* extern declaration so that the value appears correctly for the LPC checksum calculation */
EXTERN(NMI_Handler)
EXTERN(HardFault_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/*
http://www.lpcware.com/content/forum/lpc1788-flash-signature-generation
Section 3.5.2/page 12 of the LPC82x User Manual
Linker works with even addresses, however to indicate thumb address mode,
the lowest bit of the address is set to one. For the checksum calculation we
only have the even addresses, however later in the isr table the compiler will
store the odd addresses for the three handler subprocedures if compiled in
thumb mode. Because of this, 3 is added to consider the three odd handler calls.
*/
LPC_checksum = 0- (__StackTop + Reset_Handler + NMI_Handler + HardFault_Handler + 3 /* three entries */);
}

View File

@@ -0,0 +1,98 @@
/*
use ctimer to do a LED blink
*/
#include <LPC8xx.h>
#include <iocon.h>
#include <syscon.h>
#include <gpio.h>
#include <swm.h>
#include <ctimer.h>
#include <delay.h>
/*=======================================================================*/
/* Configuration */
#define SYS_TICK_PERIOD_IN_MS 100
/*=======================================================================*/
/* system procedures and sys tick master task */
volatile uint32_t sys_tick_irq_cnt=0;
void __attribute__ ((interrupt)) SysTick_Handler(void)
{
sys_tick_irq_cnt++;
}
/*=======================================================================*/
/*
replacement for ConfigSWM(uint32_t func, uint32_t port_pin)
Args:
fn: A function number, e.g. T0_MAT0, see swm.h
port: A port number for the GPIO port (0..30)
*/
void mapFunctionToPort(uint32_t fn, uint32_t port)
{
/* first reset the pin assignment to 0xff (this is also the reset value */
LPC_SWM->PINASSIGN[fn/4] |= ((0xffUL)<<(8*(fn%4)));
/* then write the destination pin to it */
LPC_SWM->PINASSIGN[fn/4] &= ~((port^255UL)<<(8*(fn%4)));
}
/*=======================================================================*/
/*
setup the hardware and start interrupts.
called by "Reset_Handler"
*/
int __attribute__ ((noinline)) main(void)
{
/* call to the lpc lib setup procedure. This will set the IRC as clk src and main clk to 24 MHz */
SystemInit();
/* if the clock or PLL has been changed, also update the global variable SystemCoreClock */
SystemCoreClockUpdate();
/* set systick and start systick interrupt */
SysTick_Config(main_clk/1000UL*(unsigned long)SYS_TICK_PERIOD_IN_MS);
/* init GPIOs */
GPIOInit();
/* enable clock for several subsystems */
Enable_Periph_Clock(CLK_IOCON);
Enable_Periph_Clock(CLK_SWM);
Enable_Periph_Clock(CLK_CTIMER0);
GPIOSetDir( PORT0, 15, OUTPUT);
LPC_CTIMER0->PR = 0; /* no prescale */
LPC_CTIMER0->MR[3] = 15000000; /* PWM cycle length: one second with 15MHz AHB clock */
LPC_CTIMER0->MCR |= 1<<MR3R; /* Use MR3 value to reset the counter: MR3 is the upper value and sets the PWM cycle */
LPC_CTIMER0->MR[0] = 14000000; /* PWM duty cycle in MR0 */
LPC_CTIMER0->PWMC |= 1<<PWMEN0; /* PWM mode for MR0 */
/* invert output, will only work with PIO0_30, not with PIO0_15 */
LPC_IOCON->PIO0_30 |= 1<<IOCON_INV;
/* connect subsystems to the GPIOs */
/* Just for testing: The signal is routed via PIN0_30 */
mapFunctionToPort(T0_MAT0, 30);
mapFunctionToPort(LVLSHFT_IN0, 30);
mapFunctionToPort(LVLSHFT_OUT0, 15);
/* enable the timer */
LPC_CTIMER0->TCR |= 1<<CEN;
}

View File

@@ -0,0 +1,201 @@
/*
startup.c
LPC804
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
Requires code from the LPC804 example zip files
*/
#include <LPC8xx.h>
/*=======================================================================*/
/* external functions */
void __attribute__ ((interrupt)) SysTick_Handler(void);
//void __attribute__ ((interrupt, used)) UART_IRQ(void);
int __attribute__ ((noinline)) main(void);
/*=======================================================================*/
/*
Reserve some space for the stack. This is used to check if global variables + stack exceed RAM size.
If -Wl,--gc-sections is used, then also define -Wl,--undefined=arm_stack_area to keep the variable in RAM.
The name of the variable (here: arm_stack_area) does not matter.
Heap (=dynamic memory allocation) is not supported
*/
#ifndef __STACK_SIZE
#define __STACK_SIZE 0x100
#endif
unsigned char arm_stack_area[__STACK_SIZE] __attribute__ ((section(".stack"))) __attribute__ ((aligned(8)));
/*=======================================================================*/
/* isr system procedures */
/* make the top of the stack known to the c compiler, value will be calculated by the linker script */
void __StackTop(void);
void __attribute__ ((interrupt)) __attribute__ ((noreturn)) Reset_Handler(void)
{
register unsigned long *ptr;
register unsigned long *start;
register unsigned long *end;
/*
The following two operations are not required in normal mode reset mode,
however it is usefull if the reset handler is started via ISP "Go" command
*/
__set_MSP((uint32_t)__StackTop);
//Chip_SYSCTL_Map(2);
LPC_SYSCON->SYSMEMREMAP = (uint32_t) 2; // user flash mode: use user isr vector table
/*
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.
*/
extern unsigned long __data_start__[];
extern unsigned long __data_end__[];
extern unsigned long __etext[];
ptr = __etext;
start = __data_start__;
end = __data_end__;
while( start < end )
{
*start = *ptr;
start++;
ptr++;
}
/*
Loop to zero out BSS section, which uses following symbols
in linker script:
__bss_start__: start of BSS section. Must align to 4
__bss_end__: end of BSS section. Must align to 4
*/
extern unsigned long __bss_start__[];
extern unsigned long __bss_end__[];
ptr = __bss_start__;
end = __bss_end__;
while( ptr < end )
{
*ptr = 0;
ptr++;
}
/* Call main procedure */
main();
/* finished, do nothing. */
for(;;)
;
}
/* "NMI_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) NMI_Handler(void)
{
}
/* "HardFault_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) HardFault_Handler(void)
{
}
/* make the checksum known to the c compiler, value will be calculated by the linker script */
void LPC_checksum(void);
/*=======================================================================*/
/* isr vector */
/* based on LPC8xx.h */
/* see table 38 of the LPC804 user manual (page 39) */
typedef void (*isr_handler_t)(void);
isr_handler_t __isr_vector[48] __attribute__ ((section(".isr_vector"))) __attribute__ ((aligned(4)))=
{
__StackTop, /* 0x00: Top of Stack, calculated by the linker script */
Reset_Handler, /* -15, 0x04: Reset Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
NMI_Handler, /* .14, 0x08: NMI Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
HardFault_Handler, /* -13, 0x0c: Hard Fault Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
0, /* 0x10: Reserved, must be 0 */
0, /* 0x14: Reserved, must be 0 */
0, /* 0x18: Reserved, must be 0 */
LPC_checksum, /* 0x1c: Checksum, calculated by the linker script or the flash utility */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* -5, SVCall Handler */
0, /* -4, Reserved */
0, /* -3, Reserved */
0, /* -2, PendSV Handler */
SysTick_Handler, /* -1, SysTick Handler */
0, /* 0 SPI0_IRQn, SPI0 controller */
0, /* 1 Not used/Reserved */
0, /* 2 DAC0_IRQn, DAC0 Interrupt */
0, /* 3 UART0_IRQn, USART0 */
0, /* 4 UART1_IRQn, USART1 */
0, /* 5 Not used */
0, /* 6 Not used */
0, /* 7 I2C1 controller */
0, /* 8 I2C0 controller */
0, /* 9 Not used/Reserved */
0, /* 10 MRT_IRQnMulti-Rate Timer */
0, /* 11 CMP_IRQn, Analog Comparator /CapTouch*/
0, /* 12 WDT_IRQn WDT */
0, /* 13 BOD_IRQn BOD Brown Out Detect */
0, /* 14 FLASH_IRQn (/Reserved according to the user manual) */
0, /* 15 WKT_IRQn Self wake-up timer */
0, /* 16 ADC_SEQA_IRQn */
0, /* 17 ADC_SEQB_IRQn */
0, /* 18 ADC_THCMP_IRQn ADC threshold compare */
0, /* 19 ADC_OVR_IRQn ADC overrun */
0, /* 20 Not used/Reserved */
0, /* 21 Not used/Reserved */
0, /* 22 Not used/Reserved */
0, /* 23 CTIMER0_IRQn, CT32B0_IRQ */
0, /* 24 PIO INT0 */
0, /* 25 PIO INT1 */
0, /* 26 PIO INT2 */
0, /* 27 PIO INT3 */
0, /* 28 PIO INT4 */
0, /* 29 PIO INT5 */
0, /* 30 PIO INT6 */
0 /* 31 PIO INT7 */
};

View File

@@ -0,0 +1,17 @@
#
# hex2lpc: Linux flash utility for LPC8xx devices
#
CFLAGS = -g -pg -Wall
#CFLAGS = -O4 -Wall
SRC = hex2lpc.c
OBJ = $(SRC:.c=.o)
hex2lpc: $(SRC)
$(CC) -Wall -g $(LDFLAGS) $(SRC) -o hex2lpc
clean:
-rm ./hex2lpc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,772 @@
// Attention please!
// This is the header file for the LPC80x product family only.
/****************************************************************************
* $Id:: LPC8xx.h 6437 2012-10-31 11:06:06Z dep00694 $
* Project: NXP LPC8xx software example
*
* Description:
* CMSIS Cortex-M0+ Core Peripheral Access Layer Header File for
* NXP LPC800 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 __LPC8xx_H__
#define __LPC8xx_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup LPC8xx_Definitions LPC8xx Definitions
This file defines all structures and symbols for LPC8xx:
- Registers and bitfields
- peripheral base address
- PIO definitions
@{
*/
/******************************************************************************/
/* Processor and Core Peripherals */
/******************************************************************************/
/** @addtogroup LPC8xx_CMSIS LPC8xx CMSIS Definitions
Configuration of the Cortex-M0+ Processor and Core Peripherals
@{
*/
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/
Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset*/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */
PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
/****** LPC80x Specific Interrupt Numbers ********************************************************/
SPI0_IRQn = 0, /*!< SPI0 */
DAC0_IRQn = 2, /*!< DAC0 Interrupt */
UART0_IRQn = 3, /*!< USART0 */
UART1_IRQn = 4, /*!< USART1 */
I2C1_IRQn = 7, /*!< I2C1 */
I2C0_IRQn = 8, /*!< I2C0 */
MRT_IRQn = 10, /*!< MRT */
CMP_IRQn = 11, /*!< Analog Comparator /CapTouch */
WDT_IRQn = 12, /*!< WDT */
BOD_IRQn = 13, /*!< BOD */
FLASH_IRQn = 14, /*!< FLASH */
WKT_IRQn = 15, /*!< WKT Interrupt */
ADC_SEQA_IRQn = 16, /*!< ADC Seq. A */
ADC_SEQB_IRQn = 17, /*!< ADC Seq. B */
ADC_THCMP_IRQn = 18, /*!< ADC Thresh Comp */
ADC_OVR_IRQn = 19, /*!< ADC overrun */
CTIMER0_IRQn = 23, /*!< Timer 0 Interrupt */
PININT0_IRQn = 24, /*!< External Interrupt 0 */
PININT1_IRQn = 25, /*!< External Interrupt 1 */
PININT2_IRQn = 26, /*!< External Interrupt 2 */
PININT3_IRQn = 27, /*!< External Interrupt 3 */
PININT4_IRQn = 28, /*!< External Interrupt 4 */
PININT5_IRQn = 29, /*!< External Interrupt 5 */
PININT6_IRQn = 30, /*!< External Interrupt 6 */
PININT7_IRQn = 31, /*!< External Interrupt 7 */
} IRQn_Type;
#define CAPT_IRQn CMP_IRQn
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M0+ Processor and Core Peripherals */
#define __CM0PLUS_REV 0x0001
#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 LPC8xx_CMSIS */
#include "core_cm0plus.h" /* Cortex-M0+ processor and core peripherals */
#include "system.h" /* System Header */
#if defined ( __CC_ARM )
#pragma anon_unions // This is needed by the Keil compiler
#endif
/******************************************************************************/
/* Device Specific Peripheral Registers structures */
/******************************************************************************/
//------------- System Control (SYSCON) --------------------------------------
typedef struct
{
__IO uint32_t SYSMEMREMAP ; ///< (0x000) System memory remap
__IO uint32_t RESERVED0[8] ; ///< (0x004 - 0x020)
__IO uint32_t LPOSCCTRL ; ///< (0x024) Low power oscillator control
__IO uint32_t FROOSCCTRL ; ///< (0x028) FRO oscillator control
__IO uint32_t RESERVED2[3] ; ///< (0x02C - 0x034)
__IO uint32_t SYSRSTSTAT ; ///< (0x038) System reset status 0
__IO uint32_t RESERVED3[5] ; ///< (0x03C - 0x04C)
__IO uint32_t MAINCLKSEL ; ///< (0x050) Main clock source select
__IO uint32_t MAINCLKUEN ; ///< (0x054) Main clock source update enable
__IO uint32_t SYSAHBCLKDIV ; ///< (0x058) System clock divider
__IO uint32_t RESERVED4[1] ; ///< (0x05C)
__IO uint32_t CAPTCLKSEL ; ///< (0x060) /* Added by Andrew Su 2018-01-18. */
__IO uint32_t ADCCLKSEL ; ///< (0x064) ADC clock source select
__IO uint32_t ADCCLKDIV ; ///< (0x068) ADC clock divider
__IO uint32_t RESERVED5[4] ; ///< (0x06C - 0x078)
__IO uint32_t LPOSCCLKEN ; ///< (0x07C)
union {
__IO uint32_t SYSAHBCLKCTRL[2] ;
struct {
__IO uint32_t SYSAHBCLKCTRL0 ; ///< (0x080) System clock group 0 control
__IO uint32_t SYSAHBCLKCTRL1 ; ///< (0x084) System clock group 1 control
};
};
union {
__IO uint32_t PRESETCTRL[2] ;
struct {
__IO uint32_t PRESETCTRL0 ; ///< (0x088) Peripheral reset group 0 control
__IO uint32_t PRESETCTRL1 ; ///< (0x08C) Peripheral reset group 1 control
};
};
union {
__IO uint32_t FCLKSEL[11] ;
struct {
__IO uint32_t UART0CLKSEL ; ///< (0x090) FCLK0 clock source select
__IO uint32_t UART1CLKSEL ; ///< (0x094) FCLK1 clock source select
__IO uint32_t unimp2CLKSEL ; ///< (0x098) FCLK2 clock source select
__IO uint32_t unimp3CLKSEL ; ///< (0x09C) FCLK3 clock source select
__IO uint32_t unimp4CLKSEL ; ///< (0x0A0) FCLK4 clock source select
__IO uint32_t I2C0CLKSEL ; ///< (0x0A4) FCLK5 clock source select
__IO uint32_t I2C1CLKSEL ; ///< (0x0A8) FCLK6 clock source select
__IO uint32_t unimp7CLKSEL ; ///< (0x0AC) FCLK7 clock source select
__IO uint32_t unimp8CLKSEL ; ///< (0x0B0) FCLK8 clock source select
__IO uint32_t SPI0CLKSEL ; ///< (0x0B4) FCLK9 clock source select
__IO uint32_t unimp10CLKSEL ; ///< (0x0B8) FCLK10 clock source select
};
};
__IO uint32_t RESERVED6[5] ; ///< (0x0BC - 0x0CC)
__IO uint32_t FRG0DIV ; ///< (0x0D0) Fractional generator divider value
__IO uint32_t FRG0MULT ; ///< (0x0D4) Fractional generator multiplier value
__IO uint32_t FRG0CLKSEL ; ///< (0x0D8) FRG0 clock source select
__IO uint32_t RESERVED8[5] ; ///< (0x0DC - 0x0EC)
__IO uint32_t CLKOUTSEL ; ///< (0x0F0) CLKOUT clock source select
__IO uint32_t CLKOUTDIV ; ///< (0x0F4) CLKOUT clock divider
__IO uint32_t RESERVED10[2] ; ///< (0x0F8 - 0x0FC)
__I uint32_t PIOPORCAP0 ; ///< (0x100) POR captured PIO0 status 0
__I uint32_t RESERVED11[19] ; ///< (0x104 - 0x14C)
__IO uint32_t BODCTRL ; ///< (0x150) Brown-Out Detect
__IO uint32_t SYSTCKCAL ; ///< (0x154) System tick counter calibration
__IO uint32_t RESERVED12[6] ; ///< (0x158 - 0x16C)
__IO uint32_t IRQLATENCY ; ///< (0x170) IRQ delay. Allows trade-off between interrupt latency and determinism.
__IO uint32_t NMISRC ; ///< (0x174) NMI Source Control
union {
__IO uint32_t PINTSEL[8] ;
struct {
__IO uint32_t PINTSEL0 ; ///< (0x178) GPIO Pin Interrupt Select 0
__IO uint32_t PINTSEL1 ; ///< (0x17C) GPIO Pin Interrupt Select 1
__IO uint32_t PINTSEL2 ; ///< (0x180) GPIO Pin Interrupt Select 2
__IO uint32_t PINTSEL3 ; ///< (0x184) GPIO Pin Interrupt Select 3
__IO uint32_t PINTSEL4 ; ///< (0x188) GPIO Pin Interrupt Select 4
__IO uint32_t PINTSEL5 ; ///< (0x18C) GPIO Pin Interrupt Select 5
__IO uint32_t PINTSEL6 ; ///< (0x190) GPIO Pin Interrupt Select 6
__IO uint32_t PINTSEL7 ; ///< (0x194) GPIO Pin Interrupt Select 7
};
};
__IO uint32_t RESERVED13[27] ; ///< (0x198 - 0x200)
__IO uint32_t STARTERP0 ; ///< (0x204) Start logic 0 pin wake-up enable
__IO uint32_t RESERVED14[3] ; ///< (0x208 - 0x210)
__IO uint32_t STARTERP1 ; ///< (0x214) Start logic 1 interrupt wake-up enable
__IO uint32_t RESERVED15[6] ; ///< (0x218 - 0x22C)
__IO uint32_t PDSLEEPCFG ; ///< (0x230) Power-down states in deep-sleep mode
__IO uint32_t PDAWAKECFG ; ///< (0x234) Power-down states for wake-up from deep-sleep
__IO uint32_t PDRUNCFG ; ///< (0x238) Power configuration
__IO uint32_t RESERVED16[111] ; ///< (0x23C - 0x3F4)
__I uint32_t DEVICE_ID ; ///< (0x3F8) Device ID
} LPC_SYSCON_TypeDef;
// ---------------- IOCON ----------------
typedef struct {
__IO uint32_t PIO0_17; // 0x00
__IO uint32_t PIO0_13; // 0x04
__IO uint32_t PIO0_12; // 0x08
__IO uint32_t PIO0_5; // 0x0C
__IO uint32_t PIO0_4; // 0x10
__IO uint32_t PIO0_3; // 0x14
__IO uint32_t PIO0_2; // 0x18
__IO uint32_t PIO0_11; // 0x1C
__IO uint32_t PIO0_10; // 0x20
__IO uint32_t PIO0_16; // 0x24
__IO uint32_t PIO0_15; // 0x28
__IO uint32_t PIO0_1; // 0x2C
__IO uint32_t PIO0_21; // 0x30
__IO uint32_t PIO0_9; // 0x34
__IO uint32_t PIO0_8; // 0x38
__IO uint32_t PIO0_7; // 0x3C
__IO uint32_t PIO0_29; // 0x40
__IO uint32_t PIO0_0; // 0x44
__IO uint32_t PIO0_14; // 0x48
__IO uint32_t PIO0_28; // 0x4C
__IO uint32_t PIO0_27; // 0x50
__IO uint32_t PIO0_26; // 0x54
__IO uint32_t PIO0_20; // 0x58
__IO uint32_t PIO0_30; // 0x5C
__IO uint32_t PIO0_19; // 0x60
__IO uint32_t PIO0_25; // 0x64
__IO uint32_t PIO0_24; // 0x68
__IO uint32_t PIO0_23; // 0x6C
__IO uint32_t PIO0_22; // 0x70
__IO uint32_t PIO0_18; // 0x74
} LPC_IOCON_TypeDef;
//------------- Power Management Unit (PMU) --------------------------
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)
__I uint32_t RESERVED[2]; // 0x18 - 0x1C
__IO uint32_t WUSRCREG; // 0x20
__IO uint32_t WUENAREG; // 0x24
} LPC_PMU_TypeDef;
//------------- Switch Matrix (SWM) --------------------------
typedef struct
{
union {
__IO uint32_t PINASSIGN[10];
struct {
__IO uint32_t PINASSIGN0; // 0x000
__IO uint32_t PINASSIGN1; // 0x004
__IO uint32_t PINASSIGN2; // 0x008
__IO uint32_t PINASSIGN3; // 0x00C
__IO uint32_t PINASSIGN4; // 0x010
__IO uint32_t PINASSIGN5; // 0x014
__IO uint32_t PINASSIGN6; // 0x018
__IO uint32_t PINASSIGN7; // 0x01C
__IO uint32_t PINASSIGN8; // 0x020
__IO uint32_t PINASSIGN9; // 0x024
};
};
__I uint32_t Reserved0[86]; // 0x028 - 0x17C
__IO uint32_t PINASSIGN_4PIN; // 0x180
__I uint32_t Reserved1[15]; // 0x184 - 0x1BC
__IO uint32_t PINENABLE0; // 0x1C0
__IO uint32_t PINENABLE1; // 0x1C4
} LPC_SWM_TypeDef;
// ------------------------------------------------------------------------------------------------
// ----- General Purpose I/O (GPIO) -----
// ------------------------------------------------------------------------------------------------
typedef struct {
__IO uint8_t B0[32]; // 0x00 - 0x1F Byte pin registers P0.0 - P0.31
__IO uint8_t B1[32]; // 0x20 - 0x3F Byte pin registers P1.0 - P1.31
__I uint8_t Reserved0[4032]; // 0x40 - 0xFFF
__IO uint32_t W0[32]; // 0x1000 - 0x107C Word pin registers P0.0 - P0.31
__IO uint32_t W1[32]; // 0x1080 - 0x10FC Word pin registers P1.0 - P1.31
__I uint32_t Reserved1[960]; // 0x1100 - 0x1FFC (960d = 0x3c0)
union {
__IO uint32_t DIR[2]; // 0x2000 - 0x2004
struct {
__IO uint32_t DIR0; // 0x2000
__IO uint32_t DIR1; // 0x2004
};
};
__I uint32_t Reserved2[30]; // 0x2008 - 0x207C
union {
__IO uint32_t MASK[2]; // 0x2080 - 0x2084
struct {
__IO uint32_t MASK0; // 0x2080
__IO uint32_t MASK1; // 0x2084
};
};
__I uint32_t Reserved3[30]; // 0x2088 - 0x20FC
union {
__IO uint32_t PIN[2]; // 0x2100 - 0x2104
struct {
__IO uint32_t PIN0; // 0x2100
__IO uint32_t PIN1; // 0x2104
};
};
__I uint32_t Reserved4[30]; // 0x2108 - 0x217C
union {
__IO uint32_t MPIN[2]; // 0x22180 - 0x2184
struct {
__IO uint32_t MPIN0; // 0x2180
__IO uint32_t MPIN1; // 0x2184
};
};
__I uint32_t Reserved5[30]; // 0x2188 - 0x21FC
union {
__IO uint32_t SET[2]; // 0x2200 -0x2204
struct {
__IO uint32_t SET0; // 0x2200
__IO uint32_t SET1; // 0x2204
};
};
__I uint32_t Reserved6[30]; // 0x2208 - 0x227C
union {
__O uint32_t CLR[2]; // 0x2280 - 0x2284
struct {
__O uint32_t CLR0; // 0x2280
__O uint32_t CLR1; // 0x2284
};
};
__I uint32_t Reserved7[30]; // 0x2288 - 0x22FC
union {
__O uint32_t NOT[2]; // 0x2300 - 0x2304
struct {
__O uint32_t NOT0; // 0x2300
__O uint32_t NOT1; // 0x2304
};
};
__I uint32_t Reserved8[30]; // 0x2308 - 0x237C
union {
__O uint32_t DIRSET[2]; // 0x2380 - 0x2384
struct {
__O uint32_t DIRSET0; // 0x2380
__O uint32_t DIRSET1; // 0x2384
};
};
__I uint32_t Reserved9[30]; // 0x2388 - 0x23FC
union {
__O uint32_t DIRCLR[2]; // 0x2400 - 0x2404
struct {
__O uint32_t DIRCLR0; // 0x2400
__O uint32_t DIRCLR1; // 0x2404
};
};
__I uint32_t Reserved10[30]; // 0x2408 - 0x247C
union {
__O uint32_t DIRNOT[2]; // 0x2480 - 0x2484
struct {
__O uint32_t DIRNOT0; // 0x2480
__O uint32_t DIRNOT1; // 0x2484
};
};
} LPC_GPIO_PORT_TypeDef;
// ------------------------------------------------------------------------------------------------
// ----- Pin Interrupts and Pattern Match (PIN_INT) -----
// ------------------------------------------------------------------------------------------------
typedef struct { /*!< (@ 0xA0004000) PIN_INT Structure */
__IO uint32_t ISEL; /*!< (@ 0xA0004000) Pin Interrupt Mode register */
__IO uint32_t IENR; /*!< (@ 0xA0004004) Pin Interrupt Enable (Rising) register */
__IO uint32_t SIENR; /*!< (@ 0xA0004008) Set Pin Interrupt Enable (Rising) register */
__IO uint32_t CIENR; /*!< (@ 0xA000400C) Clear Pin Interrupt Enable (Rising) register */
__IO uint32_t IENF; /*!< (@ 0xA0004010) Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t SIENF; /*!< (@ 0xA0004014) Set Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t CIENF; /*!< (@ 0xA0004018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
__IO uint32_t RISE; /*!< (@ 0xA000401C) Pin Interrupt Rising Edge register */
__IO uint32_t FALL; /*!< (@ 0xA0004020) Pin Interrupt Falling Edge register */
__IO uint32_t IST; /*!< (@ 0xA0004024) Pin Interrupt Status register */
__IO uint32_t PMCTRL; /*!< (@ 0xA0004028) GPIO pattern match interrupt control register */
__IO uint32_t PMSRC; /*!< (@ 0xA000402C) GPIO pattern match interrupt bit-slice source register */
__IO uint32_t PMCFG; /*!< (@ 0xA0004030) GPIO pattern match interrupt bit slice configuration register */
} LPC_PIN_INT_TypeDef;
//------------- CRC Engine (CRC) -----------------------------------------
typedef struct
{
__IO uint32_t MODE;
__IO uint32_t SEED;
union {
__I uint32_t SUM;
__O uint32_t WR_DATA;
};
} LPC_CRC_TypeDef;
//------------- Comparator (CMP) --------------------------------------------------
typedef struct { /*!< (@ 0x40024000) CMP Structure */
__IO uint32_t CTRL; /*!< (@ 0x40024000) Comparator control register */
__IO uint32_t LAD; /*!< (@ 0x40024004) Voltage ladder register */
} LPC_CMP_TypeDef;
//------------- Self Wakeup Timer (WKT) --------------------------------------------------
typedef struct { /*!< (@ 0x40028000) WKT Structure */
__IO uint32_t CTRL; /*!< (@ 0x40028000) Alarm/Wakeup Timer Control register */
uint32_t Reserved[2];
__IO uint32_t COUNT; /*!< (@ 0x4002800C) Alarm/Wakeup TImer counter register */
} LPC_WKT_TypeDef;
//------------- Multi-Rate Timer (MRT) --------------------------------------------------
typedef struct {
__IO uint32_t INTVAL;
__IO uint32_t TIMER;
__IO uint32_t CTRL;
__IO uint32_t STAT;
} MRT_Channel_cfg_Type;
typedef struct {
MRT_Channel_cfg_Type Channel[4];
uint32_t Reserved0[45]; // Address offsets = 0x40 - 0xF0
__IO uint32_t IDLE_CH;
__IO uint32_t IRQ_FLAG;
} LPC_MRT_TypeDef;
//------------- USART -----------
typedef struct
{
__IO uint32_t CFG;
__IO uint32_t CTL;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR;
__I uint32_t RXDAT;
__I uint32_t RXDATSTAT;
__IO uint32_t TXDAT;
__IO uint32_t BRG;
__I uint32_t INTSTAT;
__IO uint32_t OSR;
__IO uint32_t ADDR;
} LPC_USART_TypeDef;
//------------- SPI -----------------------
typedef struct
{
__IO uint32_t CFG; /* 0x00 */
__IO uint32_t DLY;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR; /* 0x10 */
__I uint32_t RXDAT;
__IO uint32_t TXDATCTL;
__IO uint32_t TXDAT;
__IO uint32_t TXCTL; /* 0x20 */
__IO uint32_t DIV;
__I uint32_t INTSTAT;
} LPC_SPI_TypeDef;
//------------- I2C -------------------------------
typedef struct
{
__IO uint32_t CFG; /* 0x00 */
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR;
__IO uint32_t TIMEOUT; /* 0x10 */
union {
__IO uint32_t CLKDIV;
__IO uint32_t DIV;
};
__IO uint32_t INTSTAT;
uint32_t Reserved0[1];
__IO uint32_t MSTCTL; /* 0x20 */
__IO uint32_t MSTTIME;
__IO uint32_t MSTDAT;
uint32_t Reserved1[5];
__IO uint32_t SLVCTL; /* 0x40 */
__IO uint32_t SLVDAT;
__IO uint32_t SLVADR0;
__IO uint32_t SLVADR1;
__IO uint32_t SLVADR2; /* 0x50 */
__IO uint32_t SLVADR3;
__IO uint32_t SLVQUAL0;
uint32_t Reserved2[9];
__I uint32_t MONRXDAT; /* 0x80 */
} LPC_I2C_TypeDef;
//------------------- Standard Counter/Timer (CTIMER) ---------------------
typedef struct {
__IO uint32_t IR; // 0x00
__IO uint32_t TCR; // 0x04
__IO uint32_t TC; // 0x08
__IO uint32_t PR; // 0x0C
__IO uint32_t PC; // 0x10
__IO uint32_t MCR; // 0x14
__IO uint32_t MR[4]; // 0x18 - 0x24
__IO uint32_t CCR; // 0x28
__IO uint32_t CR[4]; // 0x2C - 0x38
__IO uint32_t EMR; // 0x3C
__I uint32_t RESERVED0[12]; // 0x40 - 0x6C
__IO uint32_t CTCR; // 0x70
__IO uint32_t PWMC; // 0x74
} LPC_TIMER_TypeDef;
//------------- Widowed Watchdog Timer (WWDT) -----------------------------------------
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 RESERVED; /*!< Offset: 0x010 RESERVED */
__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_WWDT_TypeDef;
//------------- ADC -----------------------------------------
typedef struct {
__IO uint32_t CTRL; // 0x0
uint32_t RESERVED0; // 0x4
__IO uint32_t SEQA_CTRL; // 0x8
__IO uint32_t SEQB_CTRL; // 0xC
__IO uint32_t SEQA_GDAT; // 0x10
__IO uint32_t SEQB_GDAT; // 0x14
uint32_t RESERVED1[2]; // 0x18 - 0x1C
__IO uint32_t DAT[12]; // 0x20 - 0x4C
__IO uint32_t THR0_LOW; // 0x50
__IO uint32_t THR1_LOW; // 0x54
__IO uint32_t THR0_HIGH; // 0x58
__IO uint32_t THR1_HIGH; // 0x5C
__IO uint32_t CHAN_THRSEL; // 0x60
__IO uint32_t INTEN; // 0x64
__IO uint32_t FLAGS; // 0x68
__IO uint32_t TRM; // 0x6C
} LPC_ADC_TypeDef;
//------------- DAC ----------------
typedef struct {
__IO uint32_t CR; // 0x00
__IO uint32_t CTRL; // 0x04
__IO uint32_t CNTVAL; // 0x08
} LPC_DAC_TypeDef;
//------------- Capacitive Touch module (CAPT) ----------------
typedef struct {
__IO uint32_t CTRL; // 0x00
__IO uint32_t STATUS; // 0x04
__IO uint32_t POLL_TCNT; // 0x08
__I uint32_t reserved0; // 0x0C
__IO uint32_t INTENSET; // 0x10
__O uint32_t INTENCLR; // 0x14
__I uint32_t INTSTAT; // 0x18
__I uint32_t reserved1; // 0x1C
__I uint32_t TOUCH; // 0x20
__I uint32_t A_hole[1014];// 0x24 - 0xFF8
__I uint32_t ID; // 0xFFC
} LPC_CAPT_TypeDef;
#define LUT_INs 5
#define PLU_INs 6
#define PLU_LUTs 26
#define PLU_FFs 4
#define PLU_OUTs 8
typedef struct {
struct { /* Input select register for LUT & Input... */
union {
__IO uint32_t INP[8]; /* Each LUT has maximum 5 inputs, the remaining are reserved. */
struct {
__IO uint32_t INP0;
__IO uint32_t INP1;
__IO uint32_t INP2;
__IO uint32_t INP3;
__IO uint32_t INP4;
uint32_t RESERVED[3];
};
} LUT_MUX[PLU_LUTs];
};
uint32_t RESERVED0[8*64-8*PLU_LUTs]; /* ...-0x7FC */
__IO uint32_t LUT_TRUTH[PLU_LUTs]; /* Truth-Table ("Look-up Table") programming */
uint32_t RESERVED1[64-PLU_LUTs]; /* ...-0x8FC */
__I uint32_t OUTPUTS; /* PLU Outputs Register (Read-only) */
uint32_t RESERVED2[3*64-1]; /* ...-0xBFC */
__IO uint32_t OUTPUT_MUX[PLU_OUTs]; /* Select register for PLU Ouptut */
} LPC_PLU_TypeDef;
#if defined ( __CC_ARM )
#pragma no_anon_unions
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
// Base addresses
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_ROM_BASE (0x1FFF0000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
// APB0 peripherals
#define LPC_WWDT_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_MRT_BASE (LPC_APB0_BASE + 0x04000)
#define LPC_WKT_BASE (LPC_APB0_BASE + 0x08000)
#define LPC_SWM_BASE (LPC_APB0_BASE + 0x0C000)
// (LPC_APB0_BASE + 0x10000)
#define LPC_DAC0_BASE (LPC_APB0_BASE + 0x14000)
// (LPC_APB0_BASE + 0x18000)
#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000)
#define LPC_PMU_BASE (LPC_APB0_BASE + 0x20000)
#define LPC_CMP_BASE (LPC_APB0_BASE + 0x24000)
#define LPC_PLU_BASE (LPC_APB0_BASE + 0x28000)
// (LPC_APB0_BASE + 0x2C000)
// (LPC_APB0_BASE + 0x30000)
// (LPC_APB0_BASE + 0x34000)
#define LPC_CTIMER0_BASE (LPC_APB0_BASE + 0x38000)
// (LPC_APB0_BASE + 0x38000)
#define LPC_FLASHCTRL_BASE (LPC_APB0_BASE + 0x40000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
#define LPC_I2C0_BASE (LPC_APB0_BASE + 0x50000)
#define LPC_I2C1_BASE (LPC_APB0_BASE + 0x54000)
#define LPC_SPI0_BASE (LPC_APB0_BASE + 0x58000)
// (LPC_APB0_BASE + 0x5C000)
#define LPC_CAPT_BASE (LPC_APB0_BASE + 0x60000)
#define LPC_USART0_BASE (LPC_APB0_BASE + 0x64000)
#define LPC_USART1_BASE (LPC_APB0_BASE + 0x68000)
// (LPC_APB0_BASE + 0x6C000)
// (LPC_APB0_BASE + 0x70000)
// (LPC_APB0_BASE + 0x74000)
// AHB peripherals
#define LPC_CRC_BASE (LPC_AHB_BASE + 0x00000)
// (LPC_AHB_BASE + 0x04000)
// (LPC_AHB_BASE + 0x08000)
// (LPC_AHB_BASE + 0x0C000)
// (LPC_AHB_BASE + 0x10000)
#define LPC_GPIO_PORT_BASE (0xA0000000)
#define LPC_PIN_INT_BASE (LPC_GPIO_PORT_BASE + 0x4000)
/******************************************************************************/
/* Peripheral declarations */
/******************************************************************************/
#define LPC_WWDT ((LPC_WWDT_TypeDef *) LPC_WWDT_BASE )
#define LPC_MRT ((LPC_MRT_TypeDef *) LPC_MRT_BASE )
#define LPC_WKT ((LPC_WKT_TypeDef *) LPC_WKT_BASE )
#define LPC_SWM ((LPC_SWM_TypeDef *) LPC_SWM_BASE )
#define LPC_DAC0 ((LPC_DAC_TypeDef *) LPC_DAC0_BASE )
#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
#define LPC_CMP ((LPC_CMP_TypeDef *) LPC_CMP_BASE )
#define LPC_CTIMER0 ((LPC_TIMER_TypeDef *) LPC_CTIMER0_BASE )
#define LPC_FLASHCTRL ((LPC_FLASHCTRL_TypeDef *) LPC_FLASHCTRL_BASE )
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_I2C0 ((LPC_I2C_TypeDef *) LPC_I2C0_BASE )
#define LPC_I2C1 ((LPC_I2C_TypeDef *) LPC_I2C1_BASE )
#define LPC_SPI0 ((LPC_SPI_TypeDef *) LPC_SPI0_BASE )
#define LPC_CAPT ((LPC_CAPT_TypeDef *) LPC_CAPT_BASE )
#define LPC_USART0 ((LPC_USART_TypeDef *) LPC_USART0_BASE )
#define LPC_USART1 ((LPC_USART_TypeDef *) LPC_USART1_BASE )
#define LPC_CRC ((LPC_CRC_TypeDef *) LPC_CRC_BASE )
#define LPC_GPIO_PORT ((LPC_GPIO_PORT_TypeDef *) LPC_GPIO_PORT_BASE )
#define LPC_PIN_INT ((LPC_PIN_INT_TypeDef *) LPC_PIN_INT_BASE )
#define LPC_PLU0 ((LPC_PLU_TypeDef *) LPC_PLU_BASE)
///////////////////////////////////////////////////////////////////////////////
// Other chip-specific macro definitions (a.k.a. the chip.h section)
///////////////////////////////////////////////////////////////////////////////
// ACMP_I-to-IOCON mapping
#define ACMP_I1_PORT PIO0_0
#define ACMP_I2_PORT PIO0_1
#define ACMP_I3_PORT PIO0_14
#define ACMP_I4_PORT PIO0_16
#define ACMP_I5_PORT PIO0_21
// For looping through the pad controls
#define NUM_IOCON_SLOTS 30
#ifdef __cplusplus
}
#endif
#endif /* __LPC8xx_H__ */

View File

@@ -0,0 +1,53 @@
/*
* lpc8xx_acomp.h
*
* Created on: Apr 7, 2016
* Author:
*/
#ifndef LPC8XX_ACOMP_H_
#define LPC8XX_ACOMP_H_
// CTRL register shifters
#define HYS 25
#define INTENA 24
#define COMPEDGE 23
#define COMPSTAT 21
#define EDGECLR 20
#define COMP_VM_SEL 11
#define COMP_VP_SEL 8
#define COMPSA 6
#define EDGESEL 3
// HYS field descriptors
#define _20mV 0x3
#define _10mV 0x2
#define _5mV 0x1
#define NONE 0x0
// COMP_VM_SEL and COMP_VP_SEL field descriptors
#define DAC_OUT_0 0x7
#define V_BANDGAP 0x6
#define ACOMP_IN5 0x5
#define ACOMP_IN4 0x4
#define ACOMP_IN3 0x3
#define ACOMP_IN2 0x2
#define ACOMP_IN1 0x1
#define V_LADDER_OUT 0x0
// EDGESEL field descriptors
#define BOTH 0x3
#define RISING 0x1
#define FALLING 0x0
// LAD register shifters
#define LADREF 6
#define LADSEL 1
#define LADEN 0
// LADREF field descriptors
#define VDDCMP_PIN 1
#define SUPPLY_VDD 0
#endif /* LPC8XX_ACOMP_H_ */

View File

@@ -0,0 +1,100 @@
/*
* lpc8xx_adc.h
*
* Created on: This day, August 18, 2016
* Author: The Creator
*/
#ifndef LPC8XX_ADC_H_
#define LPC8XX_ADC_H_
// CTRL register shifters
#define ADC_CLKDIV 0
#define ADC_LPWRMODE 10
#define ADC_CALMODE 30
// Sequence A and B control register shifters
#define ADC_CHANNELS 0
#define ADC_TRIGGER 12
#define ADC_TRIGPOL 18
#define ADC_SYNCBYPASS 19
#define ADC_START 26
#define ADC_BURST 27
#define ADC_SINGLESTEP 28
#define ADC_LOWPRIO 29
#define ADC_MODE 30
#define ADC_SEQ_ENA 31
// ADC hardware trigger inputs
#define NO_TRIGGER 0
#define PININT0_IRQ 1
#define PININT1_IRQ 2
#define TIM0_MAT3 5
#define CMP0_OUT_ADC 6
#define GPIO_INT_BMATCH 7
#define ARM_TXEV 8
// Threshold compare register shifters
#define THRLOW 15
#define THRHIGH 15
// INTEN register shifters
#define SEQA_INTEN 0
#define SEQB_INTEN 1
#define OVR_INTEN 2
#define ADCMPINTEN0 3
#define ADCMPINTEN1 5
#define ADCMPINTEN2 7
#define ADCMPINTEN3 9
#define ADCMPINTEN4 11
#define ADCMPINTEN5 13
#define ADCMPINTEN6 15
#define ADCMPINTEN7 17
#define ADCMPINTEN8 19
#define ADCMPINTEN9 21
#define ADCMPINTEN10 23
#define ADCMPINTEN11 25
// FLAGS register shifters
#define ADC_THCMP0 0
#define ADC_THCMP1 1
#define ADC_THCMP2 2
#define ADC_THCMP3 3
#define ADC_THCMP4 4
#define ADC_THCMP5 5
#define ADC_THCMP6 6
#define ADC_THCMP7 7
#define ADC_THCMP8 8
#define ADC_THCMP9 9
#define ADC_THCMP10 10
#define ADC_THCMP11 11
#define ADC_OVERRUN0 12
#define ADC_OVERRUN1 13
#define ADC_OVERRUN2 14
#define ADC_OVERRUN3 15
#define ADC_OVERRUN4 16
#define ADC_OVERRUN5 17
#define ADC_OVERRUN6 18
#define ADC_OVERRUN7 19
#define ADC_OVERRUN8 20
#define ADC_OVERRUN9 21
#define ADC_OVERRUN10 22
#define ADC_OVERRUN11 23
#define ADC_SEQA_OVR 24
#define ADC_SEQB_OVR 25
#define ADC_SEQA_INT 28
#define ADC_SEQB_INT 29
#define ADC_THCMP_INT 30
#define ADC_OVR_INT 31
// TRM register shifters
#define ADC_VRANGE 5
#endif /* LPC8XX_ADC_H_ */

View File

@@ -0,0 +1,79 @@
/*
* board.h
*
* Created on:
* Author:
*/
#ifndef BOARD_H_
#define BOARD_H_
//#define XPRESSO_812_BOARD // For the LPC812 Max board
//#define XPRESSO_824_BOARD // For the LPC824 Max board
//#define XPRESSO_845_BOARD // For the LPC845 Max board
//#define XPRESSO_802_BOARD // For the LPC802 Max board
#define XPRESSO_804_BOARD // For the LPC804 Max board
// LPC812 Max board
#ifdef XPRESSO_812_BOARD
#define RED (1<<7)
#define BLUE (1<<16)
#define GREEN (1<<17)
#define red_led_port P0_7
#define blue_led_port P0_16
#define green_led_port P0_17
#define PCF8591_address 0x4F // The on-board ADC/DAC default I2C address
#define PCA9672_address 0x23 // The on-board GPIO Expander default I2C address
#define TARGET_TX P0_6 // For the VCOM serial port
#define TARGET_RX P0_1 // For the VCOM serial port
#define NUM_IOCON_P0_SLOTS 19 // For looping through the pad controls
#endif
// LPC824 Max board
#ifdef XPRESSO_824_BOARD
#define RED (1<<12)
#define BLUE (1<<27)
#define GREEN (1<<16)
#define red_led_port P0_12
#define blue_led_port P0_27
#define green_led_port P0_16
#define TARGET_TX P0_7 // For the VCOM serial port
#define TARGET_RX P0_18 // For the VCOM serial port
#define NUM_IOCON_P0_SLOTS 31 // For looping through the pad controls
#endif
// LPC845 Max board
#ifdef XPRESSO_845_BOARD
#define LED_RED P0_12
#define LED_BLUE P1_15
#define LED_GREEN P0_0
#define TARGET_TX P1_17 // For the VCOM serial port
#define TARGET_RX P1_16 // For the VCOM serial port
#define DACOUT0_PIN PIO0_17
#define DACOUT1_PIN PIO0_29
#define AUDIO_AMP_ENABLE_PORT PORT1
#define AUDIO_AMP_ENABLE_PIN Bit11
#define NUM_IOCON_P0_SLOTS 56 // For looping through the pad controls
#endif
// LPC802 MAX board
#ifdef XPRESSO_802_BOARD
#define LED_BLUE P0_8
#define LED_RED P0_9
#define LED_GREEN P0_12
#define TARGET_TX P0_4 // For the VCOM serial port
#define TARGET_RX P0_0 // For the VCOM serial port
#endif
// LPC804 MAX board
#ifdef XPRESSO_804_BOARD
#define LED_BLUE P0_11
#define LED_RED P0_13
#define LED_GREEN P0_12
#define TARGET_TX P0_4 // For the VCOM serial port
#define TARGET_RX P0_0 // For the VCOM serial port
#define TARTET_I2CSCL P0_14
#define TARTET_I2CSDA P0_7
#define DACOUT_PIN PIO0_19
#endif
#endif /* BOARD_H_ */

View File

@@ -0,0 +1,85 @@
/*
* lpc8xx_capt.h
*
* Created on: This day
* Author: The Creator
*/
#ifndef LPC8XX_CAPT_H_
#define LPC8XX_CAPT_H_
#define CAPT_X_PIN_COUNT 5U
// CTRL register
#define POLLMODE_INACTIVE (0x0<<0)
#define POLLMODE_NOW (0x1<<0)
#define POLLMODE_CONTINUOUS (0x2<<0)
#define POLLMODE_LOWPWR (0x3<<0)
#define POLLMODE 0 // Use this as a shifter for a 2-bit value
#define TYPE_NORMAL (0x0<<2)
#define TYPE_3x3 (0x1<<2)
#define TYPE_5_INTERLEAVE (0x2<<2)
#define TYPE_TRIGGER_YH (0x0<<4)
#define TYPE_TRIGGER_ACMP (0x1<<4)
#define WAIT (0x1<<5)
#define DMA_NONE (0x0<<6)
#define DMA_TOUCH (0x1<<6)
#define DMA_BOTH (0x2<<6)
#define DMA_BOTH_PLUS_TO (0x3<<6)
#define FDIV 8 // Use this as a shifter for a 4-bit value
#define XPINUSE_HIGHZ (0x0<<12)
#define XPINUSE_LOW (0x1<<12)
#define INCHANGE (0x1<<15) // Use as an AND-mask, when reading this bit
#define X0_ACTV 1<<0
#define X1_ACTV 1<<1
#define X2_ACTV 1<<2
#define X3_ACTV 1<<3
#define X4_ACTV 1<<4
#define X5_ACTV 1<<5
#define X6_ACTV 1<<6
#define X7_ACTV 1<<7
#define X8_ACTV 1<<8
#define X9_ACTV 1<<9
#define X10_ACTV 1<<10
#define X11_ACTV 1<<11
#define X12_ACTV 1<<12
#define X13_ACTV 1<<13
#define X14_ACTV 1<<14
#define X15_ACTV 1<<15
#define XPINSEL 16 // Use this as a shifter for a 16-bit value
// STATUS, INTENSET, INTENCLR, INTSTAT registers
#define YESTOUCH (1<<0)
#define NOTOUCH (1<<1)
#define POLLDONE (1<<2)
#define TIMEOUT (1<<3)
#define OVERRUN (1<<4)
#define BUSY (1<<8)
#define XMAX (0xFF<<16) // Use as an AND-mask, when reading this field
// POLL_TCNT register
#define TCNT 0 // Use this as a shifter for a 12-bit value
#define TOUT 12 // Use this as a shifter for a 4-bit value
#define POLL 16 // Use this as a shifter for an 8-bit value
#define MDELAY 24 // Use this as a shifter for a 2-bit value
#define RDELAY 26 // Use this as a shifter for a 2-bit value
#define TCHLOWER 31 // Use this as a shifter for a 1-bit value
// TOUCH register
#define TOUCH_COUNT (0xFFF<<0) // Use as an AND-mask, when reading this field
#define TOUCH_XVAL (0xF<<12) // Use as an AND-mask, when reading this field
#define TOUCH_ISTOUCH (0x1<<16) // Use as an AND-mask, when reading this field
#define TOUCH_ISTO (0x1<<17) // Use as an AND-mask, when reading this field
#define TOUCH_SEQ (0xF<<20) // Use as an AND-mask, when reading this field
#define TOUCH_CHANGE (0x1<<31) // Use as an AND-mask, when reading this field
#endif /* LPC8XX_CAPT_H_ */

View File

@@ -0,0 +1,66 @@
#include "board.h"
//
// The following parameters need to be defined for each project's inital clock setup (used in system.c))
//
#define FRO_FREQ_VAL 2 // 0 = 18 MHz
// 1 = 24 MHz (reset value)
// 2 = 30 MHz
#define MAINCLKSEL_VAL 0 // 00 = fro (reset value)
// 01 = external_clk
// 10 = lposc_clk
// 11 = fro_div
#define SYSAHBCLKDIV_VAL 1 // 0x00 = system_ahb_clk disabled (use with caution)
// 0x01 = divide_by_1 (reset value)
// 0x02 = divide_by_2
// 0xFF = divide_by_255
#define CLKIN_CLK_VAL 12000000 // External Clock (CLKIN) frequency [Hz] must be in the range of 1 MHz to 25 MHz
#define EXT_CLOCK_FORCE_ENABLE 0 // Force config. and enable of external_clk for use by other than main_clk
// 0 = external_clk will be configured and enabled only if needed by main_clk or sys_pll0_clk.
// 1 = external_clk will be configured and enabled (available for other, e.g. clock out).
// End of clocks configuration section
//
// The following parameters need to be defined for projects that use the debug UART (used in serial.c)
//
#define DBGUART 0 // Choose the index for the debug UART (0 for UART0, 1 for UART1, etc.)
#define DBGBAUDRATE 9600 // Choose the baud rate for the debug UART
#define USE_VCOM_PORT 1 // '1' to use VCOM serial port, '0' to use user-defined port pins for debug UART
#if (USE_VCOM_PORT == 1)
#define DBGTXPIN TARGET_TX // For VCOM serial port (see board.h)
#define DBGRXPIN TARGET_RX // For VCOM serial port (see board.h)
#else
#define DBGTXPIN P0_15 // Use with USB-to-RS232 break-out cable (choose your own favorite TxD pin)
#define DBGRXPIN P0_14 // Use with USB-to-RS232 break-out cable (choose your own favorite RxD pin)
#endif
//
// The following are so the debug UART is selectable from any UART on the device (used in Serial.c)
//
#define __CONCAT(x,y,z) x##y##z
#define __XCONCAT(x,y,z) __CONCAT(x,y,z)
#define INDEX DBGUART
#define pDBGU __XCONCAT(LPC_USART,INDEX,)
#define DBGU __XCONCAT(UART,INDEX,)
#define DBGUTXD __XCONCAT(U,INDEX,_TXD)
#define DBGURXD __XCONCAT(U,INDEX,_RXD)
#define DBGURST __XCONCAT(UART,INDEX,_RST_N)
#define DBGUIRQ __XCONCAT(UART,INDEX,_IRQn)

View File

@@ -0,0 +1,778 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V3.01
* @date 22. March 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_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_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.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex-M0+
@{
*/
/* CMSIS CM0P definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
__CM0PLUS_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 <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0
#warning "__VTOR_PRESENT 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
<strong>IO Type Qualifiers</strong> 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
- Core MPU 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 */
#if (__VTOR_PRESENT == 1)
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__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 */
#if (__VTOR_PRESENT == 1)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* 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 */
#if (__MPU_PRESENT == 1)
/** \ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/** \brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register */
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register */
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register */
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register */
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \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 */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* 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) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0+ system interrupts */
else {
return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 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_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,616 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.01
* @date 06. March 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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#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");
}
/** \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");
}
/** \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");
}
/** \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");
}
/** \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 */

View File

@@ -0,0 +1,618 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.01
* @date 06. March 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
*/
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
/** \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__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
/** \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
#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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#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);
}
#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 */

View File

@@ -0,0 +1,87 @@
#ifndef LPC8XX_CTIMER_H_
#define LPC8XX_CTIMER_H_
// Interrupt Register (IR) shifters
#define MR0INT 0
#define MR1INT 1
#define MR2INT 2
#define MR3INT 3
#define CR0INT 4
#define CR1INT 5
#define CR2INT 6
#define CR3INT 7
// Timer Control Register (TCR) shifters
#define CEN 0
#define CRST 1
// Match Control Register (MCR) shifters
#define MR0I 0
#define MR0R 1
#define MR0S 2
#define MR1I 3
#define MR1R 4
#define MR1S 5
#define MR2I 6
#define MR2R 7
#define MR2S 8
#define MR3I 9
#define MR3R 10
#define MR3S 11
// Capture Control Register (CCR) shifters
#define CAP0RE 0
#define CAP0FE 1
#define CAP0I 2
#define CAP1RE 3
#define CAP1FE 4
#define CAP1I 5
#define CAP2RE 6
#define CAP2FE 7
#define CAP2I 8
#define CAP3RE 9
#define CAP3FE 10
#define CAP3I 11
// External Match Register (EMR) shifters
#define EM0 0
#define EM1 1
#define EM2 2
#define EM3 3
#define EMC0 4
#define EMC1 6
#define EMC2 8
#define EMC3 10
// EMR bit fields
#define DO_NOTHING_ON_MATCH 0x0
#define CLEAR_ON_MATCH 0x1
#define SET_ON_MATCH 0x2
#define TOGGLE_ON_MATCH 0x3
// Count Control Register (CTCR) shifters
#define CTMODE 0
#define CINSEL 2
#define ENCC 4
#define SELCC 5
// CTCR bit fields
#define TIMER_MODE 0x0
#define COUNTER_MODE_RISING 0x1
#define COUNTER_MODE_FALLING 0x2
#define COUNTER_MODE_BOTH 0x3
#define CLEAR_ON_CAP0_RISING 0x0
#define CLEAR_ON_CAP0_FALLING 0x1
#define CLEAR_ON_CAP1_RISING 0x2
#define CLEAR_ON_CAP1_FALLING 0x3
#define CLEAR_ON_CAP2_RISING 0x4
#define CLEAR_ON_CAP2_FALLING 0x5
#define CLEAR_ON_CAP3_RISING 0x6
#define CLEAR_ON_CAP3_FALLING 0x7
// PWM Control Register (PWMC) shifters
#define PWMEN0 0
#define PWMEN1 1
#define PWMEN2 2
#define PWMEN3 3
#endif // LPC8XX_CTIMER_H_

View File

@@ -0,0 +1,21 @@
/*
* dac.h
* Author: Arthur
*/
#ifndef LPC8XX_DAC_H_
#define LPC8XX_DAC_H_
// D/A Converter Register (VAL) shifters
#define DAC_VALUE 6
#define DAC_BIAS 16
// CTRL register shifters
#define DAC_INT_DMA_REQ 0
#define DAC_DBLBUF_ENA 1
#define DAC_CNT_ENA 2
#define DAC_DMA_ENA 3
#endif /* LPC8XX_DAC_H_ */

View File

@@ -0,0 +1,21 @@
#ifndef __FRO_H__
#define __FRO_H__
// FROOSCTRL register shifters
#define FRO_FREQ_SEL 0
#define FRO_TRIM 11
#define FRO_TEMP_TRIM 12
#define FRO_DIRECT 17
#define FRO_DEBUG_ENABLE 18
// FROOSCTRL register values
#define FRO_18MHZ 0
#define FRO_24MHZ 1
#define FRO_30MHZ 2
#define FRO_FREQSEL_MASK 3
#define FRO_DIVIDERS_OUT 0
#define FRO_OSCOUT 1
#endif // __FRO_H

View File

@@ -0,0 +1,84 @@
/****************************************************************************
****************************************************************************
* 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 __LPC8XX_GPIO_H
#define __LPC8XX_GPIO_H
#define INPUT 0
#define OUTPUT 1
#define PORT0 0
#define PORT1 1
#define Bit0 0
#define Bit1 1
#define Bit2 2
#define Bit3 3
#define Bit4 4
#define Bit5 5
#define Bit6 6
#define Bit7 7
#define Bit8 8
#define Bit9 9
#define Bit10 10
#define Bit11 11
#define Bit12 12
#define Bit13 13
#define Bit14 14
#define Bit15 15
#define Bit16 16
#define Bit17 17
#define Bit18 18
#define Bit19 19
#define Bit20 20
#define Bit21 21
#define Bit22 22
#define Bit23 23
#define Bit24 24
#define Bit25 25
#define Bit26 26
#define Bit27 27
#define Bit28 28
#define Bit29 29
#define Bit30 30
#define Bit31 31
void PININT_Handler ( uint32_t irq_num );
void PININT0_IRQHandler(void);
void PININT1_IRQHandler(void);
void PININT2_IRQHandler(void);
void PININT3_IRQHandler(void);
void PININT4_IRQHandler(void);
void PININT5_IRQHandler(void);
void PININT6_IRQHandler(void);
void PININT7_IRQHandler(void);
void GPIOInit( void );
uint32_t GPIOGetPinValue( uint32_t portNum, uint32_t bitPosi );
void GPIOSetBitValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal );
void GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir );
#endif /* end __LPC8XX_GPIO_H */
/*****************************************************************************
** End Of File
******************************************************************************/

View File

@@ -0,0 +1,80 @@
/**********************************************************************
***********************************************************************
* 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<72>
* 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 lpc8xx_I2C_H_
#define lpc8xx_I2C_H_
#include "LPC8xx.h"
#define RD_BIT 0x01
#define CFG_MSTENA (1 << 0)
#define CFG_SLVENA (1 << 1)
#define CFG_MONENA (1 << 2)
#define CFG_TIMEOUTENA (1 << 3)
#define CFG_MONCLKSTR (1 << 4)
#define CTL_MSTCONTINUE (1 << 0)
#define CTL_MSTSTART (1 << 1)
#define CTL_MSTSTOP (1 << 2)
#define CTL_SLVCONTINUE (1 << 0)
#define CTL_SLVNACK (1 << 1)
// Below matches the Niobe2 user manual
#define I2C_STAT_MSTSTATE (0x7<<1)
#define I2C_STAT_MSTST_IDLE (0x0<<1)
#define I2C_STAT_MSTST_RX (0x1<<1)
#define I2C_STAT_MSTST_TX (0x2<<1)
#define STAT_MSTPEND (1 << 0)
#define MASTER_STATE_MASK (0x7<<1)
#define STAT_MSTIDLE (0x0 << 1)
#define STAT_MSTRX (0x1 << 1)
#define STAT_MSTTX (0x2 << 1)
#define STAT_MSTNACKADDR (0x3 << 1)
#define STAT_MSTNACKTX (0x4 << 1)
#define STAT_MSTARBLOSS (1 << 4)
#define STAT_MSTSSERR (1 << 6)
#define STAT_SLVPEND (1 << 8)
#define SLAVE_STATE_MASK (0x3<<9)
#define STAT_SLVADDR (0x0 << 9)
#define STAT_SLVRX (0x1 << 9)
#define STAT_SLVTX (0x2 << 9)
#define STAT_SLVNOTSTR (1 << 11)
#define STAT_SLVSEL (1 << 14)
#define STAT_SLVDESEL (1 << 15)
#define STAT_MONOVERRUN (1 << 17)
#define STAT_MONACTIVE (1 << 18)
#define STAT_MONIDLE (1 << 19)
#define STAT_EVTIMEOUT (1 << 24)
#define STAT_SCLTIMEOUT (1 << 25)
void WaitI2CMasterState(LPC_I2C_TypeDef * ptr_LPC_I2C, uint32_t state);
void WaitI2CSlaveState(LPC_I2C_TypeDef * ptr_LPC_I2C, uint32_t state);
void I2CmasterWrite( uint8_t *WrBuf, uint8_t WrLen );
void I2CmasterWriteRead( uint8_t *WrBuf, uint8_t *RdBuf, uint8_t WrLen, uint8_t RdLen );
#endif /* lpc8xx_I2C_H_ */

View File

@@ -0,0 +1,40 @@
#ifndef __IAP_H__
#define __IAP_H__
#include <stdint.h> // standard types definitions
enum eIAP_COMMANDS
{
IAP_PREPARE = 50, // Prepare sector(s) for write operation
IAP_COPY_RAM2FLASH, // Copy RAM to Flash
IAP_ERASE, // Erase sector(s)
IAP_BLANK_CHECK, // Blank check sector(s)
IAP_READ_PART_ID, // Read chip part ID
IAP_READ_BOOT_VER, // Read chip boot code version
IAP_COMPARE, // Compare memory areas
IAP_REINVOKE_ISP, // Reinvoke ISP
IAP_READ_UID, // Read unique ID
IAP_ERASE_PAGE, // Erase page(s)
IAP_READ_MISR=70,
IAP_READ_MISR_EX=73,
};
struct sIAP
{
uint32_t cmd; // Command
uint32_t par[4]; // Parameters
uint32_t stat; // Status
uint32_t res[4]; // Result
};
#define REINVOKE_AUTO 0
#define REINVOKE_UART 1
// Pointer to ROM IAP entry functions
#define IAP_ENTRY_LOCATION 0x0F001FF1
// IAP Call
typedef void (*IAP_Entry) (uint32_t *cmd, uint32_t *stat);
#define IAP_Call ((IAP_Entry) IAP_ENTRY_LOCATION)
#endif // __IAP_H__

View File

@@ -0,0 +1,30 @@
#ifndef IOCON_H_
#define IOCON_H_
#define IOCON_MODE_MASK (0xFFFFFFe7)
#define IOCON_DACEN_MASK (0xFFFeFFFF)
#define MODE_INACTIVE (0<<3)
#define MODE_PULLDOWN (1<<3)
#define MODE_PULLUP (2<<3)
#define MODE_REPEATER (3<<3)
// DAC pin shifters
#define IOCON_MODE 3
#define IOCON_HYS 5
#define IOCON_INV 6
#define IOCON_RESERVED789 (0x1<<7)
#define IOCON_OD 10
#define IOCON_S_MODE 11
#define IOCON_CLK_DIV 13
#define IOCON_DAC_ENABLE 16
#endif // IOCON_H_

View File

@@ -0,0 +1,223 @@
/*
* @brief Common types used in LPC functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __LPC_TYPES_H_
#define __LPC_TYPES_H_
#include <stdint.h>
#include <stdbool.h>
/** @defgroup LPC_Types CHIP: LPC Common Types
* @ingroup CHIP_Common
* @{
*/
/** @defgroup LPC_Types_Public_Types LPC Public Types
* @{
*/
/**
* @brief Boolean Type definition
*/
typedef enum {FALSE = 0, TRUE = !FALSE} Bool;
/**
* @brief Boolean Type definition
*/
#if !defined(__cplusplus)
// typedef enum {false = 0, true = !false} bool;
#endif
/**
* @brief Flag Status and Interrupt Flag Status type definition
*/
typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState;
#define PARAM_SETSTATE(State) ((State == RESET) || (State == SET))
/**
* @brief Functional State Definition
*/
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define PARAM_FUNCTIONALSTATE(State) ((State == DISABLE) || (State == ENABLE))
/**
* @ Status type definition
*/
typedef enum {ERROR = 0, SUCCESS = !ERROR} Status;
/**
* Read/Write transfer type mode (Block or non-block)
*/
typedef enum {
NONE_BLOCKING = 0, /**< None Blocking type */
BLOCKING, /**< Blocking type */
} TRANSFER_BLOCK_T;
/** Pointer to Function returning Void (any number of parameters) */
typedef void (*PFV)();
/** Pointer to Function returning int32_t (any number of parameters) */
typedef int32_t (*PFI)();
/**
* @}
*/
/** @defgroup LPC_Types_Public_Macros LPC Public Macros
* @{
*/
/* _BIT(n) sets the bit at position "n"
* _BIT(n) is intended to be used in "OR" and "AND" expressions:
* e.g., "(_BIT(3) | _BIT(7))".
*/
#undef _BIT
/* Set bit macro */
#define _BIT(n) (1 << (n))
/* _SBF(f,v) sets the bit field starting at position "f" to value "v".
* _SBF(f,v) is intended to be used in "OR" and "AND" expressions:
* e.g., "((_SBF(5,7) | _SBF(12,0xF)) & 0xFFFF)"
*/
#undef _SBF
/* Set bit field macro */
#define _SBF(f, v) ((v) << (f))
/* _BITMASK constructs a symbol with 'field_width' least significant
* bits set.
* e.g., _BITMASK(5) constructs '0x1F', _BITMASK(16) == 0xFFFF
* The symbol is intended to be used to limit the bit field width
* thusly:
* <a_register> = (any_expression) & _BITMASK(x), where 0 < x <= 32.
* If "any_expression" results in a value that is larger than can be
* contained in 'x' bits, the bits above 'x - 1' are masked off. When
* used with the _SBF example above, the example would be written:
* a_reg = ((_SBF(5,7) | _SBF(12,0xF)) & _BITMASK(16))
* This ensures that the value written to a_reg is no wider than
* 16 bits, and makes the code easier to read and understand.
*/
#undef _BITMASK
/* Bitmask creation macro */
#define _BITMASK(field_width) ( _BIT(field_width) - 1)
/* NULL pointer */
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* Number of elements in an array */
#define NELEMENTS(array) (sizeof(array) / sizeof(array[0]))
/* Static data/function define */
#define STATIC static
/* External data/function define */
#define EXTERN extern
#if !defined(MAX)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#if !defined(MIN)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
/**
* @}
*/
/* Old Type Definition compatibility */
/** @addtogroup LPC_Types_Public_Types
* @{
*/
/** LPC type for character type */
typedef char CHAR;
/** LPC type for 8 bit unsigned value */
typedef uint8_t UNS_8;
/** LPC type for 8 bit signed value */
typedef int8_t INT_8;
/** LPC type for 16 bit unsigned value */
typedef uint16_t UNS_16;
/** LPC type for 16 bit signed value */
typedef int16_t INT_16;
/** LPC type for 32 bit unsigned value */
typedef uint32_t UNS_32;
/** LPC type for 32 bit signed value */
typedef int32_t INT_32;
/** LPC type for 64 bit signed value */
typedef int64_t INT_64;
/** LPC type for 64 bit unsigned value */
typedef uint64_t UNS_64;
#ifdef __CODE_RED
#define BOOL_32 bool
#define BOOL_16 bool
#define BOOL_8 bool
#else
/** 32 bit boolean type */
typedef bool BOOL_32;
/** 16 bit boolean type */
typedef bool BOOL_16;
/** 8 bit boolean type */
typedef bool BOOL_8;
#endif
#ifdef __CC_ARM
#define INLINE __inline
#else
#define INLINE inline
#endif
#ifdef __ICCARM__
#define ALIGNSTR(x) # x
#define ALIGN(x) _Pragma(ALIGNSTR(data_alignment = x))
#else /* __CC_ARM || __GNUC__ */
#define ALIGN(x) __attribute__ ((aligned(x)))
#endif
/**
* @}
*/
/**
* @}
*/
#endif /* __LPC_TYPES_H_ */

View File

@@ -0,0 +1,38 @@
/*
* lpc8xx_mrt.h
*
* Created on: Apr 11, 2016
* Author:
*/
#ifndef LPC8XX_MRT_H_
#define LPC8XX_MRT_H_
// INTVAL register values
#define NoForceLoad 0<<31
#define ForceLoad (uint32_t)1<<31
// INTVAL register bit field shifters
#define MRT_LOAD 31
// Control register bit field shifters
#define MRT_INTEN 0
#define MRT_MODE 1
// Control register values
#define MRT_Repeat 0
#define MRT_OneShot 1
#define MRT_OneShotBusStall 2
// Status register
#define MRT_INTFLAG 0
#define MRT_RUN 1
// Idle channel register
#define IDLE_CHAN 4
// IRQ_FLAG register
#define GFLAG0 0
#define GFLAG1 1
#define GFLAG2 2
#define GFLAG3 3
#endif /* LPC8XX_MRT_H_ */

View File

@@ -0,0 +1,136 @@
#ifndef __LPCPLU_H__
#define __LPCPLU_H__
#ifdef __cplusplus
extern "C" {
#endif
//#define CONFIG_PLU_nLUT_IN (5)
//#define CONFIG_PLU_nIN (6) /* Number of inputs */
//#define CONFIG_PLU_nLU (26) /* Number of LUTs */
//#define CONFIG_PLU_nFF (4) /* Number of FFs */
//#define CONFIG_PLU_nOU (8) /* Number of outputs */
#define LUT_INs 5
#define PLU_INs 6
#define PLU_LUTs 26
#define PLU_FFs 4
#define PLU_OUTs 8
#pragma anon_unions
typedef struct
{
struct { /* Input select register for LUT & Input... */
union {
__IO uint32_t INP[8]; /* Each LUT has maximum 5 inputs, the remaining are reserved. */
struct {
__IO uint32_t INP0;
__IO uint32_t INP1;
__IO uint32_t INP2;
__IO uint32_t INP3;
__IO uint32_t INP4;
uint32_t RESERVED[3];
};
} LUT_MUX[PLU_LUTs];
};
uint32_t RESERVED0[8*64-8*PLU_LUTs]; /* ...-0x7FC */
__IO uint32_t LUT_TRUTH[PLU_LUTs]; /* Truth-Table ("Look-up Table") programming */
uint32_t RESERVED1[64-PLU_LUTs]; /* ...-0x8FC */
__I uint32_t OUTPUTS; /* PLU Outputs Register (Read-only) */
uint32_t RESERVED2[3*64-1]; /* ...-0xBFC */
__IO uint32_t OUTPUT_MUX[PLU_OUTs]; /* Select register for PLU Ouptut */
} LPC_PLU_T;
/* PLU driver error code */
#define PLU_OK 0
#define PLU_INPUT_OUT_OF_RANGE 1
#define PLU_LUT_OUT_OF_RANGE 2
#define PLU_FF_OUT_OF_RANGE 3
#define PLU_OUTPUT_OUT_OF_RANGE 4
#define PLU_LUT_IN_DEFAULT 999
#define PLU_ROUTINE_FAILED 9999
#define PLU_STDL_OUT_OF_RANGE 0xDEAD
/* PLU masks, and micros if PLU tool is not used. */
#define LUT_OUT_MASK (1<<7)
#define FF_OUT_MASK (1<<6)
#define PLU_INPUT_MASK (0<<6)
#define LUT_OUT(x) (LUT_OUT_MASK | (x & 0x7F))
#define FF_OUT(x) (FF_OUT_MASK | (x & 0x3F))
#define PLU_INPUT(x) (PLU_INPUT_MASK | (x & 0x3F))
#define LUT_IN_OFFSET_INPUT 0
#define LUT_IN_OFFSET_LUT_OUT (PLU_INs)
#define LUT_IN_OFFSET_FF (PLU_INs+PLU_LUTs)
#define LUT_IN_PLU_INPUT(x) (LUT_IN_OFFSET_INPUT+x)
#define LUT_IN_LUT_OUT(x) (LUT_IN_OFFSET_LUT_OUT+x)
#define LUT_IN_FF(x) (LUT_IN_OFFSET_FF+x)
#define PLU_OUT_OFFSET_LUT_OUT 0
#define PLU_OUT_OFFSET_FF (PLU_LUTs)
#define PLU_OUT_LUT(x) (PLU_OUT_OFFSET_LUT_OUT+x)
#define PLU_OUT_FF(x) (PLU_OUT_OFFSET_FF+x)
extern uint32_t generate_plu_tt(uint32_t (* pnt_tt_function)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint32_t * pnt_tt);
#define INMUX_IN(x) (x)
#define INMUX_LUT(x) (PLU_INs+x)
#define INMUX_FF(x) (PLU_INs+PLU_LUTs+x)
#define INMUXDEF(x) INMUX_LUT(x)
#define PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,tt) LPC_PLU0->LUT_MUX[lut].INP[0]=in0; \
LPC_PLU0->LUT_MUX[lut].INP[1]=in1; \
LPC_PLU0->LUT_MUX[lut].INP[2]=in2; \
LPC_PLU0->LUT_MUX[lut].INP[3]=in3; \
LPC_PLU0->LUT_MUX[lut].INP[4]=in4; \
LPC_PLU0->LUT_TRUTH[lut]=tt
#define PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,tt) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,INMUXDEF(lut),tt)
#define PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,tt) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,INMUXDEF(lut),INMUXDEF(lut),tt)
#define PLU_LUT_2IN_CUSTOM(lut,in0,in1,tt) PLU_LUT_5IN_CUSTOM(lut,in0,in1,INMUXDEF(lut),INMUXDEF(lut),INMUXDEF(lut),tt)
#define PLU_LUT_2IN_AND(lut,in0,in1) PLU_LUT_2IN_CUSTOM(lut,in0,in1,0x88888888)
#define PLU_LUT_3IN_AND(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0x80808080)
#define PLU_LUT_4IN_AND(lut,in0,in1,in2,in3) PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,0x80008000)
#define PLU_LUT_5IN_AND(lut,in0,in1,in2,in3,in4) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,0x80000000)
#define PLU_LUT_2IN_NAND(lut,in0,in1) PLU_LUT_2IN_CUSTOM(lut,in0,in1,0x77777777)
#define PLU_LUT_3IN_NAND(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0x7F7F7F7F)
#define PLU_LUT_4IN_NAND(lut,in0,in1,in2,in3) PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,0x7FFF7FFF)
#define PLU_LUT_5IN_NAND(lut,in0,in1,in2,in3,in4) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,0x7FFFFFFF)
#define PLU_LUT_2IN_OR(lut,in0,in1) PLU_LUT_2IN_CUSTOM(lut,in0,in1,0xEEEEEEEE)
#define PLU_LUT_3IN_OR(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0xFEFEFEFE)
#define PLU_LUT_4IN_OR(lut,in0,in1,in2,in3) PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,0xFFFEFFFE)
#define PLU_LUT_5IN_OR(lut,in0,in1,in2,in3,in4) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,0xFFFFFFFE)
#define PLU_LUT_2IN_NOR(lut,in0,in1) PLU_LUT_2IN_CUSTOM(lut,in0,in1,0x11111111)
#define PLU_LUT_3IN_NOR(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0x01010101)
#define PLU_LUT_4IN_NOR(lut,in0,in1,in2,in3) PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,0x00010001)
#define PLU_LUT_5IN_NOR(lut,in0,in1,in2,in3,in4) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,0x00000001)
#define PLU_LUT_2IN_XOR(lut,in0,in1) PLU_LUT_2IN_CUSTOM(lut,in0,in1,0x66666666)
#define PLU_LUT_3IN_XOR(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0x96969696)
#define PLU_LUT_4IN_XOR(lut,in0,in1,in2,in3) PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,0x69966996)
#define PLU_LUT_5IN_XOR(lut,in0,in1,in2,in3,in4) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,0x96696996)
#define PLU_LUT_2IN_XNOR(lut,in0,in1) PLU_LUT_2IN_CUSTOM(lut,in0,in1,0x99999999)
#define PLU_LUT_3IN_XNOR(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0x69696969)
#define PLU_LUT_4IN_XNOR(lut,in0,in1,in2,in3) PLU_LUT_4IN_CUSTOM(lut,in0,in1,in2,in3,0x96699669)
#define PLU_LUT_5IN_XNOR(lut,in0,in1,in2,in3,in4) PLU_LUT_5IN_CUSTOM(lut,in0,in1,in2,in3,in4,0x69969669)
#define PLU_LUT_2IN1SEL_MUX(lut,in0,in1,in2) PLU_LUT_3IN_CUSTOM(lut,in0,in1,in2,0xCACACACA)
#define PLU_LUT_BUFFER(lut,in0) PLU_LUT_2IN_CUSTOM(lut,in0,INMUXDEF(lut),0xAAAAAAAA)
#define PLU_LUT_INVERTER(lut,in0) PLU_LUT_2IN_CUSTOM(lut,in0,INMUXDEF(lut),0x55555555)
#define OUTMUX_LUT(x) (x)
#define OUTMUX_FF(x) (PLU_LUTs+x)
#define PLU_OUT(out,src) LPC_PLU0->OUTPUT_MUX[out]=src
#ifdef __cplusplus
}
#endif
#endif /* __LPCPLU_H__ */

View File

@@ -0,0 +1,20 @@
#ifndef LPC8XX_PMU_H_
#define LPC8XX_PMU_H_
// PCON register shifters
#define PM 0
#define NODPD 3
#define SLEEPFLAG 8
#define DPDFLAG 11
// WUSRCREG and WUENAREG
#define PIO_15_WU (1<<0)
#define PIO_9_WU (1<<1)
#define PIO_8_WU (1<<2)
#define PIO_17_WU (1<<3)
#define PIO_13_WU (1<<4)
#define PIO_5_WU (1<<5)
#define PIO_11_WU (1<<6)
#define PIO_10_WU (1<<7)
#endif // LPC8XX_PMU_H_

View File

@@ -0,0 +1,78 @@
/*
* rom_api_.h
*
* Created on:
* By Arthur:
*/
#ifndef __ROM_API_H_
#define __ROM_API_H_
// FRO API
typedef struct _PWRD {
const unsigned int reserved[2];
void (*set_fro_frequency)(unsigned frequency);
} PWRD_API_T;
// Integer divide API routines
typedef struct {
int quot; // Quotient
int rem; // Remainder
} IDIV_RETURN_T;
typedef struct {
unsigned quot; // Quotient
unsigned rem; // Reminder
} UIDIV_RETURN_T;
typedef struct {
int (*sidiv)(int numerator, int denominator); // Signed integer division
unsigned (*uidiv)(unsigned numerator, unsigned denominator); // Unsigned integer division
IDIV_RETURN_T (*sidivmod)(int numerator, int denominator); // Signed integer division with remainder
UIDIV_RETURN_T (*uidivmod)(unsigned numerator, unsigned denominator); // Unsigned integer division with remainder
} ROM_DIV_API_T;
// The master structure that defines the table of all ROM APIs on the device (a.k.a ROM Driver table)
typedef struct _ROM_API {
const unsigned int reserved3[3]; // Offsets 0, 4, 8
const PWRD_API_T *pPWRD; // Offset 0xC. Power APIs function table base address
const ROM_DIV_API_T *divApiBase; // Offset 0x10. Integer division routines function table base address
const unsigned int reserved7[7]; // Offsets 0x14 - 0x2C
} LPC_ROM_API_T;
#define ROM_DRIVER_BASE (0x0F001FF8UL)
// Define a pointer to the master table
#define LPC_ROM_API (*(LPC_ROM_API_T * *)ROM_DRIVER_BASE)
// Use like this:
// ROM_DIV_API_T const *pROMDiv = LPC_ROM_API->divApiBase; // Create and initialize a pointer to the DIVIDE functions table
// int32_t result; // Declare an int variable
// result = pROMDiv->sidiv(-99, 6); // Call the sidiv routine, result now contains -99/6 = -16
// ROM_DIV_API_T const *pPwr = LPC_ROM_API->pPWRD; // Create and initialize a pointer to the power API functions table
// pPwr->set_power((uint32_t *)&cmd_table, (uint32_t *)&result_table); // Call the set_power routine
// Alternate form
#define LPC_PWRD_API ((PWRD_API_T * ) ((*(LPC_ROM_API_T * *) (ROM_DRIVER_BASE))->pPWRD))
#define LPC_DIVD_API ((ROM_DIV_API_T *) ((*(LPC_ROM_API_T * *) (ROM_DRIVER_BASE))->divApiBase))
// Use like this:
// LPC_PWRD_API->set_power((uint32_t *)&cmd_table, (uint32_t *)&result_table); // Call the set_power routine
#endif // rom_api.h

View File

@@ -0,0 +1,98 @@
/**********************************************************************
***********************************************************************
* 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<72>
* 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 lpc8xx_SPI_H_
#define lpc8xx_SPI_H_
#include "LPC8xx.h"
#include "swm.h"
#define SPI_FLASH_CS1() (LPC_GPIO_PORT->SET[0] = 1<<P0_16) /* Use for LPC804 */
#define SPI_FLASH_CS0() (LPC_GPIO_PORT->CLR[0] = 1<<P0_16) /* Use for LPC804 */
#define DATA_WIDTH 8
#define DUMMY_BYTE 0x55
#define BUFFER_SIZE 64
#define LPC_SPI0BAUDRate 500000
#define SPI_CFG_ENABLE (1 << 0)
#define SPI_CFG_MASTER (1 << 2)
#define SPI_CFG_SLAVE (0 << 2)
#define SPI_CFG_LSBF (1 << 3)
#define SPI_CFG_CPHA (1 << 4)
#define SPI_CFG_CPOL (1 << 5)
#define SPI_CFG_MOSIDRV (1 << 6)
#define SPI_CFG_LOOPBACK (1 << 7)
#define SPI_CFG_SPOL (1<<8)
//#define SPI_CFG_SPOL(s) (1 << (8 + s))
#define SPI_DLY_PREDELAY(d) ((d) << 0)
#define SPI_DLY_POSTDELAY(d) ((d) << 4)
#define SPI_DLY_FRAMEDELAY(d) ((d) << 8)
#define SPI_DLY_INTERDELAY(d) ((d) << 12)
#define SPI_STAT_RXRDY (1 << 0)
#define SPI_STAT_TXRDY (1 << 1)
#define SPI_STAT_RXOVERRUN (1 << 2)
#define SPI_STAT_TXUNDERRUN (1 << 3)
#define SPI_STAT_SELNASSERT (1 << 4)
#define SPI_STAT_SELNDEASSERT (1 << 5)
#define SPI_STAT_CLKSTALL (1 << 6)
#define SPI_STAT_ET (1 << 7)
#define SPI_STAT_MSTIDLE (1<<8)
#define SPI_STAT_ERROR_MASK (SPI_STAT_RXOVERRUN|SPI_STAT_TXUNDERRUN|SPI_STAT_SELNASSERT|SPI_STAT_SELNDEASSERT|SPI_STAT_CLKSTALL)
#define SPI_RXRDYEN (1<<0)
#define SPI_TXRDYEN (1<<1)
#define SPI_RXOVEN (1<<2)
#define SPI_TXUREN (1<<3)
#define SPI_SSAEN (1<<4)
#define SPI_SSDEN (1<<5)
#define SPI_RXRDY (1<<0)
#define SPI_TXRDY (1<<1)
#define SPI_RXOV (1<<2)
#define SPI_TXUR (1<<3)
#define SPI_SSA (1<<4)
#define SPI_SSD (1<<5)
#define SPI_CTL_TXSSELN (1<<16)
#define SPI_CTL_EOT (1<<20)
#define SPI_CTL_EOF (1<<21)
#define SPI_CTL_RXIGNORE (1<<22)
#define SPI_CTL_LEN(b) (((b)-1)<<24)
#define SPI_TXDATCTL_SSELN(s) (s << 16)
#define SPI_TXDATCTL_EOT (1 << 20)
#define SPI_TXDATCTL_EOF (1 << 21)
#define SPI_TXDATCTL_RX_IGNORE (1 << 22)
#define SPI_TXDATCTL_FSIZE(s) ((s) << 24)
#define SPI_RXDAT_SOT (1 << 20)
void SPI0_IRQHandler(void);
void SPImasterWriteOnly( uint8_t *WrBuf, uint32_t WrLen );
void SPImasterWriteRead( uint8_t *WrBuf, uint8_t *RdBuf, uint32_t WrLen );
void SPImasterReadOnly( uint8_t *RdBuf, uint32_t RdLen );
#endif /* lpc8xx_SPI_H_ */

View File

@@ -0,0 +1,253 @@
/*
* lpc8xx_swm.h
*
* Created on: March 28, 2017
*
*/
#ifndef LPC8XX_SWM_H_
#define LPC8XX_SWM_H_
#include "LPC8xx.h"
// Port pin number equates
#define P0_0 0
#define P0_1 1
#define P0_2 2
#define P0_3 3
#define P0_4 4
#define P0_5 5
#define P0_6 6
#define P0_7 7
#define P0_8 8
#define P0_9 9
#define P0_10 10
#define P0_11 11
#define P0_12 12
#define P0_13 13
#define P0_14 14
#define P0_15 15
#define P0_16 16
#define P0_17 17
#define P0_18 18
#define P0_19 19
#define P0_20 20
#define P0_21 21
#define P0_22 22
#define P0_23 23
#define P0_24 24
#define P0_25 25
#define P0_26 26
#define P0_27 27
#define P0_28 28
#define P0_29 29
#define P0_30 30
#define P0_31 31
#define P1_0 32
#define P1_1 33
#define P1_2 34
#define P1_3 35
#define P1_4 36
#define P1_5 37
#define P1_6 38
#define P1_7 39
#define P1_8 40
#define P1_9 41
#define P1_10 42
#define P1_11 43
#define P1_12 44
#define P1_13 45
#define P1_14 46
#define P1_15 47
#define P1_16 48
#define P1_17 49
#define P1_18 50
#define P1_19 51
#define P1_20 52
#define P1_21 53
#define P1_22 54
#define P1_23 55
#define P1_24 56
#define P1_25 57
#define P1_26 58
#define P1_27 59
#define P1_28 60
#define P1_29 61
#define P1_30 62
#define P1_31 63
#define NO_PIN 0xFF
// Function name equates (for normal people)
#define U0_TXD 0
#define U0_RXD 1
#define U0_RTS 2
#define U0_CTS 3
#define U0_SCLK 4
#define U1_TXD 5
#define U1_RXD 6
#define U1_SCLK 7
#define SPI0_SCK 8
#define SPI0_MOSI 9
#define SPI0_MISO 10
#define SPI0_SSEL0 11
#define SPI0_SSEL1 12
#define T0_CAP0 13
#define T0_CAP1 14
#define T0_CAP2 15
#define T0_MAT0 16
#define T0_MAT1 17
#define T0_MAT2 18
#define T0_MAT3 19
#define I2C0_SDA 20
#define I2C0_SCL 21
#define COMP0_OUT 22
#define ACOMP 22
#define CLKOUT 23
#define GPIO_INT_BMAT 24
#define LVLSHFT_IN0 25
#define LVLSHFT_IN1 26
#define LVLSHFT_OUT0 27
#define LVLSHFT_OUT1 28
#define I2C1_SDA 29
#define I2C1_SCL 30
#define PLU_CLKIN 31
#define CAPT_X0 32
#define CAPT_X1 33
#define CAPT_X2 34
#define CAPT_X3 35
#define CAPT_X4 36
#define CAPT_YL 37
#define CAPT_YH 38
#define num_funcs 39
// Function name equates for the PINASSIGN_4PIN register
#define min_4pin_func 100
#define PLU_IN0 100
#define PLU_IN1 101
#define PLU_IN2 102
#define PLU_IN3 103
#define PLU_IN4 104
#define PLU_IN5 105
#define PLU_OUT0 106
#define PLU_OUT1 107
#define PLU_OUT2 108
#define PLU_OUT3 109
#define PLU_OUT4 110
#define PLU_OUT5 111
#define PLU_OUT6 112
#define PLU_OUT7 113
#define max_4pin_func 113
// PINENABLE0 register defines
#define ACMP_I1 (1<<0)
#define ACMP_I2 (1<<1)
#define ACMP_I3 (1<<2)
#define ACMP_I4 (1<<3)
#define SWCLK (1<<4)
#define SWDIO (1<<5)
#define RESETN (1<<6)
#define CLKIN (1<<7)
#define WKTCLKIN (1<<8)
#define VDDCMP (1<<9)
#define ADC_0 (1<<10)
#define ADC_1 (1<<11)
#define ADC_2 (1<<12)
#define ADC_3 (1<<13)
#define ADC_4 (1<<14)
#define ADC_5 (1<<15)
#define ADC_6 (1<<16)
#define ADC_7 (1<<17)
#define ADC_8 (1<<18)
#define ADC_9 (1<<19)
#define ADC_10 (1<<20)
#define ADC_11 (1<<21)
#define ACMP_I5 (1<<22)
#define DACOUT0 (1<<23)
/**
* @brief LPC8XX Switch Matrix PLU Movable pins (works for LPC804 with PLU)
*/
typedef enum CHIP_SWM_PLU_MOVABLE {
PLU_INPUT0_PIO0_0 = 0x00 << 0, /*!< PLU_INPUT0 - PIO0_0 */
PLU_INPUT0_PIO0_8 = 0x01 << 0, /*!< PLU_INPUT0 - PIO0_8 */
PLU_INPUT0_PIO0_17 = 0x02 << 0, /*!< PLU_INPUT0 - PIO0_17 */
PLU_INPUT0_NONE = 0x03 << 0, /*!< PLU_INPUT0 - NONE */
PLU_INPUT1_PIO0_1 = 0x00 << 2, /*!< PLU_INPUT1 - PIO0_1 */
PLU_INPUT1_PIO0_9 = 0x01 << 2, /*!< PLU_INPUT1 - PIO0_9 */
PLU_INPUT1_PIO0_18 = 0x02 << 2, /*!< PLU_INPUT1 - PIO0_18 */
PLU_INPUT1_NONE = 0x03 << 2, /*!< PLU_INPUT1 - NONE */
PLU_INPUT2_PIO0_2 = 0x00 << 4, /*!< PLU_INPUT2 - PIO0_2 */
PLU_INPUT2_PIO0_10 = 0x01 << 4, /*!< PLU_INPUT2 - PIO0_10 */
PLU_INPUT2_PIO0_19 = 0x02 << 4, /*!< PLU_INPUT2 - PIO0_19 */
PLU_INPUT2_NONE = 0x03 << 4, /*!< PLU_INPUT2 - NONE */
PLU_INPUT3_PIO0_3 = 0x00 << 6, /*!< PLU_INPUT3 - PIO0_3 */
PLU_INPUT3_PIO0_11 = 0x01 << 6, /*!< PLU_INPUT3 - PIO0_11 */
PLU_INPUT3_PIO0_20 = 0x02 << 6, /*!< PLU_INPUT3 - PIO0_20 */
PLU_INPUT3_NONE = 0x03 << 6, /*!< PLU_INPUT3 - NONE */
PLU_INPUT4_PIO0_4 = 0x00 << 8, /*!< PLU_INPUT4 - PIO0_4 */
PLU_INPUT4_PIO0_12 = 0x01 << 8, /*!< PLU_INPUT4 - PIO0_12 */
PLU_INPUT4_PIO0_21 = 0x02 << 8, /*!< PLU_INPUT4 - PIO0_21 */
PLU_INPUT4_NONE = 0x03 << 8, /*!< PLU_INPUT4 - NONE */
PLU_INPUT5_PIO0_5 = 0x00 << 10, /*!< PLU_INPUT5 - PIO0_5 */
PLU_INPUT5_PIO0_13 = 0x01 << 10, /*!< PLU_INPUT5 - PIO0_13 */
PLU_INPUT5_PIO0_22 = 0x02 << 10, /*!< PLU_INPUT5 - PIO0_22 */
PLU_INPUT5_NONE = 0x03 << 10, /*!< PLU_INPUT5 - NONE */
PLU_OUTPUT0_PIO0_7 = 0x00 << 12, /*!< PLU_OUTPUT0 - PIO0_7 */
PLU_OUTPUT0_PIO0_14 = 0x01 << 12, /*!< PLU_OUTPUT0 - PIO0_14 */
PLU_OUTPUT0_PIO0_23 = 0x02 << 12, /*!< PLU_OUTPUT0 - PIO0_23 */
PLU_OUTPUT0_NONE = 0x03 << 12, /*!< PLU_OUTPUT0 - NONE */
PLU_OUTPUT1_PIO0_8 = 0x00 << 14, /*!< PLU_OUTPUT1 - PIO0_8 */
PLU_OUTPUT1_PIO0_15 = 0x01 << 14, /*!< PLU_OUTPUT1 - PIO0_15 */
PLU_OUTPUT1_PIO0_24 = 0x02 << 14, /*!< PLU_OUTPUT1 - PIO0_24 */
PLU_OUTPUT1_NONE = 0x03 << 14, /*!< PLU_OUTPUT1 - NONE */
PLU_OUTPUT2_PIO0_9 = 0x00 << 16, /*!< PLU_OUTPUT2 - PIO0_9 */
PLU_OUTPUT2_PIO0_16 = 0x01 << 16, /*!< PLU_OUTPUT2 - PIO0_16 */
PLU_OUTPUT2_PIO0_25 = 0x02 << 16, /*!< PLU_OUTPUT2 - PIO0_25 */
PLU_OUTPUT2_NONE = 0x03 << 16, /*!< PLU_OUTPUT2 - NONE */
PLU_OUTPUT3_PIO0_10 = 0x00 << 18, /*!< PLU_OUTPUT3 - PIO0_10 */
PLU_OUTPUT3_PIO0_17 = 0x01 << 18, /*!< PLU_OUTPUT3 - PIO0_17 */
PLU_OUTPUT3_PIO0_26 = 0x02 << 18, /*!< PLU_OUTPUT3 - PIO0_26 */
PLU_OUTPUT3_NONE = 0x03 << 18, /*!< PLU_OUTPUT3 - NONE */
PLU_OUTPUT4_PIO0_11 = 0x00 << 20, /*!< PLU_OUTPUT4 - PIO0_11 */
PLU_OUTPUT4_PIO0_18 = 0x01 << 20, /*!< PLU_OUTPUT4 - PIO0_18 */
PLU_OUTPUT4_PIO0_27 = 0x02 << 20, /*!< PLU_OUTPUT4 - PIO0_27 */
PLU_OUTPUT4_NONE = 0x03 << 20, /*!< PLU_OUTPUT4 - NONE */
PLU_OUTPUT5_PIO0_12 = 0x00 << 22, /*!< PLU_OUTPUT5 - PIO0_12 */
PLU_OUTPUT5_PIO0_19 = 0x01 << 22, /*!< PLU_OUTPUT5 - PIO0_19 */
PLU_OUTPUT5_PIO0_28 = 0x02 << 22, /*!< PLU_OUTPUT5 - PIO0_28 */
PLU_OUTPUT5_NONE = 0x03 << 22, /*!< PLU_OUTPUT5 - NONE */
PLU_OUTPUT6_PIO0_13 = 0x00 << 24, /*!< PLU_OUTPUT6 - PIO0_13 */
PLU_OUTPUT6_PIO0_20 = 0x01 << 24, /*!< PLU_OUTPUT6 - PIO0_20 */
PLU_OUTPUT6_PIO0_29 = 0x02 << 24, /*!< PLU_OUTPUT6 - PIO0_29 */
PLU_OUTPUT6_NONE = 0x03 << 24, /*!< PLU_OUTPUT6 - NONE */
PLU_OUTPUT7_PIO0_14 = 0x00 << 26, /*!< PLU_OUTPUT7 - PIO0_14 */
PLU_OUTPUT7_PIO0_21 = 0x01 << 26, /*!< PLU_OUTPUT7 - PIO0_21 */
PLU_OUTPUT7_PIO0_30 = 0x02 << 26, /*!< PLU_OUTPUT7 - PIO0_30 */
PLU_OUTPUT7_NONE = 0x03 << 26, /*!< PLU_OUTPUT7 - NONE */
} CHIP_SWM_PLU_MOVABLE_T;
// Function prototypes
void ConfigSWM(uint32_t func, uint32_t port_pin);
void EnableFixedPinFunc(uint32_t func);
void DisableFixedPinFunc(uint32_t func);
#endif /* LPC8XX_SWM_H_ */

View File

@@ -0,0 +1,220 @@
/*
* lpc8xx_syscon.h
*
* Created on:
* Author:
*/
#include <stdint.h>
#ifndef LPC8XX_SYSCON_H_
#define LPC8XX_SYSCON_H_
// SYSAHBCLKCTRL0 register bits
#define ROM (1<<1)
#define RAM0_1 (1<<2)
#define FLASH (1<<4)
#define I2C0 (1<<5)
#define GPIO (1<<6)
#define GPIO0 (1<<6)
#define SWM (1<<7)
#define WKT (1<<9)
#define MRT (1<<10)
#define SPI0 (1<<11)
#define CRC (1<<13)
#define UART0 (1<<14)
#define UART1 (1<<15)
#define WWDT (1<<17)
#define IOCON (1<<18)
#define ACMP (1<<19)
#define GPIO1 (1<<20)
#define I2C1 (1<<21)
#define ADC (1<<24)
#define CTIMER0 (1<<25)
#define DAC0 (1<<27)
#define GPIO_INT (1<<28)
// SYSAHBCLKCTRL1 register bits
#define CAPT (1<<0)
#define PLU (1<<5)
// SYSAHBCLKCTRL[] register bits (alternate form)
typedef enum {
CLK_ROM = 1 ,
CLK_RAM0_1 ,
CLK_FLASH = 4 ,
CLK_I2C0 ,
CLK_GPIO0 ,
CLK_SWM ,
CLK_WKT = 9 ,
CLK_MRT ,
CLK_SPI0 ,
CLK_CRC = 13 ,
CLK_UART0 ,
CLK_UART1 ,
CLK_WWDT = 17 ,
CLK_IOCON ,
CLK_ACMP ,
CLK_I2C1 = 21 ,
CLK_ADC = 24 ,
CLK_CTIMER0 ,
CLK_DAC0 = 27 ,
CLK_GPIO_INT ,
CLK_CAPT = 32,
CLK_PLU = 37
} CHIP_SYSCON_CLOCK_CTRL_T;
// PRESETCTRL0 register bits
#define FLASH_RST_N ~(1<<4)
#define I2C0_RST_N ~(1<<5)
#define GPIO0_RST_N ~(1<<6)
#define SWM_RST_N ~(1<<7)
#define WKT_RST_N ~(1<<9)
#define MRT_RST_N ~(1<<10)
#define SPI0_RST_N ~(1<<11)
#define CRC_RST_N ~(1<<13)
#define UART0_RST_N ~(1<<14)
#define UART1_RST_N ~(1<<15)
#define IOCON_RST_N ~(1<<18)
#define ACMP_RST_N ~(1<<19)
#define GPIO1_RST_N ~(1<<20)
#define I2C1_RST_N ~(1<<21)
#define ADC_RST_N ~(1<<24)
#define CTIMER0_RST_N ~(1<<25)
#define DAC0_RST_N ~(1<<27)
#define GPIOINT_RST_N ~(1<<28)
// PRESETCTRL1 register bits
#define CAPT_RST_N ~(1<<0)
#define FRG0_RST_N ~(1<<3)
#define PLU_RST_N ~(1<<5)
// PRESETCTRL[] register bits (alternate form)
typedef enum {
RESET_FLASH = 4 ,
RESET_I2C0 ,
RESET_GPIO0 ,
RESET_SWM ,
RESET_WKT = 9 ,
RESET_MRT ,
RESET_SPI0 ,
RESET_CRC = 13 ,
RESET_UART0 ,
RESET_UART1 ,
RESET_IOCON = 18,
RESET_ACMP ,
RESET_I2C1 = 21 ,
RESET_ADC = 24 ,
RESET_CTIMER0 ,
RESET_DAC0 = 27 ,
RESET_GPIO_INT ,
RESET_CAPT = 32 ,
RESET_FRG0 = 35 ,
RESET_PLU = 37
} CHIP_SYSCON_PERIPH_RESET_T;
// STARTERP0 register bits
#define PINT0_WAKEUP (1<<0)
#define PINT1_WAKEUP (1<<1)
#define PINT2_WAKEUP (1<<2)
#define PINT3_WAKEUP (1<<3)
#define PINT4_WAKEUP (1<<4)
#define PINT5_WAKEUP (1<<5)
#define PINT6_WAKEUP (1<<6)
#define PINT7_WAKEUP (1<<7)
// STARTERP1 register bits
#define SPI0_INT_WAKEUP (1<<0)
#define USART0_INT_WAKEUP (1<<3)
#define USART1_INT_WAKEUP (1<<4)
#define I2C1_INT_WAKEUP (1<<7)
#define I2C0_INT_WAKEUP (1<<8)
#define WWDT_INT_WAKE (1<<12)
#define BOD_INT_WAKE (1<<13)
#define WKT_INT_WAKEUP (1<<15)
// PDAWAKECFG and PDRUNCFG register bits
#define FROOUT_PD (1<<0)
#define FRO_PD (1<<1)
#define FLASH_PD (1<<2)
#define BOD_PD (1<<3) // Also for PDSLEEPCFG
#define ADC_PD (1<<4)
#define LPOSC_PD (1<<6) // Also for PDSLEEPCFG
#define DAC0_PD (1<<13)
#define ACMP_PD (1<<15)
// LPOSCCLKEN register bit field shifters
#define WWDT_CLK_EN 0
#define WKT_CLK_EN 1
// BODCTRL register bit field shifters
#define BODRSTLEV 0
#define BODINTVAL 2
#define BODRSTENA 4
// Below entries are for clock select mux functions
typedef enum {
FCLKSEL_FRO_CLK = 0,
FCLKSEL_MAIN_CLK = 1,
FCLKSEL_FRG0CLK = 2,
FCLKSEL_FRO_DIV_CLK = 4,
FCLKSEL_OFF = 7
} SYSCON_FCLKSEL_CLK_T;
typedef enum {
FCLK_TO_UART0 = 0,
FCLK_TO_UART1 = 1,
FCLK_TO_I2C0 = 5,
FCLK_TO_I2C1 = 6,
FCLK_TO_SPI0 = 9
} SYSCON_FCLKSEL_T;
typedef enum {
FRGCLKSEL_FRO_CLK = 0,
FRGCLKSEL_MAIN_CLK = 1,
FRGCLKSEL_OFF = 3
} SYSCON_FRGCLKSEL_T;
typedef enum {
CLKOUTSEL_FRO_CLK = 0,
CLKOUTSEL_MAIN_CLK = 1,
CLKOUTSEL_EXTERNAL_CLK = 3,
CLKOUTSEL_LPOSC_CLK = 4,
CLKOUTSEL_OFF = 7
} SYSCON_CLKOUTSEL_T;
typedef enum {
ADCCLKSEL_FRO_CLK = 0,
ADCCLKSEL_EXTERNAL_CLK = 1,
ADCCLKSEL_OFF = 3
} SYSCON_ADCCLKSEL_T;
void Enable_Periph_Clock(uint32_t slot);
void Disable_Periph_Clock(uint32_t slot);
void Do_Periph_Reset(uint32_t slot);
//void Config_Syspll(unsigned int which_clock, unsigned int pll_ctrl_value);
void Config_Fclksel_Mux(uint32_t to_which_periph, uint32_t which_clock);
#endif /* LPC8XX_SYSCON_H_ */

View File

@@ -0,0 +1,67 @@
/**************************************************************************//**
* @file system_LPC8xx.h
* @brief CMSIS Device System Header File for
* NXP LPC845
* @version V1.10
* @date 19. August 2014
*
* @note
* Copyright (C) 2014 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_LPC8xx_H
#define __SYSTEM_LPC8xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t main_clk;
extern uint32_t wdt_osc_clk;
extern uint32_t sys_pll0_clk;
extern uint32_t fro_clk;
extern uint32_t fro_div_clk;
extern uint32_t system_ahb_clk;
/**
* 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_LPC8xx_H */

View File

@@ -0,0 +1,69 @@
/**********************************************************************
***********************************************************************
* 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<72>
* 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 __lpc8xx_UART_H
#define __lpc8xx_UART_H
#define UART_EN (0x01<<0)
#define DATA_LENG_7 (0x00<<2)
#define DATA_LENG_8 (0x01<<2)
#define DATA_LENG_9 (0x02<<2)
#define PARITY_NONE (0x00<<4)
#define PARITY_NC (0x01<<4)
#define PARITY_EVEN (0x02<<4)
#define PARITY_ODD (0x03<<4)
#define STOP_BIT_1 (0x00<<6)
#define STOP_BIT_2 (0x01<<6)
#define MODE_32K (0x01<<7)
#define EXT_CTS_EN (0x01<<9)
#define INT_CTS_EN (0x01<<10)
#define SYNC_EN (0x01<<11)
#define CLK_POL (0x01<<12)
#define SYNC_MS (0x01<<14)
#define LOOPBACK (0x01<<15)
// UART Control register
#define TXBRK_EN (0x01<<1)
#define ADDR_DET (0x01<<2)
#define TXDIS (0x01<<6)
#define CC (0x01<<8)
#define CCCLR (0x01<<9)
// UART status register
#define RXRDY (0x01<<0)
#define RXIDLE (0x01<<1)
#define TXRDY (0x01<<2)
#define TXIDLE (0x01<<3)
#define CTS (0x01<<4)
#define CTS_DELTA (0x01<<5)
#define TXINT_DIS (0x01<<6)
#define OVRN_ERR (0x01<<8)
#define RXBRK (0x01<<10)
#define DELTA_RXBRK (0x01<<11)
#define START_DETECT (0x01<<12)
#define FRM_ERR (0x01<<13)
#define PAR_ERR (0x01<<14)
#define RXNOISE (0x01<<15)
#endif /* __lpc8xx_UART_H */

View File

@@ -0,0 +1,20 @@
/*
* lpc8xx_wkt.h
*
* Created on: Apr 11, 2016
* Author:
*/
#ifndef LPC8XX_WKT_H_
#define LPC8XX_WKT_H_
// Control register shifters
#define WKT_CLKSEL 0
#define WKT_ALARMFLAG 1
#define WKT_CLEARCTR 2
// Control register fields
#define DIVIDED_IRC 0
#define LOW_POWER_OSC 1
#endif /* LPC8XX_WKT_H_ */

View File

@@ -0,0 +1,21 @@
/*
* lpc8xx_wwdt.h
*
* Created on: Apr 12, 2016
* Author:
*/
#ifndef LPC8XX_WWDT_H_
#define LPC8XX_WWDT_H_
// MOD register
#define WDEN 0
#define WDRESET 1
#define WDTOF 2
#define WDINT 3
#define WDPROTECT 4
#define LOCK 5
#endif /* LPC8XX_WWDT_H_ */

View File

@@ -0,0 +1,31 @@
There seems to be no LPCOpen library for the LPC804:
https://www.nxp.com/design/microcontrollers-developer-resources/lpcopen-libraries-and-examples/lpcopen-software-development-platform-lpc8xx:LPCOPEN-SOFTWARE-FOR-LPC8XX
Source: LPC804-EX-CODE-MCUXPRESSO.zip from nxp.com
available from here:
https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc800-cortex-m0-plus-/low-cost-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:LPC80X?tab=Design_Tools_Tab#t749
"LPC804 Example Code Bundle MCUXpresso"
Toplevel include should be "LPC8xx.h".
The name "LPC8xx.h" might be misleading: This file is specific to the LPC804, but
I decided not to change the name, but keep the orginal file name from the above zip
folder. In fact plan is not to modify any of the files in lpc_chip_804 so that they can
be overwritten at any time with the original files (maybe chip_setup.h is an exception).
For some reason the variable "SystemCoreClock" is renamed to "main_clk".
While working in the code, I saw, that there are some issues in "lpc_chip_804":
- Removed includes of "utilities.h" because the funcionality is not called
- added inclusion of "swm.h" from "spi.h", because "spi.h" makes use of
some definitions from "swm.h"
- Removed "Config_Syspll" declaration from "syscon.h" because it is removed in the src.
- Alligned "unsigned int" with "uint32_t" declarations in syscon.h and .c
- Change the inclusion of "lpc8xx.h" to "LPC8xx.h" in i2c.h
As a conclusion, I had to change the following files compared to the original zip content:
i2c.h syscon.h syscon.c i2c.c spi.c spi.h plu.c

View File

@@ -0,0 +1,119 @@
/****************************************************************************
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
****************************************************************************/
#include "LPC8xx.h" /* LPC8xx Peripheral Registers */
#include "gpio.h"
#include "syscon.h"
/*****************************************************************************
** Function name: GPIOInit
**
** Description: Enable clock, then reset the GPIO module.
** See syscon.h for register bit definitions.
**
** Parameters: None
**
** Returned value: None
*****************************************************************************/
void GPIOInit( void )
{
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL[0] |= (GPIO0 | GPIO1);
/* Peripheral reset to the GPIO module. '0' asserts, '1' deasserts reset. */
LPC_SYSCON->PRESETCTRL[0] &= (GPIO0_RST_N & GPIO1_RST_N);
LPC_SYSCON->PRESETCTRL[0] |= ~(GPIO0_RST_N & GPIO1_RST_N);
return;
}
/*****************************************************************************
** Function name: GPIOGetPinValue
**
** Description: Read Current state of port pin, PIN register value
**
** parameters: port number, bit position
** Returned value: The value, obviously
**
*****************************************************************************/
uint32_t GPIOGetPinValue( uint32_t portNum, uint32_t bitPosi )
{
return (LPC_GPIO_PORT->PIN[portNum] & (1<<bitPosi));
}
/*****************************************************************************
** Function name: GPIOSetBitValue
**
** Descriptions: Set/clear a bit in a specific position
**
** parameters: port num, bit position, bit value
**
** Returned value: None
**
*****************************************************************************/
void GPIOSetBitValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal )
{
if ( bitVal )
{
LPC_GPIO_PORT->SET[portNum] = 1<<bitPosi;
}
else
{
LPC_GPIO_PORT->CLR[portNum] = 1<<bitPosi;
}
return;
}
/*****************************************************************************
** Function name: GPIOSetDir
**
** Descriptions: Set the direction in GPIO port
**
** parameters: portNum, bit position, direction (1 out, 0 input)
**
** Returned value: None
**
*****************************************************************************/
void GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir )
{
if( dir )
{
LPC_GPIO_PORT->DIRSET[portNum] = 1<<bitPosi;
}
else
{
LPC_GPIO_PORT->DIRCLR[portNum] = 1<<bitPosi;
}
return;
}
/******************************************************************************
** End Of File
******************************************************************************/

View File

@@ -0,0 +1,129 @@
/*
* i2c.c
*
* Created on: Apr 5, 2016
*
*/
#include "LPC8xx.h"
//#include "utilities.h"
#include "i2c.h"
/*****************************************************************************
** Function name: I2CmasterWrite
**
** Description: Write a block of data to the I2C slave using polling.
**
** parameters: pointer to the write buffer starting with the I2C slave address.
** Length of the write data block
** Returned value: None
**
*****************************************************************************/
void I2CmasterWrite( uint8_t *WrBuf, uint8_t WrLen )
{
uint32_t i;
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_IDLE); // Wait for the master state to be idle
LPC_I2C0->MSTDAT = *WrBuf | 0; // Address with 0 for RWn bit (WRITE)
LPC_I2C0->MSTCTL = CTL_MSTSTART; // Start the transaction by setting the MSTSTART bit to 1 in the Master control register.
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the address to be ACK'd
for ( i = 0; i < WrLen; i++ ) {
LPC_I2C0->MSTDAT = *(WrBuf + i + 1); // Send the data to the slave
LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // Continue the transaction
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the data to be ACK'd
}
LPC_I2C0->MSTCTL = CTL_MSTSTOP; // Send a stop to end the transaction
return;
}
/*****************************************************************************
** Function name: I2CmasterWriteRead
**
** Description: Write the command to the i2C slave and followed by using repeated start
to read a block of data from the I2C slave.
**
** parameters: pointer to the write buffer
pointer to the read buffer
length of the write data buffer
length of the read data buffer
e.g. WR_Addr, Write data (0~WrLen-1), RD_addr, Read data (0~RdLen-1)
** Returned value: None
**
*****************************************************************************/
void I2CmasterWriteRead( uint8_t *WrBuf, uint8_t *RdBuf, uint8_t WrLen, uint8_t RdLen )
{
uint32_t i, i2c_addr;
i2c_addr = *WrBuf;
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_IDLE); // Wait for the master state to be idle
LPC_I2C0->MSTDAT = i2c_addr; // Address with 0 for RWn bit (WRITE)
LPC_I2C0->MSTCTL = CTL_MSTSTART; // Start the transaction by setting the MSTSTART bit to 1 in the Master control register.
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the address to be ACK'd
for ( i = 0; i < WrLen; i++ ) {
LPC_I2C0->MSTDAT = *(WrBuf + i + 1); // Send the data to the slave
LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // Continue the transaction
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_TX); // Wait for the data to be ACK'd
}
LPC_I2C0->MSTDAT = i2c_addr | RD_BIT; // Address with 1 for RWn bit (READ)
LPC_I2C0->MSTCTL = CTL_MSTSTART; // Start the transaction by setting the MSTSTART bit to 1 in the Master control register.
for ( i = 0; i < RdLen; i++ ) {
WaitI2CMasterState(LPC_I2C0, I2C_STAT_MSTST_RX); // Wait for the data to be ACK'd
*(RdBuf + i) = LPC_I2C0->MSTDAT; // Send the data to the slave
LPC_I2C0->MSTCTL = CTL_MSTCONTINUE; // Continue the transaction
}
LPC_I2C0->MSTCTL = CTL_MSTSTOP; // Send a stop to end the transaction
return;
}
/*****************************************************************************
** Function name: WaitI2CMasterState
**
** Description: Waits for I2C master pending, then compares the master
** state to the state parameter. If compare fails, enter
** a while(1) loop. If compare passes, return.
**
** parameters:
** ptr_LPC_I2C: A pointer to an I2C instance
** state: One of the 3-bit Master function state codes of the I2C
** Returned value: None
**
*****************************************************************************/
void WaitI2CMasterState(LPC_I2C_TypeDef * ptr_LPC_I2C, uint32_t state) {
while(!(ptr_LPC_I2C->STAT & STAT_MSTPEND)); // Wait for MSTPENDING bit set in STAT register
if((ptr_LPC_I2C->STAT & MASTER_STATE_MASK) != state) { // If master state mismatch ...
while(1); // die here and debug the problem
}
return; // If no mismatch, return
}
/*****************************************************************************
** Function name: WaitI2CSlaveState
**
** Description: Waits for I2C slave pending, then compares the slave
** state to the state parameter. If compare fails, enter
** a while(1) loop. If compare passes, return.
**
** parameters:
** ptr_LPC_I2C: A pointer to an I2C instance
** state: One of the 2-bit slave function state codes of the I2C
** Returned value: None
**
*****************************************************************************/
void WaitI2CSlaveState(LPC_I2C_TypeDef * ptr_LPC_I2C, uint32_t state) {
while(!(ptr_LPC_I2C->STAT & STAT_SLVPEND)); // Wait for SLVPENDING bit in STAT register
if((ptr_LPC_I2C->STAT & SLAVE_STATE_MASK) != state) // If state mismatches
while(1); // Die here, and debug the problem
return; // Otherwise, return
}

View File

@@ -0,0 +1,67 @@
/*
* @brief LPC80X Analog comparator driver
*
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes 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' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "LPC8xx.h"
#include "core_cm0plus.h"
#include "syscon.h"
#include "plu.h"
#include <stdarg.h>
typedef struct {
uint16_t id;
uint16_t inputs;
uint32_t tt;
} _stdl_id_ins_tt;
uint32_t generate_plu_tt(uint32_t (* pnt_tt_function)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t), uint32_t * pnt_tt)
{
uint32_t result;
uint32_t fin, fin4, fin3, fin2, fin1, fin0;
uint32_t tt_loc;
result = PLU_ROUTINE_FAILED;
tt_loc = 0;
for (fin = 0; fin != 32; fin++)
{
fin0 = (fin >> 0) & 1;
fin1 = (fin >> 1) & 1;
fin2 = (fin >> 2) & 1;
fin3 = (fin >> 3) & 1;
fin4 = (fin >> 4) & 1;
tt_loc |= (*pnt_tt_function)(fin0, fin1, fin2, fin3, fin4)<<fin;
}
*pnt_tt = tt_loc;
result = PLU_OK;
return result;
}

View File

@@ -0,0 +1,165 @@
/*
* spi.c
*
* Created on: Apr 5, 2016
*
*/
#include "LPC8xx.h"
//#include "utilities.h"
#include "spi.h"
uint32_t SPI_RXCount, SPI_TXCount;
void SPI0_IRQHandler(void)
{
uint32_t active = LPC_SPI0->STAT & LPC_SPI0->INTENSET;
if(active & SPI_STAT_RXRDY) {
SPI_RXCount++;
LPC_SPI0->INTENCLR = SPI_STAT_RXRDY;
}
if(active & SPI_STAT_TXRDY) {
SPI_TXCount++;
LPC_SPI0->INTENCLR = SPI_STAT_TXRDY;
}
return;
}
/*****************************************************************************
** Function name: SPImasterWriteOnly
**
** Description: Write a block of data to the SPI slave using polling.
** In this example, data width is limited to 8 bits only.
**
** parameters: pointer to the write buffer.
** Length of the write data block
** Returned value: None
**
*****************************************************************************/
void SPImasterWriteOnly( uint8_t *WrBuf, uint32_t WrLen )
{
uint32_t i = 0;
volatile uint32_t temp;
LPC_SPI0->TXCTL &= ~(SPI_CTL_EOT); // Start a new transfer, clear the EOT bit
SPI_FLASH_CS0(); /* Drive SPI CS low. */
if ( WrLen == 1 ) {
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_CTL_EOT | *WrBuf;
}
else {
while ( i < WrLen ) {
/* Move only if TXRDY is ready */
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
if ( i == 0 ) {
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_TXDATCTL_RX_IGNORE | *WrBuf++;
}
else if ( i == WrLen-1 ) {
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_CTL_EOT | *WrBuf++;
}
else {
LPC_SPI0->TXDAT = *WrBuf++;
}
i++;
}
}
while ( (LPC_SPI0->STAT & SPI_STAT_RXRDY) == 0 ); /* For last frame to be sent, wait until RX on MISO arrives before raising CS. */
temp = LPC_SPI0->RXDAT;
SPI_FLASH_CS1(); /* Drive SPI CS high */
return;
}
/*****************************************************************************
** Function name: SPImasterWriteRead
**
** Description: Write data on the SPI MOSI line while reading data from MISO.
** In this example, data width is limited to 8 bits only.
**
** parameters: pointer to the write buffer
pointer to the read buffer
length of the write/read data buffer
** Returned value: None
**
*****************************************************************************/
void SPImasterWriteRead( uint8_t *WrBuf, uint8_t *RdBuf, uint32_t WrLen )
{
uint32_t i = 0;
LPC_SPI0->TXCTL &= ~(SPI_CTL_EOT); // Start a new transfer, clear the EOT bit
SPI_FLASH_CS0(); /* Drive SPI CS low. */
if ( WrLen == 1 ) {
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_CTL_EOT | *WrBuf;
while ( (LPC_SPI0->STAT & SPI_STAT_RXRDY) == 0 );
*RdBuf = LPC_SPI0->RXDAT;
}
else {
while ( i < WrLen ) {
/* Move only if TXRDY is ready */
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
if ( i == 0 ) {
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | *WrBuf++;
}
else if ( i == WrLen-1 ) {
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_CTL_EOT | *WrBuf++;
}
else {
LPC_SPI0->TXDAT = *WrBuf++;
}
while ( (LPC_SPI0->STAT & SPI_STAT_RXRDY) == 0 );
*RdBuf++ = LPC_SPI0->RXDAT;
i++;
}
}
SPI_FLASH_CS1(); /* Drive SPI CS high */
return;
}
/*****************************************************************************
** Function name: SPImasterReadOnly
**
** Description: Read a block of data to the SPI slave using polling. It's almost
** the same as SPImasterWriteRead() except that SPI master writes
** dummy data the MOSI.
** In this example, data width is limited to 8 bits only.
**
** parameters: pointer to the read buffer.
** Length of the write data block
** Returned value: None
**
*****************************************************************************/
void SPImasterReadOnly( uint8_t *RdBuf, uint32_t RdLen )
{
uint32_t i = 0;
LPC_SPI0->TXCTL &= ~(SPI_CTL_EOT); // Start a new transfer, clear the EOT bit
SPI_FLASH_CS0(); /* Drive SPI CS low. */
if ( RdLen == 1 ) {
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_CTL_EOT | DUMMY_BYTE;
while ( (LPC_SPI0->STAT & SPI_STAT_RXRDY) == 0 );
*RdBuf = LPC_SPI0->RXDAT;
}
else {
while ( i < RdLen ) {
/* Move only if TXRDY is ready */
while ( (LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0 );
if ( i == 0 ) {
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | DUMMY_BYTE;
}
else if ( i == RdLen-1 ) {
LPC_SPI0->TXDATCTL = SPI_CTL_LEN(DATA_WIDTH) | SPI_CTL_EOT | DUMMY_BYTE;
}
else {
LPC_SPI0->TXDAT = DUMMY_BYTE;
}
while ( (LPC_SPI0->STAT & SPI_STAT_RXRDY) == 0 );
*RdBuf++ = LPC_SPI0->RXDAT;
i++;
}
}
SPI_FLASH_CS1(); /* Drive SPI CS high */
return;
}

View File

@@ -0,0 +1,68 @@
#include "swm.h"
#include "LPC8xx.h"
/*****************************************************************************
** Function name: ConfigSWM
** Description: Attaches a pin (designated by its GPIO port and bit numbers)
** to a function.
** parameters: func: Any function name that is movable.
** port_pin: Any pin which has a GPIO port number and bit number.
** Returned value: None
*****************************************************************************/
void ConfigSWM(uint32_t func, uint32_t port_pin) {
uint32_t temp, i;
uint32_t pinassign = 0;
uint32_t shifter = 0;
for (i=0; i<num_funcs; i++) {
if (func != i)
continue;
else {
pinassign = i/4;
shifter = (i%4)*8;
break;
}
}
temp = LPC_SWM->PINASSIGN[pinassign];
temp &= ~(0xFF<<(shifter));
temp |= (port_pin << shifter);
LPC_SWM->PINASSIGN[pinassign] = temp;
return;
}
/*****************************************************************************
** Function name: EnableFixedPinFunc
** Description: Enables a fixed-pin function in PINENABLE0 or PINENABLE1.
** parameters: func: Any function name that is a fixed-pin function.
** Returned value: None
*****************************************************************************/
void EnableFixedPinFunc(uint32_t func) {
if (func <= 0x80000000) {
LPC_SWM->PINENABLE0 &= ~(func);
}
else {
LPC_SWM->PINENABLE1 &= ~(func);
}
}
/*****************************************************************************
** Function name: DisableFixedPinFunc
** Description: Disables a fixed-pin function in PINENABLE0 or PINENABLE1.
** parameters: func: Any function name that is a fixed-pin function.
** Returned value: None
*****************************************************************************/
void DisableFixedPinFunc(uint32_t func) {
if (func <= 0x80000000) {
LPC_SWM->PINENABLE0 |= (func);
}
else {
LPC_SWM->PINENABLE1 |= (func);
}
}

View File

@@ -0,0 +1,79 @@
//
// syscon.c
//
#include "syscon.h"
#include "LPC8xx.h"
// Function: Enable_Periph_Clock
// Use like this: Enable_Periph_Clock(CLK_SPI0);
//
void Enable_Periph_Clock(uint32_t slot) {
if (slot < 32) {
LPC_SYSCON->SYSAHBCLKCTRL[0] |= 1<<slot;
}
else if (slot < 64) {
LPC_SYSCON->SYSAHBCLKCTRL[1] |= 1<<(slot-32);
}
}
// Function: Disable_Periph_Clock
// Use like this: Disable_Periph_Clock(CLK_SPI0);
//
void Disable_Periph_Clock(uint32_t slot) {
if (slot < 32) {
LPC_SYSCON->SYSAHBCLKCTRL[0] &= ~(1<<slot);
}
else if (slot < 64) {
LPC_SYSCON->SYSAHBCLKCTRL[1] &= ~(1<<(slot-32));
}
}
// Function: Do_Periph_Reset
// Use like this: Do_Periph_Reset(RESET_SPI0);
//
void Do_Periph_Reset(uint32_t slot) {
if (slot < 32) {
LPC_SYSCON->PRESETCTRL[0] &= ~(1<<slot);
LPC_SYSCON->PRESETCTRL[0] |= (1<<slot);
}
else if (slot < 64) {
LPC_SYSCON->PRESETCTRL[1] &= ~(1<<(slot-32));
LPC_SYSCON->PRESETCTRL[1] |= (1<<(slot-32));
}
}
// Function: Config_Syspll
// Use like this: Config_Syspll(SYSPLL_CLKSEL_EXTERNAL_CLK, 0x42);
//
//void Config_Syspll(unsigned int which_clock, unsigned int pll_ctrl_value) {
// LPC_SYSCON->SYSPLLCLKSEL = which_clock; // Select the input to the system PLL (sys_pll0_clk_src_i)
// LPC_SYSCON->SYSPLLCLKUEN = 0; // Toggle update register
// LPC_SYSCON->SYSPLLCLKUEN = 1;
// while (!(LPC_SYSCON->SYSPLLCLKUEN & 1)) __NOP(); // Wait until updated
// LPC_SYSCON->SYSPLLCTRL = pll_ctrl_value; // Update the SYSPLLCTRL register
// LPC_SYSCON->PDRUNCFG &= ~(SYSPLL_PD); // Power up system PLL
// while (!(LPC_SYSCON->SYSPLLSTAT & 1)) __NOP(); // Wait until PLL locked
//}
// Function: Config_Fclksel_Mux
// Use like this: Config_Fclksel_Mux(FCLK_TO_UART0, FCLKSEL_MAIN_CLK);
//
void Config_Fclksel_Mux(uint32_t to_which_periph, uint32_t which_clock) {
LPC_SYSCON->FCLKSEL[to_which_periph] = which_clock;
}

View File

@@ -0,0 +1,212 @@
/**************************************************************************//**
* @file system.c
* @brief CMSIS Device System Source File for
* NXP LPC80xm Device Series
* @version V1.0
* @date 01. April 2017
*
******************************************************************************/
//----------------------------------------------------------------------------
// Important!
// Please configure the desired initial clock setup for your project in:
// $proj_name/inc/chip_setup.h
//----------------------------------------------------------------------------
#include <stdint.h>
#include "LPC8xx.h"
#include "swm.h"
#include "syscon.h"
#include "iocon.h"
#include "fro.h"
#include "rom_api.h"
#include "chip_setup.h"
//----------------------------------------------------------------------------
// Validate the the user's selctions
//----------------------------------------------------------------------------
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
#if (CHECK_RANGE((FRO_FREQ_VAL), 0, 2))
#error "FRO_FREQ_VAL: Value out of range."
#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
#if (CHECK_RANGE(CLKIN_CLK_VAL, 1000000, 25000000))
#error "CLKIN frequency is out of bounds"
#endif
//----------------------------------------------------------------------------
// Calculate internal clock node frequency initial values
//----------------------------------------------------------------------------
#define __LPOSC_CLK (1000000)
// determine output of the FRO_CLKDIV subsystem
#if FRO_FREQ_VAL == 0
#define __FRO_OSCOUT (18000000)
#elif FRO_FREQ_VAL == 2
#define __FRO_OSCOUT (30000000)
#else
#define __FRO_OSCOUT (24000000)
#endif
#define __FRO_DIVIDERS_OUT (__FRO_OSCOUT / 2)
#define __FRO_CLK __FRO_DIVIDERS_OUT
#define __FRO_DIV_CLK (__FRO_CLK / 2)
// determine external_clk
#define __SYS_OSC_CLK (0)
#define __CLKIN_CLK (CLKIN_CLK_VAL)
#define __EXTERNAL_CLK __CLKIN_CLK
// determine main_clk
#if MAINCLKSEL_VAL == 0
#define __MAIN_CLK __FRO_CLK
#elif MAINCLKSEL_VAL == 1
#define __MAIN_CLK __EXTERNAL_CLK
#elif MAINCLKSEL_VAL == 2
#define __MAIN_CLK __LPOSC_CLK
#else
#define __MAIN_CLK __FRO_DIV_CLK
#endif
// determine system_ahb_clk
#define __SYSTEM_AHB_CLK (__MAIN_CLK / SYSAHBCLKDIV_VAL)
//----------------------------------------------------------------------------
// Function name: SystemInit
// Sets up the initial chip clocking based on MACROs defined in chip_setup.h.
//----------------------------------------------------------------------------
void SystemInit (void) {
uint32_t i;
for (i = 1; i < 1; i++) __NOP(); // To avoid a warning if variable i is unused
// Enable clocks to IOCON and SWM upon entry, disable them upon exit
LPC_SYSCON->SYSAHBCLKCTRL[0] |= (SWM | IOCON);
// Step 0. Configure the FRO subsystem (choose the source for clocks fro and fro_div)
#if (FRO_FREQ_VAL == 0)
//temp |= (FRO_18MHZ << FRO_FREQ_SEL);
LPC_PWRD_API->set_fro_frequency(18000);
#elif (FRO_FREQ_VAL == 2)
//temp |= (FRO_30MHZ << FRO_FREQ_SEL);
LPC_PWRD_API->set_fro_frequency(30000);
#else
//temp |= (FRO_24MHZ << FRO_FREQ_SEL);
LPC_PWRD_API->set_fro_frequency(24000);
#endif
//temp = LPC_SYSCON->FROOSCCTRL; // Get the current register contents
//temp &= ~(FRO_FREQSEL_MASK); // Preserve all but the bits of interest [1:0]
///PC_SYSCON->FROOSCCTRL = temp; // Update the actual register
//LPC_SYSCON->FRODIRECTCLKUEN = 0; // Toggle the update register for the output mux
//LPC_SYSCON->FRODIRECTCLKUEN = 1;
//while (!(LPC_SYSCON->FRODIRECTCLKUEN & 1)) __NOP(); // Wait for update to take effect
// Configure clk_in, if needed for main_clk or other (e.g. clock out, ADC clk.)
#if ((MAINCLKSEL_VAL == 1) || (EXT_CLOCK_FORCE_ENABLE == 1))
LPC_IOCON->PIO0_1 &= (IOCON_MODE_MASK | MODE_INACTIVE); // Disable pull-up and pull-down
LPC_SWM->PINENABLE0 &= ~(CLKIN); // Enable CLKIN func.
#endif
// Step 2. Power up the LP OSC if it's needed for main_clk
#if (MAINCLKSEL_VAL == 2)
LPC_SYSCON->PDRUNCFG &= ~(LPOSC_PD); // Power up the LP OSC
for (i = 0; i < 200; i++) __NOP(); // Wait for osc to stabilize
#endif
// Step 4. Choose source for main_clk
LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_VAL; // Update the actual register
LPC_SYSCON->MAINCLKUEN = 0; // Toggle update register
LPC_SYSCON->MAINCLKUEN = 1;
while (!(LPC_SYSCON->MAINCLKUEN & 1)) __NOP(); // Wait until updated
// Step 6. Configure the main_clock divider
LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_VAL; // Update the actual register
LPC_SYSCON->SYSAHBCLKCTRL[0] &= ~(SWM | IOCON); // Turn off peripheral clocks before leaving
} // end of SystemInit
//----------------------------------------------------------------------------
// Global clock variable declarations and initial value assignments
//----------------------------------------------------------------------------
uint32_t main_clk = __MAIN_CLK;
uint32_t lposc_clk = __LPOSC_CLK;
uint32_t fro_clk = __FRO_CLK;
uint32_t fro_div_clk = __FRO_DIV_CLK;
uint32_t system_ahb_clk = __SYSTEM_AHB_CLK;
//----------------------------------------------------------------------------
// Function name: SystemCoreClockUpdate
// Determines the actual system_ahb_clk (core clock), main_clock,
// fro_clk, and fro_div_clk frequencies
// based on the current state of the device, and updates the associated
// global clock variables.
//----------------------------------------------------------------------------
void SystemCoreClockUpdate (void)
{
uint32_t external_clk;
uint32_t fro_oscout, fro_clock;
uint32_t temp;
// Set the fro_clk and fro_div_clk variables according to current register settings
temp = LPC_SYSCON->FROOSCCTRL;
switch (temp & FRO_FREQSEL_MASK) {
case 0: fro_oscout = 18000000; break;
case 1: fro_oscout = 24000000; break;
default:fro_oscout = 30000000; break;
}
fro_clock = 0;
if ((LPC_SYSCON->PDRUNCFG & (FROOUT_PD | FRO_PD)) == 0x0) {
fro_clock = fro_oscout;
}
fro_clk = fro_clock / 2;
fro_div_clk = fro_clk / 2;
// Set the external_clk variable according to current register values
//if (LPC_SYSCON->EXTCLKSEL == 0)
// external_clk = __SYS_OSC_CLK;
//else
external_clk = __CLKIN_CLK;
// Set the lposc_clk variable
if (!(LPC_SYSCON->PDRUNCFG & LPOSC_PD)) {
lposc_clk = __LPOSC_CLK;
}
else {
lposc_clk = 0;
}
// Set the main_clk variable according to current register values
switch (LPC_SYSCON->MAINCLKSEL & 0x3) {
case 0: main_clk = fro_clk; break;
case 1: main_clk = external_clk; break;
case 2: main_clk = lposc_clk; break;
case 3: main_clk = fro_div_clk; break;
}
// Set the system_ahb_clk (a.k.a SystemCoreClock) variable according to current register values
system_ahb_clk = main_clk / LPC_SYSCON->SYSAHBCLKDIV;
} // end of SystemCoreClockUpdate

View File

@@ -0,0 +1,148 @@
#
# Generic and Simple GNU ARM Makefile
#
# Desinged for the gnu-arm-none-eabi tool chain
#
# Features
# - create hex file
# - create assembler listing (.dis)
#
# Limitations
# - only C-files supported
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
#
# Targets:
# make
# create hex file, no upload
# make upload
# create and upload hex file
# make clean
# delete all generated files
#
# Note:
# Display list make database: make -p -f/dev/null | less
#
#================================================
# External tools
# The base directory of gcc-arm-none-eabi
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
# If set, GCCBINPATH must contain a "/" at the end.
GCCBINPATH:=/usr/bin/
#================================================
# Project Information
# The name for the project
TARGETNAME:=plu
# The source files of the project
SRC:=$(wildcard *.c)
# The CPU architecture (will be used for -mcpu)
# for the LPC804, can we use "cortex-m0plus" instead of "cortex-m0"?
MCPU:=cortex-m0plus
# Include directory for the system include files
SYSINC:=../lpc_chip_804/inc
SYSSRC:=$(wildcard ../lpc_chip_804/src/*.c)
# Include directory for the u8g2 include files
#U8G2INC:=../../../../csrc/
#U8G2SRC:=$(wildcard ../../../../csrc/*.c)
# directory for FatFS
#FFINC:=../fatfs
#FFSRC:=$(wildcard ../fatfs/*.c)
# Directory for the linker script
LDSCRIPTDIR:=.
# Name of the linker script (must be the "keep" script, because the other script is not always working)
LDSCRIPT:=lpc804.ld
#================================================
# Main part of the Makefile starts here. Usually no changes are needed.
# Internal Variable Names
LIBNAME:=$(TARGETNAME).a
ELFNAME:=$(TARGETNAME).elf
HEXNAME:=$(TARGETNAME).hex
DISNAME:=$(TARGETNAME).dis
MAPNAME:=$(TARGETNAME).map
OBJ:=$(SRC:.c=.o) $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o) $(FFSRC:.c=.o)
# Replace standard build tools by arm tools
CC:=$(GCCBINPATH)arm-none-eabi-gcc
AR:=$(GCCBINPATH)arm-none-eabi-ar
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
SIZE:=$(GCCBINPATH)arm-none-eabi-size
# Common flags
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
# define stack size (defaults to 0x0100)
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
# COMMON_FLAGS += -Os -flto
COMMON_FLAGS += -Os
# COMMON_FLAGS += -fstack-protector
# COMMON_FLAGS += -finstrument-functions
# Do not use stand libs startup code. Uncomment this for gcclib procedures
# memcpy still works, but might be required for __aeabi_uidiv
# COMMON_FLAGS += -nostdlib
# remove unused data and function
COMMON_FLAGS += -ffunction-sections -fdata-sections
# COMMON_FLAGS += -ffunction-sections -fdata-sections -fshort-wchar
# C flags
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
# LD flags
# remove unreferenced procedures and variables, but keep "arm_stack_area" and __isr_vector
GC:=-Wl,--gc-sections -Wl,--undefined=arm_stack_area -Wl,--undefined=__isr_vector
MAP:=-Wl,-Map=$(MAPNAME)
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
#LDLIBS:=--specs=nano.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
LDLIBS:=--specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
# Additional Suffixes
.SUFFIXES: .elf .hex .bin .dis
# Targets
.PHONY: all
all: plu.c $(DISNAME) $(HEXNAME)
$(SIZE) $(ELFNAME)
.PHONY: upload
upload: $(DISNAME) $(HEXNAME) $(ELFNAME)
$(SIZE) $(ELFNAME)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) libssp.a libssp_nonshared.a plu.c
# implicit rules
.elf.hex:
$(OBJCOPY) -O ihex $< $@
# explicit rules
plu.c: Makefile plu.bex plu.bms
./pluc plu.bex plu.bms -oc plu.c
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a plu.c
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
$(DISNAME): $(ELFNAME)
$(OBJDUMP) -D -S $< > $@
# create empty ssp libs for -fstack-protector-all -fstack-protector
libssp.a:
$(AR) rcs $@
libssp_nonshared.a:
$(AR) rcs $@

View File

@@ -0,0 +1,129 @@
/*
delay.c
The delay function delay_micro_seconds() will use the global variable
SystemCoreClock. A call to SystemCoreClockUpdate() is required before
using delay_micro_seconds().
LPC804 Project
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <LPC8xx.h>
/* Generic ARM delay procedure, based on the system timer (SysTick) */
/*
Delay by the provided number of system ticks.
The delay must be smaller than the RELOAD value.
This delay has an imprecision of about +/- 20 system ticks.
*/
static void _delay_system_ticks_sub(uint32_t sys_ticks)
{
uint32_t start_val, end_val, curr_val;
uint32_t load;
start_val = SysTick->VAL;
start_val &= 0x0ffffffUL;
end_val = start_val;
if ( end_val < sys_ticks )
{
/* check, if the operation after this if clause would lead to a negative result */
/* if this would be the case, then add the reload value first */
load = SysTick->LOAD;
load &= 0x0ffffffUL;
end_val += load;
}
/* counter goes towards zero, so end_val is below start value */
end_val -= sys_ticks;
/* wait until interval is left */
if ( start_val >= end_val )
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val )
break;
if ( curr_val > start_val )
break;
}
}
else
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val && curr_val > start_val )
break;
}
}
}
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks)
{
uint32_t load4;
load4 = SysTick->LOAD;
load4 &= 0x0ffffffUL;
load4 >>= 2;
while ( sys_ticks > load4 )
{
sys_ticks -= load4;
_delay_system_ticks_sub(load4);
}
_delay_system_ticks_sub(sys_ticks);
}
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us)
{
uint32_t sys_ticks;
sys_ticks = main_clk;
sys_ticks /=1000000UL;
sys_ticks *= us;
delay_system_ticks(sys_ticks);
}

View File

@@ -0,0 +1,55 @@
/*
delay.h
LPC11U3x GPS Logger (https://github.com/olikraus/lpc11u3x-gps-logger)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#ifndef _DELAY_H
#define _DELAY_H
#include <stdint.h>
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks);
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us);
#endif /* _DELAY_H */

View File

@@ -0,0 +1,177 @@
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld */
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
/* LPC804 */
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x8000 /* 32K for LPC804 */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x1000 /* 4K for LPC804 */
}
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/sections.ld */
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
/* entry point */
ENTRY(Reset_Handler)
/* extern declaration so that the value appears correctly for the LPC checksum calculation */
EXTERN(NMI_Handler)
EXTERN(HardFault_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/*
http://www.lpcware.com/content/forum/lpc1788-flash-signature-generation
Section 3.5.2/page 12 of the LPC82x User Manual
Linker works with even addresses, however to indicate thumb address mode,
the lowest bit of the address is set to one. For the checksum calculation we
only have the even addresses, however later in the isr table the compiler will
store the odd addresses for the three handler subprocedures if compiled in
thumb mode. Because of this, 3 is added to consider the three odd handler calls.
*/
LPC_checksum = 0- (__StackTop + Reset_Handler + NMI_Handler + HardFault_Handler + 3 /* three entries */);
}

View File

@@ -0,0 +1,112 @@
/*
main.c
PLU example
switch at PIO0_02 and PIO0_10
LED at PIO0_09 and PIO0_15
*/
#include <LPC8xx.h>
#include <syscon.h>
#include <gpio.h>
#include <delay.h>
void plu(void);
/*=======================================================================*/
/* Configuration */
#define SYS_TICK_PERIOD_IN_MS 100
/*=======================================================================*/
/* system procedures and sys tick master task */
volatile uint32_t sys_tick_irq_cnt=0;
void __attribute__ ((interrupt)) SysTick_Handler(void)
{
sys_tick_irq_cnt++;
}
/*=======================================================================*/
/*
config: 0
PIO0_2 --> PLUINPUT2 --> LUT4_INP0
PIO0_10 --> IN0 --> OUT0 --> PIN0_22 --> PLUINPUT5 --> LUT4_INP1
Cfg | PIO10 PIO2 | result
1 | 0 0 | 1
Cfg | PIO10 PIO2 | result
2 | 0 1 | 1 falsch, sieht nach 2 | 1 0 | 1 aus (reihenfolge falsch???)
Cfg | PIO10 PIO2 | result
3 | 0 1 | 1
3 | 1 1 | 1
Config=1
PIO10 PIO2 | result
0 0 | 1 --> ok
0 1 | 0
1 0 | 0
1 1 | 0
Config=1
PIO10 PIO2 | result
0 0 | 0 --> ok
0 1 | 1
1 0 | 0
1 1 | 0
*/
/*=======================================================================*/
/*
setup the hardware and start interrupts.
called by "Reset_Handler"
*/
int __attribute__ ((noinline)) main(void)
{
/* call to the lpc lib setup procedure. This will set the IRC as clk src and main clk to 24 MHz */
SystemInit();
/* if the clock or PLL has been changed, also update the global variable SystemCoreClock */
SystemCoreClockUpdate();
/* set systick and start systick interrupt */
SysTick_Config(main_clk/1000UL*(unsigned long)SYS_TICK_PERIOD_IN_MS);
/* */
GPIOInit();
/* enable clock for several subsystems */
Enable_Periph_Clock(CLK_IOCON);
Enable_Periph_Clock(CLK_SWM);
GPIOSetDir( PORT0, 15, OUTPUT);
GPIOSetDir( PORT0, 9, OUTPUT);
GPIOSetDir( PORT0, 2, INPUT);
plu();
for(;;)
{
GPIOSetBitValue(PORT0, 15, 1);
delay_micro_seconds(100000);
GPIOSetBitValue(PORT0, 15, 0);
delay_micro_seconds(1000000);
}
}

View File

@@ -0,0 +1,13 @@
# plu.bex
#
# switches are at PIO0_10 and PIO0_2
# Because only PIO0_10 or PIO0_2 can be used as input for PLU,
# PIO0_10 is routed via LVLSHFT0 path to PIO0_22
PIO0_22 <= LVLSHFT_OUT0;
LVLSHFT_IN0 <= PIO0_10;
#PIO0_9 <= !PIO0_2 & !PIO0_22;
PLU_CLKIN <= CLKOUT;

View File

@@ -0,0 +1,12 @@
#
#
name muller_c
input PIO0_2 0
input PIO0_22 0
output PIO0_9 0
0 1 PIO0_2+ PIO0_22+ | PIO0_9+
1 0 PIO0_2- PIO0_22- | PIO0_9-

View File

@@ -0,0 +1,201 @@
/*
startup.c
LPC804
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
Requires code from the LPC804 example zip files
*/
#include <LPC8xx.h>
/*=======================================================================*/
/* external functions */
void __attribute__ ((interrupt)) SysTick_Handler(void);
//void __attribute__ ((interrupt, used)) UART_IRQ(void);
int __attribute__ ((noinline)) main(void);
/*=======================================================================*/
/*
Reserve some space for the stack. This is used to check if global variables + stack exceed RAM size.
If -Wl,--gc-sections is used, then also define -Wl,--undefined=arm_stack_area to keep the variable in RAM.
The name of the variable (here: arm_stack_area) does not matter.
Heap (=dynamic memory allocation) is not supported
*/
#ifndef __STACK_SIZE
#define __STACK_SIZE 0x100
#endif
unsigned char arm_stack_area[__STACK_SIZE] __attribute__ ((section(".stack"))) __attribute__ ((aligned(8)));
/*=======================================================================*/
/* isr system procedures */
/* make the top of the stack known to the c compiler, value will be calculated by the linker script */
void __StackTop(void);
void __attribute__ ((interrupt)) __attribute__ ((noreturn)) Reset_Handler(void)
{
register unsigned long *ptr;
register unsigned long *start;
register unsigned long *end;
/*
The following two operations are not required in normal mode reset mode,
however it is usefull if the reset handler is started via ISP "Go" command
*/
__set_MSP((uint32_t)__StackTop);
//Chip_SYSCTL_Map(2);
LPC_SYSCON->SYSMEMREMAP = (uint32_t) 2; // user flash mode: use user isr vector table
/*
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.
*/
extern unsigned long __data_start__[];
extern unsigned long __data_end__[];
extern unsigned long __etext[];
ptr = __etext;
start = __data_start__;
end = __data_end__;
while( start < end )
{
*start = *ptr;
start++;
ptr++;
}
/*
Loop to zero out BSS section, which uses following symbols
in linker script:
__bss_start__: start of BSS section. Must align to 4
__bss_end__: end of BSS section. Must align to 4
*/
extern unsigned long __bss_start__[];
extern unsigned long __bss_end__[];
ptr = __bss_start__;
end = __bss_end__;
while( ptr < end )
{
*ptr = 0;
ptr++;
}
/* Call main procedure */
main();
/* finished, do nothing. */
for(;;)
;
}
/* "NMI_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) NMI_Handler(void)
{
}
/* "HardFault_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) HardFault_Handler(void)
{
}
/* make the checksum known to the c compiler, value will be calculated by the linker script */
void LPC_checksum(void);
/*=======================================================================*/
/* isr vector */
/* based on LPC8xx.h */
/* see table 38 of the LPC804 user manual (page 39) */
typedef void (*isr_handler_t)(void);
isr_handler_t __isr_vector[48] __attribute__ ((section(".isr_vector"))) __attribute__ ((aligned(4)))=
{
__StackTop, /* 0x00: Top of Stack, calculated by the linker script */
Reset_Handler, /* -15, 0x04: Reset Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
NMI_Handler, /* .14, 0x08: NMI Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
HardFault_Handler, /* -13, 0x0c: Hard Fault Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
0, /* 0x10: Reserved, must be 0 */
0, /* 0x14: Reserved, must be 0 */
0, /* 0x18: Reserved, must be 0 */
LPC_checksum, /* 0x1c: Checksum, calculated by the linker script or the flash utility */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* -5, SVCall Handler */
0, /* -4, Reserved */
0, /* -3, Reserved */
0, /* -2, PendSV Handler */
SysTick_Handler, /* -1, SysTick Handler */
0, /* 0 SPI0_IRQn, SPI0 controller */
0, /* 1 Not used/Reserved */
0, /* 2 DAC0_IRQn, DAC0 Interrupt */
0, /* 3 UART0_IRQn, USART0 */
0, /* 4 UART1_IRQn, USART1 */
0, /* 5 Not used */
0, /* 6 Not used */
0, /* 7 I2C1 controller */
0, /* 8 I2C0 controller */
0, /* 9 Not used/Reserved */
0, /* 10 MRT_IRQnMulti-Rate Timer */
0, /* 11 CMP_IRQn, Analog Comparator /CapTouch*/
0, /* 12 WDT_IRQn WDT */
0, /* 13 BOD_IRQn BOD Brown Out Detect */
0, /* 14 FLASH_IRQn (/Reserved according to the user manual) */
0, /* 15 WKT_IRQn Self wake-up timer */
0, /* 16 ADC_SEQA_IRQn */
0, /* 17 ADC_SEQB_IRQn */
0, /* 18 ADC_THCMP_IRQn ADC threshold compare */
0, /* 19 ADC_OVR_IRQn ADC overrun */
0, /* 20 Not used/Reserved */
0, /* 21 Not used/Reserved */
0, /* 22 Not used/Reserved */
0, /* 23 CTIMER0_IRQn, CT32B0_IRQ */
0, /* 24 PIO INT0 */
0, /* 25 PIO INT1 */
0, /* 26 PIO INT2 */
0, /* 27 PIO INT3 */
0, /* 28 PIO INT4 */
0, /* 29 PIO INT5 */
0, /* 30 PIO INT6 */
0 /* 31 PIO INT7 */
};

View File

@@ -0,0 +1,154 @@
#
# Generic and Simple GNU ARM Makefile
#
# Desinged for the gnu-arm-none-eabi tool chain
#
# Features
# - create hex file
# - create assembler listing (.dis)
#
# Limitations
# - only C-files supported
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
#
# Targets:
# make
# create hex file, no upload
# make upload
# create and upload hex file
# make clean
# delete all generated files
#
# Note:
# Display list make database: make -p -f/dev/null | less
#
#================================================
# External tools
# The base directory of gcc-arm-none-eabi
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
# If set, GCCBINPATH must contain a "/" at the end.
GCCBINPATH:=/usr/bin/
#================================================
# Project Information
# The name for the project
TARGETNAME:=blink
# The source files of the project
SRC:=$(wildcard *.c)
# The CPU architecture (will be used for -mcpu)
# for the LPC824, can we use "cortex-m0plus"?
MCPU:=cortex-m0
# Include directory for the system include files
SYSINC:=../lpc_chip_82x/inc
SYSSRC:=$(wildcard ../lpc_chip_82x/src/*.c)
# Include directory for the u8g2 include files
U8G2INC:=../../../../csrc/
U8G2SRC:=$(wildcard ../../../../csrc/*.c)
# directory for FatFS
#FFINC:=../fatfs
#FFSRC:=$(wildcard ../fatfs/*.c)
# Directory for the linker script
LDSCRIPTDIR:=.
# Name of the linker script (must be the "keep" script, because the other script is not always working)
LDSCRIPT:=lpc824.ld
#================================================
# Main part of the Makefile starts here. Usually no changes are needed.
# Internal Variable Names
LIBNAME:=$(TARGETNAME).a
ELFNAME:=$(TARGETNAME).elf
HEXNAME:=$(TARGETNAME).hex
BINNAME:=firmware.bin
DISNAME:=$(TARGETNAME).dis
MAPNAME:=$(TARGETNAME).map
OBJ:=$(SRC:.c=.o) $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o) $(FFSRC:.c=.o)
# Replace standard build tools by avr tools
CC:=$(GCCBINPATH)arm-none-eabi-gcc
AR:=$(GCCBINPATH)arm-none-eabi-ar
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
SIZE:=$(GCCBINPATH)arm-none-eabi-size
# Common flags
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
# define stack size (defaults to 0x0100)
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
# define constant for lpcopen library
COMMON_FLAGS += -DCORE_M0PLUS
# instruct LPC8xx lib procedures to use the ROM API
COMMON_FLAGS += -DUSE_ROM_API
# do not make a call to SystemInit()
# COMMON_FLAGS += -Os -flto
COMMON_FLAGS += -Os
# COMMON_FLAGS += -fstack-protector
# COMMON_FLAGS += -finstrument-functions
# Do not use stand libs startup code. Uncomment this for gcclib procedures
# memcpy still works, but might be required for __aeabi_uidiv
# COMMON_FLAGS += -nostdlib
# remove unused data and function
COMMON_FLAGS += -ffunction-sections -fdata-sections
# COMMON_FLAGS += -ffunction-sections -fdata-sections -fshort-wchar
# C flags
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
# LD flags
# remove unreferenced procedures and variables, but keep "arm_stack_area" and __isr_vector
GC:=-Wl,--gc-sections -Wl,--undefined=arm_stack_area -Wl,--undefined=__isr_vector
MAP:=-Wl,-Map=$(MAPNAME)
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
#LDLIBS:=--specs=nano.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
LDLIBS:=--specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
# Additional Suffixes
.SUFFIXES: .elf .hex .bin .dis
# Targets
.PHONY: all
all: $(DISNAME) $(HEXNAME) $(BINNAME)
$(SIZE) $(ELFNAME)
.PHONY: upload
upload: $(DISNAME) $(HEXNAME) $(ELFNAME) $(BINNAME)
#dd bs=1024 conv=nocreat,notrunc if=$(BINNAME) of="/media/$(shell echo $$USER)/CRP DISABLD/firmware.bin"
$(SIZE) $(ELFNAME)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) $(BINNAME) libssp.a libssp_nonshared.a
# implicit rules
.elf.hex:
$(OBJCOPY) -O ihex $< $@
# explicit rules
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
$(DISNAME): $(ELFNAME)
$(OBJDUMP) -D -S $< > $@
# not required for this project
$(BINNAME): $(ELFNAME)
$(OBJCOPY) -O binary --gap-fill 255 --pad-to 32768 $< $@
# create empty ssp libs for -fstack-protector-all -fstack-protector
libssp.a:
$(AR) rcs $@
libssp_nonshared.a:
$(AR) rcs $@

View File

@@ -0,0 +1,129 @@
/*
delay.c
The delay function delay_micro_seconds() will use the global variable
SystemCoreClock. A call to SystemCoreClockUpdate() is required before
using delay_micro_seconds().
LPC824 Project (U8g2 Library)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <chip.h>
/* Generic ARM delay procedure, based on the system timer (SysTick) */
/*
Delay by the provided number of system ticks.
The delay must be smaller than the RELOAD value.
This delay has an imprecision of about +/- 20 system ticks.
*/
static void _delay_system_ticks_sub(uint32_t sys_ticks)
{
uint32_t start_val, end_val, curr_val;
uint32_t load;
start_val = SysTick->VAL;
start_val &= 0x0ffffffUL;
end_val = start_val;
if ( end_val < sys_ticks )
{
/* check, if the operation after this if clause would lead to a negative result */
/* if this would be the case, then add the reload value first */
load = SysTick->LOAD;
load &= 0x0ffffffUL;
end_val += load;
}
/* counter goes towards zero, so end_val is below start value */
end_val -= sys_ticks;
/* wait until interval is left */
if ( start_val >= end_val )
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val )
break;
if ( curr_val > start_val )
break;
}
}
else
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val && curr_val > start_val )
break;
}
}
}
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks)
{
uint32_t load4;
load4 = SysTick->LOAD;
load4 &= 0x0ffffffUL;
load4 >>= 2;
while ( sys_ticks > load4 )
{
sys_ticks -= load4;
_delay_system_ticks_sub(load4);
}
_delay_system_ticks_sub(sys_ticks);
}
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us)
{
uint32_t sys_ticks;
sys_ticks = SystemCoreClock;
sys_ticks /=1000000UL;
sys_ticks *= us;
delay_system_ticks(sys_ticks);
}

View File

@@ -0,0 +1,55 @@
/*
delay.h
LPC11U3x GPS Logger (https://github.com/olikraus/lpc11u3x-gps-logger)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#ifndef _DELAY_H
#define _DELAY_H
#include <stdint.h>
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks);
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us);
#endif /* _DELAY_H */

View File

@@ -0,0 +1,177 @@
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld */
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
/* LPC82x User Manual Page 8 */
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x8000 /* 32K for LPC824 */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x2000 /* 8K for LPC824 */
}
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/sections.ld */
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
/* entry point */
ENTRY(Reset_Handler)
/* extern declaration so that the value appears correctly for the LPC checksum calculation */
EXTERN(NMI_Handler)
EXTERN(HardFault_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/*
http://www.lpcware.com/content/forum/lpc1788-flash-signature-generation
Section 3.5.2/page 12 of the LPC82x User Manual
Linker works with even addresses, however to indicate thumb address mode,
the lowest bit of the address is set to one. For the checksum calculation we
only have the even addresses, however later in the isr table the compiler will
store the odd addresses for the three handler subprocedures if compiled in
thumb mode. Because of this, 3 is added to consider the three odd handler calls.
*/
LPC_checksum = 0- (__StackTop + Reset_Handler + NMI_Handler + HardFault_Handler + 3 /* three entries */);
}

View File

@@ -0,0 +1,58 @@
#include <chip.h>
#include <delay.h>
/*=======================================================================*/
/* Configuration */
#define SYS_TICK_PERIOD_IN_MS 100
/*=======================================================================*/
/* system procedures and sys tick master task */
volatile uint32_t sys_tick_irq_cnt=0;
void __attribute__ ((interrupt)) SysTick_Handler(void)
{
sys_tick_irq_cnt++;
}
/*=======================================================================*/
/*
setup the hardware and start interrupts.
called by "Reset_Handler"
*/
int __attribute__ ((noinline)) main(void)
{
/* call to the lpc lib setup procedure. This will set the IRC as clk src and main clk to 24 MHz */
Chip_SystemInit();
/* if the clock or PLL has been changed, also update the global variable SystemCoreClock */
SystemCoreClockUpdate();
/* set systick and start systick interrupt */
SysTick_Config(SystemCoreClock/1000UL*(unsigned long)SYS_TICK_PERIOD_IN_MS);
/* enable clock for several subsystems */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON | SYSCTL_CLOCK_GPIO | SYSCTL_CLOCK_SWM);
/* turn on GPIO */
Chip_GPIO_Init(LPC_GPIO_PORT); /* Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO); */
//Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 15, IOCON_FUNC1); /* RxD */
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 15);
for(;;)
{
Chip_GPIO_SetPinOutHigh(LPC_GPIO_PORT, 0, 15);
delay_micro_seconds(1000000);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, 0, 15);
delay_micro_seconds(1000000);
}
}

View File

@@ -0,0 +1,203 @@
/*
startup.c
LPC824
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
Requires LPC82x Chip Library
*/
#include <chip.h>
/*=======================================================================*/
/* external functions */
void __attribute__ ((interrupt)) SysTick_Handler(void);
//void __attribute__ ((interrupt, used)) UART_IRQ(void);
int __attribute__ ((noinline)) main(void);
/*=======================================================================*/
/*
Reserve some space for the stack. This is used to check if global variables + stack exceed RAM size.
If -Wl,--gc-sections is used, then also define -Wl,--undefined=arm_stack_area to keep the variable in RAM.
The name of the variable (here: arm_stack_area) does not matter.
Heap (=dynamic memory allocation) is not supported
*/
#ifndef __STACK_SIZE
#define __STACK_SIZE 0x100
#endif
unsigned char arm_stack_area[__STACK_SIZE] __attribute__ ((section(".stack"))) __attribute__ ((aligned(8)));
/*=======================================================================*/
/* isr system procedures */
/* make the top of the stack known to the c compiler, value will be calculated by the linker script */
void __StackTop(void);
void __attribute__ ((interrupt)) __attribute__ ((noreturn)) Reset_Handler(void)
{
register unsigned long *ptr;
register unsigned long *start;
register unsigned long *end;
/*
The following two operations are not required in normal mode reset mode,
however it is usefull if the reset handler is started via ISP "Go" command
*/
__set_MSP((uint32_t)__StackTop);
Chip_SYSCTL_Map(2);
/*
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.
*/
extern unsigned long __data_start__[];
extern unsigned long __data_end__[];
extern unsigned long __etext[];
ptr = __etext;
start = __data_start__;
end = __data_end__;
while( start < end )
{
*start = *ptr;
start++;
ptr++;
}
/*
Loop to zero out BSS section, which uses following symbols
in linker script:
__bss_start__: start of BSS section. Must align to 4
__bss_end__: end of BSS section. Must align to 4
*/
extern unsigned long __bss_start__[];
extern unsigned long __bss_end__[];
ptr = __bss_start__;
end = __bss_end__;
while( ptr < end )
{
*ptr = 0;
ptr++;
}
/* Call main procedure */
main();
/* finished, do nothing. */
for(;;)
;
}
/* "NMI_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) NMI_Handler(void)
{
}
/* "HardFault_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) HardFault_Handler(void)
{
}
/* make the checksum known to the c compiler, value will be calculated by the linker script */
void LPC_checksum(void);
/*=======================================================================*/
/* isr vector */
/* see page 445 of the LPC11U3x user manual */
/* see also enum LPC11UXX_IRQn in isr/cmsis_11uxx.h */
typedef void (*isr_handler_t)(void);
isr_handler_t __isr_vector[48] __attribute__ ((section(".isr_vector"))) __attribute__ ((aligned(4)))=
{
__StackTop, /* 0x00: Top of Stack, calculated by the linker script */
Reset_Handler, /* 0x04: Reset Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
NMI_Handler, /* 0x08: NMI Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
HardFault_Handler, /* 0x0c: Hard Fault Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
0, /* 0x10: Reserved, must be 0 */
0, /* 0x14: Reserved, must be 0 */
0, /* 0x18: Reserved, must be 0 */
LPC_checksum, /* 0x1c: Checksum, calculated by the linker script or the flash utility */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* SVCall Handler */
0, /* Reserved */
0, /* Reserved */
0, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
0, /* 0 SPI0 controller */
0, /* 1 SPI1 controller */
0, /* 2 Reserved */
0, /* 3 UART0 */
0, /* 4 UART1 */
0, /* 5 UART2 */
0, /* 6 Reserved */
0, /* 7 I2C1 controller */
0, /* 8 I2C0 controller */
0, /* 9 SCT */
0, /* 10 Multi-Rate Timer */
0, /* 11 CMP_IRQn Comparator */
0, /* 12 WDT_IRQn WDT */
0, /* 13 BOD_IRQn BOD Brown Out Detect */
0, /* 14 FLASH_IRQn */
0, /* 15 WKT_IRQn Self wake-up timer */
0, /* 16 ADC_SEQA_IRQn */
0, /* 17 ADC_SEQB_IRQn */
0, /* 18 ADC_THCMP_IRQn ADC threshold compare */
0, /* 19 ADC_OVR_IRQn ADC overrun */
0, /* 20 Reserved */
0, /* 21 Reserved */
0, /* 22 Reserved */
0, /* 23 Reserved */
0, /* 24 PIO INT0 */
0, /* 25 PIO INT1 */
0, /* 26 PIO INT2 */
0, /* 27 PIO INT3 */
0, /* 28 PIO INT4 */
0, /* 29 PIO INT5 */
0, /* 30 PIO INT6 */
0 /* 31 PIO INT7 */
};

View File

@@ -0,0 +1,48 @@
/*
sysclk.c
LPC824
Copyright (c) 2017, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <chip.h>
/*
According to chip.h there must be two variables which have to be defined
by a user program: OscRateIn and ExtRateIn
Values can be 0, but if not 0, then these values define the clock speed
Actually there is one more variable (SystemCoreClock) which is
updated by SystemCoreClockUpdate() based on the values given in the
other two values.
*/
const uint32_t OscRateIn = 0; /* freq. of the external crystal osc */
const uint32_t ExtRateIn = 0;

View File

@@ -0,0 +1,156 @@
#
# Generic and Simple GNU ARM Makefile
#
# Desinged for the gnu-arm-none-eabi tool chain
#
# Features
# - create hex file
# - create assembler listing (.dis)
#
# Limitations
# - only C-files supported
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
#
# Targets:
# make
# create hex file, no upload
# make upload
# create and upload hex file
# make clean
# delete all generated files
#
# Note:
# Display list make database: make -p -f/dev/null | less
#
#================================================
# External tools
# The base directory of gcc-arm-none-eabi
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
# If set, GCCBINPATH must contain a "/" at the end.
GCCBINPATH:=/usr/bin/
#================================================
# Project Information
# The name for the project
TARGETNAME:=hello_world
# The source files of the project
SRC:=$(wildcard *.c)
# The CPU architecture (will be used for -mcpu)
# for the LPC824, can we use "cortex-m0plus"?
#MCPU:=cortex-m0
MCPU:=cortex-m0plus
# Include directory for the system include files
SYSINC:=../lpc_chip_82x/inc
SYSSRC:=$(wildcard ../lpc_chip_82x/src/*.c)
# Include directory for the u8g2 include files
U8G2INC:=../../../../csrc/
U8G2SRC:=$(wildcard ../../../../csrc/*.c)
# directory for FatFS
#FFINC:=../fatfs
#FFSRC:=$(wildcard ../fatfs/*.c)
# Directory for the linker script
LDSCRIPTDIR:=.
# Name of the linker script (must be the "keep" script, because the other script is not always working)
LDSCRIPT:=lpc824.ld
#================================================
# Main part of the Makefile starts here. Usually no changes are needed.
# Internal Variable Names
LIBNAME:=$(TARGETNAME).a
ELFNAME:=$(TARGETNAME).elf
HEXNAME:=$(TARGETNAME).hex
BINNAME:=firmware.bin
DISNAME:=$(TARGETNAME).dis
MAPNAME:=$(TARGETNAME).map
OBJ:=$(SRC:.c=.o) $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o) $(FFSRC:.c=.o)
# Replace standard build tools by avr tools
CC:=$(GCCBINPATH)arm-none-eabi-gcc
AR:=$(GCCBINPATH)arm-none-eabi-ar
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
SIZE:=$(GCCBINPATH)arm-none-eabi-size
# Common flags
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
# define stack size (defaults to 0x0100)
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
# define constant for lpcopen library
COMMON_FLAGS += -DCORE_M0PLUS
# instruct LPC8xx lib procedures to use the ROM API
COMMON_FLAGS += -DUSE_ROM_API
# do not make a call to SystemInit()
# COMMON_FLAGS += -Os -flto
COMMON_FLAGS += -Os
# COMMON_FLAGS += -fstack-protector
# COMMON_FLAGS += -finstrument-functions
# Do not use stand libs startup code. Uncomment this for gcclib procedures
# memcpy still works, but might be required for __aeabi_uidiv
# COMMON_FLAGS += -nostdlib
# remove unused data and function
COMMON_FLAGS += -ffunction-sections -fdata-sections
# COMMON_FLAGS += -fshort-wchar
# C flags
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
# LD flags
# remove unreferenced procedures and variables, but keep "arm_stack_area" and __isr_vector
GC:=-Wl,--gc-sections -Wl,--undefined=arm_stack_area -Wl,--undefined=__isr_vector
MAP:=-Wl,-Map=$(MAPNAME)
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
#LDLIBS:=--specs=nano.specs -lc -lc -lnosys -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
LDLIBS:=--specs=nosys.specs -lc -lc -lnosys -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
# Additional Suffixes
.SUFFIXES: .elf .hex .bin .dis
# Targets
.PHONY: all
all: $(DISNAME) $(HEXNAME) $(BINNAME)
$(SIZE) $(ELFNAME)
.PHONY: upload
upload: $(DISNAME) $(HEXNAME) $(ELFNAME) $(BINNAME)
#dd bs=1024 conv=nocreat,notrunc if=$(BINNAME) of="/media/$(shell echo $$USER)/CRP DISABLD/firmware.bin"
../hex2lpc/hex2lpc -s 2 -f $(HEXNAME) -x
$(SIZE) $(ELFNAME)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) $(BINNAME) libssp.a libssp_nonshared.a
# implicit rules
.elf.hex:
$(OBJCOPY) -O ihex $< $@
# explicit rules
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
$(DISNAME): $(ELFNAME)
$(OBJDUMP) -D -S $< > $@
# not required for this project
$(BINNAME): $(ELFNAME)
$(OBJCOPY) -O binary --gap-fill 255 --pad-to 32768 $< $@
# create empty ssp libs for -fstack-protector-all -fstack-protector
libssp.a:
$(AR) rcs $@
libssp_nonshared.a:
$(AR) rcs $@

View File

@@ -0,0 +1,129 @@
/*
delay.c
The delay function delay_micro_seconds() will use the global variable
SystemCoreClock. A call to SystemCoreClockUpdate() is required before
using delay_micro_seconds().
LPC824 Project (U8g2 Library)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <chip.h>
/* Generic ARM delay procedure, based on the system timer (SysTick) */
/*
Delay by the provided number of system ticks.
The delay must be smaller than the RELOAD value.
This delay has an imprecision of about +/- 20 system ticks.
*/
static void _delay_system_ticks_sub(uint32_t sys_ticks)
{
uint32_t start_val, end_val, curr_val;
uint32_t load;
start_val = SysTick->VAL;
start_val &= 0x0ffffffUL;
end_val = start_val;
if ( end_val < sys_ticks )
{
/* check, if the operation after this if clause would lead to a negative result */
/* if this would be the case, then add the reload value first */
load = SysTick->LOAD;
load &= 0x0ffffffUL;
end_val += load;
}
/* counter goes towards zero, so end_val is below start value */
end_val -= sys_ticks;
/* wait until interval is left */
if ( start_val >= end_val )
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val )
break;
if ( curr_val > start_val )
break;
}
}
else
{
for(;;)
{
curr_val = SysTick->VAL;
curr_val &= 0x0ffffffUL;
if ( curr_val <= end_val && curr_val > start_val )
break;
}
}
}
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks)
{
uint32_t load4;
load4 = SysTick->LOAD;
load4 &= 0x0ffffffUL;
load4 >>= 2;
while ( sys_ticks > load4 )
{
sys_ticks -= load4;
_delay_system_ticks_sub(load4);
}
_delay_system_ticks_sub(sys_ticks);
}
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must not overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us)
{
uint32_t sys_ticks;
sys_ticks = SystemCoreClock;
sys_ticks /=1000000UL;
sys_ticks *= us;
delay_system_ticks(sys_ticks);
}

View File

@@ -0,0 +1,55 @@
/*
delay.h
LPC11U3x GPS Logger (https://github.com/olikraus/lpc11u3x-gps-logger)
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#ifndef _DELAY_H
#define _DELAY_H
#include <stdint.h>
/*
Delay by the provided number of system ticks.
Any values between 0 and 0x0ffffffff are allowed.
*/
void delay_system_ticks(uint32_t sys_ticks);
/*
Delay by the provided number of micro seconds.
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
Values between 0 and 1.000.000 (1 second) are ok.
Important: Call SystemCoreClockUpdate() before calling this function.
*/
void delay_micro_seconds(uint32_t us);
#endif /* _DELAY_H */

View File

@@ -0,0 +1,177 @@
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld */
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
/* LPC82x User Manual Page 8 */
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x8000 /* 32K for LPC824 */
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 0x2000 /* 8K for LPC824 */
}
/* source: gcc-arm-none-eabi-4_7-2013q1/share/gcc-arm-none-eabi/samples/ldscripts/sections.ld */
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
/* entry point */
ENTRY(Reset_Handler)
/* extern declaration so that the value appears correctly for the LPC checksum calculation */
EXTERN(NMI_Handler)
EXTERN(HardFault_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/*
http://www.lpcware.com/content/forum/lpc1788-flash-signature-generation
Section 3.5.2/page 12 of the LPC82x User Manual
Linker works with even addresses, however to indicate thumb address mode,
the lowest bit of the address is set to one. For the checksum calculation we
only have the even addresses, however later in the isr table the compiler will
store the odd addresses for the three handler subprocedures if compiled in
thumb mode. Because of this, 3 is added to consider the three odd handler calls.
*/
LPC_checksum = 0- (__StackTop + Reset_Handler + NMI_Handler + HardFault_Handler + 3 /* three entries */);
}

View File

@@ -0,0 +1,89 @@
#include <chip.h>
#include <delay.h>
#include "u8g2.h"
/*=======================================================================*/
/* Configuration */
#define SYS_TICK_PERIOD_IN_MS 100
/*=======================================================================*/
/* external functions */
uint8_t u8x8_gpio_and_delay_lpc824(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
/*=======================================================================*/
/* system procedures and sys tick master task */
volatile uint32_t sys_tick_irq_cnt=0;
void __attribute__ ((interrupt)) SysTick_Handler(void)
{
sys_tick_irq_cnt++;
}
/*=======================================================================*/
u8g2_t u8g2;
void draw(u8g2_t *u8g2)
{
u8g2_SetFontMode(u8g2, 1); // Transparent
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_6x12_tr);
u8g2_DrawStr(u8g2, 0, 20, "Hello World");
}
/*=======================================================================*/
/*
setup the hardware and start interrupts.
called by "Reset_Handler"
*/
int __attribute__ ((noinline)) main(void)
{
/* call to the lpc lib setup procedure. This will set the IRC as clk src and main clk to 24 MHz */
Chip_SystemInit();
/* if the clock or PLL has been changed, also update the global variable SystemCoreClock */
SystemCoreClockUpdate();
/* set systick and start systick interrupt */
SysTick_Config(SystemCoreClock/1000UL*(unsigned long)SYS_TICK_PERIOD_IN_MS);
/* enable clock for several subsystems */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON | SYSCTL_CLOCK_GPIO | SYSCTL_CLOCK_SWM);
/* turn on GPIO */
Chip_GPIO_Init(LPC_GPIO_PORT); /* Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO); */
//Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 15, IOCON_FUNC1); /* RxD */
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, 15);
/* setup display */
u8g2_Setup_ssd1306_i2c_128x64_noname_2(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_lpc824);
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
for(;;)
{
Chip_GPIO_SetPinOutHigh(LPC_GPIO_PORT, 0, 15);
delay_micro_seconds(1000000);
u8g2_FirstPage(&u8g2);
do
{
draw(&u8g2);
} while( u8g2_NextPage(&u8g2) );
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, 0, 15);
delay_micro_seconds(1000000);
}
}

View File

@@ -0,0 +1,203 @@
/*
startup.c
LPC824
Copyright (c) 2016, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
Requires LPC82x Chip Library
*/
#include <chip.h>
/*=======================================================================*/
/* external functions */
void __attribute__ ((interrupt)) SysTick_Handler(void);
//void __attribute__ ((interrupt, used)) UART_IRQ(void);
int __attribute__ ((noinline)) main(void);
/*=======================================================================*/
/*
Reserve some space for the stack. This is used to check if global variables + stack exceed RAM size.
If -Wl,--gc-sections is used, then also define -Wl,--undefined=arm_stack_area to keep the variable in RAM.
The name of the variable (here: arm_stack_area) does not matter.
Heap (=dynamic memory allocation) is not supported
*/
#ifndef __STACK_SIZE
#define __STACK_SIZE 0x100
#endif
unsigned char arm_stack_area[__STACK_SIZE] __attribute__ ((section(".stack"))) __attribute__ ((aligned(8)));
/*=======================================================================*/
/* isr system procedures */
/* make the top of the stack known to the c compiler, value will be calculated by the linker script */
void __StackTop(void);
void __attribute__ ((interrupt)) __attribute__ ((noreturn)) Reset_Handler(void)
{
register unsigned long *ptr;
register unsigned long *start;
register unsigned long *end;
/*
The following two operations are not required in normal mode reset mode,
however it is usefull if the reset handler is started via ISP "Go" command
*/
__set_MSP((uint32_t)__StackTop);
Chip_SYSCTL_Map(2);
/*
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.
*/
extern unsigned long __data_start__[];
extern unsigned long __data_end__[];
extern unsigned long __etext[];
ptr = __etext;
start = __data_start__;
end = __data_end__;
while( start < end )
{
*start = *ptr;
start++;
ptr++;
}
/*
Loop to zero out BSS section, which uses following symbols
in linker script:
__bss_start__: start of BSS section. Must align to 4
__bss_end__: end of BSS section. Must align to 4
*/
extern unsigned long __bss_start__[];
extern unsigned long __bss_end__[];
ptr = __bss_start__;
end = __bss_end__;
while( ptr < end )
{
*ptr = 0;
ptr++;
}
/* Call main procedure */
main();
/* finished, do nothing. */
for(;;)
;
}
/* "NMI_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) NMI_Handler(void)
{
}
/* "HardFault_Handler" is used in the ld script to calculate the checksum */
void __attribute__ ((interrupt)) HardFault_Handler(void)
{
}
/* make the checksum known to the c compiler, value will be calculated by the linker script */
void LPC_checksum(void);
/*=======================================================================*/
/* isr vector */
/* see page 445 of the LPC11U3x user manual */
/* see also enum LPC11UXX_IRQn in isr/cmsis_11uxx.h */
typedef void (*isr_handler_t)(void);
isr_handler_t __isr_vector[48] __attribute__ ((section(".isr_vector"))) __attribute__ ((aligned(4)))=
{
__StackTop, /* 0x00: Top of Stack, calculated by the linker script */
Reset_Handler, /* 0x04: Reset Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
NMI_Handler, /* 0x08: NMI Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
HardFault_Handler, /* 0x0c: Hard Fault Handler, DO NOT CHANGE THE ISR NAME (used for LPC_checksum calculation) */
0, /* 0x10: Reserved, must be 0 */
0, /* 0x14: Reserved, must be 0 */
0, /* 0x18: Reserved, must be 0 */
LPC_checksum, /* 0x1c: Checksum, calculated by the linker script or the flash utility */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* SVCall Handler */
0, /* Reserved */
0, /* Reserved */
0, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
0, /* 0 SPI0 controller */
0, /* 1 SPI1 controller */
0, /* 2 Reserved */
0, /* 3 UART0 */
0, /* 4 UART1 */
0, /* 5 UART2 */
0, /* 6 Reserved */
0, /* 7 I2C1 controller */
0, /* 8 I2C0 controller */
0, /* 9 SCT */
0, /* 10 Multi-Rate Timer */
0, /* 11 CMP_IRQn Comparator */
0, /* 12 WDT_IRQn WDT */
0, /* 13 BOD_IRQn BOD Brown Out Detect */
0, /* 14 FLASH_IRQn */
0, /* 15 WKT_IRQn Self wake-up timer */
0, /* 16 ADC_SEQA_IRQn */
0, /* 17 ADC_SEQB_IRQn */
0, /* 18 ADC_THCMP_IRQn ADC threshold compare */
0, /* 19 ADC_OVR_IRQn ADC overrun */
0, /* 20 Reserved */
0, /* 21 Reserved */
0, /* 22 Reserved */
0, /* 23 Reserved */
0, /* 24 PIO INT0 */
0, /* 25 PIO INT1 */
0, /* 26 PIO INT2 */
0, /* 27 PIO INT3 */
0, /* 28 PIO INT4 */
0, /* 29 PIO INT5 */
0, /* 30 PIO INT6 */
0 /* 31 PIO INT7 */
};

View File

@@ -0,0 +1,48 @@
/*
sysclk.c
LPC824
Copyright (c) 2017, olikraus@gmail.com
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.
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 THE COPYRIGHT HOLDER OR
CONTRIBUTORS 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.
*/
#include <chip.h>
/*
According to chip.h there must be two variables which have to be defined
by a user program: OscRateIn and ExtRateIn
Values can be 0, but if not 0, then these values define the clock speed
Actually there is one more variable (SystemCoreClock) which is
updated by SystemCoreClockUpdate() based on the values given in the
other two values.
*/
const uint32_t OscRateIn = 0; /* freq. of the external crystal osc */
const uint32_t ExtRateIn = 0;

View File

@@ -0,0 +1,106 @@
/*
u8x8cb.c
*/
#include "chip.h"
#include "delay.h"
#include "u8x8.h"
/* although we use SW I2C, use the HW pins for later upgrade */
#define I2C_CLOCK_PIN 13
#define I2C_CLOCK_PORT 0
#define I2C_DATA_PIN 17
#define I2C_DATA_PORT 0
uint8_t u8x8_gpio_and_delay_lpc824(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT:
/* only support for software I2C*/
Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO13, PIN_MODE_PULLUP); /* clk */
Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO17, PIN_MODE_PULLUP); /* data */
Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
/*
Chip_IOCON_PinMuxSet(LPC_IOCON, KEY_SELECT_PORT, KEY_SELECT_PIN, KEY_SELECT_FN|IOCON_MODE_PULLUP);
Chip_GPIO_SetPinDIRInput(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN);
Chip_IOCON_PinMuxSet(LPC_IOCON, KEY_PREV_PORT, KEY_PREV_PIN, IOCON_MODE_PULLUP);
Chip_GPIO_SetPinDIRInput(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN);
Chip_IOCON_PinMuxSet(LPC_IOCON, KEY_NEXT_PORT, KEY_NEXT_PIN, IOCON_MODE_PULLUP);
Chip_GPIO_SetPinDIRInput(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN);
Chip_IOCON_PinMuxSet(LPC_IOCON, KEY_HOME_PORT, KEY_HOME_PIN, KEY_HOME_FN|IOCON_MODE_PULLUP);
Chip_GPIO_SetPinDIRInput(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN);
*/
break;
case U8X8_MSG_DELAY_NANO:
/* not required for SW I2C */
break;
case U8X8_MSG_DELAY_10MICRO:
/* not used at the moment */
break;
case U8X8_MSG_DELAY_100NANO:
/* not used at the moment */
break;
case U8X8_MSG_DELAY_MILLI:
delay_micro_seconds(arg_int*1000UL);
break;
case U8X8_MSG_DELAY_I2C:
/* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
delay_micro_seconds(arg_int<=2?5:1);
break;
case U8X8_MSG_GPIO_I2C_CLOCK:
if ( arg_int == 0 )
{
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
}
else
{
//Chip_GPIO_SetPinOutHigh(LPC_GPIO, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
}
break;
case U8X8_MSG_GPIO_I2C_DATA:
if ( arg_int == 0 )
{
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
}
else
{
//Chip_GPIO_SetPinOutHigh(LPC_GPIO, I2C_DATA_PORT, I2C_DATA_PIN);
Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
}
break;
/*
case U8X8_MSG_GPIO_MENU_SELECT:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN));
break;
case U8X8_MSG_GPIO_MENU_NEXT:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN));
break;
case U8X8_MSG_GPIO_MENU_PREV:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN));
break;
case U8X8_MSG_GPIO_MENU_HOME:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN));
break;
*/
default:
u8x8_SetGPIOResult(u8x8, 1);
break;
}
return 1;
}

View File

@@ -0,0 +1,17 @@
#
# hex2lpc: Linux flash utility for LPC8xx devices
#
CFLAGS = -g -Wall
#CFLAGS = -O4 -Wall
SRC = hex2lpc.c
OBJ = $(SRC:.c=.o)
hex2lpc: $(SRC)
$(CC) -Wall -g $(LDFLAGS) $(SRC) -o hex2lpc
clean:
-rm ./hex2lpc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
/*
* @brief LPC8xx Analog comparator driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __ACMP_8XX_H_
#define __ACMP_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup ACMP_8XX CHIP: LPC8xx Analog Comparator driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief Analog Comparator register block structure
*/
typedef struct { /*!< ACMP Structure */
__IO uint32_t CTRL; /*!< Comparator control register */
__IO uint32_t LAD; /*!< Voltage ladder register */
} LPC_CMP_T;
/* Reserved bits masks for registers */
#define ACMP_CTRL_RESERVED (7|(1<<5)|(1<<7)|(0x3f<<14)|(1<<22)|(1<<24)|(0x1fu<<27))
#define ACMP_LAD_RESERVED (~0x7f)
#define ACMP_COMPSA_BIT (1 << 6) /* Comparator output control bit */
#define ACMP_COMPSTAT_BIT (1 << 21) /* Comparator status, reflects the state of the comparator output */
#define ACMP_COMPEDGE_BIT (1 << 23) /* Comparator edge-detect status */
#define ACMP_LADENAB_BIT (1 << 0) /* Voltage ladder enable bit */
/* EDGECLR interrupt clear bit, write 1, then 0 */
#define ACMP_EDGECLR_BIT (1 << 20)
#define ACMP_EDGESEL_MASK (0x3 << 3)
#define ACMP_COMPVPSEL_MASK (0x7 << 8)
#define ACMP_COMPVMSEL_MASK (0x7 << 11)
#define ACMP_HYSTERESIS_MASK (0x3 << 25)
#define ACMP_LADSEL_MASK (0x1F << 1)
#define ACMP_LADREF_MASK (0x1 << 6)
/** Edge selection for comparator */
typedef enum {
ACMP_EDGESEL_FALLING = (0 << 3), /* Set the COMPEDGE bit on falling edge */
ACMP_EDGESEL_RISING = (1 << 3), /* Set the COMPEDGE bit on rising edge */
ACMP_EDGESEL_BOTH = (2 << 3) /* Set the COMPEDGE bit on falling and rising edges */
} ACMP_EDGESEL_T;
/** Hysteresis selection for comparator */
typedef enum {
ACMP_HYS_NONE = (0 << 25), /* No hysteresis (the output will switch as the voltages cross) */
ACMP_HYS_5MV = (1 << 25), /* 5mV hysteresis */
ACMP_HYS_10MV = (2 << 25), /* 10mV hysteresis */
ACMP_HYS_20MV = (3 << 25) /* 20mV hysteresis */
} ACMP_HYS_T;
/**
* Analog Comparator positive input values
*/
typedef enum CHIP_ACMP_POS_INPUT {
ACMP_POSIN_VLO = (0 << 8), /*!< Voltage ladder output */
ACMP_POSIN_ACMP_I1 = (1 << 8), /*!< ACMP_I1 pin */
ACMP_POSIN_ACMP_I2 = (2 << 8), /*!< ACMP_I2 pin */
ACMP_POSIN_ACMP_I3 = (3 << 8), /*!< ACMP_I3 pin */
ACMP_POSIN_ACMP_I4 = (4 << 8), /*!< ACMP_I4 pin */
#if defined(CHIP_LPC82X)
ACMP_POSIN_INT_REF = (5 << 8), /*!< Internal reference voltage */
ACMP_POSIN_ADC_0 = (6 << 8), /*!< ADC_0 Input */
#else
ACMP_POSIN_INT_REF = (6 << 8), /*!< Internal reference voltage */
#endif
} ACMP_POS_INPUT_T;
/**
* Analog Comparator negative input values
*/
typedef enum CHIP_ACMP_NEG_INPUT {
ACMP_NEGIN_VLO = (0 << 11), /*!< Voltage ladder output */
ACMP_NEGIN_ACMP_I1 = (1 << 11), /*!< ACMP_I1 pin */
ACMP_NEGIN_ACMP_I2 = (2 << 11), /*!< ACMP_I2 pin */
ACMP_NEGIN_ACMP_I3 = (3 << 11), /*!< ACMP_I3 pin */
ACMP_NEGIN_ACMP_I4 = (4 << 11), /*!< ACMP_I4 pin */
#if defined(CHIP_LPC82X)
ACMP_NEGIN_INT_REF = (5 << 11), /*!< Internal reference voltage */
ACMP_NEGIN_ADC_0 = (6 << 11), /*!< ADC_0 Input */
#else
ACMP_NEGIN_INT_REF = (6 << 11) /*!< Internal reference voltage */
#endif
} ACMP_NEG_INPUT_T;
/**
* @brief Initializes the ACMP
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
void Chip_ACMP_Init(LPC_CMP_T *pACMP);
/**
* @brief Deinitializes the ACMP
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
void Chip_ACMP_Deinit(LPC_CMP_T *pACMP);
/**
* @brief Returns the current comparator status
* @param pACMP : Pointer to Analog Comparator block
* @return Status is an Or'ed value of ACMP_COMPSTAT_BIT or ACMP_COMPEDGE_BIT
*/
STATIC INLINE uint32_t Chip_ACMP_GetCompStatus(LPC_CMP_T *pACMP)
{
return pACMP->CTRL & (ACMP_COMPSTAT_BIT | ACMP_COMPEDGE_BIT);
}
/**
* @brief Clears the ACMP interrupt (EDGECLR bit)
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
void Chip_ACMP_EdgeClear(LPC_CMP_T *pACMP);
/**
* @brief Sets up ACMP edge selection
* @param pACMP : Pointer to Analog Comparator block
* @param edgeSel : Edge selection value
* @return Nothing
*/
void Chip_ACMP_SetEdgeSelection(LPC_CMP_T *pACMP, ACMP_EDGESEL_T edgeSel);
/**
* @brief Synchronizes Comparator output to bus clock
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_EnableSyncCompOut(LPC_CMP_T *pACMP)
{
pACMP->CTRL = ACMP_COMPSA_BIT | (pACMP->CTRL & ~ACMP_CTRL_RESERVED);
}
/**
* @brief Sets comparator output to be used directly (no sync)
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_DisableSyncCompOut(LPC_CMP_T *pACMP)
{
pACMP->CTRL &= ~(ACMP_COMPSA_BIT | ACMP_CTRL_RESERVED);
}
/**
* @brief Selects positive voltage input
* @param pACMP : Pointer to Analog Comparator block
* @param Posinput : one of the positive input voltage sources
* @return Nothing
*/
void Chip_ACMP_SetPosVoltRef(LPC_CMP_T *pACMP, ACMP_POS_INPUT_T Posinput);
/**
* @brief Selects negative voltage input
* @param pACMP : Pointer to Analog Comparator block
* @param Neginput : one of the negative input voltage sources
* @return Nothing
*/
void Chip_ACMP_SetNegVoltRef(LPC_CMP_T *pACMP, ACMP_NEG_INPUT_T Neginput);
/**
* @brief Selects hysteresis level
* @param pACMP : Pointer to Analog Comparator block
* @param hys : Selected Hysteresis level
* @return Nothing
*/
void Chip_ACMP_SetHysteresis(LPC_CMP_T *pACMP, ACMP_HYS_T hys);
/**
* @brief Helper function for setting up ACMP control
* @param pACMP : Pointer to Analog Comparator block
* @param edgeSel : Edge selection value
* @param Posinput : one of the positive input voltage sources
* @param Neginput : one of the negative input voltage sources
* @param hys : Selected Hysteresis level
* @return Nothing
*/
void Chip_ACMP_SetupAMCPRefs(LPC_CMP_T *pACMP, ACMP_EDGESEL_T edgeSel,
ACMP_POS_INPUT_T Posinput, ACMP_NEG_INPUT_T Neginput,
ACMP_HYS_T hys);
/**
* @brief Sets up voltage ladder
* @param pACMP : Pointer to Analog Comparator block
* @param ladsel : Voltage ladder value (0 .. 31)
* @param ladrefVDDCMP : Selects the reference voltage Vref for the voltage ladder
* : false for VDD, true for VDDCMP pin
* @return Nothing
*/
void Chip_ACMP_SetupVoltLadder(LPC_CMP_T *pACMP, uint32_t ladsel, bool ladrefVDDCMP);
/**
* @brief Enables voltage ladder
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_EnableVoltLadder(LPC_CMP_T *pACMP)
{
pACMP->LAD = ACMP_LADENAB_BIT | (pACMP->LAD & ~ACMP_LAD_RESERVED);
}
/**
* @brief Disables voltage ladder
* @param pACMP : Pointer to Analog Comparator block
* @return Nothing
*/
STATIC INLINE void Chip_ACMP_DisableVoltLadder(LPC_CMP_T *pACMP)
{
pACMP->LAD &= ~(ACMP_LADENAB_BIT | ACMP_LAD_RESERVED);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ACMP_8XX_H_ */

View File

@@ -0,0 +1,586 @@
/*
* @brief LPC82x ADC driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __ADC_8XX_H_
#define __ADC_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup ADC_8XX CHIP: LPC8xx A/D conversion driver (Available on LPC82x Family)
* @ingroup CHIP_8xx_Drivers
* @{
*/
/** Sequence index enumerations, used in various parts of the code for
register indexing and sequencer selection */
typedef enum {
ADC_SEQA_IDX,
ADC_SEQB_IDX
} ADC_SEQ_IDX_T;
/**
* @brief ADC register block structure
*/
typedef struct { /*!< ADCn Structure */
__IO uint32_t CTRL; /*!< A/D Control Register. The AD0CR register must be written to select the operating mode before A/D conversion can occur. */
__I uint32_t RESERVED0;
__IO uint32_t SEQ_CTRL[ADC_SEQB_IDX + 1]; /*!< A/D Sequence A & B Control Register. Controls triggering and channel selection for sonversion sequence. */
__IO uint32_t SEQ_GDAT[ADC_SEQB_IDX + 1]; /*!< A/D Sequence A & B Global Data Register. Contains the result of the most recent A/D conversion for sequence. */
__I uint32_t RESERVED1[2];
__I uint32_t DR[12]; /*!< A/D Channel Data Register. This register contains the result of the most recent conversion completed on channel n. */
__IO uint32_t THR_LOW[2]; /*!< A/D Low Compare Threshold Register 0 & 1. Contains the lower threshold level for automatic threshold comparison. */
__IO uint32_t THR_HIGH[2]; /*!< A/D High Compare Threshold Register 0 & 1. Contains the higher threshold level for automatic threshold comparison. */
__IO uint32_t CHAN_THRSEL; /*!< A/D Channel Threshold Select Register. Specifies which set of threshold compare registers to use. */
__IO uint32_t INTEN; /*!< A/D Interrupt Enable Register. This register contains enable bits that enable sequence-A, sequence-B, threshold compare and overrun interrupts. */
__IO uint32_t FLAGS; /*!< A/D Flags Register. This register contains interrupt flags. - To be checked */
__IO uint32_t TRM; /*!< A/D Trim Register. */
} LPC_ADC_T;
/** Maximum sample rate in Hz (12-bit conversions) */
#define ADC_MAX_SAMPLE_RATE 30000000
/**
* @brief ADC register support bitfields and mask
*/
/** ADC Control register bit fields */
#define ADC_CR_CLKDIV_MASK (0xFF << 0) /*!< Mask for Clock divider value */
#define ADC_CR_CLKDIV_BITPOS (0) /*!< Bit position for Clock divider value */
#define ADC_CR_ASYNMODE (1 << 8) /*!< Asynchronous mode enable bit */
#define ADC_CR_MODE10BIT (1 << 9) /*!< 10-bit mode enable bit */
#define ADC_CR_LPWRMODEBIT (1 << 10) /*!< Low power mode enable bit */
#define ADC_CR_CALMODEBIT (1 << 30) /*!< Self calibration cycle enable bit */
#define ADC_CR_BITACC(n) ((((n) & 0x1) << 9)) /*!< 12-bit or 10-bit ADC accuracy */
#define ADC_CR_CLKDIV(n) ((((n) & 0xFF) << 0)) /*!< The APB clock (PCLK) is divided by (this value plus one) to produce the clock for the A/D */
#define ADC_SAMPLE_RATE_CONFIG_MASK (ADC_CR_CLKDIV(0xFF) | ADC_CR_BITACC(0x01))
/** ADC Sequence Control register bit fields */
#define ADC_SEQ_CTRL_CHANSEL(n) (1 << (n)) /*!< Channel select macro */
#define ADC_SEQ_CTRL_CHANSEL_MASK (0xFFF) /*!< Channel select mask */
/** ADC hardware trigger sources in SEQ_CTRL */
#define ADC_SEQ_CTRL_HWTRIG_ARM_TXEV (0 << 12) /*!< HW trigger input - ARM TXEV */
#define ADC_SEQ_CTRL_HWTRIG_CT32B0_MAT0 (1 << 12) /*!< HW trigger input - Match output 0 of CT32B0 */
#define ADC_SEQ_CTRL_HWTRIG_CT32B0_MAT1 (2 << 12) /*!< HW trigger input - Match output 1 of CT32B1 or SCT_OUT0 */
#define ADC_SEQ_CTRL_HWTRIG_SCT_OUT0 (2 << 12) /*!< HW trigger input - Match output 1 of CT32B1 or SCT_OUT0 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B0_MAT0 (3 << 12) /*!< HW trigger input - Match output 0 of CT16B0 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B0_MAT1 (4 << 12) /*!< HW trigger input - Match output 1 of CT16B1 or SCT_OUT1 */
#define ADC_SEQ_CTRL_HWTRIG_SCT_OUT1 (4 << 12) /*!< HW trigger input - Match output 1 of CT16B1 or SCT_OUT1 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B0_CAP0 (5 << 12) /*!< HW trigger input - Capture input 0 of CT16B0 */
#define ADC_SEQ_CTRL_HWTRIG_CT16B1_CAP0 (6 << 12) /*!< HW trigger input - Capture input 0 of CT16B1 */
#define ADC_SEQ_CTRL_HWTRIG_CT32B0_CAP0 (7 << 12) /*!< HW trigger input - Capture input 0 of CT32B1 */
#define ADC_SEQ_CTRL_HWTRIG_MASK (0x3F << 12) /*!< HW trigger input bitfield mask */
/** SEQ_CTRL register bit fields */
#define ADC_SEQ_CTRL_HWTRIG_POLPOS (1 << 18) /*!< HW trigger polarity - positive edge */
#define ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS (1 << 19) /*!< HW trigger bypass synchronisation */
#define ADC_SEQ_CTRL_START (1 << 26) /*!< Start conversion enable bit */
#define ADC_SEQ_CTRL_BURST (1 << 27) /*!< Repeated conversion enable bit */
#define ADC_SEQ_CTRL_SINGLESTEP (1 << 28) /*!< Single step enable bit */
#define ADC_SEQ_CTRL_LOWPRIO (1 << 29) /*!< High priority enable bit (regardless of name) */
#define ADC_SEQ_CTRL_MODE_EOS (1 << 30) /*!< Mode End of sequence enable bit */
#define ADC_SEQ_CTRL_SEQ_ENA (1UL << 31) /*!< Sequence enable bit */
/** ADC global data register bit fields */
#define ADC_SEQ_GDAT_RESULT_MASK (0xFFF << 4) /*!< Result value mask */
#define ADC_SEQ_GDAT_RESULT_BITPOS (4) /*!< Result start bit position */
#define ADC_SEQ_GDAT_THCMPRANGE_MASK (0x3 << 16) /*!< Comparion range mask */
#define ADC_SEQ_GDAT_THCMPRANGE_BITPOS (16) /*!< Comparison range bit position */
#define ADC_SEQ_GDAT_THCMPCROSS_MASK (0x3 << 18) /*!< Comparion cross mask */
#define ADC_SEQ_GDAT_THCMPCROSS_BITPOS (18) /*!< Comparison cross bit position */
#define ADC_SEQ_GDAT_CHAN_MASK (0xF << 26) /*!< Channel number mask */
#define ADC_SEQ_GDAT_CHAN_BITPOS (26) /*!< Channel number bit position */
#define ADC_SEQ_GDAT_OVERRUN (1 << 30) /*!< Overrun bit */
#define ADC_SEQ_GDAT_DATAVALID (1UL << 31) /*!< Data valid bit */
/** ADC Data register bit fields */
#define ADC_DR_RESULT(n) ((((n) >> 4) & 0xFFF)) /*!< Macro for getting the ADC data value */
#define ADC_DR_THCMPRANGE_MASK (0x3 << 16) /*!< Comparion range mask */
#define ADC_DR_THCMPRANGE_BITPOS (16) /*!< Comparison range bit position */
#define ADC_DR_THCMPRANGE(n) (((n) >> ADC_DR_THCMPRANGE_BITPOS) & 0x3)
#define ADC_DR_THCMPCROSS_MASK (0x3 << 18) /*!< Comparion cross mask */
#define ADC_DR_THCMPCROSS_BITPOS (18) /*!< Comparison cross bit position */
#define ADC_DR_THCMPCROSS(n) (((n) >> ADC_DR_THCMPCROSS_BITPOS) & 0x3)
#define ADC_DR_CHAN_MASK (0xF << 26) /*!< Channel number mask */
#define ADC_DR_CHAN_BITPOS (26) /*!< Channel number bit position */
#define ADC_DR_CHANNEL(n) (((n) >> ADC_DR_CHAN_BITPOS) & 0xF) /*!< Channel number bit position */
#define ADC_DR_OVERRUN (1 << 30) /*!< Overrun bit */
#define ADC_DR_DATAVALID (1UL << 31) /*!< Data valid bit */
#define ADC_DR_DONE(n) (((n) >> 31))
/** ADC low/high Threshold register bit fields */
#define ADC_THR_VAL_MASK (0xFFF << 4) /*!< Threshold value bit mask */
#define ADC_THR_VAL_POS (4) /*!< Threshold value bit position */
/** ADC Threshold select register bit fields */
#define ADC_THRSEL_CHAN_SEL_THR1(n) (1 << (n)) /*!< Select THR1 register for channel n */
/** ADC Interrupt Enable register bit fields */
#define ADC_INTEN_SEQA_ENABLE (1 << 0) /*!< Sequence A Interrupt enable bit */
#define ADC_INTEN_SEQB_ENABLE (1 << 1) /*!< Sequence B Interrupt enable bit */
#define ADC_INTEN_SEQN_ENABLE(seq) (1 << (seq)) /*!< Sequence A/B Interrupt enable bit */
#define ADC_INTEN_OVRRUN_ENABLE (1 << 2) /*!< Overrun Interrupt enable bit */
#define ADC_INTEN_CMP_DISBALE (0) /*!< Disable comparison interrupt value */
#define ADC_INTEN_CMP_OUTSIDETH (1) /*!< Outside threshold interrupt value */
#define ADC_INTEN_CMP_CROSSTH (2) /*!< Crossing threshold interrupt value */
#define ADC_INTEN_CMP_MASK (3) /*!< Comparison interrupt value mask */
#define ADC_INTEN_CMP_ENABLE(isel, ch) (((isel) & ADC_INTEN_CMP_MASK) << ((2 * (ch)) + 3)) /*!< Interrupt selection for channel */
/** ADC Flags register bit fields */
#define ADC_FLAGS_THCMP_MASK(ch) (1 << (ch)) /*!< Threshold comparison status for channel */
#define ADC_FLAGS_OVRRUN_MASK(ch) (1 << (12 + (ch))) /*!< Overrun status for channel */
#define ADC_FLAGS_SEQA_OVRRUN_MASK (1 << 24) /*!< Seq A Overrun status */
#define ADC_FLAGS_SEQB_OVRRUN_MASK (1 << 25) /*!< Seq B Overrun status */
#define ADC_FLAGS_SEQN_OVRRUN_MASK(seq) (1 << (24 + (seq))) /*!< Seq A/B Overrun status */
#define ADC_FLAGS_SEQA_INT_MASK (1 << 28) /*!< Seq A Interrupt status */
#define ADC_FLAGS_SEQB_INT_MASK (1 << 29) /*!< Seq B Interrupt status */
#define ADC_FLAGS_SEQN_INT_MASK(seq) (1 << (28 + (seq)))/*!< Seq A/B Interrupt status */
#define ADC_FLAGS_THCMP_INT_MASK (1 << 30) /*!< Threshold comparison Interrupt status */
#define ADC_FLAGS_OVRRUN_INT_MASK (1UL << 31) /*!< Overrun Interrupt status */
/** ADC Trim register bit fields */
#define ADC_TRIM_VRANGE_HIGHV (0 << 5) /*!< Voltage range bit - High volatge (2.7V to 3.6V) */
#define ADC_TRIM_VRANGE_LOWV (1 << 5) /*!< Voltage range bit - Low volatge (1.8V to 2.7V) */
/** ADC Register reserved bit masks */
#define ADC_CHAN_THRSEL_RES 0xFFFFF000
#define ADC_INTEN_RES 0xF8000000
#define ADC_SEQ_CTRL_RES ((7 << 15) | (0x3F << 20))
/**
* @brief Initialize the ADC peripheral
* @param pADC : The base of ADC peripheral on the chip
* @param flags : ADC flags for init (ADC_CR_MODE10BIT and/or ADC_CR_LPWRMODEBIT)
* @return Nothing
* @note To select low-power ADC mode, enable the ADC_CR_LPWRMODEBIT flag.
* To select 10-bit conversion mode, enable the ADC_CR_MODE10BIT flag.<br>
* Example: Chip_ADC_Init(LPC_ADC, (ADC_CR_MODE10BIT | ADC_CR_LPWRMODEBIT));
*/
void Chip_ADC_Init(LPC_ADC_T *pADC, uint32_t flags);
/**
* @brief Shutdown ADC
* @param pADC : The base of ADC peripheral on the chip
* @return Nothing
* @note Disables the ADC clocks and ADC power
*/
void Chip_ADC_DeInit(LPC_ADC_T *pADC);
/**
* @brief Set ADC divider
* @param pADC : The base of ADC peripheral on the chip
* @param div : ADC divider value to set minus 1
* @return Nothing
* @note The value is used as a divider to generate the ADC
* clock rate from the ADC input clock. The ADC input clock is based
* on the system clock. Valid values for this function are from 0 to 255
* with 0=divide by 1, 1=divide by 2, 2=divide by 3, etc.<br>
* Do not decrement this value by 1.<br>
* To set the ADC clock rate to 1MHz, use the following function:<br>
* Chip_ADC_SetDivider(LPC_ADC, (Chip_Clock_GetSystemClockRate() / 1000000) - 1);
*/
STATIC INLINE void Chip_ADC_SetDivider(LPC_ADC_T *pADC, uint8_t div)
{
uint32_t temp;
temp = pADC->CTRL & ~(ADC_CR_CLKDIV_MASK);
pADC->CTRL = temp | (uint32_t) div;
}
/**
* @brief Set ADC clock rate
* @param pADC : The base of ADC peripheral on the chip
* @param rate : rate in Hz to set ADC clock to (maximum ADC_MAX_SAMPLE_RATE)
* @return Nothing
* @note When ADC is set to ADC_CR_ASYNMODE this function has no effect. The
* rate mentioned in @a rate is the sampling clock rate and not the frequency at
* at which the conversion will be done. Example setting @a rate to 30 MHz will
* get a sampling rate of 1.2M samples per second.
*/
STATIC INLINE void Chip_ADC_SetClockRate(LPC_ADC_T *pADC, uint32_t rate)
{
Chip_ADC_SetDivider(pADC, (uint8_t) (Chip_Clock_GetSystemClockRate() / rate) - 1);
}
/**
* @brief Get ADC divider
* @param pADC : The base of ADC peripheral on the chip
* @return the current ADC divider
* @note This function returns the divider that is used to generate the
* ADC frequency. The returned value must be incremented by 1. The
* frequency can be determined with the following function:<br>
* adc_freq = Chip_Clock_GetSystemClockRate() / (Chip_ADC_GetDivider(LPC_ADC) + 1);
*/
STATIC INLINE uint8_t Chip_ADC_GetDivider(LPC_ADC_T *pADC)
{
return pADC->CTRL & ADC_CR_CLKDIV_MASK;
}
/**
* @brief Start ADC calibration
* @param pADC : The base of ADC peripheral on the chip
* @return Nothing
* @note Calibration is not done as part of Chip_ADC_Init(), but
* is required after the call to Chip_ADC_Init() or after returning
* from a power-down state. Calibration may alter the ADC_CR_ASYNMODE
* and ADC_CR_LPWRMODEBIT flags ni the CTRL register.
*/
void Chip_ADC_StartCalibration(LPC_ADC_T *pADC);
/**
* @brief Start ADC calibration
* @param pADC : The base of ADC peripheral on the chip
* @return TRUE if calibration is complete, otherwise FALSE.
*/
STATIC INLINE bool Chip_ADC_IsCalibrationDone(LPC_ADC_T *pADC)
{
return (bool) ((pADC->CTRL & ADC_CR_CALMODEBIT) == 0);
}
/**
* @brief Helper function for safely setting ADC sequencer register bits
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to set bits for
* @param bits : Or'ed bits of a sequencer register to set
* @return Nothing
* @note This function will safely set the ADC sequencer register bits
* while maintaining bits 20..25 as 0, regardless of the read state of those bits.
*/
STATIC INLINE void Chip_ADC_SetSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
{
pADC->SEQ_CTRL[seqIndex] = (pADC->SEQ_CTRL[seqIndex] & ~ADC_SEQ_CTRL_RES) | bits;
}
/**
* @brief Helper function for safely clearing ADC sequencer register bits
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to clear bits for
* @param bits : Or'ed bits of a sequencer register to clear
* @return Nothing
* @note This function will safely clear the ADC sequencer register bits
* while maintaining bits 20..25 as 0, regardless of the read state of those bits.
*/
STATIC INLINE void Chip_ADC_ClearSequencerBits(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t bits)
{
pADC->SEQ_CTRL[seqIndex] = pADC->SEQ_CTRL[seqIndex] & ~(ADC_SEQ_CTRL_RES | bits);
}
/**
* @brief Sets up ADC conversion sequencer A or B
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to setup
* @param options : OR'ed Sequencer options to setup (see notes)
* @return Nothing
* @note Sets up sequencer options for a conversion sequence. This function
* should be used to setup the selected channels for the sequence, the sequencer
* trigger, the trigger polarity, synchronization bypass, priority, and mode. All
* options are passed to the functions as a OR'ed list of values. This function will
* disable/clear the sequencer start/burst/single step/enable if they are enabled.<br>
* Select the channels by OR'ing in one or more ADC_SEQ_CTRL_CHANSEL(ch) values.<br>
* Select the hardware trigger by OR'ing in one ADC_SEQ_CTRL_HWTRIG_* value.<br>
* Select a positive edge hardware trigger by OR'ing in ADC_SEQ_CTRL_HWTRIG_POLPOS.<br>
* Select trigger bypass synchronisation by OR'ing in ADC_SEQ_CTRL_HWTRIG_SYNCBYPASS.<br>
* Select ADC single step on trigger/start by OR'ing in ADC_SEQ_CTRL_SINGLESTEP.<br>
* Select higher priority conversion on the other sequencer by OR'ing in ADC_SEQ_CTRL_LOWPRIO.<br>
* Select end of seqeuence instead of end of conversion interrupt by OR'ing in ADC_SEQ_CTRL_MODE_EOS.<br>
* Example for setting up sequencer A (channels 0-2, trigger on high edge of PIO0_2, interrupt on end of sequence):<br>
* Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX, (
* ADC_SEQ_CTRL_CHANSEL(0) | ADC_SEQ_CTRL_CHANSEL(1) | ADC_SEQ_CTRL_CHANSEL(2) |
* ADC_SEQ_CTRL_HWTRIG_PIO0_2 | ADC_SEQ_CTRL_HWTRIG_POLPOS | ADC_SEQ_CTRL_MODE_EOS));
*/
STATIC INLINE void Chip_ADC_SetupSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex, uint32_t options)
{
pADC->SEQ_CTRL[seqIndex] = options;
}
/**
* @brief Enables a sequencer
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to enable
* @return Nothing
*/
STATIC INLINE void Chip_ADC_EnableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA);
}
/**
* @brief Disables a sequencer
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to disable
* @return Nothing
*/
STATIC INLINE void Chip_ADC_DisableSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_SEQ_ENA);
}
/**
* @brief Forces a sequencer trigger event (software trigger of ADC)
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to start
* @return Nothing
* @note This function sets the START bit for the sequencer to force a
* single conversion sequence or a single step conversion.
*/
STATIC INLINE void Chip_ADC_StartSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_START);
}
/**
* @brief Starts sequencer burst mode
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to start burst on
* @return Nothing
* @note This function sets the BURST bit for the sequencer to force
* continuous conversion. Use Chip_ADC_StopBurstSequencer() to stop the
* ADC burst sequence.
*/
STATIC INLINE void Chip_ADC_StartBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_SetSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST);
}
/**
* @brief Stops sequencer burst mode
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to stop burst on
* @return Nothing
*/
STATIC INLINE void Chip_ADC_StopBurstSequencer(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
Chip_ADC_ClearSequencerBits(pADC, seqIndex, ADC_SEQ_CTRL_BURST);
}
/** ADC sequence global data register threshold comparison range enumerations */
typedef enum {
ADC_DR_THCMPRANGE_INRANGE,
ADC_DR_THCMPRANGE_RESERVED,
ADC_DR_THCMPRANGE_BELOW,
ADC_DR_THCMPRANGE_ABOVE
} ADC_DR_THCMPRANGE_T;
/** ADC sequence global data register threshold comparison cross enumerations */
typedef enum {
ADC_DR_THCMPCROSS_NOCROSS,
ADC_DR_THCMPCROSS_RESERVED,
ADC_DR_THCMPCROSS_DOWNWARD,
ADC_DR_THCMPCROSS_UPWARD
} ADC_DR_THCMPCROSS_T;
/**
* @brief Read a ADC sequence global data register
* @param pADC : The base of ADC peripheral on the chip
* @param seqIndex : Sequencer to read
* @return Current raw value of the ADC sequence A or B global data register
* @note This function returns the raw value of the data register and clears
* the overrun and datavalid status for the register. Once this register is read,
* the following functions can be used to parse the raw value:<br>
* uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value
* uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value
* ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high
* ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low
* uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data
* bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag
* bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag
*/
STATIC INLINE uint32_t Chip_ADC_GetSequencerDataReg(LPC_ADC_T *pADC, ADC_SEQ_IDX_T seqIndex)
{
return pADC->SEQ_GDAT[seqIndex];
}
/**
* @brief Read a ADC data register
* @param pADC : The base of ADC peripheral on the chip
* @param index : Data register to read, 1-8
* @return Current raw value of the ADC data register
* @note This function returns the raw value of the data register and clears
* the overrun and datavalid status for the register. Once this register is read,
* the following functions can be used to parse the raw value:<br>
* uint32_t adcDataRawValue = Chip_ADC_ReadSequencerDataReg(LPC_ADC, ADC_SEQA_IDX); // Get raw value
* uint32_t adcDataValue = ADC_DR_RESULT(adcDataRawValue); // Aligned and masked ADC data value
* ADC_DR_THCMPRANGE_T adcRange = (ADC_DR_THCMPRANGE_T) ADC_DR_THCMPRANGE(adcDataRawValue); // Sample range compared to threshold low/high
* ADC_DR_THCMPCROSS_T adcRange = (ADC_DR_THCMPCROSS_T) ADC_DR_THCMPCROSS(adcDataRawValue); // Sample cross compared to threshold low
* uint32_t channel = ADC_DR_CHANNEL(adcDataRawValue); // ADC channel for this sample/data
* bool adcDataOverrun = (bool) ((adcDataRawValue & ADC_DR_OVERRUN) != 0); // Data overrun flag
* bool adcDataValid = (bool) ((adcDataRawValue & ADC_SEQ_GDAT_DATAVALID) != 0); // Data valid flag
*/
STATIC INLINE uint32_t Chip_ADC_GetDataReg(LPC_ADC_T *pADC, uint8_t index)
{
return pADC->DR[index];
}
/**
* @brief Set Threshold low value in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param thrnum : Threshold register value (1 for threshold register 1, 0 for threshold register 0)
* @param value : Threshold low data value (should be 12-bit value)
* @return None
*/
STATIC INLINE void Chip_ADC_SetThrLowValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value)
{
pADC->THR_LOW[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS);
}
/**
* @brief Set Threshold high value in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param thrnum : Threshold register value (1 for threshold register 1, 0 for threshold register 0)
* @param value : Threshold high data value (should be 12-bit value)
* @return None
*/
STATIC INLINE void Chip_ADC_SetThrHighValue(LPC_ADC_T *pADC, uint8_t thrnum, uint16_t value)
{
pADC->THR_HIGH[thrnum] = (((uint32_t) value) << ADC_THR_VAL_POS);
}
/**
* @brief Select threshold 0 values for comparison for selected channels
* @param pADC : The base of ADC peripheral on the chip
* @param channels : An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values
* @return None
* @note Select multiple channels to use the threshold 0 comparison.<br>
* Example:<br>
* Chip_ADC_SelectTH0Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(1) | ADC_THRSEL_CHAN_SEL_THR1(2))); // Selects channels 1 and 2 for threshold 0
*/
STATIC INLINE void Chip_ADC_SelectTH0Channels(LPC_ADC_T *pADC, uint32_t channels)
{
pADC->CHAN_THRSEL = pADC->CHAN_THRSEL & ~(ADC_CHAN_THRSEL_RES | channels);
}
/**
* @brief Select threshold 1 value for comparison for selected channels
* @param pADC : The base of ADC peripheral on the chip
* @param channels : An OR'ed value of one or more ADC_THRSEL_CHAN_SEL_THR1(ch) values
* @return None
* @note Select multiple channels to use the 1 threshold comparison.<br>
* Example:<br>
* Chip_ADC_SelectTH1Channels(LPC_ADC, (ADC_THRSEL_CHAN_SEL_THR1(4) | ADC_THRSEL_CHAN_SEL_THR1(5))); // Selects channels 4 and 5 for 1 threshold
*/
STATIC INLINE void Chip_ADC_SelectTH1Channels(LPC_ADC_T *pADC, uint32_t channels)
{
pADC->CHAN_THRSEL = (pADC->CHAN_THRSEL & ~ADC_CHAN_THRSEL_RES) | channels;
}
/**
* @brief Enable interrupts in ADC (sequencers A/B and overrun)
* @param pADC : The base of ADC peripheral on the chip
* @param intMask : Interrupt values to be enabled (see notes)
* @return None
* @note Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE,
* ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to enable the
* specific ADC interrupts.
*/
STATIC INLINE void Chip_ADC_EnableInt(LPC_ADC_T *pADC, uint32_t intMask)
{
pADC->INTEN = (pADC->INTEN & ~ADC_INTEN_RES) | intMask;
}
/**
* @brief Disable interrupts in ADC (sequencers A/B and overrun)
* @param pADC : The base of ADC peripheral on the chip
* @param intMask : Interrupt values to be disabled (see notes)
* @return None
* @note Select one or more OR'ed values of ADC_INTEN_SEQA_ENABLE,
* ADC_INTEN_SEQB_ENABLE, and ADC_INTEN_OVRRUN_ENABLE to disable the
* specific ADC interrupts.
*/
STATIC INLINE void Chip_ADC_DisableInt(LPC_ADC_T *pADC, uint32_t intMask)
{
pADC->INTEN = pADC->INTEN & ~(ADC_INTEN_RES | intMask);
}
/** Threshold interrupt event options */
typedef enum {
ADC_INTEN_THCMP_DISABLE,
ADC_INTEN_THCMP_OUTSIDE,
ADC_INTEN_THCMP_CROSSING,
} ADC_INTEN_THCMP_T;
/**
* @brief Enable a threshold event interrupt in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param ch : ADC channel to set threshold inetrrupt for, 1-8
* @param thInt : Selected threshold interrupt type
* @return None
*/
STATIC INLINE void Chip_ADC_SetThresholdInt(LPC_ADC_T *pADC, uint8_t ch, ADC_INTEN_THCMP_T thInt)
{
pADC->INTEN = (pADC->INTEN & ~(ADC_INTEN_RES | (3 << (3 + (ch * 2))))) | (thInt << (3 + (ch * 2)));
}
/**
* @brief Get flags register in ADC
* @param pADC : The base of ADC peripheral on the chip
* @return Flags register value (ORed ADC_FLAG* values)
* @note Mask the return value of this function with the ADC_FLAGS_*
* definitions to determine the overall ADC interrupt events.<br>
* Example:<br>
* if (Chip_ADC_GetFlags(LPC_ADC) & ADC_FLAGS_THCMP_MASK(3) // Check of threshold comp status for ADC channel 3
*/
STATIC INLINE uint32_t Chip_ADC_GetFlags(LPC_ADC_T *pADC)
{
return pADC->FLAGS;
}
/**
* @brief Clear flags register in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param flags : An Or'ed values of ADC_FLAGS_* values to clear
* @return Flags register value (ORed ADC_FLAG* values)
*/
STATIC INLINE void Chip_ADC_ClearFlags(LPC_ADC_T *pADC, uint32_t flags)
{
pADC->FLAGS = flags;
}
/**
* @brief Set Trim register in ADC
* @param pADC : The base of ADC peripheral on the chip
* @param trim : Trim value (ADC_TRIM_VRANGE_HIGHV or ADC_TRIM_VRANGE_LOWV)
* @return None
*/
STATIC INLINE void Chip_ADC_SetTrim(LPC_ADC_T *pADC, uint32_t trim)
{
pADC->TRM = trim;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ADC_8XX_H_ */

View File

@@ -0,0 +1,250 @@
/*
* @brief LPC8xx basic chip inclusion file
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __CHIP_H_
#define __CHIP_H_
#include "lpc_types.h"
#include "sys_config.h"
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CORE_M0PLUS
#error CORE_M0PLUS is not defined for the LPC8xx architecture
#error CORE_M0PLUS should be defined as part of your compiler define list
#endif
#ifndef CHIP_LPC8XX
#error The LPC8XX Chip include path is used for this build, but
#error CHIP_LPC8XX is not defined!
#endif
/** @defgroup PERIPH_8XX_BASE CHIP: LPC8xx Peripheral addresses and register set declarations
* @ingroup CHIP_8XX_Drivers
* @{
*/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_ROM_BASE (0x1FFF0000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_WWDT_BASE (0x40000000UL)
#define LPC_MRT_BASE (0x40004000UL)
#define LPC_WKT_BASE (0x40008000UL)
#define LPC_SWM_BASE (0x4000C000UL)
#define LPC_ADC_BASE (0x4001C000UL) /* Available only on LPC82x */
#define LPC_PMU_BASE (0x40020000UL)
#define LPC_CMP_BASE (0x40024000UL)
#define LPC_DMATIRGMUX_BASE (0x40028000UL) /* Available only on LPC82x */
#define LPC_INMUX_BASE (0x4002C000UL) /* Available only on LPC82x */
#define LPC_FMC_BASE (0x40040000UL)
#define LPC_IOCON_BASE (0x40044000UL)
#define LPC_SYSCTL_BASE (0x40048000UL)
#define LPC_I2C0_BASE (0x40050000UL)
#define LPC_I2C1_BASE (0x40054000UL) /* Available only on LPC82x */
#define LPC_SPI0_BASE (0x40058000UL)
#define LPC_SPI1_BASE (0x4005C000UL)
#define LPC_USART0_BASE (0x40064000UL)
#define LPC_USART1_BASE (0x40068000UL)
#define LPC_USART2_BASE (0x4006C000UL)
#define LPC_I2C2_BASE (0x40070000UL) /* Available only on LPC82x */
#define LPC_I2C3_BASE (0x40074000UL) /* Available only on LPC82x */
/* AHB peripherals */
#define LPC_CRC_BASE (0x50000000UL)
#define LPC_SCT_BASE (0x50004000UL)
#define LPC_DMA_BASE (0x50008000UL) /* Available only on LPC82x */
#define LPC_GPIO_PORT_BASE (0xA0000000UL)
#define LPC_PIN_INT_BASE (0xA0004000UL)
#define LPC_WWDT ((LPC_WWDT_T *) LPC_WWDT_BASE)
#define LPC_SPI0 ((LPC_SPI_T *) LPC_SPI0_BASE)
#define LPC_SPI1 ((LPC_SPI_T *) LPC_SPI1_BASE)
#define LPC_USART0 ((LPC_USART_T *) LPC_USART0_BASE)
#define LPC_USART1 ((LPC_USART_T *) LPC_USART1_BASE)
#define LPC_USART2 ((LPC_USART_T *) LPC_USART2_BASE)
#define LPC_WKT ((LPC_WKT_T *) LPC_WKT_BASE)
#define LPC_PMU ((LPC_PMU_T *) LPC_PMU_BASE)
#define LPC_CRC ((LPC_CRC_T *) LPC_CRC_BASE)
#define LPC_SCT ((LPC_SCT_T *) LPC_SCT_BASE)
#define LPC_GPIO_PORT ((LPC_GPIO_T *) LPC_GPIO_PORT_BASE)
#define LPC_PININT ((LPC_PIN_INT_T *) LPC_PIN_INT_BASE)
#define LPC_IOCON ((LPC_IOCON_T *) LPC_IOCON_BASE)
#define LPC_SWM ((LPC_SWM_T *) LPC_SWM_BASE)
#define LPC_SYSCTL ((LPC_SYSCTL_T *) LPC_SYSCTL_BASE)
#define LPC_CMP ((LPC_CMP_T *) LPC_CMP_BASE)
#define LPC_FMC ((LPC_FMC_T *) LPC_FMC_BASE)
#define LPC_MRT ((LPC_MRT_T *) LPC_MRT_BASE)
#define LPC_I2C0 ((LPC_I2C_T *) LPC_I2C0_BASE)
#ifdef CHIP_LPC82X
/* Peripherals available only on LPC82x */
#define LPC_ADC ((LPC_ADC_T *) LPC_ADC_BASE)
#define LPC_I2C1 ((LPC_I2C_T *) LPC_I2C1_BASE)
#define LPC_I2C2 ((LPC_I2C_T *) LPC_I2C2_BASE)
#define LPC_I2C3 ((LPC_I2C_T *) LPC_I2C3_BASE)
#define LPC_DMA ((LPC_DMA_T *) LPC_DMA_BASE)
#define LPC_DMATRIGMUX ((LPC_DMATRIGMUX_T *) LPC_DMATIRGMUX_BASE)
#define LPC_INMUX ((LPC_INMUX_T *) LPC_INMUX_BASE)
#endif
/* Base address Alias list */
#define LPC_I2C_BASE LPC_I2C0_BASE
#define LPC_I2C LPC_I2C0
#define LPC_SYSCON LPC_SYSCTL
/* IRQ Handler alias list */
#ifdef CHIP_LPC82X
#define I2C_IRQHandler I2C0_IRQHandler
#define PININT0_IRQHandler PIN_INT0_IRQHandler
#define PININT1_IRQHandler PIN_INT1_IRQHandler
#define PININT2_IRQHandler PIN_INT2_IRQHandler
#define PININT3_IRQHandler PIN_INT3_IRQHandler
#define PININT4_IRQHandler PIN_INT4_IRQHandler
#define PININT5_IRQHandler PIN_INT5_IRQHandler
#define PININT6_IRQHandler PIN_INT6_IRQHandler
#define PININT7_IRQHandler PIN_INT7_IRQHandler
#endif
/**
* @}
*/
/** @ingroup CHIP_8XX_DRIVER_OPTIONS
* @{
*/
/**
* @brief System oscillator rate
* This value is defined externally to the chip layer and contains
* the value in Hz for the external oscillator for the board. If using the
* internal oscillator, this rate can be 0.
*/
extern const uint32_t OscRateIn;
/**
* @brief Clock rate on the CLKIN pin
* This value is defined externally to the chip layer and contains
* the value in Hz for the CLKIN pin for the board. If this pin isn't used,
* this rate can be 0.
*/
extern const uint32_t ExtRateIn;
/**
* @}
*/
/* Include order is important! */
#include "romapi_8xx.h"
#include "syscon_8xx.h"
#include "clock_8xx.h"
#include "iocon_8xx.h"
#include "swm_8xx.h"
#include "fmc_8xx.h"
#include "pinint_8xx.h"
#include "pmu_8xx.h"
#include "acmp_8xx.h"
#include "crc_8xx.h"
#include "gpio_8xx.h"
#include "mrt_8xx.h"
#include "uart_8xx.h"
#include "wkt_8xx.h"
#include "wwdt_8xx.h"
#include "sct_8xx.h"
#include "sct_pwm_8xx.h"
#include "spi_8xx.h"
#include "i2cm_8xx.h"
#include "i2cs_8xx.h"
#include "spim_8xx.h"
#include "spis_8xx.h"
#ifdef CHIP_LPC82X
#include "adc_8xx.h"
#include "dma_8xx.h"
#include "inmux_8xx.h"
#endif
/** @defgroup SUPPORT_8XX_FUNC CHIP: LPC8xx support functions
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief Current system clock rate, mainly used for sysTick
*/
extern uint32_t SystemCoreClock;
/**
* @brief Update system core clock rate, should be called if the
* system has a clock rate change
* @return None
*/
void SystemCoreClockUpdate(void);
/**
* @brief Set up and initialize hardware prior to call to main()
* @return None
* @note Chip_SystemInit() is called prior to the application and sets up
* system clocking prior to the application starting.
*/
void Chip_SystemInit(void);
/**
* @brief Clock and PLL initialization based on the external oscillator
* @return None
* @note This function assumes an external crystal oscillator
* frequency of 12MHz.
*/
void Chip_SetupXtalClocking(void);
/**
* @brief Clock and PLL initialization based on the internal oscillator
* @return None
*/
void Chip_SetupIrcClocking(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CHIP_H_ */

View File

@@ -0,0 +1,421 @@
/*
* @brief LPC8xx clock driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __CLOCK_8XX_H_
#define __CLOCK_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CLOCK_8XX CHIP: LPC8xx Clock Driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/* Internal oscillator frequency */
#define SYSCTL_IRC_FREQ (12000000)
/**
* Clock sources for system and USB PLLs
*/
typedef enum CHIP_SYSCTL_PLLCLKSRC {
SYSCTL_PLLCLKSRC_IRC = 0, /*!< Internal oscillator */
SYSCTL_PLLCLKSRC_SYSOSC, /*!< Crystal (system) oscillator */
SYSCTL_PLLCLKSRC_RESERVED,
SYSCTL_PLLCLKSRC_EXT_CLKIN, /*!< External clock input */
} CHIP_SYSCTL_PLLCLKSRC_T;
/**
* Watchdog oscillator analog output frequency selection
* values enum (plus or minus 40%)
*/
typedef enum CHIP_WDTLFO_OSC {
WDTLFO_OSC_ILLEGAL,
WDTLFO_OSC_0_60, /*!< 0.6 MHz watchdog/LFO rate */
WDTLFO_OSC_1_05, /*!< 1.05 MHz watchdog/LFO rate */
WDTLFO_OSC_1_40, /*!< 1.4 MHz watchdog/LFO rate */
WDTLFO_OSC_1_75, /*!< 1.75 MHz watchdog/LFO rate */
WDTLFO_OSC_2_10, /*!< 2.1 MHz watchdog/LFO rate */
WDTLFO_OSC_2_40, /*!< 2.4 MHz watchdog/LFO rate */
WDTLFO_OSC_2_70, /*!< 2.7 MHz watchdog/LFO rate */
WDTLFO_OSC_3_00, /*!< 3.0 MHz watchdog/LFO rate */
WDTLFO_OSC_3_25, /*!< 3.25 MHz watchdog/LFO rate */
WDTLFO_OSC_3_50, /*!< 3.5 MHz watchdog/LFO rate */
WDTLFO_OSC_3_75, /*!< 3.75 MHz watchdog/LFO rate */
WDTLFO_OSC_4_00, /*!< 4.0 MHz watchdog/LFO rate */
WDTLFO_OSC_4_20, /*!< 4.2 MHz watchdog/LFO rate */
WDTLFO_OSC_4_40, /*!< 4.4 MHz watchdog/LFO rate */
WDTLFO_OSC_4_60 /*!< 4.6 MHz watchdog/LFO rate */
} CHIP_WDTLFO_OSC_T;
/**
* Clock sources for main system clock
*/
typedef enum CHIP_SYSCTL_MAINCLKSRC {
SYSCTL_MAINCLKSRC_IRC = 0, /*!< Internal oscillator */
SYSCTL_MAINCLKSRC_PLLIN, /*!< System PLL input */
SYSCTL_MAINCLKSRC_WDTOSC, /*!< Watchdog oscillator rate */
SYSCTL_MAINCLKSRC_PLLOUT, /*!< System PLL output */
} CHIP_SYSCTL_MAINCLKSRC_T;
/**
* System and peripheral clocks enum
*/
typedef enum CHIP_SYSCTL_CLOCK {
SYSCTL_CLOCK_SYS = 0, /*!< System clock */
SYSCTL_CLOCK_ROM, /*!< ROM clock */
SYSCTL_CLOCK_RAM, /*!< RAM clock */
SYSCTL_CLOCK_FLASHREG, /*!< FLASH register interface clock */
SYSCTL_CLOCK_FLASH, /*!< FLASH array access clock */
SYSCTL_CLOCK_I2C0, /*!< I2C0 clock */
SYSCTL_CLOCK_GPIO, /*!< GPIO clock */
SYSCTL_CLOCK_SWM, /*!< Switch matrix clock */
SYSCTL_CLOCK_SCT, /*!< State configurable timer clock */
SYSCTL_CLOCK_WKT, /*!< Self wake-up timer clock */
SYSCTL_CLOCK_MRT, /*!< Multi-rate timer clock */
SYSCTL_CLOCK_SPI0, /*!< SPI0 clock */
SYSCTL_CLOCK_SPI1, /*!< SPI01 clock */
SYSCTL_CLOCK_CRC, /*!< CRC clock */
SYSCTL_CLOCK_UART0, /*!< UART0 clock */
SYSCTL_CLOCK_UART1, /*!< UART1 clock */
SYSCTL_CLOCK_UART2, /*!< UART2 clock */
SYSCTL_CLOCK_WWDT, /*!< Watchdog clock */
SYSCTL_CLOCK_IOCON, /*!< IOCON clock */
SYSCTL_CLOCK_ACOMP, /*!< Analog comparator clock */
/* LPC82x Specific Clocks */
SYSCTL_CLOCK_I2C1 = 21, /*!< I2C1 Clock */
SYSCTL_CLOCK_I2C2, /*!< I2C2 Clock */
SYSCTL_CLOCK_I2C3, /*!< I2C3 Clock */
SYSCTL_CLOCK_ADC, /*!< 12-Bit ADC Clock */
SYSCTL_CLOCK_MTB = 26, /*!< Macro Trace Buffer [USED FOR DEBUGGING] */
SYSCTL_CLOCK_DMA = 29, /*!< DMA Clock */
} CHIP_SYSCTL_CLOCK_T;
/* Clock name alias */
#define SYSCTL_CLOCK_I2C SYSCTL_CLOCK_I2C0
#define SYSCTL_CLOCK_ACMP SYSCTL_CLOCK_ACOMP
/**
* Clock sources for CLKOUT
*/
typedef enum CHIP_SYSCTL_CLKOUTSRC {
SYSCTL_CLKOUTSRC_IRC = 0, /*!< Internal oscillator for CLKOUT */
SYSCTL_CLKOUTSRC_SYSOSC, /*!< System oscillator for CLKOUT */
SYSCTL_CLKOUTSRC_WDTOSC, /*!< Watchdog oscillator for CLKOUT */
SYSCTL_CLKOUTSRC_MAINSYSCLK, /*!< Main system clock for CLKOUT */
} CHIP_SYSCTL_CLKOUTSRC_T;
/**
* @brief Set System PLL divider values
* @param msel : PLL feedback divider value
* @param psel : PLL post divider value
* @return Nothing
* @note See the user manual for how to setup the PLL
*/
STATIC INLINE void Chip_Clock_SetupSystemPLL(uint8_t msel, uint8_t psel)
{
LPC_SYSCTL->SYSPLLCTRL = (msel & 0x1F) | ((psel & 0x3) << 5);
}
/**
* @brief Read System PLL status
* @return true if the PLL is locked, false if not locked
*/
STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void)
{
return (bool) ((LPC_SYSCTL->SYSPLLSTAT & 1) != 0);
}
/**
* @brief Setup Watchdog oscillator rate and divider
* @param wdtclk : Selected watchdog clock rate
* @param div : Watchdog divider value, even value between 2 and 64
* @return Nothing
* @note Watchdog rate = selected rate divided by divider rate
*/
STATIC INLINE void Chip_Clock_SetWDTOSC(CHIP_WDTLFO_OSC_T wdtclk, uint8_t div)
{
LPC_SYSCTL->WDTOSCCTRL = (((uint32_t) wdtclk) << 5) | ((div >> 1) - 1);
}
/**
* @brief Returns the main clock source
* @return Main clock source
*/
STATIC INLINE CHIP_SYSCTL_MAINCLKSRC_T Chip_Clock_GetMainClockSource(void)
{
return (CHIP_SYSCTL_MAINCLKSRC_T) (LPC_SYSCTL->MAINCLKSEL & ~SYSCTL_MAINCLKSEL_RESERVED);
}
/**
* @brief Set system clock divider
* @param div : divider for system clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The system clock
* rate is the main system clock divided by this value.
*/
STATIC INLINE void Chip_Clock_SetSysClockDiv(uint32_t div)
{
LPC_SYSCTL->SYSAHBCLKDIV = div;
}
/**
* @brief Enable system or peripheral clock
* @param clk : Clock to enable
* @return Nothing
*/
STATIC INLINE void Chip_Clock_EnablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
{
LPC_SYSCTL->SYSAHBCLKCTRL = (1 << clk) | (LPC_SYSCTL->SYSAHBCLKCTRL & ~SYSCTL_SYSAHBCLKCTRL_RESERVED);
}
/**
* @brief Disable system or peripheral clock
* @param clk : Clock to disable
* @return Nothing
*/
STATIC INLINE void Chip_Clock_DisablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
{
LPC_SYSCTL->SYSAHBCLKCTRL &= ~((1 << clk) | SYSCTL_SYSAHBCLKCTRL_RESERVED);
}
/**
* @brief Set UART divider clock
* @param div : divider for UART clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The UART clock
* rate is the main system clock divided by this value.
*/
STATIC INLINE void Chip_Clock_SetUARTClockDiv(uint32_t div)
{
LPC_SYSCTL->UARTCLKDIV = div;
}
/**
* @brief Return UART divider
* @return divider for UART clock
* @note A value of 0 means the clock is disabled.
*/
STATIC INLINE uint32_t Chip_Clock_GetUARTClockDiv(void)
{
return LPC_SYSCTL->UARTCLKDIV & ~SYSCTL_UARTCLKDIV_RESERVED;
}
/**
* @brief Set The USART Fractional Generator Divider
* @param div : Fractional Generator Divider value, should be 0xFF
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_SetUSARTFRGDivider(uint8_t div)
{
LPC_SYSCTL->UARTFRGDIV = (uint32_t) div;
}
/**
* @brief Get The USART Fractional Generator Divider
* @return Value of USART Fractional Generator Divider
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetUSARTFRGDivider(void)
{
return LPC_SYSCTL->UARTFRGDIV & ~SYSCTL_UARTFRGDIV_RESERVED;
}
/**
* @brief Set The USART Fractional Generator Multiplier
* @param mult : An 8-bit value (0-255) U_PCLK = UARTCLKDIV/(1 + MULT/256)
* @return Nothing
*/
STATIC INLINE void Chip_SYSCTL_SetUSARTFRGMultiplier(uint8_t mult)
{
LPC_SYSCTL->UARTFRGMULT = (uint32_t) mult;
}
/**
* @brief Get The USART Fractional Generator Multiplier
* @return Value of USART Fractional Generator Multiplier
*/
STATIC INLINE uint32_t Chip_SYSCTL_GetUSARTFRGMultiplier(void)
{
return LPC_SYSCTL->UARTFRGMULT & ~SYSCTL_UARTFRGMULT_RESERVED;
}
/**
* @brief Set USART 0/1/2 UART base rate (up to main clock rate)
* @param rate : Desired rate for fractional divider/multipler output
* @param fEnable : true to use fractional clocking, false for integer clocking
* @return Actual rate generated
* @note USARTs 0 - 2 use the same base clock for their baud rate
* basis. This function is used to generate that clock, while the
* UART driver's SetBaud functions will attempt to get the closest
* baud rate from this base clock without altering it. This needs
* to be setup prior to individual UART setup.<br>
* UARTs need a base clock 16x faster than the baud rate, so if you
* need a 115.2Kbps baud rate, you will need a clock rate of at
* least (115.2K * 16). The UART base clock is generated from the
* main system clock, so fractional clocking may be the only
* possible choice when using a low main system clock frequency.
* Do not alter the FRGCLKDIV register after this call.
*/
uint32_t Chip_Clock_SetUSARTNBaseClockRate(uint32_t rate, bool fEnable);
/**
* @brief Get USART 0/1/2 UART base rate
* @return USART 0/1/2 UART base rate
*/
uint32_t Chip_Clock_GetUSARTNBaseClockRate(void);
/**
* @brief Returns the main oscillator clock rate
* @return main oscillator clock rate
*/
STATIC INLINE uint32_t Chip_Clock_GetMainOscRate(void)
{
return OscRateIn;
}
/**
* @brief Returns the internal oscillator (IRC) clock rate
* @return internal oscillator (IRC) clock rate
*/
STATIC INLINE uint32_t Chip_Clock_GetIntOscRate(void)
{
return SYSCTL_IRC_FREQ;
}
/**
* @brief Returns the external clock input rate
* @return External clock input rate
*/
STATIC INLINE uint32_t Chip_Clock_GetExtClockInRate(void)
{
return ExtRateIn;
}
/**
* @brief Set System PLL clock source
* @param src : Clock source for system PLL
* @return Nothing
* @note This function will also toggle the clock source update register
* to update the clock source
*/
void Chip_Clock_SetSystemPLLSource(CHIP_SYSCTL_PLLCLKSRC_T src);
/**
* @brief Bypass System Oscillator and set oscillator frequency range
* @param bypass : Flag to bypass oscillator
* @param highfr : Flag to set oscillator range from 15-25 MHz
* @return Nothing
* @note Sets the PLL input to bypass the oscillator. This would be
* used if an external clock that is not an oscillator is attached
* to the XTALIN pin.
*/
void Chip_Clock_SetPLLBypass(bool bypass, bool highfr);
/**
* @brief Set main system clock source
* @param src : Clock source for main system
* @return Nothing
* @note This function will also toggle the clock source update register
* to update the clock source
*/
void Chip_Clock_SetMainClockSource(CHIP_SYSCTL_MAINCLKSRC_T src);
/**
* @brief Set CLKOUT clock source and divider
* @param src : Clock source for CLKOUT
* @param div : divider for CLKOUT clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255. The CLKOUT clock
* rate is the clock source divided by the divider. This function will
* also toggle the clock source update register to update the clock
* source.
*/
void Chip_Clock_SetCLKOUTSource(CHIP_SYSCTL_CLKOUTSRC_T src, uint32_t div);
/**
* @brief Return estimated watchdog oscillator rate
* @return Estimated watchdog oscillator rate
* @note This rate is accurate to plus or minus 40%.
*/
uint32_t Chip_Clock_GetWDTOSCRate(void);
/**
* @brief Return System PLL input clock rate
* @return System PLL input clock rate
*/
uint32_t Chip_Clock_GetSystemPLLInClockRate(void);
/**
* @brief Return System PLL output clock rate
* @return System PLL output clock rate
*/
uint32_t Chip_Clock_GetSystemPLLOutClockRate(void);
/**
* @brief Return main clock rate
* @return main clock rate
*/
uint32_t Chip_Clock_GetMainClockRate(void);
/**
* @brief Return system clock rate
* @return system clock rate
*/
uint32_t Chip_Clock_GetSystemClockRate(void);
/**
* @brief Get IOCONCLKDIV clock rate
* @param reg : Divider register to get
* @return The clock rate going to the IOCON glitch filter
* @note Use 0 to disable, or a divider value of 1 to 255.
*/
uint32_t Chip_Clock_GetIOCONCLKDIVClockRate(CHIP_PIN_CLKDIV_T reg);
/**
* @brief Set IOCONCLKDIV divider
* @param reg : divider register to set
* @param div : divider value for IOCONCLKDIV[reg] clock
* @return Nothing
* @note Use 0 to disable, or a divider value of 1 to 255.
*/
void Chip_Clock_SetIOCONCLKDIV(CHIP_PIN_CLKDIV_T reg, uint8_t div);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CLOCK_8XX_H_ */

View File

@@ -0,0 +1,156 @@
/*
* @brief Basic CMSIS include file
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __CMSIS_H_
#define __CMSIS_H_
#include "lpc_types.h"
#include "sys_config.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CMSIS_8XX_ALL CHIP: LPC8xx CMSIS include file
* @ingroup CHIP_8XX_Drivers
* @{
*/
#if defined(__ARMCC_VERSION)
// Kill warning "#pragma push with no matching #pragma pop"
#pragma diag_suppress 2525
#pragma push
#pragma anon_unions
#elif defined(__CWCC__)
#pragma push
#pragma cpp_extensions on
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__IAR_SYSTEMS_ICC__)
// #pragma push // FIXME not usable for IAR
#pragma language=extended
#else
#error Not supported compiler type
#endif
#if !defined(CORE_M0PLUS)
#error Please #define CORE_M0PLUS
#endif
/** @defgroup CMSIS_8XX CHIP: LPC8xx Cortex CMSIS definitions
* @ingroup CMSIS_8XX_ALL
* @{
*/
/* Configuration of the Cortex-M0+ Processor and Core Peripherals */
#define __CM0PLUS_REV 0x0001 /*!< Cortex-M0+ Core Revision */
#define __MPU_PRESENT 0 /*!< MPU present or not */
#define __VTOR_PRESENT 1 /*!< VTOR is present in this implementation */
#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 */
/**
* @}
*/
/** @defgroup CMSIS_8XX_IRQ CHIP: LPC8xx peripheral interrupt numbers
* @ingroup CMSIS_8XX_ALL
* @{
*/
typedef enum {
/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/
Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
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 */
/****** LPC8xx Specific Interrupt Numbers ********************************************************/
SPI0_IRQn = 0, /*!< SPI0 */
SPI1_IRQn = 1, /*!< SPI1 */
Reserved0_IRQn = 2, /*!< Reserved Interrupt */
UART0_IRQn = 3, /*!< USART0 */
UART1_IRQn = 4, /*!< USART1 */
UART2_IRQn = 5, /*!< USART2 */
Reserved1_IRQn = 6, /*!< Reserved Interrupt */
I2C1_IRQn = 7, /*!< I2C1 */
I2C0_IRQn = 8, /*!< I2C0 */
I2C_IRQn = 8, /*!< Alias for I2C0 */
SCT_IRQn = 9, /*!< SCT */
MRT_IRQn = 10, /*!< MRT */
CMP_IRQn = 11, /*!< CMP */
WDT_IRQn = 12, /*!< WDT */
BOD_IRQn = 13, /*!< BOD */
FLASH_IRQn = 14, /*!< Flash interrupt */
WKT_IRQn = 15, /*!< WKT Interrupt */
ADC_SEQA_IRQn = 16, /*!< ADC sequence A completion */
ADC_SEQB_IRQn = 17, /*!< ADC sequence B completion */
ADC_THCMP_IRQn = 18, /*!< ADC threshold compare */
ADC_OVR_IRQn = 19, /*!< ADC overrun */
DMA_IRQn = 20, /*!< Reserved Interrupt */
I2C2_IRQn = 21, /*!< Reserved Interrupt */
I2C3_IRQn = 22, /*!< Reserved Interrupt */
Reserved2_IRQn = 23, /*!< Reserved Interrupt */
PININT0_IRQn = 24, /*!< External Interrupt 0 */
PIN_INT0_IRQn = 24, /*!< External Interrupt 0 (alias) */
PININT1_IRQn = 25, /*!< External Interrupt 1 */
PIN_INT1_IRQn = 25, /*!< External Interrupt 1 (alias) */
PININT2_IRQn = 26, /*!< External Interrupt 2 */
PIN_INT2_IRQn = 26, /*!< External Interrupt 2 (alias) */
PININT3_IRQn = 27, /*!< External Interrupt 3 */
PIN_INT3_IRQn = 27, /*!< External Interrupt 3 (alias) */
PININT4_IRQn = 28, /*!< External Interrupt 4 */
PIN_INT4_IRQn = 28, /*!< External Interrupt 4 (alias) */
PININT5_IRQn = 29, /*!< External Interrupt 5 */
PIN_INT5_IRQn = 29, /*!< External Interrupt 5 (alias) */
PININT6_IRQn = 30, /*!< External Interrupt 6 */
PIN_INT6_IRQn = 30, /*!< External Interrupt 6 (alias) */
PININT7_IRQn = 31, /*!< External Interrupt 7 */
PIN_INT7_IRQn = 31, /*!< External Interrupt 7 (alias) */
} IRQn_Type;
/**
* @}
*/
#include "core_cm0plus.h" /*!< Cortex-M0+ processor and core peripherals */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CMSIS_H_ */

View File

@@ -0,0 +1,793 @@
/**************************************************************************//**
* @file core_cm0plus.h
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
* @version V3.20
* @date 25. February 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2013 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 ARM 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM0PLUS_H_GENERIC
#define __CORE_CM0PLUS_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.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \ingroup Cortex-M0+
@{
*/
/* CMSIS CM0P definitions */
#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
#define __CM0PLUS_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \
__CM0PLUS_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 <stdint.h> /* standard types definitions */
#include <core_cmInstr.h> /* Core Instruction Access */
#include <core_cmFunc.h> /* Core Function Access */
#endif /* __CORE_CM0PLUS_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0PLUS_H_DEPENDANT
#define __CORE_CM0PLUS_H_DEPENDANT
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0PLUS_REV
#define __CM0PLUS_REV 0x0000
#warning "__CM0PLUS_REV not defined in device header file; using default!"
#endif
#ifndef __MPU_PRESENT
#define __MPU_PRESENT 0
#warning "__MPU_PRESENT not defined in device header file; using default!"
#endif
#ifndef __VTOR_PRESENT
#define __VTOR_PRESENT 0
#warning "__VTOR_PRESENT 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
<strong>IO Type Qualifiers</strong> 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
- Core MPU 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 */
#if (__VTOR_PRESENT == 1)
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
#else
uint32_t RESERVED0;
#endif
__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 */
#if (__VTOR_PRESENT == 1)
/* SCB Interrupt Control State Register Definitions */
#define SCB_VTOR_TBLOFF_Pos 8 /*!< SCB VTOR: TBLOFF Position */
#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
#endif
/* 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 */
#if (__MPU_PRESENT == 1)
/** \ingroup CMSIS_core_register
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
\brief Type definitions for the Memory Protection Unit (MPU)
@{
*/
/** \brief Structure type to access the Memory Protection Unit (MPU).
*/
typedef struct
{
__I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
__IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
__IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
__IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
__IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
} MPU_Type;
/* MPU Type Register */
#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */
#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */
/* MPU Control Register */
#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */
#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */
/* MPU Region Number Register */
#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */
#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */
/* MPU Region Base Address Register */
#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */
#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */
#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */
/* MPU Region Attribute and Size Register */
#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */
#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */
#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */
#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */
#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */
#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */
#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */
#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */
#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */
#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */
#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */
/*@} end of group CMSIS_MPU */
#endif
/** \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 */
#if (__MPU_PRESENT == 1)
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
#endif
/*@} */
/*******************************************************************************
* 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 <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
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_CM0PLUS_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,635 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.20
* @date 25. February 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2013 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 ARM 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
---------------------------------------------------------------------------*/
#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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#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) : "memory");
}
/** \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) : "sp");
}
/** \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) : "sp");
}
/** \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) : "memory");
}
#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) : "memory");
}
/** \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) : "memory");
}
#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;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
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)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#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 */

View File

@@ -0,0 +1,688 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.20
* @date 05. March 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2013 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 ARM 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
---------------------------------------------------------------------------*/
#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 <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \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)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \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" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (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)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#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
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \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)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
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)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
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) : "Q" (*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), "=Q" (*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), "=Q" (*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), "=Q" (*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" ::: "memory");
}
/** \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)
{
uint32_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 */

View File

@@ -0,0 +1,262 @@
/*
* @brief LPC8xx Cyclic Redundancy Check (CRC) Engine driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __CRC_8XX_H_
#define __CRC_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup CRC_8XX CHIP: LPC8xx Cyclic Redundancy Check Engine driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief CRC register block structure
*/
typedef struct { /*!< CRC Structure */
__IO uint32_t MODE; /*!< CRC Mode Register */
__IO uint32_t SEED; /*!< CRC SEED Register */
union {
__I uint32_t SUM; /*!< CRC Checksum Register. */
__O uint32_t WRDATA32; /*!< CRC Data Register: write size 32-bit*/
__O uint16_t WRDATA16; /*!< CRC Data Register: write size 16-bit*/
__O uint8_t WRDATA8; /*!< CRC Data Register: write size 8-bit*/
};
} LPC_CRC_T;
/*
* @brief CRC MODE register description
*/
#define CRC_MODE_POLY_BITMASK ((0x03)) /** CRC polynomial Bit mask */
#define CRC_MODE_POLY_CCITT (0x00) /** Select CRC-CCITT polynomial */
#define CRC_MODE_POLY_CRC16 (0x01) /** Select CRC-16 polynomial */
#define CRC_MODE_POLY_CRC32 (0x02) /** Select CRC-32 polynomial */
#define CRC_MODE_WRDATA_BITMASK (0x03 << 2) /** CRC WR_Data Config Bit mask */
#define CRC_MODE_WRDATA_BIT_RVS (1 << 2) /** Select Bit order reverse for WR_DATA (per byte) */
#define CRC_MODE_WRDATA_CMPL (1 << 3) /** Select One's complement for WR_DATA */
#define CRC_MODE_SUM_BITMASK (0x03 << 4) /** CRC Sum Config Bit mask */
#define CRC_MODE_SUM_BIT_RVS (1 << 4) /** Select Bit order reverse for CRC_SUM */
#define CRC_MODE_SUM_CMPL (1 << 5) /** Select One's complement for CRC_SUM */
#define MODE_CFG_CCITT (0x00) /** Pre-defined mode word for default CCITT setup */
#define MODE_CFG_CRC16 (0x15) /** Pre-defined mode word for default CRC16 setup */
#define MODE_CFG_CRC32 (0x36) /** Pre-defined mode word for default CRC32 setup */
#define CRC_SEED_CCITT (0x0000FFFF)/** Initial seed value for CCITT mode */
#define CRC_SEED_CRC16 (0x00000000)/** Initial seed value for CRC16 mode */
#define CRC_SEED_CRC32 (0xFFFFFFFF)/** Initial seed value for CRC32 mode */
/**
* @brief CRC polynomial
*/
typedef enum IP_CRC_001_POLY {
CRC_POLY_CCITT = CRC_MODE_POLY_CCITT, /**< CRC-CCIT polynomial */
CRC_POLY_CRC16 = CRC_MODE_POLY_CRC16, /**< CRC-16 polynomial */
CRC_POLY_CRC32 = CRC_MODE_POLY_CRC32, /**< CRC-32 polynomial */
CRC_POLY_LAST,
} CRC_POLY_T;
/**
* @brief Initializes the CRC Engine
* @return Nothing
*/
void Chip_CRC_Init(void);
/**
* @brief Deinitializes the CRC Engine
* @return Nothing
*/
void Chip_CRC_Deinit(void);
/**
* @brief Set the polynomial used for the CRC calculation
* @param poly : The enumerated polynomial to be used
* @param flags : An Or'ed value of flags that setup the mode
* @return Nothing
* @note Flags for setting up the mode word include CRC_MODE_WRDATA_BIT_RVS,
* CRC_MODE_WRDATA_CMPL, CRC_MODE_SUM_BIT_RVS, and CRC_MODE_SUM_CMPL.
*/
STATIC INLINE void Chip_CRC_SetPoly(CRC_POLY_T poly, uint32_t flags)
{
LPC_CRC->MODE = (uint32_t) poly | flags;
}
/**
* @brief Sets up the CRC engine for CRC16 mode
* @return Nothing
*/
STATIC INLINE void Chip_CRC_UseCRC16(void)
{
LPC_CRC->MODE = MODE_CFG_CRC16;
LPC_CRC->SEED = CRC_SEED_CRC16;
}
/**
* @brief Sets up the CRC engine for CRC32 mode
* @return Nothing
*/
STATIC INLINE void Chip_CRC_UseCRC32(void)
{
LPC_CRC->MODE = MODE_CFG_CRC32;
LPC_CRC->SEED = CRC_SEED_CRC32;
}
/**
* @brief Sets up the CRC engine for CCITT mode
* @return Nothing
*/
STATIC INLINE void Chip_CRC_UseCCITT(void)
{
LPC_CRC->MODE = MODE_CFG_CCITT;
LPC_CRC->SEED = CRC_SEED_CCITT;
}
/**
* @brief Engage the CRC engine with defaults based on the polynomial to be used
* @param poly : The enumerated polynomial to be used
* @return Nothing
*/
void Chip_CRC_UseDefaultConfig(CRC_POLY_T poly);
/**
* @brief Set the CRC Mode bits
* @param mode : Mode value
* @return Nothing
*/
STATIC INLINE void Chip_CRC_SetMode(uint32_t mode)
{
LPC_CRC->MODE = mode;
}
/**
* @brief Get the CRC Mode bits
* @return The current value of the CRC Mode bits
*/
STATIC INLINE uint32_t Chip_CRC_GetMode(void)
{
return LPC_CRC->MODE;
}
/**
* @brief Set the seed bits used by the CRC_SUM register
* @param seed : Seed value
* @return Nothing
*/
STATIC INLINE void Chip_CRC_SetSeed(uint32_t seed)
{
LPC_CRC->SEED = seed;
}
/**
* @brief Get the CRC seed value
* @return Seed value
*/
STATIC INLINE uint32_t Chip_CRC_GetSeed(void)
{
return LPC_CRC->SEED;
}
/**
* @brief Convenience function for writing 8-bit data to the CRC engine
* @param data : 8-bit data to write
* @return Nothing
*/
STATIC INLINE void Chip_CRC_Write8(uint8_t data)
{
LPC_CRC->WRDATA8 = data;
}
/**
* @brief Convenience function for writing 16-bit data to the CRC engine
* @param data : 16-bit data to write
* @return Nothing
*/
STATIC INLINE void Chip_CRC_Write16(uint16_t data)
{
LPC_CRC->WRDATA16 = data;
}
/**
* @brief Convenience function for writing 32-bit data to the CRC engine
* @param data : 32-bit data to write
* @return Nothing
*/
STATIC INLINE void Chip_CRC_Write32(uint32_t data)
{
LPC_CRC->WRDATA32 = data;
}
/**
* @brief Gets the CRC Sum based on the Mode and Seed as previously configured
* @return CRC Checksum value
*/
STATIC INLINE uint32_t Chip_CRC_Sum(void)
{
return LPC_CRC->SUM;
}
/**
* @brief Convenience function for computing a standard CCITT checksum from an 8-bit data block
* @param data : Pointer to the block of 8-bit data
* @param bytes : The number of bytes pointed to by data
* @return Check sum value
*/
uint32_t Chip_CRC_CRC8(const uint8_t *data, uint32_t bytes);
/**
* @brief Convenience function for computing a standard CRC16 checksum from 16-bit data block
* @param data : Pointer to the block of 16-bit data
* @param hwords : The number of 16 byte entries pointed to by data
* @return Check sum value
*/
uint32_t Chip_CRC_CRC16(const uint16_t *data, uint32_t hwords);
/**
* @brief Convenience function for computing a standard CRC32 checksum from 32-bit data block
* @param data : Pointer to the block of 32-bit data
* @param words : The number of 32-bit entries pointed to by data
* @return Check sum value
*/
uint32_t Chip_CRC_CRC32(const uint32_t *data, uint32_t words);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __CRC_8XX_H_ */

View File

@@ -0,0 +1,750 @@
/*
* @brief LPC8xx DMA chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __DMA_8XX_H_
#define __DMA_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup DMA_8XX CHIP: LPC8xx DMA Controller driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief DMA Controller shared registers structure
*/
typedef struct { /*!< DMA shared registers structure */
__IO uint32_t ENABLESET; /*!< DMA Channel Enable read and Set for all DMA channels */
__I uint32_t RESERVED0;
__O uint32_t ENABLECLR; /*!< DMA Channel Enable Clear for all DMA channels */
__I uint32_t RESERVED1;
__I uint32_t ACTIVE; /*!< DMA Channel Active status for all DMA channels */
__I uint32_t RESERVED2;
__I uint32_t BUSY; /*!< DMA Channel Busy status for all DMA channels */
__I uint32_t RESERVED3;
__IO uint32_t ERRINT; /*!< DMA Error Interrupt status for all DMA channels */
__I uint32_t RESERVED4;
__IO uint32_t INTENSET; /*!< DMA Interrupt Enable read and Set for all DMA channels */
__I uint32_t RESERVED5;
__O uint32_t INTENCLR; /*!< DMA Interrupt Enable Clear for all DMA channels */
__I uint32_t RESERVED6;
__IO uint32_t INTA; /*!< DMA Interrupt A status for all DMA channels */
__I uint32_t RESERVED7;
__IO uint32_t INTB; /*!< DMA Interrupt B status for all DMA channels */
__I uint32_t RESERVED8;
__O uint32_t SETVALID; /*!< DMA Set ValidPending control bits for all DMA channels */
__I uint32_t RESERVED9;
__O uint32_t SETTRIG; /*!< DMA Set Trigger control bits for all DMA channels */
__I uint32_t RESERVED10;
__O uint32_t ABORT; /*!< DMA Channel Abort control for all DMA channels */
} LPC_DMA_COMMON_T;
/**
* @brief DMA Controller shared registers structure
*/
typedef struct { /*!< DMA channel register structure */
__IO uint32_t CFG; /*!< DMA Configuration register */
__I uint32_t CTLSTAT; /*!< DMA Control and status register */
__IO uint32_t XFERCFG; /*!< DMA Transfer configuration register */
__I uint32_t RESERVED;
} LPC_DMA_CHANNEL_T;
/* Reserved bits masks... */
#define DMA_CFG_RESERVED ((3<<2)|(1<<7)|(3<<12)|0xfffc0000)
#define DMA_CTLSTAT_RESERVED (~(1|(1<<2)))
#define DMA_XFERCFG_RESERVED ((3<<6)|(3<<10)|(0x3fu<<26))
/* DMA channel mapping - each channel is mapped to an individual peripheral
and direction or a DMA imput mux trigger */
typedef enum {
DMAREQ_USART0_RX, /*!< USART0 receive DMA channel */
DMA_CH0 = DMAREQ_USART0_RX,
DMAREQ_USART0_TX, /*!< USART0 transmit DMA channel */
DMA_CH1 = DMAREQ_USART0_TX,
DMAREQ_USART1_RX, /*!< USART1 receive DMA channel */
DMA_CH2 = DMAREQ_USART1_RX,
DMAREQ_USART1_TX, /*!< USART1 transmit DMA channel */
DMA_CH3 = DMAREQ_USART1_TX,
DMAREQ_USART2_RX, /*!< USART2 receive DMA channel */
DMA_CH4 = DMAREQ_USART2_RX,
DMAREQ_USART2_TX, /*!< USART2 transmit DMA channel */
DMA_CH5 = DMAREQ_USART2_TX,
DMAREQ_SPI0_RX,
DMA_CH6 = DMAREQ_SPI0_RX, /*!< SPI0 receive DMA channel */
DMAREQ_SPI0_TX,
DMA_CH7 = DMAREQ_SPI0_TX, /*!< SPI0 transmit DMA channel */
DMAREQ_SPI1_RX,
DMA_CH8 = DMAREQ_SPI1_RX, /*!< SPI1 receive DMA channel */
DMAREQ_SPI1_TX,
DMA_CH9 = DMAREQ_SPI1_TX, /*!< SPI1 transmit DMA channel */
DMAREQ_I2C0_MST,
DMA_CH10 = DMAREQ_I2C0_MST, /*!< I2C0 Master DMA channel */
DMAREQ_I2C0_SLV,
DMA_CH11 = DMAREQ_I2C0_SLV, /*!< I2C0 Slave DMA channel */
DMAREQ_I2C1_MST,
DMA_CH12 = DMAREQ_I2C1_MST, /*!< I2C1 Master DMA channel */
DMAREQ_I2C1_SLV,
DMA_CH13 = DMAREQ_I2C1_SLV, /*!< I2C1 Slave DMA channel */
DMAREQ_I2C2_MST,
DMA_CH14 = DMAREQ_I2C2_MST, /*!< I2C2 Master DMA channel */
DMAREQ_I2C2_SLV,
DMA_CH15 = DMAREQ_I2C2_SLV, /*!< I2C2 Slave DMA channel */
DMAREQ_I2C3_MST,
DMA_CH16 = DMAREQ_I2C3_MST, /*!< I2C2 Master DMA channel */
DMAREQ_I2C3_SLV,
DMA_CH17 = DMAREQ_I2C3_SLV, /*!< I2C2 Slave DMA channel */
} DMA_CHID_T;
/* On LPC82x, Max DMA channel is 18 */
#define MAX_DMA_CHANNEL (DMA_CH17 + 1)
/* Reserved bits masks... */
#define DMA_COMMON_RESERVED (~(0UL) << MAX_DMA_CHANNEL)
#define DMA_ENABLESET_RESERVED DMA_COMMON_RESERVED
#define DMA_ENABLECLR_RESERVED DMA_COMMON_RESERVED
#define DMA_ACTIVE_RESERVED DMA_COMMON_RESERVED
#define DMA_BUSY_RESERVED DMA_COMMON_RESERVED
#define DMA_ERRINT_RESERVED DMA_COMMON_RESERVED
#define DMA_INTENSET_RESERVED DMA_COMMON_RESERVED
#define DMA_INTENCLR_RESERVED DMA_COMMON_RESERVED
#define DMA_INTA_RESERVED DMA_COMMON_RESERVED
#define DMA_INTB_RESERVED DMA_COMMON_RESERVED
#define DMA_SETVALID_RESERVED DMA_COMMON_RESERVED
#define DMA_SETTRIG_RESERVED DMA_COMMON_RESERVED
#define DMA_ABORT_RESERVED DMA_COMMON_RESERVED
/**
* @brief DMA Controller register block structure
*/
typedef struct { /*!< DMA Structure */
__IO uint32_t CTRL; /*!< DMA control register */
__I uint32_t INTSTAT; /*!< DMA Interrupt status register */
__IO uint32_t SRAMBASE; /*!< DMA SRAM address of the channel configuration table */
__I uint32_t RESERVED2[5];
LPC_DMA_COMMON_T DMACOMMON[1]; /*!< DMA shared channel (common) registers */
__I uint32_t RESERVED0[225];
LPC_DMA_CHANNEL_T DMACH[MAX_DMA_CHANNEL]; /*!< DMA channel registers */
} LPC_DMA_T;
/* Reserved bits masks... */
#define DMA_CTRL_RESERVED (~1)
#define DMA_INTSTAT_RESERVED (~7)
#define DMA_SRAMBASE_RESERVED (0xFF)
/** @defgroup DMA_COMMONDRV_8XX CHIP: LPC8xx DMA Controller driver common functions
* @{
*/
/**
* @brief Initialize DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_Init(LPC_DMA_T *pDMA)
{
(void) pDMA;
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_DMA);
}
/**
* @brief De-Initialize DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_DeInit(LPC_DMA_T *pDMA)
{
(void) pDMA;
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_DMA);
}
/**
* @brief Enable DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_Enable(LPC_DMA_T *pDMA)
{
pDMA->CTRL = 1;
}
/**
* @brief Disable DMA controller
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
*/
STATIC INLINE void Chip_DMA_Disable(LPC_DMA_T *pDMA)
{
pDMA->CTRL = 0;
}
/* DMA interrupt status bits (common) */
#define DMA_INTSTAT_ACTIVEINT 0x2 /*!< Summarizes whether any enabled interrupts are pending */
#define DMA_INTSTAT_ACTIVEERRINT 0x4 /*!< Summarizes whether any error interrupts are pending */
/**
* @brief Get pending interrupt or error interrupts
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of DMA_INTSTAT_* types
* @note If any DMA channels have an active interrupt or error interrupt
* pending, this functional will a common status that applies to all
* channels.
*/
STATIC INLINE uint32_t Chip_DMA_GetIntStatus(LPC_DMA_T *pDMA)
{
return (pDMA->INTSTAT & ~DMA_INTSTAT_RESERVED);
}
/* DMA channel source/address/next descriptor */
typedef struct {
uint32_t xfercfg; /*!< Transfer configuration (only used in linked lists and ping-pong configs) */
uint32_t source; /*!< DMA transfer source end address */
uint32_t dest; /*!< DMA transfer desintation end address */
uint32_t next; /*!< Link to next DMA descriptor, must be 16 byte aligned */
} DMA_CHDESC_T;
/* DMA SRAM table - this can be optionally used with the Chip_DMA_SetSRAMBase()
function if a DMA SRAM table is needed. */
extern DMA_CHDESC_T Chip_DMA_Table[MAX_DMA_CHANNEL];
/**
* @brief Set DMA controller SRAM base address
* @param pDMA : The base of DMA controller on the chip
* @param base : The base address where the DMA descriptors will be stored
* @return Nothing
* @note A 256 byte block of memory aligned on a 256 byte boundary must be
* provided for this function. It sets the base address used for
* DMA descriptor table (16 descriptors total that use 16 bytes each).<br>
*
* A pre-defined table with correct alignment can be used for this
* function by calling Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));
*/
STATIC INLINE void Chip_DMA_SetSRAMBase(LPC_DMA_T *pDMA, uint32_t base)
{
pDMA->SRAMBASE = base;
}
/**
* @brief Returns DMA controller SRAM base address
* @param pDMA : The base of DMA controller on the chip
* @return The base address where the DMA descriptors are stored
*/
STATIC INLINE uint32_t Chip_DMA_GetSRAMBase(LPC_DMA_T *pDMA)
{
return (pDMA->SRAMBASE & ~DMA_SRAMBASE_RESERVED);
}
/**
* @}
*/
/** @defgroup DMA_COMMON_8XX CHIP: LPC8xx DMA Controller driver common channel functions
* @{
*/
/**
* @brief Enables a single DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_EnableChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ENABLESET = (1 << ch);
}
/**
* @brief Disables a single DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_DisableChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ENABLECLR = (1 << ch);
}
/**
* @brief Returns all enabled DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all enabled DMA channels (0 - 15)
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) is enabled. A low state is disabled.
*/
STATIC INLINE uint32_t Chip_DMA_GetEnabledChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].ENABLESET & ~DMA_ENABLESET_RESERVED);
}
/**
* @brief Returns all active DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all active DMA channels (0 - 15)
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) is active. A low state is inactive. A active
* channel indicates that a DMA operation has been started but
* not yet fully completed.
*/
STATIC INLINE uint32_t Chip_DMA_GetActiveChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].ACTIVE & ~DMA_ACTIVE_RESERVED);
}
/**
* @brief Returns all busy DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all busy DMA channels (0 - 15)
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) is busy. A low state is not busy. A DMA
* channel is considered busy when there is any operation
* related to that channel in the DMA controller<65>s internal
* pipeline.
*/
STATIC INLINE uint32_t Chip_DMA_GetBusyChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].BUSY & ~DMA_BUSY_RESERVED);
}
/**
* @brief Returns pending error interrupt status for all DMA channels
* @param pDMA : The base of DMA controller on the chip
* @return An Or'ed value of all channels (0 - 15) error interrupt status
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has a pending error interrupt. A low state
* indicates no error interrupt.
*/
STATIC INLINE uint32_t Chip_DMA_GetErrorIntChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].ERRINT & ~DMA_ERRINT_RESERVED);
}
/**
* @brief Clears a pending error interrupt status for a single DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_ClearErrorIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ERRINT = (1 << ch);
}
/**
* @brief Enables a single DMA channel's interrupt used in common DMA interrupt
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_EnableIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTENSET = (1 << ch);
}
/**
* @brief Disables a single DMA channel's interrupt used in common DMA interrupt
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_DisableIntChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTENCLR = (1 << ch);
}
/**
* @brief Returns all enabled interrupt channels
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has an enabled interrupt for the channel.
* A low state indicates that the DMA channel will not contribute
* to the common DMA interrupt status.
*/
STATIC INLINE uint32_t Chip_DMA_GetEnableIntChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].INTENSET & ~DMA_INTENSET_RESERVED);
}
/**
* @brief Returns active A interrupt status for all channels
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has an active A interrupt for the channel.
* A low state indicates that the A interrupt is not active.
*/
STATIC INLINE uint32_t Chip_DMA_GetActiveIntAChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].INTA & ~DMA_INTA_RESERVED);
}
/**
* @brief Clears active A interrupt status for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_ClearActiveIntAChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTA = (1 << ch);
}
/**
* @brief Returns active B interrupt status for all channels
* @param pDMA : The base of DMA controller on the chip
* @return Nothing
* @note A high values in bits 0 .. 15 in the return values indicates
* that the channel for that bit (bit 0 = channel 0, bit 1 -
* channel 1, etc.) has an active B interrupt for the channel.
* A low state indicates that the B interrupt is not active.
*/
STATIC INLINE uint32_t Chip_DMA_GetActiveIntBChannels(LPC_DMA_T *pDMA)
{
return (pDMA->DMACOMMON[0].INTB & ~DMA_INTB_RESERVED);
}
/**
* @brief Clears active B interrupt status for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_ClearActiveIntBChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].INTB = (1 << ch);
}
/**
* @brief Sets the VALIDPENDING control bit for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
* @note See the User Manual for more information for what this bit does.
*
*/
STATIC INLINE void Chip_DMA_SetValidChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].SETVALID = (1 << ch);
}
/**
* @brief Sets the TRIG bit for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
* @note See the User Manual for more information for what this bit does.
*/
STATIC INLINE void Chip_DMA_SetTrigChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].SETTRIG = (1 << ch);
}
/**
* @brief Aborts a DMA operation for a single channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
* @note To abort a channel, the channel should first be disabled. Then wait
* until the channel is no longer busy by checking the corresponding
* bit in BUSY. Finally, abort the channel operation. This prevents the
* channel from restarting an incomplete operation when it is enabled
* again.
*/
STATIC INLINE void Chip_DMA_AbortChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
pDMA->DMACOMMON[0].ABORT = (1 << ch);
}
/**
* @}
*/
/** @defgroup DMA_CHANNEL_8XX CHIP: LPC8xx DMA Controller driver channel specific functions
* @{
*/
/* Support macro for DMA_CHDESC_T */
#define DMA_ADDR(addr) ((uint32_t) (addr))
/* Support definitions for setting the configuration of a DMA channel. You
will need to get more information on these options from the User manual. */
#define DMA_CFG_PERIPHREQEN (1 << 0) /*!< Enables Peripheral DMA requests */
#define DMA_CFG_HWTRIGEN (1 << 1) /*!< Use hardware triggering via imput mux */
#define DMA_CFG_TRIGPOL_LOW (0 << 4) /*!< Hardware trigger is active low or falling edge */
#define DMA_CFG_TRIGPOL_HIGH (1 << 4) /*!< Hardware trigger is active high or rising edge */
#define DMA_CFG_TRIGTYPE_EDGE (0 << 5) /*!< Hardware trigger is edge triggered */
#define DMA_CFG_TRIGTYPE_LEVEL (1 << 5) /*!< Hardware trigger is level triggered */
#define DMA_CFG_TRIGBURST_SNGL (0 << 6) /*!< Single transfer. Hardware trigger causes a single transfer */
#define DMA_CFG_TRIGBURST_BURST (1 << 6) /*!< Burst transfer (see UM) */
#define DMA_CFG_BURSTPOWER_1 (0 << 8) /*!< Set DMA burst size to 1 transfer */
#define DMA_CFG_BURSTPOWER_2 (1 << 8) /*!< Set DMA burst size to 2 transfers */
#define DMA_CFG_BURSTPOWER_4 (2 << 8) /*!< Set DMA burst size to 4 transfers */
#define DMA_CFG_BURSTPOWER_8 (3 << 8) /*!< Set DMA burst size to 8 transfers */
#define DMA_CFG_BURSTPOWER_16 (4 << 8) /*!< Set DMA burst size to 16 transfers */
#define DMA_CFG_BURSTPOWER_32 (5 << 8) /*!< Set DMA burst size to 32 transfers */
#define DMA_CFG_BURSTPOWER_64 (6 << 8) /*!< Set DMA burst size to 64 transfers */
#define DMA_CFG_BURSTPOWER_128 (7 << 8) /*!< Set DMA burst size to 128 transfers */
#define DMA_CFG_BURSTPOWER_256 (8 << 8) /*!< Set DMA burst size to 256 transfers */
#define DMA_CFG_BURSTPOWER_512 (9 << 8) /*!< Set DMA burst size to 512 transfers */
#define DMA_CFG_BURSTPOWER_1024 (10 << 8) /*!< Set DMA burst size to 1024 transfers */
#define DMA_CFG_BURSTPOWER(n) ((n) << 8) /*!< Set DMA burst size to 2^n transfers, max n=10 */
#define DMA_CFG_SRCBURSTWRAP (1 << 14) /*!< Source burst wrapping is enabled for this DMA channel */
#define DMA_CFG_DSTBURSTWRAP (1 << 15) /*!< Destination burst wrapping is enabled for this DMA channel */
#define DMA_CFG_CHPRIORITY(p) ((p) << 16) /*!< Sets DMA channel priority, min 0 (highest), max 3 (lowest) */
/**
* @brief Setup a DMA channel configuration
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param cfg : An Or'ed value of DMA_CFG_* values that define the channel's configuration
* @return Nothing
* @note This function sets up all configurable options for the DMA channel.
* These options are usually set once for a channel and then unchanged.<br>
*
* The following example show how to configure the channel for peripheral
* DMA requests, burst transfer size of 1 (in 'transfers', not bytes),
* continuous reading of the same source address, incrementing destination
* address, and highest channel priority.<br>
* Example: Chip_DMA_SetupChannelConfig(pDMA, SSP0_RX_DMA,
* (DMA_CFG_PERIPHREQEN | DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_1 |
* DMA_CFG_SRCBURSTWRAP | DMA_CFG_CHPRIORITY(0)));<br>
*
* The following example show how to configure the channel for an external
* trigger from the imput mux with low edge polarity, a burst transfer size of 8,
* incrementing source and destination addresses, and lowest channel
* priority.<br>
* Example: Chip_DMA_SetupChannelConfig(pDMA, DMA_CH14,
* (DMA_CFG_HWTRIGEN | DMA_CFG_TRIGPOL_LOW | DMA_CFG_TRIGTYPE_EDGE |
* DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_8 |
* DMA_CFG_CHPRIORITY(3)));<br>
*
* For non-peripheral DMA triggering (DMA_CFG_HWTRIGEN definition), use the
* DMA input mux functions to configure the DMA trigger source for a DMA channel.
*/
STATIC INLINE void Chip_DMA_SetupChannelConfig(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t cfg)
{
pDMA->DMACH[ch].CFG = cfg;
}
/* DMA channel control and status register definitions */
#define DMA_CTLSTAT_VALIDPENDING (1 << 0) /*!< Valid pending flag for this channel */
#define DMA_CTLSTAT_TRIG (1 << 2) /*!< Trigger flag. Indicates that the trigger for this channel is currently set */
/**
* @brief Returns channel specific status flags
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return AN Or'ed value of DMA_CTLSTAT_VALIDPENDING and DMA_CTLSTAT_TRIG
*/
STATIC INLINE uint32_t Chip_DMA_GetChannelStatus(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
return (pDMA->DMACH[ch].XFERCFG & ~DMA_XFERCFG_RESERVED);
}
/* DMA channel transfer configuration registers definitions */
#define DMA_XFERCFG_CFGVALID (1 << 0) /*!< Configuration Valid flag */
#define DMA_XFERCFG_RELOAD (1 << 1) /*!< Indicates whether the channels control structure will be reloaded when the current descriptor is exhausted */
#define DMA_XFERCFG_SWTRIG (1 << 2) /*!< Software Trigger */
#define DMA_XFERCFG_CLRTRIG (1 << 3) /*!< Clear Trigger */
#define DMA_XFERCFG_SETINTA (1 << 4) /*!< Set Interrupt flag A for this channel to fire when descriptor is complete */
#define DMA_XFERCFG_SETINTB (1 << 5) /*!< Set Interrupt flag B for this channel to fire when descriptor is complete */
#define DMA_XFERCFG_WIDTH_8 (0 << 8) /*!< 8-bit transfers are performed */
#define DMA_XFERCFG_WIDTH_16 (1 << 8) /*!< 16-bit transfers are performed */
#define DMA_XFERCFG_WIDTH_32 (2 << 8) /*!< 32-bit transfers are performed */
#define DMA_XFERCFG_SRCINC_0 (0 << 12) /*!< DMA source address is not incremented after a transfer */
#define DMA_XFERCFG_SRCINC_1 (1 << 12) /*!< DMA source address is incremented by 1 (width) after a transfer */
#define DMA_XFERCFG_SRCINC_2 (2 << 12) /*!< DMA source address is incremented by 2 (width) after a transfer */
#define DMA_XFERCFG_SRCINC_4 (3 << 12) /*!< DMA source address is incremented by 4 (width) after a transfer */
#define DMA_XFERCFG_DSTINC_0 (0 << 14) /*!< DMA destination address is not incremented after a transfer */
#define DMA_XFERCFG_DSTINC_1 (1 << 14) /*!< DMA destination address is incremented by 1 (width) after a transfer */
#define DMA_XFERCFG_DSTINC_2 (2 << 14) /*!< DMA destination address is incremented by 2 (width) after a transfer */
#define DMA_XFERCFG_DSTINC_4 (3 << 14) /*!< DMA destination address is incremented by 4 (width) after a transfer */
#define DMA_XFERCFG_XFERCOUNT(n) ((n - 1) << 16) /*!< DMA transfer count in 'transfers', between (0)1 and (1023)1024 */
/**
* @brief Setup a DMA channel transfer configuration
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param cfg : An Or'ed value of DMA_XFERCFG_* values that define the channel's transfer configuration
* @return Nothing
* @note This function sets up the transfer configuration for the DMA channel.<br>
*
* The following example show how to configure the channel's transfer for
* multiple transfer descriptors (ie, ping-pong), interrupt 'A' trigger on
* transfer descriptor completion, 128 byte size transfers, and source and
* destination address increment.<br>
* Example: Chip_DMA_SetupChannelTransfer(pDMA, SSP0_RX_DMA,
* (DMA_XFERCFG_CFGVALID | DMA_XFERCFG_RELOAD | DMA_XFERCFG_SETINTA |
* DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 | DMA_XFERCFG_DSTINC_1 |
* DMA_XFERCFG_XFERCOUNT(128)));<br>
*/
STATIC INLINE void Chip_DMA_SetupChannelTransfer(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t cfg)
{
pDMA->DMACH[ch].XFERCFG = cfg;
}
/**
* @brief Set DMA transfer register interrupt bits (safe)
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param mask : Bits to set
* @return Nothing
* @note This function safely sets bits in the DMA channel specific XFERCFG
* register.
*/
STATIC INLINE void Chip_DMA_SetTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask)
{
/* Read and write values may not be the same, write 0 to
undefined bits */
pDMA->DMACH[ch].XFERCFG = (pDMA->DMACH[ch].XFERCFG & ~DMA_XFERCFG_RESERVED) | mask;
}
/**
* @brief Clear DMA transfer register interrupt bits (safe)
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param mask : Bits to clear
* @return Nothing
* @note This function safely clears bits in the DMA channel specific XFERCFG
* register.
*/
STATIC INLINE void Chip_DMA_ClearTranBits(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t mask)
{
/* Read and write values may not be the same, write 0 to
undefined bits */
pDMA->DMACH[ch].XFERCFG &= ~(DMA_XFERCFG_RESERVED | mask);
}
/**
* @brief Update the transfer size in an existing DMA channel transfer configuration
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param trans : Number of transfers to update the transfer configuration to (1 - 1023)
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SetupChannelTransferSize(LPC_DMA_T *pDMA, DMA_CHID_T ch, uint32_t trans)
{
pDMA->DMACH[ch].XFERCFG = (pDMA->DMACH[ch].XFERCFG & ~(DMA_XFERCFG_RESERVED | (0x3FF << 16))) | DMA_XFERCFG_XFERCOUNT(trans);
}
/**
* @brief Sets a DMA channel configuration as valid
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SetChannelValid(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_CFGVALID);
}
/**
* @brief Sets a DMA channel configuration as invalid
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SetChannelInValid(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
Chip_DMA_ClearTranBits(pDMA, ch, DMA_XFERCFG_CFGVALID);
}
/**
* @brief Performs a software trigger of the DMA channel
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_DMA_SWTriggerChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
Chip_DMA_SetTranBits(pDMA, ch, DMA_XFERCFG_SWTRIG);
}
/**
* @brief Checks if the given channel is active or not
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @return 1 if channel @a ch is active; 0 if channel @a ch is not active
*/
STATIC INLINE bool Chip_DMA_IsChannelActive(LPC_DMA_T *pDMA, DMA_CHID_T ch)
{
return (pDMA->DMACOMMON[0].ACTIVE & (1 << ch)) != 0;
}
/**
* @brief Sets up a DMA channel with the passed DMA transfer descriptor
* @param pDMA : The base of DMA controller on the chip
* @param ch : DMA channel ID
* @param desc : Pointer to DMA transfer descriptor
* @return false if the DMA channel was active, otherwise true
* @note This function will set the DMA descriptor in the SRAM table to the
* the passed descriptor. This function is only meant to be used when
* the DMA channel is not active and can be used to setup the
* initial transfer for a linked list or ping-pong buffer or just a
* single transfer without a next descriptor.<br>
*
* If using this function to write the initial transfer descriptor in
* a linked list or ping-pong buffer configuration, it should contain a
* non-NULL 'next' field pointer.
*/
STATIC INLINE bool Chip_DMA_SetupTranChannel(LPC_DMA_T *pDMA, DMA_CHID_T ch, const DMA_CHDESC_T *desc)
{
/* If channel is active return false */
if (Chip_DMA_IsChannelActive(pDMA, ch))
return false;
/* Assign the descriptor to descriptor table */
((DMA_CHDESC_T *) (pDMA->SRAMBASE & ~DMA_SRAMBASE_RESERVED))[ch] = *desc;
return true;
}
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __DMA_8XX_H_ */

View File

@@ -0,0 +1,272 @@
/*
* @brief Error code returned by Boot ROM drivers/library functions
*
* This file contains unified error codes to be used across driver,
* middleware, applications, hal and demo software.
*
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __LPC_ERROR_H__
#define __LPC_ERROR_H__
/** Error code returned by Boot ROM drivers/library functions
*
* Error codes are a 32-bit value with :
* - The 16 MSB contains the peripheral code number
* - The 16 LSB contains an error code number associated to that peripheral
*
*/
typedef enum
{
/**\b 0x00000000*/ LPC_OK=0, /**< enum value returned on Success */
/**\b 0xFFFFFFFF*/ ERR_FAILED = -1, /**< enum value returned on general failure */
/**\b 0xFFFFFFFE*/ ERR_TIME_OUT = -2, /**< enum value returned on general timeout */
/**\b 0xFFFFFFFD*/ ERR_BUSY = -3, /**< enum value returned when resource is busy */
/* ISP related errors */
ERR_ISP_BASE = 0x00000000,
/*0x00000001*/ ERR_ISP_INVALID_COMMAND = ERR_ISP_BASE + 1,
/*0x00000002*/ ERR_ISP_SRC_ADDR_ERROR, /* Source address not on word boundary */
/*0x00000003*/ ERR_ISP_DST_ADDR_ERROR, /* Destination address not on word or 256 byte boundary */
/*0x00000004*/ ERR_ISP_SRC_ADDR_NOT_MAPPED,
/*0x00000005*/ ERR_ISP_DST_ADDR_NOT_MAPPED,
/*0x00000006*/ ERR_ISP_COUNT_ERROR, /* Byte count is not multiple of 4 or is not a permitted value */
/*0x00000007*/ ERR_ISP_INVALID_SECTOR,
/*0x00000008*/ ERR_ISP_SECTOR_NOT_BLANK,
/*0x00000009*/ ERR_ISP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
/*0x0000000A*/ ERR_ISP_COMPARE_ERROR,
/*0x0000000B*/ ERR_ISP_BUSY, /* Flash programming hardware interface is busy */
/*0x0000000C*/ ERR_ISP_PARAM_ERROR, /* Insufficient number of parameters */
/*0x0000000D*/ ERR_ISP_ADDR_ERROR, /* Address not on word boundary */
/*0x0000000E*/ ERR_ISP_ADDR_NOT_MAPPED,
/*0x0000000F*/ ERR_ISP_CMD_LOCKED, /* Command is locked */
/*0x00000010*/ ERR_ISP_INVALID_CODE, /* Unlock code is invalid */
/*0x00000011*/ ERR_ISP_INVALID_BAUD_RATE,
/*0x00000012*/ ERR_ISP_INVALID_STOP_BIT,
/*0x00000013*/ ERR_ISP_CODE_READ_PROTECTION_ENABLED,
/*0x00000014*/ ERR_ISP_INVALID_FLASH_UNIT,
/*0x00000015*/ ERR_ISP_USER_CODE_CHECKSUM,
/*0x00000016*/ ERR_ISP_SETTING_ACTIVE_PARTITION,
/*0x00000017*/ ERR_ISP_IRC_NO_POWER,
/*0x00000018*/ ERR_ISP_FLASH_NO_POWER,
/*0x00000019*/ ERR_ISP_EEPROM_NO_POWER,
/*0x0000001A*/ ERR_ISP_EEPROM_NO_CLOCK,
/*0x0000001B*/ ERR_ISP_FLASH_NO_CLOCK,
/*0x0000001C*/ ERR_ISP_REINVOKE_ISP_CONFIG,
/* ROM API related errors */
ERR_API_BASE = 0x00010000,
/**\b 0x00010001*/ ERR_API_INVALID_PARAMS = ERR_API_BASE + 1, /**< Invalid parameters*/
/**\b 0x00010002*/ ERR_API_INVALID_PARAM1, /**< PARAM1 is invalid */
/**\b 0x00010003*/ ERR_API_INVALID_PARAM2, /**< PARAM2 is invalid */
/**\b 0x00010004*/ ERR_API_INVALID_PARAM3, /**< PARAM3 is invalid */
/**\b 0x00010005*/ ERR_API_MOD_INIT, /**< API is called before module init */
/* SPIFI API related errors */
ERR_SPIFI_BASE = 0x00020000,
/*0x00020001*/ ERR_SPIFI_DEVICE_ERROR =ERR_SPIFI_BASE+1,
/*0x00020002*/ ERR_SPIFI_INTERNAL_ERROR,
/*0x00020003*/ ERR_SPIFI_TIMEOUT,
/*0x00020004*/ ERR_SPIFI_OPERAND_ERROR,
/*0x00020005*/ ERR_SPIFI_STATUS_PROBLEM,
/*0x00020006*/ ERR_SPIFI_UNKNOWN_EXT,
/*0x00020007*/ ERR_SPIFI_UNKNOWN_ID,
/*0x00020008*/ ERR_SPIFI_UNKNOWN_TYPE,
/*0x00020009*/ ERR_SPIFI_UNKNOWN_MFG,
/*0x0002000A*/ ERR_SPIFI_NO_DEVICE,
/*0x0002000B*/ ERR_SPIFI_ERASE_NEEDED,
SEC_AES_NO_ERROR=0,
/* Security API related errors */
ERR_SEC_AES_BASE = 0x00030000,
/*0x00030001*/ ERR_SEC_AES_WRONG_CMD=ERR_SEC_AES_BASE+1,
/*0x00030002*/ ERR_SEC_AES_NOT_SUPPORTED,
/*0x00030003*/ ERR_SEC_AES_KEY_ALREADY_PROGRAMMED,
/*0x00030004*/ ERR_SEC_AES_DMA_CHANNEL_CFG,
/*0x00030005*/ ERR_SEC_AES_DMA_MUX_CFG,
/*0x00030006*/ SEC_AES_DMA_BUSY,
/* USB device stack related errors */
ERR_USBD_BASE = 0x00040000,
/**\b 0x00040001*/ ERR_USBD_INVALID_REQ = ERR_USBD_BASE + 1, /**< invalid request */
/**\b 0x00040002*/ ERR_USBD_UNHANDLED, /**< Callback did not process the event */
/**\b 0x00040003*/ ERR_USBD_STALL, /**< Stall the endpoint on which the call back is called */
/**\b 0x00040004*/ ERR_USBD_SEND_ZLP, /**< Send ZLP packet on the endpoint on which the call back is called */
/**\b 0x00040005*/ ERR_USBD_SEND_DATA, /**< Send data packet on the endpoint on which the call back is called */
/**\b 0x00040006*/ ERR_USBD_BAD_DESC, /**< Bad descriptor*/
/**\b 0x00040007*/ ERR_USBD_BAD_CFG_DESC,/**< Bad config descriptor*/
/**\b 0x00040008*/ ERR_USBD_BAD_INTF_DESC,/**< Bad interface descriptor*/
/**\b 0x00040009*/ ERR_USBD_BAD_EP_DESC,/**< Bad endpoint descriptor*/
/**\b 0x0004000a*/ ERR_USBD_BAD_MEM_BUF, /**< Bad alignment of buffer passed. */
/**\b 0x0004000b*/ ERR_USBD_TOO_MANY_CLASS_HDLR, /**< Too many class handlers. */
/* CGU related errors */
ERR_CGU_BASE = 0x00050000,
/*0x00050001*/ ERR_CGU_NOT_IMPL=ERR_CGU_BASE+1,
/*0x00050002*/ ERR_CGU_INVALID_PARAM,
/*0x00050003*/ ERR_CGU_INVALID_SLICE,
/*0x00050004*/ ERR_CGU_OUTPUT_GEN,
/*0x00050005*/ ERR_CGU_DIV_SRC,
/*0x00050006*/ ERR_CGU_DIV_VAL,
/*0x00050007*/ ERR_CGU_SRC,
/* I2C related errors */
ERR_I2C_BASE = 0x00060000,
/*0x00060000*/ ERR_I2C_BUSY = ERR_I2C_BASE,
/*0x00060001*/ ERR_I2C_NAK,
/*0x00060002*/ ERR_I2C_BUFFER_OVERFLOW,
/*0x00060003*/ ERR_I2C_BYTE_COUNT_ERR,
/*0x00060004*/ ERR_I2C_LOSS_OF_ARBRITRATION,
/*0x00060005*/ ERR_I2C_SLAVE_NOT_ADDRESSED,
/*0x00060006*/ ERR_I2C_LOSS_OF_ARBRITRATION_NAK_BIT,
/*0x00060007*/ ERR_I2C_GENERAL_FAILURE,
/*0x00060008*/ ERR_I2C_REGS_SET_TO_DEFAULT,
/*0x00060009*/ ERR_I2C_TIMEOUT,
/*0x0006000A*/ ERR_I2C_BUFFER_UNDERFLOW,
/*0x0006000B*/ ERR_I2C_PARAM,
/* OTP related errors */
ERR_OTP_BASE = 0x00070000,
/*0x00070001*/ ERR_OTP_WR_ENABLE_INVALID = ERR_OTP_BASE+1,
/*0x00070002*/ ERR_OTP_SOME_BITS_ALREADY_PROGRAMMED,
/*0x00070003*/ ERR_OTP_ALL_DATA_OR_MASK_ZERO,
/*0x00070004*/ ERR_OTP_WRITE_ACCESS_LOCKED,
/*0x00070005*/ ERR_OTP_READ_DATA_MISMATCH,
/*0x00070006*/ ERR_OTP_USB_ID_ENABLED,
/*0x00070007*/ ERR_OTP_ETH_MAC_ENABLED,
/*0x00070008*/ ERR_OTP_AES_KEYS_ENABLED,
/*0x00070009*/ ERR_OTP_ILLEGAL_BANK,
/* UART related errors */
ERR_UART_BASE = 0x00080000,
/*0x00080001*/ ERR_UART_RXD_BUSY = ERR_UART_BASE+1, //UART rxd is busy
/*0x00080002*/ ERR_UART_TXD_BUSY, //UART txd is busy
/*0x00080003*/ ERR_UART_OVERRUN_FRAME_PARITY_NOISE, //overrun err, frame err, parity err, RxNoise err
/*0x00080004*/ ERR_UART_UNDERRUN, //underrun err
/*0x00080005*/ ERR_UART_PARAM, //parameter is error
/*0x00080006*/ ERR_UART_BAUDRATE, //baudrate setting is error
/* CAN related errors */
ERR_CAN_BASE = 0x00090000,
/*0x00090001*/ ERR_CAN_BAD_MEM_BUF = ERR_CAN_BASE+1,
/*0x00090002*/ ERR_CAN_INIT_FAIL,
/*0x00090003*/ ERR_CANOPEN_INIT_FAIL,
/* SPIFI Lite API related errors */
ERR_SPIFI_LITE_BASE = 0x000A0000,
/*0x000A0001*/ ERR_SPIFI_LITE_INVALID_ARGUMENTS = ERR_SPIFI_LITE_BASE+1,
/*0x000A0002*/ ERR_SPIFI_LITE_BUSY,
/*0x000A0003*/ ERR_SPIFI_LITE_MEMORY_MODE_ON,
/*0x000A0004*/ ERR_SPIFI_LITE_MEMORY_MODE_OFF,
/*0x000A0005*/ ERR_SPIFI_LITE_IN_DMA,
/*0x000A0006*/ ERR_SPIFI_LITE_NOT_IN_DMA,
/*0x000A0100*/ PENDING_SPIFI_LITE,
/* CLK related errors */
ERR_CLK_BASE = 0x000B0000,
/*0x000B0001*/ ERR_CLK_NOT_IMPL=ERR_CLK_BASE+1,
/*0x000B0002*/ ERR_CLK_INVALID_PARAM,
/*0x000B0003*/ ERR_CLK_INVALID_SLICE,
/*0x000B0004*/ ERR_CLK_OUTPUT_GEN,
/*0x000B0005*/ ERR_CLK_DIV_SRC,
/*0x000B0006*/ ERR_CLK_DIV_VAL,
/*0x000B0007*/ ERR_CLK_SRC,
/*0x000B0008*/ ERR_CLK_PLL_FIN_TOO_SMALL,
/*0x000B0009*/ ERR_CLK_PLL_FIN_TOO_LARGE,
/*0x000B000A*/ ERR_CLK_PLL_FOUT_TOO_SMALL,
/*0x000B000B*/ ERR_CLK_PLL_FOUT_TOO_LARGE,
/*0x000B000C*/ ERR_CLK_PLL_NO_SOLUTION,
/*0x000B000D*/ ERR_CLK_PLL_MIN_PCT,
/*0x000B000E*/ ERR_CLK_PLL_MAX_PCT,
/*0x000B000F*/ ERR_CLK_OSC_FREQ,
/*0x000B0010*/ ERR_CLK_CFG,
/*0x000B0011*/ ERR_CLK_TIMEOUT,
/*0x000B0012*/ ERR_CLK_BASE_OFF,
/*0x000B0013*/ ERR_CLK_OFF_DEADLOCK,
/*Power API*/
ERR_PWR_BASE = 0x000C0000,
/*0x000C0001*/ PWR_ERROR_ILLEGAL_MODE=ERR_PWR_BASE+1,
/*0x000C0002*/ PWR_ERROR_CLOCK_FREQ_TOO_HIGH,
/*0x000C0003*/ PWR_ERROR_INVALID_STATE,
/*0x000C0004*/ PWR_ERROR_INVALID_CFG,
/*0x000C0005*/ PWR_ERROR_PVT_DETECT,
/* DMA related errors */
ERR_DMA_BASE = 0x000D0000,
/*0x000D0001*/ ERR_DMA_ERROR_INT=ERR_DMA_BASE+1,
/*0x000D0002*/ ERR_DMA_CHANNEL_NUMBER,
/*0x000D0003*/ ERR_DMA_CHANNEL_DISABLED,
/*0x000D0004*/ ERR_DMA_BUSY,
/*0x000D0005*/ ERR_DMA_NOT_ALIGNMENT,
/*0x000D0006*/ ERR_DMA_PING_PONG_EN,
/*0x000D0007*/ ERR_DMA_CHANNEL_VALID_PENDING,
/*0x000D0008*/ ERR_DMA_PARAM,
/*0x000D0009*/ ERR_DMA_QUEUE_EMPTY,
/*0x000D000A*/ ERR_DMA_GENERAL,
/* SPI related errors */
ERR_SPI_BASE = 0x000E0000,
/*0x000E0000*/ ERR_SPI_BUSY=ERR_SPI_BASE,
/*0x000E0001*/ ERR_SPI_RXOVERRUN,
/*0x000E0002*/ ERR_SPI_TXUNDERRUN,
/*0x000E0003*/ ERR_SPI_SELNASSERT,
/*0x000E0004*/ ERR_SPI_SELNDEASSERT,
/*0x000E0005*/ ERR_SPI_CLKSTALL,
/*0x000E0006*/ ERR_SPI_PARAM,
/*0x000E0007*/ ERR_SPI_INVALID_LENGTH,
/* ADC related errors */
ERR_ADC_BASE = 0x000F0000,
/*0x000F0001*/ ERR_ADC_OVERRUN=ERR_ADC_BASE+1,
/*0x000F0002*/ ERR_ADC_INVALID_CHANNEL,
/*0x000F0003*/ ERR_ADC_INVALID_SEQUENCE,
/*0x000F0004*/ ERR_ADC_INVALID_SETUP,
/*0x000F0005*/ ERR_ADC_PARAM,
/*0x000F0006*/ ERR_ADC_INVALID_LENGTH,
/*0x000F0007*/ ERR_ADC_NO_POWER,
/* Debugger Mailbox related errors */
ERR_DM_BASE = 0x00100000,
/*0x00100001*/ ERR_DM_NOT_ENTERED=ERR_DM_BASE+1,
/*0x00100002*/ ERR_DM_UNKNOWN_CMD,
/*0x00100003*/ ERR_DM_COMM_FAIL
} ErrorCode_t;
#ifndef offsetof
#define offsetof(s, m) (int) &(((s *) 0)->m)
#endif
#define COMPILE_TIME_ASSERT(pred) switch (0) { \
case 0: \
case pred:; }
#endif /* __LPC_ERROR_H__ */

View File

@@ -0,0 +1,100 @@
/*
* @brief Error code returned by LPC8xx Boot ROM drivers/library functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __ERROR_8XX_H__
#define __ERROR_8XX_H__
/** @defgroup ROMAPI_ERRORCODES_8XX CHIP: LPC8xx ROM API error codes
* @ingroup ROMAPI_8XX
* @{
*/
/** Error code returned by Boot ROM drivers/library functions
*
* Error codes are a 32-bit value with :
* - The 16 MSB contains the peripheral code number
* - The 16 LSB contains an error code number associated to that peripheral
*
*/
typedef enum
{
/**\b 0x00000000*/ LPC_OK = 0, /**< enum value returned on Successful completion */
/**\b 0x00000001*/ LPC_ERROR, /**< enum value returned on general error (I2C) */
/* ISP related errors */
ERR_ISP_BASE = 0x00000000,
/**\b 0x00000001*/ ERR_ISP_INVALID_COMMAND = ERR_ISP_BASE + 1,
/**\b 0x00000002*/ ERR_ISP_SRC_ADDR_ERROR, /*!< Source address not on word boundary */
/**\b 0x00000003*/ ERR_ISP_DST_ADDR_ERROR, /*!< Destination address not on word or 256 byte boundary */
/**\b 0x00000004*/ ERR_ISP_SRC_ADDR_NOT_MAPPED,
/**\b 0x00000005*/ ERR_ISP_DST_ADDR_NOT_MAPPED,
/**\b 0x00000006*/ ERR_ISP_COUNT_ERROR, /*!< Byte count is not multiple of 4 or is not a permitted value */
/**\b 0x00000007*/ ERR_ISP_INVALID_SECTOR,
/**\b 0x00000008*/ ERR_ISP_SECTOR_NOT_BLANK,
/**\b 0x00000009*/ ERR_ISP_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
/**\b 0x0000000A*/ ERR_ISP_COMPARE_ERROR,
/**\b 0x0000000B*/ ERR_ISP_BUSY, /*!< Flash programming hardware interface is busy */
/**\b 0x0000000C*/ ERR_ISP_PARAM_ERROR, /*!< Insufficient number of parameters */
/**\b 0x0000000D*/ ERR_ISP_ADDR_ERROR, /*!< Address not on word boundary */
/**\b 0x0000000E*/ ERR_ISP_ADDR_NOT_MAPPED,
/**\b 0x0000000F*/ ERR_ISP_CMD_LOCKED, /*!< Command is locked */
/**\b 0x00000010*/ ERR_ISP_INVALID_CODE, /*!< Unlock code is invalid */
/**\b 0x00000011*/ ERR_ISP_INVALID_BAUD_RATE,
/**\b 0x00000012*/ ERR_ISP_INVALID_STOP_BIT,
/**\b 0x00000013*/ ERR_ISP_CODE_READ_PROTECTION_ENABLED,
/* I2C related errors */
ERR_I2C_BASE = 0x00060000,
/**\b 0x00060001*/ ERR_I2C_NAK = ERR_I2C_BASE + 1, /*!< NAK */
/**\b 0x00060002*/ ERR_I2C_BUFFER_OVERFLOW, /*!< Buffer overflow */
/**\b 0x00060003*/ ERR_I2C_BYTE_COUNT_ERR, /*!< Byte count error */
/**\b 0x00060004*/ ERR_I2C_LOSS_OF_ARBRITRATION, /*!< Loss of arbitration */
/**\b 0x00060005*/ ERR_I2C_SLAVE_NOT_ADDRESSED, /*!< Slave not addressed */
/**\b 0x00060006*/ ERR_I2C_LOSS_OF_ARBRITRATION_NAK_BIT, /*!< Loss arbritation NAK */
/**\b 0x00060007*/ ERR_I2C_GENERAL_FAILURE, /*!< General failure */
/**\b 0x00060008*/ ERR_I2C_REGS_SET_TO_DEFAULT, /*!< Set to default */
/**\b 0x00060009*/ ERR_I2C_TIMEOUT, /*!< I2C Timeout */
/* UART related errors */
/**\b 0x00080001*/ ERR_NO_ERROR = LPC_OK, /*!< Receive is busy */
ERR_UART_BASE = 0x00080000,
/**\b 0x00080001*/ ERR_UART_RXD_BUSY = ERR_UART_BASE + 1, /*!< Receive is busy */
/**\b 0x00080002*/ ERR_UART_TXD_BUSY, /*!< Transmit is busy */
/**\b 0x00080003*/ ERR_UART_OVERRUN_FRAME_PARITY_NOISE, /*!< Overrun, Frame, Parity , Receive Noise error */
/**\b 0x00080004*/ ERR_UART_UNDERRUN, /*!< Underrun */
/**\b 0x00080005*/ ERR_UART_PARAM, /*!< Parameter error */
} ErrorCode_t;
/**
* @}
*/
#endif /* __ERROR_8XX_H__ */

View File

@@ -0,0 +1,146 @@
/*
* @brief LPC8xx FLASH Memory Controller (FMC) driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __FMC_8XX_H_
#define __FMC_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup FMC_8XX CHIP: LPC8xx FLASH Memory Controller driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief FLASH Memory Controller Unit register block structure
*/
typedef struct {
__I uint32_t RESERVED1[4];
__IO uint32_t FLASHCFG; /*!< Flash Configuration register */
__I uint32_t RESERVED2[3];
__IO uint32_t FMSSTART; /*!< Signature start address register */
__IO uint32_t FMSSTOP; /*!< Signature stop address register */
__I uint32_t RESERVED3;
__I uint32_t FMSW[1]; /*!< Signature word regsiter */
} LPC_FMC_T;
/* Reserved bits masks for registers */
#define FMC_FLASHCFG_RESERVED (~3)
#define FMC_FMSSTART_RESERVED 0xfffe0000
#define FMC_FMSSTOP_RESERVED 0x7ffe0000
/**
* @brief FLASH Access time definitions
*/
typedef enum {
FLASHTIM_20MHZ_CPU = 0, /*!< Flash accesses use 1 CPU clocks. Use for up to 20 MHz CPU clock*/
FLASHTIM_30MHZ_CPU = 1, /*!< Flash accesses use 2 CPU clocks. Use for up to 30 MHz CPU clock*/
} FMC_FLASHTIM_T;
/**
* @brief Set FLASH memory access time in clocks
* @param clks : Clock cycles for FLASH access
* @return Nothing
* @note For CPU speed up to 20MHz, use a value of 0. For up to 30MHz, use
* a value of 1
*/
STATIC INLINE void Chip_FMC_SetFLASHAccess(FMC_FLASHTIM_T clks)
{
uint32_t tmp = LPC_FMC->FLASHCFG & (~((0x3)|FMC_FLASHCFG_RESERVED));
/* Don't alter upper bits */
LPC_FMC->FLASHCFG = tmp | clks;
}
/* Flash signature start and busy status bit */
#define FMC_FLASHSIG_BUSY (1UL << 31)
/**
* @brief Start computation of a signature for a FLASH memory range
* @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary
* @param stop : Ending FLASH address for computation, must be aligned on 16 byte boundary
* @return Nothing
* @note Only bits 20..4 are used for the FLASH signature computation.
* Use the Chip_FMC_IsSignatureBusy() function to determine when the
* signature computation operation is complete and the
* Chip_FMC_GetSignature() function to get the computed signature.
*/
STATIC INLINE void Chip_FMC_ComputeSignature(uint32_t start, uint32_t stop)
{
LPC_FMC->FMSSTART = (start >> 4);
LPC_FMC->FMSSTOP = (stop >> 4) | FMC_FLASHSIG_BUSY;
}
/**
* @brief Start computation of a signature for a FLASH memory address and block count
* @param start : Starting FLASH address for computation, must be aligned on 16 byte boundary
* @param blocks : Number of 16 byte blocks used for computation
* @return Nothing
* @note Only bits 20..4 are used for the FLASH signature computation.
* Use the Chip_FMC_IsSignatureBusy() function to determine when the
* signature computation operation is complete and the
* Chip_FMC_GetSignature() function to get the computed signature.
*/
STATIC INLINE void Chip_FMC_ComputeSignatureBlocks(uint32_t start, uint32_t blocks)
{
Chip_FMC_ComputeSignature(start, (start + (blocks * 16)));
}
/**
* @brief Check for signature geenration completion
* @return true if the signature computation is running, false if finished
*/
STATIC INLINE bool Chip_FMC_IsSignatureBusy(void)
{
return (bool) ((LPC_FMC->FMSSTOP & FMC_FLASHSIG_BUSY) != 0);
}
/**
* @brief Returns the generated FLASH signature value
* @param index : Signature index, must be 0
* @return the generated FLASH signature value
*/
STATIC INLINE uint32_t Chip_FMC_GetSignature(int index)
{
return LPC_FMC->FMSW[index];
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __FMC_8XX_H_ */

View File

@@ -0,0 +1,576 @@
/*
* @brief LPC8xx GPIO driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __GPIO_8XX_H_
#define __GPIO_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup GPIO_8XX CHIP: LPC8xx GPIO driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief GPIO port register block structure
*/
typedef struct { /*!< GPIO_PORT Structure */
__IO uint8_t B[128][32]; /*!< Offset 0x0000: Byte pin registers ports 0 to n; pins PIOn_0 to PIOn_31 */
__IO uint32_t W[32][32]; /*!< Offset 0x1000: Word pin registers port 0 to n */
__IO uint32_t DIR[32]; /*!< Offset 0x2000: Direction registers port n */
__IO uint32_t MASK[32]; /*!< Offset 0x2080: Mask register port n */
__IO uint32_t PIN[32]; /*!< Offset 0x2100: Portpin register port n */
__IO uint32_t MPIN[32]; /*!< Offset 0x2180: Masked port register port n */
__IO uint32_t SET[32]; /*!< Offset 0x2200: Write: Set register for port n Read: output bits for port n */
__O uint32_t CLR[32]; /*!< Offset 0x2280: Clear port n */
__O uint32_t NOT[32]; /*!< Offset 0x2300: Toggle port n */
__O uint32_t DIRSET[32]; /*!< Offset 0x2380: Set Direction */
__O uint32_t DIRCLR[32]; /*!< Offset 0x2400: Clear Direction */
__O uint32_t DIRNOT[32]; /*!< Offset 0x2480: Toggle Dirction */
} LPC_GPIO_T;
/**
* @brief Initialize GPIO block
* @param pGPIO : The base of GPIO peripheral on the chip
* @return Nothing
*/
void Chip_GPIO_Init(LPC_GPIO_T *pGPIO);
/**
* @brief De-Initialize GPIO block
* @param pGPIO : The base of GPIO peripheral on the chip
* @return Nothing
*/
void Chip_GPIO_DeInit(LPC_GPIO_T *pGPIO);
/**
* @brief Set a GPIO port/pin state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set
* @param setting : true for high, false for low
* @return Nothing
* @note It is recommended to use the Chip_GPIO_SetPinState() function instead.
*/
STATIC INLINE void Chip_GPIO_WritePortBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin, bool setting)
{
pGPIO->B[port][pin] = setting;
}
/**
* @brief Set a GPIO pin state via the GPIO byte register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set
* @param setting : true for high, false for low
* @return Nothing
* @note This function replaces Chip_GPIO_WritePortBit()
*/
STATIC INLINE void Chip_GPIO_SetPinState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool setting)
{
pGPIO->B[port][pin] = setting;
}
/**
* @brief Read a GPIO pin state via the GPIO byte register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param pin : GPIO pin to read
* @return true if the GPIO pin is high, false if low
* @note It is recommended to use the Chip_GPIO_GetPinState() function instead.
*/
STATIC INLINE bool Chip_GPIO_ReadPortBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin)
{
return (bool) pGPIO->B[port][pin];
}
/**
* @brief Get a GPIO pin state via the GPIO byte register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param pin : GPIO pin to get state for
* @return true if the GPIO is high, false if low
* @note This function replaces Chip_GPIO_ReadPortBit()
*/
STATIC INLINE bool Chip_GPIO_GetPinState(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
return (bool) pGPIO->B[port][pin];
}
/**
* @brief Set GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set
* @param setting : true for output, false for input
* @return Nothing
* @note This function is obsolete, use the Chip_GPIO_SetPinDIROutput(),
* Chip_GPIO_SetPinDIRInput() or Chip_GPIO_SetPinDIR() functions instead.
*/
STATIC INLINE void Chip_GPIO_WriteDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t pin, bool setting)
{
if (setting) {
pGPIO->DIR[port] |= 1UL << pin;
}
else {
pGPIO->DIR[port] &= ~(1UL << pin);
}
}
/**
* @brief Set GPIO direction for a single GPIO pin to an output
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set direction on as output
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_SetPinDIROutput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
#ifdef CHIP_LPC82X
pGPIO->DIRSET[port] = 1UL << pin;
#else
pGPIO->DIR[port] |= 1UL << pin;
#endif
}
/**
* @brief Set GPIO direction for a single GPIO pin to an input
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set direction on as input
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_SetPinDIRInput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
#ifdef CHIP_LPC82X
pGPIO->DIRCLR[port] = 1UL << pin;
#else
pGPIO->DIR[port] &= ~(1UL << pin);
#endif
}
/**
* @brief Toggle GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to toggle direction
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_TogglePinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
#ifdef CHIP_LPC82X
pGPIO->DIRNOT[port] = 1UL << pin;
#else
pGPIO->DIR[port] ^= 1UL << pin;
#endif
}
/**
* @brief Set GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to set (supports port 0 only)
* @param pin : GPIO pin to set direction for
* @param output : true for output, false for input
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_SetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin, bool output)
{
if (output) {
Chip_GPIO_SetPinDIROutput(pGPIO, port, pin);
}
else {
Chip_GPIO_SetPinDIRInput(pGPIO, port, pin);
}
}
/**
* @brief Read a GPIO direction (out or in)
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param bit : GPIO bit direction to read
* @return true if the GPIO is an output, false if input
* @note It is recommended to use the Chip_GPIO_GetPinDIR() function instead.
*/
STATIC INLINE bool Chip_GPIO_ReadDirBit(LPC_GPIO_T *pGPIO, uint32_t port, uint8_t bit)
{
return (bool) (((pGPIO->DIR[port]) >> bit) & 1);
}
/**
* @brief Get GPIO direction for a single GPIO pin
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : GPIO port to read (supports port 0 only)
* @param pin : GPIO pin to get direction for
* @return true if the GPIO is an output, false if input
*/
STATIC INLINE bool Chip_GPIO_GetPinDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
return Chip_GPIO_ReadDirBit(pGPIO, port, pin);
}
/**
* @brief Set Direction for a GPIO port (Obsolete)
* @param pGPIO : The base of GPIO peripheral on the chip
* @param portNum : port Number (supports port 0 only)
* @param bitValue : GPIO bit to set
* @param out : Direction value, 0 = input, !0 = output
* @return None
* @note Bits set to '0' are not altered. Obsolete function use the
* Chip_GPIO_SetPortDIR() function instead.
*/
STATIC INLINE void Chip_GPIO_SetDir(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue, uint8_t out)
{
if (out) {
pGPIO->DIR[portNum] |= bitValue;
}
else {
pGPIO->DIR[portNum] &= ~bitValue;
}
}
/**
* @brief Set GPIO direction for a all selected GPIO pins to an output
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask to set direction on as output (bits 0..b for pins 0..n)
* @return Nothing
* @note Sets multiple GPIO pins to the output direction, each bit's position that is
* high sets the corresponding pin number for that bit to an output.
*/
STATIC INLINE void Chip_GPIO_SetPortDIROutput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask)
{
#ifdef CHIP_LPC82X
pGPIO->DIRSET[port] = pinMask;
#else
pGPIO->DIR[port] |= pinMask;
#endif
}
/**
* @brief Set GPIO direction for a all selected GPIO pins to an input
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask to set direction on as input (bits 0..b for pins 0..n)
* @return Nothing
* @note Sets multiple GPIO pins to the input direction, each bit's position that is
* high sets the corresponding pin number for that bit to an input.
*/
STATIC INLINE void Chip_GPIO_SetPortDIRInput(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask)
{
#ifdef CHIP_LPC82X
pGPIO->DIRCLR[port] = pinMask;
#else
pGPIO->DIR[port] &= ~pinMask;
#endif
}
/**
* @brief Toggle GPIO direction for a all selected GPIO pins
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask Toggle direction (bits 0..n for pins 0..n)
* @return Nothing
* @note Toggles multiple GPIO pin's direction, each bit's position that is
* high toggles direction of the corresponding pin number.
*/
STATIC INLINE void Chip_GPIO_TogglePortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask)
{
#ifdef CHIP_LPC82X
pGPIO->DIRNOT[port] = pinMask;
#else
pGPIO->DIR[port] ^= pinMask;
#endif
}
/**
* @brief Set GPIO direction for a all selected GPIO pins to an input or output
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask to set direction on (bits 0..b for pins 0..n)
* @param outSet : Direction value, false = set as inputs, true = set as outputs
* @return Nothing
* @note Sets multiple GPIO pins to the input direction, each bit's position that is
* high sets the corresponding pin number for that bit to an input.
*/
STATIC INLINE void Chip_GPIO_SetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask, bool outSet)
{
if (outSet) {
Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask);
}
else {
Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask);
}
}
/**
* @brief Set GPIO direction for set of pins as output and a set of pins as input
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pinMask : GPIO pin mask to set direction on (bits 0..b for pins 0..n)
* @param outMask : GPIO IN/OUT mask to set pin n as output set bit-n (see note for more info)
* @return Nothing
* @note Sets multiple GPIO pins to the input or output, to change the direction of PIN0_1,
* PIN_05, PIN0_10 and PIN0_18, set the @a pinMask to ((1 << 1) | (1 << 5) | (1 << 10) | (1 << 18))
* to set PIN0_5 and PIN0_18 to output and PIN0_1 and PIN0_10 as input set @a outMask to
* ((1 << 5) | (1 << 18)).
*/
STATIC INLINE void Chip_GPIO_SetPortDIRMask(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pinMask, bool outMask)
{
Chip_GPIO_SetPortDIRInput(pGPIO, port, pinMask & ~outMask);
Chip_GPIO_SetPortDIROutput(pGPIO, port, pinMask & outMask);
}
/**
* @brief Get GPIO direction for a all GPIO pins
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return a bitfield containing the input and output states for each pin
* @note For pins 0..n, a high state in a bit corresponds to an output state for the
* same pin, while a low state corresponds to an input state.
*/
STATIC INLINE uint32_t Chip_GPIO_GetPortDIR(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->DIR[port];
}
/**
* @brief Set GPIO port mask value for GPIO masked read and write
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param mask : Mask value for read and write (only low bits are enabled)
* @return Nothing
* @note Controls which bits are set or unset when using the masked
* GPIO read and write functions. A low state indicates the pin is settable
* and readable via the masked write and read functions.
*/
STATIC INLINE void Chip_GPIO_SetPortMask(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t mask)
{
pGPIO->MASK[port] = mask;
}
/**
* @brief Get GPIO port mask value used for GPIO masked read and write
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return Returns value set with the Chip_GPIO_SetPortMask() function.
* @note A high bit in the return value indicates that that GPIO pin for the
* port cannot be set using the masked write function.
*/
STATIC INLINE uint32_t Chip_GPIO_GetPortMask(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->MASK[port];
}
/**
* @brief Set all GPIO raw pin states (regardless of masking)
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param value : Value to set all GPIO pin states (0..n) to
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_SetPortValue(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t value)
{
pGPIO->PIN[port] = value;
}
/**
* @brief Get all GPIO raw pin states (regardless of masking)
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return Current (raw) state of all GPIO pins
*/
STATIC INLINE uint32_t Chip_GPIO_GetPortValue(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->PIN[port];
}
/**
* @brief Set all GPIO pin states, but mask via the MASKP0 register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param value : Value to set all GPIO pin states (0..n) to
* @return Nothing
*/
STATIC INLINE void Chip_GPIO_SetMaskedPortValue(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t value)
{
pGPIO->MPIN[port] = value;
}
/**
* @brief Get all GPIO pin statesm but mask via the MASKP0 register
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @return Current (masked) state of all GPIO pins
*/
STATIC INLINE uint32_t Chip_GPIO_GetMaskedPortValue(LPC_GPIO_T *pGPIO, uint8_t port)
{
return pGPIO->MPIN[port];
}
/**
* @brief Set a GPIO port/bit to the high state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param portNum : port number (supports port 0 only)
* @param bitValue : bit(s) in the port to set high
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output. It is recommended to use the
* Chip_GPIO_SetPortOutHigh() function instead.
*/
STATIC INLINE void Chip_GPIO_SetValue(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue)
{
pGPIO->SET[portNum] = bitValue;
}
/**
* @brief Set selected GPIO output pins to the high state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pins : pins (0..n) to set high
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_SetPortOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins)
{
pGPIO->SET[port] = pins;
}
/**
* @brief Set an individual GPIO output pin to the high state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pin : pin number (0..n) to set high
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_SetPinOutHigh(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
pGPIO->SET[port] = (1 << pin);
}
/**
* @brief Set a GPIO port/bit to the low state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param portNum : port number (support port 0 only)
* @param bitValue : bit(s) in the port to set low
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output. It is recommended to use the
* Chip_GPIO_SetPortOutLow() function instead.
*/
STATIC INLINE void Chip_GPIO_ClearValue(LPC_GPIO_T *pGPIO, uint8_t portNum, uint32_t bitValue)
{
pGPIO->CLR[portNum] = bitValue;
}
/**
* @brief Set selected GPIO output pins to the low state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pins : pins (0..n) to set low
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_SetPortOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins)
{
pGPIO->CLR[port] = pins;
}
/**
* @brief Set an individual GPIO output pin to the low state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pin : pin number (0..n) to set low
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_SetPinOutLow(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
pGPIO->CLR[port] = (1 << pin);
}
/**
* @brief Toggle selected GPIO output pins to the opposite state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pins : pins (0..n) to toggle
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_SetPortToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint32_t pins)
{
pGPIO->NOT[port] = pins;
}
/**
* @brief Toggle an individual GPIO output pin to the opposite state
* @param pGPIO : The base of GPIO peripheral on the chip
* @param port : port Number (supports port 0 only)
* @param pin : pin number (0..n) to toggle
* @return None
* @note Any bit set as a '0' will not have it's state changed. This only
* applies to ports configured as an output.
*/
STATIC INLINE void Chip_GPIO_SetPinToggle(LPC_GPIO_T *pGPIO, uint8_t port, uint8_t pin)
{
pGPIO->NOT[port] = (1 << pin);
}
/**
* @brief Read current bit states for the selected port
* @param pGPIO : The base of GPIO peripheral on the chip
* @param portNum : port number to read (supports port 0 only)
* @return Current value of GPIO port
* @note The current states of the bits for the port are read, regardless of
* whether the GPIO port bits are input or output. It is recommended to use the
* Chip_GPIO_GetPortValue() function instead.
*/
STATIC INLINE uint32_t Chip_GPIO_ReadValue(LPC_GPIO_T *pGPIO, uint8_t portNum)
{
return pGPIO->PIN[portNum];
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __GPIO_8XX_H_ */

View File

@@ -0,0 +1,330 @@
/*
* @brief LPC15xx I2C driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __I2C_COMMON_8XX_H_
#define __I2C_COMMON_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup I2C_15XX CHIP: LPC15xx I2C driver
* @ingroup CHIP_15XX_Drivers
* @{
*/
/**
* @brief I2C register block structure
*/
typedef struct { /* I2C0 Structure */
__IO uint32_t CFG; /*!< I2C Configuration Register common for Master, Slave and Monitor */
__IO uint32_t STAT; /*!< I2C Status Register common for Master, Slave and Monitor */
__IO uint32_t INTENSET; /*!< I2C Interrupt Enable Set Register common for Master, Slave and Monitor */
__O uint32_t INTENCLR; /*!< I2C Interrupt Enable Clear Register common for Master, Slave and Monitor */
__IO uint32_t TIMEOUT; /*!< I2C Timeout value Register */
__IO uint32_t CLKDIV; /*!< I2C Clock Divider Register */
__I uint32_t INTSTAT; /*!< I2C Interrupt Status Register */
__I uint32_t RESERVED0;
__IO uint32_t MSTCTL; /*!< I2C Master Control Register */
__IO uint32_t MSTTIME; /*!< I2C Master Time Register for SCL */
__IO uint32_t MSTDAT; /*!< I2C Master Data Register */
__I uint32_t RESERVED1[5];
__IO uint32_t SLVCTL; /*!< I2C Slave Control Register */
__IO uint32_t SLVDAT; /*!< I2C Slave Data Register */
__IO uint32_t SLVADR[4]; /*!< I2C Slave Address Registers */
__IO uint32_t SLVQUAL0; /*!< I2C Slave Address Qualifier 0 Register */
__I uint32_t RESERVED2[9];
__I uint32_t MONRXDAT; /*!< I2C Monitor Data Register */
} LPC_I2C_T;
/* Reserved bits masks for registers */
#define I2C_CFG_RESERVED (~0x1f)
#define I2C_STAT_RESERVED ((1<<5)|(1<<7)|(0xf<<20)|(0x3fu<<26))
#define I2C_INTENSET_RESERVED ((7<<1)|(1<<5)|(1<<7)|(3<<9)|(7<<12)|(1<<18)|(0xf<<20)|(0x3fu<<26))
#define I2C_INTENCLR_RESERVED ((7<<1)|(1<<5)|(1<<7)|(3<<9)|(7<<12)|(1<<18)|(0xf<<20)|(0x3fu<<26))
#define I2C_TIMEOUT_RESERVED 0xffff0000
#define I2C_CLKDIV_RESERVED 0xffff0000
#define I2C_INTSTAT_RESERVED ((7<<1)|(1<<5)|(1<<7)|(3<<9)|(7<<12)|(1<<18)|(0xf<<20)|(0x3fu<<26))
#define I2C_MSTCTL_RESERVED (~7)
#define I2C_MSTTIME_RESERVED (~0x7f)
#define I2C_MSTDAT_RESERVED (~0xff)
#define I2C_SLVCTL_RESERVED (~3)
#define I2C_SLVDAT_RESERVED (~0xff)
#define I2C_SLVADR_RESERVED (~0xff)
#define I2C_SLVQUAL0_RESERVED (~0xff)
/*
* @brief I2C Configuration register Bit definition
*/
#define I2C_CFG_MSTEN (1 << 0) /*!< Master Enable/Disable Bit */
#define I2C_CFG_SLVEN (1 << 1) /*!< Slave Enable/Disable Bit */
#define I2C_CFG_MONEN (1 << 2) /*!< Monitor Enable/Disable Bit */
#define I2C_CFG_TIMEOUTEN (1 << 3) /*!< Timeout Enable/Disable Bit */
#define I2C_CFG_MONCLKSTR (1 << 4) /*!< Monitor Clock Stretching Bit */
#define I2C_CFG_MASK ((uint32_t) 0x1F) /*!< Configuration register Mask */
/*
* @brief I2C Status register Bit definition
*/
#define I2C_STAT_MSTPENDING (1 << 0) /*!< Master Pending Status Bit */
#define I2C_STAT_MSTSTATE (0x7 << 1) /*!< Master State Code */
#define I2C_STAT_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Bit */
#define I2C_STAT_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Bit */
#define I2C_STAT_SLVPENDING (1 << 8) /*!< Slave Pending Status Bit */
#define I2C_STAT_SLVSTATE (0x3 << 9) /*!< Slave State Code */
#define I2C_STAT_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Bit */
#define I2C_STAT_SLVIDX (0x3 << 12) /*!< Slave Address Index */
#define I2C_STAT_SLVSEL (1 << 14) /*!< Slave Selected Bit */
#define I2C_STAT_SLVDESEL (1 << 15) /*!< Slave Deselect Bit */
#define I2C_STAT_MONRDY (1 << 16) /*!< Monitor Ready Bit */
#define I2C_STAT_MONOV (1 << 17) /*!< Monitor Overflow Flag */
#define I2C_STAT_MONACTIVE (1 << 18) /*!< Monitor Active Flag */
#define I2C_STAT_MONIDLE (1 << 19) /*!< Monitor Idle Flag */
#define I2C_STAT_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Flag */
#define I2C_STAT_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Flag */
#define I2C_STAT_MSTCODE_IDLE (0) /*!< Master Idle State Code */
#define I2C_STAT_MSTCODE_RXREADY (1) /*!< Master Receive Ready State Code */
#define I2C_STAT_MSTCODE_TXREADY (2) /*!< Master Transmit Ready State Code */
#define I2C_STAT_MSTCODE_NACKADR (3) /*!< Master NACK by slave on address State Code */
#define I2C_STAT_MSTCODE_NACKDAT (4) /*!< Master NACK by slave on data State Code */
#define I2C_STAT_SLVCODE_ADDR (0) /*!< Master Idle State Code */
#define I2C_STAT_SLVCODE_RX (1) /*!< Received data is available Code */
#define I2C_STAT_SLVCODE_TX (2) /*!< Data can be transmitted Code */
/*
* @brief I2C Interrupt Enable Set register Bit definition
*/
#define I2C_INTENSET_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Enable Bit */
#define I2C_INTENSET_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Enable Bit */
#define I2C_INTENSET_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Enable Bit */
#define I2C_INTENSET_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Enable Bit */
#define I2C_INTENSET_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Enable Bit */
#define I2C_INTENSET_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Enable Bit */
#define I2C_INTENSET_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Enable Bit */
#define I2C_INTENSET_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Enable Bit */
#define I2C_INTENSET_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Enable Bit */
#define I2C_INTENSET_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Enable Bit */
#define I2C_INTENSET_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Enable Bit */
/*
* @brief I2C Interrupt Enable Clear register Bit definition
*/
#define I2C_INTENCLR_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Clear Bit */
#define I2C_INTENCLR_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Clear Bit */
#define I2C_INTENCLR_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Clear Bit */
#define I2C_INTENCLR_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Clear Bit */
#define I2C_INTENCLR_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Clear Bit */
#define I2C_INTENCLR_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Clear Bit */
#define I2C_INTENCLR_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Clear Bit */
#define I2C_INTENCLR_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Clear Bit */
#define I2C_INTENCLR_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Clear Bit */
#define I2C_INTENCLR_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Clear Bit */
#define I2C_INTENCLR_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Clear Bit */
/*
* @brief I2C TimeOut Value Macro
*/
#define I2C_TIMEOUT_VAL(n) (((uint32_t) ((n) - 1) & 0xFFF0) | 0x000F) /*!< Macro for Timeout value register */
/*
* @brief I2C Interrupt Status register Bit definition
*/
#define I2C_INTSTAT_MSTPENDING (1 << 0) /*!< Master Pending Interrupt Status Bit */
#define I2C_INTSTAT_MSTRARBLOSS (1 << 4) /*!< Master Arbitration Loss Interrupt Status Bit */
#define I2C_INTSTAT_MSTSTSTPERR (1 << 6) /*!< Master Start Stop Error Interrupt Status Bit */
#define I2C_INTSTAT_SLVPENDING (1 << 8) /*!< Slave Pending Interrupt Status Bit */
#define I2C_INTSTAT_SLVNOTSTR (1 << 11) /*!< Slave not stretching Clock Interrupt Status Bit */
#define I2C_INTSTAT_SLVDESEL (1 << 15) /*!< Slave Deselect Interrupt Status Bit */
#define I2C_INTSTAT_MONRDY (1 << 16) /*!< Monitor Ready Interrupt Status Bit */
#define I2C_INTSTAT_MONOV (1 << 17) /*!< Monitor Overflow Interrupt Status Bit */
#define I2C_INTSTAT_MONIDLE (1 << 19) /*!< Monitor Idle Interrupt Status Bit */
#define I2C_INTSTAT_EVENTTIMEOUT (1 << 24) /*!< Event Timeout Interrupt Status Bit */
#define I2C_INTSTAT_SCLTIMEOUT (1 << 25) /*!< SCL Timeout Interrupt Status Bit */
/*
* @brief I2C Master Control register Bit definition
*/
#define I2C_MSTCTL_MSTCONTINUE (1 << 0) /*!< Master Continue Bit */
#define I2C_MSTCTL_MSTSTART (1 << 1) /*!< Master Start Control Bit */
#define I2C_MSTCTL_MSTSTOP (1 << 2) /*!< Master Stop Control Bit */
#define I2C_MSTCTL_MSTDMA (1 << 3) /*!< Master DMA Enable Bit */
/*
* @brief I2C Master Time Register Field definition
*/
#define I2C_MSTTIME_MSTSCLLOW (0x07 << 0) /*!< Master SCL Low Time field */
#define I2C_MSTTIME_MSTSCLHIGH (0x07 << 4) /*!< Master SCL High Time field */
/*
* @brief I2C Master Data Mask
*/
#define I2C_MSTDAT_DATAMASK ((uint32_t) 0x00FF << 0) /*!< Master data mask */
/*
* @brief I2C Slave Control register Bit definition
*/
#define I2C_SLVCTL_SLVCONTINUE (1 << 0) /*!< Slave Continue Bit */
#define I2C_SLVCTL_SLVNACK (1 << 1) /*!< Slave NACK Bit */
#define I2C_SLVCTL_SLVDMA (1 << 3) /*!< Slave DMA Enable Bit */
/*
* @brief I2C Slave Data Mask
*/
#define I2C_SLVDAT_DATAMASK ((uint32_t) 0x00FF << 0) /*!< Slave data mask */
/*
* @brief I2C Slave Address register Bit definition
*/
#define I2C_SLVADR_SADISABLE (1 << 0) /*!< Slave Address n Disable Bit */
#define I2C_SLVADR_SLVADR (0x7F << 1) /*!< Slave Address field */
#define I2C_SLVADR_MASK ((uint32_t) 0x00FF) /*!< Slave Address Mask */
/*
* @brief I2C Slave Address Qualifier 0 Register Bit definition
*/
#define I2C_SLVQUAL_QUALMODE0 (1 << 0) /*!< Slave Qualifier Mode Enable Bit */
#define I2C_SLVQUAL_SLVQUAL0 (0x7F << 1) /*!< Slave Qualifier Address for Address 0 */
/*
* @brief I2C Monitor Data Register Bit definition
*/
#define I2C_MONRXDAT_DATA (0xFF << 0) /*!< Monitor Function Receive Data Field */
#define I2C_MONRXDAT_MONSTART (1 << 8) /*!< Monitor Received Start Bit */
#define I2C_MONRXDAT_MONRESTART (1 << 9) /*!< Monitor Received Repeated Start Bit */
#define I2C_MONRXDAT_MONNACK (1 << 10) /*!< Monitor Received Nack Bit */
/**
* @brief Initialize I2C Interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function enables the I2C clock for both the master and
* slave interfaces of the given I2C peripheral. LPC_I2C1, LPC_I2C2 and
* LPC_I2C3 are available only on LPC82X devices.
*/
void Chip_I2C_Init(LPC_I2C_T *pI2C);
/**
* @brief Shutdown I2C Interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function disables the I2C clock for both the master and
* slave interfaces of the given I2C peripheral. Only LPC_I2C0 is available
* on LPC81X devices.
*/
void Chip_I2C_DeInit(LPC_I2C_T *pI2C);
/**
* @brief Sets I2C Clock Divider registers
* @param pI2C : Pointer to selected I2C peripheral
* @param clkdiv : Clock Divider value for I2C, value is between (1 - 65536)
* @return Nothing
* @note The clock to I2C block is determined by the following formula (I2C_PCLK
* is the frequency of the system clock): <br>
* I2C Clock Frequency = (I2C_PCLK)/clkdiv;
*/
static INLINE void Chip_I2C_SetClockDiv(LPC_I2C_T *pI2C, uint32_t clkdiv)
{
if ((clkdiv >= 1) && (clkdiv <= 65536)) {
pI2C->CLKDIV = clkdiv - 1;
}
else {
pI2C->CLKDIV = 0;
}
}
/**
* @brief Get I2C Clock Divider registers
* @param pI2C : Pointer to selected I2C peripheral
* @return Clock Divider value
* @note Return the divider value for the I2C block
* It is the CLKDIV register value + 1
*/
static INLINE uint32_t Chip_I2C_GetClockDiv(LPC_I2C_T *pI2C)
{
return (pI2C->CLKDIV & 0xFFFF) + 1;
}
/**
* @brief Enable I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @param intEn : ORed Value of I2C_INTENSET_* values to enable
* @return Nothing
*/
static INLINE void Chip_I2C_EnableInt(LPC_I2C_T *pI2C, uint32_t intEn)
{
pI2C->INTENSET = intEn;
}
/**
* @brief Disable I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @param intClr : ORed Value of I2C_INTENSET_* values to disable
* @return Nothing
*/
static INLINE void Chip_I2C_DisableInt(LPC_I2C_T *pI2C, uint32_t intClr)
{
pI2C->INTENCLR = intClr;
}
/**
* @brief Disable I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @param intClr : ORed Value of I2C_INTENSET_* values to disable
* @return Nothing
* @note It is recommended to use the Chip_I2C_DisableInt() function
* instead of this function.
*/
static INLINE void Chip_I2C_ClearInt(LPC_I2C_T *pI2C, uint32_t intClr)
{
Chip_I2C_DisableInt(pI2C, intClr);
}
/**
* @brief Returns pending I2C Interrupts
* @param pI2C : Pointer to selected I2C peripheral
* @return All pending interrupts, mask with I2C_INTENSET_* to determine specific interrupts
*/
static INLINE uint32_t Chip_I2C_GetPendingInt(LPC_I2C_T *pI2C)
{
return pI2C->INTSTAT & ~I2C_INTSTAT_RESERVED;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __I2C_COMMON_8XX_H_ */

View File

@@ -0,0 +1,310 @@
/*
* @brief LPC8XX I2C driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __I2CM_8XX_H_
#define __I2CM_8XX_H_
#include "i2c_common_8xx.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup I2CM_8XX CHIP: LPC8XX I2C master-only driver
* @ingroup I2C_8XX
* This driver only works in master mode. To describe the I2C transactions
* following symbols are used in driver documentation.
*
* Key to symbols
* ==============
* S (1 bit) : Start bit
* P (1 bit) : Stop bit
* Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
* A, NA (1 bit) : Acknowledge and Not-Acknowledge bit.
* Addr (7 bits): I2C 7 bit address. Note that this can be expanded as usual to
* get a 10 bit I2C address.
* Data (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
* for 16 bit data.
* [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
* @{
*/
/** I2CM_8XX_STATUS_TYPES I2C master transfer status types
* @{
*/
#define I2CM_STATUS_OK 0x00 /*!< Requested Request was executed successfully. */
#define I2CM_STATUS_ERROR 0x01 /*!< Unknown error condition. */
#define I2CM_STATUS_NAK_ADR 0x02 /*!< No acknowledgement received from slave during address phase. */
#define I2CM_STATUS_BUS_ERROR 0x03 /*!< I2C bus error */
#define I2CM_STATUS_NAK_DAT 0x04 /*!< No acknowledgement received from slave during address phase. */
#define I2CM_STATUS_ARBLOST 0x05 /*!< Arbitration lost. */
#define I2CM_STATUS_BUSY 0xFF /*!< I2C transmistter is busy. */
/**
* @}
*/
/**
* @brief Master transfer data structure definitions
*/
typedef struct {
const uint8_t *txBuff; /*!< Pointer to array of bytes to be transmitted */
uint8_t *rxBuff; /*!< Pointer memory where bytes received from I2C be stored */
uint16_t txSz; /*!< Number of bytes in transmit array,
if 0 only receive transfer will be carried on */
uint16_t rxSz; /*!< Number of bytes to received,
if 0 only transmission we be carried on */
uint16_t status; /*!< Status of the current I2C transfer */
uint8_t slaveAddr; /*!< 7-bit I2C Slave address */
} I2CM_XFER_T;
/**
* @brief Set up bus speed for LPC_I2C controller
* @param pI2C : Pointer to selected I2C peripheral
* @param busSpeed : I2C bus clock rate
* @return Nothing
* @note Per I2C specification the busSpeed should be
* @li 100000 for Standard mode
* @li 400000 for Fast mode
* @li 1000000 for Fast mode plus
* IOCON registers corresponding to I2C pads should be updated
* according to the bus mode.
*/
void Chip_I2CM_SetBusSpeed(LPC_I2C_T *pI2C, uint32_t busSpeed);
/**
* @brief Enable I2C Master interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note
*/
static INLINE void Chip_I2CM_Enable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_MSTEN;
}
/**
* @brief Disable I2C Master interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note
*/
static INLINE void Chip_I2CM_Disable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_MSTEN;
}
/**
* @brief Get I2C Status
* @param pI2C : Pointer to selected I2C peripheral
* @return I2C Status register value
* @note This function returns the value of the status register.
*/
static INLINE uint32_t Chip_I2CM_GetStatus(LPC_I2C_T *pI2C)
{
return pI2C->STAT & ~I2C_STAT_RESERVED;
}
/**
* @brief Clear I2C status bits (master)
* @param pI2C : Pointer to selected I2C peripheral
* @param clrStatus : Status bit to clear, ORed Value of I2C_STAT_MSTRARBLOSS and I2C_STAT_MSTSTSTPERR
* @return Nothing
* @note This function clears selected status flags.
*/
static INLINE void Chip_I2CM_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus)
{
/* Clear Master Arbitration Loss and Start, Stop Error */
pI2C->STAT = clrStatus & (I2C_STAT_MSTRARBLOSS | I2C_STAT_MSTSTSTPERR);
}
/**
* @brief Check if I2C Master is pending
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the Master is pending else returns FALSE
* @note
*/
static INLINE bool Chip_I2CM_IsMasterPending(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_MSTPENDING) != 0;
}
/**
* @brief Get current state of the I2C Master
* @param pI2C : Pointer to selected I2C peripheral
* @return Master State Code, a value in the range of 0 - 4
* @note After the Master is pending this state code tells the reason
* for Master pending.
*/
static INLINE uint32_t Chip_I2CM_GetMasterState(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_MSTSTATE) >> 1;
}
/**
* @brief Transmit START or Repeat-START signal on I2C bus
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the controller to transmit START condition when
* the bus becomes free. This should be called only when master is pending.
* The function writes a complete value to Master Control register, ORing is not advised.
*/
static INLINE void Chip_I2CM_SendStart(LPC_I2C_T *pI2C)
{
pI2C->MSTCTL = I2C_MSTCTL_MSTSTART;
}
/**
* @brief Transmit STOP signal on I2C bus
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the controller to transmit STOP condition.
* This should be called only when master is pending. The function writes a
* complete value to Master Control register, ORing is not advised.
*/
static INLINE void Chip_I2CM_SendStop(LPC_I2C_T *pI2C)
{
pI2C->MSTCTL = I2C_MSTCTL_MSTSTOP;
}
/**
* @brief Master Continue transfer operation
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the master controller to continue transmission.
* This should be called only when master is pending. The function writes a
* complete value to Master Control register, ORing is not advised.
*/
static INLINE void Chip_I2CM_MasterContinue(LPC_I2C_T *pI2C)
{
pI2C->MSTCTL = I2C_MSTCTL_MSTCONTINUE;
}
/**
* @brief Transmit a single data byte through the I2C peripheral (master)
* @param pI2C : Pointer to selected I2C peripheral
* @param data : Byte to transmit
* @return Nothing
* @note This function attempts to place a byte into the I2C Master
* Data Register
*
*/
static INLINE void Chip_I2CM_WriteByte(LPC_I2C_T *pI2C, uint8_t data)
{
pI2C->MSTDAT = (uint32_t) data;
}
/**
* @brief Read a single byte data from the I2C peripheral (master)
* @param pI2C : Pointer to selected I2C peripheral
* @return A single byte of data read
* @note This function reads a byte from the I2C receive hold register
* regardless of I2C state.
*/
static INLINE uint8_t Chip_I2CM_ReadByte(LPC_I2C_T *pI2C)
{
return (uint8_t) (pI2C->MSTDAT & I2C_MSTDAT_DATAMASK);
}
/**
* @brief Transfer state change handler
* @param pI2C : Pointer to selected I2C peripheral
* @param xfer : Pointer to a I2CM_XFER_T structure see notes below
* @return Returns non-zero value on completion of transfer. The @a status
* member of @a xfer structure contains the current status of the
* transfer at the end of the call.
* @note
* The parameter @a xfer should be same as the one passed to Chip_I2CM_Xfer()
* routine. This function should be called from the I2C interrupt handler
* only when a master interrupt occurs.
*/
uint32_t Chip_I2CM_XferHandler(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
/**
* @brief Transmit and Receive data in master mode
* @param pI2C : Pointer to selected I2C peripheral
* @param xfer : Pointer to a I2CM_XFER_T structure see notes below
* @return Nothing
* @note
* The parameter @a xfer should have its member @a slaveAddr initialized
* to the 7-Bit slave address to which the master will do the xfer, Bit0
* to bit6 should have the address and Bit8 is ignored. During the transfer
* no code (like event handler) must change the content of the memory
* pointed to by @a xfer. The member of @a xfer, @a txBuff and @a txSz be
* initialized to the memory from which the I2C must pick the data to be
* transfered to slave and the number of bytes to send respectively, similarly
* @a rxBuff and @a rxSz must have pointer to memory where data received
* from slave be stored and the number of data to get from slave respectilvely.
* Following types of transfers are possible:
* - Write-only transfer: When @a rxSz member of @a xfer is set to 0.
*
* S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A] P
*
* - If I2CM_XFER_OPTION_IGNORE_NACK is set in @a options memeber
*
* S Addr Wr [A] txBuff0 [A or NA] ... txBuffN [A or NA] P
*
* - Read-only transfer: When @a txSz member of @a xfer is set to 0.
*
* S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P
*
* - If I2CM_XFER_OPTION_LAST_RX_ACK is set in @a options memeber
*
* S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] A P
*
* - Read-Write transfer: When @a rxSz and @ txSz members of @a xfer are non-zero.
*
* S Addr Wr [A] txBuff0 [A] txBuff1 [A] ... txBuffN [A]
* S Addr Rd [A] [rxBuff0] A [rxBuff1] A ... [rxBuffN] NA P
*
*/
void Chip_I2CM_Xfer(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
/**
* @brief Transmit and Receive data in master mode
* @param pI2C : Pointer to selected I2C peripheral
* @param xfer : Pointer to a I2CM_XFER_T structure see notes below
* @return Returns non-zero value on succesful completion of transfer.
* @note
* This function operates same as Chip_I2CM_Xfer(), but is a blocking call.
*/
uint32_t Chip_I2CM_XferBlocking(LPC_I2C_T *pI2C, I2CM_XFER_T *xfer);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __I2C_8XX_H_ */

View File

@@ -0,0 +1,337 @@
/*
* @brief LPC8XX I2C slave driver
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __I2CS_8XX_H_
#define __I2CS_8XX_H_
#include "i2c_common_8xx.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup I2CS_8XX CHIP: LPC8XX I2C slave-only driver
* @ingroup I2C_8XX
* This driver only works in slave mode.
* @{
*/
/** @brief I2C slave service start callback
* This callback is called from the I2C slave handler when an I2C slave address is
* received and needs servicing. It's used to indicate the start of a slave transfer
* that will happen on the slave bus.
*/
typedef void (*I2CSlaveXferStart)(uint8_t addr);
/** @brief I2C slave send data callback
* This callback is called from the I2C slave handler when an I2C slave address needs
* data to send. Return 0 to NACK the master and terminate the transfer, or return
* a non-0 value with the value to send in *data.
*/
typedef uint8_t (*I2CSlaveXferSend)(uint8_t *data);
/** @brief I2C slave receive data callback
* This callback is called from the I2C slave handler when an I2C slave address has
* receive data. Return 0 to NACK the master and terminate the transfer, or return
* a non-0 value to continue the transfer.
*/
typedef uint8_t (*I2CSlaveXferRecv)(uint8_t data);
/** @brief I2C slave service done callback
* This callback is called from the I2C slave handler when an I2C slave transfer is
* completed. It's used to indicate the end of a slave transfer.
*/
typedef void (*I2CSlaveXferDone)(void);
/**
* Slave transfer are performed using 3 callbacks. These 3 callbacks handle most I2C
* slave transfer cases. When the slave is setup and a slave interrupt is receive
* and processed with the Chip_I2CS_XferHandler() function in the I2C interrupt handler,
* one of these 3 callbacks is called. The callbacks can be used for unsized transfers
* from the master.
*
* When an address is received, the SlaveXferAddr() callback is called with the
* received address. Only addresses enabled in the slave controller will be handled.
* The slave controller can support up to 4 slave addresses.
*
* If the master is going to perform a read operation, the SlaveXferSend() callback
* is called. Place the data byte to send in *data and return a non-0 value to the
* caller, or return 0 to NACK the master. (Note the master ACKS/NACKS to slave
* on reads, so this won't necessarily stop the slave transfer.)<br>
*
* If the master performs a write operation, the SlaveXferRecv() callback is called
* with the received data. Return a non-0 value to the caller, or return 0 to NACK
* the master.<br>
*
* Once the transfer completes, the SlaveXferDone() callback will be called.<br>
*/
typedef struct {
I2CSlaveXferStart slaveStart; /*!< Called when an matching I2C slave address is received */
I2CSlaveXferSend slaveSend; /*!< Called when a byte is needed to send to master */
I2CSlaveXferRecv slaveRecv; /*!< Called when a byte is received from master */
I2CSlaveXferDone slaveDone; /*!< Called when a slave transfer is complete */
} I2CS_XFER_T;
/**
* @brief Enable I2C slave interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note Do not call this function until the slave interface is fully configured.
*/
STATIC INLINE void Chip_I2CS_Enable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) | I2C_CFG_SLVEN;
}
/**
* @brief Disable I2C slave interface
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
*/
STATIC INLINE void Chip_I2CS_Disable(LPC_I2C_T *pI2C)
{
pI2C->CFG = (pI2C->CFG & I2C_CFG_MASK) & ~I2C_CFG_SLVEN;
}
/**
* @brief Get I2C Status
* @param pI2C : Pointer to selected I2C peripheral
* @return I2C Status register value
* @note This function returns the value of the status register.
*/
STATIC INLINE uint32_t Chip_I2CS_GetStatus(LPC_I2C_T *pI2C)
{
return pI2C->STAT & ~I2C_STAT_RESERVED;
}
/**
* @brief Clear I2C status bits (slave)
* @param pI2C : Pointer to selected I2C peripheral
* @param clrStatus : Status bit to clear, must be I2C_STAT_SLVDESEL
* @return Nothing
* @note This function clears selected status flags.
*/
STATIC INLINE void Chip_I2CS_ClearStatus(LPC_I2C_T *pI2C, uint32_t clrStatus)
{
pI2C->STAT = clrStatus & I2C_STAT_SLVDESEL;
}
/**
* @brief Check if I2C slave is pending
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the slave is pending else returns FALSE
* @note
*/
STATIC INLINE bool Chip_I2CS_IsSlavePending(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVPENDING) != 0;
}
/**
* @brief Check if I2C slave is selected
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the slave is is selected, otherwise FALSE
* @note
*/
STATIC INLINE bool Chip_I2CS_IsSlaveSelected(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVSEL) != 0;
}
/**
* @brief Check if I2C slave is deselected
* @param pI2C : Pointer to selected I2C peripheral
* @return Returns TRUE if the slave is is deselected, otherwise FALSE
* @note
*/
STATIC INLINE bool Chip_I2CS_IsSlaveDeSelected(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVDESEL) != 0;
}
/**
* @brief Get current state of the I2C slave
* @param pI2C : Pointer to selected I2C peripheral
* @return slave State Code, a value of type I2C_STAT_SLVCODE_*
* @note After the slave is pending this state code tells the reason
* for slave pending.
*/
STATIC INLINE uint32_t Chip_I2CS_GetSlaveState(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVSTATE) >> 9;
}
/**
* @brief Returns the current slave address match index
* @param pI2C : Pointer to selected I2C peripheral
* @return slave match index, 0 - 3
*/
STATIC INLINE uint32_t Chip_I2CS_GetSlaveMatchIndex(LPC_I2C_T *pI2C)
{
return (pI2C->STAT & I2C_STAT_SLVIDX) >> 12;
}
/**
* @brief Slave Continue transfer operation (ACK)
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the slave controller to continue transmission.
* This should be called only when slave is pending. The function writes a
* complete value to slave Control register, ORing is not advised.
*/
STATIC INLINE void Chip_I2CS_SlaveContinue(LPC_I2C_T *pI2C)
{
pI2C->SLVCTL = I2C_SLVCTL_SLVCONTINUE;
}
/**
* @brief Slave NACK operation
* @param pI2C : Pointer to selected I2C peripheral
* @return Nothing
* @note This function sets the slave controller to NAK the master.
*/
STATIC INLINE void Chip_I2CS_SlaveNACK(LPC_I2C_T *pI2C)
{
pI2C->SLVCTL = I2C_SLVCTL_SLVNACK;
}
/**
* @brief Transmit a single data byte through the I2C peripheral (slave)
* @param pI2C : Pointer to selected I2C peripheral
* @param data : Byte to transmit
* @return Nothing
* @note This function attempts to place a byte into the I2C slave
* Data Register
*
*/
STATIC INLINE void Chip_I2CS_WriteByte(LPC_I2C_T *pI2C, uint8_t data)
{
pI2C->SLVDAT = (uint32_t) data;
}
/**
* @brief Read a single byte data from the I2C peripheral (slave)
* @param pI2C : Pointer to selected I2C peripheral
* @return A single byte of data read
* @note This function reads a byte from the I2C receive hold register
* regardless of I2C state.
*/
STATIC INLINE uint8_t Chip_I2CS_ReadByte(LPC_I2C_T *pI2C)
{
return (uint8_t) (pI2C->SLVDAT & I2C_SLVDAT_DATAMASK);
}
/**
* @brief Set a I2C slave address for slave operation
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @param slvAddr : Slave Address for the index (7-bits, bit 7 = 0)
* @return Nothing
* @note Setting a slave address also enables the slave address. Do
* not 'pre-shift' the slave address.
*/
STATIC INLINE void Chip_I2CS_SetSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum, uint8_t slvAddr)
{
pI2C->SLVADR[slvNum] = (uint32_t) (slvAddr << 1);
}
/**
* @brief Return a I2C programmed slave address
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @return Nothing
*/
STATIC INLINE uint8_t Chip_I2CS_GetSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum)
{
return (pI2C->SLVADR[slvNum] >> 1) & 0x7F;
}
/**
* @brief Enable a I2C address
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @return Nothing
*/
STATIC INLINE void Chip_I2CS_EnableSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum)
{
pI2C->SLVADR[slvNum] = (pI2C->SLVADR[slvNum] & I2C_SLVADR_MASK) & ~I2C_SLVADR_SADISABLE;
}
/**
* @brief Disable a I2C address
* @param pI2C : Pointer to selected I2C peripheral
* @param slvNum : Possible slave address number, between 0 - 3
* @return Nothing
*/
STATIC INLINE void Chip_I2CS_DisableSlaveAddr(LPC_I2C_T *pI2C, uint8_t slvNum)
{
pI2C->SLVADR[slvNum] = (pI2C->SLVADR[slvNum] & I2C_SLVADR_MASK) | I2C_SLVADR_SADISABLE;
}
/**
* @brief Setup slave qialifier address
* @param pI2C : Pointer to selected I2C peripheral
* @param extend : true to extend I2C slave detect address 0 range, or false to match to corresponding bits
* @param slvAddr : Slave address qualifier, see SLVQUAL0 register in User Manual
* @return Nothing
* @note Do not 'pre-shift' the slave address.
*/
STATIC INLINE void Chip_I2CS_SetSlaveQual0(LPC_I2C_T *pI2C, bool extend, uint8_t slvNum)
{
slvNum = slvNum << 1;
if (extend) {
slvNum |= I2C_SLVQUAL_QUALMODE0;
}
pI2C->SLVQUAL0 = slvNum;
}
/**
* @brief Slave transfer state change handler
* @param pI2C : Pointer to selected I2C peripheral
* @param xfers : Pointer to a I2CS_MULTI_XFER_T structure see notes below
* @return Returns non-zero value on completion of transfer
* @note See @ref I2CS_XFER_T for more information on this function. When using
* this function, the I2C_INTENSET_SLVPENDING and I2C_INTENSET_SLVDESEL interrupts
* should be enabled and setup in the I2C interrupt handler to call this function
* when they fire.
*/
uint32_t Chip_I2CS_XferHandler(LPC_I2C_T *pI2C, const I2CS_XFER_T *xfers);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __I2CS_8XX_H_ */

View File

@@ -0,0 +1,184 @@
/*
* @brief Common IAP support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __IAP_H_
#define __IAP_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup COMMON_IAP CHIP: Common Chip ISP/IAP commands and return codes
* @ingroup CHIP_Common
* @{
*/
/* IAP command definitions */
#define IAP_PREWRRITE_CMD 50 /*!< Prepare sector for write operation command */
#define IAP_WRISECTOR_CMD 51 /*!< Write Sector command */
#define IAP_ERSSECTOR_CMD 52 /*!< Erase Sector command */
#define IAP_BLANK_CHECK_SECTOR_CMD 53 /*!< Blank check sector */
#define IAP_REPID_CMD 54 /*!< Read PartID command */
#define IAP_READ_BOOT_CODE_CMD 55 /*!< Read Boot code version */
#define IAP_COMPARE_CMD 56 /*!< Compare two RAM address locations */
#define IAP_REINVOKE_ISP_CMD 57 /*!< Reinvoke ISP */
#define IAP_READ_UID_CMD 58 /*!< Read UID */
#define IAP_ERASE_PAGE_CMD 59 /*!< Erase page */
#define IAP_EEPROM_WRITE 61 /*!< EEPROM Write command */
#define IAP_EEPROM_READ 62 /*!< EEPROM READ command */
/* IAP response definitions */
#define IAP_CMD_SUCCESS 0 /*!< Command is executed successfully */
#define IAP_INVALID_COMMAND 1 /*!< Invalid command */
#define IAP_SRC_ADDR_ERROR 2 /*!< Source address is not on word boundary */
#define IAP_DST_ADDR_ERROR 3 /*!< Destination address is not on a correct boundary */
#define IAP_SRC_ADDR_NOT_MAPPED 4 /*!< Source address is not mapped in the memory map */
#define IAP_DST_ADDR_NOT_MAPPED 5 /*!< Destination address is not mapped in the memory map */
#define IAP_COUNT_ERROR 6 /*!< Byte count is not multiple of 4 or is not a permitted value */
#define IAP_INVALID_SECTOR 7 /*!< Sector number is invalid or end sector number is greater than start sector number */
#define IAP_SECTOR_NOT_BLANK 8 /*!< Sector is not blank */
#define IAP_SECTOR_NOT_PREPARED 9 /*!< Command to prepare sector for write operation was not executed */
#define IAP_COMPARE_ERROR 10 /*!< Source and destination data not equal */
#define IAP_BUSY 11 /*!< Flash programming hardware interface is busy */
#define IAP_PARAM_ERROR 12 /*!< nsufficient number of parameters or invalid parameter */
#define IAP_ADDR_ERROR 13 /*!< Address is not on word boundary */
#define IAP_ADDR_NOT_MAPPED 14 /*!< Address is not mapped in the memory map */
#define IAP_CMD_LOCKED 15 /*!< Command is locked */
#define IAP_INVALID_CODE 16 /*!< Unlock code is invalid */
#define IAP_INVALID_BAUD_RATE 17 /*!< Invalid baud rate setting */
#define IAP_INVALID_STOP_BIT 18 /*!< Invalid stop bit setting */
#define IAP_CRP_ENABLED 19 /*!< Code read protection enabled */
/* IAP_ENTRY API function type */
typedef void (*IAP_ENTRY_T)(unsigned int[], unsigned int[]);
/**
* @brief Prepare sector for write operation
* @param strSector : Start sector number
* @param endSector : End sector number
* @return Status code to indicate the command is executed successfully or not
* @note This command must be executed before executing "Copy RAM to flash"
* or "Erase Sector" command.
* The end sector must be greater than or equal to start sector number
*/
uint8_t Chip_IAP_PreSectorForReadWrite(uint32_t strSector, uint32_t endSector);
/**
* @brief Copy RAM to flash
* @param dstAdd : Destination flash address where data bytes are to be written
* @param srcAdd : Source flash address where data bytes are to be read
* @param byteswrt : Number of bytes to be written
* @return Status code to indicate the command is executed successfully or not
* @note The addresses should be a 256 byte boundary and the number of bytes
* should be 256 | 512 | 1024 | 4096
*/
uint8_t Chip_IAP_CopyRamToFlash(uint32_t dstAdd, uint32_t *srcAdd, uint32_t byteswrt);
/**
* @brief Erase sector
* @param strSector : Start sector number
* @param endSector : End sector number
* @return Status code to indicate the command is executed successfully or not
* @note The end sector must be greater than or equal to start sector number
*/
uint8_t Chip_IAP_EraseSector(uint32_t strSector, uint32_t endSector);
/**
* @brief Blank check a sector or multiples sector of on-chip flash memory
* @param strSector : Start sector number
* @param endSector : End sector number
* @return Offset of the first non blank word location if the status code is SECTOR_NOT_BLANK
* @note The end sector must be greater than or equal to start sector number
*/
// FIXME - There are two return value (result[0] & result[1]
// Result0:Offset of the first non blank word location if the Status Code is
// SECTOR_NOT_BLANK.
// Result1:Contents of non blank word location.
uint8_t Chip_IAP_BlankCheckSector(uint32_t strSector, uint32_t endSector);
/**
* @brief Read part identification number
* @return Part identification number
*/
uint32_t Chip_IAP_ReadPID(void);
/**
* @brief Read boot code version number
* @return Boot code version number
*/
uint8_t Chip_IAP_ReadBootCode(void);
/**
* @brief Compare the memory contents at two locations
* @param dstAdd : Destination of the RAM address of data bytes to be compared
* @param srcAdd : Source of the RAM address of data bytes to be compared
* @param bytescmp : Number of bytes to be compared
* @return Offset of the first mismatch of the status code is COMPARE_ERROR
* @note The addresses should be a word boundary and number of bytes should be
* a multiply of 4
*/
uint8_t Chip_IAP_Compare(uint32_t dstAdd, uint32_t srcAdd, uint32_t bytescmp);
/**
* @brief IAP reinvoke ISP to invoke the bootloader in ISP mode
* @return none
*/
uint8_t Chip_IAP_ReinvokeISP(void);
/**
* @brief Read the unique ID
* @return Status code to indicate the command is executed successfully or not
*/
uint32_t Chip_IAP_ReadUID(void);
/**
* @brief Erase a page or multiple papers of on-chip flash memory
* @param strPage : Start page number
* @param endPage : End page number
* @return Status code to indicate the command is executed successfully or not
* @note The page number must be greater than or equal to start page number
*/
// FIXME - There are four return value
// Result0:The first 32-bit word (at the lowest address)
// Result1:The second 32-bit word.
// Result2:The third 32-bit word.
// Result3:The fourth 32-bit word.
uint8_t Chip_IAP_ErasePage(uint32_t strPage, uint32_t endPage);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __IAP_H_ */

View File

@@ -0,0 +1,156 @@
/*
* @brief LPC8xx INPUT MUX chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2013
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __INMUX_8XX_H_
#define __INMUX_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup INMUX_8XX CHIP: LPC8xx INPUT Mux Controller driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
typedef struct {
__IO uint32_t DMA_INMUX_INMUX[2]; /*!< DMA Trigger Input 20 & 21 PINMUX 0-1 */
__O uint32_t RESERVED[6]; /*!< Reserved; Should not be used */
__IO uint32_t SCT0_INMUX[4]; /*!< Input mux register for SCT0; INPUT0-3 */
} LPC_INMUX_T;
/**
* @brief DMA INPUT MUX Index see Chip_INMUX_SetDMAOTrig()
*/
typedef enum {
DMA_INMUX_0, /*!< MUX for DMA input trigger 20 */
DMA_INMUX_1, /*!< MUX for DMA input trigger 21 */
}DMA_INMUX_T;
/**
* @brief SCT Input Mux Index; See Chip_INMUX_SetSCTInMux()
*/
typedef enum {
SCT_INMUX_0, /*!< Input mux for SCT0; INPUT 0 */
SCT_INMUX_1, /*!< Input mux for SCT0; INPUT 1 */
SCT_INMUX_2, /*!< Input mux for SCT0; INPUT 2 */
SCT_INMUX_3, /*!< Input mux for SCT0; INPUT 3 */
} SCT_INMUX_T;
/**
* @brief SCT INPUT triggers
*/
typedef enum {
SCT_INP_IN0, /*!< SCT0_IN0 selected by Pin Matrix */ /* FIXME: UM hints about changes */
SCT_INP_IN1, /*!< SCT0_IN1 selected by Pin Matrix */
SCT_INP_IN2, /*!< SCT0_IN2 selected by Pin Matrix */
SCT_INP_IN3, /*!< SCT0_IN3 selected by Pin Matrix */
SCT_INP_ADC_THCMP_IRQ, /*!< ADC Threshold compare IRQ */
SCT_INP_ACMP_O, /*!< Analog comparator output */
SCT_INP_ARM_TXEV, /*!< ARM TX Event */
SCT_INP_DEBUG_HALTED, /*!< Debug halted event */
} SCT_INP_T;
/**
* @brief Select a trigger source for a DMA channel
* @param pINMUX : The base of INPUT MUX register block
* @param imux : Index of DMA input mux
* @param ch : DMA channel ID
* @return Nothing
*/
STATIC INLINE void Chip_INMUX_SetDMAOTrig(LPC_INMUX_T *pINMUX, DMA_INMUX_T imux, DMA_CHID_T ch)
{
pINMUX->DMA_INMUX_INMUX[imux] = ch;
}
/**
* @brief Select a trigger source SCT module
* @param pINMUX : The base of INPUT MUX register block
* @param isct : Index of SCT input mux
* @param func : SCT Input function that will cause the trigger
* @return Nothing
*/
STATIC INLINE void Chip_INMUX_SetSCTInMux(LPC_INMUX_T *pINMUX, SCT_INMUX_T isct, SCT_INP_T trig)
{
pINMUX->SCT0_INMUX[isct] = trig;
}
/** @defgroup DMATRIGMUX_8XX CHIP: LPC8xx DMA trigger selection driver
* @{
*/
/**
* @brief DMA trigger pin muxing structure
*/
typedef struct { /*!< DMA trigger pin muxing register structure */
__IO uint32_t DMA_ITRIG_INMUX[MAX_DMA_CHANNEL]; /*!< Trigger input select register for DMA channels */
} LPC_DMATRIGMUX_T;
/* DMA triggers that can mapped to DMA channels */
typedef enum {
DMATRIG_ADC_SEQA_IRQ = 0, /*!< ADC0 sequencer A interrupt as trigger */
DMATRIG_ADC_SEQB_IRQ, /*!< ADC0 sequencer B interrupt as trigger */
DMATRIG_SCT0_DMA0, /*!< SCT 0, DMA 0 as trigger */
DMATRIG_SCT0_DMA1, /*!< SCT 1, DMA 1 as trigger */
DMATRIG_ACMP_O, /*!< Analog comparator output */
DMATRIG_PINT0, /*!< Pin interrupt 0 as trigger */
DMATRIG_PINT1, /*!< Pin interrupt 1 as trigger */
DMATRIG_DMA_INMUX0, /*!< DMA Trigger MUX0 */
DMATRIG_DMA_INMUX1, /*!< DMA Trigger MUX1 */
} DMA_TRIGSRC_T;
/**
* @brief Select a trigger source for a DMA channel
* @param pDMATRIG : The base of DMA trigger setup block on the chip
* @param ch : DMA channel ID
* @param trig : Trigger source for the DMA channel
* @return Nothing
* @note A DMA trigger source only needs to be setup when the DMA is setup
* for hardware trigger mode (when Chip_DMA_SetupChannelConfig() is
* called with DMA_CFG_HWTRIGEN as OR'ed option).
*/
STATIC INLINE void Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX_T *pDMATRIG, DMA_CHID_T ch, DMA_TRIGSRC_T trig)
{
pDMATRIG->DMA_ITRIG_INMUX[ch] = (uint32_t) trig;
}
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __INMUX_8XX_H_ */

View File

@@ -0,0 +1,337 @@
/*
* @brief LPC8xx IOCON register block and driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __IOCON_8XX_H_
#define __IOCON_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup IOCON_8XX CHIP: LPC8xx IOCON register block and driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
#define NUM_IOCON_PIO (29)
/**
* @brief Array of IOCON pin definitions passed to Chip_IOCON_SetPinMuxing() must be in this format
*/
typedef struct {
uint32_t pin:8; /* Pin number */
uint32_t modefunc:24; /* Function and mode */
} PINMUX_GRP_T;
/**
* @brief IOCON register block structure
* @note When accessing this register structure, use the PIOn enumeration
* as the array index as the pin assignments are not mapped 1-1 with the
* IOCON structure.<br>
* Incorrect: LPC_IOCON->PIO0[0] = 0x1; // Index 0 does not map to pin 0!<br>
* Correct: LPC_IOCON->PIO0[IOCON_PIO0] = 0x1; // Enumeration PIO0 maps to pin 0
*/
typedef struct { /*!< (@ 0x40044000) IOCONFIG Structure */
__IO uint32_t PIO0[NUM_IOCON_PIO + 2]; /* 2 added for reserved register */
} LPC_IOCON_T;
/**
* @brief IOCON Register bit definitions
*/
/* Pin Mode mask */
#define PIN_MODE_MASK (0x3 << 3)
#define PIN_MODE_BITNUM (3)
/* Pin Hysteresis mask */
#define PIN_HYS_MASK (0x1 << 5)
#define PIN_HYS_BITNUM (5)
/* Pin invert input mask */
#define PIN_INV_MASK (0x1 << 6)
#define PIN_INV_BITNUM (6)
/* Pin open drain mode mask */
#define PIN_OD_MASK (0x1 << 10)
#define PIN_OD_BITNUM (10)
/* Pin digital filter sample mode mask */
#define PIN_SMODE_MASK (0x3 << 11)
#define PIN_SMODE_BITNUM (11)
/* Pin clock divider mask */
#define PIN_CLKDIV_MASK (0x7 << 13)
#define PIN_CLKDIV_BITNUM (13)
/* Pin I2C mode mask - valid for PIO10 & PIO11 only */
#define PIN_I2CMODE_MASK (0x3 << 8)
#define PIN_I2CMODE_BITNUM (8)
/**
* @brief IOCON Pin Numbers enum
* Maps a pin number to an IOCON (register) array index. IOCON indexes
* are not mapped 1-1 with pin numbers. When access the PIO0 array in
* the LPC_IOCON_T structure, the array should be indexed with one of
* these enumerations based on the pin that will have it's settings
* changed.<br>
* Example: LPC_IOCON->PIO0[IOCON_PIO0] = 0x1; // Enumeration PIO0 maps to pin 0
*/
typedef enum CHIP_PINx {
IOCON_PIO0 = 0x11, /*!< PIN 0 */
IOCON_PIO1 = 0x0B, /*!< PIN 1 */
IOCON_PIO2 = 0x06, /*!< PIN 2 */
IOCON_PIO3 = 0x05, /*!< PIN 3 */
IOCON_PIO4 = 0x04, /*!< PIN 4 */
IOCON_PIO5 = 0x03, /*!< PIN 5 */
/* The following pins are not present in DIP8 packages */
IOCON_PIO6 = 0x10, /*!< PIN 6 */
IOCON_PIO7 = 0x0F, /*!< PIN 7 */
IOCON_PIO8 = 0x0E, /*!< PIN 8 */
IOCON_PIO9 = 0x0D, /*!< PIN 9 */
IOCON_PIO10 = 0x08, /*!< PIN 10 */
IOCON_PIO11 = 0x07, /*!< PIN 11 */
IOCON_PIO12 = 0x02, /*!< PIN 12 */
IOCON_PIO13 = 0x01, /*!< PIN 13 */
/* The following pins are not present in DIP8 & TSSOP16 packages */
IOCON_PIO14 = 0x12, /*!< PIN 14 */
IOCON_PIO15 = 0x0A, /*!< PIN 15 */
IOCON_PIO16 = 0x09, /*!< PIN 16 */
IOCON_PIO17 = 0x00, /*!< PIN 17 */
IOCON_PIO_NUL0 = 0x0C, /*!< PIN NULL */
/* The following pins are not present in DIP8, TSSOP16 & TSSOP20 packages */
IOCON_PIO18 = 0x1E, /*!< PIN 18 */
IOCON_PIO19 = 0x1D, /*!< PIN 19 */
IOCON_PIO20 = 0x1C, /*!< PIN 20 */
IOCON_PIO21 = 0x1B, /*!< PIN 21 */
IOCON_PIO22 = 0x1A, /*!< PIN 22 */
IOCON_PIO23 = 0x19, /*!< PIN 23 */
IOCON_PIO24 = 0x18, /*!< PIN 24 */
IOCON_PIO25 = 0x17, /*!< PIN 25 */
IOCON_PIO26 = 0x16, /*!< PIN 26 */
IOCON_PIO27 = 0x15, /*!< PIN 27 */
IOCON_PIO28 = 0x14, /*!< PIN 28 */
IOCON_PIO_NUL1 = 0x13, /*!< PIN NULL */
} CHIP_PINx_T;
/**
* @brief IOCON Pin Modes enum
*/
typedef enum CHIP_PIN_MODE {
PIN_MODE_INACTIVE = 0, /*!< Inactive mode */
PIN_MODE_PULLDN = 1, /*!< Pull Down mode */
PIN_MODE_PULLUP = 2, /*!< Pull up mode */
PIN_MODE_REPEATER = 3 /*!< Repeater mode */
} CHIP_PIN_MODE_T;
/**
* @brief IOCON Digital Filter Sample modes enum
*/
typedef enum CHIP_PIN_SMODE {
PIN_SMODE_BYPASS = 0, /*!< Bypass input filter */
PIN_SMODE_CYC1 = 1, /*!< Input pulses shorter than 1 filter clock cycle are rejected */
PIN_SMODE_CYC2 = 2, /*!< Input pulses shorter than 2 filter clock cycles are rejected */
PIN_SMODE_CYC3 = 3 /*!< Input pulses shorter than 3 filter clock cycles are rejected */
} CHIP_PIN_SMODE_T;
/**
* @brief IOCON I2C Modes enum (Only for I2C pins PIO0_10 and PIO0_11)
*/
typedef enum CHIP_PIN_I2CMODE {
PIN_I2CMODE_STDFAST = 0, /*!< I2C standard mode/Fast mode */
PIN_I2CMODE_GPIO = 1, /*!< Standard I/O functionality */
PIN_I2CMODE_FASTPLUS = 2 /*!< I2C Fast plus mode */
} CHIP_PIN_I2CMODE_T;
/**
* @brief Sets I/O Control pin mux
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : GPIO pin to mux
* @param modefunc : OR'ed values or type IOCON_*
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinMuxSet(LPC_IOCON_T *pIOCON, uint8_t pin, uint32_t modefunc)
{
pIOCON->PIO0[pin] = modefunc;
}
/**
* @brief Set all I/O Control pin muxing
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pinArray : Pointer to array of pin mux selections
* @param arrayLength : Number of entries in pinArray
* @return Nothing
*/
void Chip_IOCON_SetPinMuxing(LPC_IOCON_T *pIOCON, const PINMUX_GRP_T* pinArray, uint32_t arrayLength);
/**
* @brief Sets pull-up or pull-down mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param mode : Mode (Pull-up/Pull-down mode)
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
void Chip_IOCON_PinSetMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_MODE_T mode);
/**
* @brief Enable or disable hysteresis for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param enable : true to enable, false to disable
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
void Chip_IOCON_PinSetHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool enable);
/**
* @brief Enable hysteresis for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
STATIC INLINE void Chip_IOCON_PinEnableHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] |= PIN_HYS_MASK;
}
/**
* @brief Disable hysteresis for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
* @note Do not use with pins PIO10 and PIO11.
*/
STATIC INLINE void Chip_IOCON_PinDisableHysteresis(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] &= ~PIN_HYS_MASK;
}
/**
* @brief Enable or disable invert input for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param invert : true to invert, false to not to invert
* @return Nothing
*/
void Chip_IOCON_PinSetInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool invert);
/**
* @brief Enable invert input for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinEnableInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] |= PIN_INV_MASK;
}
/**
* @brief Disable invert input for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinDisableInputInverted(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] &= ~PIN_INV_MASK;
}
/**
* @brief Enables or disables open-drain mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param open_drain : true to enable open-drain mode,
* false to disable open-drain mode
* @return Nothing
*/
void Chip_IOCON_PinSetOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, bool open_drain);
/**
* @brief Enables open-drain mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinEnableOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] |= PIN_OD_MASK;
}
/**
* @brief Disables open-drain mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @return Nothing
*/
STATIC INLINE void Chip_IOCON_PinDisableOpenDrainMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin)
{
pIOCON->PIO0[pin] &= ~PIN_OD_MASK;
}
/**
* @brief Sets the digital filter sampling mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param smode : 0x0 = bypass, 0x[1..3] = 1 to 3 clock cycles.
* @return Nothing
*/
void Chip_IOCON_PinSetSampleMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_SMODE_T smode);
/**
* @brief Select peripheral clock divider for input filter sampling clock
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param clkdiv : 0 = no divisor, 1...6 = PCLK/clkdiv
* @return Nothing
*/
void Chip_IOCON_PinSetClockDivisor(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_CLKDIV_T clkdiv);
/**
* @brief Set I2C mode for a pin
* @param pIOCON : The base of IOCON peripheral on the chip
* @param pin : Pin number
* @param mode : 0:Standard/Fast I2C 1: GPIO 2: Fast Plus
* @return Nothing
* @note Valid for pins PIO0_10 and PIO0_11 only.
*/
void Chip_IOCON_PinSetI2CMode(LPC_IOCON_T *pIOCON, CHIP_PINx_T pin, CHIP_PIN_I2CMODE_T mode);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __IOCON_8XX_H_ */

View File

@@ -0,0 +1,216 @@
/*
* @brief Common types used in LPC functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __LPC_TYPES_H_
#define __LPC_TYPES_H_
#include <stdint.h>
#include <stdbool.h>
/** @defgroup LPC_Types CHIP: LPC Common Types
* @ingroup CHIP_Common
* @{
*/
/** @defgroup LPC_Types_Public_Types LPC Public Types
* @{
*/
/**
* @brief Boolean Type definition
*/
typedef enum {FALSE = 0, TRUE = !FALSE} Bool;
/**
* @brief Boolean Type definition
*/
#if !defined(__cplusplus)
// typedef enum {false = 0, true = !false} bool;
#endif
/**
* @brief Flag Status and Interrupt Flag Status type definition
*/
typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState;
#define PARAM_SETSTATE(State) ((State == RESET) || (State == SET))
/**
* @brief Functional State Definition
*/
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define PARAM_FUNCTIONALSTATE(State) ((State == DISABLE) || (State == ENABLE))
/**
* @ Status type definition
*/
typedef enum {ERROR = 0, SUCCESS = !ERROR} Status;
/**
* Read/Write transfer type mode (Block or non-block)
*/
typedef enum {
NONE_BLOCKING = 0, /**< None Blocking type */
BLOCKING, /**< Blocking type */
} TRANSFER_BLOCK_T;
/** Pointer to Function returning Void (any number of parameters) */
typedef void (*PFV)();
/** Pointer to Function returning int32_t (any number of parameters) */
typedef int32_t (*PFI)();
/**
* @}
*/
/** @defgroup LPC_Types_Public_Macros LPC Public Macros
* @{
*/
/* _BIT(n) sets the bit at position "n"
* _BIT(n) is intended to be used in "OR" and "AND" expressions:
* e.g., "(_BIT(3) | _BIT(7))".
*/
#undef _BIT
/* Set bit macro */
#define _BIT(n) (1 << (n))
/* _SBF(f,v) sets the bit field starting at position "f" to value "v".
* _SBF(f,v) is intended to be used in "OR" and "AND" expressions:
* e.g., "((_SBF(5,7) | _SBF(12,0xF)) & 0xFFFF)"
*/
#undef _SBF
/* Set bit field macro */
#define _SBF(f, v) ((v) << (f))
/* _BITMASK constructs a symbol with 'field_width' least significant
* bits set.
* e.g., _BITMASK(5) constructs '0x1F', _BITMASK(16) == 0xFFFF
* The symbol is intended to be used to limit the bit field width
* thusly:
* <a_register> = (any_expression) & _BITMASK(x), where 0 < x <= 32.
* If "any_expression" results in a value that is larger than can be
* contained in 'x' bits, the bits above 'x - 1' are masked off. When
* used with the _SBF example above, the example would be written:
* a_reg = ((_SBF(5,7) | _SBF(12,0xF)) & _BITMASK(16))
* This ensures that the value written to a_reg is no wider than
* 16 bits, and makes the code easier to read and understand.
*/
#undef _BITMASK
/* Bitmask creation macro */
#define _BITMASK(field_width) ( _BIT(field_width) - 1)
/* NULL pointer */
#ifndef NULL
#define NULL ((void *) 0)
#endif
/* Number of elements in an array */
#define NELEMENTS(array) (sizeof(array) / sizeof(array[0]))
/* Static data/function define */
#define STATIC static
/* External data/function define */
#define EXTERN extern
#if !defined(MAX)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#if !defined(MIN)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
/**
* @}
*/
/* Old Type Definition compatibility */
/** @addtogroup LPC_Types_Public_Types
* @{
*/
/** LPC type for character type */
typedef char CHAR;
/** LPC type for 8 bit unsigned value */
typedef uint8_t UNS_8;
/** LPC type for 8 bit signed value */
typedef int8_t INT_8;
/** LPC type for 16 bit unsigned value */
typedef uint16_t UNS_16;
/** LPC type for 16 bit signed value */
typedef int16_t INT_16;
/** LPC type for 32 bit unsigned value */
typedef uint32_t UNS_32;
/** LPC type for 32 bit signed value */
typedef int32_t INT_32;
/** LPC type for 64 bit signed value */
typedef int64_t INT_64;
/** LPC type for 64 bit unsigned value */
typedef uint64_t UNS_64;
#ifdef __CODE_RED
#define BOOL_32 bool
#define BOOL_16 bool
#define BOOL_8 bool
#else
/** 32 bit boolean type */
typedef bool BOOL_32;
/** 16 bit boolean type */
typedef bool BOOL_16;
/** 8 bit boolean type */
typedef bool BOOL_8;
#endif
#ifdef __CC_ARM
#define INLINE __inline
#else
#define INLINE inline
#endif
/**
* @}
*/
/**
* @}
*/
#endif /* __LPC_TYPES_H_ */

View File

@@ -0,0 +1,343 @@
/*
* @brief LPC8xx Multi-Rate Timer (MRT) registers and driver functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __MRT_8XX_H_
#define __MRT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup MRT_8XX CHIP: LPC8xx Multi-Rate Timer driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx MRT chip configuration
*/
#define MRT_CHANNELS_NUM (4)
#define MRT_NO_IDLE_CHANNEL (0x40)
/**
* @brief MRT register block structure
*/
typedef struct {
__IO uint32_t INTVAL; /*!< Timer interval register */
__O uint32_t TIMER; /*!< Timer register */
__IO uint32_t CTRL; /*!< Timer control register */
__IO uint32_t STAT; /*!< Timer status register */
} LPC_MRT_CH_T;
/**
* @brief MRT register block structure
*/
typedef struct {
LPC_MRT_CH_T CHANNEL[MRT_CHANNELS_NUM];
uint32_t unused[45];
__O uint32_t IDLE_CH;
__IO uint32_t IRQ_FLAG;
} LPC_MRT_T;
/* Reserved bits masks for registers */
#define MRT_CTRL_RESERVED (~7)
#define MRT_STAT_RESERVED (~3)
/**
* @brief MRT Interrupt Modes enum
*/
typedef enum MRT_MODE {
MRT_MODE_REPEAT = (0 << 1), /*!< MRT Repeat interrupt mode */
MRT_MODE_ONESHOT = (1 << 1) /*!< MRT One-shot interrupt mode */
} MRT_MODE_T;
/**
* @brief MRT register bit fields & masks
*/
/* MRT Time interval register bit fields */
#define MRT_INTVAL_IVALUE (0x7FFFFFFFUL) /* Maximum interval load value and mask */
#define MRT_INTVAL_LOAD (0x80000000UL) /* Force immediate load of timer interval register bit */
/* MRT Control register bit fields & masks */
#define MRT_CTRL_INTEN_MASK (0x01)
#define MRT_CTRL_MODE_MASK (0x06)
/* MRT Status register bit fields & masks */
#define MRT_STAT_INTFLAG (0x01)
#define MRT_STAT_RUNNING (0x02)
/* Pointer to individual MR register blocks */
#define LPC_MRT_CH0 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[0])
#define LPC_MRT_CH1 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[1])
#define LPC_MRT_CH2 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[2])
#define LPC_MRT_CH3 ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[3])
#define LPC_MRT_CH(ch) ((LPC_MRT_CH_T *) &LPC_MRT->CHANNEL[(ch)])
/* Global interrupt flag register interrupt mask/clear values */
#define MRT0_INTFLAG (1)
#define MRT1_INTFLAG (2)
#define MRT2_INTFLAG (4)
#define MRT3_INTFLAG (8)
#define MRTn_INTFLAG(ch) (1 << (ch))
/**
* @brief Initializes the MRT
* @return Nothing
*/
STATIC INLINE void Chip_MRT_Init(void)
{
/* Enable the clock to the register interface */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MRT);
/* Reset MRT */
Chip_SYSCTL_PeriphReset(RESET_MRT);
}
/**
* @brief De-initializes the MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_DeInit(void)
{
/* Disable the clock to the MRT */
Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_MRT);
}
/**
* @brief Returns a pointer to the register block for a MRT channel
* @param ch : MRT channel tog et register block for (0..3)
* @return Pointer to the MRT register block for the channel
*/
STATIC INLINE LPC_MRT_CH_T *Chip_MRT_GetRegPtr(uint8_t ch)
{
return LPC_MRT_CH(ch);
}
/**
* @brief Returns the timer time interval value
* @param pMRT : Pointer to selected MRT Channel
* @return Timer time interval value (IVALUE)
*/
STATIC INLINE uint32_t Chip_MRT_GetInterval(LPC_MRT_CH_T *pMRT)
{
return pMRT->INTVAL;
}
/**
* @brief Sets the timer time interval value
* @param pMRT : Pointer to selected MRT Channel
* @param interval : The interval timeout (31-bits)
* @return Nothing
* @note Setting bit 31 in timer time interval register causes the time interval value
* to load immediately, otherwise the time interval value will be loaded in
* next timer cycle.<br>
* Example: Chip_MRT_SetInterval(pMRT, 0x500 | MRT_INTVAL_LOAD); // Will load timer interval immediately<br>
* Example: Chip_MRT_SetInterval(pMRT, 0x500); // Will load timer interval after internal expires
*/
STATIC INLINE void Chip_MRT_SetInterval(LPC_MRT_CH_T *pMRT, uint32_t interval)
{
pMRT->INTVAL = interval;
}
/**
* @brief Returns the current timer value
* @param pMRT : Pointer to selected MRT Channel
* @return The current timer value
*/
STATIC INLINE uint32_t Chip_MRT_GetTimer(LPC_MRT_CH_T *pMRT)
{
return pMRT->TIMER;
}
/**
* @brief Returns true if the timer is enabled
* @param pMRT : Pointer to selected MRT Channel
* @return True if enabled, Flase if not enabled
*/
STATIC INLINE bool Chip_MRT_GetEnabled(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->CTRL & MRT_CTRL_INTEN_MASK) != 0);
}
/**
* @brief Enables the timer
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetEnabled(LPC_MRT_CH_T *pMRT)
{
pMRT->CTRL = MRT_CTRL_INTEN_MASK | (pMRT->CTRL & ~MRT_CTRL_RESERVED);
}
/**
* @brief Disables the timer
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetDisabled(LPC_MRT_CH_T *pMRT)
{
pMRT->CTRL &= ~(MRT_CTRL_INTEN_MASK | MRT_CTRL_RESERVED);
}
/**
* @brief Returns the timer mode (repeat or one-shot)
* @param pMRT : Pointer to selected MRT Channel
* @return The current timer mode
*/
STATIC INLINE MRT_MODE_T Chip_MRT_GetMode(LPC_MRT_CH_T *pMRT)
{
return (MRT_MODE_T) (pMRT->CTRL & MRT_CTRL_MODE_MASK);
}
/**
* @brief Sets the timer mode (repeat or one-shot)
* @param pMRT : Pointer to selected MRT Channel
* @param mode : Timer mode
* @return Nothing
*/
STATIC INLINE void Chip_MRT_SetMode(LPC_MRT_CH_T *pMRT, MRT_MODE_T mode)
{
uint32_t reg;
reg = pMRT->CTRL & ~(MRT_CTRL_MODE_MASK | MRT_CTRL_RESERVED);
pMRT->CTRL = reg | (uint32_t) mode;
}
/**
* @brief Check if the timer is configured in repeat mode
* @param pMRT : Pointer to selected MRT Channel
* @return True if in repeat mode, False if in one-shot mode
*/
STATIC INLINE bool Chip_MRT_IsRepeatMode(LPC_MRT_CH_T *pMRT)
{
return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? false : true;
}
/**
* @brief Check if the timer is configured in one-shot mode
* @param pMRT : Pointer to selected MRT Channel
* @return True if in one-shot mode, False if in repeat mode
*/
STATIC INLINE bool Chip_MRT_IsOneShotMode(LPC_MRT_CH_T *pMRT)
{
return ((pMRT->CTRL & MRT_CTRL_MODE_MASK) != 0) ? true : false;
}
/**
* @brief Check if the timer has an interrupt pending
* @param pMRT : Pointer to selected MRT Channel
* @return True if interrupt is pending, False if no interrupt is pending
*/
STATIC INLINE bool Chip_MRT_IntPending(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->STAT & MRT_STAT_INTFLAG) != 0);
}
/**
* @brief Clears the pending interrupt (if any)
* @param pMRT : Pointer to selected MRT Channel
* @return Nothing
*/
STATIC INLINE void Chip_MRT_IntClear(LPC_MRT_CH_T *pMRT)
{
pMRT->STAT = MRT_STAT_INTFLAG | (pMRT->STAT & ~MRT_STAT_RESERVED);
}
/**
* @brief Check if the timer is running
* @param pMRT : Pointer to selected MRT Channel
* @return True if running, False if stopped
*/
STATIC INLINE bool Chip_MRT_Running(LPC_MRT_CH_T *pMRT)
{
return (bool) ((pMRT->STAT & MRT_STAT_RUNNING) != 0);
}
/**
* @brief Returns the IDLE channel value
* @return IDLE channel value (unshifted in bits 7..4)
*/
STATIC INLINE uint8_t Chip_MRT_GetIdleChannel(void)
{
return (uint8_t) (LPC_MRT->IDLE_CH);
}
/**
* @brief Returns the IDLE channel value
* @return IDLE channel value (shifted in bits 3..0)
*/
STATIC INLINE uint8_t Chip_MRT_GetIdleChannelShifted(void)
{
return (uint8_t) (Chip_MRT_GetIdleChannel() >> 4);
}
/**
* @brief Returns the interrupt pending status for all MRT channels
* @return IRQ pending channel bitfield(bit 0 = MRT0, bit 1 = MRT1, etc.)
*/
STATIC INLINE uint32_t Chip_MRT_GetIntPending(void)
{
return LPC_MRT->IRQ_FLAG;
}
/**
* @brief Returns the interrupt pending status for a singel MRT channel
* @param ch : Channel to check pending interrupt status for
* @return IRQ pending channel number
*/
STATIC INLINE bool Chip_MRT_GetIntPendingByChannel(uint8_t ch)
{
return (bool) (((LPC_MRT->IRQ_FLAG >> ch) & 1) != 0);
}
/**
* @brief Clears the interrupt pending status for one or more MRT channels
* @param mask : Channels to clear (bit 0 = MRT0, bit 1 = MRT1, etc.)
* @return Nothing
* @note Use this function to clear multiple interrupt pending states in
* a single call via the IRQ_FLAG register. Performs the same function for
* all MRT channels in a single call as the Chip_MRT_IntClear() does for a
* single channel.
*/
STATIC INLINE void Chip_MRT_ClearIntPending(uint32_t mask)
{
LPC_MRT->IRQ_FLAG = mask;
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __MRT_8XX_H_ */

View File

@@ -0,0 +1,373 @@
/*
* @brief LPC8xx Pin Interrupt and Pattern Match Registers and driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __PININT_8XX_H_
#define __PININT_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup PININT_8XX CHIP: LPC8xx Pin Interrupt and Pattern Match driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx Pin Interrupt and Pattern Match register block structure
*/
typedef struct { /*!< (@ 0xA0004000) PIN_INT Structure */
__IO uint32_t ISEL; /*!< (@ 0xA0004000) Pin Interrupt Mode register */
__IO uint32_t IENR; /*!< (@ 0xA0004004) Pin Interrupt Enable (Rising) register */
__IO uint32_t SIENR; /*!< (@ 0xA0004008) Set Pin Interrupt Enable (Rising) register */
__IO uint32_t CIENR; /*!< (@ 0xA000400C) Clear Pin Interrupt Enable (Rising) register */
__IO uint32_t IENF; /*!< (@ 0xA0004010) Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t SIENF; /*!< (@ 0xA0004014) Set Pin Interrupt Enable Falling Edge / Active Level register */
__IO uint32_t CIENF; /*!< (@ 0xA0004018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
__IO uint32_t RISE; /*!< (@ 0xA000401C) Pin Interrupt Rising Edge register */
__IO uint32_t FALL; /*!< (@ 0xA0004020) Pin Interrupt Falling Edge register */
__IO uint32_t IST; /*!< (@ 0xA0004024) Pin Interrupt Status register */
__IO uint32_t PMCTRL; /*!< (@ 0xA0004028) GPIO pattern match interrupt control register */
__IO uint32_t PMSRC; /*!< (@ 0xA000402C) GPIO pattern match interrupt bit-slice source register */
__IO uint32_t PMCFG; /*!< (@ 0xA0004030) GPIO pattern match interrupt bit slice configuration register */
} LPC_PIN_INT_T;
/* Reserved bits masks for registers */
#define PININT_ISEL_RESERVED (~0xff)
#define PININT_IENR_RESERVED (~0xff)
#define PININT_SIENR_RESERVED (~0xff)
#define PININT_CIENR_RESERVED (~0xff)
#define PININT_IENF_RESERVED (~0xff)
#define PININT_SIENF_RESERVED (~0xff)
#define PININT_CIENF_RESERVED (~0xff)
#define PININT_RISE_RESERVED (~0xff)
#define PININT_FALL_RESERVED (~0xff)
#define PININT_IST_RESERVED (~0xff)
#define PININT_PMCTRL_RESERVED (~0xff000003)
#define PININT_PMSRC_RESERVED 0xff
#define PININT_PMCFG_RESERVED (1<<7)
/**
* LPC8xx Pin Interrupt and Pattern match engine register
* bit fields and macros
*/
/* PININT interrupt control register */
#define PININT_PMCTRL_PMATCH_SEL (1 << 0)
#define PININT_PMCTRL_RXEV_ENA (1 << 1)
/* PININT Bit slice source register bits */
#define PININT_SRC_BITSOURCE_START 8
#define PININT_SRC_BITSOURCE_MASK 7
/* PININT Bit slice configuration register bits */
#define PININT_SRC_BITCFG_START 8
#define PININT_SRC_BITCFG_MASK 7
/**
* LPC8xx Pin Interrupt channel values
*/
#define PININTCH0 (1 << 0)
#define PININTCH1 (1 << 1)
#define PININTCH2 (1 << 2)
#define PININTCH3 (1 << 3)
#define PININTCH4 (1 << 4)
#define PININTCH5 (1 << 5)
#define PININTCH6 (1 << 6)
#define PININTCH7 (1 << 7)
#define PININTCH(ch) (1 << (ch))
/**
* LPC8xx Pin Matching Interrupt bit slice enum values
*/
typedef enum Chip_PININT_BITSLICE {
PININTBITSLICE0 = 0, /*!< PININT Bit slice 0 */
PININTBITSLICE1 = 1, /*!< PININT Bit slice 1 */
PININTBITSLICE2 = 2, /*!< PININT Bit slice 2 */
PININTBITSLICE3 = 3, /*!< PININT Bit slice 3 */
PININTBITSLICE4 = 4, /*!< PININT Bit slice 4 */
PININTBITSLICE5 = 5, /*!< PININT Bit slice 5 */
PININTBITSLICE6 = 6, /*!< PININT Bit slice 6 */
PININTBITSLICE7 = 7 /*!< PININT Bit slice 7 */
} Chip_PININT_BITSLICE_T;
/**
* LPC8xx Pin Matching Interrupt bit slice configuration enum values
*/
typedef enum Chip_PININT_BITSLICE_CFG {
PININT_PATTERNCONST1 = 0x0, /*!< Contributes to product term match */
PININT_PATTERNRISING = 0x1, /*!< Rising edge */
PININT_PATTERNFALLING = 0x2, /*!< Falling edge */
PININT_PATTERNRISINGRFALLING = 0x3, /*!< Rising or Falling edge */
PININT_PATTERNHIGH = 0x4, /*!< High level */
PININT_PATTERNLOW = 0x5, /*!< Low level */
PININT_PATTERCONST0 = 0x6, /*!< Never contributes for match */
PININT_PATTEREVENT = 0x7 /*!< Match occurs on event */
} Chip_PININT_BITSLICE_CFG_T;
/**
* @brief Initialize Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
* @note This function should be used after the Chip_GPIO_Init() function.
*/
STATIC INLINE void Chip_PININT_Init(LPC_PIN_INT_T *pPININT) {}
/**
* @brief De-Initialize Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DeInit(LPC_PIN_INT_T *pPININT) {}
/**
* @brief Configure the pins as edge sensitive in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_SetPinModeEdge(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->ISEL &= ~(pins | PININT_ISEL_RESERVED);
}
/**
* @brief Configure the pins as level sensitive in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_SetPinModeLevel(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->ISEL = pins | (pPININT->ISEL & ~PININT_ISEL_RESERVED);
}
/**
* @brief Return current PININT rising edge or high level interrupt enable state
* @param pPININT : The base address of Pin interrupt block
* @return A bifield containing the high edge/level interrupt enables for each
* interrupt. Bit 0 = PININT0, 1 = PININT1, etc.
* For each bit, a 0 means the high edge/level interrupt is disabled, while a 1
* means it's enabled.
*/
STATIC INLINE uint32_t Chip_PININT_GetHighEnabled(LPC_PIN_INT_T *pPININT)
{
return pPININT->IENR & ~PININT_IENR_RESERVED;
}
/**
* @brief Enable high edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to enable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnableIntHigh(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->SIENR = pins;
}
/**
* @brief Disable high edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to disable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisableIntHigh(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->CIENR = pins;
}
/**
* @brief Return current PININT falling edge or low level interrupt enable state
* @param pPININT : The base address of Pin interrupt block
* @return A bifield containing the low edge/level interrupt enables for each
* interrupt. Bit 0 = PININT0, 1 = PININT1, etc.
* For each bit, a 0 means the low edge/level interrupt is disabled, while a 1
* means it's enabled.
*/
STATIC INLINE uint32_t Chip_PININT_GetLowEnabled(LPC_PIN_INT_T *pPININT)
{
return pPININT->IENF & ~PININT_IENF_RESERVED;
}
/**
* @brief Enable low edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to enable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnableIntLow(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->SIENF = pins;
}
/**
* @brief Disable low edge/level PININT interrupts for pins
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins to disable (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisableIntLow(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->CIENF = pins;
}
/**
* @brief Return pin states that have a detected latched high edge (RISE) state
* @param pPININT : The base address of Pin interrupt block
* @return PININT states (bit n = high) with a latched rise state detected
*/
STATIC INLINE uint32_t Chip_PININT_GetRiseStates(LPC_PIN_INT_T *pPININT)
{
return pPININT->RISE & ~PININT_RISE_RESERVED;
}
/**
* @brief Clears pin states that had a latched high edge (RISE) state
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins with latched states to clear
* @return Nothing
*/
STATIC INLINE void Chip_PININT_ClearRiseStates(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->RISE = pins;
}
/**
* @brief Return pin states that have a detected latched falling edge (FALL) state
* @param pPININT : The base address of Pin interrupt block
* @return PININT states (bit n = high) with a latched rise state detected
*/
STATIC INLINE uint32_t Chip_PININT_GetFallStates(LPC_PIN_INT_T *pPININT)
{
return pPININT->FALL & ~PININT_FALL_RESERVED;
}
/**
* @brief Clears pin states that had a latched falling edge (FALL) state
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pins with latched states to clear
* @return Nothing
*/
STATIC INLINE void Chip_PININT_ClearFallStates(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->FALL = pins;
}
/**
* @brief Get interrupt status from Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Interrupt status (bit n for PININTn = high means interrupt ie pending)
*/
STATIC INLINE uint32_t Chip_PININT_GetIntStatus(LPC_PIN_INT_T *pPININT)
{
return pPININT->IST& ~PININT_IST_RESERVED;
}
/**
* @brief Clear interrupt status in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param pins : Pin interrupts to clear (ORed value of PININTCH*)
* @return Nothing
*/
STATIC INLINE void Chip_PININT_ClearIntStatus(LPC_PIN_INT_T *pPININT, uint32_t pins)
{
pPININT->IST = pins;
}
/**
* @brief Set source for pattern match in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param chan : PININT channel number (From 0 to 7)
* @param slice : PININT slice number
* @return Nothing
*/
void Chip_PININT_SetPatternMatchSrc(LPC_PIN_INT_T *pPININT, uint8_t chan, Chip_PININT_BITSLICE_T slice);
/**
* @brief Configure the pattern matcch in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @param slice : PININT slice number
* @param slice_cfg : PININT slice configuration value (enum Chip_PININT_BITSLICE_CFG_T)
* @param end_point : If true, current slice is final component
* @return Nothing
*/
void Chip_PININT_SetPatternMatchConfig(LPC_PIN_INT_T *pPININT, Chip_PININT_BITSLICE_T slice,
Chip_PININT_BITSLICE_CFG_T slice_cfg, bool end_point);
/**
* @brief Enable pattern match interrupts in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnablePatternMatch(LPC_PIN_INT_T *pPININT)
{
pPININT->PMCTRL = PININT_PMCTRL_PMATCH_SEL | (pPININT->PMCTRL & ~PININT_PMCTRL_RESERVED);
}
/**
* @brief Disable pattern match interrupts in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisablePatternMatch(LPC_PIN_INT_T *pPININT)
{
pPININT->PMCTRL &= ~(PININT_PMCTRL_PMATCH_SEL | PININT_PMCTRL_RESERVED);
}
/**
* @brief Enable RXEV output in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_EnablePatternMatchRxEv(LPC_PIN_INT_T *pPININT)
{
pPININT->PMCTRL = PININT_PMCTRL_RXEV_ENA | (pPININT->PMCTRL & ~PININT_PMCTRL_RESERVED);
}
/**
* @brief Disable RXEV output in Pin interrupt block
* @param pPININT : The base address of Pin interrupt block
* @return Nothing
*/
STATIC INLINE void Chip_PININT_DisablePatternMatchRxEv(LPC_PIN_INT_T *pPININT)
{
pPININT->PMCTRL &= ~(PININT_PMCTRL_RXEV_ENA | PININT_PMCTRL_RESERVED);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __PININT_8XX_H_ */

View File

@@ -0,0 +1,237 @@
/*
* @brief LPC8xx PMU chip driver
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __PMU_8XX_H_
#define __PMU_8XX_H_
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup PMU_8XX CHIP: LPC8xx PMU driver
* @ingroup CHIP_8XX_Drivers
* @{
*/
/**
* @brief LPC8xx Power Management Unit register block structure
*/
typedef struct {
__IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */
__IO uint32_t GPREG[4]; /*!< Offset: 0x004 General purpose Registers 0..3 (R/W) */
__IO uint32_t DPDCTRL; /*!< Offset: 0x014 Deep power-down control register (R/W) */
} LPC_PMU_T;
/* Reserved bits masks for registers */
#define PMU_PCON_RESERVED ((0xf<<4)|(0x6<<8)|0xfffff000)
#define PMU_DPDCTRL_RESERVED (~0xf)
/**
* @brief LPC8xx low power mode type definitions
*/
typedef enum CHIP_PMU_MCUPOWER {
PMU_MCU_SLEEP = 0, /*!< Sleep mode */
PMU_MCU_DEEP_SLEEP, /*!< Deep Sleep mode */
PMU_MCU_POWER_DOWN, /*!< Power down mode */
PMU_MCU_DEEP_PWRDOWN /*!< Deep power down mode */
} CHIP_PMU_MCUPOWER_T;
/**
* PMU PCON register bit fields & masks
*/
#define PMU_PCON_PM_SLEEP (0x0) /*!< ARM WFI enter sleep mode */
#define PMU_PCON_PM_DEEPSLEEP (0x1) /*!< ARM WFI enter Deep-sleep mode */
#define PMU_PCON_PM_POWERDOWN (0x2) /*!< ARM WFI enter Power-down mode */
#define PMU_PCON_PM_DEEPPOWERDOWN (0x3) /*!< ARM WFI enter Deep Power-down mode */
#define PMU_PCON_NODPD (1 << 3) /*!< Disable deep power-down mode */
#define PMU_PCON_SLEEPFLAG (1 << 8) /*!< Sleep mode flag */
#define PMU_PCON_DPDFLAG (1 << 11) /*!< Deep power-down flag */
/**
* PMU DPDCTRL register bit fields & masks
*/
#define PMU_DPDCTRL_WAKEUPPHYS (1 << 0) /** Enable wake-up pin hysteresis */
#define PMU_DPDCTRL_WAKEPAD (1 << 1) /** Disable the Wake-up */
#define PMU_DPDCTRL_LPOSCEN (1 << 2) /** Enable the low-power oscillator (10 khz self wk) */
#define PMU_DPDCTRL_LPOSCDPDEN (1 << 3) /** Enable the low-power oscillator in deep power-down*/
/**
* @brief Write a value to a GPREG register
* @param pPMU : Pointer to PMU register block
* @param regIndex : Register index to write to, must be 0..3
* @param value : Value to write
* @return None
*/
STATIC INLINE void Chip_PMU_WriteGPREG(LPC_PMU_T *pPMU, uint8_t regIndex, uint32_t value)
{
pPMU->GPREG[regIndex] = value;
}
/**
* @brief Read a value to a GPREG register
* @param pPMU : Pointer to PMU register block
* @param regIndex : Register index to read from, must be 0..3
* @return Value read from the GPREG register
*/
STATIC INLINE uint32_t Chip_PMU_ReadGPREG(LPC_PMU_T *pPMU, uint8_t regIndex)
{
return pPMU->GPREG[regIndex];
}
/**
* @brief Enter MCU Sleep mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note The sleep mode affects the ARM Cortex-M0+ core only. Peripherals
* and memories are active.
*/
void Chip_PMU_SleepState(LPC_PMU_T *pPMU);
/**
* @brief Enter MCU Deep Sleep mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note In Deep-sleep mode, the peripherals receive no internal clocks.
* The flash is in stand-by mode. The SRAM memory and all peripheral registers
* as well as the processor maintain their internal states. The WWDT, WKT,
* and BOD can remain active to wake up the system on an interrupt.
*/
void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU);
/**
* @brief Enter MCU Power down mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note In Power-down mode, the peripherals receive no internal clocks.
* The internal SRAM memory and all peripheral registers as well as the
* processor maintain their internal states. The flash memory is powered
* down. The WWDT, WKT, and BOD can remain active to wake up the system
* on an interrupt.
*/
void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU);
/**
* @brief Enter MCU Deep Power down mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note For maximal power savings, the entire system is shut down
* except for the general purpose registers in the PMU and the self
* wake-up timer. Only the general purpose registers in the PMU maintain
* their internal states. The part can wake up on a pulse on the WAKEUP
* pin or when the self wake-up timer times out. On wake-up, the part
* reboots.
*/
void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU);
/**
* @brief Place the MCU in a low power state
* @param pPMU : Pointer to PMU register block
* @param SleepMode : Sleep mode
* @return None
*/
void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode);
/**
* @brief Disables deep power-down mode
* @param pPMU : Pointer to PMU register block
* @return None
* @note Calling this functions prevents entry to Deep power-down
* mode. Once set, this can only be cleared by power-on reset.
*/
STATIC INLINE void Chip_PMU_DisableDeepPowerDown(LPC_PMU_T *pPMU)
{
pPMU->PCON = PMU_PCON_NODPD | (pPMU->PCON & ~PMU_PCON_RESERVED);
}
/**
* @brief Returns sleep/power-down flags
* @param pPMU : Pointer to PMU register block
* @return Or'ed values of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG
* @note These indicate that the PMU is setup for entry into a low
* power state on the next WFI() instruction.
*/
STATIC INLINE uint32_t Chip_PMU_GetSleepFlags(LPC_PMU_T *pPMU)
{
return (pPMU->PCON & (PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG));
}
/**
* @brief Clears sleep/power-down flags
* @param pPMU : Pointer to PMU register block
* @param flags : Or'ed value of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG
* @return Nothing
* @note Use this function to clear a low power state prior to calling
* WFI().
*/
STATIC INLINE void Chip_PMU_ClearSleepFlags(LPC_PMU_T *pPMU, uint32_t flags)
{
pPMU->PCON |= (flags & (~PMU_PCON_RESERVED));
}
/**
* @brief Sets deep power-down functions
* @param pPMU : Pointer to PMU register block
* @param flags : Or'ed value of PMU_DPDCTRL_* values
* @return Nothing
* @note Some of these functions may need to be set prior to going
* into a low power mode. Note that some calls to this function enable
* functions while others disable it based on the PMU_DPDCTRL_*
* definitions.
*/
STATIC INLINE void Chip_PMU_SetPowerDownControl(LPC_PMU_T *pPMU, uint32_t flags)
{
pPMU->DPDCTRL = flags | (pPMU->DPDCTRL & ~PMU_DPDCTRL_RESERVED);
}
/**
* @brief Cleats deep power-down functions
* @param pPMU : Pointer to PMU register block
* @param flags : Or'ed value of PMU_DPDCTRL_* values
* @return Nothing
* @note Some of these functions may need to be cleared prior to going
* into a low power mode. Note that some calls to this function enable
* functions while others disable it based on the PMU_DPDCTRL_*
* definitions.
*/
STATIC INLINE void Chip_PMU_ClearPowerDownControl(LPC_PMU_T *pPMU, uint32_t flags)
{
pPMU->DPDCTRL &= ~(flags | PMU_DPDCTRL_RESERVED);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __PMU_8XX_H_ */

View File

@@ -0,0 +1,188 @@
/*
* @brief Common ring buffer support functions
*
* @note
* Copyright(C) NXP Semiconductors, 2012
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights 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 __RING_BUFFER_H_
#define __RING_BUFFER_H_
#include "lpc_types.h"
/** @defgroup Ring_Buffer CHIP: Simple ring buffer implementation
* @ingroup CHIP_Common
* @{
*/
/**
* @brief Ring buffer structure
*/
typedef struct {
void *data;
int count;
int itemSz;
uint32_t head;
uint32_t tail;
} RINGBUFF_T;
/**
* @def RB_VHEAD(rb)
* volatile typecasted head index
*/
#define RB_VHEAD(rb) (*(volatile uint32_t *) &(rb)->head)
/**
* @def RB_VTAIL(rb)
* volatile typecasted tail index
*/
#define RB_VTAIL(rb) (*(volatile uint32_t *) &(rb)->tail)
/**
* @brief Initialize ring buffer
* @param RingBuff : Pointer to ring buffer to initialize
* @param buffer : Pointer to buffer to associate with RingBuff
* @param itemSize : Size of each buffer item size
* @param count : Size of ring buffer
* @note Memory pointed by @a buffer must have correct alignment of
* @a itemSize, and @a count must be a power of 2 and must at
* least be 2 or greater.
* @return Nothing
*/
int RingBuffer_Init(RINGBUFF_T *RingBuff, void *buffer, int itemSize, int count);
/**
* @brief Resets the ring buffer to empty
* @param RingBuff : Pointer to ring buffer
* @return Nothing
*/
STATIC INLINE void RingBuffer_Flush(RINGBUFF_T *RingBuff)
{
RingBuff->head = RingBuff->tail = 0;
}
/**
* @brief Return size the ring buffer
* @param RingBuff : Pointer to ring buffer
* @return Size of the ring buffer in bytes
*/
STATIC INLINE int RingBuffer_GetSize(RINGBUFF_T *RingBuff)
{
return RingBuff->count;
}
/**
* @brief Return number of items in the ring buffer
* @param RingBuff : Pointer to ring buffer
* @return Number of items in the ring buffer
*/
STATIC INLINE int RingBuffer_GetCount(RINGBUFF_T *RingBuff)
{
return RB_VHEAD(RingBuff) - RB_VTAIL(RingBuff);
}
/**
* @brief Return number of free items in the ring buffer
* @param RingBuff : Pointer to ring buffer
* @return Number of free items in the ring buffer
*/
STATIC INLINE int RingBuffer_GetFree(RINGBUFF_T *RingBuff)
{
return RingBuff->count - RingBuffer_GetCount(RingBuff);
}
/**
* @brief Return number of items in the ring buffer
* @param RingBuff : Pointer to ring buffer
* @return 1 if the ring buffer is full, otherwise 0
*/
STATIC INLINE int RingBuffer_IsFull(RINGBUFF_T *RingBuff)
{
return (RingBuffer_GetCount(RingBuff) >= RingBuff->count);
}
/**
* @brief Return empty status of ring buffer
* @param RingBuff : Pointer to ring buffer
* @return 1 if the ring buffer is empty, otherwise 0
*/
STATIC INLINE int RingBuffer_IsEmpty(RINGBUFF_T *RingBuff)
{
return RB_VHEAD(RingBuff) == RB_VTAIL(RingBuff);
}
/**
* @brief Insert a single item into ring buffer
* @param RingBuff : Pointer to ring buffer
* @param data : pointer to item
* @return 1 when successfully inserted,
* 0 on error (Buffer not initialized using
* RingBuffer_Init() or attempted to insert
* when buffer is full)
*/
int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data);
/**
* @brief Insert an array of items into ring buffer
* @param RingBuff : Pointer to ring buffer
* @param data : Pointer to first element of the item array
* @param num : Number of items in the array
* @return number of items successfully inserted,
* 0 on error (Buffer not initialized using
* RingBuffer_Init() or attempted to insert
* when buffer is full)
*/
int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num);
/**
* @brief Pop an item from the ring buffer
* @param RingBuff : Pointer to ring buffer
* @param data : Pointer to memory where popped item be stored
* @return 1 when item popped successfuly onto @a data,
* 0 When error (Buffer not initialized using
* RingBuffer_Init() or attempted to pop item when
* the buffer is empty)
*/
int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data);
/**
* @brief Pop an array of items from the ring buffer
* @param RingBuff : Pointer to ring buffer
* @param data : Pointer to memory where popped items be stored
* @param num : Max number of items array @a data can hold
* @return Number of items popped onto @a data,
* 0 on error (Buffer not initialized using RingBuffer_Init()
* or attempted to pop when the buffer is empty)
*/
int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num);
/**
* @}
*/
#endif /* __RING_BUFFER_H_ */

Some files were not shown because too many files have changed in this diff Show More