bsp/lpc176x: New BSP

This commit is contained in:
Martin Boretto
2014-06-09 11:27:18 -03:00
committed by Sebastian Huber
parent c1072919fa
commit 19260fbe85
42 changed files with 6504 additions and 0 deletions

View File

@@ -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 )

View 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

View 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

View File

@@ -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 )
{
}

View 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 }

View 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

View 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;

View 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;
}

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

File diff suppressed because it is too large Load Diff

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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;
}

View File

@@ -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

View 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

View 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

View 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 ) {
}
}

View 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;
}

View 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. */
}

View 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;
}

View 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 )();
}

View 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;
}

View 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

View 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
}
};

View 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 */
}
}

View 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();
}

View 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 */
}

View 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

View File

@@ -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

View 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;
}

View 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;
}