commit 35199c438c0ec50adab5e32c9be2065e768de502 Author: h7x4 Date: Sat Aug 27 16:26:13 2022 +0200 Add all exercises diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..264ddb1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +**/build +**/exe +**/lst + +**/result \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..de4be14 --- /dev/null +++ b/README.md @@ -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) \ No newline at end of file diff --git a/kompendium_o123.pdf b/kompendium_o123.pdf new file mode 100644 index 0000000..bae5263 Binary files /dev/null and b/kompendium_o123.pdf differ diff --git a/o1/Makefile b/o1/Makefile new file mode 100644 index 0000000..edbba99 --- /dev/null +++ b/o1/Makefile @@ -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!" diff --git a/o1/Makefile.original b/o1/Makefile.original new file mode 100644 index 0000000..de545df --- /dev/null +++ b/o1/Makefile.original @@ -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!" diff --git a/o1/efm32gg.ld b/o1/efm32gg.ld new file mode 100644 index 0000000..9d15799 --- /dev/null +++ b/o1/efm32gg.ld @@ -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 !") +} diff --git a/o1/gpio_constants.s b/o1/gpio_constants.s new file mode 100644 index 0000000..b1e5c94 --- /dev/null +++ b/o1/gpio_constants.s @@ -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 +// ------------------------------------------------------------------------- // diff --git a/o1/o1.s b/o1/o1.s new file mode 100644 index 0000000..ee11048 --- /dev/null +++ b/o1/o1.s @@ -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 diff --git a/o1/sys-tick_constants.s b/o1/sys-tick_constants.s new file mode 100644 index 0000000..64a374f --- /dev/null +++ b/o1/sys-tick_constants.s @@ -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 +// ------------------------------------------------------------- // diff --git a/o2/Makefile b/o2/Makefile new file mode 100644 index 0000000..edbba99 --- /dev/null +++ b/o2/Makefile @@ -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!" diff --git a/o2/Makefile.original b/o2/Makefile.original new file mode 100644 index 0000000..de545df --- /dev/null +++ b/o2/Makefile.original @@ -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!" diff --git a/o2/efm32gg.ld b/o2/efm32gg.ld new file mode 100644 index 0000000..9d15799 --- /dev/null +++ b/o2/efm32gg.ld @@ -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 !") +} diff --git a/o2/gpio_constants.s b/o2/gpio_constants.s new file mode 100644 index 0000000..b1e5c94 --- /dev/null +++ b/o2/gpio_constants.s @@ -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 +// ------------------------------------------------------------------------- // diff --git a/o2/o2.s b/o2/o2.s new file mode 100644 index 0000000..ea66b36 --- /dev/null +++ b/o2/o2.s @@ -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<$(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!" diff --git a/o3/Makefile.original b/o3/Makefile.original new file mode 100644 index 0000000..f07ba55 --- /dev/null +++ b/o3/Makefile.original @@ -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!" diff --git a/o3/efm32gg.ld b/o3/efm32gg.ld new file mode 100644 index 0000000..9d15799 --- /dev/null +++ b/o3/efm32gg.ld @@ -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 !") +} diff --git a/o3/gpio.h b/o3/gpio.h new file mode 100644 index 0000000..395b57a --- /dev/null +++ b/o3/gpio.h @@ -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 diff --git a/o3/o3.c b/o3/o3.c new file mode 100644 index 0000000..2081edd --- /dev/null +++ b/o3/o3.c @@ -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; +} diff --git a/o3/o3.h b/o3/o3.h new file mode 100644 index 0000000..4c7e281 --- /dev/null +++ b/o3/o3.h @@ -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 +#include + +// 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 diff --git a/o3/systick.h b/o3/systick.h new file mode 100644 index 0000000..ee39c87 --- /dev/null +++ b/o3/systick.h @@ -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 diff --git a/o456.pdf b/o456.pdf new file mode 100644 index 0000000..dc45513 Binary files /dev/null and b/o456.pdf differ diff --git a/o456/o4.md b/o456/o4.md new file mode 100644 index 0000000..cf52265 --- /dev/null +++ b/o456/o4.md @@ -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 +``` diff --git a/o456/o4.txt b/o456/o4.txt new file mode 100644 index 0000000..883d115 --- /dev/null +++ b/o456/o4.txt @@ -0,0 +1,6 @@ +00000000100000000000000000000001 +00000000010000000000000000000001 +00010000100001000000XXXXXXXXXXXX +00101000000000000001XXXXXXXXXXXX +00011000110000000001XXXXXXXXXXXX +00100000111111111111111111110000 diff --git a/o456/o5.c b/o456/o5.c new file mode 100644 index 0000000..294e2fa --- /dev/null +++ b/o456/o5.c @@ -0,0 +1,22 @@ +#include + + +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; +} diff --git a/o456/o5.txt b/o456/o5.txt new file mode 100644 index 0000000..91acf9e --- /dev/null +++ b/o456/o5.txt @@ -0,0 +1,4 @@ +2 +6 +24 +362880 diff --git a/o456/o6.py b/o456/o6.py new file mode 100755 index 0000000..ce073c9 --- /dev/null +++ b/o456/o6.py @@ -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) diff --git a/o456/o6.txt b/o456/o6.txt new file mode 100644 index 0000000..af96e89 --- /dev/null +++ b/o456/o6.txt @@ -0,0 +1,6 @@ +1310 +1310 +0410 +0510 +0110 +0201