cpu/lpc1768: heavy clean-up of existing code
- moved to new port structure - rewrote startup code - added implementation dummies for UART and timer - switched to atmel linkerscript - cleaned up Makefilesdev/timer
parent
eff4f30640
commit
9214990aee
@ -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")
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_lpc1768
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of the CPU initialization
|
||||
*
|
||||
* @file cpu.c
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu.h"
|
||||
#include "kernel.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
int inISR(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)
|
||||
/**
|
||||
* @brief Initialize the CPU, set IRQ priorities
|
||||
*/
|
||||
void cpu_init(void)
|
||||
{
|
||||
(void) mode;
|
||||
|
||||
while (1) {
|
||||
arm_reset();
|
||||
}
|
||||
|
||||
return -1;
|
||||
/* set pendSV interrupt to lowest possible priority */
|
||||
NVIC_SetPriority(PendSV_IRQn, 0xff);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
@ -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));
|
||||
}
|
@ -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
@ -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 */
|
@ -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
|
||||
|