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:
commit
bfa2bfb5ad
@ -1,3 +1,4 @@
|
||||
MODULE =$(BOARD)_base
|
||||
# tell the Makefile.base which module to build
|
||||
MODULE = $(BOARD)_base
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
@ -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/
|
||||
|
||||
55
boards/mbed_lpc1768/board.c
Normal file
55
boards/mbed_lpc1768/board.c
Normal 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);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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 */
|
||||
/** @} */
|
||||
|
||||
72
boards/mbed_lpc1768/include/periph_conf.h
Normal file
72
boards/mbed_lpc1768/include/periph_conf.h
Normal 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 */
|
||||
/** @} */
|
||||
@ -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 */
|
||||
@ -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();
|
||||
}
|
||||
@ -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.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
70
cpu/lpc1768/hwtimer_arch.c
Normal file
70
cpu/lpc1768/hwtimer_arch.c
Normal 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));
|
||||
}
|
||||
@ -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__
|
||||
|
||||
@ -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
|
||||
\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 */
|
||||
@ -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 */
|
||||
/** @} */
|
||||
|
||||
@ -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 */
|
||||
@ -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
32
cpu/lpc1768/io_arch.c
Normal 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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
147
cpu/lpc1768/lpc1768_linkerscript.ld
Normal file
147
cpu/lpc1768/lpc1768_linkerscript.ld
Normal 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
54
cpu/lpc1768/lpm_arch.c
Normal 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 */
|
||||
}
|
||||
3
cpu/lpc1768/periph/Makefile
Normal file
3
cpu/lpc1768/periph/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = periph
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
81
cpu/lpc1768/periph/timer.c
Normal file
81
cpu/lpc1768/periph/timer.c
Normal 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
65
cpu/lpc1768/periph/uart.c
Normal 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
34
cpu/lpc1768/reboot_arch.c
Normal 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;
|
||||
}
|
||||
@ -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) */
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user