forked from Imagelibrary/rtems
bsp/lpc176x: New BSP
This commit is contained in:
committed by
Sebastian Huber
parent
c1072919fa
commit
19260fbe85
@@ -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 )
|
||||
|
||||
165
c/src/lib/libbsp/arm/lpc176x/Makefile.am
Normal file
165
c/src/lib/libbsp/arm/lpc176x/Makefile.am
Normal file
@@ -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
|
||||
11
c/src/lib/libbsp/arm/lpc176x/README
Normal file
11
c/src/lib/libbsp/arm/lpc176x/README
Normal file
@@ -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
|
||||
@@ -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 <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/btimer.h>
|
||||
|
||||
#include <bsp/timer.h>
|
||||
|
||||
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 )
|
||||
{
|
||||
}
|
||||
13
c/src/lib/libbsp/arm/lpc176x/bsp_specs
Normal file
13
c/src/lib/libbsp/arm/lpc176x/bsp_specs
Normal file
@@ -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 }
|
||||
71
c/src/lib/libbsp/arm/lpc176x/configure.ac
Normal file
71
c/src/lib/libbsp/arm/lpc176x/configure.ac
Normal file
@@ -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
|
||||
158
c/src/lib/libbsp/arm/lpc176x/console/console-config.c
Normal file
158
c/src/lib/libbsp/arm/lpc176x/console/console-config.c
Normal file
@@ -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
|
||||
* <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 <libchip/serial.h>
|
||||
#include <libchip/ns16550.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
392
c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c
Normal file
392
c/src/lib/libbsp/arm/lpc176x/gpio/gpio.c
Normal file
@@ -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 <assert.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/gpio.h>
|
||||
#include <rtems/status-checks.h>
|
||||
|
||||
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;
|
||||
}
|
||||
100
c/src/lib/libbsp/arm/lpc176x/include/bsp.h
Normal file
100
c/src/lib/libbsp/arm/lpc176x/include/bsp.h
Normal file
@@ -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
|
||||
* <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.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_ARM_LPC176X_BSP_H
|
||||
#define LIBBSP_ARM_LPC176X_BSP_H
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
#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 <rtems.h>
|
||||
#include <rtems/console.h>
|
||||
#include <rtems/clockdrv.h>
|
||||
#include <bsp/default-initial-extension.h>
|
||||
|
||||
/** 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 <bsp.h>
|
||||
*
|
||||
* #define CONFIGURE_INIT
|
||||
*
|
||||
* #define CONFIGURE_IDLE_TASK_BODY bsp_idle_thread
|
||||
*
|
||||
* #include <confdefs.h>
|
||||
* @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 */
|
||||
117
c/src/lib/libbsp/arm/lpc176x/include/common-types.h
Normal file
117
c/src/lib/libbsp/arm/lpc176x/include/common-types.h
Normal file
@@ -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 */
|
||||
98
c/src/lib/libbsp/arm/lpc176x/include/dma.h
Normal file
98
c/src/lib/libbsp/arm/lpc176x/include/dma.h
Normal file
@@ -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
|
||||
* <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.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_ARM_LPC176X_DMA_H
|
||||
#define LIBBSP_ARM_LPC176X_DMA_H
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#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 */
|
||||
218
c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h
Normal file
218
c/src/lib/libbsp/arm/lpc176x/include/gpio-defs.h
Normal file
@@ -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 <bsp/common-types.h>
|
||||
|
||||
#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 */
|
||||
100
c/src/lib/libbsp/arm/lpc176x/include/gpio.h
Normal file
100
c/src/lib/libbsp/arm/lpc176x/include/gpio.h
Normal file
@@ -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 <bsp/lpc176x.h>
|
||||
#include <bsp/gpio-defs.h>
|
||||
|
||||
#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 */
|
||||
123
c/src/lib/libbsp/arm/lpc176x/include/io-defs.h
Normal file
123
c/src/lib/libbsp/arm/lpc176x/include/io-defs.h
Normal file
@@ -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 <bsp/lpc176x.h>
|
||||
#include <bsp/common-types.h>
|
||||
|
||||
#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 */
|
||||
77
c/src/lib/libbsp/arm/lpc176x/include/io.h
Normal file
77
c/src/lib/libbsp/arm/lpc176x/include/io.h
Normal file
@@ -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 <assert.h>
|
||||
#include <rtems.h>
|
||||
#include <bsp/io-defs.h>
|
||||
|
||||
#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 */
|
||||
108
c/src/lib/libbsp/arm/lpc176x/include/irq.h
Normal file
108
c/src/lib/libbsp/arm/lpc176x/include/irq.h
Normal file
@@ -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
|
||||
* <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.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_ARM_LPC176X_IRQ_H
|
||||
#define LIBBSP_ARM_LPC176X_IRQ_H
|
||||
|
||||
#ifndef ASM
|
||||
#include <rtems.h>
|
||||
#include <rtems/irq.h>
|
||||
#include <rtems/irq-extension.h>
|
||||
#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 */
|
||||
44
c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h
Normal file
44
c/src/lib/libbsp/arm/lpc176x/include/lpc-clock-config.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup lpc176x
|
||||
*
|
||||
* @brief Clock driver configuration.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_ARM_LPC176X_LPC_CLOCK_CONFIG_H
|
||||
#define LIBBSP_ARM_LPC176X_LPC_CLOCK_CONFIG_H
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/lpc176x.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
#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 */
|
||||
1585
c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h
Normal file
1585
c/src/lib/libbsp/arm/lpc176x/include/lpc176x.h
Normal file
File diff suppressed because it is too large
Load Diff
91
c/src/lib/libbsp/arm/lpc176x/include/system-clocks.h
Normal file
91
c/src/lib/libbsp/arm/lpc176x/include/system-clocks.h
Normal file
@@ -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
|
||||
* <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.
|
||||
*/
|
||||
|
||||
#ifndef LIBBSP_ARM_LPC176X_SYSTEM_CLOCKS_H
|
||||
#define LIBBSP_ARM_LPC176X_SYSTEM_CLOCKS_H
|
||||
|
||||
#include <bsp/lpc176x.h>
|
||||
#include <bsp/timer-defs.h>
|
||||
|
||||
#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 */
|
||||
449
c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h
Normal file
449
c/src/lib/libbsp/arm/lpc176x/include/timer-defs.h
Normal file
@@ -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 <bsp/common-types.h>
|
||||
|
||||
#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 */
|
||||
195
c/src/lib/libbsp/arm/lpc176x/include/timer.h
Normal file
195
c/src/lib/libbsp/arm/lpc176x/include/timer.h
Normal file
@@ -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 <bsp/timer-defs.h>
|
||||
|
||||
#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 */
|
||||
65
c/src/lib/libbsp/arm/lpc176x/include/watchdog-defs.h
Normal file
65
c/src/lib/libbsp/arm/lpc176x/include/watchdog-defs.h
Normal file
@@ -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 <rtems/score/cpu.h>
|
||||
#include <bsp.h>
|
||||
#include <bspopts.h>
|
||||
#include <bsp/utility.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/common-types.h>
|
||||
|
||||
#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 */
|
||||
70
c/src/lib/libbsp/arm/lpc176x/include/watchdog.h
Normal file
70
c/src/lib/libbsp/arm/lpc176x/include/watchdog.h
Normal file
@@ -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 <bsp/watchdog-defs.h>
|
||||
|
||||
#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 */
|
||||
75
c/src/lib/libbsp/arm/lpc176x/irq/irq.c
Normal file
75
c/src/lib/libbsp/arm/lpc176x/irq/irq.c
Normal file
@@ -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
|
||||
* <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 <rtems/score/armv4.h>
|
||||
#include <rtems/score/armv7m.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/irq-generic.h>
|
||||
#include <bsp/lpc176x.h>
|
||||
#include <bsp/linker-symbols.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
@@ -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
|
||||
19
c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed.cfg
Normal file
19
c/src/lib/libbsp/arm/lpc176x/make/custom/lpc1768_mbed.cfg
Normal file
@@ -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
|
||||
@@ -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
|
||||
30
c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c
Normal file
30
c/src/lib/libbsp/arm/lpc176x/misc/bspidle.c
Normal file
@@ -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
|
||||
* <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 <bsp.h>
|
||||
#include <bsp/lpc176x.h>
|
||||
|
||||
void*bsp_idle_thread( const uintptr_t ignored )
|
||||
{
|
||||
while ( true ) {
|
||||
}
|
||||
}
|
||||
220
c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c
Normal file
220
c/src/lib/libbsp/arm/lpc176x/misc/dma-copy.c
Normal file
@@ -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
|
||||
* <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 <bsp/lpc176x.h>
|
||||
#include <bsp/dma.h>
|
||||
#include <bsp/irq.h>
|
||||
|
||||
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;
|
||||
}
|
||||
117
c/src/lib/libbsp/arm/lpc176x/misc/dma.c
Normal file
117
c/src/lib/libbsp/arm/lpc176x/misc/dma.c
Normal file
@@ -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
|
||||
* <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 <rtems/endian.h>
|
||||
#include <bsp/dma.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
/**
|
||||
* @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. */
|
||||
}
|
||||
334
c/src/lib/libbsp/arm/lpc176x/misc/io.c
Normal file
334
c/src/lib/libbsp/arm/lpc176x/misc/io.c
Normal file
@@ -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 <rtems/status-checks.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/start.h>
|
||||
#include <bsp/system-clocks.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
34
c/src/lib/libbsp/arm/lpc176x/misc/restart.c
Normal file
34
c/src/lib/libbsp/arm/lpc176x/misc/restart.c
Normal file
@@ -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
|
||||
* <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 <rtems.h>
|
||||
#include <bsp.h>
|
||||
|
||||
void bsp_restart( const void const *addr )
|
||||
{
|
||||
rtems_interrupt_level level;
|
||||
|
||||
void (*start) ( void ) = addr;
|
||||
|
||||
rtems_interrupt_disable( level );
|
||||
( *start )();
|
||||
}
|
||||
124
c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c
Normal file
124
c/src/lib/libbsp/arm/lpc176x/misc/system-clocks.c
Normal file
@@ -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
|
||||
* <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 <bsp.h>
|
||||
#include <bsp/system-clocks.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
167
c/src/lib/libbsp/arm/lpc176x/preinstall.am
Normal file
167
c/src/lib/libbsp/arm/lpc176x/preinstall.am
Normal file
@@ -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
|
||||
|
||||
127
c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c
Normal file
127
c/src/lib/libbsp/arm/lpc176x/rtc/rtc-config.c
Normal file
@@ -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 <libchip/rtc.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
#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
|
||||
}
|
||||
};
|
||||
42
c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c
Normal file
42
c/src/lib/libbsp/arm/lpc176x/startup/bspreset.c
Normal file
@@ -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
|
||||
* <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 <rtems.h>
|
||||
#include <rtems/score/armv7m.h>
|
||||
|
||||
#include <bsp/bootcard.h>
|
||||
#include <bsp/lpc176x.h>
|
||||
#include <bsp/start.h>
|
||||
|
||||
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 */
|
||||
}
|
||||
}
|
||||
89
c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c
Normal file
89
c/src/lib/libbsp/arm/lpc176x/startup/bspstart.c
Normal file
@@ -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
|
||||
* <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 <bsp.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/dma.h>
|
||||
#include <bsp/bootcard.h>
|
||||
#include <bsp/timer.h>
|
||||
#include <bsp/irq-generic.h>
|
||||
#include <bsp/system-clocks.h>
|
||||
#include <bsp/linker-symbols.h>
|
||||
#include <bsp/common-types.h>
|
||||
#include <bsp/uart-output-char.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
227
c/src/lib/libbsp/arm/lpc176x/startup/bspstarthooks.c
Normal file
227
c/src/lib/libbsp/arm/lpc176x/startup/bspstarthooks.c
Normal file
@@ -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 <bsp.h>
|
||||
#include <bsp/start.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
}
|
||||
27
c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed
Normal file
27
c/src/lib/libbsp/arm/lpc176x/startup/linkcmds.lpc1768_mbed
Normal file
@@ -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
|
||||
@@ -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
|
||||
407
c/src/lib/libbsp/arm/lpc176x/timer/timer.c
Normal file
407
c/src/lib/libbsp/arm/lpc176x/timer/timer.c
Normal file
@@ -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 <stdio.h>
|
||||
#include <rtems/status-checks.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/io.h>
|
||||
#include <bsp/timer.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
102
c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c
Normal file
102
c/src/lib/libbsp/arm/lpc176x/watchdog/watchdog.c
Normal file
@@ -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 <assert.h>
|
||||
#include <rtems/status-checks.h>
|
||||
#include <bsp.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/watchdog.h>
|
||||
#include <bsp/io.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user