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