Add all exercises

This commit is contained in:
Oystein Kristoffer Tveit 2022-08-27 16:26:13 +02:00
commit 35199c438c
Signed by: oysteikt
GPG Key ID: 9F2F7D8250F35146
29 changed files with 2644 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
**/build
**/exe
**/lst
**/result

24
README.md Normal file
View File

@ -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)

BIN
kompendium_o123.pdf Normal file

Binary file not shown.

214
o1/Makefile Normal file
View File

@ -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!"

214
o1/Makefile.original Normal file
View File

@ -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!"

207
o1/efm32gg.ld Normal file
View File

@ -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 !")
}

53
o1/gpio_constants.s Normal file
View File

@ -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
// ------------------------------------------------------------------------- //

27
o1/o1.s Normal file
View File

@ -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

19
o1/sys-tick_constants.s Normal file
View File

@ -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
// ------------------------------------------------------------- //

214
o2/Makefile Normal file
View File

@ -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!"

214
o2/Makefile.original Normal file
View File

@ -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!"

207
o2/efm32gg.ld Normal file
View File

@ -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 !")
}

53
o2/gpio_constants.s Normal file
View File

@ -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
// ------------------------------------------------------------------------- //

110
o2/o2.s Normal file
View File

@ -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

19
o2/sys-tick_constants.s Normal file
View File

@ -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
// ------------------------------------------------------------- //

214
o3/Makefile Normal file
View File

@ -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!"

212
o3/Makefile.original Normal file
View File

@ -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!"

207
o3/efm32gg.ld Normal file
View File

@ -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 !")
}

26
o3/gpio.h Normal file
View File

@ -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

252
o3/o3.c Normal file
View File

@ -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 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;
}

30
o3/o3.h Normal file
View File

@ -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 bunnen). kan headeren inkluderes 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

15
o3/systick.h Normal file
View File

@ -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

BIN
o456.pdf Normal file

Binary file not shown.

20
o456/o4.md Normal file
View File

@ -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
```

6
o456/o4.txt Normal file
View File

@ -0,0 +1,6 @@
00000000100000000000000000000001
00000000010000000000000000000001
00010000100001000000XXXXXXXXXXXX
00101000000000000001XXXXXXXXXXXX
00011000110000000001XXXXXXXXXXXX
00100000111111111111111111110000

22
o456/o5.c Normal file
View File

@ -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;
}

4
o456/o5.txt Normal file
View File

@ -0,0 +1,4 @@
2
6
24
362880

50
o456/o6.py Executable file
View File

@ -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)

6
o456/o6.txt Normal file
View File

@ -0,0 +1,6 @@
1310
1310
0410
0510
0110
0201