1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-28 16:01:18 +01:00

Merge pull request #2045 from haukepetersen/fix_board_mbed

board/mbed_lpc1768: remodeled to our board/cpu structure
This commit is contained in:
Hauke Petersen 2014-11-21 10:27:53 +01:00
commit bfa2bfb5ad
33 changed files with 1316 additions and 4200 deletions

View File

@ -1,3 +1,4 @@
MODULE =$(BOARD)_base
# tell the Makefile.base which module to build
MODULE = $(BOARD)_base
include $(RIOTBASE)/Makefile.base

View File

@ -34,7 +34,7 @@ export CFLAGS += -ggdb -g3 -std=gnu99 -Os -Wall -Wstrict-prototypes $(CPU_USAGE)
export CFLAGS += -ffunction-sections -fdata-sections -fno-builtin
export ASFLAGS += -ggdb -g3 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian
export LINKFLAGS += -g3 -ggdb -std=gnu99 $(CPU_USAGE) $(FPU_USAGE) -mlittle-endian -static -lgcc -mthumb -mthumb-interwork -nostartfiles
export LINKFLAGS += -T$(RIOTCPU)/$(CPU)/LPC1768.ld
export LINKFLAGS += -T$(LINKERSCRIPT)
export OFLAGS = -O binary
export FFLAGS =
export DEBUGGER_FLAGS =
@ -50,5 +50,4 @@ export LINKFLAGS += -specs=nano.specs -lc -lnosys
endif
# export board specific includes to the global includes-listing
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include/ -I$(RIOTCPU)/$(CPU)/include
export UNDEF += $(BINDIR)cpu/startup.o
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include/

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup board_mbed_lpc1768
* @{
*
* @file
* @brief Board specific implementations for the mbed LPC1768 board
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "board.h"
static void leds_init(void);
extern void SystemInit(void);
void board_init(void)
{
/* initialize core clocks via CMSIS function */
SystemInit();
/* initialize the CPU */
cpu_init();
/* initialize the boards LEDs */
leds_init();
}
/**
* @brief Initialize the boards on-board LEDs (LED1 to LED4)
*
* The LED initialization is hard-coded in this function. As the LEDs are soldered
* onto the board they are fixed to their CPU pins.
*
* The LEDs are connected to the following pins:
* - LED1: P1.18
* - LED2: P1.20
* - LED3: P1.21
* - LED4: P1.23
*/
static void leds_init(void)
{
/* configure LED pins as output */
LED_PORT->FIODIR |= (LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN);
/* clear all LEDs */
LED_PORT->FIOCLR = (LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN);
}

View File

@ -1,67 +0,0 @@
/**
* MBED LPC1768 board hwtimer_arch.h implementation stub
*
* TODO: implement
*
* Copyright (C) 2014 Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup hwtimer
* @ingroup mbed_lpc1768
* @{
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
* @file
* @}
*/
#include <inttypes.h>
#include "arch/hwtimer_arch.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
void hwtimer_arch_enable_interrupt(void)
{
DEBUG("hwtimer_arch_enable_interrupt(): not implemented\n");
return;
}
void hwtimer_arch_disable_interrupt(void)
{
DEBUG("hwtimer_arch_disable_interrupt(): not implemented\n");
return;
}
void hwtimer_arch_unset(short timer)
{
DEBUG("hwtimer_arch_unset(%i): not implemented\n", timer);
return;
}
void hwtimer_arch_set(unsigned long offset, short timer)
{
DEBUG("hwtimer_arch_set(%lu, %i): not implemented\n", offset, timer);
return;
}
void hwtimer_arch_set_absolute(unsigned long value, short timer)
{
DEBUG("hwtimer_arch_set_absolute(%lu, %i): not implemented\n", value, timer);
return;
}
unsigned long hwtimer_arch_now(void)
{
DEBUG("hwtimer_arch_now(): not implemented\n");
return 0;
}
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
{
DEBUG("hwtimer_arch_init(%p, %" PRIu32 "): not implemented\n", handler, fcpu);
return;
}

View File

@ -1,55 +1,106 @@
/*
* Copyright 2014 INRIA
* Copyright (C) 2014 INRIA
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup board_mbed_lpc1768 mbed LPC1768 development kit
* @ingroup boards
* @brief Support for the mbed LPC1762 board
* @{
*
* @file
* @brief Board specific definitions for the mbed_lpc1768 board
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __BOARD_H
#define __BOARD_H
/**
* @file
* @author Oliver Hahm <oliver.hahm@inria.fr>
*
* @defgroup mbed_lpc1768 mbed NXP LPC1768 development kit
* @ingroup boards
* @brief Support for the mbed NXP LPC1768 board.
* @{
*/
#include <stdint.h>
#include "bitarithm.h"
#include "cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
#define F_CPU (96000000)
/**
* @name The nominal CPU core clock in this board
*/
#define F_CPU (96000000)
/**
* @name Assign the peripheral timer to be used as hardware timer
*/
#define HW_TIMER TIMER_0
#define PIN_LED1 (BIT18)
#define PIN_LED2 (BIT20)
#define PIN_LED3 (BIT21)
#define PIN_LED4 (BIT23)
/**
* @name Assign the UART interface to be used for stdio
* @{
*/
#define STDIO UART_0
#define STDIO_BAUDRATE (115200U)
#define STDIO_RX_BUFSIZE (64U)
/** @} */
#define LED_ON(led_nr) (LPC_GPIO1->FIOSET = PIN_LED##led_nr)
#define LED_OFF(led_nr) (LPC_GPIO1->FIOCLR = PIN_LED##led_nr)
#define LED_TOGGLE(led_nr) (LPC_GPIO1->FIOPIN ^= PIN_LED##led_nr)
/**
* @name LED pin definitions
* @{
*/
#define LED_PORT LPC_GPIO1
#define LED1_PIN BIT18
#define LED2_PIN BIT20
#define LED3_PIN BIT21
#define LED4_PIN BIT23
/** @} */
/**
* @name Macros for controlling the on-board LEDs.
* @{
*/
#define LED1_ON (LED_PORT->FIOSET = LED1_PIN)
#define LED1_OFF (LED_PORT->FIOCLR = LED1_PIN)
#define LED1_TOGGLE (LED_PORT->FIOPIN ^= LED1_PIN)
#define LED2_ON (LED_PORT->FIOSET = LED2_PIN)
#define LED2_OFF (LED_PORT->FIOCLR = LED2_PIN)
#define LED2_TOGGLE (LED_PORT->FIOPIN ^= LED2_PIN)
#define LED3_ON (LED_PORT->FIOSET = LED3_PIN)
#define LED3_OFF (LED_PORT->FIOCLR = LED3_PIN)
#define LED3_TOGGLE (LED_PORT->FIOPIN ^= LED3_PIN)
#define LED4_ON (LED_PORT->FIOSET = LED4_PIN)
#define LED4_OFF (LED_PORT->FIOCLR = LED4_PIN)
#define LED4_TOGGLE (LED_PORT->FIOPIN ^= LED4_PIN)
/* for compatibility to other boards */
#define LED_GREEN_ON LED1_ON
#define LED_GREEN_OFF LED1_OFF
#define LED_GREEN_TOGGLE LED1_TOGGLE
#define LED_RED_ON LED4_ON
#define LED_RED_OFF LED4_OFF
#define LED_RED_TOGGLE LED4_TOGGLE
/** @} */
/**
* @name define radio packet length
*/
typedef uint8_t radio_packet_length_t;
/**
* @brief Busy waiting function (while hwtimer is not available at boot time)
*
* @param[in] t The waiting cycles
* @brief Initialize board specific hardware, include clocks, LEDs and stdio
*/
void loop_delay(uint32_t t);
void board_init(void);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* __BOARD_H */
/** @} */

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup board_mbed_lpc1768
* @{
*
* @file
* @brief Peripheral MCU configuration for the mbed LPC1768 board
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __PERIPH_CONF_H
#define __PERIPH_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Timer configuration
* @{
*/
#define TIMER_NUMOF (1U)
#define TIMER_0_EN 1
#define TIMER_1_EN 0
#define TIMER_IRQ_PRIO 1
/* Timer 0 configuration */
#define TIMER_0_DEV LPC_TIMER0
#define TIMER_0_CHANNELS 4
#define TIMER_0_PRESCALER (67U)
#define TIMER_0_MAX_VALUE (0xffffffff)
#define TIMER_0_CLKEN()
#define TIMER_0_ISR isr_timer0
#define TIMER_0_IRQ_CHAN TIMER0_IRQn
/** @} */
/**
* @brief UART configuration
* @{
*/
#define UART_NUMOF (1U)
#define UART_0_EN 1
#define UART_1_EN 0
#define UART_IRQ_PRIO 1
/* UART 0 device configuration */
#define UART_0_DEV LPC_UART2
#define UART_0_CLKEN()
#define UART_0_IRQ UART0_IRQn
#define UART_0_ISR isr_uart0
/* UART 0 pin configuration */
#define UART_0_PORT
#define UART_0_PORT_CLKEN()
#define UART_0_RX_PIN
#define UART_0_TX_PIN
#define UART_0_AF
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __PERIPH_CONF_H */
/** @} */

View File

@ -1,56 +0,0 @@
/******************************************************************************
* @file: system_LPC17xx.h
* @purpose: CMSIS Cortex-M3 Device Peripheral Access Layer Header File
* for the NXP LPC17xx Device Series
* @version: V1.03
* @date: 09. November 2013
*
* @note: Integrated and adopted for RIOT by Oliver Hahm.
*----------------------------------------------------------------------------
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@fu-berlin.de>
*
* ARM Limited (ARM) is supplying this software for use with Cortex-M3
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC17xx_H
#define __SYSTEM_LPC17xx_H
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t system_clock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void board_init(void);
/**
* Update system_clock variable
*
* @brief Updates the system_clock with current core Clock
* retrieved from cpu registers.
*/
extern void clock_update(void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC17xx_H */

View File

@ -23,9 +23,6 @@
*
******************************************************************************/
#include <stdint.h>
#include "board.h"
#include "LPC17xx.h"
/*--------------------- Clock Configuration ----------------------------------
@ -409,28 +406,6 @@
#endif
#endif
#define BLINK_DELAY (1000000)
void loop_delay(uint32_t t)
{
for (uint32_t delay = 0; delay < t; delay++) {
__asm("NOP");
}
}
void bl_blink(void)
{
LED_ON(1);
LED_ON(2);
LED_ON(3);
LED_ON(4);
loop_delay(BLINK_DELAY);
LED_OFF(1);
LED_OFF(2);
LED_OFF(3);
LED_OFF(4);
}
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
@ -440,7 +415,7 @@ uint32_t system_clock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void clock_update(void) /* Get Core Clock Frequency */
void SystemCoreClockUpdate(void) /* Get Core Clock Frequency */
{
/* Determine clock frequency according to clock register values */
if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */
@ -493,7 +468,7 @@ void clock_update(void) /* Get Core Clock Frequency */
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void board_init(void)
void SystemInit(void)
{
#if (CLOCK_SETUP) /* Clock Setup */
LPC_SC->SCS = SCS_Val;
@ -557,12 +532,4 @@ void board_init(void)
#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */
LPC_SC->FLASHCFG = (LPC_SC->FLASHCFG & ~0x0000F000) | FLASHCFG_Val;
#endif
/* Initialize LED pins */
LPC_GPIO1->FIODIR |= PIN_LED1;
LPC_GPIO1->FIODIR |= PIN_LED2;
LPC_GPIO1->FIODIR |= PIN_LED3;
LPC_GPIO1->FIODIR |= PIN_LED4;
bl_blink();
}

View File

@ -1,154 +0,0 @@
/* Linker script for mbed LPC1768 */
/* Linker script to configure memory regions. */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = 0x7F38
USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
__sidata = __etext;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE (__fini_array_end = .);
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
__bss_start__ = .;
*(.bss*)
*(COMMON)
__bss_end__ = .;
} > RAM
__heap_size = ORIGIN(RAM) + LENGTH(RAM) - . ;/*- __stack_size;*/
.heap :
{
PROVIDE(__heap_start = .);
__end__ = .;
end = __end__;
*(.heap*)
. = . + __heap_size;
PROVIDE(__heap_max = .);
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy :
{
*(.stack)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View File

@ -1,3 +1,7 @@
# define the module that is build
MODULE = cpu
# add a list of subdirectories, that should also be build
DIRS = periph $(CORTEX_COMMON)
include $(RIOTBASE)/Makefile.base

View File

@ -1,3 +1,26 @@
INCLUDES += -I$(RIOTBASE)/cpu/lpc1768/include
# this CPU implementation is using the new core/CPU interface
export CFLAGS += -DCOREIF_NG=1
# tell the build system that the CPU depends on the Cortex-M common files
export USEMODULE += cortex-m3_common
# define path to cortex-m common module, which is needed for this CPU
export CORTEX_COMMON = $(RIOTCPU)/cortex-m3_common/
# define the linker script to use for this CPU. The CPU_MODEL variable is defined in the
# board's Makefile.include. This enables multiple STMF0 controllers with different memory to
# use the same code-base.
export LINKERSCRIPT = $(RIOTCPU)/$(CPU)/lpc1768_linkerscript.ld
# include CPU specific includes
export INCLUDES += -I$(RIOTCPU)/$(CPU)/include
# add the CPU specific system calls implementations for the linker
export UNDEF += $(BINDIR)cpu/syscalls.o
export UNDEF += $(BINDIR)cpu/startup.o
# export the peripheral drivers to be linked into the final binary
export USEMODULE += periph
# CPU depends on the cortex-m common module, so include it
include $(CORTEX_COMMON)Makefile.include

View File

@ -1,174 +0,0 @@
/**
* CPU speficic RIOT kernel function for NXP LPC1768
*
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup lpc1768
* @{
* @file atom.c
* @author Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include "sched.h"
#include "cpu.h"
#include "irq.h"
#include "kernel_internal.h"
NORETURN void sched_task_return(void);
unsigned int atomic_set_return(unsigned int* p, unsigned int uiVal) {
//unsigned int cspr = disableIRQ(); //crashes
dINT();
unsigned int uiOldVal = *p;
*p = uiVal;
//restoreIRQ(cspr); //crashes
eINT();
return uiOldVal;
}
NORETURN void cpu_switch_context_exit(void){
sched_run();
sched_task_return();
}
void thread_yield_higher(void) {
asm("svc 0x01\n");
}
__attribute__((naked))
void SVC_Handler(void)
{
save_context();
asm("bl sched_run");
/* call scheduler update sched_active_thread variable with pdc of next thread
* the thread that has higest priority and is in PENDING state */
restore_context();
}
/* kernel functions */
void ctx_switch(void)
{
/* Save return address on stack */
/* stmfd sp!, {lr} */
/* disable interrupts */
/* mov lr, #NOINT|SVCMODE */
/* msr CPSR_c, lr */
/* cpsid i */
/* save other register */
asm("nop");
asm("mov r12, sp");
asm("stmfd r12!, {r4-r11}");
/* save user mode stack pointer in *sched_active_thread */
asm("ldr r1, =sched_active_thread"); /* r1 = &sched_active_thread */
asm("ldr r1, [r1]"); /* r1 = *r1 = sched_active_thread */
asm("str r12, [r1]"); /* store stack pointer in tasks pdc*/
sched_task_return();
}
/* call scheduler so sched_active_thread points to the next task */
NORETURN void sched_task_return(void)
{
/* load pdc->stackpointer in r0 */
asm("ldr r0, =sched_active_thread"); /* r0 = &sched_active_thread */
asm("ldr r0, [r0]"); /* r0 = *r0 = sched_active_thread */
asm("ldr sp, [r0]"); /* sp = r0 restore stack pointer*/
asm("pop {r4}"); /* skip exception return */
asm(" pop {r4-r11}");
asm(" pop {r0-r3,r12,lr}"); /* simulate register restor from stack */
// asm("pop {r4}"); /*foo*/
asm("pop {pc}");
UNREACHABLE();
}
/*
* cortex m4 knows stacks and handles register backups
*
* so use different stack frame layout
*
*
* with float storage
* ------------------------------------------------------------------------------------------------------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | S8 | S9 | S10 | S11 | S12 | S13 | S14 | S15 | FPSCR |
* ------------------------------------------------------------------------------------------------------------------------------------
*
* without
*
* --------------------------------------
* | R0 | R1 | R2 | R3 | LR | PC | xPSR |
* --------------------------------------
*
*
*/
char * thread_stack_init(void *(*task_func)(void *), void *arg, void *stack_start, int stack_size)
{
unsigned int * stk;
stk = (unsigned int *) ((uintptr_t) stack_start + stack_size);
/* marker */
stk--;
*stk = 0x77777777;
//FIXME FPSCR
stk--;
*stk = (unsigned int) 0;
//S0 - S15
for (int i = 15; i >= 0; i--) {
stk--;
*stk = i;
}
//FIXME xPSR
stk--;
*stk = (unsigned int) 0x01000200;
//program counter
stk--;
*stk = (unsigned int) task_func;
/* link register */
stk--;
*stk = (unsigned int) 0x0;
/* r12 */
stk--;
*stk = (unsigned int) 0;
/* r1 - r3 */
for (int i = 3; i >= 1; i--) {
stk--;
*stk = i;
}
/* r0 -> thread function parameter */
stk--;
*stk = (unsigned int) arg;
/* r11 - r4 */
for (int i = 11; i >= 4; i--) {
stk--;
*stk = i;
}
/* foo */
/*stk--;
*stk = (unsigned int) 0xDEADBEEF;*/
/* lr means exception return code */
stk--;
*stk = (unsigned int) 0xfffffff9; // return to taskmode main stack pointer
return (char*) stk;
}

View File

@ -1,145 +1,29 @@
/**
* CPU specific functions for the RIOT scheduler on NXP LPC1768
*
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @file cpu.c
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#include <stdint.h>
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the CPU initialization
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include "cpu.h"
#include "kernel.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
int inISR(void)
/**
* @brief Initialize the CPU, set IRQ priorities
*/
void cpu_init(void)
{
return (__get_IPSR() & 0xFF);
}
unsigned int disableIRQ(void)
{
// FIXME PRIMASK is the old CPSR (FAULTMASK ??? BASEPRI ???)
//PRIMASK lesen
unsigned int uiPriMask = __get_PRIMASK();
__disable_irq();
return uiPriMask;
}
unsigned enableIRQ(void)
{
unsigned int uiPriMask = __get_PRIMASK();
__enable_irq();
return uiPriMask;
}
void restoreIRQ(unsigned oldPRIMASK)
{
//PRIMASK lesen setzen
__set_PRIMASK(oldPRIMASK);
}
__attribute__((naked))
void HardFault_Handler(void) {
DEBUG("HARD FAULT\n");
while(1);
}
__attribute__((naked))
void BusFault_Handler(void) {
DEBUG("BusFault_Handler\n");
while(1);
}
__attribute__((naked))
void Usage_Handler(void) {
DEBUG("Usage FAULT\n");
while(1);
}
__attribute__((naked))
void WWDG_Handler(void) {
DEBUG("WWDG FAULT\n");
while(1);
}
void dINT(void)
{
__disable_irq();
}
void eINT(void)
{
__enable_irq();
}
void save_context(void)
{
/* {r0-r3,r12,LR,PC,xPSR} are saved automatically on exception entry */
asm("push {r4-r11}");
/* save unsaved registers */
asm("push {LR}");
/* save exception return value */
asm("ldr r1, =sched_active_thread");
/* load address of currend pdc */
asm("ldr r1, [r1]");
/* deref pdc */
asm("str sp, [r1]");
/* write sp to pdc->sp means current threads stack pointer */
}
void restore_context(void)
{
asm("ldr r0, =sched_active_thread");
/* load address of currend pdc */
asm("ldr r0, [r0]");
/* deref pdc */
asm("ldr sp, [r0]");
/* load pdc->sp to sp register */
asm("pop {r0}");
/* restore exception retrun value from stack */
asm("pop {r4-r11}");
/* load unloaded register */
// asm("pop {r4}"); /*foo*/
asm("bx r0"); /* load exception return value to pc causes end of exception*/
/* {r0-r3,r12,LR,PC,xPSR} are restored automatically on exception return */
}
#define USR_RESET (0x102)
#define SWI (0xAB)
__attribute__((naked,noreturn)) void arm_reset(void)
{
int value;
asm volatile (
"mov r0, %1" "\n\t"
"mov r1, %2" "\n\t"
"bkpt" " %a3" "\n\t"
"mov %0, r0"
: "=r" (value) /* output operands */
: "r" USR_RESET, "r" NULL, "i" SWI /* input operands */
: "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" /* list of clobbered registers */
);
}
int reboot_arch(int mode)
{
(void) mode;
while (1) {
arm_reset();
}
return -1;
/* set pendSV interrupt to lowest possible priority */
NVIC_SetPriority(PendSV_IRQn, 0xff);
}

View File

@ -1,68 +0,0 @@
/*
* Copyright (C) 2014 INRIA
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup core_util
* @{
*
* @file crash.c
* @brief Crash handling functions implementation for LPC1768 MCU
* (actually, a copy from 'arm_common'...)
*
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
*/
#include "cpu.h"
#include "lpm.h"
#include "crash.h"
#include <string.h>
#include <stdio.h>
/* "public" variables holding the crash data */
char panic_str[80];
int panic_code;
/* flag preventing "recursive crash printing loop" */
static int crashed = 0;
/* WARNING: this function NEVER returns! */
NORETURN void core_panic(int crash_code, const char *message)
{
/* copy panic datas to "public" global variables */
panic_code = crash_code;
strncpy(panic_str, message, 80);
/* print panic message to console (if possible) */
if (crashed == 0) {
crashed = 1;
puts("******** SYSTEM FAILURE ********\n");
puts(message);
#if DEVELHELP
puts("******** RIOT HALTS HERE ********\n");
#else
puts("******** RIOT WILL REBOOT ********\n");
#endif
puts("\n\n");
}
/* disable watchdog and all possible sources of interrupts */
//TODO
dINT();
#if DEVELHELP
/* enter infinite loop, into deepest possible sleep mode */
while (1) {
lpm_set(LPM_OFF);
}
#else
/* DEVELHELP not set => reboot system */
(void) reboot(RB_AUTOBOOT);
#endif
/* tell the compiler that we won't return from this function
(even if we actually won't even get here...) */
UNREACHABLE();
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the kernel's hwtimer interface
*
* The hardware timer implementation uses the Cortex build-in system timer as back-end.
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "arch/hwtimer_arch.h"
#include "periph/timer.h"
#include "board.h"
#include "thread.h"
void irq_handler(int channel);
void (*timeout_handler)(int);
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
{
timeout_handler = handler;
timer_init(HW_TIMER, 1, &irq_handler);
}
void hwtimer_arch_enable_interrupt(void)
{
timer_irq_enable(HW_TIMER);
}
void hwtimer_arch_disable_interrupt(void)
{
timer_irq_disable(HW_TIMER);
}
void hwtimer_arch_set(unsigned long offset, short timer)
{
timer_set(HW_TIMER, timer, offset);
}
void hwtimer_arch_set_absolute(unsigned long value, short timer)
{
timer_set_absolute(HW_TIMER, timer, value);
}
void hwtimer_arch_unset(short timer)
{
timer_clear(HW_TIMER, timer);
}
unsigned long hwtimer_arch_now(void)
{
return timer_read(HW_TIMER);
}
void irq_handler(int channel)
{
timeout_handler((short)(channel));
}

View File

@ -26,6 +26,10 @@
#ifndef __LPC17xx_H__
#define __LPC17xx_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
@ -1030,4 +1034,8 @@ typedef struct
#define LPC_GPDMACH7 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH7_BASE )
#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE )
#ifdef __cplusplus
}
#endif
#endif // __LPC17xx_H__

View File

@ -1,25 +0,0 @@
/* mbed Microcontroller Library - CMSIS
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* A generic CMSIS include header, pulling in LPC1768 specifics
*/
/**
* @defgroup CMSIS
* @brief Cortex Microcontroller Software Interface Standard
* @ingroup cpu
* @{
*
* @file cmsis.h
* @brief CMSIS interface pulling in LPC1768 specifics
*/
#ifndef MBED_CMSIS_H
#define MBED_CMSIS_H
#include "LPC17xx.h"
#include "cmsis_nvic.h"
#endif
/** @} */

File diff suppressed because it is too large Load Diff

View File

@ -1,616 +0,0 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.02
* @date 24. May 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
#include <stdint.h>
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl asm("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl asm("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR asm("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR asm("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR asm("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer asm("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer asm("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer asm("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer asm("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask asm("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask asm("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri asm("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri asm("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask asm("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask asm("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr asm("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr asm("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
asm volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
asm volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
asm volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
asm volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
asm volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
asm volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
asm volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
asm volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
asm volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
asm volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
asm volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
asm volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
asm volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
asm volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
asm volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
asm volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
asm volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
asm volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
asm volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
asm volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
asm volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@ -1,644 +0,0 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.03
* @date 29. August 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
\ingroup CMSIS
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
return(op1);
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@ -1,18 +1,64 @@
#ifndef CPU_CONF_H
#define CPU_CONF_H
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup cpu_lpc1768 NXP LPC1768
* @ingroup cpu
* @brief CPU specific implementations for the NXP LPC1768 cpu
* @{
*
* @file
* @brief CPU specific hwtimer configuration options
*12
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
*/
#ifndef __CPU_CONF_H
#define __CPU_CONF_H
#include "LPC17xx.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Kernel configuration
*
* The absolute minimum stack size is 140 byte (68 byte for the tcb + 72 byte
* for a complete context save).
*
* TODO: measure and adjust for the Cortex-M3
* @{
*/
#define KERNEL_CONF_STACKSIZE_PRINTF (4096)
#define KERNEL_CONF_STACKSIZE_PRINTF (1024)
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
#define KERNEL_CONF_STACKSIZE_DEFAULT 1500
#define KERNEL_CONF_STACKSIZE_DEFAULT (1024)
#endif
#define KERNEL_CONF_STACKSIZE_IDLE 1000
#define UART0_BUFSIZE (128)
#define KERNEL_CONF_STACKSIZE_IDLE (256)
/** @} */
#endif /* CPU_CONF_H */
/**
* @name UART0 buffer size definition for compatibility reasons
*
* TODO: remove once the remodeling of the uart0 driver is done
* @{
*/
#ifndef UART0_BUFSIZE
#define UART0_BUFSIZE (128)
#endif
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __CPU_CONF_H */
/** @} */

View File

@ -1,44 +0,0 @@
/**
* Copyright (C) 2014 Oliver Hahm <oliver.hahm@inria.fr>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#ifndef CPU_H
#define CPU_H
/**
* @defgroup lpc1768 NXP LPC1768
* @brief NXP LPC1768 specific code
* @ingroup cpu
* @{
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#include "LPC17xx.h"
#include "core_cm3.h"
#include "core_cmFunc.h"
extern void dINT(void);
extern void eINT(void);
/**
* @brief Save the thread's context
*/
void save_context(void);
/**
* @brief Restores the before saved context of a thread
*/
void restore_context(void);
/**
* @brief Let the scheduler yield
*/
void thread_yield_higher(void);
/** @} */
#endif /* CPU_H */

View File

@ -1,8 +1,40 @@
#ifndef HWTIMER_CPU_H_
#define HWTIMER_CPU_H_
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
#define HWTIMER_MAXTIMERS 3
#define HWTIMER_SPEED 1000000
#define HWTIMER_MAXTICKS (0xFFFFFFFF)
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief CPU specific hwtimer configuration options
*
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
*/
#endif /* HWTIMER_CPU_H_ */
#ifndef __HWTIMER_CPU_H
#define __HWTIMER_CPU_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Hardware timer configuration
* @{
*/
#define HWTIMER_MAXTIMERS 4 /**< the CPU implementation supports 4 HW timers */
#define HWTIMER_SPEED 1000000 /**< the HW timer runs with 1MHz */
#define HWTIMER_MAXTICKS (0xFFFFFFFF) /**< 32-bit timer */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __HWTIMER_CPU_H */
/** @} */

32
cpu/lpc1768/io_arch.c Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the kernel's architecture dependent IO interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "board.h"
#include "arch/io_arch.h"
#include "periph/uart.h"
int io_arch_puts(char *data, int size)
{
int i = 0;
for (; i < size; i++) {
uart_write_blocking(STDIO, data[i]);
}
return i;
}

View File

@ -1,36 +0,0 @@
/**
* LPM dummys for NXP LPC1768
*
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup lpc1768
* @{
* @file lpc1768-lpm.c
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include <stdio.h>
#include <stdint.h>
#include "lpm.h"
/* lpm is accessed before memory init and initialized separately through code */
__attribute__((section(".noinit")))
static enum lpm_mode lpm;
// TODO
enum lpm_mode lpm_set(enum lpm_mode target) {
enum lpm_mode last_lpm = lpm;
lpm = target;
return last_lpm;
}
void lpm_awake(void) {
lpm = LPM_ON;
}

View File

@ -0,0 +1,147 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 512K
ram (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8)
usb_ram (rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
eth_ram (rwx) : ORIGIN = 0x20080000, LENGTH = 16K
}
/* The stack size used by the application. NOTE: you need to adjust */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0xa00 ;
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
/* Support C constructors, and C destructors in both user code
and the C library. This also provides support for C++ code. */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
/* heap section */
. = ALIGN(4);
_sheap = . ;
_eheap = ORIGIN(ram) + LENGTH(ram);
}

54
cpu/lpc1768/lpm_arch.c Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the kernels power management interface
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include "cpu.h"
#include "arch/lpm_arch.h"
void lpm_arch_init(void)
{
/* TODO */
}
enum lpm_mode lpm_arch_set(enum lpm_mode target)
{
/* TODO */
return 0;
}
enum lpm_mode lpm_arch_get(void)
{
/* TODO */
return 0;
}
void lpm_arch_awake(void)
{
/* TODO*/
}
void lpm_arch_begin_awake(void)
{
/* TODO */
}
void lpm_arch_end_awake(void)
{
/* TODO */
}

View File

@ -0,0 +1,3 @@
MODULE = periph
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the low-level timer driver for the LPC1768
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include "periph_conf.h"
#include "periph/timer.h"
/* guard file in case no timers are defined */
#if TIMER_0_EN
int timer_init(tim_t dev, unsigned int ticks_per_us, void (*callback)(int))
{
/* not yet implemented */
return -1;
}
int timer_set(tim_t dev, int channel, unsigned int timeout)
{
/* not yet implemented */
return -1;
}
int timer_set_absolute(tim_t dev, int channel, unsigned int value)
{
/* not yet implemented */
return -1;
}
int timer_clear(tim_t dev, int channel)
{
/* not yet implemented */
return -1;
}
unsigned int timer_read(tim_t dev)
{
/* not yet implemented */
return 0;
}
void timer_start(tim_t dev)
{
/* not yet implemented */
}
void timer_stop(tim_t dev)
{
/* not yet implemented */
}
void timer_irq_enable(tim_t dev)
{
/* not yet implemented */
}
void timer_irq_disable(tim_t dev)
{
/* not yet implemented */
}
void timer_reset(tim_t dev)
{
/* not yet implemented */
}
#endif /* TIMER_0_EN */

65
cpu/lpc1768/periph/uart.c Normal file
View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the low-level UART driver for the LPC1768
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @}
*/
#include <stdint.h>
#include <stdio.h>
#include "cpu.h"
#include "periph/uart.h"
#include "periph_conf.h"
/* guard the file in case no UART is defined */
#if UART_0_EN
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg)
{
/* not yet implemented */
return -1;
}
int uart_init_blocking(uart_t uart, uint32_t baudrate)
{
/* not yet implemented */
return -1;
}
void uart_tx_begin(uart_t uart)
{
/* not yet implemented */
}
int uart_write(uart_t uart, char data)
{
/* not yet implemented */
return -1;
}
int uart_read_blocking(uart_t uart, char *data)
{
/* not yet implemented */
return -1;
}
int uart_write_blocking(uart_t uart, char data)
{
/* not yet implemented */
return -1;
}
#endif /* UART_0_EN */

34
cpu/lpc1768/reboot_arch.c Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Implementation of the kernels reboot interface
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdio.h>
#include "arch/reboot_arch.h"
#include "cpu.h"
int reboot_arch(int mode)
{
printf("Going into reboot, mode %i\n", mode);
NVIC_SystemReset();
return 0;
}

View File

@ -1,310 +1,215 @@
/******************************************************************************
* @file: startup.c
* @purpose: CMSIS Cortex-M3 Core Device Startup File
* @version: V1.02
* @date: 9. November 2013
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* @note: Integrated and adopted for RIOT by Oliver Hahm.
*----------------------------------------------------------------------------
*
* Copyright (C) 2009 ARM Limited. All rights reserved.
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
*
* ARM Limited (ARM) is supplying this software for use with Cortex-Mx
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup lpc1768
* @ingroup cpu_lpc1768
* @{
*
* @file
* @brief Startup code and interrupt vector definition
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdio.h>
#include <stdint.h>
/**
* @file
* @brief lpc1768 startup code
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
*
* memory markers as defined in the linker script
*/
extern uint32_t _sfixed;
extern uint32_t _efixed;
extern uint32_t _etext;
extern uint32_t _srelocate;
extern uint32_t _erelocate;
extern uint32_t _szero;
extern uint32_t _ezero;
extern uint32_t _sstack;
extern uint32_t _estack;
#include "LPC17xx.h"
#include "kernel_internal.h"
#define WEAK __attribute__ ((weak))
/**
* @brief functions for initializing the board, std-lib and kernel
*/
extern void board_init(void);
extern void kernel_init(void);
extern void __libc_init_array(void);
/*****************************************************************************
/**
* @brief This function is the entry point after a system reset
*
* Forward declaration of the default fault handlers.
*
*****************************************************************************/
/* System exception vector handler */
void WEAK Reset_Handler(void); /* Reset Handler */
void WEAK NMI_Handler(void); /* NMI Handler */
void WEAK HardFault_Handler(void); /* Hard Fault Handler */
void WEAK MemManage_Handler(void); /* MPU Fault Handler */
void WEAK BusFault_Handler(void); /* Bus Fault Handler */
void WEAK UsageFault_Handler(void); /* Usage Fault Handler */
void WEAK SVC_Handler(void); /* SVCall Handler */
void WEAK DebugMon_Handler(void); /* Debug Monitor Handler */
void WEAK PendSV_Handler(void); /* PendSV Handler */
void WEAK SysTick_Handler(void); /* SysTick Handler */
/* External interrupt vector handler */
void WEAK WDT_IRQHandler(void); /* Watchdog Timer */
void WEAK TIMER0_IRQHandler(void); /* Timer0 */
void WEAK TIMER1_IRQHandler(void); /* Timer1 */
void WEAK TIMER2_IRQHandler(void); /* Timer2 */
void WEAK TIMER3_IRQHandler(void); /* Timer3 */
void WEAK UART0_IRQHandler(void); /* UART0 */
void WEAK UART1_IRQHandler(void); /* UART1 */
void WEAK UART2_IRQHandler(void); /* UART2 */
void WEAK UART3_IRQHandler(void); /* UART3 */
void WEAK PWM1_IRQHandler(void); /* PWM1 */
void WEAK I2C0_IRQHandler(void); /* I2C0 */
void WEAK I2C1_IRQHandler(void); /* I2C1 */
void WEAK I2C2_IRQHandler(void); /* I2C2 */
void WEAK SPI_IRQHandler(void); /* SPI */
void WEAK SSP0_IRQHandler(void); /* SSP0 */
void WEAK SSP1_IRQHandler(void); /* SSP1 */
void WEAK PLL0_IRQHandler(void); /* PLL0 (Main PLL) */
void WEAK RTC_IRQHandler(void); /* Real Time Clock */
void WEAK EINT0_IRQHandler(void); /* External Interrupt 0 */
void WEAK EINT1_IRQHandler(void); /* External Interrupt 1 */
void WEAK EINT2_IRQHandler(void); /* External Interrupt 2 */
void WEAK EINT3_IRQHandler(void); /* External Interrupt 3 */
void WEAK ADC_IRQHandler(void); /* A/D Converter */
void WEAK BOD_IRQHandler(void); /* Brown Out Detect */
void WEAK USB_IRQHandler(void); /* USB */
void WEAK CAN_IRQHandler(void); /* CAN */
void WEAK DMA_IRQHandler(void); /* GP DMA */
void WEAK I2S_IRQHandler(void); /* I2S */
void WEAK ENET_IRQHandler(void); /* Ethernet */
void WEAK RIT_IRQHandler(void); /* Repetitive Interrupt Timer */
void WEAK MCPWM_IRQHandler(void); /* Motor Control PWM */
void WEAK QEI_IRQHandler(void); /* Quadrature Encoder Interface */
void WEAK PLL1_IRQHandler(void); /* PLL1 (USB PLL) */
/* Exported constants --------------------------------------------------------*/
extern unsigned long __etext;
extern unsigned long __sidata; /* start address for the initialization values of the .data section. defined in linker script */
extern unsigned long __data_start__; /* start address for the .data section. defined in linker script */
extern unsigned long __data_end__; /* end address for the .data section. defined in linker script */
extern unsigned long __bss_start__; /* start address for the .bss section. defined in linker script */
extern unsigned long __bss_end__; /* end address for the .bss section. defined in linker script */
extern void _estack; /* init value for the stack pointer. defined in linker script */
/* function prototypes ------------------------------------------------------*/
void Reset_Handler(void) __attribute__((__interrupt__));
extern void _CPUregTestPOST (void);
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
#define STACK_SIZE 0x00000200
__attribute__ ((section(".stackarea")))
/* static */ unsigned long pulStack[STACK_SIZE];
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
* After a system reset, the following steps are necessary and carried out:
* 1. load data section from flash to ram
* 2. overwrite uninitialized data section (BSS) with zeros
* 3. initialize the newlib
* 4. initialize the board (sync clock, setup std-IO)
* 5. initialize and start RIOTs kernel
*/
void reset_handler(void)
{
/* &_estack, // The initial stack pointer */
(void (*)(void))((unsigned long)pulStack + sizeof(pulStack)), // The initial stack pointer
Reset_Handler, /* Reset Handler */
NMI_Handler, /* NMI Handler */
HardFault_Handler, /* Hard Fault Handler */
MemManage_Handler, /* MPU Fault Handler */
BusFault_Handler, /* Bus Fault Handler */
UsageFault_Handler, /* Usage Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* SVCall Handler */
DebugMon_Handler, /* Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
uint32_t *dst;
uint32_t *src = &_etext;
// External Interrupts
WDT_IRQHandler, /* Watchdog Timer */
TIMER0_IRQHandler, /* Timer0 */
TIMER1_IRQHandler, /* Timer1 */
TIMER2_IRQHandler, /* Timer2 */
TIMER3_IRQHandler, /* Timer3 */
UART0_IRQHandler, /* UART0 */
UART1_IRQHandler, /* UART1 */
UART2_IRQHandler, /* UART2 */
UART3_IRQHandler, /* UART3 */
PWM1_IRQHandler, /* PWM1 */
I2C0_IRQHandler, /* I2C0 */
I2C1_IRQHandler, /* I2C1 */
I2C2_IRQHandler, /* I2C2 */
SPI_IRQHandler, /* SPI */
SSP0_IRQHandler, /* SSP0 */
SSP1_IRQHandler, /* SSP1 */
PLL0_IRQHandler, /* PLL0 (Main PLL) */
RTC_IRQHandler, /* Real Time Clock */
EINT0_IRQHandler, /* External Interrupt 0 */
EINT1_IRQHandler, /* External Interrupt 1 */
EINT2_IRQHandler, /* External Interrupt 2 */
EINT3_IRQHandler, /* External Interrupt 3 */
ADC_IRQHandler, /* A/D Converter */
BOD_IRQHandler, /* Brown Out Detect */
USB_IRQHandler, /* USB */
CAN_IRQHandler, /* CAN */
DMA_IRQHandler, /* GP DMA */
I2S_IRQHandler, /* I2S */
ENET_IRQHandler, /* Ethernet */
RIT_IRQHandler, /* Repetitive Interrupt Timer */
MCPWM_IRQHandler, /* Motor Control PWM */
QEI_IRQHandler, /* Quadrature Encoder Interface */
PLL1_IRQHandler, /* PLL1 (USB PLL) */
};
/*******************************************************************************
* Function Name : Reset_Handler
* Description : This is the code that gets called when the processor first starts execution
* following a reset event. Only the absolutely necessary set is performed,
* after which the application supplied main() routine is called.
* Input :
* Output :
* Return :
*******************************************************************************/
void Reset_Handler(void)
{
unsigned long *pulDest;
/*
* This used for cleaning AHBRAM0 section
*/
#if 0
for (pulDest = ((unsigned long *)AHBRAM0_BASE); \
pulDest < ((unsigned long *)(AHBRAM0_BASE + AHBRAM0_SIZE)); \
pulDest++){
*(pulDest++) = 0;
}
#endif
/*
* This used for cleaning AHBRAM1 section
*/
#if 0
for (pulDest = ((unsigned long *)AHBRAM1_BASE); \
pulDest < ((unsigned long *)(AHBRAM1_BASE + AHBRAM1_SIZE)); \
pulDest++){
*(pulDest++) = 0;
}
#endif
/*
* Copy the data segment initializers from flash to SRAM in ROM mode
*/
#if (__RAM_MODE__==0)
unsigned long *pulSrc = &__sidata;
for(pulDest = &__data_start__; pulDest < &__data_end__; )
{
*(pulDest++) = *(pulSrc++);
}
#endif
/*
* Zero fill the bss segment.
*/
for(pulDest = &__bss_start__; pulDest < &__bss_end__; )
{
*(pulDest++) = 0;
/* load data section from flash to ram */
for (dst = &_srelocate; dst < &_erelocate; ) {
*(dst++) = *(src++);
}
/*
* Call IEC60335 CPU register tests POST
*/
// __ASM volatile ("bl _CPUregTestPOST \t\n");
/* default bss section to zero */
for (dst = &_szero; dst < &_ezero; ) {
*(dst++) = 0;
}
/*
* Call the application's entry point.
*/
/* initialize the board and startup the kernel */
board_init();
/* initialize std-c library (this should be done after board_init) */
__libc_init_array();
/* startup the kernel */
kernel_init();
}
/*****************************************************************************
*
* Provide weak aliases for each Exception handler to the default_handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
****************************************************************************/
#pragma weak MemManage_Handler = default_handler /* MPU Fault Handler */
#pragma weak BusFault_Handler = default_handler /* Bus Fault Handler */
#pragma weak UsageFault_Handler = default_handler /* Usage Fault Handler */
#pragma weak SVC_Handler = default_handler /* SVCall Handler */
#pragma weak DebugMon_Handler = default_handler /* Debug Monitor Handler */
#pragma weak PendSV_Handler = default_handler /* PendSV Handler */
#pragma weak SysTick_Handler = default_handler /* SysTick Handler */
/* External interrupt vector handler */
#pragma weak WDT_IRQHandler = default_handler /* Watchdog Timer */
#pragma weak TIMER0_IRQHandler = default_handler /* Timer0 */
#pragma weak TIMER1_IRQHandler = default_handler /* Timer1 */
#pragma weak TIMER2_IRQHandler = default_handler /* Timer2 */
#pragma weak TIMER3_IRQHandler = default_handler /* Timer3 */
#pragma weak UART0_IRQHandler = default_handler /* UART0 */
#pragma weak UART1_IRQHandler = default_handler /* UART1 */
#pragma weak UART2_IRQHandler = default_handler /* UART2 */
#pragma weak UART3_IRQHandler = default_handler /* UART3 */
#pragma weak PWM1_IRQHandler = default_handler /* PWM1 */
#pragma weak I2C0_IRQHandler = default_handler /* I2C0 */
#pragma weak I2C1_IRQHandler = default_handler /* I2C1 */
#pragma weak I2C2_IRQHandler = default_handler /* I2C2 */
#pragma weak SPI_IRQHandler = default_handler /* SPI */
#pragma weak SSP0_IRQHandler = default_handler /* SSP0 */
#pragma weak SSP1_IRQHandler = default_handler /* SSP1 */
#pragma weak PLL0_IRQHandler = default_handler /* PLL0 (Main PLL) */
#pragma weak RTC_IRQHandler = default_handler /* Real Time Clock */
#pragma weak EINT0_IRQHandler = default_handler /* External Interrupt 0 */
#pragma weak EINT1_IRQHandler = default_handler /* External Interrupt 1 */
#pragma weak EINT2_IRQHandler = default_handler /* External Interrupt 2 */
#pragma weak EINT3_IRQHandler = default_handler /* External Interrupt 3 */
#pragma weak ADC_IRQHandler = default_handler /* A/D Converter */
#pragma weak BOD_IRQHandler = default_handler /* Brown Out Detect */
#pragma weak USB_IRQHandler = default_handler /* USB */
#pragma weak CAN_IRQHandler = default_handler /* CAN */
#pragma weak DMA_IRQHandler = default_handler /* GP DMA */
#pragma weak I2S_IRQHandler = default_handler /* I2S */
#pragma weak ENET_IRQHandler = default_handler /* Ethernet */
#pragma weak RIT_IRQHandler = default_handler /* Repetitive Interrupt Timer */
#pragma weak MCPWM_IRQHandler = default_handler /* Motor Control PWM */
#pragma weak QEI_IRQHandler = default_handler /* Quadrature Encoder Interface */
#pragma weak PLL1_IRQHandler = default_handler /* PLL1 (USB PLL) */
/*****************************************************************************
*
* This is the code that gets called when the processor receives an unexpected
* interrupt. This simply enters an infinite loop, preserving the system state
* for examination by a debugger.
*
****************************************************************************/
void default_handler(void) {
/* Go into an infinite loop. */
while (1) {
}
/**
* @brief Default handler is called in case no interrupt handler was defined
*/
void dummy_handler(void)
{
while (1) {asm ("nop");}
}
void isr_nmi(void)
{
while (1) {asm ("nop");}
}
void isr_mem_manage(void)
{
while (1) {asm ("nop");}
}
void isr_debug_mon(void)
{
while (1) {asm ("nop");}
}
void isr_hard_fault(void)
{
puts("##### HARD FAULT #####");
while (1) {asm ("nop");}
}
void isr_bus_fault(void)
{
puts("##### BUS FAULT #####");
while (1) {asm ("nop");}
}
void isr_usage_fault(void)
{
puts("##### USAGE FAULT #####");
while (1) {asm ("nop");}
}
/* Cortex-M specific interrupt vectors */
void isr_svc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_pendsv(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_systick(void) __attribute__ ((weak, alias("dummy_handler")));
/* LPC1768 specific interrupt vector */
void isr_wdt(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_timer0(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_timer1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_timer2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_timer3(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_uart0(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_uart1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_uart2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_uart3(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_pwm1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_i2c0(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_i2c1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_i2c2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_spi(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_ssp0(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_ssp1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_pll0(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_rtc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_eint0(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_eint1(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_eint2(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_eint3(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_adc(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_bod(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_usb(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_can(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_dma(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_i2s(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_enet(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_rit(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_mcpwm(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_qei(void) __attribute__ ((weak, alias("dummy_handler")));
void isr_pll1(void) __attribute__ ((weak, alias("dummy_handler")));
/* interrupt vector table */
__attribute__ ((section(".vectors")))
const void *interrupt_vector[] = {
/* Stack pointer */
(void*) (&_estack), /* pointer to the top of the empty stack */
/* Cortex-M handlers */
(void*) reset_handler, /* entry point of the program */
(void*) isr_nmi, /* non maskable interrupt handler */
(void*) isr_hard_fault, /* if you end up here its not good */
(void*) isr_mem_manage, /* called on memory fault */
(void*) isr_bus_fault, /* called on bus fault */
(void*) isr_usage_fault, /* callee on usage fault */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) (0UL), /* reserved */
(void*) isr_svc, /* system call interrupt */
(void*) isr_debug_mon, /* debug monitor interrupt */
(void*) (0UL), /* reserved */
(void*) isr_pendsv, /* pendSV interrupt, used for task switching in RIOT */
(void*) isr_systick, /* SysTick interrupt, not used in RIOT */
/* LPC specific peripheral handlers */
(void*) isr_wdt, /* watchdog timer */
(void*) isr_timer0, /* timer0 */
(void*) isr_timer1, /* timer1 */
(void*) isr_timer2, /* timer2 */
(void*) isr_timer3, /* timer3 */
(void*) isr_uart0, /* uart0 */
(void*) isr_uart1, /* uart1 */
(void*) isr_uart2, /* uart2 */
(void*) isr_uart3, /* uart3 */
(void*) isr_pwm1, /* pwm1 */
(void*) isr_i2c0, /* i2c0 */
(void*) isr_i2c1, /* i2c1 */
(void*) isr_i2c2, /* i2c2 */
(void*) isr_spi, /* spi */
(void*) isr_ssp0, /* ssp0 */
(void*) isr_ssp1, /* ssp1 */
(void*) isr_pll0, /* pll0 (main pll) */
(void*) isr_rtc, /* real time clock */
(void*) isr_eint0, /* external interrupt 0 */
(void*) isr_eint1, /* external interrupt 1 */
(void*) isr_eint2, /* external interrupt 2 */
(void*) isr_eint3, /* external interrupt 3 */
(void*) isr_adc, /* a/d converter */
(void*) isr_bod, /* brown out detect */
(void*) isr_usb, /* usb */
(void*) isr_can, /* can */
(void*) isr_dma, /* gp dma */
(void*) isr_i2s, /* i2s */
(void*) isr_enet, /* ethernet */
(void*) isr_rit, /* repetitive interrupt timer */
(void*) isr_mcpwm, /* motor control pwm */
(void*) isr_qei, /* quadrature encoder interface */
(void*) isr_pll1, /* pll1 (usb pll) */
};

View File

@ -1,246 +1,329 @@
/**
* Syscall implementation for NXP LPC1768
*
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup lpc1768
*/
/**
* @ingroup cpu_lpc1768
* @{
* @file syscalls.c
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
*
* @file
* @brief NewLib system calls implementations for LPC1768
*
* @author Michael Baar <michael.baar@fu-berlin.de>
* @author Stefan Pfeiffer <pfeiffer@inf.fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
*
* @}
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#include <stdint.h>
#include <sys/time.h>
#include "board.h"
#include "thread.h"
#include "kernel.h"
#include "mutex.h"
#include "ringbuffer.h"
#include "irq.h"
#ifdef MODULE_VTIMER
#include "vtimer.h"
#include "periph/uart.h"
#ifdef MODULE_UART0
#include "board_uart0.h"
#endif
/**
* @name Heaps (defined in linker script)
* @{
* manage the heap
*/
#define NUM_HEAPS 1
extern char _sheap; /* start of the heap */
extern char _eheap; /* end of the heap */
caddr_t heap_top = (caddr_t)&_sheap + 4;
#define DEBUG_SYSCALLS 0
#if DEBUG_SYSCALLS
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#ifndef MODULE_UART0
/**
* @brief use mutex for waiting on incoming UART chars
*/
static mutex_t uart_rx_mutex;
static char rx_buf_mem[STDIO_RX_BUFSIZE];
static ringbuffer_t rx_buf;
#endif
extern uintptr_t __heap_start; ///< start of heap memory space
extern uintptr_t __heap_max; ///< maximum for end of heap memory space
/// current position in heap
static caddr_t heap[NUM_HEAPS] = {(caddr_t)&__heap_start};
/// maximum position in heap
static const caddr_t heap_max[NUM_HEAPS] = {(caddr_t)&__heap_max};
// start position in heap
static const caddr_t heap_start[NUM_HEAPS] = {(caddr_t)&__heap_start};
// current heap in use
volatile static uint8_t iUsedHeap = 0;
/** @} */
/*-----------------------------------------------------------------------------------*/
void heap_stats(void) {
for(int i = 0; i < NUM_HEAPS; i++)
printf("# heap %i: %p -- %p -> %p (%li of %li free)\n", i, heap_start[i], heap[i], heap_max[i],
(uint32_t)heap_max[i] - (uint32_t)heap[i], (uint32_t)heap_max[i] - (uint32_t)heap_start[i]);
}
/*-----------------------------------------------------------------------------------*/
void __assert_func(const char *file, int line, const char *func, const char *failedexpr)
/**
* @brief Receive a new character from the UART and put it into the receive buffer
*/
void rx_cb(void *arg, char data)
{
printf("#! assertion %s failed\n\t%s() in %s:%d\n", failedexpr, func, file, line );
_exit(3);
}
/*-----------------------------------------------------------------------------------*/
void __assert(const char *file, int line, const char *failedexpr)
{
__assert_func(file, line, "?", failedexpr);
}
/*-----------------------------------------------------------------------------------*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
if(incr < 0)
{
puts("[syscalls] Negative Values for _sbrk_r are not supported");
r->_errno = ENOMEM;
return NULL;
#ifndef MODULE_UART0
(void)arg;
ringbuffer_add_one(&rx_buf, data);
mutex_unlock(&uart_rx_mutex);
#else
if (uart0_handler_pid) {
uart0_handle_incoming(data);
uart0_notify_thread();
}
uint32_t cpsr = disableIRQ();
/* check all heaps for a chunk of the requested size */
for( ; iUsedHeap < NUM_HEAPS; iUsedHeap++ ) {
caddr_t new_heap = heap[iUsedHeap] + incr;
if( new_heap <= heap_max[iUsedHeap] ) {
caddr_t prev_heap = heap[iUsedHeap];
heap[iUsedHeap] = new_heap;
r->_errno = 0;
restoreIRQ(cpsr);
return prev_heap;
}
}
restoreIRQ(cpsr);
r->_errno = ENOMEM;
return NULL;
#endif
}
/*---------------------------------------------------------------------------*/
int _isatty_r(struct _reent *r, int fd)
/**
* @brief Initialize NewLib, called by __libc_init_array() from the startup script
*/
void _init(void)
{
r->_errno = 0;
if( fd == STDOUT_FILENO || fd == STDERR_FILENO )
return 1;
else
return 0;
#ifndef MODULE_UART0
mutex_init(&uart_rx_mutex);
ringbuffer_init(&rx_buf, rx_buf_mem, STDIO_RX_BUFSIZE);
#endif
uart_init(STDIO, STDIO_BAUDRATE, rx_cb, 0, 0);
}
/*---------------------------------------------------------------------------*/
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int whence)
/**
* @brief Free resources on NewLib de-initialization, not used for RIOT
*/
void _fini(void)
{
_off_t result = -1;
PRINTF("lseek [%i] pos %li whence %i\n", fd, pos, whence);
r->_errno = ENODEV;
PRINTF("lseek returned %li (0 is success)\n", result);
return result;
/* nothing to do here */
}
/*---------------------------------------------------------------------------*/
int _open_r(struct _reent *r, const char *name, int mode)
{
int ret = -1;
PRINTF("open '%s' mode %#x\n", name, mode);
r->_errno = ENODEV; // no such device
PRINTF("open [%i] errno %i\n", ret, r->_errno);
return ret;
}
/*---------------------------------------------------------------------------*/
int _stat_r(struct _reent *r, char *name, struct stat *st)
{
int ret = -1;
PRINTF("_stat_r '%s' \n", name);
r->_errno = ENODEV; // no such device
PRINTF("_stat_r [%i] errno %i\n", ret, r->_errno);
return ret;
}
/*---------------------------------------------------------------------------*/
int _fstat_r(struct _reent *r, int fd, struct stat * st)
{
int ret = -1;
r->_errno = 0;
memset(st, 0, sizeof(*st));
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
st->st_mode = S_IFCHR;
ret = 0;
}
else {
r->_errno = ENODEV;
}
return ret;
}
/*---------------------------------------------------------------------------*/
int _write_r(struct _reent *r, int fd, const void *data, unsigned int count)
{
int result = EOF;
r->_errno = EBADF;
switch(fd) {
case STDOUT_FILENO:
case STDERR_FILENO:
{
//FIXME impl fw_puts
//char* chars = (char*) data;
for(int i = 0;i < count;i++) {
//USART_SendData(USART2, chars[i]);
/* Loop until the end of transmission */
//while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET){}
}
return count;
//result = fw_puts((char*)data, count);
}
break;
default:
break;
}
return result;
}
/*---------------------------------------------------------------------------*/
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{
int result = -1;
r->_errno = EBADF;
return result;
}
/*---------------------------------------------------------------------------*/
int _close_r(struct _reent *r, int fd)
{
int ret = -1;
r->_errno = EBADF;
return ret;
}
/*---------------------------------------------------------------------------*/
int _unlink_r(struct _reent *r, char* path)
{
int ret = -1;
r->_errno = ENODEV;
return ret;
}
/*---------------------------------------------------------------------------*/
/**
* @brief Exit a program without cleaning up files
*
* If your system doesn't provide this, it is best to avoid linking with subroutines that
* require it (exit, system).
*
* @param n the exit code, 0 for all OK, >0 for not OK
*/
void _exit(int n)
{
printf("#! exit %i: resetting\n", n);
//FIXME write out all peripherie buffers stdout flush
NVIC_SystemReset();
while(1);
}
/*---------------------------------------------------------------------------*/
pid_t _getpid(void)
/**
* @brief Allocate memory from the heap.
*
* The current heap implementation is very rudimentary, it is only able to allocate
* memory. But it does not
* - have any means to free memory again
*
* @return [description]
*/
caddr_t _sbrk_r(struct _reent *r, ptrdiff_t incr)
{
unsigned int state = disableIRQ();
caddr_t res = heap_top;
if (((incr > 0) && ((heap_top + incr > &_eheap) || (heap_top + incr < res))) ||
((incr < 0) && ((heap_top + incr < &_sheap) || (heap_top + incr > res)))) {
r->_errno = ENOMEM;
res = (void *) -1;
}
else {
heap_top += incr;
}
restoreIRQ(state);
return res;
}
/**
* @brief Get the process-ID of the current thread
*
* @return the process ID of the current thread
*/
int _getpid(void)
{
return sched_active_pid;
}
/*---------------------------------------------------------------------------*/
/**
* @brief Send a signal to a given thread
*
* @param r TODO
* @param pid TODO
* @param sig TODO
*
* @return TODO
*/
__attribute__ ((weak))
int _kill_r(struct _reent *r, int pid, int sig)
{
r->_errno = ESRCH; /* not implemented yet */
return -1;
}
/*---------------------------------------------------------------------------*/
#ifdef MODULE_VTIMER
int _gettimeofday(struct timeval *tp, void *restrict tzp) {
(void) tzp;
vtimer_gettimeofday(tp);
return 0;
}
#endif
void _init(void){}
void _fini(void){}
/**
* @brief Open a file
*
* @param r TODO
* @param name TODO
* @param mode TODO
*
* @return TODO
*/
int _open_r(struct _reent *r, const char *name, int mode)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Read from a file
*
* All input is read from UART_0. The function will block until a byte is actually read.
*
* Note: the read function does not buffer - data will be lost if the function is not
* called fast enough.
*
* TODO: implement more sophisticated read call.
*
* @param r TODO
* @param fd TODO
* @param buffer TODO
* @param int TODO
*
* @return TODO
*/
int _read_r(struct _reent *r, int fd, void *buffer, unsigned int count)
{
#ifndef MODULE_UART0
while (rx_buf.avail == 0) {
mutex_lock(&uart_rx_mutex);
}
return ringbuffer_get(&rx_buf, (char*)buffer, rx_buf.avail);
#else
char *res = (char*)buffer;
res[0] = (char)uart0_readc();
return 1;
#endif
}
/**
* @brief Write characters to a file
*
* All output is currently directed to UART_0, independent of the given file descriptor.
* The write call will further block until the byte is actually written to the UART.
*
* TODO: implement more sophisticated write call.
*
* @param r TODO
* @param fd TODO
* @param data TODO
* @param int TODO
*
* @return TODO
*/
int _write_r(struct _reent *r, int fd, const void *data, unsigned int count)
{
int i = 0;
while (i < count) {
uart_write_blocking(STDIO, ((char*)data)[i++]);
}
return i;
}
/**
* @brief Close a file
*
* @param r TODO
* @param fd TODO
*
* @return TODO
*/
int _close_r(struct _reent *r, int fd)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Set position in a file
*
* @param r TODO
* @param fd TODO
* @param pos TODO
* @param dir TODO
*
* @return TODO
*/
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int dir)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Status of an open file
*
* @param r TODO
* @param fd TODO
* @param stat TODO
*
* @return TODO
*/
int _fstat_r(struct _reent *r, int fd, struct stat * st)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Status of a file (by name)
*
* @param r TODO
* @param name TODO
* @param stat TODO
*
* @return TODO
*/
int _stat_r(struct _reent *r, char *name, struct stat *st)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Query whether output stream is a terminal
*
* @param r TODO
* @param fd TODO
*
* @return TODO
*/
int _isatty_r(struct _reent *r, int fd)
{
r->_errno = 0;
return -1;
}
/**
* @brief Remove a file's directory entry
*
* @param r TODO
* @param path TODO
*
* @return TODO
*/
int _unlink_r(struct _reent *r, char* path)
{
r->_errno = ENODEV; /* not implemented yet */
return -1;
}
/**
* @brief Send a signal to a thread