diff --git a/ASF/AtmelStart.gpdsc b/ASF/AtmelStart.gpdsc
index f11c194..b380a3f 100644
--- a/ASF/AtmelStart.gpdsc
+++ b/ASF/AtmelStart.gpdsc
@@ -54,6 +54,7 @@
+
@@ -103,9 +104,11 @@
+
+
@@ -195,8 +198,10 @@
+
+
@@ -204,10 +209,12 @@
+
+
@@ -225,6 +232,8 @@
+
+
@@ -242,6 +251,7 @@
+
@@ -264,6 +274,7 @@
+
diff --git a/ASF/armcc/Makefile b/ASF/armcc/Makefile
deleted file mode 100644
index 034f3a8..0000000
--- a/ASF/armcc/Makefile
+++ /dev/null
@@ -1,276 +0,0 @@
-
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-ifdef SystemRoot
- SHELL = cmd.exe
- MK_DIR = mkdir
-else
- ifeq ($(shell uname), Linux)
- MK_DIR = mkdir -p
- endif
-
- ifeq ($(shell uname | cut -d _ -f 1), CYGWIN)
- MK_DIR = mkdir -p
- endif
-
- ifeq ($(shell uname | cut -d _ -f 1), MINGW32)
- MK_DIR = mkdir -p
- endif
-
- ifeq ($(shell uname | cut -d _ -f 1), MINGW64)
- MK_DIR = mkdir -p
- endif
-endif
-
-# List the subdirectories for creating object files
-SUB_DIRS += \
- \
-hpl/adc \
-hpl/ramecc \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F \
-examples \
-hpl/systick \
-hpl/oscctrl \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0 \
-hpl/osc32kctrl \
-samd51a/armcc/Device/SAMD51/Source \
-hpl/dmac \
-hal/src \
-hal/utils/src \
-hpl/wdt \
-samd51a/armcc/Device/SAMD51/Source/ARM \
-hpl/trng \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang \
-hpl/mclk \
-hpl/cmcc \
-hpl/gclk \
-hpl/pm \
-hpl/sercom \
-hpl/core
-
-# List the object files
-OBJS += \
-hal/src/hal_io.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/list.o \
-hpl/systick/hpl_systick.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/event_groups.o \
-hpl/wdt/hpl_wdt.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/croutine.o \
-hpl/core/hpl_core_m4.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/stream_buffer.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang/heap_1.o \
-samd51a/armcc/Device/SAMD51/Source/ARM/startup_samd51.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/queue.o \
-hal/src/hal_spi_m_sync.o \
-hal/src/hal_i2c_m_sync.o \
-samd51a/armcc/Device/SAMD51/Source/system_samd51.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.o \
-hal/src/hal_delay.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F/port.o \
-hpl/pm/hpl_pm.o \
-hpl/core/hpl_init.o \
-hpl/gclk/hpl_gclk.o \
-hal/src/hal_wdt.o \
-hal/utils/src/utils_assert.o \
-hpl/dmac/hpl_dmac.o \
-hpl/oscctrl/hpl_oscctrl.o \
-hal/src/hal_rand_sync.o \
-hpl/trng/hpl_trng.o \
-hpl/mclk/hpl_mclk.o \
-hpl/ramecc/hpl_ramecc.o \
-hal/src/hal_init.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/rtos_port.o \
-rtos_start.o \
-hal/utils/src/utils_list.o \
-hpl/osc32kctrl/hpl_osc32kctrl.o \
-examples/driver_examples.o \
-driver_init.o \
-hal/src/hal_adc_sync.o \
-hpl/sercom/hpl_sercom.o \
-main.o \
-hal/src/hal_gpio.o \
-hal/utils/src/utils_event.o \
-hal/src/hal_sleep.o \
-hal/src/hal_cache.o \
-hpl/cmcc/hpl_cmcc.o \
-atmel_start.o \
-hal/src/hal_atomic.o \
-thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/tasks.o \
-hpl/adc/hpl_adc.o
-
-OBJS_AS_ARGS += \
-"hal/src/hal_io.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/list.o" \
-"hpl/systick/hpl_systick.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/event_groups.o" \
-"hpl/wdt/hpl_wdt.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/croutine.o" \
-"hpl/core/hpl_core_m4.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/stream_buffer.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang/heap_1.o" \
-"samd51a/armcc/Device/SAMD51/Source/ARM/startup_samd51.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/queue.o" \
-"hal/src/hal_spi_m_sync.o" \
-"hal/src/hal_i2c_m_sync.o" \
-"samd51a/armcc/Device/SAMD51/Source/system_samd51.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.o" \
-"hal/src/hal_delay.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F/port.o" \
-"hpl/pm/hpl_pm.o" \
-"hpl/core/hpl_init.o" \
-"hpl/gclk/hpl_gclk.o" \
-"hal/src/hal_wdt.o" \
-"hal/utils/src/utils_assert.o" \
-"hpl/dmac/hpl_dmac.o" \
-"hpl/oscctrl/hpl_oscctrl.o" \
-"hal/src/hal_rand_sync.o" \
-"hpl/trng/hpl_trng.o" \
-"hpl/mclk/hpl_mclk.o" \
-"hpl/ramecc/hpl_ramecc.o" \
-"hal/src/hal_init.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/rtos_port.o" \
-"rtos_start.o" \
-"hal/utils/src/utils_list.o" \
-"hpl/osc32kctrl/hpl_osc32kctrl.o" \
-"examples/driver_examples.o" \
-"driver_init.o" \
-"hal/src/hal_adc_sync.o" \
-"hpl/sercom/hpl_sercom.o" \
-"main.o" \
-"hal/src/hal_gpio.o" \
-"hal/utils/src/utils_event.o" \
-"hal/src/hal_sleep.o" \
-"hal/src/hal_cache.o" \
-"hpl/cmcc/hpl_cmcc.o" \
-"atmel_start.o" \
-"hal/src/hal_atomic.o" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/tasks.o" \
-"hpl/adc/hpl_adc.o"
-
-# List the dependency files
-DEPS := $(OBJS:%.o=%.d)
-
-DEPS_AS_ARGS += \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/event_groups.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/croutine.d" \
-"hpl/wdt/hpl_wdt.d" \
-"hal/utils/src/utils_event.d" \
-"hal/src/hal_io.d" \
-"hpl/ramecc/hpl_ramecc.d" \
-"hpl/systick/hpl_systick.d" \
-"hpl/core/hpl_core_m4.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang/heap_1.d" \
-"samd51a/armcc/Device/SAMD51/Source/system_samd51.d" \
-"hal/src/hal_i2c_m_sync.d" \
-"main.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.d" \
-"samd51a/armcc/Device/SAMD51/Source/ARM/startup_samd51.d" \
-"hal/src/hal_spi_m_sync.d" \
-"hal/src/hal_wdt.d" \
-"hpl/cmcc/hpl_cmcc.d" \
-"hpl/dmac/hpl_dmac.d" \
-"hal/utils/src/utils_assert.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/stream_buffer.d" \
-"hal/src/hal_delay.d" \
-"hpl/core/hpl_init.d" \
-"hpl/pm/hpl_pm.d" \
-"hpl/gclk/hpl_gclk.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F/port.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/rtos_port.d" \
-"hal/src/hal_init.d" \
-"hpl/trng/hpl_trng.d" \
-"hal/src/hal_rand_sync.d" \
-"hpl/mclk/hpl_mclk.d" \
-"driver_init.d" \
-"hal/src/hal_adc_sync.d" \
-"hpl/osc32kctrl/hpl_osc32kctrl.d" \
-"rtos_start.d" \
-"examples/driver_examples.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/list.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/queue.d" \
-"hal/src/hal_cache.d" \
-"hal/utils/src/utils_list.d" \
-"hal/src/hal_sleep.d" \
-"hpl/sercom/hpl_sercom.d" \
-"hal/src/hal_gpio.d" \
-"hal/src/hal_atomic.d" \
-"hpl/oscctrl/hpl_oscctrl.d" \
-"hpl/adc/hpl_adc.d" \
-"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/tasks.d" \
-"atmel_start.d"
-
-OUTPUT_FILE_NAME :=AtmelStart
-QUOTE := "
-OUTPUT_FILE_PATH +=$(OUTPUT_FILE_NAME).elf
-OUTPUT_FILE_PATH_AS_ARGS +=$(OUTPUT_FILE_NAME).elf
-
-vpath %.c ../
-vpath %.s ../
-vpath %.S ../
-
-# All Target
-all: $(SUB_DIRS) $(OUTPUT_FILE_PATH)
-
-# Linker target
-
-$(OUTPUT_FILE_PATH): $(OBJS)
- @echo Building target: $@
- @echo Invoking: ARMCC Linker
- $(QUOTE)armlink$(QUOTE) --ro-base 0x00000000 --entry 0x00000000 --rw-base 0x20000000 --entry Reset_Handler --first __Vectors \
---strict --summary_stderr --info summarysizes --map --xref --callgraph --symbols \
---info sizes --info totals --info unused --info veneers --list $(OUTPUT_FILE_NAME).map \
--o $(OUTPUT_FILE_NAME).elf --cpu Cortex-M4 \
-$(OBJS_AS_ARGS)
-
- @echo Finished building target: $@
-
-# Compiler target(s)
-
-
-
-
-%.o: %.c
- @echo Building file: $<
- @echo ARMCC Compiler
- $(QUOTE)armcc$(QUOTE) --c99 -c -DDEBUG -O1 -g --apcs=interwork --split_sections --cpu Cortex-M4 -D__SAMD51P20A__ \
--I"../" -I"../config" -I"../examples" -I"../hal/include" -I"../hal/utils/include" -I"../hpl/adc" -I"../hpl/cmcc" -I"../hpl/core" -I"../hpl/dmac" -I"../hpl/gclk" -I"../hpl/mclk" -I"../hpl/osc32kctrl" -I"../hpl/oscctrl" -I"../hpl/pm" -I"../hpl/port" -I"../hpl/ramecc" -I"../hpl/sercom" -I"../hpl/systick" -I"../hpl/trng" -I"../hpl/wdt" -I"../hri" -I"../" -I"../config" -I"../thirdparty/RTOS" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/include" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/module_config" -I"../" -I"../CMSIS/Core/Include" -I"../samd51a/include" \
---depend "$@" -o "$@" "$<"
-
- @echo Finished building: $<
-
-%.o: %.s
- @echo Building file: $<
- @echo ARMCC Assembler
- $(QUOTE)armasm$(QUOTE) -g --apcs=interwork --cpu Cortex-M4 --pd "D__SAMD51P20A__ SETA 1" \
--I"../" -I"../config" -I"../examples" -I"../hal/include" -I"../hal/utils/include" -I"../hpl/adc" -I"../hpl/cmcc" -I"../hpl/core" -I"../hpl/dmac" -I"../hpl/gclk" -I"../hpl/mclk" -I"../hpl/osc32kctrl" -I"../hpl/oscctrl" -I"../hpl/pm" -I"../hpl/port" -I"../hpl/ramecc" -I"../hpl/sercom" -I"../hpl/systick" -I"../hpl/trng" -I"../hpl/wdt" -I"../hri" -I"../" -I"../config" -I"../thirdparty/RTOS" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/include" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/module_config" -I"../" -I"../CMSIS/Core/Include" -I"../samd51a/include" \
---depend "$(@:%.o=%.d)" -o "$@" "$<"
-
- @echo Finished building: $<
-
-%.o: %.S
- @echo Building file: $<
- @echo ARMCC Preprocessing Assembler
- $(QUOTE)armcc$(QUOTE) --c99 -c -DDEBUG -O1 -g --apcs=interwork --split_sections --cpu Cortex-M4 -D__SAMD51P20A__ \
--I"../" -I"../config" -I"../examples" -I"../hal/include" -I"../hal/utils/include" -I"../hpl/adc" -I"../hpl/cmcc" -I"../hpl/core" -I"../hpl/dmac" -I"../hpl/gclk" -I"../hpl/mclk" -I"../hpl/osc32kctrl" -I"../hpl/oscctrl" -I"../hpl/pm" -I"../hpl/port" -I"../hpl/ramecc" -I"../hpl/sercom" -I"../hpl/systick" -I"../hpl/trng" -I"../hpl/wdt" -I"../hri" -I"../" -I"../config" -I"../thirdparty/RTOS" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/include" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/RVDS/ARM_CM4F" -I"../thirdparty/RTOS/freertos/FreeRTOSV10.0.0/module_config" -I"../" -I"../CMSIS/Core/Include" -I"../samd51a/include" \
---depend "$@" -o "$@" "$<"
-
- @echo Finished building: $<
-
-# Detect changes in the dependent files and recompile the respective object files.
-ifneq ($(MAKECMDGOALS),clean)
-ifneq ($(strip $(DEPS)),)
--include $(DEPS)
-endif
-endif
-
-$(SUB_DIRS):
- $(MK_DIR) "$@"
-
-clean:
- rm -f $(OBJS_AS_ARGS)
- rm -f $(OUTPUT_FILE_PATH)
- rm -f $(DEPS_AS_ARGS)
- rm -f $(OUTPUT_FILE_NAME).map $(OUTPUT_FILE_NAME).elf
diff --git a/ASF/atmel_start_config.atstart b/ASF/atmel_start_config.atstart
index 7b03665..03512f0 100644
--- a/ASF/atmel_start_config.atstart
+++ b/ASF/atmel_start_config.atstart
@@ -858,7 +858,7 @@ drivers:
RESERVED_InputFreq_id: 32kHz Ultra Low Power Internal Oscillator (OSCULP32K)
_$freq_output_RTC source: 32768
enable_osculp32k: true
- enable_rtc_source: false
+ enable_rtc_source: true
enable_xosc32k: false
osculp32k_calib: 0
osculp32k_calib_enable: false
@@ -1041,6 +1041,62 @@ drivers:
variant: null
clocks:
domain_group: null
+ TIMER_0:
+ user_label: TIMER_0
+ definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51P20A-AF::RTC::driver_config_definition::Timer::HAL:Driver:Timer
+ functionality: Timer
+ api: HAL:Driver:Timer
+ configuration:
+ rtc_arch_comp_val: 32
+ rtc_arch_init_reset: true
+ rtc_arch_prescaler: OFF(Peripheral clock divided by 1)
+ rtc_cmpeo0: false
+ rtc_cmpeo1: false
+ rtc_event_control: false
+ rtc_ovfeo: false
+ rtc_pereo0: false
+ rtc_pereo1: false
+ rtc_pereo2: false
+ rtc_pereo3: false
+ rtc_pereo4: false
+ rtc_pereo5: false
+ rtc_pereo6: false
+ rtc_pereo7: false
+ rtc_tamper_active_layer_frequency_prescalar: DIV2 CLK_RTC_OUT is CLK_RTC /2
+ rtc_tamper_debounce_frequency_prescalar: DIV2 CLK_RTC_DEB is CLK_RTC /2
+ rtc_tamper_input_action_0: OFF(Disabled)
+ rtc_tamper_input_action_1: OFF(Disabled)
+ rtc_tamper_input_action_2: OFF(Disabled)
+ rtc_tamper_input_action_3: OFF(Disabled)
+ rtc_tamper_input_action_4: OFF(Disabled)
+ rtc_tampereo: false
+ rtc_tampevei: false
+ tamper_debounce_enable_0: false
+ tamper_debounce_enable_1: false
+ tamper_debounce_enable_2: false
+ tamper_debounce_enable_3: false
+ tamper_debounce_enable_4: false
+ tamper_input_0_settings: false
+ tamper_input_1_settings: false
+ tamper_input_2_settings: false
+ tamper_input_3_settings: false
+ tamper_input_4_settings: false
+ tamper_level_0: false
+ tamper_level_1: false
+ tamper_level_2: false
+ tamper_level_3: false
+ tamper_level_4: false
+ optional_signals: []
+ variant: null
+ clocks:
+ domain_group:
+ nodes:
+ - name: RTC
+ input: RTC source
+ external: false
+ external_frequency: 0
+ configuration:
+ rtc_clk_selection: RTC source
I2C_SBAND:
user_label: I2C_SBAND
definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51P20A-AF::SERCOM2::driver_config_definition::I2C.Master.Standard~2FFast-mode::HAL:Driver:I2C.Master.Sync
diff --git a/ASF/config/hpl_osc32kctrl_config.h b/ASF/config/hpl_osc32kctrl_config.h
index e7fddd2..c899f33 100644
--- a/ASF/config/hpl_osc32kctrl_config.h
+++ b/ASF/config/hpl_osc32kctrl_config.h
@@ -7,7 +7,7 @@
// RTC Source configuration
// enable_rtc_source
#ifndef CONF_RTCCTRL_CONFIG
-#define CONF_RTCCTRL_CONFIG 0
+#define CONF_RTCCTRL_CONFIG 1
#endif
// RTC source control
diff --git a/ASF/config/hpl_rtc_config.h b/ASF/config/hpl_rtc_config.h
new file mode 100644
index 0000000..79c0192
--- /dev/null
+++ b/ASF/config/hpl_rtc_config.h
@@ -0,0 +1,341 @@
+/* Auto-generated config file hpl_rtc_config.h */
+#ifndef HPL_RTC_CONFIG_H
+#define HPL_RTC_CONFIG_H
+
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// Basic settings
+
+#ifndef CONF_RTC_ENABLE
+#define CONF_RTC_ENABLE 1
+#endif
+
+// Force reset RTC on initialization
+// Force RTC to reset on initialization.
+// Note that the previous power down data in RTC is lost if it's enabled.
+// rtc_arch_init_reset
+#ifndef CONF_RTC_INIT_RESET
+#define CONF_RTC_INIT_RESET 1
+#endif
+
+// Prescaler configuration
+// <0x0=>OFF(Peripheral clock divided by 1)
+// <0x1=>Peripheral clock divided by 1
+// <0x2=>Peripheral clock divided by 2
+// <0x3=>Peripheral clock divided by 4
+// <0x4=>Peripheral clock divided by 8
+// <0x5=>Peripheral clock divided by 16
+// <0x6=>Peripheral clock divided by 32
+// <0x7=>Peripheral clock divided by 64
+// <0x8=>Peripheral clock divided by 128
+// <0x9=>Peripheral clock divided by 256
+// <0xA=>Peripheral clock divided by 512
+// <0xB=>Peripheral clock divided by 1024
+// These bits define the RTC clock relative to the peripheral clock
+// rtc_arch_prescaler
+#ifndef CONF_RTC_PRESCALER
+#define CONF_RTC_PRESCALER 0x0
+
+#endif
+
+// Compare Value <1-4294967295>
+// These bits define the RTC Compare value, the ticks period is equal to reciprocal of (rtc clock/prescaler/compare value),
+// by default 1K clock input, 1 prescaler, 1 compare value, the ticks period equals to 1ms.
+// rtc_arch_comp_val
+
+#ifndef CONF_RTC_COMP_VAL
+
+#define CONF_RTC_COMP_VAL 32
+
+#endif
+
+// RTC Tamper Input 0 settings
+// tamper_input_0_settings
+#ifndef CONF_TAMPER_INPUT_0_SETTINGS
+#define CONF_TAMPER_INPUT_0_SETTINGS 0
+#endif
+
+// Tamper Level Settings
+// Indicates Tamper input 0 level
+// tamper_level_0
+#ifndef CONF_RTC_TAMP_LVL_0
+#define CONF_RTC_TAMP_LVL_0 0
+#endif
+
+// RTC Tamper Input Action
+// <0x0=>OFF(Disabled)
+// <0x1=>Wake and Set Tamper Flag
+// <0x2=>Capture Timestamp and Set Tamper Flag
+// <0x3=>Active Layer Mode.IN and OUT pin is used.Timestamp is also captured.
+// These bits define the RTC Tamper Input Action to be performed
+// rtc_tamper_input_action_0
+#ifndef CONF_RTC_TAMPER_INACT_0
+#define CONF_RTC_TAMPER_INACT_0 0
+#endif
+
+// Debounce Enable for Tamper Input
+// Indicates Debounce should be enabled for Tamper input 0
+// tamper_debounce_enable_0
+#ifndef CONF_RTC_TAMP_DEBNC_0
+#define CONF_RTC_TAMP_DEBNC_0 0
+#endif
+
+//
+
+// RTC Tamper Input 1 settings
+// tamper_input_1_settings
+#ifndef CONF_TAMPER_INPUT_1_SETTINGS
+#define CONF_TAMPER_INPUT_1_SETTINGS 0
+#endif
+
+// Tamper Level Settings
+// Indicates Tamper input 1 level
+// tamper_level_1
+#ifndef CONF_RTC_TAMP_LVL_1
+#define CONF_RTC_TAMP_LVL_1 0
+#endif
+
+// RTC Tamper Input Action
+// <0x0=>OFF(Disabled)
+// <0x1=>Wake and Set Tamper Flag
+// <0x2=>Capture Timestamp and Set Tamper Flag
+// <0x3=>Active Layer Mode.IN and OUT pin is used.Timestamp is also captured.
+// These bits define the RTC Tamper Input Action to be performed
+// rtc_tamper_input_action_1
+#ifndef CONF_RTC_TAMPER_INACT_1
+#define CONF_RTC_TAMPER_INACT_1 0
+#endif
+
+// Debounce Enable for Tamper Input
+// Indicates Debounce should be enabled for Tamper input 1
+// tamper_debounce_enable_1
+#ifndef CONF_RTC_TAMP_DEBNC_1
+#define CONF_RTC_TAMP_DEBNC_1 0
+#endif
+
+//
+
+// RTC Tamper Input 2 settings
+// tamper_input_2_settings
+#ifndef CONF_TAMPER_INPUT_2_SETTINGS
+#define CONF_TAMPER_INPUT_2_SETTINGS 0
+#endif
+
+// Tamper Level Settings
+// Indicates Tamper input 2 level
+// tamper_level_2
+#ifndef CONF_RTC_TAMP_LVL_2
+#define CONF_RTC_TAMP_LVL_2 0
+#endif
+
+// RTC Tamper Input Action
+// <0x0=>OFF(Disabled)
+// <0x1=>Wake and Set Tamper Flag
+// <0x2=>Capture Timestamp and Set Tamper Flag
+// <0x3=>Active Layer Mode.IN and OUT pin is used.Timestamp is also captured.
+// These bits define the RTC Tamper Input Action to be performed
+// rtc_tamper_input_action_2
+#ifndef CONF_RTC_TAMPER_INACT_2
+#define CONF_RTC_TAMPER_INACT_2 0
+#endif
+
+// Debounce Enable for Tamper Input
+// Indicates Debounce should be enabled for Tamper input 2
+// tamper_debounce_enable_2
+#ifndef CONF_RTC_TAMP_DEBNC_2
+#define CONF_RTC_TAMP_DEBNC_2 0
+#endif
+
+//
+
+// RTC Tamper Input 3 settings
+// tamper_input_3_settings
+#ifndef CONF_TAMPER_INPUT_3_SETTINGS
+#define CONF_TAMPER_INPUT_3_SETTINGS 0
+#endif
+
+// Tamper Level Settings
+// Indicates Tamper input 3 level
+// tamper_level_3
+#ifndef CONF_RTC_TAMP_LVL_3
+#define CONF_RTC_TAMP_LVL_3 0
+#endif
+
+// RTC Tamper Input Action
+// <0x0=>OFF(Disabled)
+// <0x1=>Wake and Set Tamper Flag
+// <0x2=>Capture Timestamp and Set Tamper Flag
+// <0x3=>Active Layer Mode.IN and OUT pin is used.Timestamp is also captured.
+// These bits define the RTC Tamper Input Action to be performed
+// rtc_tamper_input_action_3
+#ifndef CONF_RTC_TAMPER_INACT_3
+#define CONF_RTC_TAMPER_INACT_3 0
+#endif
+
+// Debounce Enable for Tamper Input
+// Indicates Debounce should be enabled for Tamper input 3
+// tamper_debounce_enable_3
+#ifndef CONF_RTC_TAMP_DEBNC_3
+#define CONF_RTC_TAMP_DEBNC_3 0
+#endif
+
+//
+
+// RTC Tamper Input 4 settings
+// tamper_input_4_settings
+#ifndef CONF_TAMPER_INPUT_4_SETTINGS
+#define CONF_TAMPER_INPUT_4_SETTINGS 0
+#endif
+
+// Tamper Level Settings
+// Indicates Tamper input 4 level
+// tamper_level_4
+#ifndef CONF_RTC_TAMP_LVL_4
+#define CONF_RTC_TAMP_LVL_4 0
+#endif
+
+// RTC Tamper Input Action
+// <0x0=>OFF(Disabled)
+// <0x1=>Wake and Set Tamper Flag
+// <0x2=>Capture Timestamp and Set Tamper Flag
+// <0x3=>Active Layer Mode.IN and OUT pin is used.Timestamp is also captured.
+// These bits define the RTC Tamper Input Action to be performed
+// rtc_tamper_input_action_4
+#ifndef CONF_RTC_TAMPER_INACT_4
+#define CONF_RTC_TAMPER_INACT_4 0
+#endif
+
+// Debounce Enable for Tamper Input
+// Indicates Debounce should be enabled for Tamper input 4
+// tamper_debounce_enable_4
+#ifndef CONF_RTC_TAMP_DEBNC_4
+#define CONF_RTC_TAMP_DEBNC_4 0
+#endif
+
+//
+
+// RTC Tamper Active Layer Frequency Prescalar
+// <0x0=>DIV2 CLK_RTC_OUT is CLK_RTC /2
+// <0x1=>DIV4 CLK_RTC_OUT is CLK_RTC /4
+// <0x2=>DIV8 CLK_RTC_OUT is CLK_RTC /8
+// <0x3=>DIV16 CLK_RTC_OUT is CLK_RTC /16
+// <0x4=>DIV32 CLK_RTC_OUT is CLK_RTC /32
+// <0x5=>DIV64 CLK_RTC_OUT is CLK_RTC /64
+// <0x6=>DIV128 CLK_RTC_OUT is CLK_RTC /128
+// <0x7=>DIV256 CLK_RTC_OUT is CLK_RTC /256
+// These bits define the RTC Tamper Active Layer Frequecny Prescalar
+// rtc_tamper_active_layer_frequency_prescalar
+#ifndef CONF_RTC_TAMP_ACT_LAYER_FREQ_PRES
+#define CONF_RTC_TAMP_ACT_LAYER_FREQ_PRES 0
+#endif
+
+// RTC Tamper Debounce Frequency Prescalar
+// <0x0=>DIV2 CLK_RTC_DEB is CLK_RTC /2
+// <0x1=>DIV4 CLK_RTC_DEB is CLK_RTC /4
+// <0x2=>DIV8 CLK_RTC_DEB is CLK_RTC /8
+// <0x3=>DIV16 CLK_RTC_DEB is CLK_RTC /16
+// <0x4=>DIV32 CLK_RTC_DEB is CLK_RTC /32
+// <0x5=>DIV64 CLK_RTC_DEB is CLK_RTC /64
+// <0x6=>DIV128 CLK_RTC_DEB is CLK_RTC /128
+// <0x7=>DIV256 CLK_RTC_DEB is CLK_RTC /256
+// These bits define the RTC Debounce Frequency Prescalar
+// rtc_tamper_debounce_frequency_prescalar
+#ifndef CONF_RTC_TAMP_DEBF_PRES
+#define CONF_RTC_TAMP_DEBF_PRES 0
+#endif
+
+// Event control
+// rtc_event_control
+#ifndef CONF_RTC_EVENT_CONTROL_ENABLE
+#define CONF_RTC_EVENT_CONTROL_ENABLE 0
+#endif
+
+// Periodic Interval 0 Event Output
+// This bit indicates whether Periodic interval 0 event is enabled and will be generated
+// rtc_pereo0
+#ifndef CONF_RTC_PEREO0
+#define CONF_RTC_PEREO0 0
+#endif
+// Periodic Interval 1 Event Output
+// This bit indicates whether Periodic interval 1 event is enabled and will be generated
+// rtc_pereo1
+#ifndef CONF_RTC_PEREO1
+#define CONF_RTC_PEREO1 0
+#endif
+// Periodic Interval 2 Event Output
+// This bit indicates whether Periodic interval 2 event is enabled and will be generated
+// rtc_pereo2
+#ifndef CONF_RTC_PEREO2
+#define CONF_RTC_PEREO2 0
+#endif
+// Periodic Interval 3 Event Output
+// This bit indicates whether Periodic interval 3 event is enabled and will be generated
+// rtc_pereo3
+#ifndef CONF_RTC_PEREO3
+#define CONF_RTC_PEREO3 0
+#endif
+// Periodic Interval 4 Event Output
+// This bit indicates whether Periodic interval 4 event is enabled and will be generated
+// rtc_pereo4
+#ifndef CONF_RTC_PEREO4
+#define CONF_RTC_PEREO4 0
+#endif
+// Periodic Interval 5 Event Output
+// This bit indicates whether Periodic interval 5 event is enabled and will be generated
+// rtc_pereo5
+#ifndef CONF_RTC_PEREO5
+#define CONF_RTC_PEREO5 0
+#endif
+// Periodic Interval 6 Event Output
+// This bit indicates whether Periodic interval 6 event is enabled and will be generated
+// rtc_pereo6
+#ifndef CONF_RTC_PEREO6
+#define CONF_RTC_PEREO6 0
+#endif
+// Periodic Interval 7 Event Output
+// This bit indicates whether Periodic interval 7 event is enabled and will be generated
+// rtc_pereo7
+#ifndef CONF_RTC_PEREO7
+#define CONF_RTC_PEREO7 0
+#endif
+
+// Compare 0 Event Output
+// This bit indicates whether Compare O event is enabled and will be generated
+// rtc_cmpeo0
+#ifndef CONF_RTC_COMPE0
+#define CONF_RTC_COMPE0 0
+#endif
+
+// Compare 1 Event Output
+// This bit indicates whether Compare 1 event is enabled and will be generated
+// rtc_cmpeo1
+#ifndef CONF_RTC_COMPE1
+#define CONF_RTC_COMPE1 0
+#endif
+// Overflow Event Output
+// This bit indicates whether Overflow event is enabled and will be generated
+// rtc_ovfeo
+#ifndef CONF_RTC_OVFEO
+#define CONF_RTC_OVFEO 0
+#endif
+
+// Tamper Event Output
+// This bit indicates whether Tamper event output is enabled and will be generated
+// rtc_tampereo
+#ifndef CONF_RTC_TAMPEREO
+#define CONF_RTC_TAMPEREO 0
+#endif
+
+// Tamper Event Input
+// This bit indicates whether Tamper event input is enabled and will be generated
+// rtc_tampevei
+#ifndef CONF_RTC_TAMPEVEI
+#define CONF_RTC_TAMPEVEI 0
+#endif
+//
+
+//
+
+// <<< end of configuration section >>>
+
+#endif // HPL_RTC_CONFIG_H
diff --git a/ASF/config/peripheral_clk_config.h b/ASF/config/peripheral_clk_config.h
index 63de678..d103b05 100644
--- a/ASF/config/peripheral_clk_config.h
+++ b/ASF/config/peripheral_clk_config.h
@@ -52,6 +52,22 @@
#define CONF_CPU_FREQUENCY 12000000
#endif
+// RTC Clock Source
+// rtc_clk_selection
+// RTC source
+// Select the clock source for RTC.
+#ifndef CONF_GCLK_RTC_SRC
+#define CONF_GCLK_RTC_SRC RTC_CLOCK_SOURCE
+#endif
+
+/**
+ * \def CONF_GCLK_RTC_FREQUENCY
+ * \brief RTC's Clock frequency
+ */
+#ifndef CONF_GCLK_RTC_FREQUENCY
+#define CONF_GCLK_RTC_FREQUENCY 32768
+#endif
+
// Core Clock Source
// core_gclk_selection
diff --git a/ASF/driver_init.c b/ASF/driver_init.c
index 9be0286..f3b0db4 100644
--- a/ASF/driver_init.c
+++ b/ASF/driver_init.c
@@ -12,7 +12,9 @@
#include
#include
+#include
+struct timer_descriptor TIMER_0;
struct spi_m_sync_descriptor SPI_MRAM;
struct spi_m_sync_descriptor SPI_DISPLAY;
struct spi_m_sync_descriptor SPI_CAMERA;
@@ -51,6 +53,17 @@ void ADC_0_init(void)
adc_sync_init(&ADC_0, ADC1, (void *)NULL);
}
+/**
+ * \brief Timer initialization function
+ *
+ * Enables Timer peripheral, clocks and initializes Timer driver
+ */
+static void TIMER_0_init(void)
+{
+ hri_mclk_set_APBAMASK_RTC_bit(MCLK);
+ timer_init(&TIMER_0, RTC, _rtc_get_timer());
+}
+
void I2C_SBAND_PORT_init(void)
{
@@ -664,6 +677,8 @@ void system_init(void)
ADC_0_init();
+ TIMER_0_init();
+
I2C_SBAND_init();
I2C_MAG_GYRO_init();
diff --git a/ASF/driver_init.h b/ASF/driver_init.h
index 6fe3447..2d2ff08 100644
--- a/ASF/driver_init.h
+++ b/ASF/driver_init.h
@@ -23,6 +23,8 @@ extern "C" {
#include
+#include
+
#include
#include
@@ -39,6 +41,7 @@ extern "C" {
#include
extern struct adc_sync_descriptor ADC_0;
+extern struct timer_descriptor TIMER_0;
extern struct i2c_m_sync_desc I2C_SBAND;
diff --git a/ASF/examples/driver_examples.c b/ASF/examples/driver_examples.c
index 98050a7..1f33c98 100644
--- a/ASF/examples/driver_examples.c
+++ b/ASF/examples/driver_examples.c
@@ -24,6 +24,32 @@ void ADC_0_example(void)
}
}
+static struct timer_task TIMER_0_task1, TIMER_0_task2;
+/**
+ * Example of using TIMER_0.
+ */
+static void TIMER_0_task1_cb(const struct timer_task *const timer_task)
+{
+}
+
+static void TIMER_0_task2_cb(const struct timer_task *const timer_task)
+{
+}
+
+void TIMER_0_example(void)
+{
+ TIMER_0_task1.interval = 100;
+ TIMER_0_task1.cb = TIMER_0_task1_cb;
+ TIMER_0_task1.mode = TIMER_TASK_REPEAT;
+ TIMER_0_task2.interval = 200;
+ TIMER_0_task2.cb = TIMER_0_task2_cb;
+ TIMER_0_task2.mode = TIMER_TASK_REPEAT;
+
+ timer_add_task(&TIMER_0, &TIMER_0_task1);
+ timer_add_task(&TIMER_0, &TIMER_0_task2);
+ timer_start(&TIMER_0);
+}
+
void I2C_SBAND_example(void)
{
struct io_descriptor *I2C_SBAND_io;
diff --git a/ASF/examples/driver_examples.h b/ASF/examples/driver_examples.h
index 9ec905f..3308b86 100644
--- a/ASF/examples/driver_examples.h
+++ b/ASF/examples/driver_examples.h
@@ -14,6 +14,8 @@ extern "C" {
void ADC_0_example(void);
+void TIMER_0_example(void);
+
void I2C_SBAND_example(void);
void I2C_MAG_GYRO_example(void);
diff --git a/ASF/gcc/Makefile b/ASF/gcc/Makefile
index b54d0d5..5579eb6 100644
--- a/ASF/gcc/Makefile
+++ b/ASF/gcc/Makefile
@@ -44,6 +44,7 @@ hal/src \
samd51a/gcc \
hal/utils/src \
hpl/wdt \
+hpl/rtc \
hpl/trng \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/GCC/ARM_CM4F \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang \
@@ -70,12 +71,13 @@ hal/utils/src/utils_syscalls.o \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang/heap_1.o \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/queue.o \
hal/src/hal_spi_m_sync.o \
+hal/src/hal_timer.o \
hal/src/hal_i2c_m_sync.o \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.o \
hal/src/hal_delay.o \
hpl/pm/hpl_pm.o \
hpl/core/hpl_init.o \
-hpl/gclk/hpl_gclk.o \
+hpl/ramecc/hpl_ramecc.o \
hal/src/hal_wdt.o \
hal/utils/src/utils_assert.o \
hpl/dmac/hpl_dmac.o \
@@ -83,24 +85,25 @@ hpl/oscctrl/hpl_oscctrl.o \
hal/src/hal_rand_sync.o \
hpl/trng/hpl_trng.o \
hpl/mclk/hpl_mclk.o \
-hpl/ramecc/hpl_ramecc.o \
+hpl/gclk/hpl_gclk.o \
hal/src/hal_init.o \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/rtos_port.o \
rtos_start.o \
hal/utils/src/utils_list.o \
hpl/osc32kctrl/hpl_osc32kctrl.o \
+hpl/rtc/hpl_rtc.o \
examples/driver_examples.o \
driver_init.o \
hal/src/hal_adc_sync.o \
hpl/sercom/hpl_sercom.o \
+hal/src/hal_atomic.o \
hal/src/hal_gpio.o \
hal/utils/src/utils_event.o \
hal/src/hal_sleep.o \
hal/src/hal_cache.o \
-hpl/cmcc/hpl_cmcc.o \
samd51a/gcc/gcc/startup_samd51.o \
atmel_start.o \
-hal/src/hal_atomic.o \
+hpl/cmcc/hpl_cmcc.o \
thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/tasks.o \
hpl/adc/hpl_adc.o
@@ -119,12 +122,13 @@ OBJS_AS_ARGS += \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/portable/MemMang/heap_1.o" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/queue.o" \
"hal/src/hal_spi_m_sync.o" \
+"hal/src/hal_timer.o" \
"hal/src/hal_i2c_m_sync.o" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.o" \
"hal/src/hal_delay.o" \
"hpl/pm/hpl_pm.o" \
"hpl/core/hpl_init.o" \
-"hpl/gclk/hpl_gclk.o" \
+"hpl/ramecc/hpl_ramecc.o" \
"hal/src/hal_wdt.o" \
"hal/utils/src/utils_assert.o" \
"hpl/dmac/hpl_dmac.o" \
@@ -132,24 +136,25 @@ OBJS_AS_ARGS += \
"hal/src/hal_rand_sync.o" \
"hpl/trng/hpl_trng.o" \
"hpl/mclk/hpl_mclk.o" \
-"hpl/ramecc/hpl_ramecc.o" \
+"hpl/gclk/hpl_gclk.o" \
"hal/src/hal_init.o" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/rtos_port.o" \
"rtos_start.o" \
"hal/utils/src/utils_list.o" \
"hpl/osc32kctrl/hpl_osc32kctrl.o" \
+"hpl/rtc/hpl_rtc.o" \
"examples/driver_examples.o" \
"driver_init.o" \
"hal/src/hal_adc_sync.o" \
"hpl/sercom/hpl_sercom.o" \
+"hal/src/hal_atomic.o" \
"hal/src/hal_gpio.o" \
"hal/utils/src/utils_event.o" \
"hal/src/hal_sleep.o" \
"hal/src/hal_cache.o" \
-"hpl/cmcc/hpl_cmcc.o" \
"samd51a/gcc/gcc/startup_samd51.o" \
"atmel_start.o" \
-"hal/src/hal_atomic.o" \
+"hpl/cmcc/hpl_cmcc.o" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/tasks.o" \
"hpl/adc/hpl_adc.o"
@@ -171,6 +176,7 @@ DIR_INCLUDES += \
-I"../hpl/pm" \
-I"../hpl/port" \
-I"../hpl/ramecc" \
+-I"../hpl/rtc" \
-I"../hpl/sercom" \
-I"../hpl/systick" \
-I"../hpl/trng" \
@@ -204,6 +210,7 @@ DEPS_AS_ARGS += \
"samd51a/gcc/system_samd51.d" \
"hal/src/hal_i2c_m_sync.d" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/timers.d" \
+"hal/src/hal_timer.d" \
"hal/src/hal_spi_m_sync.d" \
"hal/src/hal_wdt.d" \
"hpl/cmcc/hpl_cmcc.d" \
@@ -225,6 +232,7 @@ DEPS_AS_ARGS += \
"hpl/osc32kctrl/hpl_osc32kctrl.d" \
"rtos_start.d" \
"examples/driver_examples.d" \
+"hpl/rtc/hpl_rtc.d" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/list.d" \
"thirdparty/RTOS/freertos/FreeRTOSV10.0.0/Source/queue.d" \
"hal/src/hal_cache.d" \
diff --git a/ASF/hal/documentation/timer.rst b/ASF/hal/documentation/timer.rst
new file mode 100644
index 0000000..c5ca63d
--- /dev/null
+++ b/ASF/hal/documentation/timer.rst
@@ -0,0 +1,52 @@
+============================
+The Timer driver (bare-bone)
+============================
+
+The Timer driver provides means for delayed and periodical function invocation.
+
+A timer task is a piece of code (function) executed at a specific time or periodically by the timer after the task has
+been added to the timers task queue. The execution delay or period is set in ticks, where one tick is defined as a
+configurable number of clock cycles in the hardware timer. Changing the number of clock cycles in a tick automatically
+changes execution delays and periods for all tasks in the timers task queue.
+
+A task has two operation modes, single-shot or repeating mode. In single-shot mode the task is removed from the task queue
+and then is executed once, in repeating mode the task reschedules itself automatically after it has executed based on
+the period set in the task configuration.
+In single-shot mode a task is removed from the task queue before its callback is invoked. It allows an application to
+reuse the memory of expired task in the callback.
+
+Each instance of the Timer driver supports infinite amount of timer tasks, only limited by the amount of RAM available.
+
+Features
+--------
+* Initialization and de-initialization
+* Starting and stopping
+* Timer tasks - periodical invocation of functions
+* Changing and obtaining of the period of a timer
+
+Applications
+------------
+* Delayed and periodical function execution for middle-ware stacks and applications.
+
+Dependencies
+------------
+* Each instance of the driver requires separate hardware timer capable of generating periodic interrupt.
+
+Concurrency
+-----------
+The Timer driver is an interrupt driven driver.This means that the interrupt that triggers a task may occur during
+the process of adding or removing a task via the driver's API. In such case the interrupt processing is postponed
+until the task adding or removing is complete.
+
+The task queue is not protected from the access by interrupts not used by the driver. Due to this
+it is not recommended to add or remove a task from such interrupts: in case if a higher priority interrupt supersedes
+the driver's interrupt, adding or removing a task may cause unpredictable behavior of the driver.
+
+Limitations
+-----------
+* The driver is designed to work outside of an operating system environment, the task queue is therefore processed in interrupt context which may delay execution of other interrupts.
+* If there are a lot of frequently called interrupts with the priority higher than the driver's one, it may cause delay for triggering of a task.
+
+Knows issues and workarounds
+----------------------------
+Not applicable
diff --git a/ASF/hal/include/hal_timer.h b/ASF/hal/include/hal_timer.h
new file mode 100644
index 0000000..43a1ff4
--- /dev/null
+++ b/ASF/hal/include/hal_timer.h
@@ -0,0 +1,206 @@
+/**
+ * \file
+ *
+ * \brief Timer task functionality declaration.
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef _HAL_TIMER_H_INCLUDED
+#define _HAL_TIMER_H_INCLUDED
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \addtogroup doc_driver_hal_timer
+ *
+ * @{
+ */
+
+/**
+ * \brief Timer mode type
+ */
+enum timer_task_mode { TIMER_TASK_ONE_SHOT, TIMER_TASK_REPEAT };
+
+/**
+ * \brief Timer task descriptor
+ *
+ * The timer task descriptor forward declaration.
+ */
+struct timer_task;
+
+/**
+ * \brief Timer task callback function type
+ */
+typedef void (*timer_cb_t)(const struct timer_task *const timer_task);
+
+/**
+ * \brief Timer task structure
+ */
+struct timer_task {
+ struct list_element elem; /*! List element. */
+ uint32_t time_label; /*! Absolute timer start time. */
+
+ uint32_t interval; /*! Number of timer ticks before calling the task. */
+ timer_cb_t cb; /*! Function pointer to the task. */
+ enum timer_task_mode mode; /*! Task mode: one shot or repeat. */
+};
+
+/**
+ * \brief Timer structure
+ */
+struct timer_descriptor {
+ struct _timer_device device;
+ uint32_t time;
+ struct list_descriptor tasks; /*! Timer tasks list. */
+ volatile uint8_t flags;
+};
+
+/**
+ * \brief Initialize timer
+ *
+ * This function initializes the given timer.
+ * It checks if the given hardware is not initialized and if the given hardware
+ * is permitted to be initialized.
+ *
+ * \param[out] descr A timer descriptor to initialize
+ * \param[in] hw The pointer to the hardware instance
+ * \param[in] func The pointer to a set of function pointers
+ *
+ * \return Initialization status.
+ */
+int32_t timer_init(struct timer_descriptor *const descr, void *const hw, struct _timer_hpl_interface *const func);
+
+/**
+ * \brief Deinitialize timer
+ *
+ * This function deinitializes the given timer.
+ * It checks if the given hardware is initialized and if the given hardware is
+ * permitted to be deinitialized.
+ *
+ * \param[in] descr A timer descriptor to deinitialize
+ *
+ * \return De-initialization status.
+ */
+int32_t timer_deinit(struct timer_descriptor *const descr);
+
+/**
+ * \brief Start timer
+ *
+ * This function starts the given timer.
+ * It checks if the given hardware is initialized.
+ *
+ * \param[in] descr The timer descriptor of a timer to start
+ *
+ * \return Timer starting status.
+ */
+int32_t timer_start(struct timer_descriptor *const descr);
+
+/**
+ * \brief Stop timer
+ *
+ * This function stops the given timer.
+ * It checks if the given hardware is initialized.
+ *
+ * \param[in] descr The timer descriptor of a timer to stop
+ *
+ * \return Timer stopping status.
+ */
+int32_t timer_stop(struct timer_descriptor *const descr);
+
+/**
+ * \brief Set amount of clock cycles per timer tick
+ *
+ * This function sets the amount of clock cycles per timer tick for the given timer.
+ * It checks if the given hardware is initialized.
+ *
+ * \param[in] descr The timer descriptor of a timer to stop
+ * \param[in] clock_cycles The amount of clock cycles per tick to set
+ *
+ * \return Setting clock cycles amount status.
+ */
+int32_t timer_set_clock_cycles_per_tick(struct timer_descriptor *const descr, const uint32_t clock_cycles);
+
+/**
+ * \brief Retrieve the amount of clock cycles in a tick
+ *
+ * This function retrieves how many clock cycles there are in a single timer tick.
+ * It checks if the given hardware is initialized.
+ *
+ * \param[in] descr The timer descriptor of a timer to convert ticks to
+ * clock cycles
+ * \param[out] cycles The amount of clock cycles
+ *
+ * \return The status of clock cycles retrieving.
+ */
+int32_t timer_get_clock_cycles_in_tick(const struct timer_descriptor *const descr, uint32_t *const cycles);
+
+/**
+ * \brief Add timer task
+ *
+ * This function adds the given timer task to the given timer.
+ * It checks if the given hardware is initialized.
+ *
+ * \param[in] descr The timer descriptor of a timer to add task to
+ * \param[in] task A task to add
+ *
+ * \return Timer's task adding status.
+ */
+int32_t timer_add_task(struct timer_descriptor *const descr, struct timer_task *const task);
+
+/**
+ * \brief Remove timer task
+ *
+ * This function removes the given timer task from the given timer.
+ * It checks if the given hardware is initialized.
+ *
+ * \param[in] descr The timer descriptor of a timer to remove task from
+ * \param[in] task A task to remove
+ *
+ * \return Timer's task removing status.
+ */
+int32_t timer_remove_task(struct timer_descriptor *const descr, const struct timer_task *const task);
+
+/**
+ * \brief Retrieve the current driver version
+ *
+ * \return Current driver version.
+ */
+uint32_t timer_get_version(void);
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HAL_TIMER_H_INCLUDED */
diff --git a/ASF/hal/include/hpl_calendar.h b/ASF/hal/include/hpl_calendar.h
new file mode 100644
index 0000000..187997a
--- /dev/null
+++ b/ASF/hal/include/hpl_calendar.h
@@ -0,0 +1,321 @@
+/**
+ * \file
+ *
+ * \brief Generic CALENDAR functionality declaration.
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+#ifndef _HPL_CALENDER_H_INCLUDED
+#define _HPL_CALENDER_H_INCLUDED
+
+#include
+#include
+#include "hpl_irq.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Calendar structure
+ *
+ * The Calendar structure forward declaration.
+ */
+struct calendar_dev;
+
+/**
+ * \brief Available mask options for alarms.
+ *
+ * Available mask options for alarms.
+ */
+enum calendar_alarm_option {
+ /** Alarm disabled. */
+ CALENDAR_ALARM_MATCH_DISABLED = 0,
+ /** Alarm match on second. */
+ CALENDAR_ALARM_MATCH_SEC,
+ /** Alarm match on second and minute. */
+ CALENDAR_ALARM_MATCH_MIN,
+ /** Alarm match on second, minute, and hour. */
+ CALENDAR_ALARM_MATCH_HOUR,
+ /** Alarm match on second, minute, hour, and day. */
+ CALENDAR_ALARM_MATCH_DAY,
+ /** Alarm match on second, minute, hour, day, and month. */
+ CALENDAR_ALARM_MATCH_MONTH,
+ /** Alarm match on second, minute, hour, day, month and year. */
+ CALENDAR_ALARM_MATCH_YEAR
+};
+
+/**
+ * \brief Available mode for alarms.
+ */
+enum calendar_alarm_mode { ONESHOT = 1, REPEAT };
+/**
+ * \brief Prototype of callback on alarm match
+ */
+typedef void (*calendar_drv_cb_alarm_t)(struct calendar_dev *const dev);
+
+/**
+ * \brief Prototype of callback on tamper detect
+ */
+typedef void (*tamper_drv_cb_t)(struct calendar_dev *const dev);
+
+/**
+ * \brief Structure of Calendar instance
+ */
+struct calendar_dev {
+ /** Pointer to the hardware base */
+ void *hw;
+ /** Alarm match callback */
+ calendar_drv_cb_alarm_t callback;
+ /** Tamper callback */
+ tamper_drv_cb_t callback_tamper;
+ /** IRQ struct */
+ struct _irq_descriptor irq;
+};
+/**
+ * \brief Time struct for calendar
+ */
+struct calendar_time {
+ /*range from 0 to 59*/
+ uint8_t sec;
+ /*range from 0 to 59*/
+ uint8_t min;
+ /*range from 0 to 23*/
+ uint8_t hour;
+};
+
+/**
+ * \brief Time struct for calendar
+ */
+struct calendar_date {
+ /*range from 1 to 28/29/30/31*/
+ uint8_t day;
+ /*range from 1 to 12*/
+ uint8_t month;
+ /*absolute year>= 1970(such as 2000)*/
+ uint16_t year;
+};
+
+/** \brief Calendar driver struct
+ *
+ */
+struct calendar_descriptor {
+ struct calendar_dev device;
+ struct list_descriptor alarms;
+ /*base date/time = base_year/1/1/0/0/0(year/month/day/hour/min/sec)*/
+ uint32_t base_year;
+ uint8_t flags;
+};
+
+/** \brief Date&Time struct for calendar
+ */
+struct calendar_date_time {
+ struct calendar_time time;
+ struct calendar_date date;
+};
+
+/** \brief struct for alarm time
+ */
+struct _calendar_alarm {
+ struct calendar_date_time datetime;
+ uint32_t timestamp;
+ enum calendar_alarm_option option;
+ enum calendar_alarm_mode mode;
+};
+
+/** \enum for tamper detection mode
+ */
+enum tamper_detection_mode { TAMPER_MODE_OFF = 0U, TAMPER_MODE_WAKE, TAMPER_MODE_CAPTURE, TAMPER_MODE_ACTL };
+
+/** \enum for tamper detection mode
+ */
+enum tamper_id { TAMPID0 = 0U, TAMPID1, TAMPID2, TAMPID3, TAMPID4 };
+/**
+ * \brief Initialize Calendar instance
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_init(struct calendar_dev *const dev);
+
+/**
+ * \brief Deinitialize Calendar instance
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_deinit(struct calendar_dev *const dev);
+
+/**
+ * \brief Enable Calendar instance
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_enable(struct calendar_dev *const dev);
+
+/**
+ * \brief Disable Calendar instance
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_disable(struct calendar_dev *const dev);
+/**
+ * \brief Set time for calendar
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] p_calendar_time Pointer to the time configuration
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_set_time(struct calendar_dev *const dev, struct calendar_time *const p_calendar_time);
+
+/**
+ * \brief Set date for calendar
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] p_calendar_date Pointer to the date configuration
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_set_date(struct calendar_dev *const dev, struct calendar_date *const p_calendar_date);
+
+/**
+ * \brief Get the time for calendar HAL instance and hardware
+ * Retrieve the time from calendar instance.
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] date_time Pointer to value that will be filled with current time
+ *
+ * \return Return current counter value
+ */
+uint32_t _calendar_get_date_time(struct calendar_dev *const dev, struct calendar_date_time *const date_time);
+
+/**
+ * \brief Set compare value for calendar
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] alarm Pointer to the configuration
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_set_alarm(struct calendar_dev *const dev, struct _calendar_alarm *const alarm);
+
+/**
+ * \brief Register callback for calendar alarm
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] callback The pointer to callback function
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _calendar_register_callback(struct calendar_dev *const dev, calendar_drv_cb_alarm_t callback);
+
+/**
+ * \brief Set calendar IRQ
+ *
+ * \param[in] dev The pointer to calendar device struct
+ */
+void _calendar_set_irq(struct calendar_dev *const dev);
+
+/**
+ * \brief Register callback for tamper detection
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] callback The pointer to callback function
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _tamper_register_callback(struct calendar_dev *const dev, tamper_drv_cb_t callback_tamper);
+
+/**
+ * \brief Find tamper is detected on specified pin
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] enum Tamper ID number
+ *
+ * \return true on detection success and false on failure.
+ */
+bool _is_tamper_detected(struct calendar_dev *const dev, enum tamper_id tamper_id_pin);
+
+/**
+ * \brief brief Clear the Tamper ID flag
+ *
+ * \param[in] dev The pointer to calendar device struct
+ * \param[in] enum Tamper ID number
+ *
+ * \return ERR_NONE
+ */
+int32_t _tamper_clear_tampid_flag(struct calendar_dev *const dev, enum tamper_id tamper_id_pin);
+
+/**
+ * \brief Enable Debounce Asynchronous Feature
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _tamper_enable_debounce_asynchronous(struct calendar_dev *const dev);
+
+/**
+ * \brief Disable Tamper Debounce Asynchronous Feature
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _tamper_disable_debounce_asynchronous(struct calendar_dev *const dev);
+
+/**
+ * \brief Enable Tamper Debounce Majority Feature
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _tamper_enable_debounce_majority(struct calendar_dev *const dev);
+
+/**
+ * \brief Enable Tamper Debounce Majority Feature
+ *
+ * \param[in] dev The pointer to calendar device struct
+ *
+ * \return ERR_NONE on success, or an error code on failure.
+ */
+int32_t _tamper_disable_debounce_majority(struct calendar_dev *const dev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HPL_RTC_H_INCLUDED */
diff --git a/ASF/hal/include/hpl_timer.h b/ASF/hal/include/hpl_timer.h
new file mode 100644
index 0000000..9bdfbb7
--- /dev/null
+++ b/ASF/hal/include/hpl_timer.h
@@ -0,0 +1,160 @@
+/**
+ * \file
+ *
+ * \brief Timer related functionality declaration.
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef _HPL_TIMER_H_INCLUDED
+#define _HPL_TIMER_H_INCLUDED
+
+/**
+ * \addtogroup HPL Timer
+ *
+ * \section hpl_timer_rev Revision History
+ * - v1.0.0 Initial Release
+ *
+ *@{
+ */
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Timer device structure
+ *
+ * The Timer device structure forward declaration.
+ */
+struct _timer_device;
+
+/**
+ * \brief Timer interrupt callbacks
+ */
+struct _timer_callbacks {
+ void (*period_expired)(struct _timer_device *device);
+};
+
+/**
+ * \brief Timer device structure
+ */
+struct _timer_device {
+ struct _timer_callbacks timer_cb;
+ struct _irq_descriptor irq;
+ void * hw;
+};
+
+/**
+ * \brief Timer functions, pointers to low-level functions
+ */
+struct _timer_hpl_interface {
+ int32_t (*init)(struct _timer_device *const device, void *const hw);
+ void (*deinit)(struct _timer_device *const device);
+ void (*start_timer)(struct _timer_device *const device);
+ void (*stop_timer)(struct _timer_device *const device);
+ void (*set_timer_period)(struct _timer_device *const device, const uint32_t clock_cycles);
+ uint32_t (*get_period)(const struct _timer_device *const device);
+ bool (*is_timer_started)(const struct _timer_device *const device);
+ void (*set_timer_irq)(struct _timer_device *const device);
+};
+/**
+ * \brief Initialize TCC
+ *
+ * This function does low level TCC configuration.
+ *
+ * \param[in] device The pointer to timer device instance
+ * \param[in] hw The pointer to hardware instance
+ *
+ * \return Initialization status.
+ */
+int32_t _timer_init(struct _timer_device *const device, void *const hw);
+
+/**
+ * \brief Deinitialize TCC
+ *
+ * \param[in] device The pointer to timer device instance
+ */
+void _timer_deinit(struct _timer_device *const device);
+
+/**
+ * \brief Start hardware timer
+ *
+ * \param[in] device The pointer to timer device instance
+ */
+void _timer_start(struct _timer_device *const device);
+
+/**
+ * \brief Stop hardware timer
+ *
+ * \param[in] device The pointer to timer device instance
+ */
+void _timer_stop(struct _timer_device *const device);
+
+/**
+ * \brief Set timer period
+ *
+ * \param[in] device The pointer to timer device instance
+ */
+void _timer_set_period(struct _timer_device *const device, const uint32_t clock_cycles);
+
+/**
+ * \brief Retrieve timer period
+ *
+ * \param[in] device The pointer to timer device instance
+ *
+ * \return Timer period
+ */
+uint32_t _timer_get_period(const struct _timer_device *const device);
+
+/**
+ * \brief Check if timer is running
+ *
+ * \param[in] device The pointer to timer device instance
+ *
+ * \return Check status.
+ * \retval true The given timer is running
+ * \retval false The given timer is not running
+ */
+bool _timer_is_started(const struct _timer_device *const device);
+
+/**
+ * \brief Set timer IRQ
+ *
+ * \param[in] device The pointer to timer device instance
+ */
+void _timer_set_irq(struct _timer_device *const device);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif /* _HPL_TIMER_H_INCLUDED */
diff --git a/ASF/hal/src/hal_timer.c b/ASF/hal/src/hal_timer.c
new file mode 100644
index 0000000..565c6db
--- /dev/null
+++ b/ASF/hal/src/hal_timer.c
@@ -0,0 +1,250 @@
+/**
+ * \file
+ *
+ * \brief Timer functionality implementation.
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#include "hal_timer.h"
+#include
+#include
+#include
+#include
+
+/**
+ * \brief Driver version
+ */
+#define DRIVER_VERSION 0x00000001u
+
+/**
+ * \brief Timer flags
+ */
+#define TIMER_FLAG_QUEUE_IS_TAKEN 1
+#define TIMER_FLAG_INTERRUPT_TRIGERRED 2
+
+static void timer_add_timer_task(struct list_descriptor *list, struct timer_task *const new_task, const uint32_t time);
+static void timer_process_counted(struct _timer_device *device);
+
+/**
+ * \brief Initialize timer
+ */
+int32_t timer_init(struct timer_descriptor *const descr, void *const hw, struct _timer_hpl_interface *const func)
+{
+ ASSERT(descr && hw);
+ _timer_init(&descr->device, hw);
+ descr->time = 0;
+ descr->device.timer_cb.period_expired = timer_process_counted;
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Deinitialize timer
+ */
+int32_t timer_deinit(struct timer_descriptor *const descr)
+{
+ ASSERT(descr);
+ _timer_deinit(&descr->device);
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Start timer
+ */
+int32_t timer_start(struct timer_descriptor *const descr)
+{
+ ASSERT(descr);
+ if (_timer_is_started(&descr->device)) {
+ return ERR_DENIED;
+ }
+ _timer_start(&descr->device);
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Stop timer
+ */
+int32_t timer_stop(struct timer_descriptor *const descr)
+{
+ ASSERT(descr);
+ if (!_timer_is_started(&descr->device)) {
+ return ERR_DENIED;
+ }
+ _timer_stop(&descr->device);
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Set amount of clock cycler per timer tick
+ */
+int32_t timer_set_clock_cycles_per_tick(struct timer_descriptor *const descr, const uint32_t clock_cycles)
+{
+ ASSERT(descr);
+ _timer_set_period(&descr->device, clock_cycles);
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Add timer task
+ */
+int32_t timer_add_task(struct timer_descriptor *const descr, struct timer_task *const task)
+{
+ ASSERT(descr && task);
+
+ descr->flags |= TIMER_FLAG_QUEUE_IS_TAKEN;
+ if (is_list_element(&descr->tasks, task)) {
+ descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
+ ASSERT(false);
+ return ERR_ALREADY_INITIALIZED;
+ }
+ task->time_label = descr->time;
+ timer_add_timer_task(&descr->tasks, task, descr->time);
+
+ descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
+ if (descr->flags & TIMER_FLAG_INTERRUPT_TRIGERRED) {
+ CRITICAL_SECTION_ENTER()
+ descr->flags &= ~TIMER_FLAG_INTERRUPT_TRIGERRED;
+ _timer_set_irq(&descr->device);
+ CRITICAL_SECTION_LEAVE()
+ }
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Remove timer task
+ */
+int32_t timer_remove_task(struct timer_descriptor *const descr, const struct timer_task *const task)
+{
+ ASSERT(descr && task);
+
+ descr->flags |= TIMER_FLAG_QUEUE_IS_TAKEN;
+ if (!is_list_element(&descr->tasks, task)) {
+ descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
+ ASSERT(false);
+ return ERR_NOT_FOUND;
+ }
+ list_delete_element(&descr->tasks, task);
+
+ descr->flags &= ~TIMER_FLAG_QUEUE_IS_TAKEN;
+ if (descr->flags & TIMER_FLAG_INTERRUPT_TRIGERRED) {
+ CRITICAL_SECTION_ENTER()
+ descr->flags &= ~TIMER_FLAG_INTERRUPT_TRIGERRED;
+ _timer_set_irq(&descr->device);
+ CRITICAL_SECTION_LEAVE()
+ }
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief Retrieve the amount of clock cycles in a tick
+ */
+int32_t timer_get_clock_cycles_in_tick(const struct timer_descriptor *const descr, uint32_t *const cycles)
+{
+ ASSERT(descr && cycles);
+ *cycles = _timer_get_period(&descr->device);
+ return ERR_NONE;
+}
+
+/**
+ * \brief Retrieve the current driver version
+ */
+uint32_t timer_get_version(void)
+{
+ return DRIVER_VERSION;
+}
+
+/**
+ * \internal Insert a timer task into sorted timer's list
+ *
+ * \param[in] head The pointer to the head of timer task list
+ * \param[in] task The pointer to task to add
+ * \param[in] time Current timer time
+ */
+static void timer_add_timer_task(struct list_descriptor *list, struct timer_task *const new_task, const uint32_t time)
+{
+ struct timer_task *it, *prev = NULL, *head = (struct timer_task *)list_get_head(list);
+
+ if (!head) {
+ list_insert_as_head(list, new_task);
+ return;
+ }
+
+ for (it = head; it; it = (struct timer_task *)list_get_next_element(it)) {
+ uint32_t time_left;
+
+ if (it->time_label <= time) {
+ time_left = it->interval - (time - it->time_label);
+ } else {
+ time_left = it->interval - (0xFFFFFFFF - it->time_label) - time;
+ }
+ if (time_left >= new_task->interval)
+ break;
+ prev = it;
+ }
+
+ if (it == head) {
+ list_insert_as_head(list, new_task);
+ } else {
+ list_insert_after(prev, new_task);
+ }
+}
+
+/**
+ * \internal Process interrupts
+ */
+static void timer_process_counted(struct _timer_device *device)
+{
+ struct timer_descriptor *timer = CONTAINER_OF(device, struct timer_descriptor, device);
+ struct timer_task * it = (struct timer_task *)list_get_head(&timer->tasks);
+ uint32_t time = ++timer->time;
+
+ if ((timer->flags & TIMER_FLAG_QUEUE_IS_TAKEN) || (timer->flags & TIMER_FLAG_INTERRUPT_TRIGERRED)) {
+ timer->flags |= TIMER_FLAG_INTERRUPT_TRIGERRED;
+ return;
+ }
+
+ while (it && ((time - it->time_label) >= it->interval)) {
+ struct timer_task *tmp = it;
+
+ list_remove_head(&timer->tasks);
+ if (TIMER_TASK_REPEAT == tmp->mode) {
+ tmp->time_label = time;
+ timer_add_timer_task(&timer->tasks, tmp, time);
+ }
+ it = (struct timer_task *)list_get_head(&timer->tasks);
+
+ tmp->cb(tmp);
+ }
+}
diff --git a/ASF/hal/utils/include/utils_decrement_macro.h b/ASF/hal/utils/include/utils_decrement_macro.h
new file mode 100644
index 0000000..2b52469
--- /dev/null
+++ b/ASF/hal/utils/include/utils_decrement_macro.h
@@ -0,0 +1,309 @@
+/**
+ * \file
+ *
+ * \brief Decrement macro.
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef _UTILS_DECREMENT_MACRO_H
+#define _UTILS_DECREMENT_MACRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Compile time decrement, result value is entire integer literal
+ *
+ * \param[in] val - value to be decremented
+ */
+#define DEC_VALUE(val) DEC_##val
+
+// Preprocessor increment implementation
+#define DEC_256 255
+#define DEC_255 254
+#define DEC_254 253
+#define DEC_253 252
+#define DEC_252 251
+#define DEC_251 250
+#define DEC_250 249
+#define DEC_249 248
+#define DEC_248 247
+#define DEC_247 246
+#define DEC_246 245
+#define DEC_245 244
+#define DEC_244 243
+#define DEC_243 242
+#define DEC_242 241
+#define DEC_241 240
+#define DEC_240 239
+#define DEC_239 238
+#define DEC_238 237
+#define DEC_237 236
+#define DEC_236 235
+#define DEC_235 234
+#define DEC_234 233
+#define DEC_233 232
+#define DEC_232 231
+#define DEC_231 230
+#define DEC_230 229
+#define DEC_229 228
+#define DEC_228 227
+#define DEC_227 226
+#define DEC_226 225
+#define DEC_225 224
+#define DEC_224 223
+#define DEC_223 222
+#define DEC_222 221
+#define DEC_221 220
+#define DEC_220 219
+#define DEC_219 218
+#define DEC_218 217
+#define DEC_217 216
+#define DEC_216 215
+#define DEC_215 214
+#define DEC_214 213
+#define DEC_213 212
+#define DEC_212 211
+#define DEC_211 210
+#define DEC_210 209
+#define DEC_209 208
+#define DEC_208 207
+#define DEC_207 206
+#define DEC_206 205
+#define DEC_205 204
+#define DEC_204 203
+#define DEC_203 202
+#define DEC_202 201
+#define DEC_201 200
+#define DEC_200 199
+#define DEC_199 198
+#define DEC_198 197
+#define DEC_197 196
+#define DEC_196 195
+#define DEC_195 194
+#define DEC_194 193
+#define DEC_193 192
+#define DEC_192 191
+#define DEC_191 190
+#define DEC_190 189
+#define DEC_189 188
+#define DEC_188 187
+#define DEC_187 186
+#define DEC_186 185
+#define DEC_185 184
+#define DEC_184 183
+#define DEC_183 182
+#define DEC_182 181
+#define DEC_181 180
+#define DEC_180 179
+#define DEC_179 178
+#define DEC_178 177
+#define DEC_177 176
+#define DEC_176 175
+#define DEC_175 174
+#define DEC_174 173
+#define DEC_173 172
+#define DEC_172 171
+#define DEC_171 170
+#define DEC_170 169
+#define DEC_169 168
+#define DEC_168 167
+#define DEC_167 166
+#define DEC_166 165
+#define DEC_165 164
+#define DEC_164 163
+#define DEC_163 162
+#define DEC_162 161
+#define DEC_161 160
+#define DEC_160 159
+#define DEC_159 158
+#define DEC_158 157
+#define DEC_157 156
+#define DEC_156 155
+#define DEC_155 154
+#define DEC_154 153
+#define DEC_153 152
+#define DEC_152 151
+#define DEC_151 150
+#define DEC_150 149
+#define DEC_149 148
+#define DEC_148 147
+#define DEC_147 146
+#define DEC_146 145
+#define DEC_145 144
+#define DEC_144 143
+#define DEC_143 142
+#define DEC_142 141
+#define DEC_141 140
+#define DEC_140 139
+#define DEC_139 138
+#define DEC_138 137
+#define DEC_137 136
+#define DEC_136 135
+#define DEC_135 134
+#define DEC_134 133
+#define DEC_133 132
+#define DEC_132 131
+#define DEC_131 130
+#define DEC_130 129
+#define DEC_129 128
+#define DEC_128 127
+#define DEC_127 126
+#define DEC_126 125
+#define DEC_125 124
+#define DEC_124 123
+#define DEC_123 122
+#define DEC_122 121
+#define DEC_121 120
+#define DEC_120 119
+#define DEC_119 118
+#define DEC_118 117
+#define DEC_117 116
+#define DEC_116 115
+#define DEC_115 114
+#define DEC_114 113
+#define DEC_113 112
+#define DEC_112 111
+#define DEC_111 110
+#define DEC_110 109
+#define DEC_109 108
+#define DEC_108 107
+#define DEC_107 106
+#define DEC_106 105
+#define DEC_105 104
+#define DEC_104 103
+#define DEC_103 102
+#define DEC_102 101
+#define DEC_101 100
+#define DEC_100 99
+#define DEC_99 98
+#define DEC_98 97
+#define DEC_97 96
+#define DEC_96 95
+#define DEC_95 94
+#define DEC_94 93
+#define DEC_93 92
+#define DEC_92 91
+#define DEC_91 90
+#define DEC_90 89
+#define DEC_89 88
+#define DEC_88 87
+#define DEC_87 86
+#define DEC_86 85
+#define DEC_85 84
+#define DEC_84 83
+#define DEC_83 82
+#define DEC_82 81
+#define DEC_81 80
+#define DEC_80 79
+#define DEC_79 78
+#define DEC_78 77
+#define DEC_77 76
+#define DEC_76 75
+#define DEC_75 74
+#define DEC_74 73
+#define DEC_73 72
+#define DEC_72 71
+#define DEC_71 70
+#define DEC_70 69
+#define DEC_69 68
+#define DEC_68 67
+#define DEC_67 66
+#define DEC_66 65
+#define DEC_65 64
+#define DEC_64 63
+#define DEC_63 62
+#define DEC_62 61
+#define DEC_61 60
+#define DEC_60 59
+#define DEC_59 58
+#define DEC_58 57
+#define DEC_57 56
+#define DEC_56 55
+#define DEC_55 54
+#define DEC_54 53
+#define DEC_53 52
+#define DEC_52 51
+#define DEC_51 50
+#define DEC_50 49
+#define DEC_49 48
+#define DEC_48 47
+#define DEC_47 46
+#define DEC_46 45
+#define DEC_45 44
+#define DEC_44 43
+#define DEC_43 42
+#define DEC_42 41
+#define DEC_41 40
+#define DEC_40 39
+#define DEC_39 38
+#define DEC_38 37
+#define DEC_37 36
+#define DEC_36 35
+#define DEC_35 34
+#define DEC_34 33
+#define DEC_33 32
+#define DEC_32 31
+#define DEC_31 30
+#define DEC_30 29
+#define DEC_29 28
+#define DEC_28 27
+#define DEC_27 26
+#define DEC_26 25
+#define DEC_25 24
+#define DEC_24 23
+#define DEC_23 22
+#define DEC_22 21
+#define DEC_21 20
+#define DEC_20 19
+#define DEC_19 18
+#define DEC_18 17
+#define DEC_17 16
+#define DEC_16 15
+#define DEC_15 14
+#define DEC_14 13
+#define DEC_13 12
+#define DEC_12 11
+#define DEC_11 10
+#define DEC_10 9
+#define DEC_9 8
+#define DEC_8 7
+#define DEC_7 6
+#define DEC_6 5
+#define DEC_5 4
+#define DEC_4 3
+#define DEC_3 2
+#define DEC_2 1
+#define DEC_1 0
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _UTILS_DECREMENT_MACRO_H */
diff --git a/ASF/hal/utils/include/utils_recursion_macro.h b/ASF/hal/utils/include/utils_recursion_macro.h
new file mode 100644
index 0000000..294314c
--- /dev/null
+++ b/ASF/hal/utils/include/utils_recursion_macro.h
@@ -0,0 +1,69 @@
+/**
+ * \file
+ *
+ * \brief Recursion macro.
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef _UTILS_RECURSION_MACRO_H
+#define _UTILS_RECURSION_MACRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * \brief Macro recursion
+ *
+ * \param[in] macro Macro to be repeated recursively
+ * \param[in] arg A recursive threshold, building on this to decline by times
+ * defined with parameter n
+ * \param[in] n The number of repetitious calls to macro
+ */
+#define RECURSION_MACRO(macro, arg, n) RECURSION_MACRO_I(macro, arg, n)
+
+/*
+ * \brief Second level is needed to get integer literal from "n" if it is
+ * defined as macro
+ */
+#define RECURSION_MACRO_I(macro, arg, n) RECURSION##n(macro, arg)
+
+#define RECURSION0(macro, arg)
+#define RECURSION1(macro, arg) RECURSION0(macro, DEC_VALUE(arg)) macro(arg, 0)
+#define RECURSION2(macro, arg) RECURSION1(macro, DEC_VALUE(arg)) macro(arg, 1)
+#define RECURSION3(macro, arg) RECURSION2(macro, DEC_VALUE(arg)) macro(arg, 2)
+#define RECURSION4(macro, arg) RECURSION3(macro, DEC_VALUE(arg)) macro(arg, 3)
+#define RECURSION5(macro, arg) RECURSION4(macro, DEC_VALUE(arg)) macro(arg, 4)
+
+#ifdef __cplusplus
+}
+#endif
+
+#include
+#endif /* _UTILS_RECURSION_MACRO_H */
diff --git a/ASF/hpl/rtc/hpl_rtc.c b/ASF/hpl/rtc/hpl_rtc.c
new file mode 100644
index 0000000..0b52541
--- /dev/null
+++ b/ASF/hpl/rtc/hpl_rtc.c
@@ -0,0 +1,177 @@
+
+/**
+ * \file
+ *
+ * \brief RTC Driver
+ *
+ * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#include
+#include
+#include
+#include
+
+/*!< Pointer to hpl device */
+static struct _timer_device *_rtc_dev = NULL;
+
+/**
+ * \brief Initialize Timer
+ */
+int32_t _timer_init(struct _timer_device *const dev, void *const hw)
+{
+ ASSERT(dev);
+
+ dev->hw = hw;
+
+ hri_rtcmode0_write_CTRLA_reg(dev->hw, RTC_MODE0_CTRLA_SWRST);
+ hri_rtcmode0_wait_for_sync(dev->hw, RTC_MODE0_SYNCBUSY_SWRST);
+
+#if CONF_RTC_EVENT_CONTROL_ENABLE == 1
+ hri_rtcmode0_write_EVCTRL_reg(
+ dev->hw,
+ (CONF_RTC_PEREO0 << RTC_MODE0_EVCTRL_PEREO0_Pos) | (CONF_RTC_PEREO1 << RTC_MODE0_EVCTRL_PEREO1_Pos)
+ | (CONF_RTC_PEREO2 << RTC_MODE0_EVCTRL_PEREO2_Pos) | (CONF_RTC_PEREO3 << RTC_MODE0_EVCTRL_PEREO3_Pos)
+ | (CONF_RTC_PEREO4 << RTC_MODE0_EVCTRL_PEREO4_Pos) | (CONF_RTC_PEREO5 << RTC_MODE0_EVCTRL_PEREO5_Pos)
+ | (CONF_RTC_PEREO6 << RTC_MODE0_EVCTRL_PEREO6_Pos) | (CONF_RTC_PEREO7 << RTC_MODE0_EVCTRL_PEREO7_Pos)
+ | (CONF_RTC_COMPE0 << RTC_MODE0_EVCTRL_CMPEO_Pos) | (CONF_RTC_COMPE1 << RTC_MODE0_EVCTRL_CMPEO1_Pos)
+ | (CONF_RTC_TAMPEREO << RTC_MODE0_EVCTRL_TAMPEREO_Pos)
+ | (CONF_RTC_TAMPEVEI << RTC_MODE0_EVCTRL_TAMPEVEI_Pos) | (CONF_RTC_OVFEO << RTC_MODE0_EVCTRL_OVFEO_Pos));
+#endif
+
+ hri_rtcmode0_write_CTRLA_reg(
+ dev->hw, RTC_MODE0_CTRLA_PRESCALER(CONF_RTC_PRESCALER) | RTC_MODE0_CTRLA_COUNTSYNC | RTC_MODE0_CTRLA_MATCHCLR);
+ hri_rtcmode0_write_COMP_reg(dev->hw, 0, CONF_RTC_COMP_VAL);
+ hri_rtcmode0_set_INTEN_CMP0_bit(dev->hw);
+
+ _rtc_dev = dev;
+
+ return ERR_NONE;
+}
+
+/**
+ * \brief De-initialize Timer
+ */
+void _timer_deinit(struct _timer_device *const dev)
+{
+ ASSERT(dev && dev->hw);
+
+ NVIC_DisableIRQ(RTC_IRQn);
+
+ hri_rtcmode0_write_CTRLA_reg(dev->hw, RTC_MODE0_CTRLA_SWRST);
+}
+
+/**
+ * \brief Start hardware timer
+ */
+void _timer_start(struct _timer_device *const dev)
+{
+ ASSERT(dev && dev->hw);
+
+ NVIC_EnableIRQ(RTC_IRQn);
+ hri_rtcmode0_write_COUNT_reg(dev->hw, 0);
+ hri_rtcmode0_wait_for_sync(dev->hw, RTC_MODE0_SYNCBUSY_COUNT);
+ hri_rtcmode0_set_CTRLA_ENABLE_bit(dev->hw);
+}
+
+/**
+ * \brief Stop hardware timer
+ */
+void _timer_stop(struct _timer_device *const dev)
+{
+ ASSERT(dev && dev->hw);
+
+ hri_rtcmode0_clear_CTRLA_ENABLE_bit(dev->hw);
+}
+
+/**
+ * \brief Set timer period
+ */
+void _timer_set_period(struct _timer_device *const dev, const uint32_t clock_cycles)
+{
+ hri_rtcmode0_write_COMP_reg(dev->hw, 0, clock_cycles);
+}
+
+/**
+ * \brief Retrieve timer period
+ */
+uint32_t _timer_get_period(const struct _timer_device *const dev)
+{
+ return hri_rtcmode0_read_COMP_reg(dev->hw, 0);
+}
+
+/**
+ * \brief Check if timer is running
+ */
+bool _timer_is_started(const struct _timer_device *const dev)
+{
+ return hri_rtcmode0_get_CTRLA_ENABLE_bit(dev->hw);
+}
+
+/**
+ * \brief Set timer IRQ
+ */
+void _timer_set_irq(struct _timer_device *const dev)
+{
+ (void)dev;
+}
+
+/**
+ * \brief RTC Timer interrupt handler
+ *
+ * \param[in] p The pointer to calendar device struct
+ */
+static void _rtc_timer_interrupt_handler(struct _timer_device *dev)
+{
+ /* Read and mask interrupt flag register */
+ uint16_t flag = hri_rtcmode0_read_INTFLAG_reg(dev->hw);
+
+ if (flag & RTC_MODE0_INTFLAG_CMP0) {
+ if (dev->timer_cb.period_expired) {
+ dev->timer_cb.period_expired(dev);
+ }
+ /* Clear interrupt flag */
+ hri_rtcmode0_clear_interrupt_CMP0_bit(dev->hw);
+ }
+}
+
+/**
+ * \brief Retrieve timer helper functions
+ */
+struct _timer_hpl_interface *_rtc_get_timer(void)
+{
+ return NULL;
+}
+
+/**
+ * \brief Rtc interrupt handler
+ */
+void RTC_Handler(void)
+{
+ _rtc_timer_interrupt_handler(_rtc_dev);
+}
diff --git a/ASF/hpl/rtc/hpl_rtc_base.h b/ASF/hpl/rtc/hpl_rtc_base.h
new file mode 100644
index 0000000..06e3bd7
--- /dev/null
+++ b/ASF/hpl/rtc/hpl_rtc_base.h
@@ -0,0 +1,52 @@
+/**
+ * \file
+ *
+ * \brief RTC
+ *
+ * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ */
+
+#ifndef _HPL_RTC2_V200_H_INCLUDED
+#define _HPL_RTC2_V200_H_INCLUDED
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Retrieve timer helper functions
+ *
+ * \return A pointer to set of timer helper functions
+ */
+struct _timer_hpl_interface *_rtc_get_timer(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _HPL_RTC2_V200_H_INCLUDED */
diff --git a/ASF/samd51a/armcc/Device/SAMD51/Source/ARM/startup_samd51.s b/ASF/samd51a/armcc/Device/SAMD51/Source/ARM/startup_samd51.s
deleted file mode 100644
index 0cbc9e3..0000000
--- a/ASF/samd51a/armcc/Device/SAMD51/Source/ARM/startup_samd51.s
+++ /dev/null
@@ -1,588 +0,0 @@
-;/*****************************************************************************
-; * @file startup_samd51.s
-; * @brief CMSIS Cortex-M4 Core Device Startup File for
-; * Atmel SAMD51 Device Series
-; * @version V1.0.0
-; * @date 13. January 2017
-; *
-; * @note
-; * Copyright (C) 2017 ARM Limited. All rights reserved.
-; *
-; * @par
-; * ARM Limited (ARM) is supplying this software for use with Cortex-M
-; * processor based microcontrollers. This file can be freely distributed
-; * within development tools that are supporting such ARM based processors.
-; *
-; * @par
-; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
-; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
-; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
-; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
-; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
-; *
-; ******************************************************************************/
-;/*
-;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
-;*/
-
-
-; Stack Configuration
-; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Stack_Size EQU 0x00000200
-
- AREA STACK, NOINIT, READWRITE, ALIGN=3
-Stack_Mem SPACE Stack_Size
-__initial_sp
-
-
-; Heap Configuration
-; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
-;
-
-Heap_Size EQU 0x00000000
-
- AREA HEAP, NOINIT, READWRITE, ALIGN=3
-__heap_base
-Heap_Mem SPACE Heap_Size
-__heap_limit
-
-
- PRESERVE8
- THUMB
-
-
-; Vector Table Mapped to Address 0 at Reset
-
- AREA RESET, DATA, READONLY
- EXPORT __Vectors
- EXPORT __Vectors_End
- EXPORT __Vectors_Size
-
-__Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD 0 ; Reserved
- DCD SVC_Handler ; SVCall Handler
- DCD DebugMon_Handler ; Debug Monitor Handler
- DCD 0 ; Reserved
- DCD PendSV_Handler ; PendSV Handler
- DCD SysTick_Handler ; SysTick Handler
-
- ; External Interrupts
- DCD PM_Handler ; 0 Power Manager
- DCD MCLK_Handler ; 1 Main Clock
- DCD OSCCTRL_0_Handler ; 2 OSCCTRL_XOSCFAIL_0, OSCCTRL_XOSCRDY_0
- DCD OSCCTRL_1_Handler ; 3 OSCCTRL_XOSCFAIL_1, OSCCTRL_XOSCRDY_1
- DCD OSCCTRL_2_Handler ; 4 OSCCTRL_DFLLLOCKC, OSCCTRL_DFLLLOCKF, OSCCTRL_DFLLOOB, OSCCTRL_DFLLRCS, OSCCTRL_DFLLRDY
- DCD OSCCTRL_3_Handler ; 5 OSCCTRL_DPLLLCKF_0, OSCCTRL_DPLLLCKR_0, OSCCTRL_DPLLLDRTO_0, OSCCTRL_DPLLLTO_0
- DCD OSCCTRL_4_Handler ; 6 OSCCTRL_DPLLLCKF_1, OSCCTRL_DPLLLCKR_1, OSCCTRL_DPLLLDRTO_1, OSCCTRL_DPLLLTO_1
- DCD OSC32KCTRL_Handler ; 7 32kHz Oscillators Control
- DCD SUPC_0_Handler ; 8 SUPC_B12SRDY, SUPC_B33SRDY, SUPC_BOD12RDY, SUPC_BOD33RDY, SUPC_VCORERDY, SUPC_VREGRDY
- DCD SUPC_1_Handler ; 9 SUPC_BOD12DET, SUPC_BOD33DET
- DCD WDT_Handler ; 10 Watchdog Timer
- DCD RTC_Handler ; 11 Real-Time Counter
- DCD EIC_0_Handler ; 12 EIC_EXTINT_0
- DCD EIC_1_Handler ; 13 EIC_EXTINT_1
- DCD EIC_2_Handler ; 14 EIC_EXTINT_2
- DCD EIC_3_Handler ; 15 EIC_EXTINT_3
- DCD EIC_4_Handler ; 16 EIC_EXTINT_4
- DCD EIC_5_Handler ; 17 EIC_EXTINT_5
- DCD EIC_6_Handler ; 18 EIC_EXTINT_6
- DCD EIC_7_Handler ; 19 EIC_EXTINT_7
- DCD EIC_8_Handler ; 20 EIC_EXTINT_8
- DCD EIC_9_Handler ; 21 EIC_EXTINT_9
- DCD EIC_10_Handler ; 22 EIC_EXTINT_10
- DCD EIC_11_Handler ; 23 EIC_EXTINT_11
- DCD EIC_12_Handler ; 24 EIC_EXTINT_12
- DCD EIC_13_Handler ; 25 EIC_EXTINT_13
- DCD EIC_14_Handler ; 26 EIC_EXTINT_14
- DCD EIC_15_Handler ; 27 EIC_EXTINT_15
- DCD FREQM_Handler ; 28 Frequency Meter
- DCD NVMCTRL_0_Handler ; 29 NVMCTRL_0, NVMCTRL_1, NVMCTRL_2, NVMCTRL_3, NVMCTRL_4, NVMCTRL_5, NVMCTRL_6, NVMCTRL_7
- DCD NVMCTRL_1_Handler ; 30 NVMCTRL_10, NVMCTRL_8, NVMCTRL_9
- DCD DMAC_0_Handler ; 31 DMAC_SUSP_0, DMAC_TCMPL_0, DMAC_TERR_0
- DCD DMAC_1_Handler ; 32 DMAC_SUSP_1, DMAC_TCMPL_1, DMAC_TERR_1
- DCD DMAC_2_Handler ; 33 DMAC_SUSP_2, DMAC_TCMPL_2, DMAC_TERR_2
- DCD DMAC_3_Handler ; 34 DMAC_SUSP_3, DMAC_TCMPL_3, DMAC_TERR_3
- DCD DMAC_4_Handler ; 35 DMAC_SUSP_10, DMAC_SUSP_11, DMAC_SUSP_12, DMAC_SUSP_13, DMAC_SUSP_14, DMAC_SUSP_15, DMAC_SUSP_16, DMAC_SUSP_17, DMAC_SUSP_18, DMAC_SUSP_19, DMAC_SUSP_20, DMAC_SUSP_21, DMAC_SUSP_22, DMAC_SUSP_23, DMAC_SUSP_24, DMAC_SUSP_25, DMAC_SUSP_26, DMAC_SUSP_27, DMAC_SUSP_28, DMAC_SUSP_29, DMAC_SUSP_30, DMAC_SUSP_31, DMAC_SUSP_4, DMAC_SUSP_5, DMAC_SUSP_6, DMAC_SUSP_7, DMAC_SUSP_8, DMAC_SUSP_9, DMAC_TCMPL_10, DMAC_TCMPL_11, DMAC_TCMPL_12, DMAC_TCMPL_13, DMAC_TCMPL_14, DMAC_TCMPL_15, DMAC_TCMPL_16, DMAC_TCMPL_17, DMAC_TCMPL_18, DMAC_TCMPL_19, DMAC_TCMPL_20, DMAC_TCMPL_21, DMAC_TCMPL_22, DMAC_TCMPL_23, DMAC_TCMPL_24, DMAC_TCMPL_25, DMAC_TCMPL_26, DMAC_TCMPL_27, DMAC_TCMPL_28, DMAC_TCMPL_29, DMAC_TCMPL_30, DMAC_TCMPL_31, DMAC_TCMPL_4, DMAC_TCMPL_5, DMAC_TCMPL_6, DMAC_TCMPL_7, DMAC_TCMPL_8, DMAC_TCMPL_9, DMAC_TERR_10, DMAC_TERR_11, DMAC_TERR_12, DMAC_TERR_13, DMAC_TERR_14, DMAC_TERR_15, DMAC_TERR_16, DMAC_TERR_17, DMAC_TERR_18, DMAC_TERR_19, DMAC_TERR_20, DMAC_TERR_21, DMAC_TERR_22, DMAC_TERR_23, DMAC_TERR_24, DMAC_TERR_25, DMAC_TERR_26, DMAC_TERR_27, DMAC_TERR_28, DMAC_TERR_29, DMAC_TERR_30, DMAC_TERR_31, DMAC_TERR_4, DMAC_TERR_5, DMAC_TERR_6, DMAC_TERR_7, DMAC_TERR_8, DMAC_TERR_9
- DCD EVSYS_0_Handler ; 36 EVSYS_EVD_0, EVSYS_OVR_0
- DCD EVSYS_1_Handler ; 37 EVSYS_EVD_1, EVSYS_OVR_1
- DCD EVSYS_2_Handler ; 38 EVSYS_EVD_2, EVSYS_OVR_2
- DCD EVSYS_3_Handler ; 39 EVSYS_EVD_3, EVSYS_OVR_3
- DCD EVSYS_4_Handler ; 40 EVSYS_EVD_10, EVSYS_EVD_11, EVSYS_EVD_4, EVSYS_EVD_5, EVSYS_EVD_6, EVSYS_EVD_7, EVSYS_EVD_8, EVSYS_EVD_9, EVSYS_OVR_10, EVSYS_OVR_11, EVSYS_OVR_4, EVSYS_OVR_5, EVSYS_OVR_6, EVSYS_OVR_7, EVSYS_OVR_8, EVSYS_OVR_9
- DCD PAC_Handler ; 41 Peripheral Access Controller
- DCD TAL_0_Handler ; 42 TAL_BRK
- DCD TAL_1_Handler ; 43 TAL_IPS_0, TAL_IPS_1
- DCD 0 ; 44 Reserved
- DCD RAMECC_Handler ; 45 RAM ECC
- DCD SERCOM0_0_Handler ; 46 SERCOM0_0
- DCD SERCOM0_1_Handler ; 47 SERCOM0_1
- DCD SERCOM0_2_Handler ; 48 SERCOM0_2
- DCD SERCOM0_3_Handler ; 49 SERCOM0_3, SERCOM0_4, SERCOM0_5, SERCOM0_6
- DCD SERCOM1_0_Handler ; 50 SERCOM1_0
- DCD SERCOM1_1_Handler ; 51 SERCOM1_1
- DCD SERCOM1_2_Handler ; 52 SERCOM1_2
- DCD SERCOM1_3_Handler ; 53 SERCOM1_3, SERCOM1_4, SERCOM1_5, SERCOM1_6
- DCD SERCOM2_0_Handler ; 54 SERCOM2_0
- DCD SERCOM2_1_Handler ; 55 SERCOM2_1
- DCD SERCOM2_2_Handler ; 56 SERCOM2_2
- DCD SERCOM2_3_Handler ; 57 SERCOM2_3, SERCOM2_4, SERCOM2_5, SERCOM2_6
- DCD SERCOM3_0_Handler ; 58 SERCOM3_0
- DCD SERCOM3_1_Handler ; 59 SERCOM3_1
- DCD SERCOM3_2_Handler ; 60 SERCOM3_2
- DCD SERCOM3_3_Handler ; 61 SERCOM3_3, SERCOM3_4, SERCOM3_5, SERCOM3_6
- DCD SERCOM4_0_Handler ; 62 SERCOM4_0
- DCD SERCOM4_1_Handler ; 63 SERCOM4_1
- DCD SERCOM4_2_Handler ; 64 SERCOM4_2
- DCD SERCOM4_3_Handler ; 65 SERCOM4_3, SERCOM4_4, SERCOM4_5, SERCOM4_6
- DCD SERCOM5_0_Handler ; 66 SERCOM5_0
- DCD SERCOM5_1_Handler ; 67 SERCOM5_1
- DCD SERCOM5_2_Handler ; 68 SERCOM5_2
- DCD SERCOM5_3_Handler ; 69 SERCOM5_3, SERCOM5_4, SERCOM5_5, SERCOM5_6
- DCD SERCOM6_0_Handler ; 70 SERCOM6_0
- DCD SERCOM6_1_Handler ; 71 SERCOM6_1
- DCD SERCOM6_2_Handler ; 72 SERCOM6_2
- DCD SERCOM6_3_Handler ; 73 SERCOM6_3, SERCOM6_4, SERCOM6_5, SERCOM6_6
- DCD SERCOM7_0_Handler ; 74 SERCOM7_0
- DCD SERCOM7_1_Handler ; 75 SERCOM7_1
- DCD SERCOM7_2_Handler ; 76 SERCOM7_2
- DCD SERCOM7_3_Handler ; 77 SERCOM7_3, SERCOM7_4, SERCOM7_5, SERCOM7_6
- DCD CAN0_Handler ; 78 Control Area Network 0
- DCD CAN1_Handler ; 79 Control Area Network 1
- DCD USB_0_Handler ; 80 USB_EORSM_DNRSM, USB_EORST_RST, USB_LPMSUSP_DDISC, USB_LPM_DCONN, USB_MSOF, USB_RAMACER, USB_RXSTP_TXSTP_0, USB_RXSTP_TXSTP_1, USB_RXSTP_TXSTP_2, USB_RXSTP_TXSTP_3, USB_RXSTP_TXSTP_4, USB_RXSTP_TXSTP_5, USB_RXSTP_TXSTP_6, USB_RXSTP_TXSTP_7, USB_STALL0_STALL_0, USB_STALL0_STALL_1, USB_STALL0_STALL_2, USB_STALL0_STALL_3, USB_STALL0_STALL_4, USB_STALL0_STALL_5, USB_STALL0_STALL_6, USB_STALL0_STALL_7, USB_STALL1_0, USB_STALL1_1, USB_STALL1_2, USB_STALL1_3, USB_STALL1_4, USB_STALL1_5, USB_STALL1_6, USB_STALL1_7, USB_SUSPEND, USB_TRFAIL0_TRFAIL_0, USB_TRFAIL0_TRFAIL_1, USB_TRFAIL0_TRFAIL_2, USB_TRFAIL0_TRFAIL_3, USB_TRFAIL0_TRFAIL_4, USB_TRFAIL0_TRFAIL_5, USB_TRFAIL0_TRFAIL_6, USB_TRFAIL0_TRFAIL_7, USB_TRFAIL1_PERR_0, USB_TRFAIL1_PERR_1, USB_TRFAIL1_PERR_2, USB_TRFAIL1_PERR_3, USB_TRFAIL1_PERR_4, USB_TRFAIL1_PERR_5, USB_TRFAIL1_PERR_6, USB_TRFAIL1_PERR_7, USB_UPRSM, USB_WAKEUP
- DCD USB_1_Handler ; 81 USB_SOF_HSOF
- DCD USB_2_Handler ; 82 USB_TRCPT0_0, USB_TRCPT0_1, USB_TRCPT0_2, USB_TRCPT0_3, USB_TRCPT0_4, USB_TRCPT0_5, USB_TRCPT0_6, USB_TRCPT0_7
- DCD USB_3_Handler ; 83 USB_TRCPT1_0, USB_TRCPT1_1, USB_TRCPT1_2, USB_TRCPT1_3, USB_TRCPT1_4, USB_TRCPT1_5, USB_TRCPT1_6, USB_TRCPT1_7
- DCD GMAC_Handler ; 84 Ethernet MAC
- DCD TCC0_0_Handler ; 85 TCC0_CNT_A, TCC0_DFS_A, TCC0_ERR_A, TCC0_FAULT0_A, TCC0_FAULT1_A, TCC0_FAULTA_A, TCC0_FAULTB_A, TCC0_OVF, TCC0_TRG, TCC0_UFS_A
- DCD TCC0_1_Handler ; 86 TCC0_MC_0
- DCD TCC0_2_Handler ; 87 TCC0_MC_1
- DCD TCC0_3_Handler ; 88 TCC0_MC_2
- DCD TCC0_4_Handler ; 89 TCC0_MC_3
- DCD TCC0_5_Handler ; 90 TCC0_MC_4
- DCD TCC0_6_Handler ; 91 TCC0_MC_5
- DCD TCC1_0_Handler ; 92 TCC1_CNT_A, TCC1_DFS_A, TCC1_ERR_A, TCC1_FAULT0_A, TCC1_FAULT1_A, TCC1_FAULTA_A, TCC1_FAULTB_A, TCC1_OVF, TCC1_TRG, TCC1_UFS_A
- DCD TCC1_1_Handler ; 93 TCC1_MC_0
- DCD TCC1_2_Handler ; 94 TCC1_MC_1
- DCD TCC1_3_Handler ; 95 TCC1_MC_2
- DCD TCC1_4_Handler ; 96 TCC1_MC_3
- DCD TCC2_0_Handler ; 97 TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A
- DCD TCC2_1_Handler ; 98 TCC2_MC_0
- DCD TCC2_2_Handler ; 99 TCC2_MC_1
- DCD TCC2_3_Handler ; 100 TCC2_MC_2
- DCD TCC3_0_Handler ; 101 TCC3_CNT_A, TCC3_DFS_A, TCC3_ERR_A, TCC3_FAULT0_A, TCC3_FAULT1_A, TCC3_FAULTA_A, TCC3_FAULTB_A, TCC3_OVF, TCC3_TRG, TCC3_UFS_A
- DCD TCC3_1_Handler ; 102 TCC3_MC_0
- DCD TCC3_2_Handler ; 103 TCC3_MC_1
- DCD TCC4_0_Handler ; 104 TCC4_CNT_A, TCC4_DFS_A, TCC4_ERR_A, TCC4_FAULT0_A, TCC4_FAULT1_A, TCC4_FAULTA_A, TCC4_FAULTB_A, TCC4_OVF, TCC4_TRG, TCC4_UFS_A
- DCD TCC4_1_Handler ; 105 TCC4_MC_0
- DCD TCC4_2_Handler ; 106 TCC4_MC_1
- DCD TC0_Handler ; 107 Basic Timer Counter 0
- DCD TC1_Handler ; 108 Basic Timer Counter 1
- DCD TC2_Handler ; 109 Basic Timer Counter 2
- DCD TC3_Handler ; 110 Basic Timer Counter 3
- DCD TC4_Handler ; 111 Basic Timer Counter 4
- DCD TC5_Handler ; 112 Basic Timer Counter 5
- DCD TC6_Handler ; 113 Basic Timer Counter 6
- DCD TC7_Handler ; 114 Basic Timer Counter 7
- DCD PDEC_0_Handler ; 115 PDEC_DIR_A, PDEC_ERR_A, PDEC_OVF, PDEC_VLC_A
- DCD PDEC_1_Handler ; 116 PDEC_MC_0
- DCD PDEC_2_Handler ; 117 PDEC_MC_1
- DCD ADC0_0_Handler ; 118 ADC0_OVERRUN, ADC0_WINMON
- DCD ADC0_1_Handler ; 119 ADC0_RESRDY
- DCD ADC1_0_Handler ; 120 ADC1_OVERRUN, ADC1_WINMON
- DCD ADC1_1_Handler ; 121 ADC1_RESRDY
- DCD AC_Handler ; 122 Analog Comparators
- DCD DAC_0_Handler ; 123 DAC_OVERRUN_A_0, DAC_OVERRUN_A_1, DAC_UNDERRUN_A_0, DAC_UNDERRUN_A_1
- DCD DAC_1_Handler ; 124 DAC_EMPTY_0
- DCD DAC_2_Handler ; 125 DAC_EMPTY_1
- DCD DAC_3_Handler ; 126 DAC_RESRDY_0
- DCD DAC_4_Handler ; 127 DAC_RESRDY_1
- DCD I2S_Handler ; 128 Inter-IC Sound Interface
- DCD PCC_Handler ; 129 Parallel Capture Controller
- DCD AES_Handler ; 130 Advanced Encryption Standard
- DCD TRNG_Handler ; 131 True Random Generator
- DCD ICM_Handler ; 132 Integrity Check Monitor
- DCD PUKCC_Handler ; 133 PUblic-Key Cryptography Controller
- DCD QSPI_Handler ; 134 Quad SPI interface
- DCD SDHC0_Handler ; 135 SD/MMC Host Controller 0
- DCD SDHC1_Handler ; 136 SD/MMC Host Controller 1
-__Vectors_End
-
-__Vectors_Size EQU __Vectors_End - __Vectors
-
- AREA |.text|, CODE, READONLY
-
-
-; Reset Handler
-
-Reset_Handler PROC
- EXPORT Reset_Handler [WEAK]
- IMPORT SystemInit
- IMPORT __main
- LDR R0, =SystemInit
- BLX R0
- LDR R0, =__main
- BX R0
- ENDP
-
-
-; Dummy Exception Handlers (infinite loops which can be modified)
-
-NMI_Handler PROC
- EXPORT NMI_Handler [WEAK]
- B .
- ENDP
-HardFault_Handler\
- PROC
- EXPORT HardFault_Handler [WEAK]
- B .
- ENDP
-MemManage_Handler\
- PROC
- EXPORT MemManage_Handler [WEAK]
- B .
- ENDP
-BusFault_Handler\
- PROC
- EXPORT BusFault_Handler [WEAK]
- B .
- ENDP
-UsageFault_Handler\
- PROC
- EXPORT UsageFault_Handler [WEAK]
- B .
- ENDP
-SVC_Handler PROC
- EXPORT SVC_Handler [WEAK]
- B .
- ENDP
-DebugMon_Handler\
- PROC
- EXPORT DebugMon_Handler [WEAK]
- B .
- ENDP
-PendSV_Handler PROC
- EXPORT PendSV_Handler [WEAK]
- B .
- ENDP
-SysTick_Handler PROC
- EXPORT SysTick_Handler [WEAK]
- B .
- ENDP
-
-Default_Handler PROC
- EXPORT PM_Handler [WEAK]
- EXPORT MCLK_Handler [WEAK]
- EXPORT OSCCTRL_0_Handler [WEAK]
- EXPORT OSCCTRL_1_Handler [WEAK]
- EXPORT OSCCTRL_2_Handler [WEAK]
- EXPORT OSCCTRL_3_Handler [WEAK]
- EXPORT OSCCTRL_4_Handler [WEAK]
- EXPORT OSC32KCTRL_Handler [WEAK]
- EXPORT SUPC_0_Handler [WEAK]
- EXPORT SUPC_1_Handler [WEAK]
- EXPORT WDT_Handler [WEAK]
- EXPORT RTC_Handler [WEAK]
- EXPORT EIC_0_Handler [WEAK]
- EXPORT EIC_1_Handler [WEAK]
- EXPORT EIC_2_Handler [WEAK]
- EXPORT EIC_3_Handler [WEAK]
- EXPORT EIC_4_Handler [WEAK]
- EXPORT EIC_5_Handler [WEAK]
- EXPORT EIC_6_Handler [WEAK]
- EXPORT EIC_7_Handler [WEAK]
- EXPORT EIC_8_Handler [WEAK]
- EXPORT EIC_9_Handler [WEAK]
- EXPORT EIC_10_Handler [WEAK]
- EXPORT EIC_11_Handler [WEAK]
- EXPORT EIC_12_Handler [WEAK]
- EXPORT EIC_13_Handler [WEAK]
- EXPORT EIC_14_Handler [WEAK]
- EXPORT EIC_15_Handler [WEAK]
- EXPORT FREQM_Handler [WEAK]
- EXPORT NVMCTRL_0_Handler [WEAK]
- EXPORT NVMCTRL_1_Handler [WEAK]
- EXPORT DMAC_0_Handler [WEAK]
- EXPORT DMAC_1_Handler [WEAK]
- EXPORT DMAC_2_Handler [WEAK]
- EXPORT DMAC_3_Handler [WEAK]
- EXPORT DMAC_4_Handler [WEAK]
- EXPORT EVSYS_0_Handler [WEAK]
- EXPORT EVSYS_1_Handler [WEAK]
- EXPORT EVSYS_2_Handler [WEAK]
- EXPORT EVSYS_3_Handler [WEAK]
- EXPORT EVSYS_4_Handler [WEAK]
- EXPORT PAC_Handler [WEAK]
- EXPORT TAL_0_Handler [WEAK]
- EXPORT TAL_1_Handler [WEAK]
- EXPORT RAMECC_Handler [WEAK]
- EXPORT SERCOM0_0_Handler [WEAK]
- EXPORT SERCOM0_1_Handler [WEAK]
- EXPORT SERCOM0_2_Handler [WEAK]
- EXPORT SERCOM0_3_Handler [WEAK]
- EXPORT SERCOM1_0_Handler [WEAK]
- EXPORT SERCOM1_1_Handler [WEAK]
- EXPORT SERCOM1_2_Handler [WEAK]
- EXPORT SERCOM1_3_Handler [WEAK]
- EXPORT SERCOM2_0_Handler [WEAK]
- EXPORT SERCOM2_1_Handler [WEAK]
- EXPORT SERCOM2_2_Handler [WEAK]
- EXPORT SERCOM2_3_Handler [WEAK]
- EXPORT SERCOM3_0_Handler [WEAK]
- EXPORT SERCOM3_1_Handler [WEAK]
- EXPORT SERCOM3_2_Handler [WEAK]
- EXPORT SERCOM3_3_Handler [WEAK]
- EXPORT SERCOM4_0_Handler [WEAK]
- EXPORT SERCOM4_1_Handler [WEAK]
- EXPORT SERCOM4_2_Handler [WEAK]
- EXPORT SERCOM4_3_Handler [WEAK]
- EXPORT SERCOM5_0_Handler [WEAK]
- EXPORT SERCOM5_1_Handler [WEAK]
- EXPORT SERCOM5_2_Handler [WEAK]
- EXPORT SERCOM5_3_Handler [WEAK]
- EXPORT SERCOM6_0_Handler [WEAK]
- EXPORT SERCOM6_1_Handler [WEAK]
- EXPORT SERCOM6_2_Handler [WEAK]
- EXPORT SERCOM6_3_Handler [WEAK]
- EXPORT SERCOM7_0_Handler [WEAK]
- EXPORT SERCOM7_1_Handler [WEAK]
- EXPORT SERCOM7_2_Handler [WEAK]
- EXPORT SERCOM7_3_Handler [WEAK]
- EXPORT CAN0_Handler [WEAK]
- EXPORT CAN1_Handler [WEAK]
- EXPORT USB_0_Handler [WEAK]
- EXPORT USB_1_Handler [WEAK]
- EXPORT USB_2_Handler [WEAK]
- EXPORT USB_3_Handler [WEAK]
- EXPORT GMAC_Handler [WEAK]
- EXPORT TCC0_0_Handler [WEAK]
- EXPORT TCC0_1_Handler [WEAK]
- EXPORT TCC0_2_Handler [WEAK]
- EXPORT TCC0_3_Handler [WEAK]
- EXPORT TCC0_4_Handler [WEAK]
- EXPORT TCC0_5_Handler [WEAK]
- EXPORT TCC0_6_Handler [WEAK]
- EXPORT TCC1_0_Handler [WEAK]
- EXPORT TCC1_1_Handler [WEAK]
- EXPORT TCC1_2_Handler [WEAK]
- EXPORT TCC1_3_Handler [WEAK]
- EXPORT TCC1_4_Handler [WEAK]
- EXPORT TCC2_0_Handler [WEAK]
- EXPORT TCC2_1_Handler [WEAK]
- EXPORT TCC2_2_Handler [WEAK]
- EXPORT TCC2_3_Handler [WEAK]
- EXPORT TCC3_0_Handler [WEAK]
- EXPORT TCC3_1_Handler [WEAK]
- EXPORT TCC3_2_Handler [WEAK]
- EXPORT TCC4_0_Handler [WEAK]
- EXPORT TCC4_1_Handler [WEAK]
- EXPORT TCC4_2_Handler [WEAK]
- EXPORT TC0_Handler [WEAK]
- EXPORT TC1_Handler [WEAK]
- EXPORT TC2_Handler [WEAK]
- EXPORT TC3_Handler [WEAK]
- EXPORT TC4_Handler [WEAK]
- EXPORT TC5_Handler [WEAK]
- EXPORT TC6_Handler [WEAK]
- EXPORT TC7_Handler [WEAK]
- EXPORT PDEC_0_Handler [WEAK]
- EXPORT PDEC_1_Handler [WEAK]
- EXPORT PDEC_2_Handler [WEAK]
- EXPORT ADC0_0_Handler [WEAK]
- EXPORT ADC0_1_Handler [WEAK]
- EXPORT ADC1_0_Handler [WEAK]
- EXPORT ADC1_1_Handler [WEAK]
- EXPORT AC_Handler [WEAK]
- EXPORT DAC_0_Handler [WEAK]
- EXPORT DAC_1_Handler [WEAK]
- EXPORT DAC_2_Handler [WEAK]
- EXPORT DAC_3_Handler [WEAK]
- EXPORT DAC_4_Handler [WEAK]
- EXPORT I2S_Handler [WEAK]
- EXPORT PCC_Handler [WEAK]
- EXPORT AES_Handler [WEAK]
- EXPORT TRNG_Handler [WEAK]
- EXPORT ICM_Handler [WEAK]
- EXPORT PUKCC_Handler [WEAK]
- EXPORT QSPI_Handler [WEAK]
- EXPORT SDHC0_Handler [WEAK]
- EXPORT SDHC1_Handler [WEAK]
-
-PM_Handler
-MCLK_Handler
-OSCCTRL_0_Handler
-OSCCTRL_1_Handler
-OSCCTRL_2_Handler
-OSCCTRL_3_Handler
-OSCCTRL_4_Handler
-OSC32KCTRL_Handler
-SUPC_0_Handler
-SUPC_1_Handler
-WDT_Handler
-RTC_Handler
-EIC_0_Handler
-EIC_1_Handler
-EIC_2_Handler
-EIC_3_Handler
-EIC_4_Handler
-EIC_5_Handler
-EIC_6_Handler
-EIC_7_Handler
-EIC_8_Handler
-EIC_9_Handler
-EIC_10_Handler
-EIC_11_Handler
-EIC_12_Handler
-EIC_13_Handler
-EIC_14_Handler
-EIC_15_Handler
-FREQM_Handler
-NVMCTRL_0_Handler
-NVMCTRL_1_Handler
-DMAC_0_Handler
-DMAC_1_Handler
-DMAC_2_Handler
-DMAC_3_Handler
-DMAC_4_Handler
-EVSYS_0_Handler
-EVSYS_1_Handler
-EVSYS_2_Handler
-EVSYS_3_Handler
-EVSYS_4_Handler
-PAC_Handler
-TAL_0_Handler
-TAL_1_Handler
-RAMECC_Handler
-SERCOM0_0_Handler
-SERCOM0_1_Handler
-SERCOM0_2_Handler
-SERCOM0_3_Handler
-SERCOM1_0_Handler
-SERCOM1_1_Handler
-SERCOM1_2_Handler
-SERCOM1_3_Handler
-SERCOM2_0_Handler
-SERCOM2_1_Handler
-SERCOM2_2_Handler
-SERCOM2_3_Handler
-SERCOM3_0_Handler
-SERCOM3_1_Handler
-SERCOM3_2_Handler
-SERCOM3_3_Handler
-SERCOM4_0_Handler
-SERCOM4_1_Handler
-SERCOM4_2_Handler
-SERCOM4_3_Handler
-SERCOM5_0_Handler
-SERCOM5_1_Handler
-SERCOM5_2_Handler
-SERCOM5_3_Handler
-SERCOM6_0_Handler
-SERCOM6_1_Handler
-SERCOM6_2_Handler
-SERCOM6_3_Handler
-SERCOM7_0_Handler
-SERCOM7_1_Handler
-SERCOM7_2_Handler
-SERCOM7_3_Handler
-CAN0_Handler
-CAN1_Handler
-USB_0_Handler
-USB_1_Handler
-USB_2_Handler
-USB_3_Handler
-GMAC_Handler
-TCC0_0_Handler
-TCC0_1_Handler
-TCC0_2_Handler
-TCC0_3_Handler
-TCC0_4_Handler
-TCC0_5_Handler
-TCC0_6_Handler
-TCC1_0_Handler
-TCC1_1_Handler
-TCC1_2_Handler
-TCC1_3_Handler
-TCC1_4_Handler
-TCC2_0_Handler
-TCC2_1_Handler
-TCC2_2_Handler
-TCC2_3_Handler
-TCC3_0_Handler
-TCC3_1_Handler
-TCC3_2_Handler
-TCC4_0_Handler
-TCC4_1_Handler
-TCC4_2_Handler
-TC0_Handler
-TC1_Handler
-TC2_Handler
-TC3_Handler
-TC4_Handler
-TC5_Handler
-TC6_Handler
-TC7_Handler
-PDEC_0_Handler
-PDEC_1_Handler
-PDEC_2_Handler
-ADC0_0_Handler
-ADC0_1_Handler
-ADC1_0_Handler
-ADC1_1_Handler
-AC_Handler
-DAC_0_Handler
-DAC_1_Handler
-DAC_2_Handler
-DAC_3_Handler
-DAC_4_Handler
-I2S_Handler
-PCC_Handler
-AES_Handler
-TRNG_Handler
-ICM_Handler
-PUKCC_Handler
-QSPI_Handler
-SDHC0_Handler
-SDHC1_Handler
- B .
- ENDP
-
-
- ALIGN
-
-
-; User Initial Stack & Heap
-
- IF :DEF:__MICROLIB
-
- EXPORT __initial_sp
- EXPORT __heap_base
- EXPORT __heap_limit
-
- ELSE
-
- IMPORT __use_two_region_memory
- EXPORT __user_initial_stackheap
-__user_initial_stackheap
-
- LDR R0, = Heap_Mem
- LDR R1, =(Stack_Mem + Stack_Size)
- LDR R2, = (Heap_Mem + Heap_Size)
- LDR R3, = Stack_Mem
- BX LR
-
- ALIGN
-
- ENDIF
-
-
- END
diff --git a/ASF/samd51a/armcc/Device/SAMD51/Source/system_samd51.c b/ASF/samd51a/armcc/Device/SAMD51/Source/system_samd51.c
deleted file mode 100644
index 838f99a..0000000
--- a/ASF/samd51a/armcc/Device/SAMD51/Source/system_samd51.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * \file
- *
- * \brief Low-level initialization functions called upon chip startup.
- *
- * Copyright (c) 2016 Atmel Corporation,
- * a wholly owned subsidiary of Microchip Technology Inc.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the Licence at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * \asf_license_stop
- *
- */
-
-#include "samd51.h"
-
-/**
- * Initial system clock frequency. The System RC Oscillator (RCSYS) provides
- * the source for the main clock at chip startup.
- */
-#define __SYSTEM_CLOCK (48000000)
-
-uint32_t SystemCoreClock = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/
-
-/**
- * Initialize the system
- *
- * @brief Setup the microcontroller system.
- * Initialize the System and update the SystemCoreClock variable.
- */
-void SystemInit(void)
-{
-#if __FPU_USED
- /* Enable FPU */
- SCB->CPACR |= (0xFu << 20);
- __DSB();
- __ISB();
-#endif
-
- // Keep the default device state after reset
- SystemCoreClock = __SYSTEM_CLOCK;
- return;
-}
-
-/**
- * Update SystemCoreClock variable
- *
- * @brief Updates the SystemCoreClock with current core Clock
- * retrieved from cpu registers.
- */
-void SystemCoreClockUpdate(void)
-{
- // Not implemented
- SystemCoreClock = __SYSTEM_CLOCK;
- return;
-}
diff --git a/src/Makefile b/src/Makefile
index 23c4a22..a9103f0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -11,8 +11,6 @@
###############################################################################
###############################################################################
-
-
### ALL C FILES SHOULD HAVE AN OBJECT FILE LISTED HERE ###
export OBJS := \
../src/main.o \
@@ -51,19 +49,17 @@ export OBJS := \
../src/tasks/command_dispatcher/command_dispatcher_main.o \
../src/tasks/command_dispatcher/command_dispatcher_task.o \
\
-../src/tasks/magnetometer/magnetometer_driver.o \
-../src/tasks/magnetometer/magnetometer_task.o \
-../src/tasks/magnetometer/magnetometer_main.o \
- \
../src/tasks/shell/shell_main.o \
../src/tasks/shell/shell_helpers.o \
../src/tasks/shell/shell_commands.o \
\
../src/tasks/task_list.o \
\
-../src/tasks/photodiode/photodiode_main.o \
-../src/tasks/photodiode/photodiode_task.o \
-../src/tasks/photodiode/photodiode_driver.o \
+../src/tasks/adcs/magnetometer_driver.o \
+../src/tasks/adcs/photodiode_driver.o \
+../src/tasks/adcs/rtc_driver.o \
+../src/tasks/adcs/adcs_main.o \
+../src/tasks/adcs/adcs_task.o \
### ALL DIRECTORIES WITH SOURCE FILES MUST BE LISTED HERE ###
### THESE ARE WRITTEN RELATIVE TO THE ./ASF/gcc/Makefile FILE ###
@@ -82,17 +78,14 @@ export EXTRA_VPATH := \
../../src/tasks/display/image_buffers \
../../src/tasks/task_manager \
../../src/tasks/command_dispatcher \
-../../src/tasks/magnetometer \
../../src/tasks/shell \
-../../src/tasks/photodiode \
+../../src/tasks/adcs \
../../src/mutexes
-
###############################################################################
###############################################################################
###############################################################################
-
#Technical stuff
#Makefile usually uses /bin/sh to evaluate commands, so we need to change it to /bin/bash
@@ -126,7 +119,6 @@ else
GIT_COMMIT_HASH := \"NONE\"
endif
-
# Compiler flags
# Include git branch and commit hash in the build
CFLAGS += -D'GIT_BRANCH_NAME="$(GIT_BRANCH_NAME)"' -D'GIT_COMMIT_HASH="$(GIT_COMMIT_HASH)"'
@@ -146,7 +138,6 @@ CFLAGS_DEV := -DDEVBUILD
CFLAGS_UNITTEST := -DUNITTEST
CFLAGS_RELEASE := -DRELEASE
-
### All these variables are exported to the child makefile, and affect its behavior ###
export SUB_DIRS := $(shell for dir in $(EXTRA_VPATH); do echo $$dir | $(SED) 's|\.\./||g'; done)
@@ -156,7 +147,6 @@ export OBJS_AS_ARGS := $(foreach obj,$(OBJS),$(patsubst ../%,%,$(obj)))
export DEPS_AS_ARGS := $(patsubst %.o,%.d,$(OBJS_AS_ARGS))
-
.PHONY: all dev release test clean connect update_asf flash_bootloader
# Default target
@@ -241,4 +231,4 @@ update_asf:
&& echo "(9) ASF Linker Script: ASF Makefile updated to use custom flash script" \
&& find ../ASF -type f -newermt now -exec touch {} + \
&& echo "(10) Timestamps in future updated to present" \
- && echo " --- Finished Integrating ASF --- "
+ && echo " --- Finished Integrating ASF --- "
\ No newline at end of file
diff --git a/src/atmel_start_config.atstart b/src/atmel_start_config.atstart
index 7b03665..03512f0 100644
--- a/src/atmel_start_config.atstart
+++ b/src/atmel_start_config.atstart
@@ -858,7 +858,7 @@ drivers:
RESERVED_InputFreq_id: 32kHz Ultra Low Power Internal Oscillator (OSCULP32K)
_$freq_output_RTC source: 32768
enable_osculp32k: true
- enable_rtc_source: false
+ enable_rtc_source: true
enable_xosc32k: false
osculp32k_calib: 0
osculp32k_calib_enable: false
@@ -1041,6 +1041,62 @@ drivers:
variant: null
clocks:
domain_group: null
+ TIMER_0:
+ user_label: TIMER_0
+ definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51P20A-AF::RTC::driver_config_definition::Timer::HAL:Driver:Timer
+ functionality: Timer
+ api: HAL:Driver:Timer
+ configuration:
+ rtc_arch_comp_val: 32
+ rtc_arch_init_reset: true
+ rtc_arch_prescaler: OFF(Peripheral clock divided by 1)
+ rtc_cmpeo0: false
+ rtc_cmpeo1: false
+ rtc_event_control: false
+ rtc_ovfeo: false
+ rtc_pereo0: false
+ rtc_pereo1: false
+ rtc_pereo2: false
+ rtc_pereo3: false
+ rtc_pereo4: false
+ rtc_pereo5: false
+ rtc_pereo6: false
+ rtc_pereo7: false
+ rtc_tamper_active_layer_frequency_prescalar: DIV2 CLK_RTC_OUT is CLK_RTC /2
+ rtc_tamper_debounce_frequency_prescalar: DIV2 CLK_RTC_DEB is CLK_RTC /2
+ rtc_tamper_input_action_0: OFF(Disabled)
+ rtc_tamper_input_action_1: OFF(Disabled)
+ rtc_tamper_input_action_2: OFF(Disabled)
+ rtc_tamper_input_action_3: OFF(Disabled)
+ rtc_tamper_input_action_4: OFF(Disabled)
+ rtc_tampereo: false
+ rtc_tampevei: false
+ tamper_debounce_enable_0: false
+ tamper_debounce_enable_1: false
+ tamper_debounce_enable_2: false
+ tamper_debounce_enable_3: false
+ tamper_debounce_enable_4: false
+ tamper_input_0_settings: false
+ tamper_input_1_settings: false
+ tamper_input_2_settings: false
+ tamper_input_3_settings: false
+ tamper_input_4_settings: false
+ tamper_level_0: false
+ tamper_level_1: false
+ tamper_level_2: false
+ tamper_level_3: false
+ tamper_level_4: false
+ optional_signals: []
+ variant: null
+ clocks:
+ domain_group:
+ nodes:
+ - name: RTC
+ input: RTC source
+ external: false
+ external_frequency: 0
+ configuration:
+ rtc_clk_selection: RTC source
I2C_SBAND:
user_label: I2C_SBAND
definition: Atmel:SAMD51_Drivers:0.0.1::SAMD51P20A-AF::SERCOM2::driver_config_definition::I2C.Master.Standard~2FFast-mode::HAL:Driver:I2C.Master.Sync
diff --git a/src/globals.h b/src/globals.h
index dce579d..56d5875 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -47,6 +47,7 @@ typedef enum {
ERROR_TASK_DISABLED,
ERROR_BAD_TARGET,
ERROR_SANITY_CHECK_FAILED,
+ ERROR_PROCESSING_FAILED,
ERROR_NOT_READY,
} status_t;
@@ -68,11 +69,9 @@ typedef enum {
OPERATION_DISPLAY_IMAGE, // p_data: color_t *p_buffer
OPERATION_CLEAR_IMAGE, // p_data: NULL
- // Magnetometer operations
- OPERATION_READ, // p_data: magnetometer_read_args_t *readings
-
- // Photodiode operations
- OPERATION_PHOTODIODE_READ,
+ // Magnetometer & Photodiode operations
+ OPERATION_READ, // p_data: photomag_read_args_t *readings
+ OPERATION_PROCESS, // p_data: TBD
// TESTING
TEST_OP, // p_data: char message[]
diff --git a/src/intrinsics.h b/src/intrinsics.h
new file mode 100644
index 0000000..a8f1519
--- /dev/null
+++ b/src/intrinsics.h
@@ -0,0 +1,4 @@
+// This file is here just to silence the instrinsics.h include
+
+#include
+#include
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index 7183489..343337d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,9 @@
* the FreeRTOS scheduler.
*
* Created: November 20, 2023
- * Authors: Oren Kohavi, Siddharta Laloux, Tanish Makadia, Yi Liu, Defne Doken, Aidan Wang, Ignacio Blancas Rodriguez
+ * Modified: November 9, 2025
+ * Authors: Oren Kohavi, Siddharta Laloux, Tanish Makadia, Yi Liu,
+ * Defne Doken, Aidan Wang, Ignacio Blancas Rodriguez, Alexander Thaep
*/
#include "main.h"
@@ -67,6 +69,14 @@ int main(void) {
}
}
+ // Initialize all sensor integrity tasks
+ for (pvdx_task_t **curr_task = task_list; *curr_task != NULL; curr_task++) {
+ if ((*curr_task)->task_type == SENSOR) {
+ init_task_pointer(*curr_task);
+ info("%s initialized\n", (*curr_task)->name);
+ }
+ }
+
/* ---------- COSMIC MONKEY TASK ---------- */
#if defined(UNITTEST) || defined(DEVBUILD)
diff --git a/src/misc/exception_handlers/specific_handlers.c b/src/misc/exception_handlers/specific_handlers.c
index 05e7f2a..f3c2c7c 100644
--- a/src/misc/exception_handlers/specific_handlers.c
+++ b/src/misc/exception_handlers/specific_handlers.c
@@ -7,7 +7,8 @@
* a placeholder for future customization of specific interrupt logic.
*
* Created: April 5, 2024
- * Author: Oren Kohavi
+ * Modified: November 9, 2025
+ * Author: Oren Kohavi, Alexander Thaep
*/
#include "default_handler.h"
@@ -91,9 +92,6 @@ void SUPC_1_Handler(void) {
void WDT_Handler(void) {
PVDX_default_handler();
}
-void RTC_Handler(void) {
- PVDX_default_handler();
-}
void EIC_0_Handler(void) {
PVDX_default_handler();
}
diff --git a/src/tasks/adcs/adcs_main.c b/src/tasks/adcs/adcs_main.c
new file mode 100644
index 0000000..0a7d2e2
--- /dev/null
+++ b/src/tasks/adcs/adcs_main.c
@@ -0,0 +1,112 @@
+/**
+ * adcs_main.c
+ *
+ * Main loop of the ADCS task which handles sun sensing for ADCS and RTC timer
+ *
+ * Created: September 20, 2025
+ * Modified: November 24, 2025
+ * Authors: Avinash Patel, Yi Lyo, Alexander Thaep
+ */
+
+#include "adcs_task.h"
+#include "logging.h"
+
+// ADCS Task memory structures
+adcs_task_memory_t adcs_mem;
+
+/**
+ * \fn init_adcs
+ *
+ * \brief Initialises ADCS command queue, before `init_task_pointer()`.
+ *
+ * \returns QueueHandle_t, a handle to the created queue
+ *
+ * \see `init_task_pointer()` for usage of functions of the type `init_()`
+ */
+QueueHandle_t init_adcs(void) {
+ QueueHandle_t adcs_command_queue_handle = xQueueCreateStatic(
+ COMMAND_QUEUE_MAX_COMMANDS, COMMAND_QUEUE_ITEM_SIZE, adcs_mem.adcs_command_queue_buffer,
+ &adcs_mem.adcs_task_queue);
+
+ if (adcs_command_queue_handle == NULL) {
+ fatal("Failed to create adcs command queue!\n");
+ }
+
+ // Initialize photodiode hardware
+ status_t result = init_photodiode_hardware();
+ if (result != SUCCESS) {
+ warning("photodiode: Hardware initialization failed\n");
+ }
+
+ // Initialize magnetometer hardware
+ info("Initializing magnetometer\n");
+ result = init_rm3100();
+ if (result != SUCCESS) {
+ warning("rm3100: Hardware initialization failed\n");
+ }
+
+ // Initialize RTC timer hardware
+ info("Initializing RTC timer\n");
+ result = init_rtc_hardware();
+ if (result != SUCCESS) {
+ warning("rtc timer: Hardware initialization failed\n");
+ }
+
+ return adcs_command_queue_handle;
+}
+
+/**
+ * \fn main_adcs
+ *
+ * \param pvParameters a void pointer to the parameters required by ADCS functions; not currently set by config
+ *
+ * \warning should never return
+ */
+void main_adcs(void *pvParameters) {
+ info("adcs: Task Started!\n");
+
+ // Obtain a pointer to the current task within the global task list
+ pvdx_task_t *const current_task = get_current_task();
+ // Cache the watchdog checkin command to avoid creating it every iteration
+ command_t cmd_checkin = get_watchdog_checkin_command(current_task);
+ // Calculate the maximum time this task should block (and thus be unable to check in with the watchdog)
+ const TickType_t queue_block_time_ticks = get_command_queue_block_time_ticks(current_task);
+ // Variable to hold commands popped off the queue
+ command_t cmd;
+
+ info("photodiodes: Initialized with %d photodiodes\n", PHOTODIODE_COUNT);
+ info("magnetometer: Initialized with %d cycle count\n", INITIAL_CC);
+
+ while (true) {
+ debug_impl("\n---------- Magnetometer & Photodiode & RTC & Processing Run ----------\n");
+
+ // Block waiting for at least one command to appear in the command queue
+ if (xQueueReceive(p_adcs_task->command_queue, &cmd, queue_block_time_ticks) == pdPASS) {
+ // Once there is at least one command in the queue, empty the entire queue
+ info("adcs: performing command\n");
+ do {
+ switch (cmd.operation) {
+ case OPERATION_READ:
+ debug("photo/mag/rtc: Command popped off queue. Target: %d, Operation: %d\n", cmd.target, cmd.operation);
+ exec_command_photomagrtc(&cmd);
+ break;
+ case OPERATION_PROCESS:
+ debug("adcs processing: Command popped off queue. Target: %d, Operation: %d\n", cmd.target, cmd.operation);
+ exec_command_adcs_process(&cmd);
+ break;
+ default:
+ fatal("adcs: Invalid operation!\n");
+ cmd.result = ERROR_SANITY_CHECK_FAILED;
+ break;
+ }
+ } while (xQueueReceive(p_adcs_task->command_queue, &cmd, 0) == pdPASS);
+ }
+ debug("adcs: No more commands queued.\n");
+
+ // Check in with the watchdog task
+ if (should_checkin(current_task)) {
+ enqueue_command(&cmd_checkin);
+ debug("adcs: Enqueued watchdog checkin command\n");
+ }
+ }
+}
diff --git a/src/tasks/adcs/adcs_task.c b/src/tasks/adcs/adcs_task.c
new file mode 100644
index 0000000..4a870e5
--- /dev/null
+++ b/src/tasks/adcs/adcs_task.c
@@ -0,0 +1,121 @@
+/**
+ * adcs_task.c
+ *
+ * RTOS task for ADCS functionality
+ *
+ * Created: September 20, 2025
+ * Modified: November 24, 2025
+ * Authors: Avinash Patel, Yi Lyo, Alexander Thaep
+ */
+
+#include "adcs_task.h"
+#include "logging.h"
+
+/* ---------- DISPATCHABLE FUNCTIONS (sent as commands through the command dispatcher task) ---------- */
+
+/**
+ * \fn get_adcs_process_command
+ *
+ * \brief Creates a command to do adcs stuff
+ *
+ * \param data pointer to data structure to fill
+ *
+ * \returns command_t command structure
+ */
+command_t get_adcs_process_command(photomagrtc_read_args_t *const args) {
+ return (command_t) {
+ .target = p_adcs_task,
+ .operation = OPERATION_PROCESS,
+ .p_data = &args,
+ .len = sizeof(photomagrtc_read_args_t),
+ .result = PROCESSING,
+ .callback = NULL
+ };
+}
+
+/**
+ * \fn get_photomagrtc_read_command
+ *
+ * \brief Creates a command to read magnetometer, photodiode, rtc data
+ *
+ * \param data pointer to data structure to fill
+ *
+ * \returns command_t command structure
+ */
+command_t get_photomagrtc_read_command(
+ mag_data_t *const mag_data,
+ photodiode_data_t *const photodiode_data,
+ rtc_data_t *const rtc_data)
+ {
+ photomagrtc_read_args_t args = {
+ .mag_buffer = mag_data,
+ .photodiode_buffer = photodiode_data,
+ .rtc_buffer = rtc_data
+ };
+
+ return (command_t) {
+ .target = p_adcs_task,
+ .operation = OPERATION_READ,
+ .p_data = &args,
+ .len = sizeof(photomagrtc_read_args_t),
+ .result = PROCESSING,
+ .callback = NULL
+ };
+}
+
+/* ---------- NON-DISPATCHABLE FUNCTIONS (do not go through the command dispatcher) ---------- */
+
+/**
+ * \fn exec_command_photomagrtc
+ *
+ * \brief Executes function corresponding to the command
+ *
+ * \param p_cmd a pointer to a command forwarded to magnetometer, photodiode, and rtc
+ */
+void exec_command_photomagrtc(command_t *const p_cmd) {
+ if (p_cmd->target != p_adcs_task) {
+ fatal("photo/mag: command target is not adcs! target: %d operation: %d\n", p_cmd->target, p_cmd->operation);
+ }
+
+ photomagrtc_read_args_t *args = (photomagrtc_read_args_t *)p_cmd->p_data;
+ status_t magnetometer_status = mag_read_data(args->mag_buffer);
+ status_t photodiode_status = photodiode_read(args->photodiode_buffer);
+ status_t rtc_status = get_rtc_values(args->rtc_buffer);
+
+ if (photodiode_status == SUCCESS
+ && magnetometer_status == SUCCESS
+ && rtc_status == SUCCESS) p_cmd->result = SUCCESS;
+ p_cmd->result = ERROR_READ_FAILED;
+}
+
+/**
+ * \fn exec_command_adcs_process
+ *
+ * \brief Executes function corresponding to the command
+ *
+ * \param p_cmd a pointer to a command containing information for processing
+ */
+void exec_command_adcs_process(command_t *const p_cmd) {
+ if (p_cmd->target != p_adcs_task) {
+ fatal("adcs processing: command target is not adcs! target: %d operation: %d\n", p_cmd->target, p_cmd->operation);
+ }
+
+ rtc_data_t temp;
+
+ photomagrtc_read_args_t *args = (photomagrtc_read_args_t *)p_cmd->p_data;
+ status_t rtc_status = get_rtc_values(&temp);
+
+ if (args == NULL) info("adcs: stuff happens here\n");
+
+ // Do stuff with readings here
+
+ info("ADCS microsecond count: %lu\n", temp.microseconds_count);
+ info("ADCS seconds count: %lu\n", temp.seconds_count);
+ info("ADCS mag reading [x,y,z]: [%f,%f,%f]\n",
+ args->mag_buffer->gain_adj_readings[0],
+ args->mag_buffer->gain_adj_readings[1],
+ args->mag_buffer->gain_adj_readings[2]);
+
+ if (rtc_status == SUCCESS) p_cmd->result = SUCCESS;
+ p_cmd->result = ERROR_PROCESSING_FAILED;
+}
\ No newline at end of file
diff --git a/src/tasks/adcs/adcs_task.h b/src/tasks/adcs/adcs_task.h
new file mode 100644
index 0000000..85c129e
--- /dev/null
+++ b/src/tasks/adcs/adcs_task.h
@@ -0,0 +1,56 @@
+#ifndef ADCS_H
+#define ADCS_H
+
+// Includes
+#include "atmel_start.h"
+#include "globals.h"
+#include "logging.h"
+#include "magnetometer_driver.h"
+#include "photodiode_driver.h"
+#include "rtc_driver.h"
+#include "queue.h"
+#include "task_list.h"
+#include "watchdog_task.h"
+
+// TODO: cool ascii art
+#define ADCS_ASCII_ART \
+ " _ ____ ____ ____ \n" \
+ " / \\ | _ \\ / ___/ ___| \n" \
+ " / _ \\ | | | | | \\___ \\ \n" \
+ " / ___ \\| |_| | |___ ___) | \n" \
+ "/_/ \\_\\____/ \\____|____/ \n"
+
+// Constants
+#define ADCS_TASK_STACK_SIZE 1024 // Size of the stack in words (multiply by 4 to get bytes)
+
+// Placed in a struct to ensure that the TCB is placed higher than the stack in memory
+//^ This ensures that stack overflows do not corrupt the TCB (since the stack grows downwards)
+typedef struct {
+ StackType_t overflow_buffer[TASK_STACK_OVERFLOW_PADDING];
+ StackType_t adcs_task_stack[ADCS_TASK_STACK_SIZE];
+ uint8_t adcs_command_queue_buffer[COMMAND_QUEUE_MAX_COMMANDS * COMMAND_QUEUE_ITEM_SIZE];
+ StaticQueue_t adcs_task_queue;
+ StaticTask_t adcs_task_tcb;
+} adcs_task_memory_t;
+
+// Global memory and configuration
+extern adcs_task_memory_t adcs_mem;
+
+typedef struct {
+ photodiode_data_t *photodiode_buffer;
+ mag_data_t *mag_buffer;
+ rtc_data_t *rtc_buffer;
+} photomagrtc_read_args_t;
+
+// Function declarations
+QueueHandle_t init_adcs(void);
+void main_adcs(void *pvParameters);
+command_t get_photomagrtc_read_command(
+ mag_data_t *const mag_data,
+ photodiode_data_t *const photodiode_data,
+ rtc_data_t *const rtc_data);
+command_t get_adcs_process_command(photomagrtc_read_args_t *const args);
+void exec_command_photomagrtc(command_t *const p_cmd);
+void exec_command_adcs_process(command_t *const p_cmd);
+
+#endif // ADCS_H
diff --git a/src/tasks/magnetometer/magnetometer_driver.c b/src/tasks/adcs/magnetometer_driver.c
similarity index 83%
rename from src/tasks/magnetometer/magnetometer_driver.c
rename to src/tasks/adcs/magnetometer_driver.c
index b6d27c8..748c4e8 100644
--- a/src/tasks/magnetometer/magnetometer_driver.c
+++ b/src/tasks/adcs/magnetometer_driver.c
@@ -1,17 +1,18 @@
/**
* magnetometer_driver.c
- *
+ *
* Driver for the RM3100 Magnetometer Sensor from PNICorp
*
* Created: Dec 7, 2023 2:22 AM
+ * Modified: November 24, 2025
* Authors: Nathan Kim, Alexander Thaep, Siddharta Laloux, Tanish Makadia, Defne Doken, Aidan Wang
*/
-// IO descriptor for the RM3100
-#define I2C_SERCOM
-
+#include "adcs_task.h"
#include "magnetometer_driver.h"
+#define SIMULATED_MAGNETOMETER
+
// https://www.tri-m.com/products/pni/RM3100-User-Manual.pdf
// https://github.com/inventorandy/atmel-samd21/blob/master/07_I2CTSYS/07_I2CTSYS/ext_tsys01.h#L15
// https://os.mbed.com/users/ddelsuc/code/RM3100BB_Sample_Code/
@@ -26,13 +27,16 @@ static float m_gain;
/**
* \fn init_rm3100
- *
- * \brief Initializes the RM3100 magnetometer sensor by setting up the I2C interface, reading
+ *
+ * \brief Initializes the RM3100 magnetometer sensor by setting up the I2C interface, reading
* the handshake and revision ID registers, and setting the cycle count and sample rate.
- *
+ *
* \return `status_t` SUCCESS if the initialization was successful, calls fatal() otherwise
*/
status_t init_rm3100(void) {
+ #ifdef SIMULATED_MAGNETOMETER
+ return SUCCESS;
+ #endif
// Initialize I2C
i2c_m_sync_set_baudrate(&I2C_MAG_GYRO, 0, 115200);
i2c_m_sync_get_io_descriptor(&I2C_MAG_GYRO, &rm3100_io);
@@ -41,22 +45,22 @@ status_t init_rm3100(void) {
uint8_t init_values[4] = {0, 0, 0, 0};
uint8_t cycle_values[2] = {0, 0};
-
+
// Read the revision ID and handshake registers
- fatal_on_error(rm3100_read_reg(NULL, RM3100_REVID_REG, &init_values[0], 1),
- "magnetometer: Error reading RM3100 RevID register during initialization");
+ fatal_on_error(rm3100_read_reg(NULL, RM3100_REVID_REG, &init_values[0], 1),
+ "magnetometer: Error reading RM3100 RevID register during initialization");
fatal_on_error(rm3100_read_reg(NULL, RM3100_HSHAKE_REG, &init_values[1], 1),
- "magnetometer: Error reading RM3100 handshake register during initialization");
+ "magnetometer: Error reading RM3100 handshake register during initialization");
if (init_values[0] != RM3100_REVID_VALUE) {
fatal("magnetometer: Unexpected RM3100 RevID value during initialization");
- }
+ }
if (init_values[1] != RM3100_HSHAKE_VALUE) {
fatal("magnetometer: Unexpected RM3100 handshake value during initialization");
}
-
+
// Read the LROSCADJ and SLPOSCADJ registers
fatal_on_error(rm3100_read_reg(NULL, RM3100_LROSCADJ_REG, &init_values[2], 2),
- "magnetometer: Error reading RM3100 LROSCADJ register during initialization");
+ "magnetometer: Error reading RM3100 LROSCADJ register during initialization");
if (init_values[2] != RM3100_LROSCADJ_VALUE) {
fatal("magnetometer: Unexpected RM3100 LROSCADJ register value during initialization");
}
@@ -69,11 +73,11 @@ status_t init_rm3100(void) {
// Attempt to read back the cycle count we just set from one axis as a sanity check
fatal_on_error(rm3100_read_reg(NULL, RM3100_CCX1_REG, &cycle_values[0], 2),
- "magnetometer: Error reading first part of RM3100 CCX1 cycle-count register during initialization");
+ "magnetometer: Error reading first part of RM3100 CCX1 cycle-count register during initialization");
m_cycle_count = cycle_values[0];
m_cycle_count = (m_cycle_count << 8) | cycle_values[1];
-
+
if (m_cycle_count != INITIAL_CC) {
fatal("magnetometer: Cycle count value read from RM3100 X-axis does not match expected value");
}
@@ -94,7 +98,7 @@ status_t init_rm3100(void) {
/**
* \fn rm3100_read_reg
- *
+ *
* \brief Reads a register from the RM3100
*
* \param p_bytes_read Pointer to a uint32_t to store the number of bytes read.
@@ -103,7 +107,7 @@ status_t init_rm3100(void) {
* \param addr Address of the register to read from
* \param read_buf Buffer to store the read data
* \param size Number of bytes to read
- *
+ *
* \return `status_t` SUCCESS if the read was successful, or ERROR_READ_FAILED / ERROR_WRITE_FAILED otherwise
*/
status_t rm3100_read_reg(int32_t *p_bytes_read, uint8_t addr, uint8_t *read_buf, uint16_t size) {
@@ -118,11 +122,12 @@ status_t rm3100_read_reg(int32_t *p_bytes_read, uint8_t addr, uint8_t *read_buf,
warning("magnetometer: Error in RM3100 Read");
return ERROR_READ_FAILED;
}
-
+
if (p_bytes_read != NULL) {
*p_bytes_read = rv;
} else {
- if (rv != size) return ERROR_READ_FAILED;
+ if (rv != size)
+ return ERROR_READ_FAILED;
}
return SUCCESS;
@@ -130,16 +135,16 @@ status_t rm3100_read_reg(int32_t *p_bytes_read, uint8_t addr, uint8_t *read_buf,
/**
* \fn rm3100_write_reg
- *
+ *
* \brief Writes to a register on the RM3100
- *
+ *
* \param p_bytes_written Pointer to a uint32_t to store the number of bytes written.
* If NULL, this function returns ERROR_WRITE_FAILED if the number of bytes
* written is not equal to `size`.
* \param addr Address of the register to write to
* \param data Data to write to the register
* \param size Number of bytes to write
- *
+ *
* \return `status_t` SUCCESS if the write was successful, or ERROR_WRITE_FAILED otherwise
*/
status_t rm3100_write_reg(int32_t *p_bytes_written, uint8_t addr, uint8_t *data, uint16_t size) {
@@ -156,7 +161,8 @@ status_t rm3100_write_reg(int32_t *p_bytes_written, uint8_t addr, uint8_t *data,
if (p_bytes_written != NULL) {
*p_bytes_written = rv;
} else {
- if (rv != size) return ERROR_WRITE_FAILED;
+ if (rv != size)
+ return ERROR_WRITE_FAILED;
}
return SUCCESS;
@@ -164,23 +170,33 @@ status_t rm3100_write_reg(int32_t *p_bytes_written, uint8_t addr, uint8_t *data,
/**
* \fn mag_read_data
- *
+ *
* \brief Reads x,y,z magnetic field data from the RM3100
*
- * \param raw_readings If not NULL, pointer to a buffer (int32_t array of size
- * 3) to store the raw readings from the magnetometer.
- * \param gain_adj_readings If not NULL, pointer to a buffer (float array of
- * size 3) to store the gain-adjusted readings from the magnetometer.
- *
+ * \param data pointer to mag_data_t structure to fill
+ *
* \return `status_t` SUCCESS if the read was successful, or ERROR_READ_FAILED/ERROR_WRITE_FAILED otherwise
*/
-status_t mag_read_data(int32_t *const raw_readings, float *const gain_adj_readings) {
+status_t mag_read_data(mag_data_t *data) {
+ #ifdef SIMULATED_MAGNETOMETER
+ data->gain_adj_readings[0] = 0.7f;
+ data->gain_adj_readings[1] = 0.4f;
+ data->gain_adj_readings[2] = 0.1f;
+
+ return SUCCESS;
+ #endif
+
int32_t readings[3];
int8_t m_samples[9];
-
+
+ if (gpio_get_pin_level(Magnetometer_DRDY) == 0) {
+ debug("magnetometer: DRDY is false; not ready to read yet...");
+ return ERROR_NOT_READY;
+ }
+
// read out sensor data
ret_err_status(rm3100_read_reg(NULL, RM3100_QX2_REG, (uint8_t *)&m_samples, sizeof(m_samples)),
- "magnetometer: Read from QX2 Register failed");
+ "magnetometer: Read from QX2 Register failed");
readings[0] = ((int8_t)m_samples[0]) * 256 * 256;
readings[0] |= m_samples[1] * 256;
@@ -194,18 +210,16 @@ status_t mag_read_data(int32_t *const raw_readings, float *const gain_adj_readin
readings[2] |= m_samples[7] * 256;
readings[2] |= m_samples[8];
- if (raw_readings != NULL) {
- raw_readings[0] = readings[0];
- raw_readings[1] = readings[1];
- raw_readings[2] = readings[2];
- }
+ if (data == NULL) return ERROR_READ_FAILED;
+
+ data->raw_readings[0] = readings[0];
+ data->raw_readings[1] = readings[1];
+ data->raw_readings[2] = readings[2];
// adjust the readings based on the gain
- if (gain_adj_readings != NULL) {
- gain_adj_readings[0] = (float)readings[0] / m_gain;
- gain_adj_readings[1] = (float)readings[1] / m_gain;
- gain_adj_readings[2] = (float)readings[2] / m_gain;
- }
+ data->gain_adj_readings[0] = (float)readings[0] / m_gain;
+ data->gain_adj_readings[1] = (float)readings[1] / m_gain;
+ data->gain_adj_readings[2] = (float)readings[2] / m_gain;
return SUCCESS;
}
@@ -214,30 +228,28 @@ status_t mag_read_data(int32_t *const raw_readings, float *const gain_adj_readin
* \fn mag_modify_interrupts
* \brief Modifies the RM3100's interrupt settings
- *
+ *
* \param cmm_value Value to write to the CMM (Continuous Measurement Mode) register
* \param poll_value Value to write to the POLL register
- *
+ *
* \return `status_t` SUCCESS if the write was successful, or ERROR_WRITE_FAILED otherwise
*/
status_t mag_modify_interrupts(uint8_t cmm_value, uint8_t poll_value) {
uint8_t data[2] = {cmm_value, poll_value};
- ret_err_status(rm3100_write_reg(NULL, RM3100_CMM_REG, &data[0], 1),
- "magnetometer: Write to CMM Register failed");
- ret_err_status(rm3100_write_reg(NULL, RM3100_POLL_REG, &data[1], 1),
- "magnetometer: Read from Poll Register failed");
-
+ ret_err_status(rm3100_write_reg(NULL, RM3100_CMM_REG, &data[0], 1), "magnetometer: Write to CMM Register failed");
+ ret_err_status(rm3100_write_reg(NULL, RM3100_POLL_REG, &data[1], 1), "magnetometer: Read from Poll Register failed");
+
return SUCCESS;
}
/**
* \fn mag_set_power_mode
- *
+ *
* \brief Sets the power mode of the RM3100 magnetometer
- *
+ *
* \param mode The power mode to set the RM3100 to
- *
+ *
* \return rm3100_power_mode_t The power mode the RM3100 was set to
*/
rm3100_power_mode_t mag_set_power_mode(rm3100_power_mode_t mode) {
@@ -260,11 +272,11 @@ rm3100_power_mode_t mag_set_power_mode(rm3100_power_mode_t mode) {
/**
* \fn mag_set_sample_rate
- *
+ *
* \brief Sets the sample rate of the RM3100 magnetometer
- *
+ *
* \param sample_rate The sample rate to set the RM3100 to
- *
+ *
* \return uint16_t The sample rate the RM3100 was set to
*/
uint16_t mag_set_sample_rate(uint16_t sample_rate) {
@@ -294,26 +306,24 @@ uint16_t mag_set_sample_rate(uint16_t sample_rate) {
m_sample_rate = supported_rates[i][0];
i2c_buffer[0] = (uint8_t)supported_rates[i][1];
- ret_err_status(rm3100_write_reg(NULL, RM3100_TMRC_REG, i2c_buffer, 1),
- "magnetometer: Write to TMRC Register failed");
+ ret_err_status(rm3100_write_reg(NULL, RM3100_TMRC_REG, i2c_buffer, 1), "magnetometer: Write to TMRC Register failed");
if (m_sensor_mode == SENSOR_POWER_MODE_CONTINUOUS) {
mag_modify_interrupts(RM3100_ENABLED, RM3100_DISABLED);
}
- fatal_on_error(rm3100_read_reg(NULL, RM3100_TMRC_REG, i2c_buffer, 1),
- "magnetometer: Read from TMRC Register failed");
+ fatal_on_error(rm3100_read_reg(NULL, RM3100_TMRC_REG, i2c_buffer, 1), "magnetometer: Read from TMRC Register failed");
return i2c_buffer[0];
}
/**
* \fn mag_change_cycle_count
- *
+ *
* \brief Changes the cycle count of the RM3100 magnetometer
- *
+ *
* \param newCC The new cycle count to set the RM3100 to
- *
+ *
* \return `status_t` SUCCESS if the write was successful, or ERROR_WRITE_FAILED otherwise
*/
status_t mag_change_cycle_count(uint16_t newCC) {
@@ -331,8 +341,7 @@ status_t mag_change_cycle_count(uint16_t newCC) {
settings[5] = CCLSB; /* CCPZ0 */
/* Write register settings */
- ret_err_status(rm3100_write_reg(NULL, RM3100_CCX1_REG, settings, 6),
- "magnetometer: Write to CCX1 Register failed");
-
+ ret_err_status(rm3100_write_reg(NULL, RM3100_CCX1_REG, settings, 6), "magnetometer: Write to CCX1 Register failed");
+
return SUCCESS;
}
\ No newline at end of file
diff --git a/src/tasks/adcs/magnetometer_driver.h b/src/tasks/adcs/magnetometer_driver.h
new file mode 100644
index 0000000..84be1f1
--- /dev/null
+++ b/src/tasks/adcs/magnetometer_driver.h
@@ -0,0 +1,101 @@
+#ifndef MAGNETOMETER_DRIVER_H
+#define MAGNETOMETER_DRIVER_H
+
+#include "atmel_start.h"
+#include "driver_init.h"
+#include "globals.h"
+#include "rtos_start.h"
+#include "string.h"
+#include "watchdog_task.h"
+
+#define MAX_I2C_WRITE 32
+
+// We are on revision 34 (decimal), 0x22 (hex)
+
+// Need to put the holy grail of values here
+#define RM3100_ADDRESS 0x20 // Hexadecimal slave address for RM3100 with Pin 2 and Pin 4 set to LOW
+
+// Data reading regs are numbered in the opposite from documentation so we're reading 0-1-2 rather than 2-1-0 cause we hate RM3100
+// internal register values without the R/W bit
+#define RM3100_REVID_REG 0x36 // Hexadecimal address for the RevID internal register
+#define RM3100_POLL_REG 0x00 // Hexadecimal address for the Poll internal register
+#define RM3100_CMM_REG 0x01 // Hexadecimal address for the CMM internal register
+#define RM3100_STATUS_REG 0x34 // Hexadecimal address for the Status internal register
+#define RM3100_HSHAKE_REG 0x35 // Hexadecimal address for the HSHAKE internal register
+#define RM3100_CCX1_REG 0x04 // Hexadecimal address for Cycle Count X1 internal register
+#define RM3100_CCX0_REG 0x05 // Hexadecimal address for the Cycle Count X0 internal register
+#define RM3100_CCY1_REG 0x06
+#define RM3100_CCY0_REG 0x07
+#define RM3100_CCZ1_REG 0x08
+#define RM3100_CCZ0_REG 0x09
+#define RM3100_QX2_REG 0x24
+#define RM3100_QX1_REG 0x25
+#define RM3100_QX0_REG 0x26
+#define RM3100_QY2_REG 0x27
+#define RM3100_QY1_REG 0x28
+#define RM3100_QY0_REG 0x29
+#define RM3100_QZ2_REG 0x2A
+#define RM3100_QZ1_REG 0x2B
+#define RM3100_QZ0_REG 0x2C
+#define RM3100_TMRC_REG 0x0B
+
+#define RM3100_TEST3_REG 0x72
+
+#define RM3100_LROSCADJ_REG 0x63
+
+#define RM3100_LROSCADJ_VALUE 0xA7
+#define RM3100_SLPOSCADJ_VALUE 0x08
+
+#define RM3100_REVID_VALUE 0x22
+#define RM3100_HSHAKE_VALUE 0x1B
+
+#define RM3100_ENABLED 0x79
+#define RM3100_SINGLE 0x70
+#define RM3100_DISABLED 0x00
+
+#define RM3100_BIST_REG 0x33
+
+#define RM3100_PNI_KEY1_REG 0x2D
+#define RM3100_PNI_KEY2_REG 0x2E
+
+#define RM3100_NOS_REG 0x0A
+
+#define CCP0 0xC8 // 200 Cycle Count
+#define CCP1 0x00
+#define NOS 0x01 // Number of samples for averaging
+
+#define REQUEST 0x70 // 0b 0111 0000
+
+// options
+#define INITIAL_CC 200 // Set the cycle count
+#define SAMPLE_RATE 2 // 2 HZ
+#define SINGLE_MODE 0 // 0 = use continuous measurement mode; 1 = use single measurement mode
+#define SENSOR_OK 0 // Used in magnetometer initialization
+
+typedef enum {
+ SENSOR_POWER_MODE_INACTIVE = 0,
+ SENSOR_POWER_MODE_CONTINUOUS = 1,
+ SENSOR_POWER_MODE_SINGLE = 2
+} rm3100_power_mode_t;
+
+/* Data structure to hold mag values
+ * raw_readings If not NULL, pointer to a buffer (int32_t array of size
+ * 3) to store the raw readings from the magnetometer.
+ * gain_adj_readings If not NULL, pointer to a buffer (float array of
+ * size 3) to store the gain-adjusted readings from the magnetometer.
+ */
+typedef struct {
+ int32_t raw_readings[3];
+ float gain_adj_readings[3];
+} mag_data_t;
+
+status_t init_rm3100(void);
+status_t rm3100_read_reg(int32_t *p_bytes_read, uint8_t addr, uint8_t *read_buf, uint16_t size);
+status_t rm3100_write_reg(int32_t *p_bytes_written, uint8_t addr, uint8_t *data, uint16_t size);
+status_t mag_read_data(mag_data_t *data);
+status_t mag_modify_interrupts(uint8_t cmm_value, uint8_t poll_value);
+rm3100_power_mode_t mag_set_power_mode(rm3100_power_mode_t mode);
+uint16_t mag_set_sample_rate(uint16_t sample_rate);
+status_t mag_change_cycle_count(uint16_t newCC);
+
+#endif // MAGNETOMETER_DRIVER_H
\ No newline at end of file
diff --git a/src/tasks/photodiode/photodiode_driver.c b/src/tasks/adcs/photodiode_driver.c
similarity index 71%
rename from src/tasks/photodiode/photodiode_driver.c
rename to src/tasks/adcs/photodiode_driver.c
index 143c6a1..ace5d3f 100644
--- a/src/tasks/photodiode/photodiode_driver.c
+++ b/src/tasks/adcs/photodiode_driver.c
@@ -4,11 +4,14 @@
* Hardware driver for photodiode sensors used in ADCS sun sensing.
*
* Created: September 20, 2025
- * Authors: Avinash Patel, Yi Lyo
+ * Modified: November 24, 2025
+ * Authors: Avinash Patel, Yi Lyo, Alexander Thaep
*/
-#include
+
+#include "adcs_task.h"
#include "photodiode_driver.h"
-#include "photodiode_task.h"
+
+#include
/**
* \fn init_photodiode_hardware
@@ -27,6 +30,42 @@ status_t init_photodiode_hardware(void) {
return SUCCESS;
}
+/**
+ * \fn photodiode_read
+ *
+ * \brief Reads photodiode values and calculates sun vector
+ *
+ * \param data pointer to photodiode_data_t structure to fill
+ *
+ * \returns status_t SUCCESS if reading was successful
+ */
+status_t photodiode_read(photodiode_data_t *const data) {
+ if (!data) {
+ return ERROR_SANITY_CHECK_FAILED;
+ }
+
+ debug("photodiode: Reading photodiode values\n");
+
+ // Read raw ADC values
+ uint16_t raw_values[PHOTODIODE_COUNT];
+ status_t result = read_photodiodes(raw_values);
+
+ if (result != SUCCESS) {
+ warning("photodiode: ADC read failed\n");
+ return result;
+ }
+
+ // Copy raw values to data structure
+ for (int i = 0; i < PHOTODIODE_COUNT; i++) {
+ data->raw_values[i] = raw_values[i];
+ }
+
+ data->timestamp = xTaskGetTickCount();
+ data->valid = true;
+
+ return SUCCESS;
+}
+
/**
* \fn read_photodiodes
*
diff --git a/src/tasks/adcs/photodiode_driver.h b/src/tasks/adcs/photodiode_driver.h
new file mode 100644
index 0000000..ed67716
--- /dev/null
+++ b/src/tasks/adcs/photodiode_driver.h
@@ -0,0 +1,26 @@
+#ifndef PHOTODIODE_DRIVER_H
+#define PHOTODIODE_DRIVER_H
+
+#include "globals.h"
+#include "logging.h"
+#include "rtos_start.h"
+
+// Photodiode system constants
+#define PHOTODIODE_COUNT 22 // Number of photodiodes (8 mux + 14 direct)
+
+#define PHOTODIODE_S0_PIN (Photodiode_MUX_S0 & 0x1Fu)
+#define PHOTODIODE_MUX_MASK (0xFu << PHOTODIODE_S0_PIN)
+
+// Photodiode data structures
+typedef struct {
+ uint16_t raw_values[PHOTODIODE_COUNT]; // Raw ADC readings (up to 22)
+ uint32_t timestamp; // Reading timestamp
+ bool valid; // Data validity flag
+} photodiode_data_t;
+
+// Function declarations
+status_t init_photodiode_hardware(void);
+status_t read_photodiodes(uint16_t *values);
+status_t photodiode_read(photodiode_data_t *const data);
+
+#endif // PHOTODIODE_DRIVER_H
diff --git a/src/tasks/adcs/rtc_driver.c b/src/tasks/adcs/rtc_driver.c
new file mode 100644
index 0000000..dd6d4f8
--- /dev/null
+++ b/src/tasks/adcs/rtc_driver.c
@@ -0,0 +1,51 @@
+/**
+ * rtc_driver.c
+ *
+ * Hardware driver for RTC timer used in ADCS algorithms
+ *
+ * Created: November 9, 2025
+ * Modified: November 24, 2025
+ * Authors: Alexander Thaep
+ */
+
+#include "adcs_task.h"
+#include "rtc_driver.h"
+
+static const void *rtc_hw;
+
+/**
+ * \fn init_rtc_hardware
+ *
+ * \brief Initialize RTC timer hardware
+ *
+ * \returns status_t SUCCESS if initialization was successful
+ */
+status_t init_rtc_hardware(void) {
+ rtc_hw = (&TIMER_0.device)->hw;
+ hri_rtcmode0_clear_CTRLA_ENABLE_bit(rtc_hw);
+ hri_rtcmode0_clear_CTRLA_MATCHCLR_bit(rtc_hw);
+ hri_rtcmode0_write_COUNT_reg(rtc_hw, 0);
+ hri_rtcmode0_wait_for_sync(rtc_hw, RTC_MODE0_SYNCBUSY_COUNT);
+ hri_rtcmode0_set_CTRLA_ENABLE_bit(rtc_hw);
+ return SUCCESS;
+}
+
+/**
+ * \fn get_rtc_count
+ *
+ * \brief Get RTC raw count, microseconds, and seconds from the hardware counter
+ *
+ * \param data pointer to rtc_data_t structure to fill
+ *
+ * \returns status_t SUCCESS if reading was successful
+ */
+status_t get_rtc_values(rtc_data_t *data) {
+ if (!rtc_hw) {
+ warning("Attempting to get RTC count before initializing RTC");
+ return ERROR_NOT_READY;
+ }
+ data->rtc_count = hri_rtcmode0_get_COUNT_reg(rtc_hw, 4294967295UL);
+ data->microseconds_count = (data->rtc_count / 32);
+ data->seconds_count = data->rtc_count / 32768;
+ return SUCCESS;
+}
\ No newline at end of file
diff --git a/src/tasks/adcs/rtc_driver.h b/src/tasks/adcs/rtc_driver.h
new file mode 100644
index 0000000..ce89bda
--- /dev/null
+++ b/src/tasks/adcs/rtc_driver.h
@@ -0,0 +1,21 @@
+#ifndef RTC_DRIVER_H
+#define RTC_DRIVER_H
+
+#include "globals.h"
+#include "rtos_start.h"
+#include "watchdog_task.h"
+#include "atmel_start.h"
+#include "driver_init.h"
+
+// Data structure to hold RTC values
+typedef struct {
+ uint32_t rtc_count;
+ uint32_t seconds_count;
+ uint32_t microseconds_count;
+} rtc_data_t;
+
+// Function declarations
+status_t init_rtc_hardware(void);
+status_t get_rtc_values(rtc_data_t *data);
+
+#endif // RTC_DRIVER_H
\ No newline at end of file
diff --git a/src/tasks/magnetometer/magnetometer_driver.h b/src/tasks/magnetometer/magnetometer_driver.h
deleted file mode 100644
index ba2cc3c..0000000
--- a/src/tasks/magnetometer/magnetometer_driver.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef MAGNETOMETER_DRIVER_H
-#define MAGNETOMETER_DRIVER_H
-
-#include "stdint.h"
-#include "globals.h"
-#include "atmel_start.h"
-#include "logging.h"
-#include "string.h"
-
-#define MAX_I2C_WRITE 32
-
-// We are on revision 34 (decimal), 0x22 (hex)
-
-// Need to put the holy grail of values here
-#define RM3100_ADDRESS 0x20 // Hexadecimal slave address for RM3100 with Pin 2 and Pin 4 set to LOW
-
-// Data reading regs are numbered in the opposite from documentation so we're reading 0-1-2 rather than 2-1-0 cause we hate RM3100
-//internal register values without the R/W bit
-#define RM3100_REVID_REG 0x36 // Hexadecimal address for the RevID internal register
-#define RM3100_POLL_REG 0x00 // Hexadecimal address for the Poll internal register
-#define RM3100_CMM_REG 0x01 // Hexadecimal address for the CMM internal register
-#define RM3100_STATUS_REG 0x34 // Hexadecimal address for the Status internal register
-#define RM3100_HSHAKE_REG 0x35 // Hexadecimal address for the HSHAKE internal register
-#define RM3100_CCX1_REG 0x04 // Hexadecimal address for Cycle Count X1 internal register
-#define RM3100_CCX0_REG 0x05 // Hexadecimal address for the Cycle Count X0 internal register
-#define RM3100_CCY1_REG 0x06
-#define RM3100_CCY0_REG 0x07
-#define RM3100_CCZ1_REG 0x08
-#define RM3100_CCZ0_REG 0x09
-#define RM3100_QX2_REG 0x24
-#define RM3100_QX1_REG 0x25
-#define RM3100_QX0_REG 0x26
-#define RM3100_QY2_REG 0x27
-#define RM3100_QY1_REG 0x28
-#define RM3100_QY0_REG 0x29
-#define RM3100_QZ2_REG 0x2A
-#define RM3100_QZ1_REG 0x2B
-#define RM3100_QZ0_REG 0x2C
-#define RM3100_TMRC_REG 0x0B
-
-#define RM3100_TEST3_REG 0x72
-
-#define RM3100_LROSCADJ_REG 0x63
-
-#define RM3100_LROSCADJ_VALUE 0xA7
-#define RM3100_SLPOSCADJ_VALUE 0x08
-
-#define RM3100_REVID_VALUE 0x22
-#define RM3100_HSHAKE_VALUE 0x1B
-
-#define RM3100_ENABLED 0x79
-#define RM3100_SINGLE 0x70
-#define RM3100_DISABLED 0x00
-
-#define RM3100_BIST_REG 0x33
-
-#define RM3100_PNI_KEY1_REG 0x2D
-#define RM3100_PNI_KEY2_REG 0x2E
-
-#define RM3100_NOS_REG 0x0A
-
-#define CCP0 0xC8 /* 200 Cycle Count */
-#define CCP1 0x00
-#define NOS 0x01 /* Number of Samples for averaging */
-
-#define REQUEST 0x70 // 0b 0111 0000
-
-// options
-#define INITIAL_CC 200 // Set the cycle count
-#define SAMPLE_RATE 2 // 2 HZ
-#define SINGLE_MODE 0 // 0 = use continuous measurement mode; 1 = use single measurement mode
-#define SENSOR_OK 0 // Used in magnetometer initialization
-
-typedef enum {
- SENSOR_POWER_MODE_INACTIVE = 0,
- SENSOR_POWER_MODE_CONTINUOUS = 1,
- SENSOR_POWER_MODE_SINGLE = 2
-} rm3100_power_mode_t;
-
-status_t init_rm3100(void);
-status_t rm3100_read_reg(int32_t *p_bytes_read, uint8_t addr, uint8_t *read_buf, uint16_t size);
-status_t rm3100_write_reg(int32_t *p_bytes_written, uint8_t addr, uint8_t *data, uint16_t size);
-status_t mag_read_data(int32_t *raw_readings, float *gain_adj_readings);
-status_t mag_modify_interrupts(uint8_t cmm_value, uint8_t poll_value);
-rm3100_power_mode_t mag_set_power_mode(rm3100_power_mode_t mode);
-uint16_t mag_set_sample_rate(uint16_t sample_rate);
-status_t mag_change_cycle_count(uint16_t newCC);
-
-#endif // MAGNETOMETER_DRIVER_H
\ No newline at end of file
diff --git a/src/tasks/magnetometer/magnetometer_main.c b/src/tasks/magnetometer/magnetometer_main.c
deleted file mode 100644
index f374410..0000000
--- a/src/tasks/magnetometer/magnetometer_main.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * magnetometer_main.c
- *
- * Main loop of the satellite's RM3100 Magnetometer sensor RTOS task
- *
- * Created: Feb 20, 2025
- * Authors: Nathan Kim, Alexander Thaep, Siddharta Laloux, Defne Doken, Aidan Wang, Tanish Makadia
- **/
-
-#include "magnetometer_task.h"
-
-// Magnetometer Task memory structures
-magnetometer_task_memory_t magnetometer_mem;
-
-/**
- * \fn main_magnetometer
- *
- * \param pvParameters a void pointer to the parametres required by the
- * magnetometer task; not currently set by config
- *
- * \warning should never return
- */
-void main_magnetometer(void *pvParameters) {
- info("magnetometer: Task Started!\n");
-
- // Obtain a pointer to the current task within the global task list
- pvdx_task_t *const current_task = get_current_task();
- // Cache the watchdog checkin command to avoid creating it every iteration
- command_t cmd_checkin = get_watchdog_checkin_command(current_task);
- // Calculate the maximum time the command dispatcher should block (and thus be unable to check in with the watchdog)
- const TickType_t queue_block_time_ticks = get_command_queue_block_time_ticks(current_task);
- // Varible to hold commands popped off the queue
- command_t cmd;
-
- while (true) {
- debug_impl("\n---------- Magnetometer Task Loop ----------\n");
-
- // Execute all commands contained in the queue
- if (xQueueReceive(p_magnetometer_task->command_queue, &cmd, queue_block_time_ticks) == pdPASS) {
- do {
- debug("magnetometer: Command popped off queue. Target: %d, Operation: %d\n", cmd.target, cmd.operation);
- exec_command_magnetometer(&cmd);
- } while (xQueueReceive(p_magnetometer_task->command_queue, &cmd, 0) == pdPASS);
- }
- debug("magnetometer: No more commands queued.\n");
-
- if (should_checkin(current_task)) {
- enqueue_command(&cmd_checkin);
- debug("magnetometer: Enqueued watchdog checkin command\n");
- }
- }
-}
\ No newline at end of file
diff --git a/src/tasks/magnetometer/magnetometer_task.c b/src/tasks/magnetometer/magnetometer_task.c
deleted file mode 100644
index 60bb994..0000000
--- a/src/tasks/magnetometer/magnetometer_task.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * magnetometer_task.c
- *
- * RTOS task wrapping the driver for a RM3100 Magnetometer Sensor
- *
- * Created: Dec 7, 2023 2:22 AM
- * Authors: Nathan Kim, Alexander Thaep, Siddharta Laloux, Tanish Makadia, Defne Doken, Aidan Wang
- */
-
-#include "magnetometer_task.h"
-
-extern magnetometer_task_memory_t magnetometer_mem;
-
-/* ---------- DISPATCHABLE FUNCTIONS (sent as commands through the command dispatcher task) ---------- */
-
-/**
- * \fn magnetometer_read
- *
- * \brief Reads X,Y,Z magnetometer axes
- *
- * \param raw_readings If not NULL, pointer to a buffer (int32_t array of size 3)
- * to store the raw readings from the magnetometer.
- * \param gain_adj_readings If not NULL, pointer to a buffer (float array of size 3)
- * to store the gain-adjusted readings from the magnetometer.
- *
- * \return `status_t` SUCCESS if reading was successful, ERROR_READ_FAILED/ERROR_WRITE_FAILED if
- * there was an I2C communication error, and ERROR_NOT_READY if the magnetometer's DRDY
- * pin is set to false (indicating that data is not ready to be read).
- */
-status_t magnetometer_read(int32_t *const raw_readings, float *const gain_adj_readings) {
- if (gpio_get_pin_level(Magnetometer_DRDY) == 0) {
- debug("magnetometer: DRDY is false; not ready to read yet...");
- return ERROR_NOT_READY;
- }
-
- debug("magnetometer: Reading X,Y,Z data");
- return mag_read_data(raw_readings, gain_adj_readings);
-}
-
-/* ---------- NON-DISPATCHABLE FUNCTIONS (do not go through the command dispatcher) ---------- */
-
-/**
- * \fn exec_command_magnetometer
- *
- * \brief Executes a command received by the magnetometer task
- *
- * \param p_cmd Pointer to the received command
- */
-void exec_command_magnetometer(command_t *const p_cmd) {
- if (p_cmd->target != p_magnetometer_task) {
- fatal("magnetometer: command target is not magnetometer! target: %d operation: %d\n", p_cmd->target->name, p_cmd->operation);
- }
-
- switch (p_cmd->operation) {
- case OPERATION_READ: {
- const magnetometer_read_args_t *const args = p_cmd->p_data;
- p_cmd->result = magnetometer_read(args->raw_readings, args->gain_adj_readings);
- break;
- }
- default:
- fatal("magnetometer: Invalid operation! target: %d operation: %d\n", p_cmd->target, p_cmd->operation);
- break;
- }
-}
-
-/**
- * \fn init_magnetometer
- *
- * \brief Initializes the magnetometer task, including hardware setup and command queue creation
- *
- * \return Handle to the magnetometer task's command queue
- */
-QueueHandle_t init_magnetometer(void) {
- fatal_on_error(init_rm3100(), "magnetometer: Hardware initialization failed!");
-
- // Initialize the magnetometer command queue
- QueueHandle_t magnetometer_command_queue_handle =
- xQueueCreateStatic(COMMAND_QUEUE_MAX_COMMANDS, COMMAND_QUEUE_ITEM_SIZE, magnetometer_mem.magnetometer_command_queue_buffer,
- &magnetometer_mem.magnetometer_task_queue);
- if (magnetometer_command_queue_handle == NULL) {
- fatal("Failed to create magnetometer queue!\n");
- }
-
- return magnetometer_command_queue_handle;
-}
diff --git a/src/tasks/magnetometer/magnetometer_task.h b/src/tasks/magnetometer/magnetometer_task.h
deleted file mode 100644
index 3f69638..0000000
--- a/src/tasks/magnetometer/magnetometer_task.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef MAGNETOMETER_TASK_H
-#define MAGNETOMETER_TASK_H
-
-#include
-#include
-#include "globals.h"
-#include "logging.h"
-#include "magnetometer_driver.h"
-#include "rtos_start.h"
-#include "stdbool.h"
-#include "string.h"
-#include "watchdog_task.h"
-
-// FreeRTOS Task structs
-// Memory for the magnetometer task
-#define MAGNETOMETER_TASK_STACK_SIZE 1024 // Size of the stack in words (multiply by 4 to get bytes)
-
-// Placed in a struct to ensure that the TCB is placed higher than the stack in memory
-// ^ This ensures that stack overflows do not corrupt the TCB (since the stack grows downwards)
-typedef struct {
- StackType_t overflow_buffer[TASK_STACK_OVERFLOW_PADDING];
- StackType_t magnetometer_task_stack[MAGNETOMETER_TASK_STACK_SIZE];
- uint8_t magnetometer_command_queue_buffer[COMMAND_QUEUE_MAX_COMMANDS * COMMAND_QUEUE_ITEM_SIZE];
- StaticQueue_t magnetometer_task_queue;
- StaticTask_t magnetometer_task_tcb;
-} magnetometer_task_memory_t;
-
-// Arguments to `magnetometer_read` defined in `magnetometer_task.c`
-typedef struct {
- int32_t *const raw_readings;
- float *const gain_adj_readings;
-} magnetometer_read_args_t;
-
-extern magnetometer_task_memory_t magnetometer_mem;
-
-QueueHandle_t init_magnetometer(void);
-void exec_command_magnetometer(command_t *const p_cmd);
-void main_magnetometer(void *pvParameters);
-
-#endif // MAGNETOMETER_TASK_H
diff --git a/src/tasks/photodiode/photodiode_driver.h b/src/tasks/photodiode/photodiode_driver.h
deleted file mode 100644
index c88b273..0000000
--- a/src/tasks/photodiode/photodiode_driver.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef PHOTODIODE_DRIVER_H
-#define PHOTODIODE_DRIVER_H
-
-#include "atmel_start.h"
-#include "globals.h"
-#include "logging.h"
-#include "photodiode_task.h"
-
-// Function declarations
-status_t init_photodiode_hardware(void);
-status_t read_photodiodes(uint16_t *values);
-
-#endif // PHOTODIODE_DRIVER_H
diff --git a/src/tasks/photodiode/photodiode_main.c b/src/tasks/photodiode/photodiode_main.c
deleted file mode 100644
index 1fd3233..0000000
--- a/src/tasks/photodiode/photodiode_main.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * photodiode_main.c
- *
- * Main loop of the Photodiode task which handles sun sensing for ADCS.
- *
- * Created: September 20, 2025
- * Authors: Avinash Patel, Yi Lyo
- */
-
-#include "photodiode_task.h"
-
-// Photodiode Task memory structures
-photodiode_task_memory_t photodiode_mem;
-
-/**
- * \fn main_photodiode
- *
- * \param pvParameters a void pointer to the parametres required by photodiode; not currently set by config
- *
- * \warning should never return
- */
-void main_photodiode(void *pvParameters) {
- info("photodiode: Task Started!\n");
-
- // Obtain a pointer to the current task within the global task list
- pvdx_task_t *const current_task = get_current_task();
- // Cache the watchdog checkin command to avoid creating it every iteration
- command_t cmd_checkin = get_watchdog_checkin_command(current_task);
- // Calculate the maximum time this task should block (and thus be unable to check in with the watchdog)
- const TickType_t queue_block_time_ticks = get_command_queue_block_time_ticks(current_task);
- // Variable to hold commands popped off the queue
- command_t cmd;
-
- info("photodiode: Initialized with %d photodiodes\n", PHOTODIODE_COUNT);
-
- while (true) {
- debug_impl("\n---------- Photodiode Task Loop ----------\n");
-
- // Block waiting for at least one command to appear in the command queue
- if (xQueueReceive(p_photodiode_task->command_queue, &cmd, queue_block_time_ticks) == pdPASS) {
- // Once there is at least one command in the queue, empty the entire queue
- do {
- debug("photodiode: Command popped off queue. Target: %d, Operation: %d\n", cmd.target, cmd.operation);
- exec_command_photodiode(&cmd);
-
- } while (xQueueReceive(p_photodiode_task->command_queue, &cmd, 0) == pdPASS);
- }
- debug("photodiode: No more commands queued.\n");
-
- // Check in with the watchdog task
- if (should_checkin(current_task)) {
- enqueue_command(&cmd_checkin);
- debug("photodiode: Enqueued watchdog checkin command\n");
- }
- }
-}
diff --git a/src/tasks/photodiode/photodiode_task.c b/src/tasks/photodiode/photodiode_task.c
deleted file mode 100644
index 3cb0f01..0000000
--- a/src/tasks/photodiode/photodiode_task.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * photodiode_task.c
- *
- * RTOS task for photodiode sensors used in ADCS sun sensing.
- *
- * Created: September 20, 2025
- * Authors: Avinash Patel, Yi Lyo
- */
-
-#include "photodiode_task.h"
-
-/* ---------- DISPATCHABLE FUNCTIONS (sent as commands through the command dispatcher task) ---------- */
-
-/**
- * \fn photodiode_read
- *
- * \brief Reads photodiode values and calculates sun vector
- *
- * \param data pointer to photodiode_data_t structure to fill
- *
- * \returns status_t SUCCESS if reading was successful
- */
-status_t photodiode_read(photodiode_data_t *const data) {
- if (!data) {
- return ERROR_SANITY_CHECK_FAILED;
- }
-
- debug("photodiode: Reading photodiode values\n");
-
- // Read raw ADC values
- uint16_t raw_values[PHOTODIODE_COUNT];
- status_t result = read_photodiodes(raw_values);
-
- if (result != SUCCESS) {
- warning("photodiode: ADC read failed\n");
- return result;
- }
-
- // Copy raw values to data structure
- for (int i = 0; i < PHOTODIODE_COUNT; i++) {
- data->raw_values[i] = raw_values[i];
- }
-
- data->timestamp = xTaskGetTickCount();
- data->valid = true;
-
- return SUCCESS;
-}
-
-/**
- * \fn get_photodiode_read_command
- *
- * \brief Creates a command to read photodiode data
- *
- * \param data pointer to data structure to fill
- *
- * \returns command_t command structure
- */
-command_t get_photodiode_read_command(photodiode_data_t *const data) {
- photodiode_read_args_t args = {
- .data_buffer = data
- };
-
- return (command_t) {
- .target = p_photodiode_task,
- .operation = OPERATION_PHOTODIODE_READ,
- .p_data = &args,
- .len = sizeof(photodiode_read_args_t),
- .result = PROCESSING,
- .callback = NULL
- };
-}
-
-/* ---------- NON-DISPATCHABLE FUNCTIONS (do not go through the command dispatcher) ---------- */
-
-/**
- * \fn init_photodiode
- *
- * \brief Initialises photodiode command queue, before `init_task_pointer()`.
- *
- * \returns QueueHandle_t, a handle to the created queue
- *
- * \see `init_task_pointer()` for usage of functions of the type `init_()`
- */
-QueueHandle_t init_photodiode(void) {
- QueueHandle_t photodiode_command_queue_handle = xQueueCreateStatic(
- COMMAND_QUEUE_MAX_COMMANDS, COMMAND_QUEUE_ITEM_SIZE, photodiode_mem.photodiode_command_queue_buffer,
- &photodiode_mem.photodiode_task_queue);
-
- if (photodiode_command_queue_handle == NULL) {
- fatal("Failed to create photodiode command queue!\n");
- }
-
- // Initialize photodiode hardware
- status_t result = init_photodiode_hardware();
- if (result != SUCCESS) {
- warning("photodiode: Hardware initialization failed\n");
- }
-
- return photodiode_command_queue_handle;
-}
-
-/**
- * \fn exec_command_photodiode
- *
- * \brief Executes function corresponding to the command
- *
- * \param p_cmd a pointer to a command forwarded to photodiode
- */
-void exec_command_photodiode(command_t *const p_cmd) {
- if (p_cmd->target != p_photodiode_task) {
- fatal("photodiode: command target is not photodiode! target: %d operation: %d\n", p_cmd->target, p_cmd->operation);
- }
-
- switch (p_cmd->operation) {
- case OPERATION_PHOTODIODE_READ:
- photodiode_read_args_t *args = (photodiode_read_args_t *)p_cmd->p_data;
- p_cmd->result = photodiode_read(args->data_buffer);
- break;
- default:
- fatal("photodiode: Invalid operation!\n");
- p_cmd->result = ERROR_SANITY_CHECK_FAILED;
- break;
- }
-}
diff --git a/src/tasks/photodiode/photodiode_task.h b/src/tasks/photodiode/photodiode_task.h
deleted file mode 100644
index 9ad2516..0000000
--- a/src/tasks/photodiode/photodiode_task.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef PHOTODIODE_H
-#define PHOTODIODE_H
-
-// Includes
-#include "globals.h"
-#include "logging.h"
-#include "queue.h"
-#include "task_list.h"
-#include "atmel_start.h"
-#include "watchdog_task.h"
-#include "photodiode_driver.h"
-
-// Constants
-#define PHOTODIODE_TASK_STACK_SIZE 1024 // Size of the stack in words (multiply by 4 to get bytes)
-
-// Photodiode system constants
-#define PHOTODIODE_COUNT 22 // Number of photodiodes (8 mux + 14 direct)
-
-#define PHOTODIODE_S0_PIN (Photodiode_MUX_S0 & 0x1Fu)
-#define PHOTODIODE_MUX_MASK (0xFu << PHOTODIODE_S0_PIN)
-
-// Placed in a struct to ensure that the TCB is placed higher than the stack in memory
-//^ This ensures that stack overflows do not corrupt the TCB (since the stack grows downwards)
-typedef struct {
- StackType_t overflow_buffer[TASK_STACK_OVERFLOW_PADDING];
- StackType_t photodiode_task_stack[PHOTODIODE_TASK_STACK_SIZE];
- uint8_t photodiode_command_queue_buffer[COMMAND_QUEUE_MAX_COMMANDS * COMMAND_QUEUE_ITEM_SIZE];
- StaticQueue_t photodiode_task_queue;
- StaticTask_t photodiode_task_tcb;
-} photodiode_task_memory_t;
-
-// Photodiode data structures
-typedef struct {
- uint16_t raw_values[PHOTODIODE_COUNT]; // Raw ADC readings (up to 22)
- uint32_t timestamp; // Reading timestamp
- bool valid; // Data validity flag
-} photodiode_data_t;
-
-typedef struct {
- photodiode_data_t *data_buffer;
-} photodiode_read_args_t;
-
-// Global memory and configuration
-extern photodiode_task_memory_t photodiode_mem;
-
-// Function declarations
-QueueHandle_t init_photodiode(void);
-void main_photodiode(void *pvParameters);
-void exec_command_photodiode(command_t *const p_cmd);
-status_t photodiode_read(photodiode_data_t *const data);
-command_t get_photodiode_read_command(photodiode_data_t *const data);
-
-#endif // PHOTODIODE_H
diff --git a/src/tasks/task_list.c b/src/tasks/task_list.c
index 998625d..7b03c59 100644
--- a/src/tasks/task_list.c
+++ b/src/tasks/task_list.c
@@ -65,36 +65,18 @@ pvdx_task_t task_manager_task = {
.task_type = OS
};
-pvdx_task_t magnetometer_task = {
- .name = "Magnetometer",
+pvdx_task_t adcs_task = {
+ .name = "ADCS",
.enabled = false,
.handle = NULL,
.command_queue = NULL,
- .init = init_magnetometer,
- .function = main_magnetometer,
- .stack_size = MAGNETOMETER_TASK_STACK_SIZE,
- .stack_buffer = magnetometer_mem.magnetometer_task_stack,
+ .init = init_adcs,
+ .function = main_adcs,
+ .stack_size = ADCS_TASK_STACK_SIZE,
+ .stack_buffer = adcs_mem.adcs_task_stack,
.pvParameters = NULL,
.priority = 2,
- .task_tcb = &magnetometer_mem.magnetometer_task_tcb,
- .watchdog_timeout_ms = 10000,
- .last_checkin_time_ticks = 0xDEADBEEF,
- .has_registered = false,
- .task_type = SENSOR
-};
-
-pvdx_task_t photodiode_task = {
- .name = "Photodiode",
- .enabled = false,
- .handle = NULL,
- .command_queue = NULL,
- .init = init_photodiode,
- .function = main_photodiode,
- .stack_size = PHOTODIODE_TASK_STACK_SIZE,
- .stack_buffer = photodiode_mem.photodiode_task_stack,
- .pvParameters = NULL,
- .priority = 2,
- .task_tcb = &photodiode_mem.photodiode_task_tcb,
+ .task_tcb = &adcs_mem.adcs_task_tcb,
.watchdog_timeout_ms = 5000,
.last_checkin_time_ticks = 0xDEADBEEF,
.has_registered = false,
@@ -159,8 +141,7 @@ pvdx_task_t heartbeat_task = {
pvdx_task_t *const p_watchdog_task = &watchdog_task;
pvdx_task_t *const p_command_dispatcher_task = &command_dispatcher_task;
pvdx_task_t *const p_task_manager_task = &task_manager_task;
-pvdx_task_t *const p_magnetometer_task = &magnetometer_task;
-pvdx_task_t *const p_photodiode_task = &photodiode_task;
+pvdx_task_t *const p_adcs_task = &adcs_task;
pvdx_task_t *const p_shell_task = &shell_task;
pvdx_task_t *const p_display_task = &display_task;
pvdx_task_t *const p_heartbeat_task = &heartbeat_task;
@@ -176,8 +157,7 @@ pvdx_task_t *task_list[] = {
p_watchdog_task,
p_command_dispatcher_task,
p_task_manager_task,
- p_magnetometer_task,
- p_photodiode_task,
+ p_adcs_task,
p_shell_task,
p_display_task,
p_heartbeat_task,
diff --git a/src/tasks/task_list.h b/src/tasks/task_list.h
index 3d17c47..e418249 100644
--- a/src/tasks/task_list.h
+++ b/src/tasks/task_list.h
@@ -6,8 +6,7 @@
#include "display_task.h"
#include "globals.h"
#include "heartbeat_task.h"
-#include "magnetometer_task.h"
-#include "photodiode_task.h"
+#include "adcs_task.h"
#include "shell_task.h"
#include "task_manager_task.h"
#include "watchdog_task.h"
@@ -16,8 +15,7 @@
extern pvdx_task_t *const p_watchdog_task;
extern pvdx_task_t *const p_command_dispatcher_task;
extern pvdx_task_t *const p_task_manager_task;
-extern pvdx_task_t *const p_magnetometer_task;
-extern pvdx_task_t *const p_photodiode_task;
+extern pvdx_task_t *const p_adcs_task;
extern pvdx_task_t *const p_shell_task;
extern pvdx_task_t *const p_display_task;
extern pvdx_task_t *const p_heartbeat_task;