Add all exercises
This commit is contained in:
commit
35199c438c
|
@ -0,0 +1,5 @@
|
||||||
|
**/build
|
||||||
|
**/exe
|
||||||
|
**/lst
|
||||||
|
|
||||||
|
**/result
|
|
@ -0,0 +1,24 @@
|
||||||
|
# TDT 4160 Solutions Autumn 2021
|
||||||
|
|
||||||
|
In order to build this code, you will need to have the following installed:
|
||||||
|
|
||||||
|
- Simplicity Studio
|
||||||
|
- The `EFM32GG-STK3700` adapter for Simplicity Studio
|
||||||
|
- GNU Make (haven't tested BSD Make)
|
||||||
|
|
||||||
|
For the assembly and C exercises, I'm using the makefile to build and flash the program to the Gecko Board.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd o1 # or o2 / o3
|
||||||
|
make all
|
||||||
|
make flash
|
||||||
|
```
|
||||||
|
|
||||||
|
In order for the commands above to succeed, you might need to edit the makefile to point at your Simplicity Studio install.
|
||||||
|
The original makefile expected Simplicity Studio 3.
|
||||||
|
The paths is currently configured to point at Simplicity Studio 5, installed at `/opt/simplicitystudio5`.
|
||||||
|
The original makefiles are stored as `Makefile.original`, in order to make them easy to diff.
|
||||||
|
|
||||||
|
## Assembly cheatsheet from Azeria Labs
|
||||||
|
|
||||||
|
![azeria-labs.com](https://azeria-labs.com/downloads/cheatsheetv1.3-1920x1080.png)
|
Binary file not shown.
|
@ -0,0 +1,214 @@
|
||||||
|
####################################################################
|
||||||
|
# Makefile #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
.SUFFIXES: # ignore builtin rules
|
||||||
|
.PHONY: all debug release clean flash rammeverk
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# notdirx: version of notdir which allows spaces in path
|
||||||
|
s? = $(subst $(empty) ,?,$1)
|
||||||
|
?s = $(subst ?, ,$1)
|
||||||
|
notdirx = $(call ?s,$(notdir $(call s?,$1)))
|
||||||
|
|
||||||
|
DEVICE = EFM32GG990F1024
|
||||||
|
PROJECTNAME = $(call notdirx,$(CURDIR))
|
||||||
|
|
||||||
|
OBJ_DIR = build
|
||||||
|
EXE_DIR = exe
|
||||||
|
LST_DIR = lst
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions of toolchain. #
|
||||||
|
# You might need to do changes to match your system setup #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
NULLDEVICE := /dev/null
|
||||||
|
SHELLNAMES := $(ComSpec)$(COMSPEC)
|
||||||
|
|
||||||
|
# This is only valid for my specific system.
|
||||||
|
TOOLCHAIN_BIN_DIR := /opt/simplicitystudio5/developer/toolchains/gnu_arm/10.2_2020q4/bin
|
||||||
|
|
||||||
|
CC := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-gcc
|
||||||
|
LD := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-ld
|
||||||
|
AR := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-ar
|
||||||
|
OBJCOPY := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-objcopy
|
||||||
|
DUMP := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-objdump
|
||||||
|
|
||||||
|
# Detect operating system
|
||||||
|
ifeq ($(SHELLNAMES),) # Linux
|
||||||
|
EACOM = /opt/simplicitystudio5/developer/adapter_packs/commander/commander
|
||||||
|
else
|
||||||
|
EACOM = C:\SiliconLabs\SimplicityStudio\v3\bgtool\commander\commander.exe
|
||||||
|
ifneq ($(COMSPEC),) # mingw/msys/cygwin platform running on Windows
|
||||||
|
ifeq ($(findstring cygdrive,$(shell set)),)
|
||||||
|
# We were not on a cygwin platform
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
else # Windows
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Create directories and do a clean which is compatible with parallell make
|
||||||
|
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(shell $(RM) $(OBJ_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(EXE_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(LST_DIR)/*>$(NULLDEVICE) 2>&1) #*/
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Flags #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# -MMD : Don't generate dependencies on system header files.
|
||||||
|
# -MP : Add phony targets, useful when a h-file is removed from a project.
|
||||||
|
# -MF : Specify a file to write the dependencies to.
|
||||||
|
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
|
||||||
|
#
|
||||||
|
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb -ffunction-sections \
|
||||||
|
-fdata-sections -mfix-cortex-m3-ldrd -fomit-frame-pointer -DDEBUG_EFM \
|
||||||
|
-O0 \
|
||||||
|
$(DEPFLAGS)
|
||||||
|
|
||||||
|
ASMFLAGS += -x assembler-with-cpp -mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
|
||||||
|
#
|
||||||
|
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
|
||||||
|
-mthumb -Tefm32gg.ld --specs=nano.specs \
|
||||||
|
-Wl,--gc-sections
|
||||||
|
|
||||||
|
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||||
|
|
||||||
|
INCLUDEPATHS += \
|
||||||
|
-I.. \
|
||||||
|
-I../common/CMSIS/Include \
|
||||||
|
-I../common/EFM32GG/Include \
|
||||||
|
-I../common/emlib/inc \
|
||||||
|
-I../common/EFM32/drivers \
|
||||||
|
-I../common/EFM32/bsp \
|
||||||
|
-I../common/EFM32GG_STK3700/config
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Files #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_SRC += \
|
||||||
|
../common/EFM32GG/Source/system_efm32gg.c \
|
||||||
|
../common/EFM32/drivers/vddcheck.c \
|
||||||
|
../common/EFM32/drivers/segmentlcd.c \
|
||||||
|
../common/emlib/src/em_assert.c \
|
||||||
|
../common/emlib/src/em_cmu.c \
|
||||||
|
../common/emlib/src/em_emu.c \
|
||||||
|
../common/emlib/src/em_gpio.c \
|
||||||
|
../common/emlib/src/em_rtc.c \
|
||||||
|
../common/emlib/src/em_system.c \
|
||||||
|
../common/emlib/src/em_lcd.c \
|
||||||
|
../common/emlib/src/em_vcmp.c \
|
||||||
|
../common/emlib/src/em_usart.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk_leds.c \
|
||||||
|
../common/EFM32/bsp/bsp_trace.c \
|
||||||
|
../common/$(PROJECTNAME)/init.c
|
||||||
|
|
||||||
|
s_SRC += \
|
||||||
|
../common/EFM32GG/Source/GCC/startup_efm32gg.s
|
||||||
|
|
||||||
|
STUDENT_SRC += \
|
||||||
|
$(PROJECTNAME).s \
|
||||||
|
gpio_constants.s \
|
||||||
|
sys-tick_constants.s
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Rules #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_FILES = $(notdir $(C_SRC) )
|
||||||
|
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
|
||||||
|
#make list of source paths, sort also removes duplicates
|
||||||
|
C_PATHS = $(sort $(dir $(C_SRC) ) )
|
||||||
|
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
|
||||||
|
|
||||||
|
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
|
||||||
|
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
|
||||||
|
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
|
||||||
|
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
|
||||||
|
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
|
||||||
|
STUDENT_OBJS = $(addprefix $(OBJ_DIR)/, $(STUDENT_SRC:.s=.o))
|
||||||
|
|
||||||
|
vpath %.c $(C_PATHS)
|
||||||
|
vpath %.s $(S_PATHS)
|
||||||
|
vpath %.S $(S_PATHS)
|
||||||
|
|
||||||
|
|
||||||
|
# Default build is debug build
|
||||||
|
all: debug
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -O0 -g3
|
||||||
|
debug: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
release: CFLAGS += -DNDEBUG -O3 -g3
|
||||||
|
release: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
rammeverk: $(OBJS)
|
||||||
|
|
||||||
|
# Create objects from C SRC files
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@echo "Building file: $<"
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Assemble .s/.S files
|
||||||
|
$(OBJ_DIR)/%.o: %.s
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.S
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Link
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).out: $(STUDENT_OBJS)
|
||||||
|
@echo "Linking target: $@"
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(STUDENT_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
|
||||||
|
# Create binary file
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
@echo "Creating binary file"
|
||||||
|
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
# Uncomment next line to produce assembly listing of entire program
|
||||||
|
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
|
||||||
|
|
||||||
|
# Flash on!
|
||||||
|
ifeq ($(f), 1)
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(RM) $(LST_DIR) $(EXE_DIR)
|
||||||
|
$(RM) $(STUDENT_OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# include auto-generated dependency files (explicit rules)
|
||||||
|
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
flash:
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
@echo "Completed!"
|
|
@ -0,0 +1,214 @@
|
||||||
|
####################################################################
|
||||||
|
# Makefile #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
.SUFFIXES: # ignore builtin rules
|
||||||
|
.PHONY: all debug release clean flash rammeverk
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# notdirx: version of notdir which allows spaces in path
|
||||||
|
s? = $(subst $(empty) ,?,$1)
|
||||||
|
?s = $(subst ?, ,$1)
|
||||||
|
notdirx = $(call ?s,$(notdir $(call s?,$1)))
|
||||||
|
|
||||||
|
DEVICE = EFM32GG990F1024
|
||||||
|
PROJECTNAME = $(call notdirx,$(CURDIR))
|
||||||
|
|
||||||
|
OBJ_DIR = build
|
||||||
|
EXE_DIR = exe
|
||||||
|
LST_DIR = lst
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions of toolchain. #
|
||||||
|
# You might need to do changes to match your system setup #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
NULLDEVICE := /dev/null
|
||||||
|
SHELLNAMES := $(ComSpec)$(COMSPEC)
|
||||||
|
|
||||||
|
CC := arm-none-eabi-gcc
|
||||||
|
LD := arm-none-eabi-ld
|
||||||
|
AR := arm-none-eabi-ar
|
||||||
|
OBJCOPY := arm-none-eabi-objcopy
|
||||||
|
DUMP := arm-none-eabi-objdump
|
||||||
|
|
||||||
|
# Detect operating system
|
||||||
|
ifeq ($(SHELLNAMES),) # Linux
|
||||||
|
EACOM = /opt/SimplicityStudio_v3/bgtool/commander/commander
|
||||||
|
else
|
||||||
|
EACOM = C:\SiliconLabs\SimplicityStudio\v3\bgtool\commander\commander.exe
|
||||||
|
ifneq ($(COMSPEC),) # mingw/msys/cygwin platform running on Windows
|
||||||
|
ifeq ($(findstring cygdrive,$(shell set)),)
|
||||||
|
# We were not on a cygwin platform
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
else # Windows
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Create directories and do a clean which is compatible with parallell make
|
||||||
|
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(shell $(RM) $(OBJ_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(EXE_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(LST_DIR)/*>$(NULLDEVICE) 2>&1) #*/
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Flags #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# -MMD : Don't generate dependencies on system header files.
|
||||||
|
# -MP : Add phony targets, useful when a h-file is removed from a project.
|
||||||
|
# -MF : Specify a file to write the dependencies to.
|
||||||
|
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
|
||||||
|
#
|
||||||
|
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb -ffunction-sections \
|
||||||
|
-fdata-sections -mfix-cortex-m3-ldrd -fomit-frame-pointer -DDEBUG_EFM \
|
||||||
|
-O0 \
|
||||||
|
$(DEPFLAGS)
|
||||||
|
|
||||||
|
ASMFLAGS += -x assembler-with-cpp -mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
|
||||||
|
#
|
||||||
|
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
|
||||||
|
-mthumb -Tefm32gg.ld --specs=nano.specs \
|
||||||
|
-Wl,--gc-sections
|
||||||
|
|
||||||
|
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||||
|
|
||||||
|
INCLUDEPATHS += \
|
||||||
|
-I.. \
|
||||||
|
-I../common/CMSIS/Include \
|
||||||
|
-I../common/EFM32GG/Include \
|
||||||
|
-I../common/emlib/inc \
|
||||||
|
-I../common/EFM32/drivers \
|
||||||
|
-I../common/EFM32/bsp \
|
||||||
|
-I../common/EFM32GG_STK3700/config
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Files #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_SRC += \
|
||||||
|
../common/EFM32GG/Source/system_efm32gg.c \
|
||||||
|
../common/EFM32/drivers/vddcheck.c \
|
||||||
|
../common/EFM32/drivers/segmentlcd.c \
|
||||||
|
../common/emlib/src/em_assert.c \
|
||||||
|
../common/emlib/src/em_cmu.c \
|
||||||
|
../common/emlib/src/em_emu.c \
|
||||||
|
../common/emlib/src/em_gpio.c \
|
||||||
|
../common/emlib/src/em_rtc.c \
|
||||||
|
../common/emlib/src/em_system.c \
|
||||||
|
../common/emlib/src/em_lcd.c \
|
||||||
|
../common/emlib/src/em_vcmp.c \
|
||||||
|
../common/emlib/src/em_usart.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk_leds.c \
|
||||||
|
../common/EFM32/bsp/bsp_trace.c \
|
||||||
|
../common/$(PROJECTNAME)/init.c
|
||||||
|
|
||||||
|
s_SRC += \
|
||||||
|
../common/EFM32GG/Source/GCC/startup_efm32gg.s
|
||||||
|
|
||||||
|
STUDENT_SRC += \
|
||||||
|
$(PROJECTNAME).s \
|
||||||
|
gpio_constants.s \
|
||||||
|
sys-tick_constants.s
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Rules #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_FILES = $(notdir $(C_SRC) )
|
||||||
|
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
|
||||||
|
#make list of source paths, sort also removes duplicates
|
||||||
|
C_PATHS = $(sort $(dir $(C_SRC) ) )
|
||||||
|
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
|
||||||
|
|
||||||
|
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
|
||||||
|
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
|
||||||
|
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
|
||||||
|
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
|
||||||
|
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
|
||||||
|
STUDENT_OBJS = $(addprefix $(OBJ_DIR)/, $(STUDENT_SRC:.s=.o))
|
||||||
|
|
||||||
|
vpath %.c $(C_PATHS)
|
||||||
|
vpath %.s $(S_PATHS)
|
||||||
|
vpath %.S $(S_PATHS)
|
||||||
|
|
||||||
|
|
||||||
|
# Default build is debug build
|
||||||
|
all: debug
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -O0 -g3
|
||||||
|
debug: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
release: CFLAGS += -DNDEBUG -O3 -g3
|
||||||
|
release: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
rammeverk: $(OBJS)
|
||||||
|
|
||||||
|
# Create objects from C SRC files
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@echo "Building file: $<"
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Assemble .s/.S files
|
||||||
|
$(OBJ_DIR)/%.o: %.s
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.S
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Link
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).out: $(STUDENT_OBJS)
|
||||||
|
@echo "Linking target: $@"
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(STUDENT_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
|
||||||
|
# Create binary file
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
@echo "Creating binary file"
|
||||||
|
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
# Uncomment next line to produce assembly listing of entire program
|
||||||
|
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
|
||||||
|
|
||||||
|
# Flash on!
|
||||||
|
ifeq ($(f), 1)
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(RM) $(LST_DIR) $(EXE_DIR)
|
||||||
|
$(RM) $(STUDENT_OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# include auto-generated dependency files (explicit rules)
|
||||||
|
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
flash:
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
@echo "Completed!"
|
|
@ -0,0 +1,207 @@
|
||||||
|
/* Linker script for Silicon Labs EFM32GG devices */
|
||||||
|
/* */
|
||||||
|
/* This file is subject to the license terms as defined in ARM's */
|
||||||
|
/* CMSIS END USER LICENSE AGREEMENT.pdf, governing the use of */
|
||||||
|
/* Example Code. */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2018 Silicon Laboratories, Inc. http://www.silabs.com */
|
||||||
|
/* */
|
||||||
|
/* Version 5.5.0 */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1048576
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 131072
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_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
|
||||||
|
* __Vectors_End
|
||||||
|
* __Vectors_Size
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
__Vectors_End = .;
|
||||||
|
__Vectors_Size = __Vectors_End - __Vectors;
|
||||||
|
__end__ = .;
|
||||||
|
|
||||||
|
*(.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 = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN (4);
|
||||||
|
*(.ram)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__HeapBase = .;
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
_end = __end__;
|
||||||
|
KEEP(*(.heap*))
|
||||||
|
__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 (COPY):
|
||||||
|
{
|
||||||
|
KEEP(*(.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")
|
||||||
|
|
||||||
|
/* Check if FLASH usage exceeds FLASH size */
|
||||||
|
ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
// GPIO base-adresse
|
||||||
|
GPIO_BASE = 0x40006000
|
||||||
|
|
||||||
|
// --- [Offset til GPIO-registrene]----------------------------------------- //
|
||||||
|
// --- [Offset til portregistrene ] ------------------------------- //
|
||||||
|
GPIO_PORT_CTRL = 0 // Port Control Register
|
||||||
|
GPIO_PORT_MODEL = 4 // Port Pin Mode Low Register
|
||||||
|
GPIO_PORT_MODEH = 8 // Port Pin Mode High Register
|
||||||
|
GPIO_PORT_DOUT = 12 // Port Data Out Register
|
||||||
|
GPIO_PORT_DOUTSET = 16 // Port Data Out Set Register
|
||||||
|
GPIO_PORT_DOUTCLR = 20 // Port Data Out Clear Register
|
||||||
|
GPIO_PORT_DOUTTGL = 24 // Port Data Out Toggle Register
|
||||||
|
GPIO_PORT_DIN = 28 // Port Data In Register
|
||||||
|
GPIO_PORT_PINLOCKN = 32 // Port Unlocked Pins Register
|
||||||
|
// ---------------------------------------------------------------- //
|
||||||
|
|
||||||
|
GPIO_EXTIPSELL = 256 // External Interrupt Port Select Low Register
|
||||||
|
GPIO_EXTIPSELH = 260 // External Interrupt Port Select High Register
|
||||||
|
GPIO_EXTIRISE = 264 // External Interrupt Rising Edge Trigger Register
|
||||||
|
GPIO_EXTIFALL = 268 // External Interrupt Falling Edge Trigger Register
|
||||||
|
GPIO_IEN = 272 // Interrupt Enable Register
|
||||||
|
GPIO_IF = 276 // Interrupt Flag Register
|
||||||
|
GPIO_IFS = 280 // Interrupt Flag Set Register
|
||||||
|
GPIO_IFC = 284 // Interrupt Flag Clear Register
|
||||||
|
|
||||||
|
GPIO_ROUTE = 288 // I/O Routing Register
|
||||||
|
GPIO_INSENSE = 292 // Input Sense Register
|
||||||
|
GPIO_LOCK = 296 // Configuration Lock Register
|
||||||
|
GPIO_CTRL = 300 // GPIO Control Register
|
||||||
|
GPIO_CMD = 304 // EM4 Wake-up Clear Register
|
||||||
|
GPIO_EM4WUEN = 308 // EM4 Wake-up Enable Register
|
||||||
|
GPIO_EM4WUPOL = 312 // EM4 Wake-up Polarity Register
|
||||||
|
GPIO_EM4WUCAUSE = 316 // EM4 Wake-up Cause Register
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
// --- [Hjelpekonstanter til GPIO]------------------------------------------ //
|
||||||
|
// Porter
|
||||||
|
PORT_A = 0
|
||||||
|
PORT_B = 1
|
||||||
|
PORT_C = 2
|
||||||
|
PORT_D = 3
|
||||||
|
PORT_E = 4
|
||||||
|
PORT_F = 5
|
||||||
|
|
||||||
|
NUMBER_OF_PORTS = 6 // Antall porter
|
||||||
|
PORT_SIZE = 36 // Antall bytes i et sett med portregistre
|
||||||
|
|
||||||
|
// Enheter på kitet
|
||||||
|
LED_PORT = PORT_E
|
||||||
|
LED_PIN = 2
|
||||||
|
BUTTON_PORT = PORT_B
|
||||||
|
BUTTON_PIN = 9
|
||||||
|
// ------------------------------------------------------------------------- //
|
|
@ -0,0 +1,27 @@
|
||||||
|
.thumb
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.include "gpio_constants.s" // Register-adresser og konstanter for GPIO
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global Start
|
||||||
|
|
||||||
|
LED_PORT_BASE = GPIO_BASE + (LED_PORT * PORT_SIZE)
|
||||||
|
LED_SET_ADDR = LED_PORT_BASE + GPIO_PORT_DOUTSET
|
||||||
|
LED_CLEAR_ADDR = LED_PORT_BASE + GPIO_PORT_DOUTCLR
|
||||||
|
BUTTON_READ_ADDR = GPIO_BASE + (BUTTON_PORT * PORT_SIZE) + GPIO_PORT_DIN
|
||||||
|
|
||||||
|
Start:
|
||||||
|
LDR R0, =LED_SET_ADDR
|
||||||
|
LDR R1, =LED_CLEAR_ADDR
|
||||||
|
LDR R2, =BUTTON_READ_ADDR
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
LDR R3, [R2] // Read value of BUTTON_READ_ADDR
|
||||||
|
AND R3, R3, 1 << BUTTON_PIN // Mask out the bit of interest
|
||||||
|
LSR R3, BUTTON_PIN - LED_PIN // Shift the bit to the LED_PIN position
|
||||||
|
STR R3, [R1] // Store the value into LED_SET_ADDR
|
||||||
|
EOR R3, R3, 1 << LED_PIN // Flip the bit
|
||||||
|
STR R3, [R0] // Store the opposite bit into LED_CLEAR_ADDR
|
||||||
|
B Loop // Repeat
|
||||||
|
NOP
|
|
@ -0,0 +1,19 @@
|
||||||
|
// SysTick Base-addresse
|
||||||
|
SYSTICK_BASE = 0xE000E010
|
||||||
|
|
||||||
|
// ---[ Offset til sys-tick-registrene ]------------------------ //
|
||||||
|
SYSTICK_CTRL = 0 // SysTick Control and Status Register
|
||||||
|
SYSTICK_LOAD = 4 // SysTick Reload Value Register
|
||||||
|
SYSTICK_VAL = 8 // SysTick Current Value Register
|
||||||
|
SYSTICK_CALIB = 12 // SysTick Calibration Register
|
||||||
|
// ------------------------------------------------------------- //
|
||||||
|
|
||||||
|
|
||||||
|
// ---[ Hjelpekonstanter til sys-tick ]------------------------- //
|
||||||
|
FREQUENCY = 14000000 // Antall klokkesignaler per sekund
|
||||||
|
|
||||||
|
// CTRL-register-masker
|
||||||
|
SysTick_CTRL_CLKSOURCE_Msk = 0b100
|
||||||
|
SysTick_CTRL_TICKINT_Msk = 0b010
|
||||||
|
SysTick_CTRL_ENABLE_Msk = 0b001
|
||||||
|
// ------------------------------------------------------------- //
|
|
@ -0,0 +1,214 @@
|
||||||
|
####################################################################
|
||||||
|
# Makefile #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
.SUFFIXES: # ignore builtin rules
|
||||||
|
.PHONY: all debug release clean flash rammeverk
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# notdirx: version of notdir which allows spaces in path
|
||||||
|
s? = $(subst $(empty) ,?,$1)
|
||||||
|
?s = $(subst ?, ,$1)
|
||||||
|
notdirx = $(call ?s,$(notdir $(call s?,$1)))
|
||||||
|
|
||||||
|
DEVICE = EFM32GG990F1024
|
||||||
|
PROJECTNAME = $(call notdirx,$(CURDIR))
|
||||||
|
|
||||||
|
OBJ_DIR = build
|
||||||
|
EXE_DIR = exe
|
||||||
|
LST_DIR = lst
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions of toolchain. #
|
||||||
|
# You might need to do changes to match your system setup #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
NULLDEVICE := /dev/null
|
||||||
|
SHELLNAMES := $(ComSpec)$(COMSPEC)
|
||||||
|
|
||||||
|
# This is only valid for my specific system.
|
||||||
|
TOOLCHAIN_BIN_DIR := /opt/simplicitystudio5/developer/toolchains/gnu_arm/10.2_2020q4/bin
|
||||||
|
|
||||||
|
CC := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-gcc
|
||||||
|
LD := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-ld
|
||||||
|
AR := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-ar
|
||||||
|
OBJCOPY := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-objcopy
|
||||||
|
DUMP := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-objdump
|
||||||
|
|
||||||
|
# Detect operating system
|
||||||
|
ifeq ($(SHELLNAMES),) # Linux
|
||||||
|
EACOM = /opt/simplicitystudio5/developer/adapter_packs/commander/commander
|
||||||
|
else
|
||||||
|
EACOM = C:\SiliconLabs\SimplicityStudio\v3\bgtool\commander\commander.exe
|
||||||
|
ifneq ($(COMSPEC),) # mingw/msys/cygwin platform running on Windows
|
||||||
|
ifeq ($(findstring cygdrive,$(shell set)),)
|
||||||
|
# We were not on a cygwin platform
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
else # Windows
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Create directories and do a clean which is compatible with parallell make
|
||||||
|
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(shell $(RM) $(OBJ_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(EXE_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(LST_DIR)/*>$(NULLDEVICE) 2>&1) #*/
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Flags #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# -MMD : Don't generate dependencies on system header files.
|
||||||
|
# -MP : Add phony targets, useful when a h-file is removed from a project.
|
||||||
|
# -MF : Specify a file to write the dependencies to.
|
||||||
|
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
|
||||||
|
#
|
||||||
|
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb -ffunction-sections \
|
||||||
|
-fdata-sections -mfix-cortex-m3-ldrd -fomit-frame-pointer -DDEBUG_EFM \
|
||||||
|
-O0 \
|
||||||
|
$(DEPFLAGS)
|
||||||
|
|
||||||
|
ASMFLAGS += -x assembler-with-cpp -mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
|
||||||
|
#
|
||||||
|
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
|
||||||
|
-mthumb -Tefm32gg.ld --specs=nano.specs \
|
||||||
|
-Wl,--gc-sections
|
||||||
|
|
||||||
|
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||||
|
|
||||||
|
INCLUDEPATHS += \
|
||||||
|
-I.. \
|
||||||
|
-I../common/CMSIS/Include \
|
||||||
|
-I../common/EFM32GG/Include \
|
||||||
|
-I../common/emlib/inc \
|
||||||
|
-I../common/EFM32/drivers \
|
||||||
|
-I../common/EFM32/bsp \
|
||||||
|
-I../common/EFM32GG_STK3700/config
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Files #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_SRC += \
|
||||||
|
../common/EFM32GG/Source/system_efm32gg.c \
|
||||||
|
../common/EFM32/drivers/vddcheck.c \
|
||||||
|
../common/EFM32/drivers/segmentlcd.c \
|
||||||
|
../common/emlib/src/em_assert.c \
|
||||||
|
../common/emlib/src/em_cmu.c \
|
||||||
|
../common/emlib/src/em_emu.c \
|
||||||
|
../common/emlib/src/em_gpio.c \
|
||||||
|
../common/emlib/src/em_rtc.c \
|
||||||
|
../common/emlib/src/em_system.c \
|
||||||
|
../common/emlib/src/em_lcd.c \
|
||||||
|
../common/emlib/src/em_vcmp.c \
|
||||||
|
../common/emlib/src/em_usart.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk_leds.c \
|
||||||
|
../common/EFM32/bsp/bsp_trace.c \
|
||||||
|
../common/$(PROJECTNAME)/init.c
|
||||||
|
|
||||||
|
s_SRC += \
|
||||||
|
../common/EFM32GG/Source/GCC/startup_efm32gg.s
|
||||||
|
|
||||||
|
STUDENT_SRC += \
|
||||||
|
$(PROJECTNAME).s \
|
||||||
|
gpio_constants.s \
|
||||||
|
sys-tick_constants.s
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Rules #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_FILES = $(notdir $(C_SRC) )
|
||||||
|
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
|
||||||
|
#make list of source paths, sort also removes duplicates
|
||||||
|
C_PATHS = $(sort $(dir $(C_SRC) ) )
|
||||||
|
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
|
||||||
|
|
||||||
|
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
|
||||||
|
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
|
||||||
|
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
|
||||||
|
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
|
||||||
|
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
|
||||||
|
STUDENT_OBJS = $(addprefix $(OBJ_DIR)/, $(STUDENT_SRC:.s=.o))
|
||||||
|
|
||||||
|
vpath %.c $(C_PATHS)
|
||||||
|
vpath %.s $(S_PATHS)
|
||||||
|
vpath %.S $(S_PATHS)
|
||||||
|
|
||||||
|
|
||||||
|
# Default build is debug build
|
||||||
|
all: debug
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -O0 -g3
|
||||||
|
debug: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
release: CFLAGS += -DNDEBUG -O3 -g3
|
||||||
|
release: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
rammeverk: $(OBJS)
|
||||||
|
|
||||||
|
# Create objects from C SRC files
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@echo "Building file: $<"
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Assemble .s/.S files
|
||||||
|
$(OBJ_DIR)/%.o: %.s
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.S
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Link
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).out: $(STUDENT_OBJS)
|
||||||
|
@echo "Linking target: $@"
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(STUDENT_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
|
||||||
|
# Create binary file
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
@echo "Creating binary file"
|
||||||
|
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
# Uncomment next line to produce assembly listing of entire program
|
||||||
|
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
|
||||||
|
|
||||||
|
# Flash on!
|
||||||
|
ifeq ($(f), 1)
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(RM) $(LST_DIR) $(EXE_DIR)
|
||||||
|
$(RM) $(STUDENT_OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# include auto-generated dependency files (explicit rules)
|
||||||
|
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
flash:
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
@echo "Completed!"
|
|
@ -0,0 +1,214 @@
|
||||||
|
####################################################################
|
||||||
|
# Makefile #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
.SUFFIXES: # ignore builtin rules
|
||||||
|
.PHONY: all debug release clean flash rammeverk
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# notdirx: version of notdir which allows spaces in path
|
||||||
|
s? = $(subst $(empty) ,?,$1)
|
||||||
|
?s = $(subst ?, ,$1)
|
||||||
|
notdirx = $(call ?s,$(notdir $(call s?,$1)))
|
||||||
|
|
||||||
|
DEVICE = EFM32GG990F1024
|
||||||
|
PROJECTNAME = $(call notdirx,$(CURDIR))
|
||||||
|
|
||||||
|
OBJ_DIR = build
|
||||||
|
EXE_DIR = exe
|
||||||
|
LST_DIR = lst
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions of toolchain. #
|
||||||
|
# You might need to do changes to match your system setup #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
NULLDEVICE := /dev/null
|
||||||
|
SHELLNAMES := $(ComSpec)$(COMSPEC)
|
||||||
|
|
||||||
|
CC := arm-none-eabi-gcc
|
||||||
|
LD := arm-none-eabi-ld
|
||||||
|
AR := arm-none-eabi-ar
|
||||||
|
OBJCOPY := arm-none-eabi-objcopy
|
||||||
|
DUMP := arm-none-eabi-objdump
|
||||||
|
|
||||||
|
# Detect operating system
|
||||||
|
ifeq ($(SHELLNAMES),) # Linux
|
||||||
|
EACOM = /opt/SimplicityStudio_v3/bgtool/commander/commander
|
||||||
|
else
|
||||||
|
EACOM = C:\SiliconLabs\SimplicityStudio\v3\bgtool\commander\commander.exe
|
||||||
|
ifneq ($(COMSPEC),) # mingw/msys/cygwin platform running on Windows
|
||||||
|
ifeq ($(findstring cygdrive,$(shell set)),)
|
||||||
|
# We were not on a cygwin platform
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
else # Windows
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Create directories and do a clean which is compatible with parallell make
|
||||||
|
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(shell $(RM) $(OBJ_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(EXE_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(LST_DIR)/*>$(NULLDEVICE) 2>&1) #*/
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Flags #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# -MMD : Don't generate dependencies on system header files.
|
||||||
|
# -MP : Add phony targets, useful when a h-file is removed from a project.
|
||||||
|
# -MF : Specify a file to write the dependencies to.
|
||||||
|
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
|
||||||
|
#
|
||||||
|
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb -ffunction-sections \
|
||||||
|
-fdata-sections -mfix-cortex-m3-ldrd -fomit-frame-pointer -DDEBUG_EFM \
|
||||||
|
-O0 \
|
||||||
|
$(DEPFLAGS)
|
||||||
|
|
||||||
|
ASMFLAGS += -x assembler-with-cpp -mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
|
||||||
|
#
|
||||||
|
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
|
||||||
|
-mthumb -Tefm32gg.ld --specs=nano.specs \
|
||||||
|
-Wl,--gc-sections
|
||||||
|
|
||||||
|
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||||
|
|
||||||
|
INCLUDEPATHS += \
|
||||||
|
-I.. \
|
||||||
|
-I../common/CMSIS/Include \
|
||||||
|
-I../common/EFM32GG/Include \
|
||||||
|
-I../common/emlib/inc \
|
||||||
|
-I../common/EFM32/drivers \
|
||||||
|
-I../common/EFM32/bsp \
|
||||||
|
-I../common/EFM32GG_STK3700/config
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Files #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_SRC += \
|
||||||
|
../common/EFM32GG/Source/system_efm32gg.c \
|
||||||
|
../common/EFM32/drivers/vddcheck.c \
|
||||||
|
../common/EFM32/drivers/segmentlcd.c \
|
||||||
|
../common/emlib/src/em_assert.c \
|
||||||
|
../common/emlib/src/em_cmu.c \
|
||||||
|
../common/emlib/src/em_emu.c \
|
||||||
|
../common/emlib/src/em_gpio.c \
|
||||||
|
../common/emlib/src/em_rtc.c \
|
||||||
|
../common/emlib/src/em_system.c \
|
||||||
|
../common/emlib/src/em_lcd.c \
|
||||||
|
../common/emlib/src/em_vcmp.c \
|
||||||
|
../common/emlib/src/em_usart.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk_leds.c \
|
||||||
|
../common/EFM32/bsp/bsp_trace.c \
|
||||||
|
../common/$(PROJECTNAME)/init.c
|
||||||
|
|
||||||
|
s_SRC += \
|
||||||
|
../common/EFM32GG/Source/GCC/startup_efm32gg.s
|
||||||
|
|
||||||
|
STUDENT_SRC += \
|
||||||
|
$(PROJECTNAME).s \
|
||||||
|
gpio_constants.s \
|
||||||
|
sys-tick_constants.s
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Rules #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_FILES = $(notdir $(C_SRC) )
|
||||||
|
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
|
||||||
|
#make list of source paths, sort also removes duplicates
|
||||||
|
C_PATHS = $(sort $(dir $(C_SRC) ) )
|
||||||
|
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
|
||||||
|
|
||||||
|
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
|
||||||
|
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
|
||||||
|
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
|
||||||
|
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
|
||||||
|
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
|
||||||
|
STUDENT_OBJS = $(addprefix $(OBJ_DIR)/, $(STUDENT_SRC:.s=.o))
|
||||||
|
|
||||||
|
vpath %.c $(C_PATHS)
|
||||||
|
vpath %.s $(S_PATHS)
|
||||||
|
vpath %.S $(S_PATHS)
|
||||||
|
|
||||||
|
|
||||||
|
# Default build is debug build
|
||||||
|
all: debug
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -O0 -g3
|
||||||
|
debug: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
release: CFLAGS += -DNDEBUG -O3 -g3
|
||||||
|
release: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
rammeverk: $(OBJS)
|
||||||
|
|
||||||
|
# Create objects from C SRC files
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@echo "Building file: $<"
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Assemble .s/.S files
|
||||||
|
$(OBJ_DIR)/%.o: %.s
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.S
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Link
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).out: $(STUDENT_OBJS)
|
||||||
|
@echo "Linking target: $@"
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(STUDENT_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
|
||||||
|
# Create binary file
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
@echo "Creating binary file"
|
||||||
|
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
# Uncomment next line to produce assembly listing of entire program
|
||||||
|
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
|
||||||
|
|
||||||
|
# Flash on!
|
||||||
|
ifeq ($(f), 1)
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(RM) $(LST_DIR) $(EXE_DIR)
|
||||||
|
$(RM) $(STUDENT_OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# include auto-generated dependency files (explicit rules)
|
||||||
|
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
flash:
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
@echo "Completed!"
|
|
@ -0,0 +1,207 @@
|
||||||
|
/* Linker script for Silicon Labs EFM32GG devices */
|
||||||
|
/* */
|
||||||
|
/* This file is subject to the license terms as defined in ARM's */
|
||||||
|
/* CMSIS END USER LICENSE AGREEMENT.pdf, governing the use of */
|
||||||
|
/* Example Code. */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2018 Silicon Laboratories, Inc. http://www.silabs.com */
|
||||||
|
/* */
|
||||||
|
/* Version 5.5.0 */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1048576
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 131072
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_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
|
||||||
|
* __Vectors_End
|
||||||
|
* __Vectors_Size
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
__Vectors_End = .;
|
||||||
|
__Vectors_Size = __Vectors_End - __Vectors;
|
||||||
|
__end__ = .;
|
||||||
|
|
||||||
|
*(.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 = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN (4);
|
||||||
|
*(.ram)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__HeapBase = .;
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
_end = __end__;
|
||||||
|
KEEP(*(.heap*))
|
||||||
|
__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 (COPY):
|
||||||
|
{
|
||||||
|
KEEP(*(.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")
|
||||||
|
|
||||||
|
/* Check if FLASH usage exceeds FLASH size */
|
||||||
|
ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
// GPIO base-adresse
|
||||||
|
GPIO_BASE = 0x40006000
|
||||||
|
|
||||||
|
// --- [Offset til GPIO-registrene]----------------------------------------- //
|
||||||
|
// --- [Offset til portregistrene ] ------------------------------- //
|
||||||
|
GPIO_PORT_CTRL = 0 // Port Control Register
|
||||||
|
GPIO_PORT_MODEL = 4 // Port Pin Mode Low Register
|
||||||
|
GPIO_PORT_MODEH = 8 // Port Pin Mode High Register
|
||||||
|
GPIO_PORT_DOUT = 12 // Port Data Out Register
|
||||||
|
GPIO_PORT_DOUTSET = 16 // Port Data Out Set Register
|
||||||
|
GPIO_PORT_DOUTCLR = 20 // Port Data Out Clear Register
|
||||||
|
GPIO_PORT_DOUTTGL = 24 // Port Data Out Toggle Register
|
||||||
|
GPIO_PORT_DIN = 28 // Port Data In Register
|
||||||
|
GPIO_PORT_PINLOCKN = 32 // Port Unlocked Pins Register
|
||||||
|
// ---------------------------------------------------------------- //
|
||||||
|
|
||||||
|
GPIO_EXTIPSELL = 256 // External Interrupt Port Select Low Register
|
||||||
|
GPIO_EXTIPSELH = 260 // External Interrupt Port Select High Register
|
||||||
|
GPIO_EXTIRISE = 264 // External Interrupt Rising Edge Trigger Register
|
||||||
|
GPIO_EXTIFALL = 268 // External Interrupt Falling Edge Trigger Register
|
||||||
|
GPIO_IEN = 272 // Interrupt Enable Register
|
||||||
|
GPIO_IF = 276 // Interrupt Flag Register
|
||||||
|
GPIO_IFS = 280 // Interrupt Flag Set Register
|
||||||
|
GPIO_IFC = 284 // Interrupt Flag Clear Register
|
||||||
|
|
||||||
|
GPIO_ROUTE = 288 // I/O Routing Register
|
||||||
|
GPIO_INSENSE = 292 // Input Sense Register
|
||||||
|
GPIO_LOCK = 296 // Configuration Lock Register
|
||||||
|
GPIO_CTRL = 300 // GPIO Control Register
|
||||||
|
GPIO_CMD = 304 // EM4 Wake-up Clear Register
|
||||||
|
GPIO_EM4WUEN = 308 // EM4 Wake-up Enable Register
|
||||||
|
GPIO_EM4WUPOL = 312 // EM4 Wake-up Polarity Register
|
||||||
|
GPIO_EM4WUCAUSE = 316 // EM4 Wake-up Cause Register
|
||||||
|
// ------------------------------------------------------------------------- //
|
||||||
|
|
||||||
|
// --- [Hjelpekonstanter til GPIO]------------------------------------------ //
|
||||||
|
// Porter
|
||||||
|
PORT_A = 0
|
||||||
|
PORT_B = 1
|
||||||
|
PORT_C = 2
|
||||||
|
PORT_D = 3
|
||||||
|
PORT_E = 4
|
||||||
|
PORT_F = 5
|
||||||
|
|
||||||
|
NUMBER_OF_PORTS = 6 // Antall porter
|
||||||
|
PORT_SIZE = 36 // Antall bytes i et sett med portregistre
|
||||||
|
|
||||||
|
// Enheter på kitet
|
||||||
|
LED_PORT = PORT_E
|
||||||
|
LED_PIN = 2
|
||||||
|
BUTTON_PORT = PORT_B
|
||||||
|
BUTTON_PIN = 9
|
||||||
|
// ------------------------------------------------------------------------- //
|
|
@ -0,0 +1,110 @@
|
||||||
|
.thumb
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.include "gpio_constants.s" // Register-adresser og konstanter for GPIO
|
||||||
|
.include "sys-tick_constants.s" // Register-adresser og konstanter for SysTick
|
||||||
|
|
||||||
|
.text
|
||||||
|
.global Start
|
||||||
|
|
||||||
|
TENTH_SECOND_FREQUENCY = FREQUENCY / 10
|
||||||
|
|
||||||
|
SYSTICK_LOAD_BASE = SYSTICK_BASE + SYSTICK_LOAD
|
||||||
|
SYSTICK_VAL_BASE = SYSTICK_BASE + SYSTICK_VAL
|
||||||
|
SYSTICK_CTRL_BASE = SYSTICK_BASE + SYSTICK_CTRL
|
||||||
|
|
||||||
|
GPIO_EXTIPSELH_BASE = GPIO_BASE + GPIO_EXTIPSELH
|
||||||
|
GPIO_EXTIFALL_BASE = GPIO_BASE + GPIO_EXTIFALL
|
||||||
|
GPIO_IEN_BASE = GPIO_BASE + GPIO_IEN
|
||||||
|
GPIO_IFC_BASE = GPIO_BASE + GPIO_IFC
|
||||||
|
GPIO_LED_BASE = GPIO_BASE + (LED_PORT * PORT_SIZE) + GPIO_PORT_DOUTTGL
|
||||||
|
|
||||||
|
Start:
|
||||||
|
|
||||||
|
LDR R0, =TENTH_SECOND_FREQUENCY
|
||||||
|
LDR R1, =SYSTICK_CTRL_BASE
|
||||||
|
LDR R2, =SYSTICK_LOAD_BASE
|
||||||
|
LDR R3, =SYSTICK_VAL_BASE
|
||||||
|
|
||||||
|
MOV R4, #0b110
|
||||||
|
STR R4, [R1]
|
||||||
|
|
||||||
|
LDR R4, =TENTH_SECOND_FREQUENCY
|
||||||
|
STR R4, [R2]
|
||||||
|
|
||||||
|
MOV R4, #1
|
||||||
|
STR R4, [R3]
|
||||||
|
|
||||||
|
LDR R0, =GPIO_EXTIPSELH_BASE
|
||||||
|
LDR R1, [R0] // 0b xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
|
||||||
|
BFI R1, R4, #4, #4 // 0b xxxx xxxx xxxx xxxx xxxx xxxx 0001 xxxx
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
LDR R0, =GPIO_EXTIFALL_BASE
|
||||||
|
LDR R1, [R0]
|
||||||
|
ORR R1, 1 << BUTTON_PIN
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
LDR R0, =GPIO_IEN_BASE
|
||||||
|
LDR R1, [R0]
|
||||||
|
ORR R1, 1 << BUTTON_PIN
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
Loop:
|
||||||
|
WFI
|
||||||
|
B Loop
|
||||||
|
|
||||||
|
.global SysTick_Handler
|
||||||
|
.thumb_func
|
||||||
|
SysTick_Handler:
|
||||||
|
|
||||||
|
LDR R0, =tenths
|
||||||
|
LDR R1, =seconds
|
||||||
|
LDR R2, =minutes
|
||||||
|
LDR R10, [R0]
|
||||||
|
LDR R11, [R1]
|
||||||
|
LDR R12, [R2]
|
||||||
|
|
||||||
|
// Tenth
|
||||||
|
ADD R10, #1
|
||||||
|
CMP R10, #10
|
||||||
|
BNE SysTick_Update
|
||||||
|
MOV R10, 0
|
||||||
|
|
||||||
|
// LED
|
||||||
|
LDR R3, =GPIO_LED_BASE
|
||||||
|
LDR R4, =1<<LED_PIN
|
||||||
|
STR R4, [R3]
|
||||||
|
|
||||||
|
// Second
|
||||||
|
ADD R11, #1
|
||||||
|
CMP R11, #60
|
||||||
|
BNE SysTick_Update
|
||||||
|
MOV R11, 0
|
||||||
|
|
||||||
|
// Minute
|
||||||
|
ADD R12, #1
|
||||||
|
|
||||||
|
SysTick_Update:
|
||||||
|
STR R10, [R0]
|
||||||
|
STR R11, [R1]
|
||||||
|
STR R12, [R2]
|
||||||
|
BX LR
|
||||||
|
|
||||||
|
.global GPIO_ODD_IRQHandler
|
||||||
|
.thumb_func
|
||||||
|
GPIO_ODD_IRQHandler:
|
||||||
|
|
||||||
|
LDR R0, =SYSTICK_CTRL_BASE
|
||||||
|
LDR R1, [R0]
|
||||||
|
EOR R1, #1
|
||||||
|
STR R1, [R0]
|
||||||
|
|
||||||
|
LDR R2, =GPIO_IFC_BASE
|
||||||
|
MOV R3, 1 << BUTTON_PIN
|
||||||
|
STR R3, [R2]
|
||||||
|
|
||||||
|
BX LR
|
||||||
|
|
||||||
|
|
||||||
|
NOP
|
|
@ -0,0 +1,19 @@
|
||||||
|
// SysTick Base-addresse
|
||||||
|
SYSTICK_BASE = 0xE000E010
|
||||||
|
|
||||||
|
// ---[ Offset til sys-tick-registrene ]------------------------ //
|
||||||
|
SYSTICK_CTRL = 0 // SysTick Control and Status Register
|
||||||
|
SYSTICK_LOAD = 4 // SysTick Reload Value Register
|
||||||
|
SYSTICK_VAL = 8 // SysTick Current Value Register
|
||||||
|
SYSTICK_CALIB = 12 // SysTick Calibration Register
|
||||||
|
// ------------------------------------------------------------- //
|
||||||
|
|
||||||
|
|
||||||
|
// ---[ Hjelpekonstanter til sys-tick ]------------------------- //
|
||||||
|
FREQUENCY = 14000000 // Antall klokkesignaler per sekund
|
||||||
|
|
||||||
|
// CTRL-register-masker
|
||||||
|
SysTick_CTRL_CLKSOURCE_Msk = 0b100
|
||||||
|
SysTick_CTRL_TICKINT_Msk = 0b010
|
||||||
|
SysTick_CTRL_ENABLE_Msk = 0b001
|
||||||
|
// ------------------------------------------------------------- //
|
|
@ -0,0 +1,214 @@
|
||||||
|
####################################################################
|
||||||
|
# Makefile #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
.SUFFIXES: # ignore builtin rules
|
||||||
|
.PHONY: all debug release clean flash rammeverk
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# notdirx: version of notdir which allows spaces in path
|
||||||
|
s? = $(subst $(empty) ,?,$1)
|
||||||
|
?s = $(subst ?, ,$1)
|
||||||
|
notdirx = $(call ?s,$(notdir $(call s?,$1)))
|
||||||
|
|
||||||
|
DEVICE = EFM32GG990F1024
|
||||||
|
PROJECTNAME = $(call notdirx,$(CURDIR))
|
||||||
|
|
||||||
|
OBJ_DIR = build
|
||||||
|
EXE_DIR = exe
|
||||||
|
LST_DIR = lst
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions of toolchain. #
|
||||||
|
# You might need to do changes to match your system setup #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
NULLDEVICE := /dev/null
|
||||||
|
SHELLNAMES := $(ComSpec)$(COMSPEC)
|
||||||
|
|
||||||
|
# This is only valid for my specific system.
|
||||||
|
TOOLCHAIN_BIN_DIR := /opt/simplicitystudio5/developer/toolchains/gnu_arm/10.2_2020q4/bin
|
||||||
|
|
||||||
|
CC := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-gcc
|
||||||
|
LD := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-ld
|
||||||
|
AR := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-ar
|
||||||
|
OBJCOPY := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-objcopy
|
||||||
|
DUMP := $(TOOLCHAIN_BIN_DIR)/arm-none-eabi-objdump
|
||||||
|
|
||||||
|
# Detect operating system
|
||||||
|
ifeq ($(SHELLNAMES),) # Linux
|
||||||
|
EACOM = /opt/simplicitystudio5/developer/adapter_packs/commander/commander
|
||||||
|
else
|
||||||
|
EACOM = C:\SiliconLabs\SimplicityStudio\v3\bgtool\commander\commander.exe
|
||||||
|
ifneq ($(COMSPEC),) # mingw/msys/cygwin platform running on Windows
|
||||||
|
ifeq ($(findstring cygdrive,$(shell set)),)
|
||||||
|
# We were not on a cygwin platform
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
else # Windows
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Create directories and do a clean which is compatible with parallell make
|
||||||
|
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(shell $(RM) $(OBJ_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(EXE_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(LST_DIR)/*>$(NULLDEVICE) 2>&1) #*/
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Flags #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# -MMD : Don't generate dependencies on system header files.
|
||||||
|
# -MP : Add phony targets, useful when a h-file is removed from a project.
|
||||||
|
# -MF : Specify a file to write the dependencies to.
|
||||||
|
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
|
||||||
|
#
|
||||||
|
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb -ffunction-sections \
|
||||||
|
-fdata-sections -mfix-cortex-m3-ldrd -fomit-frame-pointer -DDEBUG_EFM \
|
||||||
|
-O0 \
|
||||||
|
$(DEPFLAGS)
|
||||||
|
|
||||||
|
ASMFLAGS += -x assembler-with-cpp -mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
|
||||||
|
#
|
||||||
|
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
|
||||||
|
-mthumb -Tefm32gg.ld --specs=nano.specs \
|
||||||
|
-Wl,--gc-sections
|
||||||
|
|
||||||
|
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||||
|
|
||||||
|
INCLUDEPATHS += \
|
||||||
|
-I.. \
|
||||||
|
-I../common/CMSIS/Include \
|
||||||
|
-I../common/EFM32GG/Include \
|
||||||
|
-I../common/emlib/inc \
|
||||||
|
-I../common/EFM32/drivers \
|
||||||
|
-I../common/EFM32/bsp \
|
||||||
|
-I../common/EFM32GG_STK3700/config
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Files #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_SRC += \
|
||||||
|
../common/EFM32GG/Source/system_efm32gg.c \
|
||||||
|
../common/EFM32/drivers/vddcheck.c \
|
||||||
|
../common/EFM32/drivers/segmentlcd.c \
|
||||||
|
../common/emlib/src/em_assert.c \
|
||||||
|
../common/emlib/src/em_cmu.c \
|
||||||
|
../common/emlib/src/em_emu.c \
|
||||||
|
../common/emlib/src/em_gpio.c \
|
||||||
|
../common/emlib/src/em_rtc.c \
|
||||||
|
../common/emlib/src/em_system.c \
|
||||||
|
../common/emlib/src/em_lcd.c \
|
||||||
|
../common/emlib/src/em_vcmp.c \
|
||||||
|
../common/emlib/src/em_usart.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk_leds.c \
|
||||||
|
../common/EFM32/bsp/bsp_trace.c \
|
||||||
|
../common/$(PROJECTNAME)/init.c
|
||||||
|
|
||||||
|
s_SRC += \
|
||||||
|
../common/EFM32GG/Source/GCC/startup_efm32gg.s
|
||||||
|
|
||||||
|
STUDENT_SRC += \
|
||||||
|
$(PROJECTNAME).s
|
||||||
|
# gpio_constants.s \
|
||||||
|
# sys-tick_constants.s
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Rules #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_FILES = $(notdir $(C_SRC) )
|
||||||
|
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
|
||||||
|
#make list of source paths, sort also removes duplicates
|
||||||
|
C_PATHS = $(sort $(dir $(C_SRC) ) )
|
||||||
|
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
|
||||||
|
|
||||||
|
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
|
||||||
|
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
|
||||||
|
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
|
||||||
|
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
|
||||||
|
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
|
||||||
|
STUDENT_OBJS = $(addprefix $(OBJ_DIR)/, $(STUDENT_SRC:.s=.o))
|
||||||
|
|
||||||
|
vpath %.c $(C_PATHS)
|
||||||
|
vpath %.s $(S_PATHS)
|
||||||
|
vpath %.S $(S_PATHS)
|
||||||
|
|
||||||
|
|
||||||
|
# Default build is debug build
|
||||||
|
all: debug
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -O0 -g3
|
||||||
|
debug: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
release: CFLAGS += -DNDEBUG -O3 -g3
|
||||||
|
release: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
rammeverk: $(OBJS)
|
||||||
|
|
||||||
|
# Create objects from C SRC files
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@echo "Building file: $<"
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Assemble .s/.S files
|
||||||
|
$(OBJ_DIR)/%.o: %.s
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.S
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Link
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).out: $(STUDENT_OBJS)
|
||||||
|
@echo "Linking target: $@"
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(STUDENT_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
|
||||||
|
# Create binary file
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
@echo "Creating binary file"
|
||||||
|
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
# Uncomment next line to produce assembly listing of entire program
|
||||||
|
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
|
||||||
|
|
||||||
|
# Flash on!
|
||||||
|
ifeq ($(f), 1)
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(RM) $(LST_DIR) $(EXE_DIR)
|
||||||
|
$(RM) $(STUDENT_OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# include auto-generated dependency files (explicit rules)
|
||||||
|
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
flash:
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
@echo "Completed!"
|
|
@ -0,0 +1,212 @@
|
||||||
|
####################################################################
|
||||||
|
# Makefile #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
.SUFFIXES: # ignore builtin rules
|
||||||
|
.PHONY: all debug release clean flash rammeverk
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# notdirx: version of notdir which allows spaces in path
|
||||||
|
s? = $(subst $(empty) ,?,$1)
|
||||||
|
?s = $(subst ?, ,$1)
|
||||||
|
notdirx = $(call ?s,$(notdir $(call s?,$1)))
|
||||||
|
|
||||||
|
DEVICE = EFM32GG990F1024
|
||||||
|
PROJECTNAME = $(call notdirx,$(CURDIR))
|
||||||
|
|
||||||
|
OBJ_DIR = build
|
||||||
|
EXE_DIR = exe
|
||||||
|
LST_DIR = lst
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Definitions of toolchain. #
|
||||||
|
# You might need to do changes to match your system setup #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
RM := rm -rf
|
||||||
|
NULLDEVICE := /dev/null
|
||||||
|
SHELLNAMES := $(ComSpec)$(COMSPEC)
|
||||||
|
|
||||||
|
CC := arm-none-eabi-gcc
|
||||||
|
LD := arm-none-eabi-ld
|
||||||
|
AR := arm-none-eabi-ar
|
||||||
|
OBJCOPY := arm-none-eabi-objcopy
|
||||||
|
DUMP := arm-none-eabi-objdump
|
||||||
|
|
||||||
|
# Detect operating system
|
||||||
|
ifeq ($(SHELLNAMES),) # Linux
|
||||||
|
EACOM = /opt/SimplicityStudio_v3/bgtool/commander/commander
|
||||||
|
else
|
||||||
|
EACOM = C:\SiliconLabs\SimplicityStudio\v3\bgtool\commander\commander.exe
|
||||||
|
ifneq ($(COMSPEC),) # mingw/msys/cygwin platform running on Windows
|
||||||
|
ifeq ($(findstring cygdrive,$(shell set)),)
|
||||||
|
# We were not on a cygwin platform
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
else # Windows
|
||||||
|
NULLDEVICE := NUL
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Create directories and do a clean which is compatible with parallell make
|
||||||
|
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
|
||||||
|
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(shell $(RM) $(OBJ_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(EXE_DIR)/*>$(NULLDEVICE) 2>&1)
|
||||||
|
$(shell $(RM) $(LST_DIR)/*>$(NULLDEVICE) 2>&1) #*/
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Flags #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
# -MMD : Don't generate dependencies on system header files.
|
||||||
|
# -MP : Add phony targets, useful when a h-file is removed from a project.
|
||||||
|
# -MF : Specify a file to write the dependencies to.
|
||||||
|
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
|
||||||
|
#
|
||||||
|
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb -ffunction-sections \
|
||||||
|
-fdata-sections -mfix-cortex-m3-ldrd -fomit-frame-pointer -DDEBUG_EFM \
|
||||||
|
-O0 \
|
||||||
|
$(DEPFLAGS)
|
||||||
|
|
||||||
|
ASMFLAGS += -x assembler-with-cpp -mcpu=cortex-m3 -mthumb
|
||||||
|
|
||||||
|
#
|
||||||
|
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
|
||||||
|
#
|
||||||
|
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
|
||||||
|
-mthumb -Tefm32gg.ld --specs=nano.specs \
|
||||||
|
-Wl,--gc-sections
|
||||||
|
|
||||||
|
LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||||
|
|
||||||
|
INCLUDEPATHS += \
|
||||||
|
-I.. \
|
||||||
|
-I../common/CMSIS/Include \
|
||||||
|
-I../common/EFM32GG/Include \
|
||||||
|
-I../common/emlib/inc \
|
||||||
|
-I../common/EFM32/drivers \
|
||||||
|
-I../common/EFM32/bsp \
|
||||||
|
-I../common/EFM32GG_STK3700/config
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Files #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_SRC += \
|
||||||
|
../common/EFM32GG/Source/system_efm32gg.c \
|
||||||
|
../common/EFM32/drivers/vddcheck.c \
|
||||||
|
../common/EFM32/drivers/segmentlcd.c \
|
||||||
|
../common/emlib/src/em_assert.c \
|
||||||
|
../common/emlib/src/em_cmu.c \
|
||||||
|
../common/emlib/src/em_emu.c \
|
||||||
|
../common/emlib/src/em_gpio.c \
|
||||||
|
../common/emlib/src/em_rtc.c \
|
||||||
|
../common/emlib/src/em_system.c \
|
||||||
|
../common/emlib/src/em_lcd.c \
|
||||||
|
../common/emlib/src/em_vcmp.c \
|
||||||
|
../common/emlib/src/em_usart.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk.c \
|
||||||
|
../common/EFM32/bsp/bsp_stk_leds.c \
|
||||||
|
../common/EFM32/bsp/bsp_trace.c \
|
||||||
|
../common/$(PROJECTNAME)/init.c
|
||||||
|
|
||||||
|
s_SRC += \
|
||||||
|
../common/EFM32GG/Source/GCC/startup_efm32gg.s
|
||||||
|
|
||||||
|
STUDENT_SRC += \
|
||||||
|
$(PROJECTNAME).c
|
||||||
|
|
||||||
|
####################################################################
|
||||||
|
# Rules #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
C_FILES = $(notdir $(C_SRC) )
|
||||||
|
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
|
||||||
|
#make list of source paths, sort also removes duplicates
|
||||||
|
C_PATHS = $(sort $(dir $(C_SRC) ) )
|
||||||
|
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )
|
||||||
|
|
||||||
|
C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
|
||||||
|
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
|
||||||
|
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
|
||||||
|
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
|
||||||
|
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)
|
||||||
|
STUDENT_OBJS = $(addprefix $(OBJ_DIR)/, $(STUDENT_SRC:.c=.o))
|
||||||
|
|
||||||
|
vpath %.c $(C_PATHS)
|
||||||
|
vpath %.s $(S_PATHS)
|
||||||
|
vpath %.S $(S_PATHS)
|
||||||
|
|
||||||
|
|
||||||
|
# Default build is debug build
|
||||||
|
all: debug
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -O0 -g3
|
||||||
|
debug: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
release: CFLAGS += -DNDEBUG -O3 -g3
|
||||||
|
release: $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
|
||||||
|
rammeverk: $(OBJS)
|
||||||
|
|
||||||
|
# Create objects from C SRC files
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@echo "Building file: $<"
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Assemble .s/.S files
|
||||||
|
$(OBJ_DIR)/%.o: %.s
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.S
|
||||||
|
@echo "Assembling $<"
|
||||||
|
$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<
|
||||||
|
|
||||||
|
# Link
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).out: $(STUDENT_OBJS)
|
||||||
|
@echo "Linking target: $@"
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(STUDENT_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
|
||||||
|
# Create binary file
|
||||||
|
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
|
||||||
|
@echo "Creating binary file"
|
||||||
|
$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
# Uncomment next line to produce assembly listing of entire program
|
||||||
|
# $(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
|
||||||
|
|
||||||
|
# Flash on!
|
||||||
|
ifeq ($(f), 1)
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
endif
|
||||||
|
|
||||||
|
clean:
|
||||||
|
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
|
||||||
|
$(RM) $(LST_DIR) $(EXE_DIR)
|
||||||
|
$(RM) $(STUDENT_OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# include auto-generated dependency files (explicit rules)
|
||||||
|
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
|
||||||
|
-include $(C_DEPS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
flash:
|
||||||
|
$(EACOM) flash $(EXE_DIR)/$(PROJECTNAME).bin
|
||||||
|
@echo "Completed!"
|
|
@ -0,0 +1,207 @@
|
||||||
|
/* Linker script for Silicon Labs EFM32GG devices */
|
||||||
|
/* */
|
||||||
|
/* This file is subject to the license terms as defined in ARM's */
|
||||||
|
/* CMSIS END USER LICENSE AGREEMENT.pdf, governing the use of */
|
||||||
|
/* Example Code. */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2018 Silicon Laboratories, Inc. http://www.silabs.com */
|
||||||
|
/* */
|
||||||
|
/* Version 5.5.0 */
|
||||||
|
/* */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1048576
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 131072
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* __copy_table_start__
|
||||||
|
* __copy_table_end__
|
||||||
|
* __zero_table_start__
|
||||||
|
* __zero_table_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
|
||||||
|
* __Vectors_End
|
||||||
|
* __Vectors_Size
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
__Vectors_End = .;
|
||||||
|
__Vectors_Size = __Vectors_End - __Vectors;
|
||||||
|
__end__ = .;
|
||||||
|
|
||||||
|
*(.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 = .;
|
||||||
|
|
||||||
|
/* To copy multiple ROM to RAM sections,
|
||||||
|
* uncomment .copy.table section and,
|
||||||
|
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.copy.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__copy_table_start__ = .;
|
||||||
|
LONG (__etext)
|
||||||
|
LONG (__data_start__)
|
||||||
|
LONG (__data_end__ - __data_start__)
|
||||||
|
LONG (__etext2)
|
||||||
|
LONG (__data2_start__)
|
||||||
|
LONG (__data2_end__ - __data2_start__)
|
||||||
|
__copy_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* To clear multiple BSS sections,
|
||||||
|
* uncomment .zero.table section and,
|
||||||
|
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||||
|
/*
|
||||||
|
.zero.table :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__zero_table_start__ = .;
|
||||||
|
LONG (__bss_start__)
|
||||||
|
LONG (__bss_end__ - __bss_start__)
|
||||||
|
LONG (__bss2_start__)
|
||||||
|
LONG (__bss2_end__ - __bss2_start__)
|
||||||
|
__zero_table_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN (4);
|
||||||
|
*(.ram)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
KEEP(*(.jcr*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__HeapBase = .;
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
_end = __end__;
|
||||||
|
KEEP(*(.heap*))
|
||||||
|
__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 (COPY):
|
||||||
|
{
|
||||||
|
KEEP(*(.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")
|
||||||
|
|
||||||
|
/* Check if FLASH usage exceeds FLASH size */
|
||||||
|
ASSERT( LENGTH(FLASH) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef GPIO_H
|
||||||
|
#define GPIO_H
|
||||||
|
|
||||||
|
// Pin-datatype
|
||||||
|
typedef struct{
|
||||||
|
unsigned int port;
|
||||||
|
unsigned int pin;
|
||||||
|
} port_pin_t;
|
||||||
|
|
||||||
|
// GPIO pin modes
|
||||||
|
#define GPIO_MODE_INPUT 0b0001
|
||||||
|
#define GPIO_MODE_OUTPUT 0b0100
|
||||||
|
|
||||||
|
// GPIO-adresse
|
||||||
|
#define GPIO_BASE 0x40006000
|
||||||
|
|
||||||
|
// GPIO port-nummere
|
||||||
|
#define GPIO_PORT_A 0
|
||||||
|
#define GPIO_PORT_B 1
|
||||||
|
#define GPIO_PORT_C 2
|
||||||
|
#define GPIO_PORT_D 3
|
||||||
|
#define GPIO_PORT_E 4
|
||||||
|
#define GPIO_PORT_F 5
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,252 @@
|
||||||
|
#include "o3.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "systick.h"
|
||||||
|
|
||||||
|
/**************************************************************************/ /**
|
||||||
|
* @brief Konverterer nummer til string
|
||||||
|
* Konverterer et nummer mellom 0 og 99 til string
|
||||||
|
*****************************************************************************/
|
||||||
|
void int_to_string(char *timestamp, unsigned int offset, int i)
|
||||||
|
{
|
||||||
|
if (i > 99)
|
||||||
|
{
|
||||||
|
timestamp[offset] = '9';
|
||||||
|
timestamp[offset + 1] = '9';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i > 0)
|
||||||
|
{
|
||||||
|
if (i >= 10)
|
||||||
|
{
|
||||||
|
i -= 10;
|
||||||
|
timestamp[offset]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timestamp[offset + 1] = '0' + i;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/ /**
|
||||||
|
* @brief Konverterer 3 tall til en timestamp-string
|
||||||
|
* timestamp-argumentet må være et array med plass til (minst) 7 elementer.
|
||||||
|
* Det kan deklareres i funksjonen som kaller som "char timestamp[7];"
|
||||||
|
* Kallet blir dermed:
|
||||||
|
* char timestamp[7];
|
||||||
|
* time_to_string(timestamp, h, m, s);
|
||||||
|
*****************************************************************************/
|
||||||
|
void time_to_string(char *timestamp, int h, int m, int s)
|
||||||
|
{
|
||||||
|
timestamp[0] = '0';
|
||||||
|
timestamp[1] = '0';
|
||||||
|
timestamp[2] = '0';
|
||||||
|
timestamp[3] = '0';
|
||||||
|
timestamp[4] = '0';
|
||||||
|
timestamp[5] = '0';
|
||||||
|
timestamp[6] = '\0';
|
||||||
|
|
||||||
|
int_to_string(timestamp, 0, h);
|
||||||
|
int_to_string(timestamp, 2, m);
|
||||||
|
int_to_string(timestamp, 4, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
word CTRL;
|
||||||
|
word MODEL;
|
||||||
|
word MODEH;
|
||||||
|
word DOUT;
|
||||||
|
word DOUTSET;
|
||||||
|
word DOUTCLR;
|
||||||
|
word DOUTTGL;
|
||||||
|
word DIN;
|
||||||
|
word PINLOCKN;
|
||||||
|
} gpio_port_map_t;
|
||||||
|
|
||||||
|
typedef volatile struct {
|
||||||
|
gpio_port_map_t ports[6];
|
||||||
|
word unused_space[10];
|
||||||
|
word EXTIPSELL;
|
||||||
|
word EXTIPSELH;
|
||||||
|
word EXTIRISE;
|
||||||
|
word EXTIFALL;
|
||||||
|
word IEN;
|
||||||
|
word IF;
|
||||||
|
word IFS;
|
||||||
|
word IFC;
|
||||||
|
word ROUTE;
|
||||||
|
word INSENSE;
|
||||||
|
word LOCK;
|
||||||
|
word CTRL;
|
||||||
|
word CMD;
|
||||||
|
word EM4WUEN;
|
||||||
|
word EM4WUPOL;
|
||||||
|
word EM4WUCAUSE;
|
||||||
|
} gpio_t;
|
||||||
|
|
||||||
|
typedef volatile struct {
|
||||||
|
word CTRL;
|
||||||
|
word LOAD;
|
||||||
|
word VAL;
|
||||||
|
word CALIB;
|
||||||
|
} systick_t;
|
||||||
|
|
||||||
|
static volatile gpio_t* const gpio = (gpio_t*) GPIO_BASE;
|
||||||
|
static volatile systick_t* const systick = (systick_t*) SYSTICK_BASE;
|
||||||
|
|
||||||
|
#define GPIO_LED GPIO_PORT_E
|
||||||
|
#define GPIO_PB GPIO_PORT_B
|
||||||
|
#define LED_PIN 2
|
||||||
|
#define PB0_PIN 9
|
||||||
|
#define PB1_PIN 10
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
enum PROGRAM_STATE {
|
||||||
|
ADD_SECS,
|
||||||
|
ADD_MINS,
|
||||||
|
ADD_HOURS,
|
||||||
|
COUNTDOWN,
|
||||||
|
ALARM,
|
||||||
|
PROGRAM_STATE_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char display[7];
|
||||||
|
unsigned char hours;
|
||||||
|
unsigned char minutes;
|
||||||
|
unsigned char seconds;
|
||||||
|
unsigned char programState;
|
||||||
|
} state;
|
||||||
|
|
||||||
|
void initializeState() {
|
||||||
|
state.hours = 0;
|
||||||
|
state.minutes = 0;
|
||||||
|
state.seconds = 0;
|
||||||
|
state.programState = ADD_SECS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeInterruptHandlers()
|
||||||
|
{
|
||||||
|
// Setup SYSTICK
|
||||||
|
systick->CTRL = 0b111;
|
||||||
|
systick->LOAD = FREQUENCY;
|
||||||
|
systick->VAL = 1;
|
||||||
|
|
||||||
|
// Setup LED
|
||||||
|
volatile word* setting;
|
||||||
|
setting = &gpio->ports[GPIO_LED].MODEL;
|
||||||
|
*setting &= ~(0xF << (4 * LED_PIN));
|
||||||
|
*setting += GPIO_MODE_OUTPUT << (4 * LED_PIN);
|
||||||
|
|
||||||
|
// Setup buttons
|
||||||
|
for (char i=0; i<2; i++) {
|
||||||
|
setting = i ? &gpio->ports[GPIO_PB].MODEH : &gpio->EXTIPSELH;
|
||||||
|
*setting &= ~(0xFF << 4);
|
||||||
|
*setting += 0x110;
|
||||||
|
|
||||||
|
word button = i ? PB0_PIN : PB1_PIN;
|
||||||
|
gpio->EXTIFALL |= (1 << button);
|
||||||
|
gpio->IEN |= (1 << button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void activateAlarm()
|
||||||
|
{
|
||||||
|
state.programState = ALARM;
|
||||||
|
gpio->ports[GPIO_LED].DOUTSET = 1 << LED_PIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deactivateAlarm()
|
||||||
|
{
|
||||||
|
gpio->ports[GPIO_LED].DOUTCLR = 1 << LED_PIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void turnToNextState()
|
||||||
|
{
|
||||||
|
if (state.programState == COUNTDOWN) return;
|
||||||
|
if (state.programState == ALARM)
|
||||||
|
deactivateAlarm();
|
||||||
|
|
||||||
|
state.programState++;
|
||||||
|
state.programState %= PROGRAM_STATE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateScreen()
|
||||||
|
{
|
||||||
|
time_to_string(state.display, state.hours, state.minutes, state.seconds);
|
||||||
|
lcd_write(state.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void SysTick_Handler()
|
||||||
|
{
|
||||||
|
gpio->ports[GPIO_LED].DOUTTGL = 1;
|
||||||
|
if (state.programState != COUNTDOWN) return;
|
||||||
|
|
||||||
|
if (!state.seconds) {
|
||||||
|
if (!state.minutes) {
|
||||||
|
if (!state.hours) {
|
||||||
|
activateAlarm();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.hours--;
|
||||||
|
state.minutes = 60;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.minutes--;
|
||||||
|
state.seconds = 60;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.seconds--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PB0
|
||||||
|
void GPIO_ODD_IRQHandler()
|
||||||
|
{
|
||||||
|
switch (state.programState)
|
||||||
|
{
|
||||||
|
case ADD_SECS:
|
||||||
|
state.seconds++;
|
||||||
|
state.seconds %= 60;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ADD_MINS:
|
||||||
|
state.minutes++;
|
||||||
|
state.minutes %= 60;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ADD_HOURS:
|
||||||
|
state.hours++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gpio->IFC = 1 << PB0_PIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PB1
|
||||||
|
void GPIO_EVEN_IRQHandler()
|
||||||
|
{
|
||||||
|
turnToNextState();
|
||||||
|
gpio->IFC = 1 << PB1_PIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
initializeInterruptHandlers();
|
||||||
|
initializeState();
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
updateScreen();
|
||||||
|
__asm__("WFI");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* En rask måte å unngå header recursion på er å sjekke om verdi, f.eks. 'O3_H',
|
||||||
|
er definert. Hvis ikke, definer 'O3_H' og deretter innholdet av headeren
|
||||||
|
(merk endif på bunnen). Nå kan headeren inkluderes så mange ganger vi vil
|
||||||
|
uten at det blir noen problemer. */
|
||||||
|
#ifndef O3_H
|
||||||
|
#define O3_H
|
||||||
|
|
||||||
|
// Type-definisjoner fra std-bibliotekene
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Type-aliaser
|
||||||
|
typedef uint32_t word;
|
||||||
|
typedef uint8_t byte;
|
||||||
|
|
||||||
|
// Prototyper for bibliotekfunksjoner
|
||||||
|
void init(void);
|
||||||
|
void lcd_write(char* string);
|
||||||
|
void int_to_string(char *timestamp, unsigned int offset, int i);
|
||||||
|
void time_to_string(char *timestamp, int h, int m, int s);
|
||||||
|
|
||||||
|
// Prototyper
|
||||||
|
// legg prototyper for dine funksjoner her
|
||||||
|
|
||||||
|
void initializeInterruptHandlers();
|
||||||
|
void SysTick_Handler();
|
||||||
|
void GPIO_ODD_IRQHandler();
|
||||||
|
void GPIO_EVEN_IRQHandler();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef SYSTICK_H
|
||||||
|
#define SYSTICK_H
|
||||||
|
|
||||||
|
// Sys-Tick adresse
|
||||||
|
#define SYSTICK_BASE 0xE000E010
|
||||||
|
|
||||||
|
// Antall klokkesignaler per sekund
|
||||||
|
#define FREQUENCY 14000000
|
||||||
|
|
||||||
|
// CTRL-register-masker
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Msk 0b100
|
||||||
|
#define SysTick_CTRL_TICKINT_Msk 0b010
|
||||||
|
#define SysTick_CTRL_ENABLE_Msk 0b001
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
```
|
||||||
|
ldi %r2, 1
|
||||||
|
00000 00010 0000000000000000000001
|
||||||
|
|
||||||
|
ldi %r1, 1
|
||||||
|
00000 00001 0000000000000000000001
|
||||||
|
|
||||||
|
mul %r2, %r2, %r0
|
||||||
|
00010 00010 00010 00000 XXXXXXXXXXXX
|
||||||
|
|
||||||
|
sub %r0, %r0, %r1
|
||||||
|
00101 00000 00000 00001 XXXXXXXXXXXX
|
||||||
|
|
||||||
|
cmp %r3, %r0, %r1
|
||||||
|
00011 00011 00000 00001 XXXXXXXXXXXX
|
||||||
|
|
||||||
|
jgt %r3, -16
|
||||||
|
00100 00011 1111111111111111110000
|
||||||
|
```
|
|
@ -0,0 +1,6 @@
|
||||||
|
00000000100000000000000000000001
|
||||||
|
00000000010000000000000000000001
|
||||||
|
00010000100001000000XXXXXXXXXXXX
|
||||||
|
00101000000000000001XXXXXXXXXXXX
|
||||||
|
00011000110000000001XXXXXXXXXXXX
|
||||||
|
00100000111111111111111111110000
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
int f(int r0) {
|
||||||
|
int r2 = 1;
|
||||||
|
int r1 = 1;
|
||||||
|
back16:
|
||||||
|
r2 = r2 * r0;
|
||||||
|
r0 = r0 - r1;
|
||||||
|
if (r0 > r1) {
|
||||||
|
goto back16;
|
||||||
|
}
|
||||||
|
return r2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int vals[] = {2, 3, 4, 9};
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
printf("f( r0=%d ) = %d\n", vals[i], f(vals[i]));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
2
|
||||||
|
6
|
||||||
|
24
|
||||||
|
362880
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
xs = []
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Regs:
|
||||||
|
imm: int
|
||||||
|
alu: int
|
||||||
|
regw: int
|
||||||
|
branch: int
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.imm}{self.alu}{self.regw}{self.branch}'
|
||||||
|
|
||||||
|
|
||||||
|
def add():
|
||||||
|
xs.append(Regs(imm=0, alu=0, regw=1, branch=0))
|
||||||
|
def sub():
|
||||||
|
xs.append(Regs(imm=0, alu=5, regw=1, branch=0))
|
||||||
|
def mul():
|
||||||
|
xs.append(Regs(imm=0, alu=4, regw=1, branch=0))
|
||||||
|
def cmp():
|
||||||
|
xs.append(Regs(imm=0, alu=1, regw=1, branch=0))
|
||||||
|
def jgt():
|
||||||
|
xs.append(Regs(imm=0, alu=2, regw=0, branch=1))
|
||||||
|
def ldi():
|
||||||
|
xs.append(Regs(imm=1, alu=3, regw=1, branch=0))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
r0 = 1
|
||||||
|
r2 = 1
|
||||||
|
ldi()
|
||||||
|
r1 = 1
|
||||||
|
ldi()
|
||||||
|
while (True):
|
||||||
|
mul()
|
||||||
|
r2 = r2 * r0
|
||||||
|
sub()
|
||||||
|
r0 = r0 - r1
|
||||||
|
cmp()
|
||||||
|
jgt()
|
||||||
|
if not (r0 > r1):
|
||||||
|
break
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
for x in xs:
|
||||||
|
print(x)
|
|
@ -0,0 +1,6 @@
|
||||||
|
1310
|
||||||
|
1310
|
||||||
|
0410
|
||||||
|
0510
|
||||||
|
0110
|
||||||
|
0201
|
Loading…
Reference in New Issue