From 19260fbe85a9a2101a2684961b7882bd91224e11 Mon Sep 17 00:00:00 2001 From: Martin Boretto Date: Mon, 9 Jun 2014 11:27:18 -0300 Subject: bsp/lpc176x: New BSP --- c/src/lib/libbsp/arm/acinclude.m4 | 2 + c/src/lib/libbsp/arm/lpc176x/Makefile.am | 165 ++ c/src/lib/libbsp/arm/lpc176x/README | 11 + .../arm/lpc176x/benchmark_timer/benchmark_timer.c | 45 + c/src/lib/libbsp/arm/lpc176x/bsp_specs | 13 + c/src/lib/libbsp/arm/lpc176x/configure.ac | 71 + .../libbsp/arm/lpc176x/console/console-config.c | 158 ++ c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c | 392 +++++ c/src/lib/libbsp/arm/lpc176x/include/bsp.h | 100 ++ .../lib/libbsp/arm/lpc176x/include/common-types.h | 117 ++ c/src/lib/libbsp/arm/lpc176x/include/dma.h | 98 ++ c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h | 218 +++ c/src/lib/libbsp/arm/lpc176x/include/gpio.h | 100 ++ c/src/lib/libbsp/arm/lpc176x/include/io-defs.h | 123 ++ c/src/lib/libbsp/arm/lpc176x/include/io.h | 77 + c/src/lib/libbsp/arm/lpc176x/include/irq.h | 108 ++ .../libbsp/arm/lpc176x/include/lpc-clock-config.h | 44 + c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h | 1585 ++++++++++++++++++++ .../lib/libbsp/arm/lpc176x/include/system-clocks.h | 91 ++ c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h | 449 ++++++ c/src/lib/libbsp/arm/lpc176x/include/timer.h | 195 +++ .../lib/libbsp/arm/lpc176x/include/watchdog-defs.h | 65 + c/src/lib/libbsp/arm/lpc176x/include/watchdog.h | 70 + c/src/lib/libbsp/arm/lpc176x/irq/irq.c | 75 + .../make/custom/lpc1768_mbed-testsuite.tcfg | 19 + .../arm/lpc176x/make/custom/lpc1768_mbed.cfg | 19 + .../lpc176x/make/custom/lpc1768_mbed_ahb_ram.cfg | 19 + c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c | 30 + c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c | 220 +++ c/src/lib/libbsp/arm/lpc176x/misc/dma.c | 117 ++ c/src/lib/libbsp/arm/lpc176x/misc/io.c | 334 +++++ c/src/lib/libbsp/arm/lpc176x/misc/restart.c | 34 + c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c | 124 ++ c/src/lib/libbsp/arm/lpc176x/preinstall.am | 167 +++ c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c | 127 ++ c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c | 42 + c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c | 89 ++ .../lib/libbsp/arm/lpc176x/startup/bspstarthooks.c | 227 +++ .../arm/lpc176x/startup/linkcmds.lpc1768_mbed | 27 + .../lpc176x/startup/linkcmds.lpc1768_mbed_ahb_ram | 28 + c/src/lib/libbsp/arm/lpc176x/timer/timer.c | 407 +++++ c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c | 102 ++ 42 files changed, 6504 insertions(+) create mode 100644 c/src/lib/libbsp/arm/lpc176x/Makefile.am create mode 100644 c/src/lib/libbsp/arm/lpc176x/README create mode 100644 c/src/lib/libbsp/arm/lpc176x/benchmark_timer/benchmark_timer.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/bsp_specs create mode 100644 c/src/lib/libbsp/arm/lpc176x/configure.ac create mode 100644 c/src/lib/libbsp/arm/lpc176x/console/console-config.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/bsp.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/common-types.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/dma.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/gpio.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/io-defs.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/io.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/irq.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/system-clocks.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/timer.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/watchdog-defs.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/include/watchdog.h create mode 100644 c/src/lib/libbsp/arm/lpc176x/irq/irq.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed-testsuite.tcfg create mode 100644 c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed.cfg create mode 100644 c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed_ahb_ram.cfg create mode 100644 c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/misc/dma.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/misc/io.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/misc/restart.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/preinstall.am create mode 100644 c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/startup/bspstarthooks.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed create mode 100644 c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed_ahb_ram create mode 100644 c/src/lib/libbsp/arm/lpc176x/timer/timer.c create mode 100644 c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c diff --git a/c/src/lib/libbsp/arm/acinclude.m4 b/c/src/lib/libbsp/arm/acinclude.m4 index b4a597d340..9192267b5d 100644 --- a/c/src/lib/libbsp/arm/acinclude.m4 +++ b/c/src/lib/libbsp/arm/acinclude.m4 @@ -20,6 +20,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR], AC_CONFIG_SUBDIRS([gumstix]);; lm3s69xx ) AC_CONFIG_SUBDIRS([lm3s69xx]);; + lpc176x ) + AC_CONFIG_SUBDIRS([lpc176x]);; lpc24xx ) AC_CONFIG_SUBDIRS([lpc24xx]);; lpc32xx ) diff --git a/c/src/lib/libbsp/arm/lpc176x/Makefile.am b/c/src/lib/libbsp/arm/lpc176x/Makefile.am new file mode 100644 index 0000000000..3a1d4b21ed --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/Makefile.am @@ -0,0 +1,165 @@ +## +# +# @file +# +# @brief Makefile of LibBSP for the LPC176x boards. +# + +ACLOCAL_AMFLAGS = -I ../../../../aclocal + +include $(top_srcdir)/../../../../automake/compile.am + +include_bspdir = $(includedir)/bsp + +dist_project_lib_DATA = bsp_specs + + +# ---------------------------- +# ------ Headers +# ---------------------------- + +include_HEADERS = include/bsp.h + +nodist_include_HEADERS = ../../shared/include/coverhd.h +nodist_include_HEADERS += include/bspopts.h + +nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h + +include_bsp_HEADERS = +include_bsp_HEADERS += ../../shared/include/utility.h +include_bsp_HEADERS += ../../shared/include/irq-generic.h +include_bsp_HEADERS += ../../shared/include/irq-info.h +include_bsp_HEADERS += ../../shared/include/stackalloc.h +include_bsp_HEADERS += ../../shared/include/uart-output-char.h +include_bsp_HEADERS += ../../shared/tod.h +include_bsp_HEADERS += ../shared/include/start.h +include_bsp_HEADERS += ../shared/lpc/include/lpc-timer.h +include_bsp_HEADERS += ../shared/lpc/include/lpc-i2s.h +include_bsp_HEADERS += ../shared/lpc/include/lpc-dma.h +include_bsp_HEADERS += ../shared/armv7m/include/armv7m-irq.h +include_bsp_HEADERS += include/dma.h +include_bsp_HEADERS += include/io-defs.h +include_bsp_HEADERS += include/io.h +include_bsp_HEADERS += include/common-types.h +include_bsp_HEADERS += include/gpio-defs.h +include_bsp_HEADERS += include/gpio.h +include_bsp_HEADERS += include/timer-defs.h +include_bsp_HEADERS += include/timer.h +include_bsp_HEADERS += include/watchdog.h +include_bsp_HEADERS += include/watchdog-defs.h +include_bsp_HEADERS += include/irq.h +include_bsp_HEADERS += include/lpc176x.h +include_bsp_HEADERS += include/lpc-clock-config.h +include_bsp_HEADERS += include/system-clocks.h + +include_HEADERS += ../../shared/include/tm27.h + + +# ---------------------------- +# ------ Data +# ---------------------------- + +noinst_LIBRARIES = libbspstart.a + +libbspstart_a_SOURCES = ../shared/start/start.S + +project_lib_DATA = start.$(OBJEXT) +project_lib_DATA += startup/linkcmds + +EXTRA_DIST = +EXTRA_DIST += startup/linkcmds.lpc1768_mbed +EXTRA_DIST += startup/linkcmds.lpc1768_mbed_ahb_ram + + +# ---------------------------- +# ------ LibBSP +# ---------------------------- + +noinst_LIBRARIES += libbsp.a + +libbsp_a_SOURCES = +libbsp_a_CPPFLAGS = +libbsp_a_LIBADD = + +# Shared +libbsp_a_SOURCES += ../../shared/bootcard.c +libbsp_a_SOURCES += ../../shared/bspclean.c +libbsp_a_SOURCES += ../../shared/bspgetworkarea.c +libbsp_a_SOURCES += ../../shared/bsplibc.c +libbsp_a_SOURCES += ../../shared/bsppost.c +libbsp_a_SOURCES += ../../shared/bsppredriverhook.c +libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c +libbsp_a_SOURCES += ../../shared/sbrk.c +libbsp_a_SOURCES += ../../shared/src/stackalloc.c +libbsp_a_SOURCES += ../../shared/src/uart-output-char.c + +# Startup +libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S +libbsp_a_SOURCES += startup/bspreset.c +libbsp_a_SOURCES += startup/bspstart.c + +# IRQ +libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c +libbsp_a_SOURCES += ../../shared/src/irq-generic.c +libbsp_a_SOURCES += ../../shared/src/irq-info.c +libbsp_a_SOURCES += ../../shared/src/irq-legacy.c +libbsp_a_SOURCES += ../../shared/src/irq-server.c +libbsp_a_SOURCES += ../../shared/src/irq-shell.c +libbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq.c +libbsp_a_SOURCES += ../shared/armv7m/irq/armv7m-irq-dispatch.c +libbsp_a_SOURCES += irq/irq.c + +# Console +libbsp_a_SOURCES += ../../shared/console.c +libbsp_a_SOURCES += ../../shared/console_control.c +libbsp_a_SOURCES += ../../shared/console_read.c +libbsp_a_SOURCES += ../../shared/console_select.c +libbsp_a_SOURCES += ../../shared/console_write.c +libbsp_a_SOURCES += console/console-config.c + +# Clock +libbsp_a_SOURCES += ../../shared/clockdrv_shell.h +libbsp_a_SOURCES += ../shared/lpc/clock/lpc-clock-config.c +libbsp_a_SOURCES += ../shared/armv7m/clock/armv7m-clock-config.c + +# RTC +libbsp_a_SOURCES += ../../shared/tod.c \ + rtc/rtc-config.c + +# GPIO +libbsp_a_SOURCES += gpio/gpio.c + +# Timer +libbsp_a_SOURCES += timer/timer.c + +# Benchmark Timer +libbsp_a_SOURCES += benchmark_timer/benchmark_timer.c + +# Misc +libbsp_a_SOURCES += misc/system-clocks.c +libbsp_a_SOURCES += misc/dma.c +libbsp_a_SOURCES += misc/dma-copy.c +libbsp_a_SOURCES += misc/bspidle.c +libbsp_a_SOURCES += misc/io.c +libbsp_a_SOURCES += misc/restart.c + +# Watchdog +libbsp_a_SOURCES += watchdog/watchdog.c + +# Cache +libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c +libbsp_a_SOURCES += ../../../libcpu/arm/shared/include/cache_.h +libbsp_a_CPPFLAGS += -I$(srcdir)/../../../libcpu/arm/shared/include + +# Start hooks +libbsp_a_SOURCES += startup/bspstarthooks.c + + +# ---------------------------- +# ------ Special Rules +# ---------------------------- + +DISTCLEANFILES = include/bspopts.h + +include $(srcdir)/preinstall.am +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/arm/lpc176x/README b/c/src/lib/libbsp/arm/lpc176x/README new file mode 100644 index 0000000000..d57e52fd93 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/README @@ -0,0 +1,11 @@ +Development Board: Base Board from Embedded Artists + +http://www.embeddedartists.com/products/lpcxpresso/mbed.php + +Drivers: + + o Console + o Clock + o Timer + o GPIO + o Watchdog diff --git a/c/src/lib/libbsp/arm/lpc176x/benchmark_timer/benchmark_timer.c b/c/src/lib/libbsp/arm/lpc176x/benchmark_timer/benchmark_timer.c new file mode 100644 index 0000000000..a8f2855660 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/benchmark_timer/benchmark_timer.c @@ -0,0 +1,45 @@ +/** + * @file timerbenchmark.c + * + * @ingroup lpc176x + * + * @brief Timer benchmark functions for the lpc176x bsp. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include + +#include + +static uint32_t benchmark_timer_base; + +void benchmark_timer_initialize( void ) +{ + benchmark_timer_base = lpc176x_timer_get_timer_value( LPC176X_TIMER_1 ); +} + +uint32_t benchmark_timer_read( void ) +{ + uint32_t delta = lpc176x_timer_get_timer_value( LPC176X_TIMER_1 ) - + benchmark_timer_base; + + return delta; +} + +void benchmark_timer_disable_subtracting_average_overhead( bool find_avg_ovhead ) +{ +} \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/bsp_specs b/c/src/lib/libbsp/arm/lpc176x/bsp_specs new file mode 100644 index 0000000000..082653ad22 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/bsp_specs @@ -0,0 +1,13 @@ +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*startfile: +%{!qrtems: %(old_startfile)} \ +%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N} + +*endfile: +%{!qrtems: *(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s } diff --git a/c/src/lib/libbsp/arm/lpc176x/configure.ac b/c/src/lib/libbsp/arm/lpc176x/configure.ac new file mode 100644 index 0000000000..82fa9d1710 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/configure.ac @@ -0,0 +1,71 @@ +## +# +# @file +# +# @brief Configure script of LibBSP for the LPC176X board. +# + +AC_PREREQ([2.69]) +AC_INIT([rtems-c-src-lib-libbsp-arm-lpc176x],[_RTEMS_VERSION], + [http://www.rtems.org/bugzilla]) +AC_CONFIG_SRCDIR([bsp_specs]) +RTEMS_TOP(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU +AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2]) +RTEMS_BSP_CONFIGURE + +RTEMS_PROG_CC_FOR_TARGET +RTEMS_CANONICALIZE_TOOLS +RTEMS_PROG_CCAS + +RTEMS_CHECK_NETWORKING +AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "no") + +RTEMS_BSPOPTS_SET([ARM_LPC1768],[*],[0]) +RTEMS_BSPOPTS_HELP([ARM_LPC1768],[target used for identify LPC1768 board]) + +RTEMS_BSPOPTS_SET([BSP_MINIMUM_TASK_STACK_SIZE],[*],[1024]) +RTEMS_BSPOPTS_HELP([BSP_MINIMUM_TASK_STACK_SIZE],[Suggested minimum task stack + size in bytes]) + +RTEMS_BSPOPTS_SET([BSP_SMALL_MEMORY],[*],[]) +RTEMS_BSPOPTS_HELP([BSP_SMALL_MEMORY],[disable testsuite + samples with high memory demands]) + +RTEMS_BSPOPTS_SET([LPC176X_OSCILLATOR_MAIN],[*],[12000000U]) +RTEMS_BSPOPTS_HELP([LPC176X_OSCILLATOR_MAIN],[main oscillator frequency in Hz]) + +RTEMS_BSPOPTS_SET([LPC176X_OSCILLATOR_RTC],[*],[32768U]) +RTEMS_BSPOPTS_HELP([LPC176X_OSCILLATOR_RTC],[RTC oscillator frequency in Hz]) + +RTEMS_BSPOPTS_SET([LPC176X_CCLK],[*],[96000000U]) +RTEMS_BSPOPTS_HELP([LPC176X_CCLK],[CPU clock in Hz]) + +RTEMS_BSPOPTS_SET([LPC176X_PCLKDIV],[*],[1U]) +RTEMS_BSPOPTS_HELP([LPC176X_PCLKDIV],[clock divider for default + PCLK (PCLK = CCLK / PCLKDIV)]) + +RTEMS_BSPOPTS_SET([LPC176X_UART_BAUD],[*],[9600U]) +RTEMS_BSPOPTS_HELP([LPC176X_UART_BAUD],[baud for UARTs]) + +RTEMS_BSPOPTS_SET([LPC176X_CONFIG_CONSOLE],[*],[0]) +RTEMS_BSPOPTS_HELP([LPC176X_CONFIG_CONSOLE],[configuration + for console (UART 0)]) + +RTEMS_BSPOPTS_SET([LPC176X_STOP_GPDMA],[*],[1]) +RTEMS_BSPOPTS_HELP([LPC176X_STOP_GPDMA],[stop general purpose DMA + at start-up to avoid DMA interference]) + +RTEMS_BSPOPTS_SET([LPC176X_STOP_USB],[*],[1]) +RTEMS_BSPOPTS_HELP([LPC176X_STOP_USB],[stop USB controller + at start-up to avoid DMA interference]) + +RTEMS_BSPOPTS_SET([LPC_DMA_CHANNEL_COUNT],[*],[2]) +RTEMS_BSPOPTS_HELP([LPC_DMA_CHANNEL_COUNT],[DMA channel count]) + +RTEMS_BSP_CLEANUP_OPTIONS(0, 1) +RTEMS_BSP_LINKCMDS + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/c/src/lib/libbsp/arm/lpc176x/console/console-config.c b/c/src/lib/libbsp/arm/lpc176x/console/console-config.c new file mode 100644 index 0000000000..246a9e65ae --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/console/console-config.c @@ -0,0 +1,158 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Console configuration. + */ + +/* + * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +#include +#include +#include + +/** + * @brief Gets the uart register according to the current address. + * + * @param addr Register address. + * @param i Index register. + * @return Uart register. + */ +static inline uint8_t lpc176x_uart_get_register( + const uintptr_t addr, + const uint8_t i +) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + return (uint8_t) reg[ i ]; +} + +/** + * @brief Sets the uart register address according to the value passed. + * + * @param addr Register address. + * @param i Index register. + * @param val Value to set. + */ +static inline void lpc176x_uart_set_register( + const uintptr_t addr, + const uint8_t i, + const uint8_t val +) +{ + volatile uint32_t *reg = (volatile uint32_t *) addr; + + reg[ i ] = val; +} + +/** + * @brief Represents the uart configuration ports. + */ +console_tbl Console_Configuration_Ports[] = { +#ifdef LPC176X_CONFIG_CONSOLE + { + .sDeviceName = "/dev/ttyS0", + .deviceType = SERIAL_NS16550_WITH_FDR, + .pDeviceFns = &ns16550_fns, + .deviceProbe = NULL, + .pDeviceFlow = NULL, + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) LPC176X_UART_BAUD, + .ulCtrlPort1 = UART0_BASE_ADDR, + .ulCtrlPort2 = 0, + .ulDataPort = UART0_BASE_ADDR, + .getRegister = lpc176x_uart_get_register, + .setRegister = lpc176x_uart_set_register, + .getData = NULL, + .setData = NULL, + .ulClock = LPC176X_PCLK, + .ulIntVector = LPC176X_IRQ_UART_0 + }, +#endif +#ifdef LPC176X_CONFIG_UART_1 + { + .sDeviceName = "/dev/ttyS1", + .deviceType = SERIAL_NS16550_WITH_FDR, + .pDeviceFns = &ns16550_fns, + .deviceProbe = lpc176x_uart_probe_1, + .pDeviceFlow = NULL, + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) LPC176X_UART_BAUD, + .ulCtrlPort1 = UART1_BASE_ADDR, + .ulCtrlPort2 = 0, + .ulDataPort = UART1_BASE_ADDR, + .getRegister = lpc176x_uart_get_register, + .setRegister = lpc176x_uart_set_register, + .getData = NULL, + .setData = NULL, + .ulClock = LPC176X_PCLK, + .ulIntVector = LPC176X_IRQ_UART_1 + }, +#endif +#ifdef LPC176X_CONFIG_UART_2 + { + .sDeviceName = "/dev/ttyS2", + .deviceType = SERIAL_NS16550_WITH_FDR, + .pDeviceFns = &ns16550_fns, + .deviceProbe = lpc176x_uart_probe_2, + .pDeviceFlow = NULL, + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) LPC176X_UART_BAUD, + .ulCtrlPort1 = UART2_BASE_ADDR, + .ulCtrlPort2 = 0, + .ulDataPort = UART2_BASE_ADDR, + .getRegister = lpc176x_uart_get_register, + .setRegister = lpc176x_uart_set_register, + .getData = NULL, + .setData = NULL, + .ulClock = LPC176X_PCLK, + .ulIntVector = LPC176X_IRQ_UART_2 + }, +#endif +#ifdef LPC176X_CONFIG_UART_3 + { + .sDeviceName = "/dev/ttyS3", + .deviceType = SERIAL_NS16550_WITH_FDR, + .pDeviceFns = &ns16550_fns, + .deviceProbe = lpc176x_uart_probe_3, + .pDeviceFlow = NULL, + .ulMargin = 16, + .ulHysteresis = 8, + .pDeviceParams = (void *) LPC176X_UART_BAUD, + .ulCtrlPort1 = UART3_BASE_ADDR, + .ulCtrlPort2 = 0, + .ulDataPort = UART3_BASE_ADDR, + .getRegister = lpc176x_uart_get_register, + .setRegister = lpc176x_uart_set_register, + .getData = NULL, + .setData = NULL, + .ulClock = LPC176X_PCLK, + .ulIntVector = LPC176X_IRQ_UART_3 + }, +#endif +}; + +#define LPC176X_UART_COUNT ( sizeof( Console_Configuration_Ports ) \ + / sizeof( Console_Configuration_Ports[ 0 ] ) ) + +unsigned long Console_Configuration_Count = LPC176X_UART_COUNT; diff --git a/c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c b/c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c new file mode 100644 index 0000000000..2fe69d4ea8 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c @@ -0,0 +1,392 @@ +/** + * @file gpio.c + * + * @ingroup lpc176x + * + * @brief GPIO library for the lpc176x bsp. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +static uint32_t function_vector_size = 0u; +static lpc176x_registered_interrupt_function function_vector[ + LPC176X_RESERVED_ISR_FUNCT_SIZE ]; +static bool isr_installed = false; + +rtems_status_code lpc176x_gpio_config( + const lpc176x_pin_number pin, + const lpc176x_gpio_direction dir +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( ( pin < LPC176X_MAX_PORT_NUMBER ) && + ( dir < LPC176X_GPIO_FUNCTION_COUNT ) ) { + const lpc176x_gpio_ports port = LPC176X_IO_PORT( pin ); + const uint32_t pin_of_port = LPC176X_IO_PORT_BIT( pin ); + + lpc176x_pin_select( pin, LPC176X_PIN_FUNCTION_00 ); + + LPC176X_SET_BIT( LPC176X_FIO[ port ].dir, pin_of_port, dir ); + + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the pin or the egde are out of range. Also, + an invalid number is returned. */ + + return status_code; +} + +/** + * @brief Check for a rising edge and call the interrupt function. + * + * @param statR Rising edge interrupt. + * @param pin The pin to check. + * @param registered_isr_function Interrupt to check. + * @return TRUE if is a rising edge. FALSE otherwise. + */ +static bool lpc176x_check_rising_edge_and_call( + const uint32_t statR, + const lpc176x_registered_interrupt_function registered_isr_function, + const uint32_t pin +) +{ + bool is_rising = false; + + if ( statR & LPC176X_PIN_BIT( pin ) ) { + registered_isr_function.function( registered_isr_function.pin, + LPC176X_GPIO_INTERRUPT_RISING ); + is_rising = true; + } + + /* else implies that the current interrupt is not STATR. Also, + there is nothing to do. */ + + return is_rising; +} + +/** + * @brief Check for a falling edge and call the interrupt function. + * + * @param statR Falling edge interrupt. + * @param pin The pin to check. + * @param registered_isr_function Interrupt to check. + * @return TRUE if is a falling edge. FALSE otherwise. + */ +static bool lpc176x_check_falling_edge_and_call( + const uint32_t statF, + const lpc176x_registered_interrupt_function registered_isr_function, + const uint32_t pin +) +{ + bool is_falling = false; + + if ( statF & LPC176X_PIN_BIT( pin ) ) { + registered_isr_function.function( registered_isr_function.pin, + LPC176X_GPIO_INTERRUPT_FALLING ); + is_falling = true; + } + + /* else implies that the current interrupt is not STATF. Also, + there is nothing to do. */ + + return is_falling; +} + +/** + * @brief Returns the interrupts base address according to the current port. + * + * @param port Input/Output port. + * @return Interrupt base address. + */ +static lpc176x_interrupt_control*lpc176x_get_interrupt_address( + const lpc176x_gpio_ports port ) +{ + lpc176x_interrupt_control *interrupt; + + switch ( port ) { + case ( LPC176X_GPIO_PORT_0 ): + interrupt = (lpc176x_interrupt_control *) LPC176X_IO0_INT_BASE_ADDRESS; + break; + case ( LPC176X_GPIO_PORT_2 ): + interrupt = (lpc176x_interrupt_control *) LPC176X_IO2_INT_BASE_ADDRESS; + break; + case ( LPC176X_GPIO_PORT_1 ): + case ( LPC176X_GPIO_PORT_3 ): + case ( LPC176X_GPIO_PORT_4 ): + default: + interrupt = NULL; + } + + return interrupt; +} + +/** + * @brief Checks the type of the current interrupt. + * + * @param registered_isr_function Interrupt to check. + */ +static void check_for_interrupt( + const lpc176x_registered_interrupt_function registered_isr_function ) +{ + assert( registered_isr_function.pin < LPC176X_MAX_PORT_NUMBER ); + + const lpc176x_gpio_ports port = LPC176X_IO_PORT( + registered_isr_function.pin ); + const uint32_t pin = LPC176X_IO_PORT_BIT( registered_isr_function.pin ); + + lpc176x_interrupt_control *interrupt = lpc176x_get_interrupt_address( port ); + assert( interrupt != NULL ); + + bool is_rising_edge = lpc176x_check_rising_edge_and_call( interrupt->StatR, + registered_isr_function, + pin ); + + bool is_falling_edge = lpc176x_check_falling_edge_and_call( interrupt->StatF, + registered_isr_function, + pin ); + + if ( is_rising_edge || is_falling_edge ) { + interrupt->Clr = LPC176X_PIN_BIT( pin ); + } + + /* else implies that the current interrupt is not CLR. Also, + there is nothing to do. */ +} + +/** + * @brief Checks all interrupts types. + * + * @param arg Interrupt to check. + */ +static inline void lpc176x_gpio_isr( void *arg ) +{ + unsigned int i; + + for ( i = 0; i < function_vector_size; ++i ) { + check_for_interrupt( function_vector[ i ] ); + } +} + +/** + * @brief Depending of the current edge sets rising/falling interrupt. + * + * @param edge Current edge. + * @param pin_of_port Pin of the port to set the interrupt. + * @param interrupt To enable the falling o rising edge. + */ +static void lpc176x_set_falling_or_rising_interrupt( + const lpc176x_gpio_interrupt edge, + const uint32_t pin_of_port, + lpc176x_interrupt_control *interrupt +) +{ + if ( edge & LPC176X_GPIO_INTERRUPT_RISING ) { + LPC176X_SET_BIT( interrupt->EnR, pin_of_port, LPC176X_INT_ENABLE ); + } + + /* else implies that it should not install the interrupt for a RISING edge. + Also, there is nothing to do. */ + + if ( edge & LPC176X_GPIO_INTERRUPT_FALLING ) { + LPC176X_SET_BIT( interrupt->EnF, pin_of_port, LPC176X_INT_ENABLE ); + } + + /* else implies that it should not install the interrupt for a FALLING edge. + Also, there is nothing to do. */ +} + +/** + * @brief Registers the pin and the callbacks functions. + * + * @param edge Current edge. + * @param pin The pin to configure. + * @param isr_funct Callback function to set. + */ +static void lpc176x_register_pin_and_callback( + const lpc176x_gpio_interrupt edge, + const lpc176x_pin_number pin, + const lpc176x_gpio_interrupt_function isr_funct +) +{ + if ( edge ) { + assert( function_vector_size < LPC176X_RESERVED_ISR_FUNCT_SIZE ); + function_vector[ function_vector_size ].function = isr_funct; + function_vector[ function_vector_size ].pin = pin; + ++function_vector_size; + } + + /* else implies that the current interrupt is DISABLED or BOTH. Also, + there is nothing to do. */ +} + +/** + * @brief Installs the interrupt handler. + * + * @param edge Which edge enable. + * @return RTEMS_SUCCESSFUL if the installation was success. + */ +static rtems_status_code lpc176x_install_interrupt_handler( + const lpc176x_gpio_interrupt edge ) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + + if ( !isr_installed && edge ) { + status_code = rtems_interrupt_handler_install( LPC176X_IRQ_EINT_3, + "gpio_interrupt", + RTEMS_INTERRUPT_UNIQUE, + lpc176x_gpio_isr, + NULL ); + isr_installed = true; + } + + /* else implies that the interrupts have been previously installed. Also, + there is nothing to do. */ + + return status_code; +} + +/** + * @brief Configures the pin as input, enables interrupt for an + * edge/s and sets isrfunct as the function to call when that + * interrupt occurs. + * + * @param pin The pin to configure. + * @param edge Which edge or edges will activate the interrupt. + * @param isrfunct The function that is called when the interrupt occurs. + * @return RTEMS_SUCCESSFUL if the configuration was success. + */ +static rtems_status_code lpc176x_check_edge_and_set_gpio_interrupts( + const lpc176x_pin_number pin, + const lpc176x_gpio_interrupt edge, + const lpc176x_gpio_interrupt_function isr_funct +) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + + const lpc176x_gpio_ports port = LPC176X_IO_PORT( pin ); + const uint32_t pin_of_port = LPC176X_IO_PORT_BIT( pin ); + + lpc176x_interrupt_control *interrupt = lpc176x_get_interrupt_address( port ); + + assert( interrupt != NULL ); + + lpc176x_gpio_config( pin, LPC176X_GPIO_FUNCTION_INPUT ); + + lpc176x_set_falling_or_rising_interrupt( edge, pin_of_port, interrupt ); + + lpc176x_register_pin_and_callback( edge, pin, isr_funct ); + + status_code = lpc176x_install_interrupt_handler( edge ); + + return status_code; +} + +rtems_status_code lpc176x_gpio_config_input_with_interrupt( + const lpc176x_pin_number pin, + const lpc176x_gpio_interrupt edge, + const lpc176x_gpio_interrupt_function isr_funct +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( ( pin < LPC176X_MAX_PORT_NUMBER ) + && ( edge < LPC176X_GPIO_INTERRUPT_COUNT ) ) { + status_code = lpc176x_check_edge_and_set_gpio_interrupts( pin, + edge, + isr_funct ); + } + + /* else implies that the pin or the egde are out of range. Also, + an invalid number is returned. */ + + return status_code; +} + +rtems_status_code lpc176x_gpio_set_pin( const lpc176x_pin_number pin ) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( pin < LPC176X_MAX_PORT_NUMBER ) { + const lpc176x_gpio_ports port = LPC176X_IO_PORT( pin ); + const uint32_t pin_of_port = LPC176X_IO_PORT_BIT( pin ); + + LPC176X_FIO[ port ].set = LPC176X_PIN_BIT( pin_of_port ); + + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the pin or the egde are out of range. Also, + an invalid number is returned. */ + + return status_code; +} + +rtems_status_code lpc176x_gpio_clear_pin( const lpc176x_pin_number pin ) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( pin < LPC176X_MAX_PORT_NUMBER ) { + const lpc176x_gpio_ports port = LPC176X_IO_PORT( pin ); + const uint32_t pin_of_port = LPC176X_IO_PORT_BIT( pin ); + + LPC176X_FIO[ port ].clr = LPC176X_PIN_BIT( pin_of_port ); + + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the pin or the egde are out of range. Also, + an invalid number is returned. */ + + return status_code; +} + +rtems_status_code lpc176x_gpio_write_pin( + const lpc176x_pin_number pin, + const bool value +) +{ + rtems_status_code status_code; + + if ( value ) { + status_code = lpc176x_gpio_set_pin( pin ); + } else { + status_code = lpc176x_gpio_clear_pin( pin ); + } + + return status_code; +} + +inline rtems_status_code lpc176x_gpio_get_pin_value( + const lpc176x_pin_number pin, + bool *pin_value +) +{ + assert( pin < LPC176X_MAX_PORT_NUMBER ); + + rtems_status_code status_code = RTEMS_SUCCESSFUL; + + const lpc176x_gpio_ports port = LPC176X_IO_PORT( pin ); + const uint32_t pin_of_port = LPC176X_IO_PORT_BIT( pin ); + *pin_value = ( LPC176X_FIO[ port ].pin & LPC176X_PIN_BIT( pin_of_port ) ); + + return status_code; +} diff --git a/c/src/lib/libbsp/arm/lpc176x/include/bsp.h b/c/src/lib/libbsp/arm/lpc176x/include/bsp.h new file mode 100644 index 0000000000..89c5c40045 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/bsp.h @@ -0,0 +1,100 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Global BSP definitions. + */ + +/* + * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_BSP_H +#define LIBBSP_ARM_LPC176X_BSP_H + +#include + +#define LPC176X_PCLK ( LPC176X_CCLK / LPC176X_PCLKDIV ) +#define LPC176X_MPU_REGION_COUNT 8u + +#define BSP_FEATURE_IRQ_EXTENSION +#define BSP_ARMV7M_IRQ_PRIORITY_DEFAULT ( 29u << 3u ) +#define BSP_ARMV7M_SYSTICK_PRIORITY ( 30u << 3u ) +#define BSP_ARMV7M_SYSTICK_FREQUENCY LPC176X_CCLK + +#ifndef ASM + +#include +#include +#include +#include + +/** Define operation count for Tests */ +#define OPERATION_COUNT 4 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct rtems_bsdnet_ifconfig; + +/** + * @defgroup lpc176x LPC176X Support + * + * @ingroup bsp_arm + * + * @brief LPC176X support package. + * + * @{ + */ + +/** + * @brief Optimized idle task. + * + * This idle task sets the power mode to idle. This causes the processor + * clock to be stopped, while on-chip peripherals remain active. + * Any enabled interrupt from a peripheral or an external interrupt source + * will cause the processor to resume execution. + * + * To enable the idle task use the following in the system configuration: + * + * @code + * #include + * + * #define CONFIGURE_INIT + * + * #define CONFIGURE_IDLE_TASK_BODY bsp_idle_thread + * + * #include + * @endcode + */ +void*bsp_idle_thread( uintptr_t ignored ); + +#define BSP_CONSOLE_UART_BASE 0x4000C000U + +/** + * @brief Restarts the bsp with "addr" address + * @param addr Address used to restart the bsp + */ +void bsp_restart( const void *addr ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ASM */ + +#endif /* LIBBSP_ARM_LPC176X_BSP_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/common-types.h b/c/src/lib/libbsp/arm/lpc176x/include/common-types.h new file mode 100644 index 0000000000..dec487c68d --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/common-types.h @@ -0,0 +1,117 @@ +/** + * @file common-types.h + * + * @ingroup lpc176x + * + * @brief Definitions types used by some devices in common. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_COMMON_TYPES_H +#define LIBBSP_ARM_LPC176X_COMMON_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief A pin of the board. + */ +typedef uint32_t lpc176x_pin_number; + +/** + * @brief Microseconds representation. + */ +typedef uint32_t lpc176x_microseconds; + +/** + * @brief lpc176x module representation. + * + * Enumerated type to define the set of modules for a lpc176x board. + */ +typedef enum { + LPC176X_MODULE_WD, + LPC176X_MODULE_ADC, + LPC176X_MODULE_CAN_0, + LPC176X_MODULE_CAN_1, + LPC176X_MODULE_DAC, + LPC176X_MODULE_GPDMA, + LPC176X_MODULE_GPIO, + LPC176X_MODULE_I2S, + LPC176X_MODULE_MCI, + LPC176X_MODULE_MCPWM, + LPC176X_MODULE_PCB, + LPC176X_MODULE_PWM_0, + LPC176X_MODULE_PWM_1, + LPC176X_MODULE_QEI, + LPC176X_MODULE_RTC, + LPC176X_MODULE_SYSCON, + LPC176X_MODULE_TIMER_0, + LPC176X_MODULE_TIMER_1, + LPC176X_MODULE_TIMER_2, + LPC176X_MODULE_TIMER_3, + LPC176X_MODULE_UART_0, + LPC176X_MODULE_UART_1, + LPC176X_MODULE_UART_2, + LPC176X_MODULE_UART_3, + LPC176X_MODULE_USB +} lpc176x_module; + +/** + * @brief Defines all the clock modules. + * + * Enumerated type to define the set of clock modules for a lpc176x board. + */ +typedef enum { + LPC176X_MODULE_PCLK_DEFAULT = 0x4U, + LPC176X_MODULE_CCLK = 0x1U, + LPC176X_MODULE_CCLK_2 = 0x2U, + LPC176X_MODULE_CCLK_4 = 0x0U, + LPC176X_MODULE_CCLK_6 = 0x3U, + LPC176X_MODULE_CCLK_8 = 0x3U +} lpc176x_module_clock; + +/** + * @brief Fast Input/Output registers representation. + */ +typedef struct { + /** + * @brief Direction control register. + */ + uint32_t dir; + uint32_t reserved[ 3U ]; + /** + * @brief Mask register for port. + */ + uint32_t mask; + /** + * @brief Pinvalue register using 'mask'. + */ + uint32_t pin; + /** + * @brief Output Set register using 'mask'. + */ + uint32_t set; + /** + * @brief Output Clear register using 'maks'. + */ + uint32_t clr; +} lpc176x_fio; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_COMMON_TYPES_H */ \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/include/dma.h b/c/src/lib/libbsp/arm/lpc176x/include/dma.h new file mode 100644 index 0000000000..c7c84d1004 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/dma.h @@ -0,0 +1,98 @@ +/** + * @file + * + * @ingroup lpc176x_dma + * + * @brief Direct memory access (DMA) support. + */ + +/* + * Copyright (c) 2008, 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_DMA_H +#define LIBBSP_ARM_LPC176X_DMA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup lpc176x_dma DMA Support + * + * @ingroup lpc176x + * + * @brief Direct memory access (DMA) support. + * + * @{ + */ + +/** + * @brief Initializes the general purpose DMA. + */ +void lpc176x_dma_initialize( void ); + +/** + * @brief Tries to obtain the DMA channel @a channel. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid channel number. + * @retval RTEMS_RESOURCE_IN_USE Channel already occupied. + */ +rtems_status_code lpc176x_dma_channel_obtain( unsigned channel ); + +/** + * @brief Releases the DMA channel @a channel. + * + * You must have obtained this channel with lpc176x_dma_channel_obtain() + * previously. + * + * If the channel number @a channel is out of range nothing will happen. + */ +void lpc176x_dma_channel_release( unsigned channel ); + +/** + * @brief Disables the DMA channel @a channel. + * + * If @a force is @c false the channel will be halted and disabled when the + * channel is inactive otherwise it will be disabled immediately. + * + * If the channel number @a channel is out of range nothing will happen. + */ +void lpc176x_dma_channel_disable( + unsigned channel, + bool force +); + +rtems_status_code lpc176x_dma_copy_initialize( void ); + +rtems_status_code lpc176x_dma_copy_release( void ); + +rtems_status_code lpc176x_dma_copy( + unsigned channel, + const void *dest, + const void *src, + size_t n, + size_t width +); + +rtems_status_code lpc176x_dma_copy_wait( unsigned channel ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_DMA_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h b/c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h new file mode 100644 index 0000000000..b185ae2257 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h @@ -0,0 +1,218 @@ +/** + * @file gpio-defs.h + * + * @ingroup lpc176x + * + * @brief API definitions of the GPIO driver for the lpc176x bsp in RTEMS. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_GPIO_DEFS_H +#define LIBBSP_ARM_LPC176X_GPIO_DEFS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* General Purpose Input/Output (GPIO) */ +#define LPC176X_GPIO_BASE_ADDR 0x40028000U +#define LPC176X_GPIO_INTERRUPT_STATUS 0x40028080U + +#define LPC176X_IOPIN0 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x00U ) ) +#define LPC176X_IOSET0 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x04U ) ) +#define LPC176X_IODIR0 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x08U ) ) +#define LPC176X_IOCLR0 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x0CU ) ) +#define LPC176X_IOPIN1 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x10U ) ) +#define LPC176X_IOSET1 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x14U ) ) +#define LPC176X_IODIR1 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x18U ) ) +#define LPC176X_IOCLR1 ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR + \ + 0x1CU ) ) + +/* GPIO Interrupt Registers */ +#define LPC176X_IO0_INT_EN_R ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0x90U ) ) +#define LPC176X_IO0_INT_EN_F ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0x94U ) ) +#define LPC176X_IO0_INT_STAT_R ( *(volatile uint32_t *) ( \ + LPC176X_GPIO_BASE_ADDR \ + + 0x84U ) ) +#define LPC176X_IO0_INT_STAT_F ( *(volatile uint32_t *) ( \ + LPC176X_GPIO_BASE_ADDR \ + + 0x88U ) ) +#define LPC176X_IO0_INT_CLR ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0x8CU ) ) +#define LPC176X_IO2_INT_EN_R ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0xB0U ) ) +#define LPC176X_IO2_INT_EN_F ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0xB4U ) ) +#define LPC176X_IO2_INT_STAT_R ( *(volatile uint32_t *) ( \ + LPC176X_GPIO_BASE_ADDR \ + + 0xA4U ) ) +#define LPC176X_IO2_INT_STAT_F ( *(volatile uint32_t *) ( \ + LPC176X_GPIO_BASE_ADDR \ + + 0xA8U ) ) +#define LPC176X_IO2_INT_CLR ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0xACU ) ) +#define LPC176X_IO_INT_STAT ( *(volatile uint32_t *) ( LPC176X_GPIO_BASE_ADDR \ + + 0x80U ) ) + +#define LPC176X_RESERVED_ISR_FUNCT_SIZE 2U +#define LPC176X_RESERVED_ISR_FUNCT_MAX_SIZE 5U + +#define LPC176X_MAX_PORT_NUMBER 160U +#define LPC176X_SET_BIT( reg, pin, value ) \ + reg = ( reg & ~( 1U << pin ) ) | ( ( value & 1U ) << pin ) + +#define LPC176X_INT_STATUS ( *(volatile uint32_t *) \ + ( LPC176X_GPIO_INTERRUPT_STATUS ) ) +#define LPC176X_INT_STATUS_P0 1U +#define LPC176X_INT_STATUS_P2 ( 1U << 2U ) +#define LPC176X_INT_ENABLE 1U +#define LPC176X_INT_DISABLE 0U + +#define LPC176X_IRQ_EINT_3 21U + +#define LPC176X_PIN_BIT( pin ) ( 1U << pin ) + +/** + * @brief The direction of the GPIO port (input or output). + * + * Enumerated type to define the set of function types for a gpio device. + */ +typedef enum { + LPC176X_GPIO_FUNCTION_INPUT, + LPC176X_GPIO_FUNCTION_OUTPUT, + LPC176X_GPIO_FUNCTION_COUNT +} +lpc176x_gpio_direction; + +/** + * @brief The interrupt sources edge for a GPIO. + * + * Enumerated type to define the set of interrupt types for a gpio device. + */ +typedef enum { + LPC176X_GPIO_INTERRUPT_DISABLE, + LPC176X_GPIO_INTERRUPT_RISING, + LPC176X_GPIO_INTERRUPT_FALLING, + LPC176X_GPIO_INTERRUPT_BOTH, + LPC176X_GPIO_INTERRUPT_COUNT +} lpc176x_gpio_interrupt; + +/** + * @brief The ports for a GPIO. + * + * Enumerated type to define the set of ports for a gpio device. + */ +typedef enum { + LPC176X_GPIO_PORT_0, + LPC176X_GPIO_PORT_1, + LPC176X_GPIO_PORT_2, + LPC176X_GPIO_PORT_3, + LPC176X_GPIO_PORT_4, + LPC176X_GPIO_PORTS_COUNT +} lpc176x_gpio_ports; + +/** + * @brief Addresses for a GPIO. + * + * Enumerated type to define the set of fio bases addresses + * for a gpio device. + */ +typedef enum { + LPC176X_FIO0_BASE_ADDRESS = 0x2009C000U, + LPC176X_FIO1_BASE_ADDRESS = 0x2009C020U, + LPC176X_FIO2_BASE_ADDRESS = 0x2009C040U, + LPC176X_FIO3_BASE_ADDRESS = 0x2009C060U, + LPC176X_FIO4_BASE_ADDRESS = 0x2009C080U, +} lpc176x_gpio_address; + +/** + * @brief Addresses for the two interrupts. + * + * Enumerated type to define the set of interrupt addresses + * for a gpio device. + */ +typedef enum { + LPC176X_IO0_INT_BASE_ADDRESS = 0x40028084U, + LPC176X_IO2_INT_BASE_ADDRESS = 0x400280A4U, +} lpc176x_interrupt_address; + +/** + * @brief GPIO Interrupt register map. + */ +typedef struct { + /** + * @brief Interrupt Enable for Rising edge. + */ + volatile uint32_t StatR; + /** + * @brief Interrupt Enable for Falling edge. + */ + volatile uint32_t StatF; + /** + * @brief Interrupt Clear. + */ + volatile uint32_t Clr; + /** + * @brief Interrupt Enable for Rising edge. + */ + volatile uint32_t EnR; + /** + * @brief Interrupt Enable for Falling edge. + */ + volatile uint32_t EnF; +} lpc176x_interrupt_control; + +/** + * @brief A function that attends an interrupt for GPIO. + * + * @param pin Pin number. + * @param edge Interrupt. + * @return Pointer to the interrupt function. + */ +typedef void (*lpc176x_gpio_interrupt_function) ( + const lpc176x_pin_number pin, + const lpc176x_gpio_interrupt edge +); + +/** + * @brief A registered interrupt function for the pin 'pin'. + */ +typedef struct { + /** + * @brief Pin board. + */ + lpc176x_pin_number pin; + /** + * @brief A function that attends an interrupt for 'pin'. + */ + lpc176x_gpio_interrupt_function function; +} lpc176x_registered_interrupt_function; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_GPIO_DEFS_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/gpio.h b/c/src/lib/libbsp/arm/lpc176x/include/gpio.h new file mode 100644 index 0000000000..af5f9ec09c --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/gpio.h @@ -0,0 +1,100 @@ +/** + * @file gpio.h + * + * @ingroup lpc176x + * + * @brief API of the GPIO driver for the lpc176x bsp in RTEMS. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_GPIO_H +#define LIBBSP_ARM_LPC176X_GPIO_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Configures the pin as input or output GPIO. + * + * @param pin The pin to configure + * @param dir Input or output. + */ +rtems_status_code lpc176x_gpio_config( + lpc176x_pin_number pin, + lpc176x_gpio_direction dir +); + +/** + * @brief Configures the pin as input, enables interrupt for an + * edge/s and sets isrfunct as the function to call when that + * interrupt occurs. + * + * @param pin The pin to configure. + * @param edge Which edge or edges will activate the interrupt. + * @param isrfunct The function that is called when the interrupt occurs. + * @return RTEMS_SUCCESSFULL if the configurations was success. + */ +rtems_status_code lpc176x_gpio_config_input_with_interrupt( + lpc176x_pin_number pin, + lpc176x_gpio_interrupt edge, + lpc176x_gpio_interrupt_function isrfunct +); + +/** + * @brief Sets the output pin to 1. + * + * @param pin The pin to set + */ +rtems_status_code lpc176x_gpio_set_pin( lpc176x_pin_number pin ); + +/** + * @brief Sets the output pin to 0. + * + * @param pin The pin to set + */ +rtems_status_code lpc176x_gpio_clear_pin( lpc176x_pin_number pin ); + +/** + * @brief Sets the output pin to 0 or 1 according to value. + * + * @param pin The pin to set + * @param value the value to set. + */ +rtems_status_code lpc176x_gpio_write_pin( + lpc176x_pin_number pin, + bool value +); + +/** + * @brief Returns the value at the given input pin. + * + * @param pin The pin where to read the value. + * @param pin_value TRUE if the pin value was getted successfuly. + * @return RTEMS_SUCCESSFUL if the pin value was getted successfuly. + */ +rtems_status_code lpc176x_gpio_get_pin_value( + lpc176x_pin_number pin, + bool *pin_value +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_GPIO_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/io-defs.h b/c/src/lib/libbsp/arm/lpc176x/include/io-defs.h new file mode 100644 index 0000000000..a0afdf47ae --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/io-defs.h @@ -0,0 +1,123 @@ +/** + * @file io-defs.h + * + * @ingroup lpc176x + * + * @brief Input/output module definitions. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_IO_DEFS_H +#define LIBBSP_ARM_LPC176X_IO_DEFS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define LPC176X_PLL0CON 0XAAU +#define LPC176X_PLL0CFG 0X55U + +#define LPC176X_CCLK_PRESCALER_DIVISOR 1000000U + +#define LPC176X_PINSEL ( &PINSEL0 ) +#define LPC176X_PINMODE ( &PINMODE0 ) + +#define LPC176X_PIN_SELECT( index ) ( ( index ) >> 4U ) +#define LPC176X_PIN_SELECT_SHIFT( index ) ( ( ( index ) & 0xFU ) << 1U ) +#define LPC176X_PIN_SELECT_MASK 0x3U +#define LPC176X_PIN_SELECT_MASK_SIZE 2U +#define LPC176X_PIN_UART_0_TXD 2U +#define LPC176X_PIN_UART_0_RXD 3U + +#define LPC176X_MODULE_BITS_COUNT 32U +#define LPC176X_MODULE_COUNT ( LPC176X_MODULE_USB + 1U ) + +#define LPC176X_IO_PORT_COUNT 5U +#define LPC176X_IO_INDEX_MAX ( LPC176X_IO_PORT_COUNT * \ + LPC176X_MODULE_BITS_COUNT ) +#define LPC176X_IO_INDEX_BY_PORT( port, bit ) ( ( ( port ) << 5U ) + ( bit ) ) +#define LPC176X_IO_PORT( index ) ( ( index ) >> 5U ) +#define LPC176X_IO_PORT_BIT( index ) ( ( index ) & 0x1FU ) + +/** + * @brief Defines the functions according to the pin. + * + * Enumerated type to define the set of pin function for a io device. + */ +typedef enum { + LPC176X_PIN_FUNCTION_00, + LPC176X_PIN_FUNCTION_01, + LPC176X_PIN_FUNCTION_10, + LPC176X_PIN_FUNCTION_11, + LPC176X_PIN_FUNCTION_COUNT +} +lpc176x_pin_function; + +/** + * @brief Defines all type of pins. + * + * Enumerated type to define the set of pin type for a io device. + */ +typedef enum { + LPC176X_PIN_TYPE_DEFAULT, + LPC176X_PIN_TYPE_ADC, + LPC176X_PIN_TYPE_DAC, + LPC176X_PIN_TYPE_OPEN_DRAIN +} lpc176x_pin_type; + +/** + * @brief Represents each pclksel number. + * + * Enumerated type to define the set of values for a pcklsel. + */ +typedef enum { + LPC176X_SCB_PCLKSEL0, + LPC176X_SCB_PCLKSEL1, + LPC176X_SCB_PCLKSEL_COUNT +} lpc176x_scb_value_pclksel; + +/** + * @brief Defines the module entry. + */ +typedef struct { + /** + * @brief Power entry bit. + */ + unsigned char power : 1; + /** + * @brief Clock entry bit. + */ + unsigned char clock : 1; + /** + * @brief Index entry bits. + */ + unsigned char index : 6; +} lpc176x_module_entry; + +#define LPC176X_MODULE_ENTRY( mod, pwr, clk, idx ) \ + [ mod ] = { \ + .power = pwr, \ + .clock = clk, \ + .index = idx \ + } + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_IO_DEFS_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/io.h b/c/src/lib/libbsp/arm/lpc176x/include/io.h new file mode 100644 index 0000000000..e7c0dd0d58 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/io.h @@ -0,0 +1,77 @@ +/** + * @file io.h + * + * @ingroup lpc176x + * + * @brief Input/output module methods definitions. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_IO_H +#define LIBBSP_ARM_LPC176X_IO_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Set pin to the selected function. + * + * @param pin The pin to set. + * @param function Defines the function to set. + */ +void lpc176x_pin_select( + uint32_t pin, + lpc176x_pin_function function +); + +/** + * @brief Enables the module power and clock. + * + * @param module Represents the module to be enabled. + * @param clock Represents the clock to set for this module. + * @return RTEMS_SUCCESFULL if the module was enabled succesfully. + */ +rtems_status_code lpc176x_module_enable( + lpc176x_module module, + lpc176x_module_clock clock +); + +/** + * @brief Checks if the current module is turned off and disables a module. + * + * @param module Represents the module to be disabled. + * @return RTEMS_SUCCESFULL if the module was disabled succesfully. + */ +rtems_status_code lpc176x_module_disable( lpc176x_module module ); + +/** + * @brief Checks if the current module is enabled or not. + * + * @param module Represents the module to be checked. + * @return TRUE if the module is enabled. + * FALSE otherwise. + */ +bool lpc176x_module_is_enabled( lpc176x_module module ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_IO_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/irq.h b/c/src/lib/libbsp/arm/lpc176x/include/irq.h new file mode 100644 index 0000000000..99032d0a55 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/irq.h @@ -0,0 +1,108 @@ +/** + * @file + * + * @ingroup bsp_interrupt + * + * @brief LPC176X interrupt definitions. + */ + +/* + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_IRQ_H +#define LIBBSP_ARM_LPC176X_IRQ_H + +#ifndef ASM +#include +#include +#include +#endif + +/** + * @addtogroup bsp_interrupt + * + * @{ + */ + +#define BSP_INTERRUPT_VECTOR_MIN 0U + +#define LPC176X_IRQ_WDT 0U +#define LPC176X_IRQ_TIMER_0 1U +#define LPC176X_IRQ_TIMER_1 2U +#define LPC176X_IRQ_TIMER_2 3U +#define LPC176X_IRQ_TIMER_3 4U +#define LPC176X_IRQ_UART_0 5U +#define LPC176X_IRQ_UART_1 6U +#define LPC176X_IRQ_UART_2 7U +#define LPC176X_IRQ_UART_3 8U +#define LPC176X_IRQ_PWM_1 9U +#define LPC176X_IRQ_PLL 16U +#define LPC176X_IRQ_RTC 17U +#define LPC176X_IRQ_EINT_0 18U +#define LPC176X_IRQ_EINT_1 19U +#define LPC176X_IRQ_EINT_2 20U +#define LPC176X_IRQ_EINT_3 21U +#define LPC176X_IRQ_ADC_0 22U +#define LPC176X_IRQ_BOD 23U +#define LPC176X_IRQ_USB 24U +#define LPC176X_IRQ_CAN 25U +#define LPC176X_IRQ_DMA 26U +#define LPC176X_IRQ_I2S 27U +#define LPC176X_IRQ_SD_MMC 29U +#define LPC176X_IRQ_MCPWM 30U +#define LPC176X_IRQ_QEI 31U +#define LPC176X_IRQ_PLL_ALT 32U +#define LPC176X_IRQ_USB_ACTIVITY 33U +#define LPC176X_IRQ_CAN_ACTIVITY 34U +#define LPC176X_IRQ_UART_4 35U +#define LPC176X_IRQ_GPIO 38U +#define LPC176X_IRQ_PWM 39U +#define LPC176X_IRQ_EEPROM 40U + +#define BSP_INTERRUPT_VECTOR_MAX 40 + +#define LPC176X_IRQ_PRIORITY_VALUE_MIN 0U + +#define LPC176X_IRQ_PRIORITY_VALUE_MAX 31U + +#define LPC176X_IRQ_PRIORITY_COUNT ( LPC176X_IRQ_PRIORITY_VALUE_MAX + 1U ) +#define LPC176X_IRQ_PRIORITY_HIGHEST LPC176X_IRQ_PRIORITY_VALUE_MIN +#define LPC176X_IRQ_PRIORITY_LOWEST LPC176X_IRQ_PRIORITY_VALUE_MAX + +#ifndef ASM + +/** + * @brief Sets the priority according to the current interruption. + * + * @param vector Interrupt to be attended. + * @param priority Interrupts priority. + */ +void lpc176x_irq_set_priority( + rtems_vector_number vector, + unsigned priority +); + +/** + * @brief Gets the priority number according to the current interruption. + * + * @param vector Interrupts to be attended. + * @return The priority number according to the current interruption. + */ +unsigned lpc176x_irq_get_priority( rtems_vector_number vector ); + +#endif /* ASM */ + +/** @} */ + +#endif /* LIBBSP_ARM_LPC176X_IRQ_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h b/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h new file mode 100644 index 0000000000..22b5747134 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Clock driver configuration. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_LPC_CLOCK_CONFIG_H +#define LIBBSP_ARM_LPC176X_LPC_CLOCK_CONFIG_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define LPC_CLOCK_INTERRUPT LPC176X_IRQ_TIMER_0 +#define LPC_CLOCK_TIMER_BASE TMR0_BASE_ADDR +#define LPC_CLOCK_REFERENCE LPC176X_PCLK +#define LPC_CLOCK_MODULE_ENABLE() \ + lpc176x_module_enable( LPC176X_MODULE_TIMER_0, LPC176X_MODULE_PCLK_DEFAULT ) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_LPC_CLOCK_CONFIG_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h b/c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h new file mode 100644 index 0000000000..951c33bc9d --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h @@ -0,0 +1,1585 @@ +/** + * @file lpc176x.h + * + * @ingroup lpc176x + * + * @brief Specific register definitions according to lpc176x family boards. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_H +#define LIBBSP_ARM_LPC176X_H + +#include + +#define LPC176X_PLL_CON_PLLE BSP_BIT32( 0 ) +#define LPC176X_PLL_CON_PLLC BSP_BIT32( 1 ) +#define LPC176X_PLL_SEL_MSEL( val ) BSP_FLD32( val, 0, 14 ) +#define LPC176X_PLL_SEL_MSEL_GET( reg ) BSP_FLD32GET( reg, 0, 14 ) +#define LPC176X_PLL_SEL_MSEL_SET( reg, val ) BSP_FLD32SET( reg, val, 0, 14 ) +#define LPC176X_PLL_SEL_PSEL( val ) BSP_FLD32( val, 16, 23 ) +#define LPC176X_PLL_SEL_PSEL_GET( reg ) BSP_FLD32GET( reg, 16, 23 ) +#define LPC176X_PLL_SEL_PSEL_SET( reg, val ) BSP_FLD32SET( reg, val, 16, 23 ) +#define LPC176X_PLL_STAT_PLLE BSP_BIT32( 24 ) +#define LPC176X_PLL_STAT_PLLC BSP_BIT32( 25 ) +#define LPC176X_PLL_STAT_PLOCK BSP_BIT32( 26 ) + +/** + * @brief Phase-Locked Loop representation. + */ +typedef struct { + /** + * @brief PLL Control Register. + */ + uint32_t con; + /** + * @brief PLL Configuration Register. + */ + uint32_t cfg; + /** + * @brief PLL Status Register. + */ + uint32_t stat; + /** + * @brief PLL Feed Register. + */ + uint32_t feed; +} lpc176x_pll; + +#define LPC176X_SCB_BASE_ADDR 0x400FC000U +#define LPC176X_SCB_FLASHCFG_FLASHTIM( val ) BSP_FLD32( val, 12, 15 ) +#define LPC176X_SCB_FLASHCFG_FLASHTIM_GET( reg ) BSP_FLD32GET( reg, 12, 15 ) +#define LPC176X_SCB_FLASHCFG_FLASHTIM_SET( reg, val ) BSP_FLD32SET( reg, val, \ + 12, 15 ) +#define LPC176X_SCB_MEMMAP_MAP BSP_BIT32( 0 ) +/* POWER MODE CONTROL REGISTER (PCON) */ +/* Power mode control bit 0 */ +#define LPC176X_SCB_PCON_PM0 BSP_BIT32( 0 ) +/* Power mode control bit 1 */ +#define LPC176X_SCB_PCON_PM1 BSP_BIT32( 1 ) +/* Brown-Out Reduced ower Down */ +#define LPC176X_SCB_PCON_BODRPM BSP_BIT32( 2 ) +/* Brown-Out Global Disable */ +#define LPC176X_SCB_PCON_BOGD BSP_BIT32( 3 ) +/* Brown-Out Reset Disable */ +#define LPC176X_SCB_PCON_BORD BSP_BIT32( 4 ) +/* Sleep Mode entry flag */ +#define LPC176X_SCB_PCON_SMFLAG BSP_BIT32( 8 ) +/* Deep Sleep entry flag */ +#define LPC176X_SCB_PCON_DSFLAG BSP_BIT32( 9 ) +/* Power-Down entry flag */ +#define LPC176X_SCB_PCON_PDFLAG BSP_BIT32( 10 ) +/* Deep Power-Down entry flag */ +#define LPC176X_SCB_PCON_DPDFLAG BSP_BIT32( 11 ) +/* POWER CONTROL for PERIPHERALS REGISTER (PCONP) */ +/* 0 - Reserved */ +/* Timer/Counter 0 power/clock control bit */ +#define LPC176X_SCB_PCONP_TIMER_0 BSP_BIT32( 1 ) +/* Timer/Counter 1 power/clock control bit */ +#define LPC176X_SCB_PCONP_TIMER_1 BSP_BIT32( 2 ) +/* UART 0 power/clock control bit */ +#define LPC176X_SCB_PCONP_UART_0 BSP_BIT32( 3 ) +/* UART 1 power/clock control bit */ +#define LPC176X_SCB_PCONP_UART_1 BSP_BIT32( 4 ) +/* 5 - Reserved */ +/* PWM 1 power/clock control bit */ +#define LPC176X_SCB_PCONP_PWM_0 BSP_BIT32( 6 ) +/* The I2C0 interface power/clock control bit */ +#define LPC176X_SCB_PCONP_I2C_0 BSP_BIT32( 7 ) +/* The SPI interface power/clock control bit */ +#define LPC176X_SCB_PCONP_SPI BSP_BIT32( 8 ) +/* The RTC power/clock control bit */ +#define LPC176X_SCB_PCONP_RTC BSP_BIT32( 9 ) +/* The SSP1 interface power/clock control bit */ +#define LPC176X_SCB_PCONP_SSP_1 BSP_BIT32( 10 ) +/* 11 - Reserved */ +/* A/D converter (ADC) power/clock control bit */ +#define LPC176X_SCB_PCONP_ADC BSP_BIT32( 12 ) +/* CAN Controller 1 power/clock control bit */ +#define LPC176X_SCB_PCONP_CAN_1 BSP_BIT32( 13 ) +/* CAN Controller 2 power/clock control bit */ +#define LPC176X_SCB_PCONP_CAN_2 BSP_BIT32( 14 ) +/* Power/clock control bit for IOCON, GPIO, and GPIO interrupts*/ +#define LPC176X_SCB_PCONP_GPIO BSP_BIT32( 15 ) +/* Repetitive Interrupt Timer power/clock control bit */ +#define LPC176X_SCB_PCONP_RIT BSP_BIT32( 16 ) +/* Motor Control PWM */ +#define LPC176X_SCB_PCONP_MCPWM BSP_BIT32( 17 ) +/* Quadrate Encoder Interface power/clock control bit */ +#define LPC176X_SCB_PCONP_QEI BSP_BIT32( 18 ) +/* The IC21 interface power/clock control bit */ +#define LPC176X_SCB_PCONP_I2C_1 BSP_BIT32( 19 ) +/* 20 - Reserved */ +/* The SSP0 interface power/clock control bit */ +#define LPC176X_SCB_PCONP_SSP_0 BSP_BIT32( 21 ) +/* Timer 2 power/clock control bit */ +#define LPC176X_SCB_PCONP_TIMER_2 BSP_BIT32( 22 ) +/* Timer 3 power/clock control bit */ +#define LPC176X_SCB_PCONP_TIMER_3 BSP_BIT32( 23 ) +/* UART 2 power/clock control bit */ +#define LPC176X_SCB_PCONP_UART_2 BSP_BIT32( 24 ) +/* UART 3 power/clock control bit */ +#define LPC176X_SCB_PCONP_UART_3 BSP_BIT32( 25 ) +/* I2C interface 2 power/clock control bit */ +#define LPC176X_SCB_PCONP_I2C_2 BSP_BIT32( 26 ) +/* I2S interface power/clock control bit */ +#define LPC176X_SCB_PCONP_I2S BSP_BIT32( 27 ) +/* 28 - Reserved */ +/* GPDMA function power/clock control bit */ +#define LPC176X_SCB_PCONP_GPDMA BSP_BIT32( 29 ) +/* Ethernet block power/clock control bit */ +#define LPC176X_SCB_PCONP_ENET BSP_BIT32( 30 ) +/* USB interface power/clock control bit */ +#define LPC176X_SCB_PCONP_USB BSP_BIT32( 31 ) +#define LPC176X_SCB_CCLKSEL_CCLKDIV( val ) BSP_FLD32( val, 0, 7 ) +#define LPC176X_SCB_CCLKSEL_CCLKDIV_GET( reg ) BSP_FLD32GET( reg, 0, 7 ) +#define LPC176X_SCB_CCLKSEL_CCLKDIV_SET( reg, val ) BSP_FLD32SET( reg, \ + val, \ + 0, \ + 7 ) +#define LPC176X_SCB_CCLKSEL_CCLKSEL BSP_BIT32( 8 ) +#define LPC176X_SCB_USBCLKSEL_USBDIV( val ) BSP_FLD32( val, 0, 4 ) +#define LPC176X_SCB_USBCLKSEL_USBDIV_GET( reg ) BSP_FLD32GET( reg, 0, 4 ) +#define LPC176X_SCB_USBCLKSEL_USBDIV_SET( reg, val ) BSP_FLD32SET( reg, \ + val, \ + 0, \ + 4 ) +#define LPC176X_SCB_USBCLKSEL_USBSEL( val ) BSP_FLD32( val, 8, 9 ) +#define LPC176X_SCB_USBCLKSEL_USBSEL_GET( reg ) BSP_FLD32GET( reg, 8, 9 ) +#define LPC176X_SCB_USBCLKSEL_USBSEL_SET( reg, val ) BSP_FLD32SET( reg, \ + val, \ + 8, \ + 9 ) +#define LPC176X_SCB_CLKSRCSEL_CLKSRC BSP_BIT32( 0 ) +#define LPC176X_SCB_SCS_MCIPWR BSP_BIT32( 3 ) +#define LPC176X_SCB_SCS_OSC_RANGE_SEL BSP_BIT32( 4 ) +#define LPC176X_SCB_SCS_OSC_ENABLE BSP_BIT32( 5 ) +#define LPC176X_SCB_SCS_OSC_STATUS BSP_BIT32( 6 ) +#define LPC176X_SCB_PCLKSEL_PCLKDIV( val ) BSP_FLD32( val, 0, 4 ) +#define LPC176X_SCB_PCLKSEL_PCLKDIV_GET( reg ) BSP_FLD32GET( reg, 0, 4 ) +#define LPC176X_SCB_PCLKSEL_PCLKDIV_SET( reg, val ) BSP_FLD32SET( reg, \ + val, \ + 0, \ + 4 ) +#define LPC176X_SCB_PBOOST_BOOST BSP_BIT32( 0 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUTSEL( val ) BSP_FLD32( val, 3, 0 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUTSEL_GET( reg ) BSP_FLD32GET( reg, 3, 0 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUTSEL_SET( reg, val ) BSP_FLD32SET( reg, val, \ + 3, 0 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUTDIV( val ) BSP_FLD32( val, 7, 4 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUTDIV_GET( reg ) BSP_FLD32GET( reg, 7, 4 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUTDIV_SET( reg, val ) BSP_FLD32SET( reg, val, \ + 7, 4 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUT_EN BSP_BIT32( 8 ) +#define LPC176X_SCB_CLKOUTCFG_CLKOUT_ACT BSP_BIT32( 9 ) + +/** + * @brief System Control Block representation. + */ +typedef struct { + /** + * @brief Flash Accelerator Configuration Register. + */ + uint32_t flashcfg; + uint32_t reserved_04[ 15 ]; + /** + * @brief Memopry Map Control. + */ + uint32_t memmap; + uint32_t reserved_44[ 15 ]; + /** + * @brief Phase-Locked Loop 0. + */ + lpc176x_pll pll_0; + uint32_t reserved_90[ 4 ]; + /** + * @brief Phase-Locked Loop 1. + */ + lpc176x_pll pll_1; + uint32_t reserved_b0[ 4 ]; + /** + * @brief Power Mode Control register. + */ + uint32_t pcon; + /** + * @brief Power Control for Peripherals register. + */ + uint32_t pconp; + uint32_t reserved_c8[ 15 ]; + /** + *@brief Selects the divide valuefor creating the CPU clock from the + * PPL0 output. + */ + uint32_t cclksel; + /** + * @brief Selects the divide value for creating the USB clock from the + * PPL0 output. + */ + uint32_t usbclksel; + /** + * @brief Clock Source Select register. + */ + uint32_t clksrcsel; + uint32_t reserved_110[ 12 ]; + /** + * @brief External Interrupt flag register. + */ + uint32_t extint; + uint32_t reserved_144; + /** + * @brief External Interrupt Mode register. + */ + uint32_t extmode; + /** + * @brief External Interrupt Polarity register. + */ + uint32_t extpolar; + uint32_t reserved_150[ 12 ]; + /** + * @brief Reset Source Identification Register. + */ + uint32_t rsid; + uint32_t reserved_184[ 7 ]; + /** + * @brief System Controls and Status Register. + */ + uint32_t scs; + uint32_t reserved_1a4; + /** + * @brief Peripheral Clock Selection registers 0 and 1. + */ + uint32_t pclksel[ 2 ]; + /** + * @brief Peripheral boost. + */ + uint32_t pboost; + uint32_t reserved_1b4[ 5 ]; + /** + * @brief Clock Output Configuration Register. + */ + uint32_t clkoutcfg; + /** + * @brief Reset Control bit 0 and 1. + */ + uint32_t rstcon[ 2 ]; + uint32_t reserved_1d4[ 4 ]; +} lpc176x_scb; + +#define LPC176X_BASE 0x00u +#define LPC176X_SCB ( *(volatile lpc176x_scb *) ( LPC176X_SCB_BASE_ADDR ) ) + +/* Fast I/O setup */ +#define LPC176X_FIO_BASE_ADDR 0x2009C000U +#define LPC176X_FIO ( (volatile lpc176x_fio *) LPC176X_FIO_BASE_ADDR ) + +#define FIO0DIR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x00U ) ) +#define FIO0MASK ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x10U ) ) +#define FIO0PIN ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x14U ) ) +#define FIO0SET ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x18U ) ) +#define FIO0CLR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x1CU ) ) + +#define FIO1DIR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x20U ) ) +#define FIO1MASK ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x30U ) ) +#define FIO1PIN ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x34U ) ) +#define FIO1SET ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x38U ) ) +#define FIO1CLR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x3CU ) ) + +#define FIO2DIR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x40U ) ) +#define FIO2MASK ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x50U ) ) +#define FIO2PIN ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x54U ) ) +#define FIO2SET ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x58U ) ) +#define FIO2CLR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x5CU ) ) + +#define FIO3DIR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x60U ) ) +#define FIO3MASK ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x70U ) ) +#define FIO3PIN ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x74U ) ) +#define FIO3SET ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x78U ) ) +#define FIO3CLR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x7CU ) ) + +#define FIO4DIR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x80U ) ) +#define FIO4MASK ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x90U ) ) +#define FIO4PIN ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x94U ) ) +#define FIO4SET ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x98U ) ) +#define FIO4CLR ( *(volatile uint32_t *) ( LPC176X_FIO_BASE_ADDR + 0x9CU ) ) + +/* FIOs can be accessed through WORD, HALF-WORD or BYTE. */ +#define FIO0DIR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x00U ) ) +#define FIO1DIR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x20U ) ) +#define FIO2DIR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x40U ) ) +#define FIO3DIR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x60U ) ) +#define FIO4DIR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x80U ) ) + +#define FIO0DIR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x01U ) ) +#define FIO1DIR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x21U ) ) +#define FIO2DIR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x41U ) ) +#define FIO3DIR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x61U ) ) +#define FIO4DIR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x81U ) ) + +#define FIO0DIR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x02U ) ) +#define FIO1DIR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x22U ) ) +#define FIO2DIR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x42U ) ) +#define FIO3DIR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x62U ) ) +#define FIO4DIR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x82U ) ) + +#define FIO0DIR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x03U ) ) +#define FIO1DIR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x23U ) ) +#define FIO2DIR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x43U ) ) +#define FIO3DIR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x63U ) ) +#define FIO4DIR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x83U ) ) + +#define FIO0DIRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x00U ) ) +#define FIO1DIRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x20U ) ) +#define FIO2DIRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x40U ) ) +#define FIO3DIRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x60U ) ) +#define FIO4DIRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x80U ) ) + +#define FIO0DIRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x02U ) ) +#define FIO1DIRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x22U ) ) +#define FIO2DIRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x42U ) ) +#define FIO3DIRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x62U ) ) +#define FIO4DIRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x82U ) ) + +#define FIO0MASK0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x10U ) ) +#define FIO1MASK0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x30U ) ) +#define FIO2MASK0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x50U ) ) +#define FIO3MASK0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x70U ) ) +#define FIO4MASK0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x90U ) ) + +#define FIO0MASK1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x11U ) ) +#define FIO1MASK1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x21U ) ) +#define FIO2MASK1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x51U ) ) +#define FIO3MASK1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x71U ) ) +#define FIO4MASK1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x91U ) ) + +#define FIO0MASK2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x12U ) ) +#define FIO1MASK2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x32U ) ) +#define FIO2MASK2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x52U ) ) +#define FIO3MASK2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x72U ) ) +#define FIO4MASK2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x92U ) ) + +#define FIO0MASK3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x13U ) ) +#define FIO1MASK3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x33U ) ) +#define FIO2MASK3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x53U ) ) +#define FIO3MASK3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x73U ) ) +#define FIO4MASK3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x93U ) ) + +#define FIO0MASKL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x10U ) ) +#define FIO1MASKL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x30U ) ) +#define FIO2MASKL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x50U ) ) +#define FIO3MASKL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x70U ) ) +#define FIO4MASKL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x90U ) ) + +#define FIO0MASKU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x12U ) ) +#define FIO1MASKU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x32U ) ) +#define FIO2MASKU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x52U ) ) +#define FIO3MASKU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x72U ) ) +#define FIO4MASKU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x92U ) ) + +#define FIO0PIN0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x14U ) ) +#define FIO1PIN0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x34U ) ) +#define FIO2PIN0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x54U ) ) +#define FIO3PIN0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x74U ) ) +#define FIO4PIN0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x94U ) ) + +#define FIO0PIN1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x15U ) ) +#define FIO1PIN1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x25U ) ) +#define FIO2PIN1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x55U ) ) +#define FIO3PIN1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x75U ) ) +#define FIO4PIN1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x95U ) ) + +#define FIO0PIN2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x16U ) ) +#define FIO1PIN2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x36U ) ) +#define FIO2PIN2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x56U ) ) +#define FIO3PIN2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x76U ) ) +#define FIO4PIN2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x96U ) ) + +#define FIO0PIN3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x17U ) ) +#define FIO1PIN3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x37U ) ) +#define FIO2PIN3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x57U ) ) +#define FIO3PIN3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x77U ) ) +#define FIO4PIN3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x97U ) ) + +#define FIO0PINL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x14U ) ) +#define FIO1PINL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x34U ) ) +#define FIO2PINL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x54U ) ) +#define FIO3PINL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x74U ) ) +#define FIO4PINL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x94U ) ) + +#define FIO0PINU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x16U ) ) +#define FIO1PINU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x36U ) ) +#define FIO2PINU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x56U ) ) +#define FIO3PINU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x76U ) ) +#define FIO4PINU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x96U ) ) + +#define FIO0SET0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x18U ) ) +#define FIO1SET0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x38U ) ) +#define FIO2SET0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x58U ) ) +#define FIO3SET0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x78U ) ) +#define FIO4SET0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x98U ) ) + +#define FIO0SET1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x19U ) ) +#define FIO1SET1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x29U ) ) +#define FIO2SET1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x59U ) ) +#define FIO3SET1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x79U ) ) +#define FIO4SET1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x99U ) ) + +#define FIO0SET2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x1AU ) ) +#define FIO1SET2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x3AU ) ) +#define FIO2SET2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x5AU ) ) +#define FIO3SET2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x7AU ) ) +#define FIO4SET2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x9AU ) ) + +#define FIO0SET3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x1BU ) ) +#define FIO1SET3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x3BU ) ) +#define FIO2SET3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x5BU ) ) +#define FIO3SET3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x7BU ) ) +#define FIO4SET3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x9BU ) ) + +#define FIO0SETL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x18U ) ) +#define FIO1SETL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x38U ) ) +#define FIO2SETL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x58U ) ) +#define FIO3SETL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x78U ) ) +#define FIO4SETL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x98U ) ) + +#define FIO0SETU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x1AU ) ) +#define FIO1SETU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x3AU ) ) +#define FIO2SETU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x5AU ) ) +#define FIO3SETU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x7AU ) ) +#define FIO4SETU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x9AU ) ) + +#define FIO0CLR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x1CU ) ) +#define FIO1CLR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x3CU ) ) +#define FIO2CLR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x5CU ) ) +#define FIO3CLR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x7CU ) ) +#define FIO4CLR0 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x9CU ) ) + +#define FIO0CLR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x1DU ) ) +#define FIO1CLR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x2DU ) ) +#define FIO2CLR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x5DU ) ) +#define FIO3CLR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x7DU ) ) +#define FIO4CLR1 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x9DU ) ) + +#define FIO0CLR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x1EU ) ) +#define FIO1CLR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x3EU ) ) +#define FIO2CLR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x5EU ) ) +#define FIO3CLR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x7EU ) ) +#define FIO4CLR2 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x9EU ) ) + +#define FIO0CLR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x1FU ) ) +#define FIO1CLR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x3FU ) ) +#define FIO2CLR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x5FU ) ) +#define FIO3CLR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x7FU ) ) +#define FIO4CLR3 ( *(volatile uint8_t *) ( LPC176X_FIO_BASE_ADDR + 0x9FU ) ) + +#define FIO0CLRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x1CU ) ) +#define FIO1CLRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x3CU ) ) +#define FIO2CLRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x5CU ) ) +#define FIO3CLRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x7CU ) ) +#define FIO4CLRL ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x9CU ) ) + +#define FIO0CLRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x1EU ) ) +#define FIO1CLRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x3EU ) ) +#define FIO2CLRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x5EU ) ) +#define FIO3CLRU ( *(volatile uint16_t *) ( LPC176X_FIO_BASE_ADDR + 0x7EU ) ) +#define FIO4CLRU ( *(volatile uint16_t *) ( FIO_BASE_ADDR + 0x9EU ) ) + +#define LPC176X_USB_CLOCK 48000000U +#define LPC176X_MODULE_CLOCK_MASK 0x3U + +/* Pin Connect Block */ +#define PINSEL_BASE_ADDR 0x4002C000U + +#define PINSEL0 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x00U ) ) +#define PINSEL1 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x04U ) ) +#define PINSEL2 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x08U ) ) +#define PINSEL3 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x0CU ) ) +#define PINSEL4 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x10U ) ) +#define PINSEL5 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x14U ) ) +#define PINSEL6 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x18U ) ) +#define PINSEL7 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x1CU ) ) +#define PINSEL8 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x20U ) ) +#define PINSEL9 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x24U ) ) +#define PINSEL10 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x28U ) ) +#define PINSEL11 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x2CU ) ) + +#define PINMODE0 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x40U ) ) +#define PINMODE1 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x44U ) ) +#define PINMODE2 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x48U ) ) +#define PINMODE3 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x4CU ) ) +#define PINMODE4 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x50U ) ) +#define PINMODE5 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x54U ) ) +#define PINMODE6 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x58U ) ) +#define PINMODE7 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x5CU ) ) +#define PINMODE8 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x60U ) ) +#define PINMODE9 ( *(volatile uint32_t *) ( PINSEL_BASE_ADDR + 0x64U ) ) + +/* Pulse Width Modulator (PWM) */ +#define PWM0_BASE_ADDR 0x40014000 + +#define PWM0IR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x00 ) ) +#define PWM0TCR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x04 ) ) +#define PWM0TC ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x08 ) ) +#define PWM0PR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x0C ) ) +#define PWM0PC ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x10 ) ) +#define PWM0MCR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x14 ) ) +#define PWM0MR0 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x18 ) ) +#define PWM0MR1 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x1C ) ) +#define PWM0MR2 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x20 ) ) +#define PWM0MR3 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x24 ) ) +#define PWM0CCR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x28 ) ) +#define PWM0CR0 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x2C ) ) +#define PWM0CR1 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x30 ) ) +#define PWM0CR2 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x34 ) ) +#define PWM0CR3 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x38 ) ) +#define PWM0EMR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x3C ) ) +#define PWM0MR4 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x40 ) ) +#define PWM0MR5 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x44 ) ) +#define PWM0MR6 ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x48 ) ) +#define PWM0PCR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x4C ) ) +#define PWM0LER ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x50 ) ) +#define PWM0CTCR ( *(volatile uint32_t *) ( PWM0_BASE_ADDR + 0x70 ) ) + +#define PWM1_BASE_ADDR 0x40018000 + +#define PWM1IR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x00 ) ) +#define PWM1TCR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x04 ) ) +#define PWM1TC ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x08 ) ) +#define PWM1PR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x0C ) ) +#define PWM1PC ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x10 ) ) +#define PWM1MCR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x14 ) ) +#define PWM1MR0 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x18 ) ) +#define PWM1MR1 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x1C ) ) +#define PWM1MR2 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x20 ) ) +#define PWM1MR3 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x24 ) ) +#define PWM1CCR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x28 ) ) +#define PWM1CR0 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x2C ) ) +#define PWM1CR1 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x30 ) ) +#define PWM1CR2 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x34 ) ) +#define PWM1CR3 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x38 ) ) +#define PWM1EMR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x3C ) ) +#define PWM1MR4 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x40 ) ) +#define PWM1MR5 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x44 ) ) +#define PWM1MR6 ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x48 ) ) +#define PWM1PCR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x4C ) ) +#define PWM1LER ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x50 ) ) +#define PWM1CTCR ( *(volatile uint32_t *) ( PWM1_BASE_ADDR + 0x70 ) ) + +/* Universal Asynchronous Receiver Transmitter 0 (UART0) */ +#define UART0_BASE_ADDR 0x4000C000 + +#define U0RBR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x00 ) ) +#define U0THR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x00 ) ) +#define U0DLL ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x00 ) ) +#define U0DLM ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x04 ) ) +#define U0IER ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x04 ) ) +#define U0IIR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x08 ) ) +#define U0FCR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x08 ) ) +#define U0LCR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x0C ) ) +#define U0LSR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x14 ) ) +#define U0SCR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x1C ) ) +#define U0ACR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x20 ) ) +#define U0ICR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x24 ) ) +#define U0FDR ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x28 ) ) +#define U0TER ( *(volatile uint32_t *) ( UART0_BASE_ADDR + 0x30 ) ) + +/* Universal Asynchronous Receiver Transmitter 1 (UART1) */ +#define UART1_BASE_ADDR 0x40010000 + +#define U1RBR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x00 ) ) +#define U1THR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x00 ) ) +#define U1DLL ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x00 ) ) +#define U1DLM ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x04 ) ) +#define U1IER ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x04 ) ) +#define U1IIR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x08 ) ) +#define U1FCR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x08 ) ) +#define U1LCR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x0C ) ) +#define U1MCR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x10 ) ) +#define U1LSR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x14 ) ) +#define U1MSR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x18 ) ) +#define U1SCR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x1C ) ) +#define U1ACR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x20 ) ) +#define U1FDR ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x28 ) ) +#define U1TER ( *(volatile uint32_t *) ( UART1_BASE_ADDR + 0x30 ) ) + +/* Universal Asynchronous Receiver Transmitter 2 (UART2) */ +#define UART2_BASE_ADDR 0x40098000 + +#define U2RBR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x00 ) ) +#define U2THR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x00 ) ) +#define U2DLL ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x00 ) ) +#define U2DLM ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x04 ) ) +#define U2IER ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x04 ) ) +#define U2IIR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x08 ) ) +#define U2FCR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x08 ) ) +#define U2LCR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x0C ) ) +#define U2LSR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x14 ) ) +#define U2SCR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x1C ) ) +#define U2ACR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x20 ) ) +#define U2ICR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x24 ) ) +#define U2FDR ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x28 ) ) +#define U2TER ( *(volatile uint32_t *) ( UART2_BASE_ADDR + 0x30 ) ) + +/* Universal Asynchronous Receiver Transmitter 3 (UART3) */ +#define UART3_BASE_ADDR 0x4009C000 + +#define U3RBR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x00 ) ) +#define U3THR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x00 ) ) +#define U3DLL ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x00 ) ) +#define U3DLM ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x04 ) ) +#define U3IER ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x04 ) ) +#define U3IIR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x08 ) ) +#define U3FCR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x08 ) ) +#define U3LCR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x0C ) ) +#define U3LSR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x14 ) ) +#define U3SCR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x1C ) ) +#define U3ACR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x20 ) ) +#define U3ICR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x24 ) ) +#define U3FDR ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x28 ) ) +#define U3TER ( *(volatile uint32_t *) ( UART3_BASE_ADDR + 0x30 ) ) + +/* SPI0 (Serial Peripheral Interface 0) */ +#define SPI0_BASE_ADDR 0xE0020000 +#define S0SPCR ( *(volatile uint32_t *) ( SPI0_BASE_ADDR + 0x00 ) ) +#define S0SPSR ( *(volatile uint32_t *) ( SPI0_BASE_ADDR + 0x04 ) ) +#define S0SPDR ( *(volatile uint32_t *) ( SPI0_BASE_ADDR + 0x08 ) ) +#define S0SPCCR ( *(volatile uint32_t *) ( SPI0_BASE_ADDR + 0x0C ) ) +#define S0SPINT ( *(volatile uint32_t *) ( SPI0_BASE_ADDR + 0x1C ) ) + +/* Real Time Clock */ +#define RTC_BASE_ADDR 0x40024000 + +#define RTC_ILR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x00 ) ) +#define RTC_CTC ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x04 ) ) +#define RTC_CCR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x08 ) ) +#define RTC_CIIR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x0C ) ) +#define RTC_AMR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x10 ) ) +#define RTC_CTIME0 ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x14 ) ) +#define RTC_CTIME1 ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x18 ) ) +#define RTC_CTIME2 ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x1C ) ) +#define RTC_SEC ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x20 ) ) +#define RTC_MIN ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x24 ) ) +#define RTC_HOUR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x28 ) ) +#define RTC_DOM ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x2C ) ) +#define RTC_DOW ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x30 ) ) +#define RTC_DOY ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x34 ) ) +#define RTC_MONTH ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x38 ) ) +#define RTC_YEAR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x3C ) ) +#define RTC_CISS ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x40 ) ) +#define RTC_ALSEC ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x60 ) ) +#define RTC_ALMIN ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x64 ) ) +#define RTC_ALHOUR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x68 ) ) +#define RTC_ALDOM ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x6C ) ) +#define RTC_ALDOW ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x70 ) ) +#define RTC_ALDOY ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x74 ) ) +#define RTC_ALMON ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x78 ) ) +#define RTC_ALYEAR ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x7C ) ) +#define RTC_PREINT ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x80 ) ) +#define RTC_PREFRAC ( *(volatile uint32_t *) ( RTC_BASE_ADDR + 0x84 ) ) + +/* A/D Converter 0 (AD0) */ +#define AD0_BASE_ADDR 0x40034000 + +#define AD0CR ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x00 ) ) +#define AD0GDR ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x04 ) ) +#define AD0INTEN ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x0C ) ) +#define AD0_DATA_START ( (volatile uint32_t *) ( AD0_BASE_ADDR + 0x10 ) ) +#define AD0DR0 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x10 ) ) +#define AD0DR1 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x14 ) ) +#define AD0DR2 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x18 ) ) +#define AD0DR3 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x1C ) ) +#define AD0DR4 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x20 ) ) +#define AD0DR5 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x24 ) ) +#define AD0DR6 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x28 ) ) +#define AD0DR7 ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x2C ) ) +#define AD0STAT ( *(volatile uint32_t *) ( AD0_BASE_ADDR + 0x30 ) ) + +/* D/A Converter */ +#define DAC_BASE_ADDR 0x4008C000 + +#define DACR ( *(volatile uint32_t *) ( DAC_BASE_ADDR + 0x00 ) ) + +/* CAN CONTROLLERS AND ACCEPTANCE FILTER */ +#define CAN_ACCEPT_BASE_ADDR 0x4003C000 + +#define CAN_AFMR ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + 0x00 ) ) +#define CAN_SFF_SA ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + 0x04 ) ) +#define CAN_SFF_GRP_SA ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + \ + 0x08 ) ) +#define CAN_EFF_SA ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + 0x0C ) ) +#define CAN_EFF_GRP_SA ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + \ + 0x10 ) ) +#define CAN_EOT ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + 0x14 ) ) +#define CAN_LUT_ERR_ADR ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + \ + 0x18 ) ) +#define CAN_LUT_ERR ( *(volatile uint32_t *) ( CAN_ACCEPT_BASE_ADDR + 0x1C ) ) + +#define CAN_CENTRAL_BASE_ADDR 0x40040000 + +#define CAN_TX_SR ( *(volatile uint32_t *) ( CAN_CENTRAL_BASE_ADDR + 0x00 ) ) +#define CAN_RX_SR ( *(volatile uint32_t *) ( CAN_CENTRAL_BASE_ADDR + 0x04 ) ) +#define CAN_MSR ( *(volatile uint32_t *) ( CAN_CENTRAL_BASE_ADDR + 0x08 ) ) + +#define CAN1_BASE_ADDR 0x40044000 + +#define CAN1MOD ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x00 ) ) +#define CAN1CMR ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x04 ) ) +#define CAN1GSR ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x08 ) ) +#define CAN1ICR ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x0C ) ) +#define CAN1IER ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x10 ) ) +#define CAN1BTR ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x14 ) ) +#define CAN1EWL ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x18 ) ) +#define CAN1SR ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x1C ) ) +#define CAN1RFS ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x20 ) ) +#define CAN1RID ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x24 ) ) +#define CAN1RDA ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x28 ) ) +#define CAN1RDB ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x2C ) ) + +#define CAN1TFI1 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x30 ) ) +#define CAN1TID1 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x34 ) ) +#define CAN1TDA1 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x38 ) ) +#define CAN1TDB1 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x3C ) ) +#define CAN1TFI2 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x40 ) ) +#define CAN1TID2 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x44 ) ) +#define CAN1TDA2 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x48 ) ) +#define CAN1TDB2 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x4C ) ) +#define CAN1TFI3 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x50 ) ) +#define CAN1TID3 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x54 ) ) +#define CAN1TDA3 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x58 ) ) +#define CAN1TDB3 ( *(volatile uint32_t *) ( CAN1_BASE_ADDR + 0x5C ) ) + +#define CAN2_BASE_ADDR 0x40048000 + +#define CAN2MOD ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x00 ) ) +#define CAN2CMR ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x04 ) ) +#define CAN2GSR ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x08 ) ) +#define CAN2ICR ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x0C ) ) +#define CAN2IER ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x10 ) ) +#define CAN2BTR ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x14 ) ) +#define CAN2EWL ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x18 ) ) +#define CAN2SR ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x1C ) ) +#define CAN2RFS ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x20 ) ) +#define CAN2RID ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x24 ) ) +#define CAN2RDA ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x28 ) ) +#define CAN2RDB ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x2C ) ) + +#define CAN2TFI1 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x30 ) ) +#define CAN2TID1 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x34 ) ) +#define CAN2TDA1 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x38 ) ) +#define CAN2TDB1 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x3C ) ) +#define CAN2TFI2 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x40 ) ) +#define CAN2TID2 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x44 ) ) +#define CAN2TDA2 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x48 ) ) +#define CAN2TDB2 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x4C ) ) +#define CAN2TFI3 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x50 ) ) +#define CAN2TID3 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x54 ) ) +#define CAN2TDA3 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x58 ) ) +#define CAN2TDB3 ( *(volatile uint32_t *) ( CAN2_BASE_ADDR + 0x5C ) ) + +/* MultiMedia Card Interface(MCI) Controller */ +#define MCI_BASE_ADDR 0x400c0000 + +#define MCI_POWER ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x00 ) ) +#define MCI_CLOCK ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x04 ) ) +#define MCI_ARGUMENT ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x08 ) ) +#define MCI_COMMAND ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x0C ) ) +#define MCI_RESP_CMD ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x10 ) ) +#define MCI_RESP0 ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x14 ) ) +#define MCI_RESP1 ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x18 ) ) +#define MCI_RESP2 ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x1C ) ) +#define MCI_RESP3 ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x20 ) ) +#define MCI_DATA_TMR ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x24 ) ) +#define MCI_DATA_LEN ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x28 ) ) +#define MCI_DATA_CTRL ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x2C ) ) +#define MCI_DATA_CNT ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x30 ) ) +#define MCI_STATUS ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x34 ) ) +#define MCI_CLEAR ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x38 ) ) +#define MCI_MASK0 ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x3C ) ) +#define MCI_MASK1 ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x40 ) ) +#define MCI_FIFO_CNT ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x48 ) ) +#define MCI_FIFO ( *(volatile uint32_t *) ( MCI_BASE_ADDR + 0x80 ) ) + +/* I2S Interface Controller (I2S) */ +#define I2S_BASE_ADDR 0x400a8000 + +#define I2S_DAO ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x00 ) ) +#define I2S_DAI ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x04 ) ) +#define I2S_TX_FIFO ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x08 ) ) +#define I2S_RX_FIFO ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x0C ) ) +#define I2S_STATE ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x10 ) ) +#define I2S_DMA1 ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x14 ) ) +#define I2S_DMA2 ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x18 ) ) +#define I2S_IRQ ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x1C ) ) +#define I2S_TXRATE ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x20 ) ) +#define I2S_RXRATE ( *(volatile uint32_t *) ( I2S_BASE_ADDR + 0x24 ) ) + +/* General-purpose DMA Controller */ +#define DMA_BASE_ADDR 0x50004000 + +#define GPDMA_INT_STAT ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x000 ) ) +#define GPDMA_INT_TCSTAT ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x004 ) ) +#define GPDMA_INT_TCCLR ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x008 ) ) +#define GPDMA_INT_ERR_STAT ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x00C ) ) +#define GPDMA_INT_ERR_CLR ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x010 ) ) +#define GPDMA_RAW_INT_TCSTAT ( *(volatile uint32_t *) ( DMA_BASE_ADDR + \ + 0x014 ) ) +#define GPDMA_RAW_INT_ERR_STAT ( *(volatile uint32_t *) ( DMA_BASE_ADDR + \ + 0x018 ) ) +#define GPDMA_ENABLED_CHNS ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x01C ) ) +#define GPDMA_SOFT_BREQ ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x020 ) ) +#define GPDMA_SOFT_SREQ ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x024 ) ) +#define GPDMA_SOFT_LBREQ ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x028 ) ) +#define GPDMA_SOFT_LSREQ ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x02C ) ) +#define GPDMA_CONFIG ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x030 ) ) +#define GPDMA_SYNC ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x034 ) ) + +/* DMA channel 0 registers */ +#define GPDMA_CH0_BASE_ADDR ( DMA_BASE_ADDR + 0x100 ) +#define GPDMA_CH0_SRC ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x100 ) ) +#define GPDMA_CH0_DEST ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x104 ) ) +#define GPDMA_CH0_LLI ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x108 ) ) +#define GPDMA_CH0_CTRL ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x10C ) ) +#define GPDMA_CH0_CFG ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x110 ) ) + +/* DMA channel 1 registers */ +#define GPDMA_CH1_BASE_ADDR ( DMA_BASE_ADDR + 0x120 ) +#define GPDMA_CH1_SRC ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x120 ) ) +#define GPDMA_CH1_DEST ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x124 ) ) +#define GPDMA_CH1_LLI ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x128 ) ) +#define GPDMA_CH1_CTRL ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x12C ) ) +#define GPDMA_CH1_CFG ( *(volatile uint32_t *) ( DMA_BASE_ADDR + 0x130 ) ) + +/* USB Controller */ +#define USB_INT_BASE_ADDR 0x400fc1c0 +#define USB_BASE_ADDR 0x2008c200 + +#define USB_INT_STAT ( *(volatile uint32_t *) ( USB_INT_BASE_ADDR + 0x00 ) ) + +/* USB Device Interrupt Registers */ +#define DEV_INT_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x00 ) ) +#define DEV_INT_EN ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x04 ) ) +#define DEV_INT_CLR ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x08 ) ) +#define DEV_INT_SET ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x0C ) ) +#define DEV_INT_PRIO ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x2C ) ) + +/* USB Device Endpoint Interrupt Registers */ +#define EP_INT_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x30 ) ) +#define EP_INT_EN ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x34 ) ) +#define EP_INT_CLR ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x38 ) ) +#define EP_INT_SET ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x3C ) ) +#define EP_INT_PRIO ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x40 ) ) + +/* USB Device Endpoint Realization Registers */ +#define REALIZE_EP ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x44 ) ) +#define EP_INDEX ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x48 ) ) +#define MAXPACKET_SIZE ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x4C ) ) + +/* USB Device Command Reagisters */ +#define CMD_CODE ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x10 ) ) +#define CMD_DATA ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x14 ) ) + +/* USB Device Data Transfer Registers */ +#define RX_DATA ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x18 ) ) +#define TX_DATA ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x1C ) ) +#define RX_PLENGTH ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x20 ) ) +#define TX_PLENGTH ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x24 ) ) +#define USB_CTRL ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x28 ) ) + +/* USB Device DMA Registers */ +#define DMA_REQ_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x50 ) ) +#define DMA_REQ_CLR ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x54 ) ) +#define DMA_REQ_SET ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x58 ) ) +#define UDCA_HEAD ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x80 ) ) +#define EP_DMA_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x84 ) ) +#define EP_DMA_EN ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x88 ) ) +#define EP_DMA_DIS ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x8C ) ) +#define DMA_INT_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x90 ) ) +#define DMA_INT_EN ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0x94 ) ) +#define EOT_INT_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xA0 ) ) +#define EOT_INT_CLR ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xA4 ) ) +#define EOT_INT_SET ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xA8 ) ) +#define NDD_REQ_INT_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xAC ) ) +#define NDD_REQ_INT_CLR ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xB0 ) ) +#define NDD_REQ_INT_SET ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xB4 ) ) +#define SYS_ERR_INT_STAT ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xB8 ) ) +#define SYS_ERR_INT_CLR ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xBC ) ) +#define SYS_ERR_INT_SET ( *(volatile uint32_t *) ( USB_BASE_ADDR + 0xC0 ) ) + +/* USB Host Controller */ +#define USBHC_BASE_ADDR 0x2008c000 + +#define HC_REVISION ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x00 ) ) +#define HC_CONTROL ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x04 ) ) +#define HC_CMD_STAT ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x08 ) ) +#define HC_INT_STAT ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x0C ) ) +#define HC_INT_EN ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x10 ) ) +#define HC_INT_DIS ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x14 ) ) +#define HC_HCCA ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x18 ) ) +#define HC_PERIOD_CUR_ED ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x1C ) ) +#define HC_CTRL_HEAD_ED ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x20 ) ) +#define HC_CTRL_CUR_ED ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x24 ) ) +#define HC_BULK_HEAD_ED ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x28 ) ) +#define HC_BULK_CUR_ED ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x2C ) ) +#define HC_DONE_HEAD ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x30 ) ) +#define HC_FM_INTERVAL ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x34 ) ) +#define HC_FM_REMAINING ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x38 ) ) +#define HC_FM_NUMBER ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x3C ) ) +#define HC_PERIOD_START ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x40 ) ) +#define HC_LS_THRHLD ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x44 ) ) +#define HC_RH_DESCA ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x48 ) ) +#define HC_RH_DESCB ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x4C ) ) +#define HC_RH_STAT ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x50 ) ) +#define HC_RH_PORT_STAT1 ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x54 ) ) +#define HC_RH_PORT_STAT2 ( *(volatile uint32_t *) ( USBHC_BASE_ADDR + 0x58 ) ) + +/* USB OTG Controller */ +#define USBOTG_BASE_ADDR 0x2008c100 + +#define OTG_INT_STAT ( *(volatile uint32_t *) ( USBOTG_BASE_ADDR + 0x00 ) ) +#define OTG_INT_EN ( *(volatile uint32_t *) ( USBOTG_BASE_ADDR + 0x04 ) ) +#define OTG_INT_SET ( *(volatile uint32_t *) ( USBOTG_BASE_ADDR + 0x08 ) ) +#define OTG_INT_CLR ( *(volatile uint32_t *) ( USBOTG_BASE_ADDR + 0x0C ) ) +#define OTG_STAT_CTRL ( *(volatile uint32_t *) ( USBOTG_BASE_ADDR + 0x10 ) ) +#define OTG_TIMER ( *(volatile uint32_t *) ( USBOTG_BASE_ADDR + 0x14 ) ) + +#define USBOTG_I2C_BASE_ADDR 0x2008c300 + +#define OTG_I2C_RX ( *(volatile uint32_t *) ( USBOTG_I2C_BASE_ADDR + 0x00 ) ) +#define OTG_I2C_TX ( *(volatile uint32_t *) ( USBOTG_I2C_BASE_ADDR + 0x00 ) ) +#define OTG_I2C_STS ( *(volatile uint32_t *) ( USBOTG_I2C_BASE_ADDR + 0x04 ) ) +#define OTG_I2C_CTL ( *(volatile uint32_t *) ( USBOTG_I2C_BASE_ADDR + 0x08 ) ) +#define OTG_I2C_CLKHI ( *(volatile uint32_t *) ( USBOTG_I2C_BASE_ADDR + \ + 0x0C ) ) +#define OTG_I2C_CLKLO ( *(volatile uint32_t *) ( USBOTG_I2C_BASE_ADDR + \ + 0x10 ) ) + +#define USBOTG_CLK_BASE_ADDR 0x2008CFF0U + +#define OTG_CLK_CTRL ( *(volatile uint32_t *) ( USBOTG_CLK_BASE_ADDR + \ + 0x04U ) ) +#define OTG_CLK_STAT ( *(volatile uint32_t *) ( USBOTG_CLK_BASE_ADDR + \ + 0x08U ) ) + +/* Register Fields */ +#define GET_FIELD( val, mask, shift ) \ + ( ( ( val ) & ( mask ) ) >> ( shift ) ) + +#define SET_FIELD( val, field, mask, shift ) \ + ( ( ( val ) & ~( mask ) ) | ( ( ( field ) << ( shift ) ) & ( mask ) ) ) + +/* CLKSRCSEL */ +#define CLKSRCSEL_CLKSRC_MASK 0x00000003U + +#define GET_CLKSRCSEL_CLKSRC( reg ) \ + GET_FIELD( reg, CLKSRCSEL_CLKSRC_MASK, 0 ) + +#define SET_CLKSRCSEL_CLKSRC( reg, val ) \ + SET_FIELD( reg, val, CLKSRCSEL_CLKSRC_MASK, 0 ) + +/* PLLCON */ +#define PLLCON_PLLE 0x00000001U + +#define PLLCON_PLLC 0x00000002U + +/* PLLCFG */ +#define PLLCFG_MSEL_MASK 0x00007fffU + +#define GET_PLLCFG_MSEL( reg ) \ + GET_FIELD( reg, PLLCFG_MSEL_MASK, 0 ) + +#define SET_PLLCFG_MSEL( reg, val ) \ + SET_FIELD( reg, val, PLLCFG_MSEL_MASK, 0 ) + +#define PLLCFG_NSEL_MASK 0x00ff0000U + +#define GET_PLLCFG_NSEL( reg ) \ + GET_FIELD( reg, PLLCFG_NSEL_MASK, 16 ) + +#define SET_PLLCFG_NSEL( reg, val ) \ + SET_FIELD( reg, val, PLLCFG_NSEL_MASK, 16 ) + +/* PLLSTAT */ +#define PLLSTAT_MSEL_MASK 0x00007fffU + +#define GET_PLLSTAT_MSEL( reg ) \ + GET_FIELD( reg, PLLSTAT_MSEL_MASK, 0 ) + +#define SET_PLLSTAT_MSEL( reg, val ) \ + SET_FIELD( reg, val, PLLSTAT_MSEL_MASK, 0 ) + +#define PLLSTAT_NSEL_MASK 0x00ff0000U + +#define GET_PLLSTAT_NSEL( reg ) \ + GET_FIELD( reg, PLLSTAT_NSEL_MASK, 16 ) + +#define SET_PLLSTAT_NSEL( reg, val ) \ + SET_FIELD( reg, val, PLLSTAT_NSEL_MASK, 16 ) + +#define PLLSTAT_PLLE 0x01000000U + +#define PLLSTAT_PLLC 0x02000000U + +#define PLLSTAT_PLOCK 0x04000000U + +/* CCLKCFG */ +#define CCLKCFG_CCLKSEL_MASK 0x000000ffU + +#define GET_CCLKCFG_CCLKSEL( reg ) \ + GET_FIELD( reg, CCLKCFG_CCLKSEL_MASK, 0 ) + +#define SET_CCLKCFG_CCLKSEL( reg, val ) \ + SET_FIELD( reg, val, CCLKCFG_CCLKSEL_MASK, 0 ) + +/* MEMMAP */ +#define MEMMAP_MAP_MASK 0x00000003U + +#define GET_MEMMAP_MAP( reg ) \ + GET_FIELD( reg, MEMMAP_MAP_MASK, 0 ) + +#define SET_MEMMAP_MAP( reg, val ) \ + SET_FIELD( reg, val, MEMMAP_MAP_MASK, 0 ) + +/* TIR */ +#define TIR_MR0 0x00000001U +#define TIR_MR1 0x00000002U +#define TIR_MR2 0x00000004U +#define TIR_MR3 0x00000008U +#define TIR_CR0 0x00000010U +#define TIR_CR1 0x00000020U +#define TIR_CR2 0x00000040U +#define TIR_CR3 0x00000080U + +/* TCR */ +#define TCR_EN 0x00000001U +#define TCR_RST 0x00000002U + +/* TMCR */ +#define TMCR_MR0I 0x00000001U +#define TMCR_MR0R 0x00000002U +#define TMCR_MR0S 0x00000004U +#define TMCR_MR1I 0x00000008U +#define TMCR_MR1R 0x00000010U +#define TMCR_MR1S 0x00000020U +#define TMCR_MR2I 0x00000040U +#define TMCR_MR2R 0x00000080U +#define TMCR_MR2S 0x00000100U +#define TMCR_MR3I 0x00000200U +#define TMCR_MR3R 0x00000400U +#define TMCR_MR3S 0x00000800U + +/* PCLKSEL0 */ +#define PCLKSEL0_PCLK_WDT_MASK 0x00000003U + +#define GET_PCLKSEL0_PCLK_WDT( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_WDT_MASK, 0 ) + +#define SET_PCLKSEL0_PCLK_WDT( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_WDT_MASK, 0 ) + +#define PCLKSEL0_PCLK_TIMER0_MASK 0x0000000cU + +#define GET_PCLKSEL0_PCLK_TIMER0( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_TIMER0_MASK, 2 ) + +#define SET_PCLKSEL0_PCLK_TIMER0( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_TIMER0_MASK, 2 ) + +#define PCLKSEL0_PCLK_TIMER1_MASK 0x00000030U + +#define GET_PCLKSEL0_PCLK_TIMER1( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_TIMER1_MASK, 4 ) + +#define SET_PCLKSEL0_PCLK_TIMER1( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_TIMER1_MASK, 4 ) + +#define PCLKSEL0_PCLK_UART0_MASK 0x000000c0U + +#define GET_PCLKSEL0_PCLK_UART0( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_UART0_MASK, 6 ) + +#define SET_PCLKSEL0_PCLK_UART0( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_UART0_MASK, 6 ) + +#define PCLKSEL0_PCLK_UART1_MASK 0x00000300U + +#define GET_PCLKSEL0_PCLK_UART1( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_UART1_MASK, 8 ) + +#define SET_PCLKSEL0_PCLK_UART1( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_UART1_MASK, 8 ) + +#define PCLKSEL0_PCLK_PWM0_MASK 0x00000c00U + +#define GET_PCLKSEL0_PCLK_PWM0( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_PWM0_MASK, 10 ) + +#define SET_PCLKSEL0_PCLK_PWM0( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_PWM0_MASK, 10 ) + +#define PCLKSEL0_PCLK_PWM1_MASK 0x00003000U + +#define GET_PCLKSEL0_PCLK_PWM1( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_PWM1_MASK, 12 ) + +#define SET_PCLKSEL0_PCLK_PWM1( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_PWM1_MASK, 12 ) + +#define PCLKSEL0_PCLK_I2C0_MASK 0x0000c000U + +#define GET_PCLKSEL0_PCLK_I2C0( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_I2C0_MASK, 14 ) + +#define SET_PCLKSEL0_PCLK_I2C0( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_I2C0_MASK, 14 ) + +#define PCLKSEL0_PCLK_SPI_MASK 0x00030000U + +#define GET_PCLKSEL0_PCLK_SPI( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_SPI_MASK, 16 ) + +#define SET_PCLKSEL0_PCLK_SPI( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_SPI_MASK, 16 ) + +#define PCLKSEL0_PCLK_RTC_MASK 0x000c0000U + +#define GET_PCLKSEL0_PCLK_RTC( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_RTC_MASK, 18 ) + +#define SET_PCLKSEL0_PCLK_RTC( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_RTC_MASK, 18 ) + +#define PCLKSEL0_PCLK_SSP1_MASK 0x00300000U + +#define GET_PCLKSEL0_PCLK_SSP1( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_SSP1_MASK, 20 ) + +#define SET_PCLKSEL0_PCLK_SSP1( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_SSP1_MASK, 20 ) + +#define PCLKSEL0_PCLK_DAC_MASK 0x00c00000U + +#define GET_PCLKSEL0_PCLK_DAC( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_DAC_MASK, 22 ) + +#define SET_PCLKSEL0_PCLK_DAC( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_DAC_MASK, 22 ) + +#define PCLKSEL0_PCLK_ADC_MASK 0x03000000U + +#define GET_PCLKSEL0_PCLK_ADC( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_ADC_MASK, 24 ) + +#define SET_PCLKSEL0_PCLK_ADC( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_ADC_MASK, 24 ) + +#define PCLKSEL0_PCLK_CAN1_MASK 0x0c000000U + +#define GET_PCLKSEL0_PCLK_CAN1( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_CAN1_MASK, 26 ) + +#define SET_PCLKSEL0_PCLK_CAN1( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_CAN1_MASK, 26 ) + +#define PCLKSEL0_PCLK_CAN2_MASK 0x30000000U + +#define GET_PCLKSEL0_PCLK_CAN2( reg ) \ + GET_FIELD( reg, PCLKSEL0_PCLK_CAN2_MASK, 28 ) + +#define SET_PCLKSEL0_PCLK_CAN2( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL0_PCLK_CAN2_MASK, 28 ) + +/* PCLKSEL1 */ +#define PCLKSEL1_PCLK_BAT_RAM_MASK 0x00000003U + +#define GET_PCLKSEL1_PCLK_BAT_RAM( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_BAT_RAM_MASK, 0 ) + +#define SET_PCLKSEL1_PCLK_BAT_RAM( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_BAT_RAM_MASK, 0 ) + +#define PCLKSEL1_PCLK_GPIO_MASK 0x0000000cU + +#define GET_PCLKSEL1_PCLK_GPIO( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_GPIO_MASK, 2 ) + +#define SET_PCLKSEL1_PCLK_GPIO( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_GPIO_MASK, 2 ) + +#define PCLKSEL1_PCLK_PCB_MASK 0x00000030U + +#define GET_PCLKSEL1_PCLK_PCB( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_PCB_MASK, 4 ) + +#define SET_PCLKSEL1_PCLK_PCB( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_PCB_MASK, 4 ) + +#define PCLKSEL1_PCLK_I2C1_MASK 0x000000c0U + +#define GET_PCLKSEL1_PCLK_I2C1( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_I2C1_MASK, 6 ) + +#define SET_PCLKSEL1_PCLK_I2C1( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_I2C1_MASK, 6 ) + +#define PCLKSEL1_PCLK_SSP0_MASK 0x00000c00U + +#define GET_PCLKSEL1_PCLK_SSP0( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_SSP0_MASK, 10 ) + +#define SET_PCLKSEL1_PCLK_SSP0( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_SSP0_MASK, 10 ) + +#define PCLKSEL1_PCLK_TIMER2_MASK 0x00003000U + +#define GET_PCLKSEL1_PCLK_TIMER2( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_TIMER2_MASK, 12 ) + +#define SET_PCLKSEL1_PCLK_TIMER2( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_TIMER2_MASK, 12 ) + +#define PCLKSEL1_PCLK_TIMER3_MASK 0x0000c000U + +#define GET_PCLKSEL1_PCLK_TIMER3( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_TIMER3_MASK, 14 ) + +#define SET_PCLKSEL1_PCLK_TIMER3( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_TIMER3_MASK, 14 ) + +#define PCLKSEL1_PCLK_UART2_MASK 0x00030000U + +#define GET_PCLKSEL1_PCLK_UART2( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_UART2_MASK, 16 ) + +#define SET_PCLKSEL1_PCLK_UART2( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_UART2_MASK, 16 ) + +#define PCLKSEL1_PCLK_UART3_MASK 0x000c0000U + +#define GET_PCLKSEL1_PCLK_UART3( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_UART3_MASK, 18 ) + +#define SET_PCLKSEL1_PCLK_UART3( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_UART3_MASK, 18 ) + +#define PCLKSEL1_PCLK_I2C2_MASK 0x00300000U + +#define GET_PCLKSEL1_PCLK_I2C2( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_I2C2_MASK, 20 ) + +#define SET_PCLKSEL1_PCLK_I2C2( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_I2C2_MASK, 20 ) + +#define PCLKSEL1_PCLK_I2S_MASK 0x00c00000U + +#define GET_PCLKSEL1_PCLK_I2S( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_I2S_MASK, 22 ) + +#define SET_PCLKSEL1_PCLK_I2S( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_I2S_MASK, 22 ) + +#define PCLKSEL1_PCLK_MCI_MASK 0x03000000U + +#define GET_PCLKSEL1_PCLK_MCI( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_MCI_MASK, 24 ) + +#define SET_PCLKSEL1_PCLK_MCI( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_MCI_MASK, 24 ) + +#define PCLKSEL1_PCLK_SYSCON_MASK 0x30000000U + +#define GET_PCLKSEL1_PCLK_SYSCON( reg ) \ + GET_FIELD( reg, PCLKSEL1_PCLK_SYSCON_MASK, 28 ) + +#define SET_PCLKSEL1_PCLK_SYSCON( reg, val ) \ + SET_FIELD( reg, val, PCLKSEL1_PCLK_SYSCON_MASK, 28 ) + +/* RTC_ILR */ +#define RTC_ILR_RTCCIF 0x00000001U +#define RTC_ILR_RTCALF 0x00000002U +#define RTC_ILR_RTSSF 0x00000004U + +/* RTC_CCR */ +#define RTC_CCR_CLKEN 0x00000001U +#define RTC_CCR_CTCRST 0x00000002U +#define RTC_CCR_CLKSRC 0x00000010U + +/* GPDMA */ +typedef struct { + uint32_t src; + uint32_t dest; + uint32_t lli; + uint32_t ctrl; +} lpc176x_dma_descriptor; + +typedef struct { + lpc176x_dma_descriptor desc; + uint32_t cfg; +} lpc176x_dma_channel; + +#define GPDMA_CH_NUMBER 2 +#define GPDMA_STATUS_CH_0 0x00000001U +#define GPDMA_STATUS_CH_1 0x00000002U +#define GPDMA_CH_BASE_ADDR( i ) \ + ( (volatile lpc176x_dma_channel *) \ + ( ( i ) ? GPDMA_CH1_BASE_ADDR : GPDMA_CH0_BASE_ADDR ) ) + +/* GPDMA_CONFIG */ +#define GPDMA_CONFIG_EN 0x00000001U +#define GPDMA_CONFIG_MODE 0x00000002U + +/* GPDMA_ENABLED_CHNS */ +#define GPDMA_ENABLED_CHNS_CH0 0x00000001U +#define GPDMA_ENABLED_CHNS_CH1 0x00000002U + +/* GPDMA_CH_CTRL */ +#define GPDMA_CH_CTRL_TSZ_MASK 0x00000fffU + +#define GET_GPDMA_CH_CTRL_TSZ( reg ) \ + GET_FIELD( reg, GPDMA_CH_CTRL_TSZ_MASK, 0 ) + +#define SET_GPDMA_CH_CTRL_TSZ( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CTRL_TSZ_MASK, 0 ) + +#define GPDMA_CH_CTRL_TSZ_MAX 0x00000fffU + +#define GPDMA_CH_CTRL_SBSZ_MASK 0x00007000U + +#define GET_GPDMA_CH_CTRL_SBSZ( reg ) \ + GET_FIELD( reg, GPDMA_CH_CTRL_SBSZ_MASK, 12 ) + +#define SET_GPDMA_CH_CTRL_SBSZ( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CTRL_SBSZ_MASK, 12 ) + +#define GPDMA_CH_CTRL_DBSZ_MASK 0x00038000U + +#define GET_GPDMA_CH_CTRL_DBSZ( reg ) \ + GET_FIELD( reg, GPDMA_CH_CTRL_DBSZ_MASK, 15 ) + +#define SET_GPDMA_CH_CTRL_DBSZ( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CTRL_DBSZ_MASK, 15 ) + +#define GPDMA_CH_CTRL_BSZ_1 0x00000000U + +#define GPDMA_CH_CTRL_BSZ_4 0x00000001U + +#define GPDMA_CH_CTRL_BSZ_8 0x00000002U + +#define GPDMA_CH_CTRL_BSZ_16 0x00000003U + +#define GPDMA_CH_CTRL_BSZ_32 0x00000004U + +#define GPDMA_CH_CTRL_BSZ_64 0x00000005U + +#define GPDMA_CH_CTRL_BSZ_128 0x00000006U + +#define GPDMA_CH_CTRL_BSZ_256 0x00000007U + +#define GPDMA_CH_CTRL_SW_MASK 0x001c0000U + +#define GET_GPDMA_CH_CTRL_SW( reg ) \ + GET_FIELD( reg, GPDMA_CH_CTRL_SW_MASK, 18 ) + +#define SET_GPDMA_CH_CTRL_SW( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CTRL_SW_MASK, 18 ) + +#define GPDMA_CH_CTRL_DW_MASK 0x00e00000U + +#define GET_GPDMA_CH_CTRL_DW( reg ) \ + GET_FIELD( reg, GPDMA_CH_CTRL_DW_MASK, 21 ) + +#define SET_GPDMA_CH_CTRL_DW( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CTRL_DW_MASK, 21 ) + +#define GPDMA_CH_CTRL_W_8 0x00000000U + +#define GPDMA_CH_CTRL_W_16 0x00000001U + +#define GPDMA_CH_CTRL_W_32 0x00000002U + +#define GPDMA_CH_CTRL_SI 0x04000000U + +#define GPDMA_CH_CTRL_DI 0x08000000U + +#define GPDMA_CH_CTRL_PROT_MASK 0x70000000U + +#define GET_GPDMA_CH_CTRL_PROT( reg ) \ + GET_FIELD( reg, GPDMA_CH_CTRL_PROT_MASK, 28 ) + +#define SET_GPDMA_CH_CTRL_PROT( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CTRL_PROT_MASK, 28 ) + +#define GPDMA_CH_CTRL_ITC 0x80000000U + +/* GPDMA_CH_CFG */ +#define GPDMA_CH_CFG_EN 0x00000001U + +#define GPDMA_CH_CFG_SRCPER_MASK 0x0000001eU + +#define GET_GPDMA_CH_CFG_SRCPER( reg ) \ + GET_FIELD( reg, GPDMA_CH_CFG_SRCPER_MASK, 1 ) + +#define SET_GPDMA_CH_CFG_SRCPER( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CFG_SRCPER_MASK, 1 ) + +#define GPDMA_CH_CFG_DESTPER_MASK 0x000003c0U + +#define GET_GPDMA_CH_CFG_DESTPER( reg ) \ + GET_FIELD( reg, GPDMA_CH_CFG_DESTPER_MASK, 6 ) + +#define SET_GPDMA_CH_CFG_DESTPER( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CFG_DESTPER_MASK, 6 ) + +#define GPDMA_CH_CFG_PER_SSP0_TX 0x00000000U + +#define GPDMA_CH_CFG_PER_SSP0_RX 0x00000001U + +#define GPDMA_CH_CFG_PER_SSP1_TX 0x00000002U + +#define GPDMA_CH_CFG_PER_SSP1_RX 0x00000003U + +#define GPDMA_CH_CFG_PER_SD_MMC 0x00000004U + +#define GPDMA_CH_CFG_PER_I2S_CH0 0x00000005U + +#define GPDMA_CH_CFG_PER_I2S_CH1 0x00000006U + +#define GPDMA_CH_CFG_FLOW_MASK 0x00003800U + +#define GET_GPDMA_CH_CFG_FLOW( reg ) \ + GET_FIELD( reg, GPDMA_CH_CFG_FLOW_MASK, 11 ) + +#define SET_GPDMA_CH_CFG_FLOW( reg, val ) \ + SET_FIELD( reg, val, GPDMA_CH_CFG_FLOW_MASK, 11 ) + +#define GPDMA_CH_CFG_FLOW_MEM_TO_MEM_DMA 0x00000000U + +#define GPDMA_CH_CFG_FLOW_MEM_TO_PER_DMA 0x00000001U + +#define GPDMA_CH_CFG_FLOW_PER_TO_MEM_DMA 0x00000002U + +#define GPDMA_CH_CFG_FLOW_PER_TO_PER_DMA 0x00000003U + +#define GPDMA_CH_CFG_FLOW_PER_TO_PER_DEST 0x00000004U + +#define GPDMA_CH_CFG_FLOW_MEM_TO_PER_PER 0x00000005U + +#define GPDMA_CH_CFG_FLOW_PER_TO_MEM_PER 0x00000006U + +#define GPDMA_CH_CFG_FLOW_PER_TO_PER_SRC 0x00000007U + +#define GPDMA_CH_CFG_IE 0x00004000U + +#define GPDMA_CH_CFG_ITC 0x00008000U + +#define GPDMA_CH_CFG_LOCK 0x00010000U + +#define GPDMA_CH_CFG_ACTIVE 0x00020000U + +#define GPDMA_CH_CFG_HALT 0x00040000U + +/* AHBCFG */ +#define AHBCFG_SCHEDULER_UNIFORM 0x00000001U + +#define AHBCFG_BREAK_BURST_MASK 0x00000006U + +#define GET_AHBCFG_BREAK_BURST( reg ) \ + GET_FIELD( reg, AHBCFG_BREAK_BURST_MASK, 1 ) + +#define SET_AHBCFG_BREAK_BURST( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_BREAK_BURST_MASK, 1 ) + +#define AHBCFG_QUANTUM_BUS_CYCLE 0x00000008U + +#define AHBCFG_QUANTUM_SIZE_MASK 0x000000f0U + +#define GET_AHBCFG_QUANTUM_SIZE( reg ) \ + GET_FIELD( reg, AHBCFG_QUANTUM_SIZE_MASK, 4 ) + +#define SET_AHBCFG_QUANTUM_SIZE( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_QUANTUM_SIZE_MASK, 4 ) + +#define AHBCFG_DEFAULT_MASTER_MASK 0x00000700U + +#define GET_AHBCFG_DEFAULT_MASTER( reg ) \ + GET_FIELD( reg, AHBCFG_DEFAULT_MASTER_MASK, 8 ) + +#define SET_AHBCFG_DEFAULT_MASTER( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_DEFAULT_MASTER_MASK, 8 ) + +#define AHBCFG_EP1_MASK 0x00007000U + +#define GET_AHBCFG_EP1( reg ) \ + GET_FIELD( reg, AHBCFG_EP1_MASK, 12 ) + +#define SET_AHBCFG_EP1( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_EP1_MASK, 12 ) + +#define AHBCFG_EP2_MASK 0x00070000U + +#define GET_AHBCFG_EP2( reg ) \ + GET_FIELD( reg, AHBCFG_EP2_MASK, 16 ) + +#define SET_AHBCFG_EP2( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_EP2_MASK, 16 ) + +#define AHBCFG_EP3_MASK 0x00700000U + +#define GET_AHBCFG_EP3( reg ) \ + GET_FIELD( reg, AHBCFG_EP3_MASK, 20 ) + +#define SET_AHBCFG_EP3( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_EP3_MASK, 20 ) + +#define AHBCFG_EP4_MASK 0x07000000U + +#define GET_AHBCFG_EP4( reg ) \ + GET_FIELD( reg, AHBCFG_EP4_MASK, 24 ) + +#define SET_AHBCFG_EP4( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_EP4_MASK, 24 ) + +#define AHBCFG_EP5_MASK 0x70000000U + +#define GET_AHBCFG_EP5( reg ) \ + GET_FIELD( reg, AHBCFG_EP5_MASK, 28 ) + +#define SET_AHBCFG_EP5( reg, val ) \ + SET_FIELD( reg, val, AHBCFG_EP5_MASK, 28 ) + +/* I2S */ +static volatile lpc_i2s * const lpc176x_i2s = (lpc_i2s *) I2S_BASE_ADDR; + +/* ADC */ +#define ADC_CR_SEL( val ) BSP_FLD32( val, 0, 7 ) +#define ADC_CR_SEL_GET( val ) BSP_FLD32GET( val, 0, 7 ) +#define ADC_CR_SEL_SET( reg, val ) BSP_FLD32SET( reg, val, 0, 7 ) +#define ADC_CR_CLKDIV( val ) BSP_FLD32( val, 8, 15 ) +#define ADC_CR_CLKDIV_GET( reg ) BSP_FLD32GET( reg, 8, 15 ) +#define ADC_CR_CLKDIV_SET( reg, val ) BSP_FLD32SET( reg, val, 8, 15 ) +#define ADC_CR_BURST BSP_BIT32( 16 ) +#define ADC_CR_CLKS( val ) BSP_FLD32( val, 17, 19 ) +#define ADC_CR_PDN BSP_BIT32( 21 ) +#define ADC_CR_START( val ) BSP_FLD32( val, 24, 26 ) +#define ADC_CR_EDGE BSP_BIT32( 27 ) + +#define ADC_DR_VALUE( reg ) BSP_FLD32GET( reg, 6, 15 ) +#define ADC_DR_OVERRUN BSP_BIT32( 30 ) +#define ADC_DR_DONE BSP_BIT32( 31 ) + +/* DAC */ +#define DAC_STEPS 1024 +#define DAC_VALUE( val ) BSP_FLD32( val, 6, 15 ) +#define DAC_BIAS BSP_BIT32( 16 ) + +#endif /* LIBBSP_ARM_LPC176X_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/system-clocks.h b/c/src/lib/libbsp/arm/lpc176x/include/system-clocks.h new file mode 100644 index 0000000000..0180141f99 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/system-clocks.h @@ -0,0 +1,91 @@ +/** + * @file + * + * @ingroup lpc176x_clocks + * + * @brief System clocks. + */ + +/* + * Copyright (c) 2008, 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_SYSTEM_CLOCKS_H +#define LIBBSP_ARM_LPC176X_SYSTEM_CLOCKS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup lpc176x_clock System Clocks + * + * @ingroup lpc176x + * + * @brief System clocks. + * + * @{ + */ + +/** + * @brief Initializes the standard timer. + * + * This function uses Timer 1. + */ +void lpc176x_timer_initialize( void ); + +/** + * @brief Returns current standard timer value in CPU clocks. + * + * @return This function uses Timer 1. + */ +static inline unsigned lpc176x_get_timer1( void ) +{ + return LPC176X_T1TC; +} + +/** + * @brief Delay for @a us micro seconds. + * + * This function uses the standard timer and assumes that the CPU + * frequency is in whole MHz numbers. The delay value @a us will be + * converted to CPU ticks and there is no protection against integer + * overflows. + * + * This function uses Timer 1. + */ +void lpc176x_micro_seconds_delay( unsigned us ); + +/** + * @brief Returns the PLL output clock frequency in [Hz]. + * + * @return Returns zero in case of an unexpected PLL input frequency. + */ +unsigned lpc176x_pllclk( void ); + +/** + * @brief Returns the CPU clock frequency in [Hz]. + * + * @return Returns zero in case of an unexpected PLL input frequency. + */ +unsigned lpc176x_cclk( void ); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_SYSTEM_CLOCKS_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h b/c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h new file mode 100644 index 0000000000..f984248e02 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h @@ -0,0 +1,449 @@ +/** + * @file timer-defs.h + * + * @ingroup lpc176x + * + * @brief API definitions of the for the timer of the lpc176x bsp. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_TIMER_DEFS_H +#define LIBBSP_ARM_LPC176X_TIMER_DEFS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Timer 0 */ +#define LPC176X_TMR0_BASE_ADDR 0x40004000U + +#define LPC176X_T0IR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x00U ) ) +#define LPC176X_T0TCR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x04U ) ) +#define LPC176X_T0TC ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x08U ) ) +#define LPC176X_T0PR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x0CU ) ) +#define LPC176X_T0PC ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x10U ) ) +#define LPC176X_T0MCR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x14U ) ) +#define LPC176X_T0MR0 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x18U ) ) +#define LPC176X_T0MR1 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x1CU ) ) +#define LPC176X_T0MR2 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x20U ) ) +#define LPC176X_T0MR3 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x24U ) ) +#define LPC176X_T0CCR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x28U ) ) +#define LPC176X_T0CR0 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x2CU ) ) +#define LPC176X_T0CR1 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x30U ) ) +#define LPC176X_T0CR2 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x34U ) ) +#define LPC176X_T0CR3 ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x38U ) ) +#define LPC176X_T0EMR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x3CU ) ) +#define LPC176X_T0CTCR ( *(volatile uint32_t *) ( LPC176X_TMR0_BASE_ADDR + \ + 0x70U ) ) + +/* Timer 1 */ +#define LPC176X_TMR1_BASE_ADDR 0x40008000U + +#define LPC176X_T1IR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x00U ) ) +#define LPC176X_T1TCR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x04U ) ) +#define LPC176X_T1TC ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x08U ) ) +#define LPC176X_T1PR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x0CU ) ) +#define LPC176X_T1PC ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x10U ) ) +#define LPC176X_T1MCR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x14U ) ) +#define LPC176X_T1MR0 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x18U ) ) +#define LPC176X_T1MR1 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x1CU ) ) +#define LPC176X_T1MR2 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x20U ) ) +#define LPC176X_T1MR3 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x24U ) ) +#define LPC176X_T1CCR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x28U ) ) +#define LPC176X_T1CR0 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x2CU ) ) +#define LPC176X_T1CR1 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x30U ) ) +#define LPC176X_T1CR2 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x34U ) ) +#define LPC176X_T1CR3 ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x38U ) ) +#define LPC176X_T1EMR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x3CU ) ) +#define LPC176X_T1CTCR ( *(volatile uint32_t *) ( LPC176X_TMR1_BASE_ADDR + \ + 0x70U ) ) + +/* Timer 2 */ +#define LPC176X_TMR2_BASE_ADDR 0x40090000U + +#define LPC176X_T2IR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x00U ) ) +#define LPC176X_T2TCR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x04U ) ) +#define LPC176X_T2TC ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x08U ) ) +#define LPC176X_T2PR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x0CU ) ) +#define LPC176X_T2PC ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x10U ) ) +#define LPC176X_T2MCR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x14U ) ) +#define LPC176X_T2MR0 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x18U ) ) +#define LPC176X_T2MR1 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x1CU ) ) +#define LPC176X_T2MR2 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x20U ) ) +#define LPC176X_T2MR3 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x24U ) ) +#define LPC176X_T2CCR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x28U ) ) +#define LPC176X_T2CR0 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x2CU ) ) +#define LPC176X_T2CR1 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x30U ) ) +#define LPC176X_T2CR2 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x34U ) ) +#define LPC176X_T2CR3 ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x38U ) ) +#define LPC176X_T2EMR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x3CU ) ) +#define LPC176X_T2CTCR ( *(volatile uint32_t *) ( LPC176X_TMR2_BASE_ADDR + \ + 0x70U ) ) + +/* Timer 3 */ +#define LPC176X_TMR3_BASE_ADDR 0x40094000U + +#define LPC176X_T3IR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x00U ) ) +#define LPC176X_T3TCR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x04U ) ) +#define LPC176X_T3TC ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x08U ) ) +#define LPC176X_T3PR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x0CU ) ) +#define LPC176X_T3PC ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x10U ) ) +#define LPC176X_T3MCR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x14U ) ) +#define LPC176X_T3MR0 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x18U ) ) +#define LPC176X_T3MR1 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x1CU ) ) +#define LPC176X_T3MR2 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x20U ) ) +#define LPC176X_T3MR3 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x24U ) ) +#define LPC176X_T3CCR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x28U ) ) +#define LPC176X_T3CR0 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x2CU ) ) +#define LPC176X_T3CR1 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x30U ) ) +#define LPC176X_T3CR2 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x34U ) ) +#define LPC176X_T3CR3 ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x38U ) ) +#define LPC176X_T3EMR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x3CU ) ) +#define LPC176X_T3CTCR ( *(volatile uint32_t *) ( LPC176X_TMR3_BASE_ADDR + \ + 0x70U ) ) + +/** + * @brief Represents the timer device registers. + */ +typedef struct { + /** + * @brief Interrupt Register. + */ + volatile uint32_t IR; + /** + * @brief Timer Control Register. + */ + volatile uint32_t TCR; + /** + * @brief Timer Counter. + */ + volatile uint32_t TC; + /** + * @brief Prescale Register. + */ + volatile uint32_t PR; + /** + * @brief Prescale Counter. + */ + volatile uint32_t PC; + /** + * @brief Match Control Register. + */ + volatile uint32_t MCR; + /** + * @brief Match Register (0, 1, 2, 3) + */ + volatile uint32_t MR[ 4 ]; + /** + * @brief Capture Control Register. + */ + volatile uint32_t CCR; + /** + * @brief Capture Register (0, 1) + */ + volatile uint32_t CR[ 2 ]; + volatile uint32_t reserved0; + volatile uint32_t reserved1; + /** + * @brief External Match Register. + */ + volatile uint32_t EMR; + volatile uint32_t reserved2[ 12 ]; + /** + * @brief Count Control Register. + */ + volatile uint32_t CTCR; +} lpc176x_timer_device; + +#define LPC176X_PIN_SELECT_TIMER 3U +#define LPC176X_PINSEL_NO_PORT 999U + +#define LPC176X_TIMER_RESET ( 1U << 1U ) +#define LPC176X_TIMER_START 1U +#define LPC176X_TIMER_MODE_COUNTER_SOURCE_CAP0 0U +#define LPC176X_TIMER_MODE_COUNTER_SOURCE_CAP1 ( 1U << 2U ) +#define LPC176X_TIMER0_CAPTURE_PORTS { 58U, 59U } +#define LPC176X_TIMER1_CAPTURE_PORTS { 50U, 51U } +#define LPC176X_TIMER2_CAPTURE_PORTS { 4U, 5U } +#define LPC176X_TIMER3_CAPTURE_PORTS { 23U, 24U } +#define LPC176X_TIMER0_EMATCH_PORTS { 60U, \ + 61U, \ + LPC176X_PINSEL_NO_PORT, \ + LPC176X_PINSEL_NO_PORT } +#define LPC176X_TIMER1_EMATCH_PORTS { 54U, \ + 57U, \ + LPC176X_PINSEL_NO_PORT, \ + LPC176X_PINSEL_NO_PORT } +#define LPC176X_TIMER2_EMATCH_PORTS { 6U, 7U, 8U, 9U } +#define LPC176X_TIMER3_EMATCH_PORTS { 10U, \ + 11U, \ + LPC176X_PINSEL_NO_PORT, \ + LPC176X_PINSEL_NO_PORT } +#define LPC176X_TIMER_DEFAULT_RESOLUTION 1U +#define LPC176X_TIMER_MCR_MASK 7U +#define LPC176X_TIMER_MCR_MASK_SIZE 3U +#define LPC176X_TIMER_CCR_MASK 7U +#define LPC176X_TIMER_CCR_MASK_SIZE 3U +#define LPC176X_TIMER_EMR_MASK 3U +#define LPC176X_TIMER_EMR_MASK_SIZE 2U +#define LPC176X_TIMER_EMR_MASK_OFFSET 4U +#define LPC176X_TIMER_CLEAR_FUNCTION 0U +#define LPC176X_TIMER_PRESCALER_DIVISOR 1000000U +#define LPC176X_TIMER_VECTOR_NUMBER( timernumber ) ( timernumber + 1U ) +#define LPC176X_TIMER_INTERRUPT_SOURCE_BIT( i ) ( 1U << i ) +#define LPC176X_TIMER_MATCH_FUNCTION_COUNT 8U +#define LPC176X_TIMER_CAPTURE_FUNCTION_COUNT 8U + +#define LPC176X_ISR_NAME_STRING_SIZE 10U + +#define LPC176X_SET_MCR( mcr, match_port, function ) \ + SET_FIELD( mcr, \ + function, \ + ( 0x7U << ( 3U * match_port ) ), \ + ( 3U * match_port ) ) +#define LPC176X_SET_CCR( mcr, capture_port, function ) \ + SET_FIELD( mcr, function, ( 0x7U << ( 3U * capture_port ) ), \ + ( 3U * capture_port ) ) +#define LPC176X_SET_EMR( mcr, match_port, function ) \ + SET_FIELD( mcr, function, ( 0x3U << ( 2U * match_port + 4U ) ), \ + ( 2U * match_port + 4U ) ) + +/** + * @brief Capture ports of a timer. + * + * Enumerated type to define the set of capture ports for a timer device. + */ +typedef enum { + LPC176X_CAPn_0, + LPC176X_CAPn_1, + LPC176X_CAPTURE_PORTS_COUNT +} lpc176x_capture_port; + +/** + * @brief Match ports of a timer. + * + * Enumerated type to define the set of match ports for a timer device. + */ +typedef enum { + LPC176X_MATn_0, + LPC176X_MATn_1, + LPC176X_MATn_2, + LPC176X_MATn_3, + LPC176X_EMATCH_PORTS_COUNT +} lpc176x_match_port; + +/** + * @brief Timer modes of a timer. + * + * Enumerated type to define the set of modes for a timer device. + */ +typedef enum { + LPC176X_TIMER_MODE_TIMER, + LPC176X_TIMER_MODE_COUNTER_RISING_CAP0, + LPC176X_TIMER_MODE_COUNTER_FALLING_CAP0, + LPC176X_TIMER_MODE_COUNTER_BOTH_CAP0, + LPC176X_TIMER_MODE_COUNTER_RISING_CAP1 = ( 1U & ( 1U << 2U ) ), + LPC176X_TIMER_MODE_COUNTER_FALLING_CAP1 = ( 2U & ( 1U << 2U ) ), + LPC176X_TIMER_MODE_COUNTER_BOTH_CAP1 = ( 3U & ( 1U << 2U ) ), +} lpc176x_timer_mode; + +/** + * @brief The timer devices in the board. + * + * Enumerated type to define the timer device's numbers. + */ +typedef enum { + LPC176X_TIMER_0, + LPC176X_TIMER_1, + LPC176X_TIMER_2, + LPC176X_TIMER_3, + LPC176X_TIMER_COUNT +} lpc176x_timer_number; + +/** + * @brief The index for the isr_funct_vector representing the functions + * that attends each possible interrupt source for a timer. + * + * Enumerated type to define the set of isr timer functions . + */ +typedef enum { + LPC176X_MAT0_ISR_FUNCTION, + LPC176X_MAT1_ISR_FUNCTION, + LPC176X_MAT2_ISR_FUNCTION, + LPC176X_MAT3_ISR_FUNCTION, + LPC176X_CAP0_ISR_FUNCTION, + LPC176X_CAP1_ISR_FUNCTION, + LPC176X_ISR_FUNCTIONS_COUNT +} lpc176x_isr_function; + +/** + * @brief The possible functions at match. This options could be + * used together. + * + * Enumerated type to define the set of functions at mach for a + * timer device. + */ +typedef enum { + LPC176X_TIMER_MATCH_FUNCTION_NONE = 0U, + LPC176X_TIMER_MATCH_FUNCTION_INTERRUPT = 1U, + LPC176X_TIMER_MATCH_FUNCTION_RESET = ( 1U << 1U ), + LPC176X_TIMER_MATCH_FUNCTION_STOP = ( 1U << 2U ) +} lpc176x_match_function; + +/** + * @brief The possible functions at capture. This options could + * be used together. + * + * Enumerated type to define the set of functions at capture for + * a timer device. + */ +typedef enum { + LPC176X_TIMER_CAPTURE_FUNCTION_NONE = 0U, + LPC176X_TIMER_CAPTURE_FUNCTION_RISING = 1U, + LPC176X_TIMER_CAPTURE_FUNCTION_FALLING = ( 1U << 1U ), + LPC176X_TIMER_CAPTURE_FUNCTION_INTERRUPT = ( 1U << 2U ) +} lpc176x_capture_function; + +/** + * @brief The possible functions at match, for the external ports. + * + * Enumerated type to define the set of functions at match, for external + * ports, for a timer device. + */ +typedef enum { + LPC176X_TIMER_EXTMATCH_FUNCTION_NONE, + LPC176X_TIMER_EXTMATCH_FUNCTION_CLEAR, + LPC176X_TIMER_EXTMATCH_FUNCTION_SET, + LPC176X_TIMER_EXTMATCH_FUNCTION_TOGGLE +} lpc176x_ext_match_function; + +/** + * @brief A function that attends an interruption for a timer. + * + * @param tnumber Timer number. + * @return Pointer to the match function. + */ +typedef void (*lpc176x_isr_funct) ( const lpc176x_timer_number tnumber ); + +/** + * @brief The vector of functions that attends each possible interrupt + * source for a timer. + */ +typedef lpc176x_isr_funct const lpc176x_isr_funct_vector[ + LPC176X_ISR_FUNCTIONS_COUNT ]; + +/** + * @brief The Timer device representation. + */ +typedef struct { + /** + * @brief The address of the controlling registers for the timer. + */ + lpc176x_timer_device *const device; + /** + * @brief The module for the RTEMS module starting (power and clock). + */ + const lpc176x_module module; + /** + * @brief The Pins for the Capture ports of this timer. + */ + const lpc176x_pin_number pinselcap[ LPC176X_CAPTURE_PORTS_COUNT ]; + /** + * @brief The Pins for the external match ports of this timer. + */ + const lpc176x_pin_number pinselemat[ LPC176X_EMATCH_PORTS_COUNT ]; +} lpc176x_timer; + +/** + * @brief The Timer functions. + */ +typedef struct { + /** + * @brief The vector of isr functions for this timer. + */ + const lpc176x_isr_funct_vector *funct_vector; +} lpc176x_timer_functions; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_TIMER_DEFS_H */ \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/include/timer.h b/c/src/lib/libbsp/arm/lpc176x/include/timer.h new file mode 100644 index 0000000000..944d3cd7dd --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/timer.h @@ -0,0 +1,195 @@ +/** + * @file timer.h + * + * @ingroup lpc176x + * + * @brief Timer API for the lpc176x bsp. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_TIMER_H +#define LIBBSP_ARM_LPC176X_TIMER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief resets timer counter and stops it. + * + * @param tnumber the device to be reseted + * @return RTEMS_SUCCESSFUL if the timer was reseted successfuly. + */ +rtems_status_code lpc176x_timer_reset( lpc176x_timer_number tnumber ); + +/** + * @brief Sets mode of the timer (timer, counter rising, counter falling + * or counter both edges) + * + * @param tnumber: the device to be setted + * @param mode: the desired mode + * @return RTEMS_SUCCESSFUL if the timer's mode was setted successfuly. + */ +rtems_status_code lpc176x_timer_set_mode( + lpc176x_timer_number tnumber, + lpc176x_timer_mode mode +); + +/** + * @brief Starts the timer counter + * + * @param tnumber: the device to be started + * @return RTEMS_SUCCESSFUL if the timer's was started successfuly. + */ +rtems_status_code lpc176x_timer_start( lpc176x_timer_number tnumber ); + +/** + * @brief true if timer is started. + * + * @param tnumber: the timer number to check. + * @param is_started: TRUE if the timer is running. + * @return RTEMS_SUCCESSFUL if the started timer check was successfuly. + */ +rtems_status_code lpc176x_timer_is_started( + lpc176x_timer_number tnumber, + bool *is_started +); + +/** + * @brief sets the resolution in microseconds of the timer + * + * @param tnumber: the device to be modified. + * @param resolution: how many microseconds will mean each timer + * counter unit. + * @return RTEMS_SUCCESSFUL if the timer resolution was setted successfuly. + */ +rtems_status_code lpc176x_timer_set_resolution( + lpc176x_timer_number tnumber, + lpc176x_microseconds resolution +); + +/** + * @brief Configures the timer match + * + * @param tnumber: the device to be modified + * @param match_port: which port of this timer will be setted + * @param function: what the timer should do when match: stop timer, clear, + * and/or interrupt + * @param match_value: the value that the timer should match. + * @return RTEMS_SUCCESSFUL if the timer was configured successfuly. + */ +rtems_status_code lpc176x_timer_match_config( + lpc176x_timer_number tnumber, + lpc176x_match_port match_port, + lpc176x_match_function function, + uint32_t match_value +); + +/** + * @brief Configures the capture ports + * + * @param tnumber: the device to be modified + * @param capture_port: which port of this timer will be setted + * @param function: At which edge/s will the capture work, and + * if it will interrupt + */ +rtems_status_code lpc176x_timer_capture_config( + lpc176x_timer_number tnumber, + lpc176x_capture_port capture_port, + lpc176x_capture_function function +); + +/** + * @brief Configures the external match ports + * + * @param tnumber: the device to be modified + * @param match_port: which match for this timer + * @param function: what should do when match: set, clear toggle or nothing + */ +rtems_status_code lpc176x_timer_external_match_config( + lpc176x_timer_number tnumber, + lpc176x_match_port match_port, + lpc176x_ext_match_function function +); + +/** + * @brief Gets the captured value + * + * @param tnumber: the device to be modified + * @param capnumber: which capture port for this timer + * @return the captured value + */ +uint32_t lpc176x_timer_get_capvalue( + lpc176x_timer_number tnumber, + lpc176x_capture_port capnumber +); + +/** + * @brief Gets the timer value + * + * @param tnumber: the device + * @return the timer value + */ +uint32_t lpc176x_timer_get_timer_value( lpc176x_timer_number tnumber ); + +/** + * @brief Sets the timer value + * + * @param tnumber: the timer to modify. + * @param timer_value the value to set. + */ +rtems_status_code lpc176x_timer_set_timer_value( + lpc176x_timer_number tnumber, + uint32_t lpc176x_timer_value +); + +/** + * @brief Timer generic isroutine. + * + * @param timernumber the number of timer. + */ +void lpc176x_timer_isr( void *lpc176x_timer_number ); + +/** + * @brief Initializes timer in timer mode and resets counter but + * without starting it, and without any capture or + * match function. + * + * @param tnumber which timer + * @return RTEMS_SUCCESSFUL when everything ok. + */ +rtems_status_code lpc176x_timer_init( lpc176x_timer_number tnumber ); + +/** + * @brief Initializes timer in timer mode and resets counter but + * without starting it, and without any capture or + * match function. + * + * @param tnumber which timer to init + * @param vector the functions to be used by the isr. + * @return RTEMS_SUCCESSFUL when everything ok. + */ +rtems_status_code lpc176x_timer_init_with_interrupt( + lpc176x_timer_number tnumber, + const lpc176x_isr_funct_vector *vector +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_TIMER_H */ \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/include/watchdog-defs.h b/c/src/lib/libbsp/arm/lpc176x/include/watchdog-defs.h new file mode 100644 index 0000000000..f91360b3a9 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/watchdog-defs.h @@ -0,0 +1,65 @@ +/** + * @file watchdog-defs.h + * + * @ingroup lpc176x + * + * @brief API definitions of the Watchdog driver for the lpc176x bsp in RTEMS. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_WATCHDOG_DEFS_H +#define LIBBSP_ARM_LPC176X_WATCHDOG_DEFS_H + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define LPC176X_WDMOD_BASE 0x40000000U +#define LPC176X_WDFEED_CON 0XAAU +#define LPC176X_WDFEED_CFG 0X55U +#define LPC176X_WD_PRESCALER_DIVISOR 4000000U +#define LPC176X_WWDT_MOD_WDEN BSP_BIT32( 0 ) +#define LPC176X_WWDT_MOD_WDRESET BSP_BIT32( 1 ) +#define LPC176X_WWDT_MOD_WDTOF BSP_BIT32( 2 ) +#define LPC176X_WWDT_MOD_WDINT BSP_BIT32( 3 ) +#define LPC176X_WWDT_CLKSEL_WDSEL_IRC 0x0U +#define LPC176X_WWDT_CLKSEL_WDSEL_PCLK 0x1U +#define LPC176X_WWDT_CLKSEL_WDSEL_RTC 0x2U +#define LPC176X_WD_INTERRUPT_VECTOR_NUMBER 0U +#define LPC176X_WDMOD ( *(volatile uint32_t *) ( LPC176X_WDMOD_BASE + 0x00U ) ) +#define LPC176X_WDTC ( *(volatile uint32_t *) ( LPC176X_WDMOD_BASE + 0x04U ) ) +#define LPC176X_WDFEED ( *(volatile uint32_t *) ( LPC176X_WDMOD_BASE + \ + 0x08U ) ) +#define LPC176X_WDTV ( *(volatile uint32_t *) ( LPC176X_WDMOD_BASE + 0x0CU ) ) +#define LPC176X_WDCLKSEL ( *(volatile uint32_t *) ( LPC176X_WDMOD_BASE + \ + 0x10U ) ) + +/** + * @brief A function that attends an interruption for a watchdog. + */ +typedef rtems_interrupt_handler lpc176x_wd_isr_funct; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_WATCHDOG_DEFS_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/include/watchdog.h b/c/src/lib/libbsp/arm/lpc176x/include/watchdog.h new file mode 100644 index 0000000000..241180e429 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/include/watchdog.h @@ -0,0 +1,70 @@ +/** + * @file watchdog.h + * + * @ingroup lpc176x + * + * @brief API of the Watchdog driver for the lpc176x bsp in RTEMS. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifndef LIBBSP_ARM_LPC176X_WATCHDOG_H +#define LIBBSP_ARM_LPC176X_WATCHDOG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Checks if the watchdog was executed by software or not. Set when + * the watchdog timer times out, cleared by software. + * + * @return TRUE if the watchdog was executed. + * FALSE otherwise. + */ +bool lpc176x_been_reset_by_watchdog( void ); + +/** + * @brief Resets the watchdog timer. + */ +void lpc176x_watchdog_reset( void ); + +/** + * @brief Configures the watchdog's timer. + * + * @param tcount Timer's out value. + * @return RTEMS_SUCCESSFUL if the watchdog was configured successfully. + */ +rtems_status_code lpc176x_watchdog_config( lpc176x_microseconds tcount ); + +/** + * @brief Configures the timer watchdog using interrupt. + * + * @param tcount Timer's out value. + * @param interrupt Interrupt to register. + * @return RTEMS_SUCCESSFUL if the watchdog was configured successfully + * with interrupts. + */ +rtems_status_code lpc176x_watchdog_config_with_interrupt( + lpc176x_wd_isr_funct interrupt, + lpc176x_microseconds tcount +); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_ARM_LPC176X_WATCHDOG_H */ diff --git a/c/src/lib/libbsp/arm/lpc176x/irq/irq.c b/c/src/lib/libbsp/arm/lpc176x/irq/irq.c new file mode 100644 index 0000000000..3d386fde0f --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/irq/irq.c @@ -0,0 +1,75 @@ +/** + * @file + * + * @ingroup bsp_interrupt + * + * @brief LPC176X interrupt support. + */ + +/* + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +#include +#include +#include +#include +#include + +/** + * @brief Checks if the current interrupt vector lenght is valid or not. + * + * @param vector The current interrupt vector lenght . + * @return TRUE if valid. + * FALSE otherwise. + */ +static inline bool lpc176x_irq_is_valid( const rtems_vector_number vector ) +{ + return vector <= BSP_INTERRUPT_VECTOR_MAX; +} + +void lpc176x_irq_set_priority( + const rtems_vector_number vector, + unsigned priority +) +{ + if ( lpc176x_irq_is_valid( vector ) ) { + if ( priority > LPC176X_IRQ_PRIORITY_VALUE_MAX ) { + priority = LPC176X_IRQ_PRIORITY_VALUE_MAX; + } + + /* else implies that the priority is unlocked. Also, + there is nothing to do. */ + + _ARMV7M_NVIC_Set_priority( (int) vector, (int) ( priority << 3u ) ); + } + + /* else implies that the rtems vector number is invalid. Also, + there is nothing to do. */ +} + +unsigned lpc176x_irq_get_priority( const rtems_vector_number vector ) +{ + unsigned priority; + + if ( lpc176x_irq_is_valid( vector ) ) { + priority = (unsigned) ( _ARMV7M_NVIC_Get_priority( (int) vector ) >> 3u ); + } else { + priority = LPC176X_IRQ_PRIORITY_VALUE_MIN - 1u; + } + + return priority; +} diff --git a/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed-testsuite.tcfg b/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed-testsuite.tcfg new file mode 100644 index 0000000000..910bf59745 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed-testsuite.tcfg @@ -0,0 +1,19 @@ +# +# lpc1768 mbed RTEMS Test Database. +# +# Format is one line per test that is _NOT_ built. +# + +flashdisk01 +utf8proc01 +spstkalloc02 +fsdosfsname01 +jffs2_fserror +jffs2_fslink +jffs2_fspatheval +jffs2_fspermission +jffs2_fsrdwr +jffs2_fssymlink +jffs2_fstime +pppd +mghttpd01 diff --git a/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed.cfg b/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed.cfg new file mode 100644 index 0000000000..4cf24c8797 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed.cfg @@ -0,0 +1,19 @@ +# +# Config file for mbed LPC1768 board. +# + +include $(RTEMS_ROOT)/make/custom/default.cfg + +RTEMS_CPU = arm + +CPU_CFLAGS = -march=armv7-m -mthumb + +CFLAGS_OPTIMIZE_V = -O2 -ggdb3 -DNDEBUG +BINEXT?=.bin +# This defines the operations performed on the linked executable. +# is currently required. +define bsp-post-link + $(OBJCOPY) -O binary --strip-all \ + $(basename $@)$(EXEEXT) $(basename $@)$(BINEXT) + $(SIZE) $(basename $@)$(EXEEXT) +endef diff --git a/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed_ahb_ram.cfg b/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed_ahb_ram.cfg new file mode 100644 index 0000000000..4cf24c8797 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed_ahb_ram.cfg @@ -0,0 +1,19 @@ +# +# Config file for mbed LPC1768 board. +# + +include $(RTEMS_ROOT)/make/custom/default.cfg + +RTEMS_CPU = arm + +CPU_CFLAGS = -march=armv7-m -mthumb + +CFLAGS_OPTIMIZE_V = -O2 -ggdb3 -DNDEBUG +BINEXT?=.bin +# This defines the operations performed on the linked executable. +# is currently required. +define bsp-post-link + $(OBJCOPY) -O binary --strip-all \ + $(basename $@)$(EXEEXT) $(basename $@)$(BINEXT) + $(SIZE) $(basename $@)$(EXEEXT) +endef diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c b/c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c new file mode 100644 index 0000000000..58ff318108 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c @@ -0,0 +1,30 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Idle task. + */ + +/* + * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +void*bsp_idle_thread( const uintptr_t ignored ) +{ + while ( true ) { + } +} diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c b/c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c new file mode 100644 index 0000000000..aadfc452b1 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c @@ -0,0 +1,220 @@ +/** + * @file + * + * @ingroup lpc176x_dma + * + * @brief Direct memory access (DMA) support. + */ + +/* + * Copyright (c) 2008, 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include + +static rtems_id lpc176x_dma_sema_table[ GPDMA_CH_NUMBER ]; +static bool lpc176x_dma_status_table[ GPDMA_CH_NUMBER ]; + +static void lpc176x_dma_copy_handler( void *arg ) +{ + /* Get interrupt status */ + uint32_t tc = GPDMA_INT_TCSTAT; + uint32_t err = GPDMA_INT_ERR_STAT; + + /* Clear interrupt status */ + GPDMA_INT_TCCLR = tc; + GPDMA_INT_ERR_CLR = err; + + if ( ( tc & GPDMA_STATUS_CH_0 ) != 0 ) { + rtems_semaphore_release( lpc176x_dma_sema_table[ 0 ] ); + } + + /* else implies that the channel is not the 0. Also, + there is nothing to do. */ + + lpc176x_dma_status_table[ 0 ] = ( err & GPDMA_STATUS_CH_0 ) == 0; + + if ( ( tc & GPDMA_STATUS_CH_1 ) != 0 ) { + rtems_semaphore_release( lpc176x_dma_sema_table[ 1 ] ); + } + + /* else implies that the channel is not the 1. Also, + there is nothing to do. */ + + lpc176x_dma_status_table[ 1 ] = ( err & GPDMA_STATUS_CH_1 ) == 0; +} + +rtems_status_code lpc176x_dma_copy_initialize( void ) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + rtems_id id0 = RTEMS_ID_NONE; + rtems_id id1 = RTEMS_ID_NONE; + + /* Create semaphore for channel 0 */ + status_code = rtems_semaphore_create( rtems_build_name( 'D', 'M', 'A', '0' ), + 0, + RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &id0 ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + return status_code; + } + + /* else implies that the semaphore to the channel 0 was created succefully. + Also, there is nothing to do. */ + + /* Create semaphore for channel 1 */ + status_code = rtems_semaphore_create( rtems_build_name( 'D', 'M', 'A', '1' ), + 0, + RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &id1 ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + rtems_semaphore_delete( id0 ); + + return status_code; + } + + /* else implies that the semaphore to the channel 1 was created succefully. + Also, there is nothing to do. */ + + /* Install DMA interrupt handler */ + status_code = rtems_interrupt_handler_install( LPC176X_IRQ_DMA, + "DMA copy", + RTEMS_INTERRUPT_UNIQUE, + lpc176x_dma_copy_handler, + NULL ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + rtems_semaphore_delete( id0 ); + rtems_semaphore_delete( id1 ); + + return status_code; + } + + /* else implies that the interrupt handler was installed succefully. Also, + there is nothing to do. */ + + /* Initialize global data */ + lpc176x_dma_sema_table[ 0 ] = id0; + lpc176x_dma_sema_table[ 1 ] = id1; + + return RTEMS_SUCCESSFUL; +} + +rtems_status_code lpc176x_dma_copy_release( void ) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + rtems_status_code status_code_aux = RTEMS_SUCCESSFUL; + + status_code = rtems_interrupt_handler_remove( LPC176X_IRQ_DMA, + lpc176x_dma_copy_handler, + NULL ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + status_code_aux = status_code; + } + + /* else implies that the interrupt handler was removed succefully. Also, + there is nothing to do. */ + + status_code = rtems_semaphore_delete( lpc176x_dma_sema_table[ 0 ] ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + status_code_aux = status_code; + } + + /* else implies that the semaphore to the channel 0 was deleted succefully. + Also, there is nothing to do. */ + + status_code = rtems_semaphore_delete( lpc176x_dma_sema_table[ 1 ] ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + status_code_aux = status_code; + } + + /* else implies that the semaphore to the channel 1 was deleted succefully. + Also, there is nothing to do. */ + + return status_code_aux; +} + +rtems_status_code lpc176x_dma_copy( + unsigned channel, + const void *const dest, + const void *const src, + size_t n, + const size_t width +) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + volatile lpc176x_dma_channel *e = GPDMA_CH_BASE_ADDR( channel ); + uint32_t w = GPDMA_CH_CTRL_W_8; + + switch ( width ) { + case 4: + w = GPDMA_CH_CTRL_W_32; + break; + case 2: + w = GPDMA_CH_CTRL_W_16; + break; + } + + n = n >> w; + + if ( n > 0 && n < 4096 ) { + e->desc.src = (uint32_t) src; + e->desc.dest = (uint32_t) dest; + e->desc.lli = 0; + e->desc.ctrl = SET_GPDMA_CH_CTRL_TSZ( 0, n ) | + SET_GPDMA_CH_CTRL_SBSZ( 0, GPDMA_CH_CTRL_BSZ_1 ) | + SET_GPDMA_CH_CTRL_DBSZ( 0, GPDMA_CH_CTRL_BSZ_1 ) | + SET_GPDMA_CH_CTRL_SW( 0, w ) | + SET_GPDMA_CH_CTRL_DW( 0, w ) | + GPDMA_CH_CTRL_ITC | + GPDMA_CH_CTRL_SI | + GPDMA_CH_CTRL_DI; + e->cfg = SET_GPDMA_CH_CFG_FLOW( 0, GPDMA_CH_CFG_FLOW_MEM_TO_MEM_DMA ) | + GPDMA_CH_CFG_IE | + GPDMA_CH_CFG_ITC | + GPDMA_CH_CFG_EN; + } else { + status_code = RTEMS_INVALID_SIZE; + } + + return status_code; +} + +rtems_status_code lpc176x_dma_copy_wait( const unsigned channel ) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + + status_code = rtems_semaphore_obtain( lpc176x_dma_sema_table[ channel ], + RTEMS_WAIT, + RTEMS_NO_TIMEOUT ); + + if ( status_code != RTEMS_SUCCESSFUL ) { + return status_code; + } + + /* else implies that the semaphore was obtained succefully. Also, + there is nothing to do. */ + + status_code = lpc176x_dma_status_table[ channel ] + ? RTEMS_SUCCESSFUL : RTEMS_IO_ERROR; + + return status_code; +} diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/dma.c b/c/src/lib/libbsp/arm/lpc176x/misc/dma.c new file mode 100644 index 0000000000..97b32c940c --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/misc/dma.c @@ -0,0 +1,117 @@ +/** + * @file + * + * @ingroup lpc176x_dma + * + * @brief Direct memory access (DMA) support. + */ + +/* + * Copyright (c) 2008-2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include + +/** + * @brief Table that indicates if a channel is currently occupied. + */ +static bool lpc176x_dma_channel_occupation[ GPDMA_CH_NUMBER ]; + +void lpc176x_dma_initialize( void ) +{ + /* Enable module power */ + lpc176x_module_enable( LPC176X_MODULE_GPDMA, LPC176X_MODULE_PCLK_DEFAULT ); + + /* Disable module */ + GPDMA_CONFIG = 0u; + + /* Reset registers */ + GPDMA_SOFT_SREQ = 0u; + GPDMA_SOFT_BREQ = 0u; + GPDMA_SOFT_LSREQ = 0u; + GPDMA_SOFT_LBREQ = 0u; + GPDMA_SYNC = 0u; + GPDMA_CH0_CFG = 0u; + GPDMA_CH1_CFG = 0u; + + /* Enable module */ +#if BYTE_ORDER == LITTLE_ENDIAN + GPDMA_CONFIG = GPDMA_CONFIG_EN; +#else + GPDMA_CONFIG = GPDMA_CONFIG_EN | GPDMA_CONFIG_MODE; +#endif +} + +rtems_status_code lpc176x_dma_channel_obtain( const unsigned channel ) +{ + rtems_status_code status_code = RTEMS_INVALID_ID; + + if ( channel < GPDMA_CH_NUMBER ) { + rtems_interrupt_level level = 0u; + bool occupation = true; + + rtems_interrupt_disable( level ); + occupation = lpc176x_dma_channel_occupation[ channel ]; + lpc176x_dma_channel_occupation[ channel ] = true; + rtems_interrupt_enable( level ); + + status_code = occupation ? RTEMS_RESOURCE_IN_USE : RTEMS_SUCCESSFUL; + } + + /* else implies that the channel is not valid. Also, + there is nothing to do. */ + + return status_code; +} + +void lpc176x_dma_channel_release( const unsigned channel ) +{ + if ( channel < GPDMA_CH_NUMBER ) { + lpc176x_dma_channel_occupation[ channel ] = false; + } + + /* else implies that the channel is not valid. Also, + there is nothing to do. */ +} + +void lpc176x_dma_channel_disable( + const unsigned channel, + const bool force +) +{ + if ( channel < GPDMA_CH_NUMBER ) { + volatile lpc176x_dma_channel *ch = GPDMA_CH_BASE_ADDR( channel ); + uint32_t cfg = ch->cfg; + + if ( !force ) { + /* Halt */ + ch->cfg |= GPDMA_CH_CFG_HALT; + + /* Wait for inactive */ + do { + cfg = ch->cfg; + } while ( ( cfg & GPDMA_CH_CFG_ACTIVE ) != 0u ); + } + + /* else implies that the channel is not to be forced. Also, + there is nothing to do. */ + + /* Disable */ + ch->cfg &= ~GPDMA_CH_CFG_EN; + } + + /* else implies that the channel is not valid. Also, + there is nothing to do. */ +} diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/io.c b/c/src/lib/libbsp/arm/lpc176x/misc/io.c new file mode 100644 index 0000000000..59b357dd0e --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/misc/io.c @@ -0,0 +1,334 @@ +/** + * @file io.c + * + * @ingroup lpc176x + * + * @brief Input/output module methods. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include +#include +#include + +/** + * @brief Modules table according to the LPC176x + */ +static const lpc176x_module_entry lpc176x_module_table[] = { + LPC176X_MODULE_ENTRY( LPC176X_MODULE_WD, 0, 1, 0 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_ADC, 1, 1, 12 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_CAN_0, 1, 1, 13 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_CAN_1, 1, 1, 14 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_DAC, 0, 1, 11 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_GPDMA, 1, 1, 29 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_GPIO, 0, 1, 15 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_I2S, 1, 1, 27 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_MCI, 1, 1, 28 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_MCPWM, 1, 1, 17 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_PCB, 0, 1, 18 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_PWM_0, 1, 1, 5 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_PWM_1, 1, 1, 6 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_QEI, 1, 1, 18 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_RTC, 1, 1, 9 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_SYSCON, 0, 1, 30 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_TIMER_0, 1, 1, 1 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_TIMER_1, 1, 1, 2 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_TIMER_2, 1, 1, 22 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_TIMER_3, 1, 1, 23 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_UART_0, 1, 1, 3 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_UART_1, 1, 1, 4 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_UART_2, 1, 1, 24 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_UART_3, 1, 1, 25 ), + LPC176X_MODULE_ENTRY( LPC176X_MODULE_USB, 1, 0, 31 ) +}; + +inline void lpc176x_pin_select( + const uint32_t pin, + const lpc176x_pin_function function +) +{ + assert( pin <= LPC176X_IO_INDEX_MAX + && function < LPC176X_PIN_FUNCTION_COUNT ); + const uint32_t pin_selected = LPC176X_PIN_SELECT( pin ); + volatile uint32_t *const pinsel = &LPC176X_PINSEL[ pin_selected ]; + const uint32_t shift = LPC176X_PIN_SELECT_SHIFT( pin ); + *pinsel = SET_FIELD( *pinsel, function, + LPC176X_PIN_SELECT_MASK << shift, shift ); +} + +/** + * @brief Checks if the module has power. + * + * @param has_power Power. + * @param index Index to shift. + * @param turn_on Turn on/off the power. + * @param level Interrupts value. + */ +static rtems_status_code check_power( + const bool has_power, + const unsigned index, + const bool turn_on, + rtems_interrupt_level level +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( index <= LPC176X_MODULE_BITS_COUNT ) { + if ( has_power ) { + rtems_interrupt_disable( level ); + + if ( turn_on ) { + LPC176X_SCB.pconp |= 1u << index; + } else { + LPC176X_SCB.pconp &= ~( 1u << index ); + } + + rtems_interrupt_enable( level ); + } + + /* else implies that the module has not power. Also, + there is nothing to do. */ + + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies an invalid index number. Also, the function + does not return successful. */ + + return status_code; +} + +/** + * @brief Sets the correct value according to the specific peripheral clock. + * + * @param is_first_pclksel Represents the first pclksel. + * @param clock The clock to set for this module. + * @param clock_shift Value to clock shift. + */ +static inline void set_pclksel_value( + const uint32_t pclksel, + const lpc176x_module_clock clock, + const unsigned clock_shift +) +{ + assert( pclksel < LPC176X_SCB_PCLKSEL_COUNT ); + const uint32_t setclock = ( clock << clock_shift ); + const uint32_t mask = ~( LPC176X_MODULE_CLOCK_MASK << clock_shift ); + LPC176X_SCB.pclksel[ pclksel ] = ( LPC176X_SCB.pclksel[ pclksel ] & mask ) | + setclock; +} + +/** + * @brief Checks if the module has clock. + * + * @param has_clock Clock. + * @param index Index to shift. + * @param clock The clock to set for this module. + * @param level Interrupts value. + */ +static rtems_status_code check_clock( + const bool has_clock, + const unsigned index, + const lpc176x_module_clock clock, + rtems_interrupt_level level +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( index <= LPC176X_MODULE_BITS_COUNT ) { + if ( has_clock ) { + unsigned clock_shift = 2u * index; + rtems_interrupt_disable( level ); + + if ( clock_shift < LPC176X_MODULE_BITS_COUNT ) { + /* Sets the pclksel 0. */ + set_pclksel_value( LPC176X_SCB_PCLKSEL0, clock, clock_shift ); + } else { + /* Sets the pclksel 1. */ + clock_shift -= LPC176X_MODULE_BITS_COUNT; + set_pclksel_value( LPC176X_SCB_PCLKSEL1, clock, clock_shift ); + } + + rtems_interrupt_enable( level ); + } + + /* else implies that the module has not clock. Also, + there is nothing to do. */ + + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies an invalid index number. Also, the function + does not return successful. */ + + return status_code; +} + +/** + * @brief Checks the usb module. + * + * @return RTEMS_SUCCESFUL if the usb module is correct. + */ +static rtems_status_code check_usb_module( void ) +{ + rtems_status_code status_code = RTEMS_INCORRECT_STATE; + const uint32_t pllclk = lpc176x_pllclk(); + const uint32_t usbclk = LPC176X_USB_CLOCK; + + if ( pllclk % usbclk == 0u ) { + const uint32_t usbdiv = pllclk / usbclk; + + LPC176X_SCB.usbclksel = LPC176X_SCB_USBCLKSEL_USBDIV( usbdiv ) | + LPC176X_SCB_USBCLKSEL_USBSEL( 1 ); + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the module has an incorrect pllclk or usbclk value. + Also, there is nothing to do. */ + + return status_code; +} + +/** + * @brief Enables the current module. + * + * @param module Current module to enable/disable. + * @param clock The clock to set for this module. + * @param enable TRUE if the module is enable. + * @return RTEMS_SUCCESSFULL if the module was enabled successfully. + */ +static rtems_status_code enable_disable_module( + const lpc176x_module module, + const lpc176x_module_clock clock, + const bool enable +) +{ + rtems_status_code status_code; + rtems_interrupt_level level = 0u; + + const bool has_power = lpc176x_module_table[ module ].power; + const bool has_clock = lpc176x_module_table[ module ].clock; + const unsigned index = lpc176x_module_table[ module ].index; + + assert( index <= LPC176X_MODULE_BITS_COUNT ); + + /* Enable or disable module */ + if ( enable ) { + status_code = check_power( has_power, index, true, level ); + RTEMS_CHECK_SC( status_code, + "Checking index shift to turn on power of the module." ); + + if ( module != LPC176X_MODULE_USB ) { + status_code = check_clock( has_clock, index, clock, level ); + RTEMS_CHECK_SC( status_code, + "Checking index shift to set pclksel to the current module." ); + } else { + status_code = check_usb_module(); + RTEMS_CHECK_SC( status_code, + "Checking pll clock to set usb clock to the current module." ); + } + } else { + status_code = check_power( has_power, index, false, level ); + RTEMS_CHECK_SC( status_code, + "Checking index shift to turn off power of the module." ); + } + + return status_code; +} + +/** + * @brief Enables the module power and clock. + * + * @param module Device to enable. + * @param clock The clock to set for this module. + * @param enable Enable or disable the module. + * @return RTEMS_SUCCESSFULL if the module was enabled succesfully. + */ +static rtems_status_code lpc176x_module_do_enable( + const lpc176x_module module, + lpc176x_module_clock clock, + const bool enable +) +{ + rtems_status_code status_code = RTEMS_SUCCESSFUL; + + if ( (unsigned) module >= LPC176X_MODULE_COUNT ) { + return RTEMS_INVALID_ID; + } + + /* else implies that the module has a correct value. Also, + there is nothing to do. */ + + if ( clock == LPC176X_MODULE_PCLK_DEFAULT ) { +#if ( LPC176X_PCLKDIV == 1u ) + clock = LPC176X_MODULE_CCLK; +#elif ( LPC176X_PCLKDIV == 2u ) + clock = LPC176X_MODULE_CCLK_2; +#elif ( LPC176X_PCLKDIV == 4u ) + clock = LPC176X_MODULE_CCLK_4; +#elif ( LPC176X_PCLKDIV == 8u ) + clock = LPC176X_MODULE_CCLK_8; +#else +#error "Unexpected clock divisor." +#endif + } + + /* else implies that the clock has a correct divisor. */ + + if ( ( clock & ~LPC176X_MODULE_CLOCK_MASK ) == 0u ) { + status_code = enable_disable_module( module, clock, enable ); + RTEMS_CHECK_SC( status_code, "Checking the module to enable/disable." ); + } else { + status_code = RTEMS_INVALID_CLOCK; + } + + return status_code; +} + +inline rtems_status_code lpc176x_module_enable( + const lpc176x_module module, + lpc176x_module_clock clock +) +{ + return lpc176x_module_do_enable( module, clock, true ); +} + +inline rtems_status_code lpc176x_module_disable( const lpc176x_module module ) +{ + return lpc176x_module_do_enable( module, + LPC176X_MODULE_PCLK_DEFAULT, + false ); +} + +bool lpc176x_module_is_enabled( const lpc176x_module module ) +{ + assert( (unsigned) module < LPC176X_MODULE_COUNT ); + + const bool has_power = lpc176x_module_table[ module ].power; + bool enabled; + + if ( has_power ) { + const unsigned index = lpc176x_module_table[ module ].index; + const uint32_t pconp = LPC176X_SCB.pconp; + + enabled = ( pconp & ( 1u << index ) ) != 0u; + } else { + enabled = true; + } + + return enabled; +} diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/restart.c b/c/src/lib/libbsp/arm/lpc176x/misc/restart.c new file mode 100644 index 0000000000..f39ae19930 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/misc/restart.c @@ -0,0 +1,34 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Restart implementation. + */ + +/* + * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +void bsp_restart( const void const *addr ) +{ + rtems_interrupt_level level; + + void (*start) ( void ) = addr; + + rtems_interrupt_disable( level ); + ( *start )(); +} diff --git a/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c b/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c new file mode 100644 index 0000000000..6b6ef9e769 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c @@ -0,0 +1,124 @@ +/** + * @file + * + * @ingroup lpc176x_clocks + * + * @brief System clocks. + */ + +/* + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +/** + * @brief Internal RC oscillator frequency in [Hz]. + */ +#define LPC176X_OSCILLATOR_INTERNAL 4000000u + +#ifndef LPC176X_OSCILLATOR_MAIN +#error "unknown main oscillator frequency" +#endif + +#ifndef LPC176X_OSCILLATOR_RTC +#error "unknown RTC oscillator frequency" +#endif + +inline unsigned lpc176x_sysclk( void ); + +void lpc176x_timer_initialize( void ) +{ + /* Reset timer */ + LPC176X_T1TCR = TCR_RST; + /* Set timer mode */ + LPC176X_T1CTCR = 0u; + /* Set prescaler to zero */ + LPC176X_T1PR = 0u; + /* Reset all interrupt flags */ + LPC176X_T1IR = 0xffU; + /* Do not stop on a match */ + LPC176X_T1MCR = 0u; + /* No captures */ + LPC176X_T1CCR = 0u; + /* Start timer */ + LPC176X_T1TCR = TCR_EN; +} + +void lpc176x_micro_seconds_delay( const unsigned us ) +{ + const unsigned start = lpc176x_get_timer1(); + const unsigned delay = us * ( LPC176X_PCLK / 1000000u ); + unsigned elapsed = 0u; + + do { + elapsed = lpc176x_get_timer1() - start; + } while ( elapsed < delay ); +} + +unsigned lpc176x_sysclk( void ) +{ + return ( LPC176X_SCB.clksrcsel & LPC176X_SCB_CLKSRCSEL_CLKSRC ) != 0u ? + LPC176X_OSCILLATOR_MAIN : LPC176X_OSCILLATOR_INTERNAL; +} + +unsigned lpc176x_pllclk( void ) +{ + const unsigned sysclk = lpc176x_sysclk(); + const unsigned pllstat = ( LPC176X_SCB.pll_0 ).stat; + const unsigned enabled_and_locked = LPC176X_PLL_STAT_PLLE | + LPC176X_PLL_STAT_PLOCK; + unsigned pllclk = 0u; + + if ( ( pllstat & enabled_and_locked ) == enabled_and_locked ) { + unsigned m = LPC176X_PLL_SEL_MSEL_GET( pllstat ) + 1u; + pllclk = sysclk * m; + } + + /* else implies that the pllstat is unlocked. Also, + there is nothing to do. */ + + return pllclk; +} + +unsigned lpc176x_cclk( void ) +{ + const unsigned cclksel = LPC176X_SCB.cclksel; + unsigned cclk_in = 0u; + unsigned cclk = 0u; + + if ( ( cclksel & LPC176X_SCB_CCLKSEL_CCLKSEL ) != 0u ) { + cclk_in = lpc176x_pllclk(); + } else { + cclk_in = lpc176x_sysclk(); + } + + cclk = cclk_in / LPC176X_SCB_CCLKSEL_CCLKDIV_GET( cclksel ); + + return cclk; +} + +CPU_Counter_ticks _CPU_Counter_read( void ) +{ + return lpc176x_get_timer1(); +} + +inline CPU_Counter_ticks _CPU_Counter_difference( + CPU_Counter_ticks second, + CPU_Counter_ticks first +) +{ + return second - first; +} + diff --git a/c/src/lib/libbsp/arm/lpc176x/preinstall.am b/c/src/lib/libbsp/arm/lpc176x/preinstall.am new file mode 100644 index 0000000000..cea255b046 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/preinstall.am @@ -0,0 +1,167 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES += $(PREINSTALL_DIRS) + +all-local: $(TMPINSTALL_FILES) + +TMPINSTALL_FILES = +CLEANFILES = $(TMPINSTALL_FILES) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES += $(PREINSTALL_FILES) + +$(PROJECT_LIB)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_LIB) + @: > $(PROJECT_LIB)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp) + +$(PROJECT_INCLUDE)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE) + @: > $(PROJECT_INCLUDE)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/bsp + @: > $(PROJECT_INCLUDE)/bsp/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp) + +$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs +PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs + +$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h + +$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h + +$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h + +$(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bootcard.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h + +$(PROJECT_INCLUDE)/bsp/utility.h: ../../shared/include/utility.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/utility.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/utility.h + +$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h + +$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h + +$(PROJECT_INCLUDE)/bsp/stackalloc.h: ../../shared/include/stackalloc.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/stackalloc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/stackalloc.h + +$(PROJECT_INCLUDE)/bsp/uart-output-char.h: ../../shared/include/uart-output-char.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/uart-output-char.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/uart-output-char.h + +$(PROJECT_INCLUDE)/bsp/tod.h: ../../shared/tod.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/tod.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/tod.h + +$(PROJECT_INCLUDE)/bsp/start.h: ../shared/include/start.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/start.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/start.h + +$(PROJECT_INCLUDE)/bsp/lpc-timer.h: ../shared/lpc/include/lpc-timer.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-timer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-timer.h + +$(PROJECT_INCLUDE)/bsp/lpc-i2s.h: ../shared/lpc/include/lpc-i2s.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-i2s.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-i2s.h + +$(PROJECT_INCLUDE)/bsp/lpc-dma.h: ../shared/lpc/include/lpc-dma.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-dma.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-dma.h + +$(PROJECT_INCLUDE)/bsp/armv7m-irq.h: ../shared/armv7m/include/armv7m-irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/armv7m-irq.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/armv7m-irq.h + +$(PROJECT_INCLUDE)/bsp/dma.h: include/dma.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/dma.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/dma.h + +$(PROJECT_INCLUDE)/bsp/io-defs.h: include/io-defs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/io-defs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/io-defs.h + +$(PROJECT_INCLUDE)/bsp/io.h: include/io.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/io.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/io.h + +$(PROJECT_INCLUDE)/bsp/common-types.h: include/common-types.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/common-types.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/common-types.h + +$(PROJECT_INCLUDE)/bsp/gpio-defs.h: include/gpio-defs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gpio-defs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gpio-defs.h + +$(PROJECT_INCLUDE)/bsp/gpio.h: include/gpio.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/gpio.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/gpio.h + +$(PROJECT_INCLUDE)/bsp/timer-defs.h: include/timer-defs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/timer-defs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/timer-defs.h + +$(PROJECT_INCLUDE)/bsp/timer.h: include/timer.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/timer.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/timer.h + +$(PROJECT_INCLUDE)/bsp/watchdog.h: include/watchdog.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/watchdog.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/watchdog.h + +$(PROJECT_INCLUDE)/bsp/watchdog-defs.h: include/watchdog-defs.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/watchdog-defs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/watchdog-defs.h + +$(PROJECT_INCLUDE)/bsp/irq.h: include/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h + +$(PROJECT_INCLUDE)/bsp/lpc176x.h: include/lpc176x.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc176x.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc176x.h + +$(PROJECT_INCLUDE)/bsp/lpc-clock-config.h: include/lpc-clock-config.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/lpc-clock-config.h + +$(PROJECT_INCLUDE)/bsp/system-clocks.h: include/system-clocks.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/system-clocks.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/system-clocks.h + +$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h + +$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT) +TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT) + +$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds +TMPINSTALL_FILES += $(PROJECT_LIB)/linkcmds + diff --git a/c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c b/c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c new file mode 100644 index 0000000000..4abdd1dd35 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c @@ -0,0 +1,127 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief RTC configuration. + */ + +/* + * Copyright (c) 2008 + * Embedded Brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * rtems@embedded-brains.de + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +#define LPC176X_RTC_NUMBER 1U + +void bsp_rtc_initialize( void ); +int bsp_rtc_get_time( rtems_time_of_day *tod ); +int bsp_rtc_set_time( const rtems_time_of_day *tod ); +bool bsp_rtc_probe( void ); + +/** + * @brief Initialize the rtc device. + */ +void bsp_rtc_initialize( void ) +{ + /* Enable module power */ + lpc176x_module_enable( LPC176X_MODULE_RTC, LPC176X_MODULE_PCLK_DEFAULT ); + + /* Enable the RTC and use external clock */ + RTC_CCR = RTC_CCR_CLKEN | RTC_CCR_CLKSRC; + + /* Disable interrupts */ + RTC_CIIR = 0U; + RTC_CISS = 0U; + RTC_AMR = 0xFFU; + + /* Clear interrupts */ + RTC_ILR = RTC_ILR_RTCCIF | RTC_ILR_RTCALF | RTC_ILR_RTSSF; +} + +/** + * @brief Gets the information according to the current time. + * + * @param tod Value to be modified. + * @return 0 + */ +int bsp_rtc_get_time( rtems_time_of_day *tod ) +{ + tod->ticks = 0; + tod->second = RTC_SEC; + tod->minute = RTC_MIN; + tod->hour = RTC_HOUR; + tod->day = RTC_DOM; + tod->month = RTC_MONTH; + tod->year = RTC_YEAR; + + return 0; +} + +/** + * @brief Sets the information according to the current time. + * + * @param tod Value to get the new information. + * @return 0 + */ +int bsp_rtc_set_time( const rtems_time_of_day *tod ) +{ + RTC_SEC = tod->second; + RTC_MIN = tod->minute; + RTC_HOUR = tod->hour; + RTC_DOM = tod->day; + RTC_MONTH = tod->month; + RTC_YEAR = tod->year; + + return 0; +} + +/** + * @brief Used to probe. At the moment is not used. + * + * @return true. + */ +bool bsp_rtc_probe( void ) +{ + return true; +} + +/** + * @brief Represents the real time clock options. + */ +const rtc_fns lpc176x_rtc_ops = { + .deviceInitialize = (void *) bsp_rtc_initialize, + .deviceGetTime = (void *) bsp_rtc_get_time, + .deviceSetTime = (void *) bsp_rtc_set_time +}; + +size_t RTC_Count = LPC176X_RTC_NUMBER; + +rtems_device_minor_number RTC_Minor = 0; + +/** + * @brief Table to describes the rtc device. + */ +rtc_tbl RTC_Table[ LPC176X_RTC_NUMBER ] = { + { + .sDeviceName = "/dev/rtc", + .deviceType = RTC_CUSTOM, + .pDeviceFns = &lpc176x_rtc_ops, + .deviceProbe = (void *) bsp_rtc_probe, + .pDeviceParams = NULL, + .ulCtrlPort1 = 0, + .ulDataPort = 0, + .getRegister = NULL, + .setRegister = NULL + } +}; diff --git a/c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c b/c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c new file mode 100644 index 0000000000..8ebd2a10a5 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c @@ -0,0 +1,42 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Reset code. + */ + +/* + * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include + +#include +#include +#include + +BSP_START_TEXT_SECTION __attribute__( ( flatten ) ) void bsp_reset( void ) +{ + rtems_interrupt_level level; + + rtems_interrupt_disable( level ); + + _ARMV7M_SCB->aircr = ARMV7M_SCB_AIRCR_VECTKEY | + ARMV7M_SCB_AIRCR_SYSRESETREQ; + + while ( true ) { + /* Do nothing */ + } +} diff --git a/c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c b/c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c new file mode 100644 index 0000000000..5d70eafea7 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c @@ -0,0 +1,89 @@ +/** + * @file + * + * @ingroup lpc176x + * + * @brief Startup code. + */ + +/* + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef LPC176X_HEAP_EXTEND +LINKER_SYMBOL( lpc176x_region_heap_0_begin ); +LINKER_SYMBOL( lpc176x_region_heap_0_size ); +LINKER_SYMBOL( lpc176x_region_heap_0_end ); +LINKER_SYMBOL( lpc176x_region_heap_1_begin ); +LINKER_SYMBOL( lpc176x_region_heap_1_size ); +LINKER_SYMBOL( lpc176x_region_heap_1_end ); +extern Heap_Control *RTEMS_Malloc_Heap; +#endif + +void bsp_pretasking_hook( void ) +{ +#ifdef LPC176X_HEAP_EXTEND + _Heap_Extend( RTEMS_Malloc_Heap, + lpc176x_region_heap_0_begin, + (uintptr_t) lpc176x_region_heap_0_size, + NULL ); + _Heap_Extend( RTEMS_Malloc_Heap, + lpc176x_region_heap_1_begin, + (uintptr_t) lpc176x_region_heap_1_size, + NULL ); +#endif +} + +/** + * @brief Console initialization + */ +static void initialize_console( void ) +{ +#ifdef LPC176X_CONFIG_CONSOLE + + lpc176x_module_enable( LPC176X_MODULE_UART_0, LPC176X_MODULE_PCLK_DEFAULT ); + + lpc176x_pin_select( LPC176X_PIN_UART_0_TXD, LPC176X_PIN_FUNCTION_01 ); + lpc176x_pin_select( LPC176X_PIN_UART_0_RXD, LPC176X_PIN_FUNCTION_01 ); + + BSP_CONSOLE_UART_INIT( LPC176X_PCLK / 16 / LPC176X_UART_BAUD ); +#endif +} + +void bsp_start( void ) +{ + /* Initialize console */ + initialize_console(); + + /*Initialize timer*/ + lpc176x_timer_init( LPC176X_TIMER_1 ); + lpc176x_timer_start( LPC176X_TIMER_1 ); + + /* Interrupts */ + bsp_interrupt_initialize(); + + /* DMA */ + lpc176x_dma_initialize(); +} \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/startup/bspstarthooks.c b/c/src/lib/libbsp/arm/lpc176x/startup/bspstarthooks.c new file mode 100644 index 0000000000..476a89cf78 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/startup/bspstarthooks.c @@ -0,0 +1,227 @@ +/** + * @file bspstarthooks.c + * + * @ingroup lpc176x + * + * @brief First configurations and initializations to the correct + * functionality of the board. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include + +/** + * @brief Initializes the oscillator according to the lpc176x board. + */ +static BSP_START_TEXT_SECTION void lpc176x_init_main_oscillator( void ) +{ + if ( ( LPC176X_SCB.scs & LPC176X_SCB_SCS_OSC_STATUS ) == 0u ) { + LPC176X_SCB.scs |= LPC176X_SCB_SCS_OSC_ENABLE; + + while ( ( LPC176X_SCB.scs & LPC176X_SCB_SCS_OSC_STATUS ) == 0u ) { + /* Wait. */ + } + } + + /* else implies that the oscillator is initialized. Also, + there is nothing to do. */ +} + +/** + * @brief Sets the PLL configuration. + * + * @param pll Value to set. + * @param val Set value. + */ +static BSP_START_TEXT_SECTION void lpc176x_pll_config( const uint32_t val ) +{ + ( LPC176X_SCB.pll_0 ).con = val; + /* The two register writes must be in correct sequence. */ + ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CON; + ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CFG; +} + +/** + * @brief Sets the PLL. + * + * @param msel Multiplier value. + * @param psel Divider value. + * @param cclkdiv Divisor clock. + */ +static BSP_START_TEXT_SECTION void lpc176x_set_pll( + const unsigned msel, + const unsigned psel, + const unsigned cclkdiv +) +{ + const uint32_t pllcfg = LPC176X_PLL_SEL_MSEL( msel ) | + LPC176X_PLL_SEL_PSEL( psel ); + const uint32_t pllstat = LPC176X_PLL_STAT_PLLE | LPC176X_PLL_STAT_PLOCK | + pllcfg; + const uint32_t cclksel_cclkdiv = LPC176X_SCB_CCLKSEL_CCLKDIV( cclkdiv ); + + if ( ( LPC176X_SCB.pll_0 ).stat != pllstat + || LPC176X_SCB.cclksel != cclksel_cclkdiv + || LPC176X_SCB.clksrcsel != LPC176X_SCB_CLKSRCSEL_CLKSRC ) { + lpc176x_pll_config( ( LPC176X_SCB.pll_0 ).con & ~LPC176X_PLL_CON_PLLC ); + + /* Turn off USB. */ + LPC176X_SCB.usbclksel = 0u; + + /* Disable PLL. */ + lpc176x_pll_config( 0u ); + + /* Use SYSCLK for CCLK. */ + LPC176X_SCB.cclksel = LPC176X_SCB_CCLKSEL_CCLKDIV( 0u ); + + /* Set the CCLK, PCLK and EMCCLK divider. */ + LPC176X_SCB.cclksel = cclksel_cclkdiv; + + /* Select main oscillator as clock source. */ + LPC176X_SCB.clksrcsel = LPC176X_SCB_CLKSRCSEL_CLKSRC; + + /* The two register writes must be in correct sequence. */ + /* Set PLL configuration. */ + ( LPC176X_SCB.pll_0 ).cfg = pllcfg; + ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CON; + ( LPC176X_SCB.pll_0 ).feed = LPC176X_PLL0CFG; + + /* Enable PLL. */ + lpc176x_pll_config( LPC176X_PLL_CON_PLLE ); + + /* Wait for lock. */ + while ( ( ( LPC176X_SCB.pll_0 ).stat & LPC176X_PLL_STAT_PLOCK ) == 0u ) { + /* Wait */ + } + + /* Connect PLL. */ + lpc176x_pll_config( ( LPC176X_PLL_CON_PLLE | LPC176X_PLL_CON_PLLC ) ); + + /* Wait for connected and enabled. */ + while ( ( ( LPC176X_SCB.pll_0 ).stat & ( LPC176X_PLL_STAT_PLLE | + LPC176X_PLL_STAT_PLLC ) ) == + 0u ) { + /* Wait */ + } + } + + /* else implies that the pll has a wrong value. Also, + there is nothing to do. */ +} + +/** + * @brief Pll initialization. + */ +static BSP_START_TEXT_SECTION void lpc176x_init_pll( void ) +{ +#if ( LPC176X_OSCILLATOR_MAIN == 12000000u ) +#if ( LPC176X_CCLK == 96000000U ) + lpc176x_set_pll( 11u, 0u, 2u ); +#else +#error "unexpected CCLK" +#endif +#else +#error "unexpected main oscillator frequency" +#endif +} + +/** + * @brief Memory map initialization. + */ +static BSP_START_TEXT_SECTION void lpc176x_init_memory_map( void ) +{ + LPC176X_SCB.memmap = LPC176X_SCB_MEMMAP_MAP; +} + +/** + * @brief Memory accelerator initialization. + */ +static BSP_START_TEXT_SECTION void lpc176x_init_memory_accelerator( void ) +{ +#if ( LPC176X_CCLK <= 20000000U ) + LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x0U ); +#elif ( LPC176X_CCLK <= 40000000U ) + LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x1U ); +#elif ( LPC176X_CCLK <= 60000000U ) + LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x2U ); +#elif ( LPC176X_CCLK <= 80000000U ) + LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x3U ); +#elif ( LPC176X_CCLK <= 100000000U ) + LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x4U ); +#else + LPC176X_SCB.flashcfg = LPC176X_SCB_FLASHCFG_FLASHTIM( 0x5U ); +#endif +} + +/** + * @brief Stops the gpdma device. + */ +static BSP_START_TEXT_SECTION void lpc176x_stop_gpdma( void ) +{ +#ifdef LPC176X_STOP_GPDMA + + bool has_power = ( LPC176X_SCB.pconp & LPC176X_SCB_PCONP_GPDMA ) != 0u; + + if ( has_power ) { + GPDMA_CONFIG = 0u; + LPC176X_SCB.pconp &= ~LPC176X_SCB_PCONP_GPDMA; + } + + /* else implies that the current module (gpdma) is turn off. Also, + there is nothing to do. */ + +#endif +} + +/** + * @brief Stops the usb device. + */ +static BSP_START_TEXT_SECTION void lpc176x_stop_usb( void ) +{ +#ifdef LPC176X_STOP_USB + + bool has_power = ( LPC176X_SCB.pconp & LPC176X_SCB_PCONP_USB ) != 0u; + + if ( has_power ) { + OTG_CLK_CTRL = 0u; + + LPC176X_SCB.pconp &= ~LPC176X_SCB_PCONP_USB; + LPC176X_SCB.usbclksel = 0u; + } + + /* else implies that the current module (usb) is turn off. Also, + there is nothing to do. */ +#endif +} + +BSP_START_TEXT_SECTION void bsp_start_hook_0( void ) +{ + lpc176x_init_main_oscillator(); + lpc176x_init_pll(); +} + +BSP_START_TEXT_SECTION void bsp_start_hook_1( void ) +{ + lpc176x_init_memory_map(); + lpc176x_init_memory_accelerator(); + lpc176x_stop_gpdma(); + lpc176x_stop_usb(); + bsp_start_copy_sections(); + bsp_start_clear_bss(); + + /* At this point we can use objects outside the .start section */ +} \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed b/c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed new file mode 100644 index 0000000000..d4a20d2dd6 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed @@ -0,0 +1,27 @@ +/* LPC1768 OEM Board from Embedded Artists */ + +MEMORY { + ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k + RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 32k +} + +REGION_ALIAS ("REGION_START", ROM_INT); +REGION_ALIAS ("REGION_VECTOR", RAM_INT); +REGION_ALIAS ("REGION_TEXT", ROM_INT); +REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT); +REGION_ALIAS ("REGION_RODATA", ROM_INT); +REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_DATA", RAM_INT); +REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT); +REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT); +REGION_ALIAS ("REGION_FAST_DATA", RAM_INT); +REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_BSS", RAM_INT); +REGION_ALIAS ("REGION_WORK", RAM_INT); +REGION_ALIAS ("REGION_STACK", RAM_INT); + +bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024; +bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align); + +INCLUDE linkcmds.armv7m diff --git a/c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed_ahb_ram b/c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed_ahb_ram new file mode 100644 index 0000000000..0cd0ee117a --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed_ahb_ram @@ -0,0 +1,28 @@ +/* LPC1768 OEM Board from Embedded Artists */ + +MEMORY { + ROM_INT (RX) : ORIGIN = 0x00000000, LENGTH = 512k + RAM_INT (AIW) : ORIGIN = 0x10000000, LENGTH = 32k + RAM_AHB (AIW) : ORIGIN = 0x2007C000, LENGTH = 32k +} + +REGION_ALIAS ("REGION_START", ROM_INT); +REGION_ALIAS ("REGION_VECTOR", RAM_INT); +REGION_ALIAS ("REGION_TEXT", ROM_INT); +REGION_ALIAS ("REGION_TEXT_LOAD", ROM_INT); +REGION_ALIAS ("REGION_RODATA", ROM_INT); +REGION_ALIAS ("REGION_RODATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_DATA", RAM_INT); +REGION_ALIAS ("REGION_DATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_FAST_TEXT", RAM_INT); +REGION_ALIAS ("REGION_FAST_TEXT_LOAD", ROM_INT); +REGION_ALIAS ("REGION_FAST_DATA", RAM_INT); +REGION_ALIAS ("REGION_FAST_DATA_LOAD", ROM_INT); +REGION_ALIAS ("REGION_BSS", RAM_INT); +REGION_ALIAS ("REGION_WORK", RAM_AHB); +REGION_ALIAS ("REGION_STACK", RAM_AHB); + +bsp_stack_main_size = DEFINED (bsp_stack_main_size) ? bsp_stack_main_size : 1024; +bsp_stack_main_size = ALIGN (bsp_stack_main_size, bsp_stack_align); + +INCLUDE linkcmds.armv7m diff --git a/c/src/lib/libbsp/arm/lpc176x/timer/timer.c b/c/src/lib/libbsp/arm/lpc176x/timer/timer.c new file mode 100644 index 0000000000..8fafc0b179 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/timer/timer.c @@ -0,0 +1,407 @@ +/** + * @file timer.c + * + * @ingroup lpc176x + * + * @brief Timer controller for the mbed lpc1768 board. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +/** + * @brief Represents all the timers. + */ +const lpc176x_timer timers[ LPC176X_TIMER_COUNT ] = +{ + { + .device = (lpc176x_timer_device *) LPC176X_TMR0_BASE_ADDR, + .module = LPC176X_MODULE_TIMER_0, + .pinselcap = LPC176X_TIMER0_CAPTURE_PORTS, + .pinselemat = LPC176X_TIMER0_EMATCH_PORTS, + }, + { + .device = (lpc176x_timer_device *) LPC176X_TMR1_BASE_ADDR, + .module = LPC176X_MODULE_TIMER_1, + .pinselcap = LPC176X_TIMER1_CAPTURE_PORTS, + .pinselemat = LPC176X_TIMER1_EMATCH_PORTS, + }, + { + .device = (lpc176x_timer_device *) LPC176X_TMR2_BASE_ADDR, + .module = LPC176X_MODULE_TIMER_2, + .pinselcap = LPC176X_TIMER2_CAPTURE_PORTS, + .pinselemat = LPC176X_TIMER2_EMATCH_PORTS, + }, + { + .device = (lpc176x_timer_device *) LPC176X_TMR3_BASE_ADDR, + .module = LPC176X_MODULE_TIMER_3, + .pinselcap = LPC176X_TIMER3_CAPTURE_PORTS, + .pinselemat = LPC176X_TIMER3_EMATCH_PORTS, + } +}; + +/** + * @brief Represents all the functions according to the timers. + */ +lpc176x_timer_functions functions_vector[ LPC176X_TIMER_COUNT ] = +{ + { + .funct_vector = NULL + }, + { + .funct_vector = NULL + }, + { + .funct_vector = NULL + }, + { + .funct_vector = NULL + } +}; + +/** + * @brief Calls the corresponding interrupt function and pass the timer + * as parameter. + * + * @param timer The specific device. + * @param interruptnumber Interrupt number. + */ +static inline void lpc176x_call_desired_isr( + const lpc176x_timer_number number, + const lpc176x_isr_function interruptfunction +) +{ + if ( ( *functions_vector[ number ].funct_vector )[ interruptfunction ] != + NULL ) { + ( *functions_vector[ number ].funct_vector )[ interruptfunction ]( number ); + } + + /* else implies that the function vector points NULL. Also, + there is nothing to do. */ +} + +/** + * @brief Gets true if the selected interrupt is pending + * + * @param number: the number of the timer. + * @param interrupt: the interrupt we are checking for. + * @return TRUE if the interrupt is pending. + */ +static inline bool lpc176x_timer_interrupt_is_pending( + const lpc176x_timer_number tnumber, + const lpc176x_isr_function function +) +{ + assert( ( tnumber < LPC176X_TIMER_COUNT ) + && ( function < LPC176X_ISR_FUNCTIONS_COUNT ) ); + + return ( timers[ tnumber ].device->IR & + LPC176X_TIMER_INTERRUPT_SOURCE_BIT( function ) ); +} + +/** + * @brief Resets interrupt status for the selected interrupt + * + * @param tnumber: the number of the timer + * @param interrupt: the interrupt we are resetting + */ +static inline void lpc176x_timer_reset_interrupt( + const lpc176x_timer_number tnumber, + const lpc176x_isr_function function +) +{ + assert( ( tnumber < LPC176X_TIMER_COUNT ) + && ( function < LPC176X_ISR_FUNCTIONS_COUNT ) ); + timers[ tnumber ].device->IR = + LPC176X_TIMER_INTERRUPT_SOURCE_BIT( function ); +} + +inline rtems_status_code lpc176x_timer_reset( + const lpc176x_timer_number tnumber ) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + timers[ tnumber ].device->TCR = LPC176X_TIMER_RESET; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +inline rtems_status_code lpc176x_timer_set_mode( + const lpc176x_timer_number tnumber, + const lpc176x_timer_mode mode +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + timers[ tnumber ].device->CTCR = mode; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +inline rtems_status_code lpc176x_timer_start( + const lpc176x_timer_number tnumber ) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + timers[ tnumber ].device->TCR = LPC176X_TIMER_START; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +inline rtems_status_code lpc176x_timer_is_started( + const lpc176x_timer_number tnumber, + bool *is_started +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + *is_started = ( timers[ tnumber ].device->TCR & LPC176X_TIMER_START ) == + LPC176X_TIMER_START; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +inline rtems_status_code lpc176x_timer_set_resolution( + const lpc176x_timer_number tnumber, + const lpc176x_microseconds resolution +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + timers[ tnumber ].device->PR = ( LPC176X_CCLK / + LPC176X_TIMER_PRESCALER_DIVISOR ) * + resolution; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +rtems_status_code lpc176x_timer_match_config( + const lpc176x_timer_number tnumber, + const lpc176x_match_port match_port, + const lpc176x_match_function function, + const uint32_t match_value +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( ( tnumber < LPC176X_TIMER_COUNT ) + && ( match_port < LPC176X_EMATCH_PORTS_COUNT ) + && ( function < LPC176X_TIMER_MATCH_FUNCTION_COUNT ) ) { + timers[ tnumber ].device->MCR = + LPC176X_SET_MCR( timers[ tnumber ].device->MCR, + match_port, function ); + timers[ tnumber ].device->MR[ match_port ] = match_value; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number, or a match port or a function + is invalid. Also, an invalid number is returned. */ + + return status_code; +} + +inline rtems_status_code lpc176x_timer_capture_config( + const lpc176x_timer_number tnumber, + const lpc176x_capture_port capture_port, + const lpc176x_capture_function function +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( ( tnumber < LPC176X_TIMER_COUNT ) + && ( capture_port < LPC176X_CAPTURE_PORTS_COUNT ) + && ( function < LPC176X_TIMER_CAPTURE_FUNCTION_COUNT ) ) { + timers[ tnumber ].device->CCR = + LPC176X_SET_CCR( timers[ tnumber ].device->CCR, + capture_port, function ); + lpc176x_pin_select( timers[ tnumber ].pinselcap[ capture_port ], + LPC176X_PIN_FUNCTION_11 ); + } + + /* else implies that the timer number or the capture port is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +inline rtems_status_code lpc176x_timer_external_match_config( + const lpc176x_timer_number number, + const lpc176x_match_port match_port, + const lpc176x_ext_match_function function +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( ( number < LPC176X_TIMER_COUNT ) + && ( match_port < LPC176X_EMATCH_PORTS_COUNT ) ) { + timers[ number ].device->EMR = + LPC176X_SET_EMR( timers[ number ].device->EMR, + match_port, function ); + lpc176x_pin_select( timers[ number ].pinselemat[ match_port ], + LPC176X_PIN_FUNCTION_11 ); + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number or the match port is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +inline uint32_t lpc176x_timer_get_capvalue( + const lpc176x_timer_number number, + const lpc176x_capture_port capture_port +) +{ + assert( ( number < LPC176X_TIMER_COUNT ) + && ( capture_port < LPC176X_CAPTURE_PORTS_COUNT ) ); + + return timers[ number ].device->CR[ capture_port ]; +} + +inline uint32_t lpc176x_timer_get_timer_value( + const lpc176x_timer_number tnumber ) +{ + assert( tnumber < LPC176X_TIMER_COUNT ); + + return timers[ tnumber ].device->TC; +} + +inline rtems_status_code lpc176x_timer_set_timer_value( + const lpc176x_timer_number tnumber, + const uint32_t timer_value +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + timers[ tnumber ].device->TC = timer_value; + status_code = RTEMS_SUCCESSFUL; + } + + /* else implies that the timer number is invalid. Also, + an invalid number is returned. */ + + return status_code; +} + +void lpc176x_timer_isr( void *arg ) +{ + const lpc176x_timer_number tnumber = (lpc176x_timer_number) arg; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + lpc176x_isr_function i; + + for ( i = 0; i < LPC176X_ISR_FUNCTIONS_COUNT; ++i ) { + if ( lpc176x_timer_interrupt_is_pending( tnumber, i ) ) { + lpc176x_call_desired_isr( tnumber, i ); + lpc176x_timer_reset_interrupt( tnumber, i ); + } + + /* else implies that the current timer is not pending. Also, + there is nothing to do. */ + } + } + + /* else implies that the timer number is not valid. Also, + there is nothing to do. */ +} + +rtems_status_code lpc176x_timer_init( const lpc176x_timer_number tnumber ) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + if ( tnumber < LPC176X_TIMER_COUNT ) { + status_code = lpc176x_module_enable( timers[ tnumber ].module, + LPC176X_MODULE_PCLK_DEFAULT ); + RTEMS_CHECK_SC( status_code, "Enabling the timer module." ); + + status_code = lpc176x_timer_reset( tnumber ); + status_code = lpc176x_timer_set_mode( tnumber, + LPC176X_TIMER_MODE_TIMER ); + status_code = lpc176x_timer_set_resolution( tnumber, + LPC176X_TIMER_DEFAULT_RESOLUTION ); + + timers[ tnumber ].device->MCR = LPC176X_TIMER_CLEAR_FUNCTION; + timers[ tnumber ].device->CCR = LPC176X_TIMER_CLEAR_FUNCTION; + timers[ tnumber ].device->EMR = LPC176X_TIMER_CLEAR_FUNCTION; + } + + /* else implies that the timer number is not valid. Also, + an invalid number is returned. */ + + return status_code; +} + +rtems_status_code lpc176x_timer_init_with_interrupt( + const lpc176x_timer_number tnumber, + const lpc176x_isr_funct_vector *const vector +) +{ + rtems_status_code status_code = RTEMS_INVALID_NUMBER; + + char isrname[ LPC176X_ISR_NAME_STRING_SIZE ]; + + snprintf( isrname, LPC176X_ISR_NAME_STRING_SIZE, "TimerIsr%d", tnumber ); + + if ( tnumber < LPC176X_TIMER_COUNT && vector != NULL ) { + functions_vector[ tnumber ].funct_vector = vector; + + status_code = lpc176x_timer_init( tnumber ); + status_code = rtems_interrupt_handler_install( + LPC176X_TIMER_VECTOR_NUMBER( tnumber ), + isrname, + RTEMS_INTERRUPT_UNIQUE, + lpc176x_timer_isr, + (void *) tnumber ); + } + + return status_code; +} \ No newline at end of file diff --git a/c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c b/c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c new file mode 100644 index 0000000000..0cb486baf3 --- /dev/null +++ b/c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c @@ -0,0 +1,102 @@ +/** + * @file watchdog.c + * + * @ingroup lpc176x + * + * @brief Watchdog controller for the mbed lpc176x family boards. + */ + +/* + * Copyright (c) 2014 Taller Technologies. + * + * @author Boretto Martin (martin.boretto@tallertechnologies.com) + * @author Diaz Marcos (marcos.diaz@tallertechnologies.com) + * @author Lenarduzzi Federico (federico.lenarduzzi@tallertechnologies.com) + * @author Daniel Chicco (daniel.chicco@tallertechnologies.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +inline bool lpc176x_been_reset_by_watchdog( void ) +{ + return ( ( LPC176X_WDMOD & LPC176X_WWDT_MOD_WDTOF ) == + LPC176X_WWDT_MOD_WDTOF ); +} + +inline void lpc176x_watchdog_reset( void ) +{ + LPC176X_WDFEED = LPC176X_WDFEED_CON; + LPC176X_WDFEED = LPC176X_WDFEED_CFG; +} + +/** + * @brief Enables the watchdog module, sets wd clock and wd timer. + * + * @param tcount Timer's out value. + * @return RTEMS_SUCCESSFUL if the configuration was done successfully. + */ +static inline rtems_status_code enable_module_and_set_clocksel( + const lpc176x_microseconds tcount ) +{ + rtems_status_code status_code; + + /* Sets clock. */ + LPC176X_WDCLKSEL = LPC176X_WWDT_CLKSEL_WDSEL_PCLK; + + /* Enables the watchdog module. */ + status_code = lpc176x_module_enable( LPC176X_MODULE_WD, + LPC176X_MODULE_PCLK_DEFAULT ); + RTEMS_CHECK_SC( status_code, "Enabling the watchdog module." ); + + /* Set the watchdog timer constant value. */ + LPC176X_WDTC = ( LPC176X_CCLK / LPC176X_WD_PRESCALER_DIVISOR ) * tcount; + + return status_code; +} + +rtems_status_code lpc176x_watchdog_config( const lpc176x_microseconds tcount ) +{ + rtems_status_code status_code = enable_module_and_set_clocksel( tcount ); + + /* Setup the Watchdog timer operating mode in WDMOD register. */ + LPC176X_WDMOD = LPC176X_WWDT_MOD_WDEN | LPC176X_WWDT_MOD_WDRESET; + + /* Enable the Watchdog by writing 0xAA followed by 0x55 to the + WDFEED register. */ + lpc176x_watchdog_reset(); + + return status_code; +} + +rtems_status_code lpc176x_watchdog_config_with_interrupt( + const lpc176x_wd_isr_funct interrupt, + const lpc176x_microseconds tcount +) +{ + rtems_status_code status_code = enable_module_and_set_clocksel( tcount ); + + /* Setup the Watchdog timer operating mode in WDMOD register. */ + LPC176X_WDMOD = LPC176X_WWDT_MOD_WDEN | LPC176X_WWDT_MOD_WDINT; + + status_code = rtems_interrupt_handler_install( + LPC176X_WD_INTERRUPT_VECTOR_NUMBER, + "watchdog_interrupt", + RTEMS_INTERRUPT_UNIQUE, + interrupt, + NULL ); + + /* Enable the Watchdog by writing 0xAA followed by 0x55 to the + WDFEED register. */ + lpc176x_watchdog_reset(); + + return status_code; +} \ No newline at end of file -- cgit v1.2.3