mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #318 from OlegHahm/lpc1768
initial support for the mbed NXP LPC168
This commit is contained in:
commit
1cc2767bb4
@ -31,3 +31,6 @@ endif
|
||||
ifeq ($(BOARD),native)
|
||||
INCLUDES += -I$(RIOTBOARD)/native/include/
|
||||
endif
|
||||
ifeq ($(BOARD),mbed_lpc1768)
|
||||
INCLUDES += -I$(RIOTBOARD)/mbed_lpc1768/include/
|
||||
endif
|
||||
|
28
boards/mbed_lpc1768/Makefile
Normal file
28
boards/mbed_lpc1768/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
SRC = $(wildcard *.c)
|
||||
BINDIR = $(RIOTBOARD)/$(BOARD)/bin/
|
||||
OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
|
||||
DEP = $(SRC:%.c=$(BINDIR)%.d)
|
||||
export ARCH = mbed_lpc1768_base.a
|
||||
|
||||
INCLUDES += -Iinclude/
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/include
|
||||
INCLUDES += -I$(RIOTBASE)/core/include
|
||||
|
||||
all: $(BINDIR)$(ARCH)
|
||||
|
||||
$(BINDIR)$(ARCH): $(OBJ)
|
||||
$(AR) rcs $(BINDIR)$(ARCH) $(OBJ)
|
||||
|
||||
# pull in dependency info for *existing* .o files
|
||||
-include $(OBJ:.o=.d)
|
||||
|
||||
# compile and generate dependency info
|
||||
$(BINDIR)%.o: %.c
|
||||
mkdir -p $(BINDIR)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d
|
||||
@printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d
|
||||
|
||||
# remove compilation products
|
||||
clean:
|
||||
rm -f $(OBJ) $(DEP)
|
28
boards/mbed_lpc1768/Makefile.include
Normal file
28
boards/mbed_lpc1768/Makefile.include
Normal file
@ -0,0 +1,28 @@
|
||||
## the cpu to build for
|
||||
export CPU = lpc1768
|
||||
|
||||
# toolchain config
|
||||
export PREFIX = arm-none-eabi-
|
||||
export CC = @$(PREFIX)gcc
|
||||
export AR = @$(PREFIX)ar
|
||||
export CFLAGS = -DUSE_STDPERIPH_DRIVER -ggdb -g3 -std=gnu99 -O0 -Wall -Wstrict-prototypes -mcpu=cortex-m3 $(FPU_USAGE) -mlittle-endian -mthumb -mthumb-interwork -nostartfiles
|
||||
export ASFLAGS = -ggdb -g3 -mcpu=cortex-m3 $(FPU_USAGE) -mlittle-endian
|
||||
export AS = $(PREFIX)as
|
||||
export LINK = $(PREFIX)gcc
|
||||
export SIZE = $(PREFIX)size
|
||||
export OBJCOPY = $(PREFIX)objcopy
|
||||
#LINKFLAGS = -g3 -ggdb -mcpu=cortex-m3 $(FPU_USAGE) -mlittle-endian -static -lgcc -mthumb -mthumb-interwork -nostartfiles -T$(RIOTCPU)/$(CPU)/LPC1768.ld
|
||||
LINKFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--gc-sections,--cref -lc -lgcc -lnosys -T$(RIOTCPU)/$(CPU)/LPC1768.ld -nostartfiles
|
||||
|
||||
ifeq ($(strip $(PORT)),)
|
||||
export PORT = /dev/ttyUSB0
|
||||
endif
|
||||
export HEXFILE = bin/$(PROJECT).hex
|
||||
export FFLAGS = $(HEXFILE)
|
||||
|
||||
export ELFFILE = bin/$(PROJECT).elf
|
||||
export DEBUGGER_FLAGS = $(ELFFILE)
|
||||
|
||||
INCLUDES += -Iinclude/
|
||||
INCLUDES += -I$(RIOTCPU)/$(CPU)/include
|
||||
export OFLAGS = -O binary
|
569
boards/mbed_lpc1768/board_init.c
Normal file
569
boards/mbed_lpc1768/board_init.c
Normal file
@ -0,0 +1,569 @@
|
||||
/**************************************************************************//**
|
||||
* @file boards_init.c
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File
|
||||
* for the NXP LPC17xx Device Series
|
||||
* @version V1.09
|
||||
* @date 09. November 2013
|
||||
*
|
||||
* @note Integrated, adopted, and renamed for RIOT by Oliver Hahm.
|
||||
*
|
||||
* Copyright (C) 2009 ARM Limited. All rights reserved.
|
||||
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @par
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "board.h"
|
||||
#include "LPC17xx.h"
|
||||
|
||||
/*--------------------- Clock Configuration ----------------------------------
|
||||
//
|
||||
// <e> Clock Configuration
|
||||
// <h> System Controls and Status Register (SCS)
|
||||
// <o1.4> OSCRANGE: Main Oscillator Range Select
|
||||
// <0=> 1 MHz to 20 MHz
|
||||
// <1=> 15 MHz to 24 MHz
|
||||
// <e1.5> OSCEN: Main Oscillator Enable
|
||||
// </e>
|
||||
// </h>
|
||||
//
|
||||
// <h> Clock Source Select Register (CLKSRCSEL)
|
||||
// <o2.0..1> CLKSRC: PLL Clock Source Selection
|
||||
// <0=> Internal RC oscillator
|
||||
// <1=> Main oscillator
|
||||
// <2=> RTC oscillator
|
||||
// </h>
|
||||
//
|
||||
// <e3> PLL0 Configuration (Main PLL)
|
||||
// <h> PLL0 Configuration Register (PLL0CFG)
|
||||
// <i> F_cco0 = (2 * M * F_in) / N
|
||||
// <i> F_in must be in the range of 32 kHz to 50 MHz
|
||||
// <i> F_cco0 must be in the range of 275 MHz to 550 MHz
|
||||
// <o4.0..14> MSEL: PLL Multiplier Selection
|
||||
// <6-32768><#-1>
|
||||
// <i> M Value
|
||||
// <o4.16..23> NSEL: PLL Divider Selection
|
||||
// <1-256><#-1>
|
||||
// <i> N Value
|
||||
// </h>
|
||||
// </e>
|
||||
//
|
||||
// <e5> PLL1 Configuration (USB PLL)
|
||||
// <h> PLL1 Configuration Register (PLL1CFG)
|
||||
// <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)
|
||||
// <i> F_cco1 = F_osc * M * 2 * P
|
||||
// <i> F_cco1 must be in the range of 156 MHz to 320 MHz
|
||||
// <o6.0..4> MSEL: PLL Multiplier Selection
|
||||
// <1-32><#-1>
|
||||
// <i> M Value (for USB maximum value is 4)
|
||||
// <o6.5..6> PSEL: PLL Divider Selection
|
||||
// <0=> 1
|
||||
// <1=> 2
|
||||
// <2=> 4
|
||||
// <3=> 8
|
||||
// <i> P Value
|
||||
// </h>
|
||||
// </e>
|
||||
//
|
||||
// <h> CPU Clock Configuration Register (CCLKCFG)
|
||||
// <o7.0..7> CCLKSEL: Divide Value for CPU Clock from PLL0
|
||||
// <1-256><#-1>
|
||||
// </h>
|
||||
//
|
||||
// <h> USB Clock Configuration Register (USBCLKCFG)
|
||||
// <o8.0..3> USBSEL: Divide Value for USB Clock from PLL0
|
||||
// <0-15>
|
||||
// <i> Divide is USBSEL + 1
|
||||
// </h>
|
||||
//
|
||||
// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
|
||||
// <o9.0..1> PCLK_WDT: Peripheral Clock Selection for WDT
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.6..7> PCLK_UART0: Peripheral Clock Selection for UART0
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.8..9> PCLK_UART1: Peripheral Clock Selection for UART1
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.16..17> PCLK_SPI: Peripheral Clock Selection for SPI
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.22..23> PCLK_DAC: Peripheral Clock Selection for DAC
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.24..25> PCLK_ADC: Peripheral Clock Selection for ADC
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o9.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 6
|
||||
// <o9.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 6
|
||||
// <o9.30..31> PCLK_ACF: Peripheral Clock Selection for ACF
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 6
|
||||
// </h>
|
||||
//
|
||||
// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
|
||||
// <o10.0..1> PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.4..5> PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM
|
||||
// <0=> Pclk = Cclk / 4
|
||||
// <1=> Pclk = Cclk
|
||||
// <2=> Pclk = Cclk / 2
|
||||
// <3=> Pclk = Hclk / 8
|
||||
// </h>
|
||||
//
|
||||
// <h> Power Control for Peripherals Register (PCONP)
|
||||
// <o11.1> PCTIM0: Timer/Counter 0 power/clock enable
|
||||
// <o11.2> PCTIM1: Timer/Counter 1 power/clock enable
|
||||
// <o11.3> PCUART0: UART 0 power/clock enable
|
||||
// <o11.4> PCUART1: UART 1 power/clock enable
|
||||
// <o11.6> PCPWM1: PWM 1 power/clock enable
|
||||
// <o11.7> PCI2C0: I2C interface 0 power/clock enable
|
||||
// <o11.8> PCSPI: SPI interface power/clock enable
|
||||
// <o11.9> PCRTC: RTC power/clock enable
|
||||
// <o11.10> PCSSP1: SSP interface 1 power/clock enable
|
||||
// <o11.12> PCAD: A/D converter power/clock enable
|
||||
// <o11.13> PCCAN1: CAN controller 1 power/clock enable
|
||||
// <o11.14> PCCAN2: CAN controller 2 power/clock enable
|
||||
// <o11.15> PCGPIO: GPIOs power/clock enable
|
||||
// <o11.16> PCRIT: Repetitive interrupt timer power/clock enable
|
||||
// <o11.17> PCMC: Motor control PWM power/clock enable
|
||||
// <o11.18> PCQEI: Quadrature encoder interface power/clock enable
|
||||
// <o11.19> PCI2C1: I2C interface 1 power/clock enable
|
||||
// <o11.21> PCSSP0: SSP interface 0 power/clock enable
|
||||
// <o11.22> PCTIM2: Timer 2 power/clock enable
|
||||
// <o11.23> PCTIM3: Timer 3 power/clock enable
|
||||
// <o11.24> PCUART2: UART 2 power/clock enable
|
||||
// <o11.25> PCUART3: UART 3 power/clock enable
|
||||
// <o11.26> PCI2C2: I2C interface 2 power/clock enable
|
||||
// <o11.27> PCI2S: I2S interface power/clock enable
|
||||
// <o11.29> PCGPDMA: GP DMA function power/clock enable
|
||||
// <o11.30> PCENET: Ethernet block power/clock enable
|
||||
// <o11.31> PCUSB: USB interface power/clock enable
|
||||
// </h>
|
||||
//
|
||||
// <h> Clock Output Configuration Register (CLKOUTCFG)
|
||||
// <o12.0..3> CLKOUTSEL: Selects clock source for CLKOUT
|
||||
// <0=> CPU clock
|
||||
// <1=> Main oscillator
|
||||
// <2=> Internal RC oscillator
|
||||
// <3=> USB clock
|
||||
// <4=> RTC oscillator
|
||||
// <o12.4..7> CLKOUTDIV: Selects clock divider for CLKOUT
|
||||
// <1-16><#-1>
|
||||
// <o12.8> CLKOUT_EN: CLKOUT enable control
|
||||
// </h>
|
||||
//
|
||||
// </e>
|
||||
*/
|
||||
#define CLOCK_SETUP 1
|
||||
#define SCS_Val 0x00000020
|
||||
#define CLKSRCSEL_Val 0x00000001
|
||||
#define PLL0_SETUP 1
|
||||
#define PLL0CFG_Val 0x00050063
|
||||
#define PLL1_SETUP 1
|
||||
#define PLL1CFG_Val 0x00000023
|
||||
#define CCLKCFG_Val 0x00000003
|
||||
#define USBCLKCFG_Val 0x00000000
|
||||
#define PCLKSEL0_Val 0x00000000
|
||||
#define PCLKSEL1_Val 0x00000000
|
||||
#define PCONP_Val 0x042887DE
|
||||
#define CLKOUTCFG_Val 0x00000000
|
||||
|
||||
|
||||
/*--------------------- Flash Accelerator Configuration ----------------------
|
||||
//
|
||||
// <e> Flash Accelerator Configuration
|
||||
// <o1.12..15> FLASHTIM: Flash Access Time
|
||||
// <0=> 1 CPU clock (for CPU clock up to 20 MHz)
|
||||
// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)
|
||||
// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)
|
||||
// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)
|
||||
// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)
|
||||
// <5=> 6 CPU clocks (for any CPU clock)
|
||||
// </e>
|
||||
*/
|
||||
#define FLASH_SETUP 1
|
||||
#define FLASHCFG_Val 0x00004000
|
||||
|
||||
/*
|
||||
//-------- <<< end of configuration section >>> ------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Check the register settings
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
|
||||
#define CHECK_RSVD(val, mask) (val & mask)
|
||||
|
||||
/* Clock Configuration -------------------------------------------------------*/
|
||||
#if (CHECK_RSVD((SCS_Val), ~0x00000030))
|
||||
#error "SCS: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
|
||||
#error "CLKSRCSEL: Value out of range!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF))
|
||||
#error "PLL0CFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
|
||||
#error "PLL1CFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (PLL0_SETUP) /* if PLL0 is used */
|
||||
#if (CCLKCFG_Val < 2) /* CCLKSEL must be greater then 1 */
|
||||
#error "CCLKCFG: CCLKSEL must be greater then 1 if PLL0 is used!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (CHECK_RANGE((CCLKCFG_Val), 2, 255))
|
||||
#error "CCLKCFG: Value out of range!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
|
||||
#error "USBCLKCFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00))
|
||||
#error "PCLKSEL0: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300))
|
||||
#error "PCLKSEL1: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((PCONP_Val), 0x10100821))
|
||||
#error "PCONP: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
|
||||
#error "CLKOUTCFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
/* Flash Accelerator Configuration -------------------------------------------*/
|
||||
#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000))
|
||||
#error "FLASHCFG: Invalid values of reserved bits!"
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
DEFINES
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL (12000000UL) /* Oscillator frequency */
|
||||
#define OSC_CLK ( XTAL) /* Main oscillator frequency */
|
||||
#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
|
||||
#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */
|
||||
|
||||
|
||||
/* F_cco0 = (2 * M * F_in) / N */
|
||||
#define __M (((PLL0CFG_Val ) & 0x7FFF) + 1)
|
||||
#define __N (((PLL0CFG_Val >> 16) & 0x00FF) + 1)
|
||||
#define __FCCO(__F_IN) ((2ULL * __M * __F_IN) / __N)
|
||||
#define __CCLK_DIV (((CCLKCFG_Val ) & 0x00FF) + 1)
|
||||
|
||||
/* Determine core clock frequency according to settings */
|
||||
#if (PLL0_SETUP)
|
||||
#if ((CLKSRCSEL_Val & 0x03) == 1)
|
||||
#define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV)
|
||||
#elif ((CLKSRCSEL_Val & 0x03) == 2)
|
||||
#define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV)
|
||||
#else
|
||||
#define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV)
|
||||
#endif
|
||||
#else
|
||||
#if ((CLKSRCSEL_Val & 0x03) == 1)
|
||||
#define __CORE_CLK (OSC_CLK / __CCLK_DIV)
|
||||
#elif ((CLKSRCSEL_Val & 0x03) == 2)
|
||||
#define __CORE_CLK (RTC_CLK / __CCLK_DIV)
|
||||
#else
|
||||
#define __CORE_CLK (IRC_OSC / __CCLK_DIV)
|
||||
#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
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t system_clock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
void clock_update(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 */
|
||||
switch (LPC_SC->CLKSRCSEL & 0x03) {
|
||||
case 0: /* Int. RC oscillator => PLL0 */
|
||||
case 3: /* Reserved, default to Int. RC */
|
||||
system_clock = (IRC_OSC *
|
||||
((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
|
||||
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
|
||||
((LPC_SC->CCLKCFG & 0xFF) + 1));
|
||||
break;
|
||||
|
||||
case 1: /* Main oscillator => PLL0 */
|
||||
system_clock = (OSC_CLK *
|
||||
((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
|
||||
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
|
||||
((LPC_SC->CCLKCFG & 0xFF) + 1));
|
||||
break;
|
||||
|
||||
case 2: /* RTC oscillator => PLL0 */
|
||||
system_clock = (RTC_CLK *
|
||||
((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
|
||||
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
|
||||
((LPC_SC->CCLKCFG & 0xFF) + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (LPC_SC->CLKSRCSEL & 0x03) {
|
||||
case 0: /* Int. RC oscillator => PLL0 */
|
||||
case 3: /* Reserved, default to Int. RC */
|
||||
system_clock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF) + 1);
|
||||
break;
|
||||
|
||||
case 1: /* Main oscillator => PLL0 */
|
||||
system_clock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF) + 1);
|
||||
break;
|
||||
|
||||
case 2: /* RTC oscillator => PLL0 */
|
||||
system_clock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF) + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the system
|
||||
*
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System.
|
||||
*/
|
||||
void board_init(void)
|
||||
{
|
||||
#if (CLOCK_SETUP) /* Clock Setup */
|
||||
LPC_SC->SCS = SCS_Val;
|
||||
|
||||
if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */
|
||||
while ((LPC_SC->SCS & (1 << 6)) == 0); /* Wait for Oscillator to be ready */
|
||||
}
|
||||
|
||||
LPC_SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */
|
||||
|
||||
LPC_SC->PCLKSEL0 = PCLKSEL0_Val; /* Peripheral Clock Selection */
|
||||
LPC_SC->PCLKSEL1 = PCLKSEL1_Val;
|
||||
|
||||
LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */
|
||||
|
||||
#if (PLL0_SETUP)
|
||||
LPC_SC->PLL0CFG = PLL0CFG_Val; /* configure PLL0 */
|
||||
LPC_SC->PLL0FEED = 0xAA;
|
||||
LPC_SC->PLL0FEED = 0x55;
|
||||
|
||||
LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
|
||||
LPC_SC->PLL0FEED = 0xAA;
|
||||
LPC_SC->PLL0FEED = 0x55;
|
||||
|
||||
while (!(LPC_SC->PLL0STAT & (1 << 26))); /* Wait for PLOCK0 */
|
||||
|
||||
LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */
|
||||
LPC_SC->PLL0FEED = 0xAA;
|
||||
LPC_SC->PLL0FEED = 0x55;
|
||||
|
||||
while (!(LPC_SC->PLL0STAT & ((1 << 25) | (1 << 24)))); /* Wait for PLLC0_STAT & PLLE0_STAT */
|
||||
|
||||
#endif
|
||||
|
||||
#if (PLL1_SETUP)
|
||||
LPC_SC->PLL1CFG = PLL1CFG_Val;
|
||||
LPC_SC->PLL1FEED = 0xAA;
|
||||
LPC_SC->PLL1FEED = 0x55;
|
||||
|
||||
LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */
|
||||
LPC_SC->PLL1FEED = 0xAA;
|
||||
LPC_SC->PLL1FEED = 0x55;
|
||||
|
||||
while (!(LPC_SC->PLL1STAT & (1 << 10))); /* Wait for PLOCK1 */
|
||||
|
||||
LPC_SC->PLL1CON = 0x03; /* PLL1 Enable & Connect */
|
||||
LPC_SC->PLL1FEED = 0xAA;
|
||||
LPC_SC->PLL1FEED = 0x55;
|
||||
|
||||
while (!(LPC_SC->PLL1STAT & ((1 << 9) | (1 << 8)))); /* Wait for PLLC1_STAT & PLLE1_STAT */
|
||||
|
||||
#else
|
||||
LPC_SC->USBCLKCFG = USBCLKCFG_Val; /* Setup USB Clock Divider */
|
||||
#endif
|
||||
|
||||
LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */
|
||||
|
||||
LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */
|
||||
#endif
|
||||
|
||||
#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();
|
||||
}
|
35
boards/mbed_lpc1768/include/board.h
Normal file
35
boards/mbed_lpc1768/include/board.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __BOARD_H
|
||||
#define __BOARD_H
|
||||
|
||||
/**
|
||||
* @file boards.h
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* @defgroup mbed_lpc1768 mbed NXP LPC1768 development kit
|
||||
* @ingroup boards
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bitarithm.h"
|
||||
|
||||
#define PIN_LED1 (BIT18)
|
||||
#define PIN_LED2 (BIT20)
|
||||
#define PIN_LED3 (BIT21)
|
||||
#define PIN_LED4 (BIT23)
|
||||
|
||||
#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)
|
||||
|
||||
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
|
||||
*/
|
||||
void loop_delay(uint32_t t);
|
||||
|
||||
/** @} */
|
||||
#endif /* __BOARD_H */
|
56
boards/mbed_lpc1768/include/system_LPC17xx.h
Normal file
56
boards/mbed_lpc1768/include/system_LPC17xx.h
Normal file
@ -0,0 +1,56 @@
|
||||
/******************************************************************************
|
||||
* @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 */
|
@ -1,3 +1,7 @@
|
||||
ifeq ($(CPU),lpc1768)
|
||||
DIRS = lpc1768
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),lpc2387)
|
||||
DIRS = arm_common lpc_common lpc2387
|
||||
endif
|
||||
@ -27,6 +31,7 @@ $(DIRS):
|
||||
@"$(MAKE)" -C $@
|
||||
|
||||
clean:
|
||||
@"$(MAKE)" -C lpc1768 clean
|
||||
@"$(MAKE)" -C lpc2387 clean
|
||||
@"$(MAKE)" -C mc1322x clean
|
||||
@"$(MAKE)" -C lpc_common clean
|
||||
|
@ -1,3 +1,6 @@
|
||||
ifeq ($(CPU),lpc1768)
|
||||
INCLUDES += -I$(MAKEBASE)/cpu/lpc1768/include
|
||||
endif
|
||||
ifeq ($(CPU),lpc2387)
|
||||
INCLUDES += -I$(MAKEBASE)/cpu/arm_common/include/
|
||||
INCLUDES += -I$(MAKEBASE)/cpu/lpc_common/include/
|
||||
|
@ -1,4 +1,7 @@
|
||||
### Minimal setup
|
||||
ifeq ($(CPU),lpc1768)
|
||||
export UNDEF += $(BINDIR)syscalls.o
|
||||
endif
|
||||
ifeq ($(CPU),lpc2387)
|
||||
export USEMODULE += arm_common lpc_common
|
||||
export UNDEF += $(BINDIR)syscalls.o $(BINDIR)lpc_syscalls.o
|
||||
|
154
cpu/lpc1768/LPC1768.ld
Normal file
154
cpu/lpc1768/LPC1768.ld
Normal file
@ -0,0 +1,154 @@
|
||||
/* 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")
|
||||
}
|
30
cpu/lpc1768/Makefile
Normal file
30
cpu/lpc1768/Makefile
Normal file
@ -0,0 +1,30 @@
|
||||
MODULE =cpu
|
||||
|
||||
OBJECTS = system_LPC17xx.o startup_LPC17xx.o main.o
|
||||
|
||||
CC_SYMBOLS = -DTARGET_LPC1769 -DTOOLCHAIN_GCC_ARM -DNDEBUG -D__CORTEX_M3
|
||||
|
||||
LD_FLAGS = -mcpu=cortex-m3 -mthumb -Wl,--gc-sections,-Map=$(PROJECT).map,--cref --specs=nano.specs
|
||||
LD_SYS_LIBS = -lc -lgcc -lnosys
|
||||
|
||||
INCLUDES = -Iinclude
|
||||
INCLUDES += -I$(RIOTBASE)/core/include -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/sys/lib
|
||||
|
||||
all: $(BINDIR)$(MODULE).a
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
clean::
|
||||
@for i in $(DIRS) ; do "$(MAKE)" -C $$i clean ; done ;
|
||||
|
||||
# This is needed for NXP Cortex M devices
|
||||
nxpsum:
|
||||
$(CCLOCAL) nxpsum.c -std=c99 -o nxpsum
|
||||
|
||||
#$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
|
||||
# $(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $(addprefix $(BUILD_DIR), $^) $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)
|
||||
|
||||
$(PROJECT).bin: $(PROJECT).elf nxpsum
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
# Compute nxp checksum on .bin file here
|
||||
./nxpsum $@
|
167
cpu/lpc1768/atom.c
Normal file
167
cpu/lpc1768/atom.c
Normal file
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* CPU speficic RIOT kernel function for NXP LPC1768
|
||||
*
|
||||
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. 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"
|
||||
|
||||
extern void sched_task_exit(void);
|
||||
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;
|
||||
}
|
||||
|
||||
void cpu_switch_context_exit(void){
|
||||
sched_run();
|
||||
sched_task_return();
|
||||
}
|
||||
|
||||
|
||||
void thread_yield(void) {
|
||||
asm("svc 0x01\n");
|
||||
}
|
||||
|
||||
|
||||
__attribute__((naked))
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
save_context();
|
||||
asm("bl sched_run");
|
||||
/* call scheduler update 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 *active_thread */
|
||||
asm("ldr r1, =active_thread"); /* r1 = &active_thread */
|
||||
asm("ldr r1, [r1]"); /* r1 = *r1 = active_thread */
|
||||
asm("str r12, [r1]"); /* store stack pointer in tasks pdc*/
|
||||
|
||||
sched_task_return();
|
||||
}
|
||||
/* call scheduler so active_thread points to the next task */
|
||||
void sched_task_return(void)
|
||||
{
|
||||
/* load pdc->stackpointer in r0 */
|
||||
asm("ldr r0, =active_thread"); /* r0 = &active_thread */
|
||||
asm("ldr r0, [r0]"); /* r0 = *r0 = 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}");
|
||||
}
|
||||
/*
|
||||
* 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 * stack_start, int stack_size ) {
|
||||
unsigned int * stk;
|
||||
stk = (unsigned int *) (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;
|
||||
|
||||
/* r0 - r3 */
|
||||
for (int i = 3; i >= 0; i--) {
|
||||
stk--;
|
||||
*stk = i;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
108
cpu/lpc1768/cpu.c
Normal file
108
cpu/lpc1768/cpu.c
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* CPU specific functions for the RIOT scheduler on NXP LPC1768
|
||||
*
|
||||
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @file cpu.c
|
||||
* @author Kaspar Schleiser <kaspar.schleiser@fu-berlin.de>
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
int inISR(void)
|
||||
{
|
||||
return (__get_IPSR() & 0xFF);
|
||||
}
|
||||
|
||||
unsigned int disableIRQ(void)
|
||||
{
|
||||
// FIXME PRIMASK is the old CPSR (FAULTMASK ??? BASEPRI ???)
|
||||
//PRIMASK lesen
|
||||
unsigned int uiPriMask = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
return uiPriMask;
|
||||
}
|
||||
|
||||
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, =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, =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 */
|
||||
}
|
1035
cpu/lpc1768/include/LPC17xx.h
Normal file
1035
cpu/lpc1768/include/LPC17xx.h
Normal file
File diff suppressed because it is too large
Load Diff
13
cpu/lpc1768/include/cmsis.h
Normal file
13
cpu/lpc1768/include/cmsis.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* mbed Microcontroller Library - CMSIS
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* A generic CMSIS include header, pulling in LPC1768 specifics
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_H
|
||||
#define MBED_CMSIS_H
|
||||
|
||||
#include "LPC17xx.h"
|
||||
#include "cmsis_nvic.h"
|
||||
|
||||
#endif
|
1612
cpu/lpc1768/include/core_cm3.h
Normal file
1612
cpu/lpc1768/include/core_cm3.h
Normal file
File diff suppressed because it is too large
Load Diff
617
cpu/lpc1768/include/core_cmFunc.h
Normal file
617
cpu/lpc1768/include/core_cmFunc.h
Normal file
@ -0,0 +1,617 @@
|
||||
/**************************************************************************//**
|
||||
* @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.
|
||||
*
|
||||
* @par
|
||||
* 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 */
|
643
cpu/lpc1768/include/core_cmInstr.h
Normal file
643
cpu/lpc1768/include/core_cmInstr.h
Normal file
@ -0,0 +1,643 @@
|
||||
/**************************************************************************//**
|
||||
* @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.
|
||||
*
|
||||
* @par
|
||||
* 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
|
||||
@{
|
||||
*/
|
||||
|
||||
#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 */
|
18
cpu/lpc1768/include/cpu-conf.h
Normal file
18
cpu/lpc1768/include/cpu-conf.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef CPU_CONF_H
|
||||
#define CPU_CONF_H
|
||||
|
||||
/**
|
||||
* @name Kernel configuration
|
||||
* @{
|
||||
*/
|
||||
#define F_CPU 96000000
|
||||
|
||||
#define KERNEL_CONF_STACKSIZE_PRINTF (4096)
|
||||
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
|
||||
#define KERNEL_CONF_STACKSIZE_DEFAULT 1500
|
||||
#endif
|
||||
|
||||
#define KERNEL_CONF_STACKSIZE_IDLE 1000
|
||||
/** @} */
|
||||
|
||||
#endif /* CPU_CONF_H */
|
34
cpu/lpc1768/include/cpu.h
Normal file
34
cpu/lpc1768/include/cpu.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
/**
|
||||
* @defgroup lpc1768 NXP LPC1768
|
||||
* @ingroup cpu
|
||||
* @{
|
||||
*/
|
||||
|
||||
#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 thread yield
|
||||
*/
|
||||
void thread_yield(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* CPU_H */
|
8
cpu/lpc1768/include/hwtimer_cpu.h
Normal file
8
cpu/lpc1768/include/hwtimer_cpu.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef HWTIMER_CPU_H_
|
||||
#define HWTIMER_CPU_H_
|
||||
|
||||
#define ARCH_MAXTIMERS 3
|
||||
#define HWTIMER_SPEED 1000000
|
||||
#define HWTIMER_MAXTICKS (0xFFFFFFFF)
|
||||
|
||||
#endif /* HWTIMER_CPU_H_ */
|
36
cpu/lpc1768/lpc1768-lpm.c
Normal file
36
cpu/lpc1768/lpc1768-lpm.c
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* LPM dummys for NXP LPC1768
|
||||
*
|
||||
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. 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;
|
||||
}
|
297
cpu/lpc1768/startup.c
Normal file
297
cpu/lpc1768/startup.c
Normal file
@ -0,0 +1,297 @@
|
||||
/******************************************************************************
|
||||
* @file: startup.c
|
||||
* @purpose: CMSIS Cortex-M3 Core Device Startup File
|
||||
* @version: V1.02
|
||||
* @date: 9. 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@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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "LPC17xx.h"
|
||||
#include "kernel_internal.h"
|
||||
|
||||
#define WEAK __attribute__ ((weak))
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* 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) =
|
||||
{
|
||||
/* &_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 */
|
||||
|
||||
// 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 *pulSrc, *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)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call IEC60335 CPU register tests POST
|
||||
*/
|
||||
// __ASM volatile ("bl _CPUregTestPOST \t\n");
|
||||
|
||||
/*
|
||||
* Call the application's entry point.
|
||||
*/
|
||||
board_init();
|
||||
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) {
|
||||
}
|
||||
}
|
231
cpu/lpc1768/syscalls.c
Normal file
231
cpu/lpc1768/syscalls.c
Normal file
@ -0,0 +1,231 @@
|
||||
/**
|
||||
* Syscall implementation for NXP LPC1768
|
||||
*
|
||||
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup lpc1768
|
||||
* @{
|
||||
* @file syscalls.c
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
* @author Alaeddine Weslati <alaeddine.weslati@inria.fr>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <stdint.h>
|
||||
#include "kernel.h"
|
||||
#include "irq.h"
|
||||
|
||||
/**
|
||||
* @name Heaps (defined in linker script)
|
||||
* @{
|
||||
*/
|
||||
#define NUM_HEAPS 1
|
||||
|
||||
#define DEBUG_SYSCALLS 0
|
||||
#if DEBUG_SYSCALLS
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#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)
|
||||
{
|
||||
printf("#! assertion %s failed\n\t%s() in %s:%u\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, size_t incr)
|
||||
{
|
||||
if(incr < 0)
|
||||
{
|
||||
puts("[syscalls] Negative Values for _sbrk_r are not supported");
|
||||
r->_errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int _isatty_r(struct _reent *r, int fd)
|
||||
{
|
||||
r->_errno = 0;
|
||||
if( fd == STDOUT_FILENO || fd == STDERR_FILENO )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
_off_t _lseek_r(struct _reent *r, int fd, _off_t pos, int whence)
|
||||
{
|
||||
_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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void _exit(int n)
|
||||
{
|
||||
printf("#! exit %i: resetting\n", n);
|
||||
|
||||
//FIXME write out all peripherie buffers stdout flush
|
||||
NVIC_SystemReset();
|
||||
while(1);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int _getpid(void)
|
||||
{
|
||||
return active_thread->pid;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int _kill_r(struct _reent *r, int pid, int sig)
|
||||
{
|
||||
/* not implemented */
|
||||
r->_errno = ESRCH; // no such process
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void _init(void){}
|
||||
void _fini(void){}
|
Loading…
Reference in New Issue
Block a user